1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-07-01 03:22:48 -05:00

Log identifying information for the other end of connections.

When anyone connects to a PuTTY tool's listening socket - whether it's
a user of a local->remote port forwarding, a connection-sharing
downstream or a client of Pageant - we'd like to log as much
information as we can find out about where the connection came from.

To that end, I've implemented a function sk_peer_info() in the socket
abstraction, which returns a freeform text string as best it can (or
NULL, if it can't get anything at all) describing the thing at the
other end of the connection. For TCP connections, this is done using
getpeername() to get an IP address and port in the obvious way; for
Unix-domain sockets, we attempt SO_PEERCRED (conditionalised on some
moderately hairy autoconfery) to get the pid and owner of the peer. I
haven't implemented anything for Windows named pipes, but I will if I
hear of anything useful.
This commit is contained in:
Simon Tatham
2015-05-18 13:57:45 +01:00
parent 63d7365ae6
commit c8f83979a3
17 changed files with 227 additions and 19 deletions

View File

@ -186,4 +186,9 @@ void *sk_getxdmdata(void *sock, int *lenp);
*/
extern Backend serial_backend;
/*
* uxpeer.c, wrapping getsockopt(SO_PEERCRED).
*/
int so_peercred(int fd, int *pid, int *uid, int *gid);
#endif

View File

@ -16,6 +16,8 @@
#include <netinet/tcp.h>
#include <netdb.h>
#include <sys/un.h>
#include <pwd.h>
#include <grp.h>
#define DEFINE_PLUG_METHOD_MACROS
#include "putty.h"
@ -485,6 +487,7 @@ static int sk_tcp_write(Socket s, const char *data, int len);
static int sk_tcp_write_oob(Socket s, const char *data, int len);
static void sk_tcp_write_eof(Socket s);
static void sk_tcp_set_frozen(Socket s, int is_frozen);
static char *sk_tcp_peer_info(Socket s);
static const char *sk_tcp_socket_error(Socket s);
static struct socket_function_table tcp_fn_table = {
@ -495,7 +498,8 @@ static struct socket_function_table tcp_fn_table = {
sk_tcp_write_eof,
sk_tcp_flush,
sk_tcp_set_frozen,
sk_tcp_socket_error
sk_tcp_socket_error,
sk_tcp_peer_info,
};
static Socket sk_tcp_accept(accept_ctx_t ctx, Plug plug)
@ -1420,6 +1424,51 @@ static void sk_tcp_set_frozen(Socket sock, int is_frozen)
uxsel_tell(s);
}
static char *sk_tcp_peer_info(Socket sock)
{
Actual_Socket s = (Actual_Socket) sock;
struct sockaddr_storage addr;
socklen_t addrlen = sizeof(addr);
char buf[INET6_ADDRSTRLEN];
if (getpeername(s->s, (struct sockaddr *)&addr, &addrlen) < 0)
return NULL;
if (addr.ss_family == AF_INET) {
return dupprintf
("%s:%d",
inet_ntoa(((struct sockaddr_in *)&addr)->sin_addr),
(int)ntohs(((struct sockaddr_in *)&addr)->sin_port));
#ifndef NO_IPV6
} else if (addr.ss_family == AF_INET6) {
return dupprintf
("[%s]:%d",
inet_ntop(AF_INET6, &((struct sockaddr_in6 *)&addr)->sin6_addr,
buf, sizeof(buf)),
(int)ntohs(((struct sockaddr_in6 *)&addr)->sin6_port));
#endif
} else if (addr.ss_family == AF_UNIX) {
/*
* For Unix sockets, the source address is unlikely to be
* helpful. Instead, we try SO_PEERCRED and try to get the
* source pid.
*/
int pid, uid, gid;
if (so_peercred(s->s, &pid, &uid, &gid)) {
char uidbuf[64], gidbuf[64];
sprintf(uidbuf, "%d", uid);
sprintf(gidbuf, "%d", gid);
struct passwd *pw = getpwuid(uid);
struct group *gr = getgrgid(gid);
return dupprintf("pid %d (%s:%s)", pid,
pw ? pw->pw_name : uidbuf,
gr ? gr->gr_name : gidbuf);
}
return NULL;
} else {
return NULL;
}
}
static void uxsel_tell(Actual_Socket s)
{
int rwx = 0;

32
unix/uxpeer.c Normal file
View File

@ -0,0 +1,32 @@
/*
* Unix: wrapper for getsockopt(SO_PEERCRED), conditionalised on
* appropriate autoconfery.
*/
#ifdef HAVE_CONFIG_H
# include "uxconfig.h" /* leading space prevents mkfiles.pl trying to follow */
#endif
#ifdef HAVE_SO_PEERCRED
#define _GNU_SOURCE
#include <features.h>
#endif
#include <sys/socket.h>
#include "putty.h"
int so_peercred(int fd, int *pid, int *uid, int *gid)
{
#ifdef HAVE_SO_PEERCRED
struct ucred cr;
socklen_t crlen = sizeof(cr);
if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cr, &crlen) == 0) {
*pid = cr.pid;
*uid = cr.uid;
*gid = cr.gid;
return TRUE;
}
#endif
return FALSE;
}

View File

@ -245,7 +245,8 @@ Socket platform_new_connection(SockAddr addr, const char *hostname,
sk_localproxy_write_eof,
sk_localproxy_flush,
sk_localproxy_set_frozen,
sk_localproxy_socket_error
sk_localproxy_socket_error,
NULL, /* peer_info */
};
Local_Proxy_Socket ret;