]> git.pld-linux.org Git - packages/cfingerd.git/blob - cfingerd-1.4.3-ipv6-12121999.patch
- store patch in decompressed file
[packages/cfingerd.git] / cfingerd-1.4.3-ipv6-12121999.patch
1 ;
2 ; IPv6 patch for cfingerd 1.4.3 daemon.
3 ; System with working getaddrinfo(), getnameinfo(),
4 ; functions and defined struct sockaddr_storage required
5 ; (ie. Linux 2.2.x with glibc 2.1.1 or *BSD/KAME)
6 ;
7 ;          Arkadiusz Mi¶kiewicz <misiek@pld.org.pl>, PLD/Linux
8 ;
9 Index: cfingerd/CHANGES
10 diff -u cfingerd/CHANGES:1.1.1.1 cfingerd/CHANGES:1.2
11 --- cfingerd/CHANGES:1.1.1.1    Sun Dec 12 12:23:27 1999
12 +++ cfingerd/CHANGES    Sun Dec 12 13:07:49 1999
13 @@ -1,3 +1,6 @@
14 +CFINGERD 1.4.4 ??/??/??
15 +  - full IPv6 support !
16 +
17  CFINGERD 1.4.3 09/29/99
18    - Security update, fixes buffer overflows introduced with sscanf(),
19      exploitable under FreeBSD
20 Index: cfingerd/src/cfingerd.h
21 diff -u cfingerd/src/cfingerd.h:1.1.1.1 cfingerd/src/cfingerd.h:1.2
22 --- cfingerd/src/cfingerd.h:1.1.1.1     Sun Dec 12 12:23:27 1999
23 +++ cfingerd/src/cfingerd.h     Sun Dec 12 13:07:49 1999
24 @@ -28,6 +28,9 @@
25  #include <ctype.h>
26  #include <time.h>
27  #include <pwd.h>
28 +#ifdef INET6
29 +#include <setjmp.h>
30 +#endif
31  
32  #include <netinet/in.h>
33  #include <sys/socket.h>
34 @@ -278,10 +281,20 @@
35  
36  extern CONFIG prog_config;
37  extern ECRUFT errors[];
38 +#ifdef INET6
39 +extern char *localhost, *ident_user;
40 +extern char remote_addr[100], ip_address[100];
41 +#else
42  extern char *remote_addr, *localhost, *ident_user, *ip_address;
43 +#endif
44  extern int trusted_host_num, rejected_host_num, forward_host_num,
45 +#ifndef INET6
46            fakeuser_num, num_finger_sites, num_headers, local_port,
47            remote_port, can_log;
48 +#else
49 +          fakeuser_num, num_finger_sites, num_headers, can_log;
50 +extern char local_port[32], remote_port[32];
51 +#endif
52  extern FILE *top_display, *bottom_display, *noname_display, *nouser_display,
53             *rejected_display, *identd_display;
54  extern BOOL local_finger, emulated;
55 Index: cfingerd/src/main.c
56 diff -u cfingerd/src/main.c:1.1.1.1 cfingerd/src/main.c:1.2
57 --- cfingerd/src/main.c:1.1.1.1 Sun Dec 12 12:23:27 1999
58 +++ cfingerd/src/main.c Sun Dec 12 13:07:49 1999
59 @@ -1,6 +1,7 @@
60  /*
61   * CFINGERD
62   * Main Routine
63 + * IPv6 code Copyright (C) 1999 Arkadiusz Mi¶kiewicz <misiek@pld.org.pl>
64   *
65   * This program is free software; you can redistribute it and/or modify
66   * it under the terms of the GNU General Public License as published by
67 @@ -20,11 +21,21 @@
68  #include "privs.h"
69  
70  CONFIG prog_config;
71 +#ifdef INET6
72 +char *localhost, *ident_user;
73 +char remote_addr[100];
74 +char ip_address[100];
75 +#else
76  char *remote_addr, *localhost, *ident_user, *ip_address;
77 +#endif
78  FILE *top_display, *bottom_display, *noname_display, *nouser_display,
79       *rejected_display, *identd_display;
80  BOOL local_finger, emulated; 
81 +#ifdef INET6
82 +char local_port[32], remote_port[32];
83 +#else
84  int local_port, remote_port;
85 +#endif
86  unsigned short listen_port;
87  unsigned long listen_addr;
88  
89 @@ -62,6 +73,7 @@
90      char line[100], username[80], syslog_str[200];
91      int un_type;
92      char *cp;
93 +#ifndef INET6
94      struct sockaddr_in local_addr;
95      struct servent *serv;
96  
97 @@ -70,6 +82,9 @@
98      else
99         listen_port = htons(79);
100      listen_addr = htonl(INADDR_ANY);
101 +#else
102 +    struct sockaddr_storage local_addr;
103 +#endif
104  
105      /* Initialize CFINGERD */
106      start_handler();
107 @@ -147,8 +162,12 @@
108      /* If we're not doing emulated stuff, we can assume that we are running
109         either as a daemon, or under INETD.  In that case... */
110      if (!emulated) {
111 +#ifdef INET6
112 +       struct sockaddr_storage socket_addr;
113 +#else
114         struct sockaddr_in socket_addr;
115         struct hostent *host_ent;
116 +#endif
117         int psize = 0;
118  
119         /* Can't run from command line (but this should already be checked) */
120 @@ -156,9 +175,19 @@
121  
122         if (getsockname(0, (struct sockaddr *) &local_addr, &psize)) {
123             syslog(LOG_WARNING, "getsockname: %s", strerror(errno));
124 +#ifndef INET6
125             local_port = 0;
126         } else
127             local_port = ntohs(local_addr.sin_port);
128 +#else
129 +           snprintf(local_port, sizeof(local_port), "0");
130 +       } else {
131 +               getnameinfo((struct sockaddr *)&local_addr,
132 +                               (socket_addr.ss_family == AF_INET6)  ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in),
133 +                               NULL, 0, local_port, sizeof(local_port),
134 +                               NI_NUMERICHOST|NI_NUMERICSERV);
135 +       }
136 +#endif
137  
138         if (getpeername(0, (struct sockaddr *) &socket_addr, &psize)) {
139             printf("Internal error - not running as either a daemon or under INETD.\n");
140 @@ -166,6 +195,7 @@
141             closelog();
142             log(LOG_ERROR, "getpeername: ", strerror(errno));
143             exit(PROGRAM_BUG);
144 +#ifndef INET6
145         } else
146             remote_port = ntohs(socket_addr.sin_port);
147  
148 @@ -174,7 +204,14 @@
149         /* Get our host entry */
150         host_ent = (struct hostent *) gethostbyaddr((char *) &socket_addr.sin_addr,
151                    sizeof(socket_addr.sin_addr), AF_INET);
152 -
153 +#else
154 +       } else {
155 +               getnameinfo((struct sockaddr *)&socket_addr,
156 +                               (socket_addr.ss_family == AF_INET6)  ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in),
157 +                               ip_address, sizeof(ip_address), remote_port, sizeof(remote_port),
158 +                               NI_NUMERICHOST|NI_NUMERICSERV);
159 +       }
160 +#endif
161         /* And get our local-host name */
162  #ifndef        ACTUAL_HOSTNAME
163         localhost = get_localhost();
164 @@ -182,16 +219,31 @@
165         localhost = ACTUAL_HOSTNAME;
166  #endif
167  
168 +#ifndef INET6
169         /* Make sure we can get the remote host's address name */
170         if (host_ent == NULL) {
171             remote_addr = inettos(socket_addr.sin_addr.s_addr);
172 +#else
173 +       /* Get our host entry and make sure we can get the remote host's address name */
174 +       if (getnameinfo((struct sockaddr *)&socket_addr,
175 +               (socket_addr.ss_family == AF_INET6)  ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in),
176 +               remote_addr, sizeof(remote_addr), NULL, 0, NI_NAMEREQD) != 0) {
177 +                       getnameinfo((struct sockaddr *)&socket_addr,
178 +                               (socket_addr.ss_family == AF_INET6)  ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in),
179 +                               remote_addr, sizeof(remote_addr),
180 +                               NULL, 0, NI_NUMERICHOST);
181 +#endif
182             syslog(LOG_WARNING, "%s %s", 
183                 prog_config.p_strings[D_IP_NO_MATCH],
184                 remote_addr);
185             if (!(prog_config.config_bits2 & SHOW_IP_MATCH))
186                 CF_ERROR(E_NOIP);
187 +#ifndef INET6
188         } else
189             remote_addr = (char *) host_ent->h_name;
190 +#else
191 +       }
192 +#endif
193  
194         /* Convert any uppercase letters in the hostname to lowercase */
195         for (cp = remote_addr; *cp; cp++)
196 @@ -202,6 +254,9 @@
197         if (!strncasecmp(remote_addr, "127.0.0.1", 9) ||
198             !strncasecmp(remote_addr, "localhost", 9) ||
199             !strncasecmp(remote_addr, "127.0.0.0", 9) || /* KTH 07/26/96 */
200 +#ifdef INET6
201 +           !strncasecmp(remote_addr, "::1", 3) ||
202 +#endif
203             !strncasecmp(remote_addr, localhost, strlen(localhost)))
204             local_finger = TRUE;
205         else
206 @@ -220,11 +275,25 @@
207         memset (ident_user, 0, sizeof (ident_user));
208         strcpy (ident_user, "emulated");
209  #ifndef        ACTUAL_LOOPBACK
210 +#ifdef INET6
211 +       sprintf(remote_addr, "127.0.0.1");
212 +#else
213         remote_addr = "127.0.0.1";
214 +#endif
215 +#else
216 +#ifdef INET6
217 +       sprintf(remote_addr, ACTUAL_LOOPBACK);
218  #else
219         remote_addr = ACTUAL_LOOPBACK;
220  #endif
221 +#endif
222      }
223 +
224 +#ifdef INET6
225 +    /* If IPv4-mapped IPv6 address convert it to clean IPv4 */
226 +    if (strncmp(remote_addr, "::ffff:", 7) == 0)
227 +               strncpy(remote_addr, remote_addr + 7, sizeof(remote_addr));
228 +#endif
229  
230      /* Now, let's check to make sure this site is trusted */
231      if ((!local_finger) && !emulated)
232 Index: cfingerd/src/options.c
233 diff -u cfingerd/src/options.c:1.1.1.1 cfingerd/src/options.c:1.2
234 --- cfingerd/src/options.c:1.1.1.1      Sun Dec 12 12:23:27 1999
235 +++ cfingerd/src/options.c      Sun Dec 12 13:07:49 1999
236 @@ -1,6 +1,7 @@
237  /*
238   * CFINGERD
239   * Starting option routines
240 + * IPv6 code Copyright (C) 1999 Arkadiusz Mi¶kiewicz <misiek@pld.org.pl>
241   *
242   * This program is free software; you can redistribute it and/or modify
243   * it under the terms of the GNU General Public License as published by
244 @@ -29,10 +30,19 @@
245  #ifdef DAEMON_MODE
246      pid_t pid;
247      int i, lsock, fd, clen;
248 +#ifdef INET6
249 +    int err = -1;
250 +#endif
251      int oval = 1;
252 +#ifdef INET6
253 +    struct sockaddr_storage caddr;
254 +    struct addrinfo hints, *res, *res0;
255 +#else
256      struct sockaddr caddr;
257      struct sockaddr_in laddr;
258 +#endif
259  
260 +#ifndef INET6
261      if ((lsock = socket (AF_INET, SOCK_STREAM, 0)) < 0) {
262         syslog (LOG_ERR,"can't open socket: %m");
263         exit (1);
264 @@ -51,6 +61,31 @@
265         syslog (LOG_ERR,"can't bind: %m");
266         exit (1);
267      }
268 +#else
269 +    memset(&hints, 0, sizeof(hints));
270 +    hints.ai_family   = AF_UNSPEC;
271 +    hints.ai_socktype = SOCK_STREAM;
272 +    hints.ai_flags    = AI_PASSIVE;
273 +    if(getaddrinfo(NULL, "79", &hints, &res0) < 0) {
274 +           syslog(LOG_ERR, "getaddrinfo() failed");
275 +           exit(1);
276 +    } else {
277 +           for (res = res0; res; res = res->ai_next) {
278 +                   if (res->ai_family == AF_UNIX)
279 +                           continue;
280 +                   if ((lsock = socket (res->ai_family, res->ai_socktype, res->ai_protocol)) < 0)
281 +                           continue;
282 +                   if (bind (lsock, res->ai_addr, res->ai_addrlen) == 0) {
283 +                           err = 0;
284 +                           break;
285 +                   }
286 +           }
287 +           freeaddrinfo(res0);
288 +           if (err < 0) {
289 +                   syslog (LOG_ERR,"can't create socket or bind: %m");
290 +                   exit (1);
291 +}
292 +#endif
293  
294      if ((pid = fork()) < 0) {
295         syslog (LOG_ERR, "can't fork(): %m");
296 @@ -77,20 +112,41 @@
297  
298  
299      while (1) {
300 +#ifdef INET6
301 +       fd = accept (lsock, (struct sockaddr *)&caddr, &clen);
302 +#else
303         fd = accept (lsock, &caddr, &clen);
304 +#endif
305         if (fd < 0) {
306  #ifndef __FreeBSD__
307             if (errno == EPROTO) {
308  #else
309             if (errno == EPROTOTYPE) {
310  #endif /* !__FreeBSD__ */
311 +#ifdef INET6
312 +        getnameinfo((struct sockaddr *)&caddr, (caddr.ss_family == AF_INET6)  ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in),
313 +               remote_addr, sizeof(remote_addr), NULL, 0, NI_NUMERICHOST);
314 +        /* If IPv4-mapped IPv6 address convert it to clean IPv4 */
315 +        if (strncmp(remote_addr, "::ffff:", 7) == 0)
316 +               strncpy(remote_addr, remote_addr + 7, sizeof(remote_addr));
317 +#else
318                 remote_addr = inet_ntoa (((struct sockaddr_in *)&caddr)->sin_addr);
319 +#endif
320                 syslog(LOG_ERR,"failed connect (possible port scan) from %s: %m",
321                        remote_addr);
322             }
323             continue;
324         }
325 +
326 +#ifdef INET6
327 +       getnameinfo((struct sockaddr *)&caddr, (caddr.ss_family == AF_INET6)  ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in),
328 +                remote_addr, sizeof(remote_addr), NULL, 0, NI_NUMERICHOST);
329 +       /* If IPv4-mapped IPv6 address convert it to clean IPv4 */
330 +       if (strncmp(remote_addr, "::ffff:", 7) == 0)
331 +               strncpy(remote_addr, remote_addr + 7, sizeof(remote_addr));
332 +#else
333         remote_addr = inet_ntoa (((struct sockaddr_in *)&caddr)->sin_addr);
334 +#endif
335  
336         /*
337          * FIXME: Support for tcp wrapper via hosts.allow and .deny is missing
338 Index: cfingerd/src/proto.h
339 diff -u cfingerd/src/proto.h:1.1.1.1 cfingerd/src/proto.h:1.2
340 --- cfingerd/src/proto.h:1.1.1.1        Sun Dec 12 12:23:27 1999
341 +++ cfingerd/src/proto.h        Sun Dec 12 13:07:49 1999
342 @@ -45,7 +45,11 @@
343  void become_nobody(void);
344  void become_user(char *);
345  int wildmat(char *, char *);
346 +#ifdef INET6
347 +char *get_rfc1413_data(struct sockaddr_storage );
348 +#else
349  char *get_rfc1413_data(struct sockaddr_in );
350 +#endif
351  void check_unknown(char *);
352  void log(int, char *, char *);
353  void userlog(uid_t, gid_t, char *, char *);
354 Index: cfingerd/src/rfc1413.c
355 diff -u cfingerd/src/rfc1413.c:1.1.1.1 cfingerd/src/rfc1413.c:1.2
356 --- cfingerd/src/rfc1413.c:1.1.1.1      Sun Dec 12 12:23:27 1999
357 +++ cfingerd/src/rfc1413.c      Sun Dec 12 13:07:49 1999
358 @@ -1,6 +1,7 @@
359  /*
360   * CFINGERD
361   * RFC1413 implementation
362 + * IPv6 code Copyright (C) 1999 Arkadiusz Mi¶kiewicz <misiek@pld.org.pl>
363   *
364   * This program is free software; you can redistribute it and/or modify
365   * it under the terms of the GNU General Public License as published by
366 @@ -15,10 +16,18 @@
367  
368  #include "cfingerd.h"
369  
370 +#ifdef INET6
371 +static jmp_buf ident_alarm;
372 +#endif
373 +
374  void rfc1413_alarm(int signal)
375  {
376 +#ifdef INET6
377 +    siglongjmp(ident_alarm, 1);
378 +#else
379      if (signal == SIGALRM)
380         ident_user = "unknown@alarm.signal";
381 +#endif
382  }
383  
384  /* Self contained RFC1413 implementation.  Thanks to Joel Katz for parts of
385 @@ -26,17 +35,28 @@
386   * contained in a single program.  Simple, easy to use.
387   */
388  #define BUFLEN 256
389 +#ifdef INET6
390 +char *get_rfc1413_data( struct sockaddr_storage local_addr )
391 +{
392 +    static int j = -1, err = -1;
393 +#else
394  char *get_rfc1413_data( struct sockaddr_in local_addr )
395  {
396      int i, j;
397      struct sockaddr_in sin;
398 +#endif
399      char buffer[1024], buf[BUFLEN], uname[64], *bleah;
400      char *cp, *xp;
401 +#ifdef INET6
402 +    struct addrinfo hints, *res, *res0;
403 +#else
404      struct servent *serv;
405 +#endif
406  
407      bleah = (char *) malloc(BUFLEN);
408      memset(bleah, 0, BUFLEN);
409  
410 +#ifndef INET6
411      j = socket(AF_INET, SOCK_STREAM, 0);
412      if (j < 2) {
413         snprintf(bleah, BUFLEN, "unknown@%s", remote_addr);
414 @@ -71,8 +91,54 @@
415         alarm(0);
416         return(bleah);
417      }
418 +     
419 +     snprintf(buffer, sizeof(buffer), "%d,%d\n", remote_port, local_port);
420 +#else
421 +    memset(&hints, 0, sizeof(hints));
422 +    hints.ai_family = local_addr.ss_family;
423 +    hints.ai_socktype = SOCK_STREAM;
424 +    if((err = getaddrinfo(ip_address, "113", &hints, &res0)) < 0) {
425 +           syslog(LOG_ERR, "rfc1413-getaddrinfo: %s", gai_strerror(err));
426 +           snprintf(bleah, BUFLEN, "unknown@%s", remote_addr);
427 +           return(bleah);
428 +    } 
429 +    err = -1;
430 +
431 +    if (sigsetjmp(ident_alarm, 1) != 0) {
432 +           snprintf(bleah, BUFLEN, "alarm.signal@%s", remote_addr);
433 +           return(bleah);
434 +    }
435 +    signal(SIGALRM, rfc1413_alarm);
436 +    alarm(5);
437 +    for (res = res0; res; res = res->ai_next) {
438 +           if ((j = socket(res->ai_family, res->ai_socktype, res->ai_protocol)))
439 +                   continue;
440 +           switch(local_addr.ss_family) {
441 +                   case AF_INET:
442 +                           ((struct sockaddr_in *)&local_addr)->sin_port = 0;
443 +                           break;
444 +                   case AF_INET6:
445 +                           ((struct sockaddr_in6 *)&local_addr)->sin6_port = 0;
446 +                          break;
447 +           }
448 +           bind(j, (struct sockaddr *)&local_addr, (local_addr.ss_family == AF_INET6)  ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in));
449 +           if (connect(j, res->ai_addr, res->ai_addrlen) < 0)
450 +                   close(j);
451 +           else {
452 +                   err = 0;
453 +                   break;
454 +           }
455 +    }
456 +    freeaddrinfo(res0);
457 +    if (err < 0) {
458 +           syslog(LOG_ERR, "rfc1413-socket-or-connect problem");
459 +           snprintf(bleah, BUFLEN, "unknown@%s", remote_addr);
460 +           alarm(0);
461 +           return(bleah);
462 +     }
463  
464 -    snprintf(buffer, sizeof(buffer), "%d,%d\n", remote_port, local_port);
465 +    snprintf(buffer, sizeof(buffer), "%s,%s\n", remote_port, local_port);
466 +#endif
467      write(j, buffer, strlen(buffer));
468  
469      memset(buf, 0, sizeof(buf));
470 Index: cfingerd/userlist/display.c
471 diff -u cfingerd/userlist/display.c:1.1.1.1 cfingerd/userlist/display.c:1.2
472 --- cfingerd/userlist/display.c:1.1.1.1 Sun Dec 12 12:23:27 1999
473 +++ cfingerd/userlist/display.c Sun Dec 12 13:06:29 1999
474 @@ -60,6 +60,7 @@
475      int i;
476      char *our_host;
477      char *idle;
478 +    char *cp, *x;
479  
480      our_host = get_localhost();
481      if (times_on == 0) {
This page took 0.08615 seconds and 3 git commands to generate.