inetd.c (56482) | inetd.c (56590) |
---|---|
1/* 2 * Copyright (c) 1983, 1991, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 28 unchanged lines hidden (view full) --- 37 The Regents of the University of California. All rights reserved.\n"; 38#endif /* not lint */ 39 40#ifndef lint 41#if 0 42static char sccsid[] = "@(#)from: inetd.c 8.4 (Berkeley) 4/13/94"; 43#endif 44static const char rcsid[] = | 1/* 2 * Copyright (c) 1983, 1991, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 28 unchanged lines hidden (view full) --- 37 The Regents of the University of California. All rights reserved.\n"; 38#endif /* not lint */ 39 40#ifndef lint 41#if 0 42static char sccsid[] = "@(#)from: inetd.c 8.4 (Berkeley) 4/13/94"; 43#endif 44static const char rcsid[] = |
45 "$FreeBSD: head/usr.sbin/inetd/inetd.c 56482 2000-01-23 20:17:41Z charnier $"; | 45 "$FreeBSD: head/usr.sbin/inetd/inetd.c 56590 2000-01-25 14:52:10Z shin $"; |
46#endif /* not lint */ 47 48/* 49 * Inetd - Internet super-server 50 * 51 * This program invokes all internet services as needed. Connection-oriented 52 * services are invoked each time a connection is made, by creating a process. 53 * This process is passed the connection as file descriptor 0 and is expected --- 43 unchanged lines hidden (view full) --- 97 * socket type stream/dgram/raw/rdm/seqpacket 98 * protocol must be in /etc/protocols 99 * wait/nowait single-threaded/multi-threaded 100 * user user to run daemon as 101 * server program full path name 102 * server program arguments maximum of MAXARGS 103 * 104 * Comment lines are indicated by a `#' in column 1. | 46#endif /* not lint */ 47 48/* 49 * Inetd - Internet super-server 50 * 51 * This program invokes all internet services as needed. Connection-oriented 52 * services are invoked each time a connection is made, by creating a process. 53 * This process is passed the connection as file descriptor 0 and is expected --- 43 unchanged lines hidden (view full) --- 97 * socket type stream/dgram/raw/rdm/seqpacket 98 * protocol must be in /etc/protocols 99 * wait/nowait single-threaded/multi-threaded 100 * user user to run daemon as 101 * server program full path name 102 * server program arguments maximum of MAXARGS 103 * 104 * Comment lines are indicated by a `#' in column 1. |
105 * 106 * #ifdef IPSEC 107 * Comment lines that start with "#@" denote IPsec policy string, as described 108 * in ipsec_set_policy(3). This will affect all the following items in 109 * inetd.conf(8). To reset the policy, just use "#@" line. By default, 110 * there's no IPsec policy. 111 * #endif |
|
105 */ 106#include <sys/param.h> 107#include <sys/ioctl.h> 108#include <sys/wait.h> 109#include <sys/time.h> 110#include <sys/resource.h> 111 112#include <netinet/in.h> --- 12 unchanged lines hidden (view full) --- 125#include <stdio.h> 126#include <stdlib.h> 127#include <string.h> 128#include <syslog.h> 129#include <tcpd.h> 130#include <unistd.h> 131#include <libutil.h> 132#include <sysexits.h> | 112 */ 113#include <sys/param.h> 114#include <sys/ioctl.h> 115#include <sys/wait.h> 116#include <sys/time.h> 117#include <sys/resource.h> 118 119#include <netinet/in.h> --- 12 unchanged lines hidden (view full) --- 132#include <stdio.h> 133#include <stdlib.h> 134#include <string.h> 135#include <syslog.h> 136#include <tcpd.h> 137#include <unistd.h> 138#include <libutil.h> 139#include <sysexits.h> |
140#include <ctype.h> |
|
133 134#include "inetd.h" 135#include "pathnames.h" 136 | 141 142#include "inetd.h" 143#include "pathnames.h" 144 |
145#ifdef IPSEC 146#include <netinet6/ipsec.h> 147#ifndef IPSEC_POLICY_IPSEC /* no ipsec support on old ipsec */ 148#undef IPSEC 149#endif 150#endif 151 152/* wrapper for KAME-special getnameinfo() */ 153#ifndef NI_WITHSCOPEID 154#define NI_WITHSCOPEID 0 155#endif 156 |
|
137#ifndef LIBWRAP_ALLOW_FACILITY 138# define LIBWRAP_ALLOW_FACILITY LOG_AUTH 139#endif 140#ifndef LIBWRAP_ALLOW_SEVERITY 141# define LIBWRAP_ALLOW_SEVERITY LOG_INFO 142#endif 143#ifndef LIBWRAP_DENY_FACILITY 144# define LIBWRAP_DENY_FACILITY LOG_AUTH --- 43 unchanged lines hidden (view full) --- 188fd_set allsock; 189int options; 190int timingout; 191int toomany = TOOMANY; 192int maxchild = MAXCHILD; 193int maxcpm = MAXCPM; 194struct servent *sp; 195struct rpcent *rpc; | 157#ifndef LIBWRAP_ALLOW_FACILITY 158# define LIBWRAP_ALLOW_FACILITY LOG_AUTH 159#endif 160#ifndef LIBWRAP_ALLOW_SEVERITY 161# define LIBWRAP_ALLOW_SEVERITY LOG_INFO 162#endif 163#ifndef LIBWRAP_DENY_FACILITY 164# define LIBWRAP_DENY_FACILITY LOG_AUTH --- 43 unchanged lines hidden (view full) --- 208fd_set allsock; 209int options; 210int timingout; 211int toomany = TOOMANY; 212int maxchild = MAXCHILD; 213int maxcpm = MAXCPM; 214struct servent *sp; 215struct rpcent *rpc; |
196struct in_addr bind_address; | 216char *hostname = NULL; 217struct sockaddr_in *bind_sa4; 218int no_v4bind = 1; 219#ifdef INET6 220struct sockaddr_in6 *bind_sa6; 221int no_v6bind = 1; 222#endif |
197int signalpipe[2]; 198#ifdef SANITY_CHECK 199int nsock; 200#endif 201 202struct servtab *servtab; 203 204extern struct biltin biltins[]; --- 38 unchanged lines hidden (view full) --- 243 char buf[50]; 244#ifdef LOGIN_CAP 245 login_cap_t *lc = NULL; 246#endif 247 struct request_info req; 248 int denied; 249 char *service = NULL; 250 char *pnm; | 223int signalpipe[2]; 224#ifdef SANITY_CHECK 225int nsock; 226#endif 227 228struct servtab *servtab; 229 230extern struct biltin biltins[]; --- 38 unchanged lines hidden (view full) --- 269 char buf[50]; 270#ifdef LOGIN_CAP 271 login_cap_t *lc = NULL; 272#endif 273 struct request_info req; 274 int denied; 275 char *service = NULL; 276 char *pnm; |
251 struct sockaddr_in peer; | 277 union { 278 struct sockaddr peer_un; 279 struct sockaddr_in peer_un4; 280 struct sockaddr_in6 peer_un6; 281 struct sockaddr_storage peer_max; 282 } p_un; 283#define peer p_un.peer_un 284#define peer4 p_un.peer_un4 285#define peer6 p_un.peer_un6 286#define peermax p_un.peer_max |
252 int i; | 287 int i; |
288 struct addrinfo hints, *res; 289 char *servname; 290 int error; |
|
253 254 255#ifdef OLD_SETPROCTITLE 256 Argv = argv; 257 if (envp == 0 || *envp == 0) 258 envp = argv; 259 while (*envp) 260 envp++; 261 LastArg = envp[-1] + strlen(envp[-1]); 262#endif 263 264 openlog("inetd", LOG_PID | LOG_NOWAIT, LOG_DAEMON); 265 | 291 292 293#ifdef OLD_SETPROCTITLE 294 Argv = argv; 295 if (envp == 0 || *envp == 0) 296 envp = argv; 297 while (*envp) 298 envp++; 299 LastArg = envp[-1] + strlen(envp[-1]); 300#endif 301 302 openlog("inetd", LOG_PID | LOG_NOWAIT, LOG_DAEMON); 303 |
266 bind_address.s_addr = htonl(INADDR_ANY); | |
267 while ((ch = getopt(argc, argv, "dlwWR:a:c:C:p:")) != -1) 268 switch(ch) { 269 case 'd': 270 debug = 1; 271 options |= SO_DEBUG; 272 break; 273 case 'l': 274 log = 1; --- 6 unchanged lines hidden (view full) --- 281 getvalue(optarg, &maxchild, 282 "-c %s: bad value for maximum children"); 283 break; 284 case 'C': 285 getvalue(optarg, &maxcpm, 286 "-C %s: bad value for maximum children/minute"); 287 break; 288 case 'a': | 304 while ((ch = getopt(argc, argv, "dlwWR:a:c:C:p:")) != -1) 305 switch(ch) { 306 case 'd': 307 debug = 1; 308 options |= SO_DEBUG; 309 break; 310 case 'l': 311 log = 1; --- 6 unchanged lines hidden (view full) --- 318 getvalue(optarg, &maxchild, 319 "-c %s: bad value for maximum children"); 320 break; 321 case 'C': 322 getvalue(optarg, &maxcpm, 323 "-C %s: bad value for maximum children/minute"); 324 break; 325 case 'a': |
289 if (!inet_aton(optarg, &bind_address)) { 290 syslog(LOG_ERR, 291 "-a %s: invalid IP address", optarg); 292 exit(EX_USAGE); 293 } | 326 hostname = optarg; |
294 break; 295 case 'p': 296 pid_file = optarg; 297 break; 298 case 'w': 299 wrap_ex++; 300 break; 301 case 'W': 302 wrap_bi++; 303 break; 304 case '?': 305 default: 306 syslog(LOG_ERR, 307 "usage: inetd [-dlwW] [-a address] [-R rate]" 308 " [-c maximum] [-C rate]" 309 " [-p pidfile] [conf-file]"); 310 exit(EX_USAGE); 311 } | 327 break; 328 case 'p': 329 pid_file = optarg; 330 break; 331 case 'w': 332 wrap_ex++; 333 break; 334 case 'W': 335 wrap_bi++; 336 break; 337 case '?': 338 default: 339 syslog(LOG_ERR, 340 "usage: inetd [-dlwW] [-a address] [-R rate]" 341 " [-c maximum] [-C rate]" 342 " [-p pidfile] [conf-file]"); 343 exit(EX_USAGE); 344 } |
345 /* 346 * Initialize Bind Addrs. 347 * When hostname is NULL, wild card bind addrs are obtained from 348 * getaddrinfo(). But getaddrinfo() requires at least one of 349 * hostname or servname is non NULL. 350 * So when hostname is NULL, set dummy value to servname. 351 */ 352 servname = (hostname == NULL) ? "discard" /* dummy */ : NULL; 353 354 bzero(&hints, sizeof(struct addrinfo)); 355 hints.ai_flags = AI_PASSIVE; 356 hints.ai_family = AF_UNSPEC; 357 error = getaddrinfo(hostname, servname, &hints, &res); 358 if (error != 0) { 359 syslog(LOG_ERR, "-a %s: %s", hostname, gai_strerror(error)); 360 if (error == EAI_SYSTEM) 361 syslog(LOG_ERR, "%s", strerror(errno)); 362 exit(EX_USAGE); 363 } 364 do { 365 if (res->ai_addr == NULL) { 366 syslog(LOG_ERR, "-a %s: getaddrinfo failed", hostname); 367 exit(EX_USAGE); 368 } 369 switch (res->ai_addr->sa_family) { 370 case AF_INET: 371 if (no_v4bind == 0) 372 continue; 373 bind_sa4 = (struct sockaddr_in *)res->ai_addr; 374 /* init port num in case servname is dummy */ 375 bind_sa4->sin_port = 0; 376 no_v4bind = 0; 377 continue; 378#ifdef INET6 379 case AF_INET6: 380 if (no_v6bind == 0) 381 continue; 382 bind_sa6 = (struct sockaddr_in6 *)res->ai_addr; 383 /* init port num in case servname is dummy */ 384 bind_sa6->sin6_port = 0; 385 no_v6bind = 0; 386 continue; 387#endif 388 } 389 if (no_v4bind == 0 390#ifdef INET6 391 && no_v6bind == 0 392#endif 393 ) 394 break; 395 } while ((res = res->ai_next) != NULL); 396 if (no_v4bind != 0 397#ifdef INET6 398 && no_v6bind != 0 399#endif 400 ) { 401 syslog(LOG_ERR, "-a %s: unknown address family", hostname); 402 exit(EX_USAGE); 403 } 404 |
|
312 argc -= optind; 313 argv += optind; 314 315 if (argc > 0) 316 CONFIG = argv[0]; 317 if (debug == 0) { 318 FILE *fp; 319 if (daemon(0, 0) < 0) { --- 132 unchanged lines hidden (view full) --- 452 syslog(LOG_ERR, "ioctl2(FIONBIO, 0): %m"); 453 if (cpmip(sep, ctrl) < 0) { 454 close(ctrl); 455 continue; 456 } 457 } else 458 ctrl = sep->se_fd; 459 if (log && !ISWRAP(sep)) { | 405 argc -= optind; 406 argv += optind; 407 408 if (argc > 0) 409 CONFIG = argv[0]; 410 if (debug == 0) { 411 FILE *fp; 412 if (daemon(0, 0) < 0) { --- 132 unchanged lines hidden (view full) --- 545 syslog(LOG_ERR, "ioctl2(FIONBIO, 0): %m"); 546 if (cpmip(sep, ctrl) < 0) { 547 close(ctrl); 548 continue; 549 } 550 } else 551 ctrl = sep->se_fd; 552 if (log && !ISWRAP(sep)) { |
553 char pname[INET6_ADDRSTRLEN]; |
|
460 pnm = "unknown"; | 554 pnm = "unknown"; |
461 i = sizeof peer; | 555 i = sizeof peermax; |
462 if (getpeername(ctrl, (struct sockaddr *) | 556 if (getpeername(ctrl, (struct sockaddr *) |
463 &peer, &i)) { 464 i = sizeof peer; | 557 &peermax, &i)) { 558 i = sizeof peermax; |
465 if (recvfrom(ctrl, buf, sizeof(buf), 466 MSG_PEEK, | 559 if (recvfrom(ctrl, buf, sizeof(buf), 560 MSG_PEEK, |
467 (struct sockaddr *)&peer, &i) >= 0) 468 pnm = inet_ntoa(peer.sin_addr); | 561 (struct sockaddr *)&peermax, 562 &i) >= 0) { 563 getnameinfo((struct sockaddr *)&peermax, 564 sizeof(peermax), 565 pname, sizeof(pname), 566 NULL, 0, 567 NI_NUMERICHOST| 568 NI_WITHSCOPEID); 569 pnm = pname; 570 } 571 } else { 572 getnameinfo((struct sockaddr *)&peermax, 573 sizeof(peermax), 574 pname, sizeof(pname), 575 NULL, 0, 576 NI_NUMERICHOST| 577 NI_WITHSCOPEID); 578 pnm = pname; |
469 } | 579 } |
470 else 471 pnm = inet_ntoa(peer.sin_addr); | |
472 syslog(LOG_INFO,"%s from %s", sep->se_service, pnm); 473 } 474 (void) sigblock(SIGBLOCK); 475 pid = 0; 476 /* 477 * Fork for all external services, builtins which need to 478 * fork and anything we're wrapping (as wrapping might 479 * block or use hosts_options(5) twist). --- 298 unchanged lines hidden (view full) --- 778 syslog(LOG_ERR, 779 "%s/%s: %s: login class error, service ignored", 780 new->se_service, new->se_proto, new->se_class); 781 continue; 782 } 783#endif 784 for (sep = servtab; sep; sep = sep->se_next) 785 if (strcmp(sep->se_service, new->se_service) == 0 && | 580 syslog(LOG_INFO,"%s from %s", sep->se_service, pnm); 581 } 582 (void) sigblock(SIGBLOCK); 583 pid = 0; 584 /* 585 * Fork for all external services, builtins which need to 586 * fork and anything we're wrapping (as wrapping might 587 * block or use hosts_options(5) twist). --- 298 unchanged lines hidden (view full) --- 886 syslog(LOG_ERR, 887 "%s/%s: %s: login class error, service ignored", 888 new->se_service, new->se_proto, new->se_class); 889 continue; 890 } 891#endif 892 for (sep = servtab; sep; sep = sep->se_next) 893 if (strcmp(sep->se_service, new->se_service) == 0 && |
786 strcmp(sep->se_proto, new->se_proto) == 0) | 894 strcmp(sep->se_proto, new->se_proto) == 0 && 895 sep->se_family == new->se_family) |
787 break; 788 if (sep != 0) { 789 int i; 790 791#define SWAP(a, b) { typeof(a) c = a; a = b; b = c; } 792 omask = sigblock(SIGBLOCK); | 896 break; 897 if (sep != 0) { 898 int i; 899 900#define SWAP(a, b) { typeof(a) c = a; a = b; b = c; } 901 omask = sigblock(SIGBLOCK); |
902 if (sep->se_nomapped != new->se_nomapped) { 903 sep->se_nomapped = new->se_nomapped; 904 sep->se_reset = 1; 905 } |
|
793 /* copy over outstanding child pids */ 794 if (sep->se_maxchild && new->se_maxchild) { 795 new->se_numchild = sep->se_numchild; 796 if (new->se_numchild > new->se_maxchild) 797 new->se_numchild = new->se_maxchild; 798 memcpy(new->se_pids, sep->se_pids, 799 new->se_numchild * sizeof(*new->se_pids)); 800 } --- 17 unchanged lines hidden (view full) --- 818 SWAP(sep->se_group, new->se_group); 819#ifdef LOGIN_CAP 820 SWAP(sep->se_class, new->se_class); 821#endif 822 SWAP(sep->se_server, new->se_server); 823 SWAP(sep->se_server_name, new->se_server_name); 824 for (i = 0; i < MAXARGV; i++) 825 SWAP(sep->se_argv[i], new->se_argv[i]); | 906 /* copy over outstanding child pids */ 907 if (sep->se_maxchild && new->se_maxchild) { 908 new->se_numchild = sep->se_numchild; 909 if (new->se_numchild > new->se_maxchild) 910 new->se_numchild = new->se_maxchild; 911 memcpy(new->se_pids, sep->se_pids, 912 new->se_numchild * sizeof(*new->se_pids)); 913 } --- 17 unchanged lines hidden (view full) --- 931 SWAP(sep->se_group, new->se_group); 932#ifdef LOGIN_CAP 933 SWAP(sep->se_class, new->se_class); 934#endif 935 SWAP(sep->se_server, new->se_server); 936 SWAP(sep->se_server_name, new->se_server_name); 937 for (i = 0; i < MAXARGV; i++) 938 SWAP(sep->se_argv[i], new->se_argv[i]); |
939#ifdef IPSEC 940 SWAP(sep->se_policy, new->se_policy); 941 ipsecsetup(sep); 942#endif |
|
826 sigsetmask(omask); 827 freeconfig(new); 828 if (debug) 829 print_service("REDO", sep); 830 } else { 831 sep = enter(new); 832 if (debug) 833 print_service("ADD ", sep); 834 } 835 sep->se_checked = 1; 836 if (ISMUX(sep)) { 837 sep->se_fd = -1; 838 continue; 839 } | 943 sigsetmask(omask); 944 freeconfig(new); 945 if (debug) 946 print_service("REDO", sep); 947 } else { 948 sep = enter(new); 949 if (debug) 950 print_service("ADD ", sep); 951 } 952 sep->se_checked = 1; 953 if (ISMUX(sep)) { 954 sep->se_fd = -1; 955 continue; 956 } |
957 switch (sep->se_family) { 958 case AF_INET: 959 if (no_v4bind != 0) { 960 sep->se_fd = -1; 961 continue; 962 } 963 break; 964#ifdef INET6 965 case AF_INET6: 966 if (no_v6bind != 0) { 967 sep->se_fd = -1; 968 continue; 969 } 970 break; 971#endif 972 } |
|
840 if (!sep->se_rpc) { 841 sp = getservbyname(sep->se_service, sep->se_proto); 842 if (sp == 0) { 843 syslog(LOG_ERR, "%s/%s: unknown service", | 973 if (!sep->se_rpc) { 974 sp = getservbyname(sep->se_service, sep->se_proto); 975 if (sp == 0) { 976 syslog(LOG_ERR, "%s/%s: unknown service", |
844 sep->se_service, sep->se_proto); | 977 sep->se_service, sep->se_proto); |
845 sep->se_checked = 0; 846 continue; 847 } | 978 sep->se_checked = 0; 979 continue; 980 } |
848 if (sp->s_port != sep->se_ctrladdr.sin_port) { 849 sep->se_ctrladdr.sin_family = AF_INET; 850 sep->se_ctrladdr.sin_addr = bind_address; 851 sep->se_ctrladdr.sin_port = sp->s_port; 852 if (sep->se_fd >= 0) 853 close_sep(sep); | 981 switch (sep->se_family) { 982 case AF_INET: 983 if (sep->se_ctladdrinitok == 0) { 984 memcpy(&sep->se_ctrladdr4, bind_sa4, 985 sizeof(sep->se_ctrladdr4)); 986 sep->se_ctrladdr_size = 987 sizeof(sep->se_ctrladdr4); 988 } 989 if (sp->s_port != sep->se_ctrladdr4.sin_port) { 990 sep->se_ctrladdr4.sin_port = 991 sp->s_port; 992 sep->se_reset = 1; 993 } 994 break; 995#ifdef INET6 996 case AF_INET6: 997 if (sep->se_ctladdrinitok == 0) { 998 memcpy(&sep->se_ctrladdr6, bind_sa6, 999 sizeof(sep->se_ctrladdr6)); 1000 sep->se_ctrladdr_size = 1001 sizeof(sep->se_ctrladdr6); 1002 } 1003 if (sp->s_port != 1004 sep->se_ctrladdr6.sin6_port) { 1005 sep->se_ctrladdr6.sin6_port = 1006 sp->s_port; 1007 sep->se_reset = 1; 1008 } 1009 break; 1010#endif |
854 } | 1011 } |
1012 if (sep->se_reset != 0 && sep->se_fd >= 0) 1013 close_sep(sep); |
|
855 } else { 856 rpc = getrpcbyname(sep->se_service); 857 if (rpc == 0) { 858 syslog(LOG_ERR, "%s/%s unknown RPC service", 859 sep->se_service, sep->se_proto); 860 if (sep->se_fd != -1) 861 (void) close(sep->se_fd); 862 sep->se_fd = -1; --- 82 unchanged lines hidden (view full) --- 945} 946 947void 948setup(sep) 949 struct servtab *sep; 950{ 951 int on = 1; 952 | 1014 } else { 1015 rpc = getrpcbyname(sep->se_service); 1016 if (rpc == 0) { 1017 syslog(LOG_ERR, "%s/%s unknown RPC service", 1018 sep->se_service, sep->se_proto); 1019 if (sep->se_fd != -1) 1020 (void) close(sep->se_fd); 1021 sep->se_fd = -1; --- 82 unchanged lines hidden (view full) --- 1104} 1105 1106void 1107setup(sep) 1108 struct servtab *sep; 1109{ 1110 int on = 1; 1111 |
953 if ((sep->se_fd = socket(AF_INET, sep->se_socktype, 0)) < 0) { | 1112 if ((sep->se_fd = socket(sep->se_family, sep->se_socktype, 0)) < 0) { |
954 if (debug) 955 warn("socket failed on %s/%s", 956 sep->se_service, sep->se_proto); 957 syslog(LOG_ERR, "%s/%s: socket: %m", 958 sep->se_service, sep->se_proto); 959 return; 960 } 961#define turnon(fd, opt) \ 962setsockopt(fd, SOL_SOCKET, opt, (char *)&on, sizeof (on)) 963 if (strcmp(sep->se_proto, "tcp") == 0 && (options & SO_DEBUG) && 964 turnon(sep->se_fd, SO_DEBUG) < 0) 965 syslog(LOG_ERR, "setsockopt (SO_DEBUG): %m"); 966 if (turnon(sep->se_fd, SO_REUSEADDR) < 0) 967 syslog(LOG_ERR, "setsockopt (SO_REUSEADDR): %m"); 968#ifdef SO_PRIVSTATE 969 if (turnon(sep->se_fd, SO_PRIVSTATE) < 0) 970 syslog(LOG_ERR, "setsockopt (SO_PRIVSTATE): %m"); 971#endif | 1113 if (debug) 1114 warn("socket failed on %s/%s", 1115 sep->se_service, sep->se_proto); 1116 syslog(LOG_ERR, "%s/%s: socket: %m", 1117 sep->se_service, sep->se_proto); 1118 return; 1119 } 1120#define turnon(fd, opt) \ 1121setsockopt(fd, SOL_SOCKET, opt, (char *)&on, sizeof (on)) 1122 if (strcmp(sep->se_proto, "tcp") == 0 && (options & SO_DEBUG) && 1123 turnon(sep->se_fd, SO_DEBUG) < 0) 1124 syslog(LOG_ERR, "setsockopt (SO_DEBUG): %m"); 1125 if (turnon(sep->se_fd, SO_REUSEADDR) < 0) 1126 syslog(LOG_ERR, "setsockopt (SO_REUSEADDR): %m"); 1127#ifdef SO_PRIVSTATE 1128 if (turnon(sep->se_fd, SO_PRIVSTATE) < 0) 1129 syslog(LOG_ERR, "setsockopt (SO_PRIVSTATE): %m"); 1130#endif |
1131 /* tftpd opens a new connection then needs more infos */ 1132 if ((sep->se_family == AF_INET6) && 1133 (strcmp(sep->se_proto, "udp") == 0) && 1134 (sep->se_accept == 0) && 1135 (setsockopt(sep->se_fd, IPPROTO_IPV6, IPV6_PKTINFO, 1136 (char *)&on, sizeof (on)) < 0)) 1137 syslog(LOG_ERR, "setsockopt (IPV6_RECVPKTINFO): %m"); 1138#ifdef IPV6_BINDV6ONLY 1139 if ((sep->se_family == AF_INET6) && 1140 (sep->se_nomapped != 0) && 1141 (setsockopt(sep->se_fd, IPPROTO_IPV6, IPV6_BINDV6ONLY, 1142 (char *)&on, sizeof (on)) < 0)) 1143 syslog(LOG_ERR, "setsockopt (IPV6_BINDV6ONLY): %m"); 1144#endif /* IPV6_BINDV6ONLY */ |
|
972#undef turnon 973 if (sep->se_type == TTCP_TYPE) 974 if (setsockopt(sep->se_fd, IPPROTO_TCP, TCP_NOPUSH, 975 (char *)&on, sizeof (on)) < 0) 976 syslog(LOG_ERR, "setsockopt (TCP_NOPUSH): %m"); | 1145#undef turnon 1146 if (sep->se_type == TTCP_TYPE) 1147 if (setsockopt(sep->se_fd, IPPROTO_TCP, TCP_NOPUSH, 1148 (char *)&on, sizeof (on)) < 0) 1149 syslog(LOG_ERR, "setsockopt (TCP_NOPUSH): %m"); |
1150#ifdef IPV6_FAITH 1151 if (sep->se_type == FAITH_TYPE) { 1152 if (setsockopt(sep->se_fd, IPPROTO_IPV6, IPV6_FAITH, &on, 1153 sizeof(on)) < 0) { 1154 syslog(LOG_ERR, "setsockopt (IPV6_FAITH): %m"); 1155 } 1156 } 1157#endif 1158#ifdef IPSEC 1159 ipsecsetup(sep); 1160#endif |
|
977 if (bind(sep->se_fd, (struct sockaddr *)&sep->se_ctrladdr, | 1161 if (bind(sep->se_fd, (struct sockaddr *)&sep->se_ctrladdr, |
978 sizeof (sep->se_ctrladdr)) < 0) { | 1162 sep->se_ctrladdr_size) < 0) { |
979 if (debug) 980 warn("bind failed on %s/%s", 981 sep->se_service, sep->se_proto); 982 syslog(LOG_ERR, "%s/%s: bind: %m", 983 sep->se_service, sep->se_proto); 984 (void) close(sep->se_fd); 985 sep->se_fd = -1; 986 if (!timingout) { 987 timingout = 1; 988 alarm(RETRYTIME); 989 } 990 return; 991 } 992 if (sep->se_rpc) { | 1163 if (debug) 1164 warn("bind failed on %s/%s", 1165 sep->se_service, sep->se_proto); 1166 syslog(LOG_ERR, "%s/%s: bind: %m", 1167 sep->se_service, sep->se_proto); 1168 (void) close(sep->se_fd); 1169 sep->se_fd = -1; 1170 if (!timingout) { 1171 timingout = 1; 1172 alarm(RETRYTIME); 1173 } 1174 return; 1175 } 1176 if (sep->se_rpc) { |
993 int i, len = sizeof(struct sockaddr); | 1177 int i, len = sep->se_ctrladdr_size; |
994 | 1178 |
1179 if (sep->se_family != AF_INET) { 1180 syslog(LOG_ERR, 1181 "%s/%s: unsupported address family for rpc", 1182 sep->se_service, sep->se_proto); 1183 (void) close(sep->se_fd); 1184 sep->se_fd = -1; 1185 return; 1186 } |
|
995 if (getsockname(sep->se_fd, 996 (struct sockaddr*)&sep->se_ctrladdr, &len) < 0){ 997 syslog(LOG_ERR, "%s/%s: getsockname: %m", 998 sep->se_service, sep->se_proto); 999 (void) close(sep->se_fd); 1000 sep->se_fd = -1; 1001 return; 1002 } 1003 if (debug) 1004 print_service("REG ", sep); 1005 for (i = sep->se_rpc_lowvers; i <= sep->se_rpc_highvers; i++) { 1006 pmap_unset(sep->se_rpc_prog, i); 1007 pmap_set(sep->se_rpc_prog, i, 1008 (sep->se_socktype == SOCK_DGRAM) 1009 ? IPPROTO_UDP : IPPROTO_TCP, | 1187 if (getsockname(sep->se_fd, 1188 (struct sockaddr*)&sep->se_ctrladdr, &len) < 0){ 1189 syslog(LOG_ERR, "%s/%s: getsockname: %m", 1190 sep->se_service, sep->se_proto); 1191 (void) close(sep->se_fd); 1192 sep->se_fd = -1; 1193 return; 1194 } 1195 if (debug) 1196 print_service("REG ", sep); 1197 for (i = sep->se_rpc_lowvers; i <= sep->se_rpc_highvers; i++) { 1198 pmap_unset(sep->se_rpc_prog, i); 1199 pmap_set(sep->se_rpc_prog, i, 1200 (sep->se_socktype == SOCK_DGRAM) 1201 ? IPPROTO_UDP : IPPROTO_TCP, |
1010 ntohs(sep->se_ctrladdr.sin_port)); | 1202 ntohs(sep->se_ctrladdr4.sin_port)); |
1011 } | 1203 } |
1012 | |
1013 } 1014 if (sep->se_socktype == SOCK_STREAM) 1015 listen(sep->se_fd, 64); 1016 enable(sep); 1017 if (debug) { 1018 warnx("registered %s on %d", 1019 sep->se_server, sep->se_fd); 1020 } 1021} 1022 | 1204 } 1205 if (sep->se_socktype == SOCK_STREAM) 1206 listen(sep->se_fd, 64); 1207 enable(sep); 1208 if (debug) { 1209 warnx("registered %s on %d", 1210 sep->se_server, sep->se_fd); 1211 } 1212} 1213 |
1214#ifdef IPSEC 1215void 1216ipsecsetup(sep) 1217 struct servtab *sep; 1218{ 1219 char *buf; 1220 char *policy_in = NULL; 1221 char *policy_out = NULL; 1222 int level; 1223 int opt; 1224 1225 switch (sep->se_family) { 1226 case AF_INET: 1227 level = IPPROTO_IP; 1228 opt = IP_IPSEC_POLICY; 1229 break; 1230#ifdef INET6 1231 case AF_INET6: 1232 level = IPPROTO_IPV6; 1233 opt = IPV6_IPSEC_POLICY; 1234 break; 1235#endif 1236 default: 1237 return; 1238 } 1239 1240 if (!sep->se_policy || sep->se_policy[0] == '\0') { 1241 policy_in = "in entrust"; 1242 policy_out = "out entrust"; 1243 } else { 1244 if (!strncmp("in", sep->se_policy, 2)) 1245 policy_in = sep->se_policy; 1246 else if (!strncmp("out", sep->se_policy, 3)) 1247 policy_out = sep->se_policy; 1248 else { 1249 syslog(LOG_ERR, "invalid security policy \"%s\"", 1250 sep->se_policy); 1251 return; 1252 } 1253 } 1254 1255 if (policy_in != NULL) { 1256 buf = ipsec_set_policy(policy_in, strlen(policy_in)); 1257 if (buf != NULL) { 1258 if (setsockopt(sep->se_fd, level, opt, 1259 buf, ipsec_get_policylen(buf)) < 0) { 1260 syslog(LOG_ERR, 1261 "%s/%s: ipsec initialization failed; %s", 1262 sep->se_service, sep->se_proto, 1263 policy_in); 1264 } 1265 free(buf); 1266 } else 1267 syslog(LOG_ERR, "invalid security policy \"%s\"", 1268 policy_in); 1269 } 1270 if (policy_out != NULL) { 1271 buf = ipsec_set_policy(policy_out, strlen(policy_out)); 1272 if (buf != NULL) { 1273 if (setsockopt(sep->se_fd, level, opt, 1274 buf, ipsec_get_policylen(buf)) < 0) { 1275 syslog(LOG_ERR, 1276 "%s/%s: ipsec initialization failed; %s", 1277 sep->se_service, sep->se_proto, 1278 policy_out); 1279 } 1280 free(buf); 1281 } else 1282 syslog(LOG_ERR, "invalid security policy \"%s\"", 1283 policy_out); 1284 } 1285} 1286#endif 1287 |
|
1023/* 1024 * Finish with a service and its socket. 1025 */ 1026void 1027close_sep(sep) 1028 struct servtab *sep; 1029{ 1030 if (sep->se_fd >= 0) { --- 137 unchanged lines hidden (view full) --- 1168getconfigent() 1169{ 1170 struct servtab *sep = &serv; 1171 int argc; 1172 char *cp, *arg, *s; 1173 char *versp; 1174 static char TCPMUX_TOKEN[] = "tcpmux/"; 1175#define MUX_LEN (sizeof(TCPMUX_TOKEN)-1) | 1288/* 1289 * Finish with a service and its socket. 1290 */ 1291void 1292close_sep(sep) 1293 struct servtab *sep; 1294{ 1295 if (sep->se_fd >= 0) { --- 137 unchanged lines hidden (view full) --- 1433getconfigent() 1434{ 1435 struct servtab *sep = &serv; 1436 int argc; 1437 char *cp, *arg, *s; 1438 char *versp; 1439 static char TCPMUX_TOKEN[] = "tcpmux/"; 1440#define MUX_LEN (sizeof(TCPMUX_TOKEN)-1) |
1441#ifdef IPSEC 1442 char *policy = NULL; 1443#endif 1444 int v4bind = 0; 1445#ifdef INET6 1446 int v6bind = 0; 1447#endif |
|
1176 1177more: | 1448 1449more: |
1178 while ((cp = nextline(fconfig)) && (*cp == '#' || *cp == '\0')) 1179 ; | 1450 while ((cp = nextline(fconfig)) != NULL) { 1451#ifdef IPSEC 1452 /* lines starting with #@ is not a comment, but the policy */ 1453 if (cp[0] == '#' && cp[1] == '@') { 1454 char *p; 1455 for (p = cp + 2; p && *p && isspace(*p); p++) 1456 ; 1457 if (*p == '\0') { 1458 if (policy) 1459 free(policy); 1460 policy = NULL; 1461 } else if (ipsec_get_policylen(p) >= 0) { 1462 if (policy) 1463 free(policy); 1464 policy = newstr(p); 1465 } else { 1466 syslog(LOG_ERR, 1467 "%s: invalid ipsec policy \"%s\"", 1468 CONFIG, p); 1469 exit(EX_CONFIG); 1470 } 1471 } 1472#endif 1473 if (*cp == '#' || *cp == '\0') 1474 continue; 1475 break; 1476 } |
1180 if (cp == NULL) 1181 return ((struct servtab *)0); 1182 /* 1183 * clear the static buffer, since some fields (se_ctrladdr, 1184 * for example) don't get initialized here. 1185 */ 1186 memset((caddr_t)sep, 0, sizeof *sep); 1187 arg = skip(&cp); --- 23 unchanged lines hidden (view full) --- 1211 else if (strcmp(arg, "seqpacket") == 0) 1212 sep->se_socktype = SOCK_SEQPACKET; 1213 else if (strcmp(arg, "raw") == 0) 1214 sep->se_socktype = SOCK_RAW; 1215 else 1216 sep->se_socktype = -1; 1217 1218 arg = sskip(&cp); | 1477 if (cp == NULL) 1478 return ((struct servtab *)0); 1479 /* 1480 * clear the static buffer, since some fields (se_ctrladdr, 1481 * for example) don't get initialized here. 1482 */ 1483 memset((caddr_t)sep, 0, sizeof *sep); 1484 arg = skip(&cp); --- 23 unchanged lines hidden (view full) --- 1508 else if (strcmp(arg, "seqpacket") == 0) 1509 sep->se_socktype = SOCK_SEQPACKET; 1510 else if (strcmp(arg, "raw") == 0) 1511 sep->se_socktype = SOCK_RAW; 1512 else 1513 sep->se_socktype = -1; 1514 1515 arg = sskip(&cp); |
1219 if (strcmp(arg, "tcp/ttcp") == 0) { 1220 sep->se_type = TTCP_TYPE; 1221 sep->se_proto = newstr("tcp"); 1222 } else { | 1516 if (strncmp(arg, "tcp", 3) == 0) { 1517 sep->se_proto = newstr(strsep(&arg, "/")); 1518 if (arg != NULL) { 1519 if (strcmp(arg, "ttcp") == 0) 1520 sep->se_type = TTCP_TYPE; 1521 else if (strcmp(arg, "faith") == 0) 1522 sep->se_type = FAITH_TYPE; 1523 } 1524 } else |
1223 sep->se_proto = newstr(arg); | 1525 sep->se_proto = newstr(arg); |
1224 } | |
1225 if (strncmp(sep->se_proto, "rpc/", 4) == 0) { | 1526 if (strncmp(sep->se_proto, "rpc/", 4) == 0) { |
1527 if (sep->se_family != AF_INET) { 1528 syslog(LOG_ERR, "IPv6 for RPC is not supported yet"); 1529 freeconfig(sep); 1530 goto more; 1531 } |
|
1226 memmove(sep->se_proto, sep->se_proto + 4, 1227 strlen(sep->se_proto) + 1 - 4); 1228 sep->se_rpc = 1; 1229 sep->se_rpc_prog = sep->se_rpc_lowvers = 1230 sep->se_rpc_lowvers = 0; | 1532 memmove(sep->se_proto, sep->se_proto + 4, 1533 strlen(sep->se_proto) + 1 - 4); 1534 sep->se_rpc = 1; 1535 sep->se_rpc_prog = sep->se_rpc_lowvers = 1536 sep->se_rpc_lowvers = 0; |
1231 sep->se_ctrladdr.sin_family = AF_INET; 1232 sep->se_ctrladdr.sin_port = 0; 1233 sep->se_ctrladdr.sin_addr = bind_address; | 1537 memcpy(&sep->se_ctrladdr4, bind_sa4, 1538 sizeof(sep->se_ctrladdr4)); |
1234 if ((versp = rindex(sep->se_service, '/'))) { 1235 *versp++ = '\0'; 1236 switch (sscanf(versp, "%d-%d", 1237 &sep->se_rpc_lowvers, 1238 &sep->se_rpc_highvers)) { 1239 case 2: 1240 break; 1241 case 1: --- 8 unchanged lines hidden (view full) --- 1250 goto more; 1251 } 1252 } 1253 else { 1254 sep->se_rpc_lowvers = 1255 sep->se_rpc_highvers = 1; 1256 } 1257 } | 1539 if ((versp = rindex(sep->se_service, '/'))) { 1540 *versp++ = '\0'; 1541 switch (sscanf(versp, "%d-%d", 1542 &sep->se_rpc_lowvers, 1543 &sep->se_rpc_highvers)) { 1544 case 2: 1545 break; 1546 case 1: --- 8 unchanged lines hidden (view full) --- 1555 goto more; 1556 } 1557 } 1558 else { 1559 sep->se_rpc_lowvers = 1560 sep->se_rpc_highvers = 1; 1561 } 1562 } |
1563 sep->se_nomapped = 0; 1564 while (isdigit(sep->se_proto[strlen(sep->se_proto) - 1])) { 1565#ifdef INET6 1566 if (sep->se_proto[strlen(sep->se_proto) - 1] == '6') { 1567 if (no_v6bind != 0) { 1568 syslog(LOG_INFO, "IPv6 bind is ignored for %s", 1569 sep->se_service); 1570 freeconfig(sep); 1571 goto more; 1572 } 1573 sep->se_proto[strlen(sep->se_proto) - 1] = '\0'; 1574 v6bind = 1; 1575 continue; 1576 } 1577#endif 1578 if (sep->se_proto[strlen(sep->se_proto) - 1] == '4') { 1579 sep->se_proto[strlen(sep->se_proto) - 1] = '\0'; 1580 v4bind = 1; 1581 continue; 1582 } 1583 /* illegal version num */ 1584 syslog(LOG_ERR, "bad IP version for %s", sep->se_proto); 1585 freeconfig(sep); 1586 goto more; 1587 } 1588#ifdef INET6 1589 if (v6bind != 0) { 1590 sep->se_family = AF_INET6; 1591 if (v4bind == 0 || no_v4bind != 0) 1592 sep->se_nomapped = 1; 1593 } 1594#endif 1595 else { /* default to v4 bind if not v6 bind */ 1596 if (no_v4bind != 0) { 1597 syslog(LOG_INFO, "IPv4 bind is ignored for %s", 1598 sep->se_service); 1599 freeconfig(sep); 1600 goto more; 1601 } 1602 sep->se_family = AF_INET; 1603 } 1604 /* init ctladdr */ 1605 switch(sep->se_family) { 1606 case AF_INET: 1607 memcpy(&sep->se_ctrladdr4, bind_sa4, 1608 sizeof(sep->se_ctrladdr4)); 1609 sep->se_ctrladdr_size = sizeof(sep->se_ctrladdr4); 1610 sep->se_ctladdrinitok = 1; 1611 break; 1612#ifdef INET6 1613 case AF_INET6: 1614 memcpy(&sep->se_ctrladdr6, bind_sa6, 1615 sizeof(sep->se_ctrladdr6)); 1616 sep->se_ctrladdr_size = sizeof(sep->se_ctrladdr6); 1617 sep->se_ctladdrinitok = 1; 1618 break; 1619#endif 1620 } |
|
1258 arg = sskip(&cp); 1259 if (!strncmp(arg, "wait", 4)) 1260 sep->se_accept = 0; 1261 else if (!strncmp(arg, "nowait", 6)) 1262 sep->se_accept = 1; 1263 else { 1264 syslog(LOG_ERR, 1265 "%s: bad wait/nowait for service %s", --- 101 unchanged lines hidden (view full) --- 1367 } else { 1368 syslog(LOG_ERR, 1369 "%s: too many arguments for service %s", 1370 CONFIG, sep->se_service); 1371 goto more; 1372 } 1373 while (argc <= MAXARGV) 1374 sep->se_argv[argc++] = NULL; | 1621 arg = sskip(&cp); 1622 if (!strncmp(arg, "wait", 4)) 1623 sep->se_accept = 0; 1624 else if (!strncmp(arg, "nowait", 6)) 1625 sep->se_accept = 1; 1626 else { 1627 syslog(LOG_ERR, 1628 "%s: bad wait/nowait for service %s", --- 101 unchanged lines hidden (view full) --- 1730 } else { 1731 syslog(LOG_ERR, 1732 "%s: too many arguments for service %s", 1733 CONFIG, sep->se_service); 1734 goto more; 1735 } 1736 while (argc <= MAXARGV) 1737 sep->se_argv[argc++] = NULL; |
1738#ifdef IPSEC 1739 sep->se_policy = policy ? newstr(policy) : NULL; 1740#endif |
|
1375 return (sep); 1376} 1377 1378void 1379freeconfig(cp) 1380 struct servtab *cp; 1381{ 1382 int i; --- 12 unchanged lines hidden (view full) --- 1395#endif 1396 if (cp->se_server) 1397 free(cp->se_server); 1398 if (cp->se_pids) 1399 free(cp->se_pids); 1400 for (i = 0; i < MAXARGV; i++) 1401 if (cp->se_argv[i]) 1402 free(cp->se_argv[i]); | 1741 return (sep); 1742} 1743 1744void 1745freeconfig(cp) 1746 struct servtab *cp; 1747{ 1748 int i; --- 12 unchanged lines hidden (view full) --- 1761#endif 1762 if (cp->se_server) 1763 free(cp->se_server); 1764 if (cp->se_pids) 1765 free(cp->se_pids); 1766 for (i = 0; i < MAXARGV; i++) 1767 if (cp->se_argv[i]) 1768 free(cp->se_argv[i]); |
1769#ifdef IPSEC 1770 if (cp->se_policy) 1771 free(cp->se_policy); 1772#endif |
|
1403} 1404 1405 1406/* 1407 * Safe skip - if skip returns null, log a syntax error in the 1408 * configuration file and exit. 1409 */ 1410char * --- 74 unchanged lines hidden (view full) --- 1485#ifdef OLD_SETPROCTITLE 1486void 1487inetd_setproctitle(a, s) 1488 char *a; 1489 int s; 1490{ 1491 int size; 1492 char *cp; | 1773} 1774 1775 1776/* 1777 * Safe skip - if skip returns null, log a syntax error in the 1778 * configuration file and exit. 1779 */ 1780char * --- 74 unchanged lines hidden (view full) --- 1855#ifdef OLD_SETPROCTITLE 1856void 1857inetd_setproctitle(a, s) 1858 char *a; 1859 int s; 1860{ 1861 int size; 1862 char *cp; |
1493 struct sockaddr_in sin; 1494 char buf[80]; | 1863 struct sockaddr_storage ss; 1864 char buf[80], pbuf[INET6_ADDRSTRLEN]; |
1495 1496 cp = Argv[0]; | 1865 1866 cp = Argv[0]; |
1497 size = sizeof(sin); 1498 if (getpeername(s, (struct sockaddr *)&sin, &size) == 0) 1499 (void) sprintf(buf, "-%s [%s]", a, inet_ntoa(sin.sin_addr)); 1500 else | 1867 size = sizeof(ss); 1868 if (getpeername(s, (struct sockaddr *)&ss, &size) == 0) { 1869 getnameinfo((struct sockaddr *)&ss, size, pbuf, sizeof(pbuf), 1870 NULL, 0, NI_NUMERICHOST|NI_WITHSCOPEID); 1871 (void) sprintf(buf, "-%s [%s]", a, pbuf); 1872 } else |
1501 (void) sprintf(buf, "-%s", a); 1502 strncpy(cp, buf, LastArg - cp); 1503 cp += strlen(cp); 1504 while (cp < LastArg) 1505 *cp++ = ' '; 1506} 1507#else 1508void 1509inetd_setproctitle(a, s) 1510 char *a; 1511 int s; 1512{ 1513 int size; | 1873 (void) sprintf(buf, "-%s", a); 1874 strncpy(cp, buf, LastArg - cp); 1875 cp += strlen(cp); 1876 while (cp < LastArg) 1877 *cp++ = ' '; 1878} 1879#else 1880void 1881inetd_setproctitle(a, s) 1882 char *a; 1883 int s; 1884{ 1885 int size; |
1514 struct sockaddr_in sin; 1515 char buf[80]; | 1886 struct sockaddr_storage ss; 1887 char buf[80], pbuf[INET6_ADDRSTRLEN]; |
1516 | 1888 |
1517 size = sizeof(sin); 1518 if (getpeername(s, (struct sockaddr *)&sin, &size) == 0) 1519 (void) sprintf(buf, "%s [%s]", a, inet_ntoa(sin.sin_addr)); 1520 else | 1889 size = sizeof(ss); 1890 if (getpeername(s, (struct sockaddr *)&ss, &size) == 0) { 1891 getnameinfo((struct sockaddr *)&ss, size, pbuf, sizeof(pbuf), 1892 NULL, 0, NI_NUMERICHOST|NI_WITHSCOPEID); 1893 (void) sprintf(buf, "%s [%s]", a, pbuf); 1894 } else |
1521 (void) sprintf(buf, "%s", a); 1522 setproctitle("%s", buf); 1523} 1524#endif 1525 1526 1527/* 1528 * Internet services provided internally by inetd: 1529 */ 1530 | 1895 (void) sprintf(buf, "%s", a); 1896 setproctitle("%s", buf); 1897} 1898#endif 1899 1900 1901/* 1902 * Internet services provided internally by inetd: 1903 */ 1904 |
1531int check_loop(sin, sep) 1532 struct sockaddr_in *sin; | 1905int check_loop(sa, sep) 1906 struct sockaddr *sa; |
1533 struct servtab *sep; 1534{ 1535 struct servtab *se2; | 1907 struct servtab *sep; 1908{ 1909 struct servtab *se2; |
1910 char pname[INET6_ADDRSTRLEN]; |
|
1536 1537 for (se2 = servtab; se2; se2 = se2->se_next) { 1538 if (!se2->se_bi || se2->se_socktype != SOCK_DGRAM) 1539 continue; 1540 | 1911 1912 for (se2 = servtab; se2; se2 = se2->se_next) { 1913 if (!se2->se_bi || se2->se_socktype != SOCK_DGRAM) 1914 continue; 1915 |
1541 if (sin->sin_port == se2->se_ctrladdr.sin_port) { 1542 syslog(LOG_WARNING, 1543 "%s/%s:%s/%s loop request REFUSED from %s", 1544 sep->se_service, sep->se_proto, 1545 se2->se_service, se2->se_proto, 1546 inet_ntoa(sin->sin_addr)); 1547 return 1; | 1916 switch (se2->se_family) { 1917 case AF_INET: 1918 if (((struct sockaddr_in *)sa)->sin_port == 1919 se2->se_ctrladdr4.sin_port) 1920 goto isloop; 1921 continue; 1922#ifdef INET6 1923 case AF_INET6: 1924 if (((struct sockaddr_in *)sa)->sin_port == 1925 se2->se_ctrladdr4.sin_port) 1926 goto isloop; 1927 continue; 1928#endif 1929 default: 1930 continue; |
1548 } | 1931 } |
1932 isloop: 1933 getnameinfo(sa, sa->sa_len, pname, sizeof(pname), NULL, 0, 1934 NI_NUMERICHOST|NI_WITHSCOPEID); 1935 syslog(LOG_WARNING, "%s/%s:%s/%s loop request REFUSED from %s", 1936 sep->se_service, sep->se_proto, 1937 se2->se_service, se2->se_proto, 1938 pname); 1939 return 1; |
|
1549 } 1550 return 0; 1551} 1552 1553/* 1554 * print_service: 1555 * Dump relevant information to stderr 1556 */ 1557void 1558print_service(action, sep) 1559 char *action; 1560 struct servtab *sep; 1561{ 1562 fprintf(stderr, | 1940 } 1941 return 0; 1942} 1943 1944/* 1945 * print_service: 1946 * Dump relevant information to stderr 1947 */ 1948void 1949print_service(action, sep) 1950 char *action; 1951 struct servtab *sep; 1952{ 1953 fprintf(stderr, |
1954 "%s: %s proto=%s accept=%d max=%d user=%s group=%s" |
|
1563#ifdef LOGIN_CAP | 1955#ifdef LOGIN_CAP |
1564 "%s: %s proto=%s accept=%d max=%d user=%s group=%s class=%s builtin=%p server=%s\n", 1565#else 1566 "%s: %s proto=%s accept=%d max=%d user=%s group=%s builtin=%p server=%s\n", | 1956 "class=%s" |
1567#endif | 1957#endif |
1958 " builtin=%p server=%s" 1959#ifdef IPSEC 1960 " policy=\"%s\"" 1961#endif 1962 "\n", |
|
1568 action, sep->se_service, sep->se_proto, 1569 sep->se_accept, sep->se_maxchild, sep->se_user, sep->se_group, 1570#ifdef LOGIN_CAP 1571 sep->se_class, 1572#endif | 1963 action, sep->se_service, sep->se_proto, 1964 sep->se_accept, sep->se_maxchild, sep->se_user, sep->se_group, 1965#ifdef LOGIN_CAP 1966 sep->se_class, 1967#endif |
1573 (void *) sep->se_bi, sep->se_server); | 1968 (void *) sep->se_bi, sep->se_server 1969#ifdef IPSEC 1970 , (sep->se_policy ? sep->se_policy : "") 1971#endif 1972 ); |
1574} 1575 1576#define CPMHSIZE 256 1577#define CPMHMASK (CPMHSIZE-1) 1578#define CHTGRAN 10 1579#define CHTSIZE 6 1580 1581typedef struct CTime { 1582 unsigned long ct_Ticks; 1583 int ct_Count; 1584} CTime; 1585 1586typedef struct CHash { | 1973} 1974 1975#define CPMHSIZE 256 1976#define CPMHMASK (CPMHSIZE-1) 1977#define CHTGRAN 10 1978#define CHTSIZE 6 1979 1980typedef struct CTime { 1981 unsigned long ct_Ticks; 1982 int ct_Count; 1983} CTime; 1984 1985typedef struct CHash { |
1587 struct in_addr ch_Addr; | 1986 union { 1987 struct in_addr c4_Addr; 1988 struct in6_addr c6_Addr; 1989 } cu_Addr; 1990#define ch_Addr4 cu_Addr.c4_Addr 1991#define ch_Addr6 cu_Addr.c6_Addr 1992 int ch_Family; |
1588 time_t ch_LTime; 1589 char *ch_Service; 1590 CTime ch_Times[CHTSIZE]; 1591} CHash; 1592 1593CHash CHashAry[CPMHSIZE]; 1594 1595int 1596cpmip(sep, ctrl) 1597 struct servtab *sep; 1598 int ctrl; 1599{ | 1993 time_t ch_LTime; 1994 char *ch_Service; 1995 CTime ch_Times[CHTSIZE]; 1996} CHash; 1997 1998CHash CHashAry[CPMHSIZE]; 1999 2000int 2001cpmip(sep, ctrl) 2002 struct servtab *sep; 2003 int ctrl; 2004{ |
1600 struct sockaddr_in rsin; 1601 int rsinLen = sizeof(rsin); | 2005 struct sockaddr_storage rss; 2006 int rssLen = sizeof(rss); |
1602 int r = 0; 1603 1604 /* 1605 * If getpeername() fails, just let it through (if logging is 1606 * enabled the condition is caught elsewhere) 1607 */ 1608 1609 if (sep->se_maxcpm > 0 && | 2007 int r = 0; 2008 2009 /* 2010 * If getpeername() fails, just let it through (if logging is 2011 * enabled the condition is caught elsewhere) 2012 */ 2013 2014 if (sep->se_maxcpm > 0 && |
1610 getpeername(ctrl, (struct sockaddr *)&rsin, &rsinLen) == 0 ) { | 2015 getpeername(ctrl, (struct sockaddr *)&rss, &rssLen) == 0 ) { |
1611 time_t t = time(NULL); 1612 int hv = 0xABC3D20F; 1613 int i; 1614 int cnt = 0; 1615 CHash *chBest = NULL; 1616 unsigned int ticks = t / CHTGRAN; | 2016 time_t t = time(NULL); 2017 int hv = 0xABC3D20F; 2018 int i; 2019 int cnt = 0; 2020 CHash *chBest = NULL; 2021 unsigned int ticks = t / CHTGRAN; |
2022 struct sockaddr_in *sin; 2023#ifdef INET6 2024 struct sockaddr_in6 *sin6; 2025#endif |
|
1617 | 2026 |
2027 sin = (struct sockaddr_in *)&rss; 2028#ifdef INET6 2029 sin6 = (struct sockaddr_in6 *)&rss; 2030#endif |
|
1618 { 1619 char *p; | 2031 { 2032 char *p; |
1620 int i; | 2033 int i, addrlen; |
1621 | 2034 |
1622 for (i = 0, p = (char *)&rsin.sin_addr; 1623 i < sizeof(rsin.sin_addr); 1624 ++i, ++p) { | 2035 switch (rss.ss_family) { 2036 case AF_INET: 2037 p = (char *)&sin->sin_addr; 2038 addrlen = sizeof(struct in_addr); 2039 break; 2040#ifdef INET6 2041 case AF_INET6: 2042 p = (char *)&sin6->sin6_addr; 2043 addrlen = sizeof(struct in6_addr); 2044 break; 2045#endif 2046 default: 2047 /* should not happen */ 2048 return -1; 2049 } 2050 2051 for (i = 0; i < addrlen; ++i, ++p) { |
1625 hv = (hv << 5) ^ (hv >> 23) ^ *p; 1626 } 1627 hv = (hv ^ (hv >> 16)); 1628 } 1629 for (i = 0; i < 5; ++i) { 1630 CHash *ch = &CHashAry[(hv + i) & CPMHMASK]; 1631 | 2052 hv = (hv << 5) ^ (hv >> 23) ^ *p; 2053 } 2054 hv = (hv ^ (hv >> 16)); 2055 } 2056 for (i = 0; i < 5; ++i) { 2057 CHash *ch = &CHashAry[(hv + i) & CPMHMASK]; 2058 |
1632 if (rsin.sin_addr.s_addr == ch->ch_Addr.s_addr && | 2059 if (rss.ss_family == AF_INET && 2060 ch->ch_Family == AF_INET && 2061 sin->sin_addr.s_addr == ch->ch_Addr4.s_addr && |
1633 ch->ch_Service && strcmp(sep->se_service, 1634 ch->ch_Service) == 0) { 1635 chBest = ch; 1636 break; 1637 } | 2062 ch->ch_Service && strcmp(sep->se_service, 2063 ch->ch_Service) == 0) { 2064 chBest = ch; 2065 break; 2066 } |
2067#ifdef INET6 2068 if (rss.ss_family == AF_INET6 && 2069 ch->ch_Family == AF_INET6 && 2070 IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, 2071 &ch->ch_Addr6) != 0 && 2072 ch->ch_Service && strcmp(sep->se_service, 2073 ch->ch_Service) == 0) { 2074 chBest = ch; 2075 break; 2076 } 2077#endif |
|
1638 if (chBest == NULL || ch->ch_LTime == 0 || 1639 ch->ch_LTime < chBest->ch_LTime) { 1640 chBest = ch; 1641 } 1642 } | 2078 if (chBest == NULL || ch->ch_LTime == 0 || 2079 ch->ch_LTime < chBest->ch_LTime) { 2080 chBest = ch; 2081 } 2082 } |
1643 if (rsin.sin_addr.s_addr != chBest->ch_Addr.s_addr || | 2083 if ((rss.ss_family == AF_INET && 2084 (chBest->ch_Family != AF_INET || 2085 sin->sin_addr.s_addr != chBest->ch_Addr4.s_addr)) || |
1644 chBest->ch_Service == NULL || 1645 strcmp(sep->se_service, chBest->ch_Service) != 0) { | 2086 chBest->ch_Service == NULL || 2087 strcmp(sep->se_service, chBest->ch_Service) != 0) { |
1646 chBest->ch_Addr = rsin.sin_addr; | 2088 chBest->ch_Family = sin->sin_family; 2089 chBest->ch_Addr4 = sin->sin_addr; |
1647 if (chBest->ch_Service) 1648 free(chBest->ch_Service); 1649 chBest->ch_Service = strdup(sep->se_service); 1650 bzero(chBest->ch_Times, sizeof(chBest->ch_Times)); 1651 } | 2090 if (chBest->ch_Service) 2091 free(chBest->ch_Service); 2092 chBest->ch_Service = strdup(sep->se_service); 2093 bzero(chBest->ch_Times, sizeof(chBest->ch_Times)); 2094 } |
2095#ifdef INET6 2096 if ((rss.ss_family == AF_INET6 && 2097 (chBest->ch_Family != AF_INET6 || 2098 IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, 2099 &chBest->ch_Addr6) == 0)) || 2100 chBest->ch_Service == NULL || 2101 strcmp(sep->se_service, chBest->ch_Service) != 0) { 2102 chBest->ch_Family = sin6->sin6_family; 2103 chBest->ch_Addr6 = sin6->sin6_addr; 2104 if (chBest->ch_Service) 2105 free(chBest->ch_Service); 2106 chBest->ch_Service = strdup(sep->se_service); 2107 bzero(chBest->ch_Times, sizeof(chBest->ch_Times)); 2108 } 2109#endif |
|
1652 chBest->ch_LTime = t; 1653 { 1654 CTime *ct = &chBest->ch_Times[ticks % CHTSIZE]; 1655 if (ct->ct_Ticks != ticks) { 1656 ct->ct_Ticks = ticks; 1657 ct->ct_Count = 0; 1658 } 1659 ++ct->ct_Count; 1660 } 1661 for (i = 0; i < CHTSIZE; ++i) { 1662 CTime *ct = &chBest->ch_Times[i]; 1663 if (ct->ct_Ticks <= ticks && 1664 ct->ct_Ticks >= ticks - CHTSIZE) { 1665 cnt += ct->ct_Count; 1666 } 1667 } 1668 if (cnt * (CHTSIZE * CHTGRAN) / 60 > sep->se_maxcpm) { | 2110 chBest->ch_LTime = t; 2111 { 2112 CTime *ct = &chBest->ch_Times[ticks % CHTSIZE]; 2113 if (ct->ct_Ticks != ticks) { 2114 ct->ct_Ticks = ticks; 2115 ct->ct_Count = 0; 2116 } 2117 ++ct->ct_Count; 2118 } 2119 for (i = 0; i < CHTSIZE; ++i) { 2120 CTime *ct = &chBest->ch_Times[i]; 2121 if (ct->ct_Ticks <= ticks && 2122 ct->ct_Ticks >= ticks - CHTSIZE) { 2123 cnt += ct->ct_Count; 2124 } 2125 } 2126 if (cnt * (CHTSIZE * CHTGRAN) / 60 > sep->se_maxcpm) { |
2127 char pname[INET6_ADDRSTRLEN]; 2128 2129 getnameinfo((struct sockaddr *)&rss, 2130 ((struct sockaddr *)&rss)->sa_len, 2131 pname, sizeof(pname), NULL, 0, 2132 NI_NUMERICHOST|NI_WITHSCOPEID); |
|
1669 r = -1; 1670 syslog(LOG_ERR, 1671 "%s from %s exceeded counts/min (limit %d/min)", | 2133 r = -1; 2134 syslog(LOG_ERR, 2135 "%s from %s exceeded counts/min (limit %d/min)", |
1672 sep->se_service, inet_ntoa(rsin.sin_addr), | 2136 sep->se_service, pname, |
1673 sep->se_maxcpm); 1674 } 1675 } 1676 return(r); 1677} | 2137 sep->se_maxcpm); 2138 } 2139 } 2140 return(r); 2141} |