From: <og...@us...> - 2008-12-01 12:34:54
|
Revision: 930 http://dansguardian.svn.sourceforge.net/dansguardian/?rev=930&view=rev Author: ognam Date: 2008-12-01 12:34:50 +0000 (Mon, 01 Dec 2008) Log Message: ----------- Add a new Windows-specific authentication plugin for identifying locally logged on users by their connection details. Will *only* work for local users, not for people connecting from a remote machine. Modified Paths: -------------- branches/mingw32/dansguardian/configs/authplugins/Makefile.am branches/mingw32/dansguardian/configs/dansguardian.conf.in branches/mingw32/dansguardian/configure.ac branches/mingw32/dansguardian/src/Auth.cpp branches/mingw32/dansguardian/src/Makefile.am branches/mingw32/dansguardian/src/Socket.cpp branches/mingw32/dansguardian/src/Socket.hpp Added Paths: ----------- branches/mingw32/dansguardian/configs/authplugins/winuser.conf branches/mingw32/dansguardian/src/authplugins/winuser.cpp Modified: branches/mingw32/dansguardian/configs/authplugins/Makefile.am =================================================================== --- branches/mingw32/dansguardian/configs/authplugins/Makefile.am 2008-11-28 13:51:54 UTC (rev 929) +++ branches/mingw32/dansguardian/configs/authplugins/Makefile.am 2008-12-01 12:34:50 UTC (rev 930) @@ -10,8 +10,12 @@ FLISTS += proxy-ntlm.conf endif +if WIN32 +FLISTS += winuser.conf +endif + EXTRA_DIST = proxy-basic.conf ident.conf ip.conf.in proxy-ntlm.conf \ - proxy-digest.conf + proxy-digest.conf winuser.conf install-data-local: $(mkinstalldirs) $(DESTDIR)$(DGDATADIR) && \ Added: branches/mingw32/dansguardian/configs/authplugins/winuser.conf =================================================================== --- branches/mingw32/dansguardian/configs/authplugins/winuser.conf (rev 0) +++ branches/mingw32/dansguardian/configs/authplugins/winuser.conf 2008-12-01 12:34:50 UTC (rev 930) @@ -0,0 +1,5 @@ +# Windows user auth plugin +# Identifies usernames of Windows users from TCP connection details. +# Only works for users logged on to the same machine that DG is running on. + +plugname = 'winuser' Modified: branches/mingw32/dansguardian/configs/dansguardian.conf.in =================================================================== --- branches/mingw32/dansguardian/configs/dansguardian.conf.in 2008-11-28 13:51:54 UTC (rev 929) +++ branches/mingw32/dansguardian/configs/dansguardian.conf.in 2008-12-01 12:34:50 UTC (rev 930) @@ -458,9 +458,9 @@ #@NTLMSUPPORT@authplugin = '@DGCONFDIR@/authplugins/proxy-ntlm.conf' #authplugin = '@DGCONFDIR@/authplugins/ident.conf' #authplugin = '@DGCONFDIR@/authplugins/ip.conf' +#@WIN32SUPPORT@authplugin = '@DGCONFDIR@/authplugins/winuser.conf' - # Re-check replaced URLs # As a matter of course, URLs undergo regular expression search/replace (urlregexplist) # *after* checking the exception site/URL/regexpURL lists, but *before* checking against Modified: branches/mingw32/dansguardian/configure.ac =================================================================== --- branches/mingw32/dansguardian/configure.ac 2008-11-28 13:51:54 UTC (rev 929) +++ branches/mingw32/dansguardian/configure.ac 2008-12-01 12:34:50 UTC (rev 930) @@ -129,13 +129,18 @@ mingw*) win=true AC_CHECK_FUNCS([inet_aton strerror_r ctime_r mkstemp localtime_r]) - LIBS="-lwsock32 ${LIBS}" + LIBS="-lwsock32 -liphlpapi ${LIBS}" CXXFLAGS="-mthreads ${CXXFLAGS}" + AC_DEFINE(WIN32_LEAN_AND_MEAN, 1, [Define if building for Windows]) + AC_DEFINE(WINVER, [0x0502], [Define if building for Windows]) + WIN32SUPPORT="" ;; *) + WIN32SUPPORT="!! Windows only !! " ;; esac AM_CONDITIONAL(WIN32, test "x$win" = "xtrue") +AC_SUBST(WIN32SUPPORT) AC_MSG_CHECKING(for debug option) AC_ARG_WITH(dgdebug, Modified: branches/mingw32/dansguardian/src/Auth.cpp =================================================================== --- branches/mingw32/dansguardian/src/Auth.cpp 2008-11-28 13:51:54 UTC (rev 929) +++ branches/mingw32/dansguardian/src/Auth.cpp 2008-12-01 12:34:50 UTC (rev 930) @@ -52,6 +52,10 @@ extern authcreate_t ntlmcreate; #endif +#ifdef WIN32 +extern authcreate_t winusercreate; +#endif + // IMPLEMENTATION AuthPlugin::AuthPlugin(ConfigVar &definition):is_connection_based(false), needs_proxy_query(false) @@ -171,6 +175,15 @@ } #endif +#ifdef WIN32 + if (plugname == "winuser") { +#ifdef DGDEBUG + std::cout << "Enabling Windows user identification auth plugin" << std::endl; +#endif + return winusercreate(cv); + } +#endif + if (!is_daemonised) { std::cerr << "Unable to load plugin: " << pluginConfigPath << std::endl; } Modified: branches/mingw32/dansguardian/src/Makefile.am =================================================================== --- branches/mingw32/dansguardian/src/Makefile.am 2008-11-28 13:51:54 UTC (rev 929) +++ branches/mingw32/dansguardian/src/Makefile.am 2008-12-01 12:34:50 UTC (rev 930) @@ -76,10 +76,12 @@ UDSOCKET_SOURCE = SYSV_SOURCE = REPLACEMENT_SOURCE = ../lib/ctime_r.cpp ../lib/inet_aton.cpp ../lib/strerror_r.cpp ../lib/mkstemp.cpp ../lib/localtime_r.cpp ../lib/syslog.cpp +WINUSERAUTH_SOURCE = authplugins/winuser.cpp else UDSOCKET_SOURCE = UDSocket.cpp UDSocket.hpp SYSV_SOURCE = SysV.cpp SysV.hpp REPLACEMENT_SOURCE = +WINUSERAUTH_SOURCE = endif sbin_PROGRAMS = dansguardian @@ -132,4 +134,4 @@ $(TRICKLEDM_SOURCE) $(PROXYAUTH_SOURCE) \ $(IDENTAUTH_SOURCE) $(IPAUTH_SOURCE) \ $(NTLMAUTH_SOURCE) $(DIGESTAUTH_SOURCE) \ - $(REPLACEMENT_SOURCE) + $(WINUSERAUTH_SOURCE) $(REPLACEMENT_SOURCE) Modified: branches/mingw32/dansguardian/src/Socket.cpp =================================================================== --- branches/mingw32/dansguardian/src/Socket.cpp 2008-11-28 13:51:54 UTC (rev 929) +++ branches/mingw32/dansguardian/src/Socket.cpp 2008-12-01 12:34:50 UTC (rev 930) @@ -97,6 +97,12 @@ return inet_ntoa(my_adr.sin_addr); } +// find the port to which the client has connected +uint16_t Socket::getLocalPort() +{ + return ntohs(my_adr.sin_port); +} + // find the ip of the client connecting to us std::string Socket::getPeerIP() { @@ -104,15 +110,15 @@ } // find the port of the client connecting to us -int Socket::getPeerSourcePort() +uint16_t Socket::getPeerSourcePort() { return ntohs(peer_adr.sin_port); } // return the address of the client connecting to us -unsigned long int Socket::getPeerSourceAddr() +uint32_t Socket::getPeerSourceAddr() { - return (unsigned long int)ntohl(peer_adr.sin_addr.s_addr); + return ntohl(peer_adr.sin_addr.s_addr); } // close connection & wipe address structs Modified: branches/mingw32/dansguardian/src/Socket.hpp =================================================================== --- branches/mingw32/dansguardian/src/Socket.hpp 2008-11-28 13:51:54 UTC (rev 929) +++ branches/mingw32/dansguardian/src/Socket.hpp 2008-12-01 12:34:50 UTC (rev 930) @@ -55,11 +55,12 @@ // get remote IP/port std::string getPeerIP(); - int getPeerSourcePort(); - unsigned long int getPeerSourceAddr(); + uint16_t getPeerSourcePort(); + uint32_t getPeerSourceAddr(); - // get local IP + // get local IP/port std::string getLocalIP(); + uint16_t getLocalPort(); private: // local & remote addresses Added: branches/mingw32/dansguardian/src/authplugins/winuser.cpp =================================================================== --- branches/mingw32/dansguardian/src/authplugins/winuser.cpp (rev 0) +++ branches/mingw32/dansguardian/src/authplugins/winuser.cpp 2008-12-01 12:34:50 UTC (rev 930) @@ -0,0 +1,152 @@ +// Windows user identification auth plugin + +//Please refer to http://dansguardian.org/?page=copyright2 +//for the license for this code. + +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +// There is a distinct lack of "#ifdef WIN32" in the below for one reason: +// this plugin is only compiled if the platform is detected as Windows to +// begin with, so portability isn't our biggest concern. + + +// INCLUDES +#ifdef HAVE_CONFIG_H + #include "dgconfig.h" +#endif + +#include "../Auth.hpp" + +#include "../../lib/syslog.h" + +#include "windows.h" +#include "iphlpapi.h" +#include "winsock2.h" +#include "ws2tcpip.h" + + +// DECLARATIONS + +// class name is relevant! +class winuserinstance:public AuthPlugin +{ +public: + winuserinstance(ConfigVar &definition):AuthPlugin(definition) {}; + int identify(Socket& peercon, Socket& proxycon, HTTPHeader &h, std::string &string); +}; + + +// IMPLEMENTATION + +// class factory code *MUST* be included in every plugin + +AuthPlugin *winusercreate(ConfigVar & definition) +{ + return new winuserinstance(definition); +} + +// end of Class factory + +// Use arcane black magic to identify Windows username from connection details +int winuserinstance::identify(Socket& peercon, Socket& proxycon, HTTPHeader &h, std::string &string) +{ + // Look up the client's connection in the extended TCP table. + // We can't predict how much memory we will need for this, + // so call it with none and allocate however much it says + // it's going to require (repeat until success). + MIB_TCPTABLE_OWNER_PID *tcptable = NULL; + DWORD tcptablesize = 0; + DWORD err; + while ((err = GetExtendedTcpTable(tcptable, &tcptablesize, false, AF_INET, TCP_TABLE_OWNER_PID_CONNECTIONS, 0)) == ERROR_INSUFFICIENT_BUFFER) + { + free(tcptable); + tcptable = (MIB_TCPTABLE_OWNER_PID *) malloc(tcptablesize); + } + if (err != NO_ERROR) + { + syslog(LOG_ERR, "GetExtendedTcpTable fail: %d", err); + return -1; + } + + // Go looking for our client connection, so we can get its PID. + for (DWORD i = 0; i < tcptable->dwNumEntries; ++i) + { + MIB_TCPROW_OWNER_PID *j = &(tcptable->table[i]); + if ((j->dwState == MIB_TCP_STATE_ESTAB) + && (ntohs(j->dwRemotePort) == peercon.getLocalPort()) + && (ntohs(j->dwLocalPort) == peercon.getPeerSourcePort()) + && (j->dwRemoteAddr == inet_addr("127.0.0.1"))) + { + // Now look up the owner of this connection's owning PID + HANDLE process = OpenProcess(PROCESS_QUERY_INFORMATION, false, j->dwOwningPid); + if (process == NULL) + { + free(tcptable); + syslog(LOG_ERR, "OpenProcess fail"); + return -2; + } + HANDLE token; + if (OpenProcessToken(process, TOKEN_READ, &token) == 0) + { + free(tcptable); + CloseHandle(process); + syslog(LOG_ERR, "OpenProcessToken fail"); + return -3; + } + TOKEN_USER *tokenuser = NULL; + DWORD tokenusersize = 0; + while (GetTokenInformation(token, TokenUser, (LPVOID) tokenuser, tokenusersize, &tokenusersize) == 0) + { + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) + { + free(tcptable); + CloseHandle(token); + CloseHandle(process); + syslog(LOG_ERR, "GetTokenInformation fail"); + return -4; + } + free(tokenuser); + tokenuser = (TOKEN_USER *) malloc(tokenusersize); + } + char username[1024]; + char domain[1024]; + DWORD usernamesize = 1024; + DWORD domainsize = 1024; + SID_NAME_USE dummy; + if (LookupAccountSid(NULL, tokenuser->User.Sid, username, &usernamesize, domain, &domainsize, &dummy) == 0) + { + free(tokenuser); + free(tcptable); + CloseHandle(token); + CloseHandle(process); + syslog(LOG_ERR, "LookupAccountSid fail"); + return -5; + } + + free(tokenuser); + free(tcptable); + CloseHandle(token); + CloseHandle(process); + + string.assign(username); + return DGAUTH_OK; + } + } + + syslog(LOG_ERR, "No matching connection was found."); + free(tcptable); + return -6; +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |