Fix three issues highlighted by clang analyser.
[exim.git] / src / src / auths / spa.c
index 70b6737904c116c883ced32c3f99765426db9592..1abd657813b3d5d3d86fa550553675f49343ce5d 100644 (file)
@@ -1,10 +1,8 @@
-/* $Cambridge: exim/src/src/auths/spa.c,v 1.9 2007/01/08 10:50:19 ph10 Exp $ */
-
 /*************************************************
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) University of Cambridge 1995 - 2007 */
+/* Copyright (c) University of Cambridge 1995 - 2009 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 /* This file, which provides support for Microsoft's Secure Password
@@ -14,6 +12,7 @@ server support. I (PH) have only modified it in very trivial ways.
 References:
   http://www.innovation.ch/java/ntlm.html
   http://www.kuro5hin.org/story/2002/4/28/1436/66154
+  http://download.microsoft.com/download/9/5/e/95ef66af-9026-4bb0-a41d-a4f81802d92c/%5bMS-SMTP%5d.pdf
 
  * It seems that some systems have existing but different definitions of some
  * of the following types. I received a complaint about "int16" causing
@@ -28,6 +27,7 @@ References:
 07-August-2003:  PH: Patched up the code to avoid assert bombouts for stupid
                      input data. Find appropriate comment by grepping for "PH".
 16-October-2006: PH: Added a call to auth_check_serv_cond() at the end
+05-June-2010:    PP: handle SASL initial response
 */
 
 
@@ -128,9 +128,11 @@ SPAAuthResponse  *responseptr = &response;
 uschar msgbuf[2048];
 uschar *clearpass;
 
-/* send a 334, MS Exchange style, and grab the client's request */
+/* send a 334, MS Exchange style, and grab the client's request,
+unless we already have it via an initial response. */
 
-if (auth_get_no64_data(&data, US"NTLM supported") != OK)
+if ((*data == '\0') &&
+    (auth_get_no64_data(&data, US"NTLM supported") != OK))
   {
   /* something borked */
   return FAIL;
@@ -200,6 +202,11 @@ auth_vars[0] = expand_nstring[1] = msgbuf;
 expand_nlength[1] = Ustrlen(msgbuf);
 expand_nmax = 1;
 
+/* clean up globals which aren't referenced, but still shouldn't be left
+pointing to stack memory */
+#define CLEANUP_RETURN(Code) do { auth_vars[0] = expand_nstring[1] = NULL; \
+  expand_nlength[1] = expand_nmax = 0; return (Code); } while (0);
+
 debug_print_string(ablock->server_debug_string);    /* customized debug */
 
 /* look up password */
@@ -211,13 +218,13 @@ if (clearpass == NULL)
     {
     DEBUG(D_auth) debug_printf("auth_spa_server(): forced failure while "
       "expanding spa_serverpassword\n");
-    return FAIL;
+    CLEANUP_RETURN(FAIL);
     }
   else
     {
     DEBUG(D_auth) debug_printf("auth_spa_server(): error while expanding "
       "spa_serverpassword: %s\n", expand_string_message);
-    return DEFER;
+    CLEANUP_RETURN(DEFER);
     }
   }
 
@@ -232,11 +239,14 @@ if (memcmp(ntRespData,
       ((unsigned char*)responseptr)+IVAL(&responseptr->ntResponse.offset,0),
       24) == 0)
   /* success. we have a winner. */
+  {
+  int rc = auth_check_serv_cond(ablock);
+  CLEANUP_RETURN(rc);
+  }
 
   /* Expand server_condition as an authorization check (PH) */
-  return auth_check_serv_cond(ablock);
 
-return FAIL;
+CLEANUP_RETURN(FAIL);
 }