explicit GenericClientRequest(WebAuthnCall action) :
m_action(action)
{
+ LogInfo(WebAuthnCallToString(m_action));
}
virtual ~GenericClientRequest()
{
m_buffer.InitForStreaming();
Serialization::Serialize(m_buffer, static_cast<int>(m_action));
- LogDebug("GenericClientRequest " << WebAuthnCallToString(m_action));
}
};
{
static constexpr const char *REQUEST_KIND_PREFIX =
std::is_same_v<typename Request::Callbacks, wauthn_mc_callbacks_s> ? "MC: " : "GA: ";
-
+ LogInfo(REQUEST_KIND_PREFIX << "Started");
int ret = try_catch([&]() -> int {
- typename Request::PubKeyCred *cred = nullptr;
if (callbacks.qrcode_callback == nullptr)
LogDebug(REQUEST_KIND_PREFIX << "There is no qrcode_callback");
else{ //callbacks.qrcode_callback != nullptr
std::string qr_code;
if (request->Recv(qr_code).Failed())
LogError(REQUEST_KIND_PREFIX << "Error on receive qrcode");
- LogDebug(REQUEST_KIND_PREFIX << "Received qr_contents: " << qr_code);
+ LogInfo(REQUEST_KIND_PREFIX << "Calling qrcode_callback with qr_contents: "
+ << qr_code);
callbacks.qrcode_callback(qr_code.c_str(), callbacks.user_data);
}
+ typename Request::PubKeyCred *cred = nullptr;
request->Recv(&cred);
+ LogInfo(REQUEST_KIND_PREFIX << "Calling response_callback");
callbacks.response_callback(cred, wauthn_error_e(request->GetStatus()),
callbacks.user_data);
if(request->Failed())
{
- LogError(REQUEST_KIND_PREFIX << "Error on receive response: " << request->GetStatus());
- return WAUTHN_ERROR_INVALID_STATE;
+ LogError(REQUEST_KIND_PREFIX << "Error on received response: "
+ << get_error_message(request->GetStatus()));
+ return request->GetStatus();
}
wauthn_hybrid_linked_data_s *linked_data = nullptr;
while (request->Recv(&linked_data).Incompleted())
{
- LogLinkedDevice(REQUEST_KIND_PREFIX, "[linked_data_callback]", linked_data);
+ LogLinkedDevice(REQUEST_KIND_PREFIX, "[Update Waiting]", linked_data);
callbacks.linked_data_callback(linked_data, wauthn_error_e(request->GetStatus()),
callbacks.user_data);
- LogDebug(REQUEST_KIND_PREFIX << "More update linked_data can be received. Waiting to recv()");
}
- LogLinkedDevice(REQUEST_KIND_PREFIX, "[linked_data_callback]", linked_data);
- LogDebug(REQUEST_KIND_PREFIX << "There is no more updated linked_data");
+ LogLinkedDevice(REQUEST_KIND_PREFIX, "[Update Done]", linked_data);
callbacks.linked_data_callback(linked_data, wauthn_error_e(request->GetStatus()),
callbacks.user_data);
return WAUTHN_ERROR_NONE;
});
- if (ret != WAUTHN_ERROR_NONE)
- LogError(REQUEST_KIND_PREFIX << "Error on handling callbacks");
+ LogInfo(REQUEST_KIND_PREFIX << "Exiting with result: " << get_error_message(ret));
}
template <typename T>
return try_catch([&]() -> int {
if (options->linked_device != nullptr) // The qrcode_callback should not be called.
{
- LogDebug("Adjust qrcode_callback to null");
+ LogInfo("Adjust callbacks->qrcode_callback to null " <<
+ "because options->linked_device not null");
callbacks->qrcode_callback = nullptr;
}
std::shared_ptr<T> request = std::make_shared<T>();
if (request->SendRequest(client_data, options).Failed())
return request->GetStatus();
- LogDebug("Response: " << get_error_message(request->GetStatus()));
+ LogInfo("SendRequest: " << get_error_message(request->GetStatus()));
std::thread worker([request = std::move(request), callbacks = *callbacks] {
cb_worker(std::move(request), callbacks);
LogWithErrno(err, "connecting socket");
return WAUTHN_ERROR_SOCKET;
}
-
+ LogDebug("socket: " << m_sock);
return WAUTHN_ERROR_NONE;
}
{
int ret = WAUTHN_ERROR_NONE;
if (WAUTHN_ERROR_NONE != (ret = m_sock->Connect(interface))) {
- LogError("Error in SockRAII");
+ LogError("Failed to create socket connection: " << get_error_message(ret));
}
return ret;
}
LogErrno("write");
return WAUTHN_ERROR_SOCKET;
}
+ LogDebug("Wrote size: " << temp);
}
return WAUTHN_ERROR_NONE;
}
LogErrno("read");
return temp;
}
+ LogDebug("Read size: " << temp);
remaining -= temp;
}
return size - remaining;
<< ToHexStr(linkedDevice->identity_key));
}
#else
- (void)prefix1;
- (void)prefix2;
- (void) linkedDevice;
+ if (!linkedDevice)
+ LogInfo(prefix1 << prefix2 << "linked_device: null");
+ else
+ LogInfo(prefix1 << prefix2 << "linked_device: not null");
#endif
}
LogDebug("Resolving symbol: " << name << " from " << m_libraryPath);
void *sym = dlsym(m_libraryHandle, name.c_str());
if (!sym)
- LogError("Unable to resolve symbol: " << name << " from " << m_libraryPath << ": " << dlerror());
+ LogError("Failed to resolve symbol: " << name << " from " << m_libraryPath << ": " << dlerror());
return sym;
}
#include <signal.h>
#include <stdlib.h>
-#include <exception.h>
#include <service.h>
#include <service-file-locker.h>
-#include <webauthn-log.h>
-#include <webauthn-types.h>
+#include <utils.h>
#ifdef GCOV_BUILD
extern "C" void __gcov_flush(void);
{
LogDebug("Start!");
WA::SocketManager manager;
- try{
+ int ret = try_catch([&]() -> int {
auto service = std::make_unique<WA::Service>(
std::make_shared<DLLoader>(WAH_PLUGIN_SO_PATH_HYBRID));
manager.RegisterSocketService(std::move(service));
manager.MainLoop();
+ return WAUTHN_ERROR_NONE;
+ });
+ if (WAUTHN_ERROR_NONE == ret)
return EXIT_SUCCESS;
- } catch (const std::exception &e) {
- LogError("Error in starting service, details:\n" << e.what());
- } catch (...) {
- LogError("Error in starting service, unknown exception occurred");
- }
- return EXIT_FAILURE;
+ else
+ return EXIT_FAILURE;
}
int main(void)
wauthn_error_e result,
void *user_data)
{
- LogDebug("result: " << get_error_message(result));
+ LogDebug("Result: " << get_error_message(result));
user_data_s *userData = GetUserData(user_data);
if (userData != nullptr)
{
wauthn_error_e result,
void *user_data)
{
- LogDebug("result: " << get_error_message(result));
+ LogInfo("Result: " << get_error_message(result));
user_data_s *userData = GetUserData(user_data);
if (userData != nullptr)
{
wauthn_error_e result,
void *user_data)
{
- LogDebug("result: " << get_error_message(result));
+ LogDebug("Result: " << get_error_message(result));
user_data_s *userData = GetUserData(user_data);
if (userData != nullptr)
{
ThrowMsg(ServiceException::InvalidAction, "Invalid call: " << call_type_int);
}
// if we reach this point, the protocol is OK
- LogDebug("Protocol is Done.");
+ LogDebug("ProcessEvent is done.");
return WAUTHN_ERROR_NONE;
});
if (ret != WAUTHN_ERROR_NONE)
{
- LogError("Error on Processing: " << ret);
+ LogError("ProcessEvent is failed: " << get_error_message(ret));
}
}
return WAUTHN_ERROR_NONE;
});
if (ret != WAUTHN_ERROR_NONE)
- LogError("Unhandled Error: " << get_error_message(ret));
+ LogError("Invoke Error: " << get_error_message(ret));
}
template <typename T>
}
else if (1 == isBusy)
{
- ret = m_pluginHybrid->Invoke<int>("wah_cancel");
+ ret = try_catch([&]() -> int {
+ m_pluginHybrid->Invoke<int>("wah_cancel");
+ return WAUTHN_ERROR_NONE;
+ });
}
else
{
int GenericService::HandleNotSupported(Event &&msg)
{
- LogDebug("Shared library is not enabled");
+ LogError("Shared library is unsupported");
MessageBuffer responseBuffer(m_serviceManager->newMessage());
responseBuffer.ModeStreaming();
Serialization::Serialize(responseBuffer, WAUTHN_ERROR_NOT_SUPPORTED);
int GenericService::GetCredentials(SocketManager::ConnectionID connectionID, Cred *creds)
{
socklen_t length = sizeof(ucred);
- if (0 > getsockopt(connectionID.sock, SOL_SOCKET, SO_PEERCRED, &creds->cred, &length)) {
- LogError("getsockopt for get pid failed");
+ int ret = WAUTHN_ERROR_NONE;
+ if (0 > (ret = getsockopt(connectionID.sock, SOL_SOCKET, SO_PEERCRED, &creds->cred, &length))) {
+ LogError("getsockopt for get pid failed: " << get_error_message(ret));
return -1;
}
LogDebug("Client PID: " << creds->cred.pid);
std::vector<char> result(SMACK_LABEL_LEN + 1);
length = SMACK_LABEL_LEN;
- if (0 != getsockopt(connectionID.sock, SOL_SOCKET, SO_PEERSEC, result.data(), &length))
+ if (0 != (ret = getsockopt(connectionID.sock, SOL_SOCKET, SO_PEERSEC, result.data(), &length)))
{
+ LogError("getsockopt for get smack label failed" << get_error_message(ret));
return -1;
- LogError("getsockopt for get smack label failed");
}
creds->smack.assign(result.data(), length);
LogDebug("Client Smack: " << creds->smack);
if ((m_notifyMe = eventfd(0, 0)) < 0)
ThrowErrno(SocketManagerException::InitFailed, "eventfd");
- LogInfo("Eventfd desc: " << m_notifyMe);
+ LogDebug("Eventfd desc: " << m_notifyMe);
RegisterFdForReading(m_notifyMe);
// std::thread bases on pthread so this should work fine
// true if quit mainloop
bool SocketManager::GotSigTerm() const {
- LogDebug("Get signal information");
+ LogInfo("Get signal information");
struct signalfd_siginfo info;
const auto s = TEMP_FAILURE_RETRY(read(m_signalFd, &info, sizeof info));
auto &buffer = desc.buffer;
ssize_t size = read(sock, buffer.Ptr(), buffer.InputSize());
+ LogDebug("Read size: " << size << " from buffer with sock:" << sock);
if (size == 0) {
LogDebug("Reading returned 0 bytes, closing socket: " << sock);
}
void SocketManager::ReadyForWrite(int sock) {
- LogDebug("IN");
auto &desc = m_socketDescriptionVector[sock];
desc.isActiveThisGeneration = true;
auto &buffer = desc.buffer;
ssize_t result = write(sock, buffer.Ptr(), buffer.OutputSize());
+ LogDebug("Wrote size: " << result << " to buffer with sock:" << sock);
+
if (result == -1) {
int err = errno;
switch (err) {
return;
}
else if (ret == 0) {
- LogDebug("Server is deactivating by timeout. (" << SOCKET_TIMEOUT << " secs)");
+ LogInfo("Server is deactivating by timeout. (" << SOCKET_TIMEOUT << " secs)");
return;
}
if (FD_ISSET(m_signalFd, &readSet)) {
}
}
- LogError("No useable sockets were passed by systemd.");
+ LogWarning("There is no usable socket by systemd.");
m_enableActivation = false;
return -1;
}
if (-1 == sockfd)
{
- LogWarning("Creating domain socket because \
- the server is not running with on-demand socket activation.");
+ LogWarning("Creating domain socket");
sockfd = CreateDomainSocketHelp(desc);
}
RegisterFdForReading(sockfd);
LogDebug("Listen on socket: " << sockfd <<
- " Handler: " << desc.serviceHandlerPath.c_str());
+ ", Handler: " << desc.serviceHandlerPath.c_str());
}
void SocketManager::RegisterSocketService(std::unique_ptr<GenericService> service) {
desc.buffer = std::move(buffer);
desc.buffer.ModeOutput();
- LogDebug("Calling ReadyForWrite");
ReadyForWrite(connectionID.sock);
}
}
struct TestContents {
- bool succeeded;
int statusMC;
int statusGA;
- int updateMCRet = -1;
- int updateGARet = -1;
+ int updateMCRet = WAUTHN_ERROR_UNKNOWN;
+ int updateGARet = WAUTHN_ERROR_UNKNOWN;
std::string path;
Buffer credentialRawId;
Buffer userId;
if (ret) {
std::cout << "chsmack command failed\n"
<< "System() returned: " << ret << std::endl;
- contents.succeeded = false;
return;
}
if (ret) {
std::cout << "launching webauthn-image-viewer command failed\n"
<< "System() returned: " << ret << std::endl;
- contents.succeeded = false;
}
}
if (ret != MEDIA_VISION_ERROR_NONE) {
std::cout << "mv_barcode_generate_image failed\n"
<< "Error code: " << ret << std::endl;
- contents.succeeded = false;
} else {
DisplayQR(contents);
}
auto testContents = static_cast<TestContents *>(data);
if (testContents->path.empty() || !qr_contents) {
std::cout << "qrcode_callback failed" << std::endl;
- testContents->succeeded = false;
return;
}
else
{
auto *testContents = static_cast<TestContents *>(data);
auto lock = std::lock_guard{testContents->mutex};
+ testContents->updateMCRet = result;
if (pubkey_cred == nullptr || result != WAUTHN_ERROR_NONE) {
std::cout << __FUNCTION__ << ": response_callback failed\n"
- << "Error code: " << result << std::endl;
+ << "Error code: " << get_error_message(result) << std::endl;
testContents->statusMC = -1;
- testContents->succeeded = false;
return;
}
testContents->credentialRawId = ToBuffer(*pubkey_cred->rawId);
- std::cerr << "MC: credentialRawId: " << LowercaseHexStringOf(testContents->credentialRawId)
+ std::cout << "[MC] credentialRawId: " << LowercaseHexStringOf(testContents->credentialRawId)
<< std::endl;
testContents->transports = pubkey_cred->response->transports;
testContents->statusMC = 1;
if (pubkey_cred->linked_device != nullptr)
testContents->UpdateLinkedData(pubkey_cred->linked_device);
-
- std::cout << "MC: awaiting potential update messages.." << std::endl;
+ std::cout << "[MC] Response: " << get_error_message(result)
+ << ", Wait for update linked data callback.." << std::endl;
}
void GACallback(const wauthn_pubkey_credential_assertion_s *pubkey_cred,
{
auto *testContents = static_cast<TestContents *>(data);
auto lock = std::unique_lock{testContents->mutex};
+ testContents->updateGARet = result;
if (pubkey_cred == nullptr || result != WAUTHN_ERROR_NONE) {
std::cout << __FUNCTION__ << ": response_callback failed\n"
- << "Error code: " << result << std::endl;
+ << "Error code: " << get_error_message(result) << std::endl;
testContents->statusGA = -1;
- testContents->succeeded = false;
return;
}
testContents->statusGA = 1;
if (pubkey_cred->linked_device != nullptr)
testContents->UpdateLinkedData(pubkey_cred->linked_device);
- std::cout << "GA: awaiting potential update messages.." << std::endl;
+ std::cout << "[GA] Response: " << get_error_message(result)
+ << ", Wait for update linked data callback.." << std::endl;
}
void MCUpdateLinkedDataCallback(const wauthn_hybrid_linked_data_s *linked_data,
auto *testContents = static_cast<TestContents *>(data);
std::lock_guard<std::mutex> ulock(testContents->mutex);
if (result != WAUTHN_ERROR_NONE && result != WAUTHN_ERROR_NONE_AND_WAIT) {
- std::cout << __FUNCTION__ << ": failed\n"
- << "Error code: " << result << std::endl;
- testContents->succeeded = false;
+ std::cout << __FUNCTION__ << " failed: "
+ << get_error_message(result) << std::endl;
return;
}
if (testContents->statusMC == 1)
{
- std::cout << "MC: UpdateLinkedDataCallback was called: " << result << std::endl;
+ std::cout << __FUNCTION__ << ": " << get_error_message(result) << std::endl;
testContents->statusMC = 2;
testContents->updateMCRet = result;
}
auto *testContents = static_cast<TestContents *>(data);
auto lock = std::unique_lock{testContents->mutex};
if (result != WAUTHN_ERROR_NONE && result != WAUTHN_ERROR_NONE_AND_WAIT) {
- std::cout << __FUNCTION__ << ": failed\n"
- << "Error code: " << result << std::endl;
- testContents->succeeded = false;
+ std::cout << __FUNCTION__ << " failed: "
+ << get_error_message(result) << std::endl;
return;
}
if (testContents->statusGA == 1)
{
- std::cout << "GA: UpdateLinkedDataCallback was called: " << result << std::endl;
+ std::cout << __FUNCTION__ << ": " << get_error_message(result) << std::endl;
testContents->statusGA = 2;
testContents->updateGARet = result;
}
mcOptions.rp = &rp;
mcOptions.user = &user;
mcOptions.pubkey_cred_params = &pubkeyCredParams;
+ mcOptions.timeout = 60000; // 60s
wauthn_mc_callbacks_s mcCallbacks;
mcCallbacks.qrcode_callback = DisplayQRCallback;
int ret = wauthn_make_credential(&clientData, &mcOptions, &mcCallbacks);
- std::cout << "ret: " << get_error_message(ret) << std::endl;
+ std::cout << "[MC] Request: " << get_error_message(ret) << std::endl;
if (ret != WAUTHN_ERROR_NONE)
return false;
int timeCount = 120;
- std::cout << "MC: Waiting Authenticate with mobile device for 120 seconds.." << std::endl;
+ std::cout << "[MC] Waiting 60 seconds for response.." << std::endl;
while (testContents.statusMC == 0 && timeCount != 0) // exit after called Response CB
{
sleep(1);
}
if (testContents.statusMC != 1) {
- std::cout << "FAILED: Make Credential" << std::endl;
+ std::cout << "[MC] Failed: " << get_error_message(testContents.updateMCRet)
+ << std::endl;
return false;
}
wauthn_hybrid_linked_data_s linkedDevice;
if (testContents.linkedData) {
- std::cout << "linkedData is exist" << std::endl;
+ std::cout << "[GA] State-assisted transaction with linked_data" << std::endl;
contactId = ToWauthnConstBuff(testContents.linkedData->contactId);
linkId = ToWauthnConstBuff(testContents.linkedData->linkId);
linkSecret = ToWauthnConstBuff(testContents.linkedData->linkSecret);
linkedDevice.tunnel_server_domain = &tunnelServerDomain;
linkedDevice.identity_key = &identityKey;
}
+ else
+ std::cout << "[GA] QR-initiated transaction without linked_data" << std::endl;
wauthn_pubkey_cred_request_options_s gaOptions;
std::memset(&gaOptions, 0, sizeof(gaOptions)); // For future compatibility.
- gaOptions.timeout = 120000; // 120s
+ gaOptions.timeout = 60000; // 60s
gaOptions.rpId = rpId;
gaOptions.user_verification = WAUTHN_USER_VERIFICATION_REQUIREMENT_REQUIRED;
gaOptions.allow_credentials = &pubkeyCredDescriptors;
lock.unlock();
ret = wauthn_get_assertion(&clientData, &gaOptions, &gaCallbacks);
- std::cout << "ret: " << get_error_message(ret) << std::endl;
+ std::cout << "[GA] Request: " << get_error_message(ret) << std::endl;
timeCount = 120;
- std::cout << "GA: Waiting Authenticate with mobile device for 120 seconds.." << std::endl;
+ std::cout << "[GA] Waiting 60 seconds for response.." << std::endl;
while (testContents.statusGA == 0 && timeCount != 0) // exit after called Response CB
{
sleep(1);
timeCount--;
}
if (testContents.statusGA != 1) {
- std::cout << "FAILED: Get Assertion" << std::endl;
- testContents.succeeded = false;
+ std::cout << "[GA] Failed: " << get_error_message(testContents.updateGARet)
+ << std::endl;
}
CloseQR();
- timeCount = 120;
- std::cout << "Waiting UpdateLinkedData CBs for 120 seconds.." << std::endl;
- while (((testContents.statusMC == 1 && testContents.updateMCRet != WAUTHN_ERROR_NONE)
- || (testContents.statusGA == 1 && testContents.updateGARet != WAUTHN_ERROR_NONE)
+ timeCount = 300;
+ std::cout << "Waiting 300 seconds for UpdateLinkedData CBs.." << std::endl;
+ while (((testContents.statusMC == 1 && testContents.updateMCRet == WAUTHN_ERROR_NONE)
+ || (testContents.statusMC == 2 && testContents.updateMCRet != WAUTHN_ERROR_NONE)
+ || (testContents.statusGA == 1 && testContents.updateGARet == WAUTHN_ERROR_NONE)
+ || (testContents.statusGA == 2 && testContents.updateGARet != WAUTHN_ERROR_NONE)
) && timeCount != 0)
{
sleep(1);
std::cout << "MC: " << testContents.statusMC << ", GA: " << testContents.statusGA
<< std::endl;
- std::cout << "MCRet: " << testContents.updateMCRet << ", GARet: "
- << testContents.updateGARet << std::endl;
- if (testContents.statusMC != 2 || testContents.statusGA != 2) {
- return testContents.succeeded = false;
- }
- if (testContents.updateMCRet != WAUTHN_ERROR_NONE
- || testContents.updateGARet != WAUTHN_ERROR_NONE)
- {
- return testContents.succeeded = false;
+ std::cout << "[MC] Test result: " << get_error_message(testContents.updateMCRet) << std::endl;
+ std::cout << "[GA] Test result: " << get_error_message(testContents.updateGARet) << std::endl;
+ if (testContents.statusMC != 2 || testContents.statusGA != 2
+ || testContents.updateMCRet != WAUTHN_ERROR_NONE
+ || testContents.updateGARet != WAUTHN_ERROR_NONE) {
+ return false;
}
- return testContents.succeeded;
+ return true;
}
} // anonymous namespace
int main(int argc, char *argv[])
{
- TestContents testContents = {true, 0, 0, -1, -1, "/tmp/webauthn-qrcode.png",
- {}, {}, WAUTHN_TRANSPORT_NONE,
- std::nullopt, false, {}};
+ TestContents testContents = {0, 0, WAUTHN_ERROR_UNKNOWN, WAUTHN_ERROR_UNKNOWN,
+ "/tmp/webauthn-qrcode.png", {}, {},
+ WAUTHN_TRANSPORT_NONE, std::nullopt, false, {}};
if (argc == 2)
{
testContents.negative = true;
else
{
- std::cout << "only -\"n\" option is supported" << std::endl;
+ std::cout << "Only -\"n\" option is supported" << std::endl;
return true;
}
}
bool ret = false;
if (Test(testContents))
- std::cout << "\nTest passed.\n";
+ std::cout << "\nManual test: Successful\n";
else {
- std::cout << "\nTest failed.\n";
+ std::cout << "\nManual test: Failed\n";
ret = true;
}