Exemplo n.º 1
0
/* Set the key for krb_rd_req so we can check tgt */
static int
set_tgtkey(char *r, krb5_kvno kvno, krb5_boolean use_3des)
{
    int     n;
    static char lastrealm[REALM_SZ] = "";
    static int last_kvno = 0;
    static krb5_boolean last_use_3des = 0;
    static int more;
    Principal p_st;
    Principal *p = &p_st;
    C_Block key;
    krb5_keyblock k5key;

    k5key.contents = NULL;
    if (!strcmp(lastrealm, r) && last_kvno == kvno && last_use_3des == use_3des)
	return (KSUCCESS);

/*  log("Getting key for %s", r); */

    n = kerb_get_principal("krbtgt", r, p, &more, &k5key, kvno, 1, NULL);
    if (n == 0)
	return (KFAILURE);

    if (isflagset(p->attributes, V4_KDB_DISALLOW_ALL_TIX)) {
	lt = klog(L_ERR_SEXP,
		  "V5 DISALLOW_ALL_TIX set: \"krbtgt\" \"%s\"", r);
	krb5_free_keyblock_contents(kdc_context, &k5key);
	return KFAILURE;
    }

    if (isflagset(p->attributes, V4_KDB_DISALLOW_SVR)) {
	lt = klog(L_ERR_SEXP, "V5 DISALLOW_SVR set: \"krbtgt\" \"%s\"", r);
	krb5_free_keyblock_contents(kdc_context, &k5key);
	return KFAILURE;
    }

    if (use_3des&&!K4KDC_ENCTYPE_OK(k5key.enctype)) {
	krb_set_key_krb5(kdc_context, &k5key);
	strncpy(lastrealm, r, sizeof(lastrealm) - 1);
	lastrealm[sizeof(lastrealm) - 1] = '\0';
	last_kvno = kvno;
	last_use_3des = use_3des;
    } else {
	/* unseal tgt key from master key */
	memcpy(key,                &p->key_low,  4);
	memcpy(((krb5_ui_4 *) key) + 1, &p->key_high, 4);
	kdb_encrypt_key(key, key, master_key,
			master_key_schedule, DECRYPT);
	krb_set_key((char *) key, 0);
	strncpy(lastrealm, r, sizeof(lastrealm) - 1);
	lastrealm[sizeof(lastrealm) - 1] = '\0';
	last_kvno = kvno;
    }
    krb5_free_keyblock_contents(kdc_context, &k5key);
    return (KSUCCESS);
}
Exemplo n.º 2
0
main()
{
	struct	sockaddr_in	foreign;
	int			foreign_len = sizeof(foreign);
	int			rval, more;
	static  char	name[] = "kpasswdd";

	static	struct rlimit	rl = { 0, 0 };

	progname = name;
	openlog("kpasswdd", LOG_CONS | LOG_PID, LOG_AUTH);

	signal(SIGHUP, SIG_IGN);
	signal(SIGINT, SIG_IGN);
	signal(SIGTSTP, SIG_IGN);
	if(setrlimit(RLIMIT_CORE, &rl) < 0) {
		syslog(LOG_ERR, "setrlimit: %m");
		exit(1);
	}

	if(getpeername(0, &foreign, &foreign_len) < 0) {
		syslog(LOG_ERR,"getpeername: %m");
		exit(1);
	}

	strcpy(inst, "*");
	rval = krb_recvauth(
		0L,				/* !MUTUAL */
		0,				/* file desc */
		&ticket,			/* client's ticket */
		SERVICE,			/* expected service */
		inst,				/* expected instance */
		&foreign,			/* foreign addr */
		(struct sockaddr_in *) 0,	
		&kdata,
		"",
		(bit_64 *) NULL,		/* key schedule */
		version
	);


	if(rval != KSUCCESS) {
		syslog(LOG_ERR, "krb_recvauth: %s", krb_err_txt[rval]);
		cleanup();
		exit(1);
	}


	/* get master key */
	if(kdb_get_master_key(0, master_key, master_key_schedule) != 0) {
		syslog(LOG_ERR, "couldn't get master key");
		cleanup();
		exit(1);
	}

	mkeyversion = 
	   kdb_get_master_key(master_key, master_key_schedule, NULL);


	if(mkeyversion < 0) {
		syslog(LOG_NOTICE, "couldn't verify master key");
		cleanup();
		exit(1);
	}

	/* get principal info */
	rval = kerb_get_principal(
		kdata.pname,
		kdata.pinst,
		&principal_data,
		1,
		&more
	);

	if(rval != 1 || (more != 0)) {
		syslog(LOG_NOTICE, "more than 1 entry for %s.%s",
			kdata.pname, kdata.pinst);
		cleanup();
		exit(1);
	}

	/* get the user's key */

	bcopy(&principal_data.key_low, key, 4);
	bcopy(&principal_data.key_high, ((long *) key) + 1, 4);
	kdb_encrypt_key(key, key, master_key, master_key_schedule,
		DECRYPT);
	key_sched(key, key_schedule);
	des_set_key(key, key_schedule);


	/* get random key and send it over {random} Kperson */

	random_key(kpwd_data.random_key);
	strcpy(kpwd_data.secure_msg, SECURE_STRING);
	if(des_write(0, &kpwd_data, sizeof(kpwd_data)) != sizeof(kpwd_data)) {
		syslog(LOG_ERR, "error writing initial data");
		cleanup();
		exit(1);
	}

	bzero(key, sizeof(key));
	bzero(key_schedule, sizeof(key_schedule));

	/* now read update info: { info }Krandom */

	key_sched(kpwd_data.random_key, random_sched);
	des_set_key(kpwd_data.random_key, random_sched);
	if(des_read(0, &ud_data, sizeof(ud_data)) != sizeof(ud_data)) {
		syslog(LOG_ERR, "update aborted");
		cleanup();
		exit(1);
	}

	/* validate info string by looking at the embedded string */

	if(strcmp(ud_data.secure_msg, SECURE_STRING)) {
		syslog(LOG_NOTICE, "invalid update from %s",
			inet_ntoa(foreign.sin_addr));
		cleanup();
		exit(1);
	}

	/* produce the new key entry in the database { key }Kmaster */
	string_to_key(ud_data.pw, key);
	kdb_encrypt_key(key, key,
		master_key, master_key_schedule,
		ENCRYPT);
	bcopy(key, &principal_data.key_low, 4);
	bcopy(((long *) key) + 1,
		&principal_data.key_high, 4);
	bzero(key, sizeof(key));
	principal_data.key_version++;
	if(kerb_put_principal(&principal_data, 1)) {
		syslog(LOG_ERR, "couldn't write new record for %s.%s",
			principal_data.name, principal_data.instance);
		cleanup();
		exit(1);
	}

	syslog(LOG_NOTICE,"wrote new password field for %s.%s from %s",
		principal_data.name,
		principal_data.instance,
		inet_ntoa(foreign.sin_addr)
	);

	send_ack(0, "Update complete.\n");
	cleanup();
	exit(0);
}
Exemplo n.º 3
0
static int
check_princ(char *p_name, char *instance, int lifetime, Principal *p,
	    krb5_keyblock *k5key, int issrv, krb5_deltat *k5life)
{
    static int n;
    static int more;
 /* long trans; */

    n = kerb_get_principal(p_name, instance, p, &more, k5key, 0,
			   issrv, k5life);
    klog(L_ALL_REQ,
	 "Principal: \"%s\", Instance: \"%s\" Lifetime = %d n = %d",
	 p_name, instance, lifetime, n, 0);
    
    if (n < 0) {
	lt = klog(L_KRB_PERR, "Database unavailable!");
	p->key_high = p->key_low = 0;    
	hang();
    }
    
    /*
     * if more than one p_name, pick one, randomly create a session key,
     * compute maximum lifetime, lookup authorizations if applicable,
     * and stuff into cipher. 
     */
    if (n == 0) {
	/* service unknown, log error, skip to next request */
	lt = klog(L_ERR_UNK, "UNKNOWN \"%s\" \"%s\"", p_name,
	    instance, 0);
	return KERB_ERR_PRINCIPAL_UNKNOWN;
    }
    if (more) {
	/* not unique, log error */
	lt = klog(L_ERR_NUN, "Principal NOT UNIQUE \"%s\" \"%s\"",
		  p_name, instance, 0);
	return KERB_ERR_PRINCIPAL_NOT_UNIQUE;
    }

    /*
     * Check our V5 stuff first.
     */

    /*
     * Does the principal have REQUIRES_PWCHANGE set?
     */
    if (isflagset(p->attributes, V4_KDB_REQUIRES_PWCHANGE)) {
	lt = klog(L_ERR_SEXP, "V5 REQUIRES_PWCHANGE set "
		  "\"%s\" \"%s\"", p_name, instance);
	return KERB_ERR_NAME_EXP;
    }

    /*
     * Does the principal have DISALLOW_ALL_TIX set?
     */
    if (isflagset(p->attributes, V4_KDB_DISALLOW_ALL_TIX)) {
	lt = klog(L_ERR_SEXP, "V5 DISALLOW_ALL_TIX set: "
		  "\"%s\" \"%s\"", p_name, instance);
	/* Not sure of a better error to return */
	return KERB_ERR_NAME_EXP;
    }

    if (isflagset(p->attributes, V4_KDB_DISALLOW_SVR)) {
	lt = klog(L_ERR_SEXP, "V5 DISALLOW_SVR set: "
		  "\"%s\" \"%s\"", p_name, instance);
	/* Not sure of a better error to return */
	return KERB_ERR_NAME_EXP;
    }

    /*
     * Does the principal require preauthentication?
     */
    if ((kdc_v4 == KDC_V4_NOPREAUTH) &&
	isflagset(p->attributes, V4_KDB_REQUIRES_PREAUTH)) {
        lt = klog(L_ERR_SEXP, "V5 REQUIRES_PREAUTH set: "
		  "\"%s\" \"%s\"", p_name, instance);
	/* Not sure of a better error to return */
	return KERB_ERR_AUTH_EXP;
/*	return KERB_ERR_NAME_EXP;*/
    }

    /* If the user's key is null, we want to return an error */
    if (k5key->contents != NULL && K4KDC_ENCTYPE_OK(k5key->enctype)) {
	if ((p->key_low == 0) && (p->key_high == 0)) {
	    /* User has a null key */
	    lt = klog(L_ERR_NKY, "Null key \"%s\" \"%s\"", p_name,
		      instance, 0);
	    return KERB_ERR_NULL_KEY;
	}
    }
    /* make sure the service hasn't expired */
    if (((u_long) p->exp_date != 0)&&
	((u_long) p->exp_date <(u_long) kerb_time.tv_sec)) {
	/* service did expire, log it */
	char timestr[40];
	struct tm *tm;
	time_t t = p->exp_date;

	tm = localtime(&t);
	if (!strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", tm))
	    timestr[0] = '\0';
	lt = klog(L_ERR_SEXP,
		  "EXPIRED \"%s\" \"%s\"  %s", p->name, p->instance, timestr);
	return KERB_ERR_NAME_EXP;
    }
    /* ok is zero */
    return 0;
}