summaryrefslogtreecommitdiff
path: root/mail/qpopper/patches/patch-ai
blob: 30d34568eb8374f853916d8850c5ae5b4f2f6758 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
$NetBSD: patch-ai,v 1.3 1999/09/07 17:58:22 bad Exp $

--- pop_init.c.orig	Thu Jul  9 16:44:07 1998
+++ pop_init.c	Tue Sep  7 10:38:33 1999
@@ -44,6 +44,8 @@
 
 #include <popper.h>
 
+#include "sockunion.h"
+
 /* CNS Kerberos IV */
 #ifdef KERBEROS
 AUTH_DAT kdata;
@@ -75,9 +77,37 @@
 }
 #endif
 
+char *
+sock_ntop(p)
+    struct sockaddr *p;
+{
+#ifdef INET6
+    static char ntop_buf[INET6_ADDRSTRLEN];
+#else
+    static char ntop_buf[INET_ADDRSTRLEN];
+#endif
+    union sockunion *su;
+
+    su = (union sockunion *)p;
+    switch (su->su_family) {
+    case AF_INET:
+	inet_ntop(su->su_family, &su->su_sin.sin_addr, ntop_buf,
+	    sizeof(ntop_buf));
+	return ntop_buf;
+#ifdef INET6
+    case AF_INET6:
+	inet_ntop(su->su_family, &su->su_sin6.sin6_addr, ntop_buf,
+	    sizeof(ntop_buf));
+	return ntop_buf;
+#endif
+    default:
+	return "(unsupported AF)";
+    }
+}
+
 authenticate(p, addr)
      POP     *p;
-     struct sockaddr_in *addr;
+     union sockunion *addr;
 {
 
 #ifdef KERBEROS
@@ -87,10 +117,10 @@
     char version[9];
     int auth;
   
-    if (p->kerberos) {
+    if (p->kerberos && addr->su_family == AF_INET) {	/*XXX*/
 	strcpy(instance, "*");
 	auth = krb_recvauth(0L, 0, &ticket, KERBEROS_SERVICE, instance,
-			    addr, (struct sockaddr_in *) NULL,
+			    (struct sockaddr_in *)addr, (struct sockaddr_in *) NULL,
 			    &kdata, "", schedule, version);
 	
 	if (auth != KSUCCESS) {
@@ -105,7 +135,7 @@
 # ifdef DEBUG
 	if (p->debug)
 	    pop_log(p, POP_DEBUG, "%s.%s@%s (%s): ok", kdata.pname, 
-		kdata.pinst, kdata.prealm, inet_ntoa(addr->sin_addr));
+		kdata.pinst, kdata.prealm, sock_ntop(addr));
 # endif /* DEBUG */
 
 	strncpy(p->user, kdata.pname, sizeof(p->user));
@@ -126,7 +156,7 @@
 char    **      argmessage;
 {
 
-    struct sockaddr_in      cs;                 /*  Communication parameters */
+    union sockunion         cs;                 /*  Communication parameters */
     struct hostent      *   ch;                 /*  Client host information */
     int                     errflag = 0;
     int                     c;
@@ -272,13 +302,25 @@
 
     /*  Save the dotted decimal form of the client's IP address 
         in the POP parameter block */
-    p->ipaddr = (char *)strdup(inet_ntoa(cs.sin_addr));
+    p->ipaddr = (char *)strdup(sock_ntop(&cs));
 
     /*  Save the client's port */
-    p->ipport = ntohs(cs.sin_port);
+    p->ipport = ntohs(cs.su_port);
 
     /*  Get the canonical name of the host to whom I am speaking */
-    ch = gethostbyaddr((char *) &cs.sin_addr, sizeof(cs.sin_addr), AF_INET);
+    switch (cs.su_family) {
+    case AF_INET:
+	ch = gethostbyaddr((char *) &cs.su_sin.sin_addr, sizeof(cs.su_sin.sin_addr), AF_INET);
+	break;
+#ifdef INET6
+    case AF_INET6:
+	ch = gethostbyaddr((char *) &cs.su_sin6.sin6_addr, sizeof(cs.su_sin6.sin6_addr), AF_INET6);
+	break;
+#endif
+    default:
+	ch = NULL;
+	break;
+    }
     if (ch == NULL){
         pop_log(p,POP_PRIORITY,
             "(v%s) Unable to get canonical name of client, err = %d",
@@ -320,6 +362,7 @@
 
 	strncpy(h_name, ch->h_name, sizeof(h_name));
 
+#ifndef INET6
         /*  See if the name obtained for the client's IP 
             address returns an address */
         if ((ch_again = gethostbyname(h_name)) == NULL) {
@@ -336,7 +379,7 @@
             /*  Look for the client's IP address in the list returned 
                 for its name */
             for (addrp=ch_again->h_addr_list; *addrp; ++addrp)
-                if (bcmp(*addrp,&(cs.sin_addr),sizeof(cs.sin_addr)) == 0) break;
+		 if (bcmp(*addrp,&(cs.su_sin.sin_addr),sizeof(cs.su_sin.sin_addr)) == 0) break;
 
             if (!*addrp) {
                 pop_log (p,POP_PRIORITY,
@@ -345,6 +388,54 @@
                 p->client = p->ipaddr;
             }
         }
+#else
+      {
+	struct addrinfo hints, *res;
+	int error;
+
+	p->client = (char *)strdup(ch->h_name);
+
+        /*
+	 * See if the name obtained for the client's IP
+         * address returns an address
+         */
+	memset(&hints, 0, sizeof(hints));
+	hints.ai_flags = AI_CANONNAME;
+	hints.ai_family = AF_UNSPEC;
+	hints.ai_socktype = SOCK_STREAM;
+	hints.ai_protocol = 0;
+	error = getaddrinfo(h_name, NULL, &hints, &res);
+	if (error) {
+            pop_log(p,POP_PRIORITY,
+                "Client at \"%s\" resolves to an unknown host name \"%s\"",
+                    p->ipaddr, h_name);
+            p->client = p->ipaddr;
+	} else {
+	    for ( ; res; res = res->ai_next) {
+		if (res->ai_addr->sa_family == AF_INET) {
+		    if (!memcmp(&((struct sockaddr_in *)res->ai_addr)->sin_addr,
+			 &(cs.su_sin.sin_addr), sizeof(cs.su_sin.sin_addr))) {
+			break;
+		    }
+		} else if (res->ai_addr->sa_family == AF_INET6) {
+		    if (!memcmp(&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr,
+			 &(cs.su_sin6.sin6_addr), sizeof(cs.su_sin6.sin6_addr))) {
+			break;
+		    }
+		} else {
+		    break;
+		}
+	    }
+
+	    if (!res) {
+                pop_log (p,POP_PRIORITY,
+                    "Client address \"%s\" not listed for its host name \"%s\"",
+                        p->ipaddr,h_name);
+                p->client = p->ipaddr;
+	    }
+	}
+      }
+#endif
 
 #ifdef RES_DEFNAMES
 	/*