source: trunk/third/openssh/auth2-hostbased.c @ 18759

Revision 18759, 5.5 KB checked in by zacheiss, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18758, which included commits to RCS files with non-trunk default branches.
Line 
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"
26RCSID("$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 */
43extern ServerOptions options;
44extern u_char *session_id2;
45extern int session_id2_len;
46
47static int
48userauth_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);
118done:
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 */
131int
132hostbased_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
178Authmethod method_hostbased = {
179        "hostbased",
180        userauth_hostbased,
181        &options.hostbased_authentication
182};
Note: See TracBrowser for help on using the repository browser.