diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | Makefile.in | 4 | ||||
-rw-r--r-- | auth.h | 9 | ||||
-rw-r--r-- | auth2-hostbased.c | 182 | ||||
-rw-r--r-- | auth2-kbdint.c | 69 | ||||
-rw-r--r-- | auth2-none.c | 111 | ||||
-rw-r--r-- | auth2-passwd.c | 65 | ||||
-rw-r--r-- | auth2-pubkey.c | 283 | ||||
-rw-r--r-- | auth2.c | 186 |
9 files changed, 726 insertions, 189 deletions
@@ -31,6 +31,10 @@ | |||
31 | - markus@cvs.openbsd.org 2002/05/25 08:50:39 | 31 | - markus@cvs.openbsd.org 2002/05/25 08:50:39 |
32 | [sshconnect2.c] | 32 | [sshconnect2.c] |
33 | execlp->execl; from stevesk | 33 | execlp->execl; from stevesk |
34 | - markus@cvs.openbsd.org 2002/05/25 18:51:07 | ||
35 | [auth.h auth2.c auth2-hostbased.c auth2-kbdint.c auth2-none.c | ||
36 | auth2-passwd.c auth2-pubkey.c Makefile.in] | ||
37 | split auth2.c into one file per method; ok provos@/deraadt@ | ||
34 | 38 | ||
35 | 20020604 | 39 | 20020604 |
36 | - (stevesk) [channels.c] bug #164 patch from YOSHIFUJI Hideaki (changed | 40 | - (stevesk) [channels.c] bug #164 patch from YOSHIFUJI Hideaki (changed |
@@ -715,4 +719,4 @@ | |||
715 | - (stevesk) entropy.c: typo in debug message | 719 | - (stevesk) entropy.c: typo in debug message |
716 | - (djm) ssh-keygen -i needs seeded RNG; report from markus@ | 720 | - (djm) ssh-keygen -i needs seeded RNG; report from markus@ |
717 | 721 | ||
718 | $Id: ChangeLog,v 1.2152 2002/06/06 20:05:57 mouring Exp $ | 722 | $Id: ChangeLog,v 1.2153 2002/06/06 20:27:55 mouring Exp $ |
diff --git a/Makefile.in b/Makefile.in index ec235f827..4001d68a8 100644 --- a/Makefile.in +++ b/Makefile.in | |||
@@ -1,4 +1,4 @@ | |||
1 | # $Id: Makefile.in,v 1.209 2002/06/06 19:57:33 mouring Exp $ | 1 | # $Id: Makefile.in,v 1.210 2002/06/06 20:27:55 mouring Exp $ |
2 | 2 | ||
3 | # uncomment if you run a non bourne compatable shell. Ie. csh | 3 | # uncomment if you run a non bourne compatable shell. Ie. csh |
4 | #SHELL = @SH@ | 4 | #SHELL = @SH@ |
@@ -61,7 +61,7 @@ LIBSSH_OBJS=atomicio.o authfd.o authfile.o bufaux.o buffer.o canohost.o channels | |||
61 | 61 | ||
62 | SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o sshtty.o readconf.o clientloop.o | 62 | SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o sshtty.o readconf.o clientloop.o |
63 | 63 | ||
64 | SSHDOBJS= sshd.o auth.o auth1.o auth2.o auth-chall.o auth2-chall.o auth-rhosts.o auth-options.o auth-krb4.o auth-krb5.o auth-pam.o auth2-pam.o auth-passwd.o auth-rsa.o auth-rh-rsa.o auth-sia.o sshpty.o sshlogin.o loginrec.o servconf.o serverloop.o md5crypt.o session.o groupaccess.o auth-skey.o auth-bsdauth.o monitor_mm.o monitor.o | 64 | SSHDOBJS= sshd.o auth.o auth1.o auth2.o auth2-hostbased.o auth2-kbdint.o auth2-none.o auth2-passwd.o auth2-pubkey.o auth-chall.o auth2-chall.o auth-rhosts.o auth-options.o auth-krb4.o auth-krb5.o auth-pam.o auth2-pam.o auth-passwd.o auth-rsa.o auth-rh-rsa.o auth-sia.o sshpty.o sshlogin.o loginrec.o servconf.o serverloop.o md5crypt.o session.o groupaccess.o auth-skey.o auth-bsdauth.o monitor_mm.o monitor.o |
65 | 65 | ||
66 | MANPAGES = scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-rand-helper.8.out | 66 | MANPAGES = scp.1.out ssh-add.1.out ssh-agent.1.out ssh-keygen.1.out ssh-keyscan.1.out ssh.1.out sshd.8.out sftp-server.8.out sftp.1.out ssh-rand-helper.8.out |
67 | MANPAGES_IN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-rand-helper.8 | 67 | MANPAGES_IN = scp.1 ssh-add.1 ssh-agent.1 ssh-keygen.1 ssh-keyscan.1 ssh.1 sshd.8 sftp-server.8 sftp.1 ssh-rand-helper.8 |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth.h,v 1.37 2002/05/13 20:44:58 markus Exp $ */ | 1 | /* $OpenBSD: auth.h,v 1.38 2002/05/25 18:51:07 markus Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
@@ -100,6 +100,13 @@ BIGNUM *auth_rsa_generate_challenge(Key *); | |||
100 | int auth_rsa_verify_response(Key *, BIGNUM *, u_char[]); | 100 | int auth_rsa_verify_response(Key *, BIGNUM *, u_char[]); |
101 | int auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **); | 101 | int auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **); |
102 | 102 | ||
103 | /* ssh2 methods */ | ||
104 | int userauth_none(Authctxt *); | ||
105 | int userauth_passwd(Authctxt *); | ||
106 | int userauth_pubkey(Authctxt *); | ||
107 | int userauth_hostbased(Authctxt *); | ||
108 | int userauth_kbdint(Authctxt *); | ||
109 | |||
103 | int auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, Key *); | 110 | int auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, Key *); |
104 | int hostbased_key_allowed(struct passwd *, const char *, char *, Key *); | 111 | int hostbased_key_allowed(struct passwd *, const char *, char *, Key *); |
105 | int user_key_allowed(struct passwd *, Key *); | 112 | int user_key_allowed(struct passwd *, Key *); |
diff --git a/auth2-hostbased.c b/auth2-hostbased.c new file mode 100644 index 000000000..2bde7bb79 --- /dev/null +++ b/auth2-hostbased.c | |||
@@ -0,0 +1,182 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * 1. Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * 2. Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * | ||
13 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | ||
14 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
15 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
16 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
17 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
18 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
19 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
20 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
22 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
23 | */ | ||
24 | |||
25 | #include "includes.h" | ||
26 | RCSID("$OpenBSD: auth2-hostbased.c,v 1.2 2002/05/31 11:35:15 markus Exp $"); | ||
27 | |||
28 | #include "ssh2.h" | ||
29 | #include "xmalloc.h" | ||
30 | #include "packet.h" | ||
31 | #include "buffer.h" | ||
32 | #include "log.h" | ||
33 | #include "servconf.h" | ||
34 | #include "compat.h" | ||
35 | #include "bufaux.h" | ||
36 | #include "auth.h" | ||
37 | #include "key.h" | ||
38 | #include "canohost.h" | ||
39 | #include "monitor_wrap.h" | ||
40 | #include "pathnames.h" | ||
41 | |||
42 | /* import */ | ||
43 | extern ServerOptions options; | ||
44 | extern u_char *session_id2; | ||
45 | extern int session_id2_len; | ||
46 | |||
47 | static int | ||
48 | userauth_hostbased(Authctxt *authctxt) | ||
49 | { | ||
50 | Buffer b; | ||
51 | Key *key = NULL; | ||
52 | char *pkalg, *cuser, *chost, *service; | ||
53 | u_char *pkblob, *sig; | ||
54 | u_int alen, blen, slen; | ||
55 | int pktype; | ||
56 | int authenticated = 0; | ||
57 | |||
58 | if (!authctxt->valid) { | ||
59 | debug2("userauth_hostbased: disabled because of invalid user"); | ||
60 | return 0; | ||
61 | } | ||
62 | pkalg = packet_get_string(&alen); | ||
63 | pkblob = packet_get_string(&blen); | ||
64 | chost = packet_get_string(NULL); | ||
65 | cuser = packet_get_string(NULL); | ||
66 | sig = packet_get_string(&slen); | ||
67 | |||
68 | debug("userauth_hostbased: cuser %s chost %s pkalg %s slen %d", | ||
69 | cuser, chost, pkalg, slen); | ||
70 | #ifdef DEBUG_PK | ||
71 | debug("signature:"); | ||
72 | buffer_init(&b); | ||
73 | buffer_append(&b, sig, slen); | ||
74 | buffer_dump(&b); | ||
75 | buffer_free(&b); | ||
76 | #endif | ||
77 | pktype = key_type_from_name(pkalg); | ||
78 | if (pktype == KEY_UNSPEC) { | ||
79 | /* this is perfectly legal */ | ||
80 | log("userauth_hostbased: unsupported " | ||
81 | "public key algorithm: %s", pkalg); | ||
82 | goto done; | ||
83 | } | ||
84 | key = key_from_blob(pkblob, blen); | ||
85 | if (key == NULL) { | ||
86 | error("userauth_hostbased: cannot decode key: %s", pkalg); | ||
87 | goto done; | ||
88 | } | ||
89 | if (key->type != pktype) { | ||
90 | error("userauth_hostbased: type mismatch for decoded key " | ||
91 | "(received %d, expected %d)", key->type, pktype); | ||
92 | goto done; | ||
93 | } | ||
94 | service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" : | ||
95 | authctxt->service; | ||
96 | buffer_init(&b); | ||
97 | buffer_put_string(&b, session_id2, session_id2_len); | ||
98 | /* reconstruct packet */ | ||
99 | buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); | ||
100 | buffer_put_cstring(&b, authctxt->user); | ||
101 | buffer_put_cstring(&b, service); | ||
102 | buffer_put_cstring(&b, "hostbased"); | ||
103 | buffer_put_string(&b, pkalg, alen); | ||
104 | buffer_put_string(&b, pkblob, blen); | ||
105 | buffer_put_cstring(&b, chost); | ||
106 | buffer_put_cstring(&b, cuser); | ||
107 | #ifdef DEBUG_PK | ||
108 | buffer_dump(&b); | ||
109 | #endif | ||
110 | /* test for allowed key and correct signature */ | ||
111 | authenticated = 0; | ||
112 | if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) && | ||
113 | PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), | ||
114 | buffer_len(&b))) == 1) | ||
115 | authenticated = 1; | ||
116 | |||
117 | buffer_clear(&b); | ||
118 | done: | ||
119 | debug2("userauth_hostbased: authenticated %d", authenticated); | ||
120 | if (key != NULL) | ||
121 | key_free(key); | ||
122 | xfree(pkalg); | ||
123 | xfree(pkblob); | ||
124 | xfree(cuser); | ||
125 | xfree(chost); | ||
126 | xfree(sig); | ||
127 | return authenticated; | ||
128 | } | ||
129 | |||
130 | /* return 1 if given hostkey is allowed */ | ||
131 | int | ||
132 | hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, | ||
133 | Key *key) | ||
134 | { | ||
135 | const char *resolvedname, *ipaddr, *lookup; | ||
136 | HostStatus host_status; | ||
137 | int len; | ||
138 | |||
139 | resolvedname = get_canonical_hostname(options.verify_reverse_mapping); | ||
140 | ipaddr = get_remote_ipaddr(); | ||
141 | |||
142 | debug2("userauth_hostbased: chost %s resolvedname %s ipaddr %s", | ||
143 | chost, resolvedname, ipaddr); | ||
144 | |||
145 | if (options.hostbased_uses_name_from_packet_only) { | ||
146 | if (auth_rhosts2(pw, cuser, chost, chost) == 0) | ||
147 | return 0; | ||
148 | lookup = chost; | ||
149 | } else { | ||
150 | if (((len = strlen(chost)) > 0) && chost[len - 1] == '.') { | ||
151 | debug2("stripping trailing dot from chost %s", chost); | ||
152 | chost[len - 1] = '\0'; | ||
153 | } | ||
154 | if (strcasecmp(resolvedname, chost) != 0) | ||
155 | log("userauth_hostbased mismatch: " | ||
156 | "client sends %s, but we resolve %s to %s", | ||
157 | chost, ipaddr, resolvedname); | ||
158 | if (auth_rhosts2(pw, cuser, resolvedname, ipaddr) == 0) | ||
159 | return 0; | ||
160 | lookup = resolvedname; | ||
161 | } | ||
162 | debug2("userauth_hostbased: access allowed by auth_rhosts2"); | ||
163 | |||
164 | host_status = check_key_in_hostfiles(pw, key, lookup, | ||
165 | _PATH_SSH_SYSTEM_HOSTFILE, | ||
166 | options.ignore_user_known_hosts ? NULL : _PATH_SSH_USER_HOSTFILE); | ||
167 | |||
168 | /* backward compat if no key has been found. */ | ||
169 | if (host_status == HOST_NEW) | ||
170 | host_status = check_key_in_hostfiles(pw, key, lookup, | ||
171 | _PATH_SSH_SYSTEM_HOSTFILE2, | ||
172 | options.ignore_user_known_hosts ? NULL : | ||
173 | _PATH_SSH_USER_HOSTFILE2); | ||
174 | |||
175 | return (host_status == HOST_OK); | ||
176 | } | ||
177 | |||
178 | Authmethod method_hostbased = { | ||
179 | "hostbased", | ||
180 | userauth_hostbased, | ||
181 | &options.hostbased_authentication | ||
182 | }; | ||
diff --git a/auth2-kbdint.c b/auth2-kbdint.c new file mode 100644 index 000000000..e60992881 --- /dev/null +++ b/auth2-kbdint.c | |||
@@ -0,0 +1,69 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * 1. Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * 2. Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * | ||
13 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | ||
14 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
15 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
16 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
17 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
18 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
19 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
20 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
22 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
23 | */ | ||
24 | |||
25 | #include "includes.h" | ||
26 | RCSID("$OpenBSD: auth2-kbdint.c,v 1.2 2002/05/31 11:35:15 markus Exp $"); | ||
27 | |||
28 | #include "packet.h" | ||
29 | #include "auth.h" | ||
30 | #include "log.h" | ||
31 | #include "servconf.h" | ||
32 | #include "xmalloc.h" | ||
33 | |||
34 | /* import */ | ||
35 | extern ServerOptions options; | ||
36 | |||
37 | static int | ||
38 | userauth_kbdint(Authctxt *authctxt) | ||
39 | { | ||
40 | int authenticated = 0; | ||
41 | char *lang, *devs; | ||
42 | |||
43 | lang = packet_get_string(NULL); | ||
44 | devs = packet_get_string(NULL); | ||
45 | packet_check_eom(); | ||
46 | |||
47 | debug("keyboard-interactive devs %s", devs); | ||
48 | |||
49 | if (options.challenge_response_authentication) | ||
50 | authenticated = auth2_challenge(authctxt, devs); | ||
51 | |||
52 | #ifdef USE_PAM | ||
53 | if (authenticated == 0 && options.pam_authentication_via_kbd_int) | ||
54 | authenticated = auth2_pam(authctxt); | ||
55 | #endif | ||
56 | xfree(devs); | ||
57 | xfree(lang); | ||
58 | #ifdef HAVE_CYGWIN | ||
59 | if (check_nt_auth(0, authctxt->pw) == 0) | ||
60 | return(0); | ||
61 | #endif | ||
62 | return authenticated; | ||
63 | } | ||
64 | |||
65 | Authmethod method_kbdint = { | ||
66 | "keyboard-interactive", | ||
67 | userauth_kbdint, | ||
68 | &options.kbd_interactive_authentication | ||
69 | }; | ||
diff --git a/auth2-none.c b/auth2-none.c new file mode 100644 index 000000000..30337fd6d --- /dev/null +++ b/auth2-none.c | |||
@@ -0,0 +1,111 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * 1. Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * 2. Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * | ||
13 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | ||
14 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
15 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
16 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
17 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
18 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
19 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
20 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
22 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
23 | */ | ||
24 | |||
25 | #include "includes.h" | ||
26 | RCSID("$OpenBSD: auth2-none.c,v 1.2 2002/05/31 11:35:15 markus Exp $"); | ||
27 | |||
28 | #include "auth.h" | ||
29 | #include "xmalloc.h" | ||
30 | #include "packet.h" | ||
31 | #include "log.h" | ||
32 | #include "servconf.h" | ||
33 | #include "atomicio.h" | ||
34 | #include "compat.h" | ||
35 | #include "ssh2.h" | ||
36 | #include "monitor_wrap.h" | ||
37 | |||
38 | /* import */ | ||
39 | extern ServerOptions options; | ||
40 | |||
41 | /* "none" is allowed only one time */ | ||
42 | static int none_enabled = 1; | ||
43 | |||
44 | char * | ||
45 | auth2_read_banner(void) | ||
46 | { | ||
47 | struct stat st; | ||
48 | char *banner = NULL; | ||
49 | off_t len, n; | ||
50 | int fd; | ||
51 | |||
52 | if ((fd = open(options.banner, O_RDONLY)) == -1) | ||
53 | return (NULL); | ||
54 | if (fstat(fd, &st) == -1) { | ||
55 | close(fd); | ||
56 | return (NULL); | ||
57 | } | ||
58 | len = st.st_size; | ||
59 | banner = xmalloc(len + 1); | ||
60 | n = atomicio(read, fd, banner, len); | ||
61 | close(fd); | ||
62 | |||
63 | if (n != len) { | ||
64 | free(banner); | ||
65 | return (NULL); | ||
66 | } | ||
67 | banner[n] = '\0'; | ||
68 | |||
69 | return (banner); | ||
70 | } | ||
71 | |||
72 | static void | ||
73 | userauth_banner(void) | ||
74 | { | ||
75 | char *banner = NULL; | ||
76 | |||
77 | if (options.banner == NULL || (datafellows & SSH_BUG_BANNER)) | ||
78 | return; | ||
79 | |||
80 | if ((banner = PRIVSEP(auth2_read_banner())) == NULL) | ||
81 | goto done; | ||
82 | |||
83 | packet_start(SSH2_MSG_USERAUTH_BANNER); | ||
84 | packet_put_cstring(banner); | ||
85 | packet_put_cstring(""); /* language, unused */ | ||
86 | packet_send(); | ||
87 | debug("userauth_banner: sent"); | ||
88 | done: | ||
89 | if (banner) | ||
90 | xfree(banner); | ||
91 | return; | ||
92 | } | ||
93 | |||
94 | static int | ||
95 | userauth_none(Authctxt *authctxt) | ||
96 | { | ||
97 | none_enabled = 0; | ||
98 | packet_check_eom(); | ||
99 | userauth_banner(); | ||
100 | #ifdef HAVE_CYGWIN | ||
101 | if (check_nt_auth(1, authctxt->pw) == 0) | ||
102 | return(0); | ||
103 | #endif | ||
104 | return (authctxt->valid ? PRIVSEP(auth_password(authctxt, "")) : 0); | ||
105 | } | ||
106 | |||
107 | Authmethod method_none = { | ||
108 | "none", | ||
109 | userauth_none, | ||
110 | &none_enabled | ||
111 | }; | ||
diff --git a/auth2-passwd.c b/auth2-passwd.c new file mode 100644 index 000000000..ffa279594 --- /dev/null +++ b/auth2-passwd.c | |||
@@ -0,0 +1,65 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * 1. Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * 2. Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * | ||
13 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | ||
14 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
15 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
16 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
17 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
18 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
19 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
20 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
22 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
23 | */ | ||
24 | |||
25 | #include "includes.h" | ||
26 | RCSID("$OpenBSD: auth2-passwd.c,v 1.2 2002/05/31 11:35:15 markus Exp $"); | ||
27 | |||
28 | #include "xmalloc.h" | ||
29 | #include "packet.h" | ||
30 | #include "log.h" | ||
31 | #include "auth.h" | ||
32 | #include "monitor_wrap.h" | ||
33 | #include "servconf.h" | ||
34 | |||
35 | /* import */ | ||
36 | extern ServerOptions options; | ||
37 | |||
38 | static int | ||
39 | userauth_passwd(Authctxt *authctxt) | ||
40 | { | ||
41 | char *password; | ||
42 | int authenticated = 0; | ||
43 | int change; | ||
44 | u_int len; | ||
45 | change = packet_get_char(); | ||
46 | if (change) | ||
47 | log("password change not supported"); | ||
48 | password = packet_get_string(&len); | ||
49 | packet_check_eom(); | ||
50 | if (authctxt->valid && | ||
51 | #ifdef HAVE_CYGWIN | ||
52 | check_nt_auth(1, authctxt->pw) && | ||
53 | #endif | ||
54 | PRIVSEP(auth_password(authctxt, password)) == 1) | ||
55 | authenticated = 1; | ||
56 | memset(password, 0, len); | ||
57 | xfree(password); | ||
58 | return authenticated; | ||
59 | } | ||
60 | |||
61 | Authmethod method_passwd = { | ||
62 | "password", | ||
63 | userauth_passwd, | ||
64 | &options.password_authentication | ||
65 | }; | ||
diff --git a/auth2-pubkey.c b/auth2-pubkey.c new file mode 100644 index 000000000..947bfed0b --- /dev/null +++ b/auth2-pubkey.c | |||
@@ -0,0 +1,283 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | ||
3 | * | ||
4 | * Redistribution and use in source and binary forms, with or without | ||
5 | * modification, are permitted provided that the following conditions | ||
6 | * are met: | ||
7 | * 1. Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * 2. Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * | ||
13 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | ||
14 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
15 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
16 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
17 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
18 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
19 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
20 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
22 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
23 | */ | ||
24 | |||
25 | #include "includes.h" | ||
26 | RCSID("$OpenBSD: auth2-pubkey.c,v 1.2 2002/05/31 11:35:15 markus Exp $"); | ||
27 | |||
28 | #include "ssh2.h" | ||
29 | #include "xmalloc.h" | ||
30 | #include "packet.h" | ||
31 | #include "buffer.h" | ||
32 | #include "log.h" | ||
33 | #include "servconf.h" | ||
34 | #include "compat.h" | ||
35 | #include "bufaux.h" | ||
36 | #include "auth.h" | ||
37 | #include "key.h" | ||
38 | #include "pathnames.h" | ||
39 | #include "uidswap.h" | ||
40 | #include "auth-options.h" | ||
41 | #include "canohost.h" | ||
42 | #include "monitor_wrap.h" | ||
43 | |||
44 | /* import */ | ||
45 | extern ServerOptions options; | ||
46 | extern u_char *session_id2; | ||
47 | extern int session_id2_len; | ||
48 | |||
49 | static int | ||
50 | userauth_pubkey(Authctxt *authctxt) | ||
51 | { | ||
52 | Buffer b; | ||
53 | Key *key = NULL; | ||
54 | char *pkalg; | ||
55 | u_char *pkblob, *sig; | ||
56 | u_int alen, blen, slen; | ||
57 | int have_sig, pktype; | ||
58 | int authenticated = 0; | ||
59 | |||
60 | if (!authctxt->valid) { | ||
61 | debug2("userauth_pubkey: disabled because of invalid user"); | ||
62 | return 0; | ||
63 | } | ||
64 | have_sig = packet_get_char(); | ||
65 | if (datafellows & SSH_BUG_PKAUTH) { | ||
66 | debug2("userauth_pubkey: SSH_BUG_PKAUTH"); | ||
67 | /* no explicit pkalg given */ | ||
68 | pkblob = packet_get_string(&blen); | ||
69 | buffer_init(&b); | ||
70 | buffer_append(&b, pkblob, blen); | ||
71 | /* so we have to extract the pkalg from the pkblob */ | ||
72 | pkalg = buffer_get_string(&b, &alen); | ||
73 | buffer_free(&b); | ||
74 | } else { | ||
75 | pkalg = packet_get_string(&alen); | ||
76 | pkblob = packet_get_string(&blen); | ||
77 | } | ||
78 | pktype = key_type_from_name(pkalg); | ||
79 | if (pktype == KEY_UNSPEC) { | ||
80 | /* this is perfectly legal */ | ||
81 | log("userauth_pubkey: unsupported public key algorithm: %s", | ||
82 | pkalg); | ||
83 | goto done; | ||
84 | } | ||
85 | key = key_from_blob(pkblob, blen); | ||
86 | if (key == NULL) { | ||
87 | error("userauth_pubkey: cannot decode key: %s", pkalg); | ||
88 | goto done; | ||
89 | } | ||
90 | if (key->type != pktype) { | ||
91 | error("userauth_pubkey: type mismatch for decoded key " | ||
92 | "(received %d, expected %d)", key->type, pktype); | ||
93 | goto done; | ||
94 | } | ||
95 | if (have_sig) { | ||
96 | sig = packet_get_string(&slen); | ||
97 | packet_check_eom(); | ||
98 | buffer_init(&b); | ||
99 | if (datafellows & SSH_OLD_SESSIONID) { | ||
100 | buffer_append(&b, session_id2, session_id2_len); | ||
101 | } else { | ||
102 | buffer_put_string(&b, session_id2, session_id2_len); | ||
103 | } | ||
104 | /* reconstruct packet */ | ||
105 | buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST); | ||
106 | buffer_put_cstring(&b, authctxt->user); | ||
107 | buffer_put_cstring(&b, | ||
108 | datafellows & SSH_BUG_PKSERVICE ? | ||
109 | "ssh-userauth" : | ||
110 | authctxt->service); | ||
111 | if (datafellows & SSH_BUG_PKAUTH) { | ||
112 | buffer_put_char(&b, have_sig); | ||
113 | } else { | ||
114 | buffer_put_cstring(&b, "publickey"); | ||
115 | buffer_put_char(&b, have_sig); | ||
116 | buffer_put_cstring(&b, pkalg); | ||
117 | } | ||
118 | buffer_put_string(&b, pkblob, blen); | ||
119 | #ifdef DEBUG_PK | ||
120 | buffer_dump(&b); | ||
121 | #endif | ||
122 | /* test for correct signature */ | ||
123 | authenticated = 0; | ||
124 | if (PRIVSEP(user_key_allowed(authctxt->pw, key)) && | ||
125 | PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b), | ||
126 | buffer_len(&b))) == 1) | ||
127 | authenticated = 1; | ||
128 | buffer_clear(&b); | ||
129 | xfree(sig); | ||
130 | } else { | ||
131 | debug("test whether pkalg/pkblob are acceptable"); | ||
132 | packet_check_eom(); | ||
133 | |||
134 | /* XXX fake reply and always send PK_OK ? */ | ||
135 | /* | ||
136 | * XXX this allows testing whether a user is allowed | ||
137 | * to login: if you happen to have a valid pubkey this | ||
138 | * message is sent. the message is NEVER sent at all | ||
139 | * if a user is not allowed to login. is this an | ||
140 | * issue? -markus | ||
141 | */ | ||
142 | if (PRIVSEP(user_key_allowed(authctxt->pw, key))) { | ||
143 | packet_start(SSH2_MSG_USERAUTH_PK_OK); | ||
144 | packet_put_string(pkalg, alen); | ||
145 | packet_put_string(pkblob, blen); | ||
146 | packet_send(); | ||
147 | packet_write_wait(); | ||
148 | authctxt->postponed = 1; | ||
149 | } | ||
150 | } | ||
151 | if (authenticated != 1) | ||
152 | auth_clear_options(); | ||
153 | done: | ||
154 | debug2("userauth_pubkey: authenticated %d pkalg %s", authenticated, pkalg); | ||
155 | if (key != NULL) | ||
156 | key_free(key); | ||
157 | xfree(pkalg); | ||
158 | xfree(pkblob); | ||
159 | #ifdef HAVE_CYGWIN | ||
160 | if (check_nt_auth(0, authctxt->pw) == 0) | ||
161 | return(0); | ||
162 | #endif | ||
163 | return authenticated; | ||
164 | } | ||
165 | |||
166 | /* return 1 if user allows given key */ | ||
167 | static int | ||
168 | user_key_allowed2(struct passwd *pw, Key *key, char *file) | ||
169 | { | ||
170 | char line[8192]; | ||
171 | int found_key = 0; | ||
172 | FILE *f; | ||
173 | u_long linenum = 0; | ||
174 | struct stat st; | ||
175 | Key *found; | ||
176 | char *fp; | ||
177 | |||
178 | if (pw == NULL) | ||
179 | return 0; | ||
180 | |||
181 | /* Temporarily use the user's uid. */ | ||
182 | temporarily_use_uid(pw); | ||
183 | |||
184 | debug("trying public key file %s", file); | ||
185 | |||
186 | /* Fail quietly if file does not exist */ | ||
187 | if (stat(file, &st) < 0) { | ||
188 | /* Restore the privileged uid. */ | ||
189 | restore_uid(); | ||
190 | return 0; | ||
191 | } | ||
192 | /* Open the file containing the authorized keys. */ | ||
193 | f = fopen(file, "r"); | ||
194 | if (!f) { | ||
195 | /* Restore the privileged uid. */ | ||
196 | restore_uid(); | ||
197 | return 0; | ||
198 | } | ||
199 | if (options.strict_modes && | ||
200 | secure_filename(f, file, pw, line, sizeof(line)) != 0) { | ||
201 | fclose(f); | ||
202 | log("Authentication refused: %s", line); | ||
203 | restore_uid(); | ||
204 | return 0; | ||
205 | } | ||
206 | |||
207 | found_key = 0; | ||
208 | found = key_new(key->type); | ||
209 | |||
210 | while (fgets(line, sizeof(line), f)) { | ||
211 | char *cp, *options = NULL; | ||
212 | linenum++; | ||
213 | /* Skip leading whitespace, empty and comment lines. */ | ||
214 | for (cp = line; *cp == ' ' || *cp == '\t'; cp++) | ||
215 | ; | ||
216 | if (!*cp || *cp == '\n' || *cp == '#') | ||
217 | continue; | ||
218 | |||
219 | if (key_read(found, &cp) != 1) { | ||
220 | /* no key? check if there are options for this key */ | ||
221 | int quoted = 0; | ||
222 | debug2("user_key_allowed: check options: '%s'", cp); | ||
223 | options = cp; | ||
224 | for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) { | ||
225 | if (*cp == '\\' && cp[1] == '"') | ||
226 | cp++; /* Skip both */ | ||
227 | else if (*cp == '"') | ||
228 | quoted = !quoted; | ||
229 | } | ||
230 | /* Skip remaining whitespace. */ | ||
231 | for (; *cp == ' ' || *cp == '\t'; cp++) | ||
232 | ; | ||
233 | if (key_read(found, &cp) != 1) { | ||
234 | debug2("user_key_allowed: advance: '%s'", cp); | ||
235 | /* still no key? advance to next line*/ | ||
236 | continue; | ||
237 | } | ||
238 | } | ||
239 | if (key_equal(found, key) && | ||
240 | auth_parse_options(pw, options, file, linenum) == 1) { | ||
241 | found_key = 1; | ||
242 | debug("matching key found: file %s, line %lu", | ||
243 | file, linenum); | ||
244 | fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX); | ||
245 | verbose("Found matching %s key: %s", | ||
246 | key_type(found), fp); | ||
247 | xfree(fp); | ||
248 | break; | ||
249 | } | ||
250 | } | ||
251 | restore_uid(); | ||
252 | fclose(f); | ||
253 | key_free(found); | ||
254 | if (!found_key) | ||
255 | debug2("key not found"); | ||
256 | return found_key; | ||
257 | } | ||
258 | |||
259 | /* check whether given key is in .ssh/authorized_keys* */ | ||
260 | int | ||
261 | user_key_allowed(struct passwd *pw, Key *key) | ||
262 | { | ||
263 | int success; | ||
264 | char *file; | ||
265 | |||
266 | file = authorized_keys_file(pw); | ||
267 | success = user_key_allowed2(pw, key, file); | ||
268 | xfree(file); | ||
269 | if (success) | ||
270 | return success; | ||
271 | |||
272 | /* try suffix "2" for backward compat, too */ | ||
273 | file = authorized_keys_file2(pw); | ||
274 | success = user_key_allowed2(pw, key, file); | ||
275 | xfree(file); | ||
276 | return success; | ||
277 | } | ||
278 | |||
279 | Authmethod method_pubkey = { | ||
280 | "publickey", | ||
281 | userauth_pubkey, | ||
282 | &options.pubkey_authentication | ||
283 | }; | ||
@@ -23,35 +23,18 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "includes.h" | 25 | #include "includes.h" |
26 | RCSID("$OpenBSD: auth2.c,v 1.91 2002/05/13 02:37:39 itojun Exp $"); | 26 | RCSID("$OpenBSD: auth2.c,v 1.92 2002/05/25 18:51:07 markus Exp $"); |
27 | |||
28 | #include <openssl/evp.h> | ||
29 | 27 | ||
30 | #include "ssh2.h" | 28 | #include "ssh2.h" |
31 | #include "xmalloc.h" | 29 | #include "xmalloc.h" |
32 | #include "rsa.h" | ||
33 | #include "sshpty.h" | ||
34 | #include "packet.h" | 30 | #include "packet.h" |
35 | #include "buffer.h" | ||
36 | #include "log.h" | 31 | #include "log.h" |
37 | #include "servconf.h" | 32 | #include "servconf.h" |
38 | #include "compat.h" | 33 | #include "compat.h" |
39 | #include "channels.h" | ||
40 | #include "bufaux.h" | ||
41 | #include "auth.h" | 34 | #include "auth.h" |
42 | #include "session.h" | ||
43 | #include "dispatch.h" | 35 | #include "dispatch.h" |
44 | #include "key.h" | ||
45 | #include "cipher.h" | ||
46 | #include "kex.h" | ||
47 | #include "pathnames.h" | 36 | #include "pathnames.h" |
48 | #include "uidswap.h" | ||
49 | #include "auth-options.h" | ||
50 | #include "hostfile.h" | ||
51 | #include "canohost.h" | ||
52 | #include "match.h" | ||
53 | #include "monitor_wrap.h" | 37 | #include "monitor_wrap.h" |
54 | #include "atomicio.h" | ||
55 | 38 | ||
56 | /* import */ | 39 | /* import */ |
57 | extern ServerOptions options; | 40 | extern ServerOptions options; |
@@ -80,12 +63,6 @@ int user_key_allowed(struct passwd *, Key *); | |||
80 | int hostbased_key_allowed(struct passwd *, const char *, char *, Key *); | 63 | int hostbased_key_allowed(struct passwd *, const char *, char *, Key *); |
81 | 64 | ||
82 | /* auth */ | 65 | /* auth */ |
83 | static void userauth_banner(void); | ||
84 | static int userauth_none(Authctxt *); | ||
85 | static int userauth_passwd(Authctxt *); | ||
86 | static int userauth_pubkey(Authctxt *); | ||
87 | static int userauth_hostbased(Authctxt *); | ||
88 | static int userauth_kbdint(Authctxt *); | ||
89 | 66 | ||
90 | Authmethod authmethods[] = { | 67 | Authmethod authmethods[] = { |
91 | {"none", | 68 | {"none", |
@@ -651,164 +628,3 @@ authmethod_lookup(const char *name) | |||
651 | debug2("Unrecognized authentication method name: %s", name ? name : "NULL"); | 628 | debug2("Unrecognized authentication method name: %s", name ? name : "NULL"); |
652 | return NULL; | 629 | return NULL; |
653 | } | 630 | } |
654 | |||
655 | /* return 1 if user allows given key */ | ||
656 | static int | ||
657 | user_key_allowed2(struct passwd *pw, Key *key, char *file) | ||
658 | { | ||
659 | char line[8192]; | ||
660 | int found_key = 0; | ||
661 | FILE *f; | ||
662 | u_long linenum = 0; | ||
663 | struct stat st; | ||
664 | Key *found; | ||
665 | char *fp; | ||
666 | |||
667 | if (pw == NULL) | ||
668 | return 0; | ||
669 | |||
670 | /* Temporarily use the user's uid. */ | ||
671 | temporarily_use_uid(pw); | ||
672 | |||
673 | debug("trying public key file %s", file); | ||
674 | |||
675 | /* Fail quietly if file does not exist */ | ||
676 | if (stat(file, &st) < 0) { | ||
677 | /* Restore the privileged uid. */ | ||
678 | restore_uid(); | ||
679 | return 0; | ||
680 | } | ||
681 | /* Open the file containing the authorized keys. */ | ||
682 | f = fopen(file, "r"); | ||
683 | if (!f) { | ||
684 | /* Restore the privileged uid. */ | ||
685 | restore_uid(); | ||
686 | return 0; | ||
687 | } | ||
688 | if (options.strict_modes && | ||
689 | secure_filename(f, file, pw, line, sizeof(line)) != 0) { | ||
690 | fclose(f); | ||
691 | log("Authentication refused: %s", line); | ||
692 | restore_uid(); | ||
693 | return 0; | ||
694 | } | ||
695 | |||
696 | found_key = 0; | ||
697 | found = key_new(key->type); | ||
698 | |||
699 | while (fgets(line, sizeof(line), f)) { | ||
700 | char *cp, *options = NULL; | ||
701 | linenum++; | ||
702 | /* Skip leading whitespace, empty and comment lines. */ | ||
703 | for (cp = line; *cp == ' ' || *cp == '\t'; cp++) | ||
704 | ; | ||
705 | if (!*cp || *cp == '\n' || *cp == '#') | ||
706 | continue; | ||
707 | |||
708 | if (key_read(found, &cp) != 1) { | ||
709 | /* no key? check if there are options for this key */ | ||
710 | int quoted = 0; | ||
711 | debug2("user_key_allowed: check options: '%s'", cp); | ||
712 | options = cp; | ||
713 | for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) { | ||
714 | if (*cp == '\\' && cp[1] == '"') | ||
715 | cp++; /* Skip both */ | ||
716 | else if (*cp == '"') | ||
717 | quoted = !quoted; | ||
718 | } | ||
719 | /* Skip remaining whitespace. */ | ||
720 | for (; *cp == ' ' || *cp == '\t'; cp++) | ||
721 | ; | ||
722 | if (key_read(found, &cp) != 1) { | ||
723 | debug2("user_key_allowed: advance: '%s'", cp); | ||
724 | /* still no key? advance to next line*/ | ||
725 | continue; | ||
726 | } | ||
727 | } | ||
728 | if (key_equal(found, key) && | ||
729 | auth_parse_options(pw, options, file, linenum) == 1) { | ||
730 | found_key = 1; | ||
731 | debug("matching key found: file %s, line %lu", | ||
732 | file, linenum); | ||
733 | fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX); | ||
734 | verbose("Found matching %s key: %s", | ||
735 | key_type(found), fp); | ||
736 | xfree(fp); | ||
737 | break; | ||
738 | } | ||
739 | } | ||
740 | restore_uid(); | ||
741 | fclose(f); | ||
742 | key_free(found); | ||
743 | if (!found_key) | ||
744 | debug2("key not found"); | ||
745 | return found_key; | ||
746 | } | ||
747 | |||
748 | /* check whether given key is in .ssh/authorized_keys* */ | ||
749 | int | ||
750 | user_key_allowed(struct passwd *pw, Key *key) | ||
751 | { | ||
752 | int success; | ||
753 | char *file; | ||
754 | |||
755 | file = authorized_keys_file(pw); | ||
756 | success = user_key_allowed2(pw, key, file); | ||
757 | xfree(file); | ||
758 | if (success) | ||
759 | return success; | ||
760 | |||
761 | /* try suffix "2" for backward compat, too */ | ||
762 | file = authorized_keys_file2(pw); | ||
763 | success = user_key_allowed2(pw, key, file); | ||
764 | xfree(file); | ||
765 | return success; | ||
766 | } | ||
767 | |||
768 | /* return 1 if given hostkey is allowed */ | ||
769 | int | ||
770 | hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost, | ||
771 | Key *key) | ||
772 | { | ||
773 | const char *resolvedname, *ipaddr, *lookup; | ||
774 | HostStatus host_status; | ||
775 | int len; | ||
776 | |||
777 | resolvedname = get_canonical_hostname(options.verify_reverse_mapping); | ||
778 | ipaddr = get_remote_ipaddr(); | ||
779 | |||
780 | debug2("userauth_hostbased: chost %s resolvedname %s ipaddr %s", | ||
781 | chost, resolvedname, ipaddr); | ||
782 | |||
783 | if (options.hostbased_uses_name_from_packet_only) { | ||
784 | if (auth_rhosts2(pw, cuser, chost, chost) == 0) | ||
785 | return 0; | ||
786 | lookup = chost; | ||
787 | } else { | ||
788 | if (((len = strlen(chost)) > 0) && chost[len - 1] == '.') { | ||
789 | debug2("stripping trailing dot from chost %s", chost); | ||
790 | chost[len - 1] = '\0'; | ||
791 | } | ||
792 | if (strcasecmp(resolvedname, chost) != 0) | ||
793 | log("userauth_hostbased mismatch: " | ||
794 | "client sends %s, but we resolve %s to %s", | ||
795 | chost, ipaddr, resolvedname); | ||
796 | if (auth_rhosts2(pw, cuser, resolvedname, ipaddr) == 0) | ||
797 | return 0; | ||
798 | lookup = resolvedname; | ||
799 | } | ||
800 | debug2("userauth_hostbased: access allowed by auth_rhosts2"); | ||
801 | |||
802 | host_status = check_key_in_hostfiles(pw, key, lookup, | ||
803 | _PATH_SSH_SYSTEM_HOSTFILE, | ||
804 | options.ignore_user_known_hosts ? NULL : _PATH_SSH_USER_HOSTFILE); | ||
805 | |||
806 | /* backward compat if no key has been found. */ | ||
807 | if (host_status == HOST_NEW) | ||
808 | host_status = check_key_in_hostfiles(pw, key, lookup, | ||
809 | _PATH_SSH_SYSTEM_HOSTFILE2, | ||
810 | options.ignore_user_known_hosts ? NULL : | ||
811 | _PATH_SSH_USER_HOSTFILE2); | ||
812 | |||
813 | return (host_status == HOST_OK); | ||
814 | } | ||