aboutsummaryrefslogtreecommitdiff
path: root/ssl.c
diff options
context:
space:
mode:
authorJames Yonan <james@openvpn.net>2010-06-01 07:12:27 +0000
committerJames Yonan <james@openvpn.net>2010-06-01 07:12:27 +0000
commitaaf72974672e4f2af2053247b63ef6f06bdc80c0 (patch)
treece55a352a9bb5f4e95a650f871ab0843964f4007 /ssl.c
parentImplemented http-proxy-override and http-proxy-fallback directives to make it (diff)
downloadopenvpn-aaf72974672e4f2af2053247b63ef6f06bdc80c0.tar.xz
Implemented a key/value auth channel from client to server.
Version 2.1.1i git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@5668 e7ae566f-a301-0410-adde-c780ea21d3b5
Diffstat (limited to 'ssl.c')
-rw-r--r--ssl.c124
1 files changed, 122 insertions, 2 deletions
diff --git a/ssl.c b/ssl.c
index 3387943..9801b0e 100644
--- a/ssl.c
+++ b/ssl.c
@@ -2558,6 +2558,8 @@ tls_multi_free (struct tls_multi *multi, bool clear)
#ifdef MANAGEMENT_DEF_AUTH
man_def_auth_set_client_reason(multi, NULL);
+
+ free (multi->peer_info);
#endif
if (multi->locked_cn)
@@ -3106,6 +3108,14 @@ write_string (struct buffer *buf, const char *str, const int maxlen)
}
static bool
+write_empty_string (struct buffer *buf)
+{
+ if (!buf_write_u16 (buf, 0))
+ return false;
+ return true;
+}
+
+static bool
read_string (struct buffer *buf, char *str, const unsigned int capacity)
{
const int len = buf_read_u16 (buf);
@@ -3117,6 +3127,33 @@ read_string (struct buffer *buf, char *str, const unsigned int capacity)
return true;
}
+static char *
+read_string_alloc (struct buffer *buf)
+{
+ const int len = buf_read_u16 (buf);
+ char *str;
+
+ if (len < 1)
+ return NULL;
+ str = (char *) malloc(len);
+ check_malloc_return(str);
+ if (!buf_read (buf, str, len))
+ {
+ free (str);
+ return NULL;
+ }
+ str[len-1] = '\0';
+ return str;
+}
+
+void
+read_string_discard (struct buffer *buf)
+{
+ char *data = read_string_alloc(buf);
+ if (data)
+ free (data);
+}
+
/*
* Authenticate a client using username/password.
* Runs on server.
@@ -3328,6 +3365,73 @@ key_method_1_write (struct buffer *buf, struct tls_session *session)
}
static bool
+push_peer_info(struct buffer *buf, struct tls_session *session)
+{
+ struct gc_arena gc = gc_new ();
+ bool ret = false;
+
+#ifdef ENABLE_PUSH_PEER_INFO
+ if (session->opt->push_peer_info) /* write peer info */
+ {
+ struct env_set *es = session->opt->es;
+ struct env_item *e;
+ struct buffer out = alloc_buf_gc (512*3, &gc);
+
+ /* push version */
+ buf_printf (&out, "IV_VER=%s\n", PACKAGE_VERSION);
+
+ /* push platform */
+#if defined(TARGET_LINUX)
+ buf_printf (&out, "IV_PLAT=linux\n");
+#elif defined(TARGET_SOLARIS)
+ buf_printf (&out, "IV_PLAT=solaris\n");
+#elif defined(TARGET_OPENBSD)
+ buf_printf (&out, "IV_PLAT=openbsd\n");
+#elif defined(TARGET_DARWIN)
+ buf_printf (&out, "IV_PLAT=mac\n");
+#elif defined(TARGET_NETBSD)
+ buf_printf (&out, "IV_PLAT=netbsd\n");
+#elif defined(TARGET_FREEBSD)
+ buf_printf (&out, "IV_PLAT=freebsd\n");
+#elif defined(WIN32)
+ buf_printf (&out, "IV_PLAT=win\n");
+#endif
+
+ /* push mac addr */
+ {
+ bool get_default_gateway_mac_addr (unsigned char *macaddr);
+ uint8_t macaddr[6];
+ get_default_gateway_mac_addr (macaddr);
+ buf_printf (&out, "IV_HWADDR=%s\n", format_hex_ex (macaddr, 6, 0, 1, ":", &gc));
+ }
+
+ /* push env vars that begin with UV_ */
+ for (e=es->list; e != NULL; e=e->next)
+ {
+ if (e->string)
+ {
+ if (!strncmp(e->string, "UV_", 3) && buf_safe(&out, strlen(e->string)+1))
+ buf_printf (&out, "%s\n", e->string);
+ }
+ }
+
+ if (!write_string(buf, BSTR(&out), -1))
+ goto error;
+ }
+ else
+#endif
+ {
+ if (!write_empty_string (buf)) /* no peer info */
+ goto error;
+ }
+ ret = true;
+
+ error:
+ gc_free (&gc);
+ return ret;
+}
+
+static bool
key_method_2_write (struct buffer *buf, struct tls_session *session)
{
ASSERT (session->opt->key_method == 2);
@@ -3361,6 +3465,16 @@ key_method_2_write (struct buffer *buf, struct tls_session *session)
goto error;
purge_user_pass (&auth_user_pass, false);
}
+ else
+ {
+ if (!write_empty_string (buf)) /* no username */
+ goto error;
+ if (!write_empty_string (buf)) /* no password */
+ goto error;
+ }
+
+ if (!push_peer_info (buf, session))
+ goto error;
/*
* generate tunnel keys if server
@@ -3507,11 +3621,13 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi
int s1 = OPENVPN_PLUGIN_FUNC_SUCCESS;
bool s2 = true;
char *raw_username;
+ bool username_status, password_status;
/* get username/password from plaintext buffer */
ALLOC_OBJ_CLEAR_GC (up, struct user_pass, &gc);
- if (!read_string (buf, up->username, USER_PASS_LEN)
- || !read_string (buf, up->password, USER_PASS_LEN))
+ username_status = read_string (buf, up->username, USER_PASS_LEN);
+ password_status = read_string (buf, up->password, USER_PASS_LEN);
+ if (!username_status || !password_status)
{
CLEAR (*up);
if (!(session->opt->ssl_flags & SSLF_AUTH_USER_PASS_OPTIONAL))
@@ -3532,6 +3648,10 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi
/* call plugin(s) and/or script */
#ifdef MANAGEMENT_DEF_AUTH
+ /* get peer info from control channel */
+ free (multi->peer_info);
+ multi->peer_info = read_string_alloc (buf);
+
if (man_def_auth == KMDA_DEF)
man_def_auth = verify_user_pass_management (session, up, raw_username);
#endif