diff options
-rw-r--r-- | rpcapd/daemon.c | 193 | ||||
-rw-r--r-- | rpcapd/daemon.h | 4 | ||||
-rw-r--r-- | rpcapd/rpcapd.c | 48 | ||||
-rw-r--r-- | sslutils.c | 10 | ||||
-rw-r--r-- | sslutils.h | 1 |
5 files changed, 117 insertions, 139 deletions
diff --git a/rpcapd/daemon.c b/rpcapd/daemon.c index 7833d11b..75d4ccca 100644 --- a/rpcapd/daemon.c +++ b/rpcapd/daemon.c @@ -76,8 +76,7 @@ // Parameters for the service loop. struct daemon_slpars { - SOCKET sockctrl_in; //!< SOCKET ID of the input side of the control connection - SOCKET sockctrl_out; //!< SOCKET ID of the output side of the control connection + SOCKET sockctrl; //!< SOCKET ID of the control connection SSL *ssl; //!< Optional SSL handler for the controlling sockets uint8 protocol_version; //!< negotiated protocol version int isactive; //!< Not null if the daemon has to run in active mode @@ -88,9 +87,9 @@ struct daemon_slpars * Data for a session managed by a thread. */ struct session { - SOCKET sockctrl_out; + SOCKET sockctrl; SOCKET sockdata; - SSL *ctrl_ssl, *data_ssl; // optional SSL handlers for sockctrl_out and sockdata. + SSL *ctrl_ssl, *data_ssl; // optional SSL handlers for sockctrl and sockdata. uint8 protocol_version; pcap_t *fp; unsigned int TotCapt; @@ -114,7 +113,7 @@ struct thread_handle { }; // Locally defined functions -static int daemon_msg_err(SOCKET sockctrl_in, SSL *, uint32 plen); +static int daemon_msg_err(SOCKET sockctrl, SSL *, uint32 plen); static int daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen); static int daemon_AuthUserPwd(char *username, char *password, char *errbuf); @@ -125,7 +124,7 @@ static int daemon_msg_startcap_req(struct daemon_slpars *pars, uint32 plen, stru static int daemon_msg_endcap_req(struct daemon_slpars *pars, struct session *session, struct thread_handle *threaddata); static int daemon_msg_updatefilter_req(struct daemon_slpars *pars, struct session *session, uint32 plen); -static int daemon_unpackapplyfilter(SOCKET sockctrl_in, SSL *, struct session *session, uint32 *plenp, char *errbuf); +static int daemon_unpackapplyfilter(SOCKET sockctrl, SSL *, struct session *session, uint32 *plenp, char *errbuf); static int daemon_msg_stats_req(struct daemon_slpars *pars, struct session *session, uint32 plen, struct pcap_stat *stats, unsigned int svrcapt); @@ -144,8 +143,8 @@ static int rpcapd_discard(SOCKET sock, SSL *, uint32 len); static void session_close(struct session *); int -daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, - int isactive, char *passiveClients, int nullAuthAllowed, int uses_ssl) +daemon_serviceloop(SOCKET sockctrl, 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 @@ -195,8 +194,7 @@ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, *errbuf = 0; // Initialize errbuf // Set parameters structure - pars.sockctrl_in = sockctrl_in; - pars.sockctrl_out = sockctrl_out; + pars.sockctrl = sockctrl; pars.protocol_version = 0; // not yet known pars.isactive = isactive; // active mode pars.nullAuthAllowed = nullAuthAllowed; @@ -213,7 +211,7 @@ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, // if (uses_ssl) { - ssl = ssl_promotion_rw(1, pars.sockctrl_in, pars.sockctrl_out, errbuf, PCAP_ERRBUF_SIZE); + ssl = ssl_promotion(1, pars.sockctrl, errbuf, PCAP_ERRBUF_SIZE); if (! ssl) { rpcapd_log(LOGPRIO_ERROR, "TLS handshake on control connection failed: %s", @@ -248,11 +246,11 @@ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, // Get the address of the other end of the connection. // fromlen = sizeof(struct sockaddr_storage); - if (getpeername(pars.sockctrl_in, (struct sockaddr *)&from, + if (getpeername(pars.sockctrl, (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) + if (rpcap_senderror(pars.sockctrl, pars.ssl, 0, PCAP_ERR_NETW, errmsgbuf, errbuf) == -1) rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); goto end; } @@ -268,7 +266,7 @@ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, // // Sorry, you're not on the guest list. // - if (rpcap_senderror(pars.sockctrl_out, pars.ssl, 0, PCAP_ERR_HOSTNOAUTH, errmsgbuf, errbuf) == -1) + if (rpcap_senderror(pars.sockctrl, pars.ssl, 0, PCAP_ERR_HOSTNOAUTH, errmsgbuf, errbuf) == -1) rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); goto end; } @@ -295,13 +293,13 @@ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, tv.tv_sec = RPCAP_TIMEOUT_INIT; tv.tv_usec = 0; - FD_SET(pars.sockctrl_in, &rfds); + FD_SET(pars.sockctrl, &rfds); - retval = select((int)pars.sockctrl_in + 1, &rfds, NULL, NULL, &tv); + retval = select((int)pars.sockctrl + 1, &rfds, NULL, NULL, &tv); if (retval == -1) { sock_geterror("select failed: ", errmsgbuf, PCAP_ERRBUF_SIZE); - if (rpcap_senderror(pars.sockctrl_out, pars.ssl, 0, PCAP_ERR_NETW, errmsgbuf, errbuf) == -1) + if (rpcap_senderror(pars.sockctrl, pars.ssl, 0, PCAP_ERR_NETW, errmsgbuf, errbuf) == -1) rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); goto end; } @@ -310,7 +308,7 @@ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, // So, this was a fake connection. Drop it down if (retval == 0) { - if (rpcap_senderror(pars.sockctrl_out, pars.ssl, 0, PCAP_ERR_INITTIMEOUT, "The RPCAP initial timeout has expired", errbuf) == -1) + if (rpcap_senderror(pars.sockctrl, pars.ssl, 0, PCAP_ERR_INITTIMEOUT, "The RPCAP initial timeout has expired", errbuf) == -1) rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); goto end; } @@ -319,7 +317,7 @@ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, // // Read the message header from the client. // - nrecv = rpcapd_recv_msg_header(pars.sockctrl_in, pars.ssl, &header); + nrecv = rpcapd_recv_msg_header(pars.sockctrl, pars.ssl, &header); if (nrecv == -1) { // Fatal error. @@ -375,7 +373,7 @@ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, // reply_version = RPCAP_MAX_VERSION; } - if (rpcap_senderror(pars.sockctrl_out, pars.ssl, reply_version, + if (rpcap_senderror(pars.sockctrl, pars.ssl, reply_version, PCAP_ERR_WRONGVER, "RPCAP version number mismatch", errbuf) == -1) { @@ -385,7 +383,7 @@ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, } // Discard the rest of the message. - if (rpcapd_discard(pars.sockctrl_in, pars.ssl, plen) == -1) + if (rpcapd_discard(pars.sockctrl, pars.ssl, plen) == -1) { // Network error. goto end; @@ -429,7 +427,7 @@ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, // Discard the rest of the message, if // there is anything more. // - (void)rpcapd_discard(pars.sockctrl_in, pars.ssl, plen); + (void)rpcapd_discard(pars.sockctrl, pars.ssl, plen); // We're done with this client. goto end; @@ -441,7 +439,7 @@ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, // an error message rather than a "let // me log in" message, indicating that // we're not allowed to connect to them? - (void)daemon_msg_err(pars.sockctrl_in, pars.ssl, plen); + (void)daemon_msg_err(pars.sockctrl, pars.ssl, plen); goto end; case RPCAP_MSG_FINDALLIF_REQ: @@ -464,7 +462,7 @@ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, { pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Message of type %u sent before authentication was completed", header.type); } - if (rpcap_senderror(pars.sockctrl_out, pars.ssl, + if (rpcap_senderror(pars.sockctrl, pars.ssl, pars.protocol_version, PCAP_ERR_WRONGMSG, errmsgbuf, errbuf) == -1) { @@ -472,7 +470,7 @@ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, goto end; } // Discard the rest of the message. - if (rpcapd_discard(pars.sockctrl_in, pars.ssl, plen) == -1) + if (rpcapd_discard(pars.sockctrl, pars.ssl, plen) == -1) { // Network error. goto end; @@ -500,7 +498,7 @@ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, { pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Server-to-client message of type %u received from client", header.type); } - if (rpcap_senderror(pars.sockctrl_out, pars.ssl, + if (rpcap_senderror(pars.sockctrl, pars.ssl, pars.protocol_version, PCAP_ERR_WRONGMSG, errmsgbuf, errbuf) == -1) { @@ -508,7 +506,7 @@ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, goto end; } // Discard the rest of the message. - if (rpcapd_discard(pars.sockctrl_in, pars.ssl, plen) == -1) + if (rpcapd_discard(pars.sockctrl, pars.ssl, plen) == -1) { // Fatal error. goto end; @@ -520,7 +518,7 @@ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, // Unknown message type. // pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Unknown message type %u", header.type); - if (rpcap_senderror(pars.sockctrl_out, pars.ssl, + if (rpcap_senderror(pars.sockctrl, pars.ssl, pars.protocol_version, PCAP_ERR_WRONGMSG, errmsgbuf, errbuf) == -1) { @@ -528,7 +526,7 @@ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, goto end; } // Discard the rest of the message. - if (rpcapd_discard(pars.sockctrl_in, pars.ssl, plen) == -1) + if (rpcapd_discard(pars.sockctrl, pars.ssl, plen) == -1) { // Fatal error. goto end; @@ -574,13 +572,13 @@ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, tv.tv_sec = RPCAP_TIMEOUT_RUNTIME; tv.tv_usec = 0; - FD_SET(pars.sockctrl_in, &rfds); + FD_SET(pars.sockctrl, &rfds); - retval = select((int)pars.sockctrl_in + 1, &rfds, NULL, NULL, &tv); + retval = select((int)pars.sockctrl + 1, &rfds, NULL, NULL, &tv); if (retval == -1) { sock_geterror("select failed: ", errmsgbuf, PCAP_ERRBUF_SIZE); - if (rpcap_senderror(pars.sockctrl_out, pars.ssl, + if (rpcap_senderror(pars.sockctrl, pars.ssl, pars.protocol_version, PCAP_ERR_NETW, errmsgbuf, errbuf) == -1) rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); @@ -591,7 +589,7 @@ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, // So, this was a fake connection. Drop it down if (retval == 0) { - if (rpcap_senderror(pars.sockctrl_out, pars.ssl, + if (rpcap_senderror(pars.sockctrl, pars.ssl, pars.protocol_version, PCAP_ERR_INITTIMEOUT, "The RPCAP initial timeout has expired", @@ -604,7 +602,7 @@ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, // // Read the message header from the client. // - nrecv = rpcapd_recv_msg_header(pars.sockctrl_in, pars.ssl, &header); + nrecv = rpcapd_recv_msg_header(pars.sockctrl, pars.ssl, &header); if (nrecv == -1) { // Fatal error. @@ -631,7 +629,7 @@ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, // so they don't reject it as having the wrong // version. // - if (rpcap_senderror(pars.sockctrl_out, pars.ssl, + if (rpcap_senderror(pars.sockctrl, pars.ssl, header.ver, PCAP_ERR_WRONGVER, "RPCAP version in message isn't the negotiated version", errbuf) == -1) @@ -642,7 +640,7 @@ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, } // Discard the rest of the message. - (void)rpcapd_discard(pars.sockctrl_in, pars.ssl, plen); + (void)rpcapd_discard(pars.sockctrl, pars.ssl, plen); // Give up on them. goto end; } @@ -651,7 +649,7 @@ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, { case RPCAP_MSG_ERROR: // The other endpoint reported an error { - (void)daemon_msg_err(pars.sockctrl_in, pars.ssl, plen); + (void)daemon_msg_err(pars.sockctrl, pars.ssl, plen); // Do nothing; just exit; the error code is already into the errbuf // XXX - actually exit.... break; @@ -696,7 +694,7 @@ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, { // They never told us what device // to capture on! - if (rpcap_senderror(pars.sockctrl_out, pars.ssl, + if (rpcap_senderror(pars.sockctrl, pars.ssl, pars.protocol_version, PCAP_ERR_STARTCAPTURE, "No capture device was specified", @@ -707,7 +705,7 @@ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); goto end; } - if (rpcapd_discard(pars.sockctrl_in, pars.ssl, plen) == -1) + if (rpcapd_discard(pars.sockctrl, pars.ssl, plen) == -1) { goto end; } @@ -736,7 +734,7 @@ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, } else { - if (rpcap_senderror(pars.sockctrl_out, pars.ssl, + if (rpcap_senderror(pars.sockctrl, pars.ssl, pars.protocol_version, PCAP_ERR_UPDATEFILTER, "Device not opened. Cannot update filter", @@ -803,7 +801,7 @@ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, } else { - rpcap_senderror(pars.sockctrl_out, pars.ssl, + rpcap_senderror(pars.sockctrl, pars.ssl, pars.protocol_version, PCAP_ERR_ENDCAPTURE, "Device not opened. Cannot close the capture", @@ -830,7 +828,7 @@ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, // get to reauthenticate. // rpcapd_log(LOGPRIO_INFO, "The client sent an RPCAP_MSG_AUTH_REQ message after authentication was completed"); - if (rpcap_senderror(pars.sockctrl_out, pars.ssl, + if (rpcap_senderror(pars.sockctrl, pars.ssl, pars.protocol_version, PCAP_ERR_WRONGMSG, "RPCAP_MSG_AUTH_REQ request sent after authentication was completed", @@ -840,7 +838,7 @@ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, goto end; } // Discard the rest of the message. - if (rpcapd_discard(pars.sockctrl_in, pars.ssl, plen) == -1) + if (rpcapd_discard(pars.sockctrl, pars.ssl, plen) == -1) { // Fatal error. goto end; @@ -870,7 +868,7 @@ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, rpcapd_log(LOGPRIO_INFO, "The client sent a server-to-client message of type %u", header.type); pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Server-to-client message of type %u received from client", header.type); } - if (rpcap_senderror(pars.sockctrl_out, pars.ssl, + if (rpcap_senderror(pars.sockctrl, pars.ssl, pars.protocol_version, PCAP_ERR_WRONGMSG, errmsgbuf, errbuf) == -1) { @@ -878,7 +876,7 @@ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, goto end; } // Discard the rest of the message. - if (rpcapd_discard(pars.sockctrl_in, pars.ssl, plen) == -1) + if (rpcapd_discard(pars.sockctrl, pars.ssl, plen) == -1) { // Fatal error. goto end; @@ -891,7 +889,7 @@ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, // rpcapd_log(LOGPRIO_INFO, "The client sent a message of type %u", header.type); pcap_snprintf(errmsgbuf, PCAP_ERRBUF_SIZE, "Unknown message type %u", header.type); - if (rpcap_senderror(pars.sockctrl_out, pars.ssl, + if (rpcap_senderror(pars.sockctrl, pars.ssl, pars.protocol_version, PCAP_ERR_WRONGMSG, errbuf, errmsgbuf) == -1) { @@ -899,7 +897,7 @@ daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, goto end; } // Discard the rest of the message. - if (rpcapd_discard(pars.sockctrl_in, pars.ssl, plen) == -1) + if (rpcapd_discard(pars.sockctrl, pars.ssl, plen) == -1) { // Fatal error. goto end; @@ -955,12 +953,17 @@ end: session = NULL; } + // + // Free the SSL handle, if we have one, and close the control + // socket. + // #ifdef HAVE_OPENSSL if (ssl) { SSL_free(ssl); } #endif + sock_close(sockctrl, NULL, 0); // Print message and return rpcapd_log(LOGPRIO_DEBUG, "I'm exiting from the child loop"); @@ -973,7 +976,7 @@ end: * This handles the RPCAP_MSG_ERR message. */ static int -daemon_msg_err(SOCKET sockctrl_in, SSL *ssl, uint32 plen) +daemon_msg_err(SOCKET sockctrl, SSL *ssl, uint32 plen) { char errbuf[PCAP_ERRBUF_SIZE]; char remote_errbuf[PCAP_ERRBUF_SIZE]; @@ -984,7 +987,7 @@ daemon_msg_err(SOCKET sockctrl_in, SSL *ssl, uint32 plen) * Message is too long; just read as much of it as we * can into the buffer provided, and discard the rest. */ - if (sock_recv(sockctrl_in, ssl, remote_errbuf, PCAP_ERRBUF_SIZE - 1, + if (sock_recv(sockctrl, ssl, remote_errbuf, PCAP_ERRBUF_SIZE - 1, SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf, PCAP_ERRBUF_SIZE) == -1) { @@ -992,7 +995,7 @@ daemon_msg_err(SOCKET sockctrl_in, SSL *ssl, uint32 plen) rpcapd_log(LOGPRIO_ERROR, "Read from client failed: %s", errbuf); return -1; } - if (rpcapd_discard(sockctrl_in, ssl, plen - (PCAP_ERRBUF_SIZE - 1)) == -1) + if (rpcapd_discard(sockctrl, ssl, plen - (PCAP_ERRBUF_SIZE - 1)) == -1) { // Network error. return -1; @@ -1010,7 +1013,7 @@ daemon_msg_err(SOCKET sockctrl_in, SSL *ssl, uint32 plen) } else { - if (sock_recv(sockctrl_in, ssl, remote_errbuf, plen, + if (sock_recv(sockctrl, ssl, remote_errbuf, plen, SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf, PCAP_ERRBUF_SIZE) == -1) { @@ -1060,7 +1063,7 @@ daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen) int status; struct rpcap_auth auth; // RPCAP authentication header - status = rpcapd_recv(pars->sockctrl_in, pars->ssl, (char *) &auth, sizeof(struct rpcap_auth), &plen, errmsgbuf); + status = rpcapd_recv(pars->sockctrl, pars->ssl, (char *) &auth, sizeof(struct rpcap_auth), &plen, errmsgbuf); if (status == -1) { return -1; @@ -1096,7 +1099,7 @@ daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen) PCAP_ERRBUF_SIZE, errno, "malloc() failed"); goto error; } - status = rpcapd_recv(pars->sockctrl_in, pars->ssl, username, usernamelen, &plen, errmsgbuf); + status = rpcapd_recv(pars->sockctrl, pars->ssl, username, usernamelen, &plen, errmsgbuf); if (status == -1) { free(username); @@ -1118,7 +1121,7 @@ daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen) free(username); goto error; } - status = rpcapd_recv(pars->sockctrl_in, pars->ssl, passwd, passwdlen, &plen, errmsgbuf); + status = rpcapd_recv(pars->sockctrl, pars->ssl, passwd, passwdlen, &plen, errmsgbuf); if (status == -1) { free(username); @@ -1141,7 +1144,7 @@ daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen) // free(username); free(passwd); - if (rpcap_senderror(pars->sockctrl_out, pars->ssl, + if (rpcap_senderror(pars->sockctrl, pars->ssl, pars->protocol_version, PCAP_ERR_AUTH, errmsgbuf, errbuf) == -1) { @@ -1178,7 +1181,7 @@ daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen) rpcap_createhdr(&header, pars->protocol_version, RPCAP_MSG_AUTH_REPLY, 0, 0); // Send the ok message back - if (sock_send(pars->sockctrl_out, pars->ssl, (char *) &header, sizeof (struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) == -1) + if (sock_send(pars->sockctrl, pars->ssl, (char *) &header, sizeof (struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) == -1) { // That failed; log a messsage and give up. rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); @@ -1186,7 +1189,7 @@ daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen) } // Check if all the data has been read; if not, discard the data in excess - if (rpcapd_discard(pars->sockctrl_in, pars->ssl, plen) == -1) + if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1) { return -1; } @@ -1194,7 +1197,7 @@ daemon_msg_auth_req(struct daemon_slpars *pars, uint32 plen) return 0; error: - if (rpcap_senderror(pars->sockctrl_out, pars->ssl, pars->protocol_version, + if (rpcap_senderror(pars->sockctrl, pars->ssl, pars->protocol_version, PCAP_ERR_AUTH, errmsgbuf, errbuf) == -1) { // That failed; log a message and give up. @@ -1204,7 +1207,7 @@ error: error_noreply: // Check if all the data has been read; if not, discard the data in excess - if (rpcapd_discard(pars->sockctrl_in, pars->ssl, plen) == -1) + if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1) { return -1; } @@ -1339,7 +1342,7 @@ daemon_msg_findallif_req(struct daemon_slpars *pars, uint32 plen) uint16 nif = 0; // counts the number of interface listed // Discard the rest of the message; there shouldn't be any payload. - if (rpcapd_discard(pars->sockctrl_in, pars->ssl, plen) == -1) + if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1) { // Network error. return -1; @@ -1351,7 +1354,7 @@ daemon_msg_findallif_req(struct daemon_slpars *pars, uint32 plen) if (alldevs == NULL) { - if (rpcap_senderror(pars->sockctrl_out, pars->ssl, pars->protocol_version, + if (rpcap_senderror(pars->sockctrl, pars->ssl, pars->protocol_version, PCAP_ERR_NOREMOTEIF, "No interfaces found! Make sure libpcap/WinPcap is properly installed" " and you have the right to access to the remote device.", @@ -1505,7 +1508,7 @@ daemon_msg_findallif_req(struct daemon_slpars *pars, uint32 plen) pcap_freealldevs(alldevs); // Send a final command that says "now send it!" - if (sock_send(pars->sockctrl_out, pars->ssl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1) + if (sock_send(pars->sockctrl, pars->ssl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1) { rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); return -1; @@ -1517,7 +1520,7 @@ error: if (alldevs) pcap_freealldevs(alldevs); - if (rpcap_senderror(pars->sockctrl_out, pars->ssl, pars->protocol_version, + if (rpcap_senderror(pars->sockctrl, pars->ssl, pars->protocol_version, PCAP_ERR_FINDALLIF, errmsgbuf, errbuf) == -1) { rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); @@ -1547,7 +1550,7 @@ daemon_msg_open_req(struct daemon_slpars *pars, uint32 plen, char *source, size_ goto error; } - nread = sock_recv(pars->sockctrl_in, pars->ssl, source, plen, + nread = sock_recv(pars->sockctrl, pars->ssl, source, plen, SOCK_RECEIVEALL_YES|SOCK_EOF_IS_ERROR, errbuf, PCAP_ERRBUF_SIZE); if (nread == -1) { @@ -1590,7 +1593,7 @@ daemon_msg_open_req(struct daemon_slpars *pars, uint32 plen, char *source, size_ pcap_close(fp); // Send the reply. - if (sock_send(pars->sockctrl_out, pars->ssl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1) + if (sock_send(pars->sockctrl, pars->ssl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1) { rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); return -1; @@ -1598,7 +1601,7 @@ daemon_msg_open_req(struct daemon_slpars *pars, uint32 plen, char *source, size_ return 0; error: - if (rpcap_senderror(pars->sockctrl_out, pars->ssl, pars->protocol_version, + if (rpcap_senderror(pars->sockctrl, pars->ssl, pars->protocol_version, PCAP_ERR_OPEN, errmsgbuf, errbuf) == -1) { // That failed; log a message and give up. @@ -1607,7 +1610,7 @@ error: } // Check if all the data has been read; if not, discard the data in excess - if (rpcapd_discard(pars->sockctrl_in, pars->ssl, plen) == -1) + if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1) { return -1; } @@ -1649,7 +1652,7 @@ daemon_msg_startcap_req(struct daemon_slpars *pars, uint32 plen, struct thread_h addrinfo = NULL; - status = rpcapd_recv(pars->sockctrl_in, pars->ssl, (char *) &startcapreq, + status = rpcapd_recv(pars->sockctrl, pars->ssl, (char *) &startcapreq, sizeof(struct rpcap_startcapreq), &plen, errmsgbuf); if (status == -1) { @@ -1712,7 +1715,7 @@ daemon_msg_startcap_req(struct daemon_slpars *pars, uint32 plen, struct thread_h we want to connect to */ saddrlen = sizeof(struct sockaddr_storage); - if (getpeername(pars->sockctrl_in, (struct sockaddr *) &saddr, &saddrlen) == -1) + if (getpeername(pars->sockctrl, (struct sockaddr *) &saddr, &saddrlen) == -1) { sock_geterror("getpeername(): ", errmsgbuf, PCAP_ERRBUF_SIZE); goto error; @@ -1774,12 +1777,12 @@ daemon_msg_startcap_req(struct daemon_slpars *pars, uint32 plen, struct thread_h addrinfo = NULL; // Needed to send an error on the ctrl connection - session->sockctrl_out = pars->sockctrl_out; + session->sockctrl = pars->sockctrl; session->ctrl_ssl = pars->ssl; session->protocol_version = pars->protocol_version; // Now I can set the filter - ret = daemon_unpackapplyfilter(pars->sockctrl_in, pars->ssl, session, &plen, errmsgbuf); + ret = daemon_unpackapplyfilter(pars->sockctrl, pars->ssl, session, &plen, errmsgbuf); if (ret == -1) { // Fatal error. A message has been logged; just give up. @@ -1814,7 +1817,7 @@ daemon_msg_startcap_req(struct daemon_slpars *pars, uint32 plen, struct thread_h startcapreply->portdata = htons(port); } - if (sock_send(pars->sockctrl_out, pars->ssl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1) + if (sock_send(pars->sockctrl, pars->ssl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1) { // That failed; log a message and give up. rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); @@ -1889,7 +1892,7 @@ daemon_msg_startcap_req(struct daemon_slpars *pars, uint32 plen, struct thread_h threaddata->have_thread = 1; // Check if all the data has been read; if not, discard the data in excess - if (rpcapd_discard(pars->sockctrl_in, pars->ssl, plen) == -1) + if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1) goto fatal_error; *sessionp = session; @@ -1928,15 +1931,13 @@ error: if (session->fp) pcap_close(session->fp); #ifdef HAVE_OPENSSL - if (session->ctrl_ssl) - SSL_free(session->ctrl_ssl); if (session->data_ssl) SSL_free(session->data_ssl); #endif free(session); } - if (rpcap_senderror(pars->sockctrl_out, pars->ssl, pars->protocol_version, + if (rpcap_senderror(pars->sockctrl, pars->ssl, pars->protocol_version, PCAP_ERR_STARTCAPTURE, errmsgbuf, errbuf) == -1) { // That failed; log a message and give up. @@ -1945,7 +1946,7 @@ error: } // Check if all the data has been read; if not, discard the data in excess - if (rpcapd_discard(pars->sockctrl_in, pars->ssl, plen) == -1) + if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1) { // Network error. return -1; @@ -2006,8 +2007,6 @@ fatal_error: if (session->fp) pcap_close(session->fp); #ifdef HAVE_OPENSSL - if (session->ctrl_ssl) - SSL_free(session->ctrl_ssl); if (session->data_ssl) SSL_free(session->data_ssl); #endif @@ -2063,7 +2062,7 @@ daemon_msg_endcap_req(struct daemon_slpars *pars, struct session *session, struc rpcap_createhdr(&header, pars->protocol_version, RPCAP_MSG_ENDCAP_REPLY, 0, 0); - if (sock_send(pars->sockctrl_out, pars->ssl, (char *) &header, sizeof(struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) == -1) + if (sock_send(pars->sockctrl, pars->ssl, (char *) &header, sizeof(struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) == -1) { // That failed; log a message and give up. rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); @@ -2074,7 +2073,7 @@ daemon_msg_endcap_req(struct daemon_slpars *pars, struct session *session, struc } static int -daemon_unpackapplyfilter(SOCKET sockctrl_in, SSL *ctrl_ssl, struct session *session, uint32 *plenp, char *errmsgbuf) +daemon_unpackapplyfilter(SOCKET sockctrl, SSL *ctrl_ssl, struct session *session, uint32 *plenp, char *errmsgbuf) { int status; struct rpcap_filter filter; @@ -2083,7 +2082,7 @@ daemon_unpackapplyfilter(SOCKET sockctrl_in, SSL *ctrl_ssl, struct session *sess struct bpf_program bf_prog; unsigned int i; - status = rpcapd_recv(sockctrl_in, ctrl_ssl, (char *) &filter, + status = rpcapd_recv(sockctrl, ctrl_ssl, (char *) &filter, sizeof(struct rpcap_filter), plenp, errmsgbuf); if (status == -1) { @@ -2114,7 +2113,7 @@ daemon_unpackapplyfilter(SOCKET sockctrl_in, SSL *ctrl_ssl, struct session *sess for (i = 0; i < bf_prog.bf_len; i++) { - status = rpcapd_recv(sockctrl_in, ctrl_ssl, (char *) &insn, + status = rpcapd_recv(sockctrl, ctrl_ssl, (char *) &insn, sizeof(struct rpcap_filterbpf_insn), plenp, errmsgbuf); if (status == -1) { @@ -2159,7 +2158,7 @@ daemon_msg_updatefilter_req(struct daemon_slpars *pars, struct session *session, int ret; // status of daemon_unpackapplyfilter() struct rpcap_header header; // keeps the answer to the updatefilter command - ret = daemon_unpackapplyfilter(pars->sockctrl_in, pars->ssl, session, &plen, errmsgbuf); + ret = daemon_unpackapplyfilter(pars->sockctrl, pars->ssl, session, &plen, errmsgbuf); if (ret == -1) { // Fatal error. A message has been logged; just give up. @@ -2172,7 +2171,7 @@ daemon_msg_updatefilter_req(struct daemon_slpars *pars, struct session *session, } // Check if all the data has been read; if not, discard the data in excess - if (rpcapd_discard(pars->sockctrl_in, pars->ssl, plen) == -1) + if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1) { // Network error. return -1; @@ -2182,7 +2181,7 @@ daemon_msg_updatefilter_req(struct daemon_slpars *pars, struct session *session, rpcap_createhdr(&header, pars->protocol_version, RPCAP_MSG_UPDATEFILTER_REPLY, 0, 0); - if (sock_send(pars->sockctrl_out, pars->ssl, (char *) &header, sizeof (struct rpcap_header), pcap_geterr(session->fp), PCAP_ERRBUF_SIZE)) + if (sock_send(pars->sockctrl, pars->ssl, (char *) &header, sizeof (struct rpcap_header), pcap_geterr(session->fp), PCAP_ERRBUF_SIZE)) { // That failed; log a messsage and give up. rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); @@ -2192,11 +2191,11 @@ daemon_msg_updatefilter_req(struct daemon_slpars *pars, struct session *session, return 0; error: - if (rpcapd_discard(pars->sockctrl_in, pars->ssl, plen) == -1) + if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1) { return -1; } - rpcap_senderror(pars->sockctrl_out, pars->ssl, pars->protocol_version, + rpcap_senderror(pars->sockctrl, pars->ssl, pars->protocol_version, PCAP_ERR_UPDATEFILTER, errmsgbuf, NULL); return 0; @@ -2214,7 +2213,7 @@ daemon_msg_setsampling_req(struct daemon_slpars *pars, uint32 plen, struct rpcap struct rpcap_sampling rpcap_samp; int status; - status = rpcapd_recv(pars->sockctrl_in, pars->ssl, (char *) &rpcap_samp, sizeof(struct rpcap_sampling), &plen, errmsgbuf); + status = rpcapd_recv(pars->sockctrl, pars->ssl, (char *) &rpcap_samp, sizeof(struct rpcap_sampling), &plen, errmsgbuf); if (status == -1) { return -1; @@ -2232,14 +2231,14 @@ daemon_msg_setsampling_req(struct daemon_slpars *pars, uint32 plen, struct rpcap rpcap_createhdr(&header, pars->protocol_version, RPCAP_MSG_SETSAMPLING_REPLY, 0, 0); - if (sock_send(pars->sockctrl_out, pars->ssl, (char *) &header, sizeof (struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) == -1) + if (sock_send(pars->sockctrl, pars->ssl, (char *) &header, sizeof (struct rpcap_header), errbuf, PCAP_ERRBUF_SIZE) == -1) { // That failed; log a messsage and give up. rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); return -1; } - if (rpcapd_discard(pars->sockctrl_in, pars->ssl, plen) == -1) + if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1) { return -1; } @@ -2247,7 +2246,7 @@ daemon_msg_setsampling_req(struct daemon_slpars *pars, uint32 plen, struct rpcap return 0; error: - if (rpcap_senderror(pars->sockctrl_out, pars->ssl, pars->protocol_version, + if (rpcap_senderror(pars->sockctrl, pars->ssl, pars->protocol_version, PCAP_ERR_AUTH, errmsgbuf, errbuf) == -1) { // That failed; log a message and give up. @@ -2256,7 +2255,7 @@ error: } // Check if all the data has been read; if not, discard the data in excess - if (rpcapd_discard(pars->sockctrl_in, pars->ssl, plen) == -1) + if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1) { return -1; } @@ -2274,7 +2273,7 @@ daemon_msg_stats_req(struct daemon_slpars *pars, struct session *session, uint32 struct rpcap_stats *netstats; // statistics sent on the network // Checks that the header does not contain other data; if so, discard it - if (rpcapd_discard(pars->sockctrl_in, pars->ssl, plen) == -1) + if (rpcapd_discard(pars->sockctrl, pars->ssl, plen) == -1) { // Network error. return -1; @@ -2318,7 +2317,7 @@ daemon_msg_stats_req(struct daemon_slpars *pars, struct session *session, uint32 } // Send the packet - if (sock_send(pars->sockctrl_out, pars->ssl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1) + if (sock_send(pars->sockctrl, pars->ssl, sendbuf, sendbufidx, errbuf, PCAP_ERRBUF_SIZE) == -1) { rpcapd_log(LOGPRIO_ERROR, "Send to client failed: %s", errbuf); return -1; @@ -2327,7 +2326,7 @@ daemon_msg_stats_req(struct daemon_slpars *pars, struct session *session, uint32 return 0; error: - rpcap_senderror(pars->sockctrl_out, pars->ssl, pars->protocol_version, + rpcap_senderror(pars->sockctrl, pars->ssl, pars->protocol_version, PCAP_ERR_GETSTATS, errmsgbuf, NULL); return 0; } @@ -2513,7 +2512,7 @@ daemon_thrdatamain(void *ptr) if (retval == -1) { pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "Error reading the packets: %s", pcap_geterr(session->fp)); - rpcap_senderror(session->sockctrl_out, session->ctrl_ssl, session->protocol_version, + rpcap_senderror(session->sockctrl, session->ctrl_ssl, session->protocol_version, PCAP_ERR_READEX, errbuf, NULL); goto error; } diff --git a/rpcapd/daemon.h b/rpcapd/daemon.h index bc72c1ca..dbbdb62c 100644 --- a/rpcapd/daemon.h +++ b/rpcapd/daemon.h @@ -44,8 +44,8 @@ // otherwise; the return value is used only by callers that call us // for active mode. // -int daemon_serviceloop(SOCKET sockctrl_in, SOCKET sockctrl_out, - int isactive, char *passiveClients, int nullAuthAllowed, int uses_ssl); +int daemon_serviceloop(SOCKET sockctrl, int isactive, char *passiveClients, + int nullAuthAllowed, int uses_ssl); void sleep_secs(int secs); diff --git a/rpcapd/rpcapd.c b/rpcapd/rpcapd.c index 03e85afe..fec263d7 100644 --- a/rpcapd/rpcapd.c +++ b/rpcapd/rpcapd.c @@ -397,33 +397,26 @@ int main(int argc, char *argv[]) // by inetd or something that can run network daemons // as if it were inetd (xinetd, launchd, systemd, etc.). // - // Our standard input is the input side of a connection, - // and our standard output is the output side of a - // connection. + // We assume that the program that launched us just + // duplicated a single socket for the connection + // to our standard input, output, and error, so we + // can just use the standard input as our control + // socket. // - int sockctrl_in, sockctrl_out; + int sockctrl; int devnull_fd; // - // Duplicate the standard input and output, making them - // the input and output side of the control connection. + // Duplicate the standard input as the control socket. // - sockctrl_in = dup(0); - if (sockctrl_in == -1) + sockctrl = dup(0); + if (sockctrl == -1) { sock_geterror(NULL, errbuf, PCAP_ERRBUF_SIZE); rpcapd_log(LOGPRIO_ERROR, "Can't dup standard input: %s", errbuf); exit(2); } - sockctrl_out = dup(1); - if (sockctrl_out == -1) - { - sock_geterror(NULL, errbuf, PCAP_ERRBUF_SIZE); - rpcapd_log(LOGPRIO_ERROR, "Can't dup standard output: %s", - errbuf); - exit(2); - } // // Try to set the standard input, output, and error @@ -452,10 +445,8 @@ int main(int argc, char *argv[]) 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); + (void)daemon_serviceloop(sockctrl, 0, hostlist_copy, + nullAuthAllowed, uses_ssl); // // Nothing more to do. @@ -1286,10 +1277,8 @@ accept_connection(SOCKET listen_sock) 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); - - sock_close(sockctrl, NULL, 0); + (void)daemon_serviceloop(sockctrl, 0, hostlist_copy, + nullAuthAllowed, uses_ssl); exit(0); } @@ -1369,18 +1358,17 @@ main_active(void *ptr) { rpcapd_log(LOGPRIO_ERROR, "Out of memory copying the host/port list"); activeclose = 0; + sock_close(sockctrl, NULL, 0); } else { // // daemon_serviceloop() will free the copy. // - activeclose = daemon_serviceloop(sockctrl, sockctrl, 1, + activeclose = daemon_serviceloop(sockctrl, 1, hostlist_copy, nullAuthAllowed, uses_ssl); } - sock_close(sockctrl, NULL, 0); - // If the connection is closed by the user explicitely, don't try to connect to it again // just exit the program if (activeclose == 1) @@ -1405,10 +1393,8 @@ unsigned __stdcall main_passive_serviceloop_thread(void *ptr) // This is passive mode, so we don't care whether we were // told by the client to close. // - (void)daemon_serviceloop(params.sockctrl, params.sockctrl, 0, - params.hostlist, nullAuthAllowed, uses_ssl); - - sock_close(params.sockctrl, NULL, 0); + (void)daemon_serviceloop(params.sockctrl, 0, params.hostlist, + nullAuthAllowed, uses_ssl); return 0; } @@ -133,15 +133,14 @@ die: return -1; } -SSL *ssl_promotion_rw(int is_server, SOCKET in, SOCKET out, char *errbuf, size_t errbuflen) +SSL *ssl_promotion(int is_server, SOCKET s, char *errbuf, size_t errbuflen) { if (ssl_init_once(is_server, 1, errbuf, errbuflen) < 0) { return NULL; } SSL *ssl = SSL_new(ctx); // TODO: also a DTLS context - SSL_set_rfd(ssl, in); - SSL_set_wfd(ssl, out); + SSL_set_fd(ssl, s); if (is_server) { if (SSL_accept(ssl) <= 0) { @@ -160,11 +159,6 @@ SSL *ssl_promotion_rw(int is_server, SOCKET in, SOCKET out, char *errbuf, size_t return ssl; } -SSL *ssl_promotion(int is_server, SOCKET s, char *errbuf, size_t errbuflen) -{ - return ssl_promotion_rw(is_server, s, s, errbuf, errbuflen); -} - // Same return value as sock_send: // 0 on OK, -1 on error but closed connection (-2). int ssl_send(SSL *ssl, char const *buffer, int size, char *errbuf, size_t errbuflen) @@ -46,7 +46,6 @@ void ssl_set_certfile(const char *certfile); void ssl_set_keyfile(const char *keyfile); int ssl_init_once(int is_server, int enable_compression, char *errbuf, size_t errbuflen); SSL *ssl_promotion(int is_server, SOCKET s, char *errbuf, size_t errbuflen); -SSL *ssl_promotion_rw(int is_server, SOCKET in, SOCKET out, char *errbuf, size_t errbuflen); int ssl_send(SSL *, char const *buffer, int size, char *errbuf, size_t errbuflen); int ssl_recv(SSL *, char *buffer, int size, char *errbuf, size_t errbuflen); |