--- 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);