in a credentials cache, which can then be used for re-authentication
to the same acceptor. You must have a valid keytab configured.
+In this testing phase of Moonshot, it's also possible to store a
+default identity and credential in a file. The format consists of
+the string representation of the initiator identity and the password,
+separated by newlines. The default location of this file is
+.gss_eap_id in the user's home directory, however the GSSEAP_IDENTITY
+environment variable can be used to set an alternate location.
+
You can also set a default realm in [appdefaults]; the Kerberos
default realm is never used by mech_eap (or at least, that is the
-intention), so if unspecified you must always qualify names.
+intention), so if unspecified you must always qualify names. It should
+generally not be necessary to specify this.
#include "gssapiP_eap.h"
+#include <pwd.h>
+
OM_uint32
gssEapAllocCred(OM_uint32 *minor, gss_cred_id_t *pCred)
{
return GSS_S_COMPLETE;
}
+static OM_uint32
+readDefaultIdentityAndCreds(OM_uint32 *minor,
+ gss_buffer_t defaultIdentity,
+ gss_buffer_t defaultCreds)
+{
+ OM_uint32 major;
+ FILE *fp = NULL;
+ char pwbuf[BUFSIZ], buf[BUFSIZ];
+ char *ccacheName;
+ struct passwd *pw = NULL, pwd;
+
+ defaultIdentity->length = 0;
+ defaultIdentity->value = NULL;
+
+ defaultCreds->length = 0;
+ defaultCreds->value = NULL;
+
+ ccacheName = getenv("GSSEAP_IDENTITY");
+ if (ccacheName == NULL) {
+ if (getpwuid_r(getuid(), &pwd, pwbuf, sizeof(pwbuf), &pw) != 0 ||
+ pw == NULL || pw->pw_dir == NULL) {
+ major = GSS_S_CRED_UNAVAIL;
+ *minor = errno;
+ goto cleanup;
+ }
+
+ snprintf(buf, sizeof(buf), "%s/.gss_eap_id", pw->pw_dir);
+ ccacheName = buf;
+ }
+
+ fp = fopen(ccacheName, "r");
+ if (fp == NULL) {
+ *minor = GSSEAP_NO_DEFAULT_CRED;
+ major = GSS_S_CRED_UNAVAIL;
+ goto cleanup;
+ }
+
+ while (fgets(buf, sizeof(buf), fp) != NULL) {
+ gss_buffer_desc src, *dst;
+
+ src.length = strlen(buf);
+ src.value = buf;
+
+ if (src.length == 0)
+ break;
+
+ if (buf[src.length - 1] == '\n') {
+ buf[src.length - 1] = '\0';
+ if (--src.length == 0)
+ break;
+ }
+
+ if (defaultIdentity->value == NULL)
+ dst = defaultIdentity;
+ else if (defaultCreds->value == NULL)
+ dst = defaultCreds;
+ else
+ break;
+
+ major = duplicateBuffer(minor, &src, dst);
+ if (GSS_ERROR(major))
+ goto cleanup;
+ }
+
+ if (defaultIdentity->length == 0) {
+ major = GSS_S_CRED_UNAVAIL;
+ *minor = GSSEAP_NO_DEFAULT_CRED;
+ goto cleanup;
+ }
+
+ major = GSS_S_COMPLETE;
+ *minor = 0;
+
+cleanup:
+ if (fp != NULL)
+ fclose(fp);
+
+ return major;
+}
+
OM_uint32
gssEapAcquireCred(OM_uint32 *minor,
const gss_name_t desiredName,
{
OM_uint32 major, tmpMinor;
gss_cred_id_t cred;
-#ifdef GSSEAP_DEBUG
- gss_buffer_desc envPassword;
-#endif
+ gss_buffer_desc defaultCreds = GSS_C_EMPTY_BUFFER;
/* XXX TODO validate with changed set_cred_option API */
*pCred = GSS_C_NO_CREDENTIAL;
} else {
gss_buffer_desc nameBuf = GSS_C_EMPTY_BUFFER;
gss_OID nameType = GSS_C_NO_OID;
+ char serviceName[5 + MAXHOSTNAMELEN];
if (cred->flags & CRED_FLAG_ACCEPT) {
- char serviceName[5 + MAXHOSTNAMELEN] = "host@";
-
/* default host-based service is host@localhost */
+ memcpy(serviceName, "host@", 5);
if (gethostname(&serviceName[5], MAXHOSTNAMELEN) != 0) {
major = GSS_S_FAILURE;
*minor = GSSEAP_NO_HOSTNAME;
nameType = GSS_C_NT_HOSTBASED_SERVICE;
} else if (cred->flags & CRED_FLAG_INITIATE) {
- /* XXX FIXME temporary implementation */
- nameBuf.value = getlogin();
- nameBuf.length = strlen((char *)nameBuf.value);
+ major = readDefaultIdentityAndCreds(minor, &nameBuf, &defaultCreds);
+ if (GSS_ERROR(major))
+ goto cleanup;
nameType = GSS_C_NT_USER_NAME;
}
goto cleanup;
}
+ if (nameBuf.value != serviceName)
+ gss_release_buffer(&tmpMinor, &nameBuf);
+
cred->flags |= CRED_FLAG_DEFAULT_IDENTITY;
}
-#ifdef GSSEAP_DEBUG
- if (password == GSS_C_NO_BUFFER &&
- (cred->flags & CRED_FLAG_DEFAULT_IDENTITY) &&
- (envPassword.value = getenv("GSSEAP_CREDS")) != NULL) {
- envPassword.length = strlen((char *)envPassword.value);
- major = duplicateBuffer(minor, &envPassword, &cred->password);
- if (GSS_ERROR(major))
- goto cleanup;
- } else
-#endif /* GSSEAP_DEBUG */
if (password != GSS_C_NO_BUFFER) {
major = duplicateBuffer(minor, password, &cred->password);
if (GSS_ERROR(major))
goto cleanup;
cred->flags |= CRED_FLAG_PASSWORD;
+ } else if (defaultCreds.value != NULL) {
+ major = duplicateBuffer(minor, &defaultCreds, &cred->password);
+ if (GSS_ERROR(major))
+ goto cleanup;
+
+ cred->flags |= CRED_FLAG_PASSWORD;
} else if (cred->flags & CRED_FLAG_INITIATE) {
/*
* OK, here we need to ask the supplicant if we have creds or it
&& !gssEapCanReauthP(cred, GSS_C_NO_NAME, timeReq)
#endif
major = GSS_S_CRED_UNAVAIL;
- *minor = GSSEAP_MISSING_PASSWORD;
+ *minor = GSSEAP_NO_DEFAULT_CRED;
goto cleanup;
}