diff options
author | Vladislav Grishenko <themiron@mail.ru> | 2017-12-16 02:48:17 +0500 |
---|---|---|
committer | Vladislav Grishenko <themiron@mail.ru> | 2017-12-30 22:49:53 +0500 |
commit | 1f473ffa8df20b929d885d41392a25fe57ded5c2 (patch) | |
tree | d1cad6d7ce03dcedecbfc3be7174d5e30f145491 /accel-pppd/ctrl/sstp | |
parent | d4b00b28c986e89ac3265150fd9928a1c20fe4ea (diff) | |
download | accel-ppp-1f473ffa8df20b929d885d41392a25fe57ded5c2.tar.gz accel-ppp-1f473ffa8df20b929d885d41392a25fe57ded5c2.zip |
sstp: add generic base for parsing http header values, improve host-name checking
Diffstat (limited to 'accel-pppd/ctrl/sstp')
-rw-r--r-- | accel-pppd/ctrl/sstp/sstp.c | 59 |
1 files changed, 41 insertions, 18 deletions
diff --git a/accel-pppd/ctrl/sstp/sstp.c b/accel-pppd/ctrl/sstp/sstp.c index 4255286..ef782e2 100644 --- a/accel-pppd/ctrl/sstp/sstp.c +++ b/accel-pppd/ctrl/sstp/sstp.c @@ -536,6 +536,27 @@ static char *http_getline(struct buffer_t *buf, char *line, size_t size) return line; } +static char *http_getvalue(char *line, const char *name, int len) +{ + int sep; + + if (len < 0) + len = strlen(name); + + if (strncasecmp(line, name, len) != 0) + return NULL; + + line += len; + for (sep = 0; *line; line++) { + if (!sep && *line == ':') + sep = 1; + else if (*line != ' ' && *line != '\t') + break; + } + + return sep ? line : NULL; +} + static int http_send_response(struct sstp_conn_t *conn, char *proto, char *status, char *headers) { char datetime[sizeof("aaa, dd bbb yyyy HH:MM:SS GMT")]; @@ -563,9 +584,9 @@ static int http_send_response(struct sstp_conn_t *conn, char *proto, char *statu static int http_recv_request(struct sstp_conn_t *conn, uint8_t *data, int len) { char linebuf[1024], protobuf[sizeof("HTTP/1.x")]; - char *line, *method, *request, *proto; + char *line, *method, *request, *proto, *host; struct buffer_t buf; - int host_match; + int ret = -1; buf.head = data; buf.end = data + len; @@ -573,13 +594,14 @@ static int http_recv_request(struct sstp_conn_t *conn, uint8_t *data, int len) line = http_getline(&buf, linebuf, sizeof(linebuf)); if (!line) - goto error; + return -1; if (conf_verbose) log_sstp_info2(conn, "recv [HTTP <%s>]\n", line); method = strsep(&line, " "); request = strsep(&line, " "); proto = strsep(&line, " "); + host = NULL; if (!method || !request || !proto) { http_send_response(conn, "HTTP/1.1", "400 Bad Request", NULL); @@ -601,23 +623,20 @@ static int http_recv_request(struct sstp_conn_t *conn, uint8_t *data, int len) snprintf(protobuf, sizeof(protobuf), "%s", proto); proto = protobuf; - host_match = 0; while ((line = http_getline(&buf, linebuf, sizeof(linebuf))) != NULL) { if (*line == '\0') break; if (conf_verbose) log_sstp_info2(conn, "recv [HTTP <%s>]\n", line); - if (conf_hostname && strncasecmp(line, "Host", sizeof("Host") - 1) == 0) { - line += sizeof("Host") - 1; - while (*line == ' ' || *line == ':') - line++; - if (strcasecmp(line, conf_hostname) == 0) - host_match = 1; + if (!host && conf_hostname) { + host = http_getvalue(line, "Host", sizeof("Host") - 1); + if (host) + host = _strdup(host); } } - if (conf_hostname && !host_match) { + if (conf_hostname && strcasecmp(host ? : "", conf_hostname) != 0) { http_send_response(conn, proto, "434 Requested host unavailable", NULL); goto error; } @@ -626,10 +645,11 @@ static int http_recv_request(struct sstp_conn_t *conn, uint8_t *data, int len) "Content-Length: 18446744073709551615\r\n")) { goto error; } - return 0; + ret = 0; error: - return -1; + _free(host); + return ret; } static int http_handler(struct sstp_conn_t *conn, struct buffer_t *buf) @@ -1916,14 +1936,17 @@ static int ssl_servername(SSL *ssl, int *al, void *arg) { const char *servername; + if (!conf_hostname) + return SSL_TLSEXT_ERR_OK; + servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); - if (conf_verbose) - log_ppp_info2("sstp: recv [SSL SNI <%s>]\n", servername ? : ""); + if (conf_verbose) { + log_ppp_info2("sstp: recv [SSL <%s%s>]\n", + servername ? "SNI " : "no SNI", servername ? : ""); + } - if (conf_hostname && (!servername || strcasecmp(servername, conf_hostname) != 0)) { - log_ppp_error("sstp: recv [SSL SNI error]\n"); + if (strcasecmp(servername ? : "", conf_hostname) != 0) return SSL_TLSEXT_ERR_ALERT_FATAL; - } return SSL_TLSEXT_ERR_OK; } |