gsasl  1.8.0
ntlm.c
Go to the documentation of this file.
00001 /* ntlm.c --- Implementation of non-standard SASL mechanism NTLM, client side.
00002  * Copyright (C) 2002-2012 Simon Josefsson
00003  *
00004  * This file is part of GNU SASL Library.
00005  *
00006  * GNU SASL Library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public License
00008  * as published by the Free Software Foundation; either version 2.1 of
00009  * the License, or (at your option) any later version.
00010  *
00011  * GNU SASL Library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with GNU SASL Library; if not, write to the Free
00018  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019  * Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #ifdef HAVE_CONFIG_H
00024 #include "config.h"
00025 #endif
00026 
00027 /* Get malloc, free. */
00028 #include <stdlib.h>
00029 
00030 /* Get memcpy. */
00031 #include <string.h>
00032 
00033 /* Get specification. */
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   const char *domain = gsasl_property_get (sctx, GSASL_REALM);
00068   const char *authid = gsasl_property_get (sctx, GSASL_AUTHID);
00069   const char *password;
00070   int res;
00071 
00072   if (!authid)
00073     return GSASL_NO_AUTHID;
00074 
00075   switch (state->step)
00076     {
00077     case 0:
00078       {
00079         tSmbNtlmAuthRequest *request;
00080 
00081         request = malloc (sizeof (*request));
00082         if (!request)
00083           return GSASL_MALLOC_ERROR;
00084 
00085         buildSmbNtlmAuthRequest (request, authid, domain);
00086 
00087         *output_len = SmbLength (request);
00088         *output = malloc (*output_len);
00089         if (!*output)
00090           {
00091             free (request);
00092             return GSASL_MALLOC_ERROR;
00093           }
00094         memcpy (*output, request, *output_len);
00095 
00096         free (request);
00097 
00098         /* dumpSmbNtlmAuthRequest(stdout, &request); */
00099 
00100         state->step++;
00101         res = GSASL_NEEDS_MORE;
00102         break;
00103       }
00104 
00105     case 1:
00106       {
00107         tSmbNtlmAuthChallenge *challenge;
00108         tSmbNtlmAuthResponse *response;
00109 
00110         if (input_len > sizeof (*challenge))
00111           return GSASL_MECHANISM_PARSE_ERROR;
00112 
00113         challenge = malloc (sizeof (*challenge));
00114         if (!challenge)
00115           return GSASL_MALLOC_ERROR;
00116 
00117         /* Hand crafted challenge for parser testing:
00118            TlRMTVNTUAAAAAAAAAAAAAAAAAAAAGFiY2RlZmdoMDEyMzQ1Njc4ODY2NDQwMTIz */
00119 
00120         memcpy (challenge, input, input_len);
00121 
00122         password = gsasl_property_get (sctx, GSASL_PASSWORD);
00123         if (!password)
00124           {
00125             free (challenge);
00126             return GSASL_NO_PASSWORD;
00127           }
00128 
00129         response = malloc (sizeof (*response));
00130         if (!response)
00131           {
00132             free (challenge);
00133             return GSASL_MALLOC_ERROR;
00134           }
00135 
00136         buildSmbNtlmAuthResponse (challenge, response, authid, password);
00137 
00138         free (challenge);
00139 
00140         *output_len = SmbLength (response);
00141         *output = malloc (*output_len);
00142         if (!*output)
00143           {
00144             free (response);
00145             return GSASL_MALLOC_ERROR;
00146           }
00147         memcpy (*output, response, *output_len);
00148 
00149         free (response);
00150 
00151         /* dumpSmbNtlmAuthResponse(stdout, &response); */
00152 
00153         state->step++;
00154         res = GSASL_OK;
00155         break;
00156       }
00157 
00158     default:
00159       res = GSASL_MECHANISM_CALLED_TOO_MANY_TIMES;
00160       break;
00161     }
00162 
00163   return res;
00164 }
00165 
00166 void
00167 _gsasl_ntlm_client_finish (Gsasl_session * sctx, void *mech_data)
00168 {
00169   _Gsasl_ntlm_state *state = mech_data;
00170 
00171   free (state);
00172 }