Fix for ipmid crash with SetUserPassword

Issue: SetUserPassword with a short password causes ipmid to crash

Fix: Adjust clear sensitive data

Tested:
1. Verified using ipmitool commands
Command: ipmitool user set password 3 a
Response: IPMI command failed: Invalid data field in request
Set User Password command failed (user 3)
Command: ipmitool user set password 3 asdf1234
Response: Set User Password command successful (user 3)
2. IPMID did not crash wth the changes

Signed-off-by: Snehalatha Venkatesh <snehalathax.v@intel.com>
Change-Id: Ib9462ed6f79a8ef8592e579521526c9f3e7c79b0
diff --git a/user_channel/user_mgmt.cpp b/user_channel/user_mgmt.cpp
index a1aba71..036f73d 100644
--- a/user_channel/user_mgmt.cpp
+++ b/user_channel/user_mgmt.cpp
@@ -737,13 +737,11 @@
                           entry("USER-ID=%d", (uint8_t)userId));
         return ccParmOutOfRange;
     }
-    std::string passwd;
+
+    ipmi::SecureString passwd;
     passwd.assign(reinterpret_cast<const char*>(userPassword), 0,
                   maxIpmi20PasswordSize);
-
     int retval = pamUpdatePasswd(userName.c_str(), passwd.c_str());
-    // Clear sensitive data
-    OPENSSL_cleanse(&passwd, passwd.length());
 
     switch (retval)
     {
diff --git a/user_channel/user_mgmt.hpp b/user_channel/user_mgmt.hpp
index 20abda1..d41a387 100644
--- a/user_channel/user_mgmt.hpp
+++ b/user_channel/user_mgmt.hpp
@@ -1,4 +1,4 @@
-/*
+/*.
 // Copyright (c) 2018 Intel Corporation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
@@ -401,4 +401,45 @@
      */
     void cacheUserDataFile();
 };
+
+template <typename T>
+class SecureAllocator : public std::allocator<T>
+{
+  public:
+    typedef size_t size_type;
+    typedef T* pointer;
+    typedef const T* const_pointer;
+
+    template <typename _Tp1>
+    struct rebind
+    {
+        typedef SecureAllocator<_Tp1> other;
+    };
+    pointer allocate(size_type n, const void* hint = 0)
+    {
+        return std::allocator<T>::allocate(n, hint);
+    }
+
+    void deallocate(pointer p, size_type n)
+    {
+        OPENSSL_cleanse(p, n);
+        return std::allocator<T>::deallocate(p, n);
+    }
+
+    SecureAllocator() throw() : std::allocator<T>()
+    {
+    }
+    SecureAllocator(const SecureAllocator& a) throw() : std::allocator<T>(a)
+    {
+    }
+    template <class U>
+    SecureAllocator(const SecureAllocator<U>& a) throw() : std::allocator<T>(a)
+    {
+    }
+    ~SecureAllocator() throw()
+    {
+    }
+};
+using SecureString = std::basic_string<char, std::char_traits<char>,
+                                       ipmi::SecureAllocator<char>>;
 } // namespace ipmi