📄 ipacl.cxx
字号:
return (address & mask) == (addr & mask);
}
///////////////////////////////////////////////////////////////////////////////
PIpAccessControlList::PIpAccessControlList(BOOL defAllow)
: defaultAllowance(defAllow)
{
}
static BOOL ReadConfigFileLine(PTextFile & file, PString & line)
{
line = PString();
do {
if (!file.ReadLine(line))
return FALSE;
} while (line.IsEmpty() || line[0] == '#');
PINDEX lastCharPos;
while (line[lastCharPos = line.GetLength()-1] == '\\') {
PString str;
if (!file.ReadLine(str))
return FALSE;
line[lastCharPos] = ' ';
line += str;
}
return TRUE;
}
static void ParseConfigFileExcepts(const PString & str,
PStringList & entries,
PStringList & exceptions)
{
PStringArray terms = str.Tokenise(' ', FALSE);
BOOL hadExcept = FALSE;
PINDEX d;
for (d = 0; d < terms.GetSize(); d++) {
if (terms[d] == "EXCEPT")
hadExcept = TRUE;
else if (hadExcept)
exceptions.AppendString(terms[d]);
else
entries.AppendString(terms[d]);
}
}
static BOOL SplitConfigFileLine(const PString & line, PString & daemons, PString & clients)
{
PINDEX colon = line.Find(':');
if (colon == P_MAX_INDEX)
return FALSE;
daemons = line.Left(colon).Trim();
PINDEX other_colon = line.Find(':', ++colon);
clients = line(colon, other_colon-1).Trim();
return TRUE;
}
static BOOL IsDaemonInConfigFileLine(const PString & daemon, const PString & daemons)
{
PStringList daemonsIn, daemonsOut;
ParseConfigFileExcepts(daemons, daemonsIn, daemonsOut);
for (PINDEX in = 0; in < daemonsIn.GetSize(); in++) {
if (daemonsIn[in] == "ALL" || daemonsIn[in] == daemon) {
PINDEX out;
for (out = 0; out < daemonsOut.GetSize(); out++) {
if (daemonsOut[out] == daemon)
break;
}
if (out >= daemonsOut.GetSize())
return TRUE;
}
}
return FALSE;
}
static BOOL ReadConfigFile(PTextFile & file,
const PString & daemon,
PStringList & clientsIn,
PStringList & clientsOut)
{
PString line;
while (ReadConfigFileLine(file, line)) {
PString daemons, clients;
if (SplitConfigFileLine(line, daemons, clients) &&
IsDaemonInConfigFileLine(daemon, daemons)) {
ParseConfigFileExcepts(clients, clientsIn, clientsOut);
return TRUE;
}
}
return FALSE;
}
BOOL PIpAccessControlList::InternalLoadHostsAccess(const PString & daemonName,
const char * filename,
BOOL allowance)
{
PTextFile file;
if (!file.Open(PProcess::GetOSConfigDir() + filename, PFile::ReadOnly))
return TRUE;
BOOL ok = TRUE;
PStringList clientsIn;
PStringList clientsOut;
while (ReadConfigFile(file, daemonName, clientsIn, clientsOut)) {
PINDEX i;
for (i = 0; i < clientsOut.GetSize(); i++) {
if (!Add((allowance ? "-@" : "+@") + clientsOut[i]))
ok = FALSE;
}
for (i = 0; i < clientsIn.GetSize(); i++) {
if (!Add((allowance ? "+@" : "-@") + clientsIn[i]))
ok = FALSE;
}
}
return ok;
}
BOOL PIpAccessControlList::LoadHostsAccess(const char * daemonName)
{
PString daemon;
if (daemonName != NULL)
daemon = daemonName;
else
daemon = PProcess::Current().GetName();
return InternalLoadHostsAccess(daemon, "hosts.allow", TRUE) & // Really is a single &
InternalLoadHostsAccess(daemon, "hosts.deny", FALSE);
}
#ifdef P_CONFIG_LIST
static const char DefaultConfigName[] = "IP Access Control List";
BOOL PIpAccessControlList::Load(PConfig & cfg)
{
return Load(cfg, DefaultConfigName);
}
BOOL PIpAccessControlList::Load(PConfig & cfg, const PString & baseName)
{
BOOL ok = TRUE;
PINDEX count = cfg.GetInteger(baseName & "Array Size");
for (PINDEX i = 1; i <= count; i++) {
if (!Add(cfg.GetString(baseName & PString(PString::Unsigned, i))))
ok = FALSE;
}
return ok;
}
void PIpAccessControlList::Save(PConfig & cfg)
{
Save(cfg, DefaultConfigName);
}
void PIpAccessControlList::Save(PConfig & cfg, const PString & baseName)
{
PINDEX count = 0;
for (PINDEX i = 0; i < GetSize(); i++) {
PIpAccessControlEntry & entry = operator[](i);
if (!entry.IsHidden()) {
count++;
cfg.SetString(baseName & PString(PString::Unsigned, count), entry.AsString());
}
}
cfg.SetInteger(baseName & "Array Size", count);
}
#endif // P_CONFIG_LIST
BOOL PIpAccessControlList::Add(PIpAccessControlEntry * entry)
{
if (!entry->IsValid()) {
delete entry;
return FALSE;
}
PINDEX idx = GetValuesIndex(*entry);
if (idx == P_MAX_INDEX) {
Append(entry);
return TRUE;
}
// Return TRUE if the newly added entry is identical to an existing one
PIpAccessControlEntry & existing = operator[](idx);
BOOL ok = existing.IsClass(PIpAccessControlEntry::Class()) &&
entry->IsClass(PIpAccessControlEntry::Class()) &&
existing.IsAllowed() == entry->IsAllowed();
delete entry;
return ok;
}
BOOL PIpAccessControlList::Add(const PString & description)
{
return Add(CreateControlEntry(description));
}
BOOL PIpAccessControlList::Add(PIPSocket::Address addr, PIPSocket::Address mask, BOOL allow)
{
PStringStream description;
description << (allow ? '+' : '-') << addr << '/' << mask;
return Add(description);
}
BOOL PIpAccessControlList::Remove(const PString & description)
{
PIpAccessControlEntry entry(description);
if (!entry.IsValid())
return FALSE;
return InternalRemoveEntry(entry);
}
BOOL PIpAccessControlList::Remove(PIPSocket::Address addr, PIPSocket::Address mask)
{
PIpAccessControlEntry entry(addr, mask, TRUE);
return InternalRemoveEntry(entry);
}
BOOL PIpAccessControlList::InternalRemoveEntry(PIpAccessControlEntry & entry)
{
PINDEX idx = GetValuesIndex(entry);
if (idx == P_MAX_INDEX)
return FALSE;
RemoveAt(idx);
return TRUE;
}
PIpAccessControlEntry * PIpAccessControlList::CreateControlEntry(const PString & description)
{
return new PIpAccessControlEntry(description);
}
PIpAccessControlEntry * PIpAccessControlList::Find(PIPSocket::Address address) const
{
PINDEX size = GetSize();
if (size == 0)
return NULL;
for (PINDEX i = 0; i < GetSize(); i++) {
PIpAccessControlEntry & entry = operator[](i);
if (entry.Match(address))
return &entry;
}
return NULL;
}
BOOL PIpAccessControlList::IsAllowed(PTCPSocket & socket) const
{
if (IsEmpty())
return defaultAllowance;
PIPSocket::Address address;
if (socket.GetPeerAddress(address))
return IsAllowed(address);
return FALSE;
}
BOOL PIpAccessControlList::IsAllowed(PIPSocket::Address address) const
{
if (IsEmpty())
return defaultAllowance;
PIpAccessControlEntry * entry = Find(address);
if (entry == NULL)
return FALSE;
return entry->IsAllowed();
}
// End of File ///////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -