mirror of
https://github.com/cesanta/mongoose.git
synced 2026-10-31 13:00:49 +00:00
Calling event handler in MITM mode before making connection to the target host
This commit is contained in:
1 parent
96ce6bac69
commit
8a2fbac4c0
1 file changed
+39
-37
+39
-37
@@ -4028,13 +4028,42 @@ static void proxy_request(struct ns_connection *pc, struct mg_connection *c) {
|
||||
|
||||
}
|
||||
|
||||
#ifdef NS_ENABLE_SSL
|
||||
int mg_terminate_ssl(struct mg_connection *c, const char *cert) {
|
||||
static const char ok[] = "HTTP/1.0 200 OK\r\n\r\n";
|
||||
struct connection *conn = MG_CONN_2_CONN(c);
|
||||
int n;
|
||||
SSL_CTX *ctx;
|
||||
|
||||
DBG(("%p MITM", conn));
|
||||
SSL_library_init();
|
||||
if ((ctx = SSL_CTX_new(SSLv23_server_method())) == NULL) return 0;
|
||||
|
||||
SSL_CTX_use_certificate_file(ctx, cert, 1);
|
||||
SSL_CTX_use_PrivateKey_file(ctx, cert, 1);
|
||||
SSL_CTX_use_certificate_chain_file(ctx, cert);
|
||||
|
||||
// When clear-text reply is pushed to client, switch to SSL mode.
|
||||
n = send(conn->ns_conn->sock, ok, sizeof(ok) - 1, 0);
|
||||
DBG(("%p %lu %d SEND", c, sizeof(ok) - 1, n));
|
||||
conn->ns_conn->send_iobuf.len = 0;
|
||||
conn->endpoint_type = EP_USER; // To keep-alive in close_local_endpoint()
|
||||
close_local_endpoint(conn); // Clean up current CONNECT request
|
||||
if ((conn->ns_conn->ssl = SSL_new(ctx)) != NULL) {
|
||||
SSL_set_fd(conn->ns_conn->ssl, conn->ns_conn->sock);
|
||||
}
|
||||
SSL_CTX_free(ctx);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void proxify_connection(struct connection *conn) {
|
||||
char proto[10], host[500], cert[500];
|
||||
unsigned short port = 80;
|
||||
struct mg_connection *c = &conn->mg_conn;
|
||||
struct ns_server *server = &conn->server->ns_server;
|
||||
struct ns_connection *pc = NULL;
|
||||
int n = 0, use_ssl = 0;
|
||||
int n = 0;
|
||||
const char *url = c->uri;
|
||||
|
||||
proto[0] = host[0] = cert[0] = '\0';
|
||||
@@ -4051,23 +4080,24 @@ static void proxify_connection(struct connection *conn) {
|
||||
int host_len = strlen(host);
|
||||
struct vec a, b;
|
||||
|
||||
while ((certs = next_option(certs, &a, &b)) != NULL) {
|
||||
if (a.len == host_len && mg_strncasecmp(a.ptr, host, a.len) == 0) {
|
||||
snprintf(cert, sizeof(cert), "%.*s", b.len, b.ptr);
|
||||
break;
|
||||
}
|
||||
while (conn->ns_conn->ssl == NULL && port != 80 &&
|
||||
(certs = next_option(certs, &a, &b)) != NULL) {
|
||||
if (a.len != host_len || mg_strncasecmp(a.ptr, host, a.len)) continue;
|
||||
snprintf(cert, sizeof(cert), "%.*s", b.len, b.ptr);
|
||||
mg_terminate_ssl(&conn->mg_conn, cert);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
use_ssl = port != 80 && cert[0] != '\0';
|
||||
if (n > 0 &&
|
||||
(pc = ns_connect(server, host, port, use_ssl, conn)) != NULL) {
|
||||
(pc = ns_connect(server, host, port, conn->ns_conn->ssl != NULL,
|
||||
conn)) != NULL) {
|
||||
// Interlink two connections
|
||||
pc->flags |= MG_PROXY_CONN;
|
||||
conn->endpoint_type = EP_PROXY;
|
||||
conn->endpoint.nc = pc;
|
||||
DBG(("%p [%s] -> %p %d", conn, c->uri, pc, use_ssl));
|
||||
DBG(("%p [%s] -> %p %p", conn, c->uri, pc, conn->ns_conn->ssl));
|
||||
|
||||
if (strcmp(c->request_method, "CONNECT") == 0) {
|
||||
// For CONNECT request, reply with 200 OK. Tunnel is established.
|
||||
@@ -4075,34 +4105,6 @@ static void proxify_connection(struct connection *conn) {
|
||||
conn->request_len = 0;
|
||||
free(conn->request);
|
||||
conn->request = NULL;
|
||||
#ifdef NS_ENABLE_SSL
|
||||
if (use_ssl) {
|
||||
SSL_CTX *ctx;
|
||||
|
||||
DBG(("%s", "Triggering MITM mode: terminating SSL connection"));
|
||||
SSL_library_init();
|
||||
ctx = SSL_CTX_new(SSLv23_server_method());
|
||||
|
||||
if (ctx == NULL) {
|
||||
pc->flags |= NSF_CLOSE_IMMEDIATELY;
|
||||
} else {
|
||||
SSL_CTX_use_certificate_file(ctx, cert, 1);
|
||||
SSL_CTX_use_PrivateKey_file(ctx, cert, 1);
|
||||
SSL_CTX_use_certificate_chain_file(ctx, cert);
|
||||
|
||||
// When clear-text reply is pushed to client, switch to SSL mode.
|
||||
n = send(conn->ns_conn->sock, conn->ns_conn->send_iobuf.buf,
|
||||
conn->ns_conn->send_iobuf.len, 0);
|
||||
DBG(("%p %lu %d SEND", c, conn->ns_conn->send_iobuf.len, n));
|
||||
conn->ns_conn->send_iobuf.len = 0;
|
||||
if ((conn->ns_conn->ssl = SSL_new(ctx)) != NULL) {
|
||||
//SSL_set_fd((SSL *) c->connection_param, conn->ns_conn->sock);
|
||||
SSL_set_fd(conn->ns_conn->ssl, conn->ns_conn->sock);
|
||||
}
|
||||
SSL_CTX_free(ctx);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
// For other methods, forward the request to the target host.
|
||||
c->uri += n;
|
||||
|
||||
Reference in new issue
Block a user