Coverage Report

Created: 2026-05-24 06:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/auth/ntlmssp/gensec_ntlmssp.c
Line
Count
Source
1
/*
2
 *  Unix SMB/CIFS implementation.
3
 *  Version 3.0
4
 *  NTLMSSP Signing routines
5
 *  Copyright (C) Luke Kenneth Casson Leighton 1996-2001
6
 *  Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003-2005
7
 *
8
 *  This program is free software; you can redistribute it and/or modify
9
 *  it under the terms of the GNU General Public License as published by
10
 *  the Free Software Foundation; either version 3 of the License, or
11
 *  (at your option) any later version.
12
 *
13
 *  This program is distributed in the hope that it will be useful,
14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 *  GNU General Public License for more details.
17
 *
18
 *  You should have received a copy of the GNU General Public License
19
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
20
 */
21
22
#include "includes.h"
23
#include "auth/ntlmssp/ntlmssp.h"
24
#include "auth/gensec/gensec.h"
25
#include "auth/gensec/gensec_internal.h"
26
#include "auth/ntlmssp/ntlmssp_private.h"
27
28
NTSTATUS gensec_ntlmssp_magic(struct gensec_security *gensec_security,
29
            const DATA_BLOB *first_packet)
30
0
{
31
0
  if (ntlmssp_blob_matches_magic(first_packet)) {
32
0
    return NT_STATUS_OK;
33
0
  } else {
34
0
    return NT_STATUS_INVALID_PARAMETER;
35
0
  }
36
0
}
37
38
/**
39
 * Return the NTLMSSP master session key
40
 *
41
 * @param ntlmssp_state NTLMSSP State
42
 */
43
44
NTSTATUS gensec_ntlmssp_session_key(struct gensec_security *gensec_security,
45
            TALLOC_CTX *mem_ctx,
46
            DATA_BLOB *session_key)
47
0
{
48
0
  struct gensec_ntlmssp_context *gensec_ntlmssp =
49
0
    talloc_get_type_abort(gensec_security->private_data,
50
0
              struct gensec_ntlmssp_context);
51
0
  struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
52
53
0
  if (ntlmssp_state->expected_state != NTLMSSP_DONE) {
54
0
    return NT_STATUS_NO_USER_SESSION_KEY;
55
0
  }
56
57
0
  if (!ntlmssp_state->session_key.data) {
58
0
    return NT_STATUS_NO_USER_SESSION_KEY;
59
0
  }
60
0
  *session_key = data_blob_talloc_s(mem_ctx,
61
0
            ntlmssp_state->session_key.data,
62
0
            ntlmssp_state->session_key.length);
63
0
  if (!session_key->data) {
64
0
    return NT_STATUS_NO_MEMORY;
65
0
  }
66
67
0
  return NT_STATUS_OK;
68
0
}
69
70
bool gensec_ntlmssp_have_feature(struct gensec_security *gensec_security,
71
         uint32_t feature)
72
0
{
73
0
  struct gensec_ntlmssp_context *gensec_ntlmssp =
74
0
    talloc_get_type_abort(gensec_security->private_data,
75
0
              struct gensec_ntlmssp_context);
76
0
  struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
77
78
0
  if (feature & GENSEC_FEATURE_SIGN) {
79
0
    if (!ntlmssp_state->session_key.length) {
80
0
      return false;
81
0
    }
82
0
    if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) {
83
0
      return true;
84
0
    }
85
0
  }
86
0
  if (feature & GENSEC_FEATURE_SEAL) {
87
0
    if (!ntlmssp_state->session_key.length) {
88
0
      return false;
89
0
    }
90
0
    if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) {
91
0
      return true;
92
0
    }
93
0
  }
94
0
  if (feature & GENSEC_FEATURE_SESSION_KEY) {
95
0
    if (ntlmssp_state->session_key.length) {
96
0
      return true;
97
0
    }
98
0
  }
99
0
  if (feature & GENSEC_FEATURE_DCE_STYLE) {
100
0
    return true;
101
0
  }
102
0
  if (feature & GENSEC_FEATURE_ASYNC_REPLIES) {
103
0
    if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
104
0
      return true;
105
0
    }
106
0
  }
107
0
  if (feature & GENSEC_FEATURE_SIGN_PKT_HEADER) {
108
0
    return true;
109
0
  }
110
0
  if (feature & GENSEC_FEATURE_NEW_SPNEGO) {
111
0
    if (!ntlmssp_state->session_key.length) {
112
0
      return false;
113
0
    }
114
0
    if (!(ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
115
0
      return false;
116
0
    }
117
0
    return ntlmssp_state->new_spnego;
118
0
  }
119
120
0
  return false;
121
0
}
122
123
NTSTATUS gensec_ntlmssp_start(struct gensec_security *gensec_security)
124
0
{
125
0
  struct gensec_ntlmssp_context *gensec_ntlmssp;
126
127
0
  gensec_ntlmssp = talloc_zero(gensec_security,
128
0
             struct gensec_ntlmssp_context);
129
0
  if (!gensec_ntlmssp) {
130
0
    return NT_STATUS_NO_MEMORY;
131
0
  }
132
133
0
  gensec_security->private_data = gensec_ntlmssp;
134
0
  return NT_STATUS_OK;
135
0
}
136
137
NTSTATUS gensec_ntlmssp_sign_packet(struct gensec_security *gensec_security,
138
            TALLOC_CTX *sig_mem_ctx,
139
            const uint8_t *data, size_t length,
140
            const uint8_t *whole_pdu, size_t pdu_length,
141
            DATA_BLOB *sig)
142
0
{
143
0
  struct gensec_ntlmssp_context *gensec_ntlmssp =
144
0
    talloc_get_type_abort(gensec_security->private_data,
145
0
              struct gensec_ntlmssp_context);
146
0
  NTSTATUS nt_status;
147
148
0
  nt_status = ntlmssp_sign_packet(gensec_ntlmssp->ntlmssp_state,
149
0
          sig_mem_ctx,
150
0
          data, length,
151
0
          whole_pdu, pdu_length,
152
0
          sig);
153
154
0
  return nt_status;
155
0
}
156
157
NTSTATUS gensec_ntlmssp_check_packet(struct gensec_security *gensec_security,
158
             const uint8_t *data, size_t length,
159
             const uint8_t *whole_pdu, size_t pdu_length,
160
             const DATA_BLOB *sig)
161
0
{
162
0
  struct gensec_ntlmssp_context *gensec_ntlmssp =
163
0
    talloc_get_type_abort(gensec_security->private_data,
164
0
              struct gensec_ntlmssp_context);
165
0
  NTSTATUS nt_status;
166
167
0
  nt_status = ntlmssp_check_packet(gensec_ntlmssp->ntlmssp_state,
168
0
           data, length,
169
0
           whole_pdu, pdu_length,
170
0
           sig);
171
172
0
  return nt_status;
173
0
}
174
175
NTSTATUS gensec_ntlmssp_seal_packet(struct gensec_security *gensec_security,
176
            TALLOC_CTX *sig_mem_ctx,
177
            uint8_t *data, size_t length,
178
            const uint8_t *whole_pdu, size_t pdu_length,
179
            DATA_BLOB *sig)
180
0
{
181
0
  struct gensec_ntlmssp_context *gensec_ntlmssp =
182
0
    talloc_get_type_abort(gensec_security->private_data,
183
0
              struct gensec_ntlmssp_context);
184
0
  NTSTATUS nt_status;
185
186
0
  nt_status = ntlmssp_seal_packet(gensec_ntlmssp->ntlmssp_state,
187
0
          sig_mem_ctx,
188
0
          data, length,
189
0
          whole_pdu, pdu_length,
190
0
          sig);
191
192
0
  return nt_status;
193
0
}
194
195
/*
196
  wrappers for the ntlmssp_*() functions
197
*/
198
NTSTATUS gensec_ntlmssp_unseal_packet(struct gensec_security *gensec_security,
199
              uint8_t *data, size_t length,
200
              const uint8_t *whole_pdu, size_t pdu_length,
201
              const DATA_BLOB *sig)
202
0
{
203
0
  struct gensec_ntlmssp_context *gensec_ntlmssp =
204
0
    talloc_get_type_abort(gensec_security->private_data,
205
0
              struct gensec_ntlmssp_context);
206
0
  NTSTATUS nt_status;
207
208
0
  nt_status = ntlmssp_unseal_packet(gensec_ntlmssp->ntlmssp_state,
209
0
            data, length,
210
0
            whole_pdu, pdu_length,
211
0
            sig);
212
213
0
  return nt_status;
214
0
}
215
216
size_t gensec_ntlmssp_sig_size(struct gensec_security *gensec_security, size_t data_size)
217
0
{
218
0
  return NTLMSSP_SIG_SIZE;
219
0
}
220
221
NTSTATUS gensec_ntlmssp_wrap(struct gensec_security *gensec_security,
222
           TALLOC_CTX *out_mem_ctx,
223
           const DATA_BLOB *in,
224
           DATA_BLOB *out)
225
0
{
226
0
  struct gensec_ntlmssp_context *gensec_ntlmssp =
227
0
    talloc_get_type_abort(gensec_security->private_data,
228
0
              struct gensec_ntlmssp_context);
229
230
0
  return ntlmssp_wrap(gensec_ntlmssp->ntlmssp_state,
231
0
          out_mem_ctx,
232
0
          in, out);
233
0
}
234
235
236
NTSTATUS gensec_ntlmssp_unwrap(struct gensec_security *gensec_security,
237
             TALLOC_CTX *out_mem_ctx,
238
             const DATA_BLOB *in,
239
             DATA_BLOB *out)
240
0
{
241
0
  struct gensec_ntlmssp_context *gensec_ntlmssp =
242
0
    talloc_get_type_abort(gensec_security->private_data,
243
0
              struct gensec_ntlmssp_context);
244
245
0
  return ntlmssp_unwrap(gensec_ntlmssp->ntlmssp_state,
246
0
            out_mem_ctx,
247
0
            in, out);
248
0
}