]> git.ipfire.org Git - thirdparty/glibc.git/blob - nss/nss_files/files-key.c
cf0a7d9ad9b909e9f8a67029bb41b22af8d2ccbb
[thirdparty/glibc.git] / nss / nss_files / files-key.c
1 /* Public key file parser in nss_files module.
2 Copyright (C) 1996-2020 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
18
19 #include <stdio.h>
20 #include <errno.h>
21 #include <string.h>
22 #include <netdb.h>
23 #include <rpc/key_prot.h>
24 #include <rpc/des_crypt.h>
25 #include "nsswitch.h"
26
27 NSS_DECLARE_MODULE_FUNCTIONS (files)
28
29 #define DATAFILE "/etc/publickey"
30
31
32 static enum nss_status
33 search (const char *netname, char *result, int *errnop, int secret)
34 {
35 FILE *stream = fopen (DATAFILE, "rce");
36 if (stream == NULL)
37 return errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
38
39 for (;;)
40 {
41 char buffer[HEXKEYBYTES * 2 + KEYCHECKSUMSIZE + MAXNETNAMELEN + 17];
42 char *p;
43 char *save_ptr;
44
45 buffer[sizeof (buffer) - 1] = '\xff';
46 p = fgets_unlocked (buffer, sizeof (buffer), stream);
47 if (p == NULL)
48 {
49 /* End of file or read error. */
50 *errnop = errno;
51 fclose (stream);
52 return NSS_STATUS_NOTFOUND;
53 }
54 else if (buffer[sizeof (buffer) - 1] != '\xff')
55 {
56 /* Invalid line in file? Skip remainder of line. */
57 if (buffer[sizeof (buffer) - 2] != '\0')
58 while (getc_unlocked (stream) != '\n')
59 continue;
60 continue;
61 }
62
63 /* Parse line. */
64 p = __strtok_r (buffer, "# \t:\n", &save_ptr);
65 if (p == NULL) /* Skip empty and comment lines. */
66 continue;
67 if (strcmp (p, netname) != 0)
68 continue;
69
70 /* A hit! Find the field we want and return. */
71 p = __strtok_r (NULL, ":\n", &save_ptr);
72 if (p == NULL) /* malformed line? */
73 continue;
74 if (secret)
75 p = __strtok_r (NULL, ":\n", &save_ptr);
76 if (p == NULL) /* malformed line? */
77 continue;
78 fclose (stream);
79 strcpy (result, p);
80 return NSS_STATUS_SUCCESS;
81 }
82 }
83
84 enum nss_status
85 _nss_files_getpublickey (const char *netname, char *pkey, int *errnop)
86 {
87 return search (netname, pkey, errnop, 0);
88 }
89
90 enum nss_status
91 _nss_files_getsecretkey (const char *netname, char *skey, char *passwd,
92 int *errnop)
93 {
94 enum nss_status status;
95 char buf[HEXKEYBYTES + KEYCHECKSUMSIZE + 16];
96
97 skey[0] = 0;
98
99 status = search (netname, buf, errnop, 1);
100 if (status != NSS_STATUS_SUCCESS)
101 return status;
102
103 if (!xdecrypt (buf, passwd))
104 return NSS_STATUS_SUCCESS;
105
106 if (memcmp (buf, &(buf[HEXKEYBYTES]), KEYCHECKSUMSIZE) != 0)
107 return NSS_STATUS_SUCCESS;
108
109 buf[HEXKEYBYTES] = 0;
110 strcpy (skey, buf);
111
112 return NSS_STATUS_SUCCESS;
113 }