svn commit: samba r9968 - in branches/tmp/RPCREWRITE/source: rpc_client rpcclient

jra at samba.org jra at samba.org
Fri Sep 2 19:53:21 GMT 2005


Author: jra
Date: 2005-09-02 19:53:20 +0000 (Fri, 02 Sep 2005)
New Revision: 9968

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=9968

Log:
NTLMSSP NTLMv2 signing and sealing now working. Check schannel next,
then add NTLMSSP SPNEGO bind.
Jeremy.

Modified:
   branches/tmp/RPCREWRITE/source/rpc_client/cli_pipe.c
   branches/tmp/RPCREWRITE/source/rpcclient/rpcclient.c


Changeset:
Modified: branches/tmp/RPCREWRITE/source/rpc_client/cli_pipe.c
===================================================================
--- branches/tmp/RPCREWRITE/source/rpc_client/cli_pipe.c	2005-09-02 19:45:48 UTC (rev 9967)
+++ branches/tmp/RPCREWRITE/source/rpc_client/cli_pipe.c	2005-09-02 19:53:20 UTC (rev 9968)
@@ -234,20 +234,20 @@
 	NTSTATUS status;
 
 	if (cli->auth.auth_level == PIPE_AUTH_LEVEL_NONE || cli->auth.auth_level == PIPE_AUTH_LEVEL_CONNECT) {
-                return NT_STATUS_OK;
-        }
+		return NT_STATUS_OK;
+	}
 
-        if (!ntlmssp_state) {
-                return NT_STATUS_INVALID_PARAMETER;
-        }
+	if (!ntlmssp_state) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
 
-        /* Ensure there's enough data for an authenticated response. */
-        if ((auth_len > RPC_MAX_SIGN_SIZE) ||
-                        (RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
-                DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
-                        (unsigned int)auth_len ));
-                return NT_STATUS_BUFFER_TOO_SMALL;
-        }
+	/* Ensure there's enough data for an authenticated response. */
+	if ((auth_len > RPC_MAX_SIGN_SIZE) ||
+			(RPC_HEADER_LEN + RPC_HDR_RESP_LEN + RPC_HDR_AUTH_LEN + auth_len > prhdr->frag_len)) {
+		DEBUG(0,("cli_pipe_verify_ntlmssp: auth_len %u is too large.\n",
+			(unsigned int)auth_len ));
+		return NT_STATUS_BUFFER_TOO_SMALL;
+	}
 
 	/*
 	 * We need the full packet data + length (minus auth stuff) as well as the packet data + length
@@ -256,16 +256,16 @@
 	 * functions as NTLMv2 checks the rpc headers also.
 	 */
 
-	data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HDR_RESP_LEN);
+	data = (unsigned char *)(prs_data_p(current_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN);
 	data_len = (size_t)(prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len);
 
 	full_packet_data = prs_data_p(current_pdu);
 	full_packet_data_len = prhdr->frag_len - auth_len;
 
 	/* Pull the auth header and the following data into a blob. */
-	if(!prs_set_offset(current_pdu, RPC_HDR_RESP_LEN + data_len)) {
+	if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
 		DEBUG(0,("cli_pipe_verify_ntlmssp: cannot move offset to %u.\n",
-			(unsigned int)RPC_HDR_RESP_LEN + data_len ));
+			(unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
 		return NT_STATUS_BUFFER_TOO_SMALL;
 	}
 
@@ -378,9 +378,9 @@
 
 	data_len = prhdr->frag_len - RPC_HEADER_LEN - RPC_HDR_RESP_LEN - RPC_HDR_AUTH_LEN - auth_len;
 
-	if(!prs_set_offset(current_pdu, RPC_HDR_RESP_LEN + data_len)) {
+	if(!prs_set_offset(current_pdu, RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len)) {
 		DEBUG(0,("cli_pipe_verify_schannel: cannot move offset to %u.\n",
-			(unsigned int)RPC_HDR_RESP_LEN + data_len ));
+			(unsigned int)RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len ));
 		return NT_STATUS_BUFFER_TOO_SMALL;
 	}
                                                                                                                              
@@ -1097,15 +1097,93 @@
 }
 
 
+/*******************************************************************
+ Create and add the NTLMSSP sign/seal auth header and data.
+ ********************************************************************/
+
 static NTSTATUS add_ntlmssp_auth_footer(struct rpc_pipe_client *cli,
 					RPC_HDR *phdr,
-					prs_struct *p_outgoing_pdu)
+					uint32 ss_padding_len,
+					prs_struct *outgoing_pdu)
 {
-	return NT_STATUS_NO_MEMORY;
+	RPC_HDR_AUTH auth_info;
+	NTSTATUS status;
+	DATA_BLOB auth_blob = data_blob(NULL, 0);
+	uint16 data_and_pad_len = prs_offset(outgoing_pdu) - RPC_HEADER_LEN - RPC_HDR_RESP_LEN;
+
+	if (!cli->auth.a_u.ntlmssp_state) {
+		return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	/* Init and marshall the auth header. */
+	init_rpc_hdr_auth(&auth_info,
+			map_pipe_auth_type_to_rpc_auth_type(cli->auth.auth_type),
+			cli->auth.auth_level,
+			ss_padding_len,
+			1 /* context id. */);
+
+	if(!smb_io_rpc_hdr_auth("hdr_auth", &auth_info, outgoing_pdu, 0)) {
+		DEBUG(0,("add_ntlmssp_auth_footer: failed to marshall RPC_HDR_AUTH.\n"));
+		data_blob_free(&auth_blob);
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	switch (cli->auth.auth_level) {
+		case PIPE_AUTH_LEVEL_PRIVACY:
+			/* Data portion is encrypted. */
+			status = ntlmssp_seal_packet(cli->auth.a_u.ntlmssp_state,
+					prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
+					data_and_pad_len,
+					prs_data_p(outgoing_pdu),
+					(size_t)prs_offset(outgoing_pdu),
+					&auth_blob);
+			if (!NT_STATUS_IS_OK(status)) {
+				data_blob_free(&auth_blob);
+				return status;
+			}
+			break;
+
+		case PIPE_AUTH_LEVEL_INTEGRITY:
+			/* Data is signed. */
+			status = ntlmssp_sign_packet(cli->auth.a_u.ntlmssp_state,
+					prs_data_p(outgoing_pdu) + RPC_HEADER_LEN + RPC_HDR_RESP_LEN,
+					data_and_pad_len,
+					prs_data_p(outgoing_pdu),
+					(size_t)prs_offset(outgoing_pdu),
+					&auth_blob);
+			if (!NT_STATUS_IS_OK(status)) {
+				data_blob_free(&auth_blob);
+				return status;
+			}
+			break;
+
+		default:
+			/* Can't happen. */
+			smb_panic("bad auth level");
+			/* Notreached. */
+			return NT_STATUS_INVALID_PARAMETER;
+	}
+
+	/* Finally marshall the blob. */
+	                                                                                               
+	if (!prs_copy_data_in(outgoing_pdu, auth_blob.data, NTLMSSP_SIG_SIZE)) {
+		DEBUG(0,("add_ntlmssp_auth_footer: failed to add %u bytes auth blob.\n",
+			(unsigned int)NTLMSSP_SIG_SIZE));
+		data_blob_free(&auth_blob);
+		return NT_STATUS_NO_MEMORY;
+	}
+                                                                                                                                
+	data_blob_free(&auth_blob);
+	return NT_STATUS_OK;
 }
 
+/*******************************************************************
+ Create and add the schannel sign/seal auth header and data.
+ ********************************************************************/
+
 static NTSTATUS add_schannel_auth_footer(struct rpc_pipe_client *cli,
 					RPC_HDR *phdr,
+					uint32 ss_padding_len,
 					prs_struct *p_outgoing_pdu)
 {
 #if 0
@@ -1288,14 +1366,14 @@
 					break;
 				case PIPE_AUTH_TYPE_NTLMSSP:
 				case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
-					ret = add_ntlmssp_auth_footer(cli, &hdr, &outgoing_pdu);
+					ret = add_ntlmssp_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
 					if (!NT_STATUS_IS_OK(ret)) {
 						prs_mem_free(&outgoing_pdu);
 						return ret;
 					}
 					break;
 				case PIPE_AUTH_TYPE_SCHANNEL:
-					ret = add_schannel_auth_footer(cli, &hdr, &outgoing_pdu);
+					ret = add_schannel_auth_footer(cli, &hdr, ss_padding, &outgoing_pdu);
 					if (!NT_STATUS_IS_OK(ret)) {
 						prs_mem_free(&outgoing_pdu);
 						return ret;

Modified: branches/tmp/RPCREWRITE/source/rpcclient/rpcclient.c
===================================================================
--- branches/tmp/RPCREWRITE/source/rpcclient/rpcclient.c	2005-09-02 19:45:48 UTC (rev 9967)
+++ branches/tmp/RPCREWRITE/source/rpcclient/rpcclient.c	2005-09-02 19:53:20 UTC (rev 9968)
@@ -315,21 +315,22 @@
 static NTSTATUS cmd_set_ss_level(void)
 {
 	struct cmd_list *tmp;
-        struct cmd_set *tmp_set;
 
 	/* Close any existing connections not at this level. */
 
 	for (tmp = cmd_list; tmp; tmp = tmp->next) {
-		tmp_set = tmp->cmd_set;
+        	struct cmd_set *tmp_set;
 
-		if (tmp_set->rpc_pipe == NULL) {
-			continue;
-		}
+		for (tmp_set = tmp->cmd_set; tmp_set->name; tmp_set++) {
+			if (tmp_set->rpc_pipe == NULL) {
+				continue;
+			}
 
-		if (tmp_set->rpc_pipe->auth.auth_type != pipe_default_auth_type ||
-				tmp_set->rpc_pipe->auth.auth_level != pipe_default_auth_level) {
-			cli_rpc_pipe_close(tmp_set->rpc_pipe);
-			tmp_set->rpc_pipe = NULL;
+			if (tmp_set->rpc_pipe->auth.auth_type != pipe_default_auth_type ||
+					tmp_set->rpc_pipe->auth.auth_level != pipe_default_auth_level) {
+				cli_rpc_pipe_close(tmp_set->rpc_pipe);
+				tmp_set->rpc_pipe = NULL;
+			}
 		}
 	}
 	return NT_STATUS_OK;



More information about the samba-cvs mailing list