[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*
|
||||
*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
|
||||
|
||||
*.autosave
|
||||
|
@ -37,6 +60,7 @@ CMakeLists.txt.user*
|
|||
|
||||
# MACOS files
|
||||
.DS_Store
|
||||
client/.DS_Store
|
||||
._.DS_Store
|
||||
._*
|
||||
*.dmg
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the OpenSSL license (the "License"). You may not use
|
||||
|
|
|
@ -58,9 +58,15 @@ ios: {
|
|||
}
|
||||
}
|
||||
|
||||
CONFIG(iphonesimulator, iphoneos|iphonesimulator) {
|
||||
INCLUDEPATH += $$PWD/ios/simulator
|
||||
HEADERS += $$PWD/ios/simulator/botan_all.h
|
||||
SOURCES += $$PWD/ios/simulator/botan_all.cpp
|
||||
}
|
||||
CONFIG(iphonesimulator, iphoneos|iphonesimulator) {
|
||||
INCLUDEPATH += $$PWD/ios/iphone
|
||||
HEADERS += $$PWD/ios/iphone/botan_all.h
|
||||
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
|
||||
|
||||
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 += \
|
||||
# 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 += \
|
||||
# platforms/ios/iosiaphandler.h \
|
||||
# platforms/ios/iosauthenticationlistener.h \
|
||||
# platforms/ios/ioscontroller.h \
|
||||
# platforms/ios/iosdatamigration.h \
|
||||
# platforms/ios/iosnotificationhandler.h \
|
||||
# platforms/ios/iosutils.h
|
||||
SOURCES += \
|
||||
protocols/ios_vpnprotocol.mm \
|
||||
platforms/ios/json.cpp \
|
||||
platforms/ios/iosglue.mm \
|
||||
platforms/ios/ipaddress.cpp \
|
||||
platforms/ios/ipaddressrange.cpp
|
||||
|
||||
Q_ENABLE_BITCODE.value = NO
|
||||
Q_ENABLE_BITCODE.name = ENABLE_BITCODE
|
||||
|
@ -314,18 +305,28 @@ ios {
|
|||
}
|
||||
}
|
||||
|
||||
CONFIG(iphonesimulator, iphoneos|iphonesimulator) {
|
||||
message("Building for iPhone Simulator")
|
||||
ARCH_TAG = "ios_x86_64"
|
||||
CONFIG(iphonesimulator, iphoneos|iphonesimulator) {
|
||||
message("Building for iPhone Simulator")
|
||||
ARCH_TAG = "ios_x86_64"
|
||||
|
||||
DEFINES += iphonesimulator
|
||||
DEFINES += iphoneos
|
||||
|
||||
LIBS += $$PWD/3rd/OpenSSL/lib/ios/simulator/libcrypto.a
|
||||
LIBS += $$PWD/3rd/OpenSSL/lib/ios/simulator/libssl.a
|
||||
}
|
||||
LIBS += $$PWD/3rd/OpenSSL/lib/ios/iphone/libcrypto.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
|
||||
! 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,
|
||||
DockerContainer container, const QJsonObject &containerConfig, Protocol proto, ErrorCode *errorCode)
|
||||
DockerContainer container, const QJsonObject &containerConfig, Proto proto, ErrorCode *errorCode)
|
||||
{
|
||||
switch (proto) {
|
||||
case Protocol::OpenVpn:
|
||||
case Proto::OpenVpn:
|
||||
return OpenVpnConfigurator::genOpenVpnConfig(credentials, container, containerConfig, errorCode);
|
||||
|
||||
case Protocol::ShadowSocks:
|
||||
case Proto::ShadowSocks:
|
||||
return ShadowSocksConfigurator::genShadowSocksConfig(credentials, container, containerConfig, errorCode);
|
||||
|
||||
case Protocol::Cloak:
|
||||
case Proto::Cloak:
|
||||
return CloakConfigurator::genCloakConfig(credentials, container, containerConfig, errorCode);
|
||||
|
||||
case Protocol::WireGuard:
|
||||
case Proto::WireGuard:
|
||||
return WireguardConfigurator::genWireguardConfig(credentials, container, containerConfig, errorCode);
|
||||
|
||||
case Protocol::Ikev2:
|
||||
case Proto::Ikev2:
|
||||
return Ikev2Configurator::genIkev2Config(credentials, container, containerConfig, errorCode);
|
||||
|
||||
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("$SECONDARY_DNS", m_settings().secondaryDns());
|
||||
|
||||
if (proto == Protocol::OpenVpn) {
|
||||
if (proto == Proto::OpenVpn) {
|
||||
return OpenVpnConfigurator::processConfigWithLocalSettings(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("$SECONDARY_DNS", m_settings().secondaryDns());
|
||||
|
||||
if (proto == Protocol::OpenVpn) {
|
||||
if (proto == Proto::OpenVpn) {
|
||||
return OpenVpnConfigurator::processConfigWithExportSettings(config);
|
||||
}
|
||||
return config;
|
||||
|
@ -66,7 +66,7 @@ QString VpnConfigurator::processConfigWithExportSettings(DockerContainer contain
|
|||
void VpnConfigurator::updateContainerConfigAfterInstallation(DockerContainer container, QJsonObject &containerConfig,
|
||||
const QString &stdOut)
|
||||
{
|
||||
Protocol mainProto = ContainerProps::defaultProtocol(container);
|
||||
Proto mainProto = ContainerProps::defaultProtocol(container);
|
||||
|
||||
if (container == DockerContainer::TorWebSite) {
|
||||
QJsonObject protocol = containerConfig.value(ProtocolProps::protoToString(mainProto)).toObject();
|
||||
|
|
|
@ -13,10 +13,10 @@ class VpnConfigurator
|
|||
public:
|
||||
|
||||
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 processConfigWithExportSettings(DockerContainer container, Protocol proto, QString config);
|
||||
static QString processConfigWithLocalSettings(DockerContainer container, Proto proto, QString config);
|
||||
static QString processConfigWithExportSettings(DockerContainer container, Proto proto, QString config);
|
||||
|
||||
// workaround for containers which is not support normal configaration
|
||||
static void updateContainerConfigAfterInstallation(DockerContainer container,
|
||||
|
|
|
@ -27,29 +27,29 @@ QString ContainerProps::containerToString(amnezia::DockerContainer c){
|
|||
return "amnezia-" + containerKey.toLower();
|
||||
}
|
||||
|
||||
QVector<amnezia::Protocol> ContainerProps::protocolsForContainer(amnezia::DockerContainer container)
|
||||
QVector<amnezia::Proto> ContainerProps::protocolsForContainer(amnezia::DockerContainer container)
|
||||
{
|
||||
switch (container) {
|
||||
case DockerContainer::None:
|
||||
return { };
|
||||
|
||||
case DockerContainer::OpenVpn:
|
||||
return { Protocol::OpenVpn };
|
||||
return { Proto::OpenVpn };
|
||||
|
||||
case DockerContainer::ShadowSocks:
|
||||
return { Protocol::OpenVpn, Protocol::ShadowSocks };
|
||||
return { Proto::OpenVpn, Proto::ShadowSocks };
|
||||
|
||||
case DockerContainer::Cloak:
|
||||
return { Protocol::OpenVpn, Protocol::ShadowSocks, Protocol::Cloak };
|
||||
return { Proto::OpenVpn, Proto::ShadowSocks, Proto::Cloak };
|
||||
|
||||
case DockerContainer::Ipsec:
|
||||
return { Protocol::Ikev2 /*, Protocol::L2tp */};
|
||||
return { Proto::Ikev2 /*, Protocol::L2tp */};
|
||||
|
||||
case DockerContainer::Dns:
|
||||
return { };
|
||||
|
||||
case DockerContainer::Sftp:
|
||||
return { Protocol::Sftp};
|
||||
return { Proto::Sftp};
|
||||
|
||||
default:
|
||||
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) {
|
||||
case DockerContainer::None : return Protocol::Any;
|
||||
case DockerContainer::OpenVpn : return Protocol::OpenVpn;
|
||||
case DockerContainer::Cloak : return Protocol::Cloak;
|
||||
case DockerContainer::ShadowSocks : return Protocol::ShadowSocks;
|
||||
case DockerContainer::WireGuard : return Protocol::WireGuard;
|
||||
case DockerContainer::Ipsec : return Protocol::Ikev2;
|
||||
case DockerContainer::None : return Proto::Any;
|
||||
case DockerContainer::OpenVpn : return Proto::OpenVpn;
|
||||
case DockerContainer::Cloak : return Proto::Cloak;
|
||||
case DockerContainer::ShadowSocks : return Proto::ShadowSocks;
|
||||
case DockerContainer::WireGuard : return Proto::WireGuard;
|
||||
case DockerContainer::Ipsec : return Proto::Ikev2;
|
||||
|
||||
case DockerContainer::TorWebSite : return Protocol::TorWebSite;
|
||||
case DockerContainer::Dns : return Protocol::Dns;
|
||||
case DockerContainer::TorWebSite : return Proto::TorWebSite;
|
||||
case DockerContainer::Dns : return Proto::Dns;
|
||||
//case DockerContainer::FileShare : return Protocol::FileShare;
|
||||
case DockerContainer::Sftp : return Protocol::Sftp;
|
||||
default: return Protocol::Any;
|
||||
case DockerContainer::Sftp : return Proto::Sftp;
|
||||
default: return Proto::Any;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -46,13 +46,13 @@ public:
|
|||
Q_INVOKABLE static QMap<DockerContainer, QString> containerDescriptions();
|
||||
|
||||
// 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);
|
||||
|
||||
// binding between Docker container and main protocol of given container
|
||||
// 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)
|
||||
{
|
||||
Protocol mainProto = ContainerProps::defaultProtocol(container);
|
||||
Proto mainProto = ContainerProps::defaultProtocol(container);
|
||||
|
||||
QJsonObject config {
|
||||
{ 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)
|
||||
{
|
||||
const QJsonObject &openvpnConfig = config.value(ProtocolProps::protoToString(Protocol::OpenVpn)).toObject();
|
||||
const QJsonObject &cloakConfig = config.value(ProtocolProps::protoToString(Protocol::Cloak)).toObject();
|
||||
const QJsonObject &ssConfig = config.value(ProtocolProps::protoToString(Protocol::ShadowSocks)).toObject();
|
||||
const QJsonObject &wireguarConfig = config.value(ProtocolProps::protoToString(Protocol::WireGuard)).toObject();
|
||||
const QJsonObject &sftpConfig = config.value(ProtocolProps::protoToString(Protocol::Sftp)).toObject();
|
||||
const QJsonObject &openvpnConfig = config.value(ProtocolProps::protoToString(Proto::OpenVpn)).toObject();
|
||||
const QJsonObject &cloakConfig = config.value(ProtocolProps::protoToString(Proto::Cloak)).toObject();
|
||||
const QJsonObject &ssConfig = config.value(ProtocolProps::protoToString(Proto::ShadowSocks)).toObject();
|
||||
const QJsonObject &wireguarConfig = config.value(ProtocolProps::protoToString(Proto::WireGuard)).toObject();
|
||||
const QJsonObject &sftpConfig = config.value(ProtocolProps::protoToString(Proto::Sftp)).toObject();
|
||||
//
|
||||
|
||||
Vars vars;
|
||||
|
@ -689,7 +689,7 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential
|
|||
|
||||
|
||||
// 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_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">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>ADJUST_SDK_TOKEN</key>
|
||||
<string>$(ADJUST_SDK_TOKEN)</string>
|
||||
<key>CFBundleAllowMixedLocalizations</key>
|
||||
<true/>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Mozilla VPN</string>
|
||||
<string>AmneziaVPN</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIcons</key>
|
||||
|
@ -49,7 +51,5 @@
|
|||
<string>Light</string>
|
||||
<key>com.wireguard.ios.app_group_id</key>
|
||||
<string>group.org.mozilla.ios.Guardian</string>
|
||||
<key>ADJUST_SDK_TOKEN</key>
|
||||
<string>$(ADJUST_SDK_TOKEN)</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
<!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>
|
||||
<string>$(GROUP_ID_IOS)</string>
|
||||
</array>
|
||||
<key>com.apple.developer.networking.networkextension</key>
|
||||
<array>
|
||||
<string>packet-tunnel-provider</string>
|
||||
</array>
|
||||
</dict>
|
||||
</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);
|
||||
|
||||
qRegisterMetaType<VpnProtocol::ConnectionState>("VpnProtocol::ConnectionState");
|
||||
qRegisterMetaType<VpnProtocol::VpnConnectionState>("VpnProtocol::ConnectionState");
|
||||
qRegisterMetaType<ServerCredentials>("ServerCredentials");
|
||||
|
||||
qRegisterMetaType<DockerContainer>("DockerContainer");
|
||||
qRegisterMetaType<TransportProto>("TransportProto");
|
||||
qRegisterMetaType<Protocol>("Protocol");
|
||||
qRegisterMetaType<Proto>("Protocol");
|
||||
qRegisterMetaType<ServiceType>("ServiceType");
|
||||
qRegisterMetaType<Page>("Page");
|
||||
qRegisterMetaType<VpnProtocol::ConnectionState>("ConnectionState");
|
||||
qRegisterMetaType<VpnProtocol::VpnConnectionState>("ConnectionState");
|
||||
|
||||
qRegisterMetaType<PageProtocolLogicBase *>("PageProtocolLogicBase *");
|
||||
|
||||
|
@ -160,7 +160,7 @@ int main(int argc, char *argv[])
|
|||
engine->rootContext()->setContextProperty("NewServerProtocolsLogic", uiLogic->newServerProtocolsLogic());
|
||||
engine->rootContext()->setContextProperty("ServerListLogic", uiLogic->serverListLogic());
|
||||
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("SitesLogic", uiLogic->sitesLogic());
|
||||
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
|
||||
#define IOSCONTROLLER_H
|
||||
|
||||
#include "controllerimpl.h"
|
||||
#include "vpnprotocol.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class IOSController final : public ControllerImpl {
|
||||
Q_DISABLE_COPY_MOVE(IOSController)
|
||||
class IOSVPNProtocol final : public VpnProtocol {
|
||||
Q_DISABLE_COPY_MOVE(IOSVPNProtocol)
|
||||
|
||||
public:
|
||||
IOSController();
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#ifndef NETWORK_EXTENSION
|
||||
# include "logger.h"
|
||||
//# include "logger.h"
|
||||
#else
|
||||
# import <Foundation/Foundation.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
|
||||
namespace {
|
||||
Logger logger(LOG_IOS, "IOSSGlue");
|
||||
//Logger logger(LOG_IOS, "IOSSGlue");
|
||||
}
|
||||
#endif
|
||||
|
||||
EXPORT void write_msg_to_log(const char* tag, const char* msg) {
|
||||
#ifndef NETWORK_EXTENSION
|
||||
logger.debug() << "Swift log - tag:" << tag << "msg: " << msg;
|
||||
// logger.debug() << "Swift log - tag:" << tag << "msg: " << msg;
|
||||
#else
|
||||
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 {
|
||||
|
||||
private lazy var adapter: WireGuardAdapter = {
|
||||
private lazy var wgAdapter: WireGuardAdapter = {
|
||||
return WireGuardAdapter(with: self) { logLevel, message in
|
||||
wg_log(logLevel.osLogLevel, message: message)
|
||||
}
|
||||
|
@ -29,9 +29,9 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
|||
}
|
||||
|
||||
// Start the tunnel
|
||||
adapter.start(tunnelConfiguration: tunnelConfiguration) { adapterError in
|
||||
wgAdapter.start(tunnelConfiguration: tunnelConfiguration) { adapterError in
|
||||
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)")
|
||||
|
||||
|
@ -72,7 +72,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
|||
override func stopTunnel(with reason: NEProviderStopReason, completionHandler: @escaping () -> Void) {
|
||||
wg_log(.info, staticMessage: "Stopping tunnel")
|
||||
|
||||
adapter.stop { error in
|
||||
wgAdapter.stop { error in
|
||||
ErrorNotifier.removeLastErrorFile()
|
||||
|
||||
if let error = error {
|
||||
|
@ -93,7 +93,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
|||
guard let completionHandler = completionHandler else { return }
|
||||
|
||||
if messageData.count == 1 && messageData[0] == 0 {
|
||||
adapter.getRuntimeConfiguration { settings in
|
||||
wgAdapter.getRuntimeConfiguration { settings in
|
||||
var data: Data?
|
||||
if let settings = settings {
|
||||
data = settings.data(using: .utf8)!
|
||||
|
@ -111,14 +111,14 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
|
|||
|
||||
do {
|
||||
let tunnelConfiguration = try TunnelConfiguration(fromWgQuickConfig: configString)
|
||||
adapter.update(tunnelConfiguration: tunnelConfiguration) { error in
|
||||
wgAdapter.update(tunnelConfiguration: tunnelConfiguration) { error in
|
||||
if let error = error {
|
||||
wg_log(.error, message: "Failed to switch tunnel configuration: \(error.localizedDescription)")
|
||||
completionHandler(nil)
|
||||
return
|
||||
}
|
||||
|
||||
self.adapter.getRuntimeConfiguration { settings in
|
||||
self.wgAdapter.getRuntimeConfiguration { settings in
|
||||
var data: Data?
|
||||
if let settings = settings {
|
||||
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
|
||||
|
||||
AndroidVpnProtocol::AndroidVpnProtocol(Protocol protocol, const QJsonObject &configuration, QObject* parent)
|
||||
AndroidVpnProtocol::AndroidVpnProtocol(Proto protocol, const QJsonObject &configuration, QObject* parent)
|
||||
: VpnProtocol(configuration, parent),
|
||||
m_protocol(protocol),
|
||||
m_binder(this)
|
||||
|
|
|
@ -17,7 +17,7 @@ class AndroidVpnProtocol : public VpnProtocol,
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit AndroidVpnProtocol(Protocol protocol, const QJsonObject& configuration, QObject* parent = nullptr);
|
||||
explicit AndroidVpnProtocol(Proto protocol, const QJsonObject& configuration, QObject* parent = nullptr);
|
||||
static AndroidVpnProtocol* instance();
|
||||
|
||||
virtual ~AndroidVpnProtocol() override = default;
|
||||
|
@ -53,7 +53,7 @@ protected:
|
|||
|
||||
|
||||
private:
|
||||
Protocol m_protocol;
|
||||
Proto m_protocol;
|
||||
|
||||
bool m_serviceConnected = false;
|
||||
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;
|
||||
|
||||
QDebug operator<<(QDebug debug, const amnezia::ProtocolEnumNS::Protocol &p)
|
||||
QDebug operator<<(QDebug debug, const amnezia::ProtocolEnumNS::Proto &p)
|
||||
{
|
||||
QDebugStateSaver saver(debug);
|
||||
debug.nospace() << ProtocolProps::protoToString(p);
|
||||
|
@ -10,29 +10,29 @@ QDebug operator<<(QDebug debug, const amnezia::ProtocolEnumNS::Protocol &p)
|
|||
return debug;
|
||||
}
|
||||
|
||||
amnezia::Protocol ProtocolProps::protoFromString(QString proto){
|
||||
QMetaEnum metaEnum = QMetaEnum::fromType<Protocol>();
|
||||
amnezia::Proto ProtocolProps::protoFromString(QString proto){
|
||||
QMetaEnum metaEnum = QMetaEnum::fromType<Proto>();
|
||||
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;
|
||||
}
|
||||
return Protocol::Any;
|
||||
return Proto::Any;
|
||||
}
|
||||
|
||||
QString ProtocolProps::protoToString(amnezia::Protocol p){
|
||||
if (p == Protocol::Any) return "";
|
||||
QString ProtocolProps::protoToString(amnezia::Proto p){
|
||||
if (p == Proto::Any) return "";
|
||||
|
||||
QMetaEnum metaEnum = QMetaEnum::fromType<Protocol>();
|
||||
QMetaEnum metaEnum = QMetaEnum::fromType<Proto>();
|
||||
QString protoKey = metaEnum.valueToKey(static_cast<int>(p));
|
||||
return protoKey.toLower();
|
||||
}
|
||||
|
||||
QList<amnezia::Protocol> ProtocolProps::allProtocols()
|
||||
QList<amnezia::Proto> ProtocolProps::allProtocols()
|
||||
{
|
||||
QMetaEnum metaEnum = QMetaEnum::fromType<Protocol>();
|
||||
QList<Protocol> all;
|
||||
QMetaEnum metaEnum = QMetaEnum::fromType<Proto>();
|
||||
QList<Proto> all;
|
||||
for (int i = 0; i < metaEnum.keyCount(); ++i) {
|
||||
all.append(static_cast<Protocol>(i));
|
||||
all.append(static_cast<Proto>(i));
|
||||
}
|
||||
|
||||
return all;
|
||||
|
@ -48,7 +48,7 @@ TransportProto ProtocolProps::transportProtoFromString(QString p)
|
|||
return TransportProto::Udp;
|
||||
}
|
||||
|
||||
QString ProtocolProps::transportProtoToString(TransportProto proto, Protocol p)
|
||||
QString ProtocolProps::transportProtoToString(TransportProto proto, Proto p)
|
||||
{
|
||||
QMetaEnum metaEnum = QMetaEnum::fromType<TransportProto>();
|
||||
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 {
|
||||
{Protocol::OpenVpn, "OpenVPN"},
|
||||
{Protocol::ShadowSocks, "ShadowSocks"},
|
||||
{Protocol::Cloak, "Cloak"},
|
||||
{Protocol::WireGuard, "WireGuard"},
|
||||
{Protocol::Ikev2, "IKEv2"},
|
||||
{Protocol::L2tp, "L2TP"},
|
||||
{Proto::OpenVpn, "OpenVPN"},
|
||||
{Proto::ShadowSocks, "ShadowSocks"},
|
||||
{Proto::Cloak, "Cloak"},
|
||||
{Proto::WireGuard, "WireGuard"},
|
||||
{Proto::Ikev2, "IKEv2"},
|
||||
{Proto::L2tp, "L2TP"},
|
||||
|
||||
{Protocol::TorWebSite, "Web site in TOR network"},
|
||||
{Protocol::Dns, "DNS Service"},
|
||||
{Protocol::FileShare, "File Sharing Service"},
|
||||
{Protocol::Sftp, QObject::tr("Sftp service")}
|
||||
{Proto::TorWebSite, "Web site in TOR network"},
|
||||
{Proto::Dns, "DNS Service"},
|
||||
{Proto::FileShare, "File Sharing Service"},
|
||||
{Proto::Sftp, QObject::tr("Sftp service")}
|
||||
};
|
||||
}
|
||||
|
||||
QMap<amnezia::Protocol, QString> ProtocolProps::protocolDescriptions()
|
||||
QMap<amnezia::Proto, QString> ProtocolProps::protocolDescriptions()
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
amnezia::ServiceType ProtocolProps::protocolService(Protocol p)
|
||||
amnezia::ServiceType ProtocolProps::protocolService(Proto p)
|
||||
{
|
||||
switch (p) {
|
||||
case Protocol::Any : return ServiceType::None;
|
||||
case Protocol::OpenVpn : return ServiceType::Vpn;
|
||||
case Protocol::Cloak : return ServiceType::Vpn;
|
||||
case Protocol::ShadowSocks : return ServiceType::Vpn;
|
||||
case Protocol::WireGuard : return ServiceType::Vpn;
|
||||
case Protocol::TorWebSite : return ServiceType::Other;
|
||||
case Protocol::Dns : return ServiceType::Other;
|
||||
case Protocol::FileShare : return ServiceType::Other;
|
||||
case Proto::Any : return ServiceType::None;
|
||||
case Proto::OpenVpn : return ServiceType::Vpn;
|
||||
case Proto::Cloak : return ServiceType::Vpn;
|
||||
case Proto::ShadowSocks : return ServiceType::Vpn;
|
||||
case Proto::WireGuard : return ServiceType::Vpn;
|
||||
case Proto::TorWebSite : return ServiceType::Other;
|
||||
case Proto::Dns : return ServiceType::Other;
|
||||
case Proto::FileShare : return ServiceType::Other;
|
||||
default: return ServiceType::Other;
|
||||
}
|
||||
}
|
||||
|
||||
int ProtocolProps::defaultPort(Protocol p)
|
||||
int ProtocolProps::defaultPort(Proto p)
|
||||
{
|
||||
switch (p) {
|
||||
case Protocol::Any : return -1;
|
||||
case Protocol::OpenVpn : return 1194;
|
||||
case Protocol::Cloak : return 443;
|
||||
case Protocol::ShadowSocks : return 6789;
|
||||
case Protocol::WireGuard : return 51820;
|
||||
case Protocol::Ikev2 : return -1;
|
||||
case Protocol::L2tp : return -1;
|
||||
case Proto::Any : return -1;
|
||||
case Proto::OpenVpn : return 1194;
|
||||
case Proto::Cloak : return 443;
|
||||
case Proto::ShadowSocks : return 6789;
|
||||
case Proto::WireGuard : return 51820;
|
||||
case Proto::Ikev2 : return -1;
|
||||
case Proto::L2tp : return -1;
|
||||
|
||||
case Protocol::TorWebSite : return -1;
|
||||
case Protocol::Dns : return 53;
|
||||
case Protocol::FileShare : return 139;
|
||||
case Protocol::Sftp : return 222;
|
||||
case Proto::TorWebSite : return -1;
|
||||
case Proto::Dns : return 53;
|
||||
case Proto::FileShare : return 139;
|
||||
case Proto::Sftp : return 222;
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
||||
bool ProtocolProps::defaultPortChangeable(Protocol p)
|
||||
bool ProtocolProps::defaultPortChangeable(Proto p)
|
||||
{
|
||||
switch (p) {
|
||||
case Protocol::Any : return false;
|
||||
case Protocol::OpenVpn : return true;
|
||||
case Protocol::Cloak : return true;
|
||||
case Protocol::ShadowSocks : return true;
|
||||
case Protocol::WireGuard : return true;
|
||||
case Protocol::Ikev2 : return false;
|
||||
case Protocol::L2tp : return false;
|
||||
case Proto::Any : return false;
|
||||
case Proto::OpenVpn : return true;
|
||||
case Proto::Cloak : return true;
|
||||
case Proto::ShadowSocks : return true;
|
||||
case Proto::WireGuard : return true;
|
||||
case Proto::Ikev2 : return false;
|
||||
case Proto::L2tp : return false;
|
||||
|
||||
|
||||
case Protocol::TorWebSite : return true;
|
||||
case Protocol::Dns : return false;
|
||||
case Protocol::FileShare : return false;
|
||||
case Proto::TorWebSite : return true;
|
||||
case Proto::Dns : return false;
|
||||
case Proto::FileShare : return false;
|
||||
default: return -1;
|
||||
}
|
||||
}
|
||||
|
||||
TransportProto ProtocolProps::defaultTransportProto(Protocol p)
|
||||
TransportProto ProtocolProps::defaultTransportProto(Proto p)
|
||||
{
|
||||
switch (p) {
|
||||
case Protocol::Any : return TransportProto::Udp;
|
||||
case Protocol::OpenVpn : return TransportProto::Udp;
|
||||
case Protocol::Cloak : return TransportProto::Tcp;
|
||||
case Protocol::ShadowSocks : return TransportProto::Tcp;
|
||||
case Protocol::WireGuard : return TransportProto::Udp;
|
||||
case Protocol::Ikev2 : return TransportProto::Udp;
|
||||
case Protocol::L2tp : return TransportProto::Udp;
|
||||
case Proto::Any : return TransportProto::Udp;
|
||||
case Proto::OpenVpn : return TransportProto::Udp;
|
||||
case Proto::Cloak : return TransportProto::Tcp;
|
||||
case Proto::ShadowSocks : return TransportProto::Tcp;
|
||||
case Proto::WireGuard : return TransportProto::Udp;
|
||||
case Proto::Ikev2 : return TransportProto::Udp;
|
||||
case Proto::L2tp : return TransportProto::Udp;
|
||||
// non-vpn
|
||||
case Protocol::TorWebSite : return TransportProto::Tcp;
|
||||
case Protocol::Dns : return TransportProto::Udp;
|
||||
case Protocol::FileShare : return TransportProto::Udp;
|
||||
case Protocol::Sftp : return TransportProto::Tcp;
|
||||
case Proto::TorWebSite : return TransportProto::Tcp;
|
||||
case Proto::Dns : return TransportProto::Udp;
|
||||
case Proto::FileShare : return TransportProto::Udp;
|
||||
case Proto::Sftp : return TransportProto::Tcp;
|
||||
}
|
||||
}
|
||||
|
||||
bool ProtocolProps::defaultTransportProtoChangeable(Protocol p)
|
||||
bool ProtocolProps::defaultTransportProtoChangeable(Proto p)
|
||||
{
|
||||
switch (p) {
|
||||
case Protocol::Any : return false;
|
||||
case Protocol::OpenVpn : return true;
|
||||
case Protocol::Cloak : return false;
|
||||
case Protocol::ShadowSocks : return false;
|
||||
case Protocol::WireGuard : return false;
|
||||
case Protocol::Ikev2 : return false;
|
||||
case Protocol::L2tp : return false;
|
||||
case Proto::Any : return false;
|
||||
case Proto::OpenVpn : return true;
|
||||
case Proto::Cloak : return false;
|
||||
case Proto::ShadowSocks : return false;
|
||||
case Proto::WireGuard : return false;
|
||||
case Proto::Ikev2 : return false;
|
||||
case Proto::L2tp : return false;
|
||||
// non-vpn
|
||||
case Protocol::TorWebSite : return false;
|
||||
case Protocol::Dns : return false;
|
||||
case Protocol::FileShare : return false;
|
||||
case Protocol::Sftp : return false;
|
||||
case Proto::TorWebSite : return false;
|
||||
case Proto::Dns : return false;
|
||||
case Proto::FileShare : return false;
|
||||
case Proto::Sftp : 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";
|
||||
}
|
||||
|
||||
QString ProtocolProps::key_proto_config_path(Protocol p)
|
||||
QString ProtocolProps::key_proto_config_path(Proto p)
|
||||
{
|
||||
return protoToString(p) + "_config_path";
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ constexpr char containers[] = "containers";
|
|||
constexpr char container[] = "container";
|
||||
constexpr char defaultContainer[] = "defaultContainer";
|
||||
|
||||
constexpr char protocol[] = "protocol";
|
||||
constexpr char vpnproto[] = "protocol";
|
||||
constexpr char protocols[] = "protocols";
|
||||
|
||||
constexpr char remote[] = "remote";
|
||||
|
@ -121,7 +121,7 @@ enum TransportProto {
|
|||
};
|
||||
Q_ENUM_NS(TransportProto)
|
||||
|
||||
enum Protocol {
|
||||
enum Proto {
|
||||
Any = 0,
|
||||
OpenVpn,
|
||||
ShadowSocks,
|
||||
|
@ -136,7 +136,7 @@ enum Protocol {
|
|||
FileShare,
|
||||
Sftp
|
||||
};
|
||||
Q_ENUM_NS(Protocol)
|
||||
Q_ENUM_NS(Proto)
|
||||
|
||||
enum ServiceType {
|
||||
None = 0,
|
||||
|
@ -153,29 +153,29 @@ class ProtocolProps : public QObject
|
|||
Q_OBJECT
|
||||
|
||||
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
|
||||
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 QString protoToString(Protocol p);
|
||||
Q_INVOKABLE static Proto protoFromString(QString p);
|
||||
Q_INVOKABLE static QString protoToString(Proto p);
|
||||
|
||||
Q_INVOKABLE static QMap<Protocol, QString> protocolHumanNames();
|
||||
Q_INVOKABLE static QMap<Protocol, QString> protocolDescriptions();
|
||||
Q_INVOKABLE static QMap<Proto, QString> protocolHumanNames();
|
||||
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 bool defaultPortChangeable(Protocol p);
|
||||
Q_INVOKABLE static int defaultPort(Proto p);
|
||||
Q_INVOKABLE static bool defaultPortChangeable(Proto p);
|
||||
|
||||
Q_INVOKABLE static TransportProto defaultTransportProto(Protocol p);
|
||||
Q_INVOKABLE static bool defaultTransportProtoChangeable(Protocol p);
|
||||
Q_INVOKABLE static TransportProto defaultTransportProto(Proto 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_path(Protocol p);
|
||||
Q_INVOKABLE static QString key_proto_config_data(Proto p);
|
||||
Q_INVOKABLE static QString key_proto_config_path(Proto p);
|
||||
|
||||
};
|
||||
|
||||
|
@ -207,6 +207,6 @@ static void declareQmlProtocolEnum() {
|
|||
|
||||
} // namespace amnezia
|
||||
|
||||
QDebug operator<<(QDebug debug, const amnezia::Protocol &p);
|
||||
QDebug operator<<(QDebug debug, const amnezia::Proto &p);
|
||||
|
||||
#endif // PROTOCOLS_DEFS_H
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
VpnProtocol::VpnProtocol(const QJsonObject &configuration, QObject* parent)
|
||||
: QObject(parent),
|
||||
m_connectionState(ConnectionState::Unknown),
|
||||
m_connectionState(VpnConnectionState::Unknown),
|
||||
m_rawConfig(configuration),
|
||||
m_timeoutTimer(new QTimer(this)),
|
||||
m_receivedBytes(0),
|
||||
|
@ -29,7 +29,7 @@ void VpnProtocol::setLastError(ErrorCode lastError)
|
|||
{
|
||||
m_lastError = lastError;
|
||||
if (lastError){
|
||||
setConnectionState(ConnectionState::Error);
|
||||
setConnectionState(VpnConnectionState::Error);
|
||||
}
|
||||
qCritical().noquote() << "VpnProtocol error, code" << m_lastError << errorString(m_lastError);
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ void VpnProtocol::stopTimeoutTimer()
|
|||
m_timeoutTimer->stop();
|
||||
}
|
||||
|
||||
VpnProtocol::ConnectionState VpnProtocol::connectionState() const
|
||||
VpnProtocol::VpnConnectionState VpnProtocol::connectionState() const
|
||||
{
|
||||
return m_connectionState;
|
||||
}
|
||||
|
@ -70,19 +70,19 @@ void VpnProtocol::setBytesChanged(quint64 receivedBytes, quint64 sentBytes)
|
|||
m_sentBytes = sentBytes;
|
||||
}
|
||||
|
||||
void VpnProtocol::setConnectionState(VpnProtocol::ConnectionState state)
|
||||
void VpnProtocol::setConnectionState(VpnProtocol::VpnConnectionState state)
|
||||
{
|
||||
qDebug() << "VpnProtocol::setConnectionState" << textConnectionState(state);
|
||||
|
||||
if (m_connectionState == state) {
|
||||
return;
|
||||
}
|
||||
if (m_connectionState == ConnectionState::Disconnected && state == ConnectionState::Disconnecting) {
|
||||
if (m_connectionState == VpnConnectionState::Disconnected && state == VpnConnectionState::Disconnecting) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_connectionState = state;
|
||||
if (m_connectionState == ConnectionState::Disconnected) {
|
||||
if (m_connectionState == VpnConnectionState::Disconnected) {
|
||||
m_receivedBytes = 0;
|
||||
m_sentBytes = 0;
|
||||
}
|
||||
|
@ -116,17 +116,17 @@ QString VpnProtocol::routeGateway() const
|
|||
return m_routeGateway;
|
||||
}
|
||||
|
||||
QString VpnProtocol::textConnectionState(ConnectionState connectionState)
|
||||
QString VpnProtocol::textConnectionState(VpnConnectionState connectionState)
|
||||
{
|
||||
switch (connectionState) {
|
||||
case ConnectionState::Unknown: return tr("Unknown");
|
||||
case ConnectionState::Disconnected: return tr("Disconnected");
|
||||
case ConnectionState::Preparing: return tr("Preparing");
|
||||
case ConnectionState::Connecting: return tr("Connecting...");
|
||||
case ConnectionState::Connected: return tr("Connected");
|
||||
case ConnectionState::Disconnecting: return tr("Disconnecting...");
|
||||
case ConnectionState::Reconnecting: return tr("Reconnecting...");
|
||||
case ConnectionState::Error: return tr("Error");
|
||||
case VpnConnectionState::Unknown: return tr("Unknown");
|
||||
case VpnConnectionState::Disconnected: return tr("Disconnected");
|
||||
case VpnConnectionState::Preparing: return tr("Preparing");
|
||||
case VpnConnectionState::Connecting: return tr("Connecting...");
|
||||
case VpnConnectionState::Connected: return tr("Connected");
|
||||
case VpnConnectionState::Disconnecting: return tr("Disconnecting...");
|
||||
case VpnConnectionState::Reconnecting: return tr("Reconnecting...");
|
||||
case VpnConnectionState::Error: return tr("Error");
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
@ -141,10 +141,10 @@ QString VpnProtocol::textConnectionState() const
|
|||
|
||||
bool VpnProtocol::isConnected() const
|
||||
{
|
||||
return m_connectionState == ConnectionState::Connected;
|
||||
return m_connectionState == VpnConnectionState::Connected;
|
||||
}
|
||||
|
||||
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);
|
||||
virtual ~VpnProtocol() override = default;
|
||||
|
||||
enum ConnectionState {Unknown, Disconnected, Preparing, Connecting, Connected, Disconnecting, Reconnecting, Error};
|
||||
Q_ENUM(ConnectionState)
|
||||
enum VpnConnectionState {Unknown, Disconnected, Preparing, Connecting, Connected, Disconnecting, Reconnecting, Error};
|
||||
Q_ENUM(VpnConnectionState)
|
||||
|
||||
static QString textConnectionState(ConnectionState connectionState);
|
||||
static QString textConnectionState(VpnConnectionState connectionState);
|
||||
|
||||
virtual ErrorCode prepare() { return ErrorCode::NoError; }
|
||||
|
||||
|
@ -32,7 +32,7 @@ public:
|
|||
virtual ErrorCode start() = 0;
|
||||
virtual void stop() = 0;
|
||||
|
||||
ConnectionState connectionState() const;
|
||||
VpnConnectionState connectionState() const;
|
||||
ErrorCode lastError() const;
|
||||
QString textConnectionState() const;
|
||||
void setLastError(ErrorCode lastError);
|
||||
|
@ -44,7 +44,7 @@ public:
|
|||
|
||||
signals:
|
||||
void bytesChanged(quint64 receivedBytes, quint64 sentBytes);
|
||||
void connectionStateChanged(VpnProtocol::ConnectionState state);
|
||||
void connectionStateChanged(VpnProtocol::VpnConnectionState state);
|
||||
void timeoutTimerEvent();
|
||||
void protocolError(amnezia::ErrorCode e);
|
||||
|
||||
|
@ -63,9 +63,9 @@ protected:
|
|||
void stopTimeoutTimer();
|
||||
|
||||
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_vpnLocalAddress;
|
||||
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);
|
||||
}
|
||||
|
||||
QJsonObject Settings::protocolConfig(int serverIndex, DockerContainer container, Protocol proto)
|
||||
QJsonObject Settings::protocolConfig(int serverIndex, DockerContainer container, Proto proto)
|
||||
{
|
||||
const QJsonObject &c = containerConfig(serverIndex, container);
|
||||
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);
|
||||
c.insert(ProtocolProps::protoToString(proto), config);
|
||||
|
@ -165,11 +165,11 @@ void Settings::setProtocolConfig(int serverIndex, DockerContainer container, Pro
|
|||
setContainerConfig(serverIndex, container, c);
|
||||
}
|
||||
|
||||
void Settings::clearLastConnectionConfig(int serverIndex, DockerContainer container, Protocol proto)
|
||||
void Settings::clearLastConnectionConfig(int serverIndex, DockerContainer container, Proto proto)
|
||||
{
|
||||
// recursively remove
|
||||
if (proto == Protocol::Any) {
|
||||
for (Protocol p: ContainerProps::protocolsForContainer(container)) {
|
||||
if (proto == Proto::Any) {
|
||||
for (Proto p: ContainerProps::protocolsForContainer(container)) {
|
||||
clearLastConnectionConfig(serverIndex, container, p);
|
||||
}
|
||||
return;
|
||||
|
|
|
@ -52,10 +52,10 @@ public:
|
|||
void setContainerConfig(int serverIndex, DockerContainer container, const QJsonObject &config);
|
||||
void removeContainerConfig(int serverIndex, DockerContainer container);
|
||||
|
||||
QJsonObject protocolConfig(int serverIndex, DockerContainer container, Protocol proto);
|
||||
void setProtocolConfig(int serverIndex, DockerContainer container, Protocol proto, const QJsonObject &config);
|
||||
QJsonObject protocolConfig(int serverIndex, DockerContainer container, Proto proto);
|
||||
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;
|
||||
QString nextAvailableServerName() const;
|
||||
|
|
|
@ -28,7 +28,7 @@ QVariant ProtocolsModel::data(const QModelIndex &index, int role) const
|
|||
return QVariant();
|
||||
}
|
||||
|
||||
Protocol p = ProtocolProps::allProtocols().at(index.row());
|
||||
Proto p = ProtocolProps::allProtocols().at(index.row());
|
||||
if (role == NameRole) {
|
||||
return ProtocolProps::protocolHumanNames().value(p);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ void NewServerProtocolsLogic::onUpdatePage()
|
|||
void NewServerProtocolsLogic::onPushButtonConfigureClicked(DockerContainer c, int port, TransportProto tp)
|
||||
{
|
||||
QMap<DockerContainer, QJsonObject> containers;
|
||||
Protocol mainProto = ContainerProps::defaultProtocol(c);
|
||||
Proto mainProto = ContainerProps::defaultProtocol(c);
|
||||
|
||||
QJsonObject config {
|
||||
{ config_key::container, ContainerProps::containerToString(c) },
|
||||
|
|
|
@ -29,7 +29,7 @@ void ServerContainersLogic::onUpdatePage()
|
|||
emit updatePage();
|
||||
}
|
||||
|
||||
void ServerContainersLogic::onPushButtonProtoSettingsClicked(DockerContainer c, Protocol p)
|
||||
void ServerContainersLogic::onPushButtonProtoSettingsClicked(DockerContainer c, Proto p)
|
||||
{
|
||||
qDebug()<< "ServerContainersLogic::onPushButtonProtoSettingsClicked" << c << p;
|
||||
uiLogic()->selectedDockerContainer = c;
|
||||
|
|
|
@ -12,7 +12,7 @@ class ServerContainersLogic : public PageLogicBase
|
|||
public:
|
||||
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 onPushButtonShareClicked(DockerContainer c);
|
||||
Q_INVOKABLE void onPushButtonRemoveClicked(DockerContainer c);
|
||||
|
|
|
@ -128,5 +128,5 @@ void ServerSettingsLogic::onLineEditDescriptionEditingFinished()
|
|||
void ServerSettingsLogic::onPushButtonShareFullClicked()
|
||||
{
|
||||
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));
|
||||
|
||||
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);
|
||||
|
||||
QString cfg = VpnConfigurator::genVpnProtocolConfig(credentials, uiLogic()->selectedDockerContainer, containerConfig, p, &e);
|
||||
|
@ -115,7 +115,7 @@ void ShareConnectionLogic::onPushButtonShareOpenVpnGenerateClicked()
|
|||
|
||||
ErrorCode e = ErrorCode::NoError;
|
||||
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());
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ void ShareConnectionLogic::onPushButtonShareShadowSocksGenerateClicked()
|
|||
DockerContainer container = uiLogic()->selectedDockerContainer;
|
||||
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();
|
||||
|
||||
if (cfg.isEmpty()) {
|
||||
|
@ -168,7 +168,7 @@ void ShareConnectionLogic::onPushButtonShareCloakGenerateClicked()
|
|||
DockerContainer container = uiLogic()->selectedDockerContainer;
|
||||
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();
|
||||
|
||||
if (cfg.isEmpty()) {
|
||||
|
@ -195,7 +195,7 @@ void ShareConnectionLogic::onPushButtonShareWireGuardGenerateClicked()
|
|||
|
||||
ErrorCode e = ErrorCode::NoError;
|
||||
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();
|
||||
|
||||
set_textEditShareWireGuardCodeText(cfg);
|
||||
|
@ -215,7 +215,7 @@ void ShareConnectionLogic::onPushButtonShareIkev2GenerateClicked()
|
|||
Ikev2Configurator::ConnectionData connData = Ikev2Configurator::prepareIkev2Config(credentials, container);
|
||||
|
||||
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();
|
||||
|
||||
set_textEditShareIkev2CertText(cfg);
|
||||
|
|
|
@ -77,7 +77,7 @@ void VpnLogic::onBytesChanged(quint64 receivedData, quint64 sentData)
|
|||
set_labelSpeedSentText(VpnConnection::bytesPerSecToText(sentData));
|
||||
}
|
||||
|
||||
void VpnLogic::onConnectionStateChanged(VpnProtocol::ConnectionState state)
|
||||
void VpnLogic::onConnectionStateChanged(VpnProtocol::VpnConnectionState state)
|
||||
{
|
||||
qDebug() << "VpnLogic::onConnectionStateChanged" << VpnProtocol::textConnectionState(state);
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ public slots:
|
|||
void onDisconnect();
|
||||
|
||||
void onBytesChanged(quint64 receivedBytes, quint64 sentBytes);
|
||||
void onConnectionStateChanged(VpnProtocol::ConnectionState state);
|
||||
void onConnectionStateChanged(VpnProtocol::VpnConnectionState state);
|
||||
void onVpnProtocolError(amnezia::ErrorCode errorCode);
|
||||
|
||||
signals:
|
||||
|
|
|
@ -22,7 +22,7 @@ QMap<DockerContainer, QJsonObject> WizardLogic::getInstallConfigsFromWizardPage(
|
|||
{
|
||||
QJsonObject cloakConfig {
|
||||
{ config_key::container, ContainerProps::containerToString(DockerContainer::Cloak) },
|
||||
{ ProtocolProps::protoToString(Protocol::Cloak), QJsonObject {
|
||||
{ ProtocolProps::protoToString(Proto::Cloak), QJsonObject {
|
||||
{ config_key::site, lineEditHighWebsiteMaskingText() }}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -52,12 +52,12 @@ QJsonObject CloakLogic::getProtocolConfigFromPage(QJsonObject oldConfig)
|
|||
|
||||
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);
|
||||
|
||||
QJsonObject containerConfig = m_settings.containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
|
||||
QJsonObject newContainerConfig = containerConfig;
|
||||
newContainerConfig.insert(ProtocolProps::protoToString(Protocol::Cloak), protocolConfig);
|
||||
newContainerConfig.insert(ProtocolProps::protoToString(Proto::Cloak), protocolConfig);
|
||||
|
||||
UiLogic::PageFunc page_func;
|
||||
page_func.setEnabledFunc = [this] (bool enabled) -> void {
|
||||
|
|
|
@ -81,12 +81,12 @@ void OpenVpnLogic::updateProtocolPage(const QJsonObject &openvpnConfig, DockerCo
|
|||
|
||||
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);
|
||||
|
||||
QJsonObject containerConfig = m_settings.containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
|
||||
QJsonObject newContainerConfig = containerConfig;
|
||||
newContainerConfig.insert(ProtocolProps::protoToString(Protocol::OpenVpn), protocolConfig);
|
||||
newContainerConfig.insert(ProtocolProps::protoToString(Proto::OpenVpn), protocolConfig);
|
||||
|
||||
UiLogic::PageFunc page_proto_openvpn;
|
||||
page_proto_openvpn.setEnabledFunc = [this] (bool enabled) -> void {
|
||||
|
|
|
@ -46,12 +46,12 @@ QJsonObject ShadowSocksLogic::getProtocolConfigFromPage(QJsonObject oldConfig)
|
|||
|
||||
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);
|
||||
|
||||
QJsonObject containerConfig = m_settings.containerConfig(uiLogic()->selectedServerIndex, uiLogic()->selectedDockerContainer);
|
||||
QJsonObject newContainerConfig = containerConfig;
|
||||
newContainerConfig.insert(ProtocolProps::protoToString(Protocol::ShadowSocks), protocolConfig);
|
||||
newContainerConfig.insert(ProtocolProps::protoToString(Proto::ShadowSocks), protocolConfig);
|
||||
UiLogic::PageFunc page_proto_shadowsocks;
|
||||
page_proto_shadowsocks.setEnabledFunc = [this] (bool enabled) -> void {
|
||||
set_pageEnabled(enabled);
|
||||
|
|
|
@ -84,21 +84,21 @@ UiLogic::UiLogic(QObject *parent) :
|
|||
m_newServerProtocolsLogic = new NewServerProtocolsLogic(this);
|
||||
m_serverListLogic = new ServerListLogic(this);
|
||||
m_serverSettingsLogic = new ServerSettingsLogic(this);
|
||||
m_serverVpnProtocolsLogic = new ServerContainersLogic(this);
|
||||
m_serverprotocolsLogic = new ServerContainersLogic(this);
|
||||
m_shareConnectionLogic = new ShareConnectionLogic(this);
|
||||
m_sitesLogic = new SitesLogic(this);
|
||||
m_startPageLogic = new StartPageLogic(this);
|
||||
m_vpnLogic = new VpnLogic(this);
|
||||
m_wizardLogic = new WizardLogic(this);
|
||||
|
||||
m_protocolLogicMap.insert(Protocol::OpenVpn, new OpenVpnLogic(this));
|
||||
m_protocolLogicMap.insert(Protocol::ShadowSocks, new ShadowSocksLogic(this));
|
||||
m_protocolLogicMap.insert(Protocol::Cloak, new CloakLogic(this));
|
||||
m_protocolLogicMap.insert(Proto::OpenVpn, new OpenVpnLogic(this));
|
||||
m_protocolLogicMap.insert(Proto::ShadowSocks, new ShadowSocksLogic(this));
|
||||
m_protocolLogicMap.insert(Proto::Cloak, new CloakLogic(this));
|
||||
//m_protocolLogicMap->insert(Protocol::WireGuard, new WireguardLogic(this));
|
||||
|
||||
m_protocolLogicMap.insert(Protocol::Dns, new OtherProtocolsLogic(this));
|
||||
m_protocolLogicMap.insert(Protocol::Sftp, new OtherProtocolsLogic(this));
|
||||
m_protocolLogicMap.insert(Protocol::TorWebSite, new OtherProtocolsLogic(this));
|
||||
m_protocolLogicMap.insert(Proto::Dns, new OtherProtocolsLogic(this));
|
||||
m_protocolLogicMap.insert(Proto::Sftp, new OtherProtocolsLogic(this));
|
||||
m_protocolLogicMap.insert(Proto::TorWebSite, new OtherProtocolsLogic(this));
|
||||
|
||||
}
|
||||
|
||||
|
@ -108,7 +108,7 @@ UiLogic::~UiLogic()
|
|||
|
||||
emit hide();
|
||||
|
||||
if (m_vpnConnection->connectionState() != VpnProtocol::ConnectionState::Disconnected) {
|
||||
if (m_vpnConnection->connectionState() != VpnProtocol::VpnConnectionState::Disconnected) {
|
||||
m_vpnConnection->disconnectFromVpn();
|
||||
for (int i = 0; i < 50; i++) {
|
||||
qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
|
||||
|
@ -226,7 +226,7 @@ void UiLogic::onUpdateAllPages()
|
|||
(PageLogicBase *) m_newServerProtocolsLogic,
|
||||
(PageLogicBase *) m_serverListLogic,
|
||||
(PageLogicBase *) m_serverSettingsLogic,
|
||||
(PageLogicBase *) m_serverVpnProtocolsLogic,
|
||||
(PageLogicBase *) m_serverprotocolsLogic,
|
||||
(PageLogicBase *) m_shareConnectionLogic,
|
||||
(PageLogicBase *) m_sitesLogic,
|
||||
(PageLogicBase *) m_startPageLogic,
|
||||
|
@ -620,7 +620,7 @@ void UiLogic::onTrayActivated(QSystemTrayIcon::ActivationReason reason)
|
|||
emit raise();
|
||||
}
|
||||
|
||||
PageProtocolLogicBase *UiLogic::protocolLogic(Protocol p) {
|
||||
PageProtocolLogicBase *UiLogic::protocolLogic(Proto p) {
|
||||
PageProtocolLogicBase *logic = m_protocolLogicMap.value(p);
|
||||
if (logic) return logic;
|
||||
else {
|
||||
|
@ -644,7 +644,7 @@ PageEnumNS::Page UiLogic::currentPage()
|
|||
return static_cast<PageEnumNS::Page>(currentPageValue());
|
||||
}
|
||||
|
||||
void UiLogic::setTrayState(VpnProtocol::ConnectionState state)
|
||||
void UiLogic::setTrayState(VpnProtocol::VpnConnectionState state)
|
||||
{
|
||||
QString resourcesPath = ":/images/tray/%1";
|
||||
|
||||
|
|
|
@ -92,8 +92,8 @@ public:
|
|||
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 onGotoProtocolPage(Protocol 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 onGotoProtocolPage(Proto p, bool reset = true, bool slide = true) { emit goToProtocolPage(p, reset, slide); }
|
||||
Q_INVOKABLE void onGotoShareProtocolPage(Proto p, bool reset = true, bool slide = true) { emit goToShareProtocolPage(p, reset, slide); }
|
||||
|
||||
Q_INVOKABLE void onGotoCurrentProtocolsPage();
|
||||
|
||||
|
@ -114,8 +114,8 @@ signals:
|
|||
|
||||
|
||||
void goToPage(PageEnumNS::Page page, bool reset = true, bool slide = true);
|
||||
void goToProtocolPage(Protocol protocol, bool reset = true, bool slide = true);
|
||||
void goToShareProtocolPage(Protocol protocol, bool reset = true, bool slide = true);
|
||||
void goToProtocolPage(Proto protocol, bool reset = true, bool slide = true);
|
||||
void goToShareProtocolPage(Proto protocol, bool reset = true, bool slide = true);
|
||||
|
||||
void closePage();
|
||||
void setStartPage(PageEnumNS::Page page, bool slide = true);
|
||||
|
@ -134,7 +134,7 @@ private slots:
|
|||
// containers - INOUT arg
|
||||
void installServer(QMap<DockerContainer, QJsonObject> &containers);
|
||||
|
||||
void setTrayState(VpnProtocol::ConnectionState state);
|
||||
void setTrayState(VpnProtocol::VpnConnectionState state);
|
||||
void onTrayActivated(QSystemTrayIcon::ActivationReason reason);
|
||||
|
||||
private:
|
||||
|
@ -183,14 +183,14 @@ public:
|
|||
NewServerProtocolsLogic *newServerProtocolsLogic() { return m_newServerProtocolsLogic; }
|
||||
ServerListLogic *serverListLogic() { return m_serverListLogic; }
|
||||
ServerSettingsLogic *serverSettingsLogic() { return m_serverSettingsLogic; }
|
||||
ServerContainersLogic *serverVpnProtocolsLogic() { return m_serverVpnProtocolsLogic; }
|
||||
ServerContainersLogic *serverprotocolsLogic() { return m_serverprotocolsLogic; }
|
||||
ShareConnectionLogic *shareConnectionLogic() { return m_shareConnectionLogic; }
|
||||
SitesLogic *sitesLogic() { return m_sitesLogic; }
|
||||
StartPageLogic *startPageLogic() { return m_startPageLogic; }
|
||||
VpnLogic *vpnLogic() { return m_vpnLogic; }
|
||||
WizardLogic *wizardLogic() { return m_wizardLogic; }
|
||||
|
||||
Q_INVOKABLE PageProtocolLogicBase *protocolLogic(Protocol p);
|
||||
Q_INVOKABLE PageProtocolLogicBase *protocolLogic(Proto p);
|
||||
|
||||
QObject *qmlRoot() const;
|
||||
void setQmlRoot(QObject *newQmlRoot);
|
||||
|
@ -205,14 +205,14 @@ private:
|
|||
NewServerProtocolsLogic *m_newServerProtocolsLogic;
|
||||
ServerListLogic *m_serverListLogic;
|
||||
ServerSettingsLogic *m_serverSettingsLogic;
|
||||
ServerContainersLogic *m_serverVpnProtocolsLogic;
|
||||
ServerContainersLogic *m_serverprotocolsLogic;
|
||||
ShareConnectionLogic *m_shareConnectionLogic;
|
||||
SitesLogic *m_sitesLogic;
|
||||
StartPageLogic *m_startPageLogic;
|
||||
VpnLogic *m_vpnLogic;
|
||||
WizardLogic *m_wizardLogic;
|
||||
|
||||
QMap<Protocol, PageProtocolLogicBase *> m_protocolLogicMap;
|
||||
QMap<Proto, PageProtocolLogicBase *> m_protocolLogicMap;
|
||||
|
||||
VpnConnection* m_vpnConnection;
|
||||
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>
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_IOS
|
||||
#include <protocols/ios_vpnprotocol.h>
|
||||
#endif
|
||||
|
||||
#include "ipc.h"
|
||||
#include "core/ipcclient.h"
|
||||
|
||||
|
@ -38,7 +42,7 @@ void VpnConnection::onBytesChanged(quint64 receivedBytes, quint64 sentBytes)
|
|||
emit bytesChanged(receivedBytes, sentBytes);
|
||||
}
|
||||
|
||||
void VpnConnection::onConnectionStateChanged(VpnProtocol::ConnectionState state)
|
||||
void VpnConnection::onConnectionStateChanged(VpnProtocol::VpnConnectionState state)
|
||||
{
|
||||
if (IpcClient::Interface()) {
|
||||
if (state == VpnProtocol::Connected){
|
||||
|
@ -124,10 +128,10 @@ ErrorCode VpnConnection::lastError() const
|
|||
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;
|
||||
for (Protocol proto: ProtocolProps::allProtocols()) {
|
||||
QMap<Proto, QString> configs;
|
||||
for (Proto proto: ProtocolProps::allProtocols()) {
|
||||
|
||||
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,
|
||||
const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig, Protocol proto,
|
||||
const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig, Proto proto,
|
||||
ErrorCode *errorCode)
|
||||
{
|
||||
ErrorCode e = ErrorCode::NoError;
|
||||
|
@ -186,7 +190,7 @@ QJsonObject VpnConnection::createVpnConfiguration(int serverIndex,
|
|||
QJsonObject vpnConfiguration;
|
||||
|
||||
|
||||
for (ProtocolEnumNS::Protocol proto : ContainerProps::protocolsForContainer(container)) {
|
||||
for (ProtocolEnumNS::Proto proto : ContainerProps::protocolsForContainer(container)) {
|
||||
QJsonObject vpnConfigData = QJsonDocument::fromJson(
|
||||
createVpnConfigurationForProto(
|
||||
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);
|
||||
}
|
||||
|
||||
Protocol proto = ContainerProps::defaultProtocol(container);
|
||||
vpnConfiguration[config_key::protocol] = ProtocolProps::protoToString(proto);
|
||||
Proto proto = ContainerProps::defaultProtocol(container);
|
||||
vpnConfiguration[config_key::vpnproto] = ProtocolProps::protoToString(proto);
|
||||
|
||||
return vpnConfiguration;
|
||||
}
|
||||
|
@ -212,7 +216,7 @@ void VpnConnection::connectToVpn(int serverIndex,
|
|||
qDebug() << QString("СonnectToVpn, Server index is %1, container is %2, route mode is")
|
||||
.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) {
|
||||
m_IpcClient = new IpcClient;
|
||||
}
|
||||
|
@ -228,7 +232,6 @@ void VpnConnection::connectToVpn(int serverIndex,
|
|||
#endif
|
||||
|
||||
m_remoteAddress = credentials.hostName;
|
||||
|
||||
emit connectionStateChanged(VpnProtocol::Connecting);
|
||||
|
||||
if (m_vpnProtocol) {
|
||||
|
@ -241,24 +244,22 @@ void VpnConnection::connectToVpn(int serverIndex,
|
|||
}
|
||||
|
||||
ErrorCode e = ErrorCode::NoError;
|
||||
|
||||
m_vpnConfiguration = createVpnConfiguration(serverIndex, credentials, container, containerConfig);
|
||||
if (e) {
|
||||
emit connectionStateChanged(VpnProtocol::Error);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#ifndef Q_OS_ANDROID
|
||||
#if !defined (Q_OS_ANDROID) && !defined (Q_OS_IOS)
|
||||
m_vpnProtocol.reset(VpnProtocol::factory(container, m_vpnConfiguration));
|
||||
if (!m_vpnProtocol) {
|
||||
emit VpnProtocol::Error;
|
||||
return;
|
||||
}
|
||||
|
||||
m_vpnProtocol->prepare();
|
||||
|
||||
#else
|
||||
Protocol proto = ContainerProps::defaultProtocol(container);
|
||||
#elif defined Q_OS_ANDROID
|
||||
Proto proto = ContainerProps::defaultProtocol(container);
|
||||
AndroidVpnProtocol *androidVpnProtocol = new AndroidVpnProtocol(proto, m_vpnConfiguration);
|
||||
if (!androidVpnProtocol->initialize()) {
|
||||
qDebug() << QString("Init failed") ;
|
||||
|
@ -266,6 +267,15 @@ void VpnConnection::connectToVpn(int serverIndex,
|
|||
return;
|
||||
}
|
||||
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
|
||||
|
||||
connect(m_vpnProtocol.data(), &VpnProtocol::protocolError, this, &VpnConnection::vpnProtocolError);
|
||||
|
@ -303,7 +313,7 @@ void VpnConnection::disconnectFromVpn()
|
|||
// qDebug() << "Disconnect from VPN 2";
|
||||
}
|
||||
|
||||
VpnProtocol::ConnectionState VpnConnection::connectionState()
|
||||
VpnProtocol::VpnConnectionState VpnConnection::connectionState()
|
||||
{
|
||||
if (!m_vpnProtocol) return VpnProtocol::Disconnected;
|
||||
return m_vpnProtocol->connectionState();
|
||||
|
|
|
@ -25,9 +25,9 @@ public:
|
|||
|
||||
ErrorCode lastError() const;
|
||||
|
||||
static QMap<Protocol, QString> getLastVpnConfig(const QJsonObject &containerConfig);
|
||||
static QMap<Proto, QString> getLastVpnConfig(const QJsonObject &containerConfig);
|
||||
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);
|
||||
|
||||
QJsonObject createVpnConfiguration(int serverIndex,
|
||||
|
@ -39,7 +39,7 @@ public:
|
|||
bool isConnected() const;
|
||||
bool isDisconnected() const;
|
||||
|
||||
VpnProtocol::ConnectionState connectionState();
|
||||
VpnProtocol::VpnConnectionState connectionState();
|
||||
QSharedPointer<VpnProtocol> vpnProtocol() const;
|
||||
|
||||
void addRoutes(const QStringList &ips);
|
||||
|
@ -56,14 +56,14 @@ public slots:
|
|||
|
||||
signals:
|
||||
void bytesChanged(quint64 receivedBytes, quint64 sentBytes);
|
||||
void connectionStateChanged(VpnProtocol::ConnectionState state);
|
||||
void connectionStateChanged(VpnProtocol::VpnConnectionState state);
|
||||
void vpnProtocolError(amnezia::ErrorCode error);
|
||||
|
||||
void serviceIsNotReady();
|
||||
|
||||
protected slots:
|
||||
void onBytesChanged(quint64 receivedBytes, quint64 sentBytes);
|
||||
void onConnectionStateChanged(VpnProtocol::ConnectionState state);
|
||||
void onConnectionStateChanged(VpnProtocol::VpnConnectionState state);
|
||||
|
||||
protected:
|
||||
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