X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=common-src%2Fkrb5-security.c;h=c3075fa9bc2456d0aafd8afec557e4138f42d337;hb=b116e9366c7b2ea2c2eb53b0a13df4090e176235;hp=dcf778e6567df9d2e062cfa866d37668675d9663;hpb=2627875b7d18858bc1f9f7652811e4d8c15a23eb;p=debian%2Famanda diff --git a/common-src/krb5-security.c b/common-src/krb5-security.c index dcf778e..c3075fa 100644 --- a/common-src/krb5-security.c +++ b/common-src/krb5-security.c @@ -37,11 +37,9 @@ #include "util.h" #include "event.h" #include "packet.h" -#include "queue.h" #include "security.h" #include "security-util.h" #include "stream.h" -#include "version.h" #include "sockaddr-util.h" #ifdef KRB5_HEIMDAL_INCLUDES @@ -168,6 +166,9 @@ static int k5_encrypt(void *cookie, void *buf, ssize_t buflen, static int k5_decrypt(void *cookie, void *buf, ssize_t buflen, void **encbuf, ssize_t *encbuflen); +static ssize_t krb5_tcpm_recv_token(struct tcp_conn *rc, int fd, int *handle, + char **errmsg, char **buf, ssize_t *size, + int timeout); /* * This is our interface to the outside world. */ @@ -175,6 +176,7 @@ const security_driver_t krb5_security_driver = { "KRB5", krb5_connect, krb5_accept, + sec_get_authenticated_peer_name_hostname, sec_close, stream_sendpkt, stream_recvpkt, @@ -518,7 +520,8 @@ gss_client( if (maj_stat != (OM_uint32)GSS_S_CONTINUE_NEEDED) break; - rvalue = tcpm_recv_token(rc, rc->read, &rc->handle, &rc->errmsg, + rvalue = krb5_tcpm_recv_token(rc, rc->read, &rc->handle, + &rc->errmsg, (void *)&recv_tok.value, (ssize_t *)&recv_tok.length, 60); if (rvalue <= 0) { @@ -551,7 +554,6 @@ gss_server( gss_name_t gss_name; gss_cred_id_t gss_creds; char *p, *realm, *msg; - uid_t euid; int rval = -1; int rvalue; char errbuf[256]; @@ -566,16 +568,9 @@ gss_server( * out of the default keytab. We also need to be root in * gss_accept_context() thanks to the replay cache code. */ - euid = geteuid(); - if (getuid() != 0) { - g_snprintf(errbuf, SIZEOF(errbuf), - _("real uid is %ld, needs to be 0 to read krb5 host key"), - (long)getuid()); - goto out; - } if (!set_root_privs(0)) { g_snprintf(errbuf, SIZEOF(errbuf), - _("can't seteuid to uid 0: %s"), strerror(errno)); + _("can't take root privileges to read krb5 host key: %s"), strerror(errno)); goto out; } @@ -614,7 +609,8 @@ gss_server( for (recv_tok.length = 0;;) { recv_tok.value = NULL; - rvalue = tcpm_recv_token(rc, rc->read, &rc->handle, &rc->errmsg, + rvalue = krb5_tcpm_recv_token(rc, rc->read, &rc->handle, + &rc->errmsg, /* (void *) is to avoid type-punning warning */ (char **)(void *)&recv_tok.value, (ssize_t *)&recv_tok.length, 60); @@ -1197,3 +1193,122 @@ common_exit: return(result); #endif /* AMANDA_PRINCIPAL */ } + +/* + * return -1 on error + * return 0 on EOF: *handle = H_EOF && *size = 0 if socket closed + * return 0 on EOF: *handle = handle && *size = 0 if stream closed + * return size : *handle = handle && *size = size for data read + */ + +static ssize_t +krb5_tcpm_recv_token( + struct tcp_conn *rc, + int fd, + int * handle, + char ** errmsg, + char ** buf, + ssize_t * size, + int timeout) +{ + unsigned int netint[2]; + + assert(SIZEOF(netint) == 8); + + switch (net_read(fd, &netint, SIZEOF(netint), timeout)) { + case -1: + if (errmsg) + *errmsg = newvstrallocf(*errmsg, _("recv error: %s"), strerror(errno)); + auth_debug(1, _("krb5_tcpm_recv_token: A return(-1)\n")); + return (-1); + case 0: + *size = 0; + *handle = H_EOF; + *errmsg = newvstrallocf(*errmsg, _("SOCKET_EOF")); + auth_debug(1, _("krb5_tcpm_recv_token: A return(0)\n")); + return (0); + default: + break; + } + + *size = (ssize_t)ntohl(netint[0]); + *handle = (int)ntohl(netint[1]); + /* amanda protocol packet can be above NETWORK_BLOCK_BYTES */ + if (*size > 128*NETWORK_BLOCK_BYTES || *size < 0) { + if (isprint((int)(*size ) & 0xFF) && + isprint((int)(*size >> 8 ) & 0xFF) && + isprint((int)(*size >> 16) & 0xFF) && + isprint((int)(*size >> 24) & 0xFF) && + isprint((*handle ) & 0xFF) && + isprint((*handle >> 8 ) & 0xFF) && + isprint((*handle >> 16) & 0xFF) && + isprint((*handle >> 24) & 0xFF)) { + char s[101]; + int i; + s[0] = ((int)(*size) >> 24) & 0xFF; + s[1] = ((int)(*size) >> 16) & 0xFF; + s[2] = ((int)(*size) >> 8) & 0xFF; + s[3] = ((int)(*size) ) & 0xFF; + s[4] = (*handle >> 24) & 0xFF; + s[5] = (*handle >> 16) & 0xFF; + s[6] = (*handle >> 8 ) & 0xFF; + s[7] = (*handle ) & 0xFF; + i = 8; s[i] = ' '; + while(i<100 && isprint((int)s[i]) && s[i] != '\n') { + switch(net_read(fd, &s[i], 1, 0)) { + case -1: s[i] = '\0'; break; + case 0: s[i] = '\0'; break; + default: + dbprintf(_("read: %c\n"), s[i]); i++; s[i]=' '; + break; + } + } + s[i] = '\0'; + *errmsg = newvstrallocf(*errmsg, _("krb5_tcpm_recv_token: invalid size: %s"), s); + dbprintf(_("krb5_tcpm_recv_token: invalid size %s\n"), s); + } else { + *errmsg = newvstrallocf(*errmsg, _("krb5_tcpm_recv_token: invalid size")); + dbprintf(_("krb5_tcpm_recv_token: invalid size %zd\n"), *size); + } + *size = -1; + return -1; + } + amfree(*buf); + *buf = alloc((size_t)*size); + + if(*size == 0) { + auth_debug(1, _("krb5_tcpm_recv_token: read EOF from %d\n"), *handle); + *errmsg = newvstrallocf(*errmsg, _("EOF")); + return 0; + } + switch (net_read(fd, *buf, (size_t)*size, timeout)) { + case -1: + if (errmsg) + *errmsg = newvstrallocf(*errmsg, _("recv error: %s"), strerror(errno)); + auth_debug(1, _("krb5_tcpm_recv_token: B return(-1)\n")); + return (-1); + case 0: + *size = 0; + *errmsg = newvstrallocf(*errmsg, _("SOCKET_EOF")); + auth_debug(1, _("krb5_tcpm_recv_token: B return(0)\n")); + return (0); + default: + break; + } + + auth_debug(1, _("krb5_tcpm_recv_token: read %zd bytes from %d\n"), *size, *handle); + + if (*size > 0 && rc->driver->data_decrypt != NULL) { + void *decbuf; + ssize_t decsize; + rc->driver->data_decrypt(rc, *buf, *size, &decbuf, &decsize); + if (*buf != (char *)decbuf) { + amfree(*buf); + *buf = (char *)decbuf; + } + *size = decsize; + } + + return((*size)); +} +