--- /dev/null
+#ifndef SECURITY_DLL_DEFINITIONS
+#define SECURITY_DLL_DEFINITIONS
+
+/*****************************************************************************\
+* *
+* Name : security DLL helper *
+* Author : Chris Koeritz *
+* *
+* Purpose: *
+* *
+* Allows the security support to work within a DLL. *
+* *
+*******************************************************************************
+* Copyright (c) 2008-$now By Author. 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 is online at: *
+* http://www.fsf.org/copyleft/gpl.html *
+* Please send any updates to: fred@gruntose.com *
+\*****************************************************************************/
+
+#include "basis/build_configuration.h"
+
+// windows class tags for the data structures library:
+// define BUILD_SECURITY when you are creating the dll and
+// define USE_HOOPLE_DLLS when you are importing a class from the dll.
+#ifdef BUILD_SECURITY
+ #define HOOPLE_DLL_EXPORT_CLASS
+ #define HOOPLE_DLL_EXPORT_FUNCTION
+#elif defined(USE_HOOPLE_DLLS)
+ #define HOOPLE_DLL_IMPORT_CLASS
+ #define HOOPLE_DLL_IMPORT_FUNCTION
+#else
+ #define SECURITY_CLASS_STYLE
+ #define SECURITY_FUNCTION_STYLE
+#endif
+
+#endif
+
--- /dev/null
+CONSOLE_MODE = true
+
+include cpp/variables.def
+
+PROJECT = security
+TYPE = library
+ifeq "$(OP_SYSTEM)" "WIN32"
+ SOURCE = nt_security.cpp win32_security.cpp windows_firewall.cpp
+endif
+TARGETS = security.lib
+
+include cpp/rules.def
--- /dev/null
+
+
+
+/*****************************************************************************\
+* *
+* Name : nt_security *
+* Author : Sue Richeson *
+* Author : Chris Koeritz *
+* *
+*******************************************************************************
+* Copyright (c) 1999-$now By Author. 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 is online at: *
+* http://www.fsf.org/copyleft/gpl.html *
+* Please send any updates to: fred@gruntose.com *
+\*****************************************************************************/
+
+#ifdef __WIN32__
+
+#include "nt_security.h"
+#include "win32_security.h"
+
+#include <basis/astring.h>
+
+#include <lm.h>
+
+// LSA success status value.
+#ifndef STATUS_SUCCESS
+ #define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
+#endif
+
+nt_security::nt_security()
+: m_sDirServiceProvider(NIL)
+{
+ // Eventually, construction of nt_security should determine if WinNT://
+ // or LDAP://, etc is the service provider and set a private member variable
+ // with the appropriate distinguished name qualifier.
+ m_sDirServiceProvider = new astring("WinNT://");
+}
+//---------------------------------------------------------------------------
+
+
+nt_security::~nt_security()
+{
+ if (m_sDirServiceProvider)
+ delete m_sDirServiceProvider;
+}
+
+
+//---------------------------------------------------------------------------
+
+bool nt_security::iequalsUsername(astring name1, astring name2)
+{
+ return normalizeUsername(name1) == normalizeUsername(name2);
+}
+
+const astring &nt_security::normalizeUsername(astring &username)
+{
+ username.replace_all('/', '\\');
+ username.replace_all('|', ':');
+ username.to_lower();
+ return username;
+}
+
+ //---------------------------------------------------------------------------
+
+astring nt_security::DomainBinding(const astring &domain)
+{
+ astring tempstring = *m_sDirServiceProvider + domain;
+ return (tempstring);
+}
+//---------------------------------------------------------------------------
+
+
+astring nt_security::DomainUserBinding(const astring &domain, const astring &user_name)
+{
+ astring tempstring = *m_sDirServiceProvider + domain + astring("/") + user_name;
+ return (tempstring);
+}
+//---------------------------------------------------------------------------
+
+// This piece of code is borrowed from the following July 1999 MSDN article
+// HOWTO: Look Up Current User Name and Domain Name
+// ID: Q155698
+//NOTE: It has been modified for inclusion in this class and it is NT-specific.
+
+bool nt_security::GetUserAndDomainName(astring &UserName, astring &DomainName)
+{
+ return win32_security::GetUserAndDomainName(UserName, DomainName);
+}
+
+
+//---------------------------------------------------------------------------
+// The following routines were taken from the lsapriv sample application by
+// Scott Field on the MSDN January 2001.
+//---------------------------------------------------------------------------
+
+/*---------------------------------------------------------------------------
+This function attempts to obtain a SID representing the supplied
+account on the supplied system.
+
+If the function succeeds, the return value is the SID. A buffer is
+allocated which contains the SID representing the supplied account.
+This buffer should be freed when it is no longer needed by calling
+HeapFree(GetProcessHeap(), 0, buffer)
+
+If the function fails, the return SID is NULL.
+
+Scott Field (sfield) 12-Jul-95
+Sue Richeson 27-FEB-2001 Mods for use in LightLink.
+Chris Koeritz 02-JAN-2008 changed some more for use within hoople.
+---------------------------------------------------------------------------*/
+
+PSID nt_security::GetUserSID(const astring &user_name)
+{
+ PSID psid = NULL;
+ char * ReferencedDomain = NULL;
+ DWORD cbSid = 128; // initial allocation attempt
+ DWORD cchReferencedDomain = 16; // initial allocation size
+ SID_NAME_USE peUse;
+ bool bSuccess = false;
+
+ try
+ { //
+ // initial memory allocations
+ //
+ psid = (PSID)HeapAlloc(GetProcessHeap(), 0, cbSid);
+ if (psid != NULL)
+ {
+ ReferencedDomain = (char *)HeapAlloc(GetProcessHeap(), 0, cchReferencedDomain * sizeof(TCHAR));
+ if (ReferencedDomain != NULL)
+ {
+ // Obtain the SID of the specified account on the specified system.
+ //
+ bSuccess = true;
+ while (!LookupAccountName(NULL, // machine to lookup account on
+ to_unicode_temp(user_name), // account to lookup
+ psid, // SID of interest
+ &cbSid, // size of SID
+ to_unicode_temp(ReferencedDomain), // domain where found.
+ &cchReferencedDomain,
+ &peUse))
+ {
+ if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+ {
+ // reallocate memory
+ //
+ psid = (PSID)HeapReAlloc(GetProcessHeap(), 0, psid, cbSid);
+ if(psid != NULL)
+ {
+ ReferencedDomain = (char *)HeapReAlloc(GetProcessHeap(), 0,
+ ReferencedDomain,
+ cchReferencedDomain * sizeof(TCHAR));
+ if (ReferencedDomain == NULL)
+ {
+ break;
+ bSuccess = false;
+ }
+ }
+ else
+ {
+ break;
+ bSuccess = false;
+ }
+ }
+ else
+ {
+ break;
+ bSuccess = false;
+ }
+ } // end while
+ } // if ReferencedDomain
+ } // if psid
+ }
+ catch(...)
+ {
+ bSuccess = false;
+ }
+
+ // Cleanup and indicate failure, if appropriate.
+ //
+ if (ReferencedDomain != NULL)
+ HeapFree(GetProcessHeap(), 0, ReferencedDomain);
+
+ if (!bSuccess)
+ {
+ if (psid != NULL)
+ {
+ HeapFree(GetProcessHeap(), 0, psid);
+ psid = NULL;
+ }
+ }
+
+ return psid;
+}
+//---------------------------------------------------------------------------
+
+
+DWORD nt_security::OpenPolicy(const astring &serverName, DWORD DesiredAccess, PLSA_HANDLE pPolicyHandle)
+{
+ LSA_OBJECT_ATTRIBUTES ObjectAttributes;
+ NTSTATUS Status;
+ DWORD winerror = 0;
+
+ // Always initialize the object attributes to all zeroes.
+ //
+ ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
+
+ transcode_to_utf16 temp_server(serverName);
+ LSA_UNICODE_STRING server;
+ server.Buffer = (PWSTR)(UTF16 *)temp_server;
+ server.Length = serverName.length() * (int)sizeof(UTF16);
+ server.MaximumLength = (serverName.length() +1) * (int)sizeof(UTF16);
+
+ // Attempt to open the policy.
+ Status = LsaOpenPolicy(&server, &ObjectAttributes, DesiredAccess, pPolicyHandle);
+ if (STATUS_SUCCESS != Status)
+ {
+ winerror = LsaNtStatusToWinError(Status);
+ ClosePolicy(pPolicyHandle);
+ return winerror;
+ }
+ else
+ return winerror;
+}
+//---------------------------------------------------------------------------
+
+
+void nt_security::ClosePolicy(PLSA_HANDLE policyHandle)
+{
+ if (policyHandle != NULL)
+ LsaClose(policyHandle);
+}
+//---------------------------------------------------------------------------
+
+
+/*
+void nt_security::InitLsaString(LPWSTR inString, PLSA_UNICODE_STRING LsaString)
+{
+ DWORD StringLength;
+
+ if (inString == NULL)
+ {
+ LsaString->Buffer = NULL;
+ LsaString->Length = 0;
+ LsaString->MaximumLength = 0;
+ return;
+ }
+
+ StringLength = wcslen(inString);
+ LsaString->Buffer = inString;
+ LsaString->Length = (USHORT) StringLength * sizeof(WCHAR);
+ LsaString->MaximumLength=(USHORT)(StringLength+1) * sizeof(WCHAR);
+}
+*/
+//---------------------------------------------------------------------------
+
+
+DWORD nt_security::SetPrivilegeOnAccount(LSA_HANDLE PolicyHandle, // open policy handle
+ PSID AccountSid, // SID to grant privilege to
+ const astring &PrivilegeName, // privilege to grant (Unicode)
+ bool bEnable) // enable or disable
+{
+ NTSTATUS Status;
+ DWORD winerror = 0;
+
+ // Create a LSA_UNICODE_STRING for the privilege name.
+ //
+ transcode_to_utf16 temp_priv(PrivilegeName);
+ LSA_UNICODE_STRING privs;
+ privs.Buffer = (PWSTR)(UTF16 *)temp_priv;
+ privs.Length = PrivilegeName.length() * (int)sizeof(UTF16);
+ privs.MaximumLength = (PrivilegeName.length() +1) * (int)sizeof(UTF16);
+
+ // grant or revoke the privilege, accordingly
+ //
+ if (bEnable)
+ {
+ Status = LsaAddAccountRights(PolicyHandle, // open policy handle
+ AccountSid, // target SID
+ &privs, // privileges
+ 1); // privilege count
+ }
+ else
+ {
+ Status = LsaRemoveAccountRights(PolicyHandle, // open policy handle
+ AccountSid, // target SID
+ FALSE, // do not disable all rights
+ &privs, // privileges
+ 1); // privilege count
+ }
+
+ if (Status == STATUS_SUCCESS)
+ return winerror;
+ else
+ {
+ winerror = LsaNtStatusToWinError(Status);
+ return winerror;
+ }
+}
+//---------------------------------------------------------------------------
+
+
+DWORD nt_security::SetPrivilegeOnUser(const astring &domain,
+ const astring &user,
+ const astring &privilege,
+ bool bEnable)
+{
+ LSA_HANDLE policyHandle;
+ PSID psid = NULL;
+ DWORD winerror = 0;
+
+ // Open the policy on the target machine.
+ //
+ winerror = OpenPolicy(domain, (POLICY_CREATE_ACCOUNT | POLICY_LOOKUP_NAMES), &policyHandle);
+ if (winerror != 0)
+ return winerror;
+
+ // Obtain the SID of the user/group.
+ // Note that we could target a specific machine, but we don't.
+ // Specifying NULL for target machine searches for the SID in the
+ // following order: well-known, Built-in and local, primary domain,
+ // trusted domains.
+ //
+ psid = GetUserSID(user);
+ if (psid == NULL)
+ {
+ ClosePolicy(&policyHandle);
+ return ERROR_NO_SUCH_USER;
+ }
+
+ // Grant the SeServiceLogonRight to users represented by psid.
+ //
+ winerror = SetPrivilegeOnAccount(policyHandle, psid, privilege, bEnable);
+
+ // Close the policy handle.
+ //
+ ClosePolicy(&policyHandle);
+
+ //
+ // Free memory allocated for SID.
+ //
+ if (psid != NULL)
+ HeapFree(GetProcessHeap(), 0, psid);
+
+ return winerror;
+}
+
+DWORD nt_security::AddUserToGroup(const astring &user_name, const astring &group_name)
+{
+ LOCALGROUP_MEMBERS_INFO_3 lgmi3;
+ DWORD dwLevel = 3;
+ DWORD totalEntries = 1;
+ NET_API_STATUS nStatus;
+
+// fwprintf(stderr, L"Usage: %s ServerName GroupName MemberAccountName-(DomainName\\AccountName)\n", argv[0]);
+
+ // Set up the LOCALGROUP_MEMBERS_INFO_3 structure.
+ // Assign the member account name in form of DomainName\AccountName
+ transcode_to_utf16 temp_user(user_name);
+ lgmi3.lgrmi3_domainandname = (LPWSTR)(UTF16 *)temp_user;
+
+ // Call the NetLocalGroupAddMembers() function, specifying level 3.
+ // Level 0 can use SID
+ transcode_to_utf16 temp_group(group_name);
+ nStatus = NetLocalGroupAddMembers(L"", (LPWSTR)(UTF16 *)temp_group, dwLevel,
+ (LPBYTE)&lgmi3, totalEntries);
+
+//printf("got error code %d\n" , nStatus);
+
+ if (nStatus == ERROR_MEMBER_IN_ALIAS) nStatus = 0; // not an error.
+
+ return nStatus;
+}
+
+#endif //win32
+
+
+
--- /dev/null
+#ifndef NT_SECURITY_CLASS
+#define NT_SECURITY_CLASS
+
+/*****************************************************************************\
+* *
+* Name : nt_security *
+* Author : Sue Richeson *
+* Author : Chris Koeritz *
+* *
+* Purpose: *
+* *
+* Provides a Win32 oracle for security questions. *
+* *
+*******************************************************************************
+* Copyright (c) 1999-$now By Author. 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 is online at: *
+* http://www.fsf.org/copyleft/gpl.html *
+* Please send any updates to: fred@gruntose.com *
+\*****************************************************************************/
+
+#ifdef __WIN32__
+
+
+
+#include <basis/utf_conversion.h>
+
+
+#include <Ntsecapi.h>
+
+// Forward class declarations
+#include <basis/astring.h>
+
+class nt_security
+{
+public:
+ nt_security();
+ virtual ~nt_security();
+
+ static bool iequalsUsername(astring name1, astring name2);
+ // Compares the two names for equality. Treats backslash (\) and
+ // forward slash (/} as equal. Ignores case. Treats the pipe (|) and
+ // colon (:) as equal.
+
+ static const astring &normalizeUsername(astring &username);
+ // Makes the username all lowercase, converts any forward slash (/)
+ // characters to back slashes (\), and converts any pipe characters (|)
+ // to colon (:) characters.
+
+ bool GetUserAndDomainName(astring &UserName, astring &DomainName);
+ // This function is NT-specific. It returns the user account name and
+ // domain name of the currently logged in user on the machine on which
+ // this class is executing.
+
+ astring DomainBinding(const astring &domain);
+ // This method will constsruct a distinguished name for the domain received.
+ astring DomainUserBinding(const astring &domain, const astring &user_name);
+ // This method will construct a distinguished name based on the domain and
+ // user name received.
+
+ DWORD SetPrivilegeOnUser(const astring &domain, const astring &user,
+ const astring &privilege, bool bEnable);
+ // Sets or disables the privilege for the user in the given domain.
+ // Can also be used to set the privilege on a group in the given domain.
+ // Returns 0 if successful. Returns Win32 error code if it fails.
+ // Domain - can be blank, in which case the local machine is assumed; can be a machine
+ // name or a network domain name (although, having privilege to change a
+ // priv in a network domain is highly unlikely and will probably result in
+ // failure, false, return of this method). Ex: "Legolas", "Buildotron"
+ // User - the account name for which to change the privilege. It can include the
+ // domain also. Example user names: "Fred", "Legolas/Bubba", "Buildotron/swbuld"
+ // Can also be a group name. Examples: "Administrators", "Legolas/Users"
+ // privilege - name of the privilege to be enable/disabled.
+ // For a list of privilges, consult winnt.h, and search for SE_ASSIGNPRIMARYTOKEN_NAME.
+ // For a list of logon rights consult ntsecapi.h, and search for SE_BATCH_LOGON_NAME.
+ // bEnable - true to enable the privilege; false to disable the privilege
+
+ DWORD AddUserToGroup(const astring &user_name, const astring &group_name);
+ // adds the "user_name" to the local group "group_name". this only makes
+ // the change on the local machine where this is run.
+
+protected:
+
+ PSID GetUserSID(const astring &user_name);
+ // Retrieves the security descriptor (SID) for "user_name".
+ // PSID is NULL if the method fails.
+
+ DWORD OpenPolicy(const astring &serverName, DWORD DesiredAccess,
+ PLSA_HANDLE pPolicyHandle);
+ // Open the LSA policy on the given machine.
+ // Returns 0 if successful. Returns Win32 error code if it fails.
+
+ void ClosePolicy(PLSA_HANDLE policyHandle);
+ // Close the given LSA policy handle.
+
+ DWORD SetPrivilegeOnAccount(LSA_HANDLE PolicyHandle, // open policy handle
+ PSID AccountSid, // SID to grant privilege to
+ const astring &PrivilegeName, // privilege to grant
+ bool bEnable); // enable or disable
+ // Enable or disable the stated privilege on the given account.
+ // Returns 0 if successful. Returns Win32 error code if it fails.
+ // PolicyHandle - must already have been opened prior to calling this method.
+ // AccountSid - must already have been obtained prior to calling this method.
+ // PrivilegeName - must be a valid security privilege name (case sensitive)
+ // For a list of privilges, consult winnt.h, and search for SE_ASSIGNPRIMARYTOKEN_NAME.
+ // For a list of logon rights consult ntsecapi.h, and search for SE_BATCH_LOGON_NAME.
+ // bEnable - true to enable the privilege; false to disable the privilege
+
+private:
+ astring *m_sDirServiceProvider; //!< the directory service provider name.
+};
+
+#endif
+
+#endif
+
--- /dev/null
+
+
+
+
+#include "nt_security.cpp"
+#include "win32_security.cpp"
+#include "windows_firewall.cpp"
+
+
+
+
--- /dev/null
+
+
+
+/*****************************************************************************\
+* *
+* Name : win32_security *
+* Author : Sue Richeson *
+* Author : Chris Koeritz *
+* *
+*******************************************************************************
+* Copyright (c) 2000-$now By Author. 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 is online at: *
+* http://www.fsf.org/copyleft/gpl.html *
+* Please send any updates to: fred@gruntose.com *
+\*****************************************************************************/
+
+#ifdef __WIN32__
+
+#include "win32_security.h"
+
+#include <basis/utf_conversion.h>
+#include <basis/astring.h>
+
+#include <comdef.h>
+#include <lm.h>
+
+// This piece of code is borrowed from the following July 1999 MSDN article
+// HOWTO: Look Up Current User Name and Domain Name, ID: Q155698
+//NOTE: It has been modified for inclusion here and it is Win32-specific.
+
+bool win32_security::GetUserAndDomainName(astring &UserName, astring &DomainName)
+{
+ HANDLE hToken;
+
+ // Initialize the return parameters.
+ UserName = "";
+ DomainName = "";
+
+ #define MY_BUFSIZE 512 // highly unlikely to exceed 512 bytes
+ UCHAR InfoBuffer[ MY_BUFSIZE + 1 ];
+ DWORD cbInfoBuffer = MY_BUFSIZE;
+ SID_NAME_USE snu;
+
+ BOOL bSuccess;
+
+ if(!OpenThreadToken(
+ GetCurrentThread(),
+ TOKEN_QUERY,
+ TRUE,
+ &hToken
+ )) {
+
+ if(GetLastError() == ERROR_NO_TOKEN) {
+
+ //
+ // attempt to open the process token, since no thread token
+ // exists
+ //
+
+ if(!OpenProcessToken(
+ GetCurrentProcess(),
+ TOKEN_QUERY,
+ &hToken
+ )) return FALSE;
+
+ } else {
+
+ //
+ // error trying to get thread token
+ //
+
+ return FALSE;
+ }
+ }
+
+ bSuccess = GetTokenInformation( hToken,
+ TokenUser,
+ InfoBuffer,
+ cbInfoBuffer,
+ &cbInfoBuffer);
+
+ if(!bSuccess) {
+ if(GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+
+ //
+ // alloc buffer and try GetTokenInformation() again
+ //
+
+ CloseHandle(hToken);
+ return FALSE;
+
+ } else {
+
+ //
+ // error getting token info
+ //
+
+ CloseHandle(hToken);
+ return FALSE;
+ }
+ }
+
+ CloseHandle(hToken);
+
+ TCHAR User[MY_BUFSIZE + 1];;
+ DWORD cchUserName = MY_BUFSIZE;
+ TCHAR Domain[MY_BUFSIZE + 1];
+ DWORD cchDomainName = MY_BUFSIZE;
+
+ bSuccess = LookupAccountSid(NULL,
+ ((PTOKEN_USER)InfoBuffer)->User.Sid,
+ User,
+ &cchUserName,
+ Domain,
+ &cchDomainName,
+ &snu);
+
+ if (bSuccess)
+ {
+ UserName = from_unicode_temp(User);
+ DomainName = from_unicode_temp(Domain);
+ }
+
+ return bSuccess;
+}
+
+astring win32_security::full_user()
+{
+ astring user, temp_domain;
+ GetUserAndDomainName(user, temp_domain);
+ user += astring("[") + temp_domain + "]";
+ return user;
+}
+
+#endif // windows.
+
+
+
+
--- /dev/null
+#ifndef WIN32_SECURITY_CLASS
+#define WIN32_SECURITY_CLASS
+
+/*****************************************************************************\
+* *
+* Name : win32_security *
+* Author : Sue Richeson *
+* Author : Chris Koeritz *
+* *
+* Purpose: *
+* *
+* Some helper functions for security calls. These are lower level than *
+* nt_security and only require bare OS calls. *
+* *
+*******************************************************************************
+* Copyright (c) 2000 By Author. 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 is online at: *
+* http://www.fsf.org/copyleft/gpl.html *
+* Please send any updates to: fred@gruntose.com *
+\*****************************************************************************/
+
+#ifdef __WIN32__
+
+
+
+// forward.
+#include <basis/astring.h>
+
+class win32_security
+{
+public:
+ static bool GetUserAndDomainName(astring &UserName, astring &DomainName);
+ //!< returns user account and windows domain of logged in user.
+
+ static astring full_user();
+ //!< returns user and domain combined into a parsable form: user[domain]
+};
+
+#endif // windows.
+
+#endif // outer guard.
+
--- /dev/null
+/*****************************************************************************\
+* *
+* Name : windows firewall wrapper *
+* Author : Chris Koeritz *
+* *
+*******************************************************************************
+* Copyright (c) 2009-$now By Author. 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 is online at: *
+* http://www.fsf.org/copyleft/gpl.html *
+* Please send any updates to: fred@gruntose.com *
+\*****************************************************************************/
+
+#include "windows_firewall.h"
+
+
+#include <basis/functions.h>
+
+using namespace portable;
+
+// so far this is a good assumption about where to find netsh.
+astring netsh_app() { return env_string("WINDIR") + "/System32/netsh.exe"; }
+
+int windows_firewall::poke_firewall_hole(const astring &program_name,
+ const astring &exception_name, const astring &hole_description)
+{
+ astring cmdline;
+#ifdef __WIN32__
+ known_operating_systems kind = determine_OS();
+ if ( (kind == WIN_SRV2K8) || (kind == WIN_VISTA) ) {
+ // newer style firewall with advfirewall.
+//::MessageBox(0, "poke app srv2k8", "yodel", MB_OK);
+ cmdline = a_sprintf("-c advfirewall firewall add rule name=\"%s\" dir=in "
+ "action=allow program=\"%s\" enable=yes profile=any "
+ "description=\"%s\"", exception_name.s(), program_name.s(),
+ hole_description.s());
+ } else {
+ // older xp style firewall (if that).
+//::MessageBox(0, "poke app xp", "yodel", MB_OK);
+ cmdline = a_sprintf("-c firewall add allowedprogram program=\"%s\" "
+ "name=\"%s\" mode=enable scope=all profile=all", program_name.s(),
+ exception_name.s());
+ }
+
+ basis::u_int kid_id;
+ basis::u_int to_return = launch_process::run(netsh_app(), cmdline,
+ portable::AWAIT_APP_EXIT | portable::HIDE_APP_WINDOW
+ | portable::SHELL_EXECUTE, kid_id);
+ return to_return;
+#else
+ if (!program_name || !exception_name || !hole_description) {} // no problem.
+ return 1; // failure on this platform.
+#endif
+}
+
+int windows_firewall::remove_firewall_hole(const astring &program_name,
+ const astring &exception_name)
+{
+#ifdef __WIN32__
+ astring cmdline;
+
+ known_operating_systems kind = determine_OS();
+ if ( (kind == WIN_SRV2K8) || (kind == WIN_VISTA) ) {
+//::MessageBox(0, "removing app srv2k8", "yodel", MB_OK);
+ // newer style firewall with advfirewall.
+ cmdline = a_sprintf("-c advfirewall firewall delete rule name=\"%s\" ",
+ exception_name.s());
+ } else {
+//::MessageBox(0, "removing app xp", "yodel", MB_OK);
+ // older xp style firewall (if that).
+ cmdline = a_sprintf("-c firewall delete allowedprogram program=\"%s\" "
+ "profile=all", program_name.s());
+ }
+
+ basis::u_int kid_id;
+ basis::u_int to_return = launch_process::run(netsh_app(), cmdline,
+ portable::AWAIT_APP_EXIT | portable::HIDE_APP_WINDOW
+ | portable::SHELL_EXECUTE, kid_id);
+ return to_return;
+#else
+ if (!program_name || !exception_name) {} // no problem.
+ return 1; // failure on this platform.
+#endif
+}
+
+int windows_firewall::poke_firewall_hole(int port_number,
+ const astring &exception_name, const astring &hole_description,
+ const astring &protocol)
+{
+#ifdef __WIN32__
+ astring cmdline;
+
+ known_operating_systems kind = determine_OS();
+ if ( (kind == WIN_SRV2K8) || (kind == WIN_VISTA) ) {
+ // newer style firewall with advfirewall.
+//::MessageBox(0, "poke port srv2k8", "yodel", MB_OK);
+ cmdline = a_sprintf("-c advfirewall firewall add rule name=\"%s\" dir=in "
+ "action=allow protocol=\"%s\" enable=yes profile=any "
+ "description=\"%s\" localport=%d",
+ exception_name.s(), protocol.s(), hole_description.s(), port_number);
+ } else {
+ // older xp style firewall (if that).
+//::MessageBox(0, "poke port xp", "yodel", MB_OK);
+ cmdline = a_sprintf("-c firewall add portopening port=%d "
+ "name=\"%s\" protocol=%s mode=enable scope=all profile=all",
+ port_number, exception_name.s(), protocol.s());
+ }
+
+ basis::u_int kid_id;
+ basis::u_int to_return = launch_process::run(netsh_app(), cmdline,
+ portable::AWAIT_APP_EXIT | portable::HIDE_APP_WINDOW
+ | portable::SHELL_EXECUTE, kid_id);
+ return to_return;
+#else
+ if (!port_number || !exception_name || !protocol || !hole_description) {} // no problem.
+ return 1; // failure on this platform.
+#endif
+}
+
+int windows_firewall::remove_firewall_hole(int port_number,
+ const astring &exception_name, const astring &protocol)
+{
+#ifdef __WIN32__
+ astring cmdline;
+
+ known_operating_systems kind = determine_OS();
+ if ( (kind == WIN_SRV2K8) || (kind == WIN_VISTA) ) {
+//::MessageBox(0, "removing port srv2k8", "yodel", MB_OK);
+ // newer style firewall with advfirewall.
+ cmdline = a_sprintf("-c advfirewall firewall delete rule name=\"%s\" "
+ "localport=%d protocol=%s", exception_name.s(),
+ port_number, protocol.s());
+ } else {
+//::MessageBox(0, "removing port xp", "yodel", MB_OK);
+ // older xp style firewall (if that).
+ cmdline = a_sprintf("-c firewall delete portopening protocol=%s "
+ "port=%d profile=all", protocol.s(), port_number);
+ }
+
+ basis::u_int kid_id;
+ basis::u_int to_return = launch_process::run(netsh_app(), cmdline,
+ portable::AWAIT_APP_EXIT | portable::HIDE_APP_WINDOW
+ | portable::SHELL_EXECUTE, kid_id);
+ return to_return;
+#else
+ if (!port_number || !exception_name || !protocol) {} // no problem.
+ return 1; // failure on this platform.
+#endif
+}
+
--- /dev/null
+#ifndef WINDOWS_FIREWALL_CLASS
+#define WINDOWS_FIREWALL_CLASS
+
+/*****************************************************************************\
+* *
+* Name : windows firewall wrapper *
+* Author : Chris Koeritz *
+* *
+*******************************************************************************
+* Copyright (c) 2009-$now By Author. 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 is online at: *
+* http://www.fsf.org/copyleft/gpl.html *
+* Please send any updates to: fred@gruntose.com *
+\*****************************************************************************/
+
+
+
+#include <basis/astring.h>
+
+class windows_firewall
+{
+public:
+ // adds a firewall hole for an executable called "program_name" (which should
+ // be the full path) using a rule called "exception_name". the description
+ // for the firewall exception should be in "hole_description" (and it's only
+ // used on vista or server 2008 or later).
+ // in this and the other methods, a zero return indicates success. any other
+ // return indicates a failure.
+ static int poke_firewall_hole(const astring &program_name,
+ const astring &exception_name, const astring &hole_description);
+
+ // this version will open an exception for a port rather than a program.
+ static int poke_firewall_hole(int port_number,
+ const astring &exception_name, const astring &hole_description,
+ const astring &protocol);
+
+ // removes a previously poked firewall hole for an application.
+ static int remove_firewall_hole(const astring &program_name,
+ const astring &exception_name);
+
+ // removes a previously poked exception for a port.
+ static int remove_firewall_hole(int port_number,
+ const astring &exception_name, const astring &protocol);
+};
+
+#endif //outer guard
+
TYPE = application
TARGETS = create_guid.exe playsound.exe short_path.exe sleep_ms.exe \
zap_process.exe
+#run_as_service.exe
ifeq "$(OMIT_VERSIONS)" ""
SOURCE += simple_utils_version.rc
endif
--- /dev/null
+/*****************************************************************************\
+* *
+* Name : run_as_service *
+* Author : Chris Koeritz *
+* *
+*******************************************************************************
+* Copyright (c) 2000-$now By Author. 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 is online at: *
+* http://www.fsf.org/copyleft/gpl.html *
+* Please send any updates to: fred@gruntose.com *
+\*****************************************************************************/
+
+#include <loggers/console_logger.h>
+#include <filesystem/filename.h>
+#include <structures/static_memory_gremlin.h>
+#include <security/nt_security.h>
+
+HOOPLE_STARTUP_CODE;
+
+//////////////
+
+bool run_as_service(char *user, log_base &out)
+{
+#ifdef __WIN32__
+ // ensure that the user has the "logon as a service" right.
+ nt_security secu;
+ long err = secu.SetPrivilegeOnUser("", user, "SeServiceLogonRight", true);
+ if (err) {
+ // that didn't work; probably the user name is bad?
+ out.log(astring(astring::SPRINTF, "There was a problem giving "
+ "\"%s\" the \"Logon as a Service\" right:\r\n%s", user,
+ critical_events::system_error_text(err).s()));
+ return false;
+ }
+#else
+ astring junk = user;
+ out.eol();
+ junk += "";
+#endif
+ return true;
+}
+
+int main(int argc, char *argv[])
+{
+ console_logger out;
+ if (argc < 2) {
+ out.log(filename(argv[0]).rootname() + " usage:\n\
+The first parameter must be a user name that will be given the\n\
+\"login as a service\" access rights.\n");
+ return 1;
+ }
+ bool did_it = run_as_service(argv[1], out);
+ if (did_it)
+ out.log(astring("Success giving \"") + argv[1] + "\" the 'login as service' rights.");
+ else
+ out.log(astring("Failed in giving \"") + argv[1] + "\" the 'login as service' rights!");
+ return !did_it;
+}
+
+#ifdef __BUILD_STATIC_APPLICATION__
+ // static dependencies found by buildor_gen_deps.sh:
+ #include <basis/byte_array.cpp>
+ #include <basis/callstack_tracker.cpp>
+ #include <basis/utf_conversion.cpp>
+ #include <basis/definitions.cpp>
+ #include <basis/earth_time.cpp>
+ #include <basis/guards.cpp>
+ #include <basis/astring.cpp>
+ #include <basis/log_base.cpp>
+ #include <basis/memory_checker.cpp>
+ #include <basis/mutex.cpp>
+ #include <basis/contracts.h>
+ #include <basis/outcome.cpp>
+ #include <basis/packable.cpp>
+ #include <basis/portable.cpp>
+ #include <basis/trap_new.addin>
+ #include <basis/untrap_new.addin>
+ #include <basis/utility.cpp>
+ #include <basis/version_record.cpp>
+ #include <structures/bit_vector.cpp>
+ #include <structures/byte_hasher.cpp>
+ #include <structures/configurator.cpp>
+ #include <structures/hash_table.h>
+ #include <structures/pointer_hash.h>
+ #include <structures/stack.h>
+ #include <structures/static_memory_gremlin.cpp>
+ #include <structures/string_hash.h>
+ #include <structures/string_hasher.cpp>
+ #include <structures/string_table.cpp>
+ #include <structures/symbol_table.h>
+ #include <structures/table_configurator.cpp>
+ #include <loggers/console_logger.cpp>
+ #include <loggers/file_logger.cpp>
+ #include <loggers/locked_logger.cpp>
+ #include <loggers/null_logger.cpp>
+ #include <loggers/program_wide_logger.cpp>
+ #include <filesystem/byte_filer.cpp>
+ #include <application/command_line.cpp>
+ #include <opsystem/critical_events.cpp>
+ #include <filesystem/directory.cpp>
+ #include <filesystem/filename.cpp>
+ #include <configuration/ini_configurator.cpp>
+ #include <opsystem/ini_parser.cpp>
+ #include <configuration/application_configuration.cpp>
+ #include <application/rendezvous.cpp>
+ #include <security/nt_security.cpp>
+ #include <security/win32_security.cpp>
+ #include <textual/byte_formatter.cpp>
+ #include <textual/parser_bits.cpp>
+ #include <textual/string_manipulation.cpp>
+ #include <configuration/variable_tokenizer.cpp>
+#endif // __BUILD_STATIC_APPLICATION__
+