]> andersk Git - openssh.git/commitdiff
- markus@cvs.openbsd.org 2002/05/25 18:51:07
authormouring <mouring>
Thu, 6 Jun 2002 20:27:55 +0000 (20:27 +0000)
committermouring <mouring>
Thu, 6 Jun 2002 20:27:55 +0000 (20:27 +0000)
     [auth.h auth2.c auth2-hostbased.c auth2-kbdint.c auth2-none.c
      auth2-passwd.c auth2-pubkey.c Makefile.in]
     split auth2.c into one file per method; ok provos@/deraadt@

NOTE: Merged back noticable cygwin and pam stuff.  May need review to
ensure I did not miss anything.

ChangeLog
Makefile.in
auth.h
auth2-hostbased.c [new file with mode: 0644]
auth2-kbdint.c [new file with mode: 0644]
auth2-none.c [new file with mode: 0644]
auth2-passwd.c [new file with mode: 0644]
auth2-pubkey.c [new file with mode: 0644]
auth2.c

index 07f2a4813e1c009de0db529469995416924659a9..d116ca7c5b40ac7c4eb78eb09e916c7f6cc0e909 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
    - markus@cvs.openbsd.org 2002/05/25 08:50:39
      [sshconnect2.c]
      execlp->execl; from stevesk
+   - markus@cvs.openbsd.org 2002/05/25 18:51:07
+     [auth.h auth2.c auth2-hostbased.c auth2-kbdint.c auth2-none.c
+      auth2-passwd.c auth2-pubkey.c Makefile.in]
+     split auth2.c into one file per method; ok provos@/deraadt@
 
 20020604
  - (stevesk) [channels.c] bug #164 patch from YOSHIFUJI Hideaki (changed
index 3ef24e8fa9da524ebd7e09f98b91925bc7486a4a..5fe66f0da7ffc57c8f49fbf5c20c0ec3274a81ff 100644 (file)
@@ -61,7 +61,7 @@ LIBSSH_OBJS=atomicio.o authfd.o authfile.o bufaux.o buffer.o canohost.o channels
 
 SSHOBJS= ssh.o sshconnect.o sshconnect1.o sshconnect2.o sshtty.o readconf.o clientloop.o
 
-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
+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
 
 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
 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
diff --git a/auth.h b/auth.h
index 2211c5b2adfa618ebf08ee6cb7c71a068156bd6d..59646ebe47d956ef98220b721356d388f4284aab 100644 (file)
--- a/auth.h
+++ b/auth.h
@@ -1,4 +1,4 @@
-/*     $OpenBSD: auth.h,v 1.37 2002/05/13 20:44:58 markus Exp $        */
+/*     $OpenBSD: auth.h,v 1.38 2002/05/25 18:51:07 markus Exp $        */
 
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
@@ -100,6 +100,13 @@ BIGNUM     *auth_rsa_generate_challenge(Key *);
 int     auth_rsa_verify_response(Key *, BIGNUM *, u_char[]);
 int     auth_rsa_key_allowed(struct passwd *, BIGNUM *, Key **);
 
+/* ssh2 methods */
+int     userauth_none(Authctxt *);
+int     userauth_passwd(Authctxt *);
+int     userauth_pubkey(Authctxt *);
+int     userauth_hostbased(Authctxt *);
+int     userauth_kbdint(Authctxt *);
+
 int     auth_rhosts_rsa_key_allowed(struct passwd *, char *, char *, Key *);
 int     hostbased_key_allowed(struct passwd *, const char *, char *, Key *);
 int     user_key_allowed(struct passwd *, Key *);
diff --git a/auth2-hostbased.c b/auth2-hostbased.c
new file mode 100644 (file)
index 0000000..2bde7bb
--- /dev/null
@@ -0,0 +1,182 @@
+/*
+ * Copyright (c) 2000 Markus Friedl.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "includes.h"
+RCSID("$OpenBSD: auth2-hostbased.c,v 1.2 2002/05/31 11:35:15 markus Exp $");
+
+#include "ssh2.h"
+#include "xmalloc.h"
+#include "packet.h"
+#include "buffer.h"
+#include "log.h"
+#include "servconf.h"
+#include "compat.h"
+#include "bufaux.h"
+#include "auth.h"
+#include "key.h"
+#include "canohost.h"
+#include "monitor_wrap.h"
+#include "pathnames.h"
+
+/* import */
+extern ServerOptions options;
+extern u_char *session_id2;
+extern int session_id2_len;
+
+static int
+userauth_hostbased(Authctxt *authctxt)
+{
+       Buffer b;
+       Key *key = NULL;
+       char *pkalg, *cuser, *chost, *service;
+       u_char *pkblob, *sig;
+       u_int alen, blen, slen;
+       int pktype;
+       int authenticated = 0;
+
+       if (!authctxt->valid) {
+               debug2("userauth_hostbased: disabled because of invalid user");
+               return 0;
+       }
+       pkalg = packet_get_string(&alen);
+       pkblob = packet_get_string(&blen);
+       chost = packet_get_string(NULL);
+       cuser = packet_get_string(NULL);
+       sig = packet_get_string(&slen);
+
+       debug("userauth_hostbased: cuser %s chost %s pkalg %s slen %d",
+           cuser, chost, pkalg, slen);
+#ifdef DEBUG_PK
+       debug("signature:");
+       buffer_init(&b);
+       buffer_append(&b, sig, slen);
+       buffer_dump(&b);
+       buffer_free(&b);
+#endif
+       pktype = key_type_from_name(pkalg);
+       if (pktype == KEY_UNSPEC) {
+               /* this is perfectly legal */
+               log("userauth_hostbased: unsupported "
+                   "public key algorithm: %s", pkalg);
+               goto done;
+       }
+       key = key_from_blob(pkblob, blen);
+       if (key == NULL) {
+               error("userauth_hostbased: cannot decode key: %s", pkalg);
+               goto done;
+       }
+       if (key->type != pktype) {
+               error("userauth_hostbased: type mismatch for decoded key "
+                   "(received %d, expected %d)", key->type, pktype);
+               goto done;
+       }
+       service = datafellows & SSH_BUG_HBSERVICE ? "ssh-userauth" :
+           authctxt->service;
+       buffer_init(&b);
+       buffer_put_string(&b, session_id2, session_id2_len);
+       /* reconstruct packet */
+       buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
+       buffer_put_cstring(&b, authctxt->user);
+       buffer_put_cstring(&b, service);
+       buffer_put_cstring(&b, "hostbased");
+       buffer_put_string(&b, pkalg, alen);
+       buffer_put_string(&b, pkblob, blen);
+       buffer_put_cstring(&b, chost);
+       buffer_put_cstring(&b, cuser);
+#ifdef DEBUG_PK
+       buffer_dump(&b);
+#endif
+       /* test for allowed key and correct signature */
+       authenticated = 0;
+       if (PRIVSEP(hostbased_key_allowed(authctxt->pw, cuser, chost, key)) &&
+           PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
+                       buffer_len(&b))) == 1)
+               authenticated = 1;
+
+       buffer_clear(&b);
+done:
+       debug2("userauth_hostbased: authenticated %d", authenticated);
+       if (key != NULL)
+               key_free(key);
+       xfree(pkalg);
+       xfree(pkblob);
+       xfree(cuser);
+       xfree(chost);
+       xfree(sig);
+       return authenticated;
+}
+
+/* return 1 if given hostkey is allowed */
+int
+hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
+    Key *key)
+{
+       const char *resolvedname, *ipaddr, *lookup;
+       HostStatus host_status;
+       int len;
+
+       resolvedname = get_canonical_hostname(options.verify_reverse_mapping);
+       ipaddr = get_remote_ipaddr();
+
+       debug2("userauth_hostbased: chost %s resolvedname %s ipaddr %s",
+           chost, resolvedname, ipaddr);
+
+       if (options.hostbased_uses_name_from_packet_only) {
+               if (auth_rhosts2(pw, cuser, chost, chost) == 0)
+                       return 0;
+               lookup = chost;
+       } else {
+               if (((len = strlen(chost)) > 0) && chost[len - 1] == '.') {
+                       debug2("stripping trailing dot from chost %s", chost);
+                       chost[len - 1] = '\0';
+               }
+               if (strcasecmp(resolvedname, chost) != 0)
+                       log("userauth_hostbased mismatch: "
+                           "client sends %s, but we resolve %s to %s",
+                           chost, ipaddr, resolvedname);
+               if (auth_rhosts2(pw, cuser, resolvedname, ipaddr) == 0)
+                       return 0;
+               lookup = resolvedname;
+       }
+       debug2("userauth_hostbased: access allowed by auth_rhosts2");
+
+       host_status = check_key_in_hostfiles(pw, key, lookup,
+           _PATH_SSH_SYSTEM_HOSTFILE,
+           options.ignore_user_known_hosts ? NULL : _PATH_SSH_USER_HOSTFILE);
+
+       /* backward compat if no key has been found. */
+       if (host_status == HOST_NEW)
+               host_status = check_key_in_hostfiles(pw, key, lookup,
+                   _PATH_SSH_SYSTEM_HOSTFILE2,
+                   options.ignore_user_known_hosts ? NULL :
+                   _PATH_SSH_USER_HOSTFILE2);
+
+       return (host_status == HOST_OK);
+}
+
+Authmethod method_hostbased = {
+       "hostbased",
+       userauth_hostbased,
+       &options.hostbased_authentication
+};
diff --git a/auth2-kbdint.c b/auth2-kbdint.c
new file mode 100644 (file)
index 0000000..e609928
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2000 Markus Friedl.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "includes.h"
+RCSID("$OpenBSD: auth2-kbdint.c,v 1.2 2002/05/31 11:35:15 markus Exp $");
+
+#include "packet.h"
+#include "auth.h"
+#include "log.h"
+#include "servconf.h"
+#include "xmalloc.h"
+
+/* import */
+extern ServerOptions options;
+
+static int
+userauth_kbdint(Authctxt *authctxt)
+{
+       int authenticated = 0;
+       char *lang, *devs;
+
+       lang = packet_get_string(NULL);
+       devs = packet_get_string(NULL);
+       packet_check_eom();
+
+       debug("keyboard-interactive devs %s", devs);
+
+       if (options.challenge_response_authentication)
+               authenticated = auth2_challenge(authctxt, devs);
+
+#ifdef USE_PAM
+       if (authenticated == 0 && options.pam_authentication_via_kbd_int)
+               authenticated = auth2_pam(authctxt);
+#endif
+       xfree(devs);
+       xfree(lang);
+#ifdef HAVE_CYGWIN
+       if (check_nt_auth(0, authctxt->pw) == 0)
+               return(0);
+#endif
+       return authenticated;
+}
+
+Authmethod method_kbdint = {
+       "keyboard-interactive",
+       userauth_kbdint,
+       &options.kbd_interactive_authentication
+};
diff --git a/auth2-none.c b/auth2-none.c
new file mode 100644 (file)
index 0000000..30337fd
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2000 Markus Friedl.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "includes.h"
+RCSID("$OpenBSD: auth2-none.c,v 1.2 2002/05/31 11:35:15 markus Exp $");
+
+#include "auth.h"
+#include "xmalloc.h"
+#include "packet.h"
+#include "log.h"
+#include "servconf.h"
+#include "atomicio.h"
+#include "compat.h"
+#include "ssh2.h"
+#include "monitor_wrap.h"
+
+/* import */
+extern ServerOptions options;
+
+/* "none" is allowed only one time */
+static int none_enabled = 1;
+
+char *
+auth2_read_banner(void)
+{
+       struct stat st;
+       char *banner = NULL;
+       off_t len, n;
+       int fd;
+
+       if ((fd = open(options.banner, O_RDONLY)) == -1)
+               return (NULL);
+       if (fstat(fd, &st) == -1) {
+               close(fd);
+               return (NULL);
+       }
+       len = st.st_size;
+       banner = xmalloc(len + 1);
+       n = atomicio(read, fd, banner, len);
+       close(fd);
+
+       if (n != len) {
+               free(banner);
+               return (NULL);
+       }
+       banner[n] = '\0';
+       
+       return (banner);
+}
+
+static void
+userauth_banner(void)
+{
+       char *banner = NULL;
+
+       if (options.banner == NULL || (datafellows & SSH_BUG_BANNER))
+               return;
+
+       if ((banner = PRIVSEP(auth2_read_banner())) == NULL)
+               goto done;
+
+       packet_start(SSH2_MSG_USERAUTH_BANNER);
+       packet_put_cstring(banner);
+       packet_put_cstring("");         /* language, unused */
+       packet_send();
+       debug("userauth_banner: sent");
+done:
+       if (banner)
+               xfree(banner);
+       return;
+}
+
+static int
+userauth_none(Authctxt *authctxt)
+{
+       none_enabled = 0;
+       packet_check_eom();
+       userauth_banner();
+#ifdef HAVE_CYGWIN
+       if (check_nt_auth(1, authctxt->pw) == 0)
+               return(0);
+#endif
+       return (authctxt->valid ? PRIVSEP(auth_password(authctxt, "")) : 0);
+}
+
+Authmethod method_none = {
+       "none",
+       userauth_none,
+       &none_enabled
+};
diff --git a/auth2-passwd.c b/auth2-passwd.c
new file mode 100644 (file)
index 0000000..ffa2795
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2000 Markus Friedl.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "includes.h"
+RCSID("$OpenBSD: auth2-passwd.c,v 1.2 2002/05/31 11:35:15 markus Exp $");
+
+#include "xmalloc.h"
+#include "packet.h"
+#include "log.h"
+#include "auth.h"
+#include "monitor_wrap.h"
+#include "servconf.h"
+
+/* import */
+extern ServerOptions options;
+
+static int
+userauth_passwd(Authctxt *authctxt)
+{
+       char *password;
+       int authenticated = 0;
+       int change;
+       u_int len;
+       change = packet_get_char();
+       if (change)
+               log("password change not supported");
+       password = packet_get_string(&len);
+       packet_check_eom();
+       if (authctxt->valid &&
+#ifdef HAVE_CYGWIN
+           check_nt_auth(1, authctxt->pw) &&
+#endif
+           PRIVSEP(auth_password(authctxt, password)) == 1)
+               authenticated = 1;
+       memset(password, 0, len);
+       xfree(password);
+       return authenticated;
+}
+
+Authmethod method_passwd = {
+       "password",
+       userauth_passwd,
+       &options.password_authentication
+};
diff --git a/auth2-pubkey.c b/auth2-pubkey.c
new file mode 100644 (file)
index 0000000..947bfed
--- /dev/null
@@ -0,0 +1,283 @@
+/*
+ * Copyright (c) 2000 Markus Friedl.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "includes.h"
+RCSID("$OpenBSD: auth2-pubkey.c,v 1.2 2002/05/31 11:35:15 markus Exp $");
+
+#include "ssh2.h"
+#include "xmalloc.h"
+#include "packet.h"
+#include "buffer.h"
+#include "log.h"
+#include "servconf.h"
+#include "compat.h"
+#include "bufaux.h"
+#include "auth.h"
+#include "key.h"
+#include "pathnames.h"
+#include "uidswap.h"
+#include "auth-options.h"
+#include "canohost.h"
+#include "monitor_wrap.h"
+
+/* import */
+extern ServerOptions options;
+extern u_char *session_id2;
+extern int session_id2_len;
+
+static int
+userauth_pubkey(Authctxt *authctxt)
+{
+       Buffer b;
+       Key *key = NULL;
+       char *pkalg;
+       u_char *pkblob, *sig;
+       u_int alen, blen, slen;
+       int have_sig, pktype;
+       int authenticated = 0;
+
+       if (!authctxt->valid) {
+               debug2("userauth_pubkey: disabled because of invalid user");
+               return 0;
+       }
+       have_sig = packet_get_char();
+       if (datafellows & SSH_BUG_PKAUTH) {
+               debug2("userauth_pubkey: SSH_BUG_PKAUTH");
+               /* no explicit pkalg given */
+               pkblob = packet_get_string(&blen);
+               buffer_init(&b);
+               buffer_append(&b, pkblob, blen);
+               /* so we have to extract the pkalg from the pkblob */
+               pkalg = buffer_get_string(&b, &alen);
+               buffer_free(&b);
+       } else {
+               pkalg = packet_get_string(&alen);
+               pkblob = packet_get_string(&blen);
+       }
+       pktype = key_type_from_name(pkalg);
+       if (pktype == KEY_UNSPEC) {
+               /* this is perfectly legal */
+               log("userauth_pubkey: unsupported public key algorithm: %s",
+                   pkalg);
+               goto done;
+       }
+       key = key_from_blob(pkblob, blen);
+       if (key == NULL) {
+               error("userauth_pubkey: cannot decode key: %s", pkalg);
+               goto done;
+       }
+       if (key->type != pktype) {
+               error("userauth_pubkey: type mismatch for decoded key "
+                   "(received %d, expected %d)", key->type, pktype);
+               goto done;
+       }
+       if (have_sig) {
+               sig = packet_get_string(&slen);
+               packet_check_eom();
+               buffer_init(&b);
+               if (datafellows & SSH_OLD_SESSIONID) {
+                       buffer_append(&b, session_id2, session_id2_len);
+               } else {
+                       buffer_put_string(&b, session_id2, session_id2_len);
+               }
+               /* reconstruct packet */
+               buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
+               buffer_put_cstring(&b, authctxt->user);
+               buffer_put_cstring(&b,
+                   datafellows & SSH_BUG_PKSERVICE ?
+                   "ssh-userauth" :
+                   authctxt->service);
+               if (datafellows & SSH_BUG_PKAUTH) {
+                       buffer_put_char(&b, have_sig);
+               } else {
+                       buffer_put_cstring(&b, "publickey");
+                       buffer_put_char(&b, have_sig);
+                       buffer_put_cstring(&b, pkalg);
+               }
+               buffer_put_string(&b, pkblob, blen);
+#ifdef DEBUG_PK
+               buffer_dump(&b);
+#endif
+               /* test for correct signature */
+               authenticated = 0;
+               if (PRIVSEP(user_key_allowed(authctxt->pw, key)) &&
+                   PRIVSEP(key_verify(key, sig, slen, buffer_ptr(&b),
+                               buffer_len(&b))) == 1)
+                       authenticated = 1;
+               buffer_clear(&b);
+               xfree(sig);
+       } else {
+               debug("test whether pkalg/pkblob are acceptable");
+               packet_check_eom();
+
+               /* XXX fake reply and always send PK_OK ? */
+               /*
+                * XXX this allows testing whether a user is allowed
+                * to login: if you happen to have a valid pubkey this
+                * message is sent. the message is NEVER sent at all
+                * if a user is not allowed to login. is this an
+                * issue? -markus
+                */
+               if (PRIVSEP(user_key_allowed(authctxt->pw, key))) {
+                       packet_start(SSH2_MSG_USERAUTH_PK_OK);
+                       packet_put_string(pkalg, alen);
+                       packet_put_string(pkblob, blen);
+                       packet_send();
+                       packet_write_wait();
+                       authctxt->postponed = 1;
+               }
+       }
+       if (authenticated != 1)
+               auth_clear_options();
+done:
+       debug2("userauth_pubkey: authenticated %d pkalg %s", authenticated, pkalg);
+       if (key != NULL)
+               key_free(key);
+       xfree(pkalg);
+       xfree(pkblob);
+#ifdef HAVE_CYGWIN
+       if (check_nt_auth(0, authctxt->pw) == 0)
+               return(0);
+#endif
+       return authenticated;
+}
+
+/* return 1 if user allows given key */
+static int
+user_key_allowed2(struct passwd *pw, Key *key, char *file)
+{
+       char line[8192];
+       int found_key = 0;
+       FILE *f;
+       u_long linenum = 0;
+       struct stat st;
+       Key *found;
+       char *fp;
+
+       if (pw == NULL)
+               return 0;
+
+       /* Temporarily use the user's uid. */
+       temporarily_use_uid(pw);
+
+       debug("trying public key file %s", file);
+
+       /* Fail quietly if file does not exist */
+       if (stat(file, &st) < 0) {
+               /* Restore the privileged uid. */
+               restore_uid();
+               return 0;
+       }
+       /* Open the file containing the authorized keys. */
+       f = fopen(file, "r");
+       if (!f) {
+               /* Restore the privileged uid. */
+               restore_uid();
+               return 0;
+       }
+       if (options.strict_modes &&
+           secure_filename(f, file, pw, line, sizeof(line)) != 0) {
+               fclose(f);
+               log("Authentication refused: %s", line);
+               restore_uid();
+               return 0;
+       }
+
+       found_key = 0;
+       found = key_new(key->type);
+
+       while (fgets(line, sizeof(line), f)) {
+               char *cp, *options = NULL;
+               linenum++;
+               /* Skip leading whitespace, empty and comment lines. */
+               for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
+                       ;
+               if (!*cp || *cp == '\n' || *cp == '#')
+                       continue;
+
+               if (key_read(found, &cp) != 1) {
+                       /* no key?  check if there are options for this key */
+                       int quoted = 0;
+                       debug2("user_key_allowed: check options: '%s'", cp);
+                       options = cp;
+                       for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
+                               if (*cp == '\\' && cp[1] == '"')
+                                       cp++;   /* Skip both */
+                               else if (*cp == '"')
+                                       quoted = !quoted;
+                       }
+                       /* Skip remaining whitespace. */
+                       for (; *cp == ' ' || *cp == '\t'; cp++)
+                               ;
+                       if (key_read(found, &cp) != 1) {
+                               debug2("user_key_allowed: advance: '%s'", cp);
+                               /* still no key?  advance to next line*/
+                               continue;
+                       }
+               }
+               if (key_equal(found, key) &&
+                   auth_parse_options(pw, options, file, linenum) == 1) {
+                       found_key = 1;
+                       debug("matching key found: file %s, line %lu",
+                           file, linenum);
+                       fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
+                       verbose("Found matching %s key: %s",
+                           key_type(found), fp);
+                       xfree(fp);
+                       break;
+               }
+       }
+       restore_uid();
+       fclose(f);
+       key_free(found);
+       if (!found_key)
+               debug2("key not found");
+       return found_key;
+}
+
+/* check whether given key is in .ssh/authorized_keys* */
+int
+user_key_allowed(struct passwd *pw, Key *key)
+{
+       int success;
+       char *file;
+
+       file = authorized_keys_file(pw);
+       success = user_key_allowed2(pw, key, file);
+       xfree(file);
+       if (success)
+               return success;
+
+       /* try suffix "2" for backward compat, too */
+       file = authorized_keys_file2(pw);
+       success = user_key_allowed2(pw, key, file);
+       xfree(file);
+       return success;
+}
+
+Authmethod method_pubkey = {
+       "publickey",
+       userauth_pubkey,
+       &options.pubkey_authentication
+};
diff --git a/auth2.c b/auth2.c
index 6bcc5652787fbac9e67e5205bee4291bb3331d3a..ffd7032820351532d5c46aa1b56f362550ea360a 100644 (file)
--- a/auth2.c
+++ b/auth2.c
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth2.c,v 1.91 2002/05/13 02:37:39 itojun Exp $");
-
-#include <openssl/evp.h>
+RCSID("$OpenBSD: auth2.c,v 1.92 2002/05/25 18:51:07 markus Exp $");
 
 #include "ssh2.h"
 #include "xmalloc.h"
-#include "rsa.h"
-#include "sshpty.h"
 #include "packet.h"
-#include "buffer.h"
 #include "log.h"
 #include "servconf.h"
 #include "compat.h"
-#include "channels.h"
-#include "bufaux.h"
 #include "auth.h"
-#include "session.h"
 #include "dispatch.h"
-#include "key.h"
-#include "cipher.h"
-#include "kex.h"
 #include "pathnames.h"
-#include "uidswap.h"
-#include "auth-options.h"
-#include "hostfile.h"
-#include "canohost.h"
-#include "match.h"
 #include "monitor_wrap.h"
-#include "atomicio.h"
 
 /* import */
 extern ServerOptions options;
@@ -80,12 +63,6 @@ int user_key_allowed(struct passwd *, Key *);
 int hostbased_key_allowed(struct passwd *, const char *, char *, Key *);
 
 /* auth */
-static void userauth_banner(void);
-static int userauth_none(Authctxt *);
-static int userauth_passwd(Authctxt *);
-static int userauth_pubkey(Authctxt *);
-static int userauth_hostbased(Authctxt *);
-static int userauth_kbdint(Authctxt *);
 
 Authmethod authmethods[] = {
        {"none",
@@ -651,164 +628,3 @@ authmethod_lookup(const char *name)
        debug2("Unrecognized authentication method name: %s", name ? name : "NULL");
        return NULL;
 }
-
-/* return 1 if user allows given key */
-static int
-user_key_allowed2(struct passwd *pw, Key *key, char *file)
-{
-       char line[8192];
-       int found_key = 0;
-       FILE *f;
-       u_long linenum = 0;
-       struct stat st;
-       Key *found;
-       char *fp;
-
-       if (pw == NULL)
-               return 0;
-
-       /* Temporarily use the user's uid. */
-       temporarily_use_uid(pw);
-
-       debug("trying public key file %s", file);
-
-       /* Fail quietly if file does not exist */
-       if (stat(file, &st) < 0) {
-               /* Restore the privileged uid. */
-               restore_uid();
-               return 0;
-       }
-       /* Open the file containing the authorized keys. */
-       f = fopen(file, "r");
-       if (!f) {
-               /* Restore the privileged uid. */
-               restore_uid();
-               return 0;
-       }
-       if (options.strict_modes &&
-           secure_filename(f, file, pw, line, sizeof(line)) != 0) {
-               fclose(f);
-               log("Authentication refused: %s", line);
-               restore_uid();
-               return 0;
-       }
-
-       found_key = 0;
-       found = key_new(key->type);
-
-       while (fgets(line, sizeof(line), f)) {
-               char *cp, *options = NULL;
-               linenum++;
-               /* Skip leading whitespace, empty and comment lines. */
-               for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
-                       ;
-               if (!*cp || *cp == '\n' || *cp == '#')
-                       continue;
-
-               if (key_read(found, &cp) != 1) {
-                       /* no key?  check if there are options for this key */
-                       int quoted = 0;
-                       debug2("user_key_allowed: check options: '%s'", cp);
-                       options = cp;
-                       for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {
-                               if (*cp == '\\' && cp[1] == '"')
-                                       cp++;   /* Skip both */
-                               else if (*cp == '"')
-                                       quoted = !quoted;
-                       }
-                       /* Skip remaining whitespace. */
-                       for (; *cp == ' ' || *cp == '\t'; cp++)
-                               ;
-                       if (key_read(found, &cp) != 1) {
-                               debug2("user_key_allowed: advance: '%s'", cp);
-                               /* still no key?  advance to next line*/
-                               continue;
-                       }
-               }
-               if (key_equal(found, key) &&
-                   auth_parse_options(pw, options, file, linenum) == 1) {
-                       found_key = 1;
-                       debug("matching key found: file %s, line %lu",
-                           file, linenum);
-                       fp = key_fingerprint(found, SSH_FP_MD5, SSH_FP_HEX);
-                       verbose("Found matching %s key: %s",
-                           key_type(found), fp);
-                       xfree(fp);
-                       break;
-               }
-       }
-       restore_uid();
-       fclose(f);
-       key_free(found);
-       if (!found_key)
-               debug2("key not found");
-       return found_key;
-}
-
-/* check whether given key is in .ssh/authorized_keys* */
-int
-user_key_allowed(struct passwd *pw, Key *key)
-{
-       int success;
-       char *file;
-
-       file = authorized_keys_file(pw);
-       success = user_key_allowed2(pw, key, file);
-       xfree(file);
-       if (success)
-               return success;
-
-       /* try suffix "2" for backward compat, too */
-       file = authorized_keys_file2(pw);
-       success = user_key_allowed2(pw, key, file);
-       xfree(file);
-       return success;
-}
-
-/* return 1 if given hostkey is allowed */
-int
-hostbased_key_allowed(struct passwd *pw, const char *cuser, char *chost,
-    Key *key)
-{
-       const char *resolvedname, *ipaddr, *lookup;
-       HostStatus host_status;
-       int len;
-
-       resolvedname = get_canonical_hostname(options.verify_reverse_mapping);
-       ipaddr = get_remote_ipaddr();
-
-       debug2("userauth_hostbased: chost %s resolvedname %s ipaddr %s",
-           chost, resolvedname, ipaddr);
-
-       if (options.hostbased_uses_name_from_packet_only) {
-               if (auth_rhosts2(pw, cuser, chost, chost) == 0)
-                       return 0;
-               lookup = chost;
-       } else {
-               if (((len = strlen(chost)) > 0) && chost[len - 1] == '.') {
-                       debug2("stripping trailing dot from chost %s", chost);
-                       chost[len - 1] = '\0';
-               }
-               if (strcasecmp(resolvedname, chost) != 0)
-                       log("userauth_hostbased mismatch: "
-                           "client sends %s, but we resolve %s to %s",
-                           chost, ipaddr, resolvedname);
-               if (auth_rhosts2(pw, cuser, resolvedname, ipaddr) == 0)
-                       return 0;
-               lookup = resolvedname;
-       }
-       debug2("userauth_hostbased: access allowed by auth_rhosts2");
-
-       host_status = check_key_in_hostfiles(pw, key, lookup,
-           _PATH_SSH_SYSTEM_HOSTFILE,
-           options.ignore_user_known_hosts ? NULL : _PATH_SSH_USER_HOSTFILE);
-
-       /* backward compat if no key has been found. */
-       if (host_status == HOST_NEW)
-               host_status = check_key_in_hostfiles(pw, key, lookup,
-                   _PATH_SSH_SYSTEM_HOSTFILE2,
-                   options.ignore_user_known_hosts ? NULL :
-                   _PATH_SSH_USER_HOSTFILE2);
-
-       return (host_status == HOST_OK);
-}
This page took 0.330784 seconds and 5 git commands to generate.