smbXsrv_session signing_key
authorStefan Metzmacher <metze@samba.org>
Fri, 2 Mar 2012 00:06:06 +0000 (01:06 +0100)
committerStefan Metzmacher <metze@samba.org>
Thu, 10 May 2012 16:42:06 +0000 (18:42 +0200)
source3/smbd/globals.h
source3/smbd/smb2_server.c
source3/smbd/smb2_sesssetup.c

index 39282dead1da1d367b8d442a6e281ffdbace4a65..7d86a62a277c090a26940610da2ba69c6954cbad 100644 (file)
@@ -490,8 +490,8 @@ struct smbd_smb2_session {
        uint64_t vuid;
        struct gensec_security *gensec_security;
        struct auth_session_info *session_info;
-       DATA_BLOB session_key;
-       bool do_signing;
+       //DATA_BLOB session_key;
+       //bool do_signing;
 
        struct smbXsrv_session *smbXsrv;
 
index 2eb1fda1e328bd8226d2fc45e823b6382b36eb97..f84e053fb74b7ab3902be07b348c0694e105d317 100644 (file)
@@ -811,9 +811,13 @@ static NTSTATUS smb2_send_async_interim_response(const struct smbd_smb2_request
        /* Re-sign if needed. */
        if (nreq->do_signing) {
                NTSTATUS status;
-               status = smb2_signing_sign_pdu(nreq->session->session_key,
-                                       get_Protocol(),
-                                       &nreq->out.vector[i], 3);
+               struct smbXsrv_session *x = nreq->session->smbXsrv;
+               struct smbXsrv_connection *conn = x->connection;
+               DATA_BLOB signing_key = x->global->channels[0].signing_key;
+
+               status = smb2_signing_sign_pdu(signing_key,
+                                              conn->protocol,
+                                              &nreq->out.vector[i], 3);
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
                }
@@ -1096,10 +1100,13 @@ static void smbd_smb2_request_pending_timer(struct tevent_context *ev,
 
        if (req->do_signing) {
                NTSTATUS status;
+               struct smbXsrv_session *x = req->session->smbXsrv;
+               struct smbXsrv_connection *conn = x->connection;
+               DATA_BLOB signing_key = x->global->channels[0].signing_key;
 
-               status = smb2_signing_sign_pdu(req->session->session_key,
-                                       get_Protocol(),
-                                       &state->vector[1], 2);
+               status = smb2_signing_sign_pdu(signing_key,
+                                              conn->protocol,
+                                              &state->vector[1], 2);
                if (!NT_STATUS_IS_OK(status)) {
                        smbd_server_connection_terminate(req->sconn,
                                                nt_errstr(status));
@@ -1386,6 +1393,7 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
        NTSTATUS session_status;
        uint32_t allowed_flags;
        NTSTATUS return_value;
+       struct smbXsrv_session *x = NULL;
 
        inhdr = (const uint8_t *)req->in.vector[i].iov_base;
 
@@ -1437,23 +1445,29 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
         * we defer the check of the session_status
         */
        session_status = smbd_smb2_request_check_session(req);
+       if (req->session) {
+               x = req->session->smbXsrv;
+       }
 
        req->do_signing = false;
        if (flags & SMB2_HDR_FLAG_SIGNED) {
+               struct smbXsrv_connection *conn = x->connection;
+               DATA_BLOB signing_key = x->global->channels[0].signing_key;
+
                if (!NT_STATUS_IS_OK(session_status)) {
                        return smbd_smb2_request_error(req, session_status);
                }
 
                req->do_signing = true;
-               status = smb2_signing_check_pdu(req->session->session_key,
-                                               get_Protocol(),
+               status = smb2_signing_check_pdu(signing_key,
+                                               conn->protocol,
                                                &req->in.vector[i], 3);
                if (!NT_STATUS_IS_OK(status)) {
                        return smbd_smb2_request_error(req, status);
                }
        } else if (opcode == SMB2_OP_CANCEL) {
                /* Cancel requests are allowed to skip the signing */
-       } else if (req->session && req->session->do_signing) {
+       } else if (x && x->global->signing_required) {
                return smbd_smb2_request_error(req, NT_STATUS_ACCESS_DENIED);
        }
 
@@ -1935,8 +1949,12 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
 
        if (req->do_signing) {
                NTSTATUS status;
-               status = smb2_signing_sign_pdu(req->session->session_key,
-                                              get_Protocol(),
+               struct smbXsrv_session *x = req->session->smbXsrv;
+               struct smbXsrv_connection *conn = x->connection;
+               DATA_BLOB signing_key = x->global->channels[0].signing_key;
+
+               status = smb2_signing_sign_pdu(signing_key,
+                                              conn->protocol,
                                               &req->out.vector[i], 3);
                if (!NT_STATUS_IS_OK(status)) {
                        return status;
index 27fc5b65bf398eba15b5913357682b12a40c89d7..5ba81c449c7188cb0a9cb1df7012e6a8f7bd7fdc 100644 (file)
@@ -150,10 +150,13 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbd_smb2_session *session,
 {
        NTSTATUS status;
        bool guest = false;
+       uint8_t session_key[16];
+       struct smbXsrv_session *x = session->smbXsrv;
+       struct smbXsrv_connection *conn = x->connection;
 
        if ((in_security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) ||
            lp_server_signing() == SMB_SIGNING_REQUIRED) {
-               session->do_signing = true;
+               x->global->signing_required = true;
        }
 
        if (security_session_user_level(session->session_info, NULL) < SECURITY_USER) {
@@ -161,11 +164,68 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbd_smb2_session *session,
                *out_session_flags |= SMB2_SESSION_FLAG_IS_GUEST;
                *out_session_flags |= SMB2_SESSION_FLAG_IS_NULL;
                /* force no signing */
-               session->do_signing = false;
+               x->global->signing_required = false;
                guest = true;
        }
 
-       session->session_key = session->session_info->session_key;
+       //session->session_key = session->session_info->session_key;
+
+       ZERO_STRUCT(session_key);
+       memcpy(session_key, session->session_info->session_key.data,
+              MIN(session->session_info->session_key.length, sizeof(session_key)));
+
+       x->global->signing_key = data_blob_talloc(x->global,
+                                                 session_key,
+                                                 sizeof(session_key));
+       if (x->global->signing_key.data == NULL) {
+               ZERO_STRUCT(session_key);
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       if (conn->protocol >= PROTOCOL_SMB2_24) {
+#define _STRING_BLOB(x) data_blob_const((const uint8_t *)(x), sizeof(x))
+               const DATA_BLOB label = _STRING_BLOB("SMB2AESCMAC");
+               const DATA_BLOB context = _STRING_BLOB("SmbSign");
+#undef _STRING_BLOB
+
+               smb2_key_derivation(session_key, sizeof(session_key),
+                                   label.data, label.length,
+                                   context.data, context.length,
+                                   x->global->signing_key.data);
+       }
+
+       x->global->application_key = data_blob_dup_talloc(x->global,
+                                               x->global->signing_key);
+       if (x->global->application_key.data == NULL) {
+               ZERO_STRUCT(session_key);
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       if (conn->protocol >= PROTOCOL_SMB2_24) {
+#define _STRING_BLOB(x) data_blob_const((const uint8_t *)(x), sizeof(x))
+               const DATA_BLOB label = _STRING_BLOB("SMB2APP");
+               const DATA_BLOB context = _STRING_BLOB("SmbRpc");
+#undef _STRING_BLOB
+
+               smb2_key_derivation(session_key, sizeof(session_key),
+                                   label.data, label.length,
+                                   context.data, context.length,
+                                   x->global->application_key.data);
+       }
+       ZERO_STRUCT(session_key);
+
+       x->global->channels[0].signing_key = data_blob_dup_talloc(x->global->channels,
+                                               x->global->signing_key);
+       if (x->global->channels[0].signing_key.data == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       data_blob_clear_free(&session->session_info->session_key);
+       session->session_info->session_key = data_blob_dup_talloc(session->session_info,
+                                               x->global->application_key);
+       if (session->session_info->session_key.data == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
 
        session->compat_vuser = talloc_zero(session, user_struct);
        if (session->compat_vuser == NULL) {