Example #1
0
Code_t
Z_MakeZcodeAuthentication(register ZNotice_t *notice,
			  char *buffer,
			  int buffer_len,
			  int *phdr_len,
			  krb5_creds *creds)
{
    krb5_error_code result = 0;
    krb5_keyblock *keyblock;
    krb5_auth_context authctx;
    krb5_data *authent;
    char *cksum_start, *cstart, *cend;
    int cksum_len, zcode_len = 0, phdr_adj = 0;

    notice->z_ascii_authent = NULL;

    keyblock = Z_credskey(creds);

    authent = (krb5_data *)malloc(sizeof(krb5_data));
    if (authent == NULL)
	result = ENOMEM;
    authent->data = NULL; /* so that we can blithely krb5_fre_data_contents on
			     the way out */

    if (!result)
	result = krb5_auth_con_init(Z_krb5_ctx, &authctx);

    if (!result) {
	result = krb5_mk_req_extended(Z_krb5_ctx, &authctx, 0 /* options */,
				      0 /* in_data */, creds, authent);
	krb5_auth_con_free(Z_krb5_ctx, authctx);
    }
    if (!result || result == KRB5KRB_AP_ERR_TKT_EXPIRED) {
	notice->z_auth = 1;
	if (result == 0) {
	    notice->z_authent_len = authent->length;
	} else {
	    notice->z_authent_len = 0;
	    result = 0;
	}
	zcode_len = notice->z_authent_len * 2 + 2; /* 2x growth plus Z and null */
	notice->z_ascii_authent = (char *)malloc(zcode_len);
	if (notice->z_ascii_authent == NULL)
	    result = ENOMEM;
    }
    if (!result)
	result = ZMakeZcode(notice->z_ascii_authent, zcode_len,
			    (unsigned char *)authent->data, notice->z_authent_len);

    /* format the notice header, with a zero checksum */
    if (!result)
	result = Z_NewFormatRawHeader(notice, buffer, buffer_len, phdr_len,
				      &cksum_start, &cksum_len, &cstart, &cend);
    notice->z_authent_len = 0;
    if (!result)
	result = Z_InsertZcodeChecksum(keyblock, notice, buffer, cksum_start,
				       cksum_len, cstart, cend, buffer_len,
				       &phdr_adj, 0);
    if (!result) 
	*phdr_len += phdr_adj;

    if (notice->z_ascii_authent != NULL)
	free(notice->z_ascii_authent);
    krb5_free_data_contents(Z_krb5_ctx, authent);
    if (authent != NULL)
	free(authent);
    return result;
}
Example #2
0
int
_GetSecurityObject(struct afscp_cell *cell)
{
    int code = ENOENT;
#ifdef HAVE_KERBEROS
    krb5_context context;
    krb5_creds match;
    krb5_creds *cred;
    krb5_ccache cc;
    char **realms, *realm;
    struct afsconf_cell celldata;
    char localcell[MAXCELLCHARS + 1];
    struct rx_securityClass *sc;
    struct ktc_encryptionKey k;
    int i;
    rxkad_level l;
    code = _GetCellInfo(cell->name, &celldata);
    if (code != 0) {
	goto try_anon;
    }

    if (authas_name[0]) {
	code = _GetLocalSecurityObject(cell, authas_name, authas_inst);
	if (code == 0) {
	    return 0;
	}
    }

    code = krb5_init_context(&context);	/* see aklog.c main() */
    if (code != 0) {
	goto try_anon;
    }

    if (cell->realm == NULL) {
	realm = NULL;
	code = krb5_get_host_realm(context, celldata.hostName[0], &realms);

	if (code == 0) {
	    strlcpy(localcell, realms[0], sizeof(localcell));
	    krb5_free_host_realm(context, realms);
	    realm = localcell;
	} else
	    goto try_anon;
    } else {
	realm = cell->realm;
	strlcpy(localcell, realm, MAXCELLCHARS + 1);
    }
    if (realm)
	if (realm == NULL) {
	    for (i = 0; (i < MAXCELLCHARS && cell->name[i]); i++) {
		if (isalpha(cell->name[i]))
		    localcell[i] = toupper(cell->name[i]);
		else
		    localcell[i] = cell->name[i];
	    }
	    localcell[i] = '\0';
	    realm = localcell;
	}
    cc = NULL;
    code = krb5_cc_default(context, &cc);

    memset(&match, 0, sizeof(match));
    Z_enctype(Z_credskey(&match)) = ENCTYPE_DES_CBC_CRC;

    if (code == 0)
	code = krb5_cc_get_principal(context, cc, &match.client);
    if (code == 0)
	code = krb5_build_principal(context, &match.server,
				    strlen(realm), realm,
				    "afs", cell->name, NULL);

    if (code != 0) {
	krb5_free_cred_contents(context, &match);
	if (cc)
	    krb5_cc_close(context, cc);
	krb5_free_context(context);
	goto try_anon;
    }

    code = krb5_get_credentials(context, 0, cc, &match, &cred);
    if (code != 0) {
	krb5_free_principal(context, match.server);
	match.server = NULL;

	code = krb5_build_principal(context, &match.server,
				    strlen(realm), realm, "afs", NULL);
	if (code == 0)
	    code = krb5_get_credentials(context, 0, cc, &match, &cred);
	if (code != 0) {
	    krb5_free_cred_contents(context, &match);
	    if (cc)
		krb5_cc_close(context, cc);
	    krb5_free_context(context);
	    goto try_anon;
	}
    }

    if (insecure)
	l = rxkad_clear;
    else
	l = rxkad_crypt;
    memcpy(&k.data, Z_keydata(Z_credskey(cred)), 8);
    sc = (struct rx_securityClass *)rxkad_NewClientSecurityObject
	(l, &k, RXKAD_TKT_TYPE_KERBEROS_V5,
	 cred->ticket.length, cred->ticket.data);
    krb5_free_creds(context, cred);
    krb5_free_cred_contents(context, &match);
    if (cc)
	krb5_cc_close(context, cc);
    krb5_free_context(context);
    cell->security = sc;
    cell->scindex = 2;
    return 0;

    try_anon:
#endif /* HAVE_KERBEROS */
    if (try_anonymous)
	return _GetNullSecurityObject(cell);
    else
	return code;
}
Example #3
0
Code_t
Z_MakeAuthenticationSaveKey(register ZNotice_t *notice,
			    char *buffer,
			    int buffer_len,
			    int *len)
{
#ifndef HAVE_KRB5
    /* Key management not implemented for krb4. */
    return ZMakeAuthentication(notice, buffer, buffer_len, len);
#else
    Code_t result;
    krb5_creds *creds = NULL;
    krb5_keyblock *keyblock;
    struct _Z_SessionKey *savedkey;

    /* Look up creds and checksum the notice. */
    if ((result = ZGetCreds(&creds)))
	return result;
    if ((result = Z_MakeZcodeAuthentication(notice, buffer, buffer_len, len,
					    creds))) {
	krb5_free_creds(Z_krb5_ctx, creds);
	return result;
    }

    /* Save the key. */
    keyblock = Z_credskey(creds);

    if (Z_keys_head &&
	Z_keys_head->keyblock->enctype == keyblock->enctype &&
	Z_keys_head->keyblock->length == keyblock->length &&
	memcmp(Z_keys_head->keyblock->contents, keyblock->contents,
	       keyblock->length) == 0) {
	/*
	 * Optimization: if the key hasn't changed, replace the current entry,
	 * rather than make a new one.
	 */
	Z_keys_head->send_time = time(NULL);
	Z_keys_head->first_use = 0;
    } else {
	savedkey = (struct _Z_SessionKey *)malloc(sizeof(struct _Z_SessionKey));
	if (!savedkey) {
	    krb5_free_creds(Z_krb5_ctx, creds);
	    return ENOMEM;
	}

	if ((result = krb5_copy_keyblock(Z_krb5_ctx, keyblock, &savedkey->keyblock))) {
	    free(savedkey);
	    krb5_free_creds(Z_krb5_ctx, creds);
	    return result;
	}
	savedkey->send_time = time(NULL);
	savedkey->first_use = 0;

	savedkey->prev = NULL;
	savedkey->next = Z_keys_head;
	if (Z_keys_head)
	    Z_keys_head->prev = savedkey;
	Z_keys_head = savedkey;
	if (!Z_keys_tail)
	    Z_keys_tail = savedkey;
    }

    krb5_free_creds(Z_krb5_ctx, creds);
    return result;
#endif
}