[BACK]Return to sshconnect2.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Diff for /src/usr.bin/ssh/sshconnect2.c between version 1.201 and 1.202

version 1.201, 2014/01/09 23:20:00 version 1.202, 2014/01/29 06:18:35
Line 64 
Line 64 
 #include "pathnames.h"  #include "pathnames.h"
 #include "uidswap.h"  #include "uidswap.h"
 #include "hostfile.h"  #include "hostfile.h"
 #include "schnorr.h"  
 #include "jpake.h"  
   
 #ifdef GSSAPI  #ifdef GSSAPI
 #include "ssh-gss.h"  #include "ssh-gss.h"
Line 283 
Line 281 
 void    input_userauth_info_req(int, u_int32_t, void *);  void    input_userauth_info_req(int, u_int32_t, void *);
 void    input_userauth_pk_ok(int, u_int32_t, void *);  void    input_userauth_pk_ok(int, u_int32_t, void *);
 void    input_userauth_passwd_changereq(int, u_int32_t, void *);  void    input_userauth_passwd_changereq(int, u_int32_t, void *);
 void    input_userauth_jpake_server_step1(int, u_int32_t, void *);  
 void    input_userauth_jpake_server_step2(int, u_int32_t, void *);  
 void    input_userauth_jpake_server_confirm(int, u_int32_t, void *);  
   
 int     userauth_none(Authctxt *);  int     userauth_none(Authctxt *);
 int     userauth_pubkey(Authctxt *);  int     userauth_pubkey(Authctxt *);
 int     userauth_passwd(Authctxt *);  int     userauth_passwd(Authctxt *);
 int     userauth_kbdint(Authctxt *);  int     userauth_kbdint(Authctxt *);
 int     userauth_hostbased(Authctxt *);  int     userauth_hostbased(Authctxt *);
 int     userauth_jpake(Authctxt *);  
   
 void    userauth_jpake_cleanup(Authctxt *);  
   
 #ifdef GSSAPI  #ifdef GSSAPI
 int     userauth_gssapi(Authctxt *authctxt);  int     userauth_gssapi(Authctxt *authctxt);
 void    input_gssapi_response(int type, u_int32_t, void *);  void    input_gssapi_response(int type, u_int32_t, void *);
Line 334 
Line 326 
                 NULL,                  NULL,
                 &options.pubkey_authentication,                  &options.pubkey_authentication,
                 NULL},                  NULL},
 #ifdef JPAKE  
         {"jpake-01@openssh.com",  
                 userauth_jpake,  
                 userauth_jpake_cleanup,  
                 &options.zero_knowledge_password_authentication,  
                 &options.batch_mode},  
 #endif  
         {"keyboard-interactive",          {"keyboard-interactive",
                 userauth_kbdint,                  userauth_kbdint,
                 NULL,                  NULL,
Line 959 
Line 944 
             &input_userauth_passwd_changereq);              &input_userauth_passwd_changereq);
 }  }
   
 #ifdef JPAKE  
 static char *  
 pw_encrypt(const char *password, const char *crypt_scheme, const char *salt)  
 {  
         /* OpenBSD crypt(3) handles all of these */  
         if (strcmp(crypt_scheme, "crypt") == 0 ||  
             strcmp(crypt_scheme, "bcrypt") == 0 ||  
             strcmp(crypt_scheme, "md5crypt") == 0 ||  
             strcmp(crypt_scheme, "crypt-extended") == 0)  
                 return xstrdup(crypt(password, salt));  
         error("%s: unsupported password encryption scheme \"%.100s\"",  
             __func__, crypt_scheme);  
         return NULL;  
 }  
   
 static BIGNUM *  
 jpake_password_to_secret(Authctxt *authctxt, const char *crypt_scheme,  
     const char *salt)  
 {  
         char prompt[256], *password, *crypted;  
         u_char *secret;  
         u_int secret_len;  
         BIGNUM *ret;  
   
         snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password (JPAKE): ",  
             authctxt->server_user, authctxt->host);  
         password = read_passphrase(prompt, 0);  
   
         if ((crypted = pw_encrypt(password, crypt_scheme, salt)) == NULL) {  
                 logit("Disabling %s authentication", authctxt->method->name);  
                 authctxt->method->enabled = NULL;  
                 /* Continue with an empty password to fail gracefully */  
                 crypted = xstrdup("");  
         }  
   
 #ifdef JPAKE_DEBUG  
         debug3("%s: salt = %s", __func__, salt);  
         debug3("%s: scheme = %s", __func__, crypt_scheme);  
         debug3("%s: crypted = %s", __func__, crypted);  
 #endif  
   
         if (hash_buffer(crypted, strlen(crypted), SSH_DIGEST_SHA1,  
             &secret, &secret_len) != 0)  
                 fatal("%s: hash_buffer", __func__);  
   
         bzero(password, strlen(password));  
         bzero(crypted, strlen(crypted));  
         free(password);  
         free(crypted);  
   
         if ((ret = BN_bin2bn(secret, secret_len, NULL)) == NULL)  
                 fatal("%s: BN_bin2bn (secret)", __func__);  
         bzero(secret, secret_len);  
         free(secret);  
   
         return ret;  
 }  
   
 /* ARGSUSED */  
 void  
 input_userauth_jpake_server_step1(int type, u_int32_t seq, void *ctxt)  
 {  
         Authctxt *authctxt = ctxt;  
         struct jpake_ctx *pctx = authctxt->methoddata;  
         u_char *x3_proof, *x4_proof, *x2_s_proof;  
         u_int x3_proof_len, x4_proof_len, x2_s_proof_len;  
         char *crypt_scheme, *salt;  
   
         /* Disable this message */  
         dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1, NULL);  
   
         if ((pctx->g_x3 = BN_new()) == NULL ||  
             (pctx->g_x4 = BN_new()) == NULL)  
                 fatal("%s: BN_new", __func__);  
   
         /* Fetch step 1 values */  
         crypt_scheme = packet_get_string(NULL);  
         salt = packet_get_string(NULL);  
         pctx->server_id = packet_get_string(&pctx->server_id_len);  
         packet_get_bignum2(pctx->g_x3);  
         packet_get_bignum2(pctx->g_x4);  
         x3_proof = packet_get_string(&x3_proof_len);  
         x4_proof = packet_get_string(&x4_proof_len);  
         packet_check_eom();  
   
         JPAKE_DEBUG_CTX((pctx, "step 1 received in %s", __func__));  
   
         /* Obtain password and derive secret */  
         pctx->s = jpake_password_to_secret(authctxt, crypt_scheme, salt);  
         bzero(crypt_scheme, strlen(crypt_scheme));  
         bzero(salt, strlen(salt));  
         free(crypt_scheme);  
         free(salt);  
         JPAKE_DEBUG_BN((pctx->s, "%s: s = ", __func__));  
   
         /* Calculate step 2 values */  
         jpake_step2(pctx->grp, pctx->s, pctx->g_x1,  
             pctx->g_x3, pctx->g_x4, pctx->x2,  
             pctx->server_id, pctx->server_id_len,  
             pctx->client_id, pctx->client_id_len,  
             x3_proof, x3_proof_len,  
             x4_proof, x4_proof_len,  
             &pctx->a,  
             &x2_s_proof, &x2_s_proof_len);  
   
         bzero(x3_proof, x3_proof_len);  
         bzero(x4_proof, x4_proof_len);  
         free(x3_proof);  
         free(x4_proof);  
   
         JPAKE_DEBUG_CTX((pctx, "step 2 sending in %s", __func__));  
   
         /* Send values for step 2 */  
         packet_start(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP2);  
         packet_put_bignum2(pctx->a);  
         packet_put_string(x2_s_proof, x2_s_proof_len);  
         packet_send();  
   
         bzero(x2_s_proof, x2_s_proof_len);  
         free(x2_s_proof);  
   
         /* Expect step 2 packet from peer */  
         dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP2,  
             input_userauth_jpake_server_step2);  
 }  
   
 /* ARGSUSED */  
 void  
 input_userauth_jpake_server_step2(int type, u_int32_t seq, void *ctxt)  
 {  
         Authctxt *authctxt = ctxt;  
         struct jpake_ctx *pctx = authctxt->methoddata;  
         u_char *x4_s_proof;  
         u_int x4_s_proof_len;  
   
         /* Disable this message */  
         dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP2, NULL);  
   
         if ((pctx->b = BN_new()) == NULL)  
                 fatal("%s: BN_new", __func__);  
   
         /* Fetch step 2 values */  
         packet_get_bignum2(pctx->b);  
         x4_s_proof = packet_get_string(&x4_s_proof_len);  
         packet_check_eom();  
   
         JPAKE_DEBUG_CTX((pctx, "step 2 received in %s", __func__));  
   
         /* Derive shared key and calculate confirmation hash */  
         jpake_key_confirm(pctx->grp, pctx->s, pctx->b,  
             pctx->x2, pctx->g_x1, pctx->g_x2, pctx->g_x3, pctx->g_x4,  
             pctx->client_id, pctx->client_id_len,  
             pctx->server_id, pctx->server_id_len,  
             session_id2, session_id2_len,  
             x4_s_proof, x4_s_proof_len,  
             &pctx->k,  
             &pctx->h_k_cid_sessid, &pctx->h_k_cid_sessid_len);  
   
         bzero(x4_s_proof, x4_s_proof_len);  
         free(x4_s_proof);  
   
         JPAKE_DEBUG_CTX((pctx, "confirm sending in %s", __func__));  
   
         /* Send key confirmation proof */  
         packet_start(SSH2_MSG_USERAUTH_JPAKE_CLIENT_CONFIRM);  
         packet_put_string(pctx->h_k_cid_sessid, pctx->h_k_cid_sessid_len);  
         packet_send();  
   
         /* Expect confirmation from peer */  
         dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_CONFIRM,  
             input_userauth_jpake_server_confirm);  
 }  
   
 /* ARGSUSED */  
 void  
 input_userauth_jpake_server_confirm(int type, u_int32_t seq, void *ctxt)  
 {  
         Authctxt *authctxt = ctxt;  
         struct jpake_ctx *pctx = authctxt->methoddata;  
   
         /* Disable this message */  
         dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_CONFIRM, NULL);  
   
         pctx->h_k_sid_sessid = packet_get_string(&pctx->h_k_sid_sessid_len);  
         packet_check_eom();  
   
         JPAKE_DEBUG_CTX((pctx, "confirm received in %s", __func__));  
   
         /* Verify expected confirmation hash */  
         if (jpake_check_confirm(pctx->k,  
             pctx->server_id, pctx->server_id_len,  
             session_id2, session_id2_len,  
             pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len) == 1)  
                 debug("%s: %s success", __func__, authctxt->method->name);  
         else {  
                 debug("%s: confirmation mismatch", __func__);  
                 /* XXX stash this so if auth succeeds then we can warn/kill */  
         }  
   
         userauth_jpake_cleanup(authctxt);  
 }  
 #endif /* JPAKE */  
   
 static int  static int
 identity_sign(Identity *id, u_char **sigp, u_int *lenp,  identity_sign(Identity *id, u_char **sigp, u_int *lenp,
     u_char *data, u_int datalen)      u_char *data, u_int datalen)
Line 1776 
Line 1558 
         packet_send();          packet_send();
         return 1;          return 1;
 }  }
   
 #ifdef JPAKE  
 int  
 userauth_jpake(Authctxt *authctxt)  
 {  
         struct jpake_ctx *pctx;  
         u_char *x1_proof, *x2_proof;  
         u_int x1_proof_len, x2_proof_len;  
         static int attempt = 0; /* XXX share with userauth_password's? */  
   
         if (attempt++ >= options.number_of_password_prompts)  
                 return 0;  
         if (attempt != 1)  
                 error("Permission denied, please try again.");  
   
         if (authctxt->methoddata != NULL)  
                 fatal("%s: authctxt->methoddata already set (%p)",  
                     __func__, authctxt->methoddata);  
   
         authctxt->methoddata = pctx = jpake_new();  
   
         /*  
          * Send request immediately, to get the protocol going while  
          * we do the initial computations.  
          */  
         packet_start(SSH2_MSG_USERAUTH_REQUEST);  
         packet_put_cstring(authctxt->server_user);  
         packet_put_cstring(authctxt->service);  
         packet_put_cstring(authctxt->method->name);  
         packet_send();  
         packet_write_wait();  
   
         jpake_step1(pctx->grp,  
             &pctx->client_id, &pctx->client_id_len,  
             &pctx->x1, &pctx->x2, &pctx->g_x1, &pctx->g_x2,  
             &x1_proof, &x1_proof_len,  
             &x2_proof, &x2_proof_len);  
   
         JPAKE_DEBUG_CTX((pctx, "step 1 sending in %s", __func__));  
   
         packet_start(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP1);  
         packet_put_string(pctx->client_id, pctx->client_id_len);  
         packet_put_bignum2(pctx->g_x1);  
         packet_put_bignum2(pctx->g_x2);  
         packet_put_string(x1_proof, x1_proof_len);  
         packet_put_string(x2_proof, x2_proof_len);  
         packet_send();  
   
         bzero(x1_proof, x1_proof_len);  
         bzero(x2_proof, x2_proof_len);  
         free(x1_proof);  
         free(x2_proof);  
   
         /* Expect step 1 packet from peer */  
         dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1,  
             input_userauth_jpake_server_step1);  
         dispatch_set(SSH2_MSG_USERAUTH_SUCCESS,  
             &input_userauth_success_unexpected);  
   
         return 1;  
 }  
   
 void  
 userauth_jpake_cleanup(Authctxt *authctxt)  
 {  
         debug3("%s: clean up", __func__);  
         if (authctxt->methoddata != NULL) {  
                 jpake_free(authctxt->methoddata);  
                 authctxt->methoddata = NULL;  
         }  
         dispatch_set(SSH2_MSG_USERAUTH_SUCCESS, &input_userauth_success);  
 }  
 #endif /* JPAKE */  
   
 /* find auth method */  /* find auth method */
   

Legend:
Removed from v.1.201  
changed lines
  Added in v.1.202