Bug Summary

File:src/usr.bin/ssh/ssh-keysign/../readconf.c
Warning:line 1580, column 4
Value stored to 'p' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name readconf.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.bin/ssh/ssh-keysign/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/usr.bin/ssh/ssh-keysign/.. -D WITH_OPENSSL -D WITH_ZLIB -D ENABLE_PKCS11 -D HAVE_DLOPEN -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -fdebug-compilation-dir=/usr/src/usr.bin/ssh/ssh-keysign/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/usr.bin/ssh/ssh-keysign/../readconf.c
1/* $OpenBSD: readconf.c,v 1.364 2021/12/19 22:14:47 djm Exp $ */
2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
5 * All rights reserved
6 * Functions for reading the configuration files.
7 *
8 * As far as I am concerned, the code I have written for this software
9 * can be used freely for any purpose. Any derived versions of this
10 * software must be clearly marked as such, and if the derived work is
11 * incompatible with the protocol description in the RFC file, it must be
12 * called by a name other than "ssh" or "Secure Shell".
13 */
14
15#include <sys/types.h>
16#include <sys/stat.h>
17#include <sys/socket.h>
18#include <sys/wait.h>
19#include <sys/un.h>
20
21#include <netinet/in.h>
22#include <netinet/ip.h>
23
24#include <ctype.h>
25#include <errno(*__errno()).h>
26#include <fcntl.h>
27#include <glob.h>
28#include <netdb.h>
29#include <paths.h>
30#include <pwd.h>
31#include <signal.h>
32#include <stdio.h>
33#include <string.h>
34#include <stdarg.h>
35#include <unistd.h>
36#include <limits.h>
37#include <util.h>
38#include <vis.h>
39
40#include "xmalloc.h"
41#include "ssh.h"
42#include "ssherr.h"
43#include "compat.h"
44#include "cipher.h"
45#include "pathnames.h"
46#include "log.h"
47#include "sshkey.h"
48#include "misc.h"
49#include "readconf.h"
50#include "match.h"
51#include "kex.h"
52#include "mac.h"
53#include "uidswap.h"
54#include "myproposal.h"
55#include "digest.h"
56
57/* Format of the configuration file:
58
59 # Configuration data is parsed as follows:
60 # 1. command line options
61 # 2. user-specific file
62 # 3. system-wide file
63 # Any configuration value is only changed the first time it is set.
64 # Thus, host-specific definitions should be at the beginning of the
65 # configuration file, and defaults at the end.
66
67 # Host-specific declarations. These may override anything above. A single
68 # host may match multiple declarations; these are processed in the order
69 # that they are given in.
70
71 Host *.ngs.fi ngs.fi
72 User foo
73
74 Host fake.com
75 Hostname another.host.name.real.org
76 User blaah
77 Port 34289
78 ForwardX11 no
79 ForwardAgent no
80
81 Host books.com
82 RemoteForward 9999 shadows.cs.hut.fi:9999
83 Ciphers 3des-cbc
84
85 Host fascist.blob.com
86 Port 23123
87 User tylonen
88 PasswordAuthentication no
89
90 Host puukko.hut.fi
91 User t35124p
92 ProxyCommand ssh-proxy %h %p
93
94 Host *.fr
95 PublicKeyAuthentication no
96
97 Host *.su
98 Ciphers aes128-ctr
99 PasswordAuthentication no
100
101 Host vpn.fake.com
102 Tunnel yes
103 TunnelDevice 3
104
105 # Defaults for various options
106 Host *
107 ForwardAgent no
108 ForwardX11 no
109 PasswordAuthentication yes
110 StrictHostKeyChecking yes
111 TcpKeepAlive no
112 IdentityFile ~/.ssh/identity
113 Port 22
114 EscapeChar ~
115
116*/
117
118static int read_config_file_depth(const char *filename, struct passwd *pw,
119 const char *host, const char *original_host, Options *options,
120 int flags, int *activep, int *want_final_pass, int depth);
121static int process_config_line_depth(Options *options, struct passwd *pw,
122 const char *host, const char *original_host, char *line,
123 const char *filename, int linenum, int *activep, int flags,
124 int *want_final_pass, int depth);
125
126/* Keyword tokens. */
127
128typedef enum {
129 oBadOption,
130 oHost, oMatch, oInclude,
131 oForwardAgent, oForwardX11, oForwardX11Trusted, oForwardX11Timeout,
132 oGatewayPorts, oExitOnForwardFailure,
133 oPasswordAuthentication,
134 oXAuthLocation,
135 oIdentityFile, oHostname, oPort, oRemoteForward, oLocalForward,
136 oPermitRemoteOpen,
137 oCertificateFile, oAddKeysToAgent, oIdentityAgent,
138 oUser, oEscapeChar, oProxyCommand,
139 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
140 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
141 oTCPKeepAlive, oNumberOfPasswordPrompts,
142 oLogFacility, oLogLevel, oLogVerbose, oCiphers, oMacs,
143 oPubkeyAuthentication,
144 oKbdInteractiveAuthentication, oKbdInteractiveDevices, oHostKeyAlias,
145 oDynamicForward, oPreferredAuthentications, oHostbasedAuthentication,
146 oHostKeyAlgorithms, oBindAddress, oBindInterface, oPKCS11Provider,
147 oClearAllForwardings, oNoHostAuthenticationForLocalhost,
148 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
149 oAddressFamily, oGssAuthentication, oGssDelegateCreds,
150 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
151 oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist,
152 oHashKnownHosts,
153 oTunnel, oTunnelDevice,
154 oLocalCommand, oPermitLocalCommand, oRemoteCommand,
155 oVisualHostKey,
156 oKexAlgorithms, oIPQoS, oRequestTTY, oSessionType, oStdinNull,
157 oForkAfterAuthentication, oIgnoreUnknown, oProxyUseFdpass,
158 oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
159 oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
160 oStreamLocalBindMask, oStreamLocalBindUnlink, oRevokedHostKeys,
161 oFingerprintHash, oUpdateHostkeys, oHostbasedAcceptedAlgorithms,
162 oPubkeyAcceptedAlgorithms, oCASignatureAlgorithms, oProxyJump,
163 oSecurityKeyProvider, oKnownHostsCommand,
164 oIgnore, oIgnoredUnknownOption, oDeprecated, oUnsupported
165} OpCodes;
166
167/* Textual representations of the tokens. */
168
169static struct {
170 const char *name;
171 OpCodes opcode;
172} keywords[] = {
173 /* Deprecated options */
174 { "protocol", oIgnore }, /* NB. silently ignored */
175 { "cipher", oDeprecated },
176 { "fallbacktorsh", oDeprecated },
177 { "globalknownhostsfile2", oDeprecated },
178 { "rhostsauthentication", oDeprecated },
179 { "userknownhostsfile2", oDeprecated },
180 { "useroaming", oDeprecated },
181 { "usersh", oDeprecated },
182 { "useprivilegedport", oDeprecated },
183
184 /* Unsupported options */
185 { "afstokenpassing", oUnsupported },
186 { "kerberosauthentication", oUnsupported },
187 { "kerberostgtpassing", oUnsupported },
188 { "rsaauthentication", oUnsupported },
189 { "rhostsrsaauthentication", oUnsupported },
190 { "compressionlevel", oUnsupported },
191
192 /* Sometimes-unsupported options */
193#if defined(GSSAPI)
194 { "gssapiauthentication", oGssAuthentication },
195 { "gssapidelegatecredentials", oGssDelegateCreds },
196# else
197 { "gssapiauthentication", oUnsupported },
198 { "gssapidelegatecredentials", oUnsupported },
199#endif
200#ifdef ENABLE_PKCS111
201 { "pkcs11provider", oPKCS11Provider },
202 { "smartcarddevice", oPKCS11Provider },
203# else
204 { "smartcarddevice", oUnsupported },
205 { "pkcs11provider", oUnsupported },
206#endif
207
208 { "forwardagent", oForwardAgent },
209 { "forwardx11", oForwardX11 },
210 { "forwardx11trusted", oForwardX11Trusted },
211 { "forwardx11timeout", oForwardX11Timeout },
212 { "exitonforwardfailure", oExitOnForwardFailure },
213 { "xauthlocation", oXAuthLocation },
214 { "gatewayports", oGatewayPorts },
215 { "passwordauthentication", oPasswordAuthentication },
216 { "kbdinteractiveauthentication", oKbdInteractiveAuthentication },
217 { "kbdinteractivedevices", oKbdInteractiveDevices },
218 { "challengeresponseauthentication", oKbdInteractiveAuthentication }, /* alias */
219 { "skeyauthentication", oKbdInteractiveAuthentication }, /* alias */
220 { "tisauthentication", oKbdInteractiveAuthentication }, /* alias */
221 { "pubkeyauthentication", oPubkeyAuthentication },
222 { "dsaauthentication", oPubkeyAuthentication }, /* alias */
223 { "hostbasedauthentication", oHostbasedAuthentication },
224 { "identityfile", oIdentityFile },
225 { "identityfile2", oIdentityFile }, /* obsolete */
226 { "identitiesonly", oIdentitiesOnly },
227 { "certificatefile", oCertificateFile },
228 { "addkeystoagent", oAddKeysToAgent },
229 { "identityagent", oIdentityAgent },
230 { "hostname", oHostname },
231 { "hostkeyalias", oHostKeyAlias },
232 { "proxycommand", oProxyCommand },
233 { "port", oPort },
234 { "ciphers", oCiphers },
235 { "macs", oMacs },
236 { "remoteforward", oRemoteForward },
237 { "localforward", oLocalForward },
238 { "permitremoteopen", oPermitRemoteOpen },
239 { "user", oUser },
240 { "host", oHost },
241 { "match", oMatch },
242 { "escapechar", oEscapeChar },
243 { "globalknownhostsfile", oGlobalKnownHostsFile },
244 { "userknownhostsfile", oUserKnownHostsFile },
245 { "connectionattempts", oConnectionAttempts },
246 { "batchmode", oBatchMode },
247 { "checkhostip", oCheckHostIP },
248 { "stricthostkeychecking", oStrictHostKeyChecking },
249 { "compression", oCompression },
250 { "tcpkeepalive", oTCPKeepAlive },
251 { "keepalive", oTCPKeepAlive }, /* obsolete */
252 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
253 { "syslogfacility", oLogFacility },
254 { "loglevel", oLogLevel },
255 { "logverbose", oLogVerbose },
256 { "dynamicforward", oDynamicForward },
257 { "preferredauthentications", oPreferredAuthentications },
258 { "hostkeyalgorithms", oHostKeyAlgorithms },
259 { "casignaturealgorithms", oCASignatureAlgorithms },
260 { "bindaddress", oBindAddress },
261 { "bindinterface", oBindInterface },
262 { "clearallforwardings", oClearAllForwardings },
263 { "enablesshkeysign", oEnableSSHKeysign },
264 { "verifyhostkeydns", oVerifyHostKeyDNS },
265 { "nohostauthenticationforlocalhost", oNoHostAuthenticationForLocalhost },
266 { "rekeylimit", oRekeyLimit },
267 { "connecttimeout", oConnectTimeout },
268 { "addressfamily", oAddressFamily },
269 { "serveraliveinterval", oServerAliveInterval },
270 { "serveralivecountmax", oServerAliveCountMax },
271 { "sendenv", oSendEnv },
272 { "setenv", oSetEnv },
273 { "controlpath", oControlPath },
274 { "controlmaster", oControlMaster },
275 { "controlpersist", oControlPersist },
276 { "hashknownhosts", oHashKnownHosts },
277 { "include", oInclude },
278 { "tunnel", oTunnel },
279 { "tunneldevice", oTunnelDevice },
280 { "localcommand", oLocalCommand },
281 { "permitlocalcommand", oPermitLocalCommand },
282 { "remotecommand", oRemoteCommand },
283 { "visualhostkey", oVisualHostKey },
284 { "kexalgorithms", oKexAlgorithms },
285 { "ipqos", oIPQoS },
286 { "requesttty", oRequestTTY },
287 { "sessiontype", oSessionType },
288 { "stdinnull", oStdinNull },
289 { "forkafterauthentication", oForkAfterAuthentication },
290 { "proxyusefdpass", oProxyUseFdpass },
291 { "canonicaldomains", oCanonicalDomains },
292 { "canonicalizefallbacklocal", oCanonicalizeFallbackLocal },
293 { "canonicalizehostname", oCanonicalizeHostname },
294 { "canonicalizemaxdots", oCanonicalizeMaxDots },
295 { "canonicalizepermittedcnames", oCanonicalizePermittedCNAMEs },
296 { "streamlocalbindmask", oStreamLocalBindMask },
297 { "streamlocalbindunlink", oStreamLocalBindUnlink },
298 { "revokedhostkeys", oRevokedHostKeys },
299 { "fingerprinthash", oFingerprintHash },
300 { "updatehostkeys", oUpdateHostkeys },
301 { "hostbasedacceptedalgorithms", oHostbasedAcceptedAlgorithms },
302 { "hostbasedkeytypes", oHostbasedAcceptedAlgorithms }, /* obsolete */
303 { "pubkeyacceptedalgorithms", oPubkeyAcceptedAlgorithms },
304 { "pubkeyacceptedkeytypes", oPubkeyAcceptedAlgorithms }, /* obsolete */
305 { "ignoreunknown", oIgnoreUnknown },
306 { "proxyjump", oProxyJump },
307 { "securitykeyprovider", oSecurityKeyProvider },
308 { "knownhostscommand", oKnownHostsCommand },
309
310 { NULL((void *)0), oBadOption }
311};
312
313static const char *lookup_opcode_name(OpCodes code);
314
315const char *
316kex_default_pk_alg(void)
317{
318 static char *pkalgs;
319
320 if (pkalgs == NULL((void *)0)) {
321 char *all_key;
322
323 all_key = sshkey_alg_list(0, 0, 1, ',');
324 pkalgs = match_filter_allowlist(KEX_DEFAULT_PK_ALG"ssh-ed25519-cert-v01@openssh.com," "ecdsa-sha2-nistp256-cert-v01@openssh.com,"
"ecdsa-sha2-nistp384-cert-v01@openssh.com," "ecdsa-sha2-nistp521-cert-v01@openssh.com,"
"sk-ssh-ed25519-cert-v01@openssh.com," "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,"
"rsa-sha2-512-cert-v01@openssh.com," "rsa-sha2-256-cert-v01@openssh.com,"
"ssh-ed25519," "ecdsa-sha2-nistp256," "ecdsa-sha2-nistp384,"
"ecdsa-sha2-nistp521," "sk-ssh-ed25519@openssh.com," "sk-ecdsa-sha2-nistp256@openssh.com,"
"rsa-sha2-512," "rsa-sha2-256"
, all_key);
325 free(all_key);
326 }
327 return pkalgs;
328}
329
330char *
331ssh_connection_hash(const char *thishost, const char *host, const char *portstr,
332 const char *user)
333{
334 struct ssh_digest_ctx *md;
335 u_char conn_hash[SSH_DIGEST_MAX_LENGTH64];
336
337 if ((md = ssh_digest_start(SSH_DIGEST_SHA11)) == NULL((void *)0) ||
338 ssh_digest_update(md, thishost, strlen(thishost)) < 0 ||
339 ssh_digest_update(md, host, strlen(host)) < 0 ||
340 ssh_digest_update(md, portstr, strlen(portstr)) < 0 ||
341 ssh_digest_update(md, user, strlen(user)) < 0 ||
342 ssh_digest_final(md, conn_hash, sizeof(conn_hash)) < 0)
343 fatal_f("mux digest failed")sshfatal("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 343, 1, SYSLOG_LEVEL_FATAL, ((void *)0), "mux digest failed"
)
;
344 ssh_digest_free(md);
345 return tohex(conn_hash, ssh_digest_bytes(SSH_DIGEST_SHA11));
346}
347
348/*
349 * Adds a local TCP/IP port forward to options. Never returns if there is an
350 * error.
351 */
352
353void
354add_local_forward(Options *options, const struct Forward *newfwd)
355{
356 struct Forward *fwd;
357 int i;
358
359 /* Don't add duplicates */
360 for (i = 0; i < options->num_local_forwards; i++) {
361 if (forward_equals(newfwd, options->local_forwards + i))
362 return;
363 }
364 options->local_forwards = xreallocarray(options->local_forwards,
365 options->num_local_forwards + 1,
366 sizeof(*options->local_forwards));
367 fwd = &options->local_forwards[options->num_local_forwards++];
368
369 fwd->listen_host = newfwd->listen_host;
370 fwd->listen_port = newfwd->listen_port;
371 fwd->listen_path = newfwd->listen_path;
372 fwd->connect_host = newfwd->connect_host;
373 fwd->connect_port = newfwd->connect_port;
374 fwd->connect_path = newfwd->connect_path;
375}
376
377/*
378 * Adds a remote TCP/IP port forward to options. Never returns if there is
379 * an error.
380 */
381
382void
383add_remote_forward(Options *options, const struct Forward *newfwd)
384{
385 struct Forward *fwd;
386 int i;
387
388 /* Don't add duplicates */
389 for (i = 0; i < options->num_remote_forwards; i++) {
390 if (forward_equals(newfwd, options->remote_forwards + i))
391 return;
392 }
393 options->remote_forwards = xreallocarray(options->remote_forwards,
394 options->num_remote_forwards + 1,
395 sizeof(*options->remote_forwards));
396 fwd = &options->remote_forwards[options->num_remote_forwards++];
397
398 fwd->listen_host = newfwd->listen_host;
399 fwd->listen_port = newfwd->listen_port;
400 fwd->listen_path = newfwd->listen_path;
401 fwd->connect_host = newfwd->connect_host;
402 fwd->connect_port = newfwd->connect_port;
403 fwd->connect_path = newfwd->connect_path;
404 fwd->handle = newfwd->handle;
405 fwd->allocated_port = 0;
406}
407
408static void
409clear_forwardings(Options *options)
410{
411 int i;
412
413 for (i = 0; i < options->num_local_forwards; i++) {
414 free(options->local_forwards[i].listen_host);
415 free(options->local_forwards[i].listen_path);
416 free(options->local_forwards[i].connect_host);
417 free(options->local_forwards[i].connect_path);
418 }
419 if (options->num_local_forwards > 0) {
420 free(options->local_forwards);
421 options->local_forwards = NULL((void *)0);
422 }
423 options->num_local_forwards = 0;
424 for (i = 0; i < options->num_remote_forwards; i++) {
425 free(options->remote_forwards[i].listen_host);
426 free(options->remote_forwards[i].listen_path);
427 free(options->remote_forwards[i].connect_host);
428 free(options->remote_forwards[i].connect_path);
429 }
430 if (options->num_remote_forwards > 0) {
431 free(options->remote_forwards);
432 options->remote_forwards = NULL((void *)0);
433 }
434 options->num_remote_forwards = 0;
435 options->tun_open = SSH_TUNMODE_NO0x00;
436}
437
438void
439add_certificate_file(Options *options, const char *path, int userprovided)
440{
441 int i;
442
443 if (options->num_certificate_files >= SSH_MAX_CERTIFICATE_FILES100)
444 fatal("Too many certificate files specified (max %d)",sshfatal("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 445, 0, SYSLOG_LEVEL_FATAL, ((void *)0), "Too many certificate files specified (max %d)"
, 100)
445 SSH_MAX_CERTIFICATE_FILES)sshfatal("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 445, 0, SYSLOG_LEVEL_FATAL, ((void *)0), "Too many certificate files specified (max %d)"
, 100)
;
446
447 /* Avoid registering duplicates */
448 for (i = 0; i < options->num_certificate_files; i++) {
449 if (options->certificate_file_userprovided[i] == userprovided &&
450 strcmp(options->certificate_files[i], path) == 0) {
451 debug2_f("ignoring duplicate key %s", path)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 451, 1, SYSLOG_LEVEL_DEBUG2, ((void *)0), "ignoring duplicate key %s"
, path)
;
452 return;
453 }
454 }
455
456 options->certificate_file_userprovided[options->num_certificate_files] =
457 userprovided;
458 options->certificate_files[options->num_certificate_files++] =
459 xstrdup(path);
460}
461
462void
463add_identity_file(Options *options, const char *dir, const char *filename,
464 int userprovided)
465{
466 char *path;
467 int i;
468
469 if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES100)
470 fatal("Too many identity files specified (max %d)",sshfatal("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 471, 0, SYSLOG_LEVEL_FATAL, ((void *)0), "Too many identity files specified (max %d)"
, 100)
471 SSH_MAX_IDENTITY_FILES)sshfatal("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 471, 0, SYSLOG_LEVEL_FATAL, ((void *)0), "Too many identity files specified (max %d)"
, 100)
;
472
473 if (dir == NULL((void *)0)) /* no dir, filename is absolute */
474 path = xstrdup(filename);
475 else if (xasprintf(&path, "%s%s", dir, filename) >= PATH_MAX1024)
476 fatal("Identity file path %s too long", path)sshfatal("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 476, 0, SYSLOG_LEVEL_FATAL, ((void *)0), "Identity file path %s too long"
, path)
;
477
478 /* Avoid registering duplicates */
479 for (i = 0; i < options->num_identity_files; i++) {
480 if (options->identity_file_userprovided[i] == userprovided &&
481 strcmp(options->identity_files[i], path) == 0) {
482 debug2_f("ignoring duplicate key %s", path)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 482, 1, SYSLOG_LEVEL_DEBUG2, ((void *)0), "ignoring duplicate key %s"
, path)
;
483 free(path);
484 return;
485 }
486 }
487
488 options->identity_file_userprovided[options->num_identity_files] =
489 userprovided;
490 options->identity_files[options->num_identity_files++] = path;
491}
492
493int
494default_ssh_port(void)
495{
496 static int port;
497 struct servent *sp;
498
499 if (port == 0) {
500 sp = getservbyname(SSH_SERVICE_NAME"ssh", "tcp");
501 port = sp ? ntohs(sp->s_port)(__uint16_t)(__builtin_constant_p(sp->s_port) ? (__uint16_t
)(((__uint16_t)(sp->s_port) & 0xffU) << 8 | ((__uint16_t
)(sp->s_port) & 0xff00U) >> 8) : __swap16md(sp->
s_port))
: SSH_DEFAULT_PORT22;
502 }
503 return port;
504}
505
506/*
507 * Execute a command in a shell.
508 * Return its exit status or -1 on abnormal exit.
509 */
510static int
511execute_in_shell(const char *cmd)
512{
513 char *shell;
514 pid_t pid;
515 int status;
516
517 if ((shell = getenv("SHELL")) == NULL((void *)0))
518 shell = _PATH_BSHELL"/bin/sh";
519
520 if (access(shell, X_OK0x01) == -1) {
521 fatal("Shell \"%s\" is not executable: %s",sshfatal("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 522, 0, SYSLOG_LEVEL_FATAL, ((void *)0), "Shell \"%s\" is not executable: %s"
, shell, strerror((*__errno())))
522 shell, strerror(errno))sshfatal("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 522, 0, SYSLOG_LEVEL_FATAL, ((void *)0), "Shell \"%s\" is not executable: %s"
, shell, strerror((*__errno())))
;
523 }
524
525 debug("Executing command: '%.500s'", cmd)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 525, 0, SYSLOG_LEVEL_DEBUG1, ((void *)0), "Executing command: '%.500s'"
, cmd)
;
526
527 /* Fork and execute the command. */
528 if ((pid = fork()) == 0) {
529 char *argv[4];
530
531 if (stdfd_devnull(1, 1, 0) == -1)
532 fatal_f("stdfd_devnull failed")sshfatal("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 532, 1, SYSLOG_LEVEL_FATAL, ((void *)0), "stdfd_devnull failed"
)
;
533 closefrom(STDERR_FILENO2 + 1);
534
535 argv[0] = shell;
536 argv[1] = "-c";
537 argv[2] = xstrdup(cmd);
538 argv[3] = NULL((void *)0);
539
540 execv(argv[0], argv);
541 error("Unable to execute '%.100s': %s", cmd, strerror(errno))sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 541, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "Unable to execute '%.100s': %s"
, cmd, strerror((*__errno())))
;
542 /* Die with signal to make this error apparent to parent. */
543 ssh_signal(SIGTERM15, SIG_DFL(void (*)(int))0);
544 kill(getpid(), SIGTERM15);
545 _exit(1);
546 }
547 /* Parent. */
548 if (pid == -1)
549 fatal_f("fork: %.100s", strerror(errno))sshfatal("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 549, 1, SYSLOG_LEVEL_FATAL, ((void *)0), "fork: %.100s", strerror
((*__errno())))
;
550
551 while (waitpid(pid, &status, 0) == -1) {
552 if (errno(*__errno()) != EINTR4 && errno(*__errno()) != EAGAIN35)
553 fatal_f("waitpid: %s", strerror(errno))sshfatal("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 553, 1, SYSLOG_LEVEL_FATAL, ((void *)0), "waitpid: %s", strerror
((*__errno())))
;
554 }
555 if (!WIFEXITED(status)(((status) & 0177) == 0)) {
556 error("command '%.100s' exited abnormally", cmd)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 556, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "command '%.100s' exited abnormally"
, cmd)
;
557 return -1;
558 }
559 debug3("command returned status %d", WEXITSTATUS(status))sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 559, 0, SYSLOG_LEVEL_DEBUG3, ((void *)0), "command returned status %d"
, (int)(((unsigned)(status) >> 8) & 0xff))
;
560 return WEXITSTATUS(status)(int)(((unsigned)(status) >> 8) & 0xff);
561}
562
563/*
564 * Parse and execute a Match directive.
565 */
566static int
567match_cfg_line(Options *options, char **condition, struct passwd *pw,
568 const char *host_arg, const char *original_host, int final_pass,
569 int *want_final_pass, const char *filename, int linenum)
570{
571 char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria;
572 const char *ruser;
573 int r, port, this_result, result = 1, attributes = 0, negate;
574 char thishost[NI_MAXHOST256], shorthost[NI_MAXHOST256], portstr[NI_MAXSERV32];
575 char uidstr[32];
576
577 /*
578 * Configuration is likely to be incomplete at this point so we
579 * must be prepared to use default values.
580 */
581 port = options->port <= 0 ? default_ssh_port() : options->port;
582 ruser = options->user == NULL((void *)0) ? pw->pw_name : options->user;
583 if (final_pass) {
584 host = xstrdup(options->hostname);
585 } else if (options->hostname != NULL((void *)0)) {
586 /* NB. Please keep in sync with ssh.c:main() */
587 host = percent_expand(options->hostname,
588 "h", host_arg, (char *)NULL((void *)0));
589 } else {
590 host = xstrdup(host_arg);
591 }
592
593 debug2("checking match for '%s' host %s originally %s",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 594, 0, SYSLOG_LEVEL_DEBUG2, ((void *)0), "checking match for '%s' host %s originally %s"
, cp, host, original_host)
594 cp, host, original_host)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 594, 0, SYSLOG_LEVEL_DEBUG2, ((void *)0), "checking match for '%s' host %s originally %s"
, cp, host, original_host)
;
595 while ((oattrib = attrib = strdelim(&cp)) && *attrib != '\0') {
596 /* Terminate on comment */
597 if (*attrib == '#') {
598 cp = NULL((void *)0); /* mark all arguments consumed */
599 break;
600 }
601 arg = criteria = NULL((void *)0);
602 this_result = 1;
603 if ((negate = attrib[0] == '!'))
604 attrib++;
605 /* Criterion "all" has no argument and must appear alone */
606 if (strcasecmp(attrib, "all") == 0) {
607 if (attributes > 1 || ((arg = strdelim(&cp)) != NULL((void *)0) &&
608 *arg != '\0' && *arg != '#')) {
609 error("%.200s line %d: '%s' cannot be combined "sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 611, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: '%s' cannot be combined "
"with other Match attributes", filename, linenum, oattrib)
610 "with other Match attributes",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 611, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: '%s' cannot be combined "
"with other Match attributes", filename, linenum, oattrib)
611 filename, linenum, oattrib)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 611, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: '%s' cannot be combined "
"with other Match attributes", filename, linenum, oattrib)
;
612 result = -1;
613 goto out;
614 }
615 if (arg != NULL((void *)0) && *arg == '#')
616 cp = NULL((void *)0); /* mark all arguments consumed */
617 if (result)
618 result = negate ? 0 : 1;
619 goto out;
620 }
621 attributes++;
622 /* criteria "final" and "canonical" have no argument */
623 if (strcasecmp(attrib, "canonical") == 0 ||
624 strcasecmp(attrib, "final") == 0) {
625 /*
626 * If the config requests "Match final" then remember
627 * this so we can perform a second pass later.
628 */
629 if (strcasecmp(attrib, "final") == 0 &&
630 want_final_pass != NULL((void *)0))
631 *want_final_pass = 1;
632 r = !!final_pass; /* force bitmask member to boolean */
633 if (r == (negate ? 1 : 0))
634 this_result = result = 0;
635 debug3("%.200s line %d: %smatched '%s'",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 637, 0, SYSLOG_LEVEL_DEBUG3, ((void *)0), "%.200s line %d: %smatched '%s'"
, filename, linenum, this_result ? "" : "not ", oattrib)
636 filename, linenum,sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 637, 0, SYSLOG_LEVEL_DEBUG3, ((void *)0), "%.200s line %d: %smatched '%s'"
, filename, linenum, this_result ? "" : "not ", oattrib)
637 this_result ? "" : "not ", oattrib)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 637, 0, SYSLOG_LEVEL_DEBUG3, ((void *)0), "%.200s line %d: %smatched '%s'"
, filename, linenum, this_result ? "" : "not ", oattrib)
;
638 continue;
639 }
640 /* All other criteria require an argument */
641 if ((arg = strdelim(&cp)) == NULL((void *)0) ||
642 *arg == '\0' || *arg == '#') {
643 error("Missing Match criteria for %s", attrib)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 643, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "Missing Match criteria for %s"
, attrib)
;
644 result = -1;
645 goto out;
646 }
647 if (strcasecmp(attrib, "host") == 0) {
648 criteria = xstrdup(host);
649 r = match_hostname(host, arg) == 1;
650 if (r == (negate ? 1 : 0))
651 this_result = result = 0;
652 } else if (strcasecmp(attrib, "originalhost") == 0) {
653 criteria = xstrdup(original_host);
654 r = match_hostname(original_host, arg) == 1;
655 if (r == (negate ? 1 : 0))
656 this_result = result = 0;
657 } else if (strcasecmp(attrib, "user") == 0) {
658 criteria = xstrdup(ruser);
659 r = match_pattern_list(ruser, arg, 0) == 1;
660 if (r == (negate ? 1 : 0))
661 this_result = result = 0;
662 } else if (strcasecmp(attrib, "localuser") == 0) {
663 criteria = xstrdup(pw->pw_name);
664 r = match_pattern_list(pw->pw_name, arg, 0) == 1;
665 if (r == (negate ? 1 : 0))
666 this_result = result = 0;
667 } else if (strcasecmp(attrib, "exec") == 0) {
668 char *conn_hash_hex, *keyalias;
669
670 if (gethostname(thishost, sizeof(thishost)) == -1)
671 fatal("gethostname: %s", strerror(errno))sshfatal("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 671, 0, SYSLOG_LEVEL_FATAL, ((void *)0), "gethostname: %s",
strerror((*__errno())))
;
672 strlcpy(shorthost, thishost, sizeof(shorthost));
673 shorthost[strcspn(thishost, ".")] = '\0';
674 snprintf(portstr, sizeof(portstr), "%d", port);
675 snprintf(uidstr, sizeof(uidstr), "%llu",
676 (unsigned long long)pw->pw_uid);
677 conn_hash_hex = ssh_connection_hash(thishost, host,
678 portstr, ruser);
679 keyalias = options->host_key_alias ?
680 options->host_key_alias : host;
681
682 cmd = percent_expand(arg,
683 "C", conn_hash_hex,
684 "L", shorthost,
685 "d", pw->pw_dir,
686 "h", host,
687 "k", keyalias,
688 "l", thishost,
689 "n", original_host,
690 "p", portstr,
691 "r", ruser,
692 "u", pw->pw_name,
693 "i", uidstr,
694 (char *)NULL((void *)0));
695 free(conn_hash_hex);
696 if (result != 1) {
697 /* skip execution if prior predicate failed */
698 debug3("%.200s line %d: skipped exec "sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 699, 0, SYSLOG_LEVEL_DEBUG3, ((void *)0), "%.200s line %d: skipped exec "
"\"%.100s\"", filename, linenum, cmd)
699 "\"%.100s\"", filename, linenum, cmd)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 699, 0, SYSLOG_LEVEL_DEBUG3, ((void *)0), "%.200s line %d: skipped exec "
"\"%.100s\"", filename, linenum, cmd)
;
700 free(cmd);
701 continue;
702 }
703 r = execute_in_shell(cmd);
704 if (r == -1) {
705 fatal("%.200s line %d: match exec "sshfatal("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 707, 0, SYSLOG_LEVEL_FATAL, ((void *)0), "%.200s line %d: match exec "
"'%.100s' error", filename, linenum, cmd)
706 "'%.100s' error", filename,sshfatal("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 707, 0, SYSLOG_LEVEL_FATAL, ((void *)0), "%.200s line %d: match exec "
"'%.100s' error", filename, linenum, cmd)
707 linenum, cmd)sshfatal("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 707, 0, SYSLOG_LEVEL_FATAL, ((void *)0), "%.200s line %d: match exec "
"'%.100s' error", filename, linenum, cmd)
;
708 }
709 criteria = xstrdup(cmd);
710 free(cmd);
711 /* Force exit status to boolean */
712 r = r == 0;
713 if (r == (negate ? 1 : 0))
714 this_result = result = 0;
715 } else {
716 error("Unsupported Match attribute %s", attrib)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 716, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "Unsupported Match attribute %s"
, attrib)
;
717 result = -1;
718 goto out;
719 }
720 debug3("%.200s line %d: %smatched '%s \"%.100s\"' ",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 722, 0, SYSLOG_LEVEL_DEBUG3, ((void *)0), "%.200s line %d: %smatched '%s \"%.100s\"' "
, filename, linenum, this_result ? "": "not ", oattrib, criteria
)
721 filename, linenum, this_result ? "": "not ",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 722, 0, SYSLOG_LEVEL_DEBUG3, ((void *)0), "%.200s line %d: %smatched '%s \"%.100s\"' "
, filename, linenum, this_result ? "": "not ", oattrib, criteria
)
722 oattrib, criteria)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 722, 0, SYSLOG_LEVEL_DEBUG3, ((void *)0), "%.200s line %d: %smatched '%s \"%.100s\"' "
, filename, linenum, this_result ? "": "not ", oattrib, criteria
)
;
723 free(criteria);
724 }
725 if (attributes == 0) {
726 error("One or more attributes required for Match")sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 726, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "One or more attributes required for Match"
)
;
727 result = -1;
728 goto out;
729 }
730 out:
731 if (result != -1)
732 debug2("match %sfound", result ? "" : "not ")sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 732, 0, SYSLOG_LEVEL_DEBUG2, ((void *)0), "match %sfound", result
? "" : "not ")
;
733 *condition = cp;
734 free(host);
735 return result;
736}
737
738/* Remove environment variable by pattern */
739static void
740rm_env(Options *options, const char *arg, const char *filename, int linenum)
741{
742 int i, j, onum_send_env = options->num_send_env;
743 char *cp;
744
745 /* Remove an environment variable */
746 for (i = 0; i < options->num_send_env; ) {
747 cp = xstrdup(options->send_env[i]);
748 if (!match_pattern(cp, arg + 1)) {
749 free(cp);
750 i++;
751 continue;
752 }
753 debug3("%s line %d: removing environment %s",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 754, 0, SYSLOG_LEVEL_DEBUG3, ((void *)0), "%s line %d: removing environment %s"
, filename, linenum, cp)
754 filename, linenum, cp)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 754, 0, SYSLOG_LEVEL_DEBUG3, ((void *)0), "%s line %d: removing environment %s"
, filename, linenum, cp)
;
755 free(cp);
756 free(options->send_env[i]);
757 options->send_env[i] = NULL((void *)0);
758 for (j = i; j < options->num_send_env - 1; j++) {
759 options->send_env[j] = options->send_env[j + 1];
760 options->send_env[j + 1] = NULL((void *)0);
761 }
762 options->num_send_env--;
763 /* NB. don't increment i */
764 }
765 if (onum_send_env != options->num_send_env) {
766 options->send_env = xrecallocarray(options->send_env,
767 onum_send_env, options->num_send_env,
768 sizeof(*options->send_env));
769 }
770}
771
772/*
773 * Returns the number of the token pointed to by cp or oBadOption.
774 */
775static OpCodes
776parse_token(const char *cp, const char *filename, int linenum,
777 const char *ignored_unknown)
778{
779 int i;
780
781 for (i = 0; keywords[i].name; i++)
782 if (strcmp(cp, keywords[i].name) == 0)
783 return keywords[i].opcode;
784 if (ignored_unknown != NULL((void *)0) &&
785 match_pattern_list(cp, ignored_unknown, 1) == 1)
786 return oIgnoredUnknownOption;
787 error("%s: line %d: Bad configuration option: %s",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 788, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s: line %d: Bad configuration option: %s"
, filename, linenum, cp)
788 filename, linenum, cp)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 788, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s: line %d: Bad configuration option: %s"
, filename, linenum, cp)
;
789 return oBadOption;
790}
791
792/* Multistate option parsing */
793struct multistate {
794 char *key;
795 int value;
796};
797static const struct multistate multistate_flag[] = {
798 { "true", 1 },
799 { "false", 0 },
800 { "yes", 1 },
801 { "no", 0 },
802 { NULL((void *)0), -1 }
803};
804static const struct multistate multistate_yesnoask[] = {
805 { "true", 1 },
806 { "false", 0 },
807 { "yes", 1 },
808 { "no", 0 },
809 { "ask", 2 },
810 { NULL((void *)0), -1 }
811};
812static const struct multistate multistate_strict_hostkey[] = {
813 { "true", SSH_STRICT_HOSTKEY_YES2 },
814 { "false", SSH_STRICT_HOSTKEY_OFF0 },
815 { "yes", SSH_STRICT_HOSTKEY_YES2 },
816 { "no", SSH_STRICT_HOSTKEY_OFF0 },
817 { "ask", SSH_STRICT_HOSTKEY_ASK3 },
818 { "off", SSH_STRICT_HOSTKEY_OFF0 },
819 { "accept-new", SSH_STRICT_HOSTKEY_NEW1 },
820 { NULL((void *)0), -1 }
821};
822static const struct multistate multistate_yesnoaskconfirm[] = {
823 { "true", 1 },
824 { "false", 0 },
825 { "yes", 1 },
826 { "no", 0 },
827 { "ask", 2 },
828 { "confirm", 3 },
829 { NULL((void *)0), -1 }
830};
831static const struct multistate multistate_addressfamily[] = {
832 { "inet", AF_INET2 },
833 { "inet6", AF_INET624 },
834 { "any", AF_UNSPEC0 },
835 { NULL((void *)0), -1 }
836};
837static const struct multistate multistate_controlmaster[] = {
838 { "true", SSHCTL_MASTER_YES1 },
839 { "yes", SSHCTL_MASTER_YES1 },
840 { "false", SSHCTL_MASTER_NO0 },
841 { "no", SSHCTL_MASTER_NO0 },
842 { "auto", SSHCTL_MASTER_AUTO2 },
843 { "ask", SSHCTL_MASTER_ASK3 },
844 { "autoask", SSHCTL_MASTER_AUTO_ASK4 },
845 { NULL((void *)0), -1 }
846};
847static const struct multistate multistate_tunnel[] = {
848 { "ethernet", SSH_TUNMODE_ETHERNET0x02 },
849 { "point-to-point", SSH_TUNMODE_POINTOPOINT0x01 },
850 { "true", SSH_TUNMODE_DEFAULT0x01 },
851 { "yes", SSH_TUNMODE_DEFAULT0x01 },
852 { "false", SSH_TUNMODE_NO0x00 },
853 { "no", SSH_TUNMODE_NO0x00 },
854 { NULL((void *)0), -1 }
855};
856static const struct multistate multistate_requesttty[] = {
857 { "true", REQUEST_TTY_YES2 },
858 { "yes", REQUEST_TTY_YES2 },
859 { "false", REQUEST_TTY_NO1 },
860 { "no", REQUEST_TTY_NO1 },
861 { "force", REQUEST_TTY_FORCE3 },
862 { "auto", REQUEST_TTY_AUTO0 },
863 { NULL((void *)0), -1 }
864};
865static const struct multistate multistate_sessiontype[] = {
866 { "none", SESSION_TYPE_NONE0 },
867 { "subsystem", SESSION_TYPE_SUBSYSTEM1 },
868 { "default", SESSION_TYPE_DEFAULT2 },
869 { NULL((void *)0), -1 }
870};
871static const struct multistate multistate_canonicalizehostname[] = {
872 { "true", SSH_CANONICALISE_YES1 },
873 { "false", SSH_CANONICALISE_NO0 },
874 { "yes", SSH_CANONICALISE_YES1 },
875 { "no", SSH_CANONICALISE_NO0 },
876 { "always", SSH_CANONICALISE_ALWAYS2 },
877 { NULL((void *)0), -1 }
878};
879static const struct multistate multistate_pubkey_auth[] = {
880 { "true", SSH_PUBKEY_AUTH_ALL0x03 },
881 { "false", SSH_PUBKEY_AUTH_NO0x00 },
882 { "yes", SSH_PUBKEY_AUTH_ALL0x03 },
883 { "no", SSH_PUBKEY_AUTH_NO0x00 },
884 { "unbound", SSH_PUBKEY_AUTH_UNBOUND0x01 },
885 { "host-bound", SSH_PUBKEY_AUTH_HBOUND0x02 },
886 { NULL((void *)0), -1 }
887};
888static const struct multistate multistate_compression[] = {
889#ifdef WITH_ZLIB1
890 { "yes", COMP_ZLIB1 },
891#endif
892 { "no", COMP_NONE0 },
893 { NULL((void *)0), -1 }
894};
895
896static int
897parse_multistate_value(const char *arg, const char *filename, int linenum,
898 const struct multistate *multistate_ptr)
899{
900 int i;
901
902 if (!arg || *arg == '\0') {
903 error("%s line %d: missing argument.", filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 903, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: missing argument."
, filename, linenum)
;
904 return -1;
905 }
906 for (i = 0; multistate_ptr[i].key != NULL((void *)0); i++) {
907 if (strcasecmp(arg, multistate_ptr[i].key) == 0)
908 return multistate_ptr[i].value;
909 }
910 return -1;
911}
912
913/*
914 * Processes a single option line as used in the configuration files. This
915 * only sets those values that have not already been set.
916 */
917int
918process_config_line(Options *options, struct passwd *pw, const char *host,
919 const char *original_host, char *line, const char *filename,
920 int linenum, int *activep, int flags)
921{
922 return process_config_line_depth(options, pw, host, original_host,
923 line, filename, linenum, activep, flags, NULL((void *)0), 0);
924}
925
926#define WHITESPACE" \t\r\n" " \t\r\n"
927static int
928process_config_line_depth(Options *options, struct passwd *pw, const char *host,
929 const char *original_host, char *line, const char *filename,
930 int linenum, int *activep, int flags, int *want_final_pass, int depth)
931{
932 char *str, **charptr, *endofnumber, *keyword, *arg, *arg2, *p, ch;
933 char **cpptr, ***cppptr, fwdarg[256];
934 u_int i, *uintptr, uvalue, max_entries = 0;
935 int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0;
936 int remotefwd, dynamicfwd;
937 LogLevel *log_level_ptr;
938 SyslogFacility *log_facility_ptr;
939 long long val64;
940 size_t len;
941 struct Forward fwd;
942 const struct multistate *multistate_ptr;
943 struct allowed_cname *cname;
944 glob_t gl;
945 const char *errstr;
946 char **oav = NULL((void *)0), **av;
947 int oac = 0, ac;
948 int ret = -1;
949
950 if (activep == NULL((void *)0)) { /* We are processing a command line directive */
951 cmdline = 1;
952 activep = &cmdline;
953 }
954
955 /* Strip trailing whitespace. Allow \f (form feed) at EOL only */
956 if ((len = strlen(line)) == 0)
957 return 0;
958 for (len--; len > 0; len--) {
959 if (strchr(WHITESPACE" \t\r\n" "\f", line[len]) == NULL((void *)0))
960 break;
961 line[len] = '\0';
962 }
963
964 str = line;
965 /* Get the keyword. (Each line is supposed to begin with a keyword). */
966 if ((keyword = strdelim(&str)) == NULL((void *)0))
967 return 0;
968 /* Ignore leading whitespace. */
969 if (*keyword == '\0')
970 keyword = strdelim(&str);
971 if (keyword == NULL((void *)0) || !*keyword || *keyword == '\n' || *keyword == '#')
972 return 0;
973 /* Match lowercase keyword */
974 lowercase(keyword);
975
976 /* Prepare to parse remainder of line */
977 if (str != NULL((void *)0))
978 str += strspn(str, WHITESPACE" \t\r\n");
979 if (str == NULL((void *)0) || *str == '\0') {
980 error("%s line %d: no argument after keyword \"%s\"",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 981, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: no argument after keyword \"%s\""
, filename, linenum, keyword)
981 filename, linenum, keyword)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 981, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: no argument after keyword \"%s\""
, filename, linenum, keyword)
;
982 return -1;
983 }
984 opcode = parse_token(keyword, filename, linenum,
985 options->ignored_unknown);
986 if (argv_split(str, &oac, &oav, 1) != 0) {
987 error("%s line %d: invalid quotes", filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 987, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: invalid quotes"
, filename, linenum)
;
988 return -1;
989 }
990 ac = oac;
991 av = oav;
992
993 switch (opcode) {
994 case oBadOption:
995 /* don't panic, but count bad options */
996 goto out;
997 case oIgnore:
998 argv_consume(&ac);
999 break;
1000 case oIgnoredUnknownOption:
1001 debug("%s line %d: Ignored unknown option \"%s\"",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1002, 0, SYSLOG_LEVEL_DEBUG1, ((void *)0), "%s line %d: Ignored unknown option \"%s\""
, filename, linenum, keyword)
1002 filename, linenum, keyword)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1002, 0, SYSLOG_LEVEL_DEBUG1, ((void *)0), "%s line %d: Ignored unknown option \"%s\""
, filename, linenum, keyword)
;
1003 argv_consume(&ac);
1004 break;
1005 case oConnectTimeout:
1006 intptr = &options->connection_timeout;
1007parse_time:
1008 arg = argv_next(&ac, &av);
1009 if (!arg || *arg == '\0') {
1010 error("%s line %d: missing time value.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1011, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: missing time value."
, filename, linenum)
1011 filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1011, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: missing time value."
, filename, linenum)
;
1012 goto out;
1013 }
1014 if (strcmp(arg, "none") == 0)
1015 value = -1;
1016 else if ((value = convtime(arg)) == -1) {
1017 error("%s line %d: invalid time value.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1018, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: invalid time value."
, filename, linenum)
1018 filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1018, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: invalid time value."
, filename, linenum)
;
1019 goto out;
1020 }
1021 if (*activep && *intptr == -1)
1022 *intptr = value;
1023 break;
1024
1025 case oForwardAgent:
1026 intptr = &options->forward_agent;
1027
1028 arg = argv_next(&ac, &av);
1029 if (!arg || *arg == '\0') {
1030 error("%s line %d: missing argument.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1031, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: missing argument."
, filename, linenum)
1031 filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1031, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: missing argument."
, filename, linenum)
;
1032 goto out;
1033 }
1034
1035 value = -1;
1036 multistate_ptr = multistate_flag;
1037 for (i = 0; multistate_ptr[i].key != NULL((void *)0); i++) {
1038 if (strcasecmp(arg, multistate_ptr[i].key) == 0) {
1039 value = multistate_ptr[i].value;
1040 break;
1041 }
1042 }
1043 if (value != -1) {
1044 if (*activep && *intptr == -1)
1045 *intptr = value;
1046 break;
1047 }
1048 /* ForwardAgent wasn't 'yes' or 'no', assume a path */
1049 if (*activep && *intptr == -1)
1050 *intptr = 1;
1051
1052 charptr = &options->forward_agent_sock_path;
1053 goto parse_agent_path;
1054
1055 case oForwardX11:
1056 intptr = &options->forward_x11;
1057 parse_flag:
1058 multistate_ptr = multistate_flag;
1059 parse_multistate:
1060 arg = argv_next(&ac, &av);
1061 if ((value = parse_multistate_value(arg, filename, linenum,
1062 multistate_ptr)) == -1) {
1063 error("%s line %d: unsupported option \"%s\".",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1064, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: unsupported option \"%s\"."
, filename, linenum, arg)
1064 filename, linenum, arg)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1064, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: unsupported option \"%s\"."
, filename, linenum, arg)
;
1065 goto out;
1066 }
1067 if (*activep && *intptr == -1)
1068 *intptr = value;
1069 break;
1070
1071 case oForwardX11Trusted:
1072 intptr = &options->forward_x11_trusted;
1073 goto parse_flag;
1074
1075 case oForwardX11Timeout:
1076 intptr = &options->forward_x11_timeout;
1077 goto parse_time;
1078
1079 case oGatewayPorts:
1080 intptr = &options->fwd_opts.gateway_ports;
1081 goto parse_flag;
1082
1083 case oExitOnForwardFailure:
1084 intptr = &options->exit_on_forward_failure;
1085 goto parse_flag;
1086
1087 case oPasswordAuthentication:
1088 intptr = &options->password_authentication;
1089 goto parse_flag;
1090
1091 case oKbdInteractiveAuthentication:
1092 intptr = &options->kbd_interactive_authentication;
1093 goto parse_flag;
1094
1095 case oKbdInteractiveDevices:
1096 charptr = &options->kbd_interactive_devices;
1097 goto parse_string;
1098
1099 case oPubkeyAuthentication:
1100 multistate_ptr = multistate_pubkey_auth;
1101 intptr = &options->pubkey_authentication;
1102 goto parse_multistate;
1103
1104 case oHostbasedAuthentication:
1105 intptr = &options->hostbased_authentication;
1106 goto parse_flag;
1107
1108 case oGssAuthentication:
1109 intptr = &options->gss_authentication;
1110 goto parse_flag;
1111
1112 case oGssDelegateCreds:
1113 intptr = &options->gss_deleg_creds;
1114 goto parse_flag;
1115
1116 case oBatchMode:
1117 intptr = &options->batch_mode;
1118 goto parse_flag;
1119
1120 case oCheckHostIP:
1121 intptr = &options->check_host_ip;
1122 goto parse_flag;
1123
1124 case oVerifyHostKeyDNS:
1125 intptr = &options->verify_host_key_dns;
1126 multistate_ptr = multistate_yesnoask;
1127 goto parse_multistate;
1128
1129 case oStrictHostKeyChecking:
1130 intptr = &options->strict_host_key_checking;
1131 multistate_ptr = multistate_strict_hostkey;
1132 goto parse_multistate;
1133
1134 case oCompression:
1135 intptr = &options->compression;
1136 multistate_ptr = multistate_compression;
1137 goto parse_multistate;
1138
1139 case oTCPKeepAlive:
1140 intptr = &options->tcp_keep_alive;
1141 goto parse_flag;
1142
1143 case oNoHostAuthenticationForLocalhost:
1144 intptr = &options->no_host_authentication_for_localhost;
1145 goto parse_flag;
1146
1147 case oNumberOfPasswordPrompts:
1148 intptr = &options->number_of_password_prompts;
1149 goto parse_int;
1150
1151 case oRekeyLimit:
1152 arg = argv_next(&ac, &av);
1153 if (!arg || *arg == '\0') {
1154 error("%.200s line %d: Missing argument.", filename,sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1155, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing argument."
, filename, linenum)
1155 linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1155, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing argument."
, filename, linenum)
;
1156 goto out;
1157 }
1158 if (strcmp(arg, "default") == 0) {
1159 val64 = 0;
1160 } else {
1161 if (scan_scaled(arg, &val64) == -1) {
1162 error("%.200s line %d: Bad number '%s': %s",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1163, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Bad number '%s': %s"
, filename, linenum, arg, strerror((*__errno())))
1163 filename, linenum, arg, strerror(errno))sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1163, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Bad number '%s': %s"
, filename, linenum, arg, strerror((*__errno())))
;
1164 goto out;
1165 }
1166 if (val64 != 0 && val64 < 16) {
1167 error("%.200s line %d: RekeyLimit too small",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1168, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: RekeyLimit too small"
, filename, linenum)
1168 filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1168, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: RekeyLimit too small"
, filename, linenum)
;
1169 goto out;
1170 }
1171 }
1172 if (*activep && options->rekey_limit == -1)
1173 options->rekey_limit = val64;
1174 if (ac != 0) { /* optional rekey interval present */
1175 if (strcmp(av[0], "none") == 0) {
1176 (void)argv_next(&ac, &av); /* discard */
1177 break;
1178 }
1179 intptr = &options->rekey_interval;
1180 goto parse_time;
1181 }
1182 break;
1183
1184 case oIdentityFile:
1185 arg = argv_next(&ac, &av);
1186 if (!arg || *arg == '\0') {
1187 error("%.200s line %d: Missing argument.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1188, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing argument."
, filename, linenum)
1188 filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1188, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing argument."
, filename, linenum)
;
1189 goto out;
1190 }
1191 if (*activep) {
1192 intptr = &options->num_identity_files;
1193 if (*intptr >= SSH_MAX_IDENTITY_FILES100) {
1194 error("%.200s line %d: Too many identity files "sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1196, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Too many identity files "
"specified (max %d).", filename, linenum, 100)
1195 "specified (max %d).", filename, linenum,sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1196, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Too many identity files "
"specified (max %d).", filename, linenum, 100)
1196 SSH_MAX_IDENTITY_FILES)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1196, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Too many identity files "
"specified (max %d).", filename, linenum, 100)
;
1197 goto out;
1198 }
1199 add_identity_file(options, NULL((void *)0),
1200 arg, flags & SSHCONF_USERCONF2);
1201 }
1202 break;
1203
1204 case oCertificateFile:
1205 arg = argv_next(&ac, &av);
1206 if (!arg || *arg == '\0') {
1207 error("%.200s line %d: Missing argument.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1208, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing argument."
, filename, linenum)
1208 filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1208, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing argument."
, filename, linenum)
;
1209 goto out;
1210 }
1211 if (*activep) {
1212 intptr = &options->num_certificate_files;
1213 if (*intptr >= SSH_MAX_CERTIFICATE_FILES100) {
1214 error("%.200s line %d: Too many certificate "sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1217, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Too many certificate "
"files specified (max %d).", filename, linenum, 100)
1215 "files specified (max %d).",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1217, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Too many certificate "
"files specified (max %d).", filename, linenum, 100)
1216 filename, linenum,sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1217, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Too many certificate "
"files specified (max %d).", filename, linenum, 100)
1217 SSH_MAX_CERTIFICATE_FILES)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1217, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Too many certificate "
"files specified (max %d).", filename, linenum, 100)
;
1218 goto out;
1219 }
1220 add_certificate_file(options, arg,
1221 flags & SSHCONF_USERCONF2);
1222 }
1223 break;
1224
1225 case oXAuthLocation:
1226 charptr=&options->xauth_location;
1227 goto parse_string;
1228
1229 case oUser:
1230 charptr = &options->user;
1231parse_string:
1232 arg = argv_next(&ac, &av);
1233 if (!arg || *arg == '\0') {
1234 error("%.200s line %d: Missing argument.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1235, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing argument."
, filename, linenum)
1235 filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1235, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing argument."
, filename, linenum)
;
1236 goto out;
1237 }
1238 if (*activep && *charptr == NULL((void *)0))
1239 *charptr = xstrdup(arg);
1240 break;
1241
1242 case oGlobalKnownHostsFile:
1243 cpptr = (char **)&options->system_hostfiles;
1244 uintptr = &options->num_system_hostfiles;
1245 max_entries = SSH_MAX_HOSTS_FILES32;
1246parse_char_array:
1247 i = 0;
1248 value = *uintptr == 0; /* was array empty when we started? */
1249 while ((arg = argv_next(&ac, &av)) != NULL((void *)0)) {
1250 if (*arg == '\0') {
1251 error("%s line %d: keyword %s empty argument",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1252, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: keyword %s empty argument"
, filename, linenum, keyword)
1252 filename, linenum, keyword)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1252, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: keyword %s empty argument"
, filename, linenum, keyword)
;
1253 goto out;
1254 }
1255 /* Allow "none" only in first position */
1256 if (strcasecmp(arg, "none") == 0) {
1257 if (i > 0 || ac > 0) {
1258 error("%s line %d: keyword %s \"none\" "sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1260, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: keyword %s \"none\" "
"argument must appear alone.", filename, linenum, keyword)
1259 "argument must appear alone.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1260, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: keyword %s \"none\" "
"argument must appear alone.", filename, linenum, keyword)
1260 filename, linenum, keyword)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1260, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: keyword %s \"none\" "
"argument must appear alone.", filename, linenum, keyword)
;
1261 goto out;
1262 }
1263 }
1264 i++;
1265 if (*activep && value) {
1266 if ((*uintptr) >= max_entries) {
1267 error("%s line %d: too many %s "sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1269, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: too many %s "
"entries.", filename, linenum, keyword)
1268 "entries.", filename, linenum,sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1269, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: too many %s "
"entries.", filename, linenum, keyword)
1269 keyword)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1269, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: too many %s "
"entries.", filename, linenum, keyword)
;
1270 goto out;
1271 }
1272 cpptr[(*uintptr)++] = xstrdup(arg);
1273 }
1274 }
1275 break;
1276
1277 case oUserKnownHostsFile:
1278 cpptr = (char **)&options->user_hostfiles;
1279 uintptr = &options->num_user_hostfiles;
1280 max_entries = SSH_MAX_HOSTS_FILES32;
1281 goto parse_char_array;
1282
1283 case oHostname:
1284 charptr = &options->hostname;
1285 goto parse_string;
1286
1287 case oHostKeyAlias:
1288 charptr = &options->host_key_alias;
1289 goto parse_string;
1290
1291 case oPreferredAuthentications:
1292 charptr = &options->preferred_authentications;
1293 goto parse_string;
1294
1295 case oBindAddress:
1296 charptr = &options->bind_address;
1297 goto parse_string;
1298
1299 case oBindInterface:
1300 charptr = &options->bind_interface;
1301 goto parse_string;
1302
1303 case oPKCS11Provider:
1304 charptr = &options->pkcs11_provider;
1305 goto parse_string;
1306
1307 case oSecurityKeyProvider:
1308 charptr = &options->sk_provider;
1309 goto parse_string;
1310
1311 case oKnownHostsCommand:
1312 charptr = &options->known_hosts_command;
1313 goto parse_command;
1314
1315 case oProxyCommand:
1316 charptr = &options->proxy_command;
1317 /* Ignore ProxyCommand if ProxyJump already specified */
1318 if (options->jump_host != NULL((void *)0))
1319 charptr = &options->jump_host; /* Skip below */
1320parse_command:
1321 if (str == NULL((void *)0)) {
1322 error("%.200s line %d: Missing argument.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1323, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing argument."
, filename, linenum)
1323 filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1323, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing argument."
, filename, linenum)
;
1324 goto out;
1325 }
1326 len = strspn(str, WHITESPACE" \t\r\n" "=");
1327 if (*activep && *charptr == NULL((void *)0))
1328 *charptr = xstrdup(str + len);
1329 argv_consume(&ac);
1330 break;
1331
1332 case oProxyJump:
1333 if (str == NULL((void *)0)) {
1334 error("%.200s line %d: Missing argument.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1335, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing argument."
, filename, linenum)
1335 filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1335, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing argument."
, filename, linenum)
;
1336 goto out;
1337 }
1338 len = strspn(str, WHITESPACE" \t\r\n" "=");
1339 /* XXX use argv? */
1340 if (parse_jump(str + len, options, *activep) == -1) {
1341 error("%.200s line %d: Invalid ProxyJump \"%s\"",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1342, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Invalid ProxyJump \"%s\""
, filename, linenum, str + len)
1342 filename, linenum, str + len)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1342, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Invalid ProxyJump \"%s\""
, filename, linenum, str + len)
;
1343 goto out;
1344 }
1345 argv_consume(&ac);
1346 break;
1347
1348 case oPort:
1349 arg = argv_next(&ac, &av);
1350 if (!arg || *arg == '\0') {
1351 error("%.200s line %d: Missing argument.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1352, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing argument."
, filename, linenum)
1352 filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1352, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing argument."
, filename, linenum)
;
1353 goto out;
1354 }
1355 value = a2port(arg);
1356 if (value <= 0) {
1357 error("%.200s line %d: Bad port '%s'.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1358, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Bad port '%s'."
, filename, linenum, arg)
1358 filename, linenum, arg)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1358, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Bad port '%s'."
, filename, linenum, arg)
;
1359 goto out;
1360 }
1361 if (*activep && options->port == -1)
1362 options->port = value;
1363 break;
1364
1365 case oConnectionAttempts:
1366 intptr = &options->connection_attempts;
1367parse_int:
1368 arg = argv_next(&ac, &av);
1369 if ((errstr = atoi_err(arg, &value)) != NULL((void *)0)) {
1370 error("%s line %d: integer value %s.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1371, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: integer value %s."
, filename, linenum, errstr)
1371 filename, linenum, errstr)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1371, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: integer value %s."
, filename, linenum, errstr)
;
1372 goto out;
1373 }
1374 if (*activep && *intptr == -1)
1375 *intptr = value;
1376 break;
1377
1378 case oCiphers:
1379 arg = argv_next(&ac, &av);
1380 if (!arg || *arg == '\0') {
1381 error("%.200s line %d: Missing argument.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1382, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing argument."
, filename, linenum)
1382 filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1382, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing argument."
, filename, linenum)
;
1383 goto out;
1384 }
1385 if (*arg != '-' &&
1386 !ciphers_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg)){
1387 error("%.200s line %d: Bad SSH2 cipher spec '%s'.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1388, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Bad SSH2 cipher spec '%s'."
, filename, linenum, arg ? arg : "<NONE>")
1388 filename, linenum, arg ? arg : "<NONE>")sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1388, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Bad SSH2 cipher spec '%s'."
, filename, linenum, arg ? arg : "<NONE>")
;
1389 goto out;
1390 }
1391 if (*activep && options->ciphers == NULL((void *)0))
1392 options->ciphers = xstrdup(arg);
1393 break;
1394
1395 case oMacs:
1396 arg = argv_next(&ac, &av);
1397 if (!arg || *arg == '\0') {
1398 error("%.200s line %d: Missing argument.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1399, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing argument."
, filename, linenum)
1399 filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1399, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing argument."
, filename, linenum)
;
1400 goto out;
1401 }
1402 if (*arg != '-' &&
1403 !mac_valid(*arg == '+' || *arg == '^' ? arg + 1 : arg)) {
1404 error("%.200s line %d: Bad SSH2 MAC spec '%s'.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1405, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Bad SSH2 MAC spec '%s'."
, filename, linenum, arg ? arg : "<NONE>")
1405 filename, linenum, arg ? arg : "<NONE>")sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1405, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Bad SSH2 MAC spec '%s'."
, filename, linenum, arg ? arg : "<NONE>")
;
1406 goto out;
1407 }
1408 if (*activep && options->macs == NULL((void *)0))
1409 options->macs = xstrdup(arg);
1410 break;
1411
1412 case oKexAlgorithms:
1413 arg = argv_next(&ac, &av);
1414 if (!arg || *arg == '\0') {
1415 error("%.200s line %d: Missing argument.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1416, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing argument."
, filename, linenum)
1416 filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1416, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing argument."
, filename, linenum)
;
1417 goto out;
1418 }
1419 if (*arg != '-' &&
1420 !kex_names_valid(*arg == '+' || *arg == '^' ?
1421 arg + 1 : arg)) {
1422 error("%.200s line %d: Bad SSH2 KexAlgorithms '%s'.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1423, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Bad SSH2 KexAlgorithms '%s'."
, filename, linenum, arg ? arg : "<NONE>")
1423 filename, linenum, arg ? arg : "<NONE>")sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1423, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Bad SSH2 KexAlgorithms '%s'."
, filename, linenum, arg ? arg : "<NONE>")
;
1424 goto out;
1425 }
1426 if (*activep && options->kex_algorithms == NULL((void *)0))
1427 options->kex_algorithms = xstrdup(arg);
1428 break;
1429
1430 case oHostKeyAlgorithms:
1431 charptr = &options->hostkeyalgorithms;
1432parse_pubkey_algos:
1433 arg = argv_next(&ac, &av);
1434 if (!arg || *arg == '\0') {
1435 error("%.200s line %d: Missing argument.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1436, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing argument."
, filename, linenum)
1436 filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1436, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing argument."
, filename, linenum)
;
1437 goto out;
1438 }
1439 if (*arg != '-' &&
1440 !sshkey_names_valid2(*arg == '+' || *arg == '^' ?
1441 arg + 1 : arg, 1)) {
1442 error("%s line %d: Bad key types '%s'.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1443, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: Bad key types '%s'."
, filename, linenum, arg ? arg : "<NONE>")
1443 filename, linenum, arg ? arg : "<NONE>")sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1443, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: Bad key types '%s'."
, filename, linenum, arg ? arg : "<NONE>")
;
1444 goto out;
1445 }
1446 if (*activep && *charptr == NULL((void *)0))
1447 *charptr = xstrdup(arg);
1448 break;
1449
1450 case oCASignatureAlgorithms:
1451 charptr = &options->ca_sign_algorithms;
1452 goto parse_pubkey_algos;
1453
1454 case oLogLevel:
1455 log_level_ptr = &options->log_level;
1456 arg = argv_next(&ac, &av);
1457 value = log_level_number(arg);
1458 if (value == SYSLOG_LEVEL_NOT_SET) {
1459 error("%.200s line %d: unsupported log level '%s'",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1460, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: unsupported log level '%s'"
, filename, linenum, arg ? arg : "<NONE>")
1460 filename, linenum, arg ? arg : "<NONE>")sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1460, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: unsupported log level '%s'"
, filename, linenum, arg ? arg : "<NONE>")
;
1461 goto out;
1462 }
1463 if (*activep && *log_level_ptr == SYSLOG_LEVEL_NOT_SET)
1464 *log_level_ptr = (LogLevel) value;
1465 break;
1466
1467 case oLogFacility:
1468 log_facility_ptr = &options->log_facility;
1469 arg = argv_next(&ac, &av);
1470 value = log_facility_number(arg);
1471 if (value == SYSLOG_FACILITY_NOT_SET) {
1472 error("%.200s line %d: unsupported log facility '%s'",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1473, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: unsupported log facility '%s'"
, filename, linenum, arg ? arg : "<NONE>")
1473 filename, linenum, arg ? arg : "<NONE>")sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1473, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: unsupported log facility '%s'"
, filename, linenum, arg ? arg : "<NONE>")
;
1474 goto out;
1475 }
1476 if (*log_facility_ptr == -1)
1477 *log_facility_ptr = (SyslogFacility) value;
1478 break;
1479
1480 case oLogVerbose:
1481 cppptr = &options->log_verbose;
1482 uintptr = &options->num_log_verbose;
1483 i = 0;
1484 while ((arg = argv_next(&ac, &av)) != NULL((void *)0)) {
1485 if (*arg == '\0') {
1486 error("%s line %d: keyword %s empty argument",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1487, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: keyword %s empty argument"
, filename, linenum, keyword)
1487 filename, linenum, keyword)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1487, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: keyword %s empty argument"
, filename, linenum, keyword)
;
1488 goto out;
1489 }
1490 /* Allow "none" only in first position */
1491 if (strcasecmp(arg, "none") == 0) {
1492 if (i > 0 || ac > 0) {
1493 error("%s line %d: keyword %s \"none\" "sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1495, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: keyword %s \"none\" "
"argument must appear alone.", filename, linenum, keyword)
1494 "argument must appear alone.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1495, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: keyword %s \"none\" "
"argument must appear alone.", filename, linenum, keyword)
1495 filename, linenum, keyword)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1495, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: keyword %s \"none\" "
"argument must appear alone.", filename, linenum, keyword)
;
1496 goto out;
1497 }
1498 }
1499 i++;
1500 if (*activep && *uintptr == 0) {
1501 *cppptr = xrecallocarray(*cppptr, *uintptr,
1502 *uintptr + 1, sizeof(**cppptr));
1503 (*cppptr)[(*uintptr)++] = xstrdup(arg);
1504 }
1505 }
1506 break;
1507
1508 case oLocalForward:
1509 case oRemoteForward:
1510 case oDynamicForward:
1511 arg = argv_next(&ac, &av);
1512 if (!arg || *arg == '\0') {
1513 error("%.200s line %d: Missing argument.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1514, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing argument."
, filename, linenum)
1514 filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1514, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing argument."
, filename, linenum)
;
1515 goto out;
1516 }
1517
1518 remotefwd = (opcode == oRemoteForward);
1519 dynamicfwd = (opcode == oDynamicForward);
1520
1521 if (!dynamicfwd) {
1522 arg2 = argv_next(&ac, &av);
1523 if (arg2 == NULL((void *)0) || *arg2 == '\0') {
1524 if (remotefwd)
1525 dynamicfwd = 1;
1526 else {
1527 error("%.200s line %d: Missing target "sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1528, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing target "
"argument.", filename, linenum)
1528 "argument.", filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1528, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing target "
"argument.", filename, linenum)
;
1529 goto out;
1530 }
1531 } else {
1532 /* construct a string for parse_forward */
1533 snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg,
1534 arg2);
1535 }
1536 }
1537 if (dynamicfwd)
1538 strlcpy(fwdarg, arg, sizeof(fwdarg));
1539
1540 if (parse_forward(&fwd, fwdarg, dynamicfwd, remotefwd) == 0) {
1541 error("%.200s line %d: Bad forwarding specification.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1542, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Bad forwarding specification."
, filename, linenum)
1542 filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1542, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Bad forwarding specification."
, filename, linenum)
;
1543 goto out;
1544 }
1545
1546 if (*activep) {
1547 if (remotefwd) {
1548 add_remote_forward(options, &fwd);
1549 } else {
1550 add_local_forward(options, &fwd);
1551 }
1552 }
1553 break;
1554
1555 case oPermitRemoteOpen:
1556 uintptr = &options->num_permitted_remote_opens;
1557 cppptr = &options->permitted_remote_opens;
1558 arg = argv_next(&ac, &av);
1559 if (!arg || *arg == '\0')
1560 fatal("%s line %d: missing %s specification",sshfatal("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1561, 0, SYSLOG_LEVEL_FATAL, ((void *)0), "%s line %d: missing %s specification"
, filename, linenum, lookup_opcode_name(opcode))
1561 filename, linenum, lookup_opcode_name(opcode))sshfatal("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1561, 0, SYSLOG_LEVEL_FATAL, ((void *)0), "%s line %d: missing %s specification"
, filename, linenum, lookup_opcode_name(opcode))
;
1562 uvalue = *uintptr; /* modified later */
1563 if (strcmp(arg, "any") == 0 || strcmp(arg, "none") == 0) {
1564 if (*activep && uvalue == 0) {
1565 *uintptr = 1;
1566 *cppptr = xcalloc(1, sizeof(**cppptr));
1567 (*cppptr)[0] = xstrdup(arg);
1568 }
1569 break;
1570 }
1571 while ((arg = argv_next(&ac, &av)) != NULL((void *)0)) {
1572 arg2 = xstrdup(arg);
1573 ch = '\0';
1574 p = hpdelim2(&arg, &ch);
1575 if (p == NULL((void *)0) || ch == '/') {
1576 fatal("%s line %d: missing host in %s",sshfatal("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1578, 0, SYSLOG_LEVEL_FATAL, ((void *)0), "%s line %d: missing host in %s"
, filename, linenum, lookup_opcode_name(opcode))
1577 filename, linenum,sshfatal("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1578, 0, SYSLOG_LEVEL_FATAL, ((void *)0), "%s line %d: missing host in %s"
, filename, linenum, lookup_opcode_name(opcode))
1578 lookup_opcode_name(opcode))sshfatal("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1578, 0, SYSLOG_LEVEL_FATAL, ((void *)0), "%s line %d: missing host in %s"
, filename, linenum, lookup_opcode_name(opcode))
;
1579 }
1580 p = cleanhostname(p);
Value stored to 'p' is never read
1581 /*
1582 * don't want to use permitopen_port to avoid
1583 * dependency on channels.[ch] here.
1584 */
1585 if (arg == NULL((void *)0) ||
1586 (strcmp(arg, "*") != 0 && a2port(arg) <= 0)) {
1587 fatal("%s line %d: bad port number in %s",sshfatal("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1589, 0, SYSLOG_LEVEL_FATAL, ((void *)0), "%s line %d: bad port number in %s"
, filename, linenum, lookup_opcode_name(opcode))
1588 filename, linenum,sshfatal("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1589, 0, SYSLOG_LEVEL_FATAL, ((void *)0), "%s line %d: bad port number in %s"
, filename, linenum, lookup_opcode_name(opcode))
1589 lookup_opcode_name(opcode))sshfatal("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1589, 0, SYSLOG_LEVEL_FATAL, ((void *)0), "%s line %d: bad port number in %s"
, filename, linenum, lookup_opcode_name(opcode))
;
1590 }
1591 if (*activep && uvalue == 0) {
1592 opt_array_append(filename, linenum,
1593 lookup_opcode_name(opcode),
1594 cppptr, uintptr, arg2);
1595 }
1596 free(arg2);
1597 }
1598 break;
1599
1600 case oClearAllForwardings:
1601 intptr = &options->clear_forwardings;
1602 goto parse_flag;
1603
1604 case oHost:
1605 if (cmdline) {
1606 error("Host directive not supported as a command-line "sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1607, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "Host directive not supported as a command-line "
"option")
1607 "option")sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1607, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "Host directive not supported as a command-line "
"option")
;
1608 goto out;
1609 }
1610 *activep = 0;
1611 arg2 = NULL((void *)0);
1612 while ((arg = argv_next(&ac, &av)) != NULL((void *)0)) {
1613 if (*arg == '\0') {
1614 error("%s line %d: keyword %s empty argument",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1615, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: keyword %s empty argument"
, filename, linenum, keyword)
1615 filename, linenum, keyword)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1615, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: keyword %s empty argument"
, filename, linenum, keyword)
;
1616 goto out;
1617 }
1618 if ((flags & SSHCONF_NEVERMATCH8) != 0) {
1619 argv_consume(&ac);
1620 break;
1621 }
1622 negated = *arg == '!';
1623 if (negated)
1624 arg++;
1625 if (match_pattern(host, arg)) {
1626 if (negated) {
1627 debug("%.200s line %d: Skipping Host "sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1630, 0, SYSLOG_LEVEL_DEBUG1, ((void *)0), "%.200s line %d: Skipping Host "
"block because of negated match " "for %.100s", filename, linenum
, arg)
1628 "block because of negated match "sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1630, 0, SYSLOG_LEVEL_DEBUG1, ((void *)0), "%.200s line %d: Skipping Host "
"block because of negated match " "for %.100s", filename, linenum
, arg)
1629 "for %.100s", filename, linenum,sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1630, 0, SYSLOG_LEVEL_DEBUG1, ((void *)0), "%.200s line %d: Skipping Host "
"block because of negated match " "for %.100s", filename, linenum
, arg)
1630 arg)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1630, 0, SYSLOG_LEVEL_DEBUG1, ((void *)0), "%.200s line %d: Skipping Host "
"block because of negated match " "for %.100s", filename, linenum
, arg)
;
1631 *activep = 0;
1632 argv_consume(&ac);
1633 break;
1634 }
1635 if (!*activep)
1636 arg2 = arg; /* logged below */
1637 *activep = 1;
1638 }
1639 }
1640 if (*activep)
1641 debug("%.200s line %d: Applying options for %.100s",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1642, 0, SYSLOG_LEVEL_DEBUG1, ((void *)0), "%.200s line %d: Applying options for %.100s"
, filename, linenum, arg2)
1642 filename, linenum, arg2)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1642, 0, SYSLOG_LEVEL_DEBUG1, ((void *)0), "%.200s line %d: Applying options for %.100s"
, filename, linenum, arg2)
;
1643 break;
1644
1645 case oMatch:
1646 if (cmdline) {
1647 error("Host directive not supported as a command-line "sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1648, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "Host directive not supported as a command-line "
"option")
1648 "option")sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1648, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "Host directive not supported as a command-line "
"option")
;
1649 goto out;
1650 }
1651 value = match_cfg_line(options, &str, pw, host, original_host,
1652 flags & SSHCONF_FINAL4, want_final_pass,
1653 filename, linenum);
1654 if (value < 0) {
1655 error("%.200s line %d: Bad Match condition", filename,sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1656, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Bad Match condition"
, filename, linenum)
1656 linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1656, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Bad Match condition"
, filename, linenum)
;
1657 goto out;
1658 }
1659 *activep = (flags & SSHCONF_NEVERMATCH8) ? 0 : value;
1660 /*
1661 * If match_cfg_line() didn't consume all its arguments then
1662 * arrange for the extra arguments check below to fail.
1663 */
1664
1665 if (str == NULL((void *)0) || *str == '\0')
1666 argv_consume(&ac);
1667 break;
1668
1669 case oEscapeChar:
1670 intptr = &options->escape_char;
1671 arg = argv_next(&ac, &av);
1672 if (!arg || *arg == '\0') {
1673 error("%.200s line %d: Missing argument.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1674, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing argument."
, filename, linenum)
1674 filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1674, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing argument."
, filename, linenum)
;
1675 goto out;
1676 }
1677 if (strcmp(arg, "none") == 0)
1678 value = SSH_ESCAPECHAR_NONE-2;
1679 else if (arg[1] == '\0')
1680 value = (u_char) arg[0];
1681 else if (arg[0] == '^' && arg[2] == 0 &&
1682 (u_char) arg[1] >= 64 && (u_char) arg[1] < 128)
1683 value = (u_char) arg[1] & 31;
1684 else {
1685 error("%.200s line %d: Bad escape character.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1686, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Bad escape character."
, filename, linenum)
1686 filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1686, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Bad escape character."
, filename, linenum)
;
1687 goto out;
1688 }
1689 if (*activep && *intptr == -1)
1690 *intptr = value;
1691 break;
1692
1693 case oAddressFamily:
1694 intptr = &options->address_family;
1695 multistate_ptr = multistate_addressfamily;
1696 goto parse_multistate;
1697
1698 case oEnableSSHKeysign:
1699 intptr = &options->enable_ssh_keysign;
1700 goto parse_flag;
1701
1702 case oIdentitiesOnly:
1703 intptr = &options->identities_only;
1704 goto parse_flag;
1705
1706 case oServerAliveInterval:
1707 intptr = &options->server_alive_interval;
1708 goto parse_time;
1709
1710 case oServerAliveCountMax:
1711 intptr = &options->server_alive_count_max;
1712 goto parse_int;
1713
1714 case oSendEnv:
1715 while ((arg = argv_next(&ac, &av)) != NULL((void *)0)) {
1716 if (*arg == '\0' || strchr(arg, '=') != NULL((void *)0)) {
1717 error("%s line %d: Invalid environment name.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1718, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: Invalid environment name."
, filename, linenum)
1718 filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1718, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: Invalid environment name."
, filename, linenum)
;
1719 goto out;
1720 }
1721 if (!*activep)
1722 continue;
1723 if (*arg == '-') {
1724 /* Removing an env var */
1725 rm_env(options, arg, filename, linenum);
1726 continue;
1727 } else {
1728 /* Adding an env var */
1729 if (options->num_send_env >= INT_MAX2147483647) {
1730 error("%s line %d: too many send env.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1731, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: too many send env."
, filename, linenum)
1731 filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1731, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: too many send env."
, filename, linenum)
;
1732 goto out;
1733 }
1734 options->send_env = xrecallocarray(
1735 options->send_env, options->num_send_env,
1736 options->num_send_env + 1,
1737 sizeof(*options->send_env));
1738 options->send_env[options->num_send_env++] =
1739 xstrdup(arg);
1740 }
1741 }
1742 break;
1743
1744 case oSetEnv:
1745 value = options->num_setenv;
1746 while ((arg = argv_next(&ac, &av)) != NULL((void *)0)) {
1747 if (strchr(arg, '=') == NULL((void *)0)) {
1748 error("%s line %d: Invalid SetEnv.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1749, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: Invalid SetEnv."
, filename, linenum)
1749 filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1749, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: Invalid SetEnv."
, filename, linenum)
;
1750 goto out;
1751 }
1752 if (!*activep || value != 0)
1753 continue;
1754 /* Adding a setenv var */
1755 if (options->num_setenv >= INT_MAX2147483647) {
1756 error("%s line %d: too many SetEnv.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1757, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: too many SetEnv."
, filename, linenum)
1757 filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1757, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: too many SetEnv."
, filename, linenum)
;
1758 goto out;
1759 }
1760 options->setenv = xrecallocarray(
1761 options->setenv, options->num_setenv,
1762 options->num_setenv + 1, sizeof(*options->setenv));
1763 options->setenv[options->num_setenv++] = xstrdup(arg);
1764 }
1765 break;
1766
1767 case oControlPath:
1768 charptr = &options->control_path;
1769 goto parse_string;
1770
1771 case oControlMaster:
1772 intptr = &options->control_master;
1773 multistate_ptr = multistate_controlmaster;
1774 goto parse_multistate;
1775
1776 case oControlPersist:
1777 /* no/false/yes/true, or a time spec */
1778 intptr = &options->control_persist;
1779 arg = argv_next(&ac, &av);
1780 if (!arg || *arg == '\0') {
1781 error("%.200s line %d: Missing ControlPersist"sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1782, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing ControlPersist"
" argument.", filename, linenum)
1782 " argument.", filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1782, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing ControlPersist"
" argument.", filename, linenum)
;
1783 goto out;
1784 }
1785 value = 0;
1786 value2 = 0; /* timeout */
1787 if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
1788 value = 0;
1789 else if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
1790 value = 1;
1791 else if ((value2 = convtime(arg)) >= 0)
1792 value = 1;
1793 else {
1794 error("%.200s line %d: Bad ControlPersist argument.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1795, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Bad ControlPersist argument."
, filename, linenum)
1795 filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1795, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Bad ControlPersist argument."
, filename, linenum)
;
1796 goto out;
1797 }
1798 if (*activep && *intptr == -1) {
1799 *intptr = value;
1800 options->control_persist_timeout = value2;
1801 }
1802 break;
1803
1804 case oHashKnownHosts:
1805 intptr = &options->hash_known_hosts;
1806 goto parse_flag;
1807
1808 case oTunnel:
1809 intptr = &options->tun_open;
1810 multistate_ptr = multistate_tunnel;
1811 goto parse_multistate;
1812
1813 case oTunnelDevice:
1814 arg = argv_next(&ac, &av);
1815 if (!arg || *arg == '\0') {
1816 error("%.200s line %d: Missing argument.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1817, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing argument."
, filename, linenum)
1817 filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1817, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing argument."
, filename, linenum)
;
1818 goto out;
1819 }
1820 value = a2tun(arg, &value2);
1821 if (value == SSH_TUNID_ERR(0x7fffffff - 1)) {
1822 error("%.200s line %d: Bad tun device.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1823, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Bad tun device."
, filename, linenum)
1823 filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1823, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Bad tun device."
, filename, linenum)
;
1824 goto out;
1825 }
1826 if (*activep && options->tun_local == -1) {
1827 options->tun_local = value;
1828 options->tun_remote = value2;
1829 }
1830 break;
1831
1832 case oLocalCommand:
1833 charptr = &options->local_command;
1834 goto parse_command;
1835
1836 case oPermitLocalCommand:
1837 intptr = &options->permit_local_command;
1838 goto parse_flag;
1839
1840 case oRemoteCommand:
1841 charptr = &options->remote_command;
1842 goto parse_command;
1843
1844 case oVisualHostKey:
1845 intptr = &options->visual_host_key;
1846 goto parse_flag;
1847
1848 case oInclude:
1849 if (cmdline) {
1850 error("Include directive not supported as a "sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1851, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "Include directive not supported as a "
"command-line option")
1851 "command-line option")sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1851, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "Include directive not supported as a "
"command-line option")
;
1852 goto out;
1853 }
1854 value = 0;
1855 while ((arg = argv_next(&ac, &av)) != NULL((void *)0)) {
1856 if (*arg == '\0') {
1857 error("%s line %d: keyword %s empty argument",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1858, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: keyword %s empty argument"
, filename, linenum, keyword)
1858 filename, linenum, keyword)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1858, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: keyword %s empty argument"
, filename, linenum, keyword)
;
1859 goto out;
1860 }
1861 /*
1862 * Ensure all paths are anchored. User configuration
1863 * files may begin with '~/' but system configurations
1864 * must not. If the path is relative, then treat it
1865 * as living in ~/.ssh for user configurations or
1866 * /etc/ssh for system ones.
1867 */
1868 if (*arg == '~' && (flags & SSHCONF_USERCONF2) == 0) {
1869 error("%.200s line %d: bad include path %s.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1870, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: bad include path %s."
, filename, linenum, arg)
1870 filename, linenum, arg)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1870, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: bad include path %s."
, filename, linenum, arg)
;
1871 goto out;
1872 }
1873 if (!path_absolute(arg) && *arg != '~') {
1874 xasprintf(&arg2, "%s/%s",
1875 (flags & SSHCONF_USERCONF2) ?
1876 "~/" _PATH_SSH_USER_DIR".ssh" : SSHDIR"/etc" "/ssh", arg);
1877 } else
1878 arg2 = xstrdup(arg);
1879 memset(&gl, 0, sizeof(gl));
1880 r = glob(arg2, GLOB_TILDE0x0800, NULL((void *)0), &gl);
1881 if (r == GLOB_NOMATCH(-3)) {
1882 debug("%.200s line %d: include %s matched no "sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1883, 0, SYSLOG_LEVEL_DEBUG1, ((void *)0), "%.200s line %d: include %s matched no "
"files",filename, linenum, arg2)
1883 "files",filename, linenum, arg2)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1883, 0, SYSLOG_LEVEL_DEBUG1, ((void *)0), "%.200s line %d: include %s matched no "
"files",filename, linenum, arg2)
;
1884 free(arg2);
1885 continue;
1886 } else if (r != 0) {
1887 error("%.200s line %d: glob failed for %s.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1888, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: glob failed for %s."
, filename, linenum, arg2)
1888 filename, linenum, arg2)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1888, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: glob failed for %s."
, filename, linenum, arg2)
;
1889 goto out;
1890 }
1891 free(arg2);
1892 oactive = *activep;
1893 for (i = 0; i < gl.gl_pathc; i++) {
1894 debug3("%.200s line %d: Including file %s "sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1897, 0, SYSLOG_LEVEL_DEBUG3, ((void *)0), "%.200s line %d: Including file %s "
"depth %d%s", filename, linenum, gl.gl_pathv[i], depth, oactive
? "" : " (parse only)")
1895 "depth %d%s", filename, linenum,sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1897, 0, SYSLOG_LEVEL_DEBUG3, ((void *)0), "%.200s line %d: Including file %s "
"depth %d%s", filename, linenum, gl.gl_pathv[i], depth, oactive
? "" : " (parse only)")
1896 gl.gl_pathv[i], depth,sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1897, 0, SYSLOG_LEVEL_DEBUG3, ((void *)0), "%.200s line %d: Including file %s "
"depth %d%s", filename, linenum, gl.gl_pathv[i], depth, oactive
? "" : " (parse only)")
1897 oactive ? "" : " (parse only)")sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1897, 0, SYSLOG_LEVEL_DEBUG3, ((void *)0), "%.200s line %d: Including file %s "
"depth %d%s", filename, linenum, gl.gl_pathv[i], depth, oactive
? "" : " (parse only)")
;
1898 r = read_config_file_depth(gl.gl_pathv[i],
1899 pw, host, original_host, options,
1900 flags | SSHCONF_CHECKPERM1 |
1901 (oactive ? 0 : SSHCONF_NEVERMATCH8),
1902 activep, want_final_pass, depth + 1);
1903 if (r != 1 && errno(*__errno()) != ENOENT2) {
1904 error("Can't open user config file "sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1906, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "Can't open user config file "
"%.100s: %.100s", gl.gl_pathv[i], strerror((*__errno())))
1905 "%.100s: %.100s", gl.gl_pathv[i],sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1906, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "Can't open user config file "
"%.100s: %.100s", gl.gl_pathv[i], strerror((*__errno())))
1906 strerror(errno))sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1906, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "Can't open user config file "
"%.100s: %.100s", gl.gl_pathv[i], strerror((*__errno())))
;
1907 globfree(&gl);
1908 goto out;
1909 }
1910 /*
1911 * don't let Match in includes clobber the
1912 * containing file's Match state.
1913 */
1914 *activep = oactive;
1915 if (r != 1)
1916 value = -1;
1917 }
1918 globfree(&gl);
1919 }
1920 if (value != 0)
1921 ret = value;
1922 break;
1923
1924 case oIPQoS:
1925 arg = argv_next(&ac, &av);
1926 if ((value = parse_ipqos(arg)) == -1) {
1927 error("%s line %d: Bad IPQoS value: %s",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1928, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: Bad IPQoS value: %s"
, filename, linenum, arg)
1928 filename, linenum, arg)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1928, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: Bad IPQoS value: %s"
, filename, linenum, arg)
;
1929 goto out;
1930 }
1931 arg = argv_next(&ac, &av);
1932 if (arg == NULL((void *)0))
1933 value2 = value;
1934 else if ((value2 = parse_ipqos(arg)) == -1) {
1935 error("%s line %d: Bad IPQoS value: %s",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1936, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: Bad IPQoS value: %s"
, filename, linenum, arg)
1936 filename, linenum, arg)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1936, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: Bad IPQoS value: %s"
, filename, linenum, arg)
;
1937 goto out;
1938 }
1939 if (*activep && options->ip_qos_interactive == -1) {
1940 options->ip_qos_interactive = value;
1941 options->ip_qos_bulk = value2;
1942 }
1943 break;
1944
1945 case oRequestTTY:
1946 intptr = &options->request_tty;
1947 multistate_ptr = multistate_requesttty;
1948 goto parse_multistate;
1949
1950 case oSessionType:
1951 intptr = &options->session_type;
1952 multistate_ptr = multistate_sessiontype;
1953 goto parse_multistate;
1954
1955 case oStdinNull:
1956 intptr = &options->stdin_null;
1957 goto parse_flag;
1958
1959 case oForkAfterAuthentication:
1960 intptr = &options->fork_after_authentication;
1961 goto parse_flag;
1962
1963 case oIgnoreUnknown:
1964 charptr = &options->ignored_unknown;
1965 goto parse_string;
1966
1967 case oProxyUseFdpass:
1968 intptr = &options->proxy_use_fdpass;
1969 goto parse_flag;
1970
1971 case oCanonicalDomains:
1972 value = options->num_canonical_domains != 0;
1973 i = 0;
1974 while ((arg = argv_next(&ac, &av)) != NULL((void *)0)) {
1975 if (*arg == '\0') {
1976 error("%s line %d: keyword %s empty argument",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1977, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: keyword %s empty argument"
, filename, linenum, keyword)
1977 filename, linenum, keyword)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1977, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: keyword %s empty argument"
, filename, linenum, keyword)
;
1978 goto out;
1979 }
1980 /* Allow "none" only in first position */
1981 if (strcasecmp(arg, "none") == 0) {
1982 if (i > 0 || ac > 0) {
1983 error("%s line %d: keyword %s \"none\" "sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1985, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: keyword %s \"none\" "
"argument must appear alone.", filename, linenum, keyword)
1984 "argument must appear alone.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1985, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: keyword %s \"none\" "
"argument must appear alone.", filename, linenum, keyword)
1985 filename, linenum, keyword)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1985, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: keyword %s \"none\" "
"argument must appear alone.", filename, linenum, keyword)
;
1986 goto out;
1987 }
1988 }
1989 i++;
1990 if (!valid_domain(arg, 1, &errstr)) {
1991 error("%s line %d: %s", filename, linenum,sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1992, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: %s",
filename, linenum, errstr)
1992 errstr)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 1992, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: %s",
filename, linenum, errstr)
;
1993 goto out;
1994 }
1995 if (!*activep || value)
1996 continue;
1997 if (options->num_canonical_domains >=
1998 MAX_CANON_DOMAINS32) {
1999 error("%s line %d: too many hostname suffixes.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2000, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: too many hostname suffixes."
, filename, linenum)
2000 filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2000, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: too many hostname suffixes."
, filename, linenum)
;
2001 goto out;
2002 }
2003 options->canonical_domains[
2004 options->num_canonical_domains++] = xstrdup(arg);
2005 }
2006 break;
2007
2008 case oCanonicalizePermittedCNAMEs:
2009 value = options->num_permitted_cnames != 0;
2010 i = 0;
2011 while ((arg = argv_next(&ac, &av)) != NULL((void *)0)) {
2012 /*
2013 * Either 'none' (only in first position), '*' for
2014 * everything or 'list:list'
2015 */
2016 if (strcasecmp(arg, "none") == 0) {
2017 if (i > 0 || ac > 0) {
2018 error("%s line %d: keyword %s \"none\" "sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2020, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: keyword %s \"none\" "
"argument must appear alone.", filename, linenum, keyword)
2019 "argument must appear alone.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2020, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: keyword %s \"none\" "
"argument must appear alone.", filename, linenum, keyword)
2020 filename, linenum, keyword)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2020, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: keyword %s \"none\" "
"argument must appear alone.", filename, linenum, keyword)
;
2021 goto out;
2022 }
2023 arg2 = "";
2024 } else if (strcmp(arg, "*") == 0) {
2025 arg2 = arg;
2026 } else {
2027 lowercase(arg);
2028 if ((arg2 = strchr(arg, ':')) == NULL((void *)0) ||
2029 arg2[1] == '\0') {
2030 error("%s line %d: "sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2032, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: " "Invalid permitted CNAME \"%s\""
, filename, linenum, arg)
2031 "Invalid permitted CNAME \"%s\"",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2032, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: " "Invalid permitted CNAME \"%s\""
, filename, linenum, arg)
2032 filename, linenum, arg)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2032, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: " "Invalid permitted CNAME \"%s\""
, filename, linenum, arg)
;
2033 goto out;
2034 }
2035 *arg2 = '\0';
2036 arg2++;
2037 }
2038 i++;
2039 if (!*activep || value)
2040 continue;
2041 if (options->num_permitted_cnames >=
2042 MAX_CANON_DOMAINS32) {
2043 error("%s line %d: too many permitted CNAMEs.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2044, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: too many permitted CNAMEs."
, filename, linenum)
2044 filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2044, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: too many permitted CNAMEs."
, filename, linenum)
;
2045 goto out;
2046 }
2047 cname = options->permitted_cnames +
2048 options->num_permitted_cnames++;
2049 cname->source_list = xstrdup(arg);
2050 cname->target_list = xstrdup(arg2);
2051 }
2052 break;
2053
2054 case oCanonicalizeHostname:
2055 intptr = &options->canonicalize_hostname;
2056 multistate_ptr = multistate_canonicalizehostname;
2057 goto parse_multistate;
2058
2059 case oCanonicalizeMaxDots:
2060 intptr = &options->canonicalize_max_dots;
2061 goto parse_int;
2062
2063 case oCanonicalizeFallbackLocal:
2064 intptr = &options->canonicalize_fallback_local;
2065 goto parse_flag;
2066
2067 case oStreamLocalBindMask:
2068 arg = argv_next(&ac, &av);
2069 if (!arg || *arg == '\0') {
2070 error("%.200s line %d: Missing StreamLocalBindMask "sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2071, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing StreamLocalBindMask "
"argument.", filename, linenum)
2071 "argument.", filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2071, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing StreamLocalBindMask "
"argument.", filename, linenum)
;
2072 goto out;
2073 }
2074 /* Parse mode in octal format */
2075 value = strtol(arg, &endofnumber, 8);
2076 if (arg == endofnumber || value < 0 || value > 0777) {
2077 error("%.200s line %d: Bad mask.", filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2077, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Bad mask."
, filename, linenum)
;
2078 goto out;
2079 }
2080 options->fwd_opts.streamlocal_bind_mask = (mode_t)value;
2081 break;
2082
2083 case oStreamLocalBindUnlink:
2084 intptr = &options->fwd_opts.streamlocal_bind_unlink;
2085 goto parse_flag;
2086
2087 case oRevokedHostKeys:
2088 charptr = &options->revoked_host_keys;
2089 goto parse_string;
2090
2091 case oFingerprintHash:
2092 intptr = &options->fingerprint_hash;
2093 arg = argv_next(&ac, &av);
2094 if (!arg || *arg == '\0') {
2095 error("%.200s line %d: Missing argument.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2096, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing argument."
, filename, linenum)
2096 filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2096, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing argument."
, filename, linenum)
;
2097 goto out;
2098 }
2099 if ((value = ssh_digest_alg_by_name(arg)) == -1) {
2100 error("%.200s line %d: Invalid hash algorithm \"%s\".",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2101, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Invalid hash algorithm \"%s\"."
, filename, linenum, arg)
2101 filename, linenum, arg)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2101, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Invalid hash algorithm \"%s\"."
, filename, linenum, arg)
;
2102 goto out;
2103 }
2104 if (*activep && *intptr == -1)
2105 *intptr = value;
2106 break;
2107
2108 case oUpdateHostkeys:
2109 intptr = &options->update_hostkeys;
2110 multistate_ptr = multistate_yesnoask;
2111 goto parse_multistate;
2112
2113 case oHostbasedAcceptedAlgorithms:
2114 charptr = &options->hostbased_accepted_algos;
2115 goto parse_pubkey_algos;
2116
2117 case oPubkeyAcceptedAlgorithms:
2118 charptr = &options->pubkey_accepted_algos;
2119 goto parse_pubkey_algos;
2120
2121 case oAddKeysToAgent:
2122 arg = argv_next(&ac, &av);
2123 arg2 = argv_next(&ac, &av);
2124 value = parse_multistate_value(arg, filename, linenum,
2125 multistate_yesnoaskconfirm);
2126 value2 = 0; /* unlimited lifespan by default */
2127 if (value == 3 && arg2 != NULL((void *)0)) {
2128 /* allow "AddKeysToAgent confirm 5m" */
2129 if ((value2 = convtime(arg2)) == -1 ||
2130 value2 > INT_MAX2147483647) {
2131 error("%s line %d: invalid time value.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2132, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: invalid time value."
, filename, linenum)
2132 filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2132, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: invalid time value."
, filename, linenum)
;
2133 goto out;
2134 }
2135 } else if (value == -1 && arg2 == NULL((void *)0)) {
2136 if ((value2 = convtime(arg)) == -1 ||
2137 value2 > INT_MAX2147483647) {
2138 error("%s line %d: unsupported option",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2139, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: unsupported option"
, filename, linenum)
2139 filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2139, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: unsupported option"
, filename, linenum)
;
2140 goto out;
2141 }
2142 value = 1; /* yes */
2143 } else if (value == -1 || arg2 != NULL((void *)0)) {
2144 error("%s line %d: unsupported option",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2145, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: unsupported option"
, filename, linenum)
2145 filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2145, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: unsupported option"
, filename, linenum)
;
2146 goto out;
2147 }
2148 if (*activep && options->add_keys_to_agent == -1) {
2149 options->add_keys_to_agent = value;
2150 options->add_keys_to_agent_lifespan = value2;
2151 }
2152 break;
2153
2154 case oIdentityAgent:
2155 charptr = &options->identity_agent;
2156 arg = argv_next(&ac, &av);
2157 if (!arg || *arg == '\0') {
2158 error("%.200s line %d: Missing argument.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2159, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing argument."
, filename, linenum)
2159 filename, linenum)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2159, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Missing argument."
, filename, linenum)
;
2160 goto out;
2161 }
2162 parse_agent_path:
2163 /* Extra validation if the string represents an env var. */
2164 if ((arg2 = dollar_expand(&r, arg)) == NULL((void *)0) || r) {
2165 error("%.200s line %d: Invalid environment expansion "sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2166, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Invalid environment expansion "
"%s.", filename, linenum, arg)
2166 "%s.", filename, linenum, arg)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2166, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Invalid environment expansion "
"%s.", filename, linenum, arg)
;
2167 goto out;
2168 }
2169 free(arg2);
2170 /* check for legacy environment format */
2171 if (arg[0] == '$' && arg[1] != '{' &&
2172 !valid_env_name(arg + 1)) {
2173 error("%.200s line %d: Invalid environment name %s.",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2174, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Invalid environment name %s."
, filename, linenum, arg)
2174 filename, linenum, arg)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2174, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: Invalid environment name %s."
, filename, linenum, arg)
;
2175 goto out;
2176 }
2177 if (*activep && *charptr == NULL((void *)0))
2178 *charptr = xstrdup(arg);
2179 break;
2180
2181 case oDeprecated:
2182 debug("%s line %d: Deprecated option \"%s\"",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2183, 0, SYSLOG_LEVEL_DEBUG1, ((void *)0), "%s line %d: Deprecated option \"%s\""
, filename, linenum, keyword)
2183 filename, linenum, keyword)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2183, 0, SYSLOG_LEVEL_DEBUG1, ((void *)0), "%s line %d: Deprecated option \"%s\""
, filename, linenum, keyword)
;
2184 argv_consume(&ac);
2185 break;
2186
2187 case oUnsupported:
2188 error("%s line %d: Unsupported option \"%s\"",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2189, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: Unsupported option \"%s\""
, filename, linenum, keyword)
2189 filename, linenum, keyword)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2189, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: Unsupported option \"%s\""
, filename, linenum, keyword)
;
2190 argv_consume(&ac);
2191 break;
2192
2193 default:
2194 error("%s line %d: Unimplemented opcode %d",sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2195, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: Unimplemented opcode %d"
, filename, linenum, opcode)
2195 filename, linenum, opcode)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2195, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%s line %d: Unimplemented opcode %d"
, filename, linenum, opcode)
;
2196 goto out;
2197 }
2198
2199 /* Check that there is no garbage at end of line. */
2200 if (ac > 0) {
2201 error("%.200s line %d: keyword %s extra arguments "sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2202, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: keyword %s extra arguments "
"at end of line", filename, linenum, keyword)
2202 "at end of line", filename, linenum, keyword)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2202, 0, SYSLOG_LEVEL_ERROR, ((void *)0), "%.200s line %d: keyword %s extra arguments "
"at end of line", filename, linenum, keyword)
;
2203 goto out;
2204 }
2205
2206 /* success */
2207 ret = 0;
2208 out:
2209 argv_free(oav, oac);
2210 return ret;
2211}
2212
2213/*
2214 * Reads the config file and modifies the options accordingly. Options
2215 * should already be initialized before this call. This never returns if
2216 * there is an error. If the file does not exist, this returns 0.
2217 */
2218int
2219read_config_file(const char *filename, struct passwd *pw, const char *host,
2220 const char *original_host, Options *options, int flags,
2221 int *want_final_pass)
2222{
2223 int active = 1;
2224
2225 return read_config_file_depth(filename, pw, host, original_host,
2226 options, flags, &active, want_final_pass, 0);
2227}
2228
2229#define READCONF_MAX_DEPTH16 16
2230static int
2231read_config_file_depth(const char *filename, struct passwd *pw,
2232 const char *host, const char *original_host, Options *options,
2233 int flags, int *activep, int *want_final_pass, int depth)
2234{
2235 FILE *f;
2236 char *line = NULL((void *)0);
2237 size_t linesize = 0;
2238 int linenum;
2239 int bad_options = 0;
2240
2241 if (depth < 0 || depth > READCONF_MAX_DEPTH16)
2242 fatal("Too many recursive configuration includes")sshfatal("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2242, 0, SYSLOG_LEVEL_FATAL, ((void *)0), "Too many recursive configuration includes"
)
;
2243
2244 if ((f = fopen(filename, "r")) == NULL((void *)0))
2245 return 0;
2246
2247 if (flags & SSHCONF_CHECKPERM1) {
2248 struct stat sb;
2249
2250 if (fstat(fileno(f)(!__isthreaded ? ((f)->_file) : (fileno)(f)), &sb) == -1)
2251 fatal("fstat %s: %s", filename, strerror(errno))sshfatal("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2251, 0, SYSLOG_LEVEL_FATAL, ((void *)0), "fstat %s: %s", filename
, strerror((*__errno())))
;
2252 if (((sb.st_uid != 0 && sb.st_uid != getuid()) ||
2253 (sb.st_mode & 022) != 0))
2254 fatal("Bad owner or permissions on %s", filename)sshfatal("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2254, 0, SYSLOG_LEVEL_FATAL, ((void *)0), "Bad owner or permissions on %s"
, filename)
;
2255 }
2256
2257 debug("Reading configuration data %.200s", filename)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2257, 0, SYSLOG_LEVEL_DEBUG1, ((void *)0), "Reading configuration data %.200s"
, filename)
;
2258
2259 /*
2260 * Mark that we are now processing the options. This flag is turned
2261 * on/off by Host specifications.
2262 */
2263 linenum = 0;
2264 while (getline(&line, &linesize, f) != -1) {
2265 /* Update line number counter. */
2266 linenum++;
2267 /*
2268 * Trim out comments and strip whitespace.
2269 * NB - preserve newlines, they are needed to reproduce
2270 * line numbers later for error messages.
2271 */
2272 if (process_config_line_depth(options, pw, host, original_host,
2273 line, filename, linenum, activep, flags, want_final_pass,
2274 depth) != 0)
2275 bad_options++;
2276 }
2277 free(line);
2278 fclose(f);
2279 if (bad_options > 0)
2280 fatal("%s: terminating, %d bad configuration options",sshfatal("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2281, 0, SYSLOG_LEVEL_FATAL, ((void *)0), "%s: terminating, %d bad configuration options"
, filename, bad_options)
2281 filename, bad_options)sshfatal("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2281, 0, SYSLOG_LEVEL_FATAL, ((void *)0), "%s: terminating, %d bad configuration options"
, filename, bad_options)
;
2282 return 1;
2283}
2284
2285/* Returns 1 if a string option is unset or set to "none" or 0 otherwise. */
2286int
2287option_clear_or_none(const char *o)
2288{
2289 return o == NULL((void *)0) || strcasecmp(o, "none") == 0;
2290}
2291
2292/*
2293 * Returns 1 if CanonicalizePermittedCNAMEs have been specified, 0 otherwise.
2294 * Allowed to be called on non-final configuration.
2295 */
2296int
2297config_has_permitted_cnames(Options *options)
2298{
2299 if (options->num_permitted_cnames == 1 &&
2300 strcasecmp(options->permitted_cnames[0].source_list, "none") == 0 &&
2301 strcmp(options->permitted_cnames[0].target_list, "") == 0)
2302 return 0;
2303 return options->num_permitted_cnames > 0;
2304}
2305
2306/*
2307 * Initializes options to special values that indicate that they have not yet
2308 * been set. Read_config_file will only set options with this value. Options
2309 * are processed in the following order: command line, user config file,
2310 * system config file. Last, fill_default_options is called.
2311 */
2312
2313void
2314initialize_options(Options * options)
2315{
2316 memset(options, 'X', sizeof(*options));
2317 options->forward_agent = -1;
2318 options->forward_agent_sock_path = NULL((void *)0);
2319 options->forward_x11 = -1;
2320 options->forward_x11_trusted = -1;
2321 options->forward_x11_timeout = -1;
2322 options->stdio_forward_host = NULL((void *)0);
2323 options->stdio_forward_port = 0;
2324 options->clear_forwardings = -1;
2325 options->exit_on_forward_failure = -1;
2326 options->xauth_location = NULL((void *)0);
2327 options->fwd_opts.gateway_ports = -1;
2328 options->fwd_opts.streamlocal_bind_mask = (mode_t)-1;
2329 options->fwd_opts.streamlocal_bind_unlink = -1;
2330 options->pubkey_authentication = -1;
2331 options->gss_authentication = -1;
2332 options->gss_deleg_creds = -1;
2333 options->password_authentication = -1;
2334 options->kbd_interactive_authentication = -1;
2335 options->kbd_interactive_devices = NULL((void *)0);
2336 options->hostbased_authentication = -1;
2337 options->batch_mode = -1;
2338 options->check_host_ip = -1;
2339 options->strict_host_key_checking = -1;
2340 options->compression = -1;
2341 options->tcp_keep_alive = -1;
2342 options->port = -1;
2343 options->address_family = -1;
2344 options->connection_attempts = -1;
2345 options->connection_timeout = -1;
2346 options->number_of_password_prompts = -1;
2347 options->ciphers = NULL((void *)0);
2348 options->macs = NULL((void *)0);
2349 options->kex_algorithms = NULL((void *)0);
2350 options->hostkeyalgorithms = NULL((void *)0);
2351 options->ca_sign_algorithms = NULL((void *)0);
2352 options->num_identity_files = 0;
2353 memset(options->identity_keys, 0, sizeof(options->identity_keys));
2354 options->num_certificate_files = 0;
2355 memset(options->certificates, 0, sizeof(options->certificates));
2356 options->hostname = NULL((void *)0);
2357 options->host_key_alias = NULL((void *)0);
2358 options->proxy_command = NULL((void *)0);
2359 options->jump_user = NULL((void *)0);
2360 options->jump_host = NULL((void *)0);
2361 options->jump_port = -1;
2362 options->jump_extra = NULL((void *)0);
2363 options->user = NULL((void *)0);
2364 options->escape_char = -1;
2365 options->num_system_hostfiles = 0;
2366 options->num_user_hostfiles = 0;
2367 options->local_forwards = NULL((void *)0);
2368 options->num_local_forwards = 0;
2369 options->remote_forwards = NULL((void *)0);
2370 options->num_remote_forwards = 0;
2371 options->permitted_remote_opens = NULL((void *)0);
2372 options->num_permitted_remote_opens = 0;
2373 options->log_facility = SYSLOG_FACILITY_NOT_SET;
2374 options->log_level = SYSLOG_LEVEL_NOT_SET;
2375 options->num_log_verbose = 0;
2376 options->log_verbose = NULL((void *)0);
2377 options->preferred_authentications = NULL((void *)0);
2378 options->bind_address = NULL((void *)0);
2379 options->bind_interface = NULL((void *)0);
2380 options->pkcs11_provider = NULL((void *)0);
2381 options->sk_provider = NULL((void *)0);
2382 options->enable_ssh_keysign = - 1;
2383 options->no_host_authentication_for_localhost = - 1;
2384 options->identities_only = - 1;
2385 options->rekey_limit = - 1;
2386 options->rekey_interval = -1;
2387 options->verify_host_key_dns = -1;
2388 options->server_alive_interval = -1;
2389 options->server_alive_count_max = -1;
2390 options->send_env = NULL((void *)0);
2391 options->num_send_env = 0;
2392 options->setenv = NULL((void *)0);
2393 options->num_setenv = 0;
2394 options->control_path = NULL((void *)0);
2395 options->control_master = -1;
2396 options->control_persist = -1;
2397 options->control_persist_timeout = 0;
2398 options->hash_known_hosts = -1;
2399 options->tun_open = -1;
2400 options->tun_local = -1;
2401 options->tun_remote = -1;
2402 options->local_command = NULL((void *)0);
2403 options->permit_local_command = -1;
2404 options->remote_command = NULL((void *)0);
2405 options->add_keys_to_agent = -1;
2406 options->add_keys_to_agent_lifespan = -1;
2407 options->identity_agent = NULL((void *)0);
2408 options->visual_host_key = -1;
2409 options->ip_qos_interactive = -1;
2410 options->ip_qos_bulk = -1;
2411 options->request_tty = -1;
2412 options->session_type = -1;
2413 options->stdin_null = -1;
2414 options->fork_after_authentication = -1;
2415 options->proxy_use_fdpass = -1;
2416 options->ignored_unknown = NULL((void *)0);
2417 options->num_canonical_domains = 0;
2418 options->num_permitted_cnames = 0;
2419 options->canonicalize_max_dots = -1;
2420 options->canonicalize_fallback_local = -1;
2421 options->canonicalize_hostname = -1;
2422 options->revoked_host_keys = NULL((void *)0);
2423 options->fingerprint_hash = -1;
2424 options->update_hostkeys = -1;
2425 options->hostbased_accepted_algos = NULL((void *)0);
2426 options->pubkey_accepted_algos = NULL((void *)0);
2427 options->known_hosts_command = NULL((void *)0);
2428}
2429
2430/*
2431 * A petite version of fill_default_options() that just fills the options
2432 * needed for hostname canonicalization to proceed.
2433 */
2434void
2435fill_default_options_for_canonicalization(Options *options)
2436{
2437 if (options->canonicalize_max_dots == -1)
2438 options->canonicalize_max_dots = 1;
2439 if (options->canonicalize_fallback_local == -1)
2440 options->canonicalize_fallback_local = 1;
2441 if (options->canonicalize_hostname == -1)
2442 options->canonicalize_hostname = SSH_CANONICALISE_NO0;
2443}
2444
2445/*
2446 * Called after processing other sources of option data, this fills those
2447 * options for which no value has been specified with their default values.
2448 */
2449int
2450fill_default_options(Options * options)
2451{
2452 char *all_cipher, *all_mac, *all_kex, *all_key, *all_sig;
2453 char *def_cipher, *def_mac, *def_kex, *def_key, *def_sig;
2454 int ret = 0, r;
2455
2456 if (options->forward_agent == -1)
2457 options->forward_agent = 0;
2458 if (options->forward_x11 == -1)
2459 options->forward_x11 = 0;
2460 if (options->forward_x11_trusted == -1)
2461 options->forward_x11_trusted = 0;
2462 if (options->forward_x11_timeout == -1)
2463 options->forward_x11_timeout = 1200;
2464 /*
2465 * stdio forwarding (-W) changes the default for these but we defer
2466 * setting the values so they can be overridden.
2467 */
2468 if (options->exit_on_forward_failure == -1)
2469 options->exit_on_forward_failure =
2470 options->stdio_forward_host != NULL((void *)0) ? 1 : 0;
2471 if (options->clear_forwardings == -1)
2472 options->clear_forwardings =
2473 options->stdio_forward_host != NULL((void *)0) ? 1 : 0;
2474 if (options->clear_forwardings == 1)
2475 clear_forwardings(options);
2476
2477 if (options->xauth_location == NULL((void *)0))
2478 options->xauth_location = xstrdup(_PATH_XAUTH"/usr/X11R6/bin/xauth");
2479 if (options->fwd_opts.gateway_ports == -1)
2480 options->fwd_opts.gateway_ports = 0;
2481 if (options->fwd_opts.streamlocal_bind_mask == (mode_t)-1)
2482 options->fwd_opts.streamlocal_bind_mask = 0177;
2483 if (options->fwd_opts.streamlocal_bind_unlink == -1)
2484 options->fwd_opts.streamlocal_bind_unlink = 0;
2485 if (options->pubkey_authentication == -1)
2486 options->pubkey_authentication = SSH_PUBKEY_AUTH_ALL0x03;
2487 if (options->gss_authentication == -1)
2488 options->gss_authentication = 0;
2489 if (options->gss_deleg_creds == -1)
2490 options->gss_deleg_creds = 0;
2491 if (options->password_authentication == -1)
2492 options->password_authentication = 1;
2493 if (options->kbd_interactive_authentication == -1)
2494 options->kbd_interactive_authentication = 1;
2495 if (options->hostbased_authentication == -1)
2496 options->hostbased_authentication = 0;
2497 if (options->batch_mode == -1)
2498 options->batch_mode = 0;
2499 if (options->check_host_ip == -1)
2500 options->check_host_ip = 0;
2501 if (options->strict_host_key_checking == -1)
2502 options->strict_host_key_checking = SSH_STRICT_HOSTKEY_ASK3;
2503 if (options->compression == -1)
2504 options->compression = 0;
2505 if (options->tcp_keep_alive == -1)
2506 options->tcp_keep_alive = 1;
2507 if (options->port == -1)
2508 options->port = 0; /* Filled in ssh_connect. */
2509 if (options->address_family == -1)
2510 options->address_family = AF_UNSPEC0;
2511 if (options->connection_attempts == -1)
2512 options->connection_attempts = 1;
2513 if (options->number_of_password_prompts == -1)
2514 options->number_of_password_prompts = 3;
2515 /* options->hostkeyalgorithms, default set in myproposals.h */
2516 if (options->add_keys_to_agent == -1) {
2517 options->add_keys_to_agent = 0;
2518 options->add_keys_to_agent_lifespan = 0;
2519 }
2520 if (options->num_identity_files == 0) {
2521 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_RSA".ssh" "/id_rsa", 0);
2522 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_DSA".ssh" "/id_dsa", 0);
2523 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_ECDSA".ssh" "/id_ecdsa", 0);
2524 add_identity_file(options, "~/",
2525 _PATH_SSH_CLIENT_ID_ECDSA_SK".ssh" "/id_ecdsa_sk", 0);
2526 add_identity_file(options, "~/",
2527 _PATH_SSH_CLIENT_ID_ED25519".ssh" "/id_ed25519", 0);
2528 add_identity_file(options, "~/",
2529 _PATH_SSH_CLIENT_ID_ED25519_SK".ssh" "/id_ed25519_sk", 0);
2530 add_identity_file(options, "~/", _PATH_SSH_CLIENT_ID_XMSS".ssh" "/id_xmss", 0);
2531 }
2532 if (options->escape_char == -1)
2533 options->escape_char = '~';
2534 if (options->num_system_hostfiles == 0) {
2535 options->system_hostfiles[options->num_system_hostfiles++] =
2536 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE"/etc" "/ssh" "/ssh_known_hosts");
2537 options->system_hostfiles[options->num_system_hostfiles++] =
2538 xstrdup(_PATH_SSH_SYSTEM_HOSTFILE2"/etc" "/ssh" "/ssh_known_hosts2");
2539 }
2540 if (options->update_hostkeys == -1) {
2541 if (options->verify_host_key_dns <= 0 &&
2542 (options->num_user_hostfiles == 0 ||
2543 (options->num_user_hostfiles == 1 && strcmp(options->
2544 user_hostfiles[0], _PATH_SSH_USER_HOSTFILE"~/" ".ssh" "/known_hosts") == 0)))
2545 options->update_hostkeys = SSH_UPDATE_HOSTKEYS_YES1;
2546 else
2547 options->update_hostkeys = SSH_UPDATE_HOSTKEYS_NO0;
2548 }
2549 if (options->num_user_hostfiles == 0) {
2550 options->user_hostfiles[options->num_user_hostfiles++] =
2551 xstrdup(_PATH_SSH_USER_HOSTFILE"~/" ".ssh" "/known_hosts");
2552 options->user_hostfiles[options->num_user_hostfiles++] =
2553 xstrdup(_PATH_SSH_USER_HOSTFILE2"~/" ".ssh" "/known_hosts2");
2554 }
2555 if (options->log_level == SYSLOG_LEVEL_NOT_SET)
2556 options->log_level = SYSLOG_LEVEL_INFO;
2557 if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
2558 options->log_facility = SYSLOG_FACILITY_USER;
2559 if (options->no_host_authentication_for_localhost == - 1)
2560 options->no_host_authentication_for_localhost = 0;
2561 if (options->identities_only == -1)
2562 options->identities_only = 0;
2563 if (options->enable_ssh_keysign == -1)
2564 options->enable_ssh_keysign = 0;
2565 if (options->rekey_limit == -1)
2566 options->rekey_limit = 0;
2567 if (options->rekey_interval == -1)
2568 options->rekey_interval = 0;
2569 if (options->verify_host_key_dns == -1)
2570 options->verify_host_key_dns = 0;
2571 if (options->server_alive_interval == -1)
2572 options->server_alive_interval = 0;
2573 if (options->server_alive_count_max == -1)
2574 options->server_alive_count_max = 3;
2575 if (options->control_master == -1)
2576 options->control_master = 0;
2577 if (options->control_persist == -1) {
2578 options->control_persist = 0;
2579 options->control_persist_timeout = 0;
2580 }
2581 if (options->hash_known_hosts == -1)
2582 options->hash_known_hosts = 0;
2583 if (options->tun_open == -1)
2584 options->tun_open = SSH_TUNMODE_NO0x00;
2585 if (options->tun_local == -1)
2586 options->tun_local = SSH_TUNID_ANY0x7fffffff;
2587 if (options->tun_remote == -1)
2588 options->tun_remote = SSH_TUNID_ANY0x7fffffff;
2589 if (options->permit_local_command == -1)
2590 options->permit_local_command = 0;
2591 if (options->visual_host_key == -1)
2592 options->visual_host_key = 0;
2593 if (options->ip_qos_interactive == -1)
2594 options->ip_qos_interactive = IPTOS_DSCP_AF210x48;
2595 if (options->ip_qos_bulk == -1)
2596 options->ip_qos_bulk = IPTOS_DSCP_CS10x20;
2597 if (options->request_tty == -1)
2598 options->request_tty = REQUEST_TTY_AUTO0;
2599 if (options->session_type == -1)
2600 options->session_type = SESSION_TYPE_DEFAULT2;
2601 if (options->stdin_null == -1)
2602 options->stdin_null = 0;
2603 if (options->fork_after_authentication == -1)
2604 options->fork_after_authentication = 0;
2605 if (options->proxy_use_fdpass == -1)
2606 options->proxy_use_fdpass = 0;
2607 if (options->canonicalize_max_dots == -1)
2608 options->canonicalize_max_dots = 1;
2609 if (options->canonicalize_fallback_local == -1)
2610 options->canonicalize_fallback_local = 1;
2611 if (options->canonicalize_hostname == -1)
2612 options->canonicalize_hostname = SSH_CANONICALISE_NO0;
2613 if (options->fingerprint_hash == -1)
2614 options->fingerprint_hash = SSH_FP_HASH_DEFAULT2;
2615 if (options->sk_provider == NULL((void *)0))
2616 options->sk_provider = xstrdup("internal");
2617
2618 /* Expand KEX name lists */
2619 all_cipher = cipher_alg_list(',', 0);
2620 all_mac = mac_alg_list(',');
2621 all_kex = kex_alg_list(',');
2622 all_key = sshkey_alg_list(0, 0, 1, ',');
2623 all_sig = sshkey_alg_list(0, 1, 1, ',');
2624 /* remove unsupported algos from default lists */
2625 def_cipher = match_filter_allowlist(KEX_CLIENT_ENCRYPT"chacha20-poly1305@openssh.com," "aes128-ctr,aes192-ctr,aes256-ctr,"
"aes128-gcm@openssh.com,aes256-gcm@openssh.com"
, all_cipher);
2626 def_mac = match_filter_allowlist(KEX_CLIENT_MAC"umac-64-etm@openssh.com," "umac-128-etm@openssh.com," "hmac-sha2-256-etm@openssh.com,"
"hmac-sha2-512-etm@openssh.com," "hmac-sha1-etm@openssh.com,"
"umac-64@openssh.com," "umac-128@openssh.com," "hmac-sha2-256,"
"hmac-sha2-512," "hmac-sha1"
, all_mac);
2627 def_kex = match_filter_allowlist(KEX_CLIENT_KEX"curve25519-sha256," "curve25519-sha256@libssh.org," "ecdh-sha2-nistp256,"
"ecdh-sha2-nistp384," "ecdh-sha2-nistp521," "sntrup761x25519-sha512@openssh.com,"
"diffie-hellman-group-exchange-sha256," "diffie-hellman-group16-sha512,"
"diffie-hellman-group18-sha512," "diffie-hellman-group14-sha256"
, all_kex);
2628 def_key = match_filter_allowlist(KEX_DEFAULT_PK_ALG"ssh-ed25519-cert-v01@openssh.com," "ecdsa-sha2-nistp256-cert-v01@openssh.com,"
"ecdsa-sha2-nistp384-cert-v01@openssh.com," "ecdsa-sha2-nistp521-cert-v01@openssh.com,"
"sk-ssh-ed25519-cert-v01@openssh.com," "sk-ecdsa-sha2-nistp256-cert-v01@openssh.com,"
"rsa-sha2-512-cert-v01@openssh.com," "rsa-sha2-256-cert-v01@openssh.com,"
"ssh-ed25519," "ecdsa-sha2-nistp256," "ecdsa-sha2-nistp384,"
"ecdsa-sha2-nistp521," "sk-ssh-ed25519@openssh.com," "sk-ecdsa-sha2-nistp256@openssh.com,"
"rsa-sha2-512," "rsa-sha2-256"
, all_key);
2629 def_sig = match_filter_allowlist(SSH_ALLOWED_CA_SIGALGS"ssh-ed25519," "ecdsa-sha2-nistp256," "ecdsa-sha2-nistp384," "ecdsa-sha2-nistp521,"
"sk-ssh-ed25519@openssh.com," "sk-ecdsa-sha2-nistp256@openssh.com,"
"rsa-sha2-512," "rsa-sha2-256"
, all_sig);
2630#define ASSEMBLE(what, defaults, all) \
2631 do { \
2632 if ((r = kex_assemble_names(&options->what, \
2633 defaults, all)) != 0) { \
2634 error_fr(r, "%s", #what)sshlog("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 2634, 1, SYSLOG_LEVEL_ERROR, ssh_err(r), "%s", #what)
; \
2635 goto fail; \
2636 } \
2637 } while (0)
2638 ASSEMBLE(ciphers, def_cipher, all_cipher);
2639 ASSEMBLE(macs, def_mac, all_mac);
2640 ASSEMBLE(kex_algorithms, def_kex, all_kex);
2641 ASSEMBLE(hostbased_accepted_algos, def_key, all_key);
2642 ASSEMBLE(pubkey_accepted_algos, def_key, all_key);
2643 ASSEMBLE(ca_sign_algorithms, def_sig, all_sig);
2644#undef ASSEMBLE
2645
2646#define CLEAR_ON_NONE(v)do { if (option_clear_or_none(v)) { free(v); v = ((void *)0);
} } while(0)
\
2647 do { \
2648 if (option_clear_or_none(v)) { \
2649 free(v); \
2650 v = NULL((void *)0); \
2651 } \
2652 } while(0)
2653 CLEAR_ON_NONE(options->local_command)do { if (option_clear_or_none(options->local_command)) { free
(options->local_command); options->local_command = ((void
*)0); } } while(0)
;
2654 CLEAR_ON_NONE(options->remote_command)do { if (option_clear_or_none(options->remote_command)) { free
(options->remote_command); options->remote_command = ((
void *)0); } } while(0)
;
2655 CLEAR_ON_NONE(options->proxy_command)do { if (option_clear_or_none(options->proxy_command)) { free
(options->proxy_command); options->proxy_command = ((void
*)0); } } while(0)
;
2656 CLEAR_ON_NONE(options->control_path)do { if (option_clear_or_none(options->control_path)) { free
(options->control_path); options->control_path = ((void
*)0); } } while(0)
;
2657 CLEAR_ON_NONE(options->revoked_host_keys)do { if (option_clear_or_none(options->revoked_host_keys))
{ free(options->revoked_host_keys); options->revoked_host_keys
= ((void *)0); } } while(0)
;
2658 CLEAR_ON_NONE(options->pkcs11_provider)do { if (option_clear_or_none(options->pkcs11_provider)) {
free(options->pkcs11_provider); options->pkcs11_provider
= ((void *)0); } } while(0)
;
2659 CLEAR_ON_NONE(options->sk_provider)do { if (option_clear_or_none(options->sk_provider)) { free
(options->sk_provider); options->sk_provider = ((void *
)0); } } while(0)
;
2660 CLEAR_ON_NONE(options->known_hosts_command)do { if (option_clear_or_none(options->known_hosts_command
)) { free(options->known_hosts_command); options->known_hosts_command
= ((void *)0); } } while(0)
;
2661 if (options->jump_host != NULL((void *)0) &&
2662 strcmp(options->jump_host, "none") == 0 &&
2663 options->jump_port == 0 && options->jump_user == NULL((void *)0)) {
2664 free(options->jump_host);
2665 options->jump_host = NULL((void *)0);
2666 }
2667 if (options->num_permitted_cnames == 1 &&
2668 !config_has_permitted_cnames(options)) {
2669 /* clean up CanonicalizePermittedCNAMEs=none */
2670 free(options->permitted_cnames[0].source_list);
2671 free(options->permitted_cnames[0].target_list);
2672 memset(options->permitted_cnames, '\0',
2673 sizeof(*options->permitted_cnames));
2674 options->num_permitted_cnames = 0;
2675 }
2676 /* options->identity_agent distinguishes NULL from 'none' */
2677 /* options->user will be set in the main program if appropriate */
2678 /* options->hostname will be set in the main program if appropriate */
2679 /* options->host_key_alias should not be set by default */
2680 /* options->preferred_authentications will be set in ssh */
2681
2682 /* success */
2683 ret = 0;
2684 fail:
2685 free(all_cipher);
2686 free(all_mac);
2687 free(all_kex);
2688 free(all_key);
2689 free(all_sig);
2690 free(def_cipher);
2691 free(def_mac);
2692 free(def_kex);
2693 free(def_key);
2694 free(def_sig);
2695 return ret;
2696}
2697
2698void
2699free_options(Options *o)
2700{
2701 int i;
2702
2703 if (o == NULL((void *)0))
2704 return;
2705
2706#define FREE_ARRAY(type, n, a) \
2707 do { \
2708 type _i; \
2709 for (_i = 0; _i < (n); _i++) \
2710 free((a)[_i]); \
2711 } while (0)
2712
2713 free(o->forward_agent_sock_path);
2714 free(o->xauth_location);
2715 FREE_ARRAY(u_int, o->num_log_verbose, o->log_verbose);
2716 free(o->log_verbose);
2717 free(o->ciphers);
2718 free(o->macs);
2719 free(o->hostkeyalgorithms);
2720 free(o->kex_algorithms);
2721 free(o->ca_sign_algorithms);
2722 free(o->hostname);
2723 free(o->host_key_alias);
2724 free(o->proxy_command);
2725 free(o->user);
2726 FREE_ARRAY(u_int, o->num_system_hostfiles, o->system_hostfiles);
2727 FREE_ARRAY(u_int, o->num_user_hostfiles, o->user_hostfiles);
2728 free(o->preferred_authentications);
2729 free(o->bind_address);
2730 free(o->bind_interface);
2731 free(o->pkcs11_provider);
2732 free(o->sk_provider);
2733 for (i = 0; i < o->num_identity_files; i++) {
2734 free(o->identity_files[i]);
2735 sshkey_free(o->identity_keys[i]);
2736 }
2737 for (i = 0; i < o->num_certificate_files; i++) {
2738 free(o->certificate_files[i]);
2739 sshkey_free(o->certificates[i]);
2740 }
2741 free(o->identity_agent);
2742 for (i = 0; i < o->num_local_forwards; i++) {
2743 free(o->local_forwards[i].listen_host);
2744 free(o->local_forwards[i].listen_path);
2745 free(o->local_forwards[i].connect_host);
2746 free(o->local_forwards[i].connect_path);
2747 }
2748 free(o->local_forwards);
2749 for (i = 0; i < o->num_remote_forwards; i++) {
2750 free(o->remote_forwards[i].listen_host);
2751 free(o->remote_forwards[i].listen_path);
2752 free(o->remote_forwards[i].connect_host);
2753 free(o->remote_forwards[i].connect_path);
2754 }
2755 free(o->remote_forwards);
2756 free(o->stdio_forward_host);
2757 FREE_ARRAY(int, o->num_send_env, o->send_env);
2758 free(o->send_env);
2759 FREE_ARRAY(int, o->num_setenv, o->setenv);
2760 free(o->setenv);
2761 free(o->control_path);
2762 free(o->local_command);
2763 free(o->remote_command);
2764 FREE_ARRAY(int, o->num_canonical_domains, o->canonical_domains);
2765 for (i = 0; i < o->num_permitted_cnames; i++) {
2766 free(o->permitted_cnames[i].source_list);
2767 free(o->permitted_cnames[i].target_list);
2768 }
2769 free(o->revoked_host_keys);
2770 free(o->hostbased_accepted_algos);
2771 free(o->pubkey_accepted_algos);
2772 free(o->jump_user);
2773 free(o->jump_host);
2774 free(o->jump_extra);
2775 free(o->ignored_unknown);
2776 explicit_bzero(o, sizeof(*o));
2777#undef FREE_ARRAY
2778}
2779
2780struct fwdarg {
2781 char *arg;
2782 int ispath;
2783};
2784
2785/*
2786 * parse_fwd_field
2787 * parses the next field in a port forwarding specification.
2788 * sets fwd to the parsed field and advances p past the colon
2789 * or sets it to NULL at end of string.
2790 * returns 0 on success, else non-zero.
2791 */
2792static int
2793parse_fwd_field(char **p, struct fwdarg *fwd)
2794{
2795 char *ep, *cp = *p;
2796 int ispath = 0;
2797
2798 if (*cp == '\0') {
2799 *p = NULL((void *)0);
2800 return -1; /* end of string */
2801 }
2802
2803 /*
2804 * A field escaped with square brackets is used literally.
2805 * XXX - allow ']' to be escaped via backslash?
2806 */
2807 if (*cp == '[') {
2808 /* find matching ']' */
2809 for (ep = cp + 1; *ep != ']' && *ep != '\0'; ep++) {
2810 if (*ep == '/')
2811 ispath = 1;
2812 }
2813 /* no matching ']' or not at end of field. */
2814 if (ep[0] != ']' || (ep[1] != ':' && ep[1] != '\0'))
2815 return -1;
2816 /* NUL terminate the field and advance p past the colon */
2817 *ep++ = '\0';
2818 if (*ep != '\0')
2819 *ep++ = '\0';
2820 fwd->arg = cp + 1;
2821 fwd->ispath = ispath;
2822 *p = ep;
2823 return 0;
2824 }
2825
2826 for (cp = *p; *cp != '\0'; cp++) {
2827 switch (*cp) {
2828 case '\\':
2829 memmove(cp, cp + 1, strlen(cp + 1) + 1);
2830 if (*cp == '\0')
2831 return -1;
2832 break;
2833 case '/':
2834 ispath = 1;
2835 break;
2836 case ':':
2837 *cp++ = '\0';
2838 goto done;
2839 }
2840 }
2841done:
2842 fwd->arg = *p;
2843 fwd->ispath = ispath;
2844 *p = cp;
2845 return 0;
2846}
2847
2848/*
2849 * parse_forward
2850 * parses a string containing a port forwarding specification of the form:
2851 * dynamicfwd == 0
2852 * [listenhost:]listenport|listenpath:connecthost:connectport|connectpath
2853 * listenpath:connectpath
2854 * dynamicfwd == 1
2855 * [listenhost:]listenport
2856 * returns number of arguments parsed or zero on error
2857 */
2858int
2859parse_forward(struct Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd)
2860{
2861 struct fwdarg fwdargs[4];
2862 char *p, *cp;
2863 int i, err;
2864
2865 memset(fwd, 0, sizeof(*fwd));
2866 memset(fwdargs, 0, sizeof(fwdargs));
2867
2868 /*
2869 * We expand environment variables before checking if we think they're
2870 * paths so that if ${VAR} expands to a fully qualified path it is
2871 * treated as a path.
2872 */
2873 cp = p = dollar_expand(&err, fwdspec);
2874 if (p == NULL((void *)0) || err)
2875 return 0;
2876
2877 /* skip leading spaces */
2878 while (isspace((u_char)*cp))
2879 cp++;
2880
2881 for (i = 0; i < 4; ++i) {
2882 if (parse_fwd_field(&cp, &fwdargs[i]) != 0)
2883 break;
2884 }
2885
2886 /* Check for trailing garbage */
2887 if (cp != NULL((void *)0) && *cp != '\0') {
2888 i = 0; /* failure */
2889 }
2890
2891 switch (i) {
2892 case 1:
2893 if (fwdargs[0].ispath) {
2894 fwd->listen_path = xstrdup(fwdargs[0].arg);
2895 fwd->listen_port = PORT_STREAMLOCAL-2;
2896 } else {
2897 fwd->listen_host = NULL((void *)0);
2898 fwd->listen_port = a2port(fwdargs[0].arg);
2899 }
2900 fwd->connect_host = xstrdup("socks");
2901 break;
2902
2903 case 2:
2904 if (fwdargs[0].ispath && fwdargs[1].ispath) {
2905 fwd->listen_path = xstrdup(fwdargs[0].arg);
2906 fwd->listen_port = PORT_STREAMLOCAL-2;
2907 fwd->connect_path = xstrdup(fwdargs[1].arg);
2908 fwd->connect_port = PORT_STREAMLOCAL-2;
2909 } else if (fwdargs[1].ispath) {
2910 fwd->listen_host = NULL((void *)0);
2911 fwd->listen_port = a2port(fwdargs[0].arg);
2912 fwd->connect_path = xstrdup(fwdargs[1].arg);
2913 fwd->connect_port = PORT_STREAMLOCAL-2;
2914 } else {
2915 fwd->listen_host = xstrdup(fwdargs[0].arg);
2916 fwd->listen_port = a2port(fwdargs[1].arg);
2917 fwd->connect_host = xstrdup("socks");
2918 }
2919 break;
2920
2921 case 3:
2922 if (fwdargs[0].ispath) {
2923 fwd->listen_path = xstrdup(fwdargs[0].arg);
2924 fwd->listen_port = PORT_STREAMLOCAL-2;
2925 fwd->connect_host = xstrdup(fwdargs[1].arg);
2926 fwd->connect_port = a2port(fwdargs[2].arg);
2927 } else if (fwdargs[2].ispath) {
2928 fwd->listen_host = xstrdup(fwdargs[0].arg);
2929 fwd->listen_port = a2port(fwdargs[1].arg);
2930 fwd->connect_path = xstrdup(fwdargs[2].arg);
2931 fwd->connect_port = PORT_STREAMLOCAL-2;
2932 } else {
2933 fwd->listen_host = NULL((void *)0);
2934 fwd->listen_port = a2port(fwdargs[0].arg);
2935 fwd->connect_host = xstrdup(fwdargs[1].arg);
2936 fwd->connect_port = a2port(fwdargs[2].arg);
2937 }
2938 break;
2939
2940 case 4:
2941 fwd->listen_host = xstrdup(fwdargs[0].arg);
2942 fwd->listen_port = a2port(fwdargs[1].arg);
2943 fwd->connect_host = xstrdup(fwdargs[2].arg);
2944 fwd->connect_port = a2port(fwdargs[3].arg);
2945 break;
2946 default:
2947 i = 0; /* failure */
2948 }
2949
2950 free(p);
2951
2952 if (dynamicfwd) {
2953 if (!(i == 1 || i == 2))
2954 goto fail_free;
2955 } else {
2956 if (!(i == 3 || i == 4)) {
2957 if (fwd->connect_path == NULL((void *)0) &&
2958 fwd->listen_path == NULL((void *)0))
2959 goto fail_free;
2960 }
2961 if (fwd->connect_port <= 0 && fwd->connect_path == NULL((void *)0))
2962 goto fail_free;
2963 }
2964
2965 if ((fwd->listen_port < 0 && fwd->listen_path == NULL((void *)0)) ||
2966 (!remotefwd && fwd->listen_port == 0))
2967 goto fail_free;
2968 if (fwd->connect_host != NULL((void *)0) &&
2969 strlen(fwd->connect_host) >= NI_MAXHOST256)
2970 goto fail_free;
2971 /*
2972 * XXX - if connecting to a remote socket, max sun len may not
2973 * match this host
2974 */
2975 if (fwd->connect_path != NULL((void *)0) &&
2976 strlen(fwd->connect_path) >= PATH_MAX_SUN(sizeof((struct sockaddr_un *)0)->sun_path))
2977 goto fail_free;
2978 if (fwd->listen_host != NULL((void *)0) &&
2979 strlen(fwd->listen_host) >= NI_MAXHOST256)
2980 goto fail_free;
2981 if (fwd->listen_path != NULL((void *)0) &&
2982 strlen(fwd->listen_path) >= PATH_MAX_SUN(sizeof((struct sockaddr_un *)0)->sun_path))
2983 goto fail_free;
2984
2985 return (i);
2986
2987 fail_free:
2988 free(fwd->connect_host);
2989 fwd->connect_host = NULL((void *)0);
2990 free(fwd->connect_path);
2991 fwd->connect_path = NULL((void *)0);
2992 free(fwd->listen_host);
2993 fwd->listen_host = NULL((void *)0);
2994 free(fwd->listen_path);
2995 fwd->listen_path = NULL((void *)0);
2996 return (0);
2997}
2998
2999int
3000parse_jump(const char *s, Options *o, int active)
3001{
3002 char *orig, *sdup, *cp;
3003 char *host = NULL((void *)0), *user = NULL((void *)0);
3004 int r, ret = -1, port = -1, first;
3005
3006 active &= o->proxy_command == NULL((void *)0) && o->jump_host == NULL((void *)0);
3007
3008 orig = sdup = xstrdup(s);
3009
3010 /* Remove comment and trailing whitespace */
3011 if ((cp = strchr(orig, '#')) != NULL((void *)0))
3012 *cp = '\0';
3013 rtrim(orig);
3014
3015 first = active;
3016 do {
3017 if (strcasecmp(s, "none") == 0)
3018 break;
3019 if ((cp = strrchr(sdup, ',')) == NULL((void *)0))
3020 cp = sdup; /* last */
3021 else
3022 *cp++ = '\0';
3023
3024 if (first) {
3025 /* First argument and configuration is active */
3026 r = parse_ssh_uri(cp, &user, &host, &port);
3027 if (r == -1 || (r == 1 &&
3028 parse_user_host_port(cp, &user, &host, &port) != 0))
3029 goto out;
3030 } else {
3031 /* Subsequent argument or inactive configuration */
3032 r = parse_ssh_uri(cp, NULL((void *)0), NULL((void *)0), NULL((void *)0));
3033 if (r == -1 || (r == 1 &&
3034 parse_user_host_port(cp, NULL((void *)0), NULL((void *)0), NULL((void *)0)) != 0))
3035 goto out;
3036 }
3037 first = 0; /* only check syntax for subsequent hosts */
3038 } while (cp != sdup);
3039 /* success */
3040 if (active) {
3041 if (strcasecmp(s, "none") == 0) {
3042 o->jump_host = xstrdup("none");
3043 o->jump_port = 0;
3044 } else {
3045 o->jump_user = user;
3046 o->jump_host = host;
3047 o->jump_port = port;
3048 o->proxy_command = xstrdup("none");
3049 user = host = NULL((void *)0);
3050 if ((cp = strrchr(s, ',')) != NULL((void *)0) && cp != s) {
3051 o->jump_extra = xstrdup(s);
3052 o->jump_extra[cp - s] = '\0';
3053 }
3054 }
3055 }
3056 ret = 0;
3057 out:
3058 free(orig);
3059 free(user);
3060 free(host);
3061 return ret;
3062}
3063
3064int
3065parse_ssh_uri(const char *uri, char **userp, char **hostp, int *portp)
3066{
3067 char *user = NULL((void *)0), *host = NULL((void *)0), *path = NULL((void *)0);
3068 int r, port;
3069
3070 r = parse_uri("ssh", uri, &user, &host, &port, &path);
3071 if (r == 0 && path != NULL((void *)0))
3072 r = -1; /* path not allowed */
3073 if (r == 0) {
3074 if (userp != NULL((void *)0)) {
3075 *userp = user;
3076 user = NULL((void *)0);
3077 }
3078 if (hostp != NULL((void *)0)) {
3079 *hostp = host;
3080 host = NULL((void *)0);
3081 }
3082 if (portp != NULL((void *)0))
3083 *portp = port;
3084 }
3085 free(user);
3086 free(host);
3087 free(path);
3088 return r;
3089}
3090
3091/* XXX the following is a near-vebatim copy from servconf.c; refactor */
3092static const char *
3093fmt_multistate_int(int val, const struct multistate *m)
3094{
3095 u_int i;
3096
3097 for (i = 0; m[i].key != NULL((void *)0); i++) {
3098 if (m[i].value == val)
3099 return m[i].key;
3100 }
3101 return "UNKNOWN";
3102}
3103
3104static const char *
3105fmt_intarg(OpCodes code, int val)
3106{
3107 if (val == -1)
3108 return "unset";
3109 switch (code) {
3110 case oAddressFamily:
3111 return fmt_multistate_int(val, multistate_addressfamily);
3112 case oVerifyHostKeyDNS:
3113 case oUpdateHostkeys:
3114 return fmt_multistate_int(val, multistate_yesnoask);
3115 case oStrictHostKeyChecking:
3116 return fmt_multistate_int(val, multistate_strict_hostkey);
3117 case oControlMaster:
3118 return fmt_multistate_int(val, multistate_controlmaster);
3119 case oTunnel:
3120 return fmt_multistate_int(val, multistate_tunnel);
3121 case oRequestTTY:
3122 return fmt_multistate_int(val, multistate_requesttty);
3123 case oSessionType:
3124 return fmt_multistate_int(val, multistate_sessiontype);
3125 case oCanonicalizeHostname:
3126 return fmt_multistate_int(val, multistate_canonicalizehostname);
3127 case oAddKeysToAgent:
3128 return fmt_multistate_int(val, multistate_yesnoaskconfirm);
3129 case oPubkeyAuthentication:
3130 return fmt_multistate_int(val, multistate_pubkey_auth);
3131 case oFingerprintHash:
3132 return ssh_digest_alg_name(val);
3133 default:
3134 switch (val) {
3135 case 0:
3136 return "no";
3137 case 1:
3138 return "yes";
3139 default:
3140 return "UNKNOWN";
3141 }
3142 }
3143}
3144
3145static const char *
3146lookup_opcode_name(OpCodes code)
3147{
3148 u_int i;
3149
3150 for (i = 0; keywords[i].name != NULL((void *)0); i++)
3151 if (keywords[i].opcode == code)
3152 return(keywords[i].name);
3153 return "UNKNOWN";
3154}
3155
3156static void
3157dump_cfg_int(OpCodes code, int val)
3158{
3159 printf("%s %d\n", lookup_opcode_name(code), val);
3160}
3161
3162static void
3163dump_cfg_fmtint(OpCodes code, int val)
3164{
3165 printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
3166}
3167
3168static void
3169dump_cfg_string(OpCodes code, const char *val)
3170{
3171 if (val == NULL((void *)0))
3172 return;
3173 printf("%s %s\n", lookup_opcode_name(code), val);
3174}
3175
3176static void
3177dump_cfg_strarray(OpCodes code, u_int count, char **vals)
3178{
3179 u_int i;
3180
3181 for (i = 0; i < count; i++)
3182 printf("%s %s\n", lookup_opcode_name(code), vals[i]);
3183}
3184
3185static void
3186dump_cfg_strarray_oneline(OpCodes code, u_int count, char **vals)
3187{
3188 u_int i;
3189
3190 printf("%s", lookup_opcode_name(code));
3191 if (count == 0)
3192 printf(" none");
3193 for (i = 0; i < count; i++)
3194 printf(" %s", vals[i]);
3195 printf("\n");
3196}
3197
3198static void
3199dump_cfg_forwards(OpCodes code, u_int count, const struct Forward *fwds)
3200{
3201 const struct Forward *fwd;
3202 u_int i;
3203
3204 /* oDynamicForward */
3205 for (i = 0; i < count; i++) {
3206 fwd = &fwds[i];
3207 if (code == oDynamicForward && fwd->connect_host != NULL((void *)0) &&
3208 strcmp(fwd->connect_host, "socks") != 0)
3209 continue;
3210 if (code == oLocalForward && fwd->connect_host != NULL((void *)0) &&
3211 strcmp(fwd->connect_host, "socks") == 0)
3212 continue;
3213 printf("%s", lookup_opcode_name(code));
3214 if (fwd->listen_port == PORT_STREAMLOCAL-2)
3215 printf(" %s", fwd->listen_path);
3216 else if (fwd->listen_host == NULL((void *)0))
3217 printf(" %d", fwd->listen_port);
3218 else {
3219 printf(" [%s]:%d",
3220 fwd->listen_host, fwd->listen_port);
3221 }
3222 if (code != oDynamicForward) {
3223 if (fwd->connect_port == PORT_STREAMLOCAL-2)
3224 printf(" %s", fwd->connect_path);
3225 else if (fwd->connect_host == NULL((void *)0))
3226 printf(" %d", fwd->connect_port);
3227 else {
3228 printf(" [%s]:%d",
3229 fwd->connect_host, fwd->connect_port);
3230 }
3231 }
3232 printf("\n");
3233 }
3234}
3235
3236void
3237dump_client_config(Options *o, const char *host)
3238{
3239 int i, r;
3240 char buf[8], *all_key;
3241
3242 /*
3243 * Expand HostKeyAlgorithms name lists. This isn't handled in
3244 * fill_default_options() like the other algorithm lists because
3245 * the host key algorithms are by default dynamically chosen based
3246 * on the host's keys found in known_hosts.
3247 */
3248 all_key = sshkey_alg_list(0, 0, 1, ',');
3249 if ((r = kex_assemble_names(&o->hostkeyalgorithms, kex_default_pk_alg(),
3250 all_key)) != 0)
3251 fatal_fr(r, "expand HostKeyAlgorithms")sshfatal("/usr/src/usr.bin/ssh/ssh-keysign/../readconf.c", __func__
, 3251, 1, SYSLOG_LEVEL_FATAL, ssh_err(r), "expand HostKeyAlgorithms"
)
;
3252 free(all_key);
3253
3254 /* Most interesting options first: user, host, port */
3255 dump_cfg_string(oUser, o->user);
3256 dump_cfg_string(oHostname, host);
3257 dump_cfg_int(oPort, o->port);
3258
3259 /* Flag options */
3260 dump_cfg_fmtint(oAddressFamily, o->address_family);
3261 dump_cfg_fmtint(oBatchMode, o->batch_mode);
3262 dump_cfg_fmtint(oCanonicalizeFallbackLocal, o->canonicalize_fallback_local);
3263 dump_cfg_fmtint(oCanonicalizeHostname, o->canonicalize_hostname);
3264 dump_cfg_fmtint(oCheckHostIP, o->check_host_ip);
3265 dump_cfg_fmtint(oCompression, o->compression);
3266 dump_cfg_fmtint(oControlMaster, o->control_master);
3267 dump_cfg_fmtint(oEnableSSHKeysign, o->enable_ssh_keysign);
3268 dump_cfg_fmtint(oClearAllForwardings, o->clear_forwardings);
3269 dump_cfg_fmtint(oExitOnForwardFailure, o->exit_on_forward_failure);
3270 dump_cfg_fmtint(oFingerprintHash, o->fingerprint_hash);
3271 dump_cfg_fmtint(oForwardX11, o->forward_x11);
3272 dump_cfg_fmtint(oForwardX11Trusted, o->forward_x11_trusted);
3273 dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports);
3274#ifdef GSSAPI
3275 dump_cfg_fmtint(oGssAuthentication, o->gss_authentication);
3276 dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds);
3277#endif /* GSSAPI */
3278 dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts);
3279 dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication);
3280 dump_cfg_fmtint(oIdentitiesOnly, o->identities_only);
3281 dump_cfg_fmtint(oKbdInteractiveAuthentication, o->kbd_interactive_authentication);
3282 dump_cfg_fmtint(oNoHostAuthenticationForLocalhost, o->no_host_authentication_for_localhost);
3283 dump_cfg_fmtint(oPasswordAuthentication, o->password_authentication);
3284 dump_cfg_fmtint(oPermitLocalCommand, o->permit_local_command);
3285 dump_cfg_fmtint(oProxyUseFdpass, o->proxy_use_fdpass);
3286 dump_cfg_fmtint(oPubkeyAuthentication, o->pubkey_authentication);
3287 dump_cfg_fmtint(oRequestTTY, o->request_tty);
3288 dump_cfg_fmtint(oSessionType, o->session_type);
3289 dump_cfg_fmtint(oStdinNull, o->stdin_null);
3290 dump_cfg_fmtint(oForkAfterAuthentication, o->fork_after_authentication);
3291 dump_cfg_fmtint(oStreamLocalBindUnlink, o->fwd_opts.streamlocal_bind_unlink);
3292 dump_cfg_fmtint(oStrictHostKeyChecking, o->strict_host_key_checking);
3293 dump_cfg_fmtint(oTCPKeepAlive, o->tcp_keep_alive);
3294 dump_cfg_fmtint(oTunnel, o->tun_open);
3295 dump_cfg_fmtint(oVerifyHostKeyDNS, o->verify_host_key_dns);
3296 dump_cfg_fmtint(oVisualHostKey, o->visual_host_key);
3297 dump_cfg_fmtint(oUpdateHostkeys, o->update_hostkeys);
3298
3299 /* Integer options */
3300 dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots);
3301 dump_cfg_int(oConnectionAttempts, o->connection_attempts);
3302 dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout);
3303 dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);
3304 dump_cfg_int(oServerAliveCountMax, o->server_alive_count_max);
3305 dump_cfg_int(oServerAliveInterval, o->server_alive_interval);
3306
3307 /* String options */
3308 dump_cfg_string(oBindAddress, o->bind_address);
3309 dump_cfg_string(oBindInterface, o->bind_interface);
3310 dump_cfg_string(oCiphers, o->ciphers);
3311 dump_cfg_string(oControlPath, o->control_path);
3312 dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms);
3313 dump_cfg_string(oHostKeyAlias, o->host_key_alias);
3314 dump_cfg_string(oHostbasedAcceptedAlgorithms, o->hostbased_accepted_algos);
3315 dump_cfg_string(oIdentityAgent, o->identity_agent);
3316 dump_cfg_string(oIgnoreUnknown, o->ignored_unknown);
3317 dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);
3318 dump_cfg_string(oKexAlgorithms, o->kex_algorithms);
3319 dump_cfg_string(oCASignatureAlgorithms, o->ca_sign_algorithms);
3320 dump_cfg_string(oLocalCommand, o->local_command);
3321 dump_cfg_string(oRemoteCommand, o->remote_command);
3322 dump_cfg_string(oLogLevel, log_level_name(o->log_level));
3323 dump_cfg_string(oMacs, o->macs);
3324#ifdef ENABLE_PKCS111
3325 dump_cfg_string(oPKCS11Provider, o->pkcs11_provider);
3326#endif
3327 dump_cfg_string(oSecurityKeyProvider, o->sk_provider);
3328 dump_cfg_string(oPreferredAuthentications, o->preferred_authentications);
3329 dump_cfg_string(oPubkeyAcceptedAlgorithms, o->pubkey_accepted_algos);
3330 dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys);
3331 dump_cfg_string(oXAuthLocation, o->xauth_location);
3332 dump_cfg_string(oKnownHostsCommand, o->known_hosts_command);
3333
3334 /* Forwards */
3335 dump_cfg_forwards(oDynamicForward, o->num_local_forwards, o->local_forwards);
3336 dump_cfg_forwards(oLocalForward, o->num_local_forwards, o->local_forwards);
3337 dump_cfg_forwards(oRemoteForward, o->num_remote_forwards, o->remote_forwards);
3338
3339 /* String array options */
3340 dump_cfg_strarray(oIdentityFile, o->num_identity_files, o->identity_files);
3341 dump_cfg_strarray_oneline(oCanonicalDomains, o->num_canonical_domains, o->canonical_domains);
3342 dump_cfg_strarray(oCertificateFile, o->num_certificate_files, o->certificate_files);
3343 dump_cfg_strarray_oneline(oGlobalKnownHostsFile, o->num_system_hostfiles, o->system_hostfiles);
3344 dump_cfg_strarray_oneline(oUserKnownHostsFile, o->num_user_hostfiles, o->user_hostfiles);
3345 dump_cfg_strarray(oSendEnv, o->num_send_env, o->send_env);
3346 dump_cfg_strarray(oSetEnv, o->num_setenv, o->setenv);
3347 dump_cfg_strarray_oneline(oLogVerbose,
3348 o->num_log_verbose, o->log_verbose);
3349
3350 /* Special cases */
3351
3352 /* PermitRemoteOpen */
3353 if (o->num_permitted_remote_opens == 0)
3354 printf("%s any\n", lookup_opcode_name(oPermitRemoteOpen));
3355 else
3356 dump_cfg_strarray_oneline(oPermitRemoteOpen,
3357 o->num_permitted_remote_opens, o->permitted_remote_opens);
3358
3359 /* AddKeysToAgent */
3360 if (o->add_keys_to_agent_lifespan <= 0)
3361 dump_cfg_fmtint(oAddKeysToAgent, o->add_keys_to_agent);
3362 else {
3363 printf("addkeystoagent%s %d\n",
3364 o->add_keys_to_agent == 3 ? " confirm" : "",
3365 o->add_keys_to_agent_lifespan);
3366 }
3367
3368 /* oForwardAgent */
3369 if (o->forward_agent_sock_path == NULL((void *)0))
3370 dump_cfg_fmtint(oForwardAgent, o->forward_agent);
3371 else
3372 dump_cfg_string(oForwardAgent, o->forward_agent_sock_path);
3373
3374 /* oConnectTimeout */
3375 if (o->connection_timeout == -1)
3376 printf("connecttimeout none\n");
3377 else
3378 dump_cfg_int(oConnectTimeout, o->connection_timeout);
3379
3380 /* oTunnelDevice */
3381 printf("tunneldevice");
3382 if (o->tun_local == SSH_TUNID_ANY0x7fffffff)
3383 printf(" any");
3384 else
3385 printf(" %d", o->tun_local);
3386 if (o->tun_remote == SSH_TUNID_ANY0x7fffffff)
3387 printf(":any");
3388 else
3389 printf(":%d", o->tun_remote);
3390 printf("\n");
3391
3392 /* oCanonicalizePermittedCNAMEs */
3393 printf("canonicalizePermittedcnames");
3394 if (o->num_permitted_cnames == 0)
3395 printf(" none");
3396 for (i = 0; i < o->num_permitted_cnames; i++) {
3397 printf(" %s:%s", o->permitted_cnames[i].source_list,
3398 o->permitted_cnames[i].target_list);
3399 }
3400 printf("\n");
3401
3402 /* oControlPersist */
3403 if (o->control_persist == 0 || o->control_persist_timeout == 0)
3404 dump_cfg_fmtint(oControlPersist, o->control_persist);
3405 else
3406 dump_cfg_int(oControlPersist, o->control_persist_timeout);
3407
3408 /* oEscapeChar */
3409 if (o->escape_char == SSH_ESCAPECHAR_NONE-2)
3410 printf("escapechar none\n");
3411 else {
3412 vis(buf, o->escape_char, VIS_WHITE(0x04 | 0x08 | 0x10), 0);
3413 printf("escapechar %s\n", buf);
3414 }
3415
3416 /* oIPQoS */
3417 printf("ipqos %s ", iptos2str(o->ip_qos_interactive));
3418 printf("%s\n", iptos2str(o->ip_qos_bulk));
3419
3420 /* oRekeyLimit */
3421 printf("rekeylimit %llu %d\n",
3422 (unsigned long long)o->rekey_limit, o->rekey_interval);
3423
3424 /* oStreamLocalBindMask */
3425 printf("streamlocalbindmask 0%o\n",
3426 o->fwd_opts.streamlocal_bind_mask);
3427
3428 /* oLogFacility */
3429 printf("syslogfacility %s\n", log_facility_name(o->log_facility));
3430
3431 /* oProxyCommand / oProxyJump */
3432 if (o->jump_host == NULL((void *)0))
3433 dump_cfg_string(oProxyCommand, o->proxy_command);
3434 else {
3435 /* Check for numeric addresses */
3436 i = strchr(o->jump_host, ':') != NULL((void *)0) ||
3437 strspn(o->jump_host, "1234567890.") == strlen(o->jump_host);
3438 snprintf(buf, sizeof(buf), "%d", o->jump_port);
3439 printf("proxyjump %s%s%s%s%s%s%s%s%s\n",
3440 /* optional additional jump spec */
3441 o->jump_extra == NULL((void *)0) ? "" : o->jump_extra,
3442 o->jump_extra == NULL((void *)0) ? "" : ",",
3443 /* optional user */
3444 o->jump_user == NULL((void *)0) ? "" : o->jump_user,
3445 o->jump_user == NULL((void *)0) ? "" : "@",
3446 /* opening [ if hostname is numeric */
3447 i ? "[" : "",
3448 /* mandatory hostname */
3449 o->jump_host,
3450 /* closing ] if hostname is numeric */
3451 i ? "]" : "",
3452 /* optional port number */
3453 o->jump_port <= 0 ? "" : ":",
3454 o->jump_port <= 0 ? "" : buf);
3455 }
3456}