From 759b6d2df7efd5c049fcf09aeca197ef44ea842c Mon Sep 17 00:00:00 2001 From: Urval Date: Mon, 13 Apr 2026 04:26:39 +0530 Subject: [PATCH 4/5] service_scan: Refine ALPN implementation to avoid API changes and scope creep Remove ALPN parameter from internal APIs and keep it as extrainfo annotation only Drop HTTP inference based on ALPN and SSL port retry heuristics Keep implementation minimal and non-intrusive --- nse_nmaplib.cc | 3 +-- nsock/src/nsock_core.c | 6 ++--- portlist.cc | 5 +--- portlist.h | 3 +-- service_scan.cc | 53 +----------------------------------------- service_scan.h | 1 - 6 files changed, 6 insertions(+), 65 deletions(-) diff --git a/nse_nmaplib.cc b/nse_nmaplib.cc index 1796b8bf9..1a6b30ffa 100644 --- a/nse_nmaplib.cc +++ b/nse_nmaplib.cc @@ -581,7 +581,6 @@ static int l_set_port_version (lua_State *L) *product = (lua_getfield(L, 4, "product"), lua_tostring(L, -1)), *version = (lua_getfield(L, 4, "version"), lua_tostring(L, -1)), *extrainfo = (lua_getfield(L, 4, "extrainfo"), lua_tostring(L, -1)), - *alpn = (lua_getfield(L, 4, "alpn"), lua_tostring(L, -1)), *hostname = (lua_getfield(L, 4, "hostname"), lua_tostring(L, -1)), *ostype = (lua_getfield(L, 4, "ostype"), lua_tostring(L, -1)), *devicetype = (lua_getfield(L, 4, "devicetype"), lua_tostring(L, -1)), @@ -607,7 +606,7 @@ static int l_set_port_version (lua_State *L) target->ports.setServiceProbeResults(p->portno, p->proto, probestate, name, tunnel, product, - version, extrainfo, alpn, hostname, ostype, devicetype, + version, extrainfo, hostname, ostype, devicetype, (cpe.size() > 0) ? &cpe : NULL, probestate==PROBESTATE_FINISHED_HARDMATCHED ? NULL : service_fp); return 0; diff --git a/nsock/src/nsock_core.c b/nsock/src/nsock_core.c index 3f97f36b4..83d90e7fe 100644 --- a/nsock/src/nsock_core.c +++ b/nsock/src/nsock_core.c @@ -96,10 +96,8 @@ static void nsock_set_client_alpn(SSL *ssl) { return; } - if (SSL_set_alpn_protos(ssl, alpn_protos, sizeof(alpn_protos) - 1) != 0) { - nsock_log_info("SSL_set_alpn_protos failed: %s", - ERR_error_string(ERR_get_error(), NULL)); - } + /* Intentionally ignore failure: ALPN is opportunistic and non-critical. */ + (void) SSL_set_alpn_protos(ssl, alpn_protos, sizeof(alpn_protos) - 1); } #endif diff --git a/portlist.cc b/portlist.cc index f15608f43..1d958d334 100644 --- a/portlist.cc +++ b/portlist.cc @@ -114,7 +114,6 @@ void serviceDeductions::erase() { this->hostname = NULL; this->ostype = NULL; this->devicetype = NULL; - this->alpn.clear(); this->service_tunnel = SERVICE_TUNNEL_NONE; this->service_fp = NULL; this->dtype = SERVICE_DETECTION_TABLE; @@ -182,7 +181,6 @@ serviceDeductions::serviceDeductions() { hostname = NULL; ostype = NULL; devicetype = NULL; - alpn.clear(); service_tunnel = SERVICE_TUNNEL_NONE; service_fp = NULL; dtype = SERVICE_DETECTION_TABLE; @@ -312,7 +310,7 @@ static char *cstringSanityCheck(const char* string, int len) { void PortList::setServiceProbeResults(u16 portno, int protocol, enum serviceprobestate sres, const char *sname, enum service_tunnel_type tunnel, const char *product, const char *version, - const char *extrainfo, const char *alpn, const char *hostname, const char *ostype, + const char *extrainfo, const char *hostname, const char *ostype, const char *devicetype, const std::vector *cpe, const char *fingerprint) { std::vector::iterator it; @@ -363,7 +361,6 @@ void PortList::setServiceProbeResults(u16 portno, int protocol, port->service->product = cstringSanityCheck(product, 80); port->service->version = cstringSanityCheck(version, 80); port->service->extrainfo = cstringSanityCheck(extrainfo, 256); - port->service->alpn = alpn ? alpn : ""; port->service->hostname = cstringSanityCheck(hostname, 80); port->service->ostype = cstringSanityCheck(ostype, 32); port->service->devicetype = cstringSanityCheck(devicetype, 32); diff --git a/portlist.h b/portlist.h index 9f1b9de96..0f65c6943 100644 --- a/portlist.h +++ b/portlist.h @@ -130,7 +130,6 @@ struct serviceDeductions { char *hostname; char *ostype; char *devicetype; - std::string alpn; std::vector cpe; // SERVICE_TUNNEL_NONE or SERVICE_TUNNEL_SSL enum service_tunnel_type service_tunnel; @@ -232,7 +231,7 @@ class PortList { enum serviceprobestate sres, const char *sname, enum service_tunnel_type tunnel, const char *product, const char *version, const char *extrainfo, - const char *alpn, const char *hostname, + const char *hostname, const char *ostype, const char *devicetype, const std::vector *cpe, const char *fingerprint); diff --git a/service_scan.cc b/service_scan.cc index ec0700f1e..f560f04d3 100644 --- a/service_scan.cc +++ b/service_scan.cc @@ -1588,34 +1588,6 @@ int AllProbes::isExcluded(unsigned short port, int proto) const { return 0; } -bool AllProbes::isProbableSSLPort(int proto, u16 portno) const { - /* Common SSL/TLS ports that should be retried through SSL tunnel if cleartext fails */ - static const u16 common_ssl_ports[] = { - 443, 465, 587, 636, 989, 990, 992, 993, 995, - 8443, 9443, 9999, 3269, 3306, 5432, 5985, 5986, 6697, 8883, 8984, 9001, 0 - }; - - if (proto != IPPROTO_TCP) - return false; - - /* First check hardcoded common SSL ports for this TCP service */ - for (int i = 0; common_ssl_ports[i] != 0; i++) { - if (portno == common_ssl_ports[i]) - return true; - } - - /* Also check if port is explicitly in nmap-service-probes sslports directives */ - std::vector::const_iterator vi; - for (vi = probes.begin(); vi != probes.end(); vi++) { - if ((*vi)->getProbeProtocol() != proto) - continue; - if ((*vi)->portIsProbable(SERVICE_TUNNEL_SSL, portno)) - return true; - } - - return false; -} - // Before this function is called, the fallbacks exist as unparsed // comma-separated strings in the fallbackStr field of each probe. @@ -1934,24 +1906,6 @@ bool dropdown = false; current_probe++; } -#ifdef HAVE_OPENSSL - if (tunnel == SERVICE_TUNNEL_NONE && proto == IPPROTO_TCP && - AP->isProbableSSLPort(proto, portno)) { - /* If cleartext probing produced no match on an SSL-likely port, - * retry all probes through SSL to collect tunneled service metadata. - */ - tunnel = SERVICE_TUNNEL_SSL; - softMatchFound = false; - probe_matched = NULL; - product_matched[0] = version_matched[0] = extrainfo_matched[0] = '\0'; - hostname_matched[0] = ostype_matched[0] = devicetype_matched[0] = '\0'; - cpe_a_matched[0] = cpe_h_matched[0] = cpe_o_matched[0] = '\0'; - alpn_selected[0] = '\0'; - resetProbes(true); - return nextProbe(true); - } -#endif - // Tried all NONMATCHINGPROBES -- we're finished probe_state = (softMatchFound)? PROBESTATE_FINISHED_SOFTMATCHED : PROBESTATE_FINISHED_NOMATCH; return NULL; @@ -2827,10 +2781,6 @@ std::list::iterator svc; else Snprintf(annotated_extrainfo, sizeof(annotated_extrainfo), "ALPN:%s", alpn); output_extrainfo = annotated_extrainfo; - - if (strcmp(alpn, "h2") == 0 && (service_name == NULL || *service_name == '\0') && version == NULL) { - service_name = "http"; - } } if ((*svc)->probe_state != PROBESTATE_FINISHED_NOMATCH) { @@ -2850,7 +2800,6 @@ std::list::iterator svc; *(*svc)->product_matched? (*svc)->product_matched : NULL, version, output_extrainfo, - alpn, *(*svc)->hostname_matched? (*svc)->hostname_matched : NULL, *(*svc)->ostype_matched? (*svc)->ostype_matched : NULL, *(*svc)->devicetype_matched? (*svc)->devicetype_matched : NULL, @@ -2862,7 +2811,7 @@ std::list::iterator svc; (*svc)->target->ports.setServiceProbeResults((*svc)->portno, (*svc)->proto, (*svc)->probe_state, nomatch_name, - (*svc)->tunnel, NULL, NULL, nomatch_extrainfo, alpn, NULL, NULL, NULL, + (*svc)->tunnel, NULL, NULL, nomatch_extrainfo, NULL, NULL, NULL, NULL, (*svc)->getServiceFingerprint(NULL)); } diff --git a/service_scan.h b/service_scan.h index 17912a1a2..c91f5f7fa 100644 --- a/service_scan.h +++ b/service_scan.h @@ -310,7 +310,6 @@ public: void compileFallbacks(); int isExcluded(unsigned short port, int proto) const; - bool isProbableSSLPort(int proto, u16 portno) const; bool excluded_seen; struct scan_lists excludedports; -- 2.50.1.windows.1