From d08a4569ad2dbc68ad1f5797dc318ab4555559fb Mon Sep 17 00:00:00 2001 From: Alexander Filippov Date: Tue, 20 Mar 2018 12:02:23 +0300 Subject: Prevent users from logging in while BMC is not yet ready. Reject user logins while BMC_READY state has not been reached yet, and report the reason in response. Resolves: openbmc/openbmc#2974 This behavior may be enabled by appending `--with-bmc-check` to command line arguments. When it is enabled it maybe temporary disabled by sending `force` flag with the login request: ``` { "data": [ "username", "password" ], "force": true } ``` Tested: When trying to login in REST receiving response with code 503 while BMC is booting. Change-Id: I04fce09de2b7a3074b5253346a87773641fd57d0 Signed-off-by: Alexander Filippov --- module/obmc/wsgi/apps/rest_dbus.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'module/obmc/wsgi/apps') diff --git a/module/obmc/wsgi/apps/rest_dbus.py b/module/obmc/wsgi/apps/rest_dbus.py index ffbab94..bf4fe7c 100644 --- a/module/obmc/wsgi/apps/rest_dbus.py +++ b/module/obmc/wsgi/apps/rest_dbus.py @@ -15,6 +15,7 @@ # permissions and limitations under the License. import os +import sys import dbus import dbus.exceptions import json @@ -630,8 +631,13 @@ class SessionHandler(MethodHandler): no_user_str = "No user logged in" bad_json_str = "Expecting request format { 'data': " \ "[, ] }, got '%s'" + bmc_not_ready_str = "BMC is not ready (booting)" _require_auth = None MAX_SESSIONS = 16 + BMCSTATE_IFACE = 'xyz.openbmc_project.State.BMC' + BMCSTATE_PATH = '/xyz/openbmc_project/state/bmc0' + BMCSTATE_PROPERTY = 'CurrentBMCState' + BMCSTATE_READY = 'xyz.openbmc_project.State.BMC.BMCState.Ready' def __init__(self, app, bus): super(SessionHandler, self).__init__( @@ -696,6 +702,15 @@ class SessionHandler(MethodHandler): if not self.authenticate(*request.parameter_list): abort(401, self.bad_passwd_str) + force = False + try: + force = request.json.get('force') + except (ValueError, AttributeError, KeyError, TypeError): + force = False + + if not force and not self.is_bmc_ready(): + abort(503, self.bmc_not_ready_str) + user = request.parameter_list[0] session = self.new_session() session['user'] = user @@ -705,6 +720,22 @@ class SessionHandler(MethodHandler): httponly=True) return self.login_str % (user, 'in') + def is_bmc_ready(self): + if not self.app.with_bmc_check: + return True + + try: + obj = self.bus.get_object(self.BMCSTATE_IFACE, self.BMCSTATE_PATH) + iface = dbus.Interface(obj, dbus.PROPERTIES_IFACE) + state = iface.Get(self.BMCSTATE_IFACE, self.BMCSTATE_PROPERTY) + if state == self.BMCSTATE_READY: + return True + + except dbus.exceptions.DBusException: + pass + + return False + def find(self, **kw): pass @@ -1419,6 +1450,7 @@ class App(Bottle): super(App, self).__init__(autojson=False) self.have_wsock = kw.get('have_wsock', False) + self.with_bmc_check = '--with-bmc-check' in sys.argv self.bus = dbus.SystemBus() self.mapper = obmc.mapper.Mapper(self.bus) -- cgit v1.2.1