+ if (gssapi_client.mech && gssapi_client.mech->userok)
+ return ((*gssapi_client.mech->userok)(&gssapi_client, user));
+ else
+ debug("ssh_gssapi_userok: Unknown GSSAPI mechanism");
+ return (0);
+}
+
+/* Return a list of the gss-group1-sha1-x mechanisms supported by this
+ * program.
+ *
+ * We only support the mechanisms that we've indicated in the list above,
+ * but we check that they're supported by the GSSAPI mechanism on the
+ * machine. We also check, before including them in the list, that
+ * we have the necesary information in order to carry out the key exchange
+ * (that is, that the user has credentials, the server's creds are accessible,
+ * etc)
+ *
+ * The way that this is done is fairly nasty, as we do a lot of work that
+ * is then thrown away. This should possibly be implemented with a cache
+ * that stores the results (in an expanded Gssctxt structure), which are
+ * then used by the first calls if that key exchange mechanism is chosen.
+ */
+
+/* Unpriviledged */
+char *
+ssh_gssapi_server_mechanisms() {
+ gss_OID_set supported;
+ Gssctxt *ctx = NULL;
+ OM_uint32 maj_status, min_status;
+ Buffer buf;
+ int i = 0;
+ int first = 0;
+ int present;
+ char * mechs;
+
+ ssh_gssapi_supported_oids(&supported);
+
+ buffer_init(&buf);
+
+ while(supported_mechs[i]->name != NULL) {
+ if ((maj_status=gss_test_oid_set_member(&min_status,
+ &supported_mechs[i]->oid,
+ supported,
+ &present))) {
+ present=0;
+ }
+
+ if (present) {
+ if (!GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctx,
+ &supported_mechs[i]->oid)))) {
+ /* Append gss_group1_sha1_x to our list */
+ if (first++!=0)
+ buffer_put_char(&buf,',');
+ buffer_append(&buf, KEX_GSS_SHA1,
+ sizeof(KEX_GSS_SHA1)-1);
+ buffer_append(&buf,
+ supported_mechs[i]->enc_name,
+ strlen(supported_mechs[i]->enc_name));
+ debug("GSSAPI mechanism %s (%s%s) supported",
+ supported_mechs[i]->name, KEX_GSS_SHA1,
+ supported_mechs[i]->enc_name);
+ } else {
+ debug("no credentials for GSSAPI mechanism %s",
+ supported_mechs[i]->name);
+ }
+ } else {
+ debug("GSSAPI mechanism %s not supported",
+ supported_mechs[i]->name);
+ }
+ ssh_gssapi_delete_ctx(&ctx);
+ i++;
+ }
+
+ buffer_put_char(&buf,'\0');
+
+ mechs=xmalloc(buffer_len(&buf));
+ buffer_get(&buf,mechs,buffer_len(&buf));
+ buffer_free(&buf);
+ if (strlen(mechs)==0) {
+ options.gss_authentication = 0; /* no mechs. skip gss auth. */
+ return(NULL);
+ } else {
+ return(mechs);