diff --git a/lib/socket.cpp b/lib/socket.cpp index ad70cb93..61ba79e4 100644 --- a/lib/socket.cpp +++ b/lib/socket.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #define BUFFER_BLOCKSIZE 4096 // set buffer blocksize to 4KiB @@ -656,17 +657,17 @@ bool Socket::Connection::isAddress(std::string addr){ int s = getaddrinfo(addr.c_str(), 0, &hints, &result); if (s != 0){return false;} - char newaddr[INET_ADDRSTRLEN]; + char newaddr[INET6_ADDRSTRLEN]; newaddr[0] = 0; for (rp = result; rp != NULL; rp = rp->ai_next){ - if (rp->ai_family == AF_INET && inet_ntop(rp->ai_family, &(((sockaddr_in *)rp->ai_addr)->sin_addr), newaddr, INET_ADDRSTRLEN)){ - DEBUG_MSG(DLVL_DEVEL, "Comparing: '%s' to '%s'", remotehost.c_str(), newaddr); + if (rp->ai_family == AF_INET && inet_ntop(rp->ai_family, &(((sockaddr_in *)rp->ai_addr)->sin_addr), newaddr, INET6_ADDRSTRLEN)){ + INFO_MSG("Comparing '%s' to '%s'", remotehost.c_str(), newaddr); if (remotehost == newaddr){return true;} - DEBUG_MSG(DLVL_DEVEL, "Comparing: '%s' to '::ffff:%s'", remotehost.c_str(), newaddr); + INFO_MSG("Comparing '%s' to '::ffff:%s'", remotehost.c_str(), newaddr); if (remotehost == std::string("::ffff:") + newaddr){return true;} } - if (rp->ai_family == AF_INET6 && inet_ntop(rp->ai_family, &(((sockaddr_in6 *)rp->ai_addr)->sin6_addr), newaddr, INET_ADDRSTRLEN)){ - DEBUG_MSG(DLVL_DEVEL, "Comparing: '%s' to '%s'", remotehost.c_str(), newaddr); + if (rp->ai_family == AF_INET6 && inet_ntop(rp->ai_family, &(((sockaddr_in6 *)rp->ai_addr)->sin6_addr), newaddr, INET6_ADDRSTRLEN)){ + INFO_MSG("Comparing '%s' to '%s'", remotehost.c_str(), newaddr); if (remotehost == newaddr){return true;} } } @@ -674,6 +675,36 @@ bool Socket::Connection::isAddress(std::string addr){ return false; } +bool Socket::Connection::isLocal(){ + struct ifaddrs * ifAddrStruct=NULL; + struct ifaddrs * ifa=NULL; + void * tmpAddrPtr=NULL; + char addressBuffer[INET6_ADDRSTRLEN]; + + getifaddrs(&ifAddrStruct); + + for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) { + if (!ifa->ifa_addr) { + continue; + } + if (ifa->ifa_addr->sa_family == AF_INET) { // check it is IP4 + tmpAddrPtr=&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr; + inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN); + INFO_MSG("Comparing '%s' to '%s'", remotehost.c_str(), addressBuffer); + if (remotehost == addressBuffer){return true;} + INFO_MSG("Comparing '%s' to '::ffff:%s'", remotehost.c_str(), addressBuffer); + if (remotehost == std::string("::ffff:") + addressBuffer){return true;} + } else if (ifa->ifa_addr->sa_family == AF_INET6) { // check it is IP6 + tmpAddrPtr=&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr; + inet_ntop(AF_INET6, tmpAddrPtr, addressBuffer, INET6_ADDRSTRLEN); + INFO_MSG("Comparing '%s' to '%s'", remotehost.c_str(), addressBuffer); + if (remotehost == addressBuffer){return true;} + } + } + if (ifAddrStruct!=NULL) freeifaddrs(ifAddrStruct); + return false; +} + /// Create a new base Server. The socket is never connected, and a placeholder for later connections. Socket::Server::Server(){ sock = -1; diff --git a/lib/socket.h b/lib/socket.h index 0ebe0eb8..7704143d 100644 --- a/lib/socket.h +++ b/lib/socket.h @@ -82,6 +82,7 @@ namespace Socket{ std::string getError(); ///< Returns a string describing the last error that occured. bool connected() const; ///< Returns the connected-state for this socket. bool isAddress(std::string addr); + bool isLocal(); ///< Returns true if remote address is a local address. // buffered i/o methods bool spool(); ///< Updates the downbufferinternal variables. bool peek(); ///< Clears the downbuffer and fills it with peek diff --git a/src/controller/controller_api.cpp b/src/controller/controller_api.cpp index aef78505..e022f624 100644 --- a/src/controller/controller_api.cpp +++ b/src/controller/controller_api.cpp @@ -174,6 +174,11 @@ int Controller::handleAPIConnection(Socket::Connection & conn){ } {//lock the config mutex here - do not unlock until done processing tthread::lock_guard guard(configMutex); + //Are we local and not forwarded? Instant-authorized. + if (!authorized && !H.hasHeader("X-Real-IP") && conn.isLocal()){ + INFO_MSG("Local API access automatically authorized"); + authorized = true; + } //if already authorized, do not re-check for authorization if (authorized){ Response["authorize"]["status"] = "OK";