Line | Source | Count |
1 | | - |
2 | | - |
3 | | - |
4 | | - |
5 | | - |
6 | | - |
7 | | - |
8 | | - |
9 | | - |
10 | | - |
11 | | - |
12 | | - |
13 | | - |
14 | | - |
15 | | - |
16 | | - |
17 | | - |
18 | #include "includes.h" | - |
19 | | - |
20 | #include <sys/types.h> | - |
21 | | - |
22 | #include <netdb.h> | - |
23 | #include <pwd.h> | - |
24 | #include <string.h> | - |
25 | #include <stdio.h> | - |
26 | #include <stdarg.h> | - |
27 | #include <ctype.h> | - |
28 | #include <limits.h> | - |
29 | | - |
30 | #include "openbsd-compat/sys-queue.h" | - |
31 | | - |
32 | #include "xmalloc.h" | - |
33 | #include "ssherr.h" | - |
34 | #include "log.h" | - |
35 | #include "sshbuf.h" | - |
36 | #include "misc.h" | - |
37 | #include "sshkey.h" | - |
38 | #include "match.h" | - |
39 | #include "ssh2.h" | - |
40 | #include "auth-options.h" | - |
41 | | - |
42 | | - |
43 | | - |
44 | | - |
45 | | - |
46 | | - |
47 | | - |
48 | | - |
49 | static int | - |
50 | opt_flag(const char *opt, int allow_negate, const char **optsp) | - |
51 | { | - |
52 | size_t opt_len = strlen(opt); | - |
53 | const char *opts = *optsp; | - |
54 | int negate = 0; | - |
55 | | - |
56 | if (allow_negate && strncasecmp(opts, "no-", 3) == 0) {TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
57 | opts += 3; | - |
58 | negate = 1; | - |
59 | } never executed: end of block | 0 |
60 | if (strncasecmp(opts, opt, opt_len) == 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
61 | *optsp = opts + opt_len; | - |
62 | return negate ? 0 : 1; never executed: return negate ? 0 : 1; TRUE | never evaluated | FALSE | never evaluated |
| 0 |
63 | } | - |
64 | return -1; never executed: return -1; | 0 |
65 | } | - |
66 | | - |
67 | static char * | - |
68 | opt_dequote(const char **sp, const char **errstrp) | - |
69 | { | - |
70 | const char *s = *sp; | - |
71 | char *ret; | - |
72 | size_t i; | - |
73 | | - |
74 | *errstrp = NULL; | - |
75 | if (*s != '"') {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
76 | *errstrp = "missing start quote"; | - |
77 | return NULL; never executed: return ((void *)0) ; | 0 |
78 | } | - |
79 | s++; | - |
80 | if ((ret = malloc(strlen((s)) + 1)) == NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
81 | *errstrp = "memory allocation failed"; | - |
82 | return NULL; never executed: return ((void *)0) ; | 0 |
83 | } | - |
84 | for (i = 0; *s != '\0' && *s != '"';) {TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
85 | if (s[0] == '\\' && s[1] == '"')TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
86 | s++; never executed: s++; | 0 |
87 | ret[i++] = *s++; | - |
88 | } never executed: end of block | 0 |
89 | if (*s == '\0') {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
90 | *errstrp = "missing end quote"; | - |
91 | free(ret); | - |
92 | return NULL; never executed: return ((void *)0) ; | 0 |
93 | } | - |
94 | ret[i] = '\0'; | - |
95 | s++; | - |
96 | *sp = s; | - |
97 | return ret; never executed: return ret; | 0 |
98 | } | - |
99 | | - |
100 | static int | - |
101 | opt_match(const char **opts, const char *term) | - |
102 | { | - |
103 | if (strncasecmp((*opts), term, strlen(term)) == 0 &&TRUE | never evaluated | FALSE | never evaluated |
| 0 |
104 | (*opts)[strlen(term)] == '=') {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
105 | *opts += strlen(term) + 1; | - |
106 | return 1; never executed: return 1; | 0 |
107 | } | - |
108 | return 0; never executed: return 0; | 0 |
109 | } | - |
110 | | - |
111 | static int | - |
112 | dup_strings(char ***dstp, size_t *ndstp, char **src, size_t nsrc) | - |
113 | { | - |
114 | char **dst; | - |
115 | size_t i, j; | - |
116 | | - |
117 | *dstp = NULL; | - |
118 | *ndstp = 0; | - |
119 | if (nsrc == 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
120 | return 0; never executed: return 0; | 0 |
121 | | - |
122 | if ((dst = calloc(nsrc, sizeof(*src))) == NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
123 | return -1; never executed: return -1; | 0 |
124 | for (i = 0; i < nsrc; i++) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
125 | if ((dst[i] = strdup(src[i])) == NULL) { never executed: __retval = (char *) memcpy (__retval, src[i] , __len); TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
126 | for (j = 0; j < i; j++)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
127 | free(dst[j]); never executed: free(dst[j]); | 0 |
128 | free(dst); | - |
129 | return -1; never executed: return -1; | 0 |
130 | } | - |
131 | } never executed: end of block | 0 |
132 | | - |
133 | *dstp = dst; | - |
134 | *ndstp = nsrc; | - |
135 | return 0; never executed: return 0; | 0 |
136 | } | - |
137 | | - |
138 | #define OPTIONS_CRITICAL 1 | - |
139 | #define OPTIONS_EXTENSIONS 2 | - |
140 | static int | - |
141 | cert_option_list(struct sshauthopt *opts, struct sshbuf *oblob, | - |
142 | u_int which, int crit) | - |
143 | { | - |
144 | char *command, *allowed; | - |
145 | char *name = NULL; | - |
146 | struct sshbuf *c = NULL, *data = NULL; | - |
147 | int r, ret = -1, found; | - |
148 | | - |
149 | if ((c = sshbuf_fromb(oblob)) == NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
150 | error("%s: sshbuf_fromb failed", __func__); | - |
151 | goto out; never executed: goto out; | 0 |
152 | } | - |
153 | | - |
154 | while (sshbuf_len(c) > 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
155 | sshbuf_free(data); | - |
156 | data = NULL; | - |
157 | if ((r = sshbuf_get_cstring(c, &name, NULL)) != 0 ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
158 | (r = sshbuf_froms(c, &data)) != 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
159 | error("Unable to parse certificate options: %s", | - |
160 | ssh_err(r)); | - |
161 | goto out; never executed: goto out; | 0 |
162 | } | - |
163 | debug3("found certificate option \"%.100s\" len %zu", | - |
164 | name, sshbuf_len(data)); | - |
165 | found = 0; | - |
166 | if ((which & OPTIONS_EXTENSIONS) != 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
167 | if (strcmp(name, "permit-X11-forwarding") == 0) { never executed: __result = (((const unsigned char *) (const char *) ( name ))[3] - __s2[3]); never executed: end of block never executed: end of block never executed: __result = (((const unsigned char *) (const char *) ( "permit-X11-forwarding" ))[3] - __s2[3]); never executed: end of block never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
168 | opts->permit_x11_forwarding_flag = 1; | - |
169 | found = 1; | - |
170 | } else if (strcmp(name, never executed: end of block never executed: __result = (((const unsigned char *) (const char *) ( name ))[3] - __s2[3]); never executed: end of block never executed: end of block never executed: __result = (((const unsigned char *) (const char *) ( "permit-agent-forwarding" ))[3] - __s2[3]); never executed: end of block never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
171 | "permit-agent-forwarding") == 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
172 | opts->permit_agent_forwarding_flag = 1; | - |
173 | found = 1; | - |
174 | } else if (strcmp(name, never executed: end of block never executed: __result = (((const unsigned char *) (const char *) ( name ))[3] - __s2[3]); never executed: end of block never executed: end of block never executed: __result = (((const unsigned char *) (const char *) ( "permit-port-forwarding" ))[3] - __s2[3]); never executed: end of block never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
175 | "permit-port-forwarding") == 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
176 | opts->permit_port_forwarding_flag = 1; | - |
177 | found = 1; | - |
178 | } else if (strcmp(name, "permit-pty") == 0) { never executed: end of block never executed: __result = (((const unsigned char *) (const char *) ( name ))[3] - __s2[3]); never executed: end of block never executed: end of block never executed: __result = (((const unsigned char *) (const char *) ( "permit-pty" ))[3] - __s2[3]); never executed: end of block never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
179 | opts->permit_pty_flag = 1; | - |
180 | found = 1; | - |
181 | } else if (strcmp(name, "permit-user-rc") == 0) { never executed: end of block never executed: __result = (((const unsigned char *) (const char *) ( name ))[3] - __s2[3]); never executed: end of block never executed: end of block never executed: __result = (((const unsigned char *) (const char *) ( "permit-user-rc" ))[3] - __s2[3]); never executed: end of block never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
182 | opts->permit_user_rc = 1; | - |
183 | found = 1; | - |
184 | } never executed: end of block | 0 |
185 | } never executed: end of block | 0 |
186 | if (!found && (which & OPTIONS_CRITICAL) != 0) {TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
187 | if (strcmp(name, "force-command") == 0) { never executed: __result = (((const unsigned char *) (const char *) ( name ))[3] - __s2[3]); never executed: end of block never executed: end of block never executed: __result = (((const unsigned char *) (const char *) ( "force-command" ))[3] - __s2[3]); never executed: end of block never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
188 | if ((r = sshbuf_get_cstring(data, &command,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
189 | NULL)) != 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
190 | error("Unable to parse \"%s\" " | - |
191 | "section: %s", name, ssh_err(r)); | - |
192 | goto out; never executed: goto out; | 0 |
193 | } | - |
194 | if (opts->force_command != NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
195 | error("Certificate has multiple " | - |
196 | "force-command options"); | - |
197 | free(command); | - |
198 | goto out; never executed: goto out; | 0 |
199 | } | - |
200 | opts->force_command = command; | - |
201 | found = 1; | - |
202 | } never executed: end of block | 0 |
203 | if (strcmp(name, "source-address") == 0) { never executed: __result = (((const unsigned char *) (const char *) ( name ))[3] - __s2[3]); never executed: end of block never executed: end of block never executed: __result = (((const unsigned char *) (const char *) ( "source-address" ))[3] - __s2[3]); never executed: end of block never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
204 | if ((r = sshbuf_get_cstring(data, &allowed,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
205 | NULL)) != 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
206 | error("Unable to parse \"%s\" " | - |
207 | "section: %s", name, ssh_err(r)); | - |
208 | goto out; never executed: goto out; | 0 |
209 | } | - |
210 | if (opts->required_from_host_cert != NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
211 | error("Certificate has multiple " | - |
212 | "source-address options"); | - |
213 | free(allowed); | - |
214 | goto out; never executed: goto out; | 0 |
215 | } | - |
216 | | - |
217 | if (addr_match_cidr_list(NULL, allowed) == -1) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
218 | error("Certificate source-address " | - |
219 | "contents invalid"); | - |
220 | goto out; never executed: goto out; | 0 |
221 | } | - |
222 | opts->required_from_host_cert = allowed; | - |
223 | found = 1; | - |
224 | } never executed: end of block | 0 |
225 | } never executed: end of block | 0 |
226 | | - |
227 | if (!found) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
228 | if (crit) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
229 | error("Certificate critical option \"%s\" " | - |
230 | "is not supported", name); | - |
231 | goto out; never executed: goto out; | 0 |
232 | } else { | - |
233 | logit("Certificate extension \"%s\" " | - |
234 | "is not supported", name); | - |
235 | } never executed: end of block | 0 |
236 | } else if (sshbuf_len(data) != 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
237 | error("Certificate option \"%s\" corrupt " | - |
238 | "(extra data)", name); | - |
239 | goto out; never executed: goto out; | 0 |
240 | } | - |
241 | free(name); | - |
242 | name = NULL; | - |
243 | } never executed: end of block | 0 |
244 | | - |
245 | ret = 0; | - |
246 | | - |
247 | out: code before this statement never executed: out: | 0 |
248 | free(name); | - |
249 | sshbuf_free(data); | - |
250 | sshbuf_free(c); | - |
251 | return ret; never executed: return ret; | 0 |
252 | } | - |
253 | | - |
254 | struct sshauthopt * | - |
255 | sshauthopt_new(void) | - |
256 | { | - |
257 | struct sshauthopt *ret; | - |
258 | | - |
259 | if ((ret = calloc(1, sizeof(*ret))) == NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
260 | return NULL; never executed: return ((void *)0) ; | 0 |
261 | ret->force_tun_device = -1; | - |
262 | return ret; never executed: return ret; | 0 |
263 | } | - |
264 | | - |
265 | void | - |
266 | sshauthopt_free(struct sshauthopt *opts) | - |
267 | { | - |
268 | size_t i; | - |
269 | | - |
270 | if (opts == NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
271 | return; never executed: return; | 0 |
272 | | - |
273 | free(opts->cert_principals); | - |
274 | free(opts->force_command); | - |
275 | free(opts->required_from_host_cert); | - |
276 | free(opts->required_from_host_keys); | - |
277 | | - |
278 | for (i = 0; i < opts->nenv; i++)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
279 | free(opts->env[i]); never executed: free(opts->env[i]); | 0 |
280 | free(opts->env); | - |
281 | | - |
282 | for (i = 0; i < opts->npermitopen; i++)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
283 | free(opts->permitopen[i]); never executed: free(opts->permitopen[i]); | 0 |
284 | free(opts->permitopen); | - |
285 | | - |
286 | for (i = 0; i < opts->npermitlisten; i++)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
287 | free(opts->permitlisten[i]); never executed: free(opts->permitlisten[i]); | 0 |
288 | free(opts->permitlisten); | - |
289 | | - |
290 | explicit_bzero(opts, sizeof(*opts)); | - |
291 | free(opts); | - |
292 | } never executed: end of block | 0 |
293 | | - |
294 | struct sshauthopt * | - |
295 | sshauthopt_new_with_keys_defaults(void) | - |
296 | { | - |
297 | struct sshauthopt *ret = NULL; | - |
298 | | - |
299 | if ((ret = sshauthopt_new()) == NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
300 | return NULL; never executed: return ((void *)0) ; | 0 |
301 | | - |
302 | | - |
303 | ret->permit_port_forwarding_flag = 1; | - |
304 | ret->permit_agent_forwarding_flag = 1; | - |
305 | ret->permit_x11_forwarding_flag = 1; | - |
306 | ret->permit_pty_flag = 1; | - |
307 | ret->permit_user_rc = 1; | - |
308 | return ret; never executed: return ret; | 0 |
309 | } | - |
310 | | - |
311 | | - |
312 | | - |
313 | | - |
314 | | - |
315 | static int | - |
316 | handle_permit(const char **optsp, int allow_bare_port, | - |
317 | char ***permitsp, size_t *npermitsp, const char **errstrp) | - |
318 | { | - |
319 | char *opt, *tmp, *cp, *host, **permits = *permitsp; | - |
320 | size_t npermits = *npermitsp; | - |
321 | const char *errstr = "unknown error"; | - |
322 | | - |
323 | if (npermits > INT_MAX) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
324 | *errstrp = "too many permission directives"; | - |
325 | return -1; never executed: return -1; | 0 |
326 | } | - |
327 | if ((opt = opt_dequote(optsp, &errstr)) == NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
328 | return -1; never executed: return -1; | 0 |
329 | } | - |
330 | if (allow_bare_port && strchr(opt, ':') == NULL) {TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
331 | | - |
332 | | - |
333 | | - |
334 | | - |
335 | if (asprintf(&tmp, "*:%s", opt) < 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
336 | *errstrp = "memory allocation failed"; | - |
337 | return -1; never executed: return -1; | 0 |
338 | } | - |
339 | free(opt); | - |
340 | opt = tmp; | - |
341 | } never executed: end of block | 0 |
342 | if ((tmp = strdup(opt)) == NULL) { never executed: __retval = (char *) memcpy (__retval, opt , __len); TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
343 | free(opt); | - |
344 | *errstrp = "memory allocation failed"; | - |
345 | return -1; never executed: return -1; | 0 |
346 | } | - |
347 | cp = tmp; | - |
348 | | - |
349 | host = hpdelim(&cp); | - |
350 | if (host == NULL || strlen(host) >= NI_MAXHOST) {TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
351 | free(tmp); | - |
352 | free(opt); | - |
353 | *errstrp = "invalid permission hostname"; | - |
354 | return -1; never executed: return -1; | 0 |
355 | } | - |
356 | | - |
357 | | - |
358 | | - |
359 | | - |
360 | if (cp == NULL ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
361 | (strcmp(cp, "*") != 0 && a2port(cp) <= 0)) { never executed: __result = (((const unsigned char *) (const char *) ( cp ))[3] - __s2[3]); never executed: end of block never executed: end of block never executed: __result = (((const unsigned char *) (const char *) ( "*" ))[3] - __s2[3]); never executed: end of block never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
362 | free(tmp); | - |
363 | free(opt); | - |
364 | *errstrp = "invalid permission port"; | - |
365 | return -1; never executed: return -1; | 0 |
366 | } | - |
367 | | - |
368 | free(tmp); | - |
369 | | - |
370 | if ((permits = recallocarray(permits, npermits, npermits + 1,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
371 | sizeof(*permits))) == NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
372 | free(opt); | - |
373 | | - |
374 | *errstrp = "memory allocation failed"; | - |
375 | return -1; never executed: return -1; | 0 |
376 | } | - |
377 | permits[npermits++] = opt; | - |
378 | *permitsp = permits; | - |
379 | *npermitsp = npermits; | - |
380 | return 0; never executed: return 0; | 0 |
381 | } | - |
382 | | - |
383 | struct sshauthopt * | - |
384 | sshauthopt_parse(const char *opts, const char **errstrp) | - |
385 | { | - |
386 | char **oarray, *opt, *cp, *tmp; | - |
387 | int r; | - |
388 | struct sshauthopt *ret = NULL; | - |
389 | const char *errstr = "unknown error"; | - |
390 | uint64_t valid_before; | - |
391 | | - |
392 | if (errstrp != NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
393 | *errstrp = NULL; never executed: *errstrp = ((void *)0) ; | 0 |
394 | if ((ret = sshauthopt_new_with_keys_defaults()) == NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
395 | goto alloc_fail; never executed: goto alloc_fail; | 0 |
396 | | - |
397 | if (opts == NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
398 | return ret; never executed: return ret; | 0 |
399 | | - |
400 | while (*opts && *opts != ' ' && *opts != '\t') {TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
401 | | - |
402 | if ((r = opt_flag("restrict", 0, &opts)) != -1) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
403 | ret->restricted = 1; | - |
404 | ret->permit_port_forwarding_flag = 0; | - |
405 | ret->permit_agent_forwarding_flag = 0; | - |
406 | ret->permit_x11_forwarding_flag = 0; | - |
407 | ret->permit_pty_flag = 0; | - |
408 | ret->permit_user_rc = 0; | - |
409 | } else if ((r = opt_flag("cert-authority", 0, &opts)) != -1) { never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
| 0 |
410 | ret->cert_authority = r; | - |
411 | } else if ((r = opt_flag("port-forwarding", 1, &opts)) != -1) { never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
| 0 |
412 | ret->permit_port_forwarding_flag = r == 1; | - |
413 | } else if ((r = opt_flag("agent-forwarding", 1, &opts)) != -1) { never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
| 0 |
414 | ret->permit_agent_forwarding_flag = r == 1; | - |
415 | } else if ((r = opt_flag("x11-forwarding", 1, &opts)) != -1) { never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
| 0 |
416 | ret->permit_x11_forwarding_flag = r == 1; | - |
417 | } else if ((r = opt_flag("pty", 1, &opts)) != -1) { never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
| 0 |
418 | ret->permit_pty_flag = r == 1; | - |
419 | } else if ((r = opt_flag("user-rc", 1, &opts)) != -1) { never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
| 0 |
420 | ret->permit_user_rc = r == 1; | - |
421 | } else if (opt_match(&opts, "command")) { never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
| 0 |
422 | if (ret->force_command != NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
423 | errstr = "multiple \"command\" clauses"; | - |
424 | goto fail; never executed: goto fail; | 0 |
425 | } | - |
426 | ret->force_command = opt_dequote(&opts, &errstr); | - |
427 | if (ret->force_command == NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
428 | goto fail; never executed: goto fail; | 0 |
429 | } else if (opt_match(&opts, "principals")) { never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
| 0 |
430 | if (ret->cert_principals != NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
431 | errstr = "multiple \"principals\" clauses"; | - |
432 | goto fail; never executed: goto fail; | 0 |
433 | } | - |
434 | ret->cert_principals = opt_dequote(&opts, &errstr); | - |
435 | if (ret->cert_principals == NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
436 | goto fail; never executed: goto fail; | 0 |
437 | } else if (opt_match(&opts, "from")) { never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
| 0 |
438 | if (ret->required_from_host_keys != NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
439 | errstr = "multiple \"from\" clauses"; | - |
440 | goto fail; never executed: goto fail; | 0 |
441 | } | - |
442 | ret->required_from_host_keys = opt_dequote(&opts, | - |
443 | &errstr); | - |
444 | if (ret->required_from_host_keys == NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
445 | goto fail; never executed: goto fail; | 0 |
446 | } else if (opt_match(&opts, "expiry-time")) { never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
| 0 |
447 | if ((opt = opt_dequote(&opts, &errstr)) == NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
448 | goto fail; never executed: goto fail; | 0 |
449 | if (parse_absolute_time(opt, &valid_before) != 0 ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
450 | valid_before == 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
451 | free(opt); | - |
452 | errstr = "invalid expires time"; | - |
453 | goto fail; never executed: goto fail; | 0 |
454 | } | - |
455 | free(opt); | - |
456 | if (ret->valid_before == 0 ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
457 | valid_before < ret->valid_before)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
458 | ret->valid_before = valid_before; never executed: ret->valid_before = valid_before; | 0 |
459 | } else if (opt_match(&opts, "environment")) { never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
| 0 |
460 | if (ret->nenv > INT_MAX) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
461 | errstr = "too many environment strings"; | - |
462 | goto fail; never executed: goto fail; | 0 |
463 | } | - |
464 | if ((opt = opt_dequote(&opts, &errstr)) == NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
465 | goto fail; never executed: goto fail; | 0 |
466 | | - |
467 | if ((tmp = strchr(opt, '=')) == NULL) {TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
468 | free(opt); | - |
469 | errstr = "invalid environment string"; | - |
470 | goto fail; never executed: goto fail; | 0 |
471 | } | - |
472 | for (cp = opt; cp < tmp; cp++) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
473 | if (!isalnum((u_char)*cp) && *cp != '_') {TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
474 | free(opt); | - |
475 | errstr = "invalid environment string"; | - |
476 | goto fail; never executed: goto fail; | 0 |
477 | } | - |
478 | } never executed: end of block | 0 |
479 | | - |
480 | oarray = ret->env; | - |
481 | if ((ret->env = recallocarray(ret->env, ret->nenv,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
482 | ret->nenv + 1, sizeof(*ret->env))) == NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
483 | free(opt); | - |
484 | ret->env = oarray; | - |
485 | goto alloc_fail; never executed: goto alloc_fail; | 0 |
486 | } | - |
487 | ret->env[ret->nenv++] = opt; | - |
488 | } else if (opt_match(&opts, "permitopen")) { never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
| 0 |
489 | if (handle_permit(&opts, 0, &ret->permitopen,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
490 | &ret->npermitopen, &errstr) != 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
491 | goto fail; never executed: goto fail; | 0 |
492 | } else if (opt_match(&opts, "permitlisten")) { never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
| 0 |
493 | if (handle_permit(&opts, 1, &ret->permitlisten,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
494 | &ret->npermitlisten, &errstr) != 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
495 | goto fail; never executed: goto fail; | 0 |
496 | } else if (opt_match(&opts, "tunnel")) { never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
| 0 |
497 | if ((opt = opt_dequote(&opts, &errstr)) == NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
498 | goto fail; never executed: goto fail; | 0 |
499 | ret->force_tun_device = a2tun(opt, NULL); | - |
500 | free(opt); | - |
501 | if (ret->force_tun_device == SSH_TUNID_ERR) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
502 | errstr = "invalid tun device"; | - |
503 | goto fail; never executed: goto fail; | 0 |
504 | } | - |
505 | } never executed: end of block | 0 |
506 | | - |
507 | | - |
508 | | - |
509 | | - |
510 | if (*opts == '\0' || *opts == ' ' || *opts == '\t')TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
511 | break; never executed: break; | 0 |
512 | | - |
513 | if (*opts != ',') {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
514 | errstr = "unknown key option"; | - |
515 | goto fail; never executed: goto fail; | 0 |
516 | } | - |
517 | opts++; | - |
518 | if (*opts == '\0') {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
519 | errstr = "unexpected end-of-options"; | - |
520 | goto fail; never executed: goto fail; | 0 |
521 | } | - |
522 | } never executed: end of block | 0 |
523 | | - |
524 | | - |
525 | if (errstrp != NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
526 | *errstrp = NULL; never executed: *errstrp = ((void *)0) ; | 0 |
527 | return ret; never executed: return ret; | 0 |
528 | | - |
529 | alloc_fail: | - |
530 | errstr = "memory allocation failed"; | - |
531 | fail: code before this statement never executed: fail: | 0 |
532 | sshauthopt_free(ret); | - |
533 | if (errstrp != NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
534 | *errstrp = errstr; never executed: *errstrp = errstr; | 0 |
535 | return NULL; never executed: return ((void *)0) ; | 0 |
536 | } | - |
537 | | - |
538 | struct sshauthopt * | - |
539 | sshauthopt_from_cert(struct sshkey *k) | - |
540 | { | - |
541 | struct sshauthopt *ret; | - |
542 | | - |
543 | if (k == NULL || !sshkey_type_is_cert(k->type) || k->cert == NULL ||TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
544 | k->cert->type != SSH2_CERT_TYPE_USER)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
545 | return NULL; never executed: return ((void *)0) ; | 0 |
546 | | - |
547 | if ((ret = sshauthopt_new()) == NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
548 | return NULL; never executed: return ((void *)0) ; | 0 |
549 | | - |
550 | | - |
551 | if (cert_option_list(ret, k->cert->critical,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
552 | OPTIONS_CRITICAL, 1) == -1) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
553 | sshauthopt_free(ret); | - |
554 | return NULL; never executed: return ((void *)0) ; | 0 |
555 | } | - |
556 | if (cert_option_list(ret, k->cert->extensions,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
557 | OPTIONS_EXTENSIONS, 0) == -1) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
558 | sshauthopt_free(ret); | - |
559 | return NULL; never executed: return ((void *)0) ; | 0 |
560 | } | - |
561 | | - |
562 | return ret; never executed: return ret; | 0 |
563 | } | - |
564 | | - |
565 | | - |
566 | | - |
567 | | - |
568 | | - |
569 | struct sshauthopt * | - |
570 | sshauthopt_merge(const struct sshauthopt *primary, | - |
571 | const struct sshauthopt *additional, const char **errstrp) | - |
572 | { | - |
573 | struct sshauthopt *ret; | - |
574 | const char *errstr = "internal error"; | - |
575 | const char *tmp; | - |
576 | | - |
577 | if (errstrp != NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
578 | *errstrp = NULL; never executed: *errstrp = ((void *)0) ; | 0 |
579 | | - |
580 | if ((ret = sshauthopt_new()) == NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
581 | goto alloc_fail; never executed: goto alloc_fail; | 0 |
582 | | - |
583 | | - |
584 | | - |
585 | | - |
586 | | - |
587 | tmp = primary->required_from_host_cert; | - |
588 | if (tmp == NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
589 | tmp = additional->required_from_host_cert; never executed: tmp = additional->required_from_host_cert; | 0 |
590 | if (tmp != NULL && (ret->required_from_host_cert = strdup(tmp)) == NULL) never executed: __retval = (char *) memcpy (__retval, tmp , __len); TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
591 | goto alloc_fail; never executed: goto alloc_fail; | 0 |
592 | tmp = primary->required_from_host_keys; | - |
593 | if (tmp == NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
594 | tmp = additional->required_from_host_keys; never executed: tmp = additional->required_from_host_keys; | 0 |
595 | if (tmp != NULL && (ret->required_from_host_keys = strdup(tmp)) == NULL) never executed: __retval = (char *) memcpy (__retval, tmp , __len); TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
596 | goto alloc_fail; never executed: goto alloc_fail; | 0 |
597 | | - |
598 | | - |
599 | | - |
600 | | - |
601 | | - |
602 | ret->force_tun_device = primary->force_tun_device; | - |
603 | if (ret->force_tun_device == -1)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
604 | ret->force_tun_device = additional->force_tun_device; never executed: ret->force_tun_device = additional->force_tun_device; | 0 |
605 | if (primary->nenv > 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
606 | if (dup_strings(&ret->env, &ret->nenv,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
607 | primary->env, primary->nenv) != 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
608 | goto alloc_fail; never executed: goto alloc_fail; | 0 |
609 | } else if (additional->nenv) { never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
| 0 |
610 | if (dup_strings(&ret->env, &ret->nenv,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
611 | additional->env, additional->nenv) != 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
612 | goto alloc_fail; never executed: goto alloc_fail; | 0 |
613 | } never executed: end of block | 0 |
614 | if (primary->npermitopen > 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
615 | if (dup_strings(&ret->permitopen, &ret->npermitopen,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
616 | primary->permitopen, primary->npermitopen) != 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
617 | goto alloc_fail; never executed: goto alloc_fail; | 0 |
618 | } else if (additional->npermitopen > 0) { never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
| 0 |
619 | if (dup_strings(&ret->permitopen, &ret->npermitopen,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
620 | additional->permitopen, additional->npermitopen) != 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
621 | goto alloc_fail; never executed: goto alloc_fail; | 0 |
622 | } never executed: end of block | 0 |
623 | | - |
624 | if (primary->npermitlisten > 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
625 | if (dup_strings(&ret->permitlisten, &ret->npermitlisten,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
626 | primary->permitlisten, primary->npermitlisten) != 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
627 | goto alloc_fail; never executed: goto alloc_fail; | 0 |
628 | } else if (additional->npermitlisten > 0) { never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
| 0 |
629 | if (dup_strings(&ret->permitlisten, &ret->npermitlisten,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
630 | additional->permitlisten, additional->npermitlisten) != 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
631 | goto alloc_fail; never executed: goto alloc_fail; | 0 |
632 | } never executed: end of block | 0 |
633 | | - |
634 | | - |
635 | #define OPTFLAG(x) ret->x = (primary->x == 1) && (additional->x == 1) | - |
636 | OPTFLAG(permit_port_forwarding_flag);TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
637 | OPTFLAG(permit_agent_forwarding_flag);TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
638 | OPTFLAG(permit_x11_forwarding_flag);TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
639 | OPTFLAG(permit_pty_flag);TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
640 | OPTFLAG(permit_user_rc);TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
641 | #undef OPTFLAG | - |
642 | | - |
643 | | - |
644 | if (primary->valid_before != 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
645 | ret->valid_before = primary->valid_before; never executed: ret->valid_before = primary->valid_before; | 0 |
646 | if (additional->valid_before != 0 &&TRUE | never evaluated | FALSE | never evaluated |
| 0 |
647 | additional->valid_before < ret->valid_before)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
648 | ret->valid_before = additional->valid_before; never executed: ret->valid_before = additional->valid_before; | 0 |
649 | | - |
650 | | - |
651 | | - |
652 | | - |
653 | | - |
654 | if (primary->force_command != NULL &&TRUE | never evaluated | FALSE | never evaluated |
| 0 |
655 | additional->force_command != NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
656 | if (strcmp(primary->force_command, never executed: __result = (((const unsigned char *) (const char *) ( primary->force_command ))[3] - __s2[3]); never executed: end of block never executed: end of block never executed: __result = (((const unsigned char *) (const char *) ( additional->force_command ))[3] - __s2[3]); never executed: end of block never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
657 | additional->force_command) == 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
658 | | - |
659 | ret->force_command = strdup(primary->force_command); never executed: __retval = (char *) memcpy (__retval, primary->force_command , __len); TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
660 | if (ret->force_command == NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
661 | goto alloc_fail; never executed: goto alloc_fail; | 0 |
662 | } else { never executed: end of block | 0 |
663 | errstr = "forced command options do not match"; | - |
664 | goto fail; never executed: goto fail; | 0 |
665 | } | - |
666 | } else if (primary->force_command != NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
667 | if ((ret->force_command = strdup( never executed: __retval = (char *) memcpy (__retval, primary->force_command , __len); TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
668 | primary->force_command)) == NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
669 | goto alloc_fail; never executed: goto alloc_fail; | 0 |
670 | } else if (additional->force_command != NULL) { never executed: end of block TRUE | never evaluated | FALSE | never evaluated |
| 0 |
671 | if ((ret->force_command = strdup( never executed: __retval = (char *) memcpy (__retval, additional->force_command , __len); TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
672 | additional->force_command)) == NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
673 | goto alloc_fail; never executed: goto alloc_fail; | 0 |
674 | } never executed: end of block | 0 |
675 | | - |
676 | if (errstrp != NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
677 | *errstrp = NULL; never executed: *errstrp = ((void *)0) ; | 0 |
678 | return ret; never executed: return ret; | 0 |
679 | | - |
680 | alloc_fail: | - |
681 | errstr = "memory allocation failed"; | - |
682 | fail: code before this statement never executed: fail: | 0 |
683 | if (errstrp != NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
684 | *errstrp = errstr; never executed: *errstrp = errstr; | 0 |
685 | sshauthopt_free(ret); | - |
686 | return NULL; never executed: return ((void *)0) ; | 0 |
687 | } | - |
688 | | - |
689 | | - |
690 | | - |
691 | | - |
692 | struct sshauthopt * | - |
693 | sshauthopt_copy(const struct sshauthopt *orig) | - |
694 | { | - |
695 | struct sshauthopt *ret; | - |
696 | | - |
697 | if ((ret = sshauthopt_new()) == NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
698 | return NULL; never executed: return ((void *)0) ; | 0 |
699 | | - |
700 | #define OPTSCALAR(x) ret->x = orig->x | - |
701 | OPTSCALAR(permit_port_forwarding_flag); | - |
702 | OPTSCALAR(permit_agent_forwarding_flag); | - |
703 | OPTSCALAR(permit_x11_forwarding_flag); | - |
704 | OPTSCALAR(permit_pty_flag); | - |
705 | OPTSCALAR(permit_user_rc); | - |
706 | OPTSCALAR(restricted); | - |
707 | OPTSCALAR(cert_authority); | - |
708 | OPTSCALAR(force_tun_device); | - |
709 | OPTSCALAR(valid_before); | - |
710 | #undef OPTSCALAR | - |
711 | #define OPTSTRING(x) \ | - |
712 | do { \ | - |
713 | if (orig->x != NULL && (ret->x = strdup(orig->x)) == NULL) { \ | - |
714 | sshauthopt_free(ret); \ | - |
715 | return NULL; \ | - |
716 | } \ | - |
717 | } while (0) | - |
718 | OPTSTRING(cert_principals); never executed: __retval = (char *) memcpy (__retval, orig->cert_principals , __len); never executed: return ((void *)0) ; TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
719 | OPTSTRING(force_command); never executed: __retval = (char *) memcpy (__retval, orig->force_command , __len); never executed: return ((void *)0) ; TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
720 | OPTSTRING(required_from_host_cert); never executed: __retval = (char *) memcpy (__retval, orig->required_from_host_cert , __len); never executed: return ((void *)0) ; TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
721 | OPTSTRING(required_from_host_keys); never executed: __retval = (char *) memcpy (__retval, orig->required_from_host_keys , __len); never executed: return ((void *)0) ; TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
722 | #undef OPTSTRING | - |
723 | | - |
724 | if (dup_strings(&ret->env, &ret->nenv, orig->env, orig->nenv) != 0 ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
725 | dup_strings(&ret->permitopen, &ret->npermitopen,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
726 | orig->permitopen, orig->npermitopen) != 0 ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
727 | dup_strings(&ret->permitlisten, &ret->npermitlisten,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
728 | orig->permitlisten, orig->npermitlisten) != 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
729 | sshauthopt_free(ret); | - |
730 | return NULL; never executed: return ((void *)0) ; | 0 |
731 | } | - |
732 | return ret; never executed: return ret; | 0 |
733 | } | - |
734 | | - |
735 | static int | - |
736 | serialise_array(struct sshbuf *m, char **a, size_t n) | - |
737 | { | - |
738 | struct sshbuf *b; | - |
739 | size_t i; | - |
740 | int r; | - |
741 | | - |
742 | if (n > INT_MAX)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
743 | return SSH_ERR_INTERNAL_ERROR; never executed: return -1; | 0 |
744 | | - |
745 | if ((b = sshbuf_new()) == NULL) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
746 | return SSH_ERR_ALLOC_FAIL; never executed: return -2; | 0 |
747 | } | - |
748 | for (i = 0; i < n; i++) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
749 | if ((r = sshbuf_put_cstring(b, a[i])) != 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
750 | sshbuf_free(b); | - |
751 | return r; never executed: return r; | 0 |
752 | } | - |
753 | } never executed: end of block | 0 |
754 | if ((r = sshbuf_put_u32(m, n)) != 0 ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
755 | (r = sshbuf_put_stringb(m, b)) != 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
756 | sshbuf_free(b); | - |
757 | return r; never executed: return r; | 0 |
758 | } | - |
759 | | - |
760 | return 0; never executed: return 0; | 0 |
761 | } | - |
762 | | - |
763 | static int | - |
764 | deserialise_array(struct sshbuf *m, char ***ap, size_t *np) | - |
765 | { | - |
766 | char **a = NULL; | - |
767 | size_t i, n = 0; | - |
768 | struct sshbuf *b = NULL; | - |
769 | u_int tmp; | - |
770 | int r = SSH_ERR_INTERNAL_ERROR; | - |
771 | | - |
772 | if ((r = sshbuf_get_u32(m, &tmp)) != 0 ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
773 | (r = sshbuf_froms(m, &b)) != 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
774 | goto out; never executed: goto out; | 0 |
775 | if (tmp > INT_MAX) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
776 | r = SSH_ERR_INVALID_FORMAT; | - |
777 | goto out; never executed: goto out; | 0 |
778 | } | - |
779 | n = tmp; | - |
780 | if (n > 0 && (a = calloc(n, sizeof(*a))) == NULL) {TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
781 | r = SSH_ERR_ALLOC_FAIL; | - |
782 | goto out; never executed: goto out; | 0 |
783 | } | - |
784 | for (i = 0; i < n; i++) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
785 | if ((r = sshbuf_get_cstring(b, &a[i], NULL)) != 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
786 | goto out; never executed: goto out; | 0 |
787 | } never executed: end of block | 0 |
788 | | - |
789 | r = 0; | - |
790 | *ap = a; | - |
791 | a = NULL; | - |
792 | *np = n; | - |
793 | n = 0; | - |
794 | out: code before this statement never executed: out: | 0 |
795 | for (i = 0; i < n; i++)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
796 | free(a[i]); never executed: free(a[i]); | 0 |
797 | free(a); | - |
798 | sshbuf_free(b); | - |
799 | return r; never executed: return r; | 0 |
800 | } | - |
801 | | - |
802 | static int | - |
803 | serialise_nullable_string(struct sshbuf *m, const char *s) | - |
804 | { | - |
805 | int r; | - |
806 | | - |
807 | if ((r = sshbuf_put_u8(m, s == NULL)) != 0 ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
808 | (r = sshbuf_put_cstring(m, s)) != 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
809 | return r; never executed: return r; | 0 |
810 | return 0; never executed: return 0; | 0 |
811 | } | - |
812 | | - |
813 | static int | - |
814 | deserialise_nullable_string(struct sshbuf *m, char **sp) | - |
815 | { | - |
816 | int r; | - |
817 | u_char flag; | - |
818 | | - |
819 | *sp = NULL; | - |
820 | if ((r = sshbuf_get_u8(m, &flag)) != 0 ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
821 | (r = sshbuf_get_cstring(m, flag ? NULL : sp, NULL)) != 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
822 | return r; never executed: return r; | 0 |
823 | return 0; never executed: return 0; | 0 |
824 | } | - |
825 | | - |
826 | int | - |
827 | sshauthopt_serialise(const struct sshauthopt *opts, struct sshbuf *m, | - |
828 | int untrusted) | - |
829 | { | - |
830 | int r = SSH_ERR_INTERNAL_ERROR; | - |
831 | | - |
832 | | - |
833 | if ((r = sshbuf_put_u8(m, opts->permit_port_forwarding_flag)) != 0 ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
834 | (r = sshbuf_put_u8(m, opts->permit_agent_forwarding_flag)) != 0 ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
835 | (r = sshbuf_put_u8(m, opts->permit_x11_forwarding_flag)) != 0 ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
836 | (r = sshbuf_put_u8(m, opts->permit_pty_flag)) != 0 ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
837 | (r = sshbuf_put_u8(m, opts->permit_user_rc)) != 0 ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
838 | (r = sshbuf_put_u8(m, opts->restricted)) != 0 ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
839 | (r = sshbuf_put_u8(m, opts->cert_authority)) != 0 ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
840 | (r = sshbuf_put_u64(m, opts->valid_before)) != 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
841 | return r; never executed: return r; | 0 |
842 | | - |
843 | | - |
844 | if ((r = sshbuf_put_u8(m, opts->force_tun_device == -1)) != 0 ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
845 | (r = sshbuf_put_u32(m, (opts->force_tun_device < 0) ?TRUE | never evaluated | FALSE | never evaluated |
| 0 |
846 | 0 : (u_int)opts->force_tun_device)) != 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
847 | return r; never executed: return r; | 0 |
848 | | - |
849 | | - |
850 | if ((r = serialise_nullable_string(m,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
851 | untrusted ? "yes" : opts->cert_principals)) != 0 ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
852 | (r = serialise_nullable_string(m,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
853 | untrusted ? "true" : opts->force_command)) != 0 ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
854 | (r = serialise_nullable_string(m,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
855 | untrusted ? NULL : opts->required_from_host_cert)) != 0 ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
856 | (r = serialise_nullable_string(m,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
857 | untrusted ? NULL : opts->required_from_host_keys)) != 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
858 | return r; never executed: return r; | 0 |
859 | | - |
860 | | - |
861 | if ((r = serialise_array(m, opts->env,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
862 | untrusted ? 0 : opts->nenv)) != 0 ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
863 | (r = serialise_array(m, opts->permitopen,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
864 | untrusted ? 0 : opts->npermitopen)) != 0 ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
865 | (r = serialise_array(m, opts->permitlisten,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
866 | untrusted ? 0 : opts->npermitlisten)) != 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
867 | return r; never executed: return r; | 0 |
868 | | - |
869 | | - |
870 | return 0; never executed: return 0; | 0 |
871 | } | - |
872 | | - |
873 | int | - |
874 | sshauthopt_deserialise(struct sshbuf *m, struct sshauthopt **optsp) | - |
875 | { | - |
876 | struct sshauthopt *opts = NULL; | - |
877 | int r = SSH_ERR_INTERNAL_ERROR; | - |
878 | u_char f; | - |
879 | u_int tmp; | - |
880 | | - |
881 | if ((opts = calloc(1, sizeof(*opts))) == NULL)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
882 | return SSH_ERR_ALLOC_FAIL; never executed: return -2; | 0 |
883 | | - |
884 | #define OPT_FLAG(x) \ | - |
885 | do { \ | - |
886 | if ((r = sshbuf_get_u8(m, &f)) != 0) \ | - |
887 | goto out; \ | - |
888 | opts->x = f; \ | - |
889 | } while (0) | - |
890 | OPT_FLAG(permit_port_forwarding_flag); never executed: goto out; TRUE | never evaluated | FALSE | never evaluated |
| 0 |
891 | OPT_FLAG(permit_agent_forwarding_flag); never executed: goto out; TRUE | never evaluated | FALSE | never evaluated |
| 0 |
892 | OPT_FLAG(permit_x11_forwarding_flag); never executed: goto out; TRUE | never evaluated | FALSE | never evaluated |
| 0 |
893 | OPT_FLAG(permit_pty_flag); never executed: goto out; TRUE | never evaluated | FALSE | never evaluated |
| 0 |
894 | OPT_FLAG(permit_user_rc); never executed: goto out; TRUE | never evaluated | FALSE | never evaluated |
| 0 |
895 | OPT_FLAG(restricted); never executed: goto out; TRUE | never evaluated | FALSE | never evaluated |
| 0 |
896 | OPT_FLAG(cert_authority); never executed: goto out; TRUE | never evaluated | FALSE | never evaluated |
| 0 |
897 | #undef OPT_FLAG | - |
898 | | - |
899 | if ((r = sshbuf_get_u64(m, &opts->valid_before)) != 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
900 | goto out; never executed: goto out; | 0 |
901 | | - |
902 | | - |
903 | if ((r = sshbuf_get_u8(m, &f)) != 0 ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
904 | (r = sshbuf_get_u32(m, &tmp)) != 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
905 | goto out; never executed: goto out; | 0 |
906 | opts->force_tun_device = f ? -1 : (int)tmp;TRUE | never evaluated | FALSE | never evaluated |
| 0 |
907 | | - |
908 | | - |
909 | if ((r = deserialise_nullable_string(m, &opts->cert_principals)) != 0 ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
910 | (r = deserialise_nullable_string(m, &opts->force_command)) != 0 ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
911 | (r = deserialise_nullable_string(m,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
912 | &opts->required_from_host_cert)) != 0 ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
913 | (r = deserialise_nullable_string(m,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
914 | &opts->required_from_host_keys)) != 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
915 | goto out; never executed: goto out; | 0 |
916 | | - |
917 | | - |
918 | if ((r = deserialise_array(m, &opts->env, &opts->nenv)) != 0 ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
919 | (r = deserialise_array(m,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
920 | &opts->permitopen, &opts->npermitopen)) != 0 ||TRUE | never evaluated | FALSE | never evaluated |
| 0 |
921 | (r = deserialise_array(m,TRUE | never evaluated | FALSE | never evaluated |
| 0 |
922 | &opts->permitlisten, &opts->npermitlisten)) != 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
923 | goto out; never executed: goto out; | 0 |
924 | | - |
925 | | - |
926 | r = 0; | - |
927 | *optsp = opts; | - |
928 | opts = NULL; | - |
929 | out: code before this statement never executed: out: | 0 |
930 | sshauthopt_free(opts); | - |
931 | return r; never executed: return r; | 0 |
932 | } | - |
| | |