cfingerd (1.4.3-3) src/main.c

Summary

 src/main.c |   89 +++++++++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 63 insertions(+), 26 deletions(-)

    
download this patch

Patch contents

--- cfingerd-1.4.3.orig/src/main.c
+++ cfingerd-1.4.3/src/main.c
@@ -20,11 +20,13 @@
 #include "privs.h"
 
 CONFIG prog_config;
-char *remote_addr, *localhost, *ident_user, *ip_address;
+char *localhost, *ident_user;
+char ip_address[INET6_ADDRSTRLEN] = "";
+char remote_addr[INET6_ADDRSTRLEN] = "";
 FILE *top_display, *bottom_display, *noname_display, *nouser_display,
      *rejected_display, *identd_display;
 BOOL local_finger, emulated; 
-int local_port, remote_port;
+unsigned short local_port, remote_port;
 unsigned short listen_port;
 unsigned long listen_addr;
 
@@ -62,14 +64,15 @@
     char line[100], username[80], syslog_str[200];
     int un_type;
     char *cp;
-    struct sockaddr_in local_addr;
+    struct sockaddr_storage local_addr;
+    struct sockaddr_in *sloc4 = (struct sockaddr_in *) &local_addr;
+    struct sockaddr_in6 *sloc6 = (struct sockaddr_in6 *) &local_addr;
     struct servent *serv;
 
     if ((serv = getservbyname("finger","tcp")) != NULL)
 	listen_port = serv->s_port;
     else
 	listen_port = htons(79);
-    listen_addr = htonl(INADDR_ANY);
 
     /* Initialize CFINGERD */
     start_handler();
@@ -108,12 +111,12 @@
     /* Make sure there is actually data waiting in the finger port */
     if (!emulated) {
 	if (!fgets(username, sizeof(username), stdin)) {
-	  if (remote_addr != NULL) {
+	  if (remote_addr != NULL && *remote_addr) {
 	    syslog(LOG_ERR, "Null query from %s: %m", remote_addr);
-	    log(LOG_ERROR, remote_addr, strerror(errno));
+	    mylog(LOG_ERROR, remote_addr, strerror(errno));
 	  } else {
 	    syslog(LOG_ERR, "Null query: %m");
-	    log(LOG_ERROR, strerror(errno), strerror(0));
+	    mylog(LOG_ERROR, strerror(errno), strerror(0));
 	  }
 	    closelog();
 	    exit(PROGRAM_SYSLOG);
@@ -147,33 +150,64 @@
     /* If we're not doing emulated stuff, we can assume that we are running
        either as a daemon, or under INETD.  In that case... */
     if (!emulated) {
-	struct sockaddr_in socket_addr;
+	struct sockaddr_storage socket_addr;
+	struct sockaddr_in *srem4 = (struct sockaddr_in *) &socket_addr;
+	struct sockaddr_in6 *srem6 = (struct sockaddr_in6 *) &socket_addr;
 	struct hostent *host_ent;
-	int psize = 0;
+	socklen_t locsize = 0, remsize = 0;
 
 	/* Can't run from command line (but this should already be checked) */
-	psize = sizeof(socket_addr);
+	locsize = sizeof(local_addr);
 
-	if (getsockname(0, (struct sockaddr *) &local_addr, &psize)) {
+	if (getsockname(0, (struct sockaddr *) &local_addr, &locsize)) {
 	    syslog(LOG_WARNING, "getsockname: %s", strerror(errno));
 	    local_port = 0;
 	} else
-	    local_port = ntohs(local_addr.sin_port);
+	    switch (local_addr.ss_family) {
+		case AF_INET6:
+		    local_port = ntohs(sloc6->sin6_port);
+		    break;
+		case AF_INET:
+		default:
+		    local_port = ntohs(sloc4->sin_port);
+	    }
+
+	remsize = sizeof(socket_addr);
 
-	if (getpeername(0, (struct sockaddr *) &socket_addr, &psize)) {
+	if (getpeername(0, (struct sockaddr *) &socket_addr, &remsize)) {
 	    printf("Internal error - not running as either a daemon or under INETD.\n");
 	    printf("Fatal - getpeername: %s\n", strerror(errno));
 	    closelog();
-	    log(LOG_ERROR, "getpeername: ", strerror(errno));
+	    mylog(LOG_ERROR, "getpeername: ", strerror(errno));
 	    exit(PROGRAM_BUG);
 	} else
-	    remote_port = ntohs(socket_addr.sin_port);
+	    switch (socket_addr.ss_family) {
+		case AF_INET6:
+		    remote_port = ntohs(srem6->sin6_port);
+		    break;
+		case AF_INET:
+		default:
+		    remote_port = ntohs(srem4->sin_port);
+	    }
 
-	ip_address = inet_ntoa (socket_addr.sin_addr);
+	inet_ntop(socket_addr.ss_family, &socket_addr,
+			ip_address, INET6_ADDRSTRLEN);
 
 	/* Get our host entry */
-	host_ent = (struct hostent *) gethostbyaddr((char *) &socket_addr.sin_addr,
-		   sizeof(socket_addr.sin_addr), AF_INET);
+	switch (socket_addr.ss_family) {
+	    case AF_INET6:
+		host_ent = (struct hostent *)
+				gethostbyaddr((char *) &srem6->sin6_addr,
+					sizeof(struct in6_addr),
+					socket_addr.ss_family);
+		break;
+	    case AF_INET:
+	    default:
+		host_ent = (struct hostent *)
+				gethostbyaddr((char *) &srem4->sin_addr,
+					sizeof(struct in_addr),
+					socket_addr.ss_family);
+	}
 
 	/* And get our local-host name */
 #ifndef	ACTUAL_HOSTNAME
@@ -184,14 +218,14 @@
 
 	/* Make sure we can get the remote host's address name */
 	if (host_ent == NULL) {
-	    remote_addr = inettos(socket_addr.sin_addr.s_addr);
+	    strncpy(remote_addr, ip_address, INET6_ADDRSTRLEN);
 	    syslog(LOG_WARNING, "%s %s", 
 		prog_config.p_strings[D_IP_NO_MATCH],
 		remote_addr);
 	    if (!(prog_config.config_bits2 & SHOW_IP_MATCH))
 		CF_ERROR(E_NOIP);
 	} else
-	    remote_addr = (char *) host_ent->h_name;
+	    strncpy(remote_addr, host_ent->h_name, INET6_ADDRSTRLEN);
 
 	/* Convert any uppercase letters in the hostname to lowercase */
 	for (cp = remote_addr; *cp; cp++)
@@ -200,14 +234,17 @@
 
 	/* And find out if this is a local finger */
 	if (!strncasecmp(remote_addr, "127.0.0.1", 9) ||
+	    !strncasecmp(remote_addr, "::1", 3) ||
 	    !strncasecmp(remote_addr, "localhost", 9) ||
+	    !strncasecmp(remote_addr, "ip6-localhost", 9) ||
+	    !strncasecmp(remote_addr, "ip6-loopback", 9) ||
 	    !strncasecmp(remote_addr, "127.0.0.0", 9) || /* KTH 07/26/96 */
 	    !strncasecmp(remote_addr, localhost, strlen(localhost)))
 	    local_finger = TRUE;
 	else
 	    local_finger = FALSE;
 
-	ident_user = get_rfc1413_data(local_addr);
+	ident_user = get_rfc1413_data(&local_addr, &socket_addr);
 	set_time_format();
 
     } else
@@ -220,9 +257,9 @@
 	memset (ident_user, 0, sizeof (ident_user));
 	strcpy (ident_user, "emulated");
 #ifndef	ACTUAL_LOOPBACK
-	remote_addr = "127.0.0.1";
+	strcpy(remote_addr,"127.0.0.1");
 #else
-	remote_addr = ACTUAL_LOOPBACK;
+	strcpy(remote_addr, ACTUAL_LOOPBACK);
 #endif
     }
 
@@ -242,7 +279,7 @@
 	    if (!emulated) {
 		snprintf(syslog_str, sizeof(syslog_str), "%s fingered (internal) from %s", username,
 		    ident_user);
-		syslog(LOG_NOTICE, (char *) syslog_str);
+		syslog(LOG_NOTICE, "%s", (char *) syslog_str);
 	    }
 
 	    handle_internal(username);
@@ -255,7 +292,7 @@
 		    snprintf(syslog_str, sizeof(syslog_str), "%s fingered from %s",
 			prog_config.p_strings[D_ROOT_FINGER], ident_user);
 
-		syslog(LOG_NOTICE, (char *) syslog_str);
+		syslog(LOG_NOTICE, "%s", (char *) syslog_str);
 	    }
 
 	    handle_standard(username);
@@ -265,7 +302,7 @@
 		snprintf(syslog_str, sizeof(syslog_str), "%s %s from %s", username, 
 		    prog_config.p_strings[D_FAKE_USER], ident_user);
 
-		syslog(LOG_NOTICE, (char *) syslog_str);
+		syslog(LOG_NOTICE, "%s", (char *) syslog_str);
 	    }
 
 	    handle_fakeuser(username);