diff options
-rw-r--r-- | source4/librpc/rpc/dcerpc.c | 59 | ||||
-rw-r--r-- | source4/librpc/rpc/dcerpc.h | 7 | ||||
-rw-r--r-- | source4/librpc/rpc/dcerpc_auth.c | 21 | ||||
-rw-r--r-- | source4/torture/torture.c | 9 |
4 files changed, 77 insertions, 19 deletions
diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index df9c1face4..3868bfdf45 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -135,11 +135,30 @@ static NTSTATUS dcerpc_pull_request_sign(struct dcerpc_pipe *p, return status; } - /* check the signature */ - status = ntlmssp_check_packet(p->ntlmssp_state, - pkt->u.response.stub_and_verifier.data, - pkt->u.response.stub_and_verifier.length, - &auth.credentials); + + /* check signature or unseal the packet */ + switch (p->auth_info->auth_level) { + case DCERPC_AUTH_LEVEL_PRIVACY: + status = ntlmssp_unseal_packet(p->ntlmssp_state, + pkt->u.response.stub_and_verifier.data, + pkt->u.response.stub_and_verifier.length, + &auth.credentials); + break; + + case DCERPC_AUTH_LEVEL_INTEGRITY: + status = ntlmssp_check_packet(p->ntlmssp_state, + pkt->u.response.stub_and_verifier.data, + pkt->u.response.stub_and_verifier.length, + &auth.credentials); + break; + + case DCERPC_AUTH_LEVEL_NONE: + break; + + default: + status = NT_STATUS_INVALID_LEVEL; + break; + } /* remove the indicated amount of paddiing */ if (pkt->u.response.stub_and_verifier.length < auth.auth_pad_length) { @@ -221,11 +240,31 @@ static NTSTATUS dcerpc_push_request_sign(struct dcerpc_pipe *p, p->auth_info->auth_pad_length = NDR_ALIGN(ndr, 8); ndr_push_zero(ndr, p->auth_info->auth_pad_length); - /* sign the packet */ - status = ntlmssp_sign_packet(p->ntlmssp_state, - ndr->data + DCERPC_REQUEST_LENGTH, - ndr->offset - DCERPC_REQUEST_LENGTH, - &p->auth_info->credentials); + /* sign or seal the packet */ + switch (p->auth_info->auth_level) { + case DCERPC_AUTH_LEVEL_PRIVACY: + status = ntlmssp_seal_packet(p->ntlmssp_state, + ndr->data + DCERPC_REQUEST_LENGTH, + ndr->offset - DCERPC_REQUEST_LENGTH, + &p->auth_info->credentials); + break; + + case DCERPC_AUTH_LEVEL_INTEGRITY: + status = ntlmssp_sign_packet(p->ntlmssp_state, + ndr->data + DCERPC_REQUEST_LENGTH, + ndr->offset - DCERPC_REQUEST_LENGTH, + &p->auth_info->credentials); + break; + + case DCERPC_AUTH_LEVEL_NONE: + p->auth_info->credentials = data_blob(NULL, 0); + break; + + default: + status = NT_STATUS_INVALID_LEVEL; + break; + } + if (!NT_STATUS_IS_OK(status)) { return status; } diff --git a/source4/librpc/rpc/dcerpc.h b/source4/librpc/rpc/dcerpc.h index e41b998d90..906f613593 100644 --- a/source4/librpc/rpc/dcerpc.h +++ b/source4/librpc/rpc/dcerpc.h @@ -51,14 +51,17 @@ struct dcerpc_pipe { }; /* dcerpc pipe flags */ -#define DCERPC_DEBUG_PRINT_IN 1 -#define DCERPC_DEBUG_PRINT_OUT 2 +#define DCERPC_DEBUG_PRINT_IN (1<<0) +#define DCERPC_DEBUG_PRINT_OUT (1<<1) #define DCERPC_DEBUG_PRINT_BOTH (DCERPC_DEBUG_PRINT_IN | DCERPC_DEBUG_PRINT_OUT) #define DCERPC_DEBUG_VALIDATE_IN 4 #define DCERPC_DEBUG_VALIDATE_OUT 8 #define DCERPC_DEBUG_VALIDATE_BOTH (DCERPC_DEBUG_VALIDATE_IN | DCERPC_DEBUG_VALIDATE_OUT) +#define DCERPC_SIGN 16 +#define DCERPC_SEAL 32 + /* this is used to find pointers to calls */ diff --git a/source4/librpc/rpc/dcerpc_auth.c b/source4/librpc/rpc/dcerpc_auth.c index 103a3c70d8..5850ec6979 100644 --- a/source4/librpc/rpc/dcerpc_auth.c +++ b/source4/librpc/rpc/dcerpc_auth.c @@ -68,7 +68,17 @@ NTSTATUS dcerpc_bind_auth_ntlm(struct dcerpc_pipe *p, } p->auth_info->auth_type = DCERPC_AUTH_TYPE_NTLMSSP; - p->auth_info->auth_level = DCERPC_AUTH_LEVEL_INTEGRITY; + + if (p->flags & DCERPC_SEAL) { + p->auth_info->auth_level = DCERPC_AUTH_LEVEL_PRIVACY; + state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL; + } else if (p->flags & DCERPC_SIGN) { + state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + p->auth_info->auth_level = DCERPC_AUTH_LEVEL_INTEGRITY; + } else { + state->neg_flags &= ~(NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL); + p->auth_info->auth_level = DCERPC_AUTH_LEVEL_NONE; + } p->auth_info->auth_pad_length = 0; p->auth_info->auth_reserved = 0; p->auth_info->auth_context_id = random(); @@ -113,8 +123,13 @@ NTSTATUS dcerpc_bind_auth_ntlm(struct dcerpc_pipe *p, p->ntlmssp_state = state; - /* setup for signing */ - status = ntlmssp_sign_init(state); + switch (p->auth_info->auth_level) { + case DCERPC_AUTH_LEVEL_PRIVACY: + case DCERPC_AUTH_LEVEL_INTEGRITY: + /* setup for signing */ + status = ntlmssp_sign_init(state); + break; + } done: talloc_destroy(mem_ctx); diff --git a/source4/torture/torture.c b/source4/torture/torture.c index 0a1881d590..7055acbb85 100644 --- a/source4/torture/torture.c +++ b/source4/torture/torture.c @@ -150,6 +150,7 @@ static NTSTATUS torture_rpc_tcp(struct dcerpc_pipe **p, pipe_name, nt_errstr(status))); return status; } + DEBUG(1,("Mapped to DCERPC/TCP port %u\n", port)); } DEBUG(2,("Connecting to dcerpc server %s:%u\n", host, port)); @@ -164,6 +165,9 @@ static NTSTATUS torture_rpc_tcp(struct dcerpc_pipe **p, /* always do NDR validation in smbtorture */ (*p)->flags |= DCERPC_DEBUG_VALIDATE_BOTH; + /* enable signing on tcp connections */ + (*p)->flags |= DCERPC_SIGN; + /* bind to the pipe, using the uuid as the key */ status = dcerpc_bind_auth_ntlm(*p, pipe_uuid, pipe_version, lp_workgroup(), @@ -214,10 +218,7 @@ NTSTATUS torture_rpc_connection(struct dcerpc_pipe **p, } /* bind to the pipe, using the uuid as the key */ - status = dcerpc_bind_auth_ntlm(*p, pipe_uuid, pipe_version, - lp_workgroup(), - lp_parm_string(-1, "torture", "username"), - lp_parm_string(-1, "torture", "password")); + status = dcerpc_bind_auth_none(*p, pipe_uuid, pipe_version); if (!NT_STATUS_IS_OK(status)) { dcerpc_pipe_close(*p); return status; |