static void session_close(struct session *);
int
-daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, SSL *ssl, int isactive, int nullAuthAllowed, int uses_ssl)
+daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out,
+ int isactive, char *passiveClients, int nullAuthAllowed, int uses_ssl)
{
struct daemon_slpars pars; // service loop parameters
char errbuf[PCAP_ERRBUF_SIZE + 1]; // keeps the error string, prior to be printed
char errmsgbuf[PCAP_ERRBUF_SIZE + 1]; // buffer for errors to send to the client
+ int host_port_ok;
+ SSL *ssl = NULL;
int nrecv;
struct rpcap_header header; // RPCAP message general header
uint32 plen; // payload length from header
struct timeval tv; // maximum time the select() can block waiting for data
int retval; // select() return value
- // Set parameters structure
- pars.sockctrl_in = sockctrl_in;
- pars.sockctrl_out = sockctrl_out;
- pars.ssl = ssl;
- pars.protocol_version = 0; // not yet known
- pars.isactive = isactive; // active mode
- pars.nullAuthAllowed = nullAuthAllowed;
-
// We don't have a thread yet.
threaddata.have_thread = 0;
//
*errbuf = 0; // Initialize errbuf
+#ifdef HAVE_OPENSSL
+ //
+ // We have to upgrade to TLS as soon as possible, so that the
+ // whole protocol goes through the encrypted tunnel, including
+ // early error messages.
+ //
+ // Even in active mode, the other end has to initiate the TLS
+ // handshake as we still are the server as far as TLS is concerned,
+ // so we don't check isactive.
+ //
+ if (uses_ssl)
+ {
+ ssl = ssl_promotion_rw(1, pars.sockctrl_in, pars.sockctrl_out, errbuf, PCAP_ERRBUF_SIZE);
+ if (! ssl)
+ {
+ rpcapd_log(LOGPRIO_ERROR, "TLS handshake on control connection failed: %s",
+ errbuf);
+ goto end;
+ }
+ }
+#endif
+
+ // Set parameters structure
+ pars.sockctrl_in = sockctrl_in;
+ pars.sockctrl_out = sockctrl_out;
+ pars.ssl = ssl;
+ pars.protocol_version = 0; // not yet known
+ pars.isactive = isactive; // active mode
+ pars.nullAuthAllowed = nullAuthAllowed;
+
+ //
+ // We have a connection.
+ //
+ // If it's a passive mode connection, check whether the connecting
+ // host is among the ones allowed.
+ //
+ // In either case, we were handed a copy of the host list; free it
+ // as soon as we're done with it.
+ //
+ if (pars.isactive)
+ {
+ // Nothing to do.
+ free(passiveClients);
+ passiveClients = NULL;
+ }
+ else
+ {
+ struct sockaddr_storage from;
+ socklen_t fromlen;
+
+ //
+ // Get the address of the other end of the connection.
+ //
+ fromlen = sizeof(struct sockaddr_storage);
+ if (getpeername(pars.sockctrl_in, (struct sockaddr *)&from,
+ &fromlen) == -1)
+ {
+ sock_geterror("getpeername(): ", errmsgbuf, PCAP_ERRBUF_SIZE);
+ if (rpcap_senderror(pars.sockctrl_out, pars.ssl, 0, PCAP_ERR_NETW, errmsgbuf, errbuf) == -1)
+ rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
+ goto end;
+ }
+
+ //
+ // Are they in the list of host/port combinations we allow?
+ //
+ host_port_ok = (sock_check_hostlist(passiveClients, RPCAP_HOSTLIST_SEP, &from, errmsgbuf, PCAP_ERRBUF_SIZE) == 0);
+ free(passiveClients);
+ passiveClients = NULL;
+ if (!host_port_ok)
+ {
+ //
+ // Sorry, you're not on the guest list.
+ //
+ if (rpcap_senderror(pars.sockctrl_out, pars.ssl, 0, PCAP_ERR_HOSTNOAUTH, errmsgbuf, errbuf) == -1)
+ rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf);
+ goto end;
+ }
+ }
+
//
// The client must first authenticate; loop until they send us a
// message with a version we support and credentials we accept,
session = NULL;
}
+#ifdef HAVE_OPENSSL
+ if (ssl)
+ {
+ SSL_free(ssl);
+ }
+#endif
+
// Print message and return
rpcapd_log(LOGPRIO_DEBUG, "I'm exiting from the child loop");
rpcapd_log(LOGPRIO_DEBUG, "%s", errbuf);
}
//
- // Try to set the standard input and output to /dev/null.
+ // Try to set the standard input, output, and error
+ // to /dev/null.
//
devnull_fd = open("/dev/null", O_RDWR);
if (devnull_fd != -1)
//
(void)dup2(devnull_fd, 0);
(void)dup2(devnull_fd, 1);
+ (void)dup2(devnull_fd, 2);
close(devnull_fd);
}
- SSL *ssl = NULL;
-#ifdef HAVE_OPENSSL
- if (uses_ssl)
- {
- ssl = ssl_promotion_rw(1, sockctrl_in, sockctrl_out, errbuf, PCAP_ERRBUF_SIZE);
- if (! ssl)
- {
- rpcapd_log(LOGPRIO_ERROR, "TLS handshake on control connection failed: %s",
- errbuf);
- exit(2);
- }
- }
-#endif
//
// Handle this client.
// This is passive mode, so we don't care whether we were
// told by the client to close.
//
- (void)daemon_serviceloop(sockctrl_in, sockctrl_out, ssl, 0,
- nullAuthAllowed, uses_ssl);
+ char *hostlist_copy = strdup(hostlist);
+ if (hostlist_copy == NULL)
+ {
+ rpcapd_log(LOGPRIO_ERROR, "Out of memory copying the host/port list");
+ exit(0);
+ }
+ (void)daemon_serviceloop(sockctrl_in, sockctrl_out, 0,
+ hostlist_copy, nullAuthAllowed, uses_ssl);
+
+ sock_close(sockctrl_out, NULL, 0);
//
// Nothing more to do.
//
struct sock_copy {
SOCKET sockctrl;
-# ifdef HAVE_OPENSSL
- SSL *ssl;
-# else
- void *ssl;
-# endif
};
#endif
struct sockaddr_storage from; // generic sockaddr_storage variable
socklen_t fromlen; // keeps the length of the sockaddr_storage variable
- SSL *ssl = NULL;
-
#ifdef _WIN32
HANDLE threadId; // handle for the subthread
u_long off = 0;
return;
}
-#ifdef HAVE_OPENSSL
- /* We have to upgrade to TLS as soon as possible so that the whole protocol
- * goes through the encrypted tunnel, including early error messages. */
- if (uses_ssl)
- {
- ssl = ssl_promotion(1, sockctrl, errbuf, PCAP_ERRBUF_SIZE);
- if (! ssl)
- {
- rpcapd_log(LOGPRIO_ERROR, "TLS handshake on control connection failed: %s",
- errbuf);
- goto error;
- }
- }
-#endif
-
- //
- // We have a connection.
- // Check whether the connecting host is among the ones allowed.
- //
- if (sock_check_hostlist(hostlist, RPCAP_HOSTLIST_SEP, &from, errbuf, PCAP_ERRBUF_SIZE) < 0)
- {
- rpcap_senderror(sockctrl, ssl, 0, PCAP_ERR_HOSTNOAUTH, errbuf, NULL);
- goto error;
- }
-
#ifdef _WIN32
//
// Put the socket back into blocking mode; doing WSAEventSelect()
goto error;
}
sock_copy->sockctrl = sockctrl;
- sock_copy->ssl = NULL;
threadId = (HANDLE)_beginthreadex(NULL, 0,
main_passive_serviceloop_thread, (void *) sock_copy, 0, NULL);
if (threadId == 0)
{
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error creating the child thread");
- rpcap_senderror(sockctrl, ssl, 0, PCAP_ERR_OPEN, errbuf, NULL);
+ rpcapd_log(LOG_ERROR, "Error creating the child thread");
goto error;
}
CloseHandle(threadId);
-#else
+#else /* _WIN32 */
pid = fork();
if (pid == -1)
{
- pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error creating the child process");
- rpcap_senderror(sockctrl, ssl, 0, PCAP_ERR_OPEN, errbuf, NULL);
+ rpcapd_log(LOGPRIO_ERROR, "Error creating the child process: %s",
+ strerror(errno));
goto error;
}
if (pid == 0)
// This is passive mode, so we don't care whether we were
// told by the client to close.
//
- (void)daemon_serviceloop(sockctrl, sockctrl, ssl, 0,
- nullAuthAllowed, uses_ssl);
+ char *hostlist_copy = strdup(hostlist);
+ if (hostlist_copy == NULL)
+ {
+ rpcapd_log(LOGPRIO_ERROR, "Out of memory copying the host/port list");
+ exit(0);
+ }
+ (void)daemon_serviceloop(sockctrl, sockctrl, 0,
+ hostlist_copy, nullAuthAllowed, uses_ssl);
- close(sockctrl);
+ sock_close(sockctrl, NULL, 0);
exit(0);
}
// I am the parent
// Close the socket for this session (must be open only in the child)
-#ifdef HAVE_OPENSSL
- if (ssl)
- {
- SSL_free(ssl);
- ssl = NULL;
- }
-#endif
closesocket(sockctrl);
-#endif
+#endif /* _WIN32 */
return;
error:
#ifdef _WIN32
if (sock_copy) free(sock_copy);
-#endif
-#ifdef HAVE_OPENSSL
- if (ssl) SSL_free(ssl); // Have to be done before closing soskctrl
#endif
sock_close(sockctrl, NULL, 0);
}
struct addrinfo hints; // temporary struct to keep settings needed to open the new socket
struct addrinfo *addrinfo; // keeps the addrinfo chain; required to open a new socket
struct active_pars *activepars;
- SSL *ssl = NULL;
activepars = (struct active_pars *) ptr;
continue;
}
-#ifdef HAVE_OPENSSL
- /* Even in active mode the other other end has to initiate the TLS handshake
- * as we still are the server as far as TLS is concerned: */
- if (uses_ssl)
+ char *hostlist_copy = strdup(hostlist);
+ if (hostlist_copy == NULL)
{
- ssl = ssl_promotion(1, sockctrl, errbuf, PCAP_ERRBUF_SIZE);
- if (! ssl)
- {
- rpcapd_log(LOGPRIO_ERROR, "TLS handshake on control connection failed: %s",
- errbuf);
- sock_close(sockctrl, NULL, 0);
- continue;
- }
+ rpcapd_log(LOGPRIO_ERROR, "Out of memory copying the host/port list");
+ activeclose = 0;
+ }
+ else
+ {
+ //
+ // daemon_serviceloop() will free the copy.
+ //
+ activeclose = daemon_serviceloop(sockctrl, sockctrl, 1,
+ hostlist_copy, nullAuthAllowed, uses_ssl);
}
-#endif
-
- activeclose = daemon_serviceloop(sockctrl, sockctrl, ssl, 1,
- nullAuthAllowed, uses_ssl);
-#ifdef HAVE_OPENSSL
- if (ssl) SSL_free(ssl);
-#endif
sock_close(sockctrl, NULL, 0);
// If the connection is closed by the user explicitely, don't try to connect to it again
// This is passive mode, so we don't care whether we were
// told by the client to close.
//
- (void)daemon_serviceloop(sock.sockctrl, sock.sockctrl, sock.ssl, 0,
+ (void)daemon_serviceloop(sock.sockctrl, sock.sockctrl, 0,
nullAuthAllowed, uses_ssl);
sock_close(sock.sockctrl, NULL, 0);