diff options
author | Damien Miller <djm@mindrot.org> | 1999-10-27 13:42:43 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 1999-10-27 13:42:43 +1000 |
commit | d4a8b7e34dd619a4debf9a206c81db26d1402ea6 (patch) | |
tree | a47d770a2f790f40d18b0982d4e55fa7cfb1fa3b /readconf.c |
Initial revision
Diffstat (limited to 'readconf.c')
-rw-r--r-- | readconf.c | 684 |
1 files changed, 684 insertions, 0 deletions
diff --git a/readconf.c b/readconf.c new file mode 100644 index 000000000..281548d2a --- /dev/null +++ b/readconf.c | |||
@@ -0,0 +1,684 @@ | |||
1 | /* | ||
2 | |||
3 | readconf.c | ||
4 | |||
5 | Author: Tatu Ylonen <ylo@cs.hut.fi> | ||
6 | |||
7 | Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | ||
8 | All rights reserved | ||
9 | |||
10 | Created: Sat Apr 22 00:03:10 1995 ylo | ||
11 | |||
12 | Functions for reading the configuration files. | ||
13 | |||
14 | */ | ||
15 | |||
16 | #include "includes.h" | ||
17 | RCSID("$Id: readconf.c,v 1.1 1999/10/27 03:42:44 damien Exp $"); | ||
18 | |||
19 | #include "ssh.h" | ||
20 | #include "cipher.h" | ||
21 | #include "readconf.h" | ||
22 | #include "xmalloc.h" | ||
23 | |||
24 | /* Format of the configuration file: | ||
25 | |||
26 | # Configuration data is parsed as follows: | ||
27 | # 1. command line options | ||
28 | # 2. user-specific file | ||
29 | # 3. system-wide file | ||
30 | # Any configuration value is only changed the first time it is set. | ||
31 | # Thus, host-specific definitions should be at the beginning of the | ||
32 | # configuration file, and defaults at the end. | ||
33 | |||
34 | # Host-specific declarations. These may override anything above. A single | ||
35 | # host may match multiple declarations; these are processed in the order | ||
36 | # that they are given in. | ||
37 | |||
38 | Host *.ngs.fi ngs.fi | ||
39 | FallBackToRsh no | ||
40 | |||
41 | Host fake.com | ||
42 | HostName another.host.name.real.org | ||
43 | User blaah | ||
44 | Port 34289 | ||
45 | ForwardX11 no | ||
46 | ForwardAgent no | ||
47 | |||
48 | Host books.com | ||
49 | RemoteForward 9999 shadows.cs.hut.fi:9999 | ||
50 | Cipher 3des | ||
51 | |||
52 | Host fascist.blob.com | ||
53 | Port 23123 | ||
54 | User tylonen | ||
55 | RhostsAuthentication no | ||
56 | PasswordAuthentication no | ||
57 | |||
58 | Host puukko.hut.fi | ||
59 | User t35124p | ||
60 | ProxyCommand ssh-proxy %h %p | ||
61 | |||
62 | Host *.fr | ||
63 | UseRsh yes | ||
64 | |||
65 | Host *.su | ||
66 | Cipher none | ||
67 | PasswordAuthentication no | ||
68 | |||
69 | # Defaults for various options | ||
70 | Host * | ||
71 | ForwardAgent no | ||
72 | ForwardX11 yes | ||
73 | RhostsAuthentication yes | ||
74 | PasswordAuthentication yes | ||
75 | RSAAuthentication yes | ||
76 | RhostsRSAAuthentication yes | ||
77 | FallBackToRsh no | ||
78 | UseRsh no | ||
79 | StrictHostKeyChecking yes | ||
80 | KeepAlives no | ||
81 | IdentityFile ~/.ssh/identity | ||
82 | Port 22 | ||
83 | EscapeChar ~ | ||
84 | |||
85 | */ | ||
86 | |||
87 | /* Keyword tokens. */ | ||
88 | |||
89 | typedef enum | ||
90 | { | ||
91 | oForwardAgent, oForwardX11, oGatewayPorts, oRhostsAuthentication, | ||
92 | oPasswordAuthentication, oRSAAuthentication, oFallBackToRsh, oUseRsh, | ||
93 | #ifdef KRB4 | ||
94 | oKerberosAuthentication, | ||
95 | #endif /* KRB4 */ | ||
96 | #ifdef AFS | ||
97 | oKerberosTgtPassing, oAFSTokenPassing, | ||
98 | #endif | ||
99 | oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward, | ||
100 | oUser, oHost, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand, | ||
101 | oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, | ||
102 | oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, | ||
103 | oCompressionLevel, oKeepAlives, oNumberOfPasswordPrompts, oTISAuthentication, | ||
104 | oUsePrivilegedPort | ||
105 | } OpCodes; | ||
106 | |||
107 | /* Textual representations of the tokens. */ | ||
108 | |||
109 | static struct | ||
110 | { | ||
111 | const char *name; | ||
112 | OpCodes opcode; | ||
113 | } keywords[] = | ||
114 | { | ||
115 | { "forwardagent", oForwardAgent }, | ||
116 | { "forwardx11", oForwardX11 }, | ||
117 | { "gatewayports", oGatewayPorts }, | ||
118 | { "useprivilegedport", oUsePrivilegedPort }, | ||
119 | { "rhostsauthentication", oRhostsAuthentication }, | ||
120 | { "passwordauthentication", oPasswordAuthentication }, | ||
121 | { "rsaauthentication", oRSAAuthentication }, | ||
122 | #ifdef KRB4 | ||
123 | { "kerberosauthentication", oKerberosAuthentication }, | ||
124 | #endif /* KRB4 */ | ||
125 | #ifdef AFS | ||
126 | { "kerberostgtpassing", oKerberosTgtPassing }, | ||
127 | { "afstokenpassing", oAFSTokenPassing }, | ||
128 | #endif | ||
129 | { "fallbacktorsh", oFallBackToRsh }, | ||
130 | { "usersh", oUseRsh }, | ||
131 | { "identityfile", oIdentityFile }, | ||
132 | { "hostname", oHostName }, | ||
133 | { "proxycommand", oProxyCommand }, | ||
134 | { "port", oPort }, | ||
135 | { "cipher", oCipher }, | ||
136 | { "remoteforward", oRemoteForward }, | ||
137 | { "localforward", oLocalForward }, | ||
138 | { "user", oUser }, | ||
139 | { "host", oHost }, | ||
140 | { "escapechar", oEscapeChar }, | ||
141 | { "rhostsrsaauthentication", oRhostsRSAAuthentication }, | ||
142 | { "globalknownhostsfile", oGlobalKnownHostsFile }, | ||
143 | { "userknownhostsfile", oUserKnownHostsFile }, | ||
144 | { "connectionattempts", oConnectionAttempts }, | ||
145 | { "batchmode", oBatchMode }, | ||
146 | { "checkhostip", oCheckHostIP }, | ||
147 | { "stricthostkeychecking", oStrictHostKeyChecking }, | ||
148 | { "compression", oCompression }, | ||
149 | { "compressionlevel", oCompressionLevel }, | ||
150 | { "keepalive", oKeepAlives }, | ||
151 | { "numberofpasswordprompts", oNumberOfPasswordPrompts }, | ||
152 | { "tisauthentication", oTISAuthentication }, | ||
153 | { NULL, 0 } | ||
154 | }; | ||
155 | |||
156 | /* Characters considered whitespace in strtok calls. */ | ||
157 | #define WHITESPACE " \t\r\n" | ||
158 | |||
159 | |||
160 | /* Adds a local TCP/IP port forward to options. Never returns if there | ||
161 | is an error. */ | ||
162 | |||
163 | void add_local_forward(Options *options, int port, const char *host, | ||
164 | int host_port) | ||
165 | { | ||
166 | Forward *fwd; | ||
167 | extern uid_t original_real_uid; | ||
168 | if ((port & 0xffff) != port) | ||
169 | fatal("Requested forwarding of nonexistent port %d.", port); | ||
170 | if (port < IPPORT_RESERVED && original_real_uid != 0) | ||
171 | fatal("Privileged ports can only be forwarded by root.\n"); | ||
172 | if (options->num_local_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) | ||
173 | fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION); | ||
174 | fwd = &options->local_forwards[options->num_local_forwards++]; | ||
175 | fwd->port = port; | ||
176 | fwd->host = xstrdup(host); | ||
177 | fwd->host_port = host_port; | ||
178 | } | ||
179 | |||
180 | /* Adds a remote TCP/IP port forward to options. Never returns if there | ||
181 | is an error. */ | ||
182 | |||
183 | void add_remote_forward(Options *options, int port, const char *host, | ||
184 | int host_port) | ||
185 | { | ||
186 | Forward *fwd; | ||
187 | if (options->num_remote_forwards >= SSH_MAX_FORWARDS_PER_DIRECTION) | ||
188 | fatal("Too many remote forwards (max %d).", | ||
189 | SSH_MAX_FORWARDS_PER_DIRECTION); | ||
190 | fwd = &options->remote_forwards[options->num_remote_forwards++]; | ||
191 | fwd->port = port; | ||
192 | fwd->host = xstrdup(host); | ||
193 | fwd->host_port = host_port; | ||
194 | } | ||
195 | |||
196 | /* Returns the number of the token pointed to by cp of length len. | ||
197 | Never returns if the token is not known. */ | ||
198 | |||
199 | static OpCodes parse_token(const char *cp, const char *filename, int linenum) | ||
200 | { | ||
201 | unsigned int i; | ||
202 | |||
203 | for (i = 0; keywords[i].name; i++) | ||
204 | if (strcmp(cp, keywords[i].name) == 0) | ||
205 | return keywords[i].opcode; | ||
206 | |||
207 | fatal("%.200s line %d: Bad configuration option.", | ||
208 | filename, linenum); | ||
209 | /*NOTREACHED*/ | ||
210 | return 0; | ||
211 | } | ||
212 | |||
213 | /* Processes a single option line as used in the configuration files. | ||
214 | This only sets those values that have not already been set. */ | ||
215 | |||
216 | void process_config_line(Options *options, const char *host, | ||
217 | char *line, const char *filename, int linenum, | ||
218 | int *activep) | ||
219 | { | ||
220 | char buf[256], *cp, *string, **charptr; | ||
221 | int opcode, *intptr, value, fwd_port, fwd_host_port; | ||
222 | |||
223 | /* Skip leading whitespace. */ | ||
224 | cp = line + strspn(line, WHITESPACE); | ||
225 | if (!*cp || *cp == '\n' || *cp == '#') | ||
226 | return; | ||
227 | |||
228 | /* Get the keyword. (Each line is supposed to begin with a keyword). */ | ||
229 | cp = strtok(cp, WHITESPACE); | ||
230 | { | ||
231 | char *t = cp; | ||
232 | for (; *t != 0; t++) | ||
233 | if ('A' <= *t && *t <= 'Z') | ||
234 | *t = *t - 'A' + 'a'; /* tolower */ | ||
235 | |||
236 | } | ||
237 | opcode = parse_token(cp, filename, linenum); | ||
238 | |||
239 | switch (opcode) | ||
240 | { | ||
241 | |||
242 | case oForwardAgent: | ||
243 | intptr = &options->forward_agent; | ||
244 | parse_flag: | ||
245 | cp = strtok(NULL, WHITESPACE); | ||
246 | if (!cp) | ||
247 | fatal("%.200s line %d: Missing yes/no argument.", filename, linenum); | ||
248 | value = 0; /* To avoid compiler warning... */ | ||
249 | if (strcmp(cp, "yes") == 0 || strcmp(cp, "true") == 0) | ||
250 | value = 1; | ||
251 | else if (strcmp(cp, "no") == 0 || strcmp(cp, "false") == 0) | ||
252 | value = 0; | ||
253 | else | ||
254 | fatal("%.200s line %d: Bad yes/no argument.", filename, linenum); | ||
255 | if (*activep && *intptr == -1) | ||
256 | *intptr = value; | ||
257 | break; | ||
258 | |||
259 | case oForwardX11: | ||
260 | intptr = &options->forward_x11; | ||
261 | goto parse_flag; | ||
262 | |||
263 | case oGatewayPorts: | ||
264 | intptr = &options->gateway_ports; | ||
265 | goto parse_flag; | ||
266 | |||
267 | case oUsePrivilegedPort: | ||
268 | intptr = &options->use_privileged_port; | ||
269 | goto parse_flag; | ||
270 | |||
271 | case oRhostsAuthentication: | ||
272 | intptr = &options->rhosts_authentication; | ||
273 | goto parse_flag; | ||
274 | |||
275 | case oPasswordAuthentication: | ||
276 | intptr = &options->password_authentication; | ||
277 | goto parse_flag; | ||
278 | |||
279 | case oRSAAuthentication: | ||
280 | intptr = &options->rsa_authentication; | ||
281 | goto parse_flag; | ||
282 | |||
283 | case oRhostsRSAAuthentication: | ||
284 | intptr = &options->rhosts_rsa_authentication; | ||
285 | goto parse_flag; | ||
286 | |||
287 | #ifdef KRB4 | ||
288 | case oKerberosAuthentication: | ||
289 | intptr = &options->kerberos_authentication; | ||
290 | goto parse_flag; | ||
291 | #endif /* KRB4 */ | ||
292 | |||
293 | #ifdef AFS | ||
294 | case oKerberosTgtPassing: | ||
295 | intptr = &options->kerberos_tgt_passing; | ||
296 | goto parse_flag; | ||
297 | |||
298 | case oAFSTokenPassing: | ||
299 | intptr = &options->afs_token_passing; | ||
300 | goto parse_flag; | ||
301 | #endif | ||
302 | |||
303 | case oFallBackToRsh: | ||
304 | intptr = &options->fallback_to_rsh; | ||
305 | goto parse_flag; | ||
306 | |||
307 | case oUseRsh: | ||
308 | intptr = &options->use_rsh; | ||
309 | goto parse_flag; | ||
310 | |||
311 | case oBatchMode: | ||
312 | intptr = &options->batch_mode; | ||
313 | goto parse_flag; | ||
314 | |||
315 | case oCheckHostIP: | ||
316 | intptr = &options->check_host_ip; | ||
317 | goto parse_flag; | ||
318 | |||
319 | case oStrictHostKeyChecking: | ||
320 | intptr = &options->strict_host_key_checking; | ||
321 | cp = strtok(NULL, WHITESPACE); | ||
322 | if (!cp) | ||
323 | fatal("%.200s line %d: Missing yes/no argument.", | ||
324 | filename, linenum); | ||
325 | value = 0; /* To avoid compiler warning... */ | ||
326 | if (strcmp(cp, "yes") == 0 || strcmp(cp, "true") == 0) | ||
327 | value = 1; | ||
328 | else if (strcmp(cp, "no") == 0 || strcmp(cp, "false") == 0) | ||
329 | value = 0; | ||
330 | else if (strcmp(cp, "ask") == 0) | ||
331 | value = 2; | ||
332 | else | ||
333 | fatal("%.200s line %d: Bad yes/no/ask argument.", filename, linenum); | ||
334 | if (*activep && *intptr == -1) | ||
335 | *intptr = value; | ||
336 | break; | ||
337 | |||
338 | case oCompression: | ||
339 | intptr = &options->compression; | ||
340 | goto parse_flag; | ||
341 | |||
342 | case oKeepAlives: | ||
343 | intptr = &options->keepalives; | ||
344 | goto parse_flag; | ||
345 | |||
346 | case oNumberOfPasswordPrompts: | ||
347 | intptr = &options->number_of_password_prompts; | ||
348 | goto parse_int; | ||
349 | |||
350 | case oTISAuthentication: | ||
351 | cp = strtok(NULL, WHITESPACE); | ||
352 | if (cp != 0 && (strcmp(cp, "yes") == 0 || strcmp(cp, "true") == 0)) | ||
353 | fprintf(stderr, | ||
354 | "%.99s line %d: Warning, TIS is not supported.\n", | ||
355 | filename, | ||
356 | linenum); | ||
357 | break; | ||
358 | |||
359 | case oCompressionLevel: | ||
360 | intptr = &options->compression_level; | ||
361 | goto parse_int; | ||
362 | |||
363 | case oIdentityFile: | ||
364 | cp = strtok(NULL, WHITESPACE); | ||
365 | if (!cp) | ||
366 | fatal("%.200s line %d: Missing argument.", filename, linenum); | ||
367 | if (*activep) | ||
368 | { | ||
369 | if (options->num_identity_files >= SSH_MAX_IDENTITY_FILES) | ||
370 | fatal("%.200s line %d: Too many identity files specified (max %d).", | ||
371 | filename, linenum, SSH_MAX_IDENTITY_FILES); | ||
372 | options->identity_files[options->num_identity_files++] = xstrdup(cp); | ||
373 | } | ||
374 | break; | ||
375 | |||
376 | case oUser: | ||
377 | charptr = &options->user; | ||
378 | parse_string: | ||
379 | cp = strtok(NULL, WHITESPACE); | ||
380 | if (!cp) | ||
381 | fatal("%.200s line %d: Missing argument.", filename, linenum); | ||
382 | if (*activep && *charptr == NULL) | ||
383 | *charptr = xstrdup(cp); | ||
384 | break; | ||
385 | |||
386 | case oGlobalKnownHostsFile: | ||
387 | charptr = &options->system_hostfile; | ||
388 | goto parse_string; | ||
389 | |||
390 | case oUserKnownHostsFile: | ||
391 | charptr = &options->user_hostfile; | ||
392 | goto parse_string; | ||
393 | |||
394 | case oHostName: | ||
395 | charptr = &options->hostname; | ||
396 | goto parse_string; | ||
397 | |||
398 | case oProxyCommand: | ||
399 | charptr = &options->proxy_command; | ||
400 | string = xstrdup(""); | ||
401 | while ((cp = strtok(NULL, WHITESPACE)) != NULL) | ||
402 | { | ||
403 | string = xrealloc(string, strlen(string) + strlen(cp) + 2); | ||
404 | strcat(string, " "); | ||
405 | strcat(string, cp); | ||
406 | } | ||
407 | if (*activep && *charptr == NULL) | ||
408 | *charptr = string; | ||
409 | else | ||
410 | xfree(string); | ||
411 | return; | ||
412 | |||
413 | case oPort: | ||
414 | intptr = &options->port; | ||
415 | parse_int: | ||
416 | cp = strtok(NULL, WHITESPACE); | ||
417 | if (!cp) | ||
418 | fatal("%.200s line %d: Missing argument.", filename, linenum); | ||
419 | if (cp[0] < '0' || cp[0] > '9') | ||
420 | fatal("%.200s line %d: Bad number.", filename, linenum); | ||
421 | #if 0 | ||
422 | value = atoi(cp); | ||
423 | #else | ||
424 | { | ||
425 | char *ptr; | ||
426 | value = strtol(cp, &ptr, 0); /* Octal, decimal, or hex format? */ | ||
427 | if (cp == ptr) | ||
428 | fatal("%.200s line %d: Bad number.", filename, linenum); | ||
429 | } | ||
430 | #endif | ||
431 | if (*activep && *intptr == -1) | ||
432 | *intptr = value; | ||
433 | break; | ||
434 | |||
435 | case oConnectionAttempts: | ||
436 | intptr = &options->connection_attempts; | ||
437 | goto parse_int; | ||
438 | |||
439 | case oCipher: | ||
440 | intptr = &options->cipher; | ||
441 | cp = strtok(NULL, WHITESPACE); | ||
442 | value = cipher_number(cp); | ||
443 | if (value == -1) | ||
444 | fatal("%.200s line %d: Bad cipher.", filename, linenum); | ||
445 | if (*activep && *intptr == -1) | ||
446 | *intptr = value; | ||
447 | break; | ||
448 | |||
449 | case oRemoteForward: | ||
450 | cp = strtok(NULL, WHITESPACE); | ||
451 | if (!cp) | ||
452 | fatal("%.200s line %d: Missing argument.", filename, linenum); | ||
453 | if (cp[0] < '0' || cp[0] > '9') | ||
454 | fatal("%.200s line %d: Badly formatted port number.", | ||
455 | filename, linenum); | ||
456 | fwd_port = atoi(cp); | ||
457 | cp = strtok(NULL, WHITESPACE); | ||
458 | if (!cp) | ||
459 | fatal("%.200s line %d: Missing second argument.", | ||
460 | filename, linenum); | ||
461 | if (sscanf(cp, "%255[^:]:%d", buf, &fwd_host_port) != 2) | ||
462 | fatal("%.200s line %d: Badly formatted host:port.", | ||
463 | filename, linenum); | ||
464 | if (*activep) | ||
465 | add_remote_forward(options, fwd_port, buf, fwd_host_port); | ||
466 | break; | ||
467 | |||
468 | case oLocalForward: | ||
469 | cp = strtok(NULL, WHITESPACE); | ||
470 | if (!cp) | ||
471 | fatal("%.200s line %d: Missing argument.", filename, linenum); | ||
472 | if (cp[0] < '0' || cp[0] > '9') | ||
473 | fatal("%.200s line %d: Badly formatted port number.", | ||
474 | filename, linenum); | ||
475 | fwd_port = atoi(cp); | ||
476 | cp = strtok(NULL, WHITESPACE); | ||
477 | if (!cp) | ||
478 | fatal("%.200s line %d: Missing second argument.", | ||
479 | filename, linenum); | ||
480 | if (sscanf(cp, "%255[^:]:%d", buf, &fwd_host_port) != 2) | ||
481 | fatal("%.200s line %d: Badly formatted host:port.", | ||
482 | filename, linenum); | ||
483 | if (*activep) | ||
484 | add_local_forward(options, fwd_port, buf, fwd_host_port); | ||
485 | break; | ||
486 | |||
487 | case oHost: | ||
488 | *activep = 0; | ||
489 | while ((cp = strtok(NULL, WHITESPACE)) != NULL) | ||
490 | if (match_pattern(host, cp)) | ||
491 | { | ||
492 | debug("Applying options for %.100s", cp); | ||
493 | *activep = 1; | ||
494 | break; | ||
495 | } | ||
496 | /* Avoid garbage check below, as strtok already returned NULL. */ | ||
497 | return; | ||
498 | |||
499 | case oEscapeChar: | ||
500 | intptr = &options->escape_char; | ||
501 | cp = strtok(NULL, WHITESPACE); | ||
502 | if (!cp) | ||
503 | fatal("%.200s line %d: Missing argument.", filename, linenum); | ||
504 | if (cp[0] == '^' && cp[2] == 0 && | ||
505 | (unsigned char)cp[1] >= 64 && (unsigned char)cp[1] < 128) | ||
506 | value = (unsigned char)cp[1] & 31; | ||
507 | else | ||
508 | if (strlen(cp) == 1) | ||
509 | value = (unsigned char)cp[0]; | ||
510 | else | ||
511 | if (strcmp(cp, "none") == 0) | ||
512 | value = -2; | ||
513 | else | ||
514 | { | ||
515 | fatal("%.200s line %d: Bad escape character.", | ||
516 | filename, linenum); | ||
517 | /*NOTREACHED*/ | ||
518 | value = 0; /* Avoid compiler warning. */ | ||
519 | } | ||
520 | if (*activep && *intptr == -1) | ||
521 | *intptr = value; | ||
522 | break; | ||
523 | |||
524 | default: | ||
525 | fatal("parse_config_file: Unimplemented opcode %d", opcode); | ||
526 | } | ||
527 | |||
528 | /* Check that there is no garbage at end of line. */ | ||
529 | if (strtok(NULL, WHITESPACE) != NULL) | ||
530 | fatal("%.200s line %d: garbage at end of line.", | ||
531 | filename, linenum); | ||
532 | } | ||
533 | |||
534 | |||
535 | /* Reads the config file and modifies the options accordingly. Options should | ||
536 | already be initialized before this call. This never returns if there | ||
537 | is an error. If the file does not exist, this returns immediately. */ | ||
538 | |||
539 | void read_config_file(const char *filename, const char *host, Options *options) | ||
540 | { | ||
541 | FILE *f; | ||
542 | char line[1024]; | ||
543 | int active, linenum; | ||
544 | |||
545 | /* Open the file. */ | ||
546 | f = fopen(filename, "r"); | ||
547 | if (!f) | ||
548 | return; | ||
549 | |||
550 | debug("Reading configuration data %.200s", filename); | ||
551 | |||
552 | /* Mark that we are now processing the options. This flag is turned on/off | ||
553 | by Host specifications. */ | ||
554 | active = 1; | ||
555 | linenum = 0; | ||
556 | while (fgets(line, sizeof(line), f)) | ||
557 | { | ||
558 | /* Update line number counter. */ | ||
559 | linenum++; | ||
560 | |||
561 | process_config_line(options, host, line, filename, linenum, &active); | ||
562 | } | ||
563 | fclose(f); | ||
564 | } | ||
565 | |||
566 | /* Initializes options to special values that indicate that they have not | ||
567 | yet been set. Read_config_file will only set options with this value. | ||
568 | Options are processed in the following order: command line, user config | ||
569 | file, system config file. Last, fill_default_options is called. */ | ||
570 | |||
571 | void initialize_options(Options *options) | ||
572 | { | ||
573 | memset(options, 'X', sizeof(*options)); | ||
574 | options->forward_agent = -1; | ||
575 | options->forward_x11 = -1; | ||
576 | options->gateway_ports = -1; | ||
577 | options->use_privileged_port = -1; | ||
578 | options->rhosts_authentication = -1; | ||
579 | options->rsa_authentication = -1; | ||
580 | #ifdef KRB4 | ||
581 | options->kerberos_authentication = -1; | ||
582 | #endif | ||
583 | #ifdef AFS | ||
584 | options->kerberos_tgt_passing = -1; | ||
585 | options->afs_token_passing = -1; | ||
586 | #endif | ||
587 | options->password_authentication = -1; | ||
588 | options->rhosts_rsa_authentication = -1; | ||
589 | options->fallback_to_rsh = -1; | ||
590 | options->use_rsh = -1; | ||
591 | options->batch_mode = -1; | ||
592 | options->check_host_ip = -1; | ||
593 | options->strict_host_key_checking = -1; | ||
594 | options->compression = -1; | ||
595 | options->keepalives = -1; | ||
596 | options->compression_level = -1; | ||
597 | options->port = -1; | ||
598 | options->connection_attempts = -1; | ||
599 | options->number_of_password_prompts = -1; | ||
600 | options->cipher = -1; | ||
601 | options->num_identity_files = 0; | ||
602 | options->hostname = NULL; | ||
603 | options->proxy_command = NULL; | ||
604 | options->user = NULL; | ||
605 | options->escape_char = -1; | ||
606 | options->system_hostfile = NULL; | ||
607 | options->user_hostfile = NULL; | ||
608 | options->num_local_forwards = 0; | ||
609 | options->num_remote_forwards = 0; | ||
610 | } | ||
611 | |||
612 | /* Called after processing other sources of option data, this fills those | ||
613 | options for which no value has been specified with their default values. */ | ||
614 | |||
615 | void fill_default_options(Options *options) | ||
616 | { | ||
617 | if (options->forward_agent == -1) | ||
618 | options->forward_agent = 1; | ||
619 | if (options->forward_x11 == -1) | ||
620 | options->forward_x11 = 1; | ||
621 | if (options->gateway_ports == -1) | ||
622 | options->gateway_ports = 0; | ||
623 | if (options->use_privileged_port == -1) | ||
624 | options->use_privileged_port = 1; | ||
625 | if (options->rhosts_authentication == -1) | ||
626 | options->rhosts_authentication = 1; | ||
627 | if (options->rsa_authentication == -1) | ||
628 | options->rsa_authentication = 1; | ||
629 | #ifdef KRB4 | ||
630 | if (options->kerberos_authentication == -1) | ||
631 | options->kerberos_authentication = 1; | ||
632 | #endif /* KRB4 */ | ||
633 | #ifdef AFS | ||
634 | if (options->kerberos_tgt_passing == -1) | ||
635 | options->kerberos_tgt_passing = 1; | ||
636 | if (options->afs_token_passing == -1) | ||
637 | options->afs_token_passing = 1; | ||
638 | #endif /* AFS */ | ||
639 | if (options->password_authentication == -1) | ||
640 | options->password_authentication = 1; | ||
641 | if (options->rhosts_rsa_authentication == -1) | ||
642 | options->rhosts_rsa_authentication = 1; | ||
643 | if (options->fallback_to_rsh == -1) | ||
644 | options->fallback_to_rsh = 1; | ||
645 | if (options->use_rsh == -1) | ||
646 | options->use_rsh = 0; | ||
647 | if (options->batch_mode == -1) | ||
648 | options->batch_mode = 0; | ||
649 | if (options->check_host_ip == -1) | ||
650 | options->check_host_ip = 1; | ||
651 | if (options->strict_host_key_checking == -1) | ||
652 | options->strict_host_key_checking = 2; /* 2 is default */ | ||
653 | if (options->compression == -1) | ||
654 | options->compression = 0; | ||
655 | if (options->keepalives == -1) | ||
656 | options->keepalives = 1; | ||
657 | if (options->compression_level == -1) | ||
658 | options->compression_level = 6; | ||
659 | if (options->port == -1) | ||
660 | options->port = 0; /* Filled in ssh_connect. */ | ||
661 | if (options->connection_attempts == -1) | ||
662 | options->connection_attempts = 4; | ||
663 | if (options->number_of_password_prompts == -1) | ||
664 | options->number_of_password_prompts = 3; | ||
665 | if (options->cipher == -1) | ||
666 | options->cipher = SSH_CIPHER_NOT_SET; /* Selected in ssh_login(). */ | ||
667 | if (options->num_identity_files == 0) | ||
668 | { | ||
669 | options->identity_files[0] = | ||
670 | xmalloc(2 + strlen(SSH_CLIENT_IDENTITY) + 1); | ||
671 | sprintf(options->identity_files[0], "~/%.100s", SSH_CLIENT_IDENTITY); | ||
672 | options->num_identity_files = 1; | ||
673 | } | ||
674 | if (options->escape_char == -1) | ||
675 | options->escape_char = '~'; | ||
676 | if (options->system_hostfile == NULL) | ||
677 | options->system_hostfile = SSH_SYSTEM_HOSTFILE; | ||
678 | if (options->user_hostfile == NULL) | ||
679 | options->user_hostfile = SSH_USER_HOSTFILE; | ||
680 | /* options->proxy_command should not be set by default */ | ||
681 | /* options->user will be set in the main program if appropriate */ | ||
682 | /* options->hostname will be set in the main program if appropriate */ | ||
683 | } | ||
684 | |||