Support username for IPMI default user account

The current support in IPMI is for the nameless account, which has
no username and only password associated with the account. In
ipmitool for the nameless account -U option is not needed. There are
management scripts which take a parameter for -U option and fails
if -U option is not supported by ipmitool option. This patch is to
support "admin" username for the default account. Once full fledged
user account management is in place, this change can be removed.

Change-Id: Idad73c0d04f189af66f2365424a68a637fe0e476
Signed-off-by: Tom Joseph <tomjoseph@in.ibm.com>
diff --git a/command/rakp12.cpp b/command/rakp12.cpp
index 5963cef..c52d188 100644
--- a/command/rakp12.cpp
+++ b/command/rakp12.cpp
@@ -3,6 +3,7 @@
 #include <openssl/rand.h>
 
 #include <algorithm>
+#include <cstring>
 #include <iomanip>
 #include <iostream>
 
@@ -45,6 +46,29 @@
         return outPayload;
     }
 
+    auto rakp1Size = sizeof(RAKP1request) -
+            (userNameMaxLen - request->user_name_len);
+
+    // Validate user name length in the message
+    if (request->user_name_len > userNameMaxLen ||
+        inPayload.size() !=  rakp1Size)
+    {
+        response->rmcpStatusCode =
+            static_cast<uint8_t>(RAKP_ReturnCode::INVALID_NAME_LENGTH);
+        return outPayload;
+    }
+
+    session->userName.assign(request->user_name, request->user_name_len);
+
+    // Validate the user name if the username is provided
+    if (request->user_name_len &&
+        (session->userName != cipher::rakp_auth::userName))
+    {
+        response->rmcpStatusCode =
+            static_cast<uint8_t>(RAKP_ReturnCode::UNAUTH_NAME);
+        return outPayload;
+    }
+
     // Update transaction time
     session->updateLastTransactionTime();
 
@@ -70,7 +94,8 @@
                  cipher::rakp_auth::REMOTE_CONSOLE_RANDOM_NUMBER_LEN +
                  cipher::rakp_auth::BMC_RANDOM_NUMBER_LEN +
                  BMC_GUID_LEN + sizeof(request->req_max_privilege_level) +
-                 sizeof(request->user_name_len));
+                 sizeof(request->user_name_len) +
+                 session->userName.size());
 
     auto iter = input.begin();
 
@@ -127,6 +152,9 @@
     // User Name Length Byte
     std::copy_n(&(request->user_name_len), sizeof(request->user_name_len),
                 iter);
+    std::advance(iter, sizeof(request->user_name_len));
+
+    std::copy_n(session->userName.data(), session->userName.size(), iter);
 
     // Generate Key Exchange Authentication Code - RAKP2
     auto output = authAlgo->generateHMAC(input);