184 lines
5.1 KiB
Text
184 lines
5.1 KiB
Text
$NetBSD: patch-ad,v 1.3 1999/09/15 21:30:59 tron Exp $
|
|
|
|
--- pop_init.c.orig Fri Jul 10 01:44:07 1998
|
|
+++ pop_init.c Wed Sep 15 23:28:18 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
|
|
/*
|