remove krb4 support
This commit is contained in:
144
kdc/v4_dump.c
144
kdc/v4_dump.c
@@ -1,144 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2000 - 2001, 2003 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 "hprop.h"
|
||||
|
||||
#ifdef KRB4
|
||||
|
||||
static time_t
|
||||
time_parse(const char *cp)
|
||||
{
|
||||
char wbuf[5];
|
||||
struct tm tp;
|
||||
int local;
|
||||
|
||||
memset(&tp, 0, sizeof(tp)); /* clear out the struct */
|
||||
|
||||
/* new format is YYYYMMDDHHMM UTC,
|
||||
old format is YYMMDDHHMM local time */
|
||||
if (strlen(cp) > 10) { /* new format */
|
||||
strlcpy(wbuf, cp, sizeof(wbuf));
|
||||
tp.tm_year = atoi(wbuf) - 1900;
|
||||
cp += 4;
|
||||
local = 0;
|
||||
} else {
|
||||
wbuf[0] = *cp++;
|
||||
wbuf[1] = *cp++;
|
||||
wbuf[2] = '\0';
|
||||
tp.tm_year = atoi(wbuf);
|
||||
if(tp.tm_year < 38)
|
||||
tp.tm_year += 100;
|
||||
local = 1;
|
||||
}
|
||||
|
||||
wbuf[0] = *cp++;
|
||||
wbuf[1] = *cp++;
|
||||
wbuf[2] = 0;
|
||||
tp.tm_mon = atoi(wbuf) - 1;
|
||||
|
||||
wbuf[0] = *cp++;
|
||||
wbuf[1] = *cp++;
|
||||
tp.tm_mday = atoi(wbuf);
|
||||
|
||||
wbuf[0] = *cp++;
|
||||
wbuf[1] = *cp++;
|
||||
tp.tm_hour = atoi(wbuf);
|
||||
|
||||
wbuf[0] = *cp++;
|
||||
wbuf[1] = *cp++;
|
||||
tp.tm_min = atoi(wbuf);
|
||||
|
||||
return(tm2time(tp, local));
|
||||
}
|
||||
|
||||
/* convert a version 4 dump file */
|
||||
int
|
||||
v4_prop_dump(void *arg, const char *file)
|
||||
{
|
||||
char buf [1024];
|
||||
FILE *f;
|
||||
int lineno = 0;
|
||||
|
||||
f = fopen(file, "r");
|
||||
if(f == NULL)
|
||||
return errno;
|
||||
|
||||
while(fgets(buf, sizeof(buf), f)) {
|
||||
int ret;
|
||||
unsigned long key[2]; /* yes, long */
|
||||
char exp_date[64], mod_date[64];
|
||||
struct v4_principal pr;
|
||||
int attributes;
|
||||
|
||||
memset(&pr, 0, sizeof(pr));
|
||||
errno = 0;
|
||||
lineno++;
|
||||
ret = sscanf(buf, "%63s %63s %d %d %d %d %lx %lx %63s %63s %63s %63s",
|
||||
pr.name, pr.instance,
|
||||
&pr.max_life, &pr.mkvno, &pr.kvno,
|
||||
&attributes,
|
||||
&key[0], &key[1],
|
||||
exp_date, mod_date,
|
||||
pr.mod_name, pr.mod_instance);
|
||||
if(ret != 12){
|
||||
warnx("Line %d malformed (ignored)", lineno);
|
||||
continue;
|
||||
}
|
||||
if(attributes != 0) {
|
||||
warnx("Line %d (%s.%s) has non-zero attributes - skipping",
|
||||
lineno, pr.name, pr.instance);
|
||||
continue;
|
||||
}
|
||||
pr.key[0] = (key[0] >> 24) & 0xff;
|
||||
pr.key[1] = (key[0] >> 16) & 0xff;
|
||||
pr.key[2] = (key[0] >> 8) & 0xff;
|
||||
pr.key[3] = (key[0] >> 0) & 0xff;
|
||||
pr.key[4] = (key[1] >> 24) & 0xff;
|
||||
pr.key[5] = (key[1] >> 16) & 0xff;
|
||||
pr.key[6] = (key[1] >> 8) & 0xff;
|
||||
pr.key[7] = (key[1] >> 0) & 0xff;
|
||||
pr.exp_date = time_parse(exp_date);
|
||||
pr.mod_date = time_parse(mod_date);
|
||||
if (pr.instance[0] == '*')
|
||||
pr.instance[0] = '\0';
|
||||
if (pr.mod_name[0] == '*')
|
||||
pr.mod_name[0] = '\0';
|
||||
if (pr.mod_instance[0] == '*')
|
||||
pr.mod_instance[0] = '\0';
|
||||
v4_prop(arg, &pr);
|
||||
memset(&pr, 0, sizeof(pr));
|
||||
}
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
#endif /* KRB4 */
|
@@ -24,7 +24,6 @@ TESTS = \
|
||||
aes-test \
|
||||
derived-key-test \
|
||||
n-fold-test \
|
||||
name-45-test \
|
||||
parse-name-test \
|
||||
store-test \
|
||||
string-to-key-test \
|
||||
@@ -220,7 +219,6 @@ dist_libkrb5_la_SOURCES = \
|
||||
ticket.c \
|
||||
time.c \
|
||||
transited.c \
|
||||
v4_glue.c \
|
||||
verify_init.c \
|
||||
verify_user.c \
|
||||
version.c \
|
||||
|
@@ -376,67 +376,6 @@ krb5_get_in_tkt_with_keytab (krb5_context context,
|
||||
ret_as_reply);
|
||||
}
|
||||
|
||||
#ifdef KRB4
|
||||
|
||||
static krb5_boolean
|
||||
convert_func(krb5_context conxtext, void *funcctx, krb5_principal principal)
|
||||
{
|
||||
krb5_boolean (*func)(krb5_context, krb5_principal) = funcctx;
|
||||
return (*func)(conxtext, principal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated: kerberos 4 is dead, let it die.
|
||||
*
|
||||
* @ingroup krb5_deprecated
|
||||
*/
|
||||
|
||||
KRB5_DEPRECATED
|
||||
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
|
||||
krb5_425_conv_principal_ext(krb5_context context,
|
||||
const char *name,
|
||||
const char *instance,
|
||||
const char *realm,
|
||||
krb5_boolean (*func)(krb5_context, krb5_principal),
|
||||
krb5_boolean resolve,
|
||||
krb5_principal *principal)
|
||||
{
|
||||
return krb5_425_conv_principal_ext2(context,
|
||||
name,
|
||||
instance,
|
||||
realm,
|
||||
func ? convert_func : NULL,
|
||||
func,
|
||||
resolve,
|
||||
principal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deprecated: kerberos 4 is dead, let it die.
|
||||
*
|
||||
* @ingroup krb5_deprecated
|
||||
*/
|
||||
|
||||
KRB5_DEPRECATED
|
||||
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
|
||||
krb5_425_conv_principal(krb5_context context,
|
||||
const char *name,
|
||||
const char *instance,
|
||||
const char *realm,
|
||||
krb5_principal *princ)
|
||||
{
|
||||
krb5_boolean resolve = krb5_config_get_bool(context,
|
||||
NULL,
|
||||
"libdefaults",
|
||||
"v4_instance_resolve",
|
||||
NULL);
|
||||
|
||||
return krb5_425_conv_principal_ext(context, name, instance, realm,
|
||||
NULL, resolve, princ);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Generate a new ccache of type `ops' in `id'.
|
||||
*
|
||||
|
@@ -1,302 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2002 - 2003 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 KTH 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 KTH AND ITS 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 KTH OR ITS 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. */
|
||||
|
||||
#define KRB5_DEPRECATED
|
||||
|
||||
#include "krb5_locl.h"
|
||||
#include <err.h>
|
||||
|
||||
#ifdef KRB4
|
||||
|
||||
enum { MAX_COMPONENTS = 3 };
|
||||
|
||||
static struct testcase {
|
||||
const char *v4_name;
|
||||
const char *v4_inst;
|
||||
const char *v4_realm;
|
||||
|
||||
krb5_realm v5_realm;
|
||||
unsigned ncomponents;
|
||||
char *comp_val[MAX_COMPONENTS];
|
||||
|
||||
const char *config_file;
|
||||
krb5_error_code ret; /* expected error code from 524 */
|
||||
|
||||
krb5_error_code ret2; /* expected error code from 425 */
|
||||
} tests[] = {
|
||||
{"", "", "", "", 1, {""}, NULL, 0, 0},
|
||||
{"a", "", "", "", 1, {"a"}, NULL, 0, 0},
|
||||
{"a", "b", "", "", 2, {"a", "b"}, NULL, 0, 0},
|
||||
{"a", "b", "c", "c", 2, {"a", "b"}, NULL, 0, 0},
|
||||
|
||||
{"krbtgt", "FOO.SE", "FOO.SE", "FOO.SE", 2,
|
||||
{"krbtgt", "FOO.SE"}, NULL, 0, 0},
|
||||
|
||||
{"foo", "bar2", "BAZ", "BAZ", 2,
|
||||
{"foo", "bar2"}, NULL, 0, 0},
|
||||
{"foo", "bar2", "BAZ", "BAZ", 2,
|
||||
{"foo", "bar2"},
|
||||
"[libdefaults]\n"
|
||||
" v4_name_convert = {\n"
|
||||
" host = {\n"
|
||||
" foo = foo5\n"
|
||||
" }\n"
|
||||
"}\n",
|
||||
HEIM_ERR_V4_PRINC_NO_CONV, 0},
|
||||
{"foo", "bar2", "BAZ", "BAZ", 2,
|
||||
{"foo5", "bar2.baz"},
|
||||
"[realms]\n"
|
||||
" BAZ = {\n"
|
||||
" v4_name_convert = {\n"
|
||||
" host = {\n"
|
||||
" foo = foo5\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" v4_instance_convert = {\n"
|
||||
" bar2 = bar2.baz\n"
|
||||
" }\n"
|
||||
" }\n",
|
||||
0, 0},
|
||||
|
||||
{"rcmd", "foo", "realm", "realm", 2, {"host", "foo"}, NULL,
|
||||
HEIM_ERR_V4_PRINC_NO_CONV, 0},
|
||||
{"rcmd", "foo", "realm", "realm", 2, {"host", "foo.realm"},
|
||||
"[realms]\n"
|
||||
" realm = {\n"
|
||||
" v4_instance_convert = {\n"
|
||||
" foo = foo.realm\n"
|
||||
" }\n"
|
||||
" }\n",
|
||||
0, 0},
|
||||
|
||||
{"pop", "mail0", "NADA.KTH.SE", "NADA.KTH.SE", 2,
|
||||
{"pop", "mail0.nada.kth.se"}, "", HEIM_ERR_V4_PRINC_NO_CONV, 0},
|
||||
{"pop", "mail0", "NADA.KTH.SE", "NADA.KTH.SE", 2,
|
||||
{"pop", "mail0.nada.kth.se"},
|
||||
"[realms]\n"
|
||||
" NADA.KTH.SE = {\n"
|
||||
" default_domain = nada.kth.se\n"
|
||||
" }\n",
|
||||
0, 0},
|
||||
{"pop", "mail0", "NADA.KTH.SE", "NADA.KTH.SE", 2,
|
||||
{"pop", "mail0.nada.kth.se"},
|
||||
"[libdefaults]\n"
|
||||
" v4_instance_resolve = true\n",
|
||||
HEIM_ERR_V4_PRINC_NO_CONV, 0},
|
||||
|
||||
{"rcmd", "hokkigai", "NADA.KTH.SE", "NADA.KTH.SE", 2,
|
||||
{"host", "hokkigai.pdc.kth.se"}, "", HEIM_ERR_V4_PRINC_NO_CONV, 0},
|
||||
{"rcmd", "hokkigai", "NADA.KTH.SE", "NADA.KTH.SE", 2,
|
||||
{"host", "hokkigai.pdc.kth.se"},
|
||||
"[libdefaults]\n"
|
||||
" v4_instance_resolve = true\n"
|
||||
"[realms]\n"
|
||||
" NADA.KTH.SE = {\n"
|
||||
" v4_name_convert = {\n"
|
||||
" host = {\n"
|
||||
" rcmd = host\n"
|
||||
" }\n"
|
||||
" }\n"
|
||||
" default_domain = pdc.kth.se\n"
|
||||
" }\n",
|
||||
0, 0},
|
||||
|
||||
{"0123456789012345678901234567890123456789",
|
||||
"0123456789012345678901234567890123456789",
|
||||
"0123456789012345678901234567890123456789",
|
||||
"0123456789012345678901234567890123456789",
|
||||
2, {"0123456789012345678901234567890123456789",
|
||||
"0123456789012345678901234567890123456789"}, NULL,
|
||||
0, KRB5_PARSE_MALFORMED},
|
||||
|
||||
{"012345678901234567890123456789012345678",
|
||||
"012345678901234567890123456789012345678",
|
||||
"012345678901234567890123456789012345678",
|
||||
"012345678901234567890123456789012345678",
|
||||
2, {"012345678901234567890123456789012345678",
|
||||
"012345678901234567890123456789012345678"}, NULL,
|
||||
0, 0},
|
||||
|
||||
{NULL, NULL, NULL, NULL, 0, {NULL}, NULL, 0}
|
||||
};
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
struct testcase *t;
|
||||
krb5_context context;
|
||||
krb5_error_code ret;
|
||||
char hostname[1024];
|
||||
int val = 0;
|
||||
|
||||
setprogname(argv[0]);
|
||||
|
||||
gethostname(hostname, sizeof(hostname));
|
||||
if (!(strstr(hostname, "kth.se") != NULL || strstr(hostname, "su.se") != NULL))
|
||||
return 0;
|
||||
|
||||
for (t = tests; t->v4_name; ++t) {
|
||||
krb5_principal princ;
|
||||
int i;
|
||||
char name[40], inst[40], realm[40];
|
||||
char printable_princ[256];
|
||||
|
||||
ret = krb5_init_context (&context);
|
||||
if (ret)
|
||||
errx (1, "krb5_init_context failed: %d", ret);
|
||||
|
||||
if (t->config_file != NULL) {
|
||||
char template[] = "/tmp/krb5-conf-XXXXXX";
|
||||
int fd = mkstemp(template);
|
||||
char *files[2];
|
||||
|
||||
if (fd < 0)
|
||||
krb5_err (context, 1, errno, "mkstemp %s", template);
|
||||
|
||||
if (write (fd, t->config_file, strlen(t->config_file))
|
||||
!= strlen(t->config_file))
|
||||
krb5_err (context, 1, errno, "write %s", template);
|
||||
close (fd);
|
||||
files[0] = template;
|
||||
files[1] = NULL;
|
||||
|
||||
ret = krb5_set_config_files (context, files);
|
||||
unlink (template);
|
||||
if (ret)
|
||||
krb5_err (context, 1, ret, "krb5_set_config_files");
|
||||
}
|
||||
|
||||
ret = krb5_425_conv_principal (context,
|
||||
t->v4_name,
|
||||
t->v4_inst,
|
||||
t->v4_realm,
|
||||
&princ);
|
||||
if (ret) {
|
||||
if (ret != t->ret) {
|
||||
krb5_warn (context, ret,
|
||||
"krb5_425_conv_principal %s.%s@%s",
|
||||
t->v4_name, t->v4_inst, t->v4_realm);
|
||||
val = 1;
|
||||
}
|
||||
} else {
|
||||
if (t->ret) {
|
||||
char *s;
|
||||
krb5_unparse_name(context, princ, &s);
|
||||
krb5_warnx (context,
|
||||
"krb5_425_conv_principal %s.%s@%s "
|
||||
"passed unexpected: %s",
|
||||
t->v4_name, t->v4_inst, t->v4_realm, s);
|
||||
free(s);
|
||||
val = 1;
|
||||
krb5_free_context(context);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
krb5_free_context(context);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp (t->v5_realm, princ->realm) != 0) {
|
||||
printf ("wrong realm (\"%s\" should be \"%s\")"
|
||||
" for \"%s.%s@%s\"\n",
|
||||
princ->realm, t->v5_realm,
|
||||
t->v4_name,
|
||||
t->v4_inst,
|
||||
t->v4_realm);
|
||||
val = 1;
|
||||
}
|
||||
|
||||
if (t->ncomponents != princ->name.name_string.len) {
|
||||
printf ("wrong number of components (%u should be %u)"
|
||||
" for \"%s.%s@%s\"\n",
|
||||
princ->name.name_string.len, t->ncomponents,
|
||||
t->v4_name,
|
||||
t->v4_inst,
|
||||
t->v4_realm);
|
||||
val = 1;
|
||||
} else {
|
||||
for (i = 0; i < t->ncomponents; ++i) {
|
||||
if (strcmp(t->comp_val[i],
|
||||
princ->name.name_string.val[i]) != 0) {
|
||||
printf ("bad component %d (\"%s\" should be \"%s\")"
|
||||
" for \"%s.%s@%s\"\n",
|
||||
i,
|
||||
princ->name.name_string.val[i],
|
||||
t->comp_val[i],
|
||||
t->v4_name,
|
||||
t->v4_inst,
|
||||
t->v4_realm);
|
||||
val = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = krb5_524_conv_principal (context, princ,
|
||||
name, inst, realm);
|
||||
if (krb5_unparse_name_fixed(context, princ,
|
||||
printable_princ, sizeof(printable_princ)))
|
||||
strlcpy(printable_princ, "unknown principal",
|
||||
sizeof(printable_princ));
|
||||
if (ret) {
|
||||
if (ret != t->ret2) {
|
||||
krb5_warn (context, ret,
|
||||
"krb5_524_conv_principal %s", printable_princ);
|
||||
val = 1;
|
||||
}
|
||||
} else {
|
||||
if (t->ret2) {
|
||||
krb5_warnx (context,
|
||||
"krb5_524_conv_principal %s "
|
||||
"passed unexpected", printable_princ);
|
||||
val = 1;
|
||||
krb5_free_context(context);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (ret) {
|
||||
krb5_free_principal (context, princ);
|
||||
krb5_free_context(context);
|
||||
continue;
|
||||
}
|
||||
|
||||
krb5_free_principal (context, princ);
|
||||
krb5_free_context(context);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
#else /* stub for !KRB4 */
|
||||
int main(int argc, char *argv[]) {
|
||||
return 77;
|
||||
}
|
||||
#endif
|
@@ -1013,437 +1013,6 @@ krb5_principal_match(krb5_context context,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#if defined(KRB4) || !defined(HEIMDAL_SMALLER)
|
||||
|
||||
static struct v4_name_convert {
|
||||
const char *from;
|
||||
const char *to;
|
||||
} default_v4_name_convert[] = {
|
||||
{ "ftp", "ftp" },
|
||||
{ "hprop", "hprop" },
|
||||
{ "pop", "pop" },
|
||||
{ "imap", "imap" },
|
||||
{ "rcmd", "host" },
|
||||
{ "smtp", "smtp" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef KRB4
|
||||
|
||||
/*
|
||||
* return the converted instance name of `name' in `realm'.
|
||||
* look in the configuration file and then in the default set above.
|
||||
* return NULL if no conversion is appropriate.
|
||||
*/
|
||||
|
||||
static const char*
|
||||
get_name_conversion(krb5_context context, const char *realm, const char *name)
|
||||
{
|
||||
struct v4_name_convert *q;
|
||||
const char *p;
|
||||
|
||||
p = krb5_config_get_string(context, NULL, "realms", realm,
|
||||
"v4_name_convert", "host", name, NULL);
|
||||
if(p == NULL)
|
||||
p = krb5_config_get_string(context, NULL, "libdefaults",
|
||||
"v4_name_convert", "host", name, NULL);
|
||||
if(p)
|
||||
return p;
|
||||
|
||||
/* XXX should be possible to override default list */
|
||||
p = krb5_config_get_string(context, NULL,
|
||||
"realms",
|
||||
realm,
|
||||
"v4_name_convert",
|
||||
"plain",
|
||||
name,
|
||||
NULL);
|
||||
if(p)
|
||||
return NULL;
|
||||
p = krb5_config_get_string(context, NULL,
|
||||
"libdefaults",
|
||||
"v4_name_convert",
|
||||
"plain",
|
||||
name,
|
||||
NULL);
|
||||
if(p)
|
||||
return NULL;
|
||||
for(q = default_v4_name_convert; q->from; q++)
|
||||
if(strcmp(q->from, name) == 0)
|
||||
return q->to;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* convert the v4 principal `name.instance@realm' to a v5 principal in `princ'.
|
||||
* if `resolve', use DNS.
|
||||
* if `func', use that function for validating the conversion
|
||||
*/
|
||||
|
||||
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
|
||||
krb5_425_conv_principal_ext2(krb5_context context,
|
||||
const char *name,
|
||||
const char *instance,
|
||||
const char *realm,
|
||||
krb5_boolean (*func)(krb5_context,
|
||||
void *, krb5_principal),
|
||||
void *funcctx,
|
||||
krb5_boolean resolve,
|
||||
krb5_principal *princ)
|
||||
{
|
||||
const char *p;
|
||||
krb5_error_code ret;
|
||||
krb5_principal pr;
|
||||
char host[MAXHOSTNAMELEN];
|
||||
char local_hostname[MAXHOSTNAMELEN];
|
||||
|
||||
/* do the following: if the name is found in the
|
||||
`v4_name_convert:host' part, is assumed to be a `host' type
|
||||
principal, and the instance is looked up in the
|
||||
`v4_instance_convert' part. if not found there the name is
|
||||
(optionally) looked up as a hostname, and if that doesn't yield
|
||||
anything, the `default_domain' is appended to the instance
|
||||
*/
|
||||
|
||||
if(instance == NULL)
|
||||
goto no_host;
|
||||
if(instance[0] == 0){
|
||||
instance = NULL;
|
||||
goto no_host;
|
||||
}
|
||||
p = get_name_conversion(context, realm, name);
|
||||
if(p == NULL)
|
||||
goto no_host;
|
||||
name = p;
|
||||
p = krb5_config_get_string(context, NULL, "realms", realm,
|
||||
"v4_instance_convert", instance, NULL);
|
||||
if(p){
|
||||
instance = p;
|
||||
ret = krb5_make_principal(context, &pr, realm, name, instance, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
if(func == NULL || (*func)(context, funcctx, pr)){
|
||||
*princ = pr;
|
||||
return 0;
|
||||
}
|
||||
krb5_free_principal(context, pr);
|
||||
*princ = NULL;
|
||||
krb5_clear_error_message (context);
|
||||
return HEIM_ERR_V4_PRINC_NO_CONV;
|
||||
}
|
||||
if(resolve){
|
||||
krb5_boolean passed = FALSE;
|
||||
char *inst = NULL;
|
||||
#ifdef USE_RESOLVER
|
||||
struct rk_dns_reply *r;
|
||||
|
||||
r = rk_dns_lookup(instance, "aaaa");
|
||||
if (r) {
|
||||
if (r->head && r->head->type == rk_ns_t_aaaa) {
|
||||
inst = strdup(r->head->domain);
|
||||
passed = TRUE;
|
||||
}
|
||||
rk_dns_free_data(r);
|
||||
} else {
|
||||
r = rk_dns_lookup(instance, "a");
|
||||
if (r) {
|
||||
if(r->head && r->head->type == rk_ns_t_a) {
|
||||
inst = strdup(r->head->domain);
|
||||
passed = TRUE;
|
||||
}
|
||||
rk_dns_free_data(r);
|
||||
}
|
||||
}
|
||||
#else
|
||||
struct addrinfo hints, *ai;
|
||||
|
||||
memset (&hints, 0, sizeof(hints));
|
||||
hints.ai_flags = AI_CANONNAME;
|
||||
ret = getaddrinfo(instance, NULL, &hints, &ai);
|
||||
if (ret == 0) {
|
||||
const struct addrinfo *a;
|
||||
for (a = ai; a != NULL; a = a->ai_next) {
|
||||
if (a->ai_canonname != NULL) {
|
||||
inst = strdup (a->ai_canonname);
|
||||
passed = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
freeaddrinfo (ai);
|
||||
}
|
||||
#endif
|
||||
if (passed) {
|
||||
if (inst == NULL) {
|
||||
krb5_set_error_message(context, ENOMEM,
|
||||
N_("malloc: out of memory", ""));
|
||||
return ENOMEM;
|
||||
}
|
||||
strlwr(inst);
|
||||
ret = krb5_make_principal(context, &pr, realm, name, inst,
|
||||
NULL);
|
||||
free (inst);
|
||||
if(ret == 0) {
|
||||
if(func == NULL || (*func)(context, funcctx, pr)){
|
||||
*princ = pr;
|
||||
return 0;
|
||||
}
|
||||
krb5_free_principal(context, pr);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(func != NULL) {
|
||||
snprintf(host, sizeof(host), "%s.%s", instance, realm);
|
||||
strlwr(host);
|
||||
ret = krb5_make_principal(context, &pr, realm, name, host, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
if((*func)(context, funcctx, pr)){
|
||||
*princ = pr;
|
||||
return 0;
|
||||
}
|
||||
krb5_free_principal(context, pr);
|
||||
}
|
||||
|
||||
/*
|
||||
* if the instance is the first component of the local hostname,
|
||||
* the converted host should be the long hostname.
|
||||
*/
|
||||
|
||||
if (func == NULL &&
|
||||
gethostname (local_hostname, sizeof(local_hostname)) == 0 &&
|
||||
strncmp(instance, local_hostname, strlen(instance)) == 0 &&
|
||||
local_hostname[strlen(instance)] == '.') {
|
||||
strlcpy(host, local_hostname, sizeof(host));
|
||||
goto local_host;
|
||||
}
|
||||
|
||||
{
|
||||
char **domains, **d;
|
||||
domains = krb5_config_get_strings(context, NULL, "realms", realm,
|
||||
"v4_domains", NULL);
|
||||
for(d = domains; d && *d; d++){
|
||||
snprintf(host, sizeof(host), "%s.%s", instance, *d);
|
||||
ret = krb5_make_principal(context, &pr, realm, name, host, NULL);
|
||||
if (ret) {
|
||||
krb5_config_free_strings(domains);
|
||||
return ret;
|
||||
}
|
||||
if(func == NULL || (*func)(context, funcctx, pr)){
|
||||
*princ = pr;
|
||||
krb5_config_free_strings(domains);
|
||||
return 0;
|
||||
}
|
||||
krb5_free_principal(context, pr);
|
||||
}
|
||||
krb5_config_free_strings(domains);
|
||||
}
|
||||
|
||||
|
||||
p = krb5_config_get_string(context, NULL, "realms", realm,
|
||||
"default_domain", NULL);
|
||||
if(p == NULL){
|
||||
/* this should be an error, just faking a name is not good */
|
||||
krb5_clear_error_message (context);
|
||||
return HEIM_ERR_V4_PRINC_NO_CONV;
|
||||
}
|
||||
|
||||
if (*p == '.')
|
||||
++p;
|
||||
snprintf(host, sizeof(host), "%s.%s", instance, p);
|
||||
local_host:
|
||||
ret = krb5_make_principal(context, &pr, realm, name, host, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
if(func == NULL || (*func)(context, funcctx, pr)){
|
||||
*princ = pr;
|
||||
return 0;
|
||||
}
|
||||
krb5_free_principal(context, pr);
|
||||
krb5_clear_error_message (context);
|
||||
return HEIM_ERR_V4_PRINC_NO_CONV;
|
||||
no_host:
|
||||
p = krb5_config_get_string(context, NULL,
|
||||
"realms",
|
||||
realm,
|
||||
"v4_name_convert",
|
||||
"plain",
|
||||
name,
|
||||
NULL);
|
||||
if(p == NULL)
|
||||
p = krb5_config_get_string(context, NULL,
|
||||
"libdefaults",
|
||||
"v4_name_convert",
|
||||
"plain",
|
||||
name,
|
||||
NULL);
|
||||
if(p)
|
||||
name = p;
|
||||
|
||||
ret = krb5_make_principal(context, &pr, realm, name, instance, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
if(func == NULL || (*func)(context, funcctx, pr)){
|
||||
*princ = pr;
|
||||
return 0;
|
||||
}
|
||||
krb5_free_principal(context, pr);
|
||||
krb5_clear_error_message (context);
|
||||
return HEIM_ERR_V4_PRINC_NO_CONV;
|
||||
}
|
||||
|
||||
#endif /* KRB4 */
|
||||
|
||||
#ifndef HEIMDAL_SMALLER
|
||||
|
||||
static int
|
||||
check_list(const krb5_config_binding *l, const char *name, const char **out)
|
||||
{
|
||||
while(l){
|
||||
if (l->type != krb5_config_string)
|
||||
continue;
|
||||
if(strcmp(name, l->u.string) == 0) {
|
||||
*out = l->name;
|
||||
return 1;
|
||||
}
|
||||
l = l->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
name_convert(krb5_context context, const char *name, const char *realm,
|
||||
const char **out)
|
||||
{
|
||||
const krb5_config_binding *l;
|
||||
l = krb5_config_get_list (context,
|
||||
NULL,
|
||||
"realms",
|
||||
realm,
|
||||
"v4_name_convert",
|
||||
"host",
|
||||
NULL);
|
||||
if(l && check_list(l, name, out))
|
||||
return KRB5_NT_SRV_HST;
|
||||
l = krb5_config_get_list (context,
|
||||
NULL,
|
||||
"libdefaults",
|
||||
"v4_name_convert",
|
||||
"host",
|
||||
NULL);
|
||||
if(l && check_list(l, name, out))
|
||||
return KRB5_NT_SRV_HST;
|
||||
l = krb5_config_get_list (context,
|
||||
NULL,
|
||||
"realms",
|
||||
realm,
|
||||
"v4_name_convert",
|
||||
"plain",
|
||||
NULL);
|
||||
if(l && check_list(l, name, out))
|
||||
return KRB5_NT_UNKNOWN;
|
||||
l = krb5_config_get_list (context,
|
||||
NULL,
|
||||
"libdefaults",
|
||||
"v4_name_convert",
|
||||
"host",
|
||||
NULL);
|
||||
if(l && check_list(l, name, out))
|
||||
return KRB5_NT_UNKNOWN;
|
||||
|
||||
/* didn't find it in config file, try built-in list */
|
||||
#ifdef KRB4
|
||||
{
|
||||
struct v4_name_convert *q;
|
||||
for(q = default_v4_name_convert; q->from; q++) {
|
||||
if(strcmp(name, q->to) == 0) {
|
||||
*out = q->from;
|
||||
return KRB5_NT_SRV_HST;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* convert the v5 principal in `principal' into a v4 corresponding one
|
||||
* in `name, instance, realm'
|
||||
* this is limited interface since there's no length given for these
|
||||
* three parameters. They have to be 40 bytes each (ANAME_SZ).
|
||||
*/
|
||||
|
||||
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
|
||||
krb5_524_conv_principal(krb5_context context,
|
||||
const krb5_principal principal,
|
||||
char *name,
|
||||
char *instance,
|
||||
char *realm)
|
||||
{
|
||||
const char *n, *i, *r;
|
||||
char tmpinst[40];
|
||||
int type = princ_type(principal);
|
||||
const int aname_sz = 40;
|
||||
|
||||
r = principal->realm;
|
||||
|
||||
switch(principal->name.name_string.len){
|
||||
case 1:
|
||||
n = principal->name.name_string.val[0];
|
||||
i = "";
|
||||
break;
|
||||
case 2:
|
||||
n = principal->name.name_string.val[0];
|
||||
i = principal->name.name_string.val[1];
|
||||
break;
|
||||
default:
|
||||
krb5_set_error_message(context, KRB5_PARSE_MALFORMED,
|
||||
N_("cannot convert a %d "
|
||||
"component principal", ""),
|
||||
principal->name.name_string.len);
|
||||
return KRB5_PARSE_MALFORMED;
|
||||
}
|
||||
|
||||
{
|
||||
const char *tmp;
|
||||
int t = name_convert(context, n, r, &tmp);
|
||||
if(t >= 0) {
|
||||
type = t;
|
||||
n = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
if(type == KRB5_NT_SRV_HST){
|
||||
char *p;
|
||||
|
||||
strlcpy (tmpinst, i, sizeof(tmpinst));
|
||||
p = strchr(tmpinst, '.');
|
||||
if(p)
|
||||
*p = 0;
|
||||
i = tmpinst;
|
||||
}
|
||||
|
||||
if (strlcpy (name, n, aname_sz) >= aname_sz) {
|
||||
krb5_set_error_message(context, KRB5_PARSE_MALFORMED,
|
||||
N_("too long name component to convert", ""));
|
||||
return KRB5_PARSE_MALFORMED;
|
||||
}
|
||||
if (strlcpy (instance, i, aname_sz) >= aname_sz) {
|
||||
krb5_set_error_message(context, KRB5_PARSE_MALFORMED,
|
||||
N_("too long instance component to convert", ""));
|
||||
return KRB5_PARSE_MALFORMED;
|
||||
}
|
||||
if (strlcpy (realm, r, aname_sz) >= aname_sz) {
|
||||
krb5_set_error_message(context, KRB5_PARSE_MALFORMED,
|
||||
N_("too long realm component to convert", ""));
|
||||
return KRB5_PARSE_MALFORMED;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* !HEIMDAL_SMALLER */
|
||||
|
||||
/**
|
||||
* Create a principal for the service running on hostname. If
|
||||
* KRB5_NT_SRV_HST is used, the hostname is canonization using DNS (or
|
||||
|
@@ -1,960 +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 "krb5_locl.h"
|
||||
|
||||
#include "krb5-v4compat.h"
|
||||
|
||||
#ifndef HEIMDAL_SMALLER
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
#define RCHECK(r,func,label) \
|
||||
do { (r) = func ; if (r) goto label; } while(0);
|
||||
|
||||
|
||||
/* include this here, to avoid dependencies on libkrb */
|
||||
|
||||
static const int _tkt_lifetimes[TKTLIFENUMFIXED] = {
|
||||
38400, 41055, 43894, 46929, 50174, 53643, 57352, 61318,
|
||||
65558, 70091, 74937, 80119, 85658, 91581, 97914, 104684,
|
||||
111922, 119661, 127935, 136781, 146239, 156350, 167161, 178720,
|
||||
191077, 204289, 218415, 233517, 249664, 266926, 285383, 305116,
|
||||
326213, 348769, 372885, 398668, 426234, 455705, 487215, 520904,
|
||||
556921, 595430, 636601, 680618, 727680, 777995, 831789, 889303,
|
||||
950794, 1016537, 1086825, 1161973, 1242318, 1328218, 1420057, 1518247,
|
||||
1623226, 1735464, 1855462, 1983758, 2120925, 2267576, 2424367, 2592000
|
||||
};
|
||||
|
||||
KRB5_LIB_FUNCTION int KRB5_LIB_CALL
|
||||
_krb5_krb_time_to_life(time_t start, time_t end)
|
||||
{
|
||||
int i;
|
||||
time_t life = end - start;
|
||||
|
||||
if (life > MAXTKTLIFETIME || life <= 0)
|
||||
return 0;
|
||||
#if 0
|
||||
if (krb_no_long_lifetimes)
|
||||
return (life + 5*60 - 1)/(5*60);
|
||||
#endif
|
||||
|
||||
if (end >= NEVERDATE)
|
||||
return TKTLIFENOEXPIRE;
|
||||
if (life < _tkt_lifetimes[0])
|
||||
return (life + 5*60 - 1)/(5*60);
|
||||
for (i=0; i<TKTLIFENUMFIXED; i++)
|
||||
if (life <= _tkt_lifetimes[i])
|
||||
return i + TKTLIFEMINFIXED;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
KRB5_LIB_FUNCTION time_t KRB5_LIB_CALL
|
||||
_krb5_krb_life_to_time(int start, int life_)
|
||||
{
|
||||
unsigned char life = (unsigned char) life_;
|
||||
|
||||
#if 0
|
||||
if (krb_no_long_lifetimes)
|
||||
return start + life*5*60;
|
||||
#endif
|
||||
|
||||
if (life == TKTLIFENOEXPIRE)
|
||||
return NEVERDATE;
|
||||
if (life < TKTLIFEMINFIXED)
|
||||
return start + life*5*60;
|
||||
if (life > TKTLIFEMAXFIXED)
|
||||
return start + MAXTKTLIFETIME;
|
||||
return start + _tkt_lifetimes[life - TKTLIFEMINFIXED];
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the name of the krb4 credentials cache, will use `tkfile' as
|
||||
* the name if that is passed in. `cc' must be free()ed by caller,
|
||||
*/
|
||||
|
||||
static krb5_error_code
|
||||
get_krb4_cc_name(const char *tkfile, char **cc)
|
||||
{
|
||||
|
||||
*cc = NULL;
|
||||
if(tkfile == NULL) {
|
||||
char *path;
|
||||
if(!issuid()) {
|
||||
path = getenv("KRBTKFILE");
|
||||
if (path)
|
||||
*cc = strdup(path);
|
||||
}
|
||||
#ifdef HAVE_GETUID
|
||||
if(*cc == NULL)
|
||||
if (asprintf(cc, "%s%u", TKT_ROOT, (unsigned)getuid()) < 0 || *cc == NULL)
|
||||
return errno;
|
||||
#elif defined(KRB5_USE_PATH_TOKENS)
|
||||
if(*cc == NULL)
|
||||
if (_krb5_expand_path_tokens(NULL, TKT_ROOT "%{uid}", cc))
|
||||
return ENOMEM;
|
||||
#endif
|
||||
} else {
|
||||
*cc = strdup(tkfile);
|
||||
if (*cc == NULL)
|
||||
return ENOMEM;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write a Kerberos 4 ticket file
|
||||
*/
|
||||
|
||||
#define KRB5_TF_LCK_RETRY_COUNT 50
|
||||
#define KRB5_TF_LCK_RETRY 1
|
||||
|
||||
static krb5_error_code
|
||||
write_v4_cc(krb5_context context, const char *tkfile,
|
||||
krb5_storage *sp, int append)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
struct stat sb;
|
||||
krb5_data data;
|
||||
char *path;
|
||||
int fd, i;
|
||||
|
||||
ret = get_krb4_cc_name(tkfile, &path);
|
||||
if (ret) {
|
||||
krb5_set_error_message(context, ret,
|
||||
N_("Failed getting the krb4 credentials "
|
||||
"cache name", ""));
|
||||
return ret;
|
||||
}
|
||||
|
||||
fd = open(path, O_WRONLY|O_CREAT, 0600);
|
||||
if (fd < 0) {
|
||||
ret = errno;
|
||||
krb5_set_error_message(context, ret,
|
||||
N_("Failed opening krb4 credential cache "
|
||||
"%s: %s", "path, error"),
|
||||
path, strerror(ret));
|
||||
free(path);
|
||||
return ret;
|
||||
}
|
||||
rk_cloexec(fd);
|
||||
|
||||
if (fstat(fd, &sb) != 0 || !S_ISREG(sb.st_mode)) {
|
||||
krb5_set_error_message(context, ret,
|
||||
N_("krb4 credential cache %s is not a file", ""),
|
||||
path);
|
||||
free(path);
|
||||
close(fd);
|
||||
return KRB5_FCC_PERM;
|
||||
}
|
||||
|
||||
for (i = 0; i < KRB5_TF_LCK_RETRY_COUNT; i++) {
|
||||
if (flock(fd, LOCK_EX | LOCK_NB) < 0) {
|
||||
sleep(KRB5_TF_LCK_RETRY);
|
||||
} else
|
||||
break;
|
||||
}
|
||||
if (i == KRB5_TF_LCK_RETRY_COUNT) {
|
||||
krb5_set_error_message(context, KRB5_FCC_PERM,
|
||||
N_("Failed to lock credentail cache %s", ""),
|
||||
path);
|
||||
free(path);
|
||||
close(fd);
|
||||
return KRB5_FCC_PERM;
|
||||
}
|
||||
|
||||
if (!append) {
|
||||
ret = ftruncate(fd, 0);
|
||||
if (ret < 0) {
|
||||
flock(fd, LOCK_UN);
|
||||
krb5_set_error_message(context, KRB5_FCC_PERM,
|
||||
N_("Failed to truncate krb4 cc %s", ""),
|
||||
path);
|
||||
free(path);
|
||||
close(fd);
|
||||
return KRB5_FCC_PERM;
|
||||
}
|
||||
}
|
||||
ret = lseek(fd, 0L, SEEK_END);
|
||||
if (ret < 0) {
|
||||
ret = errno;
|
||||
flock(fd, LOCK_UN);
|
||||
free(path);
|
||||
close(fd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
krb5_storage_to_data(sp, &data);
|
||||
|
||||
ret = write(fd, data.data, data.length);
|
||||
if (ret != data.length)
|
||||
ret = KRB5_CC_IO;
|
||||
else
|
||||
ret = 0;
|
||||
|
||||
krb5_data_free(&data);
|
||||
|
||||
flock(fd, LOCK_UN);
|
||||
free(path);
|
||||
close(fd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
|
||||
_krb5_krb_tf_setup(krb5_context context,
|
||||
struct credentials *v4creds,
|
||||
const char *tkfile,
|
||||
int append)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_storage *sp;
|
||||
|
||||
sp = krb5_storage_emem();
|
||||
if (sp == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_HOST);
|
||||
krb5_storage_set_eof_code(sp, KRB5_CC_IO);
|
||||
|
||||
krb5_clear_error_message(context);
|
||||
|
||||
if (!append) {
|
||||
RCHECK(ret, krb5_store_stringz(sp, v4creds->pname), error);
|
||||
RCHECK(ret, krb5_store_stringz(sp, v4creds->pinst), error);
|
||||
}
|
||||
|
||||
/* cred */
|
||||
RCHECK(ret, krb5_store_stringz(sp, v4creds->service), error);
|
||||
RCHECK(ret, krb5_store_stringz(sp, v4creds->instance), error);
|
||||
RCHECK(ret, krb5_store_stringz(sp, v4creds->realm), error);
|
||||
ret = krb5_storage_write(sp, v4creds->session, 8);
|
||||
if (ret != 8) {
|
||||
ret = KRB5_CC_IO;
|
||||
goto error;
|
||||
}
|
||||
RCHECK(ret, krb5_store_int32(sp, v4creds->lifetime), error);
|
||||
RCHECK(ret, krb5_store_int32(sp, v4creds->kvno), error);
|
||||
RCHECK(ret, krb5_store_int32(sp, v4creds->ticket_st.length), error);
|
||||
|
||||
ret = krb5_storage_write(sp, v4creds->ticket_st.dat,
|
||||
v4creds->ticket_st.length);
|
||||
if (ret != v4creds->ticket_st.length) {
|
||||
ret = KRB5_CC_IO;
|
||||
goto error;
|
||||
}
|
||||
RCHECK(ret, krb5_store_int32(sp, v4creds->issue_date), error);
|
||||
|
||||
ret = write_v4_cc(context, tkfile, sp, append);
|
||||
|
||||
error:
|
||||
krb5_storage_free(sp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
|
||||
_krb5_krb_dest_tkt(krb5_context context, const char *tkfile)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
char *path;
|
||||
|
||||
ret = get_krb4_cc_name(tkfile, &path);
|
||||
if (ret) {
|
||||
krb5_set_error_message(context, ret,
|
||||
N_("Failed getting the krb4 credentials "
|
||||
"cache name", ""));
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (unlink(path) < 0) {
|
||||
ret = errno;
|
||||
krb5_set_error_message(context, ret,
|
||||
N_("Failed removing the cache %s "
|
||||
"with error %s", "path, error"),
|
||||
path, strerror(ret));
|
||||
}
|
||||
free(path);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
static krb5_error_code
|
||||
decrypt_etext(krb5_context context, const krb5_keyblock *key,
|
||||
const krb5_data *cdata, krb5_data *data)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_crypto crypto;
|
||||
|
||||
ret = krb5_crypto_init(context, key, ETYPE_DES_PCBC_NONE, &crypto);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = krb5_decrypt(context, crypto, 0, cdata->data, cdata->length, data);
|
||||
krb5_crypto_destroy(context, crypto);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
static const char eightzeros[8] = "\x00\x00\x00\x00\x00\x00\x00\x00";
|
||||
|
||||
static krb5_error_code
|
||||
storage_to_etext(krb5_context context,
|
||||
krb5_storage *sp,
|
||||
const krb5_keyblock *key,
|
||||
krb5_data *enc_data)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_crypto crypto;
|
||||
krb5_ssize_t size;
|
||||
krb5_data data;
|
||||
|
||||
/* multiple of eight bytes, don't round up */
|
||||
|
||||
size = krb5_storage_seek(sp, 0, SEEK_END);
|
||||
if (size < 0)
|
||||
return KRB4ET_RD_AP_UNDEC;
|
||||
size = ((size+7) & ~7) - size;
|
||||
|
||||
ret = krb5_storage_write(sp, eightzeros, size);
|
||||
if (ret != size)
|
||||
return KRB4ET_RD_AP_UNDEC;
|
||||
|
||||
ret = krb5_storage_to_data(sp, &data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = krb5_crypto_init(context, key, ETYPE_DES_PCBC_NONE, &crypto);
|
||||
if (ret) {
|
||||
krb5_data_free(&data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = krb5_encrypt(context, crypto, 0, data.data, data.length, enc_data);
|
||||
|
||||
krb5_data_free(&data);
|
||||
krb5_crypto_destroy(context, crypto);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
static krb5_error_code
|
||||
put_nir(krb5_storage *sp, const char *name,
|
||||
const char *instance, const char *realm)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
|
||||
RCHECK(ret, krb5_store_stringz(sp, name), error);
|
||||
RCHECK(ret, krb5_store_stringz(sp, instance), error);
|
||||
if (realm) {
|
||||
RCHECK(ret, krb5_store_stringz(sp, realm), error);
|
||||
}
|
||||
error:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
|
||||
_krb5_krb_create_ticket(krb5_context context,
|
||||
unsigned char flags,
|
||||
const char *pname,
|
||||
const char *pinstance,
|
||||
const char *prealm,
|
||||
int32_t paddress,
|
||||
const krb5_keyblock *session,
|
||||
int16_t life,
|
||||
int32_t life_sec,
|
||||
const char *sname,
|
||||
const char *sinstance,
|
||||
const krb5_keyblock *key,
|
||||
krb5_data *enc_data)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_storage *sp;
|
||||
|
||||
krb5_data_zero(enc_data);
|
||||
|
||||
sp = krb5_storage_emem();
|
||||
if (sp == NULL) {
|
||||
krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
|
||||
return ENOMEM;
|
||||
}
|
||||
krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE);
|
||||
|
||||
RCHECK(ret, krb5_store_int8(sp, flags), error);
|
||||
RCHECK(ret, put_nir(sp, pname, pinstance, prealm), error);
|
||||
RCHECK(ret, krb5_store_int32(sp, ntohl(paddress)), error);
|
||||
|
||||
/* session key */
|
||||
ret = krb5_storage_write(sp,
|
||||
session->keyvalue.data,
|
||||
session->keyvalue.length);
|
||||
if (ret != session->keyvalue.length) {
|
||||
ret = KRB4ET_INTK_PROT;
|
||||
goto error;
|
||||
}
|
||||
|
||||
RCHECK(ret, krb5_store_int8(sp, life), error);
|
||||
RCHECK(ret, krb5_store_int32(sp, life_sec), error);
|
||||
RCHECK(ret, put_nir(sp, sname, sinstance, NULL), error);
|
||||
|
||||
ret = storage_to_etext(context, sp, key, enc_data);
|
||||
|
||||
error:
|
||||
krb5_storage_free(sp);
|
||||
if (ret)
|
||||
krb5_set_error_message(context, ret,
|
||||
N_("Failed to encode kerberos 4 ticket", ""));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
|
||||
_krb5_krb_create_ciph(krb5_context context,
|
||||
const krb5_keyblock *session,
|
||||
const char *service,
|
||||
const char *instance,
|
||||
const char *realm,
|
||||
uint32_t life,
|
||||
unsigned char kvno,
|
||||
const krb5_data *ticket,
|
||||
uint32_t kdc_time,
|
||||
const krb5_keyblock *key,
|
||||
krb5_data *enc_data)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_storage *sp;
|
||||
|
||||
krb5_data_zero(enc_data);
|
||||
|
||||
sp = krb5_storage_emem();
|
||||
if (sp == NULL) {
|
||||
krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
|
||||
return ENOMEM;
|
||||
}
|
||||
krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE);
|
||||
|
||||
/* session key */
|
||||
ret = krb5_storage_write(sp,
|
||||
session->keyvalue.data,
|
||||
session->keyvalue.length);
|
||||
if (ret != session->keyvalue.length) {
|
||||
ret = KRB4ET_INTK_PROT;
|
||||
goto error;
|
||||
}
|
||||
|
||||
RCHECK(ret, put_nir(sp, service, instance, realm), error);
|
||||
RCHECK(ret, krb5_store_int8(sp, life), error);
|
||||
RCHECK(ret, krb5_store_int8(sp, kvno), error);
|
||||
RCHECK(ret, krb5_store_int8(sp, ticket->length), error);
|
||||
ret = krb5_storage_write(sp, ticket->data, ticket->length);
|
||||
if (ret != ticket->length) {
|
||||
ret = KRB4ET_INTK_PROT;
|
||||
goto error;
|
||||
}
|
||||
RCHECK(ret, krb5_store_int32(sp, kdc_time), error);
|
||||
|
||||
ret = storage_to_etext(context, sp, key, enc_data);
|
||||
|
||||
error:
|
||||
krb5_storage_free(sp);
|
||||
if (ret)
|
||||
krb5_set_error_message(context, ret,
|
||||
N_("Failed to encode kerberos 4 ticket", ""));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
|
||||
_krb5_krb_create_auth_reply(krb5_context context,
|
||||
const char *pname,
|
||||
const char *pinst,
|
||||
const char *prealm,
|
||||
int32_t time_ws,
|
||||
int n,
|
||||
uint32_t x_date,
|
||||
unsigned char kvno,
|
||||
const krb5_data *cipher,
|
||||
krb5_data *data)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_storage *sp;
|
||||
|
||||
krb5_data_zero(data);
|
||||
|
||||
sp = krb5_storage_emem();
|
||||
if (sp == NULL) {
|
||||
krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
|
||||
return ENOMEM;
|
||||
}
|
||||
krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE);
|
||||
|
||||
RCHECK(ret, krb5_store_int8(sp, KRB_PROT_VERSION), error);
|
||||
RCHECK(ret, krb5_store_int8(sp, AUTH_MSG_KDC_REPLY), error);
|
||||
RCHECK(ret, put_nir(sp, pname, pinst, prealm), error);
|
||||
RCHECK(ret, krb5_store_int32(sp, time_ws), error);
|
||||
RCHECK(ret, krb5_store_int8(sp, n), error);
|
||||
RCHECK(ret, krb5_store_int32(sp, x_date), error);
|
||||
RCHECK(ret, krb5_store_int8(sp, kvno), error);
|
||||
RCHECK(ret, krb5_store_int16(sp, cipher->length), error);
|
||||
ret = krb5_storage_write(sp, cipher->data, cipher->length);
|
||||
if (ret != cipher->length) {
|
||||
ret = KRB4ET_INTK_PROT;
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = krb5_storage_to_data(sp, data);
|
||||
|
||||
error:
|
||||
krb5_storage_free(sp);
|
||||
if (ret)
|
||||
krb5_set_error_message(context, ret,
|
||||
N_("Failed to encode kerberos 4 ticket", ""));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
|
||||
_krb5_krb_cr_err_reply(krb5_context context,
|
||||
const char *name,
|
||||
const char *inst,
|
||||
const char *realm,
|
||||
uint32_t time_ws,
|
||||
uint32_t e,
|
||||
const char *e_string,
|
||||
krb5_data *data)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_storage *sp;
|
||||
|
||||
krb5_data_zero(data);
|
||||
|
||||
if (name == NULL) name = "";
|
||||
if (inst == NULL) inst = "";
|
||||
if (realm == NULL) realm = "";
|
||||
if (e_string == NULL) e_string = "";
|
||||
|
||||
sp = krb5_storage_emem();
|
||||
if (sp == NULL) {
|
||||
krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
|
||||
return ENOMEM;
|
||||
}
|
||||
krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE);
|
||||
|
||||
RCHECK(ret, krb5_store_int8(sp, KRB_PROT_VERSION), error);
|
||||
RCHECK(ret, krb5_store_int8(sp, AUTH_MSG_ERR_REPLY), error);
|
||||
RCHECK(ret, put_nir(sp, name, inst, realm), error);
|
||||
RCHECK(ret, krb5_store_int32(sp, time_ws), error);
|
||||
/* If it is a Kerberos 4 error-code, remove the et BASE */
|
||||
if (e >= ERROR_TABLE_BASE_krb && e <= ERROR_TABLE_BASE_krb + 255)
|
||||
e -= ERROR_TABLE_BASE_krb;
|
||||
RCHECK(ret, krb5_store_int32(sp, e), error);
|
||||
RCHECK(ret, krb5_store_stringz(sp, e_string), error);
|
||||
|
||||
ret = krb5_storage_to_data(sp, data);
|
||||
|
||||
error:
|
||||
krb5_storage_free(sp);
|
||||
if (ret)
|
||||
krb5_set_error_message(context, ret, "Failed to encode kerberos 4 error");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static krb5_error_code
|
||||
get_v4_stringz(krb5_storage *sp, char **str, size_t max_len)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
|
||||
ret = krb5_ret_stringz(sp, str);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (strlen(*str) > max_len) {
|
||||
free(*str);
|
||||
*str = NULL;
|
||||
return KRB4ET_INTK_PROT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
|
||||
_krb5_krb_decomp_ticket(krb5_context context,
|
||||
const krb5_data *enc_ticket,
|
||||
const krb5_keyblock *key,
|
||||
const char *local_realm,
|
||||
char **sname,
|
||||
char **sinstance,
|
||||
struct _krb5_krb_auth_data *ad)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_ssize_t size;
|
||||
krb5_storage *sp = NULL;
|
||||
krb5_data ticket;
|
||||
unsigned char des_key[8];
|
||||
|
||||
memset(ad, 0, sizeof(*ad));
|
||||
krb5_data_zero(&ticket);
|
||||
|
||||
*sname = NULL;
|
||||
*sinstance = NULL;
|
||||
|
||||
RCHECK(ret, decrypt_etext(context, key, enc_ticket, &ticket), error);
|
||||
|
||||
sp = krb5_storage_from_data(&ticket);
|
||||
if (sp == NULL) {
|
||||
krb5_data_free(&ticket);
|
||||
krb5_set_error_message(context, ENOMEM, "alloc: out of memory");
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
krb5_storage_set_eof_code(sp, KRB4ET_INTK_PROT);
|
||||
|
||||
RCHECK(ret, krb5_ret_int8(sp, &ad->k_flags), error);
|
||||
RCHECK(ret, get_v4_stringz(sp, &ad->pname, ANAME_SZ), error);
|
||||
RCHECK(ret, get_v4_stringz(sp, &ad->pinst, INST_SZ), error);
|
||||
RCHECK(ret, get_v4_stringz(sp, &ad->prealm, REALM_SZ), error);
|
||||
RCHECK(ret, krb5_ret_uint32(sp, &ad->address), error);
|
||||
|
||||
size = krb5_storage_read(sp, des_key, sizeof(des_key));
|
||||
if (size != sizeof(des_key)) {
|
||||
ret = KRB4ET_INTK_PROT;
|
||||
goto error;
|
||||
}
|
||||
|
||||
RCHECK(ret, krb5_ret_uint8(sp, &ad->life), error);
|
||||
|
||||
if (ad->k_flags & 1)
|
||||
krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_LE);
|
||||
else
|
||||
krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE);
|
||||
|
||||
RCHECK(ret, krb5_ret_uint32(sp, &ad->time_sec), error);
|
||||
|
||||
RCHECK(ret, get_v4_stringz(sp, sname, ANAME_SZ), error);
|
||||
RCHECK(ret, get_v4_stringz(sp, sinstance, INST_SZ), error);
|
||||
|
||||
ret = krb5_keyblock_init(context, ETYPE_DES_PCBC_NONE,
|
||||
des_key, sizeof(des_key), &ad->session);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
if (strlen(ad->prealm) == 0) {
|
||||
free(ad->prealm);
|
||||
ad->prealm = strdup(local_realm);
|
||||
if (ad->prealm == NULL) {
|
||||
ret = ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
error:
|
||||
memset(des_key, 0, sizeof(des_key));
|
||||
if (sp)
|
||||
krb5_storage_free(sp);
|
||||
krb5_data_free(&ticket);
|
||||
if (ret) {
|
||||
if (*sname) {
|
||||
free(*sname);
|
||||
*sname = NULL;
|
||||
}
|
||||
if (*sinstance) {
|
||||
free(*sinstance);
|
||||
*sinstance = NULL;
|
||||
}
|
||||
_krb5_krb_free_auth_data(context, ad);
|
||||
krb5_set_error_message(context, ret, "Failed to decode v4 ticket");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
|
||||
_krb5_krb_rd_req(krb5_context context,
|
||||
krb5_data *authent,
|
||||
const char *service,
|
||||
const char *instance,
|
||||
const char *local_realm,
|
||||
int32_t from_addr,
|
||||
const krb5_keyblock *key,
|
||||
struct _krb5_krb_auth_data *ad)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_storage *sp;
|
||||
krb5_data ticket, eaut, aut;
|
||||
krb5_ssize_t size;
|
||||
int little_endian;
|
||||
int8_t pvno;
|
||||
int8_t type;
|
||||
int8_t s_kvno;
|
||||
uint8_t ticket_length;
|
||||
uint8_t eaut_length;
|
||||
uint8_t time_5ms;
|
||||
char *realm = NULL;
|
||||
char *sname = NULL;
|
||||
char *sinstance = NULL;
|
||||
char *r_realm = NULL;
|
||||
char *r_name = NULL;
|
||||
char *r_instance = NULL;
|
||||
|
||||
uint32_t r_time_sec; /* Coarse time from authenticator */
|
||||
unsigned long delta_t; /* Time in authenticator - local time */
|
||||
long tkt_age; /* Age of ticket */
|
||||
|
||||
struct timeval tv;
|
||||
|
||||
krb5_data_zero(&ticket);
|
||||
krb5_data_zero(&eaut);
|
||||
krb5_data_zero(&aut);
|
||||
|
||||
sp = krb5_storage_from_data(authent);
|
||||
if (sp == NULL) {
|
||||
krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", ""));
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
krb5_storage_set_eof_code(sp, KRB4ET_INTK_PROT);
|
||||
|
||||
ret = krb5_ret_int8(sp, &pvno);
|
||||
if (ret) {
|
||||
krb5_set_error_message(context, ret, N_("Failed reading v4 pvno", ""));
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (pvno != KRB_PROT_VERSION) {
|
||||
ret = KRB4ET_RD_AP_VERSION;
|
||||
krb5_set_error_message(context, ret, N_("Failed v4 pvno not 4", ""));
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = krb5_ret_int8(sp, &type);
|
||||
if (ret) {
|
||||
krb5_set_error_message(context, ret, N_("Failed readin v4 type", ""));
|
||||
goto error;
|
||||
}
|
||||
|
||||
little_endian = type & 1;
|
||||
type &= ~1;
|
||||
|
||||
if(type != AUTH_MSG_APPL_REQUEST && type != AUTH_MSG_APPL_REQUEST_MUTUAL) {
|
||||
ret = KRB4ET_RD_AP_MSG_TYPE;
|
||||
krb5_set_error_message(context, ret,
|
||||
N_("Not a valid v4 request type", ""));
|
||||
goto error;
|
||||
}
|
||||
|
||||
RCHECK(ret, krb5_ret_int8(sp, &s_kvno), error);
|
||||
RCHECK(ret, get_v4_stringz(sp, &realm, REALM_SZ), error);
|
||||
RCHECK(ret, krb5_ret_uint8(sp, &ticket_length), error);
|
||||
RCHECK(ret, krb5_ret_uint8(sp, &eaut_length), error);
|
||||
RCHECK(ret, krb5_data_alloc(&ticket, ticket_length), error);
|
||||
|
||||
size = krb5_storage_read(sp, ticket.data, ticket.length);
|
||||
if (size != ticket.length) {
|
||||
ret = KRB4ET_INTK_PROT;
|
||||
krb5_set_error_message(context, ret, N_("Failed reading v4 ticket", ""));
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Decrypt and take apart ticket */
|
||||
ret = _krb5_krb_decomp_ticket(context, &ticket, key, local_realm,
|
||||
&sname, &sinstance, ad);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
RCHECK(ret, krb5_data_alloc(&eaut, eaut_length), error);
|
||||
|
||||
size = krb5_storage_read(sp, eaut.data, eaut.length);
|
||||
if (size != eaut.length) {
|
||||
ret = KRB4ET_INTK_PROT;
|
||||
krb5_set_error_message(context, ret,
|
||||
N_("Failed reading v4 authenticator", ""));
|
||||
goto error;
|
||||
}
|
||||
|
||||
krb5_storage_free(sp);
|
||||
sp = NULL;
|
||||
|
||||
ret = decrypt_etext(context, &ad->session, &eaut, &aut);
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
sp = krb5_storage_from_data(&aut);
|
||||
if (sp == NULL) {
|
||||
ret = ENOMEM;
|
||||
krb5_set_error_message(context, ret, N_("malloc: out of memory", ""));
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (little_endian)
|
||||
krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_LE);
|
||||
else
|
||||
krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE);
|
||||
|
||||
RCHECK(ret, get_v4_stringz(sp, &r_name, ANAME_SZ), error);
|
||||
RCHECK(ret, get_v4_stringz(sp, &r_instance, INST_SZ), error);
|
||||
RCHECK(ret, get_v4_stringz(sp, &r_realm, REALM_SZ), error);
|
||||
|
||||
RCHECK(ret, krb5_ret_uint32(sp, &ad->checksum), error);
|
||||
RCHECK(ret, krb5_ret_uint8(sp, &time_5ms), error);
|
||||
RCHECK(ret, krb5_ret_uint32(sp, &r_time_sec), error);
|
||||
|
||||
if (strcmp(ad->pname, r_name) != 0 ||
|
||||
strcmp(ad->pinst, r_instance) != 0 ||
|
||||
strcmp(ad->prealm, r_realm) != 0) {
|
||||
ret = KRB4ET_RD_AP_INCON;
|
||||
krb5_set_error_message(context, ret, N_("v4 principal mismatch", ""));
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (from_addr && ad->address && from_addr != ad->address) {
|
||||
ret = KRB4ET_RD_AP_BADD;
|
||||
krb5_set_error_message(context, ret,
|
||||
N_("v4 bad address in ticket", ""));
|
||||
goto error;
|
||||
}
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
delta_t = abs((int)(tv.tv_sec - r_time_sec));
|
||||
if (delta_t > CLOCK_SKEW) {
|
||||
ret = KRB4ET_RD_AP_TIME;
|
||||
krb5_set_error_message(context, ret, N_("v4 clock skew", ""));
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Now check for expiration of ticket */
|
||||
|
||||
tkt_age = tv.tv_sec - ad->time_sec;
|
||||
|
||||
if ((tkt_age < 0) && (-tkt_age > CLOCK_SKEW)) {
|
||||
ret = KRB4ET_RD_AP_NYV;
|
||||
krb5_set_error_message(context, ret,
|
||||
N_("v4 clock skew for expiration", ""));
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (tv.tv_sec > _krb5_krb_life_to_time(ad->time_sec, ad->life)) {
|
||||
ret = KRB4ET_RD_AP_EXP;
|
||||
krb5_set_error_message(context, ret, N_("v4 ticket expired", ""));
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
error:
|
||||
krb5_data_free(&ticket);
|
||||
krb5_data_free(&eaut);
|
||||
krb5_data_free(&aut);
|
||||
if (realm)
|
||||
free(realm);
|
||||
if (sname)
|
||||
free(sname);
|
||||
if (sinstance)
|
||||
free(sinstance);
|
||||
if (r_name)
|
||||
free(r_name);
|
||||
if (r_instance)
|
||||
free(r_instance);
|
||||
if (r_realm)
|
||||
free(r_realm);
|
||||
if (sp)
|
||||
krb5_storage_free(sp);
|
||||
|
||||
if (ret)
|
||||
krb5_clear_error_message(context);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
KRB5_LIB_FUNCTION void KRB5_LIB_CALL
|
||||
_krb5_krb_free_auth_data(krb5_context context, struct _krb5_krb_auth_data *ad)
|
||||
{
|
||||
if (ad->pname)
|
||||
free(ad->pname);
|
||||
if (ad->pinst)
|
||||
free(ad->pinst);
|
||||
if (ad->prealm)
|
||||
free(ad->prealm);
|
||||
krb5_free_keyblock_contents(context, &ad->session);
|
||||
memset(ad, 0, sizeof(*ad));
|
||||
}
|
||||
|
||||
#endif /* HEIMDAL_SMALLER */
|
@@ -41,9 +41,6 @@
|
||||
#ifdef KRB5
|
||||
extern const char *heimdal_version;
|
||||
#endif
|
||||
#ifdef KRB4
|
||||
extern const char *krb4_version;
|
||||
#endif
|
||||
#include <version.h>
|
||||
|
||||
int
|
||||
@@ -62,12 +59,6 @@ main(int argc, char **argv)
|
||||
fprintf(f, "#define VERSIONLIST \"");
|
||||
#ifdef KRB5
|
||||
fprintf(f, "%s", heimdal_version);
|
||||
#endif
|
||||
#ifdef KRB4
|
||||
#ifdef KRB5
|
||||
fprintf(f, ", ");
|
||||
#endif
|
||||
fprintf(f, "%s", krb4_version);
|
||||
#endif
|
||||
fprintf(f, "\"\n");
|
||||
fclose(f);
|
||||
|
Reference in New Issue
Block a user