summaryrefslogtreecommitdiff
path: root/include
AgeCommit message (Collapse)AuthorFilesLines
2024-07-12Support RespondToUnauthenticatedClients PATCHEd Tanous4-19/+35
RespondToUnauthenticatedClients allows users to explicitly select mTLS as their only authentication mechanism, thus significantly reducing their code exposure to unauthenticated clients. From the Redfish specification ``` The RespondToUnauthenticatedClients property within the ClientCertificate property within the MFA property of the AccountService resource controls the response behavior when an invalid certificate is provided by the client. • If the property contains true or is not supported by the service, the service shall not fail the TLS handshake. This is to allow the service to send error messages or unauthenticated resources to the client. • If the property contains false , the service shall fail the TLS handshake. ``` This commit implements that behavior. This also has some added benefits in that we no longer have to check the filesystem for every connection, as TLS is controlled explicitly, and not whether or not a root cert is in place. Note, this also implements a TODO to disable cookie auth when using mTLS. Clients can still use IsAuthenticated to determine if they are authenticated on request. Tested: Run scripts/generate_auth_certs.py to set up a root certificate and client certificate. This verifies that mTLS as optional has not been broken. Script succeeds. ``` PATCH /redfish/v1/AccountService {"MultiFactorAuth": {"ClientCertificate": {"RespondToUnauthenticatedClients": false}}} ``` GET /redfish/v1 without a client certificate now fails with an ssl verification error GET /redfish/v1 with a client certificate returns the result ``` PATCH /redfish/v1/AccountService {"MultiFactorAuth": {"ClientCertificate": {"RespondToUnauthenticatedClients": false}}} With certificate returns non mTLS functionality. ``` Change-Id: I5a9d6d6b1698bff83ab62b1f760afed6555849c9 Signed-off-by: Ed Tanous <ed@tanous.net>
2024-07-12Store Request Fields that are needed laterEd Tanous5-46/+72
Because of recent changes to how dbus authentication is done, Requests might be moved out before they can be used. This commit is an attempt to mitigate the problem without needing to revert that patch. This commit does two relatively distinct things. First, it moves basic auth types to a model where they're timed out instead of removed on destruction. This removes the need for a Request object to track that state, and arguably gives better behavior, as basic auth sessions will survive through the timeout. To prevent lots of basic auth sessions getting created, a basic auth session is reused if it was: 1. Created by basic auth previously. 2. Created by the same user. 3. Created from the same source IP address. Second, both connection classes now store the accept, and origin headers from the request in the connection class itself, removing the need for them. Tested: HTML page now loads when pointing at a redfish URL with a browser. Change-Id: I623b43cbcbb43d9e65b408853660be09a5edb2b3 Signed-off-by: Ed Tanous <ed@tanous.net>
2024-07-11Mutual TLS parsing change at runtimeEd Tanous2-22/+89
Redfish AccountService[1] defines methods for selecting how to map a certificate CommonName attribute to a user. These are intended to be a patch parameter. This commit implements the Redfish defined schemas; The parsing mode is stored in the bmcweb persistent configuration file as an integer enum, with Mapping to the Redfish schema. To handle OEM specific parsing modes, an enum value of 100+ is defined to allow the additional OEM parameters. Unfortunately, Redfish doesn't have a way to represent these today, so those modes are currently not selectable at runtime. Now that things are runtime selectable, this obsoletes the option mutual-tls-common-name-parsing, as it is not longer required at compile time. Tested: GET /redfish/v1/AccountService returns MultiFactorAuth/ClientCertificate/CertificateMappingAttribute PATCH /redfish/v1/AccountService ``` {"MultiFactorAuth": {"ClientCertificate": {"CertificateMappingAttribute":"CommonName"}}} ``` Returns 200 [1] https://github.com/DMTF/Redfish-Publications/blob/5b217908b5378b24e4f390c063427d7a707cd308/csdl/AccountService_v1.xml#L1631 Change-Id: I67db0dfa5245a9da973320aab666d12dbd9229e4 Signed-off-by: Ed Tanous <ed@tanous.net>
2024-07-11Send cookies to webui-vue from Sessions POSTPaul Fertser3-18/+34
Using Redfish-standard X-Auth-Token authentication is less secure (against injected JS code) compared to an HttpOnly (not available to the JS VM) SESSION cookie. Currently webui-vue authenticates connections to WebSocket URIs not only by a JS-accessible token (passed as subprotocol when upgrading to WS) but also via a SESSION cookie (even though it is not subject to CORS policy). To allow WebSocket-based functionality (IP KVM, SOL, VM) after creating a Session object send a set of cookies instead of the X-Auth-Token header if the request was made by webui-vue (detected by presence of "X-Requested-With" header). Factor out cookie setting and clearing functions and use explicit Path=/ attribute as the cookies are valid for the whole server, not just the path of the endpoint they were created by. Not specifying Path was functional for /login endpoint because https://www.rfc-editor.org/rfc/rfc6265#section-5.3 point 7 for this case says "set the cookie's path to the default-path of the request-uri" and https://www.rfc-editor.org/rfc/rfc6265#section-5.1.4 tells how to compute the default path. Basically, it was a "happy coincidence" that /login defaults to / for the Path, if it was /openbmc/login then the cookies would have been set to Path=/openbmc and not work at all for /redfish/v1 endpoints. Tested: Redfish-Service-Validator doesn't see a difference. Runtime testing logging in via Sessions endpoint, getting data, using websockets and logging out against webui-vue with a corresponding change while carefully observing Request and Response headers. Creating a session with curl without the special header shows just X-Auth-Token and no cookies in the response. Change-Id: I0b1774e586671874bb79f115e9cddf194f9ea653 Signed-off-by: Paul Fertser <fercerpav@gmail.com>
2024-07-11Clean up static assetsEd Tanous1-144/+152
This file has several long lambdas, and some functions that should be broken down into smaller components. This is a refactor that should make no functional changes. Tested: Webui-vue loads correctly, shows static files are working as designed. Change-Id: Ie272a15fd935823743303c287a475114a734feb5 Signed-off-by: Ed Tanous <ed@tanous.net>
2024-07-01Fix returning Roles for Sessions POSTPaul Fertser1-33/+60
When the session is just getting created the normal privileges validation workflow isn't executed and so the current role remains unknown. Fix this by refactoring dbus_privileges.hpp to allow obtaining the information from phosphor-user-manager late in the request processing. Tested: Redfish Service Validator passes. Creating a session for local user: ``` $ curl -k -H "Content-Type: application/json" -X POST https://172.41.1.250:18080/redfish/v1/SessionService/Sessions -d '{"UserName":"root", "Password":"0penBmc"}' { "@odata.id": "/redfish/v1/SessionService/Sessions/lfFsCNjshV", "@odata.type": "#Session.v1_7_0.Session", "ClientOriginIPAddress": "172.40.1.4", "Description": "Manager User Session", "Id": "lfFsCNjshV", "Name": "User Session", "Roles": [ "Administrator" ], "UserName": "root" } ``` Creating a session for remote user mapped to Operator: ``` $ curl -k -H "Content-Type: application/json" -X POST https://172.41.1.250:18080/redfish/v1/SessionService/Sessions -d '{"UserName":ldap_sync", "Password":"ldap_password"}' { "@odata.id": "/redfish/v1/SessionService/Sessions/qVffc4ePJK", "@odata.type": "#Session.v1_7_0.Session", "ClientOriginIPAddress": "172.40.1.4", "Description": "Manager User Session", "Id": "qVffc4ePJK", "Name": "User Session", "Roles": [ "Operator" ], "UserName": "ldap_sync" } ``` Fixes: https://github.com/openbmc/bmcweb/issues/280 Fixes: ce22f6099e7e28ae26591348bf484ebedbc1ed42 Change-Id: If76c43563244e3819ee3fbc60d9df7f6a21c1fa3 Signed-off-by: Paul Fertser <fercerpav@gmail.com>
2024-06-25Remove nlohmann::json::items()Ed Tanous5-101/+170
nlohmann::json::items() throws an exception if the object in question is not a json object. This has the potential to cause problems, and isn't in line with the standard that we code against. Replace all uses of items with iterating the nlohmann::json::object_t. This adds a new error check for pulling the object_t out of the nlohmann::json object before each iteration, to ensure that we're handling errors. Tested: Redfish service validator passes. Change-Id: I2934c9450ec296c76544c2a7c5855c9b519eae7f Signed-off-by: Ed Tanous <ed@tanous.net>
2024-06-14Fix login webui failVinceChang66371-1/+1
WebUI cannot login cause by 38221509e6cc06a6897e8b9b2aa049a70c033840. The root URL ("/") represents the top-level directory of a website. Removing the trailing slash from the root URL could lead to incorrect representations. Therefore, add to check that the URL is not the root before removing the trailing slash. Fixes #279 Tested: Use Chrome to access https://${BMC_IP}. Success login WebUI. Change-Id: I19527ee785f550ba5aeafe6e94e8521ab508817c Signed-off-by: VinceChang6637 <vince_chang@aspeedtech.com>
2024-06-11ssl_key_handler: utilize ssl pathAndrew Geissler1-1/+1
A bug was found in CI where the server.pem was a directory vs. the expected file. Tested: - None, simple bug Change-Id: Ib0abafe34864f505e7c677457bae89e5aefca394 Signed-off-by: Andrew Geissler <geissonator@yahoo.com>
2024-06-10Break out random ID methodsEd Tanous2-58/+12
The method of creating a random ID from an openssl random generator of a particular length is something that is generally useful, and something we can write unit tests for. Add it. Tested: Redfish service validator login flows work correctly in redfish service validator. Change-Id: Ic3b58d33f1421f3eb39e2d57585958f87f6fb8ea Signed-off-by: Ed Tanous <ed@tanous.net>
2024-06-10MTLS Client: Enabling mtls support in http_clientAbhilash Raju1-52/+91
http_client currently does not uses mtls client certificates. This is a good feature for both authentication and authorization purpose. It will help external servers to trust the identity of bmc for better security.This patch will add MTLS client certificate support for bmcweb This is a needed feature to support secure redfish aggregation between BMCs. To support secure aggregation BMCs should be provisioned with CA signed certificate with an authorized username as the subject name field of the certificate. With the support of strong MTLS authentication from Bmcweb server we can use the MTLS path to enable secure redfish aggregation among BMCs. This can avoid complexities and extra API calls needed for token based approach. Tested by: Aggregation Test1: 1) Setup two instance of romulus qemu session at different ports.This will act as two BMCs 2) Installed CA root certificates at /etc/ssl/certs/authority in both BMCs 3) Installed server.pem and client.pem entity certificates signed by the root CA at /etc/ssl/certs/https folder in both BMCs 4) Enable aggregation for Bmcweb. 5) Fired several redfish queries to BMC1 Result Observed that the aggregation worked fine. User session created using username mentined in the CN field of certificate. Aggregation Test2: Followed same steps from Aggregation Test1 with modification in step 3 In step3 installed only the server.pem. Result Bmcweb ran as usual. But aggregation failed to collect resources from BMC2. No crash observed. Redfish Event Test: Subscribed for redfish events using test server. Fired redfish test events from BMC. Result: Events reached server successfully. Change-Id: Id8cccf9beec77da0f16adb72d52f3adf46347d06 Signed-off-by: Abhilash Raju <abhilash.kollam@gmail.com> Signed-off-by: Ed Tanous <etanous@nvidia.com>
2024-06-10Make cert generate for readonly directoriesEd Tanous2-90/+158
When run from a development PC, we shouldn't REQUIRE that the cert directory exists or is writable. This commit reworks the SSL cert generation to generate a string with the certification info, instead of writing it to disk and reading it back. This allows bmcweb to start up in read-only environments, or environments where there isn't access to the key information. Tested: Launching the application on a dev desktop without an ssl directory present no longer crashes. Change-Id: I0d44eb1ce8d298986c5560803ca2d72958d3707c Signed-off-by: Ed Tanous <ed@tanous.net>
2024-06-04Fix regression in metadataEd Tanous1-5/+10
Metadata payloads are no longer accessible without authentication due to a regression caused by 090ab8e1042e14f7e5e02572ae2a2102677f1f00. Add /redfish/v1/$metadata to the allow list, and use this as an opportunity to refactor the isOnAllowList() code and simplify it. Fixes #277 Tested: Redfish protocol validator $metadata tests now pass again. ``` curl -vvvv -k https://192.168.7.2/redfish/v1/\$metadata ``` Now succeeds. Change-Id: I0cc3492f6184b2cad3281b22535d5089709c16a4 Signed-off-by: Ed Tanous <etanous@nvidia.com>
2024-05-31Remove the last instances of json patternEd Tanous2-7/+6
In the past, we've tried to erradicate the use of nlohmann::json(initiatlizer_list<...>) because it bloats binary sizes, as every type is given a new nlohmann constructor. This commit hunts down the last few places where we call this. There is still 2 remaining in openbmc_dbus_rest after this, but those are variant accesses that are difficult to triage, and considering it's a less used api, they're left as is. Tested: WIP Change-Id: Iaac24584bb78bb238da69010b511c1d598bd38bc Signed-off-by: Ed Tanous <ed@tanous.net>
2024-05-28Generate metadata at runtimeEd Tanous1-0/+37
In the initial implementation of metadata indexing the bmc knew at compile time what schemas it could potentially publish. bmcweb took the approach of adding all schemas of all versions to the $metadata resource. Since that was made, two major changes have happened. First, Redfish has added significantly more versions of each schema, as well as significantly more schemas to the point where the metadata index is now 213KB. While this file compresses fairly well, the size is obvious from the large amount of time that redfish service validator takes to parse the schemas, compared to actually acquiring BMC redfish resources. Second, aggregation was added, where an aggregated Redfish service might implement any number of schemas, including OEM ones. In an effort to fix this, this patch takes the compile-time algorithm in update_schemas.py, and moves it into bmcweb itself, parsing the files on disk as needed on demand. This has some immediate benefits; First, is that now schemas can be potentially installed from anywhere, not only from within the bmcweb build, and they will be resolved at runtime. Second, patches that want to add support for a given schema need to only symlink the schema into the correct folder, without needing to rerun update_schemas.py. This saves time in review. Finally, this opens to door to reducing the schema versions present in the metadata to the unique set of only what this bmcweb instance, and its aggregated BMCs expose. Tested: Redfish service validator passes. Need A/B checking to verify the file is byte for byte the same. GET /redfish/v1/$metadata returns what looks like sane results, with a correct content-type. Unit tests require the use of TemporaryFileHandle, so that class is moved into a more general folder, outside of test/http. Change-Id: I326159099c6b6c4056023b2e173c5f074ed88ce1 Signed-off-by: Ed Tanous <ed@tanous.net>
2024-05-20Remove sessions on user password updateRavi Teja1-0/+14
When a user's password is changed, existing Redfish sessions for that user, created with the old password, continue to work. As per OWASP session management, "The session ID must be renewed or regenerated by the web application after any privilege level change within the associated user session... Common scenarios to consider include; password changes, permission changes, or switching from a regular user role to an administrator role within the web application." [1] https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html This commit removes existing user sessions when the user's password is changed. This commit leaves the current session in place though a new removeSessionsByUsernameExceptSession(). This commit doesn't completely get us fully to what owasp says but is a start. Tested: Create some users: ``` curl -k -v -X POST -H "Content-Type: application/json" \ https://$bmc/redfish/v1/AccountService/Accounts/ -d \ '{"UserName":"testadminuser","Password":"<password>","RoleId":"Administrator","Enabled":true}' ``` Using basic auth was able to update own password and another user's password. Using token auth, verified the current session did not get deleted but other sessions from that user did. ``` curl -k -H "Content-Type: application/json" -X POST -D headers.txt \ https://${bmc}/redfish/v1/SessionService/Sessions -d \ '{"UserName":"testadminuser", "Password":"<password>"}' ``` ``` curl -k -v -X PATCH -H "X-Auth-Token: $token" \ -H "Content-Type:application/json" \ https://$bmc/redfish/v1/AccountService/Accounts/testadminuser \ -d '{"Password":"<password>"}' ``` Verified when changing another user's password all sessions were dropped. Change-Id: I4de60b84964a6b29c021dc3a2bece9ed4bc09eac Signed-off-by: Ravi Teja <raviteja28031990@gmail.com>
2024-05-17Fix mounting in proxy mode in virtual mediaBoleslaw Ogonczyk Makowski1-4/+12
Broken by [1], interface and path were incorrect after changing getManagedObjects to getAllProperties. Tested: Mounting in proxy mode works [1]: https://github.com/openbmc/bmcweb/commit/e4b32753a7ce7ca436bf751f390ee01f02b9efd5 Change-Id: I06f36e8fc864fe13200d5d13a12639ebba9d9be1 Signed-off-by: Boleslaw Ogonczyk Makowski <boleslawx.ogonczyk-makowski@intel.com>
2024-05-15Check sizeEd Tanous1-3/+4
Static analysis flags that we're ignoring a return value here. Use it. Tested: Code compiles. Change-Id: I2b37286b5a7b549b483ed5669fa0c24a628adc98 Signed-off-by: Ed Tanous <ed@tanous.net>
2024-05-13Last fix for inversionEd Tanous1-1/+1
CSRF option got inverted. Fix it. Tested: Code compiles. Change-Id: Ibfc56ef2ce8d065aa7dad836e3d4a5edc5632926 Signed-off-by: Ed Tanous <ed@tanous.net>
2024-05-11Remove reserveEd Tanous1-5/+0
This is flagging static analysis issues, because we don't reserve a quadraticly sized increment. This is a micro optimization that never made much sense. Tested: Old code. Inspection only. Change-Id: I442628751558616c24123dba66aab448a4c24039 Signed-off-by: Ed Tanous <ed@tanous.net>
2024-05-09Fix merge conflict in sessionEd Tanous1-0/+1
9f217c26f58c0a99c18e7cac7b095dcf6068562d had a merge conflict that was resolved incorrectly with 25b54dba775b31021a3a4677eb79e9771bcb97f7 The line returning the cookie session got dropped in that merge conflict. Restore it. Tested: Webui can log in, and cookie auth works again. Ideally in the future we'd have some tests for places like this where we've gone outside the redfish spec. Change-Id: I7740e19dac4d0dae5c5c9b27a5b8699a4751fd6f Signed-off-by: Ed Tanous <ed@tanous.net>
2024-05-09std::remove to std::filesystem::removeEd Tanous1-1/+3
Change-Id: Ie7729554e438f3af9ddb58941297525c50c6b419 Signed-off-by: Ed Tanous <ed@tanous.net>
2024-05-09Check return codesEd Tanous1-2/+10
Static analysis finds these two places that we don't check error codes. Check them. Tested: Deprecated code. Inspection only. Change-Id: I92c238c5a4b1f51c5c6855c59f4f943855c4e50f Signed-off-by: Ed Tanous <ed@tanous.net>
2024-05-07Move logging argsEd Tanous2-2/+0
Args captured by logging functions should be captured by rvalue, and use std::forward to get perfect forwarding. In addition, separate out the various std::out lines. While we're here, also try to optimize a little. We should ideally be writing each log line to the output once, and ideally not use iostreams, which induce a lot of overhead. Similar to spdlog[1] (which at one point this codebase used), construct the string, then call fwrite and fflush once, rather than calling std::cout repeatedly. Now that we don't have a dependency on iostreams anymore, we can remove it from the places where it has snuck in. Tested: Logging still functions as before. Logs present. [1] https://github.com/gabime/spdlog/blob/27cb4c76708608465c413f6d0e6b8d99a4d84302/include/spdlog/sinks/stdout_sinks-inl.h#L70C7-L70C13 Change-Id: I1dd4739e06eb506d68989a066d122109b71b92cd Signed-off-by: Ed Tanous <ed@tanous.net>
2024-05-04obmc_console: Fix some missing headersGunnar Mills1-0/+6
Fix some obvious missed headers. Tested: It builds, no other testing. Change-Id: I8cfd95e16eca38c75dcf76fc974ed384d13c6757 Signed-off-by: Gunnar Mills <gmills@us.ibm.com>
2024-05-03Manage Request with shared_ptrJonathan Doman1-17/+18
This is an attempt to solve a class of use-after-move bugs on the Request objects which have popped up several times. This more clearly identifies code which owns the Request objects and has a need to keep it alive. Currently it's just the `Connection` (or `HTTP2Connection`) (which needs to access Request headers while sending the response), and the `validatePrivilege()` function (which needs to temporarily own the Request while doing an asynchronous D-Bus call). Route handlers are provided a non-owning `Request&` for immediate use and required to not hold the `Request&` for future use. Tested: Redfish validator passes (with a few unrelated fails). Redfish URLs are sent to a browser as HTML instead of raw JSON. Change-Id: Id581fda90b6bceddd08a5dc7ff0a04b91e7394bf Signed-off-by: Jonathan Doman <jonathan.doman@intel.com> Signed-off-by: Ed Tanous <ed@tanous.net>
2024-05-01Bring consistency to config optionsEd Tanous5-100/+67
The configuration options that exist in bmcweb are an amalgimation of CROW options, CMAKE options using #define, pre-bmcweb ifdef mechanisms and meson options using a config file. This history has led to a lot of different ways to configure code in the codebase itself, which has led to problems, and issues in consistency. ifdef options do no compile time checking of code not within the branch. This is good when you have optional dependencies, but not great when you're trying to ensure both options compile. This commit moves all internal configuration options to: 1. A namespace called bmcweb 2. A naming scheme matching the meson option. hyphens are replaced with underscores, and the option is uppercased. This consistent transform allows matching up option keys with their code counterparts, without naming changes. 3. All options are bool true = enabled, and any options with _ENABLED or _DISABLED postfixes have those postfixes removed. (note, there are still some options with disable in the name, those are left as-is) 4. All options are now constexpr booleans, without an explicit compare. To accomplish this, unfortunately an option list in config/meson.build is required, given that meson doesn't provide a way to dump all options, as is a manual entry in bmcweb_config.h.in, in addition to the meson_options. This obsoletes the map in the main meson.build, which helps some of the complexity. Now that we've done this, we have some rules that will be documented. 1. Runtime behavior changes should be added as a constexpr bool to bmcweb_config.h 2. Options that require optionally pulling in a dependency shall use an ifdef, defined in the primary meson.build. (note, there are no options that currently meet this class, but it's included for completeness.) Note, that this consolidation means that at configure time, all options are printed. This is a good thing and allows direct comparison of configs in log files. Tested: Code compiles Server boots, and shows options configured in the default build. (HTTPS, log level, etc) Change-Id: I94e79a56bcdc01755036e4e7278c7e69e25809ce Signed-off-by: Ed Tanous <ed@tanous.net>
2024-04-30Fix bad merge conflictEd Tanous1-11/+2
nbd proxy and vm websocket options got reversed in 36c0f2a35e670a4b798b7b42fd18455085e9d9c0 Change them back. Change-Id: I7c54e66f88aee956bd20f2139d110e64998a4ef5 Signed-off-by: Ed Tanous <ed@tanous.net>
2024-04-30Break out lambdas into real methodsEd Tanous1-156/+144
Tested: Need help Change-Id: I28cc1626212ec746b5345490ec285706eb386e65 Signed-off-by: Ed Tanous <ed@tanous.net>
2024-04-30Consolidate Vm implementationsEd Tanous2-426/+434
As much as the two vm implementations SEEM different, the differences largely lie in how we're getting the nbd proxy socket. One is relying on launching a process (nbd-proxy), the other is getting the fd from dbus. Given [1] exists and is in process, we need to have a plan for getting these two VM implementations into one, once that patchset is complete. This commit: Splits the vm-websocket option into vm-websocket-provider, providing two options, nbd-proxy, and virtual-media (the names of the respective apps). To accomplish this, it moves the contents of nbd-proxy into include/vm-websocket, so we can compare the similarities and start consolidating. The longer term intent is that the nbd-proxy option will be completely removed, and the code deleted. This has the additional advantage that we will no longer require the boost::process dependency, as all info will be available on dbus. As part of this, the nbd proxy websocket is also registered at /vm/0/0, to be backward compatible with the old interfaces. Tested: Code compiles. Need some help here. [1] https://gerrit.openbmc.org/c/openbmc/jsnbd/+/49944 Change-Id: Iedbca169ea40d45a8775f843792b874a248bb594 Signed-off-by: Ed Tanous <ed@tanous.net>
2024-04-29Break out formattersEd Tanous4-0/+105
In the change made to move to std::format, we defined some custom type formatters in logging.hpp. This had the unintended effect of making all compile units pull in the majority of boost::url, and nlohmann::json as includes. This commit breaks out boost and json formatters into their own separate includes. Tested: Code compiles. Logging changes only. Change-Id: I6a788533169f10e19130a1910cd3be0cc729b020 Signed-off-by: Ed Tanous <ed@tanous.net>
2024-04-27Add static webpack etag supportEd Tanous2-4/+67
Webpack (which is what vue uses to compress its HTML) is capable of generating hashes of files when it produces the dist files[1]. This gets generated in the form of <filename>.<hash>.<extension> This commit attempts to detect these patterns, and enable etag caching to speed up webui load times. It detects these patterns, grabs the hash for the file, and returns it in the Etag header[2]. The behavior is implemented such that: If the file has an etag, the etag header is returned. If the request has an If-None-Match header, and that header matches, only 304 is returned. Tested: Tests were run on qemu S7106 bmcweb with default error logging level, and HTTP/2 enabled, along with svg optimization patches. Run scripts/generate_auth_certificate.py to set up TLS certificates. (valid TLS certs are required for HTTP caching to work properly in some browsers). Load the webui. Note that DOM load takes 1.10 seconds, Load takes 1.10 seconds, and all requests return 200 OK. Refresh the GUI. Note that most resources now return 304, and DOM time is reduced to 279 milliseconds and load is reduced to 280 milliseconds. DOM load (which is what the BMC has control over) is decreased by a factor of 3-4X. Setting chrome to "Fast 5g" throttling in the network tab shows a more pronounced difference, 1.28S load time vs 3.96S. BMC also shows 477KB transferred on the wire, versus 2.3KB transferred on the wire. This has the potential to significantly reduce the load on the BMC when the webui refreshes. [1] https://webpack.js.org/guides/caching/ [2] https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag Change-Id: I68aa7ef75533506d98e8fce10bb04a494dc49669 Signed-off-by: Ed Tanous <ed@tanous.net>
2024-04-27Move to process v2Ed Tanous2-17/+30
Boost process v2 brings some significant benefits to our launching of processes[1]. In bmcweb terms: 1. The code is radically simpler, which decreaeses compile times, and reduces the scope for code scanning tools. 2. The code now uses standard asio pipes instead of inventing its own. 3. Separate compilation. Tested: We don't have a lot of unit tests for the virtual media stuff that I can run, but we do have unit tests for credentials pipe, which in this change have been ported over, so the feature works. Unit tests are passing. [1] https://www.boost.org/doc/libs/1_80_0/doc/html/boost_process/v2.html#boost_process.v2.introduction Change-Id: Ia20226819d75ff6e492f8852185f0b73e8f5cf83 Signed-off-by: Ed Tanous <ed@tanous.net>
2024-04-26Make cookie auth check all headersEd Tanous1-43/+48
Currently, the Cookie auth only checks the first cookie header in a request. This works fine for most things, because a lot of implementations (browsers) seem to either put the Cookie headers in alphabetical order, or put them in the order in which they were stored which in the case of bmcweb, is also alphabetical. Well, http2 blows this up, because cookies could potentially be in any order, given the hpack compression techniques, so there's no promise that Cookie[0] is the Session cookie. This commit reworks the authentication code to call beasts "equal_range" getter, which returns the range of all headers that matched. This allows us to attempt to parse the cookies in whatever order they might have been received. The auth routine only tries to log in the first cookie matching SESSION=, and do not try to handle duplicates, as this might allow attackers to negate the anti brute force measures by testing multiple passwords at once Tested: With http2 enabled, the UI can now log in more consistently, and in addition, the HTML redfish pages function more consistently when using cookie auth. Redfish service validator passes. Change-Id: I3a61a5a654f62096ff19cfbfaf0a10f30a1a3605 Signed-off-by: Ed Tanous <ed@tanous.net>
2024-04-23Remove XSS prevention codeEd Tanous2-65/+14
This feature was created for a time before webpack had a built in proxy, and to debug the UI required setting specific flags. The webpack proxy solves this problem in a much better way, by proxying everything. This commit is one piece in the solving a use after free bug. Removing this allows us to no longer have to cache the origin header [1], which is only used in this mode. Tested: Code compiles. [1] https://gerrit.openbmc.org/c/openbmc/bmcweb/+/70850 Change-Id: I01d67006e217c0c9fd2db7526c0ec34b0da068f3 Signed-off-by: Ed Tanous <ed@tanous.net>
2024-04-23Implement a Content-Security-Policy TODOEd Tanous1-83/+82
This TODO has been in bmcweb for a very long time. Implement it. W3 sets rules for what security policies apply to which content types[1]. Reading through this, essentially CSP should only apply to HTML files. Tested: Unit tests pass. Webui loads properly. Chrome network window Shows headers show up as expected. [1] https://www.w3.org/TR/CSP2/#which-policy-applies Change-Id: I5467d0373832668763c72a66da2a8872e07bfb58 Signed-off-by: Ed Tanous <ed@tanous.net>
2024-04-19Add missing headersEd Tanous3-4/+1
Most of these were found by breaking every redfish class handler into its own compile unit: When that's done, these missing headers become compile errors. We should just fix them. In addition, this allows us to enable automatic header checking in clang-tidy using misc-header-cleaner. Because the compiler can now "see" all the defines, it no longer tries to remove headers that it thinks are unused. [1] https://github.com/openbmc/bmcweb/commit/4fdee9e39e9f03122ee16a6fb251a380681f56ac Tested: Code compiles. Change-Id: Ifa27ac4a512362b7ded7cc3068648dc4aea6ad7b Signed-off-by: Ed Tanous <ed@tanous.net>
2024-04-18Remove ibm locks featureSunitha Harish3-958/+1
This feature was introduced to manage the operation sync at BMC while multiple clients manage the BMC. This feature scope has gone away and it is not a simple code to maintain as per the growing standards of bmcweb. This commit removes the feature from this repo. Tested by: Locks routes are not available anymore Change-Id: I257225cfb1f43d7d5dadb21a28a2ee5345c5112a Signed-off-by: Sunitha Harish <sunithaharish04@gmail.com> Signed-off-by: Ed Tanous <ed@tanous.net>
2024-04-18Clean up BMCWEB_ENABLE_SSLEd Tanous1-2/+0
This macro came originally from CROW_ENABLE_SSL, and was used as a macro to optionally compile without openssl being required. OpenSSL has been pulled into many other dependencies, and has been functionally required to be included for a long time, so there's no reason to hold onto this macro. Remove most uses of the macro, and for the couple functional places the macro is used, transition to a constexpr if to enable the TLS paths. This allows a large simplification of code in some places. Tested: Redfish service validator passes. Change-Id: Iebd46a68e5e417b6031479e24be3c21bef782f4c Signed-off-by: Ed Tanous <ed@tanous.net>
2024-04-16Remove OpenSSL warnings ignoreEd Tanous2-1/+4
If we include OpenSSL in extern "C" blocks consistently, c++ warnings no longer appear. This means we can remove the special case from meson. Tested: Code compiles when built locally on an ubuntu 22.04 system. Change-Id: I5add4113b32cd88b7fdd874174c845425a7c287a Signed-off-by: Ed Tanous <ed@tanous.net>
2024-04-13Fix nullptr failures for image uploadEd Tanous1-0/+6
Several places that call *req.ioService were missing nullptr checks. Add them, and fix the one case where it might not be filled in. Tested: With HTTP2 enabled, the following command succeeds. ``` curl -k https://192.168.7.2/redfish/v1/UpdateService/update -F 'UpdateParameters={"Targets":["/redfish/v1/Managers/bmc"]} ;type=application/json' --user "root:0penBmc" -F UpdateFile=@/home/ed/bmcweb/16mb.txt -v -H "Expect:" ``` Change-Id: I81e7944c22f5922d461bf5d231086c7468a16e62 Signed-off-by: Ed Tanous <ed@tanous.net>
2024-04-11Fix file removalEd Tanous2-3/+13
This code used std::remove, which is a mechanism for removing characters from strings. Clearly it meant std::filesystem::remove(), which removes files from the filesystem. Correct it. Change-Id: I030966203c1682a11c723c596accdf34637dd1ba Signed-off-by: Ed Tanous <ed@tanous.net>
2024-04-11Fix buffer_copyEd Tanous3-10/+11
boost::asio::buffer_copy returns an integer of the number of values copied. Some static analysis tools mark that value as nodiscard, although it should never fail. Audit all uses of buffer_copy, and make sure that they're using the return value. In theory this should have no change on the behavior. Change-Id: I6af39b5347954c2932cf3d4e48e96ff9ae01583a Signed-off-by: Ed Tanous <ed@tanous.net>
2024-04-11Fix large copies with url_view and segments_viewEd Tanous1-0/+1
Despite these objects being called "view" they are still relatively large, as clang-tidy correctly flags, and we ignore. Change all function uses to capture by: const boost::urls::url_view_base& Which is the base class of all boost URL types, and any class (url, url_view, etc) is convertible to that base. Change-Id: I8ee2ea3f4cfba38331303a7e4eb520a2b6f8ba92 Signed-off-by: Ed Tanous <ed@tanous.net>
2024-04-11Simplify routerEd Tanous2-2/+0
Now that we only support string types in the router we no longer need to build a "Tag" to be used for constructing argument types. Now, we can just track the number of arguments, which simplifies the code significantly, and removes the need to convert to and from the tag to parameter counts. This in turn deletes a lot of code in the router, removing the need for tracking tag types. Tested: Redfish service validator passes. Unit tests pass. Change-Id: Ide1d665dc1984552681e8c05952b38073d5e32dd Signed-off-by: Ed Tanous <ed@tanous.net>
2024-04-10Move run and redfish to compile unitsEd Tanous1-0/+3
Meson supports unity builds[1] natively. There's no reason to continue with the pseudo unity build we've been using by putting implementations in header files. This commit is the first in a long series of starting to break this up into smaller compile units, in the hopes of dropping incremental compile times for developers, and reduce the total per-core memory usage that gcc requires. This commit breaks out the run() function from main() and the constructor of RedfishService from redfish.hpp into their own compile units. According to tracing, even after broken out, these are still by far the two longest to compile units in the build. Tested: Code compiles. Debug build on a 24 core build server results in a decrease in compile time for compiling just bmcweb from 1m38s to 1m22s. [1] https://mesonbuild.com/Unity-builds.html Change-Id: Ibf352e8aba61d64c9a41a7a76e94ab3b5a0dde4b Signed-off-by: Ed Tanous <ed@tanous.net>
2024-04-07Fix moves/forwardEd Tanous4-6/+5
Clang has new checks for std::move/std::forward correctness, which catches quite a few "wrong" things where we were making copies of callback handlers. Unfortunately, the lambda syntax of callback{std::forward<Callback>(callback)} in a capture confuses it, so change usages to callback = std::forward<Callback>(callback) to be consistent. Tested: Redfish service validator passes. Change-Id: I7a111ec00cf78ecb7d5f5b102c786c1c14d74384 Signed-off-by: Ed Tanous <ed@tanous.net>
2024-04-03Call dump() lessEd Tanous1-4/+1
nlohmann::json::dump() is not an easy function to get the call parameters correct on. We should limit the places we use it. Luckily, both logging and redfish::messages support printing json values directly. Use them where appropriate. Tested: Error logging and out of range calls only of heavily used messages and logging calls. Inspection only. Change-Id: I57521d8791dd95250c93e8e3b2d4a959740ac713 Signed-off-by: Ed Tanous <ed@tanous.net>
2024-04-01Fix redundant inline operatorsEd Tanous1-1/+1
inline is not required on member methods. Clang-tidy has a check for this. Enable the check and fix the two bad usages. Tested: Code compiles. Change-Id: I3115b7c0c4005e1082e0005b818fbe6569511f49 Signed-off-by: Ed Tanous <ed@tanous.net>
2024-04-01Use no-switch-default on clangEd Tanous1-0/+2
clang-18 improves this check so that we can actually use it. Enable it and fix all violations. Change-Id: Ibe4ce19c423d447a4cbe593d1abba948362426af Signed-off-by: Ed Tanous <ed@tanous.net>