Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
1 deleted
6 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source4/auth/ntlmssp/ntlmssp.c

    r414 r745  
    2424#include "includes.h"
    2525#include "auth/ntlmssp/ntlmssp.h"
    26 #include "../librpc/gen_ndr/ntlmssp.h"
    2726#include "../libcli/auth/libcli_auth.h"
    2827#include "librpc/gen_ndr/ndr_dcerpc.h"
    29 #include "auth/credentials/credentials.h"
    3028#include "auth/gensec/gensec.h"
    3129#include "auth/gensec/gensec_proto.h"
    32 #include "param/param.h"
    3330
    3431/**
     
    5148                .role           = NTLMSSP_SERVER,
    5249                .command        = NTLMSSP_NEGOTIATE,
    53                 .sync_fn        = ntlmssp_server_negotiate,
     50                .sync_fn        = gensec_ntlmssp_server_negotiate,
    5451        },{
    5552                .role           = NTLMSSP_CLIENT,
     
    5956                .role           = NTLMSSP_SERVER,
    6057                .command        = NTLMSSP_AUTH,
    61                 .sync_fn        = ntlmssp_server_auth,
     58                .sync_fn        = gensec_ntlmssp_server_auth,
    6259        }
    6360};
    6461
    65 
    66 /**
    67  * Print out the NTLMSSP flags for debugging
    68  * @param neg_flags The flags from the packet
    69  */
    70 
    71 void debug_ntlmssp_flags(uint32_t neg_flags)
    72 {
    73         DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags));
    74        
    75         if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE)
    76                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_UNICODE\n"));
    77         if (neg_flags & NTLMSSP_NEGOTIATE_OEM)
    78                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_OEM\n"));
    79         if (neg_flags & NTLMSSP_REQUEST_TARGET)
    80                 DEBUGADD(4, ("  NTLMSSP_REQUEST_TARGET\n"));
    81         if (neg_flags & NTLMSSP_NEGOTIATE_SIGN)
    82                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_SIGN\n"));
    83         if (neg_flags & NTLMSSP_NEGOTIATE_SEAL)
    84                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_SEAL\n"));
    85         if (neg_flags & NTLMSSP_NEGOTIATE_DATAGRAM)
    86                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_DATAGRAM\n"));
    87         if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
    88                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_LM_KEY\n"));
    89         if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE)
    90                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_NETWARE\n"));
    91         if (neg_flags & NTLMSSP_NEGOTIATE_NTLM)
    92                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_NTLM\n"));
    93         if (neg_flags & NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED)
    94                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED\n"));
    95         if (neg_flags & NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED)
    96                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED\n"));
    97         if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL)
    98                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n"));
    99         if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)
    100                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n"));
    101         if (neg_flags & NTLMSSP_REQUEST_NON_NT_SESSION_KEY)
    102                 DEBUGADD(4, ("  NTLMSSP_REQUEST_NON_NT_SESSION_KEY\n"));
    103         if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2)
    104                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_NTLM2\n"));
    105         if (neg_flags & NTLMSSP_NEGOTIATE_TARGET_INFO)
    106                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_TARGET_INFO\n"));
    107         if (neg_flags & NTLMSSP_NEGOTIATE_128)
    108                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_128\n"));
    109         if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)
    110                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_KEY_EXCH\n"));
    111         if (neg_flags & NTLMSSP_NEGOTIATE_56)
    112                 DEBUGADD(4, ("  NTLMSSP_NEGOTIATE_56\n"));
    113 }
    11462
    11563static NTSTATUS gensec_ntlmssp_magic(struct gensec_security *gensec_security,
     
    12371}
    12472
    125 static NTSTATUS gensec_ntlmssp_update_find(struct gensec_ntlmssp_state *gensec_ntlmssp_state,
     73static NTSTATUS gensec_ntlmssp_update_find(struct ntlmssp_state *ntlmssp_state,
    12674                                           const DATA_BLOB input, uint32_t *idx)
    12775{
    128         struct gensec_security *gensec_security = gensec_ntlmssp_state->gensec_security;
     76        struct gensec_ntlmssp_context *gensec_ntlmssp =
     77                talloc_get_type_abort(ntlmssp_state->callback_private,
     78                                      struct gensec_ntlmssp_context);
     79        struct gensec_security *gensec_security = gensec_ntlmssp->gensec_security;
    12980        uint32_t ntlmssp_command;
    13081        uint32_t i;
    13182
    132         if (gensec_ntlmssp_state->expected_state == NTLMSSP_DONE) {
     83        if (ntlmssp_state->expected_state == NTLMSSP_DONE) {
    13384                /* We are strict here because other modules, which we
    13485                 * don't fully control (such as GSSAPI) are also
     
    14091
    14192        if (!input.length) {
    142                 switch (gensec_ntlmssp_state->role) {
     93                switch (ntlmssp_state->role) {
    14394                case NTLMSSP_CLIENT:
    14495                        ntlmssp_command = NTLMSSP_INITIAL;
     
    156107                }
    157108        } else {
    158                 if (!msrpc_parse(gensec_ntlmssp_state,
     109                if (!msrpc_parse(ntlmssp_state,
    159110                                 &input, "Cd",
    160111                                 "NTLMSSP",
     
    166117        }
    167118
    168         if (ntlmssp_command != gensec_ntlmssp_state->expected_state) {
    169                 DEBUG(2, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, gensec_ntlmssp_state->expected_state));
     119        if (ntlmssp_command != ntlmssp_state->expected_state) {
     120                DEBUG(2, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state));
    170121                return NT_STATUS_INVALID_PARAMETER;
    171122        }
    172123
    173124        for (i=0; i < ARRAY_SIZE(ntlmssp_callbacks); i++) {
    174                 if (ntlmssp_callbacks[i].role == gensec_ntlmssp_state->role &&
     125                if (ntlmssp_callbacks[i].role == ntlmssp_state->role &&
    175126                    ntlmssp_callbacks[i].command == ntlmssp_command) {
    176127                        *idx = i;
     
    180131
    181132        DEBUG(1, ("failed to find NTLMSSP callback for NTLMSSP mode %u, command %u\n",
    182                   gensec_ntlmssp_state->role, ntlmssp_command));
     133                  ntlmssp_state->role, ntlmssp_command));
    183134               
    184135        return NT_STATUS_INVALID_PARAMETER;
     
    200151                                      const DATA_BLOB input, DATA_BLOB *out)
    201152{
    202         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
     153        struct gensec_ntlmssp_context *gensec_ntlmssp =
     154                talloc_get_type_abort(gensec_security->private_data,
     155                                      struct gensec_ntlmssp_context);
     156        struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
    203157        NTSTATUS status;
    204158        uint32_t i;
     
    209163                /* if the caller doesn't want to manage/own the memory,
    210164                   we can put it on our context */
    211                 out_mem_ctx = gensec_ntlmssp_state;
    212         }
    213 
    214         status = gensec_ntlmssp_update_find(gensec_ntlmssp_state, input, &i);
     165                out_mem_ctx = ntlmssp_state;
     166        }
     167
     168        status = gensec_ntlmssp_update_find(ntlmssp_state, input, &i);
    215169        NT_STATUS_NOT_OK_RETURN(status);
    216170
     
    224178 * Return the NTLMSSP master session key
    225179 *
    226  * @param gensec_ntlmssp_state NTLMSSP State
     180 * @param ntlmssp_state NTLMSSP State
    227181 */
    228182
     
    230184                                    DATA_BLOB *session_key)
    231185{
    232         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
    233 
    234         if (gensec_ntlmssp_state->expected_state != NTLMSSP_DONE) {
     186        struct gensec_ntlmssp_context *gensec_ntlmssp =
     187                talloc_get_type_abort(gensec_security->private_data,
     188                                      struct gensec_ntlmssp_context);
     189        struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
     190
     191        if (ntlmssp_state->expected_state != NTLMSSP_DONE) {
    235192                return NT_STATUS_NO_USER_SESSION_KEY;
    236193        }
    237194
    238         if (!gensec_ntlmssp_state->session_key.data) {
     195        if (!ntlmssp_state->session_key.data) {
    239196                return NT_STATUS_NO_USER_SESSION_KEY;
    240197        }
    241         *session_key = gensec_ntlmssp_state->session_key;
     198        *session_key = ntlmssp_state->session_key;
    242199
    243200        return NT_STATUS_OK;
    244 }
    245 
    246 void ntlmssp_handle_neg_flags(struct gensec_ntlmssp_state *gensec_ntlmssp_state,
    247                               uint32_t neg_flags, bool allow_lm)
    248 {
    249         if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) {
    250                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
    251                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM;
    252                 gensec_ntlmssp_state->unicode = true;
    253         } else {
    254                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE;
    255                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
    256                 gensec_ntlmssp_state->unicode = false;
    257         }
    258 
    259         if ((neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && allow_lm && !gensec_ntlmssp_state->use_ntlmv2) {
    260                 /* other end forcing us to use LM */
    261                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
    262                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
    263         } else {
    264                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
    265         }
    266 
    267         if (!(neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) {
    268                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
    269         }
    270 
    271         if (!(neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
    272                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN;
    273         }
    274 
    275         if (!(neg_flags & NTLMSSP_NEGOTIATE_SEAL)) {
    276                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL;
    277         }
    278 
    279         if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) {
    280                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
    281         }
    282 
    283         if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) {
    284                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128;
    285         }
    286 
    287         if (!(neg_flags & NTLMSSP_NEGOTIATE_56)) {
    288                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_56;
    289         }
    290 
    291         if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) {
    292                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH;
    293         }
    294 
    295         /* Woop Woop - unknown flag for Windows compatibility...
    296            What does this really do ? JRA. */
    297         if (!(neg_flags & NTLMSSP_NEGOTIATE_VERSION)) {
    298                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_VERSION;
    299         }
    300 
    301         if ((neg_flags & NTLMSSP_REQUEST_TARGET)) {
    302                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET;
    303         }
    304        
    305 }
    306 
    307 /**
    308    Weaken NTLMSSP keys to cope with down-level clients and servers.
    309 
    310    We probably should have some parameters to control this, but as
    311    it only occours for LM_KEY connections, and this is controlled
    312    by the client lanman auth/lanman auth parameters, it isn't too bad.
    313 */
    314 
    315 DATA_BLOB ntlmssp_weakend_key(struct gensec_ntlmssp_state *gensec_ntlmssp_state,
    316                               TALLOC_CTX *mem_ctx)
    317 {
    318         DATA_BLOB weakened_key = data_blob_talloc(mem_ctx,
    319                                                   gensec_ntlmssp_state->session_key.data,
    320                                                   gensec_ntlmssp_state->session_key.length);
    321         /* Nothing to weaken.  We certainly don't want to 'extend' the length... */
    322         if (weakened_key.length < 16) {
    323                 /* perhaps there was no key? */
    324                 return weakened_key;
    325         }
    326 
    327         /* Key weakening not performed on the master key for NTLM2
    328            and does not occour for NTLM1.  Therefore we only need
    329            to do this for the LM_KEY. 
    330         */
    331         if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) {
    332                 /* LM key doesn't support 128 bit crypto, so this is
    333                  * the best we can do.  If you negotiate 128 bit, but
    334                  * not 56, you end up with 40 bit... */
    335                 if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) {
    336                         weakened_key.data[7] = 0xa0;
    337                         weakened_key.length = 8;
    338                 } else { /* forty bits */
    339                         weakened_key.data[5] = 0xe5;
    340                         weakened_key.data[6] = 0x38;
    341                         weakened_key.data[7] = 0xb0;
    342                         weakened_key.length = 8;
    343                 }
    344         }
    345         return weakened_key;
    346201}
    347202
     
    349204                                        uint32_t feature)
    350205{
    351         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
     206        struct gensec_ntlmssp_context *gensec_ntlmssp =
     207                talloc_get_type_abort(gensec_security->private_data,
     208                                      struct gensec_ntlmssp_context);
     209        struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
     210
    352211        if (feature & GENSEC_FEATURE_SIGN) {
    353                 if (!gensec_ntlmssp_state->session_key.length) {
     212                if (!ntlmssp_state->session_key.length) {
    354213                        return false;
    355214                }
    356                 if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) {
     215                if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) {
    357216                        return true;
    358217                }
    359218        }
    360219        if (feature & GENSEC_FEATURE_SEAL) {
    361                 if (!gensec_ntlmssp_state->session_key.length) {
     220                if (!ntlmssp_state->session_key.length) {
    362221                        return false;
    363222                }
    364                 if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) {
     223                if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) {
    365224                        return true;
    366225                }
    367226        }
    368227        if (feature & GENSEC_FEATURE_SESSION_KEY) {
    369                 if (gensec_ntlmssp_state->session_key.length) {
     228                if (ntlmssp_state->session_key.length) {
    370229                        return true;
    371230                }
     
    375234        }
    376235        if (feature & GENSEC_FEATURE_ASYNC_REPLIES) {
    377                 if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
     236                if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
    378237                        return true;
    379238                }
     
    384243NTSTATUS gensec_ntlmssp_start(struct gensec_security *gensec_security)
    385244{
    386         struct gensec_ntlmssp_state *gensec_ntlmssp_state;
    387        
    388         gensec_ntlmssp_state = talloc_zero(gensec_security, struct gensec_ntlmssp_state);
    389         if (!gensec_ntlmssp_state) {
     245        struct gensec_ntlmssp_context *gensec_ntlmssp;
     246        struct ntlmssp_state *ntlmssp_state;
     247
     248        gensec_ntlmssp = talloc_zero(gensec_security,
     249                                     struct gensec_ntlmssp_context);
     250        if (!gensec_ntlmssp) {
    390251                return NT_STATUS_NO_MEMORY;
    391252        }
    392253
    393         gensec_ntlmssp_state->gensec_security = gensec_security;
    394         gensec_ntlmssp_state->auth_context = NULL;
    395         gensec_ntlmssp_state->server_info = NULL;
    396 
    397         gensec_security->private_data = gensec_ntlmssp_state;
     254        gensec_ntlmssp->gensec_security = gensec_security;
     255
     256        ntlmssp_state = talloc_zero(gensec_ntlmssp,
     257                                    struct ntlmssp_state);
     258        if (!ntlmssp_state) {
     259                return NT_STATUS_NO_MEMORY;
     260        }
     261
     262        ntlmssp_state->callback_private = gensec_ntlmssp;
     263
     264        gensec_ntlmssp->ntlmssp_state = ntlmssp_state;
     265
     266        gensec_security->private_data = gensec_ntlmssp;
    398267        return NT_STATUS_OK;
    399268}
     
    406275static const struct gensec_security_ops gensec_ntlmssp_security_ops = {
    407276        .name           = "ntlmssp",
    408         .sasl_name      = "NTLM",
     277        .sasl_name      = GENSEC_SASL_NAME_NTLMSSP, /* "NTLM" */
    409278        .auth_type      = DCERPC_AUTH_TYPE_NTLMSSP,
    410279        .oid            = gensec_ntlmssp_oids,
  • trunk/server/source4/auth/ntlmssp/ntlmssp.h

    r414 r745  
    1 /* 
     1/*
    22   Unix SMB/CIFS implementation.
    33   SMB parameters and setup
     
    55   Copyright (C) Luke Kenneth Casson Leighton 1996-1997
    66   Copyright (C) Paul Ashton 1997
    7    
     7   Copyright (C) Andrew Bartlett 2010
     8
    89   This program is free software; you can redistribute it and/or modify
    910   it under the terms of the GNU General Public License as published by
    1011   the Free Software Foundation; either version 3 of the License, or
    1112   (at your option) any later version.
    12    
     13
    1314   This program is distributed in the hope that it will be useful,
    1415   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1516   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1617   GNU General Public License for more details.
    17    
     18
    1819   You should have received a copy of the GNU General Public License
    1920   along with this program.  If not, see <http://www.gnu.org/licenses/>.
    2021*/
    2122
    22 #include "librpc/gen_ndr/samr.h"
    2323#include "../librpc/gen_ndr/ntlmssp.h"
     24#include "../libcli/auth/ntlmssp.h"
    2425
    25 /* NTLMSSP mode */
    26 enum ntlmssp_role
    27 {
    28         NTLMSSP_SERVER,
    29         NTLMSSP_CLIENT
    30 };
    31 
    32 /* NTLMSSP message types */
    33 enum ntlmssp_message_type
    34 {
    35         NTLMSSP_INITIAL = 0 /* samba internal state */,
    36         NTLMSSP_NEGOTIATE = 1,
    37         NTLMSSP_CHALLENGE = 2,
    38         NTLMSSP_AUTH      = 3,
    39         NTLMSSP_UNKNOWN   = 4,
    40         NTLMSSP_DONE   = 5 /* samba final state */
    41 };
    42 
    43 struct gensec_ntlmssp_state
    44 {
     26struct gensec_ntlmssp_context {
    4527        struct gensec_security *gensec_security;
    46 
    47         enum ntlmssp_role role;
    48         enum samr_Role server_role;
    49         uint32_t expected_state;
    50 
    51         bool unicode;
    52         bool use_ntlmv2;
    53         bool use_nt_response;  /* Set to 'False' to debug what happens when the NT response is omited */
    54         bool allow_lm_key;     /* The LM_KEY code is not functional at this point, and it's not
    55                                   very secure anyway */
    56 
    57         bool server_multiple_authentications;  /* Set to 'True' to allow squid 2.5
    58                                                   style 'challenge caching' */
    59 
    60         char *user;
    61         const char *domain;
    62         const char *workstation;
    63         char *server_domain;
    64 
    65         DATA_BLOB internal_chal; /* Random challenge as supplied to the client for NTLM authentication */
    66 
    67         DATA_BLOB chal; /* Random challenge as input into the actual NTLM (or NTLM2) authentication */
    68         DATA_BLOB lm_resp;
    69         DATA_BLOB nt_resp;
    70         DATA_BLOB session_key;
    71        
    72         uint32_t neg_flags; /* the current state of negotiation with the NTLMSSP partner */
    73 
    74         /* internal variables used by KEY_EXCH (client-supplied user session key */
    75         DATA_BLOB encrypted_session_key;
    76        
    77         /**
    78          * Callback to get the 'challenge' used for NTLM authentication. 
    79          *
    80          * @param ntlmssp_state This structure
    81          * @return 8 bytes of challenge data, determined by the server to be the challenge for NTLM authentication
    82          *
    83          */
    84         const uint8_t *(*get_challenge)(const struct gensec_ntlmssp_state *);
    85 
    86         /**
    87          * Callback to find if the challenge used by NTLM authentication may be modified
    88          *
    89          * The NTLM2 authentication scheme modifies the effective challenge, but this is not compatiable with the
    90          * current 'security=server' implementation.. 
    91          *
    92          * @param ntlmssp_state This structure
    93          * @return Can the challenge be set to arbitary values?
    94          *
    95          */
    96         bool (*may_set_challenge)(const struct gensec_ntlmssp_state *);
    97 
    98         /**
    99          * Callback to set the 'challenge' used for NTLM authentication. 
    100          *
    101          * The callback may use the void *auth_context to store state information, but the same value is always available
    102          * from the DATA_BLOB chal on this structure.
    103          *
    104          * @param ntlmssp_state This structure
    105          * @param challenge 8 bytes of data, agreed by the client and server to be the effective challenge for NTLM2 authentication
    106          *
    107          */
    108         NTSTATUS (*set_challenge)(struct gensec_ntlmssp_state *, DATA_BLOB *challenge);
    109 
    110         /**
    111          * Callback to check the user's password. 
    112          *
    113          * The callback must reads the feilds of this structure for the information it needs on the user
    114          * @param ntlmssp_state This structure
    115          * @param nt_session_key If an NT session key is returned by the authentication process, return it here
    116          * @param lm_session_key If an LM session key is returned by the authentication process, return it here
    117          *
    118          */
    119         NTSTATUS (*check_password)(struct gensec_ntlmssp_state *,
    120                                    TALLOC_CTX *mem_ctx,
    121                                    DATA_BLOB *nt_session_key, DATA_BLOB *lm_session_key);
    122 
    123         const char *server_name;
    124 
    125         bool doing_ntlm2;
    126 
    127         union {
    128                 /* NTLM */
    129                 struct {
    130                         uint32_t seq_num;
    131                         struct arcfour_state *arcfour_state;
    132                 } ntlm;
    133 
    134                 /* NTLM2 */
    135                 struct {
    136                         uint32_t send_seq_num;
    137                         uint32_t recv_seq_num;
    138                         DATA_BLOB send_sign_key;
    139                         DATA_BLOB recv_sign_key;
    140                         struct arcfour_state *send_seal_arcfour_state;
    141                         struct arcfour_state *recv_seal_arcfour_state;
    142 
    143                         /* internal variables used by NTLM2 */
    144                         uint8_t session_nonce[16];
    145                 } ntlm2;
    146         } crypt;
    147 
     28        struct ntlmssp_state *ntlmssp_state;
    14829        struct auth_context *auth_context;
    149         struct auth_serversupplied_info *server_info;
     30        struct auth_user_info_dc *user_info_dc;
    15031};
    15132
     
    15334struct auth_session_info;
    15435
     36NTSTATUS gensec_ntlmssp_init(void);
     37
    15538#include "auth/ntlmssp/proto.h"
  • trunk/server/source4/auth/ntlmssp/ntlmssp_client.c

    r414 r745  
    2424#include "includes.h"
    2525#include "auth/ntlmssp/ntlmssp.h"
    26 #include "../librpc/gen_ndr/ntlmssp.h"
    2726#include "../lib/crypto/crypto.h"
    2827#include "../libcli/auth/libcli_auth.h"
     
    3029#include "auth/gensec/gensec.h"
    3130#include "param/param.h"
     31#include "libcli/auth/ntlmssp_private.h"
    3232
    3333/*********************************************************************
     
    4949                                DATA_BLOB in, DATA_BLOB *out)
    5050{
    51         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
    52         const char *domain = gensec_ntlmssp_state->domain;
     51        struct gensec_ntlmssp_context *gensec_ntlmssp =
     52                talloc_get_type_abort(gensec_security->private_data,
     53                                      struct gensec_ntlmssp_context);
     54        struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
     55        const char *domain = ntlmssp_state->domain;
    5356        const char *workstation = cli_credentials_get_workstation(gensec_security->credentials);
     57        NTSTATUS status;
    5458
    5559        /* These don't really matter in the initial packet, so don't panic if they are not set */
     
    6266        }
    6367
    64         if (gensec_ntlmssp_state->unicode) {
    65                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
     68        if (ntlmssp_state->unicode) {
     69                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE;
    6670        } else {
    67                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
     71                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM;
    6872        }
    6973       
    70         if (gensec_ntlmssp_state->use_ntlmv2) {
    71                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
     74        if (ntlmssp_state->use_ntlmv2) {
     75                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
    7276        }
    7377
    7478        /* generate the ntlmssp negotiate packet */
    75         msrpc_gen(out_mem_ctx,
     79        status = msrpc_gen(out_mem_ctx,
    7680                  out, "CddAA",
    7781                  "NTLMSSP",
    7882                  NTLMSSP_NEGOTIATE,
    79                   gensec_ntlmssp_state->neg_flags,
     83                  ntlmssp_state->neg_flags,
    8084                  domain,
    8185                  workstation);
    8286
    83         gensec_ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
     87        if (!NT_STATUS_IS_OK(status)) {
     88                return status;
     89        }
     90
     91        ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
    8492
    8593        return NT_STATUS_MORE_PROCESSING_REQUIRED;
     
    100108                                  const DATA_BLOB in, DATA_BLOB *out)
    101109{
    102         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
     110        struct gensec_ntlmssp_context *gensec_ntlmssp =
     111                talloc_get_type_abort(gensec_security->private_data,
     112                                      struct gensec_ntlmssp_context);
     113        struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
    103114        uint32_t chal_flags, ntlmssp_command, unkn1, unkn2;
    104115        DATA_BLOB server_domain_blob;
     
    140151        debug_ntlmssp_flags(chal_flags);
    141152
    142         ntlmssp_handle_neg_flags(gensec_ntlmssp_state, chal_flags, gensec_ntlmssp_state->allow_lm_key);
    143 
    144         if (gensec_ntlmssp_state->unicode) {
     153        ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, ntlmssp_state->allow_lm_key);
     154
     155        if (ntlmssp_state->unicode) {
    145156                if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) {
    146157                        chal_parse_string = "CdUdbddB";
     
    174185        }
    175186
    176         gensec_ntlmssp_state->server_domain = server_domain;
     187        if (chal_flags & NTLMSSP_TARGET_TYPE_SERVER) {
     188                ntlmssp_state->server.is_standalone = true;
     189        } else {
     190                ntlmssp_state->server.is_standalone = false;
     191        }
     192        /* TODO: parse struct_blob and fill in the rest */
     193        ntlmssp_state->server.netbios_name = "";
     194        ntlmssp_state->server.netbios_domain = server_domain;
     195        ntlmssp_state->server.dns_name = "";
     196        ntlmssp_state->server.dns_domain = "";
    177197
    178198        if (challenge_blob.length != 8) {
     
    184204                                                 &user, &domain);
    185205
    186         if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
     206        if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
    187207                flags |= CLI_CRED_NTLM2;
    188208        }
    189         if (gensec_ntlmssp_state->use_ntlmv2) {
     209        if (ntlmssp_state->use_ntlmv2) {
    190210                flags |= CLI_CRED_NTLMv2_AUTH;
    191211        }
    192         if (gensec_ntlmssp_state->use_nt_response) {
     212        if (ntlmssp_state->use_nt_response) {
    193213                flags |= CLI_CRED_NTLM_AUTH;
    194214        }
    195         if (lp_client_lanman_auth(gensec_security->settings->lp_ctx)) {
     215        if (lpcfg_client_lanman_auth(gensec_security->settings->lp_ctx)) {
    196216                flags |= CLI_CRED_LANMAN_AUTH;
    197217        }
     
    209229                /* LM Key is still possible, just silly.  Fortunetly
    210230                 * we require command line options to end up here */
    211                 /* gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; */
     231                /* ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; */
    212232        }
    213233
    214234        if (!(flags & CLI_CRED_NTLM2)) {
    215235                /* NTLM2 is incompatible... */
    216                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
     236                ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
    217237        }
    218238       
    219         if ((gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
    220             && lp_client_lanman_auth(gensec_security->settings->lp_ctx) && lm_session_key.length == 16) {
     239        if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
     240            && lpcfg_client_lanman_auth(gensec_security->settings->lp_ctx) && lm_session_key.length == 16) {
    221241                DATA_BLOB new_session_key = data_blob_talloc(mem_ctx, NULL, 16);
    222242                if (lm_response.length == 24) {
     
    235255        /* Key exchange encryptes a new client-generated session key with
    236256           the password-derived key */
    237         if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
     257        if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
    238258                /* Make up a new session key */
    239259                uint8_t client_session_key[16];
     
    241261
    242262                /* Encrypt the new session key with the old one */
    243                 encrypted_session_key = data_blob_talloc(gensec_ntlmssp_state,
     263                encrypted_session_key = data_blob_talloc(ntlmssp_state,
    244264                                                         client_session_key, sizeof(client_session_key));
    245265                dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length);
     
    252272
    253273        DEBUG(3, ("NTLMSSP: Set final flags:\n"));
    254         debug_ntlmssp_flags(gensec_ntlmssp_state->neg_flags);
     274        debug_ntlmssp_flags(ntlmssp_state->neg_flags);
    255275
    256276        /* this generates the actual auth packet */
    257         if (!msrpc_gen(mem_ctx,
     277        nt_status = msrpc_gen(mem_ctx,
    258278                       out, auth_gen_string,
    259279                       "NTLMSSP",
     
    265285                       cli_credentials_get_workstation(gensec_security->credentials),
    266286                       encrypted_session_key.data, encrypted_session_key.length,
    267                        gensec_ntlmssp_state->neg_flags)) {
     287                       ntlmssp_state->neg_flags);
     288        if (!NT_STATUS_IS_OK(nt_status)) {
    268289                talloc_free(mem_ctx);
    269                 return NT_STATUS_NO_MEMORY;
    270         }
    271 
    272         gensec_ntlmssp_state->session_key = session_key;
    273         talloc_steal(gensec_ntlmssp_state, session_key.data);
     290                return nt_status;
     291        }
     292
     293        ntlmssp_state->session_key = session_key;
     294        talloc_steal(ntlmssp_state, session_key.data);
    274295
    275296        talloc_steal(out_mem_ctx, out->data);
    276297
    277         gensec_ntlmssp_state->chal = challenge_blob;
    278         gensec_ntlmssp_state->lm_resp = lm_response;
    279         talloc_steal(gensec_ntlmssp_state->lm_resp.data, lm_response.data);
    280         gensec_ntlmssp_state->nt_resp = nt_response;
    281         talloc_steal(gensec_ntlmssp_state->nt_resp.data, nt_response.data);
    282 
    283         gensec_ntlmssp_state->expected_state = NTLMSSP_DONE;
     298        ntlmssp_state->chal = challenge_blob;
     299        ntlmssp_state->lm_resp = lm_response;
     300        talloc_steal(ntlmssp_state->lm_resp.data, lm_response.data);
     301        ntlmssp_state->nt_resp = nt_response;
     302        talloc_steal(ntlmssp_state->nt_resp.data, nt_response.data);
     303
     304        ntlmssp_state->expected_state = NTLMSSP_DONE;
    284305
    285306        if (gensec_security->want_features & (GENSEC_FEATURE_SIGN|GENSEC_FEATURE_SEAL)) {
    286                 nt_status = ntlmssp_sign_init(gensec_ntlmssp_state);
     307                nt_status = ntlmssp_sign_init(ntlmssp_state);
    287308                if (!NT_STATUS_IS_OK(nt_status)) {
    288309                        DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n",
     
    299320NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security)
    300321{
    301         struct gensec_ntlmssp_state *gensec_ntlmssp_state;
     322        struct gensec_ntlmssp_context *gensec_ntlmssp;
     323        struct ntlmssp_state *ntlmssp_state;
    302324        NTSTATUS nt_status;
    303325
     
    305327        NT_STATUS_NOT_OK_RETURN(nt_status);
    306328
    307         gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
    308 
    309         gensec_ntlmssp_state->role = NTLMSSP_CLIENT;
    310 
    311         gensec_ntlmssp_state->domain = lp_workgroup(gensec_security->settings->lp_ctx);
    312 
    313         gensec_ntlmssp_state->unicode = gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "unicode", true);
    314 
    315         gensec_ntlmssp_state->use_nt_response = gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "send_nt_reponse", true);
    316 
    317         gensec_ntlmssp_state->allow_lm_key = (lp_client_lanman_auth(gensec_security->settings->lp_ctx)
     329        gensec_ntlmssp = talloc_get_type_abort(gensec_security->private_data,
     330                                               struct gensec_ntlmssp_context);
     331        ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
     332
     333        ntlmssp_state->role = NTLMSSP_CLIENT;
     334
     335        ntlmssp_state->domain = lpcfg_workgroup(gensec_security->settings->lp_ctx);
     336
     337        ntlmssp_state->unicode = gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "unicode", true);
     338
     339        ntlmssp_state->use_nt_response = gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "send_nt_reponse", true);
     340
     341        ntlmssp_state->allow_lm_key = (lpcfg_client_lanman_auth(gensec_security->settings->lp_ctx)
    318342                                              && (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "allow_lm_key", false)
    319343                                                  || gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "lm_key", false)));
    320344
    321         gensec_ntlmssp_state->use_ntlmv2 = lp_client_ntlmv2_auth(gensec_security->settings->lp_ctx);
    322 
    323         gensec_ntlmssp_state->expected_state = NTLMSSP_INITIAL;
    324 
    325         gensec_ntlmssp_state->neg_flags =
     345        ntlmssp_state->use_ntlmv2 = lpcfg_client_ntlmv2_auth(gensec_security->settings->lp_ctx);
     346
     347        ntlmssp_state->expected_state = NTLMSSP_INITIAL;
     348
     349        ntlmssp_state->neg_flags =
    326350                NTLMSSP_NEGOTIATE_NTLM |
    327351                NTLMSSP_REQUEST_TARGET;
    328352
    329353        if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "128bit", true)) {
    330                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_128;               
     354                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_128;
    331355        }
    332356
    333357        if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "56bit", false)) {
    334                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;               
     358                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;
    335359        }
    336360
    337361        if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "lm_key", false)) {
    338                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
     362                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY;
    339363        }
    340364
    341365        if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "keyexchange", true)) {
    342                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;         
     366                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
    343367        }
    344368
    345369        if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "alwayssign", true)) {
    346                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;               
     370                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
    347371        }
    348372
    349373        if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "ntlm2", true)) {
    350                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;             
     374                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
    351375        } else {
    352376                /* apparently we can't do ntlmv2 if we don't do ntlm2 */
    353                 gensec_ntlmssp_state->use_ntlmv2 = false;
     377                ntlmssp_state->use_ntlmv2 = false;
    354378        }
    355379
     
    364388                 * sealing.  (It is actually pulled out and used directly)
    365389                 */
    366                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
     390                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
    367391        }
    368392        if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {
    369                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
     393                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
    370394        }
    371395        if (gensec_security->want_features & GENSEC_FEATURE_SEAL) {
    372                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
    373         }
    374 
    375         gensec_security->private_data = gensec_ntlmssp_state;
     396                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
     397                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
     398        }
    376399
    377400        return NT_STATUS_OK;
  • trunk/server/source4/auth/ntlmssp/ntlmssp_server.c

    r414 r745  
    2424#include "includes.h"
    2525#include "system/network.h"
     26#include "lib/tsocket/tsocket.h"
    2627#include "auth/ntlmssp/ntlmssp.h"
    27 #include "../librpc/gen_ndr/ntlmssp.h"
     28#include "../librpc/gen_ndr/ndr_ntlmssp.h"
     29#include "../libcli/auth/ntlmssp_ndr.h"
     30#include "../libcli/auth/ntlmssp_private.h"
    2831#include "../libcli/auth/libcli_auth.h"
    2932#include "../lib/crypto/crypto.h"
    3033#include "auth/gensec/gensec.h"
     34#include "auth/gensec/gensec_proto.h"
    3135#include "auth/auth.h"
    32 #include "auth/ntlm/auth_proto.h"
    3336#include "param/param.h"
    34 #include "auth/session_proto.h"
    35 
    36 /**
    37  * Set a username on an NTLMSSP context - ensures it is talloc()ed
    38  *
    39  */
    40 
    41 static NTSTATUS ntlmssp_set_username(struct gensec_ntlmssp_state *gensec_ntlmssp_state, const char *user)
    42 {
    43         if (!user) {
    44                 /* it should be at least "" */
    45                 DEBUG(1, ("NTLMSSP failed to set username - cannot accept NULL username\n"));
    46                 return NT_STATUS_INVALID_PARAMETER;
    47         }
    48         gensec_ntlmssp_state->user = talloc_strdup(gensec_ntlmssp_state, user);
    49         if (!gensec_ntlmssp_state->user) {
    50                 return NT_STATUS_NO_MEMORY;
    51         }
    52         return NT_STATUS_OK;
    53 }
    54 
    55 /**
    56  * Set a domain on an NTLMSSP context - ensures it is talloc()ed
    57  *
    58  */
    59 static NTSTATUS ntlmssp_set_domain(struct gensec_ntlmssp_state *gensec_ntlmssp_state, const char *domain)
    60 {
    61         gensec_ntlmssp_state->domain = talloc_strdup(gensec_ntlmssp_state, domain);
    62         if (!gensec_ntlmssp_state->domain) {
    63                 return NT_STATUS_NO_MEMORY;
    64         }
    65         return NT_STATUS_OK;
    66 }
    67 
    68 /**
    69  * Set a workstation on an NTLMSSP context - ensures it is talloc()ed
    70  *
    71  */
    72 static NTSTATUS ntlmssp_set_workstation(struct gensec_ntlmssp_state *gensec_ntlmssp_state, const char *workstation)
    73 {
    74         gensec_ntlmssp_state->workstation = talloc_strdup(gensec_ntlmssp_state, workstation);
    75         if (!gensec_ntlmssp_state->workstation) {
    76                 return NT_STATUS_NO_MEMORY;
    77         }
    78         return NT_STATUS_OK;
    79 }
    80 
    81 /**
    82  * Determine correct target name flags for reply, given server role
    83  * and negotiated flags
    84  *
    85  * @param gensec_ntlmssp_state NTLMSSP State
    86  * @param neg_flags The flags from the packet
    87  * @param chal_flags The flags to be set in the reply packet
    88  * @return The 'target name' string.
    89  */
    90 
    91 static const char *ntlmssp_target_name(struct gensec_ntlmssp_state *gensec_ntlmssp_state,
    92                                        uint32_t neg_flags, uint32_t *chal_flags)
    93 {
    94         if (neg_flags & NTLMSSP_REQUEST_TARGET) {
    95                 *chal_flags |= NTLMSSP_NEGOTIATE_TARGET_INFO;
    96                 *chal_flags |= NTLMSSP_REQUEST_TARGET;
    97                 if (gensec_ntlmssp_state->server_role == ROLE_STANDALONE) {
    98                         *chal_flags |= NTLMSSP_TARGET_TYPE_SERVER;
    99                         return gensec_ntlmssp_state->server_name;
    100                 } else {
    101                         *chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN;
    102                         return gensec_ntlmssp_state->domain;
    103                 };
    104         } else {
    105                 return "";
    106         }
    107 }
    108 
    109 
    110 
    111 /**
    112  * Next state function for the Negotiate packet
    113  *
     37
     38/**
     39 * Next state function for the Negotiate packet (GENSEC wrapper)
     40 *
    11441 * @param gensec_security GENSEC state
    11542 * @param out_mem_ctx Memory context for *out
    11643 * @param in The request, as a DATA_BLOB.  reply.data must be NULL
    11744 * @param out The reply, as an allocated DATA_BLOB, caller to free.
    118  * @return Errors or MORE_PROCESSING_REQUIRED if (normal) a reply is required.
    119  */
    120 
    121 NTSTATUS ntlmssp_server_negotiate(struct gensec_security *gensec_security,
    122                                   TALLOC_CTX *out_mem_ctx,
    123                                   const DATA_BLOB in, DATA_BLOB *out)
    124 {
    125         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
    126         DATA_BLOB struct_blob;
    127         uint32_t neg_flags = 0;
    128         uint32_t ntlmssp_command, chal_flags;
    129         const uint8_t *cryptkey;
    130         const char *target_name;
    131 
    132         /* parse the NTLMSSP packet */
    133 #if 0
    134         file_save("ntlmssp_negotiate.dat", request.data, request.length);
    135 #endif
    136 
    137         if (in.length) {
    138                 if ((in.length < 16) || !msrpc_parse(out_mem_ctx,
    139                                                          &in, "Cdd",
    140                                                          "NTLMSSP",
    141                                                          &ntlmssp_command,
    142                                                          &neg_flags)) {
    143                         DEBUG(1, ("ntlmssp_server_negotiate: failed to parse "
    144                                 "NTLMSSP Negotiate of length %u:\n",
    145                                 (unsigned int)in.length ));
    146                         dump_data(2, in.data, in.length);
    147                         return NT_STATUS_INVALID_PARAMETER;
    148                 }
    149                 debug_ntlmssp_flags(neg_flags);
    150         }
    151        
    152         ntlmssp_handle_neg_flags(gensec_ntlmssp_state, neg_flags, gensec_ntlmssp_state->allow_lm_key);
    153 
    154         /* Ask our caller what challenge they would like in the packet */
    155         cryptkey = gensec_ntlmssp_state->get_challenge(gensec_ntlmssp_state);
    156         if (!cryptkey) {
    157                 DEBUG(1, ("ntlmssp_server_negotiate: backend doesn't give a challenge\n"));
    158                 return NT_STATUS_INTERNAL_ERROR;
    159         }
    160 
    161         /* Check if we may set the challenge */
    162         if (!gensec_ntlmssp_state->may_set_challenge(gensec_ntlmssp_state)) {
    163                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
    164         }
    165 
    166         /* The flags we send back are not just the negotiated flags,
    167          * they are also 'what is in this packet'.  Therfore, we
    168          * operate on 'chal_flags' from here on
    169          */
    170 
    171         chal_flags = gensec_ntlmssp_state->neg_flags;
    172 
    173         /* get the right name to fill in as 'target' */
    174         target_name = ntlmssp_target_name(gensec_ntlmssp_state,
    175                                           neg_flags, &chal_flags);
    176         if (target_name == NULL)
     45 * @return Errors or MORE_PROCESSING_REQUIRED if (normal) a reply is required.
     46 */
     47
     48NTSTATUS gensec_ntlmssp_server_negotiate(struct gensec_security *gensec_security,
     49                                         TALLOC_CTX *out_mem_ctx,
     50                                         const DATA_BLOB request, DATA_BLOB *reply)
     51{
     52        struct gensec_ntlmssp_context *gensec_ntlmssp =
     53                talloc_get_type_abort(gensec_security->private_data,
     54                                      struct gensec_ntlmssp_context);
     55        struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
     56        return ntlmssp_server_negotiate(ntlmssp_state, out_mem_ctx, request, reply);
     57}
     58
     59/**
     60 * Next state function for the Authenticate packet (GENSEC wrapper)
     61 *
     62 * @param gensec_security GENSEC state
     63 * @param out_mem_ctx Memory context for *out
     64 * @param in The request, as a DATA_BLOB.  reply.data must be NULL
     65 * @param out The reply, as an allocated DATA_BLOB, caller to free.
     66 * @return Errors or NT_STATUS_OK if authentication sucessful
     67 */
     68
     69NTSTATUS gensec_ntlmssp_server_auth(struct gensec_security *gensec_security,
     70                                    TALLOC_CTX *out_mem_ctx,
     71                                    const DATA_BLOB in, DATA_BLOB *out)
     72{
     73        struct gensec_ntlmssp_context *gensec_ntlmssp =
     74                talloc_get_type_abort(gensec_security->private_data,
     75                                      struct gensec_ntlmssp_context);
     76        struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
     77        return ntlmssp_server_auth(ntlmssp_state, out_mem_ctx, in, out);
     78}
     79
     80/**
     81 * Return the challenge as determined by the authentication subsystem
     82 * @return an 8 byte random challenge
     83 */
     84
     85static NTSTATUS auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_state,
     86                                           uint8_t chal[8])
     87{
     88        struct gensec_ntlmssp_context *gensec_ntlmssp =
     89                talloc_get_type_abort(ntlmssp_state->callback_private,
     90                                      struct gensec_ntlmssp_context);
     91        struct auth_context *auth_context = gensec_ntlmssp->auth_context;
     92        NTSTATUS status;
     93
     94        status = auth_context->get_challenge(auth_context, chal);
     95        if (!NT_STATUS_IS_OK(status)) {
     96                DEBUG(1, ("auth_ntlmssp_get_challenge: failed to get challenge: %s\n",
     97                        nt_errstr(status)));
     98                return status;
     99        }
     100
     101        return NT_STATUS_OK;
     102}
     103
     104/**
     105 * Some authentication methods 'fix' the challenge, so we may not be able to set it
     106 *
     107 * @return If the effective challenge used by the auth subsystem may be modified
     108 */
     109static bool auth_ntlmssp_may_set_challenge(const struct ntlmssp_state *ntlmssp_state)
     110{
     111        struct gensec_ntlmssp_context *gensec_ntlmssp =
     112                talloc_get_type_abort(ntlmssp_state->callback_private,
     113                                      struct gensec_ntlmssp_context);
     114        struct auth_context *auth_context = gensec_ntlmssp->auth_context;
     115
     116        return auth_context->challenge_may_be_modified(auth_context);
     117}
     118
     119/**
     120 * NTLM2 authentication modifies the effective challenge,
     121 * @param challenge The new challenge value
     122 */
     123static NTSTATUS auth_ntlmssp_set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge)
     124{
     125        struct gensec_ntlmssp_context *gensec_ntlmssp =
     126                talloc_get_type_abort(ntlmssp_state->callback_private,
     127                                      struct gensec_ntlmssp_context);
     128        struct auth_context *auth_context = gensec_ntlmssp->auth_context;
     129        NTSTATUS nt_status;
     130        const uint8_t *chal;
     131
     132        if (challenge->length != 8) {
    177133                return NT_STATUS_INVALID_PARAMETER;
    178 
    179         gensec_ntlmssp_state->chal = data_blob_talloc(gensec_ntlmssp_state, cryptkey, 8);
    180         gensec_ntlmssp_state->internal_chal = data_blob_talloc(gensec_ntlmssp_state, cryptkey, 8);
    181 
    182         /* This creates the 'blob' of names that appears at the end of the packet */
    183         if (chal_flags & NTLMSSP_NEGOTIATE_TARGET_INFO) {
     134        }
     135
     136        chal = challenge->data;
     137
     138        nt_status = auth_context->set_challenge(auth_context,
     139                                                chal,
     140                                                "NTLMSSP callback (NTLM2)");
     141
     142        return nt_status;
     143}
     144
     145/**
     146 * Check the password on an NTLMSSP login. 
     147 *
     148 * Return the session keys used on the connection.
     149 */
     150
     151static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state,
     152                                            TALLOC_CTX *mem_ctx,
     153                                            DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)
     154{
     155        struct gensec_ntlmssp_context *gensec_ntlmssp =
     156                talloc_get_type_abort(ntlmssp_state->callback_private,
     157                                      struct gensec_ntlmssp_context);
     158        struct auth_context *auth_context = gensec_ntlmssp->auth_context;
     159        NTSTATUS nt_status;
     160        struct auth_usersupplied_info *user_info;
     161
     162        user_info = talloc_zero(ntlmssp_state, struct auth_usersupplied_info);
     163        if (!user_info) {
     164                return NT_STATUS_NO_MEMORY;
     165        }
     166
     167        user_info->logon_parameters = MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
     168        user_info->flags = 0;
     169        user_info->mapped_state = false;
     170        user_info->client.account_name = ntlmssp_state->user;
     171        user_info->client.domain_name = ntlmssp_state->domain;
     172        user_info->workstation_name = ntlmssp_state->client.netbios_name;
     173        user_info->remote_host = gensec_get_remote_address(gensec_ntlmssp->gensec_security);
     174
     175        user_info->password_state = AUTH_PASSWORD_RESPONSE;
     176        user_info->password.response.lanman = ntlmssp_state->lm_resp;
     177        user_info->password.response.lanman.data = talloc_steal(user_info, ntlmssp_state->lm_resp.data);
     178        user_info->password.response.nt = ntlmssp_state->nt_resp;
     179        user_info->password.response.nt.data = talloc_steal(user_info, ntlmssp_state->nt_resp.data);
     180
     181        nt_status = auth_context->check_password(auth_context,
     182                                                 gensec_ntlmssp,
     183                                                 user_info,
     184                                                 &gensec_ntlmssp->user_info_dc);
     185        talloc_free(user_info);
     186        NT_STATUS_NOT_OK_RETURN(nt_status);
     187
     188        if (gensec_ntlmssp->user_info_dc->user_session_key.length) {
     189                DEBUG(10, ("Got NT session key of length %u\n",
     190                           (unsigned)gensec_ntlmssp->user_info_dc->user_session_key.length));
     191                *user_session_key = gensec_ntlmssp->user_info_dc->user_session_key;
     192                talloc_steal(mem_ctx, user_session_key->data);
     193                gensec_ntlmssp->user_info_dc->user_session_key = data_blob_null;
     194        }
     195        if (gensec_ntlmssp->user_info_dc->lm_session_key.length) {
     196                DEBUG(10, ("Got LM session key of length %u\n",
     197                           (unsigned)gensec_ntlmssp->user_info_dc->lm_session_key.length));
     198                *lm_session_key = gensec_ntlmssp->user_info_dc->lm_session_key;
     199                talloc_steal(mem_ctx, lm_session_key->data);
     200                gensec_ntlmssp->user_info_dc->lm_session_key = data_blob_null;
     201        }
     202        return nt_status;
     203}
     204
     205/**
     206 * Return the credentials of a logged on user, including session keys
     207 * etc.
     208 *
     209 * Only valid after a successful authentication
     210 *
     211 * May only be called once per authentication.
     212 *
     213 */
     214
     215NTSTATUS gensec_ntlmssp_session_info(struct gensec_security *gensec_security,
     216                                     struct auth_session_info **session_info)
     217{
     218        NTSTATUS nt_status;
     219        struct gensec_ntlmssp_context *gensec_ntlmssp =
     220                talloc_get_type_abort(gensec_security->private_data,
     221                                      struct gensec_ntlmssp_context);
     222        struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
     223
     224        nt_status = gensec_generate_session_info(ntlmssp_state,
     225                                                 gensec_security,
     226                                                 gensec_ntlmssp->user_info_dc,
     227                                                 session_info);
     228        NT_STATUS_NOT_OK_RETURN(nt_status);
     229
     230        (*session_info)->session_key = data_blob_talloc(*session_info,
     231                                                        ntlmssp_state->session_key.data,
     232                                                        ntlmssp_state->session_key.length);
     233
     234        return NT_STATUS_OK;
     235}
     236
     237/**
     238 * Start NTLMSSP on the server side
     239 *
     240 */
     241NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security)
     242{
     243        NTSTATUS nt_status;
     244        struct ntlmssp_state *ntlmssp_state;
     245        struct gensec_ntlmssp_context *gensec_ntlmssp;
     246
     247        nt_status = gensec_ntlmssp_start(gensec_security);
     248        NT_STATUS_NOT_OK_RETURN(nt_status);
     249
     250        gensec_ntlmssp = talloc_get_type_abort(gensec_security->private_data,
     251                                               struct gensec_ntlmssp_context);
     252        ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
     253
     254        ntlmssp_state->role = NTLMSSP_SERVER;
     255
     256        ntlmssp_state->expected_state = NTLMSSP_NEGOTIATE;
     257
     258        ntlmssp_state->allow_lm_key = (lpcfg_lanman_auth(gensec_security->settings->lp_ctx)
     259                                          && gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "allow_lm_key", false));
     260
     261        ntlmssp_state->neg_flags =
     262                NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_VERSION;
     263
     264        ntlmssp_state->lm_resp = data_blob(NULL, 0);
     265        ntlmssp_state->nt_resp = data_blob(NULL, 0);
     266
     267        if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "128bit", true)) {
     268                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_128;
     269        }
     270
     271        if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "56bit", true)) {
     272                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;
     273        }
     274
     275        if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "keyexchange", true)) {
     276                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;
     277        }
     278
     279        if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "alwayssign", true)) {
     280                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
     281        }
     282
     283        if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "ntlm2", true)) {
     284                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;
     285        }
     286
     287        if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {
     288                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
     289        }
     290        if (gensec_security->want_features & GENSEC_FEATURE_SEAL) {
     291                ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
     292        }
     293
     294        gensec_ntlmssp->auth_context = gensec_security->auth_context;
     295
     296        ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge;
     297        ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge;
     298        ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge;
     299        ntlmssp_state->check_password = auth_ntlmssp_check_password;
     300        if (lpcfg_server_role(gensec_security->settings->lp_ctx) == ROLE_STANDALONE) {
     301                ntlmssp_state->server.is_standalone = true;
     302        } else {
     303                ntlmssp_state->server.is_standalone = false;
     304        }
     305
     306        ntlmssp_state->server.netbios_name = lpcfg_netbios_name(gensec_security->settings->lp_ctx);
     307
     308        ntlmssp_state->server.netbios_domain = lpcfg_workgroup(gensec_security->settings->lp_ctx);
     309
     310        {
    184311                char dnsdomname[MAXHOSTNAMELEN], dnsname[MAXHOSTNAMELEN];
    185                 const char *target_name_dns = "";
    186312
    187313                /* Find out the DNS domain name */
    188314                dnsdomname[0] = '\0';
    189                 safe_strcpy(dnsdomname, lp_realm(gensec_security->settings->lp_ctx), sizeof(dnsdomname) - 1);
    190                 strlower_m(dnsdomname);
     315                safe_strcpy(dnsdomname, lpcfg_dnsdomain(gensec_security->settings->lp_ctx), sizeof(dnsdomname) - 1);
    191316
    192317                /* Find out the DNS host name */
    193                 safe_strcpy(dnsname, gensec_ntlmssp_state->server_name, sizeof(dnsname) - 1);
     318                safe_strcpy(dnsname, ntlmssp_state->server.netbios_name, sizeof(dnsname) - 1);
    194319                if (dnsdomname[0] != '\0') {
    195320                        safe_strcat(dnsname, ".", sizeof(dnsname) - 1);
     
    198323                strlower_m(dnsname);
    199324
    200                 if (chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN) {
    201                         target_name_dns = dnsdomname;
    202                 } else if (chal_flags |= NTLMSSP_TARGET_TYPE_SERVER) {
    203                         target_name_dns = dnsname;
    204                 }
    205 
    206                 msrpc_gen(out_mem_ctx,
    207                           &struct_blob, "aaaaa",
    208                           MsvAvNbDomainName, target_name,
    209                           MsvAvNbComputerName, gensec_ntlmssp_state->server_name,
    210                           MsvAvDnsDomainName, dnsdomname,
    211                           MsvAvDnsComputerName, dnsname,
    212                           MsvAvEOL, "");
    213         } else {
    214                 struct_blob = data_blob(NULL, 0);
    215         }
    216 
    217         {
    218                 /* Marshal the packet in the right format, be it unicode or ASCII */
    219                 const char *gen_string;
    220                 if (gensec_ntlmssp_state->unicode) {
    221                         gen_string = "CdUdbddB";
    222                 } else {
    223                         gen_string = "CdAdbddB";
    224                 }
    225                
    226                 msrpc_gen(out_mem_ctx,
    227                           out, gen_string,
    228                           "NTLMSSP",
    229                           NTLMSSP_CHALLENGE,
    230                           target_name,
    231                           chal_flags,
    232                           cryptkey, 8,
    233                           0, 0,
    234                           struct_blob.data, struct_blob.length);
    235         }
    236                
    237         gensec_ntlmssp_state->expected_state = NTLMSSP_AUTH;
    238 
    239         return NT_STATUS_MORE_PROCESSING_REQUIRED;
    240 }
    241 
    242 /**
    243  * Next state function for the Authenticate packet
    244  *
    245  * @param gensec_ntlmssp_state NTLMSSP State
    246  * @param request The request, as a DATA_BLOB
    247  * @return Errors or NT_STATUS_OK.
    248  */
    249 
    250 static NTSTATUS ntlmssp_server_preauth(struct gensec_ntlmssp_state *gensec_ntlmssp_state,
    251                                        const DATA_BLOB request)
    252 {
    253         uint32_t ntlmssp_command, auth_flags;
    254         NTSTATUS nt_status;
    255 
    256         uint8_t session_nonce_hash[16];
    257 
    258         const char *parse_string;
    259         char *domain = NULL;
    260         char *user = NULL;
    261         char *workstation = NULL;
    262 
    263 #if 0
    264         file_save("ntlmssp_auth.dat", request.data, request.length);
    265 #endif
    266 
    267         if (gensec_ntlmssp_state->unicode) {
    268                 parse_string = "CdBBUUUBd";
    269         } else {
    270                 parse_string = "CdBBAAABd";
    271         }
    272 
    273         /* zero these out */
    274         data_blob_free(&gensec_ntlmssp_state->lm_resp);
    275         data_blob_free(&gensec_ntlmssp_state->nt_resp);
    276         data_blob_free(&gensec_ntlmssp_state->encrypted_session_key);
    277 
    278         gensec_ntlmssp_state->user = NULL;
    279         gensec_ntlmssp_state->domain = NULL;
    280         gensec_ntlmssp_state->workstation = NULL;
    281 
    282         /* now the NTLMSSP encoded auth hashes */
    283         if (!msrpc_parse(gensec_ntlmssp_state,
    284                          &request, parse_string,
    285                          "NTLMSSP",
    286                          &ntlmssp_command,
    287                          &gensec_ntlmssp_state->lm_resp,
    288                          &gensec_ntlmssp_state->nt_resp,
    289                          &domain,
    290                          &user,
    291                          &workstation,
    292                          &gensec_ntlmssp_state->encrypted_session_key,
    293                          &auth_flags)) {
    294                 DEBUG(10, ("ntlmssp_server_auth: failed to parse NTLMSSP (nonfatal):\n"));
    295                 dump_data(10, request.data, request.length);
    296 
    297                 /* zero this out */
    298                 data_blob_free(&gensec_ntlmssp_state->encrypted_session_key);
    299                 auth_flags = 0;
    300                
    301                 /* Try again with a shorter string (Win9X truncates this packet) */
    302                 if (gensec_ntlmssp_state->unicode) {
    303                         parse_string = "CdBBUUU";
    304                 } else {
    305                         parse_string = "CdBBAAA";
    306                 }
    307 
    308                 /* now the NTLMSSP encoded auth hashes */
    309                 if (!msrpc_parse(gensec_ntlmssp_state,
    310                                  &request, parse_string,
    311                                  "NTLMSSP",
    312                                  &ntlmssp_command,
    313                                  &gensec_ntlmssp_state->lm_resp,
    314                                  &gensec_ntlmssp_state->nt_resp,
    315                                  &domain,
    316                                  &user,
    317                                  &workstation)) {
    318                         DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n"));
    319                         dump_data(2, request.data, request.length);
    320 
    321                         return NT_STATUS_INVALID_PARAMETER;
    322                 }
    323         }
    324 
    325         if (auth_flags)
    326                 ntlmssp_handle_neg_flags(gensec_ntlmssp_state, auth_flags, gensec_ntlmssp_state->allow_lm_key);
    327 
    328         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(gensec_ntlmssp_state, domain))) {
    329                 /* zero this out */
    330                 data_blob_free(&gensec_ntlmssp_state->encrypted_session_key);
    331                 return nt_status;
    332         }
    333 
    334         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(gensec_ntlmssp_state, user))) {
    335                 /* zero this out */
    336                 data_blob_free(&gensec_ntlmssp_state->encrypted_session_key);
    337                 return nt_status;
    338         }
    339 
    340         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_workstation(gensec_ntlmssp_state, workstation))) {
    341                 /* zero this out */
    342                 data_blob_free(&gensec_ntlmssp_state->encrypted_session_key);
    343                 return nt_status;
    344         }
    345 
    346         DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n",
    347                  gensec_ntlmssp_state->user, gensec_ntlmssp_state->domain, gensec_ntlmssp_state->workstation, (unsigned long)gensec_ntlmssp_state->lm_resp.length, (unsigned long)gensec_ntlmssp_state->nt_resp.length));
    348 
    349 #if 0
    350         file_save("nthash1.dat",  &gensec_ntlmssp_state->nt_resp.data,  &gensec_ntlmssp_state->nt_resp.length);
    351         file_save("lmhash1.dat",  &gensec_ntlmssp_state->lm_resp.data,  &gensec_ntlmssp_state->lm_resp.length);
    352 #endif
    353 
    354         /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a
    355            client challenge
    356        
    357            However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful.
    358         */
    359         if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
    360                 if (gensec_ntlmssp_state->nt_resp.length == 24 && gensec_ntlmssp_state->lm_resp.length == 24) {
    361                         struct MD5Context md5_session_nonce_ctx;
    362                         SMB_ASSERT(gensec_ntlmssp_state->internal_chal.data
    363                                    && gensec_ntlmssp_state->internal_chal.length == 8);
    364                        
    365                         gensec_ntlmssp_state->doing_ntlm2 = true;
    366 
    367                         memcpy(gensec_ntlmssp_state->crypt.ntlm2.session_nonce, gensec_ntlmssp_state->internal_chal.data, 8);
    368                         memcpy(&gensec_ntlmssp_state->crypt.ntlm2.session_nonce[8], gensec_ntlmssp_state->lm_resp.data, 8);
    369                        
    370                         MD5Init(&md5_session_nonce_ctx);
    371                         MD5Update(&md5_session_nonce_ctx, gensec_ntlmssp_state->crypt.ntlm2.session_nonce, 16);
    372                         MD5Final(session_nonce_hash, &md5_session_nonce_ctx);
    373                        
    374                         gensec_ntlmssp_state->chal = data_blob_talloc(gensec_ntlmssp_state,
    375                                                                session_nonce_hash, 8);
    376 
    377                         /* LM response is no longer useful, zero it out */
    378                         data_blob_free(&gensec_ntlmssp_state->lm_resp);
    379 
    380                         /* We changed the effective challenge - set it */
    381                         if (!NT_STATUS_IS_OK(nt_status =
    382                                              gensec_ntlmssp_state->set_challenge(gensec_ntlmssp_state,
    383                                                                                  &gensec_ntlmssp_state->chal))) {
    384                                 /* zero this out */
    385                                 data_blob_free(&gensec_ntlmssp_state->encrypted_session_key);
    386                                 return nt_status;
    387                         }
    388 
    389                         /* LM Key is incompatible... */
    390                         gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
    391                 }
    392         }
     325                ntlmssp_state->server.dns_name = talloc_strdup(ntlmssp_state,
     326                                                                      dnsname);
     327                NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.dns_name);
     328
     329                ntlmssp_state->server.dns_domain = talloc_strdup(ntlmssp_state,
     330                                                                        dnsdomname);
     331                NT_STATUS_HAVE_NO_MEMORY(ntlmssp_state->server.dns_domain);
     332        }
     333
    393334        return NT_STATUS_OK;
    394335}
    395336
    396 /**
    397  * Next state function for the Authenticate packet
    398  * (after authentication - figures out the session keys etc)
    399  *
    400  * @param gensec_ntlmssp_state NTLMSSP State
    401  * @return Errors or NT_STATUS_OK.
    402  */
    403 
    404 static NTSTATUS ntlmssp_server_postauth(struct gensec_security *gensec_security,
    405                                         DATA_BLOB *user_session_key,
    406                                         DATA_BLOB *lm_session_key)
    407 {
    408         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
    409         NTSTATUS nt_status;
    410         DATA_BLOB session_key = data_blob(NULL, 0);
    411 
    412         if (user_session_key)
    413                 dump_data_pw("USER session key:\n", user_session_key->data, user_session_key->length);
    414 
    415         if (lm_session_key)
    416                 dump_data_pw("LM first-8:\n", lm_session_key->data, lm_session_key->length);
    417 
    418         /* Handle the different session key derivation for NTLM2 */
    419         if (gensec_ntlmssp_state->doing_ntlm2) {
    420                 if (user_session_key && user_session_key->data && user_session_key->length == 16) {
    421                         session_key = data_blob_talloc(gensec_ntlmssp_state, NULL, 16);
    422                         hmac_md5(user_session_key->data, gensec_ntlmssp_state->crypt.ntlm2.session_nonce,
    423                                  sizeof(gensec_ntlmssp_state->crypt.ntlm2.session_nonce), session_key.data);
    424                         DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n"));
    425                         dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length);
    426                        
    427                 } else {
    428                         DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n"));
    429                         session_key = data_blob(NULL, 0);
    430                 }
    431         } else if ((gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY)
    432                 /* Ensure we can never get here on NTLMv2 */
    433                 && (gensec_ntlmssp_state->nt_resp.length == 0 || gensec_ntlmssp_state->nt_resp.length == 24)) {
    434 
    435                 if (lm_session_key && lm_session_key->data && lm_session_key->length >= 8) {
    436                         if (gensec_ntlmssp_state->lm_resp.data && gensec_ntlmssp_state->lm_resp.length == 24) {
    437                                 session_key = data_blob_talloc(gensec_ntlmssp_state, NULL, 16);
    438                                 SMBsesskeygen_lm_sess_key(lm_session_key->data, gensec_ntlmssp_state->lm_resp.data,
    439                                                           session_key.data);
    440                                 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
    441                                 dump_data_pw("LM session key:\n", session_key.data, session_key.length);
    442                         } else {
    443                                
    444                                 /* When there is no LM response, just use zeros */
    445                                 static const uint8_t zeros[24];
    446                                 session_key = data_blob_talloc(gensec_ntlmssp_state, NULL, 16);
    447                                 SMBsesskeygen_lm_sess_key(zeros, zeros,
    448                                                           session_key.data);
    449                                 DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
    450                                 dump_data_pw("LM session key:\n", session_key.data, session_key.length);
    451                         }
    452                 } else {
    453                         /* LM Key not selected */
    454                         gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
    455 
    456                         DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n"));
    457                         session_key = data_blob(NULL, 0);
    458                 }
    459 
    460         } else if (user_session_key && user_session_key->data) {
    461                 session_key = data_blob_talloc(gensec_ntlmssp_state, user_session_key->data, user_session_key->length);
    462                 DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n"));
    463                 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
    464 
    465                 /* LM Key not selected */
    466                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
    467 
    468         } else if (lm_session_key && lm_session_key->data) {
    469                 /* Very weird to have LM key, but no user session key, but anyway.. */
    470                 session_key = data_blob_talloc(gensec_ntlmssp_state, lm_session_key->data, lm_session_key->length);
    471                 DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n"));
    472                 dump_data_pw("unmodified session key:\n", session_key.data, session_key.length);
    473 
    474                 /* LM Key not selected */
    475                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
    476 
    477         } else {
    478                 DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n"));
    479                 session_key = data_blob(NULL, 0);
    480 
    481                 /* LM Key not selected */
    482                 gensec_ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY;
    483         }
    484 
    485         /* With KEY_EXCH, the client supplies the proposed session key,
    486            but encrypts it with the long-term key */
    487         if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
    488                 if (!gensec_ntlmssp_state->encrypted_session_key.data
    489                     || gensec_ntlmssp_state->encrypted_session_key.length != 16) {
    490                         data_blob_free(&gensec_ntlmssp_state->encrypted_session_key);
    491                         DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n",
    492                                   (unsigned)gensec_ntlmssp_state->encrypted_session_key.length));
    493                         return NT_STATUS_INVALID_PARAMETER;
    494                 } else if (!session_key.data || session_key.length != 16) {
    495                         DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n",
    496                                   (unsigned)session_key.length));
    497                         gensec_ntlmssp_state->session_key = session_key;
    498                 } else {
    499                         dump_data_pw("KEY_EXCH session key (enc):\n",
    500                                      gensec_ntlmssp_state->encrypted_session_key.data,
    501                                      gensec_ntlmssp_state->encrypted_session_key.length);
    502                         arcfour_crypt(gensec_ntlmssp_state->encrypted_session_key.data,
    503                                       session_key.data,
    504                                       gensec_ntlmssp_state->encrypted_session_key.length);
    505                         gensec_ntlmssp_state->session_key = data_blob_talloc(gensec_ntlmssp_state,
    506                                                                       gensec_ntlmssp_state->encrypted_session_key.data,
    507                                                                       gensec_ntlmssp_state->encrypted_session_key.length);
    508                         dump_data_pw("KEY_EXCH session key:\n", gensec_ntlmssp_state->encrypted_session_key.data,
    509                                      gensec_ntlmssp_state->encrypted_session_key.length);
    510                         talloc_free(session_key.data);
    511                 }
    512         } else {
    513                 gensec_ntlmssp_state->session_key = session_key;
    514         }
    515 
    516         if ((gensec_security->want_features & GENSEC_FEATURE_SIGN)
    517             || (gensec_security->want_features & GENSEC_FEATURE_SEAL)) {
    518                 nt_status = ntlmssp_sign_init(gensec_ntlmssp_state);
    519         } else {
    520                 nt_status = NT_STATUS_OK;
    521         }
    522 
    523         data_blob_free(&gensec_ntlmssp_state->encrypted_session_key);
    524        
    525         /* allow arbitarily many authentications, but watch that this will cause a
    526            memory leak, until the gensec_ntlmssp_state is shutdown
    527         */
    528 
    529         if (gensec_ntlmssp_state->server_multiple_authentications) {
    530                 gensec_ntlmssp_state->expected_state = NTLMSSP_AUTH;
    531         } else {
    532                 gensec_ntlmssp_state->expected_state = NTLMSSP_DONE;
    533         }
    534 
    535         return nt_status;
    536 }
    537 
    538 
    539 /**
    540  * Next state function for the Authenticate packet
    541  *
    542  * @param gensec_security GENSEC state
    543  * @param out_mem_ctx Memory context for *out
    544  * @param in The request, as a DATA_BLOB.  reply.data must be NULL
    545  * @param out The reply, as an allocated DATA_BLOB, caller to free.
    546  * @return Errors or NT_STATUS_OK if authentication sucessful
    547  */
    548 
    549 NTSTATUS ntlmssp_server_auth(struct gensec_security *gensec_security,
    550                              TALLOC_CTX *out_mem_ctx,
    551                              const DATA_BLOB in, DATA_BLOB *out)
    552 {       
    553         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
    554         DATA_BLOB user_session_key = data_blob(NULL, 0);
    555         DATA_BLOB lm_session_key = data_blob(NULL, 0);
    556         NTSTATUS nt_status;
    557 
    558         TALLOC_CTX *mem_ctx = talloc_new(out_mem_ctx);
    559         if (!mem_ctx) {
    560                 return NT_STATUS_NO_MEMORY;
    561         }
    562 
    563         /* zero the outbound NTLMSSP packet */
    564         *out = data_blob_talloc(out_mem_ctx, NULL, 0);
    565 
    566         if (!NT_STATUS_IS_OK(nt_status = ntlmssp_server_preauth(gensec_ntlmssp_state, in))) {
    567                 talloc_free(mem_ctx);
    568                 return nt_status;
    569         }
    570 
    571         /*
    572          * Note we don't check here for NTLMv2 auth settings. If NTLMv2 auth
    573          * is required (by "ntlm auth = no" and "lm auth = no" being set in the
    574          * smb.conf file) and no NTLMv2 response was sent then the password check
    575          * will fail here. JRA.
    576          */
    577 
    578         /* Finally, actually ask if the password is OK */
    579 
    580         if (!NT_STATUS_IS_OK(nt_status = gensec_ntlmssp_state->check_password(gensec_ntlmssp_state, mem_ctx,
    581                                                                               &user_session_key, &lm_session_key))) {
    582                 talloc_free(mem_ctx);
    583                 return nt_status;
    584         }
    585        
    586         if (gensec_security->want_features
    587             & (GENSEC_FEATURE_SIGN|GENSEC_FEATURE_SEAL|GENSEC_FEATURE_SESSION_KEY)) {
    588                 nt_status = ntlmssp_server_postauth(gensec_security, &user_session_key, &lm_session_key);
    589                 talloc_free(mem_ctx);
    590                 return nt_status;
    591         } else {
    592                 gensec_ntlmssp_state->session_key = data_blob(NULL, 0);
    593                 talloc_free(mem_ctx);
    594                 return NT_STATUS_OK;
    595         }
    596 }
    597 
    598 /**
    599  * Return the challenge as determined by the authentication subsystem
    600  * @return an 8 byte random challenge
    601  */
    602 
    603 static const uint8_t *auth_ntlmssp_get_challenge(const struct gensec_ntlmssp_state *gensec_ntlmssp_state)
    604 {
    605         NTSTATUS status;
    606         const uint8_t *chal;
    607 
    608         status = gensec_ntlmssp_state->auth_context->get_challenge(gensec_ntlmssp_state->auth_context, &chal);
    609         if (!NT_STATUS_IS_OK(status)) {
    610                 DEBUG(1, ("auth_ntlmssp_get_challenge: failed to get challenge: %s\n",
    611                         nt_errstr(status)));
    612                 return NULL;
    613         }
    614 
    615         return chal;
    616 }
    617 
    618 /**
    619  * Some authentication methods 'fix' the challenge, so we may not be able to set it
    620  *
    621  * @return If the effective challenge used by the auth subsystem may be modified
    622  */
    623 static bool auth_ntlmssp_may_set_challenge(const struct gensec_ntlmssp_state *gensec_ntlmssp_state)
    624 {
    625         return gensec_ntlmssp_state->auth_context->challenge_may_be_modified(gensec_ntlmssp_state->auth_context);
    626 }
    627 
    628 /**
    629  * NTLM2 authentication modifies the effective challenge,
    630  * @param challenge The new challenge value
    631  */
    632 static NTSTATUS auth_ntlmssp_set_challenge(struct gensec_ntlmssp_state *gensec_ntlmssp_state, DATA_BLOB *challenge)
    633 {
    634         NTSTATUS nt_status;
    635         struct auth_context *auth_context = gensec_ntlmssp_state->auth_context;
    636         const uint8_t *chal;
    637 
    638         if (challenge->length != 8) {
    639                 return NT_STATUS_INVALID_PARAMETER;
    640         }
    641 
    642         chal = challenge->data;
    643 
    644         nt_status = gensec_ntlmssp_state->auth_context->set_challenge(auth_context,
    645                                                                       chal,
    646                                                                       "NTLMSSP callback (NTLM2)");
    647 
    648         return nt_status;
    649 }
    650 
    651 /**
    652  * Check the password on an NTLMSSP login. 
    653  *
    654  * Return the session keys used on the connection.
    655  */
    656 
    657 static NTSTATUS auth_ntlmssp_check_password(struct gensec_ntlmssp_state *gensec_ntlmssp_state,
    658                                             TALLOC_CTX *mem_ctx,
    659                                             DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)
    660 {
    661         NTSTATUS nt_status;
    662         struct auth_usersupplied_info *user_info = talloc(mem_ctx, struct auth_usersupplied_info);
    663         if (!user_info) {
    664                 return NT_STATUS_NO_MEMORY;
    665         }
    666 
    667         user_info->logon_parameters = MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT;
    668         user_info->flags = 0;
    669         user_info->mapped_state = false;
    670         user_info->client.account_name = gensec_ntlmssp_state->user;
    671         user_info->client.domain_name = gensec_ntlmssp_state->domain;
    672         user_info->workstation_name = gensec_ntlmssp_state->workstation;
    673         user_info->remote_host = gensec_get_peer_addr(gensec_ntlmssp_state->gensec_security);
    674 
    675         user_info->password_state = AUTH_PASSWORD_RESPONSE;
    676         user_info->password.response.lanman = gensec_ntlmssp_state->lm_resp;
    677         user_info->password.response.lanman.data = talloc_steal(user_info, gensec_ntlmssp_state->lm_resp.data);
    678         user_info->password.response.nt = gensec_ntlmssp_state->nt_resp;
    679         user_info->password.response.nt.data = talloc_steal(user_info, gensec_ntlmssp_state->nt_resp.data);
    680 
    681         nt_status = gensec_ntlmssp_state->auth_context->check_password(gensec_ntlmssp_state->auth_context,
    682                                                                        mem_ctx,
    683                                                                        user_info,
    684                                                                        &gensec_ntlmssp_state->server_info);
    685         talloc_free(user_info);
    686         NT_STATUS_NOT_OK_RETURN(nt_status);
    687 
    688         talloc_steal(gensec_ntlmssp_state, gensec_ntlmssp_state->server_info);
    689 
    690         if (gensec_ntlmssp_state->server_info->user_session_key.length) {
    691                 DEBUG(10, ("Got NT session key of length %u\n",
    692                            (unsigned)gensec_ntlmssp_state->server_info->user_session_key.length));
    693                 if (!talloc_reference(mem_ctx, gensec_ntlmssp_state->server_info->user_session_key.data)) {
    694                         return NT_STATUS_NO_MEMORY;
    695                 }
    696 
    697                 *user_session_key = gensec_ntlmssp_state->server_info->user_session_key;
    698         }
    699         if (gensec_ntlmssp_state->server_info->lm_session_key.length) {
    700                 DEBUG(10, ("Got LM session key of length %u\n",
    701                            (unsigned)gensec_ntlmssp_state->server_info->lm_session_key.length));
    702                 if (!talloc_reference(mem_ctx, gensec_ntlmssp_state->server_info->lm_session_key.data)) {
    703                         return NT_STATUS_NO_MEMORY;
    704                 }
    705 
    706                 *lm_session_key = gensec_ntlmssp_state->server_info->lm_session_key;
    707         }
    708         return nt_status;
    709 }
    710 
    711 /**
    712  * Return the credentials of a logged on user, including session keys
    713  * etc.
    714  *
    715  * Only valid after a successful authentication
    716  *
    717  * May only be called once per authentication.
    718  *
    719  */
    720 
    721 NTSTATUS gensec_ntlmssp_session_info(struct gensec_security *gensec_security,
    722                                      struct auth_session_info **session_info)
    723 {
    724         NTSTATUS nt_status;
    725         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
    726 
    727         nt_status = auth_generate_session_info(gensec_ntlmssp_state, gensec_security->event_ctx, gensec_security->settings->lp_ctx, gensec_ntlmssp_state->server_info, session_info);
    728         NT_STATUS_NOT_OK_RETURN(nt_status);
    729 
    730         (*session_info)->session_key = data_blob_talloc(*session_info,
    731                                                         gensec_ntlmssp_state->session_key.data,
    732                                                         gensec_ntlmssp_state->session_key.length);
    733 
    734         return NT_STATUS_OK;
    735 }
    736 
    737 /**
    738  * Start NTLMSSP on the server side
    739  *
    740  */
    741 NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security)
    742 {
    743         NTSTATUS nt_status;
    744         struct gensec_ntlmssp_state *gensec_ntlmssp_state;
    745 
    746         nt_status = gensec_ntlmssp_start(gensec_security);
    747         NT_STATUS_NOT_OK_RETURN(nt_status);
    748 
    749         gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
    750 
    751         gensec_ntlmssp_state->role = NTLMSSP_SERVER;
    752 
    753         gensec_ntlmssp_state->workstation = NULL;
    754         gensec_ntlmssp_state->server_name = lp_netbios_name(gensec_security->settings->lp_ctx);
    755 
    756         gensec_ntlmssp_state->domain = lp_workgroup(gensec_security->settings->lp_ctx);
    757 
    758         gensec_ntlmssp_state->expected_state = NTLMSSP_NEGOTIATE;
    759 
    760         gensec_ntlmssp_state->allow_lm_key = (lp_lanman_auth(gensec_security->settings->lp_ctx)
    761                                           && gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "allow_lm_key", false));
    762 
    763         gensec_ntlmssp_state->server_multiple_authentications = false;
    764        
    765         gensec_ntlmssp_state->neg_flags =
    766                 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_VERSION;
    767 
    768         gensec_ntlmssp_state->lm_resp = data_blob(NULL, 0);
    769         gensec_ntlmssp_state->nt_resp = data_blob(NULL, 0);
    770         gensec_ntlmssp_state->encrypted_session_key = data_blob(NULL, 0);
    771 
    772         if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "128bit", true)) {
    773                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_128;               
    774         }
    775 
    776         if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "56bit", true)) {
    777                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56;               
    778         }
    779 
    780         if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "keyexchange", true)) {
    781                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH;         
    782         }
    783 
    784         if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "alwayssign", true)) {
    785                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;               
    786         }
    787 
    788         if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "ntlm2", true)) {
    789                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2;             
    790         }
    791 
    792         if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {
    793                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
    794         }
    795         if (gensec_security->want_features & GENSEC_FEATURE_SEAL) {
    796                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
    797         }
    798 
    799         gensec_ntlmssp_state->auth_context = gensec_security->auth_context;
    800 
    801         gensec_ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge;
    802         gensec_ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge;
    803         gensec_ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge;
    804         gensec_ntlmssp_state->check_password = auth_ntlmssp_check_password;
    805         gensec_ntlmssp_state->server_role = lp_server_role(gensec_security->settings->lp_ctx);
    806 
    807         return NT_STATUS_OK;
    808 }
    809 
  • trunk/server/source4/auth/ntlmssp/ntlmssp_sign.c

    r414 r745  
    1 /* 
     1/*
    22 *  Unix SMB/CIFS implementation.
    33 *  Version 3.0
     
    55 *  Copyright (C) Luke Kenneth Casson Leighton 1996-2001
    66 *  Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003-2005
    7  * 
     7 *
    88 *  This program is free software; you can redistribute it and/or modify
    99 *  it under the terms of the GNU General Public License as published by
    1010 *  the Free Software Foundation; either version 3 of the License, or
    1111 *  (at your option) any later version.
    12  * 
     12 *
    1313 *  This program is distributed in the hope that it will be useful,
    1414 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
    1515 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1616 *  GNU General Public License for more details.
    17  * 
     17 *
    1818 *  You should have received a copy of the GNU General Public License
    1919 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
     
    2222#include "includes.h"
    2323#include "auth/ntlmssp/ntlmssp.h"
    24 #include "../librpc/gen_ndr/ntlmssp.h"
    25 #include "../libcli/auth/libcli_auth.h"
    26 #include "../lib/crypto/crypto.h"
    2724#include "auth/gensec/gensec.h"
     25#include "../libcli/auth/ntlmssp_private.h"
    2826
    29 #define CLI_SIGN "session key to client-to-server signing key magic constant"
    30 #define CLI_SEAL "session key to client-to-server sealing key magic constant"
    31 #define SRV_SIGN "session key to server-to-client signing key magic constant"
    32 #define SRV_SEAL "session key to server-to-client sealing key magic constant"
    33 
    34 /**
    35  * Some notes on the NTLM2 code:
    36  *
    37  * NTLM2 is a AEAD system.  This means that the data encrypted is not
    38  * all the data that is signed.  In DCE-RPC case, the headers of the
    39  * DCE-RPC packets are also signed.  This prevents some of the
    40  * fun-and-games one might have by changing them.
    41  *
    42  */
    43 
    44 static void calc_ntlmv2_key(TALLOC_CTX *mem_ctx,
    45                             DATA_BLOB *subkey,
    46                             DATA_BLOB session_key,
    47                             const char *constant)
    48 {
    49         struct MD5Context ctx3;
    50         *subkey = data_blob_talloc(mem_ctx, NULL, 16);
    51         MD5Init(&ctx3);
    52         MD5Update(&ctx3, session_key.data, session_key.length);
    53         MD5Update(&ctx3, (const uint8_t *)constant, strlen(constant)+1);
    54         MD5Final(subkey->data, &ctx3);
    55 }
    56 
    57 enum ntlmssp_direction {
    58         NTLMSSP_SEND,
    59         NTLMSSP_RECEIVE
    60 };
    61 
    62 static NTSTATUS ntlmssp_make_packet_signature(struct gensec_ntlmssp_state *gensec_ntlmssp_state,
    63                                               TALLOC_CTX *sig_mem_ctx,
    64                                               const uint8_t *data, size_t length,
    65                                               const uint8_t *whole_pdu, size_t pdu_length,
    66                                               enum ntlmssp_direction direction,
    67                                               DATA_BLOB *sig, bool encrypt_sig)
    68 {
    69         if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
    70 
    71                 HMACMD5Context ctx;
    72                 uint8_t digest[16];
    73                 uint8_t seq_num[4];
    74 
    75                 *sig = data_blob_talloc(sig_mem_ctx, NULL, NTLMSSP_SIG_SIZE);
    76                 if (!sig->data) {
    77                         return NT_STATUS_NO_MEMORY;
    78                 }
    79                        
    80                 switch (direction) {
    81                 case NTLMSSP_SEND:
    82                         SIVAL(seq_num, 0, gensec_ntlmssp_state->crypt.ntlm2.send_seq_num);
    83                         gensec_ntlmssp_state->crypt.ntlm2.send_seq_num++;
    84                         hmac_md5_init_limK_to_64(gensec_ntlmssp_state->crypt.ntlm2.send_sign_key.data,
    85                                                  gensec_ntlmssp_state->crypt.ntlm2.send_sign_key.length, &ctx);
    86                         break;
    87                 case NTLMSSP_RECEIVE:
    88                         SIVAL(seq_num, 0, gensec_ntlmssp_state->crypt.ntlm2.recv_seq_num);
    89                         gensec_ntlmssp_state->crypt.ntlm2.recv_seq_num++;
    90                         hmac_md5_init_limK_to_64(gensec_ntlmssp_state->crypt.ntlm2.recv_sign_key.data,
    91                                                  gensec_ntlmssp_state->crypt.ntlm2.recv_sign_key.length, &ctx);
    92                         break;
    93                 }
    94                 hmac_md5_update(seq_num, sizeof(seq_num), &ctx);
    95                 hmac_md5_update(whole_pdu, pdu_length, &ctx);
    96                 hmac_md5_final(digest, &ctx);
    97 
    98                 if (encrypt_sig && gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
    99                         switch (direction) {
    100                         case NTLMSSP_SEND:
    101                                 arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state, digest, 8);
    102                                 break;
    103                         case NTLMSSP_RECEIVE:
    104                                 arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm2.recv_seal_arcfour_state, digest, 8);
    105                                 break;
    106                         }
    107                 }
    108 
    109                 SIVAL(sig->data, 0, NTLMSSP_SIGN_VERSION);
    110                 memcpy(sig->data + 4, digest, 8);
    111                 memcpy(sig->data + 12, seq_num, 4);
    112 
    113                 DEBUG(10, ("NTLM2: created signature over %llu bytes of input:\n", (unsigned long long)pdu_length));
    114                 dump_data(11, sig->data, sig->length);
    115                        
    116         } else {
    117                 uint32_t crc;
    118                 crc = crc32_calc_buffer(data, length);
    119                 if (!msrpc_gen(sig_mem_ctx,
    120                                sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, gensec_ntlmssp_state->crypt.ntlm.seq_num)) {
    121                         return NT_STATUS_NO_MEMORY;
    122                 }
    123                 gensec_ntlmssp_state->crypt.ntlm.seq_num++;
    124 
    125                 arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm.arcfour_state, sig->data+4, sig->length-4);
    126 
    127                 DEBUG(10, ("NTLM1: created signature over %llu bytes of input:\n", (unsigned long long)length));
    128                 dump_data(11, sig->data, sig->length);
    129         }
    130         return NT_STATUS_OK;
    131 }
    132 
    133 /* TODO: make this non-public */
    134 NTSTATUS gensec_ntlmssp_sign_packet(struct gensec_security *gensec_security,
    135                                     TALLOC_CTX *sig_mem_ctx,
    136                                     const uint8_t *data, size_t length,
    137                                     const uint8_t *whole_pdu, size_t pdu_length,
     27NTSTATUS gensec_ntlmssp_sign_packet(struct gensec_security *gensec_security,
     28                                    TALLOC_CTX *sig_mem_ctx,
     29                                    const uint8_t *data, size_t length,
     30                                    const uint8_t *whole_pdu, size_t pdu_length,
    13831                                    DATA_BLOB *sig)
    13932{
    140         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
    141 
    142         return ntlmssp_make_packet_signature(gensec_ntlmssp_state, sig_mem_ctx,
    143                                              data, length,
    144                                              whole_pdu, pdu_length,
    145                                              NTLMSSP_SEND, sig, true);
    146 }
    147 
    148 /**
    149  * Check the signature of an incoming packet
    150  *
    151  */
    152 
    153 NTSTATUS gensec_ntlmssp_check_packet(struct gensec_security *gensec_security,
    154                                      TALLOC_CTX *sig_mem_ctx,
    155                                      const uint8_t *data, size_t length,
    156                                      const uint8_t *whole_pdu, size_t pdu_length,
    157                                      const DATA_BLOB *sig)
    158 {
    159         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
    160 
    161         DATA_BLOB local_sig;
     33        struct gensec_ntlmssp_context *gensec_ntlmssp =
     34                talloc_get_type_abort(gensec_security->private_data,
     35                                      struct gensec_ntlmssp_context);
    16236        NTSTATUS nt_status;
    16337
    164         if (!gensec_ntlmssp_state->session_key.length) {
    165                 DEBUG(3, ("NO session key, cannot check packet signature\n"));
    166                 return NT_STATUS_NO_USER_SESSION_KEY;
    167         }
    168 
    169         nt_status = ntlmssp_make_packet_signature(gensec_ntlmssp_state, sig_mem_ctx,
    170                                                   data, length,
    171                                                   whole_pdu, pdu_length,
    172                                                   NTLMSSP_RECEIVE, &local_sig, true);
    173        
    174         if (!NT_STATUS_IS_OK(nt_status)) {
    175                 DEBUG(0, ("NTLMSSP packet check failed with %s\n", nt_errstr(nt_status)));
    176                 return nt_status;
    177         }
    178 
    179         if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
    180                 if (local_sig.length != sig->length ||
    181                     memcmp(local_sig.data,
    182                            sig->data, sig->length) != 0) {
    183                         DEBUG(5, ("BAD SIG NTLM2: wanted signature over %llu bytes of input:\n", (unsigned long long)pdu_length));
    184                         dump_data(5, local_sig.data, local_sig.length);
    185                        
    186                         DEBUG(5, ("BAD SIG: got signature over %llu bytes of input:\n", (unsigned long long)pdu_length));
    187                         dump_data(5, sig->data, sig->length);
    188                        
    189                         DEBUG(1, ("NTLMSSP NTLM2 packet check failed due to invalid signature on %llu bytes of input!\n", (unsigned long long)pdu_length));
    190                         return NT_STATUS_ACCESS_DENIED;
    191                 }
    192         } else {
    193                 if (local_sig.length != sig->length ||
    194                     memcmp(local_sig.data + 8,
    195                            sig->data + 8, sig->length - 8) != 0) {
    196                         DEBUG(5, ("BAD SIG NTLM1: wanted signature of %llu bytes of input:\n", (unsigned long long)length));
    197                         dump_data(5, local_sig.data, local_sig.length);
    198                        
    199                         DEBUG(5, ("BAD SIG: got signature of %llu bytes of input:\n", (unsigned long long)length));
    200                         dump_data(5, sig->data, sig->length);
    201                        
    202                         DEBUG(1, ("NTLMSSP NTLM1 packet check failed due to invalid signature on %llu bytes of input:\n", (unsigned long long)length));
    203                         return NT_STATUS_ACCESS_DENIED;
    204                 }
    205         }
    206         dump_data_pw("checked ntlmssp signature\n", sig->data, sig->length);
    207 
    208         return NT_STATUS_OK;
    209 }
    210 
    211 
    212 /**
    213  * Seal data with the NTLMSSP algorithm
    214  *
    215  */
    216 
    217 NTSTATUS gensec_ntlmssp_seal_packet(struct gensec_security *gensec_security,
    218                                     TALLOC_CTX *sig_mem_ctx,
    219                                     uint8_t *data, size_t length,
    220                                     const uint8_t *whole_pdu, size_t pdu_length,
    221                                     DATA_BLOB *sig)
    222 {
    223         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
    224         NTSTATUS nt_status;
    225         if (!gensec_ntlmssp_state->session_key.length) {
    226                 DEBUG(3, ("NO session key, cannot seal packet\n"));
    227                 return NT_STATUS_NO_USER_SESSION_KEY;
    228         }
    229 
    230         DEBUG(10,("ntlmssp_seal_data: seal\n"));
    231         dump_data_pw("ntlmssp clear data\n", data, length);
    232         if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
    233                 /* The order of these two operations matters - we must first seal the packet,
    234                    then seal the sequence number - this is becouse the send_seal_hash is not
    235                    constant, but is is rather updated with each iteration */
    236                 nt_status = ntlmssp_make_packet_signature(gensec_ntlmssp_state, sig_mem_ctx,
    237                                                           data, length,
    238                                                           whole_pdu, pdu_length,
    239                                                           NTLMSSP_SEND, sig, false);
    240                 arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state, data, length);
    241                 if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) {
    242                         arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state, sig->data+4, 8);
    243                 }
    244         } else {
    245                 uint32_t crc;
    246                 crc = crc32_calc_buffer(data, length);
    247                 if (!msrpc_gen(sig_mem_ctx,
    248                                sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, gensec_ntlmssp_state->crypt.ntlm.seq_num)) {
    249                         return NT_STATUS_NO_MEMORY;
    250                 }
    251 
    252                 /* The order of these two operations matters - we must
    253                    first seal the packet, then seal the sequence
    254                    number - this is becouse the ntlmssp_hash is not
    255                    constant, but is is rather updated with each
    256                    iteration */
    257 
    258                 arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm.arcfour_state, data, length);
    259                 arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm.arcfour_state, sig->data+4, sig->length-4);
    260                 /* increment counter on send */
    261                 gensec_ntlmssp_state->crypt.ntlm.seq_num++;
    262                 nt_status = NT_STATUS_OK;
    263         }
    264         dump_data_pw("ntlmssp signature\n", sig->data, sig->length);
    265         dump_data_pw("ntlmssp sealed data\n", data, length);
    266 
     38        nt_status = ntlmssp_sign_packet(gensec_ntlmssp->ntlmssp_state,
     39                                        sig_mem_ctx,
     40                                        data, length,
     41                                        whole_pdu, pdu_length,
     42                                        sig);
    26743
    26844        return nt_status;
    26945}
    27046
    271 /**
    272  * Unseal data with the NTLMSSP algorithm
    273  *
    274  */
     47NTSTATUS gensec_ntlmssp_check_packet(struct gensec_security *gensec_security,
     48                                     TALLOC_CTX *sig_mem_ctx,
     49                                     const uint8_t *data, size_t length,
     50                                     const uint8_t *whole_pdu, size_t pdu_length,
     51                                     const DATA_BLOB *sig)
     52{
     53        struct gensec_ntlmssp_context *gensec_ntlmssp =
     54                talloc_get_type_abort(gensec_security->private_data,
     55                                      struct gensec_ntlmssp_context);
     56        NTSTATUS nt_status;
     57
     58        nt_status = ntlmssp_check_packet(gensec_ntlmssp->ntlmssp_state,
     59                                         data, length,
     60                                         whole_pdu, pdu_length,
     61                                         sig);
     62
     63        return nt_status;
     64}
     65
     66NTSTATUS gensec_ntlmssp_seal_packet(struct gensec_security *gensec_security,
     67                                    TALLOC_CTX *sig_mem_ctx,
     68                                    uint8_t *data, size_t length,
     69                                    const uint8_t *whole_pdu, size_t pdu_length,
     70                                    DATA_BLOB *sig)
     71{
     72        struct gensec_ntlmssp_context *gensec_ntlmssp =
     73                talloc_get_type_abort(gensec_security->private_data,
     74                                      struct gensec_ntlmssp_context);
     75        NTSTATUS nt_status;
     76
     77        nt_status = ntlmssp_seal_packet(gensec_ntlmssp->ntlmssp_state,
     78                                        sig_mem_ctx,
     79                                        data, length,
     80                                        whole_pdu, pdu_length,
     81                                        sig);
     82
     83        return nt_status;
     84}
    27585
    27686/*
    27787  wrappers for the ntlmssp_*() functions
    27888*/
    279 NTSTATUS gensec_ntlmssp_unseal_packet(struct gensec_security *gensec_security, 
    280                                       TALLOC_CTX *sig_mem_ctx, 
    281                                       uint8_t *data, size_t length, 
    282                                       const uint8_t *whole_pdu, size_t pdu_length, 
     89NTSTATUS gensec_ntlmssp_unseal_packet(struct gensec_security *gensec_security,
     90                                      TALLOC_CTX *sig_mem_ctx,
     91                                      uint8_t *data, size_t length,
     92                                      const uint8_t *whole_pdu, size_t pdu_length,
    28393                                      const DATA_BLOB *sig)
    28494{
    285         struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data;
    286         if (!gensec_ntlmssp_state->session_key.length) {
    287                 DEBUG(3, ("NO session key, cannot unseal packet\n"));
    288                 return NT_STATUS_NO_USER_SESSION_KEY;
    289         }
     95        struct gensec_ntlmssp_context *gensec_ntlmssp =
     96                talloc_get_type_abort(gensec_security->private_data,
     97                                      struct gensec_ntlmssp_context);
     98        NTSTATUS nt_status;
    29099
    291         dump_data_pw("ntlmssp sealed data\n", data, length);
    292         if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
    293                 arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm2.recv_seal_arcfour_state, data, length);
    294         } else {
    295                 arcfour_crypt_sbox(gensec_ntlmssp_state->crypt.ntlm.arcfour_state, data, length);
    296         }
    297         dump_data_pw("ntlmssp clear data\n", data, length);
    298         return gensec_ntlmssp_check_packet(gensec_security, sig_mem_ctx, data, length, whole_pdu, pdu_length, sig);
    299 }
     100        nt_status = ntlmssp_unseal_packet(gensec_ntlmssp->ntlmssp_state,
     101                                          data, length,
     102                                          whole_pdu, pdu_length,
     103                                          sig);
    300104
    301 /**
    302    Initialise the state for NTLMSSP signing.
    303 */
    304 /* TODO: make this non-public */
    305 NTSTATUS ntlmssp_sign_init(struct gensec_ntlmssp_state *gensec_ntlmssp_state)
    306 {
    307         TALLOC_CTX *mem_ctx = talloc_new(gensec_ntlmssp_state);
    308 
    309         if (!mem_ctx) {
    310                 return NT_STATUS_NO_MEMORY;
    311         }
    312 
    313         DEBUG(3, ("NTLMSSP Sign/Seal - Initialising with flags:\n"));
    314         debug_ntlmssp_flags(gensec_ntlmssp_state->neg_flags);
    315 
    316         if (gensec_ntlmssp_state->session_key.length < 8) {
    317                 talloc_free(mem_ctx);
    318                 DEBUG(3, ("NO session key, cannot intialise signing\n"));
    319                 return NT_STATUS_NO_USER_SESSION_KEY;
    320         }
    321 
    322         if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2)
    323         {
    324                 DATA_BLOB weak_session_key = gensec_ntlmssp_state->session_key;
    325                 const char *send_sign_const;
    326                 const char *send_seal_const;
    327                 const char *recv_sign_const;
    328                 const char *recv_seal_const;
    329 
    330                 DATA_BLOB send_seal_key;
    331                 DATA_BLOB recv_seal_key;
    332 
    333                 switch (gensec_ntlmssp_state->role) {
    334                 case NTLMSSP_CLIENT:
    335                         send_sign_const = CLI_SIGN;
    336                         send_seal_const = CLI_SEAL;
    337                         recv_sign_const = SRV_SIGN;
    338                         recv_seal_const = SRV_SEAL;
    339                         break;
    340                 case NTLMSSP_SERVER:
    341                         send_sign_const = SRV_SIGN;
    342                         send_seal_const = SRV_SEAL;
    343                         recv_sign_const = CLI_SIGN;
    344                         recv_seal_const = CLI_SEAL;
    345                         break;
    346                 default:
    347                         talloc_free(mem_ctx);
    348                         return NT_STATUS_INTERNAL_ERROR;
    349                 }
    350                
    351                 gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state = talloc(gensec_ntlmssp_state, struct arcfour_state);
    352                 NT_STATUS_HAVE_NO_MEMORY(gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state);
    353                 gensec_ntlmssp_state->crypt.ntlm2.recv_seal_arcfour_state = talloc(gensec_ntlmssp_state, struct arcfour_state);
    354                 NT_STATUS_HAVE_NO_MEMORY(gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state);
    355 
    356                 /**
    357                    Weaken NTLMSSP keys to cope with down-level
    358                    clients, servers and export restrictions.
    359                    
    360                    We probably should have some parameters to control
    361                    this, once we get NTLM2 working.
    362                 */
    363 
    364                 /* Key weakening was not performed on the master key
    365                  * for NTLM2 (in ntlmssp_weaken_keys()), but must be
    366                  * done on the encryption subkeys only.  That is why
    367                  * we don't have this code for the ntlmv1 case.
    368                  */
    369 
    370                 if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_128) {
    371                        
    372                 } else if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) {
    373                         weak_session_key.length = 7;
    374                 } else { /* forty bits */
    375                         weak_session_key.length = 5;
    376                 }
    377                 dump_data_pw("NTLMSSP weakend master key:\n",
    378                              weak_session_key.data,
    379                              weak_session_key.length);
    380 
    381                 /* SEND: sign key */
    382                 calc_ntlmv2_key(gensec_ntlmssp_state,
    383                                 &gensec_ntlmssp_state->crypt.ntlm2.send_sign_key,
    384                                 gensec_ntlmssp_state->session_key, send_sign_const);
    385                 dump_data_pw("NTLMSSP send sign key:\n",
    386                              gensec_ntlmssp_state->crypt.ntlm2.send_sign_key.data,
    387                              gensec_ntlmssp_state->crypt.ntlm2.send_sign_key.length);
    388                
    389                 /* SEND: seal ARCFOUR pad */
    390                 calc_ntlmv2_key(mem_ctx,
    391                                 &send_seal_key,
    392                                 weak_session_key, send_seal_const);
    393                 dump_data_pw("NTLMSSP send seal key:\n",
    394                              send_seal_key.data,
    395                              send_seal_key.length);
    396                 arcfour_init(gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state,
    397                              &send_seal_key);
    398                 dump_data_pw("NTLMSSP send sesl hash:\n",
    399                              gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state->sbox,
    400                              sizeof(gensec_ntlmssp_state->crypt.ntlm2.send_seal_arcfour_state->sbox));
    401 
    402                 /* RECV: sign key */
    403                 calc_ntlmv2_key(gensec_ntlmssp_state,
    404                                 &gensec_ntlmssp_state->crypt.ntlm2.recv_sign_key,
    405                                 gensec_ntlmssp_state->session_key, recv_sign_const);
    406                 dump_data_pw("NTLMSSP recv sign key:\n",
    407                              gensec_ntlmssp_state->crypt.ntlm2.recv_sign_key.data,
    408                              gensec_ntlmssp_state->crypt.ntlm2.recv_sign_key.length);
    409 
    410                 /* RECV: seal ARCFOUR pad */
    411                 calc_ntlmv2_key(mem_ctx,
    412                                 &recv_seal_key,
    413                                 weak_session_key, recv_seal_const);
    414                 dump_data_pw("NTLMSSP recv seal key:\n",
    415                              recv_seal_key.data,
    416                              recv_seal_key.length);
    417                 arcfour_init(gensec_ntlmssp_state->crypt.ntlm2.recv_seal_arcfour_state,
    418                              &recv_seal_key);
    419                 dump_data_pw("NTLMSSP receive seal hash:\n",
    420                              gensec_ntlmssp_state->crypt.ntlm2.recv_seal_arcfour_state->sbox,
    421                              sizeof(gensec_ntlmssp_state->crypt.ntlm2.recv_seal_arcfour_state->sbox));
    422 
    423                 gensec_ntlmssp_state->crypt.ntlm2.send_seq_num = 0;
    424                 gensec_ntlmssp_state->crypt.ntlm2.recv_seq_num = 0;
    425 
    426         } else {
    427                 DATA_BLOB weak_session_key = ntlmssp_weakend_key(gensec_ntlmssp_state, mem_ctx);
    428                 DEBUG(5, ("NTLMSSP Sign/Seal - using NTLM1\n"));
    429 
    430                 gensec_ntlmssp_state->crypt.ntlm.arcfour_state = talloc(gensec_ntlmssp_state, struct arcfour_state);
    431                 NT_STATUS_HAVE_NO_MEMORY(gensec_ntlmssp_state->crypt.ntlm.arcfour_state);
    432 
    433                 arcfour_init(gensec_ntlmssp_state->crypt.ntlm.arcfour_state,
    434                              &weak_session_key);
    435                 dump_data_pw("NTLMSSP hash:\n", gensec_ntlmssp_state->crypt.ntlm.arcfour_state->sbox,
    436                              sizeof(gensec_ntlmssp_state->crypt.ntlm.arcfour_state->sbox));
    437 
    438                 gensec_ntlmssp_state->crypt.ntlm.seq_num = 0;
    439         }
    440 
    441         talloc_free(mem_ctx);
    442         return NT_STATUS_OK;
     105        return nt_status;
    443106}
    444107
     
    449112
    450113NTSTATUS gensec_ntlmssp_wrap(struct gensec_security *gensec_security,
    451                              TALLOC_CTX *sig_mem_ctx,
     114                             TALLOC_CTX *out_mem_ctx,
    452115                             const DATA_BLOB *in,
    453116                             DATA_BLOB *out)
    454117{
    455         DATA_BLOB sig;
    456         NTSTATUS nt_status;
     118        struct gensec_ntlmssp_context *gensec_ntlmssp =
     119                talloc_get_type_abort(gensec_security->private_data,
     120                                      struct gensec_ntlmssp_context);
    457121
    458         if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
    459 
    460                 *out = data_blob_talloc(sig_mem_ctx, NULL, in->length + NTLMSSP_SIG_SIZE);
    461                 if (!out->data) {
    462                         return NT_STATUS_NO_MEMORY;
    463                 }
    464                 memcpy(out->data + NTLMSSP_SIG_SIZE, in->data, in->length);
    465                
    466                 nt_status = gensec_ntlmssp_seal_packet(gensec_security, sig_mem_ctx,
    467                                                        out->data + NTLMSSP_SIG_SIZE,
    468                                                        out->length - NTLMSSP_SIG_SIZE,
    469                                                        out->data + NTLMSSP_SIG_SIZE,
    470                                                        out->length - NTLMSSP_SIG_SIZE,
    471                                                        &sig);
    472                
    473                 if (NT_STATUS_IS_OK(nt_status)) {
    474                         memcpy(out->data, sig.data, NTLMSSP_SIG_SIZE);
    475                 }
    476                 return nt_status;
    477 
    478         } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
    479 
    480                 *out = data_blob_talloc(sig_mem_ctx, NULL, in->length + NTLMSSP_SIG_SIZE);
    481                 if (!out->data) {
    482                         return NT_STATUS_NO_MEMORY;
    483                 }
    484                 memcpy(out->data + NTLMSSP_SIG_SIZE, in->data, in->length);
    485 
    486                 nt_status = gensec_ntlmssp_sign_packet(gensec_security, sig_mem_ctx,
    487                                                        out->data + NTLMSSP_SIG_SIZE,
    488                                                        out->length - NTLMSSP_SIG_SIZE,
    489                                                        out->data + NTLMSSP_SIG_SIZE,
    490                                                        out->length - NTLMSSP_SIG_SIZE,
    491                                                        &sig);
    492 
    493                 if (NT_STATUS_IS_OK(nt_status)) {
    494                         memcpy(out->data, sig.data, NTLMSSP_SIG_SIZE);
    495                 }
    496                 return nt_status;
    497 
    498         } else {
    499                 *out = *in;
    500                 return NT_STATUS_OK;
    501         }
     122        return ntlmssp_wrap(gensec_ntlmssp->ntlmssp_state,
     123                            out_mem_ctx,
     124                            in, out);
    502125}
    503126
    504127
    505128NTSTATUS gensec_ntlmssp_unwrap(struct gensec_security *gensec_security,
    506                                TALLOC_CTX *sig_mem_ctx,
     129                               TALLOC_CTX *out_mem_ctx,
    507130                               const DATA_BLOB *in,
    508131                               DATA_BLOB *out)
    509132{
    510         DATA_BLOB sig;
     133        struct gensec_ntlmssp_context *gensec_ntlmssp =
     134                talloc_get_type_abort(gensec_security->private_data,
     135                                      struct gensec_ntlmssp_context);
    511136
    512         if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
    513                 if (in->length < NTLMSSP_SIG_SIZE) {
    514                         return NT_STATUS_INVALID_PARAMETER;
    515                 }
    516                 sig.data = in->data;
    517                 sig.length = NTLMSSP_SIG_SIZE;
    518 
    519                 *out = data_blob_talloc(sig_mem_ctx, in->data + NTLMSSP_SIG_SIZE, in->length - NTLMSSP_SIG_SIZE);
    520                
    521                 return gensec_ntlmssp_unseal_packet(gensec_security, sig_mem_ctx,
    522                                                     out->data, out->length,
    523                                                     out->data, out->length,
    524                                                     &sig);
    525                                                  
    526         } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
    527                 struct gensec_ntlmssp_state *gensec_ntlmssp_state =
    528                 (struct gensec_ntlmssp_state *)gensec_security->private_data;
    529                 NTSTATUS status;
    530                 uint32_t ntlm_seqnum;
    531                 struct arcfour_state ntlm_state;
    532                 uint32_t ntlm2_seqnum_r;
    533                 uint8_t ntlm2_key_r[16];
    534                 struct arcfour_state ntlm2_state_r;
    535 
    536                 if (in->length < NTLMSSP_SIG_SIZE) {
    537                         return NT_STATUS_INVALID_PARAMETER;
    538                 }
    539                 sig.data = in->data;
    540                 sig.length = NTLMSSP_SIG_SIZE;
    541                 *out = data_blob_talloc(sig_mem_ctx, in->data + NTLMSSP_SIG_SIZE, in->length - NTLMSSP_SIG_SIZE);
    542 
    543                 if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
    544                         ntlm2_seqnum_r = gensec_ntlmssp_state->crypt.ntlm2.recv_seq_num;
    545                         ntlm2_state_r = *gensec_ntlmssp_state->crypt.ntlm2.recv_seal_arcfour_state;
    546                         memcpy(ntlm2_key_r,
    547                                gensec_ntlmssp_state->crypt.ntlm2.recv_sign_key.data,
    548                                16);
    549                 } else {
    550                         ntlm_seqnum = gensec_ntlmssp_state->crypt.ntlm.seq_num;
    551                         ntlm_state = *gensec_ntlmssp_state->crypt.ntlm.arcfour_state;
    552                 }
    553 
    554                 status = gensec_ntlmssp_check_packet(gensec_security, sig_mem_ctx,
    555                                                      out->data, out->length,
    556                                                      out->data, out->length,
    557                                                      &sig);
    558                 if (!NT_STATUS_IS_OK(status)) {
    559                         NTSTATUS check_status = status;
    560                         /*
    561                          * The Windows LDAP libraries seems to have a bug
    562                          * and always use sealing even if only signing was
    563                          * negotiated. So we need to fallback.
    564                          */
    565 
    566                         if (gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
    567                                 gensec_ntlmssp_state->crypt.ntlm2.recv_seq_num = ntlm2_seqnum_r;
    568                                 *gensec_ntlmssp_state->crypt.ntlm2.recv_seal_arcfour_state = ntlm2_state_r;
    569                                 memcpy(gensec_ntlmssp_state->crypt.ntlm2.recv_sign_key.data,
    570                                        ntlm2_key_r, 16);
    571                         } else {
    572                                 gensec_ntlmssp_state->crypt.ntlm.seq_num = ntlm_seqnum;
    573                                 *gensec_ntlmssp_state->crypt.ntlm.arcfour_state = ntlm_state;
    574                         }
    575 
    576                         status = gensec_ntlmssp_unseal_packet(gensec_security,
    577                                                               sig_mem_ctx,
    578                                                               out->data,
    579                                                               out->length,
    580                                                               out->data,
    581                                                               out->length,
    582                                                               &sig);
    583                         if (NT_STATUS_IS_OK(status)) {
    584                                 gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
    585                         } else {
    586                                 status = check_status;
    587                         }
    588                 }
    589                 return status;
    590         } else {
    591                 *out = *in;
    592                 return NT_STATUS_OK;
    593         }
     137        return ntlmssp_unwrap(gensec_ntlmssp->ntlmssp_state,
     138                              out_mem_ctx,
     139                              in, out);
    594140}
    595 
Note: See TracChangeset for help on using the changeset viewer.