diff --git a/debian/copyright b/debian/copyright index 01591299..d8f01ee1 100644 --- a/debian/copyright +++ b/debian/copyright @@ -49,7 +49,7 @@ Files: src/json.c src/json.h Copyright: 2012-2014, James McLaughlin et al. License: BSD-2-clause -Files: src/http.c src/http.h src/protocol.h src/resolv.c src/resolv.h src/tls.c src/tls.h +Files: src/resolv.c src/resolv.h Copyright: 2011-2014, Dustin Lundquist License: BSD-2-clause diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 08f60cd3..0799569c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,11 +6,6 @@ else () endif () -set(SS_SNI_SOURCE - http.c - tls.c - ) - set(SS_ACL_SOURCE acl.c rule.c @@ -42,7 +37,6 @@ set(LIBSHADOWSOCKS_LIBEV_SOURCE local.c ${SS_CRYPTO_SOURCE} ${SS_PLUGIN_SOURCE} - ${SS_SNI_SOURCE} ${SS_ACL_SOURCE} ) @@ -68,7 +62,6 @@ set(SS_SERVER_SOURCE server.c ${SS_CRYPTO_SOURCE} ${SS_PLUGIN_SOURCE} - ${SS_SNI_SOURCE} ${SS_ACL_SOURCE} ) diff --git a/src/Makefile.am b/src/Makefile.am index b926e7d4..c261ed0f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -24,9 +24,6 @@ if !BUILD_WINCOMPAT bin_PROGRAMS += ss-manager endif -sni_src = http.c \ - tls.c - acl_src = rule.c \ acl.c @@ -53,7 +50,6 @@ ss_local_SOURCES = local.c \ $(common_src) \ $(crypto_src) \ $(plugin_src) \ - $(sni_src) \ $(acl_src) ss_tunnel_SOURCES = tunnel.c \ @@ -66,7 +62,6 @@ ss_server_SOURCES = resolv.c \ $(common_src) \ $(crypto_src) \ $(plugin_src) \ - $(sni_src) \ ${acl_src} ss_manager_SOURCES = utils.c \ @@ -114,7 +109,7 @@ libshadowsocks_libev_la_LDFLAGS = -version-info $(VERSION_INFO) libshadowsocks_libev_la_LIBADD = $(ss_local_LDADD) include_HEADERS = shadowsocks.h -noinst_HEADERS = acl.h crypto.h stream.h aead.h json.h netutils.h redir.h server.h tls.h uthash.h \ - cache.h http.h local.h plugin.h resolv.h tunnel.h utils.h base64.h ppbloom.h \ - common.h jconf.h manager.h protocol.h rule.h socks5.h udprelay.h winsock.h +noinst_HEADERS = acl.h crypto.h stream.h aead.h json.h netutils.h redir.h server.h uthash.h \ + cache.h local.h plugin.h resolv.h tunnel.h utils.h base64.h ppbloom.h \ + common.h jconf.h manager.h rule.h socks5.h udprelay.h winsock.h EXTRA_DIST = ss-nat diff --git a/src/common.h b/src/common.h index 696248f6..14f1d8db 100644 --- a/src/common.h +++ b/src/common.h @@ -51,7 +51,6 @@ int send_traffic_stat(uint64_t tx, uint64_t rx); #define STAGE_ERROR -1 /* Error detected */ #define STAGE_INIT 0 /* Initial stage */ #define STAGE_HANDSHAKE 1 /* Handshake with client */ -#define STAGE_SNI 3 /* Parse HTTP/SNI header */ #define STAGE_RESOLVE 4 /* Resolve the hostname */ #define STAGE_STREAM 5 /* Stream between client and server */ #define STAGE_STOP 6 /* Server stop to response */ diff --git a/src/http.c b/src/http.c deleted file mode 100644 index 235b37fa..00000000 --- a/src/http.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2011 and 2012, Dustin Lundquist - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include /* malloc() */ -#include /* strncpy() */ -#include /* strncasecmp() */ -#include /* isblank(), isdigit() */ - -#include "http.h" -#include "protocol.h" - -static int parse_http_header(const char *, size_t, char **); -static int get_header(const char *, const char *, int, char **); -static int next_header(const char **, int *); - -static const protocol_t http_protocol_st = { - .default_port = 80, - .parse_packet = &parse_http_header, -}; -const protocol_t *const http_protocol = &http_protocol_st; - -/* - * Parses a HTTP request for the Host: header - * - * Returns: - * >=0 - length of the hostname and updates *hostname - * caller is responsible for freeing *hostname - * -1 - Incomplete request - * -2 - No Host header included in this request - * -3 - Invalid hostname pointer - * -4 - malloc failure - * < -4 - Invalid HTTP request - * - */ -static int -parse_http_header(const char *data, size_t data_len, char **hostname) -{ - int result, i; - - if (hostname == NULL) - return -3; - - if (data_len == 0) - return -1; - - result = get_header("Host:", data, data_len, hostname); - if (result < 0) - return result; - - /* - * if the user specifies the port in the request, it is included here. - * Host: example.com:80 - * Host: [2001:db8::1]:8080 - * so we trim off port portion - */ - for (i = result - 1; i >= 0; i--) - if ((*hostname)[i] == ':') { - (*hostname)[i] = '\0'; - result = i; - break; - } else if (!isdigit((*hostname)[i])) { - break; - } - - return result; -} - -static int -get_header(const char *header, const char *data, int data_len, char **value) -{ - int len, header_len; - - header_len = strlen(header); - - /* loop through headers stopping at first blank line */ - while ((len = next_header(&data, &data_len)) != 0) - if (len > header_len && strncasecmp(header, data, header_len) == 0) { - /* Eat leading whitespace */ - while (header_len < len && isblank((unsigned char)data[header_len])) - header_len++; - - *value = malloc(len - header_len + 1); - if (*value == NULL) - return -4; - - strncpy(*value, data + header_len, len - header_len); - (*value)[len - header_len] = '\0'; - - return len - header_len; - } - - /* If there is no data left after reading all the headers then we do not - * have a complete HTTP request, there must be a blank line */ - if (data_len == 0) - return -1; - - return -2; -} - -static int -next_header(const char **data, int *len) -{ - int header_len; - - /* perhaps we can optimize this to reuse the value of header_len, rather - * than scanning twice. - * Walk our data stream until the end of the header */ - while (*len > 2 && (*data)[0] != '\r' && (*data)[1] != '\n') { - (*len)--; - (*data)++; - } - - /* advanced past the pair */ - *data += 2; - *len -= 2; - - /* Find the length of the next header */ - header_len = 0; - while (*len > header_len + 1 - && (*data)[header_len] != '\r' - && (*data)[header_len + 1] != '\n') - header_len++; - - return header_len; -} diff --git a/src/http.h b/src/http.h deleted file mode 100644 index 914815ae..00000000 --- a/src/http.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2011 and 2012, Dustin Lundquist - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef HTTP_H -#define HTTP_H - -#include -#include "protocol.h" - -const protocol_t *const http_protocol; - -#endif diff --git a/src/local.c b/src/local.c index 97ac6815..de19a1db 100644 --- a/src/local.c +++ b/src/local.c @@ -55,8 +55,6 @@ #include "utils.h" #include "socks5.h" #include "acl.h" -#include "http.h" -#include "tls.h" #include "plugin.h" #include "local.h" #include "winsock.h" @@ -88,7 +86,6 @@ uint64_t tx = 0; uint64_t rx = 0; ev_tstamp last = 0; -int is_remote_dns = 1; // resolve hostname remotely char *stat_path = NULL; #endif @@ -431,48 +428,17 @@ server_handshake(EV_P_ ev_io *w, buffer_t *buf) return -1; } - size_t abuf_len = abuf->len; - int sni_detected = 0; - int hostname_len = 0; - - char *hostname; - uint16_t dst_port = load16_be(abuf->data + abuf->len - 2); - - if (atyp == SOCKS5_ATYP_IPV4 || atyp == SOCKS5_ATYP_IPV6) { - if (dst_port == http_protocol->default_port) - hostname_len = http_protocol->parse_packet(buf->data + 3 + abuf->len, - buf->len - 3 - abuf->len, &hostname); - else if (dst_port == tls_protocol->default_port) - hostname_len = tls_protocol->parse_packet(buf->data + 3 + abuf->len, - buf->len - 3 - abuf->len, &hostname); - if (hostname_len == -1 && buf->len < SOCKET_BUF_SIZE && server->stage != STAGE_SNI) { - if (server_handshake_reply(EV_A_ w, 0, &response) < 0) - return -1; - server->stage = STAGE_SNI; - ev_timer_start(EV_A_ & server->delayed_connect_watcher); - return -1; - } else if (hostname_len > 0) { - sni_detected = 1; - if (acl || verbose) { - hostname_len = hostname_len > MAX_HOSTNAME_LEN ? MAX_HOSTNAME_LEN : hostname_len; - memcpy(host, hostname, hostname_len); - host[hostname_len] = '\0'; - } - ss_free(hostname); - } - } - if (server_handshake_reply(EV_A_ w, 0, &response) < 0) return -1; server->stage = STAGE_STREAM; - buf->len -= (3 + abuf_len); + buf->len -= (3 + abuf->len); if (buf->len > 0) { - memmove(buf->data, buf->data + 3 + abuf_len, buf->len); + memmove(buf->data, buf->data + 3 + abuf->len, buf->len); } if (verbose) { - if (sni_detected || atyp == SOCKS5_ATYP_DOMAIN) + if (atyp == SOCKS5_ATYP_DOMAIN) LOGI("connect to %s:%s", host, port); else if (atyp == SOCKS5_ATYP_IPV4) LOGI("connect to %s:%s", ip, port); @@ -492,7 +458,7 @@ server_handshake(EV_P_ ev_io *w, buffer_t *buf) int err; int host_match = 0; - if (sni_detected || atyp == SOCKS5_ATYP_DOMAIN) + if (atyp == SOCKS5_ATYP_DOMAIN) host_match = acl_match_host(host); if (host_match > 0) @@ -546,7 +512,7 @@ server_handshake(EV_P_ ev_io *w, buffer_t *buf) if (bypass) { if (verbose) { - if (sni_detected || atyp == SOCKS5_ATYP_DOMAIN) + if (atyp == SOCKS5_ATYP_DOMAIN) LOGI("bypass %s:%s", host, port); else if (atyp == 1) LOGI("bypass %s:%s", ip, port); @@ -572,22 +538,6 @@ not_bypass: // Not bypass if (remote == NULL) { remote = create_remote(server->listener, NULL, 0); - - if (sni_detected && acl -#ifdef __ANDROID__ - && is_remote_dns -#endif - ) { - // Reconstruct address buffer - abuf->len = 0; - abuf->data[abuf->len++] = 3; - abuf->data[abuf->len++] = hostname_len; - memcpy(abuf->data + abuf->len, host, hostname_len); - abuf->len += hostname_len; - dst_port = htons(dst_port); - memcpy(abuf->data + abuf->len, &dst_port, 2); - abuf->len += 2; - } } if (remote == NULL) { @@ -614,7 +564,7 @@ not_bypass: server->remote = remote; remote->server = server; - if (buf->len > 0 || sni_detected) { + if (buf->len > 0) { return 0; } else { ev_timer_start(EV_A_ & server->delayed_connect_watcher); @@ -924,8 +874,7 @@ server_recv_cb(EV_P_ ev_io *w, int revents) buf->len = 0; return; - } else if (server->stage == STAGE_HANDSHAKE || - server->stage == STAGE_SNI) { + } else if (server->stage == STAGE_HANDSHAKE) { int ret = server_handshake(EV_A_ w, buf); if (ret) return; @@ -1499,7 +1448,7 @@ main(int argc, char **argv) USE_TTY(); #ifdef __ANDROID__ - while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:i:c:b:a:n:S:huUvV6AD", + while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:i:c:b:a:n:S:huUvV6A", long_options, NULL)) != -1) { #else while ((c = getopt_long(argc, argv, "f:s:p:l:k:t:m:i:c:b:a:n:huUv6A", @@ -1599,9 +1548,6 @@ main(int argc, char **argv) case 'S': stat_path = optarg; break; - case 'D': - is_remote_dns = 0; - break; case 'V': vpn = 1; break; diff --git a/src/local.h b/src/local.h index 9f0a16f7..96ee92a5 100644 --- a/src/local.h +++ b/src/local.h @@ -37,7 +37,6 @@ #include "crypto.h" #include "jconf.h" -#include "protocol.h" #include "common.h" diff --git a/src/protocol.h b/src/protocol.h deleted file mode 100644 index 88b61730..00000000 --- a/src/protocol.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2014, Dustin Lundquist - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef PROTOCOL_H -#define PROTOCOL_H - -#define MAX_HOSTNAME_LEN 256 - -typedef struct protocol { - const int default_port; - int(*const parse_packet) (const char *, size_t, char **); -} protocol_t; - -#endif diff --git a/src/server.c b/src/server.c index 29fb7ae2..2e04fd40 100644 --- a/src/server.c +++ b/src/server.c @@ -57,6 +57,7 @@ #include "plugin.h" #include "server.h" #include "winsock.h" +#include "resolv.h" #ifndef EAGAIN #define EAGAIN EWOULDBLOCK @@ -531,7 +532,7 @@ connect_to_remote(EV_P_ struct addrinfo *res, memset(&remote->olap, 0, sizeof(remote->olap)); remote->connect_ex_done = 0; if (ConnectEx(sockfd, res->ai_addr, res->ai_addrlen, - server->buf->data + server->buf->idx, + server->buf->data + server->buf->idx, server->buf->len, &s, &remote->olap)) { remote->connect_ex_done = 1; break; diff --git a/src/server.h b/src/server.h index 9f5f6814..cdff2c15 100644 --- a/src/server.h +++ b/src/server.h @@ -38,7 +38,6 @@ #include "crypto.h" #include "jconf.h" -#include "resolv.h" #include "netutils.h" #include "common.h" diff --git a/src/tls.c b/src/tls.c deleted file mode 100644 index 5c25445a..00000000 --- a/src/tls.c +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (c) 2011 and 2012, Dustin Lundquist - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This is a minimal TLS implementation intended only to parse the server name - * extension. This was created based primarily on Wireshark dissection of a - * TLS handshake and RFC4366. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include /* malloc() */ -#include /* strncpy() */ -#ifndef __MINGW32__ -#include -#endif - -#include "tls.h" -#include "protocol.h" -#include "utils.h" - -#define TLS_HEADER_LEN 5 -#define TLS_HANDSHAKE_CONTENT_TYPE 0x16 -#define TLS_HANDSHAKE_TYPE_CLIENT_HELLO 0x01 - -#ifndef MIN -#define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) -#endif - -extern int verbose; - -static int parse_tls_header(const char *, size_t, char **); -static int parse_extensions(const char *, size_t, char **); -static int parse_server_name_extension(const char *, size_t, char **); - -static const protocol_t tls_protocol_st = { - .default_port = 443, - .parse_packet = &parse_tls_header, -}; -const protocol_t *const tls_protocol = &tls_protocol_st; - -/* Parse a TLS packet for the Server Name Indication extension in the client - * hello handshake, returning the first servername found (pointer to static - * array) - * - * Returns: - * >=0 - length of the hostname and updates *hostname - * caller is responsible for freeing *hostname - * -1 - Incomplete request - * -2 - No Host header included in this request - * -3 - Invalid hostname pointer - * -4 - malloc failure - * < -4 - Invalid TLS client hello - */ -static int -parse_tls_header(const char *data, size_t data_len, char **hostname) -{ - char tls_content_type; - char tls_version_major; - char tls_version_minor; - size_t pos = TLS_HEADER_LEN; - size_t len; - - if (hostname == NULL) - return -3; - - /* Check that our TCP payload is at least large enough for a TLS header */ - if (data_len < TLS_HEADER_LEN) - return -1; - - /* SSL 2.0 compatible Client Hello - * - * High bit of first byte (length) and content type is Client Hello - * - * See RFC5246 Appendix E.2 - */ - if (data[0] & 0x80 && data[2] == 1) { - if (verbose) - LOGI("Received SSL 2.0 Client Hello which can not support SNI."); - return -2; - } - - tls_content_type = data[0]; - if (tls_content_type != TLS_HANDSHAKE_CONTENT_TYPE) { - if (verbose) - LOGI("Request did not begin with TLS handshake."); - return -5; - } - - tls_version_major = data[1]; - tls_version_minor = data[2]; - if (tls_version_major < 3) { - if (verbose) - LOGI("Received SSL %d.%d handshake which can not support SNI.", - tls_version_major, tls_version_minor); - - return -2; - } - - /* TLS record length */ - len = ((unsigned char)data[3] << 8) + - (unsigned char)data[4] + TLS_HEADER_LEN; - data_len = MIN(data_len, len); - - /* Check we received entire TLS record length */ - if (data_len < len) - return -1; - - /* - * Handshake - */ - if (pos + 1 > data_len) { - return -5; - } - if (data[pos] != TLS_HANDSHAKE_TYPE_CLIENT_HELLO) { - if (verbose) - LOGI("Not a client hello"); - - return -5; - } - - /* Skip past fixed length records: - * 1 Handshake Type - * 3 Length - * 2 Version (again) - * 32 Random - * to Session ID Length - */ - pos += 38; - - /* Session ID */ - if (pos + 1 > data_len) - return -5; - len = (unsigned char)data[pos]; - pos += 1 + len; - - /* Cipher Suites */ - if (pos + 2 > data_len) - return -5; - len = ((unsigned char)data[pos] << 8) + (unsigned char)data[pos + 1]; - pos += 2 + len; - - /* Compression Methods */ - if (pos + 1 > data_len) - return -5; - len = (unsigned char)data[pos]; - pos += 1 + len; - - if (pos == data_len && tls_version_major == 3 && tls_version_minor == 0) { - if (verbose) - LOGI("Received SSL 3.0 handshake without extensions"); - return -2; - } - - /* Extensions */ - if (pos + 2 > data_len) - return -5; - len = ((unsigned char)data[pos] << 8) + (unsigned char)data[pos + 1]; - pos += 2; - - if (pos + len > data_len) - return -5; - return parse_extensions(data + pos, len, hostname); -} - -static int -parse_extensions(const char *data, size_t data_len, char **hostname) -{ - size_t pos = 0; - size_t len; - - /* Parse each 4 bytes for the extension header */ - while (pos + 4 <= data_len) { - /* Extension Length */ - len = ((unsigned char)data[pos + 2] << 8) + - (unsigned char)data[pos + 3]; - - /* Check if it's a server name extension */ - if (data[pos] == 0x00 && data[pos + 1] == 0x00) { - /* There can be only one extension of each type, so we break - * our state and move p to beinnging of the extension here */ - if (pos + 4 + len > data_len) - return -5; - return parse_server_name_extension(data + pos + 4, len, hostname); - } - pos += 4 + len; /* Advance to the next extension header */ - } - /* Check we ended where we expected to */ - if (pos != data_len) - return -5; - - return -2; -} - -static int -parse_server_name_extension(const char *data, size_t data_len, - char **hostname) -{ - size_t pos = 2; /* skip server name list length */ - size_t len; - - while (pos + 3 < data_len) { - len = ((unsigned char)data[pos + 1] << 8) + - (unsigned char)data[pos + 2]; - - if (pos + 3 + len > data_len) - return -5; - - switch (data[pos]) { /* name type */ - case 0x00: /* host_name */ - *hostname = malloc(len + 1); - if (*hostname == NULL) { - ERROR("malloc() failure"); - return -4; - } - - strncpy(*hostname, data + pos + 3, len); - - (*hostname)[len] = '\0'; - - return len; - default: - if (verbose) - LOGI("Unknown server name extension name type: %d", - data[pos]); - } - pos += 3 + len; - } - /* Check we ended where we expected to */ - if (pos != data_len) - return -5; - - return -2; -} diff --git a/src/tls.h b/src/tls.h deleted file mode 100644 index 39989131..00000000 --- a/src/tls.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2011 and 2012, Dustin Lundquist - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef TLS_H -#define TLS_H - -#include "protocol.h" - -const protocol_t *const tls_protocol; - -#endif