From owner-p4-projects@FreeBSD.ORG Mon Jul 11 11:08:16 2005 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id C7AF616A420; Mon, 11 Jul 2005 11:08:15 +0000 (GMT) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 88AED16A41C for ; Mon, 11 Jul 2005 11:08:15 +0000 (GMT) (envelope-from soc-bushman@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 3D77043D53 for ; Mon, 11 Jul 2005 11:08:15 +0000 (GMT) (envelope-from soc-bushman@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id j6BB8F5S013724 for ; Mon, 11 Jul 2005 11:08:15 GMT (envelope-from soc-bushman@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id j6BB8ExJ013721 for perforce@freebsd.org; Mon, 11 Jul 2005 11:08:14 GMT (envelope-from soc-bushman@freebsd.org) Date: Mon, 11 Jul 2005 11:08:14 GMT Message-Id: <200507111108.j6BB8ExJ013721@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to soc-bushman@freebsd.org using -f From: soc-bushman To: Perforce Change Reviews Cc: Subject: PERFORCE change 79976 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 11 Jul 2005 11:08:16 -0000 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 +#include +#include #include #include #include @@ -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);