Server : Apache/2.4.43 (Win64) OpenSSL/1.1.1g PHP/7.4.6 System : Windows NT USER-PC 6.1 build 7601 (Windows 7 Professional Edition Service Pack 1) AMD64 User : User ( 0) PHP Version : 7.4.6 Disable Function : NONE Directory : C:/xampp/FileZillaFTP/source/ |
#include "stdafx.h" #include "accounts.h" #include "iputils.h" t_directory::t_directory() { bAutoCreate = FALSE; } t_group::t_group() { pOwner = NULL; for (int i = 0; i < 2; i++) { nSpeedLimitType[i] = 0; nSpeedLimit[i] = 10; nBypassServerSpeedLimit[i] = 0; } nEnabled = 1; forceSsl = 0; } t_group& t_group::operator=(const t_group &a) { group = a.group; nBypassUserLimit = a.nBypassUserLimit; nUserLimit = a.nUserLimit; nIpLimit = a.nIpLimit; permissions = a.permissions; nEnabled = a.nEnabled; disallowedIPs = a.disallowedIPs; allowedIPs = a.allowedIPs; comment = a.comment; forceSsl = a.forceSsl; for (int i = 0; i < 2; i++) { nBypassServerSpeedLimit[i] = a.nBypassServerSpeedLimit[i]; nSpeedLimit[i] = a.nSpeedLimit[i]; nSpeedLimitType[i] = a.nSpeedLimitType[i]; SpeedLimits[i] = a.SpeedLimits[i]; } return *this; } bool t_group::BypassUserLimit() const { if (!nBypassUserLimit) return false; if (nBypassUserLimit == 2 && pOwner) return pOwner->BypassUserLimit(); return true; } int t_group::GetIpLimit() const { if (nIpLimit) return nIpLimit; if (pOwner) return pOwner->GetIpLimit(); return 0; } int t_group::GetUserLimit() const { if (nUserLimit) return nUserLimit; if (pOwner) return pOwner->GetUserLimit(); return 0; } t_user::t_user() { } t_user& t_user::operator=(const t_user &a) { group = a.group; pOwner = a.pOwner; user=a.user; password=a.password; nBypassUserLimit = a.nBypassUserLimit; nUserLimit = a.nUserLimit; nIpLimit = a.nIpLimit; permissions = a.permissions; nEnabled = a.nEnabled; disallowedIPs = a.disallowedIPs; allowedIPs = a.allowedIPs; comment = a.comment; forceSsl = a.forceSsl; for (int i = 0; i < 2; i++) { nBypassServerSpeedLimit[i] = a.nBypassServerSpeedLimit[i]; nSpeedLimit[i] = a.nSpeedLimit[i]; nSpeedLimitType[i] = a.nSpeedLimitType[i]; SpeedLimits[i] = a.SpeedLimits[i]; } return *this; } unsigned char * t_group::ParseBuffer(unsigned char *pBuffer, int length) { unsigned char *p = pBuffer; unsigned char *endMarker = pBuffer + length; if (!ParseString(endMarker, p, group)) return 0; if ((endMarker - p) < 11) return NULL; memcpy(&nIpLimit, p, 4); p += 4; memcpy(&nUserLimit, p, 4); p += 4; int options = *p++; nBypassUserLimit = options & 0x03; nEnabled = (options >> 2) & 0x03; // Parse IP filter rules. int numDisallowedIPs = (int(*p) << 8) + p[1]; p += 2; while (numDisallowedIPs--) { CStdString ip; if (!ParseString(endMarker, p, ip)) return 0; if (IsValidAddressFilter(ip) || ip == _T("*")) disallowedIPs.push_back(ip); } if ((endMarker - p) < 2) return NULL; int numAllowedIPs = (int(*p) << 8) + p[1]; p += 2; while (numAllowedIPs--) { CStdString ip; if (!ParseString(endMarker, p, ip)) return 0; if (IsValidAddressFilter(ip) || ip == _T("*")) allowedIPs.push_back(ip); } if ((endMarker - p) < 2) return NULL; int dircount = (int(*p) << 8) + p[1]; p += 2; BOOL bGotHome = FALSE; for (int j = 0; j < dircount; j++) { t_directory dir; CStdString str; if (!ParseString(endMarker, p, str)) return 0; str.TrimRight(_T("\\")); if (str == _T("")) return 0; dir.dir = str; // Get directory aliases. if ((endMarker - p) < 2) return NULL; int aliascount = (int(*p) << 8) + p[1]; p += 2; for (int i = 0; i < aliascount; i++) { CStdString alias; if (!ParseString(endMarker, p, alias)) return 0; alias.TrimRight(_T("\\")); if (alias == _T("")) return 0; dir.aliases.push_back(alias); } if ((endMarker - p) < 2) return NULL; int rights = (int(*p) << 8) + p[1]; p += 2; dir.bDirCreate = rights & 0x0001 ? 1:0; dir.bDirDelete = rights & 0x0002 ? 1:0; dir.bDirList = rights & 0x0004 ? 1:0; dir.bDirSubdirs = rights & 0x0008 ? 1:0; dir.bFileAppend = rights & 0x0010 ? 1:0; dir.bFileDelete = rights & 0x0020 ? 1:0; dir.bFileRead = rights & 0x0040 ? 1:0; dir.bFileWrite = rights & 0x0080 ? 1:0; dir.bIsHome = rights & 0x0100 ? 1:0; dir.bAutoCreate = rights & 0x0200 ? 1:0; // Avoid multiple home directories. if (dir.bIsHome) if (!bGotHome) bGotHome = TRUE; else dir.bIsHome = FALSE; permissions.push_back(dir); } for (int i = 0; i < 2; i++) { if ((endMarker - p) < 5) return NULL; nSpeedLimitType[i] = *p & 3; nBypassServerSpeedLimit[i] = (*p++ >> 2) & 3; nSpeedLimit[i] = int(*p++) << 8; nSpeedLimit[i] |= *p++; if (!nSpeedLimit[i]) nSpeedLimit[i] = 10; int num = (int(*p) << 8) + p[1]; p += 2; while (num--) { CSpeedLimit sl; p = sl.ParseBuffer(p, length-(int)(p-pBuffer)); if (!p) return NULL; SpeedLimits[i].push_back(sl); } } if (!ParseString(endMarker, p, comment)) return 0; if (p >= endMarker) return 0; forceSsl = *p++; return p; } int t_group::GetRequiredStringBufferLen(const CStdString& str) const { char* utf8 = ConvToNetwork(str); if (!utf8) return 2; int len = strlen(utf8); delete [] utf8; return len + 2; } void t_group::FillString(char *& p, const CStdString& str) const { char* utf8 = ConvToNetwork(str); if (!utf8) { *p++ = 0; *p++ = 0; return; } int len = strlen(utf8); *p++ = (char)(len >> 8); *p++ = (char)(len & 0xff); memcpy(p, utf8, len); p += len; delete [] utf8; } char * t_group::FillBuffer(char *p) const { FillString(p, group); memcpy(p, &nIpLimit, 4); p += 4; memcpy(p, &nUserLimit, 4); p += 4; int options = nBypassUserLimit & 3; options |= (nEnabled & 3) << 2; *p++ = options & 0xff; std::list<CStdString>::const_iterator ipLimitIter; *p++ = (char)(disallowedIPs.size() >> 8); *p++ = (char)(disallowedIPs.size() & 0xff); for (ipLimitIter = disallowedIPs.begin(); ipLimitIter != disallowedIPs.end(); ipLimitIter++) FillString(p, *ipLimitIter); *p++ = (char)(allowedIPs.size() >> 8); *p++ = (char)(allowedIPs.size() & 0xff); for (ipLimitIter = allowedIPs.begin(); ipLimitIter != allowedIPs.end(); ipLimitIter++) FillString(p, *ipLimitIter); *p++ = (char)(permissions.size() >> 8); *p++ = (char)(permissions.size() & 0xff); for (std::vector<t_directory>::const_iterator permissioniter = permissions.begin(); permissioniter!=permissions.end(); permissioniter++) { FillString(p, permissioniter->dir); *p++ = (char)(permissioniter->aliases.size() >> 8); *p++ = (char)(permissioniter->aliases.size() & 0xff); for (std::list<CStdString>::const_iterator aliasiter = permissioniter->aliases.begin(); aliasiter != permissioniter->aliases.end(); aliasiter++) FillString(p, *aliasiter); int rights = 0; rights |= permissioniter->bDirCreate ? 0x0001:0; rights |= permissioniter->bDirDelete ? 0x0002:0; rights |= permissioniter->bDirList ? 0x0004:0; rights |= permissioniter->bDirSubdirs ? 0x0008:0; rights |= permissioniter->bFileAppend ? 0x0010:0; rights |= permissioniter->bFileDelete ? 0x0020:0; rights |= permissioniter->bFileRead ? 0x0040:0; rights |= permissioniter->bFileWrite ? 0x0080:0; rights |= permissioniter->bIsHome ? 0x0100:0; rights |= permissioniter->bAutoCreate ? 0x0200:0; *p++ = (char)(rights >> 8); *p++ = (char)(rights & 0xff); } for (int i = 0; i < 2; i++) { *p++ = (char)((nSpeedLimitType[i] & 3) + ((nBypassServerSpeedLimit[i] & 3) << 2)); *p++ = (char)(nSpeedLimit[i] >> 8); *p++ = (char)(nSpeedLimit[i] & 0xff); SPEEDLIMITSLIST::const_iterator iter; *p++ = (char)(SpeedLimits[i].size() >> 8); *p++ = (char)(SpeedLimits[i].size() & 0xff); for (iter = SpeedLimits[i].begin(); (iter != SpeedLimits[i].end()) && p; iter++) p = iter->FillBuffer(p); if (!p) return NULL; } FillString(p, comment); *p++ = (char)forceSsl; return p; } int t_group::GetRequiredBufferLen() const { int len = 9; len += GetRequiredStringBufferLen(group); len += 4; std::list<CStdString>::const_iterator ipLimitIter; for (ipLimitIter = disallowedIPs.begin(); ipLimitIter != disallowedIPs.end(); ipLimitIter++) len += GetRequiredStringBufferLen(*ipLimitIter); for (ipLimitIter = allowedIPs.begin(); ipLimitIter != allowedIPs.end(); ipLimitIter++) len += GetRequiredStringBufferLen(*ipLimitIter); len += 2; for (std::vector<t_directory>::const_iterator permissioniter = permissions.begin(); permissioniter!=permissions.end(); permissioniter++) { t_directory directory = *permissioniter; len += 2; len += GetRequiredStringBufferLen(directory.dir); len += 2; for (std::list<CStdString>::const_iterator aliasiter = permissioniter->aliases.begin(); aliasiter != permissioniter->aliases.end(); aliasiter++) len += GetRequiredStringBufferLen(*aliasiter); } // Speed limits. len += 6; // Basic limits. len += 4; // Number of rules. for (int i = 0; i < 2; i++) { SPEEDLIMITSLIST::const_iterator iter; for (iter = SpeedLimits[i].begin(); iter != SpeedLimits[i].end(); iter++) len += iter->GetRequiredBufferLen(); } len += GetRequiredStringBufferLen(comment); len++; //forceSsl return len; } int t_group::GetCurrentSpeedLimit(sltype type) const { switch (nSpeedLimitType[type]) { case 0: if (pOwner) return pOwner->GetCurrentSpeedLimit(type); else return 0; case 1: return 0; case 2: return nSpeedLimit[type]; case 3: { SYSTEMTIME st; GetLocalTime(&st); for (SPEEDLIMITSLIST::const_iterator iter = SpeedLimits[type].begin(); iter != SpeedLimits[type].end(); iter++) if (iter->IsItActive(st)) return iter->m_Speed; } if (pOwner) return pOwner->GetCurrentSpeedLimit(type); else return 0; } return 0; } bool t_group::BypassServerSpeedLimit(sltype type) const { if (nBypassServerSpeedLimit[type] == 1) return true; else if (!nBypassServerSpeedLimit[type]) return false; else if (pOwner) return pOwner->BypassServerSpeedLimit(type); else return false; } bool t_group::IsEnabled() const { switch (nEnabled) { default: case 0: return false; case 1: return true; case 2: if (!pOwner) return false; return pOwner->IsEnabled(); } } bool t_group::AccessAllowed(const CStdString& ip) const { bool disallowed = false; std::list<CStdString>::const_iterator iter; for (iter = disallowedIPs.begin(); iter != disallowedIPs.end(); iter++) { if (disallowed = MatchesFilter(*iter, ip)) break; } if (!disallowed) { if (!pOwner) return true; if (pOwner->AccessAllowed(ip)) return true; } for (iter = allowedIPs.begin(); iter != allowedIPs.end(); iter++) { if (MatchesFilter(*iter, ip)) return true; } if (pOwner && !disallowed) return pOwner->AccessAllowed(ip); return false; } unsigned char * t_user::ParseBuffer(unsigned char *pBuffer, int length) { unsigned char *p = pBuffer; unsigned char *endMarker = pBuffer + length; p = t_group::ParseBuffer(p, length); if (!p) return NULL; if (!ParseString(endMarker, p, user)) return 0; if (!ParseString(endMarker, p, password)) return 0; return p; } char * t_user::FillBuffer(char *p) const { p = t_group::FillBuffer(p); if (!p) return NULL; FillString(p, user); FillString(p, password); return p; } int t_user::GetRequiredBufferLen() const { int len = t_group::GetRequiredBufferLen(); len += GetRequiredStringBufferLen(user); len += GetRequiredStringBufferLen(password); return len; } bool t_group::ParseString(const unsigned char* endMarker, unsigned char *&p, CStdString &string) { if ((endMarker - p) < 2) return false; int len = *p * 256 + p[1]; p += 2; if ((endMarker - p) < len) return false; char* tmp = new char[len + 1]; tmp[len] = 0; memcpy(tmp, p, len); CStdStringW str = ConvFromNetwork((const char*)tmp); delete [] tmp; p += len; #ifdef _UNICODE string = str; #else string = ConvToLocal(str); #endif return true; } bool t_group::ForceSsl() const { switch (forceSsl) { default: case 0: return false; case 1: return true; case 2: if (!pOwner) return false; return pOwner->ForceSsl(); } }