X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=unix%2Fuxnet.c;h=5058d8ab20409a82f92c159979f6f0cd841ded6d;hb=a063e522970946bf7d5dc052079d7773c0dee76d;hp=235d6fd97d039d3ed2f97167e68e4285935981ee;hpb=fe24f4dfba2aa2db270427bb3d1f7c6cb7f19221;p=PuTTY.git diff --git a/unix/uxnet.c b/unix/uxnet.c index 235d6fd9..5058d8ab 100644 --- a/unix/uxnet.c +++ b/unix/uxnet.c @@ -16,6 +16,8 @@ #include #include #include +#include +#include #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) @@ -1419,6 +1423,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;