Compare commits

...

31 Commits

Author SHA1 Message Date
Fedotov Anton
0d0c29493b definition of the routing string to be deleted for wg and ikev2 connections 2021-12-10 13:02:54 +03:00
pokamest
4abfc58ad0 Merge branch 'dev' into dev-netadapters 2021-12-04 18:42:14 +03:00
pokamest
4c2941acf0 Merge pull request #45 from amnezia-vpn/ios-wireguard
Ios wireguard
2021-12-04 16:27:46 +03:00
pokamest
40791a9cd4 Merge branch 'dev' into ios-wireguard 2021-12-04 05:24:11 -08:00
pokamest
4d374581b5 isWorkingOnPlatform function added 2021-12-04 16:13:34 +03:00
Fedotov Anton
5245fe103c increase timeout after connection for getting info about routes 2021-12-02 22:58:44 +03:00
Fedotov Anton
3dd207a3a1 unused code commented out 2021-12-02 20:36:56 +03:00
Fedotov Anton
1a16a61ced added the method to get the route table 2021-12-02 15:08:54 +03:00
Alex Kh
4976dc3a4c Added missing parameters for init and connect 2021-12-01 20:02:54 +04:00
pokamest
9e0fd7d51e iOS build fixes 2021-11-30 12:53:12 -08:00
pokamest
bf8b3c3b2f Merge branch 'dev' into ios-wireguard 2021-11-30 21:51:06 +03:00
Alex Kh
38336fdb02 Removed build folders from being tracked 2021-11-30 17:13:00 +04:00
Alex Kh
7c7f77adc6 [WIP] Added wireguard, prepare to test and debug 2021-11-30 16:56:24 +04:00
pokamest
340639b3c8 Code cleanup 2021-11-28 19:28:51 +03:00
pokamest
dd427f89bc VPN modes ui fix 2021-11-28 19:14:12 +03:00
pokamest
051487d6ef Comments cleanup 2021-11-28 19:13:33 +03:00
pokamest
97d3b92988 Merge branch 'dev' into dev-netadapters 2021-11-28 17:42:11 +03:00
pokamest
d28a2ebc57 NotificationHandler systemtray 2021-11-28 17:28:25 +03:00
pokamest
67d413956d AndroidController reimpl 2021-11-26 17:43:02 +03:00
Fedotov Anton
8262d743d8 WMI dependency removed, all available protocols checked 2021-11-24 13:35:37 +03:00
Fedotov Anton
18654ca4ef the information about ikev2 was got 2021-11-24 03:05:40 +03:00
Fedotov Anton
44bc831b7f Object that receives information about network adapters was included in the source files tree 2021-11-24 03:03:36 +03:00
Fedotov Anton
3424068993 Changes to the mechanics of obtaining data about network adapters 2021-11-24 03:00:27 +03:00
pokamest
e644575bc5 Merge branch 'dev' into ios_main 2021-11-22 03:41:38 -08:00
pokamest
0291ba8cb5 Server add fix 2021-11-22 14:40:23 +03:00
pokamest
622a390b23 Windows deploy fixed 2021-11-22 14:34:33 +03:00
ToshDev
90a92bea1b Collection of network information about the adapter through which the connection to the server is made 2021-11-22 14:21:56 +03:00
pokamest
2e92705f9c build fix 2021-11-22 01:42:16 -08:00
pokamest
c6548afa1b Merge branch 'dev' into ios_main 2021-11-22 00:08:34 -08:00
pokamest
fd9d54d2dd Merge branch 'dev' into ios_main 2021-11-18 03:48:34 -08:00
pokamest
7701efc704 iOS Wireguard 2021-10-23 04:26:47 -07:00
216 changed files with 12151 additions and 959 deletions

25
.gitignore vendored
View File

@@ -24,6 +24,30 @@ ui_*.h
Makefile*
*build-*
# Qt-es
client/Debug-iphoneos/
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 +61,7 @@ CMakeLists.txt.user*
# MACOS files
.DS_Store
client/.DS_Store
._.DS_Store
._*
*.dmg

3
.gitmodules vendored
View File

@@ -4,3 +4,6 @@
[submodule "client/3rd/wireguard-tools"]
path = client/3rd/wireguard-tools
url = https://github.com/WireGuard/wireguard-tools/
[submodule "client/3rd/wireguard-apple"]
path = client/3rd/wireguard-apple
url = https://github.com/WireGuard/wireguard-apple

View File

@@ -0,0 +1,7 @@
HEADERS += \
3rd/AdpInfo/netadpinfo.h \
win32: {
SOURCES += \
3rd/AdpInfo/win_netadpinfo.cc \
}

View File

@@ -0,0 +1,71 @@
#pragma once
#include <vector>
#include <string>
#include <tuple>
#include <memory>
namespace adpinfo{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// {false,""} - no error
// {true,"descr"} - error with description
using RET_TYPE = std::tuple<bool, std::string>;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/*
* Getting the route table
*/
typedef struct route_table{
std::string szDestIp{};
std::string szMaskIp{};
std::string szGatewayIp{};
std::string szInterfaceIp{};
unsigned long ulIfIndex{};
}route_table;
std::vector</*std::tuple<std::string,std::string,std::string,std::string>*/route_table>get_route_table(std::string_view);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/*
* The object uses for collect the information about active network adapters/interfaces
*/
class NetAdpInfo final{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class Adapter{
std::string name{};
std::string descr{};
std::string route{};
std::string address{};
std::string gateway{};
public:
explicit Adapter() = default;
~Adapter() = default;
void set_name(std::string_view);
std::string_view get_name()const;
void set_description(std::string_view);
std::string_view get_description()const;
void set_route_gateway(std::string_view);
std::string_view get_route_gateway()const;
void set_local_address(std::string_view);
std::string_view get_local_address()const;
void set_local_gateway(std::string_view);
std::string_view get_local_gateway()const;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int16_t _index_of_adapter{};
std::vector<std::shared_ptr<Adapter>>_adapters{};
RET_TYPE collect_adapters_data();
public:
explicit NetAdpInfo() = default;
~NetAdpInfo() = default;
RET_TYPE get_adapter_info(std::string_view );
std::string_view get_adapter_route_gateway()const;
std::string_view get_adapter_local_address()const;
std::string_view get_adapter_local_gateway()const;
};
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
} //end namespace

View File

@@ -0,0 +1,321 @@
#include "netadpinfo.h"
#include <QDebug>
#include <algorithm>
#include <iterator>
#include <cassert>
#include <windows.h>
#include <iphlpapi.h>
#pragma comment(lib, "iphlpapi.lib")
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//static std::string convert_wide_to_ansi(const std::wstring& widestring) {
// auto nchars = WideCharToMultiByte(
// CP_ACP,
// 0,
// widestring.c_str(),
// static_cast<int>(widestring.length() + 1),
// nullptr,
// 0,
// nullptr,
// nullptr);
// std::string converted_string{};
// converted_string.resize(nchars);
// WideCharToMultiByte(CP_ACP,
// 0,
// widestring.c_str(),
// -1,
// &converted_string[0],
// static_cast<int>(widestring.length()),
// nullptr,
// nullptr);
// return converted_string;
//}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//static std::string get_founded_route(std::string_view ip_address){
// MIB_IPFORWARDROW br{0};
// ZeroMemory(&br, sizeof(MIB_IPFORWARDROW));
// struct in_addr ia;
// std::string sTmp{};
// DWORD dwRes = GetBestRoute(inet_addr(ip_address.data()), 0, &br);
// if( dwRes == NO_ERROR ){
// ia.S_un.S_addr = (u_long) br.dwForwardDest;
// sTmp = inet_ntoa(ia);
// qDebug()<<"Best Route:"<< sTmp.data();
// }
// return sTmp;
//}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
static std::string get_route_gateway()
{
std::string route_gateway{};
PMIB_IPFORWARDTABLE pIpForwardTable{nullptr};
DWORD dwSize = 0;
BOOL bOrder = FALSE;
struct in_addr IpAddr;
char szGatewayIp[128]{'\0'};
DWORD dwStatus = GetIpForwardTable(pIpForwardTable, &dwSize, bOrder);
if (dwStatus == ERROR_INSUFFICIENT_BUFFER) {
if (!(pIpForwardTable = (PMIB_IPFORWARDTABLE) malloc(dwSize))) {
return {"Out of memory"};
}
dwStatus = GetIpForwardTable(pIpForwardTable, &dwSize, bOrder);
}
if (dwStatus != ERROR_SUCCESS) {
if (pIpForwardTable)
free(pIpForwardTable);
return {"getIpForwardTable failed"};
}
const DWORD end = pIpForwardTable->dwNumEntries;
for (DWORD i = 0; i < end; i++) {
if (pIpForwardTable->table[i].dwForwardDest == 0) {
IpAddr.S_un.S_addr =
(u_long) pIpForwardTable->table[i].dwForwardNextHop;
strcpy_s(szGatewayIp, sizeof (szGatewayIp), inet_ntoa(IpAddr));
route_gateway = std::string(szGatewayIp);
break;
}
}
if (pIpForwardTable)
free(pIpForwardTable);
return route_gateway;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
static std::string get_interface_ip(DWORD index){
std::string _ipaddr{'\0'};
std::vector<BYTE> buffer{};
IP_ADAPTER_INFO *adapter_info{nullptr};
DWORD result{ERROR_BUFFER_OVERFLOW};
ULONG buffer_len = sizeof(IP_ADAPTER_INFO) * 10;
while (result == ERROR_BUFFER_OVERFLOW){
buffer.resize(buffer_len);
adapter_info = reinterpret_cast<IP_ADAPTER_INFO*>(&buffer[0]);
result = GetAdaptersInfo(adapter_info, &buffer_len);
if (result == ERROR_NO_DATA){
return _ipaddr;
}
}//end while
if (result != NO_ERROR){
return _ipaddr;
}
IP_ADAPTER_INFO *adapter_iterator = adapter_info;
while(adapter_iterator){
if (adapter_iterator->Index == index)
break;
adapter_iterator = adapter_iterator->Next;
}//end while
if ( adapter_iterator != nullptr || adapter_iterator != 0x0 || adapter_iterator != NULL )
_ipaddr = std::string(adapter_iterator->IpAddressList.IpAddress.String, 16);
else
_ipaddr = "127.0.0.1";
return _ipaddr;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
namespace adpinfo {
std::vector<route_table>get_route_table(std::string_view ipifaddrs){
/*std::tuple<std::string, std::string, std::string, std::string >*/
std::vector<route_table>ret_table{};
PMIB_IPFORWARDTABLE p_table{nullptr};
struct in_addr ip_addr{};
DWORD size{};
p_table = (MIB_IPFORWARDTABLE *) HeapAlloc(GetProcessHeap(), 0, (sizeof (MIB_IPFORWARDTABLE)));
if (p_table == nullptr)
{
return ret_table;
}
if (GetIpForwardTable(p_table, &size, 0) == ERROR_INSUFFICIENT_BUFFER) {
HeapFree(GetProcessHeap(), 0, p_table);
p_table = (MIB_IPFORWARDTABLE *) HeapAlloc(GetProcessHeap(), 0, size);
if (p_table == nullptr) {
return ret_table;
}
}
DWORD ret = GetIpForwardTable(p_table, &size, 0);
if (ret == NO_ERROR) {
const int &numEntries = static_cast<int>(p_table->dwNumEntries);
for (int i = 0; i <numEntries; ++i) {
char szDestIp[128]{};
char szMaskIp[128]{};
char szGatewayIp[128]{};
char szInterfaceIp[21]{};
ip_addr.S_un.S_addr = (u_long) p_table->table[i].dwForwardDest;
strcpy_s(szDestIp, sizeof (szDestIp), inet_ntoa(ip_addr));
ip_addr.S_un.S_addr = (u_long) p_table->table[i].dwForwardMask;
strcpy_s(szMaskIp, sizeof (szMaskIp), inet_ntoa(ip_addr));
ip_addr.S_un.S_addr = (u_long) p_table->table[i].dwForwardNextHop;
strcpy_s(szGatewayIp, sizeof (szGatewayIp), inet_ntoa(ip_addr));
const auto &ifname = get_interface_ip(p_table->table[i].dwForwardIfIndex);
const auto &ifnameSize = ifname.length() + 1;
strcpy_s(szInterfaceIp, ifnameSize, ifname.data());
if (ipifaddrs.length() == 0){
//std::make_tuple(std::string(szDestIp), std::string(szMaskIp), std::string(szGatewayIp), std::string(szInterfaceIp));
const route_table &mt = {
std::string(szDestIp),
std::string(szMaskIp),
std::string(szGatewayIp),
std::string(szInterfaceIp),
p_table->table[i].dwForwardIfIndex
};
ret_table.emplace_back(mt);
}else{
bool in_not_empty = (ifname.find(ipifaddrs) != std::string::npos);
//bool in_as_destIp = ( std::string(szDestIp).find(ipifaddrs) != std::string::npos);
bool destIp_as_zero = (std::string(szDestIp).find("0.0.0.0") != std::string::npos);
bool mask_as_zero = (std::string(szMaskIp).find("0.0.0.0") != std::string::npos);
// bool ip_the_same = (
// std::string(szDestIp).find(ipifaddrs) != std::string::npos &&
// std::string(szDestIp).find(szGatewayIp) != std::string::npos &&
// std::string(szDestIp).find(szInterfaceIp) != std::string::npos
// );
// bool not_default = (std::string(szDestIp).find("127.0.0.1") == std::string::npos);
if ( in_not_empty &&
// in_as_destIp &&
destIp_as_zero &&
mask_as_zero//) || ( ip_the_same && not_default )
)
{
// finded
const route_table &mt = {
std::string(szDestIp),
std::string(szMaskIp),
std::string(szGatewayIp),
std::string(szInterfaceIp),
p_table->table[i].dwForwardIfIndex
};//std::make_tuple(std::string(szDestIp), std::string(szMaskIp), std::string(szGatewayIp), std::string(szInterfaceIp));
ret_table.emplace_back(mt);
}
}
}//end for
}//end if
return ret_table;
}
}//end namespace adpinfo
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
namespace adpinfo {
void NetAdpInfo::Adapter::set_name(std::string_view value){
name = value;
}
std::string_view NetAdpInfo::Adapter::get_name()const{
return name;
}
void NetAdpInfo::Adapter::set_description(std::string_view value){
descr = value;
}
std::string_view NetAdpInfo::Adapter::get_description()const{
return descr;
}
void NetAdpInfo::Adapter::set_route_gateway(std::string_view value){
route = value;
}
std::string_view NetAdpInfo::Adapter::get_route_gateway()const{
return route;
}
void NetAdpInfo::Adapter::set_local_address(std::string_view value){
address = value;
}
std::string_view NetAdpInfo::Adapter::get_local_address()const{
return address;
}
void NetAdpInfo::Adapter::set_local_gateway(std::string_view value){
gateway = value;
}
std::string_view NetAdpInfo::Adapter::get_local_gateway()const{
return gateway;
}
RET_TYPE NetAdpInfo::collect_adapters_data(){
_adapters.clear();
std::vector<BYTE> buffer{};
IP_ADAPTER_INFO *adapter_info{nullptr};
DWORD result{ERROR_BUFFER_OVERFLOW};
ULONG buffer_len = sizeof(IP_ADAPTER_INFO) * 10;
while (result == ERROR_BUFFER_OVERFLOW){
buffer.resize(buffer_len);
adapter_info = reinterpret_cast<IP_ADAPTER_INFO*>(&buffer[0]);
result = GetAdaptersInfo(adapter_info, &buffer_len);
if (result == ERROR_NO_DATA){
return {true, "GetAdaptersInfo return ERROR_NO_DATA"};
}
}//end while
if (result != NO_ERROR){
const std::string &error = "GetAdaptersInfo failed :" + std::to_string(result);
return {true, error};
}
IP_ADAPTER_INFO *adapter_iterator = adapter_info;
while(adapter_iterator){
std::shared_ptr<Adapter>_tmp{std::make_shared<Adapter>()};
_tmp->set_name(adapter_iterator->AdapterName);
_tmp->set_description(adapter_iterator->Description);
_tmp->set_local_address(adapter_iterator->IpAddressList.IpAddress.String);
std::string lgw = adapter_iterator->GatewayList.IpAddress.String;
// if (lgw.length() == 0 || lgw.find("0.0.0.0") != std::string::npos)
// {
// //lgw = get_founded_route("8.8.8.8");
// if (adapter_iterator->DhcpEnabled == 1)
// {
// lgw = adapter_iterator->DhcpServer.IpAddress.String;
// }
// }
_tmp->set_local_gateway(lgw);
_tmp->set_route_gateway(get_route_gateway());
_adapters.emplace_back(_tmp);
adapter_iterator = adapter_iterator->Next;
}
return {false, ""};
}
RET_TYPE NetAdpInfo::get_adapter_info(std::string_view _adapter_name){
_index_of_adapter = -1;
const auto result{collect_adapters_data()};
if (std::get<0>(result) == true){
_index_of_adapter = -1;
return result;
}
const int16_t &len = static_cast<int16_t>(_adapters.size());
for (auto i = 0; i< len; ++i){
auto adap_name = _adapters[i]->get_name();
auto adap_desc = _adapters[i]->get_description();
if ( adap_name.find(_adapter_name) != std::string::npos || adap_desc.find(_adapter_name) != std::string::npos ){
_index_of_adapter = i;
return {false, ""};
}
}
return {true, "adapters no founded"};
}
std::string_view NetAdpInfo::get_adapter_route_gateway()const{
if (_index_of_adapter < 0)
return "error adapter index";
return _adapters.at(_index_of_adapter)->get_route_gateway();
}
std::string_view NetAdpInfo::get_adapter_local_address()const{
if (_index_of_adapter < 0)
return "error adapter index";
return _adapters.at(_index_of_adapter)->get_local_address();
}
std::string_view NetAdpInfo::get_adapter_local_gateway()const{
if (_index_of_adapter < 0)
return "error adapter index";
return _adapters.at(_index_of_adapter)->get_local_gateway();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//std::string NetAdpInfo::get_system_route(){
// return get_route_gateway();
//}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
}// end namespace

View File

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

View File

@@ -57,10 +57,16 @@ ios: {
ARCH_TAG = "ios_armv7"
}
}
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
}
# 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
View 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 presharedKey:(NSString * _Nonnull)presharedKey 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 */

39
client/Info.plist Normal file
View 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>

View 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

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/vpnicon_background"/>
<foreground android:drawable="@mipmap/vpnicon_foreground"/>
</adaptive-icon>

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/vpnicon_background"/>
<foreground android:drawable="@mipmap/vpnicon_round"/>
</adaptive-icon>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="vpnicon_background">#000000</color>
</resources>

View File

@@ -377,11 +377,11 @@ class VPNService : android.net.VpnService() {
val wgConfig: String = wireguard_conf!!.toWgUserspaceString()
val builder = Builder()
setupBuilder(wireguard_conf, builder)
builder.setSession("mvpn0")
builder.setSession("avpn0")
builder.establish().use { tun ->
if (tun == null)return
Log.i(tag, "Go backend " + wgVersion())
currentTunnelHandle = wgTurnOn("mvpn0", tun.detachFd(), wgConfig)
currentTunnelHandle = wgTurnOn("avpn0", tun.detachFd(), wgConfig)
}
if (currentTunnelHandle < 0) {
Log.e(tag, "Activation Error Code -> $currentTunnelHandle")

View File

@@ -13,6 +13,7 @@ include("3rd/QtSsh/src/botan/botan.pri")
!android:!ios:include("3rd/SingleApplication/singleapplication.pri")
include("3rd/QRCodeGenerator/QRCodeGenerator.pri")
include ("3rd/SortFilterProxyModel/SortFilterProxyModel.pri")
include("3rd/AdpInfo/adpinfo.pri")
INCLUDEPATH += $$PWD/3rd/OpenSSL/include
DEPENDPATH += $$PWD/3rd/OpenSSL/include
@@ -39,6 +40,7 @@ HEADERS += \
managementserver.h \
protocols/protocols_defs.h \
settings.h \
ui/notificationhandler.h \
ui/models/containers_model.h \
ui/models/protocols_model.h \
ui/pages.h \
@@ -69,6 +71,10 @@ HEADERS += \
utils.h \
vpnconnection.h \
protocols/vpnprotocol.h \
logger.h \
loghandler.h \
loglevel.h \
constants.h
SOURCES += \
configurators/cloak_configurator.cpp \
@@ -90,6 +96,7 @@ SOURCES += \
managementserver.cpp \
protocols/protocols_defs.cpp \
settings.cpp \
ui/notificationhandler.cpp \
ui/models/containers_model.cpp \
ui/models/protocols_model.cpp \
ui/pages_logic/AppSettingsLogic.cpp \
@@ -118,6 +125,9 @@ SOURCES += \
utils.cpp \
vpnconnection.cpp \
protocols/vpnprotocol.cpp \
logger.cpp \
loghandler.cpp
RESOURCES += \
resources.qrc
@@ -126,6 +136,8 @@ TRANSLATIONS = \
translations/amneziavpn_ru.ts
win32 {
DEFINES += MVPN_WINDOWS
OTHER_FILES += platform_win/vpnclient.rc
RC_FILE = platform_win/vpnclient.rc
@@ -161,6 +173,8 @@ win32 {
}
macx {
DEFINES += MVPN_MACOS
ICON = $$PWD/images/app.icns
HEADERS += ui/macos_util.h
@@ -173,6 +187,8 @@ macx {
}
linux:!android {
DEFINES += MVPN_LINUX
LIBS += /usr/lib/x86_64-linux-gnu/libcrypto.a
LIBS += /usr/lib/x86_64-linux-gnu/libssl.a
}
@@ -180,6 +196,7 @@ linux:!android {
win32|macx|linux:!android {
HEADERS += \
ui/systemtray_notificationhandler.h \
protocols/openvpnprotocol.h \
protocols/ikev2_vpn_protocol.h \
protocols/openvpnovercloakprotocol.h \
@@ -187,6 +204,7 @@ win32|macx|linux:!android {
protocols/wireguardprotocol.h \
SOURCES += \
ui/systemtray_notificationhandler.cpp \
protocols/openvpnprotocol.cpp \
protocols/ikev2_vpn_protocol.cpp \
protocols/openvpnovercloakprotocol.cpp \
@@ -196,12 +214,20 @@ win32|macx|linux:!android {
android {
QT += androidextras
DEFINES += MVPN_ANDROID
INCLUDEPATH += platforms/android
HEADERS += protocols/android_vpnprotocol.h \
HEADERS += \
platforms/android/android_controller.h \
platforms/android/android_notificationhandler.h \
protocols/android_vpnprotocol.h
SOURCES += \
platforms/android/android_controller.cpp \
platforms/android/android_notificationhandler.cpp \
protocols/android_vpnprotocol.cpp
SOURCES += protocols/android_vpnprotocol.cpp \
DISTFILES += \
android/AndroidManifest.xml \
@@ -240,46 +266,90 @@ android {
ios {
message("Client ios build")
CONFIG += static
CONFIG += file_copies
# For the authentication
LIBS += -framework AuthenticationServices
# For notifications
LIBS += -framework UIKit
LIBS += -framework Foundation
LIBS += -framework StoreKit
LIBS += -framework UserNotifications
DEFINES += MVPN_IOS
HEADERS += \
protocols/ios_vpnprotocol.h \
platforms/ios/iosnotificationhandler.h \
platforms/ios/json.h \
platforms/ios/bigint.h \
platforms/ios/bigintipv6addr.h \
platforms/ios/ipaddress.h \
platforms/ios/ipaddressrange.h
SOURCES += \
protocols/ios_vpnprotocol.mm \
platforms/ios/iosnotificationhandler.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
QMAKE_MAC_XCODE_SETTINGS += Q_ENABLE_BITCODE
CONFIG(iphoneos, iphoneos|iphonesimulator) {
message("Building for iPhone OS")
QMAKE_TARGET_BUNDLE_PREFIX = org.amnezia
QMAKE_BUNDLE = AmneziaVPN
QMAKE_IOS_DEPLOYMENT_TARGET = 12.0
QMAKE_APPLE_TARGETED_DEVICE_FAMILY = 1
QMAKE_DEVELOPMENT_TEAM = X7UJ388FXK
QMAKE_PROVISIONING_PROFILE = f2fefb59-14aa-4aa9-ac14-1d5531b06dcc
QMAKE_XCODE_CODE_SIGN_IDENTITY = "Apple Distribution"
XCODEBUILD_FLAGS += -allowProvisioningUpdates
DEFINES += iphoneos
contains(QT_ARCH, arm64) {
message("Building for iOS/ARM v8 64-bit architecture")
ARCH_TAG = "ios_armv8_64"
LIBS += $$PWD/3rd/OpenSSL/lib/ios/iphone/libcrypto.a
LIBS += $$PWD/3rd/OpenSSL/lib/ios/iphone/libssl.a
} else {
message("Building for iOS/ARM v7 (32-bit) architecture")
ARCH_TAG = "ios_armv7"
}
# CONFIG(iphoneos, iphoneos|iphonesimulator) {
iphoneos {
message("Building for iPhone OS")
QMAKE_TARGET_BUNDLE_PREFIX = org.amnezia
QMAKE_BUNDLE = AmneziaVPN
QMAKE_IOS_DEPLOYMENT_TARGET = 12.0
QMAKE_APPLE_TARGETED_DEVICE_FAMILY = 1
QMAKE_DEVELOPMENT_TEAM = X7UJ388FXK
QMAKE_PROVISIONING_PROFILE = f2fefb59-14aa-4aa9-ac14-1d5531b06dcc
QMAKE_XCODE_CODE_SIGN_IDENTITY = "Apple Distribution"
QMAKE_INFO_PLIST= $$PWD/ios/app/Info.plist
XCODEBUILD_FLAGS += -allowProvisioningUpdates
DEFINES += iphoneos
contains(QT_ARCH, arm64) {
message("Building for iOS/ARM v8 64-bit architecture")
ARCH_TAG = "ios_armv8_64"
LIBS += $$PWD/3rd/OpenSSL/lib/ios/iphone/libcrypto.a
LIBS += $$PWD/3rd/OpenSSL/lib/ios/iphone/libssl.a
} else {
message("Building for iOS/ARM v7 (32-bit) architecture")
ARCH_TAG = "ios_armv7"
}
}
# }
CONFIG(iphonesimulator, iphoneos|iphonesimulator) {
message("Building for iPhone Simulator")
ARCH_TAG = "ios_x86_64"
# CONFIG(iphonesimulator, iphoneos|iphonesimulator) {
# 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
# }
# }
DEFINES += iphonesimulator
NETWORKEXTENSION=1
# ! 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")
LIBS += $$PWD/3rd/OpenSSL/lib/ios/simulator/libcrypto.a
LIBS += $$PWD/3rd/OpenSSL/lib/ios/simulator/libssl.a
}
#ruby %{sourceDir}/client/ios/xcode_patcher.rb "%{buildDir}/AmneziaVPN.xcodeproj" "2.0" "2.0.0" "ios" "1"
#cd client/ && /Users/md/Qt/5.15.2/ios/bin/qmake -o Makefile /Users/md/amnezia/desktop-client/client/client.pro -spec macx-ios-clang CONFIG+=iphonesimulator CONFIG+=simulator CONFIG+=qml_debug -after
# %{sourceDir}/client/ios/xcode_patcher.rb %{buildDir}/client/AmneziaVPN.xcodeproj 2.0 2.0.0 ios 1
}

View File

@@ -22,7 +22,7 @@ Ikev2Configurator::ConnectionData Ikev2Configurator::prepareIkev2Config(const Se
connData.host = credentials.hostName;
connData.clientId = Utils::getRandomString(16);
connData.password = Utils::getRandomString(16);
connData.password = "";
//connData.password = "";
QString certFileName = "/opt/amnezia/ikev2/clients/" + connData.clientId + ".p12";

View File

@@ -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();

View File

@@ -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,

127
client/constants.h Normal file
View 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 CONSTANTS_H
#define CONSTANTS_H
#include <stdint.h>
namespace Constants {
// Returns true if we are in a production environment.
bool inProduction();
void setStaging();
// Number of msecs for the captive-portal block alert.
constexpr uint32_t CAPTIVE_PORTAL_ALERT_MSEC = 4000;
// Number of msecs for the unsecured network alert.
constexpr uint32_t UNSECURED_NETWORK_ALERT_MSEC = 4000;
// Number of recent connections to retain.
constexpr int RECENT_CONNECTIONS_MAX_COUNT = 5;
#if defined(UNIT_TEST)
# define CONSTEXPR(type, functionName, releaseValue, debugValue, \
testingValue) \
inline type functionName() { return testingValue; }
#else
# define CONSTEXPR(type, functionName, releaseValue, debugValue, \
testingValue) \
inline type functionName() { \
return inProduction() ? releaseValue : debugValue; \
}
#endif
// Let's refresh the IP address any 10 minutes (in milliseconds).
CONSTEXPR(uint32_t, ipAddressTimerMsec, 600000, 10000, 0)
// Let's check the connection status any second.
CONSTEXPR(uint32_t, checkStatusTimerMsec, 1000, 1000, 0)
// Number of points for the charts.
CONSTEXPR(int, chartsMaxPoints, 30, 30, 30);
// Any 6 hours, a new check
CONSTEXPR(uint32_t, releaseMonitorMsec, 21600000, 4000, 0)
// in milliseconds, how often we should fetch the server list and the account.
CONSTEXPR(uint32_t, scheduleAccountAndServersTimerMsec, 3600000, 4000, 0)
// how often we check the captive portal when the VPN is on.
CONSTEXPR(uint32_t, captivePortalRequestTimeoutMsec, 10000, 4000, 0)
// How fast the animated icon should move
CONSTEXPR(uint32_t, statusIconAnimationMsec, 200, 200, 0)
// How often glean pings are sent
CONSTEXPR(uint32_t, gleanTimeoutMsec, 1200000, 1000, 0)
// How often we check the surveys to be executed (no network requests are done
// for this check)
CONSTEXPR(uint32_t, surveyTimerMsec, 300000, 4000, 0)
#undef CONSTEXPR
#define PRODBETAEXPR(type, functionName, prod, beta) \
inline type functionName() { return inProduction() ? prod : beta; }
constexpr const char* API_PRODUCTION_URL = "https://vpn.mozilla.org";
constexpr const char* API_STAGING_URL =
"https://stage-vpn.guardian.nonprod.cloudops.mozgcp.net";
constexpr const char* LOGO_URL = ":/ui/resources/logo-dock.png";
PRODBETAEXPR(const char*, fxaUrl, "https://api.accounts.firefox.com",
"https://api-accounts.stage.mozaws.net")
PRODBETAEXPR(
const char*, balrogUrl,
"https://aus5.mozilla.org/json/1/FirefoxVPN/%1/%2/release/update.json",
"https://stage.balrog.nonprod.cloudops.mozgcp.net/json/1/FirefoxVPN/%1/%2/"
"release-cdntest/update.json");
PRODBETAEXPR(
const char*, balrogRootCertFingerprint,
"97e8ba9cf12fb3de53cc42a4e6577ed64df493c247b414fea036818d3823560e",
"3c01446abe9036cea9a09acaa3a520ac628f20a7ae32ce861cb2efb70fa0c745");
#undef PRODBETAEXPR
constexpr const char* PLATFORM_NAME =
#if defined(MVPN_IOS)
"ios"
#elif defined(MVPN_MACOS)
"macos"
#elif defined(MVPN_LINUX)
"linux"
#elif defined(MVPN_ANDROID)
"android"
#elif defined(MVPN_WINDOWS)
"windows"
#elif defined(UNIT_TEST) || defined(MVPN_DUMMY)
"dummy"
#else
# error "Unsupported platform"
#endif
;
constexpr const char* PLACEHOLDER_USER_DNS = "127.0.0.1";
#if defined(MVPN_ADJUST)
// These are the two auto-generated token from the Adjust dashboard for the
// "Subscription Completed" event. We have two since in the Adjust dashboard we
// have defined two apps for iOS and Android with a event token each.
constexpr const char* ADJUST_SUBSCRIPTION_COMPLETED =
# if defined(MVPN_IOS)
"jl72xm"
# elif defined(MVPN_ANDROID)
"o1mn9m"
# else
""
# endif
;
#endif
}; // namespace Constants
#endif // CONSTANTS_H

View File

@@ -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,50 @@ 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;
}
}
bool ContainerProps::isWorkingOnPlatform(DockerContainer c)
{
#ifdef Q_OS_WINDOWS
return true;
#elif defined (Q_OS_IOS)
switch (c) {
case DockerContainer::WireGuard: return true;
case DockerContainer::OpenVpn: return true;
default: return false;
}
#elif defined (Q_OS_MAC)
return false;
#elif defined (Q_OS_ANDROID)
switch (c) {
case DockerContainer::WireGuard: return true;
case DockerContainer::OpenVpn: return true;
default: return false;
}
#elif defined (Q_OS_LINUX)
return false;
#else
return false;
#endif
}

View File

@@ -46,13 +46,15 @@ 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);
Q_INVOKABLE static bool isWorkingOnPlatform(DockerContainer c);
};

View File

@@ -1,5 +1,6 @@
#include "privileged_process.h"
#ifndef Q_OS_IOS
PrivilegedProcess::PrivilegedProcess() :
IpcProcessInterfaceReplica()
{
@@ -25,3 +26,4 @@ void PrivilegedProcess::waitForFinished(int msecs)
loop->exec();
}
#endif // Q_OS_IOS

View File

@@ -20,11 +20,11 @@ public:
};
#endif // PRIVILEGED_PROCESS_H
#else // defined Q_OS_IOS
class IpcProcessInterfaceReplica {};
class PrivilegedProcess {};
#endif
#endif // Q_OS_IOS
#endif // PRIVILEGED_PROCESS_H

View File

@@ -1,6 +1,7 @@
#include "servercontroller.h"
#include <QCryptographicHash>
#include <QDir>
#include <QFile>
#include <QEventLoop>
#include <QLoggingCategory>
@@ -10,6 +11,7 @@
#include <QJsonDocument>
#include <QApplication>
#include <QTemporaryFile>
#include <QFileInfo>
#include "sftpchannel.h"
#include "sshconnectionmanager.h"
@@ -134,12 +136,7 @@ ErrorCode ServerController::runContainerScript(const ServerCredentials &credenti
{
QString fileName = "/opt/amnezia/" + Utils::getRandomString(16) + ".sh";
QString mkdir = "sudo docker exec -i $CONTAINER_NAME mkdir -p /opt/amnezia/";
ErrorCode e = runScript(credentials,
replaceVars(mkdir, genVarsForScript(credentials, container)), cbReadStdOut, cbReadStdErr);
if (e) return e;
e = uploadTextFileToContainer(container, credentials, script, fileName);
ErrorCode e = uploadTextFileToContainer(container, credentials, script, fileName);
if (e) return e;
QString runner = QString("sudo docker exec -i $CONTAINER_NAME bash %1 ").arg(fileName);
@@ -167,6 +164,14 @@ ErrorCode ServerController::uploadTextFileToContainer(DockerContainer container,
stdOut += data + "\n";
};
// mkdir
QFileInfo fi(path);
QString mkdir = "sudo docker exec -i $CONTAINER_NAME mkdir -p " + fi.absoluteDir().absolutePath();
e = runScript(credentials,
replaceVars(mkdir, genVarsForScript(credentials, container)));
if (e) return e;
if (overwriteMode == QSsh::SftpOverwriteMode::SftpOverwriteExisting) {
e = runScript(credentials,
replaceVars(QString("sudo docker cp %1 $CONTAINER_NAME:/%2").arg(tmpFileName).arg(path),
@@ -449,7 +454,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 +621,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 +694,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() }});

View File

@@ -0,0 +1,67 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="256.000000pt" height="256.000000pt" viewBox="0 0 256.000000 256.000000"
preserveAspectRatio="xMidYMid meet">
<g transform="translate(0.000000,256.000000) scale(0.100000,-0.100000)"
fill="#000000" stroke="none">
<path d="M1216 2523 c-3 -21 -8 -91 -12 -156 -3 -64 -10 -120 -15 -123 -5 -3
-9 -13 -9 -23 0 -26 -48 -71 -76 -71 -13 0 -24 -4 -24 -9 0 -5 -10 -11 -22
-13 -16 -2 -24 -11 -26 -30 -3 -22 -9 -27 -43 -33 -21 -4 -39 -10 -39 -15 0
-4 -29 -13 -65 -20 -36 -7 -65 -16 -65 -21 0 -4 -20 -11 -45 -15 -40 -6 -47
-11 -65 -48 -36 -72 -51 -96 -60 -96 -5 0 -17 -14 -25 -31 -14 -25 -21 -30
-47 -27 -27 3 -32 -1 -46 -36 -9 -22 -31 -53 -49 -69 -18 -16 -33 -34 -33 -40
0 -5 -13 -37 -29 -71 -15 -34 -31 -71 -35 -83 -4 -13 -11 -23 -15 -23 -4 0
-15 -24 -26 -52 -10 -29 -21 -57 -25 -63 -4 -5 -13 -34 -21 -62 -7 -29 -16
-53 -20 -53 -11 0 -31 -154 -35 -274 l-4 -110 -43 -45 c-24 -26 -65 -63 -92
-84 -119 -89 -132 -113 -57 -102 26 4 52 11 57 15 16 14 144 32 169 24 22 -7
66 -49 66 -64 0 -5 52 -63 116 -130 l117 -121 -6 -96 c-4 -52 -11 -101 -17
-108 -12 -14 -27 -145 -16 -145 3 0 19 11 35 25 18 17 34 47 46 88 9 34 21 71
26 82 5 11 13 32 19 48 5 15 16 27 25 27 8 0 15 5 15 10 0 16 43 12 86 -9 126
-60 153 -71 177 -71 15 0 27 -4 27 -8 0 -4 62 -16 138 -27 75 -10 141 -22 147
-27 12 -11 121 -10 143 1 9 5 44 15 77 21 33 7 78 20 100 30 23 10 54 22 70
26 17 4 35 10 41 15 15 12 133 39 170 39 23 0 33 -5 37 -19 2 -10 17 -25 32
-32 18 -10 34 -31 49 -67 23 -57 87 -132 112 -132 15 0 16 10 9 82 -4 46 -10
85 -14 88 -8 5 -26 95 -37 188 -7 60 11 151 32 159 8 3 14 11 14 18 0 6 21 37
48 68 103 123 96 106 102 258 3 75 11 143 17 150 6 8 14 32 18 54 6 34 42 103
74 141 5 6 12 25 16 42 l7 32 -68 0 -67 0 6 47 c3 26 10 49 16 51 6 2 11 9 11
15 0 14 104 117 118 117 5 0 16 8 26 19 9 10 34 26 56 36 22 10 40 22 40 27 0
4 7 8 15 8 9 0 15 9 15 21 0 20 -3 21 -57 14 -32 -4 -62 -10 -68 -15 -18 -13
-145 -33 -177 -26 -17 3 -41 16 -52 29 -39 40 -104 94 -122 101 -13 5 -15 14
-10 45 6 41 -3 51 -44 51 -11 0 -39 19 -64 43 -45 43 -80 72 -151 126 -22 17
-47 36 -55 43 -8 7 -22 18 -30 23 -9 6 -32 20 -51 32 -28 19 -48 23 -111 23
-42 0 -80 5 -83 10 -3 6 -16 10 -28 10 -12 0 -29 6 -38 13 -27 20 -68 109 -80
172 -7 33 -16 65 -20 70 -4 6 -13 33 -19 60 -15 70 -29 95 -56 95 -18 0 -23
-7 -28 -37z m409 -738 c32 -16 75 -39 95 -52 19 -13 43 -29 54 -36 49 -32 113
-88 134 -116 35 -47 34 -81 -3 -100 -16 -9 -35 -21 -41 -27 -7 -6 -33 -17 -58
-24 -26 -7 -49 -17 -52 -21 -3 -5 -29 -9 -59 -9 -49 0 -56 3 -79 33 -14 18
-33 53 -41 78 -9 24 -22 58 -29 74 -8 17 -19 57 -26 90 -7 33 -16 62 -20 65
-4 3 -10 22 -14 44 l-7 39 43 -5 c24 -3 70 -18 103 -33z m-595 -1 c0 -9 -6
-30 -14 -47 -12 -27 -65 -193 -83 -262 -3 -11 -9 -24 -13 -30 -4 -5 -15 -41
-25 -80 -10 -38 -21 -74 -25 -80 -4 -5 -13 -35 -20 -65 -7 -30 -16 -57 -19
-60 -3 -3 -11 -14 -17 -24 -6 -11 -19 -24 -30 -30 -10 -6 -21 -14 -24 -17 -3
-3 -22 -12 -42 -20 -21 -7 -38 -16 -38 -20 0 -4 -31 -15 -70 -25 -38 -10 -70
-22 -70 -26 0 -4 -19 -8 -42 -8 l-41 0 6 98 c9 130 24 183 84 297 42 79 94
144 184 229 112 105 114 106 128 106 6 0 14 6 17 13 2 7 25 22 49 32 25 11 45
23 45 28 0 4 14 7 30 7 21 0 30 -5 30 -16z m239 -6 c7 -13 23 -41 36 -63 14
-22 35 -60 46 -85 12 -25 25 -47 29 -50 4 -3 13 -23 20 -45 7 -22 17 -45 22
-52 6 -7 12 -39 15 -73 5 -54 3 -62 -18 -84 -36 -35 -98 -63 -170 -76 -35 -6
-83 -15 -107 -21 -23 -5 -54 -9 -67 -9 -28 0 -43 23 -28 43 6 6 16 35 23 62 7
28 16 55 20 60 4 6 15 45 25 88 10 42 21 77 25 77 4 0 10 19 14 42 4 23 13 56
21 72 7 17 19 49 25 71 21 68 47 84 69 43z m807 -449 c8 -13 7 -261 -2 -329
-3 -25 -9 -54 -14 -65 -5 -11 -13 -48 -19 -82 -7 -34 -18 -76 -27 -95 -55
-123 -71 -133 -102 -66 -51 108 -71 158 -77 192 -4 20 -10 36 -14 36 -4 0 -13
21 -21 47 -7 26 -19 58 -26 72 -16 31 -39 155 -31 174 8 21 142 83 212 98 33
7 64 16 70 21 13 12 43 10 51 -3z m-514 -219 c37 -29 55 -74 67 -170 8 -64 19
-101 45 -150 78 -148 98 -196 103 -247 7 -66 -7 -95 -53 -113 -19 -8 -34 -17
-34 -21 0 -4 -21 -15 -47 -25 -27 -10 -50 -21 -53 -25 -16 -22 -77 -29 -259
-29 -197 0 -289 9 -346 34 -16 8 -45 17 -63 21 -18 4 -52 25 -75 47 l-42 40 1
89 c1 49 6 95 12 102 5 6 13 30 16 51 11 61 64 145 136 216 80 78 88 85 137
107 21 10 40 20 43 23 3 3 25 12 50 19 25 7 54 17 65 22 26 12 133 26 211 28
47 1 67 -4 86 -19z m-882 -286 c0 -30 -32 -154 -41 -159 -5 -4 -9 -16 -9 -29
0 -12 -6 -31 -14 -41 -14 -19 -15 -19 -49 -1 -34 19 -87 103 -87 138 0 33 68
88 109 88 12 0 21 5 21 10 0 6 16 10 35 10 25 0 35 -4 35 -16z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17506" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<device id="ipad12_9rounded" orientation="portrait" layout="fullscreen" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17505"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="gZ9-gc-3t5">
<rect key="frame" x="0.0" y="0.0" width="1024" height="1366"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="launch.png" translatesAutoresizingMaskIntoConstraints="NO" id="q5g-aV-39U">
<rect key="frame" x="467" y="638" width="90" height="90"/>
<constraints>
<constraint firstAttribute="width" constant="90" id="VFp-nz-h8O"/>
<constraint firstAttribute="height" constant="90" id="ZUg-Ud-mgE"/>
</constraints>
</imageView>
</subviews>
<viewLayoutGuide key="safeArea" id="Whf-X3-AA4"/>
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="q5g-aV-39U" firstAttribute="centerX" secondItem="gZ9-gc-3t5" secondAttribute="centerX" id="Ayw-bo-LVF"/>
<constraint firstItem="q5g-aV-39U" firstAttribute="centerY" secondItem="gZ9-gc-3t5" secondAttribute="centerY" id="YHd-Kc-J0u"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
<resources>
<image name="launch.png" width="1024" height="1024"/>
</resources>
</document>

View File

@@ -0,0 +1,116 @@
{
"images" : [
{
"filename" : "icon-ios-20@2x.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "20x20"
},
{
"filename" : "icon-ios-20@3x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "20x20"
},
{
"filename" : "icon-ios-29@2x-1.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "29x29"
},
{
"filename" : "icon-ios-29@3x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "29x29"
},
{
"filename" : "icon-ios-40@2x-1.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "40x40"
},
{
"filename" : "icon-ios-40@3x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "40x40"
},
{
"filename" : "icon-ios-60@2x.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "60x60"
},
{
"filename" : "icon-ios-60@3x.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "60x60"
},
{
"filename" : "icon-ios-20@1x.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "20x20"
},
{
"filename" : "icon-ios-20@2x-1.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "20x20"
},
{
"filename" : "icon-ios-29@1x.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "29x29"
},
{
"filename" : "icon-ios-29@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "29x29"
},
{
"filename" : "icon-ios-40@1x.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "40x40"
},
{
"filename" : "icon-ios-40@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "40x40"
},
{
"filename" : "icon-ios-76@1x.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "76x76"
},
{
"filename" : "icon-ios-76@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "76x76"
},
{
"filename" : "icon-ios-83.5@2x.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "83.5x83.5"
},
{
"filename" : "icon-ios-1024@1x.png",
"idiom" : "ios-marketing",
"scale" : "1x",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 407 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 721 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 721 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 596 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 975 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 975 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 744 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

49
client/ios/app/Info.plist Normal file
View File

@@ -0,0 +1,49 @@
<?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>CFBundleAllowMixedLocalizations</key>
<true/>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>AmneziaVPN</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIcons</key>
<dict/>
<key>CFBundleIcons~ipad</key>
<dict/>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${APP_DISPLAY_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>LSSupportsOpeningDocumentsInPlace</key>
<false/>
<key>UILaunchStoryboardName</key>
<string>AmneziaVPNLaunchScreen</string>
<key>UIRequiresFullScreen</key>
<true/>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationPortrait</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array/>
<key>UIUserInterfaceStyle</key>
<string>Light</string>
</dict>
</plist>

BIN
client/ios/app/launch.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -0,0 +1,20 @@
<?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>
<string>group.ru.kotit.AmneziaVPN.udev</string>
</array>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>keychain-access-groups</key>
<array>
<string>$(AppIdentifierPrefix)group.ru.kotit.AmneziaVPN.udev</string>
</array>
</dict>
</plist>

View File

@@ -0,0 +1,18 @@
<?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>
<string>group.ru.kotit.AmneziaVPN.udev</string>
</array>
<key>keychain-access-groups</key>
<array>
<string>$(AppIdentifierPrefix)group.ru.kotit.AmneziaVPN.udev</string>
</array>
</dict>
</plist>

13
client/ios/xcode.xconfig Normal file
View File

@@ -0,0 +1,13 @@
DEVELOPMENT_TEAM = <X7UJ388FXK>
# MacOS configuration
GROUP_ID_MACOS = <>
APP_ID_MACOS = <>
NETEXT_ID_MACOS = <>
LOGIN_ID_MACOS = <>
NATIVEMESSAGING_ID_MACOS = <>
# IOS configuration
GROUP_ID_IOS = group.org.mozilla.ios.Guardian
APP_ID_IOS = org.mozilla.ios.FirefoxVPN
NETEXT_ID_IOS = org.mozilla.ios.FirefoxVPN.network-extension

598
client/ios/xcode_patcher.rb Normal file
View File

@@ -0,0 +1,598 @@
# 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 :p_root
attr :target_main
attr :target_extension
# @@project_root
# def self.project_root
# @@project_root
# end
def run(project_root, file, shortVersion, fullVersion, platform, networkExtension, webExtension, configHash, adjust_sdk_token)
@p_root = project_root
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('ios/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 if webExtension
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)
puts 'Failed to open the project file: ' + file if @project.nil?
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?
puts 'Unable to open AmneziaVPN target'
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'] ||= p_root + "/" + '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'] = 'Mozilla VPN'
# other config
config.build_settings['INFOPLIST_FILE'] ||= p_root + "/" + platform + '/app/Info.plist'
if platform == 'ios'
config.build_settings['CODE_SIGN_ENTITLEMENTS'] ||= p_root + "/" + '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'] ||= p_root + "/" + 'macos/app/app.entitlements'
else
config.build_settings['CODE_SIGN_ENTITLEMENTS'] ||= p_root + "/" + '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']
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(p_root + "/" + filename)
@target_main.add_file_references([file])
}
# @target_main + swift integration
group = @project.main_group.new_group('SwiftIntegration')
[
'platforms/ios/ioscontroller.swift',
'platforms/ios/ioslogger.swift',
].each { |filename|
file = group.new_file(p_root + "/" + 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' }
embed_frameworks_build_phase = @target_main.build_phases.find { |build_phase| build_phase.to_s == 'Embed Frameworks' }
framework_ref = frameworks_group.new_file('3rd/AdjustSdk.framework')
frameworks_build_phase.add_file_reference(framework_ref)
framework_file = embed_frameworks_build_phase.add_file_reference(framework_ref)
framework_file.settings = { "ATTRIBUTES" => ['RemoveHeadersOnCopy', 'CodeSignOnCopy'] }
framework_ref = frameworks_group.new_file('AdServices.framework')
frameworks_build_phase.add_file_reference(framework_ref)
framework_ref = frameworks_group.new_file('iAd.framework')
frameworks_build_phase.add_file_reference(framework_ref)
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'] ||= p_root + "/" + 'macos/networkextension/WireGuardNetworkExtension-Bridging-Header.h'
config.build_settings['SWIFT_PRECOMPILE_BRIDGING_HEADER'] = 'NO'
# 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'] ||= p_root + "/" + 'macos/networkextension/Info.plist'
config.build_settings['CODE_SIGN_ENTITLEMENTS'] ||= p_root + "/" + 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(p_root + "/" + filename)
@target_extension.add_file_references([file])
}
# @target_extension + swift integration
group = @project.main_group.new_group('SwiftIntegration')
[
'platforms/ios/iostunnel.swift',
'platforms/ios/iosglue.mm',
'platforms/ios/ioslogger.swift',
].each { |filename|
file = group.new_file(p_root + "/" + 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 = p_root + "/" + '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 = p_root + "/" + '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 = p_root + "/" + '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 = p_root + "/" + '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)
return
@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'] ||= p_root + "/" + 'macos/loginitem/AmneziaVPNLoginItem.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'] ||= p_root + "/" + 'macos/nativeMessaging/Info.plist'
config.build_settings['CODE_SIGN_ENTITLEMENTS'] ||= p_root + "/" + 'macos/nativeMessaging/AmneziaVPNNativeMessaging.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(p_root + "/" + 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[4] != "ios" && ARGV[4] != "macos")
puts "Usage: <script> project_file shortVersion fullVersion ios/macos"
exit 1
end
if !File.exist?("ios/xcode.xconfig")
puts "xcode.xconfig file is required! See the template file."
exit 1
end
config = Hash.new
configFile = File.read("ios/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[4] == "ios"
networkExtension = true
webExtension = false
adjustToken = ""
r = XCodeprojPatcher.new
r.run ARGV[0], ARGV[1], ARGV[2], ARGV[3], platform, networkExtension, webExtension, config, adjustToken
exit 0

59
client/logger.cpp Normal file
View 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/. */
#include "logger.h"
#include "loghandler.h"
Logger::Logger(const QString& module, const QString& className)
: Logger(QStringList({module}), className) {}
Logger::Logger(const QStringList& modules, const QString& className)
: m_modules(modules), m_className(className) {}
Logger::Log Logger::error() { return Log(this, LogLevel::Error); }
Logger::Log Logger::warning() { return Log(this, LogLevel::Warning); }
Logger::Log Logger::info() { return Log(this, LogLevel::Info); }
Logger::Log Logger::debug() { return Log(this, LogLevel::Debug); }
Logger::Log::Log(Logger* logger, LogLevel logLevel)
: m_logger(logger), m_logLevel(logLevel), m_data(new Data()) {}
Logger::Log::~Log() {
LogHandler::messageHandler(m_logLevel, m_logger->modules(),
m_logger->className(), m_data->m_buffer.trimmed());
delete m_data;
}
#define CREATE_LOG_OP_REF(x) \
Logger::Log& Logger::Log::operator<<(x t) { \
m_data->m_ts << t << ' '; \
return *this; \
}
CREATE_LOG_OP_REF(uint64_t);
CREATE_LOG_OP_REF(const char*);
CREATE_LOG_OP_REF(const QString&);
CREATE_LOG_OP_REF(const QByteArray&);
CREATE_LOG_OP_REF(void*);
#undef CREATE_LOG_OP_REF
Logger::Log& Logger::Log::operator<<(const QStringList& t) {
m_data->m_ts << '[' << t.join(",") << ']' << ' ';
return *this;
}
Logger::Log& Logger::Log::operator<<(QTextStreamFunction t) {
m_data->m_ts << t;
return *this;
}
// static
QString Logger::sensitive(const QString& input) {
#ifdef QT_DEBUG
return input;
#else
return QString(input.length(), 'X');
#endif
}

88
client/logger.h Normal file
View File

@@ -0,0 +1,88 @@
/* 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 LOGGER_H
#define LOGGER_H
#include "loglevel.h"
#include <QString>
#include <QTextStream>
constexpr const char* LOG_CAPTIVEPORTAL = "captiveportal";
constexpr const char* LOG_CONTROLLER = "controller";
constexpr const char* LOG_IAP = "iap";
constexpr const char* LOG_INSPECTOR = "inspector";
constexpr const char* LOG_MAIN = "main";
constexpr const char* LOG_MODEL = "model";
constexpr const char* LOG_NETWORKING = "networking";
constexpr const char* LOG_SERVER = "server";
#if defined(MVPN_LINUX) || defined(MVPN_ANDROID)
constexpr const char* LOG_LINUX = "linux";
#endif
#ifdef MVPN_WINDOWS
constexpr const char* LOG_WINDOWS = "windows";
#endif
#if __APPLE__ || defined(MVPN_WASM)
constexpr const char* LOG_MACOS = "macos";
constexpr const char* LOG_IOS = "ios";
#endif
#if defined(MVPN_ANDROID) || defined(UNIT_TEST)
constexpr const char* LOG_ANDROID = "android";
#endif
class Logger {
public:
Logger(const QString& module, const QString& className);
Logger(const QStringList& modules, const QString& className);
const QStringList& modules() const { return m_modules; }
const QString& className() const { return m_className; }
class Log {
public:
Log(Logger* logger, LogLevel level);
~Log();
Log& operator<<(uint64_t t);
Log& operator<<(const char* t);
Log& operator<<(const QString& t);
Log& operator<<(const QStringList& t);
Log& operator<<(const QByteArray& t);
Log& operator<<(QTextStreamFunction t);
Log& operator<<(void* t);
private:
Logger* m_logger;
LogLevel m_logLevel;
struct Data {
Data() : m_ts(&m_buffer, QIODevice::WriteOnly) {}
QString m_buffer;
QTextStream m_ts;
};
Data* m_data;
};
Log error();
Log warning();
Log info();
Log debug();
// Use this to log sensitive data such as IP address, session tokens, and so
// on.
QString sensitive(const QString& input);
private:
QStringList m_modules;
QString m_className;
};
#endif // LOGGER_H

346
client/loghandler.cpp Normal file
View File

@@ -0,0 +1,346 @@
/* 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 "loghandler.h"
#include "constants.h"
#include "logger.h"
#include <QDate>
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QMessageLogContext>
#include <QMutexLocker>
#include <QProcessEnvironment>
#include <QStandardPaths>
#include <QString>
#include <QTextStream>
#ifdef MVPN_ANDROID
# include <android/log.h>
#endif
constexpr qint64 LOG_MAX_FILE_SIZE = 204800;
constexpr const char* LOG_FILENAME = "mozillavpn.txt";
namespace {
QMutex s_mutex;
QString s_location =
QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
LogHandler* s_instance = nullptr;
LogLevel qtTypeToLogLevel(QtMsgType type) {
switch (type) {
case QtDebugMsg:
return Debug;
case QtInfoMsg:
return Info;
case QtWarningMsg:
return Warning;
case QtCriticalMsg:
[[fallthrough]];
case QtFatalMsg:
return Error;
default:
return Debug;
}
}
} // namespace
// static
LogHandler* LogHandler::instance() {
QMutexLocker lock(&s_mutex);
return maybeCreate(lock);
}
// static
void LogHandler::messageQTHandler(QtMsgType type,
const QMessageLogContext& context,
const QString& message) {
QMutexLocker lock(&s_mutex);
maybeCreate(lock)->addLog(Log(qtTypeToLogLevel(type), context.file,
context.function, context.line, message),
lock);
}
// static
void LogHandler::messageHandler(LogLevel logLevel, const QStringList& modules,
const QString& className,
const QString& message) {
QMutexLocker lock(&s_mutex);
maybeCreate(lock)->addLog(Log(logLevel, modules, className, message), lock);
}
// static
LogHandler* LogHandler::maybeCreate(const QMutexLocker& proofOfLock) {
if (!s_instance) {
LogLevel minLogLevel = Debug; // TODO: in prod, we should log >= warning
QStringList modules;
QProcessEnvironment pe = QProcessEnvironment::systemEnvironment();
if (pe.contains("MOZVPN_LEVEL")) {
QString level = pe.value("MOZVPN_LEVEL");
if (level == "info")
minLogLevel = Info;
else if (level == "warning")
minLogLevel = Warning;
else if (level == "error")
minLogLevel = Error;
}
if (pe.contains("MOZVPN_LOG")) {
QStringList parts = pe.value("MOZVPN_LOG").split(",");
for (const QString& part : parts) {
modules.append(part.trimmed());
}
}
s_instance = new LogHandler(minLogLevel, modules, proofOfLock);
}
return s_instance;
}
// static
void LogHandler::prettyOutput(QTextStream& out, const LogHandler::Log& log) {
out << "[" << log.m_dateTime.toString("dd.MM.yyyy hh:mm:ss.zzz") << "] ";
switch (log.m_logLevel) {
case Debug:
out << "Debug: ";
break;
case Info:
out << "Info: ";
break;
case Warning:
out << "Warning: ";
break;
case Error:
out << "Error: ";
break;
default:
out << "?!?: ";
break;
}
if (log.m_fromQT) {
out << log.m_message;
if (!log.m_file.isEmpty() || !log.m_function.isEmpty()) {
out << " (";
if (!log.m_file.isEmpty()) {
int pos = log.m_file.lastIndexOf("/");
out << log.m_file.right(log.m_file.length() - pos - 1);
if (log.m_line >= 0) {
out << ":" << log.m_line;
}
if (!log.m_function.isEmpty()) {
out << ", ";
}
}
if (!log.m_function.isEmpty()) {
out << log.m_function;
}
out << ")";
}
} else {
out << "(" << log.m_modules.join("|") << " - " << log.m_className << ") "
<< log.m_message;
}
out << Qt::endl;
}
// static
void LogHandler::enableDebug() {
QMutexLocker lock(&s_mutex);
maybeCreate(lock)->m_showDebug = true;
}
LogHandler::LogHandler(LogLevel minLogLevel, const QStringList& modules,
const QMutexLocker& proofOfLock)
: m_minLogLevel(minLogLevel), m_modules(modules) {
Q_UNUSED(proofOfLock);
#if defined(QT_DEBUG) || defined(MVPN_WASM)
m_showDebug = true;
#endif
if (!s_location.isEmpty()) {
openLogFile(proofOfLock);
}
}
void LogHandler::addLog(const Log& log, const QMutexLocker& proofOfLock) {
if (!matchLogLevel(log, proofOfLock)) {
return;
}
if (!matchModule(log, proofOfLock)) {
return;
}
if (m_output) {
prettyOutput(*m_output, log);
}
if ((log.m_logLevel != LogLevel::Debug) || m_showDebug) {
QTextStream out(stderr);
prettyOutput(out, log);
}
QByteArray buffer;
{
QTextStream out(&buffer);
prettyOutput(out, log);
}
emit logEntryAdded(buffer);
#if defined(MVPN_ANDROID) && defined(QT_DEBUG)
const char* str = buffer.constData();
if (str) {
__android_log_write(ANDROID_LOG_DEBUG, "mozillavpn", str);
}
#endif
}
bool LogHandler::matchModule(const Log& log,
const QMutexLocker& proofOfLock) const {
Q_UNUSED(proofOfLock);
// Let's include QT logs always.
if (log.m_fromQT) {
return true;
}
// If no modules has been specified, let's include all.
if (m_modules.isEmpty()) {
return true;
}
for (const QString& module : log.m_modules) {
if (m_modules.contains(module)) {
return true;
}
}
return false;
}
bool LogHandler::matchLogLevel(const Log& log,
const QMutexLocker& proofOfLock) const {
Q_UNUSED(proofOfLock);
return log.m_logLevel >= m_minLogLevel;
}
// static
void LogHandler::writeLogs(QTextStream& out) {
QMutexLocker lock(&s_mutex);
if (!s_instance || !s_instance->m_logFile) {
return;
}
QString logFileName = s_instance->m_logFile->fileName();
s_instance->closeLogFile(lock);
{
QFile file(logFileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
return;
}
out << file.readAll();
}
s_instance->openLogFile(lock);
}
// static
void LogHandler::cleanupLogs() {
QMutexLocker lock(&s_mutex);
cleanupLogFile(lock);
}
// static
void LogHandler::cleanupLogFile(const QMutexLocker& proofOfLock) {
if (!s_instance || !s_instance->m_logFile) {
return;
}
QString logFileName = s_instance->m_logFile->fileName();
s_instance->closeLogFile(proofOfLock);
{
QFile file(logFileName);
file.remove();
}
s_instance->openLogFile(proofOfLock);
}
// static
void LogHandler::setLocation(const QString& path) {
QMutexLocker lock(&s_mutex);
s_location = path;
if (s_instance && s_instance->m_logFile) {
cleanupLogFile(lock);
}
}
void LogHandler::openLogFile(const QMutexLocker& proofOfLock) {
Q_UNUSED(proofOfLock);
Q_ASSERT(!m_logFile);
Q_ASSERT(!m_output);
QDir appDataLocation(s_location);
if (!appDataLocation.exists()) {
QDir tmp(s_location);
tmp.cdUp();
if (!tmp.exists()) {
return;
}
if (!tmp.mkdir(appDataLocation.dirName())) {
return;
}
}
QString logFileName = appDataLocation.filePath(LOG_FILENAME);
m_logFile = new QFile(logFileName);
if (m_logFile->size() > LOG_MAX_FILE_SIZE) {
m_logFile->remove();
}
if (!m_logFile->open(QIODevice::WriteOnly | QIODevice::Append |
QIODevice::Text)) {
delete m_logFile;
m_logFile = nullptr;
return;
}
m_output = new QTextStream(m_logFile);
addLog(Log(Debug, QStringList{LOG_MAIN}, "LogHandler",
QString("Log file: %1").arg(logFileName)),
proofOfLock);
}
void LogHandler::closeLogFile(const QMutexLocker& proofOfLock) {
Q_UNUSED(proofOfLock);
if (m_logFile) {
delete m_output;
m_output = nullptr;
delete m_logFile;
m_logFile = nullptr;
}
}

102
client/loghandler.h Normal file
View File

@@ -0,0 +1,102 @@
/* 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 LOGHANDLER_H
#define LOGHANDLER_H
#include "loglevel.h"
#include <QDateTime>
#include <QObject>
#include <QVector>
class QFile;
class QMutexLocker;
class QTextStream;
class LogHandler final : public QObject {
Q_OBJECT
public:
struct Log {
Log() = default;
Log(LogLevel logLevel, const QStringList& modules, const QString& className,
const QString& message)
: m_logLevel(logLevel),
m_dateTime(QDateTime::currentDateTime()),
m_modules(modules),
m_className(className),
m_message(message),
m_fromQT(false) {}
Log(LogLevel logLevel, const QString& file, const QString& function,
uint32_t line, const QString& message)
: m_logLevel(logLevel),
m_dateTime(QDateTime::currentDateTime()),
m_file(file),
m_function(function),
m_message(message),
m_line(line),
m_fromQT(true) {}
LogLevel m_logLevel = LogLevel::Debug;
QDateTime m_dateTime;
QString m_file;
QString m_function;
QStringList m_modules;
QString m_className;
QString m_message;
int32_t m_line = -1;
bool m_fromQT = false;
};
static LogHandler* instance();
static void messageQTHandler(QtMsgType type,
const QMessageLogContext& context,
const QString& message);
static void messageHandler(LogLevel logLevel, const QStringList& modules,
const QString& className, const QString& message);
static void prettyOutput(QTextStream& out, const LogHandler::Log& log);
static void writeLogs(QTextStream& out);
static void cleanupLogs();
static void setLocation(const QString& path);
static void enableDebug();
signals:
void logEntryAdded(const QByteArray& log);
private:
LogHandler(LogLevel m_minLogLevel, const QStringList& modules,
const QMutexLocker& proofOfLock);
static LogHandler* maybeCreate(const QMutexLocker& proofOfLock);
void addLog(const Log& log, const QMutexLocker& proofOfLock);
bool matchLogLevel(const Log& log, const QMutexLocker& proofOfLock) const;
bool matchModule(const Log& log, const QMutexLocker& proofOfLock) const;
void openLogFile(const QMutexLocker& proofOfLock);
void closeLogFile(const QMutexLocker& proofOfLock);
static void cleanupLogFile(const QMutexLocker& proofOfLock);
const LogLevel m_minLogLevel;
const QStringList m_modules;
bool m_showDebug = false;
QFile* m_logFile = nullptr;
QTextStream* m_output = nullptr;
};
#endif // LOGHANDLER_H

15
client/loglevel.h Normal file
View File

@@ -0,0 +1,15 @@
/* 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 LOGLEVEL_H
#define LOGLEVEL_H
enum LogLevel {
Debug,
Info,
Warning,
Error,
};
#endif // LOGLEVEL_H

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 623 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 623 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 336 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 593 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 593 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@@ -0,0 +1,68 @@
{
"images" : [
{
"filename" : "16.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "16x16"
},
{
"filename" : "16@2x.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "16x16"
},
{
"filename" : "32.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "32x32"
},
{
"filename" : "32@2x.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "32x32"
},
{
"filename" : "128.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "128x128"
},
{
"filename" : "128@2x.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "128x128"
},
{
"filename" : "256.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "256x256"
},
{
"filename" : "256@2x.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "256x256"
},
{
"filename" : "512.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "512x512"
},
{
"filename" : "512@2x.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "512x512"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,50 @@
<?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>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleAllowMixedLocalizations</key>
<true/>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSApplicationCategoryType</key>
<string>public.app-category.utilities</string>
<key>LSMinimumSystemVersion</key>
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
<key>LSMultipleInstancesProhibited</key>
<true/>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<true/>
</dict>
</plist>

View 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

View File

@@ -0,0 +1,35 @@
<?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.application-identifier</key>
<string>$(DEVELOPMENT_TEAM).$(APP_ID_MACOS)</string>
<key>com.apple.developer.networking.networkextension</key>
<array>
<string>packet-tunnel-provider</string>
</array>
<key>keychain-access-groups</key>
<array>
<string>$(DEVELOPMENT_TEAM).*</string>
</array>
<key>com.apple.developer.team-identifier</key>
<string>$(DEVELOPMENT_TEAM)</string>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.application-groups</key>
<array>
<string>$(DEVELOPMENT_TEAM).$(GROUP_ID_MACOS)</string>
</array>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
</dict>
</plist>

Some files were not shown because too many files have changed in this diff Show More