summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cfingerd-1.4.3-ipv6-12121999.patch481
-rw-r--r--cfingerd.spec2
2 files changed, 482 insertions, 1 deletions
diff --git a/cfingerd-1.4.3-ipv6-12121999.patch b/cfingerd-1.4.3-ipv6-12121999.patch
new file mode 100644
index 0000000..860743b
--- /dev/null
+++ b/cfingerd-1.4.3-ipv6-12121999.patch
@@ -0,0 +1,481 @@
+;
+; IPv6 patch for cfingerd 1.4.3 daemon.
+; System with working getaddrinfo(), getnameinfo(),
+; functions and defined struct sockaddr_storage required
+; (ie. Linux 2.2.x with glibc 2.1.1 or *BSD/KAME)
+;
+; Arkadiusz Mi¶kiewicz <misiek@pld.org.pl>, PLD/Linux
+;
+Index: cfingerd/CHANGES
+diff -u cfingerd/CHANGES:1.1.1.1 cfingerd/CHANGES:1.2
+--- cfingerd/CHANGES:1.1.1.1 Sun Dec 12 12:23:27 1999
++++ cfingerd/CHANGES Sun Dec 12 13:07:49 1999
+@@ -1,3 +1,6 @@
++CFINGERD 1.4.4 ??/??/??
++ - full IPv6 support !
++
+ CFINGERD 1.4.3 09/29/99
+ - Security update, fixes buffer overflows introduced with sscanf(),
+ exploitable under FreeBSD
+Index: cfingerd/src/cfingerd.h
+diff -u cfingerd/src/cfingerd.h:1.1.1.1 cfingerd/src/cfingerd.h:1.2
+--- cfingerd/src/cfingerd.h:1.1.1.1 Sun Dec 12 12:23:27 1999
++++ cfingerd/src/cfingerd.h Sun Dec 12 13:07:49 1999
+@@ -28,6 +28,9 @@
+ #include <ctype.h>
+ #include <time.h>
+ #include <pwd.h>
++#ifdef INET6
++#include <setjmp.h>
++#endif
+
+ #include <netinet/in.h>
+ #include <sys/socket.h>
+@@ -278,10 +281,20 @@
+
+ extern CONFIG prog_config;
+ extern ECRUFT errors[];
++#ifdef INET6
++extern char *localhost, *ident_user;
++extern char remote_addr[100], ip_address[100];
++#else
+ extern char *remote_addr, *localhost, *ident_user, *ip_address;
++#endif
+ extern int trusted_host_num, rejected_host_num, forward_host_num,
++#ifndef INET6
+ fakeuser_num, num_finger_sites, num_headers, local_port,
+ remote_port, can_log;
++#else
++ fakeuser_num, num_finger_sites, num_headers, can_log;
++extern char local_port[32], remote_port[32];
++#endif
+ extern FILE *top_display, *bottom_display, *noname_display, *nouser_display,
+ *rejected_display, *identd_display;
+ extern BOOL local_finger, emulated;
+Index: cfingerd/src/main.c
+diff -u cfingerd/src/main.c:1.1.1.1 cfingerd/src/main.c:1.2
+--- cfingerd/src/main.c:1.1.1.1 Sun Dec 12 12:23:27 1999
++++ cfingerd/src/main.c Sun Dec 12 13:07:49 1999
+@@ -1,6 +1,7 @@
+ /*
+ * CFINGERD
+ * Main Routine
++ * IPv6 code Copyright (C) 1999 Arkadiusz Mi¶kiewicz <misiek@pld.org.pl>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+@@ -20,11 +21,21 @@
+ #include "privs.h"
+
+ CONFIG prog_config;
++#ifdef INET6
++char *localhost, *ident_user;
++char remote_addr[100];
++char ip_address[100];
++#else
+ char *remote_addr, *localhost, *ident_user, *ip_address;
++#endif
+ FILE *top_display, *bottom_display, *noname_display, *nouser_display,
+ *rejected_display, *identd_display;
+ BOOL local_finger, emulated;
++#ifdef INET6
++char local_port[32], remote_port[32];
++#else
+ int local_port, remote_port;
++#endif
+ unsigned short listen_port;
+ unsigned long listen_addr;
+
+@@ -62,6 +73,7 @@
+ char line[100], username[80], syslog_str[200];
+ int un_type;
+ char *cp;
++#ifndef INET6
+ struct sockaddr_in local_addr;
+ struct servent *serv;
+
+@@ -70,6 +82,9 @@
+ else
+ listen_port = htons(79);
+ listen_addr = htonl(INADDR_ANY);
++#else
++ struct sockaddr_storage local_addr;
++#endif
+
+ /* Initialize CFINGERD */
+ start_handler();
+@@ -147,8 +162,12 @@
+ /* 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) {
++#ifdef INET6
++ struct sockaddr_storage socket_addr;
++#else
+ struct sockaddr_in socket_addr;
+ struct hostent *host_ent;
++#endif
+ int psize = 0;
+
+ /* Can't run from command line (but this should already be checked) */
+@@ -156,9 +175,19 @@
+
+ if (getsockname(0, (struct sockaddr *) &local_addr, &psize)) {
+ syslog(LOG_WARNING, "getsockname: %s", strerror(errno));
++#ifndef INET6
+ local_port = 0;
+ } else
+ local_port = ntohs(local_addr.sin_port);
++#else
++ snprintf(local_port, sizeof(local_port), "0");
++ } else {
++ getnameinfo((struct sockaddr *)&local_addr,
++ (socket_addr.ss_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in),
++ NULL, 0, local_port, sizeof(local_port),
++ NI_NUMERICHOST|NI_NUMERICSERV);
++ }
++#endif
+
+ if (getpeername(0, (struct sockaddr *) &socket_addr, &psize)) {
+ printf("Internal error - not running as either a daemon or under INETD.\n");
+@@ -166,6 +195,7 @@
+ closelog();
+ log(LOG_ERROR, "getpeername: ", strerror(errno));
+ exit(PROGRAM_BUG);
++#ifndef INET6
+ } else
+ remote_port = ntohs(socket_addr.sin_port);
+
+@@ -174,7 +204,14 @@
+ /* Get our host entry */
+ host_ent = (struct hostent *) gethostbyaddr((char *) &socket_addr.sin_addr,
+ sizeof(socket_addr.sin_addr), AF_INET);
+-
++#else
++ } else {
++ getnameinfo((struct sockaddr *)&socket_addr,
++ (socket_addr.ss_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in),
++ ip_address, sizeof(ip_address), remote_port, sizeof(remote_port),
++ NI_NUMERICHOST|NI_NUMERICSERV);
++ }
++#endif
+ /* And get our local-host name */
+ #ifndef ACTUAL_HOSTNAME
+ localhost = get_localhost();
+@@ -182,16 +219,31 @@
+ localhost = ACTUAL_HOSTNAME;
+ #endif
+
++#ifndef INET6
+ /* Make sure we can get the remote host's address name */
+ if (host_ent == NULL) {
+ remote_addr = inettos(socket_addr.sin_addr.s_addr);
++#else
++ /* Get our host entry and make sure we can get the remote host's address name */
++ if (getnameinfo((struct sockaddr *)&socket_addr,
++ (socket_addr.ss_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in),
++ remote_addr, sizeof(remote_addr), NULL, 0, NI_NAMEREQD) != 0) {
++ getnameinfo((struct sockaddr *)&socket_addr,
++ (socket_addr.ss_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in),
++ remote_addr, sizeof(remote_addr),
++ NULL, 0, NI_NUMERICHOST);
++#endif
+ 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);
++#ifndef INET6
+ } else
+ remote_addr = (char *) host_ent->h_name;
++#else
++ }
++#endif
+
+ /* Convert any uppercase letters in the hostname to lowercase */
+ for (cp = remote_addr; *cp; cp++)
+@@ -202,6 +254,9 @@
+ if (!strncasecmp(remote_addr, "127.0.0.1", 9) ||
+ !strncasecmp(remote_addr, "localhost", 9) ||
+ !strncasecmp(remote_addr, "127.0.0.0", 9) || /* KTH 07/26/96 */
++#ifdef INET6
++ !strncasecmp(remote_addr, "::1", 3) ||
++#endif
+ !strncasecmp(remote_addr, localhost, strlen(localhost)))
+ local_finger = TRUE;
+ else
+@@ -220,11 +275,25 @@
+ memset (ident_user, 0, sizeof (ident_user));
+ strcpy (ident_user, "emulated");
+ #ifndef ACTUAL_LOOPBACK
++#ifdef INET6
++ sprintf(remote_addr, "127.0.0.1");
++#else
+ remote_addr = "127.0.0.1";
++#endif
++#else
++#ifdef INET6
++ sprintf(remote_addr, ACTUAL_LOOPBACK);
+ #else
+ remote_addr = ACTUAL_LOOPBACK;
+ #endif
++#endif
+ }
++
++#ifdef INET6
++ /* If IPv4-mapped IPv6 address convert it to clean IPv4 */
++ if (strncmp(remote_addr, "::ffff:", 7) == 0)
++ strncpy(remote_addr, remote_addr + 7, sizeof(remote_addr));
++#endif
+
+ /* Now, let's check to make sure this site is trusted */
+ if ((!local_finger) && !emulated)
+Index: cfingerd/src/options.c
+diff -u cfingerd/src/options.c:1.1.1.1 cfingerd/src/options.c:1.2
+--- cfingerd/src/options.c:1.1.1.1 Sun Dec 12 12:23:27 1999
++++ cfingerd/src/options.c Sun Dec 12 13:07:49 1999
+@@ -1,6 +1,7 @@
+ /*
+ * CFINGERD
+ * Starting option routines
++ * IPv6 code Copyright (C) 1999 Arkadiusz Mi¶kiewicz <misiek@pld.org.pl>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+@@ -29,10 +30,19 @@
+ #ifdef DAEMON_MODE
+ pid_t pid;
+ int i, lsock, fd, clen;
++#ifdef INET6
++ int err = -1;
++#endif
+ int oval = 1;
++#ifdef INET6
++ struct sockaddr_storage caddr;
++ struct addrinfo hints, *res, *res0;
++#else
+ struct sockaddr caddr;
+ struct sockaddr_in laddr;
++#endif
+
++#ifndef INET6
+ if ((lsock = socket (AF_INET, SOCK_STREAM, 0)) < 0) {
+ syslog (LOG_ERR,"can't open socket: %m");
+ exit (1);
+@@ -51,6 +61,31 @@
+ syslog (LOG_ERR,"can't bind: %m");
+ exit (1);
+ }
++#else
++ memset(&hints, 0, sizeof(hints));
++ hints.ai_family = AF_UNSPEC;
++ hints.ai_socktype = SOCK_STREAM;
++ hints.ai_flags = AI_PASSIVE;
++ if(getaddrinfo(NULL, "79", &hints, &res0) < 0) {
++ syslog(LOG_ERR, "getaddrinfo() failed");
++ exit(1);
++ } else {
++ for (res = res0; res; res = res->ai_next) {
++ if (res->ai_family == AF_UNIX)
++ continue;
++ if ((lsock = socket (res->ai_family, res->ai_socktype, res->ai_protocol)) < 0)
++ continue;
++ if (bind (lsock, res->ai_addr, res->ai_addrlen) == 0) {
++ err = 0;
++ break;
++ }
++ }
++ freeaddrinfo(res0);
++ if (err < 0) {
++ syslog (LOG_ERR,"can't create socket or bind: %m");
++ exit (1);
++}
++#endif
+
+ if ((pid = fork()) < 0) {
+ syslog (LOG_ERR, "can't fork(): %m");
+@@ -77,20 +112,41 @@
+
+
+ while (1) {
++#ifdef INET6
++ fd = accept (lsock, (struct sockaddr *)&caddr, &clen);
++#else
+ fd = accept (lsock, &caddr, &clen);
++#endif
+ if (fd < 0) {
+ #ifndef __FreeBSD__
+ if (errno == EPROTO) {
+ #else
+ if (errno == EPROTOTYPE) {
+ #endif /* !__FreeBSD__ */
++#ifdef INET6
++ getnameinfo((struct sockaddr *)&caddr, (caddr.ss_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in),
++ remote_addr, sizeof(remote_addr), NULL, 0, NI_NUMERICHOST);
++ /* If IPv4-mapped IPv6 address convert it to clean IPv4 */
++ if (strncmp(remote_addr, "::ffff:", 7) == 0)
++ strncpy(remote_addr, remote_addr + 7, sizeof(remote_addr));
++#else
+ remote_addr = inet_ntoa (((struct sockaddr_in *)&caddr)->sin_addr);
++#endif
+ syslog(LOG_ERR,"failed connect (possible port scan) from %s: %m",
+ remote_addr);
+ }
+ continue;
+ }
++
++#ifdef INET6
++ getnameinfo((struct sockaddr *)&caddr, (caddr.ss_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in),
++ remote_addr, sizeof(remote_addr), NULL, 0, NI_NUMERICHOST);
++ /* If IPv4-mapped IPv6 address convert it to clean IPv4 */
++ if (strncmp(remote_addr, "::ffff:", 7) == 0)
++ strncpy(remote_addr, remote_addr + 7, sizeof(remote_addr));
++#else
+ remote_addr = inet_ntoa (((struct sockaddr_in *)&caddr)->sin_addr);
++#endif
+
+ /*
+ * FIXME: Support for tcp wrapper via hosts.allow and .deny is missing
+Index: cfingerd/src/proto.h
+diff -u cfingerd/src/proto.h:1.1.1.1 cfingerd/src/proto.h:1.2
+--- cfingerd/src/proto.h:1.1.1.1 Sun Dec 12 12:23:27 1999
++++ cfingerd/src/proto.h Sun Dec 12 13:07:49 1999
+@@ -45,7 +45,11 @@
+ void become_nobody(void);
+ void become_user(char *);
+ int wildmat(char *, char *);
++#ifdef INET6
++char *get_rfc1413_data(struct sockaddr_storage );
++#else
+ char *get_rfc1413_data(struct sockaddr_in );
++#endif
+ void check_unknown(char *);
+ void log(int, char *, char *);
+ void userlog(uid_t, gid_t, char *, char *);
+Index: cfingerd/src/rfc1413.c
+diff -u cfingerd/src/rfc1413.c:1.1.1.1 cfingerd/src/rfc1413.c:1.2
+--- cfingerd/src/rfc1413.c:1.1.1.1 Sun Dec 12 12:23:27 1999
++++ cfingerd/src/rfc1413.c Sun Dec 12 13:07:49 1999
+@@ -1,6 +1,7 @@
+ /*
+ * CFINGERD
+ * RFC1413 implementation
++ * IPv6 code Copyright (C) 1999 Arkadiusz Mi¶kiewicz <misiek@pld.org.pl>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+@@ -15,10 +16,18 @@
+
+ #include "cfingerd.h"
+
++#ifdef INET6
++static jmp_buf ident_alarm;
++#endif
++
+ void rfc1413_alarm(int signal)
+ {
++#ifdef INET6
++ siglongjmp(ident_alarm, 1);
++#else
+ if (signal == SIGALRM)
+ ident_user = "unknown@alarm.signal";
++#endif
+ }
+
+ /* Self contained RFC1413 implementation. Thanks to Joel Katz for parts of
+@@ -26,17 +35,28 @@
+ * contained in a single program. Simple, easy to use.
+ */
+ #define BUFLEN 256
++#ifdef INET6
++char *get_rfc1413_data( struct sockaddr_storage local_addr )
++{
++ static int j = -1, err = -1;
++#else
+ char *get_rfc1413_data( struct sockaddr_in local_addr )
+ {
+ int i, j;
+ struct sockaddr_in sin;
++#endif
+ char buffer[1024], buf[BUFLEN], uname[64], *bleah;
+ char *cp, *xp;
++#ifdef INET6
++ struct addrinfo hints, *res, *res0;
++#else
+ struct servent *serv;
++#endif
+
+ bleah = (char *) malloc(BUFLEN);
+ memset(bleah, 0, BUFLEN);
+
++#ifndef INET6
+ j = socket(AF_INET, SOCK_STREAM, 0);
+ if (j < 2) {
+ snprintf(bleah, BUFLEN, "unknown@%s", remote_addr);
+@@ -71,8 +91,54 @@
+ alarm(0);
+ return(bleah);
+ }
++
++ snprintf(buffer, sizeof(buffer), "%d,%d\n", remote_port, local_port);
++#else
++ memset(&hints, 0, sizeof(hints));
++ hints.ai_family = local_addr.ss_family;
++ hints.ai_socktype = SOCK_STREAM;
++ if((err = getaddrinfo(ip_address, "113", &hints, &res0)) < 0) {
++ syslog(LOG_ERR, "rfc1413-getaddrinfo: %s", gai_strerror(err));
++ snprintf(bleah, BUFLEN, "unknown@%s", remote_addr);
++ return(bleah);
++ }
++ err = -1;
++
++ if (sigsetjmp(ident_alarm, 1) != 0) {
++ snprintf(bleah, BUFLEN, "alarm.signal@%s", remote_addr);
++ return(bleah);
++ }
++ signal(SIGALRM, rfc1413_alarm);
++ alarm(5);
++ for (res = res0; res; res = res->ai_next) {
++ if ((j = socket(res->ai_family, res->ai_socktype, res->ai_protocol)))
++ continue;
++ switch(local_addr.ss_family) {
++ case AF_INET:
++ ((struct sockaddr_in *)&local_addr)->sin_port = 0;
++ break;
++ case AF_INET6:
++ ((struct sockaddr_in6 *)&local_addr)->sin6_port = 0;
++ break;
++ }
++ bind(j, (struct sockaddr *)&local_addr, (local_addr.ss_family == AF_INET6) ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in));
++ if (connect(j, res->ai_addr, res->ai_addrlen) < 0)
++ close(j);
++ else {
++ err = 0;
++ break;
++ }
++ }
++ freeaddrinfo(res0);
++ if (err < 0) {
++ syslog(LOG_ERR, "rfc1413-socket-or-connect problem");
++ snprintf(bleah, BUFLEN, "unknown@%s", remote_addr);
++ alarm(0);
++ return(bleah);
++ }
+
+- snprintf(buffer, sizeof(buffer), "%d,%d\n", remote_port, local_port);
++ snprintf(buffer, sizeof(buffer), "%s,%s\n", remote_port, local_port);
++#endif
+ write(j, buffer, strlen(buffer));
+
+ memset(buf, 0, sizeof(buf));
+Index: cfingerd/userlist/display.c
+diff -u cfingerd/userlist/display.c:1.1.1.1 cfingerd/userlist/display.c:1.2
+--- cfingerd/userlist/display.c:1.1.1.1 Sun Dec 12 12:23:27 1999
++++ cfingerd/userlist/display.c Sun Dec 12 13:06:29 1999
+@@ -60,6 +60,7 @@
+ int i;
+ char *our_host;
+ char *idle;
++ char *cp, *x;
+
+ our_host = get_localhost();
+ if (times_on == 0) {
diff --git a/cfingerd.spec b/cfingerd.spec
index 3abe9a6..bce05bc 100644
--- a/cfingerd.spec
+++ b/cfingerd.spec
@@ -10,7 +10,7 @@ Source0: http://www.infodrom.org/projects/cfingerd/download/%{name}-%{version}.t
# Source0-md5: fe9365f811624248aa3df52c4a832fc7
Source1: %{name}.logrotate
Source2: %{name}.inetd
-Patch0: http://www.misiek.eu.org/ipv6/%{name}-1.4.3-ipv6-12121999.patch.gz
+Patch0: %{name}-1.4.3-ipv6-12121999.patch
Patch1: %{name}-config.patch
Patch2: %{name}-security_format_bug.patch
Patch3: %{name}-gpg.patch