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