make smb_signing more generic... v4-0-aes
authorStefan Metzmacher <metze@samba.org>
Wed, 10 Sep 2008 18:43:37 +0000 (20:43 +0200)
committerStefan Metzmacher <metze@samba.org>
Wed, 10 Sep 2008 18:43:37 +0000 (20:43 +0200)
source/libcli/config.mk
source/libcli/raw/signing.h
source/libcli/raw/smb_signing.c
source/libcli/smb_composite/sesssetup.c
source/smb_server/smb/negprot.c
source/smb_server/smb/receive.c
source/smb_server/smb/signing.c

index 262a2cfa22a61bfb4252387a047cbcc2b19b02b8..3eb9e9aec7bd389dc04f3f28daed94b258efc3c6 100644 (file)
@@ -170,7 +170,7 @@ PRIVATE_DEPENDENCIES = LIBCLI_COMPOSITE LP_RESOLVE gensec LIBCLI_RESOLVE LIBSECU
 #LDFLAGS = $(LIBCLI_SMB_COMPOSITE_OUTPUT)
 PUBLIC_DEPENDENCIES = samba-socket LIBPACKET gensec LIBCRYPTO CREDENTIALS 
 
-LIBCLI_RAW_OBJ_FILES = $(addprefix $(libclisrcdir)/raw/, rawfile.o smb_signing.o clisocket.o \
+LIBCLI_RAW_OBJ_FILES = $(addprefix $(libclisrcdir)/raw/, rawfile.o smb_signing.o clisigning.o clisocket.o \
                                          clitransport.o clisession.o clitree.o clierror.o rawrequest.o \
                                          rawreadwrite.o rawsearch.o rawsetfileinfo.o raweas.o rawtrans.o \
                                          clioplock.o rawnegotiate.o rawfsinfo.o rawfileinfo.o rawnotify.o \
index 56e977ed7c3465dd0e21e5a3f66723c0c6ded996..fb58f371406d730da0f2bf076c5a6d51c311ee21 100644 (file)
@@ -31,13 +31,12 @@ enum smb_signing_state {
        SMB_SIGNING_REQUIRED, SMB_SIGNING_AUTO};
 
 struct smb_signing_context {
-       enum smb_signing_engine_state signing_state;
+       enum smb_signing_engine_state engine_state;
        DATA_BLOB mac_key;
        uint32_t next_seq_num;
-       bool allow_smb_signing;
+       bool allow_signing;
+       bool require_signing;
        bool doing_signing;
-       bool mandatory_signing;
-       bool seen_valid; /* Have I ever seen a validly signed packet? */
 };
 
 #endif
index c4bcc41b8bf41f6936f3788ea2cb2f390c2ee693..3fe97117d5a46681f6cc7e8f1b076ccacfe79405 100644 (file)
@@ -1,9 +1,10 @@
 /* 
    Unix SMB/CIFS implementation.
-   SMB Signing Code
+   SMB Signing Common Code
    Copyright (C) Jeremy Allison 2002.
    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003
    Copyright (C) James J Myers <myersjj@samba.org> 2003
+   Copyright (C) Stefan Metzmacher <metze@samba.org> 2008
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 #include "lib/crypto/crypto.h"
 #include "param/param.h"
 
-/***********************************************************
- SMB signing - Common code before we set a new signing implementation
-************************************************************/
-bool set_smb_signing_common(struct smb_signing_context *sign_info)
+void smb_signing_init_context(struct smb_signing_context *sign_ctx,
+                             enum smb_signing_state state)
+{
+       sign_ctx->engine_state  = SMB_SIGNING_ENGINE_OFF;
+       sign_ctx->mac_key       = data_blob(NULL, 0);
+       sign_ctx->next_seq_num  = 0;
+       sign_ctx->doing_signing = false;
+
+       switch (state) {
+       case SMB_SIGNING_OFF:
+               sign_ctx->allow_signing         = false;
+               sign_ctx->require_signing       = false;
+               break;
+
+       case SMB_SIGNING_SUPPORTED:
+               sign_ctx->allow_signing         = true;
+               sign_ctx->require_signing       = false;
+               break;
+
+       case SMB_SIGNING_REQUIRED:
+       case SMB_SIGNING_AUTO:
+       default:
+               /*
+                * it's the callers task to map 'auto'
+                * if wanted, but here we choose the most secure
+                * option as default
+                */
+               sign_ctx->allow_signing         = true;
+               sign_ctx->require_signing       = true;
+               break;
+       }
+}
+
+bool smb_signing_allow_state_change(struct smb_signing_context *sign_info)
 {
        if (sign_info->doing_signing) {
                DEBUG(5, ("SMB Signing already in progress, so we don't start it again\n"));
                return false;
        }
 
-       if (!sign_info->allow_smb_signing) {
+       if (!sign_info->allow_signing) {
                DEBUG(5, ("SMB Signing has been locally disabled\n"));
                return false;
        }
@@ -44,29 +75,74 @@ bool set_smb_signing_common(struct smb_signing_context *sign_info)
        return true;
 }
 
-/***********************************************************
- SMB signing - Common code before we set a new signing implementation
-************************************************************/
-static bool smbcli_set_smb_signing_common(struct smbcli_transport *transport)
+void smb_signing_set_bsrspyl(struct smb_signing_context *sign_info)
 {
-       if (!set_smb_signing_common(&transport->negotiate.sign_info)) {
-               return false;
+       DEBUG(5,("BSRSPYL SMB signing enabled\n"));
+
+       sign_info->engine_state = SMB_SIGNING_ENGINE_BSRSPYL;
+}
+
+bool smb_signing_set_mac_key(TALLOC_CTX *mem_ctx,
+                            struct smb_signing_context *sign_info,
+                            const DATA_BLOB *user_session_key,
+                            const DATA_BLOB *response)
+{
+       if (sign_info->require_signing) {
+               DEBUG(5, ("Mandatory SMB signing enabled!\n"));
        }
 
-       if (!(transport->negotiate.sec_mode & 
-             (NEGOTIATE_SECURITY_SIGNATURES_REQUIRED|NEGOTIATE_SECURITY_SIGNATURES_ENABLED))) {
-               DEBUG(5, ("SMB Signing is not negotiated by the peer\n"));
-               return false;
+       DEBUG(5, ("SMB signing enabled!\n"));
+
+       if (response && response->length) {
+               sign_info->mac_key = data_blob_talloc(mem_ctx, NULL, response->length + user_session_key->length);
+       } else {
+               sign_info->mac_key = data_blob_talloc(mem_ctx, NULL, user_session_key->length);
        }
 
-       /* These calls are INCOMPATIBLE with SMB signing */
-       transport->negotiate.readbraw_supported = false;
-       transport->negotiate.writebraw_supported = false;
+       memcpy(&sign_info->mac_key.data[0], user_session_key->data, user_session_key->length);
+
+       if (response && response->length) {
+               memcpy(&sign_info->mac_key.data[user_session_key->length],response->data, response->length);
+       }
+
+       dump_data_pw("Started Signing with key:\n", sign_info->mac_key.data, sign_info->mac_key.length);
+
+       sign_info->engine_state = SMB_SIGNING_ENGINE_ON;
 
        return true;
 }
 
-void mark_packet_signed(struct smb_request_buffer *out) 
+uint32_t smb_signing_next_seq_num(struct smb_signing_context *sign_info,
+                                 bool single_increment)
+{
+       uint32_t seq_num;
+
+       seq_num = sign_info->next_seq_num;
+
+       switch (sign_info->engine_state) {
+       case SMB_SIGNING_ENGINE_OFF:
+               break;
+
+       case SMB_SIGNING_ENGINE_BSRSPYL:
+               break;
+
+       case SMB_SIGNING_ENGINE_ON:
+               /*
+                * some requests (eg. NTcancel) are one way, and the sequence number
+                * should be increased by 1 not 2
+                */
+               if (single_increment) {
+                       sign_info->next_seq_num += 1;
+               } else {
+                       sign_info->next_seq_num += 2;
+               }
+               break;
+       }
+
+       return seq_num;
+}
+
+static void mark_packet_signed(struct smb_request_buffer *out)
 {
        uint16_t flags2;
        flags2 = SVAL(out->hdr, HDR_FLG2);
@@ -74,67 +150,83 @@ void mark_packet_signed(struct smb_request_buffer *out)
        SSVAL(out->hdr, HDR_FLG2, flags2);
 }
 
-bool signing_good(struct smb_signing_context *sign_info, 
-                        unsigned int seq, bool good) 
+void smb_signing_create_signature(struct smb_signing_context *sign_info,
+                                 struct smb_request_buffer *buf,
+                                 uint32_t seq_num,
+                                 const struct smb_request_buffer *peer_buf)
 {
-       if (good) {
-               if (!sign_info->doing_signing) {
-                       DEBUG(5, ("Seen valid packet, so turning signing on\n"));
-                       sign_info->doing_signing = true;
-               }
-               if (!sign_info->seen_valid) {
-                       DEBUG(5, ("Seen valid packet, so marking signing as 'seen valid'\n"));
-                       sign_info->seen_valid = true;
-               }
-       } else {
-               if (!sign_info->seen_valid) {
-                       /* If we have never seen a good packet, just turn it off */
-                       DEBUG(5, ("signing_good: signing negotiated but not required and peer\n"
-                                 "isn't sending correct signatures. Turning off.\n"));
-                       smbcli_set_signing_off(sign_info);
-                       return true;
+       const uint8_t *signature;
+       uint8_t calc_md5_mac[16];
+       struct MD5Context md5_ctx;
+
+#if 0
+       /* enable this when packet signing is preventing you working out why valgrind
+          says that data is uninitialised */
+       file_save("pkt.dat", buf->buffer, buf->size);
+#endif
+
+       if (buf->size < (NBT_HDR_SIZE + HDR_SS_FIELD + 8)) {
+               return;
+       }
+
+       switch (sign_info->engine_state) {
+       case SMB_SIGNING_ENGINE_OFF:
+               break;
+
+       case SMB_SIGNING_ENGINE_BSRSPYL:
+               if (peer_buf && peer_buf->size >= (NBT_HDR_SIZE + HDR_SS_FIELD + 8)) {
+                       /* as server we just echo the signature from the client */
+                       signature = buf->hdr + HDR_SS_FIELD;
                } else {
-                       /* bad packet after signing started - fail and disconnect. */
-                       DEBUG(0, ("signing_good: BAD SIG: seq %u\n", seq));
-                       return false;
+                       /*
+                        * I wonder what BSRSPYL stands for - but this is what MS
+                        * actually sends!
+                        */
+                       signature = (const uint8_t *)"BSRSPYL ";
                }
-       }
-       return true;
-}
 
-void sign_outgoing_message(struct smb_request_buffer *out, DATA_BLOB *mac_key, unsigned int seq_num) 
-{
-       uint8_t calc_md5_mac[16];
-       struct MD5Context md5_ctx;
+               mark_packet_signed(buf);
+
+               memcpy(buf->hdr + HDR_SS_FIELD, signature, 8);
+               break;
 
-       /*
-        * Firstly put the sequence number into the first 4 bytes.
-        * and zero out the next 4 bytes.
-        */
-       SIVAL(out->hdr, HDR_SS_FIELD, seq_num);
-       SIVAL(out->hdr, HDR_SS_FIELD + 4, 0);
-
-       /* mark the packet as signed - BEFORE we sign it...*/
-       mark_packet_signed(out);
-
-       /* Calculate the 16 byte MAC and place first 8 bytes into the field. */
-       MD5Init(&md5_ctx);
-        MD5Update(&md5_ctx, mac_key->data, mac_key->length);
-       MD5Update(&md5_ctx, 
-                 out->buffer + NBT_HDR_SIZE, 
-                 out->size - NBT_HDR_SIZE);
-       MD5Final(calc_md5_mac, &md5_ctx);
-
-       memcpy(&out->hdr[HDR_SS_FIELD], calc_md5_mac, 8);
-
-       DEBUG(5, ("sign_outgoing_message: SENT SIG (seq: %d): sent SMB signature of\n", 
-                 seq_num));
-       dump_data(5, calc_md5_mac, 8);
-/*     req->out.hdr[HDR_SS_FIELD+2]=0; 
-       Uncomment this to test if the remote server actually verifies signitures...*/
+       case SMB_SIGNING_ENGINE_ON:
+               /*
+                * Firstly put the sequence number into the first 4 bytes.
+                * and zero out the next 4 bytes.
+                */
+               SIVAL(buf->hdr, HDR_SS_FIELD, seq_num);
+               SIVAL(buf->hdr, HDR_SS_FIELD + 4, 0);
+
+               /* mark the packet as signed - BEFORE we sign it...*/
+               mark_packet_signed(buf);
+
+               /* Calculate the 16 byte MAC and place first 8 bytes into the field. */
+               MD5Init(&md5_ctx);
+               MD5Update(&md5_ctx, sign_info->mac_key.data, sign_info->mac_key.length);
+               MD5Update(&md5_ctx,
+                         buf->buffer + NBT_HDR_SIZE,
+                         buf->size - NBT_HDR_SIZE);
+               MD5Final(calc_md5_mac, &md5_ctx);
+
+               memcpy(buf->hdr + HDR_SS_FIELD, calc_md5_mac, 8);
+
+               DEBUG(5,("smb_signing_create_signature: SENT SIG (seq: %u): sent SMB signature of\n",
+                        seq_num));
+               dump_data(5, calc_md5_mac, 8);
+
+               /*
+                * Uncomment this to test if the remote server actually verifies signitures...
+                */
+               /*req->out.hdr[HDR_SS_FIELD+2]=0;*/
+               break;
+       }
+       return;
 }
 
-bool check_signed_incoming_message(struct smb_request_buffer *in, DATA_BLOB *mac_key, uint_t seq_num) 
+static bool check_signed_incoming_message(const struct smb_request_buffer *in,
+                                         DATA_BLOB *mac_key,
+                                         uint32_t seq_num)
 {
        bool good;
        uint8_t calc_md5_mac[16];
@@ -204,132 +296,45 @@ bool check_signed_incoming_message(struct smb_request_buffer *in, DATA_BLOB *mac
        return good;
 }
 
-static void smbcli_req_allocate_seq_num(struct smbcli_request *req) 
+static bool signing_good(struct smb_signing_context *sign_info,
+                        unsigned int seq, bool good)
 {
-       req->seq_num = req->transport->negotiate.sign_info.next_seq_num;
-       
-       /* some requests (eg. NTcancel) are one way, and the sequence number
-          should be increased by 1 not 2 */
-       if (req->sign_single_increment) {
-               req->transport->negotiate.sign_info.next_seq_num += 1;
+       if (good) {
+               if (!sign_info->doing_signing) {
+                       DEBUG(5, ("Seen valid packet, so turning signing on\n"));
+                       sign_info->doing_signing = true;
+               }
        } else {
-               req->transport->negotiate.sign_info.next_seq_num += 2;
-       }
-}
-
-/***********************************************************
- SMB signing - Simple implementation - calculate a MAC to send.
-************************************************************/
-void smbcli_request_calculate_sign_mac(struct smbcli_request *req)
-{
-       const uint8_t *signature;
-#if 0
-       /* enable this when packet signing is preventing you working out why valgrind 
-          says that data is uninitialised */
-       file_save("pkt.dat", req->out.buffer, req->out.size);
-#endif
-
-       switch (req->transport->negotiate.sign_info.signing_state) {
-       case SMB_SIGNING_ENGINE_OFF:
-               break;
-
-       case SMB_SIGNING_ENGINE_BSRSPYL:
-               if (req->in.size >= (HDR_SS_FIELD + 8) && req->in.hdr) {
-                       /* as server we just echo the signature from the client */
-                       signature = req->in.hdr + HDR_SS_FIELD;
+               if (!sign_info->doing_signing && !sign_info->require_signing) {
+                       /* If we have never seen a good packet, just turn it off */
+                       DEBUG(5, ("signing_good: signing negotiated but not required and peer\n"
+                                 "isn't sending correct signatures. Turning off.\n"));
+                       sign_info->engine_state = SMB_SIGNING_ENGINE_OFF;
+                       data_blob_free(&sign_info->mac_key);
+                       return true;
                } else {
-                       /*
-                        * I wonder what BSRSPYL stands for - but this is what MS
-                        * actually sends!
-                        */
-                       signature = (const uint8_t *)"BSRSPYL ";
+                       /* bad packet after signing started - fail and disconnect. */
+                       DEBUG(0, ("signing_good: BAD SIG: seq %u\n", seq));
+                       return false;
                }
-
-               /* mark the packet as signed - BEFORE we sign it...*/
-               mark_packet_signed(&req->out);
-
-               memcpy((req->out.hdr + HDR_SS_FIELD), signature, 8);
-               break;
-
-       case SMB_SIGNING_ENGINE_ON:
-                       
-               smbcli_req_allocate_seq_num(req);
-               sign_outgoing_message(&req->out, 
-                                     &req->transport->negotiate.sign_info.mac_key, 
-                                     req->seq_num);
-               break;
        }
-       return;
-}
-
-
-/**
- SMB signing - NULL implementation
-
- @note Used as an initialisation only - it will not correctly
-       shut down a real signing mechanism
-*/
-bool smbcli_set_signing_off(struct smb_signing_context *sign_info)
-{
-       DEBUG(5, ("Shutdown SMB signing\n"));
-       sign_info->doing_signing = false;
-       data_blob_free(&sign_info->mac_key);
-       sign_info->signing_state = SMB_SIGNING_ENGINE_OFF;
-       return true;
-}
-
-/**
- SMB signing - TEMP implementation - setup the MAC key.
-
-*/
-bool smbcli_temp_set_signing(struct smbcli_transport *transport)
-{
-       if (!smbcli_set_smb_signing_common(transport)) {
-               return false;
-       }
-       DEBUG(5, ("BSRSPYL SMB signing enabled\n"));
-       smbcli_set_signing_off(&transport->negotiate.sign_info);
-
-       transport->negotiate.sign_info.mac_key = data_blob(NULL, 0);
-       transport->negotiate.sign_info.signing_state = SMB_SIGNING_ENGINE_BSRSPYL;
-
        return true;
 }
 
-/***********************************************************
- SMB signing - Simple implementation - check a MAC sent by server.
-************************************************************/
-/**
- * Check a packet supplied by the server.
- * @return false if we had an established signing connection
- *         which had a back checksum, true otherwise
- */
-bool smbcli_request_check_sign_mac(struct smbcli_request *req) 
+bool smb_signing_check_signature(struct smb_signing_context *sign_info,
+                                const struct smb_request_buffer *buf,
+                                uint32_t seq_num)
 {
        bool good;
 
-       if (!req->transport->negotiate.sign_info.doing_signing &&
-           req->sign_caller_checks) {
-               return true;
-       }
-
-       req->sign_caller_checks = false;
-
-       switch (req->transport->negotiate.sign_info.signing_state) 
-       {
+       switch (sign_info->engine_state) {
        case SMB_SIGNING_ENGINE_OFF:
                return true;
-       case SMB_SIGNING_ENGINE_BSRSPYL:
-               if (req->in.size < (HDR_SS_FIELD + 8)) {
-                       return false;
-               }
 
-               good = check_signed_incoming_message(&req->in,
-                                                    &req->transport->negotiate.sign_info.mac_key,
-                                                    req->seq_num+1);
+       case SMB_SIGNING_ENGINE_BSRSPYL:
+               good = check_signed_incoming_message(buf, &sign_info->mac_key, seq_num);
                if (good) {
-                       return signing_good(&req->transport->negotiate.sign_info,
-                                           req->seq_num+1, good);
+                       return signing_good(sign_info, seq_num, good);
                }
                /*
                 * It's not an error if the signature isn't valid.
@@ -338,93 +343,9 @@ bool smbcli_request_check_sign_mac(struct smbcli_request *req)
                return true;
 
        case SMB_SIGNING_ENGINE_ON:
-               if (req->in.size < (HDR_SS_FIELD + 8)) {
-                       return false;
-               }
-
-               good = check_signed_incoming_message(&req->in,
-                                                    &req->transport->negotiate.sign_info.mac_key,
-                                                    req->seq_num+1);
-
-               return signing_good(&req->transport->negotiate.sign_info,
-                                   req->seq_num+1, good);
-       }
-       return false;
-}
-
-
-/***********************************************************
- SMB signing - Simple implementation - setup the MAC key.
-************************************************************/
-bool smbcli_simple_set_signing(TALLOC_CTX *mem_ctx,
-                              struct smb_signing_context *sign_info,
-                              const DATA_BLOB *user_session_key, 
-                              const DATA_BLOB *response)
-{
-       if (sign_info->mandatory_signing) {
-               DEBUG(5, ("Mandatory SMB signing enabled!\n"));
-       }
-
-       DEBUG(5, ("SMB signing enabled!\n"));
-
-       if (response && response->length) {
-               sign_info->mac_key = data_blob_talloc(mem_ctx, NULL, response->length + user_session_key->length);
-       } else {
-               sign_info->mac_key = data_blob_talloc(mem_ctx, NULL, user_session_key->length);
-       }
-               
-       memcpy(&sign_info->mac_key.data[0], user_session_key->data, user_session_key->length);
-
-       if (response && response->length) {
-               memcpy(&sign_info->mac_key.data[user_session_key->length],response->data, response->length);
+               good = check_signed_incoming_message(buf, &sign_info->mac_key, seq_num);
+               return signing_good(sign_info, seq_num, good);
        }
 
-       dump_data_pw("Started Signing with key:\n", sign_info->mac_key.data, sign_info->mac_key.length);
-
-       sign_info->signing_state = SMB_SIGNING_ENGINE_ON;
-
-       return true;
-}
-
-
-/***********************************************************
- SMB signing - Simple implementation - setup the MAC key.
-************************************************************/
-bool smbcli_transport_simple_set_signing(struct smbcli_transport *transport,
-                                        const DATA_BLOB user_session_key, 
-                                        const DATA_BLOB response)
-{
-       if (!smbcli_set_smb_signing_common(transport)) {
-               return false;
-       }
-
-       return smbcli_simple_set_signing(transport,
-                                        &transport->negotiate.sign_info,
-                                        &user_session_key,
-                                        &response);
-}
-
-
-bool smbcli_init_signing(struct smbcli_transport *transport) 
-{
-       transport->negotiate.sign_info.next_seq_num = 0;
-       transport->negotiate.sign_info.mac_key = data_blob(NULL, 0);
-       if (!smbcli_set_signing_off(&transport->negotiate.sign_info)) {
-               return false;
-       }
-       
-       switch (transport->options.signing) {
-       case SMB_SIGNING_OFF:
-               transport->negotiate.sign_info.allow_smb_signing = false;
-               break;
-       case SMB_SIGNING_SUPPORTED:
-       case SMB_SIGNING_AUTO:
-               transport->negotiate.sign_info.allow_smb_signing = true;
-               break;
-       case SMB_SIGNING_REQUIRED:
-               transport->negotiate.sign_info.allow_smb_signing = true;
-               transport->negotiate.sign_info.mandatory_signing = true;
-               break;
-       }
-       return true;
+       return false;
 }
index b918c842d5a2cb1b719db6a570ad92716f0ee715..4c0cbd327076a9cbedb1cb569d35664b8098b637 100644 (file)
@@ -229,7 +229,8 @@ static void request_handler(struct smbcli_request *req)
        /* enforce the local signing required flag */
        if (NT_STATUS_IS_OK(c->status) && !cli_credentials_is_anonymous(state->io->in.credentials)) {
                if (!session->transport->negotiate.sign_info.doing_signing 
-                   && session->transport->negotiate.sign_info.mandatory_signing) {
+                   && session->transport->negotiate.sign_info.require_signing) {
+/* TODO: moves this checks*/
                        DEBUG(0, ("SMB signing required, but server does not support it\n"));
                        c->status = NT_STATUS_ACCESS_DENIED;
                }
@@ -499,7 +500,7 @@ static NTSTATUS session_setup_spnego(struct composite_context *c,
                session_key_err = gensec_session_key(session->gensec, &session_key);
                if (NT_STATUS_IS_OK(session_key_err)) {
                        smbcli_transport_simple_set_signing(session->transport, session_key, null_data_blob);
-                       session->transport->negotiate.sign_info.next_seq_num += 2;
+                       smb_signing_next_seq_num(&session->transport->negotiate.sign_info, false);
                }
        }
 
index 00ff3862f5edbf678211a835dda8dc0d640dae71..514268eefcd423c130a3609ebc2c2ea480a9d892 100644 (file)
@@ -76,7 +76,7 @@ static void reply_corep(struct smbsrv_request *req, uint16_t choice)
 
        req->smb_conn->negotiate.protocol = PROTOCOL_CORE;
 
-       if (req->smb_conn->signing.mandatory_signing) {
+       if (req->smb_conn->signing.require_signing) {
                smbsrv_terminate_connection(req->smb_conn, 
                                            "CORE does not support SMB signing, and it is mandatory\n");
                return;
@@ -109,7 +109,7 @@ static void reply_coreplus(struct smbsrv_request *req, uint16_t choice)
 
        req->smb_conn->negotiate.protocol = PROTOCOL_COREPLUS;
 
-       if (req->smb_conn->signing.mandatory_signing) {
+       if (req->smb_conn->signing.require_signing) {
                smbsrv_terminate_connection(req->smb_conn, 
                                            "COREPLUS does not support SMB signing, and it is mandatory\n");
                return;
@@ -167,7 +167,7 @@ static void reply_lanman1(struct smbsrv_request *req, uint16_t choice)
                }
        }
 
-       if (req->smb_conn->signing.mandatory_signing) {
+       if (req->smb_conn->signing.require_signing) {
                smbsrv_terminate_connection(req->smb_conn, 
                                            "LANMAN1 does not support SMB signing, and it is mandatory\n");
                return;
@@ -217,7 +217,7 @@ static void reply_lanman2(struct smbsrv_request *req, uint16_t choice)
 
        req_push_str(req, NULL, lp_workgroup(req->smb_conn->lp_ctx), -1, STR_TERMINATE);
 
-       if (req->smb_conn->signing.mandatory_signing) {
+       if (req->smb_conn->signing.require_signing) {
                smbsrv_terminate_connection(req->smb_conn, 
                                            "LANMAN2 does not support SMB signing, and it is mandatory\n");
                return;
@@ -313,11 +313,11 @@ static void reply_nt1(struct smbsrv_request *req, uint16_t choice)
                secword |= NEGOTIATE_SECURITY_CHALLENGE_RESPONSE;
        }
 
-       if (req->smb_conn->signing.allow_smb_signing) {
+       if (req->smb_conn->signing.allow_signing) {
                secword |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED;
        }
 
-       if (req->smb_conn->signing.mandatory_signing) {
+       if (req->smb_conn->signing.require_signing) {
                secword |= NEGOTIATE_SECURITY_SIGNATURES_REQUIRED;
        }
        
index fd2810e54a3810cbc98bce3b704e654075b0c5c4..37eb76d3ece5231eede31273351b2bed5f1f2fe2 100644 (file)
@@ -533,7 +533,7 @@ static void switch_message(int type, struct smbsrv_request *req)
                 * so just skip the reply
                 */
                if ((flags & SIGNING_NO_REPLY) &&
-                   (req->smb_conn->signing.signing_state != SMB_SIGNING_ENGINE_OFF)) {
+                   (req->smb_conn->signing.engine_state != SMB_SIGNING_ENGINE_OFF)) {
                        DEBUG(1,("SKIP ERROR REPLY: %s %s because of unknown smb signing case\n",
                                smb_fn_name(type), nt_errstr(status)));
                        talloc_free(req);
@@ -565,7 +565,7 @@ static void switch_message(int type, struct smbsrv_request *req)
                 * so just skip the reply
                 */
                if ((flags & SIGNING_NO_REPLY) &&
-                   (req->smb_conn->signing.signing_state != SMB_SIGNING_ENGINE_OFF)) {
+                   (req->smb_conn->signing.engine_state != SMB_SIGNING_ENGINE_OFF)) {
                        DEBUG(1,("SKIP ERROR REPLY: %s %s because of unknown smb signing case\n",
                                smb_fn_name(type), nt_errstr(status)));
                        talloc_free(req);
index b103bbcd60530fd1f4996c9a06c3ac8ca00727f4..c0243865d497b7bfe09fd1b443e6477c990ca30c 100644 (file)
 */
 void smbsrv_sign_packet(struct smbsrv_request *req)
 {
-#if 0
-       /* enable this when packet signing is preventing you working out why valgrind 
-          says that data is uninitialised */
-       file_save("pkt.dat", req->out.buffer, req->out.size);
-#endif
-
-       switch (req->smb_conn->signing.signing_state) {
-       case SMB_SIGNING_ENGINE_OFF:
-               break;
-
-       case SMB_SIGNING_ENGINE_BSRSPYL:
-               /* mark the packet as signed - BEFORE we sign it...*/
-               mark_packet_signed(&req->out);
-               
-               /* I wonder what BSRSPYL stands for - but this is what MS 
-                  actually sends! */
-               memcpy((req->out.hdr + HDR_SS_FIELD), "BSRSPYL ", 8);
-               break;
-
-       case SMB_SIGNING_ENGINE_ON:
-                       
-               sign_outgoing_message(&req->out, 
-                                     &req->smb_conn->signing.mac_key, 
-                                     req->seq_num+1);
-               break;
-       }
-       return;
+       smb_signing_create_signature(&req->smb_conn->signing,
+                                    &req->out, req->seq_num+1, &req->in);
 }
 
-
-
 /*
   setup the signing key for a connection. Called after authentication succeeds
   in a session setup
@@ -68,11 +41,11 @@ bool smbsrv_setup_signing(struct smbsrv_connection *smb_conn,
                          DATA_BLOB *session_key,
                          DATA_BLOB *response)
 {
-       if (!set_smb_signing_common(&smb_conn->signing)) {
+       if (!smb_signing_allow_state_change(&smb_conn->signing)) {
                return false;
        }
-       return smbcli_simple_set_signing(smb_conn,
-                                        &smb_conn->signing, session_key, response);
+       return smb_signing_set_mac_key(smb_conn, &smb_conn->signing,
+                                      session_key, response);
 }
 
 void smbsrv_signing_restart(struct smbsrv_connection *smb_conn,
@@ -80,113 +53,45 @@ void smbsrv_signing_restart(struct smbsrv_connection *smb_conn,
                            DATA_BLOB *response,
                            bool authenticated_session) 
 {
-       if (!smb_conn->signing.seen_valid) {
-               DEBUG(5, ("Client did not send a valid signature on "
-                         "SPNEGO session setup - ignored, expect good next time\n"));
-               /* force things back on (most clients do not sign this packet)... */
-               smbsrv_setup_signing(smb_conn, session_key, response);
-               smb_conn->signing.next_seq_num = 2;
+       bool ok;
 
-               /* If mandetory_signing is set, and this was an authenticated logon, then force on */
-               if (smb_conn->signing.mandatory_signing && authenticated_session) {
-                       DEBUG(5, ("Configured for mandatory signing, 'good packet seen' forced on\n"));
-                       /* if this is mandatory, then
-                        * pretend we have seen a
-                        * valid packet, so we don't
-                        * turn it off */
-                       smb_conn->signing.seen_valid = true;
-               }
+       if (!smb_signing_allow_state_change(&smb_conn->signing)) {
+               return;
        }
-}
 
-bool smbsrv_init_signing(struct smbsrv_connection *smb_conn)
-{
-       smb_conn->signing.mac_key = data_blob(NULL, 0);
-       if (!smbcli_set_signing_off(&smb_conn->signing)) {
-               return false;
-       }
-       
-       switch (lp_server_signing(smb_conn->lp_ctx)) {
-       case SMB_SIGNING_OFF:
-               smb_conn->signing.allow_smb_signing = false;
-               break;
-       case SMB_SIGNING_SUPPORTED:
-               smb_conn->signing.allow_smb_signing = true;
-               break;
-       case SMB_SIGNING_REQUIRED:
-               smb_conn->signing.allow_smb_signing = true;
-               smb_conn->signing.mandatory_signing = true;
-               break;
-       case SMB_SIGNING_AUTO:
-               if (lp_server_role(smb_conn->lp_ctx) == ROLE_DOMAIN_CONTROLLER) {
-                       smb_conn->signing.allow_smb_signing = true;
-                       smb_conn->signing.mandatory_signing = true;
-               } else {
-                       smb_conn->signing.allow_smb_signing = true;
-               }
-               break;
-       }
-       return true;
-}
+/* TODO: handle anon...*/
 
-/*
-  allocate a sequence number to a request
-*/
-static void req_signing_alloc_seq_num(struct smbsrv_request *req)
-{
-       req->seq_num = req->smb_conn->signing.next_seq_num;
+       DEBUG(5, ("Client did not send a valid signature on "
+                 "SPNEGO session setup - ignored, expect good next time\n"));
 
-       if (req->smb_conn->signing.signing_state != SMB_SIGNING_ENGINE_OFF) {
-               req->smb_conn->signing.next_seq_num += 2;
+       ok = smb_signing_set_mac_key(smb_conn, &smb_conn->signing,
+                                    session_key, response);
+       if (ok) {
+               smb_signing_next_seq_num(&smb_conn->signing, false);
        }
 }
 
-/*
-  called for requests that do not produce a reply of their own
-*/
-void smbsrv_signing_no_reply(struct smbsrv_request *req)
+void smbsrv_init_signing(struct smbsrv_connection *smb_conn)
 {
-       if (req->smb_conn->signing.signing_state != SMB_SIGNING_ENGINE_OFF) {
-               req->smb_conn->signing.next_seq_num--;
+       enum smb_signing_state signing = lp_server_signing(smb_conn->lp_ctx);
+
+       if (signing == SMB_SIGNING_AUTO) {
+               if (lp_server_role(smb_conn->lp_ctx) == ROLE_DOMAIN_CONTROLLER) {
+                       signing = SMB_SIGNING_REQUIRED;
+               } else {
+                       signing = SMB_SIGNING_SUPPORTED;
+               }
        }
+
+       smb_signing_init_context(&smb_conn->signing, signing);
 }
 
-/***********************************************************
- SMB signing - Simple implementation - check a MAC sent by client
-************************************************************/
-/**
- * Check a packet supplied by the server.
- * @return false if we had an established signing connection
- *         which had a back checksum, true otherwise
- */
 bool smbsrv_signing_check_incoming(struct smbsrv_request *req,
                                   bool single_increment)
 {
-       bool good;
-
-       req_signing_alloc_seq_num(req);
-       if (single_increment) {
-               smbsrv_signing_no_reply(req);
-       }
+       req->seq_num = smb_signing_next_seq_num(&req->smb_conn->signing,
+                                               single_increment);
 
-       switch (req->smb_conn->signing.signing_state) 
-       {
-       case SMB_SIGNING_ENGINE_OFF:
-               return true;
-       case SMB_SIGNING_ENGINE_BSRSPYL:
-       case SMB_SIGNING_ENGINE_ON:
-       {                       
-               if (req->in.size < (HDR_SS_FIELD + 8)) {
-                       return false;
-               } else {
-                       good = check_signed_incoming_message(&req->in, 
-                                                            &req->smb_conn->signing.mac_key, 
-                                                            req->seq_num);
-                       
-                       return signing_good(&req->smb_conn->signing, 
-                                           req->seq_num+1, good);
-               }
-       }
-       }
-       return false;
+       return smb_signing_check_signature(&req->smb_conn->signing,
+                                          &req->in, req->seq_num);
 }