--- krb5-1.2.1-fresh/clients/kinit/kinit.c	Thu Jun 29 22:27:15 2000
+++ krb5-1.2.1/clients/kinit/kinit.c	Tue Jul 18 22:47:29 2000
@@ -55,6 +55,11 @@
 #endif /* HAVE_UNISTD_H */
 #endif /* GETOPT_LONG */
 
+/* smartcard mode */
+#ifdef KRBSC
+#include "krbsc_extern.h"
+#endif /* KRBSC */
+
 #ifndef _WIN32
 #define GET_PROGNAME(x) (strrchr((x), '/') ? strrchr((x), '/')+1 : (x))
 #else
@@ -114,7 +119,11 @@
 
 #define KRB4_BACKUP_DEFAULT_LIFE_SECS 10*60*60 /* 10 hours */
 
+#ifdef KRBSC
+typedef enum { INIT_PW, INIT_KT, RENEW, VALIDATE, INIT_SC } action_type;
+#else /* KRBSC */
 typedef enum { INIT_PW, INIT_KT, RENEW, VALIDATE } action_type;
+#endif /* KRBSC */
 
 struct k_opts
 {
@@ -214,6 +223,11 @@
 	    USAGE_BREAK
 	    "[-c cachename] "
 	    "[-S service_name] [principal]"
+#ifdef KRBSC
+	    USAGE_BREAK
+	    "[-h smartcard_port_num] [-e] [-K]"
+	    USAGE_BREAK
+#endif KRBSC
 	    "\n\n", 
 	    progname);
 
@@ -262,6 +276,11 @@
     /* This options is not yet available: */
     /* ULINE("\t", "-C Kerberos 4 cache name",     OPTTYPE_KRB4); */
     ULINE("\t", "-S service",                   OPTTYPE_BOTH);
+#ifdef KRBSC
+    ULINE("\t", "-h smartcard_port_num",	OPTTYPE_KRB5);
+    ULINE("\t", "-e EECS598 mode",		OPTTYPE_KRB5);
+    ULINE("\t", "-K print out key",		OPTTYPE_KRB5);
+#endif KRBSC
     exit(2);
 }
 
@@ -277,7 +296,11 @@
     int use_k5 = 0;
     int i;
 
+#ifdef KRBSC
+    while ((i = GETOPT(argc, argv, "r:fpFP54AVl:s:c:kt:RS:vh:Ke:"))
+#else /* KRBSC */
     while ((i = GETOPT(argc, argv, "r:fpFP54AVl:s:c:kt:RS:v"))
+#endif /* KRBSC */
 	   != -1) {
 	switch (i) {
 	case 'V':
@@ -397,6 +420,37 @@
 	    }
 	    use_k5 = 1;
 	    break;
+#ifdef KRBSC
+	case 'h':
+	  /* smartcard mode */
+	  KRB5_USE_SC = 1;
+	  opts->action = INIT_SC;
+	  KRB5_SC_PORTNUM = atoi(optarg);
+#ifdef SCDEBUG
+	  printf ("smartcard mode.  KRB5_SC_PORTNUM = %d\n",
+		  KRB5_SC_PORTNUM);
+#endif /* SCDEBUG */
+	  break;
+
+	case 'K':
+	  /* print key mode */
+	  KRB5_PRINT_KEY = 1;
+#ifdef SCDEBUG
+	  printf ("print key mode.\n");
+#endif /* SCDEBUG */
+	  break;
+	case 'e':
+	  /* EECS 598 mode */
+	  KRB5_USE_SC = 1;
+	  opts->action = INIT_SC;
+	  KRB5_EECS_598 = 1;
+	  KRB5_SC_PORTNUM = atoi(optarg);
+#ifdef SCDEBUG
+	  printf ("EECS 598 smartcard mode.  KRB5_SC_PORTNUM = %d\n",
+		  KRB5_SC_PORTNUM);
+#endif /* SCDEBUG */
+	  break;
+#endif /* KRBSC */
 	default:
 	    errflg++;
 	    break;
@@ -555,6 +609,11 @@
     }
     opts->principal_name = k5->name;
 
+#ifdef KRBSC
+    /* put client name into global_c_n for sc_cbc.c in libcrypto.a */
+    global_client_name = k5->name; 
+#endif KRBSC
+    
 #ifdef KRB5_KRB4_COMPAT
     if (got_k4)
     {
@@ -726,6 +785,14 @@
     krb5_creds my_creds;
     krb5_error_code code = 0;
     krb5_get_init_creds_opt options;
+#ifdef KRBSC
+    krb5_enctype *etype_list = (krb5_enctype *) malloc (sizeof (krb5_enctype));
+
+    if (etype_list == NULL) {
+      perror ("k5_kinit");
+      return 0; 
+    }
+#endif /* KRBSC */
 
     if (!got_k5)
 	return 0;
@@ -782,6 +849,17 @@
 					    opts->service_name,
 					    &options);
 	break;
+#ifdef KRBSC
+    case INIT_SC:
+	*etype_list = ENCTYPE_DES_CBC_MD5; 
+	krb5_get_init_creds_opt_set_etype_list (&options, etype_list, 1);
+	code = krb5_get_init_creds_password(k5->ctx, &my_creds, k5->me,
+					    0, kinit_prompter, 0,
+					    opts->starttime, 
+					    opts->service_name,
+					    &options);
+	break; 
+#endif /* KRBSC */
     case INIT_KT:
 	code = krb5_get_init_creds_keytab(k5->ctx, &my_creds, k5->me,
 					  keytab,
@@ -854,6 +932,11 @@
     krb5_free_cred_contents(k5->ctx, &my_creds);
     if (keytab)
 	krb5_kt_close(k5->ctx, keytab);
+
+#ifdef KRBSC
+    free (etype_list);
+#endif /* KRBSC */
+    
     return notix?0:1;
 }
 
@@ -1053,6 +1136,15 @@
     struct k5_data k5;
     struct k4_data k4;
 
+#ifdef KRBSC
+    KRB5_USE_SC = 0;
+    KRB5_PRINT_KEY = 0;
+    KRB5_SC_PORTNUM = 0;
+    KRB5_EECS_598 = 0;
+    global_client_name = NULL;
+    KRB5_SC_OVER_IP = NULL;
+#endif /* KRBSC */
+    
     progname = GET_PROGNAME(argv[0]);
     progname_v5 = getvprogname("5");
 #ifdef KRB5_KRB4_COMPAT
