#include "mysccs.h"
SCCSID("@(#)errors.c   %E%   SAP   %I%")

static char * this_File GNU_UNUSED = __FILE__;

/************************************************************************/
/* $Id: //tools/src/freeware/gsstest/errors.c#5 $
 ************************************************************************
 *
 * Copyright (c) 1998-2000  SAP AG.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer. 
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. All advertising materials mentioning features or use of this
 *    software must display the following acknowledgment:
 *    "This product includes software developed by SAP AG"
 *
 * 4. The name "SAP AG" must not be used to endorse or promote products
 *    derived from this software without prior written permission.
 *    For written permission, please contact www.press@sap.com
 *
 * 5. Redistributions of any form whatsoever must retain the following
 *    acknowledgment:
 *    "This product includes software developed by SAP AG"
 *
 * THIS SOFTWARE IS PROVIDED BY SAP AG ``AS IS'' AND ANY EXPRESSED
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. SAP AG SHALL BE LIABLE FOR ANY DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE ONLY IF CAUSED BY SAP AG'S
 * INTENT OR GROSS NEGLIGENCE. IN CASE SAP AG IS LIABLE UNDER THIS
 * AGREEMENT FOR DAMAGES CAUSED BY SAP AG'S GROSS NEGLIGENCE SAP AG
 * FURTHER SHALL NOT BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT, AND SHALL NOT BE LIABLE IN EXCESS OF THE AMOUNT OF
 * DAMAGES TYPICALLY FORESEEABLE FOR SAP AG, WHICH SHALL IN NO EVENT
 * EXCEED US$ 500.000.- 
 *
 ************************************************************************/


#include "gsstest.h"


static gss_OID_desc  sapntlm_mech_oid = { 10, "\053\006\001\004\001\205\066\002\001\002"     };
static gss_OID_desc  sapntlm_nt_oid   = { 11, "\053\006\001\004\001\205\066\002\001\002\001" };


/*
 * error_tests()
 *
 *
 */
int
error_tests( DLL_GSSFP_T  * p_gssfp_ini,  DLL_GSSFP_T  * p_gssfp_acc )
{
   int    rc = 0;

   XVEB((V_SHOW, "====================\nTesting gss_display_status() major_status translations ...\n----------\n"));
   rc += errors_with_display_status( p_gssfp_ini );

   ignore_name_for_statistics = TRUE;

   XVEB((V_SHOW, "====================\nTesting error handling of name management functions ...\n----------\n"));
   rc += errors_with_names( p_gssfp_ini );

   XVEB((V_SHOW, "====================\nTesting error handling of credential management functions ...\n----------\n"));
   rc += errors_with_creds( p_gssfp_ini, p_gssfp_acc );

   XVEB((V_SHOW, "====================\nTesting error handling of context establishment functions ...\n----------\n"));
   rc += errors_with_contexts( p_gssfp_ini, p_gssfp_acc );

   ignore_name_for_statistics = FALSE;

   return(rc);

} /* error_tests() */


/*************************************************************************/
/*************************************************************************/
/**									**/
/**	    Test of gss_display_status() output                         **/
/**									**/
/*************************************************************************/
/*************************************************************************/

#define DSPNAME_TEST_ENTRY(x,y)	 { (OM_uint32) (x), #x, (y) }
#define DSPNAME_TEST_FINAL       { 0, 0, 0 }

static struct dspname_test_s dspname_test_routine[] = {
	 DSPNAME_TEST_ENTRY(GSS_S_COMPLETE,0),
	 DSPNAME_TEST_ENTRY(GSS_S_BAD_MECH,0),
	 DSPNAME_TEST_ENTRY(GSS_S_BAD_NAME,0),
	 DSPNAME_TEST_ENTRY(GSS_S_BAD_NAMETYPE,0),
	 DSPNAME_TEST_ENTRY(GSS_S_BAD_BINDINGS,0),
	 DSPNAME_TEST_ENTRY(GSS_S_BAD_STATUS,0),
	 DSPNAME_TEST_ENTRY(GSS_S_BAD_MIC,0),
	 DSPNAME_TEST_ENTRY(GSS_S_NO_CRED,0),
	 DSPNAME_TEST_ENTRY(GSS_S_NO_CONTEXT,0),
	 DSPNAME_TEST_ENTRY(GSS_S_DEFECTIVE_TOKEN,0),
	 DSPNAME_TEST_ENTRY(GSS_S_DEFECTIVE_CREDENTIAL,0),
	 DSPNAME_TEST_ENTRY(GSS_S_CREDENTIALS_EXPIRED,0),
	 DSPNAME_TEST_ENTRY(GSS_S_CONTEXT_EXPIRED,0),
	 DSPNAME_TEST_ENTRY(GSS_S_FAILURE,0),
	 DSPNAME_TEST_ENTRY(GSS_S_BAD_QOP,0),
	 DSPNAME_TEST_ENTRY(GSS_S_UNAUTHORIZED,0),
	 DSPNAME_TEST_ENTRY(GSS_S_UNAVAILABLE,0),
	 DSPNAME_TEST_ENTRY(GSS_S_DUPLICATE_ELEMENT,0),
	 DSPNAME_TEST_ENTRY(GSS_S_NAME_NOT_MN,0),
	 DSPNAME_TEST_FINAL
};

static struct dspname_test_s dspname_test_info[] = {
	 
	 DSPNAME_TEST_ENTRY(GSS_S_CONTINUE_NEEDED,0),
	 DSPNAME_TEST_ENTRY(GSS_S_DUPLICATE_TOKEN,0),
	 DSPNAME_TEST_ENTRY(GSS_S_OLD_TOKEN,0),
	 DSPNAME_TEST_ENTRY(GSS_S_UNSEQ_TOKEN,0),
	 DSPNAME_TEST_ENTRY(GSS_S_GAP_TOKEN,0),
	 DSPNAME_TEST_FINAL
};

static struct dspname_test_s dspname_test_calling[] = {
	 DSPNAME_TEST_ENTRY(GSS_S_CALL_INACCESSIBLE_READ,0),
	 DSPNAME_TEST_ENTRY(GSS_S_CALL_INACCESSIBLE_WRITE,0),
	 DSPNAME_TEST_ENTRY(GSS_S_CALL_BAD_STRUCTURE,0),
	 DSPNAME_TEST_FINAL
};

static struct dspname_test_s dspname_test_combined[] = {
	 DSPNAME_TEST_ENTRY((GSS_S_FAILURE|GSS_S_DUPLICATE_TOKEN),0),
	 DSPNAME_TEST_ENTRY((GSS_S_FAILURE|GSS_S_OLD_TOKEN),0),
	 DSPNAME_TEST_ENTRY((GSS_S_FAILURE|GSS_S_UNSEQ_TOKEN),0),
	 DSPNAME_TEST_ENTRY((GSS_S_FAILURE|GSS_S_GAP_TOKEN),0),
	 DSPNAME_TEST_ENTRY((GSS_S_CALL_INACCESSIBLE_READ|GSS_S_BAD_NAME),1),
	 DSPNAME_TEST_ENTRY((GSS_S_CALL_INACCESSIBLE_WRITE|GSS_S_DEFECTIVE_CREDENTIAL),1),
	 DSPNAME_TEST_ENTRY((GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_BINDINGS),1),
	 DSPNAME_TEST_FINAL
};

static struct dspname_test_s dspname_test_mean[] = {
	 DSPNAME_TEST_ENTRY((GSS_S_CALL_INACCESSIBLE_READ|GSS_S_DEFECTIVE_TOKEN|GSS_S_DUPLICATE_TOKEN),1),
	 DSPNAME_TEST_ENTRY((GSS_S_CALL_INACCESSIBLE_READ|GSS_S_DEFECTIVE_TOKEN|GSS_S_DUPLICATE_TOKEN|GSS_S_CONTINUE_NEEDED),1),
	 DSPNAME_TEST_ENTRY((GSS_S_CONTINUE_NEEDED|GSS_S_DUPLICATE_TOKEN|GSS_S_UNSEQ_TOKEN),1),
	 DSPNAME_TEST_ENTRY((0xfffffffful),1),
	 DSPNAME_TEST_ENTRY((0x04130020ul),1),
	 DSPNAME_TEST_ENTRY((0x10200800ul),1),
	 DSPNAME_TEST_FINAL
};


/*
 * test_for_real_message()
 *
 * Check whether there are any "printable" characters present
 * whitespace characters do not count as printables here.
 *
 * Return values:
 *   0 - at least one printable character found
 *   1 - no printable characters encountered
 */
int
test_for_real_message( Uchar  * p_src,  size_t  p_len )
{
   int     rc = 1;
   size_t  i;

   if ( p_src==NULL || p_len==0 ) {
      /* ERROR: No message at all */
      return(rc);
   }

   for ( i=0 ; i<p_len ; i++ ) {
      switch( p_src[i] ) {
	 case '\0':
	 case ' ':
	 case '\t':
	 case '\r':
	 case '\n':  break;

	 default:    rc = 0;
		     break;
      }
   }

   return(rc);

} /* test_for_real_message() */



#define MAX_MESSAGE_LINES   8
/*
 * test_display_status()
 *
 *
 */
int
test_display_status( int                      p_trclevel,      DLL_GSSFP_T   * p_gssfp,
		     struct dspname_test_s  * p_test_liste,    Ulong         * pp_maxlines,
		     size_t		    * pp_min_linelen,  size_t	     * pp_max_linelen,
		     size_t		    * pp_sum_linelen,  Ulong	     * pp_counter )
{
   char			  * this_Call GNU_UNUSED = "test_display_status";
   struct dspname_test_s  * test;
   char                   * lptr;
   char			  * msg;
   char			  * sepstr;
   int			    msg_len;
   int                      value_rejected;
   gss_buffer_desc          message[MAX_MESSAGE_LINES];
   OM_uint32		    maj_stat;
   OM_uint32		    context;
   int			    line;
   int			    i;
   int			    plen;
   int			    rc        = 0;
   int			    rci;

   for( test = p_test_liste; test->error_name!=NULL ; test++ ) {
      context = 0;
      if ( p_trclevel==1 ) {
	 XVEB((V_OK, p_trclevel, "  %-39.200s =>\n", test->error_name ));
      } else {
	 XVEB((V_OK, p_trclevel, "  gss_display_status(GSS_C_GSS_CODE, %.200s) returns\n",
		    test->error_name ));
      }

      line           = 0;
      value_rejected = FALSE;

      do {

	 message[line].value  = NULL;
	 message[line].length = 0;
	 rci = display_status( verbose_level, p_gssfp, test->status_value,
			       GSS_C_GSS_CODE, GSS_C_NO_OID, &context,
			       &(message[line]), &maj_stat );

	 if ( maj_stat==GSS_S_BAD_STATUS && test->may_fail!=FALSE ) {

	    value_rejected = TRUE;

	 } else {
	    rc += rci;

	 /* if ( message[line].value!=NULL && message[line].length>0 ) */
	    if ( pp_counter!=NULL ) { (*pp_counter)++; }
	    if ( pp_sum_linelen!=NULL ) { (*pp_sum_linelen) += message[line].length; }
	    if ( pp_min_linelen!=NULL
	         && ((*pp_min_linelen)==0 || message[line].length<(*pp_min_linelen)) ) {
	       (*pp_min_linelen) = message[line].length;
	    }
	    if ( pp_max_linelen!=NULL && message[line].length > (*pp_max_linelen) ) {
	       /* memorize new maximum line length */
	       (*pp_max_linelen) = message[line].length;
	    }

	 }

	 line++;

      } while ( GSS_ERROR(maj_stat)==GSS_S_COMPLETE && context!=0 && line<MAX_MESSAGE_LINES);

      for ( i=0 ; i<line ; i++ ) {

	 msg     = (char *) message[i].value;
	 msg_len = (int)    message[i].length;
	 sepstr  = "\"";

	 if ( i+1==line ) {
	    lptr = "  ________" "__________" "__________";
	 } else {
	    lptr = "          " "          " "          ";
	 }

	 if ( value_rejected!=FALSE ) {
	    msg           = "    ---GSS_S_BAD_STATUS---";
	    msg_len       = (int)strlen(msg);
	    sepstr        = "";
	 } else if ( test_for_real_message( (Uchar *)msg, msg_len )==1 ) {
	    if ( (test->status_value)==GSS_S_COMPLETE ) {
	       /* allow empty string for GSS_S_COMPLETE */
	       msg        = "    ---Empty String---";
	    } else {
	       msg        = "    ---!! MISSING !!---";
	       rc++;
	    }
	    msg_len = (int)strlen(msg);
	    sepstr  = "";
	 }

	 plen = (msg_len<48) ? 28 : (msg_len>72) ? 6 : 76 - msg_len;

	 XVEB((V_OK, p_trclevel, "%.*s%s%.*s%s\n", plen, lptr, sepstr, msg_len, msg, sepstr ));
         rc += release_buffer( p_gssfp, &(message[i]) );
      }

      if ( pp_maxlines!=NULL && (Ulong)line>(*pp_maxlines) ) {
	 (*pp_maxlines) = (Ulong)line;
      }

   }

   return(rc);
   
} /* test_display_status() */




/*
 * errors_with_display_status()
 *
 *
 */
int
errors_with_display_status( DLL_GSSFP_T  * p_gssfp )
{
   int    rc  = 0;
   int    rci = 0;

   XVEB((V_TEST, "Testing gss_display_status() for routine errors:\n"));
   rci = test_display_status( verbose_level+1, p_gssfp, &(dspname_test_routine[0]),
			      &(p_gssfp->dspstat_one_max_lines),
			      &(p_gssfp->dspstat_one_min_linelen),
			      &(p_gssfp->dspstat_one_max_linelen),
			      &(p_gssfp->dspstat_one_sum_linelen),
			      &(p_gssfp->dspstat_one_counter) );
   XVEB((V_RESULT, rci, 0, NULL ));
   rc += rci;

   XVEB((V_TEST, "Testing gss_display_status() for informational status:\n"));
   rci = test_display_status( verbose_level+1, p_gssfp, &(dspname_test_info[0]),
			      &(p_gssfp->dspstat_one_max_lines),
			      &(p_gssfp->dspstat_one_min_linelen),
			      &(p_gssfp->dspstat_one_max_linelen),
			      &(p_gssfp->dspstat_one_sum_linelen),
			      &(p_gssfp->dspstat_one_counter) );
   XVEB((V_RESULT, rci, 0, NULL ));
   rc += rci;

   XVEB((V_TEST, "Testing gss_display_status() for calling errors:\n"));
   rci = test_display_status( verbose_level+1, p_gssfp, &(dspname_test_calling[0]),
			      &(p_gssfp->dspstat_one_max_lines),
			      &(p_gssfp->dspstat_one_min_linelen),
			      &(p_gssfp->dspstat_one_max_linelen),
			      &(p_gssfp->dspstat_one_sum_linelen),
			      &(p_gssfp->dspstat_one_counter) );
   XVEB((V_RESULT, rci, 0, NULL ));
   rc += rci;


   XVEB((V_TEST, "Testing gss_display_status() for status value combinations:\n"));
   rci = test_display_status( verbose_level+1, p_gssfp, &(dspname_test_combined[0]),
			      &(p_gssfp->dspstat_two_max_lines),
			      &(p_gssfp->dspstat_two_min_linelen),
			      &(p_gssfp->dspstat_two_max_linelen),
			      &(p_gssfp->dspstat_two_sum_linelen),
			      &(p_gssfp->dspstat_two_counter) );
   XVEB((V_RESULT, rci, 0, NULL ));
   rc += rci;

   XVEB((V_TEST, "Testing gss_display_status() for mean/invalid value combinations:\n"));
   rci = test_display_status( verbose_level+1, p_gssfp, &(dspname_test_mean[0]), NULL, NULL, NULL, NULL, NULL );
   XVEB((V_RESULT, rci, 0, NULL ));
   rc += rci;

   return(rc);

} /* errors_with_display_status() */


char  * bad_target_name = 0;

struct bad_name_list_s {
   int     has_whitespace;
   int     name_ok;
   int     ini_cred_ok;
   int	   acc_cred_ok;
   char  * name;
} bad_name_list[] = {
   { 0, 0, 0, 0, "XXXXXXXX"		     },
   { 0, 0, 0, 0, "CBA/ZYX"		     },
   { 0, 0, 0, 0, "CBA\\ZYX"		     },
   { 0, 0, 0, 0, "CBA@ZYX"		     },
   { 0, 0, 0, 0, "CBA@"			     },
   { 0, 0, 0, 0, "XY\tZ"		     },
   { 0, 0, 0, 0, "AB C"			     },
   { 0, 0, 0, 0, "A B C\tD"		     },
   { 0, 0, 0, 0, "A@B@C@X"		     },
   { 0, 0, 0, 0, "A@@@@@@Z"		     },
   { 0, 0, 0, 0, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" },
   { 0, 0, 0, 0, "a,b,c,d"		     },
   { 0, 0, 0, 0, "A/B/C/D"		     },
   { 0, 0, 0, 0, "D\\C\\B\\A"		     },

   { 0, 0, 0, 0, "CN=A1a,OU=Bb  ,O  = Cc,     C   =ES" },
   { 0, 0, 0, 0, "CN=A2a, OU=Cb, O=Dc, C=ES" },	   /* syntactically correct X.500 DN, RDNs seperated by ", ", uppercase RDN tags */
   { 0, 0, 0, 0, "cn=A3a, ou=Cb, o=Dc, c=ES" },	   /* syntactically correct X.500 DN, RDNs seperated by ", ", lowercase RDN tags */
   { 0, 0, 0, 0, "CN=A4a; OU=Yb; O=Xc; C=ES" },	   /* syntactically correct X.500 DN, RDNs seperated by "; ", uppercase RDN tags */
   { 0, 0, 0, 0, "cn=A5a; ou=Cb; o=Dc; c=ES" },	   /* syntactically correct X.500 DN, RDNs seperated by "; ", lowercase RDN tags */
   { 0, 0, 0, 0, "CN=A6a, OU=Cb, O=Dc"	     },	   /* test for missing C=  (uppercase RDN tags) */
   { 0, 0, 0, 0, "cn=A7a, ou=cb, o=Dc"	     },	   /* test for missing c=  (lowercase RDN tags) */
   { 0, 0, 0, 0, "C=ES, O=Cc,   OU = Bb,CN=A8a" },	   /* reversed DN, additional whitespace (check whether parser uses canonical RDN order) */
   { 0, 0, 0, 0, "OU=H, C=ES, CN=A9a, O=J"   },	   /* reorderd DN */
   { 0, 0, 0, 0, "CN=A10a, OU=C, O=D, CN=Bb, C=ES"	 },/* double CN= RDN */
   { 0, 0, 0, 0, "CN=A11a, OU=C, O=D, OU=F, CN=Bb, OU=G, C=ES" }, /* double CN= plus triple OU= RDNs */

   { 0, 0, 0, 0, "CN=A12a, OU=C, O=D, C=ES," },	   /* syntax error: trailing comma,     RDNs seperated by ", " */
   { 0, 0, 0, 0, "CN=A13a; OU=Y; O=X; C=ES;" },	   /* syntax error: trailing semicolon, RDNs seperated by "; " */
   { 0, 0, 0, 0, "CN = A14a , OU=T;O =U, C= ES" },	   /* mixing seperators ";" and ",", uneven whitespace between RDNs */
   { 0, 0, 0, 0, "CN=A15a,, OU=Z,O=Y,, ,C=ES"   },	   /* syntax error: repeated comma     seperators (missing RDNs) */
   { 0, 0, 0, 0, "CN=A16a;; OU=T;O=S;; ;C=ES"   },	   /* syntax error: repeated semicolon seperators (missing RDNs) */
   { 0, 0, 0, 0, "CN=, O=X17a,C=ES"	     },	   /* syntax error: CN= missing RDN value */
   { 0, 0, 0, 0, "CN=A18a, O=Z, C="	     },	   /* syntax error: C= missing RDN value */
   { 0, 0, 0, 0, "FOO=A19a, O=Z, C=ES"	     },	   /* additional (non-standard) RDNs */
   { 0, 0, 0, 0, "BAR=, O=Z20a, C=ES"	     },	   /* syntax error: additional (non-standard) RDN is lacking a value */
   { 0, 0, 0, 0, "FOO=BAR=O, O=Z21a, C=ES"   },	   /* syntax error: value contains unescaped "=" */
   { 0, 0, 0, 0, "CN=A22c, O=Z, C=E"	     },	   /* syntax error: C= is not a valid 2-letter ISO country code */
   { 0, 0, 0, 0, "CN=A23c, O=Z, C=ES, C=US"  },    /* double Country RDN C= */
   { 0, 0, 0, 0, "cn=A24a, o=z, c=es"        },    /* lowercase Country RDN attribute */
   { 0, 0, 0, 0, "CN=A25a, O=ACME Puter, C=ES"  },    /* unquoted whitespace in O= RDN */
   { 0, 0, 0, 0, "CN=A26a, O=\"ACME Puter\", C=ES" },  /* quoted simple whitespace in O= RDN */
   { 0, 0, 0, 0, "CN=A27a, O=\"ACME Puter, Inc.\", C=ES" }, /* quoted seperator and whitespace in O= RDN */
   { 0, 0, 0, 0, "CN=A28a, 0=ACME, C=ES"     },    /* typo in O= prefix, using "0" instead of "O" */
   { 0, 0, 0, 0, "OID.2.5.4.3=A29a, C=ES"   },    /* OID-prefix instead of CN= */
   { 0, 0, 0, 0, "CN=A30a, OID.1.2.840.113549.1.9.1=foo@bar.com, C=ES" }, /* OID-prefix for EMAIL= */
   { 0, 0, 0, 0, "CN=A31a, ST=CA, STREET=somestreet, C=US" }, /* DName components ST and STREET */
   { 0, 0, 0, 0, "CN=A32a, SP=SP, C=DE"      },    /* DName component SP */
   { 0, 0, 0, 0, "2.5.4.3=A33a, O=Z, C=ES"   },    /* exotic x.y.z OID-encoding of Prefix */
   { 0, 0, 0, 0, "CN=A34a, 2.5.4.10=#1303416243, C=ES" },  /* numericoid plus Hex Encoding (rfc4514) */
   { 0, 0, 0, 0, "CN=A35a, O=#04024566, C=ES" },           /* Hex Encoding (rfc4514) */
   { 0, 0, 0, 0, "CN=A36a, O=#13024566, C=ES" },           /* Hex Encoding (rfc4514) */
   { 0, 0, 0, 0, "CN=A37a, O=\\58\\59\\5A, C=ES" },           /* Hex Escape (rfc4514)  */
   { 0, 0, 0, 0, "CN=A38a, O=A\\<B\\>C\\,\\;\\\"\\'\\+\\ \\\\\\#\\=Hi\\ , C=ES" }, /* SpecialChar Escapes (rfc4514) */
   { 0, 0, 0, 0, "CN=A39a, O=Hello-\xc3\xb6\xc3\xA4\xC3\xbc\xc3\x96\xc3\x84\xc3\x9c\xc3\x9f-umlauts, C=ES" }, /* UTF-8 Umlauts */
   { 0, 0, 0, 0, "CN=A40a, O=Foo{Bar}, OU=[Uh]-(oh), C=ES" }, /* braces,brackets,parentheses */
   { 0, 0, 0, 0, "CN=A41a, 2.5.4.14=FOObar, C=ES" }, /* uncommon DName component */
   { 0, 0, 0, 0, "CN=A42a, O=Foo/baR, C=ES"  },    /* RDN with forward slash char */

   { 1, 0, 0, 0, " cn=W01a, o=z,  c=ES"      },    /* leading (white)space */
   { 1, 0, 0, 0, "cn=W02a,  o=z, c=ES "      },    /* trailing (white)space */
   { 1, 0, 0, 0, "\tcn=W03a,o=z,  c=ES"      },   /* leading whitespace/tab */
   { 1, 0, 0, 0, "cn=W04a,  o=z,c=ES\t"      },   /* trailing whitespace/tab */
   
   { 0, 0, 0, 0, "/CN=B01a/OU=Db/O=Ec/C=ES"  },	   /* OpenSSL-style X.500 DN */
   { 0, 0, 0, 0, "/C=ES/O=Fc/OU=Eb/CN=B02a"  },	   /* OpenSSL-style reversed X.500 DN */
   { 0, 0, 0, 0, "/OU=E/C=ES/CN=B03b/O=G"    },	   /* OpenSSL-style reorderd X.500 DN */
   { 0, 0, 0, 0, "/C=ES/O=Fc/OU=Eb/OU=Ec/CN=B04a"  }, /* OpenSSL-style reversed X.500 DN, doubled OU= RDN */
   { 0, 0, 0, 0, "/C=ES/O=Fc/OU=Eb/CN=Ab/CN=B05a"  }, /* OpenSSL-style reversed X.500 DN, doubled CN= RDN */
   { 0, 0, 0, 0, "/C=ES/O=Fc//OU=Eb/CN=B06a" },	   /* OpenSSL-style reversed X.500 DN, repeated / seperator */
   { 0, 0, 0, 0, "/C=ES/O=Fc/OU=/CN=B07a"    },	   /* OpenSSL-style reversed X.500 DN, missing OU= RDN value */
   { 0, 0, 0, 0, "/C=ES/O=Fc/FOO=BAR/OU=Eb/CN=B08a" },/* OpenSSL-style reversed X.500 DN, additional non-standard RDN */
   { 0, 0, 0, 0, "/C=ES/O=Fc/FOO=/OU=Eb/CN=B09a" },
   { 0, 0, 0, 0, "/O=Eb/OU=Fc/CN=B10a"	     },	   /* OpenSSL-style X.500DN, no C= RDN value */
   { 0, 0, 0, 0, "/CN=B11a/OU=Fc/O=Eb"	     },	   /* OpenSSL-style reversed X.500DN, no C= RDN value */ 
   { 0, 0, 0, 0, "/C=ES/O=Foo{[(Bar)]}/CN=B12a"	}, /* OpenSSL-style X.500DN, braces,bracket,parentheses value */
   { 0, 0, 0, 0, "/C=ES/O=Foo\\/Bar/CN=B13a"	}, /* OpenSSL-style X.500DN with forward-slash */ 
   { 0, 0, 0, 0, "/C=ES/O=#13024566/CN=B14a" },	   /* OpenSSL-style X.500DN, with hex encoded attribute value  */ 
   { 0, 0, 0, 0, "/C=ES/2.5.4.14=FOObar/CN=B15a" }, /* OpenSSL-style reversed X.500DN, no C= RDN value */ 

   { 0, 0, 0, 0, "A:B%C/D\\E+F-G@H"	     },
   { 0, 0, 0, 0, "A@B:C%D/E\\F+G-H"	     },
   { 0, 0, 0, 0, "@"			     },
   { 0, 0, 0, 0, ","			     },
   { 0, 0, 0, 0, "/"			     },
   { 0, 0, 0, 0, "/@"			     },
   { 0, 0, 0, 0, "\\"			     },
   { 0, 0, 0, 0, ""			     },
   { 0, 0, 0, 0, 0			     }
};


#define NAME_TESTS_WITH_NAMETYPE    NULL
/* #define NAME_TESTS_WITH_NAMETYPE   (p_gssfp->can_nametype) */

/*
 * errors_with_names()
 *
 *
 */
int
errors_with_names( DLL_GSSFP_T   * p_gssfp )
{
   char             * this_Call GNU_UNUSED = "errors_with_names";
   char             * bad_name;
   gss_name_t         name1     = GSS_C_NO_NAME;
   gss_name_t         name2     = GSS_C_NO_NAME;
   gss_name_t	      name2a    = GSS_C_NO_NAME;
   gss_name_t	      name3     = GSS_C_NO_NAME;
   size_t             bad_name_len;
   unsigned int       ui;
   OM_uint32	      maj_stat;
   OM_uint32	      maj_stata;
   int		      removes_whitespace = FALSE;
   int		      i;
   int		      sp_count;
   int		      orig_sp_count;
   int		      rci       = 0;
   int		      rcia	= 0;
   int                rc        = 0;

   XVEB((V_TEST, "Feeding gss_import_name() with a mech_oid nametype\n"));
   rci = import_and_canonicalize( verbose_level, p_gssfp,
				  p_gssfp->acceptor, p_gssfp->acceptor_len,
				  &sapntlm_mech_oid, &name1, &maj_stat );
   if ( maj_stat==GSS_S_BAD_NAMETYPE ) {
      rci = (rci>0) ? rci - 1 : rci;
   } else {
      rci++;
      XVEB((V_ERR, "gss_import_name() FAILED to return GSS_S_BAD_NAMETYPE!\n" ));
   }
   XVEB((V_RESULT, rci, 0, NULL ));
   rc += rci;

   for( i = 0 ; (bad_name = (bad_name_list[i].name))!=0 ; i++ ) {
      bad_name_list[i].name_ok = FALSE;
      bad_name_len = strlen(bad_name);
      for ( orig_sp_count=0,ui=0 ; ui<bad_name_len ; ui++ ) {
	  if ( bad_name[ui]==' ' ) {
	      orig_sp_count++;
	  }
      }

      if ( bad_name_list[i].has_whitespace!=0 && removes_whitespace==FALSE ) {
	  /* skip name patterns with leading and trailing whitespace    */
	  /* for mechanisms that didn't remove spaced from any previous */
	  /* name patterns (otherwise a failed SAP constraint will      */
	  /* later be counted)						*/
	  continue;
      }

      XVEB((V_TEST, "Trying gss_import_name() with \"%s\"\n", bad_name ));
      rci  = import_and_canonicalize( verbose_level, p_gssfp,
				      bad_name, bad_name_len,
				      NULL, &name2, &maj_stat );
      if ( maj_stat==GSS_S_COMPLETE ) {
         rcia = import_and_canonicalize( verbose_level, p_gssfp,
				         bad_name, bad_name_len,
				         (p_gssfp->can_nametype), &name2a, &maj_stata );
	 if ( maj_stata!=GSS_S_COMPLETE ) {
	    XVEB((V_SHOW, "*ERROR*: gss_import_name(nametype==NULL) works but gss_import_name(nametype=can) fails!\n"));
	    rci++;
	 }
	 if ( strlen(bad_name)==0 ) {
	    XVEB((V_SHOW, "HUH?!  Empty name accepted? This looks suspicious!\n"));
	 }
	 bad_name_list[i].name_ok = TRUE;
	 rci += name_transform_xp( verbose_level, p_gssfp, name2, &name3, &maj_stat );
	 rci += print_name( 1, p_gssfp, "parses to", (name3!=GSS_C_NO_NAME) ? name3 : name2, &sp_count, NULL, &maj_stat );
	 if ( bad_target_name==NULL ) {
	    bad_target_name = bad_name;
	 }
	 if ( sp_count<orig_sp_count ) {
	     removes_whitespace = TRUE;
	 }
      } else if ( maj_stat==GSS_S_BAD_NAME || maj_stat==GSS_S_FAILURE ) {
	 /* I would prefer GSS_S_BAD_NAME, but GSS_S_FAILURE is also acceptable, */
	 /* depending on underlying functions that generate the error            */
	 rci = (rci>0) ? rci - 1 : rci;
      } else {
	 XVEB((V_ERR, "gss_import_name() didn't return GSS_S_BAD_NAME or GSS_S_FAILURE!\n" ));
      }
      rci += release_name( p_gssfp, &name2  );
      rci += release_name( p_gssfp, &name2a );
      rci += release_name( p_gssfp, &name3  );

      XVEB((V_RESULT, rci, 0, NULL ));
      rc += rci;
   }

   rc += release_name( p_gssfp, &name1 );
   rc += release_name( p_gssfp, &name2 );

   return(rc);

}/* errors_with_names() */




/*
 * errors_with_creds()
 *
 *
 */
int
errors_with_creds( DLL_GSSFP_T   * p_gssfp_ini,   DLL_GSSFP_T   * p_gssfp_acc )
{
   char             * this_Call GNU_UNUSED = "errors_with_creds";
   char		    * bad_name;
   gss_name_t         ini_name   = GSS_C_NO_NAME;
   gss_name_t	      acc_name   = GSS_C_NO_NAME;
   gss_name_t	      ini_name_i = GSS_C_NO_NAME;
   gss_name_t	      acc_name_i = GSS_C_NO_NAME;
   gss_OID_set_desc   mech_set;
   gss_cred_id_t      ini_cred  = GSS_C_NO_CREDENTIAL;
   gss_cred_id_t      acc_cred	= GSS_C_NO_CREDENTIAL;
   gss_cred_usage_t   usage;
   OM_uint32	      lifetime;
   OM_uint32	      maj_stat;
   int		      i;
   int		      rc        = 0;
   int		      rci       = 0;

   mech_set.elements = &sapntlm_nt_oid;
   mech_set.count    = 1;

   /****************************************************************/
   /* Testing gss_acquire_cred(initiator) for GSS_S_BAD_MECH       */
   /****************************************************************/
   XVEB((V_TEST, "Feeding gss_acquire_cred(INITIATE) with a single nametype-OID mech_set\n"));
   rci = acquire_cred( verbose_level, p_gssfp_ini, GSS_C_INITIATE, GSS_C_NO_NAME,
			&mech_set, &ini_cred, NULL, 0, &maj_stat );

   if ( maj_stat==GSS_S_BAD_MECH ) {
      rci = (rci>0) ? rci - 1 : rci;
   } else { 
      rci++;
      XVEB((V_ERR, "gss_acquire_cred(INITIATE) failed to return GSS_S_BAD_MECH!\n"));
   } 
   XVEB((V_RESULT, rci, 0, NULL ));
   rc += rci;

   rc += release_cred( p_gssfp_ini, &ini_cred );


   /****************************************************************/
   /* Testing gss_acquire_cred(acceptor) for GSS_S_BAD_MECH        */
   /****************************************************************/
   if ( p_gssfp_acc->acc_name!=GSS_C_NO_NAME ) {
      XVEB((V_TEST, "Feeding gss_acquire_cred(ACCEPT) with a single nametype-OID mech_set\n"));
      rci = acquire_cred( verbose_level, p_gssfp_acc, GSS_C_ACCEPT, (p_gssfp_acc->acc_name),
			  &mech_set, &acc_cred, NULL, 0, &maj_stat );

      if ( maj_stat==GSS_S_BAD_MECH ) {
	 rci = (rci>0) ? rci - 1 : rci;
      } else { 
	 rci++;
	 XVEB((V_ERR, "gss_acquire_cred(ACCEPT) failed to return GSS_S_BAD_MECH!\n"));
      } 
      XVEB((V_RESULT, rci, 0, NULL ));
      rc += rci;

   } /* gss_fp->acc_name!=GSS_C_NO_NAME */


   rc += release_cred( p_gssfp_acc, &acc_cred );


   if ( bad_target_name==NULL ) {

      XVEB((V_SHOW, "  Sorry, I don't have a bad target name for this test!\n"));
      rc++;

   } else {

      mech_set.elements = (p_gssfp_ini->mech);
      mech_set.count    = 1;

      for ( i=0 ; bad_name_list[i].name!=NULL ; i++ ) {

	 bad_name_list[i].ini_cred_ok = FALSE;

	 if ( bad_name_list[i].name_ok == FALSE )
	    continue;

	 bad_name = bad_name_list[i].name;
	 /***************************************************************************/
	 /* Testing gss_acquire_cred() for GSS_S_NO_CRED                            */
	 /* (this may cause a GSS_S_BAD_NAME by gss_import_name() already)          */
	 /***************************************************************************/
	 XVEB((V_TEST, "Trying gss_acquire_cred(INITIATE) for \"%.128s\"\n", bad_name));
	 rci = import_name(verbose_level, p_gssfp_ini, bad_name, strlen(bad_name),
			   NAME_TESTS_WITH_NAMETYPE, &ini_name, &maj_stat);
	 if ( ini_name!=GSS_C_NO_NAME ) {
	    rci += acquire_cred( verbose_level, p_gssfp_ini, GSS_C_INITIATE, ini_name,
				 &mech_set, &ini_cred, NULL, 0, &maj_stat );
	    if ( maj_stat==GSS_S_COMPLETE ) {
	       XVEB((V_SHOW, "  Hmmm ... gss_acquire_cred(INITIATE) happily accepted name \"%.128s\"\n",
		             bad_name ));
	       if ( ini_cred!=GSS_C_NO_CREDENTIAL ) {
		  bad_name_list[i].ini_cred_ok = TRUE;
		  rci += inquire_cred( verbose_level, p_gssfp_ini, ini_cred, CTX_INITIATOR,
				       &ini_name_i, &lifetime, &usage, NULL, &maj_stat );
		  if ( ini_name_i!=GSS_C_NO_NAME ) {
		     rci += print_name( 1, p_gssfp_ini, "cred owner resolves to", ini_name_i, NULL, NULL, &maj_stat );
		     rci += verify_same_name( 1, p_gssfp_ini, "", "requested name", ini_name,
							          "actual cred owner", ini_name_i );
		     rci += verify_same_aclkey( 1, "", "requested name", TRUE, p_gssfp_ini, ini_name,
						       "actual cred owner", TRUE, p_gssfp_ini, ini_name_i );
		     rci += release_name( p_gssfp_ini, &ini_name_i );
		  }
	       }

	    } else {

	       switch(maj_stat) {
		  case GSS_S_NO_CRED:	    /* good error code */
		  case GSS_S_FAILURE:	    /* ok error code */
		  case GSS_S_BAD_NAME:	    /* acceptable error code */
		  case GSS_S_BAD_NAMETYPE:  /* acceptable error code */
			   rci = (rci>0) ? rci - 1 : rci;
			   break;

		  case GSS_S_BAD_MECH:
			   XVEB((V_SHOW, "gss_acquire_cred(INITIATE) SHOULD NOT fail here with GSS_S_BAD_MECH!\n"));
			   break;

		  case GSS_S_CREDENTIALS_EXPIRED:
		  default:
			   XVEB((V_ERR, "gss_acquire_cred(INITIATE) is expected to fail with one of\n"));
			   XVEB((V_SHOW,"\t GSS_S_NO_CRED, GSS_FAILURE, GSS_S_BAD_NAME\n"));
			   break;
	       }
	    }

	 } else {

	    XVEB((V_ERR, "gss_import_name() FAILED? But it worked the first time!\n"));
	    rci++;

	 }

	 rci += release_name( p_gssfp_ini, &ini_name );
	 rci += release_cred( p_gssfp_ini, &ini_cred );

	 XVEB((V_RESULT, rci, 0, NULL ));
	 rc += rci;

      }

   } /* bad_target_name!=NULL */


   if ( bad_target_name==NULL ) {

      XVEB((V_SHOW, "  Sorry, I don't have a bad target name for this test!\n"));
      rc++;

   } else {

      for ( i=0 ; bad_name_list[i].name!=NULL ; i++ ) {

	 bad_name_list[i].acc_cred_ok = FALSE;

	 if ( bad_name_list[i].name_ok == FALSE )
	    continue;

	 bad_name = bad_name_list[i].name;
	 /***************************************************************************/
	 /* Testing gss_acquire_cred() for GSS_S_NO_CRED                            */
	 /* (this may cause a GSS_S_BAD_NAME by gss_import_name() already)          */
	 /***************************************************************************/
	 XVEB((V_TEST, "Trying gss_acquire_cred(ACCEPT) for \"%.128s\"\n",
		       bad_name ));
	 rci = import_name(verbose_level, p_gssfp_acc, bad_name, strlen(bad_name),
			   NAME_TESTS_WITH_NAMETYPE, &acc_name, &maj_stat);
	 if ( acc_name!=GSS_C_NO_NAME ) {
	    rci += acquire_cred( verbose_level, p_gssfp_acc, GSS_C_ACCEPT, acc_name,
				 &mech_set, &acc_cred, NULL, 0, &maj_stat );
	    if ( maj_stat==GSS_S_COMPLETE ) {
	       XVEB((V_SHOW, "  Hmmm ... gss_acquire_cred() happily accepted name \"%.128s\"\n",
			     bad_name ));
	       if ( acc_cred!=GSS_C_NO_CREDENTIAL ) {
		  bad_name_list[i].acc_cred_ok = TRUE;
		  rci += inquire_cred( verbose_level, p_gssfp_acc, acc_cred, CTX_ACCEPTOR,
				       &acc_name_i, &lifetime, &usage, NULL, &maj_stat );
		  if ( acc_name_i!=GSS_C_NO_NAME ) {
		     rci += print_name( 1, p_gssfp_acc, "cred owner resolves to", acc_name_i, NULL, NULL, &maj_stat );
		     rci += verify_same_name( 1, p_gssfp_acc, "", "requested name", acc_name,
							          "actual cred owner", acc_name_i );
		     rci += verify_same_aclkey( 1, "", "requested name", TRUE, p_gssfp_acc, acc_name,
						       "actual cred owner", TRUE, p_gssfp_acc, acc_name_i );
		     rci += release_name( p_gssfp_acc, &acc_name_i );
		  }
	       }

	    } else {
	       
	       switch(maj_stat) {
		  case GSS_S_NO_CRED:	    /* good error code */
		  case GSS_S_FAILURE:	    /* ok error code */
		  case GSS_S_BAD_NAME:	    /* acceptable error code */
		  case GSS_S_BAD_NAMETYPE:  /* acceptable error code */
			   rci = (rci>0) ? rci - 1 : rci;
			   break;

		  case GSS_S_BAD_MECH:
			   XVEB((V_SHOW, "gss_acquire_cred(ACCEPT) SHOULD NOT fail here with GSS_S_BAD_MECH!\n"));
			   break;

		  case GSS_S_CREDENTIALS_EXPIRED:
		  default:
			   XVEB((V_ERR, "gss_acquire_cred(ACCEPT) is expected to fail with one of\n"));
			   XVEB((V_SHOW,"\t GSS_S_NO_CRED, GSS_FAILURE, GSS_S_BAD_NAME\n"));
			   break;
	       }
	    }

	 } else {

	    if ( p_gssfp_acc!=p_gssfp_ini ) {
	       /* We only tested import for the initiator,              */
	       /* so don't fail here when running with 2 libraries      */
	       /* when the acceptor dislikes a name that the initiator  */
	       /* still accepted.					*/
	       rci = (rci>0) ? rci - 1 : rci;
	    } else {
	       XVEB((V_ERR, "gss_import_name() FAILED? But it worked the first time!\n"));
	       rci++;
	    }

	 }

	 rci += release_name( p_gssfp_acc, &acc_name );
	 rci += release_cred( p_gssfp_acc, &acc_cred );

	 XVEB((V_RESULT, rci, 0, NULL ));
	 rc += rci;

      }

   }

   rc += release_name( p_gssfp_acc, &acc_name   );
   rc += release_name( p_gssfp_acc, &acc_name_i );
   rc += release_name( p_gssfp_ini, &ini_name   );
   rc += release_name( p_gssfp_ini, &ini_name_i );
   rc += release_cred( p_gssfp_ini, &ini_cred   );
   rc += release_cred( p_gssfp_acc, &acc_cred   );

   return(rc);

} /* errors_with_creds() */




/*
 * errors_with_contexts()
 *
 *
 */
int
errors_with_contexts( DLL_GSSFP_T   * p_gssfp_ini, DLL_GSSFP_T   * p_gssfp_acc )
{
   char             * this_Call GNU_UNUSED = "errors_with_contexts";
   gss_name_t	      ini_target_name = GSS_C_NO_NAME;
   struct ctx_desc  * x_acc	      = NULL;
   struct ctx_desc  * x_ini           = NULL;
   char		    * bad_name;
   OM_uint32	      maj_stat;
   int		      match;
   int		      i;
   int		      rci	      = 0;
   int		      rc	      = 0;

   /* dropping this test for kerberos because it may result in false errors */
   /* on the Microsoft Windows platform (where context establishment might  */
   /* succeed where one would not expect it).                               */
   /* Instead, I have added a test with the krbtgt/REALM@REALM target name  */
   /* which should simulate the desired "Wrong principal in request"        */
   /* scenario more reliably.                                               */
   if ( 0==testing_kerberos && p_gssfp_ini->acceptor!=NULL  &&  p_gssfp_ini->acceptor_len>0 ) {

      rci = import_name( verbose_level, p_gssfp_ini,
			 p_gssfp_ini->acceptor, p_gssfp_ini->acceptor_len,
			 NAME_TESTS_WITH_NAMETYPE, &ini_target_name, &maj_stat );

      if ( ini_target_name!=GSS_C_NO_NAME
	   &&  p_gssfp_ini->ini_name!=GSS_C_NO_NAME ) {

	 rci += compare_names( verbose_level, p_gssfp_ini, ini_target_name,
			      (p_gssfp_ini->ini_name), &match, &maj_stat );

	 if ( maj_stat==GSS_S_COMPLETE  &&  match==FALSE ) {

	    XVEB((V_TEST, "Testing context establishment with target name \"%.*s\"\n",
			  (int)p_gssfp_ini->initiator_len, p_gssfp_ini->initiator ));

	    rci += sap_establish_context( verbose_level, SNC_CONTEXT_FLAGS, GSS_C_INDEFINITE,
					  p_gssfp_ini, p_gssfp_acc, &x_ini, &x_acc,
				          SNC_SIMPLE_CRED, SNC_GSSNAMED_CRED,
				          p_gssfp_ini->initiator, p_gssfp_ini->initiator_len,
					  &maj_stat );
	    if ( GSS_ERROR(maj_stat)==GSS_S_COMPLETE ) {
	       rci++; /* count this as an error */
	    }

	    rci += release_ctx_desc( &x_ini );
	    rci += release_ctx_desc( &x_acc );

	    XVEB((V_RESULT, rci, 0, NULL ));

	 } /* initiator name different from acceptor name */

      } /* have target and initiator name */

      rci += release_name( p_gssfp_ini, &ini_target_name );
      rc += rci;

   }

   if ( (testing_kerberos) && p_gssfp_ini->initiator && p_gssfp_ini->initiator_len>0 ) {
      char            * ptr;
      char              namebuf[1024];
      int               realm_len;
      int               name_len;

      /* we're testing with a Kerberos GSS-API mechanism			 */
      /* in order to provoke a "wrong Principal in Request" error situation, we  */
      /* try to compose the name of KDC principal and use it as a target name    */
      /* it is composed like this "krbtgt/REALM@REALM"				 */
      /* we start with "krbtgt", import_and_canonicalize, hoping to receive      */
      /* "krbtgt@REALM", i.e. the name of the default realm, which we parse out  */
      ptr = memchr( p_gssfp_ini->initiator, '@', p_gssfp_ini->initiator_len );
      if ( NULL!=ptr ) {
	 ptr += 1; /* move ptr past '@' at beginning of realm name */
	 realm_len = p_gssfp_ini->initiator_len - (ptr - p_gssfp_ini->initiator);
	 name_len  = sprintf( namebuf, "krbtgt/%.*s@%.*s",
			      realm_len, ptr, realm_len, ptr );

	 XVEB((V_TEST, "Testing context establishment with target name \"%.*s\"\n",
		      (int)name_len, namebuf ));

    	 rci += sap_establish_context( verbose_level, SNC_CONTEXT_FLAGS, GSS_C_INDEFINITE,
				       p_gssfp_ini, p_gssfp_acc, &x_ini, &x_acc,
				       SNC_SIMPLE_CRED, SNC_GSSNAMED_CRED,
				       namebuf, name_len, &maj_stat );
 	 if ( GSS_ERROR(maj_stat)==GSS_S_COMPLETE ) {
	     /* count this as an error */
	     rci++;
	 }

	 rci += release_ctx_desc( &x_ini );
	 rci += release_ctx_desc( &x_acc );

	 XVEB((V_RESULT, rci, 0, NULL ));
	 rc  += rci;

      } /* realm has been determined */

   } /* testing_kerberos with KDC principal as incorrect target */

   if ( bad_target_name==NULL ) {

      XVEB((V_SHOW, "  Sorry, I don't have BAD target names for further test!\n"));
      rc++;

   } else {

      for ( i=0 ; bad_name_list[i].name!=NULL ; i++ ) {

	 if ( (bad_name_list[i].name_ok)==FALSE )
	    continue;

	 bad_name = bad_name_list[i].name;

	 XVEB((V_TEST, "Trying context establishment with target \"%.128s\"\n",
		       bad_name ));

	 rci = sap_establish_context( verbose_level, SNC_CONTEXT_FLAGS, GSS_C_INDEFINITE,
				      p_gssfp_ini, p_gssfp_acc, &x_ini, &x_acc,
				      SNC_SIMPLE_CRED, SNC_GSSNAMED_CRED,
				      bad_name, strlen(bad_name), &maj_stat );

	 if ( GSS_ERROR(maj_stat)!=GSS_S_COMPLETE ) {
	   /*  rci = (rci>0) ? rci-1 : rci ; */
	 }

	 rci += release_ctx_desc( &x_ini );
	 rci += release_ctx_desc( &x_acc );

	 XVEB((V_RESULT, rci, 0, NULL ));
	 rc += rci;

      }


      for ( i=0 ; bad_name_list[i].name!=NULL ; i++ ) {

	 if ( (bad_name_list[i].ini_cred_ok)==FALSE )
	    continue;

	 bad_name = bad_name_list[i].name;

	 XVEB((V_TEST, "Trying context establishment with initiator cred for \"%.128s\"\n",
		       bad_name ));

	 rci = sap_establish_context( verbose_level, SNC_CONTEXT_FLAGS, GSS_C_INDEFINITE,
				      p_gssfp_ini, p_gssfp_acc, &x_ini, &x_acc,
				      SNC_MISNAMED_CRED, SNC_GSSNAMED_CRED,
				      (p_gssfp_ini->acceptor), (p_gssfp_ini->acceptor_len), &maj_stat );

	 if ( GSS_ERROR(maj_stat)!=GSS_S_COMPLETE ) {
	   /*  rci = (rci>0) ? rci-1 : rci ; */
	 }

	 rci += release_ctx_desc( &x_ini );
	 rci += release_ctx_desc( &x_acc );

	 XVEB((V_RESULT, rci, 0, NULL ));
	 rc += rci;

      }


      for ( i=0 ; bad_name_list[i].name!=NULL ; i++ ) {

	 if ( (bad_name_list[i].acc_cred_ok)==FALSE )
	    continue;

	 bad_name = bad_name_list[i].name;

	 XVEB((V_TEST, "Trying context establishment with acceptor cred for \"%.128s\"\n",
		       bad_name ));

	 rci = sap_establish_context( verbose_level, SNC_CONTEXT_FLAGS, GSS_C_INDEFINITE,
				      p_gssfp_ini, p_gssfp_acc, &x_ini, &x_acc,
				      SNC_SIMPLE_CRED, SNC_MISNAMED_CRED,
				      (p_gssfp_ini->acceptor), (p_gssfp_ini->acceptor_len), &maj_stat );

	 if ( GSS_ERROR(maj_stat)!=GSS_S_COMPLETE ) {
	   /*  rci = (rci>0) ? rci-1 : rci ; */
	 }

	 rci += release_ctx_desc( &x_ini );
	 rci += release_ctx_desc( &x_acc );

	 XVEB((V_RESULT, rci, 0, NULL ));
	 rc += rci;

      }

   }


   return(rc);

} /* errors_with_contexts() */
