summaryrefslogtreecommitdiff
path: root/readconf.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>1999-11-25 00:26:21 +1100
committerDamien Miller <djm@mindrot.org>1999-11-25 00:26:21 +1100
commit95def09838fc61b37b6ea7cd5c234a465b4b129b (patch)
tree042744f76f40a326b873cb1c3690a6d7d966bc3e /readconf.c
parent4d2f15f895f4c795afc008aeff3fd2ceffbc44f4 (diff)
- Merged very large OpenBSD source code reformat
- OpenBSD CVS updates - [channels.c cipher.c compat.c log-client.c scp.c serverloop.c] [ssh.h sshd.8 sshd.c] syslog changes: * Unified Logmessage for all auth-types, for success and for failed * Standard connections get only ONE line in the LOG when level==LOG: Auth-attempts are logged only, if authentication is: a) successfull or b) with passwd or c) we had more than AUTH_FAIL_LOG failues * many log() became verbose() * old behaviour with level=VERBOSE - [readconf.c readconf.h ssh.1 ssh.h sshconnect.c sshd.c] tranfer s/key challenge/response data in SSH_SMSG_AUTH_TIS_CHALLENGE messages. allows use of s/key in windows (ttssh, securecrt) and ssh-1.2.27 clients without 'ssh -v', ok: niels@ - [sshd.8] -V, for fallback to openssh in SSH2 compatibility mode - [sshd.c] fix sigchld race; cjc5@po.cwru.edu
Diffstat (limited to 'readconf.c')
-rw-r--r--readconf.c1097
1 files changed, 548 insertions, 549 deletions
diff --git a/readconf.c b/readconf.c
index d8694b82d..063bd467d 100644
--- a/readconf.c
+++ b/readconf.c
@@ -1,20 +1,20 @@
1/* 1/*
2 2 *
3readconf.c 3 * readconf.c
4 4 *
5Author: Tatu Ylonen <ylo@cs.hut.fi> 5 * Author: Tatu Ylonen <ylo@cs.hut.fi>
6 6 *
7Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 7 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
8 All rights reserved 8 * All rights reserved
9 9 *
10Created: Sat Apr 22 00:03:10 1995 ylo 10 * Created: Sat Apr 22 00:03:10 1995 ylo
11 11 *
12Functions for reading the configuration files. 12 * Functions for reading the configuration files.
13 13 *
14*/ 14 */
15 15
16#include "includes.h" 16#include "includes.h"
17RCSID("$Id: readconf.c,v 1.4 1999/11/21 02:23:53 damien Exp $"); 17RCSID("$Id: readconf.c,v 1.5 1999/11/24 13:26:22 damien Exp $");
18 18
19#include "ssh.h" 19#include "ssh.h"
20#include "cipher.h" 20#include "cipher.h"
@@ -86,73 +86,72 @@ RCSID("$Id: readconf.c,v 1.4 1999/11/21 02:23:53 damien Exp $");
86 86
87/* Keyword tokens. */ 87/* Keyword tokens. */
88 88
89typedef enum 89typedef enum {
90{ 90 oBadOption,
91 oBadOption, 91 oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication,
92 oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication, 92 oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh,
93 oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh, 93 oSkeyAuthentication,
94#ifdef KRB4 94#ifdef KRB4
95 oKerberosAuthentication, 95 oKerberosAuthentication,
96#endif /* KRB4 */ 96#endif /* KRB4 */
97#ifdef AFS 97#ifdef AFS
98 oKerberosTgtPassing, oAFSTokenPassing, 98 oKerberosTgtPassing, oAFSTokenPassing,
99#endif 99#endif
100 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward, 100 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
101 oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand, 101 oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
102 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, 102 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
103 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, 103 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
104 oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, oTISAuthentication, 104 oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, oTISAuthentication,
105 oUsePrivilegedPort, oLogLevel 105 oUsePrivilegedPort, oLogLevel
106} OpCodes; 106} OpCodes;
107 107
108/* Textual representations of the tokens. */ 108/* Textual representations of the tokens. */
109 109
110static struct 110static struct {
111{ 111 const char *name;
112 const char *name; 112 OpCodes opcode;
113 OpCodes opcode; 113} keywords[] = {
114} keywords[] = 114 { "forwardagent", oForwardAgent },
115{ 115 { "forwardx11", oForwardX11 },
116 { "forwardagent", oForwardAgent }, 116 { "gatewayports", oGatewayPorts },
117 { "forwardx11", oForwardX11 }, 117 { "useprivilegedport", oUsePrivilegedPort },
118 { "gatewayports", oGatewayPorts }, 118 { "rhostsauthentication", oRhostsAuthentication },
119 { "useprivilegedport", oUsePrivilegedPort }, 119 { "passwordauthentication", oPasswordAuthentication },
120 { "rhostsauthentication", oRhostsAuthentication }, 120 { "rsaauthentication", oRSAAuthentication },
121 { "passwordauthentication", oPasswordAuthentication }, 121 { "skeyauthentication", oSkeyAuthentication },
122 { "rsaauthentication", oRSAAuthentication },
123#ifdef KRB4 122#ifdef KRB4
124 { "kerberosauthentication", oKerberosAuthentication }, 123 { "kerberosauthentication", oKerberosAuthentication },
125#endif /* KRB4 */ 124#endif /* KRB4 */
126#ifdef AFS 125#ifdef AFS
127 { "kerberostgtpassing", oKerberosTgtPassing }, 126 { "kerberostgtpassing", oKerberosTgtPassing },
128 { "afstokenpassing", oAFSTokenPassing }, 127 { "afstokenpassing", oAFSTokenPassing },
129#endif 128#endif
130 { "fallbacktorsh", oFallBackToRsh }, 129 { "fallbacktorsh", oFallBackToRsh },
131 { "usersh", oUseRsh }, 130 { "usersh", oUseRsh },
132 { "identityfile", oIdentityFile }, 131 { "identityfile", oIdentityFile },
133 { "hostname", oHostName }, 132 { "hostname", oHostName },
134 { "proxycommand", oProxyCommand }, 133 { "proxycommand", oProxyCommand },
135 { "port", oPort }, 134 { "port", oPort },
136 { "cipher", oCipher }, 135 { "cipher", oCipher },
137 { "remoteforward", oRemoteForward }, 136 { "remoteforward", oRemoteForward },
138 { "localforward", oLocalForward }, 137 { "localforward", oLocalForward },
139 { "user", oUser }, 138 { "user", oUser },
140 { "host", oHost }, 139 { "host", oHost },
141 { "escapechar", oEscapeChar }, 140 { "escapechar", oEscapeChar },
142 { "rhostsrsaauthentication", oRhostsRSAAuthentication }, 141 { "rhostsrsaauthentication", oRhostsRSAAuthentication },
143 { "globalknownhostsfile", oGlobalKnownHostsFile }, 142 { "globalknownhostsfile", oGlobalKnownHostsFile },
144 { "userknownhostsfile", oUserKnownHostsFile }, 143 { "userknownhostsfile", oUserKnownHostsFile },
145 { "connectionattempts", oConnectionAttempts }, 144 { "connectionattempts", oConnectionAttempts },
146 { "batchmode", oBatchMode }, 145 { "batchmode", oBatchMode },
147 { "checkhostip", oCheckHostIP }, 146 { "checkhostip", oCheckHostIP },
148 { "stricthostkeychecking", oStrictHostKeyChecking }, 147 { "stricthostkeychecking", oStrictHostKeyChecking },
149 { "compression", oCompression }, 148 { "compression", oCompression },
150 { "compressionlevel", oCompressionLevel }, 149 { "compressionlevel", oCompressionLevel },
151 { "keepalive", oKeepAlives }, 150 { "keepalive", oKeepAlives },
152 { "numberofpasswordprompts", oNumberOfPasswordPrompts }, 151 { "numberofpasswordprompts", oNumberOfPasswordPrompts },
153 { "tisauthentication", oTISAuthentication }, 152 { "tisauthentication", oTISAuthentication },
154 { "loglevel", oLogLevel }, 153 { "loglevel", oLogLevel },
155 { NULL, 0 } 154 { NULL, 0 }
156}; 155};
157 156
158/* Characters considered whitespace in strtok calls. */ 157/* Characters considered whitespace in strtok calls. */
@@ -162,53 +161,56 @@ static struct
162/* Adds a local TCP/IP port forward to options. Never returns if there 161/* Adds a local TCP/IP port forward to options. Never returns if there
163 is an error. */ 162 is an error. */
164 163
165void add_local_forward(Options *options, int port, const char *host, 164void
166 int host_port) 165add_local_forward(Options *options, int port, const char *host,
166 int host_port)
167{ 167{
168 Forward *fwd; 168 Forward *fwd;
169 extern uid_t original_real_uid; 169 extern uid_t original_real_uid;
170 if ((port & 0xffff) != port) 170 if ((port & 0xffff) != port)
171 fatal("Requested forwarding of nonexistent port %d.", port); 171 fatal("Requested forwarding of nonexistent port %d.", port);
172 if (port < IPPORT_RESERVED && original_real_uid != 0) 172 if (port < IPPORT_RESERVED && original_real_uid != 0)
173 fatal("Privileged ports can only be forwarded by root.\n"); 173 fatal("Privileged ports can only be forwarded by root.\n");
174 if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) 174 if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
175 fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION); 175 fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION);
176 fwd = &options->local_forwards[options->num_local_forwards++]; 176 fwd = &options->local_forwards[options->num_local_forwards++];
177 fwd->port = port; 177 fwd->port = port;
178 fwd->host = xstrdup(host); 178 fwd->host = xstrdup(host);
179 fwd->host_port = host_port; 179 fwd->host_port = host_port;
180} 180}
181 181
182/* Adds a remote TCP/IP port forward to options. Never returns if there 182/* Adds a remote TCP/IP port forward to options. Never returns if there
183 is an error. */ 183 is an error. */
184 184
185void add_remote_forward(Options *options, int port, const char *host, 185void
186 int host_port) 186add_remote_forward(Options *options, int port, const char *host,
187 int host_port)
187{ 188{
188 Forward *fwd; 189 Forward *fwd;
189 if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) 190 if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION)
190 fatal("Too many remote forwards (max %d).", 191 fatal("Too many remote forwards (max %d).",
191 SSH_MAX_FORWARDS_PER_DIRECTION); 192 SSH_MAX_FORWARDS_PER_DIRECTION);
192 fwd = &options->remote_forwards[options->num_remote_forwards++]; 193 fwd = &options->remote_forwards[options->num_remote_forwards++];
193 fwd->port = port; 194 fwd->port = port;
194 fwd->host = xstrdup(host); 195 fwd->host = xstrdup(host);
195 fwd->host_port = host_port; 196 fwd->host_port = host_port;
196} 197}
197 198
198/* Returns the number of the token pointed to by cp of length len. 199/* Returns the number of the token pointed to by cp of length len.
199 Never returns if the token is not known. */ 200 Never returns if the token is not known. */
200 201
201static OpCodes parse_token(const char *cp, const char *filename, int linenum) 202static OpCodes
203parse_token(const char *cp, const char *filename, int linenum)
202{ 204{
203 unsigned int i; 205 unsigned int i;
204 206
205 for (i = 0; keywords[i].name; i++) 207 for (i = 0; keywords[i].name; i++)
206 if (strcmp(cp, keywords[i].name) == 0) 208 if (strcmp(cp, keywords[i].name) == 0)
207 return keywords[i].opcode; 209 return keywords[i].opcode;
208 210
209 fprintf(stderr, "%s: line %d: Bad configuration option: %s\n", 211 fprintf(stderr, "%s: line %d: Bad configuration option: %s\n",
210 filename, linenum, cp); 212 filename, linenum, cp);
211 return oBadOption; 213 return oBadOption;
212} 214}
213 215
214/* Processes a single option line as used in the configuration files. 216/* Processes a single option line as used in the configuration files.
@@ -216,336 +218,329 @@ static OpCodes parse_token(const char *cp, const char *filename, int linenum)
216 218
217int 219int
218process_config_line(Options *options, const char *host, 220process_config_line(Options *options, const char *host,
219 char *line, const char *filename, int linenum, 221 char *line, const char *filename, int linenum,
220 int *activep) 222 int *activep)
221{ 223{
222 char buf[256], *cp, *string, **charptr; 224 char buf[256], *cp, *string, **charptr;
223 int opcode, *intptr, value, fwd_port, fwd_host_port; 225 int opcode, *intptr, value, fwd_port, fwd_host_port;
224 226
225 /* Skip leading whitespace. */ 227 /* Skip leading whitespace. */
226 cp = line + strspn(line, WHITESPACE); 228 cp = line + strspn(line, WHITESPACE);
227 if (!*cp || *cp == '\n' || *cp == '#') 229 if (!*cp || *cp == '\n' || *cp == '#')
228 return 0; 230 return 0;
229 231
230 /* Get the keyword. (Each line is supposed to begin with a keyword). */ 232 /* Get the keyword. (Each line is supposed to begin with a
231 cp = strtok(cp, WHITESPACE); 233 keyword). */
232 { 234 cp = strtok(cp, WHITESPACE);
233 char *t = cp; 235 {
234 for (; *t != 0; t++) 236 char *t = cp;
235 if ('A' <= *t && *t <= 'Z') 237 for (; *t != 0; t++)
236 *t = *t - 'A' + 'a'; /* tolower */ 238 if ('A' <= *t && *t <= 'Z')
237 239 *t = *t - 'A' + 'a'; /* tolower */
238 } 240
239 opcode = parse_token(cp, filename, linenum); 241 }
240 242 opcode = parse_token(cp, filename, linenum);
241 switch (opcode) 243
242 { 244 switch (opcode) {
243 case oBadOption: 245 case oBadOption:
244 return -1; /* don't panic, but count bad options */ 246 return -1; /* don't panic, but count bad options */
245 /*NOTREACHED*/ 247 /* NOTREACHED */
246 case oForwardAgent: 248 case oForwardAgent:
247 intptr = &options->forward_agent; 249 intptr = &options->forward_agent;
248 parse_flag: 250parse_flag:
249 cp = strtok(NULL, WHITESPACE); 251 cp = strtok(NULL, WHITESPACE);
250 if (!cp) 252 if (!cp)
251 fatal("%.200s line %d: Missing yes/no argument.", filename, linenum); 253 fatal("%.200s line %d: Missing yes/no argument.", filename, linenum);
252 value = 0; /* To avoid compiler warning... */ 254 value = 0; /* To avoid compiler warning... */
253 if (strcmp(cp, "yes") == 0 || strcmp(cp, "true") == 0) 255 if (strcmp(cp, "yes") == 0 || strcmp(cp, "true") == 0)
254 value = 1; 256 value = 1;
255 else if (strcmp(cp, "no") == 0 || strcmp(cp, "false") == 0) 257 else if (strcmp(cp, "no") == 0 || strcmp(cp, "false") == 0)
256 value = 0; 258 value = 0;
257 else 259 else
258 fatal("%.200s line %d: Bad yes/no argument.", filename, linenum); 260 fatal("%.200s line %d: Bad yes/no argument.", filename, linenum);
259 if (*activep && *intptr == -1) 261 if (*activep && *intptr == -1)
260 *intptr = value; 262 *intptr = value;
261 break; 263 break;
262 264
263 case oForwardX11: 265 case oForwardX11:
264 intptr = &options->forward_x11; 266 intptr = &options->forward_x11;
265 goto parse_flag; 267 goto parse_flag;
266 268
267 case oGatewayPorts: 269 case oGatewayPorts:
268 intptr = &options->gateway_ports; 270 intptr = &options->gateway_ports;
269 goto parse_flag; 271 goto parse_flag;
270 272
271 case oUsePrivilegedPort: 273 case oUsePrivilegedPort:
272 intptr = &options->use_privileged_port; 274 intptr = &options->use_privileged_port;
273 goto parse_flag; 275 goto parse_flag;
274 276
275 case oRhostsAuthentication: 277 case oRhostsAuthentication:
276 intptr = &options->rhosts_authentication; 278 intptr = &options->rhosts_authentication;
277 goto parse_flag; 279 goto parse_flag;
278 280
279 case oPasswordAuthentication: 281 case oPasswordAuthentication:
280 intptr = &options->password_authentication; 282 intptr = &options->password_authentication;
281 goto parse_flag; 283 goto parse_flag;
282 284
283 case oRSAAuthentication: 285 case oRSAAuthentication:
284 intptr = &options->rsa_authentication; 286 intptr = &options->rsa_authentication;
285 goto parse_flag; 287 goto parse_flag;
286 288
287 case oRhostsRSAAuthentication: 289 case oRhostsRSAAuthentication:
288 intptr = &options->rhosts_rsa_authentication; 290 intptr = &options->rhosts_rsa_authentication;
289 goto parse_flag; 291 goto parse_flag;
292
293 case oTISAuthentication:
294 /* fallthrough, there is no difference on the client side */
295 case oSkeyAuthentication:
296 intptr = &options->skey_authentication;
297 goto parse_flag;
290 298
291#ifdef KRB4 299#ifdef KRB4
292 case oKerberosAuthentication: 300 case oKerberosAuthentication:
293 intptr = &options->kerberos_authentication; 301 intptr = &options->kerberos_authentication;
294 goto parse_flag; 302 goto parse_flag;
295#endif /* KRB4 */ 303#endif /* KRB4 */
296 304
297#ifdef AFS 305#ifdef AFS
298 case oKerberosTgtPassing: 306 case oKerberosTgtPassing:
299 intptr = &options->kerberos_tgt_passing; 307 intptr = &options->kerberos_tgt_passing;
300 goto parse_flag; 308 goto parse_flag;
301 309
302 case oAFSTokenPassing: 310 case oAFSTokenPassing:
303 intptr = &options->afs_token_passing; 311 intptr = &options->afs_token_passing;
304 goto parse_flag; 312 goto parse_flag;
305#endif 313#endif
306 314
307 case oFallBackToRsh: 315 case oFallBackToRsh:
308 intptr = &options->fallback_to_rsh; 316 intptr = &options->fallback_to_rsh;
309 goto parse_flag; 317 goto parse_flag;
310 318
311 case oUseRsh: 319 case oUseRsh:
312 intptr = &options->use_rsh; 320 intptr = &options->use_rsh;
313 goto parse_flag; 321 goto parse_flag;
314 322
315 case oBatchMode: 323 case oBatchMode:
316 intptr = &options->batch_mode; 324 intptr = &options->batch_mode;
317 goto parse_flag; 325 goto parse_flag;
318 326
319 case oCheckHostIP: 327 case oCheckHostIP:
320 intptr = &options->check_host_ip; 328 intptr = &options->check_host_ip;
321 goto parse_flag; 329 goto parse_flag;
322 330
323 case oStrictHostKeyChecking: 331 case oStrictHostKeyChecking:
324 intptr = &options->strict_host_key_checking; 332 intptr = &options->strict_host_key_checking;
325 cp = strtok(NULL, WHITESPACE); 333 cp = strtok(NULL, WHITESPACE);
326 if (!cp) 334 if (!cp)
327 fatal("%.200s line %d: Missing yes/no argument.", 335 fatal("%.200s line %d: Missing yes/no argument.",
328 filename, linenum); 336 filename, linenum);
329 value = 0; /* To avoid compiler warning... */ 337 value = 0; /* To avoid compiler warning... */
330 if (strcmp(cp, "yes") == 0 || strcmp(cp, "true") == 0) 338 if (strcmp(cp, "yes") == 0 || strcmp(cp, "true") == 0)
331 value = 1; 339 value = 1;
332 else if (strcmp(cp, "no") == 0 || strcmp(cp, "false") == 0) 340 else if (strcmp(cp, "no") == 0 || strcmp(cp, "false") == 0)
333 value = 0; 341 value = 0;
334 else if (strcmp(cp, "ask") == 0) 342 else if (strcmp(cp, "ask") == 0)
335 value = 2; 343 value = 2;
336 else 344 else
337 fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum); 345 fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum);
338 if (*activep && *intptr == -1) 346 if (*activep && *intptr == -1)
339 *intptr = value; 347 *intptr = value;
340 break; 348 break;
341 349
342 case oCompression: 350 case oCompression:
343 intptr = &options->compression; 351 intptr = &options->compression;
344 goto parse_flag; 352 goto parse_flag;
345 353
346 case oKeepAlives: 354 case oKeepAlives:
347 intptr = &options->keepalives; 355 intptr = &options->keepalives;
348 goto parse_flag; 356 goto parse_flag;
349 357
350 case oNumberOfPasswordPrompts: 358 case oNumberOfPasswordPrompts:
351 intptr = &options->number_of_password_prompts; 359 intptr = &options->number_of_password_prompts;
352 goto parse_int; 360 goto parse_int;
353 361
354 case oTISAuthentication: 362 case oCompressionLevel:
355 cp = strtok(NULL, WHITESPACE); 363 intptr = &options->compression_level;
356 if (cp != 0 && (strcmp(cp, "yes") == 0 || strcmp(cp, "true") == 0)) 364 goto parse_int;
357 fprintf(stderr, 365
358 "%.99s line %d: Warning, TIS is not supported.\n", 366 case oIdentityFile:
359 filename, 367 cp = strtok(NULL, WHITESPACE);
360 linenum); 368 if (!cp)
361 break; 369 fatal("%.200s line %d: Missing argument.", filename, linenum);
362 370 if (*activep) {
363 case oCompressionLevel: 371 if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES)
364 intptr = &options->compression_level; 372 fatal("%.200s line %d: Too many identity files specified (max %d).",
365 goto parse_int; 373 filename, linenum, SSH_MAX_IDENTITY_FILES);
366 374 options->identity_files[options->num_identity_files++] = xstrdup(cp);
367 case oIdentityFile: 375 }
368 cp = strtok(NULL, WHITESPACE); 376 break;
369 if (!cp) 377
370 fatal("%.200s line %d: Missing argument.", filename, linenum); 378 case oUser:
371 if (*activep) 379 charptr = &options->user;
372 { 380parse_string:
373 if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES) 381 cp = strtok(NULL, WHITESPACE);
374 fatal("%.200s line %d: Too many identity files specified (max %d).", 382 if (!cp)
375 filename, linenum, SSH_MAX_IDENTITY_FILES); 383 fatal("%.200s line %d: Missing argument.", filename, linenum);
376 options->identity_files[options->num_identity_files++] = xstrdup(cp); 384 if (*activep && *charptr == NULL)
377 } 385 *charptr = xstrdup(cp);
378 break; 386 break;
379 387
380 case oUser: 388 case oGlobalKnownHostsFile:
381 charptr = &options->user; 389 charptr = &options->system_hostfile;
382 parse_string: 390 goto parse_string;
383 cp = strtok(NULL, WHITESPACE); 391
384 if (!cp) 392 case oUserKnownHostsFile:
385 fatal("%.200s line %d: Missing argument.", filename, linenum); 393 charptr = &options->user_hostfile;
386 if (*activep && *charptr == NULL) 394 goto parse_string;
387 *charptr = xstrdup(cp); 395
388 break; 396 case oHostName:
389 397 charptr = &options->hostname;
390 case oGlobalKnownHostsFile: 398 goto parse_string;
391 charptr = &options->system_hostfile; 399
392 goto parse_string; 400 case oProxyCommand:
393 401 charptr = &options->proxy_command;
394 case oUserKnownHostsFile: 402 string = xstrdup("");
395 charptr = &options->user_hostfile; 403 while ((cp = strtok(NULL, WHITESPACE)) != NULL) {
396 goto parse_string; 404 string = xrealloc(string, strlen(string) + strlen(cp) + 2);
397 405 strcat(string, " ");
398 case oHostName: 406 strcat(string, cp);
399 charptr = &options->hostname; 407 }
400 goto parse_string; 408 if (*activep && *charptr == NULL)
401 409 *charptr = string;
402 case oProxyCommand: 410 else
403 charptr = &options->proxy_command; 411 xfree(string);
404 string = xstrdup(""); 412 return 0;
405 while ((cp = strtok(NULL, WHITESPACE)) != NULL) 413
406 { 414 case oPort:
407 string = xrealloc(string, strlen(string) + strlen(cp) + 2); 415 intptr = &options->port;
408 strcat(string, " "); 416parse_int:
409 strcat(string, cp); 417 cp = strtok(NULL, WHITESPACE);
410 } 418 if (!cp)
411 if (*activep && *charptr == NULL) 419 fatal("%.200s line %d: Missing argument.", filename, linenum);
412 *charptr = string; 420 if (cp[0] < '0' || cp[0] > '9')
413 else 421 fatal("%.200s line %d: Bad number.", filename, linenum);
414 xfree(string);
415 return 0;
416
417 case oPort:
418 intptr = &options->port;
419 parse_int:
420 cp = strtok(NULL, WHITESPACE);
421 if (!cp)
422 fatal("%.200s line %d: Missing argument.", filename, linenum);
423 if (cp[0] < '0' || cp[0] > '9')
424 fatal("%.200s line %d: Bad number.", filename, linenum);
425#if 0 422#if 0
426 value = atoi(cp); 423 value = atoi(cp);
427#else 424#else
428 { 425 {
429 char *ptr; 426 char *ptr;
430 value = strtol(cp, &ptr, 0); /* Octal, decimal, or hex format? */ 427 value = strtol(cp, &ptr, 0); /* Octal, decimal, or
431 if (cp == ptr) 428 hex format? */
432 fatal("%.200s line %d: Bad number.", filename, linenum); 429 if (cp == ptr)
433 } 430 fatal("%.200s line %d: Bad number.", filename, linenum);
431 }
434#endif 432#endif
435 if (*activep && *intptr == -1) 433 if (*activep && *intptr == -1)
436 *intptr = value; 434 *intptr = value;
437 break; 435 break;
438 436
439 case oConnectionAttempts: 437 case oConnectionAttempts:
440 intptr = &options->connection_attempts; 438 intptr = &options->connection_attempts;
441 goto parse_int; 439 goto parse_int;
442 440
443 case oCipher: 441 case oCipher:
444 intptr = &options->cipher; 442 intptr = &options->cipher;
445 cp = strtok(NULL, WHITESPACE); 443 cp = strtok(NULL, WHITESPACE);
446 value = cipher_number(cp); 444 value = cipher_number(cp);
447 if (value == -1) 445 if (value == -1)
448 fatal("%.200s line %d: Bad cipher '%s'.", 446 fatal("%.200s line %d: Bad cipher '%s'.",
449 filename, linenum, cp ? cp : "<NONE>"); 447 filename, linenum, cp ? cp : "<NONE>");
450 if (*activep && *intptr == -1) 448 if (*activep && *intptr == -1)
451 *intptr = value; 449 *intptr = value;
452 break; 450 break;
453 451
454 case oLogLevel: 452 case oLogLevel:
455 intptr = (int *)&options->log_level; 453 intptr = (int *) &options->log_level;
456 cp = strtok(NULL, WHITESPACE); 454 cp = strtok(NULL, WHITESPACE);
457 value = log_level_number(cp); 455 value = log_level_number(cp);
458 if (value == (LogLevel)-1) 456 if (value == (LogLevel) - 1)
459 fatal("%.200s line %d: unsupported log level '%s'\n", 457 fatal("%.200s line %d: unsupported log level '%s'\n",
460 filename, linenum, cp ? cp : "<NONE>"); 458 filename, linenum, cp ? cp : "<NONE>");
461 if (*activep && (LogLevel)*intptr == -1) 459 if (*activep && (LogLevel) * intptr == -1)
462 *intptr = (LogLevel)value; 460 *intptr = (LogLevel) value;
463 break; 461 break;
464 462
465 case oRemoteForward: 463 case oRemoteForward:
466 cp = strtok(NULL, WHITESPACE); 464 cp = strtok(NULL, WHITESPACE);
467 if (!cp) 465 if (!cp)
468 fatal("%.200s line %d: Missing argument.", filename, linenum); 466 fatal("%.200s line %d: Missing argument.", filename, linenum);
469 if (cp[0] < '0' || cp[0] > '9') 467 if (cp[0] < '0' || cp[0] > '9')
470 fatal("%.200s line %d: Badly formatted port number.", 468 fatal("%.200s line %d: Badly formatted port number.",
471 filename, linenum); 469 filename, linenum);
472 fwd_port = atoi(cp); 470 fwd_port = atoi(cp);
473 cp = strtok(NULL, WHITESPACE); 471 cp = strtok(NULL, WHITESPACE);
474 if (!cp) 472 if (!cp)
475 fatal("%.200s line %d: Missing second argument.", 473 fatal("%.200s line %d: Missing second argument.",
476 filename, linenum); 474 filename, linenum);
477 if (sscanf(cp, "%255[^:]:%d", buf, &fwd_host_port) != 2) 475 if (sscanf(cp, "%255[^:]:%d", buf, &fwd_host_port) != 2)
478 fatal("%.200s line %d: Badly formatted host:port.", 476 fatal("%.200s line %d: Badly formatted host:port.",
479 filename, linenum); 477 filename, linenum);
480 if (*activep) 478 if (*activep)
481 add_remote_forward(options, fwd_port, buf, fwd_host_port); 479 add_remote_forward(options, fwd_port, buf, fwd_host_port);
482 break; 480 break;
483 481
484 case oLocalForward: 482 case oLocalForward:
485 cp = strtok(NULL, WHITESPACE); 483 cp = strtok(NULL, WHITESPACE);
486 if (!cp) 484 if (!cp)
487 fatal("%.200s line %d: Missing argument.", filename, linenum); 485 fatal("%.200s line %d: Missing argument.", filename, linenum);
488 if (cp[0] < '0' || cp[0] > '9') 486 if (cp[0] < '0' || cp[0] > '9')
489 fatal("%.200s line %d: Badly formatted port number.", 487 fatal("%.200s line %d: Badly formatted port number.",
490 filename, linenum); 488 filename, linenum);
491 fwd_port = atoi(cp); 489 fwd_port = atoi(cp);
492 cp = strtok(NULL, WHITESPACE); 490 cp = strtok(NULL, WHITESPACE);
493 if (!cp) 491 if (!cp)
494 fatal("%.200s line %d: Missing second argument.", 492 fatal("%.200s line %d: Missing second argument.",
495 filename, linenum); 493 filename, linenum);
496 if (sscanf(cp, "%255[^:]:%d", buf, &fwd_host_port) != 2) 494 if (sscanf(cp, "%255[^:]:%d", buf, &fwd_host_port) != 2)
497 fatal("%.200s line %d: Badly formatted host:port.", 495 fatal("%.200s line %d: Badly formatted host:port.",
498 filename, linenum); 496 filename, linenum);
499 if (*activep) 497 if (*activep)
500 add_local_forward(options, fwd_port, buf, fwd_host_port); 498 add_local_forward(options, fwd_port, buf, fwd_host_port);
501 break; 499 break;
502 500
503 case oHost: 501 case oHost:
504 *activep = 0; 502 *activep = 0;
505 while ((cp = strtok(NULL, WHITESPACE)) != NULL) 503 while ((cp = strtok(NULL, WHITESPACE)) != NULL)
506 if (match_pattern(host, cp)) 504 if (match_pattern(host, cp)) {
507 { 505 debug("Applying options for %.100s", cp);
508 debug("Applying options for %.100s", cp); 506 *activep = 1;
509 *activep = 1; 507 break;
510 break; 508 }
511 } 509 /* Avoid garbage check below, as strtok already returned
512 /* Avoid garbage check below, as strtok already returned NULL. */ 510 NULL. */
513 return 0; 511 return 0;
514 512
515 case oEscapeChar: 513 case oEscapeChar:
516 intptr = &options->escape_char; 514 intptr = &options->escape_char;
517 cp = strtok(NULL, WHITESPACE); 515 cp = strtok(NULL, WHITESPACE);
518 if (!cp) 516 if (!cp)
519 fatal("%.200s line %d: Missing argument.", filename, linenum); 517 fatal("%.200s line %d: Missing argument.", filename, linenum);
520 if (cp[0] == '^' && cp[2] == 0 && 518 if (cp[0] == '^' && cp[2] == 0 &&
521 (unsigned char)cp[1] >= 64 && (unsigned char)cp[1] < 128) 519 (unsigned char) cp[1] >= 64 && (unsigned char) cp[1] < 128)
522 value = (unsigned char)cp[1] & 31; 520 value = (unsigned char) cp[1] & 31;
523 else 521 else if (strlen(cp) == 1)
524 if (strlen(cp) == 1) 522 value = (unsigned char) cp[0];
525 value = (unsigned char)cp[0]; 523 else if (strcmp(cp, "none") == 0)
526 else 524 value = -2;
527 if (strcmp(cp, "none") == 0) 525 else {
528 value = -2; 526 fatal("%.200s line %d: Bad escape character.",
529 else 527 filename, linenum);
530 { 528 /* NOTREACHED */
531 fatal("%.200s line %d: Bad escape character.", 529 value = 0; /* Avoid compiler warning. */
532 filename, linenum); 530 }
533 /*NOTREACHED*/ 531 if (*activep && *intptr == -1)
534 value = 0; /* Avoid compiler warning. */ 532 *intptr = value;
535 } 533 break;
536 if (*activep && *intptr == -1) 534
537 *intptr = value; 535 default:
538 break; 536 fatal("process_config_line: Unimplemented opcode %d", opcode);
539 537 }
540 default: 538
541 fatal("process_config_line: Unimplemented opcode %d", opcode); 539 /* Check that there is no garbage at end of line. */
542 } 540 if (strtok(NULL, WHITESPACE) != NULL)
543 541 fatal("%.200s line %d: garbage at end of line.",
544 /* Check that there is no garbage at end of line. */ 542 filename, linenum);
545 if (strtok(NULL, WHITESPACE) != NULL) 543 return 0;
546 fatal("%.200s line %d: garbage at end of line.",
547 filename, linenum);
548 return 0;
549} 544}
550 545
551 546
@@ -553,35 +548,35 @@ process_config_line(Options *options, const char *host,
553 already be initialized before this call. This never returns if there 548 already be initialized before this call. This never returns if there
554 is an error. If the file does not exist, this returns immediately. */ 549 is an error. If the file does not exist, this returns immediately. */
555 550
556void read_config_file(const char *filename, const char *host, Options *options) 551void
552read_config_file(const char *filename, const char *host, Options *options)
557{ 553{
558 FILE *f; 554 FILE *f;
559 char line[1024]; 555 char line[1024];
560 int active, linenum; 556 int active, linenum;
561 int bad_options = 0; 557 int bad_options = 0;
562 558
563 /* Open the file. */ 559 /* Open the file. */
564 f = fopen(filename, "r"); 560 f = fopen(filename, "r");
565 if (!f) 561 if (!f)
566 return; 562 return;
567 563
568 debug("Reading configuration data %.200s", filename); 564 debug("Reading configuration data %.200s", filename);
569 565
570 /* Mark that we are now processing the options. This flag is turned on/off 566 /* Mark that we are now processing the options. This flag is
571 by Host specifications. */ 567 turned on/off by Host specifications. */
572 active = 1; 568 active = 1;
573 linenum = 0; 569 linenum = 0;
574 while (fgets(line, sizeof(line), f)) 570 while (fgets(line, sizeof(line), f)) {
575 { 571 /* Update line number counter. */
576 /* Update line number counter. */ 572 linenum++;
577 linenum++; 573 if (process_config_line(options, host, line, filename, linenum, &active) != 0)
578 if (process_config_line(options, host, line, filename, linenum, &active) != 0) 574 bad_options++;
579 bad_options++; 575 }
580 } 576 fclose(f);
581 fclose(f); 577 if (bad_options > 0)
582 if (bad_options > 0) 578 fatal("%s: terminating, %d bad configuration options\n",
583 fatal("%s: terminating, %d bad configuration options\n", 579 filename, bad_options);
584 filename, bad_options);
585} 580}
586 581
587/* Initializes options to special values that indicate that they have not 582/* Initializes options to special values that indicate that they have not
@@ -589,120 +584,124 @@ void read_config_file(const char *filename, const char *host, Options *options)
589 Options are processed in the following order: command line, user config 584 Options are processed in the following order: command line, user config
590 file, system config file. Last, fill_default_options is called. */ 585 file, system config file. Last, fill_default_options is called. */
591 586
592void initialize_options(Options *options) 587void
588initialize_options(Options * options)
593{ 589{
594 memset(options, 'X', sizeof(*options)); 590 memset(options, 'X', sizeof(*options));
595 options->forward_agent = -1; 591 options->forward_agent = -1;
596 options->forward_x11 = -1; 592 options->forward_x11 = -1;
597 options->gateway_ports = -1; 593 options->gateway_ports = -1;
598 options->use_privileged_port = -1; 594 options->use_privileged_port = -1;
599 options->rhosts_authentication = -1; 595 options->rhosts_authentication = -1;
600 options->rsa_authentication = -1; 596 options->rsa_authentication = -1;
597 options->skey_authentication = -1;
601#ifdef KRB4 598#ifdef KRB4
602 options->kerberos_authentication = -1; 599 options->kerberos_authentication = -1;
603#endif 600#endif
604#ifdef AFS 601#ifdef AFS
605 options->kerberos_tgt_passing = -1; 602 options->kerberos_tgt_passing = -1;
606 options->afs_token_passing = -1; 603 options->afs_token_passing = -1;
607#endif 604#endif
608 options->password_authentication = -1; 605 options->password_authentication = -1;
609 options->rhosts_rsa_authentication = -1; 606 options->rhosts_rsa_authentication = -1;
610 options->fallback_to_rsh = -1; 607 options->fallback_to_rsh = -1;
611 options->use_rsh = -1; 608 options->use_rsh = -1;
612 options->batch_mode = -1; 609 options->batch_mode = -1;
613 options->check_host_ip = -1; 610 options->check_host_ip = -1;
614 options->strict_host_key_checking = -1; 611 options->strict_host_key_checking = -1;
615 options->compression = -1; 612 options->compression = -1;
616 options->keepalives = -1; 613 options->keepalives = -1;
617 options->compression_level = -1; 614 options->compression_level = -1;
618 options->port = -1; 615 options->port = -1;
619 options->connection_attempts = -1; 616 options->connection_attempts = -1;
620 options->number_of_password_prompts = -1; 617 options->number_of_password_prompts = -1;
621 options->cipher = -1; 618 options->cipher = -1;
622 options->num_identity_files = 0; 619 options->num_identity_files = 0;
623 options->hostname = NULL; 620 options->hostname = NULL;
624 options->proxy_command = NULL; 621 options->proxy_command = NULL;
625 options->user = NULL; 622 options->user = NULL;
626 options->escape_char = -1; 623 options->escape_char = -1;
627 options->system_hostfile = NULL; 624 options->system_hostfile = NULL;
628 options->user_hostfile = NULL; 625 options->user_hostfile = NULL;
629 options->num_local_forwards = 0; 626 options->num_local_forwards = 0;
630 options->num_remote_forwards = 0; 627 options->num_remote_forwards = 0;
631 options->log_level = (LogLevel)-1; 628 options->log_level = (LogLevel) - 1;
632} 629}
633 630
634/* Called after processing other sources of option data, this fills those 631/* Called after processing other sources of option data, this fills those
635 options for which no value has been specified with their default values. */ 632 options for which no value has been specified with their default values. */
636 633
637void fill_default_options(Options *options) 634void
635fill_default_options(Options * options)
638{ 636{
639 if (options->forward_agent == -1) 637 if (options->forward_agent == -1)
640 options->forward_agent = 1; 638 options->forward_agent = 1;
641 if (options->forward_x11 == -1) 639 if (options->forward_x11 == -1)
642 options->forward_x11 = 1; 640 options->forward_x11 = 1;
643 if (options->gateway_ports == -1) 641 if (options->gateway_ports == -1)
644 options->gateway_ports = 0; 642 options->gateway_ports = 0;
645 if (options->use_privileged_port == -1) 643 if (options->use_privileged_port == -1)
646 options->use_privileged_port = 1; 644 options->use_privileged_port = 1;
647 if (options->rhosts_authentication == -1) 645 if (options->rhosts_authentication == -1)
648 options->rhosts_authentication = 1; 646 options->rhosts_authentication = 1;
649 if (options->rsa_authentication == -1) 647 if (options->rsa_authentication == -1)
650 options->rsa_authentication = 1; 648 options->rsa_authentication = 1;
649 if (options->skey_authentication == -1)
650 options->skey_authentication = 0;
651#ifdef KRB4 651#ifdef KRB4
652 if (options->kerberos_authentication == -1) 652 if (options->kerberos_authentication == -1)
653 options->kerberos_authentication = 1; 653 options->kerberos_authentication = 1;
654#endif /* KRB4 */ 654#endif /* KRB4 */
655#ifdef AFS 655#ifdef AFS
656 if (options->kerberos_tgt_passing == -1) 656 if (options->kerberos_tgt_passing == -1)
657 options->kerberos_tgt_passing = 1; 657 options->kerberos_tgt_passing = 1;
658 if (options->afs_token_passing == -1) 658 if (options->afs_token_passing == -1)
659 options->afs_token_passing = 1; 659 options->afs_token_passing = 1;
660#endif /* AFS */ 660#endif /* AFS */
661 if (options->password_authentication == -1) 661 if (options->password_authentication == -1)
662 options->password_authentication = 1; 662 options->password_authentication = 1;
663 if (options->rhosts_rsa_authentication == -1) 663 if (options->rhosts_rsa_authentication == -1)
664 options->rhosts_rsa_authentication = 1; 664 options->rhosts_rsa_authentication = 1;
665 if (options->fallback_to_rsh == -1) 665 if (options->fallback_to_rsh == -1)
666 options->fallback_to_rsh = 1; 666 options->fallback_to_rsh = 1;
667 if (options->use_rsh == -1) 667 if (options->use_rsh == -1)
668 options->use_rsh = 0; 668 options->use_rsh = 0;
669 if (options->batch_mode == -1) 669 if (options->batch_mode == -1)
670 options->batch_mode = 0; 670 options->batch_mode = 0;
671 if (options->check_host_ip == -1) 671 if (options->check_host_ip == -1)
672 options->check_host_ip = 1; 672 options->check_host_ip = 1;
673 if (options->strict_host_key_checking == -1) 673 if (options->strict_host_key_checking == -1)
674 options->strict_host_key_checking = 2; /* 2 is default */ 674 options->strict_host_key_checking = 2; /* 2 is default */
675 if (options->compression == -1) 675 if (options->compression == -1)
676 options->compression = 0; 676 options->compression = 0;
677 if (options->keepalives == -1) 677 if (options->keepalives == -1)
678 options->keepalives = 1; 678 options->keepalives = 1;
679 if (options->compression_level == -1) 679 if (options->compression_level == -1)
680 options->compression_level = 6; 680 options->compression_level = 6;
681 if (options->port == -1) 681 if (options->port == -1)
682 options->port = 0; /* Filled in ssh_connect. */ 682 options->port = 0; /* Filled in ssh_connect. */
683 if (options->connection_attempts == -1) 683 if (options->connection_attempts == -1)
684 options->connection_attempts = 4; 684 options->connection_attempts = 4;
685 if (options->number_of_password_prompts == -1) 685 if (options->number_of_password_prompts == -1)
686 options->number_of_password_prompts = 3; 686 options->number_of_password_prompts = 3;
687 if (options->cipher == -1) 687 /* Selected in ssh_login(). */
688 options->cipher = SSH_CIPHER_NOT_SET; /* Selected in ssh_login(). */ 688 if (options->cipher == -1)
689 if (options->num_identity_files == 0) 689 options->cipher = SSH_CIPHER_NOT_SET;
690 { 690 if (options->num_identity_files == 0) {
691 options->identity_files[0] = 691 options->identity_files[0] =
692 xmalloc(2 + strlen(SSH_CLIENT_IDENTITY) + 1); 692 xmalloc(2 + strlen(SSH_CLIENT_IDENTITY) + 1);
693 sprintf(options->identity_files[0], "~/%.100s", SSH_CLIENT_IDENTITY); 693 sprintf(options->identity_files[0], "~/%.100s", SSH_CLIENT_IDENTITY);
694 options->num_identity_files = 1; 694 options->num_identity_files = 1;
695 } 695 }
696 if (options->escape_char == -1) 696 if (options->escape_char == -1)
697 options->escape_char = '~'; 697 options->escape_char = '~';
698 if (options->system_hostfile == NULL) 698 if (options->system_hostfile == NULL)
699 options->system_hostfile = SSH_SYSTEM_HOSTFILE; 699 options->system_hostfile = SSH_SYSTEM_HOSTFILE;
700 if (options->user_hostfile == NULL) 700 if (options->user_hostfile == NULL)
701 options->user_hostfile = SSH_USER_HOSTFILE; 701 options->user_hostfile = SSH_USER_HOSTFILE;
702 if (options->log_level == (LogLevel)-1) 702 if (options->log_level == (LogLevel) - 1)
703 options->log_level = SYSLOG_LEVEL_INFO; 703 options->log_level = SYSLOG_LEVEL_INFO;
704 /* options->proxy_command should not be set by default */ 704 /* options->proxy_command should not be set by default */
705 /* options->user will be set in the main program if appropriate */ 705 /* options->user will be set in the main program if appropriate */
706 /* options->hostname will be set in the main program if appropriate */ 706 /* options->hostname will be set in the main program if appropriate */
707} 707}
708