Fix NOLINT in pam module
There's a number of places in the pam module where we do pointer
manipulation by hand. This is because pam relies on passing pointers.
This commit updates to at least using unqiue_ptr with release(), as well
as std::span, rather than using raw pointers.
Tested: Tested in token commit. Will merge at same time.
Change-Id: Ie49f7e6eeaa5c7ac1798b9a123e3ab5439a4ab28
Signed-off-by: Ed Tanous <etanous@nvidia.com>
diff --git a/include/pam_authenticate.hpp b/include/pam_authenticate.hpp
index 9854df6..22c8695 100644
--- a/include/pam_authenticate.hpp
+++ b/include/pam_authenticate.hpp
@@ -8,10 +8,10 @@
#include <string_view>
// function used to get user input
-inline int pamFunctionConversation(int numMsg, const struct pam_message** msg,
+inline int pamFunctionConversation(int numMsg, const struct pam_message** msgs,
struct pam_response** resp, void* appdataPtr)
{
- if ((appdataPtr == nullptr) || (msg == nullptr) || (resp == nullptr))
+ if ((appdataPtr == nullptr) || (msgs == nullptr) || (resp == nullptr))
{
return PAM_CONV_ERR;
}
@@ -20,64 +20,56 @@
{
return PAM_CONV_ERR;
}
-
auto msgCount = static_cast<size_t>(numMsg);
- auto messages = std::span(msg, msgCount);
- auto responses = std::span(resp, msgCount);
+ // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays)
+ auto responseArrPtr = std::make_unique<pam_response[]>(msgCount);
+ auto responses = std::span(responseArrPtr.get(), msgCount);
+ auto messagePtrs = std::span(msgs, msgCount);
for (size_t i = 0; i < msgCount; ++i)
{
- /* Ignore all PAM messages except prompting for hidden input */
- if (messages[i]->msg_style != PAM_PROMPT_ECHO_OFF)
+ const pam_message& msg = *(messagePtrs[i]);
+
+ pam_response& response = responses[i];
+ response.resp_retcode = 0;
+ response.resp = nullptr;
+
+ switch (msg.msg_style)
{
- continue;
+ case PAM_PROMPT_ECHO_ON:
+ break;
+ case PAM_PROMPT_ECHO_OFF:
+ {
+ // Assume PAM is only prompting for the password as hidden input
+ // Allocate memory only when PAM_PROMPT_ECHO_OFF is encounterred
+ char* appPass = static_cast<char*>(appdataPtr);
+ size_t appPassSize = std::strlen(appPass);
+
+ if ((appPassSize + 1) > PAM_MAX_RESP_SIZE)
+ {
+ return PAM_CONV_ERR;
+ }
+ // Create an array for pam to own
+ // NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays)
+ auto passPtr = std::make_unique<char[]>(appPassSize + 1);
+ std::strncpy(passPtr.get(), appPass, appPassSize + 1);
+
+ responses[i].resp = passPtr.release();
+ }
+ break;
+ case PAM_ERROR_MSG:
+ BMCWEB_LOG_ERROR("Pam error {}", msg.msg);
+ break;
+ case PAM_TEXT_INFO:
+ BMCWEB_LOG_ERROR("Pam info {}", msg.msg);
+ break;
+ default:
+ return PAM_CONV_ERR;
}
-
- /* Assume PAM is only prompting for the password as hidden input */
- /* Allocate memory only when PAM_PROMPT_ECHO_OFF is encounterred */
-
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- char* appPass = reinterpret_cast<char*>(appdataPtr);
- size_t appPassSize = std::strlen(appPass);
-
- if ((appPassSize + 1) > PAM_MAX_RESP_SIZE)
- {
- return PAM_CONV_ERR;
- }
- // IDeally we'd like to avoid using malloc here, but because we're
- // passing off ownership of this to a C application, there aren't a lot
- // of sane ways to avoid it.
-
- // NOLINTNEXTLINE(cppcoreguidelines-no-malloc)
- void* passPtr = malloc(appPassSize + 1);
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- char* pass = reinterpret_cast<char*>(passPtr);
- if (pass == nullptr)
- {
- return PAM_BUF_ERR;
- }
-
- std::strncpy(pass, appPass, appPassSize + 1);
-
- size_t numMsgSize = static_cast<size_t>(numMsg);
- // NOLINTNEXTLINE(cppcoreguidelines-no-malloc)
- void* ptr = calloc(numMsgSize, sizeof(struct pam_response));
- if (ptr == nullptr)
- {
- // NOLINTNEXTLINE(cppcoreguidelines-no-malloc)
- free(pass);
- return PAM_BUF_ERR;
- }
-
- // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- *resp = reinterpret_cast<pam_response*>(ptr);
-
- responses[i]->resp = pass;
-
- return PAM_SUCCESS;
}
- return PAM_CONV_ERR;
+ *resp = responseArrPtr.release();
+ return PAM_SUCCESS;
}
/**