gsasl  1.10.0
About: GNU SASL is an implementation of the Simple Authentication and Security Layer (SASL). Development version.
  Fossies Dox: gsasl-1.10.0.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

server.c
Go to the documentation of this file.
1 /* server.c --- OPENID20 mechanism, server side.
2  * Copyright (C) 2011-2021 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 "openid20.h"
29 
30 /* Get strdup, strlen. */
31 #include <string.h>
32 
33 /* Get calloc, free. */
34 #include <stdlib.h>
35 
36 /* Get _gsasl_parse_gs2_header. */
37 #include "mechtools.h"
38 
40 {
41  int step;
43 };
44 
45 int
47  void **mech_data)
48 {
49  struct openid20_server_state *state;
50 
51  state = (struct openid20_server_state *) calloc (sizeof (*state), 1);
52  if (state == NULL)
53  return GSASL_MALLOC_ERROR;
54 
55  *mech_data = state;
56 
57  return GSASL_OK;
58 }
59 
60 int
62  void *mech_data,
63  const char *input, size_t input_len,
64  char **output, size_t *output_len)
65 {
66  struct openid20_server_state *state = mech_data;
68 
69  *output_len = 0;
70  *output = NULL;
71 
72  switch (state->step)
73  {
74  case 0:
75  {
76  const char *p;
77  char *authzid;
78  size_t headerlen;
79 
80  if (input_len == 0)
81  return GSASL_NEEDS_MORE;
82 
83  res = _gsasl_parse_gs2_header (input, input_len,
84  &authzid, &headerlen);
85  if (res != GSASL_OK)
86  return res;
87 
88  if (authzid)
89  {
90  gsasl_property_set (sctx, GSASL_AUTHZID, authzid);
91  free (authzid);
92  }
93 
94  input += headerlen;
95  input_len -= headerlen;
96 
97  gsasl_property_set_raw (sctx, GSASL_AUTHID, input, input_len);
98 
100  if (!p || !*p)
102 
103  *output_len = strlen (p);
104  *output = malloc (*output_len);
105  if (!*output)
106  return GSASL_MALLOC_ERROR;
107 
108  memcpy (*output, p, *output_len);
109 
111  state->step++;
112  break;
113  }
114 
115  case 1:
116  {
117  const char *outcome_data;
118 
119  if (!(input_len == 1 && *input == '='))
121 
123  if (res != GSASL_OK)
124  {
125  *output = strdup ("openid.error=fail");
126  if (!*output)
127  return GSASL_MALLOC_ERROR;
128  *output_len = strlen (*output);
129 
130  /* [RFC4422] Section 3.6 explicitly prohibits additional
131  information in an unsuccessful authentication outcome.
132  Therefore, the openid.error and openid.error_code are
133  to be sent as an additional challenge in the event of
134  an unsuccessful outcome. In this case, as the protocol
135  is lock step, the client will follow with an additional
136  exchange containing "=", after which the server will
137  respond with an application-level outcome. */
138 
139  state->allow_error_step = 1;
140  state->step++;
141  return GSASL_NEEDS_MORE;
142  }
143 
144  outcome_data = gsasl_property_get (sctx, GSASL_OPENID20_OUTCOME_DATA);
145  if (outcome_data)
146  {
147  *output = strdup (outcome_data);
148  if (!*output)
149  return GSASL_MALLOC_ERROR;
150  *output_len = strlen (*output);
151  }
152  else
153  {
154  *output = NULL;
155  *output_len = 0;
156  }
157 
158  res = GSASL_OK;
159  state->step++;
160  }
161  break;
162 
163  case 2:
164  {
165  /* We only get here when the previous step signalled an error
166  to the client. */
167 
168  if (!state->allow_error_step)
170 
171  if (!(input_len == 1 && *input == '='))
173 
175  state->step++;
176  }
177  break;
178 
179  default:
180  break;
181  }
182 
183  return res;
184 }
185 
186 void
188  void *mech_data)
189 {
190  struct openid20_server_state *state = mech_data;
191 
192  if (!state)
193  return;
194 
195  free (state);
196 }
int gsasl_callback(Gsasl *ctx, Gsasl_session *sctx, Gsasl_property prop)
Definition: callback.c:75
#define NULL
Definition: stddef.in.h:72
const char * gsasl_property_get(Gsasl_session *sctx, Gsasl_property prop)
Definition: property.c:263
void gsasl_property_set(Gsasl_session *sctx, Gsasl_property prop, const char *data)
Definition: property.c:158
@ GSASL_OK
Definition: gsasl.h:171
@ GSASL_NO_OPENID20_REDIRECT_URL
Definition: gsasl.h:196
@ GSASL_AUTHENTICATION_ERROR
Definition: gsasl.h:180
@ GSASL_NEEDS_MORE
Definition: gsasl.h:172
@ GSASL_MALLOC_ERROR
Definition: gsasl.h:175
@ GSASL_MECHANISM_CALLED_TOO_MANY_TIMES
Definition: gsasl.h:174
@ GSASL_MECHANISM_PARSE_ERROR
Definition: gsasl.h:179
void gsasl_property_set_raw(Gsasl_session *sctx, Gsasl_property prop, const char *data, size_t len)
Definition: property.c:184
@ GSASL_AUTHZID
Definition: gsasl.h:336
@ GSASL_OPENID20_OUTCOME_DATA
Definition: gsasl.h:358
@ GSASL_VALIDATE_OPENID20
Definition: gsasl.h:369
@ GSASL_AUTHID
Definition: gsasl.h:335
@ GSASL_OPENID20_REDIRECT_URL
Definition: gsasl.h:357
int res
Definition: mbrtowc-impl.h:45
const char * p
Definition: mbrtowc-impl.h:42
int _gsasl_parse_gs2_header(const char *data, size_t len, char **authzid, size_t *headerlen)
Definition: mechtools.c:99
void _gsasl_openid20_server_finish(Gsasl_session *sctx _GL_UNUSED, void *mech_data)
Definition: server.c:187
int _gsasl_openid20_server_step(Gsasl_session *sctx, void *mech_data, const char *input, size_t input_len, char **output, size_t *output_len)
Definition: server.c:61
int _gsasl_openid20_server_start(Gsasl_session *sctx _GL_UNUSED, void **mech_data)
Definition: server.c:46
char * strdup(const char *s)
Definition: strdup.c:39