Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 11 Jul 2005 11:08:14 GMT
From:      soc-bushman <soc-bushman@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 79976 for review
Message-ID:  <200507111108.j6BB8ExJ013721@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=79976

Change 79976 by soc-bushman@soc-bushman_stinger on 2005/07/11 11:07:56

	last submit

Affected files ...

.. //depot/projects/soc2005/nsswitch_cached/src/lib/libc/net/getservent.c#8 edit
.. //depot/projects/soc2005/nsswitch_cached/src/lib/libc/net/netdb_private.h#4 edit
.. //depot/projects/soc2005/nsswitch_cached/tests/ssh_keys/auth.c#2 edit
.. //depot/projects/soc2005/nsswitch_cached/tests/ssh_keys/auth.h#2 edit
.. //depot/projects/soc2005/nsswitch_cached/tests/ssh_keys/auth2-hostbased.c#2 edit
.. //depot/projects/soc2005/nsswitch_cached/tests/ssh_keys/auth2.c#2 edit
.. //depot/projects/soc2005/nsswitch_cached/tests/ssh_keys/hostfile.c#2 edit
.. //depot/projects/soc2005/nsswitch_cached/tests/ssh_keys/hostfile.h#2 edit
.. //depot/projects/soc2005/nsswitch_cached/tests/ssh_keys/key.h#2 edit
.. //depot/projects/soc2005/nsswitch_cached/tests/ssh_keys/sshconnect.c#2 edit

Differences ...

==== //depot/projects/soc2005/nsswitch_cached/src/lib/libc/net/getservent.c#8 (text+ko) ====

@@ -64,6 +64,9 @@
 {
 	SETSERVENT = 1,
 	ENDSERVENT = 2,
+	SERVENT_UNPACK_SUCCES = 3,
+	SERVENT_UNPACK_ERANGE = 4,
+	SERVENT_UNPACK_ERROR = 5,
 	SERVENT_STORAGE_INITIAL	= 1 << 10, /* 1 KByte */
 	SERVENT_STORAGE_MAX		= 1 << 20, /* 1 MByte */	
 };
@@ -79,7 +82,7 @@
 	{ NULL, 0 }
 };
 
-static	int	servent_unpack(char *, struct servent *, char **, size_t, int *);
+static	enum constants	servent_unpack(char *, struct servent *, char **, size_t);
 
 /* files backend declarations */
 struct files_state
@@ -132,25 +135,24 @@
 	};
 };
 
-static	int	wrap_getservbyname_r(struct key key, struct servent *serv, char *buffer, 
-			size_t bufsize, struct servent **res);
-static	int	wrap_getservbyport_r(struct key key, struct servent *serv, char *buffer, 
-			size_t bufsize, struct servent **res);
-static	int	wrap_getservent_r(struct key key, struct servent *serv, char *buffer,
-			size_t bufsize, struct servent **res);
-static	struct servent *getserv(int (*fn)(struct key, struct servent *, char *, 
-			size_t, struct servent **), struct key key);
+static	struct servent	*wrap_getservbyname_r(struct key key, struct servent *serv,
+			char *buffer, size_t bufsize);
+static	struct servent *wrap_getservbyport_r(struct key key, struct servent *serv,
+			char *buffer, size_t bufsize);
+static	struct servent	*wrap_getservent_r(struct key key, struct servent *serv,
+			char *buffer, size_t bufsize);
+static	struct servent *getserv(struct servent *(*fn)(struct key, struct servent *, char *, 
+			size_t), struct key key);
 				
 			
-static int
-servent_unpack(char *p, struct servent * serv, char ** aliases, size_t aliases_size,
-	int * errnop)
+static enum constants
+servent_unpack(char *p, struct servent * serv, char ** aliases, size_t aliases_size)
 {
 	char	*cp, **q, *endp;
 	long	l;		
 	
 	if (*p == '#')
-		return -1;
+		return SERVENT_UNPACK_ERROR;
 
 	memset(serv, 0, sizeof(struct servent));
 	
@@ -161,18 +163,18 @@
 
 	p = strpbrk(p, " \t");
 	if (p == NULL)
-		return -1;
+		return SERVENT_UNPACK_ERROR;
 	*p++ = '\0';
 	while (*p == ' ' || *p == '\t')
 		p++;
 	cp = strpbrk(p, ",/");
 	if (cp == NULL)
-		return -1;
+		return SERVENT_UNPACK_ERROR;
 
 	*cp++ = '\0';
 	l = strtol(p, &endp, 10);
 	if (endp == p || *endp != '\0' || l < 0 || l > USHRT_MAX)
-		return -1;
+		return SERVENT_UNPACK_ERROR;
 	serv->s_port = htons((in_port_t)l);
 	serv->s_proto = cp;
 
@@ -189,8 +191,7 @@
 			*q++ = cp;
 		} else {
 			*q = NULL;
-			*errnop = ERANGE;
-			return -1;
+			return SERVENT_UNPACK_ERANGE;
 		}
 		cp = strpbrk(cp, " \t");
 		if (cp != NULL)
@@ -198,7 +199,7 @@
 	}		
 	*q = NULL;
 
-	return 0;
+	return SERVENT_UNPACK_SUCCES;
 }
 
 /* files backend implementation */
@@ -249,7 +250,6 @@
 	struct servent *serv;
 	char		*buffer;
 	size_t	bufsize;
-	int		*errnop;
 	
 	char		**aliases;
 	int		aliases_size;	
@@ -278,19 +278,18 @@
 	serv = va_arg(ap, struct servent *);
 	buffer  = va_arg(ap, char *);
 	bufsize = va_arg(ap, size_t);
-	errnop = va_arg(ap,int *);
 	
-	*errnop = files_getstate(&st);
-	if (*errnop != 0)
+	rv = files_getstate(&st);
+	if (rv != 0) {
+		errno = rv;
 		return (NS_UNAVAIL);	
+	}
 	
 	if (st->fp == NULL)
 		st->compat_mode_active = 0;
 	
-	if (st->fp == NULL && (st->fp = fopen(_PATH_SERVICES, "r")) == NULL) {
-		*errnop = errno;
+	if (st->fp == NULL && (st->fp = fopen(_PATH_SERVICES, "r")) == NULL)
 		return (NS_UNAVAIL);	
-	}
 	
 	if (serv_mdata->how == nss_lt_all)
 		stayopen = 1;
@@ -303,7 +302,6 @@
 	do {			
 		if (!st->compat_mode_active) {
 			if ((line = fgetln(st->fp, &linesize)) == NULL) {
-				*errnop = errno;
 				rv = NS_RETURN;
 				break;
 			}
@@ -313,14 +311,14 @@
 					st->compat_mode_active = 1;
 			} else {			
 				if (bufsize <= linesize + _ALIGNBYTES + sizeof(char *)) {
-					*errnop = ERANGE;
+					errno = ERANGE;
 					rv = NS_RETURN;
 					break;
 				}
 				aliases = (char **)_ALIGN(&buffer[linesize+1]);
 				aliases_size = (buffer + bufsize - (char *)aliases)/sizeof(char *);
 				if (aliases_size < 1) {
-					*errnop = ERANGE;
+					errno = ERANGE;
 					rv = NS_RETURN;
 					break;
 				}
@@ -334,15 +332,15 @@
 			switch (serv_mdata->how) {
 			case nss_lt_name:
 				rv = nsdispatch(retval, compat_dtab, NSDB_SERVICES_COMPAT, "getservbyname_r",
-					compat_src, name, proto, serv, buffer, bufsize, errnop);
+					compat_src, name, proto, serv, buffer, bufsize);
 				break;
 			case nss_lt_id:
 				rv = nsdispatch(retval, compat_dtab, NSDB_SERVICES_COMPAT, "getservbyport_r",
-					compat_src, port, proto, serv, buffer, bufsize, errnop);
+					compat_src, port, proto, serv, buffer, bufsize);
 				break;
 			case nss_lt_all:
 				rv = nsdispatch(retval, compat_dtab, NSDB_SERVICES_COMPAT, "getservent_r",
-					compat_src, serv, buffer, bufsize, errnop);
+					compat_src, serv, buffer, bufsize);
 				break;
 			}
 			
@@ -352,17 +350,18 @@
 			continue;
 		}
 
-		rv = servent_unpack(line, serv, aliases, aliases_size, errnop);
-		if (rv !=0 ) {
-			if (*errnop == 0) {
-				rv = NS_NOTFOUND;
-				continue;
-			}
-			else {
-				rv = NS_RETURN;
-				break;
-			}
-		}
+		switch (servent_unpack(line, serv, aliases, aliases_size))
+		{
+		case SERVENT_UNPACK_ERROR:
+			rv = NS_NOTFOUND;			
+			continue;
+		case SERVENT_UNPACK_ERANGE:
+			errno = ERANGE;
+			rv = NS_RETURN;
+			goto fin;
+		default:
+			break;
+		};
 			
 		switch (serv_mdata->how) {
 		case nss_lt_name:
@@ -390,13 +389,14 @@
 		}
 		
 	} while (!(rv & NS_TERMINATE));
-	
+
+fin:	
 	if (!stayopen && st->fp!=NULL) {
 		fclose(st->fp);
 		st->fp = NULL;
 	}
 	
-	if ((rv ==NS_SUCCESS) && (retval != NULL))
+	if ((rv == NS_SUCCESS) && (retval != NULL))
 		*(struct servent **)retval=serv;
 	
 	return (rv);
@@ -463,7 +463,6 @@
 	struct servent *serv;
 	char		*buffer;
 	size_t	bufsize;
-	int		*errnop;
 	
 	char		**aliases;
 	int		aliases_size;
@@ -489,18 +488,15 @@
 	serv = va_arg(ap, struct servent *);
 	buffer  = va_arg(ap, char *);
 	bufsize = va_arg(ap, size_t);
-	errnop = va_arg(ap, int *);
 	
-	*errnop = nis_getstate(&st);
-	if (*errnop != 0)
+	rv = nis_getstate(&st);
+	if (rv != 0) {
+		errno = rv;
 		return (NS_UNAVAIL);
+	}
 	
-	if (st->yp_domain[0] == '\0') {
-		if (getdomainname(st->yp_domain, sizeof st->yp_domain)) {
-			*errnop=errno;
+	if ((st->yp_domain[0] == '\0') && (getdomainname(st->yp_domain, sizeof st->yp_domain)))
 			return (NS_UNAVAIL);
-		}
-	}
 
 	do {
 		switch (how)
@@ -567,7 +563,7 @@
 
 		/* we need a room for additional \n symbol */
 		if (bufsize <= resultbuflen +1 + _ALIGNBYTES + sizeof(char *)) {
-			*errnop = ERANGE;
+			errno = ERANGE;
 			rv = NS_RETURN;
 			break;
 		}
@@ -575,7 +571,7 @@
 		aliases=(char **)_ALIGN(&buffer[resultbuflen+2]);
 		aliases_size = (buffer + bufsize - (char *)aliases)/sizeof(char *);
 		if (aliases_size < 1) {
-			*errnop = ERANGE;
+			errno = ERANGE;
 			rv = NS_RETURN;
 			break;
 		}
@@ -585,15 +581,22 @@
 		buffer[resultbuflen] = '\n';
 		buffer[resultbuflen+1] = '\0';
 		
-		if (servent_unpack(buffer, serv, aliases, aliases_size, errnop) != 0) {
-			if (*errnop == 0)
-				rv = NS_NOTFOUND;
-			else
-				rv = NS_RETURN;
+		switch (servent_unpack(buffer, serv, aliases, aliases_size)) {
+		case SERVENT_UNPACK_ERANGE:
+			errno = ERANGE;
+			rv = NS_RETURN;
+			break;
+		case SERVENT_UNPACK_ERROR:
+			rv = NS_NOTFOUND;
+			break;
+		case SERVENT_UNPACK_SUCCES:
+			rv = NS_SUCCESS;
+			break;
+		default:
+			break;
 		}
+
 		free(resultbuf);
-		rv = NS_SUCCESS;
-
 	} while (!(rv & NS_TERMINATE) && (how == nss_lt_all));
 	
 fin:
@@ -665,9 +668,9 @@
 }
 
 /* get**_r functions implementation */
-int 
+struct servent *
 getservbyname_r(const char *name, const char *proto, 
-	struct servent *serv, char *buffer, size_t bufsize, struct servent **result)
+	struct servent *serv, char *buffer, size_t bufsize)
 {
 	static const struct servent_mdata mdata = { nss_lt_name, 0 };
 	static const struct servent_mdata compat_mdata = { nss_lt_name, 1 };
@@ -681,22 +684,22 @@
 		{ NULL, NULL, NULL }
 	};
 	
-	int	rv, ret_errno;
+	struct servent	*result;
+	int	rv;
 
-	ret_errno = 0;
-	*result = NULL;
-	rv = nsdispatch(result, dtab, NSDB_SERVICES, "getservbyname_r", defaultsrc,
-	    name, proto, serv, buffer, bufsize, &ret_errno);
+	result = NULL;
+	rv = nsdispatch(&result, dtab, NSDB_SERVICES, "getservbyname_r", defaultsrc,
+	    name, proto, serv, buffer, bufsize);
 	
 	if (rv == NS_SUCCESS)
-		return (0);
+		return (result);
 	else
-		return (ret_errno);	
+		return (NULL);	
 }
 
-int 
+struct servent *
 getservbyport_r(int port, const char *proto, struct servent *serv, char *buffer, 
-	size_t bufsize, struct servent **result)
+	size_t bufsize)
 {
 	static const struct servent_mdata mdata = { nss_lt_id, 0 };
 	static const struct servent_mdata compat_mdata = { nss_lt_id, 1 };
@@ -709,22 +712,22 @@
 		{ NSSRC_COMPAT, files_servent, (void *)&compat_mdata },
 		{ NULL, NULL, NULL }
 	};
-	int	rv, ret_errno;
+	
+	struct servent	*result;
+	int	rv;
 
-	ret_errno = 0;
-	*result = NULL;
-	rv = nsdispatch(result, dtab, NSDB_SERVICES, "getservbyport_r", defaultsrc,
-	    port, proto, serv, buffer, bufsize, &ret_errno);
+	result = NULL;
+	rv = nsdispatch(&result, dtab, NSDB_SERVICES, "getservbyport_r", defaultsrc,
+	    port, proto, serv, buffer, bufsize);
 	
 	if (rv == NS_SUCCESS)
-		return (0);
+		return (result);
 	else
-		return (ret_errno);		
+		return (NULL);
 }
 
-int
-getservent_r(struct servent *serv, char *buffer, size_t bufsize,
-	struct servent **result)
+struct servent *
+getservent_r(struct servent *serv, char *buffer, size_t bufsize)
 {
 	static const struct servent_mdata mdata = { nss_lt_all, 0 };
 	static const struct servent_mdata compat_mdata = { nss_lt_all, 1 };
@@ -737,17 +740,18 @@
 		{ NSSRC_COMPAT, files_servent, (void *)&compat_mdata },
 		{ NULL, NULL, NULL }
 	};
-	int	rv, ret_errno;
+	
+	struct servent	*result;
+	int	rv;
 
-	ret_errno = 0;
-	*result = NULL;
-	rv = nsdispatch(result, dtab, NSDB_SERVICES, "getservent_r", defaultsrc,
-	    serv, buffer, bufsize, &ret_errno);
+	result = NULL;
+	rv = nsdispatch(&result, dtab, NSDB_SERVICES, "getservent_r", defaultsrc,
+	    serv, buffer, bufsize);
 
 	if (rv == NS_SUCCESS)
-		return (0);
+		return (result);
 	else
-		return (ret_errno);		
+		return (NULL);		
 }
 
 void 
@@ -791,30 +795,26 @@
 	free(p);
 }
 
-static	int
-wrap_getservbyname_r(struct key key, struct servent *serv, char *buffer, size_t bufsize,
-    struct servent **res)
+static struct servent *
+wrap_getservbyname_r(struct key key, struct servent *serv, char *buffer, size_t bufsize)
 {
-	return (getservbyname_r(key.name, key.proto, serv, buffer, bufsize, res));
+	return (getservbyname_r(key.name, key.proto, serv, buffer, bufsize));
 }
 
-static	int
-wrap_getservbyport_r(struct key key, struct servent *serv, char *buffer, size_t bufsize,
-    struct servent **res)
+static struct servent *
+wrap_getservbyport_r(struct key key, struct servent *serv, char *buffer, size_t bufsize)
 {
-	return (getservbyport_r(key.port, key.proto, serv, buffer, bufsize, res));
+	return (getservbyport_r(key.port, key.proto, serv, buffer, bufsize));
 }
 
-static	int
-wrap_getservent_r(struct key key, struct servent *serv, char *buffer, size_t bufsize,
-    struct servent **res)
+static struct servent *
+wrap_getservent_r(struct key key, struct servent *serv, char *buffer, size_t bufsize)
 {
-	return (getservent_r(serv, buffer, bufsize, res));
+	return (getservent_r(serv, buffer, bufsize));
 }
 
 static struct servent *
-getserv(int (*fn)(struct key, struct servent *, char *, size_t, struct servent **),
-    struct key key)
+getserv(struct servent *(*fn)(struct key, struct servent *, char *, size_t), struct key key)
 {
 	int		 rv;
 	struct servent	*res;
@@ -833,12 +833,11 @@
 		st->bufsize = SERVENT_STORAGE_INITIAL;
 	}
 	do {
-		rv = fn(key, &st->serv, st->buffer, st->bufsize, &res);
-		if (res == NULL && rv == ERANGE) {
+		res = fn(key, &st->serv, st->buffer, st->bufsize);
+		if (res == NULL && errno == ERANGE) {
 			free(st->buffer);
 			if ((st->bufsize << 1) > SERVENT_STORAGE_MAX) {
 				st->buffer = NULL;
-				errno = ERANGE;
 				return (NULL);
 			}
 			st->bufsize <<= 1;
@@ -846,7 +845,7 @@
 			if (st->buffer == NULL)
 				return (NULL);
 		}
-	} while (res == NULL && rv == ERANGE);
+	} while (res == NULL && errno == ERANGE);
 	if (rv != 0)
 		errno = rv;
 	return (res);

==== //depot/projects/soc2005/nsswitch_cached/src/lib/libc/net/netdb_private.h#4 (text+ko) ====

@@ -134,11 +134,11 @@
 int getprotobyname_r(const char *, struct protoent *, struct protoent_data *);
 int getprotobynumber_r(int, struct protoent *, struct protoent_data *);
 int getprotoent_r(struct protoent *, struct protoent_data *);
-int getservbyname_r(const char *, const char *, struct servent *,
-	char *, size_t, struct servent **);
-int getservbyport_r(int, const char *, struct servent *,
-	char *, size_t, struct servent **);
-int getservent_r(struct servent *, char *, size_t, struct servent **);
+struct servent *getservbyname_r(const char *, const char *, struct servent *,
+	char *, size_t);
+struct servent *getservbyport_r(int, const char *, struct servent *,
+	char *, size_t);
+struct servent *getservent_r(struct servent *, char *, size_t);
 void sethostent_r(int, struct hostent_data *);
 void setnetent_r(int, struct netent_data *);
 void setprotoent_r(int, struct protoent_data *);

==== //depot/projects/soc2005/nsswitch_cached/tests/ssh_keys/auth.c#2 (text+ko) ====

@@ -399,8 +399,8 @@
 
 /* return ok if key exists in sysfile or userfile */
 HostStatus
-check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host,
-    const char *sysfile, const char *userfile)
+check_key_in_user_hostfile(struct passwd *pw, Key *key, const char *host,
+    const char *userfile)
 {
 	Key *found;
 	char *user_hostfile;
@@ -409,9 +409,9 @@
 
 	/* Check if we know the host and its host key. */
 	found = key_new(key->type);
-	host_status = check_host_in_hostfile(sysfile, host, key, found, NULL);
 
-	if (host_status != HOST_OK && userfile != NULL) {
+	host_status = HOST_NEW;
+	if (userfile != NULL) {
 		user_hostfile = tilde_expand_filename(userfile, pw->pw_uid);
 		if (options.strict_modes &&
 		    (stat(user_hostfile, &st) == 0) &&
@@ -435,6 +435,22 @@
 	return host_status;
 }
 
+/* return ok if key exists in sysfile or userfile */
+HostStatus
+check_key_in_nsswitch(struct passwd *pw, Key *key, const char *host)
+{
+	Key *found;
+	HostStatus host_status;
+
+	/* Check if we know the host and its host key. */
+	found = key_new(key->type);
+	host_status = nsswitch_check_host(host, key, found);
+	key_free(found);
+
+	debug2("check_key_in_nsswitch: key %s for %s", host_status == HOST_OK ?
+	    "ok" : "not found", host);
+	return host_status;
+}
 
 /*
  * Check a given file for security. This is defined as all components

==== //depot/projects/soc2005/nsswitch_cached/tests/ssh_keys/auth.h#2 (text+ko) ====

@@ -171,8 +171,11 @@
 secure_filename(FILE *, const char *, struct passwd *, char *, size_t);
 
 HostStatus
-check_key_in_hostfiles(struct passwd *, Key *, const char *,
-    const char *, const char *);
+check_key_in_user_hostfile(struct passwd *, Key *, const char *,
+    const char *);
+
+HostStatus
+check_key_in_nsswitch(struct passwd *, Key *, const char *);
 
 /* hostkey handling */
 Key	*get_hostkey_by_index(int);

==== //depot/projects/soc2005/nsswitch_cached/tests/ssh_keys/auth2-hostbased.c#2 (text+ko) ====

@@ -161,16 +161,18 @@
 	}
 	debug2("userauth_hostbased: access allowed by auth_rhosts2");
 
-	host_status = check_key_in_hostfiles(pw, key, lookup,
-	    _PATH_SSH_SYSTEM_HOSTFILE,
-	    options.ignore_user_known_hosts ? NULL : _PATH_SSH_USER_HOSTFILE);
+	host_status = check_key_in_nsswitch(pw, key, lookup);
+	
+	if (host_status == HOST_NEW) {
+		host_status = check_key_in_user_hostfile(pw, key, lookup,
+	    	options.ignore_user_known_hosts ? NULL : _PATH_SSH_USER_HOSTFILE);
 
-	/* backward compat if no key has been found. */
-	if (host_status == HOST_NEW)
-		host_status = check_key_in_hostfiles(pw, key, lookup,
-		    _PATH_SSH_SYSTEM_HOSTFILE2,
-		    options.ignore_user_known_hosts ? NULL :
-		    _PATH_SSH_USER_HOSTFILE2);
+		/* backward compat if no key has been found. */
+		if (host_status == HOST_NEW)
+			host_status = check_key_in_user_hostfile(pw, key, lookup,
+		    	options.ignore_user_known_hosts ? NULL :
+			    _PATH_SSH_USER_HOSTFILE2);
+	}
 
 	return (host_status == HOST_OK);
 }

==== //depot/projects/soc2005/nsswitch_cached/tests/ssh_keys/auth2.c#2 (text+ko) ====


==== //depot/projects/soc2005/nsswitch_cached/tests/ssh_keys/hostfile.c#2 (text+ko) ====

@@ -38,6 +38,9 @@
 #include "includes.h"
 RCSID("$OpenBSD: hostfile.c,v 1.34 2005/03/10 22:01:05 deraadt Exp $");
 
+#include <sys/types.h>
+#include <nsswitch.h>
+#include <stdarg.h>
 #include <resolv.h>
 #include <openssl/hmac.h>
 #include <openssl/sha.h>
@@ -48,6 +51,148 @@
 #include "hostfile.h"
 #include "log.h"
 #include "xmalloc.h"
+#include "pathnames.h"
+
+struct nsswitch_files_configuration {
+	char *system_hostfile;
+	char *system_hostfile2;
+};
+
+static	struct nsswitch_files_configuration	nsswitch_files_conf = {
+	_PATH_SSH_SYSTEM_HOSTFILE,
+	_PATH_SSH_SYSTEM_HOSTFILE2
+	};
+	
+void	nsswitch_set_system_hostfiles(char *system_hostfile, 
+	char *system_hostfile2)
+{
+	nsswitch_files_conf.system_hostfile = system_hostfile;
+	nsswitch_files_conf.system_hostfile2 = system_hostfile2;
+}
+
+static	HostStatus	check_host_in_hostfile_by_key_or_type(const char *, 
+	const char *, const Key *, int, Key *, int *);
+
+enum constants {
+	CHECK_HOST,
+	LOOKUP_KEY_BY_TYPE
+};
+
+static const ns_src defaultsrc[] = {
+	{ NSSRC_FILES, NS_SUCCESS },
+	{ NULL, 0 }
+};
+
+static	int	files_check_host_by_key_or_type(void *, void *, va_list);
+
+/* files backend implementation */
+static	int
+files_check_host_by_key_or_type(void *result, void *mdata, va_list ap)
+{
+	const char	*host;
+	const Key	*key;
+	Key		*found;
+	int		keytype;
+	
+	int rv, numret;
+	char * filename;
+	enum constants how;
+	
+	how = (enum constants)mdata;
+	switch (how) {
+	case CHECK_HOST:
+		host = va_arg(ap, const char *);
+		key = va_arg(ap, const Key *);
+		found = va_arg(ap, Key *);
+		break;
+	case LOOKUP_KEY_BY_TYPE:
+		host = va_arg(ap, const char *);
+		keytype = va_arg(ap, int);
+		found = va_arg(ap, Key *);
+		break;
+	default:
+		return NS_NOTFOUND;
+	}
+	
+	switch (how) {
+	case CHECK_HOST:	
+		filename = nsswitch_files_conf.system_hostfile;
+		rv = check_host_in_hostfile_by_key_or_type(filename, host, key, 0,
+	    	found, &numret);	
+		if (rv == HOST_NEW) {
+			filename = nsswitch_files_conf.system_hostfile2;
+			rv = check_host_in_hostfile_by_key_or_type(filename, host, key, 0,
+	    	found, &numret);	
+		}
+						
+		debug3("files_check_host_by_key_or_type: CHECK_HOST - %d", rv);			
+		if (result != NULL)
+			*((int *)result) = rv;
+		return ((rv == HOST_NEW) ? NS_NOTFOUND : NS_SUCCESS);
+	
+	case LOOKUP_KEY_BY_TYPE:
+		filename = nsswitch_files_conf.system_hostfile;
+		rv = (check_host_in_hostfile_by_key_or_type(filename, host, NULL,
+	    	keytype, found, &numret) == HOST_FOUND);		
+		if (rv == 0) {
+			filename = nsswitch_files_conf.system_hostfile2;
+			rv = (check_host_in_hostfile_by_key_or_type(filename, host, NULL,
+		    	keytype, found, &numret) == HOST_FOUND);
+		}
+
+		debug3("files_check_host_by_key_or_type: LOOKUP_KEY_BY_TYPE - %d", rv);			
+		if (result != NULL)
+			*((int *)result) = rv;
+		return ((rv == 0) ? NS_NOTFOUND : NS_SUCCESS);
+	}
+	
+	return (NS_NOTFOUND);
+}
+
+/* nsswitch interface functions implementation */
+HostStatus 
+nsswitch_check_host(const char *host, const Key *key, Key *found)
+{
+	static const ns_dtab dtab[] = {
+		{ NSSRC_FILES, files_check_host_by_key_or_type, (void *)CHECK_HOST },
+		{ NULL, NULL, NULL }
+	};
+	
+	int	rv;
+	HostStatus result;
+
+	if (key == NULL)
+		fatal("no key to look up");
+
+	result = HOST_NEW;
+	rv = nsdispatch(&result, dtab, NSDB_SSH_HOSTKEYS, "check_host_by_key", defaultsrc,
+	    host, key, found);
+	
+	if (rv == NS_SUCCESS)
+		return (result);
+	else
+		return (HOST_NEW);	
+}
+
+int	
+nsswitch_lookup_key_by_type(const char *host, int keytype, Key *found)
+{
+	static const ns_dtab dtab[] = {
+		{ NSSRC_FILES, files_check_host_by_key_or_type, (void *)LOOKUP_KEY_BY_TYPE },
+		{ NULL, NULL, NULL }
+	};
+	
+	int	rv, result;
+
+	result = 0;
+	rv = nsdispatch(&result, dtab, NSDB_SSH_HOSTKEYS, "lookup_key_by_type", defaultsrc,
+	    host, keytype, found);
+	
+	if (rv == NS_SUCCESS)
+		return (result);
+	else
+		return (0);
+}
 
 static int
 extract_salt(const char *s, u_int l, char *salt, size_t salt_len)

==== //depot/projects/soc2005/nsswitch_cached/tests/ssh_keys/hostfile.h#2 (text+ko) ====

@@ -30,4 +30,15 @@
 
 char	*host_hash(const char *, const char *, u_int);
 
+/*
+ * Nsswitch declarations
+ * Here 2 functions are defined. Both are equivalents of the correspondent
+ * *_hostfile functions (defined above). But functions below don't have the
+ * 'file' argument, because they use nsswitch data source instead
+ */
+
+void nsswitch_set_system_hostfiles(char *, char *);
+HostStatus nsswitch_check_host(const char *, const Key *, Key *);
+int	nsswitch_lookup_key_by_type(const char *, int, Key *);
+
 #endif

==== //depot/projects/soc2005/nsswitch_cached/tests/ssh_keys/key.h#2 (text+ko) ====


==== //depot/projects/soc2005/nsswitch_cached/tests/ssh_keys/sshconnect.c#2 (text+ko) ====

@@ -637,9 +637,9 @@
 	host_status = check_host_in_hostfile(host_file, host, host_key,
 	    file_key, &host_line);
 	if (host_status == HOST_NEW) {
-		host_file = system_hostfile;
-		host_status = check_host_in_hostfile(host_file, host, host_key,
-		    file_key, &host_line);
+		host_file = "nsswitch";
+		host_line = 0;
+		host_status = nsswitch_check_host(host, host_key, file_key);
 	}
 	/*
 	 * Also perform check for the ip address, skip the check if we are
@@ -652,9 +652,9 @@
 		ip_status = check_host_in_hostfile(ip_file, ip, host_key,
 		    ip_key, &ip_line);
 		if (ip_status == HOST_NEW) {
-			ip_file = system_hostfile;
-			ip_status = check_host_in_hostfile(ip_file, ip,
-			    host_key, ip_key, &ip_line);
+			ip_file = "nsswitch";
+			ip_line = 0;
+			ip_status = nsswitch_check_host(ip, host_key, ip_key);
 		}
 		if (host_status == HOST_CHANGED &&
 		    (ip_status != HOST_CHANGED || !key_equal(ip_key, file_key)))
@@ -1008,6 +1008,28 @@
 	return (ret);
 }
 
+static int
+show_key_from_nsswitch(const char *host, int keytype)
+{
+	Key *found;
+	char *fp;
+	int ret;
+
+	found = key_new(keytype);
+	if ((ret = nsswitch_lookup_key_by_type(host,
+	    keytype, found))) {
+		fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
+		logit("WARNING: %s key found for host %s\n"
+		    "via nsswitch\n"
+		    "%s key fingerprint %s.",
+		    key_type(found), host,
+		    key_type(found), fp);
+		xfree(fp);
+	}
+	key_free(found);
+	return (ret);	
+}
+
 /* print all known host keys for a given host, but skip keys of given type */
 static int
 show_other_keys(const char *host, Key *key)
@@ -1023,19 +1045,23 @@
 			found = 1;
 			continue;
 		}
-		if (type[i] != KEY_RSA1 &&
+/*		if (type[i] != KEY_RSA1 &&
 		    show_key_from_file(options.system_hostfile2, host, type[i])) {
 			found = 1;
 			continue;
-		}
+		}*/
 		if (show_key_from_file(options.user_hostfile, host, type[i])) {
 			found = 1;
 			continue;
 		}
-		if (show_key_from_file(options.system_hostfile, host, type[i])) {
+		if (show_key_from_nsswitch(host, type[i])) {
 			found = 1;
 			continue;
 		}
+/*		if (show_key_from_file(options.system_hostfile, host, type[i])) {
+			found = 1;
+			continue;
+		}*/		
 		debug2("no key of type %d for host %s", type[i], host);
 	}
 	return (found);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200507111108.j6BB8ExJ013721>