Пример #1
0
int
gfarmGssImportName(gss_name_t *namePtr, void *nameValue, size_t nameLength,
    gss_OID nameType, OM_uint32 *majStatPtr, OM_uint32 *minStatPtr)
{
    OM_uint32 majStat = 0;
    OM_uint32 minStat = 0;
    int ret = -1;
    gss_buffer_desc buf;

#if GFARM_FAKE_GSS_C_NT_USER_NAME_FOR_GLOBUS
    if (nameType == GSS_C_NT_USER_NAME) {
	char *user;
	gfarmAuthEntry *aePtr;

	GFARM_MALLOC_ARRAY(user, nameLength + 1);
	if (user == NULL) {
	    gflog_auth_error(GFARM_MSG_1000611,
		"gfarmGssImportName(): no memory");
	    majStat = GSS_S_FAILURE;
	    minStat = GFSL_DEFAULT_MINOR_ERROR;
	    goto Done;
	}
	memcpy(user, nameValue, nameLength);
	user[nameLength] = '\0';
	aePtr = gfarmAuthGetLocalUserEntry(user);
	if (aePtr == NULL) {
	    gflog_auth_error(GFARM_MSG_1000612, "%s: ERROR: cannot convert "
			     "this user name to X.509 Distinguish name", user);
	    free(user);
	    majStat = GSS_S_FAILURE;
	    minStat = GFSL_DEFAULT_MINOR_ERROR;
	    goto Done;
	}
	free(user);
	assert(aePtr->authType == GFARM_AUTH_USER);
	nameValue = aePtr->distName;
	nameLength = strlen(aePtr->distName);
	nameType = GSS_C_NO_OID; /* mechanism specific */
    }
#endif /* GFARM_FAKE_GSS_C_NT_USER_NAME_FOR_GLOBUS */
    buf.length = nameLength;
    buf.value = nameValue;
    majStat = gss_import_name(&minStat, &buf, nameType, namePtr);
    if (majStat == GSS_S_COMPLETE) {
	ret = 1; /* OK */
    }

#if GFARM_FAKE_GSS_C_NT_USER_NAME_FOR_GLOBUS
    Done:
#endif /* GFARM_FAKE_GSS_C_NT_USER_NAME_FOR_GLOBUS */
    if (majStatPtr != NULL) {
	*majStatPtr = majStat;
    }
    if (minStatPtr != NULL) {
	*minStatPtr = minStat;
    }
    return ret;
}
Пример #2
0
int
gfarmGssImportNameOfHostBasedService(gss_name_t *namePtr, char *service,
    char *hostname, OM_uint32 *majStatPtr, OM_uint32 *minStatPtr)
{
    OM_uint32 majStat;
    OM_uint32 minStat;
    int ret = -1;
    size_t nameLength = strlen(service) + 1 + strlen(hostname);
    char *nameString;

    GFARM_MALLOC_ARRAY(nameString, nameLength + 1);
    if (nameString == NULL) {
	gflog_auth_error(GFARM_MSG_1000613,
	    "gfarmGssImportNameOfHostBasedService(): "
			 "no memory");
	majStat = GSS_S_FAILURE;
	minStat = GFSL_DEFAULT_MINOR_ERROR;
    } else {
	sprintf(nameString, "%s@%s", service, hostname);
	if (gfarmGssImportName(namePtr, nameString, nameLength,
			       GSS_C_NT_HOSTBASED_SERVICE,
			       &majStat, &minStat) > 0) {
	    ret = 1;
	}
	free(nameString);
    }
    if (majStatPtr != NULL) {
	*majStatPtr = majStat;
    }
    if (minStatPtr != NULL) {
	*minStatPtr = minStat;
    }
    return ret;
}
Пример #3
0
static void
gfarmGssInitiateSecurityContextReceiveToken(int events, int fd, 
    void *closure, const struct timeval *t)
{
    struct gfarmGssInitiateSecurityContextState *state = closure;
    int tknStat;

    if ((events & GFARM_EVENT_TIMEOUT) != 0) {
	assert(events == GFARM_EVENT_TIMEOUT);
	state->majStat = GSS_S_UNAVAILABLE; /* failure: timeout */
    } else {
	assert(events == GFARM_EVENT_READ);
	tknStat = gfarmGssReceiveToken(fd, state->itPtr,
				       GFARM_GSS_TIMEOUT_INFINITE);
	if (tknStat <= 0) {
	    gflog_auth_error(GFARM_MSG_1000624,
		"gfarmGssInitiateSecurityContextReceiveToken(): "
			     "failed to receive response");
	    state->majStat= GSS_S_DEFECTIVE_TOKEN|GSS_S_CALL_INACCESSIBLE_READ;
	    state->minStat= GFSL_DEFAULT_MINOR_ERROR;
	} else if (gssInitiateSecurityContextNext(state)) {
	    return;
	}
    }
    assert(GSS_ERROR(state->majStat) || state->completed);
    if (state->continuation != NULL)
	(*state->continuation)(state->closure);
}
Пример #4
0
static void
gfarmGssInitiateSecurityContextSendToken(int events, int fd, void *closure,
    const struct timeval *t)
{
    struct gfarmGssInitiateSecurityContextState *state = closure;
    int tknStat;
    OM_uint32 minStat2;

    tknStat = gfarmGssSendToken(fd, state->otPtr);
    gss_release_buffer(&minStat2, state->otPtr);
    if (tknStat <= 0) {
	gflog_auth_error(GFARM_MSG_1000623,
	    "gfarmGssInitiateSecurityContextSendToken(): "
			 "failed to send response");
	state->majStat = GSS_S_DEFECTIVE_TOKEN|GSS_S_CALL_INACCESSIBLE_WRITE;
	state->minStat = GFSL_DEFAULT_MINOR_ERROR;
    }

    if (gssInitiateSecurityContextSwitch(state)) {
	return;
    }
    if (state->continuation != NULL) {
	(*state->continuation)(state->closure);
    }
}
Пример #5
0
/* this function returns 1, if an event is added */
static int
gssInitiateSecurityContextSwitch(
    struct gfarmGssInitiateSecurityContextState *state)
{
    int rv;
    struct timeval timeout;

    if (GSS_ERROR(state->majStat)) {
	return 0;
    }

    if (state->majStat & GSS_S_CONTINUE_NEEDED) {
	timeout.tv_sec = GFARM_GSS_AUTH_TIMEOUT;
	timeout.tv_usec = 0;
	rv = gfarm_eventqueue_add_event(state->q, state->readable, &timeout);
	if (rv == 0) {
	    /* go to gfarmGssInitiateSecurityContextReceiveToken() */
	    return 1;
	}
	gflog_auth_error(GFARM_MSG_1000621,
	    "gfarm:gssInitiateSecurityContextSwitch(): %s",
			 strerror(rv));
	state->majStat = GSS_S_FAILURE;
	state->minStat = GFSL_DEFAULT_MINOR_ERROR;
    } else {
	state->completed = 1;
    }
    return 0;
}
Пример #6
0
char *
gfarmGssNewDisplayName(const gss_name_t inputName, OM_uint32 *majStatPtr,
    OM_uint32 *minStatPtr, gss_OID *outputNameTypePtr)
{
    OM_uint32 majStat;
    OM_uint32 minStat, minStat2;
    char *ret = NULL;
    gss_buffer_desc buf;
    gss_OID outputNameType;

    if (inputName == GSS_C_NO_NAME) {
	gflog_auth_error(GFARM_MSG_1000614,
	    "gfarmGssNewDisplayName(): GSS_C_NO_NAME is passed");
	majStat = GSS_S_FAILURE;
	minStat = GFSL_DEFAULT_MINOR_ERROR;
    } else if ((majStat = gss_display_name(&minStat, inputName,
					   &buf, &outputNameType))
	       == GSS_S_COMPLETE) {
	GFARM_MALLOC_ARRAY(ret, buf.length + 1);
	if (ret == NULL) {
	    gflog_auth_error(GFARM_MSG_1000615,
		"gfarmGssNewDisplayName(): no memory");
	    majStat = GSS_S_FAILURE;
	    minStat = GFSL_DEFAULT_MINOR_ERROR;
	} else {
	    ret[buf.length] = '\0';
	    memcpy(ret, buf.value, buf.length);
	    gss_release_buffer(&minStat2, &buf);
	    if (outputNameTypePtr != NULL) {
		*outputNameTypePtr = outputNameType;
	    }
	}
    }
    if (majStatPtr != NULL) {
	*majStatPtr = majStat;
    }
    if (minStatPtr != NULL) {
	*minStatPtr = minStat;
    }
    return ret;
}
Пример #7
0
/* this function returns 1, if an event is added */
static int
gssInitiateSecurityContextNext(
    struct gfarmGssInitiateSecurityContextState *state)
{
    OM_uint32 minStat2;
    int rv;
    static const char diag[] = "gssInitiateSecurityContextNext()";

    gfarm_mutex_lock(&gss_mutex, diag, gssDiag);
    state->majStat = gss_init_sec_context(&state->minStat,
					  state->cred,
					  &state->sc,
					  state->acceptorName,
					  GSS_C_NO_OID,
					  state->reqFlag,
					  0,
					  GSS_C_NO_CHANNEL_BINDINGS,
					  state->itPtr,
					  state->actualMechType,
					  state->otPtr,
					  &state->retFlag,
					  &state->timeRet);
    gfarm_mutex_unlock(&gss_mutex, diag, gssDiag);

    if (state->itPtr->length > 0)
	gss_release_buffer(&minStat2, state->itPtr);

    if (state->otPtr->length > 0) {
	rv = gfarm_eventqueue_add_event(state->q, state->writable, NULL);
	if (rv == 0) {
	    /* go to gfarmGssInitiateSecurityContextSendToken() */
	    return 1;
	}
	gflog_auth_error(GFARM_MSG_1000622,
	    "gfarm:gssInitiateSecurityContextNext(): %s",
			 strerror(rv));
	state->majStat = GSS_S_FAILURE;
	state->minStat = GFSL_DEFAULT_MINOR_ERROR;
    }

    return gssInitiateSecurityContextSwitch(state);
}
Пример #8
0
char *
gfarm_gsi_client_cred_name(void)
{
	gss_cred_id_t cred;
	gss_name_t name;
	OM_uint32 e_major, e_minor;
	static int initialized = 0;
	static char *dn;

	if (initialized)
		return (dn);
	
	if (gfarmSecSessionGetInitiatorInitialCredential(&cred) < 0) {
		dn = NULL;
		gflog_auth_error("gfarm_gsi_client_cred_name(): "
		    "not initialized as an initiator");
	} else if (gfarmGssNewCredentialName(&name, cred, &e_major, &e_minor)
	    < 0) {
		dn = NULL;
		if (gflog_auth_get_verbose()) {
			gflog_error("cannot convert initiator credential "
			    "to name");
			gfarmGssPrintMajorStatus(e_major);
			gfarmGssPrintMinorStatus(e_minor);
		}
	} else {
		dn = gfarmGssNewDisplayName(name, &e_major, &e_minor, NULL);
		if (dn == NULL && gflog_auth_get_verbose()) {
			gflog_error("cannot convert initiator credential "
			    "to string");
			gfarmGssPrintMajorStatus(e_major);
			gfarmGssPrintMinorStatus(e_minor);
		}
		gfarmGssDeleteName(&name, NULL, NULL);
	}
	initialized = 1;
	return (dn);
}
Пример #9
0
int
gfarmGssInitiateSecurityContext(int fd, const gss_name_t acceptorName,
    gss_cred_id_t cred, OM_uint32 reqFlag, gss_ctx_id_t *scPtr,
    OM_uint32 *majStatPtr, OM_uint32 *minStatPtr, gss_name_t *remoteNamePtr)
{
    OM_uint32 majStat;
    OM_uint32 minStat, minStat2;
    OM_uint32 retFlag = 0;

    gss_buffer_desc inputToken = GSS_C_EMPTY_BUFFER;
    gss_buffer_t itPtr = &inputToken;
    
    gss_buffer_desc outputToken = GSS_C_EMPTY_BUFFER;
    gss_buffer_t otPtr = &outputToken;

    gss_OID *actualMechType = NULL;
    OM_uint32 timeRet;

    int tknStat;

    static const char diag[] = "gfarmGssInitiateSecurityContext()";

    *scPtr = GSS_C_NO_CONTEXT;

    /*
     * Implementation specification:
     * In gfarm, an initiator must reveal own identity to an acceptor.
     */
    if ((reqFlag & GSS_C_ANON_FLAG) == GSS_C_ANON_FLAG) {
	/* It is a bit safer to deny the request than to silently ignore it */
	gflog_auth_error(GFARM_MSG_1000618,
	    "gfarmGssInitiateSecurityContext(): "
	    "GSS_C_ANON_FLAG is not allowed");
	majStat = GSS_S_UNAVAILABLE;
	minStat = GFSL_DEFAULT_MINOR_ERROR;
	goto Done;
    }

    while (1) {
	gfarm_mutex_lock(&gss_mutex, diag, gssDiag);
	majStat = gss_init_sec_context(&minStat,
				       cred,
				       scPtr,
				       acceptorName,
				       GSS_C_NO_OID,
				       reqFlag,
				       0,
				       GSS_C_NO_CHANNEL_BINDINGS,
				       itPtr,
				       actualMechType,
				       otPtr,
				       &retFlag,
				       &timeRet);
	gfarm_mutex_unlock(&gss_mutex, diag, gssDiag);
	
	if (itPtr->length > 0)
	    gss_release_buffer(&minStat2, itPtr);

	if (otPtr->length > 0) {
	    tknStat = gfarmGssSendToken(fd, otPtr);
	    gss_release_buffer(&minStat2, otPtr);
	    if (tknStat <= 0) {
		gflog_auth_error(GFARM_MSG_1000619,
		    "gfarmGssInitiateSecurityContext(): "
				 "failed to send response");
		majStat = GSS_S_DEFECTIVE_TOKEN|GSS_S_CALL_INACCESSIBLE_WRITE;
		minStat = GFSL_DEFAULT_MINOR_ERROR;
	    }
	}

	if (GSS_ERROR(majStat)) {
	    break;
	}
    
	if (majStat & GSS_S_CONTINUE_NEEDED) {
	    tknStat = gfarmGssReceiveToken(fd, itPtr,
					   GFARM_GSS_TIMEOUT_INFINITE);
	    if (tknStat <= 0) {
		gflog_auth_error(GFARM_MSG_1000620,
		    "gfarmGssInitiateSecurityContext(): "
				 "failed to receive response");
		majStat = GSS_S_DEFECTIVE_TOKEN|GSS_S_CALL_INACCESSIBLE_READ;
		minStat = GFSL_DEFAULT_MINOR_ERROR;
		break;
	    }
	} else {
	    break;
	}
    }

    if (itPtr->length > 0)
	gss_release_buffer(&minStat2, itPtr);

    if (majStat == GSS_S_COMPLETE && remoteNamePtr != NULL) {
	majStat = gss_inquire_context(&minStat,
				      *scPtr,
				      NULL,
				      remoteNamePtr,
				      NULL,
				      NULL,
				      NULL,
				      NULL,
				      NULL);
    }

    Done:
    if (majStatPtr != NULL)
	*majStatPtr = majStat;
    if (minStatPtr != NULL)
	*minStatPtr = minStat;

    if (majStat != GSS_S_COMPLETE && *scPtr != GSS_C_NO_CONTEXT)
	gss_delete_sec_context(&minStat2, scPtr, GSS_C_NO_BUFFER);

    return majStat == GSS_S_COMPLETE ? 1 : -1;
}
Пример #10
0
struct gfarmGssInitiateSecurityContextState *
gfarmGssInitiateSecurityContextRequest(struct gfarm_eventqueue *q, int fd,
    const gss_name_t acceptorName, gss_cred_id_t cred, OM_uint32 reqFlag,
    void (*continuation) (void *), void *closure, OM_uint32 *majStatPtr,
    OM_uint32 *minStatPtr)
{
    OM_uint32 majStat;
    OM_uint32 minStat;
    struct gfarmGssInitiateSecurityContextState *state;

    /*
     * Implementation specification:
     * In gfarm, an initiator must reveal own identity to an acceptor.
     */
    if ((reqFlag & GSS_C_ANON_FLAG) == GSS_C_ANON_FLAG) {
	/* It is a bit safer to deny the request than to silently ignore it */
	gflog_auth_error(GFARM_MSG_1000625,
	    "gfarmGssInitiateSecurityContextRequest(): "
	    "GSS_C_ANON_FLAG is not allowed");
	majStat = GSS_S_UNAVAILABLE;
	minStat = GFSL_DEFAULT_MINOR_ERROR;
	goto ReturnStat;
    }

    GFARM_MALLOC(state);
    if (state == NULL) {
	gflog_auth_error(GFARM_MSG_1000626,
	    "gfarmGssInitiateSecurityContextRequest(): "
			 "no memory");
	majStat = GSS_S_FAILURE;
	minStat = GFSL_DEFAULT_MINOR_ERROR;
	goto ReturnStat;
    }

    state->completed = 0;
    state->majStat = GSS_S_COMPLETE;
    state->minStat = GFSL_DEFAULT_MINOR_ERROR;

    state->writable =
	gfarm_fd_event_alloc(GFARM_EVENT_WRITE, fd,
			     gfarmGssInitiateSecurityContextSendToken,
			     state);
    if (state->writable == NULL) {
	gflog_auth_error(GFARM_MSG_1000627,
	    "gfarmGssInitiateSecurityContextRequest(): "
			 "no memory");
	state->majStat = GSS_S_FAILURE;
	goto FreeState;
    }
    /*
     * We cannot use two independent events (i.e. a fd_event with
     * GFARM_EVENT_READ flag and a timer_event) here, because
     * it's possible that both event handlers are called at once.
     */
    state->readable =
	gfarm_fd_event_alloc(GFARM_EVENT_READ|GFARM_EVENT_TIMEOUT, fd,
			     gfarmGssInitiateSecurityContextReceiveToken,
			     state);
    if (state->readable == NULL) {
	gflog_auth_error(GFARM_MSG_1000628,
	    "gfarmGssInitiateSecurityContextRequest(): "
			 "no memory");
	state->majStat = GSS_S_FAILURE;
	goto FreeWritable;
    }

    state->q = q;
    state->fd = fd;
    state->acceptorName = acceptorName;
    state->cred = cred;
    state->reqFlag = reqFlag;
    state->continuation = continuation;
    state->closure = closure;

    state->retFlag = 0;

    /* GSS_C_EMPTY_BUFFER */
    state->inputToken.length = 0; state->inputToken.value = NULL;
    state->itPtr = &state->inputToken;

    /* GSS_C_EMPTY_BUFFER */
    state->outputToken.length = 0; state->outputToken.value = NULL;
    state->otPtr = &state->outputToken;

    state->actualMechType = NULL;

    state->sc = GSS_C_NO_CONTEXT;

    gssInitiateSecurityContextNext(state);
    assert(!state->completed);
    if (!GSS_ERROR(state->majStat)) {
	if (majStatPtr != NULL) {
	    *majStatPtr = GSS_S_COMPLETE;
	}
	if (minStatPtr != NULL) {
	    *minStatPtr = GFSL_DEFAULT_MINOR_ERROR;
	}
	return (state);
    }

    gfarm_event_free(state->readable);

    FreeWritable:
    gfarm_event_free(state->writable);

    FreeState:
    majStat = state->majStat;
    minStat = state->minStat;
    free(state);

    ReturnStat:
    if (majStatPtr != NULL)
	*majStatPtr = majStat;
    if (minStatPtr != NULL)
	*minStatPtr = minStat;

    if (GSS_ERROR(majStat)) {
	gflog_debug(GFARM_MSG_1000801,
		"failed to request initiate security context (%u)(%u)",
		 majStat, minStat);
    }

    return (NULL);
}