]> PatchyGit - patchyircd.git/commitdiff
fix localhost/hidden service detection
authorEgor <egor@patchysicp.xyz>
Wed, 31 Jan 2024 11:52:12 +0000 (13:52 +0200)
committerEgor <egor@patchysicp.xyz>
Wed, 31 Jan 2024 11:52:12 +0000 (13:52 +0200)
tbh hidden service should be probably done via AF_UNIX

src/main.c

index 1627ffc..5ae98d9 100644 (file)
@@ -149,13 +149,38 @@ void accept_from_sock(struct listener *listener)
                // Set nonblock
                net_nonblock(newSocket);
 
+               int is_onion = 0;
+               {
+                       struct sockaddr_storage sockname;
+                       socklen_t socknamelen = sizeof(sockname);
+                       if (getsockname(newSocket, (struct sockaddr *)&sockname, &socknamelen) == -1) {
+                               net_perror("getsockname");
+                               exit(EXIT_FAILURE);
+                       }
+                       if (sockname.ss_family == AF_INET) {
+                               struct in_addr *ia = &((struct sockaddr_in *)&sockname)->sin_addr;
+                               // onion if connecting to 127.0.0.2
+                               if (ntohl(ia->s_addr) == 0x7F000002)
+                                       is_onion = 1;
+                       }
+               }
+
                char client_addr[100];
                int port;
+               int is_local = 0;
                if (addr.ss_family == AF_INET) {
-                       inet_ntop(AF_INET, &((struct sockaddr_in*)&addr)->sin_addr, client_addr, sizeof(client_addr));
+                       struct in_addr *ia = &((struct sockaddr_in *)&addr)->sin_addr;
+                       // local if connecting from 127.0.0.0/8
+                       if ((ntohl(ia->s_addr) & 0xFF000000) == 0x7F000000)
+                               is_local = 1;
+                       inet_ntop(AF_INET, ia, client_addr, sizeof(client_addr));
                        port = ntohs(((struct sockaddr_in*)&addr)->sin_port);
                } else if (addr.ss_family == AF_INET6) {
-                       inet_ntop(AF_INET6, &((struct sockaddr_in6*)&addr)->sin6_addr, client_addr, sizeof(client_addr));
+                       struct in6_addr *ia = &((struct sockaddr_in6 *)&addr)->sin6_addr;
+                       // local if connecting from ::1
+                       if (!memcmp(ia->s6_addr, "\0\0\0\0""\0\0\0\0""\0\0\0\0""\0\0\0\1", 16))
+                               is_local = 1;
+                       inet_ntop(AF_INET6, ia, client_addr, sizeof(client_addr));
                        port = ntohs(((struct sockaddr_in6*)&addr)->sin6_port);
                } else {
                        strcpy_lit(client_addr, "?");
@@ -184,11 +209,8 @@ void accept_from_sock(struct listener *listener)
                if (cctx)
                        cl->umode |= UMODE_SECURE;
                extern const char *hostname;
-               if (!strcmp(cl->peername, "127.0.0.1")) {
-                       cl->hostname = mystrdup("localhost");
-                       cl->umode |= UMODE_SECURE;
-               } else if (!strcmp(cl->peername, "127.0.0.2")) {
-                       cl->hostname = mystrdup("onion");
+               if (is_local) {
+                       cl->hostname = mystrdup(is_onion ? "onion" : "localhost");
                        cl->umode |= UMODE_SECURE;
                } else {
                        cl->hostname = mystrdup(hostname);