/* ** A proper identification protocol (RFC 1413) implementation, ** providing all the utility, security, and authentication ** of all other implementations of this protocol, without ** all the expensive and pointless grovelling in /dev/kmem. ** ** Careful design and software engineering makes this software ** efficient, fast, compact, scalable, and completely maintenance free. ** ** Anyone who feels the need to use a daemon more complex than this one ** should go read section 6 of RFC 1413 very carefully, and think again. ** ** Erik E. Fair , February 1, 2000 */ /* ** This runs under inetd, with the following configuration: ** ident stream tcp nowait nobody /usr/local/libexec/identd identd ** ** There are two mutually exclusive options: ** -h - always reply that the user is hidden ** -u - always reply that there was an unknown error */ #include #include #include #include #include #include #define STDIN 0 #define STDOUT 1 const char hiding[] = ":ERROR:HIDDEN-USER\r\n"; const char unknown[] = ":ERROR:UNKNOWN-ERROR\r\n"; const char resperr[] = "0,0:ERROR:INVALID-PORT\r\n"; const char response[] = "%s:USERID:OTHER:%lu-ident-is-a-completely-pointless-protocol-that-offers-no-security-or-traceability-at-all-so-take-this-and-log-it!\r\n"; #define MAXREAD 1024 static char buf[MAXREAD]; char * MakeItAllUp(query) char *query; { struct timeval tod; pid_t pid = getpid(); /* fail? perish the thought! */ unsigned long nonsense; static char silliness[MAXREAD]; /* never let it be said that I won't give anyone the time of day */ if (gettimeofday(&tod, NULL) < 0) { exit(4); } nonsense = tod.tv_usec % pid; snprintf(silliness, MAXREAD, response, query, nonsense); return(silliness); } int main(ac, av) int ac; char *av[]; { char *p; ssize_t resplen = read(STDIN, buf, MAXREAD); if (resplen <= 0) { exit(1); } p = memchr(buf, '\r', MAXREAD); if (p == NULL) { exit(2); } *p = '\0'; resplen = strlen(buf) + sizeof(response); if (resplen > MAXREAD) { (void)write(STDOUT, resperr, sizeof(resperr)); exit(3); } if ((ac > 1) && (strlen(av[1]) > 1)) { switch (av[1][1]) { case 'h': resplen = strlen(buf) + sizeof(hiding); p = strcat(buf, hiding); break; case 'u': resplen = strlen(buf) + sizeof(unknown); p = strcat(buf, unknown); break; default: p = MakeItAllUp(buf); break; } } else { p = MakeItAllUp(buf); } (void)write(STDOUT, p, strlen(p)); exit(0); }