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;
|
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