Merged revisions 332177 via svnmerge from
[asterisk/asterisk.git] / tests / test_security_events.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2009, Digium, Inc.
5  *
6  * Russell Bryant <russell@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  *
21  * \brief Test security event generation
22  *
23  * \author Russell Bryant <russell@digium.com>
24  */
25
26 /*** MODULEINFO
27         <defaultenabled>no</defaultenabled>
28         <support_level>core</support_level>
29  ***/
30
31 #include "asterisk.h"
32
33 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
34
35 #include "asterisk/module.h"
36 #include "asterisk/cli.h"
37 #include "asterisk/utils.h"
38 #include "asterisk/security_events.h"
39
40 static void evt_gen_failed_acl(void);
41 static void evt_gen_inval_acct_id(void);
42 static void evt_gen_session_limit(void);
43 static void evt_gen_mem_limit(void);
44 static void evt_gen_load_avg(void);
45 static void evt_gen_req_no_support(void);
46 static void evt_gen_req_not_allowed(void);
47 static void evt_gen_auth_method_not_allowed(void);
48 static void evt_gen_req_bad_format(void);
49 static void evt_gen_successful_auth(void);
50 static void evt_gen_unexpected_addr(void);
51 static void evt_gen_chal_resp_failed(void);
52 static void evt_gen_inval_password(void);
53
54 typedef void (*evt_generator)(void);
55 static const evt_generator evt_generators[AST_SECURITY_EVENT_NUM_TYPES] = {
56         [AST_SECURITY_EVENT_FAILED_ACL]              = evt_gen_failed_acl,
57         [AST_SECURITY_EVENT_INVAL_ACCT_ID]           = evt_gen_inval_acct_id,
58         [AST_SECURITY_EVENT_SESSION_LIMIT]           = evt_gen_session_limit,
59         [AST_SECURITY_EVENT_MEM_LIMIT]               = evt_gen_mem_limit,
60         [AST_SECURITY_EVENT_LOAD_AVG]                = evt_gen_load_avg,
61         [AST_SECURITY_EVENT_REQ_NO_SUPPORT]          = evt_gen_req_no_support,
62         [AST_SECURITY_EVENT_REQ_NOT_ALLOWED]         = evt_gen_req_not_allowed,
63         [AST_SECURITY_EVENT_AUTH_METHOD_NOT_ALLOWED] = evt_gen_auth_method_not_allowed,
64         [AST_SECURITY_EVENT_REQ_BAD_FORMAT]          = evt_gen_req_bad_format,
65         [AST_SECURITY_EVENT_SUCCESSFUL_AUTH]         = evt_gen_successful_auth,
66         [AST_SECURITY_EVENT_UNEXPECTED_ADDR]         = evt_gen_unexpected_addr,
67         [AST_SECURITY_EVENT_CHAL_RESP_FAILED]        = evt_gen_chal_resp_failed,
68         [AST_SECURITY_EVENT_INVAL_PASSWORD]          = evt_gen_inval_password,
69 };
70
71 static void evt_gen_failed_acl(void)
72 {
73         struct sockaddr_in sin_local = {
74                 .sin_family = AF_INET
75         };
76         struct sockaddr_in sin_remote = {
77                 .sin_family = AF_INET
78         };
79         struct timeval session_tv = ast_tvnow();
80         struct ast_security_event_failed_acl failed_acl_event = {
81                 .common.event_type = AST_SECURITY_EVENT_FAILED_ACL,
82                 .common.version    = AST_SECURITY_EVENT_FAILED_ACL_VERSION,
83                 .common.service    = "TEST",
84                 .common.module     = AST_MODULE,
85                 .common.account_id = "Username",
86                 .common.session_id = "Session123",
87                 .common.session_tv = &session_tv,
88                 .common.local_addr = {
89                         .sin  = &sin_local,
90                         .transport  = AST_SECURITY_EVENT_TRANSPORT_UDP,
91                 },
92                 .common.remote_addr = {
93                         .sin = &sin_remote,
94                         .transport  = AST_SECURITY_EVENT_TRANSPORT_UDP,
95                 },
96
97                 .acl_name   = "TEST_ACL",
98         };
99
100         inet_aton("192.168.1.1", &sin_local.sin_addr);
101         sin_local.sin_port = htons(12121);
102
103         inet_aton("192.168.1.2", &sin_remote.sin_addr);
104         sin_remote.sin_port = htons(12345);
105
106         ast_security_event_report(AST_SEC_EVT(&failed_acl_event));
107 }
108
109 static void evt_gen_inval_acct_id(void)
110 {
111         struct sockaddr_in sin_local = {
112                 .sin_family = AF_INET
113         };
114         struct sockaddr_in sin_remote = {
115                 .sin_family = AF_INET
116         };
117         struct timeval session_tv = ast_tvnow();
118         struct ast_security_event_inval_acct_id inval_acct_id = {
119                 .common.event_type = AST_SECURITY_EVENT_INVAL_ACCT_ID,
120                 .common.version    = AST_SECURITY_EVENT_INVAL_ACCT_ID_VERSION,
121                 .common.service    = "TEST",
122                 .common.module     = AST_MODULE,
123                 .common.account_id = "FakeUser",
124                 .common.session_id = "Session456",
125                 .common.session_tv = &session_tv,
126                 .common.local_addr = {
127                         .sin  = &sin_local,
128                         .transport  = AST_SECURITY_EVENT_TRANSPORT_TCP,
129                 },
130                 .common.remote_addr = {
131                         .sin = &sin_remote,
132                         .transport  = AST_SECURITY_EVENT_TRANSPORT_TCP,
133                 },
134         };
135
136         inet_aton("10.1.2.3", &sin_local.sin_addr);
137         sin_local.sin_port = htons(4321);
138
139         inet_aton("10.1.2.4", &sin_remote.sin_addr);
140         sin_remote.sin_port = htons(1234);
141
142         ast_security_event_report(AST_SEC_EVT(&inval_acct_id));
143 }
144
145 static void evt_gen_session_limit(void)
146 {
147         struct sockaddr_in sin_local = {
148                 .sin_family = AF_INET
149         };
150         struct sockaddr_in sin_remote = {
151                 .sin_family = AF_INET
152         };
153         struct timeval session_tv = ast_tvnow();
154         struct ast_security_event_session_limit session_limit = {
155                 .common.event_type = AST_SECURITY_EVENT_SESSION_LIMIT,
156                 .common.version    = AST_SECURITY_EVENT_SESSION_LIMIT_VERSION,
157                 .common.service    = "TEST",
158                 .common.module     = AST_MODULE,
159                 .common.account_id = "Jenny",
160                 .common.session_id = "8675309",
161                 .common.session_tv = &session_tv,
162                 .common.local_addr = {
163                         .sin  = &sin_local,
164                         .transport  = AST_SECURITY_EVENT_TRANSPORT_TLS,
165                 },
166                 .common.remote_addr = {
167                         .sin = &sin_remote,
168                         .transport  = AST_SECURITY_EVENT_TRANSPORT_TLS,
169                 },
170         };
171
172         inet_aton("10.5.4.3", &sin_local.sin_addr);
173         sin_local.sin_port = htons(4444);
174
175         inet_aton("10.5.4.2", &sin_remote.sin_addr);
176         sin_remote.sin_port = htons(3333);
177
178         ast_security_event_report(AST_SEC_EVT(&session_limit));
179 }
180
181 static void evt_gen_mem_limit(void)
182 {
183         struct sockaddr_in sin_local = {
184                 .sin_family = AF_INET
185         };
186         struct sockaddr_in sin_remote = {
187                 .sin_family = AF_INET
188         };
189         struct timeval session_tv = ast_tvnow();
190         struct ast_security_event_mem_limit mem_limit = {
191                 .common.event_type = AST_SECURITY_EVENT_MEM_LIMIT,
192                 .common.version    = AST_SECURITY_EVENT_MEM_LIMIT_VERSION,
193                 .common.service    = "TEST",
194                 .common.module     = AST_MODULE,
195                 .common.account_id = "Felix",
196                 .common.session_id = "Session2604",
197                 .common.session_tv = &session_tv,
198                 .common.local_addr = {
199                         .sin  = &sin_local,
200                         .transport  = AST_SECURITY_EVENT_TRANSPORT_UDP,
201                 },
202                 .common.remote_addr = {
203                         .sin = &sin_remote,
204                         .transport  = AST_SECURITY_EVENT_TRANSPORT_UDP,
205                 },
206         };
207
208         inet_aton("10.10.10.10", &sin_local.sin_addr);
209         sin_local.sin_port = htons(555);
210
211         inet_aton("10.10.10.12", &sin_remote.sin_addr);
212         sin_remote.sin_port = htons(5656);
213
214         ast_security_event_report(AST_SEC_EVT(&mem_limit));
215 }
216
217 static void evt_gen_load_avg(void)
218 {
219         struct sockaddr_in sin_local = {
220                 .sin_family = AF_INET
221         };
222         struct sockaddr_in sin_remote = {
223                 .sin_family = AF_INET
224         };
225         struct timeval session_tv = ast_tvnow();
226         struct ast_security_event_load_avg load_avg = {
227                 .common.event_type = AST_SECURITY_EVENT_LOAD_AVG,
228                 .common.version    = AST_SECURITY_EVENT_LOAD_AVG_VERSION,
229                 .common.service    = "TEST",
230                 .common.module     = AST_MODULE,
231                 .common.account_id = "GuestAccount",
232                 .common.session_id = "XYZ123",
233                 .common.session_tv = &session_tv,
234                 .common.local_addr = {
235                         .sin  = &sin_local,
236                         .transport  = AST_SECURITY_EVENT_TRANSPORT_UDP,
237                 },
238                 .common.remote_addr = {
239                         .sin = &sin_remote,
240                         .transport  = AST_SECURITY_EVENT_TRANSPORT_UDP,
241                 },
242         };
243
244         inet_aton("10.11.12.13", &sin_local.sin_addr);
245         sin_local.sin_port = htons(9876);
246
247         inet_aton("10.12.11.10", &sin_remote.sin_addr);
248         sin_remote.sin_port = htons(9825);
249
250         ast_security_event_report(AST_SEC_EVT(&load_avg));
251 }
252
253 static void evt_gen_req_no_support(void)
254 {
255         struct sockaddr_in sin_local = {
256                 .sin_family = AF_INET
257         };
258         struct sockaddr_in sin_remote = {
259                 .sin_family = AF_INET
260         };
261         struct timeval session_tv = ast_tvnow();
262         struct ast_security_event_req_no_support req_no_support = {
263                 .common.event_type = AST_SECURITY_EVENT_REQ_NO_SUPPORT,
264                 .common.version    = AST_SECURITY_EVENT_REQ_NO_SUPPORT_VERSION,
265                 .common.service    = "TEST",
266                 .common.module     = AST_MODULE,
267                 .common.account_id = "George",
268                 .common.session_id = "asdkl23478289lasdkf",
269                 .common.session_tv = &session_tv,
270                 .common.local_addr = {
271                         .sin  = &sin_local,
272                         .transport  = AST_SECURITY_EVENT_TRANSPORT_UDP,
273                 },
274                 .common.remote_addr = {
275                         .sin = &sin_remote,
276                         .transport  = AST_SECURITY_EVENT_TRANSPORT_UDP,
277                 },
278
279                 .request_type = "MakeMeDinner",
280         };
281
282         inet_aton("10.110.120.130", &sin_local.sin_addr);
283         sin_local.sin_port = htons(9888);
284
285         inet_aton("10.120.110.100", &sin_remote.sin_addr);
286         sin_remote.sin_port = htons(9777);
287
288         ast_security_event_report(AST_SEC_EVT(&req_no_support));
289 }
290
291 static void evt_gen_req_not_allowed(void)
292 {
293         struct sockaddr_in sin_local = {
294                 .sin_family = AF_INET
295         };
296         struct sockaddr_in sin_remote = {
297                 .sin_family = AF_INET
298         };
299         struct timeval session_tv = ast_tvnow();
300         struct ast_security_event_req_not_allowed req_not_allowed = {
301                 .common.event_type = AST_SECURITY_EVENT_REQ_NOT_ALLOWED,
302                 .common.version    = AST_SECURITY_EVENT_REQ_NOT_ALLOWED_VERSION,
303                 .common.service    = "TEST",
304                 .common.module     = AST_MODULE,
305                 .common.account_id = "George",
306                 .common.session_id = "alksdjf023423h4lka0df",
307                 .common.session_tv = &session_tv,
308                 .common.local_addr = {
309                         .sin  = &sin_local,
310                         .transport  = AST_SECURITY_EVENT_TRANSPORT_UDP,
311                 },
312                 .common.remote_addr = {
313                         .sin = &sin_remote,
314                         .transport  = AST_SECURITY_EVENT_TRANSPORT_UDP,
315                 },
316
317                 .request_type = "MakeMeBreakfast",
318                 .request_params = "BACONNNN!",
319         };
320
321         inet_aton("10.110.120.130", &sin_local.sin_addr);
322         sin_local.sin_port = htons(9888);
323
324         inet_aton("10.120.110.100", &sin_remote.sin_addr);
325         sin_remote.sin_port = htons(9777);
326
327         ast_security_event_report(AST_SEC_EVT(&req_not_allowed));
328 }
329
330 static void evt_gen_auth_method_not_allowed(void)
331 {
332         struct sockaddr_in sin_local = {
333                 .sin_family = AF_INET
334         };
335         struct sockaddr_in sin_remote = {
336                 .sin_family = AF_INET
337         };
338         struct timeval session_tv = ast_tvnow();
339         struct ast_security_event_auth_method_not_allowed auth_method_not_allowed = {
340                 .common.event_type = AST_SECURITY_EVENT_AUTH_METHOD_NOT_ALLOWED,
341                 .common.version    = AST_SECURITY_EVENT_AUTH_METHOD_NOT_ALLOWED_VERSION,
342                 .common.service    = "TEST",
343                 .common.module     = AST_MODULE,
344                 .common.account_id = "Bob",
345                 .common.session_id = "010101010101",
346                 .common.session_tv = &session_tv,
347                 .common.local_addr = {
348                         .sin  = &sin_local,
349                         .transport  = AST_SECURITY_EVENT_TRANSPORT_TCP,
350                 },
351                 .common.remote_addr = {
352                         .sin = &sin_remote,
353                         .transport  = AST_SECURITY_EVENT_TRANSPORT_TCP,
354                 },
355
356                 .auth_method = "PlainText"
357         };
358
359         inet_aton("10.110.120.135", &sin_local.sin_addr);
360         sin_local.sin_port = htons(8754);
361
362         inet_aton("10.120.110.105", &sin_remote.sin_addr);
363         sin_remote.sin_port = htons(8745);
364
365         ast_security_event_report(AST_SEC_EVT(&auth_method_not_allowed));
366 }
367
368 static void evt_gen_req_bad_format(void)
369 {
370         struct sockaddr_in sin_local = {
371                 .sin_family = AF_INET
372         };
373         struct sockaddr_in sin_remote = {
374                 .sin_family = AF_INET
375         };
376         struct timeval session_tv = ast_tvnow();
377         struct ast_security_event_req_bad_format req_bad_format = {
378                 .common.event_type = AST_SECURITY_EVENT_REQ_BAD_FORMAT,
379                 .common.version    = AST_SECURITY_EVENT_REQ_BAD_FORMAT_VERSION,
380                 .common.service    = "TEST",
381                 .common.module     = AST_MODULE,
382                 .common.account_id = "Larry",
383                 .common.session_id = "838383fhfhf83hf8h3f8h",
384                 .common.session_tv = &session_tv,
385                 .common.local_addr = {
386                         .sin  = &sin_local,
387                         .transport  = AST_SECURITY_EVENT_TRANSPORT_TCP,
388                 },
389                 .common.remote_addr = {
390                         .sin = &sin_remote,
391                         .transport  = AST_SECURITY_EVENT_TRANSPORT_TCP,
392                 },
393
394                 .request_type = "CheeseBurger",
395                 .request_params = "Onions,Swiss,MotorOil",
396         };
397
398         inet_aton("10.110.220.230", &sin_local.sin_addr);
399         sin_local.sin_port = htons(1212);
400
401         inet_aton("10.120.210.200", &sin_remote.sin_addr);
402         sin_remote.sin_port = htons(2121);
403
404         ast_security_event_report(AST_SEC_EVT(&req_bad_format));
405 }
406
407 static void evt_gen_successful_auth(void)
408 {
409         struct sockaddr_in sin_local = {
410                 .sin_family = AF_INET
411         };
412         struct sockaddr_in sin_remote = {
413                 .sin_family = AF_INET
414         };
415         struct timeval session_tv = ast_tvnow();
416         struct ast_security_event_successful_auth successful_auth = {
417                 .common.event_type = AST_SECURITY_EVENT_SUCCESSFUL_AUTH,
418                 .common.version    = AST_SECURITY_EVENT_SUCCESSFUL_AUTH_VERSION,
419                 .common.service    = "TEST",
420                 .common.module     = AST_MODULE,
421                 .common.account_id = "ValidUser",
422                 .common.session_id = "Session456",
423                 .common.session_tv = &session_tv,
424                 .common.local_addr = {
425                         .sin  = &sin_local,
426                         .transport  = AST_SECURITY_EVENT_TRANSPORT_TCP,
427                 },
428                 .common.remote_addr = {
429                         .sin = &sin_remote,
430                         .transport  = AST_SECURITY_EVENT_TRANSPORT_TCP,
431                 },
432         };
433
434         inet_aton("10.1.2.3", &sin_local.sin_addr);
435         sin_local.sin_port = htons(4321);
436
437         inet_aton("10.1.2.4", &sin_remote.sin_addr);
438         sin_remote.sin_port = htons(1234);
439
440         ast_security_event_report(AST_SEC_EVT(&successful_auth));
441 }
442
443 static void evt_gen_unexpected_addr(void)
444 {
445         struct sockaddr_in sin_local = {
446                 .sin_family = AF_INET
447         };
448         struct sockaddr_in sin_remote = {
449                 .sin_family = AF_INET
450         };
451         struct sockaddr_in sin_expected = {
452                 .sin_family = AF_INET
453         };
454         struct timeval session_tv = ast_tvnow();
455         struct ast_security_event_unexpected_addr unexpected_addr = {
456                 .common.event_type = AST_SECURITY_EVENT_UNEXPECTED_ADDR,
457                 .common.version    = AST_SECURITY_EVENT_UNEXPECTED_ADDR_VERSION,
458                 .common.service    = "TEST",
459                 .common.module     = AST_MODULE,
460                 .common.account_id = "CoolUser",
461                 .common.session_id = "Session789",
462                 .common.session_tv = &session_tv,
463                 .common.local_addr = {
464                         .sin  = &sin_local,
465                         .transport  = AST_SECURITY_EVENT_TRANSPORT_UDP,
466                 },
467                 .common.remote_addr = {
468                         .sin = &sin_remote,
469                         .transport  = AST_SECURITY_EVENT_TRANSPORT_UDP,
470                 },
471
472                 .expected_addr = {
473                         .sin = &sin_expected,
474                         .transport  = AST_SECURITY_EVENT_TRANSPORT_UDP,
475                 },
476         };
477
478         inet_aton("10.1.2.3", &sin_local.sin_addr);
479         sin_local.sin_port = htons(4321);
480
481         inet_aton("10.1.2.4", &sin_remote.sin_addr);
482         sin_remote.sin_port = htons(1234);
483
484         inet_aton("10.1.2.5", &sin_expected.sin_addr);
485         sin_expected.sin_port = htons(2343);
486
487         ast_security_event_report(AST_SEC_EVT(&unexpected_addr));
488 }
489
490 static void evt_gen_chal_resp_failed(void)
491 {
492         struct sockaddr_in sin_local = {
493                 .sin_family = AF_INET
494         };
495         struct sockaddr_in sin_remote = {
496                 .sin_family = AF_INET
497         };
498         struct timeval session_tv = ast_tvnow();
499         struct ast_security_event_chal_resp_failed chal_resp_failed = {
500                 .common.event_type = AST_SECURITY_EVENT_CHAL_RESP_FAILED,
501                 .common.version    = AST_SECURITY_EVENT_CHAL_RESP_FAILED_VERSION,
502                 .common.service    = "TEST",
503                 .common.module     = AST_MODULE,
504                 .common.account_id = "SuperDuperUser",
505                 .common.session_id = "Session1231231231",
506                 .common.session_tv = &session_tv,
507                 .common.local_addr = {
508                         .sin  = &sin_local,
509                         .transport  = AST_SECURITY_EVENT_TRANSPORT_TCP,
510                 },
511                 .common.remote_addr = {
512                         .sin = &sin_remote,
513                         .transport  = AST_SECURITY_EVENT_TRANSPORT_TCP,
514                 },
515
516                 .challenge         = "8adf8a9sd8fas9df23ljk4",
517                 .response          = "9u3jlaksdjflakjsdfoi23",
518                 .expected_response = "oiafaljhadf9834luahk3k",
519         };
520
521         inet_aton("10.1.2.3", &sin_local.sin_addr);
522         sin_local.sin_port = htons(4321);
523
524         inet_aton("10.1.2.4", &sin_remote.sin_addr);
525         sin_remote.sin_port = htons(1234);
526
527         ast_security_event_report(AST_SEC_EVT(&chal_resp_failed));
528 }
529
530 static void evt_gen_inval_password(void)
531 {
532         struct sockaddr_in sin_local = {
533                 .sin_family = AF_INET
534         };
535         struct sockaddr_in sin_remote = {
536                 .sin_family = AF_INET
537         };
538         struct timeval session_tv = ast_tvnow();
539         struct ast_security_event_inval_password inval_password = {
540                 .common.event_type = AST_SECURITY_EVENT_INVAL_PASSWORD,
541                 .common.version    = AST_SECURITY_EVENT_INVAL_PASSWORD_VERSION,
542                 .common.service    = "TEST",
543                 .common.module     = AST_MODULE,
544                 .common.account_id = "AccountIDGoesHere",
545                 .common.session_id = "SessionIDGoesHere",
546                 .common.session_tv = &session_tv,
547                 .common.local_addr = {
548                         .sin  = &sin_local,
549                         .transport  = AST_SECURITY_EVENT_TRANSPORT_TCP,
550                 },
551                 .common.remote_addr = {
552                         .sin = &sin_remote,
553                         .transport  = AST_SECURITY_EVENT_TRANSPORT_TCP,
554                 },
555         };
556
557         inet_aton("10.200.100.30", &sin_local.sin_addr);
558         sin_local.sin_port = htons(4321);
559
560         inet_aton("10.200.100.40", &sin_remote.sin_addr);
561         sin_remote.sin_port = htons(1234);
562
563         ast_security_event_report(AST_SEC_EVT(&inval_password));
564 }
565
566 static void gen_events(struct ast_cli_args *a)
567 {
568         unsigned int i;
569
570         ast_cli(a->fd, "Generating some security events ...\n");
571
572         for (i = 0; i < ARRAY_LEN(evt_generators); i++) {
573                 const char *event_type = ast_security_event_get_name(i);
574
575                 if (!evt_generators[i]) {
576                         ast_cli(a->fd, "*** No event generator for event type '%s' ***\n",
577                                         event_type);
578                         continue;
579                 }
580
581                 ast_cli(a->fd, "Generating a '%s' security event ...\n", event_type);
582
583                 evt_generators[i]();
584         }
585
586         ast_cli(a->fd, "Security event generation complete.\n");
587 }
588
589 static char *handle_cli_sec_evt_test(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
590 {
591         switch (cmd) {
592         case CLI_INIT:
593                 e->command = "securityevents test generation";
594                 e->usage = ""
595                         "Usage: securityevents test generation"
596                         "";
597                 return NULL;
598         case CLI_GENERATE:
599                 return NULL;
600         case CLI_HANDLER:
601                 gen_events(a);
602                 return CLI_SUCCESS;
603         }
604
605         return CLI_FAILURE;
606 }
607
608 static struct ast_cli_entry cli_sec_evt[] = {
609         AST_CLI_DEFINE(handle_cli_sec_evt_test, "Test security event generation"),
610 };
611
612 static int unload_module(void)
613 {
614         return ast_cli_unregister_multiple(cli_sec_evt, ARRAY_LEN(cli_sec_evt));
615 }
616
617 static int load_module(void)
618 {
619         int res;
620
621         res = ast_cli_register_multiple(cli_sec_evt, ARRAY_LEN(cli_sec_evt));
622
623         return res ? AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS;
624 }
625
626 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Test Security Event Generation");