Import OpenSSH-5.8p1.
[dragonfly.git] / crypto / openssh / servconf.c
1 /* $OpenBSD: servconf.c,v 1.213 2010/11/13 23:27:50 djm Exp $ */
2 /*
3  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4  *                    All rights reserved
5  *
6  * As far as I am concerned, the code I have written for this software
7  * can be used freely for any purpose.  Any derived versions of this
8  * software must be clearly marked as such, and if the derived work is
9  * incompatible with the protocol description in the RFC file, it must be
10  * called by a name other than "ssh" or "Secure Shell".
11  */
12
13 #include "includes.h"
14
15 #include <sys/types.h>
16 #include <sys/socket.h>
17
18 #include <netinet/in.h>
19 #include <netinet/in_systm.h>
20 #include <netinet/ip.h>
21
22 #include <netdb.h>
23 #include <pwd.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <signal.h>
28 #include <unistd.h>
29 #include <stdarg.h>
30 #include <errno.h>
31
32 #include "openbsd-compat/sys-queue.h"
33 #include "xmalloc.h"
34 #include "ssh.h"
35 #include "log.h"
36 #include "buffer.h"
37 #include "servconf.h"
38 #include "compat.h"
39 #include "pathnames.h"
40 #include "misc.h"
41 #include "cipher.h"
42 #include "key.h"
43 #include "kex.h"
44 #include "mac.h"
45 #include "match.h"
46 #include "channels.h"
47 #include "groupaccess.h"
48
49 static void add_listen_addr(ServerOptions *, char *, int);
50 static void add_one_listen_addr(ServerOptions *, char *, int);
51
52 /* Use of privilege separation or not */
53 extern int use_privsep;
54 extern Buffer cfg;
55
56 /* Initializes the server options to their default values. */
57
58 void
59 initialize_server_options(ServerOptions *options)
60 {
61         memset(options, 0, sizeof(*options));
62
63         /* Portable-specific options */
64         options->use_pam = -1;
65
66         /* Standard Options */
67         options->num_ports = 0;
68         options->ports_from_cmdline = 0;
69         options->listen_addrs = NULL;
70         options->address_family = -1;
71         options->num_host_key_files = 0;
72         options->num_host_cert_files = 0;
73         options->pid_file = NULL;
74         options->server_key_bits = -1;
75         options->login_grace_time = -1;
76         options->key_regeneration_time = -1;
77         options->permit_root_login = PERMIT_NOT_SET;
78         options->ignore_rhosts = -1;
79         options->ignore_user_known_hosts = -1;
80         options->print_motd = -1;
81         options->print_lastlog = -1;
82         options->x11_forwarding = -1;
83         options->x11_display_offset = -1;
84         options->x11_use_localhost = -1;
85         options->xauth_location = NULL;
86         options->strict_modes = -1;
87         options->tcp_keep_alive = -1;
88         options->log_facility = SYSLOG_FACILITY_NOT_SET;
89         options->log_level = SYSLOG_LEVEL_NOT_SET;
90         options->rhosts_rsa_authentication = -1;
91         options->hostbased_authentication = -1;
92         options->hostbased_uses_name_from_packet_only = -1;
93         options->rsa_authentication = -1;
94         options->pubkey_authentication = -1;
95         options->kerberos_authentication = -1;
96         options->kerberos_or_local_passwd = -1;
97         options->kerberos_ticket_cleanup = -1;
98         options->kerberos_get_afs_token = -1;
99         options->gss_authentication=-1;
100         options->gss_cleanup_creds = -1;
101         options->password_authentication = -1;
102         options->kbd_interactive_authentication = -1;
103         options->challenge_response_authentication = -1;
104         options->permit_empty_passwd = -1;
105         options->permit_user_env = -1;
106         options->use_login = -1;
107         options->compression = -1;
108         options->allow_tcp_forwarding = -1;
109         options->allow_agent_forwarding = -1;
110         options->num_allow_users = 0;
111         options->num_deny_users = 0;
112         options->num_allow_groups = 0;
113         options->num_deny_groups = 0;
114         options->ciphers = NULL;
115         options->macs = NULL;
116         options->kex_algorithms = NULL;
117         options->protocol = SSH_PROTO_UNKNOWN;
118         options->gateway_ports = -1;
119         options->num_subsystems = 0;
120         options->max_startups_begin = -1;
121         options->max_startups_rate = -1;
122         options->max_startups = -1;
123         options->max_authtries = -1;
124         options->max_sessions = -1;
125         options->banner = NULL;
126         options->use_dns = -1;
127         options->client_alive_interval = -1;
128         options->client_alive_count_max = -1;
129         options->authorized_keys_file = NULL;
130         options->authorized_keys_file2 = NULL;
131         options->num_accept_env = 0;
132         options->permit_tun = -1;
133         options->num_permitted_opens = -1;
134         options->adm_forced_command = NULL;
135         options->chroot_directory = NULL;
136         options->zero_knowledge_password_authentication = -1;
137         options->revoked_keys_file = NULL;
138         options->trusted_user_ca_keys = NULL;
139         options->authorized_principals_file = NULL;
140         options->ip_qos_interactive = -1;
141         options->ip_qos_bulk = -1;
142 }
143
144 void
145 fill_default_server_options(ServerOptions *options)
146 {
147         /* Portable-specific options */
148         if (options->use_pam == -1)
149                 options->use_pam = 0;
150
151         /* Standard Options */
152         if (options->protocol == SSH_PROTO_UNKNOWN)
153                 options->protocol = SSH_PROTO_2;
154         if (options->num_host_key_files == 0) {
155                 /* fill default hostkeys for protocols */
156                 if (options->protocol & SSH_PROTO_1)
157                         options->host_key_files[options->num_host_key_files++] =
158                             _PATH_HOST_KEY_FILE;
159                 if (options->protocol & SSH_PROTO_2) {
160                         options->host_key_files[options->num_host_key_files++] =
161                             _PATH_HOST_RSA_KEY_FILE;
162                         options->host_key_files[options->num_host_key_files++] =
163                             _PATH_HOST_DSA_KEY_FILE;
164 #ifdef OPENSSL_HAS_ECC
165                         options->host_key_files[options->num_host_key_files++] =
166                             _PATH_HOST_ECDSA_KEY_FILE;
167 #endif
168                 }
169         }
170         /* No certificates by default */
171         if (options->num_ports == 0)
172                 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
173         if (options->listen_addrs == NULL)
174                 add_listen_addr(options, NULL, 0);
175         if (options->pid_file == NULL)
176                 options->pid_file = _PATH_SSH_DAEMON_PID_FILE;
177         if (options->server_key_bits == -1)
178                 options->server_key_bits = 1024;
179         if (options->login_grace_time == -1)
180                 options->login_grace_time = 120;
181         if (options->key_regeneration_time == -1)
182                 options->key_regeneration_time = 3600;
183         if (options->permit_root_login == PERMIT_NOT_SET)
184                 options->permit_root_login = PERMIT_YES;
185         if (options->ignore_rhosts == -1)
186                 options->ignore_rhosts = 1;
187         if (options->ignore_user_known_hosts == -1)
188                 options->ignore_user_known_hosts = 0;
189         if (options->print_motd == -1)
190                 options->print_motd = 1;
191         if (options->print_lastlog == -1)
192                 options->print_lastlog = 1;
193         if (options->x11_forwarding == -1)
194                 options->x11_forwarding = 0;
195         if (options->x11_display_offset == -1)
196                 options->x11_display_offset = 10;
197         if (options->x11_use_localhost == -1)
198                 options->x11_use_localhost = 1;
199         if (options->xauth_location == NULL)
200                 options->xauth_location = _PATH_XAUTH;
201         if (options->strict_modes == -1)
202                 options->strict_modes = 1;
203         if (options->tcp_keep_alive == -1)
204                 options->tcp_keep_alive = 1;
205         if (options->log_facility == SYSLOG_FACILITY_NOT_SET)
206                 options->log_facility = SYSLOG_FACILITY_AUTH;
207         if (options->log_level == SYSLOG_LEVEL_NOT_SET)
208                 options->log_level = SYSLOG_LEVEL_INFO;
209         if (options->rhosts_rsa_authentication == -1)
210                 options->rhosts_rsa_authentication = 0;
211         if (options->hostbased_authentication == -1)
212                 options->hostbased_authentication = 0;
213         if (options->hostbased_uses_name_from_packet_only == -1)
214                 options->hostbased_uses_name_from_packet_only = 0;
215         if (options->rsa_authentication == -1)
216                 options->rsa_authentication = 1;
217         if (options->pubkey_authentication == -1)
218                 options->pubkey_authentication = 1;
219         if (options->kerberos_authentication == -1)
220                 options->kerberos_authentication = 0;
221         if (options->kerberos_or_local_passwd == -1)
222                 options->kerberos_or_local_passwd = 1;
223         if (options->kerberos_ticket_cleanup == -1)
224                 options->kerberos_ticket_cleanup = 1;
225         if (options->kerberos_get_afs_token == -1)
226                 options->kerberos_get_afs_token = 0;
227         if (options->gss_authentication == -1)
228                 options->gss_authentication = 0;
229         if (options->gss_cleanup_creds == -1)
230                 options->gss_cleanup_creds = 1;
231         if (options->password_authentication == -1)
232                 options->password_authentication = 1;
233         if (options->kbd_interactive_authentication == -1)
234                 options->kbd_interactive_authentication = 0;
235         if (options->challenge_response_authentication == -1)
236                 options->challenge_response_authentication = 1;
237         if (options->permit_empty_passwd == -1)
238                 options->permit_empty_passwd = 0;
239         if (options->permit_user_env == -1)
240                 options->permit_user_env = 0;
241         if (options->use_login == -1)
242                 options->use_login = 0;
243         if (options->compression == -1)
244                 options->compression = COMP_DELAYED;
245         if (options->allow_tcp_forwarding == -1)
246                 options->allow_tcp_forwarding = 1;
247         if (options->allow_agent_forwarding == -1)
248                 options->allow_agent_forwarding = 1;
249         if (options->gateway_ports == -1)
250                 options->gateway_ports = 0;
251         if (options->max_startups == -1)
252                 options->max_startups = 10;
253         if (options->max_startups_rate == -1)
254                 options->max_startups_rate = 100;               /* 100% */
255         if (options->max_startups_begin == -1)
256                 options->max_startups_begin = options->max_startups;
257         if (options->max_authtries == -1)
258                 options->max_authtries = DEFAULT_AUTH_FAIL_MAX;
259         if (options->max_sessions == -1)
260                 options->max_sessions = DEFAULT_SESSIONS_MAX;
261         if (options->use_dns == -1)
262                 options->use_dns = 1;
263         if (options->client_alive_interval == -1)
264                 options->client_alive_interval = 0;
265         if (options->client_alive_count_max == -1)
266                 options->client_alive_count_max = 3;
267         if (options->authorized_keys_file2 == NULL) {
268                 /* authorized_keys_file2 falls back to authorized_keys_file */
269                 if (options->authorized_keys_file != NULL)
270                         options->authorized_keys_file2 = xstrdup(options->authorized_keys_file);
271                 else
272                         options->authorized_keys_file2 = xstrdup(_PATH_SSH_USER_PERMITTED_KEYS2);
273         }
274         if (options->authorized_keys_file == NULL)
275                 options->authorized_keys_file = xstrdup(_PATH_SSH_USER_PERMITTED_KEYS);
276         if (options->permit_tun == -1)
277                 options->permit_tun = SSH_TUNMODE_NO;
278         if (options->zero_knowledge_password_authentication == -1)
279                 options->zero_knowledge_password_authentication = 0;
280         if (options->ip_qos_interactive == -1)
281                 options->ip_qos_interactive = IPTOS_LOWDELAY;
282         if (options->ip_qos_bulk == -1)
283                 options->ip_qos_bulk = IPTOS_THROUGHPUT;
284
285         /* Turn privilege separation on by default */
286         if (use_privsep == -1)
287                 use_privsep = 1;
288
289 #ifndef HAVE_MMAP
290         if (use_privsep && options->compression == 1) {
291                 error("This platform does not support both privilege "
292                     "separation and compression");
293                 error("Compression disabled");
294                 options->compression = 0;
295         }
296 #endif
297
298 }
299
300 /* Keyword tokens. */
301 typedef enum {
302         sBadOption,             /* == unknown option */
303         /* Portable-specific options */
304         sUsePAM,
305         /* Standard Options */
306         sPort, sHostKeyFile, sServerKeyBits, sLoginGraceTime, sKeyRegenerationTime,
307         sPermitRootLogin, sLogFacility, sLogLevel,
308         sRhostsRSAAuthentication, sRSAAuthentication,
309         sKerberosAuthentication, sKerberosOrLocalPasswd, sKerberosTicketCleanup,
310         sKerberosGetAFSToken,
311         sKerberosTgtPassing, sChallengeResponseAuthentication,
312         sPasswordAuthentication, sKbdInteractiveAuthentication,
313         sListenAddress, sAddressFamily,
314         sPrintMotd, sPrintLastLog, sIgnoreRhosts,
315         sX11Forwarding, sX11DisplayOffset, sX11UseLocalhost,
316         sStrictModes, sEmptyPasswd, sTCPKeepAlive,
317         sPermitUserEnvironment, sUseLogin, sAllowTcpForwarding, sCompression,
318         sAllowUsers, sDenyUsers, sAllowGroups, sDenyGroups,
319         sIgnoreUserKnownHosts, sCiphers, sMacs, sProtocol, sPidFile,
320         sGatewayPorts, sPubkeyAuthentication, sXAuthLocation, sSubsystem,
321         sMaxStartups, sMaxAuthTries, sMaxSessions,
322         sBanner, sUseDNS, sHostbasedAuthentication,
323         sHostbasedUsesNameFromPacketOnly, sClientAliveInterval,
324         sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2,
325         sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel,
326         sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
327         sUsePrivilegeSeparation, sAllowAgentForwarding,
328         sZeroKnowledgePasswordAuthentication, sHostCertificate,
329         sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
330         sKexAlgorithms, sIPQoS,
331         sDeprecated, sUnsupported
332 } ServerOpCodes;
333
334 #define SSHCFG_GLOBAL   0x01    /* allowed in main section of sshd_config */
335 #define SSHCFG_MATCH    0x02    /* allowed inside a Match section */
336 #define SSHCFG_ALL      (SSHCFG_GLOBAL|SSHCFG_MATCH)
337
338 /* Textual representation of the tokens. */
339 static struct {
340         const char *name;
341         ServerOpCodes opcode;
342         u_int flags;
343 } keywords[] = {
344         /* Portable-specific options */
345 #ifdef USE_PAM
346         { "usepam", sUsePAM, SSHCFG_GLOBAL },
347 #else
348         { "usepam", sUnsupported, SSHCFG_GLOBAL },
349 #endif
350         { "pamauthenticationviakbdint", sDeprecated, SSHCFG_GLOBAL },
351         /* Standard Options */
352         { "port", sPort, SSHCFG_GLOBAL },
353         { "hostkey", sHostKeyFile, SSHCFG_GLOBAL },
354         { "hostdsakey", sHostKeyFile, SSHCFG_GLOBAL },          /* alias */
355         { "pidfile", sPidFile, SSHCFG_GLOBAL },
356         { "serverkeybits", sServerKeyBits, SSHCFG_GLOBAL },
357         { "logingracetime", sLoginGraceTime, SSHCFG_GLOBAL },
358         { "keyregenerationinterval", sKeyRegenerationTime, SSHCFG_GLOBAL },
359         { "permitrootlogin", sPermitRootLogin, SSHCFG_ALL },
360         { "syslogfacility", sLogFacility, SSHCFG_GLOBAL },
361         { "loglevel", sLogLevel, SSHCFG_GLOBAL },
362         { "rhostsauthentication", sDeprecated, SSHCFG_GLOBAL },
363         { "rhostsrsaauthentication", sRhostsRSAAuthentication, SSHCFG_ALL },
364         { "hostbasedauthentication", sHostbasedAuthentication, SSHCFG_ALL },
365         { "hostbasedusesnamefrompacketonly", sHostbasedUsesNameFromPacketOnly, SSHCFG_ALL },
366         { "rsaauthentication", sRSAAuthentication, SSHCFG_ALL },
367         { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL },
368         { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */
369 #ifdef KRB5
370         { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL },
371         { "kerberosorlocalpasswd", sKerberosOrLocalPasswd, SSHCFG_GLOBAL },
372         { "kerberosticketcleanup", sKerberosTicketCleanup, SSHCFG_GLOBAL },
373 #ifdef USE_AFS
374         { "kerberosgetafstoken", sKerberosGetAFSToken, SSHCFG_GLOBAL },
375 #else
376         { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
377 #endif
378 #else
379         { "kerberosauthentication", sUnsupported, SSHCFG_ALL },
380         { "kerberosorlocalpasswd", sUnsupported, SSHCFG_GLOBAL },
381         { "kerberosticketcleanup", sUnsupported, SSHCFG_GLOBAL },
382         { "kerberosgetafstoken", sUnsupported, SSHCFG_GLOBAL },
383 #endif
384         { "kerberostgtpassing", sUnsupported, SSHCFG_GLOBAL },
385         { "afstokenpassing", sUnsupported, SSHCFG_GLOBAL },
386 #ifdef GSSAPI
387         { "gssapiauthentication", sGssAuthentication, SSHCFG_ALL },
388         { "gssapicleanupcredentials", sGssCleanupCreds, SSHCFG_GLOBAL },
389 #else
390         { "gssapiauthentication", sUnsupported, SSHCFG_ALL },
391         { "gssapicleanupcredentials", sUnsupported, SSHCFG_GLOBAL },
392 #endif
393         { "passwordauthentication", sPasswordAuthentication, SSHCFG_ALL },
394         { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL },
395         { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL },
396         { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */
397 #ifdef JPAKE
398         { "zeroknowledgepasswordauthentication", sZeroKnowledgePasswordAuthentication, SSHCFG_ALL },
399 #else
400         { "zeroknowledgepasswordauthentication", sUnsupported, SSHCFG_ALL },
401 #endif
402         { "checkmail", sDeprecated, SSHCFG_GLOBAL },
403         { "listenaddress", sListenAddress, SSHCFG_GLOBAL },
404         { "addressfamily", sAddressFamily, SSHCFG_GLOBAL },
405         { "printmotd", sPrintMotd, SSHCFG_GLOBAL },
406         { "printlastlog", sPrintLastLog, SSHCFG_GLOBAL },
407         { "ignorerhosts", sIgnoreRhosts, SSHCFG_GLOBAL },
408         { "ignoreuserknownhosts", sIgnoreUserKnownHosts, SSHCFG_GLOBAL },
409         { "x11forwarding", sX11Forwarding, SSHCFG_ALL },
410         { "x11displayoffset", sX11DisplayOffset, SSHCFG_ALL },
411         { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL },
412         { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL },
413         { "strictmodes", sStrictModes, SSHCFG_GLOBAL },
414         { "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL },
415         { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL },
416         { "uselogin", sUseLogin, SSHCFG_GLOBAL },
417         { "compression", sCompression, SSHCFG_GLOBAL },
418         { "tcpkeepalive", sTCPKeepAlive, SSHCFG_GLOBAL },
419         { "keepalive", sTCPKeepAlive, SSHCFG_GLOBAL },  /* obsolete alias */
420         { "allowtcpforwarding", sAllowTcpForwarding, SSHCFG_ALL },
421         { "allowagentforwarding", sAllowAgentForwarding, SSHCFG_ALL },
422         { "allowusers", sAllowUsers, SSHCFG_GLOBAL },
423         { "denyusers", sDenyUsers, SSHCFG_GLOBAL },
424         { "allowgroups", sAllowGroups, SSHCFG_GLOBAL },
425         { "denygroups", sDenyGroups, SSHCFG_GLOBAL },
426         { "ciphers", sCiphers, SSHCFG_GLOBAL },
427         { "macs", sMacs, SSHCFG_GLOBAL },
428         { "protocol", sProtocol, SSHCFG_GLOBAL },
429         { "gatewayports", sGatewayPorts, SSHCFG_ALL },
430         { "subsystem", sSubsystem, SSHCFG_GLOBAL },
431         { "maxstartups", sMaxStartups, SSHCFG_GLOBAL },
432         { "maxauthtries", sMaxAuthTries, SSHCFG_ALL },
433         { "maxsessions", sMaxSessions, SSHCFG_ALL },
434         { "banner", sBanner, SSHCFG_ALL },
435         { "usedns", sUseDNS, SSHCFG_GLOBAL },
436         { "verifyreversemapping", sDeprecated, SSHCFG_GLOBAL },
437         { "reversemappingcheck", sDeprecated, SSHCFG_GLOBAL },
438         { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL },
439         { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL },
440         { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_ALL },
441         { "authorizedkeysfile2", sAuthorizedKeysFile2, SSHCFG_ALL },
442         { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL},
443         { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL },
444         { "permittunnel", sPermitTunnel, SSHCFG_ALL },
445         { "match", sMatch, SSHCFG_ALL },
446         { "permitopen", sPermitOpen, SSHCFG_ALL },
447         { "forcecommand", sForceCommand, SSHCFG_ALL },
448         { "chrootdirectory", sChrootDirectory, SSHCFG_ALL },
449         { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
450         { "revokedkeys", sRevokedKeys, SSHCFG_ALL },
451         { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
452         { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
453         { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
454         { "ipqos", sIPQoS, SSHCFG_ALL },
455         { NULL, sBadOption, 0 }
456 };
457
458 static struct {
459         int val;
460         char *text;
461 } tunmode_desc[] = {
462         { SSH_TUNMODE_NO, "no" },
463         { SSH_TUNMODE_POINTOPOINT, "point-to-point" },
464         { SSH_TUNMODE_ETHERNET, "ethernet" },
465         { SSH_TUNMODE_YES, "yes" },
466         { -1, NULL }
467 };
468
469 /*
470  * Returns the number of the token pointed to by cp or sBadOption.
471  */
472
473 static ServerOpCodes
474 parse_token(const char *cp, const char *filename,
475             int linenum, u_int *flags)
476 {
477         u_int i;
478
479         for (i = 0; keywords[i].name; i++)
480                 if (strcasecmp(cp, keywords[i].name) == 0) {
481                         *flags = keywords[i].flags;
482                         return keywords[i].opcode;
483                 }
484
485         error("%s: line %d: Bad configuration option: %s",
486             filename, linenum, cp);
487         return sBadOption;
488 }
489
490 char *
491 derelativise_path(const char *path)
492 {
493         char *expanded, *ret, cwd[MAXPATHLEN];
494
495         expanded = tilde_expand_filename(path, getuid());
496         if (*expanded == '/')
497                 return expanded;
498         if (getcwd(cwd, sizeof(cwd)) == NULL)
499                 fatal("%s: getcwd: %s", __func__, strerror(errno));
500         xasprintf(&ret, "%s/%s", cwd, expanded);
501         xfree(expanded);
502         return ret;
503 }
504
505 static void
506 add_listen_addr(ServerOptions *options, char *addr, int port)
507 {
508         u_int i;
509
510         if (options->num_ports == 0)
511                 options->ports[options->num_ports++] = SSH_DEFAULT_PORT;
512         if (options->address_family == -1)
513                 options->address_family = AF_UNSPEC;
514         if (port == 0)
515                 for (i = 0; i < options->num_ports; i++)
516                         add_one_listen_addr(options, addr, options->ports[i]);
517         else
518                 add_one_listen_addr(options, addr, port);
519 }
520
521 static void
522 add_one_listen_addr(ServerOptions *options, char *addr, int port)
523 {
524         struct addrinfo hints, *ai, *aitop;
525         char strport[NI_MAXSERV];
526         int gaierr;
527
528         memset(&hints, 0, sizeof(hints));
529         hints.ai_family = options->address_family;
530         hints.ai_socktype = SOCK_STREAM;
531         hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0;
532         snprintf(strport, sizeof strport, "%d", port);
533         if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0)
534                 fatal("bad addr or host: %s (%s)",
535                     addr ? addr : "<NULL>",
536                     ssh_gai_strerror(gaierr));
537         for (ai = aitop; ai->ai_next; ai = ai->ai_next)
538                 ;
539         ai->ai_next = options->listen_addrs;
540         options->listen_addrs = aitop;
541 }
542
543 /*
544  * The strategy for the Match blocks is that the config file is parsed twice.
545  *
546  * The first time is at startup.  activep is initialized to 1 and the
547  * directives in the global context are processed and acted on.  Hitting a
548  * Match directive unsets activep and the directives inside the block are
549  * checked for syntax only.
550  *
551  * The second time is after a connection has been established but before
552  * authentication.  activep is initialized to 2 and global config directives
553  * are ignored since they have already been processed.  If the criteria in a
554  * Match block is met, activep is set and the subsequent directives
555  * processed and actioned until EOF or another Match block unsets it.  Any
556  * options set are copied into the main server config.
557  *
558  * Potential additions/improvements:
559  *  - Add Match support for pre-kex directives, eg Protocol, Ciphers.
560  *
561  *  - Add a Tag directive (idea from David Leonard) ala pf, eg:
562  *      Match Address 192.168.0.*
563  *              Tag trusted
564  *      Match Group wheel
565  *              Tag trusted
566  *      Match Tag trusted
567  *              AllowTcpForwarding yes
568  *              GatewayPorts clientspecified
569  *              [...]
570  *
571  *  - Add a PermittedChannelRequests directive
572  *      Match Group shell
573  *              PermittedChannelRequests session,forwarded-tcpip
574  */
575
576 static int
577 match_cfg_line_group(const char *grps, int line, const char *user)
578 {
579         int result = 0;
580         struct passwd *pw;
581
582         if (user == NULL)
583                 goto out;
584
585         if ((pw = getpwnam(user)) == NULL) {
586                 debug("Can't match group at line %d because user %.100s does "
587                     "not exist", line, user);
588         } else if (ga_init(pw->pw_name, pw->pw_gid) == 0) {
589                 debug("Can't Match group because user %.100s not in any group "
590                     "at line %d", user, line);
591         } else if (ga_match_pattern_list(grps) != 1) {
592                 debug("user %.100s does not match group list %.100s at line %d",
593                     user, grps, line);
594         } else {
595                 debug("user %.100s matched group list %.100s at line %d", user,
596                     grps, line);
597                 result = 1;
598         }
599 out:
600         ga_free();
601         return result;
602 }
603
604 static int
605 match_cfg_line(char **condition, int line, const char *user, const char *host,
606     const char *address)
607 {
608         int result = 1;
609         char *arg, *attrib, *cp = *condition;
610         size_t len;
611
612         if (user == NULL)
613                 debug3("checking syntax for 'Match %s'", cp);
614         else
615                 debug3("checking match for '%s' user %s host %s addr %s", cp,
616                     user ? user : "(null)", host ? host : "(null)",
617                     address ? address : "(null)");
618
619         while ((attrib = strdelim(&cp)) && *attrib != '\0') {
620                 if ((arg = strdelim(&cp)) == NULL || *arg == '\0') {
621                         error("Missing Match criteria for %s", attrib);
622                         return -1;
623                 }
624                 len = strlen(arg);
625                 if (strcasecmp(attrib, "user") == 0) {
626                         if (!user) {
627                                 result = 0;
628                                 continue;
629                         }
630                         if (match_pattern_list(user, arg, len, 0) != 1)
631                                 result = 0;
632                         else
633                                 debug("user %.100s matched 'User %.100s' at "
634                                     "line %d", user, arg, line);
635                 } else if (strcasecmp(attrib, "group") == 0) {
636                         switch (match_cfg_line_group(arg, line, user)) {
637                         case -1:
638                                 return -1;
639                         case 0:
640                                 result = 0;
641                         }
642                 } else if (strcasecmp(attrib, "host") == 0) {
643                         if (!host) {
644                                 result = 0;
645                                 continue;
646                         }
647                         if (match_hostname(host, arg, len) != 1)
648                                 result = 0;
649                         else
650                                 debug("connection from %.100s matched 'Host "
651                                     "%.100s' at line %d", host, arg, line);
652                 } else if (strcasecmp(attrib, "address") == 0) {
653                         switch (addr_match_list(address, arg)) {
654                         case 1:
655                                 debug("connection from %.100s matched 'Address "
656                                     "%.100s' at line %d", address, arg, line);
657                                 break;
658                         case 0:
659                         case -1:
660                                 result = 0;
661                                 break;
662                         case -2:
663                                 return -1;
664                         }
665                 } else {
666                         error("Unsupported Match attribute %s", attrib);
667                         return -1;
668                 }
669         }
670         if (user != NULL)
671                 debug3("match %sfound", result ? "" : "not ");
672         *condition = cp;
673         return result;
674 }
675
676 #define WHITESPACE " \t\r\n"
677
678 int
679 process_server_config_line(ServerOptions *options, char *line,
680     const char *filename, int linenum, int *activep, const char *user,
681     const char *host, const char *address)
682 {
683         char *cp, **charptr, *arg, *p;
684         int cmdline = 0, *intptr, value, value2, n;
685         SyslogFacility *log_facility_ptr;
686         LogLevel *log_level_ptr;
687         ServerOpCodes opcode;
688         int port;
689         u_int i, flags = 0;
690         size_t len;
691
692         cp = line;
693         if ((arg = strdelim(&cp)) == NULL)
694                 return 0;
695         /* Ignore leading whitespace */
696         if (*arg == '\0')
697                 arg = strdelim(&cp);
698         if (!arg || !*arg || *arg == '#')
699                 return 0;
700         intptr = NULL;
701         charptr = NULL;
702         opcode = parse_token(arg, filename, linenum, &flags);
703
704         if (activep == NULL) { /* We are processing a command line directive */
705                 cmdline = 1;
706                 activep = &cmdline;
707         }
708         if (*activep && opcode != sMatch)
709                 debug3("%s:%d setting %s %s", filename, linenum, arg, cp);
710         if (*activep == 0 && !(flags & SSHCFG_MATCH)) {
711                 if (user == NULL) {
712                         fatal("%s line %d: Directive '%s' is not allowed "
713                             "within a Match block", filename, linenum, arg);
714                 } else { /* this is a directive we have already processed */
715                         while (arg)
716                                 arg = strdelim(&cp);
717                         return 0;
718                 }
719         }
720
721         switch (opcode) {
722         /* Portable-specific options */
723         case sUsePAM:
724                 intptr = &options->use_pam;
725                 goto parse_flag;
726
727         /* Standard Options */
728         case sBadOption:
729                 return -1;
730         case sPort:
731                 /* ignore ports from configfile if cmdline specifies ports */
732                 if (options->ports_from_cmdline)
733                         return 0;
734                 if (options->listen_addrs != NULL)
735                         fatal("%s line %d: ports must be specified before "
736                             "ListenAddress.", filename, linenum);
737                 if (options->num_ports >= MAX_PORTS)
738                         fatal("%s line %d: too many ports.",
739                             filename, linenum);
740                 arg = strdelim(&cp);
741                 if (!arg || *arg == '\0')
742                         fatal("%s line %d: missing port number.",
743                             filename, linenum);
744                 options->ports[options->num_ports++] = a2port(arg);
745                 if (options->ports[options->num_ports-1] <= 0)
746                         fatal("%s line %d: Badly formatted port number.",
747                             filename, linenum);
748                 break;
749
750         case sServerKeyBits:
751                 intptr = &options->server_key_bits;
752  parse_int:
753                 arg = strdelim(&cp);
754                 if (!arg || *arg == '\0')
755                         fatal("%s line %d: missing integer value.",
756                             filename, linenum);
757                 value = atoi(arg);
758                 if (*activep && *intptr == -1)
759                         *intptr = value;
760                 break;
761
762         case sLoginGraceTime:
763                 intptr = &options->login_grace_time;
764  parse_time:
765                 arg = strdelim(&cp);
766                 if (!arg || *arg == '\0')
767                         fatal("%s line %d: missing time value.",
768                             filename, linenum);
769                 if ((value = convtime(arg)) == -1)
770                         fatal("%s line %d: invalid time value.",
771                             filename, linenum);
772                 if (*intptr == -1)
773                         *intptr = value;
774                 break;
775
776         case sKeyRegenerationTime:
777                 intptr = &options->key_regeneration_time;
778                 goto parse_time;
779
780         case sListenAddress:
781                 arg = strdelim(&cp);
782                 if (arg == NULL || *arg == '\0')
783                         fatal("%s line %d: missing address",
784                             filename, linenum);
785                 /* check for bare IPv6 address: no "[]" and 2 or more ":" */
786                 if (strchr(arg, '[') == NULL && (p = strchr(arg, ':')) != NULL
787                     && strchr(p+1, ':') != NULL) {
788                         add_listen_addr(options, arg, 0);
789                         break;
790                 }
791                 p = hpdelim(&arg);
792                 if (p == NULL)
793                         fatal("%s line %d: bad address:port usage",
794                             filename, linenum);
795                 p = cleanhostname(p);
796                 if (arg == NULL)
797                         port = 0;
798                 else if ((port = a2port(arg)) <= 0)
799                         fatal("%s line %d: bad port number", filename, linenum);
800
801                 add_listen_addr(options, p, port);
802
803                 break;
804
805         case sAddressFamily:
806                 arg = strdelim(&cp);
807                 if (!arg || *arg == '\0')
808                         fatal("%s line %d: missing address family.",
809                             filename, linenum);
810                 intptr = &options->address_family;
811                 if (options->listen_addrs != NULL)
812                         fatal("%s line %d: address family must be specified before "
813                             "ListenAddress.", filename, linenum);
814                 if (strcasecmp(arg, "inet") == 0)
815                         value = AF_INET;
816                 else if (strcasecmp(arg, "inet6") == 0)
817                         value = AF_INET6;
818                 else if (strcasecmp(arg, "any") == 0)
819                         value = AF_UNSPEC;
820                 else
821                         fatal("%s line %d: unsupported address family \"%s\".",
822                             filename, linenum, arg);
823                 if (*intptr == -1)
824                         *intptr = value;
825                 break;
826
827         case sHostKeyFile:
828                 intptr = &options->num_host_key_files;
829                 if (*intptr >= MAX_HOSTKEYS)
830                         fatal("%s line %d: too many host keys specified (max %d).",
831                             filename, linenum, MAX_HOSTKEYS);
832                 charptr = &options->host_key_files[*intptr];
833  parse_filename:
834                 arg = strdelim(&cp);
835                 if (!arg || *arg == '\0')
836                         fatal("%s line %d: missing file name.",
837                             filename, linenum);
838                 if (*activep && *charptr == NULL) {
839                         *charptr = derelativise_path(arg);
840                         /* increase optional counter */
841                         if (intptr != NULL)
842                                 *intptr = *intptr + 1;
843                 }
844                 break;
845
846         case sHostCertificate:
847                 intptr = &options->num_host_cert_files;
848                 if (*intptr >= MAX_HOSTKEYS)
849                         fatal("%s line %d: too many host certificates "
850                             "specified (max %d).", filename, linenum,
851                             MAX_HOSTCERTS);
852                 charptr = &options->host_cert_files[*intptr];
853                 goto parse_filename;
854                 break;
855
856         case sPidFile:
857                 charptr = &options->pid_file;
858                 goto parse_filename;
859
860         case sPermitRootLogin:
861                 intptr = &options->permit_root_login;
862                 arg = strdelim(&cp);
863                 if (!arg || *arg == '\0')
864                         fatal("%s line %d: missing yes/"
865                             "without-password/forced-commands-only/no "
866                             "argument.", filename, linenum);
867                 value = 0;      /* silence compiler */
868                 if (strcmp(arg, "without-password") == 0)
869                         value = PERMIT_NO_PASSWD;
870                 else if (strcmp(arg, "forced-commands-only") == 0)
871                         value = PERMIT_FORCED_ONLY;
872                 else if (strcmp(arg, "yes") == 0)
873                         value = PERMIT_YES;
874                 else if (strcmp(arg, "no") == 0)
875                         value = PERMIT_NO;
876                 else
877                         fatal("%s line %d: Bad yes/"
878                             "without-password/forced-commands-only/no "
879                             "argument: %s", filename, linenum, arg);
880                 if (*activep && *intptr == -1)
881                         *intptr = value;
882                 break;
883
884         case sIgnoreRhosts:
885                 intptr = &options->ignore_rhosts;
886  parse_flag:
887                 arg = strdelim(&cp);
888                 if (!arg || *arg == '\0')
889                         fatal("%s line %d: missing yes/no argument.",
890                             filename, linenum);
891                 value = 0;      /* silence compiler */
892                 if (strcmp(arg, "yes") == 0)
893                         value = 1;
894                 else if (strcmp(arg, "no") == 0)
895                         value = 0;
896                 else
897                         fatal("%s line %d: Bad yes/no argument: %s",
898                                 filename, linenum, arg);
899                 if (*activep && *intptr == -1)
900                         *intptr = value;
901                 break;
902
903         case sIgnoreUserKnownHosts:
904                 intptr = &options->ignore_user_known_hosts;
905                 goto parse_flag;
906
907         case sRhostsRSAAuthentication:
908                 intptr = &options->rhosts_rsa_authentication;
909                 goto parse_flag;
910
911         case sHostbasedAuthentication:
912                 intptr = &options->hostbased_authentication;
913                 goto parse_flag;
914
915         case sHostbasedUsesNameFromPacketOnly:
916                 intptr = &options->hostbased_uses_name_from_packet_only;
917                 goto parse_flag;
918
919         case sRSAAuthentication:
920                 intptr = &options->rsa_authentication;
921                 goto parse_flag;
922
923         case sPubkeyAuthentication:
924                 intptr = &options->pubkey_authentication;
925                 goto parse_flag;
926
927         case sKerberosAuthentication:
928                 intptr = &options->kerberos_authentication;
929                 goto parse_flag;
930
931         case sKerberosOrLocalPasswd:
932                 intptr = &options->kerberos_or_local_passwd;
933                 goto parse_flag;
934
935         case sKerberosTicketCleanup:
936                 intptr = &options->kerberos_ticket_cleanup;
937                 goto parse_flag;
938
939         case sKerberosGetAFSToken:
940                 intptr = &options->kerberos_get_afs_token;
941                 goto parse_flag;
942
943         case sGssAuthentication:
944                 intptr = &options->gss_authentication;
945                 goto parse_flag;
946
947         case sGssCleanupCreds:
948                 intptr = &options->gss_cleanup_creds;
949                 goto parse_flag;
950
951         case sPasswordAuthentication:
952                 intptr = &options->password_authentication;
953                 goto parse_flag;
954
955         case sZeroKnowledgePasswordAuthentication:
956                 intptr = &options->zero_knowledge_password_authentication;
957                 goto parse_flag;
958
959         case sKbdInteractiveAuthentication:
960                 intptr = &options->kbd_interactive_authentication;
961                 goto parse_flag;
962
963         case sChallengeResponseAuthentication:
964                 intptr = &options->challenge_response_authentication;
965                 goto parse_flag;
966
967         case sPrintMotd:
968                 intptr = &options->print_motd;
969                 goto parse_flag;
970
971         case sPrintLastLog:
972                 intptr = &options->print_lastlog;
973                 goto parse_flag;
974
975         case sX11Forwarding:
976                 intptr = &options->x11_forwarding;
977                 goto parse_flag;
978
979         case sX11DisplayOffset:
980                 intptr = &options->x11_display_offset;
981                 goto parse_int;
982
983         case sX11UseLocalhost:
984                 intptr = &options->x11_use_localhost;
985                 goto parse_flag;
986
987         case sXAuthLocation:
988                 charptr = &options->xauth_location;
989                 goto parse_filename;
990
991         case sStrictModes:
992                 intptr = &options->strict_modes;
993                 goto parse_flag;
994
995         case sTCPKeepAlive:
996                 intptr = &options->tcp_keep_alive;
997                 goto parse_flag;
998
999         case sEmptyPasswd:
1000                 intptr = &options->permit_empty_passwd;
1001                 goto parse_flag;
1002
1003         case sPermitUserEnvironment:
1004                 intptr = &options->permit_user_env;
1005                 goto parse_flag;
1006
1007         case sUseLogin:
1008                 intptr = &options->use_login;
1009                 goto parse_flag;
1010
1011         case sCompression:
1012                 intptr = &options->compression;
1013                 arg = strdelim(&cp);
1014                 if (!arg || *arg == '\0')
1015                         fatal("%s line %d: missing yes/no/delayed "
1016                             "argument.", filename, linenum);
1017                 value = 0;      /* silence compiler */
1018                 if (strcmp(arg, "delayed") == 0)
1019                         value = COMP_DELAYED;
1020                 else if (strcmp(arg, "yes") == 0)
1021                         value = COMP_ZLIB;
1022                 else if (strcmp(arg, "no") == 0)
1023                         value = COMP_NONE;
1024                 else
1025                         fatal("%s line %d: Bad yes/no/delayed "
1026                             "argument: %s", filename, linenum, arg);
1027                 if (*intptr == -1)
1028                         *intptr = value;
1029                 break;
1030
1031         case sGatewayPorts:
1032                 intptr = &options->gateway_ports;
1033                 arg = strdelim(&cp);
1034                 if (!arg || *arg == '\0')
1035                         fatal("%s line %d: missing yes/no/clientspecified "
1036                             "argument.", filename, linenum);
1037                 value = 0;      /* silence compiler */
1038                 if (strcmp(arg, "clientspecified") == 0)
1039                         value = 2;
1040                 else if (strcmp(arg, "yes") == 0)
1041                         value = 1;
1042                 else if (strcmp(arg, "no") == 0)
1043                         value = 0;
1044                 else
1045                         fatal("%s line %d: Bad yes/no/clientspecified "
1046                             "argument: %s", filename, linenum, arg);
1047                 if (*activep && *intptr == -1)
1048                         *intptr = value;
1049                 break;
1050
1051         case sUseDNS:
1052                 intptr = &options->use_dns;
1053                 goto parse_flag;
1054
1055         case sLogFacility:
1056                 log_facility_ptr = &options->log_facility;
1057                 arg = strdelim(&cp);
1058                 value = log_facility_number(arg);
1059                 if (value == SYSLOG_FACILITY_NOT_SET)
1060                         fatal("%.200s line %d: unsupported log facility '%s'",
1061                             filename, linenum, arg ? arg : "<NONE>");
1062                 if (*log_facility_ptr == -1)
1063                         *log_facility_ptr = (SyslogFacility) value;
1064                 break;
1065
1066         case sLogLevel:
1067                 log_level_ptr = &options->log_level;
1068                 arg = strdelim(&cp);
1069                 value = log_level_number(arg);
1070                 if (value == SYSLOG_LEVEL_NOT_SET)
1071                         fatal("%.200s line %d: unsupported log level '%s'",
1072                             filename, linenum, arg ? arg : "<NONE>");
1073                 if (*log_level_ptr == -1)
1074                         *log_level_ptr = (LogLevel) value;
1075                 break;
1076
1077         case sAllowTcpForwarding:
1078                 intptr = &options->allow_tcp_forwarding;
1079                 goto parse_flag;
1080
1081         case sAllowAgentForwarding:
1082                 intptr = &options->allow_agent_forwarding;
1083                 goto parse_flag;
1084
1085         case sUsePrivilegeSeparation:
1086                 intptr = &use_privsep;
1087                 goto parse_flag;
1088
1089         case sAllowUsers:
1090                 while ((arg = strdelim(&cp)) && *arg != '\0') {
1091                         if (options->num_allow_users >= MAX_ALLOW_USERS)
1092                                 fatal("%s line %d: too many allow users.",
1093                                     filename, linenum);
1094                         options->allow_users[options->num_allow_users++] =
1095                             xstrdup(arg);
1096                 }
1097                 break;
1098
1099         case sDenyUsers:
1100                 while ((arg = strdelim(&cp)) && *arg != '\0') {
1101                         if (options->num_deny_users >= MAX_DENY_USERS)
1102                                 fatal("%s line %d: too many deny users.",
1103                                     filename, linenum);
1104                         options->deny_users[options->num_deny_users++] =
1105                             xstrdup(arg);
1106                 }
1107                 break;
1108
1109         case sAllowGroups:
1110                 while ((arg = strdelim(&cp)) && *arg != '\0') {
1111                         if (options->num_allow_groups >= MAX_ALLOW_GROUPS)
1112                                 fatal("%s line %d: too many allow groups.",
1113                                     filename, linenum);
1114                         options->allow_groups[options->num_allow_groups++] =
1115                             xstrdup(arg);
1116                 }
1117                 break;
1118
1119         case sDenyGroups:
1120                 while ((arg = strdelim(&cp)) && *arg != '\0') {
1121                         if (options->num_deny_groups >= MAX_DENY_GROUPS)
1122                                 fatal("%s line %d: too many deny groups.",
1123                                     filename, linenum);
1124                         options->deny_groups[options->num_deny_groups++] = xstrdup(arg);
1125                 }
1126                 break;
1127
1128         case sCiphers:
1129                 arg = strdelim(&cp);
1130                 if (!arg || *arg == '\0')
1131                         fatal("%s line %d: Missing argument.", filename, linenum);
1132                 if (!ciphers_valid(arg))
1133                         fatal("%s line %d: Bad SSH2 cipher spec '%s'.",
1134                             filename, linenum, arg ? arg : "<NONE>");
1135                 if (options->ciphers == NULL)
1136                         options->ciphers = xstrdup(arg);
1137                 break;
1138
1139         case sMacs:
1140                 arg = strdelim(&cp);
1141                 if (!arg || *arg == '\0')
1142                         fatal("%s line %d: Missing argument.", filename, linenum);
1143                 if (!mac_valid(arg))
1144                         fatal("%s line %d: Bad SSH2 mac spec '%s'.",
1145                             filename, linenum, arg ? arg : "<NONE>");
1146                 if (options->macs == NULL)
1147                         options->macs = xstrdup(arg);
1148                 break;
1149
1150         case sKexAlgorithms:
1151                 arg = strdelim(&cp);
1152                 if (!arg || *arg == '\0')
1153                         fatal("%s line %d: Missing argument.",
1154                             filename, linenum);
1155                 if (!kex_names_valid(arg))
1156                         fatal("%s line %d: Bad SSH2 KexAlgorithms '%s'.",
1157                             filename, linenum, arg ? arg : "<NONE>");
1158                 if (options->kex_algorithms == NULL)
1159                         options->kex_algorithms = xstrdup(arg);
1160                 break;
1161
1162         case sProtocol:
1163                 intptr = &options->protocol;
1164                 arg = strdelim(&cp);
1165                 if (!arg || *arg == '\0')
1166                         fatal("%s line %d: Missing argument.", filename, linenum);
1167                 value = proto_spec(arg);
1168                 if (value == SSH_PROTO_UNKNOWN)
1169                         fatal("%s line %d: Bad protocol spec '%s'.",
1170                             filename, linenum, arg ? arg : "<NONE>");
1171                 if (*intptr == SSH_PROTO_UNKNOWN)
1172                         *intptr = value;
1173                 break;
1174
1175         case sSubsystem:
1176                 if (options->num_subsystems >= MAX_SUBSYSTEMS) {
1177                         fatal("%s line %d: too many subsystems defined.",
1178                             filename, linenum);
1179                 }
1180                 arg = strdelim(&cp);
1181                 if (!arg || *arg == '\0')
1182                         fatal("%s line %d: Missing subsystem name.",
1183                             filename, linenum);
1184                 if (!*activep) {
1185                         arg = strdelim(&cp);
1186                         break;
1187                 }
1188                 for (i = 0; i < options->num_subsystems; i++)
1189                         if (strcmp(arg, options->subsystem_name[i]) == 0)
1190                                 fatal("%s line %d: Subsystem '%s' already defined.",
1191                                     filename, linenum, arg);
1192                 options->subsystem_name[options->num_subsystems] = xstrdup(arg);
1193                 arg = strdelim(&cp);
1194                 if (!arg || *arg == '\0')
1195                         fatal("%s line %d: Missing subsystem command.",
1196                             filename, linenum);
1197                 options->subsystem_command[options->num_subsystems] = xstrdup(arg);
1198
1199                 /* Collect arguments (separate to executable) */
1200                 p = xstrdup(arg);
1201                 len = strlen(p) + 1;
1202                 while ((arg = strdelim(&cp)) != NULL && *arg != '\0') {
1203                         len += 1 + strlen(arg);
1204                         p = xrealloc(p, 1, len);
1205                         strlcat(p, " ", len);
1206                         strlcat(p, arg, len);
1207                 }
1208                 options->subsystem_args[options->num_subsystems] = p;
1209                 options->num_subsystems++;
1210                 break;
1211
1212         case sMaxStartups:
1213                 arg = strdelim(&cp);
1214                 if (!arg || *arg == '\0')
1215                         fatal("%s line %d: Missing MaxStartups spec.",
1216                             filename, linenum);
1217                 if ((n = sscanf(arg, "%d:%d:%d",
1218                     &options->max_startups_begin,
1219                     &options->max_startups_rate,
1220                     &options->max_startups)) == 3) {
1221                         if (options->max_startups_begin >
1222                             options->max_startups ||
1223                             options->max_startups_rate > 100 ||
1224                             options->max_startups_rate < 1)
1225                                 fatal("%s line %d: Illegal MaxStartups spec.",
1226                                     filename, linenum);
1227                 } else if (n != 1)
1228                         fatal("%s line %d: Illegal MaxStartups spec.",
1229                             filename, linenum);
1230                 else
1231                         options->max_startups = options->max_startups_begin;
1232                 break;
1233
1234         case sMaxAuthTries:
1235                 intptr = &options->max_authtries;
1236                 goto parse_int;
1237
1238         case sMaxSessions:
1239                 intptr = &options->max_sessions;
1240                 goto parse_int;
1241
1242         case sBanner:
1243                 charptr = &options->banner;
1244                 goto parse_filename;
1245
1246         /*
1247          * These options can contain %X options expanded at
1248          * connect time, so that you can specify paths like:
1249          *
1250          * AuthorizedKeysFile   /etc/ssh_keys/%u
1251          */
1252         case sAuthorizedKeysFile:
1253                 charptr = &options->authorized_keys_file;
1254                 goto parse_tilde_filename;
1255         case sAuthorizedKeysFile2:
1256                 charptr = &options->authorized_keys_file2;
1257                 goto parse_tilde_filename;
1258         case sAuthorizedPrincipalsFile:
1259                 charptr = &options->authorized_principals_file;
1260  parse_tilde_filename:
1261                 arg = strdelim(&cp);
1262                 if (!arg || *arg == '\0')
1263                         fatal("%s line %d: missing file name.",
1264                             filename, linenum);
1265                 if (*activep && *charptr == NULL) {
1266                         *charptr = tilde_expand_filename(arg, getuid());
1267                         /* increase optional counter */
1268                         if (intptr != NULL)
1269                                 *intptr = *intptr + 1;
1270                 }
1271                 break;
1272
1273         case sClientAliveInterval:
1274                 intptr = &options->client_alive_interval;
1275                 goto parse_time;
1276
1277         case sClientAliveCountMax:
1278                 intptr = &options->client_alive_count_max;
1279                 goto parse_int;
1280
1281         case sAcceptEnv:
1282                 while ((arg = strdelim(&cp)) && *arg != '\0') {
1283                         if (strchr(arg, '=') != NULL)
1284                                 fatal("%s line %d: Invalid environment name.",
1285                                     filename, linenum);
1286                         if (options->num_accept_env >= MAX_ACCEPT_ENV)
1287                                 fatal("%s line %d: too many allow env.",
1288                                     filename, linenum);
1289                         if (!*activep)
1290                                 break;
1291                         options->accept_env[options->num_accept_env++] =
1292                             xstrdup(arg);
1293                 }
1294                 break;
1295
1296         case sPermitTunnel:
1297                 intptr = &options->permit_tun;
1298                 arg = strdelim(&cp);
1299                 if (!arg || *arg == '\0')
1300                         fatal("%s line %d: Missing yes/point-to-point/"
1301                             "ethernet/no argument.", filename, linenum);
1302                 value = -1;
1303                 for (i = 0; tunmode_desc[i].val != -1; i++)
1304                         if (strcmp(tunmode_desc[i].text, arg) == 0) {
1305                                 value = tunmode_desc[i].val;
1306                                 break;
1307                         }
1308                 if (value == -1)
1309                         fatal("%s line %d: Bad yes/point-to-point/ethernet/"
1310                             "no argument: %s", filename, linenum, arg);
1311                 if (*intptr == -1)
1312                         *intptr = value;
1313                 break;
1314
1315         case sMatch:
1316                 if (cmdline)
1317                         fatal("Match directive not supported as a command-line "
1318                            "option");
1319                 value = match_cfg_line(&cp, linenum, user, host, address);
1320                 if (value < 0)
1321                         fatal("%s line %d: Bad Match condition", filename,
1322                             linenum);
1323                 *activep = value;
1324                 break;
1325
1326         case sPermitOpen:
1327                 arg = strdelim(&cp);
1328                 if (!arg || *arg == '\0')
1329                         fatal("%s line %d: missing PermitOpen specification",
1330                             filename, linenum);
1331                 n = options->num_permitted_opens;       /* modified later */
1332                 if (strcmp(arg, "any") == 0) {
1333                         if (*activep && n == -1) {
1334                                 channel_clear_adm_permitted_opens();
1335                                 options->num_permitted_opens = 0;
1336                         }
1337                         break;
1338                 }
1339                 if (*activep && n == -1)
1340                         channel_clear_adm_permitted_opens();
1341                 for (; arg != NULL && *arg != '\0'; arg = strdelim(&cp)) {
1342                         p = hpdelim(&arg);
1343                         if (p == NULL)
1344                                 fatal("%s line %d: missing host in PermitOpen",
1345                                     filename, linenum);
1346                         p = cleanhostname(p);
1347                         if (arg == NULL || (port = a2port(arg)) <= 0)
1348                                 fatal("%s line %d: bad port number in "
1349                                     "PermitOpen", filename, linenum);
1350                         if (*activep && n == -1)
1351                                 options->num_permitted_opens =
1352                                     channel_add_adm_permitted_opens(p, port);
1353                 }
1354                 break;
1355
1356         case sForceCommand:
1357                 if (cp == NULL)
1358                         fatal("%.200s line %d: Missing argument.", filename,
1359                             linenum);
1360                 len = strspn(cp, WHITESPACE);
1361                 if (*activep && options->adm_forced_command == NULL)
1362                         options->adm_forced_command = xstrdup(cp + len);
1363                 return 0;
1364
1365         case sChrootDirectory:
1366                 charptr = &options->chroot_directory;
1367
1368                 arg = strdelim(&cp);
1369                 if (!arg || *arg == '\0')
1370                         fatal("%s line %d: missing file name.",
1371                             filename, linenum);
1372                 if (*activep && *charptr == NULL)
1373                         *charptr = xstrdup(arg);
1374                 break;
1375
1376         case sTrustedUserCAKeys:
1377                 charptr = &options->trusted_user_ca_keys;
1378                 goto parse_filename;
1379
1380         case sRevokedKeys:
1381                 charptr = &options->revoked_keys_file;
1382                 goto parse_filename;
1383
1384         case sIPQoS:
1385                 arg = strdelim(&cp);
1386                 if ((value = parse_ipqos(arg)) == -1)
1387                         fatal("%s line %d: Bad IPQoS value: %s",
1388                             filename, linenum, arg);
1389                 arg = strdelim(&cp);
1390                 if (arg == NULL)
1391                         value2 = value;
1392                 else if ((value2 = parse_ipqos(arg)) == -1)
1393                         fatal("%s line %d: Bad IPQoS value: %s",
1394                             filename, linenum, arg);
1395                 if (*activep) {
1396                         options->ip_qos_interactive = value;
1397                         options->ip_qos_bulk = value2;
1398                 }
1399                 break;
1400
1401         case sDeprecated:
1402                 logit("%s line %d: Deprecated option %s",
1403                     filename, linenum, arg);
1404                 while (arg)
1405                     arg = strdelim(&cp);
1406                 break;
1407
1408         case sUnsupported:
1409                 logit("%s line %d: Unsupported option %s",
1410                     filename, linenum, arg);
1411                 while (arg)
1412                     arg = strdelim(&cp);
1413                 break;
1414
1415         default:
1416                 fatal("%s line %d: Missing handler for opcode %s (%d)",
1417                     filename, linenum, arg, opcode);
1418         }
1419         if ((arg = strdelim(&cp)) != NULL && *arg != '\0')
1420                 fatal("%s line %d: garbage at end of line; \"%.200s\".",
1421                     filename, linenum, arg);
1422         return 0;
1423 }
1424
1425 /* Reads the server configuration file. */
1426
1427 void
1428 load_server_config(const char *filename, Buffer *conf)
1429 {
1430         char line[1024], *cp;
1431         FILE *f;
1432
1433         debug2("%s: filename %s", __func__, filename);
1434         if ((f = fopen(filename, "r")) == NULL) {
1435                 perror(filename);
1436                 exit(1);
1437         }
1438         buffer_clear(conf);
1439         while (fgets(line, sizeof(line), f)) {
1440                 /*
1441                  * Trim out comments and strip whitespace
1442                  * NB - preserve newlines, they are needed to reproduce
1443                  * line numbers later for error messages
1444                  */
1445                 if ((cp = strchr(line, '#')) != NULL)
1446                         memcpy(cp, "\n", 2);
1447                 cp = line + strspn(line, " \t\r");
1448
1449                 buffer_append(conf, cp, strlen(cp));
1450         }
1451         buffer_append(conf, "\0", 1);
1452         fclose(f);
1453         debug2("%s: done config len = %d", __func__, buffer_len(conf));
1454 }
1455
1456 void
1457 parse_server_match_config(ServerOptions *options, const char *user,
1458     const char *host, const char *address)
1459 {
1460         ServerOptions mo;
1461
1462         initialize_server_options(&mo);
1463         parse_server_config(&mo, "reprocess config", &cfg, user, host, address);
1464         copy_set_server_options(options, &mo, 0);
1465 }
1466
1467 /* Helper macros */
1468 #define M_CP_INTOPT(n) do {\
1469         if (src->n != -1) \
1470                 dst->n = src->n; \
1471 } while (0)
1472 #define M_CP_STROPT(n) do {\
1473         if (src->n != NULL) { \
1474                 if (dst->n != NULL) \
1475                         xfree(dst->n); \
1476                 dst->n = src->n; \
1477         } \
1478 } while(0)
1479
1480 /*
1481  * Copy any supported values that are set.
1482  *
1483  * If the preauth flag is set, we do not bother copying the string or
1484  * array values that are not used pre-authentication, because any that we
1485  * do use must be explictly sent in mm_getpwnamallow().
1486  */
1487 void
1488 copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth)
1489 {
1490         M_CP_INTOPT(password_authentication);
1491         M_CP_INTOPT(gss_authentication);
1492         M_CP_INTOPT(rsa_authentication);
1493         M_CP_INTOPT(pubkey_authentication);
1494         M_CP_INTOPT(kerberos_authentication);
1495         M_CP_INTOPT(hostbased_authentication);
1496         M_CP_INTOPT(hostbased_uses_name_from_packet_only);
1497         M_CP_INTOPT(kbd_interactive_authentication);
1498         M_CP_INTOPT(zero_knowledge_password_authentication);
1499         M_CP_INTOPT(permit_root_login);
1500         M_CP_INTOPT(permit_empty_passwd);
1501
1502         M_CP_INTOPT(allow_tcp_forwarding);
1503         M_CP_INTOPT(allow_agent_forwarding);
1504         M_CP_INTOPT(permit_tun);
1505         M_CP_INTOPT(gateway_ports);
1506         M_CP_INTOPT(x11_display_offset);
1507         M_CP_INTOPT(x11_forwarding);
1508         M_CP_INTOPT(x11_use_localhost);
1509         M_CP_INTOPT(max_sessions);
1510         M_CP_INTOPT(max_authtries);
1511         M_CP_INTOPT(ip_qos_interactive);
1512         M_CP_INTOPT(ip_qos_bulk);
1513
1514         M_CP_STROPT(banner);
1515         if (preauth)
1516                 return;
1517         M_CP_STROPT(adm_forced_command);
1518         M_CP_STROPT(chroot_directory);
1519         M_CP_STROPT(trusted_user_ca_keys);
1520         M_CP_STROPT(revoked_keys_file);
1521         M_CP_STROPT(authorized_keys_file);
1522         M_CP_STROPT(authorized_keys_file2);
1523         M_CP_STROPT(authorized_principals_file);
1524 }
1525
1526 #undef M_CP_INTOPT
1527 #undef M_CP_STROPT
1528
1529 void
1530 parse_server_config(ServerOptions *options, const char *filename, Buffer *conf,
1531     const char *user, const char *host, const char *address)
1532 {
1533         int active, linenum, bad_options = 0;
1534         char *cp, *obuf, *cbuf;
1535
1536         debug2("%s: config %s len %d", __func__, filename, buffer_len(conf));
1537
1538         obuf = cbuf = xstrdup(buffer_ptr(conf));
1539         active = user ? 0 : 1;
1540         linenum = 1;
1541         while ((cp = strsep(&cbuf, "\n")) != NULL) {
1542                 if (process_server_config_line(options, cp, filename,
1543                     linenum++, &active, user, host, address) != 0)
1544                         bad_options++;
1545         }
1546         xfree(obuf);
1547         if (bad_options > 0)
1548                 fatal("%s: terminating, %d bad configuration options",
1549                     filename, bad_options);
1550 }
1551
1552 static const char *
1553 fmt_intarg(ServerOpCodes code, int val)
1554 {
1555         if (code == sAddressFamily) {
1556                 switch (val) {
1557                 case AF_INET:
1558                         return "inet";
1559                 case AF_INET6:
1560                         return "inet6";
1561                 case AF_UNSPEC:
1562                         return "any";
1563                 default:
1564                         return "UNKNOWN";
1565                 }
1566         }
1567         if (code == sPermitRootLogin) {
1568                 switch (val) {
1569                 case PERMIT_NO_PASSWD:
1570                         return "without-password";
1571                 case PERMIT_FORCED_ONLY:
1572                         return "forced-commands-only";
1573                 case PERMIT_YES:
1574                         return "yes";
1575                 }
1576         }
1577         if (code == sProtocol) {
1578                 switch (val) {
1579                 case SSH_PROTO_1:
1580                         return "1";
1581                 case SSH_PROTO_2:
1582                         return "2";
1583                 case (SSH_PROTO_1|SSH_PROTO_2):
1584                         return "2,1";
1585                 default:
1586                         return "UNKNOWN";
1587                 }
1588         }
1589         if (code == sGatewayPorts && val == 2)
1590                 return "clientspecified";
1591         if (code == sCompression && val == COMP_DELAYED)
1592                 return "delayed";
1593         switch (val) {
1594         case -1:
1595                 return "unset";
1596         case 0:
1597                 return "no";
1598         case 1:
1599                 return "yes";
1600         }
1601         return "UNKNOWN";
1602 }
1603
1604 static const char *
1605 lookup_opcode_name(ServerOpCodes code)
1606 {
1607         u_int i;
1608
1609         for (i = 0; keywords[i].name != NULL; i++)
1610                 if (keywords[i].opcode == code)
1611                         return(keywords[i].name);
1612         return "UNKNOWN";
1613 }
1614
1615 static void
1616 dump_cfg_int(ServerOpCodes code, int val)
1617 {
1618         printf("%s %d\n", lookup_opcode_name(code), val);
1619 }
1620
1621 static void
1622 dump_cfg_fmtint(ServerOpCodes code, int val)
1623 {
1624         printf("%s %s\n", lookup_opcode_name(code), fmt_intarg(code, val));
1625 }
1626
1627 static void
1628 dump_cfg_string(ServerOpCodes code, const char *val)
1629 {
1630         if (val == NULL)
1631                 return;
1632         printf("%s %s\n", lookup_opcode_name(code), val);
1633 }
1634
1635 static void
1636 dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals)
1637 {
1638         u_int i;
1639
1640         for (i = 0; i < count; i++)
1641                 printf("%s %s\n", lookup_opcode_name(code),  vals[i]);
1642 }
1643
1644 void
1645 dump_config(ServerOptions *o)
1646 {
1647         u_int i;
1648         int ret;
1649         struct addrinfo *ai;
1650         char addr[NI_MAXHOST], port[NI_MAXSERV], *s = NULL;
1651
1652         /* these are usually at the top of the config */
1653         for (i = 0; i < o->num_ports; i++)
1654                 printf("port %d\n", o->ports[i]);
1655         dump_cfg_fmtint(sProtocol, o->protocol);
1656         dump_cfg_fmtint(sAddressFamily, o->address_family);
1657
1658         /* ListenAddress must be after Port */
1659         for (ai = o->listen_addrs; ai; ai = ai->ai_next) {
1660                 if ((ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, addr,
1661                     sizeof(addr), port, sizeof(port),
1662                     NI_NUMERICHOST|NI_NUMERICSERV)) != 0) {
1663                         error("getnameinfo failed: %.100s",
1664                             (ret != EAI_SYSTEM) ? gai_strerror(ret) :
1665                             strerror(errno));
1666                 } else {
1667                         if (ai->ai_family == AF_INET6)
1668                                 printf("listenaddress [%s]:%s\n", addr, port);
1669                         else
1670                                 printf("listenaddress %s:%s\n", addr, port);
1671                 }
1672         }
1673
1674         /* integer arguments */
1675 #ifdef USE_PAM
1676         dump_cfg_int(sUsePAM, o->use_pam);
1677 #endif
1678         dump_cfg_int(sServerKeyBits, o->server_key_bits);
1679         dump_cfg_int(sLoginGraceTime, o->login_grace_time);
1680         dump_cfg_int(sKeyRegenerationTime, o->key_regeneration_time);
1681         dump_cfg_int(sX11DisplayOffset, o->x11_display_offset);
1682         dump_cfg_int(sMaxAuthTries, o->max_authtries);
1683         dump_cfg_int(sMaxSessions, o->max_sessions);
1684         dump_cfg_int(sClientAliveInterval, o->client_alive_interval);
1685         dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max);
1686
1687         /* formatted integer arguments */
1688         dump_cfg_fmtint(sPermitRootLogin, o->permit_root_login);
1689         dump_cfg_fmtint(sIgnoreRhosts, o->ignore_rhosts);
1690         dump_cfg_fmtint(sIgnoreUserKnownHosts, o->ignore_user_known_hosts);
1691         dump_cfg_fmtint(sRhostsRSAAuthentication, o->rhosts_rsa_authentication);
1692         dump_cfg_fmtint(sHostbasedAuthentication, o->hostbased_authentication);
1693         dump_cfg_fmtint(sHostbasedUsesNameFromPacketOnly,
1694             o->hostbased_uses_name_from_packet_only);
1695         dump_cfg_fmtint(sRSAAuthentication, o->rsa_authentication);
1696         dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication);
1697 #ifdef KRB5
1698         dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication);
1699         dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd);
1700         dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup);
1701 # ifdef USE_AFS
1702         dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token);
1703 # endif
1704 #endif
1705 #ifdef GSSAPI
1706         dump_cfg_fmtint(sGssAuthentication, o->gss_authentication);
1707         dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds);
1708 #endif
1709 #ifdef JPAKE
1710         dump_cfg_fmtint(sZeroKnowledgePasswordAuthentication,
1711             o->zero_knowledge_password_authentication);
1712 #endif
1713         dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication);
1714         dump_cfg_fmtint(sKbdInteractiveAuthentication,
1715             o->kbd_interactive_authentication);
1716         dump_cfg_fmtint(sChallengeResponseAuthentication,
1717             o->challenge_response_authentication);
1718         dump_cfg_fmtint(sPrintMotd, o->print_motd);
1719         dump_cfg_fmtint(sPrintLastLog, o->print_lastlog);
1720         dump_cfg_fmtint(sX11Forwarding, o->x11_forwarding);
1721         dump_cfg_fmtint(sX11UseLocalhost, o->x11_use_localhost);
1722         dump_cfg_fmtint(sStrictModes, o->strict_modes);
1723         dump_cfg_fmtint(sTCPKeepAlive, o->tcp_keep_alive);
1724         dump_cfg_fmtint(sEmptyPasswd, o->permit_empty_passwd);
1725         dump_cfg_fmtint(sPermitUserEnvironment, o->permit_user_env);
1726         dump_cfg_fmtint(sUseLogin, o->use_login);
1727         dump_cfg_fmtint(sCompression, o->compression);
1728         dump_cfg_fmtint(sGatewayPorts, o->gateway_ports);
1729         dump_cfg_fmtint(sUseDNS, o->use_dns);
1730         dump_cfg_fmtint(sAllowTcpForwarding, o->allow_tcp_forwarding);
1731         dump_cfg_fmtint(sUsePrivilegeSeparation, use_privsep);
1732
1733         /* string arguments */
1734         dump_cfg_string(sPidFile, o->pid_file);
1735         dump_cfg_string(sXAuthLocation, o->xauth_location);
1736         dump_cfg_string(sCiphers, o->ciphers);
1737         dump_cfg_string(sMacs, o->macs);
1738         dump_cfg_string(sBanner, o->banner);
1739         dump_cfg_string(sAuthorizedKeysFile, o->authorized_keys_file);
1740         dump_cfg_string(sAuthorizedKeysFile2, o->authorized_keys_file2);
1741         dump_cfg_string(sForceCommand, o->adm_forced_command);
1742         dump_cfg_string(sChrootDirectory, o->chroot_directory);
1743         dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
1744         dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
1745         dump_cfg_string(sAuthorizedPrincipalsFile,
1746             o->authorized_principals_file);
1747
1748         /* string arguments requiring a lookup */
1749         dump_cfg_string(sLogLevel, log_level_name(o->log_level));
1750         dump_cfg_string(sLogFacility, log_facility_name(o->log_facility));
1751
1752         /* string array arguments */
1753         dump_cfg_strarray(sHostKeyFile, o->num_host_key_files,
1754              o->host_key_files);
1755         dump_cfg_strarray(sHostKeyFile, o->num_host_cert_files,
1756              o->host_cert_files);
1757         dump_cfg_strarray(sAllowUsers, o->num_allow_users, o->allow_users);
1758         dump_cfg_strarray(sDenyUsers, o->num_deny_users, o->deny_users);
1759         dump_cfg_strarray(sAllowGroups, o->num_allow_groups, o->allow_groups);
1760         dump_cfg_strarray(sDenyGroups, o->num_deny_groups, o->deny_groups);
1761         dump_cfg_strarray(sAcceptEnv, o->num_accept_env, o->accept_env);
1762
1763         /* other arguments */
1764         for (i = 0; i < o->num_subsystems; i++)
1765                 printf("subsystem %s %s\n", o->subsystem_name[i],
1766                     o->subsystem_args[i]);
1767
1768         printf("maxstartups %d:%d:%d\n", o->max_startups_begin,
1769             o->max_startups_rate, o->max_startups);
1770
1771         for (i = 0; tunmode_desc[i].val != -1; i++)
1772                 if (tunmode_desc[i].val == o->permit_tun) {
1773                         s = tunmode_desc[i].text;
1774                         break;
1775                 }
1776         dump_cfg_string(sPermitTunnel, s);
1777
1778         printf("ipqos 0x%02x 0x%02x\n", o->ip_qos_interactive, o->ip_qos_bulk);
1779
1780         channel_print_adm_permitted_opens();
1781 }