summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2007-12-19 07:45:32 +0000
committerRainer Gerhards <rgerhards@adiscon.com>2007-12-19 07:45:32 +0000
commit3cdb6743f792f9b6705b352c9e4a5b502b1f5993 (patch)
tree7376e1c66c8394055fb1d79aa47abdca65c7a0a2
parent83da22c61ec3a3cb3911112591b22aa7d4d037b8 (diff)
downloadrsyslog-3cdb6743f792f9b6705b352c9e4a5b502b1f5993.tar.gz
rsyslog-3cdb6743f792f9b6705b352c9e4a5b502b1f5993.tar.xz
rsyslog-3cdb6743f792f9b6705b352c9e4a5b502b1f5993.zip
applied enhanced gss-api functionality provided by varmojfekoj
-rw-r--r--configure.ac1
-rw-r--r--gss-misc.c10
-rw-r--r--omfwd.c4
-rw-r--r--syslogd.c88
-rw-r--r--syslogd.h1
-rw-r--r--tcpsyslog.c217
-rw-r--r--tcpsyslog.h6
7 files changed, 255 insertions, 72 deletions
diff --git a/configure.ac b/configure.ac
index a6330eba..9a0d019e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -147,7 +147,6 @@ AC_ARG_ENABLE(gssapi_krb5,
if test $want_gssapi_krb5 = yes; then
AC_CHECK_LIB(gssapi_krb5, gss_acquire_cred, [
AC_CHECK_HEADER(gssapi/gssapi.h, [
- AC_MSG_ERROR(GSS-API not ready for prime time yet -- wait for next release);
AC_DEFINE(USE_GSSAPI,,
Define if you want to use GSSAPI)
gss_libs="-lgssapi_krb5"
diff --git a/gss-misc.c b/gss-misc.c
index 68197f01..7a09b1b9 100644
--- a/gss-misc.c
+++ b/gss-misc.c
@@ -85,12 +85,12 @@ static int read_all(int fd, char *buf, unsigned int nbyte)
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) {
+ FD_ZERO(&rfds);
+ FD_SET(fd, &rfds);
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+
if ((ret = select(FD_SETSIZE, &rfds, NULL, NULL, &tv)) <= 0
|| !FD_ISSET(fd, &rfds))
return ret;
diff --git a/omfwd.c b/omfwd.c
index e3ec0266..13ec3b73 100644
--- a/omfwd.c
+++ b/omfwd.c
@@ -171,7 +171,7 @@ CODESTARTfreeInstance
OM_uint32 maj_stat, min_stat;
if (pData->gss_context != GSS_C_NO_CONTEXT) {
- maj_stat = gss_delete_sec_context(&min_stat, pData->gss_context, GSS_C_NO_BUFFER);
+ maj_stat = gss_delete_sec_context(&min_stat, &pData->gss_context, GSS_C_NO_BUFFER);
if (maj_stat != GSS_S_COMPLETE)
display_status("deleting context", maj_stat, min_stat);
}
@@ -1146,7 +1146,7 @@ ENDqueryEtryPt
#ifdef USE_GSSAPI
-static rsRetVal setGSSMode(void *pVal, uchar *mode)
+static rsRetVal setGSSMode(void __attribute__((unused)) *pVal, uchar *mode)
{
if (!strcmp((char *) mode, "none")) {
gss_mode = GSSMODE_NONE;
diff --git a/syslogd.c b/syslogd.c
index c0284c83..d80a6ebb 100644
--- a/syslogd.c
+++ b/syslogd.c
@@ -633,6 +633,10 @@ static struct AllowedSenders *pAllowedSenders_UDP = NULL; /* the roots of the al
struct AllowedSenders *pAllowedSenders_TCP = NULL; /* lists. If NULL, all senders are ok! */
static struct AllowedSenders *pLastAllowedSenders_UDP = NULL; /* and now the pointers to the last */
static struct AllowedSenders *pLastAllowedSenders_TCP = NULL; /* element in the respective list */
+#ifdef USE_GSSAPI
+struct AllowedSenders *pAllowedSenders_GSS = NULL;
+static struct AllowedSenders *pLastAllowedSenders_GSS = NULL;
+#endif
#endif /* #ifdef SYSLOG_INET */
int option_DisallowWarning = 1; /* complain if message from disallowed sender is received */
@@ -926,12 +930,24 @@ static void PrintAllowedSenders(int iListToPrint)
struct AllowedSenders *pSender;
uchar szIP[64];
- assert((iListToPrint == 1) || (iListToPrint == 2));
+ assert((iListToPrint == 1) || (iListToPrint == 2)
+#ifdef USE_GSSAPI
+ || (iListToPrint == 3)
+#endif
+ );
printf("\nAllowed %s Senders:\n",
- (iListToPrint == 1) ? "UDP" : "TCP");
- pSender = (iListToPrint == 1) ?
- pAllowedSenders_UDP : pAllowedSenders_TCP;
+ (iListToPrint == 1) ? "UDP" :
+#ifdef USE_GSSAPI
+ (iListToPrint == 3) ? "GSS" :
+#endif
+ "TCP");
+
+ pSender = (iListToPrint == 1) ? pAllowedSenders_UDP :
+#ifdef USE_GSSAPI
+ (iListToPrint == 3) ? pAllowedSenders_GSS :
+#endif
+ pAllowedSenders_TCP;
if(pSender == NULL) {
printf("\tNo restrictions set.\n");
} else {
@@ -1054,7 +1070,6 @@ int isAllowedSender(struct AllowedSenders *pAllowRoot, struct sockaddr *pFrom, c
if (MaskCmp (&(pAllow->allowedSender), pAllow->SignificantBits, pFrom, pszFromHost))
return 1;
}
- dbgprintf("%s is not an allowed sender\n", pszFromHost);
return 0;
}
#endif /* #ifdef SYSLOG_INET */
@@ -1615,7 +1630,7 @@ void getCurrTime(struct syslogTime *t)
static int usage(void)
{
fprintf(stderr, "usage: rsyslogd [-46AdhqQvw] [-l hostlist] [-m markinterval] [-n] [-p path]\n" \
- " [-s domainlist] [-r[port]] [-tport[,max-sessions]] [-f conffile] [-i pidfile] [-x]\n");
+ " [-s domainlist] [-r[port]] [-tport[,max-sessions]] [-gport[,max-sessions]] [-f conffile] [-i pidfile] [-x]\n");
exit(1); /* "good" exit - done to terminate usage() */
}
@@ -3507,6 +3522,10 @@ static void die(int sig)
if(sockTCPLstn != NULL && *sockTCPLstn) {
deinit_tcp_listener();
}
+#ifdef USE_GSSAPI
+ if(bEnableTCP & ALLOWEDMETHOD_GSS)
+ TCPSessGSSDeinit();
+#endif
#endif
/* Clean-up files. */
@@ -3597,6 +3616,11 @@ static rsRetVal addAllowedSenderLine(char* pName, uchar** ppRestOfConfLine)
} else if(!strcasecmp(pName, "tcp")) {
ppRoot = &pAllowedSenders_TCP;
ppLast = &pLastAllowedSenders_TCP;
+#ifdef USE_GSSAPI
+ } else if(!strcasecmp(pName, "gss")) {
+ ppRoot = &pAllowedSenders_GSS;
+ ppLast = &pLastAllowedSenders_GSS;
+#endif
} else {
logerrorSz("Invalid protocol '%s' in allowed sender "
"list, line ignored", pName);
@@ -4103,6 +4127,9 @@ static void dbgPrintInitInfo(void)
/* now the allowedSender lists: */
PrintAllowedSenders(1); /* UDP */
PrintAllowedSenders(2); /* TCP */
+#ifdef USE_GSSAPI
+ PrintAllowedSenders(3); /* GSS */
+#endif
printf("\n");
#endif /* #ifdef SYSLOG_INET */
@@ -4284,9 +4311,19 @@ init(void)
clearAllowedSenders (pAllowedSenders_TCP);
pAllowedSenders_TCP = NULL;
}
+#ifdef USE_GSSAPI
+ if (pAllowedSenders_GSS != NULL) {
+ clearAllowedSenders (pAllowedSenders_GSS);
+ pAllowedSenders_GSS = NULL;
+ }
+#endif
}
- assert(pAllowedSenders_UDP == NULL && pAllowedSenders_TCP == NULL);
+ assert(pAllowedSenders_UDP == NULL && pAllowedSenders_TCP == NULL
+#ifdef USE_GSSAPI
+ && pAllowedSenders_GSS == NULL
+#endif
+ );
#endif
/* I was told by an IPv6 expert that calling getservbyname() seems to be
* still valid, at least for the use case we have. So I re-enabled that
@@ -4421,16 +4458,17 @@ init(void)
* user-selectable option. rgerhards, 2007-06-21
*/
# ifdef USE_GSSAPI
- if(bEnableTCP == 2) {
+ if(bEnableTCP & ALLOWEDMETHOD_GSS) {
if(TCPSessGSSInit()) {
logerror("GSS-API initialization failed\n");
- bEnableTCP = -1;
+ bEnableTCP &= ~(ALLOWEDMETHOD_GSS);
}
}
+ if(bEnableTCP)
# endif
- if((sockTCPLstn = create_tcp_socket()) != NULL) {
- dbgprintf("Opened %d syslog TCP port(s).\n", *sockTCPLstn);
- }
+ if((sockTCPLstn = create_tcp_socket()) != NULL) {
+ dbgprintf("Opened %d syslog TCP port(s).\n", *sockTCPLstn);
+ }
}
}
#endif
@@ -5642,6 +5680,7 @@ static rsRetVal processSelectAfter(int maxfds, int nfds, fd_set *pReadfds, fd_se
(struct sockaddr *)&frominet, (char*)fromHostFQDN)) {
printchopped((char*)fromHost, line, l, finet[i+1], 1);
} else {
+ dbgprintf("%s is not an allowed sender\n", (char*)fromHostFQDN);
if(option_DisallowWarning) {
logerrorSz("UDP message from disallowed sender %s discarded",
(char*)fromHost);
@@ -5666,7 +5705,7 @@ static rsRetVal processSelectAfter(int maxfds, int nfds, fd_set *pReadfds, fd_se
if (FD_ISSET(sockTCPLstn[i+1], pReadfds)) {
dbgprintf("New connect on TCP inetd socket: #%d\n", sockTCPLstn[i+1]);
# ifdef USE_GSSAPI
- if(bEnableTCP == 2)
+ if(bEnableTCP & ALLOWEDMETHOD_GSS)
TCPSessGSSAccept(sockTCPLstn[i+1]);
else
# endif
@@ -5687,14 +5726,15 @@ static rsRetVal processSelectAfter(int maxfds, int nfds, fd_set *pReadfds, fd_se
/* Receive message */
# ifdef USE_GSSAPI
- if(bEnableTCP == 2)
+ int allowedMethods = pTCPSessions[iTCPSess].allowedMethods;
+ if(allowedMethods & ALLOWEDMETHOD_GSS)
state = TCPSessGSSRecv(iTCPSess, buf, sizeof(buf));
else
# endif
state = recv(fdSess, buf, sizeof(buf), 0);
if(state == 0) {
# ifdef USE_GSSAPI
- if(bEnableTCP == 2)
+ if(allowedMethods & ALLOWEDMETHOD_GSS)
TCPSessGSSClose(iTCPSess);
else {
# endif
@@ -5709,7 +5749,7 @@ static rsRetVal processSelectAfter(int maxfds, int nfds, fd_set *pReadfds, fd_se
logerrorInt("TCP session %d will be closed, error ignored\n",
fdSess);
# ifdef USE_GSSAPI
- if(bEnableTCP == 2)
+ if(allowedMethods & ALLOWEDMETHOD_GSS)
TCPSessGSSClose(iTCPSess);
else
# endif
@@ -5724,7 +5764,7 @@ static rsRetVal processSelectAfter(int maxfds, int nfds, fd_set *pReadfds, fd_se
"previous messages for reason(s)\n",
iTCPSess);
# ifdef USE_GSSAPI
- if(bEnableTCP == 2)
+ if(allowedMethods & ALLOWEDMETHOD_GSS)
TCPSessGSSClose(iTCPSess);
else
# endif
@@ -6039,6 +6079,11 @@ static void printVersion(void)
#else
printf("\tSYSLOG_INET (Internet/remote support):\tNo\n");
#endif
+#if defined(SYSLOG_INET) && defined(USE_GSSAPI)
+ printf("\tFEATURE_GSSAPI (GSSAPI Kerberos 5 support):\tYes\n");
+#else
+ printf("\tFEATURE_GSSAPI (GSSAPI Kerberos 5 support):\tNo\n");
+#endif
#ifndef NDEBUG
printf("\tFEATURE_DEBUG (debug build, slow code):\tYes\n");
#else
@@ -6182,8 +6227,9 @@ int main(int argc, char **argv)
break;
case 'g': /* enable tcp gssapi logging */
#if defined(SYSLOG_INET) && defined(USE_GSSAPI)
- configureTCPListen(optarg);
- bEnableTCP = 2;
+ if (!bEnableTCP)
+ configureTCPListen(optarg);
+ bEnableTCP |= ALLOWEDMETHOD_GSS;
#else
fprintf(stderr, "rsyslogd: -g not valid - not compiled with gssapi support");
#endif
@@ -6241,7 +6287,9 @@ int main(int argc, char **argv)
break;
case 't': /* enable tcp logging */
#ifdef SYSLOG_INET
- configureTCPListen(optarg);
+ if (!bEnableTCP)
+ configureTCPListen(optarg);
+ bEnableTCP |= ALLOWEDMETHOD_TCP;
#else
fprintf(stderr, "rsyslogd: -t not valid - not compiled with network support");
#endif
diff --git a/syslogd.h b/syslogd.h
index fe58b9b9..24341b21 100644
--- a/syslogd.h
+++ b/syslogd.h
@@ -87,6 +87,7 @@ extern char **StripDomains;
extern char *LocalDomain;
extern int bDropMalPTRMsgs;
extern struct AllowedSenders *pAllowedSenders_TCP;
+extern struct AllowedSenders *pAllowedSenders_GSS;
extern char ctty[];
#endif /* #ifndef SYSLOGD_H_INCLUDED */
diff --git a/tcpsyslog.c b/tcpsyslog.c
index d187d6c5..022a5fc4 100644
--- a/tcpsyslog.c
+++ b/tcpsyslog.c
@@ -78,7 +78,7 @@ int *sockTCPLstn = NULL; /* read-only after startup, modified by restart */
struct TCPSession *pTCPSessions;
/* The thread-safeness of the sesion table is doubtful */
#ifdef USE_GSSAPI
-static gss_cred_id_t gss_server_creds;
+static gss_cred_id_t gss_server_creds = GSS_C_NO_CREDENTIAL;
char *gss_listen_service_name = NULL;
#endif
@@ -100,7 +100,6 @@ void configureTCPListen(char *cOptarg)
register char *pArg = cOptarg;
assert(cOptarg != NULL);
- bEnableTCP = -1; /* enable TCP listening */
/* extract port */
i = 0;
@@ -167,6 +166,7 @@ static int TCPSessInit(void)
#ifdef USE_GSSAPI
pTCPSessions[i].gss_flags = 0;
pTCPSessions[i].gss_context = GSS_C_NO_CONTEXT;
+ pTCPSessions[i].allowedMethods = 0;
#endif
}
return(0);
@@ -230,7 +230,7 @@ void deinit_tcp_listener(void)
close(fd);
free(pTCPSessions[iTCPSess].fromHost);
#ifdef USE_GSSAPI
- if(bEnableTCP == 2) {
+ if(bEnableTCP & ALLOWEDMETHOD_GSS) {
OM_uint32 maj_stat, min_stat;
maj_stat = gss_delete_sec_context(&min_stat, &pTCPSessions[iTCPSess].gss_context, GSS_C_NO_BUFFER);
if (maj_stat != GSS_S_COMPLETE)
@@ -421,6 +421,9 @@ int TCPSessAccept(int fd)
uchar fromHost[NI_MAXHOST];
uchar fromHostFQDN[NI_MAXHOST];
char *pBuf;
+#ifdef USE_GSSAPI
+ char allowedMethods = 0;
+#endif
newConn = accept(fd, (struct sockaddr*) &addr, &addrlen);
if (newConn < 0) {
@@ -454,7 +457,21 @@ int TCPSessAccept(int fd)
* configured to do this).
* rgerhards, 2005-09-26
*/
- if(!isAllowedSender(pAllowedSenders_TCP, (struct sockaddr *)&addr, (char*)fromHostFQDN)) {
+#ifdef USE_GSSAPI
+ if((bEnableTCP & ALLOWEDMETHOD_TCP) &&
+ isAllowedSender(pAllowedSenders_TCP, (struct sockaddr *)&addr, (char*)fromHostFQDN))
+ allowedMethods |= ALLOWEDMETHOD_TCP;
+ if((bEnableTCP & ALLOWEDMETHOD_GSS) &&
+ isAllowedSender(pAllowedSenders_GSS, (struct sockaddr *)&addr, (char*)fromHostFQDN))
+ allowedMethods |= ALLOWEDMETHOD_GSS;
+ if(allowedMethods)
+ pTCPSessions[iSess].allowedMethods = allowedMethods;
+ else
+#else
+ if(!isAllowedSender(pAllowedSenders_TCP, (struct sockaddr *)&addr, (char*)fromHostFQDN))
+#endif
+ {
+ dbgprintf("%s is not an allowed sender\n", (char *) fromHostFQDN);
if(option_DisallowWarning) {
errno = 0;
logerrorSz("TCP message from disallowed sender %s discarded",
@@ -707,7 +724,10 @@ int TCPSessGSSInit(void)
gss_buffer_desc name_buf;
gss_name_t server_name;
OM_uint32 maj_stat, min_stat;
-
+
+ if (gss_server_creds != GSS_C_NO_CREDENTIAL)
+ return 0;
+
name_buf.value = (gss_listen_service_name == NULL) ? "host" : gss_listen_service_name;
name_buf.length = strlen(name_buf.value) + 1;
maj_stat = gss_import_name(&min_stat, &name_buf, GSS_C_NT_HOSTBASED_SERVICE, &server_name);
@@ -734,60 +754,159 @@ int TCPSessGSSAccept(int fd)
{
gss_buffer_desc send_tok, recv_tok;
gss_name_t client;
- gss_OID doid;
OM_uint32 maj_stat, min_stat, acc_sec_min_stat;
int iSess;
gss_ctx_id_t *context;
OM_uint32 *sess_flags;
int fdSess;
+ char allowedMethods;
if ((iSess = TCPSessAccept(fd)) == -1)
return -1;
- context = &pTCPSessions[iSess].gss_context;
- *context = GSS_C_NO_CONTEXT;
- sess_flags = &pTCPSessions[iSess].gss_flags;
- fdSess = pTCPSessions[iSess].sock;
-
- do {
- if (recv_token(fdSess, &recv_tok) <= 0)
- return -1;
-
- maj_stat = gss_accept_sec_context(&acc_sec_min_stat, context, gss_server_creds,
- &recv_tok, GSS_C_NO_CHANNEL_BINDINGS, &client,
- NULL, &send_tok, sess_flags, NULL, NULL);
- if (recv_tok.value) {
- free(recv_tok.value);
- recv_tok.value = NULL;
- }
- if (send_tok.length != 0) {
- if (send_token(fdSess, &send_tok) < 0) {
+ allowedMethods = pTCPSessions[iSess].allowedMethods;
+ if (allowedMethods & ALLOWEDMETHOD_GSS) {
+ /* Buffer to store raw message in case that
+ * gss authentication fails halfway through.
+ */
+ char buf[MAXLINE];
+ int ret = 0;
+
+ dbgprintf("GSS-API Trying to accept TCP session %d\n", iSess);
+
+ fdSess = pTCPSessions[iSess].sock;
+ if (allowedMethods & ALLOWEDMETHOD_TCP) {
+ int len;
+ fd_set fds;
+ struct timeval tv;
+
+ do {
+ FD_ZERO(&fds);
+ FD_SET(fdSess, &fds);
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+ ret = select(fdSess + 1, &fds, NULL, NULL, &tv);
+ } while (ret < 0 && errno == EINTR);
+ if (ret < 0) {
+ logerrorInt("TCP session %d will be closed, error ignored\n", iSess);
+ TCPSessClose(iSess);
return -1;
+ } else if (ret == 0) {
+ dbgprintf("GSS-API Reverting to plain TCP\n");
+ pTCPSessions[iSess].allowedMethods = ALLOWEDMETHOD_TCP;
+ return 0;
}
- gss_release_buffer(&min_stat, &send_tok);
- }
- if (maj_stat != GSS_S_COMPLETE
- && maj_stat != GSS_S_CONTINUE_NEEDED) {
- display_status("accepting context", maj_stat,
- acc_sec_min_stat);
- if (*context != GSS_C_NO_CONTEXT)
- gss_delete_sec_context(&min_stat, context,
- GSS_C_NO_BUFFER);
- return -1;
- }
- } while (maj_stat == GSS_S_CONTINUE_NEEDED);
+ do {
+ ret = recv(fdSess, buf, sizeof (buf), MSG_PEEK);
+ } while (ret < 0 && errno == EINTR);
+ if (ret <= 0) {
+ if (ret == 0)
+ dbgprintf("GSS-API Connection closed by peer\n");
+ else
+ logerrorInt("TCP session %d will be closed, error ignored\n", iSess);
+ TCPSessClose(iSess);
+ return -1;
+ }
- maj_stat = gss_display_name(&min_stat, client, &recv_tok, NULL);
- if (maj_stat != GSS_S_COMPLETE)
- display_status("displaying name", maj_stat, min_stat);
- gss_release_name(&min_stat, &client);
+ if (ret < 4) {
+ dbgprintf("GSS-API Reverting to plain TCP\n");
+ pTCPSessions[iSess].allowedMethods = ALLOWEDMETHOD_TCP;
+ return 0;
+ } else if (ret == 4) {
+ /* The client might has been interupted after sending
+ * the data length (4B), give him another chance.
+ */
+ sleep(1);
+ do {
+ ret = recv(fdSess, buf, sizeof (buf), MSG_PEEK);
+ } while (ret < 0 && errno == EINTR);
+ if (ret <= 0) {
+ if (ret == 0)
+ dbgprintf("GSS-API Connection closed by peer\n");
+ else
+ logerrorInt("TCP session %d will be closed, error ignored\n", iSess);
+ TCPSessClose(iSess);
+ return -1;
+ }
+ }
- dbgprintf("GSS-API Accepted connection from: %s\n", recv_tok.value);
- gss_release_buffer(&min_stat, &recv_tok);
+ len = ntohl((buf[0] << 24)
+ | (buf[1] << 16)
+ | (buf[2] << 8)
+ | buf[3]);
+ if ((ret - 4) < len || len == 0) {
+ dbgprintf("GSS-API Reverting to plain TCP\n");
+ pTCPSessions[iSess].allowedMethods = ALLOWEDMETHOD_TCP;
+ return 0;
+ }
+ }
- dbgprintf("GSS-API Provided context flags:\n");
- display_ctx_flags(*sess_flags);
+ context = &pTCPSessions[iSess].gss_context;
+ *context = GSS_C_NO_CONTEXT;
+ sess_flags = &pTCPSessions[iSess].gss_flags;
+ do {
+ if (recv_token(fdSess, &recv_tok) <= 0) {
+ logerrorInt("TCP session %d will be closed, error ignored\n", iSess);
+ TCPSessClose(iSess);
+ return -1;
+ }
+ maj_stat = gss_accept_sec_context(&acc_sec_min_stat, context, gss_server_creds,
+ &recv_tok, GSS_C_NO_CHANNEL_BINDINGS, &client,
+ NULL, &send_tok, sess_flags, NULL, NULL);
+ if (recv_tok.value) {
+ free(recv_tok.value);
+ recv_tok.value = NULL;
+ }
+ if (maj_stat != GSS_S_COMPLETE
+ && maj_stat != GSS_S_CONTINUE_NEEDED) {
+ gss_release_buffer(&min_stat, &send_tok);
+ if (*context != GSS_C_NO_CONTEXT)
+ gss_delete_sec_context(&min_stat, context, GSS_C_NO_BUFFER);
+ if ((allowedMethods & ALLOWEDMETHOD_TCP) &&
+ (GSS_ROUTINE_ERROR(maj_stat) == GSS_S_DEFECTIVE_TOKEN)) {
+ dbgprintf("GSS-API Reverting to plain TCP\n");
+ dbgprintf("tcp session socket with new data: #%d\n", fdSess);
+ if(TCPSessDataRcvd(iSess, buf, ret) == 0) {
+ logerrorInt("Tearing down TCP Session %d - see "
+ "previous messages for reason(s)\n",
+ iSess);
+ TCPSessClose(iSess);
+ return -1;
+ }
+ pTCPSessions[iSess].allowedMethods = ALLOWEDMETHOD_TCP;
+ return 0;
+ }
+ display_status("accepting context", maj_stat,
+ acc_sec_min_stat);
+ TCPSessClose(iSess);
+ return -1;
+ }
+ if (send_tok.length != 0) {
+ if (send_token(fdSess, &send_tok) < 0) {
+ gss_release_buffer(&min_stat, &send_tok);
+ logerrorInt("TCP session %d will be closed, error ignored\n", iSess);
+ if (*context != GSS_C_NO_CONTEXT)
+ gss_delete_sec_context(&min_stat, context, GSS_C_NO_BUFFER);
+ TCPSessClose(iSess);
+ return -1;
+ }
+ gss_release_buffer(&min_stat, &send_tok);
+ }
+ } while (maj_stat == GSS_S_CONTINUE_NEEDED);
+
+ maj_stat = gss_display_name(&min_stat, client, &recv_tok, NULL);
+ if (maj_stat != GSS_S_COMPLETE)
+ display_status("displaying name", maj_stat, min_stat);
+ else
+ dbgprintf("GSS-API Accepted connection from: %s\n", recv_tok.value);
+ gss_release_name(&min_stat, &client);
+ gss_release_buffer(&min_stat, &recv_tok);
+
+ dbgprintf("GSS-API Provided context flags:\n");
+ display_ctx_flags(*sess_flags);
+ pTCPSessions[iSess].allowedMethods = ALLOWEDMETHOD_GSS;
+ }
return 0;
}
@@ -846,9 +965,19 @@ void TCPSessGSSClose(int iSess) {
display_status("deleting context", maj_stat, min_stat);
*context = GSS_C_NO_CONTEXT;
pTCPSessions[iSess].gss_flags = 0;
+ pTCPSessions[iSess].allowedMethods = 0;
TCPSessClose(iSess);
}
+
+
+void TCPSessGSSDeinit(void) {
+ OM_uint32 maj_stat, min_stat;
+
+ maj_stat = gss_release_cred(&min_stat, &gss_server_creds);
+ if (maj_stat != GSS_S_COMPLETE)
+ display_status("releasing credentials", maj_stat, min_stat);
+}
#endif /* #ifdef USE_GSSAPI */
diff --git a/tcpsyslog.h b/tcpsyslog.h
index 45ad717e..adf98f0c 100644
--- a/tcpsyslog.h
+++ b/tcpsyslog.h
@@ -40,6 +40,7 @@ struct TCPSession {
#if defined(SYSLOG_INET) && defined(USE_GSSAPI)
OM_uint32 gss_flags;
gss_ctx_id_t gss_context;
+ char allowedMethods;
#endif
};
@@ -50,8 +51,12 @@ extern int bEnableTCP;
extern struct TCPSession *pTCPSessions;
#if defined(SYSLOG_INET) && defined(USE_GSSAPI)
extern char *gss_listen_service_name;
+
+#define ALLOWEDMETHOD_GSS 2
#endif
+#define ALLOWEDMETHOD_TCP 1
+
/* prototypes */
void deinit_tcp_listener(void);
int *create_tcp_socket(void);
@@ -66,6 +71,7 @@ int TCPSessGSSInit(void);
int TCPSessGSSAccept(int fd);
int TCPSessGSSRecv(int fd, void *buf, size_t buf_len);
void TCPSessGSSClose(int sess);
+void TCPSessGSSDeinit(void);
#endif
#endif /* #ifndef TCPSYSLOG_H_INCLUDED */