/* ** identify.c Identify a connection with the Identification Protocol ** ** Version: 0.6 ** ** Author: Peter Eriksson ** ** This program is in the public domain. */ #include #include #include #include #include #include #include #include int debug = 0; int fd = 0; char *name = "ident"; char *msg = NULL; int logopt = 0; #ifdef LOG_AUTH int facility = LOG_AUTH; #endif int priority = LOG_NOTICE; int background = 0; int child_pid = 0; char *force_log = NULL; int noidentify = 0; int bits = 0; int reject_flag = 0; struct in_addr inlocal; struct in_addr inremote; int timeout = 120; char *ident_get_identifier(fd, host, len) int fd; char *host; int len; { struct sockaddr_in sa; int l; l=sizeof(sa); if (getsockname(fd,(struct sockaddr *)&sa,&l)<0) { if (debug) perror("getsockname()"); return NULL; } inlocal=sa.sin_addr; if (getpeername(fd,(struct sockaddr *)&sa,&l)<0) { if (debug) perror("getpeername()"); return NULL; } inremote=sa.sin_addr; if (host) { struct hostent *hp; hp = gethostbyaddr((const char *)&inremote,sizeof(struct in_addr),AF_INET); if (hp) strncpy(host, hp->h_name, len); else strncpy(host, inet_ntoa(inremote), len); host[len] = '\0'; } if (noidentify) return NULL; else return ident_id(fd,timeout); } main(argc,argv) int argc; char *argv[]; { int i; char *id; char host[1024]; if (argv[0]) name = argv[0]; for (i = 1; i < argc && argv[i][0] == '-'; i++) switch (argv[i][1]) { case 'x': noidentify = 1; force_log = ""; break; case 't': timeout = atoi(argv[i]+2); break; case 'R': if (!argv[i][2]) reject_flag = 1; else reject_flag = atoi(argv[i]+2); break; case 'r': bits = 32 - atoi(argv[i]+2); break; case 'o': logopt = atoi(argv[i]+2); break; #ifdef LOG_AUTH case 'f': facility = atoi(argv[i]+2)<<3; break; #endif case 'p': priority = atoi(argv[i]+2); break; case 'n': name = argv[i]+2; break; case 'd': fd = atoi(argv[i]+2); break; case 'm': msg = argv[i]+2; break; case 'b': background = 1; break; case 'i': if (!argv[i][2]) force_log = ""; else force_log = argv[i]+2; break; case 'D': debug = 1; break; } /* ** Can do the background stuff if using -R or -r */ if (reject_flag || bits) background = 0; if (background) { signal(SIGCHLD, SIG_IGN); child_pid = fork(); if (!child_pid) { /* In child, let's fork again so we can forget about this child */ if (fork()) _exit(0); } else { /* Do this so we can forget about this child */ int status; wait(&status); } } if (!child_pid) { #ifdef LOG_AUTH openlog(name, logopt, facility); #else openlog(name, logopt); #endif id = ident_get_identifier(fd, host, sizeof(host)-1); if (id || force_log) { if (!id) id = force_log; if (debug) fprintf(stderr, "syslog: %s@%s: %s", id, host, msg ? msg : argv[i]); syslog(priority, "%s@%s: %s", id, host, msg ? msg : argv[i]); } else if (debug) perror("ident error"); if (background) { closelog(); _exit(0); } } if ((bits && (htonl(inremote.s_addr) >> bits != htonl(inlocal.s_addr) >> bits)) || (reject_flag && !id)) { if (id) syslog(priority, "Rejecting from %s@%s", id, inet_ntoa(inremote)); else syslog(priority, "Rejecting from %s", inet_ntoa(inremote)); exit(1); } execv(argv[i], argv+i+1); if (debug) fprintf(stderr, "execv(%s, ..) failed\r\n", argv[i]); exit(1); }