~ubuntu-branches/ubuntu/edgy/openssh/edgy

« back to all changes in this revision

Viewing changes to auth2-hostbased.c

  • Committer: Bazaar Package Importer
  • Author(s): Noah Meyerhans
  • Date: 2006-10-31 17:53:38 UTC
  • Revision ID: james.westby@ubuntu.com-20061031175338-kh299ada2qc2kzlb
Tags: upstream-3.8.1p1
ImportĀ upstreamĀ versionĀ 3.8.1p1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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.6 2004/01/19 21:25: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 u_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
                logit("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_free(&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.use_dns);
 
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
                        logit("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
};