summaryrefslogtreecommitdiffstats
path: root/tcpsyslog.c
diff options
context:
space:
mode:
Diffstat (limited to 'tcpsyslog.c')
-rw-r--r--tcpsyslog.c187
1 files changed, 180 insertions, 7 deletions
diff --git a/tcpsyslog.c b/tcpsyslog.c
index d2a4b724..c2591663 100644
--- a/tcpsyslog.c
+++ b/tcpsyslog.c
@@ -42,10 +42,15 @@
#if HAVE_FCNTL_H
#include <fcntl.h>
#endif
-
+#if defined(SYSLOG_INET) && defined(USE_GSSAPI)
+#include <gssapi.h>
+#endif
#include "syslogd.h"
#include "syslogd-types.h"
#include "net.h"
+#if defined(SYSLOG_INET) && defined(USE_GSSAPI)
+#include "gss-misc.h"
+#endif
#include "tcpsyslog.h"
/********************************************************************
* ### SYSLOG/TCP CODE ###
@@ -71,7 +76,10 @@ int bEnableTCP = 0; /* read-only after startup */
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;
+char *gss_listen_service_name = NULL;
+#endif
/* configure TCP listener settings. This is called during command
* line parsing. The argument following -t is supplied as an argument.
@@ -155,6 +163,10 @@ static int TCPSessInit(void)
pTCPSessions[i].iMsg = 0; /* just make sure... */
pTCPSessions[i].bAtStrtOfFram = 1; /* indicate frame header expected */
pTCPSessions[i].eFraming = TCP_FRAMING_OCTET_STUFFING; /* just make sure... */
+#ifdef USE_GSSAPI
+ pTCPSessions[i].gss_flags = 0;
+ pTCPSessions[i].gss_context = GSS_C_NO_CONTEXT;
+#endif
}
return(0);
}
@@ -215,6 +227,15 @@ void deinit_tcp_listener(void)
fd = pTCPSessions[iTCPSess].sock;
dbgprintf("Closing TCP Session %d\n", fd);
close(fd);
+ free(pTCPSessions[iTCPSess].fromHost);
+#ifdef USE_GSSAPI
+ if(bEnableTCP == 2) {
+ 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)
+ display_status("deleting context", maj_stat, min_stat);
+ }
+#endif
/* now get next... */
iTCPSess = TCPSessGetNxtSess(iTCPSess);
}
@@ -389,7 +410,7 @@ int *create_tcp_socket(void)
* is no more space left in the connection table, the new TCP
* connection is immediately dropped.
*/
-void TCPSessAccept(int fd)
+int TCPSessAccept(int fd)
{
int newConn;
int iSess;
@@ -403,7 +424,7 @@ void TCPSessAccept(int fd)
newConn = accept(fd, (struct sockaddr*) &addr, &addrlen);
if (newConn < 0) {
logerror("tcp accept, ignoring error and connection request");
- return;
+ return -1;
}
/* Add to session list */
@@ -412,7 +433,7 @@ void TCPSessAccept(int fd)
errno = 0;
logerror("too many tcp sessions - dropping incoming request");
close(newConn);
- return;
+ return -1;
}
/* OK, we have a "good" index... */
@@ -423,7 +444,7 @@ void TCPSessAccept(int fd)
* Error message has been generated by cvthname.
*/
close (newConn);
- return;
+ return -1;
}
/* Here we check if a host is permitted to send us
@@ -439,7 +460,7 @@ void TCPSessAccept(int fd)
(char*)fromHost);
}
close(newConn);
- return;
+ return -1;
}
/* OK, we have an allowed sender, so let's continue */
@@ -454,6 +475,7 @@ void TCPSessAccept(int fd)
pTCPSessions[iSess].sock = newConn;
pTCPSessions[iSess].iMsg = 0; /* init msg buffer! */
+ return iSess;
}
@@ -678,6 +700,157 @@ int TCPSessDataRcvd(int iTCPSess, char *pData, int iLen)
}
+#ifdef USE_GSSAPI
+int TCPSessGSSInit(void)
+{
+ gss_buffer_desc name_buf;
+ gss_name_t server_name;
+ OM_uint32 maj_stat, min_stat;
+
+ 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);
+ if (maj_stat != GSS_S_COMPLETE) {
+ display_status("importing name", maj_stat, min_stat);
+ return -1;
+ }
+
+ maj_stat = gss_acquire_cred(&min_stat, server_name, 0,
+ GSS_C_NULL_OID_SET, GSS_C_ACCEPT,
+ &gss_server_creds, NULL, NULL);
+ if (maj_stat != GSS_S_COMPLETE) {
+ display_status("acquiring credentials", maj_stat, min_stat);
+ return -1;
+ }
+
+ gss_release_name(&min_stat, &server_name);
+ dbgprintf("GSS-API initialized\n");
+ return 0;
+}
+
+
+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;
+
+ 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) {
+ return -1;
+ }
+
+ 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);
+
+ 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);
+
+ dbgprintf("GSS-API Accepted connection from: %s\n", recv_tok.value);
+ gss_release_buffer(&min_stat, &recv_tok);
+
+ dbgprintf("GSS-API Provided context flags:\n");
+ display_ctx_flags(*sess_flags);
+
+ return 0;
+}
+
+
+int TCPSessGSSRecv(int iSess, void *buf, size_t buf_len)
+{
+ gss_buffer_desc xmit_buf, msg_buf;
+ gss_ctx_id_t *context;
+ OM_uint32 maj_stat, min_stat;
+ int fdSess;
+ int conf_state;
+ int state, len;
+
+ fdSess = pTCPSessions[iSess].sock;
+ if ((state = recv_token(fdSess, &xmit_buf)) <= 0)
+ return state;
+
+ context = &pTCPSessions[iSess].gss_context;
+ maj_stat = gss_unwrap(&min_stat, *context, &xmit_buf, &msg_buf,
+ &conf_state, (gss_qop_t *) NULL);
+ if (maj_stat != GSS_S_COMPLETE) {
+ display_status("unsealing message", maj_stat, min_stat);
+ if (xmit_buf.value) {
+ free(xmit_buf.value);
+ xmit_buf.value = 0;
+ }
+ return (-1);
+ }
+ if (xmit_buf.value) {
+ free(xmit_buf.value);
+ xmit_buf.value = 0;
+ }
+
+ len = msg_buf.length < buf_len ? msg_buf.length : buf_len;
+ memcpy(buf, msg_buf.value, len);
+ gss_release_buffer(&min_stat, &msg_buf);
+
+ return len;
+}
+
+
+void TCPSessGSSClose(int iSess) {
+ OM_uint32 maj_stat, min_stat;
+ gss_ctx_id_t *context;
+
+ if(iSess < 0 || iSess > iTCPSessMax) {
+ errno = 0;
+ logerror("internal error, trying to close an invalid TCP session!");
+ return;
+ }
+
+ context = &pTCPSessions[iSess].gss_context;
+ maj_stat = gss_delete_sec_context(&min_stat, context, GSS_C_NO_BUFFER);
+ if (maj_stat != GSS_S_COMPLETE)
+ display_status("deleting context", maj_stat, min_stat);
+ *context = GSS_C_NO_CONTEXT;
+ pTCPSessions[iSess].gss_flags = 0;
+
+ TCPSessClose(iSess);
+}
+#endif /* #ifdef USE_GSSAPI */
+
+
#endif
/********************************************************************
* ### END OF SYSLOG/TCP CODE ###