mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-10-13 18:12:03 +08:00
Use base64 to encode Cookies. That reduces the size of the cookie.
This commit is contained in:
+1
-1
@@ -21,7 +21,7 @@
|
|||||||
* == Auth with legacy client ==
|
* == Auth with legacy client ==
|
||||||
*
|
*
|
||||||
* main worker
|
* main worker
|
||||||
* <------ AUTH_INIT (username)
|
* <------ AUTH_INIT (username, sid)
|
||||||
* AUTH_REP(MSG) ------>
|
* AUTH_REP(MSG) ------>
|
||||||
*
|
*
|
||||||
* (worker terminates as client disconnects)
|
* (worker terminates as client disconnects)
|
||||||
|
|||||||
@@ -981,9 +981,6 @@ int main(int argc, char** argv)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
gnutls_rnd(GNUTLS_RND_NONCE, ws.sid, sizeof(ws.sid));
|
|
||||||
ws.sid_size = sizeof(ws.sid);
|
|
||||||
|
|
||||||
pid = fork();
|
pid = fork();
|
||||||
if (pid == 0) { /* child */
|
if (pid == 0) { /* child */
|
||||||
/* close any open descriptors, and erase
|
/* close any open descriptors, and erase
|
||||||
|
|||||||
+7
-4
@@ -90,11 +90,13 @@ struct proc_st {
|
|||||||
struct sockaddr_storage remote_addr; /* peer address */
|
struct sockaddr_storage remote_addr; /* peer address */
|
||||||
socklen_t remote_addr_len;
|
socklen_t remote_addr_len;
|
||||||
|
|
||||||
/* A unique session identifier used to distinguish
|
/* A unique session identifier used to distinguish sessions
|
||||||
* sessions prior to authentication.
|
* prior to authentication. It is sent as cookie to the client
|
||||||
|
* who re-uses it when it performs authentication in multiple
|
||||||
|
* sessions.
|
||||||
*/
|
*/
|
||||||
uint8_t sid[MAX_SID_SIZE];
|
uint8_t sid[MAX_SID_SIZE];
|
||||||
unsigned sid_size; /* would act as a flag if sid is set */
|
unsigned sid_size; /* acts as a flag if sid is set */
|
||||||
|
|
||||||
/* The DTLS session ID associated with the TLS session
|
/* The DTLS session ID associated with the TLS session
|
||||||
* it is either generated or restored from a cookie.
|
* it is either generated or restored from a cookie.
|
||||||
@@ -113,7 +115,8 @@ struct proc_st {
|
|||||||
char dtls_ciphersuite[MAX_DTLS_CIPHERSUITE_NAME];
|
char dtls_ciphersuite[MAX_DTLS_CIPHERSUITE_NAME];
|
||||||
|
|
||||||
/* if the session is initiated by a cookie the following two are set
|
/* if the session is initiated by a cookie the following two are set
|
||||||
* and are considered when generating an IP address.
|
* and are considered when generating an IP address. That is used to
|
||||||
|
* generate the same address as previously allocated.
|
||||||
*/
|
*/
|
||||||
uint8_t seeds_are_set; /* non zero if the following two elements are set */
|
uint8_t seeds_are_set; /* non zero if the following two elements are set */
|
||||||
uint8_t ipv4_seed[4];
|
uint8_t ipv4_seed[4];
|
||||||
|
|||||||
+10
-14
@@ -33,6 +33,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <ipc.pb-c.h>
|
#include <ipc.pb-c.h>
|
||||||
|
#include <base64.h>
|
||||||
|
|
||||||
#include <vpn.h>
|
#include <vpn.h>
|
||||||
#include "html.h"
|
#include "html.h"
|
||||||
@@ -92,11 +93,11 @@ int get_auth_handler2(worker_st * ws, unsigned http_ver, const char *pmsg)
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (req->sid_cookie_set == 0) {
|
if (req->sid_cookie_set == 0) {
|
||||||
char context[MAX_SID_SIZE*2+1];
|
char context[BASE64_LENGTH(MAX_SID_SIZE)+1];
|
||||||
size_t csize = sizeof(context);
|
size_t csize = sizeof(context);
|
||||||
gnutls_datum_t sid = {ws->sid, ws->sid_size};
|
|
||||||
|
|
||||||
ret = gnutls_hex_encode(&sid, context, &csize);
|
base64_encode((char*)ws->sid, sizeof(ws->sid), (char*)context, csize);
|
||||||
|
|
||||||
ret =
|
ret =
|
||||||
tls_printf(ws->session, "Set-Cookie: webvpncontext=%s; Max-Age=%u; Secure\r\n",
|
tls_printf(ws->session, "Set-Cookie: webvpncontext=%s; Max-Age=%u; Secure\r\n",
|
||||||
context, (unsigned)MAX_ZOMBIE_SECS);
|
context, (unsigned)MAX_ZOMBIE_SECS);
|
||||||
@@ -422,16 +423,11 @@ int auth_cookie(worker_st * ws, void *cookie, size_t cookie_size)
|
|||||||
int post_common_handler(worker_st * ws, unsigned http_ver)
|
int post_common_handler(worker_st * ws, unsigned http_ver)
|
||||||
{
|
{
|
||||||
int ret, size;
|
int ret, size;
|
||||||
char str_cookie[2 * COOKIE_SIZE + 1];
|
char str_cookie[BASE64_LENGTH(COOKIE_SIZE)+1];
|
||||||
char *p;
|
size_t str_cookie_size = sizeof(str_cookie);
|
||||||
unsigned i;
|
|
||||||
char msg[MAX_BANNER_SIZE + 32];
|
char msg[MAX_BANNER_SIZE + 32];
|
||||||
|
|
||||||
p = str_cookie;
|
base64_encode((char*)ws->cookie, sizeof(ws->cookie), (char*)str_cookie, str_cookie_size);
|
||||||
for (i = 0; i < sizeof(ws->cookie); i++) {
|
|
||||||
sprintf(p, "%.2x", (unsigned int)ws->cookie[i]);
|
|
||||||
p += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* reply */
|
/* reply */
|
||||||
tls_cork(ws->session);
|
tls_cork(ws->session);
|
||||||
@@ -703,7 +699,7 @@ int post_auth_handler(worker_st * ws, unsigned http_ver)
|
|||||||
rreq.tls_auth_ok = ws->cert_auth_ok;
|
rreq.tls_auth_ok = ws->cert_auth_ok;
|
||||||
rreq.password = password;
|
rreq.password = password;
|
||||||
rreq.sid.data = ws->sid;
|
rreq.sid.data = ws->sid;
|
||||||
rreq.sid.len = ws->sid_size;
|
rreq.sid.len = sizeof(ws->sid);
|
||||||
|
|
||||||
ret = send_msg_to_main(ws, AUTH_REINIT, &rreq,
|
ret = send_msg_to_main(ws, AUTH_REINIT, &rreq,
|
||||||
(pack_size_func)auth_reinit_msg__get_packed_size,
|
(pack_size_func)auth_reinit_msg__get_packed_size,
|
||||||
@@ -751,9 +747,9 @@ int post_auth_handler(worker_st * ws, unsigned http_ver)
|
|||||||
|
|
||||||
ireq.hostname = req->hostname;
|
ireq.hostname = req->hostname;
|
||||||
if (req->sid_cookie_set != 0) {
|
if (req->sid_cookie_set != 0) {
|
||||||
oclog(ws, LOG_INFO, "updating SID (%u)", ws->sid_size);
|
oclog(ws, LOG_INFO, "updating SID");
|
||||||
ireq.sid.data = ws->sid;
|
ireq.sid.data = ws->sid;
|
||||||
ireq.sid.len = ws->sid_size;
|
ireq.sid.len = sizeof(ws->sid);
|
||||||
ireq.has_sid = 1;
|
ireq.has_sid = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+14
-17
@@ -42,6 +42,7 @@
|
|||||||
#include <gettime.h>
|
#include <gettime.h>
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <html.h>
|
#include <html.h>
|
||||||
|
#include <base64.h>
|
||||||
#include <c-strcase.h>
|
#include <c-strcase.h>
|
||||||
#include <worker-bandwidth.h>
|
#include <worker-bandwidth.h>
|
||||||
|
|
||||||
@@ -186,6 +187,7 @@ int url_cb(http_parser * parser, const char *at, size_t length)
|
|||||||
static void value_check(struct worker_st *ws, struct http_req_st *req)
|
static void value_check(struct worker_st *ws, struct http_req_st *req)
|
||||||
{
|
{
|
||||||
unsigned length;
|
unsigned length;
|
||||||
|
int ret;
|
||||||
size_t nlen;
|
size_t nlen;
|
||||||
uint8_t *p;
|
uint8_t *p;
|
||||||
char *token;
|
char *token;
|
||||||
@@ -312,18 +314,13 @@ static void value_check(struct worker_st *ws, struct http_req_st *req)
|
|||||||
p += 7;
|
p += 7;
|
||||||
length -= 7;
|
length -= 7;
|
||||||
|
|
||||||
if (length < COOKIE_SIZE * 2) {
|
|
||||||
req->cookie_set = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
length = COOKIE_SIZE * 2;
|
|
||||||
nlen = sizeof(req->cookie);
|
nlen = sizeof(req->cookie);
|
||||||
gnutls_hex2bin((void *)p, length, req->cookie, &nlen);
|
ret = base64_decode((char*)p, length, (char*)req->cookie, &nlen);
|
||||||
|
if (ret == 0 || nlen != COOKIE_SIZE) {
|
||||||
if (nlen < COOKIE_SIZE) {
|
|
||||||
req->cookie_set = 0;
|
req->cookie_set = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
req->cookie_set = 1;
|
req->cookie_set = 1;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
@@ -332,20 +329,14 @@ static void value_check(struct worker_st *ws, struct http_req_st *req)
|
|||||||
p += 14;
|
p += 14;
|
||||||
length -= 14;
|
length -= 14;
|
||||||
|
|
||||||
if (length < sizeof(ws->sid) * 2) {
|
|
||||||
req->sid_cookie_set = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
length = sizeof(ws->sid) * 2;
|
|
||||||
nlen = sizeof(ws->sid);
|
nlen = sizeof(ws->sid);
|
||||||
gnutls_hex2bin((void *)p, length, ws->sid, &nlen);
|
ret = base64_decode((char*)p, length, (char*)ws->sid, &nlen);
|
||||||
|
if (ret == 0 || nlen != sizeof(ws->sid)) {
|
||||||
if (nlen < sizeof(ws->sid)) {
|
|
||||||
req->sid_cookie_set = 0;
|
req->sid_cookie_set = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
req->sid_cookie_set = 1;
|
req->sid_cookie_set = 1;
|
||||||
ws->sid_size = nlen;
|
|
||||||
oclog(ws, LOG_ERR, "received sid: %.*s", length, p);
|
oclog(ws, LOG_ERR, "received sid: %.*s", length, p);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -626,6 +617,12 @@ void vpn_server(struct worker_st *ws)
|
|||||||
else
|
else
|
||||||
ws->proto = AF_INET6;
|
ws->proto = AF_INET6;
|
||||||
|
|
||||||
|
ret = gnutls_rnd(GNUTLS_RND_NONCE, ws->sid, sizeof(ws->sid));
|
||||||
|
if (ret < 0) {
|
||||||
|
oclog(ws, LOG_ERR, "Error generating SID");
|
||||||
|
exit_worker(ws);
|
||||||
|
}
|
||||||
|
|
||||||
/* initialize the session */
|
/* initialize the session */
|
||||||
ret = gnutls_init(&session, GNUTLS_SERVER);
|
ret = gnutls_init(&session, GNUTLS_SERVER);
|
||||||
GNUTLS_FATAL_ERR(ret);
|
GNUTLS_FATAL_ERR(ret);
|
||||||
|
|||||||
@@ -109,7 +109,6 @@ typedef struct worker_st {
|
|||||||
|
|
||||||
/* inique session identifier */
|
/* inique session identifier */
|
||||||
uint8_t sid[MAX_SID_SIZE];
|
uint8_t sid[MAX_SID_SIZE];
|
||||||
unsigned sid_size;
|
|
||||||
|
|
||||||
int cmd_fd;
|
int cmd_fd;
|
||||||
int conn_fd;
|
int conn_fd;
|
||||||
|
|||||||
Reference in New Issue
Block a user