gsasl  2.2.1
login/server.c
Go to the documentation of this file.
1 /* server.c --- Non-standard SASL mechanism LOGIN, server 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 strdup, strlen. */
29 #include <string.h>
30 
31 /* Get specification. */
32 #include "login.h"
33 
35 {
36  int step;
37  char *username;
38  char *password;
39 };
40 
41 #define CHALLENGE_USERNAME "User Name"
42 #define CHALLENGE_PASSWORD "Password"
43 
44 int
45 _gsasl_login_server_start (Gsasl_session *sctx _GL_UNUSED, void **mech_data)
46 {
47  struct _Gsasl_login_server_state *state;
48 
49  state = calloc (1, sizeof (*state));
50  if (state == NULL)
51  return GSASL_MALLOC_ERROR;
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  struct _Gsasl_login_server_state *state = mech_data;
65  int res;
66 
67  switch (state->step)
68  {
69  case 0:
70  *output = strdup (CHALLENGE_USERNAME);
71  if (!*output)
72  return GSASL_MALLOC_ERROR;
73  *output_len = strlen (CHALLENGE_USERNAME);
74 
75  state->step++;
76  res = GSASL_NEEDS_MORE;
77  break;
78 
79  case 1:
80  if (input_len == 0)
82 
83  state->username = strndup (input, input_len);
84  if (state->username == NULL)
85  return GSASL_MALLOC_ERROR;
86 
87  if (input_len != strlen (state->username))
89 
90  *output = strdup (CHALLENGE_PASSWORD);
91  if (!*output)
92  return GSASL_MALLOC_ERROR;
93  *output_len = strlen (CHALLENGE_PASSWORD);
94 
95  state->step++;
96  res = GSASL_NEEDS_MORE;
97  break;
98 
99  case 2:
100  if (input_len == 0)
102 
103  state->password = strndup (input, input_len);
104  if (state->password == NULL)
105  return GSASL_MALLOC_ERROR;
106 
107  if (input_len != strlen (state->password))
109 
110  res = gsasl_property_set (sctx, GSASL_AUTHID, state->username);
111  if (res != GSASL_OK)
112  return res;
113  res = gsasl_property_set (sctx, GSASL_PASSWORD, state->password);
114  if (res != GSASL_OK)
115  return res;
116 
117  res = gsasl_callback (NULL, sctx, GSASL_VALIDATE_SIMPLE);
118  if (res == GSASL_NO_CALLBACK)
119  {
120  const char *key;
121 
124 
125  key = gsasl_property_get (sctx, GSASL_PASSWORD);
126 
127  if (key && strlen (state->password) == strlen (key) &&
128  strcmp (state->password, key) == 0)
129  res = GSASL_OK;
130  else
132  }
133 
134  *output_len = 0;
135  *output = NULL;
136  state->step++;
137  break;
138 
139  default:
141  break;
142  }
143 
144  return res;
145 }
146 
147 void
148 _gsasl_login_server_finish (Gsasl_session *sctx _GL_UNUSED, void *mech_data)
149 {
150  struct _Gsasl_login_server_state *state = mech_data;
151 
152  if (!state)
153  return;
154 
155  free (state->username);
156  free (state->password);
157  free (state);
158 }
int gsasl_callback(Gsasl *ctx, Gsasl_session *sctx, Gsasl_property prop)
Definition: callback.c:71
_GSASL_API void gsasl_property_free(Gsasl_session *sctx, Gsasl_property prop)
Definition: property.c:159
@ GSASL_NO_CALLBACK
Definition: gsasl.h:142
@ GSASL_OK
Definition: gsasl.h:129
@ GSASL_AUTHENTICATION_ERROR
Definition: gsasl.h:138
@ GSASL_NEEDS_MORE
Definition: gsasl.h:130
@ GSASL_MALLOC_ERROR
Definition: gsasl.h:133
@ GSASL_MECHANISM_CALLED_TOO_MANY_TIMES
Definition: gsasl.h:132
@ GSASL_MECHANISM_PARSE_ERROR
Definition: gsasl.h:137
_GSASL_API int gsasl_property_set(Gsasl_session *sctx, Gsasl_property prop, const char *data)
Definition: property.c:189
_GSASL_API const char * gsasl_property_get(Gsasl_session *sctx, Gsasl_property prop)
Definition: property.c:292
@ GSASL_AUTHZID
Definition: gsasl.h:225
@ GSASL_VALIDATE_SIMPLE
Definition: gsasl.h:253
@ GSASL_PASSWORD
Definition: gsasl.h:226
@ GSASL_AUTHID
Definition: gsasl.h:224
#define CHALLENGE_USERNAME
Definition: login/server.c:41
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:59
void _gsasl_login_server_finish(Gsasl_session *sctx _GL_UNUSED, void *mech_data)
Definition: login/server.c:148
#define CHALLENGE_PASSWORD
Definition: login/server.c:42
int _gsasl_login_server_start(Gsasl_session *sctx _GL_UNUSED, void **mech_data)
Definition: login/server.c:45