gsasl  2.2.2
login/server.c
Go to the documentation of this file.
1 /* server.c --- Non-standard SASL mechanism LOGIN, server side.
2  * Copyright (C) 2002-2025 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, see
18  * <https://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #include <config.h>
23 
24 /* Get malloc, free. */
25 #include <stdlib.h>
26 
27 /* Get strdup, strlen. */
28 #include <string.h>
29 
30 /* Get specification. */
31 #include "login.h"
32 
34 {
35  int step;
36  char *username;
37  char *password;
38 };
39 
40 #define CHALLENGE_USERNAME "User Name"
41 #define CHALLENGE_PASSWORD "Password"
42 
43 int
44 _gsasl_login_server_start (Gsasl_session *sctx _GL_UNUSED, void **mech_data)
45 {
46  struct _Gsasl_login_server_state *state;
47 
48  state = calloc (1, sizeof (*state));
49  if (state == NULL)
50  return GSASL_MALLOC_ERROR;
51 
52  *mech_data = state;
53 
54  return GSASL_OK;
55 }
56 
57 int
59  void *mech_data,
60  const char *input, size_t input_len,
61  char **output, size_t *output_len)
62 {
63  struct _Gsasl_login_server_state *state = mech_data;
64  int res;
65 
66  switch (state->step)
67  {
68  case 0:
69  *output = strdup (CHALLENGE_USERNAME);
70  if (!*output)
71  return GSASL_MALLOC_ERROR;
72  *output_len = strlen (CHALLENGE_USERNAME);
73 
74  state->step++;
75  res = GSASL_NEEDS_MORE;
76  break;
77 
78  case 1:
79  if (input_len == 0)
81 
82  state->username = strndup (input, input_len);
83  if (state->username == NULL)
84  return GSASL_MALLOC_ERROR;
85 
86  if (input_len != strlen (state->username))
88 
89  *output = strdup (CHALLENGE_PASSWORD);
90  if (!*output)
91  return GSASL_MALLOC_ERROR;
92  *output_len = strlen (CHALLENGE_PASSWORD);
93 
94  state->step++;
95  res = GSASL_NEEDS_MORE;
96  break;
97 
98  case 2:
99  if (input_len == 0)
101 
102  state->password = strndup (input, input_len);
103  if (state->password == NULL)
104  return GSASL_MALLOC_ERROR;
105 
106  if (input_len != strlen (state->password))
108 
109  res = gsasl_property_set (sctx, GSASL_AUTHID, state->username);
110  if (res != GSASL_OK)
111  return res;
112  res = gsasl_property_set (sctx, GSASL_PASSWORD, state->password);
113  if (res != GSASL_OK)
114  return res;
115 
116  res = gsasl_callback (NULL, sctx, GSASL_VALIDATE_SIMPLE);
117  if (res == GSASL_NO_CALLBACK)
118  {
119  const char *key;
120 
123 
124  key = gsasl_property_get (sctx, GSASL_PASSWORD);
125 
126  if (key && strlen (state->password) == strlen (key) &&
127  strcmp (state->password, key) == 0)
128  res = GSASL_OK;
129  else
131  }
132 
133  *output_len = 0;
134  *output = NULL;
135  state->step++;
136  break;
137 
138  default:
140  break;
141  }
142 
143  return res;
144 }
145 
146 void
147 _gsasl_login_server_finish (Gsasl_session *sctx _GL_UNUSED, void *mech_data)
148 {
149  struct _Gsasl_login_server_state *state = mech_data;
150 
151  if (!state)
152  return;
153 
154  free (state->username);
155  free (state->password);
156  free (state);
157 }
int gsasl_callback(Gsasl *ctx, Gsasl_session *sctx, Gsasl_property prop)
Definition: callback.c:70
_GSASL_API void gsasl_property_free(Gsasl_session *sctx, Gsasl_property prop)
Definition: property.c:158
@ GSASL_NO_CALLBACK
Definition: gsasl.h:141
@ GSASL_OK
Definition: gsasl.h:128
@ GSASL_AUTHENTICATION_ERROR
Definition: gsasl.h:137
@ GSASL_NEEDS_MORE
Definition: gsasl.h:129
@ GSASL_MALLOC_ERROR
Definition: gsasl.h:132
@ GSASL_MECHANISM_CALLED_TOO_MANY_TIMES
Definition: gsasl.h:131
@ GSASL_MECHANISM_PARSE_ERROR
Definition: gsasl.h:136
_GSASL_API int gsasl_property_set(Gsasl_session *sctx, Gsasl_property prop, const char *data)
Definition: property.c:188
_GSASL_API const char * gsasl_property_get(Gsasl_session *sctx, Gsasl_property prop)
Definition: property.c:291
@ GSASL_AUTHZID
Definition: gsasl.h:224
@ GSASL_VALIDATE_SIMPLE
Definition: gsasl.h:252
@ GSASL_PASSWORD
Definition: gsasl.h:225
@ GSASL_AUTHID
Definition: gsasl.h:223
#define CHALLENGE_USERNAME
Definition: login/server.c:40
int _gsasl_login_server_step(Gsasl_session *sctx, void *mech_data, const char *input, size_t input_len, char **output, size_t *output_len)
Definition: login/server.c:58
void _gsasl_login_server_finish(Gsasl_session *sctx _GL_UNUSED, void *mech_data)
Definition: login/server.c:147
#define CHALLENGE_PASSWORD
Definition: login/server.c:41
int _gsasl_login_server_start(Gsasl_session *sctx _GL_UNUSED, void **mech_data)
Definition: login/server.c:44