Security: add security_runtime_error
Signed-off-by: Simon Rozman <simon@rozman.si>
This commit is contained in:
parent
945d6d819e
commit
e15c6fc25a
134
include/MacStd/Security.hpp
Normal file
134
include/MacStd/Security.hpp
Normal file
@ -0,0 +1,134 @@
|
||||
/*
|
||||
SPDX-License-Identifier: MIT
|
||||
Copyright © 2025 Amebis
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common.hpp"
|
||||
#import <Security/Security.h>
|
||||
|
||||
namespace macstd
|
||||
{
|
||||
///
|
||||
/// Security runtime error
|
||||
///
|
||||
class security_runtime_error : public num_runtime_error<OSStatus>
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Constructs an exception
|
||||
///
|
||||
/// \param[in] num WinSock2 error code
|
||||
///
|
||||
security_runtime_error(error_type num) : num_runtime_error<OSStatus>(num, message(num))
|
||||
{
|
||||
}
|
||||
|
||||
///
|
||||
/// Constructs an exception
|
||||
///
|
||||
/// \param[in] num WinSock2 error code
|
||||
/// \param[in] msg Error message
|
||||
///
|
||||
security_runtime_error(error_type num, const std::string &msg) : num_runtime_error<OSStatus>(num, msg + ": " + message(num))
|
||||
{
|
||||
}
|
||||
|
||||
///
|
||||
/// Constructs an exception
|
||||
///
|
||||
/// \param[in] num WinSock2 error code
|
||||
/// \param[in] msg Error message
|
||||
///
|
||||
security_runtime_error(error_type num, const char *msg) : num_runtime_error<OSStatus>(num, std::string(msg) + ": " + message(num))
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
///
|
||||
/// Returns a string explaining the meaning of a security result code
|
||||
///
|
||||
/// \sa [SecCopyErrorMessageString function](https://developer.apple.com/documentation/security/seccopyerrormessagestring)
|
||||
///
|
||||
static std::string message(error_type num)
|
||||
{
|
||||
// Handle common errors Apple does not provide message strings for.
|
||||
switch (num) {
|
||||
case errAuthorizationCanceled: return "Authorization was canceled by user";
|
||||
case errAuthorizationDenied: return "Authorization was denied";
|
||||
case errAuthorizationInteractionNotAllowed: return "User interaction not allowed for authorization";
|
||||
}
|
||||
auto cfstr = SecCopyErrorMessageString(num, NULL);
|
||||
if (!cfstr)
|
||||
return "Security Framework error " + std::to_string(num);
|
||||
auto ptr = CFStringGetCStringPtr(cfstr, kCFStringEncodingUTF8);
|
||||
if (!ptr) {
|
||||
CFRelease(cfstr);
|
||||
return "Security Framework error " + std::to_string(num);
|
||||
}
|
||||
std::string str(ptr);
|
||||
CFRelease(cfstr);
|
||||
return str;
|
||||
}
|
||||
};
|
||||
|
||||
///
|
||||
/// Authorization reference wrapper class
|
||||
///
|
||||
class authorization : public handle<AuthorizationRef, static_cast<AuthorizationRef>(NULL)>
|
||||
{
|
||||
MACSTD_HANDLE_IMPL(authorization, AuthorizationRef, static_cast<AuthorizationRef>(NULL))
|
||||
|
||||
public:
|
||||
///
|
||||
/// Creates a new authorization reference and provides an option to authorize or preauthorize rights
|
||||
///
|
||||
/// \sa [AuthorizationCreate function](https://developer.apple.com/documentation/security/authorizationcreate)
|
||||
///
|
||||
authorization(const AuthorizationRights* rights, const AuthorizationEnvironment* environment, AuthorizationFlags flags)
|
||||
{
|
||||
AuthorizationRef h;
|
||||
OSStatus status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &h);
|
||||
if (status != errAuthorizationSuccess)
|
||||
throw security_runtime_error(status, "AuthorizationCreate failed");
|
||||
this->m_h = h;
|
||||
}
|
||||
|
||||
///
|
||||
/// Internalizes the external representation of an authorization reference
|
||||
///
|
||||
/// \sa [AuthorizationCreateFromExternalForm function](https://developer.apple.com/documentation/security/authorizationcreatefromexternalform)
|
||||
///
|
||||
authorization(const AuthorizationExternalForm& extForm)
|
||||
{
|
||||
AuthorizationRef h;
|
||||
OSStatus status = AuthorizationCreateFromExternalForm(&extForm, &h);
|
||||
if (status != errAuthorizationSuccess)
|
||||
throw security_runtime_error(status, "AuthorizationCreateFromExternalForm failed");
|
||||
this->m_h = h;
|
||||
}
|
||||
|
||||
///
|
||||
/// Releases an object handle
|
||||
///
|
||||
/// \sa [AuthorizationFree function](https://developer.apple.com/documentation/security/authorizationfree)
|
||||
///
|
||||
virtual ~authorization()
|
||||
{
|
||||
if (this->m_h != static_cast<AuthorizationRef>(NULL))
|
||||
free_internal();
|
||||
}
|
||||
|
||||
protected:
|
||||
///
|
||||
/// Releases an object handle
|
||||
///
|
||||
/// \sa [AuthorizationFree function](https://developer.apple.com/documentation/security/authorizationfree)
|
||||
///
|
||||
void free_internal() noexcept override
|
||||
{
|
||||
AuthorizationFree(this->m_h, kAuthorizationFlagDefaults);
|
||||
}
|
||||
};
|
||||
}
|
@ -431,4 +431,49 @@ namespace macstd
|
||||
///
|
||||
virtual T duplicate_internal(_In_ T h) const = 0;
|
||||
};
|
||||
|
||||
|
||||
///
|
||||
/// Numerical runtime error
|
||||
///
|
||||
template <typename _Tn>
|
||||
class num_runtime_error : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
typedef _Tn error_type; ///< Error number type
|
||||
|
||||
public:
|
||||
///
|
||||
/// Constructs an exception
|
||||
///
|
||||
/// \param[in] num Numeric error code
|
||||
/// \param[in] msg Error message
|
||||
///
|
||||
num_runtime_error(_In_ error_type num, _In_ const std::string& msg) :
|
||||
m_num(num),
|
||||
runtime_error(msg)
|
||||
{}
|
||||
|
||||
///
|
||||
/// Constructs an exception
|
||||
///
|
||||
/// \param[in] num Numeric error code
|
||||
/// \param[in] msg Error message
|
||||
///
|
||||
num_runtime_error(_In_ error_type num, _In_z_ const char *msg) :
|
||||
m_num(num),
|
||||
runtime_error(msg)
|
||||
{}
|
||||
|
||||
///
|
||||
/// Returns the error number
|
||||
///
|
||||
error_type number() const
|
||||
{
|
||||
return m_num;
|
||||
}
|
||||
|
||||
protected:
|
||||
error_type m_num; ///< Numeric error code
|
||||
};
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user