1 /*
2 * Copyright (C) 2014-2021 Cisco and/or its affiliates. All rights reserved.
3 * Copyright (C) 2007-2013 Sourcefire, Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License Version 2 as
7 * published by the Free Software Foundation. You may not use, modify or
8 * distribute this program under any other version of the GNU General
9 * Public License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21 /*
22 * File: ssl_config.c
23 * Author: Bhagyashree Bantwal <bbantwal@cisco.com>
24 * Brief: Configuration for the SSL preprocessor
25 */
26
27
28 #include "ssl_config.h"
29 #ifdef ENABLE_HA
30 #include "ssl_ha.h"
31 #endif
32 #include <errno.h>
33
34 #define PATH_MAX 4096
35 #define MIN_HB_LEN 0
36 #define MAX_HB_LEN 65535
37
38 #ifdef TARGET_BASED
39 int16_t ssl_app_id = SFTARGET_UNKNOWN_PROTOCOL;
40 #endif
41
42 #ifdef PERF_PROFILING
43 PreprocStats sslpp_perf_stats;
44 #endif
45
46
47 tSfPolicyUserContextId ssl_config = NULL;
48
49 static void SSLFreeConfig(tSfPolicyUserContextId config, bool full_cleanup);
50 static void SSLCleanExit(int, void *);
51 static void SSLResetStats(int, void *);
52 static int SSLPP_CheckConfig(struct _SnortConfig *);
53
54 /* Parsing for the ssl_state rule option */
SSLPP_state_init(struct _SnortConfig * sc,char * name,char * params,void ** data)55 static int SSLPP_state_init(struct _SnortConfig *sc, char *name, char *params, void **data)
56 {
57 int flags = 0, mask = 0;
58 char *end = NULL;
59 char *tok;
60 SslRuleOptData *sdata;
61
62 tok = strtok_r(params, ",", &end);
63
64 if(!tok)
65 DynamicPreprocessorFatalMessage("%s(%d) => missing argument to"
66 "ssl_state keyword\n", *(_dpd.config_file), *(_dpd.config_line));
67
68 do
69 {
70 int negated = 0;
71
72 if (tok[0] == '!')
73 {
74 negated = 1;
75 tok++;
76 }
77
78 if(!strcasecmp("client_hello", tok))
79 {
80 flags |= SSL_CUR_CLIENT_HELLO_FLAG;
81 if (negated)
82 mask |= SSL_CUR_CLIENT_HELLO_FLAG;
83 }
84 else if(!strcasecmp("server_hello", tok))
85 {
86 flags |= SSL_CUR_SERVER_HELLO_FLAG;
87 if (negated)
88 mask |= SSL_CUR_SERVER_HELLO_FLAG;
89 }
90 else if(!strcasecmp("client_keyx", tok))
91 {
92 flags |= SSL_CUR_CLIENT_KEYX_FLAG;
93 if (negated)
94 mask |= SSL_CUR_CLIENT_KEYX_FLAG;
95 }
96 else if(!strcasecmp("server_keyx", tok))
97 {
98 flags |= SSL_CUR_SERVER_KEYX_FLAG;
99 if (negated)
100 mask |= SSL_CUR_SERVER_KEYX_FLAG;
101 }
102 else if(!strcasecmp("unknown", tok))
103 {
104 flags |= SSL_UNKNOWN_FLAG;
105 if (negated)
106 mask |= SSL_UNKNOWN_FLAG;
107 }
108 else
109 {
110 DynamicPreprocessorFatalMessage(
111 "%s(%d) => %s is not a recognized argument to %s.\n",
112 *(_dpd.config_file), _dpd.config_file, tok, name);
113 }
114
115 } while( (tok = strtok_r(NULL, ",", &end)) != NULL );
116
117 sdata = (SslRuleOptData *)calloc(1, sizeof(*sdata));
118 if (sdata == NULL)
119 {
120 DynamicPreprocessorFatalMessage("Could not allocate memory for the "
121 "ssl_state preprocessor rule option.\n");
122 }
123
124 sdata->flags = flags;
125 sdata->mask = mask;
126 *data = (void *)sdata;
127
128 return 1;
129 }
130
131 /* Parsing for the ssl_version rule option */
SSLPP_ver_init(struct _SnortConfig * sc,char * name,char * params,void ** data)132 static int SSLPP_ver_init(struct _SnortConfig *sc, char *name, char *params, void **data)
133 {
134 int flags = 0, mask = 0;
135 char *end = NULL;
136 char *tok;
137 SslRuleOptData *sdata;
138
139 tok = strtok_r(params, ",", &end);
140
141 if(!tok)
142 DynamicPreprocessorFatalMessage("%s(%d) => missing argument to"
143 "ssl_state keyword\n", *(_dpd.config_file), *(_dpd.config_line));
144
145 do
146 {
147 int negated = 0;
148
149 if (tok[0] == '!')
150 {
151 negated = 1;
152 tok++;
153 }
154
155 if(!strcasecmp("sslv2", tok))
156 {
157 flags |= SSL_VER_SSLV2_FLAG;
158 if (negated)
159 mask |= SSL_VER_SSLV2_FLAG;
160 }
161 else if(!strcasecmp("sslv3", tok))
162 {
163 flags |= SSL_VER_SSLV3_FLAG;
164 if (negated)
165 mask |= SSL_VER_SSLV3_FLAG;
166 }
167 else if(!strcasecmp("tls1.0", tok))
168 {
169 flags |= SSL_VER_TLS10_FLAG;
170 if (negated)
171 mask |= SSL_VER_TLS10_FLAG;
172 }
173 else if(!strcasecmp("tls1.1", tok))
174 {
175 flags |= SSL_VER_TLS11_FLAG;
176 if (negated)
177 mask |= SSL_VER_TLS11_FLAG;
178 }
179 else if(!strcasecmp("tls1.2", tok))
180 {
181 flags |= SSL_VER_TLS12_FLAG;
182 if (negated)
183 mask |= SSL_VER_TLS12_FLAG;
184 }
185 else
186 {
187 DynamicPreprocessorFatalMessage(
188 "%s(%d) => %s is not a recognized argument to %s.\n",
189 *(_dpd.config_file), _dpd.config_file, tok, name);
190 }
191
192 } while( (tok = strtok_r(NULL, ",", &end)) != NULL );
193
194 sdata = (SslRuleOptData *)calloc(1, sizeof(*sdata));
195 if (sdata == NULL)
196 {
197 DynamicPreprocessorFatalMessage("Could not allocate memory for the "
198 "ssl_version preprocessor rule option.\n");
199 }
200
201 sdata->flags = flags;
202 sdata->mask = mask;
203 *data = (void *)sdata;
204
205 return 1;
206 }
207
UpdatePathToDir(char * full_path_dirname,unsigned int max_size,char * dirname)208 static void UpdatePathToDir(char *full_path_dirname, unsigned int max_size, char *dirname)
209 {
210 int iRet;
211 char *snort_conf_dir = *(_dpd.snort_conf_dir);
212
213 if (!snort_conf_dir || !(*snort_conf_dir) || !full_path_dirname || !dirname)
214 {
215 DynamicPreprocessorFatalMessage(" %s(%d) => can't create path.\n",
216 *(_dpd.config_file), *(_dpd.config_line));
217 }
218 /*dirname is too long*/
219 if ( max_size < strlen(dirname) )
220 {
221 DynamicPreprocessorFatalMessage(" %s(%d) => the dir name length %u is longer than allowed %u.\n",
222 *(_dpd.config_file), *(_dpd.config_line), strlen(dirname), max_size);
223 }
224
225 /*
226 * If an absolute path is specified, then use that.
227 */
228 #ifndef WIN32
229 if(dirname[0] == '/')
230 {
231 iRet = snprintf(full_path_dirname, max_size, "%s", dirname);
232 }
233 else
234 {
235 /*
236 * Set up the dir name directory.
237 */
238 if (snort_conf_dir[strlen(snort_conf_dir) - 1] == '/')
239 {
240 iRet = snprintf(full_path_dirname,max_size,
241 "%s%s", snort_conf_dir, dirname);
242 }
243 else
244 {
245 iRet = snprintf(full_path_dirname, max_size,
246 "%s/%s", snort_conf_dir, dirname);
247 }
248 }
249 #else
250 if(strlen(dirname)>3 && dirname[1]==':' && dirname[2]=='\\')
251 {
252 iRet = snprintf(full_path_dirname, max_size, "%s", dirname);
253 }
254 else
255 {
256 /*
257 ** Set up the dir name directory
258 */
259 if (snort_conf_dir[strlen(snort_conf_dir) - 1] == '\\' ||
260 snort_conf_dir[strlen(snort_conf_dir) - 1] == '/' )
261 {
262 iRet = snprintf(full_path_dirname,max_size,
263 "%s%s", snort_conf_dir, dirname);
264 }
265 else
266 {
267 iRet = snprintf(full_path_dirname, max_size,
268 "%s\\%s", snort_conf_dir, dirname);
269 }
270 }
271 #endif
272
273 if(iRet < 0)
274 {
275 DynamicPreprocessorFatalMessage(" %s(%d) => the dir name length %u is longer than allowed %u.\n",
276 *(_dpd.config_file), *(_dpd.config_line), strlen(dirname), max_size);
277 }
278 }
279
280 /* SSL Preprocessor configuration parsing */
SSLPP_config(SSLPP_config_t * config,char * conf)281 static void SSLPP_config(SSLPP_config_t *config, char *conf)
282 {
283 char *saveptr;
284 char *space_tok;
285 char *comma_tok;
286 char *portptr;
287 char *search;
288 SFP_errstr_t err;
289
290 if(!conf)
291 return;
292
293 if (config == NULL)
294 return;
295
296 search = conf;
297
298 while( (comma_tok = strtok_r(search, ",", &saveptr)) != NULL )
299 {
300 search = NULL;
301
302 space_tok = strtok_r(comma_tok, " ", &portptr);
303
304 if(!space_tok)
305 return;
306
307 if(!strcasecmp(space_tok, "ports"))
308 {
309 memset(config->ports, 0, sizeof(config->ports));
310
311 if(SFP_ports(config->ports, portptr, err) != SFP_SUCCESS)
312 DynamicPreprocessorFatalMessage(
313 "%s(%d) => Failed to parse: %s\n",
314 *(_dpd.config_file), *(_dpd.config_line), SFP_GET_ERR(err));
315
316 }
317 else if(!strcasecmp(space_tok, "noinspect_encrypted"))
318 {
319 char *tmpChar;
320 tmpChar = strtok_r(NULL, " \t\n", &portptr);
321 if(tmpChar)
322 {
323 DynamicPreprocessorFatalMessage("%s(%d) => Invalid argument to the"
324 " SSL preprocessor: '%s' in %s\n",
325 *(_dpd.config_file), *(_dpd.config_line), space_tok, tmpChar);
326 }
327 config->flags |= SSLPP_DISABLE_FLAG;
328 }
329 else if(!strcasecmp(space_tok, "trustservers"))
330 {
331 char *tmpChar;
332 tmpChar = strtok_r(NULL, " \t\n", &portptr);
333 if(tmpChar)
334 {
335 DynamicPreprocessorFatalMessage("%s(%d) => Invalid argument to the"
336 " SSL preprocessor: '%s' in %s\n",
337 *(_dpd.config_file), *(_dpd.config_line), space_tok, tmpChar);
338 }
339 config->flags |= SSLPP_TRUSTSERVER_FLAG;
340 }
341 else if(!strcasecmp(space_tok, "pki_dir"))
342 {
343 char *tmpChar;
344 char full_path_dirname[PATH_MAX+1];
345 tmpChar = strtok_r(NULL, " \t\n", &portptr);
346 if(tmpChar == NULL)
347 {
348 DynamicPreprocessorFatalMessage("%s(%d) => Invalid argument to '%s' option in the"
349 " SSL preprocessor\n",
350 *(_dpd.config_file), *(_dpd.config_line), space_tok);
351 }
352 UpdatePathToDir(full_path_dirname, PATH_MAX, tmpChar);
353 config->pki_dir = strdup(full_path_dirname);
354 if (!config->pki_dir)
355 {
356 DynamicPreprocessorFatalMessage("%s(%d) Failed to allocate memory for "
357 "option in SSL preprocessor\n", __FILE__, __LINE__);
358 }
359 }
360 else if(!strcasecmp(space_tok, "ssl_rules_dir"))
361 {
362 char *tmpChar;
363 char full_path_dirname[PATH_MAX+1];
364 tmpChar = strtok_r(NULL, " \t\n", &portptr);
365 if(tmpChar == NULL)
366 {
367 DynamicPreprocessorFatalMessage("%s(%d) => Invalid argument to '%s' option in the"
368 " SSL preprocessor\n",
369 *(_dpd.config_file), *(_dpd.config_line), space_tok);
370 }
371 UpdatePathToDir(full_path_dirname, PATH_MAX, tmpChar);
372 config->ssl_rules_dir = strdup(full_path_dirname);
373 if (!config->ssl_rules_dir)
374 {
375 DynamicPreprocessorFatalMessage("%s(%d) Failed to allocate memory for "
376 "option in SSL preprocessor\n", __FILE__, __LINE__);
377 }
378 }
379 else if(!strcasecmp(space_tok, "memcap"))
380 {
381 int value;
382 char *endStr = NULL;
383 char *tmpChar;
384
385 tmpChar = strtok_r(NULL, " \t\n", &portptr);
386 if(tmpChar == NULL)
387 {
388 DynamicPreprocessorFatalMessage("%s(%d) => Invalid argument to '%s' option in the"
389 " SSL preprocessor\n",
390 *(_dpd.config_file), *(_dpd.config_line), space_tok);
391 }
392
393 value = _dpd.SnortStrtol( tmpChar, &endStr, 10);
394
395 if (( *endStr) || (errno == ERANGE))
396 {
397 DynamicPreprocessorFatalMessage("%s(%d) => Invalid argument to '%s' option in the"
398 " SSL preprocessor\n",
399 *(_dpd.config_file), *(_dpd.config_line), space_tok);
400 }
401
402 config->memcap = value;
403
404 }
405 else if(!strcasecmp(space_tok, "decrypt_memcap"))
406 {
407 int value;
408 char *endStr = NULL;
409 char *tmpChar;
410
411 tmpChar = strtok_r(NULL, " \t\n", &portptr);
412 if(tmpChar == NULL)
413 {
414 DynamicPreprocessorFatalMessage("%s(%d) => Invalid argument to '%s' option in the"
415 " SSL preprocessor\n",
416 *(_dpd.config_file), *(_dpd.config_line), space_tok);
417 }
418
419 value = _dpd.SnortStrtol( tmpChar, &endStr, 10);
420
421 if (( *endStr) || (errno == ERANGE))
422 {
423 DynamicPreprocessorFatalMessage("%s(%d) => Invalid argument to '%s' option in the"
424 " SSL preprocessor\n",
425 *(_dpd.config_file), *(_dpd.config_line), space_tok);
426 }
427
428 config->decrypt_memcap = value;
429
430 }
431 #ifdef ENABLE_HA
432 else if(!strcasecmp(space_tok, "enable_ssl_ha"))
433 {
434 char *tmpChar;
435 tmpChar = strtok_r(NULL, " \t\n", &portptr);
436 if(tmpChar == NULL)
437 {
438 DynamicPreprocessorFatalMessage("%s(%d) => Invalid argument to '%s' option in the"
439 " SSL preprocessor\n",
440 *(_dpd.config_file), *(_dpd.config_line), space_tok);
441 }
442 if(!strcasecmp(tmpChar, "yes"))
443 config->enable_ssl_ha = true;
444 else if(!strcasecmp(tmpChar, "no"))
445 config->enable_ssl_ha = false;
446 else
447 {
448 DynamicPreprocessorFatalMessage("%s(%d) => Invalid argument '%s' to '%s' option in the"
449 " SSL preprocessor\n",
450 *(_dpd.config_file), *(_dpd.config_line), tmpChar, space_tok);
451 }
452 }
453 #endif
454 else if(!strcasecmp(space_tok, "max_heartbeat_length"))
455 {
456 int value;
457 char *endStr = NULL;
458 char *tmpChar;
459
460 tmpChar = strtok_r(NULL, " \t\n", &portptr);
461 if(tmpChar == NULL)
462 {
463 DynamicPreprocessorFatalMessage("%s(%d) => Invalid argument to '%s' option in the"
464 " SSL preprocessor\n",
465 *(_dpd.config_file), *(_dpd.config_line), space_tok);
466 }
467
468 value = _dpd.SnortStrtol( tmpChar, &endStr, 10);
469
470 if (( *endStr) || (errno == ERANGE))
471 {
472 DynamicPreprocessorFatalMessage("%s(%d) => Invalid argument to '%s' option in the"
473 " SSL preprocessor\n",
474 *(_dpd.config_file), *(_dpd.config_line), space_tok);
475 }
476
477 if (value < MIN_HB_LEN || value > MAX_HB_LEN)
478 {
479 DynamicPreprocessorFatalMessage(" %s(%d) => Value specified for %s is out of "
480 "bounds. Please specify an integer between %d and %d.\n",
481 *(_dpd.config_file), *(_dpd.config_line),
482 space_tok, MIN_HB_LEN, MAX_HB_LEN);
483 }
484
485 config->max_heartbeat_len = value;
486 }
487 else
488 {
489 DynamicPreprocessorFatalMessage("%s(%d) => Invalid argument to the"
490 " SSL preprocessor: '%s' in %s\n",
491 *(_dpd.config_file), *(_dpd.config_line), comma_tok, conf);
492 }
493 }
494
495 /* Verify configured options make sense */
496 if ((config->flags & SSLPP_TRUSTSERVER_FLAG) &&
497 !(config->flags & SSLPP_DISABLE_FLAG))
498 {
499 DynamicPreprocessorFatalMessage("%s(%d) => SSL preprocessor: 'trustservers' "
500 "requires 'noinspect_encrypted' to be useful.\n",
501 *(_dpd.config_file), *(_dpd.config_line));
502 }
503 }
504
SSLPP_print_config(SSLPP_config_t * config)505 static void SSLPP_print_config(SSLPP_config_t *config)
506 {
507 char buf[1024]; /* For syslog printing */
508 int i;
509 int newline;
510
511 if (config == NULL)
512 return;
513
514 memset(buf, 0, sizeof(buf));
515
516 _dpd.logMsg("SSLPP config:\n");
517 _dpd.logMsg(" Encrypted packets: %s\n",
518 config->flags & SSLPP_DISABLE_FLAG ? "not inspected" : "inspected");
519
520 _dpd.logMsg(" Ports:\n");
521
522 for(newline = 0, i = 0; i < MAXPORTS; i++)
523 {
524 if( config->ports[ PORT_INDEX(i) ] & CONV_PORT(i) )
525 {
526 SFP_snprintfa(buf, sizeof(buf), " %5d", i);
527 if( !((++newline) % 5) )
528 {
529 SFP_snprintfa(buf, sizeof(buf), "\n");
530 _dpd.logMsg(buf);
531 memset(buf, 0, sizeof(buf));
532 }
533 }
534 }
535
536 if(newline % 5)
537 SFP_snprintfa(buf, sizeof(buf), "\n");
538
539 _dpd.logMsg(buf);
540
541 if ( config->flags & SSLPP_TRUSTSERVER_FLAG )
542 {
543 _dpd.logMsg(" Server side data is trusted\n");
544 }
545
546 if ( config->pki_dir )
547 {
548 _dpd.logMsg(" PKI Directory: %s\n", config->pki_dir);
549 }
550
551 if ( config->ssl_rules_dir )
552 {
553 _dpd.logMsg(" SSL Rules Directory: %s\n", config->ssl_rules_dir);
554 }
555
556 #ifdef ENABLE_HA
557 _dpd.logMsg(" SSL HA enabled : %s\n", config->enable_ssl_ha ? "YES" : "NO" );
558 #endif
559 _dpd.logMsg(" Maximum SSL Heartbeat length: %d\n", config->max_heartbeat_len);
560
561 }
562
SSLSetPort(SSLPP_config_t * config,int port)563 static inline void SSLSetPort(SSLPP_config_t *config, int port)
564 {
565 if (config == NULL)
566 return;
567
568 config->ports[ PORT_INDEX(port) ] |= CONV_PORT(port);
569 }
570
571
572
SSLPP_init_config(SSLPP_config_t * config)573 static void SSLPP_init_config(SSLPP_config_t *config)
574 {
575 if (config == NULL)
576 return;
577 config->ssl_rules_dir = NULL;
578 config->pki_dir = NULL;
579 config->memcap = 100000;
580 config->enable_ssl_ha = false;
581 config->decrypt_memcap = 100000;
582 config->current_handle = NULL;
583 config->reload_handle = NULL;
584 config->max_heartbeat_len = 0;
585
586 /* Setup default ports */
587 SSLSetPort(config, 443); /* HTTPS */
588 SSLSetPort(config, 465); /* SMTPS */
589 SSLSetPort(config, 563); /* NNTPS */
590 SSLSetPort(config, 636); /* LDAPS */
591 SSLSetPort(config, 989); /* FTPS */
592 SSLSetPort(config, 992); /* TelnetS */
593 SSLSetPort(config, 993); /* IMAPS */
594 SSLSetPort(config, 994); /* IRCS */
595 SSLSetPort(config, 995); /* POPS */
596 }
597
registerPortsForDispatch(struct _SnortConfig * sc,SSLPP_config_t * policy)598 static void registerPortsForDispatch( struct _SnortConfig *sc, SSLPP_config_t *policy )
599 {
600 int port;
601
602 for ( port = 0; port < MAXPORTS; port++ )
603 {
604 if( policy->ports[ port / 8 ] & ( 1 << ( port % 8 ) ) )
605 {
606 _dpd.sessionAPI->enable_preproc_for_port( sc, PP_SSL, PROTO_BIT__TCP, port );
607 }
608 }
609 }
610
registerPortsForReassembly(SSLPP_config_t * policy,int direction)611 static void registerPortsForReassembly( SSLPP_config_t *policy, int direction )
612 {
613 uint32_t port;
614
615 for ( port = 0; port < MAXPORTS; port++ )
616 {
617 if( policy->ports[ port / 8 ] & ( 1 << ( port % 8 ) ) )
618 {
619 _dpd.streamAPI->register_reassembly_port( NULL, port, direction );
620 }
621 }
622 }
623
624
_addPortsToStream5Filter(struct _SnortConfig * sc,SSLPP_config_t * config,tSfPolicyId policy_id)625 static void _addPortsToStream5Filter(struct _SnortConfig *sc, SSLPP_config_t *config, tSfPolicyId policy_id)
626 {
627 unsigned int portNum;
628
629 if (config == NULL)
630 return;
631
632 for (portNum = 0; portNum < MAXPORTS; portNum++)
633 {
634 if(config->ports[(portNum/8)] & (1<<(portNum%8)))
635 {
636 //Add port the port
637 _dpd.streamAPI->set_port_filter_status
638 (sc, IPPROTO_TCP, (uint16_t)portNum, PORT_MONITOR_SESSION, policy_id, 1);
639 }
640 }
641 }
642
643 #ifdef TARGET_BASED
_addServicesToStream5Filter(struct _SnortConfig * sc,tSfPolicyId policy_id)644 static void _addServicesToStream5Filter(struct _SnortConfig *sc, tSfPolicyId policy_id)
645 {
646 _dpd.streamAPI->set_service_filter_status
647 (sc, ssl_app_id, PORT_MONITOR_SESSION, policy_id, 1);
648 }
649 #endif
650
SSLPP_init(struct _SnortConfig * sc,char * args)651 void SSLPP_init(struct _SnortConfig *sc, char *args)
652 {
653 tSfPolicyId policy_id = _dpd.getParserPolicy(sc);
654 SSLPP_config_t *pPolicyConfig = NULL;
655
656 /* For SFR CLI*/
657 _dpd.controlSocketRegisterHandler(CS_TYPE_SSL_STATS, NULL, NULL, &DisplaySSLPPStats);
658 if (ssl_config == NULL)
659 {
660 //create a context
661 ssl_config = sfPolicyConfigCreate();
662
663 if (ssl_config == NULL)
664 {
665 DynamicPreprocessorFatalMessage("Could not allocate memory for the "
666 "SSL preprocessor configuration.\n");
667 }
668
669 if (_dpd.streamAPI == NULL)
670 {
671 DynamicPreprocessorFatalMessage(
672 "SSLPP_init(): The Stream preprocessor must be enabled.\n");
673 }
674
675 SSL_InitGlobals();
676
677 _dpd.registerPreprocStats("ssl", SSLPP_drop_stats);
678 _dpd.addPreprocConfCheck(sc, SSLPP_CheckConfig);
679 _dpd.addPreprocExit(SSLCleanExit, NULL, PRIORITY_LAST, PP_SSL);
680 _dpd.addPreprocResetStats(SSLResetStats, NULL, PRIORITY_LAST, PP_SSL);
681
682 #ifdef PERF_PROFILING
683 _dpd.addPreprocProfileFunc("ssl", (void *)&sslpp_perf_stats, 0, _dpd.totalPerfStats, NULL);
684 #endif
685
686 #ifdef ENABLE_HA
687 _dpd.addFuncToPostConfigList(sc, SSLHAPostConfigInit, NULL);
688 #endif
689
690 #ifdef TARGET_BASED
691 ssl_app_id = _dpd.findProtocolReference("ssl");
692 if (ssl_app_id == SFTARGET_UNKNOWN_PROTOCOL)
693 {
694 ssl_app_id = _dpd.addProtocolReference("ssl");
695 }
696 _dpd.sessionAPI->register_service_handler( PP_SSL, ssl_app_id );
697 #endif
698 }
699
700 sfPolicyUserPolicySet (ssl_config, policy_id);
701 pPolicyConfig = (SSLPP_config_t *)sfPolicyUserDataGetCurrent(ssl_config);
702 if (pPolicyConfig != NULL)
703 {
704 DynamicPreprocessorFatalMessage("SSL preprocessor can only be "
705 "configured once.\n");
706 }
707
708 pPolicyConfig = (SSLPP_config_t *)calloc(1, sizeof(SSLPP_config_t));
709 if (pPolicyConfig == NULL)
710 {
711 DynamicPreprocessorFatalMessage("Could not allocate memory for the "
712 "SSL preprocessor configuration.\n");
713 }
714
715 sfPolicyUserDataSetCurrent(ssl_config, pPolicyConfig);
716
717 SSLPP_init_config(pPolicyConfig);
718 SSLPP_config(pPolicyConfig, args);
719 SSLPP_print_config(pPolicyConfig);
720
721 _dpd.preprocOptRegister(sc, "ssl_state", SSLPP_state_init, SSLPP_rule_eval,
722 free, NULL, NULL, NULL, NULL);
723 _dpd.preprocOptRegister(sc, "ssl_version", SSLPP_ver_init, SSLPP_rule_eval,
724 free, NULL, NULL, NULL, NULL);
725
726 _dpd.addPreproc( sc, SSLPP_process, PRIORITY_APPLICATION, PP_SSL, PROTO_BIT__TCP );
727
728 registerPortsForDispatch( sc, pPolicyConfig );
729 registerPortsForReassembly( pPolicyConfig, SSN_DIR_FROM_SERVER | SSN_DIR_FROM_CLIENT );
730 _addPortsToStream5Filter(sc, pPolicyConfig, policy_id);
731
732 #ifdef TARGET_BASED
733 _addServicesToStream5Filter(sc, policy_id);
734 #endif
735
736 }
737
SSLFreeConfigPolicy(tSfPolicyUserContextId config,tSfPolicyId policyId,void * pData)738 static int SSLFreeConfigPolicy(
739 tSfPolicyUserContextId config,
740 tSfPolicyId policyId,
741 void* pData
742 )
743 {
744 SSLPP_config_t *pPolicyConfig = (SSLPP_config_t *)pData;
745
746 //do any housekeeping before freeing SSLPP_config_t
747 sfPolicyUserDataClear (config, policyId);
748
749 if(pPolicyConfig->pki_dir)
750 free(pPolicyConfig->pki_dir);
751
752 if(pPolicyConfig->ssl_rules_dir)
753 free(pPolicyConfig->ssl_rules_dir);
754
755
756 free(pPolicyConfig);
757
758 return 0;
759 }
760
SSLFreeConfig(tSfPolicyUserContextId config,bool full_cleanup)761 static void SSLFreeConfig(tSfPolicyUserContextId config, bool full_cleanup)
762 {
763 SSLPP_config_t *defaultConfig;
764 ssl_callback_interface_t *ssl_cb = (ssl_callback_interface_t *)_dpd.getSSLCallback();
765 if (config == NULL)
766 return;
767
768 defaultConfig = (SSLPP_config_t *)sfPolicyUserDataGetDefault(config);
769
770 if(defaultConfig && ssl_cb)
771 {
772 ssl_cb->policy_free(&(defaultConfig->current_handle), full_cleanup);
773 #ifdef ENABLE_HA
774 if(defaultConfig->ssl_ha_config)
775 {
776 SSLHAConfigFree(defaultConfig->ssl_ha_config);
777 defaultConfig->ssl_ha_config = NULL;
778 }
779 #endif
780 }
781
782 sfPolicyUserDataFreeIterate (config, SSLFreeConfigPolicy);
783 sfPolicyConfigDelete(config);
784 }
785
SSLCleanExit(int signal,void * data)786 static void SSLCleanExit(int signal, void *data)
787 {
788 if (ssl_config != NULL)
789 {
790 #ifdef ENABLE_HA
791 SSLCleanHA();
792 #endif
793 SSLFreeConfig(ssl_config, true);
794 ssl_config = NULL;
795 }
796 }
797
SSLResetStats(int signal,void * data)798 static void SSLResetStats(int signal, void *data)
799 {
800 SSL_InitGlobals();
801 #ifdef ENABLE_HA
802 SSLResetHAStats();
803 #endif
804 }
805
SSLPP_SetSSLPolicy(struct _SnortConfig * sc,tSfPolicyUserContextId config,tSfPolicyId policyId,void * pData)806 static int SSLPP_SetSSLPolicy(struct _SnortConfig *sc,
807 tSfPolicyUserContextId config,
808 tSfPolicyId policyId,
809 void* pData
810 )
811 {
812 _dpd.setSSLPolicyEnabled(sc, policyId, true);
813
814 return 0;
815 }
816
SSLPP_PolicyInit(struct _SnortConfig * sc,tSfPolicyUserContextId ssl_config,SSLPP_config_t * pPolicyConfig,tSfPolicyId policyId,bool reloading)817 static int SSLPP_PolicyInit(struct _SnortConfig *sc, tSfPolicyUserContextId ssl_config, SSLPP_config_t *pPolicyConfig, tSfPolicyId policyId, bool reloading)
818 {
819 ssl_callback_interface_t *ssl_cb = (ssl_callback_interface_t *)_dpd.getSSLCallback();
820 // Load SSL once for default policy
821 if (pPolicyConfig != NULL)
822 {
823 if(pPolicyConfig->pki_dir && pPolicyConfig->ssl_rules_dir && ssl_cb)
824 {
825 if ( ssl_cb->policy_initialize(pPolicyConfig, reloading) != 0 )
826 {
827 _dpd.errMsg(
828 "SSLPP_PolicyInit(): Failed to initialize ssl_rules_dir and pki_dir.\n");
829 return -1;
830 }
831 else
832 {
833 if((sfPolicyUserDataIterate (sc, ssl_config, SSLPP_SetSSLPolicy))!= 0)
834 {
835 _dpd.errMsg(
836 "SSLPP_PolicyInit(): SetSSLpolicy failed.\n");
837 return -1;
838 }
839 }
840 }
841 }
842
843 return 0;
844 }
845
SSLPP_CheckPolicyConfig(struct _SnortConfig * sc,tSfPolicyUserContextId config,tSfPolicyId policyId,void * pData)846 static int SSLPP_CheckPolicyConfig(
847 struct _SnortConfig *sc,
848 tSfPolicyUserContextId config,
849 tSfPolicyId policyId,
850 void* pData
851 )
852 {
853 _dpd.setParserPolicy(sc, policyId);
854
855 if (!_dpd.isPreprocEnabled(sc, PP_STREAM))
856 {
857 _dpd.errMsg(
858 "SSLPP_CheckPolicyConfig(): The Stream preprocessor must be enabled.\n");
859 return -1;
860 }
861
862 return 0;
863 }
864
865
866 // Enable SSL preproc for any policies that have inspection turned on.
SSLPP_CheckPolicyEnabled(struct _SnortConfig * sc,tSfPolicyUserContextId config,tSfPolicyId policyId,void * pData)867 static int SSLPP_CheckPolicyEnabled(
868 struct _SnortConfig *sc,
869 tSfPolicyUserContextId config,
870 tSfPolicyId policyId,
871 void* pData
872 )
873 {
874 if(_dpd.isSSLPolicyEnabled(sc))
875 {
876 // Send packets to SSL preproc even when only doing Network Discovery.
877 _dpd.reenablePreprocBit(sc, PP_SSL);
878 }
879
880 return 0;
881 }
882
883
SSLPP_CheckConfig(struct _SnortConfig * sc)884 static int SSLPP_CheckConfig(struct _SnortConfig *sc)
885 {
886 #ifdef ENABLE_HA
887 int haNotConfigured = 0;
888 #endif
889 int rval;
890 SSLPP_config_t *defaultConfig =
891 (SSLPP_config_t *)sfPolicyUserDataGetDefault(ssl_config);
892
893 if ((rval = sfPolicyUserDataIterate (sc, ssl_config, SSLPP_CheckPolicyConfig)))
894 return rval;
895
896 // Load SSL once for default policy
897 if (defaultConfig)
898 {
899 if( SSLPP_PolicyInit(sc, ssl_config, defaultConfig, _dpd.getDefaultPolicy(), false) != 0 )
900 return -1;
901
902 #ifdef ENABLE_HA
903 if (defaultConfig->enable_ssl_ha)
904 {
905 haNotConfigured = (SSLVerifyHAConfig(sc, defaultConfig->ssl_ha_config) != 0);
906 if (haNotConfigured)
907 {
908 _dpd.errMsg("WARNING: SSL HA misconfigured.\n");
909 return -1;
910 }
911 }
912 #endif
913 }
914
915 if ((rval = sfPolicyUserDataIterate (sc, ssl_config, SSLPP_CheckPolicyEnabled)))
916 return rval;
917
918 return 0;
919 }
920
921 #ifdef SNORT_RELOAD
SSLReload(struct _SnortConfig * sc,char * args,void ** new_config)922 void SSLReload(struct _SnortConfig *sc, char *args, void **new_config)
923 {
924 tSfPolicyUserContextId ssl_swap_config = (tSfPolicyUserContextId)*new_config;
925 tSfPolicyId policy_id = _dpd.getParserPolicy(sc);
926 SSLPP_config_t * pPolicyConfig = NULL;
927
928 if (ssl_swap_config == NULL)
929 {
930 //create a context
931 ssl_swap_config = sfPolicyConfigCreate();
932
933 if (ssl_swap_config == NULL)
934 {
935 DynamicPreprocessorFatalMessage("Could not allocate memory for the "
936 "SSL preprocessor configuration.\n");
937 }
938
939 if (_dpd.streamAPI == NULL)
940 {
941 DynamicPreprocessorFatalMessage(
942 "SSLPP_init(): The Stream preprocessor must be enabled.\n");
943 }
944 *new_config = (void *)ssl_swap_config;
945 }
946
947 sfPolicyUserPolicySet (ssl_swap_config, policy_id);
948 pPolicyConfig = (SSLPP_config_t *)sfPolicyUserDataGetCurrent(ssl_swap_config);
949 if (pPolicyConfig != NULL)
950 {
951 DynamicPreprocessorFatalMessage("SSL preprocessor can only be "
952 "configured once.\n");
953 }
954
955 pPolicyConfig = (SSLPP_config_t *)calloc(1, sizeof(SSLPP_config_t));
956 if (pPolicyConfig == NULL)
957 {
958 DynamicPreprocessorFatalMessage("Could not allocate memory for the "
959 "SSL preprocessor configuration.\n");
960 }
961
962 sfPolicyUserDataSetCurrent(ssl_swap_config, pPolicyConfig);
963
964 SSLPP_init_config(pPolicyConfig);
965 SSLPP_config(pPolicyConfig, args);
966 SSLPP_print_config(pPolicyConfig);
967
968 _dpd.preprocOptRegister(sc, "ssl_state", SSLPP_state_init, SSLPP_rule_eval,
969 free, NULL, NULL, NULL, NULL);
970 _dpd.preprocOptRegister(sc, "ssl_version", SSLPP_ver_init, SSLPP_rule_eval,
971 free, NULL, NULL, NULL, NULL);
972
973 _dpd.addPreproc(sc, SSLPP_process, PRIORITY_APPLICATION, PP_SSL, PROTO_BIT__TCP);
974
975 registerPortsForDispatch( sc, pPolicyConfig );
976 registerPortsForReassembly( pPolicyConfig, SSN_DIR_FROM_SERVER | SSN_DIR_FROM_CLIENT );
977 _addPortsToStream5Filter(sc, pPolicyConfig, policy_id);
978
979 #ifdef TARGET_BASED
980 _addServicesToStream5Filter(sc, policy_id);
981 #endif
982 }
983
SSLReloadVerify(struct _SnortConfig * sc,void * swap_config)984 int SSLReloadVerify(struct _SnortConfig *sc, void *swap_config)
985 {
986 tSfPolicyUserContextId ssl_swap_config = (tSfPolicyUserContextId)swap_config;
987 SSLPP_config_t *reload_config = NULL;
988 SSLPP_config_t *start_config = NULL;
989 tSfPolicyId policyId = _dpd.getDefaultPolicy();
990 int ret = 0;
991 bool register_sfssl_preproc_reload_flag = false;
992 ssl_callback_interface_t *ssl_cb = (ssl_callback_interface_t *)_dpd.getSSLCallback();
993
994 if (!_dpd.isPreprocEnabled(sc, PP_STREAM))
995 {
996 _dpd.errMsg("SSLPP_init(): The Stream preprocessor must be enabled.\n");
997 return -1;
998 }
999
1000 if (!ssl_swap_config || !ssl_config)
1001 return 0;
1002
1003 reload_config = (SSLPP_config_t *)sfPolicyUserDataGet(ssl_swap_config, policyId);
1004 start_config = (SSLPP_config_t *)sfPolicyUserDataGet(ssl_config, policyId);
1005
1006 if( !reload_config || !start_config )
1007 {
1008 _dpd.errMsg("SSL reload: Turning on or off SSL preprocessor requires a restart.\n");
1009 return -1;
1010 }
1011
1012 if (ssl_cb && ssl_cb->reload_mem_adjust_available())
1013 {
1014 _dpd.logMsg("SSL reload: SFSSL reload memcap adjust is available.\n");
1015 register_sfssl_preproc_reload_flag = true;
1016 }
1017
1018 if (!register_sfssl_preproc_reload_flag &&
1019 reload_config->memcap != start_config->memcap)
1020 {
1021 /* Reload mem adjust not available, restart snort. */
1022 _dpd.errMsg("SSL reload: Changing the memcap requires a restart.\n");
1023 return -1;
1024 }
1025
1026 if (!register_sfssl_preproc_reload_flag &&
1027 reload_config->decrypt_memcap != start_config->decrypt_memcap)
1028 {
1029 /* Reload mem adjust not available, restart snort. */
1030 _dpd.errMsg("SSL reload: Changing the decrypt_memcap requires a restart.\n");
1031 return -1;
1032 }
1033
1034 if (reload_config->memcap != start_config->memcap)
1035 {
1036 /* reload mem adjust is available, any change in sfssl memcap, adjust the difference in sftls memcap */
1037 reload_config->decrypt_memcap += reload_config->memcap - start_config->memcap;
1038 _dpd.logMsg("SSL reload: Change in sfssl memcap:%d, sftls memcap:%d.\n", reload_config->memcap, reload_config->decrypt_memcap);
1039 }
1040
1041 ret = SSLPP_PolicyInit(sc, ssl_swap_config, reload_config, policyId, true);
1042
1043 if (!ret)
1044 {
1045 start_config->reload_handle = reload_config->current_handle;
1046 }
1047
1048 if (register_sfssl_preproc_reload_flag)
1049 {
1050 /* Always register the SFSSL preproc reload, if sftls memcap adjuster is available
1051 * even in case where decrypt memcap doesn't change, may be we will add sftls_memcap in
1052 * ssl_tuning.conf file which might be differrent.
1053 */
1054 ssl_cb->register_reload_mem_adjust(sc, reload_config);
1055 }
1056
1057 return ret;
1058 }
1059
1060
SSLReloadSwap(struct _SnortConfig * sc,void * swap_config)1061 void * SSLReloadSwap(struct _SnortConfig *sc, void *swap_config)
1062 {
1063 tSfPolicyUserContextId ssl_swap_config = (tSfPolicyUserContextId)swap_config;
1064 tSfPolicyUserContextId old_config = ssl_config;
1065
1066 if (ssl_swap_config == NULL)
1067 return NULL;
1068
1069 ssl_config = ssl_swap_config;
1070
1071 return (void *)old_config;
1072 }
1073
SSLReloadSwapFree(void * data)1074 void SSLReloadSwapFree(void *data)
1075 {
1076 if (data == NULL)
1077 return;
1078
1079 SSLFreeConfig((tSfPolicyUserContextId)data, false);
1080 }
1081 #endif
1082