[1821] in Kerberos-V5-bugs

home help back first fref pref prev next nref lref last post

KDC reply: starttime=0 STILL

daemon@ATHENA.MIT.EDU (Richard Basch)
Wed Feb 28 16:02:17 1996

Date: Wed, 28 Feb 1996 16:00:51 -0500
To: tytso@MIT.EDU
Cc: krb5-bugs@MIT.EDU
From: "Richard Basch" <basch@lehman.com>

Even after your ASN.1 checkin last night, I am still experiencing the
problem where the starttime is still being interpreted as 0, and I am
getting clockskew problems.  Commenting out the code in the KDC that
sets it to 0, and always returning the starttime fixes the problem for
me.

My "make" is up-to-date, and the libraries installed seem to be current.
I will recompile again later to make sure that there isn't some time
skew that occurred that created some confusion, but consider this a
heads-up.  Confirmation will follow...

Included is my login module for logdaemon-5.0, which can be compiled
standalone, in case anyone else wants to test it...

Richard Basch                   
Sr. Developer/Analyst           URL: http://web.mit.edu/basch/www/home.html
Lehman Brothers, Inc.           Email: basch@lehman.com, basch@mit.edu
101 Hudson St., 33rd Floor      Fax:   +1-201-524-5828
Jersey City, NJ 07302-3988      Voice: +1-201-524-5049



#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <errno.h>
#include <pwd.h>
#include <netdb.h>

#include <krb5.h>
#include <com_err.h>

static krb5_data tgtname = {
    0,
    KRB5_TGS_NAME_SIZE,
    KRB5_TGS_NAME
};

int
validate_kerberos(pwd, password, ccname)
struct passwd	*pwd;
char		*password;
char		**ccname;
{
    krb5_context	context;
    krb5_error_code	kret;
    krb5_ccache		ccache = NULL;
    krb5_creds		*my_creds;
    krb5_creds		*ret_cred = 0;
    krb5_keytab		keytab;
    krb5_timestamp	now;
    krb5_deltat		lifetime = 10 * 3600;
    krb5_ticket		*ticket = 0;
    krb5_keytab_entry	ktent;
    int			options = KDC_OPT_FORWARDABLE;
    char		*status = 0;

    /* Don't try to validate root */
    if (!pwd || !pwd->pw_uid) return 0;

    my_creds = (krb5_creds *)calloc(1, sizeof(krb5_creds));
    if (my_creds == 0) return 0;
    
    (void) krb5_init_context(&context);
    (void) krb5_init_ets(context);
    (void) krb5_secure_config_files(context);

    (void) memset((char *)&ktent, 0, sizeof(ktent));

    kret = krb5_parse_name(context, pwd->pw_name, &my_creds->client);
    if (kret) goto done;

    kret = krb5_build_principal_ext(context, &my_creds->server,
		    krb5_princ_realm(context, my_creds->client)->length,
		    krb5_princ_realm(context, my_creds->client)->data,
		    tgtname.length, tgtname.data,
		    krb5_princ_realm(context, my_creds->client)->length,
		    krb5_princ_realm(context, my_creds->client)->data,
		    0);
    if (kret) goto done;

    kret = krb5_timeofday(context, &now);
    if (kret) goto done;

    my_creds->times.starttime = 0;
    my_creds->times.endtime = now + lifetime;
    my_creds->times.renew_till = 0;

    kret = krb5_get_in_tkt_with_password(context, options, 0, 0, 0,
					 password, 0, my_creds, 0);
    if (kret == KRB5KRB_AP_ERR_BAD_INTEGRITY) {
	fprintf(stderr, "login: Kerberos password incorrect\n");
	kret = -1;
	goto done;
    }
    else if (kret) goto done;

    /* Store credentials */
    status = " while storing credentials.";
    
#ifdef TEST
    *ccname = krb5_cc_default_name(context);
#else
    *ccname = tempnam("/tmp", "cc5_");
#endif
    kret = krb5_cc_resolve(context, *ccname, &ccache);
    if (kret) goto done;
    kret = krb5_cc_initialize(context, ccache, my_creds->client);
    if (kret) goto done;
    kret = krb5_cc_store_cred(context, ccache, my_creds);
    if (kret) goto done;

#ifndef TEST
    if (chown(*ccname, pwd->pw_uid, -1)) {
	kret = errno;
	goto done;
    }
#endif

    /*
     * Test the credentials against a local keytab entry
     */

    status = " while verifying credentials.";
    
    (void) krb5_free_creds(context, my_creds);
    my_creds = (krb5_creds *)calloc(1, sizeof(krb5_creds));
    if (my_creds == 0) {
	kret = errno;
	goto done;
    }
    
    kret = krb5_cc_get_principal(context, ccache, &my_creds->client);
    if (kret) goto done;

    kret = krb5_sname_to_principal(context, NULL, NULL,
				   KRB5_NT_SRV_HST, &my_creds->server);
    if (kret) goto done;

    kret = krb5_get_credentials(context, 0, ccache, my_creds, &ret_cred);
    if (kret) goto done;

    kret = decode_krb5_ticket(&ret_cred->ticket, &ticket);
    if (kret) goto done;

    /* Get the keytab entry */
    kret = krb5_kt_default(context, &keytab);
    if (kret) goto done;
    kret = krb5_kt_get_entry(context, keytab, ticket->server,
		     ticket->enc_part.kvno, ticket->enc_part.enctype, &ktent);
    (void) krb5_kt_close(context, keytab);
    if (kret) {
	status = " while getting keytab entry.";
	goto done;
    }

    /* Now make sure we got what we expected */
    kret = krb5_decrypt_tkt_part(context, &ktent.key, ticket);
    if (kret) goto done;

    if (ticket->enc_part2 && krb5_principal_compare(context,
				ticket->enc_part2->client,
				my_creds->client)) {
	kret = 0;
#ifdef TEST
	fprintf(stderr, "test: Kerberos tickets verified SUCCESSFULLY.\n");
#endif
    } else {
	fprintf(stderr, "login: Kerberos tickets not verified\n");
	kret = -1;
    }

done:
    (void) krb5_kt_free_entry(context, &ktent);
    (void) krb5_free_creds(context, my_creds);

    if (ccache)
	(void) krb5_cc_close(context, ccache);

    if (kret == 0) return 1;

    if (kret != -1)
	fprintf(stderr, "login: Kerberos error: %s%s\n",
		error_message(kret), status ? status : "");
    return 0;
}

#ifdef TEST
int main(argc, argv)
int argc;
char *argv[];
{
    krb5_context kcontext;
    char password[256];
    int pwsize;
    krb5_error_code kret;
    char *ccname;
    struct passwd *pwd;

    (void) krb5_init_context(&kcontext);
    (void) krb5_init_ets(kcontext);

    pwsize = sizeof(password);
    kret = krb5_read_password(kcontext, "Password: ", 0, password, &pwsize);
    if (kret) goto error;

    if (argc > 1)
	pwd = getpwnam(argv[1]);
    else
	pwd = getpwuid(getuid());
    return (!validate_kerberos(pwd, password, &ccname));

error:
    fprintf(stderr, "Kerberos error: %s\n", error_message(kret));
    return -1;
}
#endif

home help back first fref pref prev next nref lref last post