[WIP] Added wireguard, prepare to test and debug
This commit is contained in:
parent
e644575bc5
commit
7c7f77adc6
98 changed files with 4410 additions and 302 deletions
24
.gitignore
vendored
24
.gitignore
vendored
|
@ -24,6 +24,29 @@ ui_*.h
|
||||||
Makefile*
|
Makefile*
|
||||||
*build-*
|
*build-*
|
||||||
|
|
||||||
|
# Qt-es
|
||||||
|
client/.xcode/
|
||||||
|
client/.qmake.cache
|
||||||
|
client/.qmake.stash
|
||||||
|
client/*.pro.user
|
||||||
|
client/*.pro.user.*
|
||||||
|
client/*.qbs.user
|
||||||
|
client/*.qbs.user.*
|
||||||
|
client/*.moc
|
||||||
|
client/moc_*.cpp
|
||||||
|
client/qrc_*.cpp
|
||||||
|
client/ui_*.h
|
||||||
|
client/ui_*.cpp
|
||||||
|
client/Makefile*
|
||||||
|
client/*build-*
|
||||||
|
client/AmneziaVPN.xcodeproj
|
||||||
|
client/Debug-iphonesimulator
|
||||||
|
client/amneziavpn_plugin_import.cpp
|
||||||
|
client/amneziavpn_qml_plugin_import.cpp
|
||||||
|
client/qmlcache_loader.cpp
|
||||||
|
client/rep_ipc_interface_replica.h
|
||||||
|
client/resources_qmlcache.qrc
|
||||||
|
|
||||||
# QtCreator
|
# QtCreator
|
||||||
|
|
||||||
*.autosave
|
*.autosave
|
||||||
|
@ -37,6 +60,7 @@ CMakeLists.txt.user*
|
||||||
|
|
||||||
# MACOS files
|
# MACOS files
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
client/.DS_Store
|
||||||
._.DS_Store
|
._.DS_Store
|
||||||
._*
|
._*
|
||||||
*.dmg
|
*.dmg
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
|
* Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||||
*
|
*
|
||||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||||
|
|
|
@ -58,9 +58,15 @@ ios: {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CONFIG(iphonesimulator, iphoneos|iphonesimulator) {
|
CONFIG(iphonesimulator, iphoneos|iphonesimulator) {
|
||||||
INCLUDEPATH += $$PWD/ios/simulator
|
INCLUDEPATH += $$PWD/ios/iphone
|
||||||
HEADERS += $$PWD/ios/simulator/botan_all.h
|
HEADERS += $$PWD/ios/iphone/botan_all.h
|
||||||
SOURCES += $$PWD/ios/simulator/botan_all.cpp
|
SOURCES += $$PWD/ios/iphone/botan_all.cpp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# CONFIG(iphonesimulator, iphoneos|iphonesimulator) {
|
||||||
|
# INCLUDEPATH += $$PWD/ios/simulator
|
||||||
|
# HEADERS += $$PWD/ios/simulator/botan_all.h
|
||||||
|
# SOURCES += $$PWD/ios/simulator/botan_all.cpp
|
||||||
|
# }
|
||||||
}
|
}
|
||||||
|
|
247
client/AmneziaVPN-Swift.h
Normal file
247
client/AmneziaVPN-Swift.h
Normal file
|
@ -0,0 +1,247 @@
|
||||||
|
#ifndef AmneziaVPN_Swift_h
|
||||||
|
#define AmneziaVPN_Swift_h
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wgcc-compat"
|
||||||
|
|
||||||
|
#if !defined(__has_include)
|
||||||
|
# define __has_include(x) 0
|
||||||
|
#endif
|
||||||
|
#if !defined(__has_attribute)
|
||||||
|
# define __has_attribute(x) 0
|
||||||
|
#endif
|
||||||
|
#if !defined(__has_feature)
|
||||||
|
# define __has_feature(x) 0
|
||||||
|
#endif
|
||||||
|
#if !defined(__has_warning)
|
||||||
|
# define __has_warning(x) 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __has_include(<swift/objc-prologue.h>)
|
||||||
|
# include <swift/objc-prologue.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#pragma clang diagnostic ignored "-Wauto-import"
|
||||||
|
#include <Foundation/Foundation.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#if !defined(SWIFT_TYPEDEFS)
|
||||||
|
# define SWIFT_TYPEDEFS 1
|
||||||
|
# if __has_include(<uchar.h>)
|
||||||
|
# include <uchar.h>
|
||||||
|
# elif !defined(__cplusplus)
|
||||||
|
typedef uint_least16_t char16_t;
|
||||||
|
typedef uint_least32_t char32_t;
|
||||||
|
# endif
|
||||||
|
typedef float swift_float2 __attribute__((__ext_vector_type__(2)));
|
||||||
|
typedef float swift_float3 __attribute__((__ext_vector_type__(3)));
|
||||||
|
typedef float swift_float4 __attribute__((__ext_vector_type__(4)));
|
||||||
|
typedef double swift_double2 __attribute__((__ext_vector_type__(2)));
|
||||||
|
typedef double swift_double3 __attribute__((__ext_vector_type__(3)));
|
||||||
|
typedef double swift_double4 __attribute__((__ext_vector_type__(4)));
|
||||||
|
typedef int swift_int2 __attribute__((__ext_vector_type__(2)));
|
||||||
|
typedef int swift_int3 __attribute__((__ext_vector_type__(3)));
|
||||||
|
typedef int swift_int4 __attribute__((__ext_vector_type__(4)));
|
||||||
|
typedef unsigned int swift_uint2 __attribute__((__ext_vector_type__(2)));
|
||||||
|
typedef unsigned int swift_uint3 __attribute__((__ext_vector_type__(3)));
|
||||||
|
typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4)));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(SWIFT_PASTE)
|
||||||
|
# define SWIFT_PASTE_HELPER(x, y) x##y
|
||||||
|
# define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y)
|
||||||
|
#endif
|
||||||
|
#if !defined(SWIFT_METATYPE)
|
||||||
|
# define SWIFT_METATYPE(X) Class
|
||||||
|
#endif
|
||||||
|
#if !defined(SWIFT_CLASS_PROPERTY)
|
||||||
|
# if __has_feature(objc_class_property)
|
||||||
|
# define SWIFT_CLASS_PROPERTY(...) __VA_ARGS__
|
||||||
|
# else
|
||||||
|
# define SWIFT_CLASS_PROPERTY(...)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __has_attribute(objc_runtime_name)
|
||||||
|
# define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X)))
|
||||||
|
#else
|
||||||
|
# define SWIFT_RUNTIME_NAME(X)
|
||||||
|
#endif
|
||||||
|
#if __has_attribute(swift_name)
|
||||||
|
# define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X)))
|
||||||
|
#else
|
||||||
|
# define SWIFT_COMPILE_NAME(X)
|
||||||
|
#endif
|
||||||
|
#if __has_attribute(objc_method_family)
|
||||||
|
# define SWIFT_METHOD_FAMILY(X) __attribute__((objc_method_family(X)))
|
||||||
|
#else
|
||||||
|
# define SWIFT_METHOD_FAMILY(X)
|
||||||
|
#endif
|
||||||
|
#if __has_attribute(noescape)
|
||||||
|
# define SWIFT_NOESCAPE __attribute__((noescape))
|
||||||
|
#else
|
||||||
|
# define SWIFT_NOESCAPE
|
||||||
|
#endif
|
||||||
|
#if __has_attribute(ns_consumed)
|
||||||
|
# define SWIFT_RELEASES_ARGUMENT __attribute__((ns_consumed))
|
||||||
|
#else
|
||||||
|
# define SWIFT_RELEASES_ARGUMENT
|
||||||
|
#endif
|
||||||
|
#if __has_attribute(warn_unused_result)
|
||||||
|
# define SWIFT_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
|
||||||
|
#else
|
||||||
|
# define SWIFT_WARN_UNUSED_RESULT
|
||||||
|
#endif
|
||||||
|
#if __has_attribute(noreturn)
|
||||||
|
# define SWIFT_NORETURN __attribute__((noreturn))
|
||||||
|
#else
|
||||||
|
# define SWIFT_NORETURN
|
||||||
|
#endif
|
||||||
|
#if !defined(SWIFT_CLASS_EXTRA)
|
||||||
|
# define SWIFT_CLASS_EXTRA
|
||||||
|
#endif
|
||||||
|
#if !defined(SWIFT_PROTOCOL_EXTRA)
|
||||||
|
# define SWIFT_PROTOCOL_EXTRA
|
||||||
|
#endif
|
||||||
|
#if !defined(SWIFT_ENUM_EXTRA)
|
||||||
|
# define SWIFT_ENUM_EXTRA
|
||||||
|
#endif
|
||||||
|
#if !defined(SWIFT_CLASS)
|
||||||
|
# if __has_attribute(objc_subclassing_restricted)
|
||||||
|
# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA
|
||||||
|
# define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
|
||||||
|
# else
|
||||||
|
# define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
|
||||||
|
# define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#if !defined(SWIFT_RESILIENT_CLASS)
|
||||||
|
# if __has_attribute(objc_class_stub)
|
||||||
|
# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME) __attribute__((objc_class_stub))
|
||||||
|
# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_class_stub)) SWIFT_CLASS_NAMED(SWIFT_NAME)
|
||||||
|
# else
|
||||||
|
# define SWIFT_RESILIENT_CLASS(SWIFT_NAME) SWIFT_CLASS(SWIFT_NAME)
|
||||||
|
# define SWIFT_RESILIENT_CLASS_NAMED(SWIFT_NAME) SWIFT_CLASS_NAMED(SWIFT_NAME)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(SWIFT_PROTOCOL)
|
||||||
|
# define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA
|
||||||
|
# define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(SWIFT_EXTENSION)
|
||||||
|
# define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(OBJC_DESIGNATED_INITIALIZER)
|
||||||
|
# if __has_attribute(objc_designated_initializer)
|
||||||
|
# define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
|
||||||
|
# else
|
||||||
|
# define OBJC_DESIGNATED_INITIALIZER
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#if !defined(SWIFT_ENUM_ATTR)
|
||||||
|
# if defined(__has_attribute) && __has_attribute(enum_extensibility)
|
||||||
|
# define SWIFT_ENUM_ATTR(_extensibility) __attribute__((enum_extensibility(_extensibility)))
|
||||||
|
# else
|
||||||
|
# define SWIFT_ENUM_ATTR(_extensibility)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#if !defined(SWIFT_ENUM)
|
||||||
|
# define SWIFT_ENUM(_type, _name, _extensibility) enum _name : _type _name; enum SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type
|
||||||
|
# if __has_feature(generalized_swift_name)
|
||||||
|
# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_ATTR(_extensibility) SWIFT_ENUM_EXTRA _name : _type
|
||||||
|
# else
|
||||||
|
# define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME, _extensibility) SWIFT_ENUM(_type, _name, _extensibility)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#if !defined(SWIFT_UNAVAILABLE)
|
||||||
|
# define SWIFT_UNAVAILABLE __attribute__((unavailable))
|
||||||
|
#endif
|
||||||
|
#if !defined(SWIFT_UNAVAILABLE_MSG)
|
||||||
|
# define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg)))
|
||||||
|
#endif
|
||||||
|
#if !defined(SWIFT_AVAILABILITY)
|
||||||
|
# define SWIFT_AVAILABILITY(plat, ...) __attribute__((availability(plat, __VA_ARGS__)))
|
||||||
|
#endif
|
||||||
|
#if !defined(SWIFT_WEAK_IMPORT)
|
||||||
|
# define SWIFT_WEAK_IMPORT __attribute__((weak_import))
|
||||||
|
#endif
|
||||||
|
#if !defined(SWIFT_DEPRECATED)
|
||||||
|
# define SWIFT_DEPRECATED __attribute__((deprecated))
|
||||||
|
#endif
|
||||||
|
#if !defined(SWIFT_DEPRECATED_MSG)
|
||||||
|
# define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__)))
|
||||||
|
#endif
|
||||||
|
#if __has_feature(attribute_diagnose_if_objc)
|
||||||
|
# define SWIFT_DEPRECATED_OBJC(Msg) __attribute__((diagnose_if(1, Msg, "warning")))
|
||||||
|
#else
|
||||||
|
# define SWIFT_DEPRECATED_OBJC(Msg) SWIFT_DEPRECATED_MSG(Msg)
|
||||||
|
#endif
|
||||||
|
#if !defined(IBSegueAction)
|
||||||
|
# define IBSegueAction
|
||||||
|
#endif
|
||||||
|
#if __has_feature(modules)
|
||||||
|
#if __has_warning("-Watimport-in-framework-header")
|
||||||
|
#pragma clang diagnostic ignored "-Watimport-in-framework-header"
|
||||||
|
#endif
|
||||||
|
@import Foundation;
|
||||||
|
@import ObjectiveC;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#pragma clang diagnostic ignored "-Wproperty-attribute-mismatch"
|
||||||
|
#pragma clang diagnostic ignored "-Wduplicate-method-arg"
|
||||||
|
#if __has_warning("-Wpragma-clang-attribute")
|
||||||
|
# pragma clang diagnostic ignored "-Wpragma-clang-attribute"
|
||||||
|
#endif
|
||||||
|
#pragma clang diagnostic ignored "-Wunknown-pragmas"
|
||||||
|
#pragma clang diagnostic ignored "-Wnullability"
|
||||||
|
|
||||||
|
#if __has_attribute(external_source_symbol)
|
||||||
|
# pragma push_macro("any")
|
||||||
|
# undef any
|
||||||
|
# pragma clang attribute push(__attribute__((external_source_symbol(language="Swift", defined_in="AmneziaVPN",generated_declaration))), apply_to=any(function,enum,objc_interface,objc_category,objc_protocol))
|
||||||
|
# pragma pop_macro("any")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@class NSString;
|
||||||
|
@class NSData;
|
||||||
|
enum ConnectionState : NSInteger;
|
||||||
|
@class NSDate;
|
||||||
|
@class NSNumber;
|
||||||
|
@class VPNIPAddressRange;
|
||||||
|
|
||||||
|
SWIFT_CLASS("_TtC10AmneziaVPN18IOSVpnProtocolImpl")
|
||||||
|
@interface IOSVpnProtocolImpl : NSObject
|
||||||
|
- (nonnull instancetype)initWithBundleID:(NSString * _Nonnull)bundleID privateKey:(NSData * _Nonnull)privateKey deviceIpv4Address:(NSString * _Nonnull)deviceIpv4Address deviceIpv6Address:(NSString * _Nonnull)deviceIpv6Address closure:(void (^ _Nonnull)(enum ConnectionState, NSDate * _Nullable))closure callback:(void (^ _Nonnull)(BOOL))callback OBJC_DESIGNATED_INITIALIZER;
|
||||||
|
- (void)connectWithDnsServer:(NSString * _Nonnull)dnsServer serverIpv6Gateway:(NSString * _Nonnull)serverIpv6Gateway serverPublicKey:(NSString * _Nonnull)serverPublicKey serverIpv4AddrIn:(NSString * _Nonnull)serverIpv4AddrIn serverPort:(NSInteger)serverPort allowedIPAddressRanges:(NSArray<VPNIPAddressRange *> * _Nonnull)allowedIPAddressRanges ipv6Enabled:(Boolean)enabled reason:(NSInteger)reason failureCallback:(void (^ _Nonnull)(void))failureCallback;
|
||||||
|
- (void)disconnect;
|
||||||
|
- (void)checkStatusWithCallback:(void (^ _Nonnull)(NSString * _Nonnull, NSString * _Nonnull, NSString * _Nonnull))callback;
|
||||||
|
- (nonnull instancetype)init SWIFT_UNAVAILABLE;
|
||||||
|
+ (nonnull instancetype)new SWIFT_UNAVAILABLE_MSG("-init is unavailable");
|
||||||
|
@end
|
||||||
|
|
||||||
|
typedef SWIFT_ENUM(NSInteger, ConnectionState, closed) {
|
||||||
|
ConnectionStateError = 0,
|
||||||
|
ConnectionStateConnected = 1,
|
||||||
|
ConnectionStateDisconnected = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SWIFT_CLASS("_TtC10AmneziaVPN17VPNIPAddressRange")
|
||||||
|
@interface VPNIPAddressRange : NSObject
|
||||||
|
- (nonnull instancetype)initWithAddress:(NSString * _Nonnull)address networkPrefixLength:(uint8_t)networkPrefixLength isIpv6:(BOOL)isIpv6 OBJC_DESIGNATED_INITIALIZER;
|
||||||
|
- (nonnull instancetype)init SWIFT_UNAVAILABLE;
|
||||||
|
+ (nonnull instancetype)new SWIFT_UNAVAILABLE_MSG("-init is unavailable");
|
||||||
|
@end
|
||||||
|
|
||||||
|
#if __has_attribute(external_source_symbol)
|
||||||
|
# pragma clang attribute pop
|
||||||
|
#endif
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
#endif /* AmneziaVPN_Swift_h */
|
||||||
|
|
14
client/AmneziaVPNRelease.entitlements
Normal file
14
client/AmneziaVPNRelease.entitlements
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>com.apple.developer.networking.networkextension</key>
|
||||||
|
<array>
|
||||||
|
<string>packet-tunnel-provider</string>
|
||||||
|
</array>
|
||||||
|
<key>com.apple.security.application-groups</key>
|
||||||
|
<array/>
|
||||||
|
<key>com.apple.security.files.user-selected.read-write</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
BIN
client/Debug-iphoneos/AmneziaVPN.app/AmneziaVPN
Executable file
BIN
client/Debug-iphoneos/AmneziaVPN.app/AmneziaVPN
Executable file
Binary file not shown.
BIN
client/Debug-iphoneos/AmneziaVPN.app/Default-568h@2x.png
Normal file
BIN
client/Debug-iphoneos/AmneziaVPN.app/Default-568h@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.6 KiB |
BIN
client/Debug-iphoneos/AmneziaVPN.app/Info.plist
Normal file
BIN
client/Debug-iphoneos/AmneziaVPN.app/Info.plist
Normal file
Binary file not shown.
BIN
client/Debug-iphoneos/AmneziaVPN.app/LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib
generated
Normal file
BIN
client/Debug-iphoneos/AmneziaVPN.app/LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib
generated
Normal file
Binary file not shown.
Binary file not shown.
BIN
client/Debug-iphoneos/AmneziaVPN.app/LaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib
generated
Normal file
BIN
client/Debug-iphoneos/AmneziaVPN.app/LaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib
generated
Normal file
Binary file not shown.
1
client/Debug-iphoneos/AmneziaVPN.app/PkgInfo
Normal file
1
client/Debug-iphoneos/AmneziaVPN.app/PkgInfo
Normal file
|
@ -0,0 +1 @@
|
||||||
|
APPL????
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,113 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>files</key>
|
||||||
|
<dict>
|
||||||
|
<key>Info.plist</key>
|
||||||
|
<data>
|
||||||
|
Vpf+GoPF6i8Z3silvQ81FJOPi2k=
|
||||||
|
</data>
|
||||||
|
<key>embedded.mobileprovision</key>
|
||||||
|
<data>
|
||||||
|
XsqCdj+fjmJRIQlbMFY/hQ8MMvA=
|
||||||
|
</data>
|
||||||
|
</dict>
|
||||||
|
<key>files2</key>
|
||||||
|
<dict>
|
||||||
|
<key>embedded.mobileprovision</key>
|
||||||
|
<dict>
|
||||||
|
<key>hash2</key>
|
||||||
|
<data>
|
||||||
|
MIAxFA1iZa5ZIg95xlnuoq1pWj1eqsV143zU3y/fs/w=
|
||||||
|
</data>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<key>rules</key>
|
||||||
|
<dict>
|
||||||
|
<key>^.*</key>
|
||||||
|
<true/>
|
||||||
|
<key>^.*\.lproj/</key>
|
||||||
|
<dict>
|
||||||
|
<key>optional</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>1000</real>
|
||||||
|
</dict>
|
||||||
|
<key>^.*\.lproj/locversion.plist$</key>
|
||||||
|
<dict>
|
||||||
|
<key>omit</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>1100</real>
|
||||||
|
</dict>
|
||||||
|
<key>^Base\.lproj/</key>
|
||||||
|
<dict>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>1010</real>
|
||||||
|
</dict>
|
||||||
|
<key>^version.plist$</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
<key>rules2</key>
|
||||||
|
<dict>
|
||||||
|
<key>.*\.dSYM($|/)</key>
|
||||||
|
<dict>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>11</real>
|
||||||
|
</dict>
|
||||||
|
<key>^(.*/)?\.DS_Store$</key>
|
||||||
|
<dict>
|
||||||
|
<key>omit</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>2000</real>
|
||||||
|
</dict>
|
||||||
|
<key>^.*</key>
|
||||||
|
<true/>
|
||||||
|
<key>^.*\.lproj/</key>
|
||||||
|
<dict>
|
||||||
|
<key>optional</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>1000</real>
|
||||||
|
</dict>
|
||||||
|
<key>^.*\.lproj/locversion.plist$</key>
|
||||||
|
<dict>
|
||||||
|
<key>omit</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>1100</real>
|
||||||
|
</dict>
|
||||||
|
<key>^Base\.lproj/</key>
|
||||||
|
<dict>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>1010</real>
|
||||||
|
</dict>
|
||||||
|
<key>^Info\.plist$</key>
|
||||||
|
<dict>
|
||||||
|
<key>omit</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>20</real>
|
||||||
|
</dict>
|
||||||
|
<key>^PkgInfo$</key>
|
||||||
|
<dict>
|
||||||
|
<key>omit</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>20</real>
|
||||||
|
</dict>
|
||||||
|
<key>^embedded\.provisionprofile$</key>
|
||||||
|
<dict>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>20</real>
|
||||||
|
</dict>
|
||||||
|
<key>^version\.plist$</key>
|
||||||
|
<dict>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>20</real>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
Binary file not shown.
|
@ -0,0 +1,205 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>files</key>
|
||||||
|
<dict>
|
||||||
|
<key>Default-568h@2x.png</key>
|
||||||
|
<data>
|
||||||
|
poDYGy1JWXBgPH3/wCEBNbVTOks=
|
||||||
|
</data>
|
||||||
|
<key>Info.plist</key>
|
||||||
|
<data>
|
||||||
|
TCqIXlhIQW7A69Ve4j1KetGfmt4=
|
||||||
|
</data>
|
||||||
|
<key>LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib</key>
|
||||||
|
<data>
|
||||||
|
QDw1rEcub/rLRhQ/kjizyHomgLM=
|
||||||
|
</data>
|
||||||
|
<key>LaunchScreen.storyboardc/Info.plist</key>
|
||||||
|
<data>
|
||||||
|
n2t8gsDpfE6XkhG31p7IQJRxTxU=
|
||||||
|
</data>
|
||||||
|
<key>LaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib</key>
|
||||||
|
<data>
|
||||||
|
U0x8EM0781fCPb62BbZIXKeDlZ4=
|
||||||
|
</data>
|
||||||
|
<key>PkgInfo</key>
|
||||||
|
<data>
|
||||||
|
n57qDP4tZfLD1rCS43W0B4LQjzE=
|
||||||
|
</data>
|
||||||
|
<key>PlugIns/WireGuardNetworkExtension.appex/Info.plist</key>
|
||||||
|
<data>
|
||||||
|
Vpf+GoPF6i8Z3silvQ81FJOPi2k=
|
||||||
|
</data>
|
||||||
|
<key>PlugIns/WireGuardNetworkExtension.appex/WireGuardNetworkExtension</key>
|
||||||
|
<data>
|
||||||
|
lXak+Jrx39GLG9y+yV7abfizjj0=
|
||||||
|
</data>
|
||||||
|
<key>PlugIns/WireGuardNetworkExtension.appex/_CodeSignature/CodeResources</key>
|
||||||
|
<data>
|
||||||
|
ghJ0YXx7j96o3qv/XzbZ1TssY4s=
|
||||||
|
</data>
|
||||||
|
<key>PlugIns/WireGuardNetworkExtension.appex/embedded.mobileprovision</key>
|
||||||
|
<data>
|
||||||
|
XsqCdj+fjmJRIQlbMFY/hQ8MMvA=
|
||||||
|
</data>
|
||||||
|
<key>embedded.mobileprovision</key>
|
||||||
|
<data>
|
||||||
|
CN/zNwvfKR8n8CTJE8vTbS8nhJY=
|
||||||
|
</data>
|
||||||
|
</dict>
|
||||||
|
<key>files2</key>
|
||||||
|
<dict>
|
||||||
|
<key>Default-568h@2x.png</key>
|
||||||
|
<dict>
|
||||||
|
<key>hash2</key>
|
||||||
|
<data>
|
||||||
|
UdHegDh1HZlDpSEYtzMl4sjA9q8uvK4K9OL0sRTFD6M=
|
||||||
|
</data>
|
||||||
|
</dict>
|
||||||
|
<key>LaunchScreen.storyboardc/01J-lp-oVM-view-Ze5-6b-2t3.nib</key>
|
||||||
|
<dict>
|
||||||
|
<key>hash2</key>
|
||||||
|
<data>
|
||||||
|
dHm6NLKlFVMgSTmcNjdaMKOOuFZ5X4PUOOFDTUOOV1I=
|
||||||
|
</data>
|
||||||
|
</dict>
|
||||||
|
<key>LaunchScreen.storyboardc/Info.plist</key>
|
||||||
|
<dict>
|
||||||
|
<key>hash2</key>
|
||||||
|
<data>
|
||||||
|
HyVdXMU7Ux4/KalAao30mpWOK/lEPT4gvYN09wf31cg=
|
||||||
|
</data>
|
||||||
|
</dict>
|
||||||
|
<key>LaunchScreen.storyboardc/UIViewController-01J-lp-oVM.nib</key>
|
||||||
|
<dict>
|
||||||
|
<key>hash2</key>
|
||||||
|
<data>
|
||||||
|
cWq7q+iQcmpSoaFGecnyPdKFEPFwRD3slgUmxFADkVs=
|
||||||
|
</data>
|
||||||
|
</dict>
|
||||||
|
<key>PlugIns/WireGuardNetworkExtension.appex/Info.plist</key>
|
||||||
|
<dict>
|
||||||
|
<key>hash2</key>
|
||||||
|
<data>
|
||||||
|
zGanBzJi5ruG2C96kDY8yR9v246oh2ZT26KMjE3t2Gs=
|
||||||
|
</data>
|
||||||
|
</dict>
|
||||||
|
<key>PlugIns/WireGuardNetworkExtension.appex/WireGuardNetworkExtension</key>
|
||||||
|
<dict>
|
||||||
|
<key>hash2</key>
|
||||||
|
<data>
|
||||||
|
RrENvr9JToqfolIOWfhiXxXt3JyQZ9A7vr2MxwspB/g=
|
||||||
|
</data>
|
||||||
|
</dict>
|
||||||
|
<key>PlugIns/WireGuardNetworkExtension.appex/_CodeSignature/CodeResources</key>
|
||||||
|
<dict>
|
||||||
|
<key>hash2</key>
|
||||||
|
<data>
|
||||||
|
0oir90Tb6hylweTKthB0OaNQrpXqvEdSW72QdH0u48w=
|
||||||
|
</data>
|
||||||
|
</dict>
|
||||||
|
<key>PlugIns/WireGuardNetworkExtension.appex/embedded.mobileprovision</key>
|
||||||
|
<dict>
|
||||||
|
<key>hash2</key>
|
||||||
|
<data>
|
||||||
|
MIAxFA1iZa5ZIg95xlnuoq1pWj1eqsV143zU3y/fs/w=
|
||||||
|
</data>
|
||||||
|
</dict>
|
||||||
|
<key>embedded.mobileprovision</key>
|
||||||
|
<dict>
|
||||||
|
<key>hash2</key>
|
||||||
|
<data>
|
||||||
|
phvsugRYPb6ozM0Feuw5oIla/PgY84jsyntA+R4HqGU=
|
||||||
|
</data>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<key>rules</key>
|
||||||
|
<dict>
|
||||||
|
<key>^.*</key>
|
||||||
|
<true/>
|
||||||
|
<key>^.*\.lproj/</key>
|
||||||
|
<dict>
|
||||||
|
<key>optional</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>1000</real>
|
||||||
|
</dict>
|
||||||
|
<key>^.*\.lproj/locversion.plist$</key>
|
||||||
|
<dict>
|
||||||
|
<key>omit</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>1100</real>
|
||||||
|
</dict>
|
||||||
|
<key>^Base\.lproj/</key>
|
||||||
|
<dict>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>1010</real>
|
||||||
|
</dict>
|
||||||
|
<key>^version.plist$</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
<key>rules2</key>
|
||||||
|
<dict>
|
||||||
|
<key>.*\.dSYM($|/)</key>
|
||||||
|
<dict>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>11</real>
|
||||||
|
</dict>
|
||||||
|
<key>^(.*/)?\.DS_Store$</key>
|
||||||
|
<dict>
|
||||||
|
<key>omit</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>2000</real>
|
||||||
|
</dict>
|
||||||
|
<key>^.*</key>
|
||||||
|
<true/>
|
||||||
|
<key>^.*\.lproj/</key>
|
||||||
|
<dict>
|
||||||
|
<key>optional</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>1000</real>
|
||||||
|
</dict>
|
||||||
|
<key>^.*\.lproj/locversion.plist$</key>
|
||||||
|
<dict>
|
||||||
|
<key>omit</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>1100</real>
|
||||||
|
</dict>
|
||||||
|
<key>^Base\.lproj/</key>
|
||||||
|
<dict>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>1010</real>
|
||||||
|
</dict>
|
||||||
|
<key>^Info\.plist$</key>
|
||||||
|
<dict>
|
||||||
|
<key>omit</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>20</real>
|
||||||
|
</dict>
|
||||||
|
<key>^PkgInfo$</key>
|
||||||
|
<dict>
|
||||||
|
<key>omit</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>20</real>
|
||||||
|
</dict>
|
||||||
|
<key>^embedded\.provisionprofile$</key>
|
||||||
|
<dict>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>20</real>
|
||||||
|
</dict>
|
||||||
|
<key>^version\.plist$</key>
|
||||||
|
<dict>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>20</real>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
BIN
client/Debug-iphoneos/AmneziaVPN.app/embedded.mobileprovision
Normal file
BIN
client/Debug-iphoneos/AmneziaVPN.app/embedded.mobileprovision
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
client/Debug-iphoneos/AmneziaVPN.swiftmodule/arm64.swiftdoc
Normal file
BIN
client/Debug-iphoneos/AmneziaVPN.swiftmodule/arm64.swiftdoc
Normal file
Binary file not shown.
BIN
client/Debug-iphoneos/AmneziaVPN.swiftmodule/arm64.swiftmodule
Normal file
BIN
client/Debug-iphoneos/AmneziaVPN.swiftmodule/arm64.swiftmodule
Normal file
Binary file not shown.
BIN
client/Debug-iphoneos/WireGuardNetworkExtension.appex/Info.plist
Normal file
BIN
client/Debug-iphoneos/WireGuardNetworkExtension.appex/Info.plist
Normal file
Binary file not shown.
BIN
client/Debug-iphoneos/WireGuardNetworkExtension.appex/WireGuardNetworkExtension
Executable file
BIN
client/Debug-iphoneos/WireGuardNetworkExtension.appex/WireGuardNetworkExtension
Executable file
Binary file not shown.
|
@ -0,0 +1,113 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>files</key>
|
||||||
|
<dict>
|
||||||
|
<key>Info.plist</key>
|
||||||
|
<data>
|
||||||
|
Vpf+GoPF6i8Z3silvQ81FJOPi2k=
|
||||||
|
</data>
|
||||||
|
<key>embedded.mobileprovision</key>
|
||||||
|
<data>
|
||||||
|
XsqCdj+fjmJRIQlbMFY/hQ8MMvA=
|
||||||
|
</data>
|
||||||
|
</dict>
|
||||||
|
<key>files2</key>
|
||||||
|
<dict>
|
||||||
|
<key>embedded.mobileprovision</key>
|
||||||
|
<dict>
|
||||||
|
<key>hash2</key>
|
||||||
|
<data>
|
||||||
|
MIAxFA1iZa5ZIg95xlnuoq1pWj1eqsV143zU3y/fs/w=
|
||||||
|
</data>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<key>rules</key>
|
||||||
|
<dict>
|
||||||
|
<key>^.*</key>
|
||||||
|
<true/>
|
||||||
|
<key>^.*\.lproj/</key>
|
||||||
|
<dict>
|
||||||
|
<key>optional</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>1000</real>
|
||||||
|
</dict>
|
||||||
|
<key>^.*\.lproj/locversion.plist$</key>
|
||||||
|
<dict>
|
||||||
|
<key>omit</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>1100</real>
|
||||||
|
</dict>
|
||||||
|
<key>^Base\.lproj/</key>
|
||||||
|
<dict>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>1010</real>
|
||||||
|
</dict>
|
||||||
|
<key>^version.plist$</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
<key>rules2</key>
|
||||||
|
<dict>
|
||||||
|
<key>.*\.dSYM($|/)</key>
|
||||||
|
<dict>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>11</real>
|
||||||
|
</dict>
|
||||||
|
<key>^(.*/)?\.DS_Store$</key>
|
||||||
|
<dict>
|
||||||
|
<key>omit</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>2000</real>
|
||||||
|
</dict>
|
||||||
|
<key>^.*</key>
|
||||||
|
<true/>
|
||||||
|
<key>^.*\.lproj/</key>
|
||||||
|
<dict>
|
||||||
|
<key>optional</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>1000</real>
|
||||||
|
</dict>
|
||||||
|
<key>^.*\.lproj/locversion.plist$</key>
|
||||||
|
<dict>
|
||||||
|
<key>omit</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>1100</real>
|
||||||
|
</dict>
|
||||||
|
<key>^Base\.lproj/</key>
|
||||||
|
<dict>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>1010</real>
|
||||||
|
</dict>
|
||||||
|
<key>^Info\.plist$</key>
|
||||||
|
<dict>
|
||||||
|
<key>omit</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>20</real>
|
||||||
|
</dict>
|
||||||
|
<key>^PkgInfo$</key>
|
||||||
|
<dict>
|
||||||
|
<key>omit</key>
|
||||||
|
<true/>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>20</real>
|
||||||
|
</dict>
|
||||||
|
<key>^embedded\.provisionprofile$</key>
|
||||||
|
<dict>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>20</real>
|
||||||
|
</dict>
|
||||||
|
<key>^version\.plist$</key>
|
||||||
|
<dict>
|
||||||
|
<key>weight</key>
|
||||||
|
<real>20</real>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
client/Debug-iphoneos/libwg-go.a
Normal file
BIN
client/Debug-iphoneos/libwg-go.a
Normal file
Binary file not shown.
39
client/Info.plist
Normal file
39
client/Info.plist
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDisplayName</key>
|
||||||
|
<string>${PRODUCT_NAME}</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>${EXECUTABLE_NAME}</string>
|
||||||
|
<key>CFBundleIconFile</key>
|
||||||
|
<string>${ASSETCATALOG_COMPILER_APPICON_NAME}</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>${PRODUCT_BUNDLE_IDENTIFIER}</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>${PRODUCT_NAME}</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>${QMAKE_SHORT_VERSION}</string>
|
||||||
|
<key>CFBundleSignature</key>
|
||||||
|
<string>${QMAKE_PKGINFO_TYPEINFO}</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>${QMAKE_FULL_VERSION}</string>
|
||||||
|
<key>LSRequiresIPhoneOS</key>
|
||||||
|
<true/>
|
||||||
|
<key>MinimumOSVersion</key>
|
||||||
|
<string>${IPHONEOS_DEPLOYMENT_TARGET}</string>
|
||||||
|
<key>NOTE</key>
|
||||||
|
<string>This file was generated by Qt/QMake.</string>
|
||||||
|
<key>UILaunchStoryboardName</key>
|
||||||
|
<string>LaunchScreen</string>
|
||||||
|
<key>UISupportedInterfaceOrientations</key>
|
||||||
|
<array>
|
||||||
|
<string>UIInterfaceOrientationPortrait</string>
|
||||||
|
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||||
|
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||||
|
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
29
client/WireGuard-Bridging-Header.h
Normal file
29
client/WireGuard-Bridging-Header.h
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "wireguard-go-version.h"
|
||||||
|
#include "3rd/wireguard-apple/Sources/WireGuardKitC/WireGuardKitC.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define WG_KEY_LEN (32)
|
||||||
|
#define WG_KEY_LEN_BASE64 (45)
|
||||||
|
#define WG_KEY_LEN_HEX (65)
|
||||||
|
|
||||||
|
void key_to_base64(char base64[WG_KEY_LEN_BASE64],
|
||||||
|
const uint8_t key[WG_KEY_LEN]);
|
||||||
|
bool key_from_base64(uint8_t key[WG_KEY_LEN], const char* base64);
|
||||||
|
|
||||||
|
void key_to_hex(char hex[WG_KEY_LEN_HEX], const uint8_t key[WG_KEY_LEN]);
|
||||||
|
bool key_from_hex(uint8_t key[WG_KEY_LEN], const char* hex);
|
||||||
|
|
||||||
|
bool key_eq(const uint8_t key1[WG_KEY_LEN], const uint8_t key2[WG_KEY_LEN]);
|
||||||
|
|
||||||
|
void write_msg_to_log(const char* tag, const char* msg);
|
||||||
|
|
||||||
|
#import "TargetConditionals.h"
|
||||||
|
#if TARGET_OS_OSX
|
||||||
|
# include <libproc.h>
|
||||||
|
#endif
|
|
@ -260,29 +260,20 @@ ios {
|
||||||
|
|
||||||
DEFINES += MVPN_IOS
|
DEFINES += MVPN_IOS
|
||||||
|
|
||||||
SOURCES += \
|
|
||||||
# platforms/macos/macospingsender.cpp
|
|
||||||
|
|
||||||
OBJECTIVE_SOURCES += \
|
|
||||||
# platforms/ios/iosiaphandler.mm \
|
|
||||||
# platforms/ios/iosauthenticationlistener.mm \
|
|
||||||
# platforms/ios/ioscontroller.mm \
|
|
||||||
# platforms/ios/iosdatamigration.mm \
|
|
||||||
platforms/ios/iosglue.mm \
|
|
||||||
# platforms/ios/iosnotificationhandler.mm \
|
|
||||||
# platforms/ios/iosutils.mm \
|
|
||||||
# platforms/macos/macoscryptosettings.mm
|
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
# platforms/macos/macospingsender.h
|
protocols/ios_vpnprotocol.h \
|
||||||
|
platforms/ios/json.h \
|
||||||
|
platforms/ios/bigint.h \
|
||||||
|
platforms/ios/bigintipv6addr.h \
|
||||||
|
platforms/ios/ipaddress.h \
|
||||||
|
platforms/ios/ipaddressrange.h
|
||||||
|
|
||||||
OBJECTIVE_HEADERS += \
|
SOURCES += \
|
||||||
# platforms/ios/iosiaphandler.h \
|
protocols/ios_vpnprotocol.mm \
|
||||||
# platforms/ios/iosauthenticationlistener.h \
|
platforms/ios/json.cpp \
|
||||||
# platforms/ios/ioscontroller.h \
|
platforms/ios/iosglue.mm \
|
||||||
# platforms/ios/iosdatamigration.h \
|
platforms/ios/ipaddress.cpp \
|
||||||
# platforms/ios/iosnotificationhandler.h \
|
platforms/ios/ipaddressrange.cpp
|
||||||
# platforms/ios/iosutils.h
|
|
||||||
|
|
||||||
Q_ENABLE_BITCODE.value = NO
|
Q_ENABLE_BITCODE.value = NO
|
||||||
Q_ENABLE_BITCODE.name = ENABLE_BITCODE
|
Q_ENABLE_BITCODE.name = ENABLE_BITCODE
|
||||||
|
@ -314,18 +305,28 @@ ios {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CONFIG(iphonesimulator, iphoneos|iphonesimulator) {
|
CONFIG(iphonesimulator, iphoneos|iphonesimulator) {
|
||||||
message("Building for iPhone Simulator")
|
message("Building for iPhone Simulator")
|
||||||
ARCH_TAG = "ios_x86_64"
|
ARCH_TAG = "ios_x86_64"
|
||||||
|
|
||||||
DEFINES += iphonesimulator
|
DEFINES += iphoneos
|
||||||
|
|
||||||
LIBS += $$PWD/3rd/OpenSSL/lib/ios/simulator/libcrypto.a
|
LIBS += $$PWD/3rd/OpenSSL/lib/ios/iphone/libcrypto.a
|
||||||
LIBS += $$PWD/3rd/OpenSSL/lib/ios/simulator/libssl.a
|
LIBS += $$PWD/3rd/OpenSSL/lib/ios/iphone/libssl.a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# CONFIG(iphonesimulator, iphoneos|iphonesimulator) {
|
||||||
|
# message("Building for iPhone Simulator")
|
||||||
|
# ARCH_TAG = "ios_x86_64"
|
||||||
|
#
|
||||||
|
# DEFINES += iphonesimulator
|
||||||
|
#
|
||||||
|
# LIBS += $$PWD/3rd/OpenSSL/lib/ios/simulator/libcrypto.a
|
||||||
|
# LIBS += $$PWD/3rd/OpenSSL/lib/ios/simulator/libssl.a
|
||||||
|
# }
|
||||||
|
|
||||||
NETWORKEXTENSION=1
|
NETWORKEXTENSION=1
|
||||||
! build_pass: system(ruby $$PWD/ios/xcode_patcher.rb "$$PWD" "$$OUT_PWD/AmneziaVPN.xcodeproj" "2.0" "2.0.0" "ios" "$$NETWORKEXTENSION"|| echo "Failed to merge xcode with wireguard")
|
# ! build_pass: system(ruby $$PWD/scripts/xcode_patcher.rb "$$PWD" "$$OUT_PWD/AmneziaVPN.xcodeproj" "2.0" "2.0.0" "ios" "$$NETWORKEXTENSION"|| echo "Failed to merge xcode with wireguard")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -18,22 +18,22 @@ Settings &VpnConfigurator::m_settings()
|
||||||
}
|
}
|
||||||
|
|
||||||
QString VpnConfigurator::genVpnProtocolConfig(const ServerCredentials &credentials,
|
QString VpnConfigurator::genVpnProtocolConfig(const ServerCredentials &credentials,
|
||||||
DockerContainer container, const QJsonObject &containerConfig, Protocol proto, ErrorCode *errorCode)
|
DockerContainer container, const QJsonObject &containerConfig, Proto proto, ErrorCode *errorCode)
|
||||||
{
|
{
|
||||||
switch (proto) {
|
switch (proto) {
|
||||||
case Protocol::OpenVpn:
|
case Proto::OpenVpn:
|
||||||
return OpenVpnConfigurator::genOpenVpnConfig(credentials, container, containerConfig, errorCode);
|
return OpenVpnConfigurator::genOpenVpnConfig(credentials, container, containerConfig, errorCode);
|
||||||
|
|
||||||
case Protocol::ShadowSocks:
|
case Proto::ShadowSocks:
|
||||||
return ShadowSocksConfigurator::genShadowSocksConfig(credentials, container, containerConfig, errorCode);
|
return ShadowSocksConfigurator::genShadowSocksConfig(credentials, container, containerConfig, errorCode);
|
||||||
|
|
||||||
case Protocol::Cloak:
|
case Proto::Cloak:
|
||||||
return CloakConfigurator::genCloakConfig(credentials, container, containerConfig, errorCode);
|
return CloakConfigurator::genCloakConfig(credentials, container, containerConfig, errorCode);
|
||||||
|
|
||||||
case Protocol::WireGuard:
|
case Proto::WireGuard:
|
||||||
return WireguardConfigurator::genWireguardConfig(credentials, container, containerConfig, errorCode);
|
return WireguardConfigurator::genWireguardConfig(credentials, container, containerConfig, errorCode);
|
||||||
|
|
||||||
case Protocol::Ikev2:
|
case Proto::Ikev2:
|
||||||
return Ikev2Configurator::genIkev2Config(credentials, container, containerConfig, errorCode);
|
return Ikev2Configurator::genIkev2Config(credentials, container, containerConfig, errorCode);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -41,23 +41,23 @@ QString VpnConfigurator::genVpnProtocolConfig(const ServerCredentials &credentia
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString VpnConfigurator::processConfigWithLocalSettings(DockerContainer container, Protocol proto, QString config)
|
QString VpnConfigurator::processConfigWithLocalSettings(DockerContainer container, Proto proto, QString config)
|
||||||
{
|
{
|
||||||
config.replace("$PRIMARY_DNS", m_settings().primaryDns());
|
config.replace("$PRIMARY_DNS", m_settings().primaryDns());
|
||||||
config.replace("$SECONDARY_DNS", m_settings().secondaryDns());
|
config.replace("$SECONDARY_DNS", m_settings().secondaryDns());
|
||||||
|
|
||||||
if (proto == Protocol::OpenVpn) {
|
if (proto == Proto::OpenVpn) {
|
||||||
return OpenVpnConfigurator::processConfigWithLocalSettings(config);
|
return OpenVpnConfigurator::processConfigWithLocalSettings(config);
|
||||||
}
|
}
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString VpnConfigurator::processConfigWithExportSettings(DockerContainer container, Protocol proto, QString config)
|
QString VpnConfigurator::processConfigWithExportSettings(DockerContainer container, Proto proto, QString config)
|
||||||
{
|
{
|
||||||
config.replace("$PRIMARY_DNS", m_settings().primaryDns());
|
config.replace("$PRIMARY_DNS", m_settings().primaryDns());
|
||||||
config.replace("$SECONDARY_DNS", m_settings().secondaryDns());
|
config.replace("$SECONDARY_DNS", m_settings().secondaryDns());
|
||||||
|
|
||||||
if (proto == Protocol::OpenVpn) {
|
if (proto == Proto::OpenVpn) {
|
||||||
return OpenVpnConfigurator::processConfigWithExportSettings(config);
|
return OpenVpnConfigurator::processConfigWithExportSettings(config);
|
||||||
}
|
}
|
||||||
return config;
|
return config;
|
||||||
|
@ -66,7 +66,7 @@ QString VpnConfigurator::processConfigWithExportSettings(DockerContainer contain
|
||||||
void VpnConfigurator::updateContainerConfigAfterInstallation(DockerContainer container, QJsonObject &containerConfig,
|
void VpnConfigurator::updateContainerConfigAfterInstallation(DockerContainer container, QJsonObject &containerConfig,
|
||||||
const QString &stdOut)
|
const QString &stdOut)
|
||||||
{
|
{
|
||||||
Protocol mainProto = ContainerProps::defaultProtocol(container);
|
Proto mainProto = ContainerProps::defaultProtocol(container);
|
||||||
|
|
||||||
if (container == DockerContainer::TorWebSite) {
|
if (container == DockerContainer::TorWebSite) {
|
||||||
QJsonObject protocol = containerConfig.value(ProtocolProps::protoToString(mainProto)).toObject();
|
QJsonObject protocol = containerConfig.value(ProtocolProps::protoToString(mainProto)).toObject();
|
||||||
|
|
|
@ -13,10 +13,10 @@ class VpnConfigurator
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static QString genVpnProtocolConfig(const ServerCredentials &credentials, DockerContainer container,
|
static QString genVpnProtocolConfig(const ServerCredentials &credentials, DockerContainer container,
|
||||||
const QJsonObject &containerConfig, Protocol proto, ErrorCode *errorCode = nullptr);
|
const QJsonObject &containerConfig, Proto proto, ErrorCode *errorCode = nullptr);
|
||||||
|
|
||||||
static QString processConfigWithLocalSettings(DockerContainer container, Protocol proto, QString config);
|
static QString processConfigWithLocalSettings(DockerContainer container, Proto proto, QString config);
|
||||||
static QString processConfigWithExportSettings(DockerContainer container, Protocol proto, QString config);
|
static QString processConfigWithExportSettings(DockerContainer container, Proto proto, QString config);
|
||||||
|
|
||||||
// workaround for containers which is not support normal configaration
|
// workaround for containers which is not support normal configaration
|
||||||
static void updateContainerConfigAfterInstallation(DockerContainer container,
|
static void updateContainerConfigAfterInstallation(DockerContainer container,
|
||||||
|
|
|
@ -27,29 +27,29 @@ QString ContainerProps::containerToString(amnezia::DockerContainer c){
|
||||||
return "amnezia-" + containerKey.toLower();
|
return "amnezia-" + containerKey.toLower();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<amnezia::Protocol> ContainerProps::protocolsForContainer(amnezia::DockerContainer container)
|
QVector<amnezia::Proto> ContainerProps::protocolsForContainer(amnezia::DockerContainer container)
|
||||||
{
|
{
|
||||||
switch (container) {
|
switch (container) {
|
||||||
case DockerContainer::None:
|
case DockerContainer::None:
|
||||||
return { };
|
return { };
|
||||||
|
|
||||||
case DockerContainer::OpenVpn:
|
case DockerContainer::OpenVpn:
|
||||||
return { Protocol::OpenVpn };
|
return { Proto::OpenVpn };
|
||||||
|
|
||||||
case DockerContainer::ShadowSocks:
|
case DockerContainer::ShadowSocks:
|
||||||
return { Protocol::OpenVpn, Protocol::ShadowSocks };
|
return { Proto::OpenVpn, Proto::ShadowSocks };
|
||||||
|
|
||||||
case DockerContainer::Cloak:
|
case DockerContainer::Cloak:
|
||||||
return { Protocol::OpenVpn, Protocol::ShadowSocks, Protocol::Cloak };
|
return { Proto::OpenVpn, Proto::ShadowSocks, Proto::Cloak };
|
||||||
|
|
||||||
case DockerContainer::Ipsec:
|
case DockerContainer::Ipsec:
|
||||||
return { Protocol::Ikev2 /*, Protocol::L2tp */};
|
return { Proto::Ikev2 /*, Protocol::L2tp */};
|
||||||
|
|
||||||
case DockerContainer::Dns:
|
case DockerContainer::Dns:
|
||||||
return { };
|
return { };
|
||||||
|
|
||||||
case DockerContainer::Sftp:
|
case DockerContainer::Sftp:
|
||||||
return { Protocol::Sftp};
|
return { Proto::Sftp};
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return { defaultProtocol(container) };
|
return { defaultProtocol(container) };
|
||||||
|
@ -118,21 +118,21 @@ amnezia::ServiceType ContainerProps::containerService(DockerContainer c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Protocol ContainerProps::defaultProtocol(DockerContainer c)
|
Proto ContainerProps::defaultProtocol(DockerContainer c)
|
||||||
{
|
{
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case DockerContainer::None : return Protocol::Any;
|
case DockerContainer::None : return Proto::Any;
|
||||||
case DockerContainer::OpenVpn : return Protocol::OpenVpn;
|
case DockerContainer::OpenVpn : return Proto::OpenVpn;
|
||||||
case DockerContainer::Cloak : return Protocol::Cloak;
|
case DockerContainer::Cloak : return Proto::Cloak;
|
||||||
case DockerContainer::ShadowSocks : return Protocol::ShadowSocks;
|
case DockerContainer::ShadowSocks : return Proto::ShadowSocks;
|
||||||
case DockerContainer::WireGuard : return Protocol::WireGuard;
|
case DockerContainer::WireGuard : return Proto::WireGuard;
|
||||||
case DockerContainer::Ipsec : return Protocol::Ikev2;
|
case DockerContainer::Ipsec : return Proto::Ikev2;
|
||||||
|
|
||||||
case DockerContainer::TorWebSite : return Protocol::TorWebSite;
|
case DockerContainer::TorWebSite : return Proto::TorWebSite;
|
||||||
case DockerContainer::Dns : return Protocol::Dns;
|
case DockerContainer::Dns : return Proto::Dns;
|
||||||
//case DockerContainer::FileShare : return Protocol::FileShare;
|
//case DockerContainer::FileShare : return Protocol::FileShare;
|
||||||
case DockerContainer::Sftp : return Protocol::Sftp;
|
case DockerContainer::Sftp : return Proto::Sftp;
|
||||||
default: return Protocol::Any;
|
default: return Proto::Any;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,13 +46,13 @@ public:
|
||||||
Q_INVOKABLE static QMap<DockerContainer, QString> containerDescriptions();
|
Q_INVOKABLE static QMap<DockerContainer, QString> containerDescriptions();
|
||||||
|
|
||||||
// these protocols will be displayed in container settings
|
// these protocols will be displayed in container settings
|
||||||
Q_INVOKABLE static QVector<Protocol> protocolsForContainer(DockerContainer container);
|
Q_INVOKABLE static QVector<Proto> protocolsForContainer(DockerContainer container);
|
||||||
|
|
||||||
Q_INVOKABLE static ServiceType containerService(DockerContainer c);
|
Q_INVOKABLE static ServiceType containerService(DockerContainer c);
|
||||||
|
|
||||||
// binding between Docker container and main protocol of given container
|
// binding between Docker container and main protocol of given container
|
||||||
// it may be changed fot future containers :)
|
// it may be changed fot future containers :)
|
||||||
Q_INVOKABLE static Protocol defaultProtocol(DockerContainer c);
|
Q_INVOKABLE static Proto defaultProtocol(DockerContainer c);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -449,7 +449,7 @@ ErrorCode ServerController::updateContainer(const ServerCredentials &credentials
|
||||||
|
|
||||||
QJsonObject ServerController::createContainerInitialConfig(DockerContainer container, int port, TransportProto tp)
|
QJsonObject ServerController::createContainerInitialConfig(DockerContainer container, int port, TransportProto tp)
|
||||||
{
|
{
|
||||||
Protocol mainProto = ContainerProps::defaultProtocol(container);
|
Proto mainProto = ContainerProps::defaultProtocol(container);
|
||||||
|
|
||||||
QJsonObject config {
|
QJsonObject config {
|
||||||
{ config_key::container, ContainerProps::containerToString(container) }
|
{ config_key::container, ContainerProps::containerToString(container) }
|
||||||
|
@ -616,11 +616,11 @@ ErrorCode ServerController::startupContainerWorker(const ServerCredentials &cred
|
||||||
|
|
||||||
ServerController::Vars ServerController::genVarsForScript(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config)
|
ServerController::Vars ServerController::genVarsForScript(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &config)
|
||||||
{
|
{
|
||||||
const QJsonObject &openvpnConfig = config.value(ProtocolProps::protoToString(Protocol::OpenVpn)).toObject();
|
const QJsonObject &openvpnConfig = config.value(ProtocolProps::protoToString(Proto::OpenVpn)).toObject();
|
||||||
const QJsonObject &cloakConfig = config.value(ProtocolProps::protoToString(Protocol::Cloak)).toObject();
|
const QJsonObject &cloakConfig = config.value(ProtocolProps::protoToString(Proto::Cloak)).toObject();
|
||||||
const QJsonObject &ssConfig = config.value(ProtocolProps::protoToString(Protocol::ShadowSocks)).toObject();
|
const QJsonObject &ssConfig = config.value(ProtocolProps::protoToString(Proto::ShadowSocks)).toObject();
|
||||||
const QJsonObject &wireguarConfig = config.value(ProtocolProps::protoToString(Protocol::WireGuard)).toObject();
|
const QJsonObject &wireguarConfig = config.value(ProtocolProps::protoToString(Proto::WireGuard)).toObject();
|
||||||
const QJsonObject &sftpConfig = config.value(ProtocolProps::protoToString(Protocol::Sftp)).toObject();
|
const QJsonObject &sftpConfig = config.value(ProtocolProps::protoToString(Proto::Sftp)).toObject();
|
||||||
//
|
//
|
||||||
|
|
||||||
Vars vars;
|
Vars vars;
|
||||||
|
@ -689,7 +689,7 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
|
||||||
|
|
||||||
|
|
||||||
// Sftp vars
|
// Sftp vars
|
||||||
vars.append({{"$SFTP_PORT", sftpConfig.value(config_key::port).toString(QString::number(ProtocolProps::defaultPort(Protocol::Sftp))) }});
|
vars.append({{"$SFTP_PORT", sftpConfig.value(config_key::port).toString(QString::number(ProtocolProps::defaultPort(Proto::Sftp))) }});
|
||||||
vars.append({{"$SFTP_USER", sftpConfig.value(config_key::userName).toString() }});
|
vars.append({{"$SFTP_USER", sftpConfig.value(config_key::userName).toString() }});
|
||||||
vars.append({{"$SFTP_PASSWORD", sftpConfig.value(config_key::password).toString() }});
|
vars.append({{"$SFTP_PASSWORD", sftpConfig.value(config_key::password).toString() }});
|
||||||
|
|
||||||
|
|
|
@ -2,12 +2,14 @@
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
<key>ADJUST_SDK_TOKEN</key>
|
||||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
<string>$(ADJUST_SDK_TOKEN)</string>
|
||||||
<key>CFBundleAllowMixedLocalizations</key>
|
<key>CFBundleAllowMixedLocalizations</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||||
<key>CFBundleDisplayName</key>
|
<key>CFBundleDisplayName</key>
|
||||||
<string>Mozilla VPN</string>
|
<string>AmneziaVPN</string>
|
||||||
<key>CFBundleExecutable</key>
|
<key>CFBundleExecutable</key>
|
||||||
<string>$(EXECUTABLE_NAME)</string>
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
<key>CFBundleIcons</key>
|
<key>CFBundleIcons</key>
|
||||||
|
@ -49,7 +51,5 @@
|
||||||
<string>Light</string>
|
<string>Light</string>
|
||||||
<key>com.wireguard.ios.app_group_id</key>
|
<key>com.wireguard.ios.app_group_id</key>
|
||||||
<string>group.org.mozilla.ios.Guardian</string>
|
<string>group.org.mozilla.ios.Guardian</string>
|
||||||
<key>ADJUST_SDK_TOKEN</key>
|
|
||||||
<string>$(ADJUST_SDK_TOKEN)</string>
|
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>com.apple.developer.networking.networkextension</key>
|
||||||
|
<array>
|
||||||
|
<string>packet-tunnel-provider</string>
|
||||||
|
</array>
|
||||||
<key>com.apple.security.application-groups</key>
|
<key>com.apple.security.application-groups</key>
|
||||||
<array>
|
<array>
|
||||||
<string>$(GROUP_ID_IOS)</string>
|
<string>$(GROUP_ID_IOS)</string>
|
||||||
</array>
|
</array>
|
||||||
<key>com.apple.developer.networking.networkextension</key>
|
|
||||||
<array>
|
|
||||||
<string>packet-tunnel-provider</string>
|
|
||||||
</array>
|
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
0
client/macos/gobridge/api.go
Executable file → Normal file
0
client/macos/gobridge/api.go
Executable file → Normal file
0
client/macos/gobridge/dummy.c
Executable file → Normal file
0
client/macos/gobridge/dummy.c
Executable file → Normal file
0
client/macos/gobridge/go.mod
Executable file → Normal file
0
client/macos/gobridge/go.mod
Executable file → Normal file
0
client/macos/gobridge/go.sum
Executable file → Normal file
0
client/macos/gobridge/go.sum
Executable file → Normal file
0
client/macos/gobridge/goruntime-boottime-over-monotonic.diff
Executable file → Normal file
0
client/macos/gobridge/goruntime-boottime-over-monotonic.diff
Executable file → Normal file
0
client/macos/gobridge/module.modulemap
Executable file → Normal file
0
client/macos/gobridge/module.modulemap
Executable file → Normal file
0
client/macos/gobridge/wireguard-go-version.h
Executable file → Normal file
0
client/macos/gobridge/wireguard-go-version.h
Executable file → Normal file
0
client/macos/gobridge/wireguard.h
Executable file → Normal file
0
client/macos/gobridge/wireguard.h
Executable file → Normal file
|
@ -116,15 +116,15 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
app.setQuitOnLastWindowClosed(false);
|
app.setQuitOnLastWindowClosed(false);
|
||||||
|
|
||||||
qRegisterMetaType<VpnProtocol::ConnectionState>("VpnProtocol::ConnectionState");
|
qRegisterMetaType<VpnProtocol::VpnConnectionState>("VpnProtocol::ConnectionState");
|
||||||
qRegisterMetaType<ServerCredentials>("ServerCredentials");
|
qRegisterMetaType<ServerCredentials>("ServerCredentials");
|
||||||
|
|
||||||
qRegisterMetaType<DockerContainer>("DockerContainer");
|
qRegisterMetaType<DockerContainer>("DockerContainer");
|
||||||
qRegisterMetaType<TransportProto>("TransportProto");
|
qRegisterMetaType<TransportProto>("TransportProto");
|
||||||
qRegisterMetaType<Protocol>("Protocol");
|
qRegisterMetaType<Proto>("Protocol");
|
||||||
qRegisterMetaType<ServiceType>("ServiceType");
|
qRegisterMetaType<ServiceType>("ServiceType");
|
||||||
qRegisterMetaType<Page>("Page");
|
qRegisterMetaType<Page>("Page");
|
||||||
qRegisterMetaType<VpnProtocol::ConnectionState>("ConnectionState");
|
qRegisterMetaType<VpnProtocol::VpnConnectionState>("ConnectionState");
|
||||||
|
|
||||||
qRegisterMetaType<PageProtocolLogicBase *>("PageProtocolLogicBase *");
|
qRegisterMetaType<PageProtocolLogicBase *>("PageProtocolLogicBase *");
|
||||||
|
|
||||||
|
@ -160,7 +160,7 @@ int main(int argc, char *argv[])
|
||||||
engine->rootContext()->setContextProperty("NewServerProtocolsLogic", uiLogic->newServerProtocolsLogic());
|
engine->rootContext()->setContextProperty("NewServerProtocolsLogic", uiLogic->newServerProtocolsLogic());
|
||||||
engine->rootContext()->setContextProperty("ServerListLogic", uiLogic->serverListLogic());
|
engine->rootContext()->setContextProperty("ServerListLogic", uiLogic->serverListLogic());
|
||||||
engine->rootContext()->setContextProperty("ServerSettingsLogic", uiLogic->serverSettingsLogic());
|
engine->rootContext()->setContextProperty("ServerSettingsLogic", uiLogic->serverSettingsLogic());
|
||||||
engine->rootContext()->setContextProperty("ServerContainersLogic", uiLogic->serverVpnProtocolsLogic());
|
engine->rootContext()->setContextProperty("ServerContainersLogic", uiLogic->serverprotocolsLogic());
|
||||||
engine->rootContext()->setContextProperty("ShareConnectionLogic", uiLogic->shareConnectionLogic());
|
engine->rootContext()->setContextProperty("ShareConnectionLogic", uiLogic->shareConnectionLogic());
|
||||||
engine->rootContext()->setContextProperty("SitesLogic", uiLogic->sitesLogic());
|
engine->rootContext()->setContextProperty("SitesLogic", uiLogic->sitesLogic());
|
||||||
engine->rootContext()->setContextProperty("StartPageLogic", uiLogic->startPageLogic());
|
engine->rootContext()->setContextProperty("StartPageLogic", uiLogic->startPageLogic());
|
||||||
|
|
29
client/platforms/ios/WireGuard-Bridging-Header.h
Normal file
29
client/platforms/ios/WireGuard-Bridging-Header.h
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "wireguard-go-version.h"
|
||||||
|
#include "3rd/wireguard-apple/Sources/WireGuardKitC/WireGuardKitC.h"
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define WG_KEY_LEN (32)
|
||||||
|
#define WG_KEY_LEN_BASE64 (45)
|
||||||
|
#define WG_KEY_LEN_HEX (65)
|
||||||
|
|
||||||
|
void key_to_base64(char base64[WG_KEY_LEN_BASE64],
|
||||||
|
const uint8_t key[WG_KEY_LEN]);
|
||||||
|
bool key_from_base64(uint8_t key[WG_KEY_LEN], const char* base64);
|
||||||
|
|
||||||
|
void key_to_hex(char hex[WG_KEY_LEN_HEX], const uint8_t key[WG_KEY_LEN]);
|
||||||
|
bool key_from_hex(uint8_t key[WG_KEY_LEN], const char* hex);
|
||||||
|
|
||||||
|
bool key_eq(const uint8_t key1[WG_KEY_LEN], const uint8_t key2[WG_KEY_LEN]);
|
||||||
|
|
||||||
|
void write_msg_to_log(const char* tag, const char* msg);
|
||||||
|
|
||||||
|
#import "TargetConditionals.h"
|
||||||
|
#if TARGET_OS_OSX
|
||||||
|
# include <libproc.h>
|
||||||
|
#endif
|
127
client/platforms/ios/bigint.h
Normal file
127
client/platforms/ios/bigint.h
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef BIGINT_H
|
||||||
|
#define BIGINT_H
|
||||||
|
|
||||||
|
#include <QVector>
|
||||||
|
|
||||||
|
// This BigInt implementation is meant to be used for IPv6 addresses. It
|
||||||
|
// doesn't support dynamic resize: when the max size is reached, the value
|
||||||
|
// overflows. If you need to change the size, use `resize()`.
|
||||||
|
|
||||||
|
class BigInt final {
|
||||||
|
public:
|
||||||
|
explicit BigInt(uint8_t bytes) {
|
||||||
|
m_value.resize(bytes);
|
||||||
|
memset(m_value.data(), 0, bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
BigInt(const BigInt& other) { m_value = other.m_value; }
|
||||||
|
|
||||||
|
const uint8_t* value() const { return m_value.data(); }
|
||||||
|
|
||||||
|
uint8_t size() const { return m_value.size(); }
|
||||||
|
|
||||||
|
// Assign operator.
|
||||||
|
|
||||||
|
BigInt& operator=(const BigInt& other) {
|
||||||
|
m_value = other.m_value;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Comparison operators.
|
||||||
|
|
||||||
|
bool operator==(const BigInt& other) const {
|
||||||
|
return m_value == other.m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const BigInt& other) const { return !(*this == other); }
|
||||||
|
|
||||||
|
bool operator<(const BigInt& other) const { return cmp(other) < 0; }
|
||||||
|
|
||||||
|
bool operator>(const BigInt& other) const { return cmp(other) > 0; }
|
||||||
|
|
||||||
|
bool operator<=(const BigInt& other) const { return cmp(other) <= 0; }
|
||||||
|
|
||||||
|
bool operator>=(const BigInt& other) const { return cmp(other) >= 0; }
|
||||||
|
|
||||||
|
// math operators (only some of them are implemented)
|
||||||
|
|
||||||
|
BigInt& operator++() {
|
||||||
|
for (int i = size() - 1; i >= 0; --i) {
|
||||||
|
if (m_value[i] < UINT8_MAX) {
|
||||||
|
++m_value[i];
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
m_value[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// overflow
|
||||||
|
memset(m_value.data(), 0, size());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BigInt& operator+=(const BigInt& other) {
|
||||||
|
Q_ASSERT(other.size() == size());
|
||||||
|
|
||||||
|
uint8_t carry = 0;
|
||||||
|
for (int i = m_value.size() - 1; i >= 0; --i) {
|
||||||
|
uint16_t total = carry + m_value[i] + other.m_value[i];
|
||||||
|
m_value[i] = (uint8_t)(total & UINT8_MAX);
|
||||||
|
carry = (uint8_t)((total & 0xFF00) >> 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shift operators
|
||||||
|
|
||||||
|
BigInt operator>>(int shift) {
|
||||||
|
BigInt x(size());
|
||||||
|
x = *this;
|
||||||
|
|
||||||
|
for (int i = 0; i < shift; i++) {
|
||||||
|
BigInt a(size());
|
||||||
|
a = x;
|
||||||
|
|
||||||
|
a.m_value[size() - 1] = x.m_value[size() - 1] >> 1;
|
||||||
|
for (int j = size() - 2; j >= 0; j--) {
|
||||||
|
a.m_value[j] = x.m_value[j] >> 1;
|
||||||
|
if ((x.m_value[j] & 1) != 0) {
|
||||||
|
a.m_value[j + 1] |= 128; // Set most significant bit or a uint8_t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
x = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setValueAt(uint8_t value, uint8_t pos) {
|
||||||
|
Q_ASSERT(pos < size());
|
||||||
|
m_value[pos] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t valueAt(uint8_t pos) const {
|
||||||
|
Q_ASSERT(size() > pos);
|
||||||
|
return m_value[pos];
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int cmp(const BigInt& other) const {
|
||||||
|
Q_ASSERT(size() == other.size());
|
||||||
|
for (int i = 0; i < size(); i++) {
|
||||||
|
int diff = (m_value[i] - other.m_value[i]);
|
||||||
|
if (diff != 0) return diff;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QVector<uint8_t> m_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // BIGINT_H
|
86
client/platforms/ios/bigintipv6addr.h
Normal file
86
client/platforms/ios/bigintipv6addr.h
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef BIGINTIPV6ADDR_H
|
||||||
|
#define BIGINTIPV6ADDR_H
|
||||||
|
|
||||||
|
#include "bigint.h"
|
||||||
|
|
||||||
|
#include <QHostAddress>
|
||||||
|
|
||||||
|
class BigIntIPv6Addr final {
|
||||||
|
public:
|
||||||
|
BigIntIPv6Addr() : m_value(16) {}
|
||||||
|
|
||||||
|
explicit BigIntIPv6Addr(const Q_IPV6ADDR& a) : m_value(16) {
|
||||||
|
for (int i = 0; i < 16; ++i) m_value.setValueAt(a[i], i);
|
||||||
|
}
|
||||||
|
|
||||||
|
BigIntIPv6Addr(const BigIntIPv6Addr& other) : m_value(16) { *this = other; }
|
||||||
|
|
||||||
|
Q_IPV6ADDR value() const {
|
||||||
|
Q_IPV6ADDR addr;
|
||||||
|
for (int i = 0; i < 16; ++i) addr[i] = m_value.valueAt(i);
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign operator.
|
||||||
|
|
||||||
|
BigIntIPv6Addr& operator=(const BigIntIPv6Addr& other) {
|
||||||
|
m_value = other.m_value;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Comparison operators.
|
||||||
|
|
||||||
|
bool operator==(const BigIntIPv6Addr& other) const {
|
||||||
|
return m_value == other.m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const BigIntIPv6Addr& other) const {
|
||||||
|
return m_value != other.m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator<(const BigIntIPv6Addr& other) const {
|
||||||
|
return m_value < other.m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator>(const BigIntIPv6Addr& other) const {
|
||||||
|
return m_value > other.m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator<=(const BigIntIPv6Addr& other) const {
|
||||||
|
return m_value <= other.m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator>=(const BigIntIPv6Addr& other) const {
|
||||||
|
return m_value >= other.m_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// math operators (only some of them are implemented)
|
||||||
|
|
||||||
|
BigIntIPv6Addr& operator++() {
|
||||||
|
++m_value;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BigIntIPv6Addr& operator+=(const BigIntIPv6Addr& b) {
|
||||||
|
m_value += b.m_value;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shift operators
|
||||||
|
|
||||||
|
BigIntIPv6Addr operator>>(int shift) {
|
||||||
|
BigIntIPv6Addr x;
|
||||||
|
|
||||||
|
x.m_value = m_value >> shift;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
BigInt m_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // BIGINTIPV6ADDR_H
|
|
@ -5,12 +5,12 @@
|
||||||
#ifndef IOSCONTROLLER_H
|
#ifndef IOSCONTROLLER_H
|
||||||
#define IOSCONTROLLER_H
|
#define IOSCONTROLLER_H
|
||||||
|
|
||||||
#include "controllerimpl.h"
|
#include "vpnprotocol.h"
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
class IOSController final : public ControllerImpl {
|
class IOSVPNProtocol final : public VpnProtocol {
|
||||||
Q_DISABLE_COPY_MOVE(IOSController)
|
Q_DISABLE_COPY_MOVE(IOSVPNProtocol)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IOSController();
|
IOSController();
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#ifndef NETWORK_EXTENSION
|
#ifndef NETWORK_EXTENSION
|
||||||
# include "logger.h"
|
//# include "logger.h"
|
||||||
#else
|
#else
|
||||||
# import <Foundation/Foundation.h>
|
# import <Foundation/Foundation.h>
|
||||||
# import <os/log.h>
|
# import <os/log.h>
|
||||||
|
@ -183,13 +183,13 @@ EXPORT bool key_eq(const uint8_t key1[WG_KEY_LEN], const uint8_t key2[WG_KEY_LEN
|
||||||
|
|
||||||
#ifndef NETWORK_EXTENSION
|
#ifndef NETWORK_EXTENSION
|
||||||
namespace {
|
namespace {
|
||||||
Logger logger(LOG_IOS, "IOSSGlue");
|
//Logger logger(LOG_IOS, "IOSSGlue");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EXPORT void write_msg_to_log(const char* tag, const char* msg) {
|
EXPORT void write_msg_to_log(const char* tag, const char* msg) {
|
||||||
#ifndef NETWORK_EXTENSION
|
#ifndef NETWORK_EXTENSION
|
||||||
logger.debug() << "Swift log - tag:" << tag << "msg: " << msg;
|
// logger.debug() << "Swift log - tag:" << tag << "msg: " << msg;
|
||||||
#else
|
#else
|
||||||
os_log_with_type(OS_LOG_DEFAULT, OS_LOG_TYPE_DEBUG, "tag: %s - msg: %s", tag, msg);
|
os_log_with_type(OS_LOG_DEFAULT, OS_LOG_TYPE_DEBUG, "tag: %s - msg: %s", tag, msg);
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import os
|
||||||
|
|
||||||
class PacketTunnelProvider: NEPacketTunnelProvider {
|
class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||||
|
|
||||||
private lazy var adapter: WireGuardAdapter = {
|
private lazy var wgAdapter: WireGuardAdapter = {
|
||||||
return WireGuardAdapter(with: self) { logLevel, message in
|
return WireGuardAdapter(with: self) { logLevel, message in
|
||||||
wg_log(logLevel.osLogLevel, message: message)
|
wg_log(logLevel.osLogLevel, message: message)
|
||||||
}
|
}
|
||||||
|
@ -29,9 +29,9 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start the tunnel
|
// Start the tunnel
|
||||||
adapter.start(tunnelConfiguration: tunnelConfiguration) { adapterError in
|
wgAdapter.start(tunnelConfiguration: tunnelConfiguration) { adapterError in
|
||||||
guard let adapterError = adapterError else {
|
guard let adapterError = adapterError else {
|
||||||
let interfaceName = self.adapter.interfaceName ?? "unknown"
|
let interfaceName = self.wgAdapter.interfaceName ?? "unknown"
|
||||||
|
|
||||||
wg_log(.info, message: "Tunnel interface is \(interfaceName)")
|
wg_log(.info, message: "Tunnel interface is \(interfaceName)")
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||||
override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
|
override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
|
||||||
wg_log(.info, staticMessage: "Stopping tunnel")
|
wg_log(.info, staticMessage: "Stopping tunnel")
|
||||||
|
|
||||||
adapter.stop { error in
|
wgAdapter.stop { error in
|
||||||
ErrorNotifier.removeLastErrorFile()
|
ErrorNotifier.removeLastErrorFile()
|
||||||
|
|
||||||
if let error = error {
|
if let error = error {
|
||||||
|
@ -93,7 +93,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||||
guard let completionHandler = completionHandler else { return }
|
guard let completionHandler = completionHandler else { return }
|
||||||
|
|
||||||
if messageData.count == 1 && messageData[0] == 0 {
|
if messageData.count == 1 && messageData[0] == 0 {
|
||||||
adapter.getRuntimeConfiguration { settings in
|
wgAdapter.getRuntimeConfiguration { settings in
|
||||||
var data: Data?
|
var data: Data?
|
||||||
if let settings = settings {
|
if let settings = settings {
|
||||||
data = settings.data(using: .utf8)!
|
data = settings.data(using: .utf8)!
|
||||||
|
@ -111,14 +111,14 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
||||||
|
|
||||||
do {
|
do {
|
||||||
let tunnelConfiguration = try TunnelConfiguration(fromWgQuickConfig: configString)
|
let tunnelConfiguration = try TunnelConfiguration(fromWgQuickConfig: configString)
|
||||||
adapter.update(tunnelConfiguration: tunnelConfiguration) { error in
|
wgAdapter.update(tunnelConfiguration: tunnelConfiguration) { error in
|
||||||
if let error = error {
|
if let error = error {
|
||||||
wg_log(.error, message: "Failed to switch tunnel configuration: \(error.localizedDescription)")
|
wg_log(.error, message: "Failed to switch tunnel configuration: \(error.localizedDescription)")
|
||||||
completionHandler(nil)
|
completionHandler(nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
self.adapter.getRuntimeConfiguration { settings in
|
self.wgAdapter.getRuntimeConfiguration { settings in
|
||||||
var data: Data?
|
var data: Data?
|
||||||
if let settings = settings {
|
if let settings = settings {
|
||||||
data = settings.data(using: .utf8)!
|
data = settings.data(using: .utf8)!
|
||||||
|
|
292
client/platforms/ios/iosvpnprotocol.swift
Normal file
292
client/platforms/ios/iosvpnprotocol.swift
Normal file
|
@ -0,0 +1,292 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import NetworkExtension
|
||||||
|
|
||||||
|
let vpnName = "AmneziaVPN"
|
||||||
|
var vpnBundleID = "";
|
||||||
|
|
||||||
|
@objc class VPNIPAddressRange : NSObject {
|
||||||
|
public var address: NSString = ""
|
||||||
|
public var networkPrefixLength: UInt8 = 0
|
||||||
|
public var isIpv6: Bool = false
|
||||||
|
|
||||||
|
@objc init(address: NSString, networkPrefixLength: UInt8, isIpv6: Bool) {
|
||||||
|
super.init()
|
||||||
|
|
||||||
|
self.address = address
|
||||||
|
self.networkPrefixLength = networkPrefixLength
|
||||||
|
self.isIpv6 = isIpv6
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IOSVpnProtocolImpl : NSObject {
|
||||||
|
|
||||||
|
private var tunnel: NETunnelProviderManager? = nil
|
||||||
|
private var stateChangeCallback: ((Bool) -> Void?)? = nil
|
||||||
|
private var privateKey : PrivateKey? = nil
|
||||||
|
private var deviceIpv4Address: String? = nil
|
||||||
|
private var deviceIpv6Address: String? = nil
|
||||||
|
|
||||||
|
@objc enum IOSConnectionState: Int { case Error, Connected, Disconnected }
|
||||||
|
|
||||||
|
@objc init(bundleID: String, privateKey: Data, deviceIpv4Address: String, deviceIpv6Address: String, closure: @escaping (IOSConnectionState, Date?) -> Void, callback: @escaping (Bool) -> Void) {
|
||||||
|
super.init()
|
||||||
|
|
||||||
|
Logger.configureGlobal(tagged: "APP", withFilePath: "")
|
||||||
|
|
||||||
|
vpnBundleID = bundleID;
|
||||||
|
precondition(!vpnBundleID.isEmpty)
|
||||||
|
|
||||||
|
stateChangeCallback = callback
|
||||||
|
self.privateKey = PrivateKey(rawValue: privateKey)
|
||||||
|
self.deviceIpv4Address = deviceIpv4Address
|
||||||
|
self.deviceIpv6Address = deviceIpv6Address
|
||||||
|
|
||||||
|
NotificationCenter.default.addObserver(self, selector: #selector(self.vpnStatusDidChange(notification:)), name: Notification.Name.NEVPNStatusDidChange, object: nil)
|
||||||
|
|
||||||
|
NETunnelProviderManager.loadAllFromPreferences { [weak self] managers, error in
|
||||||
|
if let error = error {
|
||||||
|
Logger.global?.log(message: "Loading from preference failed: \(error)")
|
||||||
|
closure(IOSConnectionState.Error, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if self == nil {
|
||||||
|
Logger.global?.log(message: "We are shutting down.")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let nsManagers = managers ?? []
|
||||||
|
Logger.global?.log(message: "We have received \(nsManagers.count) managers.")
|
||||||
|
|
||||||
|
let tunnel = nsManagers.first(where: IOSVpnProtocolImpl.isOurManager(_:))
|
||||||
|
if tunnel == nil {
|
||||||
|
Logger.global?.log(message: "Creating the tunnel")
|
||||||
|
self!.tunnel = NETunnelProviderManager()
|
||||||
|
closure(IOSConnectionState.Disconnected, nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.global?.log(message: "Tunnel already exists")
|
||||||
|
|
||||||
|
self!.tunnel = tunnel
|
||||||
|
if tunnel?.connection.status == .connected {
|
||||||
|
closure(IOSConnectionState.Connected, tunnel?.connection.connectedDate)
|
||||||
|
} else {
|
||||||
|
closure(IOSConnectionState.Disconnected, nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc private func vpnStatusDidChange(notification: Notification) {
|
||||||
|
guard let session = (notification.object as? NETunnelProviderSession), tunnel?.connection == session else { return }
|
||||||
|
|
||||||
|
switch session.status {
|
||||||
|
case .connected:
|
||||||
|
Logger.global?.log(message: "STATE CHANGED: connected")
|
||||||
|
case .connecting:
|
||||||
|
Logger.global?.log(message: "STATE CHANGED: connecting")
|
||||||
|
case .disconnected:
|
||||||
|
Logger.global?.log(message: "STATE CHANGED: disconnected")
|
||||||
|
case .disconnecting:
|
||||||
|
Logger.global?.log(message: "STATE CHANGED: disconnecting")
|
||||||
|
case .invalid:
|
||||||
|
Logger.global?.log(message: "STATE CHANGED: invalid")
|
||||||
|
case .reasserting:
|
||||||
|
Logger.global?.log(message: "STATE CHANGED: reasserting")
|
||||||
|
default:
|
||||||
|
Logger.global?.log(message: "STATE CHANGED: unknown status")
|
||||||
|
}
|
||||||
|
|
||||||
|
// We care about "unknown" state changes.
|
||||||
|
if (session.status != .connected && session.status != .disconnected) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
stateChangeCallback?(session.status == .connected)
|
||||||
|
}
|
||||||
|
|
||||||
|
private static func isOurManager(_ manager: NETunnelProviderManager) -> Bool {
|
||||||
|
guard
|
||||||
|
let proto = manager.protocolConfiguration,
|
||||||
|
let tunnelProto = proto as? NETunnelProviderProtocol
|
||||||
|
else {
|
||||||
|
Logger.global?.log(message: "Ignoring manager because the proto is invalid.")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tunnelProto.providerBundleIdentifier == nil) {
|
||||||
|
Logger.global?.log(message: "Ignoring manager because the bundle identifier is null.")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tunnelProto.providerBundleIdentifier != vpnBundleID) {
|
||||||
|
Logger.global?.log(message: "Ignoring manager because the bundle identifier doesn't match.")
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.global?.log(message: "Found the manager with the correct bundle identifier: \(tunnelProto.providerBundleIdentifier!)")
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc func connect(dnsServer: String, serverIpv6Gateway: String, serverPublicKey: String, serverIpv4AddrIn: String, serverPort: Int, allowedIPAddressRanges: Array<VPNIPAddressRange>, ipv6Enabled: Bool, reason: Int, failureCallback: @escaping () -> Void) {
|
||||||
|
Logger.global?.log(message: "Connecting")
|
||||||
|
assert(tunnel != nil)
|
||||||
|
|
||||||
|
// Let's remove the previous config if it exists.
|
||||||
|
(tunnel?.protocolConfiguration as? NETunnelProviderProtocol)?.destroyConfigurationReference()
|
||||||
|
|
||||||
|
let keyData = PublicKey(base64Key: serverPublicKey)!
|
||||||
|
let dnsServerIP = IPv4Address(dnsServer)
|
||||||
|
let ipv6GatewayIP = IPv6Address(serverIpv6Gateway)
|
||||||
|
|
||||||
|
var peerConfiguration = PeerConfiguration(publicKey: keyData)
|
||||||
|
peerConfiguration.endpoint = Endpoint(from: serverIpv4AddrIn + ":\(serverPort )")
|
||||||
|
peerConfiguration.allowedIPs = []
|
||||||
|
|
||||||
|
allowedIPAddressRanges.forEach {
|
||||||
|
if (!$0.isIpv6) {
|
||||||
|
peerConfiguration.allowedIPs.append(IPAddressRange(address: IPv4Address($0.address as String)!, networkPrefixLength: $0.networkPrefixLength))
|
||||||
|
} else if (ipv6Enabled) {
|
||||||
|
peerConfiguration.allowedIPs.append(IPAddressRange(address: IPv6Address($0.address as String)!, networkPrefixLength: $0.networkPrefixLength))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var peerConfigurations: [PeerConfiguration] = []
|
||||||
|
peerConfigurations.append(peerConfiguration)
|
||||||
|
|
||||||
|
var interface = InterfaceConfiguration(privateKey: privateKey!)
|
||||||
|
|
||||||
|
if let ipv4Address = IPAddressRange(from: deviceIpv4Address!),
|
||||||
|
let ipv6Address = IPAddressRange(from: deviceIpv6Address!) {
|
||||||
|
interface.addresses = [ipv4Address]
|
||||||
|
if (ipv6Enabled) {
|
||||||
|
interface.addresses.append(ipv6Address)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
interface.dns = [ DNSServer(address: dnsServerIP!)]
|
||||||
|
|
||||||
|
if (ipv6Enabled) {
|
||||||
|
interface.dns.append(DNSServer(address: ipv6GatewayIP!))
|
||||||
|
}
|
||||||
|
|
||||||
|
let config = TunnelConfiguration(name: vpnName, interface: interface, peers: peerConfigurations)
|
||||||
|
|
||||||
|
self.configureTunnel(config: config, reason: reason, failureCallback: failureCallback)
|
||||||
|
}
|
||||||
|
|
||||||
|
func configureTunnel(config: TunnelConfiguration, reason: Int, failureCallback: @escaping () -> Void) {
|
||||||
|
guard let proto = NETunnelProviderProtocol(tunnelConfiguration: config) else {
|
||||||
|
failureCallback()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
proto.providerBundleIdentifier = vpnBundleID
|
||||||
|
|
||||||
|
tunnel!.protocolConfiguration = proto
|
||||||
|
tunnel!.localizedDescription = vpnName
|
||||||
|
tunnel!.isEnabled = true
|
||||||
|
|
||||||
|
tunnel!.saveToPreferences { [unowned self] saveError in
|
||||||
|
if let error = saveError {
|
||||||
|
Logger.global?.log(message: "Connect Tunnel Save Error: \(error)")
|
||||||
|
failureCallback()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.global?.log(message: "Saving the tunnel succeeded")
|
||||||
|
|
||||||
|
self.tunnel!.loadFromPreferences { error in
|
||||||
|
if let error = error {
|
||||||
|
Logger.global?.log(message: "Connect Tunnel Load Error: \(error)")
|
||||||
|
failureCallback()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.global?.log(message: "Loading the tunnel succeeded")
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (reason == 1 /* ReasonSwitching */) {
|
||||||
|
let settings = config.asWgQuickConfig()
|
||||||
|
let settingsData = settings.data(using: .utf8)!
|
||||||
|
try (self.tunnel!.connection as? NETunnelProviderSession)?
|
||||||
|
.sendProviderMessage(settingsData) { data in
|
||||||
|
guard let data = data,
|
||||||
|
let configString = String(data: data, encoding: .utf8)
|
||||||
|
else {
|
||||||
|
Logger.global?.log(message: "Failed to convert response to string")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try (self.tunnel!.connection as? NETunnelProviderSession)?.startTunnel()
|
||||||
|
}
|
||||||
|
} catch let error {
|
||||||
|
Logger.global?.log(message: "Something went wrong: \(error)")
|
||||||
|
failureCallback()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc func disconnect() {
|
||||||
|
Logger.global?.log(message: "Disconnecting")
|
||||||
|
assert(tunnel != nil)
|
||||||
|
(tunnel!.connection as? NETunnelProviderSession)?.stopTunnel()
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc func checkStatus(callback: @escaping (String, String, String) -> Void) {
|
||||||
|
Logger.global?.log(message: "Check status")
|
||||||
|
assert(tunnel != nil)
|
||||||
|
|
||||||
|
let proto = tunnel!.protocolConfiguration as? NETunnelProviderProtocol
|
||||||
|
if proto == nil {
|
||||||
|
callback("", "", "")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let tunnelConfiguration = proto?.asTunnelConfiguration()
|
||||||
|
if tunnelConfiguration == nil {
|
||||||
|
callback("", "", "")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let serverIpv4Gateway = tunnelConfiguration?.interface.dns[0].address
|
||||||
|
if serverIpv4Gateway == nil {
|
||||||
|
callback("", "", "")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let deviceIpv4Address = tunnelConfiguration?.interface.addresses[0].address
|
||||||
|
if deviceIpv4Address == nil {
|
||||||
|
callback("", "", "")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let session = tunnel?.connection as? NETunnelProviderSession
|
||||||
|
else {
|
||||||
|
callback("", "", "")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
try session.sendProviderMessage(Data([UInt8(0)])) { [callback] data in
|
||||||
|
guard let data = data,
|
||||||
|
let configString = String(data: data, encoding: .utf8)
|
||||||
|
else {
|
||||||
|
Logger.global?.log(message: "Failed to convert data to string")
|
||||||
|
callback("", "", "")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
callback("\(serverIpv4Gateway!)", "\(deviceIpv4Address!)", configString)
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
Logger.global?.log(message: "Failed to retrieve data from session")
|
||||||
|
callback("", "", "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
313
client/platforms/ios/ipaddress.cpp
Normal file
313
client/platforms/ios/ipaddress.cpp
Normal file
|
@ -0,0 +1,313 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "ipaddress.h"
|
||||||
|
#include "bigintipv6addr.h"
|
||||||
|
|
||||||
|
#include <QtMath>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
quint32 s_allIpV4Ones = static_cast<quint32>(qPow(2, 32) - 1);
|
||||||
|
|
||||||
|
BigIntIPv6Addr s_allIPv6Ones;
|
||||||
|
bool s_ipv6Initialized = false;
|
||||||
|
|
||||||
|
void maybeInitialize() {
|
||||||
|
if (s_ipv6Initialized) return;
|
||||||
|
|
||||||
|
s_ipv6Initialized = true;
|
||||||
|
|
||||||
|
Q_IPV6ADDR allOnes;
|
||||||
|
memset((void*)&allOnes, static_cast<quint8>(qPow(2, 8) - 1), sizeof(allOnes));
|
||||||
|
|
||||||
|
s_allIPv6Ones = BigIntIPv6Addr(allOnes);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// static
|
||||||
|
IPAddress IPAddress::create(const QString& ip) {
|
||||||
|
if (ip.contains("/")) {
|
||||||
|
QPair<QHostAddress, int> p = QHostAddress::parseSubnet(ip);
|
||||||
|
|
||||||
|
if (p.first.protocol() == QAbstractSocket::IPv4Protocol) {
|
||||||
|
if (p.second < 32) {
|
||||||
|
return IPAddress(p.first, p.second);
|
||||||
|
}
|
||||||
|
return IPAddress(p.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p.first.protocol() == QAbstractSocket::IPv6Protocol) {
|
||||||
|
if (p.second < 128) {
|
||||||
|
return IPAddress(p.first, p.second);
|
||||||
|
}
|
||||||
|
return IPAddress(p.first);
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_ASSERT(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return IPAddress(QHostAddress(ip));
|
||||||
|
}
|
||||||
|
|
||||||
|
IPAddress::IPAddress() {
|
||||||
|
maybeInitialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
IPAddress::IPAddress(const IPAddress& other) {
|
||||||
|
maybeInitialize();
|
||||||
|
*this = other;
|
||||||
|
}
|
||||||
|
|
||||||
|
IPAddress& IPAddress::operator=(const IPAddress& other) {
|
||||||
|
if (this == &other) return *this;
|
||||||
|
|
||||||
|
m_address = other.m_address;
|
||||||
|
m_prefixLength = other.m_prefixLength;
|
||||||
|
m_netmask = other.m_netmask;
|
||||||
|
m_hostmask = other.m_hostmask;
|
||||||
|
m_broadcastAddress = other.m_broadcastAddress;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
IPAddress::IPAddress(const QHostAddress& address)
|
||||||
|
: m_address(address), m_broadcastAddress(address) {
|
||||||
|
maybeInitialize();
|
||||||
|
|
||||||
|
if (address.protocol() == QAbstractSocket::IPv4Protocol) {
|
||||||
|
m_prefixLength = 32;
|
||||||
|
m_netmask = QHostAddress(s_allIpV4Ones);
|
||||||
|
m_hostmask = QHostAddress((quint32)(0));
|
||||||
|
} else {
|
||||||
|
Q_ASSERT(address.protocol() == QAbstractSocket::IPv6Protocol);
|
||||||
|
m_prefixLength = 128;
|
||||||
|
|
||||||
|
m_netmask = QHostAddress(s_allIPv6Ones.value());
|
||||||
|
|
||||||
|
{
|
||||||
|
Q_IPV6ADDR ipv6;
|
||||||
|
memset((void*)&ipv6, 0, sizeof(ipv6));
|
||||||
|
m_hostmask = QHostAddress(ipv6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IPAddress::IPAddress(const QHostAddress& address, int prefixLength)
|
||||||
|
: m_address(address), m_prefixLength(prefixLength) {
|
||||||
|
maybeInitialize();
|
||||||
|
|
||||||
|
if (address.protocol() == QAbstractSocket::IPv4Protocol) {
|
||||||
|
Q_ASSERT(prefixLength >= 0 && prefixLength <= 32);
|
||||||
|
m_netmask = QHostAddress(s_allIpV4Ones ^ (s_allIpV4Ones >> prefixLength));
|
||||||
|
m_hostmask = QHostAddress(m_netmask.toIPv4Address() ^ s_allIpV4Ones);
|
||||||
|
m_broadcastAddress =
|
||||||
|
QHostAddress(address.toIPv4Address() | m_hostmask.toIPv4Address());
|
||||||
|
} else {
|
||||||
|
Q_ASSERT(address.protocol() == QAbstractSocket::IPv6Protocol);
|
||||||
|
Q_ASSERT(prefixLength >= 0 && prefixLength <= 128);
|
||||||
|
|
||||||
|
Q_IPV6ADDR netmask;
|
||||||
|
{
|
||||||
|
BigIntIPv6Addr tmp = (s_allIPv6Ones >> prefixLength);
|
||||||
|
for (int i = 0; i < 16; ++i)
|
||||||
|
netmask[i] = s_allIPv6Ones.value()[i] ^ tmp.value()[i];
|
||||||
|
}
|
||||||
|
m_netmask = QHostAddress(netmask);
|
||||||
|
|
||||||
|
{
|
||||||
|
Q_IPV6ADDR tmp;
|
||||||
|
for (int i = 0; i < 16; ++i)
|
||||||
|
tmp[i] = netmask[i] ^ s_allIPv6Ones.value()[i];
|
||||||
|
m_hostmask = QHostAddress(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
Q_IPV6ADDR ipv6Address = address.toIPv6Address();
|
||||||
|
Q_IPV6ADDR ipv6Hostname = m_hostmask.toIPv6Address();
|
||||||
|
for (int i = 0; i < 16; ++i) ipv6Address[i] |= ipv6Hostname[i];
|
||||||
|
m_broadcastAddress = QHostAddress(ipv6Address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IPAddress::~IPAddress() { }
|
||||||
|
|
||||||
|
QAbstractSocket::NetworkLayerProtocol IPAddress::type() const {
|
||||||
|
return m_address.protocol();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IPAddress::overlaps(const IPAddress& other) const {
|
||||||
|
return other.contains(m_address) || other.contains(m_broadcastAddress) ||
|
||||||
|
contains(other.m_address) || contains(other.m_broadcastAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IPAddress::contains(const QHostAddress& address) const {
|
||||||
|
if (address.protocol() != m_address.protocol()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (address.protocol() == QAbstractSocket::IPv4Protocol) {
|
||||||
|
return (m_address.toIPv4Address() <= address.toIPv4Address()) &&
|
||||||
|
(address.toIPv4Address() <= m_broadcastAddress.toIPv4Address());
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_ASSERT(address.protocol() == QAbstractSocket::IPv6Protocol);
|
||||||
|
return (BigIntIPv6Addr(m_address.toIPv6Address()) <=
|
||||||
|
BigIntIPv6Addr(address.toIPv6Address())) &&
|
||||||
|
(BigIntIPv6Addr(address.toIPv6Address()) <=
|
||||||
|
BigIntIPv6Addr(m_broadcastAddress.toIPv6Address()));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IPAddress::operator==(const IPAddress& other) const {
|
||||||
|
return m_address == other.m_address && m_netmask == other.m_netmask;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IPAddress::subnetOf(const IPAddress& other) const {
|
||||||
|
if (other.m_address.protocol() != m_address.protocol()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_address.protocol() == QAbstractSocket::IPv4Protocol) {
|
||||||
|
return other.m_address.toIPv4Address() <= m_address.toIPv4Address() &&
|
||||||
|
other.m_broadcastAddress.toIPv4Address() >=
|
||||||
|
m_broadcastAddress.toIPv4Address();
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_ASSERT(m_address.protocol() == QAbstractSocket::IPv6Protocol);
|
||||||
|
return BigIntIPv6Addr(other.m_address.toIPv6Address()) <=
|
||||||
|
BigIntIPv6Addr(m_address.toIPv6Address()) &&
|
||||||
|
BigIntIPv6Addr(other.m_broadcastAddress.toIPv6Address()) >=
|
||||||
|
BigIntIPv6Addr(m_broadcastAddress.toIPv6Address());
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<IPAddress> IPAddress::subnets() const {
|
||||||
|
QList<IPAddress> list;
|
||||||
|
|
||||||
|
if (m_address.protocol() == QAbstractSocket::IPv4Protocol) {
|
||||||
|
if (m_prefixLength == 32) {
|
||||||
|
list.append(*this);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
quint64 start = m_address.toIPv4Address();
|
||||||
|
quint64 end = quint64(m_broadcastAddress.toIPv4Address()) + 1;
|
||||||
|
quint64 step = ((quint64)m_hostmask.toIPv4Address() + 1) >> 1;
|
||||||
|
|
||||||
|
while (start < end) {
|
||||||
|
int newPrefixLength = m_prefixLength + 1;
|
||||||
|
if (newPrefixLength == 32) {
|
||||||
|
list.append(IPAddress(QHostAddress(static_cast<quint32>(start))));
|
||||||
|
} else {
|
||||||
|
list.append(IPAddress(QHostAddress(static_cast<quint32>(start)),
|
||||||
|
m_prefixLength + 1));
|
||||||
|
}
|
||||||
|
start += step;
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_ASSERT(m_address.protocol() == QAbstractSocket::IPv6Protocol);
|
||||||
|
|
||||||
|
if (m_prefixLength == 128) {
|
||||||
|
list.append(*this);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
BigInt start(17);
|
||||||
|
{
|
||||||
|
Q_IPV6ADDR addr = m_address.toIPv6Address();
|
||||||
|
for (int i = 0; i < 16; ++i) {
|
||||||
|
start.setValueAt(addr[i], i + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BigInt end(17);
|
||||||
|
{
|
||||||
|
Q_IPV6ADDR addr = m_broadcastAddress.toIPv6Address();
|
||||||
|
for (int i = 0; i < 16; ++i) {
|
||||||
|
end.setValueAt(addr[i], i + 1);
|
||||||
|
}
|
||||||
|
++end;
|
||||||
|
}
|
||||||
|
|
||||||
|
BigInt step(17);
|
||||||
|
{
|
||||||
|
Q_IPV6ADDR addr = m_hostmask.toIPv6Address();
|
||||||
|
for (int i = 0; i < 16; ++i) {
|
||||||
|
step.setValueAt(addr[i], i + 1);
|
||||||
|
}
|
||||||
|
step = (++step) >> 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (start < end) {
|
||||||
|
int newPrefixLength = m_prefixLength + 1;
|
||||||
|
Q_IPV6ADDR startIPv6;
|
||||||
|
for (int i = 0; i < 16; ++i) {
|
||||||
|
startIPv6[i] = start.valueAt(i + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newPrefixLength == 128) {
|
||||||
|
list.append(IPAddress(QHostAddress(startIPv6)));
|
||||||
|
} else {
|
||||||
|
list.append(IPAddress(QHostAddress(startIPv6), m_prefixLength + 1));
|
||||||
|
}
|
||||||
|
start += step;
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
QList<IPAddress> IPAddress::excludeAddresses(
|
||||||
|
const QList<IPAddress>& sourceList, const QList<IPAddress>& excludeList) {
|
||||||
|
QList<IPAddress> results = sourceList;
|
||||||
|
|
||||||
|
for (const IPAddress& exclude : excludeList) {
|
||||||
|
QList<IPAddress> newResults;
|
||||||
|
|
||||||
|
for (const IPAddress& ip : results) {
|
||||||
|
if (ip.overlaps(exclude)) {
|
||||||
|
QList<IPAddress> range = ip.excludeAddresses(exclude);
|
||||||
|
newResults.append(range);
|
||||||
|
} else {
|
||||||
|
newResults.append(ip);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
results = newResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<IPAddress> IPAddress::excludeAddresses(const IPAddress& ip) const {
|
||||||
|
QList<IPAddress> sn = subnets();
|
||||||
|
Q_ASSERT(sn.length() >= 2);
|
||||||
|
|
||||||
|
QList<IPAddress> result;
|
||||||
|
while (sn[0] != ip && sn[1] != ip) {
|
||||||
|
if (ip.subnetOf(sn[0])) {
|
||||||
|
result.append(sn[1]);
|
||||||
|
sn = sn[0].subnets();
|
||||||
|
} else if (ip.subnetOf(sn[1])) {
|
||||||
|
result.append(sn[0]);
|
||||||
|
sn = sn[1].subnets();
|
||||||
|
} else {
|
||||||
|
Q_ASSERT(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sn[0] == ip) {
|
||||||
|
result.append(sn[1]);
|
||||||
|
} else if (sn[1] == ip) {
|
||||||
|
result.append(sn[0]);
|
||||||
|
} else {
|
||||||
|
Q_ASSERT(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
59
client/platforms/ios/ipaddress.h
Normal file
59
client/platforms/ios/ipaddress.h
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef IPADDRESS_H
|
||||||
|
#define IPADDRESS_H
|
||||||
|
|
||||||
|
#include <QHostAddress>
|
||||||
|
|
||||||
|
class IPAddress final {
|
||||||
|
public:
|
||||||
|
static IPAddress create(const QString& ip);
|
||||||
|
static QList<IPAddress> excludeAddresses(const QList<IPAddress>& sourceList,
|
||||||
|
const QList<IPAddress>& excludeList);
|
||||||
|
|
||||||
|
IPAddress();
|
||||||
|
IPAddress(const IPAddress& other);
|
||||||
|
IPAddress& operator=(const IPAddress& other);
|
||||||
|
~IPAddress();
|
||||||
|
|
||||||
|
QString toString() const {
|
||||||
|
return QString("%1/%2").arg(m_address.toString()).arg(m_prefixLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
const QHostAddress& address() const { return m_address; }
|
||||||
|
int prefixLength() const { return m_prefixLength; }
|
||||||
|
const QHostAddress& netmask() const { return m_netmask; }
|
||||||
|
const QHostAddress& hostmask() const { return m_hostmask; }
|
||||||
|
const QHostAddress& broadcastAddress() const { return m_broadcastAddress; }
|
||||||
|
|
||||||
|
bool overlaps(const IPAddress& other) const;
|
||||||
|
|
||||||
|
bool contains(const QHostAddress& address) const;
|
||||||
|
|
||||||
|
bool operator==(const IPAddress& other) const;
|
||||||
|
bool operator!=(const IPAddress& other) const { return !operator==(other); }
|
||||||
|
|
||||||
|
bool subnetOf(const IPAddress& other) const;
|
||||||
|
|
||||||
|
QList<IPAddress> subnets() const;
|
||||||
|
|
||||||
|
QList<IPAddress> excludeAddresses(const IPAddress& ip) const;
|
||||||
|
|
||||||
|
QAbstractSocket::NetworkLayerProtocol type() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
IPAddress(const QHostAddress& address);
|
||||||
|
IPAddress(const QHostAddress& address, int prefixLength);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QHostAddress m_address;
|
||||||
|
int m_prefixLength;
|
||||||
|
|
||||||
|
QHostAddress m_netmask;
|
||||||
|
QHostAddress m_hostmask;
|
||||||
|
QHostAddress m_broadcastAddress;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // IPADDRESS_H
|
60
client/platforms/ios/ipaddressrange.cpp
Normal file
60
client/platforms/ios/ipaddressrange.cpp
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "ipaddressrange.h"
|
||||||
|
#include "ipaddress.h"
|
||||||
|
|
||||||
|
IPAddressRange::IPAddressRange(const QString& ipAddress, uint32_t range,
|
||||||
|
IPAddressType type)
|
||||||
|
: m_ipAddress(ipAddress), m_range(range), m_type(type) {}
|
||||||
|
|
||||||
|
IPAddressRange::IPAddressRange(const QString& prefix) {
|
||||||
|
QStringList split = prefix.split('/');
|
||||||
|
m_ipAddress = split[0];
|
||||||
|
if (m_ipAddress.contains(':')) {
|
||||||
|
// Probably IPv6
|
||||||
|
m_type = IPv6;
|
||||||
|
m_range = 128;
|
||||||
|
} else {
|
||||||
|
// Assume IPv4
|
||||||
|
m_type = IPv4;
|
||||||
|
m_range = 32;
|
||||||
|
}
|
||||||
|
if (split.count() > 1) {
|
||||||
|
m_range = split[1].toUInt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IPAddressRange::IPAddressRange(const IPAddressRange& other) {
|
||||||
|
*this = other;
|
||||||
|
}
|
||||||
|
|
||||||
|
IPAddressRange& IPAddressRange::operator=(const IPAddressRange& other) {
|
||||||
|
if (this == &other) return *this;
|
||||||
|
|
||||||
|
m_ipAddress = other.m_ipAddress;
|
||||||
|
m_range = other.m_range;
|
||||||
|
m_type = other.m_type;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IPAddressRange::operator==(const IPAddressRange& other) const {
|
||||||
|
if (this == &other) return true;
|
||||||
|
|
||||||
|
return m_ipAddress == other.m_ipAddress && m_range == other.m_range &&
|
||||||
|
m_type == other.m_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
IPAddressRange::~IPAddressRange() { }
|
||||||
|
|
||||||
|
// static
|
||||||
|
QList<IPAddressRange> IPAddressRange::fromIPAddressList(
|
||||||
|
const QList<IPAddress>& list) {
|
||||||
|
QList<IPAddressRange> result;
|
||||||
|
for (const IPAddress& ip : list) {
|
||||||
|
result.append(IPAddressRange(ip.toString()));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
42
client/platforms/ios/ipaddressrange.h
Normal file
42
client/platforms/ios/ipaddressrange.h
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#ifndef IPADDRESSRANGE_H
|
||||||
|
#define IPADDRESSRANGE_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
class IPAddress;
|
||||||
|
|
||||||
|
class IPAddressRange final {
|
||||||
|
public:
|
||||||
|
enum IPAddressType {
|
||||||
|
IPv4,
|
||||||
|
IPv6,
|
||||||
|
};
|
||||||
|
|
||||||
|
static QList<IPAddressRange> fromIPAddressList(const QList<IPAddress>& list);
|
||||||
|
|
||||||
|
IPAddressRange(const QString& prefix);
|
||||||
|
IPAddressRange(const QString& ipAddress, uint32_t range, IPAddressType type);
|
||||||
|
IPAddressRange(const IPAddressRange& other);
|
||||||
|
IPAddressRange& operator=(const IPAddressRange& other);
|
||||||
|
bool operator==(const IPAddressRange& other) const;
|
||||||
|
~IPAddressRange();
|
||||||
|
|
||||||
|
const QString& ipAddress() const { return m_ipAddress; }
|
||||||
|
uint32_t range() const { return m_range; }
|
||||||
|
IPAddressType type() const { return m_type; }
|
||||||
|
const QString toString() const {
|
||||||
|
return QString("%1/%2").arg(m_ipAddress).arg(m_range);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_ipAddress;
|
||||||
|
uint32_t m_range;
|
||||||
|
IPAddressType m_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // IPADDRESSRANGE_H
|
732
client/platforms/ios/json.cpp
Normal file
732
client/platforms/ios/json.cpp
Normal file
|
@ -0,0 +1,732 @@
|
||||||
|
/**
|
||||||
|
* QtJson - A simple class for parsing JSON data into a QVariant hierarchies and vice-versa.
|
||||||
|
* Copyright (C) 2011 Eeli Reilin
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file json.cpp
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QStringList>
|
||||||
|
#include "json.h"
|
||||||
|
|
||||||
|
namespace QtJson {
|
||||||
|
static QString dateFormat, dateTimeFormat;
|
||||||
|
static bool prettySerialize = false;
|
||||||
|
|
||||||
|
static QString sanitizeString(QString str);
|
||||||
|
static QByteArray join(const QList<QByteArray> &list, const QByteArray &sep);
|
||||||
|
static QVariant parseValue(const QString &json, int &index, bool &success);
|
||||||
|
static QVariant parseObject(const QString &json, int &index, bool &success);
|
||||||
|
static QVariant parseArray(const QString &json, int &index, bool &success);
|
||||||
|
static QVariant parseString(const QString &json, int &index, bool &success);
|
||||||
|
static QVariant parseNumber(const QString &json, int &index);
|
||||||
|
static int lastIndexOfNumber(const QString &json, int index);
|
||||||
|
static void eatWhitespace(const QString &json, int &index);
|
||||||
|
static int lookAhead(const QString &json, int index);
|
||||||
|
static int nextToken(const QString &json, int &index);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
QByteArray serializeMap(const T &map, bool &success, int _level = 0) {
|
||||||
|
QByteArray newline;
|
||||||
|
QByteArray tabs;
|
||||||
|
QByteArray tabsFields;
|
||||||
|
if (prettySerialize && !map.isEmpty()) {
|
||||||
|
newline = "\n";
|
||||||
|
for (uint l=1; l<_level; l++) {
|
||||||
|
tabs += " ";
|
||||||
|
}
|
||||||
|
tabsFields = tabs + " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray str = "{" + newline;
|
||||||
|
QList<QByteArray> pairs;
|
||||||
|
for (typename T::const_iterator it = map.begin(), itend = map.end(); it != itend; ++it) {
|
||||||
|
bool otherSuccess = true;
|
||||||
|
QByteArray serializedValue = serialize(it.value(), otherSuccess, _level);
|
||||||
|
if (serializedValue.isNull()) {
|
||||||
|
success = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pairs << tabsFields + sanitizeString(it.key()).toUtf8() + ":" + (prettySerialize ? " " : "") + serializedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
str += join(pairs, "," + newline) + newline;
|
||||||
|
str += tabs + "}";
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
void insert(QVariant &v, const QString &key, const QVariant &value);
|
||||||
|
void append(QVariant &v, const QVariant &value);
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void cloneMap(QVariant &json, const T &map) {
|
||||||
|
for (typename T::const_iterator it = map.begin(), itend = map.end(); it != itend; ++it) {
|
||||||
|
insert(json, it.key(), (*it));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void cloneList(QVariant &json, const T &list) {
|
||||||
|
for (typename T::const_iterator it = list.begin(), itend = list.end(); it != itend; ++it) {
|
||||||
|
append(json, (*it));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* parse
|
||||||
|
*/
|
||||||
|
QVariant parse(const QString &json) {
|
||||||
|
bool success = true;
|
||||||
|
return parse(json, success);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* parse
|
||||||
|
*/
|
||||||
|
QVariant parse(const QString &json, bool &success) {
|
||||||
|
success = true;
|
||||||
|
|
||||||
|
// Return an empty QVariant if the JSON data is either null or empty
|
||||||
|
if (!json.isNull() || !json.isEmpty()) {
|
||||||
|
QString data = json;
|
||||||
|
// We'll start from index 0
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
// Parse the first value
|
||||||
|
QVariant value = parseValue(data, index, success);
|
||||||
|
|
||||||
|
// Return the parsed value
|
||||||
|
return value;
|
||||||
|
} else {
|
||||||
|
// Return the empty QVariant
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clone
|
||||||
|
*/
|
||||||
|
QVariant clone(const QVariant &data) {
|
||||||
|
QVariant v;
|
||||||
|
|
||||||
|
if (data.type() == QVariant::Map) {
|
||||||
|
cloneMap(v, data.toMap());
|
||||||
|
} else if (data.type() == QVariant::Hash) {
|
||||||
|
cloneMap(v, data.toHash());
|
||||||
|
} else if (data.type() == QVariant::List) {
|
||||||
|
cloneList(v, data.toList());
|
||||||
|
} else if (data.type() == QVariant::StringList) {
|
||||||
|
cloneList(v, data.toStringList());
|
||||||
|
} else {
|
||||||
|
v = QVariant(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* insert value (map case)
|
||||||
|
*/
|
||||||
|
void insert(QVariant &v, const QString &key, const QVariant &value) {
|
||||||
|
if (!v.canConvert<QVariantMap>()) v = QVariantMap();
|
||||||
|
QVariantMap *p = (QVariantMap *)v.data();
|
||||||
|
p->insert(key, clone(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* append value (list case)
|
||||||
|
*/
|
||||||
|
void append(QVariant &v, const QVariant &value) {
|
||||||
|
if (!v.canConvert<QVariantList>()) v = QVariantList();
|
||||||
|
QVariantList *p = (QVariantList *)v.data();
|
||||||
|
p->append(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray serialize(const QVariant &data) {
|
||||||
|
bool success = true;
|
||||||
|
return serialize(data, success);
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray serialize(const QVariant &data, bool &success, int _level /*= 0*/) {
|
||||||
|
QByteArray newline;
|
||||||
|
QByteArray tabs;
|
||||||
|
QByteArray tabsFields;
|
||||||
|
if (prettySerialize) {
|
||||||
|
newline = "\n";
|
||||||
|
for (uint l=0; l<_level; l++) {
|
||||||
|
tabs += " ";
|
||||||
|
}
|
||||||
|
tabsFields = tabs + " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray str;
|
||||||
|
success = true;
|
||||||
|
|
||||||
|
if (!data.isValid()) { // invalid or null?
|
||||||
|
str = "null";
|
||||||
|
} else if ((data.type() == QVariant::List) ||
|
||||||
|
(data.type() == QVariant::StringList)) { // variant is a list?
|
||||||
|
QList<QByteArray> values;
|
||||||
|
const QVariantList list = data.toList();
|
||||||
|
Q_FOREACH(const QVariant& v, list) {
|
||||||
|
bool otherSuccess = true;
|
||||||
|
QByteArray serializedValue = serialize(v, otherSuccess, _level+1);
|
||||||
|
if (serializedValue.isNull()) {
|
||||||
|
success = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
values << tabsFields + serializedValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!values.isEmpty()) {
|
||||||
|
str = "[" + newline + join( values, "," + newline ) + newline + tabs + "]";
|
||||||
|
} else {
|
||||||
|
str = "[]";
|
||||||
|
}
|
||||||
|
} else if (data.type() == QVariant::Hash) { // variant is a hash?
|
||||||
|
str = serializeMap<>(data.toHash(), success, _level+1);
|
||||||
|
} else if (data.type() == QVariant::Map) { // variant is a map?
|
||||||
|
str = serializeMap<>(data.toMap(), success, _level+1);
|
||||||
|
} else if ((data.type() == QVariant::String) ||
|
||||||
|
(data.type() == QVariant::ByteArray)) {// a string or a byte array?
|
||||||
|
str = sanitizeString(data.toString()).toUtf8();
|
||||||
|
} else if (data.type() == QVariant::Double) { // double?
|
||||||
|
double value = data.toDouble(&success);
|
||||||
|
if (success) {
|
||||||
|
str = QByteArray::number(value, 'g');
|
||||||
|
if (!str.contains(".") && ! str.contains("e")) {
|
||||||
|
str += ".0";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (data.type() == QVariant::Bool) { // boolean value?
|
||||||
|
str = data.toBool() ? "true" : "false";
|
||||||
|
} else if (data.type() == QVariant::ULongLong) { // large unsigned number?
|
||||||
|
str = QByteArray::number(data.value<qulonglong>());
|
||||||
|
} else if (data.canConvert<qlonglong>()) { // any signed number?
|
||||||
|
str = QByteArray::number(data.value<qlonglong>());
|
||||||
|
} else if (data.canConvert<long>()) { //TODO: this code is never executed because all smaller types can be converted to qlonglong
|
||||||
|
str = QString::number(data.value<long>()).toUtf8();
|
||||||
|
} else if (data.type() == QVariant::DateTime) { // datetime value?
|
||||||
|
str = sanitizeString(dateTimeFormat.isEmpty()
|
||||||
|
? data.toDateTime().toString()
|
||||||
|
: data.toDateTime().toString(dateTimeFormat)).toUtf8();
|
||||||
|
} else if (data.type() == QVariant::Date) { // date value?
|
||||||
|
str = sanitizeString(dateTimeFormat.isEmpty()
|
||||||
|
? data.toDate().toString()
|
||||||
|
: data.toDate().toString(dateFormat)).toUtf8();
|
||||||
|
} else if (data.canConvert<QString>()) { // can value be converted to string?
|
||||||
|
// this will catch QUrl, ... (all other types which can be converted to string)
|
||||||
|
str = sanitizeString(data.toString()).toUtf8();
|
||||||
|
} else {
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
return QByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString serializeStr(const QVariant &data) {
|
||||||
|
return QString::fromUtf8(serialize(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
QString serializeStr(const QVariant &data, bool &success) {
|
||||||
|
return QString::fromUtf8(serialize(data, success));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \enum JsonToken
|
||||||
|
*/
|
||||||
|
enum JsonToken {
|
||||||
|
JsonTokenNone = 0,
|
||||||
|
JsonTokenCurlyOpen = 1,
|
||||||
|
JsonTokenCurlyClose = 2,
|
||||||
|
JsonTokenSquaredOpen = 3,
|
||||||
|
JsonTokenSquaredClose = 4,
|
||||||
|
JsonTokenColon = 5,
|
||||||
|
JsonTokenComma = 6,
|
||||||
|
JsonTokenString = 7,
|
||||||
|
JsonTokenNumber = 8,
|
||||||
|
JsonTokenTrue = 9,
|
||||||
|
JsonTokenFalse = 10,
|
||||||
|
JsonTokenNull = 11
|
||||||
|
};
|
||||||
|
|
||||||
|
static QString sanitizeString(QString str) {
|
||||||
|
str.replace(QLatin1String("\\"), QLatin1String("\\\\"));
|
||||||
|
str.replace(QLatin1String("\""), QLatin1String("\\\""));
|
||||||
|
str.replace(QLatin1String("\b"), QLatin1String("\\b"));
|
||||||
|
str.replace(QLatin1String("\f"), QLatin1String("\\f"));
|
||||||
|
str.replace(QLatin1String("\n"), QLatin1String("\\n"));
|
||||||
|
str.replace(QLatin1String("\r"), QLatin1String("\\r"));
|
||||||
|
str.replace(QLatin1String("\t"), QLatin1String("\\t"));
|
||||||
|
return QString(QLatin1String("\"%1\"")).arg(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
static QByteArray join(const QList<QByteArray> &list, const QByteArray &sep) {
|
||||||
|
QByteArray res;
|
||||||
|
Q_FOREACH(const QByteArray &i, list) {
|
||||||
|
if (!res.isEmpty()) {
|
||||||
|
res += sep;
|
||||||
|
}
|
||||||
|
res += i;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* parseValue
|
||||||
|
*/
|
||||||
|
static QVariant parseValue(const QString &json, int &index, bool &success) {
|
||||||
|
// Determine what kind of data we should parse by
|
||||||
|
// checking out the upcoming token
|
||||||
|
switch(lookAhead(json, index)) {
|
||||||
|
case JsonTokenString:
|
||||||
|
return parseString(json, index, success);
|
||||||
|
case JsonTokenNumber:
|
||||||
|
return parseNumber(json, index);
|
||||||
|
case JsonTokenCurlyOpen:
|
||||||
|
return parseObject(json, index, success);
|
||||||
|
case JsonTokenSquaredOpen:
|
||||||
|
return parseArray(json, index, success);
|
||||||
|
case JsonTokenTrue:
|
||||||
|
nextToken(json, index);
|
||||||
|
return QVariant(true);
|
||||||
|
case JsonTokenFalse:
|
||||||
|
nextToken(json, index);
|
||||||
|
return QVariant(false);
|
||||||
|
case JsonTokenNull:
|
||||||
|
nextToken(json, index);
|
||||||
|
return QVariant();
|
||||||
|
case JsonTokenNone:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there were no tokens, flag the failure and return an empty QVariant
|
||||||
|
success = false;
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* parseObject
|
||||||
|
*/
|
||||||
|
static QVariant parseObject(const QString &json, int &index, bool &success) {
|
||||||
|
QVariantMap map;
|
||||||
|
int token;
|
||||||
|
|
||||||
|
// Get rid of the whitespace and increment index
|
||||||
|
nextToken(json, index);
|
||||||
|
|
||||||
|
// Loop through all of the key/value pairs of the object
|
||||||
|
bool done = false;
|
||||||
|
while (!done) {
|
||||||
|
// Get the upcoming token
|
||||||
|
token = lookAhead(json, index);
|
||||||
|
|
||||||
|
if (token == JsonTokenNone) {
|
||||||
|
success = false;
|
||||||
|
return QVariantMap();
|
||||||
|
} else if (token == JsonTokenComma) {
|
||||||
|
nextToken(json, index);
|
||||||
|
} else if (token == JsonTokenCurlyClose) {
|
||||||
|
nextToken(json, index);
|
||||||
|
return map;
|
||||||
|
} else {
|
||||||
|
// Parse the key/value pair's name
|
||||||
|
QString name = parseString(json, index, success).toString();
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
return QVariantMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the next token
|
||||||
|
token = nextToken(json, index);
|
||||||
|
|
||||||
|
// If the next token is not a colon, flag the failure
|
||||||
|
// return an empty QVariant
|
||||||
|
if (token != JsonTokenColon) {
|
||||||
|
success = false;
|
||||||
|
return QVariant(QVariantMap());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the key/value pair's value
|
||||||
|
QVariant value = parseValue(json, index, success);
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
return QVariantMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign the value to the key in the map
|
||||||
|
map[name] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the map successfully
|
||||||
|
return QVariant(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* parseArray
|
||||||
|
*/
|
||||||
|
static QVariant parseArray(const QString &json, int &index, bool &success) {
|
||||||
|
QVariantList list;
|
||||||
|
|
||||||
|
nextToken(json, index);
|
||||||
|
|
||||||
|
bool done = false;
|
||||||
|
while(!done) {
|
||||||
|
int token = lookAhead(json, index);
|
||||||
|
|
||||||
|
if (token == JsonTokenNone) {
|
||||||
|
success = false;
|
||||||
|
return QVariantList();
|
||||||
|
} else if (token == JsonTokenComma) {
|
||||||
|
nextToken(json, index);
|
||||||
|
} else if (token == JsonTokenSquaredClose) {
|
||||||
|
nextToken(json, index);
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
QVariant value = parseValue(json, index, success);
|
||||||
|
if (!success) {
|
||||||
|
return QVariantList();
|
||||||
|
}
|
||||||
|
list.push_back(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* parseString
|
||||||
|
*/
|
||||||
|
static QVariant parseString(const QString &json, int &index, bool &success) {
|
||||||
|
QString s;
|
||||||
|
QChar c;
|
||||||
|
|
||||||
|
eatWhitespace(json, index);
|
||||||
|
|
||||||
|
c = json[index++];
|
||||||
|
|
||||||
|
bool complete = false;
|
||||||
|
while(!complete) {
|
||||||
|
if (index == json.size()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = json[index++];
|
||||||
|
|
||||||
|
if (c == '\"') {
|
||||||
|
complete = true;
|
||||||
|
break;
|
||||||
|
} else if (c == '\\') {
|
||||||
|
if (index == json.size()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
c = json[index++];
|
||||||
|
|
||||||
|
if (c == '\"') {
|
||||||
|
s.append('\"');
|
||||||
|
} else if (c == '\\') {
|
||||||
|
s.append('\\');
|
||||||
|
} else if (c == '/') {
|
||||||
|
s.append('/');
|
||||||
|
} else if (c == 'b') {
|
||||||
|
s.append('\b');
|
||||||
|
} else if (c == 'f') {
|
||||||
|
s.append('\f');
|
||||||
|
} else if (c == 'n') {
|
||||||
|
s.append('\n');
|
||||||
|
} else if (c == 'r') {
|
||||||
|
s.append('\r');
|
||||||
|
} else if (c == 't') {
|
||||||
|
s.append('\t');
|
||||||
|
} else if (c == 'u') {
|
||||||
|
int remainingLength = json.size() - index;
|
||||||
|
if (remainingLength >= 4) {
|
||||||
|
QString unicodeStr = json.mid(index, 4);
|
||||||
|
|
||||||
|
int symbol = unicodeStr.toInt(0, 16);
|
||||||
|
|
||||||
|
s.append(QChar(symbol));
|
||||||
|
|
||||||
|
index += 4;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
s.append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!complete) {
|
||||||
|
success = false;
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* parseNumber
|
||||||
|
*/
|
||||||
|
static QVariant parseNumber(const QString &json, int &index) {
|
||||||
|
eatWhitespace(json, index);
|
||||||
|
|
||||||
|
int lastIndex = lastIndexOfNumber(json, index);
|
||||||
|
int charLength = (lastIndex - index) + 1;
|
||||||
|
QString numberStr;
|
||||||
|
|
||||||
|
numberStr = json.mid(index, charLength);
|
||||||
|
|
||||||
|
index = lastIndex + 1;
|
||||||
|
bool ok;
|
||||||
|
|
||||||
|
if (numberStr.contains('.')) {
|
||||||
|
return QVariant(numberStr.toDouble(NULL));
|
||||||
|
} else if (numberStr.startsWith('-')) {
|
||||||
|
int i = numberStr.toInt(&ok);
|
||||||
|
if (!ok) {
|
||||||
|
qlonglong ll = numberStr.toLongLong(&ok);
|
||||||
|
return ok ? ll : QVariant(numberStr);
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
} else {
|
||||||
|
uint u = numberStr.toUInt(&ok);
|
||||||
|
if (!ok) {
|
||||||
|
qulonglong ull = numberStr.toULongLong(&ok);
|
||||||
|
return ok ? ull : QVariant(numberStr);
|
||||||
|
}
|
||||||
|
return u;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* lastIndexOfNumber
|
||||||
|
*/
|
||||||
|
static int lastIndexOfNumber(const QString &json, int index) {
|
||||||
|
int lastIndex;
|
||||||
|
|
||||||
|
for(lastIndex = index; lastIndex < json.size(); lastIndex++) {
|
||||||
|
if (QString("0123456789+-.eE").indexOf(json[lastIndex]) == -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return lastIndex -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* eatWhitespace
|
||||||
|
*/
|
||||||
|
static void eatWhitespace(const QString &json, int &index) {
|
||||||
|
for(; index < json.size(); index++) {
|
||||||
|
if (QString(" \t\n\r").indexOf(json[index]) == -1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* lookAhead
|
||||||
|
*/
|
||||||
|
static int lookAhead(const QString &json, int index) {
|
||||||
|
int saveIndex = index;
|
||||||
|
return nextToken(json, saveIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nextToken
|
||||||
|
*/
|
||||||
|
static int nextToken(const QString &json, int &index) {
|
||||||
|
eatWhitespace(json, index);
|
||||||
|
|
||||||
|
if (index == json.size()) {
|
||||||
|
return JsonTokenNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
QChar c = json[index];
|
||||||
|
index++;
|
||||||
|
switch(c.toLatin1()) {
|
||||||
|
case '{': return JsonTokenCurlyOpen;
|
||||||
|
case '}': return JsonTokenCurlyClose;
|
||||||
|
case '[': return JsonTokenSquaredOpen;
|
||||||
|
case ']': return JsonTokenSquaredClose;
|
||||||
|
case ',': return JsonTokenComma;
|
||||||
|
case '"': return JsonTokenString;
|
||||||
|
case '0': case '1': case '2': case '3': case '4':
|
||||||
|
case '5': case '6': case '7': case '8': case '9':
|
||||||
|
case '-': return JsonTokenNumber;
|
||||||
|
case ':': return JsonTokenColon;
|
||||||
|
}
|
||||||
|
index--; // ^ WTF?
|
||||||
|
|
||||||
|
int remainingLength = json.size() - index;
|
||||||
|
|
||||||
|
// True
|
||||||
|
if (remainingLength >= 4) {
|
||||||
|
if (json[index] == 't' && json[index + 1] == 'r' &&
|
||||||
|
json[index + 2] == 'u' && json[index + 3] == 'e') {
|
||||||
|
index += 4;
|
||||||
|
return JsonTokenTrue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// False
|
||||||
|
if (remainingLength >= 5) {
|
||||||
|
if (json[index] == 'f' && json[index + 1] == 'a' &&
|
||||||
|
json[index + 2] == 'l' && json[index + 3] == 's' &&
|
||||||
|
json[index + 4] == 'e') {
|
||||||
|
index += 5;
|
||||||
|
return JsonTokenFalse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Null
|
||||||
|
if (remainingLength >= 4) {
|
||||||
|
if (json[index] == 'n' && json[index + 1] == 'u' &&
|
||||||
|
json[index + 2] == 'l' && json[index + 3] == 'l') {
|
||||||
|
index += 4;
|
||||||
|
return JsonTokenNull;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return JsonTokenNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDateTimeFormat(const QString &format) {
|
||||||
|
dateTimeFormat = format;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDateFormat(const QString &format) {
|
||||||
|
dateFormat = format;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString getDateTimeFormat() {
|
||||||
|
return dateTimeFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString getDateFormat() {
|
||||||
|
return dateFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPrettySerialize(bool enabled) {
|
||||||
|
prettySerialize = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isPrettySerialize() {
|
||||||
|
return prettySerialize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
QQueue<BuilderJsonObject *> BuilderJsonObject::created_list;
|
||||||
|
|
||||||
|
BuilderJsonObject::BuilderJsonObject() {
|
||||||
|
// clean objects previous "created"
|
||||||
|
while (!BuilderJsonObject::created_list.isEmpty()) {
|
||||||
|
delete BuilderJsonObject::created_list.dequeue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BuilderJsonObject::BuilderJsonObject(JsonObject &json) {
|
||||||
|
BuilderJsonObject();
|
||||||
|
|
||||||
|
obj = json;
|
||||||
|
}
|
||||||
|
|
||||||
|
BuilderJsonObject *BuilderJsonObject::set(const QString &key, const QVariant &value) {
|
||||||
|
obj[key] = value;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BuilderJsonObject *BuilderJsonObject::set(const QString &key, BuilderJsonObject *builder) {
|
||||||
|
return set(key, builder->create());
|
||||||
|
}
|
||||||
|
|
||||||
|
BuilderJsonObject *BuilderJsonObject::set(const QString &key, BuilderJsonArray *builder) {
|
||||||
|
return set(key, builder->create());
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonObject BuilderJsonObject::create() {
|
||||||
|
BuilderJsonObject::created_list.enqueue(this);
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QQueue<BuilderJsonArray *> BuilderJsonArray::created_list;
|
||||||
|
|
||||||
|
BuilderJsonArray::BuilderJsonArray() {
|
||||||
|
// clean objects previous "created"
|
||||||
|
while (!BuilderJsonArray::created_list.isEmpty()) {
|
||||||
|
delete BuilderJsonArray::created_list.dequeue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BuilderJsonArray::BuilderJsonArray(JsonArray &json) {
|
||||||
|
BuilderJsonArray();
|
||||||
|
|
||||||
|
array = json;
|
||||||
|
}
|
||||||
|
|
||||||
|
BuilderJsonArray *BuilderJsonArray::add(const QVariant &element) {
|
||||||
|
array.append(element);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
BuilderJsonArray *BuilderJsonArray::add(BuilderJsonObject *builder) {
|
||||||
|
return add(builder->create());
|
||||||
|
}
|
||||||
|
|
||||||
|
BuilderJsonArray *BuilderJsonArray::add(BuilderJsonArray *builder) {
|
||||||
|
return add(builder->create());
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonArray BuilderJsonArray::create() {
|
||||||
|
BuilderJsonArray::created_list.enqueue(this);
|
||||||
|
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BuilderJsonObject *objectBuilder() {
|
||||||
|
return new BuilderJsonObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
BuilderJsonObject *objectBuilder(JsonObject &json) {
|
||||||
|
return new BuilderJsonObject(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
BuilderJsonArray *arrayBuilder() {
|
||||||
|
return new BuilderJsonArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
BuilderJsonArray *arrayBuilder(JsonArray &json) {
|
||||||
|
return new BuilderJsonArray(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
} //end namespace
|
265
client/platforms/ios/json.h
Normal file
265
client/platforms/ios/json.h
Normal file
|
@ -0,0 +1,265 @@
|
||||||
|
/**
|
||||||
|
* QtJson - A simple class for parsing JSON data into a QVariant hierarchies and vice-versa.
|
||||||
|
* Copyright (C) 2011 Eeli Reilin
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file json.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef JSON_H
|
||||||
|
#define JSON_H
|
||||||
|
|
||||||
|
#include <QVariant>
|
||||||
|
#include <QString>
|
||||||
|
#include <QQueue>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \namespace QtJson
|
||||||
|
* \brief A JSON data parser
|
||||||
|
*
|
||||||
|
* Json parses a JSON data into a QVariant hierarchy.
|
||||||
|
*/
|
||||||
|
namespace QtJson {
|
||||||
|
typedef QVariantMap JsonObject;
|
||||||
|
typedef QVariantList JsonArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clone a JSON object (makes a deep copy)
|
||||||
|
*
|
||||||
|
* \param data The JSON object
|
||||||
|
*/
|
||||||
|
QVariant clone(const QVariant &data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert value to JSON object (QVariantMap)
|
||||||
|
*
|
||||||
|
* \param v The JSON object
|
||||||
|
* \param key The key
|
||||||
|
* \param value The value
|
||||||
|
*/
|
||||||
|
void insert(QVariant &v, const QString &key, const QVariant &value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append value to JSON array (QVariantList)
|
||||||
|
*
|
||||||
|
* \param v The JSON array
|
||||||
|
* \param value The value
|
||||||
|
*/
|
||||||
|
void append(QVariant &v, const QVariant &value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a JSON string
|
||||||
|
*
|
||||||
|
* \param json The JSON data
|
||||||
|
*/
|
||||||
|
QVariant parse(const QString &json);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse a JSON string
|
||||||
|
*
|
||||||
|
* \param json The JSON data
|
||||||
|
* \param success The success of the parsing
|
||||||
|
*/
|
||||||
|
QVariant parse(const QString &json, bool &success);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method generates a textual JSON representation
|
||||||
|
*
|
||||||
|
* \param data The JSON data generated by the parser.
|
||||||
|
*
|
||||||
|
* \return QByteArray Textual JSON representation in UTF-8
|
||||||
|
*/
|
||||||
|
QByteArray serialize(const QVariant &data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method generates a textual JSON representation
|
||||||
|
*
|
||||||
|
* \param data The JSON data generated by the parser.
|
||||||
|
* \param success The success of the serialization
|
||||||
|
*
|
||||||
|
* \return QByteArray Textual JSON representation in UTF-8
|
||||||
|
*/
|
||||||
|
QByteArray serialize(const QVariant &data, bool &success, int _level = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method generates a textual JSON representation
|
||||||
|
*
|
||||||
|
* \param data The JSON data generated by the parser.
|
||||||
|
*
|
||||||
|
* \return QString Textual JSON representation
|
||||||
|
*/
|
||||||
|
QString serializeStr(const QVariant &data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method generates a textual JSON representation
|
||||||
|
*
|
||||||
|
* \param data The JSON data generated by the parser.
|
||||||
|
* \param success The success of the serialization
|
||||||
|
*
|
||||||
|
* \return QString Textual JSON representation
|
||||||
|
*/
|
||||||
|
QString serializeStr(const QVariant &data, bool &success, int _level = 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets date(time) format to be used for QDateTime::toString
|
||||||
|
* If QString is empty, Qt::TextDate is used.
|
||||||
|
*
|
||||||
|
* \param format The JSON data generated by the parser.
|
||||||
|
*/
|
||||||
|
void setDateTimeFormat(const QString& format);
|
||||||
|
void setDateFormat(const QString& format);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method gets date(time) format to be used for QDateTime::toString
|
||||||
|
* If QString is empty, Qt::TextDate is used.
|
||||||
|
*/
|
||||||
|
QString getDateTimeFormat();
|
||||||
|
QString getDateFormat();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief setPrettySerialize enable/disabled pretty-print when serialize() a json
|
||||||
|
* @param enabled
|
||||||
|
*/
|
||||||
|
void setPrettySerialize(bool enabled);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief isPrettySerialize check if is enabled pretty-print when serialize() a json
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
bool isPrettySerialize();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* QVariant based Json object
|
||||||
|
*/
|
||||||
|
class Object : public QVariant {
|
||||||
|
template<typename T>
|
||||||
|
Object& insertKey(Object* ptr, const QString& key) {
|
||||||
|
T* p = (T*)ptr->data();
|
||||||
|
if (!p->contains(key)) p->insert(key, QVariant());
|
||||||
|
return *reinterpret_cast<Object*>(&p->operator[](key));
|
||||||
|
}
|
||||||
|
template<typename T>
|
||||||
|
void removeKey(Object *ptr, const QString& key) {
|
||||||
|
T* p = (T*)ptr->data();
|
||||||
|
p->remove(key);
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
Object() : QVariant() {}
|
||||||
|
Object(const Object& ref) : QVariant(ref) {}
|
||||||
|
|
||||||
|
Object& operator=(const QVariant& rhs) {
|
||||||
|
/** It maybe more robust when running under Qt versions below 4.7 */
|
||||||
|
QObject * obj = qvariant_cast<QObject *>(rhs);
|
||||||
|
// setValue(rhs);
|
||||||
|
setValue(obj);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
Object& operator[](const QString& key) {
|
||||||
|
if (type() == QVariant::Map)
|
||||||
|
return insertKey<QVariantMap>(this, key);
|
||||||
|
else if (type() == QVariant::Hash)
|
||||||
|
return insertKey<QVariantHash>(this, key);
|
||||||
|
|
||||||
|
setValue(QVariantMap());
|
||||||
|
|
||||||
|
return insertKey<QVariantMap>(this, key);
|
||||||
|
}
|
||||||
|
const Object& operator[](const QString& key) const {
|
||||||
|
return const_cast<Object*>(this)->operator[](key);
|
||||||
|
}
|
||||||
|
void remove(const QString& key) {
|
||||||
|
if (type() == QVariant::Map)
|
||||||
|
removeKey<QVariantMap>(this, key);
|
||||||
|
else if (type() == QVariant::Hash)
|
||||||
|
removeKey<QVariantHash>(this, key);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class BuilderJsonArray;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The BuilderJsonObject class
|
||||||
|
*/
|
||||||
|
class BuilderJsonObject {
|
||||||
|
|
||||||
|
public:
|
||||||
|
BuilderJsonObject();
|
||||||
|
BuilderJsonObject(JsonObject &json);
|
||||||
|
|
||||||
|
BuilderJsonObject *set(const QString &key, const QVariant &value);
|
||||||
|
BuilderJsonObject *set(const QString &key, BuilderJsonObject *builder);
|
||||||
|
BuilderJsonObject *set(const QString &key, BuilderJsonArray *builder);
|
||||||
|
JsonObject create();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static QQueue<BuilderJsonObject *> created_list;
|
||||||
|
|
||||||
|
JsonObject obj;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief The BuilderJsonArray class
|
||||||
|
*/
|
||||||
|
class BuilderJsonArray {
|
||||||
|
|
||||||
|
public:
|
||||||
|
BuilderJsonArray();
|
||||||
|
BuilderJsonArray(JsonArray &json);
|
||||||
|
|
||||||
|
BuilderJsonArray *add(const QVariant &element);
|
||||||
|
BuilderJsonArray *add(BuilderJsonObject *builder);
|
||||||
|
BuilderJsonArray *add(BuilderJsonArray *builder);
|
||||||
|
JsonArray create();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static QQueue<BuilderJsonArray *> created_list;
|
||||||
|
|
||||||
|
JsonArray array;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create a BuilderJsonObject
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
BuilderJsonObject *objectBuilder();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create a BuilderJsonObject starting from copy of another json
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
BuilderJsonObject *objectBuilder(JsonObject &json);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create a BuilderJsonArray
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
BuilderJsonArray *arrayBuilder();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create a BuilderJsonArray starting from copy of another json
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
BuilderJsonArray *arrayBuilder(JsonArray &json);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //JSON_H
|
|
@ -46,7 +46,7 @@ constexpr auto PERMISSIONHELPER_CLASS =
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
AndroidVpnProtocol::AndroidVpnProtocol(Protocol protocol, const QJsonObject &configuration, QObject* parent)
|
AndroidVpnProtocol::AndroidVpnProtocol(Proto protocol, const QJsonObject &configuration, QObject* parent)
|
||||||
: VpnProtocol(configuration, parent),
|
: VpnProtocol(configuration, parent),
|
||||||
m_protocol(protocol),
|
m_protocol(protocol),
|
||||||
m_binder(this)
|
m_binder(this)
|
||||||
|
|
|
@ -17,7 +17,7 @@ class AndroidVpnProtocol : public VpnProtocol,
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit AndroidVpnProtocol(Protocol protocol, const QJsonObject& configuration, QObject* parent = nullptr);
|
explicit AndroidVpnProtocol(Proto protocol, const QJsonObject& configuration, QObject* parent = nullptr);
|
||||||
static AndroidVpnProtocol* instance();
|
static AndroidVpnProtocol* instance();
|
||||||
|
|
||||||
virtual ~AndroidVpnProtocol() override = default;
|
virtual ~AndroidVpnProtocol() override = default;
|
||||||
|
@ -53,7 +53,7 @@ protected:
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Protocol m_protocol;
|
Proto m_protocol;
|
||||||
|
|
||||||
bool m_serviceConnected = false;
|
bool m_serviceConnected = false;
|
||||||
std::function<void(const QString&)> m_logCallback;
|
std::function<void(const QString&)> m_logCallback;
|
||||||
|
|
51
client/protocols/ios_vpnprotocol.h
Normal file
51
client/protocols/ios_vpnprotocol.h
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
#ifndef IOS_VPNPROTOCOL_H
|
||||||
|
#define IOS_VPNPROTOCOL_H
|
||||||
|
|
||||||
|
#include "vpnprotocol.h"
|
||||||
|
#include "protocols/protocols_defs.h"
|
||||||
|
|
||||||
|
using namespace amnezia;
|
||||||
|
|
||||||
|
|
||||||
|
class IOSVpnProtocol : public VpnProtocol
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit IOSVpnProtocol(amnezia::Proto proto, const QJsonObject& configuration, QObject* parent = nullptr);
|
||||||
|
static IOSVpnProtocol* instance();
|
||||||
|
|
||||||
|
virtual ~IOSVpnProtocol() = default;
|
||||||
|
|
||||||
|
bool initialize();
|
||||||
|
|
||||||
|
virtual ErrorCode start() override;
|
||||||
|
virtual void stop() override;
|
||||||
|
|
||||||
|
void resume_start();
|
||||||
|
|
||||||
|
void checkStatus();
|
||||||
|
|
||||||
|
void setNotificationText(const QString& title, const QString& message,
|
||||||
|
int timerSec);
|
||||||
|
void setFallbackConnectedNotification();
|
||||||
|
|
||||||
|
void getBackendLogs(std::function<void(const QString&)>&& callback);
|
||||||
|
|
||||||
|
void cleanupBackendLogs();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
private:
|
||||||
|
Proto m_protocol;
|
||||||
|
bool m_serviceConnected = false;
|
||||||
|
bool m_checkingStatus = false;
|
||||||
|
std::function<void(const QString&)> m_logCallback;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // IOS_VPNPROTOCOL_H
|
298
client/protocols/ios_vpnprotocol.mm
Normal file
298
client/protocols/ios_vpnprotocol.mm
Normal file
|
@ -0,0 +1,298 @@
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QHostAddress>
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#include <QRandomGenerator>
|
||||||
|
#include <QTextCodec>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QFile>
|
||||||
|
|
||||||
|
#include <QByteArray>
|
||||||
|
|
||||||
|
#include "json.h"
|
||||||
|
|
||||||
|
#include "ipaddressrange.h"
|
||||||
|
#include "ios_vpnprotocol.h"
|
||||||
|
#include "core/errorstrings.h"
|
||||||
|
#include "AmneziaVPN-Swift.h"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
IOSVpnProtocol* s_instance = nullptr;
|
||||||
|
IOSVpnProtocolImpl* m_controller = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOSVpnProtocol::IOSVpnProtocol(Proto proto, const QJsonObject &configuration, QObject* parent)
|
||||||
|
: VpnProtocol(configuration, parent),
|
||||||
|
m_protocol(proto) {}
|
||||||
|
|
||||||
|
IOSVpnProtocol* IOSVpnProtocol::instance() {
|
||||||
|
return s_instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IOSVpnProtocol::initialize()
|
||||||
|
{
|
||||||
|
qDebug() << "Initializing Swift Controller";
|
||||||
|
|
||||||
|
static bool creating = false;
|
||||||
|
// No nested creation!
|
||||||
|
Q_ASSERT(creating == false);
|
||||||
|
creating = true;
|
||||||
|
|
||||||
|
if (!m_controller) {
|
||||||
|
bool ok;
|
||||||
|
QtJson::JsonObject result = QtJson::parse(QJsonDocument(m_rawConfig).toJson(), ok).toMap();
|
||||||
|
|
||||||
|
if(!ok) {
|
||||||
|
qDebug() << QString("An error occurred during parsing");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString vpnProto = result["protocol"].toString();
|
||||||
|
qDebug() << "protocol: " << vpnProto;
|
||||||
|
qDebug() << "config data => ";
|
||||||
|
QtJson::JsonObject config = result["wireguard_config_data"].toMap();
|
||||||
|
|
||||||
|
QString privateKey = config["client_priv_key"].toString();
|
||||||
|
QByteArray key = QByteArray::fromBase64(privateKey.toLocal8Bit());
|
||||||
|
|
||||||
|
qDebug() << " - " << "client_priv_key: " << config["client_priv_key"].toString();
|
||||||
|
qDebug() << " - " << "client_pub_key: " << config["client_pub_key"].toString();
|
||||||
|
qDebug() << " - " << "interface config: " << config["config"].toString();
|
||||||
|
|
||||||
|
QString addr = config["config"].toString().split("\n").takeAt(1).split(" = ").takeLast();
|
||||||
|
QString dns = config["config"].toString().split("\n").takeAt(2).split(" = ").takeLast();
|
||||||
|
QString privkey = config["config"].toString().split("\n").takeAt(3).split(" = ").takeLast();
|
||||||
|
QString pubkey = config["config"].toString().split("\n").takeAt(6).split(" = ").takeLast();
|
||||||
|
QString presharedkey = config["config"].toString().split("\n").takeAt(7).split(" = ").takeLast();
|
||||||
|
QString allowedips = config["config"].toString().split("\n").takeAt(8).split(" = ").takeLast();
|
||||||
|
QString endpoint = config["config"].toString().split("\n").takeAt(9).split(" = ").takeLast();
|
||||||
|
QString keepalive = config["config"].toString().split("\n").takeAt(10).split(" = ").takeLast();
|
||||||
|
qDebug() << " - " << "[Interface] address: " << addr;
|
||||||
|
qDebug() << " - " << "[Interface] dns: " << dns;
|
||||||
|
qDebug() << " - " << "[Interface] private key: " << privkey;
|
||||||
|
qDebug() << " - " << "[Peer] public key: " << pubkey;
|
||||||
|
qDebug() << " - " << "[Peer] preshared key: " << presharedkey;
|
||||||
|
qDebug() << " - " << "[Peer] allowed ips: " << allowedips;
|
||||||
|
qDebug() << " - " << "[Peer] endpoint: " << endpoint;
|
||||||
|
qDebug() << " - " << "[Peer] keepalive: " << keepalive;
|
||||||
|
|
||||||
|
qDebug() << " - " << "hostName: " << config["hostName"].toString();
|
||||||
|
qDebug() << " - " << "psk_key: " << config["psk_key"].toString();
|
||||||
|
qDebug() << " - " << "server_pub_key: " << config["server_pub_key"].toString();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
m_controller = [[IOSVpnProtocolImpl alloc] initWithBundleID:@VPN_NE_BUNDLEID
|
||||||
|
privateKey:key.toNSData()
|
||||||
|
deviceIpv4Address:addr.toNSString()
|
||||||
|
deviceIpv6Address:@"::/0"
|
||||||
|
closure:^(ConnectionState state, NSDate* date) {
|
||||||
|
qDebug() << "Creation completed with connection state:" << state;
|
||||||
|
creating = false;
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case ConnectionStateError: {
|
||||||
|
[m_controller dealloc];
|
||||||
|
m_controller = nullptr;
|
||||||
|
emit initialized(false, false, QDateTime());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case ConnectionStateConnected: {
|
||||||
|
Q_ASSERT(date);
|
||||||
|
QDateTime qtDate(QDateTime::fromNSDate(date));
|
||||||
|
emit initialized(true, true, qtDate);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case ConnectionStateDisconnected:
|
||||||
|
// Just in case we are connecting, let's call disconnect.
|
||||||
|
[m_controller disconnect];
|
||||||
|
emit initialized(true, false, QDateTime());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callback:^(BOOL a_connected) {
|
||||||
|
qDebug() << "State changed: " << a_connected;
|
||||||
|
if (a_connected) {
|
||||||
|
emit isConnected();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit isDisconnected();
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorCode IOSVpnProtocol::start()
|
||||||
|
{
|
||||||
|
bool ok;
|
||||||
|
QtJson::JsonObject result = QtJson::parse(QJsonDocument(m_rawConfig).toJson(), ok).toMap();
|
||||||
|
|
||||||
|
if(!ok) {
|
||||||
|
qDebug() << QString("An error occurred during config parsing");
|
||||||
|
return InternalError;
|
||||||
|
}
|
||||||
|
QString protocol = result["protocol"].toString();
|
||||||
|
QtJson::JsonObject config = result["wireguard_config_data"].toMap();
|
||||||
|
|
||||||
|
QString clientPrivateKey = config["client_priv_key"].toString();
|
||||||
|
QByteArray key = QByteArray::fromBase64(clientPrivateKey.toLocal8Bit());
|
||||||
|
QString clientPubKey = config["client_pub_key"].toString();
|
||||||
|
|
||||||
|
QString addr = config["config"].toString().split("\n").takeAt(1).split(" = ").takeLast();
|
||||||
|
QStringList dnsServersList = config["config"].toString().split("\n").takeAt(2).split(" = ").takeLast().split(", ");
|
||||||
|
QString privkey = config["config"].toString().split("\n").takeAt(3).split(" = ").takeLast();
|
||||||
|
QString pubkey = config["config"].toString().split("\n").takeAt(6).split(" = ").takeLast();
|
||||||
|
QString presharedkey = config["config"].toString().split("\n").takeAt(7).split(" = ").takeLast();
|
||||||
|
QStringList allowedIPList = config["config"].toString().split("\n").takeAt(8).split(" = ").takeLast().split(", ");
|
||||||
|
QString endpoint = config["config"].toString().split("\n").takeAt(9).split(" = ").takeLast();
|
||||||
|
QString serverAddr = config["config"].toString().split("\n").takeAt(9).split(" = ").takeLast().split(":").takeFirst();
|
||||||
|
QString port = config["config"].toString().split("\n").takeAt(9).split(" = ").takeLast().split(":").takeLast();
|
||||||
|
QString keepalive = config["config"].toString().split("\n").takeAt(10).split(" = ").takeLast();
|
||||||
|
|
||||||
|
QString hostname = config["hostName"].toString();
|
||||||
|
QString pskKey = config["psk_key"].toString();
|
||||||
|
QString serverPubKey = config["server_pub_key"].toString();
|
||||||
|
|
||||||
|
qDebug() << "IOSVPNProtocol starts for" << hostname;
|
||||||
|
qDebug() << "DNS:" << dnsServersList.takeFirst().toNSString();
|
||||||
|
qDebug() << "serverPublicKey:" << serverPubKey.toNSString();
|
||||||
|
qDebug() << "serverIpv4AddrIn:" << serverAddr.toNSString();
|
||||||
|
qDebug() << "serverPort:" << (uint32_t)port.toInt();
|
||||||
|
qDebug() << "allowed ip list" << allowedIPList;
|
||||||
|
|
||||||
|
NSMutableArray<VPNIPAddressRange*>* allowedIPAddressRangesNS =
|
||||||
|
[NSMutableArray<VPNIPAddressRange*> arrayWithCapacity:allowedIPList.length()];
|
||||||
|
for (const IPAddressRange item : allowedIPList) {
|
||||||
|
VPNIPAddressRange* range =
|
||||||
|
[[VPNIPAddressRange alloc] initWithAddress:item.ipAddress().toNSString()
|
||||||
|
networkPrefixLength:item.range()
|
||||||
|
isIpv6:item.type() == IPAddressRange::IPv6];
|
||||||
|
[allowedIPAddressRangesNS addObject:[range autorelease]];
|
||||||
|
}
|
||||||
|
|
||||||
|
[m_controller connectWithDnsServer:dnsServersList.takeFirst().toNSString()
|
||||||
|
serverIpv6Gateway:@"FE80::1"
|
||||||
|
serverPublicKey:serverPubKey.toNSString()
|
||||||
|
serverIpv4AddrIn:serverAddr.toNSString()
|
||||||
|
serverPort:port.toInt()
|
||||||
|
allowedIPAddressRanges:allowedIPAddressRangesNS
|
||||||
|
ipv6Enabled:NO
|
||||||
|
reason:0
|
||||||
|
failureCallback:^() {
|
||||||
|
qDebug() << "IOSVPNProtocol - connection failed";
|
||||||
|
emit isDisconnected();
|
||||||
|
}];
|
||||||
|
return NoError;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOSVpnProtocol::stop()
|
||||||
|
{
|
||||||
|
if (!m_controller) {
|
||||||
|
qDebug() << "Not correctly initialized";
|
||||||
|
emit isDisconnected();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
[m_controller disconnect];
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOSVpnProtocol::resume_start()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOSVpnProtocol::checkStatus()
|
||||||
|
{
|
||||||
|
qDebug() << "Checking status";
|
||||||
|
|
||||||
|
if (m_checkingStatus) {
|
||||||
|
qDebug() << "We are still waiting for the previous status.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_controller) {
|
||||||
|
qDebug() << "Not correctly initialized";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_checkingStatus = true;
|
||||||
|
|
||||||
|
[m_controller checkStatusWithCallback:^(NSString* serverIpv4Gateway, NSString* deviceIpv4Address,
|
||||||
|
NSString* configString) {
|
||||||
|
QString config = QString::fromNSString(configString);
|
||||||
|
|
||||||
|
m_checkingStatus = false;
|
||||||
|
|
||||||
|
if (config.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t txBytes = 0;
|
||||||
|
uint64_t rxBytes = 0;
|
||||||
|
|
||||||
|
QStringList lines = config.split("\n");
|
||||||
|
for (const QString& line : lines) {
|
||||||
|
if (line.startsWith("tx_bytes=")) {
|
||||||
|
txBytes = line.split("=")[1].toULongLong();
|
||||||
|
} else if (line.startsWith("rx_bytes=")) {
|
||||||
|
rxBytes = line.split("=")[1].toULongLong();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (txBytes && rxBytes) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "ServerIpv4Gateway:" << QString::fromNSString(serverIpv4Gateway)
|
||||||
|
<< "DeviceIpv4Address:" << QString::fromNSString(deviceIpv4Address)
|
||||||
|
<< "RxBytes:" << rxBytes << "TxBytes:" << txBytes;
|
||||||
|
emit bytesChanged(rxBytes, txBytes);
|
||||||
|
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOSVpnProtocol::setNotificationText(const QString &title, const QString &message, int timerSec)
|
||||||
|
{
|
||||||
|
// TODO: add user notifications?
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOSVpnProtocol::setFallbackConnectedNotification()
|
||||||
|
{
|
||||||
|
// TODO: add default user notifications?
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOSVpnProtocol::getBackendLogs(std::function<void (const QString &)> &&callback)
|
||||||
|
{
|
||||||
|
std::function<void(const QString&)> a_callback = std::move(callback);
|
||||||
|
|
||||||
|
QString groupId(GROUP_ID);
|
||||||
|
NSURL* groupPath = [[NSFileManager defaultManager]
|
||||||
|
containerURLForSecurityApplicationGroupIdentifier:groupId.toNSString()];
|
||||||
|
|
||||||
|
NSURL* path = [groupPath URLByAppendingPathComponent:@"networkextension.log"];
|
||||||
|
|
||||||
|
QFile file(QString::fromNSString([path path]));
|
||||||
|
if (!file.open(QIODevice::ReadOnly)) {
|
||||||
|
a_callback("Network extension log file missing or unreadable.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray content = file.readAll();
|
||||||
|
a_callback(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IOSVpnProtocol::cleanupBackendLogs()
|
||||||
|
{
|
||||||
|
QString groupId(GROUP_ID);
|
||||||
|
NSURL* groupPath = [[NSFileManager defaultManager]
|
||||||
|
containerURLForSecurityApplicationGroupIdentifier:groupId.toNSString()];
|
||||||
|
|
||||||
|
NSURL* path = [groupPath URLByAppendingPathComponent:@"networkextension.log"];
|
||||||
|
|
||||||
|
QFile file(QString::fromNSString([path path]));
|
||||||
|
file.remove();
|
||||||
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
using namespace amnezia;
|
using namespace amnezia;
|
||||||
|
|
||||||
QDebug operator<<(QDebug debug, const amnezia::ProtocolEnumNS::Protocol &p)
|
QDebug operator<<(QDebug debug, const amnezia::ProtocolEnumNS::Proto &p)
|
||||||
{
|
{
|
||||||
QDebugStateSaver saver(debug);
|
QDebugStateSaver saver(debug);
|
||||||
debug.nospace() << ProtocolProps::protoToString(p);
|
debug.nospace() << ProtocolProps::protoToString(p);
|
||||||
|
@ -10,29 +10,29 @@ QDebug operator<<(QDebug debug, const amnezia::ProtocolEnumNS::Protocol &p)
|
||||||
return debug;
|
return debug;
|
||||||
}
|
}
|
||||||
|
|
||||||
amnezia::Protocol ProtocolProps::protoFromString(QString proto){
|
amnezia::Proto ProtocolProps::protoFromString(QString proto){
|
||||||
QMetaEnum metaEnum = QMetaEnum::fromType<Protocol>();
|
QMetaEnum metaEnum = QMetaEnum::fromType<Proto>();
|
||||||
for (int i = 0; i < metaEnum.keyCount(); ++i) {
|
for (int i = 0; i < metaEnum.keyCount(); ++i) {
|
||||||
Protocol p = static_cast<Protocol>(i);
|
Proto p = static_cast<Proto>(i);
|
||||||
if (proto == protoToString(p)) return p;
|
if (proto == protoToString(p)) return p;
|
||||||
}
|
}
|
||||||
return Protocol::Any;
|
return Proto::Any;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ProtocolProps::protoToString(amnezia::Protocol p){
|
QString ProtocolProps::protoToString(amnezia::Proto p){
|
||||||
if (p == Protocol::Any) return "";
|
if (p == Proto::Any) return "";
|
||||||
|
|
||||||
QMetaEnum metaEnum = QMetaEnum::fromType<Protocol>();
|
QMetaEnum metaEnum = QMetaEnum::fromType<Proto>();
|
||||||
QString protoKey = metaEnum.valueToKey(static_cast<int>(p));
|
QString protoKey = metaEnum.valueToKey(static_cast<int>(p));
|
||||||
return protoKey.toLower();
|
return protoKey.toLower();
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<amnezia::Protocol> ProtocolProps::allProtocols()
|
QList<amnezia::Proto> ProtocolProps::allProtocols()
|
||||||
{
|
{
|
||||||
QMetaEnum metaEnum = QMetaEnum::fromType<Protocol>();
|
QMetaEnum metaEnum = QMetaEnum::fromType<Proto>();
|
||||||
QList<Protocol> all;
|
QList<Proto> all;
|
||||||
for (int i = 0; i < metaEnum.keyCount(); ++i) {
|
for (int i = 0; i < metaEnum.keyCount(); ++i) {
|
||||||
all.append(static_cast<Protocol>(i));
|
all.append(static_cast<Proto>(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
return all;
|
return all;
|
||||||
|
@ -48,7 +48,7 @@ TransportProto ProtocolProps::transportProtoFromString(QString p)
|
||||||
return TransportProto::Udp;
|
return TransportProto::Udp;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ProtocolProps::transportProtoToString(TransportProto proto, Protocol p)
|
QString ProtocolProps::transportProtoToString(TransportProto proto, Proto p)
|
||||||
{
|
{
|
||||||
QMetaEnum metaEnum = QMetaEnum::fromType<TransportProto>();
|
QMetaEnum metaEnum = QMetaEnum::fromType<TransportProto>();
|
||||||
QString protoKey = metaEnum.valueToKey(static_cast<int>(proto));
|
QString protoKey = metaEnum.valueToKey(static_cast<int>(proto));
|
||||||
|
@ -66,124 +66,124 @@ QString ProtocolProps::transportProtoToString(TransportProto proto, Protocol p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QMap<amnezia::Protocol, QString> ProtocolProps::protocolHumanNames()
|
QMap<amnezia::Proto, QString> ProtocolProps::protocolHumanNames()
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
{Protocol::OpenVpn, "OpenVPN"},
|
{Proto::OpenVpn, "OpenVPN"},
|
||||||
{Protocol::ShadowSocks, "ShadowSocks"},
|
{Proto::ShadowSocks, "ShadowSocks"},
|
||||||
{Protocol::Cloak, "Cloak"},
|
{Proto::Cloak, "Cloak"},
|
||||||
{Protocol::WireGuard, "WireGuard"},
|
{Proto::WireGuard, "WireGuard"},
|
||||||
{Protocol::Ikev2, "IKEv2"},
|
{Proto::Ikev2, "IKEv2"},
|
||||||
{Protocol::L2tp, "L2TP"},
|
{Proto::L2tp, "L2TP"},
|
||||||
|
|
||||||
{Protocol::TorWebSite, "Web site in TOR network"},
|
{Proto::TorWebSite, "Web site in TOR network"},
|
||||||
{Protocol::Dns, "DNS Service"},
|
{Proto::Dns, "DNS Service"},
|
||||||
{Protocol::FileShare, "File Sharing Service"},
|
{Proto::FileShare, "File Sharing Service"},
|
||||||
{Protocol::Sftp, QObject::tr("Sftp service")}
|
{Proto::Sftp, QObject::tr("Sftp service")}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
QMap<amnezia::Protocol, QString> ProtocolProps::protocolDescriptions()
|
QMap<amnezia::Proto, QString> ProtocolProps::protocolDescriptions()
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
amnezia::ServiceType ProtocolProps::protocolService(Protocol p)
|
amnezia::ServiceType ProtocolProps::protocolService(Proto p)
|
||||||
{
|
{
|
||||||
switch (p) {
|
switch (p) {
|
||||||
case Protocol::Any : return ServiceType::None;
|
case Proto::Any : return ServiceType::None;
|
||||||
case Protocol::OpenVpn : return ServiceType::Vpn;
|
case Proto::OpenVpn : return ServiceType::Vpn;
|
||||||
case Protocol::Cloak : return ServiceType::Vpn;
|
case Proto::Cloak : return ServiceType::Vpn;
|
||||||
case Protocol::ShadowSocks : return ServiceType::Vpn;
|
case Proto::ShadowSocks : return ServiceType::Vpn;
|
||||||
case Protocol::WireGuard : return ServiceType::Vpn;
|
case Proto::WireGuard : return ServiceType::Vpn;
|
||||||
case Protocol::TorWebSite : return ServiceType::Other;
|
case Proto::TorWebSite : return ServiceType::Other;
|
||||||
case Protocol::Dns : return ServiceType::Other;
|
case Proto::Dns : return ServiceType::Other;
|
||||||
case Protocol::FileShare : return ServiceType::Other;
|
case Proto::FileShare : return ServiceType::Other;
|
||||||
default: return ServiceType::Other;
|
default: return ServiceType::Other;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ProtocolProps::defaultPort(Protocol p)
|
int ProtocolProps::defaultPort(Proto p)
|
||||||
{
|
{
|
||||||
switch (p) {
|
switch (p) {
|
||||||
case Protocol::Any : return -1;
|
case Proto::Any : return -1;
|
||||||
case Protocol::OpenVpn : return 1194;
|
case Proto::OpenVpn : return 1194;
|
||||||
case Protocol::Cloak : return 443;
|
case Proto::Cloak : return 443;
|
||||||
case Protocol::ShadowSocks : return 6789;
|
case Proto::ShadowSocks : return 6789;
|
||||||
case Protocol::WireGuard : return 51820;
|
case Proto::WireGuard : return 51820;
|
||||||
case Protocol::Ikev2 : return -1;
|
case Proto::Ikev2 : return -1;
|
||||||
case Protocol::L2tp : return -1;
|
case Proto::L2tp : return -1;
|
||||||
|
|
||||||
case Protocol::TorWebSite : return -1;
|
case Proto::TorWebSite : return -1;
|
||||||
case Protocol::Dns : return 53;
|
case Proto::Dns : return 53;
|
||||||
case Protocol::FileShare : return 139;
|
case Proto::FileShare : return 139;
|
||||||
case Protocol::Sftp : return 222;
|
case Proto::Sftp : return 222;
|
||||||
default: return -1;
|
default: return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProtocolProps::defaultPortChangeable(Protocol p)
|
bool ProtocolProps::defaultPortChangeable(Proto p)
|
||||||
{
|
{
|
||||||
switch (p) {
|
switch (p) {
|
||||||
case Protocol::Any : return false;
|
case Proto::Any : return false;
|
||||||
case Protocol::OpenVpn : return true;
|
case Proto::OpenVpn : return true;
|
||||||
case Protocol::Cloak : return true;
|
case Proto::Cloak : return true;
|
||||||
case Protocol::ShadowSocks : return true;
|
case Proto::ShadowSocks : return true;
|
||||||
case Protocol::WireGuard : return true;
|
case Proto::WireGuard : return true;
|
||||||
case Protocol::Ikev2 : return false;
|
case Proto::Ikev2 : return false;
|
||||||
case Protocol::L2tp : return false;
|
case Proto::L2tp : return false;
|
||||||
|
|
||||||
|
|
||||||
case Protocol::TorWebSite : return true;
|
case Proto::TorWebSite : return true;
|
||||||
case Protocol::Dns : return false;
|
case Proto::Dns : return false;
|
||||||
case Protocol::FileShare : return false;
|
case Proto::FileShare : return false;
|
||||||
default: return -1;
|
default: return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TransportProto ProtocolProps::defaultTransportProto(Protocol p)
|
TransportProto ProtocolProps::defaultTransportProto(Proto p)
|
||||||
{
|
{
|
||||||
switch (p) {
|
switch (p) {
|
||||||
case Protocol::Any : return TransportProto::Udp;
|
case Proto::Any : return TransportProto::Udp;
|
||||||
case Protocol::OpenVpn : return TransportProto::Udp;
|
case Proto::OpenVpn : return TransportProto::Udp;
|
||||||
case Protocol::Cloak : return TransportProto::Tcp;
|
case Proto::Cloak : return TransportProto::Tcp;
|
||||||
case Protocol::ShadowSocks : return TransportProto::Tcp;
|
case Proto::ShadowSocks : return TransportProto::Tcp;
|
||||||
case Protocol::WireGuard : return TransportProto::Udp;
|
case Proto::WireGuard : return TransportProto::Udp;
|
||||||
case Protocol::Ikev2 : return TransportProto::Udp;
|
case Proto::Ikev2 : return TransportProto::Udp;
|
||||||
case Protocol::L2tp : return TransportProto::Udp;
|
case Proto::L2tp : return TransportProto::Udp;
|
||||||
// non-vpn
|
// non-vpn
|
||||||
case Protocol::TorWebSite : return TransportProto::Tcp;
|
case Proto::TorWebSite : return TransportProto::Tcp;
|
||||||
case Protocol::Dns : return TransportProto::Udp;
|
case Proto::Dns : return TransportProto::Udp;
|
||||||
case Protocol::FileShare : return TransportProto::Udp;
|
case Proto::FileShare : return TransportProto::Udp;
|
||||||
case Protocol::Sftp : return TransportProto::Tcp;
|
case Proto::Sftp : return TransportProto::Tcp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProtocolProps::defaultTransportProtoChangeable(Protocol p)
|
bool ProtocolProps::defaultTransportProtoChangeable(Proto p)
|
||||||
{
|
{
|
||||||
switch (p) {
|
switch (p) {
|
||||||
case Protocol::Any : return false;
|
case Proto::Any : return false;
|
||||||
case Protocol::OpenVpn : return true;
|
case Proto::OpenVpn : return true;
|
||||||
case Protocol::Cloak : return false;
|
case Proto::Cloak : return false;
|
||||||
case Protocol::ShadowSocks : return false;
|
case Proto::ShadowSocks : return false;
|
||||||
case Protocol::WireGuard : return false;
|
case Proto::WireGuard : return false;
|
||||||
case Protocol::Ikev2 : return false;
|
case Proto::Ikev2 : return false;
|
||||||
case Protocol::L2tp : return false;
|
case Proto::L2tp : return false;
|
||||||
// non-vpn
|
// non-vpn
|
||||||
case Protocol::TorWebSite : return false;
|
case Proto::TorWebSite : return false;
|
||||||
case Protocol::Dns : return false;
|
case Proto::Dns : return false;
|
||||||
case Protocol::FileShare : return false;
|
case Proto::FileShare : return false;
|
||||||
case Protocol::Sftp : return false;
|
case Proto::Sftp : return false;
|
||||||
default: return false;
|
default: return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ProtocolProps::key_proto_config_data(Protocol p)
|
QString ProtocolProps::key_proto_config_data(Proto p)
|
||||||
{
|
{
|
||||||
return protoToString(p) + "_config_data";
|
return protoToString(p) + "_config_data";
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ProtocolProps::key_proto_config_path(Protocol p)
|
QString ProtocolProps::key_proto_config_path(Proto p)
|
||||||
{
|
{
|
||||||
return protoToString(p) + "_config_path";
|
return protoToString(p) + "_config_path";
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ constexpr char containers[] = "containers";
|
||||||
constexpr char container[] = "container";
|
constexpr char container[] = "container";
|
||||||
constexpr char defaultContainer[] = "defaultContainer";
|
constexpr char defaultContainer[] = "defaultContainer";
|
||||||
|
|
||||||
constexpr char protocol[] = "protocol";
|
constexpr char vpnproto[] = "protocol";
|
||||||
constexpr char protocols[] = "protocols";
|
constexpr char protocols[] = "protocols";
|
||||||
|
|
||||||
constexpr char remote[] = "remote";
|
constexpr char remote[] = "remote";
|
||||||
|
@ -121,7 +121,7 @@ enum TransportProto {
|
||||||
};
|
};
|
||||||
Q_ENUM_NS(TransportProto)
|
Q_ENUM_NS(TransportProto)
|
||||||
|
|
||||||
enum Protocol {
|
enum Proto {
|
||||||
Any = 0,
|
Any = 0,
|
||||||
OpenVpn,
|
OpenVpn,
|
||||||
ShadowSocks,
|
ShadowSocks,
|
||||||
|
@ -136,7 +136,7 @@ enum Protocol {
|
||||||
FileShare,
|
FileShare,
|
||||||
Sftp
|
Sftp
|
||||||
};
|
};
|
||||||
Q_ENUM_NS(Protocol)
|
Q_ENUM_NS(Proto)
|
||||||
|
|
||||||
enum ServiceType {
|
enum ServiceType {
|
||||||
None = 0,
|
None = 0,
|
||||||
|
@ -153,29 +153,29 @@ class ProtocolProps : public QObject
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Q_INVOKABLE static QList<Protocol> allProtocols();
|
Q_INVOKABLE static QList<Proto> allProtocols();
|
||||||
|
|
||||||
// spelling may differ for various protocols - TCP for OpenVPN, tcp for others
|
// spelling may differ for various protocols - TCP for OpenVPN, tcp for others
|
||||||
Q_INVOKABLE static TransportProto transportProtoFromString(QString p);
|
Q_INVOKABLE static TransportProto transportProtoFromString(QString p);
|
||||||
Q_INVOKABLE static QString transportProtoToString(TransportProto proto, Protocol p = Protocol::Any);
|
Q_INVOKABLE static QString transportProtoToString(TransportProto proto, Proto p = Proto::Any);
|
||||||
|
|
||||||
Q_INVOKABLE static Protocol protoFromString(QString p);
|
Q_INVOKABLE static Proto protoFromString(QString p);
|
||||||
Q_INVOKABLE static QString protoToString(Protocol p);
|
Q_INVOKABLE static QString protoToString(Proto p);
|
||||||
|
|
||||||
Q_INVOKABLE static QMap<Protocol, QString> protocolHumanNames();
|
Q_INVOKABLE static QMap<Proto, QString> protocolHumanNames();
|
||||||
Q_INVOKABLE static QMap<Protocol, QString> protocolDescriptions();
|
Q_INVOKABLE static QMap<Proto, QString> protocolDescriptions();
|
||||||
|
|
||||||
Q_INVOKABLE static ServiceType protocolService(Protocol p);
|
Q_INVOKABLE static ServiceType protocolService(Proto p);
|
||||||
|
|
||||||
Q_INVOKABLE static int defaultPort(Protocol p);
|
Q_INVOKABLE static int defaultPort(Proto p);
|
||||||
Q_INVOKABLE static bool defaultPortChangeable(Protocol p);
|
Q_INVOKABLE static bool defaultPortChangeable(Proto p);
|
||||||
|
|
||||||
Q_INVOKABLE static TransportProto defaultTransportProto(Protocol p);
|
Q_INVOKABLE static TransportProto defaultTransportProto(Proto p);
|
||||||
Q_INVOKABLE static bool defaultTransportProtoChangeable(Protocol p);
|
Q_INVOKABLE static bool defaultTransportProtoChangeable(Proto p);
|
||||||
|
|
||||||
|
|
||||||
Q_INVOKABLE static QString key_proto_config_data(Protocol p);
|
Q_INVOKABLE static QString key_proto_config_data(Proto p);
|
||||||
Q_INVOKABLE static QString key_proto_config_path(Protocol p);
|
Q_INVOKABLE static QString key_proto_config_path(Proto p);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -207,6 +207,6 @@ static void declareQmlProtocolEnum() {
|
||||||
|
|
||||||
} // namespace amnezia
|
} // namespace amnezia
|
||||||
|
|
||||||
QDebug operator<<(QDebug debug, const amnezia::Protocol &p);
|
QDebug operator<<(QDebug debug, const amnezia::Proto &p);
|
||||||
|
|
||||||
#endif // PROTOCOLS_DEFS_H
|
#endif // PROTOCOLS_DEFS_H
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
VpnProtocol::VpnProtocol(const QJsonObject &configuration, QObject* parent)
|
VpnProtocol::VpnProtocol(const QJsonObject &configuration, QObject* parent)
|
||||||
: QObject(parent),
|
: QObject(parent),
|
||||||
m_connectionState(ConnectionState::Unknown),
|
m_connectionState(VpnConnectionState::Unknown),
|
||||||
m_rawConfig(configuration),
|
m_rawConfig(configuration),
|
||||||
m_timeoutTimer(new QTimer(this)),
|
m_timeoutTimer(new QTimer(this)),
|
||||||
m_receivedBytes(0),
|
m_receivedBytes(0),
|
||||||
|
@ -29,7 +29,7 @@ void VpnProtocol::setLastError(ErrorCode lastError)
|
||||||
{
|
{
|
||||||
m_lastError = lastError;
|
m_lastError = lastError;
|
||||||
if (lastError){
|
if (lastError){
|
||||||
setConnectionState(ConnectionState::Error);
|
setConnectionState(VpnConnectionState::Error);
|
||||||
}
|
}
|
||||||
qCritical().noquote() << "VpnProtocol error, code" << m_lastError << errorString(m_lastError);
|
qCritical().noquote() << "VpnProtocol error, code" << m_lastError << errorString(m_lastError);
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ void VpnProtocol::stopTimeoutTimer()
|
||||||
m_timeoutTimer->stop();
|
m_timeoutTimer->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
VpnProtocol::ConnectionState VpnProtocol::connectionState() const
|
VpnProtocol::VpnConnectionState VpnProtocol::connectionState() const
|
||||||
{
|
{
|
||||||
return m_connectionState;
|
return m_connectionState;
|
||||||
}
|
}
|
||||||
|
@ -70,19 +70,19 @@ void VpnProtocol::setBytesChanged(quint64 receivedBytes, quint64 sentBytes)
|
||||||
m_sentBytes = sentBytes;
|
m_sentBytes = sentBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VpnProtocol::setConnectionState(VpnProtocol::ConnectionState state)
|
void VpnProtocol::setConnectionState(VpnProtocol::VpnConnectionState state)
|
||||||
{
|
{
|
||||||
qDebug() << "VpnProtocol::setConnectionState" << textConnectionState(state);
|
qDebug() << "VpnProtocol::setConnectionState" << textConnectionState(state);
|
||||||
|
|
||||||
if (m_connectionState == state) {
|
if (m_connectionState == state) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (m_connectionState == ConnectionState::Disconnected && state == ConnectionState::Disconnecting) {
|
if (m_connectionState == VpnConnectionState::Disconnected && state == VpnConnectionState::Disconnecting) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_connectionState = state;
|
m_connectionState = state;
|
||||||
if (m_connectionState == ConnectionState::Disconnected) {
|
if (m_connectionState == VpnConnectionState::Disconnected) {
|
||||||
m_receivedBytes = 0;
|
m_receivedBytes = 0;
|
||||||
m_sentBytes = 0;
|
m_sentBytes = 0;
|
||||||
}
|
}
|
||||||
|
@ -116,17 +116,17 @@ QString VpnProtocol::routeGateway() const
|
||||||
return m_routeGateway;
|
return m_routeGateway;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString VpnProtocol::textConnectionState(ConnectionState connectionState)
|
QString VpnProtocol::textConnectionState(VpnConnectionState connectionState)
|
||||||
{
|
{
|
||||||
switch (connectionState) {
|
switch (connectionState) {
|
||||||
case ConnectionState::Unknown: return tr("Unknown");
|
case VpnConnectionState::Unknown: return tr("Unknown");
|
||||||
case ConnectionState::Disconnected: return tr("Disconnected");
|
case VpnConnectionState::Disconnected: return tr("Disconnected");
|
||||||
case ConnectionState::Preparing: return tr("Preparing");
|
case VpnConnectionState::Preparing: return tr("Preparing");
|
||||||
case ConnectionState::Connecting: return tr("Connecting...");
|
case VpnConnectionState::Connecting: return tr("Connecting...");
|
||||||
case ConnectionState::Connected: return tr("Connected");
|
case VpnConnectionState::Connected: return tr("Connected");
|
||||||
case ConnectionState::Disconnecting: return tr("Disconnecting...");
|
case VpnConnectionState::Disconnecting: return tr("Disconnecting...");
|
||||||
case ConnectionState::Reconnecting: return tr("Reconnecting...");
|
case VpnConnectionState::Reconnecting: return tr("Reconnecting...");
|
||||||
case ConnectionState::Error: return tr("Error");
|
case VpnConnectionState::Error: return tr("Error");
|
||||||
default:
|
default:
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
@ -141,10 +141,10 @@ QString VpnProtocol::textConnectionState() const
|
||||||
|
|
||||||
bool VpnProtocol::isConnected() const
|
bool VpnProtocol::isConnected() const
|
||||||
{
|
{
|
||||||
return m_connectionState == ConnectionState::Connected;
|
return m_connectionState == VpnConnectionState::Connected;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VpnProtocol::isDisconnected() const
|
bool VpnProtocol::isDisconnected() const
|
||||||
{
|
{
|
||||||
return m_connectionState == ConnectionState::Disconnected;
|
return m_connectionState == VpnConnectionState::Disconnected;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,10 +20,10 @@ public:
|
||||||
explicit VpnProtocol(const QJsonObject& configuration, QObject* parent = nullptr);
|
explicit VpnProtocol(const QJsonObject& configuration, QObject* parent = nullptr);
|
||||||
virtual ~VpnProtocol() override = default;
|
virtual ~VpnProtocol() override = default;
|
||||||
|
|
||||||
enum ConnectionState {Unknown, Disconnected, Preparing, Connecting, Connected, Disconnecting, Reconnecting, Error};
|
enum VpnConnectionState {Unknown, Disconnected, Preparing, Connecting, Connected, Disconnecting, Reconnecting, Error};
|
||||||
Q_ENUM(ConnectionState)
|
Q_ENUM(VpnConnectionState)
|
||||||
|
|
||||||
static QString textConnectionState(ConnectionState connectionState);
|
static QString textConnectionState(VpnConnectionState connectionState);
|
||||||
|
|
||||||
virtual ErrorCode prepare() { return ErrorCode::NoError; }
|
virtual ErrorCode prepare() { return ErrorCode::NoError; }
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ public:
|
||||||
virtual ErrorCode start() = 0;
|
virtual ErrorCode start() = 0;
|
||||||
virtual void stop() = 0;
|
virtual void stop() = 0;
|
||||||
|
|
||||||
ConnectionState connectionState() const;
|
VpnConnectionState connectionState() const;
|
||||||
ErrorCode lastError() const;
|
ErrorCode lastError() const;
|
||||||
QString textConnectionState() const;
|
QString textConnectionState() const;
|
||||||
void setLastError(ErrorCode lastError);
|
void setLastError(ErrorCode lastError);
|
||||||
|
@ -44,7 +44,7 @@ public:
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void bytesChanged(quint64 receivedBytes, quint64 sentBytes);
|
void bytesChanged(quint64 receivedBytes, quint64 sentBytes);
|
||||||
void connectionStateChanged(VpnProtocol::ConnectionState state);
|
void connectionStateChanged(VpnProtocol::VpnConnectionState state);
|
||||||
void timeoutTimerEvent();
|
void timeoutTimerEvent();
|
||||||
void protocolError(amnezia::ErrorCode e);
|
void protocolError(amnezia::ErrorCode e);
|
||||||
|
|
||||||
|
@ -63,9 +63,9 @@ protected:
|
||||||
void stopTimeoutTimer();
|
void stopTimeoutTimer();
|
||||||
|
|
||||||
virtual void setBytesChanged(quint64 receivedBytes, quint64 sentBytes);
|
virtual void setBytesChanged(quint64 receivedBytes, quint64 sentBytes);
|
||||||
virtual void setConnectionState(VpnProtocol::ConnectionState state);
|
virtual void setConnectionState(VpnProtocol::VpnConnectionState state);
|
||||||
|
|
||||||
ConnectionState m_connectionState;
|
VpnConnectionState m_connectionState;
|
||||||
QString m_routeGateway;
|
QString m_routeGateway;
|
||||||
QString m_vpnLocalAddress;
|
QString m_vpnLocalAddress;
|
||||||
QString m_vpnGateway;
|
QString m_vpnGateway;
|
||||||
|
|
51
client/scripts/commons.sh
Normal file
51
client/scripts/commons.sh
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
printv() {
|
||||||
|
if [ -t 1 ]; then
|
||||||
|
NCOLORS=$(tput colors)
|
||||||
|
|
||||||
|
if test -n "$NCOLORS" && test "$NCOLORS" -ge 8; then
|
||||||
|
NORMAL="$(tput sgr0)"
|
||||||
|
RED="$(tput setaf 1)"
|
||||||
|
GREEN="$(tput setaf 2)"
|
||||||
|
YELLOW="$(tput setaf 3)"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $2 = 'G' ]]; then
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
echo $1 -e "${GREEN}$3${NORMAL}"
|
||||||
|
elif [[ $2 = 'Y' ]]; then
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
echo $1 -e "${YELLOW}$3${NORMAL}"
|
||||||
|
elif [[ $2 = 'N' ]]; then
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
echo $1 -e "$3"
|
||||||
|
else
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
echo $1 -e "${RED}$3${NORMAL}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
print() {
|
||||||
|
printv '' "$1" "$2"
|
||||||
|
}
|
||||||
|
|
||||||
|
printn() {
|
||||||
|
printv "-n" "$1" "$2"
|
||||||
|
}
|
||||||
|
|
||||||
|
error() {
|
||||||
|
printv '' R "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
die() {
|
||||||
|
if [[ "$1" ]]; then
|
||||||
|
error "$1"
|
||||||
|
else
|
||||||
|
error Failed
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
227
client/scripts/ios_compile.sh
Executable file
227
client/scripts/ios_compile.sh
Executable file
|
@ -0,0 +1,227 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
|
||||||
|
. $(dirname $0)/commons.sh
|
||||||
|
|
||||||
|
if [ -f .env ]; then
|
||||||
|
. .env
|
||||||
|
fi
|
||||||
|
|
||||||
|
RELEASE=1
|
||||||
|
OS=
|
||||||
|
NETWORKEXTENSION=
|
||||||
|
ADJUST_SDK_TOKEN=
|
||||||
|
ADJUST="CONFIG-=adjust"
|
||||||
|
|
||||||
|
helpFunction() {
|
||||||
|
print G "Usage:"
|
||||||
|
print N "\t$0 <ios> [-d|--debug] [-n|--networkextension] [-a|--adjusttoken <adjust_token>]"
|
||||||
|
print N ""
|
||||||
|
print N "By default, the project is compiled in release mode. Use -d or --debug for a debug build."
|
||||||
|
print N "Use -n or --networkextension to force the network-extension component for MacOS too."
|
||||||
|
print N ""
|
||||||
|
print N "If MVPN_IOS_ADJUST_TOKEN env is found, this will be used at compilation time."
|
||||||
|
print N ""
|
||||||
|
print G "Config variables:"
|
||||||
|
print N "\tQT_MACOS_BIN=</path/of/the/qt/bin/folder/for/macos>"
|
||||||
|
print N "\tQT_IOS_BIN=</path/of/the/qt/bin/folder/for/ios>"
|
||||||
|
print N "\tMVPN_IOS_ADJUST_TOKEN=<token>"
|
||||||
|
print N ""
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
print N "This script compiles AmneziaVPN for MacOS/iOS"
|
||||||
|
print N ""
|
||||||
|
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
key="$1"
|
||||||
|
|
||||||
|
case $key in
|
||||||
|
-a | --adjusttoken)
|
||||||
|
ADJUST_SDK_TOKEN="$2"
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-d | --debug)
|
||||||
|
RELEASE=
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-n | --networkextension)
|
||||||
|
NETWORKEXTENSION=1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-h | --help)
|
||||||
|
helpFunction
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
if [[ "$OS" ]]; then
|
||||||
|
helpFunction
|
||||||
|
fi
|
||||||
|
|
||||||
|
OS=$1
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
fetch() {
|
||||||
|
if command -v "wget" &>/dev/null; then
|
||||||
|
wget -nc -O "$2" "$1"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v "curl" &>/dev/null; then
|
||||||
|
curl "$1" -o "$2" -s -L
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
die "You must have 'wget' or 'curl' installed."
|
||||||
|
}
|
||||||
|
|
||||||
|
sha256() {
|
||||||
|
if command -v "sha256sum" &>/dev/null; then
|
||||||
|
sha256sum "$1"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v "openssl" &>/dev/null; then
|
||||||
|
openssl dgst -sha256 "$1"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
die "You must have 'sha256sum' or 'openssl' installed."
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ "$OS" != "macos" ]] && [[ "$OS" != "ios" ]] && [[ "$OS" != "macostest" ]]; then
|
||||||
|
helpFunction
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! [[ "$ADJUST_SDK_TOKEN" ]] && [[ "$MVPN_IOS_ADJUST_TOKEN" ]]; then
|
||||||
|
print Y "Using the MVPN_IOS_ADJUST_TOKEN value for the adjust token"
|
||||||
|
ADJUST_SDK_TOKEN=$MVPN_IOS_ADJUST_TOKEN
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$OS" == "ios" ]]; then
|
||||||
|
# Network-extension is the default for IOS
|
||||||
|
NETWORKEXTENSION=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! [ -d "ios" ] || ! [ -d "macos" ]; then
|
||||||
|
die "This script must be executed at the root of the repository."
|
||||||
|
fi
|
||||||
|
|
||||||
|
QMAKE=qmake
|
||||||
|
if [ "$OS" = "macos" ] && ! [ "$QT_MACOS_BIN" = "" ]; then
|
||||||
|
QMAKE=$QT_MACOS_BIN/qmake
|
||||||
|
elif [ "$OS" = "macostest" ] && ! [ "$QT_MACOS_BIN" = "" ]; then
|
||||||
|
QMAKE=$QT_MACOS_BIN/qmake
|
||||||
|
elif [ "$OS" = "ios" ] && ! [ "$QT_IOS_BIN" = "" ]; then
|
||||||
|
QMAKE=$QT_IOS_BIN/qmake
|
||||||
|
fi
|
||||||
|
|
||||||
|
$QMAKE -v &>/dev/null || die "qmake doesn't exist or it fails"
|
||||||
|
|
||||||
|
printn Y "Retrieve the wireguard-go version... "
|
||||||
|
(cd macos/gobridge && go list -m golang.zx2c4.com/wireguard | sed -n 's/.*v\([0-9.]*\).*/#define WIREGUARD_GO_VERSION "\1"/p') > macos/gobridge/wireguard-go-version.h
|
||||||
|
print G "done."
|
||||||
|
|
||||||
|
printn Y "Cleaning the existing project... "
|
||||||
|
rm -rf mozillavpn.xcodeproj/ || die "Failed to remove things"
|
||||||
|
print G "done."
|
||||||
|
|
||||||
|
#print Y "Importing translation files..."
|
||||||
|
#git submodule update --remote --depth 1 i18n || die "Failed to fetch newest translation files"
|
||||||
|
#python scripts/importLanguages.py $([[ "$OS" = "macos" ]] && echo "-m" || echo "") || die "Failed to import languages"
|
||||||
|
#
|
||||||
|
#print Y "Generating glean samples..."
|
||||||
|
#python scripts/generate_glean.py || die "Failed to generate glean samples"
|
||||||
|
|
||||||
|
printn Y "Extract the project version... "
|
||||||
|
SHORTVERSION=$(cat version.pri | grep VERSION | grep defined | cut -d= -f2 | tr -d \ )
|
||||||
|
FULLVERSION=$(echo $SHORTVERSION | cut -d. -f1).$(date +"%Y%m%d%H%M")
|
||||||
|
print G "$SHORTVERSION - $FULLVERSION"
|
||||||
|
|
||||||
|
MACOS_FLAGS="
|
||||||
|
QTPLUGIN+=qsvg
|
||||||
|
CONFIG-=static
|
||||||
|
CONFIG+=balrog
|
||||||
|
MVPN_MACOS=1
|
||||||
|
"
|
||||||
|
|
||||||
|
MACOSTEST_FLAGS="
|
||||||
|
QTPLUGIN+=qsvg
|
||||||
|
CONFIG-=static
|
||||||
|
CONFIG+=DUMMY
|
||||||
|
"
|
||||||
|
|
||||||
|
IOS_FLAGS="
|
||||||
|
MVPN_IOS=1
|
||||||
|
Q_OS_IOS=1
|
||||||
|
"
|
||||||
|
|
||||||
|
#printn Y "Mode: "
|
||||||
|
#if [[ "$RELEASE" ]]; then
|
||||||
|
# print G "release"
|
||||||
|
# MODE="CONFIG-=debug CONFIG+=release CONFIG-=debug_and_release"
|
||||||
|
#else
|
||||||
|
# print G "debug"
|
||||||
|
# MODE="CONFIG+=debug CONFIG-=release CONFIG-=debug_and_release"
|
||||||
|
#fi
|
||||||
|
MODE="CONFIG-=debug CONFIG+=release CONFIG-=debug_and_release"
|
||||||
|
|
||||||
|
OSRUBY=$OS
|
||||||
|
printn Y "OS: "
|
||||||
|
print G "$OS"
|
||||||
|
if [ "$OS" = "macos" ]; then
|
||||||
|
PLATFORM=$MACOS_FLAGS
|
||||||
|
elif [ "$OS" = "macostest" ]; then
|
||||||
|
OSRUBY=macos
|
||||||
|
PLATFORM=$MACOSTEST_FLAGS
|
||||||
|
elif [ "$OS" = "ios" ]; then
|
||||||
|
PLATFORM=$IOS_FLAGS
|
||||||
|
if [[ "$ADJUST_SDK_TOKEN" ]]; then
|
||||||
|
printn Y "ADJUST_SDK_TOKEN: "
|
||||||
|
print G "$ADJUST_SDK_TOKEN"
|
||||||
|
ADJUST="CONFIG+=adjust"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
die "Why we are here?"
|
||||||
|
fi
|
||||||
|
|
||||||
|
VPNMODE=
|
||||||
|
printn Y "VPN mode: "
|
||||||
|
if [[ "$NETWORKEXTENSION" ]]; then
|
||||||
|
print G network-extension
|
||||||
|
VPNMODE="CONFIG+=networkextension"
|
||||||
|
else
|
||||||
|
print G daemon
|
||||||
|
fi
|
||||||
|
|
||||||
|
printn Y "Web-Extension: "
|
||||||
|
WEMODE=
|
||||||
|
if [ "$OS" = "macos" ]; then
|
||||||
|
print G web-extension
|
||||||
|
WEMODE="CONFIG+=webextension"
|
||||||
|
else
|
||||||
|
print G none
|
||||||
|
fi
|
||||||
|
|
||||||
|
print Y "Creating the xcode project via qmake..."
|
||||||
|
$QMAKE \
|
||||||
|
VERSION=$SHORTVERSION \
|
||||||
|
BUILD_ID=$FULLVERSION \
|
||||||
|
-spec macx-xcode \
|
||||||
|
$MODE \
|
||||||
|
$VPNMODE \
|
||||||
|
$WEMODE \
|
||||||
|
$PLATFORM \
|
||||||
|
$ADJUST \
|
||||||
|
./client.pro || die "Compilation failed"
|
||||||
|
|
||||||
|
print Y "Patching the xcode project..."
|
||||||
|
ruby scripts/xcode_patcher.rb "AmneziaVPN.xcodeproj" "$SHORTVERSION" "$FULLVERSION" "$OSRUBY" "$NETWORKEXTENSION" "$ADJUST_SDK_TOKEN" || die "Failed to merge xcode with wireguard"
|
||||||
|
print G "done."
|
||||||
|
|
||||||
|
print Y "Opening in XCode..."
|
||||||
|
open AmneziaVPN.xcodeproj
|
||||||
|
print G "All done!"
|
664
client/scripts/xcode_patcher.rb
Normal file
664
client/scripts/xcode_patcher.rb
Normal file
|
@ -0,0 +1,664 @@
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
require 'xcodeproj'
|
||||||
|
|
||||||
|
class XCodeprojPatcher
|
||||||
|
attr :project
|
||||||
|
attr :target_main
|
||||||
|
attr :target_extension
|
||||||
|
|
||||||
|
def run(file, shortVersion, fullVersion, platform, networkExtension, configHash, adjust_sdk_token)
|
||||||
|
open_project file
|
||||||
|
open_target_main
|
||||||
|
|
||||||
|
die 'IOS requires networkExtension mode' if not networkExtension and platform == 'ios'
|
||||||
|
|
||||||
|
group = @project.main_group.new_group('Configuration')
|
||||||
|
@configFile = group.new_file('xcode.xconfig')
|
||||||
|
|
||||||
|
setup_target_main shortVersion, fullVersion, platform, networkExtension, configHash, adjust_sdk_token
|
||||||
|
|
||||||
|
# if platform == 'macos'
|
||||||
|
# setup_target_loginitem shortVersion, fullVersion, configHash
|
||||||
|
# setup_target_nativemessaging shortVersion, fullVersion, configHash
|
||||||
|
# end
|
||||||
|
|
||||||
|
|
||||||
|
if networkExtension
|
||||||
|
setup_target_extension shortVersion, fullVersion, platform, configHash
|
||||||
|
setup_target_gobridge
|
||||||
|
else
|
||||||
|
setup_target_wireguardgo
|
||||||
|
setup_target_wireguardtools
|
||||||
|
end
|
||||||
|
|
||||||
|
setup_target_balrog if platform == 'macos'
|
||||||
|
|
||||||
|
@project.save
|
||||||
|
end
|
||||||
|
|
||||||
|
def open_project(file)
|
||||||
|
@project = Xcodeproj::Project.open(file)
|
||||||
|
die 'Failed to open the project file: ' + file if @project.nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
def open_target_main
|
||||||
|
@target_main = @project.targets.find { |target| target.to_s == 'AmneziaVPN' }
|
||||||
|
return @target_main if not @target_main.nil?
|
||||||
|
|
||||||
|
die 'Unable to open AmneziaVPN target'
|
||||||
|
end
|
||||||
|
|
||||||
|
def setup_target_main(shortVersion, fullVersion, platform, networkExtension, configHash, adjust_sdk_token)
|
||||||
|
@target_main.build_configurations.each do |config|
|
||||||
|
config.base_configuration_reference = @configFile
|
||||||
|
|
||||||
|
config.build_settings['LD_RUNPATH_SEARCH_PATHS'] ||= '"$(inherited) @executable_path/../Frameworks"'
|
||||||
|
config.build_settings['SWIFT_VERSION'] ||= '5.0'
|
||||||
|
config.build_settings['CLANG_ENABLE_MODULES'] ||= 'YES'
|
||||||
|
config.build_settings['SWIFT_OBJC_BRIDGING_HEADER'] ||= 'macos/app/WireGuard-Bridging-Header.h'
|
||||||
|
config.build_settings['FRAMEWORK_SEARCH_PATHS'] ||= [
|
||||||
|
"$(inherited)",
|
||||||
|
"$(PROJECT_DIR)/3rd"
|
||||||
|
]
|
||||||
|
|
||||||
|
# Versions and names
|
||||||
|
config.build_settings['MARKETING_VERSION'] ||= shortVersion
|
||||||
|
config.build_settings['CURRENT_PROJECT_VERSION'] ||= fullVersion
|
||||||
|
config.build_settings['PRODUCT_BUNDLE_IDENTIFIER'] = configHash['APP_ID_MACOS'] if platform == 'macos'
|
||||||
|
config.build_settings['PRODUCT_BUNDLE_IDENTIFIER'] = configHash['APP_ID_IOS'] if platform == 'ios'
|
||||||
|
config.build_settings['PRODUCT_NAME'] = 'AmneziaVPN'
|
||||||
|
|
||||||
|
# other config
|
||||||
|
config.build_settings['INFOPLIST_FILE'] ||= platform + '/app/Info.plist'
|
||||||
|
if platform == 'ios'
|
||||||
|
config.build_settings['CODE_SIGN_ENTITLEMENTS'] ||= 'ios/app/main.entitlements'
|
||||||
|
if adjust_sdk_token != ""
|
||||||
|
config.build_settings['ADJUST_SDK_TOKEN'] = adjust_sdk_token
|
||||||
|
end
|
||||||
|
elsif networkExtension
|
||||||
|
config.build_settings['CODE_SIGN_ENTITLEMENTS'] ||= 'macos/app/app.entitlements'
|
||||||
|
else
|
||||||
|
config.build_settings['CODE_SIGN_ENTITLEMENTS'] ||= 'macos/app/daemon.entitlements'
|
||||||
|
end
|
||||||
|
|
||||||
|
config.build_settings['CODE_SIGN_IDENTITY'] ||= 'Apple Development'
|
||||||
|
config.build_settings['ENABLE_BITCODE'] ||= 'NO' if platform == 'ios'
|
||||||
|
config.build_settings['SDKROOT'] = 'iphoneos' if platform == 'ios'
|
||||||
|
config.build_settings['SWIFT_PRECOMPILE_BRIDGING_HEADER'] = 'NO' if platform == 'ios'
|
||||||
|
|
||||||
|
groupId = "";
|
||||||
|
if (platform == 'macos')
|
||||||
|
groupId = configHash['DEVELOPMENT_TEAM'] + "." + configHash['GROUP_ID_MACOS']
|
||||||
|
config.build_settings['APP_ID_MACOS'] ||= configHash['APP_ID_MACOS']
|
||||||
|
else
|
||||||
|
groupId = configHash['GROUP_ID_IOS']
|
||||||
|
config.build_settings['GROUP_ID_IOS'] ||= configHash['GROUP_ID_IOS']
|
||||||
|
# Force xcode to not set QT_LIBRARY_SUFFIX to "_debug", which causes crash
|
||||||
|
config.build_settings['QT_LIBRARY_SUFFIX'] = ""
|
||||||
|
end
|
||||||
|
|
||||||
|
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
|
||||||
|
'GROUP_ID=\"' + groupId + '\"',
|
||||||
|
"VPN_NE_BUNDLEID=\\\"" + (platform == 'macos' ? configHash['NETEXT_ID_MACOS'] : configHash['NETEXT_ID_IOS']) + "\\\"",
|
||||||
|
]
|
||||||
|
|
||||||
|
if config.name == 'Release'
|
||||||
|
config.build_settings['SWIFT_OPTIMIZATION_LEVEL'] ||= '-Onone'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if networkExtension
|
||||||
|
# WireGuard group
|
||||||
|
group = @project.main_group.new_group('WireGuard')
|
||||||
|
|
||||||
|
[
|
||||||
|
'macos/gobridge/wireguard-go-version.h',
|
||||||
|
'3rd/wireguard-apple/Sources/Shared/Keychain.swift',
|
||||||
|
'3rd/wireguard-apple/Sources/WireGuardKit/IPAddressRange.swift',
|
||||||
|
'3rd/wireguard-apple/Sources/WireGuardKit/InterfaceConfiguration.swift',
|
||||||
|
'3rd/wireguard-apple/Sources/Shared/Model/NETunnelProviderProtocol+Extension.swift',
|
||||||
|
'3rd/wireguard-apple/Sources/WireGuardKit/TunnelConfiguration.swift',
|
||||||
|
'3rd/wireguard-apple/Sources/Shared/Model/TunnelConfiguration+WgQuickConfig.swift',
|
||||||
|
'3rd/wireguard-apple/Sources/WireGuardKit/Endpoint.swift',
|
||||||
|
'3rd/wireguard-apple/Sources/Shared/Model/String+ArrayConversion.swift',
|
||||||
|
'3rd/wireguard-apple/Sources/WireGuardKit/PeerConfiguration.swift',
|
||||||
|
'3rd/wireguard-apple/Sources/WireGuardKit/DNSServer.swift',
|
||||||
|
'3rd/wireguard-apple/Sources/WireGuardApp/LocalizationHelper.swift',
|
||||||
|
'3rd/wireguard-apple/Sources/Shared/FileManager+Extension.swift',
|
||||||
|
'3rd/wireguard-apple/Sources/WireGuardKitC/x25519.c',
|
||||||
|
'3rd/wireguard-apple/Sources/WireGuardKit/PrivateKey.swift',
|
||||||
|
].each { |filename|
|
||||||
|
file = group.new_file(filename)
|
||||||
|
@target_main.add_file_references([file])
|
||||||
|
}
|
||||||
|
|
||||||
|
# @target_main + swift integration
|
||||||
|
group = @project.main_group.new_group('SwiftMainIntegration')
|
||||||
|
|
||||||
|
[
|
||||||
|
'platforms/ios/iosvpnprotocol.swift',
|
||||||
|
'platforms/ios/ioslogger.swift',
|
||||||
|
].each { |filename|
|
||||||
|
file = group.new_file(filename)
|
||||||
|
@target_main.add_file_references([file])
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
if (platform == 'ios' && adjust_sdk_token != "")
|
||||||
|
frameworks_group = @project.groups.find { |group| group.display_name == 'Frameworks' }
|
||||||
|
frameworks_build_phase = @target_main.build_phases.find { |build_phase| build_phase.to_s == 'FrameworksBuildPhase' }
|
||||||
|
|
||||||
|
framework_ref = frameworks_group.new_file('AdServices.framework')
|
||||||
|
build_file = frameworks_build_phase.add_file_reference(framework_ref)
|
||||||
|
build_file.settings = { 'ATTRIBUTES' => ['Weak'] }
|
||||||
|
|
||||||
|
framework_ref = frameworks_group.new_file('iAd.framework')
|
||||||
|
frameworks_build_phase.add_file_reference(framework_ref)
|
||||||
|
|
||||||
|
# Adjust SDK
|
||||||
|
group = @project.main_group.new_group('AdjustSDK')
|
||||||
|
|
||||||
|
[
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJActivityHandler.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJActivityKind.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJActivityPackage.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJActivityState.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJAdjustFactory.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJAdRevenue.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJAttribution.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJAttributionHandler.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJBackoffStrategy.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJAdditions/NSData+ADJAdditions.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJAdditions/NSNumber+ADJAdditions.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJAdditions/NSString+ADJAdditions.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJConfig.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJEvent.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJEventFailure.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJEventSuccess.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJLinkResolution.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJLogger.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJPackageBuilder.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJPackageHandler.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJPackageParams.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJRequestHandler.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJResponseData.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJSdkClickHandler.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJSessionFailure.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJSessionParameters.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJSessionSuccess.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJSubscription.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJThirdPartySharing.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJTimerCycle.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJTimerOnce.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJUrlStrategy.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJUserDefaults.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/Adjust.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJUtil.h',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJActivityHandler.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJActivityKind.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJActivityPackage.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJActivityState.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJAdjustFactory.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJAdRevenue.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJAttribution.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJAttributionHandler.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJBackoffStrategy.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJAdditions/NSData+ADJAdditions.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJAdditions/NSNumber+ADJAdditions.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJAdditions/NSString+ADJAdditions.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJConfig.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJEvent.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJEventFailure.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJEventSuccess.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJLinkResolution.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJLogger.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJPackageBuilder.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJPackageHandler.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJPackageParams.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJRequestHandler.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJResponseData.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJSdkClickHandler.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJSessionFailure.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJSessionParameters.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJSessionSuccess.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJSubscription.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJThirdPartySharing.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJTimerCycle.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJTimerOnce.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJUrlStrategy.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJUserDefaults.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/Adjust.m',
|
||||||
|
'3rd/adjust-ios-sdk/Adjust/ADJUtil.m',
|
||||||
|
].each { |filename|
|
||||||
|
file = group.new_file(filename)
|
||||||
|
file_reference = @target_main.add_file_references([file], '-fobjc-arc')
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def setup_target_extension(shortVersion, fullVersion, platform, configHash)
|
||||||
|
@target_extension = @project.new_target(:app_extension, 'WireGuardNetworkExtension', platform == 'macos' ? :osx : :ios)
|
||||||
|
|
||||||
|
@target_extension.build_configurations.each do |config|
|
||||||
|
config.base_configuration_reference = @configFile
|
||||||
|
|
||||||
|
config.build_settings['LD_RUNPATH_SEARCH_PATHS'] ||= '"$(inherited) @executable_path/../Frameworks"'
|
||||||
|
config.build_settings['SWIFT_VERSION'] ||= '5.0'
|
||||||
|
config.build_settings['CLANG_ENABLE_MODULES'] ||= 'YES'
|
||||||
|
config.build_settings['SWIFT_OBJC_BRIDGING_HEADER'] ||= 'macos/networkextension/WireGuardNetworkExtension-Bridging-Header.h'
|
||||||
|
config.build_settings['SWIFT_PRECOMPILE_BRIDGING_HEADER'] = 'NO'
|
||||||
|
config.build_settings['APPLICATION_EXTENSION_API_ONLY'] = 'YES'
|
||||||
|
|
||||||
|
# Versions and names
|
||||||
|
config.build_settings['MARKETING_VERSION'] ||= shortVersion
|
||||||
|
config.build_settings['CURRENT_PROJECT_VERSION'] ||= fullVersion
|
||||||
|
config.build_settings['PRODUCT_BUNDLE_IDENTIFIER'] ||= configHash['NETEXT_ID_MACOS'] if platform == 'macos'
|
||||||
|
config.build_settings['PRODUCT_BUNDLE_IDENTIFIER'] ||= configHash['NETEXT_ID_IOS'] if platform == 'ios'
|
||||||
|
config.build_settings['PRODUCT_NAME'] = 'WireGuardNetworkExtension'
|
||||||
|
|
||||||
|
# other configs
|
||||||
|
config.build_settings['INFOPLIST_FILE'] ||= 'macos/networkextension/Info.plist'
|
||||||
|
config.build_settings['CODE_SIGN_ENTITLEMENTS'] ||= platform + '/networkextension/AmneziaVPNNetworkExtension.entitlements'
|
||||||
|
config.build_settings['CODE_SIGN_IDENTITY'] = 'Apple Development'
|
||||||
|
|
||||||
|
if platform == 'ios'
|
||||||
|
config.build_settings['ENABLE_BITCODE'] ||= 'NO'
|
||||||
|
config.build_settings['SDKROOT'] = 'iphoneos'
|
||||||
|
|
||||||
|
config.build_settings['OTHER_LDFLAGS'] ||= [
|
||||||
|
"-stdlib=libc++",
|
||||||
|
"-Wl,-rpath,@executable_path/Frameworks",
|
||||||
|
"-framework",
|
||||||
|
"AssetsLibrary",
|
||||||
|
"-framework",
|
||||||
|
"MobileCoreServices",
|
||||||
|
"-lm",
|
||||||
|
"-framework",
|
||||||
|
"UIKit",
|
||||||
|
"-lz",
|
||||||
|
"-framework",
|
||||||
|
"OpenGLES",
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
groupId = "";
|
||||||
|
if (platform == 'macos')
|
||||||
|
groupId = configHash['DEVELOPMENT_TEAM'] + "." + configHash['GROUP_ID_MACOS']
|
||||||
|
else
|
||||||
|
groupId = configHash['GROUP_ID_IOS']
|
||||||
|
end
|
||||||
|
|
||||||
|
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
|
||||||
|
# This is needed to compile the iosglue without Qt.
|
||||||
|
'NETWORK_EXTENSION=1',
|
||||||
|
'GROUP_ID=\"' + groupId + '\"',
|
||||||
|
]
|
||||||
|
|
||||||
|
if config.name == 'Release'
|
||||||
|
config.build_settings['SWIFT_OPTIMIZATION_LEVEL'] ||= '-Onone'
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
group = @project.main_group.new_group('WireGuardExtension')
|
||||||
|
[
|
||||||
|
'3rd/wireguard-apple/Sources/WireGuardKit/WireGuardAdapter.swift',
|
||||||
|
'3rd/wireguard-apple/Sources/WireGuardKit/PacketTunnelSettingsGenerator.swift',
|
||||||
|
'3rd/wireguard-apple/Sources/WireGuardKit/DNSResolver.swift',
|
||||||
|
'3rd/wireguard-apple/Sources/WireGuardNetworkExtension/ErrorNotifier.swift',
|
||||||
|
'3rd/wireguard-apple/Sources/Shared/Keychain.swift',
|
||||||
|
'3rd/wireguard-apple/Sources/Shared/Model/TunnelConfiguration+WgQuickConfig.swift',
|
||||||
|
'3rd/wireguard-apple/Sources/Shared/Model/NETunnelProviderProtocol+Extension.swift',
|
||||||
|
'3rd/wireguard-apple/Sources/Shared/Model/String+ArrayConversion.swift',
|
||||||
|
'3rd/wireguard-apple/Sources/WireGuardKit/TunnelConfiguration.swift',
|
||||||
|
'3rd/wireguard-apple/Sources/WireGuardKit/IPAddressRange.swift',
|
||||||
|
'3rd/wireguard-apple/Sources/WireGuardKit/Endpoint.swift',
|
||||||
|
'3rd/wireguard-apple/Sources/WireGuardKit/DNSServer.swift',
|
||||||
|
'3rd/wireguard-apple/Sources/WireGuardKit/InterfaceConfiguration.swift',
|
||||||
|
'3rd/wireguard-apple/Sources/WireGuardKit/PeerConfiguration.swift',
|
||||||
|
'3rd/wireguard-apple/Sources/Shared/FileManager+Extension.swift',
|
||||||
|
'3rd/wireguard-apple/Sources/WireGuardKitC/x25519.c',
|
||||||
|
'3rd/wireguard-apple/Sources/WireGuardKit/Array+ConcurrentMap.swift',
|
||||||
|
'3rd/wireguard-apple/Sources/WireGuardKit/IPAddress+AddrInfo.swift',
|
||||||
|
'3rd/wireguard-apple/Sources/WireGuardKit/PrivateKey.swift',
|
||||||
|
].each { |filename|
|
||||||
|
file = group.new_file(filename)
|
||||||
|
@target_extension.add_file_references([file])
|
||||||
|
}
|
||||||
|
# @target_extension + swift integration
|
||||||
|
group = @project.main_group.new_group('SwiftExtensionIntegration')
|
||||||
|
|
||||||
|
[
|
||||||
|
'platforms/ios/iostunnel.swift',
|
||||||
|
'platforms/ios/iosglue.mm',
|
||||||
|
'platforms/ios/ioslogger.swift',
|
||||||
|
].each { |filename|
|
||||||
|
file = group.new_file(filename)
|
||||||
|
@target_extension.add_file_references([file])
|
||||||
|
}
|
||||||
|
|
||||||
|
frameworks_group = @project.groups.find { |group| group.display_name == 'Frameworks' }
|
||||||
|
frameworks_build_phase = @target_extension.build_phases.find { |build_phase| build_phase.to_s == 'FrameworksBuildPhase' }
|
||||||
|
|
||||||
|
frameworks_build_phase.clear
|
||||||
|
|
||||||
|
framework_ref = frameworks_group.new_file('libwg-go.a')
|
||||||
|
frameworks_build_phase.add_file_reference(framework_ref)
|
||||||
|
|
||||||
|
framework_ref = frameworks_group.new_file('NetworkExtension.framework')
|
||||||
|
frameworks_build_phase.add_file_reference(framework_ref)
|
||||||
|
|
||||||
|
# This fails: @target_main.add_dependency @target_extension
|
||||||
|
container_proxy = @project.new(Xcodeproj::Project::PBXContainerItemProxy)
|
||||||
|
container_proxy.container_portal = @project.root_object.uuid
|
||||||
|
container_proxy.proxy_type = Xcodeproj::Constants::PROXY_TYPES[:native_target]
|
||||||
|
container_proxy.remote_global_id_string = @target_extension.uuid
|
||||||
|
container_proxy.remote_info = @target_extension.name
|
||||||
|
|
||||||
|
dependency = @project.new(Xcodeproj::Project::PBXTargetDependency)
|
||||||
|
dependency.name = @target_extension.name
|
||||||
|
dependency.target = @target_main
|
||||||
|
dependency.target_proxy = container_proxy
|
||||||
|
|
||||||
|
@target_main.dependencies << dependency
|
||||||
|
|
||||||
|
copy_appex = @target_main.new_copy_files_build_phase
|
||||||
|
copy_appex.name = 'Copy Network-Extension plugin'
|
||||||
|
copy_appex.symbol_dst_subfolder_spec = :plug_ins
|
||||||
|
|
||||||
|
appex_file = copy_appex.add_file_reference @target_extension.product_reference
|
||||||
|
appex_file.settings = { "ATTRIBUTES" => ['RemoveHeadersOnCopy'] }
|
||||||
|
end
|
||||||
|
|
||||||
|
def setup_target_gobridge
|
||||||
|
target_gobridge = legacy_target = @project.new(Xcodeproj::Project::PBXLegacyTarget)
|
||||||
|
|
||||||
|
target_gobridge.build_working_directory = 'macos/gobridge'
|
||||||
|
target_gobridge.build_tool_path = 'make'
|
||||||
|
target_gobridge.pass_build_settings_in_environment = '1'
|
||||||
|
target_gobridge.build_arguments_string = '$(ACTION)'
|
||||||
|
target_gobridge.name = 'WireGuardGoBridge'
|
||||||
|
target_gobridge.product_name = 'WireGuardGoBridge'
|
||||||
|
|
||||||
|
@project.targets << target_gobridge
|
||||||
|
@target_extension.add_dependency target_gobridge
|
||||||
|
end
|
||||||
|
|
||||||
|
def setup_target_balrog
|
||||||
|
target_balrog = legacy_target = @project.new(Xcodeproj::Project::PBXLegacyTarget)
|
||||||
|
|
||||||
|
target_balrog.build_working_directory = 'balrog'
|
||||||
|
target_balrog.build_tool_path = 'make'
|
||||||
|
target_balrog.pass_build_settings_in_environment = '1'
|
||||||
|
target_balrog.build_arguments_string = '$(ACTION)'
|
||||||
|
target_balrog.name = 'WireGuardBalrog'
|
||||||
|
target_balrog.product_name = 'WireGuardBalrog'
|
||||||
|
|
||||||
|
@project.targets << target_balrog
|
||||||
|
|
||||||
|
frameworks_group = @project.groups.find { |group| group.display_name == 'Frameworks' }
|
||||||
|
frameworks_build_phase = @target_main.build_phases.find { |build_phase| build_phase.to_s == 'FrameworksBuildPhase' }
|
||||||
|
|
||||||
|
framework_ref = frameworks_group.new_file('balrog/balrog.a')
|
||||||
|
frameworks_build_phase.add_file_reference(framework_ref)
|
||||||
|
|
||||||
|
# This fails: @target_main.add_dependency target_balrog
|
||||||
|
container_proxy = @project.new(Xcodeproj::Project::PBXContainerItemProxy)
|
||||||
|
container_proxy.container_portal = @project.root_object.uuid
|
||||||
|
container_proxy.proxy_type = Xcodeproj::Constants::PROXY_TYPES[:native_target]
|
||||||
|
container_proxy.remote_global_id_string = target_balrog.uuid
|
||||||
|
container_proxy.remote_info = target_balrog.name
|
||||||
|
|
||||||
|
dependency = @project.new(Xcodeproj::Project::PBXTargetDependency)
|
||||||
|
dependency.name = target_balrog.name
|
||||||
|
dependency.target = @target_main
|
||||||
|
dependency.target_proxy = container_proxy
|
||||||
|
|
||||||
|
@target_main.dependencies << dependency
|
||||||
|
end
|
||||||
|
|
||||||
|
def setup_target_wireguardtools
|
||||||
|
target_wireguardtools = legacy_target = @project.new(Xcodeproj::Project::PBXLegacyTarget)
|
||||||
|
|
||||||
|
target_wireguardtools.build_working_directory = '3rd/wireguard-tools/src'
|
||||||
|
target_wireguardtools.build_tool_path = 'make'
|
||||||
|
target_wireguardtools.pass_build_settings_in_environment = '1'
|
||||||
|
target_wireguardtools.build_arguments_string = '$(ACTION)'
|
||||||
|
target_wireguardtools.name = 'WireGuardTools'
|
||||||
|
target_wireguardtools.product_name = 'WireGuardTools'
|
||||||
|
|
||||||
|
@project.targets << target_wireguardtools
|
||||||
|
|
||||||
|
# This fails: @target_main.add_dependency target_wireguardtools
|
||||||
|
container_proxy = @project.new(Xcodeproj::Project::PBXContainerItemProxy)
|
||||||
|
container_proxy.container_portal = @project.root_object.uuid
|
||||||
|
container_proxy.proxy_type = Xcodeproj::Constants::PROXY_TYPES[:native_target]
|
||||||
|
container_proxy.remote_global_id_string = target_wireguardtools.uuid
|
||||||
|
container_proxy.remote_info = target_wireguardtools.name
|
||||||
|
|
||||||
|
dependency = @project.new(Xcodeproj::Project::PBXTargetDependency)
|
||||||
|
dependency.name = target_wireguardtools.name
|
||||||
|
dependency.target = @target_main
|
||||||
|
dependency.target_proxy = container_proxy
|
||||||
|
|
||||||
|
@target_main.dependencies << dependency
|
||||||
|
|
||||||
|
copy_wireguardTools = @target_main.new_copy_files_build_phase
|
||||||
|
copy_wireguardTools.name = 'Copy wireguard-tools'
|
||||||
|
copy_wireguardTools.symbol_dst_subfolder_spec = :wrapper
|
||||||
|
copy_wireguardTools.dst_path = 'Contents/Resources/utils'
|
||||||
|
|
||||||
|
group = @project.main_group.new_group('WireGuardTools')
|
||||||
|
file = group.new_file '3rd/wireguard-tools/src/wg'
|
||||||
|
|
||||||
|
wireguardTools_file = copy_wireguardTools.add_file_reference file
|
||||||
|
wireguardTools_file.settings = { "ATTRIBUTES" => ['RemoveHeadersOnCopy'] }
|
||||||
|
end
|
||||||
|
|
||||||
|
def setup_target_wireguardgo
|
||||||
|
target_wireguardgo = legacy_target = @project.new(Xcodeproj::Project::PBXLegacyTarget)
|
||||||
|
|
||||||
|
target_wireguardgo.build_working_directory = '3rd/wireguard-go'
|
||||||
|
target_wireguardgo.build_tool_path = 'make'
|
||||||
|
target_wireguardgo.pass_build_settings_in_environment = '1'
|
||||||
|
target_wireguardgo.build_arguments_string = '$(ACTION)'
|
||||||
|
target_wireguardgo.name = 'WireGuardGo'
|
||||||
|
target_wireguardgo.product_name = 'WireGuardGo'
|
||||||
|
|
||||||
|
@project.targets << target_wireguardgo
|
||||||
|
|
||||||
|
# This fails: @target_main.add_dependency target_wireguardgo
|
||||||
|
container_proxy = @project.new(Xcodeproj::Project::PBXContainerItemProxy)
|
||||||
|
container_proxy.container_portal = @project.root_object.uuid
|
||||||
|
container_proxy.proxy_type = Xcodeproj::Constants::PROXY_TYPES[:native_target]
|
||||||
|
container_proxy.remote_global_id_string = target_wireguardgo.uuid
|
||||||
|
container_proxy.remote_info = target_wireguardgo.name
|
||||||
|
|
||||||
|
dependency = @project.new(Xcodeproj::Project::PBXTargetDependency)
|
||||||
|
dependency.name = target_wireguardgo.name
|
||||||
|
dependency.target = @target_main
|
||||||
|
dependency.target_proxy = container_proxy
|
||||||
|
|
||||||
|
@target_main.dependencies << dependency
|
||||||
|
|
||||||
|
copy_wireguardGo = @target_main.new_copy_files_build_phase
|
||||||
|
copy_wireguardGo.name = 'Copy wireguard-go'
|
||||||
|
copy_wireguardGo.symbol_dst_subfolder_spec = :wrapper
|
||||||
|
copy_wireguardGo.dst_path = 'Contents/Resources/utils'
|
||||||
|
|
||||||
|
group = @project.main_group.new_group('WireGuardGo')
|
||||||
|
file = group.new_file '3rd/wireguard-go/wireguard-go'
|
||||||
|
|
||||||
|
wireguardGo_file = copy_wireguardGo.add_file_reference file
|
||||||
|
wireguardGo_file.settings = { "ATTRIBUTES" => ['RemoveHeadersOnCopy'] }
|
||||||
|
end
|
||||||
|
|
||||||
|
def setup_target_loginitem(shortVersion, fullVersion, configHash)
|
||||||
|
@target_loginitem = @project.new_target(:application, 'AmneziaVPNLoginItem', :osx)
|
||||||
|
|
||||||
|
@target_loginitem.build_configurations.each do |config|
|
||||||
|
config.base_configuration_reference = @configFile
|
||||||
|
|
||||||
|
config.build_settings['LD_RUNPATH_SEARCH_PATHS'] ||= '"$(inherited) @executable_path/../Frameworks"'
|
||||||
|
|
||||||
|
# Versions and names
|
||||||
|
config.build_settings['MARKETING_VERSION'] ||= shortVersion
|
||||||
|
config.build_settings['CURRENT_PROJECT_VERSION'] ||= fullVersion
|
||||||
|
config.build_settings['PRODUCT_BUNDLE_IDENTIFIER'] ||= configHash['LOGIN_ID_MACOS']
|
||||||
|
config.build_settings['PRODUCT_NAME'] = 'AmneziaVPNLoginItem'
|
||||||
|
|
||||||
|
# other configs
|
||||||
|
config.build_settings['INFOPLIST_FILE'] ||= 'macos/loginitem/Info.plist'
|
||||||
|
config.build_settings['CODE_SIGN_ENTITLEMENTS'] ||= 'macos/loginitem/MozillaVPNLoginItem.entitlements'
|
||||||
|
config.build_settings['CODE_SIGN_IDENTITY'] = 'Apple Development'
|
||||||
|
config.build_settings['SKIP_INSTALL'] = 'YES'
|
||||||
|
|
||||||
|
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
|
||||||
|
'APP_ID=\"' + configHash['APP_ID_MACOS'] + '\"',
|
||||||
|
]
|
||||||
|
|
||||||
|
if config.name == 'Release'
|
||||||
|
config.build_settings['SWIFT_OPTIMIZATION_LEVEL'] ||= '-Onone'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
group = @project.main_group.new_group('LoginItem')
|
||||||
|
[
|
||||||
|
'macos/loginitem/main.m',
|
||||||
|
].each { |filename|
|
||||||
|
file = group.new_file(filename)
|
||||||
|
@target_loginitem.add_file_references([file])
|
||||||
|
}
|
||||||
|
|
||||||
|
# This fails: @target_main.add_dependency @target_loginitem
|
||||||
|
container_proxy = @project.new(Xcodeproj::Project::PBXContainerItemProxy)
|
||||||
|
container_proxy.container_portal = @project.root_object.uuid
|
||||||
|
container_proxy.proxy_type = Xcodeproj::Constants::PROXY_TYPES[:native_target]
|
||||||
|
container_proxy.remote_global_id_string = @target_loginitem.uuid
|
||||||
|
container_proxy.remote_info = @target_loginitem.name
|
||||||
|
|
||||||
|
dependency = @project.new(Xcodeproj::Project::PBXTargetDependency)
|
||||||
|
dependency.name = @target_loginitem.name
|
||||||
|
dependency.target = @target_main
|
||||||
|
dependency.target_proxy = container_proxy
|
||||||
|
|
||||||
|
@target_main.dependencies << dependency
|
||||||
|
|
||||||
|
copy_app = @target_main.new_copy_files_build_phase
|
||||||
|
copy_app.name = 'Copy LoginItem'
|
||||||
|
copy_app.symbol_dst_subfolder_spec = :wrapper
|
||||||
|
copy_app.dst_path = 'Contents/Library/LoginItems'
|
||||||
|
|
||||||
|
app_file = copy_app.add_file_reference @target_loginitem.product_reference
|
||||||
|
app_file.settings = { "ATTRIBUTES" => ['RemoveHeadersOnCopy'] }
|
||||||
|
end
|
||||||
|
|
||||||
|
def setup_target_nativemessaging(shortVersion, fullVersion, configHash)
|
||||||
|
@target_nativemessaging = @project.new_target(:application, 'AmneziaVPNNativeMessaging', :osx)
|
||||||
|
|
||||||
|
@target_nativemessaging.build_configurations.each do |config|
|
||||||
|
config.base_configuration_reference = @configFile
|
||||||
|
|
||||||
|
config.build_settings['LD_RUNPATH_SEARCH_PATHS'] ||= '"$(inherited) @executable_path/../Frameworks"'
|
||||||
|
|
||||||
|
# Versions and names
|
||||||
|
config.build_settings['MARKETING_VERSION'] ||= shortVersion
|
||||||
|
config.build_settings['CURRENT_PROJECT_VERSION'] ||= fullVersion
|
||||||
|
config.build_settings['PRODUCT_BUNDLE_IDENTIFIER'] ||= configHash['NATIVEMESSAGING_ID_MACOS']
|
||||||
|
config.build_settings['PRODUCT_NAME'] = 'AmneziaVPNNativeMessaging'
|
||||||
|
|
||||||
|
# other configs
|
||||||
|
config.build_settings['INFOPLIST_FILE'] ||= 'macos/nativeMessaging/Info.plist'
|
||||||
|
config.build_settings['CODE_SIGN_ENTITLEMENTS'] ||= 'macos/nativeMessaging/MozillaVPNNativeMessaging.entitlements'
|
||||||
|
config.build_settings['CODE_SIGN_IDENTITY'] = 'Apple Development'
|
||||||
|
config.build_settings['SKIP_INSTALL'] = 'YES'
|
||||||
|
end
|
||||||
|
|
||||||
|
group = @project.main_group.new_group('NativeMessaging')
|
||||||
|
[
|
||||||
|
'extension/app/constants.h',
|
||||||
|
'extension/app/handler.cpp',
|
||||||
|
'extension/app/handler.h',
|
||||||
|
'extension/app/json.hpp',
|
||||||
|
'extension/app/logger.cpp',
|
||||||
|
'extension/app/logger.h',
|
||||||
|
'extension/app/main.cpp',
|
||||||
|
'extension/app/vpnconnection.cpp',
|
||||||
|
'extension/app/vpnconnection.h',
|
||||||
|
].each { |filename|
|
||||||
|
file = group.new_file(filename)
|
||||||
|
@target_nativemessaging.add_file_references([file])
|
||||||
|
}
|
||||||
|
|
||||||
|
# This fails: @target_main.add_dependency @target_nativemessaging
|
||||||
|
container_proxy = @project.new(Xcodeproj::Project::PBXContainerItemProxy)
|
||||||
|
container_proxy.container_portal = @project.root_object.uuid
|
||||||
|
container_proxy.proxy_type = Xcodeproj::Constants::PROXY_TYPES[:native_target]
|
||||||
|
container_proxy.remote_global_id_string = @target_nativemessaging.uuid
|
||||||
|
container_proxy.remote_info = @target_nativemessaging.name
|
||||||
|
|
||||||
|
dependency = @project.new(Xcodeproj::Project::PBXTargetDependency)
|
||||||
|
dependency.name = @target_nativemessaging.name
|
||||||
|
dependency.target = @target_main
|
||||||
|
dependency.target_proxy = container_proxy
|
||||||
|
|
||||||
|
@target_main.dependencies << dependency
|
||||||
|
|
||||||
|
copy_app = @target_main.new_copy_files_build_phase
|
||||||
|
copy_app.name = 'Copy LoginItem'
|
||||||
|
copy_app.symbol_dst_subfolder_spec = :wrapper
|
||||||
|
copy_app.dst_path = 'Contents/Library/NativeMessaging'
|
||||||
|
|
||||||
|
app_file = copy_app.add_file_reference @target_nativemessaging.product_reference
|
||||||
|
app_file.settings = { "ATTRIBUTES" => ['RemoveHeadersOnCopy'] }
|
||||||
|
|
||||||
|
copy_nativeMessagingManifest = @target_main.new_copy_files_build_phase
|
||||||
|
copy_nativeMessagingManifest.name = 'Copy native messaging manifest'
|
||||||
|
copy_nativeMessagingManifest.symbol_dst_subfolder_spec = :wrapper
|
||||||
|
copy_nativeMessagingManifest.dst_path = 'Contents/Resources/utils'
|
||||||
|
|
||||||
|
group = @project.main_group.new_group('WireGuardHelper')
|
||||||
|
file = group.new_file 'extension/app/manifests/macos/mozillavpn.json'
|
||||||
|
|
||||||
|
nativeMessagingManifest_file = copy_nativeMessagingManifest.add_file_reference file
|
||||||
|
nativeMessagingManifest_file.settings = { "ATTRIBUTES" => ['RemoveHeadersOnCopy'] }
|
||||||
|
end
|
||||||
|
|
||||||
|
def die(msg)
|
||||||
|
print $msg
|
||||||
|
exit 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if ARGV.length < 4 || (ARGV[3] != "ios" && ARGV[3] != "macos")
|
||||||
|
puts "Usage: <script> project_file shortVersion fullVersion ios/macos"
|
||||||
|
exit 1
|
||||||
|
end
|
||||||
|
|
||||||
|
if !File.exist?("xcode.xconfig")
|
||||||
|
puts "xcode.xconfig file is required! See the template file."
|
||||||
|
exit 1
|
||||||
|
end
|
||||||
|
|
||||||
|
config = Hash.new
|
||||||
|
configFile = File.read("xcode.xconfig").split("\n")
|
||||||
|
configFile.each { |line|
|
||||||
|
next if line[0] == "#"
|
||||||
|
|
||||||
|
if line.include? "="
|
||||||
|
keys = line.split("=")
|
||||||
|
config[keys[0].strip] = keys[1].strip
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
platform = "macos"
|
||||||
|
platform = "ios" if ARGV[3] == "ios"
|
||||||
|
networkExtension = true if ARGV[4] == "1"
|
||||||
|
adjust_sdk_token = ARGV[5]
|
||||||
|
|
||||||
|
r = XCodeprojPatcher.new
|
||||||
|
r.run ARGV[0], ARGV[1], ARGV[2], platform, networkExtension, config, adjust_sdk_token
|
||||||
|
exit 0
|
|
@ -151,13 +151,13 @@ void Settings::removeContainerConfig(int serverIndex, DockerContainer container)
|
||||||
setContainers(serverIndex, c);
|
setContainers(serverIndex, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject Settings::protocolConfig(int serverIndex, DockerContainer container, Protocol proto)
|
QJsonObject Settings::protocolConfig(int serverIndex, DockerContainer container, Proto proto)
|
||||||
{
|
{
|
||||||
const QJsonObject &c = containerConfig(serverIndex, container);
|
const QJsonObject &c = containerConfig(serverIndex, container);
|
||||||
return c.value(ProtocolProps::protoToString(proto)).toObject();
|
return c.value(ProtocolProps::protoToString(proto)).toObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::setProtocolConfig(int serverIndex, DockerContainer container, Protocol proto, const QJsonObject &config)
|
void Settings::setProtocolConfig(int serverIndex, DockerContainer container, Proto proto, const QJsonObject &config)
|
||||||
{
|
{
|
||||||
QJsonObject c = containerConfig(serverIndex, container);
|
QJsonObject c = containerConfig(serverIndex, container);
|
||||||
c.insert(ProtocolProps::protoToString(proto), config);
|
c.insert(ProtocolProps::protoToString(proto), config);
|
||||||
|
@ -165,11 +165,11 @@ void Settings::setProtocolConfig(int serverIndex, DockerContainer container, Pro
|
||||||
setContainerConfig(serverIndex, container, c);
|
setContainerConfig(serverIndex, container, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Settings::clearLastConnectionConfig(int serverIndex, DockerContainer container, Protocol proto)
|
void Settings::clearLastConnectionConfig(int serverIndex, DockerContainer container, Proto proto)
|
||||||
{
|
{
|
||||||
// recursively remove
|
// recursively remove
|
||||||
if (proto == Protocol::Any) {
|
if (proto == Proto::Any) {
|
||||||
for (Protocol p: ContainerProps::protocolsForContainer(container)) {
|
for (Proto p: ContainerProps::protocolsForContainer(container)) {
|
||||||
clearLastConnectionConfig(serverIndex, container, p);
|
clearLastConnectionConfig(serverIndex, container, p);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -52,10 +52,10 @@ public:
|
||||||
void setContainerConfig(int serverIndex, DockerContainer container, const QJsonObject &config);
|
void setContainerConfig(int serverIndex, DockerContainer container, const QJsonObject &config);
|
||||||
void removeContainerConfig(int serverIndex, DockerContainer container);
|
void removeContainerConfig(int serverIndex, DockerContainer container);
|
||||||
|
|
||||||
QJsonObject protocolConfig(int serverIndex, DockerContainer container, Protocol proto);
|
QJsonObject protocolConfig(int serverIndex, DockerContainer container, Proto proto);
|
||||||
void setProtocolConfig(int serverIndex, DockerContainer container, Protocol proto, const QJsonObject &config);
|
void setProtocolConfig(int serverIndex, DockerContainer container, Proto proto, const QJsonObject &config);
|
||||||
|
|
||||||
void clearLastConnectionConfig(int serverIndex, DockerContainer container, Protocol proto = Protocol::Any);
|
void clearLastConnectionConfig(int serverIndex, DockerContainer container, Proto proto = Proto::Any);
|
||||||
|
|
||||||
bool haveAuthData(int serverIndex) const;
|
bool haveAuthData(int serverIndex) const;
|
||||||
QString nextAvailableServerName() const;
|
QString nextAvailableServerName() const;
|
||||||
|
|
|
@ -28,7 +28,7 @@ QVariant ProtocolsModel::data(const QModelIndex &index, int role) const
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
Protocol p = ProtocolProps::allProtocols().at(index.row());
|
Proto p = ProtocolProps::allProtocols().at(index.row());
|
||||||
if (role == NameRole) {
|
if (role == NameRole) {
|
||||||
return ProtocolProps::protocolHumanNames().value(p);
|
return ProtocolProps::protocolHumanNames().value(p);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ void NewServerProtocolsLogic::onUpdatePage()
|
||||||
void NewServerProtocolsLogic::onPushButtonConfigureClicked(DockerContainer c, int port, TransportProto tp)
|
void NewServerProtocolsLogic::onPushButtonConfigureClicked(DockerContainer c, int port, TransportProto tp)
|
||||||
{
|
{
|
||||||
QMap<DockerContainer, QJsonObject> containers;
|
QMap<DockerContainer, QJsonObject> containers;
|
||||||
Protocol mainProto = ContainerProps::defaultProtocol(c);
|
Proto mainProto = ContainerProps::defaultProtocol(c);
|
||||||
|
|
||||||
QJsonObject config {
|
QJsonObject config {
|
||||||
{ config_key::container, ContainerProps::containerToString(c) },
|
{ config_key::container, ContainerProps::containerToString(c) },
|
||||||
|
|
|
@ -29,7 +29,7 @@ void ServerContainersLogic::onUpdatePage()
|
||||||
emit updatePage();
|
emit updatePage();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerContainersLogic::onPushButtonProtoSettingsClicked(DockerContainer c, Protocol p)
|
void ServerContainersLogic::onPushButtonProtoSettingsClicked(DockerContainer c, Proto p)
|
||||||
{
|
{
|
||||||
qDebug()<< "ServerContainersLogic::onPushButtonProtoSettingsClicked" << c << p;
|
qDebug()<< "ServerContainersLogic::onPushButtonProtoSettingsClicked" << c << p;
|
||||||
uiLogic()->selectedDockerContainer = c;
|
uiLogic()->selectedDockerContainer = c;
|
||||||
|
|
|
@ -12,7 +12,7 @@ class ServerContainersLogic : public PageLogicBase
|
||||||
public:
|
public:
|
||||||
Q_INVOKABLE void onUpdatePage() override;
|
Q_INVOKABLE void onUpdatePage() override;
|
||||||
|
|
||||||
Q_INVOKABLE void onPushButtonProtoSettingsClicked(DockerContainer c, Protocol p);
|
Q_INVOKABLE void onPushButtonProtoSettingsClicked(DockerContainer c, Proto p);
|
||||||
Q_INVOKABLE void onPushButtonDefaultClicked(DockerContainer c);
|
Q_INVOKABLE void onPushButtonDefaultClicked(DockerContainer c);
|
||||||
Q_INVOKABLE void onPushButtonShareClicked(DockerContainer c);
|
Q_INVOKABLE void onPushButtonShareClicked(DockerContainer c);
|
||||||
Q_INVOKABLE void onPushButtonRemoveClicked(DockerContainer c);
|
Q_INVOKABLE void onPushButtonRemoveClicked(DockerContainer c);
|
||||||
|
|
|
@ -128,5 +128,5 @@ void ServerSettingsLogic::onLineEditDescriptionEditingFinished()
|
||||||
void ServerSettingsLogic::onPushButtonShareFullClicked()
|
void ServerSettingsLogic::onPushButtonShareFullClicked()
|
||||||
{
|
{
|
||||||
uiLogic()->shareConnectionLogic()->updateSharingPage(uiLogic()->selectedServerIndex, DockerContainer::None);
|
uiLogic()->shareConnectionLogic()->updateSharingPage(uiLogic()->selectedServerIndex, DockerContainer::None);
|
||||||
emit uiLogic()->goToShareProtocolPage(Protocol::Any);
|
emit uiLogic()->goToShareProtocolPage(Proto::Any);
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,7 +70,7 @@ void ShareConnectionLogic::onPushButtonShareAmneziaGenerateClicked()
|
||||||
containerConfig.insert(config_key::container, ContainerProps::containerToString(uiLogic()->selectedDockerContainer));
|
containerConfig.insert(config_key::container, ContainerProps::containerToString(uiLogic()->selectedDockerContainer));
|
||||||
|
|
||||||
ErrorCode e = ErrorCode::NoError;
|
ErrorCode e = ErrorCode::NoError;
|
||||||
for (Protocol p: ContainerProps::protocolsForContainer(uiLogic()->selectedDockerContainer)) {
|
for (Proto p: ContainerProps::protocolsForContainer(uiLogic()->selectedDockerContainer)) {
|
||||||
QJsonObject protoConfig = m_settings.protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, p);
|
QJsonObject protoConfig = m_settings.protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, p);
|
||||||
|
|
||||||
QString cfg = VpnConfigurator::genVpnProtocolConfig(credentials, uiLogic()->selectedDockerContainer, containerConfig, p, &e);
|
QString cfg = VpnConfigurator::genVpnProtocolConfig(credentials, uiLogic()->selectedDockerContainer, containerConfig, p, &e);
|
||||||
|
@ -115,7 +115,7 @@ void ShareConnectionLogic::onPushButtonShareOpenVpnGenerateClicked()
|
||||||
|
|
||||||
ErrorCode e = ErrorCode::NoError;
|
ErrorCode e = ErrorCode::NoError;
|
||||||
QString cfg = OpenVpnConfigurator::genOpenVpnConfig(credentials, uiLogic()->selectedDockerContainer, containerConfig, &e);
|
QString cfg = OpenVpnConfigurator::genOpenVpnConfig(credentials, uiLogic()->selectedDockerContainer, containerConfig, &e);
|
||||||
cfg = VpnConfigurator::processConfigWithExportSettings(uiLogic()->selectedDockerContainer, Protocol::OpenVpn, cfg);
|
cfg = VpnConfigurator::processConfigWithExportSettings(uiLogic()->selectedDockerContainer, Proto::OpenVpn, cfg);
|
||||||
|
|
||||||
set_textEditShareOpenVpnCodeText(QJsonDocument::fromJson(cfg.toUtf8()).object()[config_key::config].toString());
|
set_textEditShareOpenVpnCodeText(QJsonDocument::fromJson(cfg.toUtf8()).object()[config_key::config].toString());
|
||||||
}
|
}
|
||||||
|
@ -126,7 +126,7 @@ void ShareConnectionLogic::onPushButtonShareShadowSocksGenerateClicked()
|
||||||
DockerContainer container = uiLogic()->selectedDockerContainer;
|
DockerContainer container = uiLogic()->selectedDockerContainer;
|
||||||
ServerCredentials credentials = m_settings.serverCredentials(serverIndex);
|
ServerCredentials credentials = m_settings.serverCredentials(serverIndex);
|
||||||
|
|
||||||
QJsonObject protoConfig = m_settings.protocolConfig(serverIndex, container, Protocol::ShadowSocks);
|
QJsonObject protoConfig = m_settings.protocolConfig(serverIndex, container, Proto::ShadowSocks);
|
||||||
QString cfg = protoConfig.value(config_key::last_config).toString();
|
QString cfg = protoConfig.value(config_key::last_config).toString();
|
||||||
|
|
||||||
if (cfg.isEmpty()) {
|
if (cfg.isEmpty()) {
|
||||||
|
@ -168,7 +168,7 @@ void ShareConnectionLogic::onPushButtonShareCloakGenerateClicked()
|
||||||
DockerContainer container = uiLogic()->selectedDockerContainer;
|
DockerContainer container = uiLogic()->selectedDockerContainer;
|
||||||
ServerCredentials credentials = m_settings.serverCredentials(serverIndex);
|
ServerCredentials credentials = m_settings.serverCredentials(serverIndex);
|
||||||
|
|
||||||
QJsonObject protoConfig = m_settings.protocolConfig(serverIndex, container, Protocol::Cloak);
|
QJsonObject protoConfig = m_settings.protocolConfig(serverIndex, container, Proto::Cloak);
|
||||||
QString cfg = protoConfig.value(config_key::last_config).toString();
|
QString cfg = protoConfig.value(config_key::last_config).toString();
|
||||||
|
|
||||||
if (cfg.isEmpty()) {
|
if (cfg.isEmpty()) {
|
||||||
|
@ -195,7 +195,7 @@ void ShareConnectionLogic::onPushButtonShareWireGuardGenerateClicked()
|
||||||
|
|
||||||
ErrorCode e = ErrorCode::NoError;
|
ErrorCode e = ErrorCode::NoError;
|
||||||
QString cfg = WireguardConfigurator::genWireguardConfig(credentials, container, containerConfig, &e);
|
QString cfg = WireguardConfigurator::genWireguardConfig(credentials, container, containerConfig, &e);
|
||||||
cfg = VpnConfigurator::processConfigWithExportSettings(container, Protocol::WireGuard, cfg);
|
cfg = VpnConfigurator::processConfigWithExportSettings(container, Proto::WireGuard, cfg);
|
||||||
cfg = QJsonDocument::fromJson(cfg.toUtf8()).object()[config_key::config].toString();
|
cfg = QJsonDocument::fromJson(cfg.toUtf8()).object()[config_key::config].toString();
|
||||||
|
|
||||||
set_textEditShareWireGuardCodeText(cfg);
|
set_textEditShareWireGuardCodeText(cfg);
|
||||||
|
@ -215,7 +215,7 @@ void ShareConnectionLogic::onPushButtonShareIkev2GenerateClicked()
|
||||||
Ikev2Configurator::ConnectionData connData = Ikev2Configurator::prepareIkev2Config(credentials, container);
|
Ikev2Configurator::ConnectionData connData = Ikev2Configurator::prepareIkev2Config(credentials, container);
|
||||||
|
|
||||||
QString cfg = Ikev2Configurator::genIkev2Config(connData);
|
QString cfg = Ikev2Configurator::genIkev2Config(connData);
|
||||||
cfg = VpnConfigurator::processConfigWithExportSettings(container, Protocol::Ikev2, cfg);
|
cfg = VpnConfigurator::processConfigWithExportSettings(container, Proto::Ikev2, cfg);
|
||||||
cfg = QJsonDocument::fromJson(cfg.toUtf8()).object()[config_key::cert].toString();
|
cfg = QJsonDocument::fromJson(cfg.toUtf8()).object()[config_key::cert].toString();
|
||||||
|
|
||||||
set_textEditShareIkev2CertText(cfg);
|
set_textEditShareIkev2CertText(cfg);
|
||||||
|
|
|
@ -77,7 +77,7 @@ void VpnLogic::onBytesChanged(quint64 receivedData, quint64 sentData)
|
||||||
set_labelSpeedSentText(VpnConnection::bytesPerSecToText(sentData));
|
set_labelSpeedSentText(VpnConnection::bytesPerSecToText(sentData));
|
||||||
}
|
}
|
||||||
|
|
||||||
void VpnLogic::onConnectionStateChanged(VpnProtocol::ConnectionState state)
|
void VpnLogic::onConnectionStateChanged(VpnProtocol::VpnConnectionState state)
|
||||||
{
|
{
|
||||||
qDebug() << "VpnLogic::onConnectionStateChanged" << VpnProtocol::textConnectionState(state);
|
qDebug() << "VpnLogic::onConnectionStateChanged" << VpnProtocol::textConnectionState(state);
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@ public slots:
|
||||||
void onDisconnect();
|
void onDisconnect();
|
||||||
|
|
||||||
void onBytesChanged(quint64 receivedBytes, quint64 sentBytes);
|
void onBytesChanged(quint64 receivedBytes, quint64 sentBytes);
|
||||||
void onConnectionStateChanged(VpnProtocol::ConnectionState state);
|
void onConnectionStateChanged(VpnProtocol::VpnConnectionState state);
|
||||||
void onVpnProtocolError(amnezia::ErrorCode errorCode);
|
void onVpnProtocolError(amnezia::ErrorCode errorCode);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
|
@ -22,7 +22,7 @@ QMap<DockerContainer, QJsonObject> WizardLogic::getInstallConfigsFromWizardPage(
|
||||||
{
|
{
|
||||||
QJsonObject cloakConfig {
|
QJsonObject cloakConfig {
|
||||||
{ config_key::container, ContainerProps::containerToString(DockerContainer::Cloak) },
|
{ config_key::container, ContainerProps::containerToString(DockerContainer::Cloak) },
|
||||||
{ ProtocolProps::protoToString(Protocol::Cloak), QJsonObject {
|
{ ProtocolProps::protoToString(Proto::Cloak), QJsonObject {
|
||||||
{ config_key::site, lineEditHighWebsiteMaskingText() }}
|
{ config_key::site, lineEditHighWebsiteMaskingText() }}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -52,12 +52,12 @@ QJsonObject CloakLogic::getProtocolConfigFromPage(QJsonObject oldConfig)
|
||||||
|
|
||||||
void CloakLogic::onPushButtonSaveClicked()
|
void CloakLogic::onPushButtonSaveClicked()
|
||||||
{
|
{
|
||||||
QJsonObject protocolConfig = m_settings.protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, Protocol::Cloak);
|
QJsonObject protocolConfig = m_settings.protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, Proto::Cloak);
|
||||||
protocolConfig = getProtocolConfigFromPage(protocolConfig);
|
protocolConfig = getProtocolConfigFromPage(protocolConfig);
|
||||||
|
|
||||||
QJsonObject containerConfig = m_settings.containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
|
QJsonObject containerConfig = m_settings.containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
|
||||||
QJsonObject newContainerConfig = containerConfig;
|
QJsonObject newContainerConfig = containerConfig;
|
||||||
newContainerConfig.insert(ProtocolProps::protoToString(Protocol::Cloak), protocolConfig);
|
newContainerConfig.insert(ProtocolProps::protoToString(Proto::Cloak), protocolConfig);
|
||||||
|
|
||||||
UiLogic::PageFunc page_func;
|
UiLogic::PageFunc page_func;
|
||||||
page_func.setEnabledFunc = [this] (bool enabled) -> void {
|
page_func.setEnabledFunc = [this] (bool enabled) -> void {
|
||||||
|
|
|
@ -81,12 +81,12 @@ void OpenVpnLogic::updateProtocolPage(const QJsonObject &openvpnConfig, DockerCo
|
||||||
|
|
||||||
void OpenVpnLogic::onPushButtonProtoOpenVpnSaveClicked()
|
void OpenVpnLogic::onPushButtonProtoOpenVpnSaveClicked()
|
||||||
{
|
{
|
||||||
QJsonObject protocolConfig = m_settings.protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, Protocol::OpenVpn);
|
QJsonObject protocolConfig = m_settings.protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, Proto::OpenVpn);
|
||||||
protocolConfig = getProtocolConfigFromPage(protocolConfig);
|
protocolConfig = getProtocolConfigFromPage(protocolConfig);
|
||||||
|
|
||||||
QJsonObject containerConfig = m_settings.containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
|
QJsonObject containerConfig = m_settings.containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
|
||||||
QJsonObject newContainerConfig = containerConfig;
|
QJsonObject newContainerConfig = containerConfig;
|
||||||
newContainerConfig.insert(ProtocolProps::protoToString(Protocol::OpenVpn), protocolConfig);
|
newContainerConfig.insert(ProtocolProps::protoToString(Proto::OpenVpn), protocolConfig);
|
||||||
|
|
||||||
UiLogic::PageFunc page_proto_openvpn;
|
UiLogic::PageFunc page_proto_openvpn;
|
||||||
page_proto_openvpn.setEnabledFunc = [this] (bool enabled) -> void {
|
page_proto_openvpn.setEnabledFunc = [this] (bool enabled) -> void {
|
||||||
|
|
|
@ -46,12 +46,12 @@ QJsonObject ShadowSocksLogic::getProtocolConfigFromPage(QJsonObject oldConfig)
|
||||||
|
|
||||||
void ShadowSocksLogic::onPushButtonSaveClicked()
|
void ShadowSocksLogic::onPushButtonSaveClicked()
|
||||||
{
|
{
|
||||||
QJsonObject protocolConfig = m_settings.protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, Protocol::ShadowSocks);
|
QJsonObject protocolConfig = m_settings.protocolConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer, Proto::ShadowSocks);
|
||||||
//protocolConfig = getShadowSocksConfigFromPage(protocolConfig);
|
//protocolConfig = getShadowSocksConfigFromPage(protocolConfig);
|
||||||
|
|
||||||
QJsonObject containerConfig = m_settings.containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
|
QJsonObject containerConfig = m_settings.containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
|
||||||
QJsonObject newContainerConfig = containerConfig;
|
QJsonObject newContainerConfig = containerConfig;
|
||||||
newContainerConfig.insert(ProtocolProps::protoToString(Protocol::ShadowSocks), protocolConfig);
|
newContainerConfig.insert(ProtocolProps::protoToString(Proto::ShadowSocks), protocolConfig);
|
||||||
UiLogic::PageFunc page_proto_shadowsocks;
|
UiLogic::PageFunc page_proto_shadowsocks;
|
||||||
page_proto_shadowsocks.setEnabledFunc = [this] (bool enabled) -> void {
|
page_proto_shadowsocks.setEnabledFunc = [this] (bool enabled) -> void {
|
||||||
set_pageEnabled(enabled);
|
set_pageEnabled(enabled);
|
||||||
|
|
|
@ -84,21 +84,21 @@ UiLogic::UiLogic(QObject *parent) :
|
||||||
m_newServerProtocolsLogic = new NewServerProtocolsLogic(this);
|
m_newServerProtocolsLogic = new NewServerProtocolsLogic(this);
|
||||||
m_serverListLogic = new ServerListLogic(this);
|
m_serverListLogic = new ServerListLogic(this);
|
||||||
m_serverSettingsLogic = new ServerSettingsLogic(this);
|
m_serverSettingsLogic = new ServerSettingsLogic(this);
|
||||||
m_serverVpnProtocolsLogic = new ServerContainersLogic(this);
|
m_serverprotocolsLogic = new ServerContainersLogic(this);
|
||||||
m_shareConnectionLogic = new ShareConnectionLogic(this);
|
m_shareConnectionLogic = new ShareConnectionLogic(this);
|
||||||
m_sitesLogic = new SitesLogic(this);
|
m_sitesLogic = new SitesLogic(this);
|
||||||
m_startPageLogic = new StartPageLogic(this);
|
m_startPageLogic = new StartPageLogic(this);
|
||||||
m_vpnLogic = new VpnLogic(this);
|
m_vpnLogic = new VpnLogic(this);
|
||||||
m_wizardLogic = new WizardLogic(this);
|
m_wizardLogic = new WizardLogic(this);
|
||||||
|
|
||||||
m_protocolLogicMap.insert(Protocol::OpenVpn, new OpenVpnLogic(this));
|
m_protocolLogicMap.insert(Proto::OpenVpn, new OpenVpnLogic(this));
|
||||||
m_protocolLogicMap.insert(Protocol::ShadowSocks, new ShadowSocksLogic(this));
|
m_protocolLogicMap.insert(Proto::ShadowSocks, new ShadowSocksLogic(this));
|
||||||
m_protocolLogicMap.insert(Protocol::Cloak, new CloakLogic(this));
|
m_protocolLogicMap.insert(Proto::Cloak, new CloakLogic(this));
|
||||||
//m_protocolLogicMap->insert(Protocol::WireGuard, new WireguardLogic(this));
|
//m_protocolLogicMap->insert(Protocol::WireGuard, new WireguardLogic(this));
|
||||||
|
|
||||||
m_protocolLogicMap.insert(Protocol::Dns, new OtherProtocolsLogic(this));
|
m_protocolLogicMap.insert(Proto::Dns, new OtherProtocolsLogic(this));
|
||||||
m_protocolLogicMap.insert(Protocol::Sftp, new OtherProtocolsLogic(this));
|
m_protocolLogicMap.insert(Proto::Sftp, new OtherProtocolsLogic(this));
|
||||||
m_protocolLogicMap.insert(Protocol::TorWebSite, new OtherProtocolsLogic(this));
|
m_protocolLogicMap.insert(Proto::TorWebSite, new OtherProtocolsLogic(this));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ UiLogic::~UiLogic()
|
||||||
|
|
||||||
emit hide();
|
emit hide();
|
||||||
|
|
||||||
if (m_vpnConnection->connectionState() != VpnProtocol::ConnectionState::Disconnected) {
|
if (m_vpnConnection->connectionState() != VpnProtocol::VpnConnectionState::Disconnected) {
|
||||||
m_vpnConnection->disconnectFromVpn();
|
m_vpnConnection->disconnectFromVpn();
|
||||||
for (int i = 0; i < 50; i++) {
|
for (int i = 0; i < 50; i++) {
|
||||||
qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
|
qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
|
||||||
|
@ -226,7 +226,7 @@ void UiLogic::onUpdateAllPages()
|
||||||
(PageLogicBase *) m_newServerProtocolsLogic,
|
(PageLogicBase *) m_newServerProtocolsLogic,
|
||||||
(PageLogicBase *) m_serverListLogic,
|
(PageLogicBase *) m_serverListLogic,
|
||||||
(PageLogicBase *) m_serverSettingsLogic,
|
(PageLogicBase *) m_serverSettingsLogic,
|
||||||
(PageLogicBase *) m_serverVpnProtocolsLogic,
|
(PageLogicBase *) m_serverprotocolsLogic,
|
||||||
(PageLogicBase *) m_shareConnectionLogic,
|
(PageLogicBase *) m_shareConnectionLogic,
|
||||||
(PageLogicBase *) m_sitesLogic,
|
(PageLogicBase *) m_sitesLogic,
|
||||||
(PageLogicBase *) m_startPageLogic,
|
(PageLogicBase *) m_startPageLogic,
|
||||||
|
@ -620,7 +620,7 @@ void UiLogic::onTrayActivated(QSystemTrayIcon::ActivationReason reason)
|
||||||
emit raise();
|
emit raise();
|
||||||
}
|
}
|
||||||
|
|
||||||
PageProtocolLogicBase *UiLogic::protocolLogic(Protocol p) {
|
PageProtocolLogicBase *UiLogic::protocolLogic(Proto p) {
|
||||||
PageProtocolLogicBase *logic = m_protocolLogicMap.value(p);
|
PageProtocolLogicBase *logic = m_protocolLogicMap.value(p);
|
||||||
if (logic) return logic;
|
if (logic) return logic;
|
||||||
else {
|
else {
|
||||||
|
@ -644,7 +644,7 @@ PageEnumNS::Page UiLogic::currentPage()
|
||||||
return static_cast<PageEnumNS::Page>(currentPageValue());
|
return static_cast<PageEnumNS::Page>(currentPageValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
void UiLogic::setTrayState(VpnProtocol::ConnectionState state)
|
void UiLogic::setTrayState(VpnProtocol::VpnConnectionState state)
|
||||||
{
|
{
|
||||||
QString resourcesPath = ":/images/tray/%1";
|
QString resourcesPath = ":/images/tray/%1";
|
||||||
|
|
||||||
|
|
|
@ -92,8 +92,8 @@ public:
|
||||||
Q_INVOKABLE QString containerDesc(int container);
|
Q_INVOKABLE QString containerDesc(int container);
|
||||||
|
|
||||||
Q_INVOKABLE void onGotoPage(PageEnumNS::Page p, bool reset = true, bool slide = true) { emit goToPage(p, reset, slide); }
|
Q_INVOKABLE void onGotoPage(PageEnumNS::Page p, bool reset = true, bool slide = true) { emit goToPage(p, reset, slide); }
|
||||||
Q_INVOKABLE void onGotoProtocolPage(Protocol p, bool reset = true, bool slide = true) { emit goToProtocolPage(p, reset, slide); }
|
Q_INVOKABLE void onGotoProtocolPage(Proto p, bool reset = true, bool slide = true) { emit goToProtocolPage(p, reset, slide); }
|
||||||
Q_INVOKABLE void onGotoShareProtocolPage(Protocol p, bool reset = true, bool slide = true) { emit goToShareProtocolPage(p, reset, slide); }
|
Q_INVOKABLE void onGotoShareProtocolPage(Proto p, bool reset = true, bool slide = true) { emit goToShareProtocolPage(p, reset, slide); }
|
||||||
|
|
||||||
Q_INVOKABLE void onGotoCurrentProtocolsPage();
|
Q_INVOKABLE void onGotoCurrentProtocolsPage();
|
||||||
|
|
||||||
|
@ -114,8 +114,8 @@ signals:
|
||||||
|
|
||||||
|
|
||||||
void goToPage(PageEnumNS::Page page, bool reset = true, bool slide = true);
|
void goToPage(PageEnumNS::Page page, bool reset = true, bool slide = true);
|
||||||
void goToProtocolPage(Protocol protocol, bool reset = true, bool slide = true);
|
void goToProtocolPage(Proto protocol, bool reset = true, bool slide = true);
|
||||||
void goToShareProtocolPage(Protocol protocol, bool reset = true, bool slide = true);
|
void goToShareProtocolPage(Proto protocol, bool reset = true, bool slide = true);
|
||||||
|
|
||||||
void closePage();
|
void closePage();
|
||||||
void setStartPage(PageEnumNS::Page page, bool slide = true);
|
void setStartPage(PageEnumNS::Page page, bool slide = true);
|
||||||
|
@ -134,7 +134,7 @@ private slots:
|
||||||
// containers - INOUT arg
|
// containers - INOUT arg
|
||||||
void installServer(QMap<DockerContainer, QJsonObject> &containers);
|
void installServer(QMap<DockerContainer, QJsonObject> &containers);
|
||||||
|
|
||||||
void setTrayState(VpnProtocol::ConnectionState state);
|
void setTrayState(VpnProtocol::VpnConnectionState state);
|
||||||
void onTrayActivated(QSystemTrayIcon::ActivationReason reason);
|
void onTrayActivated(QSystemTrayIcon::ActivationReason reason);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -183,14 +183,14 @@ public:
|
||||||
NewServerProtocolsLogic *newServerProtocolsLogic() { return m_newServerProtocolsLogic; }
|
NewServerProtocolsLogic *newServerProtocolsLogic() { return m_newServerProtocolsLogic; }
|
||||||
ServerListLogic *serverListLogic() { return m_serverListLogic; }
|
ServerListLogic *serverListLogic() { return m_serverListLogic; }
|
||||||
ServerSettingsLogic *serverSettingsLogic() { return m_serverSettingsLogic; }
|
ServerSettingsLogic *serverSettingsLogic() { return m_serverSettingsLogic; }
|
||||||
ServerContainersLogic *serverVpnProtocolsLogic() { return m_serverVpnProtocolsLogic; }
|
ServerContainersLogic *serverprotocolsLogic() { return m_serverprotocolsLogic; }
|
||||||
ShareConnectionLogic *shareConnectionLogic() { return m_shareConnectionLogic; }
|
ShareConnectionLogic *shareConnectionLogic() { return m_shareConnectionLogic; }
|
||||||
SitesLogic *sitesLogic() { return m_sitesLogic; }
|
SitesLogic *sitesLogic() { return m_sitesLogic; }
|
||||||
StartPageLogic *startPageLogic() { return m_startPageLogic; }
|
StartPageLogic *startPageLogic() { return m_startPageLogic; }
|
||||||
VpnLogic *vpnLogic() { return m_vpnLogic; }
|
VpnLogic *vpnLogic() { return m_vpnLogic; }
|
||||||
WizardLogic *wizardLogic() { return m_wizardLogic; }
|
WizardLogic *wizardLogic() { return m_wizardLogic; }
|
||||||
|
|
||||||
Q_INVOKABLE PageProtocolLogicBase *protocolLogic(Protocol p);
|
Q_INVOKABLE PageProtocolLogicBase *protocolLogic(Proto p);
|
||||||
|
|
||||||
QObject *qmlRoot() const;
|
QObject *qmlRoot() const;
|
||||||
void setQmlRoot(QObject *newQmlRoot);
|
void setQmlRoot(QObject *newQmlRoot);
|
||||||
|
@ -205,14 +205,14 @@ private:
|
||||||
NewServerProtocolsLogic *m_newServerProtocolsLogic;
|
NewServerProtocolsLogic *m_newServerProtocolsLogic;
|
||||||
ServerListLogic *m_serverListLogic;
|
ServerListLogic *m_serverListLogic;
|
||||||
ServerSettingsLogic *m_serverSettingsLogic;
|
ServerSettingsLogic *m_serverSettingsLogic;
|
||||||
ServerContainersLogic *m_serverVpnProtocolsLogic;
|
ServerContainersLogic *m_serverprotocolsLogic;
|
||||||
ShareConnectionLogic *m_shareConnectionLogic;
|
ShareConnectionLogic *m_shareConnectionLogic;
|
||||||
SitesLogic *m_sitesLogic;
|
SitesLogic *m_sitesLogic;
|
||||||
StartPageLogic *m_startPageLogic;
|
StartPageLogic *m_startPageLogic;
|
||||||
VpnLogic *m_vpnLogic;
|
VpnLogic *m_vpnLogic;
|
||||||
WizardLogic *m_wizardLogic;
|
WizardLogic *m_wizardLogic;
|
||||||
|
|
||||||
QMap<Protocol, PageProtocolLogicBase *> m_protocolLogicMap;
|
QMap<Proto, PageProtocolLogicBase *> m_protocolLogicMap;
|
||||||
|
|
||||||
VpnConnection* m_vpnConnection;
|
VpnConnection* m_vpnConnection;
|
||||||
QThread m_vpnConnectionThread;
|
QThread m_vpnConnectionThread;
|
||||||
|
|
5
client/version.pri
Normal file
5
client/version.pri
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
!defined(VERSION, var):VERSION = 1
|
|
@ -15,6 +15,10 @@
|
||||||
#include <protocols/android_vpnprotocol.h>
|
#include <protocols/android_vpnprotocol.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef Q_OS_IOS
|
||||||
|
#include <protocols/ios_vpnprotocol.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "ipc.h"
|
#include "ipc.h"
|
||||||
#include "core/ipcclient.h"
|
#include "core/ipcclient.h"
|
||||||
|
|
||||||
|
@ -38,7 +42,7 @@ void VpnConnection::onBytesChanged(quint64 receivedBytes, quint64 sentBytes)
|
||||||
emit bytesChanged(receivedBytes, sentBytes);
|
emit bytesChanged(receivedBytes, sentBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VpnConnection::onConnectionStateChanged(VpnProtocol::ConnectionState state)
|
void VpnConnection::onConnectionStateChanged(VpnProtocol::VpnConnectionState state)
|
||||||
{
|
{
|
||||||
if (IpcClient::Interface()) {
|
if (IpcClient::Interface()) {
|
||||||
if (state == VpnProtocol::Connected){
|
if (state == VpnProtocol::Connected){
|
||||||
|
@ -124,10 +128,10 @@ ErrorCode VpnConnection::lastError() const
|
||||||
return m_vpnProtocol.data()->lastError();
|
return m_vpnProtocol.data()->lastError();
|
||||||
}
|
}
|
||||||
|
|
||||||
QMap<Protocol, QString> VpnConnection::getLastVpnConfig(const QJsonObject &containerConfig)
|
QMap<Proto, QString> VpnConnection::getLastVpnConfig(const QJsonObject &containerConfig)
|
||||||
{
|
{
|
||||||
QMap<Protocol, QString> configs;
|
QMap<Proto, QString> configs;
|
||||||
for (Protocol proto: ProtocolProps::allProtocols()) {
|
for (Proto proto: ProtocolProps::allProtocols()) {
|
||||||
|
|
||||||
QString cfg = containerConfig.value(ProtocolProps::protoToString(proto)).toObject().value(config_key::last_config).toString();
|
QString cfg = containerConfig.value(ProtocolProps::protoToString(proto)).toObject().value(config_key::last_config).toString();
|
||||||
|
|
||||||
|
@ -137,7 +141,7 @@ QMap<Protocol, QString> VpnConnection::getLastVpnConfig(const QJsonObject &conta
|
||||||
}
|
}
|
||||||
|
|
||||||
QString VpnConnection::createVpnConfigurationForProto(int serverIndex,
|
QString VpnConnection::createVpnConfigurationForProto(int serverIndex,
|
||||||
const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig, Protocol proto,
|
const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig, Proto proto,
|
||||||
ErrorCode *errorCode)
|
ErrorCode *errorCode)
|
||||||
{
|
{
|
||||||
ErrorCode e = ErrorCode::NoError;
|
ErrorCode e = ErrorCode::NoError;
|
||||||
|
@ -186,7 +190,7 @@ QJsonObject VpnConnection::createVpnConfiguration(int serverIndex,
|
||||||
QJsonObject vpnConfiguration;
|
QJsonObject vpnConfiguration;
|
||||||
|
|
||||||
|
|
||||||
for (ProtocolEnumNS::Protocol proto : ContainerProps::protocolsForContainer(container)) {
|
for (ProtocolEnumNS::Proto proto : ContainerProps::protocolsForContainer(container)) {
|
||||||
QJsonObject vpnConfigData = QJsonDocument::fromJson(
|
QJsonObject vpnConfigData = QJsonDocument::fromJson(
|
||||||
createVpnConfigurationForProto(
|
createVpnConfigurationForProto(
|
||||||
serverIndex, credentials, container, containerConfig, proto, &e).toUtf8()).
|
serverIndex, credentials, container, containerConfig, proto, &e).toUtf8()).
|
||||||
|
@ -200,8 +204,8 @@ QJsonObject VpnConnection::createVpnConfiguration(int serverIndex,
|
||||||
vpnConfiguration.insert(ProtocolProps::key_proto_config_data(proto), vpnConfigData);
|
vpnConfiguration.insert(ProtocolProps::key_proto_config_data(proto), vpnConfigData);
|
||||||
}
|
}
|
||||||
|
|
||||||
Protocol proto = ContainerProps::defaultProtocol(container);
|
Proto proto = ContainerProps::defaultProtocol(container);
|
||||||
vpnConfiguration[config_key::protocol] = ProtocolProps::protoToString(proto);
|
vpnConfiguration[config_key::vpnproto] = ProtocolProps::protoToString(proto);
|
||||||
|
|
||||||
return vpnConfiguration;
|
return vpnConfiguration;
|
||||||
}
|
}
|
||||||
|
@ -212,7 +216,7 @@ void VpnConnection::connectToVpn(int serverIndex,
|
||||||
qDebug() << QString("СonnectToVpn, Server index is %1, container is %2, route mode is")
|
qDebug() << QString("СonnectToVpn, Server index is %1, container is %2, route mode is")
|
||||||
.arg(serverIndex).arg(ContainerProps::containerToString(container)) << m_settings.routeMode();
|
.arg(serverIndex).arg(ContainerProps::containerToString(container)) << m_settings.routeMode();
|
||||||
|
|
||||||
#if !defined (Q_OS_ANDROID) && !defined (Q_OS_IOS)
|
#if !defined (Q_OS_ANDROID) && !defined (Q_OS_IOS)
|
||||||
if (!m_IpcClient) {
|
if (!m_IpcClient) {
|
||||||
m_IpcClient = new IpcClient;
|
m_IpcClient = new IpcClient;
|
||||||
}
|
}
|
||||||
|
@ -228,7 +232,6 @@ void VpnConnection::connectToVpn(int serverIndex,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_remoteAddress = credentials.hostName;
|
m_remoteAddress = credentials.hostName;
|
||||||
|
|
||||||
emit connectionStateChanged(VpnProtocol::Connecting);
|
emit connectionStateChanged(VpnProtocol::Connecting);
|
||||||
|
|
||||||
if (m_vpnProtocol) {
|
if (m_vpnProtocol) {
|
||||||
|
@ -241,24 +244,22 @@ void VpnConnection::connectToVpn(int serverIndex,
|
||||||
}
|
}
|
||||||
|
|
||||||
ErrorCode e = ErrorCode::NoError;
|
ErrorCode e = ErrorCode::NoError;
|
||||||
|
|
||||||
m_vpnConfiguration = createVpnConfiguration(serverIndex, credentials, container, containerConfig);
|
m_vpnConfiguration = createVpnConfiguration(serverIndex, credentials, container, containerConfig);
|
||||||
if (e) {
|
if (e) {
|
||||||
emit connectionStateChanged(VpnProtocol::Error);
|
emit connectionStateChanged(VpnProtocol::Error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined (Q_OS_ANDROID) && !defined (Q_OS_IOS)
|
||||||
#ifndef Q_OS_ANDROID
|
|
||||||
m_vpnProtocol.reset(VpnProtocol::factory(container, m_vpnConfiguration));
|
m_vpnProtocol.reset(VpnProtocol::factory(container, m_vpnConfiguration));
|
||||||
if (!m_vpnProtocol) {
|
if (!m_vpnProtocol) {
|
||||||
emit VpnProtocol::Error;
|
emit VpnProtocol::Error;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_vpnProtocol->prepare();
|
m_vpnProtocol->prepare();
|
||||||
|
#elif defined Q_OS_ANDROID
|
||||||
#else
|
Proto proto = ContainerProps::defaultProtocol(container);
|
||||||
Protocol proto = ContainerProps::defaultProtocol(container);
|
|
||||||
AndroidVpnProtocol *androidVpnProtocol = new AndroidVpnProtocol(proto, m_vpnConfiguration);
|
AndroidVpnProtocol *androidVpnProtocol = new AndroidVpnProtocol(proto, m_vpnConfiguration);
|
||||||
if (!androidVpnProtocol->initialize()) {
|
if (!androidVpnProtocol->initialize()) {
|
||||||
qDebug() << QString("Init failed") ;
|
qDebug() << QString("Init failed") ;
|
||||||
|
@ -266,6 +267,15 @@ void VpnConnection::connectToVpn(int serverIndex,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_vpnProtocol.reset(androidVpnProtocol);
|
m_vpnProtocol.reset(androidVpnProtocol);
|
||||||
|
#elif defined Q_OS_IOS
|
||||||
|
Proto proto = ContainerProps::defaultProtocol(container);
|
||||||
|
IOSVpnProtocol *iosVpnProtocol = new IOSVpnProtocol(proto, m_vpnConfiguration);
|
||||||
|
if (!iosVpnProtocol->initialize()) {
|
||||||
|
qDebug() << QString("Init failed") ;
|
||||||
|
emit VpnProtocol::Error;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_vpnProtocol.reset(iosVpnProtocol);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
connect(m_vpnProtocol.data(), &VpnProtocol::protocolError, this, &VpnConnection::vpnProtocolError);
|
connect(m_vpnProtocol.data(), &VpnProtocol::protocolError, this, &VpnConnection::vpnProtocolError);
|
||||||
|
@ -303,7 +313,7 @@ void VpnConnection::disconnectFromVpn()
|
||||||
// qDebug() << "Disconnect from VPN 2";
|
// qDebug() << "Disconnect from VPN 2";
|
||||||
}
|
}
|
||||||
|
|
||||||
VpnProtocol::ConnectionState VpnConnection::connectionState()
|
VpnProtocol::VpnConnectionState VpnConnection::connectionState()
|
||||||
{
|
{
|
||||||
if (!m_vpnProtocol) return VpnProtocol::Disconnected;
|
if (!m_vpnProtocol) return VpnProtocol::Disconnected;
|
||||||
return m_vpnProtocol->connectionState();
|
return m_vpnProtocol->connectionState();
|
||||||
|
|
|
@ -25,9 +25,9 @@ public:
|
||||||
|
|
||||||
ErrorCode lastError() const;
|
ErrorCode lastError() const;
|
||||||
|
|
||||||
static QMap<Protocol, QString> getLastVpnConfig(const QJsonObject &containerConfig);
|
static QMap<Proto, QString> getLastVpnConfig(const QJsonObject &containerConfig);
|
||||||
QString createVpnConfigurationForProto(int serverIndex,
|
QString createVpnConfigurationForProto(int serverIndex,
|
||||||
const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig, Protocol proto,
|
const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig, Proto proto,
|
||||||
ErrorCode *errorCode = nullptr);
|
ErrorCode *errorCode = nullptr);
|
||||||
|
|
||||||
QJsonObject createVpnConfiguration(int serverIndex,
|
QJsonObject createVpnConfiguration(int serverIndex,
|
||||||
|
@ -39,7 +39,7 @@ public:
|
||||||
bool isConnected() const;
|
bool isConnected() const;
|
||||||
bool isDisconnected() const;
|
bool isDisconnected() const;
|
||||||
|
|
||||||
VpnProtocol::ConnectionState connectionState();
|
VpnProtocol::VpnConnectionState connectionState();
|
||||||
QSharedPointer<VpnProtocol> vpnProtocol() const;
|
QSharedPointer<VpnProtocol> vpnProtocol() const;
|
||||||
|
|
||||||
void addRoutes(const QStringList &ips);
|
void addRoutes(const QStringList &ips);
|
||||||
|
@ -56,14 +56,14 @@ public slots:
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void bytesChanged(quint64 receivedBytes, quint64 sentBytes);
|
void bytesChanged(quint64 receivedBytes, quint64 sentBytes);
|
||||||
void connectionStateChanged(VpnProtocol::ConnectionState state);
|
void connectionStateChanged(VpnProtocol::VpnConnectionState state);
|
||||||
void vpnProtocolError(amnezia::ErrorCode error);
|
void vpnProtocolError(amnezia::ErrorCode error);
|
||||||
|
|
||||||
void serviceIsNotReady();
|
void serviceIsNotReady();
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void onBytesChanged(quint64 receivedBytes, quint64 sentBytes);
|
void onBytesChanged(quint64 receivedBytes, quint64 sentBytes);
|
||||||
void onConnectionStateChanged(VpnProtocol::ConnectionState state);
|
void onConnectionStateChanged(VpnProtocol::VpnConnectionState state);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QSharedPointer<VpnProtocol> m_vpnProtocol;
|
QSharedPointer<VpnProtocol> m_vpnProtocol;
|
||||||
|
|
5
client/xcode.xconfig
Normal file
5
client/xcode.xconfig
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
DEVELOPMENT_TEAM = X7UJ388FXK
|
||||||
|
|
||||||
|
GROUP_ID_IOS = group.ru.kotit.AmneziaVPN.udev
|
||||||
|
APP_ID_IOS = ru.kotit.AmneziaVPN
|
||||||
|
NETEXT_ID_IOS = ru.kotit.AmneziaVPN.network-extension
|
Loading…
Add table
Add a link
Reference in a new issue