Annotation of src/usr.bin/ssh/servconf.c, Revision 1.24
1.1 deraadt 1: /*
2:
3: servconf.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: Mon Aug 21 15:48:58 1995 ylo
11:
12: */
13:
14: #include "includes.h"
1.24 ! markus 15: RCSID("$Id: servconf.c,v 1.23 1999/11/19 16:04:17 markus Exp $");
1.1 deraadt 16:
17: #include "ssh.h"
18: #include "servconf.h"
19: #include "xmalloc.h"
20:
21: /* Initializes the server options to their default values. */
22:
23: void initialize_server_options(ServerOptions *options)
24: {
25: memset(options, 0, sizeof(*options));
26: options->port = -1;
1.3 deraadt 27: options->listen_addr.s_addr = htonl(INADDR_ANY);
1.1 deraadt 28: options->host_key_file = NULL;
29: options->server_key_bits = -1;
30: options->login_grace_time = -1;
31: options->key_regeneration_time = -1;
32: options->permit_root_login = -1;
33: options->ignore_rhosts = -1;
1.21 markus 34: options->ignore_user_known_hosts = -1;
1.1 deraadt 35: options->print_motd = -1;
1.11 markus 36: options->check_mail = -1;
1.1 deraadt 37: options->x11_forwarding = -1;
1.2 deraadt 38: options->x11_display_offset = -1;
1.1 deraadt 39: options->strict_modes = -1;
40: options->keepalives = -1;
41: options->log_facility = (SyslogFacility)-1;
1.20 markus 42: options->log_level = (LogLevel)-1;
1.1 deraadt 43: options->rhosts_authentication = -1;
44: options->rhosts_rsa_authentication = -1;
45: options->rsa_authentication = -1;
46: #ifdef KRB4
47: options->kerberos_authentication = -1;
48: options->kerberos_or_local_passwd = -1;
49: options->kerberos_ticket_cleanup = -1;
50: #endif
1.4 dugsong 51: #ifdef AFS
1.1 deraadt 52: options->kerberos_tgt_passing = -1;
53: options->afs_token_passing = -1;
54: #endif
55: options->password_authentication = -1;
1.10 markus 56: #ifdef SKEY
57: options->skey_authentication = -1;
58: #endif
1.1 deraadt 59: options->permit_empty_passwd = -1;
1.12 markus 60: options->use_login = -1;
1.13 markus 61: options->num_allow_users = 0;
62: options->num_deny_users = 0;
63: options->num_allow_groups = 0;
64: options->num_deny_groups = 0;
1.1 deraadt 65: }
66:
67: void fill_default_server_options(ServerOptions *options)
68: {
69: if (options->port == -1)
70: {
71: struct servent *sp;
72:
73: sp = getservbyname(SSH_SERVICE_NAME, "tcp");
74: if (sp)
75: options->port = ntohs(sp->s_port);
76: else
77: options->port = SSH_DEFAULT_PORT;
78: endservent();
79: }
80: if (options->host_key_file == NULL)
81: options->host_key_file = HOST_KEY_FILE;
82: if (options->server_key_bits == -1)
83: options->server_key_bits = 768;
84: if (options->login_grace_time == -1)
85: options->login_grace_time = 600;
86: if (options->key_regeneration_time == -1)
87: options->key_regeneration_time = 3600;
88: if (options->permit_root_login == -1)
1.15 markus 89: options->permit_root_login = 1; /* yes */
1.1 deraadt 90: if (options->ignore_rhosts == -1)
91: options->ignore_rhosts = 0;
1.21 markus 92: if (options->ignore_user_known_hosts == -1)
93: options->ignore_user_known_hosts = 0;
1.11 markus 94: if (options->check_mail == -1)
95: options->check_mail = 0;
1.1 deraadt 96: if (options->print_motd == -1)
97: options->print_motd = 1;
98: if (options->x11_forwarding == -1)
99: options->x11_forwarding = 1;
1.2 deraadt 100: if (options->x11_display_offset == -1)
101: options->x11_display_offset = 1;
1.1 deraadt 102: if (options->strict_modes == -1)
103: options->strict_modes = 1;
104: if (options->keepalives == -1)
105: options->keepalives = 1;
106: if (options->log_facility == (SyslogFacility)(-1))
1.19 markus 107: options->log_facility = SYSLOG_FACILITY_AUTH;
1.20 markus 108: if (options->log_level == (LogLevel)(-1))
109: options->log_level = SYSLOG_LEVEL_INFO;
1.1 deraadt 110: if (options->rhosts_authentication == -1)
111: options->rhosts_authentication = 0;
112: if (options->rhosts_rsa_authentication == -1)
113: options->rhosts_rsa_authentication = 1;
114: if (options->rsa_authentication == -1)
115: options->rsa_authentication = 1;
116: #ifdef KRB4
117: if (options->kerberos_authentication == -1)
1.5 dugsong 118: options->kerberos_authentication = (access(KEYFILE, R_OK) == 0);
1.1 deraadt 119: if (options->kerberos_or_local_passwd == -1)
1.18 dugsong 120: options->kerberos_or_local_passwd = 1;
1.1 deraadt 121: if (options->kerberos_ticket_cleanup == -1)
122: options->kerberos_ticket_cleanup = 1;
1.4 dugsong 123: #endif /* KRB4 */
124: #ifdef AFS
1.1 deraadt 125: if (options->kerberos_tgt_passing == -1)
126: options->kerberos_tgt_passing = 0;
127: if (options->afs_token_passing == -1)
1.5 dugsong 128: options->afs_token_passing = k_hasafs();
1.4 dugsong 129: #endif /* AFS */
1.1 deraadt 130: if (options->password_authentication == -1)
131: options->password_authentication = 1;
1.10 markus 132: #ifdef SKEY
133: if (options->skey_authentication == -1)
134: options->skey_authentication = 1;
135: #endif
1.1 deraadt 136: if (options->permit_empty_passwd == -1)
1.10 markus 137: options->permit_empty_passwd = 1;
1.12 markus 138: if (options->use_login == -1)
139: options->use_login = 0;
1.1 deraadt 140: }
141:
142: #define WHITESPACE " \t\r\n"
143:
144: /* Keyword tokens. */
145: typedef enum
146: {
1.22 markus 147: sBadOption, /* == unknown option */
1.1 deraadt 148: sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
1.20 markus 149: sPermitRootLogin, sLogFacility, sLogLevel,
1.1 deraadt 150: sRhostsAuthentication, sRhostsRSAAuthentication, sRSAAuthentication,
151: #ifdef KRB4
1.4 dugsong 152: sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
1.1 deraadt 153: #endif
154: #ifdef AFS
1.4 dugsong 155: sKerberosTgtPassing, sAFSTokenPassing,
1.1 deraadt 156: #endif
1.10 markus 157: #ifdef SKEY
158: sSkeyAuthentication,
159: #endif
1.17 dugsong 160: sPasswordAuthentication, sListenAddress,
1.2 deraadt 161: sPrintMotd, sIgnoreRhosts, sX11Forwarding, sX11DisplayOffset,
1.12 markus 162: sStrictModes, sEmptyPasswd, sRandomSeedFile, sKeepAlives, sCheckMail,
1.21 markus 163: sUseLogin, sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
164: sIgnoreUserKnownHosts
1.1 deraadt 165: } ServerOpCodes;
166:
167: /* Textual representation of the tokens. */
168: static struct
169: {
170: const char *name;
171: ServerOpCodes opcode;
172: } keywords[] =
173: {
174: { "port", sPort },
175: { "hostkey", sHostKeyFile },
176: { "serverkeybits", sServerKeyBits },
177: { "logingracetime", sLoginGraceTime },
178: { "keyregenerationinterval", sKeyRegenerationTime },
179: { "permitrootlogin", sPermitRootLogin },
180: { "syslogfacility", sLogFacility },
1.20 markus 181: { "loglevel", sLogLevel },
1.1 deraadt 182: { "rhostsauthentication", sRhostsAuthentication },
183: { "rhostsrsaauthentication", sRhostsRSAAuthentication },
184: { "rsaauthentication", sRSAAuthentication },
185: #ifdef KRB4
186: { "kerberosauthentication", sKerberosAuthentication },
187: { "kerberosorlocalpasswd", sKerberosOrLocalPasswd },
188: { "kerberosticketcleanup", sKerberosTicketCleanup },
189: #endif
1.4 dugsong 190: #ifdef AFS
1.1 deraadt 191: { "kerberostgtpassing", sKerberosTgtPassing },
192: { "afstokenpassing", sAFSTokenPassing },
193: #endif
194: { "passwordauthentication", sPasswordAuthentication },
1.10 markus 195: #ifdef SKEY
196: { "skeyauthentication", sSkeyAuthentication },
197: #endif
1.11 markus 198: { "checkmail", sCheckMail },
1.1 deraadt 199: { "listenaddress", sListenAddress },
200: { "printmotd", sPrintMotd },
201: { "ignorerhosts", sIgnoreRhosts },
1.21 markus 202: { "ignoreuserknownhosts", sIgnoreUserKnownHosts },
1.1 deraadt 203: { "x11forwarding", sX11Forwarding },
1.2 deraadt 204: { "x11displayoffset", sX11DisplayOffset },
1.1 deraadt 205: { "strictmodes", sStrictModes },
206: { "permitemptypasswords", sEmptyPasswd },
1.12 markus 207: { "uselogin", sUseLogin },
1.1 deraadt 208: { "randomseed", sRandomSeedFile },
209: { "keepalive", sKeepAlives },
1.13 markus 210: { "allowusers", sAllowUsers },
211: { "denyusers", sDenyUsers },
212: { "allowgroups", sAllowGroups },
213: { "denygroups", sDenyGroups },
1.1 deraadt 214: { NULL, 0 }
215: };
216:
217: /* Returns the number of the token pointed to by cp of length len.
218: Never returns if the token is not known. */
219:
220: static ServerOpCodes parse_token(const char *cp, const char *filename,
221: int linenum)
222: {
223: unsigned int i;
224:
225: for (i = 0; keywords[i].name; i++)
226: if (strcmp(cp, keywords[i].name) == 0)
227: return keywords[i].opcode;
228:
1.22 markus 229: fprintf(stderr, "%s: line %d: Bad configuration option: %s\n",
1.1 deraadt 230: filename, linenum, cp);
1.22 markus 231: return sBadOption;
1.1 deraadt 232: }
233:
234: /* Reads the server configuration file. */
235:
236: void read_server_config(ServerOptions *options, const char *filename)
237: {
238: FILE *f;
239: char line[1024];
240: char *cp, **charptr;
1.24 ! markus 241: int linenum, *intptr, value;
1.22 markus 242: int bad_options = 0;
1.1 deraadt 243: ServerOpCodes opcode;
244:
245: f = fopen(filename, "r");
246: if (!f)
247: {
248: perror(filename);
1.16 markus 249: exit(1);
1.1 deraadt 250: }
251:
252: linenum = 0;
253: while (fgets(line, sizeof(line), f))
254: {
255: linenum++;
256: cp = line + strspn(line, WHITESPACE);
257: if (!*cp || *cp == '#')
258: continue;
259: cp = strtok(cp, WHITESPACE);
260: {
261: char *t = cp;
262: for (; *t != 0; t++)
263: if ('A' <= *t && *t <= 'Z')
264: *t = *t - 'A' + 'a'; /* tolower */
265:
266: }
267: opcode = parse_token(cp, filename, linenum);
268: switch (opcode)
269: {
1.22 markus 270: case sBadOption:
271: bad_options++;
272: continue;
1.1 deraadt 273: case sPort:
274: intptr = &options->port;
275: parse_int:
276: cp = strtok(NULL, WHITESPACE);
277: if (!cp)
278: {
279: fprintf(stderr, "%s line %d: missing integer value.\n",
280: filename, linenum);
281: exit(1);
282: }
283: value = atoi(cp);
284: if (*intptr == -1)
285: *intptr = value;
286: break;
287:
288: case sServerKeyBits:
289: intptr = &options->server_key_bits;
290: goto parse_int;
291:
292: case sLoginGraceTime:
293: intptr = &options->login_grace_time;
294: goto parse_int;
295:
296: case sKeyRegenerationTime:
297: intptr = &options->key_regeneration_time;
298: goto parse_int;
299:
300: case sListenAddress:
301: cp = strtok(NULL, WHITESPACE);
302: if (!cp)
303: {
304: fprintf(stderr, "%s line %d: missing inet addr.\n",
305: filename, linenum);
306: exit(1);
307: }
308: options->listen_addr.s_addr = inet_addr(cp);
309: break;
310:
311: case sHostKeyFile:
312: charptr = &options->host_key_file;
313: cp = strtok(NULL, WHITESPACE);
314: if (!cp)
315: {
316: fprintf(stderr, "%s line %d: missing file name.\n",
317: filename, linenum);
318: exit(1);
319: }
320: if (*charptr == NULL)
321: *charptr = tilde_expand_filename(cp, getuid());
322: break;
323:
324: case sRandomSeedFile:
1.8 deraadt 325: fprintf(stderr, "%s line %d: \"randomseed\" option is obsolete.\n",
1.7 provos 326: filename, linenum);
327: cp = strtok(NULL, WHITESPACE);
328: break;
1.1 deraadt 329:
330: case sPermitRootLogin:
331: intptr = &options->permit_root_login;
1.15 markus 332: cp = strtok(NULL, WHITESPACE);
333: if (!cp)
334: {
335: fprintf(stderr, "%s line %d: missing yes/without-password/no argument.\n",
336: filename, linenum);
337: exit(1);
338: }
339: if (strcmp(cp, "without-password") == 0)
340: value = 2;
341: else if (strcmp(cp, "yes") == 0)
342: value = 1;
343: else if (strcmp(cp, "no") == 0)
344: value = 0;
345: else
346: {
347: fprintf(stderr, "%s line %d: Bad yes/without-password/no argument: %s\n",
348: filename, linenum, cp);
349: exit(1);
350: }
351: if (*intptr == -1)
352: *intptr = value;
353: break;
354:
355: case sIgnoreRhosts:
356: intptr = &options->ignore_rhosts;
1.1 deraadt 357: parse_flag:
358: cp = strtok(NULL, WHITESPACE);
359: if (!cp)
360: {
361: fprintf(stderr, "%s line %d: missing yes/no argument.\n",
362: filename, linenum);
363: exit(1);
364: }
365: if (strcmp(cp, "yes") == 0)
366: value = 1;
367: else
368: if (strcmp(cp, "no") == 0)
369: value = 0;
370: else
371: {
372: fprintf(stderr, "%s line %d: Bad yes/no argument: %s\n",
373: filename, linenum, cp);
374: exit(1);
375: }
376: if (*intptr == -1)
377: *intptr = value;
378: break;
1.21 markus 379:
380: case sIgnoreUserKnownHosts:
381: intptr = &options->ignore_user_known_hosts;
382: goto parse_int;
383:
1.1 deraadt 384: case sRhostsAuthentication:
385: intptr = &options->rhosts_authentication;
386: goto parse_flag;
387:
388: case sRhostsRSAAuthentication:
389: intptr = &options->rhosts_rsa_authentication;
390: goto parse_flag;
391:
392: case sRSAAuthentication:
393: intptr = &options->rsa_authentication;
394: goto parse_flag;
395:
396: #ifdef KRB4
397: case sKerberosAuthentication:
398: intptr = &options->kerberos_authentication;
399: goto parse_flag;
400:
401: case sKerberosOrLocalPasswd:
402: intptr = &options->kerberos_or_local_passwd;
403: goto parse_flag;
404:
405: case sKerberosTicketCleanup:
406: intptr = &options->kerberos_ticket_cleanup;
407: goto parse_flag;
408: #endif
409:
1.4 dugsong 410: #ifdef AFS
1.1 deraadt 411: case sKerberosTgtPassing:
412: intptr = &options->kerberos_tgt_passing;
413: goto parse_flag;
414:
415: case sAFSTokenPassing:
416: intptr = &options->afs_token_passing;
417: goto parse_flag;
418: #endif
419:
420: case sPasswordAuthentication:
421: intptr = &options->password_authentication;
422: goto parse_flag;
1.11 markus 423:
424: case sCheckMail:
425: intptr = &options->check_mail;
426: goto parse_flag;
1.10 markus 427:
428: #ifdef SKEY
429: case sSkeyAuthentication:
430: intptr = &options->skey_authentication;
431: goto parse_flag;
432: #endif
1.1 deraadt 433:
434: case sPrintMotd:
435: intptr = &options->print_motd;
436: goto parse_flag;
437:
438: case sX11Forwarding:
439: intptr = &options->x11_forwarding;
440: goto parse_flag;
1.2 deraadt 441:
442: case sX11DisplayOffset:
443: intptr = &options->x11_display_offset;
444: goto parse_int;
1.1 deraadt 445:
446: case sStrictModes:
447: intptr = &options->strict_modes;
448: goto parse_flag;
449:
450: case sKeepAlives:
451: intptr = &options->keepalives;
452: goto parse_flag;
453:
454: case sEmptyPasswd:
455: intptr = &options->permit_empty_passwd;
456: goto parse_flag;
1.12 markus 457:
458: case sUseLogin:
459: intptr = &options->use_login;
1.14 markus 460: goto parse_flag;
461:
1.1 deraadt 462: case sLogFacility:
1.23 markus 463: intptr = (int *)&options->log_facility;
1.1 deraadt 464: cp = strtok(NULL, WHITESPACE);
1.23 markus 465: value = log_facility_number(cp);
466: if (value == (SyslogFacility)-1)
467: fatal("%.200s line %d: unsupported log facility '%s'\n",
468: filename, linenum, cp ? cp : "<NONE>");
469: if (*intptr == -1)
470: *intptr = (SyslogFacility)value;
1.20 markus 471: break;
472:
473: case sLogLevel:
1.23 markus 474: intptr = (int *)&options->log_level;
1.20 markus 475: cp = strtok(NULL, WHITESPACE);
1.23 markus 476: value = log_level_number(cp);
477: if (value == (LogLevel)-1)
478: fatal("%.200s line %d: unsupported log level '%s'\n",
479: filename, linenum, cp ? cp : "<NONE>");
480: if (*intptr == -1)
481: *intptr = (LogLevel)value;
1.1 deraadt 482: break;
483:
1.13 markus 484: case sAllowUsers:
485: while ((cp = strtok(NULL, WHITESPACE)))
486: {
487: if (options->num_allow_users >= MAX_ALLOW_USERS)
488: {
489: fprintf(stderr, "%s line %d: too many allow users.\n",
490: filename, linenum);
491: exit(1);
492: }
493: options->allow_users[options->num_allow_users++] = xstrdup(cp);
494: }
495: break;
496:
497: case sDenyUsers:
498: while ((cp = strtok(NULL, WHITESPACE)))
499: {
500: if (options->num_deny_users >= MAX_DENY_USERS)
501: {
502: fprintf(stderr, "%s line %d: too many deny users.\n",
503: filename, linenum);
504: exit(1);
505: }
506: options->deny_users[options->num_deny_users++] = xstrdup(cp);
507: }
508: break;
509:
510: case sAllowGroups:
511: while ((cp = strtok(NULL, WHITESPACE)))
512: {
513: if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
514: {
515: fprintf(stderr, "%s line %d: too many allow groups.\n",
516: filename, linenum);
517: exit(1);
518: }
519: options->allow_groups[options->num_allow_groups++] = xstrdup(cp);
520: }
521: break;
522:
523: case sDenyGroups:
524: while ((cp = strtok(NULL, WHITESPACE)))
525: {
526: if (options->num_deny_groups >= MAX_DENY_GROUPS)
527: {
528: fprintf(stderr, "%s line %d: too many deny groups.\n",
529: filename, linenum);
530: exit(1);
531: }
532: options->deny_groups[options->num_deny_groups++] = xstrdup(cp);
1.1 deraadt 533: }
534: break;
535:
536: default:
537: fprintf(stderr, "%s line %d: Missing handler for opcode %s (%d)\n",
538: filename, linenum, cp, opcode);
539: exit(1);
540: }
541: if (strtok(NULL, WHITESPACE) != NULL)
542: {
543: fprintf(stderr, "%s line %d: garbage at end of line.\n",
544: filename, linenum);
545: exit(1);
546: }
547: }
548: fclose(f);
1.22 markus 549: if (bad_options > 0) {
550: fprintf(stderr, "%s: terminating, %d bad configuration options\n",
551: filename, bad_options);
552: exit(1);
553: }
1.1 deraadt 554: }