r22013: Move to SSPI framing (sig first in NTLM).
authorJeremy Allison <jra@samba.org>
Fri, 30 Mar 2007 22:19:51 +0000 (22:19 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:19:01 +0000 (12:19 -0500)
Jeremy
(This used to be commit 22eaed76f01ea9d0184dcaf57adca23abc6330b9)

source3/libsmb/smb_seal.c
source3/smbd/seal.c

index 891673ed154af20a56057c4116db197246f123e5..fac451a6c599769f734f2bfd51d51ce4c7628873 100644 (file)
@@ -30,13 +30,15 @@ NTSTATUS get_enc_ctx_num(char *buf, uint16 *p_enc_ctx_num)
                return NT_STATUS_INVALID_BUFFER_SIZE;
        }
 
-       if (buf[4] == (char)0xFF && buf[5] == 'S') {
-               if (buf [6] == 'M' && buf[7] == 'B') {
+       if (buf[4] == (char)0xFF) {
+               if (buf[5] == 'S' && buf [6] == 'M' && buf[7] == 'B') {
                        /* Not an encrypted buffer. */
                        return NT_STATUS_NOT_FOUND;
                }
-               *p_enc_ctx_num = SVAL(buf,6);
-               return NT_STATUS_OK;
+               if (buf[5] == 'E') {
+                       *p_enc_ctx_num = SVAL(buf,6);
+                       return NT_STATUS_OK;
+               }
        }
        return NT_STATUS_INVALID_NETWORK_RESPONSE;
 }
@@ -54,44 +56,55 @@ BOOL common_encryption_on(struct smb_trans_enc_state *es)
 /******************************************************************************
  Generic code for client and server.
  NTLM decrypt an incoming buffer.
+ Abartlett tells me that SSPI puts the signature first before the encrypted
+ output, so cope with the same for compatibility.
 ******************************************************************************/
 
 NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf)
 {
        NTSTATUS status;
        size_t buf_len = smb_len(buf) + 4; /* Don't forget the 4 length bytes. */
+       size_t data_len;
+       char *inbuf;
        DATA_BLOB sig;
 
        if (buf_len < 8 + NTLMSSP_SIG_SIZE) {
                return NT_STATUS_BUFFER_TOO_SMALL;
        }
 
+       inbuf = smb_xmemdup(buf, buf_len);
+
        /* Adjust for the signature. */
-       buf_len -= NTLMSSP_SIG_SIZE;
+       data_len = buf_len - 8 - NTLMSSP_SIG_SIZE;
 
-       /* Save off the signature. */
-       sig = data_blob(buf+buf_len, NTLMSSP_SIG_SIZE);
+       /* Point at the signature. */
+       sig = data_blob_const(inbuf+8, NTLMSSP_SIG_SIZE);
 
        status = ntlmssp_unseal_packet(ntlmssp_state,
-               (unsigned char *)buf + 8, /* 4 byte len + 0xFF 'S' <enc> <ctx> */
-               buf_len - 8,
-               (unsigned char *)buf + 8,
-               buf_len - 8,
+               (unsigned char *)inbuf + 8 + NTLMSSP_SIG_SIZE, /* 4 byte len + 0xFF 'E' <enc> <ctx> */
+               data_len,
+               (unsigned char *)inbuf + 8 + NTLMSSP_SIG_SIZE,
+               data_len,
                &sig);
 
        if (!NT_STATUS_IS_OK(status)) {
-               data_blob_free(&sig);
+               SAFE_FREE(inbuf);
                return status;
        }
 
+       memcpy(buf + 8, inbuf + 8 + NTLMSSP_SIG_SIZE, data_len);
+       SAFE_FREE(inbuf);
+
        /* Reset the length. */
-       smb_setlen(buf, smb_len(buf) - NTLMSSP_SIG_SIZE);
+       smb_setlen(buf, data_len + 4);
        return NT_STATUS_OK;
 }
 
 /******************************************************************************
  Generic code for client and server.
  NTLM encrypt an outgoing buffer. Return the encrypted pointer in ppbuf_out.
+ Abartlett tells me that SSPI puts the signature first before the encrypted
+ output, so do the same for compatibility.
 ******************************************************************************/
 
 NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state,
@@ -101,12 +114,12 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state,
 {
        NTSTATUS status;
        char *buf_out;
-       size_t buf_len = smb_len(buf) + 4; /* Don't forget the 4 length bytes. */
+       size_t data_len = smb_len(buf) - 4; /* Ignore the 0xFF SMB bytes. */
        DATA_BLOB sig;
 
        *ppbuf_out = NULL;
 
-       if (buf_len < 8) {
+       if (data_len == 0) {
                return NT_STATUS_BUFFER_TOO_SMALL;
        }
 
@@ -115,21 +128,21 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state,
         * check needed.
         */
 
-       /* Copy the original buffer. */
+       buf_out = SMB_XMALLOC_ARRAY(char, 8 + NTLMSSP_SIG_SIZE + data_len);
+
+       /* Copy the data from the original buffer. */
 
-       buf_out = SMB_XMALLOC_ARRAY(char, buf_len + NTLMSSP_SIG_SIZE);
-       memcpy(buf_out, buf, buf_len);
-       /* Last 16 bytes undefined here... */
+       memcpy(buf_out + 8 + NTLMSSP_SIG_SIZE, buf + 8, data_len);
 
        smb_set_enclen(buf_out, smb_len(buf) + NTLMSSP_SIG_SIZE, enc_ctx_num);
 
        sig = data_blob(NULL, NTLMSSP_SIG_SIZE);
 
        status = ntlmssp_seal_packet(ntlmssp_state,
-               (unsigned char *)buf_out + 8, /* 4 byte len + 0xFF 'S' <enc> <ctx> */
-               buf_len - 8,
-               (unsigned char *)buf_out + 8,
-               buf_len - 8,
+               (unsigned char *)buf_out + 8 + NTLMSSP_SIG_SIZE, /* 4 byte len + 0xFF 'S' <enc> <ctx> */
+               data_len,
+               (unsigned char *)buf_out + 8 + NTLMSSP_SIG_SIZE,
+               data_len,
                &sig);
 
        if (!NT_STATUS_IS_OK(status)) {
@@ -138,7 +151,8 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state,
                return status;
        }
 
-       memcpy(buf_out+buf_len, sig.data, NTLMSSP_SIG_SIZE);
+       /* First 16 data bytes are signature for SSPI compatibility. */
+       memcpy(buf_out + 8, sig.data, NTLMSSP_SIG_SIZE);
        *ppbuf_out = buf_out;
        return NT_STATUS_OK;
 }
@@ -195,14 +209,12 @@ NTSTATUS common_gss_decrypt_buffer(struct smb_tran_enc_state_gss *gss_state, cha
        gss_release_buffer(&minor, &out_buf);
        return NT_STATUS_OK;
 }
-#endif
 
 /******************************************************************************
  Generic code for client and server.
  gss-api encrypt an outgoing buffer. Return the alloced encrypted pointer in buf_out.
 ******************************************************************************/
 
-#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
 NTSTATUS common_gss_encrypt_buffer(struct smb_tran_enc_state_gss *gss_state,
                                        uint16 enc_ctx_num,
                                        char *buf,
index 0a093d21ab2f3063e90b7e909dfbd7e40085c528..66ae8419d46244c7d5565b3e72d71978cd8b277b 100644 (file)
@@ -91,7 +91,7 @@ static void destroy_auth_ntlmssp(struct smb_srv_trans_enc_ctx *ec)
  Import a name.
 ******************************************************************************/
 
-static NTSTATUS get_gss_creds(const char *service,
+static NTSTATUS get_srv_gss_creds(const char *service,
                                const char *name,
                                gss_cred_usage_t cred_type,
                                gss_cred_id_t *p_srv_cred)
@@ -154,9 +154,9 @@ static NTSTATUS make_auth_gss(struct smb_srv_trans_enc_ctx *ec)
        name_to_fqdn(fqdn, global_myname());
        strlower_m(fqdn);
 
-       status = get_gss_creds("cifs", fqdn, GSS_C_ACCEPT, &srv_cred);
+       status = get_srv_gss_creds("cifs", fqdn, GSS_C_ACCEPT, &srv_cred);
        if (!NT_STATUS_IS_OK(status)) {
-               status = get_gss_creds("host", fqdn, GSS_C_ACCEPT, &srv_cred);
+               status = get_srv_gss_creds("host", fqdn, GSS_C_ACCEPT, &srv_cred);
                if (!NT_STATUS_IS_OK(status)) {
                        return nt_status_squash(status);
                }