예제 #1
0
void
input_userauth_success(int type, u_int32_t seq, void *ctxt)
{
	Authctxt *authctxt = ctxt;
	if (authctxt == NULL)
		fatal("input_userauth_success: no authentication context");
	if (authctxt->authlist)
		xfree(authctxt->authlist);
	clear_auth_state(authctxt);
	authctxt->success = 1;			/* break out */
}
예제 #2
0
void
input_userauth_failure(int type, u_int32_t seq, void *ctxt)
{
	Authctxt *authctxt = ctxt;
	char *authlist = NULL;
	int partial;

	if (authctxt == NULL)
		fatal("input_userauth_failure: no authentication context");

	authlist = packet_get_string(NULL);
	partial = packet_get_char();
	packet_check_eom();

	if (partial != 0)
		log("Authenticated with partial success.");
	debug("Authentications that can continue: %s", authlist);

	clear_auth_state(authctxt);
	userauth(authctxt, authlist);
}
예제 #3
0
void
input_gssapi_errtok(int type, u_int32_t plen, void *ctxt)
{
	OM_uint32 min_status;
	Authctxt *authctxt = ctxt;
	Gssctxt *gssctxt;
	gss_buffer_desc send_tok, recv_tok;
	
	if (authctxt == NULL)
		fatal("input_gssapi_response: no authentication context");
	gssctxt = authctxt->methoddata;
	
	recv_tok.value=packet_get_string(&recv_tok.length);

	/* Stick it into GSSAPI and see what it says */
	(void) ssh_gssapi_init_ctx(gssctxt, authctxt->host,
					options.gss_deleg_creds,
					&recv_tok, &send_tok);

	xfree(recv_tok.value);
	(void) gss_release_buffer(&min_status, &send_tok);

	debug("Server sent a GSS-API error token during GSS userauth -- %s",
		ssh_gssapi_last_error(gssctxt, NULL, NULL));

	packet_check_eom();
	
	/* We can't send a packet to the server */

	/* The draft says that we should wait for the server to fail 
	 * before starting the next authentication. So, we clear the
	 * state, but don't do anything else
	 */
	clear_auth_state(authctxt);
	return;
}
예제 #4
0
int
userauth_gssapi_keyex(Authctxt *authctxt)
{
	Gssctxt *gssctxt;
	gss_buffer_desc send_tok;
	OM_uint32 status;
        static int attempt = 0;
	
	if (authctxt == NULL || authctxt->method == NULL)
		fatal("input_gssapi_response: no authentication context");

	if (xxx_gssctxt == NULL || xxx_gssctxt->context == GSS_C_NO_CONTEXT)
		return 0;

	if (strcmp(authctxt->method->name, "gssapi-keyex") == 0)
		authctxt->methoddata = gssctxt = xxx_gssctxt;
	
        if (attempt++ >= 1)
        	return 0;
                                
	if (strcmp(authctxt->method->name, "gssapi-keyex") == 0) {
		gss_buffer_desc g_mic_data;
		Buffer mic_data;

		debug2("Authenticating with GSS-API context from key exchange (w/ MIC)");

		/* Make data buffer to MIC */
		buffer_init(&mic_data);
		buffer_put_string(&mic_data, session_id2, session_id2_len);
		buffer_put_char(&mic_data, SSH2_MSG_USERAUTH_REQUEST);
		buffer_put_cstring(&mic_data, authctxt->server_user);
		buffer_put_cstring(&mic_data, authctxt->service);
		buffer_put_cstring(&mic_data, authctxt->method->name);

		/* Make MIC */
		g_mic_data.value  = buffer_ptr(&mic_data);
		g_mic_data.length = buffer_len(&mic_data);
		status = ssh_gssapi_get_mic(gssctxt, &g_mic_data, &send_tok);
		buffer_clear(&mic_data);

		if (GSS_ERROR(status) || send_tok.length == 0) {
			/*
			 * Oops, now what?  There's no error token...
			 * Next userauth
			 */
			debug("GSS_GetMIC() failed! - "
			      "Abandoning GSSAPI userauth");
			clear_auth_state(authctxt);
			userauth(authctxt,NULL);
			return 0;
		}
		packet_start(SSH2_MSG_USERAUTH_REQUEST);
		packet_put_cstring(authctxt->server_user);
		packet_put_cstring(authctxt->service);
		packet_put_cstring(authctxt->method->name);
		packet_put_string(send_tok.value,send_tok.length); /* MIC */
		packet_send();
		packet_write_wait();
		(void) gss_release_buffer(&status, &send_tok);
	} else if (strcmp(authctxt->method->name, "external-keyx") == 0) {
		debug2("Authentication with deprecated \"external-keyx\""
			" method not supported");
		return 0;
	}
        return 1;
}
예제 #5
0
void
input_gssapi_token(int type, u_int32_t plen, void *ctxt)
{
	Authctxt *authctxt = ctxt;
	Gssctxt *gssctxt;
	gss_buffer_desc send_tok, recv_tok, g_mic_data;
	Buffer mic_data;
	OM_uint32 status;
	u_int slen;
	
	if (authctxt == NULL || authctxt->method == NULL)
		fatal("input_gssapi_response: no authentication context");
	gssctxt = authctxt->methoddata;
	
	recv_tok.value=packet_get_string(&slen);
	recv_tok.length=slen;	/* safe typecast */

	status=ssh_gssapi_init_ctx(gssctxt, authctxt->host,
					options.gss_deleg_creds,
					&recv_tok, &send_tok);

	packet_check_eom();
	
	if (GSS_ERROR(status)) {
		if (send_tok.length>0) {
			packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK);
			packet_put_string(send_tok.value,send_tok.length);
			packet_send();
			packet_write_wait();
		}
		/* Start again with the next method in the list */
		clear_auth_state(authctxt);
		userauth(authctxt,NULL);
		return;
	}
	
	if (send_tok.length>0) {
		packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
		packet_put_string(send_tok.value,send_tok.length);
		packet_send();
		packet_write_wait();
	}

	if (status != GSS_S_COMPLETE)
		return;

	/* Make data buffer to MIC */
	buffer_init(&mic_data);
	buffer_put_string(&mic_data, session_id2, session_id2_len);
	buffer_put_char(&mic_data, SSH2_MSG_USERAUTH_REQUEST);
	buffer_put_cstring(&mic_data, authctxt->server_user);
	buffer_put_cstring(&mic_data, authctxt->service);
	buffer_put_cstring(&mic_data, authctxt->method->name);

	/* Make MIC */
	g_mic_data.value  = buffer_ptr(&mic_data);
	g_mic_data.length = buffer_len(&mic_data);

	status = ssh_gssapi_get_mic(gssctxt, &g_mic_data, &send_tok);
	buffer_clear(&mic_data);

	if (GSS_ERROR(status) || send_tok.length == 0) {
		/*
		 * Oops, now what?  There's no error token...
		 * Next userauth
		 */
		debug("GSS_GetMIC() failed! - "
		      "Abandoning GSSAPI userauth");
		clear_auth_state(authctxt);
		userauth(authctxt,NULL);
		return;
	}
	packet_start(SSH2_MSG_USERAUTH_GSSAPI_MIC);
	packet_put_string(send_tok.value,send_tok.length);
	packet_send();
	packet_write_wait();
}
예제 #6
0
void
input_gssapi_response(int type, u_int32_t plen, void *ctxt) 
{
	Authctxt *authctxt = ctxt;
	Gssctxt *gssctxt;
	OM_uint32 status,ms;
	u_int oidlen;
	char *oidv;
	gss_buffer_desc send_tok;
	
	if (authctxt == NULL)
		fatal("input_gssapi_response: no authentication context");
	gssctxt = authctxt->methoddata;
	
	/* Setup our OID */
	oidv=packet_get_string(&oidlen);
	
	if (datafellows & SSH_BUG_GSSAPI_BER) {
		if (!ssh_gssapi_check_mech_oid(gssctxt,oidv,oidlen)) {
			gss_OID oid;

			oid = ssh_gssapi_make_oid(oidlen, oidv);
			debug("Server returned different OID (%s) than expected (%s)",
				ssh_gssapi_oid_to_str(oid),
				ssh_gssapi_oid_to_str(gssctxt->desired_mech));
			ssh_gssapi_release_oid(&oid);
			clear_auth_state(authctxt);
			userauth(authctxt,NULL);
			return;
		}
	} else {
		if(oidv[0]!=0x06 || oidv[1]!=oidlen-2) {
			debug("Badly encoded mechanism OID received");
			clear_auth_state(authctxt);
			userauth(authctxt,NULL);
			return;
		}
		if (!ssh_gssapi_check_mech_oid(gssctxt,oidv+2,oidlen-2)) {
			gss_OID oid;

			oid = ssh_gssapi_make_oid(oidlen-2, oidv+2);
			debug("Server returned different OID (%s) than expected (%s)",
				ssh_gssapi_oid_to_str(oid),
				ssh_gssapi_oid_to_str(gssctxt->desired_mech));
			clear_auth_state(authctxt);
			userauth(authctxt,NULL);
			return;
		}
	}
		
	packet_check_eom();

        dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN,&input_gssapi_token);
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERROR,&input_gssapi_error);
	dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK,&input_gssapi_errtok);
	
	status = ssh_gssapi_init_ctx(gssctxt, authctxt->host,
					options.gss_deleg_creds,
					GSS_C_NO_BUFFER, &send_tok);
	if (GSS_ERROR(status)) {
		if (send_tok.length>0) {
			packet_start(SSH2_MSG_USERAUTH_GSSAPI_ERRTOK);
			packet_put_string(send_tok.value,send_tok.length);
			packet_send();
			packet_write_wait();
		}
		/* Start again with next method on list */
		debug("Trying to start again");
		clear_auth_state(authctxt);
		userauth(authctxt,NULL);
		return;
	}

	/* We must have data to send */					
	packet_start(SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
	packet_put_string(send_tok.value,send_tok.length);
	packet_send();
	packet_write_wait();
	gss_release_buffer(&ms, &send_tok);
}
예제 #7
0
void
input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt)
{
	Authctxt *authctxt = ctxt;
	Key *key = NULL;
	Buffer b;
	int pktype, sent = 0;
	u_int alen, blen;
	char *pkalg, *fp;
	u_char *pkblob;

	if (authctxt == NULL)
		fatal("input_userauth_pk_ok: no authentication context");
	if (datafellows & SSH_BUG_PKOK) {
		/* this is similar to SSH_BUG_PKAUTH */
		debug2("input_userauth_pk_ok: SSH_BUG_PKOK");
		pkblob = packet_get_string(&blen);
		buffer_init(&b);
		buffer_append(&b, pkblob, blen);
		pkalg = buffer_get_string(&b, &alen);
		buffer_free(&b);
	} else {
		pkalg = packet_get_string(&alen);
		pkblob = packet_get_string(&blen);
	}
	packet_check_eom();

	debug("Server accepts key: pkalg %s blen %u lastkey %p hint %d",
	    pkalg, blen, authctxt->last_key, authctxt->last_key_hint);

	do {
		if (authctxt->last_key == NULL ||
		    authctxt->last_key_sign == NULL) {
			debug("no last key or no sign cb");
			break;
		}
		if ((pktype = key_type_from_name(pkalg)) == KEY_UNSPEC) {
			debug("unknown pkalg %s", pkalg);
			break;
		}
		if ((key = key_from_blob(pkblob, blen)) == NULL) {
			debug("no key from blob. pkalg %s", pkalg);
			break;
		}
		if (key->type != pktype) {
			error("input_userauth_pk_ok: type mismatch "
			    "for decoded key (received %d, expected %d)",
			    key->type, pktype);
			break;
		}
		fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
		debug2("input_userauth_pk_ok: fp %s", fp);
		xfree(fp);
		if (!key_equal(key, authctxt->last_key)) {
			debug("key != last_key");
			break;
		}
		sent = sign_and_send_pubkey(authctxt, key,
		   authctxt->last_key_sign);
	} while (0);

	if (key != NULL)
		key_free(key);
	xfree(pkalg);
	xfree(pkblob);

	/* unregister */
	clear_auth_state(authctxt);
	dispatch_set(SSH2_MSG_USERAUTH_PK_OK, NULL);

	/* try another method if we did not send a packet */
	if (sent == 0)
		userauth(authctxt, NULL);

}