summaryrefslogtreecommitdiff
path: root/rpcapd
Commit message (Collapse)AuthorAgeFilesLines
...
* Clean up comment formatting.Guy Harris2019-10-021-0/+1
|
* Remove more trailing white space.Guy Harris2019-10-021-1/+1
|
* Get rid of trailing white space.Guy Harris2019-10-021-1/+1
|
* Limit the size of a filter program.Guy Harris2019-10-021-0/+24
| | | | | | | This makes it harder to run the Windows daemon our of memory. It also addresses Include Security issue F1: [libpcap] Remote Packet Capture Daemon (RPCAPD) Integer Overflow Leads to Heap Buffer Overflow.
* Calculate the reply payload length in a local variable.Guy Harris2019-10-021-6/+9
| | | | | | | | | Using the same variable for the remaining request length and the reply length is confusing at best and can cause errors at worst (if the request had extra stuff at the end, so that the variable is non-zero). This addresses Include Security issue I8: [libpcap] Remote Packet Capture Daemon Parameter Reuse.
* In the open request, reject capture sources that are URLs.Guy Harris2019-10-021-2/+72
| | | | | | | | You shouldn't be able to ask a server to open a remote device on some *other* server; just open it yourself. This addresses Include Security issue F13: [libpcap] Remote Packet Capture Daemon Allows Opening Capture URLs.
* On UN*X, don't tell the client why authentication failed.Guy Harris2019-10-021-7/+44
| | | | | | | | | | | | | | | | | | | | "no such user" tells the client that the user ID isn't valid and, therefore, that it needn't bother trying to do password cracking for that user ID; just saying that the authentication failed dosn't give them that hint. This resolves the third problem in Include Security issue F11: [libpcap] Remote Packet Capture Daemon Multiple Authentication Improvements. The Windows LogonUser() API returns ERROR_LOGON_FAILURE for both cases, so the Windows code doesn't have this issue. Just return the same "Authentication failed" message on Windows to the user. For various authentication failures *other* than "no such user" and "password not valid", log a message, as there's a problem that may need debugging. We don't need to tell the end user what the problem is, as they may not bother reporting it and, even if they do, they may not give the full error message.
* Don't crash if crypt() fails.Guy Harris2019-10-021-1/+8
| | | | | | | | It can fail, so make sure it doesn't before comparing its result with the password. This addresses Include Security issue F12: [libpcap] Remote Packet Capture Daemon Null Pointer Dereference Denial of Service.
* Get rid of FILECONF_ISSPACE().Guy Harris2019-08-311-9/+9
| | | | | Explicitly check for the characters we care about, to make it clearer what we're doing.
* Banish ctype.h from rpcapd as well.Guy Harris2019-08-311-8/+17
| | | | | | | | | | | | | | | Some of them are locale-dependent, and all of them run the risk of failing if you hand them a char with the 8th bit set. Define our own locale-independent macros that can be handed any integral value. Don't include <ctype.h>. This should address the issue in GitHub pull request #839, and should also catch any (highly unlikely) cases in which something other than Boring Old Space And Tab and, sometimes, CR and LF are treated as white space. (No, we don't want FF or VT treated as white space.)
* We now use MSVC's snprintf(), and don't have our own version.Guy Harris2019-08-091-1/+0
|
* Remove some workarounds for old compilers.Guy Harris2019-08-093-26/+26
| | | | | | | | | | | | | Require Visual Studio 2015 or later; fail if we don't have it, and remove checks for older versions. That means we have C99-compliant snprintf() and vsnprintf(); require them when configuring for UN*X, and then use them directly, rather than having wrappers for systems lacking them. If we're using MSVC, skip the tests for options to request C99 compatibility - either we have VS 2015, which is sufficient, or we don't, in which case we fail.
* Have a pcap_fmt_errmsg_for_win32_err() routine and use it.Guy Harris2019-06-293-37/+44
| | | | | | | | | It's like pcap_fmt_errmsg_for_errno(), but for Windows error codes. Use it, rather than calling pcap_win32_err_to_str() and then formatting a message with pcap_strerror(). Clean up some error messages while we're at it.
* Add some new authentication error codes for specific errors.Guy Harris2019-02-061-8/+24
| | | | | | | | | | | | | | | This might make it a bit cleaner to handle new authentication types; clients will still have to check for PCAP_ERR_AUTH with particular error strings to detect "that authentication type isn't supported by the server", but at least they can check first for PCAP_ERR_AUTH_TYPE_NOTSUP. Also add PCAP_ERR_AUTH_FAILED for authentication failures and PCAP_ERR_TLS_REQUIRED for "the server requires TLS". PCAP_ERR_AUTH is used for all other errors, including internal errors. While we're at it, fix one case where the wrong error code was returned for "set sampling" request errors.
* Send errors for select() failure or timeout with a version of 0.Guy Harris2019-02-041-3/+2
| | | | | If we haven't received a request containing a version number, send the error reply with a version of 0.
* Don't distinguish between invalid user name and invalid password.Guy Harris2019-02-031-3/+12
| | | | | | That makes brute-forcing harder, as a brute-forcing client isn't told that it can give up on a given user name. (Perhaps it can guess that based on how quickly we say "no".)
* Redo protocol version negotiation.Guy Harris2019-01-301-128/+124
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | During the authentication phase, which begins when the connection is made and ends when an authentication reply is received or the connection is closed, require that all request have a version number of 0, and accept version 0 in that phase, regardless of whether we support it once we're authenticated. That means the messages from the client will not be rejected any server with an "unsupported version" error, and also means we can distinguish between a plaintext request and a TLS handshake message. Have the server send out authentication replies with a payload giving the minimum and maximum version number supported by the server. Have the client accept authentication replies whether or not they have that additional information; if the reply has no payload, the server is assumed to support only version 0. This means that old servers that don't supply that information, and new servers that do, can be handled by the new client code; old clients discard extra payload, and only support version 0 (no servers or clients supporting versions other than 0 have been released, yet), so they can also handle both old and new servers. The client then uses that information (sent or implied) to try to find the highest version that it and the server supports. If there is no such version, it's impossible for the client and server to communicate further, so the client just reports an error to its caller and gives up. If there *is* such a version, the client then uses it in all subsequent requests, and the server replies with the version in the request. For data packets, the version used in the "start capture" request is used. This avoids timeouts or dropped connections with old servers due to the initial request having an unsupported version number, and means that the negotiation never requires two authentication requests.
* Improve comments.Guy Harris2019-01-301-7/+26
|
* Shut down SSL sessions semi-gracefully.Guy Harris2019-01-291-4/+8
| | | | | | | | | Before we shut down the socket, send a shutdown alert. That should prevent some cases where errors are reported when they shouldn't be (it was happening if I did a --list-remote-interfaces in tcpdump). While we're at it, do the SSL shutdown *before* closing the main active socket; we were doing it *after*. Also, fix a comment.
* Clean up some whitespacesFrancois-Xavier Le Bail2019-01-231-1/+1
|
* You still have to send the timezone offset over the wire in an open reply.Guy Harris2019-01-221-0/+8
| | | | | | Removing it would be a *protocol* change, and there are clients out there that expect the open reply to be 8 bytes long. Just continue to send a zero over the wire.
* Use pthread_sigmask() rather than sigprocmask().Guy Harris2019-01-181-3/+3
| | | | | | The Single UNIX Specification says you should use pthread_sigmask(), not sigprocmask(), in multithreaded programs, and rpcapd is a multithreaded program.
* Log sock_check_hostlist() errors in rpcapd.Guy Harris2019-01-121-0/+7
| | | | | | | And make a getaddrinfo() failure an error, so that they're logged. ("The host trying to connect to us is not in the list" is not an error; we tell the client about it, but we don't have a reason to log it.)
* Fix the man page to reflect reality.Guy Harris2019-01-121-2/+3
|
* Don't log the error buffer before returning.Guy Harris2019-01-121-1/+0
| | | | | If there was an error, a message should already have been logged at priority LOGPRIO_ERROR; logging it again at LOGPRIO_DEBUG isn't useful.
* Pass the address of the error buffer.Guy Harris2019-01-121-1/+1
|
* Don't try to peek more than one byte into the stream.Guy Harris2019-01-121-38/+7
| | | | | | | | | There's no guarantee that we can arrange to wait for more than one byte while peeking into the socket. This means that a client sending a version 22 authentication request will make us think they're requesting TLS, but They. Shouldn't. Be. Doing. That.
* Try to catch TLS to a non-TLS server or non-TLS to a TLS-only server.Guy Harris2019-01-121-0/+212
| | | | | | | | | | | That way, the failure modes for those are a bit less ugly; for the former, you'll get a TLS handshake failure error, and for the latter, you'll get a "server requires TLS" authentication error, rather than some ugly protocol error from rpcapd in the former case and TLS in the latter case. To make this work, we just have to make sure that we never use protocol version 22. Do so.
* Wrong #define name for an invalid Windows API handle.Guy Harris2019-01-111-1/+1
|
* Clean up the termination of a capture session.Guy Harris2019-01-111-241/+200
| | | | | | | | | | | | | | | | | | On UN*X, instead of just cancelling the thread doing the capture, send it a SIGUSR1, to break out of a blocking call in libpcap, and wait for the thread to end with pthread_join(). Don't make it a detached thread, so that we can do this. In that thread, block SIGUSR1 unless we're in a pcap call, so that other system calls aren't disturbed by the SIGUSR1. (We were already doing things similarly on Windows.) Do all session cleanup in the main thread, after the thread completes. That way, we don't run the risk of trying to do cleanup in both threads. Put the thread information into the session structure, rather than having a separate structure. In session_close(), if there's a thread, tell it to finish and wait for it to finish, before cleaning up the session. Use session_close() in all cases where we want to finish with a capture session.
* Set up the parameters structure in one place.Guy Harris2019-01-111-7/+7
|
* Handle systems that lack vsyslog(), such as AIX.Guy Harris2019-01-112-0/+72
| | | | Add a copyright notice to rpcapd/log.{c,h} while we're at it.
* Properly check the return status of sock_check_hostlist().Guy Harris2019-01-091-4/+4
| | | | | | | | | It's not a boolean with 0 meaning "host not authorized" and 1 meaning "host authorized"; it's negative if we shouldn't let them connect, with -1 meaning "not in the host list" and -2 meaning "an error occurred in the process of checking", and non-negative if we should let them connect, with 0 meaning "they're in the host list" and 1 meaning "the host list is empty, so we're letting everybody in".
* Don't use two sockets for the control connection.Guy Harris2019-01-093-130/+115
| | | | | | | | | | | | | | | | | | | | | | If we do the accept() ourselves, we get only one socket on which we send and from which we receive messages. If we're run by an inetd-compatible daemon, it does the accept() and gets only one socket, which it proceeds to dup and hand to us as the standard input, output, and error; we really only need to use one of them. In the latter case, just dup the standard input, and then close the standard input, output, and error as we dup a descriptor for /dev/null to them. In both cases, just hand the one control socket to daemon_serviceloop(). Close it in daemon_serviceloop() before it returns, rather than in the caller after it returns. Only free the SSL structure for the control connection right before we close the socket for the control connection; we don't need to free it when we close a data connection.
* Clarify comment.Guy Harris2019-01-091-1/+2
|
* rpcapd-config.manfile is a generated file; ignore it in Git.Guy Harris2019-01-091-0/+1
|
* Document the -D option.Guy Harris2019-01-092-1/+7
|
* Fix some errors.Guy Harris2019-01-081-1/+2
|
* Put pcap_win32_err_to_str() into fmtutils.c, and use it for all Win32 errors.Guy Harris2019-01-082-31/+9
| | | | | | | | We don't need N different places all doing their own calls to FormatMessage(); centralize it in pcap_win32_err_to_str(), now in fmtutils.c for use in rpcapd as well as libpcap. Merge in some fixes from the code in sock_fmterror().
* Initialize most of the pars structure before we use it.Guy Harris2019-01-081-7/+7
|
* Add sslutils.c to rpcapd.Guy Harris2019-01-081-0/+1
|
* To use rpcapd_log() you need to include log.h.Guy Harris2019-01-071-0/+1
|
* Fix a typo and a "my brain was on syslog time" error.Guy Harris2019-01-071-2/+2
|
* Temporarily remove the Windows "system log" code.Guy Harris2019-01-071-0/+4
| | | | Needs more work; this should fix compile errors for now.
* Pass a copy of the host/port list to daemon_serviceloop() on Windows.Guy Harris2019-01-071-29/+43
| | | | | | | | Rename the sock_copy structure to params_copy, and add a pointer to the host list to it. Make the copy, stuff a pointer to it into the allocated structure, and do the appropriate freeing on errors; in the initial routine of the service thread, pass on the host list pointer from the structure.
* Make the key file and certificate file names local to sslutils.c.Guy Harris2019-01-071-2/+2
| | | | | | | | | Have routines that set them, given a pointer to the name. Use that in rpcapd, rather than copying to a buffer (you don't need to copy strings from argv - unless you're going to overwrite them, which you probably shouldn't do). This removes a requirement for the platform to define PATH_MAX.
* Move the SSL setup and host/port list checking to daemon_serviceloop().Guy Harris2019-01-073-100/+133
| | | | | | | | | | | | | | | | | | | | | | | | | | | | That: 1) arranges that it's done only in one code path; 2) arranges that it not be done in the main connection-accepting thread/process if this isn't an inetd-style daemon; 3) means that we're doing the host/port list checking in inetd-style daemons - we weren't doing it before; 4) means that we're doing both of them after we've turned off non-blocking mode on Windows, not before - doing it before may cause the SSL setup and sending a host/port list check error not to work (as we won't block waiting for input or waiting for buffer space to be available for output). Fix the file descriptor handling for inetd-style daemons while we're at it; we should redirect the standard error to /dev/null - it's not guaranteed to, for example, go to a daemon that reads your error messages and logs them, and it could be going over the connection, which would be a problem. Close the control socket with sock_close() after daemon_serviceloop() returns, in case shutting down the write side is necessary to have the connection shut down cleanly.
* Defer initialization of a log system to the first attempt to log to it.Guy Harris2019-01-071-38/+24
| | | | | | | | | | | | | That: 1) avoids doing any initialization if we end up logging to the standard error and 2) means that the first time we log to the "system log" we'll attempt to initialize it, even if we've logged to the standard error earlier.
* Default to logging to the standard error, not the system log.Guy Harris2019-01-071-1/+1
| | | | | Only if it thinks it's being run as a daemon should rpcapd log to the system log.
* Support logging rpcapd messages to the "system log".Guy Harris2019-01-076-58/+233
| | | | | | | | That's what you want for daemons, as the standard error might not go anywhere or, worse, might go to the control socket. Also have a -D flag to control whether to log debug messages or not; the default is "not".