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, 2003, 2004, 2006  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 #if 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   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       /* Isn't this just the IMAP continuation char?  Not part of SASL mech.
00082          if (input_len != 1 && *input != '+')
00083          return GSASL_MECHANISM_PARSE_ERROR; */
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       /* dumpSmbNtlmAuthRequest(stdout, &request); */
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       /* Hand crafted challenge for parser testing:
00104          TlRMTVNTUAAAAAAAAAAAAAAAAAAAAGFiY2RlZmdoMDEyMzQ1Njc4ODY2NDQwMTIz */
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       /* dumpSmbNtlmAuthResponse(stdout, &response); */
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 }

Generated on Tue Aug 22 12:06:06 2006 for gsasl by  doxygen 1.4.7