+
+ ssh_gssapi_supported_oids(&supported);
+ do {
+ if (oid.elements)
+ xfree(oid.elements);
+ oid.elements = packet_get_string(&len);
+ oid.length = len;
+ gss_test_oid_set_member(&ms, &oid, supported, &present);
+ mechs--;
+ } while (mechs>0 && !present);
+
+ if (!present) {
+ xfree(oid.elements);
+ return(0);
+ }
+
+ ctxt=xmalloc(sizeof(Gssctxt));
+ authctxt->methoddata=(void *)ctxt;
+
+ ssh_gssapi_build_ctx(ctxt);
+ ssh_gssapi_set_oid(ctxt,&oid);
+
+ if (ssh_gssapi_acquire_cred(ctxt))
+ return 0;
+
+ /* Send SSH_MSG_USERAUTH_GSSAPI_RESPONSE */
+
+ if (!compat20)
+ packet_start(SSH_SMSG_AUTH_GSSAPI_RESPONSE);
+ else
+ packet_start(SSH2_MSG_USERAUTH_GSSAPI_RESPONSE);
+ packet_put_string(oid.elements,oid.length);
+ packet_send();
+ packet_write_wait();
+ xfree(oid.elements);
+
+ if (!compat20)
+ dispatch_set(SSH_MSG_AUTH_GSSAPI_TOKEN,
+ &input_gssapi_token);
+ else
+ dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN,
+ &input_gssapi_token);
+ authctxt->postponed = 1;
+
+ return 0;
+}
+
+void
+input_gssapi_token(int type, u_int32_t plen, void *ctxt)
+{
+ Authctxt *authctxt = ctxt;
+ Gssctxt *gssctxt;
+ gss_buffer_desc send_tok,recv_tok;
+ OM_uint32 maj_status, min_status;
+
+ if (authctxt == NULL || authctxt->methoddata == NULL)
+ fatal("No authentication or GSSAPI context");
+
+ gssctxt=authctxt->methoddata;
+
+ recv_tok.value=packet_get_string(&recv_tok.length);
+
+ maj_status=ssh_gssapi_accept_ctx(gssctxt, &recv_tok, &send_tok, NULL);
+ packet_check_eom();
+
+ if (GSS_ERROR(maj_status)) {
+ /* Failure <sniff> */
+ ssh_gssapi_send_error(maj_status,min_status);
+ authctxt->postponed = 0;
+ dispatch_set(SSH_MSG_AUTH_GSSAPI_TOKEN, NULL);
+ dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
+ userauth_finish(authctxt, 0, "gssapi");
+ }
+
+ if (send_tok.length != 0) {
+ /* Send a packet back to the client */
+ if (!compat20)
+ packet_start(SSH_MSG_AUTH_GSSAPI_TOKEN);
+ else
+ packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
+ packet_put_string(send_tok.value,send_tok.length);
+ packet_send();
+ packet_write_wait();
+ gss_release_buffer(&min_status, &send_tok);
+ }
+
+ if (maj_status == GSS_S_COMPLETE) {
+ dispatch_set(SSH_MSG_AUTH_GSSAPI_TOKEN, NULL);
+ dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN,NULL);
+ /* ssh1 does not have an extra message here */
+ if (!compat20)
+ input_gssapi_exchange_complete(0, 0, ctxt);
+ else
+ dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE,
+ &input_gssapi_exchange_complete);
+ }
+}
+
+/* This is called when the client thinks we've completed authentication.
+ * It should only be enabled in the dispatch handler by the function above,
+ * which only enables it once the GSSAPI exchange is complete.
+ */
+
+void
+input_gssapi_exchange_complete(int type, u_int32_t plen, void *ctxt)
+{
+ Authctxt *authctxt = ctxt;
+ Gssctxt *gssctxt;
+ int authenticated;
+
+ if(strcmp(authctxt->user,"") == 0) {
+ char *user;
+ char *gridmapped_name = NULL;
+ struct passwd *pw = NULL;
+ if(globus_gss_assist_gridmap(gssapi_client_name.value,
+ &gridmapped_name) == 0) {
+ user = gridmapped_name;
+ debug("I gridmapped and got %s", user);
+ pw = getpwnam(user);
+ if (pw && allowed_user(pw)) {
+ authctxt->user = user;
+ authctxt->pw = pwcopy(pw);
+ authctxt->valid = 1;
+ }
+ }
+ }
+
+
+ if (authctxt == NULL || authctxt->methoddata == NULL)
+ fatal("No authentication or GSSAPI context");
+
+ gssctxt=authctxt->methoddata;
+
+ /* This should never happen, but better safe than sorry. */
+ if (gssctxt->status != GSS_S_COMPLETE) {
+ packet_disconnect("Context negotiation is not complete");
+ }
+
+ if (ssh_gssapi_getclient(gssctxt,&gssapi_client_type,
+ &gssapi_client_name,
+ &gssapi_client_creds)) {
+ fatal("Couldn't convert client name");
+ }
+
+ authenticated = ssh_gssapi_userok(authctxt->user);
+
+ /* ssh1 needs to exchange the hash of the keys */
+ if (!compat20) {
+ if (authenticated) {
+
+ OM_uint32 maj_status, min_status;
+ gss_buffer_desc gssbuf,msg_tok;
+
+ /* ssh1 uses wrap */
+ gssbuf.value=ssh1_key_digest;
+ gssbuf.length=sizeof(ssh1_key_digest);
+ if ((maj_status=gss_wrap(&min_status,
+ gssctxt->context,
+ 0,
+ GSS_C_QOP_DEFAULT,
+ &gssbuf,
+ NULL,
+ &msg_tok))) {
+ ssh_gssapi_error(maj_status,min_status);
+ fatal("Couldn't wrap keys");
+ }
+ packet_start(SSH_SMSG_AUTH_GSSAPI_HASH);
+ packet_put_string((char *)msg_tok.value,msg_tok.length);
+ packet_send();
+ packet_write_wait();
+ gss_release_buffer(&min_status,&msg_tok);
+ } else {
+ packet_start(SSH_MSG_AUTH_GSSAPI_ABORT);
+ packet_send();
+ packet_write_wait();
+ }
+ }
+
+ authctxt->postponed = 0;
+ dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
+ dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
+ userauth_finish(authctxt, authenticated, "gssapi");