From f3b3f8cfaf6d43188d333119cbdc049231863cdb Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Tue, 20 Nov 2007 16:08:25 +0000 Subject: applied gssapi patch from varmojfekoj - gss-api is now supported --- gss-misc.c | 210 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 210 insertions(+) create mode 100644 gss-misc.c (limited to 'gss-misc.c') diff --git a/gss-misc.c b/gss-misc.c new file mode 100644 index 00000000..68197f01 --- /dev/null +++ b/gss-misc.c @@ -0,0 +1,210 @@ +#include "config.h" +#if defined(SYSLOG_INET) && defined(USE_GSSAPI) +#include "rsyslog.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef USE_PTHREADS +#include +#else +#include +#endif +#include +#include "syslogd.h" +#include "syslogd-types.h" +#include "srUtils.h" +#include "net.h" +#include "omfwd.h" +#include "template.h" +#include "msg.h" +#include "tcpsyslog.h" +#include "module-template.h" +#include "gss-misc.h" + + +static void display_status_(char *m, OM_uint32 code, int type) +{ + OM_uint32 maj_stat, min_stat, msg_ctx = 0; + gss_buffer_desc msg; + + do { + maj_stat = gss_display_status(&min_stat, code, type, GSS_C_NO_OID, &msg_ctx, &msg); + if (maj_stat != GSS_S_COMPLETE) { + logerrorSz("GSS-API error in gss_display_status called from <%s>\n", m); + break; + } else { + char buf[1024]; + snprintf(buf, sizeof(buf), "GSS-API error %s: %s\n", m, (char *) msg.value); + buf[sizeof(buf)/sizeof(char) - 1] = '\0'; + logerror(buf); + } + if (msg.length != 0) + gss_release_buffer(&min_stat, &msg); + } while (msg_ctx); +} + + +void display_status(char *m, OM_uint32 maj_stat, OM_uint32 min_stat) +{ + display_status_(m, maj_stat, GSS_C_GSS_CODE); + display_status_(m, min_stat, GSS_C_MECH_CODE); +} + + +void display_ctx_flags(OM_uint32 flags) +{ + if (flags & GSS_C_DELEG_FLAG) + dbgprintf("GSS_C_DELEG_FLAG\n"); + if (flags & GSS_C_MUTUAL_FLAG) + dbgprintf("GSS_C_MUTUAL_FLAG\n"); + if (flags & GSS_C_REPLAY_FLAG) + dbgprintf("GSS_C_REPLAY_FLAG\n"); + if (flags & GSS_C_SEQUENCE_FLAG) + dbgprintf("GSS_C_SEQUENCE_FLAG\n"); + if (flags & GSS_C_CONF_FLAG) + dbgprintf("GSS_C_CONF_FLAG\n"); + if (flags & GSS_C_INTEG_FLAG) + dbgprintf("GSS_C_INTEG_FLAG\n"); +} + + +static int read_all(int fd, char *buf, unsigned int nbyte) +{ + int ret; + char *ptr; + fd_set rfds; + struct timeval tv; + + FD_ZERO(&rfds); + FD_SET(fd, &rfds); + tv.tv_sec = 1; + tv.tv_usec = 0; + + for (ptr = buf; nbyte; ptr += ret, nbyte -= ret) { + if ((ret = select(FD_SETSIZE, &rfds, NULL, NULL, &tv)) <= 0 + || !FD_ISSET(fd, &rfds)) + return ret; + ret = recv(fd, ptr, nbyte, 0); + if (ret < 0) { + if (errno == EINTR) + continue; + return (ret); + } else if (ret == 0) { + return (ptr - buf); + } + } + + return (ptr - buf); +} + + +static int write_all(int fd, char *buf, unsigned int nbyte) +{ + int ret; + char *ptr; + + for (ptr = buf; nbyte; ptr += ret, nbyte -= ret) { + ret = send(fd, ptr, nbyte, 0); + if (ret < 0) { + if (errno == EINTR) + continue; + return (ret); + } else if (ret == 0) { + return (ptr - buf); + } + } + + return (ptr - buf); +} + + +int recv_token(int s, gss_buffer_t tok) +{ + int ret; + unsigned char lenbuf[4]; + unsigned int len; + + ret = read_all(s, (char *) lenbuf, 4); + if (ret < 0) { + logerror("GSS-API error reading token length"); + return -1; + } else if (!ret) { + return 0; + } else if (ret != 4) { + logerror("GSS-API error reading token length"); + return -1; + } + + len = ((lenbuf[0] << 24) + | (lenbuf[1] << 16) + | (lenbuf[2] << 8) + | lenbuf[3]); + tok->length = ntohl(len); + + tok->value = (char *) malloc(tok->length ? tok->length : 1); + if (tok->length && tok->value == NULL) { + logerror("Out of memory allocating token data\n"); + return -1; + } + + ret = read_all(s, (char *) tok->value, tok->length); + if (ret < 0) { + logerror("GSS-API error reading token data"); + free(tok->value); + return -1; + } else if (ret != (int) tok->length) { + logerror("GSS-API error reading token data"); + free(tok->value); + return -1; + } + + return 1; +} + + +int send_token(int s, gss_buffer_t tok) +{ + int ret; + unsigned char lenbuf[4]; + unsigned int len; + + if (tok->length > 0xffffffffUL) + abort(); /* TODO: we need to reconsider this, abort() is not really a solution - degrade, but keep running */ + len = htonl(tok->length); + lenbuf[0] = (len >> 24) & 0xff; + lenbuf[1] = (len >> 16) & 0xff; + lenbuf[2] = (len >> 8) & 0xff; + lenbuf[3] = len & 0xff; + + ret = write_all(s, (char *) lenbuf, 4); + if (ret < 0) { + logerror("GSS-API error sending token length"); + return -1; + } else if (ret != 4) { + logerror("GSS-API error sending token length"); + return -1; + } + + ret = write_all(s, tok->value, tok->length); + if (ret < 0) { + logerror("GSS-API error sending token data"); + return -1; + } else if (ret != (int) tok->length) { + logerror("GSS-API error sending token data"); + return -1; + } + + return 0; +} + +#endif /* #if defined(SYSLOG_INET) && defined(USE_GSSAPI) */ -- cgit