summaryrefslogtreecommitdiff
path: root/source3/libsmb/smb_seal.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2007-03-19 20:39:58 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:18:42 -0500
commitc48b610b516b72edd6232235a6f83d388f5a0552 (patch)
tree8698a0d14ab7a1a54821d3aa7c316f4f0f10e733 /source3/libsmb/smb_seal.c
parent1899c834f0261edaecc575b17d8aeb57b82717e2 (diff)
downloadsamba-c48b610b516b72edd6232235a6f83d388f5a0552.tar.gz
samba-c48b610b516b72edd6232235a6f83d388f5a0552.tar.bz2
samba-c48b610b516b72edd6232235a6f83d388f5a0552.zip
r21876: Start adding in the seal implementation - prototype code
for the server side enc. (doesn't break anything). I'll keep updating this until I've got NTLM seal working on both client and server, then add in the gss level seal. Jeremy. (This used to be commit 530ac29abf23e920baa549e7cec55199edd8bd74)
Diffstat (limited to 'source3/libsmb/smb_seal.c')
-rw-r--r--source3/libsmb/smb_seal.c178
1 files changed, 176 insertions, 2 deletions
diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c
index eb35fc05f9..90efa05f0b 100644
--- a/source3/libsmb/smb_seal.c
+++ b/source3/libsmb/smb_seal.c
@@ -30,12 +30,186 @@ NTSTATUS cli_encrypt_message(struct cli_state *cli)
return NT_STATUS_OK;
}
-NTSTATUS srv_decrypt_buffer(char *buffer)
+/* Server state if we're encrypting SMBs. If NULL then enc is off. */
+
+static struct smb_trans_enc_state *srv_trans_enc_state;
+
+/******************************************************************************
+ Is server encryption on ?
+******************************************************************************/
+
+BOOL srv_encryption_on(void)
+{
+ return srv_trans_enc_state != NULL;
+}
+
+/******************************************************************************
+ Free an encryption-allocated buffer.
+******************************************************************************/
+
+void srv_free_buffer(char *buf_out)
{
+ if (!srv_trans_enc_state) {
+ return;
+ }
+
+ if (srv_trans_enc_state->smb_enc_type == SMB_TRANS_ENC_NTLM) {
+ SAFE_FREE(buf_out);
+ return;
+ }
+
+#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
+ /* gss-api free buffer.... */
+#endif
+}
+
+/******************************************************************************
+ gss-api decrypt an incoming buffer.
+******************************************************************************/
+
+#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
+static NTSTATUS srv_gss_decrypt_buffer(gss_ctx_id_t context_handle, char *buf)
+{
+ return NT_STATUS_NOT_SUPPORTED;
+}
+#endif
+
+/******************************************************************************
+ NTLM decrypt an incoming buffer.
+******************************************************************************/
+
+static NTSTATUS srv_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf)
+{
+ NTSTATUS status;
+ size_t orig_len = smb_len(buf);
+ size_t new_len = orig_len - NTLMSSP_SIG_SIZE;
+ DATA_BLOB sig;
+
+ if (orig_len < 8 + NTLMSSP_SIG_SIZE) {
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ }
+
+ /* Save off the signature. */
+ sig = data_blob(buf+orig_len-NTLMSSP_SIG_SIZE, NTLMSSP_SIG_SIZE);
+
+ status = ntlmssp_unseal_packet(ntlmssp_state,
+ (unsigned char *)buf + 8, /* 4 byte len + 0xFF 'S' 'M' 'B' */
+ new_len - 8,
+ (unsigned char *)buf,
+ new_len,
+ &sig);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ data_blob_free(&sig);
+ return status;
+ }
+ /* Reset the length. */
+ smb_setlen(buf, new_len);
return NT_STATUS_OK;
}
-NTSTATUS srv_encrypt_buffer(char *buffer)
+/******************************************************************************
+ Decrypt an incoming buffer.
+******************************************************************************/
+
+NTSTATUS srv_decrypt_buffer(char *buf)
{
+ if (!srv_trans_enc_state) {
+ /* Not decrypting. */
+ return NT_STATUS_OK;
+ }
+ if (srv_trans_enc_state->smb_enc_type == SMB_TRANS_ENC_NTLM) {
+ return srv_ntlm_decrypt_buffer(srv_trans_enc_state->ntlmssp_state, buf);
+ } else {
+#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
+ return srv_gss_decrypt_buffer(srv_trans_enc_state->context_handle, buf);
+#else
+ return NT_STATUS_NOT_SUPPORTED;
+#endif
+ }
+}
+
+/******************************************************************************
+ gss-api encrypt an outgoing buffer. Return the encrypted pointer in buf_out.
+******************************************************************************/
+
+#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
+static NTSTATUS srv_gss_encrypt_buffer(gss_ctx_id_t context_handle, char *buf, char **buf_out)
+{
+ return NT_STATUS_NOT_SUPPORTED;
+}
+#endif
+
+/******************************************************************************
+ NTLM encrypt an outgoing buffer. Return the encrypted pointer in ppbuf_out.
+******************************************************************************/
+
+static NTSTATUS srv_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, char **ppbuf_out)
+{
+ NTSTATUS status;
+ char *buf_out;
+ size_t orig_len = smb_len(buf);
+ size_t new_len = orig_len + NTLMSSP_SIG_SIZE;
+ DATA_BLOB sig;
+
+ *ppbuf_out = NULL;
+
+ if (orig_len < 8) {
+ return NT_STATUS_BUFFER_TOO_SMALL;
+ }
+
+ /*
+ * We know smb_len can't return a value > 128k, so no int overflow
+ * check needed.
+ */
+
+ /* Copy the original buffer. */
+
+ buf_out = SMB_XMALLOC_ARRAY(char, new_len);
+ memcpy(buf_out, buf, orig_len);
+ /* Last 16 bytes undefined here... */
+
+ smb_setlen(buf_out, new_len);
+
+ sig = data_blob(NULL, NTLMSSP_SIG_SIZE);
+
+ status = ntlmssp_seal_packet(ntlmssp_state,
+ (unsigned char *)buf_out + 8, /* 4 byte len + 0xFF 'S' 'M' 'B' */
+ orig_len - 8,
+ (unsigned char *)buf_out,
+ orig_len,
+ &sig);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ data_blob_free(&sig);
+ SAFE_FREE(buf_out);
+ return status;
+ }
+
+ memcpy(buf_out+orig_len, sig.data, NTLMSSP_SIG_SIZE);
+ *ppbuf_out = buf_out;
return NT_STATUS_OK;
}
+
+/******************************************************************************
+ Encrypt an outgoing buffer. Return the encrypted pointer in buf_out.
+******************************************************************************/
+
+NTSTATUS srv_encrypt_buffer(char *buffer, char **buf_out)
+{
+ if (!srv_trans_enc_state) {
+ /* Not encrypting. */
+ *buf_out = buffer;
+ return NT_STATUS_OK;
+ }
+
+ if (srv_trans_enc_state->smb_enc_type == SMB_TRANS_ENC_NTLM) {
+ return srv_ntlm_encrypt_buffer(srv_trans_enc_state->ntlmssp_state, buffer, buf_out);
+ } else {
+#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
+ return srv_gss_encrypt_buffer(srv_trans_enc_state->context_handle, buffer, buf_out);
+#else
+ return NT_STATUS_NOT_SUPPORTED;
+#endif
+ }
+}