diff --git a/libretroshare/src/retroshare/rsbanlist.h b/libretroshare/src/retroshare/rsbanlist.h index adca966af..5b9db04d8 100644 --- a/libretroshare/src/retroshare/rsbanlist.h +++ b/libretroshare/src/retroshare/rsbanlist.h @@ -30,23 +30,36 @@ class RsBanList; extern RsBanList *rsBanList ; +#define RSBANLIST_ORIGIN_UNKNOWN 0 +#define RSBANLIST_ORIGIN_SELF 1 +#define RSBANLIST_ORIGIN_FRIEND 2 +#define RSBANLIST_ORIGIN_FOF 3 + +#define RSBANLIST_REASON_UNKNOWN 0 +#define RSBANLIST_REASON_USER 1 +#define RSBANLIST_REASON_DHT 2 + class BanListPeer { public: - struct sockaddr_storage addr; - uint8_t masked_bytes ; - uint32_t reason; // Dup Self, Dup Friend - int level; // LOCAL, FRIEND, FoF. - time_t mTs; + uint8_t masked_bytes ; // 0 = []/32. 1=[]/24, 2=[]/16 + uint32_t reason; // User, DHT + uint32_t level; // LOCAL, FRIEND, FoF. bool state ; // true=>active, false=>just stored but inactive + int connect_attempts ; // recorded by the BanList service + time_t mTs; + std::string comment ; // }; class RsBanList { - public: - virtual bool isAddressAccepted(const struct sockaddr_storage& addr) =0; - virtual void getListOfBannedIps(std::list& list) =0; +public: + virtual void enableIPFiltering(bool b) =0; + virtual bool ipFilteringEnabled() =0; + + virtual bool isAddressAccepted(const struct sockaddr_storage& addr) =0; + virtual void getListOfBannedIps(std::list& list) =0; }; diff --git a/libretroshare/src/rsserver/rsinit.cc b/libretroshare/src/rsserver/rsinit.cc index 85ced9dce..6bc56386d 100644 --- a/libretroshare/src/rsserver/rsinit.cc +++ b/libretroshare/src/rsserver/rsinit.cc @@ -1142,6 +1142,7 @@ int RsServer::StartupRetroShare() // NEXT BITDHT. p3BitDht *mBitDht = new p3BitDht(ownId, mLinkMgr, mNetMgr, mDhtStack, bootstrapfile, filteredipfile); + /* install external Pointer for Interface */ rsDht = mBitDht; @@ -1520,7 +1521,8 @@ int RsServer::StartupRetroShare() #endif // new services to test. - p3BanList *mBanList = new p3BanList(serviceCtrl, mNetMgr); + p3BanList *mBanList = new p3BanList(serviceCtrl, mNetMgr); + rsBanList = mBanList ; pqih -> addService(mBanList, true); mBitDht->setupPeerSharer(mBanList); diff --git a/libretroshare/src/serialiser/rstlvbanlist.h b/libretroshare/src/serialiser/rstlvbanlist.h index 73eeb7dea..180c4ba93 100644 --- a/libretroshare/src/serialiser/rstlvbanlist.h +++ b/libretroshare/src/serialiser/rstlvbanlist.h @@ -50,7 +50,8 @@ virtual std::ostream &print(std::ostream &out, uint16_t indent) const; RsTlvIpAddress addr; uint32_t level; uint32_t reason; - uint32_t age; + uint32_t age; + uint8_t masked_bytes ; }; diff --git a/libretroshare/src/services/p3banlist.cc b/libretroshare/src/services/p3banlist.cc index 820517bcd..4c90acc58 100644 --- a/libretroshare/src/services/p3banlist.cc +++ b/libretroshare/src/services/p3banlist.cc @@ -38,6 +38,7 @@ * #define DEBUG_BANLIST 1 ****/ #define DEBUG_BANLIST 1 + #define DEBUG_BANLIST_CONDENSE 1 /* DEFINE INTERFACE POINTER! */ @@ -46,10 +47,6 @@ #define RSBANLIST_ENTRY_MAX_AGE (60 * 60 * 1) // 1 HOURS #define RSBANLIST_SEND_PERIOD 600 // 10 Minutes. -#define RSBANLIST_SOURCE_SELF 0 -#define RSBANLIST_SOURCE_FRIEND 1 -#define RSBANLIST_SOURCE_FOF 2 - #define RSBANLIST_DELAY_BETWEEN_TALK_TO_DHT 60 // should be more: e.g. 600 secs. @@ -87,6 +84,16 @@ RsServiceInfo p3BanList::getServiceInfo() BANLIST_MIN_MINOR_VERSION); } +bool p3BanList::ipFilteringEnabled() +{ + return mIPFilteringEnabled ; +} + +void p3BanList::enableIPFiltering(bool b) +{ + mIPFilteringEnabled = b ; +} + bool p3BanList::isAddressAccepted(const sockaddr_storage &addr) { // we should normally work this including entire ranges of IPs. For now, just check the exact IPs. @@ -140,11 +147,12 @@ void p3BanList::getDhtInfo() { std::cerr << " filtered peer: " << rs_inet_ntoa((*it).mAddr.sin_addr) << std::endl; - int int_reason = 0 ; - int age = 0 ; + int int_reason = RSBANLIST_REASON_DHT ; + int time_stamp = (*it).mLastSeen ; + uint8_t masked_bytes = 0 ; sockaddr_storage ad = *(sockaddr_storage*)&(*it).mAddr ; - addBanEntry(ownId, ad, RSBANLIST_SOURCE_SELF, int_reason, age); + addBanEntry(ownId, ad, RSBANLIST_ORIGIN_SELF, int_reason, time_stamp, masked_bytes); } condenseBanSources_locked() ; @@ -202,36 +210,39 @@ bool p3BanList::recvBanItem(RsBanListItem *item) { bool updated = false; + std::cerr << "(EE) should not receive a Ban item yet. Not implemented!" << std::endl; + time_t now = time(NULL) ; std::list::const_iterator it; //for(it = item->peerList.entries.begin(); it != item->peerList.entries.end(); ++it) for(it = item->peerList.mList.begin(); it != item->peerList.mList.end(); ++it) { // Order is important!. - updated = (addBanEntry(item->PeerId(), it->addr.addr, it->level, - it->reason, it->age) || updated); + updated = (addBanEntry(item->PeerId(), it->addr.addr, it->level, it->reason, now - it->age,it->masked_bytes) || updated); } return updated; } /* overloaded from pqiNetAssistSharePeer */ -void p3BanList::updatePeer(const RsPeerId& /*id*/, const struct sockaddr_storage &addr, int /*type*/, int /*reason*/, int age) +void p3BanList::updatePeer(const RsPeerId& /*id*/, const struct sockaddr_storage &addr, int type, int /*reason*/, int time_stamp) { - RsPeerId ownId = mServiceCtrl->getOwnId(); + RsPeerId ownId = mServiceCtrl->getOwnId(); - int int_reason = 0; - addBanEntry(ownId, addr, RSBANLIST_SOURCE_SELF, int_reason, age); + int int_reason = RSBANLIST_REASON_DHT; - /* process */ - { - RsStackMutex stack(mBanMtx); /****** LOCKED MUTEX *******/ + addBanEntry(ownId, addr, RSBANLIST_ORIGIN_SELF, int_reason, time_stamp,0); - mBanSet.clear(); - condenseBanSources_locked(); - } + /* process */ + { + RsStackMutex stack(mBanMtx); /****** LOCKED MUTEX *******/ + + mBanSet.clear(); + condenseBanSources_locked(); + } } -bool p3BanList::addBanEntry(const RsPeerId &peerId, const struct sockaddr_storage &addr, int level, uint32_t reason, uint32_t age) +bool p3BanList::addBanEntry(const RsPeerId &peerId, const struct sockaddr_storage &addr, + int level, uint32_t reason, time_t time_stamp,uint8_t masked_bytes) { RsStackMutex stack(mBanMtx); /****** LOCKED MUTEX *******/ @@ -239,8 +250,8 @@ bool p3BanList::addBanEntry(const RsPeerId &peerId, const struct sockaddr_storag bool updated = false; #ifdef DEBUG_BANLIST - std::cerr << "p3BanList::addBanEntry() Addr: " << sockaddr_storage_iptostring(addr) << " Level: " << level; - std::cerr << " Reason: " << reason << " Age: " << age; + std::cerr << "p3BanList::addBanEntry() Addr: " << sockaddr_storage_iptostring(addr) << " Origin: " << level; + std::cerr << " Reason: " << reason << " Age: " << now - time_stamp; std::cerr << std::endl; #endif @@ -282,9 +293,9 @@ bool p3BanList::addBanEntry(const RsPeerId &peerId, const struct sockaddr_storag BanListPeer blp; blp.addr = addr; blp.reason = reason; - blp.level = level; - blp.mTs = now - age; - + blp.level = level; + blp.mTs = time_stamp ; + blp.masked_bytes = masked_bytes ; it->second.mBanPeers[bannedaddr] = blp; it->second.mLastUpdate = now; @@ -294,14 +305,17 @@ bool p3BanList::addBanEntry(const RsPeerId &peerId, const struct sockaddr_storag { /* see if it needs an update */ if ((mit->second.reason != reason) || - (mit->second.level != level) || - (mit->second.mTs < (time_t) (now - age))) + (mit->second.level != level) || + (mit->second.mTs < time_stamp)|| + (mit->second.masked_bytes < masked_bytes) + ) { /* update */ mit->second.addr = addr; mit->second.reason = reason; - mit->second.level = level; - mit->second.mTs = now - age; + mit->second.level = level; + mit->second.mTs = time_stamp; + mit->second.masked_bytes = masked_bytes ; it->second.mLastUpdate = now; updated = true; @@ -328,15 +342,15 @@ int p3BanList::condenseBanSources_locked() std::map::const_iterator it; for(it = mBanSources.begin(); it != mBanSources.end(); ++it) { - if (now - it->second.mLastUpdate > RSBANLIST_ENTRY_MAX_AGE) - { -#ifdef DEBUG_BANLIST_CONDENSE - std::cerr << "p3BanList::condenseBanSources_locked()"; - std::cerr << " Ignoring Out-Of-Date peer: " << it->first; - std::cerr << std::endl; -#endif - continue; - } +// if (now - it->second.mLastUpdate > RSBANLIST_ENTRY_MAX_AGE) +// { +//#ifdef DEBUG_BANLIST_CONDENSE +// std::cerr << "p3BanList::condenseBanSources_locked()"; +// std::cerr << " Ignoring Out-Of-Date peer: " << it->first; +// std::cerr << std::endl; +//#endif +// continue; +// } #ifdef DEBUG_BANLIST_CONDENSE std::cerr << "p3BanList::condenseBanSources_locked()"; @@ -349,18 +363,19 @@ int p3BanList::condenseBanSources_locked() lit != it->second.mBanPeers.end(); ++lit) { /* check timestamp */ - if (now - lit->second.mTs > RSBANLIST_ENTRY_MAX_AGE) - { -#ifdef DEBUG_BANLIST_CONDENSE - std::cerr << "p3BanList::condenseBanSources_locked()"; - std::cerr << " Ignoring Out-Of-Date Entry for: "; - std::cerr << sockaddr_storage_iptostring(lit->second.addr); - std::cerr << std::endl; -#endif - continue; - } +// if (now > RSBANLIST_ENTRY_MAX_AGE + lit->second.mTs) +// { +//#ifdef DEBUG_BANLIST_CONDENSE +// std::cerr << "p3BanList::condenseBanSources_locked()"; +// std::cerr << " Ignoring Out-Of-Date Entry for: "; +// std::cerr << sockaddr_storage_iptostring(lit->second.addr); +// std::cerr << " time stamp= " << lit->second.mTs << ", age=" << now - lit->second.mTs; +// std::cerr << std::endl; +//#endif +// continue; +// } - int lvl = lit->second.level; + int lvl = lit->second.level; if (it->first != ownId) { /* as from someone else, increment level */ @@ -376,10 +391,10 @@ int p3BanList::condenseBanSources_locked() /* check if it exists in the Set already */ std::map::iterator sit; sit = mBanSet.find(bannedaddr); - if ((sit == mBanSet.end()) || (lvl < sit->second.level)) + if ((sit == mBanSet.end()) || (lvl < sit->second.level)) { BanListPeer bp = lit->second; - bp.level = lvl; + bp.level = lvl; sockaddr_storage_setport(bp.addr, 0); mBanSet[bannedaddr] = bp; #ifdef DEBUG_BANLIST_CONDENSE @@ -398,7 +413,7 @@ int p3BanList::condenseBanSources_locked() std::cerr << std::endl; #endif /* update if necessary */ - if (lvl == sit->second.level) + if (lvl == sit->second.level) { sit->second.reason |= lit->second.reason; if (sit->second.mTs < lit->second.mTs) @@ -492,7 +507,7 @@ int p3BanList::sendBanSet(const RsPeerId& peerid) std::map::iterator it; for(it = mBanSet.begin(); it != mBanSet.end(); ++it) { - if (it->second.level >= RSBANLIST_SOURCE_FRIEND) + if (it->second.level >= RSBANLIST_ORIGIN_FRIEND) { continue; // only share OWN for the moment. } @@ -500,7 +515,7 @@ int p3BanList::sendBanSet(const RsPeerId& peerid) RsTlvBanListEntry bi; bi.addr.addr = it->second.addr; bi.reason = it->second.reason; - bi.level = it->second.level; + bi.level = it->second.level; bi.age = now - it->second.mTs; //item->peerList.entries.push_back(bi); @@ -525,8 +540,8 @@ int p3BanList::printBanSet_locked(std::ostream &out) { out << "Ban: " << sockaddr_storage_iptostring(it->second.addr); out << " Reason: " << it->second.reason; - out << " Level: " << it->second.level; - if (it->second.level > RSBANLIST_SOURCE_FRIEND) + out << " Level: " << it->second.level; + if (it->second.level > RSBANLIST_ORIGIN_FRIEND) { out << " (unused)"; } @@ -557,7 +572,7 @@ int p3BanList::printBanSources_locked(std::ostream &out) out << "\t"; out << "Ban: " << sockaddr_storage_iptostring(lit->second.addr); out << " Reason: " << lit->second.reason; - out << " Level: " << lit->second.level; + out << " Level: " << lit->second.level; out << " Age: " << now - lit->second.mTs; out << std::endl; } diff --git a/libretroshare/src/services/p3banlist.h b/libretroshare/src/services/p3banlist.h index a36d1fe9f..644e68f4a 100644 --- a/libretroshare/src/services/p3banlist.h +++ b/libretroshare/src/services/p3banlist.h @@ -38,8 +38,6 @@ class p3ServiceControl; class p3NetMgr; - - class BanList { public: @@ -49,8 +47,6 @@ class BanList std::map mBanPeers; }; - - //!The RS BanList service. /** * @@ -59,72 +55,75 @@ class BanList class p3BanList: public RsBanList, public p3Service, public pqiNetAssistPeerShare /* , public p3Config, public pqiMonitor */ { - public: - p3BanList(p3ServiceControl *sc, p3NetMgr *nm); - virtual RsServiceInfo getServiceInfo(); +public: + p3BanList(p3ServiceControl *sc, p3NetMgr *nm); + virtual RsServiceInfo getServiceInfo(); - /***** overloaded from RsBanList *****/ + /***** overloaded from RsBanList *****/ - virtual bool isAddressAccepted(const struct sockaddr_storage& addr) ; - virtual void getListOfBannedIps(std::list& list) ; + virtual void enableIPFiltering(bool b) ; + virtual bool ipFilteringEnabled() ; + virtual bool isAddressAccepted(const struct sockaddr_storage& addr) ; + virtual void getListOfBannedIps(std::list& list) ; - /***** overloaded from pqiNetAssistPeerShare *****/ + /***** overloaded from pqiNetAssistPeerShare *****/ - virtual void updatePeer(const RsPeerId& id, const struct sockaddr_storage &addr, int type, int reason, int age); + virtual void updatePeer(const RsPeerId& id, const struct sockaddr_storage &addr, int type, int reason, int time_stamp); - /***** overloaded from p3Service *****/ - /*! - * This retrieves all chat msg items and also (important!) - * processes chat-status items that are in service item queue. chat msg item requests are also processed and not returned - * (important! also) notifications sent to notify base on receipt avatar, immediate status and custom status - * : notifyCustomState, notifyChatStatus, notifyPeerHasNewAvatar - * @see NotifyBase + /***** overloaded from p3Service *****/ + /*! + * This retrieves all chat msg items and also (important!) + * processes chat-status items that are in service item queue. chat msg item requests are also processed and not returned + * (important! also) notifications sent to notify base on receipt avatar, immediate status and custom status + * : notifyCustomState, notifyChatStatus, notifyPeerHasNewAvatar + * @see NotifyBase - */ - virtual int tick(); - virtual int status(); + */ + virtual int tick(); + virtual int status(); - int sendPackets(); - bool processIncoming(); + int sendPackets(); + bool processIncoming(); - bool recvBanItem(RsBanListItem *item); - bool addBanEntry(const RsPeerId &peerId, const struct sockaddr_storage &addr, int level, uint32_t reason, uint32_t age); - void sendBanLists(); - int sendBanSet(const RsPeerId& peerid); + bool recvBanItem(RsBanListItem *item); + bool addBanEntry(const RsPeerId &peerId, const struct sockaddr_storage &addr, int level, uint32_t reason, time_t time_stamp, uint8_t masked_bytes); + void sendBanLists(); + int sendBanSet(const RsPeerId& peerid); - /*! - * Interface stuff. - */ + /*! + * Interface stuff. + */ - /*************** pqiMonitor callback ***********************/ - //virtual void statusChange(const std::list &plist); + /*************** pqiMonitor callback ***********************/ + //virtual void statusChange(const std::list &plist); - /************* from p3Config *******************/ - //virtual RsSerialiser *setupSerialiser() ; - //virtual bool saveList(bool& cleanup, std::list&) ; - //virtual void saveDone(); - //virtual bool loadList(std::list& load) ; + /************* from p3Config *******************/ + //virtual RsSerialiser *setupSerialiser() ; + //virtual bool saveList(bool& cleanup, std::list&) ; + //virtual void saveDone(); + //virtual bool loadList(std::list& load) ; - private: - void getDhtInfo() ; +private: + void getDhtInfo() ; - RsMutex mBanMtx; + RsMutex mBanMtx; - int condenseBanSources_locked(); - int printBanSources_locked(std::ostream &out); - int printBanSet_locked(std::ostream &out); + int condenseBanSources_locked(); + int printBanSources_locked(std::ostream &out); + int printBanSet_locked(std::ostream &out); - time_t mSentListTime; - std::map mBanSources; - std::map mBanSet; + time_t mSentListTime; + std::map mBanSources; + std::map mBanSet; - p3ServiceControl *mServiceCtrl; - p3NetMgr *mNetMgr; - time_t mLastDhtInfoRequest ; + p3ServiceControl *mServiceCtrl; + p3NetMgr *mNetMgr; + time_t mLastDhtInfoRequest ; + bool mIPFilteringEnabled ; }; #endif // SERVICE_RSBANLIST_HEADER diff --git a/retroshare-gui/src/gui/settings/ServerPage.cpp b/retroshare-gui/src/gui/settings/ServerPage.cpp index 05f4fa3ad..3caa8c886 100755 --- a/retroshare-gui/src/gui/settings/ServerPage.cpp +++ b/retroshare-gui/src/gui/settings/ServerPage.cpp @@ -29,8 +29,10 @@ #include #include #include +#include #include +#include #include #include #include @@ -41,6 +43,12 @@ #define ICON_STATUS_UNKNOWN ":/images/ledoff1.png" #define ICON_STATUS_OK ":/images/ledon1.png" +#define COLUMN_RANGE 0 +#define COLUMN_STATUS 1 +#define COLUMN_ORIGIN 2 +#define COLUMN_REASON 3 +#define COLUMN_COMMENT 4 + //#define SERVER_DEBUG 1 ServerPage::ServerPage(QWidget * parent, Qt::WindowFlags flags) @@ -56,6 +64,17 @@ ServerPage::ServerPage(QWidget * parent, Qt::WindowFlags flags) manager = NULL ; + ui.filteredIpsTable->setHorizontalHeaderItem(COLUMN_RANGE,new QTableWidgetItem(tr("IP Range"))) ; + ui.filteredIpsTable->setHorizontalHeaderItem(COLUMN_STATUS,new QTableWidgetItem(tr("Status"))) ; + ui.filteredIpsTable->setHorizontalHeaderItem(COLUMN_ORIGIN,new QTableWidgetItem(tr("Origin"))) ; + ui.filteredIpsTable->setHorizontalHeaderItem(COLUMN_COMMENT,new QTableWidgetItem(tr("Comment"))) ; + + ui.filteredIpsTable->verticalHeader()->hide() ; + + + QObject::connect(ui.filteredIpsTable,SIGNAL(customContextMenuRequested(const QPoint&)),this,SLOT(ipFilterContextMenu(const QPoint&))) ; + QObject::connect(ui.denyAll_CB,SIGNAL(toggled(bool)),this,SLOT(toggleIpFiltering(bool))); + QTimer *timer = new QTimer(this); timer->connect(timer, SIGNAL(timeout()), this, SLOT(updateStatus())); timer->start(1000); @@ -136,9 +155,11 @@ void ServerPage::load() if (!rsPeers->getPeerDetails(rsPeers->getOwnId(), detail)) { return; - } + } + loadFilteredIps() ; + + mIsHiddenNode = (detail.netMode == RS_NETMODE_HIDDEN); - mIsHiddenNode = (detail.netMode == RS_NETMODE_HIDDEN); if (mIsHiddenNode) { loadHiddenNode(); @@ -233,12 +254,209 @@ void ServerPage::load() updateTorOutProxyIndicator(); } -//void ServerPage::toggleTurtleRouting(bool b) -//{ -// ui._max_tr_up_per_sec_SB->setEnabled(b) ; -// -// rsTurtle->setEnabled(b) ; -//} +static std::string print_addr(const struct sockaddr_storage& addr) +{ + const sockaddr_in *in = (const sockaddr_in*)&addr ; + + char str[100]; + uint8_t *bytes = (uint8_t *) &(in->sin_addr.s_addr); + sprintf(str, "%u.%u.%u.%u", (int) bytes[0], (int) bytes[1], (int) bytes[2], (int) bytes[3]); + + return std::string(str) ; +} + +std::string print_addr_range(const struct sockaddr_storage& addr,uint8_t masked_bytes) +{ + const sockaddr_in *in = (const sockaddr_in*)&addr ; + + char str[100]; + uint8_t *bytes = (uint8_t *) &(in->sin_addr.s_addr); + str[0] = 0 ; + + switch(masked_bytes) + { + case 0: sprintf(str, "%u.%u.%u.%u", (int) bytes[0], (int) bytes[1], (int) bytes[2], (int) bytes[3]); + break ; + case 1: sprintf(str, "%u.%u.%u.255/24", (int) bytes[0], (int) bytes[1], (int) bytes[2]); + break ; + case 2: sprintf(str, "%u.%u.255.255/16", (int) bytes[0], (int) bytes[1]); + break ; + default: + std::cerr << "ERROR: Wrong format : masked_bytes = " << masked_bytes << std::endl; + return std::string("Invalid format") ; + } + + return std::string(str) ; +} + +void ServerPage::toggleIpFiltering(bool b) +{ + rsBanList->enableIPFiltering(b) ; + loadFilteredIps() ; +} + +void ServerPage::loadFilteredIps() +{ + ui.includeFromFriends_CB->setChecked(false) ; + ui.includeFromDHT_CB->setChecked(true) ; + + ui.ipInput_LE->setEnabled(false) ; + ui.ipInputRange_SB->setEnabled(false) ; + ui.ipInputComment_LE->setEnabled(false) ; + ui.ipInputAdd_PB->setEnabled(false) ; + + if(rsBanList->ipFilteringEnabled()) + { + ui.denyAll_CB->setChecked(true) ; + ui.filteredIpsTable->setEnabled(true) ; + ui.includeFromFriends_CB->setEnabled(false) ; + ui.includeFromDHT_CB->setEnabled(false) ; + } + else + { + ui.denyAll_CB->setChecked(false) ; + ui.filteredIpsTable->setEnabled(false) ; + ui.includeFromFriends_CB->setEnabled(false) ; + ui.includeFromDHT_CB->setEnabled(false) ; + } + + std::list lst ; + + rsBanList->getListOfBannedIps(lst) ; + + ui.filteredIpsTable->setRowCount(lst.size()) ; + + //std::cerr << "Adding " << lst.size() << " entries to table." << std::endl; + + int row = 0 ; + for(std::list::const_iterator it(lst.begin());it!=lst.end();++it,++row) + { + //std::cerr << " adding banned lst peer: " << print_addr((*it).addr) << std::endl; + + ui.filteredIpsTable->setItem(row,COLUMN_RANGE,new QTableWidgetItem(QString::fromStdString(print_addr_range((*it).addr,(*it).masked_bytes)))) ; + + if( (*it).state ) + ui.filteredIpsTable->setItem(row,COLUMN_STATUS,new QTableWidgetItem(QString("active"))) ; + else + ui.filteredIpsTable->setItem(row,COLUMN_STATUS,new QTableWidgetItem(QString(""))) ; + + ui.filteredIpsTable->item(row,COLUMN_STATUS)->setData(Qt::UserRole,QVariant( (*it).state )) ; + + switch((*it).level) + { + default: + case RSBANLIST_ORIGIN_UNKNOWN: ui.filteredIpsTable->setItem(row,COLUMN_ORIGIN,new QTableWidgetItem(QString("Unknown"))) ; + break ; + case RSBANLIST_ORIGIN_FOF: ui.filteredIpsTable->setItem(row,COLUMN_ORIGIN,new QTableWidgetItem(QString("From friend of a friend"))) ; + break ; + case RSBANLIST_ORIGIN_FRIEND: ui.filteredIpsTable->setItem(row,COLUMN_ORIGIN,new QTableWidgetItem(QString("From friend"))) ; + break ; + case RSBANLIST_ORIGIN_SELF: ui.filteredIpsTable->setItem(row,COLUMN_ORIGIN,new QTableWidgetItem(QString("From you"))) ; + break ; + } + + switch( (*it).reason ) + { + case RSBANLIST_REASON_DHT: ui.filteredIpsTable->setItem(row,COLUMN_REASON,new QTableWidgetItem(QString("Bad peer (DHT)"))) ; + break ; + case RSBANLIST_REASON_USER: ui.filteredIpsTable->setItem(row,COLUMN_REASON,new QTableWidgetItem(QString("Home-made rule"))) ; + break ; + default: + case RSBANLIST_REASON_UNKNOWN: ui.filteredIpsTable->setItem(row,COLUMN_REASON,new QTableWidgetItem(QString("Unknown"))) ; + break ; + } + ui.filteredIpsTable->setItem(row,COLUMN_COMMENT,new QTableWidgetItem(QString::fromStdString((*it).comment))) ; + } +} + +static bool parseAddrFromQString(const QString& s,struct sockaddr_storage& addr,int& bytes ) +{ + QStringList lst = s.split(".") ; + + QStringList::const_iterator it = lst.begin(); + bool ok ; + + uint32_t s1 = (*it).toInt(&ok) ; ++it ; if(!ok) return false ; + uint32_t s2 = (*it).toInt(&ok) ; ++it ; if(!ok) return false ; + uint32_t s3 = (*it).toInt(&ok) ; ++it ; if(!ok) return false ; + + QStringList lst2 = (*it).split("/") ; + + it = lst2.begin(); + + uint32_t s4 ; + s4 = (*it).toInt(&ok) ; ++it ; if(!ok) return false ; + + if(it != lst2.end()) + { + uint32_t x = (*it).toInt(&ok) ; if(!ok) return false ; + if(x%8 != 0) + return false ; + + if(x != 16 && x != 24) + return false ; + + bytes = 4 - x/8 ; + } + + const sockaddr_in *in = (const sockaddr_in*)&addr ; + ((uint8_t*)&in->sin_addr.s_addr)[0] = s1 ; + ((uint8_t*)&in->sin_addr.s_addr)[1] = s2 ; + ((uint8_t*)&in->sin_addr.s_addr)[2] = s3 ; + ((uint8_t*)&in->sin_addr.s_addr)[3] = s4 ; + + return ok; +} + +void ServerPage::ipFilterContextMenu(const QPoint& point) +{ + QMenu contextMenu(this) ; + int row = ui.filteredIpsTable->currentRow(); + + QTableWidgetItem *item = ui.filteredIpsTable->item(row, COLUMN_STATUS); + + if(item == NULL) + return ; + + bool status = item->data(Qt::UserRole).toBool(); + + if(!status) + contextMenu.addAction(tr("Disable/remove"),this,SLOT(removeBannedIp()))->setEnabled(false) ; + + QString addr_string = ui.filteredIpsTable->item(row,COLUMN_RANGE)->text() ; + + sockaddr_storage addr ; + int masked_bytes ; + + if(!parseAddrFromQString(addr_string,addr,masked_bytes)) + { + std::cerr <<"Cannot parse IP \"" << addr_string.toStdString() << "\"" << std::endl; + return ; + } + + QString range0 = QString::fromStdString(print_addr_range(addr,0)) ; + QString range1 = QString::fromStdString(print_addr_range(addr,1)) ; + QString range2 = QString::fromStdString(print_addr_range(addr,2)) ; + + contextMenu.addAction(QObject::tr("Filter IP " )+range0,this,SLOT(enableBannedIp()))->setEnabled(false) ; +#warning UNIMPLEMENTED CODE + contextMenu.addAction(QObject::tr("Filter entire range ")+range1,this,SLOT(enableBannedIp()))->setEnabled(false) ; + contextMenu.addAction(QObject::tr("Filter entire range ")+range2,this,SLOT(enableBannedIp()))->setEnabled(false) ; + + contextMenu.exec(QCursor::pos()) ; +} + +void ServerPage::removeBannedIp() +{ +#warning UNIMPLEMENTED CODE + std::cerr << "Removing banned IP" << std::endl; +} + +void ServerPage::enableBannedIp() +{ +#warning UNIMPLEMENTED CODE + std::cerr << "Removing banned IP" << std::endl; +} /** Loads the settings for this page */ void ServerPage::updateStatus() @@ -254,11 +472,13 @@ void ServerPage::updateStatus() if(!isVisible()) return ; + loadFilteredIps() ; + if (mIsHiddenNode) { updateStatusHiddenNode(); return; - } + } /* load up configuration from rsPeers */ RsPeerDetails detail; diff --git a/retroshare-gui/src/gui/settings/ServerPage.h b/retroshare-gui/src/gui/settings/ServerPage.h index 206c74ebe..8f711a520 100755 --- a/retroshare-gui/src/gui/settings/ServerPage.h +++ b/retroshare-gui/src/gui/settings/ServerPage.h @@ -50,6 +50,10 @@ public slots: void updateStatus(); private slots: + void toggleIpFiltering(bool b); + void ipFilterContextMenu(const QPoint &); + void removeBannedIp(); + void enableBannedIp(); void saveAddresses(); void toggleUPnP(); void toggleIpDetermination(bool) ; @@ -66,6 +70,7 @@ private: void saveAddressesHiddenNode(); void updateTorOutProxyIndicator(); void updateLocInProxyIndicator(); + void loadFilteredIps() ; Ui::ServerPage ui; diff --git a/retroshare-gui/src/gui/settings/ServerPage.ui b/retroshare-gui/src/gui/settings/ServerPage.ui index 2e2660f12..4726c638b 100755 --- a/retroshare-gui/src/gui/settings/ServerPage.ui +++ b/retroshare-gui/src/gui/settings/ServerPage.ui @@ -498,6 +498,128 @@ behind a firewall or a VPN. + + + IP Filters + + + + + + Deny all connections from the following IP ranges: + + + + + + + Qt::CustomContextMenu + + + true + + + false + + + true + + + + IP range + + + + + Status + + + + + Origin + + + + + Reason + + + + + Comment + + + + + + + + Automatically include the IPs denied by your friends + + + + + + + Automatically filter suspicious IPs detected by DHT + + + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Enter an IP range. Accepted formats:</p><p>193.190.209.15</p><p>193.190.209.15/24</p><p>193.190.209.15/16</p></body></html> + + + + + + + 16 + + + 32 + + + 8 + + + 32 + + + + + + + + 0 + 0 + + + + <html><head/><body><p>Enter any comment you'd like</p></body></html> + + + + + + + Add + + + + + + + TOR Configuration