Print this page
10116 mech_dh needs smatch fixes
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/gss_mechs/mech_dh/dh_common/dh_template.c
+++ new/usr/src/lib/gss_mechs/mech_dh/dh_common/dh_template.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License, Version 1.0 only
6 6 * (the "License"). You may not use this file except in compliance
7 7 * with the License.
8 8 *
9 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 10 * or http://www.opensolaris.org/os/licensing.
11 11 * See the License for the specific language governing permissions
12 12 * and limitations under the License.
13 13 *
14 14 * When distributing Covered Code, include this CDDL HEADER in each
15 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 16 * If applicable, add the following below this CDDL HEADER, with the
17 17 * fields enclosed by brackets "[]" replaced with your own identifying
18 18 * information: Portions Copyright [yyyy] [name of copyright owner]
↓ open down ↓ |
18 lines elided |
↑ open up ↑ |
19 19 *
20 20 * CDDL HEADER END
21 21 */
22 22 /*
23 23 * dh_template.c
24 24 *
25 25 * Copyright (c) 1997, by Sun Microsystems, Inc.
26 26 * All rights reserved.
27 27 */
28 28
29 -#pragma ident "%Z%%M% %I% %E% SMI"
29 +/*
30 + * Copyright (c) 2018, Joyent, Inc.
31 + */
30 32
31 33 #include <stdlib.h>
32 34 #include <string.h>
33 35 #include <syslog.h>
34 36 #include <dh_gssapi.h>
35 37 #include <dlfcn.h>
36 38 #include "../dh_common/dh_common.h"
37 39
38 40 extern int key_encryptsession_pk_g();
39 41 extern int key_decryptsession_pk_g();
40 42 extern int key_gendes_g();
41 43 extern int key_secretkey_is_set_g();
42 44
43 45 static int __encrypt(const char *remotename, des_block deskeys[], int no_keys);
44 46 static int __decrypt(const char *remotename,
45 47 des_block deskeys[], int no_keys, int *key_cached);
46 48 static int __gendes(des_block deskeys[], int no_keys);
47 49 static int __secret_is_set(void);
48 50 static char *__get_principal(void);
49 51
50 52 /*
51 53 * This module defines the entry point for gss_mech_initialize and the
52 54 * key opts for Diffie-Hellman mechanism of type algorithm 0. Each algorithm
53 55 * 0 mechanism defines its OID, MODULUS, ROOT, KEYLEN, ALGTYPE (which should
54 56 * be zero) and HEX_KEY_BYTES. That module then will #include this file.
55 57 */
56 58
57 59 /* The keyopts for the per mechanism context */
58 60 static dh_keyopts_desc dh_keyopts = {
59 61 __encrypt,
60 62 __decrypt,
61 63 __gendes,
62 64 __secret_is_set,
63 65 __get_principal
64 66 };
65 67
66 68 /* The gss_context for this mechanism */
67 69 static struct gss_config dh_mech;
68 70
69 71 /*
70 72 * gss_mech_initialize: This is the libgss entry point to bring this
71 73 * mechanism on line. It is just a wrap to pass the pointer to its
72 74 * gss_config structure, OID, and the above keyopts to the common
73 75 * __dh_geneirc_initialize routine. We return null on failure, otherwise
74 76 * we return the mechanism's gss_mechanism.
75 77 */
76 78 gss_mechanism
77 79 gss_mech_initialize()
78 80 {
79 81 gss_mechanism mech;
80 82
81 83 mech = __dh_generic_initialize(&dh_mech, OID, &dh_keyopts);
82 84
83 85 if (mech == NULL) {
84 86 return (NULL);
85 87 }
86 88
87 89 return (mech);
88 90 }
89 91
90 92 /*
91 93 * A NIS+ server will define the function __rpcsec_gss_is_server.
92 94 * This function will return one when it is appropriate to get public
93 95 * keys out of the per process public key cache. Appropriateness here
94 96 * is when the name server just put the public key in the cache from a
95 97 * received directory object, typically from the cold start file.
96 98 */
↓ open down ↓ |
57 lines elided |
↑ open up ↑ |
97 99 static int
98 100 dh_getpublickey(const char *remote, keylen_t keylen, algtype_t algtype,
99 101 char *pk, size_t pklen)
100 102 {
101 103 static mutex_t init_nis_pubkey_lock = DEFAULTMUTEX;
102 104 static int init_nis_pubkey = 0;
103 105 static int (*nis_call)();
104 106 static const char NIS_SYMBOL[] = "__rpcsec_gss_is_server";
105 107
106 108 if (!init_nis_pubkey) {
107 - mutex_lock(&init_nis_pubkey_lock);
109 + (void) mutex_lock(&init_nis_pubkey_lock);
108 110 if (!init_nis_pubkey) {
109 111 void *dlhandle = dlopen(0, RTLD_NOLOAD);
110 112 if (dlhandle == 0) {
111 113 syslog(LOG_ERR, "dh: Could not dlopen "
112 114 "in dh_getpublickey for %s. "
113 115 "dlopen returned %s", remote, dlerror());
114 116 } else {
115 117 nis_call = (int (*)())
116 118 dlsym(dlhandle, NIS_SYMBOL);
117 119 }
118 120 init_nis_pubkey = 1;
119 121 }
120 - mutex_unlock(&init_nis_pubkey_lock);
122 + (void) mutex_unlock(&init_nis_pubkey_lock);
121 123 }
122 124 if (nis_call && (*nis_call)()) {
123 125 int key_cached;
124 126 return (__getpublickey_cached_g(remote, keylen, algtype,
125 127 pk, pklen, &key_cached));
126 128 }
127 129
128 130 /*
129 131 * If we're not being called by a nis plus server or that
130 132 * server does not want to get the keys from the cache we
131 133 * get the key in the normal manner.
132 134 */
133 135
134 136 return (getpublickey_g(remote, keylen, algtype, pk, pklen));
135 137 }
136 138
137 139
138 140 /*
139 141 * Routine to encrypt a set of session keys with keys derived from
140 142 * the common key with the caller and the remote principal.
141 143 */
142 144 static int __encrypt(const char *remotename, des_block deskeys[], int no_keys)
143 145 {
144 146 char pk[HEX_KEY_BYTES+1];
145 147
146 148 /*
147 149 * Get the public key out of the cache if this is a NIS+
148 150 * server. The reason is that the server may be a root replica
149 151 * that has just been created. It will not yet have the
150 152 * public key data to talk to its master. When the cold start
151 153 * file is read the public keys that are found there are
152 154 * cached. We will use the cache to get the public key data so
153 155 * the server will not hang or dump core. We call NIS_getpublickey
154 156 * to get the appropriate public key from NIS+. If that fails
155 157 * we just try to get the public key in the normal manner.
156 158 */
157 159
158 160 if (!dh_getpublickey(remotename, KEYLEN, 0, pk, sizeof (pk)))
159 161 return (-1);
160 162
161 163 if (key_encryptsession_pk_g(remotename, pk,
162 164 KEYLEN, ALGTYPE, deskeys, no_keys))
163 165 return (-1);
164 166
165 167 return (0);
166 168 }
167 169
168 170 /*
169 171 * Routine to decrypt a set of session keys with the common key that
170 172 * is held between the caller and the remote principal.
171 173 */
172 174 static int __decrypt(const char *remotename,
173 175 des_block deskeys[], int no_keys, int *key_cached)
174 176 {
175 177 int *use_cache = key_cached;
176 178 char pk[HEX_KEY_BYTES+1];
177 179
178 180 if (key_cached) {
179 181 use_cache = *key_cached ? key_cached : 0;
180 182 *key_cached = 0;
181 183 }
182 184
183 185 #ifdef DH_DEBUG
184 186 syslog(LOG_DEBUG, "dh: __decrypt is %s cache for %s\n",
185 187 use_cache ? "using" : "not using", remotename);
186 188 #endif
187 189
188 190 /*
189 191 * If we are not using the cache, flush the entry for remotename.
190 192 * It may be bad. The call to __getpublickey_cached_g below will
191 193 * repopulate the cache with the current public key.
192 194 */
193 195 if (!use_cache)
194 196 __getpublickey_flush_g(remotename, KEYLEN, ALGTYPE);
195 197
196 198 /* Get the public key */
197 199 if (!__getpublickey_cached_g(remotename, KEYLEN,
198 200 0, pk, sizeof (pk), use_cache))
199 201 return (-1);
200 202
201 203 #if DH_DEBUG
202 204 if (use_cache)
203 205 syslog(LOG_DEBUG, "dh: __decrypt cache = %d\n", *key_cached);
204 206 #endif
205 207
206 208 if (key_decryptsession_pk_g(remotename, pk,
207 209 KEYLEN, ALGTYPE, deskeys, no_keys)) {
208 210
209 211 return (-1);
210 212 }
211 213
212 214 return (0);
213 215 }
214 216
215 217 /*
216 218 * Routine to generate a set of random session keys.
217 219 */
218 220 static int __gendes(des_block deskeys[], int no_keys)
219 221 {
220 222
221 223 memset(deskeys, 0, no_keys* sizeof (des_block));
222 224 if (key_gendes_g(deskeys, no_keys))
223 225 return (-1);
224 226
225 227 return (0);
226 228 }
227 229
228 230 /*
229 231 * Routine that will return true if this mechanism corresponding
230 232 * private keys has been set.
231 233 */
232 234 static int __secret_is_set(void)
233 235 {
234 236 return (key_secretkey_is_set_g(KEYLEN, ALGTYPE));
235 237 }
236 238
237 239 /*
238 240 * Routine to retrieve the callers principal name. Note it is up to
239 241 * the caller to free the result.
240 242 */
241 243 static char * __get_principal(void)
242 244 {
243 245 char netname[MAXNETNAMELEN+1];
244 246
245 247 if (getnetname(netname))
246 248 return (strdup(netname));
247 249
248 250 return (NULL);
249 251 }
↓ open down ↓ |
119 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX