1*ba1276acSMatthew Dillon /*
2*ba1276acSMatthew Dillon * Copyright (c) 2012,2023 Damien Miller <djm@mindrot.org>
3*ba1276acSMatthew Dillon *
4*ba1276acSMatthew Dillon * Permission to use, copy, modify, and distribute this software for any
5*ba1276acSMatthew Dillon * purpose with or without fee is hereby granted, provided that the above
6*ba1276acSMatthew Dillon * copyright notice and this permission notice appear in all copies.
7*ba1276acSMatthew Dillon *
8*ba1276acSMatthew Dillon * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9*ba1276acSMatthew Dillon * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10*ba1276acSMatthew Dillon * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11*ba1276acSMatthew Dillon * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12*ba1276acSMatthew Dillon * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13*ba1276acSMatthew Dillon * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14*ba1276acSMatthew Dillon * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15*ba1276acSMatthew Dillon */
16*ba1276acSMatthew Dillon
17*ba1276acSMatthew Dillon #include "includes.h"
18*ba1276acSMatthew Dillon
19*ba1276acSMatthew Dillon #include <sys/types.h>
20*ba1276acSMatthew Dillon
21*ba1276acSMatthew Dillon #include <stdlib.h>
22*ba1276acSMatthew Dillon #include <string.h>
23*ba1276acSMatthew Dillon
24*ba1276acSMatthew Dillon #include "log.h"
25*ba1276acSMatthew Dillon #include "misc.h"
26*ba1276acSMatthew Dillon #include "servconf.h"
27*ba1276acSMatthew Dillon #include "xmalloc.h"
28*ba1276acSMatthew Dillon #include "hostfile.h"
29*ba1276acSMatthew Dillon #include "auth.h"
30*ba1276acSMatthew Dillon
31*ba1276acSMatthew Dillon extern ServerOptions options;
32*ba1276acSMatthew Dillon
33*ba1276acSMatthew Dillon /*
34*ba1276acSMatthew Dillon * Configuration of enabled authentication methods. Separate from the rest of
35*ba1276acSMatthew Dillon * auth2-*.c because we want to query it during server configuration validity
36*ba1276acSMatthew Dillon * checking in the sshd listener process without pulling all the auth code in
37*ba1276acSMatthew Dillon * too.
38*ba1276acSMatthew Dillon */
39*ba1276acSMatthew Dillon
40*ba1276acSMatthew Dillon /* "none" is allowed only one time and it is cleared by userauth_none() later */
41*ba1276acSMatthew Dillon int none_enabled = 1;
42*ba1276acSMatthew Dillon struct authmethod_cfg methodcfg_none = {
43*ba1276acSMatthew Dillon "none",
44*ba1276acSMatthew Dillon NULL,
45*ba1276acSMatthew Dillon &none_enabled
46*ba1276acSMatthew Dillon };
47*ba1276acSMatthew Dillon struct authmethod_cfg methodcfg_pubkey = {
48*ba1276acSMatthew Dillon "publickey",
49*ba1276acSMatthew Dillon "publickey-hostbound-v00@openssh.com",
50*ba1276acSMatthew Dillon &options.pubkey_authentication
51*ba1276acSMatthew Dillon };
52*ba1276acSMatthew Dillon #ifdef GSSAPI
53*ba1276acSMatthew Dillon struct authmethod_cfg methodcfg_gssapi = {
54*ba1276acSMatthew Dillon "gssapi-with-mic",
55*ba1276acSMatthew Dillon NULL,
56*ba1276acSMatthew Dillon &options.gss_authentication
57*ba1276acSMatthew Dillon };
58*ba1276acSMatthew Dillon #endif
59*ba1276acSMatthew Dillon struct authmethod_cfg methodcfg_passwd = {
60*ba1276acSMatthew Dillon "password",
61*ba1276acSMatthew Dillon NULL,
62*ba1276acSMatthew Dillon &options.password_authentication
63*ba1276acSMatthew Dillon };
64*ba1276acSMatthew Dillon struct authmethod_cfg methodcfg_kbdint = {
65*ba1276acSMatthew Dillon "keyboard-interactive",
66*ba1276acSMatthew Dillon NULL,
67*ba1276acSMatthew Dillon &options.kbd_interactive_authentication
68*ba1276acSMatthew Dillon };
69*ba1276acSMatthew Dillon struct authmethod_cfg methodcfg_hostbased = {
70*ba1276acSMatthew Dillon "hostbased",
71*ba1276acSMatthew Dillon NULL,
72*ba1276acSMatthew Dillon &options.hostbased_authentication
73*ba1276acSMatthew Dillon };
74*ba1276acSMatthew Dillon
75*ba1276acSMatthew Dillon static struct authmethod_cfg *authmethod_cfgs[] = {
76*ba1276acSMatthew Dillon &methodcfg_none,
77*ba1276acSMatthew Dillon &methodcfg_pubkey,
78*ba1276acSMatthew Dillon #ifdef GSSAPI
79*ba1276acSMatthew Dillon &methodcfg_gssapi,
80*ba1276acSMatthew Dillon #endif
81*ba1276acSMatthew Dillon &methodcfg_passwd,
82*ba1276acSMatthew Dillon &methodcfg_kbdint,
83*ba1276acSMatthew Dillon &methodcfg_hostbased,
84*ba1276acSMatthew Dillon NULL
85*ba1276acSMatthew Dillon };
86*ba1276acSMatthew Dillon
87*ba1276acSMatthew Dillon /*
88*ba1276acSMatthew Dillon * Check a comma-separated list of methods for validity. If need_enable is
89*ba1276acSMatthew Dillon * non-zero, then also require that the methods are enabled.
90*ba1276acSMatthew Dillon * Returns 0 on success or -1 if the methods list is invalid.
91*ba1276acSMatthew Dillon */
92*ba1276acSMatthew Dillon int
auth2_methods_valid(const char * _methods,int need_enable)93*ba1276acSMatthew Dillon auth2_methods_valid(const char *_methods, int need_enable)
94*ba1276acSMatthew Dillon {
95*ba1276acSMatthew Dillon char *methods, *omethods, *method, *p;
96*ba1276acSMatthew Dillon u_int i, found;
97*ba1276acSMatthew Dillon int ret = -1;
98*ba1276acSMatthew Dillon const struct authmethod_cfg *cfg;
99*ba1276acSMatthew Dillon
100*ba1276acSMatthew Dillon if (*_methods == '\0') {
101*ba1276acSMatthew Dillon error("empty authentication method list");
102*ba1276acSMatthew Dillon return -1;
103*ba1276acSMatthew Dillon }
104*ba1276acSMatthew Dillon omethods = methods = xstrdup(_methods);
105*ba1276acSMatthew Dillon while ((method = strsep(&methods, ",")) != NULL) {
106*ba1276acSMatthew Dillon for (found = i = 0; !found && authmethod_cfgs[i] != NULL; i++) {
107*ba1276acSMatthew Dillon cfg = authmethod_cfgs[i];
108*ba1276acSMatthew Dillon if ((p = strchr(method, ':')) != NULL)
109*ba1276acSMatthew Dillon *p = '\0';
110*ba1276acSMatthew Dillon if (strcmp(method, cfg->name) != 0)
111*ba1276acSMatthew Dillon continue;
112*ba1276acSMatthew Dillon if (need_enable) {
113*ba1276acSMatthew Dillon if (cfg->enabled == NULL ||
114*ba1276acSMatthew Dillon *(cfg->enabled) == 0) {
115*ba1276acSMatthew Dillon error("Disabled method \"%s\" in "
116*ba1276acSMatthew Dillon "AuthenticationMethods list \"%s\"",
117*ba1276acSMatthew Dillon method, _methods);
118*ba1276acSMatthew Dillon goto out;
119*ba1276acSMatthew Dillon }
120*ba1276acSMatthew Dillon }
121*ba1276acSMatthew Dillon found = 1;
122*ba1276acSMatthew Dillon break;
123*ba1276acSMatthew Dillon }
124*ba1276acSMatthew Dillon if (!found) {
125*ba1276acSMatthew Dillon error("Unknown authentication method \"%s\" in list",
126*ba1276acSMatthew Dillon method);
127*ba1276acSMatthew Dillon goto out;
128*ba1276acSMatthew Dillon }
129*ba1276acSMatthew Dillon }
130*ba1276acSMatthew Dillon ret = 0;
131*ba1276acSMatthew Dillon out:
132*ba1276acSMatthew Dillon free(omethods);
133*ba1276acSMatthew Dillon return ret;
134*ba1276acSMatthew Dillon }
135