From 8a4577cc22be9937dbd5f5334bf4e8b01f81b199 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 16 Jul 2003 03:22:43 +0000 Subject: Fix up our auth_pipe code to always cope with fragmented datagrams, in both SCHANNEL and NTLMSSP. (Try not to deal with a general case as individual special cases...) Andrew Bartlett (This used to be commit 6ca77bd28f16f9f65ff40bf8996e39356de5b4f8) --- source3/rpc_client/cli_pipe.c | 105 +++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 64 deletions(-) (limited to 'source3/rpc_client') diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index d8f5e01cc2..d6307ddb46 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -185,6 +185,10 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, RPC_HDR_AUTH rhdr_auth; + char *dp = prs_data_p(rdata) + fragment_start + len - + RPC_HDR_AUTH_LEN - auth_len; + prs_struct auth_verf; + *pauth_padding_len = 0; if (auth_len == 0) { @@ -204,30 +208,29 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, BOOLSTR(cli->pipe_auth_flags & AUTH_PIPE_SIGN), BOOLSTR(cli->pipe_auth_flags & AUTH_PIPE_SEAL))); - { - int auth_type; - int auth_level; - char *dp = prs_data_p(rdata) + fragment_start + len - - RPC_HDR_AUTH_LEN - auth_len; - prs_struct auth_verf; - - if (dp - prs_data_p(rdata) > prs_data_size(rdata)) { - DEBUG(0,("rpc_auth_pipe: schannel auth data > data size !\n")); - return False; - } - - DEBUG(10,("rpc_auth_pipe: packet:\n")); - dump_data(100, dp, auth_len); - - prs_init(&auth_verf, RPC_HDR_AUTH_LEN, cli->mem_ctx, UNMARSHALL); - - /* The endinness must be preserved. JRA. */ - prs_set_endian_data( &auth_verf, rdata->bigendian_data); + if (dp - prs_data_p(rdata) > prs_data_size(rdata)) { + DEBUG(0,("rpc_auth_pipe: schannel auth data > data size !\n")); + return False; + } - prs_copy_data_in(&auth_verf, dp, RPC_HDR_AUTH_LEN); - prs_set_offset(&auth_verf, 0); + DEBUG(10,("rpc_auth_pipe: packet:\n")); + dump_data(100, dp, auth_len); + prs_init(&auth_verf, 0, cli->mem_ctx, UNMARSHALL); + + /* The endinness must be preserved. JRA. */ + prs_set_endian_data( &auth_verf, rdata->bigendian_data); + + /* Point this new parse struct at the auth section of the main + parse struct - rather than copying it. Avoids needing to + free it on every error + */ + prs_give_memory(&auth_verf, dp, RPC_HDR_AUTH_LEN + auth_len, False /* not dynamic */); + prs_set_offset(&auth_verf, 0); + { + int auth_type; + int auth_level; if (!smb_io_rpc_hdr_auth("auth_hdr", &rhdr_auth, &auth_verf, 0)) { DEBUG(0, ("rpc_auth_pipe: Could not parse auth header\n")); return False; @@ -254,20 +257,21 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, if (pkt_type == RPC_BINDACK) { if (cli->pipe_auth_flags & AUTH_PIPE_NTLMSSP) { - char *dp = prs_data_p(rdata) + len - auth_len; - - if(dp - prs_data_p(rdata) > prs_data_size(rdata)) { - DEBUG(0,("rpc_auth_pipe: auth data > data size !\n")); - return False; - } + /* copy the next auth_len bytes into a buffer for + later use */ + + DATA_BLOB ntlmssp_verf = data_blob(NULL, auth_len); /* save the reply away, for use a little later */ + prs_copy_data_out(ntlmssp_verf.data, &auth_verf, auth_len); + + return (NT_STATUS_IS_OK(ntlmssp_client_store_response(cli->ntlmssp_pipe_state, - data_blob(dp, auth_len)))); - } - if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { - /* nothing to do here - we don't seem to be able to validate the - bindack based on VL's comments */ + ntlmssp_verf))); + } + else if (cli->pipe_auth_flags & AUTH_PIPE_NETSEC) { + /* nothing to do here - we don't seem to be able to + validate the bindack based on VL's comments */ return True; } } @@ -277,19 +281,12 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, DATA_BLOB sig; if ((cli->pipe_auth_flags & AUTH_PIPE_SIGN) || (cli->pipe_auth_flags & AUTH_PIPE_SEAL)) { - char *dp = prs_data_p(rdata) + len - auth_len; - - if(dp - prs_data_p(rdata) > prs_data_size(rdata)) { - DEBUG(0,("rpc_auth_pipe: auth data > data size !\n")); - return False; - } - if (auth_len != RPC_AUTH_NTLMSSP_CHK_LEN) { DEBUG(0,("rpc_auth_pipe: wrong ntlmssp auth len %d\n", auth_len)); return False; } - - sig = data_blob(dp, auth_len); + sig = data_blob(NULL, auth_len); + prs_copy_data_out(sig.data, &auth_verf, auth_len); } /* @@ -308,8 +305,8 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, return False; } nt_status = ntlmssp_client_unseal_packet(cli->ntlmssp_pipe_state, - reply_data, data_len, - &sig); + reply_data, data_len, + &sig); } else if (cli->pipe_auth_flags & AUTH_PIPE_SIGN) { nt_status = ntlmssp_client_check_packet(cli->ntlmssp_pipe_state, @@ -328,34 +325,16 @@ 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; - prs_struct netsec_verf; - - char *dp = prs_data_p(rdata) + fragment_start + len - auth_len; - - if(dp - prs_data_p(rdata) > prs_data_size(rdata)) { - DEBUG(0,("rpc_auth_pipe: auth data > data size !\n")); - return False; - } if (auth_len != RPC_AUTH_NETSEC_CHK_LEN) { DEBUG(0,("rpc_auth_pipe: wrong schannel auth len %d\n", auth_len)); return False; } - prs_init(&netsec_verf, RPC_AUTH_NETSEC_CHK_LEN, - cli->mem_ctx, UNMARSHALL); - - /* The endinness must be preserved. JRA. */ - prs_set_endian_data( &netsec_verf, rdata->bigendian_data); - - prs_copy_data_in(&netsec_verf, dp, auth_len); - prs_set_offset(&netsec_verf, 0); - if (!smb_io_rpc_auth_netsec_chk("schannel_auth_sign", - &chk, &netsec_verf, 0)) { + &chk, &auth_verf, 0)) { DEBUG(0, ("rpc_auth_pipe: schannel unmarshalling " "RPC_AUTH_NETSECK_CHK failed\n")); - prs_mem_free(&netsec_verf); return False; } @@ -364,13 +343,11 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata, SENDER_IS_ACCEPTOR, &chk, reply_data, data_len)) { DEBUG(0, ("rpc_auth_pipe: Could not decode schannel\n")); - prs_mem_free(&netsec_verf); return False; } cli->auth_info.seq_num++; - prs_mem_free(&netsec_verf); } return True; } -- cgit