Add content type check in the update service

The content type check is required in the update service. This may be a
security issue.

The correct content types to update service are multipart/form-data and
application/octet-stream. The multipart content type was missing from
the contentTypes array which is added in this drop.

Added couple of test cases.

Tested:

1) Make sure that update service content type
   application/octet-stream are working correctly.
$ curl -k -H 'X-Auth-Token: THIbp1G0DiNVj3JrCZMf' -H 'Content-Type:  \
  application/octet-stream' -X POST   \
  -T ./obmc-phosphor-image-everest.ext4.mmc.tar  \
  https://${bmc}/redfish/v1/UpdateService/update
{
  "@odata.id": "/redfish/v1/TaskService/Tasks/0",
  "@odata.type": "#Task.v1_4_3.Task",
  "Id": "0",
  "TaskState": "Running",
  "TaskStatus": "OK"

2) Make sure that update service content type
  multipart/form-data are working correctly.
$ curl -k -H 'X-Auth-Token: Vc7KBgM6z3uMs1G7uVqu'                      \
  -H Content-Type:multipart/form-data                                  \
  -F 'UpdateParameters={"Targets":["/redfish/v1/Managers/bmc"],        \
      "@Redfish.OperationApplyTime":"Immediate"};type=application/json'\
  -F 'UpdateFile=@obmc-phosphor-image-p10bmc.ext4.mmc.tar;             \
      type=application/octet-stream'                                   \
  https://${bmc}/redfish/v1/UpdateService/update
{
  "@Message.ExtendedInfo": [
    {
      "@odata.type": "#Message.v1_1_1.Message",
      "Message": "The request completed successfully.",
      "MessageArgs": [],
      "MessageId": "Base.1.16.0.Success",
      "MessageSeverity": "OK",
      "Resolution": "None"
    }
  ],
  "@odata.id": "/redfish/v1/TaskService/Tasks/0",
  "@odata.type": "#Task.v1_4_3.Task",
  "Id": "0",
  "TaskState": "Running",
  "TaskStatus": "OK"

3) Make sure that command fails when content type is missing.
$ curl -k -H 'X-Auth-Token: vH3B88sh323sfy0YG8eN' -H Content-Type: \
  -X POST -T ./obmc-phosphor-image-everest.ext4.mmc.tar \
  https://${bmc}/redfish/v1/UpdateService/update
Bad Request

[INFO "http_connection.hpp":201] Request:  0x177f920 HTTP/1.1 POST \
/redfish/v1/UpdateService/update ::ffff:x.x.xx.xxx
                                |
[DEBUG "update_service.hpp":687] doPost: contentType=
[DEBUG "update_service.hpp":692] Bad content type specified:

4) Make sure that command fails when wrong cotent type specified.
$ curl -k -H 'X-Auth-Token: OQzODMaR0G29AjpD2YmT' -H 'Content-Type: \
  application/octet-json' -X POST \
  -T ./obmc-phosphor-image-everest.ext4.mmc.tar \
  https://${bmc}/redfish/v1/UpdateService/update
Bad Request

[INFO "http_connection.hpp":201] Request:  0x17a69d0 HTTP/1.1 POST \
/redfish/v1/UpdateService/update ::ffff:x.x.xx.xxx
                    |
[DEBUG "update_service.hpp":687] doPost:
    contentType=application/octet-json
[DEBUG "update_service.hpp":720] Bad content type specified:
    application/octet-json

5) Make sure that command fails when header is not specified.
$ curl -k -H 'X-Auth-Token: Z1AEXg075qGKi0xISu6o' -X POST \
-T ./obmc-phosphor-image-everest.ext4.mmc.tar \
https://${bmc}/redfish/v1/UpdateService/update
Bad Request

[INFO "http_connection.hpp":201] Request:  0x17a69d0 HTTP/1.1 \
POST /redfish/v1/UpdateService/update ::ffff:x.x.xx.xxx
                    |
[DEBUG "update_service.hpp":687] doPost: contentType=
[DEBUG "update_service.hpp":692] Bad content type specified:

Change-Id: I48b709b6219debfed9ff60dd46ab87652e5a1fe5
Signed-off-by: Ninad Palsule <ninad@linux.ibm.com>
diff --git a/redfish-core/lib/update_service.hpp b/redfish-core/lib/update_service.hpp
index 08af788..795010d 100644
--- a/redfish-core/lib/update_service.hpp
+++ b/redfish-core/lib/update_service.hpp
@@ -682,28 +682,44 @@
     {
         return;
     }
-    BMCWEB_LOG_DEBUG << "doPost...";
+    std::string_view contentType = req.getHeaderValue("Content-Type");
 
-    // Setup callback for when new software detected
-    monitorForSoftwareAvailable(asyncResp, req, "/redfish/v1/UpdateService");
+    BMCWEB_LOG_DEBUG << "doPost: contentType=" << contentType;
 
-    MultipartParser parser;
-    ParserError ec = parser.parse(req);
-    if (ec == ParserError::ERROR_BOUNDARY_FORMAT)
+    // Make sure that content type is application/octet-stream or
+    // multipart/form-data
+    if (boost::iequals(contentType, "application/octet-stream"))
     {
-        // If the request didnt' contain boundary information, assume it was a
-        // POST binary payload.
+        // Setup callback for when new software detected
+        monitorForSoftwareAvailable(asyncResp, req,
+                                    "/redfish/v1/UpdateService");
+
         uploadImageFile(asyncResp->res, req.body());
-        return;
     }
-    if (ec != ParserError::PARSER_SUCCESS)
+    else if (contentType.starts_with("multipart/form-data"))
     {
-        // handle error
-        BMCWEB_LOG_ERROR << "MIME parse failed, ec : " << static_cast<int>(ec);
-        messages::internalError(asyncResp->res);
-        return;
+        MultipartParser parser;
+
+        // Setup callback for when new software detected
+        monitorForSoftwareAvailable(asyncResp, req,
+                                    "/redfish/v1/UpdateService");
+
+        ParserError ec = parser.parse(req);
+        if (ec != ParserError::PARSER_SUCCESS)
+        {
+            // handle error
+            BMCWEB_LOG_ERROR << "MIME parse failed, ec : "
+                             << static_cast<int>(ec);
+            messages::internalError(asyncResp->res);
+            return;
+        }
+        updateMultipartContext(asyncResp, parser);
     }
-    updateMultipartContext(asyncResp, parser);
+    else
+    {
+        BMCWEB_LOG_DEBUG << "Bad content type specified:" << contentType;
+        asyncResp->res.result(boost::beast::http::status::bad_request);
+    }
 }
 
 inline void requestRoutesUpdateService(App& app)