Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
thibaultcha committed Aug 16, 2023
1 parent 254cd3b commit 3243acc
Show file tree
Hide file tree
Showing 9 changed files with 536 additions and 188 deletions.
130 changes: 85 additions & 45 deletions src/common/ngx_wasm_socket_tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ static ngx_int_t ngx_wasm_socket_tcp_ssl_handshake(ngx_wasm_socket_tcp_t *sock);
static void ngx_wasm_socket_tcp_ssl_handshake_handler(ngx_connection_t *c);
static ngx_int_t ngx_wasm_socket_tcp_ssl_handshake_done(ngx_connection_t *c);
static ngx_int_t ngx_wasm_socket_tcp_ssl_set_server_name(ngx_connection_t *c,
ngx_str_t *name);
ngx_wasm_socket_tcp_t *sock);
#endif


Expand Down Expand Up @@ -119,7 +119,7 @@ ngx_wasm_socket_tcp_resume(ngx_wasm_socket_tcp_t *sock)

ngx_int_t
ngx_wasm_socket_tcp_init(ngx_wasm_socket_tcp_t *sock,
ngx_str_t *host, unsigned tls, ngx_wasm_subsys_env_t *env)
ngx_str_t *host, unsigned tls, ngx_str_t *sni, ngx_wasm_subsys_env_t *env)
{
u_char *p, *last;
static ngx_str_t uds_prefix = ngx_string("unix:");
Expand Down Expand Up @@ -163,6 +163,10 @@ ngx_wasm_socket_tcp_init(ngx_wasm_socket_tcp_t *sock,
#if (NGX_SSL)
sock->ssl_conf = tls ? env->ssl_conf : NULL;
sock->url.default_port = tls ? 443 : 80;

if (tls) {
sock->sni = sni;
}
#else
sock->url.default_port = 80;
#endif
Expand All @@ -175,7 +179,7 @@ ngx_wasm_socket_tcp_init(ngx_wasm_socket_tcp_t *sock,

#if (!NGX_HAVE_UNIX_DOMAIN)
ngx_wasm_log_error(NGX_LOG_ERR, sock->log, 0,
"host \"%V\" requires unix domain socket support",
"host at \"%V\" requires unix domain socket support",
host);
return NGX_ERROR;
#endif
Expand Down Expand Up @@ -322,13 +326,13 @@ ngx_wasm_socket_tcp_connect(ngx_wasm_socket_tcp_t *sock)
&sock->resolved.host);

rc = ngx_wasm_socket_tcp_connect_peer(sock);
if (sock->connected) {
#if (NGX_SSL)
if (sock->connected) {
if (sock->ssl_conf) {
return ngx_wasm_socket_tcp_ssl_handshake(sock);
}
#endif
}
#endif
return rc;
}

Expand Down Expand Up @@ -622,7 +626,7 @@ ngx_wasm_socket_tcp_ssl_handshake(ngx_wasm_socket_tcp_t *sock)

dd("tls connection created");

rc = ngx_wasm_socket_tcp_ssl_set_server_name(c, &sock->host);
rc = ngx_wasm_socket_tcp_ssl_set_server_name(c, sock);
if (rc == NGX_ERROR) {
return NGX_ERROR;
}
Expand Down Expand Up @@ -681,9 +685,10 @@ ngx_wasm_socket_tcp_ssl_handshake_done(ngx_connection_t *c)
}

if (sock->ssl_conf->verify_cert) {
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
"wasm tcp socket verifying tls certificate for \"%V\"",
&sock->host);
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
"wasm tcp socket verifying tls certificate for \"%V\" "
"(sni: \"%V\")",
&sock->host, &sock->ssl_server_name);

rc = SSL_get_verify_result(c->ssl->connection);
if (rc != X509_V_OK) {
Expand All @@ -699,14 +704,16 @@ ngx_wasm_socket_tcp_ssl_handshake_done(ngx_connection_t *c)
}

if (sock->ssl_conf->verify_host) {
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
"wasm tcp socket checking tls certificate "
"host for \"%V\"", &sock->host);
"CN for \"%V\" (sni: \"%V\")",
&sock->host, &sock->ssl_server_name);

if (ngx_ssl_check_host(c, &sock->host) != NGX_OK) {
if (ngx_ssl_check_host(c, &sock->ssl_server_name) != NGX_OK) {
ngx_wasm_socket_tcp_err(sock,
"tls certificate does not match \"%V\"",
&sock->host);
"tls certificate CN "
"does not match \"%V\" sni",
&sock->ssl_server_name);
return NGX_ERROR;
}

Expand All @@ -728,74 +735,101 @@ ngx_wasm_socket_tcp_ssl_handshake_done(ngx_connection_t *c)

/* Modified from `ngx_http_upstream_ssl_name` */
static ngx_int_t
ngx_wasm_socket_tcp_ssl_set_server_name(ngx_connection_t *c, ngx_str_t *name)
ngx_wasm_socket_tcp_ssl_set_server_name(ngx_connection_t *c,
ngx_wasm_socket_tcp_t *sock)
{
u_char *p, *last;
size_t len;
ngx_int_t rc;
ngx_str_t *name;
u_char *p, *last, *sni = NULL;

if (sock->sni) {
name = sock->sni;

if (name->len == 0) {
goto done;
} else {
name = &sock->host;
}

/*
/**
* ssl name here may contain port, notably if derived from $proxy_host
* or $http_host; we have to strip it
*/

p = name->data;
len = name->len;
last = name->data + name->len;

if (*p == '[') {
p = ngx_strlchr(p, last, ']');
if (p) {
if (*p == '[') {
p = ngx_strlchr(p, last, ']');

if (p == NULL) {
p = name->data;
if (p == NULL) {
p = name->data;
}
}
}

p = ngx_strlchr(p, last, ':');

if (p) {
name->len = p - name->data;
p = ngx_strlchr(p, last, ':');
if (p) {
len = p - name->data;
}
}

/* as per RFC 6066, literal IPv4 and IPv6 addresses are not permitted */

if (name->len == 0 || *name->data == '[') {
goto done;
}

if (ngx_inet_addr(name->data, name->len) != INADDR_NONE) {
goto done;
if (len == 0
|| (name->data && *name->data == '[')
|| ngx_inet_addr(name->data, len) != INADDR_NONE)
{
ngx_wasm_socket_tcp_err(sock,
"could not derive tls sni from host (\"%V\")",
&sock->host);
goto error;
}

/*
/**
* SSL_set_tlsext_host_name() needs a null-terminated string,
* hence we explicitly null-terminate name here
*/

p = ngx_pnalloc(c->pool, name->len + 1);
if (p == NULL) {
return NGX_ERROR;
sni = ngx_pnalloc(sock->pool, len + 1);
if (sni == NULL) {
goto error;
}

(void) ngx_cpystrn(p, name->data, name->len + 1);
(void) ngx_cpystrn(sni, name->data, len + 1);

name->data = p;
sock->ssl_server_name.len = len;
sock->ssl_server_name.data = sni;

if (SSL_set_tlsext_host_name(c->ssl->connection, (char *) name->data)
if (SSL_set_tlsext_host_name(c->ssl->connection, (char *) sni)
== 0)
{
ngx_ssl_error(NGX_LOG_ERR, c->log, 0,
"SSL_set_tlsext_host_name(\"%s\") failed", name->data);
return NGX_ERROR;
"SSL_set_tlsext_host_name(\"%s\") failed", sni);
goto error;
}

ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
"wasm tcp socket upstream tls server name: \"%V\"", name);
"wasm tcp socket upstream tls server name: \"%s\"", sni);

rc = NGX_OK;

goto done;

error:

if (sni) {
ngx_pfree(c->pool, sni);
}

sock->ssl_server_name.len = 0;
sock->ssl_server_name.data = NULL;

rc = NGX_ERROR;

done:

return NGX_OK;
return rc;
}
#endif

Expand Down Expand Up @@ -1187,6 +1221,11 @@ ngx_wasm_socket_tcp_destroy(ngx_wasm_socket_tcp_t *sock)
sock->host.data = NULL;
}

if (sock->ssl_server_name.data) {
ngx_pfree(sock->pool, sock->ssl_server_name.data);
sock->ssl_server_name.data = NULL;
}

if (c && c->pool) {
#if 0
/* disabled: c->pool is inherited from sock->env.pool */
Expand Down Expand Up @@ -1542,6 +1581,7 @@ ngx_wasm_socket_tcp_init_addr_text(ngx_peer_connection_t *pc)
default:
addr_text_max_len = NGX_SOCKADDR_STRLEN;
break;

}

c->addr_text.data = ngx_pnalloc(c->pool, addr_text_max_len);
Expand Down
4 changes: 3 additions & 1 deletion src/common/ngx_wasm_socket_tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ struct ngx_wasm_socket_tcp_s {
/* ssl */

#if (NGX_SSL)
ngx_str_t *sni;
ngx_str_t ssl_server_name;
ngx_wasm_ssl_conf_t *ssl_conf;
#endif

Expand All @@ -94,7 +96,7 @@ struct ngx_wasm_socket_tcp_s {


ngx_int_t ngx_wasm_socket_tcp_init(ngx_wasm_socket_tcp_t *sock,
ngx_str_t *host, unsigned tls, ngx_wasm_subsys_env_t *env);
ngx_str_t *host, unsigned tls, ngx_str_t *sni, ngx_wasm_subsys_env_t *env);
ngx_int_t ngx_wasm_socket_tcp_connect(ngx_wasm_socket_tcp_t *sock);
ngx_int_t ngx_wasm_socket_tcp_send(ngx_wasm_socket_tcp_t *sock,
ngx_chain_t *cl);
Expand Down
30 changes: 24 additions & 6 deletions src/http/proxy_wasm/ngx_http_proxy_wasm_dispatch.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ static ngx_str_t ngx_http_proxy_wasm_dispatch_errlist[] = {
ngx_null_string,
ngx_string("no :method"),
ngx_string("no :path"),
ngx_string("no :authority"),
ngx_string("bad step"),
ngx_string("no memory"),
ngx_string("marshalling error"),
Expand Down Expand Up @@ -305,10 +304,6 @@ ngx_http_proxy_wasm_dispatch(ngx_proxy_wasm_exec_t *pwexec,
} else if (!call->uri.len) {
call->error = NGX_HTTP_PROXY_WASM_DISPATCH_ERR_BAD_PATH;
goto error;

} else if (!call->authority.len) {
call->error = NGX_HTTP_PROXY_WASM_DISPATCH_ERR_BAD_AUTHORITY;
goto error;
}

/* body */
Expand All @@ -333,7 +328,8 @@ ngx_http_proxy_wasm_dispatch(ngx_proxy_wasm_exec_t *pwexec,

ngx_wasm_assert(rctx);

if (ngx_wasm_socket_tcp_init(sock, &call->host, enable_ssl, &rctx->env)
if (ngx_wasm_socket_tcp_init(sock, &call->host, enable_ssl,
&call->authority, &rctx->env)
!= NGX_OK)
{
dd("tcp init error");
Expand Down Expand Up @@ -464,6 +460,8 @@ ngx_http_proxy_wasm_dispatch_request(ngx_http_proxy_wasm_dispatch_t *call)
ngx_buf_t *b;
ngx_list_part_t *part;
ngx_table_elt_t *elt, *elts;
ngx_wasm_socket_tcp_t *sock;
ngx_peer_connection_t *pc;
ngx_http_wasm_req_ctx_t *rctx;
ngx_http_request_t *fake_r;
ngx_http_request_t *r;
Expand All @@ -472,6 +470,24 @@ ngx_http_proxy_wasm_dispatch_request(ngx_http_proxy_wasm_dispatch_t *call)
return call->req_out;
}

if (!call->authority.len) {
sock = &call->sock;
pc = &sock->peer;

switch (pc->sockaddr->sa_family) {
#if (NGX_HAVE_UNIX_DOMAIN)
case AF_UNIX:
call->authority.len = 9;
call->authority.data = (u_char *) "localhost";
break;
#endif
default:
call->authority.len = sock->host.len;
call->authority.data = sock->host.data;
break;
}
}

rctx = call->rctx;
fake_r = &call->fake_r;
r = rctx->r;
Expand Down Expand Up @@ -573,6 +589,7 @@ ngx_http_proxy_wasm_dispatch_request(ngx_http_proxy_wasm_dispatch_t *call)
* Connection:
* Content-Length:
*/

b->last = ngx_cpymem(b->last, call->method.data, call->method.len);
*b->last++ = ' ';

Expand All @@ -584,6 +601,7 @@ ngx_http_proxy_wasm_dispatch_request(ngx_http_proxy_wasm_dispatch_t *call)

b->last = ngx_cpymem(b->last, ngx_http_proxy_wasm_host,
sizeof(ngx_http_proxy_wasm_host) - 1);

b->last = ngx_cpymem(b->last, call->authority.data, call->authority.len);
*b->last++ = CR;
*b->last++ = LF;
Expand Down
1 change: 0 additions & 1 deletion src/http/proxy_wasm/ngx_http_proxy_wasm_dispatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ typedef enum {
NGX_HTTP_PROXY_WASM_DISPATCH_ERR_NONE = 0,
NGX_HTTP_PROXY_WASM_DISPATCH_ERR_BAD_METHOD,
NGX_HTTP_PROXY_WASM_DISPATCH_ERR_BAD_PATH,
NGX_HTTP_PROXY_WASM_DISPATCH_ERR_BAD_AUTHORITY,
NGX_HTTP_PROXY_WASM_DISPATCH_ERR_BAD_STEP,
NGX_HTTP_PROXY_WASM_DISPATCH_ERR_NOMEM,
NGX_HTTP_PROXY_WASM_DISPATCH_ERR_MARSHALLING,
Expand Down
Loading

0 comments on commit 3243acc

Please sign in to comment.