#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,
#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.
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) {
(*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);
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
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);
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);
}
/* 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);
}
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");
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;
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.
*
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 &&
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);