Compare commits
40 Commits
0.0.201903
...
0.0.201904
Author | SHA1 | Date | |
---|---|---|---|
571349bb3d | |||
98ebd55208 | |||
83d0d34411 | |||
8c7c4b6792 | |||
5b34f49166 | |||
cef3957875 | |||
d9e88c51bd | |||
db876647d6 | |||
90eb45e287 | |||
9f3d86723a | |||
11063d0f88 | |||
557ee4390b | |||
9ce42d152d | |||
4c1b2e1258 | |||
3bd611aa7c | |||
adbe0b065e | |||
6015661beb | |||
6e6a6b88fb | |||
9690365dd4 | |||
0299c3929e | |||
0043233872 | |||
a74dd24578 | |||
dd9506ecee | |||
0c2eb003a0 | |||
f83f159f97 | |||
6175de0438 | |||
bd61be52e6 | |||
909f88be70 | |||
b7c3bd0d8c | |||
4237ab4a6f | |||
0fcaf6debb | |||
dbd5ea1ff0 | |||
9afe230c10 | |||
4bdfbb518e | |||
fbe101eabb | |||
cda3170970 | |||
a5e7c3906b | |||
b21fdfed67 | |||
5f8843e247 | |||
7a3f65fd2f |
@ -107,7 +107,7 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t view_lines_from_cursor(const struct log *input_log, uint32_t cursor, void(*cb)(const char *, uint64_t))
|
||||
uint32_t view_lines_from_cursor(const struct log *input_log, uint32_t cursor, void *ctx, void(*cb)(const char *, uint64_t, void *))
|
||||
{
|
||||
struct log *log;
|
||||
uint32_t l, i = cursor;
|
||||
@ -132,7 +132,7 @@ uint32_t view_lines_from_cursor(const struct log *input_log, uint32_t cursor, vo
|
||||
else
|
||||
break;
|
||||
}
|
||||
cb(line->line, line->time_ns);
|
||||
cb(line->line, line->time_ns, ctx);
|
||||
cursor = (i + 1) % MAX_LINES;
|
||||
}
|
||||
free(log);
|
||||
|
@ -11,7 +11,7 @@
|
||||
struct log;
|
||||
void write_msg_to_log(struct log *log, const char *tag, const char *msg);
|
||||
int write_log_to_file(const char *file_name, const struct log *input_log);
|
||||
uint32_t view_lines_from_cursor(const struct log *input_log, uint32_t cursor, void(*)(const char *, uint64_t));
|
||||
uint32_t view_lines_from_cursor(const struct log *input_log, uint32_t cursor, void *ctx, void(*)(const char *, uint64_t, void *));
|
||||
struct log *open_log(const char *file_name);
|
||||
void close_log(struct log *log);
|
||||
|
||||
|
@ -13,8 +13,8 @@ extension Data {
|
||||
return nil
|
||||
}
|
||||
var out = Data(repeating: 0, count: Int(WG_KEY_LEN_HEX))
|
||||
out.withUnsafeMutableBytes { outBytes in
|
||||
self.withUnsafeBytes { inBytes in
|
||||
out.withUnsafeMutableInt8Bytes { outBytes in
|
||||
self.withUnsafeUInt8Bytes { inBytes in
|
||||
key_to_hex(outBytes, inBytes)
|
||||
}
|
||||
}
|
||||
@ -25,7 +25,7 @@ extension Data {
|
||||
init?(hexKey hexString: String) {
|
||||
self.init(repeating: 0, count: Int(WG_KEY_LEN))
|
||||
|
||||
if !self.withUnsafeMutableBytes { key_from_hex($0, hexString) } {
|
||||
if !self.withUnsafeMutableUInt8Bytes { key_from_hex($0, hexString) } {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@ -35,8 +35,8 @@ extension Data {
|
||||
return nil
|
||||
}
|
||||
var out = Data(repeating: 0, count: Int(WG_KEY_LEN_BASE64))
|
||||
out.withUnsafeMutableBytes { outBytes in
|
||||
self.withUnsafeBytes { inBytes in
|
||||
out.withUnsafeMutableInt8Bytes { outBytes in
|
||||
self.withUnsafeUInt8Bytes { inBytes in
|
||||
key_to_base64(outBytes, inBytes)
|
||||
}
|
||||
}
|
||||
@ -47,8 +47,34 @@ extension Data {
|
||||
init?(base64Key base64String: String) {
|
||||
self.init(repeating: 0, count: Int(WG_KEY_LEN))
|
||||
|
||||
if !self.withUnsafeMutableBytes { key_from_base64($0, base64String) } {
|
||||
if !self.withUnsafeMutableUInt8Bytes { key_from_base64($0, base64String) } {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Data {
|
||||
func withUnsafeUInt8Bytes<R>(_ body: (UnsafePointer<UInt8>) -> R) -> R {
|
||||
assert(!isEmpty)
|
||||
return self.withUnsafeBytes { (ptr: UnsafeRawBufferPointer) -> R in
|
||||
let bytes = ptr.bindMemory(to: UInt8.self)
|
||||
return body(bytes.baseAddress!) // might crash if self.count == 0
|
||||
}
|
||||
}
|
||||
|
||||
mutating func withUnsafeMutableUInt8Bytes<R>(_ body: (UnsafeMutablePointer<UInt8>) -> R) -> R {
|
||||
assert(!isEmpty)
|
||||
return self.withUnsafeMutableBytes { (ptr: UnsafeMutableRawBufferPointer) -> R in
|
||||
let bytes = ptr.bindMemory(to: UInt8.self)
|
||||
return body(bytes.baseAddress!) // might crash if self.count == 0
|
||||
}
|
||||
}
|
||||
|
||||
mutating func withUnsafeMutableInt8Bytes<R>(_ body: (UnsafeMutablePointer<Int8>) -> R) -> R {
|
||||
assert(!isEmpty)
|
||||
return self.withUnsafeMutableBytes { (ptr: UnsafeMutableRawBufferPointer) -> R in
|
||||
let bytes = ptr.bindMemory(to: Int8.self)
|
||||
return body(bytes.baseAddress!) // might crash if self.count == 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,8 @@ extension Endpoint {
|
||||
return "\(address):\(port)"
|
||||
case .ipv6(let address):
|
||||
return "[\(address)]:\(port)"
|
||||
@unknown default:
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,6 +80,8 @@ extension Endpoint {
|
||||
return true
|
||||
case .ipv6:
|
||||
return true
|
||||
@unknown default:
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
|
||||
@ -89,6 +93,8 @@ extension Endpoint {
|
||||
return nil
|
||||
case .ipv6:
|
||||
return nil
|
||||
@unknown default:
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,9 +49,9 @@ extension NETunnelProviderProtocol {
|
||||
Keychain.deleteReference(called: ref)
|
||||
}
|
||||
|
||||
func verifyConfigurationReference() -> Data? {
|
||||
guard let ref = passwordReference else { return nil }
|
||||
return Keychain.verifyReference(called: ref) ? ref : nil
|
||||
func verifyConfigurationReference() -> Bool {
|
||||
guard let ref = passwordReference else { return false }
|
||||
return Keychain.verifyReference(called: ref)
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
|
@ -41,15 +41,16 @@
|
||||
6B62E45F220A6FA900EF34A6 /* PrivateDataConfirmation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B62E45E220A6FA900EF34A6 /* PrivateDataConfirmation.swift */; };
|
||||
6B62E460220A6FA900EF34A6 /* PrivateDataConfirmation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B62E45E220A6FA900EF34A6 /* PrivateDataConfirmation.swift */; };
|
||||
6B653B86220DE2960050E69C /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6FF4AC462120B9E0002C96EB /* NetworkExtension.framework */; };
|
||||
6B6956362211DA80001B618A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B6956352211DA80001B618A /* main.m */; };
|
||||
6B707D8421F918D4000A8F73 /* TunnelConfiguration+UapiConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B707D8321F918D4000A8F73 /* TunnelConfiguration+UapiConfig.swift */; };
|
||||
6B707D8621F918D4000A8F73 /* TunnelConfiguration+UapiConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6B707D8321F918D4000A8F73 /* TunnelConfiguration+UapiConfig.swift */; };
|
||||
6BAC16E6221634B300A5FB78 /* AppStorePrivacyNotice.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BAC16E42216324B00A5FB78 /* AppStorePrivacyNotice.swift */; };
|
||||
6BD5C97B220D1AE200784E08 /* key.c in Sources */ = {isa = PBXBuildFile; fileRef = 6BD5C979220D1AE100784E08 /* key.c */; };
|
||||
6BD5C97C220D1AE200784E08 /* key.c in Sources */ = {isa = PBXBuildFile; fileRef = 6BD5C979220D1AE100784E08 /* key.c */; };
|
||||
6BD5C97D220D1AE200784E08 /* key.c in Sources */ = {isa = PBXBuildFile; fileRef = 6BD5C979220D1AE100784E08 /* key.c */; };
|
||||
6BD5C97E220D1AE200784E08 /* key.c in Sources */ = {isa = PBXBuildFile; fileRef = 6BD5C979220D1AE100784E08 /* key.c */; };
|
||||
6F0F44C9222D55BB00B0FF04 /* TextCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F0F44C8222D55BB00B0FF04 /* TextCell.swift */; };
|
||||
6F0F44CB222D55FD00B0FF04 /* EditableTextCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F0F44CA222D55FD00B0FF04 /* EditableTextCell.swift */; };
|
||||
6F1075642258AE9800D78929 /* DeleteTunnelsConfirmationAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F1075632258AE9800D78929 /* DeleteTunnelsConfirmationAlert.swift */; };
|
||||
6F19D30422402B8700A126F2 /* ConfirmationAlertPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F19D30322402B8700A126F2 /* ConfirmationAlertPresenter.swift */; };
|
||||
6F4DD16B21DA558800690EAE /* TunnelListRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F4DD16A21DA558800690EAE /* TunnelListRow.swift */; };
|
||||
6F4DD16C21DA558F00690EAE /* NSTableView+Reuse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F4DD16721DA552B00690EAE /* NSTableView+Reuse.swift */; };
|
||||
@ -70,6 +71,7 @@
|
||||
6F693A562179E556008551C1 /* Endpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F693A552179E556008551C1 /* Endpoint.swift */; };
|
||||
6F70E20E221058E1008BDFB4 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6F70E20C221058DF008BDFB4 /* InfoPlist.strings */; };
|
||||
6F70E20F221058E1008BDFB4 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6F70E20C221058DF008BDFB4 /* InfoPlist.strings */; };
|
||||
6F70E23D22109E15008BDFB4 /* WireGuardLoginItemHelper.app in Embed Login Item Helper */ = {isa = PBXBuildFile; fileRef = 6F70E22922106A2D008BDFB4 /* WireGuardLoginItemHelper.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
6F7774E1217181B1006A79B3 /* MainViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F7774DF217181B1006A79B3 /* MainViewController.swift */; };
|
||||
6F7774E2217181B1006A79B3 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F7774E0217181B1006A79B3 /* AppDelegate.swift */; };
|
||||
6F7774E421718281006A79B3 /* TunnelsListTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F7774E321718281006A79B3 /* TunnelsListTableViewController.swift */; };
|
||||
@ -84,12 +86,15 @@
|
||||
6F8F0D7222258153000E8335 /* ActivateOnDemandViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F8F0D7022258153000E8335 /* ActivateOnDemandViewModel.swift */; };
|
||||
6F8F0D7422267AD2000E8335 /* ChevronCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F8F0D7322267AD2000E8335 /* ChevronCell.swift */; };
|
||||
6F8F0D7722267C57000E8335 /* SSIDOptionEditTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F8F0D7622267C57000E8335 /* SSIDOptionEditTableViewController.swift */; };
|
||||
6F907C9C224663A2003CED21 /* LogViewHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F907C9B224663A2003CED21 /* LogViewHelper.swift */; };
|
||||
6F907C9D224663A2003CED21 /* LogViewHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F907C9B224663A2003CED21 /* LogViewHelper.swift */; };
|
||||
6F919EC3218A2AE90023B400 /* ErrorPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F919EC2218A2AE90023B400 /* ErrorPresenter.swift */; };
|
||||
6F919ED9218C65C50023B400 /* wireguard_doc_logo_22x29.png in Resources */ = {isa = PBXBuildFile; fileRef = 6F919ED5218C65C50023B400 /* wireguard_doc_logo_22x29.png */; };
|
||||
6F919EDA218C65C50023B400 /* wireguard_doc_logo_44x58.png in Resources */ = {isa = PBXBuildFile; fileRef = 6F919ED6218C65C50023B400 /* wireguard_doc_logo_44x58.png */; };
|
||||
6F919EDB218C65C50023B400 /* wireguard_doc_logo_64x64.png in Resources */ = {isa = PBXBuildFile; fileRef = 6F919ED7218C65C50023B400 /* wireguard_doc_logo_64x64.png */; };
|
||||
6F919EDC218C65C50023B400 /* wireguard_doc_logo_320x320.png in Resources */ = {isa = PBXBuildFile; fileRef = 6F919ED8218C65C50023B400 /* wireguard_doc_logo_320x320.png */; };
|
||||
6F9B8A8E223398610041B9C4 /* SSIDOptionDetailTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F9B8A8D223398610041B9C4 /* SSIDOptionDetailTableViewController.swift */; };
|
||||
6FADE96C2254B8C300B838A4 /* UnusableTunnelDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FADE96A2254A6C200B838A4 /* UnusableTunnelDetailViewController.swift */; };
|
||||
6FB1017921C57DE600766195 /* MockTunnels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FB1017821C57DE600766195 /* MockTunnels.swift */; };
|
||||
6FB17946222FD5960018AE71 /* OnDemandWiFiControls.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FB17945222FD5960018AE71 /* OnDemandWiFiControls.swift */; };
|
||||
6FB1BD6021D2607A00A991BF /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FB1BD5F21D2607A00A991BF /* AppDelegate.swift */; };
|
||||
@ -155,6 +160,9 @@
|
||||
6FCD99B121E0EDA900BA4C82 /* TunnelEditViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FCD99B021E0EDA900BA4C82 /* TunnelEditViewController.swift */; };
|
||||
6FDB3C3B21DCF47400A0C0BF /* TunnelDetailTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FDB3C3A21DCF47400A0C0BF /* TunnelDetailTableViewController.swift */; };
|
||||
6FDB3C3C21DCF6BB00A0C0BF /* TunnelViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F628C3C217F09E9003482A3 /* TunnelViewModel.swift */; };
|
||||
6FDB6D13224A15BF00EE4BC3 /* LogViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FDB6D12224A15BE00EE4BC3 /* LogViewController.swift */; };
|
||||
6FDB6D15224CB2CE00EE4BC3 /* LogViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FDB6D14224CB2CE00EE4BC3 /* LogViewCell.swift */; };
|
||||
6FDB6D18224CC05A00EE4BC3 /* LogViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FDB6D16224CC04E00EE4BC3 /* LogViewController.swift */; };
|
||||
6FDEF7E421846C1A00D8FBF6 /* libwg-go.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 6FDEF7E321846C1A00D8FBF6 /* libwg-go.a */; };
|
||||
6FDEF7E62185EFB200D8FBF6 /* QRScanViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FDEF7E52185EFAF00D8FBF6 /* QRScanViewController.swift */; };
|
||||
6FDEF7FB21863B6100D8FBF6 /* unzip.c in Sources */ = {isa = PBXBuildFile; fileRef = 6FDEF7F621863B6100D8FBF6 /* unzip.c */; };
|
||||
@ -194,6 +202,13 @@
|
||||
remoteGlobalIDString = 6F5D0C19218352EF000F85AD;
|
||||
remoteInfo = WireGuardNetworkExtension;
|
||||
};
|
||||
6F70E23A22109DD3008BDFB4 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 6FF4AC0C211EC46F002C96EB /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = 6F70E22822106A2D008BDFB4;
|
||||
remoteInfo = WireGuardmacOSLoginItemHelper;
|
||||
};
|
||||
6FB1BD9721D4BFE700A991BF /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 6FF4AC0C211EC46F002C96EB /* Project object */;
|
||||
@ -229,6 +244,17 @@
|
||||
name = "Embed App Extensions";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
6F70E23C22109DE5008BDFB4 /* Embed Login Item Helper */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = Contents/Library/LoginItems;
|
||||
dstSubfolderSpec = 1;
|
||||
files = (
|
||||
6F70E23D22109E15008BDFB4 /* WireGuardLoginItemHelper.app in Embed Login Item Helper */,
|
||||
);
|
||||
name = "Embed Login Item Helper";
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
6FB1BD9D21D4BFE700A991BF /* Embed App Extensions */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@ -264,12 +290,13 @@
|
||||
6B586C52220CBA6D00427C51 /* Data+KeyEncoding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Data+KeyEncoding.swift"; sourceTree = "<group>"; };
|
||||
6B5C5E26220A48D30024272E /* Keychain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Keychain.swift; sourceTree = "<group>"; };
|
||||
6B62E45E220A6FA900EF34A6 /* PrivateDataConfirmation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrivateDataConfirmation.swift; sourceTree = "<group>"; };
|
||||
6B6956352211DA80001B618A /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
6B707D8321F918D4000A8F73 /* TunnelConfiguration+UapiConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TunnelConfiguration+UapiConfig.swift"; sourceTree = "<group>"; };
|
||||
6BAC16E42216324B00A5FB78 /* AppStorePrivacyNotice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppStorePrivacyNotice.swift; sourceTree = "<group>"; };
|
||||
6BD5C979220D1AE100784E08 /* key.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = key.c; sourceTree = "<group>"; };
|
||||
6BD5C97A220D1AE200784E08 /* key.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = key.h; sourceTree = "<group>"; };
|
||||
6F0F44C8222D55BB00B0FF04 /* TextCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextCell.swift; sourceTree = "<group>"; };
|
||||
6F0F44CA222D55FD00B0FF04 /* EditableTextCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditableTextCell.swift; sourceTree = "<group>"; };
|
||||
6F1075632258AE9800D78929 /* DeleteTunnelsConfirmationAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeleteTunnelsConfirmationAlert.swift; sourceTree = "<group>"; };
|
||||
6F19D30322402B8700A126F2 /* ConfirmationAlertPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfirmationAlertPresenter.swift; sourceTree = "<group>"; };
|
||||
6F4DD16721DA552B00690EAE /* NSTableView+Reuse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSTableView+Reuse.swift"; sourceTree = "<group>"; };
|
||||
6F4DD16A21DA558800690EAE /* TunnelListRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelListRow.swift; sourceTree = "<group>"; };
|
||||
@ -295,6 +322,9 @@
|
||||
6F6899A7218044FC0012E523 /* Curve25519.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Curve25519.swift; sourceTree = "<group>"; };
|
||||
6F693A552179E556008551C1 /* Endpoint.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Endpoint.swift; sourceTree = "<group>"; };
|
||||
6F70E20D221058DF008BDFB4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = WireGuard/Base.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
6F70E22922106A2D008BDFB4 /* WireGuardLoginItemHelper.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WireGuardLoginItemHelper.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
6F70E23222106A31008BDFB4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
6F70E23922109BEF008BDFB4 /* LoginItemHelper.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = LoginItemHelper.entitlements; sourceTree = "<group>"; };
|
||||
6F7774DF217181B1006A79B3 /* MainViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainViewController.swift; sourceTree = "<group>"; };
|
||||
6F7774E0217181B1006A79B3 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
6F7774E321718281006A79B3 /* TunnelsListTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TunnelsListTableViewController.swift; sourceTree = "<group>"; };
|
||||
@ -308,12 +338,14 @@
|
||||
6F8F0D7022258153000E8335 /* ActivateOnDemandViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivateOnDemandViewModel.swift; sourceTree = "<group>"; };
|
||||
6F8F0D7322267AD2000E8335 /* ChevronCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChevronCell.swift; sourceTree = "<group>"; };
|
||||
6F8F0D7622267C57000E8335 /* SSIDOptionEditTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SSIDOptionEditTableViewController.swift; sourceTree = "<group>"; };
|
||||
6F907C9B224663A2003CED21 /* LogViewHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogViewHelper.swift; sourceTree = "<group>"; };
|
||||
6F919EC2218A2AE90023B400 /* ErrorPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorPresenter.swift; sourceTree = "<group>"; };
|
||||
6F919ED5218C65C50023B400 /* wireguard_doc_logo_22x29.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = wireguard_doc_logo_22x29.png; sourceTree = "<group>"; };
|
||||
6F919ED6218C65C50023B400 /* wireguard_doc_logo_44x58.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = wireguard_doc_logo_44x58.png; sourceTree = "<group>"; };
|
||||
6F919ED7218C65C50023B400 /* wireguard_doc_logo_64x64.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = wireguard_doc_logo_64x64.png; sourceTree = "<group>"; };
|
||||
6F919ED8218C65C50023B400 /* wireguard_doc_logo_320x320.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = wireguard_doc_logo_320x320.png; sourceTree = "<group>"; };
|
||||
6F9B8A8D223398610041B9C4 /* SSIDOptionDetailTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SSIDOptionDetailTableViewController.swift; sourceTree = "<group>"; };
|
||||
6FADE96A2254A6C200B838A4 /* UnusableTunnelDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnusableTunnelDetailViewController.swift; sourceTree = "<group>"; };
|
||||
6FB1017821C57DE600766195 /* MockTunnels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockTunnels.swift; sourceTree = "<group>"; };
|
||||
6FB17945222FD5960018AE71 /* OnDemandWiFiControls.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnDemandWiFiControls.swift; sourceTree = "<group>"; };
|
||||
6FB1BD5D21D2607A00A991BF /* WireGuard.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WireGuard.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
@ -335,6 +367,9 @@
|
||||
6FCD99AE21E0EA1700BA4C82 /* ImportPanelPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImportPanelPresenter.swift; sourceTree = "<group>"; };
|
||||
6FCD99B021E0EDA900BA4C82 /* TunnelEditViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelEditViewController.swift; sourceTree = "<group>"; };
|
||||
6FDB3C3A21DCF47400A0C0BF /* TunnelDetailTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelDetailTableViewController.swift; sourceTree = "<group>"; };
|
||||
6FDB6D12224A15BE00EE4BC3 /* LogViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LogViewController.swift; sourceTree = "<group>"; };
|
||||
6FDB6D14224CB2CE00EE4BC3 /* LogViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogViewCell.swift; sourceTree = "<group>"; };
|
||||
6FDB6D16224CC04E00EE4BC3 /* LogViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogViewController.swift; sourceTree = "<group>"; };
|
||||
6FDEF7E321846C1A00D8FBF6 /* libwg-go.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; path = "libwg-go.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
6FDEF7E52185EFAF00D8FBF6 /* QRScanViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = QRScanViewController.swift; sourceTree = "<group>"; };
|
||||
6FDEF7F621863B6100D8FBF6 /* unzip.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = unzip.c; sourceTree = "<group>"; };
|
||||
@ -432,6 +467,7 @@
|
||||
6F7774DF217181B1006A79B3 /* MainViewController.swift */,
|
||||
6F8F0D7622267C57000E8335 /* SSIDOptionEditTableViewController.swift */,
|
||||
6F9B8A8D223398610041B9C4 /* SSIDOptionDetailTableViewController.swift */,
|
||||
6FDB6D16224CC04E00EE4BC3 /* LogViewController.swift */,
|
||||
);
|
||||
path = ViewController;
|
||||
sourceTree = "<group>";
|
||||
@ -448,6 +484,8 @@
|
||||
6FE3661C21F64F6B00F78C7D /* ConfTextColorTheme.swift */,
|
||||
6F5EA59A223E58A8002B380A /* ButtonRow.swift */,
|
||||
6FB17945222FD5960018AE71 /* OnDemandWiFiControls.swift */,
|
||||
6FDB6D14224CB2CE00EE4BC3 /* LogViewCell.swift */,
|
||||
6F1075632258AE9800D78929 /* DeleteTunnelsConfirmationAlert.swift */,
|
||||
);
|
||||
path = View;
|
||||
sourceTree = "<group>";
|
||||
@ -488,6 +526,16 @@
|
||||
path = Crypto;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
6F70E22A22106A2D008BDFB4 /* LoginItemHelper */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6F70E23922109BEF008BDFB4 /* LoginItemHelper.entitlements */,
|
||||
6F70E23222106A31008BDFB4 /* Info.plist */,
|
||||
6B6956352211DA80001B618A /* main.m */,
|
||||
);
|
||||
path = LoginItemHelper;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
6F7774DD217181B1006A79B3 /* UI */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -498,6 +546,7 @@
|
||||
6FBA103D21D6B6D70051C35F /* TunnelImporter.swift */,
|
||||
6FBA103A21D6B4280051C35F /* ErrorPresenterProtocol.swift */,
|
||||
6B62E45E220A6FA900EF34A6 /* PrivateDataConfirmation.swift */,
|
||||
6F907C9B224663A2003CED21 /* LogViewHelper.swift */,
|
||||
);
|
||||
path = UI;
|
||||
sourceTree = "<group>";
|
||||
@ -507,8 +556,8 @@
|
||||
children = (
|
||||
6FF4AC1E211EC472002C96EB /* Assets.xcassets */,
|
||||
6FF4AC20211EC472002C96EB /* LaunchScreen.storyboard */,
|
||||
5F4541AC21C4720B00994C13 /* ViewController */,
|
||||
5F4541A721C44F5B00994C13 /* View */,
|
||||
5F4541AC21C4720B00994C13 /* ViewController */,
|
||||
6F7774E0217181B1006A79B3 /* AppDelegate.swift */,
|
||||
6F919EC2218A2AE90023B400 /* ErrorPresenter.swift */,
|
||||
6F19D30322402B8700A126F2 /* ConfirmationAlertPresenter.swift */,
|
||||
@ -573,6 +622,7 @@
|
||||
6FB1BD5E21D2607A00A991BF /* macOS */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
6F70E22A22106A2D008BDFB4 /* LoginItemHelper */,
|
||||
6F4DD16921DA556600690EAE /* View */,
|
||||
6FBA104421D7EA750051C35F /* ViewController */,
|
||||
6FBA101321D613F30051C35F /* Application.swift */,
|
||||
@ -588,7 +638,6 @@
|
||||
6F4DD16721DA552B00690EAE /* NSTableView+Reuse.swift */,
|
||||
5F52D0BE21E3788900283CEA /* NSColor+Hex.swift */,
|
||||
6FFACD1E21E4D89600E9A2A5 /* ParseError+WireGuardAppError.swift */,
|
||||
6BAC16E42216324B00A5FB78 /* AppStorePrivacyNotice.swift */,
|
||||
);
|
||||
path = macOS;
|
||||
sourceTree = "<group>";
|
||||
@ -601,6 +650,8 @@
|
||||
6FDB3C3A21DCF47400A0C0BF /* TunnelDetailTableViewController.swift */,
|
||||
6FCD99A821E0E0C700BA4C82 /* ButtonedDetailViewController.swift */,
|
||||
6FCD99B021E0EDA900BA4C82 /* TunnelEditViewController.swift */,
|
||||
6FDB6D12224A15BE00EE4BC3 /* LogViewController.swift */,
|
||||
6FADE96A2254A6C200B838A4 /* UnusableTunnelDetailViewController.swift */,
|
||||
);
|
||||
path = ViewController;
|
||||
sourceTree = "<group>";
|
||||
@ -667,6 +718,7 @@
|
||||
6F5D0C1A218352EF000F85AD /* WireGuardNetworkExtension.appex */,
|
||||
6FB1BD5D21D2607A00A991BF /* WireGuard.app */,
|
||||
6FB1BD9121D4BFE600A991BF /* WireGuardNetworkExtension.appex */,
|
||||
6F70E22922106A2D008BDFB4 /* WireGuardLoginItemHelper.app */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
@ -753,6 +805,21 @@
|
||||
productReference = 6F5D0C1A218352EF000F85AD /* WireGuardNetworkExtension.appex */;
|
||||
productType = "com.apple.product-type.app-extension";
|
||||
};
|
||||
6F70E22822106A2D008BDFB4 /* WireGuardmacOSLoginItemHelper */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 6F70E23622106A31008BDFB4 /* Build configuration list for PBXNativeTarget "WireGuardmacOSLoginItemHelper" */;
|
||||
buildPhases = (
|
||||
6F70E22522106A2D008BDFB4 /* Sources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = WireGuardmacOSLoginItemHelper;
|
||||
productName = WireGuardmacOSLoginItemHelper;
|
||||
productReference = 6F70E22922106A2D008BDFB4 /* WireGuardLoginItemHelper.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
6FB1BD5C21D2607A00A991BF /* WireGuardmacOS */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 6FB1BD6A21D2607E00A991BF /* Build configuration list for PBXNativeTarget "WireGuardmacOS" */;
|
||||
@ -764,10 +831,12 @@
|
||||
6FB1BD5A21D2607A00A991BF /* Frameworks */,
|
||||
6FB1BD5B21D2607A00A991BF /* Resources */,
|
||||
6FB1BD9D21D4BFE700A991BF /* Embed App Extensions */,
|
||||
6F70E23C22109DE5008BDFB4 /* Embed Login Item Helper */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
6F70E23B22109DD3008BDFB4 /* PBXTargetDependency */,
|
||||
6FB1BD9821D4BFE700A991BF /* PBXTargetDependency */,
|
||||
);
|
||||
name = WireGuardmacOS;
|
||||
@ -829,10 +898,19 @@
|
||||
TargetAttributes = {
|
||||
6F5D0C19218352EF000F85AD = {
|
||||
CreatedOnToolsVersion = 10.0;
|
||||
LastSwiftMigration = 1000;
|
||||
LastSwiftMigration = 1020;
|
||||
};
|
||||
6F70E22822106A2D008BDFB4 = {
|
||||
CreatedOnToolsVersion = 10.1;
|
||||
SystemCapabilities = {
|
||||
com.apple.Sandbox = {
|
||||
enabled = 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
6FB1BD5C21D2607A00A991BF = {
|
||||
CreatedOnToolsVersion = 10.1;
|
||||
LastSwiftMigration = 1020;
|
||||
SystemCapabilities = {
|
||||
com.apple.ApplicationGroups.Mac = {
|
||||
enabled = 1;
|
||||
@ -847,6 +925,7 @@
|
||||
};
|
||||
6FB1BD9021D4BFE600A991BF = {
|
||||
CreatedOnToolsVersion = 10.1;
|
||||
LastSwiftMigration = 1020;
|
||||
SystemCapabilities = {
|
||||
com.apple.ApplicationGroups.Mac = {
|
||||
enabled = 1;
|
||||
@ -858,7 +937,7 @@
|
||||
};
|
||||
6FF4AC13211EC46F002C96EB = {
|
||||
CreatedOnToolsVersion = 9.4.1;
|
||||
LastSwiftMigration = 1000;
|
||||
LastSwiftMigration = 1020;
|
||||
SystemCapabilities = {
|
||||
com.apple.AccessWiFi = {
|
||||
enabled = 1;
|
||||
@ -892,6 +971,7 @@
|
||||
6FB1BD5C21D2607A00A991BF /* WireGuardmacOS */,
|
||||
6FB1BD9021D4BFE600A991BF /* WireGuardNetworkExtensionmacOS */,
|
||||
6FDAA03421CE69D000FA6925 /* WireGuardGoBridgemacOS */,
|
||||
6F70E22822106A2D008BDFB4 /* WireGuardmacOSLoginItemHelper */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
@ -1151,6 +1231,14 @@
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
6F70E22522106A2D008BDFB4 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
6B6956362211DA80001B618A /* main.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
6FB1BD5921D2607A00A991BF /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
@ -1167,6 +1255,7 @@
|
||||
6FB1BDD321D50F5300A991BF /* ZipArchive.swift in Sources */,
|
||||
6FB1BDD421D50F5300A991BF /* ioapi.c in Sources */,
|
||||
6FDB3C3C21DCF6BB00A0C0BF /* TunnelViewModel.swift in Sources */,
|
||||
6FDB6D13224A15BF00EE4BC3 /* LogViewController.swift in Sources */,
|
||||
6B5C5E29220A48D30024272E /* Keychain.swift in Sources */,
|
||||
6FCD99AF21E0EA1700BA4C82 /* ImportPanelPresenter.swift in Sources */,
|
||||
6FB1BDD521D50F5300A991BF /* unzip.c in Sources */,
|
||||
@ -1187,7 +1276,6 @@
|
||||
6FB1BDCA21D50F1700A991BF /* x25519.c in Sources */,
|
||||
6FB1BDCB21D50F1700A991BF /* Curve25519.swift in Sources */,
|
||||
6B586C55220CBA6D00427C51 /* Data+KeyEncoding.swift in Sources */,
|
||||
6BAC16E6221634B300A5FB78 /* AppStorePrivacyNotice.swift in Sources */,
|
||||
6FB17946222FD5960018AE71 /* OnDemandWiFiControls.swift in Sources */,
|
||||
6FB1BDBB21D50F0200A991BF /* Localizable.strings in Sources */,
|
||||
6FB1BDBC21D50F0200A991BF /* ringlogger.c in Sources */,
|
||||
@ -1196,12 +1284,15 @@
|
||||
6F89E17A21EDEB0E00C97BB9 /* StatusItemController.swift in Sources */,
|
||||
6F5EA59B223E58A8002B380A /* ButtonRow.swift in Sources */,
|
||||
6F4DD16B21DA558800690EAE /* TunnelListRow.swift in Sources */,
|
||||
6FDB6D15224CB2CE00EE4BC3 /* LogViewCell.swift in Sources */,
|
||||
6FE3661D21F64F6B00F78C7D /* ConfTextColorTheme.swift in Sources */,
|
||||
5F52D0BF21E3788900283CEA /* NSColor+Hex.swift in Sources */,
|
||||
6FB1BDBE21D50F0200A991BF /* Logger.swift in Sources */,
|
||||
6FB1BDBF21D50F0200A991BF /* TunnelConfiguration+WgQuickConfig.swift in Sources */,
|
||||
6FADE96C2254B8C300B838A4 /* UnusableTunnelDetailViewController.swift in Sources */,
|
||||
6FFACD2021E4D8D500E9A2A5 /* ParseError+WireGuardAppError.swift in Sources */,
|
||||
6FB1BDC021D50F0200A991BF /* NETunnelProviderProtocol+Extension.swift in Sources */,
|
||||
6F1075642258AE9800D78929 /* DeleteTunnelsConfirmationAlert.swift in Sources */,
|
||||
6FBA101821D656000051C35F /* StatusMenu.swift in Sources */,
|
||||
6F613D9B21DE33B8004B217A /* KeyValueRow.swift in Sources */,
|
||||
6FB1BDC121D50F0200A991BF /* String+ArrayConversion.swift in Sources */,
|
||||
@ -1214,6 +1305,7 @@
|
||||
6FB1BDC521D50F0300A991BF /* Endpoint.swift in Sources */,
|
||||
6FB1BDC621D50F0300A991BF /* DNSServer.swift in Sources */,
|
||||
6FB1BDC721D50F0300A991BF /* InterfaceConfiguration.swift in Sources */,
|
||||
6F907C9D224663A2003CED21 /* LogViewHelper.swift in Sources */,
|
||||
6FB1BDC821D50F0300A991BF /* PeerConfiguration.swift in Sources */,
|
||||
6FB1BDC921D50F0300A991BF /* FileManager+Extension.swift in Sources */,
|
||||
6FB1BD6021D2607A00A991BF /* AppDelegate.swift in Sources */,
|
||||
@ -1264,6 +1356,7 @@
|
||||
6B586C53220CBA6D00427C51 /* Data+KeyEncoding.swift in Sources */,
|
||||
6F693A562179E556008551C1 /* Endpoint.swift in Sources */,
|
||||
6FDEF7E62185EFB200D8FBF6 /* QRScanViewController.swift in Sources */,
|
||||
6FDB6D18224CC05A00EE4BC3 /* LogViewController.swift in Sources */,
|
||||
6FFA5D952194454A0001E2F7 /* NETunnelProviderProtocol+Extension.swift in Sources */,
|
||||
5FF7B96221CC95DE00A7DD74 /* InterfaceConfiguration.swift in Sources */,
|
||||
5F4541A921C451D100994C13 /* TunnelStatus.swift in Sources */,
|
||||
@ -1309,6 +1402,7 @@
|
||||
6F7774E1217181B1006A79B3 /* MainViewController.swift in Sources */,
|
||||
6FFA5DA42197085D0001E2F7 /* ActivateOnDemandOption.swift in Sources */,
|
||||
5F4541B221CBFAEE00994C13 /* String+ArrayConversion.swift in Sources */,
|
||||
6F907C9C224663A2003CED21 /* LogViewHelper.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -1320,6 +1414,11 @@
|
||||
target = 6F5D0C19218352EF000F85AD /* WireGuardNetworkExtensioniOS */;
|
||||
targetProxy = 6F5D0C20218352EF000F85AD /* PBXContainerItemProxy */;
|
||||
};
|
||||
6F70E23B22109DD3008BDFB4 /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 6F70E22822106A2D008BDFB4 /* WireGuardmacOSLoginItemHelper */;
|
||||
targetProxy = 6F70E23A22109DD3008BDFB4 /* PBXContainerItemProxy */;
|
||||
};
|
||||
6FB1BD9821D4BFE700A991BF /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = 6FB1BD9021D4BFE600A991BF /* WireGuardNetworkExtensionmacOS */;
|
||||
@ -1383,7 +1482,7 @@
|
||||
PRODUCT_NAME = WireGuardNetworkExtension;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "WireGuardNetworkExtension/WireGuardNetworkExtension-Bridging-Header.h";
|
||||
SWIFT_VERSION = 4.2;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@ -1405,7 +1504,33 @@
|
||||
PRODUCT_NAME = WireGuardNetworkExtension;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "WireGuardNetworkExtension/WireGuardNetworkExtension-Bridging-Header.h";
|
||||
SWIFT_VERSION = 4.2;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
6F70E23422106A31008BDFB4 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_ENTITLEMENTS = WireGuard/UI/macOS/LoginItemHelper/LoginItemHelper.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Mac Developer";
|
||||
INFOPLIST_FILE = WireGuard/UI/macOS/Info.plist;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "$(APP_ID_MACOS).login-item-helper";
|
||||
PRODUCT_NAME = WireGuardLoginItemHelper;
|
||||
SDKROOT = macosx;
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
6F70E23522106A31008BDFB4 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_ENTITLEMENTS = WireGuard/UI/macOS/LoginItemHelper/LoginItemHelper.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Mac Developer";
|
||||
INFOPLIST_FILE = WireGuard/UI/macOS/Info.plist;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "$(APP_ID_MACOS).login-item-helper";
|
||||
PRODUCT_NAME = WireGuardLoginItemHelper;
|
||||
SDKROOT = macosx;
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
@ -1425,6 +1550,7 @@
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "$(APP_ID_MACOS)";
|
||||
PRODUCT_NAME = WireGuard;
|
||||
SDKROOT = macosx;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@ -1444,6 +1570,7 @@
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "$(APP_ID_MACOS)";
|
||||
PRODUCT_NAME = WireGuard;
|
||||
SDKROOT = macosx;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
@ -1465,6 +1592,7 @@
|
||||
SDKROOT = macosx;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "WireGuardNetworkExtension/WireGuardNetworkExtension-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@ -1486,6 +1614,7 @@
|
||||
SDKROOT = macosx;
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "WireGuardNetworkExtension/WireGuardNetworkExtension-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
@ -1662,6 +1791,7 @@
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "$(APP_ID_IOS)";
|
||||
PRODUCT_NAME = WireGuard;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
@ -1678,6 +1808,7 @@
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = "$(APP_ID_IOS)";
|
||||
PRODUCT_NAME = WireGuard;
|
||||
SWIFT_VERSION = 5.0;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
@ -1693,6 +1824,15 @@
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
6F70E23622106A31008BDFB4 /* Build configuration list for PBXNativeTarget "WireGuardmacOSLoginItemHelper" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
6F70E23422106A31008BDFB4 /* Debug */,
|
||||
6F70E23522106A31008BDFB4 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
6FB1BD6A21D2607E00A991BF /* Build configuration list for PBXNativeTarget "WireGuardmacOS" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
|
@ -37,8 +37,8 @@
|
||||
"alertBadConfigImportMessage (%@)" = "The file ‘%@’ does not contain a valid WireGuard configuration";
|
||||
|
||||
"deleteTunnelsConfirmationAlertButtonTitle" = "Delete";
|
||||
"deleteTunnelConfirmationAlertButtonMessage (%d)" = "Delete %d tunnel";
|
||||
"deleteTunnelsConfirmationAlertButtonMessage (%d)" = "Delete %d tunnels";
|
||||
"deleteTunnelConfirmationAlertButtonMessage (%d)" = "Delete %d tunnel?";
|
||||
"deleteTunnelsConfirmationAlertButtonMessage (%d)" = "Delete %d tunnels?";
|
||||
|
||||
// Tunnel detail and edit UI
|
||||
|
||||
@ -209,10 +209,14 @@
|
||||
"settingsSectionTitleExportConfigurations" = "Export configurations";
|
||||
"settingsExportZipButtonTitle" = "Export zip archive";
|
||||
|
||||
"settingsSectionTitleTunnelLog" = "Tunnel log";
|
||||
"settingsExportLogFileButtonTitle" = "Export log file";
|
||||
"settingsSectionTitleTunnelLog" = "Log";
|
||||
"settingsViewLogButtonTitle" = "View log";
|
||||
|
||||
// Settings alerts
|
||||
// Log view
|
||||
|
||||
"logViewTitle" = "Log";
|
||||
|
||||
// Log alerts
|
||||
|
||||
"alertUnableToRemovePreviousLogTitle" = "Log export failed";
|
||||
"alertUnableToRemovePreviousLogMessage" = "The pre-existing log could not be cleared";
|
||||
@ -296,7 +300,7 @@
|
||||
"macMenuManageTunnels" = "Manage tunnels";
|
||||
"macMenuImportTunnels" = "Import tunnel(s) from file…";
|
||||
"macMenuAddEmptyTunnel" = "Add empty tunnel…";
|
||||
"macMenuExportLog" = "Export log to file…";
|
||||
"macMenuViewLog" = "View log";
|
||||
"macMenuExportTunnels" = "Export tunnels to zip…";
|
||||
"macMenuAbout" = "About WireGuard";
|
||||
"macMenuQuit" = "Quit";
|
||||
@ -310,14 +314,15 @@
|
||||
"macDeleteTunnelConfirmationAlertInfo" = "You cannot undo this action.";
|
||||
"macDeleteTunnelConfirmationAlertButtonTitleDelete" = "Delete";
|
||||
"macDeleteTunnelConfirmationAlertButtonTitleCancel" = "Cancel";
|
||||
"macDeleteTunnelConfirmationAlertButtonTitleDeleting" = "Deleting…";
|
||||
|
||||
"macButtonImportTunnels" = "Import tunnel(s) from file";
|
||||
"macSheetButtonImport" = "Import";
|
||||
|
||||
"macNameFieldExportLog" = "Export log to";
|
||||
"macNameFieldExportLog" = "Save log to:";
|
||||
"macSheetButtonExportLog" = "Save";
|
||||
|
||||
"macNameFieldExportZip" = "Export tunnels to";
|
||||
"macNameFieldExportZip" = "Export tunnels to:";
|
||||
"macSheetButtonExportZip" = "Save";
|
||||
|
||||
"macButtonDeleteTunnels (%d)" = "Delete %d tunnels";
|
||||
@ -387,3 +392,16 @@
|
||||
|
||||
"macToolTipEditTunnel" = "Edit tunnel (⌘E)";
|
||||
"macToolTipToggleStatus" = "Toggle status (⌘T)";
|
||||
|
||||
// Mac log view
|
||||
|
||||
"macLogColumnTitleTime" = "Time";
|
||||
"macLogColumnTitleLogMessage" = "Log message";
|
||||
"macLogButtonTitleClose" = "Close";
|
||||
"macLogButtonTitleSave" = "Save…";
|
||||
|
||||
// Mac unusable tunnel view
|
||||
|
||||
"macUnusableTunnelMessage" = "The configuration for this tunnel cannot be found in the keychain.";
|
||||
"macUnusableTunnelInfo" = "In case this tunnel was created by another user, only that user can view, edit, or activate this tunnel.";
|
||||
"macUnusableTunnelButtonTitleDeleteTunnel" = "Delete tunnel";
|
||||
|
@ -1,2 +1,2 @@
|
||||
VERSION_NAME = 0.0.20190319
|
||||
VERSION_ID = 4
|
||||
VERSION_NAME = 0.0.20190409
|
||||
VERSION_ID = 7
|
||||
|
@ -9,7 +9,7 @@ struct Curve25519 {
|
||||
|
||||
static func generatePrivateKey() -> Data {
|
||||
var privateKey = Data(repeating: 0, count: TunnelConfiguration.keyLength)
|
||||
privateKey.withUnsafeMutableBytes { bytes in
|
||||
privateKey.withUnsafeMutableUInt8Bytes { bytes in
|
||||
curve25519_generate_private_key(bytes)
|
||||
}
|
||||
assert(privateKey.count == TunnelConfiguration.keyLength)
|
||||
@ -19,8 +19,8 @@ struct Curve25519 {
|
||||
static func generatePublicKey(fromPrivateKey privateKey: Data) -> Data {
|
||||
assert(privateKey.count == TunnelConfiguration.keyLength)
|
||||
var publicKey = Data(repeating: 0, count: TunnelConfiguration.keyLength)
|
||||
privateKey.withUnsafeBytes { privateKeyBytes in
|
||||
publicKey.withUnsafeMutableBytes { bytes in
|
||||
privateKey.withUnsafeUInt8Bytes { privateKeyBytes in
|
||||
publicKey.withUnsafeMutableUInt8Bytes { bytes in
|
||||
curve25519_derive_public_key(bytes, privateKeyBytes)
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,8 @@ import NetworkExtension
|
||||
self = .reasserting
|
||||
case .invalid:
|
||||
self = .inactive
|
||||
@unknown default:
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -54,6 +56,8 @@ extension NEVPNStatus: CustomDebugStringConvertible {
|
||||
case .disconnecting: return "disconnecting"
|
||||
case .reasserting: return "reasserting"
|
||||
case .invalid: return "invalid"
|
||||
@unknown default:
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,11 +47,18 @@ class TunnelsManager {
|
||||
var tunnelManagers = managers ?? []
|
||||
var refs: Set<Data> = []
|
||||
for (index, tunnelManager) in tunnelManagers.enumerated().reversed() {
|
||||
let proto = tunnelManager.protocolConfiguration as? NETunnelProviderProtocol
|
||||
if proto?.migrateConfigurationIfNeeded(called: tunnelManager.localizedDescription ?? "unknown") ?? false {
|
||||
guard let proto = tunnelManager.protocolConfiguration as? NETunnelProviderProtocol else { continue }
|
||||
if proto.migrateConfigurationIfNeeded(called: tunnelManager.localizedDescription ?? "unknown") {
|
||||
tunnelManager.saveToPreferences { _ in }
|
||||
}
|
||||
if let ref = proto?.verifyConfigurationReference() {
|
||||
#if os(iOS)
|
||||
let passwordRef = proto.verifyConfigurationReference() ? proto.passwordReference : nil
|
||||
#elseif os(macOS)
|
||||
let passwordRef = proto.passwordReference // To handle multiple users in macOS, we skip verifying
|
||||
#else
|
||||
#error("Unimplemented")
|
||||
#endif
|
||||
if let ref = passwordRef {
|
||||
refs.insert(ref)
|
||||
} else {
|
||||
tunnelManager.removeFromPreferences { _ in }
|
||||
@ -71,14 +78,14 @@ class TunnelsManager {
|
||||
let loadedTunnelProviders = managers ?? []
|
||||
|
||||
for (index, currentTunnel) in self.tunnels.enumerated().reversed() {
|
||||
if !loadedTunnelProviders.contains(where: { $0.tunnelConfiguration == currentTunnel.tunnelConfiguration }) {
|
||||
if !loadedTunnelProviders.contains(where: { $0.isEquivalentTo(currentTunnel) }) {
|
||||
// Tunnel was deleted outside the app
|
||||
self.tunnels.remove(at: index)
|
||||
self.tunnelsListDelegate?.tunnelRemoved(at: index, tunnel: currentTunnel)
|
||||
}
|
||||
}
|
||||
for loadedTunnelProvider in loadedTunnelProviders {
|
||||
if let matchingTunnel = self.tunnels.first(where: { $0.tunnelConfiguration == loadedTunnelProvider.tunnelConfiguration }) {
|
||||
if let matchingTunnel = self.tunnels.first(where: { loadedTunnelProvider.isEquivalentTo($0) }) {
|
||||
matchingTunnel.tunnelProvider = loadedTunnelProvider
|
||||
matchingTunnel.refreshStatus()
|
||||
} else {
|
||||
@ -238,7 +245,9 @@ class TunnelsManager {
|
||||
|
||||
func remove(tunnel: TunnelContainer, completionHandler: @escaping (TunnelsManagerError?) -> Void) {
|
||||
let tunnelProviderManager = tunnel.tunnelProvider
|
||||
(tunnelProviderManager.protocolConfiguration as? NETunnelProviderProtocol)?.destroyConfigurationReference()
|
||||
if tunnel.isTunnelConfigurationAvailableInKeychain {
|
||||
(tunnelProviderManager.protocolConfiguration as? NETunnelProviderProtocol)?.destroyConfigurationReference()
|
||||
}
|
||||
|
||||
tunnelProviderManager.removeFromPreferences { [weak self] error in
|
||||
guard error == nil else {
|
||||
@ -455,6 +464,10 @@ class TunnelContainer: NSObject {
|
||||
return tunnelProvider.tunnelConfiguration
|
||||
}
|
||||
|
||||
var isTunnelConfigurationAvailableInKeychain: Bool {
|
||||
return tunnelProvider.isTunnelConfigurationAvailableInKeychain
|
||||
}
|
||||
|
||||
var onDemandOption: ActivateOnDemandOption {
|
||||
return ActivateOnDemandOption(from: tunnelProvider)
|
||||
}
|
||||
@ -473,7 +486,7 @@ class TunnelContainer: NSObject {
|
||||
completionHandler(tunnelConfiguration)
|
||||
return
|
||||
}
|
||||
guard nil != (try? session.sendProviderMessage(Data(bytes: [ 0 ]), responseHandler: {
|
||||
guard nil != (try? session.sendProviderMessage(Data([ UInt8(0) ]), responseHandler: {
|
||||
guard self.status != .inactive, let data = $0, let base = self.tunnelConfiguration, let settings = String(data: data, encoding: .utf8) else {
|
||||
completionHandler(self.tunnelConfiguration)
|
||||
return
|
||||
@ -567,7 +580,18 @@ class TunnelContainer: NSObject {
|
||||
}
|
||||
|
||||
extension NETunnelProviderManager {
|
||||
private static var cachedIsConfigAvailableInKeychainKey: UInt8 = 0
|
||||
private static var cachedConfigKey: UInt8 = 0
|
||||
|
||||
var isTunnelConfigurationAvailableInKeychain: Bool {
|
||||
if let cachedNumber = objc_getAssociatedObject(self, &NETunnelProviderManager.cachedIsConfigAvailableInKeychainKey) as? NSNumber {
|
||||
return cachedNumber.boolValue
|
||||
}
|
||||
let isAvailable = (protocolConfiguration as? NETunnelProviderProtocol)?.verifyConfigurationReference() ?? false
|
||||
objc_setAssociatedObject(self, &NETunnelProviderManager.cachedIsConfigAvailableInKeychainKey, NSNumber(value: isAvailable), objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
|
||||
return isAvailable
|
||||
}
|
||||
|
||||
var tunnelConfiguration: TunnelConfiguration? {
|
||||
if let cached = objc_getAssociatedObject(self, &NETunnelProviderManager.cachedConfigKey) as? TunnelConfiguration {
|
||||
return cached
|
||||
@ -583,5 +607,17 @@ extension NETunnelProviderManager {
|
||||
protocolConfiguration = NETunnelProviderProtocol(tunnelConfiguration: tunnelConfiguration, previouslyFrom: protocolConfiguration)
|
||||
localizedDescription = tunnelConfiguration.name
|
||||
objc_setAssociatedObject(self, &NETunnelProviderManager.cachedConfigKey, tunnelConfiguration, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
|
||||
objc_setAssociatedObject(self, &NETunnelProviderManager.cachedIsConfigAvailableInKeychainKey, NSNumber(value: true), objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
|
||||
}
|
||||
|
||||
func isEquivalentTo(_ tunnel: TunnelContainer) -> Bool {
|
||||
switch (isTunnelConfigurationAvailableInKeychain, tunnel.isTunnelConfigurationAvailableInKeychain) {
|
||||
case (true, true):
|
||||
return tunnelConfiguration == tunnel.tunnelConfiguration
|
||||
case (false, false):
|
||||
return localizedDescription == tunnel.name
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
57
WireGuard/WireGuard/UI/LogViewHelper.swift
Normal file
57
WireGuard/WireGuard/UI/LogViewHelper.swift
Normal file
@ -0,0 +1,57 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved.
|
||||
|
||||
import Foundation
|
||||
|
||||
public class LogViewHelper {
|
||||
var log: OpaquePointer
|
||||
var cursor: UInt32 = UINT32_MAX
|
||||
static let formatOptions: ISO8601DateFormatter.Options = [
|
||||
.withYear, .withMonth, .withDay, .withTime,
|
||||
.withDashSeparatorInDate, .withColonSeparatorInTime, .withSpaceBetweenDateAndTime,
|
||||
.withFractionalSeconds
|
||||
]
|
||||
|
||||
struct LogEntry {
|
||||
let timestamp: String
|
||||
let message: String
|
||||
|
||||
func text() -> String {
|
||||
return timestamp + " " + message
|
||||
}
|
||||
}
|
||||
|
||||
class LogEntries {
|
||||
var entries: [LogEntry] = []
|
||||
}
|
||||
|
||||
init?(logFilePath: String?) {
|
||||
guard let logFilePath = logFilePath else { return nil }
|
||||
guard let log = open_log(logFilePath) else { return nil }
|
||||
self.log = log
|
||||
}
|
||||
|
||||
deinit {
|
||||
close_log(self.log)
|
||||
}
|
||||
|
||||
func fetchLogEntriesSinceLastFetch(completion: @escaping ([LogViewHelper.LogEntry]) -> Void) {
|
||||
var logEntries = LogEntries()
|
||||
DispatchQueue.global(qos: .userInitiated).async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
let newCursor = view_lines_from_cursor(self.log, self.cursor, &logEntries) { cStr, timestamp, ctx in
|
||||
let message = cStr != nil ? String(cString: cStr!) : ""
|
||||
let date = Date(timeIntervalSince1970: Double(timestamp) / 1000000000)
|
||||
let dateString = ISO8601DateFormatter.string(from: date, timeZone: TimeZone.current, formatOptions: LogViewHelper.formatOptions)
|
||||
if let logEntries = ctx?.bindMemory(to: LogEntries.self, capacity: 1) {
|
||||
logEntries.pointee.entries.append(LogEntry(timestamp: dateString, message: message))
|
||||
}
|
||||
}
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.cursor = newCursor
|
||||
completion(logEntries.entries)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -82,7 +82,6 @@
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
|
@ -0,0 +1,129 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved.
|
||||
|
||||
import UIKit
|
||||
|
||||
class LogViewController: UIViewController {
|
||||
|
||||
let textView: UITextView = {
|
||||
let textView = UITextView()
|
||||
textView.isEditable = false
|
||||
textView.isSelectable = true
|
||||
textView.font = UIFont.preferredFont(forTextStyle: UIFont.TextStyle.body)
|
||||
textView.adjustsFontForContentSizeCategory = true
|
||||
return textView
|
||||
}()
|
||||
|
||||
let busyIndicator: UIActivityIndicatorView = {
|
||||
let busyIndicator = UIActivityIndicatorView(style: .gray)
|
||||
busyIndicator.hidesWhenStopped = true
|
||||
return busyIndicator
|
||||
}()
|
||||
|
||||
var logViewHelper: LogViewHelper?
|
||||
var isFetchingLogEntries = false
|
||||
private var updateLogEntriesTimer: Timer?
|
||||
|
||||
override func loadView() {
|
||||
view = UIView()
|
||||
view.backgroundColor = .white
|
||||
|
||||
view.addSubview(textView)
|
||||
textView.translatesAutoresizingMaskIntoConstraints = false
|
||||
NSLayoutConstraint.activate([
|
||||
textView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
||||
textView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
||||
textView.topAnchor.constraint(equalTo: view.topAnchor),
|
||||
textView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
|
||||
])
|
||||
|
||||
view.addSubview(busyIndicator)
|
||||
busyIndicator.translatesAutoresizingMaskIntoConstraints = false
|
||||
NSLayoutConstraint.activate([
|
||||
busyIndicator.centerXAnchor.constraint(equalTo: view.centerXAnchor),
|
||||
busyIndicator.centerYAnchor.constraint(equalTo: view.centerYAnchor)
|
||||
])
|
||||
|
||||
busyIndicator.startAnimating()
|
||||
|
||||
logViewHelper = LogViewHelper(logFilePath: FileManager.logFileURL?.path)
|
||||
startUpdatingLogEntries()
|
||||
}
|
||||
|
||||
override func viewDidLoad() {
|
||||
title = tr("logViewTitle")
|
||||
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .save, target: self, action: #selector(saveTapped(sender:)))
|
||||
}
|
||||
|
||||
func updateLogEntries() {
|
||||
guard !isFetchingLogEntries else { return }
|
||||
isFetchingLogEntries = true
|
||||
logViewHelper?.fetchLogEntriesSinceLastFetch { [weak self] fetchedLogEntries in
|
||||
guard let self = self else { return }
|
||||
defer {
|
||||
self.isFetchingLogEntries = false
|
||||
}
|
||||
if self.busyIndicator.isAnimating {
|
||||
self.busyIndicator.stopAnimating()
|
||||
}
|
||||
guard !fetchedLogEntries.isEmpty else { return }
|
||||
let isScrolledToEnd = self.textView.contentSize.height - self.textView.bounds.height - self.textView.contentOffset.y < 1
|
||||
let text = fetchedLogEntries.reduce("") { $0 + $1.text() + "\n" }
|
||||
let font = UIFont.preferredFont(forTextStyle: UIFont.TextStyle.body)
|
||||
let richText = NSAttributedString(string: text, attributes: [.font: font])
|
||||
self.textView.textStorage.append(richText)
|
||||
if isScrolledToEnd {
|
||||
let endOfCurrentText = NSRange(location: (self.textView.text as NSString).length, length: 0)
|
||||
self.textView.scrollRangeToVisible(endOfCurrentText)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func startUpdatingLogEntries() {
|
||||
updateLogEntries()
|
||||
updateLogEntriesTimer?.invalidate()
|
||||
let timer = Timer(timeInterval: 1 /* second */, repeats: true) { [weak self] _ in
|
||||
self?.updateLogEntries()
|
||||
}
|
||||
updateLogEntriesTimer = timer
|
||||
RunLoop.main.add(timer, forMode: .common)
|
||||
}
|
||||
|
||||
@objc func saveTapped(sender: AnyObject) {
|
||||
guard let destinationDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return }
|
||||
|
||||
let dateFormatter = ISO8601DateFormatter()
|
||||
dateFormatter.formatOptions = [.withFullDate, .withTime, .withTimeZone] // Avoid ':' in the filename
|
||||
let timeStampString = dateFormatter.string(from: Date())
|
||||
let destinationURL = destinationDir.appendingPathComponent("wireguard-log-\(timeStampString).txt")
|
||||
|
||||
DispatchQueue.global(qos: .userInitiated).async {
|
||||
|
||||
if FileManager.default.fileExists(atPath: destinationURL.path) {
|
||||
let isDeleted = FileManager.deleteFile(at: destinationURL)
|
||||
if !isDeleted {
|
||||
ErrorPresenter.showErrorAlert(title: tr("alertUnableToRemovePreviousLogTitle"), message: tr("alertUnableToRemovePreviousLogMessage"), from: self)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
let isWritten = Logger.global?.writeLog(to: destinationURL.path) ?? false
|
||||
|
||||
DispatchQueue.main.async {
|
||||
guard isWritten else {
|
||||
ErrorPresenter.showErrorAlert(title: tr("alertUnableToWriteLogTitle"), message: tr("alertUnableToWriteLogMessage"), from: self)
|
||||
return
|
||||
}
|
||||
let activityVC = UIActivityViewController(activityItems: [destinationURL], applicationActivities: nil)
|
||||
if let sender = sender as? UIBarButtonItem {
|
||||
activityVC.popoverPresentationController?.barButtonItem = sender
|
||||
}
|
||||
activityVC.completionWithItemsHandler = { _, _, _, _ in
|
||||
// Remove the exported log file after the activity has completed
|
||||
_ = FileManager.deleteFile(at: destinationURL)
|
||||
}
|
||||
self.present(activityVC, animated: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -10,14 +10,14 @@ class SettingsTableViewController: UITableViewController {
|
||||
case iosAppVersion
|
||||
case goBackendVersion
|
||||
case exportZipArchive
|
||||
case exportLogFile
|
||||
case viewLog
|
||||
|
||||
var localizedUIString: String {
|
||||
switch self {
|
||||
case .iosAppVersion: return tr("settingsVersionKeyWireGuardForIOS")
|
||||
case .goBackendVersion: return tr("settingsVersionKeyWireGuardGoBackend")
|
||||
case .exportZipArchive: return tr("settingsExportZipButtonTitle")
|
||||
case .exportLogFile: return tr("settingsExportLogFileButtonTitle")
|
||||
case .viewLog: return tr("settingsViewLogButtonTitle")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -25,7 +25,7 @@ class SettingsTableViewController: UITableViewController {
|
||||
let settingsFieldsBySection: [[SettingsFields]] = [
|
||||
[.iosAppVersion, .goBackendVersion],
|
||||
[.exportZipArchive],
|
||||
[.exportLogFile]
|
||||
[.viewLog]
|
||||
]
|
||||
|
||||
let tunnelsManager: TunnelsManager?
|
||||
@ -108,41 +108,10 @@ class SettingsTableViewController: UITableViewController {
|
||||
}
|
||||
}
|
||||
|
||||
func exportLogForLastActivatedTunnel(sourceView: UIView) {
|
||||
guard let destinationDir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else { return }
|
||||
func presentLogView() {
|
||||
let logVC = LogViewController()
|
||||
navigationController?.pushViewController(logVC, animated: true)
|
||||
|
||||
let dateFormatter = ISO8601DateFormatter()
|
||||
dateFormatter.formatOptions = [.withFullDate, .withTime, .withTimeZone] // Avoid ':' in the filename
|
||||
let timeStampString = dateFormatter.string(from: Date())
|
||||
let destinationURL = destinationDir.appendingPathComponent("wireguard-log-\(timeStampString).txt")
|
||||
|
||||
DispatchQueue.global(qos: .userInitiated).async {
|
||||
|
||||
if FileManager.default.fileExists(atPath: destinationURL.path) {
|
||||
let isDeleted = FileManager.deleteFile(at: destinationURL)
|
||||
if !isDeleted {
|
||||
ErrorPresenter.showErrorAlert(title: tr("alertUnableToRemovePreviousLogTitle"), message: tr("alertUnableToRemovePreviousLogMessage"), from: self)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
let isWritten = Logger.global?.writeLog(to: destinationURL.path) ?? false
|
||||
|
||||
DispatchQueue.main.async {
|
||||
guard isWritten else {
|
||||
ErrorPresenter.showErrorAlert(title: tr("alertUnableToWriteLogTitle"), message: tr("alertUnableToWriteLogMessage"), from: self)
|
||||
return
|
||||
}
|
||||
let activityVC = UIActivityViewController(activityItems: [destinationURL], applicationActivities: nil)
|
||||
activityVC.popoverPresentationController?.sourceView = sourceView
|
||||
activityVC.popoverPresentationController?.sourceRect = sourceView.bounds
|
||||
activityVC.completionWithItemsHandler = { _, _, _, _ in
|
||||
// Remove the exported log file after the activity has completed
|
||||
_ = FileManager.deleteFile(at: destinationURL)
|
||||
}
|
||||
self.present(activityVC, animated: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -192,11 +161,11 @@ extension SettingsTableViewController {
|
||||
}
|
||||
return cell
|
||||
} else {
|
||||
assert(field == .exportLogFile)
|
||||
assert(field == .viewLog)
|
||||
let cell: ButtonCell = tableView.dequeueReusableCell(for: indexPath)
|
||||
cell.buttonText = field.localizedUIString
|
||||
cell.onTapped = { [weak self] in
|
||||
self?.exportLogForLastActivatedTunnel(sourceView: cell.button)
|
||||
self?.presentLogView()
|
||||
}
|
||||
return cell
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved.
|
||||
|
||||
import Cocoa
|
||||
import ServiceManagement
|
||||
|
||||
@NSApplicationMain
|
||||
class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
@ -15,6 +16,7 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
|
||||
func applicationDidFinishLaunching(_ aNotification: Notification) {
|
||||
Logger.configureGlobal(tagged: "APP", withFilePath: FileManager.logFileURL?.path)
|
||||
registerLoginItem(shouldLaunchAtLogin: true)
|
||||
|
||||
TunnelsManager.create { [weak self] result in
|
||||
guard let self = self else { return }
|
||||
@ -42,6 +44,12 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
}
|
||||
|
||||
@objc func quit() {
|
||||
if let manageWindow = manageTunnelsWindowObject, manageWindow.attachedSheet != nil {
|
||||
NSApp.activate(ignoringOtherApps: true)
|
||||
manageWindow.orderFront(self)
|
||||
return
|
||||
}
|
||||
registerLoginItem(shouldLaunchAtLogin: false)
|
||||
guard let currentTunnel = tunnelsTracker?.currentTunnel, currentTunnel.status == .active || currentTunnel.status == .activating else {
|
||||
NSApp.terminate(nil)
|
||||
return
|
||||
@ -49,8 +57,10 @@ class AppDelegate: NSObject, NSApplicationDelegate {
|
||||
let alert = NSAlert()
|
||||
alert.messageText = tr("macAppExitingWithActiveTunnelMessage")
|
||||
alert.informativeText = tr("macAppExitingWithActiveTunnelInfo")
|
||||
if let window = manageTunnelsWindowObject {
|
||||
alert.beginSheetModal(for: window) { _ in
|
||||
NSApp.activate(ignoringOtherApps: true)
|
||||
if let manageWindow = manageTunnelsWindowObject {
|
||||
manageWindow.orderFront(self)
|
||||
alert.beginSheetModal(for: manageWindow) { _ in
|
||||
NSApp.terminate(nil)
|
||||
}
|
||||
} else {
|
||||
@ -74,3 +84,10 @@ extension AppDelegate: StatusMenuWindowDelegate {
|
||||
return manageTunnelsWindowObject!
|
||||
}
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
func registerLoginItem(shouldLaunchAtLogin: Bool) -> Bool {
|
||||
let appId = Bundle.main.bundleIdentifier!
|
||||
let helperBundleId = "\(appId).login-item-helper"
|
||||
return SMLoginItemSetEnabled(helperBundleId as CFString, shouldLaunchAtLogin)
|
||||
}
|
||||
|
@ -1,29 +0,0 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved.
|
||||
|
||||
import Cocoa
|
||||
|
||||
class AppStorePrivacyNotice {
|
||||
// The App Store Review Board does not comprehend the fact that this application
|
||||
// is not a service and does not have any servers of its own. They therefore require
|
||||
// us to give a notice regarding collection of user data using our non-existent
|
||||
// servers. This demand is obviously impossible to fulfill, since it doesn't make sense,
|
||||
// but we do our best here to show something in that category.
|
||||
static func show(from sourceVC: NSViewController?, into tunnelsManager: TunnelsManager, _ callback: @escaping () -> Void) {
|
||||
if tunnelsManager.numberOfTunnels() > 0 {
|
||||
callback()
|
||||
return
|
||||
}
|
||||
let alert = NSAlert()
|
||||
|
||||
alert.messageText = tr("macPrivacyNoticeMessage")
|
||||
alert.informativeText = tr("macPrivacyNoticeInfo")
|
||||
alert.alertStyle = NSAlert.Style.warning
|
||||
if let window = sourceVC?.view.window {
|
||||
alert.beginSheetModal(for: window) { _ in callback() }
|
||||
} else {
|
||||
alert.runModal()
|
||||
callback()
|
||||
}
|
||||
}
|
||||
}
|
@ -13,9 +13,7 @@ class ImportPanelPresenter {
|
||||
openPanel.beginSheetModal(for: window) { [weak tunnelsManager] response in
|
||||
guard let tunnelsManager = tunnelsManager else { return }
|
||||
guard response == .OK else { return }
|
||||
AppStorePrivacyNotice.show(from: sourceVC, into: tunnelsManager) {
|
||||
TunnelImporter.importFromFile(urls: openPanel.urls, into: tunnelsManager, sourceVC: sourceVC, errorPresenterType: ErrorPresenter.self)
|
||||
}
|
||||
TunnelImporter.importFromFile(urls: openPanel.urls, into: tunnelsManager, sourceVC: sourceVC, errorPresenterType: ErrorPresenter.self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
34
WireGuard/WireGuard/UI/macOS/LoginItemHelper/Info.plist
Normal file
34
WireGuard/WireGuard/UI/macOS/LoginItemHelper/Info.plist
Normal file
@ -0,0 +1,34 @@
|
||||
<?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>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></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>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2018-2019 WireGuard LLC. All Rights Reserved.</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
<key>LSBackgroundOnly</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
@ -0,0 +1,8 @@
|
||||
<?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.security.app-sandbox</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
16
WireGuard/WireGuard/UI/macOS/LoginItemHelper/main.m
Normal file
16
WireGuard/WireGuard/UI/macOS/LoginItemHelper/main.m
Normal file
@ -0,0 +1,16 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved.
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
NSURL *bundleURL = [NSBundle.mainBundle bundleURL];
|
||||
|
||||
// From <path>/WireGuard.app/Contents/Library/LoginItems/WireGuardLoginItemHelper.app, derive <path>/WireGuard.app
|
||||
for (int i = 0; i < 4; ++i)
|
||||
bundleURL = [bundleURL URLByDeletingLastPathComponent];
|
||||
|
||||
[NSWorkspace.sharedWorkspace launchApplication:[bundleURL path]];
|
||||
return 0;
|
||||
}
|
@ -13,6 +13,7 @@ class StatusMenu: NSMenu {
|
||||
|
||||
var statusMenuItem: NSMenuItem?
|
||||
var networksMenuItem: NSMenuItem?
|
||||
var deactivateMenuItem: NSMenuItem?
|
||||
var firstTunnelMenuItemIndex = 0
|
||||
var numberOfTunnelMenuItems = 0
|
||||
|
||||
@ -53,16 +54,22 @@ class StatusMenu: NSMenu {
|
||||
networksMenuItem.isEnabled = false
|
||||
networksMenuItem.isHidden = true
|
||||
addItem(networksMenuItem)
|
||||
let deactivateMenuItem = NSMenuItem(title: tr("macToggleStatusButtonDeactivate"), action: #selector(deactivateClicked), keyEquivalent: "")
|
||||
deactivateMenuItem.target = self
|
||||
deactivateMenuItem.isHidden = true
|
||||
addItem(deactivateMenuItem)
|
||||
self.statusMenuItem = statusMenuItem
|
||||
self.networksMenuItem = networksMenuItem
|
||||
self.deactivateMenuItem = deactivateMenuItem
|
||||
}
|
||||
|
||||
func updateStatusMenuItems(with tunnel: TunnelContainer?) {
|
||||
guard let statusMenuItem = statusMenuItem, let networksMenuItem = networksMenuItem else { return }
|
||||
guard let statusMenuItem = statusMenuItem, let networksMenuItem = networksMenuItem, let deactivateMenuItem = deactivateMenuItem else { return }
|
||||
guard let tunnel = tunnel else {
|
||||
statusMenuItem.title = tr(format: "macStatus (%@)", tr("tunnelStatusInactive"))
|
||||
networksMenuItem.title = ""
|
||||
networksMenuItem.isHidden = true
|
||||
deactivateMenuItem.isHidden = true
|
||||
return
|
||||
}
|
||||
var statusText: String
|
||||
@ -98,6 +105,7 @@ class StatusMenu: NSMenu {
|
||||
}
|
||||
networksMenuItem.isHidden = false
|
||||
}
|
||||
deactivateMenuItem.isHidden = tunnel.status != .active
|
||||
}
|
||||
|
||||
func addTunnelMenuItems() -> Bool {
|
||||
@ -127,6 +135,12 @@ class StatusMenu: NSMenu {
|
||||
addItem(quitItem)
|
||||
}
|
||||
|
||||
@objc func deactivateClicked() {
|
||||
if let currentTunnel = currentTunnel {
|
||||
tunnelsManager.startDeactivation(of: currentTunnel)
|
||||
}
|
||||
}
|
||||
|
||||
@objc func tunnelClicked(sender: AnyObject) {
|
||||
guard let tunnelMenuItem = sender as? TunnelMenuItem else { return }
|
||||
if tunnelMenuItem.state == .off {
|
||||
@ -170,6 +184,7 @@ extension StatusMenu {
|
||||
func insertTunnelMenuItem(for tunnel: TunnelContainer, at tunnelIndex: Int) {
|
||||
let menuItem = TunnelMenuItem(tunnel: tunnel, action: #selector(tunnelClicked(sender:)))
|
||||
menuItem.target = self
|
||||
menuItem.isHidden = !tunnel.isTunnelConfigurationAvailableInKeychain
|
||||
insertItem(menuItem, at: firstTunnelMenuItemIndex + tunnelIndex)
|
||||
if numberOfTunnelMenuItems == 0 {
|
||||
insertItem(NSMenuItem.separator(), at: firstTunnelMenuItemIndex + tunnelIndex + 1)
|
||||
|
@ -19,6 +19,7 @@ class ConfTextStorage: NSTextStorage {
|
||||
private(set) var hasOnePeer: Bool = false
|
||||
private(set) var lastOnePeerAllowedIPs = [String]()
|
||||
private(set) var lastOnePeerDNSServers = [String]()
|
||||
private(set) var lastOnePeerHasPublicKey = false
|
||||
|
||||
override init() {
|
||||
backingStore = NSMutableAttributedString(string: "")
|
||||
@ -88,6 +89,7 @@ class ConfTextStorage: NSTextStorage {
|
||||
hasOnePeer = false
|
||||
lastOnePeerAllowedIPs = []
|
||||
lastOnePeerDNSServers = []
|
||||
lastOnePeerHasPublicKey = false
|
||||
}
|
||||
|
||||
func evaluateExcludePrivateIPs(highlightSpans: UnsafePointer<highlight_span>) {
|
||||
@ -125,6 +127,8 @@ class ConfTextStorage: NSTextStorage {
|
||||
backingStore.attributedSubstring(from: NSRange(location: nextnext.pointee.start, length: nextnext.pointee.len)).string
|
||||
}
|
||||
lastOnePeerAllowedIPs.append(substring)
|
||||
} else if span.type == HighlightPublicKey {
|
||||
lastOnePeerHasPublicKey = true
|
||||
}
|
||||
spans = spans.successor()
|
||||
}
|
||||
@ -143,9 +147,10 @@ class ConfTextStorage: NSTextStorage {
|
||||
.font: defaultFont
|
||||
]
|
||||
backingStore.setAttributes(defaultAttributes, range: fullTextRange)
|
||||
var spans = highlight_config(backingStore.string.cString(using: String.Encoding.utf8))!
|
||||
var spans = highlight_config(backingStore.string)!
|
||||
evaluateExcludePrivateIPs(highlightSpans: spans)
|
||||
|
||||
let spansStart = spans
|
||||
while spans.pointee.type != HighlightEnd {
|
||||
let span = spans.pointee
|
||||
|
||||
@ -165,6 +170,7 @@ class ConfTextStorage: NSTextStorage {
|
||||
spans = spans.successor()
|
||||
}
|
||||
backingStore.endEditing()
|
||||
free(spansStart)
|
||||
|
||||
beginEditing()
|
||||
edited(.editedAttributes, range: fullTextRange, changeInLength: 0)
|
||||
|
@ -14,6 +14,7 @@ class ConfTextView: NSTextView {
|
||||
override var string: String {
|
||||
didSet {
|
||||
confTextStorage.highlightSyntax()
|
||||
updateConfigData()
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,6 +54,21 @@ class ConfTextView: NSTextView {
|
||||
}
|
||||
}
|
||||
|
||||
private func updateConfigData() {
|
||||
if hasError != confTextStorage.hasError {
|
||||
hasError = confTextStorage.hasError
|
||||
}
|
||||
if privateKeyString != confTextStorage.privateKeyString {
|
||||
privateKeyString = confTextStorage.privateKeyString
|
||||
}
|
||||
let hasSyntaxError = confTextStorage.hasError
|
||||
let hasSemanticError = confTextStorage.privateKeyString == nil || !confTextStorage.lastOnePeerHasPublicKey
|
||||
let updatedSinglePeerAllowedIPs = confTextStorage.hasOnePeer && !hasSyntaxError && !hasSemanticError ? confTextStorage.lastOnePeerAllowedIPs : nil
|
||||
if singlePeerAllowedIPs != updatedSinglePeerAllowedIPs {
|
||||
singlePeerAllowedIPs = updatedSinglePeerAllowedIPs
|
||||
}
|
||||
}
|
||||
|
||||
func setConfText(_ text: String) {
|
||||
let fullTextRange = NSRange(location: 0, length: (string as NSString).length)
|
||||
if shouldChangeText(in: fullTextRange, replacementString: text) {
|
||||
@ -66,16 +82,7 @@ extension ConfTextView: NSTextViewDelegate {
|
||||
|
||||
func textDidChange(_ notification: Notification) {
|
||||
confTextStorage.highlightSyntax()
|
||||
if hasError != confTextStorage.hasError {
|
||||
hasError = confTextStorage.hasError
|
||||
}
|
||||
if privateKeyString != confTextStorage.privateKeyString {
|
||||
privateKeyString = confTextStorage.privateKeyString
|
||||
}
|
||||
let updatedSinglePeerAllowedIPs = confTextStorage.hasOnePeer && !confTextStorage.hasError ? confTextStorage.lastOnePeerAllowedIPs : nil
|
||||
if singlePeerAllowedIPs != updatedSinglePeerAllowedIPs {
|
||||
singlePeerAllowedIPs = updatedSinglePeerAllowedIPs
|
||||
}
|
||||
updateConfigData()
|
||||
needsDisplay = true
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,36 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved.
|
||||
|
||||
import Cocoa
|
||||
|
||||
class DeleteTunnelsConfirmationAlert: NSAlert {
|
||||
var alertDeleteButton: NSButton?
|
||||
var alertCancelButton: NSButton?
|
||||
|
||||
var onDeleteClicked: ((_ completionHandler: @escaping () -> Void) -> Void)?
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
let alertDeleteButton = addButton(withTitle: tr("macDeleteTunnelConfirmationAlertButtonTitleDelete"))
|
||||
alertDeleteButton.target = self
|
||||
alertDeleteButton.action = #selector(removeTunnelAlertDeleteClicked)
|
||||
self.alertDeleteButton = alertDeleteButton
|
||||
self.alertCancelButton = addButton(withTitle: tr("macDeleteTunnelConfirmationAlertButtonTitleCancel"))
|
||||
}
|
||||
|
||||
@objc func removeTunnelAlertDeleteClicked() {
|
||||
alertDeleteButton?.title = tr("macDeleteTunnelConfirmationAlertButtonTitleDeleting")
|
||||
alertDeleteButton?.isEnabled = false
|
||||
alertCancelButton?.isEnabled = false
|
||||
if let onDeleteClicked = onDeleteClicked {
|
||||
onDeleteClicked { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.window.sheetParent?.endSheet(self.window)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func beginSheetModal(for sheetWindow: NSWindow) {
|
||||
beginSheetModal(for: sheetWindow) { _ in }
|
||||
}
|
||||
}
|
52
WireGuard/WireGuard/UI/macOS/View/LogViewCell.swift
Normal file
52
WireGuard/WireGuard/UI/macOS/View/LogViewCell.swift
Normal file
@ -0,0 +1,52 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved.
|
||||
|
||||
import Cocoa
|
||||
|
||||
class LogViewCell: NSTextField {
|
||||
init() {
|
||||
super.init(frame: .zero)
|
||||
isSelectable = false
|
||||
isEditable = false
|
||||
isBordered = false
|
||||
backgroundColor = .clear
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override func prepareForReuse() {
|
||||
stringValue = ""
|
||||
preferredMaxLayoutWidth = 0
|
||||
}
|
||||
}
|
||||
|
||||
class LogViewTimestampCell: LogViewCell {
|
||||
override init() {
|
||||
super.init()
|
||||
maximumNumberOfLines = 1
|
||||
lineBreakMode = .byClipping
|
||||
preferredMaxLayoutWidth = 0
|
||||
setContentCompressionResistancePriority(.defaultHigh, for: .vertical)
|
||||
setContentHuggingPriority(.defaultLow, for: .vertical)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
}
|
||||
|
||||
class LogViewMessageCell: LogViewCell {
|
||||
override init() {
|
||||
super.init()
|
||||
maximumNumberOfLines = 0
|
||||
lineBreakMode = .byWordWrapping
|
||||
setContentCompressionResistancePriority(.required, for: .vertical)
|
||||
setContentHuggingPriority(.required, for: .vertical)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
}
|
@ -0,0 +1,263 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved.
|
||||
|
||||
import Cocoa
|
||||
|
||||
class LogViewController: NSViewController {
|
||||
|
||||
enum LogColumn: String {
|
||||
case time = "Time"
|
||||
case logMessage = "LogMessage"
|
||||
|
||||
func createColumn() -> NSTableColumn {
|
||||
return NSTableColumn(identifier: NSUserInterfaceItemIdentifier(rawValue))
|
||||
}
|
||||
|
||||
func isRepresenting(tableColumn: NSTableColumn?) -> Bool {
|
||||
return tableColumn?.identifier.rawValue == rawValue
|
||||
}
|
||||
}
|
||||
|
||||
let scrollView: NSScrollView = {
|
||||
let scrollView = NSScrollView()
|
||||
scrollView.hasVerticalScroller = true
|
||||
scrollView.autohidesScrollers = false
|
||||
scrollView.borderType = .bezelBorder
|
||||
return scrollView
|
||||
}()
|
||||
|
||||
let tableView: NSTableView = {
|
||||
let tableView = NSTableView()
|
||||
let timeColumn = LogColumn.time.createColumn()
|
||||
timeColumn.title = tr("macLogColumnTitleTime")
|
||||
timeColumn.width = 160
|
||||
timeColumn.resizingMask = []
|
||||
tableView.addTableColumn(timeColumn)
|
||||
let messageColumn = LogColumn.logMessage.createColumn()
|
||||
messageColumn.title = tr("macLogColumnTitleLogMessage")
|
||||
messageColumn.minWidth = 360
|
||||
messageColumn.resizingMask = .autoresizingMask
|
||||
tableView.addTableColumn(messageColumn)
|
||||
tableView.rowSizeStyle = .custom
|
||||
tableView.rowHeight = 16
|
||||
tableView.usesAlternatingRowBackgroundColors = true
|
||||
tableView.usesAutomaticRowHeights = true
|
||||
tableView.allowsColumnReordering = false
|
||||
tableView.allowsColumnResizing = true
|
||||
tableView.allowsMultipleSelection = true
|
||||
return tableView
|
||||
}()
|
||||
|
||||
let progressIndicator: NSProgressIndicator = {
|
||||
let progressIndicator = NSProgressIndicator()
|
||||
progressIndicator.controlSize = .small
|
||||
progressIndicator.isIndeterminate = true
|
||||
progressIndicator.style = .spinning
|
||||
progressIndicator.isDisplayedWhenStopped = false
|
||||
return progressIndicator
|
||||
}()
|
||||
|
||||
let closeButton: NSButton = {
|
||||
let button = NSButton()
|
||||
button.title = tr("macLogButtonTitleClose")
|
||||
button.setButtonType(.momentaryPushIn)
|
||||
button.bezelStyle = .rounded
|
||||
return button
|
||||
}()
|
||||
|
||||
let saveButton: NSButton = {
|
||||
let button = NSButton()
|
||||
button.title = tr("macLogButtonTitleSave")
|
||||
button.setButtonType(.momentaryPushIn)
|
||||
button.bezelStyle = .rounded
|
||||
return button
|
||||
}()
|
||||
|
||||
let logViewHelper: LogViewHelper?
|
||||
var logEntries = [LogViewHelper.LogEntry]()
|
||||
var isFetchingLogEntries = false
|
||||
var isInScrolledToEndMode = true
|
||||
|
||||
private var updateLogEntriesTimer: Timer?
|
||||
|
||||
init() {
|
||||
logViewHelper = LogViewHelper(logFilePath: FileManager.logFileURL?.path)
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override func loadView() {
|
||||
tableView.dataSource = self
|
||||
tableView.delegate = self
|
||||
|
||||
closeButton.target = self
|
||||
closeButton.action = #selector(closeClicked)
|
||||
|
||||
saveButton.target = self
|
||||
saveButton.action = #selector(saveClicked)
|
||||
saveButton.isEnabled = false
|
||||
|
||||
let clipView = NSClipView()
|
||||
clipView.documentView = tableView
|
||||
scrollView.contentView = clipView
|
||||
|
||||
_ = NotificationCenter.default.addObserver(forName: NSView.boundsDidChangeNotification, object: clipView, queue: OperationQueue.main) { [weak self] _ in
|
||||
guard let self = self else { return }
|
||||
let lastVisibleRowIndex = self.tableView.row(at: NSPoint(x: 0, y: self.scrollView.contentView.documentVisibleRect.maxY - 1))
|
||||
self.isInScrolledToEndMode = lastVisibleRowIndex < 0 || lastVisibleRowIndex == self.logEntries.count - 1
|
||||
}
|
||||
|
||||
_ = NotificationCenter.default.addObserver(forName: NSView.frameDidChangeNotification, object: tableView, queue: OperationQueue.main) { [weak self] _ in
|
||||
guard let self = self else { return }
|
||||
if self.isInScrolledToEndMode {
|
||||
DispatchQueue.main.async {
|
||||
self.tableView.scroll(NSPoint(x: 0, y: self.tableView.frame.maxY - clipView.documentVisibleRect.height))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let margin: CGFloat = 20
|
||||
let internalSpacing: CGFloat = 10
|
||||
|
||||
let buttonRowStackView = NSStackView()
|
||||
buttonRowStackView.addView(closeButton, in: .leading)
|
||||
buttonRowStackView.addView(saveButton, in: .trailing)
|
||||
buttonRowStackView.orientation = .horizontal
|
||||
buttonRowStackView.spacing = internalSpacing
|
||||
|
||||
let containerView = NSView()
|
||||
[scrollView, progressIndicator, buttonRowStackView].forEach { view in
|
||||
containerView.addSubview(view)
|
||||
view.translatesAutoresizingMaskIntoConstraints = false
|
||||
}
|
||||
NSLayoutConstraint.activate([
|
||||
scrollView.topAnchor.constraint(equalTo: containerView.topAnchor, constant: margin),
|
||||
scrollView.leftAnchor.constraint(equalTo: containerView.leftAnchor, constant: margin),
|
||||
containerView.rightAnchor.constraint(equalTo: scrollView.rightAnchor, constant: margin),
|
||||
buttonRowStackView.topAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: internalSpacing),
|
||||
buttonRowStackView.leftAnchor.constraint(equalTo: containerView.leftAnchor, constant: margin),
|
||||
containerView.rightAnchor.constraint(equalTo: buttonRowStackView.rightAnchor, constant: margin),
|
||||
containerView.bottomAnchor.constraint(equalTo: buttonRowStackView.bottomAnchor, constant: margin),
|
||||
progressIndicator.centerXAnchor.constraint(equalTo: scrollView.centerXAnchor),
|
||||
progressIndicator.centerYAnchor.constraint(equalTo: scrollView.centerYAnchor)
|
||||
])
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
containerView.widthAnchor.constraint(equalToConstant: 640),
|
||||
containerView.heightAnchor.constraint(greaterThanOrEqualToConstant: 240)
|
||||
])
|
||||
|
||||
containerView.frame = NSRect(x: 0, y: 0, width: 640, height: 480)
|
||||
|
||||
view = containerView
|
||||
|
||||
progressIndicator.startAnimation(self)
|
||||
startUpdatingLogEntries()
|
||||
}
|
||||
|
||||
func updateLogEntries() {
|
||||
guard !isFetchingLogEntries else { return }
|
||||
isFetchingLogEntries = true
|
||||
logViewHelper?.fetchLogEntriesSinceLastFetch { [weak self] fetchedLogEntries in
|
||||
guard let self = self else { return }
|
||||
defer {
|
||||
self.isFetchingLogEntries = false
|
||||
}
|
||||
if !self.progressIndicator.isHidden {
|
||||
self.progressIndicator.stopAnimation(self)
|
||||
self.saveButton.isEnabled = true
|
||||
}
|
||||
guard !fetchedLogEntries.isEmpty else { return }
|
||||
let oldCount = self.logEntries.count
|
||||
self.logEntries.append(contentsOf: fetchedLogEntries)
|
||||
self.tableView.insertRows(at: IndexSet(integersIn: oldCount ..< oldCount + fetchedLogEntries.count), withAnimation: .slideDown)
|
||||
}
|
||||
}
|
||||
|
||||
func startUpdatingLogEntries() {
|
||||
updateLogEntries()
|
||||
updateLogEntriesTimer?.invalidate()
|
||||
let timer = Timer(timeInterval: 1 /* second */, repeats: true) { [weak self] _ in
|
||||
self?.updateLogEntries()
|
||||
}
|
||||
updateLogEntriesTimer = timer
|
||||
RunLoop.main.add(timer, forMode: .common)
|
||||
}
|
||||
|
||||
func stopUpdatingLogEntries() {
|
||||
updateLogEntriesTimer?.invalidate()
|
||||
updateLogEntriesTimer = nil
|
||||
}
|
||||
|
||||
override func viewWillDisappear() {
|
||||
super.viewWillDisappear()
|
||||
stopUpdatingLogEntries()
|
||||
}
|
||||
|
||||
@objc func saveClicked() {
|
||||
let savePanel = NSSavePanel()
|
||||
savePanel.prompt = tr("macSheetButtonExportLog")
|
||||
savePanel.nameFieldLabel = tr("macNameFieldExportLog")
|
||||
|
||||
let dateFormatter = ISO8601DateFormatter()
|
||||
dateFormatter.formatOptions = [.withFullDate, .withTime, .withTimeZone] // Avoid ':' in the filename
|
||||
let timeStampString = dateFormatter.string(from: Date())
|
||||
savePanel.nameFieldStringValue = "wireguard-log-\(timeStampString).txt"
|
||||
|
||||
savePanel.beginSheetModal(for: self.view.window!) { [weak self] response in
|
||||
guard response == .OK else { return }
|
||||
guard let destinationURL = savePanel.url else { return }
|
||||
|
||||
DispatchQueue.global(qos: .userInitiated).async { [weak self] in
|
||||
let isWritten = Logger.global?.writeLog(to: destinationURL.path) ?? false
|
||||
guard isWritten else {
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
ErrorPresenter.showErrorAlert(title: tr("alertUnableToWriteLogTitle"), message: tr("alertUnableToWriteLogMessage"), from: self)
|
||||
}
|
||||
return
|
||||
}
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
self?.dismiss(self)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@objc func closeClicked() {
|
||||
dismiss(self)
|
||||
}
|
||||
|
||||
@objc func copy(_ sender: Any?) {
|
||||
let text = tableView.selectedRowIndexes.sorted().reduce("") { $0 + self.logEntries[$1].text() + "\n" }
|
||||
let pasteboard = NSPasteboard.general
|
||||
pasteboard.clearContents()
|
||||
pasteboard.writeObjects([text as NSString])
|
||||
}
|
||||
}
|
||||
|
||||
extension LogViewController: NSTableViewDataSource {
|
||||
func numberOfRows(in tableView: NSTableView) -> Int {
|
||||
return logEntries.count
|
||||
}
|
||||
}
|
||||
|
||||
extension LogViewController: NSTableViewDelegate {
|
||||
func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
|
||||
if LogColumn.time.isRepresenting(tableColumn: tableColumn) {
|
||||
let cell: LogViewTimestampCell = tableView.dequeueReusableCell()
|
||||
cell.stringValue = logEntries[row].timestamp
|
||||
return cell
|
||||
} else if LogColumn.logMessage.isRepresenting(tableColumn: tableColumn) {
|
||||
let cell: LogViewMessageCell = tableView.dequeueReusableCell()
|
||||
cell.stringValue = logEntries[row].message
|
||||
cell.preferredMaxLayoutWidth = tableColumn?.width ?? 0
|
||||
return cell
|
||||
} else {
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
}
|
@ -81,16 +81,20 @@ extension ManageTunnelsRootViewController: TunnelsListTableViewControllerDelegat
|
||||
assert(!tunnelIndices.isEmpty)
|
||||
if tunnelIndices.count == 1 {
|
||||
let tunnel = tunnelsManager.tunnel(at: tunnelIndices.first!)
|
||||
let tunnelDetailVC = TunnelDetailTableViewController(tunnelsManager: tunnelsManager, tunnel: tunnel)
|
||||
setTunnelDetailContentVC(tunnelDetailVC)
|
||||
self.tunnelDetailVC = tunnelDetailVC
|
||||
} else if tunnelIndices.count > 1 {
|
||||
let multiSelectionVC: ButtonedDetailViewController
|
||||
if let buttonedDetailVC = tunnelDetailContentVC as? ButtonedDetailViewController {
|
||||
multiSelectionVC = buttonedDetailVC
|
||||
if tunnel.isTunnelConfigurationAvailableInKeychain {
|
||||
let tunnelDetailVC = TunnelDetailTableViewController(tunnelsManager: tunnelsManager, tunnel: tunnel)
|
||||
setTunnelDetailContentVC(tunnelDetailVC)
|
||||
self.tunnelDetailVC = tunnelDetailVC
|
||||
} else {
|
||||
multiSelectionVC = ButtonedDetailViewController()
|
||||
let unusableTunnelDetailVC = tunnelDetailContentVC as? UnusableTunnelDetailViewController ?? UnusableTunnelDetailViewController()
|
||||
unusableTunnelDetailVC.onButtonClicked = { [weak tunnelsListVC] in
|
||||
tunnelsListVC?.handleRemoveTunnelAction()
|
||||
}
|
||||
setTunnelDetailContentVC(unusableTunnelDetailVC)
|
||||
self.tunnelDetailVC = nil
|
||||
}
|
||||
} else if tunnelIndices.count > 1 {
|
||||
let multiSelectionVC = tunnelDetailContentVC as? ButtonedDetailViewController ?? ButtonedDetailViewController()
|
||||
multiSelectionVC.setButtonTitle(tr(format: "macButtonDeleteTunnels (%d)", tunnelIndices.count))
|
||||
multiSelectionVC.onButtonClicked = { [weak tunnelsListVC] in
|
||||
tunnelsListVC?.handleRemoveTunnelAction()
|
||||
|
@ -117,6 +117,8 @@ class TunnelEditViewController: NSViewController {
|
||||
let bootstrappingText = "[Interface]\nPrivateKey = \(privateKey.base64Key() ?? "")\n"
|
||||
publicKeyRow.value = publicKey.base64Key() ?? ""
|
||||
textView.string = bootstrappingText
|
||||
updateExcludePrivateIPsVisibility(singlePeerAllowedIPs: nil)
|
||||
dnsServersAddedToAllowedIPs = nil
|
||||
}
|
||||
privateKeyObservationToken = textView.observe(\.privateKeyString) { [weak publicKeyRow] textView, _ in
|
||||
if let privateKeyString = textView.privateKeyString,
|
||||
@ -243,17 +245,15 @@ class TunnelEditViewController: NSViewController {
|
||||
}
|
||||
} else {
|
||||
// We're creating a new tunnel
|
||||
AppStorePrivacyNotice.show(from: self, into: tunnelsManager) { [weak self] in
|
||||
self?.tunnelsManager.add(tunnelConfiguration: tunnelConfiguration, onDemandOption: onDemandOption) { [weak self] result in
|
||||
self?.setUserInteractionEnabled(true)
|
||||
if let error = result.error {
|
||||
ErrorPresenter.showErrorAlert(error: error, from: self)
|
||||
return
|
||||
}
|
||||
let tunnel: TunnelContainer = result.value!
|
||||
self?.dismiss(self)
|
||||
self?.delegate?.tunnelSaved(tunnel: tunnel)
|
||||
self.tunnelsManager.add(tunnelConfiguration: tunnelConfiguration, onDemandOption: onDemandOption) { [weak self] result in
|
||||
self?.setUserInteractionEnabled(true)
|
||||
if let error = result.error {
|
||||
ErrorPresenter.showErrorAlert(error: error, from: self)
|
||||
return
|
||||
}
|
||||
let tunnel: TunnelContainer = result.value!
|
||||
self?.dismiss(self)
|
||||
self?.delegate?.tunnelSaved(tunnel: tunnel)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ class TunnelsListTableViewController: NSViewController {
|
||||
|
||||
let tunnelsManager: TunnelsManager
|
||||
weak var delegate: TunnelsListTableViewControllerDelegate?
|
||||
var isRemovingTunnels = false
|
||||
|
||||
let tableView: NSTableView = {
|
||||
let tableView = NSTableView()
|
||||
@ -53,7 +54,7 @@ class TunnelsListTableViewController: NSViewController {
|
||||
|
||||
let menu = NSMenu()
|
||||
menu.addItem(imageItem)
|
||||
menu.addItem(withTitle: tr("macMenuExportLog"), action: #selector(handleExportLogAction), keyEquivalent: "")
|
||||
menu.addItem(withTitle: tr("macMenuViewLog"), action: #selector(handleViewLogAction), keyEquivalent: "")
|
||||
menu.addItem(withTitle: tr("macMenuExportTunnels"), action: #selector(handleExportTunnelsAction), keyEquivalent: "")
|
||||
menu.autoenablesItems = false
|
||||
|
||||
@ -162,60 +163,41 @@ class TunnelsListTableViewController: NSViewController {
|
||||
|
||||
@objc func handleRemoveTunnelAction() {
|
||||
guard let window = view.window else { return }
|
||||
let selectedTunnelIndices = tableView.selectedRowIndexes.sorted()
|
||||
let selectedTunnels = selectedTunnelIndices.compactMap { tunnelIndex in
|
||||
tunnelIndex >= 0 && tunnelIndex < tunnelsManager.numberOfTunnels() ? tunnelsManager.tunnel(at: tunnelIndex) : nil
|
||||
|
||||
let selectedTunnelIndices = tableView.selectedRowIndexes.sorted().filter { $0 >= 0 && $0 < tunnelsManager.numberOfTunnels() }
|
||||
guard !selectedTunnelIndices.isEmpty else { return }
|
||||
var nextSelection = selectedTunnelIndices.last! + 1
|
||||
if nextSelection >= tunnelsManager.numberOfTunnels() {
|
||||
nextSelection = max(selectedTunnelIndices.first! - 1, 0)
|
||||
}
|
||||
guard !selectedTunnels.isEmpty else { return }
|
||||
let alert = NSAlert()
|
||||
if selectedTunnels.count == 1 {
|
||||
alert.messageText = tr(format: "macDeleteTunnelConfirmationAlertMessage (%@)", selectedTunnels.first!.name)
|
||||
|
||||
let alert = DeleteTunnelsConfirmationAlert()
|
||||
if selectedTunnelIndices.count == 1 {
|
||||
let firstSelectedTunnel = tunnelsManager.tunnel(at: selectedTunnelIndices.first!)
|
||||
alert.messageText = tr(format: "macDeleteTunnelConfirmationAlertMessage (%@)", firstSelectedTunnel.name)
|
||||
} else {
|
||||
alert.messageText = tr(format: "macDeleteMultipleTunnelsConfirmationAlertMessage (%d)", selectedTunnels.count)
|
||||
alert.messageText = tr(format: "macDeleteMultipleTunnelsConfirmationAlertMessage (%d)", selectedTunnelIndices.count)
|
||||
}
|
||||
alert.informativeText = tr("macDeleteTunnelConfirmationAlertInfo")
|
||||
alert.addButton(withTitle: tr("macDeleteTunnelConfirmationAlertButtonTitleDelete"))
|
||||
alert.addButton(withTitle: tr("macDeleteTunnelConfirmationAlertButtonTitleCancel"))
|
||||
alert.beginSheetModal(for: window) { [weak self] response in
|
||||
guard response == .alertFirstButtonReturn else { return }
|
||||
self?.removeButton.isEnabled = false
|
||||
self?.tunnelsManager.removeMultiple(tunnels: selectedTunnels) { [weak self] error in
|
||||
alert.onDeleteClicked = { [weak self] completion in
|
||||
guard let self = self else { return }
|
||||
self.selectTunnel(at: nextSelection)
|
||||
let selectedTunnels = selectedTunnelIndices.map { self.tunnelsManager.tunnel(at: $0) }
|
||||
self.tunnelsManager.removeMultiple(tunnels: selectedTunnels) { [weak self] error in
|
||||
guard let self = self else { return }
|
||||
defer { self.removeButton.isEnabled = true }
|
||||
defer { completion() }
|
||||
if let error = error {
|
||||
ErrorPresenter.showErrorAlert(error: error, from: self)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
alert.beginSheetModal(for: window)
|
||||
}
|
||||
|
||||
@objc func handleExportLogAction() {
|
||||
guard let window = view.window else { return }
|
||||
let savePanel = NSSavePanel()
|
||||
savePanel.prompt = tr("macSheetButtonExportLog")
|
||||
savePanel.nameFieldLabel = tr("macNameFieldExportLog")
|
||||
|
||||
let dateFormatter = ISO8601DateFormatter()
|
||||
dateFormatter.formatOptions = [.withFullDate, .withTime, .withTimeZone] // Avoid ':' in the filename
|
||||
let timeStampString = dateFormatter.string(from: Date())
|
||||
savePanel.nameFieldStringValue = "wireguard-log-\(timeStampString).txt"
|
||||
|
||||
savePanel.beginSheetModal(for: window) { response in
|
||||
guard response == .OK else { return }
|
||||
guard let destinationURL = savePanel.url else { return }
|
||||
|
||||
DispatchQueue.global(qos: .userInitiated).async {
|
||||
let isWritten = Logger.global?.writeLog(to: destinationURL.path) ?? false
|
||||
guard isWritten else {
|
||||
DispatchQueue.main.async { [weak self] in
|
||||
ErrorPresenter.showErrorAlert(title: tr("alertUnableToWriteLogTitle"), message: tr("alertUnableToWriteLogMessage"), from: self)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@objc func handleViewLogAction() {
|
||||
let logVC = LogViewController()
|
||||
self.presentAsSheet(logVC)
|
||||
}
|
||||
|
||||
@objc func handleExportTunnelsAction() {
|
||||
@ -299,15 +281,10 @@ extension TunnelsListTableViewController {
|
||||
}
|
||||
|
||||
func tunnelRemoved(at index: Int) {
|
||||
let selectedTunnelIndex = tableView.selectedRow
|
||||
tableView.removeRows(at: IndexSet(integer: index), withAnimation: .slideLeft)
|
||||
if tunnelsManager.numberOfTunnels() == 0 {
|
||||
delegate?.tunnelsListEmpty()
|
||||
}
|
||||
let tunnelIndex = min(selectedTunnelIndex, self.tunnelsManager.numberOfTunnels() - 1)
|
||||
if tunnelIndex >= 0 {
|
||||
self.selectTunnel(at: tunnelIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,71 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved.
|
||||
|
||||
import Cocoa
|
||||
|
||||
class UnusableTunnelDetailViewController: NSViewController {
|
||||
|
||||
var onButtonClicked: (() -> Void)?
|
||||
|
||||
let messageLabel: NSTextField = {
|
||||
let text = tr("macUnusableTunnelMessage")
|
||||
let boldFont = NSFont.boldSystemFont(ofSize: NSFont.systemFontSize)
|
||||
let boldText = NSAttributedString(string: text, attributes: [.font: boldFont])
|
||||
let label = NSTextField(labelWithAttributedString: boldText)
|
||||
return label
|
||||
}()
|
||||
|
||||
let infoLabel: NSTextField = {
|
||||
let label = NSTextField(wrappingLabelWithString: tr("macUnusableTunnelInfo"))
|
||||
return label
|
||||
}()
|
||||
|
||||
let button: NSButton = {
|
||||
let button = NSButton()
|
||||
button.title = tr("macUnusableTunnelButtonTitleDeleteTunnel")
|
||||
button.setButtonType(.momentaryPushIn)
|
||||
button.bezelStyle = .rounded
|
||||
return button
|
||||
}()
|
||||
|
||||
init() {
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override func loadView() {
|
||||
|
||||
button.target = self
|
||||
button.action = #selector(buttonClicked)
|
||||
|
||||
let margin: CGFloat = 20
|
||||
let internalSpacing: CGFloat = 20
|
||||
let buttonSpacing: CGFloat = 30
|
||||
let stackView = NSStackView(views: [messageLabel, infoLabel, button])
|
||||
stackView.orientation = .vertical
|
||||
stackView.edgeInsets = NSEdgeInsets(top: margin, left: margin, bottom: margin, right: margin)
|
||||
stackView.spacing = internalSpacing
|
||||
stackView.setCustomSpacing(buttonSpacing, after: infoLabel)
|
||||
|
||||
let view = NSView()
|
||||
view.addSubview(stackView)
|
||||
stackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
NSLayoutConstraint.activate([
|
||||
stackView.widthAnchor.constraint(equalToConstant: 360),
|
||||
stackView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
|
||||
stackView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
|
||||
view.widthAnchor.constraint(greaterThanOrEqualToConstant: 420),
|
||||
view.heightAnchor.constraint(greaterThanOrEqualToConstant: 240)
|
||||
])
|
||||
|
||||
self.view = view
|
||||
}
|
||||
|
||||
@objc func buttonClicked() {
|
||||
onButtonClicked?()
|
||||
}
|
||||
}
|
@ -31,7 +31,7 @@ class ZipArchive {
|
||||
let fileName = input.fileName
|
||||
let contents = input.contents
|
||||
zipOpenNewFileInZip(zipFile, fileName.cString(using: .utf8), nil, nil, 0, nil, 0, nil, Z_DEFLATED, Z_DEFAULT_COMPRESSION)
|
||||
contents.withUnsafeBytes { (ptr: UnsafePointer<UInt8>) -> Void in
|
||||
contents.withUnsafeUInt8Bytes { ptr -> Void in
|
||||
zipWriteInFileInZip(zipFile, UnsafeRawPointer(ptr), UInt32(contents.count))
|
||||
}
|
||||
zipCloseFileInZip(zipFile)
|
||||
|
@ -117,6 +117,8 @@ extension Endpoint {
|
||||
hostname = "\(address)"
|
||||
case .ipv6(let address):
|
||||
hostname = "\(address)"
|
||||
@unknown default:
|
||||
fatalError()
|
||||
}
|
||||
|
||||
var resultPointer = UnsafeMutablePointer<addrinfo>(OpaquePointer(bitPattern: 0))
|
||||
|
@ -26,7 +26,7 @@ export CGO_ENABLED := 1
|
||||
build: $(DESTDIR)/libwg-go.a
|
||||
version-header: $(DESTDIR)/wireguard-go-version.h
|
||||
|
||||
GOBUILDVERSION_NEEDED := go version go1.12 darwin/amd64
|
||||
GOBUILDVERSION_NEEDED := go version go1.12.1 darwin/amd64
|
||||
GOBUILDVERSION_CURRENT := $(shell go version 2>/dev/null)
|
||||
export REAL_GOROOT := $(shell go env GOROOT 2>/dev/null)
|
||||
export GOROOT := $(BUILDDIR)/goroot
|
||||
@ -44,7 +44,10 @@ $(GOROOT)/.prepared:
|
||||
[ -n "$(REAL_GOROOT)" ]
|
||||
mkdir -p "$(GOROOT)"
|
||||
rsync -a --delete --exclude=pkg/obj/go-build "$(REAL_GOROOT)/" "$(GOROOT)/"
|
||||
patch -p1 -f -N -r- -d "$(GOROOT)" < goruntime-boottime-over-monotonic.diff
|
||||
cat goruntime-*.diff | patch -p1 -f -N -r- -d "$(GOROOT)"
|
||||
rm -rf "$(GOPATH)/pkg/mod"
|
||||
go get -d -tags ios; chmod -fR +w "$(GOPATH)/pkg/mod"
|
||||
for sys in "$(GOPATH)/pkg/mod/golang.org/x/sys@"*; do cat sys-unix-*.diff | patch -p1 -f -N -r- -d "$$sys"; done
|
||||
touch "$@"
|
||||
|
||||
$(shell test "$$(cat "$(BUILDDIR)/.gobuildversion" 2>/dev/null)" = "$(GOBUILDVERSION_CURRENT)" || rm -f "$(DESTDIR)/libwg-go.a")
|
||||
@ -63,7 +66,6 @@ endef
|
||||
$(foreach ARCH,$(ARCHS),$(eval $(call libwg-go-a,$(ARCH))))
|
||||
|
||||
$(DESTDIR)/wireguard-go-version.h: go.mod $(GOROOT)/.prepared
|
||||
go get -d -tags ios; chmod -fR +w "$(GOPATH)/pkg/mod"
|
||||
wggo="$(GOPATH)/pkg/mod/$$(sed -n 's/.*\(golang\.zx2c4\.com\/wireguard\) \(.*\)$$/\1@\2/p' go.mod)"; \
|
||||
sed -n 's/.*WireGuardGoVersion = "\(.*\)"/#define WIREGUARD_GO_VERSION "\1"/p' "$$wggo/device/version.go" > "$@"
|
||||
|
||||
|
@ -3,6 +3,6 @@ module golang.zx2c4.com/wireguard/ios
|
||||
go 1.12
|
||||
|
||||
require (
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313
|
||||
golang.zx2c4.com/wireguard v0.0.0-20190310024754-66fb5caf023e
|
||||
golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67
|
||||
golang.zx2c4.com/wireguard v0.0.0-20190409083948-18fa27047265
|
||||
)
|
||||
|
@ -1,11 +1,13 @@
|
||||
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
||||
golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25 h1:jsG6UpNLt9iAsb0S2AGW28DveNzzgmbXR+ENoPjUeIU=
|
||||
golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/net v0.0.0-20190301231341-16b79f2e4e95 h1:fY7Dsw114eJN4boqzVSbpVHO6rTdhq6/GnXeu+PKnzU=
|
||||
golang.org/x/net v0.0.0-20190301231341-16b79f2e4e95/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
github.com/Microsoft/go-winio v0.4.12/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576 h1:aUX/1G2gFSs4AsJJg2cL3HuoRhCSCz733FE5GUSuaT4=
|
||||
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53 h1:kcXqo9vE6fsZY5X5Rd7R1l7fTgnWaDCVmln65REefiE=
|
||||
golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190302025703-b6889370fb10/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313 h1:pczuHS43Cp2ktBEEmLwScxgjWsBSzdaQiKzUyf3DTTc=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20190310024754-66fb5caf023e h1:lyp5Vq7gvB3Ei9iCJNhEvzuQx99gteo+GoRZPFOCmRE=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20190310024754-66fb5caf023e/go.mod h1:Koyxt99ZAZcr8lJuisBNX9vnaqKVNGcITeWOI1Zkmsw=
|
||||
golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67 h1:1Fzlr8kkDLQwqMP8GxrhptBLqZG/EDpiATneiZHY998=
|
||||
golang.org/x/sys v0.0.0-20190405154228-4b34438f7a67/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20190409083948-18fa27047265 h1:ujM5BaP4MD/2MJZ1n7pmw6IIsyyS7SyPl0fDefnx/2o=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20190409083948-18fa27047265/go.mod h1:u0Cl3X+pyWdXaax3S583DQrnGDuTASO0QdlKFrs8r/8=
|
||||
|
279
wireguard-go-bridge/goruntime-syscall-remove-getdirentries.diff
Normal file
279
wireguard-go-bridge/goruntime-syscall-remove-getdirentries.diff
Normal file
@ -0,0 +1,279 @@
|
||||
From bc77ad792117829909eeeca3aa492d6f292d004d Mon Sep 17 00:00:00 2001
|
||||
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
|
||||
Date: Tue, 19 Mar 2019 13:55:44 -0600
|
||||
Subject: [PATCH] syscall: do not link against ___getdirentries64
|
||||
|
||||
---
|
||||
.../x/sys/unix/syscall_darwin_386.go | 5 ++++-
|
||||
.../x/sys/unix/syscall_darwin_amd64.go | 5 ++++-
|
||||
.../x/sys/unix/zsyscall_darwin_386.go | 22 -------------------
|
||||
.../x/sys/unix/zsyscall_darwin_386.s | 2 --
|
||||
.../x/sys/unix/zsyscall_darwin_amd64.go | 22 -------------------
|
||||
.../x/sys/unix/zsyscall_darwin_amd64.s | 2 --
|
||||
src/syscall/syscall_darwin_386.go | 5 ++++-
|
||||
src/syscall/syscall_darwin_amd64.go | 5 ++++-
|
||||
src/syscall/zsyscall_darwin_386.go | 20 -----------------
|
||||
src/syscall/zsyscall_darwin_386.s | 2 --
|
||||
src/syscall/zsyscall_darwin_amd64.go | 20 -----------------
|
||||
src/syscall/zsyscall_darwin_amd64.s | 2 --
|
||||
12 files changed, 16 insertions(+), 96 deletions(-)
|
||||
|
||||
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_386.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_386.go
|
||||
index 489726fa9b..900dd7c91f 100644
|
||||
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_386.go
|
||||
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_386.go
|
||||
@@ -56,8 +56,11 @@ const SYS___SYSCTL = SYS_SYSCTL
|
||||
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
|
||||
//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
|
||||
//sys Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_FSTATFS64
|
||||
-//sys Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) = SYS_GETDIRENTRIES64
|
||||
//sys getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT64
|
||||
//sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
|
||||
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
|
||||
//sys Statfs(path string, stat *Statfs_t) (err error) = SYS_STATFS64
|
||||
+
|
||||
+func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
|
||||
+ return 0, ENOSYS
|
||||
+}
|
||||
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go
|
||||
index 914b89bde5..95e245fff7 100644
|
||||
--- a/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go
|
||||
+++ b/src/cmd/vendor/golang.org/x/sys/unix/syscall_darwin_amd64.go
|
||||
@@ -56,8 +56,11 @@ const SYS___SYSCTL = SYS_SYSCTL
|
||||
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
|
||||
//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
|
||||
//sys Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_FSTATFS64
|
||||
-//sys Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) = SYS_GETDIRENTRIES64
|
||||
//sys getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT64
|
||||
//sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
|
||||
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
|
||||
//sys Statfs(path string, stat *Statfs_t) (err error) = SYS_STATFS64
|
||||
+
|
||||
+func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
|
||||
+ return 0, ENOSYS
|
||||
+}
|
||||
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go
|
||||
index 23346dc68f..db4f1eaf1c 100644
|
||||
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go
|
||||
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.go
|
||||
@@ -2408,28 +2408,6 @@ func libc_fstatfs64_trampoline()
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
-func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
|
||||
- var _p0 unsafe.Pointer
|
||||
- if len(buf) > 0 {
|
||||
- _p0 = unsafe.Pointer(&buf[0])
|
||||
- } else {
|
||||
- _p0 = unsafe.Pointer(&_zero)
|
||||
- }
|
||||
- r0, _, e1 := syscall_syscall6(funcPC(libc___getdirentries64_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
|
||||
- n = int(r0)
|
||||
- if e1 != 0 {
|
||||
- err = errnoErr(e1)
|
||||
- }
|
||||
- return
|
||||
-}
|
||||
-
|
||||
-func libc___getdirentries64_trampoline()
|
||||
-
|
||||
-//go:linkname libc___getdirentries64 libc___getdirentries64
|
||||
-//go:cgo_import_dynamic libc___getdirentries64 __getdirentries64 "/usr/lib/libSystem.B.dylib"
|
||||
-
|
||||
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
-
|
||||
func getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) {
|
||||
r0, _, e1 := syscall_syscall(funcPC(libc_getfsstat64_trampoline), uintptr(buf), uintptr(size), uintptr(flags))
|
||||
n = int(r0)
|
||||
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.s b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.s
|
||||
index 37b85b4f61..6165f70e33 100644
|
||||
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.s
|
||||
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_386.s
|
||||
@@ -272,8 +272,6 @@ TEXT ·libc_fstatat64_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fstatat64(SB)
|
||||
TEXT ·libc_fstatfs64_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fstatfs64(SB)
|
||||
-TEXT ·libc___getdirentries64_trampoline(SB),NOSPLIT,$0-0
|
||||
- JMP libc___getdirentries64(SB)
|
||||
TEXT ·libc_getfsstat64_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getfsstat64(SB)
|
||||
TEXT ·libc_lstat64_trampoline(SB),NOSPLIT,$0-0
|
||||
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go
|
||||
index b50178d679..dea5dee75e 100644
|
||||
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go
|
||||
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.go
|
||||
@@ -2408,28 +2408,6 @@ func libc_fstatfs64_trampoline()
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
-func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
|
||||
- var _p0 unsafe.Pointer
|
||||
- if len(buf) > 0 {
|
||||
- _p0 = unsafe.Pointer(&buf[0])
|
||||
- } else {
|
||||
- _p0 = unsafe.Pointer(&_zero)
|
||||
- }
|
||||
- r0, _, e1 := syscall_syscall6(funcPC(libc___getdirentries64_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
|
||||
- n = int(r0)
|
||||
- if e1 != 0 {
|
||||
- err = errnoErr(e1)
|
||||
- }
|
||||
- return
|
||||
-}
|
||||
-
|
||||
-func libc___getdirentries64_trampoline()
|
||||
-
|
||||
-//go:linkname libc___getdirentries64 libc___getdirentries64
|
||||
-//go:cgo_import_dynamic libc___getdirentries64 __getdirentries64 "/usr/lib/libSystem.B.dylib"
|
||||
-
|
||||
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
-
|
||||
func getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) {
|
||||
r0, _, e1 := syscall_syscall(funcPC(libc_getfsstat64_trampoline), uintptr(buf), uintptr(size), uintptr(flags))
|
||||
n = int(r0)
|
||||
diff --git a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s
|
||||
index da9b900a8c..f1e2d7e9a4 100644
|
||||
--- a/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s
|
||||
+++ b/src/cmd/vendor/golang.org/x/sys/unix/zsyscall_darwin_amd64.s
|
||||
@@ -272,8 +272,6 @@ TEXT ·libc_fstatat64_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fstatat64(SB)
|
||||
TEXT ·libc_fstatfs64_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fstatfs64(SB)
|
||||
-TEXT ·libc___getdirentries64_trampoline(SB),NOSPLIT,$0-0
|
||||
- JMP libc___getdirentries64(SB)
|
||||
TEXT ·libc_getfsstat64_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getfsstat64(SB)
|
||||
TEXT ·libc_lstat64_trampoline(SB),NOSPLIT,$0-0
|
||||
diff --git a/src/syscall/syscall_darwin_386.go b/src/syscall/syscall_darwin_386.go
|
||||
index 045ebc726b..826d76f569 100644
|
||||
--- a/src/syscall/syscall_darwin_386.go
|
||||
+++ b/src/syscall/syscall_darwin_386.go
|
||||
@@ -16,7 +16,6 @@ func setTimeval(sec, usec int64) Timeval {
|
||||
|
||||
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_fstat64
|
||||
//sys Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_fstatfs64
|
||||
-//sys Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) = SYS___getdirentries64
|
||||
//sysnb Gettimeofday(tp *Timeval) (err error)
|
||||
//sys Lstat(path string, stat *Stat_t) (err error) = SYS_lstat64
|
||||
//sys Stat(path string, stat *Stat_t) (err error) = SYS_stat64
|
||||
@@ -63,3 +62,7 @@ func libc_sendfile_trampoline()
|
||||
func syscall9(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)
|
||||
|
||||
func Syscall9(num, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno) // sic
|
||||
+
|
||||
+func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
|
||||
+ return 0, ENOSYS
|
||||
+}
|
||||
diff --git a/src/syscall/syscall_darwin_amd64.go b/src/syscall/syscall_darwin_amd64.go
|
||||
index 7b6493bf9f..3868790049 100644
|
||||
--- a/src/syscall/syscall_darwin_amd64.go
|
||||
+++ b/src/syscall/syscall_darwin_amd64.go
|
||||
@@ -16,7 +16,6 @@ func setTimeval(sec, usec int64) Timeval {
|
||||
|
||||
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_fstat64
|
||||
//sys Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_fstatfs64
|
||||
-//sys Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) = SYS___getdirentries64
|
||||
//sysnb Gettimeofday(tp *Timeval) (err error)
|
||||
//sys Lstat(path string, stat *Stat_t) (err error) = SYS_lstat64
|
||||
//sys Stat(path string, stat *Stat_t) (err error) = SYS_stat64
|
||||
@@ -63,3 +62,7 @@ func libc_sendfile_trampoline()
|
||||
func syscallX(fn, a1, a2, a3 uintptr) (r1, r2 uintptr, err Errno)
|
||||
|
||||
func Syscall9(trap, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2 uintptr, err Errno)
|
||||
+
|
||||
+func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
|
||||
+ return 0, ENOSYS
|
||||
+}
|
||||
diff --git a/src/syscall/zsyscall_darwin_386.go b/src/syscall/zsyscall_darwin_386.go
|
||||
index 758ff7b129..a666a1f65e 100644
|
||||
--- a/src/syscall/zsyscall_darwin_386.go
|
||||
+++ b/src/syscall/zsyscall_darwin_386.go
|
||||
@@ -1845,27 +1845,7 @@ func libc_fstatfs64_trampoline()
|
||||
|
||||
//go:linkname libc_fstatfs64 libc_fstatfs64
|
||||
//go:cgo_import_dynamic libc_fstatfs64 fstatfs64 "/usr/lib/libSystem.B.dylib"
|
||||
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
-
|
||||
-func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
|
||||
- var _p0 unsafe.Pointer
|
||||
- if len(buf) > 0 {
|
||||
- _p0 = unsafe.Pointer(&buf[0])
|
||||
- } else {
|
||||
- _p0 = unsafe.Pointer(&_zero)
|
||||
- }
|
||||
- r0, _, e1 := syscall6(funcPC(libc___getdirentries64_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
|
||||
- n = int(r0)
|
||||
- if e1 != 0 {
|
||||
- err = errnoErr(e1)
|
||||
- }
|
||||
- return
|
||||
-}
|
||||
-
|
||||
-func libc___getdirentries64_trampoline()
|
||||
|
||||
-//go:linkname libc___getdirentries64 libc___getdirentries64
|
||||
-//go:cgo_import_dynamic libc___getdirentries64 __getdirentries64 "/usr/lib/libSystem.B.dylib"
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func Gettimeofday(tp *Timeval) (err error) {
|
||||
diff --git a/src/syscall/zsyscall_darwin_386.s b/src/syscall/zsyscall_darwin_386.s
|
||||
index a688192501..a5af9b64b9 100644
|
||||
--- a/src/syscall/zsyscall_darwin_386.s
|
||||
+++ b/src/syscall/zsyscall_darwin_386.s
|
||||
@@ -235,8 +235,6 @@ TEXT ·libc_fstat64_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fstat64(SB)
|
||||
TEXT ·libc_fstatfs64_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fstatfs64(SB)
|
||||
-TEXT ·libc___getdirentries64_trampoline(SB),NOSPLIT,$0-0
|
||||
- JMP libc___getdirentries64(SB)
|
||||
TEXT ·libc_gettimeofday_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_gettimeofday(SB)
|
||||
TEXT ·libc_lstat64_trampoline(SB),NOSPLIT,$0-0
|
||||
diff --git a/src/syscall/zsyscall_darwin_amd64.go b/src/syscall/zsyscall_darwin_amd64.go
|
||||
index afc3d72d8d..bb87aef1f9 100644
|
||||
--- a/src/syscall/zsyscall_darwin_amd64.go
|
||||
+++ b/src/syscall/zsyscall_darwin_amd64.go
|
||||
@@ -1845,27 +1845,7 @@ func libc_fstatfs64_trampoline()
|
||||
|
||||
//go:linkname libc_fstatfs64 libc_fstatfs64
|
||||
//go:cgo_import_dynamic libc_fstatfs64 fstatfs64 "/usr/lib/libSystem.B.dylib"
|
||||
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
-
|
||||
-func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
|
||||
- var _p0 unsafe.Pointer
|
||||
- if len(buf) > 0 {
|
||||
- _p0 = unsafe.Pointer(&buf[0])
|
||||
- } else {
|
||||
- _p0 = unsafe.Pointer(&_zero)
|
||||
- }
|
||||
- r0, _, e1 := syscall6(funcPC(libc___getdirentries64_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
|
||||
- n = int(r0)
|
||||
- if e1 != 0 {
|
||||
- err = errnoErr(e1)
|
||||
- }
|
||||
- return
|
||||
-}
|
||||
-
|
||||
-func libc___getdirentries64_trampoline()
|
||||
|
||||
-//go:linkname libc___getdirentries64 libc___getdirentries64
|
||||
-//go:cgo_import_dynamic libc___getdirentries64 __getdirentries64 "/usr/lib/libSystem.B.dylib"
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
func Gettimeofday(tp *Timeval) (err error) {
|
||||
diff --git a/src/syscall/zsyscall_darwin_amd64.s b/src/syscall/zsyscall_darwin_amd64.s
|
||||
index 21ab38e3ee..409320dea5 100644
|
||||
--- a/src/syscall/zsyscall_darwin_amd64.s
|
||||
+++ b/src/syscall/zsyscall_darwin_amd64.s
|
||||
@@ -235,8 +235,6 @@ TEXT ·libc_fstat64_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fstat64(SB)
|
||||
TEXT ·libc_fstatfs64_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fstatfs64(SB)
|
||||
-TEXT ·libc___getdirentries64_trampoline(SB),NOSPLIT,$0-0
|
||||
- JMP libc___getdirentries64(SB)
|
||||
TEXT ·libc_gettimeofday_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_gettimeofday(SB)
|
||||
TEXT ·libc_lstat64_trampoline(SB),NOSPLIT,$0-0
|
||||
--
|
||||
2.21.0
|
||||
|
143
wireguard-go-bridge/sys-unix-remove-getdirentries.diff
Normal file
143
wireguard-go-bridge/sys-unix-remove-getdirentries.diff
Normal file
@ -0,0 +1,143 @@
|
||||
From 3efe4df9b66d4af86363e37768ea469abb8f7bdc Mon Sep 17 00:00:00 2001
|
||||
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
|
||||
Date: Tue, 19 Mar 2019 14:01:21 -0600
|
||||
Subject: [PATCH] unix: do not link against ___getdirentries64
|
||||
|
||||
---
|
||||
unix/syscall_darwin_386.go | 5 ++++-
|
||||
unix/syscall_darwin_amd64.go | 5 ++++-
|
||||
unix/zsyscall_darwin_386.go | 22 ----------------------
|
||||
unix/zsyscall_darwin_386.s | 2 --
|
||||
unix/zsyscall_darwin_amd64.go | 22 ----------------------
|
||||
unix/zsyscall_darwin_amd64.s | 2 --
|
||||
6 files changed, 8 insertions(+), 50 deletions(-)
|
||||
|
||||
diff --git a/unix/syscall_darwin_386.go b/unix/syscall_darwin_386.go
|
||||
index 489726f..900dd7c 100644
|
||||
--- a/unix/syscall_darwin_386.go
|
||||
+++ b/unix/syscall_darwin_386.go
|
||||
@@ -56,8 +56,11 @@ const SYS___SYSCTL = SYS_SYSCTL
|
||||
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
|
||||
//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
|
||||
//sys Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_FSTATFS64
|
||||
-//sys Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) = SYS_GETDIRENTRIES64
|
||||
//sys getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT64
|
||||
//sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
|
||||
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
|
||||
//sys Statfs(path string, stat *Statfs_t) (err error) = SYS_STATFS64
|
||||
+
|
||||
+func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
|
||||
+ return 0, ENOSYS
|
||||
+}
|
||||
diff --git a/unix/syscall_darwin_amd64.go b/unix/syscall_darwin_amd64.go
|
||||
index 914b89b..95e245f 100644
|
||||
--- a/unix/syscall_darwin_amd64.go
|
||||
+++ b/unix/syscall_darwin_amd64.go
|
||||
@@ -56,8 +56,11 @@ const SYS___SYSCTL = SYS_SYSCTL
|
||||
//sys Fstat(fd int, stat *Stat_t) (err error) = SYS_FSTAT64
|
||||
//sys Fstatat(fd int, path string, stat *Stat_t, flags int) (err error) = SYS_FSTATAT64
|
||||
//sys Fstatfs(fd int, stat *Statfs_t) (err error) = SYS_FSTATFS64
|
||||
-//sys Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) = SYS_GETDIRENTRIES64
|
||||
//sys getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) = SYS_GETFSSTAT64
|
||||
//sys Lstat(path string, stat *Stat_t) (err error) = SYS_LSTAT64
|
||||
//sys Stat(path string, stat *Stat_t) (err error) = SYS_STAT64
|
||||
//sys Statfs(path string, stat *Statfs_t) (err error) = SYS_STATFS64
|
||||
+
|
||||
+func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
|
||||
+ return 0, ENOSYS
|
||||
+}
|
||||
diff --git a/unix/zsyscall_darwin_386.go b/unix/zsyscall_darwin_386.go
|
||||
index 23346dc..db4f1ea 100644
|
||||
--- a/unix/zsyscall_darwin_386.go
|
||||
+++ b/unix/zsyscall_darwin_386.go
|
||||
@@ -2408,28 +2408,6 @@ func libc_fstatfs64_trampoline()
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
-func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
|
||||
- var _p0 unsafe.Pointer
|
||||
- if len(buf) > 0 {
|
||||
- _p0 = unsafe.Pointer(&buf[0])
|
||||
- } else {
|
||||
- _p0 = unsafe.Pointer(&_zero)
|
||||
- }
|
||||
- r0, _, e1 := syscall_syscall6(funcPC(libc___getdirentries64_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
|
||||
- n = int(r0)
|
||||
- if e1 != 0 {
|
||||
- err = errnoErr(e1)
|
||||
- }
|
||||
- return
|
||||
-}
|
||||
-
|
||||
-func libc___getdirentries64_trampoline()
|
||||
-
|
||||
-//go:linkname libc___getdirentries64 libc___getdirentries64
|
||||
-//go:cgo_import_dynamic libc___getdirentries64 __getdirentries64 "/usr/lib/libSystem.B.dylib"
|
||||
-
|
||||
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
-
|
||||
func getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) {
|
||||
r0, _, e1 := syscall_syscall(funcPC(libc_getfsstat64_trampoline), uintptr(buf), uintptr(size), uintptr(flags))
|
||||
n = int(r0)
|
||||
diff --git a/unix/zsyscall_darwin_386.s b/unix/zsyscall_darwin_386.s
|
||||
index 37b85b4..6165f70 100644
|
||||
--- a/unix/zsyscall_darwin_386.s
|
||||
+++ b/unix/zsyscall_darwin_386.s
|
||||
@@ -272,8 +272,6 @@ TEXT ·libc_fstatat64_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fstatat64(SB)
|
||||
TEXT ·libc_fstatfs64_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fstatfs64(SB)
|
||||
-TEXT ·libc___getdirentries64_trampoline(SB),NOSPLIT,$0-0
|
||||
- JMP libc___getdirentries64(SB)
|
||||
TEXT ·libc_getfsstat64_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getfsstat64(SB)
|
||||
TEXT ·libc_lstat64_trampoline(SB),NOSPLIT,$0-0
|
||||
diff --git a/unix/zsyscall_darwin_amd64.go b/unix/zsyscall_darwin_amd64.go
|
||||
index c142e33..126f993 100644
|
||||
--- a/unix/zsyscall_darwin_amd64.go
|
||||
+++ b/unix/zsyscall_darwin_amd64.go
|
||||
@@ -2423,28 +2423,6 @@ func libc_fstatfs64_trampoline()
|
||||
|
||||
// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
|
||||
-func Getdirentries(fd int, buf []byte, basep *uintptr) (n int, err error) {
|
||||
- var _p0 unsafe.Pointer
|
||||
- if len(buf) > 0 {
|
||||
- _p0 = unsafe.Pointer(&buf[0])
|
||||
- } else {
|
||||
- _p0 = unsafe.Pointer(&_zero)
|
||||
- }
|
||||
- r0, _, e1 := syscall_syscall6(funcPC(libc___getdirentries64_trampoline), uintptr(fd), uintptr(_p0), uintptr(len(buf)), uintptr(unsafe.Pointer(basep)), 0, 0)
|
||||
- n = int(r0)
|
||||
- if e1 != 0 {
|
||||
- err = errnoErr(e1)
|
||||
- }
|
||||
- return
|
||||
-}
|
||||
-
|
||||
-func libc___getdirentries64_trampoline()
|
||||
-
|
||||
-//go:linkname libc___getdirentries64 libc___getdirentries64
|
||||
-//go:cgo_import_dynamic libc___getdirentries64 __getdirentries64 "/usr/lib/libSystem.B.dylib"
|
||||
-
|
||||
-// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT
|
||||
-
|
||||
func getfsstat(buf unsafe.Pointer, size uintptr, flags int) (n int, err error) {
|
||||
r0, _, e1 := syscall_syscall(funcPC(libc_getfsstat64_trampoline), uintptr(buf), uintptr(size), uintptr(flags))
|
||||
n = int(r0)
|
||||
diff --git a/unix/zsyscall_darwin_amd64.s b/unix/zsyscall_darwin_amd64.s
|
||||
index 1a39151..a19c4f5 100644
|
||||
--- a/unix/zsyscall_darwin_amd64.s
|
||||
+++ b/unix/zsyscall_darwin_amd64.s
|
||||
@@ -274,8 +274,6 @@ TEXT ·libc_fstatat64_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fstatat64(SB)
|
||||
TEXT ·libc_fstatfs64_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_fstatfs64(SB)
|
||||
-TEXT ·libc___getdirentries64_trampoline(SB),NOSPLIT,$0-0
|
||||
- JMP libc___getdirentries64(SB)
|
||||
TEXT ·libc_getfsstat64_trampoline(SB),NOSPLIT,$0-0
|
||||
JMP libc_getfsstat64(SB)
|
||||
TEXT ·libc_lstat64_trampoline(SB),NOSPLIT,$0-0
|
||||
--
|
||||
2.21.0
|
||||
|
Reference in New Issue
Block a user