+static OM_uint32
+readDefaultIdentityAndCreds(OM_uint32 *minor,
+ gss_buffer_t defaultIdentity,
+ gss_buffer_t defaultCreds)
+{
+ OM_uint32 major, tmpMinor;
+ 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) {
+ major = GSS_S_CRED_UNAVAIL;
+ *minor = GSSEAP_NO_DEFAULT_CRED;
+ 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);
+
+ if (GSS_ERROR(major)) {
+ gss_release_buffer(&tmpMinor, defaultIdentity);
+ gss_release_buffer(&tmpMinor, defaultCreds);
+ }
+
+ return major;
+}
+