diff --git a/COPYING b/COPYING index b6b2e1edf..a590b557c 100644 --- a/COPYING +++ b/COPYING @@ -1,4 +1,4 @@ -Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/Package.swift b/Package.swift index ddd48223a..8e3864fd0 100644 --- a/Package.swift +++ b/Package.swift @@ -30,7 +30,7 @@ let package = Package( "goruntime-boottime-over-monotonic.diff", "go.mod", "go.sum", - "api-ios.go", + "api-apple.go", "Makefile" ], publicHeadersPath: ".", diff --git a/README.md b/README.md index 953ea63fb..2f09231ce 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ $ open WireGuard.xcodeproj the "External Build Tool Configuration": ``` - $BUILD_DIR/../../SourcePackages/checkouts/wireguard-apple/Sources/WireGuardKitGo + ${BUILD_DIR%Build/*}SourcePackages/checkouts/wireguard-apple/Sources/WireGuardKitGo ``` - Switch to "Build Settings" and find `SDKROOT`. diff --git a/Sources/Shared/FileManager+Extension.swift b/Sources/Shared/FileManager+Extension.swift index 9aa1e826d..d09f2b552 100644 --- a/Sources/Shared/FileManager+Extension.swift +++ b/Sources/Shared/FileManager+Extension.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Foundation import os.log diff --git a/Sources/Shared/Keychain.swift b/Sources/Shared/Keychain.swift index c6e7526b3..5400c67e1 100644 --- a/Sources/Shared/Keychain.swift +++ b/Sources/Shared/Keychain.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Foundation import Security diff --git a/Sources/Shared/Logging/Logger.swift b/Sources/Shared/Logging/Logger.swift index f345e3361..089fd109d 100644 --- a/Sources/Shared/Logging/Logger.swift +++ b/Sources/Shared/Logging/Logger.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Foundation import os.log diff --git a/Sources/Shared/Logging/ringlogger.c b/Sources/Shared/Logging/ringlogger.c index 7f53bca1b..0c16cd625 100644 --- a/Sources/Shared/Logging/ringlogger.c +++ b/Sources/Shared/Logging/ringlogger.c @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: MIT * - * Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. + * Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. */ #include diff --git a/Sources/Shared/Logging/ringlogger.h b/Sources/Shared/Logging/ringlogger.h index 0a39e44a5..4211e9f12 100644 --- a/Sources/Shared/Logging/ringlogger.h +++ b/Sources/Shared/Logging/ringlogger.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: MIT * - * Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. + * Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. */ #ifndef RINGLOGGER_H diff --git a/Sources/Shared/Model/NETunnelProviderProtocol+Extension.swift b/Sources/Shared/Model/NETunnelProviderProtocol+Extension.swift index 4dd337af8..12b9d6bca 100644 --- a/Sources/Shared/Model/NETunnelProviderProtocol+Extension.swift +++ b/Sources/Shared/Model/NETunnelProviderProtocol+Extension.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import NetworkExtension diff --git a/Sources/Shared/Model/String+ArrayConversion.swift b/Sources/Shared/Model/String+ArrayConversion.swift index 64646901f..adb959f13 100644 --- a/Sources/Shared/Model/String+ArrayConversion.swift +++ b/Sources/Shared/Model/String+ArrayConversion.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Foundation diff --git a/Sources/Shared/Model/TunnelConfiguration+WgQuickConfig.swift b/Sources/Shared/Model/TunnelConfiguration+WgQuickConfig.swift index 0cc180331..5d5216cb5 100644 --- a/Sources/Shared/Model/TunnelConfiguration+WgQuickConfig.swift +++ b/Sources/Shared/Model/TunnelConfiguration+WgQuickConfig.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Foundation diff --git a/Sources/Shared/NotificationToken.swift b/Sources/Shared/NotificationToken.swift index df5bc25fd..9eb94ef54 100644 --- a/Sources/Shared/NotificationToken.swift +++ b/Sources/Shared/NotificationToken.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Foundation diff --git a/Sources/WireGuardApp/Base.lproj/InfoPlist.strings b/Sources/WireGuardApp/Base.lproj/InfoPlist.strings index aca130f14..2a7c6d7a8 100644 --- a/Sources/WireGuardApp/Base.lproj/InfoPlist.strings +++ b/Sources/WireGuardApp/Base.lproj/InfoPlist.strings @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. // iOS permission prompts diff --git a/Sources/WireGuardApp/Base.lproj/Localizable.strings b/Sources/WireGuardApp/Base.lproj/Localizable.strings index 4ef954039..4533739f8 100644 --- a/Sources/WireGuardApp/Base.lproj/Localizable.strings +++ b/Sources/WireGuardApp/Base.lproj/Localizable.strings @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. // Generic alert action names @@ -109,6 +109,7 @@ "tunnelOnDemandSectionTitleAddSSIDs" = "Add SSIDs"; "tunnelOnDemandAddMessageAddConnectedSSID (%@)" = "Add connected: %@"; "tunnelOnDemandAddMessageAddNewSSID" = "Add new"; +"tunnelOnDemandSSIDTextFieldPlaceholder" = "SSID"; "tunnelOnDemandKey" = "On demand"; "tunnelOnDemandOptionOff" = "Off"; @@ -297,6 +298,7 @@ "macMenuNetworksNone" = "Networks: None"; "macMenuTitle" = "WireGuard"; +"macTunnelsMenuTitle" = "Tunnels"; "macMenuManageTunnels" = "Manage Tunnels"; "macMenuImportTunnels" = "Import Tunnel(s) from File…"; "macMenuAddEmptyTunnel" = "Add Empty Tunnel…"; diff --git a/Sources/WireGuardApp/Config/Version.xcconfig b/Sources/WireGuardApp/Config/Version.xcconfig index fa6e391a1..276a68ffe 100644 --- a/Sources/WireGuardApp/Config/Version.xcconfig +++ b/Sources/WireGuardApp/Config/Version.xcconfig @@ -1,2 +1,2 @@ -VERSION_NAME = 1.0.11 -VERSION_ID = 21 +VERSION_NAME = 1.0.13 +VERSION_ID = 24 diff --git a/Sources/WireGuardApp/LocalizationHelper.swift b/Sources/WireGuardApp/LocalizationHelper.swift index 04555a409..0f22acbe1 100644 --- a/Sources/WireGuardApp/LocalizationHelper.swift +++ b/Sources/WireGuardApp/LocalizationHelper.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Foundation diff --git a/Sources/WireGuardApp/Tunnel/ActivateOnDemandOption.swift b/Sources/WireGuardApp/Tunnel/ActivateOnDemandOption.swift index d32bdb75d..0de026eed 100644 --- a/Sources/WireGuardApp/Tunnel/ActivateOnDemandOption.swift +++ b/Sources/WireGuardApp/Tunnel/ActivateOnDemandOption.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import NetworkExtension diff --git a/Sources/WireGuardApp/Tunnel/MockTunnels.swift b/Sources/WireGuardApp/Tunnel/MockTunnels.swift index 94537fc09..15fe1c2f1 100644 --- a/Sources/WireGuardApp/Tunnel/MockTunnels.swift +++ b/Sources/WireGuardApp/Tunnel/MockTunnels.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import NetworkExtension diff --git a/Sources/WireGuardApp/Tunnel/TunnelConfiguration+UapiConfig.swift b/Sources/WireGuardApp/Tunnel/TunnelConfiguration+UapiConfig.swift index e8aa8a994..cdc81cee4 100644 --- a/Sources/WireGuardApp/Tunnel/TunnelConfiguration+UapiConfig.swift +++ b/Sources/WireGuardApp/Tunnel/TunnelConfiguration+UapiConfig.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Foundation diff --git a/Sources/WireGuardApp/Tunnel/TunnelErrors.swift b/Sources/WireGuardApp/Tunnel/TunnelErrors.swift index e8db86a7d..99c90d002 100644 --- a/Sources/WireGuardApp/Tunnel/TunnelErrors.swift +++ b/Sources/WireGuardApp/Tunnel/TunnelErrors.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import NetworkExtension diff --git a/Sources/WireGuardApp/Tunnel/TunnelStatus.swift b/Sources/WireGuardApp/Tunnel/TunnelStatus.swift index 496ca5ec3..3d4a408ba 100644 --- a/Sources/WireGuardApp/Tunnel/TunnelStatus.swift +++ b/Sources/WireGuardApp/Tunnel/TunnelStatus.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Foundation import NetworkExtension diff --git a/Sources/WireGuardApp/Tunnel/TunnelsManager.swift b/Sources/WireGuardApp/Tunnel/TunnelsManager.swift index 352336d9a..cecaf58b0 100644 --- a/Sources/WireGuardApp/Tunnel/TunnelsManager.swift +++ b/Sources/WireGuardApp/Tunnel/TunnelsManager.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Foundation import NetworkExtension @@ -260,19 +260,22 @@ class TunnelsManager { (tunnel.tunnelProvider.connection as? NETunnelProviderSession)?.stopTunnel() } } - - // Reload tunnel after saving. - // Without this, the tunnel stopes getting updates on the tunnel status from iOS. - tunnelProviderManager.loadFromPreferences { error in - tunnel.tunnelManagerDidChangeTunnelProvider() - if let error = error { - wg_log(.error, message: "Modify: Re-loading after saving configuration failed: \(error)") - completionHandler(TunnelsManagerError.systemErrorOnModifyTunnel(systemError: error)) - } else { - completionHandler(nil) + + if isActivatingOnDemand { + // Reload tunnel after saving. + // Without this, the tunnel stopes getting updates on the tunnel status from iOS. + tunnelProviderManager.loadFromPreferences { error in + tunnel.isActivateOnDemandEnabled = tunnelProviderManager.isOnDemandEnabled + if let error = error { + wg_log(.error, message: "Modify: Re-loading after saving configuration failed: \(error)") + completionHandler(TunnelsManagerError.systemErrorOnModifyTunnel(systemError: error)) + } else { + completionHandler(nil) + } } + } else { + completionHandler(nil) } - } } diff --git a/Sources/WireGuardApp/UI/ActivateOnDemandViewModel.swift b/Sources/WireGuardApp/UI/ActivateOnDemandViewModel.swift index a11ace61f..121a1a623 100644 --- a/Sources/WireGuardApp/UI/ActivateOnDemandViewModel.swift +++ b/Sources/WireGuardApp/UI/ActivateOnDemandViewModel.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Foundation diff --git a/Sources/WireGuardApp/UI/ErrorPresenterProtocol.swift b/Sources/WireGuardApp/UI/ErrorPresenterProtocol.swift index 93633c0dc..aed2149c3 100644 --- a/Sources/WireGuardApp/UI/ErrorPresenterProtocol.swift +++ b/Sources/WireGuardApp/UI/ErrorPresenterProtocol.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. protocol ErrorPresenterProtocol { static func showErrorAlert(title: String, message: String, from sourceVC: AnyObject?, onPresented: (() -> Void)?, onDismissal: (() -> Void)?) diff --git a/Sources/WireGuardApp/UI/LogViewHelper.swift b/Sources/WireGuardApp/UI/LogViewHelper.swift index 7d2b47028..0b97b8fba 100644 --- a/Sources/WireGuardApp/UI/LogViewHelper.swift +++ b/Sources/WireGuardApp/UI/LogViewHelper.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Foundation diff --git a/Sources/WireGuardApp/UI/PrivateDataConfirmation.swift b/Sources/WireGuardApp/UI/PrivateDataConfirmation.swift index 2b3e7b58c..4b134a344 100644 --- a/Sources/WireGuardApp/UI/PrivateDataConfirmation.swift +++ b/Sources/WireGuardApp/UI/PrivateDataConfirmation.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Foundation import LocalAuthentication diff --git a/Sources/WireGuardApp/UI/TunnelImporter.swift b/Sources/WireGuardApp/UI/TunnelImporter.swift index 672a4f759..469158280 100644 --- a/Sources/WireGuardApp/UI/TunnelImporter.swift +++ b/Sources/WireGuardApp/UI/TunnelImporter.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Foundation diff --git a/Sources/WireGuardApp/UI/TunnelViewModel.swift b/Sources/WireGuardApp/UI/TunnelViewModel.swift index cf7de4ea5..b65c8ccfd 100644 --- a/Sources/WireGuardApp/UI/TunnelViewModel.swift +++ b/Sources/WireGuardApp/UI/TunnelViewModel.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Foundation diff --git a/Sources/WireGuardApp/UI/iOS/AppDelegate.swift b/Sources/WireGuardApp/UI/iOS/AppDelegate.swift index 4262e95c8..4ab3b303f 100644 --- a/Sources/WireGuardApp/UI/iOS/AppDelegate.swift +++ b/Sources/WireGuardApp/UI/iOS/AppDelegate.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import UIKit import os.log diff --git a/Sources/WireGuardApp/UI/iOS/ConfirmationAlertPresenter.swift b/Sources/WireGuardApp/UI/iOS/ConfirmationAlertPresenter.swift index 8290ebba0..824a0a52c 100644 --- a/Sources/WireGuardApp/UI/iOS/ConfirmationAlertPresenter.swift +++ b/Sources/WireGuardApp/UI/iOS/ConfirmationAlertPresenter.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import UIKit diff --git a/Sources/WireGuardApp/UI/iOS/ErrorPresenter.swift b/Sources/WireGuardApp/UI/iOS/ErrorPresenter.swift index b4f27db03..5dd505beb 100644 --- a/Sources/WireGuardApp/UI/iOS/ErrorPresenter.swift +++ b/Sources/WireGuardApp/UI/iOS/ErrorPresenter.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import UIKit import os.log diff --git a/Sources/WireGuardApp/UI/iOS/QuickActionItem.swift b/Sources/WireGuardApp/UI/iOS/QuickActionItem.swift index cddaf2367..f41d8a0d9 100644 --- a/Sources/WireGuardApp/UI/iOS/QuickActionItem.swift +++ b/Sources/WireGuardApp/UI/iOS/QuickActionItem.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import UIKit diff --git a/Sources/WireGuardApp/UI/iOS/RecentTunnelsTracker.swift b/Sources/WireGuardApp/UI/iOS/RecentTunnelsTracker.swift index f98bdc71e..ddc5ca946 100644 --- a/Sources/WireGuardApp/UI/iOS/RecentTunnelsTracker.swift +++ b/Sources/WireGuardApp/UI/iOS/RecentTunnelsTracker.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Foundation diff --git a/Sources/WireGuardApp/UI/iOS/UITableViewCell+Reuse.swift b/Sources/WireGuardApp/UI/iOS/UITableViewCell+Reuse.swift index 5ceb86327..fbe56a11c 100644 --- a/Sources/WireGuardApp/UI/iOS/UITableViewCell+Reuse.swift +++ b/Sources/WireGuardApp/UI/iOS/UITableViewCell+Reuse.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import UIKit diff --git a/Sources/WireGuardApp/UI/iOS/View/BorderedTextButton.swift b/Sources/WireGuardApp/UI/iOS/View/BorderedTextButton.swift index 114a879e9..f8f373a7e 100644 --- a/Sources/WireGuardApp/UI/iOS/View/BorderedTextButton.swift +++ b/Sources/WireGuardApp/UI/iOS/View/BorderedTextButton.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import UIKit diff --git a/Sources/WireGuardApp/UI/iOS/View/ButtonCell.swift b/Sources/WireGuardApp/UI/iOS/View/ButtonCell.swift index 2e9ed46da..1d9912dd9 100644 --- a/Sources/WireGuardApp/UI/iOS/View/ButtonCell.swift +++ b/Sources/WireGuardApp/UI/iOS/View/ButtonCell.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import UIKit diff --git a/Sources/WireGuardApp/UI/iOS/View/CheckmarkCell.swift b/Sources/WireGuardApp/UI/iOS/View/CheckmarkCell.swift index e3ec62323..34eb0df71 100644 --- a/Sources/WireGuardApp/UI/iOS/View/CheckmarkCell.swift +++ b/Sources/WireGuardApp/UI/iOS/View/CheckmarkCell.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import UIKit diff --git a/Sources/WireGuardApp/UI/iOS/View/ChevronCell.swift b/Sources/WireGuardApp/UI/iOS/View/ChevronCell.swift index ce4f1ec42..30256a0f6 100644 --- a/Sources/WireGuardApp/UI/iOS/View/ChevronCell.swift +++ b/Sources/WireGuardApp/UI/iOS/View/ChevronCell.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import UIKit diff --git a/Sources/WireGuardApp/UI/iOS/View/EditableTextCell.swift b/Sources/WireGuardApp/UI/iOS/View/EditableTextCell.swift index f7e907e58..d84d23e51 100644 --- a/Sources/WireGuardApp/UI/iOS/View/EditableTextCell.swift +++ b/Sources/WireGuardApp/UI/iOS/View/EditableTextCell.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import UIKit @@ -9,6 +9,11 @@ class EditableTextCell: UITableViewCell { set(value) { valueTextField.text = value } } + var placeholder: String? { + get { return valueTextField.placeholder } + set(value) { valueTextField.placeholder = value } + } + let valueTextField: UITextField = { let valueTextField = UITextField() valueTextField.textAlignment = .left @@ -29,12 +34,13 @@ class EditableTextCell: UITableViewCell { valueTextField.delegate = self contentView.addSubview(valueTextField) valueTextField.translatesAutoresizingMaskIntoConstraints = false - let bottomAnchorConstraint = contentView.layoutMarginsGuide.bottomAnchor.constraint(equalToSystemSpacingBelow: valueTextField.bottomAnchor, multiplier: 1) + // Reduce the bottom margin by 0.5pt to maintain the default cell height (44pt) + let bottomAnchorConstraint = contentView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: valueTextField.bottomAnchor, constant: -0.5) bottomAnchorConstraint.priority = .defaultLow NSLayoutConstraint.activate([ - valueTextField.leadingAnchor.constraint(equalToSystemSpacingAfter: contentView.layoutMarginsGuide.leadingAnchor, multiplier: 1), - contentView.layoutMarginsGuide.trailingAnchor.constraint(equalToSystemSpacingAfter: valueTextField.trailingAnchor, multiplier: 1), - valueTextField.topAnchor.constraint(equalToSystemSpacingBelow: contentView.layoutMarginsGuide.topAnchor, multiplier: 1), + valueTextField.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor), + contentView.layoutMarginsGuide.trailingAnchor.constraint(equalTo: valueTextField.trailingAnchor), + contentView.layoutMarginsGuide.topAnchor.constraint(equalTo: valueTextField.topAnchor), bottomAnchorConstraint ]) } @@ -50,6 +56,7 @@ class EditableTextCell: UITableViewCell { override func prepareForReuse() { super.prepareForReuse() message = "" + placeholder = nil } } diff --git a/Sources/WireGuardApp/UI/iOS/View/KeyValueCell.swift b/Sources/WireGuardApp/UI/iOS/View/KeyValueCell.swift index f99e3eac9..e8c38503a 100644 --- a/Sources/WireGuardApp/UI/iOS/View/KeyValueCell.swift +++ b/Sources/WireGuardApp/UI/iOS/View/KeyValueCell.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import UIKit @@ -27,7 +27,7 @@ class KeyValueCell: UITableViewCell { }() let valueTextField: UITextField = { - let valueTextField = UITextField() + let valueTextField = KeyValueCellTextField() valueTextField.textAlignment = .right valueTextField.isEnabled = false valueTextField.font = UIFont.preferredFont(forTextStyle: .body) @@ -115,8 +115,6 @@ class KeyValueCell: UITableViewCell { expandToFitValueLabelConstraint.priority = .defaultLow + 1 expandToFitValueLabelConstraint.isActive = true - contentView.addSubview(valueLabelScrollView) - contentView.addSubview(valueLabelScrollView) valueLabelScrollView.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ @@ -234,3 +232,10 @@ extension KeyValueCell: UITextFieldDelegate { } } + +class KeyValueCellTextField: UITextField { + override func placeholderRect(forBounds bounds: CGRect) -> CGRect { + // UIKit renders the placeholder label 0.5pt higher + return super.placeholderRect(forBounds: bounds).integral.offsetBy(dx: 0, dy: -0.5) + } +} diff --git a/Sources/WireGuardApp/UI/iOS/View/SwitchCell.swift b/Sources/WireGuardApp/UI/iOS/View/SwitchCell.swift index 19938be23..9bdc34578 100644 --- a/Sources/WireGuardApp/UI/iOS/View/SwitchCell.swift +++ b/Sources/WireGuardApp/UI/iOS/View/SwitchCell.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import UIKit diff --git a/Sources/WireGuardApp/UI/iOS/View/TextCell.swift b/Sources/WireGuardApp/UI/iOS/View/TextCell.swift index d1f41e1de..9de50127e 100644 --- a/Sources/WireGuardApp/UI/iOS/View/TextCell.swift +++ b/Sources/WireGuardApp/UI/iOS/View/TextCell.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import UIKit diff --git a/Sources/WireGuardApp/UI/iOS/View/TunnelEditKeyValueCell.swift b/Sources/WireGuardApp/UI/iOS/View/TunnelEditKeyValueCell.swift index a6abae2dd..ac6f063d5 100644 --- a/Sources/WireGuardApp/UI/iOS/View/TunnelEditKeyValueCell.swift +++ b/Sources/WireGuardApp/UI/iOS/View/TunnelEditKeyValueCell.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import UIKit diff --git a/Sources/WireGuardApp/UI/iOS/View/TunnelListCell.swift b/Sources/WireGuardApp/UI/iOS/View/TunnelListCell.swift index 6015c8ee1..dd5f3d601 100644 --- a/Sources/WireGuardApp/UI/iOS/View/TunnelListCell.swift +++ b/Sources/WireGuardApp/UI/iOS/View/TunnelListCell.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import UIKit diff --git a/Sources/WireGuardApp/UI/iOS/ViewController/LogViewController.swift b/Sources/WireGuardApp/UI/iOS/ViewController/LogViewController.swift index 76d9a731c..eed5e46be 100644 --- a/Sources/WireGuardApp/UI/iOS/ViewController/LogViewController.swift +++ b/Sources/WireGuardApp/UI/iOS/ViewController/LogViewController.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import UIKit diff --git a/Sources/WireGuardApp/UI/iOS/ViewController/MainViewController.swift b/Sources/WireGuardApp/UI/iOS/ViewController/MainViewController.swift index 27db2cdd5..b7805172e 100644 --- a/Sources/WireGuardApp/UI/iOS/ViewController/MainViewController.swift +++ b/Sources/WireGuardApp/UI/iOS/ViewController/MainViewController.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import UIKit diff --git a/Sources/WireGuardApp/UI/iOS/ViewController/QRScanViewController.swift b/Sources/WireGuardApp/UI/iOS/ViewController/QRScanViewController.swift index 39df0ca7c..601f7b8a3 100644 --- a/Sources/WireGuardApp/UI/iOS/ViewController/QRScanViewController.swift +++ b/Sources/WireGuardApp/UI/iOS/ViewController/QRScanViewController.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import AVFoundation import UIKit diff --git a/Sources/WireGuardApp/UI/iOS/ViewController/SSIDOptionDetailTableViewController.swift b/Sources/WireGuardApp/UI/iOS/ViewController/SSIDOptionDetailTableViewController.swift index c23544af1..d315e2f81 100644 --- a/Sources/WireGuardApp/UI/iOS/ViewController/SSIDOptionDetailTableViewController.swift +++ b/Sources/WireGuardApp/UI/iOS/ViewController/SSIDOptionDetailTableViewController.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import UIKit diff --git a/Sources/WireGuardApp/UI/iOS/ViewController/SSIDOptionEditTableViewController.swift b/Sources/WireGuardApp/UI/iOS/ViewController/SSIDOptionEditTableViewController.swift index 527a8fdf8..56a344778 100644 --- a/Sources/WireGuardApp/UI/iOS/ViewController/SSIDOptionEditTableViewController.swift +++ b/Sources/WireGuardApp/UI/iOS/ViewController/SSIDOptionEditTableViewController.swift @@ -1,8 +1,9 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import UIKit import SystemConfiguration.CaptiveNetwork +import NetworkExtension protocol SSIDOptionEditTableViewControllerDelegate: class { func ssidOptionSaved(option: ActivateOnDemandViewModel.OnDemandSSIDOption, ssids: [String]) @@ -39,9 +40,16 @@ class SSIDOptionEditTableViewController: UITableViewController { selectedOption = option selectedSSIDs = ssids super.init(style: .grouped) - connectedSSID = getConnectedSSID() loadSections() - loadAddSSIDRows() + addSSIDRows.removeAll() + addSSIDRows.append(.addNewSSID) + + getConnectedSSID { [weak self] ssid in + guard let self = self else { return } + self.connectedSSID = ssid + self.updateCurrentSSIDEntry() + self.updateTableViewAddSSIDRows() + } } required init?(coder aDecoder: NSCoder) { @@ -60,6 +68,7 @@ class SSIDOptionEditTableViewController: UITableViewController { tableView.register(TextCell.self) tableView.isEditing = true tableView.allowsSelectionDuringEditing = true + tableView.keyboardDismissMode = .onDrag } func loadSections() { @@ -71,14 +80,14 @@ class SSIDOptionEditTableViewController: UITableViewController { } } - func loadAddSSIDRows() { - addSSIDRows.removeAll() - if let connectedSSID = connectedSSID { - if !selectedSSIDs.contains(connectedSSID) { - addSSIDRows.append(.addConnectedSSID(connectedSSID: connectedSSID)) + func updateCurrentSSIDEntry() { + if let connectedSSID = connectedSSID, !selectedSSIDs.contains(connectedSSID) { + if let first = addSSIDRows.first, case .addNewSSID = first { + addSSIDRows.insert(.addConnectedSSID(connectedSSID: connectedSSID), at: 0) } + } else if let first = addSSIDRows.first, case .addConnectedSSID = first { + addSSIDRows.removeFirst() } - addSSIDRows.append(.addNewSSID) } func updateTableViewAddSSIDRows() { @@ -188,12 +197,13 @@ extension SSIDOptionEditTableViewController { private func selectedSSIDCell(for tableView: UITableView, at indexPath: IndexPath) -> UITableViewCell { let cell: EditableTextCell = tableView.dequeueReusableCell(for: indexPath) cell.message = selectedSSIDs[indexPath.row] + cell.placeholder = tr("tunnelOnDemandSSIDTextFieldPlaceholder") cell.isEditing = true cell.onValueBeingEdited = { [weak self, weak cell] text in guard let self = self, let cell = cell else { return } if let row = self.tableView.indexPath(for: cell)?.row { self.selectedSSIDs[row] = text - self.loadAddSSIDRows() + self.updateCurrentSSIDEntry() self.updateTableViewAddSSIDRows() } } @@ -224,7 +234,7 @@ extension SSIDOptionEditTableViewController { } else { tableView.reloadRows(at: [indexPath], with: .automatic) } - loadAddSSIDRows() + updateCurrentSSIDEntry() updateTableViewAddSSIDRows() case .addSSIDs: assert(editingStyle == .insert) @@ -244,7 +254,7 @@ extension SSIDOptionEditTableViewController { } else { tableView.insertRows(at: [indexPath], with: .automatic) } - loadAddSSIDRows() + updateCurrentSSIDEntry() updateTableViewAddSSIDRows() if newSSID.isEmpty { if let selectedSSIDCell = tableView.cellForRow(at: indexPath) as? EditableTextCell { @@ -253,6 +263,31 @@ extension SSIDOptionEditTableViewController { } } } + + private func getConnectedSSID(completionHandler: @escaping (String?) -> Void) { + #if targetEnvironment(simulator) + completionHandler("Simulator Wi-Fi") + #else + if #available(iOS 14, *) { + NEHotspotNetwork.fetchCurrent { hotspotNetwork in + completionHandler(hotspotNetwork?.ssid) + } + } else { + if let supportedInterfaces = CNCopySupportedInterfaces() as? [CFString] { + for interface in supportedInterfaces { + if let networkInfo = CNCopyCurrentNetworkInfo(interface) { + if let ssid = (networkInfo as NSDictionary)[kCNNetworkInfoKeySSID as String] as? String { + completionHandler(!ssid.isEmpty ? ssid : nil) + return + } + } + } + } + + completionHandler(nil) + } + #endif + } } extension SSIDOptionEditTableViewController { @@ -290,14 +325,3 @@ extension SSIDOptionEditTableViewController { } } -private func getConnectedSSID() -> String? { - guard let supportedInterfaces = CNCopySupportedInterfaces() as? [CFString] else { return nil } - for interface in supportedInterfaces { - if let networkInfo = CNCopyCurrentNetworkInfo(interface) { - if let ssid = (networkInfo as NSDictionary)[kCNNetworkInfoKeySSID as String] as? String { - return !ssid.isEmpty ? ssid : nil - } - } - } - return nil -} diff --git a/Sources/WireGuardApp/UI/iOS/ViewController/SettingsTableViewController.swift b/Sources/WireGuardApp/UI/iOS/ViewController/SettingsTableViewController.swift index a3afafd3b..afec4b0a7 100644 --- a/Sources/WireGuardApp/UI/iOS/ViewController/SettingsTableViewController.swift +++ b/Sources/WireGuardApp/UI/iOS/ViewController/SettingsTableViewController.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import UIKit import os.log diff --git a/Sources/WireGuardApp/UI/iOS/ViewController/TunnelDetailTableViewController.swift b/Sources/WireGuardApp/UI/iOS/ViewController/TunnelDetailTableViewController.swift index 696136f8a..a699d1977 100644 --- a/Sources/WireGuardApp/UI/iOS/ViewController/TunnelDetailTableViewController.swift +++ b/Sources/WireGuardApp/UI/iOS/ViewController/TunnelDetailTableViewController.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import UIKit @@ -395,6 +395,7 @@ extension TunnelDetailTableViewController { let cell: KeyValueCell = tableView.dequeueReusableCell(for: indexPath) cell.key = field.localizedUIString cell.value = onDemandViewModel.localizedInterfaceDescription + cell.copyableGesture = false return cell } else { assert(field == .ssid) @@ -402,6 +403,7 @@ extension TunnelDetailTableViewController { let cell: KeyValueCell = tableView.dequeueReusableCell(for: indexPath) cell.key = field.localizedUIString cell.value = onDemandViewModel.ssidOption.localizedUIString + cell.copyableGesture = false return cell } else { let cell: ChevronCell = tableView.dequeueReusableCell(for: indexPath) diff --git a/Sources/WireGuardApp/UI/iOS/ViewController/TunnelEditTableViewController.swift b/Sources/WireGuardApp/UI/iOS/ViewController/TunnelEditTableViewController.swift index 2abce6f23..e619a8a91 100644 --- a/Sources/WireGuardApp/UI/iOS/ViewController/TunnelEditTableViewController.swift +++ b/Sources/WireGuardApp/UI/iOS/ViewController/TunnelEditTableViewController.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import UIKit diff --git a/Sources/WireGuardApp/UI/iOS/ViewController/TunnelsListTableViewController.swift b/Sources/WireGuardApp/UI/iOS/ViewController/TunnelsListTableViewController.swift index 26f5b20cd..bcb8d1f29 100644 --- a/Sources/WireGuardApp/UI/iOS/ViewController/TunnelsListTableViewController.swift +++ b/Sources/WireGuardApp/UI/iOS/ViewController/TunnelsListTableViewController.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import UIKit import MobileCoreServices diff --git a/Sources/WireGuardApp/UI/macOS/AppDelegate.swift b/Sources/WireGuardApp/UI/macOS/AppDelegate.swift index 0c33896a0..c56091e20 100644 --- a/Sources/WireGuardApp/UI/macOS/AppDelegate.swift +++ b/Sources/WireGuardApp/UI/macOS/AppDelegate.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Cocoa import ServiceManagement diff --git a/Sources/WireGuardApp/UI/macOS/Application.swift b/Sources/WireGuardApp/UI/macOS/Application.swift index 597d51183..c45763f5e 100644 --- a/Sources/WireGuardApp/UI/macOS/Application.swift +++ b/Sources/WireGuardApp/UI/macOS/Application.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Cocoa diff --git a/Sources/WireGuardApp/UI/macOS/ErrorPresenter.swift b/Sources/WireGuardApp/UI/macOS/ErrorPresenter.swift index eb1f1b65d..71157dbcc 100644 --- a/Sources/WireGuardApp/UI/macOS/ErrorPresenter.swift +++ b/Sources/WireGuardApp/UI/macOS/ErrorPresenter.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Cocoa diff --git a/Sources/WireGuardApp/UI/macOS/ImportPanelPresenter.swift b/Sources/WireGuardApp/UI/macOS/ImportPanelPresenter.swift index 033399d4b..c236e0871 100644 --- a/Sources/WireGuardApp/UI/macOS/ImportPanelPresenter.swift +++ b/Sources/WireGuardApp/UI/macOS/ImportPanelPresenter.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Cocoa diff --git a/Sources/WireGuardApp/UI/macOS/Info.plist b/Sources/WireGuardApp/UI/macOS/Info.plist index 69c4f3f80..ac23171b8 100644 --- a/Sources/WireGuardApp/UI/macOS/Info.plist +++ b/Sources/WireGuardApp/UI/macOS/Info.plist @@ -31,7 +31,7 @@ LSUIElement NSHumanReadableCopyright - Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. + Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. NSPrincipalClass WireGuard.Application com.macos.app_group_id diff --git a/Sources/WireGuardApp/UI/macOS/LaunchedAtLoginDetector.swift b/Sources/WireGuardApp/UI/macOS/LaunchedAtLoginDetector.swift index be68dce59..b3c6995a6 100644 --- a/Sources/WireGuardApp/UI/macOS/LaunchedAtLoginDetector.swift +++ b/Sources/WireGuardApp/UI/macOS/LaunchedAtLoginDetector.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Cocoa diff --git a/Sources/WireGuardApp/UI/macOS/LoginItemHelper/Info.plist b/Sources/WireGuardApp/UI/macOS/LoginItemHelper/Info.plist index c7f0c25b5..9e2645ed5 100644 --- a/Sources/WireGuardApp/UI/macOS/LoginItemHelper/Info.plist +++ b/Sources/WireGuardApp/UI/macOS/LoginItemHelper/Info.plist @@ -27,7 +27,7 @@ LSMinimumSystemVersion $(MACOSX_DEPLOYMENT_TARGET) NSHumanReadableCopyright - Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. + Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. NSPrincipalClass NSApplication com.macos.app_id diff --git a/Sources/WireGuardApp/UI/macOS/LoginItemHelper/main.m b/Sources/WireGuardApp/UI/macOS/LoginItemHelper/main.m index 102fbceaf..0f7288b3c 100644 --- a/Sources/WireGuardApp/UI/macOS/LoginItemHelper/main.m +++ b/Sources/WireGuardApp/UI/macOS/LoginItemHelper/main.m @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. #import diff --git a/Sources/WireGuardApp/UI/macOS/MacAppStoreUpdateDetector.swift b/Sources/WireGuardApp/UI/macOS/MacAppStoreUpdateDetector.swift index 5036ff256..7304bed46 100644 --- a/Sources/WireGuardApp/UI/macOS/MacAppStoreUpdateDetector.swift +++ b/Sources/WireGuardApp/UI/macOS/MacAppStoreUpdateDetector.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Cocoa diff --git a/Sources/WireGuardApp/UI/macOS/NSColor+Hex.swift b/Sources/WireGuardApp/UI/macOS/NSColor+Hex.swift index e6ece0322..b77e82edf 100644 --- a/Sources/WireGuardApp/UI/macOS/NSColor+Hex.swift +++ b/Sources/WireGuardApp/UI/macOS/NSColor+Hex.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import AppKit diff --git a/Sources/WireGuardApp/UI/macOS/NSTableView+Reuse.swift b/Sources/WireGuardApp/UI/macOS/NSTableView+Reuse.swift index 3b7d09f11..5f2e7ddf1 100644 --- a/Sources/WireGuardApp/UI/macOS/NSTableView+Reuse.swift +++ b/Sources/WireGuardApp/UI/macOS/NSTableView+Reuse.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Cocoa diff --git a/Sources/WireGuardApp/UI/macOS/ParseError+WireGuardAppError.swift b/Sources/WireGuardApp/UI/macOS/ParseError+WireGuardAppError.swift index 307a94e33..96da524dd 100644 --- a/Sources/WireGuardApp/UI/macOS/ParseError+WireGuardAppError.swift +++ b/Sources/WireGuardApp/UI/macOS/ParseError+WireGuardAppError.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Cocoa diff --git a/Sources/WireGuardApp/UI/macOS/StatusItemController.swift b/Sources/WireGuardApp/UI/macOS/StatusItemController.swift index eb31a2c8e..19723cbed 100644 --- a/Sources/WireGuardApp/UI/macOS/StatusItemController.swift +++ b/Sources/WireGuardApp/UI/macOS/StatusItemController.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Cocoa diff --git a/Sources/WireGuardApp/UI/macOS/StatusMenu.swift b/Sources/WireGuardApp/UI/macOS/StatusMenu.swift index 5630fdcc4..7076330e6 100644 --- a/Sources/WireGuardApp/UI/macOS/StatusMenu.swift +++ b/Sources/WireGuardApp/UI/macOS/StatusMenu.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Cocoa @@ -14,8 +14,14 @@ class StatusMenu: NSMenu { var statusMenuItem: NSMenuItem? var networksMenuItem: NSMenuItem? var deactivateMenuItem: NSMenuItem? - var firstTunnelMenuItemIndex = 0 - var numberOfTunnelMenuItems = 0 + + private let tunnelsBreakdownMenu = NSMenu() + private let tunnelsMenuItem = NSMenuItem(title: tr("macTunnelsMenuTitle"), action: nil, keyEquivalent: "") + private let tunnelsMenuSeparatorItem = NSMenuItem.separator() + + private var firstTunnelMenuItemIndex = 0 + private var numberOfTunnelMenuItems = 0 + private var tunnelsPresentationStyle = StatusMenuTunnelsPresentationStyle.inline var currentTunnel: TunnelContainer? { didSet { @@ -26,16 +32,20 @@ class StatusMenu: NSMenu { init(tunnelsManager: TunnelsManager) { self.tunnelsManager = tunnelsManager + super.init(title: tr("macMenuTitle")) addStatusMenuItems() addItem(NSMenuItem.separator()) + tunnelsMenuItem.submenu = tunnelsBreakdownMenu + addItem(tunnelsMenuItem) + firstTunnelMenuItemIndex = numberOfItems - let isAdded = addTunnelMenuItems() - if isAdded { - addItem(NSMenuItem.separator()) - } + populateInitialTunnelMenuItems() + + addItem(tunnelsMenuSeparatorItem) + addTunnelManagementItems() addItem(NSMenuItem.separator()) addApplicationItems() @@ -108,15 +118,6 @@ class StatusMenu: NSMenu { deactivateMenuItem.isHidden = tunnel.status != .active } - func addTunnelMenuItems() -> Bool { - let numberOfTunnels = tunnelsManager.numberOfTunnels() - for index in 0 ..< tunnelsManager.numberOfTunnels() { - let tunnel = tunnelsManager.tunnel(at: index) - insertTunnelMenuItem(for: tunnel, at: numberOfTunnelMenuItems) - } - return numberOfTunnels > 0 - } - func addTunnelManagementItems() { let manageItem = NSMenuItem(title: tr("macMenuManageTunnels"), action: #selector(manageTunnelsClicked), keyEquivalent: "") manageItem.target = self @@ -166,34 +167,121 @@ class StatusMenu: NSMenu { extension StatusMenu { func insertTunnelMenuItem(for tunnel: TunnelContainer, at tunnelIndex: Int) { + let nextNumberOfTunnels = numberOfTunnelMenuItems + 1 + + guard !reparentTunnelMenuItems(nextNumberOfTunnels: nextNumberOfTunnels) else { + return + } + + let menuItem = makeTunnelItem(tunnel: tunnel) + switch tunnelsPresentationStyle { + case .submenu: + tunnelsBreakdownMenu.insertItem(menuItem, at: tunnelIndex) + case .inline: + insertItem(menuItem, at: firstTunnelMenuItemIndex + tunnelIndex) + } + + numberOfTunnelMenuItems = nextNumberOfTunnels + updateTunnelsMenuItemVisibility() + } + + func removeTunnelMenuItem(at tunnelIndex: Int) { + let nextNumberOfTunnels = numberOfTunnelMenuItems - 1 + + guard !reparentTunnelMenuItems(nextNumberOfTunnels: nextNumberOfTunnels) else { + return + } + + switch tunnelsPresentationStyle { + case .submenu: + tunnelsBreakdownMenu.removeItem(at: tunnelIndex) + case .inline: + removeItem(at: firstTunnelMenuItemIndex + tunnelIndex) + } + + numberOfTunnelMenuItems = nextNumberOfTunnels + updateTunnelsMenuItemVisibility() + } + + func moveTunnelMenuItem(from oldTunnelIndex: Int, to newTunnelIndex: Int) { + let tunnel = tunnelsManager.tunnel(at: newTunnelIndex) + let menuItem = makeTunnelItem(tunnel: tunnel) + + switch tunnelsPresentationStyle { + case .submenu: + tunnelsBreakdownMenu.removeItem(at: oldTunnelIndex) + tunnelsBreakdownMenu.insertItem(menuItem, at: newTunnelIndex) + case .inline: + removeItem(at: firstTunnelMenuItemIndex + oldTunnelIndex) + insertItem(menuItem, at: firstTunnelMenuItemIndex + newTunnelIndex) + } + } + + private func makeTunnelItem(tunnel: TunnelContainer) -> TunnelMenuItem { let menuItem = TunnelMenuItem(tunnel: tunnel, action: #selector(tunnelClicked(sender:))) menuItem.target = self menuItem.isHidden = !tunnel.isTunnelAvailableToUser - insertItem(menuItem, at: firstTunnelMenuItemIndex + tunnelIndex) - if numberOfTunnelMenuItems == 0 { - insertItem(NSMenuItem.separator(), at: firstTunnelMenuItemIndex + tunnelIndex + 1) + return menuItem + } + + private func populateInitialTunnelMenuItems() { + let numberOfTunnels = tunnelsManager.numberOfTunnels() + let initialStyle = tunnelsPresentationStyle.preferredPresentationStyle(numberOfTunnels: numberOfTunnels) + + tunnelsPresentationStyle = initialStyle + switch initialStyle { + case .inline: + numberOfTunnelMenuItems = addTunnelMenuItems(into: self, at: firstTunnelMenuItemIndex) + case .submenu: + numberOfTunnelMenuItems = addTunnelMenuItems(into: tunnelsBreakdownMenu, at: 0) } - numberOfTunnelMenuItems += 1 + + updateTunnelsMenuItemVisibility() } - func removeTunnelMenuItem(at tunnelIndex: Int) { - removeItem(at: firstTunnelMenuItemIndex + tunnelIndex) - numberOfTunnelMenuItems -= 1 - if numberOfTunnelMenuItems == 0 { - if let firstItem = item(at: firstTunnelMenuItemIndex), firstItem.isSeparatorItem { - removeItem(at: firstTunnelMenuItemIndex) + private func reparentTunnelMenuItems(nextNumberOfTunnels: Int) -> Bool { + let nextStyle = tunnelsPresentationStyle.preferredPresentationStyle(numberOfTunnels: nextNumberOfTunnels) + + switch (tunnelsPresentationStyle, nextStyle) { + case (.inline, .submenu): + tunnelsPresentationStyle = nextStyle + for index in (0.. Int { + let numberOfTunnels = tunnelsManager.numberOfTunnels() + for tunnelIndex in 0.. StatusMenuTunnelsPresentationStyle { + let maxInlineTunnels = 10 + + if case .inline = self, numberOfTunnels > maxInlineTunnels { + return .submenu + } else if case .submenu = self, numberOfTunnels <= maxInlineTunnels { + return .inline + } else { + return self + } + } +} diff --git a/Sources/WireGuardApp/UI/macOS/TunnelsTracker.swift b/Sources/WireGuardApp/UI/macOS/TunnelsTracker.swift index aef65ef5c..86cfaa647 100644 --- a/Sources/WireGuardApp/UI/macOS/TunnelsTracker.swift +++ b/Sources/WireGuardApp/UI/macOS/TunnelsTracker.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Cocoa diff --git a/Sources/WireGuardApp/UI/macOS/View/ButtonRow.swift b/Sources/WireGuardApp/UI/macOS/View/ButtonRow.swift index 4ecd7eff0..1c04767ed 100644 --- a/Sources/WireGuardApp/UI/macOS/View/ButtonRow.swift +++ b/Sources/WireGuardApp/UI/macOS/View/ButtonRow.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Cocoa diff --git a/Sources/WireGuardApp/UI/macOS/View/ConfTextColorTheme.swift b/Sources/WireGuardApp/UI/macOS/View/ConfTextColorTheme.swift index c77885b62..db1bcae78 100644 --- a/Sources/WireGuardApp/UI/macOS/View/ConfTextColorTheme.swift +++ b/Sources/WireGuardApp/UI/macOS/View/ConfTextColorTheme.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Cocoa diff --git a/Sources/WireGuardApp/UI/macOS/View/ConfTextStorage.swift b/Sources/WireGuardApp/UI/macOS/View/ConfTextStorage.swift index d050630e4..7aa1d91d8 100644 --- a/Sources/WireGuardApp/UI/macOS/View/ConfTextStorage.swift +++ b/Sources/WireGuardApp/UI/macOS/View/ConfTextStorage.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Cocoa diff --git a/Sources/WireGuardApp/UI/macOS/View/ConfTextView.swift b/Sources/WireGuardApp/UI/macOS/View/ConfTextView.swift index 50947d787..bef088507 100644 --- a/Sources/WireGuardApp/UI/macOS/View/ConfTextView.swift +++ b/Sources/WireGuardApp/UI/macOS/View/ConfTextView.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Cocoa diff --git a/Sources/WireGuardApp/UI/macOS/View/DeleteTunnelsConfirmationAlert.swift b/Sources/WireGuardApp/UI/macOS/View/DeleteTunnelsConfirmationAlert.swift index 6eb3fbe27..e5ffd3112 100644 --- a/Sources/WireGuardApp/UI/macOS/View/DeleteTunnelsConfirmationAlert.swift +++ b/Sources/WireGuardApp/UI/macOS/View/DeleteTunnelsConfirmationAlert.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Cocoa diff --git a/Sources/WireGuardApp/UI/macOS/View/KeyValueRow.swift b/Sources/WireGuardApp/UI/macOS/View/KeyValueRow.swift index b930e62a2..68c3e8273 100644 --- a/Sources/WireGuardApp/UI/macOS/View/KeyValueRow.swift +++ b/Sources/WireGuardApp/UI/macOS/View/KeyValueRow.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Cocoa diff --git a/Sources/WireGuardApp/UI/macOS/View/LogViewCell.swift b/Sources/WireGuardApp/UI/macOS/View/LogViewCell.swift index eef6515d8..1869c8176 100644 --- a/Sources/WireGuardApp/UI/macOS/View/LogViewCell.swift +++ b/Sources/WireGuardApp/UI/macOS/View/LogViewCell.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Cocoa diff --git a/Sources/WireGuardApp/UI/macOS/View/OnDemandWiFiControls.swift b/Sources/WireGuardApp/UI/macOS/View/OnDemandWiFiControls.swift index 790d1ac70..4630d7d93 100644 --- a/Sources/WireGuardApp/UI/macOS/View/OnDemandWiFiControls.swift +++ b/Sources/WireGuardApp/UI/macOS/View/OnDemandWiFiControls.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Cocoa import CoreWLAN diff --git a/Sources/WireGuardApp/UI/macOS/View/TunnelListRow.swift b/Sources/WireGuardApp/UI/macOS/View/TunnelListRow.swift index 8e426cda7..0b858a0dd 100644 --- a/Sources/WireGuardApp/UI/macOS/View/TunnelListRow.swift +++ b/Sources/WireGuardApp/UI/macOS/View/TunnelListRow.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Cocoa diff --git a/Sources/WireGuardApp/UI/macOS/ViewController/ButtonedDetailViewController.swift b/Sources/WireGuardApp/UI/macOS/ViewController/ButtonedDetailViewController.swift index 7fd59671d..7989bdabc 100644 --- a/Sources/WireGuardApp/UI/macOS/ViewController/ButtonedDetailViewController.swift +++ b/Sources/WireGuardApp/UI/macOS/ViewController/ButtonedDetailViewController.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Cocoa diff --git a/Sources/WireGuardApp/UI/macOS/ViewController/LogViewController.swift b/Sources/WireGuardApp/UI/macOS/ViewController/LogViewController.swift index ca4e5758d..986eaa305 100644 --- a/Sources/WireGuardApp/UI/macOS/ViewController/LogViewController.swift +++ b/Sources/WireGuardApp/UI/macOS/ViewController/LogViewController.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Cocoa diff --git a/Sources/WireGuardApp/UI/macOS/ViewController/ManageTunnelsRootViewController.swift b/Sources/WireGuardApp/UI/macOS/ViewController/ManageTunnelsRootViewController.swift index 28ffc9edd..1653ab84c 100644 --- a/Sources/WireGuardApp/UI/macOS/ViewController/ManageTunnelsRootViewController.swift +++ b/Sources/WireGuardApp/UI/macOS/ViewController/ManageTunnelsRootViewController.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Cocoa diff --git a/Sources/WireGuardApp/UI/macOS/ViewController/TunnelDetailTableViewController.swift b/Sources/WireGuardApp/UI/macOS/ViewController/TunnelDetailTableViewController.swift index 3757cf28d..0c44086ca 100644 --- a/Sources/WireGuardApp/UI/macOS/ViewController/TunnelDetailTableViewController.swift +++ b/Sources/WireGuardApp/UI/macOS/ViewController/TunnelDetailTableViewController.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Cocoa diff --git a/Sources/WireGuardApp/UI/macOS/ViewController/TunnelEditViewController.swift b/Sources/WireGuardApp/UI/macOS/ViewController/TunnelEditViewController.swift index a2f70916d..139b00e16 100644 --- a/Sources/WireGuardApp/UI/macOS/ViewController/TunnelEditViewController.swift +++ b/Sources/WireGuardApp/UI/macOS/ViewController/TunnelEditViewController.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Cocoa diff --git a/Sources/WireGuardApp/UI/macOS/ViewController/TunnelsListTableViewController.swift b/Sources/WireGuardApp/UI/macOS/ViewController/TunnelsListTableViewController.swift index 87f389e4e..265d3c343 100644 --- a/Sources/WireGuardApp/UI/macOS/ViewController/TunnelsListTableViewController.swift +++ b/Sources/WireGuardApp/UI/macOS/ViewController/TunnelsListTableViewController.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Cocoa diff --git a/Sources/WireGuardApp/UI/macOS/ViewController/UnusableTunnelDetailViewController.swift b/Sources/WireGuardApp/UI/macOS/ViewController/UnusableTunnelDetailViewController.swift index 7f68b49d2..cc7ab8cec 100644 --- a/Sources/WireGuardApp/UI/macOS/ViewController/UnusableTunnelDetailViewController.swift +++ b/Sources/WireGuardApp/UI/macOS/ViewController/UnusableTunnelDetailViewController.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Cocoa diff --git a/Sources/WireGuardApp/WireGuardAppError.swift b/Sources/WireGuardApp/WireGuardAppError.swift index f45662ab6..a461909d3 100644 --- a/Sources/WireGuardApp/WireGuardAppError.swift +++ b/Sources/WireGuardApp/WireGuardAppError.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. protocol WireGuardAppError: Error { typealias AlertText = (title: String, message: String) diff --git a/Sources/WireGuardApp/WireGuardResult.swift b/Sources/WireGuardApp/WireGuardResult.swift index ba194f10d..f6c9a4c12 100644 --- a/Sources/WireGuardApp/WireGuardResult.swift +++ b/Sources/WireGuardApp/WireGuardResult.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. enum WireGuardResult { case success(_ value: T) diff --git a/Sources/WireGuardApp/ZipArchive/ZipArchive.swift b/Sources/WireGuardApp/ZipArchive/ZipArchive.swift index be2549064..59063d0ff 100644 --- a/Sources/WireGuardApp/ZipArchive/ZipArchive.swift +++ b/Sources/WireGuardApp/ZipArchive/ZipArchive.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Foundation diff --git a/Sources/WireGuardApp/ZipArchive/ZipExporter.swift b/Sources/WireGuardApp/ZipArchive/ZipExporter.swift index 9ae912ebf..1e6496a4d 100644 --- a/Sources/WireGuardApp/ZipArchive/ZipExporter.swift +++ b/Sources/WireGuardApp/ZipArchive/ZipExporter.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Foundation diff --git a/Sources/WireGuardApp/ZipArchive/ZipImporter.swift b/Sources/WireGuardApp/ZipArchive/ZipImporter.swift index 73de1ad7f..9ea89e37d 100644 --- a/Sources/WireGuardApp/ZipArchive/ZipImporter.swift +++ b/Sources/WireGuardApp/ZipArchive/ZipImporter.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Foundation diff --git a/Sources/WireGuardApp/ca.lproj/Localizable.strings b/Sources/WireGuardApp/ca.lproj/Localizable.strings index 5f94f9776..827b7376b 100644 --- a/Sources/WireGuardApp/ca.lproj/Localizable.strings +++ b/Sources/WireGuardApp/ca.lproj/Localizable.strings @@ -235,6 +235,7 @@ "macMenuFile" = "File"; "tunnelStatusActivating" = "Activating"; "macToolTipToggleStatus" = "Toggle status (⌘T)"; +"macTunnelsMenuTitle" = "Tunnels"; "alertTunnelActivationSystemErrorTitle" = "Activation failure"; "alertInvalidInterfaceMessagePrivateKeyRequired" = "Interface’s private key is required"; "alertNoTunnelsToExportTitle" = "Nothing to export"; diff --git a/Sources/WireGuardApp/de.lproj/Localizable.strings b/Sources/WireGuardApp/de.lproj/Localizable.strings index 4573672cd..72d905014 100644 --- a/Sources/WireGuardApp/de.lproj/Localizable.strings +++ b/Sources/WireGuardApp/de.lproj/Localizable.strings @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. // Generic alert action names @@ -443,3 +443,4 @@ // Donation "donateLink" = "♥ Spende an das WireGuard Projekt"; +"macTunnelsMenuTitle" = "Tunnels"; diff --git a/Sources/WireGuardApp/es.lproj/Localizable.strings b/Sources/WireGuardApp/es.lproj/Localizable.strings index 9232f5575..9e0f49e2c 100644 --- a/Sources/WireGuardApp/es.lproj/Localizable.strings +++ b/Sources/WireGuardApp/es.lproj/Localizable.strings @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. // Generic alert action names @@ -80,7 +80,7 @@ "tunnelPeerPublicKey" = "Clave pública"; "tunnelPeerPreSharedKey" = "Clave precompartida"; "tunnelPeerEndpoint" = "Punto final"; -"tunnelPeerPersistentKeepalive" = "Mantenimiento persistente"; +"tunnelPeerPersistentKeepalive" = "Keepalive persistente"; "tunnelPeerAllowedIPs" = "IPs permitidas"; "tunnelPeerRxBytes" = "Datos recibidos"; "tunnelPeerTxBytes" = "Datos enviados"; @@ -177,142 +177,219 @@ "alertInvalidPeerMessagePreSharedKeyInvalid" = "La clave precompartida del par debe ser de 32 bytes en codificación base64"; "alertInvalidPeerMessageAllowedIPsInvalid" = "Las IPs permitidas del par deben ser una lista de direcciones IP separadas por comas, opcionalmente en notación CIDR"; "alertInvalidPeerMessageEndpointInvalid" = "El punto final del par debe ser de la forma ‘host:port’ o ‘[host]:port’"; -"alertInvalidPeerMessagePersistentKeepaliveInvalid" = "El keepalive persistente del par debe estar entre 0 y 65535, o no especificado"; +"alertInvalidPeerMessagePersistentKeepaliveInvalid" = "El keepalive persistente del peer debe estar entre 0 y 65535, o no especificado"; "alertInvalidPeerMessagePublicKeyDuplicated" = "Dos o mas pares no pueden tener la misma llave pùblica"; // Scanning QR code UI "scanQRCodeViewTitle" = "Escanear código QR"; +"scanQRCodeTipText" = "Consejo: generar con `qrencode -t ansiutf8 tunnel.conf`"; + +// Scanning QR code alerts + +"alertScanQRCodeCameraUnsupportedTitle" = "Cámara no soportada"; +"alertScanQRCodeCameraUnsupportedMessage" = "Este dispositivo no es capaz de escanear códigos QR"; + +"alertScanQRCodeInvalidQRCodeTitle" = "Código QR inválido"; +"alertScanQRCodeInvalidQRCodeMessage" = "El código QR escaneado no es una configuración válida de WireGuard"; + +"alertScanQRCodeUnreadableQRCodeTitle" = "Código inválido"; +"alertScanQRCodeUnreadableQRCodeMessage" = "El código escaneado no pudo ser leído"; + +"alertScanQRCodeNamePromptTitle" = "Por favor, nombra el túnel escaneado"; + +// Settings UI + +"settingsViewTitle" = "Configuración"; + +"settingsSectionTitleAbout" = "Acerca de"; +"settingsVersionKeyWireGuardForIOS" = "WireGuard para iOS"; + +"settingsSectionTitleExportConfigurations" = "Exportar configuraciones"; +"settingsExportZipButtonTitle" = "Exportar archivo zip"; + +"settingsSectionTitleTunnelLog" = "Registro"; +"settingsViewLogButtonTitle" = "Ver registro"; + +// Log view + +"logViewTitle" = "Registro"; // Log alerts "alertUnableToRemovePreviousLogTitle" = "Exportación de registros fallida"; +"alertUnableToRemovePreviousLogMessage" = "El registro preexistente no ha podido ser borrado"; + +"alertUnableToWriteLogTitle" = "Exportación de registros fallida"; +"alertUnableToWriteLogMessage" = "No se pudo escribir en el archivo de registros"; + +// Zip import / export error alerts + +"alertCantOpenInputZipFileTitle" = "No se pudo leer el archivo zip"; +"alertCantOpenInputZipFileMessage" = "El archivo zip no pudo ser leído."; + +"alertCantOpenOutputZipFileForWritingTitle" = "No se pudo crear el archivo zip"; +"alertCantOpenOutputZipFileForWritingMessage" = "No se pudo abrir el archivo zip para escribir."; + +"alertBadArchiveTitle" = "No se pudo leer el archivo zip"; +"alertBadArchiveMessage" = "Archivo zip erróneo o corrupto."; "alertNoTunnelsToExportTitle" = "Nada para exportar"; -"settingsSectionTitleAbout" = "About"; -"macMenuDeleteSelected" = "Delete Selected"; -"alertSystemErrorMessageTunnelConfigurationInvalid" = "The configuration is invalid."; +"alertNoTunnelsToExportMessage" = "No hay túneles para exportar"; + +"alertNoTunnelsInImportedZipArchiveTitle" = "No hay túneles en el archivo zip"; + +// Tunnel management error alerts + +"alertTunnelActivationFailureTitle" = "Fallo en la activación"; +"alertTunnelActivationFailureMessage" = "El túnel no pudo ser activado. Por favor, asegúrese de estar conectado a Internet."; +"alertTunnelActivationSavedConfigFailureMessage" = "No se ha podido recuperar la información del túnel de la configuración guardada."; + +"alertTunnelDNSFailureTitle" = "Fallo en resolución DNS"; +"alertSystemErrorOnAddTunnelTitle" = "No se pudo crear el túnel"; +"alertSystemErrorOnModifyTunnelTitle" = "No se pudo modificar el túnel"; +"alertSystemErrorOnRemoveTunnelTitle" = "No se pudo eliminar el túnel"; + +/* The alert message for this alert shall include + one of the alertSystemErrorMessage* listed further down */ +"alertTunnelActivationSystemErrorTitle" = "Fallo en la activación"; +"alertTunnelActivationSystemErrorMessage (%@)" = "No se pudo activar el túnel. %@"; + +/* alertSystemErrorMessage* messages */ +"alertSystemErrorMessageTunnelConfigurationInvalid" = "La configuración es inválida."; +"alertSystemErrorMessageTunnelConfigurationDisabled" = "La configuración está desactivada."; +"alertSystemErrorMessageTunnelConnectionFailed" = "La conexión ha fallado."; +"alertSystemErrorMessageTunnelConfigurationUnknown" = "Error desconocido de sistema."; + "macMenuTitle" = "WireGuard"; +"macMenuManageTunnels" = "Gestionar túneles"; +"macMenuImportTunnels" = "Importar túnel(es) desde archivo"; +"macMenuViewLog" = "Ver registro"; +"macMenuAbout" = "Acerca de WireGuard"; +"macMenuQuit" = "Salir de WireGuard"; + +"macMenuHideApp" = "Ocultar WireGuard"; +"macMenuShowAllApps" = "Mostrar todo"; + +"macMenuFile" = "Archivo"; +"macMenuCloseWindow" = "Cerrar Ventana"; + +"macMenuEdit" = "Editar"; +"macMenuCut" = "Cortar"; +"macMenuCopy" = "Copiar"; +"macMenuPaste" = "Pegar"; +"macMenuSelectAll" = "Seleccionar todo"; + +"macMenuTunnel" = "Túnel"; +"macMenuToggleStatus" = "Cambiar estado"; +"macMenuEditTunnel" = "Editar…"; +"macMenuDeleteSelected" = "Eliminar elementos seleccionados"; + +"macMenuWindow" = "Ventana"; +"macMenuMinimize" = "Minimizar"; + +// Mac manage tunnels window + +"macWindowTitleManageTunnels" = "Gestionar Túneles WireGuard"; + +"macDeleteTunnelConfirmationAlertMessage (%@)" = "¿Estás seguro que deseas eliminar \"%@\"?"; +"macDeleteMultipleTunnelsConfirmationAlertMessage (%d)" = "¿Está seguro que desea eliminar %d túneles?"; +"macDeleteTunnelConfirmationAlertInfo" = "No puedes deshacer esta acción."; +"macDeleteTunnelConfirmationAlertButtonTitleDelete" = "Eliminar"; +"macDeleteTunnelConfirmationAlertButtonTitleCancel" = "Cancelar"; +"macDeleteTunnelConfirmationAlertButtonTitleDeleting" = "Eliminando…"; + +"macButtonImportTunnels" = "Importar túnel(es) desde archivo"; +"macSheetButtonImport" = "Importar"; + +"macNameFieldExportLog" = "Guardar registro en:"; +"macSheetButtonExportLog" = "Guardar"; + +"macNameFieldExportZip" = "Exportar túneles a:"; +"macSheetButtonExportZip" = "Guardar"; + +"macButtonDeleteTunnels (%d)" = "Eliminar %d túneles"; + +"macButtonEdit" = "Editar"; +"macFieldOnDemand" = "Bajo demanda:"; +"macFieldOnDemandSSIDs" = "SSIDs:"; + +// Mac status display + +"macStatus (%@)" = "Estado: %@"; + +// Mac editing config + +"macEditDiscard" = "Descartar"; +"macEditSave" = "Guardar"; +"macAlertDNSInvalid (%@)" = "El DNS ‘%@’ no es válido."; + +"macAlertPublicKeyInvalid" = "La Clave pública no es válida"; +"macAlertPreSharedKeyInvalid" = "La clave compartida no es válida"; +"macAlertEndpointInvalid (%@)" = "Endpoint ‘%@’ no es válido"; +"macAlertPersistentKeepliveInvalid (%@)" = "El valor keepalive persistente '%@' no es válido"; +"macAlertInfoUnrecognizedPeerKey" = "Las claves válidas son: ‘PublicKey’, ‘PresharedKey’, ‘AllowedIPs’, ‘Endpoint’ y ‘PersistentKeepalive’"; +"macConfirmAndQuitAlertQuitWireGuard" = "Salir de WireGuard"; +"macConfirmAndQuitAlertCloseWindow" = "Cerrar Gestor de túneles"; + +// Mac tooltip + +"macToolTipEditTunnel" = "Editar túnel (⌘E)"; +"macToolTipToggleStatus" = "Cambiar estado (⌘T)"; + +// Mac log view + +"macLogColumnTitleTime" = "Tiempo"; +"macLogColumnTitleLogMessage" = "Mensaje de registro"; +"macLogButtonTitleClose" = "Cerrar"; +"macLogButtonTitleSave" = "Guardar…"; + +// Mac unusable tunnel view + +"macUnusableTunnelMessage" = "La configuración de este túnel no se encuentra en el llavero."; +"macUnusableTunnelButtonTitleDeleteTunnel" = "Eliminar túnel"; + +// Mac App Store updating alert + +"macAppStoreUpdatingAlertMessage" = "App Store desea actualizar WireGuard"; + +// Donation + +"donateLink" = "♥ Donar al Proyecto WireGuard"; "macAlertNoInterface" = "Configuration must have an ‘Interface’ section."; -"macNameFieldExportZip" = "Export tunnels to:"; -"alertSystemErrorMessageTunnelConfigurationUnknown" = "Unknown system error."; -"macMenuCut" = "Cut"; -"macEditDiscard" = "Discard"; -"alertScanQRCodeCameraUnsupportedMessage" = "This device is not able to scan QR codes"; -"macSheetButtonExportZip" = "Save"; -"macWindowTitleManageTunnels" = "Manage WireGuard Tunnels"; "macConfirmAndQuitAlertInfo" = "If you close the tunnels manager, WireGuard will continue to be available from the menu bar icon."; "macUnusableTunnelInfo" = "In case this tunnel was created by another user, only that user can view, edit, or activate this tunnel."; "alertTunnelActivationErrorTunnelIsNotInactiveMessage" = "The tunnel is already active or in the process of being activated"; "alertTunnelActivationSetNetworkSettingsMessage" = "Unable to apply network settings to tunnel object."; "macMenuExportTunnels" = "Export Tunnels to Zip…"; -"macMenuShowAllApps" = "Show All"; "alertCantOpenInputConfFileTitle" = "Unable to import from file"; -"alertScanQRCodeInvalidQRCodeMessage" = "The scanned QR code is not a valid WireGuard configuration"; -"macMenuHideApp" = "Hide WireGuard"; -"settingsViewTitle" = "Settings"; -"macDeleteTunnelConfirmationAlertInfo" = "You cannot undo this action."; -"macDeleteTunnelConfirmationAlertButtonTitleDeleting" = "Deleting…"; -"settingsViewLogButtonTitle" = "View log"; -"alertSystemErrorMessageTunnelConnectionFailed" = "The connection failed."; -"macButtonEdit" = "Edit"; -"macAlertPublicKeyInvalid" = "Public key is invalid"; -"macNameFieldExportLog" = "Save log to:"; -"alertSystemErrorOnAddTunnelTitle" = "Unable to create tunnel"; "macConfirmAndQuitAlertMessage" = "Do you want to close the tunnels manager or quit WireGuard entirely?"; -"alertTunnelActivationSavedConfigFailureMessage" = "Unable to retrieve tunnel information from the saved configuration."; "macAlertInfoUnrecognizedInterfaceKey" = "Valid keys are: ‘PrivateKey’, ‘ListenPort’, ‘Address’, ‘DNS’ and ‘MTU’."; -"macLogColumnTitleTime" = "Time"; "alertTunnelNameEmptyMessage" = "Cannot create tunnel with an empty name"; "alertTunnelNameEmptyTitle" = "No name provided"; -"alertUnableToWriteLogMessage" = "Unable to write logs to file"; -"macMenuQuit" = "Quit WireGuard"; "macMenuAddEmptyTunnel" = "Add Empty Tunnel…"; -"macDeleteTunnelConfirmationAlertButtonTitleDelete" = "Delete"; "alertTunnelActivationFailureOnDemandAddendum" = " This tunnel has Activate On Demand enabled, so this tunnel might be re-activated automatically by the OS. You may turn off Activate On Demand in this app by editing the tunnel configuration."; -"alertTunnelActivationFailureTitle" = "Activation failure"; -"macLogButtonTitleClose" = "Close"; -"settingsExportZipButtonTitle" = "Export zip archive"; "macViewPrivateData" = "view tunnel private keys"; "alertTunnelActivationErrorTunnelIsNotInactiveTitle" = "Activation in progress"; "macAppExitingWithActiveTunnelInfo" = "The tunnel will remain active after exiting. You may disable it by reopening this application or through the Network panel in System Preferences."; -"macMenuEdit" = "Edit"; -"donateLink" = "♥ Donate to the WireGuard Project"; -"alertScanQRCodeCameraUnsupportedTitle" = "Camera Unsupported"; -"macMenuWindow" = "Window"; -"alertTunnelActivationFailureMessage" = "The tunnel could not be activated. Please ensure that you are connected to the Internet."; "macMenuHideOtherApps" = "Hide Others"; -"alertCantOpenInputZipFileMessage" = "The zip archive could not be read."; "macAlertPrivateKeyInvalid" = "Private key is invalid."; -"macDeleteTunnelConfirmationAlertButtonTitleCancel" = "Cancel"; -"alertSystemErrorMessageTunnelConfigurationDisabled" = "The configuration is disabled."; -"alertUnableToWriteLogTitle" = "Log export failed"; "macMenuNetworksNone" = "Networks: None"; -"alertCantOpenOutputZipFileForWritingMessage" = "Could not open zip file for writing."; -"macMenuSelectAll" = "Select All"; -"logViewTitle" = "Log"; -"macConfirmAndQuitAlertQuitWireGuard" = "Quit WireGuard"; -"alertSystemErrorOnRemoveTunnelTitle" = "Unable to remove tunnel"; -"macFieldOnDemand" = "On-Demand:"; -"macMenuCloseWindow" = "Close Window"; -"macSheetButtonExportLog" = "Save"; -"alertSystemErrorOnModifyTunnelTitle" = "Unable to modify tunnel"; "alertSystemErrorMessageTunnelConfigurationReadWriteFailed" = "Reading or writing the configuration failed."; -"macMenuEditTunnel" = "Edit…"; -"settingsSectionTitleTunnelLog" = "Log"; -"macMenuManageTunnels" = "Manage Tunnels"; -"macButtonImportTunnels" = "Import tunnel(s) from file"; "macAppExitingWithActiveTunnelMessage" = "WireGuard is exiting with an active tunnel"; "alertSystemErrorMessageTunnelConfigurationStale" = "The configuration is stale."; "alertTunnelDNSFailureMessage" = "One or more endpoint domains could not be resolved."; -"alertNoTunnelsInImportedZipArchiveTitle" = "No tunnels in zip archive"; -"alertTunnelDNSFailureTitle" = "DNS resolution failure"; -"macLogButtonTitleSave" = "Save…"; -"macMenuToggleStatus" = "Toggle Status"; -"macMenuMinimize" = "Minimize"; -"alertCantOpenInputZipFileTitle" = "Unable to read zip archive"; -"alertScanQRCodeUnreadableQRCodeMessage" = "The scanned code could not be read"; -"alertScanQRCodeUnreadableQRCodeTitle" = "Invalid Code"; "alertSystemErrorOnListingTunnelsTitle" = "Unable to list tunnels"; -"settingsVersionKeyWireGuardForIOS" = "WireGuard for iOS"; -"macMenuPaste" = "Paste"; "macAlertMultipleInterfaces" = "Configuration must have only one ‘Interface’ section."; -"macAppStoreUpdatingAlertMessage" = "App Store would like to update WireGuard"; -"macUnusableTunnelMessage" = "The configuration for this tunnel cannot be found in the keychain."; -"macToolTipEditTunnel" = "Edit tunnel (⌘E)"; "macMenuZoom" = "Zoom"; -"alertBadArchiveTitle" = "Unable to read zip archive"; "macExportPrivateData" = "export tunnel private keys"; "alertTunnelAlreadyExistsWithThatNameTitle" = "Name already exists"; "iosViewPrivateData" = "Authenticate to view tunnel private keys."; -"macAlertPreSharedKeyInvalid" = "Preshared key is invalid"; -"macEditSave" = "Save"; -"macConfirmAndQuitAlertCloseWindow" = "Close Tunnels Manager"; -"macMenuFile" = "File"; -"macToolTipToggleStatus" = "Toggle status (⌘T)"; -"alertTunnelActivationSystemErrorTitle" = "Activation failure"; -"scanQRCodeTipText" = "Tip: Generate with `qrencode -t ansiutf8 < tunnel.conf`"; -"alertNoTunnelsToExportMessage" = "There are no tunnels to export"; -"macMenuImportTunnels" = "Import Tunnel(s) from File…"; -"alertScanQRCodeInvalidQRCodeTitle" = "Invalid QR Code"; -"macMenuViewLog" = "View Log"; -"macAlertInfoUnrecognizedPeerKey" = "Valid keys are: ‘PublicKey’, ‘PresharedKey’, ‘AllowedIPs’, ‘Endpoint’ and ‘PersistentKeepalive’"; -"macUnusableTunnelButtonTitleDeleteTunnel" = "Delete tunnel"; -"macMenuTunnel" = "Tunnel"; -"macMenuCopy" = "Copy"; +"macTunnelsMenuTitle" = "Tunnels"; "alertTunnelAlreadyExistsWithThatNameMessage" = "A tunnel with that name already exists"; -"macLogColumnTitleLogMessage" = "Log message"; "iosExportPrivateData" = "Authenticate to export tunnel private keys."; -"macMenuAbout" = "About WireGuard"; -"macSheetButtonImport" = "Import"; -"alertScanQRCodeNamePromptTitle" = "Please name the scanned tunnel"; -"alertUnableToRemovePreviousLogMessage" = "The pre-existing log could not be cleared"; "alertTunnelActivationBackendFailureMessage" = "Unable to turn on Go backend library."; -"settingsSectionTitleExportConfigurations" = "Export configurations"; -"alertBadArchiveMessage" = "Bad or corrupt zip archive."; "settingsVersionKeyWireGuardGoBackend" = "WireGuard Go Backend"; -"macFieldOnDemandSSIDs" = "SSIDs:"; -"alertCantOpenOutputZipFileForWritingTitle" = "Unable to create zip archive"; "alertNoTunnelsInImportedZipArchiveMessage" = "No .conf tunnel files were found inside the zip archive."; "alertTunnelActivationFileDescriptorFailureMessage" = "Unable to determine TUN device file descriptor."; "macAlertNameIsEmpty" = "Name is required"; diff --git a/Sources/WireGuardApp/fa.lproj/Localizable.strings b/Sources/WireGuardApp/fa.lproj/Localizable.strings index 4cfd32739..71937a8b6 100644 --- a/Sources/WireGuardApp/fa.lproj/Localizable.strings +++ b/Sources/WireGuardApp/fa.lproj/Localizable.strings @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. // Generic alert action names @@ -389,6 +389,7 @@ "macUnusableTunnelMessage" = "The configuration for this tunnel cannot be found in the keychain."; "iosViewPrivateData" = "Authenticate to view tunnel private keys."; "macToolTipToggleStatus" = "Toggle status (⌘T)"; +"macTunnelsMenuTitle" = "Tunnels"; "scanQRCodeTipText" = "Tip: Generate with `qrencode -t ansiutf8 < tunnel.conf`"; "macAlertInfoUnrecognizedPeerKey" = "Valid keys are: ‘PublicKey’, ‘PresharedKey’, ‘AllowedIPs’, ‘Endpoint’ and ‘PersistentKeepalive’"; "alertInvalidPeerMessageAllowedIPsInvalid" = "Peer’s allowed IPs must be a list of comma-separated IP addresses, optionally in CIDR notation"; diff --git a/Sources/WireGuardApp/fi.lproj/Localizable.strings b/Sources/WireGuardApp/fi.lproj/Localizable.strings index 9333f681e..f3a94675e 100644 --- a/Sources/WireGuardApp/fi.lproj/Localizable.strings +++ b/Sources/WireGuardApp/fi.lproj/Localizable.strings @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. // Generic alert action names @@ -12,20 +12,103 @@ "tunnelsListTitle" = "WireGuard"; "tunnelsListSettingsButtonTitle" = "Asetukset"; "tunnelsListCenteredAddTunnelButtonTitle" = "Lisää tunneli"; +"tunnelsListSwipeDeleteButtonTitle" = "Poista"; +"tunnelsListSelectButtonTitle" = "Valitse"; +"tunnelsListSelectAllButtonTitle" = "Valitse kaikki"; +"tunnelsListDeleteButtonTitle" = "Poista"; +"tunnelsListSelectedTitle (%d)" = "%d poistettu"; + +// Tunnels list menu + +"addTunnelMenuHeader" = "Lisää uusi WireGuard tunneli"; +"addTunnelMenuImportFile" = "Luo tiedostosta tai arkistosta"; +"addTunnelMenuQRCode" = "Luo QR-koodista"; +"addTunnelMenuFromScratch" = "Luo alusta"; + +// Tunnels list alerts + +"alertImportedFromMultipleFilesTitle (%d)" = "Luotu %d tunnelia"; +"alertImportedFromMultipleFilesMessage (%1$d of %2$d)" = "Luotu %1$d / %2$d tunnelia tuoduista tiedostoista"; + +"alertImportedFromZipTitle (%d)" = "Luotu %d tunnelia"; +"alertImportedFromZipMessage (%1$d of %2$d)" = "Luotu %1$d / %2$d tunnelia zip-arkistosta"; + +"alertBadConfigImportTitle" = "Tunnelia ei voitu tuoda"; +"alertBadConfigImportMessage (%@)" = "Tiedosto ”%@” ei sisällä kelvollista WireGuard konfiguraatiota"; + +"deleteTunnelsConfirmationAlertButtonTitle" = "Poista"; +"deleteTunnelConfirmationAlertButtonMessage (%d)" = "Poista %d tunneli?"; +"deleteTunnelsConfirmationAlertButtonMessage (%d)" = "Poista %d tunnelit?"; + +// Tunnel detail and edit UI + +"newTunnelViewTitle" = "Uusi konfiguraatio"; +"editTunnelViewTitle" = "Muokkaa konfiguraatiota"; + +"tunnelSectionTitleStatus" = "Tila"; + +"tunnelStatusInactive" = "Ei aktiivinen"; +"tunnelStatusActivating" = "Aktivoidaan"; +"tunnelStatusActive" = "Aktiivinen"; +"tunnelStatusDeactivating" = "Deaktivoidaan"; +"tunnelStatusReasserting" = "Aktivoidaan uudelleen"; +"tunnelStatusRestarting" = "Käynnistetään uudelleen"; +"tunnelStatusWaiting" = "Odotetaan"; + +"macToggleStatusButtonActivate" = "Aktivoi"; +"macToggleStatusButtonActivating" = "Aktivoidaan…"; +"macToggleStatusButtonDeactivate" = "Deaktivoi"; +"macToggleStatusButtonDeactivating" = "Deaktivoidaan…"; +"macToggleStatusButtonReasserting" = "Aktivoidaan uudelleen…"; +"macToggleStatusButtonRestarting" = "Käynnistetään uudelleen…"; +"macToggleStatusButtonWaiting" = "Odotetaan…"; + +"tunnelSectionTitleInterface" = "Liittymä"; "tunnelInterfaceName" = "Nimi"; "tunnelInterfacePrivateKey" = "Yksityinen avain"; "tunnelInterfacePublicKey" = "Julkinen avain"; "tunnelInterfaceGenerateKeypair" = "Luo avainpari"; "tunnelInterfaceAddresses" = "Osoitteet"; +"tunnelInterfaceListenPort" = "Kuuntele porttia"; +"tunnelInterfaceMTU" = "MTU"; +"tunnelInterfaceDNS" = "DNS palvelimet"; +"tunnelInterfaceStatus" = "Tila"; + +"tunnelSectionTitlePeer" = "Osapuoli"; "tunnelPeerPublicKey" = "Julkinen avain"; +"tunnelPeerPreSharedKey" = "Jaettu avain"; +"tunnelPeerEndpoint" = "Päätepiste"; +"tunnelPeerPersistentKeepalive" = "Jatkuva keepalive"; +"tunnelPeerAllowedIPs" = "Sallitut IP-osoitteet"; +"tunnelPeerRxBytes" = "Data vastaanotettu"; +"tunnelPeerTxBytes" = "Data lähetetty"; +"tunnelPeerLastHandshakeTime" = "Viimeisin kättely"; +"tunnelPeerExcludePrivateIPs" = "Jätä pois yksityiset IP-osoitteet"; + +"tunnelSectionTitleOnDemand" = "Automaattinen käyttöönotto"; + +"tunnelOnDemandCellular" = "Matkapuhelinverkko"; +"tunnelOnDemandEthernet" = "Ethernet"; "tunnelOnDemandWiFi" = "Wi-Fi"; "tunnelOnDemandSSIDsKey" = "SSID:t"; "tunnelOnDemandAnySSID" = "Mikä tahansa SSID"; "tunnelOnDemandOnlyTheseSSIDs" = "Vain nämä SSID:t"; "tunnelOnDemandExceptTheseSSIDs" = "Poislukien SSID:t"; +"tunnelOnDemandOnlySSID (%d)" = "Vain %d SSID"; +"tunnelOnDemandOnlySSIDs (%d)" = "Vain %d SSID:t"; +"tunnelOnDemandExceptSSID (%d)" = "Kaikki paitsi %d SSID"; +"tunnelOnDemandExceptSSIDs (%d)" = "Kaikki paitsi %d SSID:t"; +"tunnelOnDemandSSIDOptionDescriptionMac (%1$@: %2$@)" = "%1$@: %2$@"; + +"tunnelOnDemandSSIDViewTitle" = "SSID:t"; +"tunnelOnDemandSectionTitleSelectedSSIDs" = "SSID:t"; +"tunnelOnDemandNoSSIDs" = "Ei SSID-tietoja"; +"tunnelOnDemandSectionTitleAddSSIDs" = "Lisää SSID-tietoja"; +"tunnelOnDemandAddMessageAddConnectedSSID (%@)" = "Lisää yhdistetty: %@"; +"tunnelOnDemandAddMessageAddNewSSID" = "Lisää uusi"; "tunnelOnDemandKey" = "Tarvittaessa"; "tunnelOnDemandOptionOff" = "Pois päältä"; @@ -35,6 +118,12 @@ "tunnelOnDemandOptionWiFiOrEthernet" = "Wi-Fi tai Ethernet"; "tunnelOnDemandOptionEthernetOnly" = "Vain Ethernet"; +"addPeerButtonTitle" = "Lisää toinen osapuoli"; + +"deletePeerButtonTitle" = "Poista osapuoli"; +"deletePeerConfirmationAlertButtonTitle" = "Poista"; +"deletePeerConfirmationAlertMessage" = "Poistetaanko tämä osapuoli?"; + "deleteTunnelButtonTitle" = "Poista tunneli"; "deleteTunnelConfirmationAlertButtonTitle" = "Poista"; "deleteTunnelConfirmationAlertMessage" = "Poistetaanko tämä tunneli?"; @@ -42,207 +131,273 @@ "tunnelEditPlaceholderTextRequired" = "Pakollinen"; "tunnelEditPlaceholderTextOptional" = "Valinnainen"; "tunnelEditPlaceholderTextAutomatic" = "Automaattinen"; +"tunnelEditPlaceholderTextStronglyRecommended" = "Erittäin suositeltavaa"; "tunnelEditPlaceholderTextOff" = "Pois päältä"; + +"tunnelPeerPersistentKeepaliveValue (%@)" = "joka %@ sekuntin välein"; "tunnelHandshakeTimestampNow" = "Nyt"; -"settingsSectionTitleAbout" = "About"; -"newTunnelViewTitle" = "New configuration"; -"macMenuDeleteSelected" = "Delete Selected"; -"alertSystemErrorMessageTunnelConfigurationInvalid" = "The configuration is invalid."; -"tunnelInterfaceDNS" = "DNS servers"; -"tunnelPeerEndpoint" = "Endpoint"; -"tunnelInterfaceMTU" = "MTU"; -"alertInvalidInterfaceMessageListenPortInvalid" = "Interface’s listen port must be between 0 and 65535, or unspecified"; -"addPeerButtonTitle" = "Add peer"; -"tunnelHandshakeTimestampSystemClockBackward" = "(System clock wound backwards)"; -"tunnelsListSwipeDeleteButtonTitle" = "Delete"; +"tunnelHandshakeTimestampSystemClockBackward" = "(Järjestelmän kello jättää)"; +"tunnelHandshakeTimestampAgo (%@)" = "%@ sitten"; +"tunnelHandshakeTimestampYear (%d)" = "%d vuosi"; +"tunnelHandshakeTimestampYears (%d)" = "%d vuotta"; +"tunnelHandshakeTimestampDay (%d)" = "%d päivä"; +"tunnelHandshakeTimestampDays (%d)" = "%d päivää"; +"tunnelHandshakeTimestampHour (%d)" = "%d tunti"; +"tunnelHandshakeTimestampHours (%d)" = "%d tuntia"; +"tunnelHandshakeTimestampMinute (%d)" = "%d minuutti"; +"tunnelHandshakeTimestampMinutes (%d)" = "%d minuuttia"; +"tunnelHandshakeTimestampSecond (%d)" = "%d sekunti"; +"tunnelHandshakeTimestampSeconds (%d)" = "%d sekuntia"; + +"tunnelHandshakeTimestampHours hh:mm:ss (%@)" = "%@ tuntia"; +"tunnelHandshakeTimestampMinutes mm:ss (%@)" = "%@ minuuttia"; + +"tunnelPeerPresharedKeyEnabled" = "käytössä"; + +// Error alerts while creating / editing a tunnel configuration +/* Alert title for error in the interface data */ + +"alertInvalidInterfaceTitle" = "Virheellinen liittymä"; + +/* Any one of the following alert messages can go with the above title */ +"alertInvalidInterfaceMessageNameRequired" = "Sovittimen nimi vaadittu"; +"alertInvalidInterfaceMessagePrivateKeyRequired" = "Sovittimen yksityinen avain on vaadittu"; +"alertInvalidInterfaceMessagePrivateKeyInvalid" = "Sovittimen yksityinen avain on oltava 32-tavuinen avain base64 enkoodauksella"; +"alertInvalidInterfaceMessageAddressInvalid" = "Sovittimen osoitteet on oltava pilkulla erotettujen IP-osoitteiden luettelo, valinnaisesti CIDR-notaatiossa"; +"alertInvalidInterfaceMessageListenPortInvalid" = "Sovittimen kuunteluportin on tulee olla väliltä 0 - 65535, tai sen on oltava määrittelemätön"; +"alertInvalidInterfaceMessageMTUInvalid" = "Sovittimen MTU on oltava väliltä 576 - 65535, tai sen on oltava määrittelemätön"; +"alertInvalidInterfaceMessageDNSInvalid" = "Sovittimen DNS-palvelimien on oltava lista pilkulla erotettu IP-osoitteita"; + +/* Alert title for error in the peer data */ +"alertInvalidPeerTitle" = "Virheellinen osapuoli"; + +/* Any one of the following alert messages can go with the above title */ +"alertInvalidPeerMessagePublicKeyRequired" = "Osapuolen julkinen avain on vaadittu"; +"alertInvalidPeerMessagePublicKeyInvalid" = "Osapuolen julkinen avain on oltava 32-tavuinen avain base64 -enkoodauksella"; +"alertInvalidPeerMessagePreSharedKeyInvalid" = "Osapuolen jaettu avain on oltava 32-tavuinen avain base64 -enkoodauksella"; +"alertInvalidPeerMessageAllowedIPsInvalid" = "Toisen osapuolen sallittujen IP-osoitteiden on oltava pilkulla erotettujen IP-osoitteiden luettelo, valinnaisesti CIDR-notaatiossa"; +"alertInvalidPeerMessageEndpointInvalid" = "Käyttäjän päätepisteen on oltava muotoa ”host:port” tai ”[host]:port”"; +"alertInvalidPeerMessagePersistentKeepaliveInvalid" = "Käyttäjän pysyvän keepalivin on oltava välillä 0–65535 tai määrittelemätön"; +"alertInvalidPeerMessagePublicKeyDuplicated" = "Kahdella tai useammalla osapuolella ei voi olla samaa julkista avainta"; + +// Scanning QR code UI + +"scanQRCodeViewTitle" = "Skannaa QR-koodi"; +"scanQRCodeTipText" = "Vihje: Luo käyttämällä `qrencode -t ansiutf8 < tunnel.conf`"; + +// Scanning QR code alerts + +"alertScanQRCodeCameraUnsupportedTitle" = "Kameraa ei tuettu"; +"alertScanQRCodeCameraUnsupportedMessage" = "Tämä laite ei pysty skannaamaan QR-koodeja"; + +"alertScanQRCodeInvalidQRCodeTitle" = "Virheellinen QR-koodi"; + +"alertScanQRCodeUnreadableQRCodeTitle" = "Virheellinen koodi"; + +// Settings UI + +"settingsViewTitle" = "Asetukset"; + +"settingsSectionTitleAbout" = "Tietoa"; +"settingsVersionKeyWireGuardForIOS" = "WireGuard iOS:lle"; +"settingsVersionKeyWireGuardGoBackend" = "WireGuard Go -moottori"; + +"settingsSectionTitleTunnelLog" = "Loki"; +"settingsViewLogButtonTitle" = "Näytä loki"; + +// Log view + +"logViewTitle" = "Loki"; +"alertBadArchiveMessage" = "Huono tai korruptoitunut zip arkisto."; + +"alertNoTunnelsToExportTitle" = "Ei mitään vietävää"; +"alertNoTunnelsToExportMessage" = "Vietäviä tunneleita ei ole"; + +"alertNoTunnelsInImportedZipArchiveTitle" = "Zip arkistossa ei ole tunneleita"; + +// Tunnel management error alerts + +"alertTunnelActivationFailureTitle" = "Aktivointi epäonnistui"; + +"alertTunnelNameEmptyTitle" = "Nimeä ei annettu lainkaan"; + +"alertTunnelAlreadyExistsWithThatNameTitle" = "Nimi on jo käytössä"; + +"alertTunnelActivationErrorTunnelIsNotInactiveTitle" = "Aktivointi käynnissä"; + +// Tunnel management error alerts on system error +/* The alert message that goes with the following titles would be + one of the alertSystemErrorMessage* listed further down */ + +"alertSystemErrorOnListingTunnelsTitle" = "Tunneleita ei voitu listata"; +"alertSystemErrorOnAddTunnelTitle" = "Tunnelia ei voitu luoda"; + +/* The alert message for this alert shall include + one of the alertSystemErrorMessage* listed further down */ +"alertTunnelActivationSystemErrorTitle" = "Aktivointi epäonnistui"; + +/* alertSystemErrorMessage* messages */ +"alertSystemErrorMessageTunnelConfigurationInvalid" = "Konfiguraatio ei kelpaa."; +"alertSystemErrorMessageTunnelConnectionFailed" = "Yhteys epäonnistui."; +"alertSystemErrorMessageTunnelConfigurationReadWriteFailed" = "Konfiguraation lukeminen tai kirjoittaminen epäonnistui."; +"alertSystemErrorMessageTunnelConfigurationUnknown" = "Tuntematon järjestelmävirhe."; + +// Mac status bar menu / pulldown menu / main menu + +"macMenuNetworks (%@)" = "Verkot: %@"; +"macMenuNetworksNone" = "Verkot: Ei mitään"; + "macMenuTitle" = "WireGuard"; +"macMenuManageTunnels" = "Hallitse tunneleita"; +"macMenuImportTunnels" = "Tuo tunneli(t) tiedostosta…"; +"macMenuAddEmptyTunnel" = "Lisää tyhjä tunneli…"; +"macMenuViewLog" = "Näytä loki"; +"macMenuExportTunnels" = "Vie tunnelit Zippinä…"; +"macMenuAbout" = "Tietoa WireGuardista"; +"macMenuQuit" = "Sulje WireGuard"; + +"macMenuHideApp" = "Piilota WireGuard"; +"macMenuHideOtherApps" = "Piilota muut"; +"macMenuShowAllApps" = "Näytä kaikki"; + +"macMenuFile" = "Tiedosto"; +"macMenuCloseWindow" = "Sulje ikkuna"; + +"macMenuEdit" = "Muokkaa"; +"macMenuCut" = "Leikkaa"; +"macMenuCopy" = "Kopioi"; +"macMenuPaste" = "Liitä"; +"macMenuSelectAll" = "Valitse kaikki"; + +"macMenuTunnel" = "Tunneli"; +"macMenuToggleStatus" = "Vaihda tilaa"; +"macMenuEditTunnel" = "Muokkaa…"; +"macMenuDeleteSelected" = "Poista valitut"; + +"macMenuWindow" = "Ikkuna"; +"macMenuMinimize" = "Pienennä"; +"macMenuZoom" = "Lähennä/Loitonna"; + +// Mac manage tunnels window + +"macWindowTitleManageTunnels" = "Hallitse WireGuard tunneleita"; + +"macDeleteTunnelConfirmationAlertMessage (%@)" = "Oletko varma, että haluat poistaa \"%@\"?"; +"macDeleteMultipleTunnelsConfirmationAlertMessage (%d)" = "Haluatko varmasti poistaa %d kohdetta?"; +"macDeleteTunnelConfirmationAlertInfo" = "Tätä toimintoa ei voi peruuttaa."; +"macDeleteTunnelConfirmationAlertButtonTitleDelete" = "Poista"; +"macDeleteTunnelConfirmationAlertButtonTitleCancel" = "Peruuta"; +"macDeleteTunnelConfirmationAlertButtonTitleDeleting" = "Poistetaan…"; + +"macButtonImportTunnels" = "Tuo tunneli(t) tiedostosta"; +"macSheetButtonImport" = "Tuo"; + +"macNameFieldExportLog" = "Tallenna loki kohteeseen:"; +"macSheetButtonExportLog" = "Tallenna"; + +"macNameFieldExportZip" = "Vie tunnelit kohteeseen:"; +"macSheetButtonExportZip" = "Tallenna"; + +"macButtonDeleteTunnels (%d)" = "Poista %d tunnelia"; + +"macButtonEdit" = "Muokkaa"; +"macFieldOnDemand" = "Tarvittaessa:"; +"macFieldOnDemandSSIDs" = "SSIDt:"; + +// Mac status display + +"macStatus (%@)" = "Tila: %@"; + +// Mac editing config + +"macEditDiscard" = "Hylkää"; +"macEditSave" = "Tallenna"; + +"macAlertNameIsEmpty" = "Nimi on pakollinen"; +"macAlertPrivateKeyInvalid" = "Yksityinen avain ei kelpaa."; +"macAlertListenPortInvalid (%@)" = "Portti \"%@\" ei kelpaa."; +"macAlertAddressInvalid (%@)" = "Osoite \"%@\" ei kelpaa."; +"macAlertDNSInvalid (%@)" = "DNS ‘%@’ ei kelpaa."; +"macAlertMTUInvalid (%@)" = "MTU ‘%@’ ei kelpaa."; + +"macAlertPublicKeyInvalid" = "Julkinen avain ei kelpaa"; +"macAlertPreSharedKeyInvalid" = "Jaettu avain ei kelpaa"; +"macAlertAllowedIPInvalid (%@)" = "Sallitut IP-osoitteet %@\" eivät kelpaa"; +"macAlertEndpointInvalid (%@)" = "Päätepiste \"%@\" ei kelpaa"; +"macAlertPersistentKeepliveInvalid (%@)" = "Pysyvä keepalive arvo ‘%@’ ei kelpaa"; + +"macAlertUnrecognizedPeerKey (%@)" = "Osapuoli sisältää tunnistamattoman avaimen ”%@”"; +"macAlertInfoUnrecognizedPeerKey" = "Voimassa olevat avaimet ovat: ”PublicKey”, ”PresharedKey”, ”AllowedIPs”, ”Endpoint” ja ”PersistentKeepalive”"; + +// Mac about dialog + +"macAppVersion (%@)" = "Sovelluksen versio: %@"; +"macGoBackendVersion (%@)" = "Go -moottorin versio: %@"; +"iosViewPrivateData" = "Todenna nähdäksesi tunnelin yksityiset avaimet."; +"macConfirmAndQuitAlertQuitWireGuard" = "Sulje WireGuard"; +"macConfirmAndQuitAlertCloseWindow" = "Sulje tunneleiden hallinta"; + +// Mac tooltip + +"macToolTipEditTunnel" = "Muokkaa tunnelia (⌘E)"; + +// Mac log view + +"macLogColumnTitleTime" = "Aika"; +"macLogColumnTitleLogMessage" = "Lokiviesti"; +"macLogButtonTitleClose" = "Sulje"; +"macLogButtonTitleSave" = "Tallenna…"; +"macUnusableTunnelButtonTitleDeleteTunnel" = "Poista tunneli"; + +// Mac App Store updating alert + +"macAppStoreUpdatingAlertMessage" = "App Store haluaa päivittää WireGuardin"; + +// Donation + +"donateLink" = "♥ Lahjoita WireGuard projektille"; "macAlertNoInterface" = "Configuration must have an ‘Interface’ section."; -"macNameFieldExportZip" = "Export tunnels to:"; -"editTunnelViewTitle" = "Edit configuration"; -"alertSystemErrorMessageTunnelConfigurationUnknown" = "Unknown system error."; -"macMenuCut" = "Cut"; -"macEditDiscard" = "Discard"; -"tunnelPeerPresharedKeyEnabled" = "enabled"; -"alertScanQRCodeCameraUnsupportedMessage" = "This device is not able to scan QR codes"; -"macSheetButtonExportZip" = "Save"; -"macWindowTitleManageTunnels" = "Manage WireGuard Tunnels"; "macConfirmAndQuitAlertInfo" = "If you close the tunnels manager, WireGuard will continue to be available from the menu bar icon."; "macUnusableTunnelInfo" = "In case this tunnel was created by another user, only that user can view, edit, or activate this tunnel."; "alertTunnelActivationErrorTunnelIsNotInactiveMessage" = "The tunnel is already active or in the process of being activated"; -"macToggleStatusButtonReasserting" = "Reactivating…"; "alertTunnelActivationSetNetworkSettingsMessage" = "Unable to apply network settings to tunnel object."; -"macMenuExportTunnels" = "Export Tunnels to Zip…"; -"macMenuShowAllApps" = "Show All"; "alertCantOpenInputConfFileTitle" = "Unable to import from file"; "alertScanQRCodeInvalidQRCodeMessage" = "The scanned QR code is not a valid WireGuard configuration"; -"macMenuHideApp" = "Hide WireGuard"; -"settingsViewTitle" = "Settings"; -"tunnelsListSelectAllButtonTitle" = "Select All"; -"macDeleteTunnelConfirmationAlertInfo" = "You cannot undo this action."; -"macDeleteTunnelConfirmationAlertButtonTitleDeleting" = "Deleting…"; -"tunnelPeerPersistentKeepalive" = "Persistent keepalive"; -"settingsViewLogButtonTitle" = "View log"; -"alertSystemErrorMessageTunnelConnectionFailed" = "The connection failed."; -"macButtonEdit" = "Edit"; -"macAlertPublicKeyInvalid" = "Public key is invalid"; -"macNameFieldExportLog" = "Save log to:"; -"alertSystemErrorOnAddTunnelTitle" = "Unable to create tunnel"; "macConfirmAndQuitAlertMessage" = "Do you want to close the tunnels manager or quit WireGuard entirely?"; "alertTunnelActivationSavedConfigFailureMessage" = "Unable to retrieve tunnel information from the saved configuration."; -"tunnelOnDemandSectionTitleSelectedSSIDs" = "SSIDs"; "macAlertInfoUnrecognizedInterfaceKey" = "Valid keys are: ‘PrivateKey’, ‘ListenPort’, ‘Address’, ‘DNS’ and ‘MTU’."; -"macLogColumnTitleTime" = "Time"; "alertTunnelNameEmptyMessage" = "Cannot create tunnel with an empty name"; -"alertInvalidInterfaceMessageMTUInvalid" = "Interface’s MTU must be between 576 and 65535, or unspecified"; -"alertTunnelNameEmptyTitle" = "No name provided"; -"macToggleStatusButtonRestarting" = "Restarting…"; "alertUnableToWriteLogMessage" = "Unable to write logs to file"; -"macToggleStatusButtonActivating" = "Activating…"; -"macMenuQuit" = "Quit WireGuard"; -"macMenuAddEmptyTunnel" = "Add Empty Tunnel…"; -"tunnelStatusDeactivating" = "Deactivating"; -"alertInvalidInterfaceTitle" = "Invalid interface"; -"tunnelSectionTitleStatus" = "Status"; -"macDeleteTunnelConfirmationAlertButtonTitleDelete" = "Delete"; "alertTunnelActivationFailureOnDemandAddendum" = " This tunnel has Activate On Demand enabled, so this tunnel might be re-activated automatically by the OS. You may turn off Activate On Demand in this app by editing the tunnel configuration."; -"alertTunnelActivationFailureTitle" = "Activation failure"; -"tunnelPeerTxBytes" = "Data sent"; -"macLogButtonTitleClose" = "Close"; -"tunnelOnDemandSSIDViewTitle" = "SSIDs"; "settingsExportZipButtonTitle" = "Export zip archive"; -"tunnelSectionTitleOnDemand" = "On-Demand Activation"; -"deleteTunnelsConfirmationAlertButtonTitle" = "Delete"; -"alertInvalidInterfaceMessageNameRequired" = "Interface name is required"; "macViewPrivateData" = "view tunnel private keys"; -"alertInvalidPeerTitle" = "Invalid peer"; -"alertInvalidPeerMessageEndpointInvalid" = "Peer’s endpoint must be of the form ‘host:port’ or ‘[host]:port’"; -"alertTunnelActivationErrorTunnelIsNotInactiveTitle" = "Activation in progress"; -"tunnelPeerAllowedIPs" = "Allowed IPs"; -"alertInvalidPeerMessagePublicKeyDuplicated" = "Two or more peers cannot have the same public key"; -"macToggleStatusButtonDeactivate" = "Deactivate"; -"addTunnelMenuImportFile" = "Create from file or archive"; -"deletePeerConfirmationAlertButtonTitle" = "Delete"; -"addTunnelMenuQRCode" = "Create from QR code"; -"alertInvalidPeerMessagePreSharedKeyInvalid" = "Peer’s preshared key must be a 32-byte key in base64 encoding"; "macAppExitingWithActiveTunnelInfo" = "The tunnel will remain active after exiting. You may disable it by reopening this application or through the Network panel in System Preferences."; -"macMenuEdit" = "Edit"; -"donateLink" = "♥ Donate to the WireGuard Project"; -"alertScanQRCodeCameraUnsupportedTitle" = "Camera Unsupported"; -"macMenuWindow" = "Window"; -"tunnelStatusRestarting" = "Restarting"; "alertUnableToRemovePreviousLogTitle" = "Log export failed"; "alertTunnelActivationFailureMessage" = "The tunnel could not be activated. Please ensure that you are connected to the Internet."; -"tunnelInterfaceListenPort" = "Listen port"; -"macToggleStatusButtonWaiting" = "Waiting…"; -"tunnelInterfaceStatus" = "Status"; -"macMenuHideOtherApps" = "Hide Others"; "alertCantOpenInputZipFileMessage" = "The zip archive could not be read."; -"alertInvalidInterfaceMessagePrivateKeyInvalid" = "Interface’s private key must be a 32-byte key in base64 encoding"; -"tunnelSectionTitleInterface" = "Interface"; -"alertInvalidInterfaceMessageDNSInvalid" = "Interface’s DNS servers must be a list of comma-separated IP addresses"; -"tunnelStatusInactive" = "Inactive"; -"macAlertPrivateKeyInvalid" = "Private key is invalid."; -"macDeleteTunnelConfirmationAlertButtonTitleCancel" = "Cancel"; "alertSystemErrorMessageTunnelConfigurationDisabled" = "The configuration is disabled."; -"alertInvalidPeerMessagePersistentKeepaliveInvalid" = "Peer’s persistent keepalive must be between 0 to 65535, or unspecified"; "alertUnableToWriteLogTitle" = "Log export failed"; -"alertInvalidPeerMessagePublicKeyRequired" = "Peer’s public key is required"; -"macMenuNetworksNone" = "Networks: None"; "alertCantOpenOutputZipFileForWritingMessage" = "Could not open zip file for writing."; -"macMenuSelectAll" = "Select All"; -"logViewTitle" = "Log"; -"alertInvalidPeerMessagePublicKeyInvalid" = "Peer’s public key must be a 32-byte key in base64 encoding"; -"tunnelOnDemandCellular" = "Cellular"; -"macConfirmAndQuitAlertQuitWireGuard" = "Quit WireGuard"; "alertSystemErrorOnRemoveTunnelTitle" = "Unable to remove tunnel"; -"macFieldOnDemand" = "On-Demand:"; -"macMenuCloseWindow" = "Close Window"; -"macSheetButtonExportLog" = "Save"; "alertSystemErrorOnModifyTunnelTitle" = "Unable to modify tunnel"; -"alertSystemErrorMessageTunnelConfigurationReadWriteFailed" = "Reading or writing the configuration failed."; -"macMenuEditTunnel" = "Edit…"; -"settingsSectionTitleTunnelLog" = "Log"; -"macMenuManageTunnels" = "Manage Tunnels"; -"macButtonImportTunnels" = "Import tunnel(s) from file"; "macAppExitingWithActiveTunnelMessage" = "WireGuard is exiting with an active tunnel"; -"tunnelSectionTitlePeer" = "Peer"; -"tunnelsListSelectButtonTitle" = "Select"; "alertSystemErrorMessageTunnelConfigurationStale" = "The configuration is stale."; -"tunnelPeerPreSharedKey" = "Preshared key"; "alertTunnelDNSFailureMessage" = "One or more endpoint domains could not be resolved."; -"tunnelOnDemandAddMessageAddNewSSID" = "Add new"; -"alertInvalidInterfaceMessageAddressInvalid" = "Interface addresses must be a list of comma-separated IP addresses, optionally in CIDR notation"; -"tunnelOnDemandSectionTitleAddSSIDs" = "Add SSIDs"; -"alertNoTunnelsInImportedZipArchiveTitle" = "No tunnels in zip archive"; "alertTunnelDNSFailureTitle" = "DNS resolution failure"; -"tunnelOnDemandEthernet" = "Ethernet"; -"macLogButtonTitleSave" = "Save…"; -"macMenuToggleStatus" = "Toggle Status"; -"macMenuMinimize" = "Minimize"; -"deletePeerButtonTitle" = "Delete peer"; -"tunnelPeerRxBytes" = "Data received"; "alertCantOpenInputZipFileTitle" = "Unable to read zip archive"; "alertScanQRCodeUnreadableQRCodeMessage" = "The scanned code could not be read"; -"alertScanQRCodeUnreadableQRCodeTitle" = "Invalid Code"; -"alertSystemErrorOnListingTunnelsTitle" = "Unable to list tunnels"; -"tunnelPeerExcludePrivateIPs" = "Exclude private IPs"; -"settingsVersionKeyWireGuardForIOS" = "WireGuard for iOS"; -"macMenuPaste" = "Paste"; "macAlertMultipleInterfaces" = "Configuration must have only one ‘Interface’ section."; -"scanQRCodeViewTitle" = "Scan QR code"; -"macAppStoreUpdatingAlertMessage" = "App Store would like to update WireGuard"; "macUnusableTunnelMessage" = "The configuration for this tunnel cannot be found in the keychain."; -"macToolTipEditTunnel" = "Edit tunnel (⌘E)"; -"tunnelEditPlaceholderTextStronglyRecommended" = "Strongly recommended"; -"macMenuZoom" = "Zoom"; "alertBadArchiveTitle" = "Unable to read zip archive"; "macExportPrivateData" = "export tunnel private keys"; -"alertTunnelAlreadyExistsWithThatNameTitle" = "Name already exists"; -"macToggleStatusButtonDeactivating" = "Deactivating…"; -"iosViewPrivateData" = "Authenticate to view tunnel private keys."; -"tunnelPeerLastHandshakeTime" = "Latest handshake"; -"macAlertPreSharedKeyInvalid" = "Preshared key is invalid"; -"alertBadConfigImportTitle" = "Unable to import tunnel"; -"macEditSave" = "Save"; -"macConfirmAndQuitAlertCloseWindow" = "Close Tunnels Manager"; -"macMenuFile" = "File"; -"tunnelStatusActivating" = "Activating"; "macToolTipToggleStatus" = "Toggle status (⌘T)"; -"alertTunnelActivationSystemErrorTitle" = "Activation failure"; -"alertInvalidInterfaceMessagePrivateKeyRequired" = "Interface’s private key is required"; -"alertNoTunnelsToExportTitle" = "Nothing to export"; -"scanQRCodeTipText" = "Tip: Generate with `qrencode -t ansiutf8 < tunnel.conf`"; -"alertNoTunnelsToExportMessage" = "There are no tunnels to export"; -"macMenuImportTunnels" = "Import Tunnel(s) from File…"; -"alertScanQRCodeInvalidQRCodeTitle" = "Invalid QR Code"; -"macMenuViewLog" = "View Log"; -"macAlertInfoUnrecognizedPeerKey" = "Valid keys are: ‘PublicKey’, ‘PresharedKey’, ‘AllowedIPs’, ‘Endpoint’ and ‘PersistentKeepalive’"; -"tunnelOnDemandNoSSIDs" = "No SSIDs"; -"addTunnelMenuHeader" = "Add a new WireGuard tunnel"; -"macUnusableTunnelButtonTitleDeleteTunnel" = "Delete tunnel"; -"tunnelStatusReasserting" = "Reactivating"; -"alertInvalidPeerMessageAllowedIPsInvalid" = "Peer’s allowed IPs must be a list of comma-separated IP addresses, optionally in CIDR notation"; -"macMenuTunnel" = "Tunnel"; -"macMenuCopy" = "Copy"; +"macTunnelsMenuTitle" = "Tunnels"; "alertTunnelAlreadyExistsWithThatNameMessage" = "A tunnel with that name already exists"; -"macLogColumnTitleLogMessage" = "Log message"; "iosExportPrivateData" = "Authenticate to export tunnel private keys."; -"macMenuAbout" = "About WireGuard"; -"macSheetButtonImport" = "Import"; "alertScanQRCodeNamePromptTitle" = "Please name the scanned tunnel"; "alertUnableToRemovePreviousLogMessage" = "The pre-existing log could not be cleared"; "alertTunnelActivationBackendFailureMessage" = "Unable to turn on Go backend library."; "settingsSectionTitleExportConfigurations" = "Export configurations"; -"alertBadArchiveMessage" = "Bad or corrupt zip archive."; -"settingsVersionKeyWireGuardGoBackend" = "WireGuard Go Backend"; -"macFieldOnDemandSSIDs" = "SSIDs:"; -"deletePeerConfirmationAlertMessage" = "Delete this peer?"; "alertCantOpenOutputZipFileForWritingTitle" = "Unable to create zip archive"; -"tunnelStatusActive" = "Active"; -"tunnelStatusWaiting" = "Waiting"; "alertNoTunnelsInImportedZipArchiveMessage" = "No .conf tunnel files were found inside the zip archive."; "alertTunnelActivationFileDescriptorFailureMessage" = "Unable to determine TUN device file descriptor."; -"addTunnelMenuFromScratch" = "Create from scratch"; -"macToggleStatusButtonActivate" = "Activate"; -"macAlertNameIsEmpty" = "Name is required"; -"tunnelsListDeleteButtonTitle" = "Delete"; diff --git a/Sources/WireGuardApp/fr.lproj/Localizable.strings b/Sources/WireGuardApp/fr.lproj/Localizable.strings index 73d772ac6..b9532b539 100644 --- a/Sources/WireGuardApp/fr.lproj/Localizable.strings +++ b/Sources/WireGuardApp/fr.lproj/Localizable.strings @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. // Generic alert action names @@ -443,3 +443,4 @@ // Donation "donateLink" = "♥ Faire un don au projet WireGuard"; +"macTunnelsMenuTitle" = "Tunnels"; diff --git a/Sources/WireGuardApp/id.lproj/Localizable.strings b/Sources/WireGuardApp/id.lproj/Localizable.strings index a1f5ab01d..68ac2269b 100644 --- a/Sources/WireGuardApp/id.lproj/Localizable.strings +++ b/Sources/WireGuardApp/id.lproj/Localizable.strings @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. // Generic alert action names @@ -233,6 +233,7 @@ "macConfirmAndQuitAlertCloseWindow" = "Close Tunnels Manager"; "macMenuFile" = "File"; "macToolTipToggleStatus" = "Toggle status (⌘T)"; +"macTunnelsMenuTitle" = "Tunnels"; "alertTunnelActivationSystemErrorTitle" = "Activation failure"; "alertInvalidInterfaceMessagePrivateKeyRequired" = "Interface’s private key is required"; "tunnelOnDemandAnySSID" = "Any SSID"; diff --git a/Sources/WireGuardApp/it.lproj/Localizable.strings b/Sources/WireGuardApp/it.lproj/Localizable.strings index 7ff6be61f..fb35d8996 100644 --- a/Sources/WireGuardApp/it.lproj/Localizable.strings +++ b/Sources/WireGuardApp/it.lproj/Localizable.strings @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. // Generic alert action names @@ -443,3 +443,4 @@ // Donation "donateLink" = "♥ Fai una donazione al progetto WireGuard"; +"macTunnelsMenuTitle" = "Tunnels"; diff --git a/Sources/WireGuardApp/ja.lproj/Localizable.strings b/Sources/WireGuardApp/ja.lproj/Localizable.strings index 04d44634a..633163919 100644 --- a/Sources/WireGuardApp/ja.lproj/Localizable.strings +++ b/Sources/WireGuardApp/ja.lproj/Localizable.strings @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. // Generic alert action names @@ -443,3 +443,4 @@ // Donation "donateLink" = "♥ WireGuard プロジェクトに寄付する"; +"macTunnelsMenuTitle" = "Tunnels"; diff --git a/Sources/WireGuardApp/ko.lproj/Localizable.strings b/Sources/WireGuardApp/ko.lproj/Localizable.strings index 2fda14dd4..06cb94c5d 100644 --- a/Sources/WireGuardApp/ko.lproj/Localizable.strings +++ b/Sources/WireGuardApp/ko.lproj/Localizable.strings @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. // Generic alert action names @@ -209,6 +209,7 @@ "macMenuFile" = "File"; "tunnelStatusActivating" = "Activating"; "macToolTipToggleStatus" = "Toggle status (⌘T)"; +"macTunnelsMenuTitle" = "Tunnels"; "alertTunnelActivationSystemErrorTitle" = "Activation failure"; "alertInvalidInterfaceMessagePrivateKeyRequired" = "Interface’s private key is required"; "tunnelOnDemandAnySSID" = "Any SSID"; diff --git a/Sources/WireGuardApp/pa.lproj/Localizable.strings b/Sources/WireGuardApp/pa.lproj/Localizable.strings index 10a7623f6..6ca6a648f 100644 --- a/Sources/WireGuardApp/pa.lproj/Localizable.strings +++ b/Sources/WireGuardApp/pa.lproj/Localizable.strings @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. // Generic alert action names @@ -443,3 +443,4 @@ // Donation "donateLink" = "♥ ਵਾਇਰਗਾਰਡ ਪਰੋਜੈਕਟ ਨੂੰ ਦਾਨ ਦਿਓ"; +"macTunnelsMenuTitle" = "Tunnels"; diff --git a/Sources/WireGuardApp/pl.lproj/Localizable.strings b/Sources/WireGuardApp/pl.lproj/Localizable.strings index 9127e316e..44da931c5 100644 --- a/Sources/WireGuardApp/pl.lproj/Localizable.strings +++ b/Sources/WireGuardApp/pl.lproj/Localizable.strings @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. // Generic alert action names @@ -24,6 +24,19 @@ "addTunnelMenuImportFile" = "Utwórz z pliku lub archiwum"; "addTunnelMenuQRCode" = "Utwórz za pomocą kodu QR"; "addTunnelMenuFromScratch" = "Utwórz od podstaw"; + +// Tunnels list alerts + +"alertImportedFromMultipleFilesTitle (%d)" = "Utworzono %d tuneli"; +"alertImportedFromMultipleFilesMessage (%1$d of %2$d)" = "Utworzono %1$d z %2$d tuneli z zaimportowanych plików"; + +"alertImportedFromZipTitle (%d)" = "Utworzono %d tuneli"; +"alertImportedFromZipMessage (%1$d of %2$d)" = "Utworzono %1$d z %2$d tuneli z archiwum zip"; + +"alertBadConfigImportTitle" = "Nie można zaimportować tunelu"; +"alertBadConfigImportMessage (%@)" = "Plik „%@” nie zawiera prawidłowej konfiguracji WireGuard"; + +"deleteTunnelsConfirmationAlertButtonTitle" = "Usuń"; "deleteTunnelConfirmationAlertButtonMessage (%d)" = "Usunąć %d tunel?"; "deleteTunnelsConfirmationAlertButtonMessage (%d)" = "Usunąć %d tunele(i)?"; @@ -34,34 +47,96 @@ "tunnelSectionTitleStatus" = "Status"; +"tunnelStatusInactive" = "Nieaktywny"; +"tunnelStatusActivating" = "Aktywowanie"; +"tunnelStatusActive" = "Aktywny"; +"tunnelStatusDeactivating" = "Dezaktywowanie"; +"tunnelStatusReasserting" = "Reaktywowanie"; +"tunnelStatusRestarting" = "Restartowanie"; +"tunnelStatusWaiting" = "Trwa oczekiwanie"; + +"macToggleStatusButtonActivate" = "Aktywuj"; +"macToggleStatusButtonActivating" = "Aktywowanie…"; +"macToggleStatusButtonDeactivate" = "Dezaktywuj"; +"macToggleStatusButtonDeactivating" = "Dezaktywowanie…"; +"macToggleStatusButtonReasserting" = "Reaktywowanie…"; +"macToggleStatusButtonRestarting" = "Restartowanie…"; +"macToggleStatusButtonWaiting" = "Oczekiwanie…"; + +"tunnelSectionTitleInterface" = "Interfejs"; + "tunnelInterfaceName" = "Nazwa"; "tunnelInterfacePrivateKey" = "Klucz prywatny"; "tunnelInterfacePublicKey" = "Klucz publiczny"; +"tunnelInterfaceGenerateKeypair" = "Generowanie pary kluczy"; "tunnelInterfaceAddresses" = "Adresy"; "tunnelInterfaceListenPort" = "Port nasłuchu"; "tunnelInterfaceMTU" = "MTU"; "tunnelInterfaceDNS" = "Serwery DNS"; "tunnelInterfaceStatus" = "Status"; +"tunnelSectionTitlePeer" = "Peer"; + "tunnelPeerPublicKey" = "Klucz publiczny"; +"tunnelPeerPreSharedKey" = "PSK"; +"tunnelPeerEndpoint" = "Adres"; +"tunnelPeerPersistentKeepalive" = "Utrzymanie połączenia"; "tunnelPeerAllowedIPs" = "Dozwolone adresy IP"; +"tunnelPeerRxBytes" = "Otrzymane dane"; +"tunnelPeerTxBytes" = "Dane wysłane"; +"tunnelPeerLastHandshakeTime" = "Ostatni uścisk dłoni (handshake)"; +"tunnelPeerExcludePrivateIPs" = "Wyklucz prywatne adresy IP"; + +"tunnelSectionTitleOnDemand" = "Aktywacja na żądanie"; + +"tunnelOnDemandCellular" = "Dane komórkowe"; "tunnelOnDemandEthernet" = "Ethernet"; "tunnelOnDemandWiFi" = "Wi-Fi"; +"tunnelOnDemandSSIDsKey" = "Identyfikatory SSID"; + +"tunnelOnDemandAnySSID" = "Dowolny SSID"; +"tunnelOnDemandOnlyTheseSSIDs" = "Tylko te SSID"; +"tunnelOnDemandExceptTheseSSIDs" = "Z wyjątkiem tych SSID"; +"tunnelOnDemandOnlySSID (%d)" = "Tylko %d SSID"; +"tunnelOnDemandOnlySSIDs (%d)" = "Tylko te %d SSID"; +"tunnelOnDemandExceptSSID (%d)" = "Z wyjątkiem %d SSID"; +"tunnelOnDemandExceptSSIDs (%d)" = "Z wyjątkiem tych %d SSID"; "tunnelOnDemandSSIDOptionDescriptionMac (%1$@: %2$@)" = "%1$@: %2$@"; +"tunnelOnDemandSSIDViewTitle" = "Identyfikatory SSID"; +"tunnelOnDemandSectionTitleSelectedSSIDs" = "Identyfikatory SSID"; +"tunnelOnDemandNoSSIDs" = "Brak SSID"; +"tunnelOnDemandSectionTitleAddSSIDs" = "Dodaj SSID"; +"tunnelOnDemandAddMessageAddConnectedSSID (%@)" = "Dodaj połączony: %@"; +"tunnelOnDemandAddMessageAddNewSSID" = "Dodaj nowy"; + "tunnelOnDemandKey" = "Na żądanie"; +"tunnelOnDemandOptionOff" = "Wył."; "tunnelOnDemandOptionWiFiOnly" = "Tylko Wi-Fi"; "tunnelOnDemandOptionWiFiOrCellular" = "Wi-Fi i dane sieci komórkowej"; "tunnelOnDemandOptionCellularOnly" = "Tylko dane sieci komórkowej"; "tunnelOnDemandOptionWiFiOrEthernet" = "Wi-Fi lub sieć ethernet"; "tunnelOnDemandOptionEthernetOnly" = "Tylko sieć ethernet"; + +"addPeerButtonTitle" = "Dodaj Peer'a"; + +"deletePeerButtonTitle" = "Usuń peer'a"; "deletePeerConfirmationAlertButtonTitle" = "Usuń"; +"deletePeerConfirmationAlertMessage" = "Usunąć tego peer'a?"; "deleteTunnelButtonTitle" = "Usuń tunel"; "deleteTunnelConfirmationAlertButtonTitle" = "Usuń"; "deleteTunnelConfirmationAlertMessage" = "Usunąć ten tunel?"; +"tunnelEditPlaceholderTextRequired" = "Wymagane"; +"tunnelEditPlaceholderTextOptional" = "Opcjonalne"; +"tunnelEditPlaceholderTextAutomatic" = "Automatycznie wybrany"; +"tunnelEditPlaceholderTextStronglyRecommended" = "Zalecane"; +"tunnelEditPlaceholderTextOff" = "Wył."; + "tunnelPeerPersistentKeepaliveValue (%@)" = "co %@ sekund"; +"tunnelHandshakeTimestampNow" = "Teraz"; +"tunnelHandshakeTimestampSystemClockBackward" = "(Zegar systemowy został cofnięty)"; "tunnelHandshakeTimestampAgo (%@)" = "%@ temu"; "tunnelHandshakeTimestampYear (%d)" = "%d rok"; "tunnelHandshakeTimestampYears (%d)" = "%d lat/lata"; @@ -79,14 +154,49 @@ "tunnelPeerPresharedKeyEnabled" = "włączony"; +// Error alerts while creating / editing a tunnel configuration +/* Alert title for error in the interface data */ + +"alertInvalidInterfaceTitle" = "Niewłaściwy interfejs"; + +/* Any one of the following alert messages can go with the above title */ +"alertInvalidInterfaceMessageNameRequired" = "Nazwa interfejsu jest wymagana"; +"alertInvalidInterfaceMessagePrivateKeyRequired" = "Klucz prywatny interfejsu jest wymagany"; +"alertInvalidInterfaceMessagePrivateKeyInvalid" = "Klucz prywatny interfejsu musi być 32-bajtowym kluczem zakodowanym w base64"; +"alertInvalidInterfaceMessageAddressInvalid" = "Adresy interfejsu muszą być listą adresów IP rozdzielone przecinkami, opcjonalnie w notacji CIDR"; +"alertInvalidInterfaceMessageListenPortInvalid" = "Port nasłuchiwania interfejsu musi wynosić pomiędzy 0 a 65535 lub nieokreślony"; +"alertInvalidInterfaceMessageMTUInvalid" = "Wartość MTU musi wynosić pomiędzy 576 a 65535 lub nieokreślona"; +"alertInvalidInterfaceMessageDNSInvalid" = "Serwery DNS interfejsu muszą być listą adresów IP rozdzielonych przecinkami"; + +/* Alert title for error in the peer data */ +"alertInvalidPeerTitle" = "Nieprawidłowy peer"; + +/* Any one of the following alert messages can go with the above title */ +"alertInvalidPeerMessagePublicKeyRequired" = "Klucz publiczny peer'a jest wymagany"; +"alertInvalidPeerMessagePublicKeyInvalid" = "Klucz prywatny peer'a musi być 32-bajtowym kluczem zakodowanym w base64"; +"alertInvalidPeerMessagePreSharedKeyInvalid" = "Klucz publiczny peer'a musi być 32-bajtowym kluczem zakodowanym w base64"; +"alertInvalidPeerMessageAllowedIPsInvalid" = "Dozwolone adresy peer'a muszą być listą adresów IP rozdzielone przecinkami, opcjonalnie w notacji CIDR"; +"alertInvalidPeerMessageEndpointInvalid" = "Adres peer'a musi być w postaci „adres:port” or „[host]:port”"; +"alertInvalidPeerMessagePersistentKeepaliveInvalid" = "Interwał podtrzymywania połączenia musi wynosić pomiędzy 0 a 65535 lub nieokreślony"; +"alertInvalidPeerMessagePublicKeyDuplicated" = "Dwa lub więcej peer'ów nie może współdzielić tego samego klucza publicznego"; + // Scanning QR code UI "scanQRCodeViewTitle" = "Skanuj kod QR"; "scanQRCodeTipText" = "Wskazówka: wygeneruj za pomocą `qrencode -t ansiutf8 < tunnel.conf`"; +// Scanning QR code alerts + +"alertScanQRCodeCameraUnsupportedTitle" = "Kamera nie jest obsługiwana"; +"alertScanQRCodeCameraUnsupportedMessage" = "To urządzenie nie jest w stanie zeskanować kodów QR"; + "alertScanQRCodeInvalidQRCodeTitle" = "Nieprawidłowy kod QR"; +"alertScanQRCodeInvalidQRCodeMessage" = "Zeskanowany kod QR nie jest poprawną konfiguracją WireGuard"; "alertScanQRCodeUnreadableQRCodeTitle" = "Nieprawidłowy kod"; +"alertScanQRCodeUnreadableQRCodeMessage" = "Zeskanowany kod nie mógł zostać odczytany"; + +"alertScanQRCodeNamePromptTitle" = "Nazwij zeskanowany tunel"; // Settings UI @@ -94,6 +204,10 @@ "settingsSectionTitleAbout" = "O programie"; "settingsVersionKeyWireGuardForIOS" = "WireGuard dla iOS"; +"settingsVersionKeyWireGuardGoBackend" = "WireGuard Go Backend"; + +"settingsSectionTitleExportConfigurations" = "Eksportuj konfiguracje"; +"settingsExportZipButtonTitle" = "Eksportuj do archiwum zip"; "settingsSectionTitleTunnelLog" = "Log"; "settingsViewLogButtonTitle" = "Wyświetl log"; @@ -102,6 +216,19 @@ "logViewTitle" = "Log"; +// Log alerts + +"alertUnableToRemovePreviousLogTitle" = "Export logów nie powiódł się"; +"alertUnableToRemovePreviousLogMessage" = "Nie można usunąć już istniejących logów"; + +"alertUnableToWriteLogTitle" = "Eksport logów nie powiódł się"; +"alertUnableToWriteLogMessage" = "Nie można zapisać logów do pliku"; + +// Zip import / export error alerts + +"alertCantOpenInputZipFileTitle" = "Nie można odczytać archiwum zip"; +"alertCantOpenInputZipFileMessage" = "Nie można odczytać archiwum zip."; + "alertCantOpenOutputZipFileForWritingTitle" = "Nie można utworzyć archiwum ZIP"; "alertCantOpenOutputZipFileForWritingMessage" = "Nie udało się otworzyć pliku ZIP do zapisu."; @@ -112,14 +239,65 @@ "alertNoTunnelsToExportMessage" = "Nie ma żadnych tuneli do wyeksportowania"; "alertNoTunnelsInImportedZipArchiveTitle" = "Brak tuneli w archiwum ZIP"; +"alertNoTunnelsInImportedZipArchiveMessage" = "Nie znaleziono plików konfiguracyjnych tunelu .conf w archiwum zip."; + +// Conf import error alerts + +"alertCantOpenInputConfFileTitle" = "Nie można zaimportować z pliku"; +"alertCantOpenInputConfFileMessage (%@)" = "Nie można odczytać pliku „%@”."; + +// Tunnel management error alerts + +"alertTunnelActivationFailureTitle" = "Błąd aktywacji tunelu"; +"alertTunnelActivationFailureMessage" = "Tunel nie mógł zostać aktywowany. Upewnij się, że jesteś podłączony do Internetu."; +"alertTunnelActivationSavedConfigFailureMessage" = "Nie można odczytać informacji o tunelu z zapisanej konfiguracji."; +"alertTunnelActivationBackendFailureMessage" = "Nie udało się włącz tunelu bazując na bibliotece Go."; +"alertTunnelActivationFileDescriptorFailureMessage" = "Nie można określić opisu urządzenia TUN."; +"alertTunnelActivationSetNetworkSettingsMessage" = "Nie można zastosować ustawień sieci do tunelu."; + +"alertTunnelActivationFailureOnDemandAddendum" = "Ten tunel ma włączoną aktywację na żądanie, więc ten tunel może być ponownie aktywowany automatycznie przez system operacyjny. Możesz wyłączyć aktywację na żądanie poprzez edycję konfiguracji tunelu."; + +"alertTunnelDNSFailureTitle" = "Nieudane rozpoznanie DNS"; +"alertTunnelDNSFailureMessage" = "Jedna lub więcej domen nie może zostać odnalezionych."; + +"alertTunnelNameEmptyTitle" = "Nie podano nazwy"; +"alertTunnelNameEmptyMessage" = "Nie można utworzyć tunelu z pustą nazwą"; "alertTunnelAlreadyExistsWithThatNameTitle" = "Nazwa już istnieje"; "alertTunnelAlreadyExistsWithThatNameMessage" = "Tunel o tej nazwie już istnieje"; + +"alertTunnelActivationErrorTunnelIsNotInactiveTitle" = "Aktywacja w toku"; +"alertTunnelActivationErrorTunnelIsNotInactiveMessage" = "Tunel jest już aktywny lub jest już w trakcie aktywowania"; + +// Tunnel management error alerts on system error +/* The alert message that goes with the following titles would be + one of the alertSystemErrorMessage* listed further down */ + +"alertSystemErrorOnListingTunnelsTitle" = "Nie można wyświetlić tuneli"; "alertSystemErrorOnAddTunnelTitle" = "Nie można utworzyć tunelu"; "alertSystemErrorOnModifyTunnelTitle" = "Nie można zmodyfikować tunelu"; "alertSystemErrorOnRemoveTunnelTitle" = "Nie można usunąć tunelu"; +/* The alert message for this alert shall include + one of the alertSystemErrorMessage* listed further down */ +"alertTunnelActivationSystemErrorTitle" = "Błąd aktywacji tunelu"; +"alertTunnelActivationSystemErrorMessage (%@)" = "Błąd aktywacji tunelu. %@"; + +/* alertSystemErrorMessage* messages */ +"alertSystemErrorMessageTunnelConfigurationInvalid" = "Ta konfiguracja jest nieprawidłowa."; +"alertSystemErrorMessageTunnelConfigurationDisabled" = "Konfiguracja jest wyłączona."; +"alertSystemErrorMessageTunnelConnectionFailed" = "Połączenie nie powiodło się."; +"alertSystemErrorMessageTunnelConfigurationStale" = "Konfiguracja jest przestarzała."; +"alertSystemErrorMessageTunnelConfigurationReadWriteFailed" = "Czytanie lub zapisywanie konfiguracji nie powiodło się."; +"alertSystemErrorMessageTunnelConfigurationUnknown" = "Nieznany błąd systemowy."; + +// Mac status bar menu / pulldown menu / main menu + +"macMenuNetworks (%@)" = "Sieci: %@"; +"macMenuNetworksNone" = "Sieci: brak"; + "macMenuTitle" = "WireGuard"; +"macMenuManageTunnels" = "Zarządzaj tunelami"; "macMenuImportTunnels" = "Importuj tunel(e) z pliku…"; "macMenuAddEmptyTunnel" = "Dodaj pusty tunel…"; "macMenuViewLog" = "Wyświetl log"; @@ -128,6 +306,8 @@ "macMenuQuit" = "Wyjdź z programu WireGuard"; "macMenuHideApp" = "Ukryj program WireGuard"; +"macMenuHideOtherApps" = "Ukryj pozostałe"; +"macMenuShowAllApps" = "Pokaż wszystkie"; "macMenuFile" = "Plik"; "macMenuCloseWindow" = "Zamknij okno"; @@ -139,9 +319,14 @@ "macMenuSelectAll" = "Wybierz wszystko"; "macMenuTunnel" = "Tunel"; +"macMenuToggleStatus" = "Przełącz status"; "macMenuEditTunnel" = "Edytuj…"; "macMenuDeleteSelected" = "Usuń wybrane"; +"macMenuWindow" = "Okno"; +"macMenuMinimize" = "Minimalizuj"; +"macMenuZoom" = "Powiększenie"; + // Mac manage tunnels window "macWindowTitleManageTunnels" = "Zarządzaj tunelami WireGuard"; @@ -154,6 +339,7 @@ "macDeleteTunnelConfirmationAlertButtonTitleDeleting" = "Usuwanie…"; "macButtonImportTunnels" = "Importuj tunel(e) z pliku"; +"macSheetButtonImport" = "Importuj"; "macNameFieldExportLog" = "Zapisz log do:"; "macSheetButtonExportLog" = "Zapisz"; @@ -161,163 +347,100 @@ "macNameFieldExportZip" = "Wyeksportuj tunele do:"; "macSheetButtonExportZip" = "Zapisz"; +"macButtonDeleteTunnels (%d)" = "Usuń %d tunele(i)"; + "macButtonEdit" = "Edytuj"; // Mac detail/edit view fields "macFieldKey (%@)" = "%@:"; +"macFieldOnDemand" = "Na żądanie:"; +"macFieldOnDemandSSIDs" = "Identyfikatory SSID:"; + +// Mac status display + +"macStatus (%@)" = "Status: %@"; + +// Mac editing config + +"macEditDiscard" = "Odrzuć"; "macEditSave" = "Zapisz"; "macAlertNameIsEmpty" = "Nazwa jest wymagana"; +"macAlertDuplicateName (%@)" = "Inny tunel o nazwie „%@” już istnieje."; + +"macAlertInvalidLine (%@)" = "Nieprawidłowy wiersz: „%@”."; + +"macAlertNoInterface" = "Konfiguracja musi mieć sekcję „Interface”."; +"macAlertMultipleInterfaces" = "Konfiguracja musi posiadać tylko jedną sekcję „Interface”."; "macAlertPrivateKeyInvalid" = "Klucz prywatny jest nieprawidłowy."; +"macAlertListenPortInvalid (%@)" = "Port nasłuchu „%@” jest nieprawidłowy."; "macAlertAddressInvalid (%@)" = "Adres \"%@\" jest nieprawidłowy."; +"macAlertDNSInvalid (%@)" = "DNS „%@” jest nieprawidłowy."; "macAlertMTUInvalid (%@)" = "Wartość MTU ‘%@’ jest nieprawidłowa."; +"macAlertUnrecognizedInterfaceKey (%@)" = "Interfejs zawiera nierozpoznawalny klucz „%@”"; +"macAlertInfoUnrecognizedInterfaceKey" = "Prawidłowe klucze to: „PrivateKey”, „ListenPort”, „Adres”, „DNS” i „MTU”."; + "macAlertPublicKeyInvalid" = "Klucz publiczny jest nieprawidłowy"; +"macAlertPreSharedKeyInvalid" = "Klucz wstępnie współdzielony jest niepoprawny"; +"macAlertAllowedIPInvalid (%@)" = "Dozwolony adres IP „%@” jest nieprawidłowy"; +"macAlertEndpointInvalid (%@)" = "Adres końcowy „%@” jest nieprawidłowy"; +"macAlertPersistentKeepliveInvalid (%@)" = "Obecna wartość keepalive „%@” jest nieprawidłowa"; + +"macAlertUnrecognizedPeerKey (%@)" = "Peer zawiera nierozpoznawalny klucz „%@”"; +"macAlertInfoUnrecognizedPeerKey" = "Prawidłowe klucze to: „PublicKey”, „PresharedKey”, „AllowedIPs”, „Endpoint” i „PersistentKeepalive”"; + +"macAlertMultipleEntriesForKey (%@)" = "Dla klucza „%@” powinien być tylko jeden wpis w sekcji"; // Mac about dialog "macAppVersion (%@)" = "Wersja aplikacji: %@"; "macGoBackendVersion (%@)" = "Wersja backend'u Go: %@"; + +// Privacy + +"macExportPrivateData" = "eksportuj klucze prywatne tunelu"; +"macViewPrivateData" = "wyświetl klucze prywatne tunelu"; +"iosExportPrivateData" = "Uwierzytelnij, aby wyeksportować klucze prywatne tuneli."; +"iosViewPrivateData" = "Uwierzytelnij, aby zobaczyć klucze prywatne."; + +// Mac alert + +"macConfirmAndQuitAlertMessage" = "Czy chcesz zamknąć menedżera tuneli czy wyłączyć całkowicie WireGuard?"; +"macConfirmAndQuitAlertInfo" = "Jeśli zamkniesz menedżera tuneli, WireGuard będzie nadal dostępny z ikony w pasku menu."; +"macConfirmAndQuitInfoWithActiveTunnel (%@)" = "Jeśli zamkniesz menedżera tuneli, WireGuard będzie nadal dostępny z ikony w pasku menu.\n\nZauważ, że jeśli opuścisz WireGuard całkowicie aktywny tunel („%@”) pozostanie aktywny, dopóki nie wyłączysz go z tej aplikacji lub przez panel sieci w ustawieniach systemowych."; "macConfirmAndQuitAlertQuitWireGuard" = "Wyjdź z programu WireGuard"; +"macConfirmAndQuitAlertCloseWindow" = "Zamknij menedżera tuneli"; + +"macAppExitingWithActiveTunnelMessage" = "WireGuard jest wyłączany wraz z aktywnym tunelem"; +"macAppExitingWithActiveTunnelInfo" = "Tunel pozostanie aktywny po wyjściu. Możesz go wyłączyć, ponownie otwierając tę aplikację lub przez panel sieci w ustawieniach systemowych."; // Mac tooltip "macToolTipEditTunnel" = "Edytuj tunel (⌘E)"; "macToolTipToggleStatus" = "Przełącz stan (⌘T)"; + +// Mac log view + +"macLogColumnTitleTime" = "Czas"; +"macLogColumnTitleLogMessage" = "Dziennik wiadomości"; "macLogButtonTitleClose" = "Zamknij"; "macLogButtonTitleSave" = "Zapisz…"; + +// Mac unusable tunnel view + +"macUnusableTunnelMessage" = "Konfiguracja dla tego tunelu nie może zostać znaleziona w pęku kluczy."; +"macUnusableTunnelInfo" = "W przypadku, gdy ten tunel został utworzony przez innego użytkownika, tylko ten użytkownik może przeglądać, edytować lub aktywować ten tunel."; "macUnusableTunnelButtonTitleDeleteTunnel" = "Usuń tunel"; -"alertSystemErrorMessageTunnelConfigurationInvalid" = "The configuration is invalid."; -"tunnelPeerEndpoint" = "Endpoint"; -"alertInvalidInterfaceMessageListenPortInvalid" = "Interface’s listen port must be between 0 and 65535, or unspecified"; -"addPeerButtonTitle" = "Add peer"; -"tunnelHandshakeTimestampSystemClockBackward" = "(System clock wound backwards)"; -"macAlertNoInterface" = "Configuration must have an ‘Interface’ section."; -"alertSystemErrorMessageTunnelConfigurationUnknown" = "Unknown system error."; -"macEditDiscard" = "Discard"; -"alertScanQRCodeCameraUnsupportedMessage" = "This device is not able to scan QR codes"; -"macConfirmAndQuitAlertInfo" = "If you close the tunnels manager, WireGuard will continue to be available from the menu bar icon."; -"macUnusableTunnelInfo" = "In case this tunnel was created by another user, only that user can view, edit, or activate this tunnel."; -"alertTunnelActivationErrorTunnelIsNotInactiveMessage" = "The tunnel is already active or in the process of being activated"; -"macToggleStatusButtonReasserting" = "Reactivating…"; -"alertTunnelActivationSetNetworkSettingsMessage" = "Unable to apply network settings to tunnel object."; -"macMenuShowAllApps" = "Show All"; -"alertCantOpenInputConfFileTitle" = "Unable to import from file"; -"alertScanQRCodeInvalidQRCodeMessage" = "The scanned QR code is not a valid WireGuard configuration"; -"tunnelPeerPersistentKeepalive" = "Persistent keepalive"; -"alertSystemErrorMessageTunnelConnectionFailed" = "The connection failed."; -"macConfirmAndQuitAlertMessage" = "Do you want to close the tunnels manager or quit WireGuard entirely?"; -"alertTunnelActivationSavedConfigFailureMessage" = "Unable to retrieve tunnel information from the saved configuration."; -"tunnelOnDemandOptionOff" = "Off"; -"tunnelOnDemandSectionTitleSelectedSSIDs" = "SSIDs"; -"macAlertInfoUnrecognizedInterfaceKey" = "Valid keys are: ‘PrivateKey’, ‘ListenPort’, ‘Address’, ‘DNS’ and ‘MTU’."; -"macLogColumnTitleTime" = "Time"; -"alertTunnelNameEmptyMessage" = "Cannot create tunnel with an empty name"; -"alertInvalidInterfaceMessageMTUInvalid" = "Interface’s MTU must be between 576 and 65535, or unspecified"; -"alertTunnelNameEmptyTitle" = "No name provided"; -"tunnelOnDemandOnlyTheseSSIDs" = "Only these SSIDs"; -"macToggleStatusButtonRestarting" = "Restarting…"; -"tunnelOnDemandExceptTheseSSIDs" = "Except these SSIDs"; -"alertUnableToWriteLogMessage" = "Unable to write logs to file"; -"macToggleStatusButtonActivating" = "Activating…"; -"tunnelStatusDeactivating" = "Deactivating"; -"alertInvalidInterfaceTitle" = "Invalid interface"; -"alertTunnelActivationFailureOnDemandAddendum" = " This tunnel has Activate On Demand enabled, so this tunnel might be re-activated automatically by the OS. You may turn off Activate On Demand in this app by editing the tunnel configuration."; -"alertTunnelActivationFailureTitle" = "Activation failure"; -"tunnelPeerTxBytes" = "Data sent"; -"tunnelOnDemandSSIDViewTitle" = "SSIDs"; -"tunnelEditPlaceholderTextOptional" = "Optional"; -"settingsExportZipButtonTitle" = "Export zip archive"; -"tunnelSectionTitleOnDemand" = "On-Demand Activation"; -"tunnelInterfaceGenerateKeypair" = "Generate keypair"; -"deleteTunnelsConfirmationAlertButtonTitle" = "Delete"; -"alertInvalidInterfaceMessageNameRequired" = "Interface name is required"; -"tunnelEditPlaceholderTextAutomatic" = "Automatic"; -"macViewPrivateData" = "view tunnel private keys"; -"alertInvalidPeerTitle" = "Invalid peer"; -"alertInvalidPeerMessageEndpointInvalid" = "Peer’s endpoint must be of the form ‘host:port’ or ‘[host]:port’"; -"alertTunnelActivationErrorTunnelIsNotInactiveTitle" = "Activation in progress"; -"alertInvalidPeerMessagePublicKeyDuplicated" = "Two or more peers cannot have the same public key"; -"macToggleStatusButtonDeactivate" = "Deactivate"; -"alertInvalidPeerMessagePreSharedKeyInvalid" = "Peer’s preshared key must be a 32-byte key in base64 encoding"; -"macAppExitingWithActiveTunnelInfo" = "The tunnel will remain active after exiting. You may disable it by reopening this application or through the Network panel in System Preferences."; -"donateLink" = "♥ Donate to the WireGuard Project"; -"alertScanQRCodeCameraUnsupportedTitle" = "Camera Unsupported"; -"macMenuWindow" = "Window"; -"tunnelStatusRestarting" = "Restarting"; -"alertUnableToRemovePreviousLogTitle" = "Log export failed"; -"tunnelHandshakeTimestampNow" = "Now"; -"alertTunnelActivationFailureMessage" = "The tunnel could not be activated. Please ensure that you are connected to the Internet."; -"macToggleStatusButtonWaiting" = "Waiting…"; -"macMenuHideOtherApps" = "Hide Others"; -"alertCantOpenInputZipFileMessage" = "The zip archive could not be read."; -"alertInvalidInterfaceMessagePrivateKeyInvalid" = "Interface’s private key must be a 32-byte key in base64 encoding"; -"tunnelSectionTitleInterface" = "Interface"; -"alertInvalidInterfaceMessageDNSInvalid" = "Interface’s DNS servers must be a list of comma-separated IP addresses"; -"tunnelStatusInactive" = "Inactive"; -"alertSystemErrorMessageTunnelConfigurationDisabled" = "The configuration is disabled."; -"alertInvalidPeerMessagePersistentKeepaliveInvalid" = "Peer’s persistent keepalive must be between 0 to 65535, or unspecified"; -"alertUnableToWriteLogTitle" = "Log export failed"; -"alertInvalidPeerMessagePublicKeyRequired" = "Peer’s public key is required"; -"macMenuNetworksNone" = "Networks: None"; -"tunnelOnDemandSSIDsKey" = "SSIDs"; -"alertInvalidPeerMessagePublicKeyInvalid" = "Peer’s public key must be a 32-byte key in base64 encoding"; -"tunnelOnDemandCellular" = "Cellular"; -"macFieldOnDemand" = "On-Demand:"; -"alertSystemErrorMessageTunnelConfigurationReadWriteFailed" = "Reading or writing the configuration failed."; -"macMenuManageTunnels" = "Manage Tunnels"; -"macAppExitingWithActiveTunnelMessage" = "WireGuard is exiting with an active tunnel"; -"tunnelSectionTitlePeer" = "Peer"; -"alertSystemErrorMessageTunnelConfigurationStale" = "The configuration is stale."; -"tunnelPeerPreSharedKey" = "Preshared key"; -"alertTunnelDNSFailureMessage" = "One or more endpoint domains could not be resolved."; -"tunnelOnDemandAddMessageAddNewSSID" = "Add new"; -"alertInvalidInterfaceMessageAddressInvalid" = "Interface addresses must be a list of comma-separated IP addresses, optionally in CIDR notation"; -"tunnelOnDemandSectionTitleAddSSIDs" = "Add SSIDs"; -"alertTunnelDNSFailureTitle" = "DNS resolution failure"; -"macMenuToggleStatus" = "Toggle Status"; -"macMenuMinimize" = "Minimize"; -"deletePeerButtonTitle" = "Delete peer"; -"tunnelPeerRxBytes" = "Data received"; -"alertCantOpenInputZipFileTitle" = "Unable to read zip archive"; -"alertScanQRCodeUnreadableQRCodeMessage" = "The scanned code could not be read"; -"alertSystemErrorOnListingTunnelsTitle" = "Unable to list tunnels"; -"tunnelPeerExcludePrivateIPs" = "Exclude private IPs"; -"macAlertMultipleInterfaces" = "Configuration must have only one ‘Interface’ section."; -"macAppStoreUpdatingAlertMessage" = "App Store would like to update WireGuard"; -"macUnusableTunnelMessage" = "The configuration for this tunnel cannot be found in the keychain."; -"tunnelEditPlaceholderTextStronglyRecommended" = "Strongly recommended"; -"macMenuZoom" = "Zoom"; -"macExportPrivateData" = "export tunnel private keys"; -"macToggleStatusButtonDeactivating" = "Deactivating…"; -"iosViewPrivateData" = "Authenticate to view tunnel private keys."; -"tunnelPeerLastHandshakeTime" = "Latest handshake"; -"macAlertPreSharedKeyInvalid" = "Preshared key is invalid"; -"alertBadConfigImportTitle" = "Unable to import tunnel"; -"macConfirmAndQuitAlertCloseWindow" = "Close Tunnels Manager"; -"tunnelStatusActivating" = "Activating"; -"alertTunnelActivationSystemErrorTitle" = "Activation failure"; -"alertInvalidInterfaceMessagePrivateKeyRequired" = "Interface’s private key is required"; -"tunnelOnDemandAnySSID" = "Any SSID"; -"macAlertInfoUnrecognizedPeerKey" = "Valid keys are: ‘PublicKey’, ‘PresharedKey’, ‘AllowedIPs’, ‘Endpoint’ and ‘PersistentKeepalive’"; -"tunnelOnDemandNoSSIDs" = "No SSIDs"; -"tunnelEditPlaceholderTextOff" = "Off"; -"tunnelEditPlaceholderTextRequired" = "Required"; -"tunnelStatusReasserting" = "Reactivating"; -"alertInvalidPeerMessageAllowedIPsInvalid" = "Peer’s allowed IPs must be a list of comma-separated IP addresses, optionally in CIDR notation"; -"macLogColumnTitleLogMessage" = "Log message"; -"iosExportPrivateData" = "Authenticate to export tunnel private keys."; -"macSheetButtonImport" = "Import"; -"alertScanQRCodeNamePromptTitle" = "Please name the scanned tunnel"; -"alertUnableToRemovePreviousLogMessage" = "The pre-existing log could not be cleared"; -"alertTunnelActivationBackendFailureMessage" = "Unable to turn on Go backend library."; -"settingsSectionTitleExportConfigurations" = "Export configurations"; -"settingsVersionKeyWireGuardGoBackend" = "WireGuard Go Backend"; -"macFieldOnDemandSSIDs" = "SSIDs:"; -"deletePeerConfirmationAlertMessage" = "Delete this peer?"; -"tunnelStatusActive" = "Active"; -"tunnelStatusWaiting" = "Waiting"; -"alertNoTunnelsInImportedZipArchiveMessage" = "No .conf tunnel files were found inside the zip archive."; -"alertTunnelActivationFileDescriptorFailureMessage" = "Unable to determine TUN device file descriptor."; -"macToggleStatusButtonActivate" = "Activate"; + +// Mac App Store updating alert + +"macAppStoreUpdatingAlertMessage" = "App Store chce zaktualizować WireGuard"; +"macAppStoreUpdatingAlertInfoWithOnDemand (%@)" = "Proszę najpierw wyłączyć aktywację na żądanie tunelu „%@”, dezaktywować go, a dopiero następnie kontynuować aktualizację w App Store."; +"macAppStoreUpdatingAlertInfoWithoutOnDemand (%@)" = "Proszę dezaktywować tunel „%@”, a następnie kontynuować aktualizację w App Store."; + +// Donation + +"donateLink" = "♥ Dotacja dla projektu WireGuard"; +"macTunnelsMenuTitle" = "Tunnels"; diff --git a/Sources/WireGuardApp/ro.lproj/Localizable.strings b/Sources/WireGuardApp/ro.lproj/Localizable.strings index 7b976bd3d..9ebf95614 100644 --- a/Sources/WireGuardApp/ro.lproj/Localizable.strings +++ b/Sources/WireGuardApp/ro.lproj/Localizable.strings @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. // Generic alert action names @@ -443,3 +443,4 @@ // Donation "donateLink" = "♥ Donează pentru proiectul WireGuard"; +"macTunnelsMenuTitle" = "Tunnels"; diff --git a/Sources/WireGuardApp/ru.lproj/Localizable.strings b/Sources/WireGuardApp/ru.lproj/Localizable.strings index 7c762d173..b31ff63ef 100644 --- a/Sources/WireGuardApp/ru.lproj/Localizable.strings +++ b/Sources/WireGuardApp/ru.lproj/Localizable.strings @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. // Generic alert action names @@ -443,3 +443,4 @@ // Donation "donateLink" = "♥ Пожертвовать проекту WireGuard"; +"macTunnelsMenuTitle" = "Tunnels"; diff --git a/Sources/WireGuardApp/sl.lproj/Localizable.strings b/Sources/WireGuardApp/sl.lproj/Localizable.strings index 2a8066b44..619d2b8ae 100644 --- a/Sources/WireGuardApp/sl.lproj/Localizable.strings +++ b/Sources/WireGuardApp/sl.lproj/Localizable.strings @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. // Generic alert action names @@ -443,3 +443,4 @@ // Donation "donateLink" = "♥ Donirajte projektu WireGuard"; +"macTunnelsMenuTitle" = "Tunnels"; diff --git a/Sources/WireGuardApp/tr.lproj/Localizable.strings b/Sources/WireGuardApp/tr.lproj/Localizable.strings index a4ff9363b..f25acc07c 100644 --- a/Sources/WireGuardApp/tr.lproj/Localizable.strings +++ b/Sources/WireGuardApp/tr.lproj/Localizable.strings @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. // Generic alert action names @@ -443,3 +443,4 @@ // Donation "donateLink" = "♥ WireGuard Projesine Bağış Yapın"; +"macTunnelsMenuTitle" = "Tunnels"; diff --git a/Sources/WireGuardApp/zh-Hans.lproj/Localizable.strings b/Sources/WireGuardApp/zh-Hans.lproj/Localizable.strings index ea7ce04b5..58746c6a1 100644 --- a/Sources/WireGuardApp/zh-Hans.lproj/Localizable.strings +++ b/Sources/WireGuardApp/zh-Hans.lproj/Localizable.strings @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. // Generic alert action names @@ -443,3 +443,4 @@ // Donation "donateLink" = "♥ 为 WireGuard 捐赠"; +"macTunnelsMenuTitle" = "Tunnels"; diff --git a/Sources/WireGuardApp/zh-Hant.lproj/Localizable.strings b/Sources/WireGuardApp/zh-Hant.lproj/Localizable.strings index f8de22389..f4c54c1b8 100644 --- a/Sources/WireGuardApp/zh-Hant.lproj/Localizable.strings +++ b/Sources/WireGuardApp/zh-Hant.lproj/Localizable.strings @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2019 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. // Generic alert action names @@ -42,7 +42,7 @@ "newTunnelViewTitle" = "新增設定"; "editTunnelViewTitle" = "修改設定"; -"tunnelSectionTitleStatus" = "ㄓ望太"; +"tunnelSectionTitleStatus" = "狀態"; "tunnelStatusInactive" = "未啟用"; "tunnelStatusActivating" = "啟用中"; @@ -69,6 +69,7 @@ "tunnelInterfaceListenPort" = "監聽埠"; "tunnelInterfaceMTU" = "MTU"; "tunnelInterfaceDNS" = "DNS 伺服器"; +"tunnelInterfaceStatus" = "狀態"; "tunnelEditPlaceholderTextAutomatic" = "自動"; "tunnelHandshakeTimestampNow" = "現在"; @@ -85,6 +86,7 @@ "macMenuCopy" = "複製"; "macMenuPaste" = "貼上"; "macMenuSelectAll" = "全選"; +"macMenuToggleStatus" = "切換狀態"; "macMenuMinimize" = "最小化"; "macMenuDeleteSelected" = "Delete Selected"; "alertSystemErrorMessageTunnelConfigurationInvalid" = "The configuration is invalid."; @@ -162,7 +164,6 @@ "alertUnableToRemovePreviousLogTitle" = "Log export failed"; "alertTunnelActivationFailureMessage" = "The tunnel could not be activated. Please ensure that you are connected to the Internet."; "tunnelOnDemandOptionEthernetOnly" = "Ethernet only"; -"tunnelInterfaceStatus" = "Status"; "macMenuHideOtherApps" = "Hide Others"; "alertCantOpenInputZipFileMessage" = "The zip archive could not be read."; "alertInvalidInterfaceMessagePrivateKeyInvalid" = "Interface’s private key must be a 32-byte key in base64 encoding"; @@ -206,7 +207,6 @@ "alertTunnelDNSFailureTitle" = "DNS resolution failure"; "tunnelOnDemandEthernet" = "Ethernet"; "macLogButtonTitleSave" = "Save…"; -"macMenuToggleStatus" = "Toggle Status"; "deletePeerButtonTitle" = "Delete peer"; "tunnelPeerRxBytes" = "Data received"; "alertCantOpenInputZipFileTitle" = "Unable to read zip archive"; @@ -233,6 +233,7 @@ "macConfirmAndQuitAlertCloseWindow" = "Close Tunnels Manager"; "macMenuFile" = "File"; "macToolTipToggleStatus" = "Toggle status (⌘T)"; +"macTunnelsMenuTitle" = "Tunnels"; "alertTunnelActivationSystemErrorTitle" = "Activation failure"; "alertInvalidInterfaceMessagePrivateKeyRequired" = "Interface’s private key is required"; "tunnelOnDemandAnySSID" = "Any SSID"; diff --git a/Sources/WireGuardKit/Array+ConcurrentMap.swift b/Sources/WireGuardKit/Array+ConcurrentMap.swift index dfe38fdc8..a1720625b 100644 --- a/Sources/WireGuardKit/Array+ConcurrentMap.swift +++ b/Sources/WireGuardKit/Array+ConcurrentMap.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Foundation diff --git a/Sources/WireGuardKit/DNSResolver.swift b/Sources/WireGuardKit/DNSResolver.swift index 7a0f2e916..57f959ac0 100644 --- a/Sources/WireGuardKit/DNSResolver.swift +++ b/Sources/WireGuardKit/DNSResolver.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Network import Foundation diff --git a/Sources/WireGuardKit/DNSServer.swift b/Sources/WireGuardKit/DNSServer.swift index 477bbf4c9..274fec194 100644 --- a/Sources/WireGuardKit/DNSServer.swift +++ b/Sources/WireGuardKit/DNSServer.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Foundation import Network diff --git a/Sources/WireGuardKit/Endpoint.swift b/Sources/WireGuardKit/Endpoint.swift index d86290f27..747548fc1 100644 --- a/Sources/WireGuardKit/Endpoint.swift +++ b/Sources/WireGuardKit/Endpoint.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Foundation import Network @@ -52,6 +52,7 @@ extension Endpoint { let startOfHost = string.index(after: string.startIndex) guard let endOfHost = string.dropFirst().firstIndex(of: "]") else { return nil } let afterEndOfHost = string.index(after: endOfHost) + if afterEndOfHost == string.endIndex { return nil } guard string[afterEndOfHost] == ":" else { return nil } startOfPort = string.index(after: afterEndOfHost) hostString = String(string[startOfHost ..< endOfHost]) diff --git a/Sources/WireGuardKit/IPAddress+AddrInfo.swift b/Sources/WireGuardKit/IPAddress+AddrInfo.swift index 941a57b07..4ade523ff 100644 --- a/Sources/WireGuardKit/IPAddress+AddrInfo.swift +++ b/Sources/WireGuardKit/IPAddress+AddrInfo.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Foundation import Network diff --git a/Sources/WireGuardKit/IPAddressRange.swift b/Sources/WireGuardKit/IPAddressRange.swift index 67c3955bb..28a95d82e 100644 --- a/Sources/WireGuardKit/IPAddressRange.swift +++ b/Sources/WireGuardKit/IPAddressRange.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Foundation import Network @@ -64,4 +64,52 @@ extension IPAddressRange { return (address, networkPrefixLength) } + + public func subnetMask() -> IPAddress { + if address is IPv4Address { + let mask = networkPrefixLength > 0 ? ~UInt32(0) << (32 - networkPrefixLength) : UInt32(0) + let bytes = Data([ + UInt8(truncatingIfNeeded: mask >> 24), + UInt8(truncatingIfNeeded: mask >> 16), + UInt8(truncatingIfNeeded: mask >> 8), + UInt8(truncatingIfNeeded: mask >> 0) + ]) + return IPv4Address(bytes)! + } + if address is IPv6Address { + var bytes = Data(repeating: 0, count: 16) + for i in 0..> 24) + bytes[i + 1] = UInt8(truncatingIfNeeded: mask >> 16) + bytes[i + 2] = UInt8(truncatingIfNeeded: mask >> 8) + bytes[i + 3] = UInt8(truncatingIfNeeded: mask >> 0) + } + return IPv6Address(bytes)! + } + fatalError() + } + + public func maskedAddress() -> IPAddress { + let subnet = subnetMask().rawValue + var masked = Data(address.rawValue) + if subnet.count != masked.count { + fatalError() + } + for i in 0.. String { - let length: UInt8 = addressRange.networkPrefixLength - assert(length <= 32) - var octets: [UInt8] = [0, 0, 0, 0] - let subnetMask: UInt32 = length > 0 ? ~UInt32(0) << (32 - length) : UInt32(0) - octets[0] = UInt8(truncatingIfNeeded: subnetMask >> 24) - octets[1] = UInt8(truncatingIfNeeded: subnetMask >> 16) - octets[2] = UInt8(truncatingIfNeeded: subnetMask >> 8) - octets[3] = UInt8(truncatingIfNeeded: subnetMask) - return octets.map { String($0) }.joined(separator: ".") - } - - private func routes() -> ([NEIPv4Route], [NEIPv6Route]) { + private func addresses() -> ([NEIPv4Route], [NEIPv6Route]) { var ipv4Routes = [NEIPv4Route]() var ipv6Routes = [NEIPv6Route]() for addressRange in tunnelConfiguration.interface.addresses { if addressRange.address is IPv4Address { - ipv4Routes.append(NEIPv4Route(destinationAddress: "\(addressRange.address)", subnetMask: ipv4SubnetMaskString(of: addressRange))) + ipv4Routes.append(NEIPv4Route(destinationAddress: "\(addressRange.address)", subnetMask: "\(addressRange.subnetMask())")) } else if addressRange.address is IPv6Address { /* Big fat ugly hack for broken iOS networking stack: the smallest prefix that will have * any effect on iOS is a /120, so we clamp everything above to /120. This is potentially @@ -160,10 +148,23 @@ class PacketTunnelSettingsGenerator { private func includedRoutes() -> ([NEIPv4Route], [NEIPv6Route]) { var ipv4IncludedRoutes = [NEIPv4Route]() var ipv6IncludedRoutes = [NEIPv6Route]() + + for addressRange in tunnelConfiguration.interface.addresses { + if addressRange.address is IPv4Address { + let route = NEIPv4Route(destinationAddress: "\(addressRange.maskedAddress())", subnetMask: "\(addressRange.subnetMask())") + route.gatewayAddress = "\(addressRange.address)" + ipv4IncludedRoutes.append(route) + } else if addressRange.address is IPv6Address { + let route = NEIPv6Route(destinationAddress: "\(addressRange.maskedAddress())", networkPrefixLength: NSNumber(value: addressRange.networkPrefixLength)) + route.gatewayAddress = "\(addressRange.address)" + ipv6IncludedRoutes.append(route) + } + } + for peer in tunnelConfiguration.peers { for addressRange in peer.allowedIPs { if addressRange.address is IPv4Address { - ipv4IncludedRoutes.append(NEIPv4Route(destinationAddress: "\(addressRange.address)", subnetMask: ipv4SubnetMaskString(of: addressRange))) + ipv4IncludedRoutes.append(NEIPv4Route(destinationAddress: "\(addressRange.address)", subnetMask: "\(addressRange.subnetMask())")) } else if addressRange.address is IPv6Address { ipv6IncludedRoutes.append(NEIPv6Route(destinationAddress: "\(addressRange.address)", networkPrefixLength: NSNumber(value: addressRange.networkPrefixLength))) } diff --git a/Sources/WireGuardKit/PeerConfiguration.swift b/Sources/WireGuardKit/PeerConfiguration.swift index 162a08515..8ef9f56a2 100644 --- a/Sources/WireGuardKit/PeerConfiguration.swift +++ b/Sources/WireGuardKit/PeerConfiguration.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Foundation diff --git a/Sources/WireGuardKit/PrivateKey.swift b/Sources/WireGuardKit/PrivateKey.swift index da02c456b..f98f41d0a 100644 --- a/Sources/WireGuardKit/PrivateKey.swift +++ b/Sources/WireGuardKit/PrivateKey.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Foundation diff --git a/Sources/WireGuardKit/TunnelConfiguration.swift b/Sources/WireGuardKit/TunnelConfiguration.swift index ae41b8217..51574597a 100644 --- a/Sources/WireGuardKit/TunnelConfiguration.swift +++ b/Sources/WireGuardKit/TunnelConfiguration.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Foundation diff --git a/Sources/WireGuardKit/WireGuardAdapter.swift b/Sources/WireGuardKit/WireGuardAdapter.swift index 16e1b283c..4cb2e2ea6 100644 --- a/Sources/WireGuardKit/WireGuardAdapter.swift +++ b/Sources/WireGuardKit/WireGuardAdapter.swift @@ -1,11 +1,12 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Foundation import NetworkExtension #if SWIFT_PACKAGE import WireGuardKitGo +import WireGuardKitC #endif public enum WireGuardAdapterError: Error { @@ -57,12 +58,43 @@ public class WireGuardAdapter { /// Tunnel device file descriptor. private var tunnelFileDescriptor: Int32? { - return self.packetTunnelProvider?.packetFlow.value(forKeyPath: "socket.fileDescriptor") as? Int32 + var ctlInfo = ctl_info() + withUnsafeMutablePointer(to: &ctlInfo.ctl_name) { + $0.withMemoryRebound(to: CChar.self, capacity: MemoryLayout.size(ofValue: $0.pointee)) { + _ = strcpy($0, "com.apple.net.utun_control") + } + } + for fd: Int32 in 0...1024 { + var addr = sockaddr_ctl() + var ret: Int32 = -1 + var len = socklen_t(MemoryLayout.size(ofValue: addr)) + withUnsafeMutablePointer(to: &addr) { + $0.withMemoryRebound(to: sockaddr.self, capacity: 1) { + ret = getpeername(fd, $0, &len) + } + } + if ret != 0 || addr.sc_family != AF_SYSTEM { + continue + } + if ctlInfo.ctl_id == 0 { + ret = ioctl(fd, CTLIOCGINFO, &ctlInfo) + if ret != 0 { + continue + } + } + if addr.sc_id == ctlInfo.ctl_id { + return fd + } + } + return nil } /// Returns a WireGuard version. class var backendVersion: String { - return String(cString: wgVersion()) + guard let ver = wgVersion() else { return "unknown" } + let str = String(cString: ver) + free(UnsafeMutableRawPointer(mutating: ver)) + return str } /// Returns the tunnel device interface name, or nil on error. @@ -265,7 +297,7 @@ public class WireGuardAdapter { .takeUnretainedValue() let swiftString = String(cString: message).trimmingCharacters(in: .newlines) - let tunnelLogLevel = WireGuardLogLevel(rawValue: logLevel) ?? .debug + let tunnelLogLevel = WireGuardLogLevel(rawValue: logLevel) ?? .verbose unretainedSelf.logHandler(tunnelLogLevel, swiftString) } @@ -369,9 +401,9 @@ public class WireGuardAdapter { switch result { case .success((let sourceEndpoint, let resolvedEndpoint)): if sourceEndpoint.host == resolvedEndpoint.host { - self.logHandler(.debug, "DNS64: mapped \(sourceEndpoint.host) to itself.") + self.logHandler(.verbose, "DNS64: mapped \(sourceEndpoint.host) to itself.") } else { - self.logHandler(.debug, "DNS64: mapped \(sourceEndpoint.host) to \(resolvedEndpoint.host)") + self.logHandler(.verbose, "DNS64: mapped \(sourceEndpoint.host) to \(resolvedEndpoint.host)") } case .failure(let resolutionError): self.logHandler(.error, "Failed to resolve endpoint \(resolutionError.address): \(resolutionError.errorDescription ?? "(nil)")") @@ -382,7 +414,7 @@ public class WireGuardAdapter { /// Helper method used by network path monitor. /// - Parameter path: new network path private func didReceivePathUpdate(path: Network.NWPath) { - self.logHandler(.debug, "Network change detected with \(path.status) route and interface order \(path.availableInterfaces)") + self.logHandler(.verbose, "Network change detected with \(path.status) route and interface order \(path.availableInterfaces)") #if os(macOS) if case .started(let handle, _) = self.state { @@ -399,7 +431,7 @@ public class WireGuardAdapter { wgDisableSomeRoamingForBrokenMobileSemantics(handle) wgBumpSockets(handle) } else { - self.logHandler(.info, "Connectivity offline, pausing backend.") + self.logHandler(.verbose, "Connectivity offline, pausing backend.") self.state = .temporaryShutdown(settingsGenerator) wgTurnOff(handle) @@ -408,7 +440,7 @@ public class WireGuardAdapter { case .temporaryShutdown(let settingsGenerator): guard path.status.isSatisfiable else { return } - self.logHandler(.info, "Connectivity online, resuming backend.") + self.logHandler(.verbose, "Connectivity online, resuming backend.") do { try self.setNetworkSettings(settingsGenerator.generateNetworkSettings()) @@ -434,11 +466,10 @@ public class WireGuardAdapter { } } -/// A enum describing WireGuard log levels defined in `api-ios.go`. +/// A enum describing WireGuard log levels defined in `api-apple.go`. public enum WireGuardLogLevel: Int32 { - case debug = 0 - case info = 1 - case error = 2 + case verbose = 0 + case error = 1 } private extension Network.NWPath.Status { diff --git a/Sources/WireGuardKitC/WireGuardKitC.h b/Sources/WireGuardKitC/WireGuardKitC.h index d50a4fe61..980a157a5 100644 --- a/Sources/WireGuardKitC/WireGuardKitC.h +++ b/Sources/WireGuardKitC/WireGuardKitC.h @@ -1,5 +1,28 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. #include "key.h" #include "x25519.h" + +/* From */ + + +#ifndef WIREGUARDKITC_H_INCLUDED +#define WIREGUARDKITC_H_INCLUDED + +#define CTLIOCGINFO 0xc0644e03UL + +struct ctl_info { + u_int32_t ctl_id; + char ctl_name[96]; +}; +struct sockaddr_ctl { + u_char sc_len; + u_char sc_family; + u_int16_t ss_sysaddr; + u_int32_t sc_id; + u_int32_t sc_unit; + u_int32_t sc_reserved[5]; +}; + +#endif diff --git a/Sources/WireGuardKitGo/Makefile b/Sources/WireGuardKitGo/Makefile index d7a0d1508..3fc90c0de 100644 --- a/Sources/WireGuardKitGo/Makefile +++ b/Sources/WireGuardKitGo/Makefile @@ -3,9 +3,9 @@ # Copyright (C) 2018-2019 Jason A. Donenfeld . All Rights Reserved. # These are generally passed to us by xcode, but we set working defaults for standalone compilation too. -ARCHS ?= x86_64 arm64 #TODO: add arm64 to this list once we support apple silicon -SDK_NAME ?= macosx -SDKROOT ?= $(shell xcrun --sdk $(SDK_NAME) --show-sdk-path) +ARCHS ?= x86_64 arm64 +PLATFORM_NAME ?= macosx +SDKROOT ?= $(shell xcrun --sdk $(PLATFORM_NAME) --show-sdk-path) CONFIGURATION_BUILD_DIR ?= $(CURDIR)/out CONFIGURATION_TEMP_DIR ?= $(CURDIR)/.tmp @@ -17,6 +17,9 @@ BUILDDIR ?= $(CONFIGURATION_TEMP_DIR)/wireguard-go-bridge CFLAGS_PREFIX := $(if $(DEPLOYMENT_TARGET_CLANG_FLAG_NAME),-$(DEPLOYMENT_TARGET_CLANG_FLAG_NAME)=$($(DEPLOYMENT_TARGET_CLANG_ENV_NAME)),) -isysroot $(SDKROOT) -arch GOARCH_arm64 := arm64 GOARCH_x86_64 := amd64 +GOOS_macosx := darwin +GOOS_iphoneos := ios +GOOS_iphonesimulator := ios build: $(DESTDIR)/libwg-go.a version-header: $(DESTDIR)/wireguard-go-version.h @@ -34,16 +37,16 @@ define libwg-go-a $(BUILDDIR)/libwg-go-$(1).a: export CGO_ENABLED := 1 $(BUILDDIR)/libwg-go-$(1).a: export CGO_CFLAGS := $(CFLAGS_PREFIX) $(ARCH) $(BUILDDIR)/libwg-go-$(1).a: export CGO_LDFLAGS := $(CFLAGS_PREFIX) $(ARCH) -$(BUILDDIR)/libwg-go-$(1).a: export GOOS := darwin +$(BUILDDIR)/libwg-go-$(1).a: export GOOS := $(GOOS_$(PLATFORM_NAME)) $(BUILDDIR)/libwg-go-$(1).a: export GOARCH := $(GOARCH_$(1)) $(BUILDDIR)/libwg-go-$(1).a: $(GOROOT)/.prepared go.mod - go build -tags ios -ldflags=-w -trimpath -v -o "$(BUILDDIR)/libwg-go-$(1).a" -buildmode c-archive + go build -ldflags=-w -trimpath -v -o "$(BUILDDIR)/libwg-go-$(1).a" -buildmode c-archive rm -f "$(BUILDDIR)/libwg-go-$(1).h" endef $(foreach ARCH,$(ARCHS),$(eval $(call libwg-go-a,$(ARCH)))) -$(DESTDIR)/wireguard-go-version.h: $(GOROOT)/.prepared go.mod - go list -m golang.zx2c4.com/wireguard | sed -n 's/.*v\([0-9.]*\).*/#define WIREGUARD_GO_VERSION "\1"/p' > "$@" +$(DESTDIR)/wireguard-go-version.h: go.mod $(GOROOT)/.prepared + sed -E -n 's/.*golang\.zx2c4\.com\/wireguard +v[0-9.]+-[0-9]+-([0-9a-f]{8})[0-9a-f]{4}.*/#define WIREGUARD_GO_VERSION "\1"/p' "$<" > "$@" $(DESTDIR)/libwg-go.a: $(foreach ARCH,$(ARCHS),$(BUILDDIR)/libwg-go-$(ARCH).a) @mkdir -vp "$(DESTDIR)" diff --git a/Sources/WireGuardKitGo/api-ios.go b/Sources/WireGuardKitGo/api-apple.go similarity index 67% rename from Sources/WireGuardKitGo/api-ios.go rename to Sources/WireGuardKitGo/api-apple.go index 0f924c5f1..5d24982ac 100644 --- a/Sources/WireGuardKitGo/api-ios.go +++ b/Sources/WireGuardKitGo/api-apple.go @@ -14,39 +14,41 @@ package main import "C" import ( - "bufio" - "bytes" - "errors" - "log" + "fmt" "math" "os" "os/signal" "runtime" + "runtime/debug" "strings" "time" "unsafe" "golang.org/x/sys/unix" + "golang.zx2c4.com/wireguard/conn" "golang.zx2c4.com/wireguard/device" "golang.zx2c4.com/wireguard/tun" ) var loggerFunc unsafe.Pointer var loggerCtx unsafe.Pointer -var versionString *C.char -type CLogger struct { - level C.int +type CLogger int + +func cstring(s string) *C.char { + b, err := unix.BytePtrFromString(s) + if err != nil { + b := [1]C.char{} + return &b[0] + } + return (*C.char)(unsafe.Pointer(b)) } -func (l *CLogger) Write(p []byte) (int, error) { +func (l CLogger) Printf(format string, args ...interface{}) { if uintptr(loggerFunc) == 0 { - return 0, errors.New("No logger initialized") + return } - message := C.CString(string(p)) - C.callLogger(loggerFunc, loggerCtx, l.level, message) - C.free(unsafe.Pointer(message)) - return len(p), nil + C.callLogger(loggerFunc, loggerCtx, C.int(l), cstring(fmt.Sprintf(format, args...))) } type tunnelHandle struct { @@ -57,7 +59,6 @@ type tunnelHandle struct { var tunnelHandles = make(map[int32]tunnelHandle) func init() { - versionString = C.CString(device.WireGuardGoVersion) signals := make(chan os.Signal) signal.Notify(signals, unix.SIGUSR2) go func() { @@ -84,40 +85,39 @@ func wgSetLogger(context, loggerFn uintptr) { //export wgTurnOn func wgTurnOn(settings *C.char, tunFd int32) int32 { logger := &device.Logger{ - Debug: log.New(&CLogger{level: 0}, "", 0), - Info: log.New(&CLogger{level: 1}, "", 0), - Error: log.New(&CLogger{level: 2}, "", 0), + Verbosef: CLogger(0).Printf, + Errorf: CLogger(1).Printf, } dupTunFd, err := unix.Dup(int(tunFd)) if err != nil { - logger.Error.Println(err) + logger.Errorf("Unable to dup tun fd: %v", err) return -1 } err = unix.SetNonblock(dupTunFd, true) if err != nil { - logger.Error.Println(err) + logger.Errorf("Unable to set tun fd as non blocking: %v", err) unix.Close(dupTunFd) return -1 } tun, err := tun.CreateTUNFromFile(os.NewFile(uintptr(dupTunFd), "/dev/tun"), 0) if err != nil { - logger.Error.Println(err) + logger.Errorf("Unable to create new tun device from fd: %v", err) unix.Close(dupTunFd) return -1 } - logger.Info.Println("Attaching to interface") - dev := device.NewDevice(tun, logger) + logger.Verbosef("Attaching to interface") + dev := device.NewDevice(tun, conn.NewStdNetBind(), logger) - setError := dev.IpcSetOperation(bufio.NewReader(strings.NewReader(C.GoString(settings)))) - if setError != nil { - logger.Error.Println(setError) + err = dev.IpcSet(C.GoString(settings)) + if err != nil { + logger.Errorf("Unable to set IPC settings: %v", err) unix.Close(dupTunFd) return -1 } dev.Up() - logger.Info.Println("Device started") + logger.Verbosef("Device started") var i int32 for i = 0; i < math.MaxInt32; i++ { @@ -149,9 +149,9 @@ func wgSetConfig(tunnelHandle int32, settings *C.char) int64 { if !ok { return 0 } - err := dev.IpcSetOperation(bufio.NewReader(strings.NewReader(C.GoString(settings)))) + err := dev.IpcSet(C.GoString(settings)) if err != nil { - dev.Error.Println(err) + dev.Errorf("Unable to set IPC settings: %v", err) if ipcErr, ok := err.(*device.IPCError); ok { return ipcErr.ErrorCode() } @@ -166,14 +166,11 @@ func wgGetConfig(tunnelHandle int32) *C.char { if !ok { return nil } - settings := new(bytes.Buffer) - writer := bufio.NewWriter(settings) - err := device.IpcGetOperation(writer) + settings, err := device.IpcGet() if err != nil { return nil } - writer.Flush() - return C.CString(settings.String()) + return C.CString(settings) } //export wgBumpSockets @@ -189,10 +186,10 @@ func wgBumpSockets(tunnelHandle int32) { dev.SendKeepalivesToPeersWithCurrentKeypair() return } - dev.Error.Printf("Unable to update bind, try %d: %v", i+1, err) + dev.Errorf("Unable to update bind, try %d: %v", i+1, err) time.Sleep(time.Second / 2) } - dev.Error.Println("Gave up trying to update bind; tunnel is likely dysfunctional") + dev.Errorf("Gave up trying to update bind; tunnel is likely dysfunctional") }() } @@ -207,7 +204,20 @@ func wgDisableSomeRoamingForBrokenMobileSemantics(tunnelHandle int32) { //export wgVersion func wgVersion() *C.char { - return versionString + info, ok := debug.ReadBuildInfo() + if !ok { + return C.CString("unknown") + } + for _, dep := range info.Deps { + if dep.Path == "golang.zx2c4.com/wireguard" { + parts := strings.Split(dep.Version, "-") + if len(parts) == 3 && len(parts[2]) == 12 { + return C.CString(parts[2][:7]) + } + return C.CString(dep.Version) + } + } + return C.CString("unknown") } func main() {} diff --git a/Sources/WireGuardKitGo/go.mod b/Sources/WireGuardKitGo/go.mod index f40bfdaa6..594eba175 100644 --- a/Sources/WireGuardKitGo/go.mod +++ b/Sources/WireGuardKitGo/go.mod @@ -1,10 +1,10 @@ -module golang.zx2c4.com/wireguard/ios +module golang.zx2c4.com/wireguard/apple -go 1.15 +go 1.16 require ( - golang.org/x/crypto v0.0.0-20201217014255-9d1352758620 // indirect - golang.org/x/net v0.0.0-20201216054612-986b41b23924 // indirect - golang.org/x/sys v0.0.0-20201218084310-7d0127a74742 - golang.zx2c4.com/wireguard v0.0.20201119-0.20201218223923-756958d857f8 + golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a // indirect + golang.org/x/net v0.0.0-20210614182718-04defd469f4e // indirect + golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 + golang.zx2c4.com/wireguard v0.0.0-20210604143328-f9b48a961cd2 ) diff --git a/Sources/WireGuardKitGo/go.sum b/Sources/WireGuardKitGo/go.sum index c8b077c2a..5aa6aba22 100644 --- a/Sources/WireGuardKitGo/go.sum +++ b/Sources/WireGuardKitGo/go.sum @@ -1,24 +1,23 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201124201722-c8d3bf9c5392/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20201217014255-9d1352758620 h1:3wPMTskHO3+O6jqTEXyFcsnuxMQOqYSaHsDxcbUXpqA= -golang.org/x/crypto v0.0.0-20201217014255-9d1352758620/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a h1:kr2P4QFmQr29mSLA43kwrOcgcReGTfbE9N577tCTuBc= +golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201216054612-986b41b23924 h1:QsnDpLLOKwHBBDa8nDws4DYNc/ryVW2vCpxCs09d4PY= -golang.org/x/net v0.0.0-20201216054612-986b41b23924/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q= +golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201126233918-771906719818/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201218084310-7d0127a74742 h1:+CBz4km/0KPU3RGTwARGh/noP3bEwtHcq+0YcBQM2JQ= -golang.org/x/sys v0.0.0-20201218084310-7d0127a74742/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 h1:RqytpXGR1iVNX7psjB3ff8y7sNFinVFvkx1c8SjBkio= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.zx2c4.com/wireguard v0.0.20201119-0.20201218223923-756958d857f8 h1:1FB1AE+gTFqSXTn9XlVks3iwRVUHB7OtUmpw/qf2Llg= -golang.zx2c4.com/wireguard v0.0.20201119-0.20201218223923-756958d857f8/go.mod h1:ITsWNpkFv78VPB7f8MiyuxeEMcHR4jfxHGCJLPP3GHs= +golang.zx2c4.com/wireguard v0.0.0-20210604143328-f9b48a961cd2 h1:wfOOSvHgIzTZ9h5Vb6yUFZNn7uf3bT7PeYsHOO7tYDM= +golang.zx2c4.com/wireguard v0.0.0-20210604143328-f9b48a961cd2/go.mod h1:laHzsbfMhGSobUmruXWAyMKKHSqvIcrqZJMyHD+/3O8= diff --git a/Sources/WireGuardKitGo/goruntime-boottime-over-monotonic.diff b/Sources/WireGuardKitGo/goruntime-boottime-over-monotonic.diff index d5212ef95..2f7f54edd 100644 --- a/Sources/WireGuardKitGo/goruntime-boottime-over-monotonic.diff +++ b/Sources/WireGuardKitGo/goruntime-boottime-over-monotonic.diff @@ -1,4 +1,4 @@ -From aa85e0f90c9031ff5be32296e9fed1637a2eceae Mon Sep 17 00:00:00 2001 +From 516dc0c15ff1ab781e0677606b5be72919251b3e Mon Sep 17 00:00:00 2001 From: "Jason A. Donenfeld" Date: Wed, 9 Dec 2020 14:07:06 +0100 Subject: [PATCH] runtime: use libc_mach_continuous_time in nanotime on Darwin @@ -18,23 +18,23 @@ Change-Id: Ia3282e8bd86f95ad2b76427063e60a005563f4eb 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/runtime/sys_darwin.go b/src/runtime/sys_darwin.go -index 06474434c9..6f7ca37122 100644 +index 4a3f2fc453..4a69403b32 100644 --- a/src/runtime/sys_darwin.go +++ b/src/runtime/sys_darwin.go -@@ -469,7 +469,7 @@ func setNonblock(fd int32) { +@@ -440,7 +440,7 @@ func setNonblock(fd int32) { //go:cgo_import_dynamic libc_usleep usleep "/usr/lib/libSystem.B.dylib" //go:cgo_import_dynamic libc_mach_timebase_info mach_timebase_info "/usr/lib/libSystem.B.dylib" -//go:cgo_import_dynamic libc_mach_absolute_time mach_absolute_time "/usr/lib/libSystem.B.dylib" +//go:cgo_import_dynamic libc_mach_continuous_time mach_continuous_time "/usr/lib/libSystem.B.dylib" - //go:cgo_import_dynamic libc_gettimeofday gettimeofday "/usr/lib/libSystem.B.dylib" + //go:cgo_import_dynamic libc_clock_gettime clock_gettime "/usr/lib/libSystem.B.dylib" //go:cgo_import_dynamic libc_sigaction sigaction "/usr/lib/libSystem.B.dylib" //go:cgo_import_dynamic libc_pthread_sigmask pthread_sigmask "/usr/lib/libSystem.B.dylib" diff --git a/src/runtime/sys_darwin_amd64.s b/src/runtime/sys_darwin_amd64.s -index 825852d673..5a8b994fb1 100644 +index 630fb5df64..4499c88802 100644 --- a/src/runtime/sys_darwin_amd64.s +++ b/src/runtime/sys_darwin_amd64.s -@@ -109,7 +109,7 @@ TEXT runtime·nanotime_trampoline(SB),NOSPLIT,$0 +@@ -114,7 +114,7 @@ TEXT runtime·nanotime_trampoline(SB),NOSPLIT,$0 PUSHQ BP MOVQ SP, BP MOVQ DI, BX @@ -44,10 +44,10 @@ index 825852d673..5a8b994fb1 100644 MOVL timebase<>+machTimebaseInfo_numer(SB), SI MOVL timebase<>+machTimebaseInfo_denom(SB), DI // atomic read diff --git a/src/runtime/sys_darwin_arm64.s b/src/runtime/sys_darwin_arm64.s -index 585d4f2c64..c556d88730 100644 +index 96d2ed1076..f046545395 100644 --- a/src/runtime/sys_darwin_arm64.s +++ b/src/runtime/sys_darwin_arm64.s -@@ -135,7 +135,7 @@ GLOBL timebase<>(SB),NOPTR,$(machTimebaseInfo__size) +@@ -143,7 +143,7 @@ GLOBL timebase<>(SB),NOPTR,$(machTimebaseInfo__size) TEXT runtime·nanotime_trampoline(SB),NOSPLIT,$40 MOVD R0, R19 @@ -57,5 +57,5 @@ index 585d4f2c64..c556d88730 100644 MOVW timebase<>+machTimebaseInfo_numer(SB), R20 MOVD $timebase<>+machTimebaseInfo_denom(SB), R21 -- -2.29.2 +2.30.1 diff --git a/Sources/WireGuardKitGo/wireguard.h b/Sources/WireGuardKitGo/wireguard.h index b49464e60..21ab4f95b 100644 --- a/Sources/WireGuardKitGo/wireguard.h +++ b/Sources/WireGuardKitGo/wireguard.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 * - * Copyright (C) 2018-2020 WireGuard LLC. All Rights Reserved. + * Copyright (C) 2018-2021 WireGuard LLC. All Rights Reserved. */ #ifndef WIREGUARD_H diff --git a/Sources/WireGuardNetworkExtension/ErrorNotifier.swift b/Sources/WireGuardNetworkExtension/ErrorNotifier.swift index de4265c25..a9794549c 100644 --- a/Sources/WireGuardNetworkExtension/ErrorNotifier.swift +++ b/Sources/WireGuardNetworkExtension/ErrorNotifier.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import NetworkExtension diff --git a/Sources/WireGuardNetworkExtension/PacketTunnelProvider.swift b/Sources/WireGuardNetworkExtension/PacketTunnelProvider.swift index 9ea630821..8cc73d396 100644 --- a/Sources/WireGuardNetworkExtension/PacketTunnelProvider.swift +++ b/Sources/WireGuardNetworkExtension/PacketTunnelProvider.swift @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. import Foundation import NetworkExtension @@ -111,10 +111,8 @@ class PacketTunnelProvider: NEPacketTunnelProvider { extension WireGuardLogLevel { var osLogLevel: OSLogType { switch self { - case .debug: + case .verbose: return .debug - case .info: - return .info case .error: return .error } diff --git a/WireGuard.xcodeproj/project.pbxproj b/WireGuard.xcodeproj/project.pbxproj index ec7e876c8..69eac8897 100644 --- a/WireGuard.xcodeproj/project.pbxproj +++ b/WireGuard.xcodeproj/project.pbxproj @@ -342,23 +342,7 @@ 6F6483E6229293300075BA15 /* LaunchedAtLoginDetector.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LaunchedAtLoginDetector.swift; sourceTree = ""; }; 6F689999218043390012E523 /* WireGuard-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "WireGuard-Bridging-Header.h"; sourceTree = ""; }; 6F70E20D221058DF008BDFB4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Sources/WireGuardApp/Base.lproj/InfoPlist.strings; sourceTree = ""; }; - 6F70E20D221058DF008BDFB5 /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = Sources/WireGuardApp/fr.lproj/Localizable.strings; sourceTree = ""; }; - 6F70E20D221058DF008BDFB6 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = Sources/WireGuardApp/pl.lproj/Localizable.strings; sourceTree = ""; }; - 6F70E20D221058DF008BDFB7 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = Sources/WireGuardApp/es.lproj/Localizable.strings; sourceTree = ""; }; - 6F70E20D221058DF008BDFB8 /* ca */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ca; path = Sources/WireGuardApp/ca.lproj/Localizable.strings; sourceTree = ""; }; - 6F70E20D221058DF008BDFB9 /* pa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pa; path = Sources/WireGuardApp/pa.lproj/Localizable.strings; sourceTree = ""; }; 6F70E20D221058DF008BDFBA /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "Sources/WireGuardApp/zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; - 6F70E20D221058DF008BDFBB /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = Sources/WireGuardApp/ja.lproj/Localizable.strings; sourceTree = ""; }; - 6F70E20D221058DF008BDFBC /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = Sources/WireGuardApp/it.lproj/Localizable.strings; sourceTree = ""; }; - 6F70E20D221058DF008BDFBD /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = Sources/WireGuardApp/ro.lproj/Localizable.strings; sourceTree = ""; }; - 6F70E20D221058DF008BDFBE /* fa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fa; path = Sources/WireGuardApp/fa.lproj/Localizable.strings; sourceTree = ""; }; - 6F70E20D221058DF008BDFBF /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = Sources/WireGuardApp/fi.lproj/Localizable.strings; sourceTree = ""; }; - 6F70E20D221058DF008BDFC0 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = Sources/WireGuardApp/ru.lproj/Localizable.strings; sourceTree = ""; }; - 6F70E20D221058DF008BDFC1 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = Sources/WireGuardApp/ko.lproj/Localizable.strings; sourceTree = ""; }; - 6F70E20D221058DF008BDFC2 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = Sources/WireGuardApp/tr.lproj/Localizable.strings; sourceTree = ""; }; - 6F70E20D221058DF008BDFC3 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = Sources/WireGuardApp/de.lproj/Localizable.strings; sourceTree = ""; }; - 6F70E20D221058DF008BDFC4 /* sl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sl; path = Sources/WireGuardApp/sl.lproj/Localizable.strings; sourceTree = ""; }; - 6F70E20D221058DF008BDFC5 /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = id; path = Sources/WireGuardApp/id.lproj/Localizable.strings; sourceTree = ""; }; 6F70E20D221058DF008BDFC6 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "Sources/WireGuardApp/zh-Hant.lproj/Localizable.strings"; sourceTree = ""; }; 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 = ""; }; @@ -414,6 +398,24 @@ 6FDEF801218646B900D8FBF6 /* ZipArchive.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ZipArchive.swift; sourceTree = ""; }; 6FDEF805218725D200D8FBF6 /* SettingsTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsTableViewController.swift; sourceTree = ""; }; 6FE1765521C90BBE002690EA /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Sources/WireGuardApp/Base.lproj/Localizable.strings; sourceTree = ""; }; + 6FE1765521C90BBE002690FC /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = zh-Hant; path = Sources/WireGuardApp/zh-Hant.lproj/Localizable.strings; sourceTree = ""; }; + 6FE1765521C90BBE002690F0 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = zh-Hans; path = Sources/WireGuardApp/zh-Hans.lproj/Localizable.strings; sourceTree = ""; }; + 6FE1765521C90BBE002690FB /* id */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = id; path = Sources/WireGuardApp/id.lproj/Localizable.strings; sourceTree = ""; }; + 6FE1765521C90BBE002690F2 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = Sources/WireGuardApp/it.lproj/Localizable.strings; sourceTree = ""; }; + 6FE1765521C90BBE002690F9 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = Sources/WireGuardApp/de.lproj/Localizable.strings; sourceTree = ""; }; + 6FE1765521C90BBE002690EB /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = Sources/WireGuardApp/fr.lproj/Localizable.strings; sourceTree = ""; }; + 6FE1765521C90BBE002690F5 /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = Sources/WireGuardApp/fi.lproj/Localizable.strings; sourceTree = ""; }; + 6FE1765521C90BBE002690F4 /* fa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fa; path = Sources/WireGuardApp/fa.lproj/Localizable.strings; sourceTree = ""; }; + 6FE1765521C90BBE002690FA /* sl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sl; path = Sources/WireGuardApp/sl.lproj/Localizable.strings; sourceTree = ""; }; + 6FE1765521C90BBE002690EC /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = Sources/WireGuardApp/pl.lproj/Localizable.strings; sourceTree = ""; }; + 6FE1765521C90BBE002690EF /* pa */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pa; path = Sources/WireGuardApp/pa.lproj/Localizable.strings; sourceTree = ""; }; + 6FE1765521C90BBE002690F7 /* ko */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ko; path = Sources/WireGuardApp/ko.lproj/Localizable.strings; sourceTree = ""; }; + 6FE1765521C90BBE002690EE /* ca */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ca; path = Sources/WireGuardApp/ca.lproj/Localizable.strings; sourceTree = ""; }; + 6FE1765521C90BBE002690F6 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = Sources/WireGuardApp/ru.lproj/Localizable.strings; sourceTree = ""; }; + 6FE1765521C90BBE002690F3 /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = Sources/WireGuardApp/ro.lproj/Localizable.strings; sourceTree = ""; }; + 6FE1765521C90BBE002690F8 /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = Sources/WireGuardApp/tr.lproj/Localizable.strings; sourceTree = ""; }; + 6FE1765521C90BBE002690F1 /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = Sources/WireGuardApp/ja.lproj/Localizable.strings; sourceTree = ""; }; + 6FE1765521C90BBE002690ED /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = Sources/WireGuardApp/es.lproj/Localizable.strings; sourceTree = ""; }; 6FE1765921C90E87002690EA /* LocalizationHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalizationHelper.swift; sourceTree = ""; }; 6FE254FA219C10800028284D /* ZipImporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZipImporter.swift; sourceTree = ""; }; 6FE254FE219C60290028284D /* ZipExporter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZipExporter.swift; sourceTree = ""; }; @@ -1499,24 +1501,24 @@ 6FE1765421C90BBE002690EA /* Localizable.strings */ = { isa = PBXVariantGroup; children = ( - 6F70E20D221058DF008BDFC6 /* zh-Hant */, - 6F70E20D221058DF008BDFBA /* zh-Hans */, - 6F70E20D221058DF008BDFC5 /* id */, - 6F70E20D221058DF008BDFBC /* it */, - 6F70E20D221058DF008BDFC3 /* de */, - 6F70E20D221058DF008BDFB5 /* fr */, - 6F70E20D221058DF008BDFBF /* fi */, - 6F70E20D221058DF008BDFBE /* fa */, - 6F70E20D221058DF008BDFC4 /* sl */, - 6F70E20D221058DF008BDFB6 /* pl */, - 6F70E20D221058DF008BDFB9 /* pa */, - 6F70E20D221058DF008BDFC1 /* ko */, - 6F70E20D221058DF008BDFB8 /* ca */, - 6F70E20D221058DF008BDFC0 /* ru */, - 6F70E20D221058DF008BDFBD /* ro */, - 6F70E20D221058DF008BDFC2 /* tr */, - 6F70E20D221058DF008BDFBB /* ja */, - 6F70E20D221058DF008BDFB7 /* es */, + 6FE1765521C90BBE002690FC /* zh-Hant */, + 6FE1765521C90BBE002690F0 /* zh-Hans */, + 6FE1765521C90BBE002690FB /* id */, + 6FE1765521C90BBE002690F2 /* it */, + 6FE1765521C90BBE002690F9 /* de */, + 6FE1765521C90BBE002690EB /* fr */, + 6FE1765521C90BBE002690F5 /* fi */, + 6FE1765521C90BBE002690F4 /* fa */, + 6FE1765521C90BBE002690FA /* sl */, + 6FE1765521C90BBE002690EC /* pl */, + 6FE1765521C90BBE002690EF /* pa */, + 6FE1765521C90BBE002690F7 /* ko */, + 6FE1765521C90BBE002690EE /* ca */, + 6FE1765521C90BBE002690F6 /* ru */, + 6FE1765521C90BBE002690F3 /* ro */, + 6FE1765521C90BBE002690F8 /* tr */, + 6FE1765521C90BBE002690F1 /* ja */, + 6FE1765521C90BBE002690ED /* es */, 6FE1765521C90BBE002690EA /* Base */, ); name = Localizable.strings; diff --git a/WireGuard.xcodeproj/xcshareddata/IDETemplateMacros.plist b/WireGuard.xcodeproj/xcshareddata/IDETemplateMacros.plist index 648700526..9d877823c 100644 --- a/WireGuard.xcodeproj/xcshareddata/IDETemplateMacros.plist +++ b/WireGuard.xcodeproj/xcshareddata/IDETemplateMacros.plist @@ -4,6 +4,6 @@ FILEHEADER SPDX-License-Identifier: MIT -// Copyright © 2018-2020 WireGuard LLC. All Rights Reserved. +// Copyright © 2018-2021 WireGuard LLC. All Rights Reserved. diff --git a/sync-translations.sh b/sync-translations.sh index c855aabe1..968a44671 100755 --- a/sync-translations.sh +++ b/sync-translations.sh @@ -23,7 +23,7 @@ done < Sources/WireGuardApp/Base.lproj/Localizable.strings git add Sources/WireGuardApp/*.lproj declare -A LOCALE_MAP -[[ $(< WireGuard.xcodeproj/project.pbxproj) =~ [[:space:]]([0-9A-F]{24})\ /\*\ Base\ \*/, ]] +[[ $(< WireGuard.xcodeproj/project.pbxproj) =~ [[:space:]]([0-9A-F]{24})\ /\*\ Base\ \*/\ =\ [^$'\n']*Base\.lproj/Localizable\.strings ]] base_id="${BASH_REMATCH[1]:0:16}" idx=$(( "0x${BASH_REMATCH[1]:16}" )) while read -r filename; do