1 /* $Id: ssp_ciscoacl.c,v 2.12 2008/04/26 19:53:21 fknobbe Exp $
2 *
3 *
4 * Copyright (c) 2002-2008 Ali BASEL <alib@sabanciuniv.edu>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 *
29 * ssp_ciscoacl.c
30 *
31 * Purpose:
32 *
33 * This SnortSam plugin ciscoacl telnet's into one or more Cisco CISCOACL routers,
34 * and issues the blocking ACL statements. SnortSam will also expire the blocks
35 * itself since the routers do not have automatic time-out functionality.
36 *
37 * Comments:
38 *
39 *
40 */
41
42
43 #ifndef __SSP_CISCOACL_C__
44 #define __SSP_CISCOACL_C__
45
46
47 #include "snortsam.h"
48 #include "ssp_ciscoacl.h"
49
50
51 #include <sys/types.h>
52 #include <sys/stat.h>
53 #include <stdio.h>
54 #include <string.h>
55 #include <time.h>
56 #ifdef WIN32
57 #include <winsock.h>
58 #else
59 #include <netinet/in.h>
60 #include <arpa/inet.h>
61 #endif
62
63
64 /* This routine parses the ciscoacl statements in the config file.
65 * It builds a list of ciscoacls)
66 */
67 void
CISCOACLParse(char * val,char * file,unsigned long line,DATALIST * datalistp)68 CISCOACLParse(char *val, char *file, unsigned long line, DATALIST * datalistp)
69 {
70 CISCOACLDATA *ciscoaclp;
71 char msg[STRBUFSIZE + 1], *p2;
72 struct in_addr ciscoaclip;
73
74 char buf[CISCOACLFILELEN + 1], *pp;
75 int i, j, change;
76
77 logmessage(3, "Plugin Parsing...", "ciscoacl", 0);
78
79 if(*val) {
80 p2 = val;
81 while(*p2 && !myisspace(*p2))
82 p2++; /* go to first space */
83 if(*p2)
84 *p2++ = 0;
85
86 ciscoaclip.s_addr = getip(val);
87 if(ciscoaclip.s_addr) { /* If we have a valid IP address */
88 ciscoaclp = safemalloc(sizeof(CISCOACLDATA), "CISCOACLParse", "ciscoaclp"); /* create new ciscoacl */
89 datalistp->data = ciscoaclp;
90 ciscoaclp->ip.s_addr = ciscoaclip.s_addr;
91 /* ciscoaclp->username[0] = (char) NULL;
92 ciscoaclp->telnetpw[0] = (char) NULL;
93 ciscoaclp->enablepw[0] = (char) NULL;
94 ciscoaclp->aclfile[0] = (char) NULL;
95 ciscoaclp->ftpfile[0] = (char) NULL;
96 */
97 if(*p2) {
98 val = p2;
99 while(*val && myisspace(*val)) /* jump spaces */
100 val++;
101 if(*val) {
102 p2 = val;
103 while(*p2 && !myisspace(*p2)) /* go to first following space */
104 p2++;
105 if(*p2)
106 *p2++ = 0;
107 safecopy(buf, val); /* username/password or only telnet password */
108
109 pp = buf;
110 i=j=0;
111 change = 0;
112 do {
113 if(myisspace(*pp))
114 continue;
115 if(*pp == '/') {
116 change = 1;
117 continue;
118 }
119 if(!change)
120 ciscoaclp->username[i++] = *pp;
121 else
122 ciscoaclp->telnetpw[j++] = *pp;
123 }
124 while(*(++pp) && !myisspace(*pp));
125 ciscoaclp->username[i] = (char) 0;
126 ciscoaclp->telnetpw[j] = (char) 0;
127
128 if(*p2) {
129 val = p2;
130 while(*val && myisspace(*val)) /* jump spaces */
131 val++;
132 if(*val) {
133 p2 = val;
134 while(*p2 && !myisspace(*p2))
135 p2++;
136 if(*p2)
137 *p2++ = 0;
138 safecopy(ciscoaclp->enablepw, val); /* save enable password */
139 }
140 if(*p2) {
141 while(*p2 && myisspace(*p2))
142 p2++; /* jump spaces */
143
144 safecopy(buf, p2); /* this would be the aclfile name... */
145
146 pp = buf;
147 i=j=0;
148 change = 0;
149 do {
150 if(myisspace(*pp))
151 continue;
152 if(*pp == '|') {
153 change = 1;
154 continue;
155 }
156 if(!change)
157 ciscoaclp->aclfile[i++] = *pp;
158 else
159 ciscoaclp->ftpfile[j++] = *pp;
160 }
161 while(*(++pp) && !myisspace(*pp));
162 ciscoaclp->aclfile[i] = (char) 0;
163 ciscoaclp->ftpfile[j] = (char) 0;
164 snprintf(msg, sizeof(msg) - 1,
165 "Adding CISCOACL: IP \"%s\", UName \"%s\", PW \"%s\", EN \"%s\", ACL \"%s\", FTPFILE \"%s\"",
166 inettoa(ciscoaclp->ip.s_addr),
167 ciscoaclp->username,
168 ciscoaclp->telnetpw,
169 ciscoaclp->enablepw,
170 ciscoaclp->aclfile,
171 ciscoaclp->ftpfile
172 );
173 logmessage(1, msg, "ciscoacl", ciscoaclp->ip.s_addr );
174 return;
175 } else {
176 snprintf(msg, sizeof(msg) - 1,
177 "Error: [%s: %lu] CISCOACL defined without aclfile name !",
178 file, line);
179 logmessage(1, msg, "ciscoacl", 0);
180 getout(3);
181 }
182 } else {
183 snprintf(msg, sizeof(msg) - 1,
184 "Error: [%s: %lu] CISCOACL defined without enable passwords!",
185 file, line);
186 logmessage(1, msg, "ciscoacl", 0);
187 getout(3);
188 }
189 } else {
190 snprintf(msg, sizeof(msg) - 1,
191 "Error: [%s: %lu] CISCOACL defined without passwords and ACL-file-name !",
192 file, line);
193 logmessage(1, msg, "ciscoacl", 0);
194 getout(3);
195 }
196 } else {
197 snprintf(msg, sizeof(msg) - 1,
198 "Error: [%s: %lu] CISCOACL defined without passwords and ACL-file-name !",
199 file, line);
200 logmessage(1, msg, "ciscoacl", 0);
201 getout(3);
202 }
203
204 snprintf(msg, sizeof(msg) - 1,
205 "Adding CISCOACL: IP \"%s\", UN \"%s\", PW \"%s\", EN \"%s\", ACL \"%s\", FTPFILE \"%s\"",
206 inettoa(ciscoaclp->ip.s_addr), ciscoaclp->username,
207 ciscoaclp->telnetpw, ciscoaclp->enablepw,
208 ciscoaclp->aclfile, ciscoaclp->ftpfile);
209 logmessage(3, msg, "ciscoacl", ciscoaclp->ip.s_addr);
210 } else {
211 snprintf(msg, sizeof(msg) - 1,
212 "Error: [%s: %lu] Invalid CISCOACL parameter '%s' ignored.",
213 file, line, val);
214 logmessage(1, msg, "ciscoacl", 0);
215 getout(3);
216 }
217 } else {
218 snprintf(msg, sizeof(msg) - 1,
219 "Error: [%s: %lu] Empty CISCOACL parameter.", file, line);
220 logmessage(1, msg, "ciscoacl", 0);
221 getout(3);
222 }
223 }
224
225 /* This routine initiates the block. It walks the list of CISCOACL's
226 * telnet's in, and issues the blocking ACL statement.
227 */
CISCOACLBlock(BLOCKINFO * bd,void * data,unsigned long qp)228 void CISCOACLBlock(BLOCKINFO * bd, void *data,unsigned long qp)
229 {
230 CISCOACLDATA *ciscoaclp;
231 struct sockaddr_in thissocketaddr, ciscoaclsocketaddr;
232 SOCKET ciscoaclsocket = 0;
233 signed long len;
234 char msg[STRBUFSIZE + 2];
235 struct in_addr blockthis;
236
237 FILE *readfile, *writefile, *writefile_upload, *readftpfile;
238 char ace[STRBUFSIZE + 1], buf[STRBUFSIZE + 1];
239 char filename_temp[FILEBUFSIZE + 1];
240 const char *ciscoaclbegin = "snortsam-ciscoacl-begin";
241 const char *ciscoaclend = "snortsam-ciscoacl-end";
242 int uzbegin = strlen(ciscoaclbegin), uzend = strlen(ciscoaclend);
243 int error, search, present, i, blank, ftp = 0, expect = 0, result = 0;
244
245 /* Holds the expect script's file name, if it's defined in the snortsam config file */
246 /* this plugin arranges the ACL file, and then will call this expect script to upload the ACL file */
247 char expect_file[STRBUFSIZE + 1];
248
249 /* Copy of the actual ACL file, "snortsam-ciscoacl-begin" and "snortsam-ciscoacl-end" lines are removed */
250 /* These two lines are removed in order to avoid errors when uploading this ACL file into the router */
251 char aclfile_upload[STRBUFSIZE + 1];
252 /* This file will be removed after beeing uploaded into the router */
253
254
255 if(!data)
256 return; /* if we don't have ciscoacls, we exit */
257 ciscoaclp = (CISCOACLDATA *) data;
258
259 snprintf(msg, sizeof(msg) - 1, "Plugin Blocking... block=%d", bd->block);
260 logmessage(2, msg, "ciscoacl", 0);
261
262 blockthis.s_addr = bd->blockip;
263 snprintf(msg, sizeof(msg) - 1, "deny ip host %s any",
264 inettoa(blockthis.s_addr));
265 present = CISCOACLCheck(msg, ciscoaclp->aclfile); /* check the ACL file if the blocking rule is already applied ? */
266 if(present && bd->block) {
267 logmessage(3, "already blocked, no thing to do.", "ciscoacl",
268 ciscoaclp->ip.s_addr);
269 return;
270 /* no need to reapply to this router, continue with the other */
271 }
272 if(!present && !bd->block) {
273 logmessage(3, "This is not blocked, no thing to do.", "ciscoacl",
274 ciscoaclp->ip.s_addr);
275 return;
276 /* it doesn't exist, so nothing to do */
277 }
278
279 if(strlen(ciscoaclp->ftpfile)) {
280 ftp = 1;
281 if(strstr(ciscoaclp->ftpfile, "expect:")) {
282 /* Remove the "expect:" string from the file name */
283 safecopy(expect_file, &ciscoaclp->ftpfile[strlen("expect:")] );
284 ftp = 2;
285 expect = 1; /* There is an expect script to call */
286 snprintf(msg, sizeof(msg) - 1, "Expect script name:%s",
287 expect_file);
288 logmessage(1, msg, "ciscoacl", 0);
289 readftpfile = fopen(expect_file, "r");
290 if(!readftpfile) {
291 snprintf(msg, sizeof(msg) - 1,
292 "Error: file: %s doesn't exist!", expect_file);
293 logmessage(1, msg, "ciscoacl", ciscoaclp->ip.s_addr);
294 return;
295 }
296 fclose(readftpfile);
297 } else {
298 readftpfile = fopen(ciscoaclp->ftpfile, "r");
299 if(!readftpfile) {
300 snprintf(msg, sizeof(msg) - 1,
301 "Error: file: %s doesn't exist!", ciscoaclp->ftpfile);
302 logmessage(1, msg, "ciscoacl", ciscoaclp->ip.s_addr);
303 return;
304 }
305 fclose(readftpfile);
306 }
307 } else
308 ftp = 0;
309 /* If there is an expect script to be called, there is no need to connect to the router...
310 Otherwise make the telnet connection as usual */
311 if(!expect) {
312 ciscoaclsocketaddr.sin_port = htons(23); /* telnet */
313 ciscoaclsocketaddr.sin_addr.s_addr = ciscoaclp->ip.s_addr;
314 ciscoaclsocketaddr.sin_family = AF_INET;
315
316 thissocketaddr.sin_port = htons(0); /* get a dynamic port */
317 thissocketaddr.sin_addr.s_addr = 0;
318 thissocketaddr.sin_family = AF_INET;
319
320 /* create socket */
321 ciscoaclsocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
322 if(ciscoaclsocket == INVALID_SOCKET) {
323 snprintf(msg, sizeof(msg) - 1,
324 "Error: [ciscoacl] Couldn't create socket!");
325 logmessage(1, msg, "ciscoacl", ciscoaclp->ip.s_addr);
326 return;
327 }
328 /* bind it */
329 if(bind
330 (ciscoaclsocket, (struct sockaddr *) &(thissocketaddr),
331 sizeof(struct sockaddr))) {
332 snprintf(msg, sizeof(msg) - 1,
333 "Error: [ciscoacl] Couldn't bind socket!");
334 logmessage(1, msg, "ciscoacl", ciscoaclp->ip.s_addr);
335 return;
336 }
337 /* and connect to ciscoacl */
338 if(connect
339 (ciscoaclsocket, (struct sockaddr *) &ciscoaclsocketaddr,
340 sizeof(struct sockaddr))) {
341 snprintf(msg, sizeof(msg) - 1,
342 "Error: [ciscoacl] Could not connect to CISCOACL at %s! Will try later.",
343 inettoa(ciscoaclp->ip.s_addr));
344 logmessage(1, msg, "ciscoacl", ciscoaclp->ip.s_addr);
345 return;
346 }
347
348 snprintf(msg, sizeof(msg) - 1, "Connected to CISCOACL at %s.",
349 inettoa(ciscoaclp->ip.s_addr));
350 logmessage(2, msg, "ciscoacl", ciscoaclp->ip.s_addr);
351
352 len = 1;
353
354 ioctlsocket(ciscoaclsocket, FIONBIO, &len); /* set non blocking */
355
356 if(ciscoaclp->telnetpw[0]) { /* there are username and password, so apply tacacs+ authentication */
357 if(CISCOACLsendreceive(ciscoaclsocket, "", "Username: ")) {
358 closesocket(ciscoaclsocket);
359 return;
360 }
361
362 if(CISCOACLsendreceive
363 (ciscoaclsocket, ciscoaclp->username, "Password: ")) {
364 closesocket(ciscoaclsocket);
365 return;
366 }
367
368 if(CISCOACLsendreceive(ciscoaclsocket, ciscoaclp->telnetpw, ">")) {
369 closesocket(ciscoaclsocket);
370 return;
371 }
372 } else { /* do simple authentication with password */
373 if(CISCOACLsendreceive(ciscoaclsocket, "", "Password: ")) {
374 closesocket(ciscoaclsocket);
375 return;
376 }
377
378 if(CISCOACLsendreceive(ciscoaclsocket, ciscoaclp->username, ">")) {
379 closesocket(ciscoaclsocket);
380 return;
381 }
382 }
383
384 if(CISCOACLsendreceive(ciscoaclsocket, "enable", "Password: ")) {
385 closesocket(ciscoaclsocket);
386 return;
387 }
388 if(CISCOACLsendreceive(ciscoaclsocket, ciscoaclp->enablepw, "#")) {
389 closesocket(ciscoaclsocket);
390 return;
391 }
392 /* A Telnet connection has been established */
393 /* If expect was 0 */
394 }
395
396 blockthis.s_addr = bd->blockip;
397 snprintf(msg, sizeof(msg) - 1, "deny ip host %s any",
398 inettoa(blockthis.s_addr));
399 /* don't search the whole file; search only between snortsam-acl-begin and snortsam-acl-end */
400 error = 0;
401 present = 0;
402 search = 0;
403
404 /* Expect script and tftp will use the file "ciscoaclp->aclfile"_upload */
405 snprintf(aclfile_upload, sizeof(aclfile_upload) - 1, "%s_upload",
406 ciscoaclp->aclfile);
407
408 readfile = fopen(ciscoaclp->aclfile, "r");
409 if(!readfile) {
410 snprintf(msg, sizeof(msg) - 1, "Error: file: %s doesn't exist!",
411 ciscoaclp->aclfile);
412 logmessage(1, msg, "ciscoacl", ciscoaclp->ip.s_addr);
413 if(!expect)
414 closesocket(ciscoaclsocket);
415 return;
416 }
417 snprintf(filename_temp, sizeof(filename_temp) - 1, "%s-%x%x",
418 ciscoaclp->aclfile, rand() * 65536 + rand(),
419 rand() * 65536 + rand());
420
421
422 writefile_upload = fopen(aclfile_upload, "w");
423 if(!writefile_upload) {
424 snprintf(msg, sizeof(msg) - 1, "Error: can not create file: %s !",
425 aclfile_upload);
426 logmessage(1, msg, "ciscoacl", ciscoaclp->ip.s_addr);
427 fclose(readfile);
428 if(!expect)
429 closesocket(ciscoaclsocket);
430 return;
431 }
432
433 writefile = fopen(filename_temp, "w");
434 if(!writefile_upload) {
435 snprintf(msg, sizeof(msg) - 1, "Error: can not create file: %s !",
436 ciscoaclp->aclfile);
437 logmessage(1, msg, "ciscoacl", ciscoaclp->ip.s_addr);
438 fclose(readfile);
439 fclose(writefile_upload);
440 if(!expect)
441 closesocket(ciscoaclsocket);
442 return;
443 }
444
445
446 while(!feof(readfile)) {
447 fgets(ace, sizeof(ace) - 1, readfile);
448 ace[sizeof(ace) - 1] = 0;
449 if(strlen(ace) < 4)
450 continue; /* skip blank lines */
451
452 /* if the file is created in Linux with the vi editor, lines end with 0x0A newline
453 but if in windows, lines end with 0x0D 0x0A; so, check 0x0D */
454 if(ace[strlen(ace) - 2] == (char) 0x0d)
455 ace[strlen(ace) - 2] = (char) 0; /* in windows */
456 else
457 ace[strlen(ace) - 1] = (char) 0; /* in Linux with vi */
458
459 blank = 0; /* skip initial blank characters */
460 for(i = 0; i < strlen(ace); i++) {
461 if(myisspace(ace[i]))
462 blank++;
463 else
464 break;
465 }
466 safecopy(buf, &ace[blank]);
467 safecopy(ace, buf);
468
469
470 if(!strncmp("snortsam-ciscoacl-begin", ace, uzbegin)) {
471 search = 1;
472 fprintf(writefile, "%s\r\n", ace);
473 ace[0] = (char) 0;
474 continue;
475 }
476
477 if(!strncmp("snortsam-ciscoacl-end", ace, uzend)) {
478 search = 0;
479
480 if(!present && bd->block) { /* if this ACE doesn't already exist add it. */
481 fprintf(writefile, "%s\r\n", msg);
482 fprintf(writefile_upload, "%s\r\n", msg);
483 if(!ftp)
484 CISCOACLsendreceive(ciscoaclsocket, msg, "#");
485 }
486
487 fprintf(writefile, "%s\r\n", ace);
488 ace[0] = (char) 0;
489 present = 0;
490 continue;
491 }
492
493 if(search) /* search this ACE if it already exists ? */
494 if(!strcmp(msg, ace))
495 present = 1;
496
497 if(!bd->block && present) {
498 ace[0] = (char) 0;
499 present = 0;
500 continue; /* once we found a match, make present=0 in order to no skip others */
501 }
502
503 fprintf(writefile, "%s\r\n", ace);
504 fprintf(writefile_upload, "%s\r\n", ace);
505
506 if(!ftp) {
507 logmessage(2, "sending command to the router...", "ciscoacl",
508 ciscoaclp->ip.s_addr);
509
510 if(CISCOACLsendreceive(ciscoaclsocket, ace, "#")) {
511 error = 1;
512 break;
513 }
514 }
515
516 ace[0] = (char) 0;
517 }
518
519
520 if(error) {
521 snprintf(msg, sizeof(msg) - 1,
522 "Error: [ciscoacl] Did not receive a response from CISCOACL at %s (wait for # prompt), and skipping to the next router, check acl_temp file!!!",
523 inettoa(ciscoaclp->ip.s_addr));
524 logmessage(1, msg, "ciscoacl", ciscoaclp->ip.s_addr);
525 fclose(readfile);
526 fclose(writefile);
527 fclose(writefile_upload);
528 if(!expect)
529 closesocket(ciscoaclsocket);
530 return;
531 }
532
533 fclose(readfile);
534 fclose(writefile);
535 fclose(writefile_upload);
536 unlink(ciscoaclp->aclfile);
537 rename(filename_temp, ciscoaclp->aclfile);
538
539 #ifndef WIN32
540 /* Changes permissions of the aclfile to make it readable by the tftp daemon */
541 chmod(ciscoaclp->aclfile, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
542 #endif
543 if(expect) {
544 snprintf(msg, sizeof(msg) - 1, "%s>>/var/log/snortsam_expect.log",
545 expect_file);
546 result = system(msg);
547 logmessage(1, "expect script has been executed", "ciscoacl",
548 ciscoaclp->ip.s_addr);
549 snprintf(msg, sizeof(msg) - 1, "Expect return code:%d", result);
550 logmessage(1, msg, "ciscoacl", ciscoaclp->ip.s_addr);
551 unlink(aclfile_upload); /* Remove the temporary upload file */
552
553 } else if(ftp) {
554 readftpfile = fopen(ciscoaclp->ftpfile, "r");
555
556 while(!feof(readftpfile)) {
557 fgets(ace, sizeof(ace) - 1, readftpfile);
558 ace[sizeof(ace) - 1] = 0;
559 if(strlen(ace) < 4)
560 continue; /* skip blank lines */
561
562 /* if the file is created in Linux with the vi editor, lines end with 0x0A newline
563 but if in windows, lines end with 0x0D 0x0A; so, check 0x0D */
564 if(ace[strlen(ace) - 2] == (char) 0x0d)
565 ace[strlen(ace) - 2] = (char) 0; /* in windows */
566 else
567 ace[strlen(ace) - 1] = (char) 0; /* in Linux with vi */
568
569 blank = 0; /* skip initial blank characters */
570 for(i = 0; i < strlen(ace); i++) {
571 if(myisspace(ace[i]))
572 blank++;
573 else
574 break;
575 }
576 safecopy(buf, &ace[blank]);
577 safecopy(ace, buf);
578
579
580 logmessage(2, "sending command to the router...", "ciscoacl",
581 ciscoaclp->ip.s_addr);
582
583 if(CISCOACLsendreceive(ciscoaclsocket, ace, "]? ")) {
584 error = 1;
585 break;
586 }
587
588 ace[0] = (char) 0;
589 }
590
591 fclose(readftpfile);
592
593 if(!error) // if there is no error send the last two answers
594 {
595 if(CISCOACLsendreceive(ciscoaclsocket, ciscoaclp->aclfile, "]? "))
596 error = 1;
597 else if(CISCOACLsendreceive(ciscoaclsocket, "running-config", "#"))
598 error = 1;
599 }
600 if(error) {
601 snprintf(msg, sizeof(msg) - 1,
602 "Error: [ciscoacl] Did not receive a response from CISCOACL at %s, and skipping to the next router, check %s file!!!",
603 inettoa(ciscoaclp->ip.s_addr), ciscoaclp->ftpfile);
604 logmessage(1, msg, "ciscoacl", ciscoaclp->ip.s_addr);
605 fclose(readftpfile), closesocket(ciscoaclsocket);
606 return;
607 }
608 }
609
610 if(!expect)
611 closesocket(ciscoaclsocket); /* If there is an expect script, a telnet connection
612 hasn't been established, so there is not any open socket to close */
613
614 snprintf(msg, sizeof(msg) - 1,
615 "Uploading has finished and disconnected from the router:%s",
616 inettoa(ciscoaclp->ip.s_addr));
617 logmessage(1, msg, "ciscoacl", ciscoaclp->ip.s_addr);
618 logmessage(3, "Return from ciscoacl Blocking function", "ciscoacl", 0);
619 }
620
621
622
623 /*
624 *
625 */
CISCOACLCheck(char * message,char * filename)626 int CISCOACLCheck(char *message, char *filename)
627 {
628 char msg[STRBUFSIZE + 1];
629
630 FILE *readfile;
631 char ace[STRBUFSIZE + 1], buf[STRBUFSIZE + 1];
632 const char *ciscoaclbegin = "snortsam-ciscoacl-begin";
633 const char *ciscoaclend = "snortsam-ciscoacl-end";
634 int uzbegin = strlen(ciscoaclbegin), uzend =
635 strlen(ciscoaclend), search = 1, present = 0, i, blank;
636
637 readfile = fopen(filename, "r");
638 if(!readfile) {
639 puts("hata: dosya yok !");
640 return 0;
641 }
642
643 snprintf(msg, sizeof(msg) - 1, "ACL existence check:%s", message);
644 logmessage(1, msg, "ciscoacl", 0);
645
646 while(!feof(readfile)) {
647 fgets(ace, sizeof(ace) - 1, readfile);
648 ace[sizeof(ace) - 1] = 0;
649 if(strlen(ace) < 4)
650 continue; /* skip blank lines */
651
652 /* if the file is created in Linux with the vi editor, lines end with 0x0A newline
653 but if in windows, lines end with 0x0D 0x0A; so, check 0x0D */
654 if(ace[strlen(ace) - 2] == (char) 0x0d)
655 ace[strlen(ace) - 2] = (char) 0; /* in windows */
656 else
657 ace[strlen(ace) - 1] = (char) 0; /* in Linux with vi */
658
659 blank = 0; /* skip inital blank characters */
660 for(i = 0; i < strlen(ace); i++) {
661 if(myisspace(ace[i]))
662 blank++;
663 else
664 break;
665 }
666 safecopy(buf, &ace[blank]);
667 safecopy(ace, buf);
668
669 if(!strncmp("snortsam-ciscoacl-begin", ace, uzbegin)) {
670 search = 1;
671 ace[0] = (char) 0;
672 continue;
673 }
674
675 if(!strncmp("snortsam-ciscoacl-end", ace, uzend)) {
676 break;
677 }
678
679 if(search) /* search this ACE if it already exists ? */
680 if(!strcmp(message, ace)) {
681 present = 1;
682 break;
683 }
684 ace[0] = (char) 0;
685 }
686
687 fclose(readfile);
688 if(present)
689 logmessage(1, "Present", "ciscoacl", 0);
690 else
691 logmessage(1, "Not Present", "ciscoacl", 0);
692 return present;
693 }
694
695
696
CISCOACLsendreceive(SOCKET ciscoaclsocket,char * message,char * receive)697 int CISCOACLsendreceive(SOCKET ciscoaclsocket, char *message, char *receive)
698 {
699 signed long len;
700 char msg[STRBUFSIZE + 1], buf[STRBUFSIZE + 1];
701
702 if(*message) {
703 snprintf(msg, sizeof(msg) - 1, "%s\r", message); /* send */
704 len = strlen(msg);
705
706 snprintf(buf, sizeof(buf) - 1, "Sending:%s", msg);
707 logmessage(3, buf, "ciscoacl", 0);
708
709 if(send(ciscoaclsocket, msg, len, 0) != len) { /* weird...could not send */
710 snprintf(msg, sizeof(msg) - 1,
711 "Error: [ciscoacl] Could not send to CISCOACL at %s !",
712 message);
713 logmessage(1, msg, "ciscoacl", 0);
714 return 1;
715 }
716 }
717
718 if(*receive) {
719 snprintf(buf, sizeof(buf) - 1, "Receiving: --%s--", receive);
720 logmessage(3, buf, "ciscoacl", 0);
721
722 if(!waitfor(ciscoaclsocket, receive, CISCOACLNETWAIT)) { /* wait for prompt */
723 snprintf(msg, sizeof(msg) - 1,
724 "Error: [ciscoacl] Did not receive a response from CISCOACL at %s !",
725 receive);
726 logmessage(1, msg, "ciscoacl", 0);
727 return 1;
728 }
729 }
730
731 return 0;
732 }
733
734 #endif /* __SSP_CISCOACL_C__ */
735