Update version number and copyright year.
[exim.git] / src / src / auths / spa.c
index 31451344e544a14f7c33329cc04168ec60439e17..70b6737904c116c883ced32c3f99765426db9592 100644 (file)
@@ -1,10 +1,10 @@
-/* $Cambridge: exim/src/src/auths/spa.c,v 1.1 2004/10/07 13:10:01 ph10 Exp $ */
+/* $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 - 2004 */
+/* Copyright (c) University of Cambridge 1995 - 2007 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 /* This file, which provides support for Microsoft's Secure Password
@@ -25,8 +25,9 @@ References:
  * typedef unsigned uint32;
  * typedef unsigned char  uint8;
 
-07-August-2003: PH: Patched up the code to avoid assert bombouts for stupid
-                    input data. Find appropriate comment by grepping for "PH".
+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
 */
 
 
@@ -135,7 +136,7 @@ if (auth_get_no64_data(&data, US"NTLM supported") != OK)
   return FAIL;
   }
 
-if (spa_base64_to_bits((char *)(&request), (const char *)(data)) < 0)
+if (spa_base64_to_bits((char *)(&request), sizeof(request), (const char *)(data)) < 0)
   {
   DEBUG(D_auth) debug_printf("auth_spa_server(): bad base64 data in "
   "request: %s\n", data);
@@ -155,15 +156,13 @@ if (auth_get_no64_data(&data, msgbuf) != OK)
   }
 
 /* dump client response */
-if (spa_base64_to_bits((char *)(&response), (const char *)(data)) < 0)
+if (spa_base64_to_bits((char *)(&response), sizeof(response), (const char *)(data)) < 0)
   {
   DEBUG(D_auth) debug_printf("auth_spa_server(): bad base64 data in "
   "response: %s\n", data);
   return FAIL;
   }
 
-/* get username and put it in $1 */
-
 /***************************************************************
 PH 07-Aug-2003: The original code here was this:
 
@@ -194,10 +193,15 @@ that causes failure if the size of msgbuf is exceeded. ****/
 
 /***************************************************************/
 
-expand_nstring[1] = msgbuf;
+/* Put the username in $auth1 and $1. The former is now the preferred variable;
+the latter is the original variable. */
+
+auth_vars[0] = expand_nstring[1] = msgbuf;
 expand_nlength[1] = Ustrlen(msgbuf);
 expand_nmax = 1;
 
+debug_print_string(ablock->server_debug_string);    /* customized debug */
+
 /* look up password */
 
 clearpass = expand_string(ob->spa_serverpassword);
@@ -228,7 +232,9 @@ if (memcmp(ntRespData,
       ((unsigned char*)responseptr)+IVAL(&responseptr->ntResponse.offset,0),
       24) == 0)
   /* success. we have a winner. */
-  return OK;
+
+  /* Expand server_condition as an authorization check (PH) */
+  return auth_check_serv_cond(ablock);
 
 return FAIL;
 }
@@ -258,19 +264,14 @@ auth_spa_client(
        char *domain = NULL;
        char *username, *password;
 
-    if (smtp_write_command(outblock, FALSE, "AUTH %s\r\n",
-         ablock->public_name) < 0)
-               return FAIL_SEND;
-
-       /* wait for the 3XX OK message */
-       if (!smtp_read_response(inblock, (uschar *)buffer, buffsize, '3', timeout))
-               return FAIL;
-
        /* Code added by PH to expand the options */
 
+       *buffer = 0;    /* Default no message when cancelled */
+
        username = CS expand_string(ob->spa_username);
        if (username == NULL)
          {
+         if (expand_string_forcedfail) return CANCELLED;
          string_format(buffer, buffsize, "expansion of \"%s\" failed in %s "
            "authenticator: %s", ob->spa_username, ablock->name,
            expand_string_message);
@@ -280,6 +281,7 @@ auth_spa_client(
        password = CS expand_string(ob->spa_password);
        if (password == NULL)
          {
+         if (expand_string_forcedfail) return CANCELLED;
          string_format(buffer, buffsize, "expansion of \"%s\" failed in %s "
            "authenticator: %s", ob->spa_password, ablock->name,
            expand_string_message);
@@ -291,6 +293,7 @@ auth_spa_client(
          domain = CS expand_string(ob->spa_domain);
          if (domain == NULL)
            {
+           if (expand_string_forcedfail) return CANCELLED;
            string_format(buffer, buffsize, "expansion of \"%s\" failed in %s "
              "authenticator: %s", ob->spa_domain, ablock->name,
              expand_string_message);
@@ -300,6 +303,14 @@ auth_spa_client(
 
        /* Original code */
 
+    if (smtp_write_command(outblock, FALSE, "AUTH %s\r\n",
+         ablock->public_name) < 0)
+               return FAIL_SEND;
+
+       /* wait for the 3XX OK message */
+       if (!smtp_read_response(inblock, (uschar *)buffer, buffsize, '3', timeout))
+               return FAIL;
+
        DSPA("\n\n%s authenticator: using domain %s\n\n",
                ablock->name, domain);
 
@@ -321,7 +332,7 @@ auth_spa_client(
        /* convert the challenge into the challenge struct */
        DSPA("\n\n%s authenticator: challenge (%s)\n\n",
                ablock->name, buffer + 4);
-       spa_base64_to_bits ((char *)(&challenge), (const char *)(buffer + 4));
+       spa_base64_to_bits ((char *)(&challenge), sizeof(challenge), (const char *)(buffer + 4));
 
        spa_build_auth_response (&challenge, &response,
                CS username, CS password);