⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spnego.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 3 页
字号:
			continue;		}		spnego_state->state_position = SPNEGO_FALLBACK;		nt_status = gensec_subcontext_start(spnego_state, 						    gensec_security, 						    &spnego_state->sub_sec_security);		if (!NT_STATUS_IS_OK(nt_status)) {			return nt_status;		}		/* select the sub context */		nt_status = gensec_start_mech_by_ops(spnego_state->sub_sec_security,						     all_ops[i]);		if (!NT_STATUS_IS_OK(nt_status)) {			return nt_status;		}		nt_status = gensec_update(spnego_state->sub_sec_security,					  out_mem_ctx, in, out);		return nt_status;	}	DEBUG(1, ("Failed to parse SPNEGO request\n"));	return NT_STATUS_INVALID_PARAMETER;	}/*    Parse the netTokenInit, either from the client, to the server, or   from the server to the client.*/static NTSTATUS gensec_spnego_parse_negTokenInit(struct gensec_security *gensec_security,						 struct spnego_state *spnego_state, 						 TALLOC_CTX *out_mem_ctx, 						 const char **mechType,						 const DATA_BLOB unwrapped_in, DATA_BLOB *unwrapped_out) {	int i;	NTSTATUS nt_status = NT_STATUS_INVALID_PARAMETER;	DATA_BLOB null_data_blob = data_blob(NULL,0);	const struct gensec_security_ops_wrapper *all_sec		= gensec_security_by_oid_list(gensec_security, 					      out_mem_ctx, 					      mechType,					      GENSEC_OID_SPNEGO);	if (spnego_state->state_position == SPNEGO_SERVER_START) {		for (i=0; all_sec && all_sec[i].op; i++) {			/* optomisitic token */			if (strcmp(all_sec[i].oid, mechType[0]) == 0) {				nt_status = gensec_subcontext_start(spnego_state,								    gensec_security,								    &spnego_state->sub_sec_security);				if (!NT_STATUS_IS_OK(nt_status)) {					return nt_status;				}				/* select the sub context */				nt_status = gensec_start_mech_by_ops(spnego_state->sub_sec_security,								     all_sec[i].op);				if (!NT_STATUS_IS_OK(nt_status)) {					talloc_free(spnego_state->sub_sec_security);					spnego_state->sub_sec_security = NULL;					break;				}								nt_status = gensec_update(spnego_state->sub_sec_security,							  out_mem_ctx, 							  unwrapped_in,							  unwrapped_out);				if (NT_STATUS_EQUAL(nt_status, NT_STATUS_INVALID_PARAMETER) || 				    NT_STATUS_EQUAL(nt_status, NT_STATUS_CANT_ACCESS_DOMAIN_INFO)) {					/* Pretend we never started it (lets the first run find some incompatible demand) */										DEBUG(1, ("SPNEGO(%s) NEG_TOKEN_INIT failed to parse contents: %s\n", 						  spnego_state->sub_sec_security->ops->name, nt_errstr(nt_status)));					talloc_free(spnego_state->sub_sec_security);					spnego_state->sub_sec_security = NULL;					break;				}				spnego_state->neg_oid = all_sec[i].oid;				break;			}		}	}		/* Having tried any optomisitc token from the client (if we	 * were the server), if we didn't get anywhere, walk our list	 * in our preference order */		if (!spnego_state->sub_sec_security) {		for (i=0; all_sec && all_sec[i].op; i++) {			nt_status = gensec_subcontext_start(spnego_state,							    gensec_security,							    &spnego_state->sub_sec_security);			if (!NT_STATUS_IS_OK(nt_status)) {				return nt_status;			}			/* select the sub context */			nt_status = gensec_start_mech_by_ops(spnego_state->sub_sec_security,							     all_sec[i].op);			if (!NT_STATUS_IS_OK(nt_status)) {				talloc_free(spnego_state->sub_sec_security);				spnego_state->sub_sec_security = NULL;				continue;			}						spnego_state->neg_oid = all_sec[i].oid;			/* only get the helping start blob for the first OID */			nt_status = gensec_update(spnego_state->sub_sec_security,						  out_mem_ctx, 						  null_data_blob, 						  unwrapped_out);			/* it is likely that a NULL input token will			 * not be liked by most server mechs, but if			 * we are in the client, we want the first			 * update packet to be able to abort the use			 * of this mech */			if (spnego_state->state_position != SPNEGO_SERVER_START) {				if (NT_STATUS_EQUAL(nt_status, NT_STATUS_INVALID_PARAMETER) || 				    NT_STATUS_EQUAL(nt_status, NT_STATUS_CANT_ACCESS_DOMAIN_INFO)) {					/* Pretend we never started it (lets the first run find some incompatible demand) */										DEBUG(1, ("SPNEGO(%s) NEG_TOKEN_INIT failed to parse: %s\n", 						  spnego_state->sub_sec_security->ops->name, nt_errstr(nt_status)));					talloc_free(spnego_state->sub_sec_security);					spnego_state->sub_sec_security = NULL;					continue;				}			}			break;		}	}	if (spnego_state->sub_sec_security) {		/* it is likely that a NULL input token will		 * not be liked by most server mechs, but this		 * does the right thing in the CIFS client.		 * just push us along the merry-go-round		 * again, and hope for better luck next		 * time */				if (NT_STATUS_EQUAL(nt_status, NT_STATUS_INVALID_PARAMETER)) {			*unwrapped_out = data_blob(NULL, 0);			nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED;		}				if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_INVALID_PARAMETER) 		    && !NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) 		    && !NT_STATUS_IS_OK(nt_status)) {			DEBUG(1, ("SPNEGO(%s) NEG_TOKEN_INIT failed: %s\n", 				  spnego_state->sub_sec_security->ops->name, nt_errstr(nt_status)));			talloc_free(spnego_state->sub_sec_security);			spnego_state->sub_sec_security = NULL;						/* We started the mech correctly, and the			 * input from the other side was valid.			 * Return the error (say bad password, invalid			 * ticket) */			return nt_status;		}					return nt_status; /* OK, INVALID_PARAMETER ore MORE PROCESSING */	}	DEBUG(1, ("SPNEGO: Could not find a suitable mechtype in NEG_TOKEN_INIT\n"));	/* we could re-negotiate here, but it would only work	 * if the client or server lied about what it could	 * support the first time.  Lets keep this code to	 * reality */	return nt_status;}/** create a negTokenInit  * * This is the same packet, no matter if the client or server sends it first, but it is always the first packet*/static NTSTATUS gensec_spnego_create_negTokenInit(struct gensec_security *gensec_security, 						  struct spnego_state *spnego_state,						  TALLOC_CTX *out_mem_ctx, 						  const DATA_BLOB in, DATA_BLOB *out) {	int i;	NTSTATUS nt_status = NT_STATUS_INVALID_PARAMETER;	DATA_BLOB null_data_blob = data_blob(NULL,0);	const char **mechTypes = NULL;	DATA_BLOB unwrapped_out = data_blob(NULL, 0);	const struct gensec_security_ops_wrapper *all_sec;	const char *principal = NULL;	mechTypes = gensec_security_oids(gensec_security, 					 out_mem_ctx, GENSEC_OID_SPNEGO);	all_sec	= gensec_security_by_oid_list(gensec_security, 					      out_mem_ctx, 					      mechTypes,					      GENSEC_OID_SPNEGO);	for (i=0; all_sec && all_sec[i].op; i++) {		struct spnego_data spnego_out;		nt_status = gensec_subcontext_start(spnego_state,						    gensec_security,						    &spnego_state->sub_sec_security);		if (!NT_STATUS_IS_OK(nt_status)) {			return nt_status;		}		/* select the sub context */		nt_status = gensec_start_mech_by_ops(spnego_state->sub_sec_security,						     all_sec[i].op);		if (!NT_STATUS_IS_OK(nt_status)) {			talloc_free(spnego_state->sub_sec_security);			spnego_state->sub_sec_security = NULL;			continue;		}		/* In the client, try and produce the first (optimistic) packet */		if (spnego_state->state_position == SPNEGO_CLIENT_START) {			nt_status = gensec_update(spnego_state->sub_sec_security,						  out_mem_ctx, 						  null_data_blob,						  &unwrapped_out);						if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) 			    && !NT_STATUS_IS_OK(nt_status)) {				DEBUG(1, ("SPNEGO(%s) creating NEG_TOKEN_INIT failed: %s\n", 					  spnego_state->sub_sec_security->ops->name, nt_errstr(nt_status)));				talloc_free(spnego_state->sub_sec_security);				spnego_state->sub_sec_security = NULL;				/* Pretend we never started it (lets the first run find some incompatible demand) */								continue;			}		}		spnego_out.type = SPNEGO_NEG_TOKEN_INIT;				/* List the remaining mechs as options */		spnego_out.negTokenInit.mechTypes = gensec_security_oids_from_ops_wrapped(out_mem_ctx, 											  &all_sec[i]);		spnego_out.negTokenInit.reqFlags = 0;				if (spnego_state->state_position == SPNEGO_SERVER_START) {			/* server credentials */			struct cli_credentials *creds = gensec_get_credentials(gensec_security);			if (creds) {				principal = cli_credentials_get_principal(creds, out_mem_ctx);			}		}		if (principal) {			spnego_out.negTokenInit.mechListMIC				= data_blob_string_const(principal);		} else {			spnego_out.negTokenInit.mechListMIC = null_data_blob;		}		spnego_out.negTokenInit.mechToken = unwrapped_out;				if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) {			DEBUG(1, ("Failed to write NEG_TOKEN_INIT\n"));				return NT_STATUS_INVALID_PARAMETER;		}				/* set next state */		spnego_state->neg_oid = all_sec[i].oid;				if (NT_STATUS_IS_OK(nt_status)) {			spnego_state->no_response_expected = true;		}		return NT_STATUS_MORE_PROCESSING_REQUIRED;	} 	talloc_free(spnego_state->sub_sec_security);	spnego_state->sub_sec_security = NULL;	DEBUG(1, ("Failed to setup SPNEGO negTokenInit request: %s\n", nt_errstr(nt_status)));	return NT_STATUS_INVALID_PARAMETER;}/** create a server negTokenTarg  * * This is the case, where the client is the first one who sends data*/static NTSTATUS gensec_spnego_server_negTokenTarg(struct gensec_security *gensec_security, 						  struct spnego_state *spnego_state,						  TALLOC_CTX *out_mem_ctx, 						  NTSTATUS nt_status,						  const DATA_BLOB unwrapped_out, DATA_BLOB *out) {	struct spnego_data spnego_out;	DATA_BLOB null_data_blob = data_blob(NULL, 0);	/* compose reply */	spnego_out.type = SPNEGO_NEG_TOKEN_TARG;	spnego_out.negTokenTarg.responseToken = unwrapped_out;	spnego_out.negTokenTarg.mechListMIC = null_data_blob;	spnego_out.negTokenTarg.supportedMech = NULL;	if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {			spnego_out.negTokenTarg.supportedMech = spnego_state->neg_oid;		spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_INCOMPLETE;		spnego_state->state_position = SPNEGO_SERVER_TARG;	} else if (NT_STATUS_IS_OK(nt_status)) {		if (unwrapped_out.data) {			spnego_out.negTokenTarg.supportedMech = spnego_state->neg_oid;		}		spnego_out.negTokenTarg.negResult = SPNEGO_ACCEPT_COMPLETED;		spnego_state->state_position = SPNEGO_DONE;	} else {		spnego_out.negTokenTarg.negResult = SPNEGO_REJECT;		DEBUG(2, ("SPNEGO login failed: %s\n", nt_errstr(nt_status)));		spnego_state->state_position = SPNEGO_DONE;	}	if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) {		DEBUG(1, ("Failed to write SPNEGO reply to NEG_TOKEN_TARG\n"));		return NT_STATUS_INVALID_PARAMETER;	}	spnego_state->expected_packet = SPNEGO_NEG_TOKEN_TARG;	return nt_status;}static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, 				     const DATA_BLOB in, DATA_BLOB *out) {	struct spnego_state *spnego_state = (struct spnego_state *)gensec_security->private_data;	DATA_BLOB null_data_blob = data_blob(NULL, 0);	DATA_BLOB unwrapped_out = data_blob(NULL, 0);	struct spnego_data spnego_out;	struct spnego_data spnego;	ssize_t len;	*out = data_blob(NULL, 0);	if (!out_mem_ctx) {		out_mem_ctx = spnego_state;	}	/* and switch into the state machine */	switch (spnego_state->state_position) {	case SPNEGO_FALLBACK:		return gensec_update(spnego_state->sub_sec_security,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -