]> andersk Git - gssapi-openssh.git/blobdiff - openssh/gss-serv.c
Added support for reporting usage metrics.
[gssapi-openssh.git] / openssh / gss-serv.c
index 365e48d88f1863ac3afb5722efd1d292dd232f15..6fbc09db4d27958200c95f54b5f75dbc4fb0580c 100644 (file)
 #include "servconf.h"
 #include "uidswap.h"
 
+#include "xmalloc.h"
 #include "ssh-gss.h"
 #include "monitor_wrap.h"
 
 extern ServerOptions options;
+extern Authctxt *the_authctxt;
 
 static ssh_gssapi_client gssapi_client =
     { GSS_C_EMPTY_BUFFER, GSS_C_EMPTY_BUFFER,
@@ -63,14 +65,23 @@ ssh_gssapi_mech gssapi_null_mech =
 #ifdef KRB5
 extern ssh_gssapi_mech gssapi_kerberos_mech;
 #endif
+#ifdef GSI
+extern ssh_gssapi_mech gssapi_gsi_mech;
+#endif
 
 ssh_gssapi_mech* supported_mechs[]= {
 #ifdef KRB5
        &gssapi_kerberos_mech,
+#endif
+#ifdef GSI
+       &gssapi_gsi_mech,
 #endif
        &gssapi_null_mech,
 };
 
+#ifdef GSS_C_GLOBUS_LIMITED_PROXY_FLAG
+static int limited = 0;
+#endif
 
 /*
  * Acquire credentials for a server running on the current host.
@@ -159,7 +170,8 @@ ssh_gssapi_supported_oids(gss_OID_set *oidset)
 
        gss_create_empty_oid_set(&min_status, oidset);
 
-       if (GSS_ERROR(gss_indicate_mechs(&min_status, &supported)))
+       /* Ask privileged process what mechanisms it supports. */
+       if (GSS_ERROR(PRIVSEP(gss_indicate_mechs(&min_status, &supported))))
                return;
 
        while (supported_mechs[i]->name != NULL) {
@@ -212,6 +224,10 @@ ssh_gssapi_accept_ctx(Gssctxt *ctx, gss_buffer_desc *recv_tok,
            (*flags & GSS_C_INTEG_FLAG))) && (ctx->major == GSS_S_COMPLETE)) {
                if (ssh_gssapi_getclient(ctx, &gssapi_client))
                        fatal("Couldn't convert client name");
+#ifdef GSS_C_GLOBUS_LIMITED_PROXY_FLAG
+               if (flags && (*flags & GSS_C_GLOBUS_LIMITED_PROXY_FLAG))
+                       limited=1;
+#endif
        }
 
        return (status);
@@ -231,6 +247,17 @@ ssh_gssapi_parse_ename(Gssctxt *ctx, gss_buffer_t ename, gss_buffer_t name)
 
        tok = ename->value;
 
+#ifdef GSI /* GSI gss_export_name() is broken. */
+       if ((ctx->oid->length == gssapi_gsi_mech.oid.length) &&
+           (memcmp(ctx->oid->elements, gssapi_gsi_mech.oid.elements,
+                   gssapi_gsi_mech.oid.length) == 0)) {
+           name->length = ename->length;
+           name->value = xmalloc(ename->length+1);
+           memcpy(name->value, ename->value, ename->length);
+           return GSS_S_COMPLETE;
+       }
+#endif
+
        /*
         * Check that ename is long enough for all of the fixed length
         * header, and that the initial ID bytes are correct
@@ -296,8 +323,11 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client)
                        return GSS_S_COMPLETE;
                }
 
-               if ((ctx->major = gss_inquire_cred_by_mech(&ctx->minor, 
-                   ctx->client_creds, ctx->oid, &new_name, 
+        /* Call gss_inquire_cred rather than gss_inquire_cred_by_mech
+           because GSI doesn't support the latter. -jbasney */
+
+               if ((ctx->major = gss_inquire_cred(&ctx->minor, 
+                   ctx->client_creds, &new_name, 
                    NULL, NULL, NULL))) {
                        ssh_gssapi_error(ctx);
                        return (ctx->major);
@@ -340,9 +370,12 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client)
        if (client->mech == NULL)
                return GSS_S_FAILURE;
 
+    /* Call gss_inquire_cred rather than gss_inquire_cred_by_mech
+       because GSI doesn't support the latter. -jbasney */
+
        if (ctx->client_creds &&
-           (ctx->major = gss_inquire_cred_by_mech(&ctx->minor,
-            ctx->client_creds, ctx->oid, &client->name, NULL, NULL, NULL))) {
+           (ctx->major = gss_inquire_cred(&ctx->minor,
+            ctx->client_creds, &client->name, NULL, NULL, NULL))) {
                ssh_gssapi_error(ctx);
                return (ctx->major);
        }
@@ -369,6 +402,10 @@ ssh_gssapi_getclient(Gssctxt *ctx, ssh_gssapi_client *client)
        /* We can't copy this structure, so we just move the pointer to it */
        client->creds = ctx->client_creds;
        ctx->client_creds = GSS_C_NO_CREDENTIAL;
+
+    /* needed for globus_gss_assist_map_and_authorize() */
+    client->context = ctx->context;
+
        return (ctx->major);
 }
 
@@ -389,6 +426,11 @@ void
 ssh_gssapi_storecreds(void)
 {
        if (gssapi_client.mech && gssapi_client.mech->storecreds) {
+        if (options.gss_creds_path) {
+            gssapi_client.store.filename =
+                expand_authorized_keys(options.gss_creds_path,
+                                       the_authctxt->pw);
+        }
                (*gssapi_client.mech->storecreds)(&gssapi_client);
        } else
                debug("ssh_gssapi_storecreds: Not a GSSAPI mechanism");
@@ -422,6 +464,12 @@ ssh_gssapi_userok(char *user, struct passwd *pw)
                debug("No suitable client data");
                return 0;
        }
+#ifdef GSS_C_GLOBUS_LIMITED_PROXY_FLAG
+       if (limited && options.gsi_allow_limited_proxy != 1) {
+               debug("limited proxy not acceptable for remote login");
+               return 0;
+       }
+#endif
        if (gssapi_client.mech && gssapi_client.mech->userok)
                if ((*gssapi_client.mech->userok)(&gssapi_client, user)) {
                        gssapi_client.used = 1;
@@ -440,6 +488,27 @@ ssh_gssapi_userok(char *user, struct passwd *pw)
        return (0);
 }
 
+/* ssh_gssapi_checkmic() moved to gss-genr.c so it can be called by
+   kexgss_client(). */
+
+/* Priviledged */
+int
+ssh_gssapi_localname(char **user)
+{
+       *user = NULL;
+       if (gssapi_client.displayname.length==0 || 
+           gssapi_client.displayname.value==NULL) {
+               debug("No suitable client data");
+               return(0);;
+       }
+       if (gssapi_client.mech && gssapi_client.mech->localname) {
+               return((*gssapi_client.mech->localname)(&gssapi_client,user));
+       } else {
+               debug("Unknown client authentication type");
+       }
+       return(0);
+}
+
 /* These bits are only used for rekeying. The unpriviledged child is running 
  * as the user, the monitor is root.
  *
@@ -461,11 +530,12 @@ static int ssh_gssapi_simple_conv(int n, const struct pam_message **msg,
 void
 ssh_gssapi_rekey_creds() {
        int ok;
-       int ret;
 #ifdef USE_PAM
+       int ret;
        pam_handle_t *pamh = NULL;
        struct pam_conv pamconv = {ssh_gssapi_simple_conv, NULL};
        char *envstr;
+       char **p;char **pw;
 #endif
 
        if (gssapi_client.store.filename == NULL && 
@@ -495,6 +565,18 @@ ssh_gssapi_rekey_creds() {
        if (ret)
                return;
 
+       /* Put ssh pam stack env variables in this new pam stack env 
+        * Using pam-pkinit, KRB5CCNAME is set during do_pam_session
+        * this addition enables pam-pkinit to access KRB5CCNAME if used 
+        * in sshd-rekey stack too
+        */
+       pw = p = fetch_pam_environment();
+       while ( *pw != NULL ) {
+               pam_putenv(pamh,*pw);
+               pw++;
+       }
+       free_pam_environment(p);
+
        xasprintf(&envstr, "%s=%s", gssapi_client.store.envvar, 
            gssapi_client.store.envval);
 
@@ -526,4 +608,10 @@ ssh_gssapi_update_creds(ssh_gssapi_ccache *store) {
        return ok;
 }
 
+void
+ssh_gssapi_get_client_info(char **userdn, char **mech) {
+       *userdn = gssapi_client.displayname.value;
+       *mech = gssapi_client.mech->name;
+}
+
 #endif
This page took 0.03541 seconds and 4 git commands to generate.