mirror of
https://github.com/deneraraujo/OpenVPNAdapter.git
synced 2026-02-11 00:00:08 +08:00
262 lines
8.4 KiB
C++
262 lines
8.4 KiB
C++
// OpenVPN -- An application to securely tunnel IP networks
|
|
// over a single port, with support for SSL/TLS-based
|
|
// session authentication and key exchange,
|
|
// packet encryption, packet authentication, and
|
|
// packet compression.
|
|
//
|
|
// Copyright (C) 2012-2017 OpenVPN Inc.
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Affero General Public License Version 3
|
|
// as published by the Free Software Foundation.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU Affero General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
// along with this program in the COPYING file.
|
|
// If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
#ifndef OPENVPN_APPLECRYPTO_CF_CFHELPER_H
|
|
#define OPENVPN_APPLECRYPTO_CF_CFHELPER_H
|
|
|
|
#include <openvpn/buffer/buffer.hpp>
|
|
#include <openvpn/apple/cf/cf.hpp>
|
|
|
|
// These methods build on the Wrapper classes for Apple Core Foundation objects
|
|
// defined in cf.hpp. They add additional convenience methods, such as dictionary
|
|
// lookup.
|
|
|
|
namespace openvpn {
|
|
namespace CF {
|
|
|
|
// essentially a vector of void *, used as source for array and dictionary constructors
|
|
typedef BufferAllocatedType<CFTypeRef, thread_unsafe_refcount> SrcList;
|
|
|
|
inline Array array(const SrcList& values)
|
|
{
|
|
return array((const void **)values.c_data(), values.size());
|
|
}
|
|
|
|
inline Dict dict(const SrcList& keys, const SrcList& values)
|
|
{
|
|
return dict((const void **)keys.c_data(), (const void **)values.c_data(), std::min(keys.size(), values.size()));
|
|
}
|
|
|
|
inline CFTypeRef mutable_dict_new()
|
|
{
|
|
return CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
|
|
}
|
|
|
|
inline CFTypeRef mutable_array_new()
|
|
{
|
|
return CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
|
|
}
|
|
|
|
// Lookup or create (if absent) an item in a mutable dictionary.
|
|
// Return the item, which will be owned by base.
|
|
template <typename KEY>
|
|
inline CFTypeRef dict_get_create(CFMutableDictionaryRef base,
|
|
const KEY& key,
|
|
CFTypeRef (*create_method)())
|
|
{
|
|
if (base)
|
|
{
|
|
String keystr = string(key);
|
|
CFTypeRef ret = CFDictionaryGetValue(base, keystr()); // try lookup first
|
|
if (!ret)
|
|
{
|
|
// doesn't exist, must create
|
|
ret = (*create_method)();
|
|
CFDictionaryAddValue(base, keystr(), ret);
|
|
CFRelease(ret); // because ret is now owned by base
|
|
}
|
|
return ret;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
// lookup a dict in another dict (base) and return or create if absent
|
|
template <typename KEY>
|
|
inline MutableDict dict_get_create_dict(MutableDict& base, const KEY& key)
|
|
{
|
|
String keystr = string(key);
|
|
return mutable_dict_cast(dict_get_create(base(), keystr(), mutable_dict_new));
|
|
}
|
|
|
|
// lookup an array in a dict (base) and return or create if absent
|
|
template <typename KEY>
|
|
inline MutableArray dict_get_create_array(MutableDict& base, const KEY& key)
|
|
{
|
|
String keystr = string(key);
|
|
return mutable_array_cast(dict_get_create(base(), keystr(), mutable_array_new));
|
|
}
|
|
|
|
// lookup an object in a dictionary (DICT should be a Dict or a MutableDict)
|
|
template <typename DICT, typename KEY>
|
|
inline CFTypeRef dict_get_obj(const DICT& dict, const KEY& key)
|
|
{
|
|
return dict_index(dict, key);
|
|
}
|
|
|
|
// lookup a string in a dictionary (DICT should be a Dict or a MutableDict)
|
|
template <typename DICT, typename KEY>
|
|
inline std::string dict_get_str(const DICT& dict, const KEY& key)
|
|
{
|
|
return cppstring(string_cast(dict_index(dict, key)));
|
|
}
|
|
|
|
// lookup a string in a dictionary (DICT should be a Dict or a MutableDict)
|
|
template <typename DICT, typename KEY>
|
|
inline std::string dict_get_str(const DICT& dict, const KEY& key, const std::string& default_value)
|
|
{
|
|
String str(string_cast(dict_index(dict, key)));
|
|
if (str.defined())
|
|
return cppstring(str());
|
|
else
|
|
return default_value;
|
|
}
|
|
|
|
// lookup an integer in a dictionary (DICT should be a Dict or a MutableDict)
|
|
template <typename DICT, typename KEY>
|
|
inline int dict_get_int(const DICT& dict, const KEY& key, const int default_value)
|
|
{
|
|
int ret;
|
|
Number num = number_cast(dict_index(dict, key));
|
|
if (num.defined() && CFNumberGetValue(num(), kCFNumberIntType, &ret))
|
|
return ret;
|
|
else
|
|
return default_value;
|
|
}
|
|
|
|
// lookup a boolean in a dictionary (DICT should be a Dict or a MutableDict)
|
|
template <typename DICT, typename KEY>
|
|
inline bool dict_get_bool(const DICT& dict, const KEY& key, const bool default_value)
|
|
{
|
|
Bool b = bool_cast(dict_index(dict, key));
|
|
if (b.defined())
|
|
{
|
|
if (b() == kCFBooleanTrue)
|
|
return true;
|
|
else if (b() == kCFBooleanFalse)
|
|
return false;
|
|
}
|
|
return default_value;
|
|
}
|
|
|
|
// like CFDictionarySetValue, but no-op if any args are NULL
|
|
inline void dictionarySetValue(CFMutableDictionaryRef theDict, const void *key, const void *value)
|
|
{
|
|
if (theDict && key && value)
|
|
CFDictionarySetValue(theDict, key, value);
|
|
}
|
|
|
|
// like CFArrayAppendValue, but no-op if any args are NULL
|
|
inline void arrayAppendValue(CFMutableArrayRef theArray, const void *value)
|
|
{
|
|
if (theArray && value)
|
|
CFArrayAppendValue(theArray, value);
|
|
}
|
|
|
|
// set a CFTypeRef in a mutable dictionary
|
|
template <typename KEY>
|
|
inline void dict_set_obj(MutableDict& dict, const KEY& key, CFTypeRef value)
|
|
{
|
|
String keystr = string(key);
|
|
dictionarySetValue(dict(), keystr(), value);
|
|
}
|
|
|
|
// set a string in a mutable dictionary
|
|
|
|
template <typename KEY, typename VALUE>
|
|
inline void dict_set_str(MutableDict& dict, const KEY& key, const VALUE& value)
|
|
{
|
|
String keystr = string(key);
|
|
String valstr = string(value);
|
|
dictionarySetValue(dict(), keystr(), valstr());
|
|
}
|
|
|
|
// set a number in a mutable dictionary
|
|
|
|
template <typename KEY>
|
|
inline void dict_set_int(MutableDict& dict, const KEY& key, int value)
|
|
{
|
|
String keystr = string(key);
|
|
Number num = number_from_int(value);
|
|
dictionarySetValue(dict(), keystr(), num());
|
|
}
|
|
|
|
template <typename KEY>
|
|
inline void dict_set_int32(MutableDict& dict, const KEY& key, SInt32 value)
|
|
{
|
|
String keystr = string(key);
|
|
Number num = number_from_int32(value);
|
|
dictionarySetValue(dict(), keystr(), num());
|
|
}
|
|
|
|
template <typename KEY>
|
|
inline void dict_set_long_long(MutableDict& dict, const KEY& key, long long value)
|
|
{
|
|
String keystr = string(key);
|
|
Number num = number_from_long_long(value);
|
|
dictionarySetValue(dict(), keystr(), num());
|
|
}
|
|
|
|
template <typename KEY>
|
|
inline void dict_set_index(MutableDict& dict, const KEY& key, CFIndex value)
|
|
{
|
|
String keystr = string(key);
|
|
Number num = number_from_index(value);
|
|
dictionarySetValue((CFMutableDictionaryRef)dict(), keystr(), num());
|
|
}
|
|
|
|
// set a boolean in a mutable dictionary
|
|
|
|
template <typename KEY>
|
|
inline void dict_set_bool(MutableDict& dict, const KEY& key, bool value)
|
|
{
|
|
String keystr = string(key);
|
|
CFBooleanRef boolref = value ? kCFBooleanTrue : kCFBooleanFalse;
|
|
dictionarySetValue(dict(), keystr(), boolref);
|
|
}
|
|
|
|
// append string to a mutable array
|
|
|
|
template <typename VALUE>
|
|
inline void array_append_str(MutableArray& array, const VALUE& value)
|
|
{
|
|
String valstr = string(value);
|
|
arrayAppendValue(array(), valstr());
|
|
}
|
|
|
|
// append a number to a mutable array
|
|
|
|
inline void array_append_int(MutableArray& array, int value)
|
|
{
|
|
Number num = number_from_int(value);
|
|
arrayAppendValue(array(), num());
|
|
}
|
|
|
|
inline void array_append_int32(MutableArray& array, SInt32 value)
|
|
{
|
|
Number num = number_from_int32(value);
|
|
arrayAppendValue(array(), num());
|
|
}
|
|
|
|
inline void array_append_long_long(MutableArray& array, long long value)
|
|
{
|
|
Number num = number_from_long_long(value);
|
|
arrayAppendValue(array(), num());
|
|
}
|
|
|
|
inline void array_append_index(MutableArray& array, CFIndex value)
|
|
{
|
|
Number num = number_from_index(value);
|
|
arrayAppendValue(array(), num());
|
|
}
|
|
}
|
|
}
|
|
#endif
|