Coverage Report

Created: 2025-12-31 06:20

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(mem_ctx, ntlmssp_state->session_key.data, ntlmssp_state->session_key.length);
61
0
  if (!session_key->data) {
62
0
    return NT_STATUS_NO_MEMORY;
63
0
  }
64
65
0
  return NT_STATUS_OK;
66
0
}
67
68
bool gensec_ntlmssp_have_feature(struct gensec_security *gensec_security,
69
         uint32_t feature)
70
0
{
71
0
  struct gensec_ntlmssp_context *gensec_ntlmssp =
72
0
    talloc_get_type_abort(gensec_security->private_data,
73
0
              struct gensec_ntlmssp_context);
74
0
  struct ntlmssp_state *ntlmssp_state = gensec_ntlmssp->ntlmssp_state;
75
76
0
  if (feature & GENSEC_FEATURE_SIGN) {
77
0
    if (!ntlmssp_state->session_key.length) {
78
0
      return false;
79
0
    }
80
0
    if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) {
81
0
      return true;
82
0
    }
83
0
  }
84
0
  if (feature & GENSEC_FEATURE_SEAL) {
85
0
    if (!ntlmssp_state->session_key.length) {
86
0
      return false;
87
0
    }
88
0
    if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) {
89
0
      return true;
90
0
    }
91
0
  }
92
0
  if (feature & GENSEC_FEATURE_SESSION_KEY) {
93
0
    if (ntlmssp_state->session_key.length) {
94
0
      return true;
95
0
    }
96
0
  }
97
0
  if (feature & GENSEC_FEATURE_DCE_STYLE) {
98
0
    return true;
99
0
  }
100
0
  if (feature & GENSEC_FEATURE_ASYNC_REPLIES) {
101
0
    if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) {
102
0
      return true;
103
0
    }
104
0
  }
105
0
  if (feature & GENSEC_FEATURE_SIGN_PKT_HEADER) {
106
0
    return true;
107
0
  }
108
0
  if (feature & GENSEC_FEATURE_NEW_SPNEGO) {
109
0
    if (!ntlmssp_state->session_key.length) {
110
0
      return false;
111
0
    }
112
0
    if (!(ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) {
113
0
      return false;
114
0
    }
115
0
    return ntlmssp_state->new_spnego;
116
0
  }
117
118
0
  return false;
119
0
}
120
121
NTSTATUS gensec_ntlmssp_start(struct gensec_security *gensec_security)
122
0
{
123
0
  struct gensec_ntlmssp_context *gensec_ntlmssp;
124
125
0
  gensec_ntlmssp = talloc_zero(gensec_security,
126
0
             struct gensec_ntlmssp_context);
127
0
  if (!gensec_ntlmssp) {
128
0
    return NT_STATUS_NO_MEMORY;
129
0
  }
130
131
0
  gensec_security->private_data = gensec_ntlmssp;
132
0
  return NT_STATUS_OK;
133
0
}
134
135
NTSTATUS gensec_ntlmssp_sign_packet(struct gensec_security *gensec_security,
136
            TALLOC_CTX *sig_mem_ctx,
137
            const uint8_t *data, size_t length,
138
            const uint8_t *whole_pdu, size_t pdu_length,
139
            DATA_BLOB *sig)
140
0
{
141
0
  struct gensec_ntlmssp_context *gensec_ntlmssp =
142
0
    talloc_get_type_abort(gensec_security->private_data,
143
0
              struct gensec_ntlmssp_context);
144
0
  NTSTATUS nt_status;
145
146
0
  nt_status = ntlmssp_sign_packet(gensec_ntlmssp->ntlmssp_state,
147
0
          sig_mem_ctx,
148
0
          data, length,
149
0
          whole_pdu, pdu_length,
150
0
          sig);
151
152
0
  return nt_status;
153
0
}
154
155
NTSTATUS gensec_ntlmssp_check_packet(struct gensec_security *gensec_security,
156
             const uint8_t *data, size_t length,
157
             const uint8_t *whole_pdu, size_t pdu_length,
158
             const DATA_BLOB *sig)
159
0
{
160
0
  struct gensec_ntlmssp_context *gensec_ntlmssp =
161
0
    talloc_get_type_abort(gensec_security->private_data,
162
0
              struct gensec_ntlmssp_context);
163
0
  NTSTATUS nt_status;
164
165
0
  nt_status = ntlmssp_check_packet(gensec_ntlmssp->ntlmssp_state,
166
0
           data, length,
167
0
           whole_pdu, pdu_length,
168
0
           sig);
169
170
0
  return nt_status;
171
0
}
172
173
NTSTATUS gensec_ntlmssp_seal_packet(struct gensec_security *gensec_security,
174
            TALLOC_CTX *sig_mem_ctx,
175
            uint8_t *data, size_t length,
176
            const uint8_t *whole_pdu, size_t pdu_length,
177
            DATA_BLOB *sig)
178
0
{
179
0
  struct gensec_ntlmssp_context *gensec_ntlmssp =
180
0
    talloc_get_type_abort(gensec_security->private_data,
181
0
              struct gensec_ntlmssp_context);
182
0
  NTSTATUS nt_status;
183
184
0
  nt_status = ntlmssp_seal_packet(gensec_ntlmssp->ntlmssp_state,
185
0
          sig_mem_ctx,
186
0
          data, length,
187
0
          whole_pdu, pdu_length,
188
0
          sig);
189
190
0
  return nt_status;
191
0
}
192
193
/*
194
  wrappers for the ntlmssp_*() functions
195
*/
196
NTSTATUS gensec_ntlmssp_unseal_packet(struct gensec_security *gensec_security,
197
              uint8_t *data, size_t length,
198
              const uint8_t *whole_pdu, size_t pdu_length,
199
              const DATA_BLOB *sig)
200
0
{
201
0
  struct gensec_ntlmssp_context *gensec_ntlmssp =
202
0
    talloc_get_type_abort(gensec_security->private_data,
203
0
              struct gensec_ntlmssp_context);
204
0
  NTSTATUS nt_status;
205
206
0
  nt_status = ntlmssp_unseal_packet(gensec_ntlmssp->ntlmssp_state,
207
0
            data, length,
208
0
            whole_pdu, pdu_length,
209
0
            sig);
210
211
0
  return nt_status;
212
0
}
213
214
size_t gensec_ntlmssp_sig_size(struct gensec_security *gensec_security, size_t data_size)
215
0
{
216
0
  return NTLMSSP_SIG_SIZE;
217
0
}
218
219
NTSTATUS gensec_ntlmssp_wrap(struct gensec_security *gensec_security,
220
           TALLOC_CTX *out_mem_ctx,
221
           const DATA_BLOB *in,
222
           DATA_BLOB *out)
223
0
{
224
0
  struct gensec_ntlmssp_context *gensec_ntlmssp =
225
0
    talloc_get_type_abort(gensec_security->private_data,
226
0
              struct gensec_ntlmssp_context);
227
228
0
  return ntlmssp_wrap(gensec_ntlmssp->ntlmssp_state,
229
0
          out_mem_ctx,
230
0
          in, out);
231
0
}
232
233
234
NTSTATUS gensec_ntlmssp_unwrap(struct gensec_security *gensec_security,
235
             TALLOC_CTX *out_mem_ctx,
236
             const DATA_BLOB *in,
237
             DATA_BLOB *out)
238
0
{
239
0
  struct gensec_ntlmssp_context *gensec_ntlmssp =
240
0
    talloc_get_type_abort(gensec_security->private_data,
241
0
              struct gensec_ntlmssp_context);
242
243
0
  return ntlmssp_unwrap(gensec_ntlmssp->ntlmssp_state,
244
0
            out_mem_ctx,
245
0
            in, out);
246
0
}