summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/librpc/rpc/dcerpc.h2
-rw-r--r--source3/librpc/rpc/dcerpc_helpers.c216
-rw-r--r--source3/rpc_client/cli_pipe.c203
3 files changed, 218 insertions, 203 deletions
diff --git a/source3/librpc/rpc/dcerpc.h b/source3/librpc/rpc/dcerpc.h
index bb7bd34de8..319acce990 100644
--- a/source3/librpc/rpc/dcerpc.h
+++ b/source3/librpc/rpc/dcerpc.h
@@ -139,5 +139,7 @@ NTSTATUS dcerpc_pull_dcerpc_auth(TALLOC_CTX *mem_ctx,
const DATA_BLOB *blob,
struct dcerpc_auth *r,
bool bigendian);
+NTSTATUS dcerpc_add_auth_footer(struct pipe_auth_data *auth,
+ size_t pad_len, DATA_BLOB *rpc_out);
#endif /* __DCERPC_H__ */
diff --git a/source3/librpc/rpc/dcerpc_helpers.c b/source3/librpc/rpc/dcerpc_helpers.c
index 5c92a792e9..0e43e7ad56 100644
--- a/source3/librpc/rpc/dcerpc_helpers.c
+++ b/source3/librpc/rpc/dcerpc_helpers.c
@@ -22,6 +22,10 @@
#include "librpc/rpc/dcerpc.h"
#include "librpc/gen_ndr/ndr_dcerpc.h"
#include "librpc/gen_ndr/ndr_schannel.h"
+#include "../libcli/auth/schannel.h"
+#include "../libcli/auth/spnego.h"
+#include "../libcli/auth/ntlmssp.h"
+#include "ntlmssp_wrap.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_RPC_PARSE
@@ -234,3 +238,215 @@ NTSTATUS dcerpc_pull_dcerpc_auth(TALLOC_CTX *mem_ctx,
return NT_STATUS_OK;
}
+
+/*******************************************************************
+ Create and add the NTLMSSP sign/seal auth data.
+ ********************************************************************/
+
+static NTSTATUS add_ntlmssp_auth_footer(struct auth_ntlmssp_state *auth_state,
+ enum dcerpc_AuthLevel auth_level,
+ DATA_BLOB *rpc_out)
+{
+ uint16_t data_and_pad_len = rpc_out->length
+ - DCERPC_RESPONSE_LENGTH
+ - DCERPC_AUTH_TRAILER_LENGTH;
+ DATA_BLOB auth_blob;
+ NTSTATUS status;
+
+ if (!auth_state) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ switch (auth_level) {
+ case DCERPC_AUTH_LEVEL_PRIVACY:
+ /* Data portion is encrypted. */
+ status = auth_ntlmssp_seal_packet(auth_state,
+ rpc_out->data,
+ rpc_out->data
+ + DCERPC_RESPONSE_LENGTH,
+ data_and_pad_len,
+ rpc_out->data,
+ rpc_out->length,
+ &auth_blob);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ break;
+
+ case DCERPC_AUTH_LEVEL_INTEGRITY:
+ /* Data is signed. */
+ status = auth_ntlmssp_sign_packet(auth_state,
+ rpc_out->data,
+ rpc_out->data
+ + DCERPC_RESPONSE_LENGTH,
+ data_and_pad_len,
+ rpc_out->data,
+ rpc_out->length,
+ &auth_blob);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+ break;
+
+ default:
+ /* Can't happen. */
+ smb_panic("bad auth level");
+ /* Notreached. */
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ /* Finally attach the blob. */
+ if (!data_blob_append(NULL, rpc_out,
+ auth_blob.data, auth_blob.length)) {
+ DEBUG(0, ("Failed to add %u bytes auth blob.\n",
+ (unsigned int)auth_blob.length));
+ return NT_STATUS_NO_MEMORY;
+ }
+ data_blob_free(&auth_blob);
+
+ return NT_STATUS_OK;
+}
+
+/*******************************************************************
+ Create and add the schannel sign/seal auth data.
+ ********************************************************************/
+
+static NTSTATUS add_schannel_auth_footer(struct schannel_state *sas,
+ enum dcerpc_AuthLevel auth_level,
+ DATA_BLOB *rpc_out)
+{
+ uint8_t *data_p = rpc_out->data + DCERPC_RESPONSE_LENGTH;
+ size_t data_and_pad_len = rpc_out->length
+ - DCERPC_RESPONSE_LENGTH
+ - DCERPC_AUTH_TRAILER_LENGTH;
+ DATA_BLOB auth_blob;
+ NTSTATUS status;
+
+ if (!sas) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
+ sas->seq_num));
+
+ switch (auth_level) {
+ case DCERPC_AUTH_LEVEL_PRIVACY:
+ status = netsec_outgoing_packet(sas,
+ rpc_out->data,
+ true,
+ data_p,
+ data_and_pad_len,
+ &auth_blob);
+ break;
+ case DCERPC_AUTH_LEVEL_INTEGRITY:
+ status = netsec_outgoing_packet(sas,
+ rpc_out->data,
+ false,
+ data_p,
+ data_and_pad_len,
+ &auth_blob);
+ break;
+ default:
+ status = NT_STATUS_INTERNAL_ERROR;
+ break;
+ }
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
+ nt_errstr(status)));
+ return status;
+ }
+
+ if (DEBUGLEVEL >= 10) {
+ dump_NL_AUTH_SIGNATURE(talloc_tos(), &auth_blob);
+ }
+
+ /* Finally attach the blob. */
+ if (!data_blob_append(NULL, rpc_out,
+ auth_blob.data, auth_blob.length)) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ data_blob_free(&auth_blob);
+
+ return NT_STATUS_OK;
+}
+
+/**
+* @brief Append an auth footer according to what is the current mechanism
+*
+* @param auth The pipe_auth_data associated with the connection
+* @param pad_len The padding used in the packet
+* @param rpc_out Packet blob up to and including the auth header
+*
+* @return A NTSTATUS error code.
+*/
+NTSTATUS dcerpc_add_auth_footer(struct pipe_auth_data *auth,
+ size_t pad_len, DATA_BLOB *rpc_out)
+{
+ enum dcerpc_AuthType auth_type;
+ char pad[CLIENT_NDR_PADDING_SIZE] = { 0, };
+ DATA_BLOB auth_info;
+ DATA_BLOB auth_blob;
+ NTSTATUS status;
+
+ if (auth->auth_type == PIPE_AUTH_TYPE_NONE) {
+ return NT_STATUS_OK;
+ }
+
+ if (pad_len) {
+ /* Copy the sign/seal padding data. */
+ if (!data_blob_append(NULL, rpc_out, pad, pad_len)) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+
+ auth_type = map_pipe_auth_type_to_rpc_auth_type(auth->auth_type);
+
+ /* marshall the dcerpc_auth with an actually empty auth_blob.
+ * This is needed because the ntmlssp signature includes the
+ * auth header. We will append the actual blob later. */
+ auth_blob = data_blob_null;
+ status = dcerpc_push_dcerpc_auth(rpc_out->data,
+ auth_type,
+ auth->auth_level,
+ pad_len,
+ 1 /* context id. */,
+ &auth_blob,
+ &auth_info);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ /* append the header */
+ if (!data_blob_append(NULL, rpc_out,
+ auth_info.data, auth_info.length)) {
+ DEBUG(0, ("Failed to add %u bytes auth blob.\n",
+ (unsigned int)auth_info.length));
+ return NT_STATUS_NO_MEMORY;
+ }
+ data_blob_free(&auth_info);
+
+ /* Generate any auth sign/seal and add the auth footer. */
+ switch (auth->auth_type) {
+ case PIPE_AUTH_TYPE_NONE:
+ status = NT_STATUS_OK;
+ break;
+ case PIPE_AUTH_TYPE_NTLMSSP:
+ case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
+ status = add_ntlmssp_auth_footer(auth->a_u.auth_ntlmssp_state,
+ auth->auth_level,
+ rpc_out);
+ break;
+ case PIPE_AUTH_TYPE_SCHANNEL:
+ status = add_schannel_auth_footer(auth->a_u.schannel_auth,
+ auth->auth_level,
+ rpc_out);
+ break;
+ default:
+ status = NT_STATUS_INVALID_PARAMETER;
+ break;
+ }
+
+ return status;
+}
+
diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
index d04e56207e..759cfc5c22 100644
--- a/source3/rpc_client/cli_pipe.c
+++ b/source3/rpc_client/cli_pipe.c
@@ -1581,209 +1581,6 @@ static NTSTATUS create_rpc_bind_req(TALLOC_CTX *mem_ctx,
}
/*******************************************************************
- Create and add the NTLMSSP sign/seal auth header and data.
- ********************************************************************/
-
-static NTSTATUS add_ntlmssp_auth_footer(struct auth_ntlmssp_state *auth_state,
- enum dcerpc_AuthLevel auth_level,
- DATA_BLOB *rpc_out)
-{
- uint16_t data_and_pad_len = rpc_out->length
- - DCERPC_RESPONSE_LENGTH
- - DCERPC_AUTH_TRAILER_LENGTH;
- DATA_BLOB auth_blob;
- NTSTATUS status;
-
- if (!auth_state) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- switch (auth_level) {
- case DCERPC_AUTH_LEVEL_PRIVACY:
- /* Data portion is encrypted. */
- status = auth_ntlmssp_seal_packet(auth_state,
- rpc_out->data,
- rpc_out->data
- + DCERPC_RESPONSE_LENGTH,
- data_and_pad_len,
- rpc_out->data,
- rpc_out->length,
- &auth_blob);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
- break;
-
- case DCERPC_AUTH_LEVEL_INTEGRITY:
- /* Data is signed. */
- status = auth_ntlmssp_sign_packet(auth_state,
- rpc_out->data,
- rpc_out->data
- + DCERPC_RESPONSE_LENGTH,
- data_and_pad_len,
- rpc_out->data,
- rpc_out->length,
- &auth_blob);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
- break;
-
- default:
- /* Can't happen. */
- smb_panic("bad auth level");
- /* Notreached. */
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- /* Finally attach the blob. */
- if (!data_blob_append(NULL, rpc_out,
- auth_blob.data, auth_blob.length)) {
- DEBUG(0, ("Failed to add %u bytes auth blob.\n",
- (unsigned int)auth_blob.length));
- 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 schannel_state *sas,
- enum dcerpc_AuthLevel auth_level,
- DATA_BLOB *rpc_out)
-{
- uint8_t *data_p = rpc_out->data + DCERPC_RESPONSE_LENGTH;
- size_t data_and_pad_len = rpc_out->length
- - DCERPC_RESPONSE_LENGTH
- - DCERPC_AUTH_TRAILER_LENGTH;
- DATA_BLOB auth_blob;
- NTSTATUS status;
-
- if (!sas) {
- return NT_STATUS_INVALID_PARAMETER;
- }
-
- DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
- sas->seq_num));
-
- switch (auth_level) {
- case DCERPC_AUTH_LEVEL_PRIVACY:
- status = netsec_outgoing_packet(sas,
- rpc_out->data,
- true,
- data_p,
- data_and_pad_len,
- &auth_blob);
- break;
- case DCERPC_AUTH_LEVEL_INTEGRITY:
- status = netsec_outgoing_packet(sas,
- rpc_out->data,
- false,
- data_p,
- data_and_pad_len,
- &auth_blob);
- break;
- default:
- status = NT_STATUS_INTERNAL_ERROR;
- break;
- }
-
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
- nt_errstr(status)));
- return status;
- }
-
- if (DEBUGLEVEL >= 10) {
- dump_NL_AUTH_SIGNATURE(talloc_tos(), &auth_blob);
- }
-
- /* Finally attach the blob. */
- if (!data_blob_append(NULL, rpc_out,
- auth_blob.data, auth_blob.length)) {
- return NT_STATUS_NO_MEMORY;
- }
- data_blob_free(&auth_blob);
-
- return NT_STATUS_OK;
-}
-
-static NTSTATUS dcerpc_add_auth_footer(struct pipe_auth_data *auth,
- size_t pad_len,
- DATA_BLOB *rpc_out)
-{
- enum dcerpc_AuthType auth_type;
- char pad[CLIENT_NDR_PADDING_SIZE] = { 0, };
- DATA_BLOB auth_info;
- DATA_BLOB auth_blob;
- NTSTATUS status;
-
- if (auth->auth_type == PIPE_AUTH_TYPE_NONE) {
- return NT_STATUS_OK;
- }
-
- if (pad_len) {
- /* Copy the sign/seal padding data. */
- if (!data_blob_append(NULL, rpc_out, pad, pad_len)) {
- return NT_STATUS_NO_MEMORY;
- }
- }
-
- auth_type = map_pipe_auth_type_to_rpc_auth_type(auth->auth_type);
-
- /* marshall the dcerpc_auth with an actually empty auth_blob.
- * This is needed because the ntmlssp signature includes the
- * auth header. We will append the actual blob later. */
- auth_blob = data_blob_null;
- status = dcerpc_push_dcerpc_auth(rpc_out->data,
- auth_type,
- auth->auth_level,
- pad_len,
- 1 /* context id. */,
- &auth_blob,
- &auth_info);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
- /* append the header */
- if (!data_blob_append(NULL, rpc_out,
- auth_info.data, auth_info.length)) {
- DEBUG(0, ("Failed to add %u bytes auth blob.\n",
- (unsigned int)auth_info.length));
- return NT_STATUS_NO_MEMORY;
- }
- data_blob_free(&auth_info);
-
- /* Generate any auth sign/seal and add the auth footer. */
- switch (auth->auth_type) {
- case PIPE_AUTH_TYPE_NONE:
- status = NT_STATUS_OK;
- break;
- case PIPE_AUTH_TYPE_NTLMSSP:
- case PIPE_AUTH_TYPE_SPNEGO_NTLMSSP:
- status = add_ntlmssp_auth_footer(auth->a_u.auth_ntlmssp_state,
- auth->auth_level,
- rpc_out);
- break;
- case PIPE_AUTH_TYPE_SCHANNEL:
- status = add_schannel_auth_footer(auth->a_u.schannel_auth,
- auth->auth_level,
- rpc_out);
- break;
- default:
- status = NT_STATUS_INVALID_PARAMETER;
- break;
- }
-
- return status;
-}
-
-/*******************************************************************
Calculate how much data we're going to send in this packet, also
work out any sign/seal padding length.
********************************************************************/