Reuse some code blocks using typename <RequestX> (#48)
author강용구/Security&Privacy팀(SR)/삼성전자 <ygace.kang@samsung.com>
Tue, 6 Feb 2024 04:33:11 +0000 (13:33 +0900)
committerGitHub Enterprise <noreply-CODE@samsung.com>
Tue, 6 Feb 2024 04:33:11 +0000 (13:33 +0900)
* Add Request classes
* Reuse code block using typename <RequestX>
* Change to snake case in server-side
* Remove unused lines
* Change local variables to lower camel case
* Add ClientRequest classes
* Apply typename for reuse some code blocks in client-side
* add explicit to prevent converting constructor operation

srcs/client/client-request-ga.h [new file with mode: 0644]
srcs/client/client-request-mc.h [new file with mode: 0644]
srcs/client/client.cpp
srcs/server/dl-loader.cpp
srcs/server/dl-loader.h
srcs/server/request-ga.h [new file with mode: 0644]
srcs/server/request-mc.h [new file with mode: 0644]
srcs/server/request.h [new file with mode: 0644]
srcs/server/service.cpp
srcs/server/service.h
srcs/server/socket-manager.cpp

diff --git a/srcs/client/client-request-ga.h b/srcs/client/client-request-ga.h
new file mode 100644 (file)
index 0000000..2dcd76f
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ *  Copyright (c) 2023 Samsung Electronics Co., Ltd. All rights reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ *
+ *
+ * @file        client-request-mc.h
+ * @version     1.0
+ * @brief       Helper class wrapping client communication with the service
+ *              for the get assertion request
+ */
+
+#pragma once
+
+#include "client-request.h"
+
+namespace WA {
+class ClientRequestGA : public ClientRequest
+{
+public:
+    typedef wauthn_pubkey_cred_request_options_s Options;
+    typedef wauthn_ga_callbacks_s Callbacks;
+    typedef wauthn_pubkey_credential_assertion_s PubKeyCred;
+
+    explicit ClientRequestGA() : ClientRequest(WebAuthnCall::GET_ASSERTION) {}
+};
+} //namespace WebAuthn
diff --git a/srcs/client/client-request-mc.h b/srcs/client/client-request-mc.h
new file mode 100644 (file)
index 0000000..9c29688
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ *  Copyright (c) 2023 Samsung Electronics Co., Ltd. All rights reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ *
+ *
+ * @file        client-request-mc.h
+ * @version     1.0
+ * @brief       Helper class wrapping client communication with the service
+ *              for the make credential request
+ */
+
+#pragma once
+
+#include "client-request.h"
+
+namespace WA {
+class ClientRequestMC : public ClientRequest
+{
+public:
+    typedef wauthn_pubkey_cred_creation_options_s Options;
+    typedef wauthn_mc_callbacks_s Callbacks;
+    typedef wauthn_pubkey_credential_attestaion_s PubKeyCred;
+
+    explicit ClientRequestMC() : ClientRequest(WebAuthnCall::MAKE_CREDENTIAL) {}
+};
+} //namespace WebAuthn
index 888d90c5051cbee44acd5ce98a46779c6f6d947d..24f0f3b08d2631f6d2d8e3896aa6c0642a077562 100644 (file)
 
 #include <webauthn.h>
 #include <webauthn-log.h>
-#include <client-request.h>
 #include <utils.h>
 #include <unistd.h>
 #include <thread>
 
+#include "client-request-mc.h"
+#include "client-request-ga.h"
+
 template <typename A, typename B>
 void cb_worker(std::shared_ptr<ClientRequest> request, A &callbacks, B cred)
 {
@@ -50,9 +52,10 @@ void cb_worker(std::shared_ptr<ClientRequest> request, A &callbacks, B cred)
     callbacks->response_callback(cred, wauthn_error_e(ret), callbacks->user_data);
 }
 
-int wauthn_make_credential( const wauthn_client_data_s *client_data,
-                            const wauthn_pubkey_cred_creation_options_s *options,
-                            wauthn_mc_callbacks_s *callbacks)
+template <typename T>
+int wauthn_process(const wauthn_client_data_s *client_data,
+                   const typename T::Options *options,
+                   typename T::Callbacks *callbacks)
 {
     return try_catch([&]() -> int {
         checkParameters(client_data, options, callbacks);
@@ -61,42 +64,31 @@ int wauthn_make_credential( const wauthn_client_data_s *client_data,
             LogDebug("Adjust qrcode_callback to null");
             callbacks->qrcode_callback = nullptr;
         }
-        std::shared_ptr<ClientRequest> request 
-            = std::make_shared<ClientRequest>(WebAuthnCall::MAKE_CREDENTIAL);
+        std::shared_ptr<T> request = std::make_shared<T>();
 
         if (request->sendRequest(client_data, options).failed())
             return request->getStatus();
         LogDebug("Response: " << wauthn_error_to_string(request->getStatus()));
 
-        wauthn_pubkey_credential_attestaion_s *cred = NULL;
+        typename T::PubKeyCred *cred = NULL;
         std::thread worker([request, callbacks, cred]{cb_worker(request, callbacks, cred);});
         worker.detach();
         return WAUTHN_ERROR_NONE;
     });
 }
 
+int wauthn_make_credential( const wauthn_client_data_s *client_data,
+                            const wauthn_pubkey_cred_creation_options_s *options,
+                            wauthn_mc_callbacks_s *callbacks)
+{
+    return wauthn_process<ClientRequestMC>(client_data, options, callbacks);
+}
+
 int wauthn_get_assertion( const wauthn_client_data_s *client_data,
                           const wauthn_pubkey_cred_request_options_s *options,
                           wauthn_ga_callbacks_s *callbacks)
 {
-    return try_catch([&]() -> int {
-        checkParameters(client_data, options, callbacks);
-        if (options->linked_device != nullptr)  // The qrcode_callback should not be called.
-        {
-            LogDebug("Adjust qrcode_callback to NULL");
-            callbacks->qrcode_callback = nullptr;
-        }
-        std::shared_ptr<ClientRequest> request 
-            = std::make_shared<ClientRequest>(WebAuthnCall::GET_ASSERTION);
-        if (request->sendRequest(client_data, options).failed())
-            return request->getStatus();
-        LogDebug("Response: " << wauthn_error_to_string(request->getStatus()));
-
-        wauthn_pubkey_credential_assertion_s *cred = NULL;
-        std::thread worker([request, callbacks, cred]{cb_worker(request, callbacks, cred);});
-        worker.detach();
-        return WAUTHN_ERROR_NONE;
-    });
+    return wauthn_process<ClientRequestGA>(client_data, options, callbacks);
 }
 
 int wauthn_cancel()
index 563863d464545fa51e38865d88f08968e323206e..1ca33c01e84c19494bc75a9200c63e4081e6a3e2 100644 (file)
@@ -38,7 +38,7 @@ namespace WA {
         LogDebug("Unlaoding library: " << m_libraryPath);
         dlclose(m_libraryHandle);
     }
-    void* DLLoader::resolveFunction(const std::string &name) noexcept
+    void* DLLoader::ResolveFunction(const std::string &name) noexcept
     {
         LogDebug("Resolving symbol: " << name << " from " << m_libraryPath);
         void* sym = dlsym(m_libraryHandle, name.c_str());
index c62e04783de945e6a60b5f7afcdb228b33fd4ebc..c0fc56d647be786b68332e9fe436464eb219bd26 100644 (file)
@@ -30,13 +30,13 @@ public:
     explicit DLLoader(std::string path);
     ~DLLoader();
 
-    void* resolveFunction(const std::string &name) noexcept;
+    void* ResolveFunction(const std::string &name) noexcept;
 
     template<typename ReturnValue, typename... Args>
-    ReturnValue invoke(const std::string &name, Args... args)
+    ReturnValue Invoke(const std::string &name, Args... args)
     {
         typedef ReturnValue (* function_t)(Args...);
-        function_t func = (function_t)resolveFunction(name);
+        function_t func = (function_t)ResolveFunction(name);
         if (!func)
         {
             throw std::runtime_error("Trying to call unresolved function");
diff --git a/srcs/server/request-ga.h b/srcs/server/request-ga.h
new file mode 100644 (file)
index 0000000..5fff804
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ *  Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+#pragma once
+
+#include "request.h"
+
+namespace WA {
+
+class RequestGetAssertion : Request
+{
+public:
+    typedef wauthn_pubkey_cred_request_options_s Options;
+    typedef wauthn_ga_callbacks_s Callbacks;
+    typedef wauthn_pubkey_credential_assertion_s PubKeyCred;
+
+    std::string GetAPI() {return m_API;}
+
+    static void ResponseCallback(const PubKeyCred *pubkey_cred,
+        wauthn_error_e result,
+        void *user_data)
+    {
+        user_data_s *userData = _ResponseCBHead(result, user_data);
+        MessageBuffer buffer(userData->service->GetSocketmanager()->newMessage());
+        int ret = try_catch([&]() -> int {
+            Serialization::Serialize(buffer, result, pubkey_cred);
+            return WAUTHN_ERROR_NONE;
+        });
+        _ResponseCBTail(ret, userData, std::move(buffer));
+    }
+
+private:
+    std::string m_API = "wah_get_assertion";
+};
+} // namespace WebAuthn
diff --git a/srcs/server/request-mc.h b/srcs/server/request-mc.h
new file mode 100644 (file)
index 0000000..3d42aa0
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ *  Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+#pragma once
+
+#include "request.h"
+
+namespace WA {
+
+class RequestMakeCredential : Request
+{
+public:
+    typedef wauthn_pubkey_cred_creation_options_s Options;
+    typedef wauthn_mc_callbacks_s Callbacks;
+    typedef wauthn_pubkey_credential_attestaion_s PubKeyCred;
+
+    std::string GetAPI() {return m_API;}
+
+    static void ResponseCallback(const PubKeyCred *pubkey_cred,
+        wauthn_error_e result,
+        void *user_data)
+    {
+        user_data_s *userData = _ResponseCBHead(result, user_data);
+        MessageBuffer buffer(userData->service->GetSocketmanager()->newMessage());
+        int ret = try_catch([&]() -> int {
+            Serialization::Serialize(buffer, result, pubkey_cred);
+            return WAUTHN_ERROR_NONE;
+        });
+        _ResponseCBTail(ret, userData, std::move(buffer));
+    }
+private:
+    std::string m_API = "wah_make_credential";
+};
+} // namespace WebAuthn
diff --git a/srcs/server/request.h b/srcs/server/request.h
new file mode 100644 (file)
index 0000000..976109d
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ *  Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+#pragma once
+
+namespace WA{
+
+class Request {
+public:
+    static void QRCallback(const char *qr_contents, void *user_data)
+    {
+        user_data_s *userData;
+        int ret = try_catch([&]() -> int {
+            if (user_data == nullptr)
+                ThrowMsg(ServiceException::InvalidUserdata, "Invalid user_data");
+            userData = static_cast<user_data_s *>(user_data);
+            if (userData->service == nullptr || userData->connectionID.sock == 0)
+                ThrowMsg(ServiceException::InvalidUserdata, "Invalid user_data");
+            if (qr_contents == nullptr)
+                ThrowMsg(ServiceException::InvalidQRContents, "Invalid qr_contents");
+            LogDebug("qr_contents: " << qr_contents);
+            return WAUTHN_ERROR_NONE;
+        });
+        MessageBuffer buffer(userData->service->GetSocketmanager()->newMessage());
+        if (ret != WAUTHN_ERROR_NONE)
+            Serialization::Serialize(buffer, WAUTHN_ERROR_INVALID_STATE);
+        else
+            Serialization::Serialize(buffer, ret, std::string(qr_contents));
+        
+        userData->service->GetSocketmanager()->Write(userData->connectionID, std::move(buffer));
+    }
+
+protected:
+    static user_data_s *_ResponseCBHead(wauthn_error_e result, void *user_data)
+    {
+        LogDebug("result: " << wauthn_error_to_string(result));
+        if (user_data == nullptr)
+            ThrowMsg(ServiceException::InvalidUserdata, "Invalid user_data");
+        user_data_s *userData = static_cast<user_data_s *>(user_data);
+        if (userData->service == nullptr || userData->connectionID.sock == 0)
+            ThrowMsg(ServiceException::InvalidUserdata, "Invalid user_data");
+        return userData;
+    }
+
+    static void _ResponseCBTail(int ret, user_data_s *userData, MessageBuffer &&buffer)
+    {
+        if (ret != WAUTHN_ERROR_NONE)
+        {
+            buffer.InitForStreaming();
+            switch (ret){
+                case WAUTHN_ERROR_INVALID_PARAMETER:
+                    LogError("Invalid pubkey_cred");
+                    Serialization::Serialize(buffer, WAUTHN_ERROR_INVALID_STATE);
+                    break;
+                default:
+                    LogError("Unknown error");
+                    Serialization::Serialize(buffer, WAUTHN_ERROR_UNKNOWN);
+            }
+        }
+        userData->service->GetSocketmanager()->Write(userData->connectionID, std::move(buffer));
+    }
+};
+} // namespace WebAuthn
index b82218245e0836e0d4201630c0794333cf175e03..6fc7c14121fcd8d1a022170f0d0b1635c588d805 100644 (file)
 #include <protocols.h>
 #include <service.h>
 #include <unistd.h>
-#include <webauthn-hal.h>
 #include <utils.h>
+#include <webauthn-hal.h>
+
+#include "request-mc.h"
+#include "request-ga.h"
 #define SMACK_LABEL_LEN 255
 
 namespace WA {
-typedef struct __struct_user_data
-{
-    Service *service;
-    SocketManager::ConnectionID connectionID;
-}user_data_s;
-
-void cb_display_qrcode(const char *qr_contents, void *user_data)
-{
-    user_data_s *userData;
-    int ret = try_catch([&]() -> int {
-        if (user_data == nullptr)
-            ThrowMsg(ServiceException::InvalidUserdata, "Invalid user_data");
-        userData = static_cast<user_data_s *>(user_data);
-        if (userData->service == nullptr || userData->connectionID.sock == 0)
-            ThrowMsg(ServiceException::InvalidUserdata, "Invalid user_data");
-        if (qr_contents == nullptr)
-            ThrowMsg(ServiceException::InvalidQRContents, "Invalid qr_contents");
-        LogDebug("qr_contents: " << qr_contents);
-        return WAUTHN_ERROR_NONE;
-    });
-    MessageBuffer buffer(userData->service->getSocketmanager()->newMessage());
-    if (ret != WAUTHN_ERROR_NONE)
-        Serialization::Serialize(buffer, WAUTHN_ERROR_INVALID_STATE);
-    else
-        Serialization::Serialize(buffer, ret, std::string(qr_contents));
-    
-    userData->service->getSocketmanager()->Write(userData->connectionID, std::move(buffer));
-}
-
-void cb_mc_on_response(const wauthn_pubkey_credential_attestaion_s *pubkey_cred,
-                       wauthn_error_e result,
-                       void *user_data)
-{
-    LogDebug("result: " << wauthn_error_to_string(result));
-    if (user_data == nullptr)
-        ThrowMsg(ServiceException::InvalidUserdata, "Invalid user_data");
-    user_data_s *userData = static_cast<user_data_s *>(user_data);
-    if (userData->service == nullptr || userData->connectionID.sock == 0)
-        ThrowMsg(ServiceException::InvalidUserdata, "Invalid user_data");
-
-    MessageBuffer buffer(userData->service->getSocketmanager()->newMessage());
-    int ret = try_catch([&]() -> int {
-        Serialization::Serialize(buffer, result, pubkey_cred);
-        return WAUTHN_ERROR_NONE;
-    });
-    if (ret != WAUTHN_ERROR_NONE)
-    {
-        buffer.InitForStreaming();
-        switch (ret){
-            case WAUTHN_ERROR_INVALID_PARAMETER:
-                LogError("Invalid pubkey_cred");
-                Serialization::Serialize(buffer, WAUTHN_ERROR_INVALID_STATE);
-                break;
-            default:
-                LogError("Unknown error");
-                Serialization::Serialize(buffer, WAUTHN_ERROR_UNKNOWN);
-        }
-    }
-    userData->service->getSocketmanager()->Write(userData->connectionID, std::move(buffer));
-}
-
-void cb_ga_on_response(const wauthn_pubkey_credential_assertion_s *pubkey_cred,
-                       wauthn_error_e result,
-                       void *user_data)
-{
-    LogDebug("result: " << wauthn_error_to_string(result));
-    if (user_data == nullptr)
-        ThrowMsg(ServiceException::InvalidUserdata, "Invalid user_data");
-    user_data_s *userData = static_cast<user_data_s *>(user_data);
-    if (userData->service == nullptr || userData->connectionID.sock == 0)
-        ThrowMsg(ServiceException::InvalidUserdata, "Invalid user_data");
-
-    MessageBuffer buffer(userData->service->getSocketmanager()->newMessage());
-    int ret = try_catch([&]() -> int {
-        Serialization::Serialize(buffer, result, pubkey_cred);
-        return WAUTHN_ERROR_NONE;
-    });
-    if (ret != WAUTHN_ERROR_NONE)
-    {
-        buffer.InitForStreaming();
-        switch (ret){
-            case WAUTHN_ERROR_INVALID_PARAMETER:
-                LogError("Invalid pubkey_cred");
-                Serialization::Serialize(buffer, WAUTHN_ERROR_INVALID_STATE);
-                break;
-            default:
-                LogError("Unknown error");
-                Serialization::Serialize(buffer, WAUTHN_ERROR_UNKNOWN);
-        }
-    }
-    userData->service->getSocketmanager()->Write(userData->connectionID, std::move(buffer));
-}
 
 Service::Service() : m_pluginHybrid(std::make_shared<DLLoader>(WAH_PLUGIN_SO_PATH_HYBRID)){}
 
-SocketManager *Service::getSocketmanager()
+SocketManager *Service::GetSocketmanager()
 {
     return this->m_serviceManager;
 }
 
-void Service::mcWorker(SocketManager::ConnectionID connectionID,
-    wauthn_client_data_s *client_data,
-    wauthn_pubkey_cred_creation_options_s *options)
-{
-    wauthn_mc_callbacks_s *callbacks = NULL;
-    callbacks = (wauthn_mc_callbacks_s*) calloc(1, sizeof(wauthn_mc_callbacks_s));
-    callbacks->qrcode_callback = cb_display_qrcode;
-    callbacks->response_callback = cb_mc_on_response;
-    checkParameters(client_data, options, callbacks);
-    if (options->linked_device != nullptr)  // The qrcode_callback should not be called.
-    {
-        LogDebug("Adjust qrcode_callback to null");
-        callbacks->qrcode_callback = nullptr;
-    }
-
-    user_data_s *user_data = (user_data_s *) calloc(1, sizeof(user_data_s));
-    user_data->service = this;
-    user_data->connectionID = connectionID;
-    callbacks->user_data = user_data;
-
-    int ret = try_catch([&]() -> int {
-        m_pluginHybrid->invoke<void,
-                               const wauthn_client_data_s *,
-                               const wauthn_pubkey_cred_creation_options_s *,
-                               wauthn_mc_callbacks_s *
-                              >("wah_make_credential", client_data, options, callbacks);
-        return WAUTHN_ERROR_NONE;
-    });
-    if (ret != WAUTHN_ERROR_NONE)
-        LogError("Unhandled Error: " << wauthn_error_to_string(ret));
-    unsetBusy();
-}
-
-void Service::gaWorker(SocketManager::ConnectionID connectionID,
-    wauthn_client_data_s *client_data,
-    wauthn_pubkey_cred_request_options_s *options)
-{
-    wauthn_ga_callbacks_s *callbacks = NULL;
-    callbacks = (wauthn_ga_callbacks_s*) calloc(1, sizeof(wauthn_ga_callbacks_s));
-    callbacks->qrcode_callback = cb_display_qrcode;
-    callbacks->response_callback = cb_ga_on_response;
-    checkParameters(client_data, options, callbacks);
-    if (options->linked_device != nullptr)  // The qrcode_callback should not be called.
-    {
-        LogDebug("Adjust qrcode_callback to null");
-        callbacks->qrcode_callback = nullptr;
-    }
-    
-    user_data_s *user_data = (user_data_s *) calloc(1, sizeof(user_data_s));
-    user_data->service = this;
-    user_data->connectionID = connectionID;
-    callbacks->user_data = user_data;
-
-    int ret = try_catch([&]() -> int {
-        m_pluginHybrid->invoke<void,
-                               const wauthn_client_data_s *,
-                               const wauthn_pubkey_cred_request_options_s *,
-                               wauthn_ga_callbacks_s *
-                              >("wah_get_assertion", client_data, options, callbacks);
-        return WAUTHN_ERROR_NONE;
-    });
-    if (ret != WAUTHN_ERROR_NONE)
-        LogError("Unhandled Error: " << wauthn_error_to_string(ret));
-    unsetBusy();
-}
-
-void Service::processEvent(Event &&msg)
+void Service::ProcessEvent(Event &&msg)
 {
     LogDebug("Processing message for socket " << msg.connectionID.sock <<
              " counter " << msg.connectionID.counter);
@@ -207,15 +52,15 @@ void Service::processEvent(Event &&msg)
         switch (call_type) {
             case WebAuthnCall::MAKE_CREDENTIAL:
                 LogDebug("call_type: WebAuthnCall::MAKE_CREDENTIAL");
-                processMakeCredential(msg.connectionID, msg.buffer);
+                Process<RequestMakeCredential>(std::move(msg));
                 break;
             case WebAuthnCall::GET_ASSERTION:
                 LogDebug("call_type: WebAuthnCall::GET_ASSERTION");
-                processGetAssertion(msg.connectionID, msg.buffer);
+                Process<RequestGetAssertion>(std::move(msg));
                 break;
             case WebAuthnCall::CANCEL:
                 LogDebug("call_type: WebAuthnCall::CANCEL");
-                processCancel(msg.connectionID, msg.buffer);
+                Cancel(std::move(msg));
                 break;
             default:
                 LogError("Invalid call: " << call_type_int);
@@ -227,60 +72,59 @@ void Service::processEvent(Event &&msg)
     });
     if (ret != WAUTHN_ERROR_NONE)
     {
-
+        LogError("Error on Processing: " << ret);
     }
 }
 
-void Service::processMakeCredential(
-    SocketManager::ConnectionID connectionID,
-    MessageBuffer &buffer)
+template <typename T>
+void Service::Worker(SocketManager::ConnectionID connectionID,
+    wauthn_client_data_s *clientData,
+    typename T::Options *options)
 {
-    wauthn_client_data_s *client_data;
-    wauthn_pubkey_cred_creation_options_s *options;
-    Deserialization::Deserialize(buffer, &client_data, &options);
-    
-    MessageBuffer responseBuffer(m_serviceManager->newMessage());
-
-    responseBuffer.ModeStreaming();
-    int ret = WAUTHN_ERROR_NONE;
-    int isBusy = checkBusyAndSet(connectionID);
-
-    if (-1 == isBusy)
-    {
-        LogError("Error on checkBusyAndSet");
-        ret = WAUTHN_ERROR_UNKNOWN;
-    }
-    else if (1 == isBusy)
+    typename T::Callbacks *callbacks = nullptr;
+    callbacks = (typename T::Callbacks*) calloc(1, sizeof(typename T::Callbacks));
+    callbacks->qrcode_callback = &(Request::QRCallback);
+    callbacks->response_callback = &(T::ResponseCallback);
+    //checkParameters(clientData, options, callbacks);
+    if (options->linked_device != nullptr)  // The qrcode_callback should not be called.
     {
-        LogError("Server is Busy");
-        ret = WAUTHN_ERROR_NOT_ALLOWED;
+        LogDebug("Adjust qrcode_callback to nullptr");
+        callbacks->qrcode_callback = nullptr;
     }
 
-    Serialization::Serialize(responseBuffer, ret);
-    m_serviceManager->Write(connectionID, std::move(responseBuffer));
-    
-    if (0 == isBusy)
-    {
-        std::thread worker(&Service::mcWorker, this, connectionID, client_data, options);
-        worker.detach();
-    }
+    user_data_s *userData = (user_data_s *) calloc(1, sizeof(user_data_s));
+    userData->service = this;
+    userData->connectionID = connectionID;
+    callbacks->user_data = userData;
+
+    auto request = std::make_unique<T>();
+    int ret = try_catch([&]() -> int {
+        m_pluginHybrid->Invoke<void,
+                               const wauthn_client_data_s *,
+                               const typename T::Options *,
+                               typename T::Callbacks *
+                              >(request->GetAPI().c_str(), clientData, options, callbacks);
+        return WAUTHN_ERROR_NONE;
+    });
+    if (ret != WAUTHN_ERROR_NONE)
+        LogError("Unhandled Error: " << wauthn_error_to_string(ret));
+    UnsetBusy();
 }
 
-void Service::processGetAssertion(SocketManager::ConnectionID connectionID,
-    MessageBuffer &buffer)
+template <typename T>
+void Service::Process(Event &&msg)
 {
-    wauthn_client_data_s *client_data;
-    wauthn_pubkey_cred_request_options_s *options;
-    Deserialization::Deserialize(buffer, &client_data, &options);
-
+    wauthn_client_data_s *clientData;
+    typename T::Options *options;
+    Deserialization::Deserialize(msg.buffer, &clientData, &options);
+    
     MessageBuffer responseBuffer(m_serviceManager->newMessage());
     responseBuffer.ModeStreaming();
     int ret = WAUTHN_ERROR_NONE;
-    int isBusy = checkBusyAndSet(connectionID);
-
+    int isBusy = CheckBusyAndSet(msg.connectionID);
     if (-1 == isBusy)
     {
-        LogError("Error on checkBusyAndSet");
+        LogError("Error on CheckBusyAndSet");
         ret = WAUTHN_ERROR_UNKNOWN;
     }
     else if (1 == isBusy)
@@ -290,47 +134,51 @@ void Service::processGetAssertion(SocketManager::ConnectionID connectionID,
     }
 
     Serialization::Serialize(responseBuffer, ret);
-    m_serviceManager->Write(connectionID, std::move(responseBuffer));
-    
+    m_serviceManager->Write(msg.connectionID, std::move(responseBuffer));    
     if (0 == isBusy)
     {
-        std::thread worker(&Service::gaWorker, this, connectionID, client_data, options);
+        std::thread worker(&Service::Worker<T>, this, msg.connectionID, clientData, options);
         worker.detach();
     }
 }
 
-void Service::processCancel(SocketManager::ConnectionID connectionID,
-    MessageBuffer &buffer)
+void Service::Cancel(Event &&msg)
 {
-    buffer.ModeStreaming();
     int ret = WAUTHN_ERROR_NONE;
-    int isBusy = checkBusyAndCred(connectionID);
+    int isBusy = CheckBusyAndCred(msg.connectionID);
     if (-1 == isBusy)
     {
-        LogError("Error on checkBusyAndCred");
+        LogError("Error on CheckBusyAndCred");
         ret = WAUTHN_ERROR_UNKNOWN;
     }
     else if (1 == isBusy)
     {
-        ret = m_pluginHybrid->invoke<int>("wah_cancel");
+        ret = m_pluginHybrid->Invoke<int>("wah_cancel");
     }
     else
     {
         LogError("The cancellation request is not allowed");
         ret = WAUTHN_ERROR_NOT_ALLOWED;
     }
+    MessageBuffer responseBuffer(m_serviceManager->newMessage());
+    responseBuffer.ModeStreaming();
+    Serialization::Serialize(responseBuffer, ret);
+    m_serviceManager->Write(msg.connectionID, std::move(responseBuffer));
+}
 
-    Serialization::Serialize(buffer, ret);
-    m_serviceManager->Write(connectionID, std::move(buffer));
+void Service::UnsetBusy()
+{
+    std::lock_guard<std::mutex> ulock(m_isBusyMutex);
+    m_isBusy = false;
 }
 
-int Service::checkBusyAndCred(SocketManager::ConnectionID connectionID)
+int Service::CheckBusyAndCred(SocketManager::ConnectionID connectionID)
 {
     std::lock_guard<std::mutex> ulock(m_isBusyMutex);
     if (m_isBusy)
     {
         Cred nowCreds;
-        int ret = getCredentials(connectionID, &nowCreds);
+        int ret = GetCredentials(connectionID, &nowCreds);
         if (-1 == ret)
         {
             LogError("Error on get credentials");
@@ -353,14 +201,14 @@ int Service::checkBusyAndCred(SocketManager::ConnectionID connectionID)
     }
 }
 
-int Service::checkBusyAndSet(SocketManager::ConnectionID connectionID)
+int Service::CheckBusyAndSet(SocketManager::ConnectionID connectionID)
 {
     std::lock_guard<std::mutex> ulock(m_isBusyMutex);
     if (m_isBusy)
         return 1;
     else{
         m_isBusy = true;
-        int ret = setCredentials(connectionID);
+        int ret = SetCredentials(connectionID);
         if (-1 == ret)
         {
             LogError("Error on set credentials");
@@ -370,18 +218,12 @@ int Service::checkBusyAndSet(SocketManager::ConnectionID connectionID)
     }
 }
 
-void Service::unsetBusy()
-{
-    std::lock_guard<std::mutex> ulock(m_isBusyMutex);
-    m_isBusy = false;
-}
-
-int Service::setCredentials(SocketManager::ConnectionID connectionID)
+int Service::SetCredentials(SocketManager::ConnectionID connectionID)
 {
-    return getCredentials(connectionID, &m_credentials);
+    return GetCredentials(connectionID, &m_credentials);
 }
 
-int Service::getCredentials(SocketManager::ConnectionID connectionID, Cred *creds)
+int Service::GetCredentials(SocketManager::ConnectionID connectionID, Cred *creds)
 {
     socklen_t length = sizeof(ucred);
     if (0 > getsockopt(connectionID.sock, SOL_SOCKET, SO_PEERCRED, &creds->cred, &length)) {
index 3f87f9c6b261d84b299adc3ba6858f3dfa5122f3..d77dd1385f69ae56d7301e5d5b0e8be8faeccf25 100644 (file)
 
 namespace WA {
 
+typedef struct __struct_user_data
+{
+    Service *service;
+    SocketManager::ConnectionID connectionID;
+}user_data_s;
+
 struct Event {
     SocketManager::ConnectionID connectionID;
     MessageBuffer buffer;
@@ -56,66 +62,29 @@ public:
      * Handle request message from a client
      * @param  msg  A message
      */
-    void processEvent(Event &&msg);
+    void ProcessEvent(Event &&msg);
 
     /**
      * Get the sockekmanager
      * @return The object of socket manager
      */
-    SocketManager *getSocketmanager();
+    SocketManager *GetSocketmanager();
 
     /**
      * Unset to server is not busy
      */
-    void unsetBusy();
+    void UnsetBusy();
 
 private:
-    /**
-     * Process making credential
-     * @param[in] connectionID Socket information for the connection
-     * @param[inout] buffer Input/output message buffer
-     */
-    void processMakeCredential(
-        SocketManager::ConnectionID connectionID,
-        MessageBuffer &buffer);
-
-    /**
-     * Process getting assertion
-     * @param[in] connectionID Socket information for the connection
-     * @param[inout] buffer Input/output message buffer
-     */
-    void processGetAssertion(
-        SocketManager::ConnectionID connectionID,
-        MessageBuffer &buffer);
-
-    /**
-     * Process cancelling current event
-     * @param[in] connectionID Socket information for the connection
-     * @param[inout] buffer Input/output message buffer
-     */
-    void processCancel(
-        SocketManager::ConnectionID connectionID,
-        MessageBuffer &buffer);
-
-    /**
-     * Worker thread for make credential request
-     * @param[in] connectionID Socket information for the connection
-     * @param[in] client_data client data passed from a client
-     * @param[in] options options passed from a client
-     */
-    void mcWorker(SocketManager::ConnectionID connectionID,
+    template <typename T>
+    void Worker(SocketManager::ConnectionID connectionID,
         wauthn_client_data_s *client_data,
-        wauthn_pubkey_cred_creation_options_s *options);
+        typename T::Options *options);
 
-    /**
-     * Worker thread for get assertion request
-     * @param[in] connectionID Socket information for the connection
-     * @param[in] client_data client data passed from a client
-     * @param[in] options options passed from a client
-     */
-    void gaWorker(SocketManager::ConnectionID connectionID,
-        wauthn_client_data_s *client_data,
-        wauthn_pubkey_cred_request_options_s *options);
+    template <typename T>
+    void Process(Event &&msg);
+
+    void Cancel(Event &&msg);
 
     /**
      * Check the server is busy or not and set busy if server is not busy
@@ -124,7 +93,7 @@ private:
      *         @c 0 server is not busy,
      *         @c -1 error occurred while get/set credentials when the server is not busy
      */
-    int checkBusyAndSet(SocketManager::ConnectionID connectionID);
+    int CheckBusyAndSet(SocketManager::ConnectionID connectionID);
 
     /**
      * Check the server is busy or not and credentials are matched or not
@@ -133,7 +102,7 @@ private:
      *         @c 0 server is not busy or credentials are not matched,
      *         @c -1 error occurred while get credentials
      */
-    int checkBusyAndCred(SocketManager::ConnectionID connectionID);
+    int CheckBusyAndCred(SocketManager::ConnectionID connectionID);
 
     /**
      * Set credentials for the connection
@@ -141,7 +110,7 @@ private:
      * @return @c 0 on success,
      *         @c -1 error occurred while get credentials
      */
-    int setCredentials(SocketManager::ConnectionID connectionID);
+    int SetCredentials(SocketManager::ConnectionID connectionID);
 
     /**
      * Get credentials for the connection. The smack label and process ID used to the credentials.
@@ -150,12 +119,11 @@ private:
      * @return @c 0 on success,
      *         @c -1 error occurred while get credentials
      */
-    int getCredentials(SocketManager::ConnectionID connectionID, Cred *creds);
+    int GetCredentials(SocketManager::ConnectionID connectionID, Cred *creds);
 
     bool m_isBusy = false;
     std::mutex m_isBusyMutex;
     Cred m_credentials;
     std::shared_ptr<DLLoader> m_pluginHybrid;
 };
-
 } // namespace WebAuthn
index 4e80aed0cf2be5642a5c075760017a677be319d0..ffe57eacbb9241312fe4e09a42d9df07de588386 100644 (file)
@@ -169,7 +169,7 @@ void SocketManager::ReadyForRead(int sock) {
                 FD_CLR(sock, &m_readSet); // the one and only call on this socket is complete
                 const auto event = new Event{ ConnectionID{sock, desc.counter}, std::move(buffer) };
                 //m_service->PutEvent(ConnectionID{sock, desc.counter}, std::move(buffer));
-                m_service->processEvent(std::move(*event));
+                m_service->ProcessEvent(std::move(*event));
                 break;
         }
     }