From b6c99ba3efeb51c7f08c1a4b1392f3942258195d Mon Sep 17 00:00:00 2001 From: Adam Ierymenko Date: Mon, 14 Nov 2016 15:47:06 -0800 Subject: [PATCH] Add (currently undocumented) option to allow management from certain networks. --- one.cpp | 11 ++++++++++- service/OneService.cpp | 37 +++++++++++++++++++++++-------------- service/OneService.hpp | 4 +++- 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/one.cpp b/one.cpp index 55cc2e193..51cda0c70 100644 --- a/one.cpp +++ b/one.cpp @@ -973,6 +973,7 @@ int main(int argc,char **argv) std::string homeDir; unsigned int port = ZT_DEFAULT_PORT; bool skipRootCheck = false; + const char *allowManagementFrom = (const char *)0; for(int i=1;irun()) { case OneService::ONE_STILL_RUNNING: // shouldn't happen, run() won't return until done case OneService::ONE_NORMAL_TERMINATION: diff --git a/service/OneService.cpp b/service/OneService.cpp index fcbccd634..91063bada 100644 --- a/service/OneService.cpp +++ b/service/OneService.cpp @@ -483,6 +483,7 @@ public: const std::string _homePath; BackgroundResolver _tcpFallbackResolver; + InetAddress _allowManagementFrom; EmbeddedNetworkController *_controller; Phy _phy; Node *_node; @@ -570,7 +571,7 @@ public: // end member variables ---------------------------------------------------- - OneServiceImpl(const char *hp,unsigned int port) : + OneServiceImpl(const char *hp,unsigned int port,const char *allowManagementFrom) : _homePath((hp) ? hp : ".") ,_tcpFallbackResolver(ZT_TCP_FALLBACK_RELAY) ,_controller((EmbeddedNetworkController *)0) @@ -595,6 +596,9 @@ public: #endif ,_run(true) { + if (allowManagementFrom) + _allowManagementFrom.fromString(allowManagementFrom); + _ports[0] = 0; _ports[1] = 0; _ports[2] = 0; @@ -614,7 +618,7 @@ public: struct sockaddr_in in4; memset(&in4,0,sizeof(in4)); in4.sin_family = AF_INET; - in4.sin_addr.s_addr = Utils::hton((uint32_t)0x7f000001); // right now we just listen for TCP @127.0.0.1 + in4.sin_addr.s_addr = Utils::hton((uint32_t)((allowManagementFrom) ? 0 : 0x7f000001)); // right now we just listen for TCP @127.0.0.1 in4.sin_port = Utils::hton((uint16_t)port); _v4TcpControlSocket = _phy.tcpListen((const struct sockaddr *)&in4,this); @@ -622,7 +626,8 @@ public: memset((void *)&in6,0,sizeof(in6)); in6.sin6_family = AF_INET6; in6.sin6_port = in4.sin_port; - in6.sin6_addr.s6_addr[15] = 1; // IPv6 localhost == ::1 + if (!allowManagementFrom) + in6.sin6_addr.s6_addr[15] = 1; // IPv6 localhost == ::1 _v6TcpControlSocket = _phy.tcpListen((const struct sockaddr *)&in6,this); // We must bind one of IPv4 or IPv6 -- support either failing to support hosts that @@ -1699,16 +1704,20 @@ public: std::string contentType("text/plain"); // default if not changed in handleRequest() unsigned int scode = 404; - try { - if (_controlPlane) - scode = _controlPlane->handleRequest(tc->from,tc->parser.method,tc->url,tc->headers,tc->body,data,contentType); - else scode = 500; - } catch (std::exception &exc) { - fprintf(stderr,"WARNING: unexpected exception processing control HTTP request: %s" ZT_EOL_S,exc.what()); - scode = 500; - } catch ( ... ) { - fprintf(stderr,"WARNING: unexpected exception processing control HTTP request: unknown exceptino" ZT_EOL_S); - scode = 500; + if ( ((!_allowManagementFrom)&&(tc->from.ipScope() == InetAddress::IP_SCOPE_LOOPBACK)) || (_allowManagementFrom.containsAddress(tc->from)) ) { + try { + if (_controlPlane) + scode = _controlPlane->handleRequest(tc->from,tc->parser.method,tc->url,tc->headers,tc->body,data,contentType); + else scode = 500; + } catch (std::exception &exc) { + fprintf(stderr,"WARNING: unexpected exception processing control HTTP request: %s" ZT_EOL_S,exc.what()); + scode = 500; + } catch ( ... ) { + fprintf(stderr,"WARNING: unexpected exception processing control HTTP request: unknown exceptino" ZT_EOL_S); + scode = 500; + } + } else { + scode = 401; } const char *scodestr; @@ -1973,7 +1982,7 @@ std::string OneService::autoUpdateUrl() return std::string(); } -OneService *OneService::newInstance(const char *hp,unsigned int port) { return new OneServiceImpl(hp,port); } +OneService *OneService::newInstance(const char *hp,unsigned int port,const char *allowManagementFrom) { return new OneServiceImpl(hp,port,allowManagementFrom); } OneService::~OneService() {} } // namespace ZeroTier diff --git a/service/OneService.hpp b/service/OneService.hpp index 72ff7d842..553bfd5e1 100644 --- a/service/OneService.hpp +++ b/service/OneService.hpp @@ -98,10 +98,12 @@ public: * * @param hp Home path * @param port TCP and UDP port for packets and HTTP control (if 0, pick random port) + * @param allowManagementFrom If non-NULL, allow control from supplied IP/netmask */ static OneService *newInstance( const char *hp, - unsigned int port); + unsigned int port, + const char *allowManagementFrom = (const char *)0); virtual ~OneService();