venus: Remove dedebug
[openafs.git] / src / aklog / klog.c
index 51e5411..6a75399 100644 (file)
@@ -24,6 +24,7 @@
 #include <afs/cmd.h>
 #include <afs/ptuser.h>
 
+#define KERBEROS_APPLE_DEPRECATED(x)
 #include <krb5.h>
 
 #ifdef HAVE_KRB5_CREDS_KEYBLOCK
@@ -98,7 +99,7 @@ main(int argc, char *argv[])
     zero_argc = argc;
     zero_argv = argv;
 
-    ts = cmd_CreateSyntax(NULL, CommandProc, NULL,
+    ts = cmd_CreateSyntax(NULL, CommandProc, NULL, 0,
                          "obtain Kerberos authentication");
 
 #define aXFLAG 0
@@ -115,8 +116,9 @@ main(int argc, char *argv[])
 #define aUNWRAP 11
 #define aK5 12
 #define aK4 13
+#define aDES 14
 
-    cmd_AddParm(ts, "-x", CMD_FLAG, CMD_OPTIONAL|CMD_HIDDEN, 0);
+    cmd_AddParm(ts, "-x", CMD_FLAG, CMD_OPTIONAL, "obsolete, noop");
     cmd_Seek(ts, aPRINCIPAL);
     cmd_AddParm(ts, "-principal", CMD_SINGLE, CMD_OPTIONAL, "user name");
     cmd_AddParm(ts, "-password", CMD_SINGLE, CMD_OPTIONAL, "user's password");
@@ -125,8 +127,9 @@ main(int argc, char *argv[])
     cmd_AddParm(ts, "-pipe", CMD_FLAG, CMD_OPTIONAL,
                "read password from stdin");
     cmd_AddParm(ts, "-silent", CMD_FLAG, CMD_OPTIONAL, "silent operation");
+    /* Note: -lifetime is not implemented in this version of klog. */
     cmd_AddParm(ts, "-lifetime", CMD_SINGLE, CMD_OPTIONAL,
-               "ticket lifetime in hh[:mm[:ss]]");
+               "ignored (for compatibility with the krb4-based klog)");
     cmd_AddParm(ts, "-setpag", CMD_FLAG, CMD_OPTIONAL,
                "Create a new setpag before authenticating");
     cmd_AddParm(ts, "-tmp", CMD_FLAG, CMD_OPTIONAL,
@@ -140,6 +143,8 @@ main(int argc, char *argv[])
     ++ts->nParms;      /* skip -k5 */
     cmd_AddParm(ts, "-k4", CMD_FLAG, CMD_OPTIONAL|CMD_HIDDEN, 0);
 #endif
+    cmd_AddParm(ts, "-insecure_des", CMD_FLAG, CMD_OPTIONAL,
+               "enable insecure single-DES for krb5");
 
     code = cmd_Dispatch(argc, argv);
     KLOGEXIT(code);
@@ -213,7 +218,7 @@ whoami(struct ktc_token *atoken,
     int *vicep)
 {
     int code;
-    char tempname[PR_MAXNAMELEN + 1];
+    char tempname[2*PR_MAXNAMELEN];
 
     code = pr_Initialize(0, AFSDIR_CLIENT_ETC_DIRPATH, cellconfig->name);
     if (code)
@@ -242,100 +247,17 @@ k5_to_k4_name(krb5_context k5context,
            i = get_princ_len(k5context, k5princ, 1);
            if (i > MAXKTCNAMELEN-1) i = MAXKTCNAMELEN-1;
            memcpy(ktcprinc->instance, get_princ_str(k5context, k5princ, 1), i);
-           /* fall through */
+           AFS_FALLTHROUGH;
        case 1:
            i = get_princ_len(k5context, k5princ, 0);
            if (i > MAXKTCNAMELEN-1) i = MAXKTCNAMELEN-1;
            memcpy(ktcprinc->name, get_princ_str(k5context, k5princ, 0), i);
-           /* fall through */
+           AFS_FALLTHROUGH;
        case 0:
            break;
        }
 }
 
-#if defined(USING_HEIMDAL) || defined(HAVE_KRB5_PROMPT_TYPE)
-static int
-klog_is_pass_prompt(int index, krb5_context context, krb5_prompt prompts[])
-{
-    switch (prompts[index].type) {
-    case KRB5_PROMPT_TYPE_PASSWORD:
-    case KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN:
-       return 1;
-    default:
-       return 0;
-    }
-}
-#elif defined(HAVE_KRB5_GET_PROMPT_TYPES)
-static int
-klog_is_pass_prompt(int index, krb5_context context, krb5_prompt prompts[])
-{
-    /* this isn't thread-safe or anything obviously; it just should be good
-     * enough to work with klog */
-    static krb5_prompt_type *types = NULL;
-    if (index == 0) {
-       types = NULL;
-    }
-    if (!types) {
-       types = krb5_get_prompt_types(context);
-    }
-    if (!types) {
-       return 0;
-    }
-    switch (types[index]) {
-    case KRB5_PROMPT_TYPE_PASSWORD:
-    case KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN:
-       return 1;
-    default:
-       return 0;
-    }
-}
-#else
-static int
-klog_is_pass_prompt(int index, krb5_context context, krb5_prompt prompts[])
-{
-    /* AIX 5.3 doesn't have krb5_get_prompt_types. Neither does HP-UX, which
-     * also doesn't even define KRB5_PROMPT_TYPE_PASSWORD &co. We have no way
-     * of determining the the prompt type, so just assume it's a password */
-    return 1;
-}
-#endif
-
-/* save and reuse password.  This is necessary to make
- *  "direct to service" authentication work with most
- *  flavors of kerberos, when the afs principal has no instance.
- */
-struct kp_arg {
-    char **pp, *pstore;
-    size_t allocated;
-};
-krb5_error_code
-klog_prompter(krb5_context context,
-    void *a,
-    const char *name,
-    const char *banner,
-    int num_prompts,
-    krb5_prompt prompts[])
-{
-    krb5_error_code code;
-    int i;
-    struct kp_arg *kparg = (struct kp_arg *) a;
-    size_t length;
-
-    code = krb5_prompter_posix(context, a, name, banner, num_prompts, prompts);
-    if (code) return code;
-    for (i = 0; i < num_prompts; ++i) {
-       if (klog_is_pass_prompt(i, context, prompts)) {
-           length = prompts[i].reply->length;
-           if (length > kparg->allocated - 1)
-               length = kparg->allocated - 1;
-           memcpy(kparg->pstore, prompts[i].reply->data, length);
-           kparg->pstore[length] = 0;
-           *kparg->pp = kparg->pstore;
-       }
-    }
-    return 0;
-}
-
 static int
 CommandProc(struct cmd_syndesc *as, void *arock)
 {
@@ -357,11 +279,7 @@ CommandProc(struct cmd_syndesc *as, void *arock)
     int authtype;
 #endif
     krb5_data enc_part[1];
-    time_t lifetime;           /* requested ticket lifetime */
-    krb5_prompter_fct pf = NULL;
     char *pass = 0;
-    void *pa = 0;
-    struct kp_arg klog_arg[1];
 
     char passwd[BUFSIZ];
     struct afsconf_cell cellconfig[1];
@@ -378,7 +296,6 @@ CommandProc(struct cmd_syndesc *as, void *arock)
     for (i = 1; i < zero_argc; i++)
        memset(zero_argv[i], 0, strlen(zero_argv[i]));
     zero_argc = 0;
-    memset(klog_arg, 0, sizeof *klog_arg);
 
     /* first determine quiet flag based on -silent switch */
     Silent = (as->parms[aSILENT].items ? 1 : 0);
@@ -412,13 +329,15 @@ CommandProc(struct cmd_syndesc *as, void *arock)
      * krb5_allow_weak_crypto is MIT Kerberos 1.8.  krb5_enctype_enable is
      * Heimdal.
      */
+    if (as->parms[aDES].items) {
 #if defined(HAVE_KRB5_ENCTYPE_ENABLE)
-    i = krb5_enctype_valid(k5context, ETYPE_DES_CBC_CRC);
-    if (i)
-        krb5_enctype_enable(k5context, ETYPE_DES_CBC_CRC);
+       i = krb5_enctype_valid(k5context, ETYPE_DES_CBC_CRC);
+       if (i)
+           krb5_enctype_enable(k5context, ETYPE_DES_CBC_CRC);
 #elif defined(HAVE_KRB5_ALLOW_WEAK_CRYPTO)
-    krb5_allow_weak_crypto(k5context, 1);
+       krb5_allow_weak_crypto(k5context, 1);
 #endif
+    }
 
     /* Parse remaining arguments. */
 
@@ -507,45 +426,10 @@ CommandProc(struct cmd_syndesc *as, void *arock)
        pass = passwd;
     }
 
-    if (as->parms[aLIFETIME].items) {
-       char *life = as->parms[aLIFETIME].items->data;
-       char *sp;               /* string ptr to rest of life */
-       lifetime = 3600 * strtol(life, &sp, 0); /* hours */
-       if (sp == life) {
-         bad_lifetime:
-           if (!Silent)
-               fprintf(stderr, "%s: translating '%s' to lifetime failed\n",
-                       rn, life);
-           return 1;
-       }
-       if (*sp == ':') {
-           life = sp + 1;      /* skip the colon */
-           lifetime += 60 * strtol(life, &sp, 0);      /* minutes */
-           if (sp == life)
-               goto bad_lifetime;
-           if (*sp == ':') {
-               life = sp + 1;
-               lifetime += strtol(life, &sp, 0);       /* seconds */
-               if (sp == life)
-                   goto bad_lifetime;
-               if (*sp)
-                   goto bad_lifetime;
-           } else if (*sp)
-               goto bad_lifetime;
-       } else if (*sp)
-           goto bad_lifetime;
-    } else
-       lifetime = 0;
-
-    /* Get the password if it wasn't provided. */
-    if (!pass) {
-       if (Pipe) {
-           strncpy(passwd, getpipepass(), sizeof(passwd));
-           pass = passwd;
-       } else {
-           pf = klog_prompter;
-           pa = klog_arg;
-       }
+    /* Get the password from stdin if it wasn't provided. */
+    if (!pass && Pipe) {
+       strncpy(passwd, getpipepass(), sizeof(passwd));
+       pass = passwd;
     }
 
     service = 0;
@@ -557,9 +441,6 @@ CommandProc(struct cmd_syndesc *as, void *arock)
 #endif
     snprintf (service_temp, sizeof service_temp, "afs/%s", cellconfig->name);
 
-    klog_arg->pp = &pass;
-    klog_arg->pstore = passwd;
-    klog_arg->allocated = sizeof(passwd);
     /* XXX should allow k5 to prompt in most cases -- what about expired pw?*/
 #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC
     code = krb5_get_init_creds_opt_alloc(k5context, &gic_opts);
@@ -576,10 +457,10 @@ CommandProc(struct cmd_syndesc *as, void *arock)
            incred,
            princ,
            pass,
-           pf, /* prompter */
-           pa, /* data */
-           0,  /* start_time */
-           0,  /* in_tkt_service */
+           krb5_prompter_posix,        /* prompter */
+           NULL,                       /* data */
+           0,                          /* start_time */
+           0,                          /* in_tkt_service */
            gic_opts);
        if (code != KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN)
             break;
@@ -634,9 +515,6 @@ CommandProc(struct cmd_syndesc *as, void *arock)
     for (service = service_temp;;service = "afs") {
         memset(mcred, 0, sizeof *mcred);
         mcred->client = princ;
-        /* Ask for DES since that is what rxkad understands */
-        if (service && !strncmp(service, "afs", 3))
-            get_creds_enctype(mcred) = ENCTYPE_DES_CBC_CRC;
         code = krb5_parse_name(k5context, service, &mcred->server);
         if (code) {
             afs_com_err(rn, code, "Unable to parse service <%s>\n", service);
@@ -680,13 +558,6 @@ CommandProc(struct cmd_syndesc *as, void *arock)
        struct ktc_principal aserver[1], aclient[1];
        struct ktc_token atoken[1];
 
-        if (get_cred_keylen(afscred) != sizeof(atoken->sessionKey)) {
-            afs_com_err(rn, 0, "Invalid rxkad key length (%u != 8) key type (%u)",
-                        (unsigned)get_cred_keylen(afscred),
-                        get_creds_enctype(afscred));
-            KLOGEXIT(1);
-        }
-
        memset(atoken, 0, sizeof *atoken);
        if (evil) {
            size_t elen = enc_part->length;
@@ -704,8 +575,15 @@ CommandProc(struct cmd_syndesc *as, void *arock)
        }
        atoken->startTime = afscred->times.starttime;
        atoken->endTime = afscred->times.endtime;
-       memcpy(&atoken->sessionKey, get_cred_keydata(afscred),
-           get_cred_keylen(afscred));
+       if (tkt_DeriveDesKey(get_creds_enctype(afscred),
+                            get_cred_keydata(afscred),
+                            get_cred_keylen(afscred), &atoken->sessionKey)) {
+           afs_com_err(rn, 0,
+                       "Cannot derive DES key from enctype %i of length %u",
+                       get_creds_enctype(afscred),
+                       (unsigned)get_cred_keylen(afscred));
+           KLOGEXIT(1);
+       }
        memcpy(atoken->ticket, enc_part->data,
            atoken->ticketLen = enc_part->length);
        memset(aserver, 0, sizeof *aserver);