From 5676914a4f7d31dcebf7ffb1d8af3af3d66ea828 Mon Sep 17 00:00:00 2001 From: ketmar Date: Sat, 20 Dec 2008 08:33:37 +0200 Subject: [PATCH] rule synthax changed --- sktest/rules.rc | 5 ++ sktest/src/fwrules.cpp | 173 ++++++++++++++++++++++++++++++++----------------- sktest/src/fwrules.h | 16 ++--- 3 files changed, 126 insertions(+), 68 deletions(-) create mode 100644 sktest/rules.rc diff --git a/sktest/rules.rc b/sktest/rules.rc new file mode 100644 index 0000000..ab9693e --- /dev/null +++ b/sktest/rules.rc @@ -0,0 +1,5 @@ +newrule + app * + rule allow:udp:172.16.20.1:53:"DNS query" + rule allow:tcp:172.16.21.162:80:"my HTTP server (id)" +endrule diff --git a/sktest/src/fwrules.cpp b/sktest/src/fwrules.cpp index bd155fc..8b81e90 100644 --- a/sktest/src/fwrules.cpp +++ b/sktest/src/fwrules.cpp @@ -9,8 +9,47 @@ #include "fwrules.h" -FWRule::FWRule (const QString &descr, const QString &appName) : - QObject(0), mDescr(descr), mAppName(appName) +static QString unquoteStr (const QString &str) { + QString res = str.trimmed(); + if (res.length() >= 2 && res.at(0) == '"' && res.at(res.length()-1) == '"') { + QString s(res); res.clear(); + for (int f = 1; f < s.length()-1; f++) { + QChar ch = s.at(f); + if (ch == '\\') { + /* special char */ + f++; + ch = s.at(f); + if (ch == 't') { res.append('\t'); continue; } + else if (ch == 'n') { res.append('\n'); continue; } + else if (ch == 'r') { res.append('\r'); continue; } + } + res.append(ch); + } + } + return res; +} + + +static QString quoteStr (const QString &str) { + QString res('"'), s; + s = str.trimmed(); + for (int f = 0; f < s.length(); f++) { + QChar ch = s.at(f); + if (ch == '\t') res.append("\\t"); + else if (ch == '\n') res.append("\\n"); + else if (ch == '\r') res.append("\\r"); + else if (ch == '\\' || ch == '"') { + res.append("\\"); + res.append(ch); + } else res.append(ch); + } + res.append('"'); + return res; +} + + +/*****************************************************************************/ +FWRule::FWRule (const QString &appName) : QObject(0), mAppName(appName) { } @@ -27,13 +66,10 @@ void FWRule::clear () { bool FWRule::saveTo (QTextStream &stream) const { - stream << "rule\n"; - stream << " descr " << mDescr << "\n"; + stream << "newrule\n"; stream << " app " << mAppName << "\n"; - //addr allow:udp:10.0.0.1:53 - //addr deny:udp:172.16.20.1:53 foreach (tFWRuleInfo *i, mList) { - stream << " addr "; + stream << " rule "; if (i->allow) stream << "allow:"; else stream << "deny:"; switch (i->proto) { case IPCQ_PROTO_UDP: stream << "udp:"; break; @@ -46,13 +82,20 @@ bool FWRule::saveTo (QTextStream &stream) const { stream << ipaddr.toString() << ":"; } if (i->port == 0) stream << "*"; else stream << i->port; - stream << "\n"; + stream << ":" << quoteStr(i->descr) << "\n"; } stream << "endrule\n"; return true; } +/* +newrule + app * + rule allow:udp:172.16.20.1:53:DNS query + rule allow:tcp:172.16.21.162:80:my HTTP server (id) +endrule +*/ bool FWRule::loadFrom (QTextStream &stream) { clear(); for (;;) { @@ -60,72 +103,77 @@ bool FWRule::loadFrom (QTextStream &stream) { if (s.isNull()) return false; s = s.trimmed(); qDebug() << s; - if (s == "rule") break; + if (s == "newrule") break; } qDebug() << "*rule found!"; - QString dsc, app; + QString app; for (;;) { QString s = stream.readLine(); if (s.isNull()) return false; s = s.trimmed(); if (s.isEmpty() || s.at(0) == '#') continue; if (s == "endrule") break; - qDebug() << s; - if (s.startsWith("descr ")) { - s.remove(0, 5); - dsc = s.trimmed(); - qDebug() << "dsc:" << dsc; - continue; - } + //qDebug() << s; if (s.startsWith("app ")) { s.remove(0, 4); - app = s.trimmed(); - if (app.length() >= 2 && app.at(0) == '"' && app.at(app.length()-1) == '"') { - // unquote - s = app; app.clear(); - for (int f = 1; f < s.length()-1; f++) { - QChar ch = s.at(f); - if (ch == '\\') { - f++; - ch = s.at(f); - if (ch == 't') app.append('\t'); - else if (ch == 'n') app.append('\n'); - else if (ch == 'r') app.append('\r'); - else app.append(ch); - } else app.append(ch); - } - } - qDebug() << "app:" << dsc; + app = unquoteStr(s); + qDebug() << "app:" << app; continue; } QStringList nv(s.split(' ', QString::SkipEmptyParts)); - if (nv.count() != 2) return false; - if (nv.at(0) == "addr") { - qDebug() << "addr:" << nv.at(1); - if (!append(nv.at(1))) return false; + if (nv.count() < 2) return false; + if (nv.at(0) == "rule") { + //qDebug() << s; + s.remove(0, 5); + if (!append(s)) return false; } else return false; } if (mList.count() < 1) return false; if (app.isEmpty()) app = "*"; - mDescr = dsc; mAppName = app; return true; } -//deny:udp:172.16.20.1:53 -bool FWRule::append (const QString &addrdef) { - QStringList nv(addrdef.split(':')); - if (nv.length() != 4) return false; +/* + allow:udp:172.16.20.1:53:DNS query +*/ +static bool splitRuleDef (QStringList *res, const QString &ruledef) { + //qDebug() << "parsing:" << ruledef; + for (int n = 0, pos = 0; n < 5; n++) { + if (n == 4) { + QString s = ruledef.mid(pos).trimmed(); + s = unquoteStr(s); + //qDebug() << "n:" << n << "s:" << s; + res->append(s); + return true; + } + int np = ruledef.indexOf(':', pos); + if (np == -1) return false; + QString s = ruledef.mid(pos, np-pos); + pos = np+1; + //qDebug() << "n:" << n << "s:" << s; + s = s.trimmed(); + if (s.isEmpty()) return false; + res->append(s); + } + return false; +} + + +bool FWRule::append (const QString &ruledef) { + QStringList nv; + if (!splitRuleDef(&nv, ruledef)) return false; + //qDebug() << "nv:" << nv; + tFWRuleInfo *i = new tFWRuleInfo; - /* allow/deny */ - QString s = nv.at(0).trimmed(); - if (s == "allow") i->allow = 1; else i->allow = 0; i->flags = 0; - - QHostAddress ip; + /* allow/deny */ + i->allow = (nv.at(0) == "allow")?1:0; /* proto */ - s = nv.at(1).trimmed(); + QString s; + QHostAddress ip; + s = nv.at(1); if (s == "tcp") { i->proto = IPCQ_PROTO_TCP; i->flags |= IPCR_FLAG_TCP; @@ -138,7 +186,7 @@ bool FWRule::append (const QString &addrdef) { } else goto error; /* ip */ i->flags |= IPCR_FLAG_IP; - s = nv.at(2).trimmed(); + s = nv.at(2); if (s == "*") { i->ip = 0; i->flags |= IPCR_FLAG_ANYIP; @@ -149,7 +197,7 @@ bool FWRule::append (const QString &addrdef) { } /* port */ i->flags |= IPCR_FLAG_PORT; - s = nv.at(3).trimmed(); + s = nv.at(3); if (s == "*") { i->port = 0; i->flags |= IPCR_FLAG_ANYPORT; @@ -159,7 +207,14 @@ bool FWRule::append (const QString &addrdef) { if (!ok || pn > 65535) goto error; i->port = pn; } + i->descr = nv.at(4); mList << i; + qDebug() << + "allow:" << i->allow << + "proto:" << i->proto << + "flags:" << i->flags << + "ip:" << i->ip << + "descr:" << i->descr; return true; error: delete i; @@ -167,11 +222,12 @@ error: } -void FWRule::addAction (quint32 ip, quint16 port, quint8 proto, quint8 action) { +void FWRule::addAction (const QString &descr, quint32 ip, quint16 port, quint8 proto, quint8 action) { tFWRuleInfo *i = new tFWRuleInfo; i->flags = 0; i->allow = action; + i->descr = descr; /* proto */ if (proto == IPCQ_PROTO_TCP) { i->proto = IPCQ_PROTO_TCP; @@ -215,9 +271,7 @@ bool FWRule::getAction (quint32 ip, quint16 port, quint8 proto, quint8 *action, /*****************************************************************************/ -FWRuleList::FWRuleList (const QString &fname) : - QObject(0) -{ +FWRuleList::FWRuleList (const QString &fname) : QObject(0) { if (!fname.isEmpty()) loadFrom(fname); } @@ -257,7 +311,7 @@ bool FWRuleList::loadFrom (const QString &fname) { stream.setDevice(&file); stream.setCodec("UTF-8"); for (;;) { - FWRule *r = new FWRule("", ""); + FWRule *r = new FWRule(""); if (!r->loadFrom(stream)) { delete r; break; } mList << r; } @@ -281,11 +335,10 @@ void FWRuleList::addAction (const QString &descr, const QString &appName, quint3 foreach (FWRule *r, mList) { QString an(r->getAppName()); if (an != appName) continue; - if (!descr.isEmpty() && r->getDescr() != descr) continue; - r->addAction(ip, port, proto, allow); + r->addAction(descr, ip, port, proto, allow); return; } - FWRule *r = new FWRule(descr, appName); - r->addAction(ip, port, proto, allow); + FWRule *r = new FWRule(appName); + r->addAction(descr, ip, port, proto, allow); mList << r; } diff --git a/sktest/src/fwrules.h b/sktest/src/fwrules.h index b3227bd..af7eafd 100644 --- a/sktest/src/fwrules.h +++ b/sktest/src/fwrules.h @@ -7,20 +7,22 @@ #include -typedef struct { +class tFWRuleInfo { +public: quint32 ip; /* 0: any */ - quint16 port; - quint8 proto; + quint16 port; /* 0: any */ + quint8 proto; /* 255: any */ quint8 allow; quint8 flags; -} tFWRuleInfo; + QString descr; +}; class FWRule : public QObject { Q_OBJECT public: - FWRule (const QString &descr, const QString &appName); + FWRule (const QString &appName); ~FWRule (); bool loadFrom (QTextStream &stream); @@ -28,7 +30,6 @@ public: bool append (const QString &addrdef); - inline QString getDescr (void) const { return mDescr; } inline QString getAppName (void) const { return mAppName; } /* @@ -38,12 +39,11 @@ public: */ bool getAction (quint32 ip, quint16 port, quint8 proto, quint8 *action, quint8 *flags); - void addAction (quint32 ip, quint16 port, quint8 proto, quint8 action); + void addAction (const QString &descr, quint32 ip, quint16 port, quint8 proto, quint8 action); private: void clear (); - QString mDescr; QString mAppName; QList mList; /* to save the order */ -- 2.11.4.GIT