s3:smbd: setup session->global->signing_/application_key during SPNEGO SMB1 session...
authorStefan Metzmacher <metze@samba.org>
Thu, 2 Aug 2012 16:47:48 +0000 (18:47 +0200)
committerStefan Metzmacher <metze@samba.org>
Sat, 4 Aug 2012 09:09:42 +0000 (11:09 +0200)
metze

Autobuild-User(master): Stefan Metzmacher <metze@samba.org>
Autobuild-Date(master): Sat Aug  4 11:09:42 CEST 2012 on sn-devel-104

source3/smbd/sesssetup.c

index 003e4952f2d013defd815523e2bbcc69ff147c78..cf9c2e73dd52668b04f2df7617a62fd74bee7a4c 100644 (file)
@@ -283,6 +283,58 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
                        action = 1;
                }
 
+               if (session_info->session_key.length > 0) {
+                       struct smbXsrv_session *x = session;
+                       uint8_t session_key[16];
+
+                       /*
+                        * Note: the SMB1 signing key is not truncated to 16 byte!
+                        */
+                       x->global->signing_key =
+                               data_blob_dup_talloc(x->global,
+                                                    session_info->session_key);
+                       if (x->global->signing_key.data == NULL) {
+                               data_blob_free(&out_blob);
+                               TALLOC_FREE(session);
+                               reply_nterror(req, NT_STATUS_NO_MEMORY);
+                               return;
+                       }
+
+                       /*
+                        * The application key is truncated/padded to 16 bytes
+                        */
+                       ZERO_STRUCT(session_key);
+                       memcpy(session_key, x->global->signing_key.data,
+                              MIN(x->global->signing_key.length,
+                                  sizeof(session_key)));
+                       x->global->application_key =
+                               data_blob_talloc(x->global,
+                                                session_key,
+                                                sizeof(session_key));
+                       ZERO_STRUCT(session_key);
+                       if (x->global->application_key.data == NULL) {
+                               data_blob_free(&out_blob);
+                               TALLOC_FREE(session);
+                               reply_nterror(req, NT_STATUS_NO_MEMORY);
+                               return;
+                       }
+
+                       /*
+                        * Place the application key into the session_info
+                        */
+                       data_blob_clear_free(&session_info->session_key);
+                       session_info->session_key =
+                               data_blob_dup_talloc(session_info,
+                                                    x->global->application_key);
+                       if (session_info->session_key.data == NULL) {
+                               data_blob_clear_free(&x->global->application_key);
+                               data_blob_free(&out_blob);
+                               TALLOC_FREE(session);
+                               reply_nterror(req, NT_STATUS_NO_MEMORY);
+                               return;
+                       }
+               }
+
                session->compat = talloc_zero(session, struct user_struct);
                if (session->compat == NULL) {
                        data_blob_free(&out_blob);
@@ -312,13 +364,16 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
                        return;
                }
 
-               if (srv_is_signing_negotiated(sconn) && action == 0) {
+               if (srv_is_signing_negotiated(sconn) &&
+                   action == 0 &&
+                   session->global->signing_key.length > 0)
+               {
                        /*
                         * Try and turn on server signing on the first non-guest
                         * sessionsetup.
                         */
                        srv_set_signing(sconn,
-                               session_info->session_key,
+                               session->global->signing_key,
                                data_blob_null);
                }