From 7a32c9fa69e103102235f3f81d6c354a0c08e747 Mon Sep 17 00:00:00 2001 From: Maksym Sobolyev Date: Wed, 29 Nov 2023 18:06:02 -0800 Subject: [PATCH] Push down hostname checking all the way into the TLS code. --- ip_addr.h | 2 +- modules/proto_bins/proto_bins.c | 6 +++--- modules/proto_hep/proto_hep.c | 6 +++--- modules/proto_msrp/msrp_tls.c | 4 ++-- modules/proto_msrp/msrp_tls.h | 2 +- modules/proto_smpp/proto_smpp.c | 4 ++-- modules/proto_tls/proto_tls.c | 7 ++++--- modules/proto_ws/proto_ws.c | 4 ++-- modules/proto_wss/proto_wss.c | 6 +++--- modules/tls_mgm/api.h | 2 +- modules/tls_openssl/openssl_conn_ops.c | 8 ++++++-- net/api_proto_net.h | 2 +- net/net_tcp.c | 19 +++---------------- net/net_tcp_proc.c | 2 +- net/tcp_conn_defs.h | 1 - 15 files changed, 33 insertions(+), 42 deletions(-) diff --git a/ip_addr.h b/ip_addr.h index 53145179019..72cd70ee5b7 100644 --- a/ip_addr.h +++ b/ip_addr.h @@ -422,7 +422,7 @@ static inline int hostent2hu( struct sockaddr_hu *hu, hu->_.hoststr.len = nlen; hu->hp = &hu->_.hoststr; } - return 0; + return r; } static inline void hu_dup(const struct sockaddr_hu *hu_s, struct sockaddr_hu *hu_d) diff --git a/modules/proto_bins/proto_bins.c b/modules/proto_bins/proto_bins.c index 45c8753a214..683cd0ddeaf 100644 --- a/modules/proto_bins/proto_bins.c +++ b/modules/proto_bins/proto_bins.c @@ -50,7 +50,7 @@ static int proto_bins_send(struct socket_info* send_sock, unsigned int id); static int bins_read_req(struct tcp_connection* con, int* bytes_read); static int bins_async_write(struct tcp_connection* con,int fd); -static int proto_bins_conn_init(struct tcp_connection* c); +static int proto_bins_conn_init(struct tcp_connection* c, const struct sockaddr_hu *hu); static void proto_bins_conn_clean(struct tcp_connection* c); static void bins_report(int type, unsigned long long conn_id, int conn_flags, void *extra); @@ -225,7 +225,7 @@ static int proto_bins_init_listener(struct socket_info *si) return tcp_init_listener(si); } -static int proto_bins_conn_init(struct tcp_connection* c) +static int proto_bins_conn_init(struct tcp_connection* c, const struct sockaddr_hu *hu) { struct tls_domain *dom; struct tls_data* data; @@ -264,7 +264,7 @@ static int proto_bins_conn_init(struct tcp_connection* c) return -1; } - return tls_mgm_api.tls_conn_init(c, dom); + return tls_mgm_api.tls_conn_init(c, dom, hu); } static void proto_bins_conn_clean(struct tcp_connection* c) diff --git a/modules/proto_hep/proto_hep.c b/modules/proto_hep/proto_hep.c index c7827aa5a3b..838da1f1e06 100644 --- a/modules/proto_hep/proto_hep.c +++ b/modules/proto_hep/proto_hep.c @@ -74,7 +74,7 @@ static int hep_tls_send(struct socket_info* send_sock, unsigned int id); static void update_recv_info(struct receive_info* ri, struct hep_desc* h); void free_hep_context(void* ptr); -static int proto_hep_tls_conn_init(struct tcp_connection* c); +static int proto_hep_tls_conn_init(struct tcp_connection* c, const struct sockaddr_hu *hu); static void proto_hep_tls_conn_clean(struct tcp_connection* c); static int hep_tls_write_on_socket(struct tcp_connection* c, int fd, char* buf, int len); @@ -1186,7 +1186,7 @@ static void update_recv_info(struct receive_info* ri, struct hep_desc* h) ri->dst_port = dport; } -static int proto_hep_tls_conn_init(struct tcp_connection* c) +static int proto_hep_tls_conn_init(struct tcp_connection* c, const struct sockaddr_hu *hu) { struct tls_domain* dom; @@ -1205,7 +1205,7 @@ static int proto_hep_tls_conn_init(struct tcp_connection* c) return -1; } - return tls_mgm_api.tls_conn_init(c, dom); + return tls_mgm_api.tls_conn_init(c, dom, hu); } static void proto_hep_tls_conn_clean(struct tcp_connection* c) diff --git a/modules/proto_msrp/msrp_tls.c b/modules/proto_msrp/msrp_tls.c index 7361d27484c..23355e68084 100644 --- a/modules/proto_msrp/msrp_tls.c +++ b/modules/proto_msrp/msrp_tls.c @@ -32,7 +32,7 @@ int msrps_conn_extra_match(struct tcp_connection *c, void *id) } -int proto_msrps_conn_init(struct tcp_connection* c) +int proto_msrps_conn_init(struct tcp_connection* c, const struct sockaddr_hu *hu) { struct tls_domain *dom; @@ -49,7 +49,7 @@ int proto_msrps_conn_init(struct tcp_connection* c) return -1; } - return tls_mgm_api.tls_conn_init(c, dom); + return tls_mgm_api.tls_conn_init(c, dom, hu); } diff --git a/modules/proto_msrp/msrp_tls.h b/modules/proto_msrp/msrp_tls.h index 9c6b2a2ff31..fbb9701af95 100644 --- a/modules/proto_msrp/msrp_tls.h +++ b/modules/proto_msrp/msrp_tls.h @@ -25,7 +25,7 @@ int msrps_conn_extra_match(struct tcp_connection *c, void *id); -int proto_msrps_conn_init(struct tcp_connection* c); +int proto_msrps_conn_init(struct tcp_connection* c, const struct sockaddr_hu *hu); void proto_msrps_conn_clean(struct tcp_connection* c); diff --git a/modules/proto_smpp/proto_smpp.c b/modules/proto_smpp/proto_smpp.c index b7a3fe37ffb..9e77cc48f0f 100644 --- a/modules/proto_smpp/proto_smpp.c +++ b/modules/proto_smpp/proto_smpp.c @@ -64,7 +64,7 @@ static int smpp_send(struct socket_info* send_sock, unsigned int id); static int smpp_read_req(struct tcp_connection* conn, int* bytes_read); static int smpp_write_async_req(struct tcp_connection* con,int fd); -static int smpp_conn_init(struct tcp_connection* c); +static int smpp_conn_init(struct tcp_connection* c, const struct sockaddr_hu *hu); static void smpp_conn_clean(struct tcp_connection* c); static int send_smpp_msg(struct sip_msg* msg, str *name, str *from, str *to, str *body, int *utf16, int *delivery_confirmation); @@ -211,7 +211,7 @@ static int child_init(int rank) return 0; } -static int smpp_conn_init(struct tcp_connection* c) +static int smpp_conn_init(struct tcp_connection* c, const struct sockaddr_hu *hu) { LM_INFO("smpp_conn_init called\n"); return 0; diff --git a/modules/proto_tls/proto_tls.c b/modules/proto_tls/proto_tls.c index f4945d0d940..fe39973ca7d 100644 --- a/modules/proto_tls/proto_tls.c +++ b/modules/proto_tls/proto_tls.c @@ -207,7 +207,7 @@ static struct script_route_ref *trace_filter_route_ref = NULL; static int tls_read_req(struct tcp_connection* con, int* bytes_read); static int tls_async_write(struct tcp_connection* con,int fd); -static int proto_tls_conn_init(struct tcp_connection* c); +static int proto_tls_conn_init(struct tcp_connection* c, const struct sockaddr_hu *hu); static void proto_tls_conn_clean(struct tcp_connection* c); static const cmd_export_t cmds[] = { @@ -388,10 +388,11 @@ static int proto_tls_init_listener(struct socket_info *si) } -static int proto_tls_conn_init(struct tcp_connection* c) +static int proto_tls_conn_init(struct tcp_connection* c, const struct sockaddr_hu *hu) { struct tls_data* data; struct tls_domain *dom; + const union sockaddr_union *su = &hu->su; if ( t_dst && tprot.create_trace_message ) { /* this message shall be used in first send function */ @@ -429,7 +430,7 @@ static int proto_tls_conn_init(struct tcp_connection* c) return -1; } - return tls_mgm_api.tls_conn_init(c, dom); + return tls_mgm_api.tls_conn_init(c, dom, hu); } diff --git a/modules/proto_ws/proto_ws.c b/modules/proto_ws/proto_ws.c index bfa63c45490..2c2e512c15c 100644 --- a/modules/proto_ws/proto_ws.c +++ b/modules/proto_ws/proto_ws.c @@ -98,7 +98,7 @@ static int proto_ws_send(struct socket_info* send_sock, char* buf, unsigned int len, const struct sockaddr_hu* to, unsigned int id); static int ws_read_req(struct tcp_connection* con, int* bytes_read); -static int ws_conn_init(struct tcp_connection* c); +static int ws_conn_init(struct tcp_connection* c, const struct sockaddr_hu *hu); static void ws_conn_clean(struct tcp_connection* c); static void ws_report(int type, unsigned long long conn_id, int conn_flags, void *extra); @@ -239,7 +239,7 @@ static int mod_init(void) } -static int ws_conn_init(struct tcp_connection* c) +static int ws_conn_init(struct tcp_connection* c, const struct sockaddr_hu *hu) { struct ws_data *d; diff --git a/modules/proto_wss/proto_wss.c b/modules/proto_wss/proto_wss.c index a8a136c6dcf..98024cc8975 100644 --- a/modules/proto_wss/proto_wss.c +++ b/modules/proto_wss/proto_wss.c @@ -111,7 +111,7 @@ static int proto_wss_send(struct socket_info* send_sock, char* buf, unsigned int len, const struct sockaddr_hu* to, unsigned int id); static int wss_read_req(struct tcp_connection* con, int* bytes_read); -static int wss_conn_init(struct tcp_connection* c); +static int wss_conn_init(struct tcp_connection* c, const struct sockaddr_hu *); static void ws_conn_clean(struct tcp_connection* c); static void wss_report(int type, unsigned long long conn_id, int conn_flags, void *extra); @@ -262,7 +262,7 @@ static int mod_init(void) return 0; } -static int wss_conn_init(struct tcp_connection* c) +static int wss_conn_init(struct tcp_connection* c, const struct sockaddr_hu *hu) { struct ws_data *d; struct tls_domain *dom; @@ -306,7 +306,7 @@ static int wss_conn_init(struct tcp_connection* c) return -1; } - ret = tls_mgm_api.tls_conn_init(c, dom); + ret = tls_mgm_api.tls_conn_init(c, dom, hu); if (ret < 0) { c->proto_data = NULL; LM_ERR("Cannot initiate the conn\n"); diff --git a/modules/tls_mgm/api.h b/modules/tls_mgm/api.h index 7e0c41e6f61..43cbb5f6286 100644 --- a/modules/tls_mgm/api.h +++ b/modules/tls_mgm/api.h @@ -49,7 +49,7 @@ typedef void (*tls_release_domain_f) (struct tls_domain *); /* TLS conn ops */ typedef int (*tls_conn_init_f)(struct tcp_connection *c, - struct tls_domain *tls_dom); + struct tls_domain *tls_dom, const struct sockaddr_hu *hu); typedef void (*tls_conn_clean_f)(struct tcp_connection* c, struct tls_domain **tls_dom); typedef int (*tls_update_fd_f)(struct tcp_connection* c, int fd); diff --git a/modules/tls_openssl/openssl_conn_ops.c b/modules/tls_openssl/openssl_conn_ops.c index b1672ab10f2..14979a7975c 100644 --- a/modules/tls_openssl/openssl_conn_ops.c +++ b/modules/tls_openssl/openssl_conn_ops.c @@ -198,7 +198,7 @@ int openssl_tls_update_fd(struct tcp_connection *c, int fd) return 0; } -int openssl_tls_conn_init(struct tcp_connection* c, struct tls_domain *tls_dom) +int openssl_tls_conn_init(struct tcp_connection* c, struct tls_domain *tls_dom, const struct sockaddr_hu *hu) { X509_VERIFY_PARAM *param = NULL; @@ -222,9 +222,13 @@ int openssl_tls_conn_init(struct tcp_connection* c, struct tls_domain *tls_dom) } if (tls_dom->verify_hostname) { + if (hu == NULL || hu->hp == NULL) { + LM_ERR("no hostinfo\n"); + return -1; + } param = SSL_get0_param(c->extra_data); X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS); - if (!X509_VERIFY_PARAM_set1_host(param, c->hostname, strlen(c->hostname))) { + if (!X509_VERIFY_PARAM_set1_host(param, hu->hp->s, hu->hp->len)) { LM_ERR("failed to set hostname for SSL context\n"); return -1; } diff --git a/net/api_proto_net.h b/net/api_proto_net.h index 7f570f4efaa..b2904e92fe7 100644 --- a/net/api_proto_net.h +++ b/net/api_proto_net.h @@ -35,7 +35,7 @@ typedef int (*proto_net_write_f)(void *src, int fd); typedef int (*proto_net_read_f)(void *src, int *len); -typedef int (*proto_net_conn_init_f)(struct tcp_connection *c); +typedef int (*proto_net_conn_init_f)(struct tcp_connection *c, const struct sockaddr_hu *hu); typedef void (*proto_net_conn_clean_f)(struct tcp_connection *c); typedef int (*proto_net_extra_match_f)(struct tcp_connection *c, void *id); typedef void (*proto_net_report_f)( int type, unsigned long long conn_id, diff --git a/net/net_tcp.c b/net/net_tcp.c index 0b71e9262e3..1844a34f371 100644 --- a/net/net_tcp.c +++ b/net/net_tcp.c @@ -951,21 +951,13 @@ static struct tcp_connection* tcpconn_new(int sock, const union sockaddr_union* * IMPORTANT - the function assumes you want to create a new TCP conn as * a result of a connect operation - the conn will be set as connect !! * Accepted connection are triggered internally only */ -struct tcp_connection* tcp_conn_create(int sock, const struct sockaddr_hu* shu, +struct tcp_connection* tcp_conn_create(int sock, const struct sockaddr_hu* hu, struct socket_info* si, struct tcp_conn_profile *prof, int state, int send2main) { struct tcp_connection *c; - const union sockaddr_union *su = &shu->su; + const union sockaddr_union *su = &hu->su; - if (shu->hp == NULL) { - LM_ERR("tcpconn_new: no hostinfo"); - return NULL; - } - if (shu->hp->len >= sizeof(c->hostname)) { - LM_ERR("tcpconn_new: host name is too long %d", shu->hp->len); - return NULL; - } if (!prof) tcp_con_get_profile(su, &si->su, si->proto, prof); @@ -976,13 +968,8 @@ struct tcp_connection* tcp_conn_create(int sock, const struct sockaddr_hu* shu, return NULL; } - /* copy peer hostname into the tcp_connection so that tls_openssl can verify - * the certificate hostname */ - memcpy(c->hostname, shu->hp->s, shu->hp->len); - c->hostname[shu->hp->len] = 0; - if (protos[c->type].net.conn_init && - protos[c->type].net.conn_init(c) < 0) { + protos[c->type].net.conn_init(c, hu) < 0) { LM_ERR("failed to do proto %d specific init for conn %p\n", c->type, c); tcp_conn_destroy(c); diff --git a/net/net_tcp_proc.c b/net/net_tcp_proc.c index 49da19c5b14..cfc05509795 100644 --- a/net/net_tcp_proc.c +++ b/net/net_tcp_proc.c @@ -248,7 +248,7 @@ inline static int handle_io(struct fd_map* fm, int idx,int event_type) if (!(con->flags & F_CONN_INIT)) { if (protos[con->type].net.conn_init && - protos[con->type].net.conn_init(con) < 0) { + protos[con->type].net.conn_init(con, NULL) < 0) { LM_ERR("failed to do proto %d specific init for conn %p\n", con->type, con); goto con_error; diff --git a/net/tcp_conn_defs.h b/net/tcp_conn_defs.h index 9632dac90ef..d2216d65892 100644 --- a/net/tcp_conn_defs.h +++ b/net/tcp_conn_defs.h @@ -182,7 +182,6 @@ struct tcp_connection{ struct tcp_async_data *async; /* protocol specific data attached to this connection */ void *proto_data; - char hostname[256]; /* remote side hostname (used for TLS certificate hostname verification) */ };