/ lib / gssapi / test_cred.c
test_cred.c
  1  /*
  2   * Copyright (c) 2003-2004 Kungliga Tekniska Högskolan
  3   * (Royal Institute of Technology, Stockholm, Sweden).
  4   * All rights reserved.
  5   *
  6   * Redistribution and use in source and binary forms, with or without
  7   * modification, are permitted provided that the following conditions
  8   * are met:
  9   *
 10   * 1. Redistributions of source code must retain the above copyright
 11   *    notice, this list of conditions and the following disclaimer.
 12   *
 13   * 2. Redistributions in binary form must reproduce the above copyright
 14   *    notice, this list of conditions and the following disclaimer in the
 15   *    documentation and/or other materials provided with the distribution.
 16   *
 17   * 3. Neither the name of KTH nor the names of its contributors may be
 18   *    used to endorse or promote products derived from this software without
 19   *    specific prior written permission.
 20   *
 21   * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
 22   * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 23   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 24   * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
 25   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 26   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 27   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 28   * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 29   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 30   * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 31   * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 32   */
 33  
 34  #ifdef HAVE_CONFIG_H
 35  #include <config.h>
 36  #endif
 37  
 38  #include <roken.h>
 39  #include <stdio.h>
 40  #include <stdlib.h>
 41  #include <string.h>
 42  #include <stdarg.h>
 43  #include <gssapi.h>
 44  #include <gssapi_krb5.h>
 45  #include <gssapi_spnego.h>
 46  #include <err.h>
 47  #include <getarg.h>
 48  
 49  static void
 50  gss_print_errors (int min_stat)
 51  {
 52      OM_uint32 new_stat;
 53      OM_uint32 msg_ctx = 0;
 54      gss_buffer_desc status_string;
 55      OM_uint32 ret;
 56  
 57      do {
 58  	ret = gss_display_status (&new_stat,
 59  				  min_stat,
 60  				  GSS_C_MECH_CODE,
 61  				  GSS_C_NO_OID,
 62  				  &msg_ctx,
 63  				  &status_string);
 64  	if (!GSS_ERROR(ret)) {
 65  	    fprintf (stderr, "%.*s\n", (int)status_string.length,
 66  					(char *)status_string.value);
 67  	    gss_release_buffer (&new_stat, &status_string);
 68  	}
 69      } while (!GSS_ERROR(ret) && msg_ctx != 0);
 70  }
 71  
 72  static void
 73  gss_err(int exitval, int status, const char *fmt, ...)
 74  {
 75      va_list args;
 76  
 77      va_start(args, fmt);
 78      vwarnx (fmt, args);
 79      gss_print_errors (status);
 80      va_end(args);
 81      exit (exitval);
 82  }
 83  
 84  static void
 85  acquire_release_loop(gss_name_t name, int counter, gss_cred_usage_t usage)
 86  {
 87      OM_uint32 maj_stat, min_stat;
 88      gss_cred_id_t cred;
 89      int i;
 90  
 91      for (i = 0; i < counter; i++) {
 92  	maj_stat = gss_acquire_cred(&min_stat, name,
 93  				    GSS_C_INDEFINITE,
 94  				    GSS_C_NO_OID_SET,
 95  				    usage,
 96  				    &cred,
 97  				    NULL,
 98  				    NULL);
 99  	if (maj_stat != GSS_S_COMPLETE)
100  	    gss_err(1, min_stat, "aquire %d %d != GSS_S_COMPLETE",
101  		    i, (int)maj_stat);
102  
103  	maj_stat = gss_release_cred(&min_stat, &cred);
104  	if (maj_stat != GSS_S_COMPLETE)
105  	    gss_err(1, min_stat, "release %d %d != GSS_S_COMPLETE",
106  		    i, (int)maj_stat);
107      }
108  }
109  
110  
111  static void
112  acquire_add_release_add(gss_name_t name, gss_cred_usage_t usage)
113  {
114      OM_uint32 maj_stat, min_stat;
115      gss_cred_id_t cred, cred2, cred3;
116  
117      maj_stat = gss_acquire_cred(&min_stat, name,
118  				GSS_C_INDEFINITE,
119  				GSS_C_NO_OID_SET,
120  				usage,
121  				&cred,
122  				NULL,
123  				NULL);
124      if (maj_stat != GSS_S_COMPLETE)
125  	gss_err(1, min_stat, "aquire %d != GSS_S_COMPLETE", (int)maj_stat);
126  
127      maj_stat = gss_add_cred(&min_stat,
128  			    cred,
129  			    GSS_C_NO_NAME,
130  			    GSS_KRB5_MECHANISM,
131  			    usage,
132  			    GSS_C_INDEFINITE,
133  			    GSS_C_INDEFINITE,
134  			    &cred2,
135  			    NULL,
136  			    NULL,
137  			    NULL);
138  
139      if (maj_stat != GSS_S_COMPLETE)
140  	gss_err(1, min_stat, "add_cred %d != GSS_S_COMPLETE", (int)maj_stat);
141  
142      maj_stat = gss_release_cred(&min_stat, &cred);
143      if (maj_stat != GSS_S_COMPLETE)
144  	gss_err(1, min_stat, "release %d != GSS_S_COMPLETE", (int)maj_stat);
145  
146      maj_stat = gss_add_cred(&min_stat,
147  			    cred2,
148  			    GSS_C_NO_NAME,
149  			    GSS_KRB5_MECHANISM,
150  			    GSS_C_BOTH,
151  			    GSS_C_INDEFINITE,
152  			    GSS_C_INDEFINITE,
153  			    &cred3,
154  			    NULL,
155  			    NULL,
156  			    NULL);
157  
158      maj_stat = gss_release_cred(&min_stat, &cred2);
159      if (maj_stat != GSS_S_COMPLETE)
160  	gss_err(1, min_stat, "release 2 %d != GSS_S_COMPLETE", (int)maj_stat);
161  
162      maj_stat = gss_release_cred(&min_stat, &cred3);
163      if (maj_stat != GSS_S_COMPLETE)
164  	gss_err(1, min_stat, "release 2 %d != GSS_S_COMPLETE", (int)maj_stat);
165  }
166  
167  static int version_flag = 0;
168  static int help_flag	= 0;
169  
170  static struct getargs args[] = {
171      {"version",	0,	arg_flag,	&version_flag, "print version", NULL },
172      {"help",	0,	arg_flag,	&help_flag,  NULL, NULL }
173  };
174  
175  static void
176  usage (int ret)
177  {
178      arg_printusage (args, sizeof(args)/sizeof(*args),
179  		    NULL, "service@host");
180      exit (ret);
181  }
182  
183  
184  int
185  main(int argc, char **argv)
186  {
187      struct gss_buffer_desc_struct name_buffer;
188      OM_uint32 maj_stat, min_stat;
189      gss_name_t name;
190      int optidx = 0;
191  
192      setprogname(argv[0]);
193      if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
194  	usage(1);
195  
196      if (help_flag)
197  	usage (0);
198  
199      if(version_flag){
200  	print_version(NULL);
201  	exit(0);
202      }
203  
204      argc -= optidx;
205      argv += optidx;
206  
207      if (argc < 1)
208  	errx(1, "argc < 1");
209  
210      name_buffer.value = argv[0];
211      name_buffer.length = strlen(argv[0]);
212  
213      maj_stat = gss_import_name(&min_stat, &name_buffer,
214  			       GSS_C_NT_HOSTBASED_SERVICE,
215  			       &name);
216      if (maj_stat != GSS_S_COMPLETE)
217  	errx(1, "import name error");
218  
219      acquire_release_loop(name, 100, GSS_C_ACCEPT);
220      acquire_release_loop(name, 100, GSS_C_INITIATE);
221      acquire_release_loop(name, 100, GSS_C_BOTH);
222  
223      acquire_add_release_add(name, GSS_C_ACCEPT);
224      acquire_add_release_add(name, GSS_C_INITIATE);
225      acquire_add_release_add(name, GSS_C_BOTH);
226  
227      gss_release_name(&min_stat, &name);
228  
229      return 0;
230  }