00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "includes.h"
00026 RCSID("$OpenBSD: auth2-hostbased.c,v 1.6 2004/01/19 21:25:15 markus Exp $");
00027
00028 #include "ssh2.h"
00029 #include "xmalloc.h"
00030 #include "packet.h"
00031 #include "buffer.h"
00032 #include "log.h"
00033 #include "servconf.h"
00034 #include "compat.h"
00035 #include "bufaux.h"
00036 #include "auth.h"
00037 #include "key.h"
00038 #include "canohost.h"
00039 #include "monitor_wrap.h"
00040 #include "pathnames.h"
00041
00042
00043 extern ServerOptions options;
00044 extern u_char *session_id2;
00045 extern u_int session_id2_len;
00046
00047 static int
00048 userauth_hostbased(Authctxt *authctxt)
00049 {
00050 Buffer b;
00051 Key *key = NULL;
00052 char *pkalg, *cuser, *chost, *service;
00053 u_char *pkblob, *sig;
00054 u_int alen, blen, slen;
00055 int pktype;
00056 int authenticated = 0;
00057
00058 if (!authctxt->valid) {
00059 debug2("userauth_hostbased: disabled because of invalid user");
00060 return 0;
00061 }
00062 pkalg = packet_get_string(&alen);
00063 pkblob = packet_get_string(&blen);
00064 chost = packet_get_string(NULL);
00065 cuser = packet_get_string(NULL);
00066 sig = packet_get_string(&slen);
00067
00068 debug("userauth_hostbased: cuser %s chost %s pkalg %s slen %d",
00069 cuser, chost, pkalg, slen);
00070 #ifdef DEBUG_PK
00071 debug("signature:");
00072 buffer_init(&b);
00073 buffer_append(&b, sig, slen);
00074 buffer_dump(&b);
00075 buffer_free(&b);
00076 #endif
00077 pktype = key_type_from_name(pkalg);
00078 if (pktype == KEY_UNSPEC) {
00079
00080 logit("userauth_hostbased: unsupported "
00081 "public key algorithm: %s", pkalg);
00082 goto done;
00083 }
00084 key = key_from_blob(pkblob, blen);
00085 if (key == NULL) {
00086 error("userauth_hostbased: cannot decode key: %s", pkalg);
00087 goto done;
00088 }
00089 if (key->type != pktype) {
00090 error("userauth_hostbased: type mismatch for decoded key "
00091 "(received %d, expected %d)", key->type, pktype);
00092 goto done;
00093 }
00094 service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" :
00095 authctxt->service;
00096 buffer_init(&b);
00097 buffer_put_string(&b, session_id2, session_id2_len);
00098
00099 buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
00100 buffer_put_cstring(&b, authctxt->user);
00101 buffer_put_cstring(&b, service);
00102 buffer_put_cstring(&b, "hostbased");
00103 buffer_put_string(&b, pkalg, alen);
00104 buffer_put_string(&b, pkblob, blen);
00105 buffer_put_cstring(&b, chost);
00106 buffer_put_cstring(&b, cuser);
00107 #ifdef DEBUG_PK
00108 buffer_dump(&b);
00109 #endif
00110
00111 authenticated = 0;
00112 if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) &&
00113 PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
00114 buffer_len(&b))) == 1)
00115 authenticated = 1;
00116
00117 buffer_free(&b);
00118 done:
00119 debug2("userauth_hostbased: authenticated %d", authenticated);
00120 if (key != NULL)
00121 key_free(key);
00122 xfree(pkalg);
00123 xfree(pkblob);
00124 xfree(cuser);
00125 xfree(chost);
00126 xfree(sig);
00127 return authenticated;
00128 }
00129
00130
00131 int
00132 hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
00133 Key *key)
00134 {
00135 const char *resolvedname, *ipaddr, *lookup;
00136 HostStatus host_status;
00137 int len;
00138
00139 resolvedname = get_canonical_hostname(options.use_dns);
00140 ipaddr = get_remote_ipaddr();
00141
00142 debug2("userauth_hostbased: chost %s resolvedname %s ipaddr %s",
00143 chost, resolvedname, ipaddr);
00144
00145 if (options.hostbased_uses_name_from_packet_only) {
00146 if (auth_rhosts2(pw, cuser, chost, chost) == 0)
00147 return 0;
00148 lookup = chost;
00149 } else {
00150 if (((len = strlen(chost)) > 0) && chost[len - 1] == '.') {
00151 debug2("stripping trailing dot from chost %s", chost);
00152 chost[len - 1] = '\0';
00153 }
00154 if (strcasecmp(resolvedname, chost) != 0)
00155 logit("userauth_hostbased mismatch: "
00156 "client sends %s, but we resolve %s to %s",
00157 chost, ipaddr, resolvedname);
00158 if (auth_rhosts2(pw, cuser, resolvedname, ipaddr) == 0)
00159 return 0;
00160 lookup = resolvedname;
00161 }
00162 debug2("userauth_hostbased: access allowed by auth_rhosts2");
00163
00164 host_status = check_key_in_hostfiles(pw, key, lookup,
00165 _PATH_SSH_SYSTEM_HOSTFILE,
00166 options.ignore_user_known_hosts ? NULL : _PATH_SSH_USER_HOSTFILE);
00167
00168
00169 if (host_status == HOST_NEW)
00170 host_status = check_key_in_hostfiles(pw, key, lookup,
00171 _PATH_SSH_SYSTEM_HOSTFILE2,
00172 options.ignore_user_known_hosts ? NULL :
00173 _PATH_SSH_USER_HOSTFILE2);
00174
00175 return (host_status == HOST_OK);
00176 }
00177
00178 Authmethod method_hostbased = {
00179 "hostbased",
00180 userauth_hostbased,
00181 &options.hostbased_authentication
00182 };