diff --git a/src/ocserv-args.c b/src/ocserv-args.c index 39232d0e..f09df211 100644 --- a/src/ocserv-args.c +++ b/src/ocserv-args.c @@ -2,7 +2,7 @@ * * DO NOT EDIT THIS FILE (ocserv-args.c) * - * It has been AutoGen-ed February 7, 2013 at 08:21:00 PM by AutoGen 5.16 + * It has been AutoGen-ed February 8, 2013 at 10:02:15 AM by AutoGen 5.16 * From the definitions ocserv-args.def * and the template file options * diff --git a/src/ocserv-args.h b/src/ocserv-args.h index a8083d52..b2cc36f1 100644 --- a/src/ocserv-args.h +++ b/src/ocserv-args.h @@ -2,7 +2,7 @@ * * DO NOT EDIT THIS FILE (ocserv-args.h) * - * It has been AutoGen-ed February 7, 2013 at 08:20:59 PM by AutoGen 5.16 + * It has been AutoGen-ed February 8, 2013 at 10:02:15 AM by AutoGen 5.16 * From the definitions ocserv-args.def * and the template file options * diff --git a/src/tlslib.c b/src/tlslib.c index a79ef5e3..6d7f35f6 100644 --- a/src/tlslib.c +++ b/src/tlslib.c @@ -320,3 +320,25 @@ int ret; return 0; } + +void tls_cork(gnutls_session_t session) +{ +#if GNUTLS_VERSION_NUMBER > 0x030107 + gnutls_record_cork(session); +#endif +} + +int tls_uncork(gnutls_session_t session) +{ +#if GNUTLS_VERSION_NUMBER > 0x030107 +int ret; + + do { + ret = gnutls_record_cork(session); + } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); + + return ret; +#else + return 0; +#endif +} diff --git a/src/tlslib.h b/src/tlslib.h index 539059af..522e1023 100644 --- a/src/tlslib.h +++ b/src/tlslib.h @@ -14,6 +14,9 @@ ssize_t tls_recv(gnutls_session_t session, void *data, size_t data_size); ssize_t tls_send(gnutls_session_t session, const void *data, size_t data_size); +void tls_cork(gnutls_session_t session); +int tls_uncork(gnutls_session_t session); + void tls_global_init(struct main_server_st* s); int tls_global_init_client(struct worker_st* ws); diff --git a/src/worker-auth.c b/src/worker-auth.c index 662376b3..35d1eb8b 100644 --- a/src/worker-auth.c +++ b/src/worker-auth.c @@ -56,14 +56,40 @@ const char login_msg[] = "\r\n" int get_auth_handler(worker_st *ws) { - tls_puts(ws->session, "HTTP/1.1 200 OK\r\n"); - tls_puts(ws->session, "Connection: close\r\n"); - tls_puts(ws->session, "Content-Type: text/xml\r\n"); - tls_printf(ws->session, "Content-Length: %u\r\n", (unsigned int)sizeof(login_msg)-1); - tls_puts(ws->session, "X-Transcend-Version: 1\r\n"); - tls_puts(ws->session, "\r\n"); +int ret; - tls_send(ws->session, login_msg, sizeof(login_msg)-1); + tls_cork(ws->session); + ret = tls_puts(ws->session, "HTTP/1.1 200 OK\r\n"); + if (ret < 0) + return -1; + + ret = tls_puts(ws->session, "Connection: close\r\n"); + if (ret < 0) + return -1; + + ret = tls_puts(ws->session, "Content-Type: text/xml\r\n"); + if (ret < 0) + return -1; + + ret = tls_printf(ws->session, "Content-Length: %u\r\n", (unsigned int)sizeof(login_msg)-1); + if (ret < 0) + return -1; + + ret = tls_puts(ws->session, "X-Transcend-Version: 1\r\n"); + if (ret < 0) + return -1; + + ret = tls_puts(ws->session, "\r\n"); + if (ret < 0) + return -1; + + ret = tls_send(ws->session, login_msg, sizeof(login_msg)-1); + if (ret < 0) + return -1; + + ret = tls_uncork(ws->session); + if (ret < 0) + return -1; return 0; @@ -377,20 +403,41 @@ struct cmd_auth_req_st areq; } /* reply */ + tls_cork(ws->session); - tls_puts(ws->session, "HTTP/1.1 200 OK\r\n"); - tls_puts(ws->session, "Content-Type: text/xml\r\n"); - tls_printf(ws->session, "Content-Length: %u\r\n", (unsigned)(sizeof(SUCCESS_MSG)-1)); - tls_puts(ws->session, "X-Transcend-Version: 1\r\n"); - tls_printf(ws->session, "Set-Cookie: webvpn=%s\r\n", str_cookie); - tls_puts(ws->session, "\r\n"SUCCESS_MSG); + ret = tls_puts(ws->session, "HTTP/1.1 200 OK\r\n"); + if (ret < 0) + return -1; + + ret = tls_puts(ws->session, "Content-Type: text/xml\r\n"); + if (ret < 0) + return -1; + + ret = tls_printf(ws->session, "Content-Length: %u\r\n", (unsigned)(sizeof(SUCCESS_MSG)-1)); + if (ret < 0) + return -1; + + ret = tls_puts(ws->session, "X-Transcend-Version: 1\r\n"); + if (ret < 0) + return -1; + + ret = tls_printf(ws->session, "Set-Cookie: webvpn=%s\r\n", str_cookie); + if (ret < 0) + return -1; + + ret = tls_puts(ws->session, "\r\n"SUCCESS_MSG); + if (ret < 0) + return -1; + + ret = tls_uncork(ws->session); + if (ret < 0) + return -1; return 0; auth_fail: - tls_puts(ws->session, "HTTP/1.1 503 Service Unavailable\r\n"); tls_printf(ws->session, - "X-Reason: %s\r\n\r\n", reason); + "HTTP/1.1 503 Service Unavailable\r\nX-Reason: %s\r\n\r\n", reason); tls_fatal_close(ws->session, GNUTLS_A_ACCESS_DENIED); exit(1); } @@ -472,13 +519,36 @@ struct cmd_auth_req_st areq; } /* reply */ + tls_cork(ws->session); + + ret = tls_puts(ws->session, "HTTP/1.1 200 OK\r\n"); + if (ret < 0) + return -1; + + ret = tls_puts(ws->session, "Content-Type: text/xml\r\n"); + if (ret < 0) + return -1; + + ret = tls_printf(ws->session, "Content-Length: %u\r\n", (unsigned)(sizeof(SUCCESS_MSG)-1)); + if (ret < 0) + return -1; + + ret = tls_puts(ws->session, "X-Transcend-Version: 1\r\n"); + if (ret < 0) + return -1; + + ret = tls_printf(ws->session, "Set-Cookie: webvpn=%s\r\n", str_cookie); + if (ret < 0) + return -1; + + ret = tls_puts(ws->session, "\r\n"SUCCESS_MSG); + if (ret < 0) + return -1; + + ret = tls_uncork(ws->session); + if (ret < 0) + return -1; - tls_puts(ws->session, "HTTP/1.1 200 OK\r\n"); - tls_puts(ws->session, "Content-Type: text/xml\r\n"); - tls_printf(ws->session, "Content-Length: %u\r\n", (unsigned)(sizeof(SUCCESS_MSG)-1)); - tls_puts(ws->session, "X-Transcend-Version: 1\r\n"); - tls_printf(ws->session, "Set-Cookie: webvpn=%s\r\n", str_cookie); - tls_puts(ws->session, "\r\n"SUCCESS_MSG); return 0; @@ -486,9 +556,8 @@ ask_auth: return get_auth_handler(ws); auth_fail: - tls_puts(ws->session, "HTTP/1.1 503 Service Unavailable\r\n"); tls_printf(ws->session, - "X-Reason: %s\r\n\r\n", reason); + "HTTP/1.1 503 Service Unavailable\r\nX-Reason: %s\r\n\r\n", reason); tls_fatal_close(ws->session, GNUTLS_A_ACCESS_DENIED); exit(1); } diff --git a/src/worker-vpn.c b/src/worker-vpn.c index b2b57df7..3c376141 100644 --- a/src/worker-vpn.c +++ b/src/worker-vpn.c @@ -669,6 +669,7 @@ int c; return; } +#define SEND_ERR(x) if (x<0) goto send_error static int connect_handler(worker_st *ws) { int ret; @@ -732,10 +733,15 @@ unsigned mtu_overhead, dtls_mtu = 0, tls_mtu = 0; return -1; } - tls_puts(ws->session, "HTTP/1.1 200 CONNECTED\r\n"); + tls_cork(ws->session); + ret = tls_puts(ws->session, "HTTP/1.1 200 CONNECTED\r\n"); + SEND_ERR(ret); - tls_puts(ws->session, "X-CSTP-Version: 1\r\n"); - tls_puts(ws->session, "X-CSTP-DPD: 60\r\n"); + ret = tls_puts(ws->session, "X-CSTP-Version: 1\r\n"); + SEND_ERR(ret); + + ret = tls_puts(ws->session, "X-CSTP-DPD: 60\r\n"); + SEND_ERR(ret); ws->udp_state = UP_DISABLED; if (req->master_secret_set != 0) { @@ -746,37 +752,50 @@ unsigned mtu_overhead, dtls_mtu = 0, tls_mtu = 0; if (vinfo.ipv4) { oclog(ws, LOG_DEBUG, "sending IPv4 %s", vinfo.ipv4); - tls_printf(ws->session, "X-CSTP-Address: %s\r\n", vinfo.ipv4); + ret = tls_printf(ws->session, "X-CSTP-Address: %s\r\n", vinfo.ipv4); + SEND_ERR(ret); - if (vinfo.ipv4_netmask) - tls_printf(ws->session, "X-CSTP-Netmask: %s\r\n", vinfo.ipv4_netmask); - if (vinfo.ipv4_dns) - tls_printf(ws->session, "X-CSTP-DNS: %s\r\n", vinfo.ipv4_dns); + if (vinfo.ipv4_netmask) { + ret = tls_printf(ws->session, "X-CSTP-Netmask: %s\r\n", vinfo.ipv4_netmask); + SEND_ERR(ret); + } + if (vinfo.ipv4_dns) { + ret = tls_printf(ws->session, "X-CSTP-DNS: %s\r\n", vinfo.ipv4_dns); + SEND_ERR(ret); + } } if (vinfo.ipv6) { oclog(ws, LOG_DEBUG, "sending IPv6 %s", vinfo.ipv6); - tls_printf(ws->session, "X-CSTP-Address: %s\r\n", vinfo.ipv6); + ret = tls_printf(ws->session, "X-CSTP-Address: %s\r\n", vinfo.ipv6); + SEND_ERR(ret); - if (vinfo.ipv6_netmask) - tls_printf(ws->session, "X-CSTP-Netmask: %s\r\n", vinfo.ipv6_netmask); - if (vinfo.ipv6_dns) - tls_printf(ws->session, "X-CSTP-DNS: %s\r\n", vinfo.ipv6_dns); + if (vinfo.ipv6_netmask) { + ret = tls_printf(ws->session, "X-CSTP-Netmask: %s\r\n", vinfo.ipv6_netmask); + SEND_ERR(ret); + } + if (vinfo.ipv6_dns) { + ret = tls_printf(ws->session, "X-CSTP-DNS: %s\r\n", vinfo.ipv6_dns); + SEND_ERR(ret); + } } for (i=0;isession, + ret = tls_printf(ws->session, "X-CSTP-Split-Include: %s\r\n", vinfo.routes[i]); + SEND_ERR(ret); } - tls_printf(ws->session, "X-CSTP-Keepalive: %u\r\n", ws->config->keepalive); + ret = tls_printf(ws->session, "X-CSTP-Keepalive: %u\r\n", ws->config->keepalive); + SEND_ERR(ret); tls_mtu = vinfo.mtu - 8; if (req->cstp_mtu > 0) tls_mtu = MIN(tls_mtu, req->cstp_mtu); tls_mtu = MIN(sizeof(buffer)-8, tls_mtu); - tls_printf(ws->session, "X-CSTP-MTU: %u\r\n", tls_mtu); + ret = tls_printf(ws->session, "X-CSTP-MTU: %u\r\n", tls_mtu); + SEND_ERR(ret); if (ws->udp_state != UP_DISABLED) { p = (char*)buffer; @@ -784,12 +803,20 @@ unsigned mtu_overhead, dtls_mtu = 0, tls_mtu = 0; sprintf(p, "%.2x", (unsigned int)ws->session_id[i]); p+=2; } - tls_printf(ws->session, "X-DTLS-Session-ID: %s\r\n", buffer); + ret = tls_printf(ws->session, "X-DTLS-Session-ID: %s\r\n", buffer); + SEND_ERR(ret); - tls_printf(ws->session, "X-DTLS-Port: %u\r\n", ws->config->udp_port); - tls_puts(ws->session, "X-DTLS-ReKey-Time: 86400\r\n"); - tls_printf(ws->session, "X-DTLS-Keepalive: %u\r\n", ws->config->keepalive); - tls_puts(ws->session, "X-DTLS-CipherSuite: "OPENSSL_CIPHERSUITE"\r\n"); + ret = tls_printf(ws->session, "X-DTLS-Port: %u\r\n", ws->config->udp_port); + SEND_ERR(ret); + + ret = tls_puts(ws->session, "X-DTLS-ReKey-Time: 86400\r\n"); + SEND_ERR(ret); + + ret = tls_printf(ws->session, "X-DTLS-Keepalive: %u\r\n", ws->config->keepalive); + SEND_ERR(ret); + + ret = tls_puts(ws->session, "X-DTLS-CipherSuite: "OPENSSL_CIPHERSUITE"\r\n"); + SEND_ERR(ret); /* assume that if IPv6 is used over TCP then the same would be used over UDP */ if (ws->proto == AF_INET) @@ -807,9 +834,14 @@ unsigned mtu_overhead, dtls_mtu = 0, tls_mtu = 0; tls_printf(ws->session, "X-DTLS-MTU: %u\r\n", dtls_mtu); } - tls_puts(ws->session, "X-CSTP-Banner: Welcome\r\n"); - tls_puts(ws->session, "\r\n"); - + ret = tls_puts(ws->session, "X-CSTP-Banner: Welcome\r\n"); + SEND_ERR(ret); + + ret = tls_puts(ws->session, "\r\n"); + SEND_ERR(ret); + + ret = tls_uncork(ws->session); + SEND_ERR(ret); for(;;) { FD_ZERO(&rfds); @@ -1005,6 +1037,10 @@ hsk_restart: } return 0; + +send_error: + oclog(ws, LOG_DEBUG, "Error sending data\n"); + exit(1); } static