diff options
Diffstat (limited to 'REORG.TODO/nss/nss_files/files-key.c')
-rw-r--r-- | REORG.TODO/nss/nss_files/files-key.c | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/REORG.TODO/nss/nss_files/files-key.c b/REORG.TODO/nss/nss_files/files-key.c new file mode 100644 index 0000000000..11a574a0b1 --- /dev/null +++ b/REORG.TODO/nss/nss_files/files-key.c @@ -0,0 +1,111 @@ +/* Public key file parser in nss_files module. + Copyright (C) 1996-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include <stdio.h> +#include <errno.h> +#include <string.h> +#include <netdb.h> +#include <rpc/key_prot.h> +#include <rpc/des_crypt.h> +#include "nsswitch.h" + +#define DATAFILE "/etc/publickey" + + +static enum nss_status +search (const char *netname, char *result, int *errnop, int secret) +{ + FILE *stream = fopen (DATAFILE, "rce"); + if (stream == NULL) + return errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL; + + for (;;) + { + char buffer[HEXKEYBYTES * 2 + KEYCHECKSUMSIZE + MAXNETNAMELEN + 17]; + char *p; + char *save_ptr; + + buffer[sizeof (buffer) - 1] = '\xff'; + p = fgets_unlocked (buffer, sizeof (buffer), stream); + if (p == NULL) + { + /* End of file or read error. */ + *errnop = errno; + fclose (stream); + return NSS_STATUS_NOTFOUND; + } + else if (buffer[sizeof (buffer) - 1] != '\xff') + { + /* Invalid line in file? Skip remainder of line. */ + if (buffer[sizeof (buffer) - 2] != '\0') + while (getc_unlocked (stream) != '\n') + continue; + continue; + } + + /* Parse line. */ + p = __strtok_r (buffer, "# \t:\n", &save_ptr); + if (p == NULL) /* Skip empty and comment lines. */ + continue; + if (strcmp (p, netname) != 0) + continue; + + /* A hit! Find the field we want and return. */ + p = __strtok_r (NULL, ":\n", &save_ptr); + if (p == NULL) /* malformed line? */ + continue; + if (secret) + p = __strtok_r (NULL, ":\n", &save_ptr); + if (p == NULL) /* malformed line? */ + continue; + fclose (stream); + strcpy (result, p); + return NSS_STATUS_SUCCESS; + } +} + +enum nss_status +_nss_files_getpublickey (const char *netname, char *pkey, int *errnop) +{ + return search (netname, pkey, errnop, 0); +} + +enum nss_status +_nss_files_getsecretkey (const char *netname, char *skey, char *passwd, + int *errnop) +{ + enum nss_status status; + char buf[HEXKEYBYTES + KEYCHECKSUMSIZE + 16]; + + skey[0] = 0; + + status = search (netname, buf, errnop, 1); + if (status != NSS_STATUS_SUCCESS) + return status; + + if (!xdecrypt (buf, passwd)) + return NSS_STATUS_SUCCESS; + + if (memcmp (buf, &(buf[HEXKEYBYTES]), KEYCHECKSUMSIZE) != 0) + return NSS_STATUS_SUCCESS; + + buf[HEXKEYBYTES] = 0; + strcpy (skey, buf); + + return NSS_STATUS_SUCCESS; +} |