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 "x-ntlm.h"
00035
00036 #include <ntlm.h>
00037
00038 struct _Gsasl_ntlm_state
00039 {
00040 int step;
00041 };
00042 typedef struct _Gsasl_ntlm_state _Gsasl_ntlm_state;
00043
00044 int
00045 _gsasl_ntlm_client_start (Gsasl_session * sctx, void **mech_data)
00046 {
00047 _Gsasl_ntlm_state *state;
00048
00049 state = (_Gsasl_ntlm_state *) malloc (sizeof (*state));
00050 if (state == NULL)
00051 return GSASL_MALLOC_ERROR;
00052
00053 state->step = 0;
00054
00055 *mech_data = state;
00056
00057 return GSASL_OK;
00058 }
00059
00060 int
00061 _gsasl_ntlm_client_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 _Gsasl_ntlm_state *state = mech_data;
00067 tSmbNtlmAuthRequest request;
00068 tSmbNtlmAuthChallenge challenge;
00069 tSmbNtlmAuthResponse response;
00070 const char *domain = gsasl_property_get (sctx, GSASL_REALM);
00071 const char *authid = gsasl_property_get (sctx, GSASL_AUTHID);
00072 const char *password;
00073 int res;
00074
00075 if (!authid)
00076 return GSASL_NO_AUTHID;
00077
00078 switch (state->step)
00079 {
00080 case 0:
00081
00082
00083
00084
00085 buildSmbNtlmAuthRequest (&request, authid, domain);
00086
00087 *output_len = SmbLength (&request);
00088 *output = malloc (*output_len);
00089 if (!*output)
00090 return GSASL_MALLOC_ERROR;
00091 memcpy (*output, &request, *output_len);
00092
00093
00094
00095 state->step++;
00096 res = GSASL_NEEDS_MORE;
00097 break;
00098
00099 case 1:
00100 if (input_len > sizeof (challenge))
00101 return GSASL_MECHANISM_PARSE_ERROR;
00102
00103
00104
00105
00106 memcpy (&challenge, input, input_len);
00107
00108 password = gsasl_property_get (sctx, GSASL_PASSWORD);
00109 if (!password)
00110 return GSASL_NO_PASSWORD;
00111
00112 buildSmbNtlmAuthResponse (&challenge, &response, authid, password);
00113
00114 *output_len = SmbLength (&response);
00115 *output = malloc (*output_len);
00116 if (!*output)
00117 return GSASL_MALLOC_ERROR;
00118 memcpy (*output, &response, *output_len);
00119
00120
00121
00122 state->step++;
00123 res = GSASL_OK;
00124 break;
00125
00126 default:
00127 res = GSASL_MECHANISM_CALLED_TOO_MANY_TIMES;
00128 break;
00129 }
00130
00131 return res;
00132 }
00133
00134 void
00135 _gsasl_ntlm_client_finish (Gsasl_session * sctx, void *mech_data)
00136 {
00137 _Gsasl_ntlm_state *state = mech_data;
00138
00139 if (state)
00140 free (state);
00141 }