*/
char *
-ssh_gssapi_mechanisms(int server,char *host) {
+ssh_gssapi_mechanisms(char *host) {
gss_OID_set supported;
OM_uint32 maj_status, min_status;
Buffer buf;
if (datafellows & SSH_OLD_GSSAPI) return NULL;
- PRIVSEP(gss_indicate_mechs(&min_status, &supported));
+ gss_indicate_mechs(&min_status, &supported);
buffer_init(&buf);
present=0;
}
if (present) {
- if ((server &&
- !GSS_ERROR(PRIVSEP(ssh_gssapi_server_ctx(&ctx,
- &supported_mechs[i].oid))))
- || (!server &&
- !GSS_ERROR(ssh_gssapi_client_ctx(&ctx,
- &supported_mechs[i].oid,
- host)))) {
+ if (!GSS_ERROR(ssh_gssapi_client_ctx(&ctx,
+ &supported_mechs[i].oid,
+ host))) {
/* Append gss_group1_sha1_x to our list */
if (++mech_count > 1) {
buffer_append(&buf, ",", 1);
return(mechs);
}
-void ssh_gssapi_supported_oids(gss_OID_set *oidset) {
- enum ssh_gss_id i =0;
- OM_uint32 maj_status,min_status;
- int present;
- gss_OID_set supported;
-
- gss_create_empty_oid_set(&min_status,oidset);
- PRIVSEP(gss_indicate_mechs(&min_status, &supported));
-
- 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) {
- gss_add_oid_set_member(&min_status,
- &supported_mechs[i].oid,
- oidset);
- }
- i++;
- }
-}
-
/* Set the contexts OID from a data stream */
void ssh_gssapi_set_oid_data(Gssctxt *ctx, void *data, size_t len) {
if (ctx->oid != GSS_C_NO_OID) {
/* All this effort to report an error ... */
-static void
-ssh_gssapi_error_ex(gss_OID mech, OM_uint32 major_status,
- OM_uint32 minor_status,
- int send_packet) {
+void
+ssh_gssapi_error(gss_OID mech, OM_uint32 major_status,
+ OM_uint32 minor_status) {
OM_uint32 lmaj, lmin;
gss_buffer_desc msg = {0,NULL};
OM_uint32 ctx;
ctx = 0;
/* The GSSAPI error */
do {
- lmaj = PRIVSEP(gss_display_status(&lmin, major_status,
- GSS_C_GSS_CODE,
- mech,
- &ctx, &msg));
+ lmaj = gss_display_status(&lmin, major_status,
+ GSS_C_GSS_CODE,
+ mech, &ctx, &msg);
if (lmaj == GSS_S_COMPLETE) {
debug((char *)msg.value);
- if (send_packet) packet_send_debug((char *)msg.value);
(void) gss_release_buffer(&lmin, &msg);
}
} while (ctx!=0);
/* The mechanism specific error */
do {
- lmaj = PRIVSEP(gss_display_status(&lmin, minor_status,
- GSS_C_MECH_CODE,
- mech,
- &ctx, &msg));
+ lmaj = gss_display_status(&lmin, minor_status,
+ GSS_C_MECH_CODE,
+ mech, &ctx, &msg);
if (lmaj == GSS_S_COMPLETE) {
debug((char *)msg.value);
- if (send_packet) packet_send_debug((char *)msg.value);
(void) gss_release_buffer(&lmin, &msg);
}
} while (ctx!=0);
}
-void
-ssh_gssapi_error(gss_OID mech,OM_uint32 major_status,OM_uint32 minor_status) {
- ssh_gssapi_error_ex(mech, major_status, minor_status, 0);
-}
-
-void
-ssh_gssapi_send_error(gss_OID mech,
- OM_uint32 major_status,OM_uint32 minor_status) {
- ssh_gssapi_error_ex(mech, major_status, minor_status, 1);
-}
-
-
-
-
/* Initialise our GSSAPI context. We use this opaque structure to contain all
* of the data which both the client and server need to persist across
* {accept,init}_sec_context calls, so that when we do it from the userauth
return(maj_status);
}
-/* Wrapper arround accept_sec_context
- * Requires that the context contains:
- * oid
- * credentials (from ssh_gssapi_acquire_cred)
- */
-OM_uint32 ssh_gssapi_accept_ctx(Gssctxt *ctx,gss_buffer_desc *recv_tok,
- gss_buffer_desc *send_tok, OM_uint32 *flags)
-{
- OM_uint32 maj_status, min_status;
- gss_OID mech;
-
- maj_status=gss_accept_sec_context(&min_status,
- &ctx->context,
- ctx->creds,
- recv_tok,
- GSS_C_NO_CHANNEL_BINDINGS,
- &ctx->client,
- &mech, /* read-only pointer */
- send_tok,
- flags,
- NULL,
- &ctx->client_creds);
- if (GSS_ERROR(maj_status)) {
- ssh_gssapi_send_error(ctx->oid,maj_status,min_status);
- }
-
- if (ctx->client_creds) {
- debug("Received some client credentials");
- } else {
- debug("Got no client credentials");
- }
-
- /* FIXME: We should check that the me
- * the one that we asked for (in ctx->oid) */
-
- ctx->status=maj_status;
-
- /* Now, if we're complete and we have the right flags, then
- * we flag the user as also having been authenticated
- */
-
- if (((flags==NULL) || ((*flags & GSS_C_MUTUAL_FLAG) &&
- (*flags & GSS_C_INTEG_FLAG))) &&
- (maj_status == GSS_S_COMPLETE)) {
- if (ssh_gssapi_getclient(ctx,&gssapi_client_type,
- &gssapi_client_name,
- &gssapi_client_creds))
- fatal("Couldn't convert client name");
- }
-
- return(maj_status);
-}
-
/* Create a service name for the given host */
OM_uint32
ssh_gssapi_import_name(Gssctxt *ctx, const char *host) {
return(maj_status);
}
-OM_uint32
-ssh_gssapi_server_ctx(Gssctxt **ctx,gss_OID oid) {
- if (*ctx) ssh_gssapi_delete_ctx(ctx);
- ssh_gssapi_build_ctx(ctx);
- ssh_gssapi_set_oid(*ctx,oid);
- return(ssh_gssapi_acquire_cred(*ctx));
-}
-
OM_uint32
ssh_gssapi_client_ctx(Gssctxt **ctx,gss_OID oid, char *host) {
gss_buffer_desc token = {0,NULL};
gss_release_buffer(&minor,&token);
return(major);
}
-
+
#endif /* GSSAPI */
#endif /* HAVE_UNSETENV */
}
+char *
+ssh_server_gssapi_mechanisms() {
+ gss_OID_set supported;
+ OM_uint32 maj_status, min_status;
+ Buffer buf;
+ int i = 0;
+ int present;
+ int mech_count=0;
+ char * mechs;
+ Gssctxt * ctx = NULL;
+
+ if (datafellows & SSH_OLD_GSSAPI) return NULL;
+
+ PRIVSEP(gss_indicate_mechs(&min_status, &supported));
+
+ buffer_init(&buf);
+
+ do {
+ 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 (++mech_count > 1) {
+ buffer_append(&buf, ",", 1);
+ }
+ buffer_append(&buf, gssprefix,
+ strlen(gssprefix));
+ 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, gssprefix,
+ 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);
+ }
+ } while (supported_mechs[++i].name != NULL);
+
+ buffer_put_char(&buf,'\0');
+
+ mechs=xmalloc(buffer_len(&buf));
+ buffer_get(&buf,mechs,buffer_len(&buf));
+ buffer_free(&buf);
+ if (strlen(mechs)==0)
+ return(NULL);
+ else
+ return(mechs);
+}
+
+OM_uint32
+ssh_gssapi_server_ctx(Gssctxt **ctx,gss_OID oid) {
+ if (*ctx) ssh_gssapi_delete_ctx(ctx);
+ ssh_gssapi_build_ctx(ctx);
+ ssh_gssapi_set_oid(*ctx,oid);
+ return(ssh_gssapi_acquire_cred(*ctx));
+}
+
+void ssh_gssapi_supported_oids(gss_OID_set *oidset) {
+ enum ssh_gss_id i =0;
+ OM_uint32 maj_status,min_status;
+ int present;
+ gss_OID_set supported;
+
+ gss_create_empty_oid_set(&min_status,oidset);
+ PRIVSEP(gss_indicate_mechs(&min_status, &supported));
+
+ 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) {
+ gss_add_oid_set_member(&min_status,
+ &supported_mechs[i].oid,
+ oidset);
+ }
+ i++;
+ }
+}
+
+/* Wrapper arround accept_sec_context
+ * Requires that the context contains:
+ * oid
+ * credentials (from ssh_gssapi_acquire_cred)
+ */
+OM_uint32 ssh_gssapi_accept_ctx(Gssctxt *ctx,gss_buffer_desc *recv_tok,
+ gss_buffer_desc *send_tok, OM_uint32 *flags)
+{
+ OM_uint32 maj_status, min_status;
+ gss_OID mech;
+
+ maj_status=gss_accept_sec_context(&min_status,
+ &ctx->context,
+ ctx->creds,
+ recv_tok,
+ GSS_C_NO_CHANNEL_BINDINGS,
+ &ctx->client,
+ &mech, /* read-only pointer */
+ send_tok,
+ flags,
+ NULL,
+ &ctx->client_creds);
+ if (GSS_ERROR(maj_status)) {
+ ssh_gssapi_send_error(ctx->oid,maj_status,min_status);
+ }
+
+ if (ctx->client_creds) {
+ debug("Received some client credentials");
+ } else {
+ debug("Got no client credentials");
+ }
+
+ /* FIXME: We should check that the me
+ * the one that we asked for (in ctx->oid) */
+
+ ctx->status=maj_status;
+
+ /* Now, if we're complete and we have the right flags, then
+ * we flag the user as also having been authenticated
+ */
+
+ if (((flags==NULL) || ((*flags & GSS_C_MUTUAL_FLAG) &&
+ (*flags & GSS_C_INTEG_FLAG))) &&
+ (maj_status == GSS_S_COMPLETE)) {
+ if (ssh_gssapi_getclient(ctx,&gssapi_client_type,
+ &gssapi_client_name,
+ &gssapi_client_creds))
+ fatal("Couldn't convert client name");
+ }
+
+ return(maj_status);
+}
+
+void
+ssh_gssapi_send_error(gss_OID mech, OM_uint32 major_status,
+ OM_uint32 minor_status) {
+ OM_uint32 lmaj, lmin;
+ gss_buffer_desc msg = {0,NULL};
+ OM_uint32 ctx;
+
+ ctx = 0;
+ /* The GSSAPI error */
+ do {
+ lmaj = PRIVSEP(gss_display_status(&lmin, major_status,
+ GSS_C_GSS_CODE,
+ mech,
+ &ctx, &msg));
+ if (lmaj == GSS_S_COMPLETE) {
+ debug((char *)msg.value);
+ packet_send_debug((char *)msg.value);
+ (void) gss_release_buffer(&lmin, &msg);
+ }
+ } while (ctx!=0);
+
+ /* The mechanism specific error */
+ do {
+ lmaj = PRIVSEP(gss_display_status(&lmin, minor_status,
+ GSS_C_MECH_CODE,
+ mech,
+ &ctx, &msg));
+ if (lmaj == GSS_S_COMPLETE) {
+ debug((char *)msg.value);
+ packet_send_debug((char *)msg.value);
+ (void) gss_release_buffer(&lmin, &msg);
+ }
+ } while (ctx!=0);
+}
+
#endif /* GSSAPI */