"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/dynamic-preprocessors/appid/service_plugins/service_ssl.c" between
snort-2.9.16.1.tar.gz and snort-2.9.17.tar.gz

About: Snort is a network intrusion prevention and detection system (IDS/IPS) combining the benefits of signature, protocol and anomaly-based inspection.

service_ssl.c  (snort-2.9.16.1):service_ssl.c  (snort-2.9.17)
skipping to change at line 51 skipping to change at line 51
SSL_HANDSHAKE = 22, SSL_HANDSHAKE = 22,
SSL_APPLICATION_DATA = 23 SSL_APPLICATION_DATA = 23
} SSLContentType; } SSLContentType;
#define SSL_CLIENT_HELLO 1 #define SSL_CLIENT_HELLO 1
#define SSL_SERVER_HELLO 2 #define SSL_SERVER_HELLO 2
#define SSL_CERTIFICATE 11 #define SSL_CERTIFICATE 11
#define SSL_SERVER_KEY_XCHG 12 #define SSL_SERVER_KEY_XCHG 12
#define SSL_SERVER_CERT_REQ 13 #define SSL_SERVER_CERT_REQ 13
#define SSL_SERVER_HELLO_DONE 14 #define SSL_SERVER_HELLO_DONE 14
#define SSL_CERTIFICATE_STATUS 22
#define SSL2_SERVER_HELLO 4 #define SSL2_SERVER_HELLO 4
#define PCT_SERVER_HELLO 2 #define PCT_SERVER_HELLO 2
#define FIELD_SEPARATOR "/" #define FIELD_SEPARATOR "/"
#define COMMON_NAME_STR "/CN=" #define COMMON_NAME_STR "/CN="
#define ORG_NAME_STR "/O=" #define ORG_NAME_STR "/O="
/* Extension types. */ /* Extension types. */
#define SSL_EXT_SERVER_NAME 0 #define SSL_EXT_SERVER_NAME 0
typedef struct _MatchedSSLPatterns { typedef struct _MatchedSSLPatterns {
SSLCertPattern *mpattern; SSLCertPattern *mpattern;
int index; int index;
struct _MatchedSSLPatterns *next; struct _MatchedSSLPatterns *next;
} MatchedSSLPatterns; } MatchedSSLPatterns;
typedef enum typedef enum
{ {
SSL_STATE_INITIATE, /* Client initiates. */ SSL_STATE_INITIATE, /* Client initiates. */
SSL_STATE_CONNECTION, /* Server responds... */ SSL_STATE_CONNECTION, /* Server responds... */
SSL_STATE_HEADER, SSL_STATE_HEADER
SSL_STATE_DONE
} SSLState; } SSLState;
typedef struct _SERVICE_SSL_DATA typedef struct _SERVICE_SSL_DATA
{ {
SSLState state; SSLState state;
int pos; int pos;
int length; int length;
int tot_length; int tot_length;
/* From client: */ /* From client: */
char *host_name; char *host_name;
int host_name_strlen; int host_name_strlen;
/* While collecting certificates: */ /* While collecting certificates: */
int certs_len; /* (Total) length of certificate(s). */ int certs_len; /* (Total) length of certificate(s). */
uint8_t *certs_data; /* Certificate(s) data (each proceeded by length (3 bytes)). */ uint8_t *certs_data; /* Certificate(s) data (each proceeded by length (3 bytes)). */
int in_certs; /* Currently collecting certificates? */ int in_certs; /* Currently collecting certificates? */
int certs_curr_len; /* Current amount of collected certificate data. */ int certs_curr_len; /* Current amount of collected certificate data. */
/* Data collected from certificates afterwards: */ /* Data collected from certificates afterwards: */
char *common_name; char *common_name;
int common_name_strlen; int common_name_strlen;
char *org_name;
int org_name_strlen; int org_name_strlen;
char *org_name;
} ServiceSSLData; } ServiceSSLData;
typedef struct _SERVICE_SSL_CERTIFICATE typedef struct _SERVICE_SSL_CERTIFICATE
{ {
X509 *cert; X509 *cert;
uint8_t *common_name_ptr; uint8_t *common_name_ptr;
int common_name_len; int common_name_len;
uint8_t *org_name_ptr; uint8_t *org_name_ptr;
int org_name_len; int org_name_len;
struct _SERVICE_SSL_CERTIFICATE *next; struct _SERVICE_SSL_CERTIFICATE *next;
skipping to change at line 274 skipping to change at line 274
{&ssl_validate, 448, IPPROTO_TCP}, {&ssl_validate, 448, IPPROTO_TCP},
{&ssl_validate, 448, IPPROTO_UDP}, {&ssl_validate, 448, IPPROTO_UDP},
{&ssl_validate, 465, IPPROTO_TCP}, {&ssl_validate, 465, IPPROTO_TCP},
{&ssl_validate, 563, IPPROTO_TCP}, {&ssl_validate, 563, IPPROTO_TCP},
{&ssl_validate, 563, IPPROTO_UDP}, {&ssl_validate, 563, IPPROTO_UDP},
{&ssl_validate, 585, IPPROTO_TCP}, {&ssl_validate, 585, IPPROTO_TCP},
{&ssl_validate, 585, IPPROTO_UDP}, {&ssl_validate, 585, IPPROTO_UDP},
{&ssl_validate, 614, IPPROTO_TCP}, {&ssl_validate, 614, IPPROTO_TCP},
{&ssl_validate, 636, IPPROTO_TCP}, {&ssl_validate, 636, IPPROTO_TCP},
{&ssl_validate, 636, IPPROTO_UDP}, {&ssl_validate, 636, IPPROTO_UDP},
{&ssl_validate, 853, IPPROTO_TCP},
{&ssl_validate, 989, IPPROTO_TCP}, {&ssl_validate, 989, IPPROTO_TCP},
{&ssl_validate, 990, IPPROTO_TCP}, {&ssl_validate, 990, IPPROTO_TCP},
{&ssl_validate, 992, IPPROTO_TCP}, {&ssl_validate, 992, IPPROTO_TCP},
{&ssl_validate, 992, IPPROTO_UDP}, {&ssl_validate, 992, IPPROTO_UDP},
{&ssl_validate, 993, IPPROTO_TCP}, {&ssl_validate, 993, IPPROTO_TCP},
{&ssl_validate, 993, IPPROTO_UDP}, {&ssl_validate, 993, IPPROTO_UDP},
{&ssl_validate, 994, IPPROTO_TCP}, {&ssl_validate, 994, IPPROTO_TCP},
{&ssl_validate, 994, IPPROTO_UDP}, {&ssl_validate, 994, IPPROTO_UDP},
{&ssl_validate, 995, IPPROTO_TCP}, {&ssl_validate, 995, IPPROTO_TCP},
{&ssl_validate, 995, IPPROTO_UDP}, {&ssl_validate, 995, IPPROTO_UDP},
skipping to change at line 593 skipping to change at line 594
} }
if (dir != APP_ID_FROM_RESPONDER) if (dir != APP_ID_FROM_RESPONDER)
{ {
goto inprocess; goto inprocess;
} }
switch (ss->state) switch (ss->state)
{ {
case SSL_STATE_CONNECTION: case SSL_STATE_CONNECTION:
ss->state = SSL_STATE_DONE;
pct = (ServiceSSLPCTHdr *)data; pct = (ServiceSSLPCTHdr *)data;
hdr2 = (ServiceSSLV2Hdr *)data; hdr2 = (ServiceSSLV2Hdr *)data;
hdr3 = (ServiceSSLV3Hdr *)data; hdr3 = (ServiceSSLV3Hdr *)data;
/* SSL PCT header? */
if (size >= sizeof(ServiceSSLPCTHdr) && pct->len >= 0x80 && if (size >= sizeof(ServiceSSLPCTHdr) && pct->len >= 0x80 &&
pct->type == PCT_SERVER_HELLO && ntohs(pct->version) == 0x8001) pct->type == PCT_SERVER_HELLO && ntohs(pct->version) == 0x8001)
{ {
goto success; goto success;
} }
/* SSL v2 header? */
if (size >= sizeof(ServiceSSLV2Hdr) && hdr2->len >= 0x80 && if (size >= sizeof(ServiceSSLV2Hdr) && hdr2->len >= 0x80 &&
hdr2->type == SSL2_SERVER_HELLO && !(hdr2->cert & 0xFE)) hdr2->type == SSL2_SERVER_HELLO && !(hdr2->cert & 0xFE))
{ {
switch (ntohs(hdr2->version)) uint16_t h2v = ntohs(hdr2->version);
if ((h2v == 0x0002 || h2v == 0x0300 ||
h2v == 0x0301 || h2v == 0x0303) &&
!(hdr2->cipher_len % 3))
{ {
case 0x0002: goto success;
case 0x0300:
case 0x0301:
case 0x0303:
break;
default:
goto not_v2;
} }
if (hdr2->cipher_len % 3) goto not_v2;
goto success;
not_v2:;
} }
/* it is probably an SSLv3, TLS 1.2, or TLS 1.3 header.
First record must be a handshake (type 22). */
if (size < sizeof(ServiceSSLV3Hdr) || if (size < sizeof(ServiceSSLV3Hdr) ||
hdr3->type != SSL_HANDSHAKE || hdr3->type != SSL_HANDSHAKE ||
(ntohs(hdr3->version) != 0x0300 && (ntohs(hdr3->version) != 0x0300 &&
ntohs(hdr3->version) != 0x0301 && ntohs(hdr3->version) != 0x0301 &&
ntohs(hdr3->version) != 0x0302 && ntohs(hdr3->version) != 0x0302 &&
ntohs(hdr3->version) != 0x0303)) ntohs(hdr3->version) != 0x0303))
{ {
goto fail; goto fail;
} }
data += sizeof(ServiceSSLV3Hdr); data += sizeof(ServiceSSLV3Hdr);
skipping to change at line 645 skipping to change at line 642
ntohs(rec->version) != 0x0301 && ntohs(rec->version) != 0x0301 &&
ntohs(rec->version) != 0x0302 && ntohs(rec->version) != 0x0302 &&
ntohs(rec->version) != 0x0303) || ntohs(rec->version) != 0x0303) ||
rec->length_msb) rec->length_msb)
{ {
goto fail; goto fail;
} }
ss->tot_length = ntohs(hdr3->len); ss->tot_length = ntohs(hdr3->len);
ss->length = ntohs(rec->length) + ss->length = ntohs(rec->length) +
offsetof(ServiceSSLV3Record, version); offsetof(ServiceSSLV3Record, version);
if (size == ss->length) goto success; /* Just a Server Hello. */
if (ss->tot_length < ss->length) goto fail; if (ss->tot_length < ss->length) goto fail;
ss->tot_length -= ss->length; ss->tot_length -= ss->length;
if (size < ss->length) goto fail; if (size < ss->length) goto fail;
data += ss->length; data += ss->length;
size -= ss->length; size -= ss->length;
ss->state = SSL_STATE_HEADER; ss->state = SSL_STATE_HEADER;
ss->pos = 0; ss->pos = 0;
/* fall through */ /* fall through */
case SSL_STATE_HEADER: case SSL_STATE_HEADER:
ss->state = SSL_STATE_DONE;
while (size > 0) while (size > 0)
{ {
if (!ss->pos) if (!ss->pos)
{ {
/* Need to move onto (and past) next header (i.e., record) if /* Need to move onto (and past) next header (i.e., record) if
* previous was completely consumed. */ * previous was completely consumed. */
if (ss->tot_length == 0) if (ss->tot_length == 0)
{ {
hdr3 = (ServiceSSLV3Hdr *)data; hdr3 = (ServiceSSLV3Hdr *)data;
ver = ntohs(hdr3->version); ver = ntohs(hdr3->version);
if (size < sizeof(ServiceSSLV3Hdr) || if (size < sizeof(ServiceSSLV3Hdr) ||
(hdr3->type != SSL_HANDSHAKE && (hdr3->type != SSL_HANDSHAKE &&
hdr3->type != SSL_CHANGE_CIPHER) || hdr3->type != SSL_CHANGE_CIPHER &&
hdr3->type != SSL_APPLICATION_DATA) ||
(ver != 0x0300 && (ver != 0x0300 &&
ver != 0x0301 && ver != 0x0301 &&
ver != 0x0302 && ver != 0x0302 &&
ver != 0x0303)) ver != 0x0303))
{ {
goto fail; goto fail;
} }
if (hdr3->type == SSL_CHANGE_CIPHER)
goto success;
data += sizeof(ServiceSSLV3Hdr); data += sizeof(ServiceSSLV3Hdr);
size -= sizeof(ServiceSSLV3Hdr); size -= sizeof(ServiceSSLV3Hdr);
ss->tot_length = ntohs(hdr3->len); ss->tot_length = ntohs(hdr3->len);
if (hdr3->type == SSL_CHANGE_CIPHER ||
hdr3->type == SSL_APPLICATION_DATA)
{
goto success;
}
} }
rec = (ServiceSSLV3Record *)data; rec = (ServiceSSLV3Record *)data;
if (size < offsetof(ServiceSSLV3Record, version) || if (size < offsetof(ServiceSSLV3Record, version) ||
rec->length_msb) rec->length_msb)
{ {
goto fail; goto fail;
} }
switch (rec->type) switch (rec->type)
{ {
skipping to change at line 713 skipping to change at line 712
ss->in_certs = 1; ss->in_certs = 1;
ss->certs_curr_len = size - sizeof(ServiceSSLV3Certs Record); /* Skip over header to data. */ ss->certs_curr_len = size - sizeof(ServiceSSLV3Certs Record); /* Skip over header to data. */
memcpy(ss->certs_data, data + sizeof(ServiceSSLV3Cer tsRecord), ss->certs_curr_len); memcpy(ss->certs_data, data + sizeof(ServiceSSLV3Cer tsRecord), ss->certs_curr_len);
} }
else else
{ {
/* Can get it all this time. */ /* Can get it all this time. */
ss->in_certs = 0; ss->in_certs = 0;
ss->certs_curr_len = ss->certs_len; ss->certs_curr_len = ss->certs_len;
memcpy(ss->certs_data, data + sizeof(ServiceSSLV3Cer tsRecord), ss->certs_curr_len); memcpy(ss->certs_data, data + sizeof(ServiceSSLV3Cer tsRecord), ss->certs_curr_len);
goto success; /* We got everything we need. */ break;
} }
} }
/* fall through */ /* fall through */
case SSL_CERTIFICATE_STATUS:
case SSL_SERVER_KEY_XCHG: case SSL_SERVER_KEY_XCHG:
case SSL_SERVER_CERT_REQ: case SSL_SERVER_CERT_REQ:
ss->length = ntohs(rec->length) + ss->length = ntohs(rec->length) +
offsetof(ServiceSSLV3Record, version); offsetof(ServiceSSLV3Record, version);
if (size == ss->length) goto success;
if (ss->tot_length < ss->length) goto fail; if (ss->tot_length < ss->length) goto fail;
ss->tot_length -= ss->length; ss->tot_length -= ss->length;
if (size < ss->length) if (size < ss->length)
{ {
ss->pos = size; ss->pos = size;
size = 0; size = 0;
} }
else else
{ {
data += ss->length; data += ss->length;
size -= ss->length; size -= ss->length;
ss->pos = 0; ss->pos = 0;
} }
ss->state = SSL_STATE_HEADER;
break; break;
case SSL_SERVER_HELLO_DONE: case SSL_SERVER_HELLO_DONE:
if (rec->length) goto fail; if (rec->length) goto fail;
if (ss->tot_length != offsetof(ServiceSSLV3Record, version)) if (ss->tot_length != offsetof(ServiceSSLV3Record, version))
goto fail; goto fail;
goto success; goto success;
default: default:
goto fail; goto fail;
} }
} }
skipping to change at line 764 skipping to change at line 762
memcpy(ss->certs_data + ss->certs_curr_len, data, size); memcpy(ss->certs_data + ss->certs_curr_len, data, size);
ss->in_certs = 1; ss->in_certs = 1;
ss->certs_curr_len += size; ss->certs_curr_len += size;
} }
else else
{ {
/* Can get it all this time. */ /* Can get it all this time. */
memcpy(ss->certs_data + ss->certs_curr_len, data, ss->ce rts_len - ss->certs_curr_len); memcpy(ss->certs_data + ss->certs_curr_len, data, ss->ce rts_len - ss->certs_curr_len);
ss->in_certs = 0; ss->in_certs = 0;
ss->certs_curr_len = ss->certs_len; ss->certs_curr_len = ss->certs_len;
goto success; /* We got everything we need. */
} }
} }
if (size+ss->pos < ss->length) if (size+ss->pos < ss->length)
{ {
ss->pos += size; ss->pos += size;
size = 0; size = 0;
} }
else else
{ {
data += ss->length - ss->pos; data += ss->length - ss->pos;
size -= ss->length - ss->pos; size -= ss->length - ss->pos;
ss->pos = 0; ss->pos = 0;
} }
ss->state = SSL_STATE_HEADER;
} }
} }
break; break;
default: default:
goto fail; goto fail;
} }
inprocess: inprocess:
ssl_service_mod.api->service_inprocess(flowp, args->pkt, dir, &svc_element, NULL); ssl_service_mod.api->service_inprocess(flowp, args->pkt, dir, &svc_element, NULL);
return SERVICE_INPROCESS; return SERVICE_INPROCESS;
skipping to change at line 824 skipping to change at line 820
{ {
if (!(flowp->tsession = calloc(1, sizeof(*flowp->tsession)))) if (!(flowp->tsession = calloc(1, sizeof(*flowp->tsession))))
{ {
goto fail; goto fail;
} }
} }
/* TLS Host */ /* TLS Host */
if (ss->host_name) if (ss->host_name)
{ {
if (flowp->tsession->tls_host) /* Do not overwrite SSL provided SNI */
free(flowp->tsession->tls_host); if (!(flowp->scan_flags & SCAN_CERTVIZ_ENABLED_FLAG))
flowp->tsession->tls_host = ss->host_name;
flowp->tsession->tls_host_strlen = ss->host_name_strlen;
flowp->scan_flags |= SCAN_SSL_HOST_FLAG;
}
else if (ss->common_name) // use common name (from server) if we didn
't see host name (from client)
{
char *common_name = strndup(ss->common_name, ss->common_name_strlen)
;
if (common_name)
{ {
if (flowp->tsession->tls_host) if (flowp->tsession->tls_host)
free(flowp->tsession->tls_host); free(flowp->tsession->tls_host);
flowp->tsession->tls_host = common_name; flowp->tsession->tls_host = ss->host_name;
flowp->tsession->tls_host_strlen = ss->common_name_strlen; flowp->tsession->tls_host_strlen = ss->host_name_strlen;
flowp->scan_flags |= SCAN_SSL_HOST_FLAG; flowp->scan_flags |= SCAN_SSL_HOST_FLAG;
} }
} }
else if (ss->common_name) // use common name (from server) if we didn
't see host name (from client)
{
/* Do not overwrite SSL provided SNI */
if (!(flowp->scan_flags & SCAN_CERTVIZ_ENABLED_FLAG))
{
char *common_name = strndup(ss->common_name, ss->common_name_str
len);
if (common_name)
{
if (flowp->tsession->tls_host)
free(flowp->tsession->tls_host);
flowp->tsession->tls_host = common_name;
flowp->tsession->tls_host_strlen = ss->common_name_strlen;
flowp->scan_flags |= SCAN_SSL_HOST_FLAG;
}
}
}
/* TLS Common Name */ /* TLS Common Name */
if (ss->common_name) if (ss->common_name)
{ {
if (flowp->tsession->tls_cname) /* Do not overwrite SSL provided CN */
free(flowp->tsession->tls_cname); if (!(flowp->scan_flags & SCAN_CERTVIZ_ENABLED_FLAG))
flowp->tsession->tls_cname = ss->common_name; {
flowp->tsession->tls_cname_strlen = ss->common_name_strlen; if (flowp->tsession->tls_cname)
flowp->scan_flags |= SCAN_SSL_CERTIFICATE_FLAG; free(flowp->tsession->tls_cname);
flowp->tsession->tls_cname = ss->common_name;
flowp->tsession->tls_cname_strlen = ss->common_name_strlen;
flowp->scan_flags |= SCAN_SSL_CERTIFICATE_FLAG;
}
} }
/* TLS Org Unit */ /* TLS Org Unit */
if (ss->org_name) if (ss->org_name)
{ {
if (flowp->tsession->tls_orgUnit) /* Do not overwrite SSL provided ORG NAME */
free(flowp->tsession->tls_orgUnit); if (!(flowp->scan_flags & SCAN_CERTVIZ_ENABLED_FLAG))
flowp->tsession->tls_orgUnit = ss->org_name; {
flowp->tsession->tls_orgUnit_strlen = ss->org_name_strlen; if (flowp->tsession->tls_orgUnit)
free(flowp->tsession->tls_orgUnit);
flowp->tsession->tls_orgUnit = ss->org_name;
flowp->tsession->tls_orgUnit_strlen = ss->org_name_strlen;
}
} }
ss->host_name = ss->common_name = ss->org_name = NULL; ss->host_name = ss->common_name = ss->org_name = NULL;
flowp->tsession->tls_handshake_done = true;
} }
ssl_service_mod.api->add_service(flowp, args->pkt, dir, &svc_element, ssl_service_mod.api->add_service(flowp, args->pkt, dir, &svc_element,
getSslServiceAppId(args->pkt->src_port), NU LL, NULL, NULL, NULL); getSslServiceAppId(args->pkt->src_port), NU LL, NULL, NULL, NULL);
return SERVICE_SUCCESS; return SERVICE_SUCCESS;
} }
tAppId getSslServiceAppId( short srcPort) tAppId getSslServiceAppId( short srcPort)
{ {
switch (srcPort) switch (srcPort)
{ {
skipping to change at line 890 skipping to change at line 903
return APP_ID_SMTPS; return APP_ID_SMTPS;
case 563: case 563:
return APP_ID_NNTPS; return APP_ID_NNTPS;
case 585: /*Currently 585 is de-registered at IANA but old implementation m ay still use it. */ case 585: /*Currently 585 is de-registered at IANA but old implementation m ay still use it. */
case 993: case 993:
return APP_ID_IMAPS; return APP_ID_IMAPS;
case 614: case 614:
return APP_ID_SSHELL; return APP_ID_SSHELL;
case 636: case 636:
return APP_ID_LDAPS; return APP_ID_LDAPS;
case 853:
return APP_ID_DNS_OVER_TLS;
case 989: case 989:
return APP_ID_FTPSDATA; return APP_ID_FTPSDATA;
case 990: case 990:
return APP_ID_FTPS; return APP_ID_FTPS;
case 992: case 992:
return APP_ID_TELNETS; return APP_ID_TELNETS;
case 994: case 994:
return APP_ID_IRCS; return APP_ID_IRCS;
case 995: case 995:
return APP_ID_POP3S; return APP_ID_POP3S;
 End of changes. 30 change blocks. 
50 lines changed or deleted 65 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)