Implement Redfish PasswordChangeRequired

This implements the Redfish PasswordChangeRequired handling.  See
section 13.3.7.1 "Password change required handling" in the 1.9.1 spec:
https://www.dmtf.org/sites/default/files/standards/documents/DSP0266_1.9.1.pdf

These portions of the spec are implemented:
 - Authenticatation with a correct but expired password creates a
   session:
    - The session is restricted to the ConfigureSelf privilege which
      allows a user to change their own password (via GET and PATCH
      Password for their own account).  Support for the ConfigureSelf
      privilege is already in BMCWeb.
    - The session object has the PasswordChangeRequired message.
 - All other operations respond with http status code 403 Forbidden
   and include the PasswordChangeRequired message.
 - The ManagerAccount (URI /redfish/v1/AccountService/Accounts/USER)
   PasswordChangeRequired property is implemented for local accounts
   but not present for remote accounts.

This has the following additional behavior:

The PasswordChangeRequired property is updated at the start of each new
REST operation, even within an existing session.  This behavior
implements a "dynamic" PasswordChangeRequired handling that responds to
changes to the underlying "password expired" status.  Specifically:
 - Sessions restricted by the PasswordChangeRequired handling lose that
   restriction when the underlying account password is changed.
 - Sessions become subject to the PasswordChangeRequired handling
   restrictions whenever the underlying account password expires.
 - The mechanism is to check if the password is expired at the start of
   every new REST API operation, effectively updating the ManagerAccount
   PasswordChangeRequired property each time.  This makes BMCWeb
   responsive to changes in the underlying account due to other activity
   on the BMC.

Notes:
1. Note that when an account password status is changed (for example,
   the password becomes expired or is changed) and that account has
   active sessions, those sessions remain.  They are not deleted.  Any
   current operations are allowed to complete.  Subsequent operations
   with that session pick up the new password status.

2. This does not implement OWASP recommendations which call for sessions
   to be dropped when there is a significant change to the underlying
   account.  For example, when the password is changed, the password
   becomes expired, or when the account's Role changes.  OWASP's
   recommendation is due to the session fixation vulnerability.  See the
   OWASP Session Management Cheat Sheet section "Renew the Session ID
   After Any Privilege Level Change":
   https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html#renew-the-session-id-after-any-privilege-level-change

   BMCWeb protects against session fixation vulnerabilities because it
   always regenerates new session IDs when successful authentication
   creates a new session.

3. Users authenticating via mTLS are not subject to the
   PasswordChangeRequired behavior because mTLS takes precedence over
   password-based authentication.

Tested:
0. Setup:
    - The `passwd --expire USERNAME` command was used to expire
      passwords.  The `chage USER` command was also used.
    - The following were used to change the password: Redfish API,
      passwd command, and the SSH password change dialog.
    - Tested the following via Basic Auth, /login, and Redfish login
      (except where Basic Auth does not create a persistent session).
    - Only local user account were tested.
    - Did not test authentication via mTLS or with LDAP users.
1. When the password is not expired, authentication behaves as usual
   for both correct and incorrect passwords.
2. When the password is incorrect and expired, authentication fails as
   usual.
3. When the password is correct but expired:
    A. A session is created and has the PasswordChangeRequired message.
    B. That session cannot access resources that require Login privilege
       and the 403 message contains the PasswordChangeRequired message.
    C. That session can be used to GET the user's account, PATCH the
       Password, and DELETE the session object.
    D. The account PasswordChangeRequired reports true.
4. While a session is established, try expiring and changing
   (unexpiring) the password using various mechanisms.  Ensure both the
   session object and the ManagerAccount PasswordChangeRequired property
   report the correct condition, and ensure PasswordChangeRequired
   handling (restricting operations to ConfigureSelf when
   PasswordChangeRequired is true) is applied correctly.

Signed-off-by: Joseph Reynolds <joseph-reynolds@charter.net>
Change-Id: Iedc61dea8f949e4b182e14dc189de02d1f74d3e8
9 files changed
tree: 7c91ca612d1af7f1afeba6cd47419fec41f85ffd
  1. cmake/
  2. http/
  3. include/
  4. redfish-core/
  5. scripts/
  6. src/
  7. static/
  8. .clang-format
  9. .gitignore
  10. bmcweb.service.in
  11. bmcweb.socket
  12. build_x86.sh
  13. cmake-format.json
  14. CMakeLists.txt
  15. CMakeLists.txt.in
  16. config.h.in
  17. DEVELOPING.md
  18. JenkinsFile
  19. LICENCE
  20. MAINTAINERS
  21. pam-webserver
  22. README.md
  23. Redfish.md
README.md

OpenBMC webserver

This component attempts to be a "do everything" embedded webserver for openbmc.

Capabilities

At this time, the webserver implements a few interfaces:

  • Authentication middleware that supports cookie and token based authentication, as well as CSRF prevention backed by linux PAM authentication credentials.
  • An (incomplete) attempt at replicating phosphor-dbus-rest interfaces in C++. Right now, a few of the endpoint definitions work as expected, but there is still a lot of work to be done. The portions of the interface that are functional are designed to work correctly for phosphor-webui, but may not yet be complete.
  • Replication of the rest-dbus backend interfaces to allow bmc debug to logged in users.
  • An initial attempt at a read-only redfish interface. Currently the redfish interface targets ServiceRoot, SessionService, AccountService, Roles, and ManagersService. Some functionality here has been shimmed to make development possible. For example, there exists only a single user role.
  • SSL key generation at runtime. See the configuration section for details.
  • Static file hosting. Currently, static files are hosted from the fixed location at /usr/share/www. This is intended to allow loose coupling with yocto projects, and allow overriding static files at build time.
  • Dbus-monitor over websocket. A generic endpoint that allows UIs to open a websocket and register for notification of events to avoid polling in single page applications. (this interface may be modified in the future due to security concerns.

Configuration

BMCWeb is configured by setting -D flags that correspond to options in bmcweb/CMakeLists.txt and then compiling. For example, cmake -DBMCWEB_ENABLE_KVM=NO ... followed by make. The option names become C++ preprocessor symbols that control which code is compiled into the program.

When BMCWeb starts running, it reads persistent configuration data (such as UUID and session data) from a local file. If this is not usable, it generates a new configuration.

When BMCWeb SSL support is enabled and a usable certificate is not found, it will generate a self-sign a certificate before launching the server. The keys are generated by the secp384r1 algorithm. The certificate

  • is issued by C=US, O=OpenBMC, CN=testhost,
  • is valid for 10 years,
  • has a random serial number, and
  • is signed using the SHA-256 algorithm.