00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #if HAVE_CONFIG_H
00024 # include "config.h"
00025 #endif
00026
00027
00028 #include <stdlib.h>
00029
00030
00031 #include <string.h>
00032
00033
00034 #include "login.h"
00035
00036 struct _Gsasl_login_server_state
00037 {
00038 int step;
00039 char *username;
00040 char *password;
00041 };
00042
00043 #define CHALLENGE_USERNAME "User Name"
00044 #define CHALLENGE_PASSWORD "Password"
00045
00046 int
00047 _gsasl_login_server_start (Gsasl_session * sctx, void **mech_data)
00048 {
00049 struct _Gsasl_login_server_state *state;
00050
00051 state = calloc (1, sizeof (*state));
00052 if (state == NULL)
00053 return GSASL_MALLOC_ERROR;
00054
00055 *mech_data = state;
00056
00057 return GSASL_OK;
00058 }
00059
00060 int
00061 _gsasl_login_server_step (Gsasl_session * sctx,
00062 void *mech_data,
00063 const char *input, size_t input_len,
00064 char **output, size_t * output_len)
00065 {
00066 struct _Gsasl_login_server_state *state = mech_data;
00067 int res;
00068
00069 switch (state->step)
00070 {
00071 case 0:
00072 *output = strdup (CHALLENGE_USERNAME);
00073 if (!*output)
00074 return GSASL_MALLOC_ERROR;
00075 *output_len = strlen (CHALLENGE_USERNAME);
00076
00077 state->step++;
00078 res = GSASL_NEEDS_MORE;
00079 break;
00080
00081 case 1:
00082 if (input_len == 0)
00083 return GSASL_MECHANISM_PARSE_ERROR;
00084
00085 state->username = malloc (input_len + 1);
00086 if (state->username == NULL)
00087 return GSASL_MALLOC_ERROR;
00088
00089 memcpy (state->username, input, input_len);
00090 state->username[input_len] = '\0';
00091
00092 *output = strdup (CHALLENGE_PASSWORD);
00093 if (!*output)
00094 return GSASL_MALLOC_ERROR;
00095 *output_len = strlen (CHALLENGE_PASSWORD);
00096
00097 state->step++;
00098 res = GSASL_NEEDS_MORE;
00099 break;
00100
00101 case 2:
00102 if (input_len == 0)
00103 return GSASL_MECHANISM_PARSE_ERROR;
00104
00105 state->password = malloc (input_len + 1);
00106 if (state->password == NULL)
00107 return GSASL_MALLOC_ERROR;
00108
00109 memcpy (state->password, input, input_len);
00110 state->password[input_len] = '\0';
00111
00112 if (input_len != strlen (state->password))
00113 return GSASL_MECHANISM_PARSE_ERROR;
00114
00115 gsasl_property_set (sctx, GSASL_AUTHID, state->username);
00116 gsasl_property_set (sctx, GSASL_PASSWORD, state->password);
00117
00118 res = gsasl_callback (NULL, sctx, GSASL_VALIDATE_SIMPLE);
00119 if (res == GSASL_NO_CALLBACK)
00120 {
00121 const char *key;
00122
00123 gsasl_property_set (sctx, GSASL_AUTHZID, NULL);
00124 gsasl_property_set (sctx, GSASL_PASSWORD, NULL);
00125
00126 key = gsasl_property_get (sctx, GSASL_PASSWORD);
00127
00128 if (key && strlen (state->password) == strlen (key) &&
00129 strcmp (state->password, key) == 0)
00130 res = GSASL_OK;
00131 else
00132 res = GSASL_AUTHENTICATION_ERROR;
00133 }
00134
00135 *output_len = 0;
00136 *output = NULL;
00137 state->step++;
00138 break;
00139
00140 default:
00141 res = GSASL_MECHANISM_CALLED_TOO_MANY_TIMES;
00142 break;
00143 }
00144
00145 return res;
00146 }
00147
00148 void
00149 _gsasl_login_server_finish (Gsasl_session * sctx, void *mech_data)
00150 {
00151 struct _Gsasl_login_server_state *state = mech_data;
00152
00153 if (!state)
00154 return;
00155
00156 if (state->username)
00157 free (state->username);
00158 if (state->password)
00159 free (state->password);
00160 free (state);
00161 }