From 35a18bd0b2b5b02631c5fefdbeeb1e7ad57125d4 Mon Sep 17 00:00:00 2001 From: MuxZeroNet Date: Mon, 22 May 2017 09:13:45 +0000 Subject: [PATCH] Weak password warning (#938) * Weak password warning * Update UiWebsocket.py * Don't implement print with an O(n^2) iteration * Rename method * Fix logging, uncaught exception in addNotes and pushes a notification when UI server is bound to the whole Internet. * Remove memo comments. Remove terminal hue. --- .../disabled-UiPassword/UiPasswordPlugin.py | 26 +++- src/Ui/UiWebsocket.py | 117 +++++++++++------- 2 files changed, 95 insertions(+), 48 deletions(-) diff --git a/plugins/disabled-UiPassword/UiPasswordPlugin.py b/plugins/disabled-UiPassword/UiPasswordPlugin.py index a0e42e81..7b4b2834 100644 --- a/plugins/disabled-UiPassword/UiPasswordPlugin.py +++ b/plugins/disabled-UiPassword/UiPasswordPlugin.py @@ -11,6 +11,14 @@ if "sessions" not in locals().keys(): # To keep sessions between module reloads sessions = {} +def showPasswordAdvice(password): + error_msgs = [] + if not password or not isinstance(password, (str, unicode)): + error_msgs.append("You have enabled UiPassword plugin, but you forgot to set a password!") + elif len(password) < 8: + error_msgs.append("You are using a very short UI password!") + return error_msgs + @PluginManager.registerTo("UiRequest") class UiRequestPlugin(object): sessions = sessions @@ -57,13 +65,10 @@ class UiRequestPlugin(object): yield template def checkPassword(self, password): - if password == config.ui_password: - return True - else: - return False + return password == config.ui_password - def randomString(self, chars): - return ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for _ in range(chars)) + def randomString(self, nchars): + return ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits) for _ in range(nchars)) @classmethod def cleanup(cls): @@ -97,6 +102,7 @@ class UiRequestPlugin(object): yield "Error: Invalid session id" + @PluginManager.registerTo("ConfigPlugin") class ConfigPlugin(object): def createArguments(self): @@ -106,6 +112,7 @@ class ConfigPlugin(object): return super(ConfigPlugin, self).createArguments() +from Translate import translate as lang @PluginManager.registerTo("UiWebsocket") class UiWebsocketPlugin(object): def actionUiLogout(self, to): @@ -116,3 +123,10 @@ class UiWebsocketPlugin(object): session_id = self.request.getCookies().get("session_id", "") message = "" % session_id self.cmd("notification", ["done", message]) + + def addHomepageNotifications(self): + error_msgs = showPasswordAdvice(config.ui_password) + for msg in error_msgs: + self.site.notifications.append(["error", lang[msg]]) + + return super(UiWebsocketPlugin, self).addHomepageNotifications() diff --git a/src/Ui/UiWebsocket.py b/src/Ui/UiWebsocket.py index ea65d567..495bac88 100644 --- a/src/Ui/UiWebsocket.py +++ b/src/Ui/UiWebsocket.py @@ -48,52 +48,21 @@ class UiWebsocket(object): file_server = sys.modules["main"].file_server if file_server.port_opened is None or file_server.tor_manager.start_onions is None: self.site.page_requested = False # Not ready yet, check next time - elif file_server.port_opened is True: - self.site.notifications.append([ - "done", - _["Congratulation, your port {0} is opened.
You are full member of ZeroNet network!"].format(config.fileserver_port), - 10000 - ]) - elif config.tor == "always" and file_server.tor_manager.start_onions: - self.site.notifications.append([ - "done", - _(u""" - {_[Tor mode active, every connection using Onion route.]}
- {_[Successfully started Tor onion hidden services.]} - """), - 10000 - ]) - elif config.tor == "always" and file_server.tor_manager.start_onions is not False: - self.site.notifications.append([ - "error", - _(u""" - {_[Tor mode active, every connection using Onion route.]}
- {_[Unable to start hidden services, please check your config.]} - """), - 0 - ]) - elif file_server.port_opened is False and file_server.tor_manager.start_onions: - self.site.notifications.append([ - "done", - _(u""" - {_[Successfully started Tor onion hidden services.]}
- {_[For faster connections open {0} port on your router.]} - """).format(config.fileserver_port), - 10000 - ]) else: - self.site.notifications.append([ - "error", - _(u""" - {_[Your connection is restricted. Please, open {0} port on your router]}
- {_[or configure Tor to become full member of ZeroNet network.]} - """).format(config.fileserver_port), - 0 - ]) + try: + self.addHomepageNotifications() + except Exception, err: + self.log.error("Uncaught Exception: " + Debug.formatException(err)) for notification in self.site.notifications: # Send pending notification messages + # send via WebSocket self.cmd("notification", notification) + # just in case, log them to terminal + if notification[0] == "error": + self.log.error("\n*** %s\n" % self.dedent(notification[1])) + self.site.notifications = [] + while True: try: message = ws.receive() @@ -107,7 +76,71 @@ class UiWebsocket(object): if config.debug: # Allow websocket errors to appear on /Debug sys.modules["main"].DebugHook.handleError() self.log.error("WebSocket handleRequest error: %s \n %s" % (Debug.formatException(err), message)) - self.cmd("error", "Internal error: %s" % Debug.formatException(err, "html")) + if not self.hasPlugin("Multiuser"): + self.cmd("error", "Internal error: %s" % Debug.formatException(err, "html")) + + def dedent(self, text): + return re.sub("[\\r\\n\\x20\\t]+", " ", text.strip().replace("
", " ")) + + def addHomepageNotifications(self): + if not(self.hasPlugin("Multiuser")) and not(self.hasPlugin("UiPassword")): + bind_ip = getattr(config, "ui_ip", "") + whitelist = getattr(config, "ui_restrict", []) + # binds to the Internet, no IP whitelist, no UiPassword, no Multiuser + if ("0.0.0.0" == bind_ip or "*" == bind_ip) and (not whitelist): + self.site.notifications.append([ + "error", + _(u"You are not going to set up a public gateway. However, your Web UI is
" + \ + "open to the whole Internet.
" + \ + "Please check your configuration.") + ]) + + file_server = sys.modules["main"].file_server + if file_server.port_opened is True: + self.site.notifications.append([ + "done", + _["Congratulation, your port {0} is opened.
You are full member of ZeroNet network!"].format(config.fileserver_port), + 10000 + ]) + elif config.tor == "always" and file_server.tor_manager.start_onions: + self.site.notifications.append([ + "done", + _(u""" + {_[Tor mode active, every connection using Onion route.]}
+ {_[Successfully started Tor onion hidden services.]} + """), + 10000 + ]) + elif config.tor == "always" and file_server.tor_manager.start_onions is not False: + self.site.notifications.append([ + "error", + _(u""" + {_[Tor mode active, every connection using Onion route.]}
+ {_[Unable to start hidden services, please check your config.]} + """), + 0 + ]) + elif file_server.port_opened is False and file_server.tor_manager.start_onions: + self.site.notifications.append([ + "done", + _(u""" + {_[Successfully started Tor onion hidden services.]}
+ {_[For faster connections open {0} port on your router.]} + """).format(config.fileserver_port), + 10000 + ]) + else: + self.site.notifications.append([ + "error", + _(u""" + {_[Your connection is restricted. Please, open {0} port on your router]}
+ {_[or configure Tor to become full member of ZeroNet network.]} + """).format(config.fileserver_port), + 0 + ]) + + def hasPlugin(self, name): + return name in PluginManager.plugin_manager.plugin_names # Has permission to run the command def hasCmdPermission(self, cmd):