diff --git a/src/common/identd.c b/src/common/identd.c index 919282ea..430c7e8f 100644 --- a/src/common/identd.c +++ b/src/common/identd.c @@ -1,8 +1,13 @@ /* simple identd server for xchat under win32 */ +#include "inet.h" +#include "xchat.h" +#include "xchatc.h" static int identd_is_running = FALSE; - +#ifdef USE_IPV6 +static int identd_ipv6_is_running = FALSE; +#endif static int identd (char *username) @@ -75,11 +80,102 @@ identd (char *username) return 0; } -static void +#ifdef USE_IPV6 +static int +identd_ipv6 (char *username) +{ + int sok, read_sok, len; + char *p; + char buf[256]; + char outbuf[256]; + char ipv6buf[60]; + DWORD ipv6buflen = sizeof (ipv6buf); + struct sockaddr_in6 addr; + + sok = socket (AF_INET6, SOCK_STREAM, 0); + + if (sok == INVALID_SOCKET) + { + free (username); + return 0; + } + + len = 1; + setsockopt (sok, SOL_SOCKET, SO_REUSEADDR, (char *) &len, sizeof (len)); + + memset (&addr, 0, sizeof (addr)); + addr.sin6_family = AF_INET6; + addr.sin6_port = htons (113); + + if (bind (sok, (struct sockaddr *) &addr, sizeof (addr)) == SOCKET_ERROR) + { + closesocket (sok); + free (username); + return 0; + } + + if (listen (sok, 1) == SOCKET_ERROR) + { + closesocket (sok); + free (username); + return 0; + } + + len = sizeof (addr); + read_sok = accept (sok, (struct sockaddr *) &addr, &len); + closesocket (sok); + + if (read_sok == INVALID_SOCKET) + { + free (username); + return 0; + } + + identd_ipv6_is_running = FALSE; + + if (WSAAddressToString ((struct sockaddr *) &addr, sizeof (addr), NULL, &ipv6buf, &ipv6buflen) == SOCKET_ERROR) + { + snprintf (ipv6buf, sizeof (ipv6buf) - 1, "[SOCKET ERROR: 0x%X]", WSAGetLastError ()); + } + + snprintf (outbuf, sizeof (outbuf), "%%\tServicing ident request from %s\n", ipv6buf); + PrintText (current_sess, outbuf); + + recv (read_sok, buf, sizeof (buf) - 1, 0); + buf[sizeof (buf) - 1] = 0; /* ensure null termination */ + + p = strchr (buf, ','); + + if (p) + { + snprintf (outbuf, sizeof (outbuf) - 1, "%d, %d : USERID : UNIX : %s\r\n", atoi (buf), atoi (p + 1), username); + outbuf[sizeof (outbuf) - 1] = 0; /* ensure null termination */ + send (read_sok, outbuf, strlen (outbuf), 0); + } + + sleep (1); + closesocket (read_sok); + free (username); + + return 0; +} +#endif + +void identd_start (char *username) { DWORD tid; +#ifdef USE_IPV6 + DWORD tidv6; + if (identd_ipv6_is_running == FALSE) + { + identd_ipv6_is_running = TRUE; + CloseHandle (CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) identd_ipv6, + strdup (username), 0, &tidv6)); + } +#endif + if (identd_is_running == FALSE) { identd_is_running = TRUE; diff --git a/src/common/identd.h b/src/common/identd.h new file mode 100644 index 00000000..636f9641 --- /dev/null +++ b/src/common/identd.h @@ -0,0 +1 @@ +void identd_start (char *username); diff --git a/src/common/makefile.mak b/src/common/makefile.mak index f78a6d8d..d6df2608 100644 --- a/src/common/makefile.mak +++ b/src/common/makefile.mak @@ -7,6 +7,7 @@ ctcp.obj \ dcc.obj \ dirent-win32.obj \ history.obj \ +identd.obj \ ignore.obj \ inbound.obj \ modes.obj \ diff --git a/src/common/server.c b/src/common/server.c index 53e877e3..75b2e005 100644 --- a/src/common/server.c +++ b/src/common/server.c @@ -67,7 +67,7 @@ #endif #ifdef WIN32 -#include "identd.c" +#include "identd.h" #endif #ifdef USE_LIBPROXY