/* * Minimal fake ident server for firewalls / NAT gateways. * This code is very basic, but at least _secure_ . * * Compile with : make minidentd * Install with : strip minidentd * cp minidentd /usr/local/bin/ * Spawn from your favorite superserver (inetd, tcpserver, etc), from port * 113 / TCP . * * Public domain, make what you want with this source code. * -Jedi/Sector One . */ /* An empty directory in your filesystem */ #define EMPTY "/var/empty" /* The user to switch to */ #define USER "nobody" /* The default reply */ #define DEFAULT_USER "minidentd" /* Timeout in seconds */ #define TIMEOUT 5U /* Don't change anything below that line */ #include #include #include #include #include #include #include #include #include #include #include #include #ifndef errno extern int errno; #endif #if defined(_BSD_SOURCE) || defined(_SYSV_SOURCE) || defined(_XOPEN_SOURCE) # define HAVE_SETGROUPS #endif static int parse(char *line, const char * const user) { char *coma; char *endptr; unsigned int p1, p2; if ((coma = strchr(line, ',')) == NULL) { inv: puts("0, 0 : ERROR : X-INVALID-REQUEST\r"); return -1; } *coma++ = 0; for (;;) { if (*coma == 0) { goto inv; } if (isspace((unsigned char) *coma)) { *coma++ = 0; continue; } if (isdigit((unsigned char) *coma)) { break; } goto inv; } p1 = (unsigned int) strtoul(line, &endptr, 10); if (endptr == line || p1 > 65535U) { goto inv; } p2 = (unsigned int) strtoul(coma, &endptr, 10); if (endptr == coma || p2 > 65535U) { goto inv; } printf("%u, %u : USERID : UNIX : %s\r\n", p1, p2, user); return 0; } static int safe(void) { struct passwd *pw; if (geteuid() != (uid_t) 0U) { return 0; } if ((pw = getpwnam(USER)) == NULL || pw->pw_uid <= (uid_t) 0U || chdir(EMPTY) != 0 || chroot(EMPTY) != 0 || chdir("/") != 0) { return -1; } if ( #ifdef HAVE_SETGROUPS setgroups((size_t) 1U, &pw->pw_gid) != 0 || #endif setgid(pw->pw_gid) != 0 || setegid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0 || seteuid(pw->pw_uid) != 0) { return -1; } return 0; } int main(int a, char *b[]) { const char *user = DEFAULT_USER; char line[42]; if (safe() != 0) { return -1; } (void) close(2); (void) alarm(TIMEOUT); if (isatty(1)) { puts("Usage : tcpserver -HRql0 0 113 " "/usr/local/bin/minidentd [user]\n\n" "You can of course run it from any other superserver " "(inetd, jnetd, xinetd, ...)"); return 2; } if (a == 2) { user = b[1]; } if (fgets(line, sizeof line, stdin) == NULL) { return 1; } return parse(line, user); }