From 013ad17bd66225ad95784cd4ff48b992baef1a01 Mon Sep 17 00:00:00 2001 From: Paul Borman Date: Mon, 29 Oct 1990 16:17:11 +0000 Subject: [PATCH] *** empty log message *** git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@1369 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/krb425/425data.c | 37 +++++ src/lib/krb425/425error.c | 111 ++++++++++++++ src/lib/krb425/des_sched.c | 35 +++++ src/lib/krb425/err_txt.c | 277 +++++++++++++++++++++++++++++++++++ src/lib/krb425/get_cred.c | 104 ++++++++++++++ src/lib/krb425/get_krbhst.c | 62 ++++++++ src/lib/krb425/get_lrealm.c | 45 ++++++ src/lib/krb425/get_phost.c | 40 ++++++ src/lib/krb425/kn_parse.c | 232 ++++++++++++++++++++++++++++++ src/lib/krb425/kntoln.c | 36 +++++ src/lib/krb425/krb425.h | 101 +++++++++++++ src/lib/krb425/krb_err.h | 103 +++++++++++++ src/lib/krb425/kuserok.c | 193 +++++++++++++++++++++++++ src/lib/krb425/mk_priv.c | 79 ++++++++++ src/lib/krb425/mk_req.c | 79 ++++++++++ src/lib/krb425/mk_safe.c | 78 ++++++++++ src/lib/krb425/net_read.c | 58 ++++++++ src/lib/krb425/net_write.c | 51 +++++++ src/lib/krb425/rd_priv.c | 79 ++++++++++ src/lib/krb425/rd_req.c | 172 ++++++++++++++++++++++ src/lib/krb425/rd_safe.c | 78 ++++++++++ src/lib/krb425/realmhost.c | 53 +++++++ src/lib/krb425/recvauth.c | 280 ++++++++++++++++++++++++++++++++++++ src/lib/krb425/sendauth.c | 253 ++++++++++++++++++++++++++++++++ src/lib/krb425/set_key.c | 42 ++++++ 25 files changed, 2678 insertions(+) create mode 100644 src/lib/krb425/425data.c create mode 100644 src/lib/krb425/425error.c create mode 100644 src/lib/krb425/des_sched.c create mode 100644 src/lib/krb425/err_txt.c create mode 100644 src/lib/krb425/get_cred.c create mode 100644 src/lib/krb425/get_krbhst.c create mode 100644 src/lib/krb425/get_lrealm.c create mode 100644 src/lib/krb425/get_phost.c create mode 100644 src/lib/krb425/kn_parse.c create mode 100644 src/lib/krb425/kntoln.c create mode 100644 src/lib/krb425/krb425.h create mode 100644 src/lib/krb425/krb_err.h create mode 100644 src/lib/krb425/kuserok.c create mode 100644 src/lib/krb425/mk_priv.c create mode 100644 src/lib/krb425/mk_req.c create mode 100644 src/lib/krb425/mk_safe.c create mode 100644 src/lib/krb425/net_read.c create mode 100644 src/lib/krb425/net_write.c create mode 100644 src/lib/krb425/rd_priv.c create mode 100644 src/lib/krb425/rd_req.c create mode 100644 src/lib/krb425/rd_safe.c create mode 100644 src/lib/krb425/realmhost.c create mode 100644 src/lib/krb425/recvauth.c create mode 100644 src/lib/krb425/sendauth.c create mode 100644 src/lib/krb425/set_key.c diff --git a/src/lib/krb425/425data.c b/src/lib/krb425/425data.c new file mode 100644 index 000000000..796fad3e3 --- /dev/null +++ b/src/lib/krb425/425data.c @@ -0,0 +1,37 @@ +/* + * $Source$ + * $Author$ + * + * Copyright 1990 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * Common data for krb425 library + */ + +#if !defined(lint) && !defined(SABER) +static char rcsid_425data_c[] = +"$Id$"; +#endif /* !lint & !SABER */ + +#include +#include "krb425.h" + +char _krb425_local_realm[REALM_SZ+1] = { 0 }; +krb5_ccache _krb425_ccache = 0; +int _krb425_error_init = 0; + +#ifdef EBUG +char * +basename(s) +char *s; +{ + char *r; + char *rindex(); + + if (r = rindex(s, '/')) + return(r+1); + return(s); +} +#endif diff --git a/src/lib/krb425/425error.c b/src/lib/krb425/425error.c new file mode 100644 index 000000000..f7494103f --- /dev/null +++ b/src/lib/krb425/425error.c @@ -0,0 +1,111 @@ +/* + * $Source$ + * $Author$ + * + * Copyright 1990 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * convert error codes from v5 to v4 + */ + +#if !defined(lint) && !defined(SABER) +static char rcsid_425error_c[] = +"$Id$"; +#endif /* !lint & !SABER */ + +#include +#include +#include + +int +krb425error(e) +krb5_error_code e; +{ + /* + * This is not a very good switch. + * Probably needs to be rewritten. + */ + switch (e) { + case 0: /* No error */ + return(KSUCCESS); + + case KDC_ERR_NAME_EXP: /* Client's entry in DB expired */ + return(KDC_NAME_EXP); + + case KDC_ERR_SERVICE_EXP: /* Server's entry in DB expired */ + return(KDC_SERVICE_EXP); + + case KDC_ERR_BAD_PVNO: /* Requested pvno not supported */ + return(KDC_PKT_VER); + + case KDC_ERR_C_OLD_MAST_KVNO: /* C's key encrypted in old master */ + return(KDC_P_MKEY_VER); + + case KDC_ERR_S_OLD_MAST_KVNO: /* S's key encrypted in old master */ + return(KDC_S_MKEY_VER); + + case KDC_ERR_C_PRINCIPAL_UNKNOWN:/* Client not found in Kerberos DB */ + case KDC_ERR_S_PRINCIPAL_UNKNOWN:/* Server not found in Kerberos DB */ + return(KDC_PR_UNKNOWN); + + case KDC_ERR_PRINCIPAL_NOT_UNIQUE:/* Multiple entries in Kerberos DB */ + return(KDC_PR_N_UNIQUE); + + case KDC_ERR_NULL_KEY: /* The C or S has a null key */ + return(KDC_NULL_KEY); + + case KDC_ERR_CANNOT_POSTDATE: /* Tkt ineligible for postdating */ + case KDC_ERR_NEVER_VALID: /* Requested starttime > endtime */ + case KDC_ERR_POLICY: /* KDC policy rejects request */ + case KDC_ERR_BADOPTION: /* KDC can't do requested opt. */ + case KDC_ERR_ETYPE_NOSUPP: /* No support for encryption type */ + return(KDC_GEN_ERR); + + case KRB_AP_ERR_BAD_INTEGRITY: /* Decrypt integrity check failed */ + return(RD_AP_UNDEC); + + case KRB_AP_ERR_TKT_EXPIRED: /* Ticket expired */ + return(RD_AP_EXP); + + case KRB_AP_ERR_TKT_NYV: /* Ticket not yet valid */ + return(RD_AP_NYV); + + case KRB_AP_ERR_REPEAT: /* Request is a replay */ + return(RD_AP_REPEAT); + + case KRB_AP_ERR_NOT_US: /* The ticket isn't for us */ + return(RD_AP_NOT_US); + + case KRB_AP_ERR_BADMATCH: /* Ticket/authenticator don't match */ + return(RD_AP_INCON); + + case KRB_AP_ERR_SKEW: /* Clock skew too great */ + return(RD_AP_TIME); + + case KRB_AP_ERR_BADADDR: /* Incorrect net address */ + return(RD_AP_BADD); + + case KRB_AP_ERR_BADVERSION: /* Protocol version mismatch */ + return(RD_AP_VERSION); + + case KRB_AP_ERR_MSG_TYPE: /* Invalid message type */ + return(RD_AP_MSG_TYPE); + + case KRB_AP_ERR_MODIFIED: /* Message stream modified */ + return(RD_AP_MODIFIED); + + case KRB_AP_ERR_BADORDER: /* Message out of order */ + return(RD_AP_ORDER); + + case KRB_AP_ERR_BADKEYVER: /* Key version is not available */ + case KRB_AP_ERR_NOKEY: /* Service key not available */ + case KRB_AP_ERR_MUT_FAIL: /* Mutual authentication failed */ + return(RD_AP_INCON); + + case KRB_ERR_FIELD_TOOLONG: /* Field is too long for impl. */ + default: + return(KFAILURE); + } +} diff --git a/src/lib/krb425/des_sched.c b/src/lib/krb425/des_sched.c new file mode 100644 index 000000000..c1d13e769 --- /dev/null +++ b/src/lib/krb425/des_sched.c @@ -0,0 +1,35 @@ +/* + * $Source$ + * $Author$ + * + * Copyright 1990 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * dummy function for krb425 + */ + +#if !defined(lint) && !defined(SABER) +static char rcsid_des_sched_c[] = +"$Id$"; +#endif /* !lint & !SABER */ + +#include +#include "krb425.h" + +/* + * This is a no-op because V5 will always creates it when needed. + */ +int +des_key_sched(k, s) +des_cblock k; +des_key_schedule s; +{ + /* + * Use the variables so saber does not get mad... + */ + if (k || s) + return(0); + return(0); +} diff --git a/src/lib/krb425/err_txt.c b/src/lib/krb425/err_txt.c new file mode 100644 index 000000000..dca93ef09 --- /dev/null +++ b/src/lib/krb425/err_txt.c @@ -0,0 +1,277 @@ +/* + * $Source$ + * $Author$ + * + * Copyright 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + */ + + +#include + +/* + * This file contains an array of error text strings. + * The associated error codes (which are defined in "krb.h") + * follow the string in the comments at the end of each line. + */ + +char *krb_err_txt[256] = { + "OK", /* 000 */ + "Principal expired (kerberos)", /* 001 */ + "Service expired (kerberos)", /* 002 */ + "Authentication expired (kerberos)", /* 003 */ + "Unknown protocol version number (kerberos)", /* 004 */ + "Principal: Incorrect master key version (kerberos)", /* 005 */ + "Service: Incorrect master key version (kerberos)", /* 006 */ + "Bad byte order (kerberos)", /* 007 */ + "Principal unknown (kerberos)", /* 008 */ + "Principal not unique (kerberos)", /* 009 */ + "Principal has null key (kerberos)", /* 010 */ + "Reserved error message 11 (kerberos)", /* 011 */ + "Reserved error message 12 (kerberos)", /* 012 */ + "Reserved error message 13 (kerberos)", /* 013 */ + "Reserved error message 14 (kerberos)", /* 014 */ + "Reserved error message 15 (kerberos)", /* 015 */ + "Reserved error message 16 (kerberos)", /* 016 */ + "Reserved error message 17 (kerberos)", /* 017 */ + "Reserved error message 18 (kerberos)", /* 018 */ + "Reserved error message 19 (kerberos)", /* 019 */ + "Permission Denied (kerberos)", /* 020 */ + "Can't read ticket file (krb_get_cred)", /* 021 */ + "Can't find ticket (krb_get_cred)", /* 022 */ + "Reserved error message 23 (krb_get_cred)", /* 023 */ + "Reserved error message 24 (krb_get_cred)", /* 024 */ + "Reserved error message 25 (krb_get_cred)", /* 025 */ + "Ticket granting ticket expired (krb_mk_req)", /* 026 */ + "Reserved error message 27 (krb_mk_req)", /* 027 */ + "Reserved error message 28 (krb_mk_req)", /* 028 */ + "Reserved error message 29 (krb_mk_req)", /* 029 */ + "Reserved error message 30 (krb_mk_req)", /* 030 */ + "Can't decode authenticator (krb_rd_req)", /* 031 */ + "Ticket expired (krb_rd_req)", /* 032 */ + "Ticket issue date too far in the future (krb_rd_req)",/* 033 */ + "Repeat request (krb_rd_req)", /* 034 */ + "Ticket for wrong server (krb_rd_req)", /* 035 */ + "Request inconsistent (krb_rd_req)", /* 036 */ + "Time is out of bounds (krb_rd_req)", /* 037 */ + "Incorrect network address (krb_rd_req)", /* 038 */ + "Protocol version mismatch (krb_rd_req)", /* 039 */ + "Illegal message type (krb_rd_req)", /* 040 */ + "Message integrity error (krb_rd_req)", /* 041 */ + "Message duplicate or out of order (krb_rd_req)", /* 042 */ + "Unauthorized request (krb_rd_req)", /* 043 */ + "Reserved error message 44 (krb_rd_req)", /* 044 */ + "Reserved error message 45 (krb_rd_req)", /* 045 */ + "Reserved error message 46 (krb_rd_req)", /* 046 */ + "Reserved error message 47 (krb_rd_req)", /* 047 */ + "Reserved error message 48 (krb_rd_req)", /* 048 */ + "Reserved error message 49 (krb_rd_req)", /* 049 */ + "Reserved error message 50 (krb_rd_req)", /* 050 */ + "Current password is NULL (get_pw_tkt)", /* 051 */ + "Current password incorrect (get_pw_tkt)", /* 052 */ + "Protocol error (gt_pw_tkt)", /* 053 */ + "Error returned by KDC (gt_pw_tkt)", /* 054 */ + "Null ticket returned by KDC (gt_pw_tkt)", /* 055 */ + "Retry count exceeded (send_to_kdc)", /* 056 */ + "Can't send request (send_to_kdc)", /* 057 */ + "Reserved error message 58 (send_to_kdc)", /* 058 */ + "Reserved error message 59 (send_to_kdc)", /* 059 */ + "Reserved error message 60 (send_to_kdc)", /* 060 */ + "Warning: Not ALL tickets returned", /* 061 */ + "Password incorrect", /* 062 */ + "Protocol error (get_intkt)", /* 063 */ + "Reserved error message 64 (get_in_tkt)", /* 064 */ + "Reserved error message 65 (get_in_tkt)", /* 065 */ + "Reserved error message 66 (get_in_tkt)", /* 066 */ + "Reserved error message 67 (get_in_tkt)", /* 067 */ + "Reserved error message 68 (get_in_tkt)", /* 068 */ + "Reserved error message 69 (get_in_tkt)", /* 069 */ + "Generic error (get_intkt)", /* 070 */ + "Don't have ticket granting ticket (get_ad_tkt)", /* 071 */ + "Reserved error message 72 (get_ad_tkt)", /* 072 */ + "Reserved error message 73 (get_ad_tkt)", /* 073 */ + "Reserved error message 74 (get_ad_tkt)", /* 074 */ + "Reserved error message 75 (get_ad_tkt)", /* 075 */ + "No ticket file (tf_util)", /* 076 */ + "Can't access ticket file (tf_util)", /* 077 */ + "Can't lock ticket file; try later (tf_util)", /* 078 */ + "Bad ticket file format (tf_util)", /* 079 */ + "Read ticket file before tf_init (tf_util)", /* 080 */ + "Bad Kerberos name format (kname_parse)", /* 081 */ + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "(reserved)", + "Generic kerberos error (kfailure)", /* 255 */ +}; diff --git a/src/lib/krb425/get_cred.c b/src/lib/krb425/get_cred.c new file mode 100644 index 000000000..21b3d31f8 --- /dev/null +++ b/src/lib/krb425/get_cred.c @@ -0,0 +1,104 @@ +/* + * $Source$ + * $Author$ + * + * Copyright 1990 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * krb_get_cred for krb425 + */ + +#if !defined(lint) && !defined(SABER) +static char rcsid_get_cred_c[] = +"$Id$"; +#endif /* !lint & !SABER */ + +#include +#include "krb425.h" + +int +krb_get_cred(service, instance, realm, c) +char *service; +char *instance; +char *realm; +CREDENTIALS *c; +{ + static krb5_principal client_principal = { 0 }; + + krb5_creds creds; + krb5_data *server[4]; + krb5_data srvdata[3]; + krb5_error_code r; + krb5_ticket *ticket; + + set_data5(srvdata[0], realm); + set_data5(srvdata[1], service); + set_data5(srvdata[2], instance); + + server[0] = &srvdata[0]; + server[1] = &srvdata[1]; + server[2] = &srvdata[2]; + server[3] = 0; + + if (!_krb425_ccache) + krb5_cc_default(&_krb425_ccache); + if (!client_principal) + krb5_cc_get_principal(_krb425_ccache, &client_principal); + + creds.client = client_principal; + creds.server = server; + creds.times.endtime = 0; + creds.keyblock.keytype = KEYTYPE_DES; + + if (r = krb5_get_credentials(0, _krb425_ccache, &creds)) + return(krb425error(r)); + +#ifdef EBUG + { + int i; + i = 0; + if (creds.server) + while (creds.server[i]) { + EPRINT "server: %d: ``%.*s''\n", i, + creds.server[i]->length, + creds.server[i]->data + ? creds.server[i]->data : ""); + ++i; + } + i = 0; + if (creds.client) + while (creds.client[i]) { + EPRINT "client: %d: ``%.*s''\n", i, + creds.client[i]->length, + creds.client[i]->data + ? creds.client[i]->data : ""); + ++i; + } + } +#endif + set_string(c->pname, ANAME_SZ, creds.client[1]); + set_string(c->pinst, INST_SZ, creds.client[2]); + + set_string(c->realm, REALM_SZ, creds.server[0]); + set_string(c->service, REALM_SZ, creds.server[1]); + set_string(c->instance, REALM_SZ, creds.server[2]); + + c->ticket_st.length = creds.ticket.length; + bcopy(creds.ticket.data, + c->ticket_st.dat, + min(c->ticket_st.length, MAX_KTXT_LEN)); + c->ticket_st.mbz = 0; + + bcopy(creds.keyblock.contents, + (char*)c->session, sizeof(C_Block)); + + c->issue_date = creds.times.starttime; + c->lifetime = creds.times.endtime; + + decode_krb5_ticket(&creds.ticket, &ticket); + c->kvno = ticket->enc_part.kvno; + krb5_free_ticket(ticket); + return(KSUCCESS); +} diff --git a/src/lib/krb425/get_krbhst.c b/src/lib/krb425/get_krbhst.c new file mode 100644 index 000000000..e02e1fce9 --- /dev/null +++ b/src/lib/krb425/get_krbhst.c @@ -0,0 +1,62 @@ +/* + * $Source$ + * $Author$ + * + * Copyright 1990 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * krb_get_krbhst for krb425 + */ + +#if !defined(lint) && !defined(SABER) +static char rcsid_get_krbhst_c[] = +"$Id$"; +#endif /* !lint & !SABER */ + +#include +#include "krb425.h" + +int +krb_get_krbhst(host, realm, n) +char *host; +char *realm; +int n; +{ + krb5_data realm5; + char **hosts; + krb5_error_code r; + int i = 0; + + if (n < 1) + n = 1; + + set_data5(realm5, realm); + + if (r = krb5_get_krbhst(&realm5, &hosts)) { + return(krb425error(r)); + } + if (!hosts) + return(KFAILURE); + + while (i < n) + if (!hosts[i++]) { + krb5_free_krbhst(hosts); + return(KFAILURE); + } + + strncpy(host, hosts[n-1], REALM_SZ); + krb5_free_krbhst(hosts); + return(KSUCCESS); +} + +#ifdef NOT_IMPLEMENTED +krb_get_admhst(host, realm, n) +char *host; +char *realm; +int n; +{ + +} +#endif diff --git a/src/lib/krb425/get_lrealm.c b/src/lib/krb425/get_lrealm.c new file mode 100644 index 000000000..d4de53c97 --- /dev/null +++ b/src/lib/krb425/get_lrealm.c @@ -0,0 +1,45 @@ +/* + * $Source$ + * $Author$ + * + * Copyright 1990 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * krb_get_lrealm for krb425 + */ + +#if !defined(lint) && !defined(SABER) +static char rcsid_get_lrealm_c[] = +"$Id$"; +#endif /* !lint & !SABER */ + +#include +#include "krb425.h" + +int +krb_get_lrealm(realm, n) +char *realm; +int n; +{ + krb5_error_code r; + char **realms; + int i = 0; + + if (r = krb5_get_host_realm(0, &realms)) + return(krb425error(r)); + + if (!realms) + return(KFAILURE); + + while (i < n) + if (!realms[i++]) { + krb5_free_host_realm(realms); + return(KFAILURE); + } + + strncpy(realm, realms[n-1], REALM_SZ); + krb5_free_host_realm(realms); + return(KSUCCESS); +} diff --git a/src/lib/krb425/get_phost.c b/src/lib/krb425/get_phost.c new file mode 100644 index 000000000..6a60e7f1a --- /dev/null +++ b/src/lib/krb425/get_phost.c @@ -0,0 +1,40 @@ +/* + * $Source$ + * $Author$ + * + * Copyright 1990 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * krb_get_phost for krb425 + */ + +#if !defined(lint) && !defined(SABER) +static char rcsid_get_phost_c[] = +"$Id$"; +#endif /* !lint & !SABER */ + +#include +#include "krb425.h" + +char * +krb_get_phost(alias) +char *alias; +{ + struct hostent *h; + char *phost = alias; + + if ((h = gethostbyname(alias)) != (struct hostent *)0 ) { + char *p; +#ifdef OLD_CRUFT + if (p = index( h->h_name, '.' )) + *p = 0; +#endif + p = phost = h->h_name; + do { + if (isupper(*p)) *p=tolower(*p); + } while (*p++); + } + return(phost); +} diff --git a/src/lib/krb425/kn_parse.c b/src/lib/krb425/kn_parse.c new file mode 100644 index 000000000..664b56af0 --- /dev/null +++ b/src/lib/krb425/kn_parse.c @@ -0,0 +1,232 @@ +/* + * $Source$ + * $Author$ + * + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + */ + +#include + +#include +#include +#include + +/* max size of full name */ +#define FULL_SZ (ANAME_SZ + INST_SZ + REALM_SZ) + +#define NAME 0 /* which field are we in? */ +#define INST 1 +#define REALM 2 + +extern char *krb_err_txt[]; + +/* + * This file contains four routines for handling Kerberos names. + * + * kname_parse() breaks a Kerberos name into its name, instance, + * and realm components. + * + * k_isname(), k_isinst(), and k_isrealm() check a given string to see if + * it's a syntactically legitimate respective part of a Kerberos name, + * returning 1 if it is, 0 if it isn't. + * + * Definition of "syntactically legitimate" names is according to + * the Project Athena Technical Plan Section E.2.1, page 7 "Specifying + * names", version dated 21 Dec 1987. + */ + +/* + * kname_parse() takes a Kerberos name "fullname" of the form: + * + * username[.instance][@realm] + * + * and returns the three components ("name", "instance", and "realm" + * in the example above) in the given arguments "np", "ip", and "rp". + * + * If successful, it returns KSUCCESS. If there was an error, + * KNAME_FMT is returned. + */ + +int +kname_parse(np, ip, rp, fullname) + char *np, *ip, *rp, *fullname; +{ + static char buf[FULL_SZ]; + char *rnext, *wnext; /* next char to read, write */ + register char c; + int backslash; + int field; + + backslash = 0; + rnext = buf; + wnext = np; + field = NAME; + + if (strlen(fullname) > FULL_SZ) + return KNAME_FMT; + (void) strcpy(buf, fullname); + + while (c = *rnext++) { + if (backslash) { + *wnext++ = c; + backslash = 0; + continue; + } + switch (c) { + case '\\': + backslash++; + break; + case '.': + switch (field) { + case NAME: + if (wnext == np) + return KNAME_FMT; + *wnext = '\0'; + field = INST; + wnext = ip; + break; + case INST: + return KNAME_FMT; + /* break; */ + case REALM: + *wnext++ = c; + break; + default: + fprintf(stderr, "unknown field value\n"); + exit(1); + } + break; + case '@': + switch (field) { + case NAME: + if (wnext == np) + return KNAME_FMT; + *ip = '\0'; + /* fall through */ + case INST: + *wnext = '\0'; + field = REALM; + wnext = rp; + break; + case REALM: + return KNAME_FMT; + default: + fprintf(stderr, "unknown field value\n"); + exit(1); + } + break; + default: + *wnext++ = c; + } + } + *wnext = '\0'; + if ((strlen(np) > ANAME_SZ - 1) || + (strlen(ip) > INST_SZ - 1) || + (strlen(rp) > REALM_SZ - 1)) + return KNAME_FMT; + return KSUCCESS; +} + +/* + * k_isname() returns 1 if the given name is a syntactically legitimate + * Kerberos name; returns 0 if it's not. + */ +int +k_isname(s) + char *s; +{ + register char c; + int backslash = 0; + + if (!*s) + return 0; + if (strlen(s) > ANAME_SZ - 1) + return 0; + while(c = *s++) { + if (backslash) { + backslash = 0; + continue; + } + switch(c) { + case '\\': + backslash = 1; + break; + case '.': + return 0; + /* break; */ + case '@': + return 0; + /* break; */ + } + } + return 1; +} + + +/* + * k_isinst() returns 1 if the given name is a syntactically legitimate + * Kerberos instance; returns 0 if it's not. + */ +int +k_isinst(s) + char *s; +{ + register char c; + int backslash = 0; + + if (strlen(s) > INST_SZ - 1) + return 0; + while(c = *s++) { + if (backslash) { + backslash = 0; + continue; + } + switch(c) { + case '\\': + backslash = 1; + break; + case '.': + return 0; + /* break; */ + case '@': + return 0; + /* break; */ + } + } + return 1; +} + +/* + * k_isrealm() returns 1 if the given name is a syntactically legitimate + * Kerberos realm; returns 0 if it's not. + */ +int +k_isrealm(s) + char *s; +{ + register char c; + int backslash = 0; + + if (!*s) + return 0; + if (strlen(s) > REALM_SZ - 1) + return 0; + while(c = *s++) { + if (backslash) { + backslash = 0; + continue; + } + switch(c) { + case '\\': + backslash = 1; + break; + case '@': + return 0; + /* break; */ + } + } + return 1; +} diff --git a/src/lib/krb425/kntoln.c b/src/lib/krb425/kntoln.c new file mode 100644 index 000000000..2a4c8c2f9 --- /dev/null +++ b/src/lib/krb425/kntoln.c @@ -0,0 +1,36 @@ +/* + * $Source$ + * $Author$ + * + * Copyright 1990 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * krb_kntoln for krb425 + */ + +#if !defined(lint) && !defined(SABER) +static char rcsid_kntoln_c[] = +"$Id$"; +#endif /* !lint & !SABER */ + +#include +#include "krb425.h" + +int +krb_kntoln(ad,lname) +AUTH_DAT *ad; +char *lname; +{ + if (!_krb425_local_realm[0]) + krb5_get_default_realm(REALM_SZ, _krb425_local_realm); + + if (strcmp(ad->pinst,"")) + return(KFAILURE); + if (strcmp(ad->prealm, _krb425_local_realm)) + return(KFAILURE); + + (void) strcpy(lname,ad->pname); + return(KSUCCESS); +} diff --git a/src/lib/krb425/krb425.h b/src/lib/krb425/krb425.h new file mode 100644 index 000000000..00c5d2a50 --- /dev/null +++ b/src/lib/krb425/krb425.h @@ -0,0 +1,101 @@ +/* + * $Source$ + * $Author$ + * $Id$ + * + * Copyright 1990 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * krb425.h + */ + + +#ifndef KRB5_krb425__ +#define KRB5_krb425__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef USE_STRING_H +#include +#else +#include +#endif + +#define min(a,b) ((a) < (b) ? (a) : (b)) + +#define set_data5(d5,s) d5.length = strlen(s); d5.data = s + +#define set_cksum(ck,v) { \ + ck.checksum_type = CKSUMTYPE_CRC32; \ + ck.length = sizeof(v); \ + ck.contents = (krb5_octet *)&v; \ +} + +#define set_string(str,sz,d5) { \ + if (d5) { \ + int x; \ + x = min(sz-1, d5->length); \ + strncpy(str, d5->data, x); \ + str[x] = 0; \ + } else \ + str[0] = 0; \ +} + +extern char _krb425_local_realm[REALM_SZ+1]; +extern krb5_ccache _krb425_ccache; +extern int _krb425_error_init; + + +extern int krb425error(); + +extern char *malloc(); +extern char *basename(); +extern int atoi(); +extern void bzero(); +extern void bcopy(); +extern int read(); +extern void free(); +extern int des_key_sched(); +extern int kname_parse(); +extern int krb_get_cred(); +extern int krb_get_lrealm(); +extern int krb_kntoln(); +extern long krb_mk_priv(); +extern int krb_mk_req(); +extern int krb_net_read(); +extern int krb_net_write(); +extern long krb_rd_priv(); +extern int krb_rd_req(); +extern int mit_des_string_to_key(); + + +#ifdef EBUG +#define PLINE { fprintf(stderr, "%26s:%4d\n", basename(__FILE__),__LINE__); \ + fflush(stderr); } +#define show5(x) fprintf(stderr, "``%.*s''", x.length, x.data) +#define EPRINT fprintf(stderr, "%26s:%4d: ", basename(__FILE__), __LINE__), \ + fprintf(stderr, +#define ENEWLINE fprintf(stderr, "\n"); +#define ERROR(error) { \ + if (!_krb425_error_init) { \ + _krb425_error_init = 1; \ + krb5_init_ets(); \ + } \ + fprintf(stderr, "%26s:%4d: %s (%d)\n", basename(__FILE__), __LINE__, \ + error_message(error), error); \ +} +#else +#define PLINE +#endif + +#endif /* KRB5_krb425__ */ + diff --git a/src/lib/krb425/krb_err.h b/src/lib/krb425/krb_err.h new file mode 100644 index 000000000..21bf1e7ca --- /dev/null +++ b/src/lib/krb425/krb_err.h @@ -0,0 +1,103 @@ +/* + * $Source$ + * $Author$ + * $Id$ + * + * Copyright 1990 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * krb_err.h for krb425 + */ + +#ifndef KRB5_KRB_ERR_H__ +#define KRB5_KRB_ERR_H__ + +#include +#define KRBET_KSUCCESS ((int)39525376) +#define KRBET_KDC_NAME_EXP ((int)39525377) +#define KRBET_KDC_SERVICE_EXP ((int)39525378) +#define KRBET_KDC_AUTH_EXP ((int)39525379) +#define KRBET_KDC_PKT_VER ((int)39525380) +#define KRBET_KDC_P_MKEY_VER ((int)39525381) +#define KRBET_KDC_S_MKEY_VER ((int)39525382) +#define KRBET_KDC_BYTE_ORDER ((int)39525383) +#define KRBET_KDC_PR_UNKNOWN ((int)39525384) +#define KRBET_KDC_PR_N_UNIQUE ((int)39525385) +#define KRBET_KDC_NULL_KEY ((int)39525386) +#define KRBET_KRB_RES11 ((int)39525387) +#define KRBET_KRB_RES12 ((int)39525388) +#define KRBET_KRB_RES13 ((int)39525389) +#define KRBET_KRB_RES14 ((int)39525390) +#define KRBET_KRB_RES15 ((int)39525391) +#define KRBET_KRB_RES16 ((int)39525392) +#define KRBET_KRB_RES17 ((int)39525393) +#define KRBET_KRB_RES18 ((int)39525394) +#define KRBET_KRB_RES19 ((int)39525395) +#define KRBET_KDC_GEN_ERR ((int)39525396) +#define KRBET_GC_TKFIL ((int)39525397) +#define KRBET_GC_NOTKT ((int)39525398) +#define KRBET_KRB_RES23 ((int)39525399) +#define KRBET_KRB_RES24 ((int)39525400) +#define KRBET_KRB_RES25 ((int)39525401) +#define KRBET_MK_AP_TGTEXP ((int)39525402) +#define KRBET_KRB_RES27 ((int)39525403) +#define KRBET_KRB_RES28 ((int)39525404) +#define KRBET_KRB_RES29 ((int)39525405) +#define KRBET_KRB_RES30 ((int)39525406) +#define KRBET_RD_AP_UNDEC ((int)39525407) +#define KRBET_RD_AP_EXP ((int)39525408) +#define KRBET_RD_AP_NYV ((int)39525409) +#define KRBET_RD_AP_REPEAT ((int)39525410) +#define KRBET_RD_AP_NOT_US ((int)39525411) +#define KRBET_RD_AP_INCON ((int)39525412) +#define KRBET_RD_AP_TIME ((int)39525413) +#define KRBET_RD_AP_BADD ((int)39525414) +#define KRBET_RD_AP_VERSION ((int)39525415) +#define KRBET_RD_AP_MSG_TYPE ((int)39525416) +#define KRBET_RD_AP_MODIFIED ((int)39525417) +#define KRBET_RD_AP_ORDER ((int)39525418) +#define KRBET_RD_AP_UNAUTHOR ((int)39525419) +#define KRBET_KRB_RES44 ((int)39525420) +#define KRBET_KRB_RES45 ((int)39525421) +#define KRBET_KRB_RES46 ((int)39525422) +#define KRBET_KRB_RES47 ((int)39525423) +#define KRBET_KRB_RES48 ((int)39525424) +#define KRBET_KRB_RES49 ((int)39525425) +#define KRBET_KRB_RES50 ((int)39525426) +#define KRBET_GT_PW_NULL ((int)39525427) +#define KRBET_GT_PW_BADPW ((int)39525428) +#define KRBET_GT_PW_PROT ((int)39525429) +#define KRBET_GT_PW_KDCERR ((int)39525430) +#define KRBET_GT_PW_NULLTKT ((int)39525431) +#define KRBET_SKDC_RETRY ((int)39525432) +#define KRBET_SKDC_CANT ((int)39525433) +#define KRBET_KRB_RES58 ((int)39525434) +#define KRBET_KRB_RES59 ((int)39525435) +#define KRBET_KRB_RES60 ((int)39525436) +#define KRBET_INTK_W_NOTALL ((int)39525437) +#define KRBET_INTK_BADPW ((int)39525438) +#define KRBET_INTK_PROT ((int)39525439) +#define KRBET_KRB_RES64 ((int)39525440) +#define KRBET_KRB_RES65 ((int)39525441) +#define KRBET_KRB_RES66 ((int)39525442) +#define KRBET_KRB_RES67 ((int)39525443) +#define KRBET_KRB_RES68 ((int)39525444) +#define KRBET_KRB_RES69 ((int)39525445) +#define KRBET_INTK_ERR ((int)39525446) +#define KRBET_AD_NOTGT ((int)39525447) +#define KRBET_KRB_RES72 ((int)39525448) +#define KRBET_KRB_RES73 ((int)39525449) +#define KRBET_KRB_RES74 ((int)39525450) +#define KRBET_KRB_RES75 ((int)39525451) +#define KRBET_NO_TKT_FIL ((int)39525452) +#define KRBET_TKT_FIL_ACC ((int)39525453) +#define KRBET_TKT_FIL_LCK ((int)39525454) +#define KRBET_TKT_FIL_FMT ((int)39525455) +#define KRBET_TKT_FIL_INI ((int)39525456) +#define KRBET_KNAME_FMT ((int)39525457) +extern int init_krb_err_tbl(); +extern int krb_err_base; + +#endif /* __KRB5_KRB_ERR_H__ */ diff --git a/src/lib/krb425/kuserok.c b/src/lib/krb425/kuserok.c new file mode 100644 index 000000000..a846f1b72 --- /dev/null +++ b/src/lib/krb425/kuserok.c @@ -0,0 +1,193 @@ +/* + * $Source$ + * $Author$ + * + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * kuserok: check if a kerberos principal has + * access to a local account + */ + +#include "krb425.h" + +#include +#include +#include +#include +#include + +#define OK 0 +#ifdef NOTOK +#undef NOTOK +#endif +#define NOTOK 1 +#define MAX_USERNAME 10 + +/* + * Given a Kerberos principal "kdata", and a local username "luser", + * determine whether user is authorized to login according to the + * authorization file ("~luser/.klogin" by default). Returns OK + * if authorized, NOTOK if not authorized. + * + * If there is no account for "luser" on the local machine, returns + * NOTOK. If there is no authorization file, and the given Kerberos + * name "kdata" translates to the same name as "luser" (using + * krb_kntoln()), returns OK. Otherwise, if the authorization file + * can't be accessed, returns NOTOK. Otherwise, the file is read for + * a matching principal name, instance, and realm. If one is found, + * returns OK, if none is found, returns NOTOK. + * + * The file entries are in the format: + * + * name.instance@realm + * + * one entry per line. + * + * The ATHENA_COMPAT code supports old-style Athena ~luser/.klogin + * file entries. See the file "kparse.c". + */ + +#ifdef ATHENA_COMPAT + + +/* + * The parmtable defines the keywords we will recognize with their + * default values, and keeps a pointer to the found value. The found + * value should be filled in with strsave(), since FreeParameterSet() + * will release memory for all non-NULL found strings. + * +*** NOTE WELL! *** + * + * The table below is very nice, but we cannot hard-code a default for the + * realm: we have to get the realm via krb_get_lrealm(). Even though the + * default shows as "from krb_get_lrealm, below", it gets changed in + * kuserok to whatever krb_get_lrealm() tells us. That code assumes that + * the realm will be the entry number in the table below, so if you + * change the order of the entries below, you have to change the + * #definition of REALM_SCRIPT to reflect it. + */ +#define REALM_SUBSCRIPT 1 +parmtable kparm[] = { + +/* keyword default found value */ +{"user", "", (char *) NULL}, +{"realm", "see krb_get_lrealm, below", (char *) NULL}, +{"instance", "", (char *) NULL}, +}; +#define KPARMS kparm,PARMCOUNT(kparm) +#endif /* ATHENA_COMPAT */ + +int +kuserok(kdata, luser) + AUTH_DAT *kdata; + char *luser; +{ + struct stat sbuf; + struct passwd *pwd; + char pbuf[MAXPATHLEN]; + int isok = NOTOK, rc; + FILE *fp; + char kuser[MAX_USERNAME]; + char principal[ANAME_SZ], inst[INST_SZ], realm[REALM_SZ]; + char linebuf[BUFSIZ]; + char *newline; + int gobble; +#ifdef ATHENA_COMPAT + char local_realm[REALM_SZ]; +#endif /* ATHENA_COMPAT */ + + /* no account => no access */ + if ((pwd = getpwnam(luser)) == NULL) { + return(NOTOK); + } + (void) strcpy(pbuf, pwd->pw_dir); + (void) strcat(pbuf, "/.klogin"); + + if (access(pbuf, F_OK)) { /* not accessible */ + /* + * if he's trying to log in as himself, and there is no .klogin file, + * let him. To find out, call + * krb_kntoln to convert the triple in kdata to a name which we can + * string compare. + */ + if (!krb_kntoln(kdata, kuser) && (strcmp(kuser, luser) == 0)) { + return(OK); + } + } + /* open ~/.klogin */ + if ((fp = fopen(pbuf, "r")) == NULL) { + return(NOTOK); + } + /* + * security: if the user does not own his own .klogin file, + * do not grant access + */ + if (fstat(fileno(fp), &sbuf)) { + fclose(fp); + return(NOTOK); + } + if (sbuf.st_uid != pwd->pw_uid) { + fclose(fp); + return(NOTOK); + } + +#ifdef ATHENA_COMPAT + /* Accept old-style .klogin files */ + + /* + * change the default realm from the hard-coded value to the + * accepted realm that Kerberos specifies. + */ + rc = krb_get_lrealm(local_realm, 1); + if (rc == KSUCCESS) + kparm[REALM_SUBSCRIPT].defvalue = local_realm; + else + return (rc); + + /* check each line */ + while ((isok != OK) && (rc = fGetParameterSet(fp, KPARMS)) != PS_EOF) { + switch (rc) { + case PS_BAD_KEYWORD: + case PS_SYNTAX: + while (((gobble = fGetChar(fp)) != EOF) && (gobble != '\n')); + break; + + case PS_OKAY: + isok = (ParmCompare(KPARMS, "user", kdata->pname) || + ParmCompare(KPARMS, "instance", kdata->pinst) || + ParmCompare(KPARMS, "realm", kdata->prealm)); + break; + + default: + break; + } + FreeParameterSet(kparm, PARMCOUNT(kparm)); + } + /* reset the stream for parsing new-style names, if necessary */ + rewind(fp); +#endif /* ATHENA_COMPAT */ + + /* check each line */ + while ((isok != OK) && (fgets(linebuf, BUFSIZ, fp) != NULL)) { + /* null-terminate the input string */ + linebuf[BUFSIZ-1] = '\0'; + newline = NULL; + /* nuke the newline if it exists */ + if (newline = index(linebuf, '\n')) + *newline = '\0'; + rc = kname_parse(principal, inst, realm, linebuf); + if (rc == KSUCCESS) { + isok = (strncmp(kdata->pname, principal, ANAME_SZ) || + strncmp(kdata->pinst, inst, INST_SZ) || + strncmp(kdata->prealm, realm, REALM_SZ)); + } + /* clean up the rest of the line if necessary */ + if (!newline) + while (((gobble = getc(fp)) != EOF) && gobble != '\n'); + } + fclose(fp); + return(isok); +} diff --git a/src/lib/krb425/mk_priv.c b/src/lib/krb425/mk_priv.c new file mode 100644 index 000000000..9adc184d1 --- /dev/null +++ b/src/lib/krb425/mk_priv.c @@ -0,0 +1,79 @@ +/* + * $Source$ + * $Author$ + * + * Copyright 1990 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * krb_mk_priv for krb425 + */ + +#if !defined(lint) && !defined(SABER) +static char rcsid_mk_priv_c[] = +"$Id$"; +#endif /* !lint & !SABER */ + +#include +#include "krb425.h" + +long +krb_mk_priv(in, out, in_length, sched, key, sender, receiver) +u_char *in; +u_char *out; +u_long in_length; +Key_schedule sched; /* ignored */ +des_cblock key; +struct sockaddr_in *sender; +struct sockaddr_in *receiver; +{ + krb5_data inbuf; + krb5_data out5; + krb5_keyblock keyb; + krb5_fulladdr sfaddr; + krb5_fulladdr rfaddr; + krb5_address saddr; + krb5_address raddr; + krb5_error_code r; + char sa[4], ra[4]; + + keyb.keytype = KEYTYPE_DES; + keyb.length = sizeof(des_cblock); + keyb.contents = (krb5_octet *)key; + + saddr.addrtype = ADDRTYPE_INET; + saddr.length = 4; + saddr.contents = (krb5_octet *)sa; + + raddr.addrtype = ADDRTYPE_INET; + raddr.length = 4; + raddr.contents = (krb5_octet *)ra; + + bcopy((char *)&sender->sin_addr, sa, 4); + bcopy((char *)&receiver->sin_addr, ra, 4); + + sfaddr.address = &saddr; + sfaddr.port = sender->sin_port; + + rfaddr.address = &raddr; + rfaddr.port = receiver->sin_port; + + inbuf.data = (char *)in; + inbuf.length = in_length; + + if (r = krb5_mk_priv(&inbuf, + KEYTYPE_DES, + &keyb, + &sfaddr, &rfaddr, + 0, &out5)) { +#ifdef EBUG + ERROR(r); +#endif + return(-1); + } + + bcopy(out5.data, out, out5.length); + free(out5.data); + return(out5.length); +} diff --git a/src/lib/krb425/mk_req.c b/src/lib/krb425/mk_req.c new file mode 100644 index 000000000..755bfd85f --- /dev/null +++ b/src/lib/krb425/mk_req.c @@ -0,0 +1,79 @@ +/* + * $Source$ + * $Author$ + * + * Copyright 1990 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * krb_mk_req for krb425 + */ + +#if !defined(lint) && !defined(SABER) +static char rcsid_mk_req_c[] = +"$Id$"; +#endif /* !lint & !SABER */ + +#include +#include "krb425.h" + +int +krb_mk_req(authent, service, instance, realm, checksum) +KTEXT authent; +char *service; +char *instance; +char *realm; +u_long checksum; +{ + krb5_data *server[4]; + krb5_data srvdata[3]; + krb5_error_code r; + krb5_data outbuf; + krb5_checksum ck; + + set_data5(srvdata[0], realm); + set_data5(srvdata[1], service); + set_data5(srvdata[2], instance); + + server[0] = &srvdata[0]; + server[1] = &srvdata[1]; + server[2] = &srvdata[2]; + server[3] = 0; + + if (!_krb425_ccache) + krb5_cc_default(&_krb425_ccache); + +#ifdef EBUG + EPRINT "Calling krb5_mk_req with:\n"); + EPRINT " Realm : "); show5(srvdata[0]); ENEWLINE + EPRINT " Service : "); show5(srvdata[1]); ENEWLINE + EPRINT " Instance: "); show5(srvdata[2]); ENEWLINE + EPRINT " CheckSum: %08x\n", checksum); +#endif + set_cksum(ck, checksum) + + r = krb5_mk_req((krb5_principal)server, + (krb5_flags)0, + &ck, + _krb425_ccache, + &outbuf); +#ifdef EBUG + if (r) + ERROR(r) +#endif + if (!r) { + if (outbuf.length > MAX_KTXT_LEN) { +#ifdef EBUG + EPRINT "Return to long (%d > %d)\n", + outbuf.length, MAX_KTXT_LEN); +#endif + free((char *)outbuf.data); + return(KFAILURE); + } + authent->length = outbuf.length; + bcopy((char *)outbuf.data, (char *)authent->dat, outbuf.length); + free((char *)outbuf.data); + } + return(krb425error(r)); +} diff --git a/src/lib/krb425/mk_safe.c b/src/lib/krb425/mk_safe.c new file mode 100644 index 000000000..2a2fc66d1 --- /dev/null +++ b/src/lib/krb425/mk_safe.c @@ -0,0 +1,78 @@ +/* + * $Source$ + * $Author$ + * + * Copyright 1990 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * krb_mk_safe for krb425 + */ + +#if !defined(lint) && !defined(SABER) +static char rcsid_mk_safe_c[] = +"$Id$"; +#endif /* !lint & !SABER */ + +#include +#include "krb425.h" + +long +krb_mk_safe(in, out, in_length, key, sender, receiver) +u_char *in; +u_char *out; +u_long in_length; +des_cblock key; +struct sockaddr_in *sender; +struct sockaddr_in *receiver; +{ + krb5_data inbuf; + krb5_data out5; + krb5_keyblock keyb; + krb5_fulladdr sfaddr; + krb5_fulladdr rfaddr; + krb5_address saddr; + krb5_address raddr; + krb5_error_code r; + char sa[4], ra[4]; + + keyb.keytype = KEYTYPE_DES; + keyb.length = sizeof(des_cblock); + keyb.contents = (krb5_octet *)key; + + saddr.addrtype = ADDRTYPE_INET; + saddr.length = 4; + saddr.contents = (krb5_octet *)sa; + + raddr.addrtype = ADDRTYPE_INET; + raddr.length = 4; + raddr.contents = (krb5_octet *)ra; + + bcopy((char *)&sender->sin_addr, sa, 4); + bcopy((char *)&receiver->sin_addr, ra, 4); + + sfaddr.address = &saddr; + sfaddr.port = sender->sin_port; + + rfaddr.address = &raddr; + rfaddr.port = receiver->sin_port; + + inbuf.data = (char *)in; + inbuf.length = in_length; + + if (r = krb5_mk_safe(&inbuf, + CKSUMTYPE_CRC32, + &keyb, + &sfaddr, &rfaddr, + &out5)) { +#ifdef EBUG + ERROR(r); +#endif + return(-1); + } + + bcopy(out5.data, out, out5.length); + free(out5.data); + return(out5.length); +} diff --git a/src/lib/krb425/net_read.c b/src/lib/krb425/net_read.c new file mode 100644 index 000000000..c4020c29e --- /dev/null +++ b/src/lib/krb425/net_read.c @@ -0,0 +1,58 @@ +/* + * $Source$ + * $Author$ + * + * Copyright 1990 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * krb_net_read for krb425 + */ + +#if !defined(lint) && !defined(SABER) +static char rcsid_net_read_c[] = +"$Id$"; +#endif /* !lint & !SABER */ + +#include +#include "krb425.h" + +int +krb_net_read(fd,buf,len) +int fd; +char *buf; +int len; +{ + extern int read(); + int cc, len2 = 0; +#ifdef EBUG + char *obuf = buf; +#endif + + do { + cc = read(fd, buf, len); + if (cc < 0) + return(cc); /* errno is already set */ + else if (cc == 0) { + return(len2); + } else { + buf += cc; + len2 += cc; + len -= cc; + } + } while (len > 0); +#ifdef EBUG + buf = obuf; + EPRINT "Read data: ``"); + for (cc = 0; cc < len2 && cc < 24; ++cc) { + fprintf(stderr, "%c", (buf[cc] < ' ' || buf[cc] > '~') ? '.' : buf[cc]); + } + if (cc < len2) { + fprintf(stderr, "''(%d)\n", len2); + } else { + fprintf(stderr, "''\n"); + } +#endif + return(len2); +} diff --git a/src/lib/krb425/net_write.c b/src/lib/krb425/net_write.c new file mode 100644 index 000000000..6522ae5e2 --- /dev/null +++ b/src/lib/krb425/net_write.c @@ -0,0 +1,51 @@ +/* + * $Source$ + * $Author$ + * + * Copyright 1990 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * krb_net_write for krb425 + */ + +#if !defined(lint) && !defined(SABER) +static char rcsid_net_write_c[] = +"$Id$"; +#endif /* !lint & !SABER */ + +#include +#include "krb425.h" + +int +krb_net_write(fd,buf,len) +int fd; +char *buf; +int len; +{ + int cc; + extern int write(); + register int wrlen = len; +#ifdef EBUG + EPRINT "Write data: ``"); + for (cc = 0; cc < len && cc < 24; ++cc) { + fprintf(stderr, "%c", (buf[cc] < ' ' || buf[cc] > '~') ? '.' : buf[cc]); + } + if (cc < len) { + fprintf(stderr, "''(%d)\n", len); + } else { + fprintf(stderr, "''\n"); + } +#endif + do { + cc = write(fd, buf, wrlen); + if (cc < 0) + return(cc); + else { + buf += cc; + wrlen -= cc; + } + } while (wrlen > 0); + return(len); +} diff --git a/src/lib/krb425/rd_priv.c b/src/lib/krb425/rd_priv.c new file mode 100644 index 000000000..cda7f5e25 --- /dev/null +++ b/src/lib/krb425/rd_priv.c @@ -0,0 +1,79 @@ +/* + * $Source$ + * $Author$ + * + * Copyright 1990 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * krb_rd_priv for krb425 + */ + +#if !defined(lint) && !defined(SABER) +static char rcsid_rd_priv_c[] = +"$Id$"; +#endif /* !lint & !SABER */ + +#include +#include "krb425.h" + +long +krb_rd_priv(in, in_length, sched, key, sender, receiver, msg) +u_char *in; +u_long in_length; +Key_schedule sched; /* ignored */ +des_cblock key; +struct sockaddr_in *sender; +struct sockaddr_in *receiver; +MSG_DAT *msg; +{ + krb5_data inbuf; + krb5_data out; + krb5_keyblock keyb; + krb5_fulladdr sfaddr; + krb5_fulladdr rfaddr; + krb5_address saddr; + krb5_address raddr; + krb5_error_code r; + char sa[4], ra[4]; + + keyb.keytype = KEYTYPE_DES; + keyb.length = sizeof(des_cblock); + keyb.contents = (krb5_octet *)key; + + saddr.addrtype = ADDRTYPE_INET; + saddr.length = 4; + saddr.contents = (krb5_octet *)sa; + + raddr.addrtype = ADDRTYPE_INET; + raddr.length = 4; + raddr.contents = (krb5_octet *)ra; + + bcopy((char *)&sender->sin_addr, sa, 4); + bcopy((char *)&receiver->sin_addr, ra, 4); + + sfaddr.address = &saddr; + sfaddr.port = sender->sin_port; + + rfaddr.address = &raddr; + rfaddr.port = receiver->sin_port; + + inbuf.data = (char *)in; + inbuf.length = in_length; + + if (r = krb5_rd_priv(&inbuf, &keyb, &sfaddr, &rfaddr, 0, &out)) { +#ifdef EBUG + ERROR(r) +#endif + return(-1); + } + + msg->app_data = (u_char *)out.data; + msg->app_length = out.length; + msg->hash = 0L; + msg->swap = 0; + msg->time_sec = 0; + msg->time_5ms = 0; + return(KSUCCESS); +} diff --git a/src/lib/krb425/rd_req.c b/src/lib/krb425/rd_req.c new file mode 100644 index 000000000..ad62f2add --- /dev/null +++ b/src/lib/krb425/rd_req.c @@ -0,0 +1,172 @@ +/* + * $Source$ + * $Author$ + * + * Copyright 1990 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * krb_rd_req for krb425 + */ + +#if !defined(lint) && !defined(SABER) +static char rcsid_rd_req_c[] = +"$Id$"; +#endif /* !lint & !SABER */ + +#include +#include "krb425.h" + +int +krb_rd_req(authent, service, instance, from_addr, ad, fn) +KTEXT authent; +char *service; +char *instance; +u_long from_addr; +AUTH_DAT *ad; +char *fn; +{ + krb5_address peer; + krb5_tkt_authent authd; + char addr[4]; + krb5_data *server[4]; + krb5_data srvdata[3]; + krb5_error_code r; + krb5_data authe; + extern int gethostname(); + + + if (from_addr) { + peer.addrtype = ADDRTYPE_INET; + peer.length = 4; + peer.contents = (krb5_octet *)addr; + bcopy((char *)&from_addr + (sizeof(from_addr) - 4), addr, 4); + } + + if (!_krb425_local_realm[0]) + krb5_get_default_realm(REALM_SZ, _krb425_local_realm); + + if (!strcmp(instance, "*")) { + static char hostname[64] = { 0 }; + + if (!hostname[0]) { + struct hostent *h; + + gethostname(hostname, sizeof(hostname)); + if (h = gethostbyname(hostname)) { + char *p; + + strncpy(hostname, h->h_name, sizeof(hostname)); + hostname[sizeof(hostname)-1] = 0; + p = hostname; + do { + if (isupper(*p)) *p=tolower(*p); + } while (*p++); + } + } + instance = hostname; + } + set_data5(srvdata[0], _krb425_local_realm); + set_data5(srvdata[1], service); + set_data5(srvdata[2], instance); + + server[0] = &srvdata[0]; + server[1] = &srvdata[1]; + server[2] = &srvdata[2]; + server[3] = 0; + + + authe.length = authent->length; + authe.data = (char *)authent->dat; + if (!*fn) + fn = (char *)0; +#ifdef EBUG + EPRINT "Calling krb5_rd_req with:\n"); + EPRINT " Realm : "); show5(srvdata[0]); ENEWLINE + EPRINT " Service : "); show5(srvdata[1]); ENEWLINE + EPRINT " Instance: "); show5(srvdata[2]); ENEWLINE + EPRINT "Authenenticator : %d bytes\n", authe.length); + EPRINT "Filename : %s\n", fn ? fn : "none given"); + if (from_addr) { + EPRINT "Address type : %s\n", + peer.addrtype == ADDRTYPE_INET ? "inet" : + peer.addrtype == ADDRTYPE_CHAOS ? "chaos" : + peer.addrtype == ADDRTYPE_XNS ? "xns" : + peer.addrtype == ADDRTYPE_ISO ? "iso" : + peer.addrtype == ADDRTYPE_DDP ? "ddp" : "unknown type"); + EPRINT "Address length : %d\n", peer.length); + EPRINT "Address :"); + { + int x; + for (x = 0; x < peer.length && x < 8; ++x) + fprintf(stderr, " %d", peer.contents[x]); + if (x < peer.length) + fprintf(stderr, " (%d)", peer.length); + fprintf(stderr, "\n"); + } + } +#endif + + if (r = krb5_rd_req(&authe, + (krb5_principal)server, + from_addr ? &peer : 0, + fn, 0, 0, 0, &authd)) { +#ifdef EBUG + ERROR(r) +#endif + return(krb425error(r)); + } + + ad->k_flags = 0; + +#ifdef EBUG + r = 0; + while (authd.authenticator->client[r]) { + EPRINT "Client[%d]: ", r); show5((*authd.authenticator->client[r])); ENEWLINE + ++r; + } + r = 0; + while (authd.ticket->server[r]) { + EPRINT "Server[%d]: ", r); show5((*authd.ticket->server[r])); ENEWLINE + ++r; + } + r = 0; +#endif + set_string(ad->pname, ANAME_SZ, authd.authenticator->client[1]); + set_string(ad->pinst, INST_SZ, authd.authenticator->client[2]); + set_string(ad->prealm, REALM_SZ, authd.authenticator->client[0]); + + ad->checksum = *(long *)authd.authenticator->checksum->contents; + + if (authd.ticket->enc_part2->session->keytype != KEYTYPE_DES) { + r = KFAILURE; + goto out; + } else + bcopy(authd.ticket->enc_part2->session->contents, + (char*)ad->session, sizeof(C_Block)); + + ad->life = authd.ticket->enc_part2->times.endtime; + ad->time_sec = authd.authenticator->ctime; + ad->address = 0; + + if (authd.ticket->enc_part2->caddrs[0]->addrtype != ADDRTYPE_INET) { + r = KFAILURE; + goto out; + } else + bcopy(authd.ticket->enc_part2->caddrs[0]->contents, + (char *)&ad->address + sizeof(ad->address) - 4, 4); + + if (authd.ticket->enc_part2->authorization_data && + authd.ticket->enc_part2->authorization_data[0]) { + ad->reply.length = authd.ticket->enc_part2->authorization_data[0]->length; + bcopy(authd.ticket->enc_part2->authorization_data[0]->contents, + ad->reply.dat, + min(ad->reply.length, MAX_KTXT_LEN)); + ad->reply.mbz = 0; + } +out: + krb5_free_ticket(authd.ticket); + krb5_free_authenticator(authd.authenticator); + return(r); +} diff --git a/src/lib/krb425/rd_safe.c b/src/lib/krb425/rd_safe.c new file mode 100644 index 000000000..d2f55c609 --- /dev/null +++ b/src/lib/krb425/rd_safe.c @@ -0,0 +1,78 @@ +/* + * $Source$ + * $Author$ + * + * Copyright 1990 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * krb_rd_safe for krb425 + */ + +#if !defined(lint) && !defined(SABER) +static char rcsid_rd_safe_c[] = +"$Id$"; +#endif /* !lint & !SABER */ + +#include +#include "krb425.h" + +long +krb_rd_safe(in, in_length, key, sender, receiver, msg) +u_char *in; +u_long in_length; +des_cblock key; +struct sockaddr_in *sender; +struct sockaddr_in *receiver; +MSG_DAT *msg; +{ + krb5_data inbuf; + krb5_data out; + krb5_keyblock keyb; + krb5_fulladdr sfaddr; + krb5_fulladdr rfaddr; + krb5_address saddr; + krb5_address raddr; + krb5_error_code r; + char sa[4], ra[4]; + + keyb.keytype = KEYTYPE_DES; + keyb.length = sizeof(des_cblock); + keyb.contents = (krb5_octet *)key; + + saddr.addrtype = ADDRTYPE_INET; + saddr.length = 4; + saddr.contents = (krb5_octet *)sa; + + raddr.addrtype = ADDRTYPE_INET; + raddr.length = 4; + raddr.contents = (krb5_octet *)ra; + + bcopy((char *)&sender->sin_addr, sa, 4); + bcopy((char *)&receiver->sin_addr, ra, 4); + + sfaddr.address = &saddr; + sfaddr.port = sender->sin_port; + + rfaddr.address = &raddr; + rfaddr.port = receiver->sin_port; + + inbuf.data = (char *)in; + inbuf.length = in_length; + + if (r = krb5_rd_safe(&inbuf, &keyb, &sfaddr, &rfaddr, &out)) { +#ifdef EBUG + ERROR(r) +#endif + return(-1); + } + + msg->app_data = (u_char *)out.data; + msg->app_length = out.length; + msg->hash = 0L; + msg->swap = 0; + msg->time_sec = 0; + msg->time_5ms = 0; + return(KSUCCESS); +} diff --git a/src/lib/krb425/realmhost.c b/src/lib/krb425/realmhost.c new file mode 100644 index 000000000..2f600c6eb --- /dev/null +++ b/src/lib/krb425/realmhost.c @@ -0,0 +1,53 @@ +/* + * $Source$ + * $Author$ + * + * Copyright 1990 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * krb_realmofhost for krb425 + */ + +#if !defined(lint) && !defined(SABER) +static char rcsid_realmhost_c[] = +"$Id$"; +#endif /* !lint & !SABER */ + +#include +#include "krb425.h" + +char * +krb_realmofhost(host) +char *host; +{ + char **realms; + char *domain; + static char ret_realm[REALM_SZ+1]; + + + domain = index(host, '.'); + + /* prepare default */ + if (domain) { + char *cp; + + strncpy(ret_realm, &domain[1], REALM_SZ); + ret_realm[REALM_SZ] = '\0'; + /* Upper-case realm */ + for (cp = ret_realm; *cp; cp++) + if (islower(*cp)) + *cp = toupper(*cp); + } else { + if (krb5_get_default_realm(REALM_SZ, ret_realm)) + ret_realm[0] = 0; + } + + if (krb5_get_host_realm(host, &realms)) { + return(ret_realm); + } + strncpy(ret_realm, realms[0], REALM_SZ); + krb5_free_host_realm(realms); + return(ret_realm); +} diff --git a/src/lib/krb425/recvauth.c b/src/lib/krb425/recvauth.c new file mode 100644 index 000000000..1cee4884f --- /dev/null +++ b/src/lib/krb425/recvauth.c @@ -0,0 +1,280 @@ +/* + * $Source$ + * $Author$ + * + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + */ + +#include "krb425.h" + + +#define KRB_SENDAUTH_VERS "AUTHV0.1" /* MUST be KRB_SENDAUTH_VLEN + chars */ + +/* + * If the protocol changes, you will need to change the version string + * and make appropriate changes in krb_sendauth.c + * be sure to support old versions of krb_sendauth! + */ + +extern int errno; + +/* + * krb_recvauth() reads (and optionally responds to) a message sent + * using krb_sendauth(). The "options" argument is a bit-field of + * selected options (see "sendauth.c" for options description). + * The only option relevant to krb_recvauth() is KOPT_DO_MUTUAL + * (mutual authentication requested). The "fd" argument supplies + * a file descriptor to read from (and write to, if mutual authenti- + * cation is requested). + * + * Part of the received message will be a Kerberos ticket sent by the + * client; this is read into the "ticket" argument. The "service" and + * "instance" arguments supply the server's Kerberos name. If the + * "instance" argument is the string "*", it is treated as a wild card + * and filled in during the krb_rd_req() call (see read_service_key()). + * + * The "faddr" and "laddr" give the sending (client) and receiving + * (local server) network addresses. ("laddr" may be left NULL unless + * mutual authentication is requested, in which case it must be set.) + * + * The authentication information extracted from the message is returned + * in "kdata". The "filename" argument indicates the file where the + * server's key can be found. (It is passed on to krb_rd_req().) If + * left null, the default "/etc/srvtab" will be used. + * + * If mutual authentication is requested, the session key schedule must + * be computed in order to reply; this schedule is returned in the + * "schedule" argument. A string containing the application version + * number from the received message is returned in "version", which + * should be large enough to hold a KRB_SENDAUTH_VLEN-character string. + * + * See krb_sendauth() for the format of the received client message. + * + * This routine supports another client format, for backward + * compatibility, consisting of: + * + * Size Variable Field + * ---- -------- ----- + * + * string tmp_buf, tkt_len length of ticket, in + * ascii + * + * char ' ' (space char) separator + * + * tkt_len ticket->dat the ticket + * + * This old-style version does not support mutual authentication. + * + * krb_recvauth() first reads the protocol version string from the + * given file descriptor. If it doesn't match the current protocol + * version (KRB_SENDAUTH_VERS), the old-style format is assumed. In + * that case, the string of characters up to the first space is read + * and interpreted as the ticket length, then the ticket is read. + * + * If the first string did match KRB_SENDAUTH_VERS, krb_recvauth() + * next reads the application protocol version string. Then the + * ticket length and ticket itself are read. + * + * The ticket is decrypted and checked by the call to krb_rd_req(). + * If no mutual authentication is required, the result of the + * krb_rd_req() call is retured by this routine. If mutual authenti- + * cation is required, a message in the following format is returned + * on "fd": + * + * Size Variable Field + * ---- -------- ----- + * + * 4 bytes tkt_len length of ticket or -1 + * if error occurred + * + * priv_len tmp_buf "private" message created + * by krb_mk_priv() which + * contains the incremented + * checksum sent by the client + * encrypted in the session + * key. (This field is not + * present in case of error.) + * + * If all goes well, KSUCCESS is returned; otherwise KFAILURE or some + * other error code is returned. + */ + +#ifndef max +#define max(a,b) (((a) > (b)) ? (a) : (b)) +#endif /* max */ + +int +krb_recvauth(options, fd, ticket, service, instance, faddr, laddr, kdata, + filename, schedule, version) +long options; /* bit-pattern of options */ +int fd; /* file descr. to read from */ +KTEXT ticket; /* storage for client's ticket */ +char *service; /* service expected */ +char *instance; /* inst expected (may be filled in) */ +struct sockaddr_in *faddr; /* address of foreign host on fd */ +struct sockaddr_in *laddr; /* local address */ +AUTH_DAT *kdata; /* kerberos data (returned) */ +char *filename; /* name of file with service keys */ +Key_schedule schedule; /* key schedule (return) */ +char *version; /* version string (filled in) */ +{ + + int i, cc, old_vers = 0; + char krb_vers[KRB_SENDAUTH_VLEN + 1]; /* + 1 for the null terminator */ + char *cp; + int rem; + long tkt_len, priv_len; + u_long cksum; + u_char tmp_buf[MAX_KTXT_LEN+max(KRB_SENDAUTH_VLEN+1,21)]; + + /* read the protocol version number */ + if (krb_net_read(fd, krb_vers, KRB_SENDAUTH_VLEN) != + KRB_SENDAUTH_VLEN) + return(errno); + krb_vers[KRB_SENDAUTH_VLEN] = '\0'; + + /* check version string */ + if (strcmp(krb_vers,KRB_SENDAUTH_VERS)) { + /* Assume the old version of sendkerberosdata: send ascii + length, ' ', and ticket. */ + if (options & KOPT_DO_MUTUAL) + return(KFAILURE); /* XXX can't do old style with mutual auth */ + old_vers = 1; + + /* copy what we have read into tmp_buf */ + (void) bcopy(krb_vers, (char *) tmp_buf, KRB_SENDAUTH_VLEN); + + /* search for space, and make it a null */ + for (i = 0; i < KRB_SENDAUTH_VLEN; i++) + if (tmp_buf[i]== ' ') { + tmp_buf[i] = '\0'; + /* point cp to the beginning of the real ticket */ + cp = (char *) &tmp_buf[i+1]; + break; + } + + if (i == KRB_SENDAUTH_VLEN) + /* didn't find the space, keep reading to find it */ + for (; i<20; i++) { + if (read(fd, (char *)&tmp_buf[i], 1) != 1) { + return(KFAILURE); + } + if (tmp_buf[i] == ' ') { + tmp_buf[i] = '\0'; + /* point cp to the beginning of the real ticket */ + cp = (char *) &tmp_buf[i+1]; + break; + } + } + + tkt_len = (long) atoi((char *) tmp_buf); + + /* sanity check the length */ + if ((i==20)||(tkt_len<=0)||(tkt_len>MAX_KTXT_LEN)) + return(KFAILURE); + + if (i < KRB_SENDAUTH_VLEN) { + /* since we already got the space, and part of the ticket, + we read fewer bytes to get the rest of the ticket */ + if (krb_net_read(fd, (char *)(tmp_buf+KRB_SENDAUTH_VLEN), + (int) (tkt_len - KRB_SENDAUTH_VLEN + 1 + i)) + != (int)(tkt_len - KRB_SENDAUTH_VLEN + 1 + i)) + return(errno); + } else { + if (krb_net_read(fd, (char *)(tmp_buf+i), (int)tkt_len) != + (int) tkt_len) + return(errno); + } + ticket->length = tkt_len; + /* copy the ticket into the struct */ + (void) bcopy(cp, (char *) ticket->dat, ticket->length); + + } else { + /* read the application version string */ + if (krb_net_read(fd, version, KRB_SENDAUTH_VLEN) != + KRB_SENDAUTH_VLEN) + return(errno); + version[KRB_SENDAUTH_VLEN] = '\0'; + + /* get the length of the ticket */ + if (krb_net_read(fd, (char *)&tkt_len, sizeof(tkt_len)) != + sizeof(tkt_len)) + return(errno); + + /* sanity check */ + ticket->length = ntohl((unsigned long)tkt_len); + if ((ticket->length <= 0) || (ticket->length > MAX_KTXT_LEN)) { + if (options & KOPT_DO_MUTUAL) { + rem = KFAILURE; + goto mutual_fail; + } else + return(KFAILURE); /* XXX there may still be junk on the fd? */ + } + + /* read the ticket */ + if (krb_net_read(fd, (char *) ticket->dat, ticket->length) + != ticket->length) + return(errno); + } + /* + * now have the ticket. decrypt it to get the authenticated + * data. + */ + rem = krb_rd_req(ticket,service,instance,faddr->sin_addr.s_addr, + kdata,filename); + + if (old_vers) return(rem); /* XXX can't do mutual with old client */ + + /* if we are doing mutual auth, compose a response */ + if (options & KOPT_DO_MUTUAL) { + if (rem != KSUCCESS) { +#ifdef EBUG + ERROR(rem) +#endif + /* the krb_rd_req failed */ + goto mutual_fail; + } + + /* add one to the (formerly) sealed checksum, and re-seal it + for return to the client */ + cksum = kdata->checksum + 1; + cksum = htonl(cksum); +#ifndef NOENCRYPTION + key_sched(kdata->session,schedule); +#endif /* !NOENCRYPTION */ + priv_len = krb_mk_priv((unsigned char *)&cksum, + tmp_buf, + (unsigned long) sizeof(cksum), + schedule, + kdata->session, + laddr, + faddr); + if (priv_len < 0) { + /* re-sealing failed; notify the client */ + rem = KFAILURE; /* XXX */ +mutual_fail: + priv_len = -1; + tkt_len = htonl((unsigned long) priv_len); + /* a length of -1 is interpreted as an authentication + failure by the client */ + if ((cc = krb_net_write(fd, (char *)&tkt_len, sizeof(tkt_len))) + != sizeof(tkt_len)) + return(cc); + return(rem); + } else { + /* re-sealing succeeded, send the private message */ + tkt_len = htonl((unsigned long)priv_len); + if ((cc = krb_net_write(fd, (char *)&tkt_len, sizeof(tkt_len))) + != sizeof(tkt_len)) + return(cc); + if ((cc = krb_net_write(fd, (char *)tmp_buf, (int) priv_len)) + != (int) priv_len) + return(cc); + } + } + return(rem); +} diff --git a/src/lib/krb425/sendauth.c b/src/lib/krb425/sendauth.c new file mode 100644 index 000000000..9c050104e --- /dev/null +++ b/src/lib/krb425/sendauth.c @@ -0,0 +1,253 @@ +/* + * $Source$ + * $Author$ + * + * Copyright 1987, 1988 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + */ + +#include +#include "krb425.h" + +#include +#include +#include +#include +#include + +#define KRB_SENDAUTH_VERS "AUTHV0.1" /* MUST be KRB_SENDAUTH_VLEN chars */ +/* + * If the protocol changes, you will need to change the version string + * and make appropriate changes in krb_recvauth.c + */ + +extern int errno; + +extern char *krb_get_phost(); + +/* + * This file contains two routines: krb_sendauth() and krb_sendsrv(). + * + * krb_sendauth() transmits a ticket over a file descriptor for a + * desired service, instance, and realm, doing mutual authentication + * with the server if desired. + * + * krb_sendsvc() sends a service name to a remote knetd server. + */ + +/* + * The first argument to krb_sendauth() contains a bitfield of + * options (the options are defined in "krb.h"): + * + * KOPT_DONT_CANON Don't canonicalize instance as a hostname. + * (If this option is not chosen, krb_get_phost() + * is called to canonicalize it.) + * + * KOPT_DONT_MK_REQ Don't request server ticket from Kerberos. + * A ticket must be supplied in the "ticket" + * argument. + * (If this option is not chosen, and there + * is no ticket for the given server in the + * ticket cache, one will be fetched using + * krb_mk_req() and returned in "ticket".) + * + * KOPT_DO_MUTUAL Do mutual authentication, requiring that the + * receiving server return the checksum+1 encrypted + * in the session key. The mutual authentication + * is done using krb_mk_priv() on the other side + * (see "recvauth.c") and krb_rd_priv() on this + * side. + * + * The "fd" argument is a file descriptor to write to the remote + * server on. The "ticket" argument is used to store the new ticket + * from the krb_mk_req() call. If the KOPT_DONT_MK_REQ options is + * chosen, the ticket must be supplied in the "ticket" argument. + * The "service", "inst", and "realm" arguments identify the ticket. + * If "realm" is null, the local realm is used. + * + * The following arguments are only needed if the KOPT_DO_MUTUAL option + * is chosen: + * + * The "checksum" argument is a number that the server will add 1 to + * to authenticate itself back to the client; the "msg_data" argument + * holds the returned mutual-authentication message from the server + * (i.e., the checksum+1); the "cred" structure is used to hold the + * session key of the server, extracted from the ticket file, for use + * in decrypting the mutual authentication message from the server; + * and "schedule" holds the key schedule for that decryption. The + * the local and server addresses are given in "laddr" and "faddr". + * + * The application protocol version number (of up to KRB_SENDAUTH_VLEN + * characters) is passed in "version". + * + * If all goes well, KSUCCESS is returned, otherwise some error code. + * + * The format of the message sent to the server is: + * + * Size Variable Field + * ---- -------- ----- + * + * KRB_SENDAUTH_VLEN KRB_SENDAUTH_VER sendauth protocol + * bytes version number + * + * KRB_SENDAUTH_VLEN version application protocol + * bytes version number + * + * 4 bytes ticket->length length of ticket + * + * ticket->length ticket->dat ticket itself + */ + +/* + * XXX: Note that krb_rd_priv() is coded in such a way that + * "msg_data->app_data" will be pointing into "priv_buf", which + * will disappear when krb_sendauth() returns. + */ + +int +krb_sendauth(options, fd, ticket, service, inst, realm, checksum, + msg_data, cred, schedule, laddr, faddr, version) +long options; /* bit-pattern of options */ +int fd; /* file descriptor to write onto */ +KTEXT ticket; /* where to put ticket (return); or + * supplied in case of KOPT_DONT_MK_REQ */ +char *service, *inst, *realm; /* service name, instance, realm */ +u_long checksum; /* checksum to include in request */ +MSG_DAT *msg_data; /* mutual auth MSG_DAT (return) */ +CREDENTIALS *cred; /* credentials (return) */ +Key_schedule schedule; /* key schedule (return) */ +struct sockaddr_in *laddr; /* local address */ +struct sockaddr_in *faddr; /* address of foreign host on fd */ +char *version; /* version string */ +{ + int rem, i, cc; + char srv_inst[INST_SZ]; + char krb_realm[REALM_SZ]; + char buf[BUFSIZ]; + long tkt_len; + u_char priv_buf[1024]; + u_long cksum; + + rem=KSUCCESS; + + /* get current realm if not passed in */ + if (!realm) { + rem = krb_get_lrealm(krb_realm,1); + if (rem != KSUCCESS) + return(rem); + realm = krb_realm; + } + + /* copy instance into local storage, canonicalizing if desired */ + if (options & KOPT_DONT_CANON) + (void) strncpy(srv_inst, inst, INST_SZ); + else + (void) strncpy(srv_inst, krb_get_phost(inst), INST_SZ); + + /* get the ticket if desired */ + if (!(options & KOPT_DONT_MK_REQ)) { + rem = krb_mk_req(ticket, service, srv_inst, realm, checksum); + if (rem != KSUCCESS) + return(rem); + } + + /* if mutual auth, get credentials so we have service session + keys for decryption below */ + if (options & KOPT_DO_MUTUAL) + if (cc = krb_get_cred(service, srv_inst, realm, cred)) + return(cc); + + /* zero the buffer */ + (void) bzero(buf, BUFSIZ); + + /* insert version strings */ + (void) strncpy(buf, KRB_SENDAUTH_VERS, KRB_SENDAUTH_VLEN); + (void) strncpy(buf+KRB_SENDAUTH_VLEN, version, KRB_SENDAUTH_VLEN); + + /* increment past vers strings */ + i = 2*KRB_SENDAUTH_VLEN; + + /* put ticket length into buffer */ + tkt_len = htonl((unsigned long) ticket->length); + (void) bcopy((char *) &tkt_len, buf+i, sizeof(tkt_len)); + i += sizeof(tkt_len); + + /* put ticket into buffer */ + (void) bcopy((char *) ticket->dat, buf+i, ticket->length); + i += ticket->length; + + /* write the request to the server */ + if ((cc = krb_net_write(fd, buf, i)) != i) + return(cc); + + /* mutual authentication, if desired */ + if (options & KOPT_DO_MUTUAL) { + int r; + /* get the length of the reply */ + if ((r = krb_net_read(fd, (char *) &tkt_len, sizeof(tkt_len))) != + sizeof(tkt_len)) { +#ifdef EBUG + EPRINT "krb_net_read(%d, tkt_len, %d) returns %d\n", + fd, sizeof(tkt_len), r); + ERROR(errno); +#endif + return(errno); + } + tkt_len = ntohl((unsigned long)tkt_len); + + /* if the length is negative, the server failed to recognize us. */ + if ((tkt_len < 0) || (tkt_len > sizeof(priv_buf))) + return(KFAILURE); /* XXX */ + /* read the reply... */ + if (krb_net_read(fd, (char *)priv_buf, (int) tkt_len) != (int) tkt_len) + return(errno); + + /* ...and decrypt it */ +#ifndef NOENCRYPTION + key_sched(cred->session, schedule); +#endif /* !NOENCRYPTION */ + if (cc = krb_rd_priv(priv_buf,(unsigned long) tkt_len, schedule, + cred->session, faddr, laddr, msg_data)) + return(cc); + + /* fetch the (modified) checksum */ + (void) bcopy((char *)msg_data->app_data, (char *)&cksum, + sizeof(cksum)); + cksum = ntohl(cksum); + + /* if it doesn't match, fail */ + if (cksum != checksum + 1) + return(KFAILURE); /* XXX */ + } + return(KSUCCESS); +} + +#ifdef ATHENA_COMPAT +/* + * krb_sendsvc + */ + +int +krb_sendsvc(fd, service) +int fd; +char *service; +{ + /* write the service name length and then the service name to + the fd */ + long serv_length; + int cc; + + serv_length = htonl((unsigned long)strlen(service)); + if ((cc = krb_net_write(fd, (char *) &serv_length, + sizeof(serv_length))) + != sizeof(serv_length)) + return(cc); + if ((cc = krb_net_write(fd, service, strlen(service))) + != strlen(service)) + return(cc); + return(KSUCCESS); +} +#endif ATHENA_COMPAT diff --git a/src/lib/krb425/set_key.c b/src/lib/krb425/set_key.c new file mode 100644 index 000000000..8c4a70d86 --- /dev/null +++ b/src/lib/krb425/set_key.c @@ -0,0 +1,42 @@ +/* + * $Source$ + * $Author$ + * + * Copyright 1990 by the Massachusetts Institute of Technology. + * + * For copying and distribution information, please see the file + * . + * + * krb_set_key for krb425 + */ + +#if !defined(lint) && !defined(SABER) +static char rcsid_set_key_c[] = +"$Id$"; +#endif /* !lint & !SABER */ + +#include +#include "krb425.h" + +int +krb_set_key(key, cvt) +char *key; +int cvt; +{ + static krb5_keyblock keyblock; + + if (cvt) { + if (keyblock.contents) + free((char *)keyblock.contents); + mit_des_string_to_key(KEYTYPE_DES, &keyblock, 0, 0); + } else { + if (!keyblock.contents && + !(keyblock.contents = (krb5_octet *)malloc(8))) { + return(KFAILURE); + } + keyblock.length = 8; + keyblock.keytype = KEYTYPE_DES; + bcopy(key, keyblock.contents,8); + } + return(KSUCCESS); +} -- 2.26.2