1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-24 10:50:22 +03:00

s4:heimdal: import lorikeet-heimdal-200906080040 (commit 904d0124b46eed7a8ad6e5b73e892ff34b6865ba)

Also including the supporting changes required to pass make test

A number of heimdal functions and constants have changed since we last
imported a tree (for the better, but inconvenient for us).

Andrew Bartlett
This commit is contained in:
Andrew Bartlett 2009-06-08 19:06:16 +10:00
parent 5cef57ff7d
commit 9b261c008a
328 changed files with 9521 additions and 7148 deletions

View File

@ -59,7 +59,9 @@
/* Define to 1 if you have the `krb5_free_data_contents' function. */
#define HAVE_KRB5_FREE_DATA_CONTENTS 1
/* Define to 1 if you have the `krb5_free_error_string' function. */
#define HAVE_KRB5_FREE_ERROR_STRING 1
/* #undef HAVE_KRB5_FREE_ERROR_STRING */
/* Define to 1 if you have the `krb5_free_error_message' function. */
#define HAVE_KRB5_FREE_ERROR_MESSAGE 1
/* Define to 1 if you have the `krb5_free_keytab_entry_contents' function. */
/* #undef HAVE_KRB5_FREE_KEYTAB_ENTRY_CONTENTS */
/* Define to 1 if you have the `krb5_free_ktypes' function. */
@ -70,6 +72,8 @@
#define HAVE_KRB5_GET_DEFAULT_IN_TKT_ETYPES 1
/* Define to 1 if you have the `krb5_get_error_string' function. */
#define HAVE_KRB5_GET_ERROR_STRING 1
/* Define to 1 if you have the `krb5_get_error_message' function. */
#define HAVE_KRB5_GET_ERROR_MESSAGE 1
/* Define to 1 if you have the `krb5_get_permitted_enctypes' function. */
/* #undef HAVE_KRB5_GET_PERMITTED_ENCTYPES */
/* Define to 1 if you have the `krb5_get_pw_salt' function. */

View File

@ -71,7 +71,6 @@ static int cli_credentials_set_from_ccache(struct cli_credentials *cred,
krb5_principal princ;
krb5_error_code ret;
char *name;
char **realm;
if (cred->ccache_obtained > obtained) {
return 0;
@ -98,8 +97,6 @@ static int cli_credentials_set_from_ccache(struct cli_credentials *cred,
return ret;
}
realm = krb5_princ_realm(ccache->smb_krb5_context->krb5_context, princ);
cli_credentials_set_principal(cred, name, obtained);
free(name);

View File

@ -170,6 +170,9 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security)
gensec_gssapi_state->input_chan_bindings = GSS_C_NO_CHANNEL_BINDINGS;
gensec_gssapi_state->want_flags = 0;
if (gensec_setting_bool(gensec_security->settings, "gensec_gssapi", "delegation_by_kdc_policy", true)) {
gensec_gssapi_state->want_flags |= GSS_C_DELEG_POLICY_FLAG;
}
if (gensec_setting_bool(gensec_security->settings, "gensec_gssapi", "mutual", true)) {
gensec_gssapi_state->want_flags |= GSS_C_MUTUAL_FLAG;
}

View File

@ -94,11 +94,11 @@
{
char *ret;
#if defined(HAVE_KRB5_GET_ERROR_STRING) && defined(HAVE_KRB5_FREE_ERROR_STRING)
char *context_error = krb5_get_error_string(context);
#if defined(HAVE_KRB5_GET_ERROR_MESSAGE) && defined(HAVE_KRB5_FREE_ERROR_MESSAGE)
const char *context_error = krb5_get_error_message(context, code);
if (context_error) {
ret = talloc_asprintf(mem_ctx, "%s: %s", error_message(code), context_error);
krb5_free_error_string(context, context_error);
krb5_free_error_message(context, context_error);
return ret;
}
#endif

View File

@ -258,6 +258,8 @@ if test x"$with_krb5_support" != x"no"; then
AC_CHECK_FUNC_EXT(krb5_enctypes_compatible_keys, $KRB5_LIBS)
AC_CHECK_FUNC_EXT(krb5_get_error_string, $KRB5_LIBS)
AC_CHECK_FUNC_EXT(krb5_free_error_string, $KRB5_LIBS)
AC_CHECK_FUNC_EXT(krb5_get_error_message, $KRB5_LIBS)
AC_CHECK_FUNC_EXT(krb5_free_error_message, $KRB5_LIBS)
AC_CHECK_FUNC_EXT(krb5_initlog, $KRB5_LIBS)
AC_CHECK_FUNC_EXT(krb5_addlog_func, $KRB5_LIBS)
AC_CHECK_FUNC_EXT(krb5_set_warn_dest, $KRB5_LIBS)

View File

@ -40,23 +40,27 @@
{
krb5_error_code code = 0;
krb5_creds my_creds;
krb5_get_init_creds_opt options;
krb5_get_init_creds_opt *options;
krb5_get_init_creds_opt_init(&options);
if ((code = krb5_get_init_creds_opt_alloc(ctx, &options))) {
return code;
}
krb5_get_init_creds_opt_set_default_flags(ctx, NULL, NULL, &options);
krb5_get_init_creds_opt_set_default_flags(ctx, NULL, NULL, options);
if ((code = krb5_get_init_creds_keyblock(ctx, &my_creds, principal, keyblock,
0, NULL, &options))) {
0, NULL, options))) {
return code;
}
if ((code = krb5_cc_initialize(ctx, cc, principal))) {
krb5_get_init_creds_opt_free(ctx, options);
krb5_free_cred_contents(ctx, &my_creds);
return code;
}
if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) {
krb5_get_init_creds_opt_free(ctx, options);
krb5_free_cred_contents(ctx, &my_creds);
return code;
}
@ -69,6 +73,7 @@
*kdc_time = (time_t) my_creds.times.starttime;
}
krb5_get_init_creds_opt_free(ctx, options);
krb5_free_cred_contents(ctx, &my_creds);
return 0;
@ -84,24 +89,28 @@
{
krb5_error_code code = 0;
krb5_creds my_creds;
krb5_get_init_creds_opt options;
krb5_get_init_creds_opt *options;
krb5_get_init_creds_opt_init(&options);
if ((code = krb5_get_init_creds_opt_alloc(ctx, &options))) {
return code;
}
krb5_get_init_creds_opt_set_default_flags(ctx, NULL, NULL, &options);
krb5_get_init_creds_opt_set_default_flags(ctx, NULL, NULL, options);
if ((code = krb5_get_init_creds_password(ctx, &my_creds, principal, password,
NULL,
NULL, 0, NULL, &options))) {
NULL, 0, NULL, options))) {
return code;
}
if ((code = krb5_cc_initialize(ctx, cc, principal))) {
krb5_get_init_creds_opt_free(ctx, options);
krb5_free_cred_contents(ctx, &my_creds);
return code;
}
if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) {
krb5_get_init_creds_opt_free(ctx, options);
krb5_free_cred_contents(ctx, &my_creds);
return code;
}
@ -114,6 +123,7 @@
*kdc_time = (time_t) my_creds.times.starttime;
}
krb5_get_init_creds_opt_free(ctx, options);
krb5_free_cred_contents(ctx, &my_creds);
return 0;

View File

@ -96,7 +96,7 @@ krb5_error_code check_pac_checksum(TALLOC_CTX *mem_ctx,
krb5_principal client_principal_pac;
int i;
krb5_clear_error_string(context);
krb5_clear_error_message(context);
if (k5ret) {
*k5ret = KRB5_PARSE_MALFORMED;

View File

@ -55,18 +55,18 @@ static WERROR dns_domain_from_principal(TALLOC_CTX *mem_ctx, struct smb_krb5_con
krb5_error_code ret;
krb5_principal principal;
/* perhaps it's a principal with a realm, so return the right 'domain only' response */
char **realm;
char *realm;
ret = krb5_parse_name_flags(smb_krb5_context->krb5_context, name,
KRB5_PRINCIPAL_PARSE_MUST_REALM, &principal);
KRB5_PRINCIPAL_PARSE_REQUIRE_REALM, &principal);
if (ret) {
info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
return WERR_OK;
}
/* This isn't an allocation assignemnt, so it is free'ed with the krb5_free_principal */
realm = krb5_princ_realm(smb_krb5_context->krb5_context, principal);
realm = krb5_principal_get_realm(smb_krb5_context->krb5_context, principal);
info1->dns_domain_name = talloc_strdup(mem_ctx, *realm);
info1->dns_domain_name = talloc_strdup(mem_ctx, realm);
krb5_free_principal(smb_krb5_context->krb5_context, principal);
W_ERROR_HAVE_NO_MEMORY(info1->dns_domain_name);
@ -271,7 +271,7 @@ static WERROR DsCrackNameUPN(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
const char *result_filter = NULL;
krb5_error_code ret;
krb5_principal principal;
char **realm;
char *realm;
char *unparsed_name_short;
const char *domain_attrs[] = { NULL };
struct ldb_result *domain_res = NULL;
@ -283,21 +283,21 @@ static WERROR DsCrackNameUPN(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ctx,
}
ret = krb5_parse_name_flags(smb_krb5_context->krb5_context, name,
KRB5_PRINCIPAL_PARSE_MUST_REALM, &principal);
KRB5_PRINCIPAL_PARSE_REQUIRE_REALM, &principal);
if (ret) {
info1->status = DRSUAPI_DS_NAME_STATUS_NOT_FOUND;
return WERR_OK;
}
realm = krb5_princ_realm(smb_krb5_context->krb5_context, principal);
realm = krb5_principal_get_realm(smb_krb5_context->krb5_context, principal);
ldb_ret = ldb_search(sam_ctx, mem_ctx, &domain_res,
samdb_partitions_dn(sam_ctx, mem_ctx),
LDB_SCOPE_ONELEVEL,
domain_attrs,
"(&(&(|(&(dnsRoot=%s)(nETBIOSName=*))(nETBIOSName=%s))(objectclass=crossRef))(ncName=*))",
ldb_binary_encode_string(mem_ctx, *realm),
ldb_binary_encode_string(mem_ctx, *realm));
ldb_binary_encode_string(mem_ctx, realm),
ldb_binary_encode_string(mem_ctx, realm));
if (ldb_ret != LDB_SUCCESS) {
DEBUG(2, ("DsCrackNameUPN domain ref search failed: %s", ldb_errstring(sam_ctx)));

View File

@ -1,4 +1,3 @@
$Id$
Heimdal is a Kerberos 5 implementation.

View File

@ -100,13 +100,16 @@ while(<>) {
s/^\s*//;
s/\s*$//;
s/\s+/ /g;
if($_ =~ /\)$/){
if($_ =~ /\)$/ or $_ =~ /DEPRECATED$/){
if(!/^static/ && !/^PRIVATE/){
if(/(.*)(__attribute__\s?\(.*\))/) {
$attr = $2;
$attr = "";
if(m/(.*)(__attribute__\s?\(.*\))/) {
$attr .= " $2";
$_ = $1;
}
if(m/(.*)\s(\w+DEPRECATED)/) {
$attr .= " $2";
$_ = $1;
} else {
$attr = "";
}
# remove outer ()
s/\s*\(/</;
@ -308,7 +311,7 @@ extern \"C\" {
if ($opt_E) {
$public_h_header .= "#ifndef $opt_E
#if defined(_WIN32)
#define ${opt_E}_FUNCTION _stdcall __declspec(dllimport)
#define ${opt_E}_FUNCTION __stdcall __declspec(dllimport)
#define ${opt_E}_VARIABLE __declspec(dllimport)
#else
#define ${opt_E}_FUNCTION
@ -320,7 +323,7 @@ if ($opt_E) {
$private_h_header .= "#ifndef $opt_E
#if defined(_WIN32)
#define ${opt_E}_FUNCTION _stdcall __declspec(dllimport)
#define ${opt_E}_FUNCTION __stdcall __declspec(dllimport)
#define ${opt_E}_VARIABLE __declspec(dllimport)
#else
#define ${opt_E}_FUNCTION

View File

@ -5,7 +5,7 @@ dnl
AC_DEFUN([rk_RESOLV],[
AC_CHECK_HEADERS([arpa/nameser.h])
AC_CHECK_HEADERS([arpa/nameser.h dns.h])
AC_CHECK_HEADERS(resolv.h, , , [AC_INCLUDES_DEFAULT
#ifdef HAVE_SYS_TYPES_H
@ -73,6 +73,15 @@ AC_FIND_FUNC(res_ndestroy, resolv,
],
[0])
AC_FIND_FUNC_NO_LIBS(dns_search,,
[
#ifdef HAVE_DNS_H
#include <dns.h>
#endif
],
[0,0,0,0,0,0,0,0])
AC_FIND_FUNC(dn_expand, resolv,
[
#include <stdio.h>

View File

@ -1,400 +0,0 @@
/*
* Copyright (c) 1997-2005 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "kdc_locl.h"
RCSID("$Id$");
#include <krb5-v4compat.h>
/*
* fetch the server from `t', returning the name in malloced memory in
* `spn' and the entry itself in `server'
*/
static krb5_error_code
fetch_server (krb5_context context,
krb5_kdc_configuration *config,
const Ticket *t,
char **spn,
hdb_entry_ex **server,
const char *from)
{
krb5_error_code ret;
krb5_principal sprinc;
ret = _krb5_principalname2krb5_principal(context, &sprinc,
t->sname, t->realm);
if (ret) {
kdc_log(context, config, 0, "_krb5_principalname2krb5_principal: %s",
krb5_get_err_text(context, ret));
return ret;
}
ret = krb5_unparse_name(context, sprinc, spn);
if (ret) {
krb5_free_principal(context, sprinc);
kdc_log(context, config, 0, "krb5_unparse_name: %s",
krb5_get_err_text(context, ret));
return ret;
}
ret = _kdc_db_fetch(context, config, sprinc, HDB_F_GET_SERVER,
NULL, server);
krb5_free_principal(context, sprinc);
if (ret) {
kdc_log(context, config, 0,
"Request to convert ticket from %s for unknown principal %s: %s",
from, *spn, krb5_get_err_text(context, ret));
if (ret == HDB_ERR_NOENTRY)
ret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN;
return ret;
}
return 0;
}
static krb5_error_code
log_524 (krb5_context context,
krb5_kdc_configuration *config,
const EncTicketPart *et,
const char *from,
const char *spn)
{
krb5_principal client;
char *cpn;
krb5_error_code ret;
ret = _krb5_principalname2krb5_principal(context, &client,
et->cname, et->crealm);
if (ret) {
kdc_log(context, config, 0, "_krb5_principalname2krb5_principal: %s",
krb5_get_err_text (context, ret));
return ret;
}
ret = krb5_unparse_name(context, client, &cpn);
if (ret) {
krb5_free_principal(context, client);
kdc_log(context, config, 0, "krb5_unparse_name: %s",
krb5_get_err_text (context, ret));
return ret;
}
kdc_log(context, config, 1, "524-REQ %s from %s for %s", cpn, from, spn);
free(cpn);
krb5_free_principal(context, client);
return 0;
}
static krb5_error_code
verify_flags (krb5_context context,
krb5_kdc_configuration *config,
const EncTicketPart *et,
const char *spn)
{
if(et->endtime < kdc_time){
kdc_log(context, config, 0, "Ticket expired (%s)", spn);
return KRB5KRB_AP_ERR_TKT_EXPIRED;
}
if(et->flags.invalid){
kdc_log(context, config, 0, "Ticket not valid (%s)", spn);
return KRB5KRB_AP_ERR_TKT_NYV;
}
return 0;
}
/*
* set the `et->caddr' to the most appropriate address to use, where
* `addr' is the address the request was received from.
*/
static krb5_error_code
set_address (krb5_context context,
krb5_kdc_configuration *config,
EncTicketPart *et,
struct sockaddr *addr,
const char *from)
{
krb5_error_code ret;
krb5_address *v4_addr;
v4_addr = malloc (sizeof(*v4_addr));
if (v4_addr == NULL)
return ENOMEM;
ret = krb5_sockaddr2address(context, addr, v4_addr);
if(ret) {
free (v4_addr);
kdc_log(context, config, 0, "Failed to convert address (%s)", from);
return ret;
}
if (et->caddr && !krb5_address_search (context, v4_addr, et->caddr)) {
kdc_log(context, config, 0, "Incorrect network address (%s)", from);
krb5_free_address(context, v4_addr);
free (v4_addr);
return KRB5KRB_AP_ERR_BADADDR;
}
if(v4_addr->addr_type == KRB5_ADDRESS_INET) {
/* we need to collapse the addresses in the ticket to a
single address; best guess is to use the address the
connection came from */
if (et->caddr != NULL) {
free_HostAddresses(et->caddr);
} else {
et->caddr = malloc (sizeof (*et->caddr));
if (et->caddr == NULL) {
krb5_free_address(context, v4_addr);
free(v4_addr);
return ENOMEM;
}
}
et->caddr->val = v4_addr;
et->caddr->len = 1;
} else {
krb5_free_address(context, v4_addr);
free(v4_addr);
}
return 0;
}
static krb5_error_code
encrypt_v4_ticket(krb5_context context,
krb5_kdc_configuration *config,
void *buf,
size_t len,
krb5_keyblock *skey,
EncryptedData *reply)
{
krb5_crypto crypto;
krb5_error_code ret;
ret = krb5_crypto_init(context, skey, ETYPE_DES_PCBC_NONE, &crypto);
if (ret) {
free(buf);
kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
krb5_get_err_text(context, ret));
return ret;
}
ret = krb5_encrypt_EncryptedData(context,
crypto,
KRB5_KU_TICKET,
buf,
len,
0,
reply);
krb5_crypto_destroy(context, crypto);
if(ret) {
kdc_log(context, config, 0, "Failed to encrypt data: %s",
krb5_get_err_text(context, ret));
return ret;
}
return 0;
}
static krb5_error_code
encode_524_response(krb5_context context,
krb5_kdc_configuration *config,
const char *spn, const EncTicketPart et,
const Ticket *t, hdb_entry_ex *server,
EncryptedData *ticket, int *kvno)
{
krb5_error_code ret;
int use_2b;
size_t len;
use_2b = krb5_config_get_bool(context, NULL, "kdc", "use_2b", spn, NULL);
if(use_2b) {
ASN1_MALLOC_ENCODE(EncryptedData,
ticket->cipher.data, ticket->cipher.length,
&t->enc_part, &len, ret);
if (ret) {
kdc_log(context, config, 0,
"Failed to encode v4 (2b) ticket (%s)", spn);
return ret;
}
ticket->etype = 0;
ticket->kvno = NULL;
*kvno = 213; /* 2b's use this magic kvno */
} else {
unsigned char buf[MAX_KTXT_LEN + 4 * 4];
Key *skey;
if (!config->enable_v4_cross_realm && strcmp (et.crealm, t->realm) != 0) {
kdc_log(context, config, 0, "524 cross-realm %s -> %s disabled", et.crealm,
t->realm);
return KRB5KDC_ERR_POLICY;
}
ret = _kdc_encode_v4_ticket(context, config,
buf + sizeof(buf) - 1, sizeof(buf),
&et, &t->sname, &len);
if(ret){
kdc_log(context, config, 0,
"Failed to encode v4 ticket (%s)", spn);
return ret;
}
ret = _kdc_get_des_key(context, server, TRUE, FALSE, &skey);
if(ret){
kdc_log(context, config, 0,
"no suitable DES key for server (%s)", spn);
return ret;
}
ret = encrypt_v4_ticket(context, config, buf + sizeof(buf) - len, len,
&skey->key, ticket);
if(ret){
kdc_log(context, config, 0,
"Failed to encrypt v4 ticket (%s)", spn);
return ret;
}
*kvno = server->entry.kvno;
}
return 0;
}
/*
* process a 5->4 request, based on `t', and received `from, addr',
* returning the reply in `reply'
*/
krb5_error_code
_kdc_do_524(krb5_context context,
krb5_kdc_configuration *config,
const Ticket *t, krb5_data *reply,
const char *from, struct sockaddr *addr)
{
krb5_error_code ret = 0;
krb5_crypto crypto;
hdb_entry_ex *server = NULL;
Key *skey;
krb5_data et_data;
EncTicketPart et;
EncryptedData ticket;
krb5_storage *sp;
char *spn = NULL;
unsigned char buf[MAX_KTXT_LEN + 4 * 4];
size_t len;
int kvno = 0;
if(!config->enable_524) {
ret = KRB5KDC_ERR_POLICY;
kdc_log(context, config, 0,
"Rejected ticket conversion request from %s", from);
goto out;
}
ret = fetch_server (context, config, t, &spn, &server, from);
if (ret) {
goto out;
}
ret = hdb_enctype2key(context, &server->entry, t->enc_part.etype, &skey);
if(ret){
kdc_log(context, config, 0,
"No suitable key found for server (%s) from %s", spn, from);
goto out;
}
ret = krb5_crypto_init(context, &skey->key, 0, &crypto);
if (ret) {
kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
krb5_get_err_text(context, ret));
goto out;
}
ret = krb5_decrypt_EncryptedData (context,
crypto,
KRB5_KU_TICKET,
&t->enc_part,
&et_data);
krb5_crypto_destroy(context, crypto);
if(ret){
kdc_log(context, config, 0,
"Failed to decrypt ticket from %s for %s", from, spn);
goto out;
}
ret = krb5_decode_EncTicketPart(context, et_data.data, et_data.length,
&et, &len);
krb5_data_free(&et_data);
if(ret){
kdc_log(context, config, 0,
"Failed to decode ticket from %s for %s", from, spn);
goto out;
}
ret = log_524 (context, config, &et, from, spn);
if (ret) {
free_EncTicketPart(&et);
goto out;
}
ret = verify_flags (context, config, &et, spn);
if (ret) {
free_EncTicketPart(&et);
goto out;
}
ret = set_address (context, config, &et, addr, from);
if (ret) {
free_EncTicketPart(&et);
goto out;
}
ret = encode_524_response(context, config, spn, et, t,
server, &ticket, &kvno);
free_EncTicketPart(&et);
out:
/* make reply */
memset(buf, 0, sizeof(buf));
sp = krb5_storage_from_mem(buf, sizeof(buf));
if (sp) {
krb5_store_int32(sp, ret);
if(ret == 0){
krb5_store_int32(sp, kvno);
krb5_store_data(sp, ticket.cipher);
/* Aargh! This is coded as a KTEXT_ST. */
krb5_storage_seek(sp, MAX_KTXT_LEN - ticket.cipher.length, SEEK_CUR);
krb5_store_int32(sp, 0); /* mbz */
free_EncryptedData(&ticket);
}
ret = krb5_storage_to_data(sp, reply);
reply->length = krb5_storage_seek(sp, 0, SEEK_CUR);
krb5_storage_free(sp);
} else
krb5_data_zero(reply);
if(spn)
free(spn);
if(server)
_kdc_free_ent (context, server);
return ret;
}

View File

@ -84,6 +84,7 @@ krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config)
krb5_config_get_bool_default(context, NULL,
c->enable_v4,
"kdc", "enable-524", NULL);
#ifdef DIGEST
c->enable_digest =
krb5_config_get_bool_default(context, NULL,
FALSE,
@ -110,7 +111,9 @@ krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config)
c->enable_digest = 0;
}
}
#endif
#ifdef KX509
c->enable_kx509 =
krb5_config_get_bool_default(context, NULL,
FALSE,
@ -129,6 +132,7 @@ krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config)
c->enable_kx509 = FALSE;
}
}
#endif
c->check_ticket_addresses =
krb5_config_get_bool_default(context, NULL,
@ -220,7 +224,7 @@ krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config)
"enable-pkinit",
NULL);
if (c->enable_pkinit) {
const char *user_id, *anchors, *ocsp_file;
const char *user_id, *anchors, *file;
char **pool_list, **revoke_list;
user_id =
@ -242,15 +246,23 @@ krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config)
krb5_config_get_strings(context, NULL,
"kdc", "pkinit_revoke", NULL);
ocsp_file =
krb5_config_get_string(context, NULL,
"kdc", "pkinit_kdc_ocsp", NULL);
if (ocsp_file) {
c->pkinit_kdc_ocsp_file = strdup(ocsp_file);
file = krb5_config_get_string(context, NULL,
"kdc", "pkinit_kdc_ocsp", NULL);
if (file) {
c->pkinit_kdc_ocsp_file = strdup(file);
if (c->pkinit_kdc_ocsp_file == NULL)
krb5_errx(context, 1, "out of memory");
}
file = krb5_config_get_string(context, NULL,
"kdc", "pkinit_kdc_friendly_name", NULL);
if (file) {
c->pkinit_kdc_friendly_name = strdup(file);
if (c->pkinit_kdc_friendly_name == NULL)
krb5_errx(context, 1, "out of memory");
}
_kdc_pk_initialize(context, c, user_id, anchors,
pool_list, revoke_list);

View File

@ -34,7 +34,7 @@
#include "kdc_locl.h"
#include <hex.h>
RCSID("$Id$");
#ifdef DIGEST
#define MS_CHAP_V2 0x20
#define CHAP_MD5 0x10
@ -201,7 +201,7 @@ get_password_entry(krb5_context context,
krb5_error_code
_kdc_do_digest(krb5_context context,
krb5_kdc_configuration *config,
const DigestREQ *req, krb5_data *reply,
const struct DigestREQ *req, krb5_data *reply,
const char *from, struct sockaddr *addr)
{
krb5_error_code ret = 0;
@ -234,6 +234,7 @@ _kdc_do_digest(krb5_context context,
memset(&ireq, 0, sizeof(ireq));
memset(&r, 0, sizeof(r));
memset(&rep, 0, sizeof(rep));
memset(&res, 0, sizeof(res));
kdc_log(context, config, 0, "Digest request from %s", from);
@ -487,6 +488,7 @@ _kdc_do_digest(krb5_context context,
hex_encode(buf.data, buf.length, &r.u.initReply.opaque);
free(buf.data);
krb5_data_zero(&buf);
if (r.u.initReply.opaque == NULL) {
krb5_clear_error_message(context);
ret = ENOMEM;
@ -539,8 +541,10 @@ _kdc_do_digest(krb5_context context,
ret = decode_Checksum(buf.data, buf.length, &res, NULL);
free(buf.data);
krb5_data_zero(&buf);
if (ret) {
krb5_set_error_message(context, ret, "Failed to decode digest Checksum");
krb5_set_error_message(context, ret,
"Failed to decode digest Checksum");
goto out;
}
@ -582,6 +586,8 @@ _kdc_do_digest(krb5_context context,
ret = krb5_verify_checksum(context, crypto,
KRB5_KU_DIGEST_OPAQUE,
buf.data, buf.length, &res);
free_Checksum(&res);
krb5_data_free(&buf);
krb5_crypto_destroy(context, crypto);
crypto = NULL;
if (ret)
@ -1165,6 +1171,8 @@ _kdc_do_digest(krb5_context context,
krb5_set_error_message(context, ret, "NTLM storage read flags");
goto out;
}
krb5_storage_free(sp);
sp = NULL;
krb5_data_free(&buf);
if ((flags & NTLM_NEG_NTLM) == 0) {
@ -1450,9 +1458,12 @@ _kdc_do_digest(krb5_context context,
free (client_name);
krb5_data_free(&buf);
krb5_data_free(&serverNonce);
free_Checksum(&res);
free_DigestREP(&rep);
free_DigestRepInner(&r);
free_DigestReqInner(&ireq);
return ret;
}
#endif /* DIGEST */

View File

@ -91,13 +91,19 @@
#include <parse_units.h>
#include <krb5.h>
#include <krb5_locl.h>
#ifdef DIGEST
#include <digest_asn1.h>
#endif
#ifdef KX509
#include <kx509_asn1.h>
#endif
#include <hdb.h>
#include <hdb_err.h>
#include <der.h>
#ifndef NO_NTLM
#include <heimntlm.h>
#endif
#include <windc_plugin.h>
#undef ALLOC

View File

@ -33,7 +33,7 @@
#include "kdc_locl.h"
RCSID("$Id$");
#ifdef KRB4
#include <krb5-v4compat.h>
#include <rx.h>
@ -949,3 +949,5 @@ out:
krb5_storage_free (sp);
return ret;
}
#endif /* KRB4 */

View File

@ -75,8 +75,10 @@ typedef struct krb5_kdc_configuration {
krb5_boolean enable_pkinit;
krb5_boolean pkinit_princ_in_cert;
char *pkinit_kdc_ocsp_file;
char *pkinit_kdc_friendly_name;
int pkinit_dh_min_bits;
int pkinit_require_binding;
int pkinit_allow_proxy_certs;
krb5_log_facility *logf;
@ -91,6 +93,20 @@ typedef struct krb5_kdc_configuration {
} krb5_kdc_configuration;
struct krb5_kdc_service {
unsigned int flags;
#define KS_KRB5 1
#define KS_NO_LENGTH 2
krb5_error_code (*process)(krb5_context context,
krb5_kdc_configuration *config,
krb5_data *req_buffer,
krb5_data *reply,
const char *from,
struct sockaddr *addr,
int datagram_reply,
int *claim);
};
#include <kdc-protos.h>
#endif

View File

@ -42,6 +42,8 @@
#include "kdc.h"
typedef struct pk_client_params pk_client_params;
struct DigestREQ;
struct Kx509Request;
#include <kdc-private.h>
extern sig_atomic_t exit_flag;
@ -52,9 +54,12 @@ extern krb5_addresses explicit_addresses;
extern int enable_http;
#ifdef SUPPORT_DETACH
#define DETACH_IS_DEFAULT FALSE
extern int detach_from_console;
#endif
extern const struct units _kdc_digestunits[];

View File

@ -1,794 +0,0 @@
/*
* Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "kdc_locl.h"
#include <krb5-v4compat.h>
RCSID("$Id$");
#ifndef swap32
static uint32_t
swap32(uint32_t x)
{
return ((x << 24) & 0xff000000) |
((x << 8) & 0xff0000) |
((x >> 8) & 0xff00) |
((x >> 24) & 0xff);
}
#endif /* swap32 */
int
_kdc_maybe_version4(unsigned char *buf, int len)
{
return len > 0 && *buf == 4;
}
static void
make_err_reply(krb5_context context, krb5_data *reply,
int code, const char *msg)
{
_krb5_krb_cr_err_reply(context, "", "", "",
kdc_time, code, msg, reply);
}
struct valid_princ_ctx {
krb5_kdc_configuration *config;
unsigned flags;
};
static krb5_boolean
valid_princ(krb5_context context,
void *funcctx,
krb5_principal princ)
{
struct valid_princ_ctx *ctx = funcctx;
krb5_error_code ret;
char *s;
hdb_entry_ex *ent;
ret = krb5_unparse_name(context, princ, &s);
if (ret)
return FALSE;
ret = _kdc_db_fetch(context, ctx->config, princ, ctx->flags, NULL, &ent);
if (ret) {
kdc_log(context, ctx->config, 7, "Lookup %s failed: %s", s,
krb5_get_err_text (context, ret));
free(s);
return FALSE;
}
kdc_log(context, ctx->config, 7, "Lookup %s succeeded", s);
free(s);
_kdc_free_ent(context, ent);
return TRUE;
}
krb5_error_code
_kdc_db_fetch4(krb5_context context,
krb5_kdc_configuration *config,
const char *name, const char *instance, const char *realm,
unsigned flags,
hdb_entry_ex **ent)
{
krb5_principal p;
krb5_error_code ret;
struct valid_princ_ctx ctx;
ctx.config = config;
ctx.flags = flags;
ret = krb5_425_conv_principal_ext2(context, name, instance, realm,
valid_princ, &ctx, 0, &p);
if(ret)
return ret;
ret = _kdc_db_fetch(context, config, p, flags, NULL, ent);
krb5_free_principal(context, p);
return ret;
}
#define RCHECK(X, L) if(X){make_err_reply(context, reply, KFAILURE, "Packet too short"); goto L;}
/*
* Process the v4 request in `buf, len' (received from `addr'
* (with string `from').
* Return an error code and a reply in `reply'.
*/
krb5_error_code
_kdc_do_version4(krb5_context context,
krb5_kdc_configuration *config,
unsigned char *buf,
size_t len,
krb5_data *reply,
const char *from,
struct sockaddr_in *addr)
{
krb5_storage *sp;
krb5_error_code ret = EINVAL;
hdb_entry_ex *client = NULL, *server = NULL;
Key *ckey, *skey;
int8_t pvno;
int8_t msg_type;
int lsb;
char *name = NULL, *inst = NULL, *realm = NULL;
char *sname = NULL, *sinst = NULL;
int32_t req_time;
time_t max_life;
uint8_t life;
char client_name[256];
char server_name[256];
if(!config->enable_v4) {
kdc_log(context, config, 0,
"Rejected version 4 request from %s", from);
make_err_reply(context, reply, KRB4ET_KDC_GEN_ERR,
"Function not enabled");
return 0;
}
sp = krb5_storage_from_mem(buf, len);
RCHECK(krb5_ret_int8(sp, &pvno), out);
if(pvno != 4){
kdc_log(context, config, 0,
"Protocol version mismatch (krb4) (%d)", pvno);
make_err_reply(context, reply, KRB4ET_KDC_PKT_VER, "protocol mismatch");
ret = KRB4ET_KDC_PKT_VER;
goto out;
}
RCHECK(krb5_ret_int8(sp, &msg_type), out);
lsb = msg_type & 1;
msg_type &= ~1;
switch(msg_type){
case AUTH_MSG_KDC_REQUEST: {
krb5_data ticket, cipher;
krb5_keyblock session;
krb5_data_zero(&ticket);
krb5_data_zero(&cipher);
RCHECK(krb5_ret_stringz(sp, &name), out1);
RCHECK(krb5_ret_stringz(sp, &inst), out1);
RCHECK(krb5_ret_stringz(sp, &realm), out1);
RCHECK(krb5_ret_int32(sp, &req_time), out1);
if(lsb)
req_time = swap32(req_time);
RCHECK(krb5_ret_uint8(sp, &life), out1);
RCHECK(krb5_ret_stringz(sp, &sname), out1);
RCHECK(krb5_ret_stringz(sp, &sinst), out1);
snprintf (client_name, sizeof(client_name),
"%s.%s@%s", name, inst, realm);
snprintf (server_name, sizeof(server_name),
"%s.%s@%s", sname, sinst, config->v4_realm);
kdc_log(context, config, 0, "AS-REQ (krb4) %s from %s for %s",
client_name, from, server_name);
ret = _kdc_db_fetch4(context, config, name, inst, realm,
HDB_F_GET_CLIENT, &client);
if(ret) {
kdc_log(context, config, 0, "Client not found in database: %s: %s",
client_name, krb5_get_err_text(context, ret));
make_err_reply(context, reply, KRB4ET_KDC_PR_UNKNOWN,
"principal unknown");
goto out1;
}
ret = _kdc_db_fetch4(context, config, sname, sinst, config->v4_realm,
HDB_F_GET_SERVER, &server);
if(ret){
kdc_log(context, config, 0, "Server not found in database: %s: %s",
server_name, krb5_get_err_text(context, ret));
make_err_reply(context, reply, KRB4ET_KDC_PR_UNKNOWN,
"principal unknown");
goto out1;
}
ret = _kdc_check_flags (context, config,
client, client_name,
server, server_name,
TRUE);
if (ret) {
/* good error code? */
make_err_reply(context, reply, KRB4ET_KDC_NAME_EXP,
"operation not allowed");
goto out1;
}
if (config->enable_v4_per_principal &&
client->entry.flags.allow_kerberos4 == 0)
{
kdc_log(context, config, 0,
"Per principal Kerberos 4 flag not turned on for %s",
client_name);
make_err_reply(context, reply, KRB4ET_KDC_NULL_KEY,
"allow kerberos4 flag required");
goto out1;
}
/*
* There's no way to do pre-authentication in v4 and thus no
* good error code to return if preauthentication is required.
*/
if (config->require_preauth
|| client->entry.flags.require_preauth
|| server->entry.flags.require_preauth) {
kdc_log(context, config, 0,
"Pre-authentication required for v4-request: "
"%s for %s",
client_name, server_name);
make_err_reply(context, reply, KRB4ET_KDC_NULL_KEY,
"preauth required");
goto out1;
}
ret = _kdc_get_des_key(context, client, FALSE, FALSE, &ckey);
if(ret){
kdc_log(context, config, 0, "no suitable DES key for client");
make_err_reply(context, reply, KRB4ET_KDC_NULL_KEY,
"no suitable DES key for client");
goto out1;
}
ret = _kdc_get_des_key(context, server, TRUE, FALSE, &skey);
if(ret){
kdc_log(context, config, 0, "no suitable DES key for server");
make_err_reply(context, reply, KRB4ET_KDC_NULL_KEY,
"no suitable DES key for server");
goto out1;
}
max_life = _krb5_krb_life_to_time(0, life);
if(client->entry.max_life)
max_life = min(max_life, *client->entry.max_life);
if(server->entry.max_life)
max_life = min(max_life, *server->entry.max_life);
life = krb_time_to_life(kdc_time, kdc_time + max_life);
ret = krb5_generate_random_keyblock(context,
ETYPE_DES_PCBC_NONE,
&session);
if (ret) {
make_err_reply(context, reply, KFAILURE,
"Not enough random i KDC");
goto out1;
}
ret = _krb5_krb_create_ticket(context,
0,
name,
inst,
config->v4_realm,
addr->sin_addr.s_addr,
&session,
life,
kdc_time,
sname,
sinst,
&skey->key,
&ticket);
if (ret) {
krb5_free_keyblock_contents(context, &session);
make_err_reply(context, reply, KFAILURE,
"failed to create v4 ticket");
goto out1;
}
ret = _krb5_krb_create_ciph(context,
&session,
sname,
sinst,
config->v4_realm,
life,
server->entry.kvno % 255,
&ticket,
kdc_time,
&ckey->key,
&cipher);
krb5_free_keyblock_contents(context, &session);
krb5_data_free(&ticket);
if (ret) {
make_err_reply(context, reply, KFAILURE,
"Failed to create v4 cipher");
goto out1;
}
ret = _krb5_krb_create_auth_reply(context,
name,
inst,
realm,
req_time,
0,
client->entry.pw_end ? *client->entry.pw_end : 0,
client->entry.kvno % 256,
&cipher,
reply);
krb5_data_free(&cipher);
out1:
break;
}
case AUTH_MSG_APPL_REQUEST: {
struct _krb5_krb_auth_data ad;
int8_t kvno;
int8_t ticket_len;
int8_t req_len;
krb5_data auth;
int32_t address;
size_t pos;
krb5_principal tgt_princ = NULL;
hdb_entry_ex *tgt = NULL;
Key *tkey;
time_t max_end, actual_end, issue_time;
memset(&ad, 0, sizeof(ad));
krb5_data_zero(&auth);
RCHECK(krb5_ret_int8(sp, &kvno), out2);
RCHECK(krb5_ret_stringz(sp, &realm), out2);
ret = krb5_425_conv_principal(context, "krbtgt", realm,
config->v4_realm,
&tgt_princ);
if(ret){
kdc_log(context, config, 0,
"Converting krbtgt principal (krb4): %s",
krb5_get_err_text(context, ret));
make_err_reply(context, reply, KFAILURE,
"Failed to convert v4 principal (krbtgt)");
goto out2;
}
ret = _kdc_db_fetch(context, config, tgt_princ,
HDB_F_GET_KRBTGT, NULL, &tgt);
if(ret){
char *s;
s = kdc_log_msg(context, config, 0, "Ticket-granting ticket not "
"found in database (krb4): krbtgt.%s@%s: %s",
realm, config->v4_realm,
krb5_get_err_text(context, ret));
make_err_reply(context, reply, KFAILURE, s);
free(s);
goto out2;
}
if(tgt->entry.kvno % 256 != kvno){
kdc_log(context, config, 0,
"tgs-req (krb4) with old kvno %d (current %d) for "
"krbtgt.%s@%s", kvno, tgt->entry.kvno % 256,
realm, config->v4_realm);
make_err_reply(context, reply, KRB4ET_KDC_AUTH_EXP,
"old krbtgt kvno used");
goto out2;
}
ret = _kdc_get_des_key(context, tgt, TRUE, FALSE, &tkey);
if(ret){
kdc_log(context, config, 0,
"no suitable DES key for krbtgt (krb4)");
make_err_reply(context, reply, KRB4ET_KDC_NULL_KEY,
"no suitable DES key for krbtgt");
goto out2;
}
RCHECK(krb5_ret_int8(sp, &ticket_len), out2);
RCHECK(krb5_ret_int8(sp, &req_len), out2);
pos = krb5_storage_seek(sp, ticket_len + req_len, SEEK_CUR);
auth.data = buf;
auth.length = pos;
if (config->check_ticket_addresses)
address = addr->sin_addr.s_addr;
else
address = 0;
ret = _krb5_krb_rd_req(context, &auth, "krbtgt", realm,
config->v4_realm,
address, &tkey->key, &ad);
if(ret){
kdc_log(context, config, 0, "krb_rd_req: %d", ret);
make_err_reply(context, reply, ret, "failed to parse request");
goto out2;
}
RCHECK(krb5_ret_int32(sp, &req_time), out2);
if(lsb)
req_time = swap32(req_time);
RCHECK(krb5_ret_uint8(sp, &life), out2);
RCHECK(krb5_ret_stringz(sp, &sname), out2);
RCHECK(krb5_ret_stringz(sp, &sinst), out2);
snprintf (server_name, sizeof(server_name),
"%s.%s@%s",
sname, sinst, config->v4_realm);
snprintf (client_name, sizeof(client_name),
"%s.%s@%s",
ad.pname, ad.pinst, ad.prealm);
kdc_log(context, config, 0, "TGS-REQ (krb4) %s from %s for %s",
client_name, from, server_name);
if(strcmp(ad.prealm, realm)){
kdc_log(context, config, 0,
"Can't hop realms (krb4) %s -> %s", realm, ad.prealm);
make_err_reply(context, reply, KRB4ET_KDC_PR_UNKNOWN,
"Can't hop realms");
goto out2;
}
if (!config->enable_v4_cross_realm && strcmp(realm, config->v4_realm) != 0) {
kdc_log(context, config, 0,
"krb4 Cross-realm %s -> %s disabled",
realm, config->v4_realm);
make_err_reply(context, reply, KRB4ET_KDC_PR_UNKNOWN,
"Can't hop realms");
goto out2;
}
if(strcmp(sname, "changepw") == 0){
kdc_log(context, config, 0,
"Bad request for changepw ticket (krb4)");
make_err_reply(context, reply, KRB4ET_KDC_PR_UNKNOWN,
"Can't authorize password change based on TGT");
goto out2;
}
ret = _kdc_db_fetch4(context, config, ad.pname, ad.pinst, ad.prealm,
HDB_F_GET_CLIENT, &client);
if(ret && ret != HDB_ERR_NOENTRY) {
char *s;
s = kdc_log_msg(context, config, 0,
"Client not found in database: (krb4) %s: %s",
client_name, krb5_get_err_text(context, ret));
make_err_reply(context, reply, KRB4ET_KDC_PR_UNKNOWN, s);
free(s);
goto out2;
}
if (client == NULL && strcmp(ad.prealm, config->v4_realm) == 0) {
char *s;
s = kdc_log_msg(context, config, 0,
"Local client not found in database: (krb4) "
"%s", client_name);
make_err_reply(context, reply, KRB4ET_KDC_PR_UNKNOWN, s);
free(s);
goto out2;
}
ret = _kdc_db_fetch4(context, config, sname, sinst, config->v4_realm,
HDB_F_GET_SERVER, &server);
if(ret){
char *s;
s = kdc_log_msg(context, config, 0,
"Server not found in database (krb4): %s: %s",
server_name, krb5_get_err_text(context, ret));
make_err_reply(context, reply, KRB4ET_KDC_PR_UNKNOWN, s);
free(s);
goto out2;
}
ret = _kdc_check_flags (context, config,
client, client_name,
server, server_name,
FALSE);
if (ret) {
make_err_reply(context, reply, KRB4ET_KDC_NAME_EXP,
"operation not allowed");
goto out2;
}
ret = _kdc_get_des_key(context, server, TRUE, FALSE, &skey);
if(ret){
kdc_log(context, config, 0,
"no suitable DES key for server (krb4)");
make_err_reply(context, reply, KRB4ET_KDC_NULL_KEY,
"no suitable DES key for server");
goto out2;
}
max_end = _krb5_krb_life_to_time(ad.time_sec, ad.life);
max_end = min(max_end, _krb5_krb_life_to_time(kdc_time, life));
if(server->entry.max_life)
max_end = min(max_end, kdc_time + *server->entry.max_life);
if(client && client->entry.max_life)
max_end = min(max_end, kdc_time + *client->entry.max_life);
life = min(life, krb_time_to_life(kdc_time, max_end));
issue_time = kdc_time;
actual_end = _krb5_krb_life_to_time(issue_time, life);
while (actual_end > max_end && life > 1) {
/* move them into the next earlier lifetime bracket */
life--;
actual_end = _krb5_krb_life_to_time(issue_time, life);
}
if (actual_end > max_end) {
/* if life <= 1 and it's still too long, backdate the ticket */
issue_time -= actual_end - max_end;
}
{
krb5_data ticket, cipher;
krb5_keyblock session;
krb5_data_zero(&ticket);
krb5_data_zero(&cipher);
ret = krb5_generate_random_keyblock(context,
ETYPE_DES_PCBC_NONE,
&session);
if (ret) {
make_err_reply(context, reply, KFAILURE,
"Not enough random i KDC");
goto out2;
}
ret = _krb5_krb_create_ticket(context,
0,
ad.pname,
ad.pinst,
ad.prealm,
addr->sin_addr.s_addr,
&session,
life,
issue_time,
sname,
sinst,
&skey->key,
&ticket);
if (ret) {
krb5_free_keyblock_contents(context, &session);
make_err_reply(context, reply, KFAILURE,
"failed to create v4 ticket");
goto out2;
}
ret = _krb5_krb_create_ciph(context,
&session,
sname,
sinst,
config->v4_realm,
life,
server->entry.kvno % 255,
&ticket,
issue_time,
&ad.session,
&cipher);
krb5_free_keyblock_contents(context, &session);
if (ret) {
make_err_reply(context, reply, KFAILURE,
"failed to create v4 cipher");
goto out2;
}
ret = _krb5_krb_create_auth_reply(context,
ad.pname,
ad.pinst,
ad.prealm,
req_time,
0,
0,
0,
&cipher,
reply);
krb5_data_free(&cipher);
}
out2:
_krb5_krb_free_auth_data(context, &ad);
if(tgt_princ)
krb5_free_principal(context, tgt_princ);
if(tgt)
_kdc_free_ent(context, tgt);
break;
}
case AUTH_MSG_ERR_REPLY:
ret = EINVAL;
break;
default:
kdc_log(context, config, 0, "Unknown message type (krb4): %d from %s",
msg_type, from);
make_err_reply(context, reply, KFAILURE, "Unknown message type");
ret = EINVAL;
}
out:
if(name)
free(name);
if(inst)
free(inst);
if(realm)
free(realm);
if(sname)
free(sname);
if(sinst)
free(sinst);
if(client)
_kdc_free_ent(context, client);
if(server)
_kdc_free_ent(context, server);
krb5_storage_free(sp);
return ret;
}
krb5_error_code
_kdc_encode_v4_ticket(krb5_context context,
krb5_kdc_configuration *config,
void *buf, size_t len, const EncTicketPart *et,
const PrincipalName *service, size_t *size)
{
krb5_storage *sp;
krb5_error_code ret;
char name[40], inst[40], realm[40];
char sname[40], sinst[40];
{
krb5_principal princ;
_krb5_principalname2krb5_principal(context,
&princ,
*service,
et->crealm);
ret = krb5_524_conv_principal(context,
princ,
sname,
sinst,
realm);
krb5_free_principal(context, princ);
if(ret)
return ret;
_krb5_principalname2krb5_principal(context,
&princ,
et->cname,
et->crealm);
ret = krb5_524_conv_principal(context,
princ,
name,
inst,
realm);
krb5_free_principal(context, princ);
}
if(ret)
return ret;
sp = krb5_storage_emem();
krb5_store_int8(sp, 0); /* flags */
krb5_store_stringz(sp, name);
krb5_store_stringz(sp, inst);
krb5_store_stringz(sp, realm);
{
unsigned char tmp[4] = { 0, 0, 0, 0 };
int i;
if(et->caddr){
for(i = 0; i < et->caddr->len; i++)
if(et->caddr->val[i].addr_type == AF_INET &&
et->caddr->val[i].address.length == 4){
memcpy(tmp, et->caddr->val[i].address.data, 4);
break;
}
}
krb5_storage_write(sp, tmp, sizeof(tmp));
}
if((et->key.keytype != ETYPE_DES_CBC_MD5 &&
et->key.keytype != ETYPE_DES_CBC_MD4 &&
et->key.keytype != ETYPE_DES_CBC_CRC) ||
et->key.keyvalue.length != 8)
return -1;
krb5_storage_write(sp, et->key.keyvalue.data, 8);
{
time_t start = et->starttime ? *et->starttime : et->authtime;
krb5_store_int8(sp, krb_time_to_life(start, et->endtime));
krb5_store_int32(sp, start);
}
krb5_store_stringz(sp, sname);
krb5_store_stringz(sp, sinst);
{
krb5_data data;
krb5_storage_to_data(sp, &data);
krb5_storage_free(sp);
*size = (data.length + 7) & ~7; /* pad to 8 bytes */
if(*size > len)
return -1;
memset((unsigned char*)buf - *size + 1, 0, *size);
memcpy((unsigned char*)buf - *size + 1, data.data, data.length);
krb5_data_free(&data);
}
return 0;
}
krb5_error_code
_kdc_get_des_key(krb5_context context,
hdb_entry_ex *principal, krb5_boolean is_server,
krb5_boolean prefer_afs_key, Key **ret_key)
{
Key *v5_key = NULL, *v4_key = NULL, *afs_key = NULL, *server_key = NULL;
int i;
krb5_enctype etypes[] = { ETYPE_DES_CBC_MD5,
ETYPE_DES_CBC_MD4,
ETYPE_DES_CBC_CRC };
for(i = 0;
i < sizeof(etypes)/sizeof(etypes[0])
&& (v5_key == NULL || v4_key == NULL ||
afs_key == NULL || server_key == NULL);
++i) {
Key *key = NULL;
while(hdb_next_enctype2key(context, &principal->entry, etypes[i], &key) == 0) {
if(key->salt == NULL) {
if(v5_key == NULL)
v5_key = key;
} else if(key->salt->type == hdb_pw_salt &&
key->salt->salt.length == 0) {
if(v4_key == NULL)
v4_key = key;
} else if(key->salt->type == hdb_afs3_salt) {
if(afs_key == NULL)
afs_key = key;
} else if(server_key == NULL)
server_key = key;
}
}
if(prefer_afs_key) {
if(afs_key)
*ret_key = afs_key;
else if(v4_key)
*ret_key = v4_key;
else if(v5_key)
*ret_key = v5_key;
else if(is_server && server_key)
*ret_key = server_key;
else
return KRB4ET_KDC_NULL_KEY;
} else {
if(v4_key)
*ret_key = v4_key;
else if(afs_key)
*ret_key = afs_key;
else if(v5_key)
*ret_key = v5_key;
else if(is_server && server_key)
*ret_key = server_key;
else
return KRB4ET_KDC_NULL_KEY;
}
if((*ret_key)->key.keyvalue.length == 0)
return KRB4ET_KDC_NULL_KEY;
return 0;
}

View File

@ -90,7 +90,7 @@ _kdc_find_padata(const KDC_REQ *req, int *start, int type)
*/
krb5_boolean
_kdc_is_weak_expection(krb5_principal principal, krb5_enctype etype)
_kdc_is_weak_exception(krb5_principal principal, krb5_enctype etype)
{
if (principal->name.name_string.len > 0 &&
strcmp(principal->name.name_string.val[0], "afs") == 0 &&
@ -139,7 +139,7 @@ _kdc_find_etype(krb5_context context, const hdb_entry_ex *princ,
Key *key = NULL;
if (krb5_enctype_valid(context, etypes[i]) != 0 &&
!_kdc_is_weak_expection(princ->entry.principal, etypes[i]))
!_kdc_is_weak_exception(princ->entry.principal, etypes[i]))
continue;
while (hdb_next_enctype2key(context, &princ->entry, etypes[i], &key) == 0) {
@ -260,7 +260,7 @@ _kdc_encode_reply(krb5_context context,
KDC_REP *rep, const EncTicketPart *et, EncKDCRepPart *ek,
krb5_enctype etype,
int skvno, const EncryptionKey *skey,
int ckvno, const EncryptionKey *ckey,
int ckvno, const EncryptionKey *reply_key,
const char **e_text,
krb5_data *reply)
{
@ -321,7 +321,7 @@ _kdc_encode_reply(krb5_context context,
*e_text = "KDC internal error";
return KRB5KRB_ERR_GENERIC;
}
ret = krb5_crypto_init(context, ckey, 0, &crypto);
ret = krb5_crypto_init(context, reply_key, 0, &crypto);
if (ret) {
free(buf);
kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
@ -394,18 +394,6 @@ older_enctype(krb5_enctype enctype)
}
}
static int
only_older_enctype_p(const KDC_REQ *req)
{
int i;
for(i = 0; i < req->req_body.etype.len; i++) {
if (!older_enctype(req->req_body.etype.val[i]))
return 0;
}
return 1;
}
/*
*
*/
@ -461,72 +449,23 @@ make_etype_info_entry(krb5_context context, ETYPE_INFO_ENTRY *ent, Key *key)
static krb5_error_code
get_pa_etype_info(krb5_context context,
krb5_kdc_configuration *config,
METHOD_DATA *md, hdb_entry *client,
ENCTYPE *etypes, unsigned int etypes_len)
METHOD_DATA *md, Key *ckey)
{
krb5_error_code ret = 0;
int i, j;
unsigned int n = 0;
ETYPE_INFO pa;
unsigned char *buf;
size_t len;
pa.len = client->keys.len;
if(pa.len > UINT_MAX/sizeof(*pa.val))
return ERANGE;
pa.val = malloc(pa.len * sizeof(*pa.val));
pa.len = 1;
pa.val = calloc(1, sizeof(pa.val[0]));
if(pa.val == NULL)
return ENOMEM;
memset(pa.val, 0, pa.len * sizeof(*pa.val));
for(i = 0; i < client->keys.len; i++) {
for (j = 0; j < n; j++)
if (pa.val[j].etype == client->keys.val[i].key.keytype)
goto skip1;
for(j = 0; j < etypes_len; j++) {
if(client->keys.val[i].key.keytype == etypes[j]) {
if (krb5_enctype_valid(context, etypes[j]) != 0)
continue;
if (!older_enctype(etypes[j]))
continue;
if (n >= pa.len)
krb5_abortx(context, "internal error: n >= p.len");
if((ret = make_etype_info_entry(context,
&pa.val[n++],
&client->keys.val[i])) != 0) {
free_ETYPE_INFO(&pa);
return ret;
}
break;
}
}
skip1:;
}
for(i = 0; i < client->keys.len; i++) {
/* already added? */
for(j = 0; j < etypes_len; j++) {
if(client->keys.val[i].key.keytype == etypes[j])
goto skip2;
}
if (krb5_enctype_valid(context, client->keys.val[i].key.keytype) != 0)
continue;
if (!older_enctype(etypes[j]))
continue;
if (n >= pa.len)
krb5_abortx(context, "internal error: n >= p.len");
if((ret = make_etype_info_entry(context,
&pa.val[n++],
&client->keys.val[i])) != 0) {
free_ETYPE_INFO(&pa);
return ret;
}
skip2:;
}
if(n < pa.len) {
/* stripped out dups, newer enctypes, and not valid enctypes */
pa.len = n;
ret = make_etype_info_entry(context, &pa.val[0], ckey);
if (ret) {
free_ETYPE_INFO(&pa);
return ret;
}
ASN1_MALLOC_ENCODE(ETYPE_INFO, buf, len, &pa, &len, ret);
@ -623,66 +562,22 @@ make_etype_info2_entry(ETYPE_INFO2_ENTRY *ent, Key *key)
static krb5_error_code
get_pa_etype_info2(krb5_context context,
krb5_kdc_configuration *config,
METHOD_DATA *md, hdb_entry *client,
ENCTYPE *etypes, unsigned int etypes_len)
METHOD_DATA *md, Key *ckey)
{
krb5_error_code ret = 0;
int i, j;
unsigned int n = 0;
ETYPE_INFO2 pa;
unsigned char *buf;
size_t len;
pa.len = client->keys.len;
if(pa.len > UINT_MAX/sizeof(*pa.val))
return ERANGE;
pa.val = malloc(pa.len * sizeof(*pa.val));
pa.len = 1;
pa.val = calloc(1, sizeof(pa.val[0]));
if(pa.val == NULL)
return ENOMEM;
memset(pa.val, 0, pa.len * sizeof(*pa.val));
for(i = 0; i < client->keys.len; i++) {
for (j = 0; j < n; j++)
if (pa.val[j].etype == client->keys.val[i].key.keytype)
goto skip1;
for(j = 0; j < etypes_len; j++) {
if(client->keys.val[i].key.keytype == etypes[j]) {
if (krb5_enctype_valid(context, etypes[j]) != 0)
continue;
if (n >= pa.len)
krb5_abortx(context, "internal error: n >= p.len");
if((ret = make_etype_info2_entry(&pa.val[n++],
&client->keys.val[i])) != 0) {
free_ETYPE_INFO2(&pa);
return ret;
}
break;
}
}
skip1:;
}
/* send enctypes that the client doesn't know about too */
for(i = 0; i < client->keys.len; i++) {
/* already added? */
for(j = 0; j < etypes_len; j++) {
if(client->keys.val[i].key.keytype == etypes[j])
goto skip2;
}
if (krb5_enctype_valid(context, client->keys.val[i].key.keytype) != 0)
continue;
if (n >= pa.len)
krb5_abortx(context, "internal error: n >= p.len");
if((ret = make_etype_info2_entry(&pa.val[n++],
&client->keys.val[i])) != 0) {
free_ETYPE_INFO2(&pa);
return ret;
}
skip2:;
}
if(n < pa.len) {
/* stripped out dups, and not valid enctypes */
pa.len = n;
ret = make_etype_info2_entry(&pa.val[0], ckey);
if (ret) {
free_ETYPE_INFO2(&pa);
return ret;
}
ASN1_MALLOC_ENCODE(ETYPE_INFO2, buf, len, &pa, &len, ret);
@ -712,10 +607,12 @@ log_as_req(krb5_context context,
const KDC_REQ_BODY *b)
{
krb5_error_code ret;
struct rk_strpool *p = NULL;
struct rk_strpool *p;
char *str;
int i;
p = rk_strpoolprintf(NULL, "%s", "Client supported enctypes: ");
for (i = 0; i < b->etype.len; i++) {
ret = krb5_enctype_to_string(context, b->etype.val[i], &str);
if (ret == 0) {
@ -733,10 +630,6 @@ log_as_req(krb5_context context,
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;
@ -745,21 +638,26 @@ log_as_req(krb5_context context,
if(ret == 0) {
ret = krb5_enctype_to_string(context, setype, &set);
if (ret == 0) {
kdc_log(context, config, 5, "Using %s/%s", cet, set);
p = rk_strpoolprintf(p, ", using %s/%s", cet, set);
free(set);
}
free(cet);
}
if (ret != 0)
kdc_log(context, config, 5, "Using e-types %d/%d", cetype, setype);
p = rk_strpoolprintf(p, ", using enctypes %d/%d",
cetype, setype);
}
str = rk_strpoolcollect(p);
kdc_log(context, config, 0, "%s", str);
free(str);
{
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);
kdc_log(context, config, 0, "Requested flags: %s", fixedstr);
}
}
@ -956,6 +854,17 @@ send_pac_p(krb5_context context, KDC_REQ *req)
return TRUE;
}
krb5_boolean
_kdc_is_anonymous(krb5_context context, krb5_principal principal)
{
if (principal->name.name_type != KRB5_NT_WELLKNOWN ||
principal->name.name_string.len != 2 ||
strcmp(principal->name.name_string.val[0], KRB5_WELLKNOWN_NAME) != 0 ||
strcmp(principal->name.name_string.val[1], KRB5_ANON_NAME) != 0)
return 0;
return 1;
}
/*
*
*/
@ -1039,6 +948,7 @@ _kdc_as_rep(krb5_context context,
if (ret)
goto out;
}
ret = krb5_unparse_name(context, client_princ, &client_name);
}
if (ret) {
@ -1050,6 +960,28 @@ _kdc_as_rep(krb5_context context,
kdc_log(context, config, 0, "AS-REQ %s from %s for %s",
client_name, from, server_name);
/*
*
*/
if (_kdc_is_anonymous(context, client_princ)) {
if (!b->kdc_options.request_anonymous) {
kdc_log(context, config, 0, "Anonymous ticket w/o anonymous flag");
ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
goto out;
}
} else if (b->kdc_options.request_anonymous) {
kdc_log(context, config, 0,
"Request for a anonymous ticket with non "
"anonymous client name: %s", client_name);
ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
goto out;
}
/*
*
*/
ret = _kdc_db_fetch(context, config, client_princ,
HDB_F_GET_CLIENT | flags, NULL, &client);
if(ret){
@ -1069,20 +1001,28 @@ _kdc_as_rep(krb5_context context,
goto out;
}
ret = _kdc_windc_client_access(context, client, req, &e_data);
if(ret)
goto out;
ret = _kdc_check_flags(context, config,
client, client_name,
server, server_name,
TRUE);
if(ret)
goto out;
memset(&et, 0, sizeof(et));
memset(&ek, 0, sizeof(ek));
/*
* Find the client key for reply encryption and pa-type salt, Pick
* the client key upfront before the other keys because that is
* going to affect what enctypes we are going to use in
* ETYPE-INFO{,2}.
*/
ret = _kdc_find_etype(context, client, b->etype.val, b->etype.len,
&ckey, &cetype);
if (ret) {
kdc_log(context, config, 0,
"Client (%s) has no support for etypes", client_name);
goto out;
}
/*
* Pre-auth processing
*/
if(req->padata){
int i;
const PA_DATA *pa;
@ -1097,17 +1037,15 @@ _kdc_as_rep(krb5_context context,
e_text = "No PKINIT PA found";
i = 0;
if ((pa = _kdc_find_padata(req, &i, KRB5_PADATA_PK_AS_REQ)))
;
pa = _kdc_find_padata(req, &i, KRB5_PADATA_PK_AS_REQ);
if (pa == NULL) {
i = 0;
if((pa = _kdc_find_padata(req, &i, KRB5_PADATA_PK_AS_REQ_WIN)))
;
pa = _kdc_find_padata(req, &i, KRB5_PADATA_PK_AS_REQ_WIN);
}
if (pa) {
char *client_cert = NULL;
ret = _kdc_pk_rd_padata(context, config, req, pa, &pkp);
ret = _kdc_pk_rd_padata(context, config, req, pa, client, &pkp);
if (ret) {
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
kdc_log(context, config, 5,
@ -1127,11 +1065,12 @@ _kdc_as_rep(krb5_context context,
e_text = "PKINIT certificate not allowed to "
"impersonate principal";
_kdc_pk_free_client_param(context, pkp);
kdc_log(context, config, 0, "%s", e_text);
pkp = NULL;
goto out;
}
found_pa = 1;
et.flags.pre_authent = 1;
kdc_log(context, config, 0,
@ -1158,6 +1097,12 @@ _kdc_as_rep(krb5_context context,
found_pa = 1;
if (b->kdc_options.request_anonymous) {
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY;
kdc_log(context, config, 0, "ENC-TS doesn't support anon");
goto out;
}
ret = decode_EncryptedData(pa->padata_value.data,
pa->padata_value.length,
&enc_data,
@ -1206,6 +1151,11 @@ _kdc_as_rep(krb5_context context,
&enc_data,
&ts_data);
krb5_crypto_destroy(context, crypto);
/*
* Since the user might have several keys with the same
* enctype but with diffrent salting, we need to try all
* the keys with the same enctype.
*/
if(ret){
krb5_error_code ret2;
ret2 = krb5_enctype_to_string(context,
@ -1298,6 +1248,7 @@ _kdc_as_rep(krb5_context context,
goto out;
}
}else if (config->require_preauth
|| b->kdc_options.request_anonymous /* hack to force anon */
|| client->entry.flags.require_preauth
|| server->entry.flags.require_preauth) {
METHOD_DATA method_data;
@ -1310,6 +1261,10 @@ _kdc_as_rep(krb5_context context,
method_data.val = NULL;
ret = realloc_method_data(&method_data);
if (ret) {
free_METHOD_DATA(&method_data);
goto out;
}
pa = &method_data.val[method_data.len-1];
pa->padata_type = KRB5_PADATA_ENC_TIMESTAMP;
pa->padata_value.length = 0;
@ -1317,12 +1272,20 @@ _kdc_as_rep(krb5_context context,
#ifdef PKINIT
ret = realloc_method_data(&method_data);
if (ret) {
free_METHOD_DATA(&method_data);
goto out;
}
pa = &method_data.val[method_data.len-1];
pa->padata_type = KRB5_PADATA_PK_AS_REQ;
pa->padata_value.length = 0;
pa->padata_value.data = NULL;
ret = realloc_method_data(&method_data);
if (ret) {
free_METHOD_DATA(&method_data);
goto out;
}
pa = &method_data.val[method_data.len-1];
pa->padata_type = KRB5_PADATA_PK_AS_REQ_WIN;
pa->padata_value.length = 0;
@ -1330,22 +1293,37 @@ _kdc_as_rep(krb5_context context,
#endif
/*
* RFC4120 requires:
* - If the client only knows about old enctypes, then send
* both info replies (we send 'info' first in the list).
* - If the client is 'modern', because it knows about 'new'
* enctype types, then only send the 'info2' reply.
* If there is a client key, send ETYPE_INFO{,2}
*/
if (ckey) {
/* XXX check ret */
if (only_older_enctype_p(req))
ret = get_pa_etype_info(context, config,
&method_data, &client->entry,
b->etype.val, b->etype.len);
/* XXX check ret */
ret = get_pa_etype_info2(context, config, &method_data,
&client->entry, b->etype.val, b->etype.len);
/*
* RFC4120 requires:
* - If the client only knows about old enctypes, then send
* both info replies (we send 'info' first in the list).
* - If the client is 'modern', because it knows about 'new'
* enctype types, then only send the 'info2' reply.
*
* Before we send the full list of etype-info data, we pick
* the client key we would have used anyway below, just pick
* that instead.
*/
if (older_enctype(ckey->key.keytype)) {
ret = get_pa_etype_info(context, config,
&method_data, ckey);
if (ret) {
free_METHOD_DATA(&method_data);
goto out;
}
}
ret = get_pa_etype_info2(context, config,
&method_data, ckey);
if (ret) {
free_METHOD_DATA(&method_data);
goto out;
}
}
ASN1_MALLOC_ENCODE(METHOD_DATA, buf, len, &method_data, &len, ret);
free_METHOD_DATA(&method_data);
@ -1363,20 +1341,26 @@ _kdc_as_rep(krb5_context context,
}
/*
* Find the client key (for preauth ENC-TS verification and reply
* encryption). Then the best encryption type for the KDC and
* last the best session key that shared between the client and
* KDC runtime enctypes.
* Verify flags after the user been required to prove its identity
* with in a preauth mech.
*/
ret = _kdc_find_etype(context, client, b->etype.val, b->etype.len,
&ckey, &cetype);
if (ret) {
kdc_log(context, config, 0,
"Client (%s) has no support for etypes", client_name);
ret = _kdc_check_flags(context, config,
client, client_name,
server, server_name,
TRUE);
if(ret)
goto out;
}
ret = _kdc_windc_client_access(context, client, req, &e_data);
if(ret)
goto out;
/*
* Selelct the best encryption type for the KDC with out regard to
* the client since the client never needs to read that data.
*/
ret = _kdc_get_preferred_key(context, config,
server, server_name,
&setype, &skey);
@ -1449,12 +1433,14 @@ _kdc_as_rep(krb5_context context,
rep.pvno = 5;
rep.msg_type = krb_as_rep;
copy_Realm(&client->entry.principal->realm, &rep.crealm);
if (f.request_anonymous)
_kdc_make_anonymous_principalname (&rep.cname);
else
_krb5_principal2principalname(&rep.cname,
client->entry.principal);
ret = copy_Realm(&client->entry.principal->realm, &rep.crealm);
if (ret)
goto out;
ret = _krb5_principal2principalname(&rep.cname, client->entry.principal);
if (ret)
goto out;
rep.ticket.tkt_vno = 5;
copy_Realm(&server->entry.principal->realm, &rep.ticket.realm);
_krb5_principal2principalname(&rep.ticket.sname,
@ -1500,11 +1486,12 @@ _kdc_as_rep(krb5_context context,
goto out;
}
ret = krb5_generate_random_keyblock(context, sessionetype, &et.key);
ret = copy_PrincipalName(&rep.cname, &et.cname);
if (ret)
goto out;
ret = copy_Realm(&rep.crealm, &et.crealm);
if (ret)
goto out;
copy_PrincipalName(&rep.cname, &et.cname);
copy_Realm(&rep.crealm, &et.crealm);
{
time_t start;
@ -1568,8 +1555,6 @@ _kdc_as_rep(krb5_context context,
et.transited.tr_type = DOMAIN_X500_COMPRESS;
krb5_data_zero(&et.transited.contents);
copy_EncryptionKey(&et.key, &ek.key);
/* The MIT ASN.1 library (obviously) doesn't tell lengths encoded
* as 0 and as 0x80 (meaning indefinite length) apart, and is thus
* incapable of correctly decoding SEQUENCE OF's of zero length.
@ -1637,12 +1622,12 @@ _kdc_as_rep(krb5_context context,
rep.padata->len = 0;
rep.padata->val = NULL;
reply_key = &ckey->key;
#if PKINIT
if (pkp) {
e_text = "Failed to build PK-INIT reply";
ret = _kdc_pk_mk_pa_reply(context, config, pkp, client,
req, req_buffer,
&reply_key, rep.padata);
sessionetype, req, req_buffer,
&reply_key, &et.key, rep.padata);
if (ret)
goto out;
ret = _kdc_add_inital_verified_cas(context,
@ -1651,10 +1636,25 @@ _kdc_as_rep(krb5_context context,
&et);
if (ret)
goto out;
}
} else
#endif
if (ckey) {
reply_key = &ckey->key;
ret = krb5_generate_random_keyblock(context, sessionetype, &et.key);
if (ret)
goto out;
} else {
e_text = "Client have no reply key";
ret = KRB5KDC_ERR_CLIENT_NOTYET;
goto out;
}
set_salt_padata (rep.padata, ckey->salt);
ret = copy_EncryptionKey(&et.key, &ek.key);
if (ret)
goto out;
if (ckey)
set_salt_padata (rep.padata, ckey->salt);
/* Add signing of alias referral */
if (f.canonicalize) {

View File

@ -107,7 +107,7 @@ _kdc_add_KRB5SignedPath(krb5_context context,
hdb_entry_ex *krbtgt,
krb5_enctype enctype,
krb5_const_principal server,
KRB5SignedPathPrincipals *principals,
krb5_principals principals,
EncTicketPart *tkt)
{
krb5_error_code ret;
@ -117,7 +117,7 @@ _kdc_add_KRB5SignedPath(krb5_context context,
size_t size;
if (server && principals) {
ret = add_KRB5SignedPathPrincipals(principals, server);
ret = add_Principals(principals, server);
if (ret)
return ret;
}
@ -186,7 +186,7 @@ check_KRB5SignedPath(krb5_context context,
krb5_kdc_configuration *config,
hdb_entry_ex *krbtgt,
EncTicketPart *tkt,
KRB5SignedPathPrincipals **delegated,
krb5_principals *delegated,
int *signedpath)
{
krb5_error_code ret;
@ -255,7 +255,7 @@ check_KRB5SignedPath(krb5_context context,
return ENOMEM;
}
ret = copy_KRB5SignedPathPrincipals(*delegated, sp.delegated);
ret = copy_Principals(*delegated, sp.delegated);
if (ret) {
free_KRB5SignedPath(&sp);
free(*delegated);
@ -668,7 +668,7 @@ tgs_make_reply(krb5_context context,
krb5_principal client_principal,
hdb_entry_ex *krbtgt,
krb5_enctype krbtgt_etype,
KRB5SignedPathPrincipals *spp,
krb5_principals spp,
const krb5_data *rspac,
const METHOD_DATA *enc_pa_data,
const char **e_text,
@ -725,14 +725,13 @@ tgs_make_reply(krb5_context context,
PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(server)) ||
GLOBAL_ALLOW_DISABLE_TRANSITED_CHECK),
&tgt->transited, &et,
*krb5_princ_realm(context, client_principal),
*krb5_princ_realm(context, server->entry.principal),
*krb5_princ_realm(context, krbtgt->entry.principal));
krb5_principal_get_realm(context, client_principal),
krb5_principal_get_realm(context, server->entry.principal),
krb5_principal_get_realm(context, krbtgt->entry.principal));
if(ret)
goto out;
copy_Realm(krb5_princ_realm(context, server_principal),
&rep.ticket.realm);
copy_Realm(&server_principal->realm, &rep.ticket.realm);
_krb5_principal2principalname(&rep.ticket.sname, server_principal);
copy_Realm(&tgt_name->realm, &rep.crealm);
/*
@ -888,7 +887,7 @@ tgs_make_reply(krb5_context context,
}
if (krb5_enctype_valid(context, et.key.keytype) != 0
&& _kdc_is_weak_expection(server->entry.principal, et.key.keytype))
&& _kdc_is_weak_exception(server->entry.principal, et.key.keytype))
{
krb5_enctype_enable(context, et.key.keytype);
is_weak = 1;
@ -1035,7 +1034,7 @@ need_referral(krb5_context context, krb5_kdc_configuration *config,
if (server->name.name_string.len == 1)
name = server->name.name_string.val[0];
if (server->name.name_string.len > 1)
else if (server->name.name_string.len > 1)
name = server->name.name_string.val[1];
else
return FALSE;
@ -1205,9 +1204,7 @@ tgs_parse_request(krb5_context context,
krb5_keyblock *subkey;
krb5_data ad;
ret = krb5_auth_con_getremotesubkey(context,
ac,
&subkey);
ret = krb5_auth_con_getremotesubkey(context, ac, &subkey);
if(ret){
krb5_auth_con_free(context, ac);
kdc_log(context, config, 0, "Failed to get remote subkey: %s",
@ -1232,6 +1229,7 @@ tgs_parse_request(krb5_context context,
goto out;
}
ret = krb5_crypto_init(context, subkey, 0, &crypto);
krb5_free_keyblock(context, subkey);
if (ret) {
krb5_auth_con_free(context, ac);
kdc_log(context, config, 0, "krb5_crypto_init failed: %s",
@ -1251,7 +1249,6 @@ tgs_parse_request(krb5_context context,
ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; /* ? */
goto out;
}
krb5_free_keyblock(context, subkey);
ALLOC(*auth_data);
if (*auth_data == NULL) {
krb5_auth_con_free(context, ac);
@ -1365,8 +1362,7 @@ tgs_build_reply(krb5_context context,
const char *from,
const char **e_text,
AuthorizationData **auth_data,
const struct sockaddr *from_addr,
int datagram_reply)
const struct sockaddr *from_addr)
{
krb5_error_code ret;
krb5_principal cp = NULL, sp = NULL;
@ -1375,13 +1371,11 @@ tgs_build_reply(krb5_context context,
hdb_entry_ex *server = NULL, *client = NULL;
krb5_realm ref_realm = NULL;
EncTicketPart *tgt = &ticket->ticket;
KRB5SignedPathPrincipals *spp = NULL;
Key *tkey;
krb5_principals spp = NULL;
const EncryptionKey *ekey;
krb5_keyblock sessionkey;
krb5_kvno kvno;
krb5_data rspac;
int cross_realm = 0;
METHOD_DATA enc_pa_data;
@ -1392,6 +1386,8 @@ tgs_build_reply(krb5_context context,
char opt_str[128];
int signedpath = 0;
Key *tkey;
memset(&sessionkey, 0, sizeof(sessionkey));
memset(&adtkt, 0, sizeof(adtkt));
krb5_data_zero(&rspac);
@ -1559,8 +1555,6 @@ server_lookup:
kdc_log(context, config, 1, "Client not found in database: %s: %s",
cpn, krb5_get_err_text(context, ret));
cross_realm = 1;
}
/*
@ -1578,9 +1572,10 @@ server_lookup:
break;
if(i == b->etype.len) {
kdc_log(context, config, 0,
"Addition ticket have not matching etypes", spp);
"Addition ticket have not matching etypes");
krb5_clear_error_message(context);
return KRB5KDC_ERR_ETYPE_NOSUPP;
ret = KRB5KDC_ERR_ETYPE_NOSUPP;
goto out;
}
etype = b->etype.val[i];
kvno = 0;
@ -1592,7 +1587,7 @@ server_lookup:
if(ret) {
kdc_log(context, config, 0,
"Server (%s) has no support for etypes", spn);
return ret;
goto out;
}
ekey = &skey->key;
kvno = server->entry.kvno;
@ -1603,10 +1598,6 @@ server_lookup:
goto out;
}
/*
* Validate authoriation data
*/
/*
* Check that service is in the same realm as the krbtgt. If it's
* not the same, it's someone that is using a uni-directional trust
@ -1628,13 +1619,15 @@ server_lookup:
goto out;
}
/* check PAC if there is one */
/*
* Validate authoriation data
*/
ret = hdb_enctype2key(context, &krbtgt->entry,
krbtgt_etype, &tkey);
if(ret) {
kdc_log(context, config, 0,
"Failed to find key for krbtgt PAC check");
"Failed to find key for krbtgt PAC check");
goto out;
}
@ -1672,7 +1665,7 @@ server_lookup:
const PA_DATA *sdata;
int i = 0;
sdata = _kdc_find_padata(req, &i, KRB5_PADATA_S4U2SELF);
sdata = _kdc_find_padata(req, &i, KRB5_PADATA_FOR_USER);
if (sdata) {
krb5_crypto crypto;
krb5_data datack;
@ -2044,8 +2037,7 @@ _kdc_tgs_rep(krb5_context context,
from,
&e_text,
&auth_data,
from_addr,
datagram_reply);
from_addr);
if (ret) {
kdc_log(context, config, 0,
"Failed building TGS-REP to %s", from);

View File

@ -36,14 +36,14 @@
#include <rfc2459_asn1.h>
#include <hx509.h>
RCSID("$Id$");
#ifdef KX509
/*
*
*/
krb5_error_code
_kdc_try_kx509_request(void *ptr, size_t len, Kx509Request *req, size_t *size)
_kdc_try_kx509_request(void *ptr, size_t len, struct Kx509Request *req, size_t *size)
{
if (len < 4)
return -1;
@ -97,16 +97,15 @@ calculate_reply_hash(krb5_context context,
krb5_keyblock *key,
Kx509Response *rep)
{
krb5_error_code ret;
HMAC_CTX ctx;
HMAC_CTX_init(&ctx);
HMAC_Init_ex(&ctx,
key->keyvalue.data, key->keyvalue.length,
HMAC_Init_ex(&ctx, key->keyvalue.data, key->keyvalue.length,
EVP_sha1(), NULL);
rep->hash->length = HMAC_size(&ctx);
rep->hash->data = malloc(rep->hash->length);
if (rep->hash->data == NULL) {
ret = krb5_data_alloc(rep->hash, HMAC_size(&ctx));
if (ret) {
HMAC_CTX_cleanup(&ctx);
krb5_set_error_message(context, ENOMEM, "malloc: out of memory");
return ENOMEM;
@ -208,7 +207,7 @@ build_certificate(krb5_context context,
spki.subjectPublicKey.data = key->data;
spki.subjectPublicKey.length = key->length * 8;
ret = der_copy_oid(oid_id_pkcs1_rsaEncryption(),
ret = der_copy_oid(&asn1_oid_id_pkcs1_rsaEncryption,
&spki.algorithm.algorithm);
any.data = "\x05\x00";
@ -289,7 +288,7 @@ out:
krb5_error_code
_kdc_do_kx509(krb5_context context,
krb5_kdc_configuration *config,
const Kx509Request *req, krb5_data *reply,
const struct Kx509Request *req, krb5_data *reply,
const char *from, struct sockaddr *addr)
{
krb5_error_code ret;
@ -385,8 +384,10 @@ _kdc_do_kx509(krb5_context context,
if (ret)
goto out;
free_RSAPublicKey(&key);
if (size != req->pk_key.length)
;
if (size != req->pk_key.length) {
ret = ASN1_EXTRA_DATA;
goto out;
}
}
ALLOC(rep.certificate);
@ -458,3 +459,5 @@ out:
return 0;
}
#endif /* KX509 */

File diff suppressed because it is too large Load Diff

View File

@ -34,8 +34,6 @@
#include "kdc_locl.h"
RCSID("$Id$");
/*
*
*/
@ -49,6 +47,209 @@ krb5_kdc_update_time(struct timeval *tv)
_kdc_now = *tv;
}
static krb5_error_code
kdc_as_req(krb5_context context,
krb5_kdc_configuration *config,
krb5_data *req_buffer,
krb5_data *reply,
const char *from,
struct sockaddr *addr,
int datagram_reply,
int *claim)
{
krb5_error_code ret;
KDC_REQ req;
size_t len;
ret = decode_AS_REQ(req_buffer->data, req_buffer->length, &req, &len);
if (ret)
return ret;
*claim = 1;
ret = _kdc_as_rep(context, config, &req, req_buffer,
reply, from, addr, datagram_reply);
free_AS_REQ(&req);
return ret;
}
static krb5_error_code
kdc_tgs_req(krb5_context context,
krb5_kdc_configuration *config,
krb5_data *req_buffer,
krb5_data *reply,
const char *from,
struct sockaddr *addr,
int datagram_reply,
int *claim)
{
krb5_error_code ret;
KDC_REQ req;
size_t len;
ret = decode_TGS_REQ(req_buffer->data, req_buffer->length, &req, &len);
if (ret)
return ret;
*claim = 1;
ret = _kdc_tgs_rep(context, config, &req, reply,
from, addr, datagram_reply);
free_TGS_REQ(&req);
return ret;
}
#ifdef DIGEST
static krb5_error_code
kdc_digest(krb5_context context,
krb5_kdc_configuration *config,
krb5_data *req_buffer,
krb5_data *reply,
const char *from,
struct sockaddr *addr,
int datagram_reply,
int *claim)
{
DigestREQ digestreq;
krb5_error_code ret;
size_t len;
ret = decode_DigestREQ(req_buffer->data, req_buffer->length,
&digestreq, &len);
if (ret)
return ret;
*claim = 1;
ret = _kdc_do_digest(context, config, &digestreq, reply, from, addr);
free_DigestREQ(&digestreq);
return ret;
}
#endif
#ifdef KX509
static krb5_error_code
kdc_kx509(krb5_context context,
krb5_kdc_configuration *config,
krb5_data *req_buffer,
krb5_data *reply,
const char *from,
struct sockaddr *addr,
int datagram_reply,
int *claim)
{
Kx509Request kx509req;
krb5_error_code ret;
size_t len;
ret = _kdc_try_kx509_request(req_buffer->data, req_buffer->length,
&kx509req, &len);
if (ret)
return ret;
*claim = 1;
ret = _kdc_do_kx509(context, config, &kx509req, reply, from, addr);
free_Kx509Request(&kx509req);
return ret;
}
#endif
#ifdef KRB4
static krb5_error_code
kdc_524(krb5_context context,
krb5_kdc_configuration *config,
krb5_data *req_buffer,
krb5_data *reply,
const char *from,
struct sockaddr *addr,
int datagram_reply,
int *claim)
{
krb5_error_code ret;
Ticket ticket;
size_t len;
ret = decode_Ticket(req_buffer->data, req_buffer->length, &ticket, &len);
if (ret)
return ret;
*claim = 1;
ret = _kdc_do_524(context, config, &ticket, reply, from, addr);
free_Ticket(&ticket);
return ret;
}
static krb5_error_code
kdc_krb4(krb5_context context,
krb5_kdc_configuration *config,
krb5_data *req_buffer,
krb5_data *reply,
const char *from,
struct sockaddr *addr,
int datagram_reply,
int *claim)
{
if (_kdc_maybe_version4(req_buffer->data, req_buffer->length) == 0)
return -1;
*claim = 1;
return _kdc_do_version4(context, config,
req_buffer->data, req_buffer->length,
reply, from,
(struct sockaddr_in*)addr);
}
static krb5_error_code
kdc_kaserver(krb5_context context,
krb5_kdc_configuration *config,
krb5_data *req_buffer,
krb5_data *reply,
const char *from,
struct sockaddr *addr,
int datagram_reply,
int *claim)
{
if (config->enable_kaserver == 0)
return -1;
*claim = 1;
return _kdc_do_kaserver(context, config,
req_buffer->data, req_buffer->length,
reply, from,
(struct sockaddr_in*)addr);
}
#endif /* KRB4 */
static struct krb5_kdc_service services[] = {
{ KS_KRB5, kdc_as_req },
{ KS_KRB5, kdc_tgs_req },
#ifdef DIGEST
{ 0, kdc_digest },
#endif
#ifdef KX509
{ 0, kdc_kx509 },
#endif
#ifdef KRB4
{ 0, kdc_524 },
{ KS_NO_LENGTH, kdc_krb4 },
{ 0, kdc_kaserver },
#endif
{ 0, NULL }
};
/*
* handle the request in `buf, len', from `addr' (or `from' as a string),
* sending a reply in `reply'.
@ -65,50 +266,25 @@ krb5_kdc_process_request(krb5_context context,
struct sockaddr *addr,
int datagram_reply)
{
KDC_REQ req;
Ticket ticket;
DigestREQ digestreq;
Kx509Request kx509req;
krb5_error_code ret;
size_t i;
unsigned int i;
krb5_data req_buffer;
int claim = 0;
req_buffer.data = buf;
req_buffer.length = len;
if(decode_AS_REQ(buf, len, &req, &i) == 0){
krb5_data req_buffer;
req_buffer.data = buf;
req_buffer.length = len;
ret = _kdc_as_rep(context, config, &req, &req_buffer,
reply, from, addr, datagram_reply);
free_AS_REQ(&req);
return ret;
}else if(decode_TGS_REQ(buf, len, &req, &i) == 0){
ret = _kdc_tgs_rep(context, config, &req, reply, from, addr, datagram_reply);
free_TGS_REQ(&req);
return ret;
}else if(decode_Ticket(buf, len, &ticket, &i) == 0){
ret = _kdc_do_524(context, config, &ticket, reply, from, addr);
free_Ticket(&ticket);
return ret;
}else if(decode_DigestREQ(buf, len, &digestreq, &i) == 0){
ret = _kdc_do_digest(context, config, &digestreq, reply, from, addr);
free_DigestREQ(&digestreq);
return ret;
} else if (_kdc_try_kx509_request(buf, len, &kx509req, &i) == 0) {
ret = _kdc_do_kx509(context, config, &kx509req, reply, from, addr);
free_Kx509Request(&kx509req);
return ret;
} else if(_kdc_maybe_version4(buf, len)){
*prependlength = FALSE; /* elbitapmoc sdrawkcab XXX */
ret = _kdc_do_version4(context, config, buf, len, reply, from,
(struct sockaddr_in*)addr);
return ret;
} else if (config->enable_kaserver) {
ret = _kdc_do_kaserver(context, config, buf, len, reply, from,
(struct sockaddr_in*)addr);
return ret;
for (i = 0; services[i].process != NULL; i++) {
ret = (*services[i].process)(context, config, &req_buffer,
reply, from, addr, datagram_reply,
&claim);
if (claim) {
if (services[i].flags & KS_NO_LENGTH)
*prependlength = 0;
return ret;
}
}
return -1;
}
@ -129,25 +305,24 @@ krb5_kdc_process_krb5_request(krb5_context context,
struct sockaddr *addr,
int datagram_reply)
{
KDC_REQ req;
krb5_error_code ret;
size_t i;
unsigned int i;
krb5_data req_buffer;
int claim = 0;
req_buffer.data = buf;
req_buffer.length = len;
if(decode_AS_REQ(buf, len, &req, &i) == 0){
krb5_data req_buffer;
req_buffer.data = buf;
req_buffer.length = len;
ret = _kdc_as_rep(context, config, &req, &req_buffer,
reply, from, addr, datagram_reply);
free_AS_REQ(&req);
return ret;
}else if(decode_TGS_REQ(buf, len, &req, &i) == 0){
ret = _kdc_tgs_rep(context, config, &req, reply, from, addr, datagram_reply);
free_TGS_REQ(&req);
return ret;
for (i = 0; services[i].process != NULL; i++) {
if ((services[i].flags & KS_KRB5) == 0)
continue;
ret = (*services[i].process)(context, config, &req_buffer,
reply, from, addr, datagram_reply,
&claim);
if (claim)
return ret;
}
return -1;
}

View File

@ -153,9 +153,9 @@ main (int argc, char **argv)
if (ret)
krb5_err (context, 1, ret, "krb5_cc_resolve");
} else {
ret = krb5_cc_gen_new(context, &krb5_mcc_ops, &id);
ret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, &id);
if (ret)
krb5_err (context, 1, ret, "krb5_cc_gen_new");
krb5_err (context, 1, ret, "krb5_cc_new_unique");
}
if (cred_cache_str == NULL) {

View File

@ -32,11 +32,19 @@
*/
#include "kuser_locl.h"
RCSID("$Id$");
#ifndef HEIMDAL_SMALLER
#include "krb5-v4compat.h"
#endif
struct krb5_dh_moduli;
struct AlgorithmIdentifier;
struct _krb5_krb_auth_data;
#include <krb5-private.h>
#ifndef NO_NTLM
#include "heimntlm.h"
#endif
int forwardable_flag = -1;
int proxiable_flag = -1;
@ -54,6 +62,7 @@ char *renew_life = NULL;
char *server_str = NULL;
char *cred_cache = NULL;
char *start_str = NULL;
static int switch_cache_flags = 1;
struct getarg_strings etype_str;
int use_keytab = 0;
char *keytab_str = NULL;
@ -66,13 +75,17 @@ static char *krb4_cc_name;
int fcache_version;
char *password_file = NULL;
char *pk_user_id = NULL;
int pk_enterprise_flag = 0;
char *pk_x509_anchors = NULL;
int pk_use_enckey = 0;
static int canonicalize_flag = 0;
static int enterprise_flag = 0;
static int ok_as_delegate_flag = 0;
static int use_referrals_flag = 0;
static int windows_flag = 0;
#ifndef NO_NTLM
static char *ntlm_domain;
#endif
static struct getargs args[] = {
@ -154,7 +167,13 @@ static struct getargs args[] = {
{ "canonicalize",0, arg_flag, &canonicalize_flag,
NP_("canonicalize client principal", "") },
{ "enterprise",0, arg_flag, &enterprise_flag,
NP_("parse principal as a KRB5-NT-ENTERPRISE name", "") },
#ifdef PKINIT
{ "pk-enterprise", 0, arg_flag, &pk_enterprise_flag,
NP_("use enterprise name from certificate", "") },
{ "pk-user", 'C', arg_string, &pk_user_id,
NP_("principal's public/private/certificate identifier", ""), "id" },
@ -164,8 +183,13 @@ static struct getargs args[] = {
{ "pk-use-enckey", 0, arg_flag, &pk_use_enckey,
NP_("Use RSA encrypted reply (instead of DH)", "") },
#endif
#ifndef NO_NTLM
{ "ntlm-domain", 0, arg_string, &ntlm_domain,
NP_("NTLM domain", ""), "domain" },
#endif
{ "change-default", 0, arg_negative_flag, &switch_cache_flags,
NP_("switch the default cache to the new credentials cache", "") },
{ "ok-as-delegate", 0, arg_flag, &ok_as_delegate_flag,
NP_("honor ok-as-delegate on tickets", "") },
@ -198,13 +222,13 @@ get_server(krb5_context context,
const char *server,
krb5_principal *princ)
{
krb5_realm *client_realm;
krb5_const_realm realm;
if(server)
return krb5_parse_name(context, server, princ);
client_realm = krb5_princ_realm (context, client);
return krb5_make_principal(context, princ, *client_realm,
KRB5_TGS_NAME, *client_realm, NULL);
realm = krb5_principal_get_realm(context, client);
return krb5_make_principal(context, princ, realm,
KRB5_TGS_NAME, realm, NULL);
}
#ifndef HEIMDAL_SMALLER
@ -301,7 +325,7 @@ renew_validate(krb5_context context,
else if (out)
flags.b.proxiable = out->flags.b.proxiable;
if (anonymous_flag != -1)
if (anonymous_flag)
flags.b.request_anonymous = anonymous_flag;
if(life)
in.times.endtime = time(NULL) + life;
@ -337,8 +361,10 @@ renew_validate(krb5_context context,
if(get_v4_tgt)
do_524init(context, cache, out, NULL);
#endif
#ifndef NO_AFS
if(do_afslog && k_hasafs())
krb5_afslog(context, cache, NULL, NULL);
#endif
}
krb5_free_creds (context, out);
@ -351,6 +377,8 @@ out:
return ret;
}
#ifndef NO_NTLM
static krb5_error_code
store_ntlmkey(krb5_context context, krb5_ccache id,
const char *domain, struct ntlm_buf *buf)
@ -372,6 +400,7 @@ store_ntlmkey(krb5_context context, krb5_ccache id,
free(name);
return ret;
}
#endif
static krb5_error_code
get_new_tickets(krb5_context context,
@ -388,10 +417,11 @@ get_new_tickets(krb5_context context,
krb5_deltat renew = 0;
char *renewstr = NULL;
krb5_enctype *enctype = NULL;
struct ntlm_buf ntlmkey;
krb5_ccache tempccache;
#ifndef NO_NTLM
struct ntlm_buf ntlmkey;
memset(&ntlmkey, 0, sizeof(ntlmkey));
#endif
passwd[0] = '\0';
if (password_file) {
@ -428,21 +458,24 @@ get_new_tickets(krb5_context context,
krb5_get_init_creds_opt_set_forwardable (opt, forwardable_flag);
if(proxiable_flag != -1)
krb5_get_init_creds_opt_set_proxiable (opt, proxiable_flag);
if(anonymous_flag != -1)
if(anonymous_flag)
krb5_get_init_creds_opt_set_anonymous (opt, anonymous_flag);
if (pac_flag != -1)
krb5_get_init_creds_opt_set_pac_request(context, opt,
pac_flag ? TRUE : FALSE);
if (canonicalize_flag)
krb5_get_init_creds_opt_set_canonicalize(context, opt, TRUE);
if (pk_user_id) {
if (pk_enterprise_flag && windows_flag)
krb5_get_init_creds_opt_set_win2k(context, opt, TRUE);
if (pk_user_id || anonymous_flag) {
ret = krb5_get_init_creds_opt_set_pkinit(context, opt,
principal,
pk_user_id,
pk_x509_anchors,
NULL,
NULL,
pk_use_enckey ? 2 : 0,
pk_use_enckey ? 2 : 0 |
anonymous_flag ? 4 : 0,
krb5_prompter_posix,
NULL,
passwd);
@ -510,7 +543,7 @@ get_new_tickets(krb5_context context,
server_str,
opt);
krb5_kt_close(context, kt);
} else if (pk_user_id) {
} else if (pk_user_id || anonymous_flag) {
ret = krb5_get_init_creds_password (context,
&cred,
principal,
@ -552,8 +585,10 @@ get_new_tickets(krb5_context context,
opt);
}
krb5_get_init_creds_opt_free(context, opt);
#ifndef NO_NTLM
if (ntlm_domain && passwd[0])
heim_ntlm_nt_key(passwd, &ntlmkey);
#endif
memset(passwd, 0, sizeof(passwd));
switch(ret){
@ -611,8 +646,13 @@ get_new_tickets(krb5_context context,
if (ret)
krb5_err (context, 1, ret, "krb5_cc_move");
if (switch_cache_flags)
krb5_cc_switch(context, ccache);
#ifndef NO_NTLM
if (ntlm_domain && ntlmkey.data)
store_ntlmkey(context, ccache, ntlm_domain, &ntlmkey);
#endif
if (ok_as_delegate_flag || windows_flag || use_referrals_flag) {
unsigned char d = 0;
@ -704,8 +744,10 @@ renew_func(void *ptr)
if(get_v4_tgt || convert_524)
do_524init(ctx->context, ctx->ccache, NULL, server_str);
#endif
#ifndef NO_AFS
if(do_afslog && k_hasafs())
krb5_afslog(ctx->context, ctx->ccache, NULL, NULL);
#endif
expire = ticket_lifetime(ctx->context, ctx->ccache, ctx->principal,
server_str) / 2;
@ -751,17 +793,35 @@ main (int argc, char **argv)
argc -= optidx;
argv += optidx;
if (canonicalize_flag)
if (canonicalize_flag || enterprise_flag)
parseflags |= KRB5_PRINCIPAL_PARSE_ENTERPRISE;
if (argv[0]) {
ret = krb5_parse_name_flags (context, argv[0], parseflags, &principal);
if (pk_enterprise_flag) {
ret = _krb5_pk_enterprise_cert(context, pk_user_id,
argv[0], &principal);
if (ret)
krb5_err (context, 1, ret, "krb5_parse_name");
krb5_err(context, 1, ret, "krb5_pk_enterprise_certs");
} else if (anonymous_flag) {
ret = krb5_make_principal(context, &principal, argv[0],
KRB5_WELLKNOWN_NAME, KRB5_ANON_NAME,
NULL);
if (ret)
krb5_err(context, 1, ret, "krb5_build_principal");
krb5_principal_set_type(context, principal, KRB5_NT_WELLKNOWN);
} else {
ret = krb5_get_default_principal (context, &principal);
if (ret)
krb5_err (context, 1, ret, "krb5_get_default_principal");
if (argv[0]) {
ret = krb5_parse_name_flags (context, argv[0], parseflags,
&principal);
if (ret)
krb5_err (context, 1, ret, "krb5_parse_name");
} else {
ret = krb5_get_default_principal (context, &principal);
if (ret)
krb5_err (context, 1, ret, "krb5_get_default_principal");
}
}
if(fcache_version)
@ -788,7 +848,7 @@ main (int argc, char **argv)
else {
if(argc > 1) {
char s[1024];
ret = krb5_cc_gen_new(context, &krb5_fcc_ops, &ccache);
ret = krb5_cc_new_unique(context, NULL, NULL, &ccache);
if(ret)
krb5_err(context, 1, ret, "creating cred cache");
snprintf(s, sizeof(s), "%s:%s",
@ -818,8 +878,10 @@ main (int argc, char **argv)
if (ret)
krb5_err (context, 1, ret, N_("resolving credentials cache", ""));
#ifndef NO_AFS
if(argc > 1 && k_hasafs ())
k_setpag();
#endif
if (lifetime) {
int tmp = parse_time (lifetime, "s");
@ -863,8 +925,10 @@ main (int argc, char **argv)
if(get_v4_tgt || convert_524)
do_524init(context, ccache, NULL, server_str);
#endif
#ifndef NO_AFS
if(do_afslog && k_hasafs())
krb5_afslog(context, ccache, NULL, NULL);
#endif
if(argc > 1) {
struct renew_ctx ctx;
time_t timeout;
@ -889,8 +953,10 @@ main (int argc, char **argv)
#ifndef HEIMDAL_SMALLER
_krb5_krb_dest_tkt(context, krb4_cc_name);
#endif
#ifndef NO_AFS
if(k_hasafs())
k_unlog();
#endif
} else {
krb5_cc_close (context, ccache);
ret = 0;

View File

@ -36,9 +36,7 @@
#ifndef __KUSER_LOCL_H__
#define __KUSER_LOCL_H__
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
@ -81,7 +79,9 @@
#ifdef HAVE_SYS_IOCCOM_H
#include <sys/ioccom.h>
#endif
#ifndef NO_AFS
#include <kafs.h>
#endif
#include "crypto-headers.h" /* for UI_UTIL_read_pw_string */
#ifdef HAVE_LOCALE_H

View File

@ -22,4 +22,6 @@ error_code BAD_CHARACTER, "ASN.1 invalid character in string"
error_code MIN_CONSTRAINT, "ASN.1 too few elements"
error_code MAX_CONSTRAINT, "ASN.1 too many elements"
error_code EXACT_CONSTRAINT, "ASN.1 wrong number of elements"
error_code INDEF_OVERRUN, "ASN.1 BER indefinte encoding overrun"
error_code INDEF_UNDERRUN, "ASN.1 BER indefinte encoding underun"
end

View File

@ -119,24 +119,24 @@ doit(const char *fn)
&sz);
if (ret)
errx(1, "der_put_length_and_tag: %d", ret);
if (fwrite(p + sizeof(p) - sz , sz, 1, fout) != 1)
err(1, "fwrite length/tag failed");
offset += sz;
if (data) {
size_t datalen;
datalen = strlen(data) / 2;
pdata = emalloc(sz);
if (hex_decode(data, pdata, datalen) != datalen)
errx(1, "failed to decode data");
if (fwrite(pdata, datalen, 1, fout) != 1)
err(1, "fwrite data failed");
offset += datalen;
free(pdata);
}
}

View File

@ -7,7 +7,7 @@ CANTHANDLE DEFINITIONS ::= BEGIN
-- Code the tag [2] but it should be primitive since KAKA3 is
-- Workaround: use the INTEGER type directly
Kaka2 ::= SEQUENCE {
Kaka2 ::= SEQUENCE {
kaka2-1 [0] INTEGER
}

View File

@ -18,8 +18,8 @@ id-pkcs7-digestedData OBJECT IDENTIFIER ::= { id-pkcs7 5 }
id-pkcs7-encryptedData OBJECT IDENTIFIER ::= { id-pkcs7 6 }
CMSVersion ::= INTEGER {
CMSVersion_v0(0),
CMSVersion_v1(1),
CMSVersion_v0(0),
CMSVersion_v1(1),
CMSVersion_v2(2),
CMSVersion_v3(3),
CMSVersion_v4(4)
@ -34,7 +34,7 @@ MessageDigest ::= OCTET STRING
ContentInfo ::= SEQUENCE {
contentType ContentType,
content [0] EXPLICIT heim_any OPTIONAL -- DEFINED BY contentType
content [0] EXPLICIT heim_any OPTIONAL -- DEFINED BY contentType
}
EncapsulatedContentInfo ::= SEQUENCE {
@ -53,7 +53,7 @@ IssuerAndSerialNumber ::= SEQUENCE {
serialNumber CertificateSerialNumber
}
-- RecipientIdentifier is same as SignerIdentifier,
-- RecipientIdentifier is same as SignerIdentifier,
-- lets glue them togheter and save some bytes and share code for them
CMSIdentifier ::= CHOICE {
@ -67,7 +67,7 @@ RecipientIdentifier ::= CMSIdentifier
--- CMSAttributes are the combined UnsignedAttributes and SignedAttributes
--- to store space and share code
CMSAttributes ::= SET OF Attribute -- SIZE (1..MAX)
CMSAttributes ::= SET OF Attribute -- SIZE (1..MAX)
SignatureValue ::= OCTET STRING
@ -79,7 +79,7 @@ SignerInfo ::= SEQUENCE {
SET OF Attribute OPTIONAL,
signatureAlgorithm SignatureAlgorithmIdentifier,
signature SignatureValue,
unsignedAttrs [1] IMPLICIT -- CMSAttributes --
unsignedAttrs [1] IMPLICIT -- CMSAttributes --
SET OF Attribute OPTIONAL
}

View File

@ -0,0 +1 @@
--decode-dce-ber

View File

@ -52,7 +52,7 @@ typedef enum {PRIM = 0, CONS = 1} Der_type;
enum {
UT_EndOfContent = 0,
UT_Boolean = 1,
UT_Integer = 2,
UT_Integer = 2,
UT_BitString = 3,
UT_OctetString = 4,
UT_Null = 5,

View File

@ -33,10 +33,6 @@
#include "der_locl.h"
RCSID("$Id$");
#include <version.h>
/*
* All decoding functions take a pointer `p' to first position in
* which to read, from the left, `len' which means the maximum number
@ -251,6 +247,75 @@ der_get_octet_string (const unsigned char *p, size_t len,
return 0;
}
int
der_get_octet_string_ber (const unsigned char *p, size_t len,
heim_octet_string *data, size_t *size)
{
int e;
Der_type type;
Der_class class;
unsigned int tag, depth = 0;
size_t l, datalen, oldlen = len;
data->length = 0;
data->data = NULL;
while (len) {
e = der_get_tag (p, len, &class, &type, &tag, &l);
if (e) goto out;
if (class != ASN1_C_UNIV) {
e = ASN1_BAD_ID;
goto out;
}
if (type == PRIM && tag == UT_EndOfContent) {
if (depth == 0)
break;
depth--;
}
if (tag != UT_OctetString) {
e = ASN1_BAD_ID;
goto out;
}
p += l;
len -= l;
e = der_get_length (p, len, &datalen, &l);
if (e) goto out;
p += l;
len -= l;
if (datalen > len)
return ASN1_OVERRUN;
if (type == PRIM) {
void *ptr;
ptr = realloc(data->data, data->length + datalen);
if (ptr == NULL) {
e = ENOMEM;
goto out;
}
data->data = ptr;
memcpy(((unsigned char *)data->data) + data->length, p, datalen);
data->length += datalen;
} else
depth++;
p += datalen;
len -= datalen;
}
if (depth != 0)
return ASN1_INDEF_OVERRUN;
if(size) *size = oldlen - len;
return 0;
out:
free(data->data);
data->data = NULL;
data->length = 0;
return e;
}
int
der_get_heim_integer (const unsigned char *p, size_t len,
heim_integer *data, size_t *size)
@ -397,7 +462,7 @@ der_get_oid (const unsigned char *p, size_t len,
++p;
for (n = 2; len > 0; ++n) {
unsigned u = 0, u1;
do {
--len;
u1 = u * 128 + (*p++ % 128);
@ -456,16 +521,29 @@ int
der_match_tag (const unsigned char *p, size_t len,
Der_class class, Der_type type,
unsigned int tag, size_t *size)
{
Der_type thistype;
int e;
e = der_match_tag2(p, len, class, &thistype, tag, size);
if (e) return e;
if (thistype != type) return ASN1_BAD_ID;
return 0;
}
int
der_match_tag2 (const unsigned char *p, size_t len,
Der_class class, Der_type *type,
unsigned int tag, size_t *size)
{
size_t l;
Der_class thisclass;
Der_type thistype;
unsigned int thistag;
int e;
e = der_get_tag (p, len, &thisclass, &thistype, &thistag, &l);
e = der_get_tag (p, len, &thisclass, type, &thistag, &l);
if (e) return e;
if (class != thisclass || type != thistype)
if (class != thisclass)
return ASN1_BAD_ID;
if(tag > thistag)
return ASN1_MISPLACED_FIELD;
@ -477,26 +555,25 @@ der_match_tag (const unsigned char *p, size_t len,
int
der_match_tag_and_length (const unsigned char *p, size_t len,
Der_class class, Der_type type, unsigned int tag,
Der_class class, Der_type *type, unsigned int tag,
size_t *length_ret, size_t *size)
{
size_t l, ret = 0;
int e;
e = der_match_tag (p, len, class, type, tag, &l);
e = der_match_tag2 (p, len, class, type, tag, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
e = der_get_length (p, len, length_ret, &l);
if (e) return e;
p += l;
len -= l;
ret += l;
if(size) *size = ret;
if(size) *size = ret + l;
return 0;
}
/*
* Old versions of DCE was based on a very early beta of the MIT code,
* which used MAVROS for ASN.1 encoding. MAVROS had the interesting
@ -539,8 +616,11 @@ der_get_bit_string (const unsigned char *p, size_t len,
data->data = malloc(len - 1);
if (data->data == NULL && (len - 1) != 0)
return ENOMEM;
memcpy (data->data, p + 1, len - 1);
data->length -= p[0];
/* copy data is there is data to copy */
if (len - 1 != 0) {
memcpy (data->data, p + 1, len - 1);
data->length -= p[0];
}
if(size) *size = len;
return 0;
}

View File

@ -36,9 +36,9 @@
#ifndef __DER_LOCL_H__
#define __DER_LOCL_H__
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

View File

@ -384,7 +384,7 @@ der_put_tag (unsigned char *p, size_t len, Der_class class, Der_type type,
} else {
size_t ret = 0;
unsigned int continuation = 0;
do {
if (len < 1)
return ASN1_OVERFLOW;

View File

@ -139,7 +139,7 @@ DigestREP ::= [APPLICATION 129] SEQUENCE {
-- qop == auth
-- A2 = Method ":" digest-uri-value
-- qop == auth-int
-- A2 = Method ":" digest-uri-value ":" H(entity-body)
-- A2 = Method ":" digest-uri-value ":" H(entity-body)
-- request-digest = HEX(KD(HEX(H(A1)),
-- unq(nonce-value) ":" nc-value ":" unq(cnonce-value) ":" unq(qop-value) ":" HEX(H(A2))))

View File

@ -67,15 +67,21 @@ decode_heim_any(const unsigned char *p, size_t len,
return ASN1_OVERFLOW;
e = der_get_length(p + l, len - l, &length, &len_len);
if (e) return e;
if (length + len_len + l > len)
return ASN1_OVERFLOW;
if (length == ASN1_INDEFINITE) {
if (len < len_len + l)
return ASN1_OVERFLOW;
length = len - (len_len + l);
} else {
if (len < length + len_len + l)
return ASN1_OVERFLOW;
}
data->data = malloc(length + len_len + l);
if (data->data == NULL)
return ENOMEM;
data->length = length + len_len + l;
memcpy(data->data, p, length + len_len + l);
if (size)
*size = length + len_len + l;

View File

@ -83,12 +83,19 @@ init_generate (const char *filename, const char *base)
if (headerbase == NULL)
errx(1, "strdup");
}
/* public header file */
asprintf(&header, "%s.h", headerbase);
if (header == NULL)
errx(1, "malloc");
headerfile = fopen (header, "w");
asprintf(&fn, "%s.hx", headerbase);
if (fn == NULL)
errx(1, "malloc");
headerfile = fopen (fn, "w");
if (headerfile == NULL)
err (1, "open %s", header);
err (1, "open %s", fn);
free(fn);
fprintf (headerfile,
"/* Generated from %s */\n"
"/* Do not edit */\n\n",
@ -229,7 +236,7 @@ gen_compare_defval(const char *var, struct value *val)
}
}
static void
void
generate_header_of_codefile(const char *name)
{
char *filename;
@ -267,7 +274,7 @@ generate_header_of_codefile(const char *name)
}
static void
void
close_codefile(void)
{
if (codefile == NULL)
@ -296,7 +303,8 @@ generate_constant (const Symbol *s)
struct objid *o, **list;
unsigned int i, len;
generate_header_of_codefile(s->gen_name);
if (!one_code_file)
generate_header_of_codefile(s->gen_name);
len = 0;
for (o = s->value->u.objectidentifiervalue; o != NULL; o = o->next)
@ -320,8 +328,12 @@ generate_constant (const Symbol *s)
}
fprintf (headerfile, "} */\n");
fprintf (headerfile, "const heim_oid *oid_%s(void);\n\n",
fprintf (headerfile, "const heim_oid *oid_%s(void);\n",
s->gen_name);
fprintf (headerfile,
"extern const heim_oid asn1_oid_%s;\n\n",
s->gen_name);
fprintf (codefile, "static unsigned oid_%s_variable_num[%d] = {",
s->gen_name, len);
@ -330,17 +342,20 @@ generate_constant (const Symbol *s)
}
fprintf(codefile, "};\n");
fprintf (codefile, "static const heim_oid oid_%s_variable = "
fprintf (codefile, "const heim_oid asn1_oid_%s = "
"{ %d, oid_%s_variable_num };\n\n",
s->gen_name, len, s->gen_name);
fprintf (codefile, "const heim_oid *oid_%s(void)\n"
"{\n"
"return &oid_%s_variable;\n"
"return &asn1_oid_%s;\n"
"}\n\n",
s->gen_name, s->gen_name);
close_codefile();
free(list);
if (!one_code_file)
close_codefile();
break;
}
@ -587,7 +602,7 @@ define_type (int level, const char *name, Type *t, int typedefp, int preservep)
fprintf (headerfile, "struct %s {\n", typedefp ? name : "");
ASN1_TAILQ_FOREACH(m, t->members, members) {
char *n;
asprintf (&n, "%s:1", m->gen_name);
if (n == NULL)
errx(1, "malloc");
@ -787,7 +802,8 @@ generate_type_header (const Symbol *s)
void
generate_type (const Symbol *s)
{
generate_header_of_codefile(s->gen_name);
if (!one_code_file)
generate_header_of_codefile(s->gen_name);
generate_type_header (s);
generate_type_encode (s);
@ -798,5 +814,9 @@ generate_type (const Symbol *s)
generate_type_seq (s);
generate_glue (s->type, s->gen_name);
fprintf(headerfile, "\n\n");
close_codefile();
if (!one_code_file) {
fprintf(codefile, "\n\n");
close_codefile();
}
}

View File

@ -149,7 +149,7 @@ copy_type (const char *from, const char *to, const Type *t, int preserve)
to, have_ellipsis->gen_name);
used_fail++;
}
fprintf(codefile, "}\n");
fprintf(codefile, "}\n");
}
break;
}

View File

@ -230,7 +230,7 @@ range_check(const char *name,
static int
decode_type (const char *name, const Type *t, int optional,
const char *forwstr, const char *tmpstr)
const char *forwstr, const char *tmpstr, const char *dertype)
{
switch (t->type) {
case TType: {
@ -289,7 +289,17 @@ decode_type (const char *name, const Type *t, int optional,
decode_primitive ("enumerated", name, forwstr);
break;
case TOctetString:
if (dertype) {
fprintf(codefile,
"if (%s == CONS) {\n",
dertype);
decode_primitive("octet_string_ber", name, forwstr);
fprintf(codefile,
"} else {\n");
}
decode_primitive ("octet_string", name, forwstr);
if (dertype)
fprintf(codefile, "}\n");
if (t->range)
range_check(name, "length", forwstr, t->range);
break;
@ -340,10 +350,10 @@ decode_type (const char *name, const Type *t, int optional,
name, m->gen_name);
if (s == NULL)
errx(1, "malloc");
decode_type (s, m->type, m->optional, forwstr, m->gen_name);
decode_type (s, m->type, m->optional, forwstr, m->gen_name, NULL);
free (s);
}
break;
}
case TSet: {
@ -382,7 +392,7 @@ decode_type (const char *name, const Type *t, int optional,
"%s = calloc(1, sizeof(*%s));\n"
"if (%s == NULL) { e = ENOMEM; %s; }\n",
s, s, s, forwstr);
decode_type (s, m->type, 0, forwstr, m->gen_name);
decode_type (s, m->type, 0, forwstr, m->gen_name, NULL);
free (s);
fprintf(codefile, "members |= (1 << %d);\n", memno);
@ -458,7 +468,7 @@ decode_type (const char *name, const Type *t, int optional,
asprintf (&sname, "%s_s_of", tmpstr);
if (sname == NULL)
errx(1, "malloc");
decode_type (n, t->subtype, 0, forwstr, sname);
decode_type (n, t->subtype, 0, forwstr, sname, NULL);
fprintf (codefile,
"(%s)->len++;\n"
"len = %s_origlen - ret;\n"
@ -480,21 +490,37 @@ decode_type (const char *name, const Type *t, int optional,
decode_primitive ("general_string", name, forwstr);
break;
case TTag:{
char *tname;
char *tname, *typestring;
char *ide = NULL;
asprintf(&typestring, "%s_type", tmpstr);
fprintf(codefile,
"{\n"
"size_t %s_datalen, %s_oldlen;\n",
tmpstr, tmpstr);
if(dce_fix)
"size_t %s_datalen, %s_oldlen;\n"
"Der_type %s;\n",
tmpstr, tmpstr, typestring);
if(support_ber)
fprintf(codefile,
"int dce_fix;\n");
fprintf(codefile, "e = der_match_tag_and_length(p, len, %s, %s, %s, "
"int is_indefinite;\n");
fprintf(codefile, "e = der_match_tag_and_length(p, len, %s, &%s, %s, "
"&%s_datalen, &l);\n",
classname(t->tag.tagclass),
is_primitive_type(t->subtype->type) ? "PRIM" : "CONS",
typestring,
valuename(t->tag.tagclass, t->tag.tagvalue),
tmpstr);
/* XXX hardcode for now */
if (support_ber && t->subtype->type == TOctetString) {
ide = typestring;
} else {
fprintf(codefile,
"if (e == 0 && %s != %s) { e = ASN1_BAD_ID; }\n",
typestring,
is_primitive_type(t->subtype->type) ? "PRIM" : "CONS");
}
if(optional) {
fprintf(codefile,
"if(e) {\n"
@ -510,11 +536,12 @@ decode_type (const char *name, const Type *t, int optional,
"p += l; len -= l; ret += l;\n"
"%s_oldlen = len;\n",
tmpstr);
if(dce_fix)
if(support_ber)
fprintf (codefile,
"if((dce_fix = _heim_fix_dce(%s_datalen, &len)) < 0)\n"
"{ e = ASN1_BAD_FORMAT; %s; }\n",
tmpstr, forwstr);
"if((is_indefinite = _heim_fix_dce(%s_datalen, &len)) < 0)\n"
"{ e = ASN1_BAD_FORMAT; %s; }\n"
"if (is_indefinite) { if (len < 2) { e = ASN1_OVERRUN; %s; } len -= 2; }",
tmpstr, forwstr, forwstr);
else
fprintf(codefile,
"if (%s_datalen > len) { e = ASN1_OVERRUN; %s; }\n"
@ -522,15 +549,22 @@ decode_type (const char *name, const Type *t, int optional,
asprintf (&tname, "%s_Tag", tmpstr);
if (tname == NULL)
errx(1, "malloc");
decode_type (name, t->subtype, 0, forwstr, tname);
if(dce_fix)
decode_type (name, t->subtype, 0, forwstr, tname, ide);
if(support_ber)
fprintf(codefile,
"if(dce_fix){\n"
"e = der_match_tag_and_length (p, len, "
"(Der_class)0,(Der_type)0, UT_EndOfContent, "
"if(is_indefinite){\n"
"len += 2;\n"
"e = der_match_tag_and_length(p, len, "
"(Der_class)0, &%s, UT_EndOfContent, "
"&%s_datalen, &l);\n"
"if(e) %s;\np += l; len -= l; ret += l;\n"
"} else \n", tmpstr, forwstr);
"if(e) %s;\n"
"p += l; len -= l; ret += l;\n"
"if (%s != (Der_type)0) { e = ASN1_BAD_ID; %s; }\n"
"} else \n",
typestring,
tmpstr,
forwstr,
typestring, forwstr);
fprintf(codefile,
"len = %s_oldlen - %s_datalen;\n",
tmpstr, tmpstr);
@ -540,6 +574,7 @@ decode_type (const char *name, const Type *t, int optional,
fprintf(codefile,
"}\n");
free(tname);
free(typestring);
break;
}
case TChoice: {
@ -555,7 +590,7 @@ decode_type (const char *name, const Type *t, int optional,
Der_class cl;
Der_type ty;
unsigned tag;
if (m->ellipsis) {
have_ellipsis = m;
continue;
@ -573,7 +608,7 @@ decode_type (const char *name, const Type *t, int optional,
name, m->gen_name);
if (s == NULL)
errx(1, "malloc");
decode_type (s, m->type, m->optional, forwstr, m->gen_name);
decode_type (s, m->type, m->optional, forwstr, m->gen_name, NULL);
fprintf(codefile,
"(%s)->element = %s;\n",
name, m->label);
@ -695,7 +730,7 @@ generate_type_decode (const Symbol *s)
fprintf (codefile, "\n");
fprintf (codefile, "memset(data, 0, sizeof(*data));\n"); /* hack to avoid `unused variable' */
decode_type ("data", s->type, 0, "goto fail", "Top");
decode_type ("data", s->type, 0, "goto fail", "Top", NULL);
if (preserve)
fprintf (codefile,
"data->_save.data = calloc(1, ret);\n"

View File

@ -257,7 +257,7 @@ encode_type (const char *name, const Type *t, const char *tmpstr)
if (t->members == NULL)
break;
ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) {
char *s;
@ -388,7 +388,7 @@ encode_type (const char *name, const Type *t, const char *tmpstr)
int c;
asprintf (&tname, "%s_tag", tmpstr);
if (tname == NULL)
errx(1, "malloc");
errx(1, "malloc");
c = encode_type (name, t->subtype, tname);
fprintf (codefile,
"e = der_put_length_and_tag (p, len, ret, %s, %s, %s, &l);\n"

View File

@ -110,7 +110,7 @@ free_type (const char *name, const Type *t, int preserve)
if(t->type == TChoice)
fprintf(codefile, "break;\n");
}
if(t->type == TChoice) {
if (have_ellipsis)
fprintf(codefile,

View File

@ -139,7 +139,7 @@ length_type (const char *name, const Type *t,
ASN1_TAILQ_FOREACH(m, t->members, members) {
char *s;
if (m->ellipsis) {
have_ellipsis = m;
continue;

View File

@ -36,9 +36,8 @@
#ifndef __GEN_LOCL_H__
#define __GEN_LOCL_H__
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
@ -80,9 +79,14 @@ int yyparse(void);
int preserve_type(const char *);
int seq_type(const char *);
void generate_header_of_codefile(const char *);
void close_codefile(void);
extern FILE *headerfile, *codefile, *logfile;
extern int dce_fix;
extern int support_ber;
extern int rfc1510_bitstring;
extern int one_code_file;
extern int error_flag;

View File

@ -13,6 +13,7 @@ NAME-TYPE ::= INTEGER {
KRB5_NT_X500_PRINCIPAL(6), -- PKINIT
KRB5_NT_SMTP_NAME(7), -- Name in form of SMTP email name
KRB5_NT_ENTERPRISE_PRINCIPAL(10), -- Windows 2000 UPN
KRB5_NT_WELLKNOWN(11), -- Wellknown
KRB5_NT_ENT_PRINCIPAL_AND_ID(-130), -- Windows 2000 UPN and SID
KRB5_NT_MS_PRINCIPAL(-128), -- NT 4 style name
KRB5_NT_MS_PRINCIPAL_AND_ID(-129) -- NT style name and SID
@ -64,6 +65,10 @@ PADATA-TYPE ::= INTEGER {
KRB5-PADATA-GET-FROM-TYPED-DATA(22),
KRB5-PADATA-SAM-ETYPE-INFO(23),
KRB5-PADATA-SERVER-REFERRAL(25),
KRB5-PADATA-ALT-PRINC(24), -- (crawdad@fnal.gov)
KRB5-PADATA-SAM-CHALLENGE2(30), -- (kenh@pobox.com)
KRB5-PADATA-SAM-RESPONSE2(31), -- (kenh@pobox.com)
KRB5-PA-EXTRA-TGT(41), -- Reserved extra TGT
KRB5-PADATA-TD-KRB-PRINCIPAL(102), -- PrincipalName
KRB5-PADATA-PK-TD-TRUSTED-CERTIFIERS(104), -- PKINIT
KRB5-PADATA-PK-TD-CERTIFICATE-INDEX(105), -- PKINIT
@ -71,13 +76,30 @@ PADATA-TYPE ::= INTEGER {
KRB5-PADATA-TD-REQ-NONCE(107), -- INTEGER
KRB5-PADATA-TD-REQ-SEQ(108), -- INTEGER
KRB5-PADATA-PA-PAC-REQUEST(128), -- jbrezak@exchange.microsoft.com
KRB5-PADATA-S4U2SELF(129),
KRB5-PADATA-EPAC(130), -- EPAK
KRB5-PADATA-PK-AS-09-BINDING(132), -- client send this to
-- tell KDC that is supports
KRB5-PADATA-FOR-USER(129), -- MS-KILE
KRB5-PADATA-FOR-X509-USER(130), -- MS-KILE
KRB5-PADATA-FOR-CHECK-DUPS(131), -- MS-KILE
KRB5-PADATA-AS-CHECKSUM(132), -- MS-KILE
KRB5-PADATA-PK-AS-09-BINDING(132), -- client send this to
-- tell KDC that is supports
-- the asCheckSum in the
-- PK-AS-REP
KRB5-PADATA-CLIENT-CANONICALIZED(133) --
KRB5-PADATA-CLIENT-CANONICALIZED(133), -- referals
KRB5-PADATA-FX-COOKIE(133), -- krb-wg-preauth-framework
KRB5-PADATA-AUTHENTICATION-SET(134), -- krb-wg-preauth-framework
KRB5-PADATA-AUTH-SET-SELECTED(135), -- krb-wg-preauth-framework
KRB5-PADATA-FX-FAST(136), -- krb-wg-preauth-framework
KRB5-PADATA-FX-ERROR(137), -- krb-wg-preauth-framework
KRB5-PADATA-ENCRYPTED-CHALLENGE(138), -- krb-wg-preauth-framework
KRB5-PADATA-OTP-CHALLENGE(141), -- (gareth.richards@rsa.com)
KRB5-PADATA-OTP-REQUEST(142), -- (gareth.richards@rsa.com)
KBB5-PADATA-OTP-CONFIRM(143), -- (gareth.richards@rsa.com)
KRB5-PADATA-OTP-PIN-CHANGE(144), -- (gareth.richards@rsa.com)
KRB5-PADATA-EPAK-AS-REQ(145),
KRB5-PADATA-EPAK-AS-REP(146),
KRB5-PADATA-PKINIT-KX(147), -- krb-wg-anon
KRB5-PADATA-PKU2U-NAME(148), -- zhu-pku2u
KRB5-PADATA-SUPPORTED-ETYPES(165) -- MS-KILE
}
AUTHDATA-TYPE ::= INTEGER {
@ -174,6 +196,8 @@ Principal ::= SEQUENCE {
realm[1] Realm
}
Principals ::= SEQUENCE OF Principal
HostAddress ::= SEQUENCE {
addr-type[0] krb5int32,
address[1] OCTET STRING
@ -387,7 +411,7 @@ PA-ENC-TS-ENC ::= SEQUENCE {
-- draft-brezak-win2k-krb-authz-01
PA-PAC-REQUEST ::= SEQUENCE {
include-pac[0] BOOLEAN -- Indicates whether a PAC
include-pac[0] BOOLEAN -- Indicates whether a PAC
-- should be included or not
}
@ -618,21 +642,19 @@ PA-S4U2Self ::= SEQUENCE {
auth[3] GeneralString
}
KRB5SignedPathPrincipals ::= SEQUENCE OF Principal
-- never encoded on the wire, just used to checksum over
KRB5SignedPathData ::= SEQUENCE {
encticket[0] EncTicketPart,
delegated[1] KRB5SignedPathPrincipals OPTIONAL
delegated[1] Principals OPTIONAL
}
KRB5SignedPath ::= SEQUENCE {
-- DERcoded KRB5SignedPathData
-- krbtgt key (etype), KeyUsage = XXX
-- krbtgt key (etype), KeyUsage = XXX
etype[0] ENCTYPE,
cksum[1] Checksum,
-- srvs delegated though
delegated[2] KRB5SignedPathPrincipals OPTIONAL
delegated[2] Principals OPTIONAL
}
PA-ClientCanonicalizedNames ::= SEQUENCE{
@ -666,6 +688,63 @@ PA-ServerReferralData ::= SEQUENCE {
...
}
FastOptions ::= BIT STRING {
reserved(0),
hide-client-names(1),
kdc-follow--referrals(16)
}
KrbFastReq ::= SEQUENCE {
fast-options [0] FastOptions,
padata [1] SEQUENCE OF PA-DATA,
req-body [2] KDC-REQ-BODY,
...
}
KrbFastArmor ::= SEQUENCE {
armor-type [0] krb5int32,
armor-value [1] OCTET STRING,
...
}
KrbFastArmoredReq ::= SEQUENCE {
armor [0] KrbFastArmor OPTIONAL,
req-checksum [1] Checksum,
enc-fast-req [2] EncryptedData -- KrbFastReq --
}
PA-FX-FAST-REQUEST ::= CHOICE {
armored-data [0] KrbFastArmoredReq,
...
}
KrbFastFinished ::= SEQUENCE {
timestamp [0] KerberosTime,
usec [1] krb5int32,
crealm [2] Realm,
cname [3] PrincipalName,
checksum [4] Checksum,
ticket-checksum [5] Checksum,
...
}
KrbFastResponse ::= SEQUENCE {
padata [0] SEQUENCE OF PA-DATA,
rep-key [1] EncryptionKey OPTIONAL,
finished [2] KrbFastFinished OPTIONAL,
...
}
KrbFastArmoredRep ::= SEQUENCE {
enc-fast-rep [0] EncryptedData, -- KrbFastResponse --
...
}
PA-FX-FAST-REPLY ::= CHOICE {
armored-data [0] KrbFastArmoredRep,
...
}
END
-- etags -r '/\([A-Za-z][-A-Za-z0-9]*\).*::=/\1/' k5.asn1

View File

@ -0,0 +1,6 @@
--encode-rfc1510-bit-string
--sequence=Principals
--sequence=AuthorizationData
--sequence=METHOD-DATA
--sequence=ETYPE-INFO
--sequence=ETYPE-INFO2

View File

@ -3,6 +3,17 @@
KX509 DEFINITIONS ::=
BEGIN
KX509-ERROR-CODE ::= INTEGER {
KX509-STATUS-GOOD(0),
KX509-STATUS-CLIENT-BAD(1),
KX509-STATUS-CLIENT-FIX(2),
KX509-STATUS-CLIENT-TEMP(3),
KX509-STATUS-SERVER-BAD(4),
KX509-STATUS-SERVER-TEMP(5),
-- 6 is used internally in the umich client, avoid that
KX509-STATUS-SERVER-KEY(7)
}
Kx509Request ::= SEQUENCE {
authenticator OCTET STRING,
pk-hash OCTET STRING,

View File

@ -46,7 +46,7 @@
#endif
#undef ECHO
#include "symbol.h"
#include "parse.h"
#include "asn1parse.h"
#include "lex.h"
#include "gen_locl.h"
@ -216,7 +216,7 @@ WITH { return kw_WITH; }
char *p = buf;
int f = 0;
int skip_ws = 0;
while((c = input()) != EOF) {
if(isspace(c) && skip_ws) {
if(c == '\n')
@ -224,7 +224,7 @@ WITH { return kw_WITH; }
continue;
}
skip_ws = 0;
if(c == '"') {
if(f) {
*p++ = '"';

View File

@ -62,15 +62,20 @@ seq_type(const char *p)
return 0;
}
int dce_fix;
int support_ber;
int rfc1510_bitstring;
int one_code_file;
char *option_file;
int version_flag;
int help_flag;
struct getargs args[] = {
{ "encode-rfc1510-bit-string", 0, arg_flag, &rfc1510_bitstring },
{ "decode-dce-ber", 0, arg_flag, &dce_fix },
{ "decode-dce-ber", 0, arg_flag, &support_ber },
{ "support-ber", 0, arg_flag, &support_ber },
{ "preserve-binary", 0, arg_strings, &preserve },
{ "sequence", 0, arg_strings, &seq },
{ "one-code-file", 0, arg_flag, &one_code_file },
{ "option-file", 0, arg_string, &option_file },
{ "version", 0, arg_flag, &version_flag },
{ "help", 0, arg_flag, &help_flag }
};
@ -92,6 +97,8 @@ main(int argc, char **argv)
const char *file;
const char *name = NULL;
int optidx = 0;
char **arg = NULL;
size_t len = 0, i;
setprogname(argv[0]);
if(getarg(args, num_args, argc, argv, &optidx))
@ -121,7 +128,58 @@ main(int argc, char **argv)
name = argv[optidx + 1];
}
/*
* Parse extra options file
*/
if (option_file) {
char buf[1024];
FILE *opt;
opt = fopen(option_file, "r");
if (opt == NULL) {
perror("open");
exit(1);
}
arg = calloc(2, sizeof(arg[0]));
arg[0] = option_file;
arg[1] = NULL;
len = 1;
while (fgets(buf, sizeof(buf), opt) != NULL) {
buf[strcspn(buf, "\n\r")] = '\0';
arg = realloc(arg, (len + 2) * sizeof(arg[0]));
if (argv == NULL) {
perror("malloc");
exit(1);
}
arg[len] = strdup(buf);
if (arg[len] == NULL) {
perror("strdup");
exit(1);
}
arg[len + 1] = NULL;
len++;
}
fclose(opt);
optidx = 0;
if(getarg(args, num_args, len, arg, &optidx))
usage(1);
if (len != optidx) {
fprintf(stderr, "extra args");
exit(1);
}
}
init_generate (file, name);
if (one_code_file)
generate_header_of_codefile(name);
initsym ();
ret = yyparse ();
if(ret != 0 || error_flag != 0)
@ -129,5 +187,15 @@ main(int argc, char **argv)
close_generate ();
if (argc != optidx)
fclose(yyin);
if (one_code_file)
close_codefile();
if (arg) {
for (i = 1; i < len; i++)
free(arg[i]);
free(arg);
}
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -50,7 +50,7 @@ PKCS12-AuthenticatedSafe ::= SEQUENCE OF ContentInfo
PKCS12-Attribute ::= SEQUENCE {
attrId OBJECT IDENTIFIER,
attrValues -- SET OF -- heim_any_set
attrValues -- SET OF -- heim_any_set
}
PKCS12-Attributes ::= SET OF PKCS12-Attribute

View File

@ -24,7 +24,7 @@ PKCS8EncryptedData ::= OCTET STRING
PKCS8EncryptedPrivateKeyInfo ::= SEQUENCE {
encryptionAlgorithm AlgorithmIdentifier,
encryptedData PKCS8EncryptedData
encryptedData PKCS8EncryptedData
}
END

View File

@ -27,11 +27,11 @@ id-pkinit-san OBJECT IDENTIFIER ::=
x509-sanan(2) }
id-pkinit-ms-eku OBJECT IDENTIFIER ::=
{ iso(1) org(3) dod(6) internet(1) private(4)
{ iso(1) org(3) dod(6) internet(1) private(4)
enterprise(1) microsoft(311) 20 2 2 }
id-pkinit-ms-san OBJECT IDENTIFIER ::=
{ iso(1) org(3) dod(6) internet(1) private(4)
{ iso(1) org(3) dod(6) internet(1) private(4)
enterprise(1) microsoft(311) 20 2 3 }
MS-UPN-SAN ::= UTF8String
@ -152,19 +152,18 @@ TrustedCA-Win2k ::= CHOICE {
issuerAndSerial [2] IssuerAndSerialNumber
}
PA-PK-AS-REQ-Win2k ::= SEQUENCE {
signed-auth-pack [0] IMPLICIT OCTET STRING,
trusted-certifiers [2] SEQUENCE OF TrustedCA-Win2k OPTIONAL,
kdc-cert [3] IMPLICIT OCTET STRING OPTIONAL,
PA-PK-AS-REQ-Win2k ::= SEQUENCE {
signed-auth-pack [0] IMPLICIT OCTET STRING,
trusted-certifiers [2] SEQUENCE OF TrustedCA-Win2k OPTIONAL,
kdc-cert [3] IMPLICIT OCTET STRING OPTIONAL,
encryption-cert [4] IMPLICIT OCTET STRING OPTIONAL
}
PA-PK-AS-REP-Win2k ::= CHOICE {
dhSignedData [0] IMPLICIT OCTET STRING,
dhSignedData [0] IMPLICIT OCTET STRING,
encKeyPack [1] IMPLICIT OCTET STRING
}
KDCDHKeyInfo-Win2k ::= SEQUENCE {
nonce [0] INTEGER (-2147483648..2147483647),
subjectPublicKey [2] BIT STRING
@ -176,12 +175,18 @@ ReplyKeyPack-Win2k ::= SEQUENCE {
...
}
PkinitSP80056AOtherInfo ::= SEQUENCE {
algorithmID AlgorithmIdentifier,
partyUInfo [0] OCTET STRING,
partyVInfo [1] OCTET STRING,
suppPubInfo [2] OCTET STRING OPTIONAL,
suppPrivInfo [3] OCTET STRING OPTIONAL
PA-PK-AS-REP-BTMM ::= SEQUENCE {
dhSignedData [0] heim_any OPTIONAL,
encKeyPack [1] heim_any OPTIONAL
}
PkinitSP80056AOtherInfo ::= SEQUENCE {
algorithmID AlgorithmIdentifier,
partyUInfo [0] OCTET STRING,
partyVInfo [1] OCTET STRING,
suppPubInfo [2] OCTET STRING OPTIONAL,
suppPrivInfo [3] OCTET STRING OPTIONAL
}
PkinitSuppPubInfo ::= SEQUENCE {

View File

@ -6,7 +6,7 @@ RFC2459 DEFINITIONS ::= BEGIN
IMPORTS heim_any FROM heim;
Version ::= INTEGER {
rfc3280_version_1(0),
rfc3280_version_1(0),
rfc3280_version_2(1),
rfc3280_version_3(2)
}
@ -29,7 +29,7 @@ id-pkcs2-md2 OBJECT IDENTIFIER ::= { id-pkcs-2 2 }
id-pkcs2-md4 OBJECT IDENTIFIER ::= { id-pkcs-2 4 }
id-pkcs2-md5 OBJECT IDENTIFIER ::= { id-pkcs-2 5 }
id-rsa-digestAlgorithm OBJECT IDENTIFIER ::=
id-rsa-digestAlgorithm OBJECT IDENTIFIER ::=
{ iso(1) member-body(2) us(840) rsadsi(113549) 2 }
id-rsa-digest-md2 OBJECT IDENTIFIER ::= { id-rsa-digestAlgorithm 2 }
@ -54,7 +54,7 @@ id-secsig-sha-1 OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
id-nistAlgorithm OBJECT IDENTIFIER ::= {
joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) 4 }
id-nist-aes-algs OBJECT IDENTIFIER ::= { id-nistAlgorithm 1 }
id-aes-128-cbc OBJECT IDENTIFIER ::= { id-nist-aes-algs 2 }
@ -72,9 +72,42 @@ id-dhpublicnumber OBJECT IDENTIFIER ::= {
iso(1) member-body(2) us(840) ansi-x942(10046)
number-type(2) 1 }
-- ECC
id-ecPublicKey OBJECT IDENTIFIER ::= {
iso(1) member-body(2) us(840) ansi-X9-62(10045) keyType(2) 1 }
id-ecDH OBJECT IDENTIFIER ::= {
iso(1) identified-organization(3) certicom(132) schemes(1)
ecdh(12) }
id-ecMQV OBJECT IDENTIFIER ::= {
iso(1) identified-organization(3) certicom(132) schemes(1)
ecmqv(13) }
id-ecdsa-with-SHA256 OBJECT IDENTIFIER ::= {
iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4)
ecdsa-with-SHA2(3) 2 }
id-ecdsa-with-SHA1 OBJECT IDENTIFIER ::= {
iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4) 1 }
-- some EC group ids
id-ec-group-secp256r1 OBJECT IDENTIFIER ::= {
iso(1) member-body(2) us(840) ansi-X9-62(10045) curves(3)
prime(1) 7 }
id-ec-group-secp160r1 OBJECT IDENTIFIER ::= {
iso(1) identified-organization(3) certicom(132) 0 8 }
id-ec-group-secp160r2 OBJECT IDENTIFIER ::= {
iso(1) identified-organization(3) certicom(132) 0 30 }
-- DSA
id-x9-57 OBJECT IDENTIFIER ::= {
iso(1) member-body(2) us(840) ansi-x942(10046)
4 }
iso(1) member-body(2) us(840) ansi-x942(10046) 4 }
id-dsa OBJECT IDENTIFIER ::= { id-x9-57 1 }
id-dsa-with-sha1 OBJECT IDENTIFIER ::= { id-x9-57 3 }
@ -256,8 +289,8 @@ KeyIdentifier ::= OCTET STRING
AuthorityKeyIdentifier ::= SEQUENCE {
keyIdentifier [0] IMPLICIT OCTET STRING OPTIONAL,
authorityCertIssuer [1] IMPLICIT -- GeneralName --
SEQUENCE -- SIZE (1..MAX) -- OF GeneralName OPTIONAL,
authorityCertIssuer [1] IMPLICIT -- GeneralName --
SEQUENCE -- SIZE (1..MAX) -- OF GeneralName OPTIONAL,
authorityCertSerialNumber [2] IMPLICIT INTEGER OPTIONAL
}
@ -269,7 +302,7 @@ id-x509-ce-basicConstraints OBJECT IDENTIFIER ::= { id-x509-ce 19 }
BasicConstraints ::= SEQUENCE {
cA BOOLEAN OPTIONAL -- DEFAULT FALSE --,
pathLenConstraint INTEGER (0..4294967295) OPTIONAL
pathLenConstraint INTEGER (0..4294967295) OPTIONAL
}
id-x509-ce-nameConstraints OBJECT IDENTIFIER ::= { id-x509-ce 30 }
@ -350,6 +383,21 @@ DSAParams ::= SEQUENCE {
g INTEGER
}
-- draft-ietf-pkix-ecc-subpubkeyinfo-11
ECPoint ::= OCTET STRING
ECParameters ::= CHOICE {
namedCurve OBJECT IDENTIFIER
-- implicitCurve NULL
-- specifiedCurve SpecifiedECDomain
}
ECDSA-Sig-Value ::= SEQUENCE {
r INTEGER,
s INTEGER
}
-- really pkcs1
RSAPublicKey ::= SEQUENCE {
@ -382,7 +430,7 @@ DigestInfo ::= SEQUENCE {
-- szOID_CERTIFICATE_TEMPLATE "1.3.6.1.4.1.311.21.7" is Encoded as:
-- TemplateVersion ::= INTEGER (0..4294967295)
-- TemplateVersion ::= INTEGER (0..4294967295)
-- CertificateTemplate ::= SEQUENCE {
-- templateID OBJECT IDENTIFIER,
@ -393,7 +441,7 @@ DigestInfo ::= SEQUENCE {
--
-- CRL
--
--
TBSCRLCertList ::= SEQUENCE {
version Version OPTIONAL, -- if present, MUST be v2
@ -489,16 +537,16 @@ id-uspkicommon-piv-interim OBJECT IDENTIFIER ::= { 2 16 840 1 101 3 6 9 1 }
--- Netscape extentions
id-netscape OBJECT IDENTIFIER ::=
id-netscape OBJECT IDENTIFIER ::=
{ joint-iso-itu-t(2) country(16) us(840) organization(1) netscape(113730) }
id-netscape-cert-comment OBJECT IDENTIFIER ::= { id-netscape 1 13 }
--- MS extentions
id-ms-cert-enroll-domaincontroller OBJECT IDENTIFIER ::=
id-ms-cert-enroll-domaincontroller OBJECT IDENTIFIER ::=
{ 1 3 6 1 4 1 311 20 2 }
id-ms-client-authentication OBJECT IDENTIFIER ::=
id-ms-client-authentication OBJECT IDENTIFIER ::=
{ 1 3 6 1 5 5 7 3 2 }
-- DER:1e:20:00:44:00:6f:00:6d:00:61:00:69:00:6e:00:43:00:6f:00:6e:00:74:00:72:00:6f:00:6c:00:6c:00:65:00:72

View File

@ -20,12 +20,12 @@ TESTSeq ::= SEQUENCE {
TESTChoice1 ::= CHOICE {
i1[1] INTEGER (-2147483648..2147483647),
i2[2] INTEGER (-2147483648..2147483647),
...
...
}
TESTChoice2 ::= CHOICE {
i1[1] INTEGER (-2147483648..2147483647),
...
...
}
TESTInteger ::= INTEGER (-2147483648..2147483647)
@ -35,7 +35,7 @@ TESTInteger3 ::= [5] IMPLICIT TESTInteger2
TESTImplicit ::= SEQUENCE {
ti1[0] IMPLICIT INTEGER (-2147483648..2147483647),
ti2[1] IMPLICIT SEQUENCE {
ti2[1] IMPLICIT SEQUENCE {
foo[127] INTEGER (-2147483648..2147483647)
},
ti3[2] IMPLICIT [5] IMPLICIT [4] IMPLICIT INTEGER (-2147483648..2147483647)
@ -59,19 +59,19 @@ TESTAlloc ::= SEQUENCE {
TESTCONTAINING ::= OCTET STRING ( CONTAINING INTEGER )
TESTENCODEDBY ::= OCTET STRING ( ENCODED BY
TESTENCODEDBY ::= OCTET STRING ( ENCODED BY
{ joint-iso-itu-t(2) asn(1) ber-derived(2) distinguished-encoding(1) }
)
TESTDer OBJECT IDENTIFIER ::= {
TESTDer OBJECT IDENTIFIER ::= {
joint-iso-itu-t(2) asn(1) ber-derived(2) distinguished-encoding(1)
}
TESTCONTAININGENCODEDBY ::= OCTET STRING ( CONTAINING INTEGER ENCODED BY
TESTCONTAININGENCODEDBY ::= OCTET STRING ( CONTAINING INTEGER ENCODED BY
{ joint-iso-itu-t(2) asn(1) ber-derived(2) distinguished-encoding(1) }
)
TESTCONTAININGENCODEDBY2 ::= OCTET STRING (
TESTCONTAININGENCODEDBY2 ::= OCTET STRING (
CONTAINING INTEGER ENCODED BY TESTDer
)

View File

@ -31,10 +31,9 @@
* SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
RCSID("$Id$");
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

View File

@ -35,8 +35,6 @@
#include "compile_et.h"
#include <getarg.h>
RCSID("$Id$");
#include <roken.h>
#include <err.h>
#include "parse.h"

View File

@ -36,9 +36,7 @@
#ifndef __COMPILE_ET_H__
#define __COMPILE_ET_H__
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <err.h>
#include <stdio.h>

View File

@ -31,10 +31,9 @@
* SUCH DAMAGE.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
RCSID("$Id$");
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

View File

@ -44,8 +44,6 @@
#include "parse.h"
#include "lex.h"
RCSID("$Id$");
static unsigned lineno = 1;
static int getstring(void);

View File

@ -35,8 +35,6 @@
#include "compile_et.h"
#include "lex.h"
RCSID("$Id$");
void yyerror (char *s);
static long name2number(const char *str);

View File

@ -53,6 +53,10 @@
#endif
#endif
#ifndef GSSAPI_DEPRECATED
#define GSSAPI_DEPRECATED __attribute__((deprecated))
#endif
/*
* Now define the three implementation-dependent types.
*/
@ -102,6 +106,11 @@ typedef struct gss_buffer_set_desc_struct {
gss_buffer_desc *elements;
} gss_buffer_set_desc, *gss_buffer_set_t;
typedef struct gss_iov_buffer_desc_struct {
OM_uint32 type;
gss_buffer_desc buffer;
} gss_iov_buffer_desc, *gss_iov_buffer_t;
/*
* For now, define a QOP-type as an OM_uint32
*/
@ -178,6 +187,7 @@ typedef OM_uint32 gss_qop_t;
#define GSS_C_NO_CREDENTIAL ((gss_cred_id_t) 0)
#define GSS_C_NO_CHANNEL_BINDINGS ((gss_channel_bindings_t) 0)
#define GSS_C_EMPTY_BUFFER {0, NULL}
#define GSS_C_NO_IOV_BUFFER ((gss_iov_buffer_t)0)
/*
* Some alternate names for a couple of the above
@ -206,6 +216,27 @@ typedef OM_uint32 gss_qop_t;
*/
#define GSS_C_INDEFINITE 0xfffffffful
/*
* Type of gss_wrap_iov()/gss_unwrap_iov().
*/
#define GSS_IOV_BUFFER_TYPE_EMPTY 0
#define GSS_IOV_BUFFER_TYPE_DATA 1
#define GSS_IOV_BUFFER_TYPE_HEADER 2
#define GSS_IOV_BUFFER_TYPE_MECH_PARAMS 3
#define GSS_IOV_BUFFER_TYPE_TRAILER 7
#define GSS_IOV_BUFFER_TYPE_PADDING 9
#define GSS_IOV_BUFFER_TYPE_STREAM 10
#define GSS_IOV_BUFFER_TYPE_SIGN_ONLY 11
#define GSS_IOV_BUFFER_TYPE_FLAG_MASK 0xffff0000
#define GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE 0x00010000
#define GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED 0x00020000
#define GSS_IOV_BUFFER_TYPE(_t) ((_t) & ~GSS_IOV_BUFFER_TYPE_FLAG_MASK)
#define GSS_IOV_BUFFER_FLAGS(_t) ((_t) & GSS_IOV_BUFFER_TYPE_FLAG_MASK)
#ifdef __cplusplus
extern "C" {
#endif
@ -311,12 +342,6 @@ extern GSSAPI_LIB_VARIABLE gss_OID GSS_C_NT_EXPORT_NAME;
extern GSSAPI_LIB_VARIABLE gss_OID GSS_SASL_DIGEST_MD5_MECHANISM;
/*
* NTLM mechanism
*/
extern GSSAPI_LIB_VARIABLE gss_OID GSS_NTLM_MECHANISM;
/* Major status codes */
#define GSS_S_COMPLETE 0
@ -743,6 +768,75 @@ gss_pseudo_random
gss_buffer_t prf_out
);
/*
* AEAD support
*/
OM_uint32 GSSAPI_LIB_FUNCTION
gss_wrap_iov(OM_uint32 * /* minor_status */,
gss_ctx_id_t /* context_handle */,
int /* conf_req_flag */,
gss_qop_t /* qop_req */,
int * /* conf_state */,
gss_iov_buffer_desc * /*iov */,
int /* iov_count */);
OM_uint32 GSSAPI_LIB_FUNCTION
gss_unwrap_iov(OM_uint32 * /* minor_status */,
gss_ctx_id_t /* context_handle */,
int * /* conf_state */,
gss_qop_t * /* qop_state */,
gss_iov_buffer_desc * /* iov */,
int /* iov_count */);
OM_uint32 GSSAPI_LIB_FUNCTION
gss_wrap_iov_length(OM_uint32 * /* minor_status */,
gss_ctx_id_t /* context_handle */,
int /* conf_req_flag */,
gss_qop_t /* qop_req */,
int * /* conf_state */,
gss_iov_buffer_desc * /* iov */,
int /* iov_count */);
OM_uint32 GSSAPI_LIB_FUNCTION
gss_release_iov_buffer(OM_uint32 * /* minor_status */,
gss_iov_buffer_desc * /* iov */,
int /* iov_count */);
OM_uint32
gss_store_cred(OM_uint32 * /* minor_status */,
gss_cred_id_t /* input_cred_handle */,
gss_cred_usage_t /* cred_usage */,
const gss_OID /* desired_mech */,
OM_uint32 /* overwrite_cred */,
OM_uint32 /* default_cred */,
gss_OID_set * /* elements_stored */,
gss_cred_usage_t * /* cred_usage_stored */);
/*
* Query functions
*/
typedef struct {
size_t header; /**< size of header */
size_t trailer; /**< size of trailer */
size_t max_msg_size; /**< maximum message size */
size_t buffers; /**< extra GSS_IOV_BUFFER_TYPE_EMPTY buffer to pass */
size_t blocksize; /**< Specificed optimal size of messages, also
is the maximum padding size
(GSS_IOV_BUFFER_TYPE_PADDING) */
} gss_context_stream_sizes;
extern gss_OID GSSAPI_LIB_VARIABLE GSS_C_ATTR_STREAM_SIZES;
OM_uint32 GSSAPI_LIB_FUNCTION
gss_context_query_attributes(OM_uint32 * /* minor_status */,
gss_OID /* attribute */,
void * /*data*/,
size_t /* len */);
/*
* The following routines are obsolete variants of gss_get_mic,
* gss_verify_mic, gss_wrap and gss_unwrap. They should be
@ -754,7 +848,7 @@ gss_pseudo_random
* obsolete versions of these routines and their current forms.
*/
OM_uint32 GSSAPI_LIB_FUNCTION gss_sign
OM_uint32 GSSAPI_LIB_FUNCTION GSSAPI_DEPRECATED gss_sign
(OM_uint32 * /*minor_status*/,
gss_ctx_id_t /*context_handle*/,
int /*qop_req*/,
@ -762,7 +856,7 @@ OM_uint32 GSSAPI_LIB_FUNCTION gss_sign
gss_buffer_t /*message_token*/
);
OM_uint32 GSSAPI_LIB_FUNCTION gss_verify
OM_uint32 GSSAPI_LIB_FUNCTION GSSAPI_DEPRECATED gss_verify
(OM_uint32 * /*minor_status*/,
gss_ctx_id_t /*context_handle*/,
gss_buffer_t /*message_buffer*/,
@ -770,7 +864,7 @@ OM_uint32 GSSAPI_LIB_FUNCTION gss_verify
int * /*qop_state*/
);
OM_uint32 GSSAPI_LIB_FUNCTION gss_seal
OM_uint32 GSSAPI_LIB_FUNCTION GSSAPI_DEPRECATED gss_seal
(OM_uint32 * /*minor_status*/,
gss_ctx_id_t /*context_handle*/,
int /*conf_req_flag*/,
@ -780,7 +874,7 @@ OM_uint32 GSSAPI_LIB_FUNCTION gss_seal
gss_buffer_t /*output_message_buffer*/
);
OM_uint32 GSSAPI_LIB_FUNCTION gss_unseal
OM_uint32 GSSAPI_LIB_FUNCTION GSSAPI_DEPRECATED gss_unseal
(OM_uint32 * /*minor_status*/,
gss_ctx_id_t /*context_handle*/,
gss_buffer_t /*input_message_buffer*/,
@ -809,7 +903,4 @@ gss_decapsulate_token(gss_buffer_t /* input_token */,
}
#endif
#include <gssapi/gssapi_krb5.h>
#include <gssapi/gssapi_spnego.h>
#endif /* GSSAPI_GSSAPI_H_ */

View File

@ -36,7 +36,7 @@
#ifndef GSSAPI_KRB5_H_
#define GSSAPI_KRB5_H_
#include <gssapi/gssapi.h>
#include <gssapi.h>
#ifdef __cplusplus
extern "C" {

View File

@ -307,7 +307,45 @@ typedef OM_uint32 _gss_pseudo_random(
gss_buffer_t prf_out
);
#define GMI_VERSION 1
typedef OM_uint32
_gss_wrap_iov_t(OM_uint32 *minor_status,
gss_ctx_id_t context_handle,
int conf_req_flag,
gss_qop_t qop_req,
int * conf_state,
gss_iov_buffer_desc *iov,
int iov_count);
typedef OM_uint32
_gss_unwrap_iov_t(OM_uint32 *minor_status,
gss_ctx_id_t context_handle,
int *conf_state,
gss_qop_t *qop_state,
gss_iov_buffer_desc *iov,
int iov_count);
typedef OM_uint32
_gss_wrap_iov_length_t(OM_uint32 * minor_status,
gss_ctx_id_t context_handle,
int conf_req_flag,
gss_qop_t qop_req,
int *conf_state,
gss_iov_buffer_desc *iov,
int iov_count);
typedef OM_uint32
_gss_store_cred_t(OM_uint32 *minor_status,
gss_cred_id_t input_cred_handle,
gss_cred_usage_t cred_usage,
const gss_OID desired_mech,
OM_uint32 overwrite_cred,
OM_uint32 default_cred,
gss_OID_set *elements_stored,
gss_cred_usage_t *cred_usage_stored);
#define GMI_VERSION 2
typedef struct gssapi_mech_interface_desc {
unsigned gm_version;
@ -347,6 +385,10 @@ typedef struct gssapi_mech_interface_desc {
_gss_set_sec_context_option *gm_set_sec_context_option;
_gss_set_cred_option *gm_set_cred_option;
_gss_pseudo_random *gm_pseudo_random;
_gss_wrap_iov_t *gm_wrap_iov;
_gss_unwrap_iov_t *gm_unwrap_iov;
_gss_wrap_iov_length_t *gm_wrap_iov_length;
_gss_store_cred_t *gm_store_cred;
} gssapi_mech_interface_desc, *gssapi_mech_interface;
gssapi_mech_interface

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
#include "krb5/gsskrb5_locl.h"
#include "gsskrb5_locl.h"
RCSID("$Id$");

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
#include "krb5/gsskrb5_locl.h"
#include "gsskrb5_locl.h"
RCSID("$Id$");
@ -74,12 +74,10 @@ _gsskrb5_register_acceptor_identity (const char *identity)
}
void
_gsskrb5i_is_cfx(gsskrb5_ctx ctx, int *is_cfx)
_gsskrb5i_is_cfx(krb5_context context, gsskrb5_ctx ctx, int acceptor)
{
krb5_error_code ret;
krb5_keyblock *key;
int acceptor = (ctx->more_flags & LOCAL) == 0;
*is_cfx = 0;
if (acceptor) {
if (ctx->auth_context->local_subkey)
@ -108,12 +106,16 @@ _gsskrb5i_is_cfx(gsskrb5_ctx ctx, int *is_cfx)
case ETYPE_ARCFOUR_HMAC_MD5_56:
break;
default :
*is_cfx = 1;
ctx->more_flags |= IS_CFX;
if ((acceptor && ctx->auth_context->local_subkey) ||
(!acceptor && ctx->auth_context->remote_subkey))
ctx->more_flags |= ACCEPTOR_SUBKEY;
break;
}
if (ctx->crypto)
krb5_crypto_destroy(context, ctx->crypto);
ret = krb5_crypto_init(context, key, 0, &ctx->crypto);
}
@ -136,7 +138,8 @@ gsskrb5_accept_delegated_token
kret = krb5_cc_default (context, &ccache);
} else {
*delegated_cred_handle = NULL;
kret = krb5_cc_gen_new (context, &krb5_mcc_ops, &ccache);
kret = krb5_cc_new_unique (context, krb5_cc_type_memory,
NULL, &ccache);
}
if (kret) {
ctx->flags &= ~GSS_C_DELEG_FLAG;
@ -210,7 +213,8 @@ gsskrb5_acceptor_ready(OM_uint32 * minor_status,
ctx->auth_context,
&seq_number);
_gsskrb5i_is_cfx(ctx, &is_cfx);
_gsskrb5i_is_cfx(context, ctx, 1);
is_cfx = (ctx->more_flags & IS_CFX);
ret = _gssapi_msg_order_create(minor_status,
&ctx->order,
@ -381,7 +385,7 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status,
server,
in, &out);
krb5_rd_req_in_ctx_free(context, in);
if (kret == KRB5KRB_AP_ERR_SKEW) {
if (kret == KRB5KRB_AP_ERR_SKEW || kret == KRB5KRB_AP_ERR_TKT_NYV) {
/*
* No reply in non-MUTUAL mode, but we don't know that its
* non-MUTUAL mode yet, thats inside the 8003 checksum, so
@ -526,7 +530,8 @@ gsskrb5_acceptor_start(OM_uint32 * minor_status,
krb5_data outbuf;
int use_subkey = 0;
_gsskrb5i_is_cfx(ctx, &is_cfx);
_gsskrb5i_is_cfx(context, ctx, 1);
is_cfx = (ctx->more_flags & IS_CFX);
if (is_cfx || (ap_options & AP_OPTS_USE_SUBKEY)) {
use_subkey = 1;

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
#include "krb5/gsskrb5_locl.h"
#include "gsskrb5_locl.h"
RCSID("$Id$");
@ -187,7 +187,8 @@ static OM_uint32 acquire_initiator_cred
krb5_get_init_creds_opt_free(context, opt);
if (kret)
goto end;
kret = krb5_cc_gen_new(context, &krb5_mcc_ops, &ccache);
kret = krb5_cc_new_unique(context, krb5_cc_type_memory,
NULL, &ccache);
if (kret)
goto end;
kret = krb5_cc_initialize(context, ccache, cred.client);

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
#include "krb5/gsskrb5_locl.h"
#include "gsskrb5_locl.h"
RCSID("$Id$");
@ -168,8 +168,8 @@ OM_uint32 _gsskrb5_add_cred (
}
if (strcmp(type, "MEMORY") == 0) {
ret = krb5_cc_gen_new(context, &krb5_mcc_ops,
&handle->ccache);
ret = krb5_cc_new_unique(context, type,
NULL, &handle->ccache);
if (ret) {
*minor_status = ret;
goto failure;

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
#include "krb5/gsskrb5_locl.h"
#include "gsskrb5_locl.h"
#include <roken.h>

View File

@ -0,0 +1,271 @@
/*
* Copyright (c) 2008 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "gsskrb5_locl.h"
#include <roken.h>
static OM_uint32
iov_allocate(OM_uint32 *minor_status, gss_iov_buffer_desc *iov, int iov_count)
{
unsigned int i;
for (i = 0; i < iov_count; i++) {
if (GSS_IOV_BUFFER_FLAGS(iov[i].type) & GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATE){
void *ptr = malloc(iov[i].buffer.length);
if (ptr == NULL)
abort();
if (iov[i].buffer.value)
memcpy(ptr, iov[i].buffer.value, iov[i].buffer.length);
iov[i].buffer.value = ptr;
iov[i].type |= GSS_IOV_BUFFER_TYPE_FLAG_ALLOCATED;
}
}
return GSS_S_COMPLETE;
}
static OM_uint32
iov_map(OM_uint32 *minor_status,
const gss_iov_buffer_desc *iov,
int iov_count,
krb5_crypto_iov *data)
{
unsigned int i;
for (i = 0; i < iov_count; i++) {
switch(GSS_IOV_BUFFER_TYPE(iov[i].type)) {
case GSS_IOV_BUFFER_TYPE_EMPTY:
data[i].flags = KRB5_CRYPTO_TYPE_EMPTY;
break;
case GSS_IOV_BUFFER_TYPE_DATA:
data[i].flags = KRB5_CRYPTO_TYPE_DATA;
break;
case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
data[i].flags = KRB5_CRYPTO_TYPE_SIGN_ONLY;
break;
case GSS_IOV_BUFFER_TYPE_HEADER:
data[i].flags = KRB5_CRYPTO_TYPE_HEADER;
break;
case GSS_IOV_BUFFER_TYPE_TRAILER:
data[i].flags = KRB5_CRYPTO_TYPE_TRAILER;
break;
case GSS_IOV_BUFFER_TYPE_PADDING:
data[i].flags = KRB5_CRYPTO_TYPE_PADDING;
break;
case GSS_IOV_BUFFER_TYPE_STREAM:
abort();
break;
default:
*minor_status = EINVAL;
return GSS_S_FAILURE;
}
data[i].data.data = iov[i].buffer.value;
data[i].data.length = iov[i].buffer.length;
}
return GSS_S_COMPLETE;
}
OM_uint32 GSSAPI_LIB_FUNCTION
_gk_wrap_iov(OM_uint32 * minor_status,
gss_ctx_id_t context_handle,
int conf_req_flag,
gss_qop_t qop_req,
int * conf_state,
gss_iov_buffer_desc *iov,
int iov_count)
{
gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle;
krb5_context context;
OM_uint32 major_status, junk;
krb5_crypto_iov *data;
krb5_error_code ret;
unsigned usage;
GSSAPI_KRB5_INIT (&context);
major_status = iov_allocate(minor_status, iov, iov_count);
if (major_status != GSS_S_COMPLETE)
return major_status;
data = calloc(iov_count, sizeof(data[0]));
if (data == NULL) {
gss_release_iov_buffer(&junk, iov, iov_count);
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
major_status = iov_map(minor_status, iov, iov_count, data);
if (major_status != GSS_S_COMPLETE) {
gss_release_iov_buffer(&junk, iov, iov_count);
free(data);
return major_status;
}
if (ctx->more_flags & LOCAL) {
usage = KRB5_KU_USAGE_ACCEPTOR_SIGN;
} else {
usage = KRB5_KU_USAGE_INITIATOR_SIGN;
}
ret = krb5_encrypt_iov_ivec(context, ctx->crypto, usage,
data, iov_count, NULL);
free(data);
if (ret) {
gss_release_iov_buffer(&junk, iov, iov_count);
*minor_status = ret;
return GSS_S_FAILURE;
}
*minor_status = 0;
return GSS_S_COMPLETE;
}
OM_uint32 GSSAPI_LIB_FUNCTION
_gk_unwrap_iov(OM_uint32 *minor_status,
gss_ctx_id_t context_handle,
int *conf_state,
gss_qop_t *qop_state,
gss_iov_buffer_desc *iov,
int iov_count)
{
gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle;
krb5_context context;
krb5_error_code ret;
OM_uint32 major_status, junk;
krb5_crypto_iov *data;
unsigned usage;
GSSAPI_KRB5_INIT (&context);
major_status = iov_allocate(minor_status, iov, iov_count);
if (major_status != GSS_S_COMPLETE)
return major_status;
data = calloc(iov_count, sizeof(data[0]));
if (data == NULL) {
gss_release_iov_buffer(&junk, iov, iov_count);
*minor_status = ENOMEM;
return GSS_S_FAILURE;
}
major_status = iov_map(minor_status, iov, iov_count, data);
if (major_status != GSS_S_COMPLETE) {
gss_release_iov_buffer(&junk, iov, iov_count);
free(data);
return major_status;
}
if (ctx->more_flags & LOCAL) {
usage = KRB5_KU_USAGE_INITIATOR_SIGN;
} else {
usage = KRB5_KU_USAGE_ACCEPTOR_SIGN;
}
ret = krb5_decrypt_iov_ivec(context, ctx->crypto, usage,
data, iov_count, NULL);
free(data);
if (ret) {
*minor_status = ret;
gss_release_iov_buffer(&junk, iov, iov_count);
return GSS_S_FAILURE;
}
*minor_status = 0;
return GSS_S_COMPLETE;
}
OM_uint32 GSSAPI_LIB_FUNCTION
_gk_wrap_iov_length(OM_uint32 * minor_status,
gss_ctx_id_t context_handle,
int conf_req_flag,
gss_qop_t qop_req,
int *conf_state,
gss_iov_buffer_desc *iov,
int iov_count)
{
gsskrb5_ctx ctx = (gsskrb5_ctx) context_handle;
krb5_context context;
unsigned int i;
size_t size;
size_t *padding = NULL;
GSSAPI_KRB5_INIT (&context);
*minor_status = 0;
for (size = 0, i = 0; i < iov_count; i++) {
switch(GSS_IOV_BUFFER_TYPE(iov[i].type)) {
case GSS_IOV_BUFFER_TYPE_EMPTY:
break;
case GSS_IOV_BUFFER_TYPE_DATA:
size += iov[i].buffer.length;
break;
case GSS_IOV_BUFFER_TYPE_HEADER:
iov[i].buffer.length =
krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_HEADER);
size += iov[i].buffer.length;
break;
case GSS_IOV_BUFFER_TYPE_TRAILER:
iov[i].buffer.length =
krb5_crypto_length(context, ctx->crypto, KRB5_CRYPTO_TYPE_TRAILER);
size += iov[i].buffer.length;
break;
case GSS_IOV_BUFFER_TYPE_PADDING:
if (padding != NULL) {
*minor_status = 0;
return GSS_S_FAILURE;
}
padding = &iov[i].buffer.length;
break;
case GSS_IOV_BUFFER_TYPE_STREAM:
size += iov[i].buffer.length;
break;
case GSS_IOV_BUFFER_TYPE_SIGN_ONLY:
break;
default:
*minor_status = EINVAL;
return GSS_S_FAILURE;
}
}
if (padding) {
size_t pad = krb5_crypto_length(context, ctx->crypto,
KRB5_CRYPTO_TYPE_PADDING);
if (pad > 1) {
*padding = pad - (size % pad);
if (*padding == pad)
*padding = 0;
} else
*padding = 0;
}
return GSS_S_COMPLETE;
}

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
#include "krb5/gsskrb5_locl.h"
#include "gsskrb5_locl.h"
RCSID("$Id$");

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
#include "krb5/gsskrb5_locl.h"
#include "gsskrb5_locl.h"
RCSID("$Id$");

View File

@ -30,7 +30,7 @@
* SUCH DAMAGE.
*/
#include "krb5/gsskrb5_locl.h"
#include "gsskrb5_locl.h"
RCSID("$Id$");
@ -101,49 +101,47 @@ _gsskrb5cfx_wrap_length_cfx(const gsskrb5_ctx context_handle,
return 0;
}
krb5_error_code
_gsskrb5cfx_max_wrap_length_cfx(krb5_context context,
krb5_crypto crypto,
OM_uint32 _gssapi_wrap_size_cfx(OM_uint32 *minor_status,
const gsskrb5_ctx ctx,
krb5_context context,
int conf_req_flag,
size_t input_length,
OM_uint32 *output_length)
gss_qop_t qop_req,
OM_uint32 req_output_size,
OM_uint32 *max_input_size)
{
krb5_error_code ret;
*output_length = 0;
*max_input_size = 0;
/* 16-byte header is always first */
if (input_length < 16)
if (req_output_size < 16)
return 0;
input_length -= 16;
req_output_size -= 16;
if (conf_req_flag) {
size_t wrapped_size, sz;
wrapped_size = input_length + 1;
wrapped_size = req_output_size + 1;
do {
wrapped_size--;
sz = krb5_get_wrapped_length(context,
crypto, wrapped_size);
} while (wrapped_size && sz > input_length);
if (wrapped_size == 0) {
*output_length = 0;
ctx->crypto, wrapped_size);
} while (wrapped_size && sz > req_output_size);
if (wrapped_size == 0)
return 0;
}
/* inner header */
if (wrapped_size < 16) {
*output_length = 0;
if (wrapped_size < 16)
return 0;
}
wrapped_size -= 16;
*output_length = wrapped_size;
*max_input_size = wrapped_size;
} else {
krb5_cksumtype type;
size_t cksumsize;
ret = krb5_crypto_get_checksum_type(context, crypto, &type);
ret = krb5_crypto_get_checksum_type(context, ctx->crypto, &type);
if (ret)
return ret;
@ -151,48 +149,16 @@ _gsskrb5cfx_max_wrap_length_cfx(krb5_context context,
if (ret)
return ret;
if (input_length < cksumsize)
if (req_output_size < cksumsize)
return 0;
/* Checksum is concatenated with data */
*output_length = input_length - cksumsize;
*max_input_size = req_output_size - cksumsize;
}
return 0;
}
OM_uint32 _gssapi_wrap_size_cfx(OM_uint32 *minor_status,
const gsskrb5_ctx context_handle,
krb5_context context,
int conf_req_flag,
gss_qop_t qop_req,
OM_uint32 req_output_size,
OM_uint32 *max_input_size,
krb5_keyblock *key)
{
krb5_error_code ret;
krb5_crypto crypto;
ret = krb5_crypto_init(context, key, 0, &crypto);
if (ret != 0) {
*minor_status = ret;
return GSS_S_FAILURE;
}
ret = _gsskrb5cfx_max_wrap_length_cfx(context, crypto, conf_req_flag,
req_output_size, max_input_size);
if (ret != 0) {
*minor_status = ret;
krb5_crypto_destroy(context, crypto);
return GSS_S_FAILURE;
}
krb5_crypto_destroy(context, crypto);
return GSS_S_COMPLETE;
}
/*
* Rotate "rrc" bytes to the front or back
*/
@ -238,16 +204,14 @@ rrc_rotate(void *data, size_t len, uint16_t rrc, krb5_boolean unrotate)
}
OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
const gsskrb5_ctx context_handle,
const gsskrb5_ctx ctx,
krb5_context context,
int conf_req_flag,
gss_qop_t qop_req,
const gss_buffer_t input_message_buffer,
int *conf_state,
gss_buffer_t output_message_buffer,
krb5_keyblock *key)
gss_buffer_t output_message_buffer)
{
krb5_crypto crypto;
gss_cfx_wrap_token token;
krb5_error_code ret;
unsigned usage;
@ -257,19 +221,12 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
int32_t seq_number;
u_char *p;
ret = krb5_crypto_init(context, key, 0, &crypto);
if (ret != 0) {
*minor_status = ret;
return GSS_S_FAILURE;
}
ret = _gsskrb5cfx_wrap_length_cfx(context_handle, context,
crypto, conf_req_flag,
ret = _gsskrb5cfx_wrap_length_cfx(ctx, context,
ctx->crypto, conf_req_flag,
input_message_buffer->length,
&wrapped_len, &cksumsize, &padlength);
if (ret != 0) {
*minor_status = ret;
krb5_crypto_destroy(context, crypto);
return GSS_S_FAILURE;
}
@ -280,7 +237,6 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
output_message_buffer->value = malloc(output_message_buffer->length);
if (output_message_buffer->value == NULL) {
*minor_status = ENOMEM;
krb5_crypto_destroy(context, crypto);
return GSS_S_FAILURE;
}
@ -290,9 +246,9 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
token->TOK_ID[1] = 0x04;
token->Flags = 0;
token->Filler = 0xFF;
if ((context_handle->more_flags & LOCAL) == 0)
if ((ctx->more_flags & LOCAL) == 0)
token->Flags |= CFXSentByAcceptor;
if (context_handle->more_flags & ACCEPTOR_SUBKEY)
if (ctx->more_flags & ACCEPTOR_SUBKEY)
token->Flags |= CFXAcceptorSubkey;
if (conf_req_flag) {
/*
@ -329,16 +285,16 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
token->RRC[0] = 0;
token->RRC[1] = 0;
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
krb5_auth_con_getlocalseqnumber(context,
context_handle->auth_context,
ctx->auth_context,
&seq_number);
_gsskrb5_encode_be_om_uint32(0, &token->SND_SEQ[0]);
_gsskrb5_encode_be_om_uint32(seq_number, &token->SND_SEQ[4]);
krb5_auth_con_setlocalseqnumber(context,
context_handle->auth_context,
ctx->auth_context,
++seq_number);
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
/*
* If confidentiality is requested, the token header is
@ -349,7 +305,7 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
* calculated over the plaintext concatenated with the
* token header.
*/
if (context_handle->more_flags & LOCAL) {
if (ctx->more_flags & LOCAL) {
usage = KRB5_KU_USAGE_INITIATOR_SEAL;
} else {
usage = KRB5_KU_USAGE_ACCEPTOR_SEAL;
@ -370,14 +326,13 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
memcpy(p + input_message_buffer->length + padlength,
token, sizeof(*token));
ret = krb5_encrypt(context, crypto,
ret = krb5_encrypt(context, ctx->crypto,
usage, p,
input_message_buffer->length + padlength +
sizeof(*token),
&cipher);
if (ret != 0) {
*minor_status = ret;
krb5_crypto_destroy(context, crypto);
_gsskrb5_release_buffer(minor_status, output_message_buffer);
return GSS_S_FAILURE;
}
@ -389,14 +344,13 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
* this is really ugly, but needed against windows
* for DCERPC, as windows rotates by EC+RRC.
*/
if (IS_DCE_STYLE(context_handle)) {
if (IS_DCE_STYLE(ctx)) {
ret = rrc_rotate(cipher.data, cipher.length, rrc+padlength, FALSE);
} else {
ret = rrc_rotate(cipher.data, cipher.length, rrc, FALSE);
}
if (ret != 0) {
*minor_status = ret;
krb5_crypto_destroy(context, crypto);
_gsskrb5_release_buffer(minor_status, output_message_buffer);
return GSS_S_FAILURE;
}
@ -409,21 +363,19 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
buf = malloc(input_message_buffer->length + sizeof(*token));
if (buf == NULL) {
*minor_status = ENOMEM;
krb5_crypto_destroy(context, crypto);
_gsskrb5_release_buffer(minor_status, output_message_buffer);
return GSS_S_FAILURE;
}
memcpy(buf, input_message_buffer->value, input_message_buffer->length);
memcpy(buf + input_message_buffer->length, token, sizeof(*token));
ret = krb5_create_checksum(context, crypto,
ret = krb5_create_checksum(context, ctx->crypto,
usage, 0, buf,
input_message_buffer->length +
sizeof(*token),
&cksum);
if (ret != 0) {
*minor_status = ret;
krb5_crypto_destroy(context, crypto);
_gsskrb5_release_buffer(minor_status, output_message_buffer);
free(buf);
return GSS_S_FAILURE;
@ -446,7 +398,6 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
input_message_buffer->length + cksum.checksum.length, rrc, FALSE);
if (ret != 0) {
*minor_status = ret;
krb5_crypto_destroy(context, crypto);
_gsskrb5_release_buffer(minor_status, output_message_buffer);
free_Checksum(&cksum);
return GSS_S_FAILURE;
@ -454,8 +405,6 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
free_Checksum(&cksum);
}
krb5_crypto_destroy(context, crypto);
if (conf_state != NULL) {
*conf_state = conf_req_flag;
}
@ -465,15 +414,13 @@ OM_uint32 _gssapi_wrap_cfx(OM_uint32 *minor_status,
}
OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
const gsskrb5_ctx context_handle,
const gsskrb5_ctx ctx,
krb5_context context,
const gss_buffer_t input_message_buffer,
gss_buffer_t output_message_buffer,
int *conf_state,
gss_qop_t *qop_state,
krb5_keyblock *key)
gss_qop_t *qop_state)
{
krb5_crypto crypto;
gss_cfx_wrap_token token;
u_char token_flags;
krb5_error_code ret;
@ -503,11 +450,11 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
(CFXSentByAcceptor | CFXSealed | CFXAcceptorSubkey);
if (token_flags & CFXSentByAcceptor) {
if ((context_handle->more_flags & LOCAL) == 0)
if ((ctx->more_flags & LOCAL) == 0)
return GSS_S_DEFECTIVE_TOKEN;
}
if (context_handle->more_flags & ACCEPTOR_SUBKEY) {
if (ctx->more_flags & ACCEPTOR_SUBKEY) {
if ((token_flags & CFXAcceptorSubkey) == 0)
return GSS_S_DEFECTIVE_TOKEN;
} else {
@ -537,26 +484,21 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
return GSS_S_UNSEQ_TOKEN;
}
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
ret = _gssapi_msg_order_check(context_handle->order, seq_number_lo);
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
ret = _gssapi_msg_order_check(ctx->order, seq_number_lo);
if (ret != 0) {
*minor_status = 0;
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
_gsskrb5_release_buffer(minor_status, output_message_buffer);
return ret;
}
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
/*
* Decrypt and/or verify checksum
*/
ret = krb5_crypto_init(context, key, 0, &crypto);
if (ret != 0) {
*minor_status = ret;
return GSS_S_FAILURE;
}
if (context_handle->more_flags & LOCAL) {
if (ctx->more_flags & LOCAL) {
usage = KRB5_KU_USAGE_ACCEPTOR_SEAL;
} else {
usage = KRB5_KU_USAGE_INITIATOR_SEAL;
@ -571,27 +513,24 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
* this is really ugly, but needed against windows
* for DCERPC, as windows rotates by EC+RRC.
*/
if (IS_DCE_STYLE(context_handle)) {
if (IS_DCE_STYLE(ctx)) {
*minor_status = rrc_rotate(p, len, rrc+ec, TRUE);
} else {
*minor_status = rrc_rotate(p, len, rrc, TRUE);
}
if (*minor_status != 0) {
krb5_crypto_destroy(context, crypto);
return GSS_S_FAILURE;
}
ret = krb5_decrypt(context, crypto, usage,
ret = krb5_decrypt(context, ctx->crypto, usage,
p, len, &data);
if (ret != 0) {
*minor_status = ret;
krb5_crypto_destroy(context, crypto);
return GSS_S_BAD_MIC;
}
/* Check that there is room for the pad and token header */
if (data.length < ec + sizeof(*token)) {
krb5_crypto_destroy(context, crypto);
krb5_data_free(&data);
return GSS_S_DEFECTIVE_TOKEN;
}
@ -604,7 +543,6 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
/* Check the integrity of the header */
if (memcmp(p, token, sizeof(*token)) != 0) {
krb5_crypto_destroy(context, crypto);
krb5_data_free(&data);
return GSS_S_BAD_MIC;
}
@ -617,16 +555,15 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
/* Rotate by RRC; bogus to do this in-place XXX */
*minor_status = rrc_rotate(p, len, rrc, TRUE);
if (*minor_status != 0) {
krb5_crypto_destroy(context, crypto);
return GSS_S_FAILURE;
}
/* Determine checksum type */
ret = krb5_crypto_get_checksum_type(context,
crypto, &cksum.cksumtype);
ctx->crypto,
&cksum.cksumtype);
if (ret != 0) {
*minor_status = ret;
krb5_crypto_destroy(context, crypto);
return GSS_S_FAILURE;
}
@ -635,7 +572,6 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
/* Check we have at least as much data as the checksum */
if (len < cksum.checksum.length) {
*minor_status = ERANGE;
krb5_crypto_destroy(context, crypto);
return GSS_S_BAD_MIC;
}
@ -647,7 +583,6 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
output_message_buffer->value = malloc(len + sizeof(*token));
if (output_message_buffer->value == NULL) {
*minor_status = ENOMEM;
krb5_crypto_destroy(context, crypto);
return GSS_S_FAILURE;
}
@ -664,21 +599,18 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
token->RRC[0] = 0;
token->RRC[1] = 0;
ret = krb5_verify_checksum(context, crypto,
ret = krb5_verify_checksum(context, ctx->crypto,
usage,
output_message_buffer->value,
len + sizeof(*token),
&cksum);
if (ret != 0) {
*minor_status = ret;
krb5_crypto_destroy(context, crypto);
_gsskrb5_release_buffer(minor_status, output_message_buffer);
return GSS_S_BAD_MIC;
}
}
krb5_crypto_destroy(context, crypto);
if (qop_state != NULL) {
*qop_state = GSS_C_QOP_DEFAULT;
}
@ -688,14 +620,12 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
}
OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status,
const gsskrb5_ctx context_handle,
const gsskrb5_ctx ctx,
krb5_context context,
gss_qop_t qop_req,
const gss_buffer_t message_buffer,
gss_buffer_t message_token,
krb5_keyblock *key)
gss_buffer_t message_token)
{
krb5_crypto crypto;
gss_cfx_mic_token token;
krb5_error_code ret;
unsigned usage;
@ -704,17 +634,10 @@ OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status,
size_t len;
int32_t seq_number;
ret = krb5_crypto_init(context, key, 0, &crypto);
if (ret != 0) {
*minor_status = ret;
return GSS_S_FAILURE;
}
len = message_buffer->length + sizeof(*token);
buf = malloc(len);
if (buf == NULL) {
*minor_status = ENOMEM;
krb5_crypto_destroy(context, crypto);
return GSS_S_FAILURE;
}
@ -724,38 +647,36 @@ OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status,
token->TOK_ID[0] = 0x04;
token->TOK_ID[1] = 0x04;
token->Flags = 0;
if ((context_handle->more_flags & LOCAL) == 0)
if ((ctx->more_flags & LOCAL) == 0)
token->Flags |= CFXSentByAcceptor;
if (context_handle->more_flags & ACCEPTOR_SUBKEY)
if (ctx->more_flags & ACCEPTOR_SUBKEY)
token->Flags |= CFXAcceptorSubkey;
memset(token->Filler, 0xFF, 5);
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
krb5_auth_con_getlocalseqnumber(context,
context_handle->auth_context,
ctx->auth_context,
&seq_number);
_gsskrb5_encode_be_om_uint32(0, &token->SND_SEQ[0]);
_gsskrb5_encode_be_om_uint32(seq_number, &token->SND_SEQ[4]);
krb5_auth_con_setlocalseqnumber(context,
context_handle->auth_context,
ctx->auth_context,
++seq_number);
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
if (context_handle->more_flags & LOCAL) {
if (ctx->more_flags & LOCAL) {
usage = KRB5_KU_USAGE_INITIATOR_SIGN;
} else {
usage = KRB5_KU_USAGE_ACCEPTOR_SIGN;
}
ret = krb5_create_checksum(context, crypto,
ret = krb5_create_checksum(context, ctx->crypto,
usage, 0, buf, len, &cksum);
if (ret != 0) {
*minor_status = ret;
krb5_crypto_destroy(context, crypto);
free(buf);
return GSS_S_FAILURE;
}
krb5_crypto_destroy(context, crypto);
/* Determine MIC length */
message_token->length = sizeof(*token) + cksum.checksum.length;
@ -780,14 +701,12 @@ OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status,
}
OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status,
const gsskrb5_ctx context_handle,
const gsskrb5_ctx ctx,
krb5_context context,
const gss_buffer_t message_buffer,
const gss_buffer_t token_buffer,
gss_qop_t *qop_state,
krb5_keyblock *key)
gss_qop_t *qop_state)
{
krb5_crypto crypto;
gss_cfx_mic_token token;
u_char token_flags;
krb5_error_code ret;
@ -814,10 +733,10 @@ OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status,
token_flags = token->Flags & (CFXSentByAcceptor | CFXAcceptorSubkey);
if (token_flags & CFXSentByAcceptor) {
if ((context_handle->more_flags & LOCAL) == 0)
if ((ctx->more_flags & LOCAL) == 0)
return GSS_S_DEFECTIVE_TOKEN;
}
if (context_handle->more_flags & ACCEPTOR_SUBKEY) {
if (ctx->more_flags & ACCEPTOR_SUBKEY) {
if ((token_flags & CFXAcceptorSubkey) == 0)
return GSS_S_DEFECTIVE_TOKEN;
} else {
@ -839,36 +758,29 @@ OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status,
return GSS_S_UNSEQ_TOKEN;
}
HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
ret = _gssapi_msg_order_check(context_handle->order, seq_number_lo);
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
ret = _gssapi_msg_order_check(ctx->order, seq_number_lo);
if (ret != 0) {
*minor_status = 0;
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
return ret;
}
HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
/*
* Verify checksum
*/
ret = krb5_crypto_init(context, key, 0, &crypto);
if (ret != 0) {
*minor_status = ret;
return GSS_S_FAILURE;
}
ret = krb5_crypto_get_checksum_type(context, crypto,
ret = krb5_crypto_get_checksum_type(context, ctx->crypto,
&cksum.cksumtype);
if (ret != 0) {
*minor_status = ret;
krb5_crypto_destroy(context, crypto);
return GSS_S_FAILURE;
}
cksum.checksum.data = p + sizeof(*token);
cksum.checksum.length = token_buffer->length - sizeof(*token);
if (context_handle->more_flags & LOCAL) {
if (ctx->more_flags & LOCAL) {
usage = KRB5_KU_USAGE_ACCEPTOR_SIGN;
} else {
usage = KRB5_KU_USAGE_INITIATOR_SIGN;
@ -877,18 +789,16 @@ OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status,
buf = malloc(message_buffer->length + sizeof(*token));
if (buf == NULL) {
*minor_status = ENOMEM;
krb5_crypto_destroy(context, crypto);
return GSS_S_FAILURE;
}
memcpy(buf, message_buffer->value, message_buffer->length);
memcpy(buf + message_buffer->length, token, sizeof(*token));
ret = krb5_verify_checksum(context, crypto,
ret = krb5_verify_checksum(context, ctx->crypto,
usage,
buf,
sizeof(*token) + message_buffer->length,
&cksum);
krb5_crypto_destroy(context, crypto);
if (ret != 0) {
*minor_status = ret;
free(buf);

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
#include "krb5/gsskrb5_locl.h"
#include "gsskrb5_locl.h"
RCSID("$Id$");

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
#include "krb5/gsskrb5_locl.h"
#include "gsskrb5_locl.h"
RCSID("$Id$");

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
#include "krb5/gsskrb5_locl.h"
#include "gsskrb5_locl.h"
RCSID("$Id$");

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
#include "krb5/gsskrb5_locl.h"
#include "gsskrb5_locl.h"
RCSID("$Id$");

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
#include "krb5/gsskrb5_locl.h"
#include "gsskrb5_locl.h"
RCSID("$Id$");

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
#include "krb5/gsskrb5_locl.h"
#include "gsskrb5_locl.h"
RCSID("$Id$");
@ -74,6 +74,8 @@ _gsskrb5_delete_sec_context(OM_uint32 * minor_status,
if (ctx->service_keyblock)
krb5_free_keyblock (context, ctx->service_keyblock);
krb5_data_free(&ctx->fwd_data);
if (ctx->crypto)
krb5_crypto_destroy(context, ctx->crypto);
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
HEIMDAL_MUTEX_destroy(&ctx->ctx_id_mutex);

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
#include "krb5/gsskrb5_locl.h"
#include "gsskrb5_locl.h"
RCSID("$Id$");

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
#include "krb5/gsskrb5_locl.h"
#include "gsskrb5_locl.h"
RCSID("$Id$");

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
#include "krb5/gsskrb5_locl.h"
#include "gsskrb5_locl.h"
RCSID("$Id$");

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
#include "krb5/gsskrb5_locl.h"
#include "gsskrb5_locl.h"
RCSID("$Id$");

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
#include "krb5/gsskrb5_locl.h"
#include "gsskrb5_locl.h"
RCSID("$Id$");

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
#include "krb5/gsskrb5_locl.h"
#include "gsskrb5_locl.h"
RCSID("$Id$");

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
#include "krb5/gsskrb5_locl.h"
#include "gsskrb5_locl.h"
#include <gssapi_mech.h>
RCSID("$Id$");
@ -469,7 +469,10 @@ static gssapi_mech_interface_desc krb5_mech = {
_gsskrb5_inquire_cred_by_oid,
_gsskrb5_set_sec_context_option,
_gsskrb5_set_cred_option,
_gsskrb5_pseudo_random
_gsskrb5_pseudo_random,
_gk_wrap_iov,
_gk_unwrap_iov,
_gk_wrap_iov_length
};
gssapi_mech_interface

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
#include "krb5/gsskrb5_locl.h"
#include "gsskrb5_locl.h"
RCSID("$Id$");
@ -284,6 +284,10 @@ OM_uint32 _gsskrb5_get_mic
GSSAPI_KRB5_INIT (&context);
if (ctx->more_flags & IS_CFX)
return _gssapi_mic_cfx (minor_status, ctx, context, qop_req,
message_buffer, message_token);
HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
ret = _gsskrb5i_get_token_key(ctx, context, &key);
HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
@ -308,8 +312,7 @@ OM_uint32 _gsskrb5_get_mic
message_buffer, message_token, key);
break;
default :
ret = _gssapi_mic_cfx (minor_status, ctx, context, qop_req,
message_buffer, message_token, key);
abort();
break;
}
krb5_free_keyblock (context, key);

View File

@ -36,14 +36,13 @@
#ifndef GSSKRB5_LOCL_H
#define GSSKRB5_LOCL_H
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <krb5_locl.h>
#include <gkrb5_err.h>
#include <gssapi.h>
#include <gssapi_mech.h>
#include <gssapi_krb5.h>
#include <assert.h>
#include "cfx.h"
@ -54,7 +53,7 @@
struct gss_msg_order;
typedef struct {
typedef struct gsskrb5_ctx {
struct krb5_auth_context_data *auth_context;
krb5_principal source, target;
#define IS_DCE_STYLE(ctx) (((ctx)->flags & GSS_C_DCE_STYLE) != 0)
@ -64,7 +63,8 @@ typedef struct {
COMPAT_OLD_DES3_SELECTED = 8,
ACCEPTOR_SUBKEY = 16,
RETRIED = 32,
CLOSE_CCACHE = 64
CLOSE_CCACHE = 64,
IS_CFX = 128
} more_flags;
enum gss_ctx_id_t_state {
/* initiator states */
@ -85,6 +85,7 @@ typedef struct {
struct gss_msg_order *order;
krb5_keyblock *service_keyblock;
krb5_data fwd_data;
krb5_crypto crypto;
} *gsskrb5_ctx;
typedef struct {
@ -119,7 +120,7 @@ struct gssapi_thr_context {
* Prototypes
*/
#include <krb5/gsskrb5-private.h>
#include <gsskrb5-private.h>
#define GSSAPI_KRB5_INIT(ctx) do { \
krb5_error_code kret_gss_init; \

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
#include "krb5/gsskrb5_locl.h"
#include "gsskrb5_locl.h"
RCSID("$Id$");

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
#include "krb5/gsskrb5_locl.h"
#include "gsskrb5_locl.h"
RCSID("$Id$");

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
#include "krb5/gsskrb5_locl.h"
#include "gsskrb5_locl.h"
RCSID("$Id$");

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
#include "krb5/gsskrb5_locl.h"
#include "gsskrb5_locl.h"
RCSID("$Id$");

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
#include "krb5/gsskrb5_locl.h"
#include "gsskrb5_locl.h"
RCSID("$Id$");
@ -131,6 +131,7 @@ _gsskrb5_create_ctx(
krb5_data_zero(&ctx->fwd_data);
ctx->lifetime = GSS_C_INDEFINITE;
ctx->order = NULL;
ctx->crypto = NULL;
HEIMDAL_MUTEX_init(&ctx->ctx_id_mutex);
kret = krb5_auth_con_init (context, &ctx->auth_context);
@ -257,7 +258,8 @@ gsskrb5_initiator_ready(
krb5_auth_getremoteseqnumber (context, ctx->auth_context, &seq_number);
_gsskrb5i_is_cfx(ctx, &is_cfx);
_gsskrb5i_is_cfx(context, ctx, 0);
is_cfx = (ctx->more_flags & IS_CFX);
ret = _gssapi_msg_order_create(minor_status,
&ctx->order,
@ -552,8 +554,10 @@ init_auth_restart
flags |= GSS_C_REPLAY_FLAG;
if (req_flags & GSS_C_SEQUENCE_FLAG)
flags |= GSS_C_SEQUENCE_FLAG;
#if 0
if (req_flags & GSS_C_ANON_FLAG)
; /* XXX */
#endif
if (req_flags & GSS_C_DCE_STYLE) {
/* GSS_C_DCE_STYLE implies GSS_C_MUTUAL_FLAG */
flags |= GSS_C_DCE_STYLE | GSS_C_MUTUAL_FLAG;
@ -686,7 +690,6 @@ repl_mutual
krb5_error_code kret;
krb5_data indata;
krb5_ap_rep_enc_part *repl;
int is_cfx = 0;
output_token->length = 0;
output_token->value = NULL;
@ -759,20 +762,6 @@ repl_mutual
krb5_free_ap_rep_enc_part (context,
repl);
_gsskrb5i_is_cfx(ctx, &is_cfx);
if (is_cfx) {
krb5_keyblock *key = NULL;
kret = krb5_auth_con_getremotesubkey(context,
ctx->auth_context,
&key);
if (kret == 0 && key != NULL) {
ctx->more_flags |= ACCEPTOR_SUBKEY;
krb5_free_keyblock (context, key);
}
}
*minor_status = 0;
if (time_rec) {
ret = _gsskrb5_lifetime_left(minor_status,

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
#include "krb5/gsskrb5_locl.h"
#include "gsskrb5_locl.h"
RCSID("$Id$");

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
#include "krb5/gsskrb5_locl.h"
#include "gsskrb5_locl.h"
RCSID("$Id$");

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
#include "krb5/gsskrb5_locl.h"
#include "gsskrb5_locl.h"
RCSID("$Id$");

View File

@ -30,7 +30,7 @@
* SUCH DAMAGE.
*/
#include "krb5/gsskrb5_locl.h"
#include "gsskrb5_locl.h"
RCSID("$Id$");

View File

@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
#include "krb5/gsskrb5_locl.h"
#include "gsskrb5_locl.h"
RCSID("$Id$");

Some files were not shown because too many files have changed in this diff Show More