diff --git a/lib/krb5/Makefile.am b/lib/krb5/Makefile.am index 95ba21ae0..24b8502b1 100644 --- a/lib/krb5/Makefile.am +++ b/lib/krb5/Makefile.am @@ -15,7 +15,7 @@ libkrb5_a_SOURCES = address.c asn1_glue.c auth_context.c \ keytab.c krbhst.c misc.c mk_priv.c mk_rep.c mk_req.c mk_req_ext.c \ mk_safe.c principal.c principal_p.c rd_priv.c rd_rep.c rd_req.c \ rd_safe.c send_to_kdc.c sendauth.c store.c store_emem.c store_fd.c \ - store_mem.c str2key.c \ + store_mem.c str2key.c net_write.c net_read.c recvauth.c \ error/error.c error/krb5_err.c error/asn1_err.c error/hdb_err.c config_file.c: config_file.y diff --git a/lib/krb5/net_read.c b/lib/krb5/net_read.c new file mode 100644 index 000000000..5cbd32061 --- /dev/null +++ b/lib/krb5/net_read.c @@ -0,0 +1,23 @@ +#include "krb5_locl.h" + +RCSID("$Id$"); + +ssize_t +krb5_net_read (krb5_context context, + int fd, + void *buf, + size_t len) +{ + char *cbuf = (char *)buf; + ssize_t count; + size_t rem = len; + + while (rem > 0) { + count = read (fd, cbuf, rem); + if (count <= 0) + return count; + cbuf += count; + rem -= count; + } + return len; +} diff --git a/lib/krb5/net_write.c b/lib/krb5/net_write.c new file mode 100644 index 000000000..3dede3709 --- /dev/null +++ b/lib/krb5/net_write.c @@ -0,0 +1,23 @@ +#include "krb5_locl.h" + +RCSID("$Id$"); + +ssize_t +krb5_net_write (krb5_context context, + int fd, + void *buf, + size_t len) +{ + char *cbuf = (char *)buf; + ssize_t count; + size_t rem = len; + + while (rem > 0) { + count = write (fd, cbuf, rem); + if (count < 0) + return count; + cbuf += count; + rem -= count; + } + return len; +} diff --git a/lib/krb5/recvauth.c b/lib/krb5/recvauth.c new file mode 100644 index 000000000..e7c9c66be --- /dev/null +++ b/lib/krb5/recvauth.c @@ -0,0 +1,102 @@ +#include "krb5_locl.h" + +RCSID("$Id$"); + +krb5_error_code +krb5_recvauth(krb5_context context, + krb5_auth_context *auth_context, + krb5_pointer p_fd, + char *appl_version, + krb5_principal server, + int32_t flags, + krb5_keytab keytab, + krb5_ticket **ticket) +{ + krb5_error_code ret; + const char *version = "KRB5_SENDAUTH_V1.0"; + char her_version[19]; /* Size ^ */ + char *her_appl_version; + int fd = *((int *)p_fd); + u_int32_t len; + u_char repl; + krb5_data data; + krb5_flags ap_options; + + if (krb5_net_read (context, fd, &len, 4) != 4) + return errno; + len = ntohl(len); + if (len != sizeof(her_version) + || krb5_net_read (context, fd, her_version, len) != len + || strcmp (version, her_version)) { + repl = 1; + krb5_net_write (context, fd, &repl, 1); + return KRB5_SENDAUTH_BADAUTHVERS; + } + + if (krb5_net_read (context, fd, &len, 4) != 4) + return errno; + len = ntohl(len); + if (len != strlen(appl_version) + 1) { + repl = 2; + krb5_net_write (context, fd, &repl, 1); + return KRB5_SENDAUTH_BADAPPLVERS; + } + her_appl_version = malloc (len); + if (her_appl_version == NULL) { + repl = 2; + krb5_net_write (context, fd, &repl, 1); + return ENOMEM; + } + if (krb5_net_read (context, fd, her_appl_version, len) != len + || strcmp (appl_version, her_appl_version)) { + repl = 2; + krb5_net_write (context, fd, &repl, 1); + free (her_appl_version); + return KRB5_SENDAUTH_BADAPPLVERS; + } + free (her_appl_version); + + repl = 0; + if (krb5_net_write (context, fd, &repl, 1) != 1) + return errno; + + if (krb5_net_read (context, fd, &len, 4) != 4) + return errno; + + len = ntohl(len); + data.length = len; + data.data = malloc (len); + if (data.data == NULL) + return ENOMEM; + + if (krb5_net_read (context, fd, data.data, len) != len) + return errno; + + ret = krb5_rd_req (context, + auth_context, + &data, + server, + keytab, + &ap_options, + ticket); + krb5_data_free (&data); + if (ret) + return ret; + + len = 0; + if (krb5_net_write (context, fd, &len, 4) != 4) + return errno; + + if (ap_options & AP_OPTS_MUTUAL_REQUIRED) { + ret = krb5_mk_rep (context, auth_context, &data); + if (ret) + return ret; + + len = htonl(data.length); + if (krb5_net_write (context, fd, &len, 4) != 4 + || krb5_net_write (context, fd, data.data, data.length) != data.length) + return errno; + krb5_data_free (&data); + } + return 0; +}