From 28f6809af8cdc4a53ce9b492277030cbfcda450e Mon Sep 17 00:00:00 2001 From: Alexey Sokolov Date: Sat, 31 Mar 2012 06:48:24 +0700 Subject: [PATCH] Webadmin: edit listen ports --- include/znc/znc.h | 4 +- modules/data/webadmin/tmpl/settings.tmpl | 79 ++++++++++----- modules/webadmin.cpp | 122 +++++++++++++++++++++++ webskins/_default_/pub/_default_.css | 8 +- webskins/ice/pub/ice.css | 2 +- 5 files changed, 183 insertions(+), 32 deletions(-) diff --git a/include/znc/znc.h b/include/znc/znc.h index b663fc3f..43087c68 100644 --- a/include/znc/znc.h +++ b/include/znc/znc.h @@ -143,6 +143,8 @@ public: // Listener yummy CListener* FindListener(u_short uPort, const CString& BindHost, EAddrType eAddr); bool AddListener(CListener*); + bool AddListener(unsigned int uPort, const CString& sBindHost, bool bSSL, + EAddrType eAddr, CListener::EAcceptType eAccept, CString& sError); bool DelListener(CListener*); // Message of the Day @@ -178,8 +180,6 @@ private: CString MakeConfigHeader(); bool AddListener(const CString& sLine, CString& sError); bool AddListener(CConfig* pConfig, CString& sError); - bool AddListener(unsigned int uPort, const CString& sBindHost, bool bSSL, - EAddrType eAddr, CListener::EAcceptType eAccept, CString& sError); protected: time_t m_TimeStarted; diff --git a/modules/data/webadmin/tmpl/settings.tmpl b/modules/data/webadmin/tmpl/settings.tmpl index 1d12f9a2..027b8f31 100644 --- a/modules/data/webadmin/tmpl/settings.tmpl +++ b/modules/data/webadmin/tmpl/settings.tmpl @@ -10,35 +10,60 @@
- - - - - - - - - - - - - - - - - - - - - - - - - -
PortBindHostSSLIPv4IPv6IRCWeb
YesNoYesNoYesNoYesNoYesNo
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PortBindHostSSLIPv4IPv6IRCWeb +
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked"/>
checked="checked"/>
+ + + + + + + + + + +
+
-
diff --git a/modules/webadmin.cpp b/modules/webadmin.cpp index ab7e2959..099b4d0d 100644 --- a/modules/webadmin.cpp +++ b/modules/webadmin.cpp @@ -513,6 +513,20 @@ public: return TrafficPage(WebSock, Tmpl); } else if (sPageName == "index") { return true; + } else if (sPageName == "add_listener") { + // Admin Check + if (!spSession->IsAdmin()) { + return false; + } + + return AddListener(WebSock, Tmpl); + } else if (sPageName == "del_listener") { + // Admin Check + if (!spSession->IsAdmin()) { + return false; + } + + return DelListener(WebSock, Tmpl); } return false; @@ -1233,7 +1247,110 @@ public: return true; } + bool AddListener(CWebSock& WebSock, CTemplate& Tmpl) { + unsigned int uPort = WebSock.GetParam("port").ToUInt(); + CString sHost = WebSock.GetParam("host"); + if (sHost == "*") sHost = ""; + bool bSSL = WebSock.GetParam("ssl").ToBool(); + bool bIPv4 = WebSock.GetParam("ipv4").ToBool(); + bool bIPv6 = WebSock.GetParam("ipv6").ToBool(); + bool bIRC = WebSock.GetParam("irc").ToBool(); + bool bWeb = WebSock.GetParam("web").ToBool(); + + EAddrType eAddr = ADDR_ALL; + if (bIPv4) { + if (bIPv6) { + eAddr = ADDR_ALL; + } else { + eAddr = ADDR_IPV4ONLY; + } + } else { + if (bIPv6) { + eAddr = ADDR_IPV6ONLY; + } else { + WebSock.GetSession()->AddError("Choose either IPv4 or IPv6 or both."); + return SettingsPage(WebSock, Tmpl); + } + } + + CListener::EAcceptType eAccept; + if (bIRC) { + if (bWeb) { + eAccept = CListener::ACCEPT_ALL; + } else { + eAccept = CListener::ACCEPT_IRC; + } + } else { + if (bWeb) { + eAccept = CListener::ACCEPT_HTTP; + } else { + WebSock.GetSession()->AddError("Choose either IRC or Web or both."); + return SettingsPage(WebSock, Tmpl); + } + } + + CString sMessage; + if (CZNC::Get().AddListener(uPort, sHost, bSSL, eAddr, eAccept, sMessage)) { + if (!sMessage.empty()) { + WebSock.GetSession()->AddSuccess(sMessage); + } + if (!CZNC::Get().WriteConfig()) { + WebSock.GetSession()->AddError("Port changed, but config was not written"); + } + } else { + WebSock.GetSession()->AddError(sMessage); + } + + return SettingsPage(WebSock, Tmpl); + } + + bool DelListener(CWebSock& WebSock, CTemplate& Tmpl) { + map m = WebSock.GetParams(); + DEBUG("zzz"); + for (map::iterator i = m.begin(); i != m.end(); ++i) { + DEBUG("xxxxxxxxxxxxxxxxxxx[" << i->first << "]"); + for (VCString::iterator it = i->second.begin(); it != i->second.end(); ++it) { + DEBUG("yyyyyyyy[" << *it << "]"); + } + } + unsigned int uPort = WebSock.GetParam("port").ToUInt(); + CString sHost = WebSock.GetParam("host"); + bool bIPv4 = WebSock.GetParam("ipv4").ToBool(); + bool bIPv6 = WebSock.GetParam("ipv6").ToBool(); + + DEBUG("Port [" << WebSock.GetParam("port") << "]"); + + EAddrType eAddr = ADDR_ALL; + if (bIPv4) { + if (bIPv6) { + eAddr = ADDR_ALL; + } else { + eAddr = ADDR_IPV4ONLY; + } + } else { + if (bIPv6) { + eAddr = ADDR_IPV6ONLY; + } else { + WebSock.GetSession()->AddError("Invalid request."); + return SettingsPage(WebSock, Tmpl); + } + } + + CListener* pListener = CZNC::Get().FindListener(uPort, sHost, eAddr); + if (pListener) { + CZNC::Get().DelListener(pListener); + if (!CZNC::Get().WriteConfig()) { + WebSock.GetSession()->AddError("Port changed, but config was not written"); + } + } else { + WebSock.GetSession()->AddError("The specified listener was not found."); + } + + return SettingsPage(WebSock, Tmpl); + } + bool SettingsPage(CWebSock& WebSock, CTemplate& Tmpl) { + Tmpl.SetFile("settings.tmpl"); if (!WebSock.GetParam("submitted").ToUInt()) { CString sBindHosts, sMotd; Tmpl["Action"] = "settings"; @@ -1268,6 +1385,11 @@ public: l["IsWeb"] = CString(pListener->GetAcceptType() != CListener::ACCEPT_IRC); l["IsIRC"] = CString(pListener->GetAcceptType() != CListener::ACCEPT_HTTP); + // simple protection for user from shooting his own foot + // TODO check also for hosts/families + // such check is only here, user still can forge HTTP request to delete web port + l["SuggestDeletion"] = CString(pListener->GetPort() != WebSock.GetLocalPort()); + #ifdef HAVE_LIBSSL if (pListener->IsSSL()) { l["IsSSL"] = "true"; diff --git a/webskins/_default_/pub/_default_.css b/webskins/_default_/pub/_default_.css index 4d899a12..5ef898e8 100644 --- a/webskins/_default_/pub/_default_.css +++ b/webskins/_default_/pub/_default_.css @@ -247,14 +247,18 @@ input.third, textarea.third, width: 150px; } +input.number { + width: 40px; +} + table { border: 1px solid #ccc; border-spacing: 1px; } td, th { - padding: 5px 10px; - min-width: 50px; + padding: 5px 7px; + min-width: 35px; } thead td, th { diff --git a/webskins/ice/pub/ice.css b/webskins/ice/pub/ice.css index 29943090..b6747abb 100644 --- a/webskins/ice/pub/ice.css +++ b/webskins/ice/pub/ice.css @@ -92,7 +92,7 @@ table thead { thead td { font-size: 13px; border-bottom: 1px solid #000; - min-width: 50px; + min-width: 35px; } th {