[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.120 and 1.121

version 1.120, 2003/06/24 08:23:46 version 1.121, 2003/08/22 10:56:09
Line 52 
Line 52 
 #include "msg.h"  #include "msg.h"
 #include "pathnames.h"  #include "pathnames.h"
   
   #ifdef GSSAPI
   #include "ssh-gss.h"
   #endif
   
 /* import */  /* import */
 extern char *client_version_string;  extern char *client_version_string;
 extern char *server_version_string;  extern char *server_version_string;
Line 173 
Line 177 
         Sensitive *sensitive;          Sensitive *sensitive;
         /* kbd-interactive */          /* kbd-interactive */
         int info_req_seen;          int info_req_seen;
           /* generic */
           void *methoddata;
 };  };
 struct Authmethod {  struct Authmethod {
         char    *name;          /* string to compare against server's list */          char    *name;          /* string to compare against server's list */
Line 196 
Line 202 
 int     userauth_hostbased(Authctxt *);  int     userauth_hostbased(Authctxt *);
 int     userauth_kerberos(Authctxt *);  int     userauth_kerberos(Authctxt *);
   
   #ifdef GSSAPI
   int     userauth_gssapi(Authctxt *authctxt);
   void    input_gssapi_response(int type, u_int32_t, void *);
   void    input_gssapi_token(int type, u_int32_t, void *);
   void    input_gssapi_hash(int type, u_int32_t, void *);
   void    input_gssapi_error(int, u_int32_t, void *);
   void    input_gssapi_errtok(int, u_int32_t, void *);
   #endif
   
 void    userauth(Authctxt *, char *);  void    userauth(Authctxt *, char *);
   
 static int sign_and_send_pubkey(Authctxt *, Identity *);  static int sign_and_send_pubkey(Authctxt *, Identity *);
Line 208 
Line 223 
 static char *authmethods_get(void);  static char *authmethods_get(void);
   
 Authmethod authmethods[] = {  Authmethod authmethods[] = {
   #ifdef GSSAPI
           {"gssapi",
                   userauth_gssapi,
                   &options.gss_authentication,
                   NULL},
   #endif
         {"hostbased",          {"hostbased",
                 userauth_hostbased,                  userauth_hostbased,
                 &options.hostbased_authentication,                  &options.hostbased_authentication,
Line 278 
Line 299 
         authctxt.success = 0;          authctxt.success = 0;
         authctxt.method = authmethod_lookup("none");          authctxt.method = authmethod_lookup("none");
         authctxt.authlist = NULL;          authctxt.authlist = NULL;
           authctxt.methoddata = NULL;
         authctxt.sensitive = sensitive;          authctxt.sensitive = sensitive;
         authctxt.info_req_seen = 0;          authctxt.info_req_seen = 0;
         if (authctxt.method == NULL)          if (authctxt.method == NULL)
Line 301 
Line 323 
 void  void
 userauth(Authctxt *authctxt, char *authlist)  userauth(Authctxt *authctxt, char *authlist)
 {  {
           if (authctxt->methoddata) {
                   xfree(authctxt->methoddata);
                   authctxt->methoddata = NULL;
           }
         if (authlist == NULL) {          if (authlist == NULL) {
                 authlist = authctxt->authlist;                  authlist = authctxt->authlist;
         } else {          } else {
Line 356 
Line 382 
                 fatal("input_userauth_success: no authentication context");                  fatal("input_userauth_success: no authentication context");
         if (authctxt->authlist)          if (authctxt->authlist)
                 xfree(authctxt->authlist);                  xfree(authctxt->authlist);
           if (authctxt->methoddata)
                   xfree(authctxt->methoddata);
         authctxt->success = 1;                  /* break out */          authctxt->success = 1;                  /* break out */
 }  }
   
Line 443 
Line 471 
         if (sent == 0)          if (sent == 0)
                 userauth(authctxt, NULL);                  userauth(authctxt, NULL);
 }  }
   
   #ifdef GSSAPI
   int
   userauth_gssapi(Authctxt *authctxt)
   {
           Gssctxt *gssctxt = NULL;
           static gss_OID_set supported = NULL;
           static int mech = 0;
           OM_uint32 min;
           int ok = 0;
   
           /* Try one GSSAPI method at a time, rather than sending them all at
            * once. */
   
           if (supported == NULL)
                   gss_indicate_mechs(&min, &supported);
   
           /* Check to see if the mechanism is usable before we offer it */
           while (mech<supported->count && !ok) {
                   if (gssctxt)
                           ssh_gssapi_delete_ctx(&gssctxt);
                   ssh_gssapi_build_ctx(&gssctxt);
                   ssh_gssapi_set_oid(gssctxt, &supported->elements[mech]);
   
                   /* My DER encoding requires length<128 */
                   if (supported->elements[mech].length < 128 &&
                       !GSS_ERROR(ssh_gssapi_import_name(gssctxt,
                       authctxt->host))) {
                           ok = 1; /* Mechanism works */
                   } else {
                           mech++;
                   }
           }
   
           if (!ok) return 0;
   
           authctxt->methoddata=(void *)gssctxt;
   
           packet_start(SSH2_MSG_USERAUTH_REQUEST);
           packet_put_cstring(authctxt->server_user);
           packet_put_cstring(authctxt->service);
           packet_put_cstring(authctxt->method->name);
   
           packet_put_int(1);
   
           /* Some servers encode the OID incorrectly (as we used to) */
           if (datafellows & SSH_BUG_GSSAPI_BER) {
                   packet_put_string(supported->elements[mech].elements,
                       supported->elements[mech].length);
           } else {
                   packet_put_int((supported->elements[mech].length)+2);
                   packet_put_char(SSH_GSS_OIDTYPE);
                   packet_put_char(supported->elements[mech].length);
                   packet_put_raw(supported->elements[mech].elements,
                       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 */
   
           return 1;
   }
   
   void
   input_gssapi_response(int type, u_int32_t plen, void *ctxt)
   {
           Authctxt *authctxt = ctxt;
           Gssctxt *gssctxt;
           OM_uint32 status, ms;
           int oidlen;
           char *oidv;
           gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
   
           if (authctxt == NULL)
                   fatal("input_gssapi_response: no authentication context");
           gssctxt = authctxt->methoddata;
   
           /* Setup our OID */
           oidv = packet_get_string(&oidlen);
   
           if (datafellows & SSH_BUG_GSSAPI_BER) {
                   if (!ssh_gssapi_check_oid(gssctxt, oidv, oidlen))
                           fatal("Server returned different OID than expected");
           } else {
                   if(oidv[0] != SSH_GSS_OIDTYPE || oidv[1] != oidlen-2) {
                           debug("Badly encoded mechanism OID received");
                           userauth(authctxt, NULL);
                           xfree(oidv);
                           return;
                   }
                   if (!ssh_gssapi_check_oid(gssctxt, oidv+2, oidlen-2))
                           fatal("Server returned different OID than expected");
           }
   
           packet_check_eom();
   
           xfree(oidv);
   
           status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
               GSS_C_NO_BUFFER, &send_tok, NULL);
           if (GSS_ERROR(status)) {
                   if (send_tok.length > 0) {
                           packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK);
                           packet_put_string(send_tok.value, send_tok.length);
                           packet_send();
                           gss_release_buffer(&ms, &send_tok);
                   }
                   /* Start again with next method on list */
                   debug("Trying to start again");
                   userauth(authctxt, NULL);
                   return;
           }
   
           /* We must have data to send */
           packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
           packet_put_string(send_tok.value, send_tok.length);
           packet_send();
           gss_release_buffer(&ms, &send_tok);
   }
   
   void
   input_gssapi_token(int type, u_int32_t plen, void *ctxt)
   {
           Authctxt *authctxt = ctxt;
           Gssctxt *gssctxt;
           gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
           gss_buffer_desc recv_tok;
           OM_uint32 status, ms;
           u_int slen;
   
           if (authctxt == NULL)
                   fatal("input_gssapi_response: no authentication context");
           gssctxt = authctxt->methoddata;
   
           recv_tok.value = packet_get_string(&slen);
           recv_tok.length = slen; /* safe typecast */
   
           packet_check_eom();
   
           status=ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
               &recv_tok, &send_tok, NULL);
   
           xfree(recv_tok.value);
   
           if (GSS_ERROR(status)) {
                   if (send_tok.length > 0) {
                           packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK);
                           packet_put_string(send_tok.value, send_tok.length);
                           packet_send();
                           gss_release_buffer(&ms, &send_tok);
                   }
                   /* Start again with the next method in the list */
                   userauth(authctxt, NULL);
                   return;
           }
   
           if (send_tok.length > 0) {
                   packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
                   packet_put_string(send_tok.value, send_tok.length);
                   packet_send();
                   gss_release_buffer(&ms, &send_tok);
           }
   
           if (status == GSS_S_COMPLETE) {
                   /* If that succeeded, send a exchange complete message */
                   packet_start(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE);
                   packet_send();
           }
   }
   
   void
   input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
   {
           Authctxt *authctxt = ctxt;
           Gssctxt *gssctxt;
           gss_buffer_desc send_tok = GSS_C_EMPTY_BUFFER;
           gss_buffer_desc recv_tok;
           OM_uint32 status, ms;
   
           if (authctxt == NULL)
                   fatal("input_gssapi_response: no authentication context");
           gssctxt = authctxt->methoddata;
   
           recv_tok.value = packet_get_string(&recv_tok.length);
   
           packet_check_eom();
   
           /* Stick it into GSSAPI and see what it says */
           status = ssh_gssapi_init_ctx(gssctxt, options.gss_deleg_creds,
                                        &recv_tok, &send_tok, NULL);
   
           xfree(recv_tok.value);
           gss_release_buffer(&ms, &send_tok);
   
           /* Server will be returning a failed packet after this one */
   }
   
   void
   input_gssapi_error(int type, u_int32_t plen, void *ctxt)
   {
           OM_uint32 maj, min;
           char *msg;
           char *lang;
   
           maj=packet_get_int();
           min=packet_get_int();
           msg=packet_get_string(NULL);
           lang=packet_get_string(NULL);
   
           packet_check_eom();
   
           debug("Server GSSAPI Error:\n%s\n", msg);
           xfree(msg);
           xfree(lang);
   }
   #endif /* GSSAPI */
   
 int  int
 userauth_none(Authctxt *authctxt)  userauth_none(Authctxt *authctxt)

Legend:
Removed from v.1.120  
changed lines
  Added in v.1.121