diff options
-rw-r--r-- | source3/include/rpc_dce.h | 4 | ||||
-rw-r--r-- | source3/rpc_client/cli_pipe.c | 24 | ||||
-rw-r--r-- | source3/rpc_parse/parse_rpc.c | 20 | ||||
-rw-r--r-- | source3/rpc_server/srv_pipe.c | 15 |
4 files changed, 45 insertions, 18 deletions
diff --git a/source3/include/rpc_dce.h b/source3/include/rpc_dce.h index 8266fc861f..0df903109d 100644 --- a/source3/include/rpc_dce.h +++ b/source3/include/rpc_dce.h @@ -63,7 +63,9 @@ enum RPC_PKT_TYPE #define NETSEC_AUTH_TYPE 0x44 #define NETSEC_SIGN_SIGNATURE { 0x77, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 } #define NETSEC_SEAL_SIGNATURE { 0x77, 0x00, 0x7a, 0x00, 0xff, 0xff, 0x00, 0x00 } -#define RPC_AUTH_NETSEC_CHK_LEN 0x20 + +#define RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN 0x20 +#define RPC_AUTH_NETSEC_SIGN_ONLY_CHK_LEN 0x18 /* The 7 here seems to be required to get Win2k not to downgrade us to NT4. Actually, anything other than 1ff would seem to do... */ diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index df0d37a463..b24dbb7d25 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -332,13 +332,24 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { RPC_AUTH_NETSEC_CHK chk; - if (auth_len != RPC_AUTH_NETSEC_CHK_LEN) { + if ( (auth_len != RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN) + && (auth_len != RPC_AUTH_NETSEC_SIGN_ONLY_CHK_LEN) ) + { DEBUG(0,("rpc_auth_pipe: wrong schannel auth len %d\n", auth_len)); return False; } - if (!smb_io_rpc_auth_netsec_chk("schannel_auth_sign", - &chk, &auth_verf, 0)) { + /* can't seal with no nonce */ + if ( (cli->pipe_auth_flags & AUTH_PIPE_SEAL) + && (auth_len != RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN) ) + { + DEBUG(0,("rpc_auth_pipe: sealing not supported with schannel auth len %d\n", auth_len)); + return False; + } + + + if (!smb_io_rpc_auth_netsec_chk("schannel_auth_sign", auth_len, &chk, &auth_verf, 0)) + { DEBUG(0, ("rpc_auth_pipe: schannel unmarshalling " "RPC_AUTH_NETSECK_CHK failed\n")); return False; @@ -918,7 +929,7 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, auth_len = RPC_AUTH_NTLMSSP_CHK_LEN; } if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { - auth_len = RPC_AUTH_NETSEC_CHK_LEN; + auth_len = RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN; } auth_hdr_len = RPC_HDR_AUTH_LEN; } @@ -1034,8 +1045,9 @@ BOOL rpc_api_pipe_req(struct cli_state *cli, uint8 op_num, /* write auth footer onto the packet */ parse_offset_marker = prs_offset(&sec_blob); - if (!smb_io_rpc_auth_netsec_chk("", &verf, - &sec_blob, 0)) { + if (!smb_io_rpc_auth_netsec_chk("", RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN, + &verf, &sec_blob, 0)) + { prs_mem_free(&sec_blob); return False; } diff --git a/source3/rpc_parse/parse_rpc.c b/source3/rpc_parse/parse_rpc.c index 69262b6d0c..f4ffcba1bd 100644 --- a/source3/rpc_parse/parse_rpc.c +++ b/source3/rpc_parse/parse_rpc.c @@ -1189,7 +1189,8 @@ BOOL smb_io_rpc_auth_netsec_neg(const char *desc, RPC_AUTH_NETSEC_NEG *neg, /******************************************************************* reads or writes an RPC_AUTH_NETSEC_CHK structure. ********************************************************************/ -BOOL smb_io_rpc_auth_netsec_chk(const char *desc, RPC_AUTH_NETSEC_CHK * chk, +BOOL smb_io_rpc_auth_netsec_chk(const char *desc, int auth_len, + RPC_AUTH_NETSEC_CHK * chk, prs_struct *ps, int depth) { if (chk == NULL) @@ -1198,10 +1199,19 @@ BOOL smb_io_rpc_auth_netsec_chk(const char *desc, RPC_AUTH_NETSEC_CHK * chk, prs_debug(ps, depth, desc, "smb_io_rpc_auth_netsec_chk"); depth++; - prs_uint8s(False, "sig ", ps, depth, chk->sig, sizeof(chk->sig)); - prs_uint8s(False, "seq_num", ps, depth, chk->seq_num, sizeof(chk->seq_num)); - prs_uint8s(False, "packet_digest", ps, depth, chk->packet_digest, sizeof(chk->packet_digest)); - prs_uint8s(False, "confounder", ps, depth, chk->confounder, sizeof(chk->confounder)); + if ( !prs_uint8s(False, "sig ", ps, depth, chk->sig, sizeof(chk->sig)) ) + return False; + + if ( !prs_uint8s(False, "seq_num", ps, depth, chk->seq_num, sizeof(chk->seq_num)) ) + return False; + + if ( !prs_uint8s(False, "packet_digest", ps, depth, chk->packet_digest, sizeof(chk->packet_digest)) ) + return False; + + if ( auth_len == RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN ) { + if ( !prs_uint8s(False, "confounder", ps, depth, chk->confounder, sizeof(chk->confounder)) ) + return False; + } return True; } diff --git a/source3/rpc_server/srv_pipe.c b/source3/rpc_server/srv_pipe.c index 3a4e085276..13d894d2d8 100644 --- a/source3/rpc_server/srv_pipe.c +++ b/source3/rpc_server/srv_pipe.c @@ -124,7 +124,7 @@ BOOL create_next_pdu(pipes_struct *p) if(p->ntlmssp_auth_validated) { data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NTLMSSP_CHK_LEN); } else if(p->netsec_auth_validated) { - data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NETSEC_CHK_LEN); + data_space_available -= (RPC_HDR_AUTH_LEN + RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN); } /* @@ -177,8 +177,8 @@ BOOL create_next_pdu(pipes_struct *p) } else if (p->netsec_auth_validated) { p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len + ss_padding_len + - RPC_HDR_AUTH_LEN + RPC_AUTH_NETSEC_CHK_LEN; - p->hdr.auth_len = RPC_AUTH_NETSEC_CHK_LEN; + RPC_HDR_AUTH_LEN + RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN; + p->hdr.auth_len = RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN; } else { p->hdr.frag_len = RPC_HEADER_LEN + RPC_HDR_RESP_LEN + data_len; p->hdr.auth_len = 0; @@ -309,7 +309,8 @@ BOOL create_next_pdu(pipes_struct *p) SENDER_IS_ACCEPTOR, &verf, data, data_len + ss_padding_len); - smb_io_rpc_auth_netsec_chk("", &verf, &outgoing_pdu, 0); + smb_io_rpc_auth_netsec_chk("", RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN, + &verf, &outgoing_pdu, 0); p->netsec_auth.seq_num++; } @@ -1339,7 +1340,7 @@ BOOL api_pipe_netsec_process(pipes_struct *p, prs_struct *rpc_in) auth_len = p->hdr.auth_len; - if (auth_len != RPC_AUTH_NETSEC_CHK_LEN) { + if (auth_len != RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN) { DEBUG(0,("Incorrect auth_len %d.\n", auth_len )); return False; } @@ -1384,7 +1385,9 @@ BOOL api_pipe_netsec_process(pipes_struct *p, prs_struct *rpc_in) return False; } - if(!smb_io_rpc_auth_netsec_chk("", &netsec_chk, rpc_in, 0)) { + if(!smb_io_rpc_auth_netsec_chk("", RPC_AUTH_NETSEC_SIGN_OR_SEAL_CHK_LEN, + &netsec_chk, rpc_in, 0)) + { DEBUG(0,("failed to unmarshal RPC_AUTH_NETSEC_CHK.\n")); return False; } |