gsasl  2.2.1
plain/server.c
Go to the documentation of this file.
1 /* server.c --- SASL mechanism PLAIN as defined in RFC 2595, 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 specification. */
26 #include "plain.h"
27 
28 /* Get memcpy, memchr, strlen. */
29 #include <string.h>
30 
31 /* Get malloc, free. */
32 #include <stdlib.h>
33 
34 int
36  void *mech_data _GL_UNUSED,
37  const char *input, size_t input_len,
38  char **output, size_t *output_len)
39 {
40  const char *authzidptr = input;
41  char *authidptr = NULL;
42  char *passwordptr = NULL;
43  char *passwdz = NULL, *passprep = NULL, *authidprep = NULL;
44  int res;
45 
46  *output_len = 0;
47  *output = NULL;
48 
49  if (input_len == 0)
50  return GSASL_NEEDS_MORE;
51 
52  /* Parse input. */
53  {
54  size_t tmplen;
55 
56  authidptr = memchr (input, 0, input_len - 1);
57  if (authidptr)
58  {
59  authidptr++;
60  passwordptr = memchr (authidptr, 0, input_len - strlen (input) - 1);
61  if (passwordptr)
62  passwordptr++;
63  else
65  }
66  else
68 
69  /* As the NUL (U+0000) character is used as a deliminator, the NUL
70  (U+0000) character MUST NOT appear in authzid, authcid, or passwd
71  productions. */
72  tmplen = input_len - (size_t) (passwordptr - input);
73  if (memchr (passwordptr, 0, tmplen))
75  }
76 
77  /* Store authid, after preparing it... */
78  {
79  res = gsasl_saslprep (authidptr, GSASL_ALLOW_UNASSIGNED,
80  &authidprep, NULL);
81  if (res != GSASL_OK)
82  return res;
83 
84  res = gsasl_property_set (sctx, GSASL_AUTHID, authidprep);
85  if (res != GSASL_OK)
86  return res;
87 
88  /* Store authzid, if absent, use SASLprep(authcid). */
89  if (*authzidptr == '\0')
90  res = gsasl_property_set (sctx, GSASL_AUTHZID, authidprep);
91  else
92  res = gsasl_property_set (sctx, GSASL_AUTHZID, authzidptr);
93  if (res != GSASL_OK)
94  return res;
95 
96  free (authidprep);
97  }
98 
99  /* Store passwd, after preparing it... */
100  {
101  size_t passwdzlen = input_len - (size_t) (passwordptr - input);
102 
103  /* Need to zero terminate password... */
104  passwdz = malloc (passwdzlen + 1);
105  if (passwdz == NULL)
106  return GSASL_MALLOC_ERROR;
107  memcpy (passwdz, passwordptr, passwdzlen);
108  passwdz[passwdzlen] = '\0';
109 
110  res = gsasl_saslprep (passwdz, GSASL_ALLOW_UNASSIGNED, &passprep, NULL);
111  free (passwdz);
112  if (res != GSASL_OK)
113  return res;
114 
115  res = gsasl_property_set (sctx, GSASL_PASSWORD, passprep);
116  if (res != GSASL_OK)
117  return res;
118  }
119 
120  /* Authorization. Let application verify credentials internally,
121  but fall back to deal with it locally... */
122  res = gsasl_callback (NULL, sctx, GSASL_VALIDATE_SIMPLE);
123  if (res == GSASL_NO_CALLBACK)
124  {
125  const char *key;
126  char *normkey;
127 
129 
130  /* The following will invoke a GSASL_PASSWORD callback. */
131  key = gsasl_property_get (sctx, GSASL_PASSWORD);
132  if (!key)
133  {
134  free (passprep);
135  return GSASL_NO_PASSWORD;
136  }
137 
138  /* Unassigned code points are not permitted. */
139  res = gsasl_saslprep (key, 0, &normkey, NULL);
140  if (res != GSASL_OK)
141  {
142  free (passprep);
143  return res;
144  }
145 
146  if (strcmp (normkey, passprep) == 0)
147  res = GSASL_OK;
148  else
150 
151  free (normkey);
152  }
153  free (passprep);
154 
155  return res;
156 }
int gsasl_callback(Gsasl *ctx, Gsasl_session *sctx, Gsasl_property prop)
Definition: callback.c:71
@ GSASL_ALLOW_UNASSIGNED
Definition: gsasl.h:332
_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_NO_PASSWORD
Definition: gsasl.h:146
@ 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
_GSASL_API int gsasl_saslprep(const char *in, Gsasl_saslprep_flags flags, char **out, int *stringpreprc)
int _gsasl_plain_server_step(Gsasl_session *sctx, void *mech_data _GL_UNUSED, const char *input, size_t input_len, char **output, size_t *output_len)
Definition: plain/server.c:35