Beispiel #1
0
const char *
unparse_object(dbref player, dbref loc)
{
	static char buf[BUFFER_LEN];
	if (player == NOTHING)
		goto islog;
	if (Typeof(player) != TYPE_PLAYER)
		player = OWNER(player);
islog:
	switch (loc) {
	case NOTHING:
		return "*NOTHING*";
	case AMBIGUOUS:
		return "*AMBIGUOUS*";
	case HOME:
		return "*HOME*";
	default:
		if (loc < 0 || loc >= db_top)
			return "*INVALID*";

		if ((player == NOTHING) || (!(FLAGS(player) & STICKY) &&
			(can_link_to(player, NOTYPE, loc) ||
			 ((Typeof(loc) != TYPE_PLAYER) &&
			  (controls_link(player, loc) || (FLAGS(loc) & CHOWN_OK)))))) {
			/* show everything */
			snprintf(buf, sizeof(buf), "%.*s(#%d%s)", (BUFFER_LEN / 2), NAME(loc), loc, unparse_flags(loc));
			return buf;
		} else {
			/* show only the name */
			return NAME(loc);
		}
	}
}
Beispiel #2
0
static void
log_as_req(krb5_context context,
	   krb5_kdc_configuration *config,
	   krb5_enctype cetype,
	   krb5_enctype setype,
	   const KDC_REQ_BODY *b)
{
    krb5_error_code ret;
    struct rk_strpool *p = NULL;
    char *str;
    int i;
    
    for (i = 0; i < b->etype.len; i++) {
	ret = krb5_enctype_to_string(context, b->etype.val[i], &str);
	if (ret == 0) {
	    p = rk_strpoolprintf(p, "%s", str);
	    free(str);
	} else
	    p = rk_strpoolprintf(p, "%d", b->etype.val[i]);
	if (p && i + 1 < b->etype.len)
	    p = rk_strpoolprintf(p, ", ");
	if (p == NULL) {
	    kdc_log(context, config, 0, "out of memory");
	    return;
	}
    }
    if (p == NULL)
	p = rk_strpoolprintf(p, "no encryption types");
    
    str = rk_strpoolcollect(p);
    kdc_log(context, config, 0, "Client supported enctypes: %s", str);
    free(str);

    {
	char *cet;
	char *set;

	ret = krb5_enctype_to_string(context, cetype, &cet);
	if(ret == 0) {
	    ret = krb5_enctype_to_string(context, setype, &set);
	    if (ret == 0) {
		kdc_log(context, config, 5, "Using %s/%s", cet, set);
		free(set);
	    }
	    free(cet);
	}
	if (ret != 0)
	    kdc_log(context, config, 5, "Using e-types %d/%d", cetype, setype);
    }
    
    {
	char fixedstr[128];
	unparse_flags(KDCOptions2int(b->kdc_options), asn1_KDCOptions_units(), 
		      fixedstr, sizeof(fixedstr));
	if(*fixedstr)
	    kdc_log(context, config, 2, "Requested flags: %s", fixedstr);
    }
}
Beispiel #3
0
char *unparse_object( dbref player, dbref target, int obey_myopic ) {
    char *buf, *fp, *bp;

    int exam;

    buf = alloc_lbuf( "unparse_object" );
    if( target == NOTHING ) {
        strcpy( buf, "*NOTHING*" );
    } else if( target == HOME ) {
        strcpy( buf, "*HOME*" );
    } else if( target == AMBIGUOUS ) {
        strcpy( buf, "*VARIABLE*" );
    } else if( isGarbage( target ) ) {
        fp = unparse_flags( player, target );
        bp = buf;
        safe_sprintf( buf, &bp, "*GARBAGE*(#%d%s)", target, fp );
        free_sbuf( fp );
    } else if( !Good_obj( target ) ) {
        sprintf( buf, "*ILLEGAL*(#%d)", target );
    } else {
        if( obey_myopic ) {
            exam = MyopicExam( player, target );
        } else {
            exam = Examinable( player, target );
        }
        if( exam ||
                ( Flags( target ) & ( CHOWN_OK | JUMP_OK | LINK_OK |
                                      DESTROY_OK ) ) || ( Flags2( target ) & ABODE ) ) {

            /*
             * show everything
             */
            fp = unparse_flags( player, target );
            bp = buf;
            safe_sprintf( buf, &bp, "%s(#%d%s)", Name( target ), target, fp );
            free_sbuf( fp );
        } else {
            /*
             * show only the name.
             */
            strcpy( buf, Name( target ) );
        }
    }
    return buf;
}
Beispiel #4
0
kadm5_ret_t
_kadm5_privs_to_string(uint32_t privs, char *string, size_t len)
{
    if(privs == 0)
	strlcpy(string, "none", len);
    else
	unparse_flags(privs, acl_units + 1, string, len);
    return 0;
}
Beispiel #5
0
const char *
mfn_flags(MFUNARGS)
{
	dbref obj = mesg_dbref_local(descr, player, what, perms, argv[0], mesgtyp);

	if (obj == UNKNOWN || obj == AMBIGUOUS || obj == NOTHING || obj == HOME)
		ABORT_MPI("FLAGS", "Match failed.");
	if (obj == PERMDENIED)
		ABORT_MPI("FLAGS", "Permission denied.");
	return unparse_flags(obj);
}
Beispiel #6
0
int
nnpfsdebug_cmd (int argc, char **argv)
{
    int ret;
    int flags;

    nnpfsdebug_units[0].mult = all;
    nnpfsdebug_units[1].mult = all & ~almost_all_mask;

    if ((argc > 1 && strncmp(argv[1], "-h", 2) == 0) || argc > 2) {
	fprintf (stderr, "usage: nnpfsdebug [-h] [");
	print_flags_table (nnpfsdebug_units, stderr);
	fprintf (stderr, "]\n");
	return 0;
    }

    ret = nnpfs_debug (-1, &flags);
    if (ret) {
	fprintf (stderr, "nnpfs_debug: %s\n", strerror(ret));
	return 0;
    }

    if (argc == 1) {
	char buf[1024];

	unparse_flags (flags, nnpfsdebug_units, buf, sizeof(buf));
	printf("nnpfsdebug is: %s\n", buf);
    } else if (argc == 2) {
	char *textflags;
	
	textflags = argv[1];
    
	ret = parse_flags (textflags, nnpfsdebug_units, flags);
	
	if (ret < 0) {
	    fprintf (stderr, "nnpfsdebug: unknown/bad flags `%s'\n",
		     textflags);
	    return 0;
	}
	
	flags = ret;
	ret = nnpfs_debug(flags, NULL);
	if (ret)
	    fprintf (stderr, "nnpfs_debug: %s\n", strerror(ret));
    }
    return 0;
}
Beispiel #7
0
const char *
unparse_object(dbref player, dbref loc)
{
    char tbuf[BUFFER_LEN];

    if (Typeof(player) != TYPE_PLAYER)
        player = OWNER(player);
    switch (loc) {
        case NOTHING:
            return "*NOTHING*";
        case AMBIGUOUS:
            return "*AMBIGUOUS*";
        case HOME:
            return "*HOME*";
        case NIL:
            return "*NIL*";
        default:
            if (loc < 0 || loc >= db_top)
#ifdef SANITY
            {
                sprintf(upb, "*INVALID*(#%d)", loc);
                return upb;
            }
#else
                return "*INVALID*";
#endif
#ifndef SANITY
            if (!(FLAGS(player) & STICKY) &&
                (TMage(player) || POWERS(player) & POW_SEE_ALL ||
                 can_link_to(player, NOTYPE, loc) ||
                 controls_link(player, loc) ||
                 ((Typeof(loc) != TYPE_PLAYER) && (FLAGS(loc) & CHOWN_OK))
                )) {
                /* show everything */
#endif
                sprintf(upb, "%s(#%d%s)", NAME(loc), loc,
                        unparse_flags(loc, tbuf));
                return upb;
#ifndef SANITY
            } else {
                /* show only the name */
                return NAME(loc);
            }
#endif
    }
}
const char *
unparse_object(dbref player, dbref loc)
{
    static char buf[BUFFER_LEN];

    if (Typeof(player) != TYPE_PLAYER)
	player = OWNER(player);
    switch (loc) {
	case NOTHING:
	    return "*NOTHING*";
	case AMBIGUOUS:
	    return "*AMBIGUOUS*";
	case HOME:
	    return "*HOME*";
	default:
	    if (loc < 0 || loc > db_top)
#ifdef SANITY
	    {
	        sprintf(buf, "*INVALID*(#%d)", loc);
	        return buf;
	    }
#else
		return "*INVALID*";
#endif
#ifndef SANITY
	    if (!(FLAGS(player) & STICKY) &&
		    (can_link_to(player, NOTYPE, loc) ||
		     ((Typeof(loc) != TYPE_PLAYER) &&
		      (controls_link(player, loc) ||
		       (FLAGS(loc) & CHOWN_OK)))
		    )) {
		/* show everything */
#endif
		sprintf(buf, "%s(#%d%s)", PNAME(loc), loc, unparse_flags(loc));
		return buf;
#ifndef SANITY
	    } else {
		/* show only the name */
		return PNAME(loc);
	    }
#endif
    }
}
Beispiel #9
0
const char *
ansi_unparse_object(dbref player, dbref loc)
{
    char tbuf[BUFFER_LEN], tbuf2[BUFFER_LEN];

    if (Typeof(player) != TYPE_PLAYER)
        player = OWNER(player);
    switch (loc) {
        case NOTHING:
            return SYSNORMAL "*NOTHING*";
        case AMBIGUOUS:
            return SYSPURPLE "*AMBIGUOUS*";
        case HOME:
            return SYSWHITE "*HOME*";
        case NIL:
            return SYSCYAN "*NIL*";
        default:
            if (loc < 0 || loc >= db_top) {
                sprintf(upb, SYSRED "*INVALID(#%d)*", loc);
                return upb;
            }
#ifndef SANITY
            if (!(FLAGS(player) & STICKY) &&
                (TMage(player) || POWERS(player) & POW_SEE_ALL ||
                 POWERS(player) & POW_SEARCH ||
                 can_link_to(player, NOTYPE, loc) ||
                 controls_link(player, loc) ||
                 ((Typeof(loc) != TYPE_PLAYER) && (FLAGS(loc) & CHOWN_OK))
                )) {
#endif
                /* show everything */
                sprintf(upb, "%s" SYSYELLOW "(#%d%s)",
                        ansiname(loc, tbuf), loc, unparse_flags(loc, tbuf2));
                return upb;
#ifndef SANITY
            } else {
                /* show only the name */
                return ansiname(loc, upb);
            }
#endif
    }
}
Beispiel #10
0
int
hx509_cert_keyusage_print(hx509_context context, hx509_cert c, char **s)
{
    KeyUsage ku;
    char buf[256];
    int ret;

    *s = NULL;

    ret = _hx509_cert_get_keyusage(context, c, &ku);
    if (ret)
	return ret;
    unparse_flags(KeyUsage2int(ku), asn1_KeyUsage_units(), buf, sizeof(buf));
    *s = strdup(buf);
    if (*s == NULL) {
	hx509_set_error_string(context, 0, ENOMEM, "out of memory");
	return ENOMEM;
    }

    return 0;
}
Beispiel #11
0
const char *
ansi_unparse_object(dbref player, dbref loc)
{
    char tbuf[BUFFER_LEN], tbuf2[BUFFER_LEN];

    if (Typeof(player) != TYPE_PLAYER)
	player = OWNER(player);
    switch (loc) {
	case NOTHING:
	    return CGLOOM "*NOTHING*";
	case AMBIGUOUS:
	    return CPURPLE "*AMBIGUOUS*";
	case HOME:
	    return CWHITE "*HOME*";
	default:
	    if (!OkObj(loc))
		return CRED "*INVALID*";
#ifndef SANITY
	    if (!(FLAGS(player) & STICKY) &&
		    (TMage(player) ||
		     can_link_to(player, NOTYPE, loc) ||
		     controls_link(player, loc) ||
		     ((Typeof(loc) != TYPE_PLAYER) &&
		     (FLAGS(loc) & CHOWN_OK))
		    )) {
#endif
		/* show everything */
		sprintf(upb, "%s" CYELLOW "(#%d%s)",
		    ansiname(loc, tbuf), loc, unparse_flags(loc, tbuf2));
		return upb;
#ifndef SANITY
	    } else {
		/* show only the name */
		return ansiname(loc, upb);
	    }
#endif
    }
}
Beispiel #12
0
static char *
quick_space_unparse(dbref object)
{
  static char buff[BUFFER_LEN], *bp;

  switch (object) {
  case NOTHING:
    strcpy(buff, T("*NOTHING*"));
    break;
  case AMBIGUOUS:
    strcpy(buff, T("*VARIABLE*"));
    break;
  case HOME:
    strcpy(buff, T("*HOME*"));
    break;
  default:
    bp = buff;
    safe_format(buff, &bp, "%s(#%d%s)",
		Name(object), object, unparse_flags(object, GOD));
    *bp = '\0';
  }

  return buff;
}
Beispiel #13
0
static krb5_error_code
tgs_build_reply(krb5_context context, 
		krb5_kdc_configuration *config,
		KDC_REQ *req, 
		KDC_REQ_BODY *b,
		hdb_entry_ex *krbtgt,
		krb5_enctype krbtgt_etype,
		krb5_ticket *ticket,
		krb5_data *reply,
		const char *from,
		const char **e_text,
		AuthorizationData *auth_data,
		const struct sockaddr *from_addr,
		int datagram_reply)
{
    krb5_error_code ret;
    krb5_principal cp = NULL, sp = NULL;
    krb5_principal client_principal = NULL;
    char *spn = NULL, *cpn = NULL;
    hdb_entry_ex *server = NULL, *client = NULL;
    EncTicketPart *tgt = &ticket->ticket;
    KRB5SignedPathPrincipals *spp = NULL;
    const EncryptionKey *ekey;
    krb5_keyblock sessionkey;
    krb5_kvno kvno;
    krb5_data rspac;
    int cross_realm = 0;

    PrincipalName *s;
    Realm r;
    int nloop = 0;
    EncTicketPart adtkt;
    char opt_str[128];
    int require_signedpath = 0;

    memset(&sessionkey, 0, sizeof(sessionkey));
    memset(&adtkt, 0, sizeof(adtkt));
    krb5_data_zero(&rspac);

    s = b->sname;
    r = b->realm;

    if(b->kdc_options.enc_tkt_in_skey){
	Ticket *t;
	hdb_entry_ex *uu;
	krb5_principal p;
	Key *uukey;
	    
	if(b->additional_tickets == NULL || 
	   b->additional_tickets->len == 0){
	    ret = KRB5KDC_ERR_BADOPTION; /* ? */
	    kdc_log(context, config, 0,
		    "No second ticket present in request");
	    goto out;
	}
	t = &b->additional_tickets->val[0];
	if(!get_krbtgt_realm(&t->sname)){
	    kdc_log(context, config, 0,
		    "Additional ticket is not a ticket-granting ticket");
	    ret = KRB5KDC_ERR_POLICY;
	    goto out;
	}
	_krb5_principalname2krb5_principal(context, &p, t->sname, t->realm);
	ret = _kdc_db_fetch(context, config, p, 
			    HDB_F_GET_CLIENT|HDB_F_GET_SERVER, 
			    NULL, &uu);
	krb5_free_principal(context, p);
	if(ret){
	    if (ret == HDB_ERR_NOENTRY)
		ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
	    goto out;
	}
	ret = hdb_enctype2key(context, &uu->entry, 
			      t->enc_part.etype, &uukey);
	if(ret){
	    _kdc_free_ent(context, uu);
	    ret = KRB5KDC_ERR_ETYPE_NOSUPP; /* XXX */
	    goto out;
	}
	ret = krb5_decrypt_ticket(context, t, &uukey->key, &adtkt, 0);
	_kdc_free_ent(context, uu);
	if(ret)
	    goto out;

	ret = verify_flags(context, config, &adtkt, spn);
	if (ret)
	    goto out;

	s = &adtkt.cname;
	r = adtkt.crealm;
    }

    _krb5_principalname2krb5_principal(context, &sp, *s, r);
    ret = krb5_unparse_name(context, sp, &spn);	
    if (ret)
	goto out;
    _krb5_principalname2krb5_principal(context, &cp, tgt->cname, tgt->crealm);
    ret = krb5_unparse_name(context, cp, &cpn);
    if (ret)
	goto out;
    unparse_flags (KDCOptions2int(b->kdc_options),
		   asn1_KDCOptions_units(),
		   opt_str, sizeof(opt_str));
    if(*opt_str)
	kdc_log(context, config, 0,
		"TGS-REQ %s from %s for %s [%s]", 
		cpn, from, spn, opt_str);
    else
	kdc_log(context, config, 0,
		"TGS-REQ %s from %s for %s", cpn, from, spn);

    /*
     * Fetch server
     */

server_lookup:
    ret = _kdc_db_fetch(context, config, sp, HDB_F_GET_SERVER, NULL, &server);

    if(ret){
	const char *new_rlm;
	Realm req_rlm;
	krb5_realm *realms;

	if ((req_rlm = get_krbtgt_realm(&sp->name)) != NULL) {
	    if(nloop++ < 2) {
		new_rlm = find_rpath(context, tgt->crealm, req_rlm);
		if(new_rlm) {
		    kdc_log(context, config, 5, "krbtgt for realm %s "
			    "not found, trying %s", 
			    req_rlm, new_rlm);
		    krb5_free_principal(context, sp);
		    free(spn);
		    krb5_make_principal(context, &sp, r, 
					KRB5_TGS_NAME, new_rlm, NULL);
		    ret = krb5_unparse_name(context, sp, &spn);	
		    if (ret)
			goto out;
		    goto server_lookup;
		}
	    }
	} else if(need_referral(context, sp, &realms)) {
	    if (strcmp(realms[0], sp->realm) != 0) {
		kdc_log(context, config, 5,
			"Returning a referral to realm %s for "
			"server %s that was not found",
			realms[0], spn);
		krb5_free_principal(context, sp);
		free(spn);
		krb5_make_principal(context, &sp, r, KRB5_TGS_NAME,
				    realms[0], NULL);
		ret = krb5_unparse_name(context, sp, &spn);
		if (ret)
		    goto out;
		krb5_free_host_realm(context, realms);
		goto server_lookup;
	    }
	    krb5_free_host_realm(context, realms);
	}
	kdc_log(context, config, 0,
		"Server not found in database: %s: %s", spn,
		krb5_get_err_text(context, ret));
	if (ret == HDB_ERR_NOENTRY)
	    ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
	goto out;
    }

    ret = _kdc_db_fetch(context, config, cp, HDB_F_GET_CLIENT, NULL, &client);
    if(ret) {
	const char *krbtgt_realm; 

	/*
	 * If the client belongs to the same realm as our krbtgt, it
	 * should exist in the local database.
	 *
	 */

	krbtgt_realm = 
	    krb5_principal_get_comp_string(context, 
					   krbtgt->entry.principal, 1);

	if(strcmp(krb5_principal_get_realm(context, cp), krbtgt_realm) == 0) {
	    if (ret == HDB_ERR_NOENTRY)
		ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
	    kdc_log(context, config, 1, "Client no longer in database: %s",
		    cpn);
	    goto out;
	}
	
	kdc_log(context, config, 1, "Client not found in database: %s: %s",
		cpn, krb5_get_err_text(context, ret));

	cross_realm = 1;
    }
    
    /*
     * Check that service is in the same realm as the krbtgt. If its
     * not the same, its someone that is using a uni-directional trust
     * backward.
     */
    
    if (strcmp(krb5_principal_get_realm(context, sp),
	       krb5_principal_get_comp_string(context, 
					      krbtgt->entry.principal, 
					      1)) != 0) {
	char *tpn;
	ret = krb5_unparse_name(context, krbtgt->entry.principal, &tpn);
	kdc_log(context, config, 0,
		"Request with wrong krbtgt: %s",
		(ret == 0) ? tpn : "<unknown>");
	if(ret == 0)
	    free(tpn);
	ret = KRB5KRB_AP_ERR_NOT_US;
	goto out;
    }

    /*
     *
     */

    client_principal = cp;

    if (client) {
	const PA_DATA *sdata;
	int i = 0;

	sdata = _kdc_find_padata(req, &i, KRB5_PADATA_S4U2SELF);
	if (sdata) {
	    krb5_crypto crypto;
	    krb5_data datack;
	    PA_S4U2Self self;
	    char *selfcpn = NULL;
	    const char *str;

	    ret = decode_PA_S4U2Self(sdata->padata_value.data, 
				     sdata->padata_value.length,
				     &self, NULL);
	    if (ret) {
		kdc_log(context, config, 0, "Failed to decode PA-S4U2Self");
		goto out;
	    }

	    ret = _krb5_s4u2self_to_checksumdata(context, &self, &datack);
	    if (ret)
		goto out;

	    ret = krb5_crypto_init(context, &tgt->key, 0, &crypto);
	    if (ret) {
		free_PA_S4U2Self(&self);
		krb5_data_free(&datack);
		kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
			krb5_get_err_text(context, ret));
		goto out;
	    }

	    ret = krb5_verify_checksum(context,
				       crypto,
				       KRB5_KU_OTHER_CKSUM,
				       datack.data, 
				       datack.length, 
				       &self.cksum);
	    krb5_data_free(&datack);
	    krb5_crypto_destroy(context, crypto);
	    if (ret) {
		free_PA_S4U2Self(&self);
		kdc_log(context, config, 0, 
			"krb5_verify_checksum failed for S4U2Self: %s",
			krb5_get_err_text(context, ret));
		goto out;
	    }

	    ret = _krb5_principalname2krb5_principal(context,
						     &client_principal,
						     self.name,
						     self.realm);
	    free_PA_S4U2Self(&self);
	    if (ret)
		goto out;

	    ret = krb5_unparse_name(context, client_principal, &selfcpn);	
	    if (ret)
		goto out;

	    /*
	     * Check that service doing the impersonating is
	     * requesting a ticket to it-self.
	     */
	    if (krb5_principal_compare(context, cp, sp) != TRUE) {
		kdc_log(context, config, 0, "S4U2Self: %s is not allowed "
			"to impersonate some other user "
			"(tried for user %s to service %s)",
			cpn, selfcpn, spn);
		free(selfcpn);
		ret = KRB5KDC_ERR_BADOPTION; /* ? */
		goto out;
	    }

	    /*
	     * If the service isn't trusted for authentication to
	     * delegation, remove the forward flag.
	     */

	    if (client->entry.flags.trusted_for_delegation) {
		str = "[forwardable]";
	    } else {
		b->kdc_options.forwardable = 0;
		str = "";
	    }
	    kdc_log(context, config, 0, "s4u2self %s impersonating %s to "
		    "service %s %s", cpn, selfcpn, spn, str);
	    free(selfcpn);
	}
    }

    /*
     * Constrained delegation
     */

    if (client != NULL
	&& b->additional_tickets != NULL
	&& b->additional_tickets->len != 0
	&& b->kdc_options.enc_tkt_in_skey == 0)
    {
	Key *clientkey;
	Ticket *t;
	char *str;

	t = &b->additional_tickets->val[0];

	ret = hdb_enctype2key(context, &client->entry, 
			      t->enc_part.etype, &clientkey);
	if(ret){
	    ret = KRB5KDC_ERR_ETYPE_NOSUPP; /* XXX */
	    goto out;
	}

	ret = krb5_decrypt_ticket(context, t, &clientkey->key, &adtkt, 0);
	if (ret) {
	    kdc_log(context, config, 0,
		    "failed to decrypt ticket for "
		    "constrained delegation from %s to %s ", spn, cpn);
	    goto out;
	}

	/* check that ticket is valid */

	if (adtkt.flags.forwardable == 0) {
	    kdc_log(context, config, 0,
		    "Missing forwardable flag on ticket for "
		    "constrained delegation from %s to %s ", spn, cpn);
	    ret = KRB5KDC_ERR_ETYPE_NOSUPP; /* XXX */
	    goto out;
	}

	ret = check_constrained_delegation(context, config, client, sp);
	if (ret) {
	    kdc_log(context, config, 0,
		    "constrained delegation from %s to %s not allowed", 
		    spn, cpn);
	    goto out;
	}

	ret = _krb5_principalname2krb5_principal(context,
						 &client_principal,
						 adtkt.cname,
						 adtkt.crealm);
	if (ret)
	    goto out;

	ret = krb5_unparse_name(context, client_principal, &str);
	if (ret)
	    goto out;

	ret = verify_flags(context, config, &adtkt, str);
	if (ret) {
	    free(str);
	    goto out;
	}

	/*
	 * Check KRB5SignedPath in authorization data and add new entry to
	 * make sure servers can't fake a ticket to us.
	 */

	ret = check_KRB5SignedPath(context,
				   config,
				   krbtgt,
				   &adtkt,
				   &spp,
				   1);
	if (ret) {
	    kdc_log(context, config, 0,
		    "KRB5SignedPath check from service %s failed "
		    "for delegation to %s for client %s "
		    "from %s failed with %s",
		    spn, str, cpn, from, krb5_get_err_text(context, ret));
	    free(str);
	    goto out;
	}

	kdc_log(context, config, 0, "constrained delegation for %s "
		"from %s to %s", str, cpn, spn);
	free(str);

	/* 
	 * Also require that the KDC have issue the service's krbtgt
	 * used to do the request. 
	 */
	require_signedpath = 1;
    }

    /*
     * Check flags
     */

    ret = _kdc_check_flags(context, config, 
			   client, cpn,
			   server, spn,
			   FALSE);
    if(ret)
	goto out;

    if((b->kdc_options.validate || b->kdc_options.renew) && 
       !krb5_principal_compare(context, 
			       krbtgt->entry.principal,
			       server->entry.principal)){
	kdc_log(context, config, 0, "Inconsistent request.");
	ret = KRB5KDC_ERR_SERVER_NOMATCH;
	goto out;
    }

    /* check for valid set of addresses */
    if(!_kdc_check_addresses(context, config, tgt->caddr, from_addr)) {
	ret = KRB5KRB_AP_ERR_BADADDR;
	kdc_log(context, config, 0, "Request from wrong address");
	goto out;
    }
	
    /*
     * Select enctype, return key and kvno.
     */

    {
	krb5_enctype etype;

	if(b->kdc_options.enc_tkt_in_skey) {
	    int i;
	    ekey = &adtkt.key;
	    for(i = 0; i < b->etype.len; i++)
		if (b->etype.val[i] == adtkt.key.keytype)
		    break;
	    if(i == b->etype.len) {
		krb5_clear_error_string(context);
		return KRB5KDC_ERR_ETYPE_NOSUPP;
	    }
	    etype = b->etype.val[i];
	    kvno = 0;
	} else {
	    Key *skey;
	    
	    ret = _kdc_find_etype(context, server, b->etype.val, b->etype.len,
				  &skey, &etype);
	    if(ret) {
		kdc_log(context, config, 0, 
			"Server (%s) has no support for etypes", spp);
		return ret;
	    }
	    ekey = &skey->key;
	    kvno = server->entry.kvno;
	}
	
	ret = krb5_generate_random_keyblock(context, etype, &sessionkey);
	if (ret)
	    goto out;
    }

    /* check PAC if not cross realm and if there is one */
    if (!cross_realm) {
	Key *tkey;

	ret = hdb_enctype2key(context, &krbtgt->entry, 
			      krbtgt_etype, &tkey);
	if(ret) {
	    kdc_log(context, config, 0,
		    "Failed to find key for krbtgt PAC check");
	    goto out;
	}

	ret = check_PAC(context, config, client_principal, 
			client, server, ekey, &tkey->key,
			tgt, &rspac, &require_signedpath);
	if (ret) {
	    kdc_log(context, config, 0,
		    "Verify PAC failed for %s (%s) from %s with %s",
		    spn, cpn, from, krb5_get_err_text(context, ret));
	    goto out;
	}
    }

    /* also check the krbtgt for signature */
    ret = check_KRB5SignedPath(context,
			       config,
			       krbtgt,
			       tgt,
			       &spp,
			       require_signedpath);
    if (ret) {
	kdc_log(context, config, 0,
		"KRB5SignedPath check failed for %s (%s) from %s with %s",
		spn, cpn, from, krb5_get_err_text(context, ret));
	goto out;
    }

    /*
     *
     */

    ret = tgs_make_reply(context,
			 config, 
			 b, 
			 client_principal,
			 tgt, 
			 ekey,
			 &sessionkey,
			 kvno,
			 auth_data,
			 server, 
			 spn,
			 client, 
			 cp, 
			 krbtgt, 
			 krbtgt_etype,
			 spp,
			 &rspac,
			 e_text,
			 reply);
	
out:
    free(spn);
    free(cpn);
	    
    krb5_data_free(&rspac);
    krb5_free_keyblock_contents(context, &sessionkey);
    if(server)
	_kdc_free_ent(context, server);
    if(client)
	_kdc_free_ent(context, client);

    if (client_principal && client_principal != cp)
	krb5_free_principal(context, client_principal);
    if (cp)
	krb5_free_principal(context, cp);
    if (sp)
	krb5_free_principal(context, sp);

    free_EncTicketPart(&adtkt);

    return ret;
}
Beispiel #14
0
static void
print_cred_verbose(krb5_context context, krb5_creds *cred)
{
    int j;
    char *str;
    krb5_error_code ret;
    krb5_timestamp sec;

    krb5_timeofday (context, &sec);

    ret = krb5_unparse_name(context, cred->server, &str);
    if(ret)
	exit(1);
    printf(N_("Server: %s\n", ""), str);
    free (str);
    
    ret = krb5_unparse_name(context, cred->client, &str);
    if(ret)
	exit(1);
    printf(N_("Client: %s\n", ""), str);
    free (str);
    
    {
	Ticket t;
	size_t len;
	char *s;
	
	decode_Ticket(cred->ticket.data, cred->ticket.length, &t, &len);
	ret = krb5_enctype_to_string(context, t.enc_part.etype, &s);
	printf(N_("Ticket etype: ", ""));
	if (ret == 0) {
	    printf("%s", s);
	    free(s);
	} else {
	    printf(N_("unknown-enctype(%d)", ""), t.enc_part.etype);
	}
	if(t.enc_part.kvno)
	    printf(N_(", kvno %d", ""), *t.enc_part.kvno);
	printf("\n");
	if(cred->session.keytype != t.enc_part.etype) {
	    ret = krb5_enctype_to_string(context, cred->session.keytype, &str);
	    if(ret)
		krb5_warn(context, ret, "session keytype");
	    else {
		printf(N_("Session key: %s\n", "enctype"), str);
		free(str);
	    }
	}
	free_Ticket(&t);
	printf(N_("Ticket length: %lu\n", ""),
	       (unsigned long)cred->ticket.length);
    }
    printf(N_("Auth time:  %s\n", ""),
	   printable_time_long(cred->times.authtime));
    if(cred->times.authtime != cred->times.starttime)
	printf(N_("Start time: %s\n", ""),
	       printable_time_long(cred->times.starttime));
    printf(N_("End time:   %s", ""),
	   printable_time_long(cred->times.endtime));
    if(sec > cred->times.endtime)
	printf(N_(" (expired)", ""));
    printf("\n");
    if(cred->flags.b.renewable)
	printf(N_("Renew till: %s\n", ""),
	       printable_time_long(cred->times.renew_till));
    {
	char flags[1024];
	unparse_flags(TicketFlags2int(cred->flags.b), 
		      asn1_TicketFlags_units(),
		      flags, sizeof(flags));
	printf(N_("Ticket flags: %s\n", ""), flags);
    }
    printf(N_("Addresses: ", ""));
    if (cred->addresses.len != 0) {
	for(j = 0; j < cred->addresses.len; j++){
	    char buf[128];
	    size_t len;
	    if(j) printf(", ");
	    ret = krb5_print_address(&cred->addresses.val[j],
				     buf, sizeof(buf), &len);
	
	    if(ret == 0)
		printf("%s", buf);
	}
    } else {
	printf(N_("addressless", ""));
    }
    printf("\n\n");
}
Beispiel #15
0
static int
p11_printinfo(hx509_context context, 
	      hx509_certs certs, 
	      void *data,
	      int (*func)(void *, const char *),
	      void *ctx)
{
    struct p11_module *p = data;
    int i, j;
        
    _hx509_pi_printf(func, ctx, "pkcs11 driver with %d slot%s", 
		     p->num_slots, p->num_slots > 1 ? "s" : "");

    for (i = 0; i < p->num_slots; i++) {
	struct p11_slot *s = &p->slot[i];

	_hx509_pi_printf(func, ctx, "slot %d: id: %d name: %s flags: %08x",
			 i, (int)s->id, s->name, s->flags);

	_hx509_pi_printf(func, ctx, "number of supported mechanisms: %lu", 
			 (unsigned long)s->mechs.num);
	for (j = 0; j < s->mechs.num; j++) {
	    const char *mechname = "unknown";
	    char flags[256], unknownname[40];
#define MECHNAME(s,n) case s: mechname = n; break
	    switch(s->mechs.list[j]) {
		MECHNAME(CKM_RSA_PKCS_KEY_PAIR_GEN, "rsa-pkcs-key-pair-gen");
		MECHNAME(CKM_RSA_PKCS, "rsa-pkcs");
		MECHNAME(CKM_RSA_X_509, "rsa-x-509");
		MECHNAME(CKM_MD5_RSA_PKCS, "md5-rsa-pkcs");
		MECHNAME(CKM_SHA1_RSA_PKCS, "sha1-rsa-pkcs");
		MECHNAME(CKM_SHA256_RSA_PKCS, "sha256-rsa-pkcs");
		MECHNAME(CKM_SHA384_RSA_PKCS, "sha384-rsa-pkcs");
		MECHNAME(CKM_SHA512_RSA_PKCS, "sha512-rsa-pkcs");
		MECHNAME(CKM_RIPEMD160_RSA_PKCS, "ripemd160-rsa-pkcs");
		MECHNAME(CKM_RSA_PKCS_OAEP, "rsa-pkcs-oaep");
		MECHNAME(CKM_SHA512_HMAC, "sha512-hmac");
		MECHNAME(CKM_SHA512, "sha512");
		MECHNAME(CKM_SHA384_HMAC, "sha384-hmac");
		MECHNAME(CKM_SHA384, "sha384");
		MECHNAME(CKM_SHA256_HMAC, "sha256-hmac");
		MECHNAME(CKM_SHA256, "sha256");
		MECHNAME(CKM_SHA_1, "sha1");
		MECHNAME(CKM_MD5, "md5");
		MECHNAME(CKM_MD2, "md2");
		MECHNAME(CKM_RIPEMD160, "ripemd-160");
		MECHNAME(CKM_DES_ECB, "des-ecb");
		MECHNAME(CKM_DES_CBC, "des-cbc");
		MECHNAME(CKM_AES_ECB, "aes-ecb");
		MECHNAME(CKM_AES_CBC, "aes-cbc");
		MECHNAME(CKM_DH_PKCS_PARAMETER_GEN, "dh-pkcs-parameter-gen");
	    default:
		snprintf(unknownname, sizeof(unknownname),
			 "unknown-mech-%lu", 
			 (unsigned long)s->mechs.list[j]);
		mechname = unknownname;
		break;
	    }
#undef MECHNAME
	    unparse_flags(s->mechs.infos[j]->flags, mechflags, 
			  flags, sizeof(flags));

	    _hx509_pi_printf(func, ctx, "  %s: %s", mechname, flags);
	}
    }

    return 0;
}
Beispiel #16
0
void
attributes2str(krb5_flags attributes, char *str, size_t len)
{
    unparse_flags (attributes, kdb_attrs, str, len);
}
Beispiel #17
0
static void
print_entry(kadm5_server_context *server_context,
	    uint32_t ver,
	    time_t timestamp,
	    enum kadm_ops op,
	    uint32_t len,
	    krb5_storage *sp,
	    void *ctx)
{
    char t[256];
    int32_t mask;
    hdb_entry ent;
    krb5_principal source;
    char *name1, *name2;
    krb5_data data;
    krb5_context scontext = server_context->context;

    off_t end = krb5_storage_seek(sp, 0, SEEK_CUR) + len;

    krb5_error_code ret;

    strftime(t, sizeof(t), "%Y-%m-%d %H:%M:%S", localtime(&timestamp));

    if((int)op < (int)kadm_get || (int)op > (int)kadm_nop) {
	printf("unknown op: %d\n", op);
	krb5_storage_seek(sp, end, SEEK_SET);
	return;
    }

    printf ("%s: ver = %u, timestamp = %s, len = %u\n",
	    op_names[op], ver, t, len);
    switch(op) {
    case kadm_delete:
	krb5_ret_principal(sp, &source);
	krb5_unparse_name(scontext, source, &name1);
	printf("    %s\n", name1);
	free(name1);
	krb5_free_principal(scontext, source);
	break;
    case kadm_rename:
	ret = krb5_data_alloc(&data, len);
	if (ret)
	    krb5_err (scontext, 1, ret, "kadm_rename: data alloc: %d", len);
	krb5_ret_principal(sp, &source);
	krb5_storage_read(sp, data.data, data.length);
	hdb_value2entry(scontext, &data, &ent);
	krb5_unparse_name(scontext, source, &name1);
	krb5_unparse_name(scontext, ent.principal, &name2);
	printf("    %s -> %s\n", name1, name2);
	free(name1);
	free(name2);
	krb5_free_principal(scontext, source);
	free_hdb_entry(&ent);
	break;
    case kadm_create:
	ret = krb5_data_alloc(&data, len);
	if (ret)
	    krb5_err (scontext, 1, ret, "kadm_create: data alloc: %d", len);
	krb5_storage_read(sp, data.data, data.length);
	ret = hdb_value2entry(scontext, &data, &ent);
	if(ret)
	    abort();
	mask = ~0;
	goto foo;
    case kadm_modify:
	ret = krb5_data_alloc(&data, len);
	if (ret)
	    krb5_err (scontext, 1, ret, "kadm_modify: data alloc: %d", len);
	krb5_ret_int32(sp, &mask);
	krb5_storage_read(sp, data.data, data.length);
	ret = hdb_value2entry(scontext, &data, &ent);
	if(ret)
	    abort();
    foo:
	if(ent.principal /* mask & KADM5_PRINCIPAL */) {
	    krb5_unparse_name(scontext, ent.principal, &name1);
	    printf("    principal = %s\n", name1);
	    free(name1);
	}
	if(mask & KADM5_PRINC_EXPIRE_TIME) {
	    if(ent.valid_end == NULL) {
		strlcpy(t, "never", sizeof(t));
	    } else {
		strftime(t, sizeof(t), "%Y-%m-%d %H:%M:%S",
			 localtime(ent.valid_end));
	    }
	    printf("    expires = %s\n", t);
	}
	if(mask & KADM5_PW_EXPIRATION) {
	    if(ent.pw_end == NULL) {
		strlcpy(t, "never", sizeof(t));
	    } else {
		strftime(t, sizeof(t), "%Y-%m-%d %H:%M:%S",
			 localtime(ent.pw_end));
	    }
	    printf("    password exp = %s\n", t);
	}
	if(mask & KADM5_LAST_PWD_CHANGE) {
	}
	if(mask & KADM5_ATTRIBUTES) {
	    unparse_flags(HDBFlags2int(ent.flags),
			  asn1_HDBFlags_units(), t, sizeof(t));
	    printf("    attributes = %s\n", t);
	}
	if(mask & KADM5_MAX_LIFE) {
	    if(ent.max_life == NULL)
		strlcpy(t, "for ever", sizeof(t));
	    else
		unparse_time(*ent.max_life, t, sizeof(t));
	    printf("    max life = %s\n", t);
	}
	if(mask & KADM5_MAX_RLIFE) {
	    if(ent.max_renew == NULL)
		strlcpy(t, "for ever", sizeof(t));
	    else
		unparse_time(*ent.max_renew, t, sizeof(t));
	    printf("    max rlife = %s\n", t);
	}
	if(mask & KADM5_MOD_TIME) {
	    printf("    mod time\n");
	}
	if(mask & KADM5_MOD_NAME) {
	    printf("    mod name\n");
	}
	if(mask & KADM5_KVNO) {
	    printf("    kvno = %d\n", ent.kvno);
	}
	if(mask & KADM5_MKVNO) {
	    printf("    mkvno\n");
	}
	if(mask & KADM5_AUX_ATTRIBUTES) {
	    printf("    aux attributes\n");
	}
	if(mask & KADM5_POLICY) {
	    printf("    policy\n");
	}
	if(mask & KADM5_POLICY_CLR) {
	    printf("    mod time\n");
	}
	if(mask & KADM5_LAST_SUCCESS) {
	    printf("    last success\n");
	}
	if(mask & KADM5_LAST_FAILED) {
	    printf("    last failed\n");
	}
	if(mask & KADM5_FAIL_AUTH_COUNT) {
	    printf("    fail auth count\n");
	}
	if(mask & KADM5_KEY_DATA) {
	    printf("    key data\n");
	}
	if(mask & KADM5_TL_DATA) {
	    printf("    tl data\n");
	}
	free_hdb_entry(&ent);
	break;
    case kadm_nop :
	break;
    default:
	abort();
    }
    krb5_storage_seek(sp, end, SEEK_SET);
}