mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
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 6ca77bd28f
)
This commit is contained in:
parent
2ff85e2f0a
commit
8a4577cc22
@ -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,13 +208,6 @@ 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;
|
||||
@ -219,15 +216,21 @@ static BOOL rpc_auth_pipe(struct cli_state *cli, prs_struct *rdata,
|
||||
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);
|
||||
prs_init(&auth_verf, 0, cli->mem_ctx, UNMARSHALL);
|
||||
|
||||
/* The endinness must be preserved. JRA. */
|
||||
prs_set_endian_data( &auth_verf, rdata->bigendian_data);
|
||||
|
||||
prs_copy_data_in(&auth_verf, dp, RPC_HDR_AUTH_LEN);
|
||||
/* 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;
|
||||
/* copy the next auth_len bytes into a buffer for
|
||||
later use */
|
||||
|
||||
if(dp - prs_data_p(rdata) > prs_data_size(rdata)) {
|
||||
DEBUG(0,("rpc_auth_pipe: auth data > data size !\n"));
|
||||
return False;
|
||||
}
|
||||
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))));
|
||||
ntlmssp_verf)));
|
||||
}
|
||||
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 */
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user