From 0a0b51ab37e0a2016582ea7721335e1fd5eb65f1 Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Tue, 10 Jun 2014 10:08:43 +0200 Subject: [PATCH] Added work-around for openconnect v3.20 That version of openconnect requires some strict format on the XML messages. Thus we send it, what it expects. --- src/vpn.h | 2 +- src/worker-auth.c | 84 ++++++++++++++++++++++++++++++++++++++++------- src/worker-vpn.c | 20 +++++++---- src/worker.h | 1 + 4 files changed, 88 insertions(+), 19 deletions(-) diff --git a/src/vpn.h b/src/vpn.h index 6b57c611..05672431 100644 --- a/src/vpn.h +++ b/src/vpn.h @@ -281,7 +281,7 @@ struct main_server_st; #define MAX_BANNER_SIZE 256 #define MAX_USERNAME_SIZE 64 -#define MAX_AGENT_NAME 32 +#define MAX_AGENT_NAME 48 #define MAX_PASSWORD_SIZE 64 #define TLS_MASTER_SIZE 48 #define MAX_HOSTNAME_SIZE MAX_USERNAME_SIZE diff --git a/src/worker-auth.c b/src/worker-auth.c index 34f72289..361f39d6 100644 --- a/src/worker-auth.c +++ b/src/worker-auth.c @@ -46,15 +46,22 @@ #define VERSION_MSG "0.1(1)\n" -#define SUCCESS_MSG_HEAD "\n" \ - "\n" \ - VERSION_MSG \ - "\n" \ - "SSL VPN Service" +static const char oc_success_msg_head[] = "\n" + "\n" + VERSION_MSG + "\n" + "SSL VPN Service"; -#define SUCCESS_MSG_FOOT "\n" +static const char oc_success_msg_foot[] = "\n"; -static const char login_msg_user_start[] = +static const char ocv3_success_msg_head[] = "\n" + "\n" + "SSL VPN Service"; + +static const char ocv3_success_msg_foot[] = "\n"; + + +static const char oc_login_msg_user_start[] = "\n" "\n" VERSION_MSG @@ -63,22 +70,43 @@ static const char login_msg_user_start[] = "
\n" "\n"; -static const char login_msg_user_end[] = +static const char oc_login_msg_user_end[] = "
\n" "
"; -static const char login_msg_no_user_start[] = +static const char oc_login_msg_no_user_start[] = "\n" "\n" VERSION_MSG "\n" ""; -static const char login_msg_no_user_end[] = +static const char oc_login_msg_no_user_end[] = "\n" "
\n" "\n" "
\n"; +static const char ocv3_login_msg_user_start[] = + "\n" + "\n" + "Please enter your username\n" + "
\n" + "\n"; + +static const char ocv3_login_msg_user_end[] = + "
\n"; + +static const char ocv3_login_msg_no_user_start[] = + "\n" + "\n" + ""; + +static const char ocv3_login_msg_no_user_end[] = + "\n" + "
\n" + "\n" + "
\n"; + static int get_cert_info(worker_st * ws); static int append_group_idx(worker_st * ws, str_st *str, unsigned i) @@ -133,6 +161,22 @@ int get_auth_handler2(worker_st * ws, unsigned http_ver, const char *pmsg) char temp[128]; unsigned int i, j; str_st str; + const char *login_msg_user_start; + const char *login_msg_user_end; + const char *login_msg_no_user_start; + const char *login_msg_no_user_end; + + if (ws->req.user_agent_type == AGENT_OPENCONNECT_V3) { + login_msg_user_start = ocv3_login_msg_user_start; + login_msg_user_end = ocv3_login_msg_user_end; + login_msg_no_user_start = ocv3_login_msg_no_user_start; + login_msg_no_user_end = ocv3_login_msg_no_user_end; + } else { + login_msg_user_start = oc_login_msg_user_start; + login_msg_user_end = oc_login_msg_user_end; + login_msg_no_user_start = oc_login_msg_no_user_start; + login_msg_no_user_end = oc_login_msg_no_user_end; + } str_init(&str, ws); @@ -793,6 +837,22 @@ int post_common_handler(worker_st * ws, unsigned http_ver) char str_cookie[BASE64_LENGTH(ws->cookie_size)+1]; size_t str_cookie_size = sizeof(str_cookie); char msg[MAX_BANNER_SIZE + 32]; + const char *success_msg_head; + const char *success_msg_foot; + unsigned success_msg_head_size; + unsigned success_msg_foot_size; + + if (ws->req.user_agent_type == AGENT_OPENCONNECT_V3) { + success_msg_head = ocv3_success_msg_head; + success_msg_foot = ocv3_success_msg_foot; + success_msg_head_size = sizeof(ocv3_success_msg_head)-1; + success_msg_foot_size = sizeof(ocv3_success_msg_foot)-1; + } else { + success_msg_head = oc_success_msg_head; + success_msg_foot = oc_success_msg_foot; + success_msg_head_size = sizeof(oc_success_msg_head)-1; + success_msg_foot_size = sizeof(oc_success_msg_foot)-1; + } base64_encode((char *)ws->cookie, ws->cookie_size, (char *)str_cookie, str_cookie_size); @@ -823,7 +883,7 @@ int post_common_handler(worker_st * ws, unsigned http_ver) size = 0; } - size += (sizeof(SUCCESS_MSG_HEAD) - 1) + (sizeof(SUCCESS_MSG_FOOT) - 1); + size += success_msg_head_size + success_msg_foot_size; ret = tls_printf(ws->session, "Content-Length: %u\r\n", (unsigned)size); if (ret < 0) @@ -867,7 +927,7 @@ int post_common_handler(worker_st * ws, unsigned http_ver) ret = tls_printf(ws->session, - "\r\n" SUCCESS_MSG_HEAD "%s" SUCCESS_MSG_FOOT, msg); + "\r\n%s%s%s", success_msg_head, msg, success_msg_foot); if (ret < 0) return -1; diff --git a/src/worker-vpn.c b/src/worker-vpn.c index 750b376f..6fa844ba 100644 --- a/src/worker-vpn.c +++ b/src/worker-vpn.c @@ -277,14 +277,22 @@ static void value_check(struct worker_st *ws, struct http_req_st *req) break; case HEADER_USER_AGENT: if (value_length + 1 > MAX_AGENT_NAME) { - req->user_agent[0] = 0; - goto cleanup; + memcpy(req->user_agent, value, MAX_AGENT_NAME-1); + req->user_agent[MAX_AGENT_NAME-1] = 0; + } else { + memcpy(req->user_agent, value, value_length); + req->user_agent[value_length] = 0; } - memcpy(req->user_agent, value, value_length); - req->user_agent[value_length] = 0; - if (strstr(req->user_agent, "Open Any") != NULL) - req->user_agent_type = AGENT_OPENCONNECT; + oclog(ws, LOG_DEBUG, + "User-agent: '%s'", req->user_agent); + + if (strncasecmp(req->user_agent, "Open Any", 8) == 0) { + if (strncmp(req->user_agent, "Open AnyConnect VPN Agent v3", 28) == 0) + req->user_agent_type = AGENT_OPENCONNECT_V3; + else + req->user_agent_type = AGENT_OPENCONNECT; + } break; case HEADER_DTLS_CIPHERSUITE: diff --git a/src/worker.h b/src/worker.h index 3fa48801..b6e27a5e 100644 --- a/src/worker.h +++ b/src/worker.h @@ -85,6 +85,7 @@ enum { enum { AGENT_UNKNOWN, + AGENT_OPENCONNECT_V3, AGENT_OPENCONNECT };