source: trunk/src/sh_portcheck.c@ 496

Last change on this file since 496 was 481, checked in by katerina, 9 years ago

Enhancements and fixes for tickets #374, #375, #376, #377, #378, and #379.

  • Property svn:executable set to *
File size: 54.6 KB
Line 
1/* SAMHAIN file system integrity testing */
2/* Copyright (C) 2006 Rainer Wichmann */
3/* */
4/* This program is free software; you can redistribute it */
5/* and/or modify */
6/* it under the terms of the GNU General Public License as */
7/* published by */
8/* the Free Software Foundation; either version 2 of the License, or */
9/* (at your option) any later version. */
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., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20/***************************************************************************
21 *
22 * This file provides a module for samhain to check for open ports
23 * on the local machine.
24 *
25 */
26
27
28/* #define TEST_ONLY */
29#ifndef TEST_ONLY
30#include "config_xor.h"
31#endif
32
33#include <stdio.h>
34#include <string.h>
35#include <sys/types.h>
36#include <sys/socket.h>
37#include <netinet/in.h>
38#include <arpa/inet.h>
39#include <errno.h>
40#include <unistd.h>
41#include <fcntl.h>
42
43#define PORTCHK_VERSION "1.0"
44
45#if defined(TEST_ONLY) || (defined(SH_USE_PORTCHECK) && (defined (SH_WITH_CLIENT) || defined (SH_STANDALONE)))
46
47
48#define PORTMAP
49#ifdef HAVE_RPC_RPC_H
50#include <rpc/rpc.h>
51#ifdef HAVE_RPC_RPCENT_H
52#include <rpc/rpcent.h>
53#endif
54#include <rpc/pmap_clnt.h>
55#include <rpc/pmap_prot.h>
56#endif
57#include <netdb.h>
58
59/*
60 * struct pmaplist {
61 * struct pmap pml_map;
62 * struct pmaplist *pml_next;
63 * };
64 */
65
66/* struct pmap {
67 * long unsigned pm_prog;
68 * long unsigned pm_vers;
69 * long unsigned pm_prot;
70 * long unsigned pm_port;
71 * };
72 */
73
74/* TIME_WAIT ? 60-240 seconds */
75
76#if !defined(TEST_ONLY)
77
78#define FIL__ _("sh_portcheck.c")
79#include "samhain.h"
80#include "sh_error.h"
81#include "sh_mem.h"
82#include "sh_calls.h"
83#include "sh_utils.h"
84#include "sh_modules.h"
85#define SH_NEED_GETHOSTBYXXX
86#include "sh_static.h"
87#include "sh_pthread.h"
88#include "sh_ipvx.h"
89
90/* the size of an interface string
91 */
92#define SH_INTERFACE_SIZE SH_IP_BUF
93
94#define SH_PORT_NOT 0
95#define SH_PORT_REQ 1
96#define SH_PORT_OPT 2
97#define SH_PORT_IGN 3
98#define SH_PORT_BLACKLIST 4
99
100static char * sh_port_type2str (int type)
101{
102 if (type == 0) return _("not");
103 if (type == 1) return _("req");
104 if (type == 2) return _("opt");
105 if (type == 3) return _("ign");
106 if (type == 4) return _("blc");
107 return _("???");
108}
109
110#define SH_PORT_MISS 0
111#define SH_PORT_ISOK 1
112#define SH_PORT_UNKN 2
113
114#define SH_PORT_NOREPT 0
115#define SH_PORT_REPORT 1
116
117#define SH_PROTO_TCP 0
118#define SH_PROTO_UDP 1
119#define SH_PROTO_STR(a) (((a) == IPPROTO_TCP) ? _("tcp") : _("udp"))
120
121struct sh_portentry {
122 int port;
123 char interface[SH_INTERFACE_SIZE];
124 char * service;
125 char * error;
126 int flag; /* required or not */
127 int status; /* missing or not */
128 struct sh_portentry * next;
129};
130
131static struct sh_portentry * portlist_tcp = NULL;
132static struct sh_portentry * portlist_udp = NULL;
133
134
135#define SH_PORTCHK_INTERVAL 300
136
137static int sh_portchk_check_udp = 1;
138static int sh_portchk_active = 1;
139static int sh_portchk_interval = SH_PORTCHK_INTERVAL;
140
141static int sh_portchk_minport = -1;
142static int sh_portchk_maxport = -1;
143
144struct sh_port {
145 int port;
146 struct sh_sockaddr * paddr;
147 struct sh_port * next;
148};
149
150static struct sh_port * blacklist_tcp = NULL;
151static struct sh_port * blacklist_udp = NULL;
152
153SH_MUTEX_STATIC(mutex_port_check, PTHREAD_MUTEX_INITIALIZER);
154
155static int sh_portchk_severity = SH_ERR_SEVERE;
156
157extern char * sh_port2proc_query(int proto, struct sh_sockaddr * saddr, int sport,
158 unsigned long * pid, char * user, size_t userlen);
159extern int sh_port2proc_prepare();
160extern void sh_port2proc_finish();
161
162#endif
163
164/* Exported interface to add ignoreable ports as 'iface:portlist'
165 */
166static int sh_portchk_add_ignore (const char * str);
167
168/* Exported interface to add required ports as 'iface:portlist'
169 */
170static int sh_portchk_add_required (const char * str);
171
172/* Exported interface to add optional ports as 'iface:portlist'
173 */
174static int sh_portchk_add_optional (const char * str);
175
176/* Exported interface to add blacklisted ports as 'iface:portlist'
177 */
178static int sh_portchk_add_blacklist (const char * str);
179
180/* Exported interface to add an ethernet interface
181 */
182static int sh_portchk_add_interface (const char * str);
183
184/* verify whether port/interface is blacklisted (do not check)
185 */
186static int sh_portchk_is_blacklisted(int port, struct sh_sockaddr * haddr, int proto);
187
188#ifndef TEST_ONLY
189
190static int sh_portchk_set_interval (const char * c)
191{
192 int retval = 0;
193 long val;
194
195 SL_ENTER(_("sh_portchk_set_interval"));
196 val = strtol (c, (char **)NULL, 10);
197 if (val <= 0)
198 {
199 SH_MUTEX_LOCK(mutex_thread_nolog);
200 sh_error_handle ((-1), FIL__, __LINE__, EINVAL, MSG_EINVALS,
201 _("port check interval"), c);
202 SH_MUTEX_UNLOCK(mutex_thread_nolog);
203 retval = -1;
204 }
205 else
206 {
207 sh_portchk_interval = (time_t) val;
208 }
209 SL_RETURN(retval, _("sh_portchk_set_interval"));
210}
211
212static int sh_portchk_set_port_minmax (const char * c, int * setthis)
213{
214 int retval = 0;
215 long val;
216
217 SL_ENTER(_("sh_portchk_set_port_minmax"));
218 val = strtol (c, (char **)NULL, 10);
219 if (val < 0 || val > 65535)
220 {
221 SH_MUTEX_LOCK(mutex_thread_nolog);
222 sh_error_handle ((-1), FIL__, __LINE__, EINVAL, MSG_EINVALS,
223 _("port check port minmax"), c);
224 SH_MUTEX_UNLOCK(mutex_thread_nolog);
225 retval = -1;
226 }
227 else
228 {
229 *setthis = (int) val;
230 }
231 SL_RETURN(retval, _("sh_portchk_set_port_minmax"));
232}
233
234
235static int sh_portchk_set_minport (const char * str)
236{
237 return sh_portchk_set_port_minmax (str, &sh_portchk_minport);
238}
239
240static int sh_portchk_set_maxport (const char * str)
241{
242 return sh_portchk_set_port_minmax (str, &sh_portchk_maxport);
243}
244
245static int sh_portchk_set_active (const char * str)
246{
247 return sh_util_flagval(str, &sh_portchk_active);
248}
249
250static int sh_portchk_set_udp (const char * str)
251{
252 return sh_util_flagval(str, &sh_portchk_check_udp);
253}
254
255static int sh_portchk_set_severity (const char * str)
256{
257 char tmp[32];
258 tmp[0] = '='; tmp[1] = '\0';
259 sl_strlcat (tmp, str, 32);
260 return sh_error_set_level (tmp, &sh_portchk_severity);
261}
262
263sh_rconf sh_portchk_table[] = {
264 {
265 N_("severityportcheck"),
266 sh_portchk_set_severity,
267 },
268 {
269 N_("portcheckrequired"),
270 sh_portchk_add_required,
271 },
272 {
273 N_("portcheckoptional"),
274 sh_portchk_add_optional,
275 },
276 {
277 N_("portcheckignore"),
278 sh_portchk_add_ignore,
279 },
280 {
281 N_("portcheckskip"),
282 sh_portchk_add_blacklist,
283 },
284 {
285 N_("portcheckactive"),
286 sh_portchk_set_active,
287 },
288 {
289 N_("portcheckinterface"),
290 sh_portchk_add_interface,
291 },
292 {
293 N_("portcheckinterval"),
294 sh_portchk_set_interval,
295 },
296 {
297 N_("portcheckminport"),
298 sh_portchk_set_minport,
299 },
300 {
301 N_("portcheckmaxport"),
302 sh_portchk_set_maxport,
303 },
304 {
305 N_("portcheckudp"),
306 sh_portchk_set_udp,
307 },
308 {
309 NULL,
310 NULL
311 }
312};
313
314#endif
315
316/* Interface to initialize port check
317 */
318int sh_portchk_init (struct mod_type * arg);
319
320/* Interface to reset port check
321 */
322int sh_portchk_reset (void);
323
324/* Interface to run port check
325 */
326int sh_portchk_check (void);
327
328
329static char * check_services (int port, int proto);
330
331#ifdef TEST_ONLY
332
333static int portchk_debug = 0;
334#define SH_ALLOC malloc
335#define SH_FREE free
336#define sh_util_strdup strdup
337#define sl_strlcpy strncpy
338#define _(a) a
339
340#else
341
342static int portchk_debug = 0;
343
344#endif
345
346#ifdef HAVE_RPC_RPC_H
347static char * sh_getrpcbynumber (int number, char * buf, size_t len)
348{
349 FILE * fp;
350
351 if (NULL != (fp = fopen(_("/etc/rpc"), "r")))
352 {
353 sh_string * s = sh_string_new(0);
354 while (0 < sh_string_read(s, fp, 1024))
355 {
356 char * p = sh_string_str(s);
357 while (*p && (*p == ' ' || *p == '\t')) ++p; /* skip whitespace */
358 if (*p == '\0' || *p == '#')
359 continue; /* skip comment */
360 else
361 {
362 size_t lengths[3];
363 unsigned int fields = 3;
364 char * q = sh_string_str(s);
365 char ** splits = split_array_ws(q, &fields, lengths);
366
367 if (fields >= 2)
368 {
369 int n = atoi(splits[1]);
370 if (n == number)
371 {
372 sl_strlcpy(buf, splits[0], len);
373 SH_FREE(splits);
374 sh_string_destroy(&s);
375 sl_fclose(FIL__, __LINE__, fp);
376 return buf;
377 }
378 }
379 SH_FREE(splits);
380 }
381 }
382 sh_string_destroy(&s);
383 sl_fclose(FIL__, __LINE__, fp);
384 }
385 return NULL;
386}
387#endif
388
389static char * sh_getservbyport (int port, const char * proto_in, char * buf, size_t len)
390{
391 FILE * fp;
392 char proto[8];
393
394 sl_strlcpy(proto, proto_in, sizeof(proto));
395
396 if (NULL != (fp = fopen(_("/etc/services"), "r")))
397 {
398 sh_string * s = sh_string_new(0);
399 while (0 < sh_string_read(s, fp, 1024))
400 {
401 char * p = sh_string_str(s);
402 while (*p && (*p == ' ' || *p == '\t')) ++p; /* skip whitespace */
403 if (*p == '\0' || *p == '#')
404 continue; /* skip comment */
405 else
406 {
407 size_t lengths[3];
408 unsigned int fields = 3;
409 char * q = sh_string_str(s);
410 char ** splits = split_array_ws(q, &fields, lengths);
411
412 if (fields >= 2)
413 {
414 char * end;
415 long n = strtol(splits[1], &end, 10);
416 if (n == port && end && (*end == '/' || *end == ','))
417 {
418 ++end;
419 if (0 == strcmp(end, proto))
420 {
421 sl_strlcpy(buf, splits[0], len);
422 SH_FREE(splits);
423 sh_string_destroy(&s);
424 sl_fclose(FIL__, __LINE__, fp);
425 return buf;
426 }
427 }
428 }
429 SH_FREE(splits);
430 }
431 }
432 sh_string_destroy(&s);
433 sl_fclose(FIL__, __LINE__, fp);
434 }
435 return NULL;
436}
437
438static void sh_portchk_add_to_list (int proto,
439 int port, struct sh_sockaddr * paddr,
440 char * service,
441 int flag, int status)
442{
443 struct sh_portentry * new = SH_ALLOC (sizeof(struct sh_portentry));
444
445 new->port = port;
446 sh_ipvx_ntoa(new->interface, SH_INTERFACE_SIZE, paddr);
447 new->status = status;
448 new->flag = flag;
449
450 new->error = NULL;
451
452 if (portchk_debug)
453 fprintf(stderr, _("add to list: port %d/%s %d %d (%s) %s\n"),
454 port, SH_PROTO_STR(proto), flag, status, service ? service : _("undef"),
455 new->interface);
456
457 if (service)
458 new->service = sh_util_strdup (service);
459 else
460 new->service = NULL;
461 if (proto == IPPROTO_TCP)
462 {
463 new->next = portlist_tcp;
464 portlist_tcp = new;
465 }
466 else
467 {
468 new->next = portlist_udp;
469 portlist_udp = new;
470 }
471 return;
472}
473
474/* Reset the list by setting all entries to UNKN.
475 * In the next cycle we will check, and set found ports to ISOK.
476 * Thereafter, we check for entries that are still UNKN.
477 */
478static void sh_portchk_reset_lists (void)
479{
480 struct sh_portentry * portlist;
481
482 portlist = portlist_tcp;
483 while (portlist)
484 {
485 if (portlist->status != SH_PORT_MISS)
486 portlist->status = SH_PORT_UNKN;
487 portlist = portlist->next;
488 }
489 portlist = portlist_udp;
490 while (portlist)
491 {
492 if (portlist->status != SH_PORT_MISS)
493 portlist->status = SH_PORT_UNKN;
494 portlist = portlist->next;
495 }
496 return;
497}
498
499static struct sh_portentry * sh_portchk_kill_list (struct sh_portentry * head)
500{
501 if (head)
502 {
503 if (head->next)
504 sh_portchk_kill_list (head->next);
505
506 if (head->service)
507 SH_FREE(head->service);
508 SH_FREE(head);
509 }
510 return NULL;
511}
512
513static struct sh_port * sh_portchk_kill_blacklist (struct sh_port * head)
514{
515 if (head)
516 {
517 if (head->next)
518 sh_portchk_kill_blacklist (head->next);
519
520 SH_FREE(head->paddr);
521 SH_FREE(head);
522 }
523 return NULL;
524}
525
526/* These variables are not used anywhere. They only exist
527 * to assign &pre, &ptr to them, which keeps gcc from
528 * putting it into a register, and avoids the 'clobbered
529 * by longjmp' warning. And no, 'volatile' proved insufficient.
530 */
531void * sh_dummy_531_pre = NULL;
532void * sh_dummy_532_ptr = NULL;
533
534/* check the list of open ports for any that are marked as UNKN
535 */
536static void sh_portchk_check_list (struct sh_portentry ** head,
537 int proto, int report)
538{
539 struct sh_portentry * ptr = *head;
540 struct sh_portentry * pre = *head;
541 char errbuf[256];
542
543 /* Take the address to keep gcc from putting them into registers.
544 * Avoids the 'clobbered by longjmp' warning.
545 */
546 sh_dummy_531_pre = (void*) &pre;
547 sh_dummy_532_ptr = (void*) &ptr;
548
549 while (ptr)
550 {
551 if (portchk_debug && report)
552 fprintf(stderr, _("check list: port %d/%s %d %d\n"),
553 ptr->port, SH_PROTO_STR(proto), ptr->flag, ptr->status);
554
555 if (ptr->status == SH_PORT_UNKN)
556 {
557 /* Don't report missing ports that are marked as optional
558 */
559 if (ptr->flag != SH_PORT_OPT && ptr->flag != SH_PORT_IGN)
560 {
561 snprintf (errbuf, sizeof(errbuf), _("port: %s:%d/%s (%s)"),
562 ptr->interface, ptr->port, SH_PROTO_STR(proto),
563 ptr->service ? ptr->service : check_services(ptr->port, proto));
564#ifdef TEST_ONLY
565 if (report == SH_PORT_REPORT)
566 fprintf(stderr, _("%s\n"), errbuf);
567#else
568 if (report == SH_PORT_REPORT)
569 {
570 SH_MUTEX_LOCK(mutex_thread_nolog);
571 sh_error_handle(sh_portchk_severity, FIL__, __LINE__, 0,
572 MSG_PORT_MISS, errbuf);
573 SH_MUTEX_UNLOCK(mutex_thread_nolog);
574 }
575#endif
576 }
577
578 ptr->status = SH_PORT_MISS;
579
580 if ((ptr->flag != SH_PORT_REQ) && (ptr->flag != SH_PORT_OPT) && (ptr->flag != SH_PORT_IGN))
581 {
582 if (portchk_debug && report)
583 fprintf(stderr, _("removing: port %d/%s %d %d\n"),
584 ptr->port, SH_PROTO_STR(proto), ptr->flag, ptr->status);
585
586 if (ptr == *head)
587 {
588 *head = ptr->next;
589 if (ptr->service)
590 SH_FREE(ptr->service);
591 SH_FREE(ptr);
592 ptr = *head;
593 pre = *head;
594 continue;
595 }
596 else if (ptr->next == NULL)
597 {
598 pre->next = NULL;
599 if (ptr->service)
600 SH_FREE(ptr->service);
601 SH_FREE(ptr);
602 return;
603 }
604 else
605 {
606 pre->next = ptr->next;
607 if (ptr->service)
608 SH_FREE(ptr->service);
609 SH_FREE(ptr);
610 ptr = pre->next;
611 continue;
612 }
613 }
614 }
615 pre = ptr;
616 ptr = ptr->next;
617 }
618
619 sh_dummy_532_ptr = NULL;
620 sh_dummy_531_pre = NULL;
621
622 return;
623}
624
625
626static struct sh_portentry * sh_portchk_get_from_list (int proto, int port,
627 struct sh_sockaddr * paddr, char * service)
628{
629 struct sh_portentry * portlist;
630 char str_addr[SH_IP_BUF];
631
632 if (proto == IPPROTO_TCP)
633 portlist = portlist_tcp;
634 else
635 portlist = portlist_udp;
636
637 sh_ipvx_ntoa(str_addr, sizeof(str_addr), paddr);
638
639 if (service)
640 {
641 while (portlist)
642 {
643 if (portlist->service &&
644 0 == strcmp(service, portlist->service) &&
645 ( 0 == strcmp(portlist->interface, str_addr) ||
646 sh_ipvx_isany(paddr) ))
647 return portlist;
648 portlist = portlist->next;
649 }
650 }
651 else
652 {
653 while (portlist)
654 {
655 if (port == portlist->port &&
656 (0 == strcmp(portlist->interface, str_addr) ||
657 sh_ipvx_isany(paddr) ))
658 return portlist;
659 portlist = portlist->next;
660 }
661 }
662 return NULL;
663}
664
665
666static void sh_portchk_cmp_to_list (int proto, int port,
667 struct sh_sockaddr * paddr, char * service)
668{
669 struct sh_portentry * portent;
670 char errbuf[256];
671
672
673 portent = sh_portchk_get_from_list (proto, port, paddr, service);
674
675 if (service)
676 {
677 if (!portent)
678 {
679 char * path;
680 unsigned long qpid;
681 char user[USER_MAX];
682 char saddr[SH_IP_BUF];
683
684 sh_ipvx_ntoa(saddr, sizeof(saddr), paddr);
685
686 snprintf (errbuf, sizeof(errbuf), _("port: %s:%d/%s (%s)"),
687 saddr, port, SH_PROTO_STR(proto), service);
688
689 if (portchk_debug)
690 fprintf(stderr, _("cmp_to_list: open port: %s:%d/%s (%s)\n"),
691 saddr, port, SH_PROTO_STR(proto), service);
692
693#ifndef TEST_ONLY
694 path = sh_port2proc_query(proto, paddr, port, &qpid, user, sizeof(user));
695 SH_MUTEX_LOCK(mutex_thread_nolog);
696 sh_error_handle(sh_portchk_severity, FIL__, __LINE__, 0,
697 MSG_PORT_NEW, errbuf, path, qpid, user);
698 SH_MUTEX_UNLOCK(mutex_thread_nolog);
699 SH_FREE(path);
700#endif
701 /*
702 * was not there, thus it is not in 'required' or 'optional' list
703 */
704 sh_portchk_add_to_list (proto, port, paddr, service, SH_PORT_NOT, SH_PORT_ISOK);
705 }
706 else if (portent->status == SH_PORT_MISS && portent->flag != SH_PORT_IGN)
707 {
708 char * path;
709 unsigned long qpid;
710 char user[USER_MAX];
711 char saddr[SH_IP_BUF];
712
713 sh_ipvx_ntoa(saddr, sizeof(saddr), paddr);
714
715 snprintf (errbuf, sizeof(errbuf), _("port: %s:%d/%s (%s), was %d/%s"),
716 saddr, port, SH_PROTO_STR(proto), service, portent->port, SH_PROTO_STR(proto));
717#ifdef TEST_ONLY
718 fprintf(stderr, _("service: %s\n"), errbuf);
719#else
720 path = sh_port2proc_query(proto, paddr, port, &qpid, user, sizeof(user));
721 SH_MUTEX_LOCK(mutex_thread_nolog);
722 sh_error_handle(sh_portchk_severity, FIL__, __LINE__, 0,
723 MSG_PORT_RESTART, errbuf, path, qpid, user);
724 SH_MUTEX_UNLOCK(mutex_thread_nolog);
725 SH_FREE(path);
726#endif
727
728 portent->status = SH_PORT_ISOK;
729 }
730 else if (port != portent->port && (-1) != portent->port)
731 {
732 char * path;
733 unsigned long qpid;
734 char user[USER_MAX];
735 char saddr[SH_IP_BUF];
736
737 sh_ipvx_ntoa(saddr, sizeof(saddr), paddr);
738
739 snprintf (errbuf, sizeof(errbuf), _("port: %s:%d/%s (%s), was %d/%s"),
740 saddr, port, SH_PROTO_STR(proto), service, portent->port, SH_PROTO_STR(proto));
741#ifdef TEST_ONLY
742 fprintf(stderr, _("service: %s\n"), errbuf);
743#else
744 path = sh_port2proc_query(proto, paddr, port, &qpid, user, sizeof(user));
745 SH_MUTEX_LOCK(mutex_thread_nolog);
746 sh_error_handle(sh_portchk_severity, FIL__, __LINE__, 0,
747 MSG_PORT_NEWPORT, errbuf, path, qpid, user);
748 SH_MUTEX_UNLOCK(mutex_thread_nolog);
749 SH_FREE(path);
750#endif
751 portent->port = port;
752 portent->status = SH_PORT_ISOK;
753 }
754 else
755 {
756 portent->status = SH_PORT_ISOK;
757 }
758 }
759 else
760 {
761 if (!portent)
762 {
763 char * path;
764 unsigned long qpid;
765 char user[USER_MAX];
766 char saddr[SH_IP_BUF];
767
768 if (portchk_debug)
769 fprintf(stderr, _("call to sh_ipvx_ntoa (port %d)\n"), port);
770
771 sh_ipvx_ntoa(saddr, sizeof(saddr), paddr);
772
773 snprintf (errbuf, sizeof(errbuf), _("port: %s:%d/%s (%s)"),
774 saddr, port, SH_PROTO_STR(proto), check_services(port, proto));
775
776 if (portchk_debug)
777 fprintf(stderr, _("cmp_to_list: open port: %s:%d/%s (%s) check_services\n"),
778 saddr, port, SH_PROTO_STR(proto), check_services(port, proto));
779
780#ifndef TEST_ONLY
781 path = sh_port2proc_query(proto, paddr, port, &qpid, user, sizeof(user));
782 SH_MUTEX_LOCK(mutex_thread_nolog);
783 sh_error_handle(sh_portchk_severity, FIL__, __LINE__, 0,
784 MSG_PORT_NEW, errbuf, path, qpid, user);
785 SH_MUTEX_UNLOCK(mutex_thread_nolog);
786 SH_FREE(path);
787#endif
788
789 /* was not there, thus it is not in 'required' or 'optional' list
790 */
791 sh_portchk_add_to_list (proto, port, paddr, service, SH_PORT_NOT, SH_PORT_ISOK);
792 }
793 else if (portent->status == SH_PORT_MISS && portent->flag != SH_PORT_IGN)
794 {
795 char * path;
796 unsigned long qpid;
797 char user[USER_MAX];
798 char saddr[SH_IP_BUF];
799
800 sh_ipvx_ntoa(saddr, sizeof(saddr), paddr);
801
802 snprintf (errbuf, sizeof(errbuf), _("port: %s:%d/%s (%s)"),
803 saddr, port, SH_PROTO_STR(proto), check_services(port, proto));
804#ifdef TEST_ONLY
805 fprintf(stderr, _("port : %s\n"), errbuf);
806#else
807 path = sh_port2proc_query(proto, paddr, port, &qpid, user, sizeof(user));
808 SH_MUTEX_LOCK(mutex_thread_nolog);
809 sh_error_handle(sh_portchk_severity, FIL__, __LINE__, 0,
810 MSG_PORT_RESTART, errbuf, path, qpid, user);
811 SH_MUTEX_UNLOCK(mutex_thread_nolog);
812 SH_FREE(path);
813#endif
814
815 portent->status = SH_PORT_ISOK;
816 }
817 else
818 {
819 portent->status = SH_PORT_ISOK;
820 }
821 }
822
823 return;
824}
825
826
827/* Returns a static buffer containing the name of the service
828 * running on port <port> (from /etc/services)
829 * Returns NULL on failure
830 */
831static char * check_services (int port, int proto)
832{
833 static char buf[256];
834 char * service = sh_getservbyport(port, SH_PROTO_STR(proto), buf, sizeof(buf));
835
836 if (!service)
837 {
838 snprintf (buf, sizeof(buf), "%s",_("unknown"));
839 }
840 return buf;
841}
842
843/* Returns a static buffer containing the name of the service
844 * running on port <port> at <address> (from portmap daemon)
845 * Returns NULL on failure
846 */
847static char * check_rpc_list (int port, struct sockaddr_in * address,
848 unsigned long prot)
849{
850#if defined(HAVE_RPC_RPC_H) && defined(HAVE_PMAP_GETMAPS)
851 struct pmaplist * head;
852 char *r;
853 static char buf[256];
854
855 head = pmap_getmaps(address);
856
857 if (head)
858 {
859 do /* while (head != NULL) */
860 {
861 if ((head->pml_map.pm_prot == prot) &&
862 (port == (int)head->pml_map.pm_port))
863 {
864 r = sh_getrpcbynumber((int)head->pml_map.pm_prog,
865 buf, sizeof(buf));
866 if (r)
867 {
868 return buf;
869 }
870 else
871 {
872 snprintf (buf, sizeof(buf), "RPC_%lu",
873 (unsigned long)head->pml_map.pm_prog);
874 return buf;
875 }
876 }
877 head = head->pml_next;
878 }
879 while (head != NULL);
880 }
881#else
882 (void) port;
883 (void) address;
884 (void) prot;
885#endif
886 return NULL;
887}
888
889static int check_port_udp_internal (int fd, int port, struct sh_sockaddr * paddr)
890{
891 int retval;
892 char * p = NULL;
893 char buf[8];
894#ifndef TEST_ONLY
895 char errmsg[256];
896 int nerr;
897#endif
898 char errbuf[SH_ERRBUF_SIZE];
899 char ipbuf[SH_IP_BUF];
900
901 sh_ipvx_set_port(paddr, port);
902
903 do {
904 retval = connect(fd, sh_ipvx_sockaddr_cast(paddr), SH_SSP_LEN(paddr));
905 } while (retval < 0 && (errno == EINTR || errno == EINPROGRESS));
906
907 if (retval == -1)
908 {
909#ifdef TEST_ONLY
910 if (portchk_debug)
911 perror(_("connect"));
912#else
913 sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
914
915 nerr = errno;
916 sl_snprintf(errmsg, sizeof(errmsg), _("check port: %5d/udp on %15s: %s"),
917 port, ipbuf, sh_error_message(errno, errbuf, sizeof(errbuf)));
918 SH_MUTEX_LOCK(mutex_thread_nolog);
919 sh_error_handle((-1), FIL__, __LINE__, nerr, MSG_E_SUBGEN,
920 errmsg, _("connect"));
921 SH_MUTEX_UNLOCK(mutex_thread_nolog);
922#endif
923 }
924 else
925 {
926 do {
927 retval = send (fd, buf, 0, 0);
928 } while (retval < 0 && errno == EINTR);
929
930 if (retval == -1 && errno == ECONNREFUSED)
931 {
932 sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
933 if (portchk_debug)
934 fprintf(stderr, _("check port_udp: %5d/udp on %15s established/time_wait\n"),
935 port, ipbuf);
936 }
937 else
938 {
939 /* Only the second send() may catch the error
940 */
941 do {
942 retval = send (fd, buf, 0, 0);
943 } while (retval < 0 && errno == EINTR);
944
945 if (retval == -1 && errno == ECONNREFUSED)
946 {
947 sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
948 if (portchk_debug)
949 fprintf(stderr, _("check port: %5d/udp on %15s established/time_wait\n"),
950 port, ipbuf);
951 }
952 else if (retval != -1)
953 {
954 /* Try to get service name from portmap
955 */
956 if (paddr->ss_family == AF_INET)
957 {
958 p = check_rpc_list (port,
959 (struct sockaddr_in *) sh_ipvx_sockaddr_cast(paddr),
960 IPPROTO_UDP);
961 }
962
963 sh_portchk_cmp_to_list (IPPROTO_UDP, port, paddr, p ? p : NULL);
964
965 /* If not an RPC service, try to get name from /etc/services
966 */
967 if (!p)
968 p = check_services(port, IPPROTO_UDP);
969
970 if (portchk_debug)
971 {
972 sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
973 fprintf(stderr, _("check port_udp: %5d/udp on %15s open %s\n"),
974 port, ipbuf, p);
975 }
976
977 }
978 }
979 }
980 sl_close_fd (FIL__, __LINE__, fd);
981 return 0;
982}
983
984static int check_port_tcp_internal (int fd, int port, struct sh_sockaddr * paddr)
985{
986 int retval;
987 int flags;
988 char * p = NULL;
989#ifndef TEST_ONLY
990 char errmsg[256];
991 int nerr;
992#endif
993 char errbuf[SH_ERRBUF_SIZE];
994 char ipbuf[SH_IP_BUF];
995
996 sh_ipvx_set_port(paddr, port);
997
998 do {
999 retval = connect(fd, sh_ipvx_sockaddr_cast(paddr), SH_SSP_LEN(paddr));
1000 } while (retval < 0 && (errno == EINTR || errno == EINPROGRESS));
1001
1002 if (retval == -1 && errno == ECONNREFUSED)
1003 {
1004 if (portchk_debug)
1005 {
1006 sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
1007 fprintf(stderr, _("check port_tcp: %5d on %15s closed\n"),
1008 port, ipbuf);
1009 }
1010 }
1011 else if (retval == -1)
1012 {
1013#ifdef TEST_ONLY
1014 if (portchk_debug)
1015 perror(_("connect"));
1016#else
1017 sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
1018 nerr = errno;
1019 sl_snprintf(errmsg, sizeof(errmsg), _("check port: %5d/tcp on %15s: %s"),
1020 port, ipbuf, sh_error_message(errno, errbuf, sizeof(errbuf)));
1021 SH_MUTEX_LOCK(mutex_thread_nolog);
1022 sh_error_handle((-1), FIL__, __LINE__, nerr, MSG_E_SUBGEN,
1023 errmsg, _("connect"));
1024 SH_MUTEX_UNLOCK(mutex_thread_nolog);
1025#endif
1026 }
1027 else
1028 {
1029 /* Try to get service name from portmap
1030 */
1031 if (paddr->ss_family == AF_INET)
1032 {
1033 p = check_rpc_list (port,
1034 (struct sockaddr_in *) sh_ipvx_sockaddr_cast(paddr),
1035 IPPROTO_TCP);
1036 }
1037
1038 sh_portchk_cmp_to_list (IPPROTO_TCP, port, paddr, p ? p : NULL);
1039
1040 /* If not an RPC service, try to get name from /etc/services
1041 */
1042 if (!p)
1043 p = check_services(port, IPPROTO_TCP);
1044
1045 if (portchk_debug)
1046 {
1047 sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), paddr);
1048 fprintf(stderr, _("check port_tcp: %5d on %15s open %s\n"),
1049 port, ipbuf, p);
1050 }
1051
1052#if !defined(O_NONBLOCK)
1053#if defined(O_NDELAY)
1054#define O_NONBLOCK O_NDELAY
1055#else
1056#define O_NONBLOCK 0
1057#endif
1058#endif
1059
1060 /* prepare to close connection gracefully
1061 */
1062 if (port == 22) /* ssh */
1063 {
1064 flags = retry_fcntl(FIL__, __LINE__, fd, F_GETFL, 0);
1065 retry_fcntl(FIL__, __LINE__, fd, F_SETFL, flags | O_NONBLOCK);
1066 retval = write (fd, _("SSH-2.0-Foobar"), 14);
1067 if (retval > 0) retval = write (fd, "\r\n", 2);
1068 }
1069 else if (port == 25) /* smtp */
1070 {
1071 flags = retry_fcntl(FIL__, __LINE__, fd, F_GETFL, 0);
1072 retry_fcntl(FIL__, __LINE__, fd, F_SETFL, flags | O_NONBLOCK);
1073 retval = write (fd, _("QUIT"), 4);
1074 if (retval > 0) retval = write (fd, "\r\n", 2);
1075 }
1076 else if (port == 79) /* finger */
1077 {
1078 flags = retry_fcntl(FIL__, __LINE__, fd, F_GETFL, 0);
1079 retry_fcntl(FIL__, __LINE__, fd, F_SETFL, flags | O_NONBLOCK);
1080 retval = write (fd, "\r\n", 2);
1081 }
1082 else if (port == 110) /* pop3 */
1083 {
1084 flags = retry_fcntl(FIL__, __LINE__, fd, F_GETFL, 0);
1085 retry_fcntl(FIL__, __LINE__, fd, F_SETFL, flags | O_NONBLOCK);
1086 retval = write (fd, _("QUIT"), 4);
1087 if (retval > 0) retval = write (fd, "\r\n", 2);
1088 }
1089 else if (port == 143) /* imap */
1090 {
1091 flags = retry_fcntl(FIL__, __LINE__, fd, F_GETFL, 0);
1092 retry_fcntl(FIL__, __LINE__, fd, F_SETFL, flags | O_NONBLOCK);
1093 retval = write (fd, _("A01 LOGOUT"), 10);
1094 if (retval > 0) retval = write (fd, "\r\n", 2);
1095 }
1096
1097 if (portchk_debug && retval < 0)
1098 fprintf(stderr, _("check port: error writing to port %5d\n"),
1099 port);
1100 }
1101 sl_close_fd (FIL__, __LINE__, fd);
1102 return 0;
1103}
1104
1105/* typedef uint32_t in_addr_t;
1106 * struct in_addr
1107 * {
1108 * in_addr_t s_addr;
1109 * };
1110 */
1111
1112#define SH_IFACE_MAX 16
1113
1114struct portchk_interfaces {
1115 struct sh_sockaddr iface[SH_IFACE_MAX];
1116 int used;
1117};
1118
1119static struct portchk_interfaces iface_list;
1120static int iface_initialized = 0;
1121
1122#ifdef TEST_ONLY
1123static char * portchk_hostname = NULL;
1124#else
1125static char * portchk_hostname = sh.host.name;
1126#endif
1127
1128static int sh_portchk_init_internal (void)
1129{
1130 volatile int i, j; /* might be clobbered by ‘longjmp’ or ‘vfork’*/
1131 char errbuf[256];
1132#if defined(USE_IPVX)
1133 struct addrinfo hints;
1134 struct addrinfo *res;
1135#else
1136 struct hostent * hent;
1137#endif
1138 char ipbuf[SH_IP_BUF];
1139
1140 if (portchk_debug)
1141 fprintf(stderr, _("checking ports on: %s\n"), portchk_hostname ? portchk_hostname : _("NULL"));
1142
1143 if (!portchk_hostname)
1144 return -1;
1145
1146 if (sh_portchk_active == S_FALSE)
1147 return -1;
1148
1149 SH_MUTEX_LOCK(mutex_port_check);
1150 if (iface_initialized == 0)
1151 {
1152 iface_list.used = 0;
1153 iface_initialized = 1;
1154 }
1155
1156#if !defined(USE_IPVX)
1157 SH_MUTEX_LOCK(mutex_resolv);
1158 hent = sh_gethostbyname(portchk_hostname);
1159 i = 0;
1160 while (hent && hent->h_addr_list[i] && (iface_list.used < SH_IFACE_MAX))
1161 {
1162 struct sockaddr_in sin;
1163 struct sh_sockaddr iface_tmp;
1164
1165 memcpy(&(sin.sin_addr.s_addr), hent->h_addr_list[i], sizeof(in_addr_t));
1166 sh_ipvx_save(&iface_tmp, AF_INET, (struct sockaddr *)&sin);
1167
1168 for (j = 0; j < iface_list.used; ++j)
1169 {
1170 if (0 == sh_ipvx_cmp(&iface_tmp, &(iface_list.iface[j])))
1171 {
1172 goto next_iface;
1173 }
1174 }
1175
1176 sh_ipvx_save(&(iface_list.iface[iface_list.used]),
1177 AF_INET, (struct sockaddr *)&sin);
1178
1179 if (portchk_debug)
1180 {
1181 char buf[256];
1182 sh_ipvx_ntoa(buf, sizeof(buf), &(iface_list.iface[iface_list.used]));
1183 fprintf(stderr, _("added interface[%d]: %s\n"), i, buf);
1184 }
1185 ++iface_list.used;
1186
1187 next_iface:
1188 ++i;
1189 }
1190 SH_MUTEX_UNLOCK(mutex_resolv);
1191#else
1192 memset(&hints, '\0', sizeof(hints));
1193 hints.ai_family = PF_UNSPEC;
1194 hints.ai_flags = AI_ADDRCONFIG;
1195
1196 if (0 == getaddrinfo(portchk_hostname, NULL, &hints, &res))
1197 {
1198 struct addrinfo *p = res;
1199 struct sh_sockaddr iface_tmp;
1200
1201 while ((p != NULL) && (iface_list.used < SH_IFACE_MAX))
1202 {
1203 sh_ipvx_save(&iface_tmp, p->ai_family, p->ai_addr);
1204
1205 for (j = 0; j < iface_list.used; ++j)
1206 {
1207 if (portchk_debug)
1208 {
1209 char buf1[256], buf2[256];
1210 sh_ipvx_ntoa(buf1, sizeof(buf1), &(iface_list.iface[j]));
1211 sh_ipvx_ntoa(buf2, sizeof(buf2), &iface_tmp);
1212 fprintf(stderr, _("check interface[%d]: %s vs %s\n"), j, buf1, buf2);
1213 }
1214 if (0 == sh_ipvx_cmp(&iface_tmp, &(iface_list.iface[j])))
1215 {
1216 if (portchk_debug)
1217 fprintf(stderr, _("skipping interface[%d]\n"), j);
1218 goto next_iface;
1219 }
1220 }
1221 sh_ipvx_save(&(iface_list.iface[iface_list.used]),
1222 p->ai_family, p->ai_addr);
1223
1224 if (portchk_debug)
1225 {
1226 char buf[256];
1227 sh_ipvx_ntoa(buf, sizeof(buf), &(iface_list.iface[iface_list.used]));
1228 fprintf(stderr, _("added interface[%d]: %s\n"), iface_list.used, buf);
1229 }
1230
1231 ++iface_list.used;
1232
1233 next_iface:
1234 p = p->ai_next;
1235 }
1236 freeaddrinfo(res);
1237 }
1238#endif
1239
1240 for (i = 0; i < iface_list.used; ++i)
1241 {
1242 sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), &(iface_list.iface[i]));
1243 sl_snprintf(errbuf, sizeof(errbuf), _("added interface: %s"), ipbuf);
1244
1245 SH_MUTEX_LOCK(mutex_thread_nolog);
1246 sh_error_handle(SH_ERR_INFO, FIL__, __LINE__, 0, MSG_E_SUBGEN,
1247 errbuf, _("sh_portchk_init"));
1248 SH_MUTEX_UNLOCK(mutex_thread_nolog);
1249 }
1250 SH_MUTEX_UNLOCK(mutex_port_check);
1251
1252 return 0;
1253}
1254
1255int sh_portchk_init (struct mod_type * arg)
1256{
1257#ifndef HAVE_PTHREAD
1258 (void) arg;
1259#endif
1260
1261 if (sh_portchk_active == S_FALSE)
1262 return SH_MOD_FAILED;
1263 if (!portchk_hostname)
1264 return SH_MOD_FAILED;
1265
1266#ifdef HAVE_PTHREAD
1267 if (arg != NULL && arg->initval < 0 &&
1268 (sh.flag.isdaemon == S_TRUE || sh.flag.loop == S_TRUE))
1269 {
1270 if (0 == sh_pthread_create(sh_threaded_module_run, (void *)arg))
1271 return SH_MOD_THREAD;
1272 else
1273 return SH_MOD_FAILED;
1274 }
1275 else if (arg != NULL && arg->initval == SH_MOD_THREAD &&
1276 (sh.flag.isdaemon == S_TRUE || sh.flag.loop == S_TRUE))
1277 {
1278 return SH_MOD_THREAD;
1279 }
1280#endif
1281 return sh_portchk_init_internal();
1282}
1283
1284
1285
1286#if !defined(TEST_ONLY)
1287int sh_portchk_reconf (void)
1288{
1289 SH_MUTEX_LOCK(mutex_port_check);
1290 iface_initialized = 0;
1291 sh_portchk_active = 1;
1292 sh_portchk_check_udp = 1;
1293 sh_portchk_interval = SH_PORTCHK_INTERVAL;
1294
1295 sh_portchk_minport = -1;
1296 sh_portchk_maxport = -1;
1297
1298 portlist_udp = sh_portchk_kill_list (portlist_udp);
1299 portlist_tcp = sh_portchk_kill_list (portlist_tcp);
1300
1301 blacklist_udp = sh_portchk_kill_blacklist (blacklist_udp);
1302 blacklist_tcp = sh_portchk_kill_blacklist (blacklist_tcp);
1303 sh_port2proc_finish();
1304
1305 SH_MUTEX_UNLOCK(mutex_port_check);
1306 return 0;
1307}
1308
1309int sh_portchk_cleanup (void)
1310{
1311 return sh_portchk_reconf ();
1312}
1313
1314int sh_portchk_timer (time_t tcurrent)
1315{
1316 static time_t lastcheck = 0;
1317
1318 SL_ENTER(_("sh_portchk_timer"));
1319 if ((time_t) (tcurrent - lastcheck) >= sh_portchk_interval)
1320 {
1321 lastcheck = tcurrent;
1322 SL_RETURN((-1), _("sh_portchk_timer"));
1323 }
1324 SL_RETURN(0, _("sh_portchk_timer"));
1325}
1326#endif
1327
1328static int check_port_generic (int port, int domain, int type, int protocol)
1329{
1330 volatile int i = 0;
1331 int sock = -1;
1332 int flag = 1; /* non-zero to enable an option */
1333 struct sh_sockaddr paddr;
1334 char errbuf[SH_ERRBUF_SIZE];
1335
1336 /* Check all interfaces for this host
1337 */
1338 while (i < iface_list.used)
1339 {
1340 memcpy(&paddr, &(iface_list.iface[i]), sizeof(paddr));
1341
1342 if (paddr.ss_family != domain)
1343 {
1344 ++i;
1345 continue;
1346 }
1347
1348 if (0 != sh_portchk_is_blacklisted(port, &paddr, protocol))
1349 {
1350 ++i;
1351 continue;
1352 }
1353
1354 if ((sock = socket(paddr.ss_family, type, protocol)) < 0 )
1355 {
1356 ++i;
1357#ifdef TEST_ONLY
1358 if (portchk_debug)
1359 perror(_("socket"));
1360#else
1361
1362#ifndef EPROTONOSUPPORT
1363#define EPROTONOSUPPORT 0
1364#endif
1365#ifndef EAFNOSUPPORT
1366#define EAFNOSUPPORT 0
1367#endif
1368 if (errno != EPROTONOSUPPORT && errno != EAFNOSUPPORT)
1369 {
1370 SH_MUTEX_LOCK(mutex_thread_nolog);
1371 sh_error_handle((-1), FIL__, __LINE__, errno, MSG_E_SUBGEN,
1372 sh_error_message(errno, errbuf, sizeof(errbuf)), _("socket"));
1373 SH_MUTEX_UNLOCK(mutex_thread_nolog);
1374 }
1375#endif
1376 continue;
1377 }
1378 if ( setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
1379 (void *) &flag, sizeof(flag)) < 0 )
1380 {
1381 ++i;
1382#ifdef TEST_ONLY
1383 if (portchk_debug)
1384 perror(_("setsockopt"));
1385#else
1386 SH_MUTEX_LOCK(mutex_thread_nolog);
1387 sh_error_handle((-1), FIL__, __LINE__, errno, MSG_E_SUBGEN,
1388 sh_error_message(errno, errbuf, sizeof(errbuf)),_("setsockopt"));
1389 SH_MUTEX_UNLOCK(mutex_thread_nolog);
1390#endif
1391 continue;
1392 }
1393
1394
1395 if (protocol == IPPROTO_TCP)
1396 check_port_tcp_internal(sock, port, &paddr);
1397 else
1398 check_port_udp_internal(sock, port, &paddr);
1399
1400 ++i;
1401 }
1402
1403 return 0;
1404}
1405
1406
1407
1408static int check_port_udp (int port, int domain)
1409{
1410 return check_port_generic(port, domain, SOCK_DGRAM, IPPROTO_UDP);
1411}
1412
1413static int check_port_tcp (int port, int domain)
1414{
1415 return check_port_generic(port, domain, SOCK_STREAM, IPPROTO_TCP);
1416}
1417
1418
1419static int sh_portchk_scan_ports_generic (int min_port, int max_port_arg,
1420 int domain, int type, int protocol)
1421{
1422 /*
1423 int min_port = 1024;
1424 int max_port = 65535;
1425 */
1426
1427 volatile int port; /* might be clobbered by ‘longjmp’ or ‘vfork’*/
1428 volatile int max_port = max_port_arg;
1429 int retval;
1430 int sock = -1;
1431 int flag = 1; /* non-zero to enable an option */
1432
1433 struct sockaddr_in addr4;
1434 struct sockaddr_in6 addr6;
1435
1436 int addrlen4 = sizeof(addr4);
1437 int addrlen6 = sizeof(addr6);
1438
1439 struct in6_addr anyaddr = IN6ADDR_ANY_INIT;
1440
1441 char errbuf[SH_ERRBUF_SIZE];
1442
1443 if (min_port == -1)
1444 min_port = 0;
1445 if (max_port == -1)
1446 max_port = 65535;
1447
1448 if (portchk_debug)
1449 fprintf(stderr, _("scan_ports_generic %d-%d %s %s\n"),
1450 min_port, max_port, (domain == AF_INET6) ? _("AF_INET6") : _("AF_INET"),
1451 (protocol == IPPROTO_TCP) ? _("tcp") : _("udp"));
1452
1453 for (port = min_port; port <= max_port; ++port)
1454 {
1455 if ((sock = socket(domain, type, protocol)) < 0 )
1456 {
1457#ifdef TEST_ONLY
1458 if (portchk_debug)
1459 perror(_("socket"));
1460#else
1461#ifndef EPROTONOSUPPORT
1462#define EPROTONOSUPPORT 0
1463#endif
1464#ifndef EAFNOSUPPORT
1465#define EAFNOSUPPORT 0
1466#endif
1467 if (errno != EPROTONOSUPPORT && errno != EAFNOSUPPORT)
1468 {
1469 SH_MUTEX_LOCK(mutex_thread_nolog);
1470 sh_error_handle((-1), FIL__, __LINE__, errno, MSG_E_SUBGEN,
1471 sh_error_message(errno, errbuf, sizeof(errbuf)), _("socket"));
1472 SH_MUTEX_UNLOCK(mutex_thread_nolog);
1473 }
1474#endif
1475 continue;
1476 }
1477 if ( setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
1478 (void *) &flag, sizeof(flag)) < 0 )
1479 {
1480#ifdef TEST_ONLY
1481 if (portchk_debug)
1482 perror(_("setsockopt"));
1483#else
1484 SH_MUTEX_LOCK(mutex_thread_nolog);
1485 sh_error_handle((-1), FIL__, __LINE__, errno, MSG_E_SUBGEN,
1486 sh_error_message(errno, errbuf, sizeof(errbuf)),_("setsockopt"));
1487 SH_MUTEX_UNLOCK(mutex_thread_nolog);
1488#endif
1489 continue;
1490 }
1491
1492 if (domain == AF_INET)
1493 {
1494 addr4.sin_family = AF_INET;
1495 addr4.sin_port = htons(port);
1496 addr4.sin_addr.s_addr = INADDR_ANY;
1497 retval = bind (sock, (struct sockaddr *) &addr4, addrlen4);
1498 }
1499 else
1500 {
1501 addr6.sin6_family = AF_INET6;
1502 addr6.sin6_port = htons(port);
1503 memcpy(&(addr6.sin6_addr.s6_addr), &anyaddr, sizeof(anyaddr));
1504 retval = bind (sock, (struct sockaddr *) &addr6, addrlen6);
1505 }
1506
1507 if (retval == 0)
1508 {
1509 /* we can bind the port, thus it is unused
1510 */
1511 sl_close_fd (FIL__, __LINE__, sock);
1512 }
1513 else
1514 {
1515 if (errno == EINVAL || errno == EADDRINUSE)
1516 {
1517 /* try to connect to the port
1518 */
1519 if (protocol == IPPROTO_TCP)
1520 check_port_tcp(port, domain);
1521 else
1522 check_port_udp(port, domain);
1523 }
1524 else
1525 {
1526#ifdef TEST_ONLY
1527 if (portchk_debug)
1528 perror(_("bind"));
1529#else
1530 SH_MUTEX_LOCK(mutex_thread_nolog);
1531 sh_error_handle((-1), FIL__, __LINE__, errno, MSG_E_SUBGEN,
1532 sh_error_message(errno, errbuf, sizeof(errbuf)), _("bind"));
1533 SH_MUTEX_UNLOCK(mutex_thread_nolog);
1534#endif
1535 }
1536 sl_close_fd (FIL__, __LINE__, sock);
1537 }
1538 }
1539 return 0;
1540}
1541
1542static int sh_portchk_scan_ports_tcp (int min_port, int max_port)
1543{
1544#if defined(USE_IPVX)
1545 sh_portchk_scan_ports_generic (min_port, max_port, AF_INET6,
1546 SOCK_STREAM, IPPROTO_TCP);
1547#endif
1548 return sh_portchk_scan_ports_generic (min_port, max_port, AF_INET,
1549 SOCK_STREAM, IPPROTO_TCP);
1550}
1551
1552static int sh_portchk_scan_ports_udp (int min_port, int max_port)
1553{
1554#if defined(USE_IPVX)
1555 sh_portchk_scan_ports_generic (min_port, max_port, AF_INET6,
1556 SOCK_DGRAM, IPPROTO_UDP);
1557#endif
1558 return sh_portchk_scan_ports_generic (min_port, max_port, AF_INET,
1559 SOCK_DGRAM, IPPROTO_UDP);
1560}
1561
1562/* Subroutine to add an interface
1563 */
1564void * sh_dummy_1564_str = NULL; /* fix clobbered by.. warning */
1565
1566static int sh_portchk_add_interface (const char * str)
1567{
1568 struct sh_sockaddr saddr;
1569 char errbuf[256];
1570 char buf[64];
1571
1572 sh_dummy_1564_str = (void*) &str;
1573
1574 if (iface_initialized == 0)
1575 {
1576 iface_list.used = 0;
1577 iface_initialized = 1;
1578 }
1579
1580 do {
1581
1582 while (*str == ',' || *str == ' ' || *str == '\t') ++str;
1583
1584 if (*str)
1585 {
1586 char ipbuf[SH_IP_BUF];
1587 unsigned int i = 0;
1588 while (*str && i < (sizeof(buf)-1) &&
1589 *str != ',' && *str != ' ' && *str != '\t')
1590 {
1591 buf[i] = *str; ++str; ++i;
1592 }
1593 buf[i] = '\0';
1594
1595 if (0 == sh_ipvx_aton(buf, &saddr))
1596 return -1;
1597
1598 if (iface_list.used == SH_IFACE_MAX)
1599 return -1;
1600
1601 sh_ipvx_ntoa(ipbuf, sizeof(ipbuf), &saddr);
1602 sl_snprintf(errbuf, sizeof(errbuf), _("interface: %s"), ipbuf);
1603 SH_MUTEX_LOCK(mutex_thread_nolog);
1604 sh_error_handle(SH_ERR_INFO, FIL__, __LINE__, 0, MSG_E_SUBGEN,
1605 errbuf, _("sh_portchk_add_interface"));
1606 SH_MUTEX_UNLOCK(mutex_thread_nolog);
1607
1608 memcpy (&(iface_list.iface[iface_list.used]), &(saddr), sizeof(saddr));
1609 ++iface_list.used;
1610 }
1611 } while (*str);
1612
1613 sh_dummy_1564_str = NULL;
1614 return 0;
1615}
1616
1617/* verify whether port/interface is blacklisted (do not check)
1618 */
1619static int sh_portchk_is_blacklisted(int port, struct sh_sockaddr * saddr,
1620 int proto)
1621{
1622 struct sh_port * head;
1623
1624 if (proto == IPPROTO_TCP)
1625 head = blacklist_tcp;
1626 else
1627 head = blacklist_udp;
1628
1629 while (head)
1630 {
1631 if (head->port == port)
1632 {
1633 if (sh_ipvx_isany(head->paddr) ||
1634 0 == sh_ipvx_cmp(head->paddr, saddr))
1635 return 1;
1636 else
1637 return 0;
1638 }
1639 head = head->next;
1640 }
1641 return 0;
1642}
1643
1644
1645static int sh_portchk_blacklist(int port, struct sh_sockaddr * saddr, int proto)
1646{
1647 struct sh_port * black;
1648 struct sh_port * head;
1649
1650 if (proto == IPPROTO_TCP)
1651 head = blacklist_tcp;
1652 else
1653 head = blacklist_udp;
1654
1655 black = head;
1656
1657 while (black)
1658 {
1659 if (black->port == port &&
1660 0 == sh_ipvx_cmp(head->paddr, saddr))
1661 return -1;
1662 black = black->next;
1663 }
1664
1665 black = SH_ALLOC (sizeof(struct sh_port));
1666 black->paddr = SH_ALLOC (sizeof(struct sh_sockaddr));
1667 black->port = port;
1668 memcpy(black->paddr, saddr, sizeof(struct sh_sockaddr));
1669 black->next = head;
1670
1671 if (proto == IPPROTO_TCP)
1672 blacklist_tcp = black;
1673 else
1674 blacklist_udp = black;
1675
1676 if (portchk_debug)
1677 {
1678 int checkit = sh_portchk_is_blacklisted(port, saddr, proto);
1679 fprintf(stderr, _("port blacklisted: %d %s\n"), port,
1680 (checkit == 1) ? _("ok") : _("fail"));
1681 }
1682 return 0;
1683}
1684
1685
1686/* Subroutine to add a required or optional port/service
1687 */
1688static int sh_portchk_add_required_port_generic (char * service,
1689 char * interface, int type)
1690{
1691 char buf[256] = { '\0' };
1692 int proto;
1693 char * p;
1694 char * endptr;
1695 unsigned long int port;
1696 struct sh_sockaddr saddr;
1697 struct sh_portentry * portent;
1698
1699 if (0 == sh_ipvx_aton(interface, &saddr))
1700 return -1;
1701
1702 sl_strlcpy (buf, service, sizeof(buf));
1703
1704 p = strchr(buf, '/');
1705 if (!p)
1706 return -1;
1707 if (0 == strcmp(p, _("/tcp")))
1708 proto = IPPROTO_TCP;
1709 else if (0 == strcmp(p, _("/udp")))
1710 proto = IPPROTO_UDP;
1711 else
1712 return -1;
1713
1714 *p = '\0';
1715 port = strtoul(buf, &endptr, 0);
1716
1717 if (portchk_debug)
1718 {
1719 char buf[SH_IP_BUF];
1720 sh_ipvx_ntoa(buf, sizeof(buf), &saddr);
1721 fprintf(stderr, _("add_port_generic: %s (%s) %d %s (%s)\n"),
1722 interface, buf, (int) port, (proto == IPPROTO_TCP) ? _("tcp") : _("udp"),
1723 sh_port_type2str(type));
1724 }
1725
1726 /* Blacklisted ports
1727 */
1728 if (*endptr == '\0' && port <= 65535 && type == SH_PORT_BLACKLIST)
1729 return (sh_portchk_blacklist(port, &saddr, proto));
1730
1731 if (*endptr != '\0')
1732 {
1733 portent = sh_portchk_get_from_list (proto, -1, &saddr, buf);
1734 if (!portent)
1735 {
1736 if (portchk_debug)
1737 fprintf(stderr, _("add_required_port %d\n"), (int) port);
1738 sh_portchk_add_to_list (proto, -1, &saddr, buf, type, SH_PORT_UNKN);
1739 }
1740 else
1741 {
1742#ifdef TEST_ONLY
1743 fprintf(stderr, "** WARNING: duplicate port definition %s/%s\n", buf, SH_PROTO_STR(proto));
1744#else
1745 SH_MUTEX_LOCK(mutex_thread_nolog);
1746 sh_error_handle(SH_ERR_ERR, FIL__, __LINE__, 0, MSG_E_SUBGEN,
1747 _("duplicate port definition"), _("sh_portchk_add_required_port_generic"));
1748 SH_MUTEX_UNLOCK(mutex_thread_nolog);
1749#endif
1750 return -1;
1751 }
1752 }
1753 else if (port <= 65535)
1754 {
1755 portent = sh_portchk_get_from_list (proto, port, &saddr, NULL);
1756 if (!portent)
1757 {
1758 if (portchk_debug)
1759 fprintf(stderr, _("add_required_port: open port: %d/%s\n"),
1760 (int) port, SH_PROTO_STR(proto));
1761 sh_portchk_add_to_list (proto, port, &saddr, NULL, type, SH_PORT_UNKN);
1762 }
1763 else
1764 {
1765#ifdef TEST_ONLY
1766 fprintf(stderr, "** WARNING: duplicate port definition %lu/%s\n", port, SH_PROTO_STR(proto));
1767#else
1768 SH_MUTEX_LOCK(mutex_thread_nolog);
1769 sh_error_handle(SH_ERR_ERR, FIL__, __LINE__, 0, MSG_E_SUBGEN,
1770 _("duplicate port definition"), _("sh_portchk_add_required_port_generic"));
1771 SH_MUTEX_UNLOCK(mutex_thread_nolog);
1772#endif
1773 return -1;
1774 }
1775 }
1776 else
1777 return -1;
1778
1779 return 0;
1780}
1781
1782/* Internal interface to add required or optional ports as 'iface:portlist'
1783 */
1784static int sh_portchk_add_required_generic (const char * str, int type)
1785{
1786 size_t ll = 0;
1787 int status;
1788
1789 char * interface = NULL;
1790 char * list;
1791 char * p;
1792#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_STRTOK_R)
1793 char * saveptr;
1794#endif
1795
1796 if (!str)
1797 return -1;
1798
1799 if (strchr(str, ':'))
1800 {
1801 char *last = strrchr(str, ':');
1802 if (last != NULL)
1803 {
1804 size_t tolast = (last - str);
1805 interface = SH_ALLOC(tolast+1);
1806 sl_strlcpy(interface, str, tolast+1);
1807 interface[tolast] = '\0';
1808
1809 ll = tolast;
1810
1811 while (str[ll] == ':' || str[ll] == ' ' || str[ll] == '\t')
1812 ++ll;
1813 }
1814 }
1815 else
1816 {
1817 interface = SH_ALLOC(8);
1818 sl_strlcpy(interface, _("0.0.0.0"), 8);
1819 interface[7] = '\0';
1820 while (str[ll] == ' ' || str[ll] == '\t')
1821 ++ll;
1822 }
1823
1824 if (!interface)
1825 return -1;
1826
1827 if (str[ll] == '\0')
1828 {
1829 SH_FREE(interface);
1830 return -1;
1831 }
1832
1833 if (portchk_debug)
1834 fprintf(stderr, "add ports for interface: %s (%s)\n", interface, sh_port_type2str(type));
1835
1836 list = sh_util_strdup(&str[ll]);
1837#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_STRTOK_R)
1838 p = strtok_r (list, " ,\t", &saveptr);
1839#else
1840 p = strtok (list, " ,\t");
1841#endif
1842 if (!p)
1843 {
1844 SH_FREE(interface);
1845 SH_FREE(list);
1846 return -1;
1847 }
1848 while (p)
1849 {
1850 status = sh_portchk_add_required_port_generic (p, interface, type);
1851
1852 if (-1 == status)
1853 {
1854 SH_FREE(interface);
1855 SH_FREE(list);
1856 return -1;
1857 }
1858#if defined(HAVE_PTHREAD) && defined (_POSIX_THREAD_SAFE_FUNCTIONS) && defined(HAVE_STRTOK_R)
1859 p = strtok_r (NULL, " ,\t", &saveptr);
1860#else
1861 p = strtok (NULL, " ,\t");
1862#endif
1863 }
1864 SH_FREE(interface);
1865 SH_FREE(list);
1866 return 0;
1867}
1868
1869/* User interface to add required ports as 'iface:portlist'
1870 */
1871static int sh_portchk_add_required (const char * str)
1872{
1873 return sh_portchk_add_required_generic (str, SH_PORT_REQ);
1874}
1875
1876/* User interface to add optional ports as 'iface:portlist'
1877 */
1878static int sh_portchk_add_optional (const char * str)
1879{
1880 return sh_portchk_add_required_generic (str, SH_PORT_OPT);
1881}
1882
1883/* User interface to add ignoreable ports as 'iface:portlist'
1884 */
1885static int sh_portchk_add_ignore (const char * str)
1886{
1887 return sh_portchk_add_required_generic (str, SH_PORT_IGN);
1888}
1889
1890/* User interface to add ports that should not be checked as 'iface:portlist'
1891 */
1892static int sh_portchk_add_blacklist (const char * str)
1893{
1894 return sh_portchk_add_required_generic (str, SH_PORT_BLACKLIST);
1895}
1896
1897/* Interface to run port check
1898 */
1899int sh_portchk_check ()
1900{
1901 volatile int min_port;
1902 static int noprivports = 0;
1903
1904 SH_MUTEX_LOCK(mutex_port_check);
1905
1906 min_port = (sh_portchk_minport == -1) ? 0 : sh_portchk_minport;
1907
1908 if (sh_portchk_active != S_FALSE)
1909 {
1910 SH_MUTEX_LOCK(mutex_thread_nolog);
1911 sh_error_handle(SH_ERR_INFO, FIL__, __LINE__, 0, MSG_E_SUBGEN,
1912 _("Checking for open ports"),
1913 _("sh_portchk_check"));
1914 SH_MUTEX_UNLOCK(mutex_thread_nolog);
1915
1916 sh_portchk_reset_lists();
1917 if ((0 != geteuid()) && (min_port < 1024))
1918 {
1919 min_port = 1024;
1920 if (noprivports == 0)
1921 {
1922#ifdef TEST_ONLY
1923 fprintf(stderr, "** WARNING not scanning ports < 1024\n");
1924#else
1925 SH_MUTEX_LOCK(mutex_thread_nolog);
1926 sh_error_handle(SH_ERR_ERR, FIL__, __LINE__, 0, MSG_E_SUBGEN,
1927 _("not scanning ports below 1024"),
1928 _("sh_portchk_check"));
1929 SH_MUTEX_UNLOCK(mutex_thread_nolog);
1930#endif
1931 noprivports = 1;
1932 }
1933 }
1934
1935 sh_port2proc_prepare();
1936
1937 if (sh_portchk_check_udp == 1)
1938 sh_portchk_scan_ports_udp(min_port, sh_portchk_maxport);
1939 sh_portchk_scan_ports_tcp(min_port, sh_portchk_maxport);
1940
1941
1942 sh_portchk_check_list (&portlist_tcp, IPPROTO_TCP, SH_PORT_REPORT);
1943 if (sh_portchk_check_udp == 1)
1944 sh_portchk_check_list (&portlist_udp, IPPROTO_UDP, SH_PORT_REPORT);
1945
1946 }
1947 SH_MUTEX_UNLOCK(mutex_port_check);
1948 return 0;
1949}
1950#endif
1951
1952#ifdef SH_CUTEST
1953#include "CuTest.h"
1954
1955void Test_portcheck_lists (CuTest *tc)
1956{
1957#if defined(SH_USE_PORTCHECK) && (defined(SH_WITH_CLIENT) || defined(SH_STANDALONE))
1958 struct sh_sockaddr haddr_local;
1959 struct sh_portentry * portent;
1960 char buf[256];
1961 char * p;
1962
1963#ifdef HAVE_RPC_RPC_H
1964 p = sh_getrpcbynumber(0, buf, sizeof(buf));
1965 CuAssertTrue(tc, p == NULL);
1966
1967 p = sh_getrpcbynumber(100000, buf, sizeof(buf));
1968 CuAssertPtrNotNull(tc, p);
1969 CuAssertTrue(tc, (0 == strcmp(p, "portmapper") || 0 == strcmp(p, "rpcbind")));
1970 CuAssertTrue(tc, (0 == strcmp(buf, "portmapper") || 0 == strcmp(p, "rpcbind")));
1971
1972 p = sh_getrpcbynumber(100007, buf, sizeof(buf));
1973 CuAssertPtrNotNull(tc, p);
1974 CuAssertTrue(tc, 0 == strcmp(p, "ypbind"));
1975 CuAssertTrue(tc, 0 == strcmp(buf, "ypbind"));
1976#endif
1977
1978 p = sh_getservbyport(0, SH_PROTO_STR(IPPROTO_UDP), buf, sizeof(buf));
1979 CuAssertTrue(tc, p == NULL);
1980
1981#if !defined(HOST_IS_CYGWIN)
1982 p = sh_getservbyport(22, SH_PROTO_STR(IPPROTO_TCP), buf, sizeof(buf));
1983 CuAssertPtrNotNull(tc, p);
1984 CuAssertTrue(tc, 0 == strcmp(p, "ssh"));
1985 CuAssertTrue(tc, 0 == strcmp(buf, "ssh"));
1986#endif
1987
1988 p = sh_getservbyport(13, SH_PROTO_STR(IPPROTO_UDP), buf, sizeof(buf));
1989 CuAssertPtrNotNull(tc, p);
1990 CuAssertTrue(tc, 0 == strcmp(p, "daytime"));
1991 CuAssertTrue(tc, 0 == strcmp(buf, "daytime"));
1992
1993 CuAssertTrue(tc, 0 != sh_ipvx_aton("127.0.0.1", &haddr_local));
1994
1995 sh_portchk_add_to_list (IPPROTO_TCP, 8000, &haddr_local, NULL, SH_PORT_NOT, SH_PORT_UNKN);
1996
1997 portent = sh_portchk_get_from_list(IPPROTO_TCP, 8000, &haddr_local, NULL);
1998 CuAssertPtrNotNull(tc, portent);
1999
2000 CuAssertTrue(tc, portent->port == 8000);
2001 CuAssertTrue(tc, 0 == strcmp("127.0.0.1", portent->interface));
2002 CuAssertTrue(tc, portent->status == SH_PORT_UNKN);
2003 CuAssertTrue(tc, portent->flag == SH_PORT_NOT);
2004
2005 sh_portchk_check_list (&portlist_tcp, IPPROTO_TCP, SH_PORT_NOREPT);
2006
2007 CuAssertTrue(tc, NULL == portlist_tcp);
2008
2009 sh_portchk_add_to_list (IPPROTO_TCP, 8000, &haddr_local, NULL, SH_PORT_REQ, SH_PORT_UNKN);
2010 sh_portchk_add_to_list (IPPROTO_TCP, 8001, &haddr_local, NULL, SH_PORT_NOT, SH_PORT_UNKN);
2011 sh_portchk_add_to_list (IPPROTO_TCP, 8002, &haddr_local, NULL, SH_PORT_REQ, SH_PORT_UNKN);
2012 sh_portchk_add_to_list (IPPROTO_TCP, 8003, &haddr_local, NULL, SH_PORT_NOT, SH_PORT_UNKN);
2013 sh_portchk_add_to_list (IPPROTO_TCP, 8004, &haddr_local, NULL, SH_PORT_IGN, SH_PORT_UNKN);
2014 sh_portchk_add_to_list (IPPROTO_TCP, -1, &haddr_local, "foo1", SH_PORT_NOT, SH_PORT_UNKN);
2015 sh_portchk_add_to_list (IPPROTO_TCP, -1, &haddr_local, "foo2", SH_PORT_REQ, SH_PORT_UNKN);
2016 sh_portchk_add_to_list (IPPROTO_TCP, -1, &haddr_local, "foo3", SH_PORT_NOT, SH_PORT_UNKN);
2017 sh_portchk_add_to_list (IPPROTO_TCP, -1, &haddr_local, "foo4", SH_PORT_REQ, SH_PORT_UNKN);
2018 sh_portchk_add_to_list (IPPROTO_TCP, -1, &haddr_local, "foo5", SH_PORT_IGN, SH_PORT_UNKN);
2019
2020 sh_portchk_check_list (&portlist_tcp, IPPROTO_TCP, SH_PORT_NOREPT);
2021
2022 CuAssertPtrNotNull(tc, portlist_tcp);
2023
2024 portent = sh_portchk_get_from_list(IPPROTO_TCP, 8000, &haddr_local, NULL);
2025 CuAssertPtrNotNull(tc, portent);
2026
2027 portent = sh_portchk_get_from_list(IPPROTO_TCP, 8001, &haddr_local, NULL);
2028 CuAssertTrue(tc, NULL == portent);
2029
2030 portent = sh_portchk_get_from_list(IPPROTO_TCP, 8002, &haddr_local, NULL);
2031 CuAssertPtrNotNull(tc, portent);
2032
2033 portent = sh_portchk_get_from_list(IPPROTO_TCP, 8003, &haddr_local, NULL);
2034 CuAssertTrue(tc, NULL == portent);
2035
2036 portent = sh_portchk_get_from_list(IPPROTO_TCP, 8004, &haddr_local, NULL);
2037 CuAssertPtrNotNull(tc, portent);
2038
2039 portent = sh_portchk_get_from_list(IPPROTO_TCP, 8000, &haddr_local, "foo1");
2040 CuAssertTrue(tc, NULL == portent);
2041
2042 portent = sh_portchk_get_from_list(IPPROTO_TCP, 8000, &haddr_local, "foo2");
2043 CuAssertPtrNotNull(tc, portent);
2044 CuAssertTrue(tc, 0 == strcmp(portent->service, "foo2"));
2045
2046 portent = sh_portchk_get_from_list(IPPROTO_TCP, 8000, &haddr_local, "foo3");
2047 CuAssertTrue(tc, NULL == portent);
2048
2049 portent = sh_portchk_get_from_list(IPPROTO_TCP, 8000, &haddr_local, "foo4");
2050 CuAssertPtrNotNull(tc, portent);
2051 CuAssertTrue(tc, 0 == strcmp(portent->service, "foo4"));
2052
2053 portent = sh_portchk_get_from_list(IPPROTO_TCP, 8000, &haddr_local, "foo5");
2054 CuAssertPtrNotNull(tc, portent);
2055 CuAssertTrue(tc, 0 == strcmp(portent->service, "foo5"));
2056
2057 CuAssertTrue(tc, 0 == sh_portchk_blacklist(666, &haddr_local, IPPROTO_TCP));
2058 CuAssertTrue(tc, 0 != sh_portchk_blacklist(666, &haddr_local, IPPROTO_TCP));
2059 CuAssertTrue(tc, 0 == sh_portchk_blacklist(667, &haddr_local, IPPROTO_TCP));
2060 CuAssertTrue(tc, 0 == sh_portchk_blacklist(668, &haddr_local, IPPROTO_TCP));
2061 CuAssertTrue(tc, 0 == sh_portchk_blacklist(666, &haddr_local, IPPROTO_UDP));
2062 CuAssertTrue(tc, 0 != sh_portchk_blacklist(666, &haddr_local, IPPROTO_UDP));
2063 CuAssertTrue(tc, 0 == sh_portchk_blacklist(667, &haddr_local, IPPROTO_UDP));
2064 CuAssertTrue(tc, 0 == sh_portchk_blacklist(668, &haddr_local, IPPROTO_UDP));
2065
2066 CuAssertTrue(tc, 0 != sh_portchk_is_blacklisted(668, &haddr_local, IPPROTO_UDP));
2067 CuAssertTrue(tc, 0 != sh_portchk_is_blacklisted(667, &haddr_local, IPPROTO_UDP));
2068 CuAssertTrue(tc, 0 != sh_portchk_is_blacklisted(666, &haddr_local, IPPROTO_UDP));
2069 CuAssertTrue(tc, 0 == sh_portchk_is_blacklisted(665, &haddr_local, IPPROTO_UDP));
2070
2071 CuAssertTrue(tc, 0 != sh_portchk_is_blacklisted(668, &haddr_local, IPPROTO_TCP));
2072 CuAssertTrue(tc, 0 != sh_portchk_is_blacklisted(667, &haddr_local, IPPROTO_TCP));
2073 CuAssertTrue(tc, 0 != sh_portchk_is_blacklisted(666, &haddr_local, IPPROTO_TCP));
2074 CuAssertTrue(tc, 0 == sh_portchk_is_blacklisted(665, &haddr_local, IPPROTO_TCP));
2075#else
2076 (void) tc; /* fix compiler warning */
2077#endif
2078 return;
2079}
2080#endif
2081
2082#ifdef TEST_ONLY
2083
2084void usage (char * pname)
2085{
2086 printf ("%s [-r|--required interface:portlist][-o|--optional interface:portlist][--no-udp][-d|--debug] hostname\n\n", pname);
2087 printf (" Check local host for open ports; Version %s\n\n", PORTCHK_VERSION);
2088 printf (" Interface: Numeric address for an interface, e.g. 127.0.0.1\n");
2089 printf (" Portlist: List of ports or services, e.g. 22/tcp,nfs/udp,nlockmgr/udp\n");
2090 printf (" required -> must be open\n");
2091 printf (" optional -> may be open or closed\n");
2092 printf (" RPC services must be specified with service **name**, others with **port number**\n\n");
2093 printf (" Example:\n");
2094 printf (" %s --required 192.168.1.2:22/tcp,nfs/udp,nlockmgr/udp\n\n", pname);
2095 return;
2096}
2097
2098int main(int argc, char *argv[])
2099{
2100 char * pname = argv[0];
2101
2102
2103 /*
2104 test_lists();
2105
2106 portlist_tcp = sh_portchk_kill_list (portlist_tcp);
2107 portlist_udp = sh_portchk_kill_list (portlist_udp);
2108 */
2109
2110 /* sh_portchk_add_required ("127.0.0.1 : nlockmgr/tcp, 5308/tcp, nfs/tcp"); */
2111
2112 while (argc > 1 && argv[1][0] == '-')
2113 {
2114 if (0 == strcmp(argv[1], "--help") || 0 == strcmp(argv[1], "-h"))
2115 {
2116 usage(pname);
2117 exit (0);
2118 }
2119 else if (0 == strcmp(argv[1], "--required") || 0 == strcmp(argv[1], "-r"))
2120 {
2121 if (argc < 3)
2122 {
2123 usage(pname);
2124 exit (1);
2125 }
2126 sh_portchk_add_required (argv[2]);
2127 --argc; ++argv;
2128 }
2129 else if (0 == strcmp(argv[1], "--optional") || 0 == strcmp(argv[1], "-o"))
2130 {
2131 if (argc < 3)
2132 {
2133 usage(pname);
2134 exit (1);
2135 }
2136 sh_portchk_add_optional (argv[2]);
2137 --argc; ++argv;
2138 }
2139 else if (0 == strcmp(argv[1], "--no-udp"))
2140 {
2141 sh_portchk_check_udp = 0;
2142 }
2143 else if (0 == strcmp(argv[1], "--debug") || 0 == strcmp(argv[1], "-d"))
2144 {
2145 portchk_debug = 1;
2146 }
2147 else
2148 {
2149 usage(pname);
2150 exit (1);
2151 }
2152 --argc; ++argv;
2153 }
2154
2155 if (argc < 2)
2156 {
2157 usage(pname);
2158 exit (1);
2159 }
2160
2161 portchk_hostname = argv[1];
2162
2163 if (0 != sh_portchk_init ())
2164 {
2165 usage(pname);
2166 exit (1);
2167 }
2168
2169 sh_portchk_check();
2170
2171 return 0;
2172}
2173#endif
Note: See TracBrowser for help on using the repository browser.