gsasl  2.2.1
ntlm.c
Go to the documentation of this file.
1 /* ntlm.c --- Implementation of non-standard SASL mechanism NTLM, client side.
2  * Copyright (C) 2002-2024 Simon Josefsson
3  *
4  * This file is part of GNU SASL Library.
5  *
6  * GNU SASL Library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public License
8  * as published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * GNU SASL Library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with GNU SASL Library; if not, write to the Free
18  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #include <config.h>
24 
25 /* Get malloc, free. */
26 #include <stdlib.h>
27 
28 /* Get memcpy. */
29 #include <string.h>
30 
31 /* Get specification. */
32 #include "x-ntlm.h"
33 
34 #include <ntlm.h>
35 
37 {
38  int step;
39 };
41 
42 int
43 _gsasl_ntlm_client_start (Gsasl_session *sctx _GL_UNUSED, void **mech_data)
44 {
45  _Gsasl_ntlm_state *state;
46 
47  state = (_Gsasl_ntlm_state *) malloc (sizeof (*state));
48  if (state == NULL)
49  return GSASL_MALLOC_ERROR;
50 
51  state->step = 0;
52 
53  *mech_data = state;
54 
55  return GSASL_OK;
56 }
57 
58 int
60  void *mech_data,
61  const char *input, size_t input_len,
62  char **output, size_t *output_len)
63 {
64  _Gsasl_ntlm_state *state = mech_data;
65  const char *domain = gsasl_property_get (sctx, GSASL_REALM);
66  const char *authid = gsasl_property_get (sctx, GSASL_AUTHID);
67  const char *password;
68  int res;
69 
70  if (!authid)
71  return GSASL_NO_AUTHID;
72 
73  switch (state->step)
74  {
75  case 0:
76  {
77  tSmbNtlmAuthRequest *request;
78 
79  request = malloc (sizeof (*request));
80  if (!request)
81  return GSASL_MALLOC_ERROR;
82 
83  buildSmbNtlmAuthRequest (request, authid, domain);
84 
85  *output_len = SmbLength (request);
86  *output = malloc (*output_len);
87  if (!*output)
88  {
89  free (request);
90  return GSASL_MALLOC_ERROR;
91  }
92  memcpy (*output, request, *output_len);
93 
94  free (request);
95 
96  /* dumpSmbNtlmAuthRequest(stdout, &request); */
97 
98  state->step++;
99  res = GSASL_NEEDS_MORE;
100  break;
101  }
102 
103  case 1:
104  {
105  tSmbNtlmAuthChallenge *challenge;
106  tSmbNtlmAuthResponse *response;
107 
108  if (input_len > sizeof (*challenge))
110 
111  challenge = malloc (sizeof (*challenge));
112  if (!challenge)
113  return GSASL_MALLOC_ERROR;
114 
115  /* Hand crafted challenge for parser testing:
116  TlRMTVNTUAAAAAAAAAAAAAAAAAAAAGFiY2RlZmdoMDEyMzQ1Njc4ODY2NDQwMTIz */
117 
118  memcpy (challenge, input, input_len);
119 
120  password = gsasl_property_get (sctx, GSASL_PASSWORD);
121  if (!password)
122  {
123  free (challenge);
124  return GSASL_NO_PASSWORD;
125  }
126 
127  response = malloc (sizeof (*response));
128  if (!response)
129  {
130  free (challenge);
131  return GSASL_MALLOC_ERROR;
132  }
133 
134  buildSmbNtlmAuthResponse (challenge, response, authid, password);
135 
136  free (challenge);
137 
138  *output_len = SmbLength (response);
139  *output = malloc (*output_len);
140  if (!*output)
141  {
142  free (response);
143  return GSASL_MALLOC_ERROR;
144  }
145  memcpy (*output, response, *output_len);
146 
147  free (response);
148 
149  /* dumpSmbNtlmAuthResponse(stdout, &response); */
150 
151  state->step++;
152  res = GSASL_OK;
153  break;
154  }
155 
156  default:
158  break;
159  }
160 
161  return res;
162 }
163 
164 void
165 _gsasl_ntlm_client_finish (Gsasl_session *sctx _GL_UNUSED, void *mech_data)
166 {
167  _Gsasl_ntlm_state *state = mech_data;
168 
169  free (state);
170 }
@ GSASL_OK
Definition: gsasl.h:129
@ GSASL_NEEDS_MORE
Definition: gsasl.h:130
@ GSASL_MALLOC_ERROR
Definition: gsasl.h:133
@ GSASL_NO_PASSWORD
Definition: gsasl.h:146
@ GSASL_MECHANISM_CALLED_TOO_MANY_TIMES
Definition: gsasl.h:132
@ GSASL_NO_AUTHID
Definition: gsasl.h:144
@ GSASL_MECHANISM_PARSE_ERROR
Definition: gsasl.h:137
_GSASL_API const char * gsasl_property_get(Gsasl_session *sctx, Gsasl_property prop)
Definition: property.c:292
@ GSASL_PASSWORD
Definition: gsasl.h:226
@ GSASL_REALM
Definition: gsasl.h:234
@ GSASL_AUTHID
Definition: gsasl.h:224
int _gsasl_ntlm_client_step(Gsasl_session *sctx, void *mech_data, const char *input, size_t input_len, char **output, size_t *output_len)
Definition: ntlm.c:59
int _gsasl_ntlm_client_start(Gsasl_session *sctx _GL_UNUSED, void **mech_data)
Definition: ntlm.c:43
void _gsasl_ntlm_client_finish(Gsasl_session *sctx _GL_UNUSED, void *mech_data)
Definition: ntlm.c:165