diff options
author | Jeremy Allison <jra@samba.org> | 2007-03-27 21:13:31 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 12:18:58 -0500 |
commit | 4a66d0e232271968ba96da50274428916a393975 (patch) | |
tree | 89e40c8ad86d96458905940839a5ddba4f1bd747 /source3/smbd | |
parent | 34dac35e48ca0c03d2744d9925566665285eb973 (diff) | |
download | samba-4a66d0e232271968ba96da50274428916a393975.tar.gz samba-4a66d0e232271968ba96da50274428916a393975.tar.bz2 samba-4a66d0e232271968ba96da50274428916a393975.zip |
r21991: I hate Steve French :-). Add support for encryption
contexts....
Jeremy.
(This used to be commit ae8f3649f773b8a8dcb55921536d038d3475322e)
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/seal.c | 96 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 12 |
2 files changed, 90 insertions, 18 deletions
diff --git a/source3/smbd/seal.c b/source3/smbd/seal.c index fbb0eade52..d5b956c53d 100644 --- a/source3/smbd/seal.c +++ b/source3/smbd/seal.c @@ -249,6 +249,14 @@ static struct smb_srv_trans_enc_ctx *make_srv_encryption_context(enum smb_trans_ void srv_free_enc_buffer(char *buf) { + /* We know this is an smb buffer, and we + * didn't malloc, only copy, for a keepalive, + * so ignore session keepalives. */ + + if(CVAL(buf,0) == SMBkeepalive) { + return; + } + if (srv_trans_enc_ctx) { common_free_enc_buffer(srv_trans_enc_ctx->es, buf); } @@ -260,9 +268,15 @@ void srv_free_enc_buffer(char *buf) NTSTATUS srv_decrypt_buffer(char *buf) { + /* Ignore session keepalives. */ + if(CVAL(buf,0) == SMBkeepalive) { + return NT_STATUS_OK; + } + if (srv_trans_enc_ctx) { return common_decrypt_buffer(srv_trans_enc_ctx->es, buf); } + return NT_STATUS_OK; } @@ -270,13 +284,19 @@ NTSTATUS srv_decrypt_buffer(char *buf) Encrypt an outgoing buffer. Return the encrypted pointer in buf_out. ******************************************************************************/ -NTSTATUS srv_encrypt_buffer(char *buffer, char **buf_out) +NTSTATUS srv_encrypt_buffer(char *buf, char **buf_out) { + *buf_out = buf; + + /* Ignore session keepalives. */ + if(CVAL(buf,0) == SMBkeepalive) { + return NT_STATUS_OK; + } + if (srv_trans_enc_ctx) { - return common_encrypt_buffer(srv_trans_enc_ctx->es, buffer, buf_out); + return common_encrypt_buffer(srv_trans_enc_ctx->es, buf, buf_out); } /* Not encrypting. */ - *buf_out = buffer; return NT_STATUS_OK; } @@ -340,7 +360,11 @@ static NTSTATUS srv_enc_ntlm_negotiate(unsigned char **ppdata, size_t *p_data_si Until success we do everything on the partial enc ctx. ******************************************************************************/ -static NTSTATUS srv_enc_spnego_negotiate(unsigned char **ppdata, size_t *p_data_size) +static NTSTATUS srv_enc_spnego_negotiate(connection_struct *conn, + unsigned char **ppdata, + size_t *p_data_size, + unsigned char **pparam, + size_t *p_param_size) { NTSTATUS status; DATA_BLOB blob = data_blob(NULL,0); @@ -371,6 +395,17 @@ static NTSTATUS srv_enc_spnego_negotiate(unsigned char **ppdata, size_t *p_data_ if (!NT_STATUS_EQUAL(status,NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) { srv_free_encryption_context(&partial_srv_trans_enc_ctx); + return nt_status_squash(status); + } + + if (NT_STATUS_IS_OK(status)) { + /* Return the context we're using for this encryption state. */ + *pparam = SMB_MALLOC(2); + if (!*pparam) { + return NT_STATUS_NO_MEMORY; + } + SSVAL(*pparam,0,partial_srv_trans_enc_ctx->es->enc_ctx_num); + *p_param_size = 2; } return status; @@ -381,7 +416,11 @@ static NTSTATUS srv_enc_spnego_negotiate(unsigned char **ppdata, size_t *p_data_ We only get this for a NTLM auth second stage. ******************************************************************************/ -static NTSTATUS srv_enc_spnego_ntlm_auth(unsigned char **ppdata, size_t *p_data_size) +static NTSTATUS srv_enc_spnego_ntlm_auth(connection_struct *conn, + unsigned char **ppdata, + size_t *p_data_size, + unsigned char **pparam, + size_t *p_param_size) { NTSTATUS status; DATA_BLOB blob = data_blob(NULL,0); @@ -409,6 +448,16 @@ static NTSTATUS srv_enc_spnego_ntlm_auth(unsigned char **ppdata, size_t *p_data_ response = spnego_gen_auth_response(&auth_reply, status, OID_NTLMSSP); data_blob_free(&auth_reply); + if (NT_STATUS_IS_OK(status)) { + /* Return the context we're using for this encryption state. */ + *pparam = SMB_MALLOC(2); + if (!*pparam) { + return NT_STATUS_NO_MEMORY; + } + SSVAL(*pparam,0,ec->es->enc_ctx_num); + *p_param_size = 2; + } + SAFE_FREE(*ppdata); *ppdata = response.data; *p_data_size = response.length; @@ -420,7 +469,11 @@ static NTSTATUS srv_enc_spnego_ntlm_auth(unsigned char **ppdata, size_t *p_data_ This function does both steps. ******************************************************************************/ -static NTSTATUS srv_enc_raw_ntlm_auth(unsigned char **ppdata, size_t *p_data_size) +static NTSTATUS srv_enc_raw_ntlm_auth(connection_struct *conn, + unsigned char **ppdata, + size_t *p_data_size, + unsigned char **pparam, + size_t *p_param_size) { NTSTATUS status; DATA_BLOB blob = data_blob_const(*ppdata, *p_data_size); @@ -446,6 +499,16 @@ static NTSTATUS srv_enc_raw_ntlm_auth(unsigned char **ppdata, size_t *p_data_siz /* Second step. */ status = auth_ntlmssp_update(partial_srv_trans_enc_ctx->auth_ntlmssp_state, blob, &response); + if (NT_STATUS_IS_OK(status)) { + /* Return the context we're using for this encryption state. */ + *pparam = SMB_MALLOC(2); + if (!*pparam) { + return NT_STATUS_NO_MEMORY; + } + SSVAL(*pparam,0,ec->es->enc_ctx_num); + *p_param_size = 2; + } + /* Return the raw blob. */ SAFE_FREE(*ppdata); *ppdata = response.data; @@ -457,26 +520,29 @@ static NTSTATUS srv_enc_raw_ntlm_auth(unsigned char **ppdata, size_t *p_data_siz Do the SPNEGO encryption negotiation. Parameters are in/out. ******************************************************************************/ -NTSTATUS srv_request_encryption_setup(unsigned char **ppdata, size_t *p_data_size) +NTSTATUS srv_request_encryption_setup(connection_struct *conn, + unsigned char **ppdata, + size_t *p_data_size, + unsigned char **pparam, + size_t *p_param_size) { unsigned char *pdata = *ppdata; + SAFE_FREE(*pparam); + *p_param_size = 0; + if (*p_data_size < 1) { return NT_STATUS_INVALID_PARAMETER; } if (pdata[0] == ASN1_APPLICATION(0)) { - /* - * Until success we do everything on the partial - * enc state. - */ /* its a negTokenTarg packet */ - return srv_enc_spnego_negotiate(ppdata, p_data_size); + return srv_enc_spnego_negotiate(conn, ppdata, p_data_size, pparam, p_param_size); } if (pdata[0] == ASN1_CONTEXT(1)) { /* It's an auth packet */ - return srv_enc_spnego_ntlm_auth(ppdata, p_data_size); + return srv_enc_spnego_ntlm_auth(conn, ppdata, p_data_size, pparam, p_param_size); } /* Maybe it's a raw unwrapped auth ? */ @@ -485,7 +551,7 @@ NTSTATUS srv_request_encryption_setup(unsigned char **ppdata, size_t *p_data_siz } if (strncmp((char *)pdata, "NTLMSSP", 7) == 0) { - return srv_enc_raw_ntlm_auth(ppdata, p_data_size); + return srv_enc_raw_ntlm_auth(conn, ppdata, p_data_size, pparam, p_param_size); } DEBUG(1,("srv_request_encryption_setup: Unknown packet\n")); @@ -518,7 +584,7 @@ static NTSTATUS check_enc_good(struct smb_srv_trans_enc_ctx *ec) Negotiation was successful - turn on server-side encryption. ******************************************************************************/ -NTSTATUS srv_encryption_start(void) +NTSTATUS srv_encryption_start(connection_struct *conn) { NTSTATUS status; diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 007ad50b10..df713db564 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -2765,6 +2765,7 @@ cap_low = 0x%x, cap_high = 0x%x\n", case SMB_REQUEST_TRANSPORT_ENCRYPTION: { NTSTATUS status; + size_t param_len = 0; size_t data_len = total_data; if (!lp_unix_extensions()) { @@ -2773,7 +2774,12 @@ cap_low = 0x%x, cap_high = 0x%x\n", DEBUG( 4,("call_trans2setfsinfo: request transport encrption.\n")); - status = srv_request_encryption_setup((unsigned char **)ppdata, &data_len); + status = srv_request_encryption_setup(conn, + (unsigned char **)ppdata, + &data_len, + (unsigned char **)pparams, + ¶m_len + ); if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { error_packet_set(outbuf, 0, 0, status, __LINE__,__FILE__); @@ -2781,11 +2787,11 @@ cap_low = 0x%x, cap_high = 0x%x\n", return ERROR_NT(status); } - send_trans2_replies( outbuf, bufsize, params, 0, *ppdata, data_len, max_data_bytes); + send_trans2_replies(outbuf, bufsize, *pparams, param_len, *ppdata, data_len, max_data_bytes); if (NT_STATUS_IS_OK(status)) { /* Server-side transport encryption is now *on*. */ - status = srv_encryption_start(); + status = srv_encryption_start(conn); if (!NT_STATUS_IS_OK(status)) { exit_server_cleanly("Failure in setting up encrypted transport"); } |