/*-
* SPDX-License-Identifier: BSD-3-Clause
*
* Copyright (c) 2009, Sun Microsystems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of Sun Microsystems, Inc. nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)publickey.c 1.10 91/03/11 Copyr 1986 Sun Micro";
#endif
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*
* publickey.c
* Copyright (C) 1986, Sun Microsystems, Inc.
*/
/*
* Public key lookup routines
*/
#include "namespace.h"
#include <stdio.h>
#include <pwd.h>
#include <rpc/rpc.h>
#include <rpc/key_prot.h>
#include <rpcsvc/yp_prot.h>
#include <rpcsvc/ypclnt.h>
#include <string.h>
#include <stdlib.h>
#include "un-namespace.h"
#define PKFILE "/etc/publickey"
/*
* Hack to let ypserv/rpc.nisd use AUTH_DES.
*/
int (*__getpublickey_LOCAL)(const char *, char *) = 0;
/*
* Get somebody's public key
*/
static int
__getpublickey_real(const char *netname, char *publickey)
{
char lookup[3 * HEXKEYBYTES];
char *p;
if (publickey == NULL)
return (0);
if (!getpublicandprivatekey(netname, lookup))
return (0);
p = strchr(lookup, ':');
if (p == NULL) {
return (0);
}
*p = '\0';
(void) strncpy(publickey, lookup, HEXKEYBYTES);
publickey[HEXKEYBYTES] = '\0';
return (1);
}
/*
* reads the file /etc/publickey looking for a + to optionally go to the
* yellow pages
*/
int
getpublicandprivatekey(const char *key, char *ret)
{
char buf[1024]; /* big enough */
char *res;
FILE *fd;
char *mkey;
char *mval;
fd = fopen(PKFILE, "r");
if (fd == NULL)
return (0);
for (;;) {
res = fgets(buf, sizeof(buf), fd);
if (res == NULL) {
fclose(fd);
return (0);
}
if (res[0] == '#')
continue;
else if (res[0] == '+') {
#ifdef YP
char *PKMAP = "publickey.byname";
char *lookup;
char *domain;
int err;
int len;
err = yp_get_default_domain(&domain);
if (err) {
continue;
}
lookup = NULL;
err = yp_match(domain, PKMAP, key, strlen(key), &lookup, &len);
if (err) {
#ifdef DEBUG
fprintf(stderr, "match failed error %d\n", err);
#endif
continue;
}
lookup[len] = 0;
strcpy(ret, lookup);
fclose(fd);
free(lookup);
return (2);
#else /* YP */
#ifdef DEBUG
fprintf(stderr,
"Bad record in %s '+' -- NIS not supported in this library copy\n", PKFILE);
#endif /* DEBUG */
continue;
#endif /* YP */
} else {
mkey = strsep(&res, "\t ");
if (mkey == NULL) {
fprintf(stderr,
"Bad record in %s -- %s", PKFILE, buf);
continue;
}
do {
mval = strsep(&res, " \t#\n");
} while (mval != NULL && !*mval);
if (mval == NULL) {
fprintf(stderr,
"Bad record in %s val problem - %s", PKFILE, buf);
continue;
}
if (strcmp(mkey, key) == 0) {
strcpy(ret, mval);
fclose(fd);
return (1);
}
}
}
}
int getpublickey(const char *netname, char *publickey)
{
if (__getpublickey_LOCAL != NULL)
return(__getpublickey_LOCAL(netname, publickey));
else
return(__getpublickey_real(netname, publickey));
}