Index: rinetd.c =================================================================== --- rinetd/rinetd.c.orig +++ rinetd/rinetd.c @@ -1,10 +1,11 @@ -#define VERSION "0.62" +#define VERSION "0.62+syslog+bind" #ifdef WIN32 #include #include #include "getopt.h" #else +#include #include #include #include @@ -14,8 +15,12 @@ #include #define INVALID_SOCKET (-1) #include +/* kus@suse.de at 24.08.99 */ +#define SYSLOG +#define SYSLOG_NAMES +#include #endif /* WIN32 */ - + #include #include #include @@ -23,53 +28,53 @@ #include #include #include - -#ifndef WIN32 -/* Windows sockets compatibility defines */ -#define INVALID_SOCKET (-1) -#define SOCKET_ERROR (-1) -int closesocket(int s); - -int closesocket(int s) { - return close(s); -} -#define ioctlsocket ioctl -#define MAKEWORD(a, b) -#define WSAStartup(a, b) (0) -#define WSACleanup() -#ifdef __MAC__ -/* The constants for these are a little screwy in the prelinked - MSL GUSI lib and we can't rebuild it, so roll with it */ -#define WSAEWOULDBLOCK EWOULDBLOCK -#define WSAEAGAIN EAGAIN -#define WSAEINPROGRESS EINPROGRESS -#else -#define WSAEWOULDBLOCK EWOULDBLOCK -#define WSAEAGAIN EAGAIN -#define WSAEINPROGRESS EINPROGRESS -#endif /* __MAC__ */ -#define WSAEINTR EINTR -#define SOCKET int -#define GetLastError() (errno) -typedef struct { - int dummy; -} WSADATA; - -void Sleep(long ms); - -void Sleep(long ms) -{ - struct timeval tv; - tv.tv_sec = ms / 1000; - tv.tv_usec = ms * 1000; - select(0, 0, 0, 0, &tv); -} -#else -/* WIN32 doesn't really have WSAEAGAIN */ -#ifndef WSAEAGAIN -#define WSAEAGAIN WSAEWOULDBLOCK -#endif -#endif /* WIN32 */ + +#ifndef WIN32 +/* Windows sockets compatibility defines */ +#define INVALID_SOCKET (-1) +#define SOCKET_ERROR (-1) +int closesocket(int s); + +int closesocket(int s) { + return close(s); +} +#define ioctlsocket ioctl +#define MAKEWORD(a, b) +#define WSAStartup(a, b) (0) +#define WSACleanup() +#ifdef __MAC__ +/* The constants for these are a little screwy in the prelinked + MSL GUSI lib and we can't rebuild it, so roll with it */ +#define WSAEWOULDBLOCK EWOULDBLOCK +#define WSAEAGAIN EAGAIN +#define WSAEINPROGRESS EINPROGRESS +#else +#define WSAEWOULDBLOCK EWOULDBLOCK +#define WSAEAGAIN EAGAIN +#define WSAEINPROGRESS EINPROGRESS +#endif /* __MAC__ */ +#define WSAEINTR EINTR +#define SOCKET int +#define GetLastError() (errno) +typedef struct { + int dummy; +} WSADATA; + +void Sleep(long ms); + +void Sleep(long ms) +{ + struct timeval tv; + tv.tv_sec = ms / 1000; + tv.tv_usec = ms * 1000; + select(0, 0, 0, 0, &tv); +} +#else +/* WIN32 doesn't really have WSAEAGAIN */ +#ifndef WSAEAGAIN +#define WSAEAGAIN WSAEWOULDBLOCK +#endif +#endif /* WIN32 */ #ifndef TRUE #define TRUE 1 @@ -91,15 +96,17 @@ void Sleep(long ms) #include #endif /* FIONBIO */ -#include "match.h" +#include "match.h" SOCKET *seFds = 0; /* In network order, for network purposes */ struct in_addr *seLocalAddrs = 0; unsigned short *seLocalPorts = 0; +struct in_addr *seLocalSAddrs = 0; /* In ASCII and local byte order, for logging purposes */ char **seFromHosts; int *seFromPorts; +char **seFromSHosts; char **seToHosts; int *seToPorts; @@ -143,6 +150,15 @@ char *pidLogFileName = 0; int logFormatCommon = 0; FILE *logFile = 0; +#ifdef SYSLOG + int decode __P((char *, CODE *)); + char *syslogFacility_default = "daemon"; + char *syslogFacility = 0; + char *syslogLevel_default = "info"; + char *syslogLevel = 0; + int syslogpriority = -1; +#endif + /* If 'newsize' bytes can be allocated, *data is set to point to them, the previous data is copied, and 1 is returned. If 'size' bytes cannot be allocated, *data is UNCHANGED, @@ -174,8 +190,9 @@ void RegisterPID(void); void selectLoop(void); void log(int i, int coSe, int result); - -int getAddress(char *host, struct in_addr *iaddr); +void simplelog(char *message); + +int getAddress(char *host, struct in_addr *iaddr); char *logMessages[] = { "done-local-closed", @@ -191,6 +208,8 @@ char *logMessages[] = { "not-allowed", 0, "denied", + 0, + "started", 0 }; @@ -201,6 +220,7 @@ char *logMessages[] = { #define logLocalConnectFailed 8 #define logNotAllowed 10 #define logDenied 12 +#define logStarted 14 #define logLocalClosedFirst 0 #define logRemoteClosedFirst 1 @@ -222,32 +242,32 @@ int readArgs (int argc, RinetdOptions *options); int main(int argc, char *argv[]) -{ - WSADATA wsaData; - int result = WSAStartup(MAKEWORD(1, 1), &wsaData); - if (result != 0) { - fprintf(stderr, "Your computer was not connected " - "to the Internet at the time that " - "this program was launched, or you " - "do not have a 32-bit " - "connection to the Internet."); - exit(1); - } +{ + WSADATA wsaData; + int result = WSAStartup(MAKEWORD(1, 1), &wsaData); + if (result != 0) { + fprintf(stderr, "Your computer was not connected " + "to the Internet at the time that " + "this program was launched, or you " + "do not have a 32-bit " + "connection to the Internet."); + exit(1); + } readArgs(argc, argv, &options); -#ifndef WIN32 +#ifndef WIN32 #ifndef DEBUG if (!fork()) { if (!fork()) { #endif /* DEBUG */ signal(SIGPIPE, plumber); signal(SIGHUP, hup); -#endif /* WIN32 */ +#endif /* WIN32 */ signal(SIGTERM, term); initArrays(); readConfiguration(); RegisterPID(); selectLoop(); -#ifndef WIN32 +#ifndef WIN32 #ifndef DEBUG } else { exit(0); @@ -256,7 +276,7 @@ int main(int argc, char *argv[]) exit(0); } #endif /* DEBUG */ -#endif /* WIN32 */ +#endif /* WIN32 */ return 0; } @@ -264,6 +284,30 @@ int getConfLine(FILE *in, char *line, in int patternBad(char *pattern); +/* + kus@suse.de at 25.08.1999 + Thanks to the logger.c folks +*/ +#ifdef SYSLOG +int decode(name, codetab) + char *name; + CODE *codetab; +{ + register CODE *c; + + if (isdigit(*name)) + return (atoi(name)); + + for (c = codetab; c->c_name; c++) + if (!strcasecmp(name, c->c_name)) + return (c->c_val); + + return (-1); +} + +#endif +/*End kus@suse.de at 25.08.1999 */ + void readConfiguration(void) { FILE *in; @@ -285,8 +329,10 @@ void readConfiguration(void) free(seFds); free(seLocalAddrs); free(seLocalPorts); + free(seLocalSAddrs); free(seFromHosts); free(seFromPorts); + free(seFromSHosts); free(seToHosts); free(seToPorts); free(seAllowRules); @@ -319,6 +365,16 @@ void readConfiguration(void) free(logFileName); logFileName = 0; } +/* kus@suse.de at 25.08.1999 syslog stuff */ + if (syslogLevel){ + free(syslogLevel); + syslogLevel=0; + } + if (syslogFacility){ + free(syslogFacility); + syslogFacility=0; + } +/* End kus@suse.de at 25.08.1999 */ if (pidLogFileName) { free(pidLogFileName); pidLogFileName = 0; @@ -342,6 +398,11 @@ void readConfiguration(void) continue; } else if (!strcmp(t, "logcommon")) { continue; +/* kus@suse.de at 24.08.1999 */ +#ifdef SYSLOG + } else if (!strcmp(t, "syslog")) { + continue; +#endif } else if (!strcmp(t, "allow")) { allowRulesTotal++; } else if (!strcmp(t, "deny")) { @@ -366,6 +427,11 @@ void readConfiguration(void) if (!seLocalPorts) { goto lowMemory; } + seLocalSAddrs = (struct in_addr *) malloc(sizeof(struct in_addr) * + seTotal); + if (!seLocalSAddrs) { + goto lowMemory; + } seFromHosts = (char **) malloc(sizeof(char *) * seTotal); if (!seFromHosts) { @@ -376,6 +442,11 @@ void readConfiguration(void) if (!seFromPorts) { goto lowMemory; } + seFromSHosts = (char **) + malloc(sizeof(char *) * seTotal); + if (!seFromSHosts) { + goto lowMemory; + } seToHosts = (char **) malloc(sizeof(char *) * seTotal); if (!seToHosts) { @@ -436,10 +507,12 @@ void readConfiguration(void) char *bindPortS; char *connectPortS; unsigned short connectPort; + char *sourceAddress; struct in_addr iaddr; struct sockaddr_in saddr; struct servent *service; int j; + if (!getConfLine(in, line, sizeof(line), &lnum)) { break; } @@ -527,6 +600,82 @@ void readConfiguration(void) strcpy(pidLogFileName, nt); } else if (!strcmp(bindAddress, "logcommon")) { logFormatCommon = 1; +/* kus@suse.de at 24.08.1999 */ +#ifdef SYSLOG + } else if (!strcmp(bindAddress, "syslog")) { + char dummy[100]=""; + char *param1 = strtok(0, " \t\r\n"); + char *param2 = strtok(0, " \t\r\n"); + int level = -1; + int facility = -1; +/* + If we don't got a param after the syslog statment in the conf-file + we set the Facility and the Level to default +*/ + if (!param1) { + syslogFacility = malloc(strlen(syslogFacility_default) + 1); + if (!syslogFacility) { + goto lowMemory; + } + syslogLevel = malloc(strlen(syslogLevel_default) + 1); + if (!syslogLevel) { + goto lowMemory; + } + strcpy(syslogFacility,syslogFacility_default); + strcpy(syslogLevel,syslogLevel_default); + } else { + + facility = decode(param1, facilitynames); + if (facility >= 0) { + syslogFacility = malloc(strlen(param1) + 1); + if (!syslogFacility) { + goto lowMemory; + } + strcpy(syslogFacility,param1); + } else { + // log that param 1 isn't vaild + syslogFacility = malloc(strlen(syslogFacility_default) + 1); + if (!syslogFacility) { + goto lowMemory; + } + strcpy(syslogFacility,syslogFacility_default); + } + if (param2) { + level = decode(param2, prioritynames); + if (level >=0) { + syslogLevel = malloc(strlen(param2) + 1); + if (!syslogLevel) { + goto lowMemory; + } + strcpy(syslogLevel,param2); + } else { + // log that param 2 isn't vaild + syslogLevel = malloc(strlen(syslogLevel_default) + 1); + if (!syslogLevel) { + goto lowMemory; + } + strcpy(syslogLevel,syslogLevel_default); + } + } else { + /* set level to default */ + syslogLevel = malloc(strlen(syslogLevel_default) + 1); + if (!syslogLevel) { + goto lowMemory; + } + strcpy(syslogLevel,syslogLevel_default); + } + } + + logFormatCommon = 2; + syslogpriority = decode(syslogLevel, prioritynames); + strcat(dummy,"Start with Facility: "); + strcat(dummy,syslogFacility); + strcat(dummy," Priority: "); + strcat(dummy,syslogLevel); + simplelog(dummy); + continue; +#endif +/* End kus@suse.de at 24.08.1999 */ } else { /* A regular forwarding rule. */ bindPortS = strtok(0, " \t\r\n"); @@ -569,6 +718,8 @@ void readConfiguration(void) "or out of range on line %d.\n", lnum); continue; } + sourceAddress = strtok(0, " \t\r\n"); + /* Turn all of this stuff into reasonable addresses */ if (!getAddress(bindAddress, &iaddr)) { fprintf(stderr, "rinetd: host %s could not be " @@ -583,12 +734,12 @@ void readConfiguration(void) "server socket!\n"); seFds[i] = -1; continue; - } + } #ifndef WIN32 if (seFds[i] > maxfd) { maxfd = seFds[i]; } -#endif +#endif saddr.sin_family = AF_INET; memcpy(&saddr.sin_addr, &iaddr, sizeof(iaddr)); saddr.sin_port = htons(bindPort); @@ -614,8 +765,8 @@ void readConfiguration(void) closesocket(seFds[i]); seFds[i] = INVALID_SOCKET; continue; - } - ioctlsocket(seFds[i], FIONBIO, &j); + } + ioctlsocket(seFds[i], FIONBIO, &j); if (!getAddress(connectAddress, &iaddr)) { /* Warn -- don't exit. */ fprintf(stderr, "rinetd: host %s could not be " @@ -627,6 +778,27 @@ void readConfiguration(void) } seLocalAddrs[i] = iaddr; seLocalPorts[i] = htons(connectPort); + if (sourceAddress) { + if (!getAddress(sourceAddress, &iaddr)) { + /* Warn -- don't exit. */ + fprintf(stderr, "rinetd: host %s could " + "not be resolved on line %d.\n", + sourceAddress, lnum); + closesocket(seFds[i]); + seFds[i] = INVALID_SOCKET; + continue; + } + seLocalSAddrs[i] = iaddr; + seFromSHosts[i] = + malloc(strlen(sourceAddress) + 1); + if (!seFromSHosts[i]) { + goto lowMemory; + } + strcpy(seFromSHosts[i], sourceAddress); + } else { + seLocalSAddrs[i].s_addr = 0; + seFromSHosts[i] = NULL; + } seFromHosts[i] = malloc(strlen(bindAddress) + 1); if (!seFromHosts[i]) { goto lowMemory; @@ -646,18 +818,22 @@ void readConfiguration(void) } } } - /* Open the log file */ - if (logFile) { - fclose(logFile); - logFile = 0; - } - if (logFileName) { - logFile = fopen(logFileName, "a"); - if (!logFile) { - fprintf(stderr, "rinetd: could not open %s to append.\n", - logFileName); - } - } + /* Open the log file */ +/* kus@suse.de at 25.08.1999 */ + if (logFormatCommon != 2) { + if (logFile) { + fclose(logFile); + logFile = 0; + } + if (logFileName) { + logFile = fopen(logFileName, "a"); + if (!logFile) { + fprintf(stderr, "rinetd: could not open %s to append.\n", + logFileName); + } + } + } +/* End kus@suse.de at 25.08.1999 */ return; lowMemory: fprintf(stderr, "rinetd: not enough memory to start rinetd.\n"); @@ -955,7 +1131,7 @@ void handleCloseFromLocal(int i) loClosed[i] = 1; if (!reClosed[i]) { #ifndef LINUX -#ifndef WIN32 +#ifndef WIN32 /* Now set up the remote end for a polite closing */ /* Request a low-water mark equal to the entire @@ -963,7 +1139,7 @@ void handleCloseFromLocal(int i) tells us for sure that we can close the socket. */ arg = 1024; setsockopt(reFds[i], SOL_SOCKET, SO_SNDLOWAT, - &arg, sizeof(arg)); + &arg, sizeof(arg)); #endif /* WIN32 */ #endif /* LINUX */ coLog[i] = logLocalClosedFirst; @@ -980,7 +1156,7 @@ void handleCloseFromRemote(int i) closesocket(reFds[i]); reClosed[i] = 1; if (!loClosed[i]) { -#ifndef LINUX +#ifndef LINUX #ifndef WIN32 /* Now set up the local end for a polite closing */ @@ -989,7 +1165,7 @@ void handleCloseFromRemote(int i) tells us for sure that we can close the socket. */ arg = 1024; setsockopt(loFds[i], SOL_SOCKET, SO_SNDLOWAT, - &arg, sizeof(arg)); + &arg, sizeof(arg)); #endif /* WIN32 */ #endif /* LINUX */ loClosed[i] = 0; @@ -1016,17 +1192,17 @@ void handleAccept(int i) log(-1, i, logAcceptFailed); return; } -#ifndef WIN32 +#ifndef WIN32 if (nfd > maxfd) { maxfd = nfd; } -#endif /* WIN32 */ +#endif /* WIN32 */ j = 1; - ioctlsocket(nfd, FIONBIO, &j); + ioctlsocket(nfd, FIONBIO, &j); j = 0; -#ifndef WIN32 +#ifndef WIN32 setsockopt(nfd, SOL_SOCKET, SO_LINGER, &j, sizeof(j)); -#endif +#endif for (j = 0; (j < coTotal); j++) { if (coClosed[j]) { index = j; @@ -1190,6 +1366,9 @@ void handleAccept(int i) for (j = 0; (j < globalDenyRules); j++) { if (match(addressText, denyRules[j])) { refuse(index, logDenied); +/* kus@suse.de at 25.08.1999 */ + return; +/* End kus@suse.de at 25.08.1999 */ } } } @@ -1217,6 +1396,9 @@ void handleAccept(int i) if (match(addressText, denyRules[seDenyRules[i] + j])) { refuse(index, logDenied); +/* kus@suse.de at 25.08.1999 */ + return; +/* End kus@suse.de at 25.08.1999 */ } } } @@ -1224,6 +1406,7 @@ void handleAccept(int i) This, too, is nonblocking. Why wait for anything when you don't have to? */ openLocalFd(i, index); + log(i, coSe[i], logStarted); return; shortage: fprintf(stderr, "rinetd: not enough memory to " @@ -1245,15 +1428,15 @@ void openLocalFd(int se, int i) log(i, coSe[i], logLocalSocketFailed); return; } -#ifndef WIN32 +#ifndef WIN32 if (loFds[i] > maxfd) { maxfd = loFds[i]; } -#endif /* WIN32 */ +#endif /* WIN32 */ /* Bind the local socket */ saddr.sin_family = AF_INET; saddr.sin_port = INADDR_ANY; - saddr.sin_addr.s_addr = 0; + memcpy(&saddr.sin_addr, &seLocalSAddrs[se], sizeof(struct in_addr)); if (bind(loFds[i], (struct sockaddr *) &saddr, sizeof(saddr)) == SOCKET_ERROR) { closesocket(loFds[i]); closesocket(reFds[i]); @@ -1267,7 +1450,7 @@ void openLocalFd(int se, int i) saddr.sin_family = AF_INET; memcpy(&saddr.sin_addr, &seLocalAddrs[se], sizeof(struct in_addr)); saddr.sin_port = seLocalPorts[se]; -#ifndef WIN32 +#ifndef WIN32 #ifdef LINUX j = 0; setsockopt(loFds[i], SOL_SOCKET, SO_LINGER, &j, sizeof(j)); @@ -1275,14 +1458,14 @@ void openLocalFd(int se, int i) j = 1024; setsockopt(loFds[i], SOL_SOCKET, SO_SNDBUF, &j, sizeof(j)); #endif /* LINUX */ -#endif /* WIN32 */ - j = 1; - ioctlsocket(loFds[i], FIONBIO, &j); +#endif /* WIN32 */ + j = 1; + ioctlsocket(loFds[i], FIONBIO, &j); if (connect(loFds[i], (struct sockaddr *)&saddr, sizeof(struct sockaddr_in)) == INVALID_SOCKET) { - if ((GetLastError() != WSAEINPROGRESS) && - (GetLastError() != WSAEWOULDBLOCK)) + if ((GetLastError() != WSAEINPROGRESS) && + (GetLastError() != WSAEWOULDBLOCK)) { PERROR("rinetd: connect"); closesocket(loFds[i]); @@ -1323,11 +1506,14 @@ int getAddress(char *host, struct in_add return 1; } } - + #ifndef WIN32 void plumber(int s) { /* Just reinstall */ +#ifdef SYSLOG + simplelog("SIGPIPE"); +#endif signal(SIGPIPE, plumber); } @@ -1338,7 +1524,7 @@ void hup(int s) /* And reinstall the signal handler */ signal(SIGHUP, hup); } -#endif /* WIN32 */ +#endif /* WIN32 */ int safeRealloc(void **data, int oldsize, int newsize) { @@ -1380,6 +1566,18 @@ void RegisterPID(void) unsigned char nullAddress[4] = { 0, 0, 0, 0 }; struct tm *get_gmtoff(int *tz); +/* Funktion for some extra logging info + kus@suse.de at 25.08.1999 +*/ + +void simplelog(char *message) +{ + char *facility = syslogFacility?syslogFacility:syslogFacility_default; + openlog("",LOG_PID,decode(facility, facilitynames)); + syslog(syslogpriority,"%s\n",message); + closelog(); +} +/* kus@suse.de at 25.08.1999 */ void log(int i, int coSe, int result) { @@ -1412,7 +1610,7 @@ void log(int i, int coSe, int result) bytesInput = 0; } if (logFile) { - if (logFormatCommon) { + if (logFormatCommon == 1) { /* Fake a common log format log file in a way that most web analyzers can do something interesting with. We lie and say the protocol is HTTP because we don't @@ -1425,9 +1623,14 @@ void log(int i, int coSe, int result) after several placeholders meant to fill the positions frequently occupied by user agent, referrer, and server name information. */ - fprintf(logFile, "%d.%d.%d.%d - - " + fprintf(logFile, seFromSHosts[coSe] ? + "%d.%d.%d.%d - - " + "[%s %c%.2d%.2d] " + "\"GET /rinetd-services/%s[%s]/%d/%s/%d/%s HTTP/1.0\" " + "200 %d - - - %d\n" : + "%d.%d.%d.%d - - " "[%s %c%.2d%.2d] " - "\"GET /rinetd-services/%s/%d/%s/%d/%s HTTP/1.0\" " + "\"GET /rinetd-services/%s%.0s/%d/%s/%d/%s HTTP/1.0\" " "200 %d - - - %d\n", reAddress[0], reAddress[1], @@ -1437,7 +1640,8 @@ void log(int i, int coSe, int result) sign, timz / 60, timz % 60, - seFromHosts[coSe], seFromPorts[coSe], + seFromHosts[coSe], seFromSHosts[coSe], + seFromPorts[coSe], seToHosts[coSe], seToPorts[coSe], logMessages[result], bytesOutput, @@ -1445,19 +1649,39 @@ void log(int i, int coSe, int result) } else { /* Write an rinetd-specific log entry with a less goofy format. */ - fprintf(logFile, "%s\t%d.%d.%d.%d\t%s\t%d\t%s\t%d\t%d" - "\t%d\t%s\n", - tstr, + fprintf(logFile, seFromSHosts[coSe] ? + "%s\t%d.%d.%d.%d\t%s[%s]\t%d\t%s\t%d\t%d" + "\t%d\t%s\n" : + "%s\t%d.%d.%d.%d\t%s%.0s\t%d\t%s\t%d\t%d" + "\t%d\t%s\n", + tstr, reAddress[0], reAddress[1], reAddress[2], reAddress[3], - seFromHosts[coSe], seFromPorts[coSe], + seFromHosts[coSe], seFromSHosts[coSe], + seFromPorts[coSe], seToHosts[coSe], seToPorts[coSe], bytesInput, bytesOutput, logMessages[result]); } +/* kus@suse.de at 25.08.1999 */ +#ifdef SYSLOG + } else if (logFormatCommon == 2) { + /* kus@suse.de at 24.08.1999 */ + syslog(syslogpriority,"%d.%d.%d.%d %s:%d %s:%d in:%d out:%d %s", + reAddress[0], + reAddress[1], + reAddress[2], + reAddress[3], + seFromHosts[coSe], seFromPorts[coSe], + seToHosts[coSe], seToPorts[coSe], + bytesInput, + bytesOutput, + logMessages[result]); +#endif +/* End kus@suse.de at 25.08.1999 */ } } @@ -1508,7 +1732,7 @@ int readArgs (int argc, default: exit (1); } - } + } return 0; } @@ -1557,6 +1781,9 @@ void refuse(int index, int logCode) void term(int s) { /* Obey the request, but first flush the log */ +#ifdef SYSLOG + simplelog("TERM"); +#endif if (logFile) { fclose(logFile); }