[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.277 and 1.278

version 1.277, 2018/07/09 13:37:10 version 1.278, 2018/07/09 21:03:30
Line 43 
Line 43 
 #include "xmalloc.h"  #include "xmalloc.h"
 #include "ssh.h"  #include "ssh.h"
 #include "ssh2.h"  #include "ssh2.h"
 #include "buffer.h"  #include "sshbuf.h"
 #include "packet.h"  #include "packet.h"
 #include "compat.h"  #include "compat.h"
 #include "cipher.h"  #include "cipher.h"
 #include "key.h"  #include "sshkey.h"
 #include "kex.h"  #include "kex.h"
 #include "myproposal.h"  #include "myproposal.h"
 #include "sshconnect.h"  #include "sshconnect.h"
Line 224 
Line 224 
   
 #ifdef DEBUG_KEXDH  #ifdef DEBUG_KEXDH
         /* send 1st encrypted/maced/compressed message */          /* send 1st encrypted/maced/compressed message */
         packet_start(SSH2_MSG_IGNORE);          if ((r = sshpkt_start(ssh, SSH2_MSG_IGNORE)) != 0 ||
         packet_put_cstring("markus");              (r = sshpkt_put_cstring(ssh, "markus")) != 0 ||
         packet_send();              (r = sshpkt_send(ssh)) != 0)
         packet_write_wait();                  fatal("%s: %s", __func__, ssh_err(r));
           ssh_packet_write_wait(ssh);
 #endif  #endif
 }  }
   
Line 449 
Line 450 
 void  void
 userauth(Authctxt *authctxt, char *authlist)  userauth(Authctxt *authctxt, char *authlist)
 {  {
           struct ssh *ssh = active_state; /* XXX */
   
         if (authctxt->method != NULL && authctxt->method->cleanup != NULL)          if (authctxt->method != NULL && authctxt->method->cleanup != NULL)
                 authctxt->method->cleanup(authctxt);                  authctxt->method->cleanup(authctxt);
   
Line 468 
Line 471 
                 authctxt->method = method;                  authctxt->method = method;
   
                 /* reset the per method handler */                  /* reset the per method handler */
                 dispatch_range(SSH2_MSG_USERAUTH_PER_METHOD_MIN,                  ssh_dispatch_range(ssh, SSH2_MSG_USERAUTH_PER_METHOD_MIN,
                     SSH2_MSG_USERAUTH_PER_METHOD_MAX, NULL);                      SSH2_MSG_USERAUTH_PER_METHOD_MAX, NULL);
   
                 /* and try new method */                  /* and try new method */
Line 545 
Line 548 
 {  {
         Authctxt *authctxt = ssh->authctxt;          Authctxt *authctxt = ssh->authctxt;
         char *authlist = NULL;          char *authlist = NULL;
         int partial;          u_char partial;
           int r;
   
         if (authctxt == NULL)          if (authctxt == NULL)
                 fatal("input_userauth_failure: no authentication context");                  fatal("input_userauth_failure: no authentication context");
   
         authlist = packet_get_string(NULL);          if ((r = sshpkt_get_cstring(ssh, &authlist, NULL)) != 0 ||
         partial = packet_get_char();              (r = sshpkt_get_u8(ssh, &partial)) != 0 ||
         packet_check_eom();              (r = sshpkt_get_end(ssh)) != 0)
                   goto out;
   
         if (partial != 0) {          if (partial != 0) {
                 verbose("Authenticated with partial success.");                  verbose("Authenticated with partial success.");
Line 562 
Line 567 
         debug("Authentications that can continue: %s", authlist);          debug("Authentications that can continue: %s", authlist);
   
         userauth(authctxt, authlist);          userauth(authctxt, authlist);
           authlist = NULL;
    out:
           free(authlist);
         return 0;          return 0;
 }  }
   
Line 573 
Line 581 
         struct sshkey *key = NULL;          struct sshkey *key = NULL;
         Identity *id = NULL;          Identity *id = NULL;
         int pktype, sent = 0;          int pktype, sent = 0;
         u_int alen, blen;          size_t blen;
         char *pkalg, *fp;          char *pkalg = NULL, *fp;
         u_char *pkblob;          u_char *pkblob = NULL;
           int r;
   
         if (authctxt == NULL)          if (authctxt == NULL)
                 fatal("input_userauth_pk_ok: no authentication context");                  fatal("input_userauth_pk_ok: no authentication context");
   
         pkalg = packet_get_string(&alen);          if ((r = sshpkt_get_cstring(ssh, &pkalg, NULL)) != 0 ||
         pkblob = packet_get_string(&blen);              (r = sshpkt_get_string(ssh, &pkblob, &blen)) != 0 ||
         packet_check_eom();              (r = sshpkt_get_end(ssh)) != 0)
                   goto done;
   
         debug("Server accepts key: pkalg %s blen %u", pkalg, blen);          debug("Server accepts key: pkalg %s blen %zu", pkalg, blen);
   
         if ((pktype = key_type_from_name(pkalg)) == KEY_UNSPEC) {          if ((pktype = sshkey_type_from_name(pkalg)) == KEY_UNSPEC) {
                 debug("unknown pkalg %s", pkalg);                  debug("unknown pkalg %s", pkalg);
                 goto done;                  goto done;
         }          }
         if ((key = key_from_blob(pkblob, blen)) == NULL) {          if ((r = sshkey_from_blob(pkblob, blen, &key)) != 0) {
                 debug("no key from blob. pkalg %s", pkalg);                  debug("no key from blob. pkalg %s: %s", pkalg, ssh_err(r));
                 goto done;                  goto done;
         }          }
         if (key->type != pktype) {          if (key->type != pktype) {
Line 612 
Line 622 
          * duplicate keys           * duplicate keys
          */           */
         TAILQ_FOREACH_REVERSE(id, &authctxt->keys, idlist, next) {          TAILQ_FOREACH_REVERSE(id, &authctxt->keys, idlist, next) {
                 if (key_equal(key, id->key)) {                  if (sshkey_equal(key, id->key)) {
                         sent = sign_and_send_pubkey(ssh, authctxt, id);                          sent = sign_and_send_pubkey(ssh, authctxt, id);
                         break;                          break;
                 }                  }
         }          }
 done:          r = 0;
         key_free(key);   done:
           sshkey_free(key);
         free(pkalg);          free(pkalg);
         free(pkblob);          free(pkblob);
   
         /* try another method if we did not send a packet */          /* try another method if we did not send a packet */
         if (sent == 0)          if (r == 0 && sent == 0)
                 userauth(authctxt, NULL);                  userauth(authctxt, NULL);
         return 0;          return r;
 }  }
   
 #ifdef GSSAPI  #ifdef GSSAPI
 int  int
 userauth_gssapi(Authctxt *authctxt)  userauth_gssapi(Authctxt *authctxt)
 {  {
           struct ssh *ssh = active_state; /* XXX */
         Gssctxt *gssctxt = NULL;          Gssctxt *gssctxt = NULL;
         static gss_OID_set gss_supported = NULL;          static gss_OID_set gss_supported = NULL;
         static u_int mech = 0;          static u_int mech = 0;
         OM_uint32 min;          OM_uint32 min;
         int ok = 0;          int r, ok = 0;
   
         /* Try one GSSAPI method at a time, rather than sending them all at          /* Try one GSSAPI method at a time, rather than sending them all at
          * once. */           * once. */
Line 661 
Line 673 
   
         authctxt->methoddata=(void *)gssctxt;          authctxt->methoddata=(void *)gssctxt;
   
         packet_start(SSH2_MSG_USERAUTH_REQUEST);          if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
         packet_put_cstring(authctxt->server_user);              (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 ||
         packet_put_cstring(authctxt->service);              (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 ||
         packet_put_cstring(authctxt->method->name);              (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 ||
               (r = sshpkt_put_u32(ssh, 1)) != 0 ||
               (r = sshpkt_put_u32(ssh,
               (gss_supported->elements[mech].length) + 2)) != 0 ||
               (r = sshpkt_put_u8(ssh, SSH_GSS_OIDTYPE)) != 0 ||
               (r = sshpkt_put_u8(ssh,
               gss_supported->elements[mech].length)) != 0 ||
               (r = sshpkt_put(ssh,
               gss_supported->elements[mech].elements,
               gss_supported->elements[mech].length)) != 0 ||
               (r = sshpkt_send(ssh)) != 0)
                   fatal("%s: %s", __func__, ssh_err(r));
   
         packet_put_int(1);          ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_RESPONSE, &input_gssapi_response);
           ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token);
           ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERROR, &input_gssapi_error);
           ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok);
   
         packet_put_int((gss_supported->elements[mech].length) + 2);  
         packet_put_char(SSH_GSS_OIDTYPE);  
         packet_put_char(gss_supported->elements[mech].length);  
         packet_put_raw(gss_supported->elements[mech].elements,  
             gss_supported->elements[mech].length);  
   
         packet_send();  
   
         dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE, &input_gssapi_response);  
         dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, &input_gssapi_token);  
         dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERROR, &input_gssapi_error);  
         dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, &input_gssapi_errtok);  
   
         mech++; /* Move along to next candidate */          mech++; /* Move along to next candidate */
   
         return 1;          return 1;
Line 695 
Line 708 
         gss_buffer_desc mic = GSS_C_EMPTY_BUFFER;          gss_buffer_desc mic = GSS_C_EMPTY_BUFFER;
         gss_buffer_desc gssbuf;          gss_buffer_desc gssbuf;
         OM_uint32 status, ms, flags;          OM_uint32 status, ms, flags;
         Buffer b;          int r;
   
         status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,          status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
             recv_tok, &send_tok, &flags);              recv_tok, &send_tok, &flags);
   
         if (send_tok.length > 0) {          if (send_tok.length > 0) {
                 if (GSS_ERROR(status))                  u_char type = GSS_ERROR(status) ?
                         packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK);                      SSH2_MSG_USERAUTH_GSSAPI_ERRTOK :
                 else                      SSH2_MSG_USERAUTH_GSSAPI_TOKEN;
                         packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);  
   
                 packet_put_string(send_tok.value, send_tok.length);                  if ((r = sshpkt_start(ssh, type)) != 0 ||
                 packet_send();                      (r = sshpkt_put_string(ssh, send_tok.value,
                       send_tok.length)) != 0 ||
                       (r = sshpkt_send(ssh)) != 0)
                           fatal("%s: %s", __func__, ssh_err(r));
   
                 gss_release_buffer(&ms, &send_tok);                  gss_release_buffer(&ms, &send_tok);
         }          }
   
         if (status == GSS_S_COMPLETE) {          if (status == GSS_S_COMPLETE) {
                 /* send either complete or MIC, depending on mechanism */                  /* send either complete or MIC, depending on mechanism */
                 if (!(flags & GSS_C_INTEG_FLAG)) {                  if (!(flags & GSS_C_INTEG_FLAG)) {
                         packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE);                          if ((r = sshpkt_start(ssh,
                         packet_send();                              SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE)) != 0 ||
                               (r = sshpkt_send(ssh)) != 0)
                                   fatal("%s: %s", __func__, ssh_err(r));
                 } else {                  } else {
                         ssh_gssapi_buildmic(&b, authctxt->server_user,                          struct sshbuf *b;
   
                           if ((b = sshbuf_new()) == NULL)
                                   fatal("%s: sshbuf_new failed", __func__);
                           ssh_gssapi_buildmic(b, authctxt->server_user,
                             authctxt->service, "gssapi-with-mic");                              authctxt->service, "gssapi-with-mic");
   
                         gssbuf.value = buffer_ptr(&b);                          if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL)
                         gssbuf.length = buffer_len(&b);                                  fatal("%s: sshbuf_mutable_ptr failed", __func__);
                           gssbuf.length = sshbuf_len(b);
   
                         status = ssh_gssapi_sign(gssctxt, &gssbuf, &mic);                          status = ssh_gssapi_sign(gssctxt, &gssbuf, &mic);
   
                         if (!GSS_ERROR(status)) {                          if (!GSS_ERROR(status)) {
                                 packet_start(SSH2_MSG_USERAUTH_GSSAPI_MIC);                                  if ((r = sshpkt_start(ssh,
                                 packet_put_string(mic.value, mic.length);                                      SSH2_MSG_USERAUTH_GSSAPI_MIC)) != 0 ||
                                       (r = sshpkt_put_string(ssh, mic.value,
                                 packet_send();                                      mic.length)) != 0 ||
                                       (r = sshpkt_send(ssh)) != 0)
                                           fatal("%s: %s", __func__, ssh_err(r));
                         }                          }
   
                         buffer_free(&b);                          sshbuf_free(b);
                         gss_release_buffer(&ms, &mic);                          gss_release_buffer(&ms, &mic);
                 }                  }
         }          }
Line 746 
Line 771 
 {  {
         Authctxt *authctxt = ssh->authctxt;          Authctxt *authctxt = ssh->authctxt;
         Gssctxt *gssctxt;          Gssctxt *gssctxt;
         int oidlen;          size_t oidlen;
         char *oidv;          u_char *oidv = NULL;
           int r;
   
         if (authctxt == NULL)          if (authctxt == NULL)
                 fatal("input_gssapi_response: no authentication context");                  fatal("input_gssapi_response: no authentication context");
         gssctxt = authctxt->methoddata;          gssctxt = authctxt->methoddata;
   
         /* Setup our OID */          /* Setup our OID */
         oidv = packet_get_string(&oidlen);          if ((r = sshpkt_get_string(ssh, &oidv, &oidlen)) != 0)
                   goto done;
   
         if (oidlen <= 2 ||          if (oidlen <= 2 ||
             oidv[0] != SSH_GSS_OIDTYPE ||              oidv[0] != SSH_GSS_OIDTYPE ||
             oidv[1] != oidlen - 2) {              oidv[1] != oidlen - 2) {
                 free(oidv);  
                 debug("Badly encoded mechanism OID received");                  debug("Badly encoded mechanism OID received");
                 userauth(authctxt, NULL);                  userauth(authctxt, NULL);
                 return 0;                  goto ok;
         }          }
   
         if (!ssh_gssapi_check_oid(gssctxt, oidv + 2, oidlen - 2))          if (!ssh_gssapi_check_oid(gssctxt, oidv + 2, oidlen - 2))
                 fatal("Server returned different OID than expected");                  fatal("Server returned different OID than expected");
   
         packet_check_eom();          if ((r = sshpkt_get_end(ssh)) != 0)
                   goto done;
   
         free(oidv);  
   
         if (GSS_ERROR(process_gssapi_token(ssh, GSS_C_NO_BUFFER))) {          if (GSS_ERROR(process_gssapi_token(ssh, GSS_C_NO_BUFFER))) {
                 /* Start again with next method on list */                  /* Start again with next method on list */
                 debug("Trying to start again");                  debug("Trying to start again");
                 userauth(authctxt, NULL);                  userauth(authctxt, NULL);
                 return 0;                  goto ok;
         }          }
         return 0;   ok:
           r = 0;
    done:
           free(oidv);
           return r;
 }  }
   
 /* ARGSUSED */  /* ARGSUSED */
Line 787 
Line 816 
 {  {
         Authctxt *authctxt = ssh->authctxt;          Authctxt *authctxt = ssh->authctxt;
         gss_buffer_desc recv_tok;          gss_buffer_desc recv_tok;
           u_char *p = NULL;
           size_t len;
         OM_uint32 status;          OM_uint32 status;
         u_int slen;          int r;
   
         if (authctxt == NULL)          if (authctxt == NULL)
                 fatal("input_gssapi_response: no authentication context");                  fatal("input_gssapi_response: no authentication context");
   
         recv_tok.value = packet_get_string(&slen);          if ((r = sshpkt_get_string(ssh, &p, &len)) != 0 ||
         recv_tok.length = slen; /* safe typecast */              (r = sshpkt_get_end(ssh)) != 0)
                   goto out;
   
         packet_check_eom();          recv_tok.value = p;
           recv_tok.length = len;
         status = process_gssapi_token(ssh, &recv_tok);          status = process_gssapi_token(ssh, &recv_tok);
   
         free(recv_tok.value);          /* Start again with the next method in the list */
   
         if (GSS_ERROR(status)) {          if (GSS_ERROR(status)) {
                 /* Start again with the next method in the list */  
                 userauth(authctxt, NULL);                  userauth(authctxt, NULL);
                 return 0;                  /* ok */
         }          }
         return 0;          r = 0;
    out:
           free(p);
           return r;
 }  }
   
 /* ARGSUSED */  /* ARGSUSED */
Line 819 
Line 852 
         gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;          gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
         gss_buffer_desc recv_tok;          gss_buffer_desc recv_tok;
         OM_uint32 ms;          OM_uint32 ms;
         u_int len;          u_char *p = NULL;
           size_t len;
           int r;
   
         if (authctxt == NULL)          if (authctxt == NULL)
                 fatal("input_gssapi_response: no authentication context");                  fatal("input_gssapi_response: no authentication context");
         gssctxt = authctxt->methoddata;          gssctxt = authctxt->methoddata;
   
         recv_tok.value = packet_get_string(&len);          if ((r = sshpkt_get_string(ssh, &p, &len)) != 0 ||
         recv_tok.length = len;              (r = sshpkt_get_end(ssh)) != 0) {
                   free(p);
                   return r;
           }
   
         packet_check_eom();  
   
         /* Stick it into GSSAPI and see what it says */          /* Stick it into GSSAPI and see what it says */
           recv_tok.value = p;
           recv_tok.length = len;
         (void)ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,          (void)ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
             &recv_tok, &send_tok, NULL);              &recv_tok, &send_tok, NULL);
           free(p);
         free(recv_tok.value);  
         gss_release_buffer(&ms, &send_tok);          gss_release_buffer(&ms, &send_tok);
   
         /* Server will be returning a failed packet after this one */          /* Server will be returning a failed packet after this one */
Line 845 
Line 882 
 int  int
 input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh)  input_gssapi_error(int type, u_int32_t plen, struct ssh *ssh)
 {  {
         char *msg;          char *msg = NULL;
         char *lang;          char *lang = NULL;
           int r;
   
         /* maj */(void)packet_get_int();          if ((r = sshpkt_get_u32(ssh, NULL)) != 0 ||     /* maj */
         /* min */(void)packet_get_int();              (r = sshpkt_get_u32(ssh, NULL)) != 0 ||     /* min */
         msg=packet_get_string(NULL);              (r = sshpkt_get_cstring(ssh, &msg, NULL)) != 0 ||
         lang=packet_get_string(NULL);              (r = sshpkt_get_cstring(ssh, &lang, NULL)) != 0)
                   goto out;
         packet_check_eom();          r = sshpkt_get_end(ssh);
   
         debug("Server GSSAPI Error:\n%s", msg);          debug("Server GSSAPI Error:\n%s", msg);
    out:
         free(msg);          free(msg);
         free(lang);          free(lang);
         return 0;          return r;
 }  }
 #endif /* GSSAPI */  #endif /* GSSAPI */
   
 int  int
 userauth_none(Authctxt *authctxt)  userauth_none(Authctxt *authctxt)
 {  {
           struct ssh *ssh = active_state; /* XXX */
           int r;
   
         /* initial userauth request */          /* initial userauth request */
         packet_start(SSH2_MSG_USERAUTH_REQUEST);          if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
         packet_put_cstring(authctxt->server_user);              (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 ||
         packet_put_cstring(authctxt->service);              (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 ||
         packet_put_cstring(authctxt->method->name);              (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 ||
         packet_send();              (r = sshpkt_send(ssh)) != 0)
                   fatal("%s: %s", __func__, ssh_err(r));
         return 1;          return 1;
 }  }
   
 int  int
 userauth_passwd(Authctxt *authctxt)  userauth_passwd(Authctxt *authctxt)
 {  {
           struct ssh *ssh = active_state; /* XXX */
         static int attempt = 0;          static int attempt = 0;
         char prompt[256];          char prompt[256];
         char *password;          char *password;
         const char *host = options.host_key_alias ?  options.host_key_alias :          const char *host = options.host_key_alias ?  options.host_key_alias :
             authctxt->host;              authctxt->host;
           int r;
   
         if (attempt++ >= options.number_of_password_prompts)          if (attempt++ >= options.number_of_password_prompts)
                 return 0;                  return 0;
Line 892 
Line 936 
         snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",          snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password: ",
             authctxt->server_user, host);              authctxt->server_user, host);
         password = read_passphrase(prompt, 0);          password = read_passphrase(prompt, 0);
         packet_start(SSH2_MSG_USERAUTH_REQUEST);          if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
         packet_put_cstring(authctxt->server_user);              (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 ||
         packet_put_cstring(authctxt->service);              (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 ||
         packet_put_cstring(authctxt->method->name);              (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 ||
         packet_put_char(0);              (r = sshpkt_put_u8(ssh, 0)) != 0 ||
         packet_put_cstring(password);              (r = sshpkt_put_cstring(ssh, password)) != 0 ||
         explicit_bzero(password, strlen(password));              (r = sshpkt_add_padding(ssh, 64)) != 0 ||
         free(password);              (r = sshpkt_send(ssh)) != 0)
         packet_add_padding(64);                  fatal("%s: %s", __func__, ssh_err(r));
         packet_send();  
   
         dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ,          if (password)
                   freezero(password, strlen(password));
   
           ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ,
             &input_userauth_passwd_changereq);              &input_userauth_passwd_changereq);
   
         return 1;          return 1;
Line 917 
Line 963 
 input_userauth_passwd_changereq(int type, u_int32_t seqnr, struct ssh *ssh)  input_userauth_passwd_changereq(int type, u_int32_t seqnr, struct ssh *ssh)
 {  {
         Authctxt *authctxt = ssh->authctxt;          Authctxt *authctxt = ssh->authctxt;
         char *info, *lang, *password = NULL, *retype = NULL;          char *info = NULL, *lang = NULL, *password = NULL, *retype = NULL;
         char prompt[256];          char prompt[256];
         const char *host;          const char *host;
           int r;
   
         debug2("input_userauth_passwd_changereq");          debug2("input_userauth_passwd_changereq");
   
Line 928 
Line 975 
                     "no authentication context");                      "no authentication context");
         host = options.host_key_alias ? options.host_key_alias : authctxt->host;          host = options.host_key_alias ? options.host_key_alias : authctxt->host;
   
         info = packet_get_string(NULL);          if ((r = sshpkt_get_cstring(ssh, &info, NULL)) != 0 ||
         lang = packet_get_string(NULL);              (r = sshpkt_get_cstring(ssh, &lang, NULL)) != 0)
                   goto out;
         if (strlen(info) > 0)          if (strlen(info) > 0)
                 logit("%s", info);                  logit("%s", info);
         free(info);          if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
         free(lang);              (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 ||
         packet_start(SSH2_MSG_USERAUTH_REQUEST);              (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 ||
         packet_put_cstring(authctxt->server_user);              (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 ||
         packet_put_cstring(authctxt->service);              (r = sshpkt_put_u8(ssh, 1)) != 0)   /* additional info */
         packet_put_cstring(authctxt->method->name);                  goto out;
         packet_put_char(1);                     /* additional info */  
         snprintf(prompt, sizeof(prompt),          snprintf(prompt, sizeof(prompt),
             "Enter %.30s@%.128s's old password: ",              "Enter %.30s@%.128s's old password: ",
             authctxt->server_user, host);              authctxt->server_user, host);
         password = read_passphrase(prompt, 0);          password = read_passphrase(prompt, 0);
         packet_put_cstring(password);          if ((r = sshpkt_put_cstring(ssh, password)) != 0)
         explicit_bzero(password, strlen(password));                  goto out;
         free(password);  
           freezero(password, strlen(password));
         password = NULL;          password = NULL;
         while (password == NULL) {          while (password == NULL) {
                 snprintf(prompt, sizeof(prompt),                  snprintf(prompt, sizeof(prompt),
Line 954 
Line 1003 
                 password = read_passphrase(prompt, RP_ALLOW_EOF);                  password = read_passphrase(prompt, RP_ALLOW_EOF);
                 if (password == NULL) {                  if (password == NULL) {
                         /* bail out */                          /* bail out */
                         return 0;                          r = 0;
                           goto out;
                 }                  }
                 snprintf(prompt, sizeof(prompt),                  snprintf(prompt, sizeof(prompt),
                     "Retype %.30s@%.128s's new password: ",                      "Retype %.30s@%.128s's new password: ",
                     authctxt->server_user, host);                      authctxt->server_user, host);
                 retype = read_passphrase(prompt, 0);                  retype = read_passphrase(prompt, 0);
                 if (strcmp(password, retype) != 0) {                  if (strcmp(password, retype) != 0) {
                         explicit_bzero(password, strlen(password));                          freezero(password, strlen(password));
                         free(password);  
                         logit("Mismatch; try again, EOF to quit.");                          logit("Mismatch; try again, EOF to quit.");
                         password = NULL;                          password = NULL;
                 }                  }
                 explicit_bzero(retype, strlen(retype));                  freezero(retype, strlen(retype));
                 free(retype);  
         }          }
         packet_put_cstring(password);          if ((r = sshpkt_put_cstring(ssh, password)) != 0 ||
         explicit_bzero(password, strlen(password));              (r = sshpkt_add_padding(ssh, 64)) != 0 ||
         free(password);              (r = sshpkt_send(ssh)) != 0)
         packet_add_padding(64);                  goto out;
         packet_send();  
   
         dispatch_set(SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ,          ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ,
             &input_userauth_passwd_changereq);              &input_userauth_passwd_changereq);
         return 0;          r = 0;
    out:
           if (password)
                   freezero(password, strlen(password));
           free(info);
           free(lang);
           return r;
 }  }
   
 /*  /*
Line 1184 
Line 1237 
                                     __func__, ssh_err(r));                                      __func__, ssh_err(r));
                         }                          }
                 }                  }
                 skip = buffer_len(b);                  skip = sshbuf_len(b);
                 if ((r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||                  if ((r = sshbuf_put_u8(b, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
                     (r = sshbuf_put_cstring(b, authctxt->server_user)) != 0 ||                      (r = sshbuf_put_cstring(b, authctxt->server_user)) != 0 ||
                     (r = sshbuf_put_cstring(b, authctxt->service)) != 0 ||                      (r = sshbuf_put_cstring(b, authctxt->service)) != 0 ||
Line 1251 
Line 1304 
 send_pubkey_test(struct ssh *ssh, Authctxt *authctxt, Identity *id)  send_pubkey_test(struct ssh *ssh, Authctxt *authctxt, Identity *id)
 {  {
         u_char *blob = NULL;          u_char *blob = NULL;
         u_int bloblen, have_sig = 0;  
         char *alg = NULL;          char *alg = NULL;
         int sent = 0;          size_t bloblen;
           u_int have_sig = 0;
           int sent = 0, r;
   
         if ((alg = key_sig_algorithm(ssh, id->key)) == NULL) {          if ((alg = key_sig_algorithm(ssh, id->key)) == NULL) {
                 debug("%s: no mutual signature algorithm", __func__);                  debug("%s: no mutual signature algorithm", __func__);
                 goto out;                  goto out;
         }          }
   
         if (key_to_blob(id->key, &blob, &bloblen) == 0) {          if ((r = sshkey_to_blob(id->key, &blob, &bloblen)) != 0) {
                 /* we cannot handle this key */                  /* we cannot handle this key */
                 debug3("%s: cannot handle key", __func__);                  debug3("%s: cannot handle key", __func__);
                 goto out;                  goto out;
         }          }
         /* register callback for USERAUTH_PK_OK message */          /* register callback for USERAUTH_PK_OK message */
         dispatch_set(SSH2_MSG_USERAUTH_PK_OK, &input_userauth_pk_ok);          ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_PK_OK, &input_userauth_pk_ok);
   
         packet_start(SSH2_MSG_USERAUTH_REQUEST);          if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
         packet_put_cstring(authctxt->server_user);              (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 ||
         packet_put_cstring(authctxt->service);              (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 ||
         packet_put_cstring(authctxt->method->name);              (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 ||
         packet_put_char(have_sig);              (r = sshpkt_put_u8(ssh, have_sig)) != 0 ||
         packet_put_cstring(alg);              (r = sshpkt_put_cstring(ssh, alg)) != 0 ||
         packet_put_string(blob, bloblen);              (r = sshpkt_put_string(ssh, blob, bloblen)) != 0 ||
         packet_send();              (r = sshpkt_send(ssh)) != 0)
         /* success */                  fatal("%s: %s", __func__, ssh_err(r));
         sent = 1;          sent = 1;
 out:  
    out:
         free(alg);          free(alg);
         free(blob);          free(blob);
         return sent;          return sent;
Line 1339 
Line 1394 
                     !(id->key && id->isprivate))                      !(id->key && id->isprivate))
                         maybe_add_key_to_agent(id->filename, private, comment,                          maybe_add_key_to_agent(id->filename, private, comment,
                             passphrase);                              passphrase);
                 if (i > 0) {                  if (i > 0)
                         explicit_bzero(passphrase, strlen(passphrase));                          freezero(passphrase, strlen(passphrase));
                         free(passphrase);  
                 }  
                 free(comment);                  free(comment);
                 if (private != NULL || quit)                  if (private != NULL || quit)
                         break;                          break;
Line 1419 
Line 1472 
         /* list of certificates specified by user */          /* list of certificates specified by user */
         for (i = 0; i < options.num_certificate_files; i++) {          for (i = 0; i < options.num_certificate_files; i++) {
                 key = options.certificates[i];                  key = options.certificates[i];
                 if (!key_is_cert(key) || key->cert == NULL ||                  if (!sshkey_is_cert(key) || key->cert == NULL ||
                     key->cert->type != SSH2_CERT_TYPE_USER)                      key->cert->type != SSH2_CERT_TYPE_USER)
                         continue;                          continue;
                 id = xcalloc(1, sizeof(*id));                  id = xcalloc(1, sizeof(*id));
Line 1493 
Line 1546 
                 /* If IdentitiesOnly set and key not found then don't use it */                  /* If IdentitiesOnly set and key not found then don't use it */
                 if (!found && options.identities_only) {                  if (!found && options.identities_only) {
                         TAILQ_REMOVE(&files, id, next);                          TAILQ_REMOVE(&files, id, next);
                         explicit_bzero(id, sizeof(*id));                          freezero(id, sizeof(*id));
                         free(id);  
                 }                  }
         }          }
         /* append remaining keys from the config file */          /* append remaining keys from the config file */
Line 1601 
Line 1653 
                                         sent = sign_and_send_pubkey(ssh,                                          sent = sign_and_send_pubkey(ssh,
                                             authctxt, id);                                              authctxt, id);
                                 }                                  }
                                 key_free(id->key);                                  sshkey_free(id->key);
                                 id->key = NULL;                                  id->key = NULL;
                                 id->isprivate = 0;                                  id->isprivate = 0;
                         }                          }
Line 1618 
Line 1670 
 int  int
 userauth_kbdint(Authctxt *authctxt)  userauth_kbdint(Authctxt *authctxt)
 {  {
           struct ssh *ssh = active_state; /* XXX */
         static int attempt = 0;          static int attempt = 0;
           int r;
   
         if (attempt++ >= options.number_of_password_prompts)          if (attempt++ >= options.number_of_password_prompts)
                 return 0;                  return 0;
         /* disable if no SSH2_MSG_USERAUTH_INFO_REQUEST has been seen */          /* disable if no SSH2_MSG_USERAUTH_INFO_REQUEST has been seen */
         if (attempt > 1 && !authctxt->info_req_seen) {          if (attempt > 1 && !authctxt->info_req_seen) {
                 debug3("userauth_kbdint: disable: no info_req_seen");                  debug3("userauth_kbdint: disable: no info_req_seen");
                 dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, NULL);                  ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_INFO_REQUEST, NULL);
                 return 0;                  return 0;
         }          }
   
         debug2("userauth_kbdint");          debug2("userauth_kbdint");
         packet_start(SSH2_MSG_USERAUTH_REQUEST);          if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_REQUEST)) != 0 ||
         packet_put_cstring(authctxt->server_user);              (r = sshpkt_put_cstring(ssh, authctxt->server_user)) != 0 ||
         packet_put_cstring(authctxt->service);              (r = sshpkt_put_cstring(ssh, authctxt->service)) != 0 ||
         packet_put_cstring(authctxt->method->name);              (r = sshpkt_put_cstring(ssh, authctxt->method->name)) != 0 ||
         packet_put_cstring("");                                 /* lang */              (r = sshpkt_put_cstring(ssh, "")) != 0 ||           /* lang */
         packet_put_cstring(options.kbd_interactive_devices ?              (r = sshpkt_put_cstring(ssh, options.kbd_interactive_devices ?
             options.kbd_interactive_devices : "");              options.kbd_interactive_devices : "")) != 0 ||
         packet_send();              (r = sshpkt_send(ssh)) != 0)
                   fatal("%s: %s", __func__, ssh_err(r));
   
         dispatch_set(SSH2_MSG_USERAUTH_INFO_REQUEST, &input_userauth_info_req);          ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_INFO_REQUEST, &input_userauth_info_req);
         return 1;          return 1;
 }  }
   
Line 1650 
Line 1705 
 input_userauth_info_req(int type, u_int32_t seq, struct ssh *ssh)  input_userauth_info_req(int type, u_int32_t seq, struct ssh *ssh)
 {  {
         Authctxt *authctxt = ssh->authctxt;          Authctxt *authctxt = ssh->authctxt;
         char *name, *inst, *lang, *prompt, *response;          char *name = NULL, *inst = NULL, *lang = NULL, *prompt = NULL;
           char *response = NULL;
           u_char echo = 0;
         u_int num_prompts, i;          u_int num_prompts, i;
         int echo = 0;          int r;
   
         debug2("input_userauth_info_req");          debug2("input_userauth_info_req");
   
Line 1661 
Line 1718 
   
         authctxt->info_req_seen = 1;          authctxt->info_req_seen = 1;
   
         name = packet_get_string(NULL);          if ((r = sshpkt_get_cstring(ssh, &name, NULL)) != 0 ||
         inst = packet_get_string(NULL);              (r = sshpkt_get_cstring(ssh, &inst, NULL)) != 0 ||
         lang = packet_get_string(NULL);              (r = sshpkt_get_cstring(ssh, &lang, NULL)) != 0)
                   goto out;
         if (strlen(name) > 0)          if (strlen(name) > 0)
                 logit("%s", name);                  logit("%s", name);
         if (strlen(inst) > 0)          if (strlen(inst) > 0)
                 logit("%s", inst);                  logit("%s", inst);
         free(name);  
         free(inst);  
         free(lang);  
   
         num_prompts = packet_get_int();          if ((r = sshpkt_get_u32(ssh, &num_prompts)) != 0)
                   goto out;
         /*          /*
          * Begin to build info response packet based on prompts requested.           * Begin to build info response packet based on prompts requested.
          * We commit to providing the correct number of responses, so if           * We commit to providing the correct number of responses, so if
          * further on we run into a problem that prevents this, we have to           * further on we run into a problem that prevents this, we have to
          * be sure and clean this up and send a correct error response.           * be sure and clean this up and send a correct error response.
          */           */
         packet_start(SSH2_MSG_USERAUTH_INFO_RESPONSE);          if ((r = sshpkt_start(ssh, SSH2_MSG_USERAUTH_INFO_RESPONSE)) != 0 ||
         packet_put_int(num_prompts);              (r = sshpkt_put_u32(ssh, num_prompts)) != 0)
                   goto out;
   
         debug2("input_userauth_info_req: num_prompts %d", num_prompts);          debug2("input_userauth_info_req: num_prompts %d", num_prompts);
         for (i = 0; i < num_prompts; i++) {          for (i = 0; i < num_prompts; i++) {
                 prompt = packet_get_string(NULL);                  if ((r = sshpkt_get_cstring(ssh, &prompt, NULL)) != 0 ||
                 echo = packet_get_char();                      (r = sshpkt_get_u8(ssh, &echo)) != 0)
                           goto out;
                 response = read_passphrase(prompt, echo ? RP_ECHO : 0);                  response = read_passphrase(prompt, echo ? RP_ECHO : 0);
                   if ((r = sshpkt_put_cstring(ssh, response)) != 0)
                 packet_put_cstring(response);                          goto out;
                 explicit_bzero(response, strlen(response));                  freezero(response, strlen(response));
                 free(response);  
                 free(prompt);                  free(prompt);
                   response = prompt = NULL;
         }          }
         packet_check_eom(); /* done with parsing incoming message. */          /* done with parsing incoming message. */
           if ((r = sshpkt_get_end(ssh)) != 0 ||
         packet_add_padding(64);              (r = sshpkt_add_padding(ssh, 64)) != 0)
         packet_send();                  goto out;
         return 0;          r = sshpkt_send(ssh);
    out:
           if (response)
                   freezero(response, strlen(response));
           free(prompt);
           free(name);
           free(inst);
           free(lang);
           return r;
 }  }
   
 static int  static int
Line 1944 
Line 2009 
         success = 1;          success = 1;
   
  out:   out:
         if (sig != NULL) {          if (sig != NULL)
                 explicit_bzero(sig, siglen);                  freezero(sig, siglen);
                 free(sig);  
         }  
         free(keyblob);          free(keyblob);
         free(lname);          free(lname);
         free(fp);          free(fp);
Line 2044 
Line 2107 
 authmethods_get(void)  authmethods_get(void)
 {  {
         Authmethod *method = NULL;          Authmethod *method = NULL;
         Buffer b;          struct sshbuf *b;
         char *list;          char *list;
           int r;
   
         buffer_init(&b);          if ((b = sshbuf_new()) == NULL)
                   fatal("%s: sshbuf_new failed", __func__);
         for (method = authmethods; method->name != NULL; method++) {          for (method = authmethods; method->name != NULL; method++) {
                 if (authmethod_is_enabled(method)) {                  if (authmethod_is_enabled(method)) {
                         if (buffer_len(&b) > 0)                          if ((r = sshbuf_putf(b, "%s%s",
                                 buffer_append(&b, ",", 1);                              sshbuf_len(b) ? "," : "", method->name)) != 0)
                         buffer_append(&b, method->name, strlen(method->name));                                  fatal("%s: buffer error: %s",
                                       __func__, ssh_err(r));
                 }                  }
         }          }
         if ((list = sshbuf_dup_string(&b)) == NULL)          if ((list = sshbuf_dup_string(b)) == NULL)
                 fatal("%s: sshbuf_dup_string failed", __func__);                  fatal("%s: sshbuf_dup_string failed", __func__);
         buffer_free(&b);          sshbuf_free(b);
         return list;          return list;
 }  }
   

Legend:
Removed from v.1.277  
changed lines
  Added in v.1.278