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:
parent
5cef57ff7d
commit
9b261c008a
@ -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. */
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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)));
|
||||
|
@ -1,4 +1,3 @@
|
||||
$Id$
|
||||
|
||||
Heimdal is a Kerberos 5 implementation.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
}
|
@ -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);
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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[];
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
1
source4/heimdal/lib/asn1/cms.opt
Normal file
1
source4/heimdal/lib/asn1/cms.opt
Normal file
@ -0,0 +1 @@
|
||||
--decode-dce-ber
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
|
@ -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))))
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
6
source4/heimdal/lib/asn1/krb5.opt
Normal file
6
source4/heimdal/lib/asn1/krb5.opt
Normal file
@ -0,0 +1,6 @@
|
||||
--encode-rfc1510-bit-string
|
||||
--sequence=Principals
|
||||
--sequence=AuthorizationData
|
||||
--sequence=METHOD-DATA
|
||||
--sequence=ETYPE-INFO
|
||||
--sequence=ETYPE-INFO2
|
@ -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,
|
||||
|
@ -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++ = '"';
|
||||
|
@ -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
@ -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
|
||||
|
@ -24,7 +24,7 @@ PKCS8EncryptedData ::= OCTET STRING
|
||||
|
||||
PKCS8EncryptedPrivateKeyInfo ::= SEQUENCE {
|
||||
encryptionAlgorithm AlgorithmIdentifier,
|
||||
encryptedData PKCS8EncryptedData
|
||||
encryptedData PKCS8EncryptedData
|
||||
}
|
||||
|
||||
END
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
)
|
||||
|
||||
|
@ -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>
|
||||
|
@ -35,8 +35,6 @@
|
||||
#include "compile_et.h"
|
||||
#include <getarg.h>
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
#include <roken.h>
|
||||
#include <err.h>
|
||||
#include "parse.h"
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -44,8 +44,6 @@
|
||||
#include "parse.h"
|
||||
#include "lex.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
static unsigned lineno = 1;
|
||||
static int getstring(void);
|
||||
|
||||
|
@ -35,8 +35,6 @@
|
||||
#include "compile_et.h"
|
||||
#include "lex.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
void yyerror (char *s);
|
||||
static long name2number(const char *str);
|
||||
|
||||
|
@ -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_ */
|
||||
|
@ -36,7 +36,7 @@
|
||||
#ifndef GSSAPI_KRB5_H_
|
||||
#define GSSAPI_KRB5_H_
|
||||
|
||||
#include <gssapi/gssapi.h>
|
||||
#include <gssapi.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -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
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "krb5/gsskrb5_locl.h"
|
||||
#include "gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "krb5/gsskrb5_locl.h"
|
||||
#include "gsskrb5_locl.h"
|
||||
|
||||
#include <roken.h>
|
||||
|
||||
|
271
source4/heimdal/lib/gssapi/krb5/aeap.c
Normal file
271
source4/heimdal/lib/gssapi/krb5/aeap.c
Normal 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;
|
||||
}
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "krb5/gsskrb5_locl.h"
|
||||
#include "gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "krb5/gsskrb5_locl.h"
|
||||
#include "gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
|
@ -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);
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "krb5/gsskrb5_locl.h"
|
||||
#include "gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "krb5/gsskrb5_locl.h"
|
||||
#include "gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "krb5/gsskrb5_locl.h"
|
||||
#include "gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "krb5/gsskrb5_locl.h"
|
||||
#include "gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "krb5/gsskrb5_locl.h"
|
||||
#include "gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
|
@ -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);
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "krb5/gsskrb5_locl.h"
|
||||
#include "gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "krb5/gsskrb5_locl.h"
|
||||
#include "gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "krb5/gsskrb5_locl.h"
|
||||
#include "gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "krb5/gsskrb5_locl.h"
|
||||
#include "gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "krb5/gsskrb5_locl.h"
|
||||
#include "gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "krb5/gsskrb5_locl.h"
|
||||
#include "gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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; \
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "krb5/gsskrb5_locl.h"
|
||||
#include "gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "krb5/gsskrb5_locl.h"
|
||||
#include "gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "krb5/gsskrb5_locl.h"
|
||||
#include "gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "krb5/gsskrb5_locl.h"
|
||||
#include "gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
|
@ -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,
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "krb5/gsskrb5_locl.h"
|
||||
#include "gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "krb5/gsskrb5_locl.h"
|
||||
#include "gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "krb5/gsskrb5_locl.h"
|
||||
#include "gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "krb5/gsskrb5_locl.h"
|
||||
#include "gsskrb5_locl.h"
|
||||
|
||||
RCSID("$Id$");
|
||||
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user