Bugzilla – Attachment 1453 Details for
Bug 1439
Adds Virtual Token (VToken) authentication method to kbdint
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Virtual Token (VToken) challenge authentication method
openssh-4.7p1-kbdint-vtoken.patch (text/plain), 27.90 KB, created by
Paul Sery
on 2008-02-08 17:59:52 AEDT
(
hide
)
Description:
Virtual Token (VToken) challenge authentication method
Filename:
MIME Type:
Creator:
Paul Sery
Created:
2008-02-08 17:59:52 AEDT
Size:
27.90 KB
patch
obsolete
>--- openssh-4.7p1/Makefile.in 2007-06-10 22:01:42.000000000 -0600 >+++ openssh-kbdint-vtoken/Makefile.in 2008-02-07 19:26:14.000000000 -0700 >@@ -79,10 +79,11 @@ > SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ > sshpty.o sshlogin.o servconf.o serverloop.o \ > auth.o auth1.o auth2.o auth-options.o session.o \ > auth-chall.o auth2-chall.o groupaccess.o \ > auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ >+ auth-vtoken.o \ > auth2-none.o auth2-passwd.o auth2-pubkey.o \ > monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o \ > auth-krb5.o \ > auth2-gss.o gss-serv.o gss-serv-krb5.o \ > loginrec.o auth-pam.o auth-shadow.o auth-sia.o md5crypt.o \ >--- openssh-4.7p1/config.h.in 2007-09-04 00:50:04.000000000 -0600 >+++ openssh-kbdint-vtoken/config.h.in 2008-02-07 19:26:14.000000000 -0700 >@@ -1222,10 +1222,13 @@ > #undef SIZEOF_SHORT_INT > > /* Define if you want S/Key support */ > #undef SKEY > >+/* Define if you want Virtual Token support */ >+#undef USE_VTOKEN >+ > /* Define if your skeychallenge() function takes 4 arguments (NetBSD) */ > #undef SKEYCHALLENGE_4ARG > > /* Define if you want smartcard support */ > #undef SMARTCARD >--- openssh-4.7p1/configure.ac 2007-08-09 22:36:12.000000000 -0600 >+++ openssh-kbdint-vtoken/configure.ac 2008-02-07 19:26:14.000000000 -0700 >@@ -1091,10 +1091,25 @@ > ) > fi > ] > ) > >+# Check whether user wants Calc support >+VTOKEN_MSG="no" >+AC_ARG_WITH(vtoken, >+ [ --with-vtoken Enable Virtual Token support], >+ [ >+ if test "x$withval" != "xno" ; then >+ >+ AC_DEFINE(USE_VTOKEN, 1, [Define if you want Virtual Token support]) >+ VTOKEN_MSG="yes" >+ >+ AC_MSG_CHECKING([for Virtual Token support]) >+ fi >+ ] >+) >+ > # Check whether user wants TCP wrappers support > TCPW_MSG="no" > AC_ARG_WITH(tcp-wrappers, > [ --with-tcp-wrappers[[=PATH]] Enable tcpwrappers support (optionally in PATH)], > [ >@@ -4029,10 +4044,11 @@ > echo " OSF SIA support: $SIA_MSG" > echo " KerberosV support: $KRB5_MSG" > echo " SELinux support: $SELINUX_MSG" > echo " Smartcard support: $SCARD_MSG" > echo " S/KEY support: $SKEY_MSG" >+echo " Virtual Token support: $VTOKEN_MSG" > echo " TCP Wrappers support: $TCPW_MSG" > echo " MD5 password support: $MD5_MSG" > echo " libedit support: $LIBEDIT_MSG" > echo " Solaris process contract support: $SPC_MSG" > echo " IP address in \$DISPLAY hack: $DISPLAY_HACK_MSG" >--- openssh-4.7p1/auth2-chall.c 2007-01-04 22:30:16.000000000 -0700 >+++ openssh-kbdint-vtoken/auth2-chall.c 2008-02-07 20:55:36.000000000 -0700 >@@ -57,10 +57,13 @@ > extern KbdintDevice sshpam_device; > #endif > #ifdef SKEY > extern KbdintDevice skey_device; > #endif >+#ifdef USE_VTOKEN >+extern KbdintDevice vtoken_device; >+#endif > #endif > > KbdintDevice *devices[] = { > #ifdef BSD_AUTH > &bsdauth_device, >@@ -69,10 +72,13 @@ > &sshpam_device, > #endif > #ifdef SKEY > &skey_device, > #endif >+#ifdef USE_VTOKEN >+ &vtoken_device, >+#endif > #endif > NULL > }; > > typedef struct KbdintAuthctxt KbdintAuthctxt; >@@ -88,11 +94,10 @@ > void > remove_kbdint_device(const char *devname) > { > int i, j; > >- for (i = 0; devices[i] != NULL; i++) > if (strcmp(devices[i]->name, devname) == 0) { > for (j = i; devices[j] != NULL; j++) > devices[j] = devices[j+1]; > i--; > } >@@ -193,11 +198,11 @@ > authctxt->user ? authctxt->user : "<nouser>", > devs ? devs : "<no devs>"); > > if (authctxt->user == NULL || !devs) > return 0; >- if (authctxt->kbdintctxt == NULL) >+ if (authctxt->kbdintctxt == NULL) > authctxt->kbdintctxt = kbdint_alloc(devs); > return auth2_challenge_start(authctxt); > } > > /* unregister kbd-int callbacks and context */ >@@ -350,11 +355,11 @@ > } > > void > privsep_challenge_enable(void) > { >-#if defined(BSD_AUTH) || defined(USE_PAM) || defined(SKEY) >+#if defined(BSD_AUTH) || defined(USE_PAM) || defined(SKEY) || defined(USE_VTOKEN) > int n = 0; > #endif > #ifdef BSD_AUTH > extern KbdintDevice mm_bsdauth_device; > #endif >@@ -362,17 +367,23 @@ > extern KbdintDevice mm_sshpam_device; > #endif > #ifdef SKEY > extern KbdintDevice mm_skey_device; > #endif >+#ifdef USE_VTOKEN >+ extern KbdintDevice mm_vtoken_device; >+#endif > > #ifdef BSD_AUTH > devices[n++] = &mm_bsdauth_device; > #else > #ifdef USE_PAM > devices[n++] = &mm_sshpam_device; > #endif > #ifdef SKEY > devices[n++] = &mm_skey_device; > #endif >+#ifdef USE_VTOKEN >+ devices[n++] = &mm_vtoken_device; >+#endif > #endif > } >--- openssh-4.7p1/auth.h 2006-08-18 08:32:46.000000000 -0600 >+++ openssh-kbdint-vtoken/auth.h 2008-02-07 19:26:14.000000000 -0700 >@@ -69,10 +69,11 @@ > char *krb5_ticket_file; > char *krb5_ccname; > #endif > Buffer *loginmsg; > void *methoddata; >+ char *vtoken; > }; > /* > * Every authentication method has to handle authentication requests for > * non-existing users, or for users that are not allowed to login. In this > * case 'valid' is set to 0, but 'user' points to the username requested by >@@ -153,10 +154,13 @@ > void auth2_challenge_stop(Authctxt *); > int bsdauth_query(void *, char **, char **, u_int *, char ***, u_int **); > int bsdauth_respond(void *, u_int, char **); > int skey_query(void *, char **, char **, u_int *, char ***, u_int **); > int skey_respond(void *, u_int, char **); >+int calc_challenge(Authctxt *); >+int calc_auth(Authctxt *); >+int calc_send(char *, char *, char *); > > int allowed_user(struct passwd *); > struct passwd * getpwnamallow(const char *user); > > char *get_challenge(Authctxt *); >--- openssh-4.7p1/auth-vtoken.c 1969-12-31 17:00:00.000000000 -0700 >+++ openssh-kbdint-vtoken/auth-vtoken.c 2008-02-07 21:02:44.000000000 -0700 >@@ -0,0 +1,188 @@ >+/* $OpenBSD: auth-vtoken.c,v 0.5 2008/02/04 07:55:00 pgsery Exp $ */ >+/* >+ * Copyright (c) 2008 Paul Sery. 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. >+ */ >+ >+/* This code was derived from Markus Friedl's auth-skey.c and >+ Daniel B. Cid's Ossec/sendmail.c */ >+ >+#include "includes.h" >+ >+#include <sys/types.h> >+ >+#include <string.h> >+#include <stdarg.h> >+ >+#include "xmalloc.h" >+#include "packet.h" >+#include "log.h" >+#include "key.h" >+#include "hostfile.h" >+#include "auth.h" >+#include "buffer.h" >+#ifdef GSSAPI >+#include "ssh-gss.h" >+#endif >+#include "servconf.h" >+#include "uidswap.h" >+#include "monitor_wrap.h" >+ >+#include <netinet/in.h> >+#include <netdb.h> >+#include <arpa/inet.h> >+#include <sys/socket.h> >+#include <sys/types.h> >+#include <string.h> >+#include <stdarg.h> >+#include <unistd.h> >+#include "includes.h" >+#include "log.h" >+ >+#define TIME_FRAME 30 >+ >+/* import */ >+extern ServerOptions options; >+ >+int >+get_time(void) >+{ >+ int secs; >+ time_t now; >+ struct tm *its; >+ >+ /* use time as counter */ >+ /* construct counter from minutes and seconds */ >+ now = time(NULL); >+ its = localtime(&now); >+ /* counter 60*60=3600 */ >+ secs = its->tm_min*60 + its->tm_sec; >+ >+ return(secs); >+} >+ >+int >+calculate_secret(int secret, int pin, int count) >+{ >+ int challenge; >+ >+ /* user calculable challenge */ >+ >+ /* !!! proof-of-concept calculation !!! */ >+ /* advantage: you can calculate the secret with paper >+ and pencil or simple calculator >+ advantage: you can build a simple cell phone or pda >+ app to perform this function >+ disadvantage: the unknowns can be brute-forced if the >+ challenge is intercepted */ >+ challenge = (secret * count) % pin; >+ >+ return(challenge); >+} >+ >+static int >+check_user_response(int user_response) >+{ >+ int i, j=0, secs, curr_time, serv_chall, sec1, sec2; >+ int authenticated=0, frame=TIME_FRAME, ignore[TIME_FRAME*2]; >+ char *user; >+ >+ /* get the user's secrets */ >+ for (i=0; options.vtoken_users[i] != NULL; i++) { >+ user=strtok(options.vtoken_users[i],":"); >+ sec1=atoi(strtok(NULL,":")); >+ sec2=atoi(strtok(NULL,":")); >+ debug("get user secrets %s: %d %d",user,sec1,sec2); >+ } >+ >+ /* calculate solutions, for a given time frame, using user's secrets */ >+ curr_time = get_time(); >+ for (i=-frame; i<=frame; i++) { >+ secs = curr_time + i; >+ serv_chall = calculate_secret(sec1, sec2, secs); >+ >+ /* compare user and server solutions */ >+ if (serv_chall == user_response) { >+ authenticated=1; >+ ignore[j++] = serv_chall; >+ break; >+ } >+ } >+ >+ return authenticated; >+} >+ >+static void * >+vtoken_init_ctx(Authctxt *authctxt) >+{ >+ return authctxt; >+} >+ >+int >+vtoken_query(void *ctx, char **name, char **infotxt, >+ u_int* numprompts, char ***prompts, u_int **echo_on) >+{ >+ *name = xstrdup(""); >+ *infotxt = xstrdup(""); >+ *numprompts = 1; >+ *prompts = xcalloc(*numprompts, sizeof(char *)); >+ *echo_on = xcalloc(*numprompts, sizeof(u_int)); >+ >+ xasprintf(*prompts, "Enter calculated secret:"); >+ >+ return 0; >+} >+ >+int >+vtoken_respond(void *ctx, u_int numresponses, char **responses) >+{ >+ Authctxt *authctxt = ctx; >+ >+ if (authctxt->valid && numresponses == 1 ) >+ if (check_user_response(atoi(responses[0]))) >+ return 0; >+ return -1; >+} >+ >+static void >+vtoken_free_ctx(void *ctx) >+{ >+ Authctxt *authctx = ctx; >+ >+ authctx->vtoken = NULL; >+} >+ >+KbdintDevice vtoken_device = { >+ "vtoken", >+ vtoken_init_ctx, >+ vtoken_query, >+ vtoken_respond, >+ vtoken_free_ctx >+}; >+ >+KbdintDevice mm_vtoken_device = { >+ "vtoken", >+ vtoken_init_ctx, >+ mm_vtoken_query, >+ mm_vtoken_respond, >+ vtoken_free_ctx >+}; >--- openssh-4.7p1/monitor.c 2007-05-19 23:10:16.000000000 -0600 >+++ openssh-kbdint-vtoken/monitor.c 2008-02-07 19:26:14.000000000 -0700 >@@ -156,10 +156,15 @@ > int mm_answer_pam_query(int, Buffer *); > int mm_answer_pam_respond(int, Buffer *); > int mm_answer_pam_free_ctx(int, Buffer *); > #endif > >+#ifdef USE_VTOKEN >+int mm_answer_vtoken_query(int, Buffer *); >+int mm_answer_vtoken_respond(int, Buffer *); >+#endif >+ > #ifdef GSSAPI > int mm_answer_gss_setup_ctx(int, Buffer *); > int mm_answer_gss_accept_ctx(int, Buffer *); > int mm_answer_gss_userok(int, Buffer *); > int mm_answer_gss_checkmic(int, Buffer *); >@@ -223,10 +228,14 @@ > #endif > #ifdef SKEY > {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery}, > {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond}, > #endif >+#ifdef USE_VTOKEN >+ {MONITOR_REQ_VTOKENQUERY, MON_ISAUTH, mm_answer_vtoken_query}, >+ {MONITOR_REQ_VTOKENRESPOND, MON_AUTH, mm_answer_vtoken_respond}, >+#endif > {MONITOR_REQ_KEYALLOWED, MON_ISAUTH, mm_answer_keyallowed}, > {MONITOR_REQ_KEYVERIFY, MON_AUTH, mm_answer_keyverify}, > #ifdef GSSAPI > {MONITOR_REQ_GSSSETUP, MON_ISAUTH, mm_answer_gss_setup_ctx}, > {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx}, >@@ -264,10 +273,14 @@ > #endif > #ifdef SKEY > {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery}, > {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond}, > #endif >+#ifdef USE_VTOKEN >+ {MONITOR_REQ_VTOKENQUERY, MON_ISAUTH, mm_answer_vtoken_query}, >+ {MONITOR_REQ_VTOKENRESPOND, MON_AUTH, mm_answer_vtoken_respond}, >+#endif > #ifdef USE_PAM > {MONITOR_REQ_PAM_START, MON_ONCE, mm_answer_pam_start}, > {MONITOR_REQ_PAM_ACCOUNT, 0, mm_answer_pam_account}, > {MONITOR_REQ_PAM_INIT_CTX, MON_ISAUTH, mm_answer_pam_init_ctx}, > {MONITOR_REQ_PAM_QUERY, MON_ISAUTH, mm_answer_pam_query}, >@@ -810,33 +823,48 @@ > debug3("%s: sending challenge success: %u", __func__, success); > mm_request_send(sock, MONITOR_ANS_SKEYQUERY, m); > > return (0); > } >+#endif > >+#ifdef USE_VTOKEN > int >-mm_answer_skeyrespond(int sock, Buffer *m) >+mm_answer_vtoken_query(int sock, Buffer *m) >+{ >+ char challenge[1024]; >+ u_int success=1; >+ >+ buffer_clear(m); >+ buffer_put_int(m, success); >+ if (success) >+ buffer_put_cstring(m, challenge); >+ >+ debug3("%s: sending challenge success: %u", __func__, success); >+ >+ mm_request_send(sock, MONITOR_ANS_VTOKENQUERY, m); >+ >+ return (0); >+} >+ >+int >+mm_answer_vtoken_respond(int sock, Buffer *m) > { > char *response; > int authok; > > response = buffer_get_string(m, NULL); > >- authok = (options.challenge_response_authentication && >- authctxt->valid && >- skey_haskey(authctxt->pw->pw_name) == 0 && >- skey_passcheck(authctxt->pw->pw_name, response) != -1); >- > xfree(response); > > buffer_clear(m); > buffer_put_int(m, authok); > > debug3("%s: sending authenticated: %d", __func__, authok); >- mm_request_send(sock, MONITOR_ANS_SKEYRESPOND, m); >+ mm_request_send(sock, MONITOR_ANS_VTOKENRESPOND, m); > >- auth_method = "skey"; >+ auth_method = "vtoken"; > > return (authok != 0); > } > #endif > >--- openssh-4.7p1/monitor.h 2006-03-25 20:30:02.000000000 -0700 >+++ openssh-kbdint-vtoken/monitor.h 2008-02-07 19:26:14.000000000 -0700 >@@ -37,10 +37,12 @@ > MONITOR_REQ_AUTHPASSWORD, MONITOR_ANS_AUTHPASSWORD, > MONITOR_REQ_BSDAUTHQUERY, MONITOR_ANS_BSDAUTHQUERY, > MONITOR_REQ_BSDAUTHRESPOND, MONITOR_ANS_BSDAUTHRESPOND, > MONITOR_REQ_SKEYQUERY, MONITOR_ANS_SKEYQUERY, > MONITOR_REQ_SKEYRESPOND, MONITOR_ANS_SKEYRESPOND, >+ MONITOR_REQ_VTOKENQUERY, MONITOR_ANS_VTOKENQUERY, >+ MONITOR_REQ_VTOKENRESPOND, MONITOR_ANS_VTOKENRESPOND, > MONITOR_REQ_KEYALLOWED, MONITOR_ANS_KEYALLOWED, > MONITOR_REQ_KEYVERIFY, MONITOR_ANS_KEYVERIFY, > MONITOR_REQ_KEYEXPORT, > MONITOR_REQ_PTY, MONITOR_ANS_PTY, > MONITOR_REQ_PTYCLEANUP, >--- openssh-4.7p1/monitor_wrap.c 2007-06-10 22:01:42.000000000 -0600 >+++ openssh-kbdint-vtoken/monitor_wrap.c 2008-02-07 20:59:55.000000000 -0700 >@@ -817,20 +817,20 @@ > { > Buffer m; > u_int i; > int ret; > >- debug3("%s", __func__); >+ debug2("%s", __func__); > buffer_init(&m); > buffer_put_int(&m, num); > for (i = 0; i < num; ++i) > buffer_put_cstring(&m, resp[i]); > mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PAM_RESPOND, &m); >- debug3("%s: waiting for MONITOR_ANS_PAM_RESPOND", __func__); >+ debug2("%s: waiting for MONITOR_ANS_PAM_RESPOND", __func__); > mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PAM_RESPOND, &m); > ret = buffer_get_int(&m); >- debug3("%s: pam_respond returned %d", __func__, ret); >+ debug2("%s: pam_respond returned %d", __func__, ret); > buffer_free(&m); > return (ret); > } > > void >@@ -1007,10 +1007,143 @@ > > return ((authok == 0) ? -1 : 0); > } > #endif /* SKEY */ > >+#ifdef USE_VTOKEN >+ >+#define VTOKEN_TIME_FRAME 30 >+ >+int >+mm_get_time(void) >+{ >+ int secs; >+ time_t now; >+ struct tm *its; >+ >+ /* use time as counter */ >+ now = time(NULL); >+ its = localtime(&now); >+ /* counter 60*60=3600 */ >+ secs = its->tm_min*60 + its->tm_sec; >+ >+ return(secs); >+} >+ >+int >+mm_calculate_challenge(int secret, int pin, int count) >+{ >+ int challenge; >+ >+ /* user calculable challenge */ >+ >+ /* !!! proof-of-concept !!! */ >+ /* this equation would be easy to brute-force if the >+ challenge is intercepted */ >+ challenge = (secret * count) % pin; >+ >+ return(challenge); >+} >+ >+static int >+mm_check_user_response(int c_entry) >+{ >+ int i, j=0, secs, curr_time, s_entry, sec1, sec2; >+ int authenticated=0, time_frame=VTOKEN_TIME_FRAME, ignore[VTOKEN_TIME_FRAME*2]; >+ char *user; >+ >+ /* get the user's secrets */ >+ for (i=0; options.vtoken_users[i] != NULL; i++) { >+ user=strtok(options.vtoken_users[i],":"); >+ sec1=atoi(strtok(NULL,":")); >+ sec2=atoi(strtok(NULL,":")); >+ debug("%s: %s secrets %d,%d",__func__,user,sec1,sec2); >+ } >+ >+ /* calculate solutions, for a given time frame, using user's secrets */ >+ curr_time = mm_get_time(); >+ for (i=-time_frame; i<=time_frame; i++) { >+ secs = curr_time + i; >+ s_entry = mm_calculate_challenge(sec1, sec2, secs); >+ >+ /* compare user and server solutions */ >+ if (s_entry == c_entry) { >+ authenticated=1; >+ ignore[j++] = s_entry; >+ break; >+ } >+ } >+ >+ return authenticated; >+} >+ >+int >+mm_vtoken_query(void *ctx, char **name, char **infotxt, >+ u_int *numprompts, char ***prompts, u_int **echo_on) >+{ >+ Buffer m; >+ u_int success; >+ char *challenge; >+ >+ buffer_init(&m); >+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_VTOKENQUERY, &m); >+ >+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_VTOKENQUERY, >+ &m); >+ success = buffer_get_int(&m); >+ if (success == 0) { >+ debug3("%s: no challenge", __func__); >+ buffer_free(&m); >+ return (-1); >+ } >+ >+ /* Get the challenge, and format the response */ >+ challenge = buffer_get_string(&m, NULL); >+ buffer_free(&m); >+ >+ debug2("%s: received challenge: %s", __func__, challenge); >+ >+ mm_chall_setup(name, infotxt, numprompts, prompts, echo_on); >+ >+ xasprintf(*prompts, "%s%s", challenge, "Virtual Token challenge: "); >+ xfree(challenge); >+ >+ return (0); >+} >+ >+int >+mm_vtoken_respond(void *ctx, u_int numresponses, char **responses) >+{ >+ Buffer m; >+ int authok, temp=atoi(responses[0]); >+ Authctxt *authctxt = ctx; >+ >+ debug3("%s entering", __func__); >+ if (numresponses != 1) >+ return (-1); >+ >+ buffer_init(&m); >+ buffer_put_cstring(&m, responses[0]); >+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_VTOKENRESPOND, &m); >+ >+ mm_request_receive_expect(pmonitor->m_recvfd, >+ MONITOR_ANS_VTOKENRESPOND, &m); >+ >+ authok = buffer_get_int(&m); >+ buffer_free(&m); >+ authctxt->postponed = 0; >+ >+ if (authctxt->valid && >+ numresponses == 1 && >+ mm_check_user_response(temp)) { >+ return 0; >+ } >+ return -1; >+} >+#endif /* USE_VTOKEN*/ >+ >+ > void > mm_ssh1_session_id(u_char session_id[16]) > { > Buffer m; > int i; >--- openssh-4.7p1/monitor_wrap.h 2006-08-04 20:39:40.000000000 -0600 >+++ openssh-kbdint-vtoken/monitor_wrap.h 2008-02-07 19:26:14.000000000 -0700 >@@ -99,10 +99,14 @@ > > /* skey */ > int mm_skey_query(void *, char **, char **, u_int *, char ***, u_int **); > int mm_skey_respond(void *, u_int, char **); > >+/* virtual token */ >+int mm_vtoken_query(void *, char **, char **, u_int *, char ***, u_int **); >+int mm_vtoken_respond(void *, u_int, char **); >+ > /* zlib allocation hooks */ > > void *mm_zalloc(struct mm_master *, u_int, u_int); > void mm_zfree(struct mm_master *, void *); > void mm_init_compression(struct mm_master *); >--- openssh-4.7p1/servconf.c 2007-05-19 23:03:16.000000000 -0600 >+++ openssh-kbdint-vtoken/servconf.c 2008-02-07 19:26:14.000000000 -0700 >@@ -120,10 +120,12 @@ > options->authorized_keys_file2 = NULL; > options->num_accept_env = 0; > options->permit_tun = -1; > options->num_permitted_opens = -1; > options->adm_forced_command = NULL; >+ options->vtoken_authentication = -1; >+ options->max_vtoken_users = 0; > } > > void > fill_default_server_options(ServerOptions *options) > { >@@ -261,10 +263,13 @@ > error("Compression disabled"); > options->compression = 0; > } > #endif > >+ if (options->vtoken_authentication == -1) >+ options->vtoken_authentication = 1; >+ > } > > /* Keyword tokens. */ > typedef enum { > sBadOption, /* == unknown option */ >@@ -290,12 +295,13 @@ > sBanner, sUseDNS, sHostbasedAuthentication, > sHostbasedUsesNameFromPacketOnly, sClientAliveInterval, > sClientAliveCountMax, sAuthorizedKeysFile, sAuthorizedKeysFile2, > sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, > sMatch, sPermitOpen, sForceCommand, >- sUsePrivilegeSeparation, >+ sUsePrivilegeSeparation, sFreetkUsers, > sDeprecated, sUnsupported >+ > } ServerOpCodes; > > #define SSHCFG_GLOBAL 0x01 /* allowed in main section of sshd_config */ > #define SSHCFG_MATCH 0x02 /* allowed inside a Match section */ > #define SSHCFG_ALL (SSHCFG_GLOBAL|SSHCFG_MATCH) >@@ -401,10 +407,11 @@ > { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL }, > { "permittunnel", sPermitTunnel, SSHCFG_GLOBAL }, > { "match", sMatch, SSHCFG_ALL }, > { "permitopen", sPermitOpen, SSHCFG_ALL }, > { "forcecommand", sForceCommand, SSHCFG_ALL }, >+ { "vtokenusers", sFreetkUsers, SSHCFG_GLOBAL }, > { NULL, sBadOption, 0 } > }; > > /* > * Returns the number of the token pointed to by cp or sBadOption. >@@ -1265,10 +1272,20 @@ > filename, linenum, arg); > while (arg) > arg = strdelim(&cp); > break; > >+ case sFreetkUsers: >+ while ((arg = strdelim(&cp)) && *arg != '\0') { >+ if (options->max_vtoken_users >= MAX_VTOKEN_USERS) >+ fatal("%s line %d: too many vtoken users.", >+ filename, linenum); >+ options->vtoken_users[options->max_vtoken_users++] = >+ xstrdup(arg); >+ } >+ break; >+ > default: > fatal("%s line %d: Missing handler for opcode %s (%d)", > filename, linenum, arg, opcode); > } > if ((arg = strdelim(&cp)) != NULL && *arg != '\0') >--- openssh-4.7p1/servconf.h 2007-02-19 04:25:38.000000000 -0700 >+++ openssh-kbdint-vtoken/servconf.h 2008-02-07 19:26:14.000000000 -0700 >@@ -24,10 +24,11 @@ > #define MAX_DENY_GROUPS 256 /* Max # groups on deny list. */ > #define MAX_SUBSYSTEMS 256 /* Max # subsystems. */ > #define MAX_HOSTKEYS 256 /* Max # hostkeys. */ > #define MAX_ACCEPT_ENV 256 /* Max # of env vars. */ > #define MAX_MATCH_GROUPS 256 /* Max # of groups for Match. */ >+#define MAX_VTOKEN_USERS 256 /* Max # of free token users. */ > > /* permit_root_login */ > #define PERMIT_NOT_SET -1 > #define PERMIT_NO 0 > #define PERMIT_FORCED_ONLY 1 >@@ -139,10 +140,14 @@ > int use_pam; /* Enable auth via PAM */ > > int permit_tun; > > int num_permitted_opens; >+ >+ int vtoken_authentication; /* Permit out-of-band challenge if true */ >+ int max_vtoken_users; >+ char *vtoken_users[MAX_VTOKEN_USERS]; > } ServerOptions; > > void initialize_server_options(ServerOptions *); > void fill_default_server_options(ServerOptions *); > int process_server_config_line(ServerOptions *, char *, const char *, int, >--- openssh-4.7p1/sshd_config.5 2007-06-10 22:07:13.000000000 -0600 >+++ openssh-kbdint-vtoken/sshd_config.5 2008-02-07 21:11:42.000000000 -0700 >@@ -170,10 +170,20 @@ > All authentication styles from > .Xr login.conf 5 > are supported. > The default is > .Dq yes . >+.It Cm VtokenUsers >+Specifies the two secrets used to calculate a user's virtual token challenge >+(VToken). The server generates a VToken challenge and waits for the user's >+response. The user is authenticated if he/she can respond with the same value. >+ >+Use the format: >+ >+VtokenUsers username:secret:PIN >+ >+ChallengeResponseAuthentication must be set for ChallengeUsers to work. > .It Cm Ciphers > Specifies the ciphers allowed for protocol version 2. > Multiple ciphers must be comma-separated. > The supported ciphers are > .Dq 3des-cbc , >--- openssh-4.7p1/README.vtoken 1969-12-31 17:00:00.000000000 -0700 >+++ openssh-kbdint-vtoken/README.vtoken 2008-02-07 23:07:46.000000000 -0700 >@@ -0,0 +1,37 @@ >+How to authenticate using the Virtual Token (VToken) Challenge >+ >+Overview: >+ >+The Virtual Token (VToken) patch adds a kbdint device that provides a new challenge-based authentication mechanism. The server calculates a challenge from two secrets and a counter. You authenticate by proving that you know the secrets by correctly answering the challenge. This creates a software-based token, similar in function to commercial ones, that can be run from your workstation or better yet, ubiquitous devices such as PDAs, cell phones, calculators, and even pen and paper. >+ >+VToken has the advantage of not only using cheap, generic devices but also not being network-aware. Commercial tokens can only be used on networks configured with a significant amount of dedicated infrastructure; they're network-based. VToken can be from on any machine running OpenSSH and a properly configured sshd_config file; it's a host-based system. >+ >+The current challenge is a place-holder for a more rigorous one. It uses the simple equation: Challenge=Secret*Counter Mod(PIN). The secret is designed to be embedded in the virtual token, while you must keep the PIN secret; the counter protects against replay attacks. Taking the modulus of the product maps the answer into a number set (or something like that) that . Ultimately, the calculation should probably be done by taking the hash of the combined terms (anyone who captures the current challenge will be able to calculate the secrets using brute force). >+ >+vtoken.c is an example virtual token app. It prompts you for your PIN and calculates the challenge response from the secret, which is embedded in it's source. >+ >+VToken in it's present form should be used in conjunction with the "Multiauth" patch (https://bugzilla.mindrot.org/show_bug.cgi?id=1435), which allows you to use multiple authentication methods tolog into a machine. You'll want to use Pubkey together with VToken. >+ >+In the future, VToken will by itself will provide two-factor authentication. The secret will be embedded in the app and effectively be embedded in your PDA, cell phone, etc. You'll keep your PIN separate, of course, and use the two just like on commercial tokens. >+ >+Configuration: >+ >+The user's secrets are stored in sshd_config using the format: >+ >+VTokenUsers username:secret:PIN >+ >+For instance, >+ >+VTokenUsers paul:1234:4321 >+ >+For the time-being the formula is challenge = secret * counter MOD(PIN) >+Eventually, the formula will probably be challenge = HASH(secret|counter|PIN). >+ >+ >+Compilation: >+ >+Install and compile the VToken patch: >+ >+authconf >+./configure --with-vtoken >+make install >--- openssh-4.7p1/vtoken.c 1969-12-31 17:00:00.000000000 -0700 >+++ openssh-kbdint-vtoken/vtoken.c 2008-02-07 19:57:42.000000000 -0700 >@@ -0,0 +1,84 @@ >+#include <ctype.h> >+#include <dirent.h> >+#include <errno.h> >+#include <fcntl.h> >+#include <pwd.h> >+#include <signal.h> >+#include <stdarg.h> >+#include <stdio.h> >+#include <stdlib.h> >+#include <string.h> >+#include <time.h> >+#include <unistd.h> >+ >+ >+#define PIN_LEN 4 >+ >+int getpin(void) >+{ >+ char line[PIN_LEN+1]; >+ int c, n=0, max=PIN_LEN+1; >+ >+ system("stty -echo"); >+ while((c = getchar()) != EOF) { >+ if(c == '\n') >+ break; >+ if(n < max) >+ line[n++] = c; >+ } >+ system("stty echo"); >+ printf("\n"); >+ >+ if(c == EOF && n == 0) >+ return(-1); >+ >+ line[n] = '\0'; >+ >+ return atoi(line); >+} >+ >+get_time(void) >+{ >+ int secs; >+ time_t now; >+ struct tm *its; >+ >+ /* construct term from hours, minutes and seconds */ >+ now = time(NULL); >+ its = localtime(&now); >+ secs = its->tm_hour*60*60 + its->tm_min*60 + its->tm_sec; >+ secs = its->tm_min*60 + its->tm_sec; >+ >+ return(secs); >+} >+ >+int >+calculate_challenge(int s1, int s2, int count) >+{ >+ int challenge; >+ >+ /* !!! proof-of-concept !!! */ >+ /* advantage: you can calculate the secret with paper and pencil >+ or simple calculator >+ advanatage: you can build a simple cell phone or pda app to >+ perform this function >+ disadvantage: the unknowns can be brute-forced if the >+ challenge is intercepted */ >+ >+ challenge = (count * s1) % s2; >+ >+ return(challenge); >+} >+ >+int >+main(int argc, char **argv) >+{ >+ int pin,count,secret=3361; >+ >+ printf("Enter PIN: "); >+ pin = getpin(); >+ >+ count = get_time(); >+ printf("challenge: %d\n",calculate_challenge(secret,pin,count) ); >+sleep(10); >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 1439
: 1453