diff options
Diffstat (limited to 'main/src')
182 files changed, 20623 insertions, 0 deletions
diff --git a/main/src/main/AndroidManifest.xml b/main/src/main/AndroidManifest.xml new file mode 100644 index 00000000..7043e94b --- /dev/null +++ b/main/src/main/AndroidManifest.xml @@ -0,0 +1,175 @@ +<?xml version="1.0" encoding="utf-8"?> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + package="de.blinkt.openvpn"> + + <uses-permission android:name="android.permission.INTERNET" /> + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> + <!-- <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> --> + <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> + <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> + + <uses-permission android:name="com.android.vending.BILLING" /> + + <!-- Copy the <permission> block to your app when using the REMOTE API. Otherwise OpenVPN for + Android needs to be installed first --> + <permission + android:name="de.blinkt.openvpn.REMOTE_API" + android:description="@string/permission_description" + android:label="Control OpenVPN" + android:permissionGroup="android.permission-group.NETWORK" + android:protectionLevel="dangerous" /> + + <application + android:allowBackup="true" + android:theme="@android:style/Theme.DeviceDefault.Light" + android:icon="@drawable/icon" + android:label="@string/app" + android:name=".core.ICSOpenVPNApplication" + android:supportsRtl="true" > + <activity + android:name=".activities.VPNPreferences" + android:windowSoftInputMode="stateHidden" + android:exported="false"/> + + <activity + android:theme="@android:style/Theme.DeviceDefault.Light.Dialog" + android:name=".activities.DisconnectVPN" /> + + <activity + android:name=".activities.LogWindow" + android:allowTaskReparenting="true" + android:label="@string/openvpn_log" + android:launchMode="singleTask" /> + <activity android:name=".activities.FileSelect" /> + <activity + android:name=".activities.MainActivity" + android:uiOptions="splitActionBarWhenNarrow" + tools:ignore="ExportedActivity" > + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + + <category android:name="android.intent.category.BROWSABLE" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + + <service + android:name="de.blinkt.openvpn.core.OpenVpnService" + android:permission="android.permission.BIND_VPN_SERVICE" > + <intent-filter> + <action android:name="android.net.VpnService" /> + </intent-filter> + </service> + <service + android:name=".api.ExternalOpenVPNService" + android:permission="de.blinkt.openvpn.REMOTE_API" > + <intent-filter> + <action android:name="de.blinkt.openvpn.api.IOpenVPNAPIService" /> + </intent-filter> + </service> + + <activity + android:permission="de.blinkt.openvpn.REMOTE_API" + android:name=".api.GrantPermissionsActivity"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + </intent-filter> + </activity> + <activity + android:permission="de.blinkt.openvpn.REMOTE_API" + android:name=".api.ConfirmDialog" > + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + </intent-filter> + </activity> + + <receiver android:name=".OnBootReceiver" > + <intent-filter> + <action android:name="android.intent.action.BOOT_COMPLETED" /> + </intent-filter> + </receiver> + + <activity + android:name=".activities.ConfigConverter" + android:label="Convert Config File" + android:uiOptions="splitActionBarWhenNarrow" + tools:ignore="ExportedActivity" > + <intent-filter android:label="@string/import_config" > + <action android:name="android.intent.action.VIEW" /> + + <category android:name="android.intent.category.DEFAULT" /> + <category android:name="android.intent.category.BROWSABLE" /> + + <data android:mimeType="application/x-openvpn-profile" /> + </intent-filter> + <intent-filter android:label="@string/import_config" > + <action android:name="android.intent.action.VIEW" /> + + <category android:name="android.intent.category.DEFAULT" /> + <category android:name="android.intent.category.BROWSABLE" /> + + <data android:mimeType="application/ovpn" /> + </intent-filter> + <intent-filter android:label="@string/import_config" > + + <!-- http://stackoverflow.com/questions/7030832/associating-certain-file-extension-to-my-android-application/7102838#7102838 --> + <action android:name="android.intent.action.VIEW" /> + + <category android:name="android.intent.category.BROWSABLE" /> + <category android:name="android.intent.category.DEFAULT" /> + + <data android:mimeType="*/*" /> + <data android:scheme="file" /> + <data android:host="*" /> + <data android:port="*" /> + <data android:pathPattern=".*..*..*..*..*.ovpn" /> + <data android:pathPattern=".*..*..*..*.ovpn" /> + <data android:pathPattern=".*..*..*.ovpn" /> + <data android:pathPattern=".*..*.ovpn" /> + <data android:pathPattern=".*.ovpn" /> + </intent-filter> + </activity> + <activity + android:name=".LaunchVPN" + android:label="@string/vpn_launch_title" + android:excludeFromRecents="true" + android:theme="@android:style/Theme.DeviceDefault.Light.Panel" + tools:ignore="ExportedActivity" > + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </activity> + + + <activity + android:name=".activities.CreateShortcuts" + android:label="@string/vpn_shortcut" + android:excludeFromRecents="true" + android:theme="@android:style/Theme.DeviceDefault.Light.DialogWhenLarge" > + <intent-filter> + <action android:name="android.intent.action.CREATE_SHORTCUT" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </activity> + + <provider + android:name=".FileProvider" + android:authorities="de.blinkt.openvpn.FileProvider" + android:exported="true" + android:grantUriPermissions="true" + tools:ignore="ExportedContentProvider" /> + + <!-- + <receiver android:name="core.GetRestrictionReceiver"> + <intent-filter> + <action android:name="android.intent.action.GET_RESTRICTION_ENTRIES" /> + </intent-filter> + </receiver> + --> + </application> + +</manifest> diff --git a/main/src/main/aidl/com/android/vending/billing/IInAppBillingService.aidl b/main/src/main/aidl/com/android/vending/billing/IInAppBillingService.aidl new file mode 100644 index 00000000..2a492f78 --- /dev/null +++ b/main/src/main/aidl/com/android/vending/billing/IInAppBillingService.aidl @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.vending.billing; + +import android.os.Bundle; + +/** + * InAppBillingService is the service that provides in-app billing version 3 and beyond. + * This service provides the following features: + * 1. Provides a new API to get details of in-app items published for the app including + * price, type, title and description. + * 2. The purchase flow is synchronous and purchase information is available immediately + * after it completes. + * 3. Purchase information of in-app purchases is maintained within the Google Play system + * till the purchase is consumed. + * 4. An API to consume a purchase of an inapp item. All purchases of one-time + * in-app items are consumable and thereafter can be purchased again. + * 5. An API to get current purchases of the user immediately. This will not contain any + * consumed purchases. + * + * All calls will give a response code with the following possible values + * RESULT_OK = 0 - success + * RESULT_USER_CANCELED = 1 - user pressed back or canceled a dialog + * RESULT_BILLING_UNAVAILABLE = 3 - this billing API version is not supported for the type requested + * RESULT_ITEM_UNAVAILABLE = 4 - requested SKU is not available for purchase + * RESULT_DEVELOPER_ERROR = 5 - invalid arguments provided to the API + * RESULT_ERROR = 6 - Fatal error during the API action + * RESULT_ITEM_ALREADY_OWNED = 7 - Failure to purchase since item is already owned + * RESULT_ITEM_NOT_OWNED = 8 - Failure to consume since item is not owned + */ +interface IInAppBillingService { + /** + * Checks support for the requested billing API version, package and in-app type. + * Minimum API version supported by this interface is 3. + * @param apiVersion the billing version which the app is using + * @param packageName the package name of the calling app + * @param type type of the in-app item being purchased "inapp" for one-time purchases + * and "subs" for subscription. + * @return RESULT_OK(0) on success, corresponding result code on failures + */ + int isBillingSupported(int apiVersion, String packageName, String type); + + /** + * Provides details of a list of SKUs + * Given a list of SKUs of a valid type in the skusBundle, this returns a bundle + * with a list JSON strings containing the productId, price, title and description. + * This API can be called with a maximum of 20 SKUs. + * @param apiVersion billing API version that the Third-party is using + * @param packageName the package name of the calling app + * @param skusBundle bundle containing a StringArrayList of SKUs with key "ITEM_ID_LIST" + * @return Bundle containing the following key-value pairs + * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on + * failure as listed above. + * "DETAILS_LIST" with a StringArrayList containing purchase information + * in JSON format similar to: + * '{ "productId" : "exampleSku", "type" : "inapp", "price" : "$5.00", + * "title : "Example Title", "description" : "This is an example description" }' + */ + Bundle getSkuDetails(int apiVersion, String packageName, String type, in Bundle skusBundle); + + /** + * Returns a pending intent to launch the purchase flow for an in-app item by providing a SKU, + * the type, a unique purchase token and an optional developer payload. + * @param apiVersion billing API version that the app is using + * @param packageName package name of the calling app + * @param sku the SKU of the in-app item as published in the developer console + * @param type the type of the in-app item ("inapp" for one-time purchases + * and "subs" for subscription). + * @param developerPayload optional argument to be sent back with the purchase information + * @return Bundle containing the following key-value pairs + * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on + * failure as listed above. + * "BUY_INTENT" - PendingIntent to start the purchase flow + * + * The Pending intent should be launched with startIntentSenderForResult. When purchase flow + * has completed, the onActivityResult() will give a resultCode of OK or CANCELED. + * If the purchase is successful, the result data will contain the following key-value pairs + * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on + * failure as listed above. + * "INAPP_PURCHASE_DATA" - String in JSON format similar to + * '{"orderId":"12999763169054705758.1371079406387615", + * "packageName":"com.example.app", + * "productId":"exampleSku", + * "purchaseTime":1345678900000, + * "purchaseToken" : "122333444455555", + * "developerPayload":"example developer payload" }' + * "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that + * was signed with the private key of the developer + * TODO: change this to app-specific keys. + */ + Bundle getBuyIntent(int apiVersion, String packageName, String sku, String type, + String developerPayload); + + /** + * Returns the current SKUs owned by the user of the type and package name specified along with + * purchase information and a signature of the data to be validated. + * This will return all SKUs that have been purchased in V3 and managed items purchased using + * V1 and V2 that have not been consumed. + * @param apiVersion billing API version that the app is using + * @param packageName package name of the calling app + * @param type the type of the in-app items being requested + * ("inapp" for one-time purchases and "subs" for subscription). + * @param continuationToken to be set as null for the first call, if the number of owned + * skus are too many, a continuationToken is returned in the response bundle. + * This method can be called again with the continuation token to get the next set of + * owned skus. + * @return Bundle containing the following key-value pairs + * "RESPONSE_CODE" with int value, RESULT_OK(0) if success, other response codes on + * failure as listed above. + * "INAPP_PURCHASE_ITEM_LIST" - StringArrayList containing the list of SKUs + * "INAPP_PURCHASE_DATA_LIST" - StringArrayList containing the purchase information + * "INAPP_DATA_SIGNATURE_LIST"- StringArrayList containing the signatures + * of the purchase information + * "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the + * next set of in-app purchases. Only set if the + * user has more owned skus than the current list. + */ + Bundle getPurchases(int apiVersion, String packageName, String type, String continuationToken); + + /** + * Consume the last purchase of the given SKU. This will result in this item being removed + * from all subsequent responses to getPurchases() and allow re-purchase of this item. + * @param apiVersion billing API version that the app is using + * @param packageName package name of the calling app + * @param purchaseToken token in the purchase information JSON that identifies the purchase + * to be consumed + * @return 0 if consumption succeeded. Appropriate error values for failures. + */ + int consumePurchase(int apiVersion, String packageName, String purchaseToken); +} diff --git a/main/src/main/aidl/de/blinkt/openvpn/api/APIVpnProfile.aidl b/main/src/main/aidl/de/blinkt/openvpn/api/APIVpnProfile.aidl new file mode 100644 index 00000000..f6799659 --- /dev/null +++ b/main/src/main/aidl/de/blinkt/openvpn/api/APIVpnProfile.aidl @@ -0,0 +1,3 @@ +package de.blinkt.openvpn.api; + +parcelable APIVpnProfile; diff --git a/main/src/main/aidl/de/blinkt/openvpn/api/IOpenVPNAPIService.aidl b/main/src/main/aidl/de/blinkt/openvpn/api/IOpenVPNAPIService.aidl new file mode 100644 index 00000000..794e3aad --- /dev/null +++ b/main/src/main/aidl/de/blinkt/openvpn/api/IOpenVPNAPIService.aidl @@ -0,0 +1,50 @@ +// IOpenVPNAPIService.aidl
+package de.blinkt.openvpn.api;
+
+import de.blinkt.openvpn.api.APIVpnProfile;
+import de.blinkt.openvpn.api.IOpenVPNStatusCallback;
+
+import android.content.Intent;
+import android.os.ParcelFileDescriptor;
+
+interface IOpenVPNAPIService {
+ List<APIVpnProfile> getProfiles();
+
+ void startProfile (String profileUUID);
+
+ /** Use a profile with all certificates etc. embedded */
+ boolean addVPNProfile (String name, String config);
+
+ /** start a profile using an config */
+ void startVPN (String inlineconfig);
+
+ /** This permission framework is used to avoid confused deputy style attack to the VPN
+ * calling this will give null if the app is allowed to use the external API and an Intent
+ * that can be launched to request permissions otherwise */
+ Intent prepare (String packagename);
+
+ /** Used to trigger to the Android VPN permission dialog (VPNService.prepare()) in advance,
+ * if this return null OpenVPN for ANdroid already has the permissions otherwise you can start the returned Intent
+ * to let OpenVPN for Android request the permission */
+ Intent prepareVPNService ();
+
+ /* Disconnect the VPN */
+ void disconnect();
+
+ /* Pause the VPN (same as using the pause feature in the notifcation bar) */
+ void pause();
+
+ /* Resume the VPN (same as using the pause feature in the notifcation bar) */
+ void resume();
+
+ /**
+ * Registers to receive OpenVPN Status Updates
+ */
+ void registerStatusCallback(IOpenVPNStatusCallback cb);
+
+ /**
+ * Remove a previously registered callback interface.
+ */
+ void unregisterStatusCallback(IOpenVPNStatusCallback cb);
+
+}
\ No newline at end of file diff --git a/main/src/main/aidl/de/blinkt/openvpn/api/IOpenVPNStatusCallback.aidl b/main/src/main/aidl/de/blinkt/openvpn/api/IOpenVPNStatusCallback.aidl new file mode 100644 index 00000000..1dfa1381 --- /dev/null +++ b/main/src/main/aidl/de/blinkt/openvpn/api/IOpenVPNStatusCallback.aidl @@ -0,0 +1,13 @@ +package de.blinkt.openvpn.api;
+
+/**
+ * Example of a callback interface used by IRemoteService to send
+ * synchronous notifications back to its clients. Note that this is a
+ * one-way interface so the server does not block waiting for the client.
+ */
+oneway interface IOpenVPNStatusCallback {
+ /**
+ * Called when the service has a new status for you.
+ */
+ void newStatus(String uuid, String state, String message, String level);
+}
diff --git a/main/src/main/assets/full_licenses.html b/main/src/main/assets/full_licenses.html new file mode 100644 index 00000000..468c2db9 --- /dev/null +++ b/main/src/main/assets/full_licenses.html @@ -0,0 +1,279 @@ +<h2 id="ics-openvpn">OpenVPN for Android</h2> +<p> +The name ics-openvpn and OpenVPN for Android refer to the same program. +OpenVPN for Android is distributed under the GPL license version 2 (see Below) +<p/> +<p> Special exception for linking ics-openvpn with OpenSSL:</p> + +<p> In addition, as a special exception, Arne Schwabe gives + permission to link the code of this program with the OpenSSL + library (or with modified versions of OpenSSL that use the same + license as OpenSSL), and distribute linked combinations including + the two. You must obey the GNU General Public License in all + respects for all of the code used other than OpenSSL. If you modify + this file, you may extend this exception to your version of the + file, but you are not obligated to do so. If you do not wish to + do so, delete this exception statement from your version.</p> + +<h2 id="lzo">LZO license</h2> +<p> LZO is Copyright (C) Markus F.X.J. Oberhumer, + and is licensed under the GPL.</p> + +<p> Special exception for linking OpenVPN with both OpenSSL and LZO:</p> + +<p> Hereby I grant a special exception to the OpenVPN project + (http://openvpn.net/) to link the LZO library with + the OpenSSL library (http://www.openssl.org). + + Markus F.X.J. Oberhumer +</p> +<h2> Google Breakpad</h2> + <p>Copyright (c) 2006, Google Inc.<br /> + All rights reserved.</p> + + <p>Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:</p> + + <p>1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.</p> + <p>2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.</p> + <p>3. Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.</p> + + <p>THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</p> + +<h2>Boncy Castle</h2> +<p> +Copyright (c) 2000-2013 The Legion Of The Bouncy Castle (http://www.bouncycastle.org) +<p> +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 the Software without restriction, +including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: +<p> +The above copyright notice and this permission notice shall be included in all copies or substantial +portions of the Software. +<p> +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. + + + <h2 id="GPL2">GPL Version 2, June 1991</h2> + + <p>Copyright (C) 1989, 1991 Free Software Foundation, Inc.<br /> + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA</p> + + <p>Everyone is permitted to copy and distribute verbatim copies<br /> + of this license document, but changing it is not allowed.</p> + + <p><strong>Preamble</strong></p> + + <p>The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too.</p> + + <p>When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things.</p> + + <p>To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it.</p> + + <p>For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights.</p> + + <p>We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software.</p> + + <p>Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations.</p> + + <p>Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all.</p> + + <p>The precise terms and conditions for copying, distribution and modification follow.</p> + + <p><strong>TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</strong></p> + + <p><strong>0</strong>. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you".</p> + + <p>Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does.</p> + + <p><strong>1</strong>. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program.</p> + + <p>You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.</p> + + <p><strong>2</strong>. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:</p> + + <blockquote> + <p>a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change.</p> + + <p>b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License.</p> + + <p>c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.)</p> + </blockquote> + + <p>These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.</p> + + <p>Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program.</p> + + <p>In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.</p> + + <p><strong>3</strong>. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following:</p> + + <blockquote> + <p>a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,</p> + + <p>b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or,</p> + + <p>c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.)</p> + </blockquote> + + <p>The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.</p> + + <p>If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code.</p> + + <p><strong>4</strong>. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.</p> + + <p><strong>5</strong>. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it.</p> + + <p><strong>6</strong>. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License.</p> + + <p><strong>7</strong>. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program.</p> + + <p>If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances.</p> + + <p>It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.</p> + + <p>This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.</p> + + <p><strong>8</strong>. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.</p> + + <p><strong>9</strong>. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.</p> + + <p>Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation.</p> + + <p><strong>10</strong>. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.</p> + + <p><strong>NO WARRANTY</strong></p> + + <p><strong>11</strong>. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.</p> + + <p><strong>12</strong>. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.</p> + +<p>END OF TERMS AND CONDITIONS</p> + +<h2 id="#openssl">OpenSSL</h2> +<p> The OpenSSL toolkit stays under a dual license, i.e. both the conditions of + the OpenSSL License and the original SSLeay license apply to the toolkit. + See below for the actual license texts. Actually both licenses are BSD-style + Open Source licenses. In case of any license issues related to OpenSSL + please contact openssl-core@openssl.org.</p> +<pre> +/* ==================================================================== + * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +</pre> + +<h3> Original SSLeay License</h3> +<pre> +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +</pre> diff --git a/main/src/main/java/de/blinkt/openvpn/FileProvider.java b/main/src/main/java/de/blinkt/openvpn/FileProvider.java new file mode 100644 index 00000000..9ffd6545 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/FileProvider.java @@ -0,0 +1,140 @@ +package de.blinkt.openvpn; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; + +import android.content.ContentProvider; +import android.content.ContentProvider.PipeDataWriter; +import android.content.ContentValues; +import android.content.res.AssetFileDescriptor; +import android.database.Cursor; +import android.database.MatrixCursor; +import android.net.Uri; +import android.os.Bundle; +import android.os.ParcelFileDescriptor; +import android.provider.OpenableColumns; +import android.util.Log; +import de.blinkt.openvpn.core.VpnStatus; + +/** + * A very simple content provider that can serve arbitrary asset files from + * our .apk. + */ +public class FileProvider extends ContentProvider +implements PipeDataWriter<InputStream> { + @Override + public boolean onCreate() { + return true; + } + + @Override + public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, + String sortOrder) { + try { + File dumpfile = getFileFromURI(uri); + + + MatrixCursor c = new MatrixCursor(projection); + + Object[] row = new Object[projection.length]; + int i=0; + for (String r:projection) { + if(r.equals(OpenableColumns.SIZE)) + row[i] = dumpfile.length(); + if(r.equals(OpenableColumns.DISPLAY_NAME)) + row[i] = dumpfile.getName(); + i++; + } + c.addRow(row); + return c; + } catch (FileNotFoundException e) { + VpnStatus.logException(e); + return null; + } + + + } + + @Override + public Uri insert(Uri uri, ContentValues values) { + // Don't support inserts. + return null; + } + + @Override + public int delete(Uri uri, String selection, String[] selectionArgs) { + // Don't support deletes. + return 0; + } + + @Override + public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { + // Don't support updates. + return 0; + } + + @Override + public String getType(Uri uri) { + // For this sample, assume all files are .apks. + return "application/octet-stream"; + } + + @Override + public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException { + File dumpfile = getFileFromURI(uri); + + try { + + InputStream is = new FileInputStream(dumpfile); + // Start a new thread that pipes the stream data back to the caller. + return new AssetFileDescriptor( + openPipeHelper(uri, null, null, is, this), 0, + dumpfile.length()); + } catch (IOException e) { + throw new FileNotFoundException("Unable to open minidump " + uri); + } + } + + private File getFileFromURI(Uri uri) throws FileNotFoundException { + // Try to open an asset with the given name. + String path = uri.getPath(); + if(path.startsWith("/")) + path = path.replaceFirst("/", ""); + + // I think this already random enough, no need for magic secure cookies + // 1f9563a4-a1f5-2165-255f2219-111823ef.dmp + if (!path.matches("^[0-9a-z-.]*(dmp|dmp.log)$")) + throw new FileNotFoundException("url not in expect format " + uri); + File cachedir = getContext().getCacheDir(); + return new File(cachedir,path); + } + + @Override + public void writeDataToPipe(ParcelFileDescriptor output, Uri uri, String mimeType, + Bundle opts, InputStream args) { + // Transfer data from the asset to the pipe the client is reading. + byte[] buffer = new byte[8192]; + int n; + FileOutputStream fout = new FileOutputStream(output.getFileDescriptor()); + try { + while ((n=args.read(buffer)) >= 0) { + fout.write(buffer, 0, n); + } + } catch (IOException e) { + Log.i("OpenVPNFileProvider", "Failed transferring", e); + } finally { + try { + args.close(); + } catch (IOException e) { + } + try { + fout.close(); + } catch (IOException e) { + } + } + } +} diff --git a/main/src/main/java/de/blinkt/openvpn/LaunchVPN.java b/main/src/main/java/de/blinkt/openvpn/LaunchVPN.java new file mode 100644 index 00000000..7aed4e4a --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/LaunchVPN.java @@ -0,0 +1,295 @@ +package de.blinkt.openvpn; + +import java.io.IOException; + +import android.app.Activity; +import android.app.AlertDialog; +import android.content.ActivityNotFoundException; +import android.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; +import android.content.Intent; +import android.content.SharedPreferences; +import android.net.VpnService; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.text.InputType; +import android.text.TextUtils; +import android.text.method.PasswordTransformationMethod; +import android.view.View; +import android.widget.*; + +import de.blinkt.openvpn.activities.LogWindow; +import de.blinkt.openvpn.core.VpnStatus; +import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus; +import de.blinkt.openvpn.core.ProfileManager; +import de.blinkt.openvpn.core.VPNLaunchHelper; + +/** + * This Activity actually handles two stages of a launcher shortcut's life cycle. + * + * 1. Your application offers to provide shortcuts to the launcher. When + * the user installs a shortcut, an activity within your application + * generates the actual shortcut and returns it to the launcher, where it + * is shown to the user as an icon. + * + * 2. Any time the user clicks on an installed shortcut, an intent is sent. + * Typically this would then be handled as necessary by an activity within + * your application. + * + * We handle stage 1 (creating a shortcut) by simply sending back the information (in the form + * of an {@link android.content.Intent} that the launcher will use to create the shortcut. + * + * You can also implement this in an interactive way, by having your activity actually present + * UI for the user to select the specific nature of the shortcut, such as a contact, picture, URL, + * media item, or action. + * + * We handle stage 2 (responding to a shortcut) in this sample by simply displaying the contents + * of the incoming {@link android.content.Intent}. + * + * In a real application, you would probably use the shortcut intent to display specific content + * or start a particular operation. + */ +public class LaunchVPN extends Activity { + + public static final String EXTRA_KEY = "de.blinkt.openvpn.shortcutProfileUUID"; + public static final String EXTRA_NAME = "de.blinkt.openvpn.shortcutProfileName"; + public static final String EXTRA_HIDELOG = "de.blinkt.openvpn.showNoLogWindow"; + + private static final int START_VPN_PROFILE= 70; + + + private ProfileManager mPM; + private VpnProfile mSelectedProfile; + private boolean mhideLog=false; + + private boolean mCmfixed=false; + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + + mPM =ProfileManager.getInstance(this); + + } + + @Override + protected void onStart() { + super.onStart(); + // Resolve the intent + + final Intent intent = getIntent(); + final String action = intent.getAction(); + + // If the intent is a request to create a shortcut, we'll do that and exit + + + if(Intent.ACTION_MAIN.equals(action)) { + // we got called to be the starting point, most likely a shortcut + String shortcutUUID = intent.getStringExtra( EXTRA_KEY); + String shortcutName = intent.getStringExtra( EXTRA_NAME); + mhideLog = intent.getBooleanExtra(EXTRA_HIDELOG, false); + + VpnProfile profileToConnect = ProfileManager.get(this,shortcutUUID); + if(shortcutName != null && profileToConnect ==null) + profileToConnect = ProfileManager.getInstance(this).getProfileByName(shortcutName); + + if(profileToConnect ==null) { + VpnStatus.logError(R.string.shortcut_profile_notfound); + // show Log window to display error + showLogWindow(); + finish(); + return; + } + + mSelectedProfile = profileToConnect; + launchVPN(); + + } + } + + private void askForPW(final int type) { + + final EditText entry = new EditText(this); + final View userpwlayout = getLayoutInflater().inflate(R.layout.userpass, null); + + entry.setSingleLine(); + entry.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); + entry.setTransformationMethod(new PasswordTransformationMethod()); + + AlertDialog.Builder dialog = new AlertDialog.Builder(this); + dialog.setTitle("Need " + getString(type)); + dialog.setMessage("Enter the password for profile " + mSelectedProfile.mName); + + if (type == R.string.password) { + ((EditText)userpwlayout.findViewById(R.id.username)).setText(mSelectedProfile.mUsername); + ((EditText)userpwlayout.findViewById(R.id.password)).setText(mSelectedProfile.mPassword); + ((CheckBox)userpwlayout.findViewById(R.id.save_password)).setChecked(!TextUtils.isEmpty(mSelectedProfile.mPassword)); + ((CheckBox)userpwlayout.findViewById(R.id.show_password)).setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if (isChecked) + ((EditText)userpwlayout.findViewById(R.id.password)).setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD); + else + ((EditText)userpwlayout.findViewById(R.id.password)).setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); + } + }); + + dialog.setView(userpwlayout); + } else { + dialog.setView(entry); + } + + AlertDialog.Builder builder = dialog.setPositiveButton(android.R.string.ok, + new OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + + if (type == R.string.password) { + mSelectedProfile.mUsername = ((EditText) userpwlayout.findViewById(R.id.username)).getText().toString(); + + String pw = ((EditText) userpwlayout.findViewById(R.id.password)).getText().toString(); + if (((CheckBox) userpwlayout.findViewById(R.id.save_password)).isChecked()) { + mSelectedProfile.mPassword=pw; + } else { + mSelectedProfile.mPassword=null; + mSelectedProfile.mTransientPW = pw; + } + } else { + mSelectedProfile.mTransientPCKS12PW = entry.getText().toString(); + } + onActivityResult(START_VPN_PROFILE, Activity.RESULT_OK, null); + + } + + }); + dialog.setNegativeButton(android.R.string.cancel, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + VpnStatus.updateStateString("USER_VPN_PASSWORD_CANCELLED", "", R.string.state_user_vpn_password_cancelled, + ConnectionStatus.LEVEL_NOTCONNECTED); + finish(); + } + }); + + dialog.create().show(); + + } + @Override + protected void onActivityResult (int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + + if(requestCode==START_VPN_PROFILE) { + if(resultCode == Activity.RESULT_OK) { + int needpw = mSelectedProfile.needUserPWInput(); + if(needpw !=0) { + VpnStatus.updateStateString("USER_VPN_PASSWORD", "", R.string.state_user_vpn_password, + ConnectionStatus.LEVEL_WAITING_FOR_USER_INPUT); + askForPW(needpw); + } else { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + boolean showlogwindow = prefs.getBoolean("showlogwindow", true); + + if(!mhideLog && showlogwindow) + showLogWindow(); + new startOpenVpnThread().start(); + } + } else if (resultCode == Activity.RESULT_CANCELED) { + // User does not want us to start, so we just vanish + VpnStatus.updateStateString("USER_VPN_PERMISSION_CANCELLED", "", R.string.state_user_vpn_permission_cancelled, + ConnectionStatus.LEVEL_NOTCONNECTED); + + finish(); + } + } + } + void showLogWindow() { + + Intent startLW = new Intent(getBaseContext(),LogWindow.class); + startLW.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); + startActivity(startLW); + + } + + void showConfigErrorDialog(int vpnok) { + AlertDialog.Builder d = new AlertDialog.Builder(this); + d.setTitle(R.string.config_error_found); + d.setMessage(vpnok); + d.setPositiveButton(android.R.string.ok, new OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + finish(); + + } + }); + d.show(); + } + + void launchVPN () { + int vpnok = mSelectedProfile.checkProfile(this); + if(vpnok!= R.string.no_error_found) { + showConfigErrorDialog(vpnok); + return; + } + + Intent intent = VpnService.prepare(this); + // Check if we want to fix /dev/tun + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + boolean usecm9fix = prefs.getBoolean("useCM9Fix", false); + boolean loadTunModule = prefs.getBoolean("loadTunModule", false); + + if(loadTunModule) + execeuteSUcmd("insmod /system/lib/modules/tun.ko"); + + if(usecm9fix && !mCmfixed ) { + execeuteSUcmd("chown system /dev/tun"); + } + + + if (intent != null) { + VpnStatus.updateStateString("USER_VPN_PERMISSION", "", R.string.state_user_vpn_permission, + ConnectionStatus.LEVEL_WAITING_FOR_USER_INPUT); + // Start the query + try { + startActivityForResult(intent, START_VPN_PROFILE); + } catch (ActivityNotFoundException ane) { + // Shame on you Sony! At least one user reported that + // an official Sony Xperia Arc S image triggers this exception + VpnStatus.logError(R.string.no_vpn_support_image); + showLogWindow(); + } + } else { + onActivityResult(START_VPN_PROFILE, Activity.RESULT_OK, null); + } + + } + + private void execeuteSUcmd(String command) { + ProcessBuilder pb = new ProcessBuilder("su","-c",command); + try { + Process p = pb.start(); + int ret = p.waitFor(); + if(ret ==0) + mCmfixed=true; + } catch (InterruptedException e) { + VpnStatus.logException("SU command", e); + + } catch (IOException e) { + VpnStatus.logException("SU command", e); + } + } + + private class startOpenVpnThread extends Thread { + + @Override + public void run() { + VPNLaunchHelper.startOpenVpn(mSelectedProfile, getBaseContext()); + finish(); + + } + + } + + +} diff --git a/main/src/main/java/de/blinkt/openvpn/OnBootReceiver.java b/main/src/main/java/de/blinkt/openvpn/OnBootReceiver.java new file mode 100644 index 00000000..32d14b1b --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/OnBootReceiver.java @@ -0,0 +1,34 @@ +package de.blinkt.openvpn; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import de.blinkt.openvpn.core.ProfileManager; + + +public class OnBootReceiver extends BroadcastReceiver { + + // Debug: am broadcast -a android.intent.action.BOOT_COMPLETED + @Override + public void onReceive(Context context, Intent intent) { + + final String action = intent.getAction(); + + if(Intent.ACTION_BOOT_COMPLETED.equals(action)) { + VpnProfile bootProfile = ProfileManager.getOnBootProfile(context); + if(bootProfile != null) { + launchVPN(bootProfile, context); + } + } + } + + void launchVPN(VpnProfile profile, Context context) { + Intent startVpnIntent = new Intent(Intent.ACTION_MAIN); + startVpnIntent.setClass(context, LaunchVPN.class); + startVpnIntent.putExtra(LaunchVPN.EXTRA_KEY,profile.getUUIDString()); + startVpnIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startVpnIntent.putExtra(LaunchVPN.EXTRA_HIDELOG, true); + + context.startActivity(startVpnIntent); + } +} diff --git a/main/src/main/java/de/blinkt/openvpn/VpnProfile.java b/main/src/main/java/de/blinkt/openvpn/VpnProfile.java new file mode 100644 index 00000000..1ec34b51 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/VpnProfile.java @@ -0,0 +1,947 @@ +package de.blinkt.openvpn; + +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.os.Build; +import android.preference.PreferenceManager; +import android.security.KeyChain; +import android.security.KeyChainException; +import android.util.Base64; + +import de.blinkt.openvpn.core.NativeUtils; +import de.blinkt.openvpn.core.VpnStatus; +import de.blinkt.openvpn.core.OpenVpnService; +import de.blinkt.openvpn.core.X509Utils; +import org.spongycastle.util.io.pem.PemObject; +import org.spongycastle.util.io.pem.PemWriter; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.NoSuchPaddingException; +import java.io.*; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.Collection; +import java.util.Locale; +import java.util.UUID; +import java.util.Vector; + +public class VpnProfile implements Serializable { + // Note that this class cannot be moved to core where it belongs since + // the profile loading depends on it being here + // The Serializable documentation mentions that class name change are possible + // but the how is unclear + // + transient public static final long MAX_EMBED_FILE_SIZE = 2048*1024; // 2048kB + // Don't change this, not all parts of the program use this constant + public static final String EXTRA_PROFILEUUID = "de.blinkt.openvpn.profileUUID"; + public static final String INLINE_TAG = "[[INLINE]]"; + public static final String DISPLAYNAME_TAG = "[[NAME]]"; + public static final String MINIVPN = "miniopenvpn"; + private static final long serialVersionUID = 7085688938959334563L; + private static final String OVPNCONFIGFILE = "android.conf"; + public static final int MAXLOGLEVEL = 4; + public static final int CURRENT_PROFILE_VERSION = 2; + public static String DEFAULT_DNS1 = "8.8.8.8"; + public static String DEFAULT_DNS2 = "8.8.4.4"; + + public transient String mTransientPW = null; + public transient String mTransientPCKS12PW = null; + + + public static final int TYPE_CERTIFICATES = 0; + public static final int TYPE_PKCS12 = 1; + public static final int TYPE_KEYSTORE = 2; + public static final int TYPE_USERPASS = 3; + public static final int TYPE_STATICKEYS = 4; + public static final int TYPE_USERPASS_CERTIFICATES = 5; + public static final int TYPE_USERPASS_PKCS12 = 6; + public static final int TYPE_USERPASS_KEYSTORE = 7; + public static final int X509_VERIFY_TLSREMOTE = 0; + public static final int X509_VERIFY_TLSREMOTE_COMPAT_NOREMAPPING = 1; + public static final int X509_VERIFY_TLSREMOTE_DN = 2; + public static final int X509_VERIFY_TLSREMOTE_RDN = 3; + public static final int X509_VERIFY_TLSREMOTE_RDN_PREFIX = 4; + // variable named wrong and should haven beeen transient + // but needs to keep wrong name to guarante loading of old + // profiles + public transient boolean profileDleted = false; + public int mAuthenticationType = TYPE_KEYSTORE; + public String mName; + public String mAlias; + public String mClientCertFilename; + public String mTLSAuthDirection = ""; + public String mTLSAuthFilename; + public String mClientKeyFilename; + public String mCaFilename; + public boolean mUseLzo = true; + public String mServerPort = "1194"; + public boolean mUseUdp = true; + public String mPKCS12Filename; + public String mPKCS12Password; + public boolean mUseTLSAuth = false; + public String mServerName = "openvpn.blinkt.de"; + public String mDNS1 = DEFAULT_DNS1; + public String mDNS2 = DEFAULT_DNS2; + public String mIPv4Address; + public String mIPv6Address; + public boolean mOverrideDNS = false; + public String mSearchDomain = "blinkt.de"; + public boolean mUseDefaultRoute = true; + public boolean mUsePull = true; + public String mCustomRoutes; + public boolean mCheckRemoteCN = false; + public boolean mExpectTLSCert = true; + public String mRemoteCN = ""; + public String mPassword = ""; + public String mUsername = ""; + public boolean mRoutenopull = false; + public boolean mUseRandomHostname = false; + public boolean mUseFloat = false; + public boolean mUseCustomConfig = false; + public String mCustomConfigOptions = ""; + public String mVerb = "1"; //ignored + public String mCipher = ""; + public boolean mNobind = false; + public boolean mUseDefaultRoutev6 = true; + public String mCustomRoutesv6 = ""; + public String mKeyPassword = ""; + public boolean mPersistTun = false; + public String mConnectRetryMax = "5"; + public String mConnectRetry = "5"; + public boolean mUserEditable = true; + public String mAuth = ""; + public int mX509AuthType = X509_VERIFY_TLSREMOTE_RDN; + private transient PrivateKey mPrivateKey; + // Public attributes, since I got mad with getter/setter + // set members to default values + private UUID mUuid; + public boolean mAllowLocalLAN; + private int mProfileVersion; + public String mExcludedRoutes; + public String mExcludedRoutesv6; + + public VpnProfile(String name) { + mUuid = UUID.randomUUID(); + mName = name; + mProfileVersion = CURRENT_PROFILE_VERSION; + } + + public static String openVpnEscape(String unescaped) { + if (unescaped == null) + return null; + String escapedString = unescaped.replace("\\", "\\\\"); + escapedString = escapedString.replace("\"", "\\\""); + escapedString = escapedString.replace("\n", "\\n"); + + if (escapedString.equals(unescaped) && !escapedString.contains(" ") && !escapedString.contains("#")) + return unescaped; + else + return '"' + escapedString + '"'; + } + + public void clearDefaults() { + mServerName = "unknown"; + mUsePull = false; + mUseLzo = false; + mUseDefaultRoute = false; + mUseDefaultRoutev6 = false; + mExpectTLSCert = false; + mPersistTun = false; + mAllowLocalLAN = true; + } + + public UUID getUUID() { + return mUuid; + + } + + public String getName() { + if (mName==null) + return "No profile name"; + return mName; + } + + public void upgradeProfile(){ + if(mProfileVersion< 2) { + /* default to the behaviour the OS used */ + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) + mAllowLocalLAN = true; + else + mAllowLocalLAN = false; + } + + mProfileVersion= CURRENT_PROFILE_VERSION; + } + + public String getConfigFile(Context context, boolean configForOvpn3) { + + File cacheDir = context.getCacheDir(); + String cfg = ""; + + // Enable managment interface + cfg += "# Enables connection to GUI\n"; + cfg += "management "; + + cfg += cacheDir.getAbsolutePath() + "/" + "mgmtsocket"; + cfg += " unix\n"; + cfg += "management-client\n"; + // Not needed, see updated man page in 2.3 + //cfg += "management-signal\n"; + cfg += "management-query-passwords\n"; + cfg += "management-hold\n\n"; + cfg += getVersionEnvString(context); + + cfg += "machine-readable-output\n"; + + + boolean useTLSClient = (mAuthenticationType != TYPE_STATICKEYS); + + if (useTLSClient && mUsePull) + cfg += "client\n"; + else if (mUsePull) + cfg += "pull\n"; + else if (useTLSClient) + cfg += "tls-client\n"; + + + //cfg += "verb " + mVerb + "\n"; + cfg += "verb " + MAXLOGLEVEL + "\n"; + + if (mConnectRetryMax == null) { + mConnectRetryMax = "5"; + } + + if (!mConnectRetryMax.equals("-1")) + cfg += "connect-retry-max " + mConnectRetryMax + "\n"; + + if (mConnectRetry == null) + mConnectRetry = "5"; + + + cfg += "connect-retry " + mConnectRetry + "\n"; + + cfg += "resolv-retry 60\n"; + + + // We cannot use anything else than tun + cfg += "dev tun\n"; + + // Server Address + cfg += "remote "; + cfg += mServerName; + cfg += " "; + cfg += mServerPort; + if (mUseUdp) + cfg += " udp\n"; + else + cfg += " tcp-client\n"; + + + switch (mAuthenticationType) { + case VpnProfile.TYPE_USERPASS_CERTIFICATES: + cfg += "auth-user-pass\n"; + case VpnProfile.TYPE_CERTIFICATES: + // Ca + cfg += insertFileData("ca", mCaFilename); + + // Client Cert + Key + cfg += insertFileData("key", mClientKeyFilename); + cfg += insertFileData("cert", mClientCertFilename); + + break; + case VpnProfile.TYPE_USERPASS_PKCS12: + cfg += "auth-user-pass\n"; + case VpnProfile.TYPE_PKCS12: + cfg += insertFileData("pkcs12", mPKCS12Filename); + break; + + case VpnProfile.TYPE_USERPASS_KEYSTORE: + cfg += "auth-user-pass\n"; + case VpnProfile.TYPE_KEYSTORE: + if (!configForOvpn3) { + String[] ks = getKeyStoreCertificates(context); + cfg += "### From Keystore ####\n"; + if (ks != null) { + cfg += "<ca>\n" + ks[0] + "\n</ca>\n"; + if (ks[1] != null) + cfg += "<extra-certs>\n" + ks[1] + "\n</extra-certs>\n"; + cfg += "<cert>\n" + ks[2] + "\n</cert>\n"; + cfg += "management-external-key\n"; + } else { + cfg += context.getString(R.string.keychain_access) + "\n"; + if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN) + if (!mAlias.matches("^[a-zA-Z0-9]$")) + cfg += context.getString(R.string.jelly_keystore_alphanumeric_bug) + "\n"; + } + } + break; + case VpnProfile.TYPE_USERPASS: + cfg += "auth-user-pass\n"; + cfg += insertFileData("ca", mCaFilename); + } + + if (mUseLzo) { + cfg += "comp-lzo\n"; + } + + if (mUseTLSAuth) { + if (mAuthenticationType == TYPE_STATICKEYS) + cfg += insertFileData("secret", mTLSAuthFilename); + else + cfg += insertFileData("tls-auth", mTLSAuthFilename); + + if (nonNull(mTLSAuthDirection)) { + cfg += "key-direction "; + cfg += mTLSAuthDirection; + cfg += "\n"; + } + + } + + if (!mUsePull) { + if (nonNull(mIPv4Address)) + cfg += "ifconfig " + cidrToIPAndNetmask(mIPv4Address) + "\n"; + + if (nonNull(mIPv6Address)) + cfg += "ifconfig-ipv6 " + mIPv6Address + "\n"; + } + + if (mUsePull && mRoutenopull) + cfg += "route-nopull\n"; + + String routes = ""; + int numroutes = 0; + if (mUseDefaultRoute) + routes += "route 0.0.0.0 0.0.0.0 vpn_gateway\n"; + else + { + for (String route : getCustomRoutes(mCustomRoutes)) { + routes += "route " + route + " vpn_gateway\n"; + numroutes++; + } + + for (String route: getCustomRoutes(mExcludedRoutes)) { + routes += "route " + route + " net_gateway"; + } + } + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT && !mAllowLocalLAN) + cfg+="redirect-private block-local\n"; + else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && mAllowLocalLAN) + cfg+="redirect-private unblock-local\n"; + + + if (mUseDefaultRoutev6) + cfg += "route-ipv6 ::/0\n"; + else + for (String route : getCustomRoutesv6(mCustomRoutesv6)) { + routes += "route-ipv6 " + route + "\n"; + numroutes++; + } + + // Round number to next 100 + if (numroutes > 90) { + numroutes = ((numroutes / 100) + 1) * 100; + cfg += "# A lot of routes are set, increase max-routes\n"; + cfg += "max-routes " + numroutes + "\n"; + } + cfg += routes; + + if (mOverrideDNS || !mUsePull) { + if (nonNull(mDNS1)) + cfg += "dhcp-option DNS " + mDNS1 + "\n"; + if (nonNull(mDNS2)) + cfg += "dhcp-option DNS " + mDNS2 + "\n"; + if (nonNull(mSearchDomain)) + cfg += "dhcp-option DOMAIN " + mSearchDomain + "\n"; + + } + + if (mNobind) + cfg += "nobind\n"; + + + // Authentication + if (mAuthenticationType != TYPE_STATICKEYS) { + if (mCheckRemoteCN) { + if (mRemoteCN == null || mRemoteCN.equals("")) + cfg += "verify-x509-name " + mServerName + " name\n"; + else + switch (mX509AuthType) { + + // 2.2 style x509 checks + case X509_VERIFY_TLSREMOTE_COMPAT_NOREMAPPING: + cfg += "compat-names no-remapping\n"; + case X509_VERIFY_TLSREMOTE: + cfg += "tls-remote " + openVpnEscape(mRemoteCN) + "\n"; + break; + + case X509_VERIFY_TLSREMOTE_RDN: + cfg += "verify-x509-name " + openVpnEscape(mRemoteCN) + " name\n"; + break; + + case X509_VERIFY_TLSREMOTE_RDN_PREFIX: + cfg += "verify-x509-name " + openVpnEscape(mRemoteCN) + " name-prefix\n"; + break; + + case X509_VERIFY_TLSREMOTE_DN: + cfg += "verify-x509-name " + openVpnEscape(mRemoteCN) + "\n"; + break; + } + } + if (mExpectTLSCert) + cfg += "remote-cert-tls server\n"; + } + + if (nonNull(mCipher)) { + cfg += "cipher " + mCipher + "\n"; + } + + if (nonNull(mAuth)) { + cfg += "auth " + mAuth + "\n"; + } + + // Obscure Settings dialog + if (mUseRandomHostname) + cfg += "#my favorite options :)\nremote-random-hostname\n"; + + if (mUseFloat) + cfg += "float\n"; + + if (mPersistTun) { + cfg += "persist-tun\n"; + cfg += "# persist-tun also enables pre resolving to avoid DNS resolve problem\n"; + cfg += "preresolve\n"; + } + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + boolean usesystemproxy = prefs.getBoolean("usesystemproxy", true); + if (usesystemproxy) { + cfg += "# Use system proxy setting\n"; + cfg += "management-query-proxy\n"; + } + + + if (mUseCustomConfig) { + cfg += "# Custom configuration options\n"; + cfg += "# You are on your on own here :)\n"; + cfg += mCustomConfigOptions; + cfg += "\n"; + + } + + + return cfg; + } + + private String getVersionEnvString(Context c) { + String version = "unknown"; + try { + PackageInfo packageinfo = c.getPackageManager().getPackageInfo(c.getPackageName(), 0); + version = packageinfo.versionName; + } catch (PackageManager.NameNotFoundException e) { + VpnStatus.logException(e); + } + return String.format(Locale.US, "setenv IV_GUI_VER \"%s %s\"\n", c.getPackageName(), version); + + } + + //! Put inline data inline and other data as normal escaped filename + private String insertFileData(String cfgentry, String filedata) { + if (filedata == null) { + // TODO: generate good error + return String.format("%s %s\n", cfgentry, "missing"); + } else if (isEmbedded(filedata)) { + String dataWithOutHeader = getEmbeddedContent(filedata); + return String.format(Locale.ENGLISH, "<%s>\n%s\n</%s>\n", cfgentry, dataWithOutHeader, cfgentry); + } else { + return String.format(Locale.ENGLISH, "%s %s\n", cfgentry, openVpnEscape(filedata)); + } + } + + private boolean nonNull(String val) { + if (val == null || val.equals("")) + return false; + else + return true; + } + + private Collection<String> getCustomRoutes(String routes) { + Vector<String> cidrRoutes = new Vector<String>(); + if (routes == null) { + // No routes set, return empty vector + return cidrRoutes; + } + for (String route : routes.split("[\n \t]")) { + if (!route.equals("")) { + String cidrroute = cidrToIPAndNetmask(route); + if (cidrroute == null) + return null; + + cidrRoutes.add(cidrroute); + } + } + + return cidrRoutes; + } + + private Collection<String> getCustomRoutesv6(String routes) { + Vector<String> cidrRoutes = new Vector<String>(); + if (routes == null) { + // No routes set, return empty vector + return cidrRoutes; + } + for (String route : routes.split("[\n \t]")) { + if (!route.equals("")) { + cidrRoutes.add(route); + } + } + + return cidrRoutes; + } + + private String cidrToIPAndNetmask(String route) { + String[] parts = route.split("/"); + + // No /xx, assume /32 as netmask + if (parts.length == 1) + parts = (route + "/32").split("/"); + + if (parts.length != 2) + return null; + int len; + try { + len = Integer.parseInt(parts[1]); + } catch (NumberFormatException ne) { + return null; + } + if (len < 0 || len > 32) + return null; + + + long nm = 0xffffffffl; + nm = (nm << (32 - len)) & 0xffffffffl; + + String netmask = String.format(Locale.ENGLISH, "%d.%d.%d.%d", (nm & 0xff000000) >> 24, (nm & 0xff0000) >> 16, (nm & 0xff00) >> 8, nm & 0xff); + return parts[0] + " " + netmask; + } + + private String[] buildOpenvpnArgv(File cacheDir) { + Vector<String> args = new Vector<String>(); + + // Add fixed paramenters + //args.add("/data/data/de.blinkt.openvpn/lib/openvpn"); + args.add(cacheDir.getAbsolutePath() + "/" + VpnProfile.MINIVPN); + + args.add("--config"); + args.add(cacheDir.getAbsolutePath() + "/" + OVPNCONFIGFILE); + + + return args.toArray(new String[args.size()]); + } + + public Intent prepareIntent(Context context) { + String prefix = context.getPackageName(); + + Intent intent = new Intent(context, OpenVpnService.class); + + if (mAuthenticationType == VpnProfile.TYPE_KEYSTORE || mAuthenticationType == VpnProfile.TYPE_USERPASS_KEYSTORE) { + if (getKeyStoreCertificates(context) == null) + return null; + } + + intent.putExtra(prefix + ".ARGV", buildOpenvpnArgv(context.getCacheDir())); + intent.putExtra(prefix + ".profileUUID", mUuid.toString()); + + ApplicationInfo info = context.getApplicationInfo(); + intent.putExtra(prefix + ".nativelib", info.nativeLibraryDir); + + try { + FileWriter cfg = new FileWriter(context.getCacheDir().getAbsolutePath() + "/" + OVPNCONFIGFILE); + cfg.write(getConfigFile(context, false)); + cfg.flush(); + cfg.close(); + } catch (IOException e) { + VpnStatus.logException(e); + } + + return intent; + } + + String[] getKeyStoreCertificates(Context context) { + return getKeyStoreCertificates(context, 5); + } + + public static String getDisplayName(String embeddedFile) { + int start = DISPLAYNAME_TAG.length(); + int end = embeddedFile.indexOf(INLINE_TAG); + return embeddedFile.substring(start,end); + } + + public static String getEmbeddedContent(String data) + { + if (!data.contains(INLINE_TAG)) + return data; + + int start = data.indexOf(INLINE_TAG) + INLINE_TAG.length(); + return data.substring(start); + } + + public static boolean isEmbedded(String data) { + if (data==null) + return false; + if(data.startsWith(INLINE_TAG) || data.startsWith(DISPLAYNAME_TAG)) + return true; + else + return false; + } + + + class NoCertReturnedException extends Exception { + public NoCertReturnedException (String msg) { + super(msg); + } + } + + synchronized String[] getKeyStoreCertificates(Context context,int tries) { + PrivateKey privateKey = null; + X509Certificate[] cachain; + Exception exp=null; + try { + privateKey = KeyChain.getPrivateKey(context, mAlias); + mPrivateKey = privateKey; + + String keystoreChain = null; + + + cachain = KeyChain.getCertificateChain(context, mAlias); + if(cachain == null) + throw new NoCertReturnedException("No certificate returned from Keystore"); + + if (cachain.length <= 1 && !nonNull(mCaFilename)) { + VpnStatus.logMessage(VpnStatus.LogLevel.ERROR, "", context.getString(R.string.keychain_nocacert)); + } else { + StringWriter ksStringWriter = new StringWriter(); + + PemWriter pw = new PemWriter(ksStringWriter); + for (int i = 1; i < cachain.length; i++) { + X509Certificate cert = cachain[i]; + pw.writeObject(new PemObject("CERTIFICATE", cert.getEncoded())); + } + pw.close(); + keystoreChain = ksStringWriter.toString(); + } + + + String caout = null; + if (nonNull(mCaFilename)) { + try { + Certificate cacert = X509Utils.getCertificateFromFile(mCaFilename); + StringWriter caoutWriter = new StringWriter(); + PemWriter pw = new PemWriter(caoutWriter); + + pw.writeObject(new PemObject("CERTIFICATE", cacert.getEncoded())); + pw.close(); + caout= caoutWriter.toString(); + + } catch (Exception e) { + VpnStatus.logError("Could not read CA certificate" + e.getLocalizedMessage()); + } + } + + + StringWriter certout = new StringWriter(); + + + if (cachain.length >= 1) { + X509Certificate usercert = cachain[0]; + + PemWriter upw = new PemWriter(certout); + upw.writeObject(new PemObject("CERTIFICATE", usercert.getEncoded())); + upw.close(); + + } + String user = certout.toString(); + + + String ca, extra; + if(caout==null) { + ca =keystoreChain; + extra=null; + } else { + ca = caout; + extra=keystoreChain; + } + + return new String[]{ca, extra, user}; + } catch (InterruptedException e) { + exp=e; + } catch (FileNotFoundException e) { + exp=e; + } catch (CertificateException e) { + exp=e; + } catch (IOException e) { + exp=e; + } catch (KeyChainException e) { + exp=e; + } catch (NoCertReturnedException e) { + exp =e; + } catch (IllegalArgumentException e) { + exp =e; + } catch (AssertionError e) { + if (tries ==0) + return null; + VpnStatus.logError(String.format("Failure getting Keystore Keys (%s), retrying",e.getLocalizedMessage())); + try { + Thread.sleep(3000); + } catch (InterruptedException e1) { + VpnStatus.logException(e1); + } + return getKeyStoreCertificates(context, tries-1); + } + if (exp != null) { + exp.printStackTrace(); + VpnStatus.logError(R.string.keyChainAccessError, exp.getLocalizedMessage()); + + VpnStatus.logError(R.string.keychain_access); + if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN) { + if (!mAlias.matches("^[a-zA-Z0-9]$")) { + VpnStatus.logError(R.string.jelly_keystore_alphanumeric_bug); + } + } + } + return null; + } + + //! Return an error if somethign is wrong + public int checkProfile(Context context) { + if (mAuthenticationType == TYPE_KEYSTORE || mAuthenticationType == TYPE_USERPASS_KEYSTORE) { + if (mAlias == null) + return R.string.no_keystore_cert_selected; + } + + if (!mUsePull || mAuthenticationType == TYPE_STATICKEYS) { + if (mIPv4Address == null || cidrToIPAndNetmask(mIPv4Address) == null) + return R.string.ipv4_format_error; + } + if (!mUseDefaultRoute && (getCustomRoutes(mCustomRoutes) == null || getCustomRoutes(mExcludedRoutes) ==null)) + return R.string.custom_route_format_error; + + // Everything okay + return R.string.no_error_found; + + } + + //! Openvpn asks for a "Private Key", this should be pkcs12 key + // + public String getPasswordPrivateKey() { + if (mTransientPCKS12PW != null) { + String pwcopy = mTransientPCKS12PW; + mTransientPCKS12PW = null; + return pwcopy; + } + switch (mAuthenticationType) { + case TYPE_PKCS12: + case TYPE_USERPASS_PKCS12: + return mPKCS12Password; + + case TYPE_CERTIFICATES: + case TYPE_USERPASS_CERTIFICATES: + return mKeyPassword; + + case TYPE_USERPASS: + case TYPE_STATICKEYS: + default: + return null; + } + } + + boolean isUserPWAuth() { + switch (mAuthenticationType) { + case TYPE_USERPASS: + case TYPE_USERPASS_CERTIFICATES: + case TYPE_USERPASS_KEYSTORE: + case TYPE_USERPASS_PKCS12: + return true; + default: + return false; + + } + } + + public boolean requireTLSKeyPassword() { + if (!nonNull(mClientKeyFilename)) + return false; + + String data = ""; + if (isEmbedded(mClientKeyFilename)) + data = mClientKeyFilename; + else { + char[] buf = new char[2048]; + FileReader fr; + try { + fr = new FileReader(mClientKeyFilename); + int len = fr.read(buf); + while (len > 0) { + data += new String(buf, 0, len); + len = fr.read(buf); + } + fr.close(); + } catch (FileNotFoundException e) { + return false; + } catch (IOException e) { + return false; + } + + } + + if (data.contains("Proc-Type: 4,ENCRYPTED")) + return true; + else if (data.contains("-----BEGIN ENCRYPTED PRIVATE KEY-----")) + return true; + else + return false; + } + + public int needUserPWInput() { + if ((mAuthenticationType == TYPE_PKCS12 || mAuthenticationType == TYPE_USERPASS_PKCS12) && + (mPKCS12Password == null || mPKCS12Password.equals(""))) { + if (mTransientPCKS12PW == null) + return R.string.pkcs12_file_encryption_key; + } + + if (mAuthenticationType == TYPE_CERTIFICATES || mAuthenticationType == TYPE_USERPASS_CERTIFICATES) { + if (requireTLSKeyPassword() && !nonNull(mKeyPassword)) + if (mTransientPCKS12PW == null) { + return R.string.private_key_password; + } + } + + if (isUserPWAuth() && !(nonNull(mUsername) && (nonNull(mPassword) || mTransientPW != null))) { + return R.string.password; + } + return 0; + } + + public String getPasswordAuth() { + if (mTransientPW != null) { + String pwcopy = mTransientPW; + mTransientPW = null; + return pwcopy; + } else { + return mPassword; + } + } + + // Used by the Array Adapter + @Override + public String toString() { + return mName; + } + + public String getUUIDString() { + return mUuid.toString(); + } + + public PrivateKey getKeystoreKey() { + return mPrivateKey; + } + + public String getSignedData(String b64data) { + PrivateKey privkey = getKeystoreKey(); + Exception err; + + byte[] data = Base64.decode(b64data, Base64.DEFAULT); + + // The Jelly Bean *evil* Hack + // 4.2 implements the RSA/ECB/PKCS1PADDING in the OpenSSLprovider + if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN) { + return processSignJellyBeans(privkey, data); + } + + + try { + + + Cipher rsasinger = Cipher.getInstance("RSA/ECB/PKCS1PADDING"); + + rsasinger.init(Cipher.ENCRYPT_MODE, privkey); + + byte[] signed_bytes = rsasinger.doFinal(data); + return Base64.encodeToString(signed_bytes, Base64.NO_WRAP); + + } catch (NoSuchAlgorithmException e) { + err = e; + } catch (InvalidKeyException e) { + err = e; + } catch (NoSuchPaddingException e) { + err = e; + } catch (IllegalBlockSizeException e) { + err = e; + } catch (BadPaddingException e) { + err = e; + } + + VpnStatus.logError(R.string.error_rsa_sign, err.getClass().toString(), err.getLocalizedMessage()); + + return null; + + } + + private String processSignJellyBeans(PrivateKey privkey, byte[] data) { + Exception err; + try { + Method getKey = privkey.getClass().getSuperclass().getDeclaredMethod("getOpenSSLKey"); + getKey.setAccessible(true); + + // Real object type is OpenSSLKey + Object opensslkey = getKey.invoke(privkey); + + getKey.setAccessible(false); + + Method getPkeyContext = opensslkey.getClass().getDeclaredMethod("getPkeyContext"); + + // integer pointer to EVP_pkey + getPkeyContext.setAccessible(true); + int pkey = (Integer) getPkeyContext.invoke(opensslkey); + getPkeyContext.setAccessible(false); + + // 112 with TLS 1.2 (172 back with 4.3), 36 with TLS 1.0 + byte[] signed_bytes = NativeUtils.rsasign(data, pkey); + return Base64.encodeToString(signed_bytes, Base64.NO_WRAP); + + } catch (NoSuchMethodException e) { + err = e; + } catch (IllegalArgumentException e) { + err = e; + } catch (IllegalAccessException e) { + err = e; + } catch (InvocationTargetException e) { + err = e; + } catch (InvalidKeyException e) { + err = e; + } + VpnStatus.logError(R.string.error_rsa_sign, err.getClass().toString(), err.getLocalizedMessage()); + + return null; + + } + + +} + + + + diff --git a/main/src/main/java/de/blinkt/openvpn/activities/ConfigConverter.java b/main/src/main/java/de/blinkt/openvpn/activities/ConfigConverter.java new file mode 100644 index 00000000..8e11802c --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/activities/ConfigConverter.java @@ -0,0 +1,619 @@ + +package de.blinkt.openvpn.activities; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.AlertDialog.Builder; +import android.app.ListActivity; +import android.content.ActivityNotFoundException; +import android.content.Context; +import android.content.Intent; +import android.database.Cursor; +import android.os.Bundle; +import android.os.Environment; +import android.provider.OpenableColumns; +import android.security.KeyChain; +import android.security.KeyChainAliasCallback; +import android.text.TextUtils; +import android.util.Base64; +import android.util.Log; +import android.view.*; +import android.widget.ArrayAdapter; +import android.widget.CheckBox; +import android.widget.LinearLayout; +import android.widget.TextView; + +import de.blinkt.openvpn.R; +import de.blinkt.openvpn.VpnProfile; +import de.blinkt.openvpn.core.ConfigParser; +import de.blinkt.openvpn.core.ConfigParser.ConfigParseError; +import de.blinkt.openvpn.core.ProfileManager; +import de.blinkt.openvpn.fragments.Utils; +import de.blinkt.openvpn.views.FileSelectLayout; +import junit.framework.Assert; + +import org.jetbrains.annotations.Nullable; + +import java.io.*; +import java.util.*; + +import static de.blinkt.openvpn.views.FileSelectLayout.FileSelectCallback; + +public class ConfigConverter extends ListActivity implements FileSelectCallback { + + public static final String IMPORT_PROFILE = "de.blinkt.openvpn.IMPORT_PROFILE"; + private static final int RESULT_INSTALLPKCS12 = 7; + private static final int CHOOSE_FILE_OFFSET = 1000; + public static final String VPNPROFILE = "vpnProfile"; + + private VpnProfile mResult; + private transient ArrayAdapter<String> mArrayAdapter; + + private transient List<String> mPathsegments; + + private String mAliasName = null; + + + private Map<Utils.FileType, FileSelectLayout> fileSelectMap = new HashMap<Utils.FileType, FileSelectLayout>(); + private String mEmbeddedPwFile; + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if (item.getItemId() == R.id.cancel) { + setResult(Activity.RESULT_CANCELED); + finish(); + } else if (item.getItemId() == R.id.ok) { + if (mResult == null) { + log("Importing the config had error, cannot save it"); + return true; + } + + Intent in = installPKCS12(); + + if (in != null) + startActivityForResult(in, RESULT_INSTALLPKCS12); + else + saveProfile(); + + return true; + } + + return super.onOptionsItemSelected(item); + + } + + @Override + protected void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + if (mResult != null) + outState.putSerializable(VPNPROFILE, mResult); + outState.putString("mAliasName", mAliasName); + + String[] logentries = new String[mArrayAdapter.getCount()]; + for (int i = 0; i < mArrayAdapter.getCount(); i++) { + logentries[i] = mArrayAdapter.getItem(i); + } + outState.putStringArray("logentries", logentries); + + int[] fileselects = new int[fileSelectMap.size()]; + int k = 0; + for (Utils.FileType key : fileSelectMap.keySet()) { + fileselects[k] = key.getValue(); + k++; + } + outState.putIntArray("fileselects", fileselects); + outState.putString("pwfile",mEmbeddedPwFile); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent result) { + if (requestCode == RESULT_INSTALLPKCS12 && resultCode == Activity.RESULT_OK) { + showCertDialog(); + } + + if (resultCode == Activity.RESULT_OK && requestCode >= CHOOSE_FILE_OFFSET) { + Utils.FileType type = Utils.FileType.getFileTypeByValue(requestCode - CHOOSE_FILE_OFFSET); + + + FileSelectLayout fs = fileSelectMap.get(type); + fs.parseResponse(result, this); + + String data = fs.getData(); + + switch (type) { + case USERPW_FILE: + mEmbeddedPwFile = data; + break; + case PKCS12: + mResult.mPKCS12Filename = data; + break; + case TLS_AUTH_FILE: + mResult.mTLSAuthFilename = data; + break; + case CA_CERTIFICATE: + mResult.mCaFilename = data; + break; + case CLIENT_CERTIFICATE: + mResult.mClientCertFilename = data; + break; + case KEYFILE: + mResult.mClientKeyFilename = data; + break; + default: + Assert.fail(); + } + } + + super.onActivityResult(requestCode, resultCode, result); + } + + private void saveProfile() { + Intent result = new Intent(); + ProfileManager vpl = ProfileManager.getInstance(this); + + if (!TextUtils.isEmpty(mEmbeddedPwFile)) + ConfigParser.useEmbbedUserAuth(mResult, mEmbeddedPwFile); + + vpl.addProfile(mResult); + vpl.saveProfile(this, mResult); + vpl.saveProfileList(this); + result.putExtra(VpnProfile.EXTRA_PROFILEUUID, mResult.getUUID().toString()); + setResult(Activity.RESULT_OK, result); + finish(); + } + + public void showCertDialog() { + try { + KeyChain.choosePrivateKeyAlias(this, + new KeyChainAliasCallback() { + + public void alias(String alias) { + // Credential alias selected. Remember the alias selection for future use. + mResult.mAlias = alias; + saveProfile(); + } + + + }, + new String[]{"RSA"}, // List of acceptable key types. null for any + null, // issuer, null for any + mResult.mServerName, // host name of server requesting the cert, null if unavailable + -1, // port of server requesting the cert, -1 if unavailable + mAliasName); // alias to preselect, null if unavailable + } catch (ActivityNotFoundException anf) { + Builder ab = new AlertDialog.Builder(this); + ab.setTitle(R.string.broken_image_cert_title); + ab.setMessage(R.string.broken_image_cert); + ab.setPositiveButton(android.R.string.ok, null); + ab.show(); + } + } + + + private Intent installPKCS12() { + + if (!((CheckBox) findViewById(R.id.importpkcs12)).isChecked()) { + setAuthTypeToEmbeddedPKCS12(); + return null; + + } + String pkcs12datastr = mResult.mPKCS12Filename; + if (VpnProfile.isEmbedded(pkcs12datastr)) { + Intent inkeyIntent = KeyChain.createInstallIntent(); + + pkcs12datastr = VpnProfile.getEmbeddedContent(pkcs12datastr); + + + byte[] pkcs12data = Base64.decode(pkcs12datastr, Base64.DEFAULT); + + + inkeyIntent.putExtra(KeyChain.EXTRA_PKCS12, pkcs12data); + + if (mAliasName.equals("")) + mAliasName = null; + + if (mAliasName != null) { + inkeyIntent.putExtra(KeyChain.EXTRA_NAME, mAliasName); + } + return inkeyIntent; + + } + return null; + } + + + private void setAuthTypeToEmbeddedPKCS12() { + if (VpnProfile.isEmbedded(mResult.mPKCS12Filename)) { + if (mResult.mAuthenticationType == VpnProfile.TYPE_USERPASS_KEYSTORE) + mResult.mAuthenticationType = VpnProfile.TYPE_USERPASS_PKCS12; + + if (mResult.mAuthenticationType == VpnProfile.TYPE_KEYSTORE) + mResult.mAuthenticationType = VpnProfile.TYPE_PKCS12; + + } + } + + + private String getUniqueProfileName(String possibleName) { + + int i = 0; + + ProfileManager vpl = ProfileManager.getInstance(this); + + String newname = possibleName; + + // Default to + if (mResult.mName != null && !ConfigParser.CONVERTED_PROFILE.equals(mResult.mName)) + newname = mResult.mName; + + while (newname == null || vpl.getProfileByName(newname) != null) { + i++; + if (i == 1) + newname = getString(R.string.converted_profile); + else + newname = getString(R.string.converted_profile_i, i); + } + + return newname; + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.import_menu, menu); + return true; + } + + private String embedFile(String filename, Utils.FileType type) { + if (filename == null) + return null; + + // Already embedded, nothing to do + if (VpnProfile.isEmbedded(filename)) + return filename; + + File possibleFile = findFile(filename, type); + if (possibleFile == null) + return filename; + else + return readFileContent(possibleFile, type == Utils.FileType.PKCS12); + + } + + private File findFile(String filename, Utils.FileType fileType) { + File foundfile = findFileRaw(filename); + + if (foundfile == null && filename != null && !filename.equals("")) { + log(R.string.import_could_not_open, filename); + addFileSelectDialog(fileType); + } + + + return foundfile; + } + + private void addFileSelectDialog(Utils.FileType type) { + int titleRes = 0; + String value = null; + switch (type) { + case KEYFILE: + titleRes = R.string.client_key_title; + if (mResult != null) + value = mResult.mClientKeyFilename; + break; + case CLIENT_CERTIFICATE: + titleRes = R.string.client_certificate_title; + if (mResult != null) + value = mResult.mClientCertFilename; + break; + case CA_CERTIFICATE: + titleRes = R.string.ca_title; + if (mResult != null) + value = mResult.mCaFilename; + break; + case TLS_AUTH_FILE: + titleRes = R.string.tls_auth_file; + if (mResult != null) + value = mResult.mTLSAuthFilename; + break; + case PKCS12: + titleRes = R.string.client_pkcs12_title; + if (mResult != null) + value = mResult.mPKCS12Filename; + break; + + case USERPW_FILE: + titleRes = R.string.userpw_file; + value = mEmbeddedPwFile; + break; + + } + + boolean isCert = type == Utils.FileType.CA_CERTIFICATE || type == Utils.FileType.CLIENT_CERTIFICATE; + FileSelectLayout fl = new FileSelectLayout(this, getString(titleRes), isCert); + fileSelectMap.put(type, fl); + fl.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)); + + ((LinearLayout) findViewById(R.id.config_convert_root)).addView(fl, 2); + findViewById(R.id.files_missing_hint).setVisibility(View.VISIBLE); + fl.setData(value, this); + int i = getFileLayoutOffset(type); + fl.setCaller(this, i, type); + + } + + private int getFileLayoutOffset(Utils.FileType type) { + return CHOOSE_FILE_OFFSET + type.getValue(); + } + + + private File findFileRaw(String filename) { + if (filename == null || filename.equals("")) + return null; + + // Try diffent path relative to /mnt/sdcard + File sdcard = Environment.getExternalStorageDirectory(); + File root = new File("/"); + + HashSet<File> dirlist = new HashSet<File>(); + + for (int i = mPathsegments.size() - 1; i >= 0; i--) { + String path = ""; + for (int j = 0; j <= i; j++) { + path += "/" + mPathsegments.get(j); + } + // Do a little hackish dance for the Android File Importer + // /document/primary:ovpn/openvpn-imt.conf + + + if (path.indexOf(':') != -1) { + String possibleDir = path.substring(path.indexOf(':') + 1, path.length()); + possibleDir = possibleDir.substring(0, possibleDir.lastIndexOf('/')); + + + dirlist.add(new File(sdcard, possibleDir)); + + } + dirlist.add(new File(path)); + + + } + dirlist.add(sdcard); + dirlist.add(root); + + + String[] fileparts = filename.split("/"); + for (File rootdir : dirlist) { + String suffix = ""; + for (int i = fileparts.length - 1; i >= 0; i--) { + if (i == fileparts.length - 1) + suffix = fileparts[i]; + else + suffix = fileparts[i] + "/" + suffix; + + File possibleFile = new File(rootdir, suffix); + if (!possibleFile.canRead()) + continue; + + // read the file inline + return possibleFile; + + } + } + return null; + } + + String readFileContent(File possibleFile, boolean base64encode) { + byte[] filedata; + try { + filedata = readBytesFromFile(possibleFile); + } catch (IOException e) { + log(e.getLocalizedMessage()); + return null; + } + + String data; + if (base64encode) { + data = Base64.encodeToString(filedata, Base64.DEFAULT); + } else { + data = new String(filedata); + + } + + return VpnProfile.DISPLAYNAME_TAG + possibleFile.getName() + VpnProfile.INLINE_TAG + data; + + } + + + private byte[] readBytesFromFile(File file) throws IOException { + InputStream input = new FileInputStream(file); + + long len = file.length(); + if (len > VpnProfile.MAX_EMBED_FILE_SIZE) + throw new IOException("File size of file to import too large."); + + // Create the byte array to hold the data + byte[] bytes = new byte[(int) len]; + + // Read in the bytes + int offset = 0; + int bytesRead = 0; + while (offset < bytes.length + && (bytesRead = input.read(bytes, offset, bytes.length - offset)) >= 0) { + offset += bytesRead; + } + + input.close(); + return bytes; + } + + void embedFiles() { + // This where I would like to have a c++ style + // void embedFile(std::string & option) + + if (mResult.mPKCS12Filename != null) { + File pkcs12file = findFileRaw(mResult.mPKCS12Filename); + if (pkcs12file != null) { + mAliasName = pkcs12file.getName().replace(".p12", ""); + } else { + mAliasName = "Imported PKCS12"; + } + } + + + mResult.mCaFilename = embedFile(mResult.mCaFilename, Utils.FileType.CA_CERTIFICATE); + mResult.mClientCertFilename = embedFile(mResult.mClientCertFilename, Utils.FileType.CLIENT_CERTIFICATE); + mResult.mClientKeyFilename = embedFile(mResult.mClientKeyFilename, Utils.FileType.KEYFILE); + mResult.mTLSAuthFilename = embedFile(mResult.mTLSAuthFilename, Utils.FileType.TLS_AUTH_FILE); + mResult.mPKCS12Filename = embedFile(mResult.mPKCS12Filename, Utils.FileType.PKCS12); + mEmbeddedPwFile = embedFile(mResult.mPassword, Utils.FileType.USERPW_FILE); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + + setContentView(R.layout.config_converter); + + mArrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1); + getListView().setAdapter(mArrayAdapter); + + super.onCreate(savedInstanceState); + + + if (savedInstanceState != null && savedInstanceState.containsKey(VPNPROFILE)) { + mResult = (VpnProfile) savedInstanceState.getSerializable(VPNPROFILE); + mAliasName = savedInstanceState.getString("mAliasName"); + mEmbeddedPwFile = savedInstanceState.getString("pwfile"); + mArrayAdapter.addAll(savedInstanceState.getStringArray("logentries")); + for (int k : savedInstanceState.getIntArray("fileselects")) { + addFileSelectDialog(Utils.FileType.getFileTypeByValue(k)); + } + + return; + } + + + final android.content.Intent intent = getIntent(); + + if (intent != null) { + final android.net.Uri data = intent.getData(); + if (data != null) { + //log(R.string.import_experimental); + log(R.string.importing_config, data.toString()); + try { + String possibleName = null; + if (data.getScheme().equals("file") || + data.getLastPathSegment().endsWith(".ovpn") || + data.getLastPathSegment().endsWith(".conf")) { + possibleName = data.getLastPathSegment(); + if (possibleName.lastIndexOf('/') != -1) + possibleName = possibleName.substring(possibleName.lastIndexOf('/') + 1); + + } + InputStream is = getContentResolver().openInputStream(data); + mPathsegments = data.getPathSegments(); + + + Cursor cursor = getContentResolver().query(data, null, null, null, null); + try { + + + if (cursor!=null && cursor.moveToFirst()) { + int cidx = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); + + if (cidx != -1) { + String displayName = cursor.getString(cidx); + if (displayName != null) + possibleName = displayName; + } + cidx = cursor.getColumnIndex("mime_type"); + if (cidx != -1) { + log("Opening Mime TYPE: " + cursor.getString(cidx)); + } + } + } finally { + if(cursor!=null) + cursor.close(); + } + if (possibleName != null) { + possibleName = possibleName.replace(".ovpn", ""); + possibleName = possibleName.replace(".conf", ""); + } + + doImport(is, possibleName); + + } catch (FileNotFoundException e) { + log(R.string.import_content_resolve_error); + } + } + + // We parsed the intent, relay on saved instance for restoring + setIntent(null); + } + + + } + + + @Override + protected void onStart() { + super.onStart(); + + + } + + private void log(String logmessage) { + mArrayAdapter.add(logmessage); + } + + private void doImport(InputStream is, String newName) { + ConfigParser cp = new ConfigParser(); + try { + InputStreamReader isr = new InputStreamReader(is); + + cp.parseConfig(isr); + VpnProfile vp = cp.convertProfile(); + mResult = vp; + embedFiles(); + displayWarnings(); + mResult.mName = getUniqueProfileName(newName); + + log(R.string.import_done); + return; + + } catch (IOException e) { + log(R.string.error_reading_config_file); + log(e.getLocalizedMessage()); + } catch (ConfigParseError e) { + log(R.string.error_reading_config_file); + log(e.getLocalizedMessage()); + } + mResult = null; + + } + + private void displayWarnings() { + if (mResult.mUseCustomConfig) { + log(R.string.import_warning_custom_options); + String copt = mResult.mCustomConfigOptions; + if (copt.startsWith("#")) { + int until = copt.indexOf('\n'); + copt = copt.substring(until + 1); + } + + log(copt); + } + + if (mResult.mAuthenticationType == VpnProfile.TYPE_KEYSTORE || + mResult.mAuthenticationType == VpnProfile.TYPE_USERPASS_KEYSTORE) { + findViewById(R.id.importpkcs12).setVisibility(View.VISIBLE); + } + + } + + private void log(int ressourceId, Object... formatArgs) { + log(getString(ressourceId, formatArgs)); + } + + +} diff --git a/main/src/main/java/de/blinkt/openvpn/activities/CreateShortcuts.java b/main/src/main/java/de/blinkt/openvpn/activities/CreateShortcuts.java new file mode 100644 index 00000000..53a829ff --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/activities/CreateShortcuts.java @@ -0,0 +1,154 @@ +package de.blinkt.openvpn.activities; + +import android.app.ListActivity; +import android.content.Intent; +import android.os.Bundle; +import android.os.Parcelable; +import android.view.View; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemClickListener; +import android.widget.ArrayAdapter; +import android.widget.ListView; +import android.widget.TextView; +import de.blinkt.openvpn.LaunchVPN; +import de.blinkt.openvpn.R; +import de.blinkt.openvpn.VpnProfile; +import de.blinkt.openvpn.core.ProfileManager; + +import java.util.Collection; +import java.util.Vector; + +/** + * This Activity actually handles two stages of a launcher shortcut's life cycle. + * + * 1. Your application offers to provide shortcuts to the launcher. When + * the user installs a shortcut, an activity within your application + * generates the actual shortcut and returns it to the launcher, where it + * is shown to the user as an icon. + * + * 2. Any time the user clicks on an installed shortcut, an intent is sent. + * Typically this would then be handled as necessary by an activity within + * your application. + * + * We handle stage 1 (creating a shortcut) by simply sending back the information (in the form + * of an {@link android.content.Intent} that the launcher will use to create the shortcut. + * + * You can also implement this in an interactive way, by having your activity actually present + * UI for the user to select the specific nature of the shortcut, such as a contact, picture, URL, + * media item, or action. + * + * We handle stage 2 (responding to a shortcut) in this sample by simply displaying the contents + * of the incoming {@link android.content.Intent}. + * + * In a real application, you would probably use the shortcut intent to display specific content + * or start a particular operation. + */ +public class CreateShortcuts extends ListActivity implements OnItemClickListener { + + + private static final int START_VPN_PROFILE= 70; + + + private ProfileManager mPM; + private VpnProfile mSelectedProfile; + + @Override + public void onCreate(Bundle icicle) { + super.onCreate(icicle); + + mPM =ProfileManager.getInstance(this); + + } + + @Override + protected void onStart() { + super.onStart(); + // Resolve the intent + + createListView(); + } + + private void createListView() { + ListView lv = getListView(); + //lv.setTextFilterEnabled(true); + + Collection<VpnProfile> vpnList = mPM.getProfiles(); + + Vector<String> vpnNames=new Vector<String>(); + for (VpnProfile vpnProfile : vpnList) { + vpnNames.add(vpnProfile.mName); + } + + + + ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,vpnNames); + lv.setAdapter(adapter); + + lv.setOnItemClickListener(this); + } + + /** + * This function creates a shortcut and returns it to the caller. There are actually two + * intents that you will send back. + * + * The first intent serves as a container for the shortcut and is returned to the launcher by + * setResult(). This intent must contain three fields: + * + * <ul> + * <li>{@link android.content.Intent#EXTRA_SHORTCUT_INTENT} The shortcut intent.</li> + * <li>{@link android.content.Intent#EXTRA_SHORTCUT_NAME} The text that will be displayed with + * the shortcut.</li> + * <li>{@link android.content.Intent#EXTRA_SHORTCUT_ICON} The shortcut's icon, if provided as a + * bitmap, <i>or</i> {@link android.content.Intent#EXTRA_SHORTCUT_ICON_RESOURCE} if provided as + * a drawable resource.</li> + * </ul> + * + * If you use a simple drawable resource, note that you must wrapper it using + * {@link android.content.Intent.ShortcutIconResource}, as shown below. This is required so + * that the launcher can access resources that are stored in your application's .apk file. If + * you return a bitmap, such as a thumbnail, you can simply put the bitmap into the extras + * bundle using {@link android.content.Intent#EXTRA_SHORTCUT_ICON}. + * + * The shortcut intent can be any intent that you wish the launcher to send, when the user + * clicks on the shortcut. Typically this will be {@link android.content.Intent#ACTION_VIEW} + * with an appropriate Uri for your content, but any Intent will work here as long as it + * triggers the desired action within your Activity. + * @param profile + */ + private void setupShortcut(VpnProfile profile) { + // First, set up the shortcut intent. For this example, we simply create an intent that + // will bring us directly back to this activity. A more typical implementation would use a + // data Uri in order to display a more specific result, or a custom action in order to + // launch a specific operation. + + Intent shortcutIntent = new Intent(Intent.ACTION_MAIN); + shortcutIntent.setClass(this, LaunchVPN.class); + shortcutIntent.putExtra(LaunchVPN.EXTRA_KEY,profile.getUUID().toString()); + + // Then, set up the container intent (the response to the caller) + + Intent intent = new Intent(); + intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); + intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, profile.getName()); + Parcelable iconResource = Intent.ShortcutIconResource.fromContext( + this, R.drawable.icon); + intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconResource); + + // Now, return the result to the launcher + + setResult(RESULT_OK, intent); + } + + + @Override + public void onItemClick(AdapterView<?> parent, View view, int position, + long id) { + String profileName = ((TextView) view).getText().toString(); + + VpnProfile profile = mPM.getProfileByName(profileName); + + setupShortcut(profile); + finish(); + } + +} diff --git a/main/src/main/java/de/blinkt/openvpn/activities/DisconnectVPN.java b/main/src/main/java/de/blinkt/openvpn/activities/DisconnectVPN.java new file mode 100644 index 00000000..c2d4c599 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/activities/DisconnectVPN.java @@ -0,0 +1,82 @@ +package de.blinkt.openvpn.activities; + +import android.app.Activity; +import android.app.AlertDialog; +import android.content.*; +import android.os.IBinder; + +import de.blinkt.openvpn.R; +import de.blinkt.openvpn.core.OpenVpnService; +import de.blinkt.openvpn.core.ProfileManager; + +/** + * Created by arne on 13.10.13. + */ +public class DisconnectVPN extends Activity implements DialogInterface.OnClickListener{ + protected OpenVpnService mService; + + private ServiceConnection mConnection = new ServiceConnection() { + + + @Override + public void onServiceConnected(ComponentName className, + IBinder service) { + // We've bound to LocalService, cast the IBinder and get LocalService instance + OpenVpnService.LocalBinder binder = (OpenVpnService.LocalBinder) service; + mService = binder.getService(); + } + + @Override + public void onServiceDisconnected(ComponentName arg0) { + mService =null; + } + + }; + + @Override + protected void onResume() { + super.onResume(); + Intent intent = new Intent(this, OpenVpnService.class); + intent.setAction(OpenVpnService.START_SERVICE); + bindService(intent, mConnection, Context.BIND_AUTO_CREATE); + showDisconnectDialog(); + } + + @Override + protected void onStop() { + super.onStop(); + unbindService(mConnection); + } + + // if (getIntent() !=null && OpenVpnService.DISCONNECT_VPN.equals(getIntent().getAction())) + + // setIntent(null); + + /* + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + setIntent(intent); + } + */ + + private void showDisconnectDialog() { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(R.string.title_cancel); + builder.setMessage(R.string.cancel_connection_query); + builder.setNegativeButton(android.R.string.no, this); + builder.setPositiveButton(android.R.string.yes,this); + + builder.show(); + } + + @Override + public void onClick(DialogInterface dialog, int which) { + if (which == DialogInterface.BUTTON_POSITIVE) { + ProfileManager.setConntectedVpnProfileDisconnected(this); + if (mService != null && mService.getManagement() != null) + mService.getManagement().stopVPN(); + } + finish(); + } +} diff --git a/main/src/main/java/de/blinkt/openvpn/activities/FileSelect.java b/main/src/main/java/de/blinkt/openvpn/activities/FileSelect.java new file mode 100644 index 00000000..511dc736 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/activities/FileSelect.java @@ -0,0 +1,220 @@ +package de.blinkt.openvpn.activities; + + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; + +import android.app.ActionBar; +import android.app.ActionBar.Tab; +import android.app.Activity; +import android.app.AlertDialog; +import android.app.AlertDialog.Builder; +import android.app.Fragment; +import android.app.FragmentTransaction; +import android.content.Intent; +import android.os.Bundle; +import android.os.Environment; +import android.util.Base64; + +import de.blinkt.openvpn.R; +import de.blinkt.openvpn.VpnProfile; +import de.blinkt.openvpn.fragments.FileSelectionFragment; +import de.blinkt.openvpn.fragments.InlineFileTab; + +public class FileSelect extends Activity { + public static final String RESULT_DATA = "RESULT_PATH"; + public static final String START_DATA = "START_DATA"; + public static final String WINDOW_TITLE = "WINDOW_TILE"; + public static final String NO_INLINE_SELECTION = "de.blinkt.openvpn.NO_INLINE_SELECTION"; + public static final String SHOW_CLEAR_BUTTON = "de.blinkt.openvpn.SHOW_CLEAR_BUTTON"; + public static final String DO_BASE64_ENCODE = "de.blinkt.openvpn.BASE64ENCODE"; + + private FileSelectionFragment mFSFragment; + private InlineFileTab mInlineFragment; + private String mData; + private Tab inlineFileTab; + private Tab fileExplorerTab; + private boolean mNoInline; + private boolean mShowClear; + private boolean mBase64Encode; + + + public void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + setContentView(R.layout.file_dialog); + + mData = getIntent().getStringExtra(START_DATA); + if(mData==null) + mData=Environment.getExternalStorageDirectory().getPath(); + + String title = getIntent().getStringExtra(WINDOW_TITLE); + int titleId = getIntent().getIntExtra(WINDOW_TITLE, 0); + if(titleId!=0) + title =getString(titleId); + if(title!=null) + setTitle(title); + + mNoInline = getIntent().getBooleanExtra(NO_INLINE_SELECTION, false); + mShowClear = getIntent().getBooleanExtra(SHOW_CLEAR_BUTTON, false); + mBase64Encode = getIntent().getBooleanExtra(DO_BASE64_ENCODE, false); + + ActionBar bar = getActionBar(); + bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); + fileExplorerTab = bar.newTab().setText(R.string.file_explorer_tab); + inlineFileTab = bar.newTab().setText(R.string.inline_file_tab); + + mFSFragment = new FileSelectionFragment(); + fileExplorerTab.setTabListener(new MyTabsListener<FileSelectionFragment>(this, mFSFragment)); + bar.addTab(fileExplorerTab); + + if(!mNoInline) { + mInlineFragment = new InlineFileTab(); + inlineFileTab.setTabListener(new MyTabsListener<InlineFileTab>(this, mInlineFragment)); + bar.addTab(inlineFileTab); + } else { + mFSFragment.setNoInLine(); + } + + + } + + public boolean showClear() { + if(mData == null || mData.equals("")) + return false; + else + return mShowClear; + } + + protected class MyTabsListener<T extends Fragment> implements ActionBar.TabListener + { + private Fragment mFragment; + private boolean mAdded=false; + + public MyTabsListener( Activity activity, Fragment fragment){ + this.mFragment = fragment; + } + + public void onTabSelected(Tab tab, FragmentTransaction ft) { + // Check if the fragment is already initialized + if (!mAdded) { + // If not, instantiate and add it to the activity + ft.add(android.R.id.content, mFragment); + mAdded =true; + } else { + // If it exists, simply attach it in order to show it + ft.attach(mFragment); + } + } + + @Override + public void onTabUnselected(Tab tab, FragmentTransaction ft) { + ft.detach(mFragment); + } + + @Override + public void onTabReselected(Tab tab, FragmentTransaction ft) { + + } + } + + public void importFile(String path) { + File ifile = new File(path); + Exception fe = null; + try { + + String data = ""; + + byte[] fileData = readBytesFromFile(ifile) ; + if(mBase64Encode) + data += Base64.encodeToString(fileData, Base64.DEFAULT); + else + data += new String(fileData); + + mData =data; + + /* + mInlineFragment.setData(data); + getActionBar().selectTab(inlineFileTab); */ + saveInlineData(ifile.getName(), data); + } catch (FileNotFoundException e) { + fe = e; + } catch (IOException e) { + fe =e; + } + if(fe!=null) { + Builder ab = new AlertDialog.Builder(this); + ab.setTitle(R.string.error_importing_file); + ab.setMessage(getString(R.string.import_error_message) + "\n" + fe.getLocalizedMessage()); + ab.setPositiveButton(android.R.string.ok, null); + ab.show(); + } + } + + static private byte[] readBytesFromFile(File file) throws IOException { + InputStream input = new FileInputStream(file); + + long len= file.length(); + if (len > VpnProfile.MAX_EMBED_FILE_SIZE) + throw new IOException("selected file size too big to embed into profile"); + + // Create the byte array to hold the data + byte[] bytes = new byte[(int) len]; + + // Read in the bytes + int offset = 0; + int bytesRead = 0; + while (offset < bytes.length + && (bytesRead=input.read(bytes, offset, bytes.length-offset)) >= 0) { + offset += bytesRead; + } + + input.close(); + return bytes; + } + + + public void setFile(String path) { + Intent intent = new Intent(); + intent.putExtra(RESULT_DATA, path); + setResult(Activity.RESULT_OK,intent); + finish(); + } + + public String getSelectPath() { + if(VpnProfile.isEmbedded(mData)) + return mData; + else + return Environment.getExternalStorageDirectory().getPath(); + } + + public CharSequence getInlineData() { + if(VpnProfile.isEmbedded(mData)) + return VpnProfile.getEmbeddedContent(mData); + else + return ""; + } + + public void clearData() { + Intent intent = new Intent(); + intent.putExtra(RESULT_DATA, (String)null); + setResult(Activity.RESULT_OK,intent); + finish(); + + } + + public void saveInlineData(String fileName, String string) { + Intent intent = new Intent(); + + if(fileName==null) + intent.putExtra(RESULT_DATA, VpnProfile.INLINE_TAG + string); + else + intent.putExtra(RESULT_DATA,VpnProfile.DISPLAYNAME_TAG + fileName + VpnProfile.INLINE_TAG + string); + setResult(Activity.RESULT_OK, intent); + finish(); + + } +} diff --git a/main/src/main/java/de/blinkt/openvpn/activities/LogWindow.java b/main/src/main/java/de/blinkt/openvpn/activities/LogWindow.java new file mode 100644 index 00000000..27197035 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/activities/LogWindow.java @@ -0,0 +1,32 @@ +package de.blinkt.openvpn.activities; + +import android.app.Activity; +import android.os.Bundle; +import android.view.MenuItem; + +import de.blinkt.openvpn.R; +import de.blinkt.openvpn.fragments.LogFragment; + +/** + * Created by arne on 13.10.13. + */ +public class LogWindow extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.log_window); + getActionBar().setDisplayHomeAsUpEnabled(true); + + if (savedInstanceState == null) { + getFragmentManager().beginTransaction() + .add(R.id.container, new LogFragment()) + .commit(); + } + + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + return super.onOptionsItemSelected(item); + } +} diff --git a/main/src/main/java/de/blinkt/openvpn/activities/MainActivity.java b/main/src/main/java/de/blinkt/openvpn/activities/MainActivity.java new file mode 100644 index 00000000..b32c80cc --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/activities/MainActivity.java @@ -0,0 +1,103 @@ +package de.blinkt.openvpn.activities; + +import android.app.ActionBar; +import android.app.ActionBar.Tab; +import android.app.Activity; +import android.app.Fragment; +import android.app.FragmentTransaction; +import android.content.Intent; + +import de.blinkt.openvpn.R; +import de.blinkt.openvpn.fragments.*; + + +public class MainActivity extends Activity { + + protected void onCreate(android.os.Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + ActionBar bar = getActionBar(); + bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); + + Tab vpnListTab = bar.newTab().setText(R.string.vpn_list_title); + Tab generalTab = bar.newTab().setText(R.string.generalsettings); + Tab faqtab = bar.newTab().setText(R.string.faq); + Tab abouttab = bar.newTab().setText(R.string.about); + + vpnListTab.setTabListener(new TabListener<VPNProfileList>("profiles", VPNProfileList.class)); + generalTab.setTabListener(new TabListener<GeneralSettings>("settings", GeneralSettings.class)); + faqtab.setTabListener(new TabListener<FaqFragment>("faq", FaqFragment.class)); + abouttab.setTabListener(new TabListener<AboutFragment>("about", AboutFragment.class)); + + bar.addTab(vpnListTab); + bar.addTab(generalTab); + bar.addTab(faqtab); + bar.addTab(abouttab); + + if (false) { + Tab logtab = bar.newTab().setText("Log"); + logtab.setTabListener(new TabListener<LogFragment>("log", LogFragment.class)); + bar.addTab(logtab); + } + + if(SendDumpFragment.getLastestDump(this)!=null) { + Tab sendDump = bar.newTab().setText(R.string.crashdump); + sendDump.setTabListener(new TabListener<SendDumpFragment>("crashdump",SendDumpFragment.class)); + bar.addTab(sendDump); + } + + } + + protected class TabListener<T extends Fragment> implements ActionBar.TabListener + { + private Fragment mFragment; + private String mTag; + private Class<T> mClass; + + public TabListener(String tag, Class<T> clz) { + mTag = tag; + mClass = clz; + + // Check to see if we already have a fragment for this tab, probably + // from a previously saved state. If so, deactivate it, because our + // initial state is that a tab isn't shown. + mFragment = getFragmentManager().findFragmentByTag(mTag); + if (mFragment != null && !mFragment.isDetached()) { + FragmentTransaction ft = getFragmentManager().beginTransaction(); + ft.detach(mFragment); + ft.commit(); + } + } + + public void onTabSelected(Tab tab, FragmentTransaction ft) { + if (mFragment == null) { + mFragment = Fragment.instantiate(MainActivity.this, mClass.getName()); + ft.add(android.R.id.content, mFragment, mTag); + } else { + ft.attach(mFragment); + } + } + + public void onTabUnselected(Tab tab, FragmentTransaction ft) { + if (mFragment != null) { + ft.detach(mFragment); + } + } + + + @Override + public void onTabReselected(Tab tab, FragmentTransaction ft) { + + } + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + + System.out.println(data); + + + } + + +} diff --git a/main/src/main/java/de/blinkt/openvpn/activities/VPNPreferences.java b/main/src/main/java/de/blinkt/openvpn/activities/VPNPreferences.java new file mode 100644 index 00000000..1ebb16b2 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/activities/VPNPreferences.java @@ -0,0 +1,165 @@ +package de.blinkt.openvpn.activities; + +import java.util.List; + +import android.annotation.TargetApi; +import android.app.AlertDialog; +import android.app.Fragment; +import android.content.DialogInterface; +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.preference.PreferenceActivity; +import android.preference.PreferenceFragment; +import android.view.Menu; +import android.view.MenuItem; + +import de.blinkt.openvpn.R; +import de.blinkt.openvpn.VpnProfile; +import de.blinkt.openvpn.core.ProfileManager; +import de.blinkt.openvpn.fragments.Settings_Authentication; +import de.blinkt.openvpn.fragments.Settings_Basic; +import de.blinkt.openvpn.fragments.Settings_IP; +import de.blinkt.openvpn.fragments.Settings_Obscure; +import de.blinkt.openvpn.fragments.Settings_Routing; +import de.blinkt.openvpn.fragments.ShowConfigFragment; +import de.blinkt.openvpn.fragments.VPNProfileList; + + +public class VPNPreferences extends PreferenceActivity { + + static final Class validFragments[] = new Class[] { + Settings_Authentication.class, Settings_Basic.class, Settings_IP.class, + Settings_Obscure.class, Settings_Routing.class, ShowConfigFragment.class + }; + + private String mProfileUUID; + private VpnProfile mProfile; + + public VPNPreferences() { + super(); + } + + + @TargetApi(Build.VERSION_CODES.KITKAT) + @Override + protected boolean isValidFragment(String fragmentName) { + for (Class c: validFragments) + if (c.getName().equals(fragmentName)) + return true; + return false; + + } + + @Override + protected void onStop() { + super.onStop(); + } + + @Override + protected void onSaveInstanceState(Bundle outState) { + outState.putString(getIntent().getStringExtra(getPackageName() + ".profileUUID"),mProfileUUID); + super.onSaveInstanceState(outState); + } + + @Override + protected void onResume() { + super.onResume(); + Intent intent = getIntent(); + + + if(intent!=null) { + String profileUUID = intent.getStringExtra(getPackageName() + ".profileUUID"); + if(profileUUID==null) { + Bundle initialArguments = getIntent().getBundleExtra(EXTRA_SHOW_FRAGMENT_ARGUMENTS); + profileUUID = initialArguments.getString(getPackageName() + ".profileUUID"); + } + if(profileUUID!=null){ + + mProfileUUID = profileUUID; + mProfile = ProfileManager.get(this,mProfileUUID); + + } + } + // When a profile is deleted from a category fragment in hadset mod we need to finish + // this activity as well when returning + if (mProfile==null || mProfile.profileDleted) { + setResult(VPNProfileList.RESULT_VPN_DELETED); + finish(); + } + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + mProfileUUID = getIntent().getStringExtra(getPackageName() + ".profileUUID"); + if(savedInstanceState!=null){ + String savedUUID = savedInstanceState.getString(getPackageName() + ".profileUUID"); + if(savedUUID!=null) + mProfileUUID=savedUUID; + } + + mProfile = ProfileManager.get(this,mProfileUUID); + if(mProfile!=null) { + setTitle(getString(R.string.edit_profile_title, mProfile.getName())); + } + super.onCreate(savedInstanceState); + } + + + + @Override + public void onBuildHeaders(List<Header> target) { + loadHeadersFromResource(R.xml.vpn_headers, target); + for (Header header : target) { + if(header.fragmentArguments==null) + header.fragmentArguments = new Bundle(); + header.fragmentArguments.putString(getPackageName() + ".profileUUID",mProfileUUID); + } + } + + @Override + public void onBackPressed() { + setResult(RESULT_OK, getIntent()); + super.onBackPressed(); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if(item.getItemId() == R.id.remove_vpn) + askProfileRemoval(); + return super.onOptionsItemSelected(item); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + + getMenuInflater().inflate(R.menu.vpnpreferences_menu, menu); + + return super.onCreateOptionsMenu(menu); + } + + private void askProfileRemoval() { + AlertDialog.Builder dialog = new AlertDialog.Builder(this); + dialog.setTitle("Confirm deletion"); + dialog.setMessage(getString(R.string.remove_vpn_query, mProfile.mName)); + + dialog.setPositiveButton(android.R.string.yes, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + removeProfile(mProfile); + } + + }); + dialog.setNegativeButton(android.R.string.no,null); + dialog.create().show(); + } + + protected void removeProfile(VpnProfile profile) { + ProfileManager.getInstance(this).removeProfile(this,profile); + setResult(VPNProfileList.RESULT_VPN_DELETED); + finish(); + + } +} + diff --git a/main/src/main/java/de/blinkt/openvpn/api/APIVpnProfile.java b/main/src/main/java/de/blinkt/openvpn/api/APIVpnProfile.java new file mode 100644 index 00000000..f5591764 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/api/APIVpnProfile.java @@ -0,0 +1,51 @@ +package de.blinkt.openvpn.api;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+public class APIVpnProfile implements Parcelable {
+
+ public final String mUUID;
+ public final String mName;
+ public final boolean mUserEditable;
+
+ public APIVpnProfile(Parcel in) {
+ mUUID = in.readString();
+ mName = in.readString();
+ mUserEditable = in.readInt() != 0;
+ }
+
+ public APIVpnProfile(String uuidString, String name, boolean userEditable) {
+ mUUID=uuidString;
+ mName = name;
+ mUserEditable=userEditable;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mUUID);
+ dest.writeString(mName);
+ if(mUserEditable)
+ dest.writeInt(0);
+ else
+ dest.writeInt(1);
+ }
+
+ public static final Parcelable.Creator<APIVpnProfile> CREATOR
+ = new Parcelable.Creator<APIVpnProfile>() {
+ public APIVpnProfile createFromParcel(Parcel in) {
+ return new APIVpnProfile(in);
+ }
+
+ public APIVpnProfile[] newArray(int size) {
+ return new APIVpnProfile[size];
+ }
+ };
+
+
+}
diff --git a/main/src/main/java/de/blinkt/openvpn/api/ConfirmDialog.java b/main/src/main/java/de/blinkt/openvpn/api/ConfirmDialog.java new file mode 100644 index 00000000..bcab79ed --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/api/ConfirmDialog.java @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package de.blinkt.openvpn.api; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.AlertDialog.Builder; +import android.content.DialogInterface; +import android.content.DialogInterface.OnShowListener; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.util.Log; +import android.view.View; +import android.widget.Button; +import android.widget.CompoundButton; +import android.widget.ImageView; +import android.widget.TextView; +import de.blinkt.openvpn.R; + + +public class ConfirmDialog extends Activity implements +CompoundButton.OnCheckedChangeListener, DialogInterface.OnClickListener { + private static final String TAG = "OpenVPNVpnConfirm"; + + private String mPackage; + + private Button mButton; + + private AlertDialog mAlert; + + @Override + protected void onResume() { + super.onResume(); + try { + mPackage = getCallingPackage(); + if (mPackage==null) { + finish(); + return; + } + + + PackageManager pm = getPackageManager(); + ApplicationInfo app = pm.getApplicationInfo(mPackage, 0); + + View view = View.inflate(this, R.layout.api_confirm, null); + ((ImageView) view.findViewById(R.id.icon)).setImageDrawable(app.loadIcon(pm)); + ((TextView) view.findViewById(R.id.prompt)).setText( + getString(R.string.prompt, app.loadLabel(pm), getString(R.string.app))); + ((CompoundButton) view.findViewById(R.id.check)).setOnCheckedChangeListener(this); + + + Builder builder = new AlertDialog.Builder(this); + + builder.setView(view); + + builder.setIconAttribute(android.R.attr.alertDialogIcon); + builder.setTitle(android.R.string.dialog_alert_title); + builder.setPositiveButton(android.R.string.ok,this); + builder.setNegativeButton(android.R.string.cancel,this); + + mAlert = builder.create(); + mAlert.setCanceledOnTouchOutside(false); + + mAlert.setOnShowListener (new OnShowListener() { + + @Override + public void onShow(DialogInterface dialog) { + mButton = mAlert.getButton(DialogInterface.BUTTON_POSITIVE); + mButton.setEnabled(false); + + } + }); + + //setCloseOnTouchOutside(false); + + mAlert.show(); + + } catch (Exception e) { + Log.e(TAG, "onResume", e); + finish(); + } + } + + @Override + public void onBackPressed() { + setResult(RESULT_CANCELED); + finish(); + } + + @Override + public void onCheckedChanged(CompoundButton button, boolean checked) { + mButton.setEnabled(checked); + } + + @Override + public void onClick(DialogInterface dialog, int which) { + + if (which == DialogInterface.BUTTON_POSITIVE) { + ExternalAppDatabase extapps = new ExternalAppDatabase(this); + extapps.addApp(mPackage); + setResult(RESULT_OK); + finish(); + } + + if (which == DialogInterface.BUTTON_NEGATIVE) { + setResult(RESULT_CANCELED); + finish(); + } + } + +} + diff --git a/main/src/main/java/de/blinkt/openvpn/api/ExternalAppDatabase.java b/main/src/main/java/de/blinkt/openvpn/api/ExternalAppDatabase.java new file mode 100644 index 00000000..02c369b1 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/api/ExternalAppDatabase.java @@ -0,0 +1,57 @@ +package de.blinkt.openvpn.api; + +import java.util.HashSet; +import java.util.Set; + +import android.content.Context; +import android.content.SharedPreferences; +import android.content.SharedPreferences.Editor; +import android.preference.PreferenceManager; + +public class ExternalAppDatabase { + + Context mContext; + + public ExternalAppDatabase(Context c) { + mContext =c; + } + + private final String PREFERENCES_KEY = "PREFERENCES_KEY"; + + boolean isAllowed(String packagename) { + Set<String> allowedapps = getExtAppList(); + + return allowedapps.contains(packagename); + + } + + public Set<String> getExtAppList() { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext); + return prefs.getStringSet(PREFERENCES_KEY, new HashSet<String>()); + } + + void addApp(String packagename) + { + Set<String> allowedapps = getExtAppList(); + allowedapps.add(packagename); + saveExtAppList(allowedapps); + } + + private void saveExtAppList( Set<String> allowedapps) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(mContext); + Editor prefedit = prefs.edit(); + prefedit.putStringSet(PREFERENCES_KEY, allowedapps); + prefedit.apply(); + } + + public void clearAllApiApps() { + saveExtAppList(new HashSet<String>()); + } + + public void removeApp(String packagename) { + Set<String> allowedapps = getExtAppList(); + allowedapps.remove(packagename); + saveExtAppList(allowedapps); + } + +} diff --git a/main/src/main/java/de/blinkt/openvpn/api/ExternalOpenVPNService.java b/main/src/main/java/de/blinkt/openvpn/api/ExternalOpenVPNService.java new file mode 100644 index 00000000..928a85eb --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/api/ExternalOpenVPNService.java @@ -0,0 +1,317 @@ +package de.blinkt.openvpn.api;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.lang.ref.WeakReference;
+import java.util.LinkedList;
+import java.util.List;
+
+import android.annotation.TargetApi;
+import android.app.Service;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.net.VpnService;
+import android.os.*;
+import de.blinkt.openvpn.R;
+import de.blinkt.openvpn.VpnProfile;
+import de.blinkt.openvpn.core.ConfigParser;
+import de.blinkt.openvpn.core.ConfigParser.ConfigParseError;
+import de.blinkt.openvpn.core.VpnStatus;
+import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus;
+import de.blinkt.openvpn.core.VpnStatus.StateListener;
+import de.blinkt.openvpn.core.OpenVpnService;
+import de.blinkt.openvpn.core.OpenVpnService.LocalBinder;
+import de.blinkt.openvpn.core.ProfileManager;
+import de.blinkt.openvpn.core.VPNLaunchHelper;
+
+@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
+public class ExternalOpenVPNService extends Service implements StateListener {
+
+ private static final int SEND_TOALL = 0;
+
+ final RemoteCallbackList<IOpenVPNStatusCallback> mCallbacks =
+ new RemoteCallbackList<IOpenVPNStatusCallback>();
+
+ private OpenVpnService mService;
+ private ExternalAppDatabase mExtAppDb;
+
+
+ private ServiceConnection mConnection = new ServiceConnection() {
+
+
+ @Override
+ public void onServiceConnected(ComponentName className,
+ IBinder service) {
+ // We've bound to LocalService, cast the IBinder and get LocalService instance
+ LocalBinder binder = (LocalBinder) service;
+ mService = binder.getService();
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName arg0) {
+ mService = null;
+ }
+
+ };
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ VpnStatus.addStateListener(this);
+ mExtAppDb = new ExternalAppDatabase(this);
+
+ Intent intent = new Intent(getBaseContext(), OpenVpnService.class);
+ intent.setAction(OpenVpnService.START_SERVICE);
+
+ bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
+ mHandler.setService(this);
+ }
+
+ private final IOpenVPNAPIService.Stub mBinder = new IOpenVPNAPIService.Stub() {
+
+ private void checkOpenVPNPermission() throws SecurityRemoteException {
+ PackageManager pm = getPackageManager();
+
+ for (String apppackage : mExtAppDb.getExtAppList()) {
+ ApplicationInfo app;
+ try {
+ app = pm.getApplicationInfo(apppackage, 0);
+ if (Binder.getCallingUid() == app.uid) {
+ return;
+ }
+ } catch (NameNotFoundException e) {
+ // App not found. Remove it from the list
+ mExtAppDb.removeApp(apppackage);
+ }
+
+ }
+ throw new SecurityException("Unauthorized OpenVPN API Caller");
+ }
+
+ @Override
+ public List<APIVpnProfile> getProfiles() throws RemoteException {
+ checkOpenVPNPermission();
+
+ ProfileManager pm = ProfileManager.getInstance(getBaseContext());
+
+ List<APIVpnProfile> profiles = new LinkedList<APIVpnProfile>();
+
+ for (VpnProfile vp : pm.getProfiles())
+ profiles.add(new APIVpnProfile(vp.getUUIDString(), vp.mName, vp.mUserEditable));
+
+ return profiles;
+ }
+
+ @Override
+ public void startProfile(String profileUUID) throws RemoteException {
+ checkOpenVPNPermission();
+
+ Intent shortVPNIntent = new Intent(Intent.ACTION_MAIN);
+ shortVPNIntent.setClass(getBaseContext(), de.blinkt.openvpn.LaunchVPN.class);
+ shortVPNIntent.putExtra(de.blinkt.openvpn.LaunchVPN.EXTRA_KEY, profileUUID);
+ shortVPNIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ startActivity(shortVPNIntent);
+ }
+
+ public void startVPN(String inlineconfig) throws RemoteException {
+ checkOpenVPNPermission();
+
+ ConfigParser cp = new ConfigParser();
+ try {
+ cp.parseConfig(new StringReader(inlineconfig));
+ VpnProfile vp = cp.convertProfile();
+ if (vp.checkProfile(getApplicationContext()) != R.string.no_error_found)
+ throw new RemoteException(getString(vp.checkProfile(getApplicationContext())));
+
+
+ ProfileManager.setTemporaryProfile(vp);
+ VPNLaunchHelper.startOpenVpn(vp, getBaseContext());
+
+
+ } catch (IOException e) {
+ throw new RemoteException(e.getMessage());
+ } catch (ConfigParseError e) {
+ throw new RemoteException(e.getMessage());
+ }
+ }
+
+ @Override
+ public boolean addVPNProfile(String name, String config) throws RemoteException {
+ checkOpenVPNPermission();
+
+ ConfigParser cp = new ConfigParser();
+ try {
+ cp.parseConfig(new StringReader(config));
+ VpnProfile vp = cp.convertProfile();
+ vp.mName = name;
+ ProfileManager pm = ProfileManager.getInstance(getBaseContext());
+ pm.addProfile(vp);
+ } catch (IOException e) {
+ VpnStatus.logException(e);
+ return false;
+ } catch (ConfigParseError e) {
+ VpnStatus.logException(e);
+ return false;
+ }
+
+ return true;
+ }
+
+
+ @Override
+ public Intent prepare(String packagename) {
+ if (new ExternalAppDatabase(ExternalOpenVPNService.this).isAllowed(packagename))
+ return null;
+
+ Intent intent = new Intent();
+ intent.setClass(ExternalOpenVPNService.this, ConfirmDialog.class);
+ return intent;
+ }
+
+ @Override
+ public Intent prepareVPNService() throws RemoteException {
+ checkOpenVPNPermission();
+
+ if (VpnService.prepare(ExternalOpenVPNService.this) == null)
+ return null;
+ else
+ return new Intent(getBaseContext(), GrantPermissionsActivity.class);
+ }
+
+
+ @Override
+ public void registerStatusCallback(IOpenVPNStatusCallback cb)
+ throws RemoteException {
+ checkOpenVPNPermission();
+
+ if (cb != null) {
+ cb.newStatus(mMostRecentState.vpnUUID, mMostRecentState.state,
+ mMostRecentState.logmessage, mMostRecentState.level.name());
+ mCallbacks.register(cb);
+ }
+
+
+ }
+
+ @Override
+ public void unregisterStatusCallback(IOpenVPNStatusCallback cb)
+ throws RemoteException {
+ checkOpenVPNPermission();
+
+ if (cb != null)
+ mCallbacks.unregister(cb);
+ }
+
+ @Override
+ public void disconnect() throws RemoteException {
+ checkOpenVPNPermission();
+ if (mService != null && mService.getManagement() != null)
+ mService.getManagement().stopVPN();
+ }
+
+ @Override
+ public void pause() throws RemoteException {
+ checkOpenVPNPermission();
+ if (mService != null)
+ mService.userPause(true);
+ }
+
+ @Override
+ public void resume() throws RemoteException {
+ checkOpenVPNPermission();
+ if (mService != null)
+ mService.userPause(false);
+
+ }
+ };
+
+
+ private UpdateMessage mMostRecentState;
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mBinder;
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ mCallbacks.kill();
+ unbindService(mConnection);
+ VpnStatus.removeStateListener(this);
+ }
+
+ class UpdateMessage {
+ public String state;
+ public String logmessage;
+ public ConnectionStatus level;
+ public String vpnUUID;
+
+ public UpdateMessage(String state, String logmessage, ConnectionStatus level) {
+ this.state = state;
+ this.logmessage = logmessage;
+ this.level = level;
+ }
+ }
+
+ @Override
+ public void updateState(String state, String logmessage, int resid, ConnectionStatus level) {
+ mMostRecentState = new UpdateMessage(state, logmessage, level);
+ if (ProfileManager.getLastConnectedVpn() != null)
+ mMostRecentState.vpnUUID = ProfileManager.getLastConnectedVpn().getUUIDString();
+
+ Message msg = mHandler.obtainMessage(SEND_TOALL, mMostRecentState);
+ msg.sendToTarget();
+
+ }
+
+ private static final OpenVPNServiceHandler mHandler = new OpenVPNServiceHandler();
+
+
+ static class OpenVPNServiceHandler extends Handler {
+ WeakReference<ExternalOpenVPNService> service = null;
+
+ private void setService(ExternalOpenVPNService eos) {
+ service = new WeakReference<ExternalOpenVPNService>(eos);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+
+ RemoteCallbackList<IOpenVPNStatusCallback> callbacks;
+ switch (msg.what) {
+ case SEND_TOALL:
+ if (service == null || service.get() == null)
+ return;
+
+ callbacks = service.get().mCallbacks;
+
+
+ // Broadcast to all clients the new value.
+ final int N = callbacks.beginBroadcast();
+ for (int i = 0; i < N; i++) {
+ try {
+ sendUpdate(callbacks.getBroadcastItem(i), (UpdateMessage) msg.obj);
+ } catch (RemoteException e) {
+ // The RemoteCallbackList will take care of removing
+ // the dead object for us.
+ }
+ }
+ callbacks.finishBroadcast();
+ break;
+ }
+ }
+
+ private void sendUpdate(IOpenVPNStatusCallback broadcastItem,
+ UpdateMessage um) throws RemoteException {
+ broadcastItem.newStatus(um.vpnUUID, um.state, um.logmessage, um.level.name());
+ }
+ }
+
+
+}
\ No newline at end of file diff --git a/main/src/main/java/de/blinkt/openvpn/api/GrantPermissionsActivity.java b/main/src/main/java/de/blinkt/openvpn/api/GrantPermissionsActivity.java new file mode 100644 index 00000000..659ec24b --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/api/GrantPermissionsActivity.java @@ -0,0 +1,26 @@ +package de.blinkt.openvpn.api; + +import android.app.Activity; +import android.content.Intent; +import android.net.VpnService; + +public class GrantPermissionsActivity extends Activity { + private static final int VPN_PREPARE = 0; + + @Override + protected void onStart() { + super.onStart(); + Intent i= VpnService.prepare(this); + if(i==null) + onActivityResult(VPN_PREPARE, RESULT_OK, null); + else + startActivityForResult(i, VPN_PREPARE); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + setResult(resultCode); + finish(); + } +} diff --git a/main/src/main/java/de/blinkt/openvpn/api/SecurityRemoteException.java b/main/src/main/java/de/blinkt/openvpn/api/SecurityRemoteException.java new file mode 100644 index 00000000..e6011aa3 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/api/SecurityRemoteException.java @@ -0,0 +1,12 @@ +package de.blinkt.openvpn.api;
+
+import android.os.RemoteException;
+
+public class SecurityRemoteException extends RemoteException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+}
diff --git a/main/src/main/java/de/blinkt/openvpn/core/CIDRIP.java b/main/src/main/java/de/blinkt/openvpn/core/CIDRIP.java new file mode 100644 index 00000000..960e7d11 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/core/CIDRIP.java @@ -0,0 +1,70 @@ +package de.blinkt.openvpn.core; + +import java.util.Locale; + +class CIDRIP { + String mIp; + int len; + + + public CIDRIP(String ip, String mask) { + mIp = ip; + long netmask = getInt(mask); + + // Add 33. bit to ensure the loop terminates + netmask += 1l << 32; + + int lenZeros = 0; + while ((netmask & 0x1) == 0) { + lenZeros++; + netmask = netmask >> 1; + } + // Check if rest of netmask is only 1s + if (netmask != (0x1ffffffffl >> lenZeros)) { + // Asume no CIDR, set /32 + len = 32; + } else { + len = 32 - lenZeros; + } + + } + + public CIDRIP(String address, int prefix_length) { + len = prefix_length; + mIp = address; + } + + @Override + public String toString() { + return String.format(Locale.ENGLISH, "%s/%d", mIp, len); + } + + public boolean normalise() { + long ip = getInt(mIp); + + long newip = ip & (0xffffffffl << (32 - len)); + if (newip != ip) { + mIp = String.format("%d.%d.%d.%d", (newip & 0xff000000) >> 24, (newip & 0xff0000) >> 16, (newip & 0xff00) >> 8, newip & 0xff); + return true; + } else { + return false; + } + } + + static long getInt(String ipaddr) { + String[] ipt = ipaddr.split("\\."); + long ip = 0; + + ip += Long.parseLong(ipt[0]) << 24; + ip += Integer.parseInt(ipt[1]) << 16; + ip += Integer.parseInt(ipt[2]) << 8; + ip += Integer.parseInt(ipt[3]); + + return ip; + } + + public long getInt() { + return getInt(mIp); + } + +}
\ No newline at end of file diff --git a/main/src/main/java/de/blinkt/openvpn/core/ConfigParser.java b/main/src/main/java/de/blinkt/openvpn/core/ConfigParser.java new file mode 100644 index 00000000..22cc5dce --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/core/ConfigParser.java @@ -0,0 +1,762 @@ +package de.blinkt.openvpn.core; + +import de.blinkt.openvpn.VpnProfile; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.Reader; +import java.util.Collections; +import java.util.HashMap; +import java.util.Locale; +import java.util.Vector; + +//! Openvpn Config FIle Parser, probably not 100% accurate but close enough + +// And remember, this is valid :) +// --<foo> +// bar +// </foo> +public class ConfigParser { + + + public static final String CONVERTED_PROFILE = "converted Profile"; + private HashMap<String, Vector<Vector<String>>> options = new HashMap<String, Vector<Vector<String>>>(); + private HashMap<String, Vector<String>> meta = new HashMap<String, Vector<String>>(); + + + private boolean extraRemotesAsCustom=false; + + public void parseConfig(Reader reader) throws IOException, ConfigParseError { + + + BufferedReader br =new BufferedReader(reader); + + while (true){ + String line = br.readLine(); + if(line==null) + break; + + // Check for OpenVPN Access Server Meta information + if (line.startsWith("# OVPN_ACCESS_SERVER_")) { + Vector<String> metaarg = parsemeta(line); + meta.put(metaarg.get(0),metaarg); + continue; + } + Vector<String> args = parseline(line); + + if(args.size() ==0) + continue; + + + if(args.get(0).startsWith("--")) + args.set(0, args.get(0).substring(2)); + + checkinlinefile(args,br); + + String optionname = args.get(0); + if(!options.containsKey(optionname)) { + options.put(optionname, new Vector<Vector<String>>()); + } + options.get(optionname).add(args); + } + } + + private Vector<String> parsemeta(String line) { + String meta = line.split("#\\sOVPN_ACCESS_SERVER_", 2)[1]; + String[] parts = meta.split("=",2); + Vector<String> rval = new Vector<String>(); + Collections.addAll(rval, parts); + return rval; + + } + + private void checkinlinefile(Vector<String> args, BufferedReader br) throws IOException, ConfigParseError { + String arg0 = args.get(0).trim(); + // CHeck for <foo> + if(arg0.startsWith("<") && arg0.endsWith(">")) { + String argname = arg0.substring(1, arg0.length()-1); + String inlinefile = VpnProfile.INLINE_TAG; + + String endtag = String.format("</%s>",argname); + do { + String line = br.readLine(); + if(line==null){ + throw new ConfigParseError(String.format("No endtag </%s> for starttag <%s> found",argname,argname)); + } + if(line.trim().equals(endtag)) + break; + else { + inlinefile+=line; + inlinefile+= "\n"; + } + } while(true); + + args.clear(); + args.add(argname); + args.add(inlinefile); + } + + } + + enum linestate { + initial, + readin_single_quote + , reading_quoted, reading_unquoted, done} + + private boolean space(char c) { + // I really hope nobody is using zero bytes inside his/her config file + // to sperate parameter but here we go: + return Character.isWhitespace(c) || c == '\0'; + + } + + public class ConfigParseError extends Exception { + private static final long serialVersionUID = -60L; + + public ConfigParseError(String msg) { + super(msg); + } + } + + + // adapted openvpn's parse function to java + private Vector<String> parseline(String line) throws ConfigParseError { + Vector<String> parameters = new Vector<String>(); + + if (line.length()==0) + return parameters; + + + linestate state = linestate.initial; + boolean backslash = false; + char out=0; + + int pos=0; + String currentarg=""; + + do { + // Emulate the c parsing ... + char in; + if(pos < line.length()) + in = line.charAt(pos); + else + in = '\0'; + + if (!backslash && in == '\\' && state != linestate.readin_single_quote) + { + backslash = true; + } + else + { + if (state == linestate.initial) + { + if (!space (in)) + { + if (in == ';' || in == '#') /* comment */ + break; + if (!backslash && in == '\"') + state = linestate.reading_quoted; + else if (!backslash && in == '\'') + state = linestate.readin_single_quote; + else + { + out = in; + state = linestate.reading_unquoted; + } + } + } + else if (state == linestate.reading_unquoted) + { + if (!backslash && space (in)) + state = linestate.done; + else + out = in; + } + else if (state == linestate.reading_quoted) + { + if (!backslash && in == '\"') + state = linestate.done; + else + out = in; + } + else if (state == linestate.readin_single_quote) + { + if (in == '\'') + state = linestate.done; + else + out = in; + } + + if (state == linestate.done) + { + /* ASSERT (parm_len > 0); */ + state = linestate.initial; + parameters.add(currentarg); + currentarg = ""; + out =0; + } + + if (backslash && out!=0) + { + if (!(out == '\\' || out == '\"' || space (out))) + { + throw new ConfigParseError("Options warning: Bad backslash ('\\') usage"); + } + } + backslash = false; + } + + /* store parameter character */ + if (out!=0) + { + currentarg+=out; + } + } while (pos++ < line.length()); + + return parameters; + } + + + final String[] unsupportedOptions = { "config", + "connection", + "proto-force", + "remote-random", + "tls-server" + + }; + + // Ignore all scripts + // in most cases these won't work and user who wish to execute scripts will + // figure out themselves + final String[] ignoreOptions = { "tls-client", + "askpass", + "auth-nocache", + "up", + "down", + "route-up", + "ipchange", + "route-up", + "route-pre-down", + "auth-user-pass-verify", + "dhcp-release", + "dhcp-renew", + "dh", + "group", + "ip-win32", + "management-hold", + "management", + "management-client", + "management-query-remote", + "management-query-passwords", + "management-query-proxy", + "management-external-key", + "management-forget-disconnect", + "management-signal", + "management-log-cache", + "management-up-down", + "management-client-user", + "management-client-group", + "pause-exit", + "plugin", + "machine-readable-output", + "persist-key", + "register-dns", + "route-delay", + "route-gateway", + "route-metric", + "route-method", + "status", + "script-security", + "show-net-up", + "suppress-timestamps", + "tmp-dir", + "tun-ipv6", + "topology", + "user", + "win-sys", + + }; + + final String[][] ignoreOptionsWithArg = + { + {"setenv", "IV_GUI_VER"}, + {"setenv", "IV_OPENVPN_GUI_VERSION"} + }; + + final String[] connectionOptions = { + "local", + "remote", + "float", + "port", +// "connect-retry", + "connect-timeout", + "connect-retry-max", + "link-mtu", + "tun-mtu", + "tun-mtu-extra", + "fragment", + "mtu-disc", + "local-port", + "remote-port", + "bind", + "nobind", + "proto", + "http-proxy", + "http-proxy-retry", + "http-proxy-timeout", + "http-proxy-option", + "socks-proxy", + "socks-proxy-retry", + "explicit-exit-notify", + "mssfix" + }; + + + // This method is far too long + public VpnProfile convertProfile() throws ConfigParseError{ + boolean noauthtypeset=true; + VpnProfile np = new VpnProfile(CONVERTED_PROFILE); + // Pull, client, tls-client + np.clearDefaults(); + + if(options.containsKey("client") || options.containsKey("pull")) { + np.mUsePull=true; + options.remove("pull"); + options.remove("client"); + } + + Vector<String> secret = getOption("secret", 1, 2); + if(secret!=null) + { + np.mAuthenticationType=VpnProfile.TYPE_STATICKEYS; + noauthtypeset=false; + np.mUseTLSAuth=true; + np.mTLSAuthFilename=secret.get(1); + if(secret.size()==3) + np.mTLSAuthDirection=secret.get(2); + + } + + Vector<Vector<String>> routes = getAllOption("route", 1, 4); + if(routes!=null) { + String routeopt = ""; + String routeExcluded = ""; + for(Vector<String> route:routes){ + String netmask = "255.255.255.255"; + String gateway = "vpn_gateway"; + + if(route.size() >= 3) + netmask = route.get(2); + if (route.size() >= 4) + gateway = route.get(3); + + String net = route.get(1); + try { + CIDRIP cidr = new CIDRIP(net, netmask); + if (gateway.equals("net_gateway")) + routeExcluded += cidr.toString() + " "; + else + routeopt+=cidr.toString() + " "; + } catch (ArrayIndexOutOfBoundsException aioob) { + throw new ConfigParseError("Could not parse netmask of route " + netmask); + } catch (NumberFormatException ne) { + throw new ConfigParseError("Could not parse netmask of route " + netmask); + } + + } + np.mCustomRoutes=routeopt; + np.mExcludedRoutes=routeExcluded; + } + + Vector<Vector<String>> routesV6 = getAllOption("route-ipv6", 1, 4); + if (routesV6!=null) { + String customIPv6Routes = ""; + for (Vector<String> route:routesV6){ + customIPv6Routes += route.get(1) + " "; + } + + np.mCustomRoutesv6 = customIPv6Routes; + } + + // Also recognize tls-auth [inline] direction ... + Vector<Vector<String>> tlsauthoptions = getAllOption("tls-auth", 1, 2); + if(tlsauthoptions!=null) { + for(Vector<String> tlsauth:tlsauthoptions) { + if(tlsauth!=null) + { + if(!tlsauth.get(1).equals("[inline]")) { + np.mTLSAuthFilename=tlsauth.get(1); + np.mUseTLSAuth=true; + } + if(tlsauth.size()==3) + np.mTLSAuthDirection=tlsauth.get(2); + } + } + } + + Vector<String> direction = getOption("key-direction", 1, 1); + if(direction!=null) + np.mTLSAuthDirection=direction.get(1); + + Vector<Vector<String>> defgw = getAllOption("redirect-gateway", 0, 5); + if(defgw != null) + { + np.mUseDefaultRoute=true; + checkRedirectParameters(np, defgw); + } + + Vector<Vector<String>> redirectPrivate = getAllOption("redirect-private",0,5); + if (redirectPrivate != null) + { + checkRedirectParameters(np,redirectPrivate); + } + Vector<String> dev =getOption("dev",1,1); + Vector<String> devtype =getOption("dev-type",1,1); + + if ((devtype != null && devtype.get(1).equals("tun")) || + (dev != null && dev.get(1).startsWith("tun")) || + (devtype == null && dev == null)) { + //everything okay + } else { + throw new ConfigParseError("Sorry. Only tun mode is supported. See the FAQ for more detail"); + } + + + + Vector<String> mode =getOption("mode",1,1); + if (mode != null){ + if(!mode.get(1).equals("p2p")) + throw new ConfigParseError("Invalid mode for --mode specified, need p2p"); + } + + Vector<String> port = getOption("port", 1,1); + if(port!=null){ + np.mServerPort = port.get(1); + } + + Vector<String> rport = getOption("rport", 1,1); + if(port!=null){ + np.mServerPort = port.get(1); + } + + Vector<String> proto = getOption("proto", 1,1); + if(proto!=null){ + np.mUseUdp=isUdpProto(proto.get(1)); + } + + // Parse remote config + Vector<Vector<String>> remotes = getAllOption("remote",1,3); + + if(remotes!=null && remotes.size()>=1 ) { + Vector<String> remote = remotes.get(0); + switch (remote.size()) { + case 4: + np.mUseUdp=isUdpProto(remote.get(3)); + case 3: + np.mServerPort = remote.get(2); + case 2: + np.mServerName = remote.get(1); + } + } + + + + Vector<Vector<String>> dhcpoptions = getAllOption("dhcp-option", 2, 2); + if(dhcpoptions!=null) { + for(Vector<String> dhcpoption:dhcpoptions) { + String type=dhcpoption.get(1); + String arg = dhcpoption.get(2); + if(type.equals("DOMAIN")) { + np.mSearchDomain=dhcpoption.get(2); + } else if(type.equals("DNS")) { + np.mOverrideDNS=true; + if(np.mDNS1.equals(VpnProfile.DEFAULT_DNS1)) + np.mDNS1=arg; + else + np.mDNS2=arg; + } + } + } + + Vector<String> ifconfig = getOption("ifconfig", 2, 2); + if(ifconfig!=null) { + try { + CIDRIP cidr = new CIDRIP(ifconfig.get(1), ifconfig.get(2)); + np.mIPv4Address=cidr.toString(); + } catch (NumberFormatException nfe) { + throw new ConfigParseError("Could not pase ifconfig IP address: " + nfe.getLocalizedMessage()); + } + + } + + if(getOption("remote-random-hostname", 0, 0)!=null) + np.mUseRandomHostname=true; + + if(getOption("float", 0, 0)!=null) + np.mUseFloat=true; + + if(getOption("comp-lzo", 0, 1)!=null) + np.mUseLzo=true; + + Vector<String> cipher = getOption("cipher", 1, 1); + if(cipher!=null) + np.mCipher= cipher.get(1); + + Vector<String> auth = getOption("auth", 1, 1); + if(auth!=null) + np.mAuth = auth.get(1); + + + Vector<String> ca = getOption("ca",1,1); + if(ca!=null){ + np.mCaFilename = ca.get(1); + } + + Vector<String> cert = getOption("cert",1,1); + if(cert!=null){ + np.mClientCertFilename = cert.get(1); + np.mAuthenticationType = VpnProfile.TYPE_CERTIFICATES; + noauthtypeset=false; + } + Vector<String> key= getOption("key",1,1); + if(key!=null) + np.mClientKeyFilename=key.get(1); + + Vector<String> pkcs12 = getOption("pkcs12",1,1); + if(pkcs12!=null) { + np.mPKCS12Filename = pkcs12.get(1); + np.mAuthenticationType = VpnProfile.TYPE_KEYSTORE; + noauthtypeset=false; + } + + + Vector<String> compatnames = getOption("compat-names",1,2); + Vector<String> nonameremapping = getOption("no-name-remapping",1,1); + Vector<String> tlsremote = getOption("tls-remote",1,1); + if(tlsremote!=null){ + np.mRemoteCN = tlsremote.get(1); + np.mCheckRemoteCN=true; + np.mX509AuthType = VpnProfile.X509_VERIFY_TLSREMOTE; + + if((compatnames!=null && compatnames.size() > 2) || + (nonameremapping!=null)) + np.mX509AuthType = VpnProfile.X509_VERIFY_TLSREMOTE_COMPAT_NOREMAPPING; + } + + Vector<String> verifyx509name = getOption("verify-x509-name",1,2); + if(verifyx509name!=null){ + np.mRemoteCN = verifyx509name.get(1); + np.mCheckRemoteCN=true; + if(verifyx509name.size()>2) { + if (verifyx509name.get(2).equals("name")) + np.mX509AuthType=VpnProfile.X509_VERIFY_TLSREMOTE_RDN; + else if (verifyx509name.get(2).equals("name-prefix")) + np.mX509AuthType=VpnProfile.X509_VERIFY_TLSREMOTE_RDN_PREFIX; + else + throw new ConfigParseError("Unknown parameter to x509-verify-name: " + verifyx509name.get(2) ); + } else { + np.mX509AuthType = VpnProfile.X509_VERIFY_TLSREMOTE_DN; + } + + } + + + Vector<String> verb = getOption("verb",1,1); + if(verb!=null){ + np.mVerb=verb.get(1); + } + + + if(getOption("nobind", 0, 0) != null) + np.mNobind=true; + + if(getOption("persist-tun", 0,0) != null) + np.mPersistTun=true; + + Vector<String> connectretry = getOption("connect-retry", 1, 1); + if(connectretry!=null) + np.mConnectRetry =connectretry.get(1); + + Vector<String> connectretrymax = getOption("connect-retry-max", 1, 1); + if(connectretrymax!=null) + np.mConnectRetryMax =connectretrymax.get(1); + + Vector<Vector<String>> remotetls = getAllOption("remote-cert-tls", 1, 1); + if(remotetls!=null) + if(remotetls.get(0).get(1).equals("server")) + np.mExpectTLSCert=true; + else + options.put("remotetls",remotetls); + + Vector<String> authuser = getOption("auth-user-pass",0,1); + if(authuser !=null){ + if(noauthtypeset) { + np.mAuthenticationType=VpnProfile.TYPE_USERPASS; + } else if(np.mAuthenticationType==VpnProfile.TYPE_CERTIFICATES) { + np.mAuthenticationType=VpnProfile.TYPE_USERPASS_CERTIFICATES; + } else if(np.mAuthenticationType==VpnProfile.TYPE_KEYSTORE) { + np.mAuthenticationType=VpnProfile.TYPE_USERPASS_KEYSTORE; + } + if(authuser.size()>1) { + // Set option value to password get to get cance to embed later. + np.mUsername=null; + np.mPassword=authuser.get(1); + useEmbbedUserAuth(np,authuser.get(1)); + } + } + + // Parse OpenVPN Access Server extra + Vector<String> friendlyname = meta.get("FRIENDLY_NAME"); + if(friendlyname !=null && friendlyname.size() > 1) + np.mName=friendlyname.get(1); + + + Vector<String> ocusername = meta.get("USERNAME"); + if(ocusername !=null && ocusername.size() > 1) + np.mUsername=ocusername.get(1); + + // Check the other options + if(remotes !=null && remotes.size()>1 && extraRemotesAsCustom) { + // first is already added + remotes.remove(0); + np.mCustomConfigOptions += getOptionStrings(remotes); + np.mUseCustomConfig=true; + + } + checkIgnoreAndInvalidOptions(np); + fixup(np); + + return np; + } + + private void checkRedirectParameters(VpnProfile np, Vector<Vector<String>> defgw) { + for (Vector<String> redirect: defgw) + for (int i=1;i<redirect.size();i++){ + if (defgw.get(i).equals("block-local")) + np.mAllowLocalLAN=false; + else if (defgw.get(i).equals("unblock-local")) + np.mAllowLocalLAN=true; + } + } + + public void useExtraRemotesAsCustom(boolean b) { + this.extraRemotesAsCustom = b; + } + + private boolean isUdpProto(String proto) throws ConfigParseError { + boolean isudp; + if(proto.equals("udp") || proto.equals("udp6")) + isudp=true; + else if (proto.equals("tcp-client") || + proto.equals("tcp") || + proto.equals("tcp6") || + proto.endsWith("tcp6-client")) + isudp =false; + else + throw new ConfigParseError("Unsupported option to --proto " + proto); + return isudp; + } + + static public void useEmbbedUserAuth(VpnProfile np,String inlinedata) + { + String data = VpnProfile.getEmbeddedContent(inlinedata); + String[] parts = data.split("\n"); + if(parts.length >= 2) { + np.mUsername=parts[0]; + np.mPassword=parts[1]; + } + } + + private void checkIgnoreAndInvalidOptions(VpnProfile np) throws ConfigParseError { + for(String option:unsupportedOptions) + if(options.containsKey(option)) + throw new ConfigParseError(String.format("Unsupported Option %s encountered in config file. Aborting",option)); + + for(String option:ignoreOptions) + // removing an item which is not in the map is no error + options.remove(option); + + + + + if(options.size()> 0) { + np.mCustomConfigOptions += "# These Options were found in the config file do not map to config settings:\n"; + + for(Vector<Vector<String>> option:options.values()) { + + np.mCustomConfigOptions += getOptionStrings(option); + + } + np.mUseCustomConfig=true; + + } + } + + + boolean ignoreThisOption(Vector<String> option) { + for (String[] ignoreOption : ignoreOptionsWithArg) { + + if (option.size() < ignoreOption.length) + continue; + + boolean ignore = true; + for (int i = 0; i < ignoreOption.length; i++) { + if (!ignoreOption[i].equals(option.get(i))) + ignore = false; + } + if (ignore) + return true; + + } + return false; + } + + private String getOptionStrings(Vector<Vector<String>> option) { + String custom = ""; + for (Vector<String> optionsline : option) { + if (!ignoreThisOption(optionsline)) { + for (String arg : optionsline) + custom += VpnProfile.openVpnEscape(arg) + " "; + custom += "\n"; + } + } + return custom; + } + + + private void fixup(VpnProfile np) { + if(np.mRemoteCN.equals(np.mServerName)) { + np.mRemoteCN=""; + } + } + + private Vector<String> getOption(String option, int minarg, int maxarg) throws ConfigParseError { + Vector<Vector<String>> alloptions = getAllOption(option, minarg, maxarg); + if(alloptions==null) + return null; + else + return alloptions.lastElement(); + } + + + private Vector<Vector<String>> getAllOption(String option, int minarg, int maxarg) throws ConfigParseError { + Vector<Vector<String>> args = options.get(option); + if(args==null) + return null; + + for(Vector<String> optionline:args) + + if(optionline.size()< (minarg+1) || optionline.size() > maxarg+1) { + String err = String.format(Locale.getDefault(),"Option %s has %d parameters, expected between %d and %d", + option,optionline.size()-1,minarg,maxarg ); + throw new ConfigParseError(err); + } + options.remove(option); + return args; + } + +} + + + + diff --git a/main/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java b/main/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java new file mode 100644 index 00000000..250edf42 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java @@ -0,0 +1,239 @@ +package de.blinkt.openvpn.core;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+import android.net.NetworkInfo.State;
+import android.preference.PreferenceManager;
+import de.blinkt.openvpn.R;
+import de.blinkt.openvpn.core.VpnStatus.ByteCountListener;
+
+import java.util.LinkedList;
+
+import static de.blinkt.openvpn.core.OpenVPNManagement.pauseReason;
+
+public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountListener {
+ private int lastNetwork = -1;
+ private OpenVPNManagement mManagement;
+
+ // Window time in s
+ private final int TRAFFIC_WINDOW = 60;
+ // Data traffic limit in bytes
+ private final long TRAFFIC_LIMIT = 64 * 1024;
+
+
+ connectState network = connectState.DISCONNECTED;
+ connectState screen = connectState.SHOULDBECONNECTED;
+ connectState userpause = connectState.SHOULDBECONNECTED;
+
+ private String lastStateMsg = null;
+
+ enum connectState {
+ SHOULDBECONNECTED,
+ PENDINGDISCONNECT,
+ DISCONNECTED
+ }
+
+ static class Datapoint {
+ private Datapoint(long t, long d) {
+ timestamp = t;
+ data = d;
+ }
+
+ long timestamp;
+ long data;
+ }
+
+ LinkedList<Datapoint> trafficdata = new LinkedList<DeviceStateReceiver.Datapoint>();
+
+ @Override
+ public void updateByteCount(long in, long out, long diffIn, long diffOut) {
+ if (screen != connectState.PENDINGDISCONNECT)
+ return;
+
+ long total = diffIn + diffOut;
+ trafficdata.add(new Datapoint(System.currentTimeMillis(), total));
+
+ while (trafficdata.getFirst().timestamp <= (System.currentTimeMillis() - TRAFFIC_WINDOW * 1000)) {
+ trafficdata.removeFirst();
+ }
+
+ long windowtraffic = 0;
+ for (Datapoint dp : trafficdata)
+ windowtraffic += dp.data;
+
+ if (windowtraffic < TRAFFIC_LIMIT) {
+ screen = connectState.DISCONNECTED;
+ VpnStatus.logInfo(R.string.screenoff_pause,
+ OpenVpnService.humanReadableByteCount(TRAFFIC_LIMIT, false), TRAFFIC_WINDOW);
+
+ mManagement.pause(getPauseReason());
+ }
+ }
+
+
+ public void userPause(boolean pause) {
+ if (pause) {
+ userpause = connectState.DISCONNECTED;
+ // Check if we should disconnect
+ mManagement.pause(getPauseReason());
+ } else {
+ boolean wereConnected = shouldBeConnected();
+ userpause = connectState.SHOULDBECONNECTED;
+ if (shouldBeConnected() && !wereConnected)
+ mManagement.resume();
+ else
+ // Update the reason why we currently paused
+ mManagement.pause(getPauseReason());
+ }
+ }
+
+ public DeviceStateReceiver(OpenVPNManagement magnagement) {
+ super();
+ mManagement = magnagement;
+ }
+
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+
+
+ if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
+ networkStateChange(context);
+ } else if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) {
+ boolean screenOffPause = prefs.getBoolean("screenoff", false);
+
+ if (screenOffPause) {
+ if (!ProfileManager.getLastConnectedVpn().mPersistTun)
+ VpnStatus.logError(R.string.screen_nopersistenttun);
+
+ screen = connectState.PENDINGDISCONNECT;
+ fillTrafficData();
+ if (network == connectState.DISCONNECTED || userpause == connectState.DISCONNECTED)
+ screen = connectState.DISCONNECTED;
+ }
+ } else if (Intent.ACTION_SCREEN_ON.equals(intent.getAction())) {
+ // Network was disabled because screen off
+ boolean connected = shouldBeConnected();
+ screen = connectState.SHOULDBECONNECTED;
+
+ /* should be connected has changed because the screen is on now, connect the VPN */
+ if (shouldBeConnected() != connected)
+ mManagement.resume();
+ else if (!shouldBeConnected())
+ /*Update the reason why we are still paused */
+ mManagement.pause(getPauseReason());
+
+ }
+ }
+
+
+ private void fillTrafficData() {
+ trafficdata.add(new Datapoint(System.currentTimeMillis(), TRAFFIC_LIMIT));
+ }
+
+
+ public void networkStateChange(Context context) {
+ NetworkInfo networkInfo = getCurrentNetworkInfo(context);
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+ boolean sendusr1 = prefs.getBoolean("netchangereconnect", true);
+
+
+ String netstatestring;
+ if (networkInfo == null) {
+ netstatestring = "not connected";
+ } else {
+ String subtype = networkInfo.getSubtypeName();
+ if (subtype == null)
+ subtype = "";
+ String extrainfo = networkInfo.getExtraInfo();
+ if (extrainfo == null)
+ extrainfo = "";
+
+ /*
+ if(networkInfo.getType()==android.net.ConnectivityManager.TYPE_WIFI) {
+ WifiManager wifiMgr = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
+ WifiInfo wifiinfo = wifiMgr.getConnectionInfo();
+ extrainfo+=wifiinfo.getBSSID();
+
+ subtype += wifiinfo.getNetworkId();
+ }*/
+
+
+ netstatestring = String.format("%2$s %4$s to %1$s %3$s", networkInfo.getTypeName(),
+ networkInfo.getDetailedState(), extrainfo, subtype);
+ }
+
+ if (networkInfo != null && networkInfo.getState() == State.CONNECTED) {
+ int newnet = networkInfo.getType();
+ network = connectState.SHOULDBECONNECTED;
+
+ if (sendusr1 && lastNetwork != newnet) {
+ if (screen == connectState.PENDINGDISCONNECT)
+ screen = connectState.DISCONNECTED;
+
+ if (shouldBeConnected()) {
+ if (lastNetwork == -1) {
+ mManagement.resume();
+ } else {
+ mManagement.reconnect();
+ }
+ }
+
+
+ lastNetwork = newnet;
+ }
+ } else if (networkInfo == null) {
+ // Not connected, stop openvpn, set last connected network to no network
+ lastNetwork = -1;
+ if (sendusr1) {
+ network = connectState.DISCONNECTED;
+
+ // Set screen state to be disconnected if disconnect pending
+ if (screen == connectState.PENDINGDISCONNECT)
+ screen = connectState.DISCONNECTED;
+
+ mManagement.pause(getPauseReason());
+ }
+ }
+
+
+ if (!netstatestring.equals(lastStateMsg))
+ VpnStatus.logInfo(R.string.netstatus, netstatestring);
+ lastStateMsg = netstatestring;
+
+ }
+
+ public boolean isUserPaused() {
+ return userpause == connectState.DISCONNECTED;
+ }
+
+ private boolean shouldBeConnected() {
+ return (screen == connectState.SHOULDBECONNECTED && userpause == connectState.SHOULDBECONNECTED &&
+ network == connectState.SHOULDBECONNECTED);
+ }
+
+ private pauseReason getPauseReason() {
+ if (userpause == connectState.DISCONNECTED)
+ return pauseReason.userPause;
+
+ if (screen == connectState.DISCONNECTED)
+ return pauseReason.screenOff;
+
+ if (network == connectState.DISCONNECTED)
+ return pauseReason.noNetwork;
+
+ return pauseReason.userPause;
+ }
+
+ private NetworkInfo getCurrentNetworkInfo(Context context) {
+ ConnectivityManager conn = (ConnectivityManager)
+ context.getSystemService(Context.CONNECTIVITY_SERVICE);
+
+ return conn.getActiveNetworkInfo();
+ }
+}
diff --git a/main/src/main/java/de/blinkt/openvpn/core/GetRestrictionReceiver.java b/main/src/main/java/de/blinkt/openvpn/core/GetRestrictionReceiver.java new file mode 100644 index 00000000..7f8498d5 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/core/GetRestrictionReceiver.java @@ -0,0 +1,47 @@ +package de.blinkt.openvpn.core; + +import android.annotation.TargetApi; +import android.app.Activity; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.RestrictionEntry; +import android.os.Build; +import android.os.Bundle; + +import java.util.ArrayList; + +import de.blinkt.openvpn.R; + +/** + * Created by arne on 25.07.13. + */ +@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) +public class GetRestrictionReceiver extends BroadcastReceiver { + @Override + public void onReceive(final Context context, Intent intent) { + final PendingResult result = goAsync(); + + new Thread() { + @Override + public void run() { + final Bundle extras = new Bundle(); + + ArrayList<RestrictionEntry> restrictionEntries = initRestrictions(context); + + extras.putParcelableArrayList(Intent.EXTRA_RESTRICTIONS_LIST, restrictionEntries); + result.setResult(Activity.RESULT_OK,null,extras); + result.finish(); + } + }.run(); + } + + private ArrayList<RestrictionEntry> initRestrictions(Context context) { + ArrayList<RestrictionEntry> restrictions = new ArrayList<RestrictionEntry>(); + RestrictionEntry allowChanges = new RestrictionEntry("allow_changes",false); + allowChanges.setTitle(context.getString(R.string.allow_vpn_changes)); + restrictions.add(allowChanges); + + return restrictions; + } +} diff --git a/main/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java b/main/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java new file mode 100644 index 00000000..1daa3433 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/core/ICSOpenVPNApplication.java @@ -0,0 +1,14 @@ +package de.blinkt.openvpn.core; + +import android.app.Application; + +/** + * Created by arne on 28.12.13. + */ +public class ICSOpenVPNApplication extends Application { + @Override + public void onCreate() { + super.onCreate(); + PRNGFixes.apply(); + } +} diff --git a/main/src/main/java/de/blinkt/openvpn/core/NativeUtils.java b/main/src/main/java/de/blinkt/openvpn/core/NativeUtils.java new file mode 100644 index 00000000..a2c4796d --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/core/NativeUtils.java @@ -0,0 +1,13 @@ +package de.blinkt.openvpn.core; + +import java.security.InvalidKeyException; + +public class NativeUtils { + public static native byte[] rsasign(byte[] input,int pkey) throws InvalidKeyException; + static native void jniclose(int fdint); + + static { + System.loadLibrary("stlport_shared"); + System.loadLibrary("opvpnutil"); + } +} diff --git a/main/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java b/main/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java new file mode 100644 index 00000000..c7d09065 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/core/NetworkSpace.java @@ -0,0 +1,274 @@ +package de.blinkt.openvpn.core; + +import android.os.Build; +import android.text.TextUtils; + +import java.math.BigInteger; +import java.net.Inet6Address; +import java.util.*; + +public class NetworkSpace { + + + static class ipAddress implements Comparable<ipAddress> { + private BigInteger netAddress; + public int networkMask; + private boolean included; + private boolean isV4; + + + @Override + public int compareTo(ipAddress another) { + int comp = getFirstAddress().compareTo(another.getFirstAddress()); + if (comp != 0) + return comp; + + // bigger mask means smaller address block + if (networkMask > another.networkMask) + return -1; + else if (another.networkMask == networkMask) + return 0; + else + return 1; + + + } + + public ipAddress(CIDRIP ip, boolean include) { + included = include; + netAddress = BigInteger.valueOf(ip.getInt()); + networkMask = ip.len; + isV4 = true; + } + + public ipAddress(Inet6Address address, int mask, boolean include) { + networkMask = mask; + included = include; + + int s = 128; + + netAddress = BigInteger.ZERO; + for (byte b : address.getAddress()) { + s -= 16; + netAddress = netAddress.add(BigInteger.valueOf(b).shiftLeft(s)); + } + } + + public BigInteger getLastAddress() { + return getMaskedAddress(true); + } + + + public BigInteger getFirstAddress() { + return getMaskedAddress(false); + } + + + private BigInteger getMaskedAddress(boolean one) { + BigInteger numAddress = netAddress; + + int numBits; + if (isV4) { + numBits = 32 - networkMask; + } else { + numBits = 128 - networkMask; + } + + for (int i = 0; i < numBits; i++) { + if (one) + numAddress = numAddress.setBit(i); + else + numAddress = numAddress.clearBit(i); + } + return numAddress; + } + + + @Override + public String toString() { + //String in = included ? "+" : "-"; + if (isV4) + return String.format(Locale.US,"%s/%d", getIPv4Address(), networkMask); + else + return String.format(Locale.US, "%s/%d", getIPv6Address(), networkMask); + } + + ipAddress(BigInteger baseAddress, int mask, boolean included, boolean isV4) { + this.netAddress = baseAddress; + this.networkMask = mask; + this.included = included; + this.isV4 = isV4; + } + + + public ipAddress[] split() { + ipAddress firsthalf = new ipAddress(getFirstAddress(), networkMask + 1, included, isV4); + ipAddress secondhalf = new ipAddress(firsthalf.getLastAddress().add(BigInteger.ONE), networkMask + 1, included, isV4); + assert secondhalf.getLastAddress().equals(getLastAddress()); + return new ipAddress[]{firsthalf, secondhalf}; + } + + String getIPv4Address() { + assert (isV4); + assert (netAddress.longValue() <= 0xffffffffl); + assert (netAddress.longValue() >= 0); + long ip = netAddress.longValue(); + return String.format(Locale.US, "%d.%d.%d.%d", (ip >> 24) % 256, (ip >> 16) % 256, (ip >> 8) % 256, ip % 256); + } + + String getIPv6Address() { + assert (!isV4); + BigInteger r = netAddress; + if (r.longValue() == 0) + return "::"; + + Vector<String> parts = new Vector<String>(); + while (r.compareTo(BigInteger.ZERO) == 1) { + parts.add(0, String.format(Locale.US, "%x", r.mod(BigInteger.valueOf(256)).longValue())); + r = r.shiftRight(16); + } + + return TextUtils.join(":", parts); + } + + public boolean containsNet(ipAddress network) { + return getFirstAddress().compareTo(network.getFirstAddress()) != 1 && + getLastAddress().compareTo(network.getLastAddress()) != -1; + } + } + + + TreeSet<ipAddress> mIpAddresses = new TreeSet<ipAddress>(); + + + public Collection<ipAddress> getNetworks(boolean included) { + Vector<ipAddress> ips = new Vector<ipAddress>(); + for (ipAddress ip : mIpAddresses) { + if (ip.included == included) + ips.add(ip); + } + return ips; + } + + public void clear() { + mIpAddresses.clear(); + } + + + void addIP(CIDRIP cidrIp, boolean include) { + + mIpAddresses.add(new ipAddress(cidrIp, include)); + } + + void addIPv6(Inet6Address address, int mask, boolean included) { + mIpAddresses.add(new ipAddress(address, mask, included)); + } + + TreeSet<ipAddress> generateIPList() { + TreeSet<ipAddress> ipsSorted = new TreeSet<ipAddress>(mIpAddresses); + Iterator<ipAddress> it = ipsSorted.iterator(); + + ipAddress currentNet = null; + if (it.hasNext()) + currentNet = it.next(); + while (it.hasNext()) { + // Check if it and the next of it are compatbile + ipAddress nextNet = it.next(); + + assert currentNet != null; + if (currentNet.getLastAddress().compareTo(nextNet.getFirstAddress()) == -1) { + // Everything good, no overlapping nothing to do + currentNet = nextNet; + } else { + // This network is smaller or equal to the next but has the same base address + if (currentNet.getFirstAddress().equals(nextNet.getFirstAddress()) && currentNet.networkMask >= nextNet.networkMask) { + if (currentNet.included == nextNet.included) { + ipsSorted.remove(currentNet); + } else { + + // our currentnet is included in next and nextnet needs to be split + ipsSorted.remove(nextNet); + ipAddress[] newNets = nextNet.split(); + + if (newNets[0].getLastAddress().equals(currentNet.getLastAddress())) { + assert (newNets[0].networkMask == currentNet.networkMask); + // Don't add the lower half that would conflict with currentNet + } else { + ipsSorted.add(newNets[0]); + } + + ipsSorted.add(newNets[1]); + } + } else { + assert (currentNet.networkMask < nextNet.networkMask); + assert (nextNet.getFirstAddress().compareTo(currentNet.getFirstAddress()) == 1); + // This network is bigger than the next and last ip of current >= next + assert (currentNet.getLastAddress().compareTo(nextNet.getLastAddress()) != -1); + + if (currentNet.included == nextNet.included) { + ipsSorted.remove(nextNet); + } else { + ipsSorted.remove(currentNet); + ipAddress[] newNets = currentNet.split(); + + ipsSorted.add(newNets[0]); + + if (newNets[1].networkMask == nextNet.networkMask) { + assert (newNets[1].getFirstAddress().equals(nextNet.getFirstAddress())); + assert (newNets[1].getLastAddress().equals(currentNet.getLastAddress())); + } else { + ipsSorted.add(newNets[1]); + } + } + } + // Reset iterator + it = ipsSorted.iterator(); + currentNet = it.next(); + } + + } + + return ipsSorted; + } + + Collection<ipAddress> getPositiveIPList() { + TreeSet<ipAddress> ipsSorted = generateIPList(); + + Vector<ipAddress> ips = new Vector<ipAddress>(); + for (ipAddress ia : ipsSorted) { + if (ia.included) + ips.add(ia); + } + + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) { + // Include postive routes from the original set under < 4.4 since these might overrule the local + // network but only if no smaller negative route exists + for(ipAddress origIp: mIpAddresses){ + if (!origIp.included) + continue; + + // The netspace exists + if(ipsSorted.contains(origIp)) + continue; + + boolean skipIp=false; + // If there is any smaller net that is excluded we may not add the positive route back + for (ipAddress calculatedIp: ipsSorted) { + if(!calculatedIp.included && origIp.containsNet(calculatedIp)) { + skipIp=true; + break; + } + } + if (skipIp) + continue; + + // It is safe to include the IP + ips.add(origIp); + } + + } + + return ips; + } + +} diff --git a/main/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java b/main/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java new file mode 100644 index 00000000..ce8d38c2 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java @@ -0,0 +1,20 @@ +package de.blinkt.openvpn.core; + +public interface OpenVPNManagement { + enum pauseReason { + noNetwork, + userPause, + screenOff + } + + int mBytecountInterval =2; + + void reconnect(); + + void pause(pauseReason reason); + + void resume(); + + boolean stopVPN(); + +} diff --git a/main/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java b/main/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java new file mode 100644 index 00000000..dacd41c9 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/core/OpenVPNThread.java @@ -0,0 +1,174 @@ +package de.blinkt.openvpn.core;
+
+import android.util.Log;
+import de.blinkt.openvpn.R;
+import de.blinkt.openvpn.VpnProfile;
+import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus;
+import de.blinkt.openvpn.core.VpnStatus.LogItem;
+
+import java.io.*;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class OpenVPNThread implements Runnable {
+ private static final String DUMP_PATH_STRING = "Dump path: ";
+ private static final String TAG = "OpenVPN";
+ public static final int M_FATAL = (1 << 4);
+ public static final int M_NONFATAL = (1 << 5);
+ public static final int M_WARN = (1 << 6);
+ public static final int M_DEBUG = (1 << 7);
+ private String[] mArgv;
+ private Process mProcess;
+ private String mNativeDir;
+ private OpenVpnService mService;
+ private String mDumpPath;
+ private Map<String, String> mProcessEnv;
+
+ public OpenVPNThread(OpenVpnService service,String[] argv, Map<String,String> processEnv, String nativelibdir)
+ {
+ mArgv = argv;
+ mNativeDir = nativelibdir;
+ mService = service;
+ mProcessEnv = processEnv;
+ }
+
+ public void stopProcess() {
+ mProcess.destroy();
+ }
+
+
+
+ @Override
+ public void run() {
+ try {
+ Log.i(TAG, "Starting openvpn");
+ startOpenVPNThreadArgs(mArgv, mProcessEnv);
+ Log.i(TAG, "Giving up");
+ } catch (Exception e) {
+ VpnStatus.logException("Starting OpenVPN Thread" ,e);
+ Log.e(TAG, "OpenVPNThread Got " + e.toString());
+ } finally {
+ int exitvalue = 0;
+ try {
+ if (mProcess!=null)
+ exitvalue = mProcess.waitFor();
+ } catch ( IllegalThreadStateException ite) {
+ VpnStatus.logError("Illegal Thread state: " + ite.getLocalizedMessage());
+ } catch (InterruptedException ie) {
+ VpnStatus.logError("InterruptedException: " + ie.getLocalizedMessage());
+ }
+ if( exitvalue != 0)
+ VpnStatus.logError("Process exited with exit value " + exitvalue);
+
+ VpnStatus.updateStateString("NOPROCESS", "No process running.", R.string.state_noprocess, ConnectionStatus.LEVEL_NOTCONNECTED);
+ if(mDumpPath!=null) {
+ try {
+ BufferedWriter logout = new BufferedWriter(new FileWriter(mDumpPath + ".log"));
+ SimpleDateFormat timeformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.GERMAN);
+ for(LogItem li : VpnStatus.getlogbuffer()){
+ String time = timeformat.format(new Date(li.getLogtime()));
+ logout.write(time +" " + li.getString(mService) + "\n");
+ }
+ logout.close();
+ VpnStatus.logError(R.string.minidump_generated);
+ } catch (IOException e) {
+ VpnStatus.logError("Writing minidump log: " + e.getLocalizedMessage());
+ }
+ }
+
+ mService.processDied();
+ Log.i(TAG, "Exiting");
+ }
+ }
+
+ private void startOpenVPNThreadArgs(String[] argv, Map<String, String> env) {
+ LinkedList<String> argvlist = new LinkedList<String>();
+
+ Collections.addAll(argvlist, argv);
+
+ ProcessBuilder pb = new ProcessBuilder(argvlist);
+ // Hack O rama
+
+ String lbpath = genLibraryPath(argv, pb);
+
+ pb.environment().put("LD_LIBRARY_PATH", lbpath);
+
+ // Add extra variables
+ for(Entry<String,String> e:env.entrySet()){
+ pb.environment().put(e.getKey(), e.getValue());
+ }
+ pb.redirectErrorStream(true);
+ try {
+ mProcess = pb.start();
+ // Close the output, since we don't need it
+ mProcess.getOutputStream().close();
+ InputStream in = mProcess.getInputStream();
+ BufferedReader br = new BufferedReader(new InputStreamReader(in));
+
+ while(true) {
+ String logline = br.readLine();
+ if(logline==null)
+ return;
+
+ if (logline.startsWith(DUMP_PATH_STRING))
+ mDumpPath = logline.substring(DUMP_PATH_STRING.length());
+
+
+ // 1380308330.240114 18000002 Send to HTTP proxy: 'X-Online-Host: bla.blabla.com'
+
+ Pattern p = Pattern.compile("(\\d+).(\\d+) ([0-9a-f])+ (.*)");
+ Matcher m = p.matcher(logline);
+ if(m.matches()) {
+ int flags = Integer.parseInt(m.group(3),16);
+ String msg = m.group(4);
+ int logLevel = flags & 0x0F;
+
+ VpnStatus.LogLevel logStatus = VpnStatus.LogLevel.INFO;
+
+ if ((flags & M_FATAL) != 0)
+ logStatus = VpnStatus.LogLevel.ERROR;
+ else if ((flags & M_NONFATAL)!=0)
+ logStatus = VpnStatus.LogLevel.WARNING;
+ else if ((flags & M_WARN)!=0)
+ logStatus = VpnStatus.LogLevel.WARNING;
+ else if ((flags & M_DEBUG)!=0)
+ logStatus = VpnStatus.LogLevel.VERBOSE;
+
+ if (msg.startsWith("MANAGEMENT: CMD"))
+ logLevel = Math.max(4, logLevel);
+
+
+ VpnStatus.logMessageOpenVPN(logStatus,logLevel,msg);
+ } else {
+ VpnStatus.logInfo("P:" + logline);
+ }
+ }
+
+
+ } catch (IOException e) {
+ VpnStatus.logException("Error reading from output of OpenVPN process" , e);
+ stopProcess();
+ }
+
+
+ }
+
+ private String genLibraryPath(String[] argv, ProcessBuilder pb) {
+ // Hack until I find a good way to get the real library path
+ String applibpath = argv[0].replace("/cache/" + VpnProfile.MINIVPN , "/lib");
+
+ String lbpath = pb.environment().get("LD_LIBRARY_PATH");
+ if(lbpath==null)
+ lbpath = applibpath;
+ else
+ lbpath = lbpath + ":" + applibpath;
+
+ if (!applibpath.equals(mNativeDir)) {
+ lbpath = lbpath + ":" + mNativeDir;
+ }
+ return lbpath;
+ }
+}
diff --git a/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java b/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java new file mode 100644 index 00000000..5fa70cc8 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java @@ -0,0 +1,580 @@ +package de.blinkt.openvpn.core;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.net.LocalServerSocket;
+import android.net.LocalSocket;
+import android.net.LocalSocketAddress;
+import android.os.ParcelFileDescriptor;
+import android.preference.PreferenceManager;
+import android.util.Log;
+
+import org.jetbrains.annotations.NotNull;
+
+import de.blinkt.openvpn.R;
+import de.blinkt.openvpn.VpnProfile;
+import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.Locale;
+import java.util.Vector;
+
+public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
+
+ private static final String TAG = "openvpn";
+ private LocalSocket mSocket;
+ private VpnProfile mProfile;
+ private OpenVpnService mOpenVPNService;
+ private LinkedList<FileDescriptor> mFDList=new LinkedList<FileDescriptor>();
+ private LocalServerSocket mServerSocket;
+ private boolean mReleaseHold=true;
+ private boolean mWaitingForRelease=false;
+ private long mLastHoldRelease=0;
+
+ private static Vector<OpenVpnManagementThread> active=new Vector<OpenVpnManagementThread>();
+ private LocalSocket mServerSocketLocal;
+
+ private pauseReason lastPauseReason = pauseReason.noNetwork;
+
+ public OpenVpnManagementThread(VpnProfile profile, OpenVpnService openVpnService) {
+ mProfile = profile;
+ mOpenVPNService = openVpnService;
+
+
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(openVpnService);
+ boolean managemeNetworkState = prefs.getBoolean("netchangereconnect", true);
+ if(managemeNetworkState)
+ mReleaseHold=false;
+
+ }
+
+ public boolean openManagementInterface(@NotNull Context c) {
+ // Could take a while to open connection
+ int tries=8;
+
+ String socketName = (c.getCacheDir().getAbsolutePath() + "/" + "mgmtsocket");
+ // The mServerSocketLocal is transferred to the LocalServerSocket, ignore warning
+
+ mServerSocketLocal = new LocalSocket();
+
+ while(tries > 0 && !mServerSocketLocal.isConnected()) {
+ try {
+ mServerSocketLocal.bind(new LocalSocketAddress(socketName,
+ LocalSocketAddress.Namespace.FILESYSTEM));
+ } catch (IOException e) {
+ // wait 300 ms before retrying
+ try { Thread.sleep(300);
+ } catch (InterruptedException e1) {
+ }
+
+ }
+ tries--;
+ }
+
+ try {
+
+ mServerSocket = new LocalServerSocket(mServerSocketLocal.getFileDescriptor());
+ return true;
+ } catch (IOException e) {
+ VpnStatus.logException(e);
+ }
+ return false;
+
+
+ }
+
+ public void managmentCommand(String cmd) {
+ try {
+ if(mSocket!=null && mSocket.getOutputStream() !=null) {
+ mSocket.getOutputStream().write(cmd.getBytes());
+ mSocket.getOutputStream().flush();
+ }
+ }catch (IOException e) {
+ // Ignore socket stack traces
+ }
+ }
+
+
+ @Override
+ public void run() {
+ byte [] buffer =new byte[2048];
+ // mSocket.setSoTimeout(5); // Setting a timeout cannot be that bad
+
+ String pendingInput="";
+ active.add(this);
+
+ try {
+ // Wait for a client to connect
+ mSocket= mServerSocket.accept();
+ InputStream instream = mSocket.getInputStream();
+ // Close the management socket after client connected
+
+ mServerSocket.close();
+ // Closing one of the two sockets also closes the other
+ //mServerSocketLocal.close();
+
+ while(true) {
+ int numbytesread = instream.read(buffer);
+ if(numbytesread==-1)
+ return;
+
+ FileDescriptor[] fds = null;
+ try {
+ fds = mSocket.getAncillaryFileDescriptors();
+ } catch (IOException e) {
+ VpnStatus.logException("Error reading fds from socket", e);
+ }
+ if(fds!=null){
+ Collections.addAll(mFDList, fds);
+ }
+
+ String input = new String(buffer,0,numbytesread,"UTF-8");
+
+ pendingInput += input;
+
+ pendingInput=processInput(pendingInput);
+
+
+
+ }
+ } catch (IOException e) {
+ if (!e.getMessage().equals("socket closed"))
+ VpnStatus.logException(e);
+ }
+ active.remove(this);
+ }
+
+ //! Hack O Rama 2000!
+ private void protectFileDescriptor(FileDescriptor fd) {
+ Exception exp;
+ try {
+ Method getInt = FileDescriptor.class.getDeclaredMethod("getInt$");
+ int fdint = (Integer) getInt.invoke(fd);
+
+ // You can even get more evil by parsing toString() and extract the int from that :)
+
+ mOpenVPNService.protect(fdint);
+
+ //ParcelFileDescriptor pfd = ParcelFileDescriptor.fromFd(fdint);
+ //pfd.close();
+ NativeUtils.jniclose(fdint);
+ return;
+ } catch (NoSuchMethodException e) {
+ exp =e;
+ } catch (IllegalArgumentException e) {
+ exp =e;
+ } catch (IllegalAccessException e) {
+ exp =e;
+ } catch (InvocationTargetException e) {
+ exp =e;
+ } catch (NullPointerException e) {
+ exp =e;
+ }
+
+ Log.d("Openvpn", "Failed to retrieve fd from socket: " + fd);
+ VpnStatus.logException("Failed to retrieve fd from socket (" + fd + ")" , exp);
+ }
+
+ private String processInput(String pendingInput) {
+
+
+ while(pendingInput.contains("\n")) {
+ String[] tokens = pendingInput.split("\\r?\\n", 2);
+ processCommand(tokens[0]);
+ if(tokens.length == 1)
+ // No second part, newline was at the end
+ pendingInput="";
+ else
+ pendingInput=tokens[1];
+ }
+ return pendingInput;
+ }
+
+
+ private void processCommand(String command) {
+ //Log.i(TAG, "Line from managment" + command);
+
+
+ if (command.startsWith(">") && command.contains(":")) {
+ String[] parts = command.split(":",2);
+ String cmd = parts[0].substring(1);
+ String argument = parts[1];
+
+
+ if(cmd.equals("INFO")) {
+ /* Ignore greeting from management */
+ return;
+ }else if (cmd.equals("PASSWORD")) {
+ processPWCommand(argument);
+ } else if (cmd.equals("HOLD")) {
+ handleHold();
+ } else if (cmd.equals("NEED-OK")) {
+ processNeedCommand(argument);
+ } else if (cmd.equals("BYTECOUNT")){
+ processByteCount(argument);
+ } else if (cmd.equals("STATE")) {
+ processState(argument);
+ } else if (cmd.equals("PROXY")) {
+ processProxyCMD(argument);
+ } else if (cmd.equals("LOG")) {
+ processLogMessage(argument);
+ } else if (cmd.equals("RSA_SIGN")) {
+ processSignCommand(argument);
+ } else {
+ VpnStatus.logWarning("MGMT: Got unrecognized command" + command);
+ Log.i(TAG, "Got unrecognized command" + command);
+ }
+ } else if (command.startsWith("SUCCESS:")) {
+ /* Ignore this kind of message too */
+ return;
+ } else {
+ Log.i(TAG, "Got unrecognized line from managment" + command);
+ VpnStatus.logWarning("MGMT: Got unrecognized line from management:" + command);
+ }
+ }
+
+ private void processLogMessage(String argument) {
+ String[] args = argument.split(",",4);
+ // 0 unix time stamp
+ // 1 log level N,I,E etc.
+ /*
+ (b) zero or more message flags in a single string:
+ I -- informational
+ F -- fatal error
+ N -- non-fatal error
+ W -- warning
+ D -- debug, and
+ */
+ // 2 log message
+
+ Log.d("OpenVPN", argument);
+
+ VpnStatus.LogLevel level;
+ if (args[1].equals("I")) {
+ level = VpnStatus.LogLevel.INFO;
+ } else if (args[1].equals("W")) {
+ level = VpnStatus.LogLevel.WARNING;
+ } else if (args[1].equals("D")) {
+ level = VpnStatus.LogLevel.VERBOSE;
+ } else if (args[1].equals("F")) {
+ level = VpnStatus.LogLevel.ERROR;
+ } else {
+ level = VpnStatus.LogLevel.INFO;
+ }
+
+ int ovpnlevel = Integer.parseInt(args[2]) & 0x0F;
+ String msg = args[3];
+
+ if (msg.startsWith("MANAGEMENT: CMD"))
+ ovpnlevel = Math.max(4, ovpnlevel);
+
+ VpnStatus.logMessageOpenVPN(level,ovpnlevel, msg);
+ }
+
+ private void handleHold() {
+ if(mReleaseHold) {
+ releaseHoldCmd();
+ } else {
+ mWaitingForRelease=true;
+
+ VpnStatus.updateStatePause(lastPauseReason);
+
+
+ }
+ }
+ private void releaseHoldCmd() {
+ if ((System.currentTimeMillis()- mLastHoldRelease) < 5000) {
+ try {
+ Thread.sleep(3000);
+ } catch (InterruptedException e) {
+ }
+
+ }
+ mWaitingForRelease=false;
+ mLastHoldRelease = System.currentTimeMillis();
+ managmentCommand("hold release\n");
+ managmentCommand("bytecount " + mBytecountInterval + "\n");
+ managmentCommand("state on\n");
+ //managmentCommand("log on all\n");
+ }
+
+ public void releaseHold() {
+ mReleaseHold=true;
+ if(mWaitingForRelease)
+ releaseHoldCmd();
+
+ }
+
+ private void processProxyCMD(String argument) {
+ String[] args = argument.split(",",3);
+ SocketAddress proxyaddr = ProxyDetection.detectProxy(mProfile);
+
+
+ if(args.length >= 2) {
+ String proto = args[1];
+ if(proto.equals("UDP")) {
+ proxyaddr=null;
+ }
+ }
+
+ if(proxyaddr instanceof InetSocketAddress ){
+ InetSocketAddress isa = (InetSocketAddress) proxyaddr;
+
+ VpnStatus.logInfo(R.string.using_proxy, isa.getHostName(), isa.getPort());
+
+ String proxycmd = String.format(Locale.ENGLISH,"proxy HTTP %s %d\n", isa.getHostName(),isa.getPort());
+ managmentCommand(proxycmd);
+ } else {
+ managmentCommand("proxy NONE\n");
+ }
+
+ }
+ private void processState(String argument) {
+ String[] args = argument.split(",",3);
+ String currentstate = args[1];
+
+ if(args[2].equals(",,"))
+ VpnStatus.updateStateString(currentstate, "");
+ else
+ VpnStatus.updateStateString(currentstate, args[2]);
+ }
+
+
+ private void processByteCount(String argument) {
+ // >BYTECOUNT:{BYTES_IN},{BYTES_OUT}
+ int comma = argument.indexOf(',');
+ long in = Long.parseLong(argument.substring(0, comma));
+ long out = Long.parseLong(argument.substring(comma+1));
+
+ VpnStatus.updateByteCount(in, out);
+
+ }
+
+
+
+ private void processNeedCommand(String argument) {
+ int p1 =argument.indexOf('\'');
+ int p2 = argument.indexOf('\'',p1+1);
+
+ String needed = argument.substring(p1+1, p2);
+ String extra = argument.split(":",2)[1];
+
+ String status = "ok";
+
+
+ if (needed.equals("PROTECTFD")) {
+ FileDescriptor fdtoprotect = mFDList.pollFirst();
+ protectFileDescriptor(fdtoprotect);
+ } else if (needed.equals("DNSSERVER")) {
+ mOpenVPNService.addDNS(extra);
+ }else if (needed.equals("DNSDOMAIN")){
+ mOpenVPNService.setDomain(extra);
+ } else if (needed.equals("ROUTE")) {
+ String[] routeparts = extra.split(" ");
+
+ if(routeparts.length>3) {
+ assert(routeparts[3].equals("dev"));
+ mOpenVPNService.addRoute(routeparts[0], routeparts[1], routeparts[2], routeparts[4]);
+ } else {
+ mOpenVPNService.addRoute(routeparts[0], routeparts[1], routeparts[2], null);
+ }
+
+ } else if (needed.equals("ROUTE6")) {
+ String[] routeparts = extra.split(" ");
+ mOpenVPNService.addRoutev6(routeparts[0],routeparts[1]);
+ } else if (needed.equals("IFCONFIG")) {
+ String[] ifconfigparts = extra.split(" ");
+ int mtu = Integer.parseInt(ifconfigparts[2]);
+ mOpenVPNService.setLocalIP(ifconfigparts[0], ifconfigparts[1],mtu,ifconfigparts[3]);
+ } else if (needed.equals("IFCONFIG6")) {
+ mOpenVPNService.setLocalIPv6(extra);
+
+ } else if (needed.equals("PERSIST_TUN_ACTION")) {
+ // check if tun cfg stayed the same
+ status = mOpenVPNService.getTunReopenStatus();
+ } else if (needed.equals("OPENTUN")) {
+ if(sendTunFD(needed,extra))
+ return;
+ else
+ status="cancel";
+ // This not nice or anything but setFileDescriptors accepts only FilDescriptor class :(
+
+ } else {
+ Log.e(TAG,"Unkown needok command " + argument);
+ return;
+ }
+
+ String cmd = String.format("needok '%s' %s\n", needed, status);
+ managmentCommand(cmd);
+ }
+
+ private boolean sendTunFD (String needed, String extra) {
+ Exception exp;
+ if(!extra.equals("tun")) {
+ // We only support tun
+ VpnStatus.logError(String.format("Device type %s requested, but only tun is possible with the Android API, sorry!",extra));
+
+ return false;
+ }
+ ParcelFileDescriptor pfd = mOpenVPNService.openTun();
+ if(pfd==null)
+ return false;
+
+ Method setInt;
+ int fdint = pfd.getFd();
+ try {
+ setInt = FileDescriptor.class.getDeclaredMethod("setInt$",int.class);
+ FileDescriptor fdtosend = new FileDescriptor();
+
+ setInt.invoke(fdtosend,fdint);
+
+ FileDescriptor[] fds = {fdtosend};
+ mSocket.setFileDescriptorsForSend(fds);
+
+ // Trigger a send so we can close the fd on our side of the channel
+ // The API documentation fails to mention that it will not reset the file descriptor to
+ // be send and will happily send the file descriptor on every write ...
+ String cmd = String.format("needok '%s' %s\n", needed, "ok");
+ managmentCommand(cmd);
+
+ // Set the FileDescriptor to null to stop this mad behavior
+ mSocket.setFileDescriptorsForSend(null);
+
+ pfd.close();
+
+ return true;
+ } catch (NoSuchMethodException e) {
+ exp =e;
+ } catch (IllegalArgumentException e) {
+ exp =e;
+ } catch (IllegalAccessException e) {
+ exp =e;
+ } catch (InvocationTargetException e) {
+ exp =e;
+ } catch (IOException e) {
+ exp =e;
+ }
+ VpnStatus.logException("Could not send fd over socket" , exp);
+
+ return false;
+ }
+
+ private void processPWCommand(String argument) {
+ //argument has the form Need 'Private Key' password
+ // or ">PASSWORD:Verification Failed: '%s' ['%s']"
+ String needed;
+
+
+
+ try{
+
+ int p1 = argument.indexOf('\'');
+ int p2 = argument.indexOf('\'',p1+1);
+ needed = argument.substring(p1+1, p2);
+ if (argument.startsWith("Verification Failed")) {
+ proccessPWFailed(needed, argument.substring(p2+1));
+ return;
+ }
+ } catch (StringIndexOutOfBoundsException sioob) {
+ VpnStatus.logError("Could not parse management Password command: " + argument);
+ return;
+ }
+
+ String pw=null;
+
+ if(needed.equals("Private Key")) {
+ pw = mProfile.getPasswordPrivateKey();
+ } else if (needed.equals("Auth")) {
+ String usercmd = String.format("username '%s' %s\n",
+ needed, VpnProfile.openVpnEscape(mProfile.mUsername));
+ managmentCommand(usercmd);
+ pw = mProfile.getPasswordAuth();
+ }
+ if(pw!=null) {
+ String cmd = String.format("password '%s' %s\n", needed, VpnProfile.openVpnEscape(pw));
+ managmentCommand(cmd);
+ } else {
+ VpnStatus.logError(String.format("Openvpn requires Authentication type '%s' but no password/key information available", needed));
+ }
+
+ }
+
+
+
+
+ private void proccessPWFailed(String needed, String args) {
+ VpnStatus.updateStateString("AUTH_FAILED", needed + args, R.string.state_auth_failed, ConnectionStatus.LEVEL_AUTH_FAILED);
+ }
+
+
+ private static boolean stopOpenVPN() {
+ boolean sendCMD=false;
+ for (OpenVpnManagementThread mt: active){
+ mt.managmentCommand("signal SIGINT\n");
+ sendCMD=true;
+ try {
+ if(mt.mSocket !=null)
+ mt.mSocket.close();
+ } catch (IOException e) {
+ // Ignore close error on already closed socket
+ }
+ }
+ return sendCMD;
+ }
+
+ public void signalusr1() {
+ mReleaseHold=false;
+
+ if(!mWaitingForRelease)
+ managmentCommand("signal SIGUSR1\n");
+ else
+ // If signalusr1 is called update the state string
+ // if there is another for stopping
+ VpnStatus.updateStatePause(lastPauseReason);
+ }
+
+ public void reconnect() {
+ signalusr1();
+ releaseHold();
+ }
+
+ private void processSignCommand(String b64data) {
+
+ String signed_string = mProfile.getSignedData(b64data);
+ if(signed_string==null) {
+ managmentCommand("rsa-sig\n");
+ managmentCommand("\nEND\n");
+ stopOpenVPN();
+ return;
+ }
+ managmentCommand("rsa-sig\n");
+ managmentCommand(signed_string);
+ managmentCommand("\nEND\n");
+ }
+
+ @Override
+ public void pause (pauseReason reason) {
+ lastPauseReason = reason;
+ signalusr1();
+ }
+
+ @Override
+ public void resume() {
+ releaseHold();
+ /* Reset the reason why we are disconnected */
+ lastPauseReason = pauseReason.noNetwork;
+ }
+
+ @Override
+ public boolean stopVPN() {
+ return stopOpenVPN();
+ }
+}
diff --git a/main/src/main/java/de/blinkt/openvpn/core/OpenVpnService.java b/main/src/main/java/de/blinkt/openvpn/core/OpenVpnService.java new file mode 100644 index 00000000..49f315a3 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/core/OpenVpnService.java @@ -0,0 +1,704 @@ +package de.blinkt.openvpn.core; + +import android.Manifest.permission; +import android.annotation.TargetApi; +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.SharedPreferences; +import android.net.ConnectivityManager; +import android.net.VpnService; +import android.os.*; +import android.os.Handler.Callback; +import android.preference.PreferenceManager; +import android.text.TextUtils; +import de.blinkt.openvpn.activities.DisconnectVPN; +import de.blinkt.openvpn.activities.LogWindow; +import de.blinkt.openvpn.R; +import de.blinkt.openvpn.VpnProfile; +import de.blinkt.openvpn.core.VpnStatus.ByteCountListener; +import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus; +import de.blinkt.openvpn.core.VpnStatus.StateListener; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.HashMap; +import java.util.Locale; +import java.util.Vector; + +import static de.blinkt.openvpn.core.NetworkSpace.*; +import static de.blinkt.openvpn.core.VpnStatus.ConnectionStatus.*; + +public class OpenVpnService extends VpnService implements StateListener, Callback, ByteCountListener { + public static final String START_SERVICE = "de.blinkt.openvpn.START_SERVICE"; + public static final String START_SERVICE_STICKY = "de.blinkt.openvpn.START_SERVICE_STICKY"; + public static final String ALWAYS_SHOW_NOTIFICATION = "de.blinkt.openvpn.NOTIFICATION_ALWAYS_VISIBLE"; + public static final String DISCONNECT_VPN = "de.blinkt.openvpn.DISCONNECT_VPN"; + private static final String PAUSE_VPN = "de.blinkt.openvpn.PAUSE_VPN"; + private static final String RESUME_VPN = "de.blinkt.openvpn.RESUME_VPN"; + private static final int OPENVPN_STATUS = 1; + private static boolean mNotificationAlwaysVisible = false; + private final Vector<String> mDnslist = new Vector<String>(); + private final NetworkSpace mRoutes = new NetworkSpace(); + private final NetworkSpace mRoutesv6 = new NetworkSpace(); + private final IBinder mBinder = new LocalBinder(); + private Thread mProcessThread = null; + private VpnProfile mProfile; + private String mDomain = null; + private CIDRIP mLocalIP = null; + private int mMtu; + private String mLocalIPv6 = null; + private DeviceStateReceiver mDeviceStateReceiver; + private boolean mDisplayBytecount = false; + private boolean mStarting = false; + private long mConnecttime; + private boolean mOvpn3 = false; + private OpenVPNManagement mManagement; + private String mLastTunCfg; + private String mRemoteGW; + + // From: http://stackoverflow.com/questions/3758606/how-to-convert-byte-size-into-human-readable-format-in-java + public static String humanReadableByteCount(long bytes, boolean mbit) { + if (mbit) + bytes = bytes * 8; + int unit = mbit ? 1000 : 1024; + if (bytes < unit) + return bytes + (mbit ? " bit" : " B"); + + int exp = (int) (Math.log(bytes) / Math.log(unit)); + String pre = (mbit ? "kMGTPE" : "KMGTPE").charAt(exp - 1) + (mbit ? "" : ""); + if (mbit) + return String.format(Locale.getDefault(), "%.1f %sbit", bytes / Math.pow(unit, exp), pre); + else + return String.format(Locale.getDefault(), "%.1f %sB", bytes / Math.pow(unit, exp), pre); + } + + @Override + public IBinder onBind(Intent intent) { + String action = intent.getAction(); + if (action != null && action.equals(START_SERVICE)) + return mBinder; + else + return super.onBind(intent); + } + + @Override + public void onRevoke() { + mManagement.stopVPN(); + endVpnService(); + } + + // Similar to revoke but do not try to stop process + public void processDied() { + endVpnService(); + } + + private void endVpnService() { + mProcessThread = null; + VpnStatus.removeByteCountListener(this); + unregisterDeviceStateReceiver(); + ProfileManager.setConntectedVpnProfileDisconnected(this); + if (!mStarting) { + stopForeground(!mNotificationAlwaysVisible); + + if (!mNotificationAlwaysVisible) { + stopSelf(); + VpnStatus.removeStateListener(this); + } + } + } + + private void showNotification(String msg, String tickerText, boolean lowpriority, long when, ConnectionStatus status) { + String ns = Context.NOTIFICATION_SERVICE; + NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns); + + + int icon = getIconByConnectionStatus(status); + + android.app.Notification.Builder nbuilder = new Notification.Builder(this); + + if (mProfile != null) + nbuilder.setContentTitle(getString(R.string.notifcation_title, mProfile.mName)); + else + nbuilder.setContentTitle(getString(R.string.notifcation_title_notconnect)); + + nbuilder.setContentText(msg); + nbuilder.setOnlyAlertOnce(true); + nbuilder.setOngoing(true); + nbuilder.setContentIntent(getLogPendingIntent()); + nbuilder.setSmallIcon(icon); + + + if (when != 0) + nbuilder.setWhen(when); + + + // Try to set the priority available since API 16 (Jellybean) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) + jbNotificationExtras(lowpriority, nbuilder); + + if (tickerText != null && !tickerText.equals("")) + nbuilder.setTicker(tickerText); + + @SuppressWarnings("deprecation") + Notification notification = nbuilder.getNotification(); + + + mNotificationManager.notify(OPENVPN_STATUS, notification); + startForeground(OPENVPN_STATUS, notification); + } + + private int getIconByConnectionStatus(ConnectionStatus level) { + switch (level) { + case LEVEL_CONNECTED: + return R.drawable.ic_stat_vpn; + case LEVEL_AUTH_FAILED: + case LEVEL_NONETWORK: + case LEVEL_NOTCONNECTED: + return R.drawable.ic_stat_vpn_offline; + case LEVEL_CONNECTING_NO_SERVER_REPLY_YET: + case LEVEL_WAITING_FOR_USER_INPUT: + return R.drawable.ic_stat_vpn_outline; + case LEVEL_CONNECTING_SERVER_REPLIED: + return R.drawable.ic_stat_vpn_empty_halo; + case LEVEL_VPNPAUSED: + return android.R.drawable.ic_media_pause; + case UNKNOWN_LEVEL: + default: + return R.drawable.ic_stat_vpn; + + } + } + + @TargetApi(Build.VERSION_CODES.JELLY_BEAN) + private void jbNotificationExtras(boolean lowpriority, + android.app.Notification.Builder nbuilder) { + try { + if (lowpriority) { + Method setpriority = nbuilder.getClass().getMethod("setPriority", int.class); + // PRIORITY_MIN == -2 + setpriority.invoke(nbuilder, -2); + + Method setUsesChronometer = nbuilder.getClass().getMethod("setUsesChronometer", boolean.class); + setUsesChronometer.invoke(nbuilder, true); + + } + + Intent disconnectVPN = new Intent(this, DisconnectVPN.class); + disconnectVPN.setAction(DISCONNECT_VPN); + PendingIntent disconnectPendingIntent = PendingIntent.getActivity(this, 0, disconnectVPN, 0); + + nbuilder.addAction(android.R.drawable.ic_menu_close_clear_cancel, + getString(R.string.cancel_connection), disconnectPendingIntent); + + Intent pauseVPN = new Intent(this, OpenVpnService.class); + if (mDeviceStateReceiver == null || !mDeviceStateReceiver.isUserPaused()) { + pauseVPN.setAction(PAUSE_VPN); + PendingIntent pauseVPNPending = PendingIntent.getService(this, 0, pauseVPN, 0); + nbuilder.addAction(android.R.drawable.ic_media_pause, + getString(R.string.pauseVPN), pauseVPNPending); + + } else { + pauseVPN.setAction(RESUME_VPN); + PendingIntent resumeVPNPending = PendingIntent.getService(this, 0, pauseVPN, 0); + nbuilder.addAction(android.R.drawable.ic_media_play, + getString(R.string.resumevpn), resumeVPNPending); + } + + + //ignore exception + } catch (NoSuchMethodException nsm) { + VpnStatus.logException(nsm); + } catch (IllegalArgumentException e) { + VpnStatus.logException(e); + } catch (IllegalAccessException e) { + VpnStatus.logException(e); + } catch (InvocationTargetException e) { + VpnStatus.logException(e); + } + + } + + PendingIntent getLogPendingIntent() { + // Let the configure Button show the Log + Intent intent = new Intent(getBaseContext(), LogWindow.class); + intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); + PendingIntent startLW = PendingIntent.getActivity(this, 0, intent, 0); + intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); + return startLW; + + } + + synchronized void registerDeviceStateReceiver(OpenVPNManagement magnagement) { + // Registers BroadcastReceiver to track network connection changes. + IntentFilter filter = new IntentFilter(); + filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); + filter.addAction(Intent.ACTION_SCREEN_OFF); + filter.addAction(Intent.ACTION_SCREEN_ON); + mDeviceStateReceiver = new DeviceStateReceiver(magnagement); + registerReceiver(mDeviceStateReceiver, filter); + VpnStatus.addByteCountListener(mDeviceStateReceiver); + } + + synchronized void unregisterDeviceStateReceiver() { + if (mDeviceStateReceiver != null) + try { + VpnStatus.removeByteCountListener(mDeviceStateReceiver); + this.unregisterReceiver(mDeviceStateReceiver); + } catch (IllegalArgumentException iae) { + // I don't know why this happens: + // java.lang.IllegalArgumentException: Receiver not registered: de.blinkt.openvpn.NetworkSateReceiver@41a61a10 + // Ignore for now ... + iae.printStackTrace(); + } + mDeviceStateReceiver = null; + } + + public void userPause(boolean shouldBePaused) { + if (mDeviceStateReceiver != null) + mDeviceStateReceiver.userPause(shouldBePaused); + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + + if (intent != null && intent.getBooleanExtra(ALWAYS_SHOW_NOTIFICATION, false)) + mNotificationAlwaysVisible = true; + + VpnStatus.addStateListener(this); + VpnStatus.addByteCountListener(this); + + if (intent != null && PAUSE_VPN.equals(intent.getAction())) { + if (mDeviceStateReceiver != null) + mDeviceStateReceiver.userPause(true); + return START_NOT_STICKY; + } + + if (intent != null && RESUME_VPN.equals(intent.getAction())) { + if (mDeviceStateReceiver != null) + mDeviceStateReceiver.userPause(false); + return START_NOT_STICKY; + } + + + if (intent != null && START_SERVICE.equals(intent.getAction())) + return START_NOT_STICKY; + if (intent != null && START_SERVICE_STICKY.equals(intent.getAction())) { + return START_REDELIVER_INTENT; + } + + assert (intent != null); + + // Extract information from the intent. + String prefix = getPackageName(); + String[] argv = intent.getStringArrayExtra(prefix + ".ARGV"); + String nativelibdir = intent.getStringExtra(prefix + ".nativelib"); + String profileUUID = intent.getStringExtra(prefix + ".profileUUID"); + + mProfile = ProfileManager.get(this, profileUUID); + + String startTitle = getString(R.string.start_vpn_title, mProfile.mName); + String startTicker = getString(R.string.start_vpn_ticker, mProfile.mName); + showNotification(startTitle, startTicker, + false, 0, LEVEL_CONNECTING_NO_SERVER_REPLY_YET); + + // Set a flag that we are starting a new VPN + mStarting = true; + // Stop the previous session by interrupting the thread. + if (mManagement != null && mManagement.stopVPN()) + // an old was asked to exit, wait 1s + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + } + + + if (mProcessThread != null) { + mProcessThread.interrupt(); + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + } + } + // An old running VPN should now be exited + mStarting = false; + + // Start a new session by creating a new thread. + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); + + mOvpn3 = prefs.getBoolean("ovpn3", false); + mOvpn3 = false; + + + // Open the Management Interface + if (!mOvpn3) { + + // start a Thread that handles incoming messages of the managment socket + OpenVpnManagementThread ovpnManagementThread = new OpenVpnManagementThread(mProfile, this); + if (ovpnManagementThread.openManagementInterface(this)) { + + Thread mSocketManagerThread = new Thread(ovpnManagementThread, "OpenVPNManagementThread"); + mSocketManagerThread.start(); + mManagement = ovpnManagementThread; + VpnStatus.logInfo("started Socket Thread"); + } else { + return START_NOT_STICKY; + } + } + + + Runnable processThread; + if (mOvpn3) { + + OpenVPNManagement mOpenVPN3 = instantiateOpenVPN3Core(); + processThread = (Runnable) mOpenVPN3; + mManagement = mOpenVPN3; + + + } else { + HashMap<String, String> env = new HashMap<String, String>(); + processThread = new OpenVPNThread(this, argv, env, nativelibdir); + } + + mProcessThread = new Thread(processThread, "OpenVPNProcessThread"); + mProcessThread.start(); + + if (mDeviceStateReceiver != null) + unregisterDeviceStateReceiver(); + + registerDeviceStateReceiver(mManagement); + + + ProfileManager.setConnectedVpnProfile(this, mProfile); + + return START_NOT_STICKY; + } + + private OpenVPNManagement instantiateOpenVPN3Core() { + return null; + } + + @Override + public void onDestroy() { + if (mProcessThread != null) { + mManagement.stopVPN(); + + mProcessThread.interrupt(); + } + if (mDeviceStateReceiver != null) { + this.unregisterReceiver(mDeviceStateReceiver); + } + // Just in case unregister for state + VpnStatus.removeStateListener(this); + + } + + private String getTunConfigString() { + // The format of the string is not important, only that + // two identical configurations produce the same result + String cfg = "TUNCFG UNQIUE STRING ips:"; + + if (mLocalIP != null) + cfg += mLocalIP.toString(); + if (mLocalIPv6 != null) + cfg += mLocalIPv6.toString(); + + cfg += "routes: " + TextUtils.join("|", mRoutes.getNetworks(true)) + TextUtils.join("|", mRoutesv6.getNetworks(true)); + cfg += "excl. routes:" + TextUtils.join("|", mRoutes.getNetworks(false)) + TextUtils.join("|", mRoutesv6.getNetworks(false)); + cfg += "dns: " + TextUtils.join("|", mDnslist); + cfg += "domain: " + mDomain; + cfg += "mtu: " + mMtu; + return cfg; + } + + public ParcelFileDescriptor openTun() { + Builder builder = new Builder(); + + if (mLocalIP == null && mLocalIPv6 == null) { + VpnStatus.logError(getString(R.string.opentun_no_ipaddr)); + return null; + } + + if (mLocalIP != null) { + try { + builder.addAddress(mLocalIP.mIp, mLocalIP.len); + } catch (IllegalArgumentException iae) { + VpnStatus.logError(R.string.dns_add_error, mLocalIP, iae.getLocalizedMessage()); + return null; + } + } + + if (mLocalIPv6 != null) { + String[] ipv6parts = mLocalIPv6.split("/"); + try { + builder.addAddress(ipv6parts[0], Integer.parseInt(ipv6parts[1])); + } catch (IllegalArgumentException iae) { + VpnStatus.logError(R.string.ip_add_error, mLocalIPv6, iae.getLocalizedMessage()); + return null; + } + + } + + + for (String dns : mDnslist) { + try { + builder.addDnsServer(dns); + } catch (IllegalArgumentException iae) { + VpnStatus.logError(R.string.dns_add_error, dns, iae.getLocalizedMessage()); + } + } + + + builder.setMtu(mMtu); + + + for (NetworkSpace.ipAddress route : mRoutes.getPositiveIPList()) { + try { + builder.addRoute(route.getIPv4Address(), route.networkMask); + } catch (IllegalArgumentException ia) { + VpnStatus.logError(getString(R.string.route_rejected) + route + " " + ia.getLocalizedMessage()); + } + } + + for (NetworkSpace.ipAddress route6 : mRoutesv6.getPositiveIPList()) { + try { + builder.addRoute(route6.getIPv6Address(), route6.networkMask); + } catch (IllegalArgumentException ia) { + VpnStatus.logError(getString(R.string.route_rejected) + route6 + " " + ia.getLocalizedMessage()); + } + } + + if (mDomain != null) + builder.addSearchDomain(mDomain); + + VpnStatus.logInfo(R.string.last_openvpn_tun_config); + VpnStatus.logInfo(R.string.local_ip_info, mLocalIP.mIp, mLocalIP.len, mLocalIPv6, mMtu); + VpnStatus.logInfo(R.string.dns_server_info, TextUtils.join(", ", mDnslist), mDomain); + VpnStatus.logInfo(R.string.routes_info_incl, TextUtils.join(", ", mRoutes.getNetworks(true)), TextUtils.join(", ", mRoutesv6.getNetworks(true))); + VpnStatus.logInfo(R.string.routes_info_excl, TextUtils.join(", ", mRoutes.getNetworks(false)),TextUtils.join(", ", mRoutesv6.getNetworks(false))); + VpnStatus.logDebug(R.string.routes_debug, TextUtils.join(", ", mRoutes.getPositiveIPList()), TextUtils.join(", ", mRoutesv6.getPositiveIPList())); + + String session = mProfile.mName; + if (mLocalIP != null && mLocalIPv6 != null) + session = getString(R.string.session_ipv6string, session, mLocalIP, mLocalIPv6); + else if (mLocalIP != null) + session = getString(R.string.session_ipv4string, session, mLocalIP); + + builder.setSession(session); + + // No DNS Server, log a warning + if (mDnslist.size() == 0) + VpnStatus.logInfo(R.string.warn_no_dns); + + mLastTunCfg = getTunConfigString(); + + // Reset information + mDnslist.clear(); + mRoutes.clear(); + mRoutesv6.clear(); + mLocalIP = null; + mLocalIPv6 = null; + mDomain = null; + + builder.setConfigureIntent(getLogPendingIntent()); + + try { + return builder.establish(); + } catch (Exception e) { + VpnStatus.logError(R.string.tun_open_error); + VpnStatus.logError(getString(R.string.error) + e.getLocalizedMessage()); + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN_MR1) { + VpnStatus.logError(R.string.tun_error_helpful); + } + return null; + } + + } + + public void addDNS(String dns) { + mDnslist.add(dns); + } + + public void setDomain(String domain) { + if (mDomain == null) { + mDomain = domain; + } + } + + public void addRoute (String dest, String mask, String gateway, String device) { + CIDRIP route = new CIDRIP(dest, mask); + boolean include = isAndroidTunDevice(device); + + NetworkSpace.ipAddress gatewayIP = new NetworkSpace.ipAddress(new CIDRIP(gateway, 32),false); + + NetworkSpace.ipAddress localNet = new NetworkSpace.ipAddress(mLocalIP,true); + if (localNet.containsNet(gatewayIP)) + include=true; + + if (gateway!= null && + (gateway.equals("255.255.255.255") || gateway.equals(mRemoteGW))) + include=true; + + + if (route.len == 32 && !mask.equals("255.255.255.255")) { + VpnStatus.logWarning(R.string.route_not_cidr, dest, mask); + } + + if (route.normalise()) + VpnStatus.logWarning(R.string.route_not_netip, dest, route.len, route.mIp); + + mRoutes.addIP(route, include); + } + + public void addRoutev6(String network, String device) { + String[] v6parts = network.split("/"); + boolean included = isAndroidTunDevice(device); + + // Tun is opened after ROUTE6, no device name may be present + + try { + Inet6Address ip = (Inet6Address) InetAddress.getAllByName(v6parts[0])[0]; + int mask = Integer.parseInt(v6parts[1]); + mRoutesv6.addIPv6(ip, mask, included); + + } catch (UnknownHostException e) { + VpnStatus.logException(e); + } + + + } + + private boolean isAndroidTunDevice(String device) { + return device!=null && + (device.startsWith("tun") || "(null)".equals(device) || "vpnservice-tun".equals(device)); + } + + public void setMtu(int mtu) { + mMtu = mtu; + } + + public void setLocalIP(CIDRIP cdrip) { + mLocalIP = cdrip; + } + + public void setLocalIP(String local, String netmask, int mtu, String mode) { + mLocalIP = new CIDRIP(local, netmask); + mMtu = mtu; + + if (mLocalIP.len == 32 && !netmask.equals("255.255.255.255")) { + // get the netmask as IP + long netint = CIDRIP.getInt(netmask); + if (Math.abs(netint - mLocalIP.getInt()) == 1) { + if ("net30".equals(mode)) + mLocalIP.len = 30; + else + mLocalIP.len = 31; + } else { + VpnStatus.logWarning(R.string.ip_not_cidr, local, netmask, mode); + } + } + + if ("p2p".equals(mode)) + mRemoteGW=netmask; + else + mRemoteGW=null; + + } + + public void setLocalIPv6(String ipv6addr) { + mLocalIPv6 = ipv6addr; + } + + @Override + public void updateState(String state, String logmessage, int resid, ConnectionStatus level) { + // If the process is not running, ignore any state, + // Notification should be invisible in this state + doSendBroadcast(state, level); + if (mProcessThread == null && !mNotificationAlwaysVisible) + return; + + // Display byte count only after being connected + + { + if (level == LEVEL_WAITING_FOR_USER_INPUT) { + // The user is presented a dialog of some kind, no need to inform the user + // with a notifcation + return; + } else if (level == LEVEL_CONNECTED) { + mDisplayBytecount = true; + mConnecttime = System.currentTimeMillis(); + } else { + mDisplayBytecount = false; + } + + // Other notifications are shown, + // This also mean we are no longer connected, ignore bytecount messages until next + // CONNECTED + String ticker = getString(resid); + showNotification(getString(resid) + " " + logmessage, ticker, false, 0, level); + + } + } + + private void doSendBroadcast(String state, ConnectionStatus level) { + Intent vpnstatus = new Intent(); + vpnstatus.setAction("de.blinkt.openvpn.VPN_STATUS"); + vpnstatus.putExtra("status", level.toString()); + vpnstatus.putExtra("detailstatus", state); + sendBroadcast(vpnstatus, permission.ACCESS_NETWORK_STATE); + } + + @Override + public void updateByteCount(long in, long out, long diffIn, long diffOut) { + if (mDisplayBytecount) { + String netstat = String.format(getString(R.string.statusline_bytecount), + humanReadableByteCount(in, false), + humanReadableByteCount(diffIn / OpenVPNManagement.mBytecountInterval, true), + humanReadableByteCount(out, false), + humanReadableByteCount(diffOut / OpenVPNManagement.mBytecountInterval, true)); + + boolean lowpriority = !mNotificationAlwaysVisible; + showNotification(netstat, null, lowpriority, mConnecttime, LEVEL_CONNECTED); + } + + } + + @Override + public boolean handleMessage(Message msg) { + Runnable r = msg.getCallback(); + if (r != null) { + r.run(); + return true; + } else { + return false; + } + } + + public OpenVPNManagement getManagement() { + return mManagement; + } + + public String getTunReopenStatus() { + String currentConfiguration = getTunConfigString(); + if (currentConfiguration.equals(mLastTunCfg)) + return "NOACTION"; + else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) + return "OPEN_AFTER_CLOSE"; + else + return "OPEN_BEFORE_CLOSE"; + } + + public class LocalBinder extends Binder { + public OpenVpnService getService() { + // Return this instance of LocalService so clients can call public methods + return OpenVpnService.this; + } + } +} diff --git a/main/src/main/java/de/blinkt/openvpn/core/PRNGFixes.java b/main/src/main/java/de/blinkt/openvpn/core/PRNGFixes.java new file mode 100644 index 00000000..dd420371 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/core/PRNGFixes.java @@ -0,0 +1,334 @@ +package de.blinkt.openvpn.core;/* + * This software is provided 'as-is', without any express or implied + * warranty. In no event will Google be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, as long as the origin is not misrepresented. + */ + +import android.os.Build; +import android.os.Process; +import android.util.Log; + +import java.io.ByteArrayOutputStream; +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; +import java.security.NoSuchAlgorithmException; +import java.security.Provider; +import java.security.SecureRandom; +import java.security.SecureRandomSpi; +import java.security.Security; + +/** + * Fixes for the output of the default PRNG having low entropy. + * + * The fixes need to be applied via {@link #apply()} before any use of Java + * Cryptography Architecture primitives. A good place to invoke them is in the + * application's {@code onCreate}. + */ +public final class PRNGFixes { + + private static final int VERSION_CODE_JELLY_BEAN = 16; + private static final int VERSION_CODE_JELLY_BEAN_MR2 = 18; + private static final byte[] BUILD_FINGERPRINT_AND_DEVICE_SERIAL = + getBuildFingerprintAndDeviceSerial(); + + /** Hidden constructor to prevent instantiation. */ + private PRNGFixes() {} + + /** + * Applies all fixes. + * + * @throws SecurityException if a fix is needed but could not be applied. + */ + public static void apply() { + applyOpenSSLFix(); + installLinuxPRNGSecureRandom(); + } + + /** + * Applies the fix for OpenSSL PRNG having low entropy. Does nothing if the + * fix is not needed. + * + * @throws SecurityException if the fix is needed but could not be applied. + */ + private static void applyOpenSSLFix() throws SecurityException { + if ((Build.VERSION.SDK_INT < VERSION_CODE_JELLY_BEAN) + || (Build.VERSION.SDK_INT > VERSION_CODE_JELLY_BEAN_MR2)) { + // No need to apply the fix + return; + } + + try { + // Mix in the device- and invocation-specific seed. + Class.forName("org.apache.harmony.xnet.provider.jsse.NativeCrypto") + .getMethod("RAND_seed", byte[].class) + .invoke(null, generateSeed()); + + // Mix output of Linux PRNG into OpenSSL's PRNG + int bytesRead = (Integer) Class.forName( + "org.apache.harmony.xnet.provider.jsse.NativeCrypto") + .getMethod("RAND_load_file", String.class, long.class) + .invoke(null, "/dev/urandom", 1024); + if (bytesRead != 1024) { + throw new IOException( + "Unexpected number of bytes read from Linux PRNG: " + + bytesRead); + } + } catch (Exception e) { + throw new SecurityException("Failed to seed OpenSSL PRNG", e); + } + } + + /** + * Installs a Linux PRNG-backed {@code SecureRandom} implementation as the + * default. Does nothing if the implementation is already the default or if + * there is not need to install the implementation. + * + * @throws SecurityException if the fix is needed but could not be applied. + */ + private static void installLinuxPRNGSecureRandom() + throws SecurityException { + if (Build.VERSION.SDK_INT > VERSION_CODE_JELLY_BEAN_MR2) { + // No need to apply the fix + return; + } + + // Install a Linux PRNG-based SecureRandom implementation as the + // default, if not yet installed. + Provider[] secureRandomProviders = + Security.getProviders("SecureRandom.SHA1PRNG"); + if ((secureRandomProviders == null) + || (secureRandomProviders.length < 1) + || (!LinuxPRNGSecureRandomProvider.class.equals( + secureRandomProviders[0].getClass()))) { + Security.insertProviderAt(new LinuxPRNGSecureRandomProvider(), 1); + } + + // Assert that new SecureRandom() and + // SecureRandom.getInstance("SHA1PRNG") return a SecureRandom backed + // by the Linux PRNG-based SecureRandom implementation. + SecureRandom rng1 = new SecureRandom(); + if (!LinuxPRNGSecureRandomProvider.class.equals( + rng1.getProvider().getClass())) { + throw new SecurityException( + "new SecureRandom() backed by wrong Provider: " + + rng1.getProvider().getClass()); + } + + SecureRandom rng2; + try { + rng2 = SecureRandom.getInstance("SHA1PRNG"); + } catch (NoSuchAlgorithmException e) { + throw new SecurityException("SHA1PRNG not available", e); + } + if (!LinuxPRNGSecureRandomProvider.class.equals( + rng2.getProvider().getClass())) { + throw new SecurityException( + "SecureRandom.getInstance(\"SHA1PRNG\") backed by wrong" + + " Provider: " + rng2.getProvider().getClass()); + } + } + + /** + * {@code Provider} of {@code SecureRandom} engines which pass through + * all requests to the Linux PRNG. + */ + private static class LinuxPRNGSecureRandomProvider extends Provider { + + public LinuxPRNGSecureRandomProvider() { + super("LinuxPRNG", + 1.0, + "A Linux-specific random number provider that uses" + + " /dev/urandom"); + // Although /dev/urandom is not a SHA-1 PRNG, some apps + // explicitly request a SHA1PRNG SecureRandom and we thus need to + // prevent them from getting the default implementation whose output + // may have low entropy. + put("SecureRandom.SHA1PRNG", LinuxPRNGSecureRandom.class.getName()); + put("SecureRandom.SHA1PRNG ImplementedIn", "Software"); + } + } + + /** + * {@link SecureRandomSpi} which passes all requests to the Linux PRNG + * ({@code /dev/urandom}). + */ + public static class LinuxPRNGSecureRandom extends SecureRandomSpi { + + /* + * IMPLEMENTATION NOTE: Requests to generate bytes and to mix in a seed + * are passed through to the Linux PRNG (/dev/urandom). Instances of + * this class seed themselves by mixing in the current time, PID, UID, + * build fingerprint, and hardware serial number (where available) into + * Linux PRNG. + * + * Concurrency: Read requests to the underlying Linux PRNG are + * serialized (on sLock) to ensure that multiple threads do not get + * duplicated PRNG output. + */ + + private static final File URANDOM_FILE = new File("/dev/urandom"); + + private static final Object sLock = new Object(); + + /** + * Input stream for reading from Linux PRNG or {@code null} if not yet + * opened. + * + * @GuardedBy("sLock") + */ + private static DataInputStream sUrandomIn; + + /** + * Output stream for writing to Linux PRNG or {@code null} if not yet + * opened. + * + * @GuardedBy("sLock") + */ + private static OutputStream sUrandomOut; + + /** + * Whether this engine instance has been seeded. This is needed because + * each instance needs to seed itself if the client does not explicitly + * seed it. + */ + private boolean mSeeded; + + @Override + protected void engineSetSeed(byte[] bytes) { + try { + OutputStream out; + synchronized (sLock) { + out = getUrandomOutputStream(); + } + out.write(bytes); + out.flush(); + } catch (IOException e) { + // On a small fraction of devices /dev/urandom is not writable. + // Log and ignore. + Log.w(PRNGFixes.class.getSimpleName(), + "Failed to mix seed into " + URANDOM_FILE); + } finally { + mSeeded = true; + } + } + + @Override + protected void engineNextBytes(byte[] bytes) { + if (!mSeeded) { + // Mix in the device- and invocation-specific seed. + engineSetSeed(generateSeed()); + } + + try { + DataInputStream in; + synchronized (sLock) { + in = getUrandomInputStream(); + } + synchronized (in) { + in.readFully(bytes); + } + } catch (IOException e) { + throw new SecurityException( + "Failed to read from " + URANDOM_FILE, e); + } + } + + @Override + protected byte[] engineGenerateSeed(int size) { + byte[] seed = new byte[size]; + engineNextBytes(seed); + return seed; + } + + private DataInputStream getUrandomInputStream() { + synchronized (sLock) { + if (sUrandomIn == null) { + // NOTE: Consider inserting a BufferedInputStream between + // DataInputStream and FileInputStream if you need higher + // PRNG output performance and can live with future PRNG + // output being pulled into this process prematurely. + try { + sUrandomIn = new DataInputStream( + new FileInputStream(URANDOM_FILE)); + } catch (IOException e) { + throw new SecurityException("Failed to open " + + URANDOM_FILE + " for reading", e); + } + } + return sUrandomIn; + } + } + + private OutputStream getUrandomOutputStream() throws IOException { + synchronized (sLock) { + if (sUrandomOut == null) { + sUrandomOut = new FileOutputStream(URANDOM_FILE); + } + return sUrandomOut; + } + } + } + + /** + * Generates a device- and invocation-specific seed to be mixed into the + * Linux PRNG. + */ + private static byte[] generateSeed() { + try { + ByteArrayOutputStream seedBuffer = new ByteArrayOutputStream(); + DataOutputStream seedBufferOut = + new DataOutputStream(seedBuffer); + seedBufferOut.writeLong(System.currentTimeMillis()); + seedBufferOut.writeLong(System.nanoTime()); + seedBufferOut.writeInt(Process.myPid()); + seedBufferOut.writeInt(Process.myUid()); + seedBufferOut.write(BUILD_FINGERPRINT_AND_DEVICE_SERIAL); + seedBufferOut.close(); + return seedBuffer.toByteArray(); + } catch (IOException e) { + throw new SecurityException("Failed to generate seed", e); + } + } + + /** + * Gets the hardware serial number of this device. + * + * @return serial number or {@code null} if not available. + */ + private static String getDeviceSerialNumber() { + // We're using the Reflection API because Build.SERIAL is only available + // since API Level 9 (Gingerbread, Android 2.3). + try { + return (String) Build.class.getField("SERIAL").get(null); + } catch (Exception ignored) { + return null; + } + } + + private static byte[] getBuildFingerprintAndDeviceSerial() { + StringBuilder result = new StringBuilder(); + String fingerprint = Build.FINGERPRINT; + if (fingerprint != null) { + result.append(fingerprint); + } + String serial = getDeviceSerialNumber(); + if (serial != null) { + result.append(serial); + } + try { + return result.toString().getBytes("UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException("UTF-8 encoding not supported"); + } + } +}
\ No newline at end of file diff --git a/main/src/main/java/de/blinkt/openvpn/core/ProfileManager.java b/main/src/main/java/de/blinkt/openvpn/core/ProfileManager.java new file mode 100644 index 00000000..4cfbcc8e --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/core/ProfileManager.java @@ -0,0 +1,222 @@ +package de.blinkt.openvpn.core; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.StreamCorruptedException; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; + +import de.blinkt.openvpn.VpnProfile; + +import android.app.Activity; +import android.content.Context; +import android.content.SharedPreferences; +import android.content.SharedPreferences.Editor; +import android.preference.PreferenceManager; + +public class ProfileManager { + private static final String PREFS_NAME = "VPNList"; + + + + private static final String ONBOOTPROFILE = "onBootProfile"; + + + + private static ProfileManager instance; + + + + private static VpnProfile mLastConnectedVpn=null; + private HashMap<String,VpnProfile> profiles=new HashMap<String, VpnProfile>(); + private static VpnProfile tmpprofile=null; + + + private static VpnProfile get(String key) { + if (tmpprofile!=null && tmpprofile.getUUIDString().equals(key)) + return tmpprofile; + + if(instance==null) + return null; + return instance.profiles.get(key); + + } + + + + private ProfileManager() { } + + private static void checkInstance(Context context) { + if(instance == null) { + instance = new ProfileManager(); + instance.loadVPNList(context); + } + } + + synchronized public static ProfileManager getInstance(Context context) { + checkInstance(context); + return instance; + } + + public static void setConntectedVpnProfileDisconnected(Context c) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c); + Editor prefsedit = prefs.edit(); + prefsedit.putString(ONBOOTPROFILE, null); + prefsedit.apply(); + + } + + public static void setConnectedVpnProfile(Context c, VpnProfile connectedrofile) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c); + Editor prefsedit = prefs.edit(); + + prefsedit.putString(ONBOOTPROFILE, connectedrofile.getUUIDString()); + prefsedit.apply(); + mLastConnectedVpn=connectedrofile; + + } + + public static VpnProfile getOnBootProfile(Context c) { + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(c); + + boolean useStartOnBoot = prefs.getBoolean("restartvpnonboot", false); + + + String mBootProfileUUID = prefs.getString(ONBOOTPROFILE,null); + if(useStartOnBoot && mBootProfileUUID!=null) + return get(c, mBootProfileUUID); + else + return null; + } + + + + + public Collection<VpnProfile> getProfiles() { + return profiles.values(); + } + + public VpnProfile getProfileByName(String name) { + for (VpnProfile vpnp : profiles.values()) { + if(vpnp.getName().equals(name)) { + return vpnp; + } + } + return null; + } + + public void saveProfileList(Context context) { + SharedPreferences sharedprefs = context.getSharedPreferences(PREFS_NAME,Activity.MODE_PRIVATE); + Editor editor = sharedprefs.edit(); + editor.putStringSet("vpnlist", profiles.keySet()); + + // For reasing I do not understand at all + // Android saves my prefs file only one time + // if I remove the debug code below :( + int counter = sharedprefs.getInt("counter", 0); + editor.putInt("counter", counter+1); + editor.apply(); + + } + + public void addProfile(VpnProfile profile) { + profiles.put(profile.getUUID().toString(),profile); + + } + + public static void setTemporaryProfile(VpnProfile tmp) { + ProfileManager.tmpprofile = tmp; + } + + + public void saveProfile(Context context,VpnProfile profile) { + // First let basic settings save its state + + ObjectOutputStream vpnfile; + try { + vpnfile = new ObjectOutputStream(context.openFileOutput((profile.getUUID().toString() + ".vp"),Activity.MODE_PRIVATE)); + + vpnfile.writeObject(profile); + vpnfile.flush(); + vpnfile.close(); + } catch (FileNotFoundException e) { + + VpnStatus.logException("saving VPN profile", e); + throw new RuntimeException(e); + } catch (IOException e) { + VpnStatus.logException("saving VPN profile", e); + throw new RuntimeException(e); + } + } + + + private void loadVPNList(Context context) { + profiles = new HashMap<String, VpnProfile>(); + SharedPreferences listpref = context.getSharedPreferences(PREFS_NAME,Activity.MODE_PRIVATE); + Set<String> vlist = listpref.getStringSet("vpnlist", null); + Exception exp =null; + if(vlist==null){ + vlist = new HashSet<String>(); + } + + for (String vpnentry : vlist) { + try { + ObjectInputStream vpnfile = new ObjectInputStream(context.openFileInput(vpnentry + ".vp")); + VpnProfile vp = ((VpnProfile) vpnfile.readObject()); + + // Sanity check + if(vp==null || vp.mName==null || vp.getUUID()==null) + continue; + + vp.upgradeProfile(); + profiles.put(vp.getUUID().toString(), vp); + + } catch (StreamCorruptedException e) { + exp=e; + } catch (FileNotFoundException e) { + exp=e; + } catch (IOException e) { + exp=e; + } catch (ClassNotFoundException e) { + exp=e; + } + if(exp!=null) { + VpnStatus.logException("Loading VPN List",exp); + } + } + } + + public int getNumberOfProfiles() { + return profiles.size(); + } + + + + public void removeProfile(Context context,VpnProfile profile) { + String vpnentry = profile.getUUID().toString(); + profiles.remove(vpnentry); + saveProfileList(context); + context.deleteFile(vpnentry + ".vp"); + if(mLastConnectedVpn==profile) + mLastConnectedVpn=null; + + } + + + + public static VpnProfile get(Context context, String profileUUID) { + checkInstance(context); + return get(profileUUID); + } + + + + public static VpnProfile getLastConnectedVpn() { + return mLastConnectedVpn; + } + +} diff --git a/main/src/main/java/de/blinkt/openvpn/core/ProxyDetection.java b/main/src/main/java/de/blinkt/openvpn/core/ProxyDetection.java new file mode 100644 index 00000000..4f66c503 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/core/ProxyDetection.java @@ -0,0 +1,55 @@ +package de.blinkt.openvpn.core; + +import java.net.InetSocketAddress; +import java.net.MalformedURLException; +import java.net.Proxy; +import java.net.ProxySelector; +import java.net.SocketAddress; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.List; + +import de.blinkt.openvpn.R; +import de.blinkt.openvpn.VpnProfile; + +public class ProxyDetection { + static SocketAddress detectProxy(VpnProfile vp) { + // Construct a new url with https as protocol + try { + URL url = new URL(String.format("https://%s:%s",vp.mServerName,vp.mServerPort)); + Proxy proxy = getFirstProxy(url); + + if(proxy==null) + return null; + SocketAddress addr = proxy.address(); + if (addr instanceof InetSocketAddress) { + return addr; + } + + } catch (MalformedURLException e) { + VpnStatus.logError(R.string.getproxy_error, e.getLocalizedMessage()); + } catch (URISyntaxException e) { + VpnStatus.logError(R.string.getproxy_error, e.getLocalizedMessage()); + } + return null; + } + + static Proxy getFirstProxy(URL url) throws URISyntaxException { + System.setProperty("java.net.useSystemProxies", "true"); + + List<Proxy> proxylist = ProxySelector.getDefault().select(url.toURI()); + + + if (proxylist != null) { + for (Proxy proxy: proxylist) { + SocketAddress addr = proxy.address(); + + if (addr != null) { + return proxy; + } + } + + } + return null; + } +}
\ No newline at end of file diff --git a/main/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java b/main/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java new file mode 100644 index 00000000..5f1efb5f --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/core/VPNLaunchHelper.java @@ -0,0 +1,77 @@ +package de.blinkt.openvpn.core; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; + +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import de.blinkt.openvpn.R; +import de.blinkt.openvpn.VpnProfile; + +public class VPNLaunchHelper { + static private boolean writeMiniVPN(Context context) { + File mvpnout = new File(context.getCacheDir(),VpnProfile.MINIVPN); + if (mvpnout.exists() && mvpnout.canExecute()) + return true; + + IOException e2 = null; + + try { + InputStream mvpn; + + try { + mvpn = context.getAssets().open("minivpn." + Build.CPU_ABI); + } + catch (IOException errabi) { + VpnStatus.logInfo("Failed getting assets for archicture " + Build.CPU_ABI); + e2=errabi; + mvpn = context.getAssets().open("minivpn." + Build.CPU_ABI2); + + } + + + FileOutputStream fout = new FileOutputStream(mvpnout); + + byte buf[]= new byte[4096]; + + int lenread = mvpn.read(buf); + while(lenread> 0) { + fout.write(buf, 0, lenread); + lenread = mvpn.read(buf); + } + fout.close(); + + if(!mvpnout.setExecutable(true)) { + VpnStatus.logError("Failed to set minivpn executable"); + return false; + } + + + return true; + } catch (IOException e) { + if(e2!=null) + VpnStatus.logException(e2); + VpnStatus.logException(e); + + return false; + } + } + + + public static void startOpenVpn(VpnProfile startprofile, Context context) { + if(!writeMiniVPN(context)) { + VpnStatus.logError("Error writing minivpn binary"); + return; + } + + VpnStatus.logInfo(R.string.building_configration); + + Intent startVPN = startprofile.prepareIntent(context); + if(startVPN!=null) + context.startService(startVPN); + + } +} diff --git a/main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java b/main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java new file mode 100644 index 00000000..d146aef8 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/core/VpnStatus.java @@ -0,0 +1,540 @@ +package de.blinkt.openvpn.core; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.Signature; +import android.os.Build; +import android.os.Parcel; +import android.os.Parcelable; +import de.blinkt.openvpn.R; + +import java.io.ByteArrayInputStream; +import java.io.FileNotFoundException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.Arrays; +import java.util.FormatFlagsConversionMismatchException; +import java.util.LinkedList; +import java.util.Locale; +import java.util.UnknownFormatConversionException; +import java.util.Vector; + +public class VpnStatus { + + + public static LinkedList<LogItem> logbuffer; + + private static Vector<LogListener> logListener; + private static Vector<StateListener> stateListener; + private static Vector<ByteCountListener> byteCountListener; + + private static String mLaststatemsg=""; + + private static String mLaststate = "NOPROCESS"; + + private static int mLastStateresid=R.string.state_noprocess; + + private static long mlastByteCount[]={0,0,0,0}; + + public static void logException(LogLevel ll, String context, Exception e) { + StringWriter sw = new StringWriter(); + e.printStackTrace(new PrintWriter(sw)); + LogItem li; + if (context !=null) { + li = new LogItem(ll, R.string.unhandled_exception_context, e.getMessage(), sw.toString(), context); + } else { + li = new LogItem(ll, R.string.unhandled_exception, e.getMessage(), sw.toString()); + } + newLogItem(li); + } + + public static void logException(Exception e) { + logException(LogLevel.ERROR, null, e); + } + + public static void logException(String context, Exception e) { + logException(LogLevel.ERROR, context, e); + } + + private static final int MAXLOGENTRIES = 1000; + + public static final String MANAGMENT_PREFIX = "M:"; + + public enum ConnectionStatus { + LEVEL_CONNECTED, + LEVEL_VPNPAUSED, + LEVEL_CONNECTING_SERVER_REPLIED, + LEVEL_CONNECTING_NO_SERVER_REPLY_YET, + LEVEL_NONETWORK, + LEVEL_NOTCONNECTED, + LEVEL_AUTH_FAILED, + LEVEL_WAITING_FOR_USER_INPUT, + UNKNOWN_LEVEL + } + + public enum LogLevel { + INFO(2), + ERROR(-2), + WARNING(1), + VERBOSE(3), + DEBUG(4); + + protected int mValue; + LogLevel(int value) { + mValue = value; + } + + public int getInt() { + return mValue; + } + + public static LogLevel getEnumByValue(int value) { + switch (value) { + case 1: return INFO; + case 2: return ERROR; + case 3: return WARNING; + case 4: return DEBUG; + default: return null; + } + } + } + + // keytool -printcert -jarfile de.blinkt.openvpn_85.apk + public static final byte[] officalkey = {-58, -42, -44, -106, 90, -88, -87, -88, -52, -124, 84, 117, 66, 79, -112, -111, -46, 86, -37, 109}; + public static final byte[] officaldebugkey = {-99, -69, 45, 71, 114, -116, 82, 66, -99, -122, 50, -70, -56, -111, 98, -35, -65, 105, 82, 43}; + public static final byte[] amazonkey = {-116, -115, -118, -89, -116, -112, 120, 55, 79, -8, -119, -23, 106, -114, -85, -56, -4, 105, 26, -57}; + public static final byte[] fdroidkey = {-92, 111, -42, -46, 123, -96, -60, 79, -27, -31, 49, 103, 11, -54, -68, -27, 17, 2, 121, 104}; + + + private static ConnectionStatus mLastLevel=ConnectionStatus.LEVEL_NOTCONNECTED; + + static { + logbuffer = new LinkedList<LogItem>(); + logListener = new Vector<VpnStatus.LogListener>(); + stateListener = new Vector<VpnStatus.StateListener>(); + byteCountListener = new Vector<VpnStatus.ByteCountListener>(); + logInformation(); + } + + + public static class LogItem implements Parcelable { + + + private Object [] mArgs = null; + private String mMessage = null; + private int mRessourceId; + // Default log priority + LogLevel mLevel = LogLevel.INFO; + private long logtime = System.currentTimeMillis(); + private int mVerbosityLevel = -1; + + private LogItem(int ressourceId, Object[] args) { + mRessourceId = ressourceId; + mArgs = args; + } + + public LogItem(LogLevel level, int verblevel, String message) { + mMessage=message; + mLevel = level; + mVerbosityLevel = verblevel; + } + + @Override + public int describeContents() { + return 0; + } + + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeArray(mArgs); + dest.writeString(mMessage); + dest.writeInt(mRessourceId); + dest.writeInt(mLevel.getInt()); + dest.writeInt(mVerbosityLevel); + + dest.writeLong(logtime); + } + + public LogItem(Parcel in) { + mArgs = in.readArray(Object.class.getClassLoader()); + mMessage = in.readString(); + mRessourceId = in.readInt(); + mLevel = LogLevel.getEnumByValue(in.readInt()); + mVerbosityLevel = in.readInt(); + logtime = in.readLong(); + } + + public static final Parcelable.Creator<LogItem> CREATOR + = new Parcelable.Creator<LogItem>() { + public LogItem createFromParcel(Parcel in) { + return new LogItem(in); + } + + public LogItem[] newArray(int size) { + return new LogItem[size]; + } + }; + + public LogItem(LogLevel loglevel,int ressourceId, Object... args) { + mRessourceId = ressourceId; + mArgs =args; + mLevel = loglevel; + } + + + public LogItem(LogLevel loglevel, String msg) { + mLevel = loglevel; + mMessage = msg; + } + + + public LogItem(LogLevel loglevel, int ressourceId) { + mRessourceId =ressourceId; + mLevel = loglevel; + } + + public String getString(Context c) { + try { + if(mMessage !=null) { + return mMessage; + } else { + if(c!=null) { + if(mRessourceId==R.string.mobile_info) + return getMobileInfoString(c); + if(mArgs == null) + return c.getString(mRessourceId); + else + return c.getString(mRessourceId,mArgs); + } else { + String str = String.format(Locale.ENGLISH,"Log (no context) resid %d", mRessourceId); + if(mArgs !=null) + for(Object o:mArgs) + str += "|" + o.toString(); + + return str; + } + } + } catch (UnknownFormatConversionException e) { + if (c != null) + throw new UnknownFormatConversionException(e.getLocalizedMessage() + getString(null)); + else + throw e; + } catch (java.util.FormatFlagsConversionMismatchException e) { + if (c != null) + throw new FormatFlagsConversionMismatchException(e.getLocalizedMessage() + getString(null),e.getConversion()); + else + throw e; + } + + } + + public LogLevel getLogLevel() + { + return mLevel; + } + + // The lint is wrong here + @SuppressLint("StringFormatMatches") + private String getMobileInfoString(Context c) { + c.getPackageManager(); + String apksign="error getting package signature"; + + String version="error getting version"; + try { + Signature raw = c.getPackageManager().getPackageInfo(c.getPackageName(), PackageManager.GET_SIGNATURES).signatures[0]; + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + X509Certificate cert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(raw.toByteArray())); + MessageDigest md = MessageDigest.getInstance("SHA-1"); + byte[] der = cert.getEncoded(); + md.update(der); + byte[] digest = md.digest(); + + if (Arrays.equals(digest, officalkey)) + apksign = c.getString(R.string.official_build); + else if (Arrays.equals(digest, officaldebugkey)) + apksign = c.getString(R.string.debug_build); + else if (Arrays.equals(digest, amazonkey)) + apksign = "amazon version"; + else if (Arrays.equals(digest, fdroidkey)) + apksign = "F-Droid built and signed version"; + else + apksign = c.getString(R.string.built_by,cert.getSubjectX500Principal().getName()); + + PackageInfo packageinfo = c.getPackageManager().getPackageInfo(c.getPackageName(), 0); + version = packageinfo.versionName; + + } catch (NameNotFoundException e) { + } catch (CertificateException e) { + } catch (NoSuchAlgorithmException e) { + } + + Object[] argsext = Arrays.copyOf(mArgs, mArgs.length+2); + argsext[argsext.length-1]=apksign; + argsext[argsext.length-2]=version; + + return c.getString(R.string.mobile_info_extended, argsext); + + } + + public long getLogtime() { + return logtime; + } + + + public int getVerbosityLevel() { + if (mVerbosityLevel==-1) { + // Hack: + // For message not from OpenVPN, report the status level as log level + return mLevel.getInt(); + } + return mVerbosityLevel; + } + } + + + + public interface LogListener { + void newLog(LogItem logItem); + } + + public interface StateListener { + void updateState(String state, String logmessage, int localizedResId, ConnectionStatus level); + } + + public interface ByteCountListener { + void updateByteCount(long in, long out, long diffIn, long diffOut); + } + + public synchronized static void logMessage(LogLevel level,String prefix, String message) + { + newLogItem(new LogItem(level, prefix + message)); + + } + + public synchronized static void clearLog() { + logbuffer.clear(); + logInformation(); + } + + private static void logInformation() { + logInfo(R.string.mobile_info,Build.MODEL, Build.BOARD,Build.BRAND,Build.VERSION.SDK_INT); + } + + public synchronized static void addLogListener(LogListener ll){ + logListener.add(ll); + } + + public synchronized static void removeLogListener(LogListener ll) { + logListener.remove(ll); + } + + public synchronized static void addByteCountListener(ByteCountListener bcl) { + bcl.updateByteCount(mlastByteCount[0], mlastByteCount[1], mlastByteCount[2], mlastByteCount[3]); + byteCountListener.add(bcl); + } + + public synchronized static void removeByteCountListener(ByteCountListener bcl) { + byteCountListener.remove(bcl); + } + + + public synchronized static void addStateListener(StateListener sl){ + if(!stateListener.contains(sl)){ + stateListener.add(sl); + if(mLaststate!=null) + sl.updateState(mLaststate, mLaststatemsg, mLastStateresid, mLastLevel); + } + } + + private static int getLocalizedState(String state){ + if (state.equals("CONNECTING")) + return R.string.state_connecting; + else if (state.equals("WAIT")) + return R.string.state_wait; + else if (state.equals("AUTH")) + return R.string.state_auth; + else if (state.equals("GET_CONFIG")) + return R.string.state_get_config; + else if (state.equals("ASSIGN_IP")) + return R.string.state_assign_ip; + else if (state.equals("ADD_ROUTES")) + return R.string.state_add_routes; + else if (state.equals("CONNECTED")) + return R.string.state_connected; + else if (state.equals("DISCONNECTED")) + return R.string.state_disconnected; + else if (state.equals("RECONNECTING")) + return R.string.state_reconnecting; + else if (state.equals("EXITING")) + return R.string.state_exiting; + else if (state.equals("RESOLVE")) + return R.string.state_resolve; + else if (state.equals("TCP_CONNECT")) + return R.string.state_tcp_connect; + else + return R.string.unknown_state; + + } + + public static void updateStatePause(OpenVPNManagement.pauseReason pauseReason) { + switch (pauseReason) { + case noNetwork: + VpnStatus.updateStateString("NONETWORK", "", R.string.state_nonetwork, ConnectionStatus.LEVEL_NONETWORK); + break; + case screenOff: + VpnStatus.updateStateString("SCREENOFF", "", R.string.state_screenoff, ConnectionStatus.LEVEL_VPNPAUSED); + break; + case userPause: + VpnStatus.updateStateString("USERPAUSE", "", R.string.state_userpause, ConnectionStatus.LEVEL_VPNPAUSED); + break; + } + + } + + private static ConnectionStatus getLevel(String state){ + String[] noreplyet = {"CONNECTING","WAIT", "RECONNECTING", "RESOLVE", "TCP_CONNECT"}; + String[] reply = {"AUTH","GET_CONFIG","ASSIGN_IP","ADD_ROUTES"}; + String[] connected = {"CONNECTED"}; + String[] notconnected = {"DISCONNECTED", "EXITING"}; + + for(String x:noreplyet) + if(state.equals(x)) + return ConnectionStatus.LEVEL_CONNECTING_NO_SERVER_REPLY_YET; + + for(String x:reply) + if(state.equals(x)) + return ConnectionStatus.LEVEL_CONNECTING_SERVER_REPLIED; + + for(String x:connected) + if(state.equals(x)) + return ConnectionStatus.LEVEL_CONNECTED; + + for(String x:notconnected) + if(state.equals(x)) + return ConnectionStatus.LEVEL_NOTCONNECTED; + + return ConnectionStatus.UNKNOWN_LEVEL; + + } + + + + + public synchronized static void removeStateListener(StateListener sl) { + stateListener.remove(sl); + } + + + synchronized public static LogItem[] getlogbuffer() { + + // The stoned way of java to return an array from a vector + // brought to you by eclipse auto complete + return logbuffer.toArray(new LogItem[logbuffer.size()]); + + } + + public static void updateStateString (String state, String msg) { + int rid = getLocalizedState(state); + ConnectionStatus level = getLevel(state); + updateStateString(state, msg, rid, level); + } + + public synchronized static void updateStateString(String state, String msg, int resid, ConnectionStatus level) { + // Workound for OpenVPN doing AUTH and wait and being connected + // Simply ignore these state + if (mLastLevel == ConnectionStatus.LEVEL_CONNECTED && + (state.equals("WAIT") || state.equals("AUTH"))) + { + newLogItem(new LogItem((LogLevel.DEBUG), String.format("Ignoring OpenVPN Status in CONNECTED state (%s->%s): %s",state,level.toString(),msg))); + return; + } + + mLaststate= state; + mLaststatemsg = msg; + mLastStateresid = resid; + mLastLevel = level; + + + + for (StateListener sl : stateListener) { + sl.updateState(state,msg,resid,level); + } + //newLogItem(new LogItem((LogLevel.DEBUG), String.format("New OpenVPN Status (%s->%s): %s",state,level.toString(),msg))); + } + + public static void logInfo(String message) { + newLogItem(new LogItem(LogLevel.INFO, message)); + } + + public static void logInfo(int resourceId, Object... args) { + newLogItem(new LogItem(LogLevel.INFO, resourceId, args)); + } + + public static void logDebug(int resourceId, Object... args) { + newLogItem(new LogItem(LogLevel.DEBUG, resourceId, args)); + } + + + private synchronized static void newLogItem(LogItem logItem) { + logbuffer.addLast(logItem); + if(logbuffer.size()>MAXLOGENTRIES) + logbuffer.removeFirst(); + + for (LogListener ll : logListener) { + ll.newLog(logItem); + } + } + + public static void logError(String msg) { + newLogItem(new LogItem(LogLevel.ERROR, msg)); + + } + + public static void logWarning(int resourceId, Object... args) { + newLogItem(new LogItem(LogLevel.WARNING, resourceId, args)); + } + + public static void logWarning(String msg) { + newLogItem(new LogItem(LogLevel.WARNING, msg)); + } + + + public static void logError(int resourceId) { + newLogItem(new LogItem(LogLevel.ERROR, resourceId)); + } + public static void logError(int resourceId, Object... args) { + newLogItem(new LogItem(LogLevel.ERROR, resourceId, args)); + } + + public static void logMessageOpenVPN(LogLevel level, int ovpnlevel, String message) { + newLogItem(new LogItem(level, ovpnlevel, message)); + + } + + + public static synchronized void updateByteCount(long in, long out) { + long lastIn = mlastByteCount[0]; + long lastOut = mlastByteCount[1]; + long diffIn = mlastByteCount[2] = in - lastIn; + long diffOut = mlastByteCount[3] = out - lastOut; + + + + mlastByteCount = new long[] {in,out,diffIn,diffOut}; + for(ByteCountListener bcl:byteCountListener){ + bcl.updateByteCount(in, out, diffIn,diffOut); + } + } + + + +} diff --git a/main/src/main/java/de/blinkt/openvpn/core/X509Utils.java b/main/src/main/java/de/blinkt/openvpn/core/X509Utils.java new file mode 100644 index 00000000..da1e4ed5 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/core/X509Utils.java @@ -0,0 +1,155 @@ +package de.blinkt.openvpn.core; + +import android.content.Context; +import android.text.TextUtils; + +import de.blinkt.openvpn.R; +import de.blinkt.openvpn.VpnProfile; +import org.spongycastle.util.io.pem.PemObject; +import org.spongycastle.util.io.pem.PemReader; + + +import javax.security.auth.x500.X500Principal; +import java.io.*; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.Hashtable; + +public class X509Utils { + public static Certificate getCertificateFromFile(String certfilename) throws FileNotFoundException, CertificateException { + CertificateFactory certFact = CertificateFactory.getInstance("X.509"); + + InputStream inStream; + + if(VpnProfile.isEmbedded(certfilename)) { + // The java certifcate reader is ... kind of stupid + // It does NOT ignore chars before the --BEGIN ... + int subIndex = certfilename.indexOf("-----BEGIN CERTIFICATE-----"); + subIndex = Math.max(0,subIndex); + inStream = new ByteArrayInputStream(certfilename.substring(subIndex).getBytes()); + + + } else { + inStream = new FileInputStream(certfilename); + } + + + return certFact.generateCertificate(inStream); + } + + public static PemObject readPemObjectFromFile (String keyfilename) throws IOException { + + Reader inStream; + + if(VpnProfile.isEmbedded(keyfilename)) + inStream = new StringReader(VpnProfile.getEmbeddedContent(keyfilename)); + else + inStream = new FileReader(new File(keyfilename)); + + PemReader pr = new PemReader(inStream); + PemObject r = pr.readPemObject(); + pr.close(); + return r; + } + + + + + public static String getCertificateFriendlyName (Context c, String filename) { + if(!TextUtils.isEmpty(filename)) { + try { + X509Certificate cert = (X509Certificate) getCertificateFromFile(filename); + + return getCertificateFriendlyName(cert); + + } catch (Exception e) { + VpnStatus.logError("Could not read certificate" + e.getLocalizedMessage()); + } + } + return c.getString(R.string.cannotparsecert); + } + + public static String getCertificateFriendlyName(X509Certificate cert) { + X500Principal principal = cert.getSubjectX500Principal(); + byte[] encodedSubject = principal.getEncoded(); + String friendlyName=null; + + /* Hack so we do not have to ship a whole Spongy/bouncycastle */ + Exception exp=null; + try { + Class X509NameClass = Class.forName("com.android.org.bouncycastle.asn1.x509.X509Name"); + Method getInstance = X509NameClass.getMethod("getInstance",Object.class); + + Hashtable defaultSymbols = (Hashtable) X509NameClass.getField("DefaultSymbols").get(X509NameClass); + + if (!defaultSymbols.containsKey("1.2.840.113549.1.9.1")) + defaultSymbols.put("1.2.840.113549.1.9.1","eMail"); + + Object subjectName = getInstance.invoke(X509NameClass, encodedSubject); + + Method toString = X509NameClass.getMethod("toString",boolean.class,Hashtable.class); + + friendlyName= (String) toString.invoke(subjectName,true,defaultSymbols); + + } catch (ClassNotFoundException e) { + exp =e ; + } catch (NoSuchMethodException e) { + exp =e; + } catch (InvocationTargetException e) { + exp =e; + } catch (IllegalAccessException e) { + exp =e; + } catch (NoSuchFieldException e) { + exp =e; + } + if (exp!=null) + VpnStatus.logException("Getting X509 Name from certificate", exp); + + /* Fallback if the reflection method did not work */ + if(friendlyName==null) + friendlyName = principal.getName(); + + + // Really evil hack to decode email address + // See: http://code.google.com/p/android/issues/detail?id=21531 + + String[] parts = friendlyName.split(","); + for (int i=0;i<parts.length;i++){ + String part = parts[i]; + if (part.startsWith("1.2.840.113549.1.9.1=#16")) { + parts[i] = "email=" + ia5decode(part.replace("1.2.840.113549.1.9.1=#16", "")); + } + } + friendlyName = TextUtils.join(",", parts); + return friendlyName; + } + + public static boolean isPrintableChar(char c) { + Character.UnicodeBlock block = Character.UnicodeBlock.of( c ); + return (!Character.isISOControl(c)) && + block != null && + block != Character.UnicodeBlock.SPECIALS; + } + + private static String ia5decode(String ia5string) { + String d = ""; + for (int i=1;i<ia5string.length();i=i+2) { + String hexstr = ia5string.substring(i-1,i+1); + char c = (char) Integer.parseInt(hexstr,16); + if (isPrintableChar(c)) { + d+=c; + } else if (i==1 && (c==0x12 || c==0x1b)) { + ; // ignore + } else { + d += "\\x" + hexstr; + } + } + return d; + } + + +} diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/AboutFragment.java b/main/src/main/java/de/blinkt/openvpn/fragments/AboutFragment.java new file mode 100644 index 00000000..61fcb581 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/fragments/AboutFragment.java @@ -0,0 +1,297 @@ +package de.blinkt.openvpn.fragments; + +import android.app.Fragment; +import android.app.PendingIntent; +import android.content.*; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager.NameNotFoundException; +import android.os.Bundle; +import android.os.IBinder; +import android.os.RemoteException; +import android.text.Html; +import android.text.SpannableString; +import android.text.Spanned; +import android.text.TextUtils; +import android.text.method.LinkMovementMethod; +import android.text.style.ClickableSpan; +import android.util.Log; +import android.util.Pair; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.webkit.WebView; +import android.widget.TextView; +import com.android.vending.billing.IInAppBillingService; +import de.blinkt.openvpn.R; +import de.blinkt.openvpn.core.VpnStatus; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.*; + +public class AboutFragment extends Fragment implements View.OnClickListener { + + public static final String INAPPITEM_TYPE_INAPP = "inapp"; + public static final String RESPONSE_CODE = "RESPONSE_CODE"; + private static final int DONATION_CODE = 12; + private static final int BILLING_RESPONSE_RESULT_OK = 0; + private static final String RESPONSE_BUY_INTENT = "BUY_INTENT"; + private static final String[] donationSkus = { "donation1eur", "donation2eur", "donation5eur", "donation10eur", + "donation1337eur","donation23eur","donation25eur",}; + IInAppBillingService mService; + Hashtable<View, String> viewToProduct = new Hashtable<View, String>(); + ServiceConnection mServiceConn = new ServiceConnection() { + @Override + public void onServiceDisconnected(ComponentName name) { + mService = null; + } + + @Override + public void onServiceConnected(ComponentName name, + IBinder service) { + mService = IInAppBillingService.Stub.asInterface(service); + initGooglePlayDonation(); + + } + }; + + private void initGooglePlayDonation() { + new Thread("queryGMSInApp") { + @Override + public void run() { + initGMSDonateOptions(); + } + }.start(); + } + + private TextView gmsTextView; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActivity().bindService(new + Intent("com.android.vending.billing.InAppBillingService.BIND"), + mServiceConn, Context.BIND_AUTO_CREATE); + + } + + @Override + public void onDestroy() { + super.onDestroy(); + if (mServiceConn != null) { + getActivity().unbindService(mServiceConn); + } + + } + + private void initGMSDonateOptions() { + try { + int billingSupported = mService.isBillingSupported(3, getActivity().getPackageName(), INAPPITEM_TYPE_INAPP); + if (billingSupported != BILLING_RESPONSE_RESULT_OK) { + Log.i("OpenVPN", "Play store billing not supported"); + return; + } + + ArrayList skuList = new ArrayList(); + Collections.addAll(skuList, donationSkus); + Bundle querySkus = new Bundle(); + querySkus.putStringArrayList("ITEM_ID_LIST", skuList); + + Bundle ownedItems = mService.getPurchases(3, getActivity().getPackageName(), INAPPITEM_TYPE_INAPP, null); + + + if (ownedItems.getInt(RESPONSE_CODE) != BILLING_RESPONSE_RESULT_OK) + return; + + final ArrayList<String> ownedSkus = ownedItems.getStringArrayList("INAPP_PURCHASE_ITEM_LIST"); + + Bundle skuDetails = mService.getSkuDetails(3, getActivity().getPackageName(), INAPPITEM_TYPE_INAPP, querySkus); + + + if (skuDetails.getInt(RESPONSE_CODE) != BILLING_RESPONSE_RESULT_OK) + return; + + final ArrayList<String> responseList = skuDetails.getStringArrayList("DETAILS_LIST"); + + if (getActivity() != null) { + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + createPlayBuyOptions(ownedSkus, responseList); + + } + }); + } + + } catch (RemoteException e) { + VpnStatus.logException(e); + } + } + + private static class SkuResponse { + String title; + String price; + + SkuResponse(String p, String t) + { + title=t; + price=p; + } + } + + + + private void createPlayBuyOptions(ArrayList<String> ownedSkus, ArrayList<String> responseList) { + try { + Vector<Pair<String,String>> gdonation = new Vector<Pair<String, String>>(); + + gdonation.add(new Pair<String, String>(getString(R.string.donatePlayStore),null)); + HashMap<String, SkuResponse> responseMap = new HashMap<String, SkuResponse>(); + for (String thisResponse : responseList) { + JSONObject object = new JSONObject(thisResponse); + responseMap.put( + object.getString("productId"), + new SkuResponse( + object.getString("price"), + object.getString("title"))); + + } + for (String sku: donationSkus) + if (responseMap.containsKey(sku)) + gdonation.add(getSkuTitle(sku, + responseMap.get(sku).title, responseMap.get(sku).price, ownedSkus)); + + String gmsTextString=""; + for(int i=0;i<gdonation.size();i++) { + if(i==1) + gmsTextString+= " "; + else if(i>1) + gmsTextString+= ", "; + gmsTextString+=gdonation.elementAt(i).first; + } + SpannableString gmsText = new SpannableString(gmsTextString); + + + int lStart = 0; + int lEnd=0; + for(Pair<String, String> item:gdonation){ + lEnd = lStart + item.first.length(); + if (item.second!=null) { + final String mSku = item.second; + ClickableSpan cspan = new ClickableSpan() + { + @Override + public void onClick(View widget) { + triggerBuy(mSku); + } + }; + gmsText.setSpan(cspan,lStart,lEnd,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + } + lStart = lEnd+2; // Account for ", " between items + } + + if(gmsTextView !=null) { + gmsTextView.setText(gmsText); + gmsTextView.setMovementMethod(LinkMovementMethod.getInstance()); + gmsTextView.setVisibility(View.VISIBLE); + } + + } catch (JSONException e) { + VpnStatus.logException("Parsing Play Store IAP",e); + } + + } + + private Pair<String,String> getSkuTitle(final String sku, String title, String price, ArrayList<String> ownedSkus) { + String text; + if (ownedSkus.contains(sku)) + return new Pair<String,String>(getString(R.string.thanks_for_donation, price),null); + + if (price.contains("€")|| price.contains("\u20ac")) { + text= title; + } else { + text = String.format(Locale.getDefault(), "%s (%s)", title, price); + } + //return text; + return new Pair<String,String>(price, sku); + + } + + private void triggerBuy(String sku) { + try { + Bundle buyBundle + = mService.getBuyIntent(3, getActivity().getPackageName(), + sku, INAPPITEM_TYPE_INAPP, "Thanks for the donation! :)"); + + + if (buyBundle.getInt(RESPONSE_CODE) == BILLING_RESPONSE_RESULT_OK) { + PendingIntent buyIntent = (PendingIntent) buyBundle.getParcelable(RESPONSE_BUY_INTENT); + getActivity().startIntentSenderForResult(buyIntent.getIntentSender(), DONATION_CODE, new Intent(), + 0, 0, 0); + } + + } catch (RemoteException e) { + VpnStatus.logException(e); + } catch (IntentSender.SendIntentException e) { + VpnStatus.logException(e); + } + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View v = inflater.inflate(R.layout.about, container, false); + TextView ver = (TextView) v.findViewById(R.id.version); + + String version; + String name = "Openvpn"; + try { + PackageInfo packageinfo = getActivity().getPackageManager().getPackageInfo(getActivity().getPackageName(), 0); + version = packageinfo.versionName; + name = getString(R.string.app); + } catch (NameNotFoundException e) { + version = "error fetching version"; + } + + + ver.setText(getString(R.string.version_info, name, version)); + + TextView paypal = (TextView) v.findViewById(R.id.donatestring); + + String donatetext = getActivity().getString(R.string.donatewithpaypal); + Spanned htmltext = Html.fromHtml(donatetext); + paypal.setText(htmltext); + paypal.setMovementMethod(LinkMovementMethod.getInstance()); + gmsTextView = (TextView) v.findViewById(R.id.donategms); + /* recreating view without onCreate/onDestroy cycle */ + if (mService!=null) + initGooglePlayDonation(); + + TextView translation = (TextView) v.findViewById(R.id.translation); + + // Don't print a text for myself + if (getString(R.string.translationby).contains("Arne Schwabe")) + translation.setText(""); + else + translation.setText(R.string.translationby); + + WebView wv = (WebView)v.findViewById(R.id.webView); + wv.loadUrl("file:///android_asset/full_licenses.html"); + + return v; + } + + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + if (mService!=null) + initGooglePlayDonation(); + } + + + @Override + public void onClick(View v) { + + } +} diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/FaqFragment.java b/main/src/main/java/de/blinkt/openvpn/fragments/FaqFragment.java new file mode 100644 index 00000000..238ad952 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/fragments/FaqFragment.java @@ -0,0 +1,36 @@ +package de.blinkt.openvpn.fragments; + +import android.app.Fragment; +import android.os.Bundle; +import android.text.Html; +import android.text.method.LinkMovementMethod; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; +import de.blinkt.openvpn.R; + +public class FaqFragment extends Fragment { + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View v= inflater.inflate(R.layout.faq, container, false); + + insertHtmlEntry(v,R.id.broken_images_faq,R.string.broken_images_faq); + insertHtmlEntry(v,R.id.faq_howto,R.string.faq_howto); + insertHtmlEntry(v, R.id.baterry_consumption, R.string.baterry_consumption); + insertHtmlEntry(v, R.id.faq_tethering, R.string.faq_tethering); + insertHtmlEntry(v, R.id.faq_vpndialog43, R.string.faq_vpndialog43); + insertHtmlEntry(v, R.id.faq_system_dialog_xposed, R.string.faq_system_dialog_xposed); + return v; + } + + private void insertHtmlEntry (View v, int viewId, int stringId) { + TextView faqitem = (TextView) v.findViewById(viewId); + faqitem.setText(Html.fromHtml(getActivity().getString(stringId))); + faqitem.setMovementMethod(LinkMovementMethod.getInstance()); + + } + +} diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/FileSelectionFragment.java b/main/src/main/java/de/blinkt/openvpn/fragments/FileSelectionFragment.java new file mode 100644 index 00000000..84e065a5 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/fragments/FileSelectionFragment.java @@ -0,0 +1,256 @@ +package de.blinkt.openvpn.fragments; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.TreeMap; + +import android.app.AlertDialog; +import android.app.ListFragment; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.CheckBox; +import android.widget.ListView; +import android.widget.SimpleAdapter; +import android.widget.TextView; +import de.blinkt.openvpn.activities.FileSelect; +import de.blinkt.openvpn.R; + +public class FileSelectionFragment extends ListFragment { + + private static final String ITEM_KEY = "key"; + private static final String ITEM_IMAGE = "image"; + private static final String ROOT = "/"; + + + private List<String> path = null; + private TextView myPath; + private ArrayList<HashMap<String, Object>> mList; + + private Button selectButton; + + + private String parentPath; + private String currentPath = ROOT; + + + private String[] formatFilter = null; + + private File selectedFile; + private HashMap<String, Integer> lastPositions = new HashMap<String, Integer>(); + private String mStartPath; + private CheckBox mInlineImport; + private Button mClearButton; + private boolean mHideImport=false; + + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View v = inflater.inflate(R.layout.file_dialog_main, container,false); + + myPath = (TextView) v.findViewById(R.id.path); + + mInlineImport = (CheckBox) v.findViewById(R.id.doinline); + + if(mHideImport) { + mInlineImport.setVisibility(View.GONE); + mInlineImport.setChecked(false); + } + + + + selectButton = (Button) v.findViewById(R.id.fdButtonSelect); + selectButton.setEnabled(false); + selectButton.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + if (selectedFile != null) { + if(mInlineImport.isChecked()) + + ((FileSelect) getActivity()).importFile(selectedFile.getPath()); + else + ((FileSelect) getActivity()).setFile(selectedFile.getPath()); + } + } + }); + + mClearButton = (Button) v.findViewById(R.id.fdClear); + mClearButton.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + ((FileSelect) getActivity()).clearData(); + } + }); + if(!((FileSelect) getActivity()).showClear()) { + mClearButton.setVisibility(View.GONE); + mClearButton.setEnabled(false); + } + + return v; + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + + mStartPath = ((FileSelect) getActivity()).getSelectPath(); + getDir(mStartPath); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + private void getDir(String dirPath) { + + boolean useAutoSelection = dirPath.length() < currentPath.length(); + + Integer position = lastPositions.get(parentPath); + + getDirImpl(dirPath); + + if (position != null && useAutoSelection) { + getListView().setSelection(position); + } + + } + + /** + * Monta a estrutura de arquivos e diretorios filhos do diretorio fornecido. + * + * @param dirPath + * Diretorio pai. + */ + private void getDirImpl(final String dirPath) { + + currentPath = dirPath; + + final List<String> item = new ArrayList<String>(); + path = new ArrayList<String>(); + mList = new ArrayList<HashMap<String, Object>>(); + + File f = new File(currentPath); + File[] files = f.listFiles(); + if (files == null) { + currentPath = ROOT; + f = new File(currentPath); + files = f.listFiles(); + } + + myPath.setText(getText(R.string.location) + ": " + currentPath); + + if (!currentPath.equals(ROOT)) { + + item.add(ROOT); + addItem(ROOT, R.drawable.ic_root_folder_am); + path.add(ROOT); + + item.add("../"); + addItem("../", R.drawable.ic_root_folder_am); + path.add(f.getParent()); + parentPath = f.getParent(); + + } + + TreeMap<String, String> dirsMap = new TreeMap<String, String>(); + TreeMap<String, String> dirsPathMap = new TreeMap<String, String>(); + TreeMap<String, String> filesMap = new TreeMap<String, String>(); + TreeMap<String, String> filesPathMap = new TreeMap<String, String>(); + for (File file : files) { + if (file.isDirectory()) { + String dirName = file.getName(); + dirsMap.put(dirName, dirName); + dirsPathMap.put(dirName, file.getPath()); + } else { + final String fileName = file.getName(); + final String fileNameLwr = fileName.toLowerCase(Locale.getDefault()); + // se ha um filtro de formatos, utiliza-o + if (formatFilter != null) { + boolean contains = false; + for (String aFormatFilter : formatFilter) { + final String formatLwr = aFormatFilter.toLowerCase(Locale.getDefault()); + if (fileNameLwr.endsWith(formatLwr)) { + contains = true; + break; + } + } + if (contains) { + filesMap.put(fileName, fileName); + filesPathMap.put(fileName, file.getPath()); + } + // senao, adiciona todos os arquivos + } else { + filesMap.put(fileName, fileName); + filesPathMap.put(fileName, file.getPath()); + } + } + } + item.addAll(dirsMap.tailMap("").values()); + item.addAll(filesMap.tailMap("").values()); + path.addAll(dirsPathMap.tailMap("").values()); + path.addAll(filesPathMap.tailMap("").values()); + + SimpleAdapter fileList = new SimpleAdapter(getActivity(), mList, R.layout.file_dialog_row, new String[] { + ITEM_KEY, ITEM_IMAGE }, new int[] { R.id.fdrowtext, R.id.fdrowimage }); + + for (String dir : dirsMap.tailMap("").values()) { + addItem(dir, R.drawable.ic_root_folder_am); + } + + for (String file : filesMap.tailMap("").values()) { + addItem(file, R.drawable.ic_doc_generic_am); + } + + fileList.notifyDataSetChanged(); + + setListAdapter(fileList); + + } + + private void addItem(String fileName, int imageId) { + HashMap<String, Object> item = new HashMap<String, Object>(); + item.put(ITEM_KEY, fileName); + item.put(ITEM_IMAGE, imageId); + mList.add(item); + } + + + @Override + public void onListItemClick(ListView l, View v, int position, long id) { + + File file = new File(path.get(position)); + + if (file.isDirectory()) { + selectButton.setEnabled(false); + + if (file.canRead()) { + lastPositions.put(currentPath, position); + getDir(path.get(position)); + } else { + new AlertDialog.Builder(getActivity()).setIcon(R.drawable.icon) + .setTitle("[" + file.getName() + "] " + getText(R.string.cant_read_folder)) + .setPositiveButton("OK", null).show(); + } + } else { + selectedFile = file; + v.setSelected(true); + selectButton.setEnabled(true); + } + } + + public void setNoInLine() { + mHideImport=true; + + } + +} diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/GeneralSettings.java b/main/src/main/java/de/blinkt/openvpn/fragments/GeneralSettings.java new file mode 100644 index 00000000..2e486dfe --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/fragments/GeneralSettings.java @@ -0,0 +1,123 @@ +package de.blinkt.openvpn.fragments; +import java.io.File; + +import android.app.AlertDialog; +import android.app.AlertDialog.Builder; +import android.app.Dialog; +import android.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.os.Build; +import android.os.Bundle; +import android.preference.CheckBoxPreference; +import android.preference.Preference; +import android.preference.Preference.OnPreferenceClickListener; +import android.preference.PreferenceCategory; +import android.preference.PreferenceFragment; +import de.blinkt.openvpn.R; +import de.blinkt.openvpn.api.ExternalAppDatabase; + +public class GeneralSettings extends PreferenceFragment implements OnPreferenceClickListener, OnClickListener { + + private ExternalAppDatabase mExtapp; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + + // Load the preferences from an XML resource + addPreferencesFromResource(R.xml.general_settings); + + + PreferenceCategory devHacks = (PreferenceCategory) findPreference("device_hacks"); + + + Preference loadtun = findPreference("loadTunModule"); + if(!isTunModuleAvailable()) { + loadtun.setEnabled(false); + devHacks.removePreference(loadtun); + } + + CheckBoxPreference cm9hack = (CheckBoxPreference) findPreference("useCM9Fix"); + if (!cm9hack.isChecked() && (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN_MR1)) { + devHacks.removePreference(cm9hack); + } + + mExtapp = new ExternalAppDatabase(getActivity()); + Preference clearapi = findPreference("clearapi"); + clearapi.setOnPreferenceClickListener(this); + + + if(devHacks.getPreferenceCount()==0) + getPreferenceScreen().removePreference(devHacks); + + setClearApiSummary(); + } + + private void setClearApiSummary() { + Preference clearapi = findPreference("clearapi"); + + if(mExtapp.getExtAppList().isEmpty()) { + clearapi.setEnabled(false); + clearapi.setSummary(R.string.no_external_app_allowed); + } else { + clearapi.setEnabled(true); + clearapi.setSummary(getString(R.string.allowed_apps,getExtAppList(", "))); + } + } + + private String getExtAppList(String delim) { + ApplicationInfo app; + PackageManager pm = getActivity().getPackageManager(); + + String applist=null; + for (String packagename : mExtapp.getExtAppList()) { + try { + app = pm.getApplicationInfo(packagename, 0); + if (applist==null) + applist = ""; + else + applist += delim; + applist+=app.loadLabel(pm); + + } catch (NameNotFoundException e) { + // App not found. Remove it from the list + mExtapp.removeApp(packagename); + } + } + + return applist; + } + + private boolean isTunModuleAvailable() { + // Check if the tun module exists on the file system + return new File("/system/lib/modules/tun.ko").length() > 10; + } + + @Override + public boolean onPreferenceClick(Preference preference) { + if(preference.getKey().equals("clearapi")){ + Builder builder = new AlertDialog.Builder(getActivity()); + builder.setPositiveButton(R.string.clear, this); + builder.setNegativeButton(android.R.string.cancel, null); + builder.setMessage(getString(R.string.clearappsdialog,getExtAppList("\n"))); + builder.show(); + } + + return true; + } + + @Override + public void onClick(DialogInterface dialog, int which) { + if( which == Dialog.BUTTON_POSITIVE){ + mExtapp.clearAllApiApps(); + setClearApiSummary(); + } + } + + + +}
\ No newline at end of file diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/InlineFileTab.java b/main/src/main/java/de/blinkt/openvpn/fragments/InlineFileTab.java new file mode 100644 index 00000000..bea22442 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/fragments/InlineFileTab.java @@ -0,0 +1,66 @@ +package de.blinkt.openvpn.fragments; + +import android.app.Fragment; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.EditText; +import de.blinkt.openvpn.activities.FileSelect; +import de.blinkt.openvpn.R; + +public class InlineFileTab extends Fragment +{ + + private static final int MENU_SAVE = 0; + private EditText mInlineData; + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + mInlineData.setText(((FileSelect)getActivity()).getInlineData()); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) + { + + View v = inflater.inflate(R.layout.file_dialog_inline, container, false); + mInlineData =(EditText) v.findViewById(R.id.inlineFileData); + return v; + } + + public void setData(String data) { + if(mInlineData!=null) + mInlineData.setText(data); + + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setHasOptionsMenu(true); + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + menu.add(0, MENU_SAVE, 0, "Use inline data") + .setIcon(android.R.drawable.ic_menu_save) + .setAlphabeticShortcut('u') + .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM + | MenuItem.SHOW_AS_ACTION_WITH_TEXT); + } + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if(item.getItemId()==MENU_SAVE){ + ((FileSelect)getActivity()).saveInlineData(null, mInlineData.getText().toString()); + return true; + } + return super.onOptionsItemSelected(item); + } + +}
\ No newline at end of file diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java b/main/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java new file mode 100644 index 00000000..8530be34 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/fragments/LogFragment.java @@ -0,0 +1,668 @@ +package de.blinkt.openvpn.fragments; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ObjectAnimator; +import android.app.*; +import android.content.*; +import android.database.DataSetObserver; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.os.Handler; +import android.os.Handler.Callback; +import android.os.IBinder; +import android.os.Message; +import android.text.SpannableString; +import android.text.format.DateFormat; +import android.text.style.ImageSpan; +import android.view.*; +import android.widget.*; +import android.widget.AdapterView.OnItemLongClickListener; +import de.blinkt.openvpn.*; +import de.blinkt.openvpn.activities.DisconnectVPN; +import de.blinkt.openvpn.activities.MainActivity; +import de.blinkt.openvpn.activities.VPNPreferences; +import de.blinkt.openvpn.core.OpenVPNManagement; +import de.blinkt.openvpn.core.VpnStatus; +import de.blinkt.openvpn.core.VpnStatus.ConnectionStatus; +import de.blinkt.openvpn.core.VpnStatus.LogItem; +import de.blinkt.openvpn.core.VpnStatus.LogListener; +import de.blinkt.openvpn.core.VpnStatus.StateListener; +import de.blinkt.openvpn.core.OpenVpnService; +import de.blinkt.openvpn.core.OpenVpnService.LocalBinder; +import de.blinkt.openvpn.core.ProfileManager; +import org.jetbrains.annotations.Nullable; + +import java.text.SimpleDateFormat; +import java.util.Collections; +import java.util.Date; +import java.util.Locale; +import java.util.Vector; + +import static de.blinkt.openvpn.core.OpenVpnService.humanReadableByteCount; + +public class LogFragment extends ListFragment implements StateListener, SeekBar.OnSeekBarChangeListener, RadioGroup.OnCheckedChangeListener, VpnStatus.ByteCountListener { + private static final String LOGTIMEFORMAT = "logtimeformat"; + private static final int START_VPN_CONFIG = 0; + private static final String VERBOSITYLEVEL = "verbositylevel"; + protected OpenVpnService mService; + private ServiceConnection mConnection = new ServiceConnection() { + + + @Override + public void onServiceConnected(ComponentName className, + IBinder service) { + // We've bound to LocalService, cast the IBinder and get LocalService instance + LocalBinder binder = (LocalBinder) service; + mService = binder.getService(); + } + + @Override + public void onServiceDisconnected(ComponentName arg0) { + mService =null; + } + + }; + + private SeekBar mLogLevelSlider; + private LinearLayout mOptionsLayout; + private RadioGroup mTimeRadioGroup; + private TextView mUpStatus; + private TextView mDownStatus; + private TextView mConnectStatus; + private boolean mShowOptionsLayout; + + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + ladapter.setLogLevel(progress+1); + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + } + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + } + + @Override + public void onCheckedChanged(RadioGroup group, int checkedId) { + switch (checkedId) { + case R.id.radioISO: + ladapter.setTimeFormat(LogWindowListAdapter.TIME_FORMAT_ISO); + break; + case R.id.radioNone: + ladapter.setTimeFormat(LogWindowListAdapter.TIME_FORMAT_NONE); + break; + case R.id.radioShort: + ladapter.setTimeFormat(LogWindowListAdapter.TIME_FORMAT_SHORT); + break; + + } + } + + @Override + public void updateByteCount(long in, long out, long diffIn, long diffOut) { + //%2$s/s %1$s - ↑%4$s/s %3$s + final String down = String.format("%2$s/s %1$s", humanReadableByteCount(in, false), humanReadableByteCount(diffIn / OpenVPNManagement.mBytecountInterval, true)); + final String up = String.format("%2$s/s %1$s", humanReadableByteCount(out, false), humanReadableByteCount(diffOut / OpenVPNManagement.mBytecountInterval, true)); + + if (mUpStatus != null && mDownStatus != null) { + if (getActivity() != null) { + getActivity().runOnUiThread(new Runnable() { + @Override + public void run() { + mUpStatus.setText(up); + mDownStatus.setText(down); + } + }); + } + } + + } + + + class LogWindowListAdapter implements ListAdapter, LogListener, Callback { + + private static final int MESSAGE_NEWLOG = 0; + + private static final int MESSAGE_CLEARLOG = 1; + + private static final int MESSAGE_NEWTS = 2; + private static final int MESSAGE_NEWLOGLEVEL = 3; + + public static final int TIME_FORMAT_NONE = 0; + public static final int TIME_FORMAT_SHORT = 1; + public static final int TIME_FORMAT_ISO = 2; + private static final int MAX_STORED_LOG_ENTRIES = 1000; + + private Vector<LogItem> allEntries=new Vector<LogItem>(); + + private Vector<LogItem> currentLevelEntries=new Vector<LogItem>(); + + private Handler mHandler; + + private Vector<DataSetObserver> observers=new Vector<DataSetObserver>(); + + private int mTimeFormat=0; + private int mLogLevel=3; + + + public LogWindowListAdapter() { + initLogBuffer(); + if (mHandler == null) { + mHandler = new Handler(this); + } + + VpnStatus.addLogListener(this); + } + + + + private void initLogBuffer() { + allEntries.clear(); + Collections.addAll(allEntries, VpnStatus.getlogbuffer()); + initCurrentMessages(); + } + + String getLogStr() { + String str = ""; + for(LogItem entry:allEntries) { + str+=getTime(entry, TIME_FORMAT_ISO) + entry.getString(getActivity()) + '\n'; + } + return str; + } + + + private void shareLog() { + Intent shareIntent = new Intent(Intent.ACTION_SEND); + shareIntent.putExtra(Intent.EXTRA_TEXT, getLogStr()); + shareIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.ics_openvpn_log_file)); + shareIntent.setType("text/plain"); + startActivity(Intent.createChooser(shareIntent, "Send Logfile")); + } + + @Override + public void registerDataSetObserver(DataSetObserver observer) { + observers.add(observer); + + } + + @Override + public void unregisterDataSetObserver(DataSetObserver observer) { + observers.remove(observer); + } + + @Override + public int getCount() { + return currentLevelEntries.size(); + } + + @Override + public Object getItem(int position) { + return currentLevelEntries.get(position); + } + + @Override + public long getItemId(int position) { + return ((Object)currentLevelEntries.get(position)).hashCode(); + } + + @Override + public boolean hasStableIds() { + return true; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + TextView v; + if(convertView==null) + v = new TextView(getActivity()); + else + v = (TextView) convertView; + + LogItem le = currentLevelEntries.get(position); + String msg = le.getString(getActivity()); + String time = getTime(le, mTimeFormat); + msg = time + msg; + + int spanStart = time.length(); + + SpannableString t = new SpannableString(msg); + + //t.setSpan(getSpanImage(le,(int)v.getTextSize()),spanStart,spanStart+1, Spanned.SPAN_INCLUSIVE_INCLUSIVE); + v.setText(t); + return v; + } + + private String getTime(LogItem le, int time) { + if (time != TIME_FORMAT_NONE) { + Date d = new Date(le.getLogtime()); + java.text.DateFormat timeformat; + if (time== TIME_FORMAT_ISO) + timeformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()); + else + timeformat = DateFormat.getTimeFormat(getActivity()); + + return timeformat.format(d) + " "; + + } else { + return ""; + } + + } + + private ImageSpan getSpanImage(LogItem li, int imageSize) { + int imageRes = android.R.drawable.ic_menu_call; + + switch (li.getLogLevel()) { + case ERROR: + imageRes = android.R.drawable.ic_notification_clear_all; + break; + case INFO: + imageRes = android.R.drawable.ic_menu_compass; + break; + case VERBOSE: + imageRes = android.R.drawable.ic_menu_info_details; + break; + case WARNING: + imageRes = android.R.drawable.ic_menu_camera; + break; + } + + Drawable d = getResources().getDrawable(imageRes); + + + //d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight()); + d.setBounds(0, 0, imageSize, imageSize); + ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BOTTOM); + + return span; + } + + @Override + public int getItemViewType(int position) { + return 0; + } + + @Override + public int getViewTypeCount() { + return 1; + } + + @Override + public boolean isEmpty() { + return currentLevelEntries.isEmpty(); + + } + + @Override + public boolean areAllItemsEnabled() { + return true; + } + + @Override + public boolean isEnabled(int position) { + return true; + } + + @Override + public void newLog(LogItem logMessage) { + Message msg = Message.obtain(); + assert (msg!=null); + msg.what=MESSAGE_NEWLOG; + Bundle bundle=new Bundle(); + bundle.putParcelable("logmessage", logMessage); + msg.setData(bundle); + mHandler.sendMessage(msg); + } + + @Override + public boolean handleMessage(Message msg) { + // We have been called + if(msg.what==MESSAGE_NEWLOG) { + + LogItem logMessage = msg.getData().getParcelable("logmessage"); + if(addLogMessage(logMessage)) + for (DataSetObserver observer : observers) { + observer.onChanged(); + } + } else if (msg.what == MESSAGE_CLEARLOG) { + for (DataSetObserver observer : observers) { + observer.onInvalidated(); + } + initLogBuffer(); + } else if (msg.what == MESSAGE_NEWTS) { + for (DataSetObserver observer : observers) { + observer.onInvalidated(); + } + } else if (msg.what == MESSAGE_NEWLOGLEVEL) { + initCurrentMessages(); + + for (DataSetObserver observer: observers) { + observer.onChanged(); + } + + } + + return true; + } + + private void initCurrentMessages() { + currentLevelEntries.clear(); + for(LogItem li: allEntries) { + if (li.getVerbosityLevel() <= mLogLevel || + mLogLevel == VpnProfile.MAXLOGLEVEL) + currentLevelEntries.add(li); + } + } + + /** + * + * @param logmessage + * @return True if the current entries have changed + */ + private boolean addLogMessage(LogItem logmessage) { + allEntries.add(logmessage); + + if (allEntries.size() > MAX_STORED_LOG_ENTRIES) { + Vector<LogItem> oldAllEntries = allEntries; + allEntries = new Vector<LogItem>(allEntries.size()); + for (int i=50;i<oldAllEntries.size();i++) { + allEntries.add(oldAllEntries.elementAt(i)); + } + initCurrentMessages(); + return true; + } else { + if (logmessage.getVerbosityLevel() <= mLogLevel) { + currentLevelEntries.add(logmessage); + return true; + } else { + return false; + } + } + } + + void clearLog() { + // Actually is probably called from GUI Thread as result of the user + // pressing a button. But better safe than sorry + VpnStatus.clearLog(); + VpnStatus.logInfo(R.string.logCleared); + mHandler.sendEmptyMessage(MESSAGE_CLEARLOG); + } + + + + public void setTimeFormat(int newTimeFormat) { + mTimeFormat= newTimeFormat; + mHandler.sendEmptyMessage(MESSAGE_NEWTS); + } + + public void setLogLevel(int logLevel) { + mLogLevel = logLevel; + mHandler.sendEmptyMessage(MESSAGE_NEWLOGLEVEL); + } + + } + + + + private LogWindowListAdapter ladapter; + private TextView mSpeedView; + + + + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if(item.getItemId()==R.id.clearlog) { + ladapter.clearLog(); + return true; + } else if(item.getItemId()==R.id.cancel){ + Intent intent = new Intent(getActivity(),DisconnectVPN.class); + startActivity(intent); + return true; + } else if(item.getItemId()==R.id.send) { + ladapter.shareLog(); + } else if(item.getItemId()==R.id.edit_vpn) { + VpnProfile lastConnectedprofile = ProfileManager.getLastConnectedVpn(); + + if(lastConnectedprofile!=null) { + Intent vprefintent = new Intent(getActivity(),VPNPreferences.class) + .putExtra(VpnProfile.EXTRA_PROFILEUUID,lastConnectedprofile.getUUIDString()); + startActivityForResult(vprefintent,START_VPN_CONFIG); + } else { + Toast.makeText(getActivity(), R.string.log_no_last_vpn, Toast.LENGTH_LONG).show(); + } + } else if(item.getItemId() == R.id.toggle_time) { + showHideOptionsPanel(); + } else if(item.getItemId() == android.R.id.home) { + // This is called when the Home (Up) button is pressed + // in the Action Bar. + Intent parentActivityIntent = new Intent(getActivity(), MainActivity.class); + parentActivityIntent.addFlags( + Intent.FLAG_ACTIVITY_CLEAR_TOP | + Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(parentActivityIntent); + getActivity().finish(); + return true; + + } + return super.onOptionsItemSelected(item); + + } + + private void showHideOptionsPanel() { + boolean optionsVisible = (mOptionsLayout.getVisibility() != View.GONE); + + ObjectAnimator anim; + if (optionsVisible) { + anim = ObjectAnimator.ofFloat(mOptionsLayout,"alpha",1.0f, 0f); + anim.addListener(collapseListener); + + } else { + mOptionsLayout.setVisibility(View.VISIBLE); + anim = ObjectAnimator.ofFloat(mOptionsLayout,"alpha", 0f, 1.0f); + //anim = new TranslateAnimation(0.0f, 0.0f, mOptionsLayout.getHeight(), 0.0f); + + } + + //anim.setInterpolator(new AccelerateInterpolator(1.0f)); + //anim.setDuration(300); + //mOptionsLayout.startAnimation(anim); + anim.start(); + + } + + AnimatorListenerAdapter collapseListener = new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animator) { + mOptionsLayout.setVisibility(View.GONE); + } + + }; + + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + inflater.inflate(R.menu.logmenu, menu); + if (getResources().getBoolean(R.bool.logSildersAlwaysVisible)) + menu.removeItem(R.id.toggle_time); + } + + + @Override + public void onResume() { + super.onResume(); + VpnStatus.addStateListener(this); + VpnStatus.addByteCountListener(this); + Intent intent = new Intent(getActivity(), OpenVpnService.class); + intent.setAction(OpenVpnService.START_SERVICE); + + getActivity().bindService(intent, mConnection, Context.BIND_AUTO_CREATE); + + + + } + + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + if (requestCode == START_VPN_CONFIG && resultCode== Activity.RESULT_OK) { + String configuredVPN = data.getStringExtra(VpnProfile.EXTRA_PROFILEUUID); + + final VpnProfile profile = ProfileManager.get(getActivity(),configuredVPN); + ProfileManager.getInstance(getActivity()).saveProfile(getActivity(), profile); + // Name could be modified, reset List adapter + + AlertDialog.Builder dialog = new AlertDialog.Builder(getActivity()); + dialog.setTitle(R.string.configuration_changed); + dialog.setMessage(R.string.restart_vpn_after_change); + + + dialog.setPositiveButton(R.string.restart, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Intent intent = new Intent(getActivity(), LaunchVPN.class); + intent.putExtra(LaunchVPN.EXTRA_KEY, profile.getUUIDString()); + intent.setAction(Intent.ACTION_MAIN); + startActivity(intent); + } + + + }); + dialog.setNegativeButton(R.string.ignore, null); + dialog.create().show(); + } + super.onActivityResult(requestCode, resultCode, data); + } + + @Override + public void onStop() { + super.onStop(); + VpnStatus.removeStateListener(this); + VpnStatus.removeByteCountListener(this); + + if(mService!=null) + getActivity().unbindService(mConnection); + getActivity().getPreferences(0).edit().putInt(LOGTIMEFORMAT, ladapter.mTimeFormat) + .putInt(VERBOSITYLEVEL, ladapter.mLogLevel).apply(); + + } + + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + ListView lv = getListView(); + + lv.setOnItemLongClickListener(new OnItemLongClickListener() { + + @Override + public boolean onItemLongClick(AdapterView<?> parent, View view, + int position, long id) { + ClipboardManager clipboard = (ClipboardManager) + getActivity().getSystemService(Context.CLIPBOARD_SERVICE); + ClipData clip = ClipData.newPlainText("Log Entry",((TextView) view).getText()); + clipboard.setPrimaryClip(clip); + Toast.makeText(getActivity(), R.string.copied_entry, Toast.LENGTH_SHORT).show(); + return true; + } + }); + } + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View v = inflater.inflate(R.layout.log_fragment, container, false); + + setHasOptionsMenu(true); + + ladapter = new LogWindowListAdapter(); + ladapter.mTimeFormat = getActivity().getPreferences(0).getInt(LOGTIMEFORMAT, 0); + int logLevel = getActivity().getPreferences(0).getInt(VERBOSITYLEVEL, 0); + ladapter.setLogLevel(logLevel); + + setListAdapter(ladapter); + + mTimeRadioGroup = (RadioGroup) v.findViewById(R.id.timeFormatRadioGroup); + mTimeRadioGroup.setOnCheckedChangeListener(this); + + if(ladapter.mTimeFormat== LogWindowListAdapter.TIME_FORMAT_ISO) { + mTimeRadioGroup.check(R.id.radioISO); + } else if (ladapter.mTimeFormat == LogWindowListAdapter.TIME_FORMAT_NONE) { + mTimeRadioGroup.check(R.id.radioNone); + } else if (ladapter.mTimeFormat == LogWindowListAdapter.TIME_FORMAT_SHORT) { + mTimeRadioGroup.check(R.id.radioShort); + } + + mSpeedView = (TextView) v.findViewById(R.id.speed); + + mOptionsLayout = (LinearLayout) v.findViewById(R.id.logOptionsLayout); + mLogLevelSlider = (SeekBar) v.findViewById(R.id.LogLevelSlider); + mLogLevelSlider.setMax(VpnProfile.MAXLOGLEVEL-1); + mLogLevelSlider.setProgress(logLevel-1); + + mLogLevelSlider.setOnSeekBarChangeListener(this); + + if(getResources().getBoolean(R.bool.logSildersAlwaysVisible)) + mOptionsLayout.setVisibility(View.VISIBLE); + + mUpStatus = (TextView) v.findViewById(R.id.speedUp); + mDownStatus = (TextView) v.findViewById(R.id.speedDown); + mConnectStatus = (TextView) v.findViewById(R.id.speedStatus); + if (mShowOptionsLayout) + mOptionsLayout.setVisibility(View.VISIBLE); + return v; + } + + @Override + public void onAttach(Activity activity) { + super.onAttach(activity); + if(getResources().getBoolean(R.bool.logSildersAlwaysVisible)) { + mShowOptionsLayout=true; + if (mOptionsLayout!= null) + mOptionsLayout.setVisibility(View.VISIBLE); + } + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + //getActionBar().setDisplayHomeAsUpEnabled(true); + + } + + + @Override + public void updateState(final String status, final String logMessage, final int resId, final ConnectionStatus level) { + if (isAdded()) { + getActivity().runOnUiThread(new Runnable() { + + @Override + public void run() { + String prefix = getString(resId) + ":"; + if (status.equals("BYTECOUNT") || status.equals("NOPROCESS")) + prefix = ""; + if (resId == R.string.unknown_state) + prefix += status; + if (mSpeedView != null) + mSpeedView.setText(prefix + logMessage); + + if (mConnectStatus != null) + mConnectStatus.setText(getString(resId)); + } + }); + } + } + + + @Override + public void onDestroy() { + VpnStatus.removeLogListener(ladapter); + super.onDestroy(); + } + +} diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/OpenVpnPreferencesFragment.java b/main/src/main/java/de/blinkt/openvpn/fragments/OpenVpnPreferencesFragment.java new file mode 100644 index 00000000..f23a50db --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/fragments/OpenVpnPreferencesFragment.java @@ -0,0 +1,48 @@ +package de.blinkt.openvpn.fragments;
+
+import android.os.Bundle;
+import android.preference.PreferenceFragment;
+import de.blinkt.openvpn.R;
+import de.blinkt.openvpn.VpnProfile;
+import de.blinkt.openvpn.core.ProfileManager;
+
+public abstract class OpenVpnPreferencesFragment extends PreferenceFragment {
+
+ protected VpnProfile mProfile;
+
+ protected abstract void loadSettings();
+ protected abstract void saveSettings();
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ String profileUUID = getArguments().getString(getActivity().getPackageName() + ".profileUUID");
+ mProfile = ProfileManager.get(getActivity(),profileUUID);
+ getActivity().setTitle(getString(R.string.edit_profile_title, mProfile.getName()));
+
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ saveSettings();
+ }
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ if(savedInstanceState!=null) {
+ String profileUUID=savedInstanceState.getString(VpnProfile.EXTRA_PROFILEUUID);
+ mProfile = ProfileManager.get(getActivity(),profileUUID);
+ loadSettings();
+ }
+ }
+
+ @Override
+ public void onSaveInstanceState (Bundle outState) {
+ super.onSaveInstanceState(outState);
+ saveSettings();
+ outState.putString(VpnProfile.EXTRA_PROFILEUUID, mProfile.getUUIDString());
+ }
+}
diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/SendDumpFragment.java b/main/src/main/java/de/blinkt/openvpn/fragments/SendDumpFragment.java new file mode 100644 index 00000000..d43f6427 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/fragments/SendDumpFragment.java @@ -0,0 +1,94 @@ +package de.blinkt.openvpn.fragments; + +import java.io.File; +import java.util.ArrayList; + +import android.app.Fragment; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager.NameNotFoundException; +import android.net.Uri; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.ViewGroup; +import de.blinkt.openvpn.R; +import de.blinkt.openvpn.core.VpnStatus; + +public class SendDumpFragment extends Fragment { + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + + View v = inflater.inflate(R.layout.fragment_senddump, container, false); + v.findViewById(R.id.senddump).setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + emailMiniDumps(); + } + }); + return v; + } + + public void emailMiniDumps() + { + //need to "send multiple" to get more than one attachment + final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND_MULTIPLE); + emailIntent.setType("*/*"); + emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, + new String[]{"Arne Schwabe <arne@rfc2549.org>"}); + + String version; + String name="ics-openvpn"; + try { + PackageInfo packageinfo = getActivity().getPackageManager().getPackageInfo(getActivity().getPackageName(), 0); + version = packageinfo.versionName; + name = packageinfo.applicationInfo.name; + } catch (NameNotFoundException e) { + version = "error fetching version"; + } + + + emailIntent.putExtra(Intent.EXTRA_SUBJECT, String.format("%s %s Minidump",name,version)); + + emailIntent.putExtra(Intent.EXTRA_TEXT, "Please describe the issue you have experienced"); + + ArrayList<Uri> uris = new ArrayList<Uri>(); + + File ldump = getLastestDump(getActivity()); + if(ldump==null) { + VpnStatus.logError("No Minidump found!"); + } + + uris.add(Uri.parse("content://de.blinkt.openvpn.FileProvider/" + ldump.getName())); + uris.add(Uri.parse("content://de.blinkt.openvpn.FileProvider/" + ldump.getName() + ".log")); + + emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + emailIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris); + startActivity(emailIntent); + } + + static public File getLastestDump(Context c) { + long newestDumpTime=0; + File newestDumpFile=null; + + for(File f:c.getCacheDir().listFiles()) { + if(!f.getName().endsWith(".dmp")) + continue; + + if (newestDumpTime < f.lastModified()) { + newestDumpTime = f.lastModified(); + newestDumpFile=f; + } + } + // Ignore old dumps + //if(System.currentTimeMillis() - 48 * 60 * 1000 > newestDumpTime ) + //return null; + + return newestDumpFile; + } +} diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Authentication.java b/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Authentication.java new file mode 100644 index 00000000..236d7947 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Authentication.java @@ -0,0 +1,212 @@ +package de.blinkt.openvpn.fragments; + +import android.app.Activity; +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.preference.CheckBoxPreference; +import android.preference.EditTextPreference; +import android.preference.ListPreference; +import android.preference.Preference; +import android.preference.Preference.OnPreferenceChangeListener; +import android.preference.Preference.OnPreferenceClickListener; +import android.preference.SwitchPreference; +import android.util.Pair; +import de.blinkt.openvpn.activities.FileSelect; +import de.blinkt.openvpn.R; +import de.blinkt.openvpn.core.VpnStatus; +import de.blinkt.openvpn.views.RemoteCNPreference; +import de.blinkt.openvpn.VpnProfile; + +import java.io.IOException; + + +public class Settings_Authentication extends OpenVpnPreferencesFragment implements OnPreferenceChangeListener, OnPreferenceClickListener { + private static final int SELECT_TLS_FILE = 23223232; + private static final int SELECT_TLS_FILE_KITKAT = SELECT_TLS_FILE +1; + private CheckBoxPreference mExpectTLSCert; + private CheckBoxPreference mCheckRemoteCN; + private RemoteCNPreference mRemoteCN; + private ListPreference mTLSAuthDirection; + private Preference mTLSAuthFile; + private SwitchPreference mUseTLSAuth; + private EditTextPreference mCipher; + private String mTlsAuthFileData; + private EditTextPreference mAuth; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Load the preferences from an XML resource + addPreferencesFromResource(R.xml.vpn_authentification); + + mExpectTLSCert = (CheckBoxPreference) findPreference("remoteServerTLS"); + mCheckRemoteCN = (CheckBoxPreference) findPreference("checkRemoteCN"); + mRemoteCN = (RemoteCNPreference) findPreference("remotecn"); + mRemoteCN.setOnPreferenceChangeListener(this); + + mUseTLSAuth = (SwitchPreference) findPreference("useTLSAuth" ); + mTLSAuthFile = findPreference("tlsAuthFile"); + mTLSAuthDirection = (ListPreference) findPreference("tls_direction"); + + + mTLSAuthFile.setOnPreferenceClickListener(this); + + mCipher =(EditTextPreference) findPreference("cipher"); + mCipher.setOnPreferenceChangeListener(this); + + mAuth =(EditTextPreference) findPreference("auth"); + mAuth.setOnPreferenceChangeListener(this); + + loadSettings(); + + } + + @Override + protected void loadSettings() { + + mExpectTLSCert.setChecked(mProfile.mExpectTLSCert); + mCheckRemoteCN.setChecked(mProfile.mCheckRemoteCN); + mRemoteCN.setDN(mProfile.mRemoteCN); + mRemoteCN.setAuthType(mProfile.mX509AuthType); + onPreferenceChange(mRemoteCN, + new Pair<Integer, String>(mProfile.mX509AuthType, mProfile.mRemoteCN)); + + mUseTLSAuth.setChecked(mProfile.mUseTLSAuth); + mTlsAuthFileData= mProfile.mTLSAuthFilename; + setTlsAuthSummary(mTlsAuthFileData); + mTLSAuthDirection.setValue(mProfile.mTLSAuthDirection); + mCipher.setText(mProfile.mCipher); + onPreferenceChange(mCipher, mProfile.mCipher); + mAuth.setText(mProfile.mAuth); + onPreferenceChange(mAuth, mProfile.mAuth); + + if (mProfile.mAuthenticationType == VpnProfile.TYPE_STATICKEYS) { + mExpectTLSCert.setEnabled(false); + mCheckRemoteCN.setEnabled(false); + mUseTLSAuth.setChecked(true); + } else { + mExpectTLSCert.setEnabled(true); + mCheckRemoteCN.setEnabled(true); + + } + } + + @Override + protected void saveSettings() { + mProfile.mExpectTLSCert=mExpectTLSCert.isChecked(); + mProfile.mCheckRemoteCN=mCheckRemoteCN.isChecked(); + mProfile.mRemoteCN=mRemoteCN.getCNText(); + mProfile.mX509AuthType=mRemoteCN.getAuthtype(); + + mProfile.mUseTLSAuth = mUseTLSAuth.isChecked(); + mProfile.mTLSAuthFilename = mTlsAuthFileData; + + if(mTLSAuthDirection.getValue()==null) + mProfile.mTLSAuthDirection=null; + else + mProfile.mTLSAuthDirection = mTLSAuthDirection.getValue(); + + if(mCipher.getText()==null) + mProfile.mCipher=null; + else + mProfile.mCipher = mCipher.getText(); + + if(mAuth.getText()==null) + mProfile.mAuth = null; + else + mProfile.mAuth = mAuth.getText(); + + } + + + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + if(preference==mRemoteCN) { + @SuppressWarnings("unchecked") + int authtype = ((Pair<Integer, String>) newValue).first; + @SuppressWarnings("unchecked") + String dn = ((Pair<Integer, String>) newValue).second; + + if ("".equals(dn)) + preference.setSummary(getX509String(VpnProfile.X509_VERIFY_TLSREMOTE_RDN, mProfile.mServerName)); + else + preference.setSummary(getX509String(authtype,dn)); + + } else if (preference == mCipher || preference == mAuth) { + preference.setSummary((CharSequence) newValue); + } + return true; + } + private CharSequence getX509String(int authtype, String dn) { + String ret =""; + switch (authtype) { + case VpnProfile.X509_VERIFY_TLSREMOTE: + case VpnProfile.X509_VERIFY_TLSREMOTE_COMPAT_NOREMAPPING: + ret+="tls-remote "; + break; + + case VpnProfile.X509_VERIFY_TLSREMOTE_DN: + ret="dn: "; + break; + + case VpnProfile.X509_VERIFY_TLSREMOTE_RDN: + ret="rdn: "; + break; + + case VpnProfile.X509_VERIFY_TLSREMOTE_RDN_PREFIX: + ret="rdn prefix: "; + break; + } + return ret + dn; + } + + void startFileDialog() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + Intent startFC = Utils.getFilePickerIntent (Utils.FileType.TLS_AUTH_FILE); + startActivityForResult(startFC, SELECT_TLS_FILE_KITKAT); + } else { + Intent startFC = new Intent(getActivity(), FileSelect.class); + startFC.putExtra(FileSelect.START_DATA, mTlsAuthFileData); + startFC.putExtra(FileSelect.WINDOW_TITLE, R.string.tls_auth_file); + startActivityForResult(startFC, SELECT_TLS_FILE); + } + } + + @Override + public boolean onPreferenceClick(Preference preference) { + startFileDialog(); + return true; + + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if(requestCode==SELECT_TLS_FILE && resultCode == Activity.RESULT_OK){ + String result = data.getStringExtra(FileSelect.RESULT_DATA); + mTlsAuthFileData=result; + setTlsAuthSummary(result); + } else if (requestCode == SELECT_TLS_FILE_KITKAT && resultCode == Activity.RESULT_OK) { + try { + mTlsAuthFileData= Utils.getFilePickerResult(Utils.FileType.TLS_AUTH_FILE,data,getActivity()); + setTlsAuthSummary(mTlsAuthFileData); + } catch (IOException e) { + VpnStatus.logException(e); + } + } + } + + private void setTlsAuthSummary(String result) { + if(result==null) + result = getString(R.string.no_certificate); + if(result.startsWith(VpnProfile.INLINE_TAG)) + mTLSAuthFile.setSummary(R.string.inline_file_data); + else if (result.startsWith(VpnProfile.DISPLAYNAME_TAG)) + mExpectTLSCert.setSummary(getString(R.string.imported_from_file, VpnProfile.getDisplayName(result))); + else + mTLSAuthFile.setSummary(result); + } +}
\ No newline at end of file diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Basic.java b/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Basic.java new file mode 100644 index 00000000..4145c65f --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Basic.java @@ -0,0 +1,360 @@ +package de.blinkt.openvpn.fragments; + +import android.annotation.TargetApi; +import android.app.Activity; +import android.app.AlertDialog; +import android.app.AlertDialog.Builder; +import android.app.Fragment; +import android.content.ActivityNotFoundException; +import android.content.Intent; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.os.Handler.Callback; +import android.os.Message; +import android.security.KeyChain; +import android.security.KeyChainAliasCallback; +import android.security.KeyChainException; +import android.util.SparseArray; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemSelectedListener; +import android.widget.CheckBox; +import android.widget.EditText; +import android.widget.Spinner; +import android.widget.TextView; +import android.widget.ToggleButton; +import de.blinkt.openvpn.views.FileSelectLayout; +import de.blinkt.openvpn.R; +import de.blinkt.openvpn.VpnProfile; +import de.blinkt.openvpn.R.id; +import de.blinkt.openvpn.core.ProfileManager; +import de.blinkt.openvpn.core.X509Utils; + +import java.security.cert.X509Certificate; + +public class Settings_Basic extends Fragment implements View.OnClickListener, OnItemSelectedListener, Callback, FileSelectLayout.FileSelectCallback { + private static final int CHOOSE_FILE_OFFSET = 1000; + private static final int UPDATE_ALIAS = 20; + + private TextView mServerAddress; + private TextView mServerPort; + private FileSelectLayout mClientCert; + private FileSelectLayout mCaCert; + private FileSelectLayout mClientKey; + private TextView mAliasName; + private TextView mAliasCertificate; + private CheckBox mUseLzo; + private ToggleButton mTcpUdp; + private Spinner mType; + private FileSelectLayout mpkcs12; + private TextView mPKCS12Password; + private Handler mHandler; + private EditText mUserName; + private EditText mPassword; + private View mView; + private VpnProfile mProfile; + private EditText mProfileName; + private EditText mKeyPassword; + + private SparseArray<FileSelectLayout> fileselects = new SparseArray<FileSelectLayout>(); + + + + private void addFileSelectLayout (FileSelectLayout fsl, Utils.FileType type) { + int i = fileselects.size() + CHOOSE_FILE_OFFSET; + fileselects.put(i, fsl); + fsl.setCaller(this, i, type); + } + + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + String profileUuid = getArguments().getString(getActivity().getPackageName() + ".profileUUID"); + mProfile=ProfileManager.get(getActivity(),profileUuid); + getActivity().setTitle(getString(R.string.edit_profile_title, mProfile.getName())); + } + + + private void setKeystoreCertficate() + { + new Thread() { + public void run() { + String certstr=""; + try { + X509Certificate cert = KeyChain.getCertificateChain(getActivity(), mProfile.mAlias)[0]; + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { + { + if (isInHardwareKeystore()) + certstr+=getString(R.string.hwkeychain); + } + } + + certstr+=X509Utils.getCertificateFriendlyName(cert); + } catch (Exception e) { + certstr="Could not get certificate from Keystore: " +e.getLocalizedMessage(); + } + + final String certStringCopy=certstr; + getActivity().runOnUiThread(new Runnable() { + + @Override + public void run() { + mAliasCertificate.setText(certStringCopy); + } + }); + + } + }.start(); + } + + @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) + private boolean isInHardwareKeystore() throws KeyChainException, InterruptedException { + String algorithm = KeyChain.getPrivateKey(getActivity(), mProfile.mAlias).getAlgorithm(); + return KeyChain.isBoundKeyAlgorithm(algorithm); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + + + mView = inflater.inflate(R.layout.basic_settings,container,false); + + mProfileName = (EditText) mView.findViewById(R.id.profilename); + mServerAddress = (TextView) mView.findViewById(R.id.address); + mServerPort = (TextView) mView.findViewById(R.id.port); + mClientCert = (FileSelectLayout) mView.findViewById(R.id.certselect); + mClientKey = (FileSelectLayout) mView.findViewById(R.id.keyselect); + mCaCert = (FileSelectLayout) mView.findViewById(R.id.caselect); + mpkcs12 = (FileSelectLayout) mView.findViewById(R.id.pkcs12select); + mUseLzo = (CheckBox) mView.findViewById(R.id.lzo); + mTcpUdp = (ToggleButton) mView.findViewById(id.tcpudp); + mType = (Spinner) mView.findViewById(R.id.type); + mPKCS12Password = (TextView) mView.findViewById(R.id.pkcs12password); + mAliasName = (TextView) mView.findViewById(R.id.aliasname); + mAliasCertificate = (TextView) mView.findViewById(id.alias_certificate); + + mUserName = (EditText) mView.findViewById(R.id.auth_username); + mPassword = (EditText) mView.findViewById(R.id.auth_password); + mKeyPassword = (EditText) mView.findViewById(R.id.key_password); + + addFileSelectLayout(mCaCert, Utils.FileType.CA_CERTIFICATE); + addFileSelectLayout(mClientCert, Utils.FileType.CLIENT_CERTIFICATE); + addFileSelectLayout(mClientKey, Utils.FileType.KEYFILE); + addFileSelectLayout(mpkcs12, Utils.FileType.PKCS12); + mCaCert.setShowClear(); + + mType.setOnItemSelectedListener(this); + + mView.findViewById(R.id.select_keystore_button).setOnClickListener(this); + + + if (mHandler == null) { + mHandler = new Handler(this); + } + + return mView; + } + + + @Override + public void onStart() { + super.onStart(); + String profileUuid =getArguments().getString(getActivity().getPackageName() + ".profileUUID"); + mProfile=ProfileManager.get(getActivity(),profileUuid); + loadPreferences(); + + } + + @Override + public void onActivityResult(int request, int result, Intent data) { + if (result == Activity.RESULT_OK && request >= CHOOSE_FILE_OFFSET) { + + FileSelectLayout fsl = fileselects.get(request); + fsl.parseResponse(data, getActivity()); + + savePreferences(); + + // Private key files may result in showing/hiding the private key password dialog + if(fsl==mClientKey) { + changeType(mType.getSelectedItemPosition()); + } + } + + } + + + @Override + public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { + if (parent == mType) { + changeType(position); + } + } + @Override + public void onPause() { + super.onPause(); + savePreferences(); + } + + + + private void changeType(int type){ + // hide everything + mView.findViewById(R.id.pkcs12).setVisibility(View.GONE); + mView.findViewById(R.id.certs).setVisibility(View.GONE); + mView.findViewById(R.id.statickeys).setVisibility(View.GONE); + mView.findViewById(R.id.keystore).setVisibility(View.GONE); + mView.findViewById(R.id.cacert).setVisibility(View.GONE); + mView.findViewById(R.id.userpassword).setVisibility(View.GONE); + mView.findViewById(R.id.key_password_layout).setVisibility(View.GONE); + + // Fall through are by design + switch(type) { + case VpnProfile.TYPE_USERPASS_CERTIFICATES: + mView.findViewById(R.id.userpassword).setVisibility(View.VISIBLE); + case VpnProfile.TYPE_CERTIFICATES: + mView.findViewById(R.id.certs).setVisibility(View.VISIBLE); + mView.findViewById(R.id.cacert).setVisibility(View.VISIBLE); + if(mProfile.requireTLSKeyPassword()) + mView.findViewById(R.id.key_password_layout).setVisibility(View.VISIBLE); + break; + + case VpnProfile.TYPE_USERPASS_PKCS12: + mView.findViewById(R.id.userpassword).setVisibility(View.VISIBLE); + case VpnProfile.TYPE_PKCS12: + mView.findViewById(R.id.pkcs12).setVisibility(View.VISIBLE); + break; + + case VpnProfile.TYPE_STATICKEYS: + mView.findViewById(R.id.statickeys).setVisibility(View.VISIBLE); + break; + + case VpnProfile.TYPE_USERPASS_KEYSTORE: + mView.findViewById(R.id.userpassword).setVisibility(View.VISIBLE); + case VpnProfile.TYPE_KEYSTORE: + mView.findViewById(R.id.keystore).setVisibility(View.VISIBLE); + mView.findViewById(R.id.cacert).setVisibility(View.VISIBLE); + break; + + case VpnProfile.TYPE_USERPASS: + mView.findViewById(R.id.userpassword).setVisibility(View.VISIBLE); + mView.findViewById(R.id.cacert).setVisibility(View.VISIBLE); + break; + } + + + } + + private void loadPreferences() { + mProfileName.setText(mProfile.mName); + mClientCert.setData(mProfile.mClientCertFilename, getActivity()); + mClientKey.setData(mProfile.mClientKeyFilename, getActivity()); + mCaCert.setData(mProfile.mCaFilename, getActivity()); + + mUseLzo.setChecked(mProfile.mUseLzo); + mServerPort.setText(mProfile.mServerPort); + mServerAddress.setText(mProfile.mServerName); + mTcpUdp.setChecked(mProfile.mUseUdp); + mType.setSelection(mProfile.mAuthenticationType); + mpkcs12.setData(mProfile.mPKCS12Filename, getActivity()); + mPKCS12Password.setText(mProfile.mPKCS12Password); + mUserName.setText(mProfile.mUsername); + mPassword.setText(mProfile.mPassword); + mKeyPassword.setText(mProfile.mKeyPassword); + + setAlias(); + + } + + void savePreferences() { + + mProfile.mName = mProfileName.getText().toString(); + mProfile.mCaFilename = mCaCert.getData(); + mProfile.mClientCertFilename = mClientCert.getData(); + mProfile.mClientKeyFilename = mClientKey.getData(); + + mProfile.mUseLzo = mUseLzo.isChecked(); + mProfile.mServerPort =mServerPort.getText().toString(); + mProfile.mServerName = mServerAddress.getText().toString(); + mProfile.mUseUdp = mTcpUdp.isChecked(); + + mProfile.mAuthenticationType = mType.getSelectedItemPosition(); + mProfile.mPKCS12Filename = mpkcs12.getData(); + mProfile.mPKCS12Password = mPKCS12Password.getText().toString(); + + mProfile.mPassword = mPassword.getText().toString(); + mProfile.mUsername = mUserName.getText().toString(); + mProfile.mKeyPassword = mKeyPassword.getText().toString(); + + } + + + private void setAlias() { + if(mProfile.mAlias == null) { + mAliasName.setText(R.string.client_no_certificate); + mAliasCertificate.setText(""); + } else { + mAliasCertificate.setText("Loading certificate from Keystore..."); + mAliasName.setText(mProfile.mAlias); + setKeystoreCertficate(); + } + } + + public void showCertDialog () { + try { + KeyChain.choosePrivateKeyAlias(getActivity(), + new KeyChainAliasCallback() { + + public void alias(String alias) { + // Credential alias selected. Remember the alias selection for future use. + mProfile.mAlias=alias; + mHandler.sendEmptyMessage(UPDATE_ALIAS); + } + + + }, + new String[] {"RSA"}, // List of acceptable key types. null for any + null, // issuer, null for any + mProfile.mServerName, // host name of server requesting the cert, null if unavailable + -1, // port of server requesting the cert, -1 if unavailable + mProfile.mAlias); // alias to preselect, null if unavailable + } catch (ActivityNotFoundException anf) { + Builder ab = new AlertDialog.Builder(getActivity()); + ab.setTitle(R.string.broken_image_cert_title); + ab.setMessage(R.string.broken_image_cert); + ab.setPositiveButton(android.R.string.ok, null); + ab.show(); + } + } + + @Override + public void onClick(View v) { + if (v == mView.findViewById(R.id.select_keystore_button)) { + showCertDialog(); + } + } + + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + savePreferences(); + if(mProfile!=null) { + outState.putString(getActivity().getPackageName() + "profileUUID", mProfile.getUUID().toString()); + } + } + + @Override + public void onNothingSelected(AdapterView<?> parent) { + } + + + @Override + public boolean handleMessage(Message msg) { + setAlias(); + return true; + } + + +} diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/Settings_IP.java b/main/src/main/java/de/blinkt/openvpn/fragments/Settings_IP.java new file mode 100644 index 00000000..16e3a5c4 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/fragments/Settings_IP.java @@ -0,0 +1,130 @@ +package de.blinkt.openvpn.fragments; +import android.os.Bundle; +import android.preference.CheckBoxPreference; +import android.preference.EditTextPreference; +import android.preference.Preference; +import android.preference.Preference.OnPreferenceChangeListener; +import android.preference.PreferenceManager; +import android.preference.SwitchPreference; +import de.blinkt.openvpn.R; +import de.blinkt.openvpn.VpnProfile; + +public class Settings_IP extends OpenVpnPreferencesFragment implements OnPreferenceChangeListener { + private EditTextPreference mIPv4; + private EditTextPreference mIPv6; + private SwitchPreference mUsePull; + private CheckBoxPreference mOverrideDNS; + private EditTextPreference mSearchdomain; + private EditTextPreference mDNS1; + private EditTextPreference mDNS2; + private CheckBoxPreference mNobind; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + + // Make sure default values are applied. In a real app, you would + // want this in a shared function that is used to retrieve the + // SharedPreferences wherever they are needed. + PreferenceManager.setDefaultValues(getActivity(), + R.xml.vpn_ipsettings, false); + + // Load the preferences from an XML resource + addPreferencesFromResource(R.xml.vpn_ipsettings); + mIPv4 = (EditTextPreference) findPreference("ipv4_address"); + mIPv6 = (EditTextPreference) findPreference("ipv6_address"); + mUsePull = (SwitchPreference) findPreference("usePull"); + mOverrideDNS = (CheckBoxPreference) findPreference("overrideDNS"); + mSearchdomain =(EditTextPreference) findPreference("searchdomain"); + mDNS1 = (EditTextPreference) findPreference("dns1"); + mDNS2 = (EditTextPreference) findPreference("dns2"); + mNobind = (CheckBoxPreference) findPreference("nobind"); + + mIPv4.setOnPreferenceChangeListener(this); + mIPv6.setOnPreferenceChangeListener(this); + mDNS1.setOnPreferenceChangeListener(this); + mDNS2.setOnPreferenceChangeListener(this); + mUsePull.setOnPreferenceChangeListener(this); + mOverrideDNS.setOnPreferenceChangeListener(this); + mSearchdomain.setOnPreferenceChangeListener(this); + + loadSettings(); + } + + @Override + protected void loadSettings() { + + mUsePull.setChecked(mProfile.mUsePull); + mIPv4.setText(mProfile.mIPv4Address); + mIPv6.setText(mProfile.mIPv6Address); + mDNS1.setText(mProfile.mDNS1); + mDNS2.setText(mProfile.mDNS2); + mOverrideDNS.setChecked(mProfile.mOverrideDNS); + mSearchdomain.setText(mProfile.mSearchDomain); + mNobind.setChecked(mProfile.mNobind); + if (mProfile.mAuthenticationType == VpnProfile.TYPE_STATICKEYS) + mUsePull.setChecked(false); + + // Sets Summary + onPreferenceChange(mIPv4, mIPv4.getText()); + onPreferenceChange(mIPv6, mIPv6.getText()); + onPreferenceChange(mDNS1, mDNS1.getText()); + onPreferenceChange(mDNS2, mDNS2.getText()); + onPreferenceChange(mSearchdomain, mSearchdomain.getText()); + + setDNSState(); + } + + + @Override + protected void saveSettings() { + mProfile.mUsePull = mUsePull.isChecked(); + mProfile.mIPv4Address = mIPv4.getText(); + mProfile.mIPv6Address = mIPv6.getText(); + mProfile.mDNS1 = mDNS1.getText(); + mProfile.mDNS2 = mDNS2.getText(); + mProfile.mOverrideDNS = mOverrideDNS.isChecked(); + mProfile.mSearchDomain = mSearchdomain.getText(); + mProfile.mNobind = mNobind.isChecked(); + + } + + @Override + public boolean onPreferenceChange(Preference preference, + Object newValue) { + if(preference==mIPv4 || preference == mIPv6 + || preference==mDNS1 || preference == mDNS2 + || preference == mSearchdomain + ) + + preference.setSummary((String)newValue); + + if(preference== mUsePull || preference == mOverrideDNS) + if(preference==mOverrideDNS) { + // Set so the function gets the right value + mOverrideDNS.setChecked((Boolean) newValue); + } + setDNSState(); + + saveSettings(); + return true; + } + + private void setDNSState() { + boolean enabled; + mOverrideDNS.setEnabled(mUsePull.isChecked()); + if(!mUsePull.isChecked()) + enabled =true; + else + enabled = mOverrideDNS.isChecked(); + + mDNS1.setEnabled(enabled); + mDNS2.setEnabled(enabled); + mSearchdomain.setEnabled(enabled); + + + } + + + }
\ No newline at end of file diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Obscure.java b/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Obscure.java new file mode 100644 index 00000000..0e8f1a02 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Obscure.java @@ -0,0 +1,93 @@ +package de.blinkt.openvpn.fragments; + +import android.os.Bundle; +import android.preference.CheckBoxPreference; +import android.preference.EditTextPreference; +import android.preference.ListPreference; +import android.preference.Preference; +import android.preference.Preference.OnPreferenceChangeListener; +import de.blinkt.openvpn.R; + +public class Settings_Obscure extends OpenVpnPreferencesFragment implements OnPreferenceChangeListener { + private CheckBoxPreference mUseRandomHostName; + private CheckBoxPreference mUseFloat; + private CheckBoxPreference mUseCustomConfig; + private EditTextPreference mCustomConfig; + private ListPreference mLogverbosity; + private CheckBoxPreference mPersistent; + private ListPreference mConnectretrymax; + private EditTextPreference mConnectretry; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + // Load the preferences from an XML resource + addPreferencesFromResource(R.xml.vpn_obscure); + + mUseRandomHostName = (CheckBoxPreference) findPreference("useRandomHostname"); + mUseFloat = (CheckBoxPreference) findPreference("useFloat"); + mUseCustomConfig = (CheckBoxPreference) findPreference("enableCustomOptions"); + mCustomConfig = (EditTextPreference) findPreference("customOptions"); + mPersistent = (CheckBoxPreference) findPreference("usePersistTun"); + mConnectretrymax = (ListPreference) findPreference("connectretrymax"); + mConnectretry = (EditTextPreference) findPreference("connectretry"); + + mConnectretrymax.setOnPreferenceChangeListener(this); + mConnectretrymax.setSummary("%s"); + + mConnectretry.setOnPreferenceChangeListener(this); + + + loadSettings(); + + } + + protected void loadSettings() { + mUseRandomHostName.setChecked(mProfile.mUseRandomHostname); + mUseFloat.setChecked(mProfile.mUseFloat); + mUseCustomConfig.setChecked(mProfile.mUseCustomConfig); + mCustomConfig.setText(mProfile.mCustomConfigOptions); + mPersistent.setChecked(mProfile.mPersistTun); + + mConnectretrymax.setValue(mProfile.mConnectRetryMax); + onPreferenceChange(mConnectretrymax, mProfile.mConnectRetryMax); + + mConnectretry.setText(mProfile.mConnectRetry); + onPreferenceChange(mConnectretry, mProfile.mConnectRetry); + } + + + protected void saveSettings() { + mProfile.mUseRandomHostname = mUseRandomHostName.isChecked(); + mProfile.mUseFloat = mUseFloat.isChecked(); + mProfile.mUseCustomConfig = mUseCustomConfig.isChecked(); + mProfile.mCustomConfigOptions = mCustomConfig.getText(); + mProfile.mConnectRetryMax = mConnectretrymax.getValue(); + mProfile.mPersistTun = mPersistent.isChecked(); + mProfile.mConnectRetry = mConnectretry.getText(); + } + + + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + if (preference == mConnectretrymax) { + if(newValue==null) { + newValue="5"; + } + mConnectretrymax.setDefaultValue(newValue); + + for(int i=0;i<mConnectretrymax.getEntryValues().length;i++){ + if(mConnectretrymax.getEntryValues().equals(newValue)) + mConnectretrymax.setSummary(mConnectretrymax.getEntries()[i]); + } + + } else if (preference == mConnectretry) { + if(newValue==null || newValue=="") + newValue="5"; + mConnectretry.setSummary(String.format("%s s" , newValue)); + } + + return true; + } + +}
\ No newline at end of file diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Routing.java b/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Routing.java new file mode 100644 index 00000000..c6f0dcf8 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/fragments/Settings_Routing.java @@ -0,0 +1,88 @@ +package de.blinkt.openvpn.fragments; +import android.os.Bundle; +import android.preference.CheckBoxPreference; +import android.preference.EditTextPreference; +import android.preference.Preference; +import android.preference.Preference.OnPreferenceChangeListener; +import de.blinkt.openvpn.R; + + +public class Settings_Routing extends OpenVpnPreferencesFragment implements OnPreferenceChangeListener { + private EditTextPreference mCustomRoutes; + private CheckBoxPreference mUseDefaultRoute; + private EditTextPreference mCustomRoutesv6; + private CheckBoxPreference mUseDefaultRoutev6; + private CheckBoxPreference mRouteNoPull; + private CheckBoxPreference mLocalVPNAccess; + private EditTextPreference mExcludedRoutes; + private EditTextPreference mExcludedRoutesv6; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Load the preferences from an XML resource + addPreferencesFromResource(R.xml.vpn_routing); + mCustomRoutes = (EditTextPreference) findPreference("customRoutes"); + mUseDefaultRoute = (CheckBoxPreference) findPreference("useDefaultRoute"); + mCustomRoutesv6 = (EditTextPreference) findPreference("customRoutesv6"); + mUseDefaultRoutev6 = (CheckBoxPreference) findPreference("useDefaultRoutev6"); + mExcludedRoutes = (EditTextPreference) findPreference("excludedRoutes"); + mExcludedRoutesv6 = (EditTextPreference) findPreference("excludedRoutesv6"); + + mRouteNoPull = (CheckBoxPreference) findPreference("routenopull"); + mLocalVPNAccess = (CheckBoxPreference) findPreference("unblockLocal"); + + mCustomRoutes.setOnPreferenceChangeListener(this); + mCustomRoutesv6.setOnPreferenceChangeListener(this); + + loadSettings(); + } + + @Override + protected void loadSettings() { + + mUseDefaultRoute.setChecked(mProfile.mUseDefaultRoute); + mUseDefaultRoutev6.setChecked(mProfile.mUseDefaultRoutev6); + + mCustomRoutes.setText(mProfile.mCustomRoutes); + mCustomRoutesv6.setText(mProfile.mCustomRoutesv6); + + mExcludedRoutes.setText(mProfile.mExcludedRoutes); + mExcludedRoutes.setText(mProfile.mExcludedRoutesv6); + + mRouteNoPull.setChecked(mProfile.mRoutenopull); + mLocalVPNAccess.setChecked(mProfile.mAllowLocalLAN); + + // Sets Summary + onPreferenceChange(mCustomRoutes, mCustomRoutes.getText()); + onPreferenceChange(mCustomRoutesv6, mCustomRoutesv6.getText()); + mRouteNoPull.setEnabled(mProfile.mUsePull); + } + + + @Override + protected void saveSettings() { + mProfile.mUseDefaultRoute = mUseDefaultRoute.isChecked(); + mProfile.mUseDefaultRoutev6 = mUseDefaultRoutev6.isChecked(); + mProfile.mCustomRoutes = mCustomRoutes.getText(); + mProfile.mCustomRoutesv6 = mCustomRoutesv6.getText(); + mProfile.mRoutenopull = mRouteNoPull.isChecked(); + mProfile.mAllowLocalLAN =mLocalVPNAccess.isChecked(); + mProfile.mExcludedRoutes = mExcludedRoutes.getText(); + mProfile.mExcludedRoutesv6 = mExcludedRoutesv6.getText(); + } + + @Override + public boolean onPreferenceChange(Preference preference, + Object newValue) { + if( preference == mCustomRoutes || preference == mCustomRoutesv6 + || preference == mExcludedRoutes || preference == mExcludedRoutesv6) + preference.setSummary((String)newValue); + + saveSettings(); + return true; + } + + +}
\ No newline at end of file diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/ShowConfigFragment.java b/main/src/main/java/de/blinkt/openvpn/fragments/ShowConfigFragment.java new file mode 100644 index 00000000..bf673288 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/fragments/ShowConfigFragment.java @@ -0,0 +1,89 @@ +package de.blinkt.openvpn.fragments; + +import android.app.Fragment; +import android.content.Intent; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; +import de.blinkt.openvpn.R; +import de.blinkt.openvpn.VpnProfile; +import de.blinkt.openvpn.core.ProfileManager; + + +public class ShowConfigFragment extends Fragment { + private String configtext; + public android.view.View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) + { + String profileUUID = getArguments().getString(getActivity().getPackageName() + ".profileUUID"); + final VpnProfile vp = ProfileManager.get(getActivity(),profileUUID); + View v=inflater.inflate(R.layout.viewconfig, container,false); + final TextView cv = (TextView) v.findViewById(R.id.configview); + + int check=vp.checkProfile(getActivity()); + if(check!=R.string.no_error_found) { + cv.setText(check); + configtext = getString(check); + } + else { + // Run in own Thread since Keystore does not like to be queried from the main thread + + cv.setText("Generating config..."); + startGenConfig(vp, cv); + } + return v; + } + + private void startGenConfig(final VpnProfile vp, final TextView cv) { + + new Thread() { + public void run() { + final String cfg=vp.getConfigFile(getActivity(),false); + configtext= cfg; + getActivity().runOnUiThread(new Runnable() { + + @Override + public void run() { + cv.setText(cfg); + } + }); + + + } + }.start(); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setHasOptionsMenu(true); + } + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + inflater.inflate(R.menu.configmenu, menu); + } + + private void shareConfig() { + Intent shareIntent = new Intent(Intent.ACTION_SEND); + shareIntent.putExtra(Intent.EXTRA_TEXT, configtext); + shareIntent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.export_config_title)); + shareIntent.setType("text/plain"); + startActivity(Intent.createChooser(shareIntent, "Export Configfile")); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + final int itemId = item.getItemId(); + if (itemId == R.id.sendConfig) { + shareConfig(); + return true; + } else { + return super.onOptionsItemSelected(item); + } + } +} diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/Utils.java b/main/src/main/java/de/blinkt/openvpn/fragments/Utils.java new file mode 100644 index 00000000..9117f158 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/fragments/Utils.java @@ -0,0 +1,195 @@ +package de.blinkt.openvpn.fragments; + +import android.annotation.TargetApi; +import android.content.Context; +import android.content.Intent; +import android.database.Cursor; +import android.net.Uri; +import android.os.Build; +import android.provider.OpenableColumns; +import android.util.Base64; +import android.util.Log; +import android.webkit.MimeTypeMap; +import de.blinkt.openvpn.VpnProfile; +import junit.framework.Assert; + +import java.io.*; +import java.util.TreeSet; +import java.util.Vector; + +public class Utils { + + @TargetApi(Build.VERSION_CODES.KITKAT) + public static Intent getFilePickerIntent(FileType fileType) { + Intent i = new Intent(Intent.ACTION_OPEN_DOCUMENT); + i.addCategory(Intent.CATEGORY_OPENABLE); + TreeSet<String> supportedMimeTypes = new TreeSet<String>(); + Vector<String> extensions = new Vector<String>(); + + switch (fileType) { + case PKCS12: + i.setType("application/x-pkcs12"); + supportedMimeTypes.add("application/x-pkcs12"); + extensions.add("p12"); + extensions.add("pfx"); + break; + case CLIENT_CERTIFICATE: + case CA_CERTIFICATE: + i.setType("application/x-pem-file"); + supportedMimeTypes.add("application/x-x509-ca-cert"); + supportedMimeTypes.add("application/x-x509-user-cert"); + supportedMimeTypes.add("application/x-pem-file"); + supportedMimeTypes.add("text/plain"); + + extensions.add("pem"); + extensions.add("crt"); + break; + case KEYFILE: + i.setType("application/x-pem-file"); + supportedMimeTypes.add("application/x-pem-file"); + supportedMimeTypes.add("application/pkcs8"); + + // Google drive .... + supportedMimeTypes.add("application/x-iwork-keynote-sffkey"); + extensions.add("key"); + break; + + case TLS_AUTH_FILE: + i.setType("text/plain"); + + // Backup .... + supportedMimeTypes.add("application/pkcs8"); + // Google Drive is kind of crazy ..... + supportedMimeTypes.add("application/x-iwork-keynote-sffkey"); + + extensions.add("txt"); + extensions.add("key"); + break; + + case OVPN_CONFIG: + i.setType("application/x-openvpn-profile"); + supportedMimeTypes.add("application/x-openvpn-profile"); + supportedMimeTypes.add("application/openvpn-profile"); + supportedMimeTypes.add("application/ovpn"); + supportedMimeTypes.add("text/plain"); + extensions.add("ovpn"); + extensions.add("conf"); + break; + + case USERPW_FILE: + i.setType("text/plain"); + supportedMimeTypes.add("text/plain"); + break; + } + + MimeTypeMap mtm = MimeTypeMap.getSingleton(); + + for (String ext : extensions) { + String mimeType = mtm.getMimeTypeFromExtension(ext); + if (mimeType != null) + supportedMimeTypes.add(mimeType); + } + + // Always add this as fallback + supportedMimeTypes.add("application/octet-stream"); + + i.putExtra(Intent.EXTRA_MIME_TYPES, supportedMimeTypes.toArray(new String[supportedMimeTypes.size()])); + return i; + } + + public enum FileType { + PKCS12(0), + CLIENT_CERTIFICATE(1), + CA_CERTIFICATE(2), + OVPN_CONFIG(3), + KEYFILE(4), + TLS_AUTH_FILE(5), + USERPW_FILE(6); + + private int value; + + FileType(int i) { + value = i; + } + + public static FileType getFileTypeByValue(int value) { + switch (value) { + case 0: + return PKCS12; + case 1: + return CLIENT_CERTIFICATE; + case 2: + return CA_CERTIFICATE; + case 3: + return OVPN_CONFIG; + case 4: + return KEYFILE; + case 5: + return TLS_AUTH_FILE; + case 6: + return USERPW_FILE; + default: + return null; + } + } + + public int getValue() { + return value; + } + } + + static private byte[] readBytesFromStream(InputStream input) throws IOException { + + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + int nRead; + byte[] data = new byte[16384]; + + while ((nRead = input.read(data, 0, data.length)) != -1) { + buffer.write(data, 0, nRead); + } + + buffer.flush(); + input.close(); + return buffer.toByteArray(); + } + + public static String getFilePickerResult(FileType ft, Intent result, Context c) throws IOException { + + Uri uri = result.getData(); + if (uri == null) + return null; + + byte[] fileData = readBytesFromStream(c.getContentResolver().openInputStream(uri)); + String newData = null; + + Cursor cursor = c.getContentResolver().query(uri, null, null, null, null); + + String prefix = ""; + try { + if (cursor!=null && cursor.moveToFirst()) { + int cidx = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME); + if (cidx != -1) { + String displayName = cursor.getString(cidx); + + if (!displayName.contains(VpnProfile.INLINE_TAG) && !displayName.contains(VpnProfile.DISPLAYNAME_TAG)) + prefix = VpnProfile.DISPLAYNAME_TAG + displayName; + } + } + } finally { + if(cursor!=null) + cursor.close(); + } + + switch (ft) { + case PKCS12: + newData = Base64.encodeToString(fileData, Base64.DEFAULT); + break; + default: + newData = new String(fileData, "UTF-8"); + break; + } + + return prefix + VpnProfile.INLINE_TAG + newData; + } +} diff --git a/main/src/main/java/de/blinkt/openvpn/fragments/VPNProfileList.java b/main/src/main/java/de/blinkt/openvpn/fragments/VPNProfileList.java new file mode 100644 index 00000000..b26f3505 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/fragments/VPNProfileList.java @@ -0,0 +1,346 @@ +package de.blinkt.openvpn.fragments; + +import android.annotation.TargetApi; +import android.app.Activity; +import android.app.AlertDialog; +import android.app.ListFragment; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.text.Html; +import android.text.Html.ImageGetter; +import android.view.*; +import android.view.View.OnClickListener; +import android.webkit.MimeTypeMap; +import android.widget.ArrayAdapter; +import android.widget.EditText; +import android.widget.TextView; +import android.widget.Toast; +import de.blinkt.openvpn.*; +import de.blinkt.openvpn.activities.ConfigConverter; +import de.blinkt.openvpn.activities.FileSelect; +import de.blinkt.openvpn.activities.VPNPreferences; +import de.blinkt.openvpn.core.ProfileManager; + +import java.util.Collection; +import java.util.Comparator; +import java.util.TreeSet; + +public class VPNProfileList extends ListFragment { + + public final static int RESULT_VPN_DELETED = Activity.RESULT_FIRST_USER; + + private static final int MENU_ADD_PROFILE = Menu.FIRST; + + private static final int START_VPN_CONFIG = 92; + private static final int SELECT_PROFILE = 43; + private static final int IMPORT_PROFILE = 231; + private static final int FILE_PICKER_RESULT = 392; + + private static final int MENU_IMPORT_PROFILE = Menu.FIRST +1; + + + class VPNArrayAdapter extends ArrayAdapter<VpnProfile> { + + public VPNArrayAdapter(Context context, int resource, + int textViewResourceId) { + super(context, resource, textViewResourceId); + } + + @Override + public View getView(final int position, View convertView, ViewGroup parent) { + View v = super.getView(position, convertView, parent); + + View titleview = v.findViewById(R.id.vpn_list_item_left); + titleview.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + VpnProfile profile =(VpnProfile) getListAdapter().getItem(position); + startVPN(profile); + } + }); + + View settingsview = v.findViewById(R.id.quickedit_settings); + settingsview.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View v) { + VpnProfile editProfile = (VpnProfile) getListAdapter().getItem(position); + editVPN(editProfile); + + } + }); + + return v; + } + } + + + + + + + + + private ArrayAdapter<VpnProfile> mArrayadapter; + + protected VpnProfile mEditProfile=null; + + + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setHasOptionsMenu(true); + + } + + + class MiniImageGetter implements ImageGetter { + + + @Override + public Drawable getDrawable(String source) { + Drawable d=null; + if ("ic_menu_add".equals(source)) + d = getActivity().getResources().getDrawable(android.R.drawable.ic_menu_add); + else if("ic_menu_archive".equals(source)) + d = getActivity().getResources().getDrawable(R.drawable.ic_menu_archive); + + + + if(d!=null) { + d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight()); + return d; + }else{ + return null; + } + } + } + + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View v = inflater.inflate(R.layout.vpn_profile_list, container,false); + + TextView newvpntext = (TextView) v.findViewById(R.id.add_new_vpn_hint); + TextView importvpntext = (TextView) v.findViewById(R.id.import_vpn_hint); + + + + newvpntext.setText(Html.fromHtml(getString(R.string.add_new_vpn_hint),new MiniImageGetter(),null)); + importvpntext.setText(Html.fromHtml(getString(R.string.vpn_import_hint),new MiniImageGetter(),null)); + + + + return v; + + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + setListAdapter(); + } + + static class VpnProfileNameComparator implements Comparator<VpnProfile> { + + @Override + public int compare(VpnProfile lhs, VpnProfile rhs) { + if (lhs == rhs) + // Catches also both null + return 0; + + if (lhs == null) + return -1; + if (rhs == null) + return 1; + + if (lhs.mName == null) + return -1; + if (rhs.mName == null) + return 1; + + return lhs.mName.compareTo(rhs.mName); + } + + } + + private void setListAdapter() { + mArrayadapter = new VPNArrayAdapter(getActivity(),R.layout.vpn_list_item,R.id.vpn_item_title); + Collection<VpnProfile> allvpn = getPM().getProfiles(); + + TreeSet<VpnProfile> sortedset = new TreeSet<VpnProfile>(new VpnProfileNameComparator()); + sortedset.addAll(allvpn); + mArrayadapter.addAll(sortedset); + + setListAdapter(mArrayadapter); + } + + + + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + menu.add(0, MENU_ADD_PROFILE, 0 , R.string.menu_add_profile) + .setIcon(android.R.drawable.ic_menu_add) + .setAlphabeticShortcut('a') + .setTitleCondensed(getActivity().getString(R.string.add)) + .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT); + + menu.add(0, MENU_IMPORT_PROFILE, 0, R.string.menu_import) + .setIcon(R.drawable.ic_menu_archive) + .setAlphabeticShortcut('i') + .setTitleCondensed(getActivity().getString(R.string.menu_import_short)) + .setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT ); + } + + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + final int itemId = item.getItemId(); + if (itemId == MENU_ADD_PROFILE) { + onAddProfileClicked(); + return true; + } else if (itemId == MENU_IMPORT_PROFILE) { + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) + startFilePicker(); + else + startImportConfig(); + + return true; + } else { + return super.onOptionsItemSelected(item); + } + } + + @TargetApi(Build.VERSION_CODES.KITKAT) + private void startFilePicker() { + Intent i = Utils.getFilePickerIntent(Utils.FileType.OVPN_CONFIG); + startActivityForResult(i, FILE_PICKER_RESULT); + } + + private void startImportConfig() { + Intent intent = new Intent(getActivity(),FileSelect.class); + intent.putExtra(FileSelect.NO_INLINE_SELECTION, true); + intent.putExtra(FileSelect.WINDOW_TITLE, R.string.import_configuration_file); + startActivityForResult(intent, SELECT_PROFILE); + } + + + + + + private void onAddProfileClicked() { + Context context = getActivity(); + if (context != null) { + final EditText entry = new EditText(context); + entry.setSingleLine(); + + AlertDialog.Builder dialog = new AlertDialog.Builder(context); + dialog.setTitle(R.string.menu_add_profile); + dialog.setMessage(R.string.add_profile_name_prompt); + dialog.setView(entry); + + + dialog.setPositiveButton(android.R.string.ok, + new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + String name = entry.getText().toString(); + if (getPM().getProfileByName(name)==null) { + VpnProfile profile = new VpnProfile(name); + addProfile(profile); + editVPN(profile); + } else { + Toast.makeText(getActivity(), R.string.duplicate_profile_name, Toast.LENGTH_LONG).show(); + } + } + + + }); + dialog.setNegativeButton(android.R.string.cancel, null); + dialog.create().show(); + } + + } + + private void addProfile(VpnProfile profile) { + getPM().addProfile(profile); + getPM().saveProfileList(getActivity()); + getPM().saveProfile(getActivity(),profile); + mArrayadapter.add(profile); + } + + private ProfileManager getPM() { + return ProfileManager.getInstance(getActivity()); + } + + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + + if(resultCode == RESULT_VPN_DELETED){ + if(mArrayadapter != null && mEditProfile !=null) + mArrayadapter.remove(mEditProfile); + } + + if(resultCode != Activity.RESULT_OK) + return; + + if (requestCode == START_VPN_CONFIG) { + String configuredVPN = data.getStringExtra(VpnProfile.EXTRA_PROFILEUUID); + + VpnProfile profile = ProfileManager.get(getActivity(),configuredVPN); + getPM().saveProfile(getActivity(), profile); + // Name could be modified, reset List adapter + setListAdapter(); + + } else if(requestCode== SELECT_PROFILE) { + String fileData = data.getStringExtra(FileSelect.RESULT_DATA); + Uri uri = new Uri.Builder().path(fileData).scheme("file").build(); + + startConfigImport(uri); + } else if(requestCode == IMPORT_PROFILE) { + String profileUUID = data.getStringExtra(VpnProfile.EXTRA_PROFILEUUID); + mArrayadapter.add(ProfileManager.get(getActivity(), profileUUID)); + } else if(requestCode == FILE_PICKER_RESULT) { + if (data != null) { + Uri uri = data.getData(); + startConfigImport(uri); + } + } + + } + + private void startConfigImport(Uri uri) { + Intent startImport = new Intent(getActivity(),ConfigConverter.class); + startImport.setAction(ConfigConverter.IMPORT_PROFILE); + startImport.setData(uri); + startActivityForResult(startImport, IMPORT_PROFILE); + } + + + private void editVPN(VpnProfile profile) { + mEditProfile =profile; + Intent vprefintent = new Intent(getActivity(),VPNPreferences.class) + .putExtra(getActivity().getPackageName() + ".profileUUID", profile.getUUID().toString()); + + startActivityForResult(vprefintent,START_VPN_CONFIG); + } + + private void startVPN(VpnProfile profile) { + + getPM().saveProfile(getActivity(), profile); + + Intent intent = new Intent(getActivity(),LaunchVPN.class); + intent.putExtra(LaunchVPN.EXTRA_KEY, profile.getUUID().toString()); + intent.setAction(Intent.ACTION_MAIN); + startActivity(intent); + } +} diff --git a/main/src/main/java/de/blinkt/openvpn/views/FileSelectLayout.java b/main/src/main/java/de/blinkt/openvpn/views/FileSelectLayout.java new file mode 100644 index 00000000..362777e4 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/views/FileSelectLayout.java @@ -0,0 +1,156 @@ +package de.blinkt.openvpn.views; + +import de.blinkt.openvpn.R; +import de.blinkt.openvpn.VpnProfile; +import de.blinkt.openvpn.activities.FileSelect; +import de.blinkt.openvpn.core.VpnStatus; +import de.blinkt.openvpn.core.X509Utils; +import android.content.Context; +import android.content.Intent; +import android.content.res.TypedArray; +import android.util.AttributeSet; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.Button; +import android.widget.LinearLayout; +import android.widget.TextView; +import de.blinkt.openvpn.fragments.Utils; + +import java.io.*; + +import static android.os.Build.*; + + +public class FileSelectLayout extends LinearLayout implements OnClickListener { + + public void parseResponse(Intent data, Context c) { + if (VERSION.SDK_INT < VERSION_CODES.KITKAT) { + String fileData = data.getStringExtra(FileSelect.RESULT_DATA); + setData(fileData, c); + } else if (data != null) { + try { + String newData = Utils.getFilePickerResult(fileType, data, c); + if (newData!=null) + setData(newData, c); + + } catch (IOException e) { + VpnStatus.logException(e); + } + + + } + } + + public interface FileSelectCallback { + + String getString(int res); + + void startActivityForResult(Intent startFC, int mTaskId); + } + + private boolean mIsCertificate; + private TextView mDataView; + private String mData; + private FileSelectCallback mFragment; + private int mTaskId; + private Button mSelectButton; + private Utils.FileType fileType; + private String mTitle; + private boolean mShowClear; + private TextView mDataDetails; + + public FileSelectLayout(Context context, AttributeSet attrset) { + super(context, attrset); + + TypedArray ta = context.obtainStyledAttributes(attrset, R.styleable.FileSelectLayout); + + setupViews(ta.getString(R.styleable.FileSelectLayout_title), ta.getBoolean(R.styleable.FileSelectLayout_certificate, true)); + + ta.recycle(); + } + + public FileSelectLayout (Context context, String title, boolean isCerticate) + { + super(context); + + setupViews(title, isCerticate); + + } + + private void setupViews(String title, boolean isCertificate) { + inflate(getContext(), R.layout.file_select, this); + + mTitle = title; + mIsCertificate = isCertificate; + + TextView tview = (TextView) findViewById(R.id.file_title); + tview.setText(mTitle); + + mDataView = (TextView) findViewById(R.id.file_selected_item); + mDataDetails = (TextView) findViewById(R.id.file_selected_description); + mSelectButton = (Button) findViewById(R.id.file_select_button); + mSelectButton.setOnClickListener(this); + } + + + public void setCaller(FileSelectCallback fragment, int i, Utils.FileType ft) { + mTaskId = i; + mFragment = fragment; + fileType = ft; + } + + public void getCertificateFileDialog() { + Intent startFC = new Intent(getContext(), FileSelect.class); + startFC.putExtra(FileSelect.START_DATA, mData); + startFC.putExtra(FileSelect.WINDOW_TITLE, mTitle); + if (fileType == Utils.FileType.PKCS12) + startFC.putExtra(FileSelect.DO_BASE64_ENCODE, true); + if (mShowClear) + startFC.putExtra(FileSelect.SHOW_CLEAR_BUTTON, true); + + mFragment.startActivityForResult(startFC, mTaskId); + } + + + public String getData() { + return mData; + } + + public void setData(String data, Context c) { + mData = data; + if (data == null) { + mDataView.setText(c.getString(R.string.no_data)); + mDataDetails.setText(""); + } else { + if (mData.startsWith(VpnProfile.DISPLAYNAME_TAG)) { + mDataView.setText(c.getString(R.string.imported_from_file, VpnProfile.getDisplayName(mData))); + } else if (mData.startsWith(VpnProfile.INLINE_TAG)) + mDataView.setText(R.string.inline_file_data); + else + mDataView.setText(data); + if (mIsCertificate) + mDataDetails.setText(X509Utils.getCertificateFriendlyName(c, data)); + } + + } + + @Override + public void onClick(View v) { + if (v == mSelectButton) { + if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) { + Intent startFilePicker = Utils.getFilePickerIntent(fileType); + mFragment.startActivityForResult(startFilePicker, mTaskId); + } else { + getCertificateFileDialog(); + } + } + } + + + + + public void setShowClear() { + mShowClear = true; + } + +} diff --git a/main/src/main/java/de/blinkt/openvpn/views/RemoteCNPreference.java b/main/src/main/java/de/blinkt/openvpn/views/RemoteCNPreference.java new file mode 100644 index 00000000..388f892b --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/views/RemoteCNPreference.java @@ -0,0 +1,141 @@ +package de.blinkt.openvpn.views; + +import android.content.Context; +import android.preference.DialogPreference; +import android.util.AttributeSet; +import android.util.Pair; +import android.view.View; +import android.widget.ArrayAdapter; +import android.widget.EditText; +import android.widget.Spinner; +import android.widget.TextView; + +import de.blinkt.openvpn.R; +import de.blinkt.openvpn.VpnProfile; + +public class RemoteCNPreference extends DialogPreference { + + + private Spinner mSpinner; + private EditText mEditText; + private int mDNType; + private String mDn; + private TextView mRemoteTLSNote; + //private ScrollView mScrollView; + + public RemoteCNPreference(Context context, AttributeSet attrs) { + super(context, attrs); + setDialogLayoutResource(R.layout.tlsremote); + + } + + @Override + protected void onBindDialogView(View view) { + + super.onBindDialogView(view); + + mEditText = (EditText) view.findViewById(R.id.tlsremotecn); + mSpinner = (Spinner) view.findViewById(R.id.x509verifytype); + mRemoteTLSNote = (TextView) view.findViewById(R.id.tlsremotenote); + //mScrollView = (ScrollView) view.findViewById(R.id.tlsremotescroll); + if(mDn!=null) + mEditText.setText(mDn); + + populateSpinner(); + + } + + + + public String getCNText() { + return mDn; + } + + public int getAuthtype() { + return mDNType; + } + + public void setDN(String dn) { + mDn = dn; + if(mEditText!=null) + mEditText.setText(dn); + } + + public void setAuthType(int x509authtype) { + mDNType = x509authtype; + if (mSpinner!=null) + populateSpinner(); + } + + @Override + protected void onDialogClosed(boolean positiveResult) { + super.onDialogClosed(positiveResult); + + if (positiveResult) { + String dn = mEditText.getText().toString(); + int authtype = getAuthTypeFromSpinner(); + if (callChangeListener(new Pair<Integer, String>(authtype, dn))) { + mDn = dn; + mDNType = authtype; + } + } + } + + private void populateSpinner() { + ArrayAdapter<String> authtypes = new ArrayAdapter<String>(getContext(), android.R.layout.simple_spinner_item); + authtypes.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + + authtypes.add(getContext().getString(R.string.complete_dn)); + authtypes.add(getContext().getString(R.string.rdn)); + authtypes.add(getContext().getString(R.string.rdn_prefix)); + if ((mDNType == VpnProfile.X509_VERIFY_TLSREMOTE || mDNType == VpnProfile.X509_VERIFY_TLSREMOTE_COMPAT_NOREMAPPING) + && !(mDn==null || "".equals(mDn))) { + authtypes.add(getContext().getString(R.string.tls_remote_deprecated)); + mRemoteTLSNote.setVisibility(View.VISIBLE); + } else { + mRemoteTLSNote.setVisibility(View.GONE); + } + mSpinner.setAdapter(authtypes); + mSpinner.setSelection(getSpinnerPositionFromAuthTYPE()); + } + + private int getSpinnerPositionFromAuthTYPE() { + switch (mDNType) { + case VpnProfile.X509_VERIFY_TLSREMOTE_DN: + return 0; + case VpnProfile.X509_VERIFY_TLSREMOTE_RDN: + return 1; + case VpnProfile.X509_VERIFY_TLSREMOTE_RDN_PREFIX: + return 2; + case VpnProfile.X509_VERIFY_TLSREMOTE_COMPAT_NOREMAPPING: + case VpnProfile.X509_VERIFY_TLSREMOTE: + if (mDn==null || "".equals(mDn)) + return 1; + else + return 3; + + + default: + return 0; + } + } + + private int getAuthTypeFromSpinner() { + int pos = mSpinner.getSelectedItemPosition(); + switch (pos) { + case 0: + return VpnProfile.X509_VERIFY_TLSREMOTE_DN; + case 1: + return VpnProfile.X509_VERIFY_TLSREMOTE_RDN; + case 2: + return VpnProfile.X509_VERIFY_TLSREMOTE_RDN_PREFIX; + case 3: + // This is the tls-remote entry, only visible if mDntype is a + // tls-remote type + return mDNType; + default: + return VpnProfile.X509_VERIFY_TLSREMOTE; + } + } + +} diff --git a/main/src/main/java/de/blinkt/openvpn/views/SeekBarTicks.java b/main/src/main/java/de/blinkt/openvpn/views/SeekBarTicks.java new file mode 100644 index 00000000..88e8e164 --- /dev/null +++ b/main/src/main/java/de/blinkt/openvpn/views/SeekBarTicks.java @@ -0,0 +1,69 @@ +package de.blinkt.openvpn.views; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.util.TypedValue; +import android.view.ViewConfiguration; +import android.widget.SeekBar; + +public class SeekBarTicks extends SeekBar { + private Paint mTickPaint; + private float mTickHeight; + + private float tickHeightRatio = 0.6f; + + public SeekBarTicks(Context context, AttributeSet attrs) { + super (context, attrs); + + initTicks (context, attrs, android.R.attr.seekBarStyle); + } + + + public SeekBarTicks(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + initTicks (context, attrs, defStyle); + + /*mTickHeight = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, + tickHeightDP, + ctx.getResources().getDisplayMetrics()); */ + } + + private void initTicks(Context context, AttributeSet attrs, int defStyle) { + TypedArray a = context.obtainStyledAttributes(attrs, + new int[] { android.R.attr.secondaryProgress }, defStyle, 0); + + + int tickColor = a.getColor(0, android.R.color.black); + mTickPaint = new Paint(); + mTickPaint.setColor( context.getResources().getColor(tickColor)); + a.recycle(); + } + + + @Override + protected synchronized void onDraw(Canvas canvas) { + drawTicks(canvas); + super.onDraw(canvas); + } + + private void drawTicks(Canvas canvas) { + + final int available = getWidth() - getPaddingLeft() - getPaddingRight(); + final int availableHeight = getHeight() - getPaddingBottom() - getPaddingTop(); + + int extrapadding = (int) ((availableHeight- (availableHeight * tickHeightRatio))/2); + + int tickSpacing = available / (getMax() ); + + for (int i = 1; i < getMax(); i++) { + final float x = getPaddingLeft() + i * tickSpacing; + + canvas.drawLine(x, getPaddingTop()+extrapadding, x, getHeight()-getPaddingBottom()-extrapadding, mTickPaint); + } + } +} diff --git a/main/src/main/java/org/spongycastle/util/encoders/Base64.java b/main/src/main/java/org/spongycastle/util/encoders/Base64.java new file mode 100644 index 00000000..87bd80a0 --- /dev/null +++ b/main/src/main/java/org/spongycastle/util/encoders/Base64.java @@ -0,0 +1,121 @@ +package org.spongycastle.util.encoders; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +public class Base64 +{ + private static final Encoder encoder = new Base64Encoder(); + + /** + * encode the input data producing a base 64 encoded byte array. + * + * @return a byte array containing the base 64 encoded data. + */ + public static byte[] encode( + byte[] data) + { + int len = (data.length + 2) / 3 * 4; + ByteArrayOutputStream bOut = new ByteArrayOutputStream(len); + + try + { + encoder.encode(data, 0, data.length, bOut); + } + catch (IOException e) + { + throw new RuntimeException("exception encoding base64 string: " + e); + } + + return bOut.toByteArray(); + } + + /** + * Encode the byte data to base 64 writing it to the given output stream. + * + * @return the number of bytes produced. + */ + public static int encode( + byte[] data, + OutputStream out) + throws IOException + { + return encoder.encode(data, 0, data.length, out); + } + + /** + * Encode the byte data to base 64 writing it to the given output stream. + * + * @return the number of bytes produced. + */ + public static int encode( + byte[] data, + int off, + int length, + OutputStream out) + throws IOException + { + return encoder.encode(data, off, length, out); + } + + /** + * decode the base 64 encoded input data. It is assumed the input data is valid. + * + * @return a byte array representing the decoded data. + */ + public static byte[] decode( + byte[] data) + { + int len = data.length / 4 * 3; + ByteArrayOutputStream bOut = new ByteArrayOutputStream(len); + + try + { + encoder.decode(data, 0, data.length, bOut); + } + catch (IOException e) + { + throw new RuntimeException("exception decoding base64 string: " + e); + } + + return bOut.toByteArray(); + } + + /** + * decode the base 64 encoded String data - whitespace will be ignored. + * + * @return a byte array representing the decoded data. + */ + public static byte[] decode( + String data) + { + int len = data.length() / 4 * 3; + ByteArrayOutputStream bOut = new ByteArrayOutputStream(len); + + try + { + encoder.decode(data, bOut); + } + catch (IOException e) + { + throw new RuntimeException("exception decoding base64 string: " + e); + } + + return bOut.toByteArray(); + } + + /** + * decode the base 64 encoded String data writing it to the given output stream, + * whitespace characters will be ignored. + * + * @return the number of bytes produced. + */ + public static int decode( + String data, + OutputStream out) + throws IOException + { + return encoder.decode(data, out); + } +} diff --git a/main/src/main/java/org/spongycastle/util/encoders/Base64Encoder.java b/main/src/main/java/org/spongycastle/util/encoders/Base64Encoder.java new file mode 100644 index 00000000..84060707 --- /dev/null +++ b/main/src/main/java/org/spongycastle/util/encoders/Base64Encoder.java @@ -0,0 +1,298 @@ +package org.spongycastle.util.encoders; + +import java.io.IOException; +import java.io.OutputStream; + +public class Base64Encoder + implements Encoder +{ + protected final byte[] encodingTable = + { + (byte)'A', (byte)'B', (byte)'C', (byte)'D', (byte)'E', (byte)'F', (byte)'G', + (byte)'H', (byte)'I', (byte)'J', (byte)'K', (byte)'L', (byte)'M', (byte)'N', + (byte)'O', (byte)'P', (byte)'Q', (byte)'R', (byte)'S', (byte)'T', (byte)'U', + (byte)'V', (byte)'W', (byte)'X', (byte)'Y', (byte)'Z', + (byte)'a', (byte)'b', (byte)'c', (byte)'d', (byte)'e', (byte)'f', (byte)'g', + (byte)'h', (byte)'i', (byte)'j', (byte)'k', (byte)'l', (byte)'m', (byte)'n', + (byte)'o', (byte)'p', (byte)'q', (byte)'r', (byte)'s', (byte)'t', (byte)'u', + (byte)'v', + (byte)'w', (byte)'x', (byte)'y', (byte)'z', + (byte)'0', (byte)'1', (byte)'2', (byte)'3', (byte)'4', (byte)'5', (byte)'6', + (byte)'7', (byte)'8', (byte)'9', + (byte)'+', (byte)'/' + }; + + protected byte padding = (byte)'='; + + /* + * set up the decoding table. + */ + protected final byte[] decodingTable = new byte[128]; + + protected void initialiseDecodingTable() + { + for (int i = 0; i < encodingTable.length; i++) + { + decodingTable[encodingTable[i]] = (byte)i; + } + } + + public Base64Encoder() + { + initialiseDecodingTable(); + } + + /** + * encode the input data producing a base 64 output stream. + * + * @return the number of bytes produced. + */ + public int encode( + byte[] data, + int off, + int length, + OutputStream out) + throws IOException + { + int modulus = length % 3; + int dataLength = (length - modulus); + int a1, a2, a3; + + for (int i = off; i < off + dataLength; i += 3) + { + a1 = data[i] & 0xff; + a2 = data[i + 1] & 0xff; + a3 = data[i + 2] & 0xff; + + out.write(encodingTable[(a1 >>> 2) & 0x3f]); + out.write(encodingTable[((a1 << 4) | (a2 >>> 4)) & 0x3f]); + out.write(encodingTable[((a2 << 2) | (a3 >>> 6)) & 0x3f]); + out.write(encodingTable[a3 & 0x3f]); + } + + /* + * process the tail end. + */ + int b1, b2, b3; + int d1, d2; + + switch (modulus) + { + case 0: /* nothing left to do */ + break; + case 1: + d1 = data[off + dataLength] & 0xff; + b1 = (d1 >>> 2) & 0x3f; + b2 = (d1 << 4) & 0x3f; + + out.write(encodingTable[b1]); + out.write(encodingTable[b2]); + out.write(padding); + out.write(padding); + break; + case 2: + d1 = data[off + dataLength] & 0xff; + d2 = data[off + dataLength + 1] & 0xff; + + b1 = (d1 >>> 2) & 0x3f; + b2 = ((d1 << 4) | (d2 >>> 4)) & 0x3f; + b3 = (d2 << 2) & 0x3f; + + out.write(encodingTable[b1]); + out.write(encodingTable[b2]); + out.write(encodingTable[b3]); + out.write(padding); + break; + } + + return (dataLength / 3) * 4 + ((modulus == 0) ? 0 : 4); + } + + private boolean ignore( + char c) + { + return (c == '\n' || c =='\r' || c == '\t' || c == ' '); + } + + /** + * decode the base 64 encoded byte data writing it to the given output stream, + * whitespace characters will be ignored. + * + * @return the number of bytes produced. + */ + public int decode( + byte[] data, + int off, + int length, + OutputStream out) + throws IOException + { + byte b1, b2, b3, b4; + int outLen = 0; + + int end = off + length; + + while (end > off) + { + if (!ignore((char)data[end - 1])) + { + break; + } + + end--; + } + + int i = off; + int finish = end - 4; + + i = nextI(data, i, finish); + + while (i < finish) + { + b1 = decodingTable[data[i++]]; + + i = nextI(data, i, finish); + + b2 = decodingTable[data[i++]]; + + i = nextI(data, i, finish); + + b3 = decodingTable[data[i++]]; + + i = nextI(data, i, finish); + + b4 = decodingTable[data[i++]]; + + out.write((b1 << 2) | (b2 >> 4)); + out.write((b2 << 4) | (b3 >> 2)); + out.write((b3 << 6) | b4); + + outLen += 3; + + i = nextI(data, i, finish); + } + + outLen += decodeLastBlock(out, (char)data[end - 4], (char)data[end - 3], (char)data[end - 2], (char)data[end - 1]); + + return outLen; + } + + private int nextI(byte[] data, int i, int finish) + { + while ((i < finish) && ignore((char)data[i])) + { + i++; + } + return i; + } + + /** + * decode the base 64 encoded String data writing it to the given output stream, + * whitespace characters will be ignored. + * + * @return the number of bytes produced. + */ + public int decode( + String data, + OutputStream out) + throws IOException + { + byte b1, b2, b3, b4; + int length = 0; + + int end = data.length(); + + while (end > 0) + { + if (!ignore(data.charAt(end - 1))) + { + break; + } + + end--; + } + + int i = 0; + int finish = end - 4; + + i = nextI(data, i, finish); + + while (i < finish) + { + b1 = decodingTable[data.charAt(i++)]; + + i = nextI(data, i, finish); + + b2 = decodingTable[data.charAt(i++)]; + + i = nextI(data, i, finish); + + b3 = decodingTable[data.charAt(i++)]; + + i = nextI(data, i, finish); + + b4 = decodingTable[data.charAt(i++)]; + + out.write((b1 << 2) | (b2 >> 4)); + out.write((b2 << 4) | (b3 >> 2)); + out.write((b3 << 6) | b4); + + length += 3; + + i = nextI(data, i, finish); + } + + length += decodeLastBlock(out, data.charAt(end - 4), data.charAt(end - 3), data.charAt(end - 2), data.charAt(end - 1)); + + return length; + } + + private int decodeLastBlock(OutputStream out, char c1, char c2, char c3, char c4) + throws IOException + { + byte b1, b2, b3, b4; + + if (c3 == padding) + { + b1 = decodingTable[c1]; + b2 = decodingTable[c2]; + + out.write((b1 << 2) | (b2 >> 4)); + + return 1; + } + else if (c4 == padding) + { + b1 = decodingTable[c1]; + b2 = decodingTable[c2]; + b3 = decodingTable[c3]; + + out.write((b1 << 2) | (b2 >> 4)); + out.write((b2 << 4) | (b3 >> 2)); + + return 2; + } + else + { + b1 = decodingTable[c1]; + b2 = decodingTable[c2]; + b3 = decodingTable[c3]; + b4 = decodingTable[c4]; + + out.write((b1 << 2) | (b2 >> 4)); + out.write((b2 << 4) | (b3 >> 2)); + out.write((b3 << 6) | b4); + + return 3; + } + } + + private int nextI(String data, int i, int finish) + { + while ((i < finish) && ignore(data.charAt(i))) + { + i++; + } + return i; + } +} diff --git a/main/src/main/java/org/spongycastle/util/encoders/Encoder.java b/main/src/main/java/org/spongycastle/util/encoders/Encoder.java new file mode 100644 index 00000000..106c36b7 --- /dev/null +++ b/main/src/main/java/org/spongycastle/util/encoders/Encoder.java @@ -0,0 +1,17 @@ +package org.spongycastle.util.encoders; + +import java.io.IOException; +import java.io.OutputStream; + +/** + * Encode and decode byte arrays (typically from binary to 7-bit ASCII + * encodings). + */ +public interface Encoder +{ + int encode(byte[] data, int off, int length, OutputStream out) throws IOException; + + int decode(byte[] data, int off, int length, OutputStream out) throws IOException; + + int decode(String data, OutputStream out) throws IOException; +} diff --git a/main/src/main/java/org/spongycastle/util/io/pem/PemGenerationException.java b/main/src/main/java/org/spongycastle/util/io/pem/PemGenerationException.java new file mode 100644 index 00000000..0127ca0c --- /dev/null +++ b/main/src/main/java/org/spongycastle/util/io/pem/PemGenerationException.java @@ -0,0 +1,26 @@ +package org.spongycastle.util.io.pem; + +import java.io.IOException; + +@SuppressWarnings("serial") +public class PemGenerationException + extends IOException +{ + private Throwable cause; + + public PemGenerationException(String message, Throwable cause) + { + super(message); + this.cause = cause; + } + + public PemGenerationException(String message) + { + super(message); + } + + public Throwable getCause() + { + return cause; + } +} diff --git a/main/src/main/java/org/spongycastle/util/io/pem/PemHeader.java b/main/src/main/java/org/spongycastle/util/io/pem/PemHeader.java new file mode 100644 index 00000000..4adb815e --- /dev/null +++ b/main/src/main/java/org/spongycastle/util/io/pem/PemHeader.java @@ -0,0 +1,66 @@ +package org.spongycastle.util.io.pem; + +public class PemHeader +{ + private String name; + private String value; + + public PemHeader(String name, String value) + { + this.name = name; + this.value = value; + } + + public String getName() + { + return name; + } + + public String getValue() + { + return value; + } + + public int hashCode() + { + return getHashCode(this.name) + 31 * getHashCode(this.value); + } + + public boolean equals(Object o) + { + if (!(o instanceof PemHeader)) + { + return false; + } + + PemHeader other = (PemHeader)o; + + return other == this || (isEqual(this.name, other.name) && isEqual(this.value, other.value)); + } + + private int getHashCode(String s) + { + if (s == null) + { + return 1; + } + + return s.hashCode(); + } + + private boolean isEqual(String s1, String s2) + { + if (s1 == s2) + { + return true; + } + + if (s1 == null || s2 == null) + { + return false; + } + + return s1.equals(s2); + } + +} diff --git a/main/src/main/java/org/spongycastle/util/io/pem/PemObject.java b/main/src/main/java/org/spongycastle/util/io/pem/PemObject.java new file mode 100644 index 00000000..6f7c79c5 --- /dev/null +++ b/main/src/main/java/org/spongycastle/util/io/pem/PemObject.java @@ -0,0 +1,62 @@ +package org.spongycastle.util.io.pem; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +@SuppressWarnings("all") +public class PemObject + implements PemObjectGenerator +{ + private static final List EMPTY_LIST = Collections.unmodifiableList(new ArrayList()); + + private String type; + private List headers; + private byte[] content; + + /** + * Generic constructor for object without headers. + * + * @param type pem object type. + * @param content the binary content of the object. + */ + public PemObject(String type, byte[] content) + { + this(type, EMPTY_LIST, content); + } + + /** + * Generic constructor for object with headers. + * + * @param type pem object type. + * @param headers a list of PemHeader objects. + * @param content the binary content of the object. + */ + public PemObject(String type, List headers, byte[] content) + { + this.type = type; + this.headers = Collections.unmodifiableList(headers); + this.content = content; + } + + public String getType() + { + return type; + } + + public List getHeaders() + { + return headers; + } + + public byte[] getContent() + { + return content; + } + + public PemObject generate() + throws PemGenerationException + { + return this; + } +} diff --git a/main/src/main/java/org/spongycastle/util/io/pem/PemObjectGenerator.java b/main/src/main/java/org/spongycastle/util/io/pem/PemObjectGenerator.java new file mode 100644 index 00000000..1a8cea6d --- /dev/null +++ b/main/src/main/java/org/spongycastle/util/io/pem/PemObjectGenerator.java @@ -0,0 +1,7 @@ +package org.spongycastle.util.io.pem; + +public interface PemObjectGenerator +{ + PemObject generate() + throws PemGenerationException; +} diff --git a/main/src/main/java/org/spongycastle/util/io/pem/PemReader.java b/main/src/main/java/org/spongycastle/util/io/pem/PemReader.java new file mode 100644 index 00000000..cbbebab9 --- /dev/null +++ b/main/src/main/java/org/spongycastle/util/io/pem/PemReader.java @@ -0,0 +1,84 @@ +package org.spongycastle.util.io.pem; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.Reader; +import java.util.ArrayList; +import java.util.List; + +import org.spongycastle.util.encoders.Base64; + +public class PemReader + extends BufferedReader +{ + private static final String BEGIN = "-----BEGIN "; + private static final String END = "-----END "; + + public PemReader(Reader reader) + { + super(reader); + } + + public PemObject readPemObject() + throws IOException + { + String line = readLine(); + + while (line != null && !line.startsWith(BEGIN)) + { + line = readLine(); + } + + if (line != null) + { + line = line.substring(BEGIN.length()); + int index = line.indexOf('-'); + String type = line.substring(0, index); + + if (index > 0) + { + return loadObject(type); + } + } + + return null; + } + + private PemObject loadObject(String type) + throws IOException + { + String line; + String endMarker = END + type; + StringBuffer buf = new StringBuffer(); + List headers = new ArrayList(); + + while ((line = readLine()) != null) + { + if (line.indexOf(":") >= 0) + { + int index = line.indexOf(':'); + String hdr = line.substring(0, index); + String value = line.substring(index + 1).trim(); + + headers.add(new PemHeader(hdr, value)); + + continue; + } + + if (line.indexOf(endMarker) != -1) + { + break; + } + + buf.append(line.trim()); + } + + if (line == null) + { + throw new IOException(endMarker + " not found"); + } + + return new PemObject(type, headers, Base64.decode(buf.toString())); + } + +} diff --git a/main/src/main/java/org/spongycastle/util/io/pem/PemWriter.java b/main/src/main/java/org/spongycastle/util/io/pem/PemWriter.java new file mode 100644 index 00000000..f5a6a363 --- /dev/null +++ b/main/src/main/java/org/spongycastle/util/io/pem/PemWriter.java @@ -0,0 +1,138 @@ +package org.spongycastle.util.io.pem; + +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.Writer; +import java.util.Iterator; + +import org.spongycastle.util.encoders.Base64; + +/** + * A generic PEM writer, based on RFC 1421 + */ +@SuppressWarnings("all") +public class PemWriter + extends BufferedWriter +{ + private static final int LINE_LENGTH = 64; + + private final int nlLength; + private char[] buf = new char[LINE_LENGTH]; + + /** + * Base constructor. + * + * @param out output stream to use. + */ + public PemWriter(Writer out) + { + super(out); + + String nl = System.getProperty("line.separator"); + if (nl != null) + { + nlLength = nl.length(); + } + else + { + nlLength = 2; + } + } + + /** + * Return the number of bytes or characters required to contain the + * passed in object if it is PEM encoded. + * + * @param obj pem object to be output + * @return an estimate of the number of bytes + */ + public int getOutputSize(PemObject obj) + { + // BEGIN and END boundaries. + int size = (2 * (obj.getType().length() + 10 + nlLength)) + 6 + 4; + + if (!obj.getHeaders().isEmpty()) + { + for (Iterator it = obj.getHeaders().iterator(); it.hasNext();) + { + PemHeader hdr = (PemHeader)it.next(); + + size += hdr.getName().length() + ": ".length() + hdr.getValue().length() + nlLength; + } + + size += nlLength; + } + + // base64 encoding + int dataLen = ((obj.getContent().length + 2) / 3) * 4; + + size += dataLen + (((dataLen + LINE_LENGTH - 1) / LINE_LENGTH) * nlLength); + + return size; + } + + public void writeObject(PemObjectGenerator objGen) + throws IOException + { + PemObject obj = objGen.generate(); + + writePreEncapsulationBoundary(obj.getType()); + + if (!obj.getHeaders().isEmpty()) + { + for (Iterator it = obj.getHeaders().iterator(); it.hasNext();) + { + PemHeader hdr = (PemHeader)it.next(); + + this.write(hdr.getName()); + this.write(": "); + this.write(hdr.getValue()); + this.newLine(); + } + + this.newLine(); + } + + writeEncoded(obj.getContent()); + writePostEncapsulationBoundary(obj.getType()); + } + + private void writeEncoded(byte[] bytes) + throws IOException + { + bytes = Base64.encode(bytes); + + for (int i = 0; i < bytes.length; i += buf.length) + { + int index = 0; + + while (index != buf.length) + { + if ((i + index) >= bytes.length) + { + break; + } + buf[index] = (char)bytes[i + index]; + index++; + } + this.write(buf, 0, index); + this.newLine(); + } + } + + private void writePreEncapsulationBoundary( + String type) + throws IOException + { + this.write("-----BEGIN " + type + "-----"); + this.newLine(); + } + + private void writePostEncapsulationBoundary( + String type) + throws IOException + { + this.write("-----END " + type + "-----"); + this.newLine(); + } +} diff --git a/main/src/main/res/drawable-hdpi/ic_clock.png b/main/src/main/res/drawable-hdpi/ic_clock.png Binary files differnew file mode 100644 index 00000000..22da1b4c --- /dev/null +++ b/main/src/main/res/drawable-hdpi/ic_clock.png diff --git a/main/src/main/res/drawable-hdpi/ic_doc_generic_am.png b/main/src/main/res/drawable-hdpi/ic_doc_generic_am.png Binary files differnew file mode 100644 index 00000000..55b9b7d3 --- /dev/null +++ b/main/src/main/res/drawable-hdpi/ic_doc_generic_am.png diff --git a/main/src/main/res/drawable-hdpi/ic_menu_archive.png b/main/src/main/res/drawable-hdpi/ic_menu_archive.png Binary files differnew file mode 100644 index 00000000..e2d9bc1a --- /dev/null +++ b/main/src/main/res/drawable-hdpi/ic_menu_archive.png diff --git a/main/src/main/res/drawable-hdpi/ic_root_folder_am.png b/main/src/main/res/drawable-hdpi/ic_root_folder_am.png Binary files differnew file mode 100644 index 00000000..915e1182 --- /dev/null +++ b/main/src/main/res/drawable-hdpi/ic_root_folder_am.png diff --git a/main/src/main/res/drawable-hdpi/ic_stat_vpn.png b/main/src/main/res/drawable-hdpi/ic_stat_vpn.png Binary files differnew file mode 100644 index 00000000..788cbd32 --- /dev/null +++ b/main/src/main/res/drawable-hdpi/ic_stat_vpn.png diff --git a/main/src/main/res/drawable-hdpi/ic_stat_vpn_empty_halo.png b/main/src/main/res/drawable-hdpi/ic_stat_vpn_empty_halo.png Binary files differnew file mode 100644 index 00000000..7df5b670 --- /dev/null +++ b/main/src/main/res/drawable-hdpi/ic_stat_vpn_empty_halo.png diff --git a/main/src/main/res/drawable-hdpi/ic_stat_vpn_offline.png b/main/src/main/res/drawable-hdpi/ic_stat_vpn_offline.png Binary files differnew file mode 100644 index 00000000..8aa48803 --- /dev/null +++ b/main/src/main/res/drawable-hdpi/ic_stat_vpn_offline.png diff --git a/main/src/main/res/drawable-hdpi/ic_stat_vpn_outline.png b/main/src/main/res/drawable-hdpi/ic_stat_vpn_outline.png Binary files differnew file mode 100644 index 00000000..b5583d99 --- /dev/null +++ b/main/src/main/res/drawable-hdpi/ic_stat_vpn_outline.png diff --git a/main/src/main/res/drawable-hdpi/ic_sysbar_quicksettings.png b/main/src/main/res/drawable-hdpi/ic_sysbar_quicksettings.png Binary files differnew file mode 100644 index 00000000..47b4ba23 --- /dev/null +++ b/main/src/main/res/drawable-hdpi/ic_sysbar_quicksettings.png diff --git a/main/src/main/res/drawable-hdpi/icon.png b/main/src/main/res/drawable-hdpi/icon.png Binary files differnew file mode 100644 index 00000000..d4d31f52 --- /dev/null +++ b/main/src/main/res/drawable-hdpi/icon.png diff --git a/main/src/main/res/drawable-mdpi/ic_clock.png b/main/src/main/res/drawable-mdpi/ic_clock.png Binary files differnew file mode 100644 index 00000000..9ad15397 --- /dev/null +++ b/main/src/main/res/drawable-mdpi/ic_clock.png diff --git a/main/src/main/res/drawable-mdpi/ic_doc_generic_am.png b/main/src/main/res/drawable-mdpi/ic_doc_generic_am.png Binary files differnew file mode 100644 index 00000000..a1bd14ea --- /dev/null +++ b/main/src/main/res/drawable-mdpi/ic_doc_generic_am.png diff --git a/main/src/main/res/drawable-mdpi/ic_menu_archive.png b/main/src/main/res/drawable-mdpi/ic_menu_archive.png Binary files differnew file mode 100644 index 00000000..49ac569d --- /dev/null +++ b/main/src/main/res/drawable-mdpi/ic_menu_archive.png diff --git a/main/src/main/res/drawable-mdpi/ic_root_folder_am.png b/main/src/main/res/drawable-mdpi/ic_root_folder_am.png Binary files differnew file mode 100644 index 00000000..4352d08d --- /dev/null +++ b/main/src/main/res/drawable-mdpi/ic_root_folder_am.png diff --git a/main/src/main/res/drawable-mdpi/ic_stat_vpn.png b/main/src/main/res/drawable-mdpi/ic_stat_vpn.png Binary files differnew file mode 100644 index 00000000..e1dbeb33 --- /dev/null +++ b/main/src/main/res/drawable-mdpi/ic_stat_vpn.png diff --git a/main/src/main/res/drawable-mdpi/ic_stat_vpn_empty_halo.png b/main/src/main/res/drawable-mdpi/ic_stat_vpn_empty_halo.png Binary files differnew file mode 100644 index 00000000..fc039a82 --- /dev/null +++ b/main/src/main/res/drawable-mdpi/ic_stat_vpn_empty_halo.png diff --git a/main/src/main/res/drawable-mdpi/ic_stat_vpn_offline.png b/main/src/main/res/drawable-mdpi/ic_stat_vpn_offline.png Binary files differnew file mode 100644 index 00000000..f31387a4 --- /dev/null +++ b/main/src/main/res/drawable-mdpi/ic_stat_vpn_offline.png diff --git a/main/src/main/res/drawable-mdpi/ic_stat_vpn_outline.png b/main/src/main/res/drawable-mdpi/ic_stat_vpn_outline.png Binary files differnew file mode 100644 index 00000000..052aef9d --- /dev/null +++ b/main/src/main/res/drawable-mdpi/ic_stat_vpn_outline.png diff --git a/main/src/main/res/drawable-mdpi/ic_sysbar_quicksettings.png b/main/src/main/res/drawable-mdpi/ic_sysbar_quicksettings.png Binary files differnew file mode 100644 index 00000000..79281042 --- /dev/null +++ b/main/src/main/res/drawable-mdpi/ic_sysbar_quicksettings.png diff --git a/main/src/main/res/drawable-mdpi/icon.png b/main/src/main/res/drawable-mdpi/icon.png Binary files differnew file mode 100644 index 00000000..4d58f717 --- /dev/null +++ b/main/src/main/res/drawable-mdpi/icon.png diff --git a/main/src/main/res/drawable-xhdpi/ic_clock.png b/main/src/main/res/drawable-xhdpi/ic_clock.png Binary files differnew file mode 100644 index 00000000..a2485f0e --- /dev/null +++ b/main/src/main/res/drawable-xhdpi/ic_clock.png diff --git a/main/src/main/res/drawable-xhdpi/ic_doc_generic_am.png b/main/src/main/res/drawable-xhdpi/ic_doc_generic_am.png Binary files differnew file mode 100644 index 00000000..e05c4b48 --- /dev/null +++ b/main/src/main/res/drawable-xhdpi/ic_doc_generic_am.png diff --git a/main/src/main/res/drawable-xhdpi/ic_menu_archive.png b/main/src/main/res/drawable-xhdpi/ic_menu_archive.png Binary files differnew file mode 100644 index 00000000..b1be9d5b --- /dev/null +++ b/main/src/main/res/drawable-xhdpi/ic_menu_archive.png diff --git a/main/src/main/res/drawable-xhdpi/ic_root_folder_am.png b/main/src/main/res/drawable-xhdpi/ic_root_folder_am.png Binary files differnew file mode 100644 index 00000000..c916e0be --- /dev/null +++ b/main/src/main/res/drawable-xhdpi/ic_root_folder_am.png diff --git a/main/src/main/res/drawable-xhdpi/ic_stat_vpn.png b/main/src/main/res/drawable-xhdpi/ic_stat_vpn.png Binary files differnew file mode 100644 index 00000000..605d9936 --- /dev/null +++ b/main/src/main/res/drawable-xhdpi/ic_stat_vpn.png diff --git a/main/src/main/res/drawable-xhdpi/ic_stat_vpn_empty_halo.png b/main/src/main/res/drawable-xhdpi/ic_stat_vpn_empty_halo.png Binary files differnew file mode 100644 index 00000000..2f61e890 --- /dev/null +++ b/main/src/main/res/drawable-xhdpi/ic_stat_vpn_empty_halo.png diff --git a/main/src/main/res/drawable-xhdpi/ic_stat_vpn_offline.png b/main/src/main/res/drawable-xhdpi/ic_stat_vpn_offline.png Binary files differnew file mode 100644 index 00000000..e9411518 --- /dev/null +++ b/main/src/main/res/drawable-xhdpi/ic_stat_vpn_offline.png diff --git a/main/src/main/res/drawable-xhdpi/ic_stat_vpn_outline.png b/main/src/main/res/drawable-xhdpi/ic_stat_vpn_outline.png Binary files differnew file mode 100644 index 00000000..5d27240d --- /dev/null +++ b/main/src/main/res/drawable-xhdpi/ic_stat_vpn_outline.png diff --git a/main/src/main/res/drawable-xhdpi/ic_sysbar_quicksettings.png b/main/src/main/res/drawable-xhdpi/ic_sysbar_quicksettings.png Binary files differnew file mode 100644 index 00000000..a057db8b --- /dev/null +++ b/main/src/main/res/drawable-xhdpi/ic_sysbar_quicksettings.png diff --git a/main/src/main/res/drawable-xhdpi/icon.png b/main/src/main/res/drawable-xhdpi/icon.png Binary files differnew file mode 100644 index 00000000..37612879 --- /dev/null +++ b/main/src/main/res/drawable-xhdpi/icon.png diff --git a/main/src/main/res/drawable-xxhdpi/ic_doc_generic_am.png b/main/src/main/res/drawable-xxhdpi/ic_doc_generic_am.png Binary files differnew file mode 100644 index 00000000..c0988663 --- /dev/null +++ b/main/src/main/res/drawable-xxhdpi/ic_doc_generic_am.png diff --git a/main/src/main/res/drawable-xxhdpi/ic_root_folder_am.png b/main/src/main/res/drawable-xxhdpi/ic_root_folder_am.png Binary files differnew file mode 100644 index 00000000..077c851c --- /dev/null +++ b/main/src/main/res/drawable-xxhdpi/ic_root_folder_am.png diff --git a/main/src/main/res/drawable-xxhdpi/icon.png b/main/src/main/res/drawable-xxhdpi/icon.png Binary files differnew file mode 100644 index 00000000..0132423d --- /dev/null +++ b/main/src/main/res/drawable-xxhdpi/icon.png diff --git a/main/src/main/res/layout-sw600dp-port/log_fragment.xml b/main/src/main/res/layout-sw600dp-port/log_fragment.xml new file mode 100644 index 00000000..ddf0506b --- /dev/null +++ b/main/src/main/res/layout-sw600dp-port/log_fragment.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + tools:context=".LogWindow"> + + <LinearLayout + android:layout_height="wrap_content" + android:layout_width="match_parent"> + + <include layout="@layout/log_silders"/> + + <Space + android:layout_weight="5" + android:layout_height="wrap_content" + android:layout_width="wrap_content"/> + <LinearLayout + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:orientation="vertical"> + <include layout="@layout/vpnstatus"/> + </LinearLayout> + <Space + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:layout_weight="1"/> + </LinearLayout> + + <Space + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:minHeight="5dp"/> + + <ListView + android:id="@android:id/list" + android:transcriptMode="normal" + android:layout_width="fill_parent" + android:layout_height="fill_parent"/> + +</LinearLayout>
\ No newline at end of file diff --git a/main/src/main/res/layout-sw600dp/log_fragment.xml b/main/src/main/res/layout-sw600dp/log_fragment.xml new file mode 100644 index 00000000..c4e1355c --- /dev/null +++ b/main/src/main/res/layout-sw600dp/log_fragment.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="horizontal" + android:padding="20dp" + tools:context=".LogWindow"> + + + <LinearLayout + android:minWidth="300dp" + android:orientation="vertical" + android:layout_width="wrap_content" + android:layout_height="match_parent"> + + <include layout="@layout/log_silders"/> + + <include layout="@layout/vpnstatus"/> + </LinearLayout> + + <Space + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:minWidth="5dp"/> + + <ListView + android:id="@android:id/list" + android:transcriptMode="normal" + android:layout_width="fill_parent" + android:layout_height="match_parent"/> +</LinearLayout> diff --git a/main/src/main/res/layout/about.xml b/main/src/main/res/layout/about.xml new file mode 100644 index 00000000..46a5bec2 --- /dev/null +++ b/main/src/main/res/layout/about.xml @@ -0,0 +1,191 @@ +<?xml version="1.0" encoding="utf-8"?> +<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingLeft="@dimen/stdpadding" + android:paddingRight="@dimen/stdpadding" > + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" > + + <TextView + android:id="@+id/version" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textAppearance="?android:attr/textAppearanceLarge" + tools:ignore="SelectableText" /> + + <Space + android:layout_width="match_parent" + android:layout_height="12sp" /> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:autoLink="all" + android:text="@string/copyright_blinktgui" /> + + <Space + android:layout_width="match_parent" + android:layout_height="12sp" /> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:autoLink="all" + android:text="@string/copyright_guicode" /> + + <Space + android:layout_width="match_parent" + android:layout_height="12sp" /> + + <TextView + android:id="@+id/donatestring" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/donatewithpaypal" + tools:ignore="SelectableText" /> + + + <TextView + android:paddingTop="12sp" + android:id="@+id/donategms" + android:text="@string/donatePlayStore" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:visibility="gone" + tools:ignore="SelectableText"/> + + + <Space + android:layout_width="match_parent" + android:layout_height="12sp" /> + + <TextView + android:id="@+id/translation" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:autoLink="all" + tools:ignore="SelectableText" /> + + <Space + android:layout_width="match_parent" + android:layout_height="12sp" /> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:autoLink="all" + android:text="@string/help_translate" /> + + <Space + android:layout_width="match_parent" + android:layout_height="12sp" /> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/copyright_others" /> + + <Space + android:layout_width="match_parent" + android:layout_height="12sp" /> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/openvpn" + android:textAppearance="?android:attr/textAppearanceMedium" /> + <!-- + ImageView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:contentDescription="@string/openvpn_logo_descr" + android:src="@drawable/openvpnLogo" /> + --> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/opevpn_copyright" /> + + <Space + android:layout_width="match_parent" + android:layout_height="20sp" /> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/file_dialog" + android:textAppearance="?android:attr/textAppearanceMedium" /> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/copyright_file_dialog" /> + + <Space + android:layout_width="match_parent" + android:layout_height="20sp" /> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/lzo" + android:textAppearance="?android:attr/textAppearanceMedium" /> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/lzo_copyright" /> + + <Space + android:layout_width="match_parent" + android:layout_height="20sp" /> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/openssl" + android:textAppearance="?android:attr/textAppearanceMedium" /> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/copyright_openssl" /> + + <Space + android:layout_width="match_parent" + android:layout_height="20sp" /> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/bouncy_castle" + android:textAppearance="?android:attr/textAppearanceMedium" /> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/copyright_bouncycastle" /> + + <Space + android:layout_width="match_parent" + android:layout_height="150dp" /> + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/full_licenses" + android:textAppearance="?android:attr/textAppearanceLarge" /> + + <WebView + android:layout_width="match_parent" + android:layout_height="match_parent" + android:id="@+id/webView" + android:layout_gravity="center_horizontal" /> + </LinearLayout> + +</ScrollView> diff --git a/main/src/main/res/layout/api_confirm.xml b/main/src/main/res/layout/api_confirm.xml new file mode 100644 index 00000000..28624880 --- /dev/null +++ b/main/src/main/res/layout/api_confirm.xml @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2011 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + <LinearLayout android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:padding="20dp"> + + <LinearLayout android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + tools:ignore="UseCompoundDrawables" + android:gravity="center_vertical"> + + <ImageView android:id="@+id/icon" + android:contentDescription="@string/permission_icon_app" + android:layout_width="@android:dimen/app_icon_size" + android:layout_height="@android:dimen/app_icon_size" + android:paddingRight="5dp"/> + + <TextView android:id="@+id/prompt" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:textSize="18sp"/> + </LinearLayout> + + <TextView android:id="@+id/warning" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:paddingTop="5dp" + android:paddingBottom="5dp" + android:text="@string/remote_warning" + android:textSize="18sp"/> + + <CheckBox android:id="@+id/check" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:text="@string/remote_trust" + android:textSize="20sp" + android:checked="false"/> + </LinearLayout> +</ScrollView>
\ No newline at end of file diff --git a/main/src/main/res/layout/basic_settings.xml b/main/src/main/res/layout/basic_settings.xml new file mode 100644 index 00000000..f8c38e79 --- /dev/null +++ b/main/src/main/res/layout/basic_settings.xml @@ -0,0 +1,244 @@ +<?xml version="1.0" encoding="utf-8"?> +<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:blinkt="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="wrap_content" + android:layout_height="wrap_content" > + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:padding="4dp" > + + <TextView + style="@style/item" + android:text="@string/profilename" + android:textAppearance="?android:attr/textAppearanceSmall" + /> + + <EditText + android:id="@+id/profilename" + style="@style/item" + android:inputType="text" /> + + <TextView + style="@style/item" + android:text="@string/address" + android:textAppearance="?android:attr/textAppearanceSmall" /> + + <EditText + android:id="@+id/address" + style="@style/item" + android:inputType="textUri" + android:text="@string/defaultserver" > + + <!-- <requestFocus /> --> + </EditText> + + <TextView + style="@style/item" + android:text="@string/port" + android:textAppearance="?android:attr/textAppearanceSmall" /> + + <RelativeLayout + android:id="@+id/relativeLayout1" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginLeft="8dip" + android:layout_marginRight="8dip" > + + <EditText + android:id="@+id/port" + style="@style/item" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentLeft="true" + android:layout_alignParentTop="true" + android:inputType="number" + android:text="@string/defaultport" /> + + <ToggleButton + android:id="@+id/tcpudp" + style="@style/accountSetupButton" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentRight="true" + android:layout_alignParentTop="true" + android:textOff="TCP" + android:textOn="UDP" /> + </RelativeLayout> + + <CheckBox + android:id="@+id/lzo" + style="@style/item" + android:text="@string/useLZO" /> + + <TextView + style="@style/item" + android:text="@string/vpn_type" + android:textAppearance="?android:attr/textAppearanceSmall" /> + + <Spinner + android:id="@+id/type" + style="@style/item" + android:entries="@array/vpn_types" + android:prompt="@string/vpn_type" /> + + <LinearLayout + android:id="@+id/keystore" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:visibility="gone" + tools:visibility="visible"> + + <include layout="@layout/keystore_selector" /> + + <TextView + style="@style/item" + android:singleLine="false" + android:text="@string/extracahint" + android:textAppearance="?android:attr/textAppearanceSmall" /> + </LinearLayout> + + <LinearLayout + android:id="@+id/cacert" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:visibility="gone" > + + <de.blinkt.openvpn.views.FileSelectLayout + android:id="@+id/caselect" + android:layout_width="match_parent" + android:layout_height="wrap_content" + blinkt:title="@string/ca_title" /> + </LinearLayout> + + <LinearLayout + android:id="@+id/certs" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:visibility="gone" > + + <de.blinkt.openvpn.views.FileSelectLayout + android:id="@+id/certselect" + android:layout_width="match_parent" + android:layout_height="wrap_content" + blinkt:title="@string/client_certificate_title" /> + + <de.blinkt.openvpn.views.FileSelectLayout + android:id="@+id/keyselect" + android:layout_width="match_parent" + android:layout_height="wrap_content" + blinkt:certificate="false" + blinkt:title="@string/client_key_title" /> + + <LinearLayout + android:id="@+id/key_password_layout" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:visibility="gone" > + + <TextView + style="@style/item" + android:layout_marginLeft="8dip" + android:layout_marginRight="8dip" + android:text="@string/private_key_password" + android:textAppearance="?android:attr/textAppearanceSmall" /> + + <EditText + android:id="@+id/key_password" + style="@style/item" + android:layout_marginLeft="8dip" + android:layout_marginRight="8dip" + android:hint="@string/pw_query_hint" + android:inputType="textPassword" /> + </LinearLayout> + </LinearLayout> + + <LinearLayout + android:id="@+id/pkcs12" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:visibility="gone" > + + <de.blinkt.openvpn.views.FileSelectLayout + android:id="@+id/pkcs12select" + android:layout_width="match_parent" + android:layout_height="wrap_content" + blinkt:certificate="false" + blinkt:title="@string/client_pkcs12_title" /> + + <TextView + style="@style/item" + android:layout_marginLeft="8dip" + android:layout_marginRight="8dip" + android:text="@string/pkcs12pwquery" + android:textAppearance="?android:attr/textAppearanceSmall" /> + + <EditText + android:id="@+id/pkcs12password" + style="@style/item" + android:layout_marginLeft="8dip" + android:layout_marginRight="8dip" + android:hint="@string/pw_query_hint" + android:inputType="textPassword" /> + </LinearLayout> + + <LinearLayout + android:id="@+id/userpassword" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:visibility="gone" > + + <TextView + style="@style/item" + android:layout_marginLeft="8dip" + android:layout_marginRight="8dip" + android:text="@string/auth_username" + android:textAppearance="?android:attr/textAppearanceSmall" /> + + <EditText + android:id="@+id/auth_username" + style="@style/item" + android:layout_marginLeft="8dip" + android:layout_marginRight="8dip" + android:inputType="textNoSuggestions" /> + + <TextView + style="@style/item" + android:layout_marginLeft="8dip" + android:layout_marginRight="8dip" + android:text="@string/auth_pwquery" + android:textAppearance="?android:attr/textAppearanceSmall" /> + + <EditText + android:id="@+id/auth_password" + style="@style/item" + android:layout_marginLeft="8dip" + android:layout_marginRight="8dip" + android:hint="@string/pw_query_hint" + android:inputType="textPassword" /> + </LinearLayout> + + <LinearLayout + android:id="@+id/statickeys" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + android:visibility="gone" > + + <TextView + style="@style/item" + android:singleLine="false" + android:text="@string/static_keys_info" /> + </LinearLayout> + </LinearLayout> + +</ScrollView>
\ No newline at end of file diff --git a/main/src/main/res/layout/config_converter.xml b/main/src/main/res/layout/config_converter.xml new file mode 100644 index 00000000..f43d463e --- /dev/null +++ b/main/src/main/res/layout/config_converter.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:id="@+id/config_convert_root" + android:orientation="vertical" > + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/files_missing_hint" + android:visibility="gone" + android:id="@+id/files_missing_hint" + tools:visibilty="visible"/> + + <CheckBox + android:id="@+id/importpkcs12" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:checked="true" + android:text="@string/importpkcs12fromconfig" + android:visibility="gone" /> + + <ListView + android:id="@android:id/list" + android:layout_width="fill_parent" + android:layout_height="fill_parent" /> + +</LinearLayout>
\ No newline at end of file diff --git a/main/src/main/res/layout/faq.xml b/main/src/main/res/layout/faq.xml new file mode 100644 index 00000000..8983e203 --- /dev/null +++ b/main/src/main/res/layout/faq.xml @@ -0,0 +1,141 @@ +<?xml version="1.0" encoding="utf-8"?> +<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingLeft="@dimen/stdpadding" + android:paddingRight="@dimen/stdpadding" > + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" > + + <TextView + style="@style/faqhead" + android:text="@string/faq_howto_title" /> + + <TextView + android:id="@+id/faq_howto" + style="@style/faqitem" + tools:text="@string/faq_howto" + tools:ignore="SelectableText" /> + + <TextView + style="@style/faqhead" + android:text="@string/faq_vpndialog43_title" /> + + <TextView + tools:text="@string/faq_vpndialog43" + android:id="@+id/faq_vpndialog43" + style="@style/faqitem" /> + + <TextView + style="@style/faqhead" + android:text="@string/faq_system_dialogs_title" /> + + <TextView + style="@style/faqitem" + android:text="@string/faq_system_dialogs" /> + + <TextView + style="@style/faqitem" + tools:text="@string/faq_system_dialog_xposed" + android:id="@+id/faq_system_dialog_xposed"/> + + <TextView + style="@style/faqhead" + android:text="@string/faq_duplicate_notification_title" /> + + <TextView + style="@style/faqitem" + android:text="@string/faq_duplicate_notification" /> + + <TextView + style="@style/faqhead" + android:text="@string/battery_consumption_title" /> + + <TextView + android:id="@+id/baterry_consumption" + tools:text="@string/baterry_consumption" + style="@style/faqitem" + tools:ignore="SelectableText" /> + + <TextView + style="@style/faqhead" + android:text="@string/tap_mode" /> + + <TextView + style="@style/faqitem" + android:text="@string/faq_tap_mode" /> + + <TextView + style="@style/faqhead" + android:text="@string/vpn_tethering_title" /> + + <TextView + android:id="@+id/faq_tethering" + style="@style/faqitem" + tools:text="@string/faq_tethering" + tools:ignore="SelectableText" /> + + <TextView + style="@style/faqhead" + android:text="@string/faq_security_title" /> + + <TextView + style="@style/faqitem" + android:text="@string/faq_security" /> + + <TextView + style="@style/faqhead" + android:text="@string/broken_images" /> + + <TextView + android:id="@+id/broken_images_faq" + style="@style/faqitem" + tools:ignore="SelectableText" /> + + <TextView + style="@style/faqhead" + android:text="@string/faq_shortcut" /> + + <TextView + style="@style/faqitem" + android:text="@string/faq_howto_shortcut" /> + + <TextView + style="@style/faqhead" + android:text="@string/tap_mode" /> + + <TextView + style="@style/faqitem" + android:text="@string/tap_faq2" /> + + <TextView + style="@style/faqhead" + android:text="@string/copying_log_entries" /> + + <TextView + style="@style/faqitem" + android:text="@string/faq_copying" /> + + <TextView + style="@style/faqhead" + android:text="@string/tap_mode" /> + + <TextView + style="@style/faqitem" + android:text="@string/tap_faq3" /> + + <TextView + style="@style/faqhead" + android:text="@string/faq_routing_title" /> + + <TextView + style="@style/faqitem" + android:text="@string/faq_routing" > + </TextView> + </LinearLayout> + +</ScrollView>
\ No newline at end of file diff --git a/main/src/main/res/layout/file_dialog.xml b/main/src/main/res/layout/file_dialog.xml new file mode 100644 index 00000000..12abe497 --- /dev/null +++ b/main/src/main/res/layout/file_dialog.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:orientation="vertical" > + + <LinearLayout + android:id="@+id/fragment_place" + android:orientation="horizontal" + android:layout_width="match_parent" + android:layout_height="wrap_content" > + </LinearLayout> + +</LinearLayout>
\ No newline at end of file diff --git a/main/src/main/res/layout/file_dialog_inline.xml b/main/src/main/res/layout/file_dialog_inline.xml new file mode 100644 index 00000000..61e39134 --- /dev/null +++ b/main/src/main/res/layout/file_dialog_inline.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" > +<!-- The header already states Inline File + <TextView + android:id="@+id/textView1" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="Inline File Data" + android:textAppearance="?android:attr/textAppearanceMedium" /> + --> + <EditText + android:id="@+id/inlineFileData" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:inputType="textMultiLine|textNoSuggestions" + android:textAppearance="?android:attr/textAppearanceSmall" /> + + +</LinearLayout>
\ No newline at end of file diff --git a/main/src/main/res/layout/file_dialog_main.xml b/main/src/main/res/layout/file_dialog_main.xml new file mode 100644 index 00000000..b50ef8a6 --- /dev/null +++ b/main/src/main/res/layout/file_dialog_main.xml @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="utf-8"?> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/relativeLayout01" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:orientation="vertical" > + + <LinearLayout + android:id="@+id/fdLinearLayoutList" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:layout_alignParentBottom="true" + android:orientation="horizontal" > + + <Button + android:id="@+id/fdButtonSelect" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/select_file" > + </Button> + + <CheckBox + android:id="@+id/doinline" + android:checked="true" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/make_selection_inline" /> + + <Space + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" /> + + <Button + android:id="@+id/fdClear" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="right" + android:text="@string/clear" > + </Button> + </LinearLayout> + + <LinearLayout + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:layout_above="@+id/fdLinearLayoutList" + android:orientation="vertical" > + + <TextView + android:id="@+id/path" + android:layout_width="fill_parent" + android:layout_height="wrap_content" /> + + <ListView + android:id="@android:id/list" + android:layout_width="fill_parent" + android:layout_height="fill_parent" /> + + <TextView + android:id="@android:id/empty" + android:layout_width="fill_parent" + android:layout_height="fill_parent" + android:text="@string/no_data" /> + </LinearLayout> + +</RelativeLayout>
\ No newline at end of file diff --git a/main/src/main/res/layout/file_dialog_row.xml b/main/src/main/res/layout/file_dialog_row.xml new file mode 100644 index 00000000..c7a5f652 --- /dev/null +++ b/main/src/main/res/layout/file_dialog_row.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="fill_parent" + android:layout_height="fill_parent" > + + <ImageView + android:id="@+id/fdrowimage" + android:layout_width="wrap_content" + android:layout_height="35dp" + android:layout_alignParentLeft="true" + android:paddingLeft="3dp" + android:paddingRight="5dp" android:contentDescription="@string/file_icon"/> + + <TextView + android:id="@+id/fdrowtext" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignBottom="@+id/fdrowimage" + android:layout_alignTop="@+id/fdrowimage" + android:layout_toRightOf="@+id/fdrowimage" + android:gravity="center_vertical" + android:text="@+id/fdrowtext" + android:textAppearance="?android:attr/textAppearanceMedium" /> + + +</RelativeLayout>
\ No newline at end of file diff --git a/main/src/main/res/layout/file_select.xml b/main/src/main/res/layout/file_select.xml new file mode 100644 index 00000000..5e40b3a8 --- /dev/null +++ b/main/src/main/res/layout/file_select.xml @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2011 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<!-- A layout to select a certificate, akin to a file selector on web pages. --> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_margin="8dip" + android:gravity="center_vertical" > + + <Button + android:id="@+id/file_select_button" + style="@style/accountSetupButton" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentRight="true" + android:text="@string/file_select" /> + + <TextView + android:id="@+id/file_title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentLeft="true" + android:layout_alignParentTop="true" + android:layout_toLeftOf="@+id/file_select_button" + android:text="@string/client_certificate_title" + android:textStyle="bold" /> + + <TextView + android:id="@+id/file_selected_item" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentLeft="true" + android:layout_below="@+id/file_title" + android:layout_marginLeft="16dip" + android:layout_toLeftOf="@+id/file_select_button" + android:ellipsize="end" + android:singleLine="true" + android:text="@string/file_nothing_selected" /> + + <TextView + android:id="@+id/file_selected_description" + android:layout_width="wrap_content" + android:textIsSelectable="true" + android:layout_height="wrap_content" + android:layout_alignParentLeft="true" + android:layout_below="@+id/file_selected_item" + android:layout_marginLeft="16dip" + android:layout_toLeftOf="@+id/file_select_button" + android:ellipsize="end" /> + +</RelativeLayout>
\ No newline at end of file diff --git a/main/src/main/res/layout/fragment_senddump.xml b/main/src/main/res/layout/fragment_senddump.xml new file mode 100644 index 00000000..2f573de5 --- /dev/null +++ b/main/src/main/res/layout/fragment_senddump.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/RelativeLayout1" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_gravity="center" + android:orientation="vertical" > + + <Button + android:id="@+id/senddump" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_centerHorizontal="true" + android:layout_centerVertical="true" + android:text="@string/send_minidump" /> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_below="@id/senddump" + android:layout_centerHorizontal="true" + android:text="@string/send_minidump_summary" /> + +</RelativeLayout>
\ No newline at end of file diff --git a/main/src/main/res/layout/keystore_selector.xml b/main/src/main/res/layout/keystore_selector.xml new file mode 100644 index 00000000..28a51836 --- /dev/null +++ b/main/src/main/res/layout/keystore_selector.xml @@ -0,0 +1,68 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2011 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<!-- A layout to select a certificate, akin to a file selector on web pages. --> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_margin="8dip" + android:gravity="center_vertical"> + + <Button + android:id="@+id/select_keystore_button" + style="@style/accountSetupButton" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentRight="true" + android:text="@string/select"/> + + <TextView + android:id="@+id/title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentLeft="true" + android:layout_alignParentTop="true" + android:layout_toLeftOf="@+id/select_keystore_button" + android:text="@string/client_certificate_title" + android:textStyle="bold"/> + + <TextView + android:id="@+id/aliasname" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentLeft="true" + android:layout_below="@+id/title" + android:layout_marginLeft="16dip" + android:layout_toLeftOf="@+id/select_keystore_button" + android:ellipsize="end" + android:singleLine="true" + android:text="@string/no_certificate"/> + + <TextView + android:id="@+id/alias_certificate" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentLeft="true" + android:layout_marginLeft="16dip" + android:layout_below="@id/aliasname" + android:layout_toLeftOf="@+id/select_keystore_button" + android:ellipsize="end" + android:singleLine="true" + /> + <!-- android:textColor="@color/text_secondary_color" --> + +</RelativeLayout>
\ No newline at end of file diff --git a/main/src/main/res/layout/log_fragment.xml b/main/src/main/res/layout/log_fragment.xml new file mode 100644 index 00000000..0b428070 --- /dev/null +++ b/main/src/main/res/layout/log_fragment.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <LinearLayout + android:layout_height="wrap_content" + android:layout_width="match_parent"> + + <include layout="@layout/log_silders"/> + </LinearLayout> + + <TextView + android:text="@string/speed_waiting" + android:singleLine="true" + android:id="@+id/speed" + tools:ignore="InconsistentLayout" + android:layout_width="match_parent" + android:layout_height="wrap_content"/> + + <ListView + android:id="@android:id/list" + android:transcriptMode="normal" + android:layout_width="fill_parent" + android:layout_height="fill_parent"/> + +</LinearLayout>
\ No newline at end of file diff --git a/main/src/main/res/layout/log_silders.xml b/main/src/main/res/layout/log_silders.xml new file mode 100644 index 00000000..0ecb5daa --- /dev/null +++ b/main/src/main/res/layout/log_silders.xml @@ -0,0 +1,61 @@ +<?xml version="1.0" encoding="utf-8"?> + + +<LinearLayout + xmlns:tools="http://schemas.android.com/tools" + xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:id="@+id/logOptionsLayout" + android:visibility="gone" + tools:visibility="visible" + android:layout_width="wrap_content" + android:layout_height="wrap_content"> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/log_verbosity_level"/> + + + <de.blinkt.openvpn.views.SeekBarTicks + android:id="@+id/LogLevelSlider" + android:layout_width="300dp" + android:layout_height="wrap_content" + tools:max="5" + android:indeterminate="false"/> + + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/timestamps"/> + + <RadioGroup + android:id="@+id/timeFormatRadioGroup" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal"> + + <RadioButton + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/timestamps_none" + android:id="@+id/radioNone" + /> + + <RadioButton + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/timestamp_short" + android:id="@+id/radioShort" + /> + + <RadioButton + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/timestamp_iso" + android:id="@+id/radioISO" + /> + + + </RadioGroup> +</LinearLayout>
\ No newline at end of file diff --git a/main/src/main/res/layout/log_window.xml b/main/src/main/res/layout/log_window.xml new file mode 100644 index 00000000..56c3e349 --- /dev/null +++ b/main/src/main/res/layout/log_window.xml @@ -0,0 +1,7 @@ +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/container" + android:layout_width="match_parent" + android:layout_height="match_parent" + tools:context=".LogWindow" + tools:ignore="MergeRootFrame" />
\ No newline at end of file diff --git a/main/src/main/res/layout/tlsremote.xml b/main/src/main/res/layout/tlsremote.xml new file mode 100644 index 00000000..a7bec953 --- /dev/null +++ b/main/src/main/res/layout/tlsremote.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="utf-8"?> +<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:padding="@dimen/stdpadding" + android:layout_height="match_parent" > + + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical" > + + <TextView + android:id="@+id/dialogHeader" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/enter_tlscn_dialog" /> + + <TextView + android:id="@+id/tlsremotenote" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="8sp" + android:text="@string/remotetlsnote" + android:textAppearance="?android:attr/textAppearanceSmall" + android:visibility="gone" /> + + <Spinner + android:id="@+id/x509verifytype" + android:layout_width="wrap_content" + android:layout_height="wrap_content" /> + + <EditText + android:id="@+id/tlsremotecn" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="20dp" + android:ems="10" + android:inputType="text" > + + <requestFocus /> + </EditText> + + </LinearLayout> + +</ScrollView>
\ No newline at end of file diff --git a/main/src/main/res/layout/userpass.xml b/main/src/main/res/layout/userpass.xml new file mode 100644 index 00000000..f67f998e --- /dev/null +++ b/main/src/main/res/layout/userpass.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="utf-8"?> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <EditText + android:id="@+id/username" + android:inputType="textEmailAddress" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="8dp" + android:layout_marginLeft="4dp" + android:layout_marginRight="4dp" + android:layout_marginBottom="4dp" + android:hint="@string/auth_username" /> + <EditText + android:id="@+id/password" + android:inputType="textPassword" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="4dp" + android:layout_marginLeft="4dp" + android:layout_marginRight="4dp" + android:layout_marginBottom="4dp" + android:hint="@string/password"/> + <CheckBox + android:id="@+id/show_password" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="4dp" + android:layout_marginLeft="4dp" + android:text="@string/show_password" + android:layout_marginRight="4dp" + /> + + <CheckBox + android:id="@+id/save_password" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="4dp" + android:layout_marginLeft="4dp" + android:text="@string/save_password" + android:layout_marginRight="4dp" + android:layout_marginBottom="16dp"/> + + +</LinearLayout>
\ No newline at end of file diff --git a/main/src/main/res/layout/viewconfig.xml b/main/src/main/res/layout/viewconfig.xml new file mode 100644 index 00000000..5ae34ef0 --- /dev/null +++ b/main/src/main/res/layout/viewconfig.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" > + + <TextView + android:id="@+id/configview" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + +</ScrollView>
\ No newline at end of file diff --git a/main/src/main/res/layout/vpn_list_item.xml b/main/src/main/res/layout/vpn_list_item.xml new file mode 100644 index 00000000..ae9350fa --- /dev/null +++ b/main/src/main/res/layout/vpn_list_item.xml @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2011 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center_vertical" + android:minHeight="?android:attr/listPreferredItemHeight" + android:focusable="false"> + + <LinearLayout + android:id="@+id/vpn_list_item_left" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" + android:background="?android:attr/selectableItemBackground" + android:gravity="center_vertical" + android:focusable="true"> + + <LinearLayout + android:id="@android:id/widget_frame" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:gravity="center_vertical" + android:orientation="vertical" /> + + <TextView + android:id="@+id/vpn_item_title" + tools:text="Vpn Name" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:ellipsize="marquee" + android:fadingEdge="horizontal" + android:singleLine="true" + android:textAppearance="?android:attr/textAppearanceMedium" /> + + </LinearLayout> + + <View + android:layout_width="2dip" + android:layout_height="match_parent" + android:layout_marginBottom="5dip" + android:focusable="false" + android:layout_marginTop="5dip" + android:background="@android:drawable/divider_horizontal_dark" /> + + <ImageView + android:id="@+id/quickedit_settings" + android:layout_width="wrap_content" + android:layout_height="fill_parent" + android:layout_gravity="center" + android:background="?android:attr/selectableItemBackground" + android:contentDescription="@string/configure_the_vpn" + android:paddingLeft="15dip" + android:paddingRight="?android:attr/scrollbarSize" + android:src="@drawable/ic_sysbar_quicksettings" + android:focusable="true"/> + +</LinearLayout>
\ No newline at end of file diff --git a/main/src/main/res/layout/vpn_profile_list.xml b/main/src/main/res/layout/vpn_profile_list.xml new file mode 100644 index 00000000..b8caa7c7 --- /dev/null +++ b/main/src/main/res/layout/vpn_profile_list.xml @@ -0,0 +1,68 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + android:paddingLeft="@dimen/stdpadding" + android:paddingRight="@dimen/stdpadding" > + + <ListView + android:descendantFocusability="afterDescendants" + android:id="@android:id/list" + android:layout_width="fill_parent" + android:layout_height="fill_parent" /> + + <LinearLayout + android:id="@android:id/empty" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="center" + android:orientation="vertical" > + + <TextView + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:text="@string/no_vpn_profiles_defined" + android:textAppearance="?android:attr/textAppearanceLarge" /> + + <Space + android:layout_width="match_parent" + android:layout_height="12sp" /> + + + <TextView + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:text="@string/openvpn_is_no_free_vpn" + android:autoLink="web" + android:textAppearance="?android:attr/textAppearanceMedium" /> + + <Space + android:layout_width="match_parent" + android:layout_height="12sp" /> + + + <TextView + android:id="@+id/add_new_vpn_hint" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + tools:ignore="SelectableText" /> + + <TextView + android:id="@+id/import_vpn_hint" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + tools:ignore="SelectableText" /> + + <Space + android:layout_width="match_parent" + android:layout_height="12sp" /> + + <TextView + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:text="@string/faq_hint" /> + </LinearLayout> + +</LinearLayout>
\ No newline at end of file diff --git a/main/src/main/res/layout/vpnstatus.xml b/main/src/main/res/layout/vpnstatus.xml new file mode 100644 index 00000000..eb7c53ee --- /dev/null +++ b/main/src/main/res/layout/vpnstatus.xml @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="utf-8"?> +<merge xmlns:tools="http://schemas.android.com/tools" + xmlns:android="http://schemas.android.com/apk/res/android"> + + <Space + android:layout_weight="1" + android:layout_width="wrap_content" + android:layout_height="wrap_content"/> + + + <TextView + android:text="@string/uploaded_data" + style="@style/logWindowStatusTitle"/> + + <TextView + style="@style/logWindowStatusText" + android:id="@+id/speedUp" + tools:text="4 Mbit/s 6.7 GB"/> + + <TextView + android:text="@string/downloaded_data" + style="@style/logWindowStatusTitle"/> + + <TextView + style="@style/logWindowStatusText" + android:id="@+id/speedDown" + tools:text="2 Mbit/s 4.7 GB"/> + + + <Space + android:layout_weight="1" + android:layout_width="wrap_content" + android:layout_height="wrap_content"/> + + + <TextView + android:text="@string/vpn_status" + style="@style/logWindowStatusTitle"/> + + <TextView + android:id="@+id/speedStatus" + tools:text="Connected" + style="@style/logWindowStatusText"/> + + +</merge>
\ No newline at end of file diff --git a/main/src/main/res/menu/configmenu.xml b/main/src/main/res/menu/configmenu.xml new file mode 100644 index 00000000..41130970 --- /dev/null +++ b/main/src/main/res/menu/configmenu.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <item
+ android:id="@+id/sendConfig"
+ android:icon="@android:drawable/ic_menu_share"
+ android:showAsAction="ifRoom|withText"
+ android:title="@string/send_config"
+ android:titleCondensed="@string/send"/>
+
+</menu>
\ No newline at end of file diff --git a/main/src/main/res/menu/import_menu.xml b/main/src/main/res/menu/import_menu.xml new file mode 100644 index 00000000..1bed5a6b --- /dev/null +++ b/main/src/main/res/menu/import_menu.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+ <item
+ android:id="@+id/cancel"
+ android:icon="@android:drawable/ic_menu_close_clear_cancel"
+ android:showAsAction="ifRoom|withText"
+ android:title="@android:string/cancel"
+ android:titleCondensed="@string/cancel"/>
+
+ <item
+ android:id="@+id/ok"
+ android:icon="@android:drawable/ic_menu_save"
+ android:showAsAction="ifRoom|withText"
+ android:title="@string/add_profile"
+ android:titleCondensed="@string/import_vpn"/>
+
+
+</menu>
\ No newline at end of file diff --git a/main/src/main/res/menu/logmenu.xml b/main/src/main/res/menu/logmenu.xml new file mode 100644 index 00000000..04592a26 --- /dev/null +++ b/main/src/main/res/menu/logmenu.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+
+
+ <item
+ android:id="@+id/toggle_time"
+ android:alphabeticShortcut="t"
+ android:icon="@android:drawable/ic_menu_view"
+ android:showAsAction="withText|ifRoom"
+ android:title="@string/logview_options" />
+
+ <item
+ android:id="@+id/clearlog"
+ android:icon="@android:drawable/ic_menu_delete"
+ android:showAsAction="ifRoom|withText"
+ android:title="@string/clear_log"
+ android:titleCondensed="@string/clear"/>
+ <item
+ android:id="@+id/send"
+ android:icon="@android:drawable/ic_menu_share"
+ android:showAsAction="ifRoom|withText"
+ android:title="@string/send_logfile"
+ android:titleCondensed="@string/send"/>
+
+ <item
+ android:id="@+id/cancel"
+ android:icon="@android:drawable/ic_menu_close_clear_cancel"
+ android:showAsAction="ifRoom|withText"
+ android:title="@string/cancel_connection_long"
+ android:titleCondensed="@string/cancel_connection"/>
+ <item
+ android:id="@+id/edit_vpn"
+ android:alphabeticShortcut="e"
+ android:icon="@android:drawable/ic_menu_edit"
+ android:showAsAction="withText|ifRoom"
+ android:title="@string/edit_vpn"/>
+
+</menu>
\ No newline at end of file diff --git a/main/src/main/res/menu/vpnpreferences_menu.xml b/main/src/main/res/menu/vpnpreferences_menu.xml new file mode 100644 index 00000000..71744d3c --- /dev/null +++ b/main/src/main/res/menu/vpnpreferences_menu.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:android="http://schemas.android.com/apk/res/android" > + <item + android:id="@+id/remove_vpn" + android:alphabeticShortcut="d" + android:icon="@android:drawable/ic_menu_delete" + android:showAsAction="withText|ifRoom" + android:title="@string/remove_vpn"/> + +</menu>
\ No newline at end of file diff --git a/main/src/main/res/values-ca/arrays.xml b/main/src/main/res/values-ca/arrays.xml new file mode 100755 index 00000000..8af4e790 --- /dev/null +++ b/main/src/main/res/values-ca/arrays.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string-array name="vpn_types"> + <item>Certificats</item> + <item>Fitxer PKCS12</item> + <item>Certificat Android</item> + <item>Usuari/Contrasenya</item> + <item>Claus Estàtiques</item> + <item>Usuari/Con + Certificats</item> + <item>Usuari/Con + PKCS12 </item> + <item>Usuari/Con + Android</item> + </string-array> + <string-array name="tls_directions_entries"> + <item>0</item> + <item>1</item> + <item>Sense especificar</item> + </string-array> + <string-array name="crm_entries"> + <item>No reconnection retries</item> + <item>One reconnection retry</item> + <item>Five reconnection retries</item> + <item>Fifty reconnection retries</item> + <item>Unlimited reconnection retries</item> + </string-array> +</resources> diff --git a/main/src/main/res/values-ca/strings.xml b/main/src/main/res/values-ca/strings.xml new file mode 100755 index 00000000..0145b0b1 --- /dev/null +++ b/main/src/main/res/values-ca/strings.xml @@ -0,0 +1,119 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string name="app">OpenVPN per Android</string> + <string name="address">Adreá del servidor:</string> + <string name="port">Port del servidor:</string> + <string name="location">Lloc</string> + <string name="select">Selecciona</string> + <string name="cancel">Cancel·la</string> + <string name="no_data">Sense informació</string> + <string name="useLZO">Compresió LZO</string> + <string name="client_no_certificate">Sense Certificat</string> + <string name="client_certificate_title">Certificat Client</string> + <string name="client_key_title">Clau del certificat client</string> + <string name="client_pkcs12_title">Fitxer PKCS12</string> + <string name="ca_title">Certificat CA</string> + <string name="about">Quan a</string> + <string name="vpn_type">Tipus</string> + <string name="pkcs12pwquery">Contrasenya PKCS12</string> + <string name="file_select">Selecciona…</string> + <string name="useTLSAuth">Utiltiza autenticació TLS</string> + <string name="tls_direction">Direcció TLS</string> + <string name="ipv6_dialog_tile">Introduïu l\'adreça/mascara de xarxa IPv6 en format CIDR Format (e.g. 2000:dd::23/64)</string> + <string name="ipv4_dialog_title">Introduïu l\'adreça/mascara de xarxa IPv4 en format CIDR (e.g. 1.2.3.4/24)</string> + <string name="ipv4_address">Adreça IPv4</string> + <string name="ipv6_address">Adreça IPv6</string> + <string name="auth_username">Usuari</string> + <string name="auth_pwquery">Contrasenya</string> + <string name="configure_the_vpn">Configura la VPN</string> + <string name="menu_add_profile">Afegeix un perfil</string> + <string name="add_profile_name_prompt">Introduïu un nom identificant el perfil</string> + <string name="profilename">Nom del perfil</string> + <string name="no_error_found">No s\'ha trobat cap error</string> + <string name="config_error_found">S\'ha trobat un error a la configuració</string> + <string name="vpn_shortcut">Acces directe de OpenVPN</string> + <string name="vpn_launch_title">Conecta a la VPN</string> + <string name="shortcut_profile_notfound">No s\'ha trobat el perfil especificat a l\'accès directe</string> + <string name="random_host_prefix">Prefix aleatoria del host</string> + <string name="route_rejected">La ruta ha estat refusas per Android</string> + <string name="cancel_connection">Desconecta</string> + <string name="clear_log">Neteja el registre</string> + <string name="title_cancel">Cancela la confirmació</string> + <string name="cancel_connection_query">Desconcta la conexió VPN/cancela l\'intent de conexió?</string> + <string name="remove_vpn">Eliminar VPN</string> + <string name="dns">DNS</string> + <string name="dns1_summary">Servidor DNS a utilitzar.</string> + <string name="dns_server">Servidor DNS</string> + <string name="default_route_summary">Redirecciona tot el trafic a través de la VPN</string> + <string name="use_default_title">Utilitza la ruta per defecte</string> + <string name="custom_routes_title">Rutes personalitzadse</string> + <string name="log_verbosity_level">Nivell de detall del registre</string> + <string name="custom_options_title">Opcions personalitzades</string> + <string name="edit_vpn">Edita la configuració VPN</string> + <string name="error">"Error: "</string> + <string name="clear">Neteja</string> + <string name="send_logfile">Envia el fitxer de registre</string> + <string name="send">Envia</string> + <string name="ics_openvpn_log_file">Fitxer de registre de ICS OpenVPN</string> + <string name="copied_entry">S\'ha copiat l\'entrada al porta-retalls</string> + <string name="tap_mode">Mode Tap</string> + <string name="faq_tap_mode">No es pot utiltizar el mode tap amb la api no rootejada. L\'aplicació no suporta tap</string> + <string name="faq">FAQ</string> + <string name="copying_log_entries">Copiant entrades de registre</string> + <string name="faq_shortcut">Acces directe per inciar</string> + <string name="encryption">Encriptació</string> + <string name="cipher_dialog_title">Introduïu el mètode d\'encriptació</string> + <string name="settings_auth">Autentificació/Encriptació</string> + <string name="file_explorer_tab">Explorador de fitxers</string> + <string name="inline_file_tab">Fitxer en linea</string> + <string name="error_importing_file">Error important el fitxer</string> + <string name="import_error_message">No s\'ha pogut importar el fitxer del sistema de fitxers</string> + <string name="inline_file_data">[[Inline file data]]</string> + <string name="menu_import">Importa el perfil d\'un fitxer ovpn</string> + <string name="menu_import_short">Importa</string> + <string name="import_content_resolve_error">No s\'ha pogut llegir el fitxer a importar</string> + <string name="error_reading_config_file">Error llegint el fitxer de configuració</string> + <string name="add_profile">afegir un Perfil</string> + <string name="import_done">S\'ha llegit el fitxer de configuració.</string> + <string name="import_vpn">Importa</string> + <string name="ipv4">IPv4</string> + <string name="ipv6">IPv6</string> + <string name="speed_waiting">Esperant el missatge d\'estat…</string> + <string name="converted_profile">Perfil importat</string> + <string name="converted_profile_i">Perfil importat %d</string> + <string name="broken_images">Imatges trencades</string> + <string name="private_key_password">Contrasenya de la clau privada</string> + <string name="password">Contrasenya</string> + <string name="file_icon">Icona del fitxer</string> + <string name="tls_authentication">Autentificació TLS</string> + <string name="generated_config">Configuració generada</string> + <string name="owner_fix">Corregir els permisos de /dev/tun</string> + <string name="generated_config_summary">Mostra el fitxer de configuració d\'OpenVPN generat</string> + <string name="edit_profile_title">Editant \"%s\"</string> + <string name="building_configration">Construint la configuració…</string> + <string name="netchange">Reconecta al canviar de xarxa</string> + <string name="netstatus">Estat de la xarxa %s</string> + <string name="select_file">Selecciona</string> + <string name="show_log_window">Mostra la finestra de registre</string> + <string name="translationby">Traducció al catala per Sergi Almacellas +<sergi@koolpi.com></string> + <string name="ipdns">IP i DNS</string> + <string name="basic">Bàsic</string> + <string name="routing">Ruting</string> + <string name="advanced">Avançat</string> + <string name="faq_howto_title">Inici rapid</string> + <string name="using_proxy">Utilitzant el proxy %1$s %2$d</string> + <string name="use_system_proxy">Utiliza el proxy del sistema</string> + <string name="onbootrestart">Torna a conectar al reiniciar</string> + <string name="ignore">Ignorar</string> + <string name="restart">Reinicia</string> + <string name="restart_vpn_after_change">Els canvis de configuració s\'apliquen desprès de reinicar la VPN. (Re)inicar la VPN ara?</string> + <string name="configuration_changed">S\'ha canviat la configuració</string> + <string name="faq_duplicate_notification_title">Notificacions duplicades</string> + <string name="no_vpn_profiles_defined">No s\'han definit cap perfil.</string> + <string name="faq_routing_title">Configuració del Ruting/Interficies</string> + <string name="openvpn_log">Registre OpenVPN</string> + <string name="import_config">Importa la configuració OpenVPN</string> + <string name="battery_consumption_title">Consum de la bateria</string> +</resources> diff --git a/main/src/main/res/values-cs/arrays.xml b/main/src/main/res/values-cs/arrays.xml new file mode 100755 index 00000000..f89d5b4d --- /dev/null +++ b/main/src/main/res/values-cs/arrays.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string-array name="vpn_types"> + <item>Certifikáty</item> + <item>PKCS12 Soubor</item> + <item>Android Certifikát</item> + <item>Jméno/Heslo</item> + <item>Statické klíče</item> + <item>Jméno/Heslo + Certifikát</item> + <item>Jméno/Heslo + PKCS12 </item> + <item>Jméno/Heslo + Android</item> + </string-array> + <string-array name="tls_directions_entries"> + <item>0 (server)</item> + <item>1 (klient)</item> + <item>Nespecifikováno</item> + </string-array> + <string-array name="crm_entries"> + <item>Opětovně nepřipojovat</item> + <item>Jeden pokus o připojení</item> + <item>Pět pokusů o připojení</item> + <item>Padesát pokusů o připojení</item> + <item>Neomezeně pokusů o připojení</item> + </string-array> +</resources> diff --git a/main/src/main/res/values-cs/strings.xml b/main/src/main/res/values-cs/strings.xml new file mode 100755 index 00000000..42e784c3 --- /dev/null +++ b/main/src/main/res/values-cs/strings.xml @@ -0,0 +1,308 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string name="app">OpenVPN pro Android</string> + <string name="address">Adresa serveru:</string> + <string name="port">Port serveru:</string> + <string name="location">Lokace</string> + <string name="cant_read_folder">Nelze přečíst adresář</string> + <string name="select">Zvolit</string> + <string name="cancel">Storno</string> + <string name="no_data">Žádná data</string> + <string name="useLZO">LZO komprese</string> + <string name="client_no_certificate">Žádný certifikát</string> + <string name="client_certificate_title">Klientský certifikát</string> + <string name="client_key_title">Klientský klíč</string> + <string name="client_pkcs12_title">PKCS12 soubor</string> + <string name="ca_title">CA certifikát</string> + <string name="no_certificate">Je třeba vybrat certifikát</string> + <string name="copyright_guicode">Zdrojové kódy a seznam problémů je na http://code.google.com/p/ics-openvpn/</string> + <string name="copyright_others">Tento program používá následující komponenty; viz zdrojový kód pro detaily o licenci</string> + <string name="about">O programu</string> + <string name="vpn_list_title">Profily</string> + <string name="vpn_type">Typ</string> + <string name="pkcs12pwquery">PKCS12 heslo</string> + <string name="file_select">Vyber…</string> + <string name="file_nothing_selected">Je třeba vybrat soubor</string> + <string name="useTLSAuth">Použij TLS autentikaci</string> + <string name="tls_direction">TLS řízení</string> + <string name="ipv6_dialog_tile">Zadej IPv6 adresu/masku v CIDR formátu (tj. 2000:dd::23/64)</string> + <string name="ipv4_dialog_title">Zadej IPv4 adresu/masku v CIDR formátu (tj. 1.2.3.4/24)</string> + <string name="ipv4_address">IPv4 adresa</string> + <string name="ipv6_address">IPv6 adresa</string> + <string name="custom_option_warning">Zadat vlastní nastavení. Používat opatrně. Poznámka, mnoho voleb okolo tun adaptéru nemůže být podporováno. Pokud si myslíte, že chybí podstatná volba, kontaktujte autora</string> + <string name="auth_username">Jméno</string> + <string name="auth_pwquery">Heslo</string> + <string name="static_keys_info">Pro statickou konfiguraci bude jako klíč použit autentizační klíč TLS</string> + <string name="configure_the_vpn">Konfigurace VPN</string> + <string name="menu_add_profile">Přidat profil</string> + <string name="add_profile_name_prompt">Zadej jméno identifikující nový profil</string> + <string name="duplicate_profile_name">Zadej prosím unikátní jméno profilu</string> + <string name="profilename">Jméno profilu</string> + <string name="no_keystore_cert_selected">Je třeba vybrat uživatelský certifikát</string> + <string name="no_error_found">Bez chyb</string> + <string name="config_error_found">Chyba v konfiguraci</string> + <string name="ipv4_format_error">Chyba při zpracování IPv4 adresy</string> + <string name="custom_route_format_error">Chyba při zpracování vlastního směrování</string> + <string name="pw_query_hint">(nechej prázdné pro dotazování, až bude potřeba)</string> + <string name="vpn_shortcut">OpenVPN zkratka</string> + <string name="vpn_launch_title">Připojit k VPN</string> + <string name="shortcut_profile_notfound">Profil zvolený ve zkratce nenalezen</string> + <string name="random_host_prefix">Náhodný prefix klienta</string> + <string name="random_host_summary">Přidej 6 náhodných znaků před jméno klienta (hostname)</string> + <string name="custom_config_title">Povolit vlastní nastavení</string> + <string name="custom_config_summary">Zadat vlastní nastavení. Používat opatrně!</string> + <string name="route_rejected">Směrování odmítnuto Androidem</string> + <string name="cancel_connection">Odpojit</string> + <string name="cancel_connection_long">Odpojit VPN</string> + <string name="clear_log">vymazat log</string> + <string name="title_cancel">Zrušit potvrzení</string> + <string name="cancel_connection_query">Odpojit/Zrušit připojování?</string> + <string name="remove_vpn">Odstranit VPN</string> + <string name="check_remote_tlscert">Kontrolovat, zda server používá certifikát s rozšířením TLS Server (--remote-cert-tls server)</string> + <string name="check_remote_tlscert_title">Očekávat serverový TLS certifikát</string> + <string name="remote_tlscn_check_summary">Kontrola DN v certifikátu vzdáleného serveru</string> + <string name="remote_tlscn_check_title">Ověření jména certifikátu</string> + <string name="enter_tlscn_dialog">Specifikuj způsob kontroly DN v certifikátu vzdáleného serveru (př. C=DE, L=Paderborn, OU=Avian IP Carriers, CN=openvpn.blinkt.de)\n\nSpecifikuj kompletní DN nebo RDN (openvpn.blinkt.de v příkladu) nebo RDN prefix pro verifikaci.\n\nPři použití RDN prefixu, \"Server\" sedí na \"Server-1\" i \"Server-2\"\n\nJe-li RDN pole prázdné, kontroluje se proti jménu serveru.\n\nPro více detailů, viz manuálová stránka OpenVPN 2.3.1+, přepínač —verify-x509-name</string> + <string name="enter_tlscn_title">Předmět vzdáleného certifikátu</string> + <string name="tls_key_auth">Zapnout autentikaci pomocí TLS klíče</string> + <string name="tls_auth_file">TLS autentikační soubor</string> + <string name="pull_on_summary">Použít IP adresu, směrování a časování přijaté od serveru.</string> + <string name="pull_off_summary">Žádné informace od serveru nevyžadovat. Nastavení je potřeba zadat níže.</string> + <string name="use_pull">Automaticky</string> + <string name="dns">DNS</string> + <string name="override_dns">Přepsat DNS nastavení</string> + <string name="dns_override_summary">Použit vlastní DNS server</string> + <string name="searchdomain">Doména pro hledání</string> + <string name="dns1_summary">Adresa primárního DNS serveru</string> + <string name="dns_server">Primární DNS server</string> + <string name="secondary_dns_message">Adresa záložního DNS serveru, pokud se nelze připojit k primárnímu.</string> + <string name="backup_dns">Záložní DNS server</string> + <string name="ignored_pushed_routes">Ignorovat přijaté</string> + <string name="ignore_routes_summary">Ignorovat směrování, které zaslal server.</string> + <string name="default_route_summary">Přesměrovat všechen provoz skrz VPN</string> + <string name="use_default_title">Použít jako výchozí</string> + <string name="custom_route_message">Zadat vlastní směrování. Zadej cíle v CIDR formátu. \"10.0.0.0/8 2002::/16\" nasměruje sítě 10.0.0.0/8 a 2002::/16 skrz VPN.</string> + <string name="custom_routes_title">Vlastní směrování</string> + <string name="log_verbosity_level">Ukecanost logu</string> + <string name="float_summary">Povol autentifikované pakety z libovolné IP</string> + <string name="float_title">Povol plovoucí server</string> + <string name="custom_options_title">Vlastní nastavení</string> + <string name="edit_vpn">Změnit nastavení VPN</string> + <string name="remove_vpn_query">Odstranit VPN profil \'%s\'?</string> + <string name="tun_error_helpful">Na některých ICS systémech může být oprávnění pro /dev/tun špatně nastavené, nebo tun modul může zcela chybět. Pro systém s CM9 zkus využít opravy vlastnictví v obecném nastavení</string> + <string name="tun_open_error">Chyba při otvírání tun zařízení</string> + <string name="error">"Chyba: "</string> + <string name="clear">Vymazat</string> + <string name="last_openvpn_tun_config">Otevření rozhraní tun:</string> + <string name="local_ip_info">Místní IPv4: %1$s/%2$d IPv6: %3$s MTU: %4$d</string> + <string name="dns_server_info">DNS server: %1$s, Doména: %2$s</string> + <string name="ip_not_cidr">Získány informace o rozhraní %1$s a %2$s, předpokládám, že druhá adresa je adresa vzdáleného kolegy. Používám /32 masku pro místní IP adresu. Mód OpenVPN je \"%3$s\".</string> + <string name="route_not_cidr">%1$s a %2$s jako IP adresy s CIDR maskou nedávají smysl, používám /32 jako masku.</string> + <string name="route_not_netip">Směrování opraveno z %1$s/%2$s na %3$s/%2$s</string> + <string name="keychain_access">Nelze přistoupit k Androidímu úložišti certifikátů. To může být způsobeno aktualizací firmwaru nebo obnovováním aplikace a jejího nastavení ze zálohy. Uprav VPN profil a znovu vyber certifikát pro vytvoření patřičných povolení.</string> + <string name="version_info">%1$s %2$s</string> + <string name="send_logfile">Odeslat soubor s logem</string> + <string name="send">Odeslat</string> + <string name="ics_openvpn_log_file">ICS OpenVPN logovací soubor</string> + <string name="copied_entry">Záznam z logu zkopírován do schránky</string> + <string name="tap_mode">Tap mód</string> + <string name="faq_tap_mode">Tap mód není možný bez rootovského VPN API, proto tato aplikace nemá podporu pro tap</string> + <string name="tap_faq2">Opět? Děláš si srandu? Ne, tap mód opravdu není podporován a další maily na tom nic nezmění.</string> + <string name="tap_faq3">Potřetí? Ve skutečnosti, šlo by napsat emulátor tap zařizení pomocí tun, které by patřičně zpracovávalo informace z druhé vrstvy. Ale tento emulátor by také musel implementovat ARP a DHCP. Nejsem si vědom, že by někdo tímto směrem něco podnikl. Kontaktuj mne, pokud máš zájem toto naprogramovat.</string> + <string name="faq">FAQ</string> + <string name="copying_log_entries">Kopírování záznamů z logu</string> + <string name="faq_copying">Pro zkopírování jednoho záznamu stačí dlouze zmáčknout požadovaný záznam. Pro zkopírování/odeslání celého logu použij možnost Odeslat soubor s logem. Pokud není tlačítko viditené v uživatelském rozhraní, zkus použít to hardwarové.</string> + <string name="faq_shortcut">Zkratka na spuštění</string> + <string name="faq_howto_shortcut">Můžeš umístit zástupce pro spuštění OpenVPN na plochu. V závislosti na úvodní obrazovce budeš muset přidat buď zástupce nebo widget.</string> + <string name="no_vpn_support_image">Tvůj obrázek není podporovaný rozhraním VPNService, je mi líto :-(</string> + <string name="encryption">Šifrování</string> + <string name="cipher_dialog_title">Zadej šifrovací metodu</string> + <string name="chipher_dialog_message">Zadej šifrovací algoritmus. Ponech prázdné pro výchozí šifru.</string> + <string name="auth_dialog_message">Zadej algoritmus pro autentizaci. Nech prázdné pro výchozí algoritmus.</string> + <string name="settings_auth">Autentizace/Šifrování</string> + <string name="file_explorer_tab">Prohlížeč souború</string> + <string name="inline_file_tab">Vložený soubor</string> + <string name="error_importing_file">Chyba při importu souboru</string> + <string name="import_error_message">Nemohu importovat soubor ze souborového systému</string> + <string name="inline_file_data">[[Vložená data]]</string> + <string name="opentun_no_ipaddr">Odmítám otevřít tun zařízení bez informace o IP</string> + <string name="menu_import">Importovat profil z ovpn souboru</string> + <string name="menu_import_short">Import</string> + <string name="import_content_resolve_error">Nemohu přečíst profil k importu</string> + <string name="error_reading_config_file">Chyba při čtení konfiguračního souboru</string> + <string name="add_profile">přidat profil</string> + <string name="import_could_not_open">Nemohu najít soubor %1$s zmiňovaný v importovaném profilu</string> + <string name="importing_config">Importuji nastavení z %1$s</string> + <string name="import_warning_custom_options">V konfiguraci bylo několik nastavení, která nejsou mapována na uživateské rozhraní. Toto nastavení bylo přidáno jako vlastní konfigurace. Vlastní konfigurace je zobrazena níže:</string> + <string name="import_done">Dočetl jsem konfigurační soubor.</string> + <string name="nobind_summary">Nevázat se k místní adrese a portu</string> + <string name="no_bind">Nesvazovat se</string> + <string name="import_configuration_file">Importovat nastavení ze souboru</string> + <string name="faq_security_title">Úvaha o bezpečnosti</string> + <string name="faq_security">\"Protože OpenVPN je citlivá na bezpečnost je na místě několik poznámek. Všechna data na SD kartě jsou už z principu nezabezpečená. Každá aplikace je může číst (například ani tento program nepotřebuje žádná speciǎlní práva pro SD kartu). Data této aplikace může přečist jen aplikace sama. Použitím importu pro certifikáty/klíče jsou data uložena do VPN profilu. VPN profily jsou přístupné pouze pro tuto aplikaci. (Nezapomeň ale potom smazat kopie z SD karty.) Ale i když jsou data čitelná jen touto aplikací, nejsou nijak šifrována. Je-li zařízení rootnuté nebo nějak jinak upravené, existuje možnost získat tyto data. Uložená hesla jsou také v čitelné podobě. Pro pkcs12 certifikáty je velmi doporučeno využít importu do androidího úložiště.</string> + <string name="import_vpn">Import</string> + <string name="broken_image_cert_title">Chyba při zobrazení výběru certifikátu</string> + <string name="broken_image_cert">Vyjímka při pokusu o zobrazení Android 4.0+ dialogu pro výběr certifikátu. Toto je standardní funkce Androidu 4.0+, takže k této chybě nemělo vůbec dojít, možná je chyba v podpoře certifikátů ve tvém systému</string> + <string name="ipv4">IPv4</string> + <string name="ipv6">IPv6</string> + <string name="speed_waiting">Čekám na zprávu o stavu…</string> + <string name="converted_profile">importovaný profil</string> + <string name="converted_profile_i">importovaný profil %d</string> + <string name="broken_images">Rozbité systémy</string> + <string name="broken_images_faq"><p> Oficiální HTC obrazy jsou známy tím, že mají zvláštní problémy se směrováním síťového tok skrze tunel (viz také < href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=18\" > problém 18 </a> v bug trackeru.)</p> <p> Starší oficiální obrazy SONY Xperia Arc S a Xperia Ray zcela postrádaly VPNService. (Viz také < href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=29\" > problém 29 </a> v bug trackeru.)</p> <p> Na vlastních obrazech Tun modul může chybět nebo mít špatně nastavená práva. Některé obrazy CM9 potřebují povolené \"Opravit vlastnictví\" v nastavení.</p> <p>Nejdůležitější: Pokud má zařízení poškozený Android obraz, oznam to výrobci. Čím více lidí oznámí problém výrobci, tím větší je pravděpodobnost, že to opraví.</p></string> + <string name="pkcs12_file_encryption_key">Šifrovací klíč PKCS12</string> + <string name="private_key_password">Heslo k soukromému klíči</string> + <string name="password">Heslo</string> + <string name="file_icon">ikona souboru</string> + <string name="tls_authentication">TLS autentikace</string> + <string name="generated_config">Vygenerované nastavení</string> + <string name="generalsettings">Nastavení</string> + <string name="owner_fix_summary">Pokusit se nastavit vlastníka /dev/tun zařízení. Na některých systémech s CM9 je toto potřeba pro zprovoznění VPNService API. Vyžaduje root zařízení.</string> + <string name="owner_fix">Opravit vlastnictví /dev/tun</string> + <string name="generated_config_summary">Zobrazí vygenerované nastavení OpenVPN</string> + <string name="edit_profile_title">Úprava \"%s\"</string> + <string name="building_configration">Vytvářím konfiguraci…</string> + <string name="netchange_summary">Zapnutím této volby bude vynuceno opětovné připojení, pokud se změní stav sítě (např. z WiFi na mobilní síť a zpět)</string> + <string name="netchange">Opětovně připojit při změně sítě</string> + <string name="netstatus">Stav sítě: %s</string> + <string name="extracahint">CA certifikát je obvykle získán z Androidího úložiště. Zadej samostatný certifikát, pokud dostáváš chybu při verifikaci.</string> + <string name="select_file">Vyber</string> + <string name="keychain_nocacert">Žádný CA certifikát nebyl získán z úložiště, autentikace pravděpodobně selže.</string> + <string name="show_log_summary">Zobrazit okno s logem při připojování. okno lze vždy otevřít z notifikace.</string> + <string name="show_log_window">Zobrazit okno s logem</string> + <string name="mobile_info">Spuštěno na %1$s (%2$s) %3$s, Android API %4$d</string> + <string name="error_rsa_sign">Chyba při podepisování klíčem %1$s: %2$s</string> + <string name="faq_system_dialogs">VPN varování při připojování oznamující o možnosti přesměrování veškerého provozu je vynuceno systémem, aby se zabránilo zneužití VPNService API.\nNotifikace (symbol s klíčem) je také vynucena systémem, aby signalizovala odchozí VPN spojení. Na některých systémech přehrává notifikace i zvuk.\nAndroid zavedl tyto dialogy pro tvoji osobní bezpečnost a ujistil se, že nejdou obejít. (Někdu to bohužel zahrnuje i zvuk notifikace.)</string> + <string name="faq_system_dialogs_title">Varování při připojení a zvuková notifikace</string> + <string name="translationby">Českou lokalizaci zpracoval Jan Baier <baier.jan@gmail.com></string> + <string name="ipdns">IP a DNS</string> + <string name="basic">Základní nastavení</string> + <string name="routing">Směrování</string> + <string name="obscure">Skryté OpenVPN volby. Normálně nejsou nutné.</string> + <string name="advanced">Pokročilé</string> + <string name="export_config_title">ICS OpenVPN nastavení</string> + <string name="warn_no_dns">Žádné DNS servery nejsou použity. Překlad jmen nemusí fungovat. Zvaž nastavení vlastních DNS serverů. Též dbej na to, že Android bude nadále používat nastavení proxy určené pro mobilní/Wi-Fi připojení, pokud nejsou nastaveny žádné servery DNS.</string> + <string name="dns_add_error">Nemohu přidat DNS server \"%1$s\", odmítnuto systémem: %2$s</string> + <string name="ip_add_error">Nelze nastavit IP adresu \"%1$s\", odmítnuto systémem: %2$s</string> + <string name="faq_howto"><p>Získej fungující nastavení (otestované na tvém počítači nebo stažené od poskytovatele/zaměstnavatele).</p><p>Pokud je to jeden soubor bez extra pem/pks12 souborů, můžeš ho poslat emailem jako přílohu. Pokud je souborů více, ulož je na SD kartu.</p><p>Klepni na přilohu mailu/Použij ikonu adresáře v seznamu VPN pro import nastavení.</p><p>Pokud se zobrazí chyby o chybějících souborech, ulož je na SD kartu.</p><p>Pro přidání importované VPN do seznamu, klepni na symbol pro uložení.</p><p>Pro připojení k VPN klepni na její jméno.</p><p>Pokud se v logu objeví varování nebo chyby, pokus se jim porozumět a opravit nastavení.</p> </string> + <string name="faq_howto_title">Rychlý start</string> + <string name="setting_loadtun_summary">pokus se nahrát jaderný modul tun.ko před pokusem o připojení. Vyžaduje rootnuté zařízení.</string> + <string name="setting_loadtun">Nahrát tun modul</string> + <string name="importpkcs12fromconfig">Importovat PKCS12 z konfigurace do Andoidího úložiště</string> + <string name="getproxy_error">Chyba při zjišťování nastavení proxy: %s</string> + <string name="using_proxy">Používám proxy %1$s %2$d</string> + <string name="use_system_proxy">Použít systémovou proxy</string> + <string name="use_system_proxy_summary">K připojení použít systémové nastavení pro HTTP/HTTPS.</string> + <string name="donatewithpaypal">K přispění můžeš využít <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;cmd=_s-xclick\">PayPal</a> </string> + <string name="onbootrestartsummary">OpenVPN se opětovně připojí k VPN, pokud byla aktivní před vypnutím/restartem systému. Přečti si oddíl o varování před připojením než použiješ tuto možnost.</string> + <string name="onbootrestart">Znovu připoj po restartu</string> + <string name="ignore">Ignorovat</string> + <string name="restart">Restartovat</string> + <string name="restart_vpn_after_change">Změna nastavení začne platit až po restartu VPN. Restartovat teď?</string> + <string name="configuration_changed">Nastavení změněno</string> + <string name="log_no_last_vpn">Nemohu zjistit naposledy připojený profil k úpravě</string> + <string name="faq_duplicate_notification_title">Zdvojená notifikace</string> + <string name="faq_duplicate_notification">Pokud je Android pod velkým tlakem (na RAM paměť), aplikace a služby, které nejsou zrovna potřeba, jsou odstraněny z aktivní paměti. To ukončí odchozí VPN spojení. K zajištění, že OpenVPN spojení přežije, služba běží s vysokou prioritou. Aby mohla služba běžet s vysokou prioritou, musí zobrazit notifikaci. Notifikace s klíčem je vynucena systémem (jak je popsáno v jiném oddílu) a nepočítá se jako aplikační notifikace pro účely běhu s vysokou prioritou.</string> + <string name="no_vpn_profiles_defined">není definován VPN profil.</string> + <string name="add_new_vpn_hint">Použij ikonu <img src=\"ic_menu_add\"/> k přidání nové VPN</string> + <string name="vpn_import_hint">Použij ikonu <img src=\"ic_menu_archive\"/> k imporu existujícího (.ovpn nebo .conf) profilu z SD karty.</string> + <string name="faq_hint">Ujisti se, že jsi si pročetl FAQ. Je zde nápověda pro rychlý start.</string> + <string name="faq_routing_title">Nastavení směrování/rozhraní</string> + <string name="faq_routing">Konfigurace směrování a rozhraní není pomocí tradičního příkazu ifconfig/route, ale pomocí rozhraní VPNService API. To má za následek jinou konfiguraci směrování než na jiných operačních systémech. Konfigurace tvoří pouze IP tunelového rozhraní a sítě, které by měly být směrované přes toto rozhraní. Zejména žádná adresa druhé strany nebo adresa brány není zapotřebí. Ani nejsou potřeba speciální trasy k VPN serveru (například při používání přesměrování). Aplikace bude následně ignorovat toto nastavení při importu konfigurace. Aplikace s VPNService API zajišťuje, že připojení k serveru není směrováno přes VPN tunel. Vzhledem k tomu, že pouze specifické sítě mají být směrovány přes tunel, není podporováno směrování některých cest mimo tunel (např. route x.x.x.x y.y.y.y net_gateway). Aktuální konfigurace VPNService při navazování spojení je zobrazeno v logovacím okně.</string> + <string name="persisttun_summary">Nevracej se ke spojení mimo VPN, zatímco se OpenVPN připojuje.</string> + <string name="persistent_tun_title">Trvalý tun</string> + <string name="openvpn_log">OpenVPN Log</string> + <string name="import_config">Importovat OpenVPN nastavení</string> + <string name="battery_consumption_title">Spotřeba baterie</string> + <string name="baterry_consumption">V testech se jako hlavní důvod vysoké spotřeby baterie ukázaly keepalive pakety. Většina OpenVPN serverů má v konfiguraci něco jako \'keepalive 10 60\', což znamená posílání paketů každých deset vteřin. <p> Tyto pakety jsou malé a neznamenají velký provoz, ale udržují mobilní síť aktivní a zvyšují spotřebu energie. (Viz také <a href=\"http://developer.android.com/training/efficient-downloads/efficient-network-access.html#RadioStateMachine\">The Radio State Machine | Android Developers</a>)<p> Toto nastavení nelze změnit na klientské straně. Jen administrátor OpenVPN může toto nastavení změnit. <p> Bohužel používání keepalive hodnot větších než 60 vteřin spolu s UDP může způsobovat problémy s některými NATy, které ukončují po krátkém čase spojení. Použití TCP s dlouhým keepalive funguje, ale má problém \"TCP přes TCP\" (Viz <a href=\"http://sites.inka.de/bigred/devel/tcp-tcp.html\">Proč je TCP přes TCP špatný nápad</a>)</string> + <string name="faq_tethering">Androidí funkce tetheringu (přes WiFi, USB, nebo Bluetooth) a VPService API (používané tímto programem) spolu nepracují. Více detailů viz <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=34\">problém #34</a></string> + <string name="vpn_tethering_title">VPN a tethering</string> + <string name="connection_retries">Opakování připojení</string> + <string name="reconnection_settings">Nastavení obnovení</string> + <string name="connectretrymessage">Počet vteřin mezi pokusy o připojení.</string> + <string name="connectretrywait">Vteřin mezi připojeními</string> + <string name="minidump_generated">OpenVPN neočekávaně havarovalo. Zvaž možnost použití volby poslat Minidump z hlavního menu</string> + <string name="send_minidump">Poslat Minidump vývojáři</string> + <string name="send_minidump_summary">Poslat ladící informace o poslední havárii vývojáři</string> + <string name="notifcation_title">OpenVPN - %s</string> + <string name="session_ipv4string">%1$s - %2$s</string> + <string name="session_ipv6string">%1$s - %3$s, %2$s</string> + <string name="state_connecting">Připojuji se</string> + <string name="state_wait">Čekání na odpověď serveru</string> + <string name="state_auth">Ověřuji autorizaci</string> + <string name="state_get_config">Stahuji konfiguraci klienta</string> + <string name="state_assign_ip">Nastavuji IP adresu</string> + <string name="state_add_routes">Přidávám trasy</string> + <string name="state_connected">Připojeno</string> + <string name="state_disconnected">Odpojit</string> + <string name="state_reconnecting">Obnovuji připojení</string> + <string name="state_exiting">Ukončuji</string> + <string name="state_noprocess">Neběží</string> + <string name="state_resolve">Překlad názvů</string> + <string name="state_tcp_connect">Připojuji (TCP)</string> + <string name="state_auth_failed">Přihlášení nebylo úspěšné</string> + <string name="state_nonetwork">Čekání na použitelnou síť</string> + <string name="statusline_bytecount">↓%2$s/s %1$s - ↑%4$s/s %3$s</string> + <string name="notifcation_title_notconnect">Nepřipojeno</string> + <string name="start_vpn_title">Připojování k VPN %s</string> + <string name="start_vpn_ticker">Připojování k VPN %s</string> + <string name="jelly_keystore_alphanumeric_bug">Některé verze Androidu 4.1 mají problém, pokud je ve jméně certifikátu obsažen jiný než alfanumerický znak (mezera, podtržítko, mínus). Zkus reimportovat certifikát bez speciálních znaků</string> + <string name="encryption_cipher">Šifrovací algoritmus</string> + <string name="packet_auth">Ověřování paketů</string> + <string name="auth_dialog_title">Zadej způsob ověřování paketů</string> + <string name="mobile_info_extended">Běží na %1$s (%2$s) %3$s, Android API %4$d, verze %5$s, %6$s</string> + <string name="built_by">sestaveno od %s</string> + <string name="debug_build">ladící verze</string> + <string name="official_build">oficiální verze</string> + <string name="make_selection_inline">Zkopírovat do profilu</string> + <string name="crashdump">Havarijní výpis</string> + <string name="add">Přidat</string> + <string name="send_config">Odeslat konfigurační soubor</string> + <string name="complete_dn">Kompletní DN</string> + <string name="remotetlsnote">Tvá importovaná konfigurace používá ZASTARALÉ nastavení tls-remote, které používá jiný formát DN.</string> + <string name="rdn">RDN (běžné jméno)</string> + <string name="rdn_prefix">RDN prefix</string> + <string name="tls_remote_deprecated">tls-remote (ZASTARALÉ)</string> + <string name="help_translate">Můžeš pomoci s překladem, navštiv http://crowdin.net/project/ics-openvpn/invite</string> + <string name="prompt">%1$s se pokouší o kontrolu %2$s</string> + <string name="remote_warning">Pokračováním dáváš aplikaci oprávnění pro kompletní kontrolu OpenVPN a k zachytávání veškerého síťového provozu. <b>Nepotvrzuj, pokud nevěříš aplikaci.</b> V opačném případě riskuješ napadení nebezpečným softwarem</string> + <string name="remote_trust">Věřím této aplikaci.</string> + <string name="no_external_app_allowed">Žádné aplikaci není povoleno použít externí API</string> + <string name="allowed_apps">Povolené aplikace: %s</string> + <string name="clearappsdialog">Vyčistit seznam povolených aplikací?\nSoučasný seznam povolených aplikací:\n\n%s</string> + <string name="screenoff_summary">\"Pozastavit VPN, pokud je obrazovka vypnutá a za posledních 60 vteřin se přeneslo méně než 64 kB. Pokud je volba \"Trvalé TUN\" povolena, pozastavení VPN dostane zařízení do stavu BEZ konektivity. Bez \"Trvalé TUN\" možnosti nebude mít zařízení VPN připojení (ochranu).</string> + <string name="screenoff_title">Pozastavit VPN připojení při vypnutí obrazovky</string> + <string name="screenoff_pause">Pozastavit připojení při vypnuté obrazovce: méně než %1$s za %2$s vteřin</string> + <string name="screen_nopersistenttun">Varování: \"Trvalý TUN\" není pro tuto VPN povolen. Provoz použije při vypnuté obrazovce normální internetové připojení.</string> + <string name="save_password">Uložit heslo</string> + <string name="pauseVPN">Pozastavit VPN</string> + <string name="resumevpn">Obnovit VPN</string> + <string name="state_userpause">Pozastavení VPN vyžádáno uživatelem</string> + <string name="state_screenoff">VPN pozastaveno - vypnutá obrazovka</string> + <string name="device_specific">Hacky specifické pro zařízení</string> + <string name="cannotparsecert">Nelze zobrazit informace o certifikátu</string> + <string name="appbehaviour">Chování aplikace</string> + <string name="vpnbehaviour">Chování VPN</string> + <string name="allow_vpn_changes">Povolit změny VPN profilů</string> + <string name="hwkeychain">Hardwarové úložiště:</string> + <string name="permission_icon_app">Ikona aplikace snažící se použít OpenVPN pro Android</string> + <string name="faq_vpndialog43">"Počínaje Androidem 4.3, VPN konfirmace je chráněná proti \"překryvným aplikacím\". Výsledkem je dialog nereagující na dotyk. Pokud máš aplikaci používající překryv, může to způsobit toto chování. Pokud nalezneš škodlivou aplikaci, kontaktuj jejího autora. Tento problém ovlivňuje všechny VPN aplikace na Androidu 4.3 a vyšší. Viz také <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=185\">Problém 185<a> pro další detaily."</string> + <string name="faq_vpndialog43_title">VPN potvrzovací dialog na Androidu 4.3 a vyšší</string> + <string name="donatePlayStore">Případně mě můžete sponzorovat přes Play Store:</string> + <string name="thanks_for_donation">Díky za sponzorováni %s!</string> + <string name="logCleared">Log vyčištěn.</string> + <string name="show_password">Ukázat heslo</string> + <string name="keyChainAccessError">Chyba přístupu ke KeyChain: %s</string> + <string name="timestamp_short">Krátký</string> + <string name="timestamp_iso">ISO</string> + <string name="timestamps">Časové značky</string> + <string name="timestamps_none">Žádný</string> + <string name="uploaded_data">Nahrávání</string> + <string name="downloaded_data">Stahování</string> + <string name="vpn_status">VPN stav</string> + <string name="logview_options">Zobrazit možnosti</string> + <string name="unhandled_exception">Neošetřená výjimka: %1$s\n\n%2$s</string> + <string name="unhandled_exception_context">%3$s: %1$s\n\n%2$s</string> + <string name="full_licenses">Plné licence</string> +</resources> diff --git a/main/src/main/res/values-de/arrays.xml b/main/src/main/res/values-de/arrays.xml new file mode 100755 index 00000000..930ac58c --- /dev/null +++ b/main/src/main/res/values-de/arrays.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string-array name="vpn_types"> + <item>Zertifikate</item> + <item>PKCS12 Datei</item> + <item>Android Zertifikat Speicher</item> + <item>Benutzerame/Passwort</item> + <item>Statische Schlüssel</item> + <item>Nutzer/PW + Zertifikate</item> + <item>Nutzer/PW + PKCS12 </item> + <item>Nutzer/PW + Android</item> + </string-array> + <string-array name="tls_directions_entries"> + <item>0</item> + <item>1</item> + <item>Unspezifiziert</item> + </string-array> + <string-array name="crm_entries"> + <item>Keine erneuter Verbindungsversuch</item> + <item>Ein Versuch wieder zuverbinden</item> + <item>Fünf Verbindungsversuche</item> + <item>Fünfzig Verbingsversuche</item> + <item>Unbegrenzte Anzahl Verbindungsversuche</item> + </string-array> +</resources> diff --git a/main/src/main/res/values-de/strings.xml b/main/src/main/res/values-de/strings.xml new file mode 100755 index 00000000..f9a9c2fc --- /dev/null +++ b/main/src/main/res/values-de/strings.xml @@ -0,0 +1,317 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string name="app">OpenVPN für Android</string> + <string name="address">Server:</string> + <string name="port">Server Port:</string> + <string name="location">Ort</string> + <string name="cant_read_folder">Verzeichnis kann nicht gelesen werden</string> + <string name="select">Auswählen</string> + <string name="cancel">Abbrechen</string> + <string name="no_data">Keine Daten</string> + <string name="useLZO">LZO Komprimierung</string> + <string name="client_no_certificate">Kein Zertifikat</string> + <string name="client_certificate_title">Clientzertifikat</string> + <string name="client_key_title">Clientzertifikatsschlüssel</string> + <string name="client_pkcs12_title">PKCS12 Datei</string> + <string name="ca_title">CA Zertifikat</string> + <string name="no_certificate">Kein Zertifikat ausgewählt</string> + <string name="copyright_guicode">Quellcode und Issue Tracker sind verfügbar unter http://code.google.com/p/ics-openvpn/</string> + <string name="copyright_others">Dieses Programm nutzt die folgenden Komponenten. Die kompletten Lizenzdetails sind im Quelltext verfügbar.</string> + <string name="about">Über</string> + <string name="vpn_list_title">Profile</string> + <string name="vpn_type">Typ</string> + <string name="pkcs12pwquery">PKCS12 Passwort</string> + <string name="file_select">Auswählen…</string> + <string name="file_nothing_selected">Nichts ausgewählt</string> + <string name="useTLSAuth">Benutze TLS Authentifizierung</string> + <string name="tls_direction">TLS Richtung</string> + <string name="ipv6_dialog_tile">Tragen Sie die IPv6 Adresse und Netzmaske im CIDR Format ein (z.B. 2000:dd::23/64)</string> + <string name="ipv4_dialog_title">Tragen Sie die IPv4 Adresse und Netzmaske im CIDR Format ein (z.B. 1.2.3.4/24)</string> + <string name="ipv4_address">IPv4 Adresse</string> + <string name="ipv6_address">IPv6 Adresse</string> + <string name="custom_option_warning">Tragen Sie eigene OpenVPN Optionen ein. Beachten Sie, dass einige (vor allem tun spezifische) Optionen von der Android Version nicht unterstützt werden können. Wenn Sie denken, dass eine wichtige Option fehlt, kontaktieren Sie den Autor</string> + <string name="auth_username">Benutzername</string> + <string name="auth_pwquery">Passwort</string> + <string name="static_keys_info">Für die statische Konfiguration werden die TLS Auth Schlüssel als statische Schlüssel benutzt</string> + <string name="configure_the_vpn">VPN konfigurieren</string> + <string name="menu_add_profile">Profil hinzufügen</string> + <string name="add_profile_name_prompt">Geben Sie einen Namen für das neue Profil an</string> + <string name="duplicate_profile_name">Profilname bereits vorhanden. Bitte vergeben Sie einen eindeutigen Profilnamen.</string> + <string name="profilename">Profilname</string> + <string name="no_keystore_cert_selected">Kein Benutzerzertifikat ausgewählt</string> + <string name="no_error_found">Kein Fehler.</string> + <string name="config_error_found">Fehler in der Konfiguration</string> + <string name="ipv4_format_error">Kann die IPv4 Adresse nicht parsen</string> + <string name="custom_route_format_error">Kann die manuell angegeben Routen nicht parsen</string> + <string name="pw_query_hint">(Leer lassen um nicht zu speichern)</string> + <string name="vpn_shortcut">OpenVPN Verknüpfung</string> + <string name="vpn_launch_title">VPN verbinden</string> + <string name="shortcut_profile_notfound">Von der Verknüpfung referenziertes Profil konnte nicht gefunden werden</string> + <string name="random_host_prefix">Random Host Präfix</string> + <string name="random_host_summary">Verwürfelt den Hostnamen mit zufälligen Präfix</string> + <string name="custom_config_title">Eigene Konfigurationsoptionen</string> + <string name="custom_config_summary">Geben Sie eigene Konfigurationsoptionen an. Seien Sie vorsichtig!</string> + <string name="route_rejected">Route von Android zurückgewiesen.</string> + <string name="cancel_connection">Trennen</string> + <string name="cancel_connection_long">VPN Verbindung trennen</string> + <string name="clear_log">Log löschen.</string> + <string name="title_cancel">Trennungsbestätigung</string> + <string name="cancel_connection_query">Möchten Sie das VPN trennen bzw. den Verbindungsversuch abbrechen?</string> + <string name="remove_vpn">VPN löschen</string> + <string name="check_remote_tlscert">Überprüfe, ob der Server ein Zertifikat mit TLS-Servererweiterungen verwendet (--remote-cert-tls server)</string> + <string name="check_remote_tlscert_title">TLS-Serverzertifikat erwarten</string> + <string name="remote_tlscn_check_summary">Server Zertifikatssubjekt überprüfen</string> + <string name="remote_tlscn_check_title">Zertifikat Namen überprüfen</string> + <string name="enter_tlscn_dialog">Spezifizieren Sie die Methode mit welcher der DN des Serverzertifikates (z. B. C=DE, L=Paderborn, OU=Avian IP-Carrier, CN=openvpn.blinkt.de) überprüft wird.\n\nSie können den vollständigen DN oder den RDN (openvpn.blinkt.de im Beispiel) oder ein RDN-Präfix angeben.\n\nDer RDN Präfix \"Server\" erlaubt z.B. \"Server-1\" und \"Server-2\" \n\nWenn Sie das Eingabefeld leer lassen, wird der RDN gegen den Servernamen geprüft.\n\n Für weitere Details sehen Sie die Manpage von OpenVPN 2.3.1+ unter —verify-x509-name</string> + <string name="enter_tlscn_title">Serverzertifikat Subject</string> + <string name="tls_key_auth">Benutzte TLS Schlüssel Authentifizierung</string> + <string name="tls_auth_file">TLS Auth Datei</string> + <string name="pull_on_summary">Fordert IP Adressen, Routen und andere Optionen vom Server an.</string> + <string name="pull_off_summary">Keine Informationen werden vom Server bezogen. Geben Sie manuell die Optionen an.</string> + <string name="use_pull">Pull Settings</string> + <string name="dns">DNS</string> + <string name="override_dns">Eigene DNS Server.</string> + <string name="dns_override_summary">Eigene DNS Server benutzen.</string> + <string name="searchdomain">DNS Such Domäne</string> + <string name="dns1_summary">Primärer DNS Server</string> + <string name="dns_server">DNS Server</string> + <string name="secondary_dns_message">Sekundärer DNS Server. Wird genutzt falls der normale DNS Server nicht erreicht werden kann</string> + <string name="backup_dns">Backup DNS Server</string> + <string name="ignored_pushed_routes">Ignoriere gepushte Routen</string> + <string name="ignore_routes_summary">Ignoriere die Routen, die der Server dem Client sendet.</string> + <string name="default_route_summary">Leitet allen Internet Verkehr über das VPN</string> + <string name="use_default_title">Benutze Default Route</string> + <string name="custom_route_message">Benutze eigene Routen. Geben Sie Zielnetzwerk im CIDR Format an. Z.b. \"10.0.0.0/8 2002::/16\" würde die Netzwerke 10.0.0.0/8 und 2002::/16 über das VPN routen.</string> + <string name="custom_route_message_excluded">Netze, die nicht über über das VPN weitergeleitet werden sollen. Nutzt die gleiche Syntax wie die eigenen Routen.</string> + <string name="custom_routes_title">Eigene Routen</string> + <string name="custom_routes_title_excluded">Ausgenommene Netze</string> + <string name="log_verbosity_level">Log Detail Level</string> + <string name="float_summary">Erlaube authentifizierte Pakete von jeder IP</string> + <string name="float_title">Erlaube floating Server</string> + <string name="custom_options_title">Eigene Optionen</string> + <string name="edit_vpn">Ändere VPN Einstellungen</string> + <string name="remove_vpn_query">VPN Profile \'%s\' löschen?</string> + <string name="tun_error_helpful">Auf manchen ROM Version sind eventuell die Zugriffsrechte von /dev/tun falsch oder das tun Kernel Modul fehlt. Für Cyanogenmod 9 ROMs mit root gibt einen provisorischen Fix in den generellen Einstellungen.</string> + <string name="tun_open_error">Das Öffnen des tun Interfaces ist katastrophal gescheitert</string> + <string name="error">"Fehler: "</string> + <string name="clear">Clear</string> + <string name="last_openvpn_tun_config">Öffne tun Netzwerkinterface:</string> + <string name="local_ip_info">Lokale IPv4: %1$s/%2$d IPv6: %3$s MTU: %4$d</string> + <string name="dns_server_info">DNS-Server: %1$s, Domäne: %2$s</string> + <string name="routes_info_incl">Routen: %1$s %2$s</string> + <string name="routes_info_excl">ausgenommene Routen: %1$s %2$s</string> + <string name="routes_debug">Installierte Routen (VpnService): %1$s %2$s</string> + <string name="ip_not_cidr">Interface Information %1$s und %2$s, nehme an, die zweite Adresse ist die Peer Adresse. Benutze /32 Netzmaske für die lokale IP Adresse. Interface Modus spezifiziert von OpenVPN ist \"%3$s\".</string> + <string name="route_not_cidr">Die Route %1$s mit der Netzmaske %2$s ist keine Route mit einer CIDR Netzmaske, benutze /32 als Netzmaske.</string> + <string name="route_not_netip">Route %1$s/%2$s korrigiert zu %3$s/%2$s</string> + <string name="keychain_access">Kann nicht auf die Android Keychain Zertifikate zugreifen (dies kann durch ein System Update oder durch Zurücksichern der Anwendung aus einem Backup hervorgerufen werden). Bitte editieren Sie das VPN und wählen Sie erneut das Zertifikat in dem Grundeinstellungen aus, um die Zugriffsberechtigung für das Zertifikat wieder herzustellen.</string> + <string name="version_info">%1$s %2$s</string> + <string name="send_logfile">Sende Logdatei</string> + <string name="send">Sende</string> + <string name="ics_openvpn_log_file">ICS OpenVPN log Datei</string> + <string name="copied_entry">Log Eintrag in die Zwischenablage kopiert</string> + <string name="tap_mode">Tap Mode</string> + <string name="faq_tap_mode">Die VPN API von Android, die ohne rooten des Telefons funktioniert, unterstützt nur den tun Modus. Das Unterstützen des Tap Modus ist daher nicht möglich.</string> + <string name="tap_faq2">Die gleiche Frage nochmal? Meinen Sie das ernst? Ohne root kann tap wirklich nicht unterstützt werden. Emails an mich, mit der Frage, wann tap unterstützt wird, helfen hier kein Stück.</string> + <string name="tap_faq3">Ein drittes Mal? Nun gut, theoretisch kann tap mit einem tun Gerät emuliert werden. Dieser tap Emulator müsste die Layer 2 Informationen beim Senden hinzufügen und beim Empfangen wieder entfernen. Zusätzlich muss noch ARP und sinnvollerweise auch ein DHCP Client implementiert werden. Mir ist niemand bekannt, der etwas in dieser Richtung unternimmt. Kontaktieren Sie mich, falls Sie so etwas implementieren möchten.</string> + <string name="faq">FAQ</string> + <string name="copying_log_entries">Kopieren von Log Einträgen</string> + <string name="faq_copying">Um einen einzelnen Log Eintrag zu kopieren berühren Sie den Log Eintrag und halten Sie gedrückt. Um das ganze Log zu Kopieren/Versenden benutzen Sie die \"Sende Log\" Option. Falls Sie Option nicht im in der GUI sehen, drücken Sie die Menü Taste am Gerät.</string> + <string name="faq_shortcut">Verknüpfung zu einem VPN</string> + <string name="faq_howto_shortcut">Sie können ein Shortcut zum Starten des VPN auf Ihren Startbildschirm legen. Abhängig davon welches Home/Launcher Programm Sie verwenden müssen ein Widget, einen Shortcut oder eine Verknüpfung hinzufügen.</string> + <string name="no_vpn_support_image">Dieses Android ROM enthält keine VPNService API. Sorry :(</string> + <string name="encryption">Verschlüsselung</string> + <string name="cipher_dialog_title">Geben Sie die Verschlüsslungsmethode an</string> + <string name="chipher_dialog_message">Verschlüsslungsalgorithmus der von OpenVPN genutzt werden soll. Um den Standardalgorithmus zu benutzten leer lassen.</string> + <string name="auth_dialog_message">Geben Sie den Hashalgorithmus der zur Nachrichtenauthentifizierung benutzt wird an. Leer lassen um den Standard Algorithmus zu nutzen.</string> + <string name="settings_auth">Authentifizierung/Verschlüsselung</string> + <string name="file_explorer_tab">Datei auswählen…</string> + <string name="inline_file_tab">Eingebettete Datei</string> + <string name="error_importing_file">Fehler beim importieren der Datei</string> + <string name="import_error_message">Konnte Datei nicht vom Dateisystem importieren</string> + <string name="inline_file_data">[[Eingebettete Datei]]</string> + <string name="opentun_no_ipaddr">Verweigere tun Gerät zu öffnen ohne IP Information</string> + <string name="menu_import">Importiere Profil von .ovpn Datei</string> + <string name="menu_import_short">Import</string> + <string name="import_content_resolve_error">Konnte zu importierendes Profil nicht lesen</string> + <string name="error_reading_config_file">Fehler beim Lesen der Konfigurationsdatei</string> + <string name="add_profile">Profil hinzufügen</string> + <string name="import_could_not_open">Konnte die Datei %1$s, die in der importierten Konfiguration angeben war, nicht finden</string> + <string name="importing_config">Importiere Konfigurationsdatei aus %1$s</string> + <string name="import_warning_custom_options">Ihre Konfiguration hatte ein paar Konfigurationsoptionen, die nicht direkt mit der GUI konfigurierbar sind. Diese Optionen wurden als benutzerdefinierte Konfigurationsoptionen hinzugefügt. Dies sind:</string> + <string name="import_done">Konfigurationsdatei lesen abgeschlossen.</string> + <string name="nobind_summary">Binde nicht an lokalen Port und IP Adresse</string> + <string name="no_bind">Kein lokales Binden</string> + <string name="import_configuration_file">Importiere Konfigurationsdatei</string> + <string name="faq_security_title">Bemerkungen zur Sicherheit</string> + <string name="faq_security">Da OpenVPN sicherheitsrelevant ist, sind einige Worte zur Sicherheit der Anwendung angebracht. Alle Daten, die sich auf der SD Karte befinden sind als absolut unsicher anzusehen. Jede Anwendung kann diese lesen. (Diese Anwendung braucht zum Beispiel keine SD Karten Berechtigung). Die restlichen Konfiguration dieser Anwendung kann nur von der Anwendung selbst gelesen werden. Wenn die Option genutzt wird, dass die Zertifikate und Schlüssel eingebettet werden, werden diese im VPN Profil gespeichert. Die VPN Profile sind nur von der Anwendung selbst lesbar. (Vergessen Sie nicht die ursprünglichen Zertifikate/Schlüssel von der SD Karte zu löschen). Die Daten die Anwendung selbst speichert sind unverschlüsselt. Es besteht die Möglichkeit diese mittels \"rooten\" des Telefons/Tablets oder anderen Schwachstellend diese Daten auszulesen. Gespeicherte Passwörter werden auch im Klartext gespeichert. Es wird dringend empfohlen die Zertifikate in dem Android Keystore zu speichern.\"</string> + <string name="import_vpn">Importieren</string> + <string name="broken_image_cert_title">Fehler beim Anzeigen des Zertifikatsauswahlbildschirmes</string> + <string name="broken_image_cert">Android hat einen Fehler beim Anzeigen des Zertifikat Dialog gemeldet. Dies sollte nie passieren, da dies ein Standard Feature von Android 4.0+ ist. Eventuell ist Unterstützung von Zertifikaten in Ihrer Firmware fehlerhaft</string> + <string name="ipv4">IPv4</string> + <string name="ipv6">IPv6</string> + <string name="speed_waiting">Warte auf OpenVPN Status Nachricht…</string> + <string name="converted_profile">Importiertes Profil</string> + <string name="converted_profile_i">Importiertes Profil %d</string> + <string name="broken_images">Fehlerhafte Images</string> + <string name="broken_images_faq"><p>Von offiziellen HTC Firmwares ist bekannt, dass diese teilweise merkwürdige Routing Probleme haben, die dafür sorgen, dass der Verkehr nicht durch den Tunnel fließt. (Siehe auch <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=18\">Issue 18</a> im Bug Tracker.)</p><p>Bei älteren Version der offiziellen SONY Firmwares für das Xperia arc S and Xperia Ray scheint der VPNService Support komplett zu fehlen. (Siehe auch <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=29\">Issue 29</a> im Bug Tracker.)</p><p>Auf anderen (insbesondere Custom ROMS) fehlt teilweise das tun Kernel Modul oder die Rechte von /dev/tun sind falsch gesetzt. Auf einigen CM9 Firmware wird die \"/dev/tun Eigentümer setzen\" Option in den Allgemeinen Einstellungen benötigt.</p><p>Am wichtigsten ist aber, falls Sie eine fehlerhafte Firmware haben, melden Sie dies Ihrem Hersteller. Desto mehr Leute den Fehler dem Hersteller melden desto wahrscheinlicher werden Sie eine Fehlerkorrektur bekommen.</p></string> + <string name="pkcs12_file_encryption_key">PKCS12 Veschlüsslungspassword</string> + <string name="private_key_password">Passphrase privater Schlüssel</string> + <string name="password">Passwort</string> + <string name="file_icon">Datei Symbol</string> + <string name="tls_authentication">TLS Authentifizierung</string> + <string name="generated_config">Generierte Konfiguration</string> + <string name="generalsettings">Einstellungen</string> + <string name="owner_fix_summary">Versucht den Eigentümer von /dev/tun auf system zu ändern. Einige Cyanogenmod 9 ROM Versionen benötigen diese Option, damit die VPN API funktioniert. Benötigt root.</string> + <string name="owner_fix">/dev/tun Eigentümer setzen.</string> + <string name="generated_config_summary">Zeigt die generierte Konfigurationsdatei</string> + <string name="edit_profile_title">Editiere \"%s\"</string> + <string name="building_configration">Generiere OpenVPN Konfiguration…</string> + <string name="netchange_summary">Aktivieren dieser Option zwingt OpenVPN dazu, beim Wechsel des Netzwerkes (WLAN zu Mobilfunk und umgekehrt), neu zu verbinden</string> + <string name="netchange">Netzwerkänderungen beachten</string> + <string name="netstatus">Netzwerkstatus: %s</string> + <string name="extracahint">Das CA Zertifikat wird meist aus dem Zertifikatsspeicher automatisch ausgewählt. Sollte dies nicht funktionieren und Sie Verifizierungsprobleme erhalten(self signed certificate), wählen Sie manuell ein Zertifikat aus.</string> + <string name="select_file">Auswählen</string> + <string name="keychain_nocacert">Beim Abfragen des Android KeyStore wurde kein CA Zertifikat zurückgegeben. Überprüfen des Serverzertifikat wird wahrscheinlich fehlschlagen. Geben Sie manuell ein CA Zertifikat an.</string> + <string name="show_log_summary">Zeigt das Status Log, wenn ein VPN verbunden wird. Das Status log kann immer über die Benachrichtigung aufgerufen werden.</string> + <string name="show_log_window">Zeige Log</string> + <string name="mobile_info">Modell %1$s (%2$s) %3$s, Android API %4$d</string> + <string name="error_rsa_sign">Fehler beim Zugriff auf den Android Keystore %1$s: %2$s</string> + <string name="faq_system_dialogs">Die Meldung, dass OpenVPN versucht eine VPN-Verbindung aufzubauen und dabei den gesamten Netzwerkverkehr abhören kann, wird vom Android System selbst erzeugt. Diese wird vom System erzwungen, damit keine Anwendung vom Benutzer unbemerkt eine VPN Verbindung aufbauen kann\Die VPN Benachrichtigung (Das Schlüssel Symbol) wird genauso vom Android System angezeigt um eine bestehende VPN anzuzeigen.\nDiese beiden Features wurden in Android für die Sicherheit des Nutzers implementiert und können nicht umgangen werden. (Auf machen Telefon/Tablets wird die Benachrichtigung leider mit einem Ton signalisiert.)</string> + <string name="faq_system_dialogs_title">Warnung beim Verbinden und Benachrichtigungston</string> + <string name="translationby">Deutsche Übersetzung von Arne Schwabe <arne@rfc2549.org></string> + <string name="ipdns">IP und DNS</string> + <string name="basic">Grundeinstellungen</string> + <string name="routing">Routing</string> + <string name="obscure">Obskure OpenVPN Einstellungen, die normalerweise nicht benötigt werden.</string> + <string name="advanced">Erweitert</string> + <string name="export_config_title">ICS OpenVPN Konfiguration</string> + <string name="warn_no_dns">Es werden keine DNS Server für die VPN Verbindung genutzt. Die Namensauflösung wird möglicherweise nicht funktionieren. Ziehen Sie in Erwähung selbst DNS Server in den Optionen zu setzen. Beachten Sie weiterhin, dass Android die Proxyeinstellungen für Handy/WLAN weiterhin benutzt, falls keine DNS Server für das VPN festgelegt sind.</string> + <string name="dns_add_error">Konnte den DNS Server \"%1$s\" nicht hinzufügen, da das System ihn zurückweist mit %2$s</string> + <string name="ip_add_error">Konnte nicht die IP Adresse \"%1$s\" nicht setzen. Fehlermeldung des Systems: %2$s</string> + <string name="faq_howto"><p>Benutzen Sie eine funktionierende Konfiguration (getestet auf einem Computer, oder von Ihrer Organisation/Ihrem Provider bereitgestellt)</p><p>Falls Sie nur eine einzelne Datei benötigen, können Sie sich diese als Email-Anhang zuschicken. Falls Ihre OpenVPN Konfiguration aus mehreren Dateien besteht, müssen Sie alle Dateien auf die SD Karte kopieren.</p><p>Klicken Sie auf den Email Anhang im Android Mail Programm bzw. benutzen Sie das Ordner Symbol in der VPN Liste und wählen Sie die .ovpn bzw. .conf Konfigurationsdatei aus.</p><p>Falls der Import fehlende Dateien anmerkt, kopieren Sie diese auf die SD Karte und starten den Import erneut.</p><p>Benutzen Sie anschließend das Speichern Symbol um das VPN zur VPN Liste hinzuzufügen</p><p>Tippen Sie den Namen des VPNs an, um das VPN zu starten</p><p>Achten Sie auf Fehler und Warnungen im Verbindungslog.</p> </string> + <string name="faq_howto_title">Schnellstart</string> + <string name="setting_loadtun_summary">Versuche das tun.ko Kernel Modul zu laden. Benötigt root.</string> + <string name="setting_loadtun">Lade tun Modul</string> + <string name="importpkcs12fromconfig">Importiere die PKCS12 Datei, die in der Konfiguration angegeben ist, in den Android Keystore</string> + <string name="getproxy_error">Fehler beim Ermitteln der Proxy Einstellungen: %s</string> + <string name="using_proxy">Benutzt Proxy %1$s %2$d</string> + <string name="use_system_proxy">Benutze System Proxys</string> + <string name="use_system_proxy_summary">Benutze die System weiten Einstellungen für HTTP/HTTPS Proxys beim Verbinden.</string> + <string name="donatewithpaypal"><a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;cmd=_s-xclick\">Spenden mit PayPal</a> </string> + <string name="onbootrestartsummary">OpenVPN wird bei einem Neustart des Telefon das beim herunterfahren/neu starten aktive VPN wieder verbinden. Bitte lesen Sie die FAQ \"Warnung beim Verbinden\" FAQ bevor Sie diese Option verwenden.</string> + <string name="onbootrestart">Nach Neustart verbinden</string> + <string name="ignore">Ignorieren</string> + <string name="restart">Neu verbinden</string> + <string name="restart_vpn_after_change">Konfigurationsänderungen werden erst nach einem VPN Neustart aktiv. Jetzt neu verbinden?</string> + <string name="configuration_changed">Konfiguration geändert</string> + <string name="log_no_last_vpn">Konnte das zuletzt verbundene Profile beim Versuch des Editieren nicht ermitteln.</string> + <string name="faq_duplicate_notification_title">Doppelte Benachrichtigungen</string> + <string name="faq_duplicate_notification">Android beendet automatisch Anwendungen und Dienste, die im Hintergrund laufen, wenn der Arbeitsspeicher knapp wird. Wird dabei OpenVPN beendet, bricht die VPN Verbindung ab. Um dies zu vermeiden, läuft der VPN Prozess mit einer höheren Priorität. Um eine höhere Priorität nutzen zu können, muss die Anwesenheit des Prozesses dem Benutzer im Form einer Benachrichtigung mitgeteilt werden. Daher zeigt OpenVPN für Android immer seine eigene Benachrichtigung an. Die Schlüssel Benachrichtigung, die auch im letzten Eintrag erklärt wird, zählt leider nicht als Benachrichtigung, die der Anwendung erlaubt mit höherer Priorität zu arbeiten.</string> + <string name="no_vpn_profiles_defined">Keine VPN Profile definiert.</string> + <string name="add_new_vpn_hint">Benutzen Sie <img src=\"ic_menu_add\"/> um ein neues VPN anzulegen</string> + <string name="vpn_import_hint">Benutzen Sie <img src=\"ic_menu_archive\"/> um ein vorhandenes (.ovpn oder .conf) Profil von Ihrer SD Karte zu importieren</string> + <string name="faq_hint">Lesen Sie auch die FAQ. Dort befindet sich eine Schnellstart Anleitung</string> + <string name="faq_routing_title">Routing/Netzwerk Konfiguration</string> + <string name="faq_routing">In dieser Anwendung wird die Routing und Netzwerkkonfiguration nicht mit den traditionellen ifconfig/route Kommandos konfiguriert sondern mittels der VPNService API. Diese erwartet eine Tunnel IP Adresse und die Netzwerke, die über den Tunnel geroutet werden sollen. Insbesondere wird keine Gateway oder Peer IP Adresse benötigt. Die Anwendung ignoriert diese daher auch beim Import. Dass die Verbindung zum VPN Server nicht über den Tunnel geroutet wird, wird auch über die VPNService API sichergestellt ohne dass hierfür spezielle Routen nötig sind. Da nur Netzwerke, die über den Tunnel geroutet werden sollen, angeben werden können, ist es nicht möglich andere Routen zu unterstützen (z.B. route x.x.x.x y.y.y.y net_gateway)\"</string> + <string name="persisttun_summary">Verhindere Zurückfallen auf nicht VPN Verbindungen während OpenVPN neu verbindet.</string> + <string name="persistent_tun_title">Persistentes tun Device</string> + <string name="openvpn_log">OpenVPN-Log</string> + <string name="import_config">OpenVPN Konfiguration importieren</string> + <string name="battery_consumption_title">Energieverbrauch</string> + <string name="baterry_consumption">In meinen eigenen Tests ist der Hauptgrund für den hohen Stromverbrauch von OpenVPN das Senden und Empfangen der Keepalive-Pakete. Die meisten OpenVPN-Server haben eine Konfigurationsoption wie \'keepalive 10 60\', was bedeutet, dass vom Client an den Server und vom Server an den Client alle zehn Sekunden ein Paket geschickt wird. <p> Diese Pakete sind klein und erzeugen keine große Datenmenge. Sie sorgen allerdings dafür, dass permanent Daten übertragen werden und somit auch die Mobilfunk- bzw. WLAN Einheit aktiv ist und steigern damit den Energieverbrauch. (Siehe auch <a href=\"http://developer.android.com/training/efficient-downloads/efficient-network-access.html#RadioStateMachine\">The Radio State Machine | Android Developers</a>)<p> Diese keepalive Einstellung kann nicht auf dem Client geändert werden. Nur der Systemadministrator des VPN Servers kann die Einstellung ändern. lt;pgt; Leider hat eine keepalive Einstellung von mehr als 60 Sekunden unter udp Probleme mit einigen NAT-Gateways, die für inaktive Verbindungen nur eine sehr kurze Haltzeit haben und danach verwerfen (60s in meinen Tests). Benutzen von TCP mit langen Keep-Alive-Timeouts funktioniert, hat aber das TCP über TCP Problem. (Siehe <a href=\"http://sites.inka.de/bigred/devel/tcp-tcp.html\" > Why TCP Over TCP Is A Bad Idea </a>)</string> + <string name="faq_tethering">Die Funktion \"Anbindung & mobiler WLAN-Hotspot\" und die VPNService-API, die von diesem Programm verwendet wird, funktionieren nicht zusammen. Für weitere Details siehe <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=34\"> Issue #34 </a></string> + <string name="vpn_tethering_title">VPN und \"Anbindung & mobiler WLAN-Hotspot\"</string> + <string name="connection_retries">Anzahl Verbindungsversuche</string> + <string name="reconnection_settings">Einstellungen für das Neuverbinden</string> + <string name="connectretrymessage">Anzahl von Sekunden zwischen Verbindungsversuchen.</string> + <string name="connectretrywait">Sekunden zwischen Verbindungsversuchen</string> + <string name="minidump_generated">Der OpenVPN Prozess ist unerwartet abgestürzt. Bitte erwägen Sie die Option \"Minidump senden\" im Hauptmenü</string> + <string name="send_minidump">Minidump an Entwickler senden</string> + <string name="send_minidump_summary">Sendet Debugging Informationen des letzten Absturzes an den Entwickler</string> + <string name="notifcation_title">OpenVPN - %s</string> + <string name="session_ipv4string">%1$s - %2$s</string> + <string name="session_ipv6string">%1$s - %3$s, %2$s</string> + <string name="state_connecting">Verbinde</string> + <string name="state_wait">Warte auf Serverantwort</string> + <string name="state_auth">Authentifiziere</string> + <string name="state_get_config">Warte auf Clientkonfiguration</string> + <string name="state_assign_ip">Weise IP Adressen zu</string> + <string name="state_add_routes">Hinzufügen von Routen</string> + <string name="state_connected">Verbunden</string> + <string name="state_disconnected">Trennen</string> + <string name="state_reconnecting">Wiederverbinden</string> + <string name="state_exiting">Beende</string> + <string name="state_noprocess">Kein OpenVPN Prozess</string> + <string name="state_resolve">Löse Hostnamen auf</string> + <string name="state_tcp_connect">Verbinde (TCP)</string> + <string name="state_auth_failed">Authentifizierung fehlgeschlagen</string> + <string name="state_nonetwork">Warte auf Internetverbindung</string> + <string name="statusline_bytecount">↓%2$s/s %1$s - ↑%4$s/s %3$s</string> + <string name="notifcation_title_notconnect">Nicht verbunden</string> + <string name="start_vpn_title">Verbinde mit VPN %s</string> + <string name="start_vpn_ticker">Verbinde mit VPN %s</string> + <string name="jelly_keystore_alphanumeric_bug">Einige Versionen von Android 4.1 haben Probleme, wenn der Name des im Zertifikat Keystore gespeicherten Zertifikates nicht alphanumerische Zeichen (wie Leerzeichen, Unterstriche oder Bindestriche) enthält. Probieren Sie das Sie das Zertifikat mit einem Namen ohne Sonderzeichen zu importieren.</string> + <string name="encryption_cipher">Verschlüsslungsalgorithmus</string> + <string name="packet_auth">Packetauthentifizierung</string> + <string name="auth_dialog_title">Geben Sie den Authentifizierungsalgorithmus an</string> + <string name="mobile_info_extended">Modell %1$s (%2$s) %3$s, Android API %4$d, version %5$s, %6$s</string> + <string name="built_by">compiliert von %s</string> + <string name="debug_build">Testversion</string> + <string name="official_build">offizielle Version</string> + <string name="make_selection_inline">Ins Profil einbetten</string> + <string name="crashdump">Crashlog</string> + <string name="add">Hinzufügen</string> + <string name="send_config">Konfigurationsdatei senden</string> + <string name="complete_dn">Völlständiger DN</string> + <string name="remotetlsnote">Ihre importierte Konfiguration verwendete die alte VERALTETE tls-remote-Option, die ein anderes DN-Format verwendet.</string> + <string name="rdn">RDN (common name)</string> + <string name="rdn_prefix">RDN Präfix</string> + <string name="tls_remote_deprecated">tls-remote (VERALTET)</string> + <string name="help_translate">Sie können helfen die Übersetzung zu verbessern auf der Website http://crowdin.net/project/ics-openvpn/invite</string> + <string name="prompt">%1$s versucht %2$s zu steuern</string> + <string name="remote_warning">Wenn Sie fortfahren, gestatten Sie der App OpenVPN für Android komplett zu kontrollieren und den gesamten Netzwerkverkehr abzufangen. <b> Akzeptieren Sie nur, wenn Sie der App vertrauen. </b> Anderenfalls riskieren Sie, dass Ihre Daten von schädlicher Software manipuliert werden</string> + <string name="remote_trust">Ich vertraue dieser App.</string> + <string name="no_external_app_allowed">Keine App für die Verwendung der API freigegeben</string> + <string name="allowed_apps">Freigegebene Apps: %s</string> + <string name="clearappsdialog">Liste der freigegeben externen Apps löschen? \nAktuelle Liste der freigegebenen Apps:\n\n%s</string> + <string name="screenoff_summary">Pausiert das VPN, wenn der Bildschirm aus ist und weniger als 64 kB in 60 Sekunden übertragen wurden. Falls die Option \"Persistentes tun Device\" ausgewählt wird durch das Pausieren des VPNs das Gerät KEINE Netzwerkverbindung haben. Ohne die \"Persistentes tun Device\" Option, benutzt das Gerät die normal (ungesicherte) Internetverbindung, wenn das VPN pausiert wird.</string> + <string name="screenoff_title">Bei ausgeschalteten Bildschirm VPN Verbindung pausieren</string> + <string name="screenoff_pause">Pausiere VPN Verbindung da weniger als %1$s in %2$ss.</string> + <string name="screen_nopersistenttun">Warnung: Persistentes tun Device für dieses VPN nicht aktiviert. Der Netzwerkverkehr nutzt die normale Internet Verbindung, wenn der Bildschirm aus ist.</string> + <string name="save_password">Passwort merken</string> + <string name="pauseVPN">VPN pausieren</string> + <string name="resumevpn">VPN fortsetzen</string> + <string name="state_userpause">VPN Verbindung durch Benutzer pausiert</string> + <string name="state_screenoff">VPN pausiert wegen Inaktitvität pausiert (Bildschirm aus)</string> + <string name="device_specific">Geräte spezifische Hacks</string> + <string name="cannotparsecert">Kann Zertifikatsinformationen nicht anzeigen.</string> + <string name="appbehaviour">Anwendung</string> + <string name="vpnbehaviour">VPN</string> + <string name="allow_vpn_changes">Änderungen an VPN-profilen zulassen</string> + <string name="hwkeychain">Im Hardware Keystore gespeichert:</string> + <string name="permission_icon_app">Symbol der Anwendung, die versucht OpenVPN für Android zu kontrollieren</string> + <string name="faq_vpndialog43">Beginnend mit Android 4.3 wird der VPN-Bestätigungsdialog vor \"überlappenden Anwendungen\" geschützt. Dadurch kann es vorkommen, dass der Dialog nicht auf Eingaben reagiert. Eine Anwendung benutzen, die Overlays verwendet, kann es dieses Verhalten verursachen. Sollten Sie die verursachende Anwendung finden, kontaktieren Sie dessen Author. Dieses Problem betrifft alle VPN-Anwendungen ab Android 4.3. Siehe auch <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=185\" > Issue 185 <a> für zusätzliche Details \"</string> + <string name="faq_vpndialog43_title">VPN-Bestätigungsdialog ab Android 4.3</string> + <string name="donatePlayStore">Alternativ können Sie mir per Play Store Geld zukommen lassen:</string> + <string name="thanks_for_donation">Vielen Dank für die %s Spende!</string> + <string name="logCleared">Protokoll gelöscht.</string> + <string name="show_password">Passwort anzeigen</string> + <string name="keyChainAccessError">KeyChain Zugriffsfehler: %s</string> + <string name="timestamp_short">Kurze</string> + <string name="timestamp_iso">ISO</string> + <string name="timestamps">Zeitstempel</string> + <string name="timestamps_none">Keine</string> + <string name="uploaded_data">Hochgeladen</string> + <string name="downloaded_data">Heruntergeladen</string> + <string name="vpn_status">VPN-Status</string> + <string name="logview_options">Ansichtsoptionen</string> + <string name="unhandled_exception">Unbehandelte Ausnahme: %1$s\n\n%2$s</string> + <string name="unhandled_exception_context">%3$s: %1$s\n\n%2$s</string> + <string name="faq_system_dialog_xposed">Wenn Sie ihr Gerät gerootet haben können Sie das <a href=\"http://xposed.info/\">Xposed Framework</a> und das <a href=\"http://repo.xposed.info/module/de.blinkt.vpndialogxposed\">VPN Dialog confirm Modul</a> auf eigene Gefahr installieren.</string> + <string name="full_licenses">Komplette Lizenzen</string> + <string name="blocklocal_summary">Netze, die direkt über ein lokales Interfaces erreicht werden können werden nicht über das VPN gerottet. Deaktivieren dieser Option leitet allen Verkehr, der für lokale Netzwerke bestimmt ist, über das VPN.</string> + <string name="blocklocal_title">VPN für lokale Netzwerke umgehen</string> + <string name="userpw_file">Datei mit Benutzername und Passwort</string> +</resources> diff --git a/main/src/main/res/values-es/arrays.xml b/main/src/main/res/values-es/arrays.xml new file mode 100755 index 00000000..4728f401 --- /dev/null +++ b/main/src/main/res/values-es/arrays.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string-array name="vpn_types"> + <item>Certificados</item> + <item>Archivo PKCS12</item> + <item>Certificado de Android</item> + <item>Usuario/Contraseña</item> + <item>Llaves Estaticas</item> + <item>Usuario/Contraseña + Certificados</item> + <item>Usuario/Contraseña + PKCS12 </item> + <item>Usuario/Contraseña + Android</item> + </string-array> + <string-array name="tls_directions_entries"> + <item>0</item> + <item>1</item> + <item>No especificado</item> + </string-array> + <string-array name="crm_entries"> + <item>No reconnection retries</item> + <item>One reconnection retry</item> + <item>Five reconnection retries</item> + <item>Fifty reconnection retries</item> + <item>Unlimited reconnection retries</item> + </string-array> +</resources> diff --git a/main/src/main/res/values-es/strings.xml b/main/src/main/res/values-es/strings.xml new file mode 100755 index 00000000..87bb1351 --- /dev/null +++ b/main/src/main/res/values-es/strings.xml @@ -0,0 +1,308 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string name="app">OpenVPN para Android</string> + <string name="address">Dirección del servidor:</string> + <string name="port">Puerto del servidor:</string> + <string name="location">Ubicación</string> + <string name="cant_read_folder">No se puede leer el directorio</string> + <string name="select">Seleccionar</string> + <string name="cancel">Cancelar</string> + <string name="no_data">No hay datos</string> + <string name="useLZO">Compresión LZO</string> + <string name="client_no_certificate">Sin Certificado</string> + <string name="client_certificate_title">Certificado de Cliente</string> + <string name="client_key_title">Llave del Certificado de Cliente</string> + <string name="client_pkcs12_title">Archivo PKCS12</string> + <string name="ca_title">Certificado de la CA</string> + <string name="no_certificate">Debe seleccionar un certificado</string> + <string name="copyright_guicode">Codigo fuente y sistema de reporte de errores disponibles en http://code.google.com/p/ics-openvpn/</string> + <string name="copyright_others">El programa utiliza los siguientes componentes. Vea los códigos fuentes para obtener más información sobre las licencias</string> + <string name="about">Acerca de</string> + <string name="vpn_list_title">Perfiles</string> + <string name="vpn_type">Tipo</string> + <string name="pkcs12pwquery">Contraseña PKCS12</string> + <string name="file_select">Seleccionar…</string> + <string name="file_nothing_selected">Debe seleccionar un archivo</string> + <string name="useTLSAuth">Utilizar la autenticación TLS</string> + <string name="tls_direction">Dirección TLS</string> + <string name="ipv6_dialog_tile">Introduzca la dirección/máscara de red IPv6 en formato CIDR (por ejemplo, 2000:dd::23/64)</string> + <string name="ipv4_dialog_title">Introduzca la dirección/máscara de red IPv4 en formato CIDR (por ejemplo, 1.2.3.4/24)</string> + <string name="ipv4_address">Dirección IPv4</string> + <string name="ipv6_address">Dirección IPv6</string> + <string name="custom_option_warning">Introduzca las opciones personalizadas de OpenVPN. Úselas con mucho cuidado. Además, tenga en cuenta que muchas de las configuraciones de OpenVPN relacionadas con tun no pueden ser soportadas por el diseño de VPNSettings. Si cree que falta una función importante, contacte al autor</string> + <string name="auth_username">Nombre de usuario</string> + <string name="auth_pwquery">Contraseña</string> + <string name="static_keys_info">Para la configuración estática las claves de autenticación TLS se utilizaran como claves estáticas</string> + <string name="configure_the_vpn">Configurar la VPN</string> + <string name="menu_add_profile">Agregar perfil</string> + <string name="add_profile_name_prompt">Escriba un nombre que identifica el nuevo perfil</string> + <string name="duplicate_profile_name">Por favor, introduzca un nombre de perfil único</string> + <string name="profilename">Nombre del Perfil</string> + <string name="no_keystore_cert_selected">Debe seleccionar un certificado de usuario</string> + <string name="no_error_found">No se encontraron errores</string> + <string name="config_error_found">Error en la configuración</string> + <string name="ipv4_format_error">Error al analizar la dirección IPv4</string> + <string name="custom_route_format_error">Error al analizar las rutas personalizadas</string> + <string name="pw_query_hint">(Deje en blanco para consultar sobre demanda)</string> + <string name="vpn_shortcut">Acceso directo de OpenVPN</string> + <string name="vpn_launch_title">Conectar a VPN</string> + <string name="shortcut_profile_notfound">Perfil especificado en el acceso directo no encontrado</string> + <string name="random_host_prefix">Prefijo aleatorio de Host</string> + <string name="random_host_summary">Agrega 6 caracteres al azar delante del nombre de host</string> + <string name="custom_config_title">Habilitar opciones personalizadas</string> + <string name="custom_config_summary">Especificar opciones personalizadas. ¡Use con cuidado!</string> + <string name="route_rejected">Ruta rechazada por Android</string> + <string name="cancel_connection">Desconectar</string> + <string name="cancel_connection_long">Desconectar VPN</string> + <string name="clear_log">Limpiar registro</string> + <string name="title_cancel">Cancelar confirmación</string> + <string name="cancel_connection_query">¿Desconectar la conexión VPN/cancelar el intento de conexión?</string> + <string name="remove_vpn">Eliminar VPN</string> + <string name="check_remote_tlscert">Comprueba si el servidor utiliza un certificado con las extensiones TLS de servidor (--remote-cert-tls server)</string> + <string name="check_remote_tlscert_title">Espere certificado de servidor TLS</string> + <string name="remote_tlscn_check_summary">Checar el sujeto del DN del Certificado del Servidor Remoto</string> + <string name="remote_tlscn_check_title">Comprobación del certificado de nombre de host</string> + <string name="enter_tlscn_dialog">Especifica el chequeo usado para verificar el certificado remoto DN (ej. C=DE, L=Paderborn, OU=Avian IP Carriers, CN=openvpn.blinkt.de)\n\nEspecifica el DN completo o el RDN (openvpn.blinkt.de en el ejemplo) o un prefijo RDN para la verificación.\n\nCuando se usa un prefijo RDN como \"Server\" este coincide también con \"Server-1\" y \"Server-2\"\n\nDejando el campo de texto vacío verificara el RDN contra el nombre host del servidor.\n\nPara más detalles ve la página de manual (manpage) de OpenVPN 2.3.1+ en --verify-x509-name</string> + <string name="enter_tlscn_title">Sujeto del Certificado Remoto</string> + <string name="tls_key_auth">habilita la autenticación de clave TLS</string> + <string name="tls_auth_file">Archivo de autenticación TLS</string> + <string name="pull_on_summary">Obtener Direcciones IP, rutas y opciones de sincronizacion del servidor.</string> + <string name="pull_off_summary">No se pedira informacion del servidor. Necesita especifiar la configuracion abajo.</string> + <string name="use_pull">Obtener Configuracion</string> + <string name="dns">DNS</string> + <string name="override_dns">Reemplazar la configuración DNS del Servidor</string> + <string name="dns_override_summary">Usar sus propios servidores DNS</string> + <string name="searchdomain">Dominio de busqueda</string> + <string name="dns1_summary">Servidor DNS a ser usado.</string> + <string name="dns_server">Servidor DNS</string> + <string name="secondary_dns_message">El servidor DNS secundario se utiliza si el servidor DNS normal falla.</string> + <string name="backup_dns">Servidor DNS de respaldo</string> + <string name="ignored_pushed_routes">Ignorar rutas obtenidas</string> + <string name="ignore_routes_summary">Ignorar rutas obtenidas del servidor.</string> + <string name="default_route_summary">Redirige todo el tráfico a través de VPN</string> + <string name="use_default_title">Usar ruta predeterminada</string> + <string name="custom_route_message">Introduzca las rutas personalizadas. Sólo introduzca destinos en formato CIDR. \"10.0.0.0/8 2002:: / 16\" dirigiría las redes 10.0.0.0/8 y 2002::/16 sobre la VPN.</string> + <string name="custom_routes_title">Rutas personalizadas</string> + <string name="log_verbosity_level">Nivel de detalle del registro</string> + <string name="float_summary">Permite paquetes autenticados desde cualquier IP</string> + <string name="float_title">Permitir servidor flotante</string> + <string name="custom_options_title">Opciones personalizadas</string> + <string name="edit_vpn">Modificar la configuración de VPN</string> + <string name="remove_vpn_query">¿Eliminar el perfil VPN %s?</string> + <string name="tun_error_helpful">En algunas ROMS personalizadas de ICS los permisos sobre /dev/tun podrían ser incorrectos, o el módulo tun podría faltar. Para imágenes de CM9 pruebe la opción \"arreglar la propiedad de /dev/tun\" ubicada en la configuración general</string> + <string name="tun_open_error">No se puede abrir interfaz tun</string> + <string name="error">"Error: "</string> + <string name="clear">Limpiar</string> + <string name="last_openvpn_tun_config">Abriendo interfaz tun:</string> + <string name="local_ip_info">Local IPv4: %1$s/%2$d IPv6: %3$s MTU: %4$d</string> + <string name="dns_server_info">Servidor DNS : %1$s, Dominio: %2$s</string> + <string name="ip_not_cidr">Información de la interfaz obtenida %1$s and %2$s, asumiendo que la segunda dirección es una dirección equivalente del remoto. Usando una máscara de red /32 para la IP local. El modo dado por OpenVPN es \"%3$s\".</string> + <string name="route_not_cidr">No tienen sentido %1$s y %2$s como ruta IP con máscara de red CIDR, usando /32 como máscara de red.</string> + <string name="route_not_netip">Ruta conectada de %1$s/%2$s a %3$s/%2$s</string> + <string name="keychain_access">No se puede acceder a los certificados de Android. Puede ser causado por una actualización de firmware o por restaurar una copia de seguridad de la aplicación/configuración de la aplicación. Por favor edite la VPN y vuelva a seleccionar el certificado bajo meltdownajustes básicos para recrear los permisos para acceder al certificado.</string> + <string name="version_info">%1$s %2$s</string> + <string name="send_logfile">Enviar el archivo de registro</string> + <string name="send">Enviar</string> + <string name="ics_openvpn_log_file">Archivo de registro de OpenVPN de ICS</string> + <string name="copied_entry">Entrada de registro copiada al Portapapeles</string> + <string name="tap_mode">Modo Tap</string> + <string name="faq_tap_mode">El Modo tap no es posible sin la API VPN de root. Por lo tanto la aplicacion no puede dar soporte a tap</string> + <string name="tap_faq2">¿Otra vez? ¿Estás bromeando? No, el modo tap realmente no está soportado y enviar más correos preguntando si será soportado no ayudará.</string> + <string name="tap_faq3">¿Una tercera vez? En realidad se podría escribir un emulador de tap basado en tun que podria agregar información layer2 al enviar y obtener información layer2 al recibir. Pero este emulador tap tendría que implementar también ARP y posiblemente un cliente DHCP. No sé de alguien que este realizando trabajo en esa dirección. Ponte en contacto conmigo si deseas iniciar la codificación de esto.</string> + <string name="faq">P+F</string> + <string name="copying_log_entries">Copiar las entradas del registro</string> + <string name="faq_copying">Para copiar una sola entrada de registro presione y mantenga pulsado sobre la entrada del registro. Para copiar y enviar el registro completo use la opción Enviar registro. Utilice el botón fisico de menú si no visible en la interfaz.</string> + <string name="faq_shortcut">Acceso directo para iniciar</string> + <string name="faq_howto_shortcut">Puede colocar un acceso directo para iniciar OpenVPN desde el escritorio. Dependiendo del launcher tiene que añadir un acceso directo o un widget.</string> + <string name="no_vpn_support_image">Su imagen no es compatible con la API de VPNService, lo siento :(</string> + <string name="encryption">Cifrado</string> + <string name="cipher_dialog_title">Especifique el método de cifrado</string> + <string name="chipher_dialog_message">Proporcione el algoritmo de cifrado usado por OpenVPN. Deje en blanco para usar el cifrado de fábrica.</string> + <string name="auth_dialog_message">Introduce la autenticacion digest usada por OpenVPN. Deja en blanco para usar el digest predeterminado.</string> + <string name="settings_auth">Autenticación/Cifrado</string> + <string name="file_explorer_tab">Administrador de archivos</string> + <string name="inline_file_tab">Archivo en línea</string> + <string name="error_importing_file">Error al importar el archivo</string> + <string name="import_error_message">No se pudo importar el archivo del sistema de archivos</string> + <string name="inline_file_data">[[Datos de archivo en línea]]</string> + <string name="opentun_no_ipaddr">Negandose a abrir el dispositivo tun sin información de IP</string> + <string name="menu_import">Importar perfil de un archivo ovpn</string> + <string name="menu_import_short">Importar</string> + <string name="import_content_resolve_error">No se pudo leer el perfil a importar</string> + <string name="error_reading_config_file">Error al leer el archivo de configuración</string> + <string name="add_profile">Agregar perfil</string> + <string name="import_could_not_open">No se pudo encontrar el archivo %1$s mencionado en el archivo de configuracion importado</string> + <string name="importing_config">Importando archivo de configuración del origen %1$s</string> + <string name="import_warning_custom_options">Su configuración tiene algunas opciones de configuración que no están establecidas en la interfaz de usuario . Estas opciones fueron agregadas como opciones de configuración personalizadas. A continuación se muestra la configuración personalizada:</string> + <string name="import_done">Se termino de leer el archivo de configuración.</string> + <string name="nobind_summary">No enlazar con el puerto y la dirección local</string> + <string name="no_bind">Ningún enlace local</string> + <string name="import_configuration_file">Importar archivo de configuracion</string> + <string name="faq_security_title">Consideraciones de seguridad</string> + <string name="faq_security">"Como OpenVPN es sensible a la seguridad, son razonables algunas notas acerca de seguridad. Todos los datos en la tarjeta SD son inherentemente inseguros. Cualquier aplicación puede leerla (por ejemplo, esta aplicación no requiere ningún permiso especial sobre la tarjeta SD). Los datos de esta aplicación sólo pueden ser leidos por la misma aplicación. Al utilizar la opción importar para el certificado de la CA/certificado/llave, en la ventana de diálogo para selección de archivos, los datos se almacenan en el perfil de la VPN. Los perfiles de VPN sólo son accesibles por esta aplicación. (No olvide después borrar las copias de la tarjeta SD). Aunque sólo sea accesible por esta aplicación, los datos aún están sin encriptar. Al acceder el dispositivo portátil como root u otro medio, es posible recuperar estos datos. Las contraseñas guardadas son almacenadas también en texto plano. Para archivos pkcs12 es muy recomendable que los importe al repositorio de llaves de Android."</string> + <string name="import_vpn">Importar</string> + <string name="broken_image_cert_title">Error mostrando la seleccion de certificados</string> + <string name="broken_image_cert">Se obtuvo una excepción al intentar mostrar el diálogo de selección de certificado de Android 4.0+. Esto nunca debería ocurrir por ser una funcionalidad estándar de Android 4.0+. Quizás el respaldo ROM para almacenamiento de certificados de su Android está arruinado</string> + <string name="ipv4">IPv4</string> + <string name="ipv6">IPv6</string> + <string name="speed_waiting">Esperando el mensaje de estado…</string> + <string name="converted_profile">perfil importado</string> + <string name="converted_profile_i">perfil importado %d</string> + <string name="broken_images">Imágenes rotas</string> + <string name="broken_images_faq"><p>Las imágenes oficiales de HTC son conocidas por tener un extraño problema de enrutamiento, causando que el tráfico no fluya a través del túnel (Ver también <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=18\">Issue 18</a> en el bug tracker.)</p><p> Han reportado que el VPNService hace falta completamente de las imagenes oficiales de SONY más viejas del XPeria Arc S y Xperia Ray. (Ver también <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=29\">Issue 29</a> en el bug tracker.)</p><p>Puede faltar el módulo tun o los permisos de /dev/tun/ pueden estar incorrectos. Algunas imágenes de CM9 necesitan habilitada la opcion \"Fix ownership\" option bajo \"Hacks específicos del dispositivo\".</p><p>De mayor importancia: Si tu dispositivo tiene una imágen corrupta de Android, reportalo a tu proveedor. Entre mayor gente reporte el problema al proveedor, mayores son las probabilidades de que lo reparen.</p></string> + <string name="pkcs12_file_encryption_key">Clave PKCS12 de cifrado de archivos</string> + <string name="private_key_password">Contraseña de clave privada</string> + <string name="password">Contraseña</string> + <string name="file_icon">icono de archivo</string> + <string name="tls_authentication">Autenticación TLS</string> + <string name="generated_config">Configuración generada</string> + <string name="generalsettings">Preferencias</string> + <string name="owner_fix_summary">Intenta establecer el propietario de /dev/tun a system. Algunas imágenes de CM9 lo necesitan hacer funcionar la API de VPNService. Requiere permisos root.</string> + <string name="owner_fix">Arreglar la propiedad de /dev/tun</string> + <string name="generated_config_summary">Muestra el archivo de configuración OpenVPN generado</string> + <string name="edit_profile_title">Editando \"%s\"</string> + <string name="building_configration">Construyendo configuracion…</string> + <string name="netchange_summary">Turning this option on will force a reconnect if the network state is changed (e.g. WiFi to/from mobile)</string> + <string name="netchange">Reconectar en cambio de red</string> + <string name="netstatus">Estado de la red: %s</string> + <string name="extracahint">El certificado de la CA usualmente es recuperado del almacén de claves de Android. Especifique un certificado diferente si obtiene errores de verificación de certificado.</string> + <string name="select_file">Seleccionar</string> + <string name="keychain_nocacert">No se obtuvo ningún certificado de CA al leer el almacén de claves de Android. La autenticación probablemente fallará.</string> + <string name="show_log_summary">Muestra la ventana de registro el conectarse. La ventana de registro siempre puede accederse desde el estado de la notificación.</string> + <string name="show_log_window">Mostrar ventana de registro</string> + <string name="mobile_info">Ejecutándose en %1$s (%2$s) %3$s, API de Android %4$d</string> + <string name="error_rsa_sign">Error al firmar con la llave del almacén de llaves de Android %1$s: %2$s</string> + <string name="faq_system_dialogs">El aviso de conectividad VPN que esta aplicación puede interceptar todo el trafico esta impuesta por el sistema para evitar abusos de la API VPNService.\nLa notificación de conectividad (El símbolo de llave) también esta impuesta por el sistema Android para notificar una conexión VPN en curso. En algunas imágenes, esta notificación también emite un sonido.\nAndroid ha introducido estos diálogos de sistema para su seguridad e se ha asegurado que no pueden ser evitados. (En algunas imágenes, esto incluye la notificación sonora)</string> + <string name="faq_system_dialogs_title">Advertencia de conexión y sonido de notificación</string> + <string name="translationby">Traducción al español por José Luis Bandala Perez<luis.449bp@gmail.com></string> + <string name="ipdns">IP y DNS</string> + <string name="basic">Básico</string> + <string name="routing">Enrutamiento</string> + <string name="obscure">Configuraciones oscuras de OpenVPN. Normalmente no se necesitan.</string> + <string name="advanced">Avanzado</string> + <string name="export_config_title">Configuracion Openvpn de ICS</string> + <string name="warn_no_dns">No hay servidores DNS a utilizar. La Resolución de nombres puede no funcionar. Considere configurar servidores DNS personalizados. Tenga en cuenta que Android sigue usando la configuración de proxy especificada para su conexión móvil/Wi-Fi cuando no hay servidores DNS establecidos.</string> + <string name="dns_add_error">No se puede agregar el servidor DNS \"%1$s\", rechazado por el sistema: %2$s</string> + <string name="ip_add_error">No se pudo configurar la dirección IP \"%1$s\", rechazada por el sistema: %2$s</string> + <string name="faq_howto"><p>Obtén una configuración funcionando (probada en tu computadora o descargada de tu proveedor/organización)</p><p>Si es un solo archivo sin archivos pem/pks12 puedes enviar en un correo tu mismo el archivo y abrir el adjunto. Si tienes varios archivos ponlos en tu tarjeta SD.</p><p>Da clic en el adjunto de tu correo/Usa el icono de carpeta en la lista de VPN para importar el archivo de configuración </p><p>Si hay errores de archivos faltantes pon los archivos que faltan en tu tarjeta SD.</p><p>Da clic en el símbolo de guardar para agregar la VPN importada a tu lista de VPN</p><p>Conéctate a la VPN dando clic en el nombre de la VPN</p><p>Si hay errores o advertencias en el registro intenta comprender los errores/advertencias e intenta solucionarlos</p></string> + <string name="faq_howto_title">Inicio rápido</string> + <string name="setting_loadtun_summary">Intente cargar el módulo del kernel tun.ko antes de intentar conectarse. Necesita dispositivos rooteados.</string> + <string name="setting_loadtun">Cargar modulo tun</string> + <string name="importpkcs12fromconfig">Importar PKCS12 de la configuración en el almacén de claves de Android</string> + <string name="getproxy_error">Error al obtener la configuración de proxy: %s</string> + <string name="using_proxy">Usando proxy %1$s %2$d</string> + <string name="use_system_proxy">Usar el proxy del sistema</string> + <string name="use_system_proxy_summary">Utilice la configuración del sistema para los proxies HTTP/HTTPS a conectar.</string> + <string name="donatewithpaypal">Usted puede <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;cmd=_s-xclick\">donar con PayPal</a> </string> + <string name="onbootrestartsummary">OpenVPN volvera a conectar a una VPN si estaba activa en el apagado/reinicio del sistema. Por favor lea la P+F de advertencia de conexión antes de usar esta opción.</string> + <string name="onbootrestart">Vuelva a conectar al reiniciar</string> + <string name="ignore">Ignorar</string> + <string name="restart">Reiniciar</string> + <string name="restart_vpn_after_change">Los cambios de configuración se aplican después de reiniciar la VPN. ¿(Re)iniciar la VPN ahora?</string> + <string name="configuration_changed">Configuración cambiada</string> + <string name="log_no_last_vpn">No se pudo determinar el último perfil conectado para editar</string> + <string name="faq_duplicate_notification_title">Notificaciones duplicadas</string> + <string name="faq_duplicate_notification">Si Android está bajo presión de memoria del sistema (RAM), las aplicaciones y servicios que no estén siendo usados en el momento son removidos de la memoria activa. Esto termina una conexión VPN en marcha. Para asegurarse que la conexión/OpenVPN sobreviva el servicio tiene que ejecutarse con prioridad alta. Para ejecutarse con prioridad alta la aplicación debe de mostrar una notificación. El icono de notificación de llave es impuesto por el sistema como se describió en la entrada de FAQ anterior. Esta con cuenta como notificación de la aplicación con el propósito de ejecutarse con prioridad alta.</string> + <string name="no_vpn_profiles_defined">No hay perfiles VPN definidos.</string> + <string name="add_new_vpn_hint">Use el icono <img src=\"ic_menu_add\"/> para agregar una nueva VPN</string> + <string name="vpn_import_hint">Use el icono <img src=\"ic_menu_archive\"/> para importar un perfil existente (.ovpn or .conf) de tu tarjeta.</string> + <string name="faq_hint">Asegúrese de checar también las preguntas frecuentes. Hay una guía de inicio rápido.</string> + <string name="faq_routing_title">Configuración de enrutamiento o interfaz</string> + <string name="faq_routing">El enrutamiento y la configuración de la interfaz no se hace mediante los comandos tradicionales ifconfig/route sino usando el API VPNService. Esto resulta en una configuración de enrutamiento diferente a otros Sistemas operativos. La configuración sólo consiste en la IP de la interfaz túnel y las redes que deben ser enrutadas sobre dicha interfaz. No se necesitan direcciones peer parner o de puerta de enlace. Tompoco son necesarias rutas especiales para alcanzar al servidor VPN (por ejemplo, se agregan cuando se usa la opcion \'redirect-gateway\'). La aplicación ignorará consecuentemente estas opciones al importar una configuración. La aplicación se asegura que la conexión al servidor no se realice a través del túnel VPN, gracias al API VPN Service. Debido a que sólo se soporta enrutar ciertas redes mediante el túnel, rutas que no estén apuntando al túnel tampoco serán soportadas (p/e route x.x.x.x y.y.y.y net_gateway). Las ventanas de log muestran la configuración actual del VPNService al haber establecido una conexión. </string> + <string name="persisttun_summary">No regresar a modo sin conexión VPN cuando OpenVPN esta volviendose a conectar.</string> + <string name="persistent_tun_title">Tun persistente</string> + <string name="openvpn_log">Registro de OpenVPN</string> + <string name="import_config">Importar configuración de OpenVPN</string> + <string name="battery_consumption_title">Consumo de batería</string> + <string name="baterry_consumption">En mis pruebas personales, la mayor razón de el alto consumo de batería de OpenVPN son los paquetes keepalive. La mayoría de los servidores OpenVPN tienen una directiva de configuración como \'keepalive 10 60\' la cual causa que el cliente y el servidor intercambien paquetes cada diez segundos. <p> Mientras estos paquetes sean pequeños y no utilicen mucho tráfico, mantienen la red móvil de radio ocupada e incrementan el consumo de energía. (Ver también <a href=\"http://developer.android.com/training/efficient-downloads/efficient-network-access.html#RadioStateMachine\">The Radio State Machine | Android Developers</a>) <p> Dicha configuración keepalive no puede ser cambiada en el cliente. Solo el administrador de OpenVPN puede hacerlo. <p> Infortunadamente, usar un keepalive mayor a 60 segundos con UDP puede causar que algunas puertas de enlace NAT cierren la conexión debido a inactividad. Usar TCP con largos periodos de inactividad keepalive funciona, pero el tuneleo TCP sobre TCP resulta en conexiones extremadamente pobres con alta pérdida de paquetes. (Ver <a href=\"http://sites.inka.de/bigred/devel/tcp-tcp.html\">Why TCP Over TCP Is A Bad Idea</a>)</string> + <string name="faq_tethering">La funcionalidad de Tethering de Android (sobre WiFi, USB o Bluetooth) y la API del servicio de VPN (utilizada por esta aplicación) no pueden trabajar juntas. Para más detalles vea el <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=34\">problema #34</a></string> + <string name="vpn_tethering_title">VPN y Tethering</string> + <string name="connection_retries">Reintentos de conexión</string> + <string name="reconnection_settings">Configuración de reconexión</string> + <string name="connectretrymessage">Número de segundos de espera entre intentos de conexión.</string> + <string name="connectretrywait">Segundos entre las conexiones</string> + <string name="minidump_generated">OpenVPN falló inesperadamente. Por favor considere usar la opción envío de minivolcado en el menú principal</string> + <string name="send_minidump">Enviar minivolcado al desarrollador</string> + <string name="send_minidump_summary">Enviar información de depuración sobre último fallo al desarrollador</string> + <string name="notifcation_title">OpenVPN - %s</string> + <string name="session_ipv4string">%1$s - %2$s</string> + <string name="session_ipv6string">%1$s - %3$s, %2$s</string> + <string name="state_connecting">Conectando</string> + <string name="state_wait">Esperando respuesta del servidor</string> + <string name="state_auth">Autenticando</string> + <string name="state_get_config">Obteniendo información del cliente</string> + <string name="state_assign_ip">Asignando direcciones IP</string> + <string name="state_add_routes">Añadiendo rutas</string> + <string name="state_connected">Conectado</string> + <string name="state_disconnected">Desconectar</string> + <string name="state_reconnecting">Reconectando</string> + <string name="state_exiting">Saliendo</string> + <string name="state_noprocess">Proceso terminado</string> + <string name="state_resolve">Resolviendo nombres de host</string> + <string name="state_tcp_connect">Conectando (TCP)</string> + <string name="state_auth_failed">Fallo de autenticación</string> + <string name="state_nonetwork">Esperando por una red que se pueda usar</string> + <string name="statusline_bytecount">↓%2$s/s %1$s - ↑%4$s/s %3$s</string> + <string name="notifcation_title_notconnect">No conectado</string> + <string name="start_vpn_title">Conectando a VPN %s</string> + <string name="start_vpn_ticker">Conectando a VPN %s</string> + <string name="jelly_keystore_alphanumeric_bug">Algunas versiones de Android 4.1 experimentan problemas si el nombre del almacén de certificados contiene caracteres no alfanuméricos (como espacios, subrayados o barras). Intente volver a importar el certificado sin caracteres especiales</string> + <string name="encryption_cipher">Algoritmo de encriptación</string> + <string name="packet_auth">Autenticación de paquetes</string> + <string name="auth_dialog_title">Introduzca método de autenticación de paquetes</string> + <string name="mobile_info_extended">Corriendo sobre %1$s (%2$s) %3$s, API Android %4$d, versión %5$s, %6$s</string> + <string name="built_by">compilado por %s</string> + <string name="debug_build">versión de depuración</string> + <string name="official_build">versión oficial</string> + <string name="make_selection_inline">Copiar en perfil</string> + <string name="crashdump">Volcado de fallo</string> + <string name="add">Añadir</string> + <string name="send_config">Enviar el archivo de configuración</string> + <string name="complete_dn">DN Completo</string> + <string name="remotetlsnote">La configuracion que importaste usa la opcion OBSOLETA tls-remote que usa un formato diferente para DN.</string> + <string name="rdn">RDN (nombre comun)</string> + <string name="rdn_prefix">Prefijo RDN</string> + <string name="tls_remote_deprecated">tls-remote (OBSOLETO)</string> + <string name="help_translate">Tu puedes ayudar traduciendo visitando http://crowdin.net/project/ics-openvpn/invite</string> + <string name="prompt">%1$s intentos de controlar %2$s</string> + <string name="remote_warning">Al proceder, le estás proporcionando permiso a la aplicación para controlar completamente OpenVPN for Android e interceptar todo el tráfico de la red.<b>NO aceptar a menos que confíes en la aplicación.</b> De otro modo, corres el riesgo de que tus datos se vean comprometidos por software malicioso.\"</string> + <string name="remote_trust">Confío en esta aplicación.</string> + <string name="no_external_app_allowed">La aplicación no permite usar API externo</string> + <string name="allowed_apps">Aplicaciones autorizadas: %s</string> + <string name="clearappsdialog">¿Borrar la lista de aplicaciones externas permitidas?\nLista de aplicaciones permitidas:\n\n%s</string> + <string name="screenoff_summary">Pausa la VPN cuando la pantalla está apagada y se transfieren menos de 64 Kb de datos en 60 segundos. Cuando la opción \"TUN persistente\" está habilitada, pausar la VPN dejará tu dispositivo sin conexión a la red. Sin la opción \"TUN persistente\" el dispositivo carecerá de la conexión/protección de la VPN.</string> + <string name="screenoff_title">Pausar conexión de VPN cuando se apaga la pantalla</string> + <string name="screenoff_pause">Conexión en pausa si el estado de la pantalla es apagado: menos de %1$s en %2$ss</string> + <string name="screen_nopersistenttun">Advertencia: TUN persistente no habilitado para esta VPN. El tráfico usará la conexión normal a Internet cuando la pantalla esté apagada.</string> + <string name="save_password">Guardar contraseña</string> + <string name="pauseVPN">Pausar VPN</string> + <string name="resumevpn">Reanudar VPN</string> + <string name="state_userpause">VPN pausado por solicitud del usuario</string> + <string name="state_screenoff">VPN pausado - pantalla fuera</string> + <string name="device_specific">Hacks específicos del Dispositivo</string> + <string name="cannotparsecert">No se puede mostrar la información del certificado</string> + <string name="appbehaviour">Comportamiento de la aplicación</string> + <string name="vpnbehaviour">Comportamiento de VPN</string> + <string name="allow_vpn_changes">Permitir cambios a los perfiles VPN</string> + <string name="hwkeychain">Tecla Física:</string> + <string name="permission_icon_app">Ícono de la aplicación intentando usar OpenVPN for Android</string> + <string name="faq_vpndialog43">"Empezando con Android 4.3, la confirmación de VPN está protegida contra \"aplicaciones superpuestas\". Esto resulta en que la ventana de diálogo no reaccione a los toques de pantalla. Si tienes una aplicación que sea superpuesta, es lo que puede ocasionar este problema. Si encuentras una aplicación ofensiva, contactar al autor de la misma. Este problema afecta a todas las aplicaciones VPN en Android 4.3 y superior. Ver también <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=185\">Issue 185<a> para más detalles"</string> + <string name="faq_vpndialog43_title">Ventana de diálogo de confirmación VPN en Android 4.3 y superior</string> + <string name="donatePlayStore">Alternativamente usted puede enviar una donación con el Play Store:</string> + <string name="thanks_for_donation">Gracias por su donación %s!</string> + <string name="logCleared">Registro borrado.</string> + <string name="show_password">Mostrar contraseña</string> + <string name="keyChainAccessError">Error de acceso al llavero: %s</string> + <string name="timestamp_short">Corto</string> + <string name="timestamp_iso">ISO</string> + <string name="timestamps">Marcas de tiempo</string> + <string name="timestamps_none">Ninguno</string> + <string name="uploaded_data">Subir</string> + <string name="downloaded_data">Descargar</string> + <string name="vpn_status">Estado de VPN</string> + <string name="logview_options">Opciones de visualización</string> + <string name="unhandled_exception">Excepcion no controlada: %1$s\n\n%2$s</string> + <string name="unhandled_exception_context">%3$s: %1$s\n\n%2$s</string> + <string name="full_licenses">Licencias completas</string> +</resources> diff --git a/main/src/main/res/values-et/arrays.xml b/main/src/main/res/values-et/arrays.xml new file mode 100755 index 00000000..2b4eab16 --- /dev/null +++ b/main/src/main/res/values-et/arrays.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string-array name="vpn_types"> + <item>Sertifikaadid</item> + <item>PKCS12 fail</item> + <item>Androidi sertifikaat</item> + <item>Kasutajanimi/Salasõna</item> + <item>Staatilised võtmed</item> + <item>Kasutaja/Parool + Sertifikaadid</item> + <item>Kasutaja/Parool + PKCS12 </item> + <item>Kasutaja/Parool + Android</item> + </string-array> + <string-array name="tls_directions_entries"> + <item>0</item> + <item>1</item> + <item>Määratlemata</item> + </string-array> + <string-array name="crm_entries"> + <item>No reconnection retries</item> + <item>One reconnection retry</item> + <item>Five reconnection retries</item> + <item>Fifty reconnection retries</item> + <item>Unlimited reconnection retries</item> + </string-array> +</resources> diff --git a/main/src/main/res/values-et/strings.xml b/main/src/main/res/values-et/strings.xml new file mode 100755 index 00000000..d4ab4220 --- /dev/null +++ b/main/src/main/res/values-et/strings.xml @@ -0,0 +1,312 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string name="app">OpenVPN Androidile</string> + <string name="address">Serveri aadress:</string> + <string name="port">Serveri port:</string> + <string name="location">Asukoht</string> + <string name="cant_read_folder">Kataloog pole loetav</string> + <string name="select">Vali</string> + <string name="cancel">Tühista</string> + <string name="no_data">Andmed puuduvad</string> + <string name="useLZO">LZO pakkimine</string> + <string name="client_no_certificate">Puudub sertifikaat</string> + <string name="client_certificate_title">Kliendisertifikaat</string> + <string name="client_key_title">Kliendisertifikaadi võti</string> + <string name="client_pkcs12_title">PKCS12 fail</string> + <string name="ca_title">CA sertifikaat</string> + <string name="no_certificate">Peate valima sertifikaadi</string> + <string name="copyright_guicode">Lähtetekst ja probleemihaldur asuvad veebilehel http://code.google.com/p/ics-openvpn/</string> + <string name="copyright_others">Programmis kasutatakse järgnevaid komponente. Detailse litsenseerimisinfo leiate lähtekoodist</string> + <string name="about">Lähemalt</string> + <string name="vpn_list_title">Profiilid</string> + <string name="vpn_type">Tüüp</string> + <string name="pkcs12pwquery">PKCS12 salasõna</string> + <string name="file_select">Vali…</string> + <string name="file_nothing_selected">Valige fail</string> + <string name="useTLSAuth">Kasuta TLS autentimist</string> + <string name="tls_direction">TLS suund</string> + <string name="ipv6_dialog_tile">Sisesta IPv6 Aadress/Võrgumask CIDR formaadis (nt. 2000:dd::23/64)</string> + <string name="ipv4_dialog_title">Sisesta IPv4 Aadress/Võrgumask CIDR formaadis (nt. 1.2.3.4/24)</string> + <string name="ipv4_address">IPv4 aadress</string> + <string name="ipv6_address">IPv6 aadress</string> + <string name="custom_option_warning">Sisestage OpenVPN kohandatud valikud. Ettevaatlikkus ei tee paha. Palun samuti tähele panna et VPNSettings API ei toeta paljusid tun liidesega seotud OpenVPN seadistusi. Siiski, kui te leiate et mõni oluline seadistusvalik on puudu, siis kontakteeruge programmi autoriga</string> + <string name="auth_username">Kasutajanimi</string> + <string name="auth_pwquery">Salasõna</string> + <string name="static_keys_info">Staatilise konfiguratsiooni puhul kasutatakse TLS Auth võtmeid staatiliste võtmetena</string> + <string name="configure_the_vpn">Konfigureeri VPN</string> + <string name="menu_add_profile">Lisa profiil</string> + <string name="add_profile_name_prompt">Lisage uuele profiilile osutav nimi</string> + <string name="duplicate_profile_name">Palun sisestage unikaalne profiilinimi</string> + <string name="profilename">Profiili nimi</string> + <string name="no_keystore_cert_selected">Peate valima kasutaja sertifikaadi</string> + <string name="no_error_found">Vigu ei leitud</string> + <string name="config_error_found">Konfiguratsiooni viga</string> + <string name="ipv4_format_error">Sisestatud IPv4 aadress ei allu süntaksianalüüsile</string> + <string name="custom_route_format_error">Kohandatud marsruudid ei allu süntaksianalüüsile</string> + <string name="pw_query_hint">(jäta tühjaks, küsitakse vajadusel)</string> + <string name="vpn_shortcut">OpenVPN kiirkäivitus</string> + <string name="vpn_launch_title">Ühendu VPN\'iga</string> + <string name="shortcut_profile_notfound">Lühivalikus määratud profiil puudub</string> + <string name="random_host_prefix">Juhuslik serveri eesliide</string> + <string name="random_host_summary">Lisab 6 juhuslikku tähte serveri nime ette</string> + <string name="custom_config_title">Luba kohandatud valikud</string> + <string name="custom_config_summary">Määrake kohandatud valikud. Kasutage ettevaatlikult!</string> + <string name="route_rejected">Androidi poolt keelatud ruutingud</string> + <string name="cancel_connection">Katkesta ühendus</string> + <string name="cancel_connection_long">Katkesta VPN</string> + <string name="clear_log">Tühjenda logi</string> + <string name="title_cancel">Loobu kinnitusest</string> + <string name="cancel_connection_query">Katkesta VPN ühendus/tühista ühendumise katse?</string> + <string name="remove_vpn">Eemalda VPN</string> + <string name="check_remote_tlscert">Kontrollitakse, kas server kasutab sertifikaati koos TLS Server laiendustega (--remote-cert-tls server)</string> + <string name="check_remote_tlscert_title">Oodata TLS serveri sertifikaati</string> + <string name="remote_tlscn_check_summary">Kontrollib eemalasuva serveri sertifikaadi subjekti DN\'i</string> + <string name="remote_tlscn_check_title">Sertifikaadi domeeninime kontroll</string> + <string name="enter_tlscn_dialog">Määrake meetod millega kontrollida eemalasuva sertifikaadi DN (n.: C=DE, L=Paderborn, OU=Avian IP Carriers, CN=openvpn.blinkt.de)\n\nMäärata saab kas täieliku DN, RDN (openvpn.blinkt.de eelmises näites) või eesliitega RDN kontrolli.\n\nRDN eesliite kasutamisel vastab sellele nii \"Server\", \"Server-1\" kui ka \"Server-2\"\n\nTekstivälja tühjaks jätmisel kontrollitakse kas RDN on vastavuses serveri nimega.\n\nDetailsema info leiate OpenVPN 2.3.1+ käsiraamatust —kinnita-x509-nimi all</string> + <string name="enter_tlscn_title">Eemalasuva sertifikaadi subjekt</string> + <string name="tls_key_auth">Lubab TLS võtmega autentimise</string> + <string name="tls_auth_file">TLS Auth fail</string> + <string name="pull_on_summary">Küsib serverist IP aadresse, marsruute ja ajastusvalikuid.</string> + <string name="pull_off_summary">Andmeid ei küsita serverist. Seadistused tuleb määrata allpool.</string> + <string name="use_pull">Sikuta seadistused</string> + <string name="dns">DNS</string> + <string name="override_dns">Eira serveri pakutavaid DNS seadeid</string> + <string name="dns_override_summary">Kasuta oma DNS servereid</string> + <string name="searchdomain">otsinguDomeen</string> + <string name="dns1_summary">Kasutatav DNS server.</string> + <string name="dns_server">DNS server</string> + <string name="secondary_dns_message">Sekundaarne DNS server mida kasutatakse kui vaikimisi DNS server on kättesaamatu.</string> + <string name="backup_dns">VaruDNS server</string> + <string name="ignored_pushed_routes">Ignoreeri serveri pakutavaid marsruute</string> + <string name="ignore_routes_summary">Ignoreeri serveri \'push\' direktiivi ruutinguid.</string> + <string name="default_route_summary">Suuna kogu võrguliiklus VPN kaudu</string> + <string name="use_default_title">Kasuta vaikeruutingut</string> + <string name="custom_route_message">Sisesta oma personaalsed ruutingud. Sihtkoht peab olema CIDR formaadis. \"10.0.0.0/8 2002::/16\" suunab võrgud 10.0.0.0/8 ja 2002::/16 VPN kaudu.</string> + <string name="custom_routes_title">Marsruutide kohandamine</string> + <string name="log_verbosity_level">Logimise detailsus</string> + <string name="float_summary">Suvalise IP autenditud paketid on lubatud</string> + <string name="float_title">Luba \'ujuv\' server</string> + <string name="custom_options_title">Kohandatud valikud</string> + <string name="edit_vpn">Muuda VPN seadistusi</string> + <string name="remove_vpn_query">Kas eemaldada VPN profiil \'%s\'?</string> + <string name="tun_error_helpful">Mõnel modifitseeritud ICS versioonil võivad /dev/tun õigused olla valed, või selle moodul sootuks puududa. CM9 puhul võib probleemi lahendada üldiste seadistuste alt omanikuõiguste parandamine</string> + <string name="tun_open_error">Tun liidese avamine ebaõnnestus</string> + <string name="error">"Viga:"</string> + <string name="clear">Tühjenda</string> + <string name="last_openvpn_tun_config">tun liidese avamine:</string> + <string name="local_ip_info">Lokaalne IPv4: %1$s/%2$d IPv6: %3$s MTU: %4$d</string> + <string name="dns_server_info">DNS server: %1$s, Domeen: %2$s</string> + <string name="routes_info_incl">Marsruudid: %1$s %2$s</string> + <string name="routes_info_excl">Välistatud marsruudid: %1$s %2$s</string> + <string name="routes_debug">Määratud VpnService marsruudid: %1$s %2$s</string> + <string name="ip_not_cidr">Liidese andmed on %1$s ja %2$s, eeldades et teine aadress on eemalasuva serveri aadress. Lokaalse IP jaoks kasutatakse /32 võrgumaski. OpenVPN teatab režiimiks %3$s\".</string> + <string name="route_not_cidr">%1$s ja %2$s on mõttetud CIDR võrgumaskiga IP marsruutidest, võrgumaskiks määratakse /32.</string> + <string name="route_not_netip">%1$s/%2$s marsruut parandatud: %3$s/%2$s</string> + <string name="keychain_access">Androidi Keychain sertifikaadid on kättesaamatud. See võib olla põhjustatud püsivara uuendamisest või appide/apiseadistuste taastamisest. Sertifikaatide pääsuõiguste taastamiseks redigeerige palun VPN seadistusi ja valige uuesti üldiste seadistuste alt sertifikaat.</string> + <string name="version_info">%1$s %2$s</string> + <string name="send_logfile">Saada logifail</string> + <string name="send">Saada</string> + <string name="ics_openvpn_log_file">ICS OpenVPN logifail</string> + <string name="copied_entry">Logikirje kopeeriti lõikepuhvrisse</string> + <string name="tap_mode">Tap liides</string> + <string name="faq_tap_mode">VPNService API ei toeta tap liidest. Seega ei ole ruutimata seadmel selle programmiga tap liidese kasutamine võimalik</string> + <string name="tap_faq2">Jälle? Kas teete nalja? Tap režiim pole tõepoolest toetatud ja selle lunimine e-kirjade vahendusel ei anna tulemusi.</string> + <string name="tap_faq3">Ja juba kolmas kord? Noh, kui päris aus olla, siis tun liidesel töötava tap emulaatori kirjutamine, mis lisaks saatmisel layer2 informatsiooni ja eemaldaks selle taas vastuvõtmisel, on muidugi võimalik. Aga see emulaator peaks sisaldama ka ARP ja DHCP klienti. Mul ei ole andmeid et keegi selle kallal töötaks. Aga kui soovite selle töö ette võtta, siis kontakteeruge palun minuga.</string> + <string name="faq">KKK</string> + <string name="copying_log_entries">Logikirjete kopeerimine</string> + <string name="faq_copying">Ühe logikirje kopeerimiseks vajuta ja hoia sellel kirjel. Kogu logi kopeerimiseks/saatmiseks kasuta Saada Logi valikut. Kui see valik puudub GUI all, siis kasuta riistvaralist menüünuppu.</string> + <string name="faq_shortcut">Kiirkäivitus</string> + <string name="faq_howto_shortcut">Saate paigaldada seadme töölauale OpenVPN kiirkäivituse. Selleks tuleb sõltuvalt teie seadme ekraanihalduri programmist kasutada kas kiirkäivitusikooni või vidinat.</string> + <string name="no_vpn_support_image">Teie süsteemitarkvara ei toeta VPNService API\'t, vabandame :(</string> + <string name="encryption">Krüpteerimine</string> + <string name="cipher_dialog_title">Vali krüpteerimismeetod</string> + <string name="chipher_dialog_message">Sisestage OpenVPN poolt kasutatav krüptošifri algoritm. Tühi väli tähendab vaikešifrit.</string> + <string name="auth_dialog_message">Sisestage OpenVPN poolt kasutatav autentimise räsifunktsioon. Tühi väli tähendab vaikeräsi.</string> + <string name="settings_auth">Autentimine/Krüpteerimine</string> + <string name="file_explorer_tab">Failihaldur</string> + <string name="inline_file_tab">Integreeritud fail</string> + <string name="error_importing_file">Viga faili importimisel</string> + <string name="import_error_message">Faili importimine failisüsteemist ebaõnnestus</string> + <string name="inline_file_data">[[tekstisisene faili info]]</string> + <string name="opentun_no_ipaddr">IP andmeteta keeldutakse tun liidese avamisest</string> + <string name="menu_import">Impordi profiil ovpn failist</string> + <string name="menu_import_short">Impordi</string> + <string name="import_content_resolve_error">Imporditava faili lugemine ebaõnnestus</string> + <string name="error_reading_config_file">Viga konfiguratsioonifaili lugemisel</string> + <string name="add_profile">lisa profiil</string> + <string name="import_could_not_open">Ei õnnestunud leida imporditavas konfiguratsioonifailis mainitud faili: %1$s</string> + <string name="importing_config">Allikast %1$s imporditakse konfiguratsioonifaili</string> + <string name="import_warning_custom_options">Teie konfiguratsioon sisaldas seadistusi mida ei saa liigitada ühegi graafilise kasutajaliidese poolt pakutava seadistuse alla. Need valikud lisati kui kohandatud seadistusvalikud. Kohandatud konfiguratsiooni kuvatakse allpool:</string> + <string name="import_done">Konfiguratsioonifail loetud.</string> + <string name="nobind_summary">Ära seo lokaalse aadressi ja pordiga</string> + <string name="no_bind">Lokaalne sidumine puudub</string> + <string name="import_configuration_file">Impordi konfiguratsioonifail</string> + <string name="faq_security_title">Turvakaalutlused</string> + <string name="faq_security">"Kuna OpenVPN puhul on turvalisus oluline siis on õigustatud mõned märkused. Kõik sdcard seadmel asuvad andmed on iseenesest ebaturvalised kuna suvaline programm saab neid lugeda (näiteks käesolev programm ei vaja spetsiifilisi sd card õiguseid). Samas, kindla programmi andmed on loetavad ainult sellesama programmi poolt. Kui importida cacert/cert/key andmed faili dialoogi abil, siis salvestatakse need andmed VPN profiili mis on loetav ainult käesoleva programmi poolt. (Pärast andmete importimist ära unusta kustutada koopiad sd kaardilt). Ehkki profiili andmed on loetavad ainult käesoleva programmi poolt, on nad siiski krüpteerimata ja ruuditud seade või mõni exploit võimaldab neid sellegipoolest lugeda. Sealhulgas ei ole krüptitud ka salvestatud paroolid. Pkcs12 failide puhul on tungivalt soovitatav nende importimine android keystore\'sse."</string> + <string name="import_vpn">Impordi</string> + <string name="broken_image_cert_title">Viga sertifikaadivaliku näitamisel</string> + <string name="broken_image_cert">Android 4.0+ sertifikaadivaliku dialoogi näitamise katsel tekkis erandolukord. Seda ei tohiks kunagi juhtuda kuna tegu on Android 4.0+ standardfunktsiooniga. Ehk on teie Androidi sertifikaadihoidla ROM tugi riknenud</string> + <string name="ipv4">IPv4</string> + <string name="ipv6">IPv6</string> + <string name="speed_waiting">Ootan olekuteadet…</string> + <string name="converted_profile">imporditud profiil</string> + <string name="converted_profile_i">imporditud profiil %d</string> + <string name="broken_images">Probleemsed Androidi püsivara versioonid</string> + <string name="broken_images_faq"><p>Ametlikel HTC versioonidel teatakse olevat kummaline marsruutimisprobleem, mille tulemusel ei liigu andmevoog läbi tunneli (Vaata ka <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=18\">Issue 18</a> veahalduses.)</p><p>Ametlike vanemate SONY Xperia arc S ja Xperia Ray versioonide puhul on raporteeritud ka täielikku VPNService API puudumist. (Vaata ka <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=29\">Issue 29</a> veahalduses.)</p><p>Kohandatud tarkvaraversioonides võib puududa tun moodul või /dev/tun õigused võivad olla valed. Mõned CM9 versioonid nõuavad \"seadmespetsiifiliste häkkide\" alt \"õiguste parandamise\" valiku kasutamist.</p><p>Aga mis kõige olulisem: kui teil juhtub olema vigane tarkvaraversioon, siis teatage sellest oma tarnijale. Mida rohkem kliente tarnijat seadme probleemidest teavitab, seda suurema tõenäosusega tehakse seadme tarkvara ka korda.</p></string> + <string name="pkcs12_file_encryption_key">PKCS12 faili krüpteerimisvõti</string> + <string name="private_key_password">Privaatse võtme salasõna</string> + <string name="password">Salasõna</string> + <string name="file_icon">faili ikoon</string> + <string name="tls_authentication">TLS autentimine</string> + <string name="generated_config">Genereeritud konfiguratsioon</string> + <string name="generalsettings">Seaded</string> + <string name="owner_fix_summary">Püütakse seada /dev/tun omanikku system\'iks. VPNService API nõuab seda mõne CM9 versiooni puhul. Seade peab olema ruuditud.</string> + <string name="owner_fix">Korrasta /dev/tun omanikuõigused</string> + <string name="generated_config_summary">Näitab genereeritud OpenVPN konfiguratsioonifaili</string> + <string name="edit_profile_title">Redigeeritakse \"%s\"</string> + <string name="building_configration">Koostatakse konfiguratsiooni…</string> + <string name="netchange_summary">Selle valiku aktiveerimine kutsub esile VPN uuestiühendumise kui võrgu olek muutub (nt. WIFI peale/pealt mobiilile)</string> + <string name="netchange">Uuestiühendus võrgu oleku muutumisel</string> + <string name="netstatus">Võrgu olek: %s</string> + <string name="extracahint">CA sertifikaat saadakse tavaliselt Androidi võtmehoidlast. Kui sertifikaadi kontrollimisel esineb probleeme, siis määrake palun sertifikaat ise.</string> + <string name="select_file">Vali</string> + <string name="keychain_nocacert">Androidi võtmehoidlast lugemine ei andnud ühtegi CA sertifikaati. Suure tõenäosusega autentimine ebaõnnestub.</string> + <string name="show_log_summary">Näitab ühendumisel logiakent. Logiakna saab alati ette manada VPN teatisealast.</string> + <string name="show_log_window">Näita logiakent</string> + <string name="mobile_info">Töötamas %1$s (%2$s) %3$s peal, Android API %4$d</string> + <string name="error_rsa_sign">Viga allkirjastamisel Androidi võtmehoidla võtmega %1$s: %2$s</string> + <string name="faq_system_dialogs">VPN ühendumisel ilmub ekraanile hoiatus et see programm võib pealt kuulata kogu võrguliiklust. Tegemist on VPNService API süsteemse hoiatusega et hoida ära väärkasutust.\nVPN ühenduse teatis (Võtme sümbol) on samuti VPNService API poolt kuvatav aktiivse VPN ühenduse indikaator. Mõne süsteemitarkvara puhul võib see indikaator anda märku ka heliga.\nNeed teatised on Androidi süsteemile lisatud teie turvalisuse tagamiseks ja samuti on välistatud nende kasutamisest mööda minemine. (Kahjuks tähendab see seda et mõne süsteemitarkvara puhul kaasneb ühendusega alati ka heliteade)</string> + <string name="faq_system_dialogs_title">Hoiatused ja helimärguanded ühenduse loomisel</string> + <string name="translationby">Eesti keelde tõlkis Robert Tiismus</string> + <string name="ipdns">IP ja DNS</string> + <string name="basic">Põhilised seaded</string> + <string name="routing">Marsruutimine</string> + <string name="obscure">Harvaesinevad OpenVPN seaded. Tavaliselt ebavajalikud.</string> + <string name="advanced">Põhjalikum</string> + <string name="export_config_title">ICS OpenVPN konfiguratsioon</string> + <string name="warn_no_dns">Kasutuses pole ühtegi DNS serverit. Nimelahendus ei pruugi töötada. Kaaluge kohandatud DNS serverite konfiguratsiooni. Pange tähele et DNS seadete puudumisel jätkab Android teie mobiilse/Wi-Fi proxy seadete kasutamist.</string> + <string name="dns_add_error">DNS serveri \"%1$s\" lisamine ebaõnnestus, süsteemi poolt keelduti: %2$s</string> + <string name="ip_add_error">IP aadressi \"%1$s\" seadistamine ei õnnestunud, süsteemi poolt välja praagitud: %2$s</string> + <string name="faq_howto"><p>Hankige töötav konfiguratsioon (kas arvutis järele proovitud või alla laetud võrguteenusepakkuja/organisatsiooni veebilehelt)</p><p>Kui tegu on ainult ühe failiga millega ei kaasne pem/pkcs12 faile, siis saad selle saata e-kirjas manusena iseendale. Kui faile on mitu, saab need kopeerida sdcard peale.</p><p>Kliki saabunud e-kirja manusele ja kasuta konfiguratsiooni importimiseks vpn kaustaikooni.</p><p>Kui siiski esineb puuduvatele failidele viitavaid vigu, siis kopeeri puuduvad failid sdcard peale.</p><p>Imporditud VPN lisamiseks ühenduste nimekirjale, klikkige salvestussümbolile.</p><p>VPN ühenduse loomiseks kliki loodud VPN ühenduse nimele.</p><p>Ekraanil nähtav logi lihtsustab esineda võivate probleemide/vigade lahendamist.</p> </string> + <string name="faq_howto_title">Kasutamise lühijuhend</string> + <string name="setting_loadtun_summary">Proovi enne ühendumist laadida tun.ko tuumamoodul. Nõuab ruuditud seadet.</string> + <string name="setting_loadtun">Laadi tun moodul</string> + <string name="importpkcs12fromconfig">Lae PKCS12 OpenVPN konfiguratsioonist Androidi võtmehoidlasse</string> + <string name="getproxy_error">Viga proxy seadistuste vastuvõtul: %s</string> + <string name="using_proxy">Kasutusel proxy %1$s %2$d</string> + <string name="use_system_proxy">Kasuta süsteemset proxy\'t</string> + <string name="use_system_proxy_summary">Kasuta ühendumisel süsteemse HTTP/HTTPS proxy konfiguratsiooni.</string> + <string name="donatewithpaypal">Sul on võimalus <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;cmd=_s-xclick\">annetada PayPal vahendusel</a> </string> + <string name="onbootrestartsummary">Kui VPN oli süsteemi uuestilaadimisel/sulgemisel aktiivne siis taastatakse seadme käivitamisel OpenVPN ühendus. Palun lugege enne selle valiku kasutamist läbi ühendumise hoiatuse KKK.</string> + <string name="onbootrestart">Uuestilaadimisel ühendu uuesti</string> + <string name="ignore">Ignoreeri</string> + <string name="restart">Uuestilaadimine</string> + <string name="restart_vpn_after_change">Konfiguratsioonimuudatused rakendatakse peale VPN uuestilaadimist. Kas soovite VPN kohe (uuesti)laadida?</string> + <string name="configuration_changed">Konfiguratsiooni muudeti</string> + <string name="log_no_last_vpn">Viimast kasutatud profiili pole redigeerimiseks võimalik tuvastada</string> + <string name="faq_duplicate_notification_title">Mitu teatisikooni</string> + <string name="faq_duplicate_notification">Kui Androidi süsteemimälu (RAM) on täitumas, siis eemaldatakse aktiivsest kasutusest hetkel ebavajalikud programmid ja teenused. Sellega võib kaasneda muu hulgas ka VPN ühenduse katkemine. Katkestuste välistamiseks töötab OpenVPN teenus kõrgendatud prioriteediga. Kuid prioriteeti tõstmisel kuvab Androidi süsteem sellekohane teavitusikooni. Võtme ikooniga teavitus on määratud VPNService API poolt, millest oli juttu ka eelmises KKK lõigus ja see ei lähe arvesse programmi kõrgendatud prioriteedist teatava ikoonina.</string> + <string name="no_vpn_profiles_defined">VPN profiile pole defineeritud.</string> + <string name="add_new_vpn_hint">Kasuta uue VPN lisamiseks <img src=\"ic_menu_add\"/> ikooni</string> + <string name="vpn_import_hint">Kasuta olemasoleva (.ovpn või .conf) profiili importimiseks sdcard pealt <img src=\"ic_menu_archive\"/> ikooni.</string> + <string name="faq_hint">Kindlasti vaata KKK\'d. See sisaldab ka alustamise lühijuhendit.</string> + <string name="faq_routing_title">Marsruutimine ja võrguliidese konfigureerimine</string> + <string name="faq_routing">Ruutingu ja võrguliideste seadistust ei tehta mitte traditsiooniliste ifconfig/route käskudega vaid VPNService API abil. Tulemuseks on teistest operatsioonisüsteemidest erinev ruutingu seadistus. Seadistuses on määratud tunneliliidese IP aadress ja need võrgud, mille kasutus peab toimuma üle tunneli. Täpsemalt: pole vaja määrata ei tunneliserveri ega lüüsi aadressi. Pole vaja ka VPN serverini ühenduse loomise eriruutinguid (näiteks need mida lisatakse redirect-gateway abil). Sellest lähtuvalt käesolev app lihtsalt ignoreerib neid seadeid. App kindlustab VPNService API vahenditega et otseühendust VPN serverisse ei ruuditaks läbi tunneli. Kuna seadistustes on toetatud ainult tunneli kaudu ruuditavate võrkude määratlused siis lisamarsruudid, mis ei osuta tunnelile, ei ole samuti toetatud. (n. route x.x.x.x y.y.y.y net_gateway). Logiaken peegeldab peale VPN ühenduse loomist kehtivat VPNService seadistust. </string> + <string name="persisttun_summary">Ära taasta otseühendust kui OpenVPN on taasühendumas.</string> + <string name="persistent_tun_title">Katkematu tun</string> + <string name="openvpn_log">OpenVPN Logi</string> + <string name="import_config">Impordi OpenVPN konfiguratsioon</string> + <string name="battery_consumption_title">Akukasutus</string> + <string name="baterry_consumption">Minu isiklike testide põhjal kulutavad akut peamiselt OpenVPN ülalhoide (keepalive) paketid. Enamik OpenVPN serverieid kasutab sarnast direktiivi nagu \'keepalive 10 60\' mis määrab kliendilt serverile ja serverilt kliendile saadetavate keepalive pakettide intervalliks 10 sekundit. <p> Ehkki ülalhoidepaketid on väikesed ja ei põhjusta märgatavat võrguliiklust, ei lase nad mobiilse ühenduse raadiovõrgukiibil lülituda energiasäästurežiimi. (Vaata ka <a href=\"http://developer.android.com/training/efficient-downloads/efficient-network-access.html#RadioStateMachine\">The Radio State Machine | Android Developers</a>) <p> Nimetatud ülalhoidepaketi seadistused ei ole kliendi poolt muudetavad ja neid seadistusi saab muuta ainult OpenVPN serveri süsteemiadministraator. <p> Kahjuks esineb üle 60 sekundi pikkuse keepalive puhul probleeme UDP protokolliga üle mõnede NAT võrguväratite ühenduse aegumise tõttu. TCP protokolliga seda probleemi ei esine, kuid TCP üle TCP tunnel töötab üüratult viletsasti üle kõrge paketikaoga linkide. (Vaata <a href=\"http://sites.inka.de/bigred/devel/tcp-tcp.html\">Miks TCP üle TCP on halb mõte</a>)</string> + <string name="faq_tethering">Android Tethering (üle WiFi, USB või Bluetoothi) ja VPNService API (mida käesolev programm kasutab) ei ole koos kasutatavad. Täpsemad detailid leiad <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=34\">issue #34</a></string> + <string name="vpn_tethering_title">VPN ja tether</string> + <string name="connection_retries">Ühendumise korduskatseid</string> + <string name="reconnection_settings">Taasühendusseaded</string> + <string name="connectretrymessage">Mitu sekundit oodata ühendumiskatsete vahel.</string> + <string name="connectretrywait">Sekundeid ühenduste vahel</string> + <string name="minidump_generated">OpenVPN jooksis ootamatult kokku. Palun kaaluge \"saada Minitõmmis\" valiku lubamist peamenüüs</string> + <string name="send_minidump">Saada arendajale minitõmmis</string> + <string name="send_minidump_summary">Saada eelmise kokkujooksmise kohta käiv silumisinfo arendajale</string> + <string name="notifcation_title">OpenVPN - %s</string> + <string name="session_ipv4string">%1$s - %2$s</string> + <string name="session_ipv6string">%1$s - %3$s, %2$s</string> + <string name="state_connecting">Ühendumine</string> + <string name="state_wait">Serveri vastuse ootamine</string> + <string name="state_auth">Autentimine</string> + <string name="state_get_config">Kliendikonfiguratsiooni lugemine</string> + <string name="state_assign_ip">IP-aadressite omistamine</string> + <string name="state_add_routes">Marsruutide lisamine</string> + <string name="state_connected">Ühendatud</string> + <string name="state_disconnected">Katkesta ühendus</string> + <string name="state_reconnecting">Taasühendumine</string> + <string name="state_exiting">Väljumine</string> + <string name="state_noprocess">Ei tööta</string> + <string name="state_resolve">Arvutinimede lahendamine</string> + <string name="state_tcp_connect">Ühendumine (TCP)</string> + <string name="state_auth_failed">Autentimine ebaõnnestus</string> + <string name="state_nonetwork">Oodatakse kasutatavat võrku</string> + <string name="statusline_bytecount">↓%2$s/s %1$s - ↑%4$s/s %3$s</string> + <string name="notifcation_title_notconnect">Pole ühendatud</string> + <string name="start_vpn_title">Ühendumine VPN %s külge</string> + <string name="start_vpn_ticker">Ühendumine VPN %s külge</string> + <string name="jelly_keystore_alphanumeric_bug">Mõnede Android 4.1 versioonide puhul esineb probleeme kui võtmehoidla sertifikaadi nimi sisaldab mittetähestikulisi sümboleid (nagu tühikud, alakriipsud või sidekriipsud). Proovige selline sertifikaat erisümboliteid kasutamata uuesti importida</string> + <string name="encryption_cipher">Krüptošiffer</string> + <string name="packet_auth">Pakettide autentimine</string> + <string name="auth_dialog_title">Sisestage pakettide autentimismeetod</string> + <string name="mobile_info_extended">Töötab seadmel %1$s (%2$s) %3$s, Android API %4$d, versioon %5$s, %6$s</string> + <string name="built_by">Kompileerija: %s</string> + <string name="debug_build">Silumisversioon</string> + <string name="official_build">Ametlik versioon</string> + <string name="make_selection_inline">Kopeeri profiili</string> + <string name="crashdump">Pangestustõmmis</string> + <string name="add">Lisa</string> + <string name="send_config">Saada konfiguratsioonifail</string> + <string name="complete_dn">Täielik DN</string> + <string name="remotetlsnote">Teie imporditud konfiguratsioon kasutab vana ja TAUNITAVAT tls-remote valikut mis kasutab erinevat DN kuju.</string> + <string name="rdn">RDN (ühine nimi)</string> + <string name="rdn_prefix">RDN eesliide</string> + <string name="tls_remote_deprecated">tls-remote (TAUNITAV)</string> + <string name="help_translate">Tõlkimisel saate abi pakkuda külastades veebilehte http://crowdin.net/project/ics-openvpn/invite</string> + <string name="prompt">%1$s katset et juhtida %2$s</string> + <string name="remote_warning">Jätkates annate sellele programmile täieliku kontrolli üle Androidi OpenVPN-i ja samuti õiguse jälgida kogu võrguliiklust. <b> Kui te ei usalda seda programmi, siis ÄRGE NÕUSTUGE. </b> Vastasel juhul seate oma andmed pahatahtliku tarkvara poolt ohtu.\"</string> + <string name="remote_trust">Ma usaldan seda programmi.</string> + <string name="no_external_app_allowed">Ühelgi programmil pole luba kasutada välist API-t</string> + <string name="allowed_apps">Lubatud programmid: %s</string> + <string name="clearappsdialog">Kas tühjenda lubatud väliste programmide nimekiri?\nKehtiv lubatud programmide nimekiri:\n\n%s</string> + <string name="screenoff_summary">\"Peata VPN kui ekraan on välja lülitatud ja viimase 60s jooksul on üle kantud alla 64kB anmeid. Kui \"Katkematu Tun\" valik on sees, siis jätab VPN peatamine teie seadme ilma võrguühenduseta. \"Katkematu Tun\" valikuta ei ole aga seadmel VPN ühendust/kaitset.</string> + <string name="screenoff_title">Peata VPN ühendus peale ekraani välja lülitamist</string> + <string name="screenoff_pause">Ühenduse peatamine väljalülitatud ekraani korral: vähem kui %1$s %2$ss jooksul</string> + <string name="screen_nopersistenttun">Hoiatus: Katkematu tun ei ole sellel seadmel sisse lülitatud. Andmed liiguvad ekraani välja lülitamisel tavalise Internetiühenduse kaudu.</string> + <string name="save_password">Salvesta parool</string> + <string name="pauseVPN">Peata VPN</string> + <string name="resumevpn">Jätka VPN</string> + <string name="state_userpause">Kasutaja nõudis VPN peatamist</string> + <string name="state_screenoff">VPN peatatud - ekraan väljas</string> + <string name="device_specific">Seadmespetsiifilised häkid</string> + <string name="cannotparsecert">Sertifikaadiinfo kuvamine ei õnnestu</string> + <string name="appbehaviour">Rakenduse käitumine</string> + <string name="vpnbehaviour">VPN käitumine</string> + <string name="allow_vpn_changes">Luba muudatused VPN profiilides</string> + <string name="hwkeychain">Riistvaraline võtmehoidla:</string> + <string name="permission_icon_app">\'OpenVPN Androidile\' üritatakse kasutada programmi ikooni poolt</string> + <string name="faq_vpndialog43">"Alates Android 4.3 versioonist kaitstakse VPN kinnitust \"kattuvate programmide\" eest. Selle tulemusena ei reageeri dialoog puutesisendile. Võite sattuda sellisele probleemile kui teil on programm, mis kasutab kattumist. Leides sellise häiriva programmi, teavitage sellest programmi autorit. Nimetatud probleem mõjutab kõiki VPN programme alates Android 4.3 versioonist. Lisadetailid: <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=185\"> teema 185</a>"</string> + <string name="faq_vpndialog43_title">Android 4.3 (ja hilisemate) VPN kinnitusdialoog</string> + <string name="donatePlayStore">Võite saata mulle annetusena raha ka Play Store kaudu:</string> + <string name="thanks_for_donation">Aitäh annetatud %s eest!</string> + <string name="logCleared">Logi tühjendatud.</string> + <string name="show_password">Näita salasõna</string> + <string name="keyChainAccessError">Viga KeyChain poole pöördumisel: %s</string> + <string name="timestamp_short">Lühike</string> + <string name="timestamp_iso">ISO</string> + <string name="timestamps">Ajatemplid</string> + <string name="timestamps_none">Ükski</string> + <string name="uploaded_data">Üleslaadimine</string> + <string name="downloaded_data">Allalaadimine</string> + <string name="vpn_status">Vpn olek</string> + <string name="logview_options">Kuva valikud</string> + <string name="unhandled_exception">Käsitlematu erand: %1$s\n\n%2$s</string> + <string name="unhandled_exception_context">%3$s: %1$s\n\n%2$s</string> + <string name="faq_system_dialog_xposed">Kui olete ome Androidiseadme ruutinud, saate paigaldada omal riisikol <a href=\"http://xposed.info/\">Xposed framework</a> ja <a href=\"http://repo.xposed.info/module/de.blinkt.vpndialogxposed\">VPN Dialoogi kinnitusmooduli</a>\"</string> + <string name="full_licenses">Kõik litsentsid</string> +</resources> diff --git a/main/src/main/res/values-fr/arrays.xml b/main/src/main/res/values-fr/arrays.xml new file mode 100755 index 00000000..24bedc52 --- /dev/null +++ b/main/src/main/res/values-fr/arrays.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string-array name="vpn_types"> + <item>Certificats</item> + <item>Fichier PKCS12</item> + <item>Certificat Android</item> + <item>Utilisateur / Mot de passe</item> + <item>Clés statiques</item> + <item>Nom/MDP + Certificats</item> + <item>Nom/MDP + PKCS12</item> + <item>Nom/MDP + Android</item> + </string-array> + <string-array name="tls_directions_entries"> + <item>0</item> + <item>1</item> + <item>Non spécifié</item> + </string-array> + <string-array name="crm_entries"> + <item>No reconnection retries</item> + <item>One reconnection retry</item> + <item>Five reconnection retries</item> + <item>Fifty reconnection retries</item> + <item>Unlimited reconnection retries</item> + </string-array> +</resources> diff --git a/main/src/main/res/values-fr/strings.xml b/main/src/main/res/values-fr/strings.xml new file mode 100755 index 00000000..d7d46c2d --- /dev/null +++ b/main/src/main/res/values-fr/strings.xml @@ -0,0 +1,274 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string name="app">"OpenVPN pour Android"</string> + <string name="address">"Adresse du serveur:"</string> + <string name="port">"Port du serveur:"</string> + <string name="location">"Emplacement"</string> + <string name="cant_read_folder">"Le dossier ne peut être lu !"</string> + <string name="select">"Sélectionner"</string> + <string name="cancel">"Annuler"</string> + <string name="no_data">"Aucune donnée"</string> + <string name="useLZO">"Compression LZO"</string> + <string name="client_no_certificate">"Aucun certificat"</string> + <string name="client_certificate_title">"Certificat client"</string> + <string name="client_key_title">"Clé du certificat client"</string> + <string name="client_pkcs12_title">"Fichier PKCS12"</string> + <string name="ca_title">"Certificat CA"</string> + <string name="no_certificate">"Vous devez sélectionner un certificat"</string> + <string name="copyright_guicode">"Le code source et le tracker de bugs est disponible ici: http://code.google.com/p/ics-openvpn/ "</string> + <string name="copyright_others">"Le programme utilise les composants suivants. Voir le code source pour plus de détails sur les licences."</string> + <string name="about">"À propos"</string> + <string name="vpn_list_title">Profils</string> + <string name="vpn_type">"Type"</string> + <string name="pkcs12pwquery">"Mot de passe PKCS12"</string> + <string name="file_select">"Sélectionner…"</string> + <string name="file_nothing_selected">Vous devez sélectionner un fichier</string> + <string name="useTLSAuth">"Utiliser l\'authentification TLS"</string> + <string name="tls_direction">"Direction de l\'authentification TLS"</string> + <string name="ipv6_dialog_tile">"Entrez l\'adresse IPv6 / masque de réseau au format CIDR (ex.: 2000:jj::23/64)"</string> + <string name="ipv4_dialog_title">"Saisissez l\'adresse IPv4 / masque de réseau au format CIDR (ex.: 1.2.3.4/24)"</string> + <string name="ipv4_address">"Adresse IPv4"</string> + <string name="ipv6_address">"Adresse IPv6"</string> + <string name="custom_option_warning">"Entrez les options d\'OpenVPN personnalisés. A manipuler avec le plus grand soin. A noter également que de nombreux paramètres Tun d\'OpenVPN ne sont pas pris en charge à cause de la conception de \"VPNSettings\". Si vous pensez qu\'une option importante manque, veuillez contacter l\'auteur"</string> + <string name="auth_username">"Nom d\'utilisateur"</string> + <string name="auth_pwquery">"Mot de passe"</string> + <string name="static_keys_info">"Pour la configuration statique, des clés d\'authentification TLS seront utilisés comme des clés statiques."</string> + <string name="configure_the_vpn">"Configurer le VPN"</string> + <string name="menu_add_profile">"Ajouter un profil"</string> + <string name="add_profile_name_prompt">"Entrez un nom identifiant le nouveau profil"</string> + <string name="duplicate_profile_name">Veuillez entrer un nom de profil unique</string> + <string name="profilename">"Nom de profil"</string> + <string name="no_keystore_cert_selected">"Aucun certificat utilisateur sélectionné."</string> + <string name="no_error_found">"Aucune erreur"</string> + <string name="config_error_found">"Erreur dans la configuration"</string> + <string name="ipv4_format_error">"Impossible d\'analyser l\'adresse IPv4"</string> + <string name="custom_route_format_error">"Impossible d\'analyser les règles de redirection personnalisés"</string> + <string name="pw_query_hint">"Laissez vide pour définir si nécessaire"</string> + <string name="vpn_shortcut">"Raccourci OpenVPN"</string> + <string name="vpn_launch_title">"Se connecter au VPN"</string> + <string name="shortcut_profile_notfound">"Profil spécifié dans raccourci introuvable"</string> + <string name="random_host_prefix">"Préfixe de l\'hôte au hasard"</string> + <string name="random_host_summary">"Ajoute 6 caractères aléatoires en face du nom d\'hôte"</string> + <string name="custom_config_title">"Activer les options personnalisées"</string> + <string name="custom_config_summary">"Spécifiez les options personnalisées. A utiliser avec précaution !"</string> + <string name="route_rejected">"Route rejetée par Android"</string> + <string name="cancel_connection">"Déconnecter"</string> + <string name="cancel_connection_long">Déconnecter le VPN</string> + <string name="clear_log">"Effacer les logs"</string> + <string name="title_cancel">"Annuler la confirmation"</string> + <string name="cancel_connection_query">"Déconnecter le VPN connecté / annuler la tentative de connexion ?"</string> + <string name="remove_vpn">"Retirer le VPN"</string> + <string name="check_remote_tlscert">Vérifier si le serveur utilise des certificats avec les extensions TLS serveur (--remote-cert-tls serveur)</string> + <string name="check_remote_tlscert_title">Attendre un certificat de serveur TLS</string> + <string name="remote_tlscn_check_title">"Vérification du certificat de l\'hôte"</string> + <string name="tls_key_auth">"Activer l\'authentification par clé TLS"</string> + <string name="tls_auth_file">"Fichier d\'authentification TLS"</string> + <string name="pull_on_summary">"Demande les adresses IP, les règles de redirection et les options de synchronisation du serveur."</string> + <string name="pull_off_summary">"Aucune information n\'est demandée par le serveur. Les paramètres doivent être spécifiés ci-dessous."</string> + <string name="use_pull">"Réglages \"Pull\""</string> + <string name="dns">"DNS"</string> + <string name="override_dns">"Remplacer les paramètres DNS par le serveur"</string> + <string name="dns_override_summary">"Utilisez vos propres serveurs DNS"</string> + <string name="searchdomain">"Domaine"</string> + <string name="dns1_summary">"Serveur DNS à utiliser."</string> + <string name="dns_server">"Serveur DNS"</string> + <string name="secondary_dns_message">"Serveur DNS secondaire utilisé si le serveur DNS principal ne peut pas être atteint."</string> + <string name="backup_dns">"Serveur DNS secondaire"</string> + <string name="ignored_pushed_routes">"Ignorer les règles envoyées"</string> + <string name="ignore_routes_summary">"Ignorer les règles de redirection de ports envoyées par le serveur."</string> + <string name="default_route_summary">"Redirige tout le trafic sur la connexion VPN"</string> + <string name="use_default_title">"Utiliser la redirection par défaut"</string> + <string name="custom_route_message">"Entrez les règles de redirection. N\'entrez la destination qu\'au format CIDR. \"10.0.0.0 / 8 2002::/16\" redirigerait les réseaux 10.0.0.0/8 et 2002::/16 via le VPN."</string> + <string name="custom_routes_title">"Règles personnalisés"</string> + <string name="log_verbosity_level">"Niveau de verbosité des logs"</string> + <string name="float_summary">"Autorise les paquets authentifiés à partir de n\'importe quelle adresse IP"</string> + <string name="float_title">"Permettre des serveur flottants"</string> + <string name="custom_options_title">"Options personnalisées"</string> + <string name="edit_vpn">"Modifier les paramètres VPN"</string> + <string name="remove_vpn_query">\"Effacer le profil VPN %s ?\"?</string> + <string name="tun_error_helpful">"Sur certaines ROMs ICS les permissions de /dev/tun peuvent être incorrectes, ou le module Tun peut être manquant. Pour les ROMs CM9, essayez de corriger les options dans \"General Settings\""</string> + <string name="tun_open_error">"L\'ouverture de l\'interface Tun a échoué."</string> + <string name="error">"Erreur: "</string> + <string name="clear">"Effacer"</string> + <string name="last_openvpn_tun_config">Ouverture de l\'interface tun:</string> + <string name="local_ip_info">"IPv4 locale: %1$s/%2$d IPv6: %3$s MTU: %4$d"</string> + <string name="dns_server_info">Serveur DNS: %1$s, Domaine: %2$s</string> + <string name="ip_not_cidr">"Informations récupérées de l\'interface: %1$s et %2$s , en supposant que la seconde adresse est l\'adresse peer du réseau distant. Utilisation du masque de réseau /32 pour l\'IP locale. Mode donné par OpenVPN: \"%3$s\"."</string> + <string name="route_not_cidr">"Ne peut pas donner un sens à %1$s et %2$s comme routage IP avec masque réseau de type CIDR, en utilisant /32 comme masque de réseau."</string> + <string name="route_not_netip">"Règle de redirection corrigée: %1$s / %2$s en %3$s / %2$s"</string> + <string name="keychain_access">\"Impossible d\'accéder aux certificats \"Android Keychain\". (Peut être causé par une mise à jour du firmware ou par une restauration d\'une sauvegarde des paramètres de l\'application). Veuillez modifier le profil VPN et sélectionnez de nouveau le certificat dans les réglages de base pour recréer l\'autorisation d\'accéder au certificat.\".</string> + <string name="version_info">"%1$s %2$s"</string> + <string name="send_logfile">"Envoyer le fichier de log"</string> + <string name="send">"Envoyer"</string> + <string name="ics_openvpn_log_file">"Fichier de log OpenVPN ICS"</string> + <string name="copied_entry">"Entrée du log copiée"</string> + <string name="tap_mode">"Mode TAP"</string> + <string name="faq_tap_mode">"Le mode TAP est indisponible avec l\'API non root VPN. Par conséquent, cette application ne peut pas supporter TAP"</string> + <string name="tap_faq2">\"Encore une fois? Vous plaisantez? Le mode TAP n\'est absolument pas pris en charge et l\'envoi de plus d\'e-mails demandant si il sera intégré ne va en rien aider.\".</string> + <string name="tap_faq3">\"Encore une fois ? En fait il est possible que quelqu\'un puisse écrire un émulateur TAP basé sur TUN qui pourrait analyser des informations de type \"layer2\". Mais cet émulateur devrait aussi implémenter ARP et un client DHCP. Je ne suis actuellement pas au courant que quelqu\'un travail dessus. Contactez moi si vous voulez m\'aider là dessus\".</string> + <string name="faq">"FAQ"</string> + <string name="copying_log_entries">"Copie des entrées du log"</string> + <string name="faq_copying">"Pour copier une seule entrée du log restez appuyé sur celle-ci. Pour copier ou envoyer le log au complet utilisez l\'option \"Envoi du Log\". Utilisez le bouton matériel s\'il n\'est pas visible."</string> + <string name="faq_shortcut">"Raccourci pour démarrer"</string> + <string name="faq_howto_shortcut">Vous pouvez placer un raccourci pour démarrer OpenVPN sur l\'écran d\'accueil. En fonction du programme gérant votre écran d\'accueil, vous devez soit ajouter un raccourci, soit un widget.</string> + <string name="no_vpn_support_image">"Votre ROM ne prend pas en charge l\'API VPNService, désolé :("</string> + <string name="encryption">"Cryptage"</string> + <string name="cipher_dialog_title">"Entrez la méthode de cryptage"</string> + <string name="auth_dialog_message">Entrer le digest à utiliser par OpenVPN pour l\'authentification. Laisser vide pour utiliser l\'algorithme par défaut.</string> + <string name="settings_auth">"Authentification / Cryptage"</string> + <string name="file_explorer_tab">"Explorateur de fichiers"</string> + <string name="inline_file_tab">"Fichier personnalisé"</string> + <string name="error_importing_file">"Impossible d\'importer le fichier"</string> + <string name="import_error_message">"Impossible d\'importer le fichier depuis le système de fichiers"</string> + <string name="inline_file_data">"[[Fichier de données personnalisé]]"</string> + <string name="opentun_no_ipaddr">"Impossible d\'ouvrir le périphérique TUN sans informations IP"</string> + <string name="menu_import">"Importer un profil depuis un fichier .ovpn"</string> + <string name="menu_import_short">"Importer"</string> + <string name="import_content_resolve_error">"Impossible de lire le profil à importer"</string> + <string name="error_reading_config_file">"Erreur de lecture du fichier de configuration"</string> + <string name="add_profile">"Ajouter un profil"</string> + <string name="import_could_not_open">"Impossible de trouver le fichier %1$s mentionné dans le fichier de configuration importé"</string> + <string name="importing_config">"Importation du fichier de configuration depuis %1$s"</string> + <string name="import_warning_custom_options">Votre configuration a quelques options qui ne sont pas prises en compte par l\'interface utilisateur. Ces options ont donc été ajoutées comme des options de configuration personnalisées:</string> + <string name="import_done">"Fin de la lecture du fichier de configuration."</string> + <string name="nobind_summary">"Ne pas se lier à l\'adresse locale et au port"</string> + <string name="no_bind">"Aucune liaison locale"</string> + <string name="import_configuration_file">"Importer un fichier de configuration"</string> + <string name="faq_security_title">"Considérations de sécurité"</string> + <string name="faq_security">"La stratégie de sécurité d\'OpenVPN amène quelque remarques concernant la sécurité des données saisies. En général, toutes les informations stockées sur la carte SD ne sont pas sécurisées. Toute application peut en obtenir l\'accès (par exemple, ce programme ne requiert aucun droit particulier d\'accès à la carte SD). Dans le cas de ce programme, il est le seul à avoir accès à ces données. En utilisant l\'option d\'importation pour les CaCert/Cert/Key, les données sont stockées dans le porfile VPN. Ce dernier est seulement accessible à cette application. Ainsi, veuillez ne pas oublier de supprimer les copies sur la carte SD après importation. Car, même si l\'application en a l\'exclusivité, les données ne sont pas pour autant cryptées. En \"rootant\" l\'appareil ou par d\'autres exploits il est toujours possible d\'accéder à ces informations. A titre d\'exemple, les mots de passe sont stockés en clair. Pour les fichiers de type Pkfcs12, il est fortement recommandé que vous les importiez dans le gestionnaire de clées d\'Android."</string> + <string name="import_vpn">"Importer"</string> + <string name="broken_image_cert_title">"Erreur d\'affichage certificat sélectionné"</string> + <string name="broken_image_cert">"Exception en essayant d\'afficher le dialogue de sélection du certification d\'Android 4.0+. Ceci ne devrait pas se produire car c\'est une des fonctionnalités de base de ce système. Il est donc possible que votre ROM ne supporte pas le stockage de certfiicats."</string> + <string name="ipv4">"IPv4"</string> + <string name="ipv6">"IPv6"</string> + <string name="speed_waiting">"Attente du status…"</string> + <string name="converted_profile">"profil importé"</string> + <string name="converted_profile_i">"profil importé: %d"</string> + <string name="broken_images">"Images corrompues "</string> + <string name="broken_images_faq"><>Les ROMs officielles HTC sont connues pour avoir des problèmes de routage entraînant que le trafic ne passe pas par le tunnel VPN. (C.f.: <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=18\">Issue 18</a> dans le \"bug tacker\")</p><p>Les ROMs officielles de SONY pour le Xperia Arc S et le Xperia Ray ont été signalé comme ne possédant pas le service VPN. Toute autre ROM SONY peut avoir le même problème. (C.f.: <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=29\">Issue 29</a> dans le \"bug tacker\")</p><p>Sur les ROM personnalisées le module TUN peut être manquant ou les droits de /dev/tun peuvent être incorrects. Certaines ROM CM9 peuvent nécessiter d\'utiliser l\'option de correction des droits de /dev/tun accessible depuis les \"Options générales\"/</p><p>Important: Si votre ROM a un problème, contactez le vendeur, il se peut que qu\'il vous fournisse un patch.</p></string> + <string name="pkcs12_file_encryption_key">"Fichier de clé de cryptage PKCS12"</string> + <string name="private_key_password">"Mot de passe de clé privée"</string> + <string name="password">"Mot de passe"</string> + <string name="file_icon">"icône du fichier"</string> + <string name="tls_authentication">"Authentification TLS"</string> + <string name="generated_config">"Configuration générée"</string> + <string name="generalsettings">Paramètres</string> + <string name="owner_fix_summary">"Tente de définir le propriétaire de /dev/tun. Certaines ROMs CM9 en ont besoin pour faire fonctionner l\'API VPNService. Nécessite les droits root."</string> + <string name="owner_fix">"Corriger le propriétaire de /dev/tun"</string> + <string name="generated_config_summary">"Affiche le fichier de configuration OpenVPN généré"</string> + <string name="edit_profile_title">"Modification \"%s\""</string> + <string name="building_configration">"Création de la configuration…"</string> + <string name="netchange_summary">"L\'activation de cette option forcera l\'appareil à se reconnecter si l\'état du réseau change (ex.: WIFI/Mobile)"</string> + <string name="netchange">"Reconnexion lors de changement du réseau"</string> + <string name="netstatus">"État du réseau: %s"</string> + <string name="extracahint">"Le certificat CA est généralement renvoyé par le gestionnaire de clés Android. Spécifiez un certificat distinct si vous obtenez des erreurs de vérification de certificat."</string> + <string name="select_file">"Sélectionner"</string> + <string name="keychain_nocacert">"Aucun certificat CA renvoyée lors de la lecture depuis le gestionnaire de clés. L\'authentification échouera probablement."</string> + <string name="show_log_summary">"Affiche la fenêtre de log à la connexion. Cette fenêtre peut toujours être consultée à partir de la notification d\'état."</string> + <string name="show_log_window">"Afficher la fenêtre de log"</string> + <string name="mobile_info">"Fonctionnant sur %1$s (%2$s) %3$s , Android API %4$d"</string> + <string name="error_rsa_sign">"Erreur de signature de la clé %1$s : %2$s par le gestionnaire d\'Android"</string> + <string name="faq_system_dialogs">\"L\'avertissement de connexion au VPN qui vous informe que cette application peut intercepter tout le trafic est imposé par le système pour éviter les abus de l\'API du service VPN.\nLa notification de connexion au VPN (Le symbole qui ressemble à une clé) est aussi imposé par le système Android pour signaler une connexion VPN en cours de fonctionnement. +Sur certaines images, cette notification joue un son.\nAndroid à introduit ces dialogues système pour votre propre sécurité et à fait en sorte d\'être impossible à contourner. (Cela peut inclure en plus une notification sonore pour certaines images)\"</string> + <string name="faq_system_dialogs_title">"Avertissement de connexion et son de notification"</string> + <string name="translationby">French translation by Stanislas Bach<stanislasbach@gmail.com></string> + <string name="ipdns">"IP et DNS"</string> + <string name="basic">"Base"</string> + <string name="routing">"Redirection de ports"</string> + <string name="obscure">"Réglages OpenVPN avancés"</string> + <string name="advanced">"Avancé"</string> + <string name="export_config_title">"Configuration ICS OpenVPN "</string> + <string name="warn_no_dns">Aucun serveur DNS utilisé. La résolution de noms de domaines peut ne pas fonctionner. Envisager d\'ajouter des serveurs DNS personnalisés. Veuillez également noter que Android va continuer à utiliser vos paramètres de proxy spécifiés pour votre connexion Wi-Fi/mobile lorsque aucun serveur DNS n\'est défini.</string> + <string name="dns_add_error">"Impossible d\'ajouter le serveur DNS \"%1$s\", rejetés par le système: %2$s"</string> + <string name="faq_howto">"<p>Obtenez une configuration fonctionnelle (testé sur un ordinateur ou téléchargé depuis le site de votre fournisseur/entreprise)</p><p>S\'il s\'agit d\'un seul fichier avec aucun fichier Pem/Pks12 supplémentaire, vous pouvez vous envoyer celui par mail et l\'ouvrir directement. Si vous avez plusieurs fichiers de configuration, mettez les sur votre carte SD.</p><p>Cliquez sur la pièce jointe de votre e-mail / Utilisez l\'icône du dossier dans la liste des VPN pour importer le fichier de configuration.</p><p>Si des erreurs concernant des fichiers manquants apparaissent, veuillez mettre les fichiers manquant sur la carte SD.</p><p>Cliquez sur l\'icône \"enregistrer\" pour ajouter le profil VPN importé à la liste.</p><p>Connectez le VPN en cliquant sur son nom dans cette liste.</p><p>Si vous rencontrez des erreurs ou des avertissements, veuillez lire ce qu\'il y a d\'écrit dans le log pour les corriger.</p> "</string> + <string name="faq_howto_title">"Démarrage rapide"</string> + <string name="setting_loadtun_summary">"Essayez de charger le module du noyau \"tun.ko\" avant d\'essayer de vous connecter. Requiert des droits root."</string> + <string name="setting_loadtun">"Charger le module TUN"</string> + <string name="importpkcs12fromconfig">"Importer PKCS12 de la configuration dans le gestionnaire de clés Android"</string> + <string name="getproxy_error">"Erreur d\'obtention des paramètres de proxy: %s"</string> + <string name="using_proxy">"Utilisation du proxy %1$s %2$d"</string> + <string name="use_system_proxy">"Utiliser le proxy système"</string> + <string name="use_system_proxy_summary">"Utiliser la configuration générale du système pour que les proxy HTTP / HTTPS se connectent."</string> + <string name="donatewithpaypal">"Vous pouvez faire un <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&cmd=_s-xclick\">don avec PayPal</ a> "</string> + <string name="onbootrestartsummary">"Reconnecter OpenVPN automatiquement si une connexion était active lors de l\'extinction/redémarrage de l\'appareil. Veuillez lire l\'avertissement de connexion dans la FAQ avant d\'utiliser cette option."</string> + <string name="onbootrestart">"Connexion automatique au redémarrage"</string> + <string name="ignore">"Ignorer"</string> + <string name="restart">"Redémarrer"</string> + <string name="restart_vpn_after_change">"Les changements de configuration sont appliquées après redémarrage du VPN. (Re)démarrer le VPN maintenant?"</string> + <string name="configuration_changed">"Configuration modifiée"</string> + <string name="log_no_last_vpn">"Impossible de déterminer le dernier profil connecté pour l\'édition"</string> + <string name="faq_duplicate_notification_title">"Notifications multiples"</string> + <string name="faq_duplicate_notification">"Si Android tourne sur la mémoire du système (RAM), les application et les services qui ne sont pas nécessaires à un moment sont automatiquement supprimés de la mémoire. Cela stoppe donc la connexion VPN en cours. Pour s\'assurer que celle-ci reste toujours lancée, le service est lancé avec une priorité plus élevée. Pour cela, l\'application doit afficher une notification permanente. L\'icône de \"clé\" dans la notification est imposée par le système comme expliqué dans l\'entrée de la FAQ précédente."</string> + <string name="no_vpn_profiles_defined">"Pas de profils VPN définis."</string> + <string name="add_new_vpn_hint">"Utilisez l\'icône <img src=\"ic_menu_add\"/ pour ajouter un nouveau VPN"</string> + <string name="vpn_import_hint">"Utilisez l\'icône <img src=\"ic_menu_archive\"/> pour importer un fichier profil (.opvpn ou .conf) de votre carte SD."</string> + <string name="faq_hint">"Veillez également à consulter la FAQ. Il s\'y trouve un guide de démarrage rapide."</string> + <string name="faq_routing_title">"Redirections / Configuration de l\'interface"</string> + <string name="persisttun_summary">Ne pas couper la connexion VPN lors de la reconnexion d\'OpenVPN.</string> + <string name="persistent_tun_title">Persistance de l\'interface TUN</string> + <string name="openvpn_log">Log OpenVPN</string> + <string name="import_config">"Importer une configuration OpenVPN"</string> + <string name="battery_consumption_title">"Consommation de la batterie"</string> + <string name="baterry_consumption">In my personal tests the main reason for high battery consumption of OpenVPN are the keepalive packets. Most OpenVPN servers have a configuration directive like \'keepalive 10 60\' which causes the client and server to exchange keepalive packets every ten seconds. <p> While these packets are small and do not use much traffic, they keep the mobile radio network busy and increase the energy consumption. (See also <a href=\"http://developer.android.com/training/efficient-downloads/efficient-network-access.html#RadioStateMachine\">The Radio State Machine | Android Developers</a>) <p> This keepalive setting cannot be changed on the client. Only the system administrator of the OpenVPN can change the setting. <p> Unfortunately using a keepalive larger than 60 seconds with UDP can cause some NAT gateways to drop the connection due to an inactivity timeout. Using TCP with a long keepalive timeout works, but tunneling TCP over TCP performs extremely poorly on connections with high packet loss. (See <a href=\"http://sites.inka.de/bigred/devel/tcp-tcp.html\">Why TCP Over TCP Is A Bad Idea</a>)</string> + <string name="faq_tethering">La fonctionnalité de Tethering Android (sur WiFi, USB ou Bluetooth) et l\'API VPNService (utilisé par ce programme) ne fonctionnent pas ensemble. Pour plus de détails, voir la <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=34\" > page #34 </a></string> + <string name="vpn_tethering_title">VPN et Tethering</string> + <string name="connection_retries">"Tentatives de connexion"</string> + <string name="reconnection_settings">"Paramètres de reconnexion"</string> + <string name="connectretrymessage">"Nombre de secondes d\'attente entre chaque tentative de connexion."</string> + <string name="connectretrywait">"Temps, en secondes, entre deux connexions"</string> + <string name="minidump_generated">OpenVPN s\'est écrasé de façon inattendue. S\'il vous plaît, envisagez d\'utiliser l\'option de Minidump depuis le menu principal</string> + <string name="send_minidump">Envoyer le Minidump au développeur</string> + <string name="send_minidump_summary">Envoyer les informations de débogage à propos du dernier accident au développeur</string> + <string name="notifcation_title">OpenVPN - %s</string> + <string name="session_ipv4string">%1$s - %2$s</string> + <string name="session_ipv6string">%1$s - %3$s, %2$s</string> + <string name="state_connecting">Connexion</string> + <string name="state_wait">En attente de réponse du serveur</string> + <string name="state_auth">Authentification</string> + <string name="state_get_config">Obtention de la configuration du client</string> + <string name="state_assign_ip">Attribution de l\'adresses IP</string> + <string name="state_add_routes">Ajout des routes</string> + <string name="state_connected">Connecté</string> + <string name="state_disconnected">Déconnecter</string> + <string name="state_reconnecting">Reconnexion</string> + <string name="state_exiting">Fermeture</string> + <string name="state_noprocess">Eteint</string> + <string name="state_resolve">Résolution des noms d\'hôtes</string> + <string name="state_tcp_connect">Connexion (TCP)</string> + <string name="state_auth_failed">Echec de l\'authentification</string> + <string name="state_nonetwork">En attente de réseau utilisable</string> + <string name="statusline_bytecount">↓%2$s/s %1$s - ↑%4$s/s %3$s</string> + <string name="notifcation_title_notconnect">Non connecté</string> + <string name="start_vpn_title">Connexion au VPN %s</string> + <string name="start_vpn_ticker">Connexion au VPN %s</string> + <string name="jelly_keystore_alphanumeric_bug">Certaines versions d\'Android 4.1 rencontrent des problèmes si le nom du certificat du trousseau de clé contient des caractères non alphanumériques (comme des espaces, des caractères de soulignement ou des tirets). Essayez de réimporter le certificat sans caractères spéciaux</string> + <string name="encryption_cipher">Chiffrement de cryptage</string> + <string name="packet_auth">Authentification des paquets</string> + <string name="auth_dialog_title">Méthode d\'authentification des paquets</string> + <string name="mobile_info_extended">Environnement: %1$s (%2$s) %3$s, Android API %4$d, version %5$s, %6$s</string> + <string name="built_by">compilé par %s</string> + <string name="debug_build">version de debug</string> + <string name="official_build">version officielle</string> + <string name="make_selection_inline">Copier dans le profil</string> + <string name="add">Ajouter</string> + <string name="send_config">Envoyer le fichier de config</string> + <string name="complete_dn">DN complet</string> + <string name="remotetlsnote">La configuration que vous avez importée utilise l\'option désuette tls-remote qui utilise un format de DN différent.</string> + <string name="rdn">RDN (nom commun)</string> + <string name="rdn_prefix">Préfixe RDN</string> + <string name="tls_remote_deprecated">tl-remote (OBSOLETE)</string> + <string name="help_translate">Vous pouvez aider à traduire en visitant http://crowdin.net/project/ics-openvpn/invite</string> + <string name="prompt">%1$s essais de controler %2$s</string> + <string name="remote_trust">Faire confiance à cette application.</string> + <string name="no_external_app_allowed">Aucune application n\'est autorisée à utiliser l\'API externe</string> + <string name="allowed_apps">Applications autorisées: %s</string> + <string name="clearappsdialog">Effacer la liste des appli. externes?\nListe des appli. autorisées:\n\n%s</string> + <string name="screenoff_title">Mettre la connection VPN en pause à l\'exctinction de l\'écran</string> + <string name="save_password">Enregistrer le mot de passe</string> + <string name="state_screenoff">VPN en pause - écran eteint</string> + <string name="cannotparsecert">Ne peut pas afficher les informations de certificat</string> + <string name="appbehaviour">Comportement de l\'application</string> + <string name="vpnbehaviour">Comportement du VPN</string> + <string name="allow_vpn_changes">Autoriser les modifications des profils VPN</string> +</resources> diff --git a/main/src/main/res/values-id/arrays.xml b/main/src/main/res/values-id/arrays.xml new file mode 100755 index 00000000..908d6d17 --- /dev/null +++ b/main/src/main/res/values-id/arrays.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string-array name="vpn_types"> + <item>Sertifikat</item> + <item>Berkas PKCS12</item> + <item>Sertifikat Android</item> + <item>Nama Pengguna\Sandi</item> + <item>Kunci Tetap</item> + <item>Pengguna/PW + Sertifikat</item> + <item>Pengguna/PW + PKCS12</item> + <item>Pengguna/PW + Android</item> + </string-array> + <string-array name="tls_directions_entries"> + <item>0</item> + <item>1</item> + <item>Tidak\Belum ditentukan</item> + </string-array> + <string-array name="crm_entries"> + <item>No reconnection retries</item> + <item>One reconnection retry</item> + <item>Five reconnection retries</item> + <item>Fifty reconnection retries</item> + <item>Unlimited reconnection retries</item> + </string-array> +</resources> diff --git a/main/src/main/res/values-id/strings.xml b/main/src/main/res/values-id/strings.xml new file mode 100755 index 00000000..35b82002 --- /dev/null +++ b/main/src/main/res/values-id/strings.xml @@ -0,0 +1,285 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string name="app">OpenVPN untuk Android</string> + <string name="address">Alamat Server:</string> + <string name="port">Port server:</string> + <string name="location">Lokasi</string> + <string name="cant_read_folder">Gagal membaca direktori</string> + <string name="select">Pilih</string> + <string name="cancel">Batal</string> + <string name="no_data">Tak ada data</string> + <string name="useLZO">Kompresi LZO</string> + <string name="client_no_certificate">Tanpa Sertifikat</string> + <string name="client_certificate_title">Sertifikat Klien</string> + <string name="client_key_title">Kunci Sertifikat Klien</string> + <string name="client_pkcs12_title">Berkas PKCS12</string> + <string name="ca_title">Sertifikat CA</string> + <string name="no_certificate">Anda harus memilih sertifikat</string> + <string name="copyright_guicode">Kode program dan perekam masalah tersedia di</string> + <string name="copyright_others">Aplikasi memakai komponen berikut; lihat kode program untuk lebih jelas mengenai lisensi</string> + <string name="about">Tentang…</string> + <string name="vpn_list_title">Profil</string> + <string name="vpn_type">Tipe</string> + <string name="pkcs12pwquery">Password PKCS12</string> + <string name="file_select">Pilih…</string> + <string name="file_nothing_selected">Anda harus memilih berkas (file)</string> + <string name="useTLSAuth">Pakai otentikasi TLS</string> + <string name="tls_direction">Pengarah TLS</string> + <string name="ipv6_dialog_tile">Masukkan IPv6 Address/Netmask dalam format CIDR (contoh: 2000:dd::23/64)</string> + <string name="ipv4_dialog_title">Masukkan IPv4 Address/Netmask dalam format CIDR (contoh: 1.2.3.4/24)</string> + <string name="ipv4_address">Alamat IPv4</string> + <string name="ipv6_address">Alamat IPv6</string> + <string name="custom_option_warning">Masukan seting openvpn. Gunakan dengan hati-hati. Harap dicatat, TUN yanng terkait seting OpenVPN tidak didukung oleh VPNsettings. Jika anda berpikir ada hal penting belum tersedia, hubungi pembuatnya</string> + <string name="auth_username">Nama Penguna</string> + <string name="auth_pwquery">Password</string> + <string name="static_keys_info">Untuk konfigurasi statis, kunci otentifikasi TLS akan digunakan sebagai kunci konfigurasi statis</string> + <string name="configure_the_vpn">Konfigurasi VPN</string> + <string name="menu_add_profile">Tambah Profil</string> + <string name="add_profile_name_prompt">Masukkan nama profil yang baru</string> + <string name="duplicate_profile_name">Silakan masukan UPN (Unique Profile Name)</string> + <string name="profilename">Nama profil</string> + <string name="no_keystore_cert_selected">Anda harus memilih sertifikat pengguna</string> + <string name="no_error_found">Tidak ada kesalahan</string> + <string name="config_error_found">Konfigurasi Salah</string> + <string name="ipv4_format_error">Gagal menganalisa alamat IPV4</string> + <string name="custom_route_format_error">Gagal menganalisa rute buatan</string> + <string name="pw_query_hint">(biarkan kosong untuk antrian permintaan)</string> + <string name="vpn_shortcut">Jalan Pintas OpenVPN</string> + <string name="vpn_launch_title">Hubungkan VPN</string> + <string name="shortcut_profile_notfound">Profil di shrotcut tidak ada</string> + <string name="random_host_prefix">Acak awalan Host </string> + <string name="random_host_summary">Tambah 6 karakter acak di depan nama host</string> + <string name="custom_config_title">Aktifkan pilihan buatan</string> + <string name="custom_config_summary">Tentukan seting buatan. Gunakan hati-hati</string> + <string name="route_rejected">Rute ditolak Android</string> + <string name="cancel_connection">Putus</string> + <string name="cancel_connection_long">Memutuskan sambungan VPN</string> + <string name="clear_log">Bersihkan catatan</string> + <string name="title_cancel">Batal Konfirmasi</string> + <string name="cancel_connection_query">Putuskan sambungan VPN/Batalkan usaha menyambungkan VPN?</string> + <string name="remove_vpn">Singkirkan VPN</string> + <string name="check_remote_tlscert">Memeriksa apakah server menggunakan sertifikat dengan ekstensi TLS Server (--server remote-cert-tls)</string> + <string name="check_remote_tlscert_title">Mengharapkan sertifikat server TLS</string> + <string name="remote_tlscn_check_summary">Memeriksa sertifikat Remote Server Subjek DN</string> + <string name="remote_tlscn_check_title">Cek nama sertifikat Host</string> + <string name="enter_tlscn_dialog">Tentukan nilai ynag digunakan untuk memverifikasi sertifikat remote DN (misal C=nama perusahaan, L=Kota lokasi, OU=nama departemen perusahaan, CN=openvpn.blinkt.de. Tentukan DN atau RDN yang lengkap (dalam contoh : openvpn.blinkt.de) atau sebuah awalan RDN untuk verifikasi. Saat memakai RDN awalan \"server\" cocok dengan \"server-1\" dan \"server-2\". Mengosongkan field akan membuat RDN diperiksa dengan nama host server. Lebih jelasnya lihat OpenVPN 2.3.1 manpage di bagian -verify-x509-name</string> + <string name="enter_tlscn_title">Subyek sertifikat remote</string> + <string name="tls_key_auth">Aktifkan otentifikasi kunci TLS</string> + <string name="tls_auth_file">Berkas otintikasi TLS</string> + <string name="pull_on_summary">Meminta pilihan alamat IP, rute dan waktu dari server.</string> + <string name="pull_off_summary">Tidak ada informasi diminta dari server. Seting harus ditentukan di bawah ini</string> + <string name="use_pull">Tarik pengaturan</string> + <string name="dns">DNS</string> + <string name="override_dns">Menimpa pengaturan DNS oleh Server</string> + <string name="dns_override_summary">Gunakan server DNS pribadi</string> + <string name="searchdomain">Cari domain</string> + <string name="dns1_summary">Server DNS yang akan digunakan</string> + <string name="dns_server">Server DNS</string> + <string name="secondary_dns_message">Server DNS sekunder digunakan jika Server DNS yang normal tidak dapat dicapai.</string> + <string name="backup_dns">Server DNS cadangan</string> + <string name="ignored_pushed_routes">Abaikan rute yang diberikan</string> + <string name="ignore_routes_summary">Abaikan rute yang diberikan server</string> + <string name="default_route_summary">Alihkan semua lalulintas data melalui VPN</string> + <string name="use_default_title">Gunakan rute standar</string> + <string name="custom_route_message">Masukkan rute butan sendiri. Masukkan tujuan dalam format CIDR. \"10.0.0.0/8 2002:: / 16\" akan mengarahkan jaringan 10.0.0.0/8 dan 2002:: / 16 melalui jaringan VPN</string> + <string name="custom_routes_title">Rute buatan sendiri</string> + <string name="log_verbosity_level">Tingkat rincian catatan</string> + <string name="float_summary">Ijinkan paket terotentifikasi dari semua IP</string> + <string name="float_title">Ijinkan server mengambang</string> + <string name="custom_options_title">Pilihan buatan</string> + <string name="edit_vpn">Ubah seting OpenVPN</string> + <string name="remove_vpn_query">Hapus profil \'%s\'?</string> + <string name="tun_error_helpful">Pada beberapa setelan manual gambar ICS izin pada/dev/tun mungkin salah, atau modul tun mungkin hilang sepenuhnya. Untuk gambar CM9, coba perbaiki pilihan kepemilikannya di bawah pengaturan umum</string> + <string name="tun_open_error">Gagal membuka layanan antarmuka TUN</string> + <string name="error">"Kesalahan: "</string> + <string name="clear">Bersihkan</string> + <string name="last_openvpn_tun_config">Membuka interface tun :</string> + <string name="local_ip_info">IPv4 lokal : %1$s/%2$d IPv6: %3$s MTU: %4$d</string> + <string name="dns_server_info">DNS Server: %1$s, Domain: %2$s</string> + <string name="ip_not_cidr">Memilki informasi antarmuka %1$s dan %2$s, asumsi alamat kedua adalah alamat remote. Menggunakan netmask /32 untuk IP lokal. Mode yang diberikan oleh OpenVPN adalah \"%3$s\".</string> + <string name="route_not_cidr">Tidak masuk akal membuat %1$s dan %2$s sebagai rute IP dengan netmask CIDR, Gunakan /32 sebagai netmask.</string> + <string name="route_not_netip">rute yang diperbaiki %1$s/%2$s hingga %3$s/%2$s</string> + <string name="keychain_access">Tidak dapat mengakses sertifikat Keychain Android. Dapat disebabkan karena upgrade firmware atau pengembalian backup pengaturan app. Mohon ubah VPN, dan pilih ulang sertifikat berbasis pengaturan dasar agar izin mengakses sertifikat dapat dibuat ulang.</string> + <string name="version_info">%1$s %2$s</string> + <string name="send_logfile">Kirim berkas catatan</string> + <string name="send">Kirim</string> + <string name="ics_openvpn_log_file">Berkas catatan ICS OpenVPN</string> + <string name="copied_entry">Salin catatan masuk ke clipboard</string> + <string name="tap_mode">Mode TAP</string> + <string name="faq_tap_mode">Mode TAP tidak diijinkan tanpa VPN API non admin/root. Karena itu aplikasi ini tidak dapat memberikan dukungan mode TAP</string> + <string name="tap_faq2">Lagi ? Becanda ? mode TAP benar-benar tidak didukung dan mengirim email menanyakan apakah akan ada dukungan TAP, tidak akan membantu</string> + <string name="tap_faq3">Untuk ketiga kalinya? Sebenarnya, seseorang bisa menulis emulator TAP berdasarkan tun yang akan menambahkan lapisan2 informasi pengiriman dan lapisan2 informasi penerimaan. Tapi emulator TAP ini juga harus menerapkan ARP dan mungkin klien DHCP. Saya tidak tau apakah ada yang bekerja ke arah ini. Hubungi saya jika Anda ingin memulai menulis kode2 emulator TAP ini.</string> + <string name="faq">FAQ</string> + <string name="copying_log_entries">Menyalin catatan</string> + <string name="faq_copying">Untuk menyalin satu catatan masuk, Tekan dan tahan di catatan masuk. Untuk meyanlin\mengirim seluruh catatan, gunakan opsi Kirim Log. Gunakan tombol perangkat keras jika tidak terlihat di GUI.</string> + <string name="faq_shortcut">Jalan pintas memulai</string> + <string name="faq_howto_shortcut">Anda dapat menempatkan jalan pintas untuk memulai OpenVPN pada desktop Anda. Tergantung pada program homescreen Anda, Anda harus menambahkan jalan pintas atau widget.</string> + <string name="no_vpn_support_image">Gambar Anda tidak mendukung VPNService API, maaf:(</string> + <string name="encryption">Enkripsi</string> + <string name="cipher_dialog_title">Masukkan metode enkripsi</string> + <string name="chipher_dialog_message">Masukkan sandi enkripsi algoritma yang digunakan oleh OpenVPN. Biarkan kosong untuk menggunakan sandi default.</string> + <string name="auth_dialog_message">Masukkan digest otentikasi yang digunakan OpenVPN. Biarkan kosong untuk menggunakan standar digest.</string> + <string name="settings_auth">Otentikasi/Enkripsi</string> + <string name="file_explorer_tab">Penjelajah berkas</string> + <string name="inline_file_tab">Inline File</string> + <string name="error_importing_file">Gagal mengambil berkas</string> + <string name="import_error_message">Tidak dapat mengambil berkas dari filesystem</string> + <string name="inline_file_data">[[Inline file data]]</string> + <string name="opentun_no_ipaddr">TUN tidak dapat dibuka tanpa informasi IP</string> + <string name="menu_import">Ambil profil dari berkas ovpn</string> + <string name="menu_import_short">Ambil</string> + <string name="import_content_resolve_error">Tidak dapat membaca profil yang akan diambil</string> + <string name="error_reading_config_file">Kesalahan membaca berkas konfigurasi</string> + <string name="add_profile">Tambah Profil</string> + <string name="import_could_not_open">Tidak dapat menemukan berkas %1$s yang disebut dalam berkas konfigurasi</string> + <string name="importing_config">Mengambil berkas konfigurasi dari sumber %1$s</string> + <string name="import_warning_custom_options">Konfigurasi Anda memiliki beberapa pilihan konfigurasi yang tidak dipetakan ke konfigurasi UI. Pilihan ini ditambahkan sebagai opsi konfigurasi kustom. Konfigurasi kustom ditampilkan di bawah ini:</string> + <string name="import_done">Berkas konfigurasi selesai dibaca</string> + <string name="nobind_summary">Jangan kaitkan ke alamat dan port lokal</string> + <string name="no_bind">Tidak ada ikatan lokal</string> + <string name="import_configuration_file">Ambil berkas konfigurasi</string> + <string name="faq_security_title">Pertimbangan Keamanan</string> + <string name="faq_security">"Karena OpenVPN adalah sensitif pada isu keamanan, beberapa catatan tentang keamanan dianggap perlu. Semua data pada sdcard pada dasarnya tidak aman. Setiap app dapat membaca (misalnya program ini tidak perlu hak khusus untuk membaca sd-card). Data dari aplikasi ini hanya dapat dibaca oleh aplikasi itu sendiri. Dengan menggunakan opsi impor untuk cacert/cert/kunci dalam file dialog data yang disimpan dalam profil VPN. Profil VPN hanya dapat diakses oleh aplikasi ini. (Jangan lupa untuk menghapus salinan pada sd-card setelah itu). Bahkan meskipun dapat diakses hanya dengan aplikasi ini data masih tidak terenkripsi. Dengan melakukan rooting atau eksploitasi lainnya maka memungkinkan mengambil data. Sandi-sandi (passwords) juga tersimpan dalam teks biasa. Berkas pkcs12 sangat dianjurkan Anda mengimpornya ke android keystore."</string> + <string name="import_vpn">Impor</string> + <string name="broken_image_cert_title">Kesalahan menampilkan sertifikat</string> + <string name="broken_image_cert">Mendapat pesan kesalahan saat berusaha menampilkan layar pemilihan sertifikat Android 4.0+. Ini seharusnya tidak terjadi karena ini fitur standar Android 4.0 +. Mungkin ROM Android anda yang mengurus penyimpanan sertifikat rusak</string> + <string name="ipv4">IPv4</string> + <string name="ipv6">IPv6</string> + <string name="speed_waiting">Menunggu pesan status…</string> + <string name="converted_profile">Profil yang diambil</string> + <string name="converted_profile_i">profil yang diambil %d</string> + <string name="broken_images">Gambar rusak</string> + <string name="broken_images_faq">Image HTC yang resmi diketahui memiliki masalah routing yang ganjilyang menyebabkan trafik data tidak melalui tunnel (Lihat di <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=18\">Issue 18</a> di bagian bug tracker.))</p><p> Image SONY resmi yang lama dari Xperia Arc S and Xperia Ray telah dilaporkan tidak memiliki VPNService dalam Imagenya. (Lihat juga <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=29\">Issue 29</a> di bagian bug tracker.))</p><p>Pada image yang dibuat non resmi, modul TUN mungkin tak ada atau hak /dev/tun mungkin salah. Beberapa image CM9 memerlukan pilihan \"Fix ownership\" di bagian \"Device specific hacks\" diaktfikan. .</p><p> Lebih penting lagi, jika device anda memiliki image android yang lengkap, laporkan pada vendor anda. Semakin banyak laporan masuk, semakin tinggi kemungkinan vendor melakukan perbaikan.</p></string> + <string name="pkcs12_file_encryption_key">Berkas kunci enkripsi PKCS12</string> + <string name="private_key_password">Sandi kunci pribadi</string> + <string name="password">Sandi</string> + <string name="file_icon">ikon berkas</string> + <string name="tls_authentication">Otentikasi TLS</string> + <string name="generated_config">Konfigurasi Dibuat</string> + <string name="generalsettings">Pengaturan</string> + <string name="owner_fix_summary">Mencoba menetapkan pemilik /dev/tun ke sistem. Beberapa gambar CM9 memerlukan ini untuk membuat API VPNService bekerja. Memerlukan akses Root.</string> + <string name="owner_fix">Perbaiki kepemilikan /dev/tun</string> + <string name="generated_config_summary">Tunjukkan berkas konfigurasi OpenVPN yang dibuat</string> + <string name="edit_profile_title">Mengubah \"%s\"</string> + <string name="building_configration">Membuat konfigurasi…</string> + <string name="netchange_summary">Menyalakan pilihan ini akan memaksa menyambung kembali jika keadaan jaringan berubah (misalnya WiFi dari mobile)</string> + <string name="netchange">Koneksi ulang saat ganti jaringan</string> + <string name="netstatus">Status jaringan: %s</string> + <string name="extracahint">Sertifikat CA biasanya kembali dari Android Keystore. Tentukan sertifikat terpisah jika Anda mendapatkan kesalahan verifikasi sertifikat.</string> + <string name="select_file">Pilih</string> + <string name="keychain_nocacert">Tidak ada sertifikat CA yang didapat saat membaca dari Android Keystore. Otentifikasi mungkin gagal</string> + <string name="show_log_summary">Tampilkan jendela catatan saat terkoneksi. Jendela catatan juga dapat diakses melalui status notifikasi</string> + <string name="show_log_window">Tampilkan jendela catatan</string> + <string name="mobile_info">Berjalan di %1$s (%2$s) %3$s, Android API %4$d</string> + <string name="error_rsa_sign">Kesalahan masuk dengan kunci Android keystore %1$s: %2$s</string> + <string name="faq_system_dialogs">Peringatan sambungan VPN yang memberitahukan Anda bahwa aplikasi ini dapat mencegat semua lalu lintas dikeluarkan oleh sistem untuk mencegah penyalahgunaan dari sambungan VPNService API.\nPemberitahuan sambungan VPN (simbol kunci) juga dikeluarkan oleh sistem Android untuk memberitahu VPN yang sedang berlangsung. Pada beberapa gambar pemberitahuan ini memainkan suara. \nAndroid memperkenalkan sistem dialog ini untuk keselamatan Anda sendiri dan memastikan bahwa mereka tidak membuat masalah. (Pada beberapa gambar sayangnya ini termasuk peringatan suara)</string> + <string name="faq_system_dialogs_title">Peringatan sambungan dan pemberitahuan melalui suara</string> + <string name="translationby">Terjemah Bahasa Indonesia oleh Dayro</string> + <string name="ipdns">IP dan DNS</string> + <string name="basic">Dasar</string> + <string name="routing">Rute</string> + <string name="obscure">Mengaburkan pengaturan OpenVPN. Biasanya tidak diperlukan.</string> + <string name="advanced">Lanjutan</string> + <string name="export_config_title">Konfigurasi ICS Openvpn</string> + <string name="warn_no_dns">Tidak DNS server yang digunakan. Name Resolution mungkin akan gagal bekerja. Pertimbangkan pengaturan server DNS. Harap dicatat Android akan terus memakai pengaturan proxy untuk koneksi mobile/wifi saat tidak ada server DNS diatur.</string> + <string name="dns_add_error">Tak bisa menambahkan Server DNS \"%1$s\", ditolak oleh sistem: %2$s</string> + <string name="faq_howto"><p> Ambil konfigurasi yang dapat berjalan (diuji pada komputer Anda atau download dari penyedia/organisasi) </p> <p> Satu file(berkas) saja tanpa tambahan berkas pem/pks12. Anda dapat kirim imel berkas dan membuka lampirannya. Jika Anda memiliki beberapa berkas, salin ke sd-card </p> <p> klik pada lampiran imel atau gunakan ikon folder dalam daftar vpn untuk mengimpor berkas konfigurasi </p> <p> jika ada berkas yang kurang, salin file hilang ke sd-card. </p> <p> klik pada simbol Simpan untuk menambahkan VPN yang diimpor ke daftar VPN </p> <p > Connect VPN dengan mengklik nama VPN </p> <p> jika ada kesalahan atau peringatan di catatan, coba pahami peringatannya dan coba untuk memperbaikinya </p> </string> + <string name="faq_howto_title">Mulai Cepat</string> + <string name="setting_loadtun_summary">Coba pakai tun.ko kernel sebelum mencoba koneksi. Membutuhkan perangkat yang sudah diroot. Google: android superuser</string> + <string name="setting_loadtun">Pakai modul TUN</string> + <string name="importpkcs12fromconfig">Ambil PKCS12 dari konfigurasi ke Android Keystore</string> + <string name="getproxy_error">Gagal mendapatkan pengaturan proxy: %s</string> + <string name="using_proxy">Menggunakan proxy %1$s %2$d</string> + <string name="use_system_proxy">Gunakan sistem proxy</string> + <string name="use_system_proxy_summary">Gunakan konfigurasi lebih luas untuk menyambung system melalui proxy HTTP/HTTPS</string> + <string name="donatewithpaypal">Anda dapat melakukan donasi <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;cmd=_s-xclick\">dengan PayPal</a> </string> + <string name="onbootrestartsummary">OpenVPN akan menyambung kembali VPN jika VPN aktif pada saat sistem reboot/shutdown. Silakan baca FAQ tentang peringatan sambungan sebelum menggunakan pilihan ini.</string> + <string name="onbootrestart">Koneksi ulang saat perangkat dihidupkan kembali</string> + <string name="ignore">Abaikan</string> + <string name="restart">Restart</string> + <string name="restart_vpn_after_change">Perubahan konfigurasi baru diterapkan setelah restart VPN. Restart VPN sekarang?</string> + <string name="configuration_changed">Konfigurasi berubah</string> + <string name="log_no_last_vpn">Tak bisa menentukan profil terhubung terakhir untuk diubah</string> + <string name="faq_duplicate_notification_title">Pemberitahuan berganda</string> + <string name="faq_duplicate_notification">Jika Android kekurangan sistem memori (RAM), aplikasi dan layanan yang tidak diperlukan pada saat itu akan dihapus dari memori aktif. Sambungan VPN yang sedang aktif juga ditutup. Untuk memastikan bahwa sambungan/OpenVPN tetap berjalan, OpenVPN diberikan prioritas yang lebih tinggi. Untuk menjalankan dengan prioritas lebih tinggi, aplikasi harus menampilkan pemberitahuan. Ikon pemberitahuan dijalankan oleh sistem seperti dijelaskan dalam FAQ entri sebelumnya. Ini tidak dihitung sebagai pemberitahuan app yang berjalan dengan prioritas lebih tinggi.</string> + <string name="no_vpn_profiles_defined">Tak ada profil VPN yang didefinisikan.</string> + <string name="add_new_vpn_hint">Gunakan ikon < img src = \"ic_menu_add\" / > untuk menambah VPN baru</string> + <string name="vpn_import_hint">Gunakan ikon < img src = \"ic_menu_archive\" / > untuk mengimpor profil (.ovpn atau .conf) yang ada dari sdcard Anda.</string> + <string name="faq_hint">Pastikan untuk juga memeriksa FAQ. Ada petunjuk untuk memudahkan anda.</string> + <string name="faq_routing_title">Konfigurasi rute\antarmuka</string> + <string name="faq_routing">Konfigurasi routing dan antar muka tidak dibuat memakai ifconfig/route tradisional tapi memaka API VPNservice. Menyebabkan konfigurasi routing yang berbeda di OS berbeda. Konfigurasi hanya terdiri dari IP milik tunnel antarmuka dan jaringan yang seharusnya dirutekan melalui antarmuka ini. Terlebih tidak ada alamat gateway atau peer rekanan yang dibutuhkan. Rute khusus untuk menjangkau server VPN (untu contoh tambahkan saat memakai redirect-gateway) juga tak diperlukan. Aplikasi akan mengabaikan seting ini saat mengimpor sebuah konfigurasi. Aplikasi memastikan dengan API VPNService bahwa koneksi menuju server tidak dirutekan melalui tunnel VPN. Dengan hanya menentukan jaringan dirutekan melalu tunnel, rute lainnya yang tidak ditentukan melalui tunnel juga tak dapat didukung. (e.g. route x.x.x.x y.y.y.y net_gateway). Jendela catatan menunjukkan konfigurasi terkini VPNService sejak menyediakan layanan koneksi.</string> + <string name="persisttun_summary">Jangan kembali ke status tidak ada koneksi VPN ketika OpenVPN mencoba terhubung kembali.</string> + <string name="persistent_tun_title">Paksa mode TUN</string> + <string name="openvpn_log">Catatan OpenVPN</string> + <string name="import_config">Ambil konfigurasi VPN</string> + <string name="battery_consumption_title">Konsumsi baterai</string> + <string name="baterry_consumption">Berdasarkan tes pribadi, alasan utama tingginya konsumsi baterai oleh OpenVPN adalah paket keepalive. Sebagian besar server OpenVPN memiliki parameter konfigurasi seperti \'keepalive 10 60\' yang membuat klien dan server bertukar paket keepalive setiap 10 detik. <p> Dengan kecilnya paket ini dan tidak memakai trafik terlalu banyak, mereka menjaga jaringan radio mobile tetap sibuk dan meningkatkan konsumsi energi. (See also <a href=\"http://developer.android.com/training/efficient-downloads/efficient-network-access.html#RadioStateMachine\">The Radio State Machine | Android Developers</a>) <p> Seting keepalive ini tidak bisa dirubah di klien. Hanya Admin sistem OpenVPN yang dapat merubah seting ini. <p> Sayangnya membuat keepalive lebih besar dari 60 detik tanpa UDP dapat membuat beberapa gateway NAT memutus koneksi karena anggapan tidak ada aktifitas pada periode tertentu (timeout). Memakai TCP dengan waktu timeout lebih lama dapat bekerja, tapi membuat tunnel TCP di jalur TCP menyebabkan koneksi yang buruk dan tingginya angka kehilangan paket data ((See <a href=\"http://sites.inka.de/bigred/devel/tcp-tcp.html\">Why TCP Over TCP Is A Bad Idea</a>)</string> + <string name="faq_tethering">Fitur penggandengan Android (melalui WiFi, USB atau Bluetooth) dan API VPNService (digunakan oleh program ini) tidak bekerja bersama-sama. Untuk keterangan lanjut lihat < href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=34\" > mengeluarkan #34 </a></string> + <string name="vpn_tethering_title">VPN dan penarikan</string> + <string name="connection_retries">Mengulang koneksi</string> + <string name="reconnection_settings">Pengaturan rekoneksi</string> + <string name="connectretrymessage">Jumlah detik untuk menunggu antar usaha koneksi</string> + <string name="connectretrywait">Detik antar koneksi</string> + <string name="minidump_generated">OpenVPN crash tak terduga. Silakan mempertimbangkan mengirim menggunakan pilihan Minidump di Menu Utama</string> + <string name="send_minidump">Mengirim MiniDump untuk pengembang</string> + <string name="send_minidump_summary">Mengirim informasi debug tentang kegagalan aplikasi yang terakhir ke pengembang</string> + <string name="notifcation_title">OpenVPN - %s</string> + <string name="session_ipv4string">%1$s - %2$s</string> + <string name="session_ipv6string">%1$s - %3$s, %2$s</string> + <string name="state_connecting">Menghubungkan</string> + <string name="state_wait">Menunggu jawaban server</string> + <string name="state_auth">Melakukan otentifikasi</string> + <string name="state_get_config">Mengambil konfigurasi klien</string> + <string name="state_assign_ip">Menetapkan alamat IP</string> + <string name="state_add_routes">Menambahkan rute</string> + <string name="state_connected">Terhubung</string> + <string name="state_disconnected">Putus</string> + <string name="state_reconnecting">Menghubungkan kembali</string> + <string name="state_exiting">Keluar</string> + <string name="state_noprocess">Tidak berjalan</string> + <string name="state_resolve">Mengenali nama host</string> + <string name="state_tcp_connect">Menghubungkan (TCP)</string> + <string name="state_auth_failed">Otentifikasi gagal</string> + <string name="state_nonetwork">Menunggu jaringan yang dapat dipakai</string> + <string name="statusline_bytecount">↓%2$s/s %1$s - ↑%4$s/s %3$s</string> + <string name="notifcation_title_notconnect">Tidak terhubung</string> + <string name="start_vpn_title">Menghubungkan ke VPN %s</string> + <string name="start_vpn_ticker">Menghubungkan ke VPN %s</string> + <string name="jelly_keystore_alphanumeric_bug">Beberapa versi Android 4.1 memiliki masalah jika nama sertifikat keystore berisi karakter non alfanumerik (seperti spasi, garis bawah atau tanda hubung). Cobalah import ulang sertifikat tanpa karakter khusus</string> + <string name="encryption_cipher">Enkripsi sandi</string> + <string name="packet_auth">Otentikasi paket</string> + <string name="auth_dialog_title">Masukkan metode otentikasi paket</string> + <string name="mobile_info_extended">Berjalan pada Android API %4$d, versi %5$s %1$s (%2$s) %3$s, %6$s</string> + <string name="built_by">dibangun oleh %s</string> + <string name="debug_build">Pengembangan debug</string> + <string name="official_build">Build Resmi</string> + <string name="make_selection_inline">Salin ke profil</string> + <string name="crashdump">Data saat terjadi crash</string> + <string name="add">Tambahkan</string> + <string name="send_config">Mengirim config file</string> + <string name="complete_dn">DN lengkap</string> + <string name="remotetlsnote">Konfigurasi yang diimpor menggunakan opsi tls-remote DEPRECATED tua dengan menggunakan format DN yang berbeda.</string> + <string name="rdn">RDN (nama umum)</string> + <string name="rdn_prefix">RDN awalan</string> + <string name="tls_remote_deprecated">TLS-remote (DEPRECATED)</string> + <string name="help_translate">Anda dapat membantu menerjemahkan dengan mengunjungi http://crowdin.net/project/ics-openvpn/invite</string> + <string name="prompt">%1$s berusaha mengendalikan %2$s</string> + <string name="remote_trust">Saya percaya aplikasi ini.</string> + <string name="no_external_app_allowed">App tidak diizinkan untuk menggunakan API eksternal</string> + <string name="allowed_apps">apps yang diijinkan : %s</string> + <string name="clearappsdialog">Hapus daftar aplikasi eksternal yang dibolehkan? \nDaftar apps yang dibolehkan terkini:\n\n%s </string> + <string name="screenoff_summary">\"Pause VPN ketika layar off dan data yang ditransfer dalam 60 detik kurang dari 64kB. Ketika opsi \"Persistent Tun\" diaktifkan, memberhentikan VPN akan membuat perangkat Anda tidak memiliki koneksi jaringan. Jika tidak memakai \"Persistent Tun\" maka perangkat akan menampilkan Tidak ada koneksi VPN.</string> + <string name="screenoff_title">Sambungan VPN jeda setelah layar mati</string> + <string name="screenoff_pause">Hentikan sambungan dalam kondisi layar mati: kurang dari %1$s dalam %2$ss</string> + <string name="screen_nopersistenttun">Peringatan: Pemaksaan tun tidak diaktifkan untuk VPN ini. Lalu lintas akan menggunakan koneksi Internet normal ketika layar dimatikan.</string> + <string name="save_password">Menyimpan sandi</string> + <string name="pauseVPN">Jeda VPN</string> + <string name="resumevpn">Lanjutkan VPN</string> + <string name="state_userpause">Pause VPN diminta oleh pengguna</string> + <string name="state_screenoff">VPN dijeda - layar off</string> + <string name="device_specific">Perangkat dengan spesifikasi Hacks</string> + <string name="cannotparsecert">Tidak dapat menampilkan informasi sertifikat</string> + <string name="appbehaviour">Prilaku Aplikasi</string> + <string name="vpnbehaviour">Prilaku VPN</string> +</resources> diff --git a/main/src/main/res/values-it/arrays.xml b/main/src/main/res/values-it/arrays.xml new file mode 100755 index 00000000..daa3bef3 --- /dev/null +++ b/main/src/main/res/values-it/arrays.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string-array name="vpn_types"> + <item>Certificati</item> + <item>File PKCS12</item> + <item>Certificato Android</item> + <item>Utente/Password</item> + <item>Chiavi statiche</item> + <item>Utente/password + Certificati</item> + <item>Utente/Passowrd + PKCS12 </item> + <item>Utente/Passsword + Android</item> + </string-array> + <string-array name="tls_directions_entries"> + <item>0</item> + <item>1</item> + <item>Non specificato</item> + </string-array> + <string-array name="crm_entries"> + <item>No reconnection retries</item> + <item>One reconnection retry</item> + <item>Five reconnection retries</item> + <item>Fifty reconnection retries</item> + <item>Unlimited reconnection retries</item> + </string-array> +</resources> diff --git a/main/src/main/res/values-it/strings.xml b/main/src/main/res/values-it/strings.xml new file mode 100755 index 00000000..392f5b48 --- /dev/null +++ b/main/src/main/res/values-it/strings.xml @@ -0,0 +1,310 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string name="app">OpenVPN per Android</string> + <string name="address">Indirizzo server:</string> + <string name="port">Porta del server:</string> + <string name="location">Posizione</string> + <string name="cant_read_folder">Impossibile leggere la directory</string> + <string name="select">Seleziona</string> + <string name="cancel">Annulla</string> + <string name="no_data">Nessun dato</string> + <string name="useLZO">Compressione LZO</string> + <string name="client_no_certificate">Nessun certificato</string> + <string name="client_certificate_title">Certificato client</string> + <string name="client_key_title">Chiave del certificato client</string> + <string name="client_pkcs12_title">File PKCS12</string> + <string name="ca_title">Certificato CA</string> + <string name="no_certificate">Devi selezionare un certificato</string> + <string name="copyright_guicode">Il codice sorgente e il bug tracker sono disponibili all\'indirizzo http://code.google.com/p/ics-openvpn/</string> + <string name="copyright_others">Questo programma usa i seguenti componenti; guarda il codice sorgente per i dettagli completi sulle licenze</string> + <string name="about">Informazioni</string> + <string name="vpn_list_title">Profili</string> + <string name="vpn_type">Tipo</string> + <string name="pkcs12pwquery">Password PKCS12</string> + <string name="file_select">Seleziona…</string> + <string name="file_nothing_selected">Devi selezionare un file</string> + <string name="useTLSAuth">Usa autenticazione TLS</string> + <string name="tls_direction">Direzione TLS</string> + <string name="ipv6_dialog_tile">Inserire l\'indirizzo IPv6 e la maschera di rete in formato CIDR (ad esempio 2000:dd::23/64)</string> + <string name="ipv4_dialog_title">Inserire l\'indirizzo IPv4 e la maschera di rete in formato CIDR (ad esempio 1.2.3.4/24)</string> + <string name="ipv4_address">Indirizzo IPv4</string> + <string name="ipv6_address">Indirizzo IPv6</string> + <string name="custom_option_warning">Inserire le opzioni personalizzate di OpenVPN. Usare con cautela. Si ricorda che molte delle impostazioni relative a OpenVPN non sono attualmente supportate da questo progetto. Se ritiene che manchi un\'opzione indispensabile, contatta l\'autore</string> + <string name="auth_username">Utente</string> + <string name="auth_pwquery">Password</string> + <string name="static_keys_info">Per la configurazione statica le chiavi di autorizzazione TLS saranno usate come chiavi statiche</string> + <string name="configure_the_vpn">Configura la VPN</string> + <string name="menu_add_profile">Aggiungi profilo</string> + <string name="add_profile_name_prompt">Immettere un nome per identificare il nuovo profilo</string> + <string name="duplicate_profile_name">Si prega di inserire un nome univoco del profilo</string> + <string name="profilename">Nome del profilo</string> + <string name="no_keystore_cert_selected">Devi selezionare un certificato utente</string> + <string name="no_error_found">Nessun errore trovato</string> + <string name="config_error_found">Errore nella configurazione</string> + <string name="ipv4_format_error">Impossibile analizzare l\'indirizzo IPv4</string> + <string name="custom_route_format_error">Errore durante la lettura delle regole di reindirizzamento (routing)</string> + <string name="pw_query_hint">(non compilare perché venga sempre richiesto)</string> + <string name="vpn_shortcut">Collegamento a OpenVPN</string> + <string name="vpn_launch_title">Connetti alla VPN</string> + <string name="shortcut_profile_notfound">Profilo indicato nel collegamento non trovato</string> + <string name="random_host_prefix">Prefisso Host casuale</string> + <string name="random_host_summary">Aggiunge 6 caratteri casuali prima dell\'hostname</string> + <string name="custom_config_title">Abilita opzioni personalizzate</string> + <string name="custom_config_summary">Specifica opzioni personalizzate. Utilizzare con cautela!</string> + <string name="route_rejected">Reindirizzamento (route) rifiutato da Android</string> + <string name="cancel_connection">Scollega</string> + <string name="cancel_connection_long">Disconnettere VPN</string> + <string name="clear_log">Cancella registro</string> + <string name="title_cancel">Conferma l\'annullamento</string> + <string name="cancel_connection_query">Disconnetti la VPN in uso/annulli il tentativo di connessione?</string> + <string name="remove_vpn">Rimuovi VPN</string> + <string name="check_remote_tlscert">Controlla se il server utilizza un certificato con estensioni TLS (--remote-cert-tls server)</string> + <string name="check_remote_tlscert_title">Attesa di un certificato server TLS</string> + <string name="remote_tlscn_check_summary">Controlla il soggetto DN del certificato del server remoto</string> + <string name="remote_tlscn_check_title">Verifica il certificato dell\'Host</string> + <string name="enter_tlscn_dialog">Specifica il controllo da effettuare per verificare il certificato DN remoto (e.g. C=DE, L=Paderborn, OU=Avian IP Carriers, CN=openvpn.blinkt.de)\n\nPer verifica specifica il DN o RDN completo (nell\'esempio openvpn.blinkt.de) oppure un prefisso RDN.\n\nQuando usi un prefisso RDN \"Server\" è valido per \"Server-1\" e \"Server-2\"\n\nLasciando la casella vuota verrà controllato l\'RDN con l\'hostname del server.\n\nPer maggiori informazioni consulta la manpage di OpenVPN 2.3.1+ sotto la voce —verify-x509-name</string> + <string name="enter_tlscn_title">Soggetto del certificato remoto</string> + <string name="tls_key_auth">Abilita l\'autenticazione tramite TLS</string> + <string name="tls_auth_file">File di autenticazione TLS</string> + <string name="pull_on_summary">Richiede indirizzi IP, instradamenti ed opzioni di sincronizzazione al server.</string> + <string name="pull_off_summary">Nessuna informazione è richiesta al server. Le impostazioni devono essere specificate qui di seguito.</string> + <string name="use_pull">Richiedi impostazioni</string> + <string name="dns">DNS</string> + <string name="override_dns">Modifica DNS</string> + <string name="dns_override_summary">Utilizza i propri server DNS</string> + <string name="searchdomain">Dominio di ricerca</string> + <string name="dns1_summary">Server DNS da utilizzare.</string> + <string name="dns_server">Server DNS</string> + <string name="secondary_dns_message">Server DNS secondario utilizzato se il Server DNS primario non può essere raggiunto.</string> + <string name="backup_dns">Server DNS secondario</string> + <string name="ignored_pushed_routes">Ignora gli instradamenti</string> + <string name="ignore_routes_summary">Ignora impostazioni di routing comunicate dal server.</string> + <string name="default_route_summary">Reindirizza tutto il traffico sulla VPN</string> + <string name="use_default_title">Utilizza il Routing di default</string> + <string name="custom_route_message">Inserisci instradamenti personalizzati. Usare il formato CIDR. \"10.0.0.0/8 2002::/16\" reindirizza le reti 10.0.0.0/8 e 2002::/16 sulla VPN.</string> + <string name="custom_routes_title">Routing personalizzati</string> + <string name="log_verbosity_level">Livello di dettaglio del registro</string> + <string name="float_summary">Permette pacchetti autenticati da qualsiasi IP (consente che l\'IP del server possa cambiare)</string> + <string name="float_title">Modalità float</string> + <string name="custom_options_title">Opzioni personalizzate</string> + <string name="edit_vpn">Modifica impostazioni VPN</string> + <string name="remove_vpn_query">Rimuovere il profilo VPN \'%s\'?</string> + <string name="tun_error_helpful">In alcune immagini ICS personalizzate i permessi su /dev/tun potrebbero essere errati, oppure il modulo TUN completamente assente. Per le immagini CM9 provare a correggere le opzioni Proprietà nella sezione impostazioni generali</string> + <string name="tun_open_error">Impossibile accedere all\'interfaccia tun</string> + <string name="error">"Errore:"</string> + <string name="clear">Azzera</string> + <string name="last_openvpn_tun_config">Apertura interfaccia tun in corso:</string> + <string name="local_ip_info">Indirizzi locali - IPv4: %1$s/%2$d IPv6: %3$s MTU: %4$d</string> + <string name="dns_server_info">DNS Server: %1$s, Dominio: %2$s</string> + <string name="ip_not_cidr">Ottenute le informazioni sulle interfacce %1$s e %2$s, assumendo che il secondo indirizzo sia il peer remoto. Utilizzata la maschera /32 per l\'IP locale. La modalità impostata da OpenVPN è \"%3$s\".</string> + <string name="route_not_cidr">Impossibile utilizzare %1$s e %2$s come reindirizzamenti IP con la maschera CIDR, è stata quindi usata la maschera /32.</string> + <string name="route_not_netip">Instradamento %1$s/%2$s corretto con %3$s/%2$s</string> + <string name="keychain_access">Impossibile accedere ai certificati della Keychain di Android (può essere causato da un aggiornamento del firmware o dal ripristino di un backup dell\'applicazione o delle sue impostazioni). E\' necessario modificare le impostazioni della VPN e riselezionare il certificato nelle impostazioni principali per ricreare i permessi di accesso al certificato.</string> + <string name="version_info">%1$s %2$s</string> + <string name="send_logfile">Invia il file di log</string> + <string name="send">Invia</string> + <string name="ics_openvpn_log_file">File log di OpenVPN ICS</string> + <string name="copied_entry">Voce di registro copiata negli appunti</string> + <string name="tap_mode">Modalità TAP</string> + <string name="faq_tap_mode">La modalità TAP non è disponibile con le VPN API non root</string> + <string name="tap_faq2">Ancora? Stai scherzando? No, la modalità tap non è supportata e mandare nuove email chiedendo se sarà supportata non aiuterà.</string> + <string name="tap_faq3">Per la terza volta? In realtà si potrebbe scrivere un emulatore TAP basato su TUN che aggiunge le informazioni di Layer 2 in uscita e le elimina in ingresso. Ma questo emulatore TAP dovrebbe anche implementare ARP e un client DHCP. Non sono a conoscenza di nessuno che stia realizzando qualcosa del genere. Contattami se vuoi iniziare a scrivere del codice a riguardo.</string> + <string name="faq">Domande frequenti (FAQ)</string> + <string name="copying_log_entries">Sto copiando le voci di log</string> + <string name="faq_copying">Per copiare una singola voce del log, premi e mantieni sulla voce del log. Per copiare/inviare l\'intero log usa l\'opzione \"Manda log\". +Usa il tasto hardware Menù se non è visibile nella GUI.</string> + <string name="faq_shortcut">Scorciatoia per l\'avvio</string> + <string name="faq_howto_shortcut">È possibile inserire un collegamento per avviare OpenVPN dal desktop. A seconda del vostro launcher dovrete aggiungere un collegamento o un widget.</string> + <string name="no_vpn_support_image">La tua immagine non è supportata dal VPNService API, mi dispiace :(</string> + <string name="encryption">Crittografia</string> + <string name="cipher_dialog_title">Inserire il metodo di crittografia</string> + <string name="chipher_dialog_message">Inserisci l\'algoritmo di cifratura cipher usato da OpenVPN. Lasciare vuoto per usare quello di default.</string> + <string name="auth_dialog_message">Inserisci l\'algoritmo di cifratura digest usato da OpenVPN. Lascia bianco per usare quello di default.</string> + <string name="settings_auth">Autenticazione/crittografia</string> + <string name="file_explorer_tab">Esplora risorse</string> + <string name="inline_file_tab">Blocco note</string> + <string name="error_importing_file">Errore durante l\'importazione del file</string> + <string name="import_error_message">Impossibile importare il file dal filesystem</string> + <string name="inline_file_data">[[dati del blocco note]]</string> + <string name="opentun_no_ipaddr">Rifiuto di attivare il dispositivo tun senza informazioni sull\'IP</string> + <string name="menu_import">Importa il profilo dal file .ovpn</string> + <string name="menu_import_short">Importa</string> + <string name="import_content_resolve_error">Impossibile leggere il profilo da importare</string> + <string name="error_reading_config_file">Errore di lettura del file di configurazione</string> + <string name="add_profile">Aggiungi profilo</string> + <string name="import_could_not_open">Impossibile trovare il file %1$s menzionato nel file di configurazione importato</string> + <string name="importing_config">Importa il file di configurazione dalla sorgente %1$s</string> + <string name="import_warning_custom_options">La tua configurazione usava qualche opzione non mappata sull\'Interfaccia Utente. Queste opzioni sono state quindi aggiunte come personalizzate. La configurazione personalizzata è visualizzata qui sotto:</string> + <string name="import_done"> +Effettuata la lettura del file di configurazione</string> + <string name="nobind_summary">Non si vincola all\'indirizzo e alla porta locali (bind)</string> + <string name="no_bind">Niente local binding</string> + <string name="import_configuration_file">Importa file di configurazione</string> + <string name="faq_security_title">Considerazioni sulla sicurezza</string> + <string name="faq_security">"Dato che si usa OpenVPN per motivi di sicurezza, si riportano alcune note su quanto la sicurezza sia sensibile. Tutti i dati memorizzati sulla scheda SD sono intrinsecamente insicuri. Qualunque programma può leggerli (ad esempio a questo programma non sono richiesti speciali diritti per accedere alla scheda SD). I dati di questo programma invece possono essere letti solo dal programma stesso. Utilizzando l\'opzione di importazione di cacert/cert/key nelle impostazioni, i dati vengono memorizzati nel profilo della VPN. I profili delle VPN sono accessibili solo da questo programma (non bisogna però dimenticarsi di eliminare le copie dei certificati sulla scheda SD dopo questa operazione). Tuttavia anche se accessibili solamente da questo programma, i dati vengono memorizzati senza alcuna crittografia. E\' possibile pertanto mediante rooting o altre procedure recuperare tali dati. Anche le password salvate vengono memorizzate in chiaro. Si raccomanda caldamente di importare i file pkcs12 nel keystore di Android."</string> + <string name="import_vpn">Importa</string> + <string name="broken_image_cert_title">Errore nel mostrare il certificato selezionato</string> + <string name="broken_image_cert">Si è incappati in una eccezione tentando di visualizzare la finestra di selezione dei certificati di Android 4.0+. Questo non dovrebbe mai accadere dato che questa è una caratteristica standard di Android 4.0+. Forse il supporto al salvataggio dei certificati del tuo firmware di Android è corrotto.</string> + <string name="ipv4">IPv4</string> + <string name="ipv6">IPv6</string> + <string name="speed_waiting">In attesa del messaggio di stato…</string> + <string name="converted_profile">profilo importato</string> + <string name="converted_profile_i">profilo importato %d</string> + <string name="broken_images">Firmware bacati</string> + <string name="broken_images_faq"><p>E\' noto che le immagini ufficiali di HTC presentano uno strano problema di routing causando per cui il traffico non fluisce nel tunnel (Vedere <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=18\">Issue 18</a> nella gestione dei bug.)</p><p>Le immagini SONY più vecchie per Xperia Arc S e Xperia Ray sono segnalate come completamente mancanti di VPNService. (Vedere anche <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=29\"> Problema 29</a> nella gestione bug.)</p><p> Su immagini personalizzate il modulo tun potrebbe essere mancante oppure i diritti di accesso a /dev/tun potrebbero essere errati. Alcune immagini CM9 hanno bisogno di avere abilitata \'opzione \"Aggiusta proprietà\" nelle \"Opzioni specifiche per il dispositivo\".</p><p>Molto importante: se il tuo dispositivo ha un\'immagine Android difettosa, segnalalo al tuo rivenditore. Più persone segnalano un problema al rivenditore, più è probabile che questi lo sistemi.</p></string> + <string name="pkcs12_file_encryption_key">File con la chiave di crittografia PKCS12</string> + <string name="private_key_password">Password della chiave privata</string> + <string name="password">Password</string> + <string name="file_icon">icona del file</string> + <string name="tls_authentication">Autenticazione TLS</string> + <string name="generated_config">Configurazione generata</string> + <string name="generalsettings">Impostazioni</string> + <string name="owner_fix_summary">Tenta di impostare system come proprietario di /dev/tun. Alcuni firmware CM9 necessitano di questa impostazione affinché le API del servizio VPN funzionino. E\' necessario essere root.</string> + <string name="owner_fix">Correggi i diritti su /dev/tun</string> + <string name="generated_config_summary">Mostra il file di configurazione di OpenVPN generato</string> + <string name="edit_profile_title">Modifica \"%s\"</string> + <string name="building_configration">Configurazione in corso…</string> + <string name="netchange_summary">Selezionando questa opzione verrà forzata una riconnessione se lo stato della rete cambia (da WIFI a cellulare e viceversa)</string> + <string name="netchange">Riconnetti in caso cambi la rete</string> + <string name="netstatus">Stato della rete: %s</string> + <string name="extracahint">Il certificato della CA è solitamente prelevato dal Keystore di Android. Indica un certificato differente se si generano errori di verifica del certificato.</string> + <string name="select_file">Selezionare</string> + <string name="keychain_nocacert">Nessun certificato della CA è stato prelevato dal Keystore di Android. E\' probabile che l\'autenticazione fallisca.</string> + <string name="show_log_summary">Mostra la finestra dei log della connessione. Si può sempre accedere alla finestra dei log tramite la barra delle notifiche.</string> + <string name="show_log_window">Visualizza la finestra dei log</string> + <string name="mobile_info">In esecuzione su %1$s (%2$s) %3$s, Android API %4$d</string> + <string name="error_rsa_sign">Errore di firma con la chiave %1$s: %2$s del Keystore di Android.</string> + <string name="faq_system_dialogs">L\'avvertimento durante la connessione VPN, in cui si informa che questo programma può intercettare tutto il traffico del sistema, serve a prevenire un uso fraudolento delle API del servizio VPN.\nL\'icona di notifica a forma di chiave è altresì imposta dal sistema Android per avvertire che si è connessi ad una VPN. Su alcuni apparecchi questa notifica è accompagnata da un suono.\nAndroid utilizza questi sistemi per la tua sicurezza e per assicurarsi che questi non vengano aggirati (in alcuni firmware questo sfortunamente è accompagnato da un suono di avvertimento).</string> + <string name="faq_system_dialogs_title">Avviso di connessione e notifica sonora</string> + <string name="translationby">Traduzione in inglese di Arne Schwabe<arne@rfc2549.org></string> + <string name="ipdns">IP e DNS</string> + <string name="basic">Principali</string> + <string name="routing">Instradamento (routing)</string> + <string name="obscure">Impostazioni avanzate di OpenVPN. Normalmente non necessarie.</string> + <string name="advanced">Avanzate</string> + <string name="export_config_title">Configurazione OpenVPN ICS</string> + <string name="warn_no_dns">Nessun server DNS verrà utilizzato. La risoluzione dei nomi potrebbe non funzionare. Provare a impostare i server DNS personalizzati. Si prega di notare, che Android utilizzerà le impostazioni del proxy specificate per la connessione Wi-Fi, quando non viene impostato alcun server DNS.</string> + <string name="dns_add_error">Impossibile aggiungere il server DNS \"%1$s\", respinto dal sistema: %2$s</string> + <string name="ip_add_error">Non è stato possibile configurare l\'indirizzo IP \"%1$s\", che è stato rifiutato dal sistema: %2$s</string> + <string name="faq_howto"><p>Ottieni una configurazione funzionante (testata sul tuo computer o fornita dal tuo provider o dalla tua ditta).</p><p>Se si tratta di un singolo file senza ulteriori file tipo pem/pkcs12, puoi spedire il file a te stesso via email ed aprire l\'allegato. Se hai più file, salvali sulla scheda SD.</p><p>Clicca sull\'allegato dell\'email oppure utilizza l\'icona della cartella nell\'elenco delle VPN per importare il file di configurazione.</p><p>Se compaiono degli errori relativi a file non trovati, copia i file mancanti sulla tua scheda SD.</p><p>Clicca sull\'icona di salvataggio per aggiungere la VPN importata nell\'elenco delle tue VPN.</p><p>Connettiti alla VPN cliccando sul nome della VPN.</p><p>Se compaiono degli errori o degli avvertimenti nei log, si consiglia di non ignorarli, ma di cercare delle soluzioni.</p> </string> + <string name="faq_howto_title">Guida rapida</string> + <string name="setting_loadtun_summary">Prova a caricare il modulo tun.ko prima di connettersi. Si devono avere diritti di root sul dispositivo.</string> + <string name="setting_loadtun">Carica il modulo tun</string> + <string name="importpkcs12fromconfig">Importa i PKCS12 dalla configurazione presente nel Keystore di Android</string> + <string name="getproxy_error">Errore nell\'ottenere le impostazioni del proxy: %s</string> + <string name="using_proxy">Si sta utilizzando il proxy %1$s %2$d</string> + <string name="use_system_proxy">Utilizza il proxy di sistema</string> + <string name="use_system_proxy_summary">Utilizza la configurazione generale del sistema relativa ai proxy HTTP/HTTPS per connettersi.</string> + <string name="donatewithpaypal">Puoi <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;cmd=_s-xclick\">donare tramite PayPal</a> </string> + <string name="onbootrestartsummary">OpenVPN is riconnetterà alla VPN se era in funzione durante un riavvio od un spegnimento dell\'apparecchio. Leggi con attenzione le FAQ con gli avvertimenti sulla connessione prima di scegliere questa opzione.</string> + <string name="onbootrestart">Riconnetti al riavvio</string> + <string name="ignore">Ignora</string> + <string name="restart">Riavvia</string> + <string name="restart_vpn_after_change">Le modifiche sarannoi applicate dopo aver riavviato la connessione VPN. Riavviare ora la connessione?</string> + <string name="configuration_changed">Configurazione modificata</string> + <string name="log_no_last_vpn">Impossibile determinare l\'ultimo profilo con cui ci si è connessi per poterlo modificare</string> + <string name="faq_duplicate_notification_title">Doppie notifiche</string> + <string name="faq_duplicate_notification">Normalmente, se la memoria di sistema (RAM) di Android è insufficiente, i programmi ed i servizi che non sono in quel momento necessari vengono rimossi dalla memoria attiva. Se ciò avvenisse, la connessione VPN in corso verrebbe terminata. Per far sì che la conessione OpenVPN resti in funzione, il servizio viene eseguito in priorità alta e per questo motivo appare un\'icona permanente nella barra delle notifiche. L\'icona di notifica a forma di chiave è invece imposta dal sistema come descritto nella precedente voce delle FAQ e non serve ad eseguire il programma con priorità alta.</string> + <string name="no_vpn_profiles_defined">Nessun profilo VPN definito.</string> + <string name="add_new_vpn_hint">Usa l\'icona <img src=\"ic_menu_add\"/> per aggiungere una nuova VPN</string> + <string name="vpn_import_hint">Usa l\'icona <img src=\"ic_menu_archive\"/> per importare il profilo (.ovpn o .conf) dalla tua scheda SD.</string> + <string name="faq_hint">Si raccomanda di leggere anche le FAQ. C\'è anche una guida rapida.</string> + <string name="faq_routing_title">Configurazione dei reindirizzamenti e dell\'interfaccia</string> + <string name="faq_routing">Il routing e la configurazione dell\'interfaccia non è fatta tramite il tradizionale comando ifconfig/route ma tramite la API VPNService. Questo determina una configurazione differente rispetto ad altri S.O. La configurazione consiste solo nell\'IP dell\'interfaccia di tunnel e nelle reti che dovrebbero essere ridirette su questa interfaccia. In particolare non è necessario specificare alcun indirizzo del partner o del gateway. Nè sono necessarie rotte particolari per raggiungere il Server VPN (ad esempio quando si usa l\'opzione redirect-gateway). L\'applicazione ignorerà quindi tutte queste impostazioni quando si importa una configurazione. L\'applicazione si assicura con la API VPNService che la connessione al server non venga reindirizzata tramite il tunnel VPN. Dal momento che solo reti specifiche sono supportate per essere reindirizzate tramite il tunner, anche altre rotte che non indirizzano il tunnel non possono essere supportate. (es. route x.x.x.x y.y.y.y net_gateway). La finestra del log mostra la configurazione corrente di VPNService non appena viene stabilita una connessione. </string> + <string name="persisttun_summary">Non passa allo stato di \"Nessuna connessione VPN\" quando OpenVPN sta eseguendo un tentativo di riconnessione.</string> + <string name="persistent_tun_title">tun persistente</string> + <string name="openvpn_log">Log di OpenVPN</string> + <string name="import_config">Importa configurazione OpenVPN</string> + <string name="battery_consumption_title">Consumo della batteria</string> + <string name="baterry_consumption">Nei miei test personali la ragione principale per l\'alto consumo di batteria con OpenVPN è rappresentata dai pacchetti keepalive. La maggior parte dei server OpneVPN posseggono una direttiva \'keepalive 10 60\' che fa sì che il client e il server scambino dei pacchetti keepalive ogni dieci secondi.<p> Anche se questi pacchetti sono piccoli e non usano molto traffico, essi mantengono impegnata la sezione radio del dispositivo e incrementano il consumo energetico. (Vedere anche <a href=\"http://developer.android.com/training/efficient-downloads/efficient-network-access.html#RadioStateMachine\">The Radio State Machine | Android Developers</a>) <p> Questa impostazione keepalive non può essere cambiata lato client. Solo l\'amministratore del server OpenVPN può farlo.<p> Purtroppo usando un keepalive maggiore di 60 secondi con UDP alcuni gateway NAT fanno cadere la connessione per via di un timeout su inattività. Usando TCP con un keepalive lungo il timeout funziona, ma il tunneling su TCP presenta basse prestazioni su connessioni con alta perdita di pacchetti. (Vedere <a href=\"http://sites.inka.de/bigred/devel/tcp-tcp.html\">Why TCP Over TCP Is A Bad Idea</a>)</string> + <string name="faq_tethering">Il Tethering di Android (via WiFi, USB o Bluetooth) e le API del servizio VPN (utilizzate da questo programma) non possono funzionare contemporaneamente. Per maggiori informazioni, vedi <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=34\">il problema #34</a></string> + <string name="vpn_tethering_title">VPN e Tethering</string> + <string name="connection_retries">Tentativi di riconnessione</string> + <string name="reconnection_settings">Impostazioni di riconnessione</string> + <string name="connectretrymessage">Numero di secondi di attesa tra i tentativi di connessione.</string> + <string name="connectretrywait">Secondi tra le connessioni</string> + <string name="minidump_generated">OpenVPN si è arrestato in modo imprevisto. Ti consigliamo di attivare l\'opzione Invia Minidump nel menu principale.</string> + <string name="send_minidump">Invia Minidump allo sviluppatore</string> + <string name="send_minidump_summary">Invia informazioni di debug riguardanti l\'ultimo crash allo sviluppatore</string> + <string name="notifcation_title">OpenVPN - %s</string> + <string name="session_ipv4string">%1$s - %2$s</string> + <string name="session_ipv6string">%1$s - %3$s, %2$s</string> + <string name="state_connecting">Connessione in corso</string> + <string name="state_wait">In attesa di risposta dal server</string> + <string name="state_auth">Autenticazione</string> + <string name="state_get_config">Caricamento configurazione client</string> + <string name="state_assign_ip">Assegnazione indirizzi IP</string> + <string name="state_add_routes">Configuro gli instradamenti</string> + <string name="state_connected">Connesso</string> + <string name="state_disconnected">Disconnetti</string> + <string name="state_reconnecting">Riconnessione in corso</string> + <string name="state_exiting">Uscita</string> + <string name="state_noprocess">Non in esecuzione</string> + <string name="state_resolve">Risoluzione hostname in corso</string> + <string name="state_tcp_connect">Connessione in corso (TCP)</string> + <string name="state_auth_failed">Autenticazione fallita</string> + <string name="state_nonetwork">In attesa di una rete utilizzabile</string> + <string name="statusline_bytecount">↓%2$s/s %1$s - ↑%4$s/s %3$s</string> + <string name="notifcation_title_notconnect">Non connesso</string> + <string name="start_vpn_title">Connessione alla VPN %s in corso</string> + <string name="start_vpn_ticker">Connessione alla VPN %s in corso</string> + <string name="jelly_keystore_alphanumeric_bug">Alcune versioni di Android 4.1 hanno problemi se il nome del certificato keystore contiene caratteri non alfanumerici (come spazi, caratteri di sottolineatura o trattini). Provare a reimportare il certificato senza caratteri speciali</string> + <string name="encryption_cipher">Algoritmo di crittografia</string> + <string name="packet_auth">Autenticazione pacchetti</string> + <string name="auth_dialog_title">Seleziona il metodo di autenticazione dei pacchetti</string> + <string name="mobile_info_extended">In esecuzione su %1$s (%2$s) %3$s, Android API %4$d, versione %5$s, %6$s</string> + <string name="built_by">compilato da %s</string> + <string name="debug_build">versione di debug</string> + <string name="official_build">versione ufficiale</string> + <string name="make_selection_inline">Copia nel profilo</string> + <string name="crashdump">Dump del crash</string> + <string name="add">Aggiungi</string> + <string name="send_config">Invia file di configurazione</string> + <string name="complete_dn">DN completo</string> + <string name="remotetlsnote">La configurazione importata utilizza l\'opzione tls-remote che è obsoleta, ed utilizza un diverso formato DN.</string> + <string name="rdn">RDN (nome comune)</string> + <string name="rdn_prefix">Prefisso RDN</string> + <string name="tls_remote_deprecated">TLS-remote (obsoleto)</string> + <string name="help_translate">Puoi aiutare nella traduzione visitando http://crowdin.net/project/ics-openvpn/invite</string> + <string name="prompt">%1$s tenta di controllare %2$s</string> + <string name="remote_warning">Se procedi, concedi all\'applicazione l\'autorizzazione per intercettare tutto il traffico di rete.<b> NON accettare se non consideri l\'applicazione attendibile</b>, altrimenti corri il rischio che i tuoi dati vengano compromessi da programmi software dannosi</string> + <string name="remote_trust">Considero questa applicazione attendibile.</string> + <string name="no_external_app_allowed">Nessuna app ha il permesso di usare l\'API esterna</string> + <string name="allowed_apps">Apps abilitate;%s</string> + <string name="clearappsdialog">Cancellare la lista delle apps esterne autorizzate?\nLista corrente di applicazioni autorizzate:\n\n%s</string> + <string name="screenoff_summary">Sospende la VPN quando lo schermo è spento e meno di 64Kb di dati sono trasferiti in 60s. Quando l\'opzione \"Tun persistente\" è abilitata, la sospensione della VPN lascerà il tuo dispositivo con NESSUNA connettività di rete. Senza l\'opzione \"Tun persistente\" il dispositivo non avrà alcuna connessione/protezione VPN.</string> + <string name="screenoff_title">Sospende la connessione VPN dopo lo spegnimento dello schermo</string> + <string name="screenoff_pause">Sospensione della connessione nello stato di schermo spento: meno di %1$s in %2$ss</string> + <string name="screen_nopersistenttun">Attenzione: \"Tun persistente\" non è abilitato per questa VPN. Quando lo schermo è spento verrà utilizzata la normale connessione internet.</string> + <string name="save_password">Salva la Password</string> + <string name="pauseVPN">Pausa della VPN</string> + <string name="resumevpn">Ricollega la VPN</string> + <string name="state_userpause">Sospensione della VPN richiesta dall\'utente</string> + <string name="state_screenoff">VPN sospesa - schermo spento</string> + <string name="device_specific">Regolazioni specifiche per il dispositivo</string> + <string name="cannotparsecert">Non è possibile visualizzare le informazioni del certificato</string> + <string name="appbehaviour">Comportamento dell\'applicazione</string> + <string name="vpnbehaviour">Comportamento della VPN</string> + <string name="allow_vpn_changes">Abilita modifiche ai profili VPN</string> + <string name="hwkeychain">Raccoglitore chiavi hardware:</string> + <string name="permission_icon_app">Un\'icona di applicazione sta tentando di usare OpenVPN per Android</string> + <string name="faq_vpndialog43">"A partire da Android 4.3 la conferma della VPN viene salvaguardata da \"applicazioni in overlay\". Questo fa sì che il bottone di dialogo non reagisca allo sfioramento. Se avete un\'applicazione che usa gli overlay, ciò potrebbe causare questo comportamento. Se vi capita di trovare questo tipo di situazione, contattate l\'autore dell\'applicazione. Questo problema affligge tutte le applicazioni VPN da Android 4.3 in poi. Consultare anche <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=185\">Issue 185<a> per ulteriori dettagli"</string> + <string name="faq_vpndialog43_title">Messaggio di conferma Vpn su Android 4.3 e versioni successive</string> + <string name="donatePlayStore">In alternativa, potete inviarmi una donazione con il Play Store:</string> + <string name="thanks_for_donation">Grazie per la donazione di %s!</string> + <string name="logCleared">Registrazioni log cancellate.</string> + <string name="show_password">Mostra password</string> + <string name="keyChainAccessError">Errore di accesso al Gestore Chiavi: %s</string> + <string name="timestamp_short">Breve</string> + <string name="timestamp_iso">ISO</string> + <string name="timestamps">Indicazione oraria</string> + <string name="timestamps_none">Nulla</string> + <string name="uploaded_data">Upload</string> + <string name="downloaded_data">Download</string> + <string name="vpn_status">Stato VPN</string> + <string name="logview_options">Visualizza opzioni</string> + <string name="unhandled_exception">Eccezione non gestita: %1$s\n\n%2$s</string> + <string name="unhandled_exception_context">%3$s: %1$s\n\n%2$s</string> + <string name="full_licenses">Licenze complete</string> +</resources> diff --git a/main/src/main/res/values-ja/arrays.xml b/main/src/main/res/values-ja/arrays.xml new file mode 100755 index 00000000..57442375 --- /dev/null +++ b/main/src/main/res/values-ja/arrays.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string-array name="vpn_types"> + <item>証明書</item> + <item>PKCS12 ファイル</item> + <item>Androidの証明書管理</item> + <item>ユーザー名/パスワード</item> + <item>共有鍵</item> + <item>User/PWと証明書</item> + <item>User/PWとPKCS12ファイル</item> + <item>User/PWとAndroidの証明書管理</item> + </string-array> + <string-array name="tls_directions_entries"> + <item>0</item> + <item>1</item> + <item>未指定</item> + </string-array> + <string-array name="crm_entries"> + <item>No reconnection retries</item> + <item>One reconnection retry</item> + <item>Five reconnection retries</item> + <item>Fifty reconnection retries</item> + <item>Unlimited reconnection retries</item> + </string-array> +</resources> diff --git a/main/src/main/res/values-ja/strings.xml b/main/src/main/res/values-ja/strings.xml new file mode 100755 index 00000000..f59e67b1 --- /dev/null +++ b/main/src/main/res/values-ja/strings.xml @@ -0,0 +1,299 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string name="app">OpenVPN for Android</string> + <string name="address">サーバアドレス</string> + <string name="port">ポート番号</string> + <string name="location">場所</string> + <string name="cant_read_folder">ディレクトリが読み取れません</string> + <string name="select">選択</string> + <string name="cancel">キャンセル</string> + <string name="no_data">データなし</string> + <string name="useLZO">LZO 圧縮</string> + <string name="client_no_certificate">証明書がありません。</string> + <string name="client_certificate_title">クライアント証明書</string> + <string name="client_key_title">クライアント証明書のキー</string> + <string name="client_pkcs12_title">PKCS12ファイル</string> + <string name="ca_title">CA 証明書</string> + <string name="no_certificate">証明書を選択する必要があります。</string> + <string name="copyright_guicode">ソースコードと問題管理はここにあります: http://code.google.com/p/ics-openvpn/</string> + <string name="copyright_others">プログラムは、次のコンポーネントを使用します。完全な詳細についてはソース上のライセンスを参照してください。</string> + <string name="about">バージョン情報</string> + <string name="vpn_list_title">プロファイル</string> + <string name="vpn_type">種別</string> + <string name="pkcs12pwquery">PKCS12のパスワード</string> + <string name="file_select">選択</string> + <string name="file_nothing_selected">ファイルを選択する必要があります。</string> + <string name="useTLSAuth">TLS認証を使用します。</string> + <string name="tls_direction">TLS Direction</string> + <string name="ipv6_dialog_tile">IPv6アドレスをCIDR形式で入力(例:2000:dd::23/64)</string> + <string name="ipv4_dialog_title">IPv4アドレスをCIDR形式で入力(例:1.2.3.4/24)</string> + <string name="ipv4_address">IPv4アドレス</string> + <string name="ipv6_address">IPv6アドレス</string> + <string name="custom_option_warning">OpenVPNのカスタムオプションを入力します。利用には細心の注意が必要です。設定画面ではTUNモジュールの多くの設定がサポートされていません。もしほかに重要と思う設定があれば作者に連絡してください。</string> + <string name="auth_username">ユーザー名</string> + <string name="auth_pwquery">パスワード</string> + <string name="static_keys_info">TLS認証鍵の設定は、静的キーとして使用されます。</string> + <string name="configure_the_vpn">VPNの設定</string> + <string name="menu_add_profile">プロファイルの追加</string> + <string name="add_profile_name_prompt">新しいプロファイルを識別する名前を入力します</string> + <string name="duplicate_profile_name">プロファイル名が重複しています。</string> + <string name="profilename">プロファイル名</string> + <string name="no_keystore_cert_selected">ユーザー証明書を選択する必要があります。</string> + <string name="no_error_found">エラーは見つかりませんでした。</string> + <string name="config_error_found">設定に誤りがあります。</string> + <string name="ipv4_format_error">IPv4 アドレスの解析エラー</string> + <string name="custom_route_format_error">カスタム経路の解析エラー</string> + <string name="pw_query_hint">必要に応じて入力するには空欄にしてください</string> + <string name="vpn_shortcut">OpenVPN のショートカット</string> + <string name="vpn_launch_title">VPNに接続</string> + <string name="shortcut_profile_notfound">ショートカットで指定されたプロファイルが見つかりません</string> + <string name="random_host_prefix">ランダムなホスト プレフィックス</string> + <string name="random_host_summary">ランダムな6文字をホスト名の前に付加します。</string> + <string name="custom_config_title">カスタム オプションを使用する</string> + <string name="custom_config_summary">カスタムオプションを指定します。注意を要します。</string> + <string name="route_rejected">経路がAndroidにより拒否されました。</string> + <string name="cancel_connection">切断</string> + <string name="cancel_connection_long">VPNを切断します</string> + <string name="clear_log">ログをクリア</string> + <string name="title_cancel">キャンセルの確認</string> + <string name="cancel_connection_query">接続中または試行中の接続をキャンセルしますか?</string> + <string name="remove_vpn">VPN を削除</string> + <string name="remote_tlscn_check_summary">リモートサーバー証明書の所有者識別子(Subject DN)を確認します。</string> + <string name="remote_tlscn_check_title">証明書のホスト名を確認する</string> + <string name="enter_tlscn_dialog">リモート証明書の照合に使用する識別名(DN)を指定します。(例: C=DE, L=Paderborn, OU=Avian IP Carriers, CN=openvpn.blinkt.de)\n\n完全な識別名(DN)または相対識別名(RDN)、あるいは相対識別名のプリフィクスを指定します。\n\nたとえば相対識別名のプリフィクスとして\"Server\"を指定すると、\"Server-1\"と\"Server-2\"にマッチします。\n\n空欄にした場合は相対識別名とサーバのホスト名をチェックします。\n\n詳細についてはOpenVPN 2.3.1以降のマニュアルの「--verify-x509-name」の項を参照してください。</string> + <string name="enter_tlscn_title">リモート証明書サブジェクト</string> + <string name="tls_key_auth">TLS鍵認証を有効にする</string> + <string name="tls_auth_file">TLS 認証ファイル</string> + <string name="pull_on_summary">IPアドレス、経路情報、DNSなどの情報をサーバから取得します。</string> + <string name="pull_off_summary">サーバからは何も情報が取得できません。指定が必要な設定は以下の通りです。</string> + <string name="use_pull">情報取得の設定</string> + <string name="dns">DNS</string> + <string name="override_dns">サーバ指定のDNSサーバ設定をオーバーライドします。</string> + <string name="dns_override_summary">DNSをユーザ側で指定します。</string> + <string name="searchdomain">検索ドメイン</string> + <string name="dns1_summary">使用する DNS サーバー</string> + <string name="dns_server">DNS サーバー</string> + <string name="secondary_dns_message">セカンダリDNSサーバーは、プライマリDNSサーバーに到達できない場合に使用します。</string> + <string name="backup_dns">セカンダリDNSサーバー</string> + <string name="ignored_pushed_routes">サーバ側指定の経路情報を無視する</string> + <string name="ignore_routes_summary">サーバからプッシュされた経路情報を無視します。</string> + <string name="default_route_summary">すべての通信をVPN経由にします</string> + <string name="use_default_title">既定の経路に使用</string> + <string name="custom_route_message">カスタム経路を入力します。宛先のみをCIDR形式で指定します。例えば \"10.0.0.0/8 2002::/16\"と指定すれば10.0.0.0/8と2002::/16への通信はVPNに向けられます。</string> + <string name="custom_routes_title">カスタム経路情報</string> + <string name="log_verbosity_level">ログの詳細度</string> + <string name="float_summary">認証済みパケットをどのIPからでも受け付けます。</string> + <string name="float_title">フローティング サーバーを許可</string> + <string name="custom_options_title">カスタム オプション</string> + <string name="edit_vpn">VPN 設定の編集</string> + <string name="remove_vpn_query">VPN プロファイル %s を削除しますか?</string> + <string name="tun_error_helpful">いくつかのカスタムICSイメージは、/dev/tunのパーミッションが異常か、TUNモジュールが含まれていません。CM9イメージの場合は全般設定で所有権設定を修正してください。</string> + <string name="tun_open_error">TUNデバイスを開こうとして失敗しました。</string> + <string name="error">"エラー:"</string> + <string name="clear">クリア</string> + <string name="last_openvpn_tun_config">tunインターフェースを開いています:</string> + <string name="local_ip_info">ローカル IPv4: %1$s/%2$d IPv6: %3$s MTU: %4$d</string> + <string name="dns_server_info">DNSサーバ: %1$s, ドメイン: %2$s</string> + <string name="ip_not_cidr">インターフェース情報として[%1$s]と[%2$s]を取得しました。2つめのアドレスはリモート側のピアアドレスです。32ビットマスクをローカルIPに使用します。 OpenVPNのモードは[%3$s]です。</string> + <string name="route_not_cidr">%1$sと%2$sではCIDR形式のIP経路情報として意味をなしません。32ビットマスクを使用します。</string> + <string name="route_not_netip">経路情報%1$s/%2$sを%3$s/%2$sに修正しました。</string> + <string name="keychain_access">Androidの証明書管理にアクセスできません。(ファームウェアの更新、アプリケーションまたはその設定のリストアによって発生する場合があります)。VPNの設定で証明書の選択を再度行ってください。</string> + <string name="version_info">%1$s %2$s</string> + <string name="send_logfile">ログ ファイルを送信します。</string> + <string name="send">送信</string> + <string name="ics_openvpn_log_file">ICS OpenVPN ログ ファイル</string> + <string name="copied_entry">クリップ ボードにコピーされたログ エントリ</string> + <string name="tap_mode">TAPモード</string> + <string name="faq_tap_mode">TAPモードは非root化環境では動作しません。よってこのアプリケーションではTAPをサポートできません。</string> + <string name="tap_faq2">またですか?TAPモードはサポートされていませんし、サポートされるかどうかメールを送ることは何の役にも立ちません。</string> + <string name="tap_faq3">3回目です。本当のところ、TUN上で動くレイヤ2エミュレータを書くことはできました。(送信時の情報追加と受信時の情報削除で)。しかしこのエミュレータはARPやおそらくはDHCPをも実装しなければならないでしょう。誰もこのことに気がついていません。もしあなたがこの機能を作る気になったのであれば、どうぞ私に連絡してください。 +</string> + <string name="faq">よくある質問</string> + <string name="copying_log_entries">ログ エントリのコピー</string> + <string name="faq_copying">1行のログエントリをコピーするには、そのエントリをタッチし続けます。コピー/送信するには「ログエントリを送信」を使用します。GUIで表示されない場合はハードウェアのメニューボタンを使用してください。</string> + <string name="faq_shortcut">起動ショートカット</string> + <string name="faq_howto_shortcut">OpenVPNを起動するためのショートカットをデスクトップに配置できます。ショートカットやウィジェットを配置できるかどうかはホームスクリーンプログラムに依存します。</string> + <string name="no_vpn_support_image">申し訳ありませんが、お使いの環境ではVPNサービスがサポートされていません。</string> + <string name="encryption">暗号化</string> + <string name="cipher_dialog_title">暗号化方式を入力</string> + <string name="auth_dialog_message">OpenVPNが使用する認証ダイジェストを入力します。空欄にするとデフォルトのダイジェストを使用します。</string> + <string name="settings_auth">認証/暗号化</string> + <string name="file_explorer_tab">ファイルを選択</string> + <string name="inline_file_tab">インライン ファイル</string> + <string name="error_importing_file">ファイルのインポート エラー</string> + <string name="import_error_message">ファイルシステムからファイルをインポートできませんでした。</string> + <string name="inline_file_data">[インライン ファイル データ]</string> + <string name="opentun_no_ipaddr">IP情報なしでのTUNデバイス使用は拒否しています</string> + <string name="menu_import">OVPNファイルからプロファイルをインポート</string> + <string name="menu_import_short">インポート</string> + <string name="import_content_resolve_error">インポートするプロファイルを読み取れませんでした。</string> + <string name="error_reading_config_file">構成ファイルの読み取りエラー</string> + <string name="add_profile">プロファイルの追加</string> + <string name="import_could_not_open">インポートされた構成ファイルに記載されたファイル %1$s が見つかりません。</string> + <string name="importing_config">構成ファイルを%1$sからインポートしています。</string> + <string name="import_warning_custom_options">ユーザインターフェースにマッピングされていないいくつかの設定項目があります。それらの設定はカスタムオプションとして追加されます。カスタムオプションを以下に表示します。</string> + <string name="import_done">構成ファイルの読み取り終了。</string> + <string name="nobind_summary">ローカル アドレスとポートにバインドを行いません。</string> + <string name="no_bind">ローカルバインドしない</string> + <string name="import_configuration_file">構成ファイルのインポート</string> + <string name="faq_security_title">セキュリティに関する考慮事項</string> + <string name="faq_security">OpenVPNがセキュリティに敏感であるように、セキュリティに関してのいくつかの注意事項は理にかなっています。 +SDカード上のデータは本質的に無防備です。すべてのアプリケーションが読み取り可能です。(たとえばこのプログラムはSDカードへの特別な読み取り許可を必要としていません) +このアプリケーションのデータは、自分自身のみが読み取り可能です。インポートされた証明書類はVPNプロファイルに保存されています。VPNプロファイルはこのアプリケーションからのみアクセス可能です。(あとでSDカード上のファイルを消すのを忘れないでください) +ただし、このアプリケーションからのみ読み取り可能ではあるものの、暗号化されてはいません。 +機体をroot化したり、あるいはその他の脆弱性によってファイルは読み取ることが可能かもしれません。パスワードは平文で保存されています。PKCS12ファイルをAndroidの証明書管理機能にインポートして使用することが強く推奨されます。</string> + <string name="import_vpn">インポート</string> + <string name="broken_image_cert_title">証明書の選択でエラーが表示されます</string> + <string name="broken_image_cert">Android 4.0以降の証明書選択ダイアログ表示で例外を検知しました。 +この事象は標準的なAndroid 4.0以降では発生しません。お使いのAndroidの証明書管理機構が壊れている可能性があります。</string> + <string name="ipv4">IPv4</string> + <string name="ipv6">IPv6</string> + <string name="speed_waiting">状態メッセージを待っています。</string> + <string name="converted_profile">インポートされたプロファイル</string> + <string name="converted_profile_i">インポートされたプロファイル %d</string> + <string name="broken_images">壊れたイメージ</string> + <string name="pkcs12_file_encryption_key">PKCS12ファイルの暗号化キー</string> + <string name="private_key_password">秘密鍵のパスワード</string> + <string name="password">パスワード</string> + <string name="file_icon">ファイルのアイコン</string> + <string name="tls_authentication">TLS認証</string> + <string name="generated_config">生成された構成</string> + <string name="generalsettings">設定</string> + <string name="owner_fix_summary">システムに/dev/tunの所有者を設定します。いくつかのCM9のイメージでVPNService APIを動作させるために必要です。root権限が必要です。</string> + <string name="owner_fix">/dev/tun の所有権を修正</string> + <string name="generated_config_summary">生成された OpenVPN の構成ファイルを表示します</string> + <string name="edit_profile_title">\"%s\"の編集</string> + <string name="building_configration">構成中・・・</string> + <string name="netchange_summary">この設定を有効にすると、ネットワークの状態変化時(WiFi/モバイル)に再接続を行います。</string> + <string name="netchange">ネットワーク変化時に再接続</string> + <string name="netstatus">ネットワーク状態: %s</string> + <string name="extracahint">認証局証明書(CA cert)は、通常、Android のキーストアから返されます。証明書の検証でエラーになる場合は、個別の証明書を指定します。</string> + <string name="select_file">選択</string> + <string name="keychain_nocacert">認証局証明書(CA Cert)がAndroidのキーストアから取得できませんでした。認証はおそらく失敗します。</string> + <string name="show_log_summary">接続時にログウィンドウを表示します。ログウィンドウは常に状態通知からアクセスできます。</string> + <string name="show_log_window">ログウィンドウを表示</string> + <string name="mobile_info">実行中:%1$s (%2$s)%3$s Android API %4$d</string> + <string name="error_rsa_sign">Androidキーストアに保存されたキー %1$s: %2$sの署名エラーです</string> + <string name="faq_system_dialogs">VPN接続の警告は、このアプリケーションがVPNService APIを悪用してすべての通信を傍受できることを、システムがあなたに知らせるものです。\n +VPN接続通知(鍵の形)は、VPN接続が稼働中であることをAndroidが知らせています。いくつかのシステムではこの通知で音を鳴らします。\n +Androidはあなた自身の安全性のために、これらを迂回できないようにしています。(いくつかのシステムでは、遺憾ながら音も伴います)</string> + <string name="faq_system_dialogs_title">接続時の警告と通知音</string> + <string name="translationby">日本語翻訳 高橋正希@埼玉 <tools@artin.nu></string> + <string name="ipdns">IPとDNS</string> + <string name="basic">基本</string> + <string name="routing">経路設定</string> + <string name="obscure">特殊なOpenVPNの設定。通常は必要ありません</string> + <string name="advanced">高度</string> + <string name="export_config_title">ICSのOpenVPN設定</string> + <string name="warn_no_dns">DNSサーバーが使用されていません。名前解決が動作しない可能性があります。カスタムDNSの設定を検討してください。また、DNSが指定されていない場合Androidはモバイル回線/WiFi接続に設定したプロキシを使用し続けることにも注意してください。</string> + <string name="dns_add_error">DNSサーバ \"%1$s\" の追加に失敗しました。%2$sに拒否されました。</string> + <string name="faq_howto"><p>動作確認済の設定ファイルを入手します。(あなたのコンピュータでテスト済のものや、プロバイダや会社などの組織からダウンロードしたもの)</p> +<p>もしそれが単一のファイルでpemやpks12ファイルを伴わないなら、自分宛のメールに添付して送付し、それを開いてください。もし複数のファイルで構成されているならSDカードに格納してください。</p> +<p>メールの添付ファイルを開く、あるいはVPNリストのフォルダアイコンをクリックして設定ファイルをインポートします。</p> +<p>もしファイルが足りないというエラーが表示されたら、足りなかったファイルをSDカード上に格納してください。</p> +<p>インポートされたVPN設定をリストに追加するには、保存アイコンをクリックします。</p> +<p>VPNを接続するには、VPNの名称をクリックします。</p> +<p>もし警告やエラーがログエントリに表示されたら、それらを調べて解決してください。</p> +</string> + <string name="faq_howto_title">クイックスタート</string> + <string name="setting_loadtun_summary">接続の試行前にTUNデバイスモジュール(tun.ko)を読み込みます。デバイスのroot化が必要です。</string> + <string name="setting_loadtun">TUNモジュールをロード</string> + <string name="importpkcs12fromconfig">PKCS12の設定をAndroidのキーストアにインポートします</string> + <string name="getproxy_error">プロキシ設定でエラー: %s</string> + <string name="using_proxy">プロキシを使用します %1$s %2$d</string> + <string name="use_system_proxy">システムのプロキシ設定を使用</string> + <string name="use_system_proxy_summary">システム全体の構成の HTTP/HTTPS プロキシ接続を使用します。</string> + <string name="donatewithpaypal">以下のURLより寄付いただけます。 <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;cmd=_s-xclick\">PayPalで寄付</a> </string> + <string name="onbootrestartsummary">OpenVPNはシステムの再起動やシャットダウン時に再接続するようになります。このオプションを使用する前にFAQをご一読ください。</string> + <string name="onbootrestart">システム起動後に再接続</string> + <string name="ignore">無視</string> + <string name="restart">再起動</string> + <string name="restart_vpn_after_change">設定の変更はVPNの再起動後に反映されます。VPNを(再)起動しますか?</string> + <string name="configuration_changed">設定が変更されました</string> + <string name="log_no_last_vpn">編集されたため、最後に接続したプロファイルを確認できませんでした +</string> + <string name="faq_duplicate_notification_title">重複した通知</string> + <string name="faq_duplicate_notification">もしAndroidがメモリ不足に陥った場合、その時点で必要とされないアプリケーションやサービスはアクティブなメモリから排除されます。 +この処理に伴い、VPN接続は終了されます。 +OpenVPNの接続を保証するためには、アプリケーションを高い優先度で稼働させます。 +高い優先度でアプリケーションを稼働させる場合、アプリケーションは通知を表示しなければなりません。 +鍵の形をした通知アイコンは、先述のFAQにあるとおりシステムにより表示させられたものです。 +高い優先度で稼働するための通知はアプリケーションの通知には含まれません。</string> + <string name="no_vpn_profiles_defined">VPNのプロファイルが定義されていません</string> + <string name="add_new_vpn_hint">新しいVPNを追加するには <img src=\"ic_menu_add\"/> のアイコンを使用します</string> + <string name="vpn_import_hint">SDカードからプロファイル(.ovpnや.conf)をインポートするには <img src=\"ic_menu_archive\"/> のアイコンを使用します。</string> + <string name="faq_hint">FAQを確認してください。クイックスタートガイドがあります。</string> + <string name="faq_routing_title">経路情報/インターフェース設定</string> + <string name="persisttun_summary">OpenVPNが再接続試行中は、VPNなし状態を報告しません。</string> + <string name="persistent_tun_title">永続的なTUNデバイス</string> + <string name="openvpn_log">OpenVPN のログ</string> + <string name="import_config">OpenVPN の構成のインポート</string> + <string name="battery_consumption_title">バッテリー消費量</string> + <string name="faq_tethering">Androidのテザリング機能(WiFi, USB, Bluetooth経由)とVPNService API(このプログラムから使用する機能)は同時に利用できません。詳細については<a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=34\">issue #34</a>を参照</string> + <string name="vpn_tethering_title">VPN とテザリング</string> + <string name="connection_retries">接続の再試行回数</string> + <string name="reconnection_settings">再接続の設定</string> + <string name="connectretrymessage">再接続を試行する際の間隔(秒)</string> + <string name="connectretrywait">接続間隔(秒)</string> + <string name="minidump_generated">OpenVPN は予期せず終了しました。メイン メニューでミニダンプの送信オプションを検討してください。</string> + <string name="send_minidump">ミニダンプを開発者に送信</string> + <string name="send_minidump_summary">最後にクラッシュした時のデバッグ情報を作者に送信します。</string> + <string name="notifcation_title">OpenVPN - %s</string> + <string name="session_ipv4string">%1$s - %2$s</string> + <string name="session_ipv6string">%1$s - %3$s, %2$s</string> + <string name="state_connecting">接続中</string> + <string name="state_wait">サーバーの応答を待っています。</string> + <string name="state_auth">認証中</string> + <string name="state_get_config">クライアントの構成を取得中</string> + <string name="state_assign_ip">IPアドレスを割り当て中</string> + <string name="state_add_routes">経路を追加中</string> + <string name="state_connected">接続しました</string> + <string name="state_disconnected">切断</string> + <string name="state_reconnecting">再接続中</string> + <string name="state_exiting">終了中</string> + <string name="state_noprocess">停止中</string> + <string name="state_resolve">ホスト名を解決中</string> + <string name="state_tcp_connect">接続中(TCP)</string> + <string name="state_auth_failed">認証に失敗しました</string> + <string name="state_nonetwork">使用可能なネットワークを待機中</string> + <string name="statusline_bytecount">↓%2$s/s %1$s - ↑%4$s/s %3$s</string> + <string name="notifcation_title_notconnect">未接続</string> + <string name="start_vpn_title">VPN %sに接続中</string> + <string name="start_vpn_ticker">VPN %sに接続中</string> + <string name="jelly_keystore_alphanumeric_bug">Android 4.1の一部のバージョンで、キーストアの証明書の名前にアルファベット以外の特殊な文字(スペース、アンダーバー、ダッシュ等)を含む場合に問題が発生します。証明書の名前から特殊な文字を外して再度インポートを試みてください。</string> + <string name="encryption_cipher">暗号化方式</string> + <string name="packet_auth">パケット認証</string> + <string name="auth_dialog_title">パケット認証方式を入力してください。</string> + <string name="mobile_info_extended">%1$s (%2$s) %3$s、Android API %4$d、バージョン %5$s %6$s において実行中</string> + <string name="built_by">%s によりビルド</string> + <string name="debug_build">デバッグ ビルド</string> + <string name="official_build">正式ビルド</string> + <string name="make_selection_inline">プロファイルにコピー</string> + <string name="crashdump">クラッシュ ダンプ</string> + <string name="add">追加</string> + <string name="send_config">構成ファイルを送信</string> + <string name="complete_dn">完全な識別名(DN)</string> + <string name="remotetlsnote">あなたがインポートした設定は異なるDNフォーマットを使用した非推奨のtls-remoteオプションを使用しています。</string> + <string name="rdn">相対識別名(RDN/共通名)</string> + <string name="rdn_prefix">相対識別名(RDN)プリフィクス</string> + <string name="tls_remote_deprecated"> tls-remote (非推奨)</string> + <string name="help_translate">翻訳作業を手伝っていただける方は次のURLへ http://crowdin.net/project/ics-openvpn/invite</string> + <string name="prompt">%1$s は %2$s を制御しようとしています。</string> + <string name="remote_trust">私はこのアプリケーションを信頼します</string> + <string name="no_external_app_allowed">外部APIの使用を許可されたアプリはありません</string> + <string name="allowed_apps">許可アプリ: %s</string> + <string name="clearappsdialog">許可アプリの一覧をクリアしますか?\n現在の許可アプリ一覧:\n\n%s</string> + <string name="screenoff_summary">スクリーンがオフかつ60秒で64kB以下のデータ転送量の場合、VPN通信を中断します。「永続的なTUN」設定が有効な場合、VPN接続が中断されると通信ができなくなります。「永続的なTUN」を無効にすると、VPNによる接続保護は行われなくなります。</string> + <string name="screenoff_title">画面オフ後にVPN接続を中断する</string> + <string name="screen_nopersistenttun">警告: このVPN接続には永続的なTUNが設定されていません。スクリーンオフ後の通信は通常のインターネット接続を使用します。</string> + <string name="save_password">パスワードを保存</string> + <string name="pauseVPN">VPN一時停止</string> + <string name="resumevpn">VPN再開</string> + <string name="state_userpause">ユーザによってVPN一時停止が要求されました</string> + <string name="state_screenoff">VPN一時停止中 - screenオフ</string> + <string name="device_specific">デバイス固有のhacks</string> + <string name="cannotparsecert">証明書の情報が表示できません。</string> + <string name="appbehaviour">アプリケーションの挙動</string> + <string name="faq_vpndialog43_title">Android 4.3以降用VPN確認ダイアログ</string> +</resources> diff --git a/main/src/main/res/values-ko/arrays.xml b/main/src/main/res/values-ko/arrays.xml new file mode 100755 index 00000000..00ed3d64 --- /dev/null +++ b/main/src/main/res/values-ko/arrays.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string-array name="vpn_types"> + <item>인증서</item> + <item>PKCS12 파일</item> + <item>안드로이드 인증서</item> + <item>계정/암호</item> + <item>고정키</item> + <item>계정/암호 + 인증서</item> + <item>계정/암호 + PKCS12 </item> + <item>계정/암호 + 안드로이드</item> + </string-array> + <string-array name="tls_directions_entries"> + <item>0</item> + <item>1</item> + <item>미지정</item> + </string-array> + <string-array name="crm_entries"> + <item>No reconnection retries</item> + <item>One reconnection retry</item> + <item>Five reconnection retries</item> + <item>Fifty reconnection retries</item> + <item>Unlimited reconnection retries</item> + </string-array> +</resources> diff --git a/main/src/main/res/values-ko/strings.xml b/main/src/main/res/values-ko/strings.xml new file mode 100755 index 00000000..7f8036ff --- /dev/null +++ b/main/src/main/res/values-ko/strings.xml @@ -0,0 +1,307 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string name="app">안드로이드용 OpenVPN</string> + <string name="address">서버 주소:</string> + <string name="port">서버 포트:</string> + <string name="location">위치</string> + <string name="cant_read_folder">폴더를 읽을 수 없습니다</string> + <string name="select">선택</string> + <string name="cancel">취소</string> + <string name="no_data">데이터 없음</string> + <string name="useLZO">LZO 압축</string> + <string name="client_no_certificate">인증서 없음</string> + <string name="client_certificate_title">클라이언트 인증서</string> + <string name="client_key_title">클라이언트 인증서 키</string> + <string name="client_pkcs12_title">PKCS12 파일</string> + <string name="ca_title">CA 인증서</string> + <string name="no_certificate">인증서를 선택 해야 합니다</string> + <string name="copyright_guicode">소스 코드와 문제 추적기는 http://code.google.com/p/ics-openvpn/에서 사용할 수 있습니다</string> + <string name="copyright_others">프로그램은 다음 구성 요소를 사용합니다. 라이선스에 대 한 자세한 내용은 소스를 참조 하십시오</string> + <string name="about">소개</string> + <string name="vpn_list_title">프로파일</string> + <string name="vpn_type">유형</string> + <string name="pkcs12pwquery">PKCS12 암호</string> + <string name="file_select">선택…</string> + <string name="file_nothing_selected">파일을 선택 해야 합니다</string> + <string name="useTLSAuth">TLS 인증 사용</string> + <string name="tls_direction">TLS 방향</string> + <string name="ipv6_dialog_tile">CIDR 형식의 IPv6 주소/넷마스크를 입력 (예: 2000:dd::23/64)</string> + <string name="ipv4_dialog_title">CIDR 형식의 IPv4 주소/넷마스크를 입력 (예: 1.2.3.4/24)</string> + <string name="ipv4_address">IPv4 주소</string> + <string name="ipv6_address">IPv6 주소</string> + <string name="custom_option_warning">사용자 정의 OpenVPN 옵션을 입력하세요. 매우 조심하세요. 또한 많은 tun과 연관된 OpenVPN 설정은 VPN 설정의 설계로 인하여 지원 되지 않습니다. 중요한 옵션이 누락됐다고 생각되면 저자에게 연락하십시오</string> + <string name="auth_username">계정</string> + <string name="auth_pwquery">암호</string> + <string name="static_keys_info">고정설정에는 TLS인증 키가 고정키로 사용됩니다</string> + <string name="configure_the_vpn">VPN 설정</string> + <string name="menu_add_profile">프로파일 추가</string> + <string name="add_profile_name_prompt">새 프로 파일을 식별 하는 이름을 입력 하십시오</string> + <string name="duplicate_profile_name">고유 프로필 이름을 입력 하십시오</string> + <string name="profilename">프로 파일 이름</string> + <string name="no_keystore_cert_selected">사용자 인증서를 선택 해야 합니다</string> + <string name="no_error_found">오류 없음</string> + <string name="config_error_found">설정 오류</string> + <string name="ipv4_format_error">IPv4 주소 구문 분석 오류</string> + <string name="custom_route_format_error">사용자 지정 경로 구문 분석 오류</string> + <string name="pw_query_hint">(비워두면 요청시 쿼리됨)</string> + <string name="vpn_shortcut">OpenVPN 바로 가기</string> + <string name="vpn_launch_title">VPN에 연결 하기</string> + <string name="shortcut_profile_notfound">바로 가기에 지정 된 프로파일을 찾을 수 없습니다.</string> + <string name="random_host_prefix">임의의 호스트 접두사</string> + <string name="random_host_summary">6개 임의의 문자를 호스트 이름 앞에 추가</string> + <string name="custom_config_title">사용자 지정 옵션을 사용 하도록 설정</string> + <string name="custom_config_summary">사용자 지정 옵션을 입력하세요. 주의해서 사용!</string> + <string name="route_rejected">안드로이드에 의해 거부된 라우트</string> + <string name="cancel_connection">연결 끊기</string> + <string name="cancel_connection_long">VPN 연결 끊기</string> + <string name="clear_log">로그 지우기</string> + <string name="title_cancel">취소 확인</string> + <string name="cancel_connection_query">연결된 VPN 끊기/연결시도 취소?</string> + <string name="remove_vpn">VPN 제거</string> + <string name="check_remote_tlscert">서버가 TLS 서버 확장을 포함한 인증서를 사용하는지 여부 확인 (--remote-cert-tls server)</string> + <string name="check_remote_tlscert_title">TLS 서버 인증서 바람</string> + <string name="remote_tlscn_check_summary">원격 서버 인증서 대상(Subject) DN을 확인</string> + <string name="remote_tlscn_check_title">인증서 호스트명 확인</string> + <string name="enter_tlscn_dialog">원격 인증서 DN을 확인 하는데 사용하는 검사를 지정 (예: C=DE, L=Paderborn, OU=Avian IP Carriers, CN=openvpn.blinkt.de)\n\n확인을 위해 완전한 DN이나 RDN (예 openvpn.blinkt.de) 또는 RDN 접두사를 지정.\n\nRDN 접두사 \"서버\"를 사용하면 \"서버-1\" 및 \"서버 2\"와 일치합니다\n\n텍스트 필드를 빈 상태로 두면 RDN은 서버의 호스트명과 비교됩니다\n\n더 자세한 내용은 OpenVPN 2.3.1+ 맨페이지에서 —verify-x509-name 아래를 참조</string> + <string name="enter_tlscn_title">원격 인증서 제목</string> + <string name="tls_key_auth">TLS Key 인증 활성화</string> + <string name="tls_auth_file">TLS 인증 파일</string> + <string name="pull_on_summary">서버로부터 IP 주소, 라우트와 타이밍 옵션을 요구합니다.</string> + <string name="pull_off_summary">서버로부터 정보를 요구하지 않습니다. 설정은 아래에 지정되야 합니다.</string> + <string name="use_pull">설정 받기</string> + <string name="dns">DNS</string> + <string name="override_dns">서버에서 DNS 설정을 재정의합니다</string> + <string name="dns_override_summary">지정한 DNS서버 사용하기</string> + <string name="searchdomain">searchDomain</string> + <string name="dns1_summary">사용할 DNS 서버.</string> + <string name="dns_server">DNS 서버</string> + <string name="secondary_dns_message">보조 DNS 서버는 평소 DNS 서버에 접근불가시 사용됩니다.</string> + <string name="backup_dns">보조 DNS 서버</string> + <string name="ignored_pushed_routes">받은 라우트 무시하기</string> + <string name="ignore_routes_summary">서버로부터 받은 라우트를 무시합니다.</string> + <string name="default_route_summary">VPN을 통해 모든 트래픽을 보냅니다.</string> + <string name="use_default_title">기본 라우트 사용하기</string> + <string name="custom_route_message">사용자 지정 라우트를 입력하십시오. 목적지는 CIDR 형식으로만 입력하십시오. \"10.0.0.0/8 2002::/16\"은 10.0.0.0/8 과 2002::/16 네트워크를 VPN으로 보냅니다.</string> + <string name="custom_routes_title">사용자 지정 라우트</string> + <string name="log_verbosity_level">로그의 자세한 정도</string> + <string name="float_summary">인증된 패킷은 IP와 상관없이 허용</string> + <string name="float_title">플로팅 서버 허용</string> + <string name="custom_options_title">사용자 지정 옵션</string> + <string name="edit_vpn">VPN 설정 편집</string> + <string name="remove_vpn_query">VPN 프로 파일 \'%s\' 제거?</string> + <string name="tun_error_helpful">일부 사용자 지정 ICS 이미지에서는 /dev/tun에 대한 권한이 잘못 되어 있거나 tun 모듈 자체가 누락 될 수 있습니다. CM9 이미지는 일반 설정에 있는 소유권 고치기 옵션을 사용해 보십시오.</string> + <string name="tun_open_error">Tun 인터페이스를 열지 못했습니다</string> + <string name="error">"오류:"</string> + <string name="clear">지우기</string> + <string name="last_openvpn_tun_config">TUN 인터페이스 열기:</string> + <string name="local_ip_info">로컬 IPv4: %1$s/%2$d IPv6: %3$s MTU: %4$d</string> + <string name="dns_server_info">DNS 서버: %1$s, 도메인: %2$s</string> + <string name="ip_not_cidr">인터페이스 정보 %1$s와 %2$s에 있어, 두 번째 주소를 원격 피어 주소로 가정 하겠습니다. 로컬 IP의 넷마스크로는 /32를 사용하겠습니다. OpenVPN에 의해 주어진 모드는 \"%3$s\" 입니다.</string> + <string name="route_not_cidr">CIDR 넷마스크가 있는 IP 라우트 %1$s 와 %2$s 에 있어서 처리가 불가능합니다. /32를 넷마스크로 사용하겠습니다.</string> + <string name="route_not_netip">%1$s/%2$s 에서 %3$s/%2$s로 라우트 수정</string> + <string name="keychain_access">안드로이드 키체인 인증서에 접근할 수 없습니다. 펌웨어 업그래이드 또는 백업된 앱/앱 설정을 복구하면서 발생할 수 있습니다. 인증서에 액세스할 수 있는 권한을 다시 생성하기 위해 VPN을 편집 하고 기본 설정 아래에서 인증서를 다시 선택 하십시오.</string> + <string name="version_info">%1$s %2$s</string> + <string name="send_logfile">로그 파일 보내기</string> + <string name="send">보내기</string> + <string name="ics_openvpn_log_file">ICS OpenVPN 로그 파일</string> + <string name="copied_entry">클립보드로 로그 복사</string> + <string name="tap_mode">Tap 모드</string> + <string name="faq_tap_mode">Tap 모드는 루트가 아닌 VPN API에서는 불가능합니다. 따라서 본앱은 tap지원을 제공할 수 없습니다</string> + <string name="tap_faq2">또? 농담인가요? 아니요 정말로 tap 모드는 지원이 불가능합니다. 계속해서 메일을 보내면서 요구하신다고 도움될 일이 아닙니다.</string> + <string name="tap_faq3">3번째로? 누군가가 송신때 레이어2 정보를 추가하고 수신때 레이어2정보를 때내는 tun을 이용한 tap 에뮬레이터를 제작할 수 있습니다. 하지만 이것만이 아닌 ARP 그리고 어쩌면 DHCP 클라이언트 까지도 구현해야합니다. 본인은 이 같은 작업을 하는 분을 알고있지 않습니다. 코딩을 시작하려고 하시는 분이 계시면 제게 연락주십시오.</string> + <string name="faq">자주 묻는 질문</string> + <string name="copying_log_entries">로그 항목을 복사</string> + <string name="faq_copying">단일 로그 항목을 복사 하려면 로그 항목을 누르고 계세요. 전체 로그를 복사/전송 하려면 로그 보내기 옵션을 사용하십시오. GUI에 표시 되지 않는 경우 하드웨어 메뉴 버튼를 사용하세요.</string> + <string name="faq_shortcut">시작으로 바로 가기</string> + <string name="faq_howto_shortcut">바탕 화면에 OpenVPN 시작 바로 가기를 배치할 수 있습니다. 당신의 homescreen 프로그램에 따라 바로 가기 또는 위젯 추가를 해야 합니다.</string> + <string name="no_vpn_support_image">당신의 이미지는 VPNService API를 지원 하지 않습니다, 죄송 합니다:(</string> + <string name="encryption">암호화</string> + <string name="cipher_dialog_title">입력 암호화 방법</string> + <string name="chipher_dialog_message">OpenVPN이 사용할 암호화 암호 알고리즘을 입력 합니다. 기본 암호를 사용하려면 빈 공간으로 두십시오.</string> + <string name="auth_dialog_message">OpenVPN이 사용할 인증 다이제스트를 입력 합니다. 기본 다이제스트를 사용하려면 빈 공간으로 두십시오.</string> + <string name="settings_auth">인증/암호화</string> + <string name="file_explorer_tab">파일 탐색기</string> + <string name="inline_file_tab">인라인 파일</string> + <string name="error_importing_file">파일 가져오기 오류</string> + <string name="import_error_message">파일 시스템에서 파일을 가져올 수 없습니다.</string> + <string name="inline_file_data">[[인라인 파일 데이터]]</string> + <string name="opentun_no_ipaddr">IP 정보가 없는 tun 장치 열기를 거부합니다</string> + <string name="menu_import">Ovpn 파일에서 프로파일 가져오기</string> + <string name="menu_import_short">가져오기</string> + <string name="import_content_resolve_error">가져올 프로 파일을 읽을 수 없습니다.</string> + <string name="error_reading_config_file">설정 파일 읽기 오류</string> + <string name="add_profile">프로파일 추가</string> + <string name="import_could_not_open">가져온된 설정 파일에 언급 된 파일 %1$s를 찾을 수 없습니다.</string> + <string name="importing_config">원본 %1$s에서 설정 파일 가져오기</string> + <string name="import_warning_custom_options">구성은 UI 구성으로 매핑되지 않는 몇 가지 구성 옵션을 가지고 있습니다. 이 옵션은 사용자 정의 구성 옵션으로 추가되었습니다. 사용자 정의 구성은 아래에 표시됩니다 :</string> + <string name="import_done">설정 파일 읽기 완료.</string> + <string name="nobind_summary">로컬 주소와 포트로 바인드 안하기</string> + <string name="no_bind">로컬 바인딩 안함</string> + <string name="import_configuration_file">구성 파일 가져오기</string> + <string name="faq_security_title">보안 고려 사항</string> + <string name="faq_security">"OpenVPN은 보안에 민감하기 때문에 보안에 관련된 부분을 알고가는것이 현명합니다. SD카드의 있는 데이터는 기본적으로 보안이 취약합니다. 모든 앱이 읽을 수 있기 때문입니다 (예로 이 프로그램 또한 SD카드의 읽기 권한이 필요없습니다). 본앱의 데이터는 본앱만이 읽을 수 있습니다. cacert/cert/key를 파일 탐색기의 가져오기 옵션을 사용하면 데이터는 VPN 프로파일 내에 저장됩니다. VPN 프로파일은 본앱만이 접근할 수 있습니다. (잊지말고 SD카드에 있는 것을 삭제하세요). 접근은 본앱만이 가능하더라도 데이터는 암호화가 되어있지 않습니다. 루팅을 비롯한 다른 방법을 악용하여 데이터를 빼낼 수 있습니다. 암호 또한 일반 텍스트로 저장되어 있습니다. pkcs12 파일은 안드로이드 keystore에 보관할것을 강력하게 추천합니다."</string> + <string name="import_vpn">가져오기</string> + <string name="broken_image_cert_title">인증서 선택 표시 오류</string> + <string name="broken_image_cert">안드로이드 4.0+의 인증서 선택창을 보여주려는 과정에서 예외가 발생됐습니다. 안드로이드 4.0+의 표준 기능임으로 이 같은 일은 일어나면 안됩니다. 어쩌면 인증서 저장소에 대한 귀하의 안드로이드 ROM 지원이 깨졌습니다.</string> + <string name="ipv4">IPv4</string> + <string name="ipv6">IPv6</string> + <string name="speed_waiting">상태 메시지를 기다리는 중…</string> + <string name="converted_profile">가져온 프로파일</string> + <string name="converted_profile_i">가져온 프로파일 %d</string> + <string name="broken_images">깨진 이미지</string> + <string name="broken_images_faq"><p>공식 HTC 이미지에서는 이상한 라우팅 문제로 트래픽이 터널로 통과 하지 않는 경우가 있는것으로 알려져 있습니다 (참고 <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=18\">Issue 18</a> 버그 추적기.)</p><p>Xperia arc S 와 Xperia Ray의 공식 SONY 이미지에서는 VPNService 자체가 완전히 없어진 것으로 보고 되었습니다. (참조 <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=29\">Issue 29</a> 버그추적기.)</p><p>일부 사용자를 위해 만들어진 이미지에서는 tun 모듈자체가 없거나 /dev/tun의 권한이 틀려있기도 합니다. 일부 CM9 이미지는 \"Device specific hacks\" 아래에 있는 \"Fix ownership\" 옵션을 사용해야 합니다.</p><p>가장 중요한 부분: 만약 깨진 이미지를 사용하는 경우라면 해당 공급업체에 보고해야 합니다. 업체에 문제를 보고하는 사람들이 많아야 수정될 가능성도 높아집니다..</p></string> + <string name="pkcs12_file_encryption_key">PKCS12 파일 암호화 키</string> + <string name="private_key_password">개인 키 암호</string> + <string name="password">암호</string> + <string name="file_icon">파일 아이콘</string> + <string name="tls_authentication">TLS 인증</string> + <string name="generated_config">생성 된 설정</string> + <string name="generalsettings">설정</string> + <string name="owner_fix_summary">/dev/tun의 소유권을 시스템으로 설정 하려고 합니다. 일부 CM9 이미지에서 VPNService API를 사용하기 위해서는 앞의 작업이 요구됩니다. root권한을 가져야합니다.</string> + <string name="owner_fix">/dev/tun 소유권 문제 해결</string> + <string name="generated_config_summary">생성된 OpenVPN의 설정 파일 보기</string> + <string name="edit_profile_title">수정 \"%s\"</string> + <string name="building_configration">설정 만드는중…</string> + <string name="netchange_summary">이 기능을 사용하면 네트워크 상태 변환시 강제로 재접속을 합니다 (예. WIFI 로/에서 모바일)</string> + <string name="netchange">네트워크 변화시 재접속</string> + <string name="netstatus">네트워크 상태: %s</string> + <string name="extracahint">CA 인증서는 일반적으로 안드로이드 Keystore에 있는것을 사용합니다. 인증서 오류 발생시 벌도의 인증서를 지정하세요.</string> + <string name="select_file">선택</string> + <string name="keychain_nocacert">안드로이드 keystore에서 CA 인증서를 찾지 못했습니다. Auhtentication은 실패할 것 입니다.</string> + <string name="show_log_summary">연결시 로그 윈도우를 보여드립니다. 로그 윈도우는 항상 notification status에서 접근이 가능합니다.</string> + <string name="show_log_window">로그 윈도우 보기</string> + <string name="mobile_info">%1$s (%2$s) %3$s, 안드로이드 API %4$d 에서 실행</string> + <string name="error_rsa_sign">안드로이드 keystore 키 %1$s: %2$s과 싸이닝 오류</string> + <string name="faq_system_dialogs">시스템에서는 VPN연결 경고를 통해 당신에게 본앱이 모든 트래픽을 가로챌수있다는 점을 알리게 되어 있는데 이는 VPNService API가 남용하는것을 막기 위함입니다.\nVPN 연결 알림 (키 아이콘) 또한 안드로이드 시스템에서 부과하는 부분이며 이는 VPN연결을 알리는 신호입니다. 어떤 버전에서는 소리를 알림으로 사용하는 경우도 있습니다.\n안드로이드는 이같은 방법을 당신의 안전을 위해 도입하였으며 사용은 필수적입니다. (어떤 버전에서는 유감스럽게도 소리 알림 또한 포함됩니다.)</string> + <string name="faq_system_dialogs_title">연결 경고 및 알림 소리</string> + <string name="translationby">한국어 번역 (주)기가드 안규태<ktdann@gmail.com></string> + <string name="ipdns">IP 와 DNS</string> + <string name="basic">기본</string> + <string name="routing">라우팅</string> + <string name="obscure">모호한 OpenVPN 설정. 일반적으로 필요하지 않습니다.</string> + <string name="advanced">고급</string> + <string name="export_config_title">ICS Openvpn 설정</string> + <string name="warn_no_dns">DNS 서버가 미사용중입니다. 이름 변환이 작동 않을 수 있습니다. 사용자 지정 DNS 서버를 설정 하십시오. 또한 안드로이드는 DNS서버가 없는 경우 모바일/Wi-Fi 연결에 저정된 프록시 설정을 계속해서 사용한다는 점을 유의하시기 바랍니다.</string> + <string name="dns_add_error">DNS서버 \"%1$s\" 는, 시스템에 의해 거부되 추가할 수 없습니다: %2$s</string> + <string name="ip_add_error">%2$s: 시스템에 의해 거부되어 IP 주소 \"%1$s\"를 설정하지 못하였습니다</string> + <string name="faq_howto"><p>문제없는 설정을 확보하세요 (당신의 컴퓨터에서 테스트 된것 또는 공급자/조직에서 다운받은)</p><p>이것이 단일 파일이며 추가 pem/pks12 파일이 없는 경우면 본인에게 이메일로 보내어 첨부파일을 열면 됩니다. 여러 파일인 경우 당신의 sd card에 넣으세요.</p><p>이메일 첨부파일을 클릭하세요/vpn목록에 있는 폴더 아이콘을 사용하여 설정 파일을 가져옵니다.</p><p>파일 누락 오류 발생시 누락된 파일을 sd card에 복사하세요.</p><p>저장 기호를 클릭하여 VPN 목록에 가져온 VPN을 추가 하세요.</p><p>VPN 이름을 클릭하여 VPN을 연결하세요.</p><p>오류 또는 경고가 로그에 있는 경우 오류/경고를 이해하여 이들을 해결하십시오.</p> </string> + <string name="faq_howto_title">빠른 시작</string> + <string name="setting_loadtun_summary">연결을 시도 하기 전에 tun.ko 커널 모듈을 로드하세요. 루팅된 장치야만 합니다.</string> + <string name="setting_loadtun">tun 모듈 로드하기</string> + <string name="importpkcs12fromconfig">설정에 있는 PKCS12를 안드로이드 keystore로 가져오기</string> + <string name="getproxy_error">프록시 설정 가져오기 오류: %s</string> + <string name="using_proxy">프록시 %1$s %2$d 을 사용</string> + <string name="use_system_proxy">시스템 프록시를 사용</string> + <string name="use_system_proxy_summary">연결시 전 시스템 설정에 있는 HTTP/HTTPS 프록시를 사용합니다.</string> + <string name="donatewithpaypal">당신은 <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;cmd=_s-xclick\">PayPal을 사용하여 기부할 수 있습니다.</a> </string> + <string name="onbootrestartsummary">OpenVPN은 시스템 재부팅/종료에 활성화 되었으면 VPN을 다시 연결합니다. 이 옵션을 사용 하기 전에 연결 경고 FAQ를 읽어 보시기 바랍니다.</string> + <string name="onbootrestart">재부팅시 다시 연결</string> + <string name="ignore">무시</string> + <string name="restart">다시 시작</string> + <string name="restart_vpn_after_change">VPN을 다시 시작한 후 설정 변경 내용이 적용 됩니다. VPN을 지금 (재)시작?</string> + <string name="configuration_changed">설정 변경</string> + <string name="log_no_last_vpn">편집을 위해 마지막으로 연결 된 프로파일을 확인할 수 없습니다.</string> + <string name="faq_duplicate_notification_title">중복 알림</string> + <string name="faq_duplicate_notification">안드로이드는 시스템의 메모리 (RAM) 가 부족한 경우, 현재 필요하지 않는 앱들과 서비스들을 활성화 메모리에서 삭제합니다. 이 과정에서 진행중인 VPN 연결이 끊어 집니다. 이렇게 되지 않기 위해서 OpenVPN 서비스는 우선순위가 높게 되어 실행됩니다. 높은 우선 순위로 실행되기 위해서는 응용프로그램에서 이를 알림으로 표시해야 합니다. 키 알림 아이콘은 이전 FAQ에서 설명된 대로 시스템에서 강요하기 때문입니다. 이것은 우선 순위가 높이 실행된다는 알림에 대한 알림이 아닙니다.</string> + <string name="no_vpn_profiles_defined">VPN 프로파일이 정의 않됐습니다.</string> + <string name="add_new_vpn_hint">이 <img src=\"ic_menu_add\"/> 아이콘을 사용하여 VPN을 추가 하세요</string> + <string name="vpn_import_hint">이 <img src=\"ic_menu_archive\"/> 아이콘을 사용하여 귀하의 sdcard에서 기존 (.ovpn 또는 .conf) 프로파일을 가져오세요.</string> + <string name="faq_hint">꼭 FAQ를 확인 하세요. 빠른 시작 가이드가 있습니다.</string> + <string name="faq_routing_title">라우팅/인터페이스 설정</string> + <string name="faq_routing">라우팅과 인터페이스 구성은 ifconfig/route 명령어를 사용하지 않고 VPNService API를 사용합니다. 그 결과 다른 OS들과는 다른 라우팅 구성을 합니다. 구성에는 터널 인터페이스 IP와 그 인터페이스를 통해 전달 해야 하는 네트워크로만 이루어 집니다. 특히 피어 파트너 주소 또는 게이트웨이 주소가 요구되지 않습니다. VPN 서버를 위한 특별한 경로(예를 들어 redirect-gateway를 사용할때 추가되는 것)도 필요하지 않습니다. 프로그램에서는 구성을 가져올 때 이렇나 설정을 무시합니다. 앱은 VPNService API와 함께 서버와의 연결을 VPN 터널을 통해 라우팅 되지 않도록 합니다. 터널을 통해 라우팅되는 네트워크만 지정이 가능함으로 터널을 향하지 않는 추가 라우트는 지원하지 않습니다. (예: route x.x.x.x y.y.y.y net_gateway). 로그 창에는 연결 시 VPNService의 현재 구성을 보여 줍니다.</string> + <string name="persisttun_summary">OpenVPN을 다시 연결 하는 경우 VPN 연결 없음으로 표기하지 마십시오.</string> + <string name="persistent_tun_title">tun 유지</string> + <string name="openvpn_log">OpenVPN 로그</string> + <string name="import_config">OpenVPN 설정 가져오기</string> + <string name="battery_consumption_title">배터리 소모</string> + <string name="baterry_consumption">제 개인적인 테스트에서 Openvpn의 높은 배터리 소비에 대한 주요 이유는 keepalive 패킷 때문이었습니다. 대부분의 OpenVPN 서버 설정에는 \'keepalive 10 60\' 와 같은 문구가 있는데 이는 클라이언트에서 서버로 서버에서 클라이언트로 keepalive 패킷을 10 초 마다 보냅니다. <p> 이러한 패킷은 작고 많은 트래픽을 사용 하지 않습니다만 이들은 모바일 라디오 네트워크를 계속 유지하게 만들게되고 따라서 에너지 소비를 증가 합니다. (참조 <a href=\"http://developer.android.com/training/efficient-downloads/efficient-network-access.html#RadioStateMachine\">The Radio State Machine | Android Developers</a>) <p> 이 keepalive 설정을 클라이언트에서 변경할 수 없습니다. OpenVPN의 시스템 관리자만 설정을 변경할 수 있습니다. <p> 불행히도 udp를 사용할때 keepalive값을 60초 이상으로 하면 일부의 NAT 게이트웨이에서는 비활성 타임아웃 때문에 연결을 끊어버리게 됩니다. TCP와 긴 keepalive 만료기간을 함께 사용할 수는 있지만 패킷 손실이 높은 연결구간에서는 TCP over TCP의 성능이 매우 저조합니다. (참조 <a href=\"http://sites.inka.de/bigred/devel/tcp-tcp.html\">왜 TCP를 통한 TCP는 안좋은 방법인지</a>)</string> + <string name="faq_tethering">안드로이드 테더링 기능 (WiFi, USB 또는 블루투스를 통한)과 VPNService API (이 프로그램에서 사용됨)는 함께 작동 하지 않습니다. 자세한 내용은 <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=34\">issue #34</a> 를 참조 하십시오</string> + <string name="vpn_tethering_title">VPN과 테더링</string> + <string name="connection_retries">다시 연결</string> + <string name="reconnection_settings">다시 연결 설정</string> + <string name="connectretrymessage">연결 시도 사이의 기다리는 초단위 주기 입니다.</string> + <string name="connectretrywait">연결과 연결 사이의 초단위 기간</string> + <string name="minidump_generated">OpenVPN이 예기치 않게 종료됐습니다. 메인 메뉴에 있는 미니 덤프 보내기 옵션의 사용을 고려 하시기 바랍니다</string> + <string name="send_minidump">미니 덤프를 개발자에게 보내기</string> + <string name="send_minidump_summary">개발자에게 마지막 비정상종료에 대한 디버깅 정보를 보냅니다</string> + <string name="notifcation_title">OpenVPN - %s</string> + <string name="session_ipv4string">%1$s - %2$s</string> + <string name="session_ipv6string">%1$s - %3$s, %2$s</string> + <string name="state_connecting">연결중</string> + <string name="state_wait">서버 응답 대기중</string> + <string name="state_auth">인증중</string> + <string name="state_get_config">클라이언트 구성 가져오는중</string> + <string name="state_assign_ip">IP 주소 할당중</string> + <string name="state_add_routes">노선 추가중</string> + <string name="state_connected">연결됨</string> + <string name="state_disconnected">연결 끊기</string> + <string name="state_reconnecting">재연결중</string> + <string name="state_exiting">종료중</string> + <string name="state_noprocess">실행안됨</string> + <string name="state_resolve">호스트명 찾는중</string> + <string name="state_tcp_connect">연결중 (TCP)</string> + <string name="state_auth_failed">인증 실패</string> + <string name="state_nonetwork">사용 가능한 네트워크 대기중</string> + <string name="statusline_bytecount">↓%2$s/s %1$s - ↑%4$s/s %3$s</string> + <string name="notifcation_title_notconnect">연결 되지 않음</string> + <string name="start_vpn_title">VPN %s 연결중</string> + <string name="start_vpn_ticker">VPN %s 연결중</string> + <string name="jelly_keystore_alphanumeric_bug">일부 버전의 안드로이드 4.1에서는 키 인증서의 이름에 비 영숫자 문자(공백, 밑줄 또는 대시)가 포함 된 경우 문제가 있습니다. 특수 문자 없는 인증서를 다시 가져와 시도해보세요</string> + <string name="encryption_cipher">암호화 암호</string> + <string name="packet_auth">패킷 인증</string> + <string name="auth_dialog_title">패킷 인증 방법을 입력한다</string> + <string name="mobile_info_extended">%1$s (%2$s) %3$s, 안드로이드 API %4$d, 버전 %5$s, %6$s에서 실행</string> + <string name="built_by">개발자 %s</string> + <string name="debug_build">디버그 빌드</string> + <string name="official_build">공식 빌드</string> + <string name="make_selection_inline">프로파일에 복사</string> + <string name="crashdump">크래시 덤프</string> + <string name="add">추가</string> + <string name="send_config">설정 파일 보내기</string> + <string name="complete_dn">완전한 DN</string> + <string name="remotetlsnote">가져온 구성에는 다른 DN 형식을 사용하는 오래된 tls-remote옵션이 있는데 이는 더이상 지원되지 않습니다.</string> + <string name="rdn">RDN (common 이름)</string> + <string name="rdn_prefix">RDN 접두사</string> + <string name="tls_remote_deprecated">tls-remote (지원 되지 않음)</string> + <string name="help_translate">http://crowdin.net/project/ics-openvpn/invite를 방문 하여 번역을 도울 수 있습니다</string> + <string name="prompt">%1$s 이(가) %2$s 을(를) 제어하려고 시도</string> + <string name="remote_warning">다음 진행으로, 당신은 OpenVPN for Android 응용프로그램에게 완벽한 제어권과 모든 네트워크 트래픽을 가로챌 수 있는 권한을 허락합니다. <b>앱을 신뢰하지 않는다면 허락하지 마십시오.</b> 그렇지 않으면, 당신은 당신의 데이터를 악성 소프트웨어에게 빼앗길 수 있습니다.\"</string> + <string name="remote_trust">나는 이 프로그램을 신뢰합니다.</string> + <string name="no_external_app_allowed">어떤 응용 프로그램도 외부 API를 사용할 수 없습니다</string> + <string name="allowed_apps">허용된 앱: %s</string> + <string name="clearappsdialog">허용된 외부 앱의 목록을 삭제하겠습니까?\n현재 허용된 외부 앱:\n\n%s</string> + <string name="screenoff_summary">\"화면이 꺼져있을때 60초동안 64kB 미만의 데이터가 전송되면 VPN 일시정지. \"Persistent Tun\" 옵션이 활성화되어 있으면 VPN 일시 정지시 당신의 장비는 네트워크가 끊어 집니다. \"Persistent Tun\" 옵션이 없는 경우 장비는 VPN 연결/보호를 잃습니다. </string> + <string name="screenoff_title">화면 꺼짐 후 VPN 연결 일시 정지</string> + <string name="screenoff_pause">화면이 꺼진 상태에서 일시 중지: %2$ss에서 %1$s 미만</string> + <string name="screen_nopersistenttun">경고: 이 VPN은 persistent tun이 비활성화 되어있습니다. 화면이 꺼졌을 때 트래픽은 터널을 사용하지 않고 인터넷을 바로 사용합니다.</string> + <string name="save_password">암호 저장</string> + <string name="pauseVPN">VPN 일시중지</string> + <string name="state_userpause">VPN 일시 정지 사용자의 요청</string> + <string name="state_screenoff">VPN 일시정지됨 - 화면 끄기</string> + <string name="device_specific">장치 관련 Hacks</string> + <string name="cannotparsecert">인증서 정보를 표시 할 수 없습니다</string> + <string name="appbehaviour">응용 프로그램 동작</string> + <string name="vpnbehaviour">VPN 동작</string> + <string name="allow_vpn_changes">VPN 프로필에 대한 변경을 허용</string> + <string name="hwkeychain">하드웨어 키 스토어:</string> + <string name="permission_icon_app">응용 프로그램의 아이콘이 OpenVPN for Android를 사용 하려고함</string> + <string name="faq_vpndialog43">"안드로이드 4.3부터는 VPN 확인이 \"overlaying apps\"로 부터 보호 받게 됩니다. 따라서 입력창이 터치 입력에 반응하지 않을 수 있습니다. 사용하는 앱중에서 overlay를 사용하는 경우 이러한 문제가 발생될수있습니다. 문제의 앱을 제작한 프로그램어를 연락하십시오. 이 문제는 안드로이드 4.3과 이상의 버전에서 모든 VPN 응용 프로그램에 영향을 줍니다. <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=185\">Issue 185<a> 참조"</string> + <string name="faq_vpndialog43_title">안드로이드 4.3과 이후 버전에서의 VPN 확인 창</string> + <string name="donatePlayStore">또는 당신은 플레이 스토어와 나에게 기부금을 보낼 수 있습니다:</string> + <string name="thanks_for_donation">%s 님! 기부 감사합니다</string> + <string name="logCleared">로그가 삭제되었습니다.</string> + <string name="show_password">비밀 번호 표시</string> + <string name="keyChainAccessError">키체인 접근 오류: %s</string> + <string name="timestamp_short">짧은</string> + <string name="timestamp_iso">ISO</string> + <string name="timestamps">타임 스탬프</string> + <string name="timestamps_none">없음</string> + <string name="uploaded_data">업로드</string> + <string name="downloaded_data">다운로드</string> + <string name="vpn_status">Vpn 상태</string> + <string name="logview_options">옵션 보기</string> + <string name="unhandled_exception">처리 되지 않은 예외: %1$s\n\n%2$s</string> + <string name="unhandled_exception_context">%3$s: %1$s\n\n%2$s</string> + <string name="full_licenses">전체 라이센스</string> +</resources> diff --git a/main/src/main/res/values-nl/arrays.xml b/main/src/main/res/values-nl/arrays.xml new file mode 100755 index 00000000..06074301 --- /dev/null +++ b/main/src/main/res/values-nl/arrays.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string-array name="vpn_types"> + <item>Certificaten</item> + <item>PKCS12 Bestand</item> + <item>Android Certificaat</item> + <item>Gebruikersnaam/Wachtwoord</item> + <item>Statische Sleutels</item> + <item>Gebruiker/WW + Certificaten</item> + <item>Gebruiker/WW + PKCS12 </item> + <item>Gebruiker/WW + Android</item> + </string-array> + <string-array name="tls_directions_entries"> + <item>0</item> + <item>1</item> + <item>Niet-gespecificeerd</item> + </string-array> + <string-array name="crm_entries"> + <item>No reconnection retries</item> + <item>One reconnection retry</item> + <item>Five reconnection retries</item> + <item>Fifty reconnection retries</item> + <item>Unlimited reconnection retries</item> + </string-array> +</resources> diff --git a/main/src/main/res/values-nl/strings.xml b/main/src/main/res/values-nl/strings.xml new file mode 100755 index 00000000..3d3c4279 --- /dev/null +++ b/main/src/main/res/values-nl/strings.xml @@ -0,0 +1,124 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string name="app">OpenVPN voor Android</string> + <string name="address">Server Adres:</string> + <string name="port">Server Poort:</string> + <string name="location">Locatie</string> + <string name="cant_read_folder">Map is onleesbaar</string> + <string name="select">Selecteer</string> + <string name="cancel">Annuleer</string> + <string name="no_data">Geen Gegevens</string> + <string name="useLZO">LZO Compressie</string> + <string name="client_no_certificate">Geen Certificaat</string> + <string name="client_certificate_title">Client Certificaat</string> + <string name="client_key_title">Client Certificaat Sleutel</string> + <string name="client_pkcs12_title">PKCS12 Bestand</string> + <string name="ca_title">CA Certificaat</string> + <string name="no_certificate">Je moet een certificaat selecteren</string> + <string name="copyright_guicode">De broncode en bugs zijn te vinden op http://code.google.com/p/ics-openvpn/</string> + <string name="copyright_others">Het programma gebruikt de volgende componenten. Zie de broncode voor volledige details over de licenties.</string> + <string name="about">Over</string> + <string name="vpn_list_title">Profielen</string> + <string name="vpn_type">Type</string> + <string name="pkcs12pwquery">PKCS12 Wachtwoord</string> + <string name="file_select">Selecteer…</string> + <string name="file_nothing_selected">Je moet een bestand selecteren</string> + <string name="useTLSAuth">Gebruik TLS autentificatie</string> + <string name="tls_direction">TLS Richting</string> + <string name="ipv6_dialog_tile">Voer een IPv6 Adres/Netmask in met het CIDR Formaat (v.b. 2000:dd::23/64)</string> + <string name="ipv4_dialog_title">Voer een IPv4 Adres/Netmask in met het CIDR Formaat (v.b. 1.2.3.4/24)</string> + <string name="ipv4_address">IPv4 Adres</string> + <string name="ipv6_address">IPv4 Adres</string> + <string name="custom_option_warning">Geavanceerde OpenVPN opties. Veel van de tun gerelateerde OpenVPN instellingen worden niet ondersteund. Als u denkt dat een belangrijke optie ontbreekt, neem dan contact op met de auteur.</string> + <string name="auth_username">Gebruikersnaam</string> + <string name="auth_pwquery">wachtwoord</string> + <string name="static_keys_info">Voor de statische configuratie worden de TLS Auth keys als statische sleutels gebruikt</string> + <string name="configure_the_vpn">VPN configureren</string> + <string name="menu_add_profile">Profiel toevoegen</string> + <string name="add_profile_name_prompt">Voer een naam in voor het nieuwe Profiel</string> + <string name="duplicate_profile_name">Profielnaam is al in gebruik</string> + <string name="profilename">Profiel name</string> + <string name="no_keystore_cert_selected">Geen gebruikerscertificaat geselecteerd</string> + <string name="no_error_found">Geen fout.</string> + <string name="config_error_found">Fout in de configuratie</string> + <string name="ipv4_format_error">Fout bij inlezen van IPv4-adres</string> + <string name="custom_route_format_error">Fout bij inlezen van aangepaste routes</string> + <string name="pw_query_hint">(vrij laten voor query op aanvraag)</string> + <string name="vpn_shortcut">Open VPN shortcut</string> + <string name="vpn_launch_title">Met VPN verbinden</string> + <string name="shortcut_profile_notfound">Het profiel zoals aangegeven in de snelkoppeling kon niet gevonden worden.</string> + <string name="random_host_prefix">Willekeurig Host Voorvoegsel</string> + <string name="random_host_summary">Voegt 6 willekeurige tekens toe voor de hostname</string> + <string name="custom_config_title">Eigen configuratie opties</string> + <string name="custom_config_summary">Geef je eigen configuratieopties aan. Wees voorzichtig!</string> + <string name="route_rejected">Route geweigert door Android</string> + <string name="cancel_connection">Verbinding verbreken</string> + <string name="cancel_connection_long">VPN verbinding verbreken</string> + <string name="clear_log">logboek wissen</string> + <string name="title_cancel">Annuleer bevestiging</string> + <string name="cancel_connection_query">Sluit de verbonden VPN af/annuleer de verbindingspoging?</string> + <string name="remove_vpn">VPN wissen</string> + <string name="check_remote_tlscert">Controleert of de server een certificaat met TLS Server extensions gebruikt (--remote-cert-tls server)</string> + <string name="check_remote_tlscert_title">Verwacht TLS server-certificaat</string> + <string name="remote_tlscn_check_summary">Controleert de externe server certificaathouder</string> + <string name="remote_tlscn_check_title">Controleer Certificaat Hostname</string> + <string name="enter_tlscn_title">Externe certificaathouder</string> + <string name="tls_key_auth">Activeert TLS Key verificatie</string> + <string name="tls_auth_file">TLS Auth Bestand</string> + <string name="pull_on_summary">Vraag IP adres, routes en timing opties van de server.</string> + <string name="pull_off_summary">De server vraagt geen informatie op. Instellingen moeten onderaan worden gespecificeerd.</string> + <string name="use_pull">Pull Instellingen</string> + <string name="dns">DNS</string> + <string name="override_dns">DNS Instellingen van Server Overschrijven</string> + <string name="dns_override_summary">Gebruik eigen DNS Servers</string> + <string name="searchdomain">Zoekd domein</string> + <string name="dns1_summary">Primaire DNS server</string> + <string name="dns_server">DNS Server</string> + <string name="secondary_dns_message">Secundaire DNS server. Deze wordt gebruikt voor het geval dat de primaire DNS server niet bereikbaar is</string> + <string name="backup_dns">Backup DNS server</string> + <string name="ignored_pushed_routes">Negeer ontvangen routes</string> + <string name="ignore_routes_summary">Negeer routes ontvangen van de server.</string> + <string name="default_route_summary">Leid al het Verkeer over de VPN</string> + <string name="use_default_title">Gebruik standaard Route</string> + <string name="custom_routes_title">Eigen routes</string> + <string name="float_summary">Geverifieerde pakketen zijn vanuit elk IP toegestaan</string> + <string name="float_title">Zwevende server toestaan</string> + <string name="custom_options_title">Aangepaste Opties</string> + <string name="edit_vpn">VPN Instellingen Bewerken</string> + <string name="remove_vpn_query">De VPN-profiel \'%s\' verwijderen?</string> + <string name="error">"Fout:"</string> + <string name="clear">Leeg maken</string> + <string name="local_ip_info">Lokaal IPv4: %1$s/%2$d IPv6: %3$s MTU: %4$d</string> + <string name="version_info">%1$s %2$s</string> + <string name="send_logfile">Logboek verzenden</string> + <string name="send">Verzenden</string> + <string name="tap_mode">Tap mode</string> + <string name="faq_tap_mode">De VPN API van Android werkt zonder rooten van de telefoon en ondersteunt alleen de tun modus. Daarom is de tap modus niet mogelijk met deze app.</string> + <string name="faq">Veelgestelde vragen </string> + <string name="encryption">Codering</string> + <string name="cipher_dialog_title">Codering methode</string> + <string name="menu_import_short">Import</string> + <string name="add_profile">Profiel toevoegen</string> + <string name="import_could_not_open">Kon het bestand %1$s, zoals aangegeven in de geïmporteerde configuratie niet vinden</string> + <string name="importing_config">Geïmporteerde configuratie bestand uit %1$s</string> + <string name="import_done">Lezen van configuratie bestand afgesloten.</string> + <string name="no_bind">Geen locale binding</string> + <string name="import_configuration_file">configuratie bestand importeren</string> + <string name="faq_security_title">Beveiligingsoverwegingen</string> + <string name="import_vpn">Importeren</string> + <string name="broken_image_cert_title">Fout bij het weergeven van de certificaat selectie</string> + <string name="ipv4">IPv4</string> + <string name="ipv6">IPv6</string> + <string name="speed_waiting">Wachten op status bericht…</string> + <string name="converted_profile">Geïmporteerd profiel</string> + <string name="converted_profile_i">Geïmporteerd profiel %d</string> + <string name="broken_images">Niet Werkende Afbeeldingen</string> + <string name="pkcs12_file_encryption_key">PKCS12 Bestand Encryptie Sleutel</string> + <string name="private_key_password">Privé Sleutel Wachtwoord</string> + <string name="password">Wachtwoord</string> + <string name="file_icon">bestands pictogram</string> + <string name="tls_authentication">TLS Verificatie</string> + <string name="generated_config">Gegenereerde Configuratie</string> + <string name="ipdns">IP en DNS</string> +</resources> diff --git a/main/src/main/res/values-no/arrays.xml b/main/src/main/res/values-no/arrays.xml new file mode 100755 index 00000000..317abbc8 --- /dev/null +++ b/main/src/main/res/values-no/arrays.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string-array name="vpn_types"> + <item>Sertifikater</item> + <item>PKCS12 fil</item> + <item>Android sertifikat</item> + <item>Brukernavn/passord</item> + <item>Statiske nøkler</item> + <item>Brukernavn/Passord + sertifikater</item> + <item>Brukernavn/Passord + PKCS12 </item> + <item>Brukernavn/Passord + Android</item> + </string-array> + <string-array name="tls_directions_entries"> + <item>0</item> + <item>1</item> + <item>Uspesifisert</item> + </string-array> + <string-array name="crm_entries"> + <item>No reconnection retries</item> + <item>One reconnection retry</item> + <item>Five reconnection retries</item> + <item>Fifty reconnection retries</item> + <item>Unlimited reconnection retries</item> + </string-array> +</resources> diff --git a/main/src/main/res/values-no/strings.xml b/main/src/main/res/values-no/strings.xml new file mode 100755 index 00000000..66e78d28 --- /dev/null +++ b/main/src/main/res/values-no/strings.xml @@ -0,0 +1,127 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string name="app">OpenVPN for Android</string> + <string name="address">Server adresse:</string> + <string name="port">Server port:</string> + <string name="location">Plassering</string> + <string name="select">velg</string> + <string name="cancel">Avbryt</string> + <string name="no_data">Ingen Data</string> + <string name="useLZO">LZO-komprimering</string> + <string name="client_no_certificate">Ingen sertifikat</string> + <string name="client_certificate_title">Klient sertifikat</string> + <string name="client_key_title">Klientsertifikat nøkkel</string> + <string name="client_pkcs12_title">PKCS12 fil</string> + <string name="ca_title">CA-sertifikat</string> + <string name="about">Om</string> + <string name="vpn_type">Type</string> + <string name="pkcs12pwquery">PKCS12 passord</string> + <string name="file_select">Velg…</string> + <string name="useTLSAuth">Bruke TLS-godkjenning</string> + <string name="tls_direction">TLS-retning</string> + <string name="ipv6_dialog_tile">Angi IPv6-adresse/nettmaske i CIDR format (f.eks 2000:dd::23/64)</string> + <string name="ipv4_dialog_title">Angi IPv6-adresse/nettmaske i CIDR format (f.eks 1.2.3.4/24)</string> + <string name="ipv4_address">IPv4-adresse</string> + <string name="ipv6_address">IPv6-adresse</string> + <string name="auth_username">Brukernavn</string> + <string name="auth_pwquery">Passord</string> + <string name="configure_the_vpn">Konfigurer VPN</string> + <string name="menu_add_profile">Legge til profil</string> + <string name="add_profile_name_prompt">Angi et navn som identifiserer den nye profilen</string> + <string name="profilename">Profilnavn</string> + <string name="no_error_found">Ingen feil funnet</string> + <string name="config_error_found">Feil i konfigurasjonen</string> + <string name="vpn_shortcut">OpenVPN snarvei</string> + <string name="vpn_launch_title">Koble til VPN</string> + <string name="random_host_prefix">Tilfeldig vert prefiks</string> + <string name="custom_config_title">Aktiver egendefinerte valg</string> + <string name="cancel_connection">Koble fra</string> + <string name="clear_log">Tøm logg</string> + <string name="title_cancel">Avbryt bekreftelse</string> + <string name="remove_vpn">Fjern VPN</string> + <string name="tls_auth_file">TLS-Auth-fil</string> + <string name="dns">DNS</string> + <string name="dns_override_summary">Bruk din egen DNS-server</string> + <string name="dns1_summary">DNS-Server som skal brukes.</string> + <string name="dns_server">DNS-server</string> + <string name="use_default_title">Bruk standard rute</string> + <string name="custom_routes_title">Egendefinert rute</string> + <string name="log_verbosity_level">Detaljnivå for Logging</string> + <string name="custom_options_title">Egendefinerte valg</string> + <string name="edit_vpn">Rediger VPN-innstillinger</string> + <string name="error">"Feil:"</string> + <string name="clear">Fjern</string> + <string name="version_info">%1$s %2$s</string> + <string name="send_logfile">Send loggfilen</string> + <string name="send">Send</string> + <string name="ics_openvpn_log_file">ICS OpenVPN loggfil</string> + <string name="tap_mode">Tap modus</string> + <string name="faq">FAQ</string> + <string name="copying_log_entries">Kopier loggoppføringer</string> + <string name="faq_shortcut">Snarvei til start</string> + <string name="encryption">Kryptering</string> + <string name="cipher_dialog_title">Angi krypteringsmetode</string> + <string name="settings_auth">Autentisering/kryptering</string> + <string name="file_explorer_tab">Filutforsker</string> + <string name="error_importing_file">Feil ved import av fil</string> + <string name="import_error_message">Kunne ikke importere filen fra filsystemet</string> + <string name="menu_import">Importer profil fra ovpn-fil</string> + <string name="menu_import_short">Importer</string> + <string name="import_content_resolve_error">Kan ikke lese profil for importering</string> + <string name="error_reading_config_file">Feil under lesing av config-filen</string> + <string name="add_profile">legg til profil</string> + <string name="import_could_not_open">Finner ikke filen %1$s nevnt i importert konfigurasjons fil</string> + <string name="importing_config">Importerer konfigurasjonsfilen fra kilde %1$s</string> + <string name="import_done">Ferdig med å lese konfigurasjons-filen.</string> + <string name="no_bind">Ingen lokale binding</string> + <string name="import_configuration_file">Importer konfigurasjonsfil</string> + <string name="faq_security_title">Sikkerhetsvurderinger</string> + <string name="import_vpn">Importer</string> + <string name="broken_image_cert_title">Feil ved visning av sertifikatvalg</string> + <string name="ipv4">IPv4</string> + <string name="ipv6">IPv6</string> + <string name="speed_waiting">Venter på tilstands melding…</string> + <string name="converted_profile">importert profil</string> + <string name="converted_profile_i">importert profilen %d</string> + <string name="broken_images">Ødelagte bilder</string> + <string name="pkcs12_file_encryption_key">PKCS12 Filkrypteringsnøkkel</string> + <string name="private_key_password">Privat nøkkel passord</string> + <string name="password">Passord</string> + <string name="file_icon">fil ikon</string> + <string name="tls_authentication">TLS-godkjenning</string> + <string name="generated_config">Generert konfigurasjon</string> + <string name="owner_fix">Fiks eierskap av /dev/tun</string> + <string name="edit_profile_title">Rediger \"%s\"</string> + <string name="building_configration">Lager konfigurasjon…</string> + <string name="netchange">Koble til på nytt ved nettverks endring</string> + <string name="netstatus">Nettverksstatus: %s</string> + <string name="select_file">Velg</string> + <string name="show_log_window">Vis logg-vindu</string> + <string name="mobile_info">Kjører på %1$s (%2$s) %3$s, Android API %4$d</string> + <string name="translationby">Norsk oversettelse av Jonny</string> + <string name="ipdns">IP og DNS</string> + <string name="basic">Grunnleggende</string> + <string name="routing">Ruting</string> + <string name="advanced">Avansert</string> + <string name="export_config_title">ICS Openvpn konfigurasjon</string> + <string name="faq_howto_title">Hurtigstart</string> + <string name="setting_loadtun_summary">Prøv å laste tun.ko kjernemodul før tilkobling. Krever at enheten er rootet.</string> + <string name="setting_loadtun">Last tun modul</string> + <string name="getproxy_error">Feil ved henting av proxy-innstillinger: %s</string> + <string name="using_proxy">Bruker proxy %1$s %2$d</string> + <string name="use_system_proxy">Bruk systemet proxy</string> + <string name="use_system_proxy_summary">Bruk global systemkonfigurasjon for HTTP/HTTPS proxy for å koble til.</string> + <string name="donatewithpaypal">Du kan <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;cmd=_s-xclick\">donere med PayPal</a> </string> + <string name="onbootrestart">Koble til på nytt ved restart</string> + <string name="ignore">Ignorer</string> + <string name="restart">Start på nytt</string> + <string name="configuration_changed">Konfigurasjon endret</string> + <string name="faq_duplicate_notification_title">Kopier varsler</string> + <string name="no_vpn_profiles_defined">Ingen VPN-profiler er definert.</string> + <string name="faq_routing_title">Ruting/grensesnitt-konfigurasjon</string> + <string name="persisttun_summary">Ikke gå tilbake til ingen VPN-tilkoblingen mens OpenVPN kobler til på nytt.</string> + <string name="openvpn_log">OpenVPN Logg</string> + <string name="import_config">Importer OpenVPN konfigurasjon</string> + <string name="battery_consumption_title">Batteriforbruk</string> +</resources> diff --git a/main/src/main/res/values-pl/arrays.xml b/main/src/main/res/values-pl/arrays.xml new file mode 100755 index 00000000..b5044975 --- /dev/null +++ b/main/src/main/res/values-pl/arrays.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string-array name="vpn_types"> + <item>Certyfikaty</item> + <item>Plik PKCS12</item> + <item>Certyfikat Android</item> + <item>Nazwa użytkownika/Hasło</item> + <item>Klucze statyczne</item> + <item>Użytkownik/Hasło + Certyfikaty</item> + <item>Użytkownik/Hasło + PKCS12</item> + <item>Uzytkownik/Hasło + Android</item> + </string-array> + <string-array name="tls_directions_entries"> + <item>0</item> + <item>1</item> + <item>Nieokreślone</item> + </string-array> + <string-array name="crm_entries"> + <item>No reconnection retries</item> + <item>One reconnection retry</item> + <item>Five reconnection retries</item> + <item>Fifty reconnection retries</item> + <item>Unlimited reconnection retries</item> + </string-array> +</resources> diff --git a/main/src/main/res/values-pl/strings.xml b/main/src/main/res/values-pl/strings.xml new file mode 100755 index 00000000..b0af3ddf --- /dev/null +++ b/main/src/main/res/values-pl/strings.xml @@ -0,0 +1,259 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string name="app">OpenVPN dla Androida</string> + <string name="address">Adres serwera:</string> + <string name="port">Port serwera:</string> + <string name="location">Lokalizacja</string> + <string name="cant_read_folder">Nie można odczytać katalogu</string> + <string name="select">Wybierz</string> + <string name="cancel">Anuluj</string> + <string name="no_data">Brak danych</string> + <string name="useLZO">Kompresja LZO</string> + <string name="client_no_certificate">Brak certyfikatu</string> + <string name="client_certificate_title">Certyfikat klienta</string> + <string name="client_key_title">Klucz certyfikatu klienta</string> + <string name="client_pkcs12_title">Plik PKCS12</string> + <string name="ca_title">Certyfikat urzędu certyfikacji</string> + <string name="no_certificate">Musisz wybrać certyfikat</string> + <string name="copyright_guicode">Kod źródłowy i formularz zgłoszeniowy błędów dostępny pod http://code.google.com/p/ics-openvpn/</string> + <string name="copyright_others">Program ten wykorzystuje następujące składniki; Szczegółowe informacje o licencjach w kodzie źródłowym</string> + <string name="about">O</string> + <string name="vpn_list_title">Profile</string> + <string name="vpn_type">Typ</string> + <string name="pkcs12pwquery">Hasło PKCS12</string> + <string name="file_select">Wybierz…</string> + <string name="file_nothing_selected">Wybierz plik</string> + <string name="useTLSAuth">Użyj uwierzytelniania TLS</string> + <string name="tls_direction">Kierunek TLS</string> + <string name="ipv6_dialog_tile">Wprowadź adres IPv6 w formacie CIDR (np. 2000:dd::23 / 64)</string> + <string name="ipv4_dialog_title">Wprowadź adres IPv4 w formacie CIDR (np. 1.2.3.4/24)</string> + <string name="ipv4_address">Adres IPv4</string> + <string name="ipv6_address">Adres IPv6</string> + <string name="custom_option_warning">Wprowadź ustawienia niestandardowe OpenVPN. Używać z rozwagą. Należy również pamiętać, że wiele ustawień związanych z tun OpenVPN nie jest obsługiwana przez projekt VPNSettings. Jeśli uważasz, że brakuje ważnych opcji skontaktuj się z autorem</string> + <string name="auth_username">Nazwa użytkownika</string> + <string name="auth_pwquery">Hasło</string> + <string name="static_keys_info">W konfiguracji statycznej klucze uwierzytelniania TLS zostaną wykorzystane jako statyczne klucze</string> + <string name="configure_the_vpn">Konfiguracja VPN</string> + <string name="menu_add_profile">Dodaj profil</string> + <string name="add_profile_name_prompt">Wprowadź nazwę określającą nowy profil</string> + <string name="duplicate_profile_name">Wybierz unikalną nazwę profilu</string> + <string name="profilename">Nazwa profilu</string> + <string name="no_keystore_cert_selected">Musisz wybrać certyfikat użytkownika</string> + <string name="no_error_found">Brak błędów</string> + <string name="config_error_found">Błąd w konfiguracji</string> + <string name="ipv4_format_error">Błąd parsowania adresu IPv4</string> + <string name="custom_route_format_error">Błąd parsowania niestandardowych tras</string> + <string name="pw_query_hint">(Pozostaw puste, aby wywołać na żądanie)</string> + <string name="vpn_shortcut">Skrót OpenVPN</string> + <string name="vpn_launch_title">Połącz się z siecią VPN</string> + <string name="shortcut_profile_notfound">Nie odnaleziono profilu określonego w skrócie</string> + <string name="random_host_prefix">Losowy prefiks hosta</string> + <string name="random_host_summary">Dodaje 6 losowych znaków przed nazwą hosta</string> + <string name="custom_config_title">Włącz opcje niestandardowe</string> + <string name="custom_config_summary">Określ niestandardowe opcje. Ostrożnie!</string> + <string name="route_rejected">Trasa odrzucona przez Androida</string> + <string name="cancel_connection">Rozłącz</string> + <string name="cancel_connection_long">Rozłącz VPN</string> + <string name="clear_log">Wyczyść log</string> + <string name="title_cancel">Anuluj potwierdzenie</string> + <string name="cancel_connection_query">Odłącz podłączone VPN / zrezygnować z próby połączenia?</string> + <string name="remove_vpn">Usuń VPN</string> + <string name="check_remote_tlscert_title">Oczekiwanie na certyfikat TLS z serwera</string> + <string name="remote_tlscn_check_title">Weryfikuj nazwę domenową zawartą w certyfikacie</string> + <string name="enter_tlscn_title">Temat zdalnego certyfikatu</string> + <string name="tls_key_auth">Włącza uwierzytelnianie kluczem TLS</string> + <string name="tls_auth_file">Plik TLS</string> + <string name="use_pull">Pobierz ustawienia</string> + <string name="dns">DNS</string> + <string name="override_dns">Nadpisz DNS z serwera</string> + <string name="dns_override_summary">Użyj własnych serwerów DNS</string> + <string name="dns1_summary">Używany serwer DNS.</string> + <string name="dns_server">Serwer DNS</string> + <string name="secondary_dns_message">Pomocniczy serwer DNS używany, jeśli normalny serwer DNS jest nieosiągalny.</string> + <string name="backup_dns">Zapasowy serwer DNS</string> + <string name="ignored_pushed_routes">Ignoruj trasy</string> + <string name="ignore_routes_summary">Ignoruj trasy serwera.</string> + <string name="default_route_summary">Przekieruj cały ruch przez tunel VPN</string> + <string name="use_default_title">Użyj domyślnej trasy</string> + <string name="custom_routes_title">Opcjonalne trasy</string> + <string name="log_verbosity_level">Poziom logowania</string> + <string name="float_summary">Zezwalaj uwierzytelnionym pakietom z każdego IP</string> + <string name="custom_options_title">Opcje użytkownika</string> + <string name="edit_vpn">Edytuj ustawienia VPN</string> + <string name="remove_vpn_query">Usunąć profil VPN \'%s\'?</string> + <string name="tun_error_helpful">Na niektórych customowych kompilacjach ICS może występować problem z uprawnieniami do /dev/tun albo występować problem z brakującymi częściami tun. Dla obrazów CM9 spróbuj poprawić uprawnienia za pomocą ustawień.</string> + <string name="tun_open_error">Nie można otworzyć interfejsu tun</string> + <string name="error">"Błąd:"</string> + <string name="clear">Czyść</string> + <string name="last_openvpn_tun_config">Otwieram interfejs tun:</string> + <string name="local_ip_info">Lokalne IPv4: %1$s/%2$d IPv6: %3$s MTU: %4$d</string> + <string name="dns_server_info">Serwer DNS: %1$s, Domena: %2$s</string> + <string name="version_info">%1$s %2$s</string> + <string name="send_logfile">Wyślij loga</string> + <string name="send">Wyślij</string> + <string name="ics_openvpn_log_file">Plik logów ICS OpenVPN</string> + <string name="copied_entry">Skopiowano log do schowka</string> + <string name="tap_mode">Tryb TAP</string> + <string name="faq_tap_mode">Tryb TAP nie jest możliwy z nierootwanym API VPN. Dlatego ta aplikacja nie zapewnia wsparcia TAP</string> + <string name="tap_faq2">Znowu. Żartujesz sobie? Tryb tap jest naprawdę nie wspierany, a wysyłanie więcej maili o to czy będzie wsparcie wcale nie pomoże.</string> + <string name="faq">FAQ</string> + <string name="copying_log_entries">Kopiowanie wpisów dziennika</string> + <string name="faq_copying">Aby skopiować pojedynczy wpis dziennika, naciśnij i przytrzymaj interesującą Cię pozycję. Celem skopiowania całego dziennika, należy użyć opcji Wyślij Log - jeżeli nie jest widoczna, użyj klawisza menu na obudowie urządzenia.</string> + <string name="faq_shortcut">Skrót do startu</string> + <string name="faq_howto_shortcut">Możesz umieścić skrót uruchamiający OpenVPN na swoim pulpicie. W zależności od używanej wersji oprogramowania, musisz dodać widget lub skrót na ekran główny.</string> + <string name="no_vpn_support_image">Twój obraz nie wspiera API VPN, przepraszamy ;(</string> + <string name="encryption">Szyfrowanie</string> + <string name="cipher_dialog_title">Wprowadź metodę szyfrowania</string> + <string name="chipher_dialog_message">Wybierz algorytm szyfrowania wykorzystywany przez OpenVPN. Pozostaw puste, aby skorzystać z ustawień domyślnych.</string> + <string name="auth_dialog_message">Wprowadź dane logowania użyte do OpenVPN. Pozostaw puste, aby skorzystać z ustawień domyślnych.</string> + <string name="settings_auth">Uwierzytelnianie/Szyfrowanie</string> + <string name="file_explorer_tab">Manager plików</string> + <string name="error_importing_file">Błąd importu pliku</string> + <string name="import_error_message">Nie można zaimportować pliku z systemu</string> + <string name="inline_file_data">[[Inline file data]]</string> + <string name="menu_import">Wczytaj profil z pliku ovpn</string> + <string name="menu_import_short">Wczytaj</string> + <string name="import_content_resolve_error">Nie można odczytać Profilu do importu</string> + <string name="error_reading_config_file">Błąd podczas czytania pliku konfiguracyjnego</string> + <string name="add_profile">Dodaj profil</string> + <string name="import_could_not_open">Nie można znaleźć pliku %1$s zawartego w zaimportowanym pliku</string> + <string name="importing_config">Importowanie pliku konfiguracyjnego ze źródła %1$s</string> + <string name="import_done">Skończono czytać plik konfiguracyjny.</string> + <string name="nobind_summary">Nie przypisuj do lokalnego adresu i portu</string> + <string name="import_configuration_file">Importuj plik konfiguracji</string> + <string name="import_vpn">Importuj</string> + <string name="ipv4">IPv4</string> + <string name="ipv6">IPv6</string> + <string name="speed_waiting">Oczekiwanie na wiadomość powitalną…</string> + <string name="broken_images">Uszkodzone obrazy</string> + <string name="pkcs12_file_encryption_key">Klucz pliku PKCS12</string> + <string name="private_key_password">Hasło klucza prywatnego</string> + <string name="password">Hasło</string> + <string name="file_icon">plik ikony</string> + <string name="tls_authentication">Uwierzytelnianie TLS</string> + <string name="generated_config">Wygenerowana konfiguracja</string> + <string name="generalsettings">Ustawienia</string> + <string name="owner_fix">Popraw uprawnienia do /dev/tun</string> + <string name="generated_config_summary">Pokazuje wygenerowany plik konfiguracji OpenVPN</string> + <string name="edit_profile_title">Edycja \"%s\"</string> + <string name="building_configration">Tworzenie konfiguracji…</string> + <string name="netchange_summary">Włączenie tej opcji spowoduje ponowne połączenie jeśli stan sieci się zmienił (np. z WiFi na GSM)</string> + <string name="netchange">Połącz ponownie przy zmianie sieci</string> + <string name="netstatus">Status sieci: %s</string> + <string name="select_file">Wybierz</string> + <string name="show_log_window">Pokaż okno loga</string> + <string name="faq_system_dialogs_title">Ostrzeżenie połączeń oraz dźwięki powiadomień</string> + <string name="translationby">Angielskie tłumaczenie Arne Schwabe<arne@rfc2549.org></string> + <string name="ipdns">IP i DNS</string> + <string name="basic">Podstawowe</string> + <string name="routing">Routing</string> + <string name="advanced">Zaawansowane</string> + <string name="export_config_title">Konfiguracja ICS Openvpn</string> + <string name="dns_add_error">Nie można dodać serwera DNS \"%1$s\", odrzucone przez system: %2$s</string> + <string name="faq_howto_title">Szybki start</string> + <string name="setting_loadtun_summary">Próba załadowania modułu tun.ko kernel przez próbą połączenia. Potrzeba rootowanych urządzeń.</string> + <string name="setting_loadtun">Załaduj moduł tun</string> + <string name="importpkcs12fromconfig">Importuj PKCS12 z konfiguracji do slepu kluczy Androida</string> + <string name="getproxy_error">Błąd ustawień proxy: %s</string> + <string name="using_proxy">Użycie proxy %1$s%2$d</string> + <string name="use_system_proxy">Użyj proxy systemowego</string> + <string name="use_system_proxy_summary">Użyj konfiguracji systemowej dla HTTP/HTTPS proxy w celu połączenia.</string> + <string name="donatewithpaypal">Możesz <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;cmd=_s-xclick\">wspomóc przez PayPal</a> </string> + <string name="onbootrestartsummary">OpenVPN połączy VPN jeśli był aktywny przy restarcie/zamknięciu systemu. Proszę przeczytać FAQ ostrzeżenia połączenia przez użyciem tej opcji.</string> + <string name="onbootrestart">Połącz przy reboocie</string> + <string name="ignore">Ignoruj</string> + <string name="restart">Restartuj</string> + <string name="restart_vpn_after_change">Zmiany konfiguracji będą zatwierdzone po restarcie VPN. Uruchomić ponowie teraz?</string> + <string name="configuration_changed">Zmieniono konfigurację</string> + <string name="log_no_last_vpn">Nie można ustalić ostatnio połączonego profilu do edycji</string> + <string name="faq_duplicate_notification_title">Podwójne powiadomienia</string> + <string name="no_vpn_profiles_defined">Nie zdefiniowano żadnego profilu.</string> + <string name="faq_hint">Sprawdź także nasze FAQ. Znajdziesz tam krótki poradnik dla początkujących.</string> + <string name="faq_routing_title">Konfiguracja trasy/interfejsu</string> + <string name="persistent_tun_title">Persistent tun</string> + <string name="openvpn_log">Log OpenVPN</string> + <string name="import_config">Importuj konfigurację OpenVPN</string> + <string name="battery_consumption_title">Zużycie baterii</string> + <string name="vpn_tethering_title">VPN i Tethering</string> + <string name="connection_retries">Próby połączenia</string> + <string name="reconnection_settings">Ustawienia ponownego połączenia</string> + <string name="connectretrymessage">Liczba sekund oczekiwania między próbami połączenia.</string> + <string name="connectretrywait">Sekundy pomiędzy połączeniami</string> + <string name="minidump_generated">OpenVPN niespodziewanie uległ awarii. Proszę rozważ użycie opcji wyślij Minidump w głównym menu</string> + <string name="send_minidump">Wyślij minidump do autora</string> + <string name="send_minidump_summary">Wysyłam informacje debuggera o ostatniej awarii aplikacji do twórcy</string> + <string name="notifcation_title">OpenVPN - %s</string> + <string name="session_ipv4string">%1$s-%2$s</string> + <string name="session_ipv6string">%1$s-%3$s,%2$s</string> + <string name="state_connecting">Łączę</string> + <string name="state_wait">Czekam na odpowiedź serwera</string> + <string name="state_auth">Uwierzytelnianie</string> + <string name="state_get_config">Pobieranie konfiguracji klienta</string> + <string name="state_assign_ip">Przypisywanie adresów IP</string> + <string name="state_add_routes">Dodaję trasy</string> + <string name="state_connected">Połączony</string> + <string name="state_disconnected">Odłączony</string> + <string name="state_reconnecting">Łączę ponownie</string> + <string name="state_exiting">Zamykanie</string> + <string name="state_noprocess">Nie działa</string> + <string name="state_resolve">Rozpoznwanie nazw hostów</string> + <string name="state_tcp_connect">Łączenie (TCP)</string> + <string name="state_auth_failed">Błąd autentykacji</string> + <string name="state_nonetwork">Czekam na sieć</string> + <string name="statusline_bytecount">↓%2$s/s %1$s - ↑%4$s/s %3$s</string> + <string name="notifcation_title_notconnect">Niepołączony</string> + <string name="start_vpn_title">Łączę z VPN %s</string> + <string name="start_vpn_ticker">Łączę z VPN %s</string> + <string name="jelly_keystore_alphanumeric_bug">Niektóre wersje Androida 4.1 mają problemy, jeśli nazwa certyfikatu zawiera niealfanumeryczne znaki (spacje, podkreślenia, myślniki). Spróbuj zaimportować certyfikat bez znaków specjalnych</string> + <string name="packet_auth">Pakiety uwierzytelniania</string> + <string name="auth_dialog_title">Wpisz metodę uwierzytelniania pakietów</string> + <string name="mobile_info_extended">Działa na %1$s (%2$s) %3$s, Android API %4$d, wersja %5$s, %6$s</string> + <string name="built_by">zbudowany przez %s</string> + <string name="debug_build">Kompilacja z debugiem</string> + <string name="official_build">Oficjalna kompilacja</string> + <string name="make_selection_inline">Skopiuj do profilu</string> + <string name="crashdump">Zrzut</string> + <string name="add">Dodaj</string> + <string name="send_config">Prześlij plik konfiguracyjny</string> + <string name="complete_dn">Kompletny DN</string> + <string name="remotetlsnote">Zaimportowana konfiguracja używa przestarzałej opcji tls-remote, która używa innego formatu DN.</string> + <string name="rdn">RDN (bieżąca nazwa)</string> + <string name="rdn_prefix">Prefiks RDN</string> + <string name="tls_remote_deprecated">tls-remote (PRZESTARZAŁE)</string> + <string name="help_translate">Możesz pomóc w tłumaczeniu odwiedzająć http://crowdin.net/project/ics-openvpn/invite</string> + <string name="prompt">%1$s próby kontroli %2$s</string> + <string name="remote_trust">Ufam tej aplikacji.</string> + <string name="no_external_app_allowed">Żadna aplikacja nie ma pozwolenia do używania zewnętrznego API</string> + <string name="allowed_apps">Dozwolone aplikacje: %s</string> + <string name="clearappsdialog">Wyczyścić listę dozwolonych aplikacji?\nObecna lista dozwolonych aplikacji:\n\n%s</string> + <string name="screenoff_summary">\"Wstrzymaj VPN kiedy wyświetlacz jest wyłączony i mniej niż 64kB danych przetransmitowano w 60s. Kiedy opcja \"Persistent Tun\" jest włączona wstrzymanie VPN zostawi twoje urządzenie bez połączenia. Bez opcji \"Persistent Tun\" urządzenie nie będzie miało połączenia/ochrony VPN.</string> + <string name="screenoff_title">Wstrzymaj połączenie VPN po wyłączeniu wyświetlacza</string> + <string name="screenoff_pause">Wstrzymanie połączenia na wyłączonym ekranie: w mniej niż %1$s na %2$ss</string> + <string name="screen_nopersistenttun">Ostrzeżenie. Persistent tun nie włączone dla tego VPN. Połączenie będzie generować ruch normalnego połączenia przy wyłączonym ekranie.</string> + <string name="save_password">Zapisz hasło</string> + <string name="pauseVPN">Wstrzymaj VPN</string> + <string name="resumevpn">Wznów VPN</string> + <string name="state_userpause">Wstrzymanie VPN na żądania użytkownika</string> + <string name="state_screenoff">VPN zatrzymany - ekran wyłązony</string> + <string name="device_specific">Informacje dotyczące haków w urządzeniu</string> + <string name="cannotparsecert">Nie można wyświetlić informacji o certyfikacie</string> + <string name="appbehaviour">Zachowanie aplikacji</string> + <string name="vpnbehaviour">Zachowanie VPN</string> + <string name="allow_vpn_changes">Zezwól na zmiany profili VPN</string> + <string name="hwkeychain">Sprzętowy magazyn kluczy:</string> + <string name="permission_icon_app">Ikona aplikacji próbującej użyć OpenVPN</string> + <string name="faq_vpndialog43_title">Potwierdzenie dla Android w wersji 4.3 i wyższych</string> + <string name="donatePlayStore">Alternatywnie, dotację możesz przesłać za pomocą Google Play:</string> + <string name="thanks_for_donation">Dziękujemy za wsparcie %s!</string> + <string name="logCleared">Dziennik wyczyszczony.</string> + <string name="show_password">Pokaż hasło</string> + <string name="keyChainAccessError">Błąd dostępu do klucza: %s</string> + <string name="timestamp_short">Krótki</string> + <string name="timestamp_iso">ISO</string> + <string name="timestamps">Znaczniki czasu</string> + <string name="timestamps_none">Brak</string> + <string name="uploaded_data">Wysyłanie</string> + <string name="downloaded_data">Pobieranie</string> + <string name="vpn_status">Status VPN</string> +</resources> diff --git a/main/src/main/res/values-ro/arrays.xml b/main/src/main/res/values-ro/arrays.xml new file mode 100755 index 00000000..0a7215c9 --- /dev/null +++ b/main/src/main/res/values-ro/arrays.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string-array name="vpn_types"> + <item>Certificate</item> + <item>fişier PKCS12</item> + <item>Certificat Android</item> + <item>Utilizator/Parola</item> + <item>Chei statice</item> + <item>Utilizator/PW + certificate</item> + <item>Utilizator/PW + PKCS12 </item> + <item>Utilizator/PW + Android</item> + </string-array> + <string-array name="tls_directions_entries"> + <item>0</item> + <item>1</item> + <item>Nespecificat</item> + </string-array> + <string-array name="crm_entries"> + <item>No reconnection retries</item> + <item>One reconnection retry</item> + <item>Five reconnection retries</item> + <item>Fifty reconnection retries</item> + <item>Unlimited reconnection retries</item> + </string-array> +</resources> diff --git a/main/src/main/res/values-ro/strings.xml b/main/src/main/res/values-ro/strings.xml new file mode 100755 index 00000000..ffc49216 --- /dev/null +++ b/main/src/main/res/values-ro/strings.xml @@ -0,0 +1,276 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string name="app">OpenVPN pentru Android</string> + <string name="address">Adresa server:</string> + <string name="port">Port server:</string> + <string name="location">Locaţie</string> + <string name="cant_read_folder">Directorul nu poate fi citit</string> + <string name="select">Selectare</string> + <string name="cancel">Anulare</string> + <string name="no_data">Nu există date</string> + <string name="useLZO">Compresie LZO</string> + <string name="client_no_certificate">Fără certificat</string> + <string name="client_certificate_title">Certificat client</string> + <string name="client_key_title">Cheie certificat client</string> + <string name="client_pkcs12_title">Fişier PKCS12</string> + <string name="ca_title">Certificat CA</string> + <string name="no_certificate">Trebuie să selectați un certificat</string> + <string name="copyright_guicode">Cod sursă şi tracker probleme disponibile la http://code.google.com/p/ics-openvpn/</string> + <string name="copyright_others">Acest program utilizează următoarele componente; a se vedea codul sursă pentru mai multe detalii despre licente</string> + <string name="about">Despre</string> + <string name="vpn_list_title">Profile</string> + <string name="vpn_type">Tip</string> + <string name="pkcs12pwquery">Parola PKCS12</string> + <string name="file_select">Selectaţi…</string> + <string name="file_nothing_selected">Trebuie să selectaţi un fişier</string> + <string name="useTLSAuth">Folosiţi autentificare TLS</string> + <string name="tls_direction">Direcţie TLS</string> + <string name="ipv6_dialog_tile">Introduceţi adresa IPv6/Netmask în Format CIDR (ex. 2000:dd::23 / 64)</string> + <string name="ipv4_dialog_title">Introduceţi adresa IPv4/Netmask în format CIDR (de exemplu, 1.2.3.4/24)</string> + <string name="ipv4_address">Adresă IPv4</string> + <string name="ipv6_address">Adresă IPv6</string> + <string name="custom_option_warning">Introduceţi opţiuni particularizate OpenVPN. Folosiţi cu atenţie. De asemenea, reţineţi că multe dintre opţiunile legate de OpenVPN tun nu sunt suportate de VPNSettings. Dacă lipseşte o opţiune importantă contactaţi autorul</string> + <string name="auth_username">Utilizator</string> + <string name="auth_pwquery">Parola</string> + <string name="static_keys_info">Pentru configurarea statică Cheile TLS Auth vor fi utilizate ca şi chei statice</string> + <string name="configure_the_vpn">Configurare VPN</string> + <string name="menu_add_profile">Adaugă profil</string> + <string name="add_profile_name_prompt">Introduceţi un nume ce identifică profilul nou</string> + <string name="duplicate_profile_name">Vă rugăm să introduceţi un nume de profil unic</string> + <string name="profilename">Nume profil</string> + <string name="no_keystore_cert_selected">Trebuie să selectați un certificat de utilizator</string> + <string name="no_error_found">Nu s-a găsit nici o eroare</string> + <string name="config_error_found">Eroare în configurare</string> + <string name="ipv4_format_error">Eroare parsare adresă IPv4</string> + <string name="custom_route_format_error">Eroare parsare rute particularizate</string> + <string name="pw_query_hint">(lăsaţi necompletat pentru a interoagre la cerere)</string> + <string name="vpn_shortcut">Scurtătură OpenVPN</string> + <string name="vpn_launch_title">Conectare la VPN</string> + <string name="shortcut_profile_notfound">Profilul specificat în comanda rapidă nu a fost găsit</string> + <string name="random_host_prefix">Prefix host aleator</string> + <string name="random_host_summary">Adaugă 6 caractere aleatoare în faţa hostname</string> + <string name="custom_config_title">Activare opţiuni particularizate</string> + <string name="custom_config_summary">Specificaţi opţiunile particularizate. Folosiţi cu grijă!</string> + <string name="route_rejected">Rută respinsă de Android</string> + <string name="cancel_connection">Deconectaţi</string> + <string name="cancel_connection_long">Deconectați VPN</string> + <string name="clear_log">Golire jurnal</string> + <string name="title_cancel">Anulare confirmare</string> + <string name="cancel_connection_query">Deconectaţi VPN-ul conectat/anulaţi încercarea de conectare?</string> + <string name="remove_vpn">Elimina VPN</string> + <string name="check_remote_tlscert">Verifică dacă serverul utilizează un certificat cu extensii TLS Server (--remote-cert-tls server)</string> + <string name="check_remote_tlscert_title">Aşteptă certificat de server TLS</string> + <string name="remote_tlscn_check_summary">Verifică Remote Server Certificate Subject DN</string> + <string name="remote_tlscn_check_title">Verficare hostname certificat</string> + <string name="enter_tlscn_dialog">Specifică verificarea ce va fi utilizată pentru certificatul DN (e.g. C=DE, L=Paderborn, OU=Avian IP Carriers, CN=openvpn.blinkt.de)\n\nSpecifică DN complet sau RDN (openvpn.blinkt.de in exemplu) sau un prefix RDN pentru verificare.\n\nCând folosiți prefix RDN \"Server\" face match si cu \"Server-1\" și \"Server-2\"\n\nDacă lăsați câmpul gol se va verifica RDN contra hostaname-ul serverului.\n\nPentru mai multe detalii verificați manualul OpenVPN 2.3.1+ la —verify-x509-name</string> + <string name="enter_tlscn_title">Subiect certificat remote</string> + <string name="tls_key_auth">Activează autentificarea cu cheie TLS</string> + <string name="tls_auth_file">Fişier TLS Auth</string> + <string name="pull_on_summary">Cere adrese IP, rute şi opţiuni timing de la server.</string> + <string name="pull_off_summary">Nu se cere nici o informaţie de la server. Setările trebuie specificate mai jos.</string> + <string name="use_pull">Setări pull</string> + <string name="dns">DNS</string> + <string name="override_dns">Suprascrie setările DNS trimise de Server</string> + <string name="dns_override_summary">Utilizează propriile servere DNS</string> + <string name="searchdomain">searchDomain</string> + <string name="dns1_summary">Server DNS ce va fi folosit.</string> + <string name="dns_server">Server DNS</string> + <string name="secondary_dns_message">Server DNS secundar folosit dacă serverul DNS normal nu poate fi folosit.</string> + <string name="backup_dns">Server DNS backup</string> + <string name="ignored_pushed_routes">Ignoră rutele primite</string> + <string name="ignore_routes_summary">Ignoră rutele oferite de server.</string> + <string name="default_route_summary">Redirecţionează tot traficul peste VPN</string> + <string name="use_default_title">Foloseşte ruta default</string> + <string name="custom_route_message">Introduceţi rute particularizate. Introduceţi destinaţia în format CIDR. \"10.0.0.0/8 2002:: / 16\" va redirecta reţelele 10.0.0.0/8 şi 2002:: / 16 peste VPN.</string> + <string name="custom_routes_title">Rute particularizate</string> + <string name="log_verbosity_level">Nivel detaliu jurnal</string> + <string name="float_summary">Permite pachete autentificate de la orice IP</string> + <string name="float_title">Permite floating server</string> + <string name="custom_options_title">Opţiuni particularizate</string> + <string name="edit_vpn">Editaţi setările VPN</string> + <string name="remove_vpn_query">Şterge profilul VPN \'%s\'?</string> + <string name="tun_error_helpful">În cazul anumitor imagini particularizate de ICS permisiile pentru /dev/tun pot fi greşite sau modulul tun lipseşte cu desăvârşire. Pentru imaginile CM9 ăncercaţi opţiunea de a repara permisiunile în cadrul setărilor generale</string> + <string name="tun_open_error">Eroare deschidere interfaţa tun</string> + <string name="error">"Eroare:"</string> + <string name="clear">Goleşte</string> + <string name="last_openvpn_tun_config">Se deschide interfața tun:</string> + <string name="local_ip_info">Local IPv4: %1$s/%2$d IPv6: %3$s MTU: %4$d</string> + <string name="dns_server_info">Server DNS: %1$s, Domeniu: %2$s</string> + <string name="ip_not_cidr">S-au primit informaţiile despre interfaţă %1$s şi %2$s, presupun că a doua adresă este adresa peer a serverlui remote. Folosesc netmask /32 pentru IP local. Modul dat de OpenVPN este \"%3$s\".</string> + <string name="route_not_cidr">Nu se poate interpreta %1$s şi %2$s ca rute IP cu netmask CIDR, folosesc /32 ca netmask.</string> + <string name="route_not_netip">Am corectat ruta %1$s/%2$s ca %3$s/%2$s</string> + <string name="keychain_access">Imposibil de accesat Keychain cu certificate al Android. Acest lucur poate fi cauzat de un upgrade de firmware sau de restaurarea unei copii de siguranţă a setărilor app/app. Editaţi din nou VPN-ul si reselectaţi certificatul la \"setări de bază\" pentru a recreea permisiile de a accesa certificatul.</string> + <string name="version_info">%1$s %2$s</string> + <string name="send_logfile">Trimite fişier jurnal</string> + <string name="send">Trimite</string> + <string name="ics_openvpn_log_file">Fişier jurnal OpenVPN ICS</string> + <string name="copied_entry">Linia din log s-a copiat in clip board</string> + <string name="tap_mode">Mod Tap</string> + <string name="faq_tap_mode">Modul Tap nu este posibil folosind API-ul VPN non root. Astfel această aplicaţie nu poate oferi suport tap</string> + <string name="tap_faq2">Din nou? Glumesti? Nu, modul tap chiar nu este suportat şi trimiţând mai multe email-uri în care îl cereţi nu va ajuta.</string> + <string name="tap_faq3">A treia oară? De fapt, cineva ar putea scrie un emulator tap bazat pe tun ce ar adăuga informaţii din layer2 la trimitere şi are elimina informaţiile layer2 la primire. Dar acest emulator ar trebui sa implementeze ARP şi probabil un client DHCP. Nu sunt la curent cu cineva care lucrează la asta. Daca vreţi sa programaţi aceste funcţii mă puteţi contacta.</string> + <string name="faq">FAQ</string> + <string name="copying_log_entries">Copiere linii jurnal</string> + <string name="faq_copying">Pentru a copia o singură linie din jurnal apăsaţi şi menţineţi apăsat pe acea linie. Pentru a copia/trimite întreg jurnalul folosiţi opţiunea Trimite Jurnal. Folosiţi butonul de meniu hardware dacă nu este vizibil în GUI.</string> + <string name="faq_shortcut">Shortcut pornire</string> + <string name="faq_howto_shortcut">Puteţi plasa o scurtătură pe desktop pentru a lansa OpenVPN. În funcţie de programul homescreen trebuie să adăugaţi fie o scurtătură fie un widget.</string> + <string name="no_vpn_support_image">Imaginea dvs. nu suportă API-ul VPNService, îmi pare rău :(</string> + <string name="encryption">Criptare</string> + <string name="cipher_dialog_title">Alegeţi metoda de criptare</string> + <string name="auth_dialog_message">Introduceţi autentificarea digest ce este folosită de OpenVPN. Lăsaţi gol pentru digest predefinit.</string> + <string name="settings_auth">Autentificare/criptare</string> + <string name="file_explorer_tab">File Explorer</string> + <string name="inline_file_tab">Fişier inline</string> + <string name="error_importing_file">Eroare importare fişier</string> + <string name="import_error_message">Nu s-a putut importa fişierul din filesystem</string> + <string name="inline_file_data">[[date fişier inline]]</string> + <string name="opentun_no_ipaddr">Se refuză deschiderea device-ului tun fără informaţii IP</string> + <string name="menu_import">Importa profilul din fişier ovpn</string> + <string name="menu_import_short">Import</string> + <string name="import_content_resolve_error">Imposibil de citit profilul de importat</string> + <string name="error_reading_config_file">Eroare la citirea fişierului de configurare</string> + <string name="add_profile">Adaugă profil</string> + <string name="import_could_not_open">Imposibil de găsit fișierul %1$s menţionat în fişierul de configurare importat</string> + <string name="importing_config">Import fişierul de configurare din sursa %1$s</string> + <string name="import_warning_custom_options">Configurația avut câteva opțiuni de configurare care nu sunt mapate la configurații UI. Aceste opțiuni au fost adăugate ca opțiuni de configurare personalizate. Configurația personalizată este afișată mai jos:</string> + <string name="import_done">S-a terminat citirea fişierului de configurare.</string> + <string name="nobind_summary">Nu face bind la adresa şi portul local</string> + <string name="no_bind">Fără binding local</string> + <string name="import_configuration_file">Import fişier de configurare</string> + <string name="faq_security_title">Considerente de securitate</string> + <string name="faq_security">"Deoarece OpenVPN are implicaţii de securitate este bine să facem câteva menţiuni. Toate datele de pe cardul sd sunt inerent nesecurizate. Orice aplicaţie le poate citi (de exemplu acest program nu are nevoie de drepturi speciale pentru sd). Datele acestei aplicaţii pot fi citite doar de aplicaţia însăşi. Dacă folosiţi funcţia import pentru cacert/cert/key în dialogul de import fişiere datele sunt stocate în profilul VPN. Profilele VPN sunt accesibile doar de această aplicaţie. (Nu uitaţi să ştergeţi copiile de pe cardul sd după aceea). Chiar dacă sunt accesibile doar de această aplicaţie datele sunt necriptate. Folosind root sau alte exploit-uri datele ar putea fi extrase. Parolele salvate sunt stocate de asemenea în clar. Pentru fişiere pkcs12 este recomandat să le importaţi în keystore-ul android."</string> + <string name="import_vpn">Import</string> + <string name="broken_image_cert_title">Eroare la afişarea selecţiei de certificat</string> + <string name="broken_image_cert">Excepţie la afişarea dialogului Android 4.0+ de selecţie a certificatului. Acest lucru nu ar trebui să se întâmple deoarece este o funcţie standard Android 4.0+. Poate ROM-ul dvs. Android are suportul de stocare a certificatelor defect</string> + <string name="ipv4">IPv4</string> + <string name="ipv6">IPv6</string> + <string name="speed_waiting">Se aşteaptă mesajul de stare…</string> + <string name="converted_profile">profil importat</string> + <string name="converted_profile_i">profil importat %d</string> + <string name="broken_images">Imagini defecte</string> + <string name="broken_images_faq"><p>Este cunoscut faptul ca imaginile HTC oficiale au o problemă ciudată de rutare ce nu permite traficului să treacă prin tunel (citiţi şi <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=18\">Problema 18</a>în bug tracker.)</p><p>S-a raportat că VPNService lipseşte complet din imaginile oficiale SONY mai vechi pentru Xperia arc S şi Xperia Ray. (citiţi şi <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=29\">Problema 29</a> în bug tracker.)</p><p>În imaginile particularizate modulul tun poate lipsi sau drepturile pentru /dev/tun pot fi greşite. Unele imagini CM9 au nevoie de opţiunea de reparare a drepturilor din setările generale.</p><p>Important: dacă aveţi o imagine defectă raportaţi-o fabricantului. Cu cât mai mulţi utilizatori raportează problema fabricantului cu atât este mai posibil ca el să o remedieze.</p></string> + <string name="pkcs12_file_encryption_key">Cheie criptare fişier PKCS12</string> + <string name="private_key_password">Parola cheie privată</string> + <string name="password">Parola</string> + <string name="file_icon">icon fişier</string> + <string name="tls_authentication">autentificare TLS</string> + <string name="generated_config">Config generat</string> + <string name="generalsettings">Setări</string> + <string name="owner_fix_summary">Încearcă să seteze owner-ul /dev/tun ca sistem. Unele imagini CM9 au nevoie de asta pentru a permite API-ului VPNService să funcţioneze. Are nevoie de root.</string> + <string name="owner_fix">Repară drepturi /dev/tun</string> + <string name="generated_config_summary">Afişează fişierul de configurare OpenVPN generat</string> + <string name="edit_profile_title">Editare \"%s\"</string> + <string name="building_configration">Se generează configurarea…</string> + <string name="netchange_summary">Activând această opţiune forţaţi o reconectare dacă se schimbă starea de reţea (e.g. WiFi la/de la mobil)</string> + <string name="netchange">Reconectare la schimbare reţea</string> + <string name="netstatus">Statutus reţea: %s</string> + <string name="extracahint">Certificatul CA este în mod normal returnat de Android Keystore. Specificaţi un certificat separat dacă observaţi erori de verificare a certificatului.</string> + <string name="select_file">Selectare</string> + <string name="keychain_nocacert">Nici un certificat CA nu a fost returnat la citirea din keystore-ul Android. Autentificarea probabil va eşua.</string> + <string name="show_log_summary">Afişează fereastra jurnal la conectare. Fereastra jurnal poate fi accesată oricând din statusul notificare.</string> + <string name="show_log_window">Arată fereastra Jurnal</string> + <string name="mobile_info">Rulează pe %1$s (%2$s) %3$s, Android API %4$d</string> + <string name="error_rsa_sign">Eroare semnare cu Android keystore key %1$s: %2$s</string> + <string name="faq_system_dialogs">Avertizarea la conexiunea VPN ce vă spune că această aplicaţie poate intercepta întreg traficul este impusă de sistem pentru a preveni abuzul funcţiei API VPNService.\nNotificarea de conexiune VPN(simbolul cheie)este de asemenea impusă de sistemul Android pentru a semnala o conexiune VPN în derulare. În cadrul unor imagini această notificare face şi un sunet.\nAndroid a introdus aceste notificări pentru siguranţa dvs. şi este asigurat că nu pot fi evitate. (Din păcate în anumite imagini acestea includ şi un sunet de notificare)</string> + <string name="faq_system_dialogs_title">Alertă conexiune şi sunet notificare</string> + <string name="translationby">Traducere în limba română de Silviu Vulcan<silviuvulcan.ro></string> + <string name="ipdns">IP şi DNS</string> + <string name="basic">Basic</string> + <string name="routing">Rutare</string> + <string name="obscure">Setări obscure pentru OpenVPN. În mod normal nu sunt necesare.</string> + <string name="advanced">Avansate</string> + <string name="export_config_title">Configurare Openvpn ICS</string> + <string name="warn_no_dns">Nici un server DNS utilizat. Rezolvarea de nume poate să nu funcționeze. Luați în considerare stabilirea unor servere DNS personalizate. Vă rugăm, de asemenea, rețineți că Android va continua să utilizeze setările proxy specificate pentru conexiunea mobilă/Wi-Fi atunci când nu sunt stabilite servere DNS.</string> + <string name="dns_add_error">Nu s-a putut adăuga serverul DNS \"%1$s\", respins de sistem: %2$s</string> + <string name="faq_howto"><p>Obţineţi o configurare funcţională (testată pe calculatorul dvs. sau descărcată de la provider/companie)</p><p>Dacă este un singur fişier fără alte fişiere pem/pks12 puteţi să vă trimiteţi fişierul prin email şi să deschideţi ataşamentul. Daca aveţi fişiere multiple le puteţi pune pe cardul sd.</p><p>Click pe ataşamentul email/Folosiţi icoana director din lista de vpn-ri pentru a importa fişierul de configurare.</p><p>Dacă sunt erori despre fişiere lipsă le puteţi pune pe cardul sd.</p><p>Click pe simbolul de salvare pentru a adăuga VPN-ul importat în lista dvs. de VPN-uri</p><p>Conectaţi VPN-ul dând click pe numele VPN-ului</p><p>Dacă sunt erori/avertismente în jurnal încercaţi să le înţelegeţi şi să le reparaţi</p> </string> + <string name="faq_howto_title">Pornire rapidă</string> + <string name="setting_loadtun_summary">Încearcă încărcarea modului kernel tun.ko înainte de conectare. Are nevoie de un device root-at.</string> + <string name="setting_loadtun">Încarcă modulul tun</string> + <string name="importpkcs12fromconfig">Import PKCS12 configurare în Android Keystore</string> + <string name="getproxy_error">Eroare la obţinerea setărilor proxy: %s</string> + <string name="using_proxy">Folosesc proxy %1$s %2$d</string> + <string name="use_system_proxy">Foloseşte proxy sistem</string> + <string name="use_system_proxy_summary">Foloseşte configurarea sistem pentru proxy HTTP/HTTPS folosit la conectare.</string> + <string name="donatewithpaypal">Puteţi <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;cmd=_s-xclick\">dona prin PayPal</a> </string> + <string name="onbootrestartsummary">OpenVPN va reconecta un VPN dacă a fost activ la reboot/shutdown. Citiţi avertizarea la Conexiune din FAQ înainte de a folosi această funcţie.</string> + <string name="onbootrestart">Reconectarea la reboot</string> + <string name="ignore">Ignora</string> + <string name="restart">Restart</string> + <string name="restart_vpn_after_change">Schimbările de configurare vor fi aplicate după restartarea VPN-ului. (Re)startaţi VPN-ul acum?</string> + <string name="configuration_changed">Configuraţie schimbată</string> + <string name="log_no_last_vpn">Nu se poate determina ultimul profil conectat pentru editare</string> + <string name="faq_duplicate_notification_title">Duplichează notificări</string> + <string name="faq_duplicate_notification">Dacă Android are puţină memorie (RAM) disponibilă va închide aplicaţii şi servicii ce nu sunt necesare pe moment. Acest lucru va închide o conexiune VPN activă. Pentru a asigura că acest fapt nu se întâmplă şi conexiunea/OpenVPN supravieţuieşte serviciul rulează cu prioritate ridicată. Pentru a rula cu prioritate ridicată aplicaţia trebuie să afişeze o notificare. Icoana cheie de notificare este impusă de sistem după cum s-a descris în raspunsul FAQ anterior. Nu se socoteşte ca notificare a aplicaţiei în scopul de a rula cu prioritate ridicată.</string> + <string name="no_vpn_profiles_defined">nici un profil VPN definit.</string> + <string name="add_new_vpn_hint">Folosiţi icoana <img src=\"ic_menu_add\"/> pentru a adăuga un nou VPN</string> + <string name="vpn_import_hint">Folosiţi icoana <img src=\"ic_menu_archive\"/> pentru a importa un profil existent (.ovpn sau .conf) de pe cardul sd.</string> + <string name="faq_hint">Verificaţi şi FAQ. Acolo este ghid rapid de utilizare.</string> + <string name="faq_routing_title">Configurare Rutare/Interfaţă</string> + <string name="faq_routing">Configurarea rutării şi a interfeţei nu se face folosind comenzile ifconfig/route tradiţionale ci se foloseşte API-ul VPNService. Astfel rezultă o configurarea a rutării diferită ca în cazul altor OS-uri. Configurarea constă doar în interfaţa IP tunel şi a reţelelor ce trebuie rutate prin ea. În mod special nu este necesară o adresă partener sau adresă gateway. Nu sunt necesare nici rutele speciale pentr a ajunge la serverul VPN (de exemplu cu un gateway de redirectare) Aplicaţia va ignora astfel aceste setări la importarea unei configurări. Aplicaţia se asigură cu API-ul VPNService că nu se rutează prin tunel conexiunea cu care se ajunge la server. Deoarece este suportată doar specificarea reţelelelor ce trebuiesc rutate prin tunel rutele extra ce nu pointează către tunel nu sunt suportate. (e.g. route x.x.x.x y.y.y.y net_gateway). Fereastra jurnal arată configurarea curentă a VPNService la stabilirea unei conexiuni. </string> + <string name="persisttun_summary">Nu reveni la nici o conexiune VPN câtă vreme OpenVPN se reconectează.</string> + <string name="persistent_tun_title">Tun persistent</string> + <string name="openvpn_log">jurnal OpenVPN</string> + <string name="import_config">Import configurare OpenVPN</string> + <string name="battery_consumption_title">Consum baterie</string> + <string name="baterry_consumption">În cadrul testelor mele personale principalul motiv pentru consumul ridicat de baterie al OpenVPN sunt pachetele keepalive. Majoritatea serverelor OpenVPN au în configurare o directivă cum ar fi \'keepalive 10 60\' ce face ca şi clientul să schimbe cu serverul pachete keepalive la fiecare 10 secunde.<p> Chiar dacă aceste pachete sunt mici şi nu folosesc trafic, ele menţin radioul mobil activ şi cresc consumul de energie. (Citiţi şi <a href=\"http://developer.android.com/training/efficient-downloads/efficient-network-access.html#RadioStateMachine\">The Radio State Machine | Android Developers</a>) <p>Această setare keepalive nu poate fi schimbată de client. Doar administratorul serverului OpenVPN o poate schimba.<p> Din păcate o valoare mai mare de 60 de secunde a keepalive cu UDP poate face ca unele gateway-uri NAT să termine conexiunea după un timp scurt. Folosind TCP cu valori lungi de keepalive funcţionează dar rularea unui tunel TCP peste o conexiune TCP funcţionează foarte slab în cazul conexiunilor cu pierderi mari de pachete. (Citiţi <a href=\"http://sites.inka.de/bigred/devel/tcp-tcp.html\">Why TCP Over TCP Is A Bad Ide</a>)</string> + <string name="faq_tethering">Funcţia Android Tether (folosind WiFi, USB sau Bluetooth) şi API-ul VPNService (folosit de acest program) nu funcţionează împreună. Pentru mai multe detalii vizitaţi <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=34\">issue #34</a></string> + <string name="vpn_tethering_title">VPN şi Tethering</string> + <string name="connection_retries">Reîncercări conectare</string> + <string name="reconnection_settings">Setările de reconectare</string> + <string name="connectretrymessage">Numărul de secunde între încercările de conectare.</string> + <string name="connectretrywait">Secunde între conexiuni</string> + <string name="minidump_generated">OpenVPN sa oprit în mod neaşteptat. Vă rugăm să consideraţi opţiunea de trimitere a unui Minidump din meniul principal</string> + <string name="send_minidump">Trimite Minidump la dezvoltator</string> + <string name="send_minidump_summary">Trimite informații de depanare despre ultimul crash la dezvoltator</string> + <string name="notifcation_title">OpenVPN - %s</string> + <string name="session_ipv4string">%1$s - %2$s</string> + <string name="session_ipv6string">%1$s - %3$s, %2$s</string> + <string name="state_connecting">Se conectează</string> + <string name="state_wait">Se aşteaptă răspunsul serverului</string> + <string name="state_auth">Autentificare</string> + <string name="state_get_config">Se obţine configurarea clientului</string> + <string name="state_assign_ip">Se asignează adresele IP</string> + <string name="state_add_routes">Adăugare rute</string> + <string name="state_connected">Conectat</string> + <string name="state_disconnected">Deconectaţi</string> + <string name="state_reconnecting">Se reconectează</string> + <string name="state_exiting">Se iasă</string> + <string name="state_noprocess">Nu rulează</string> + <string name="state_resolve">Rezolvare nume host</string> + <string name="state_tcp_connect">Se conectează (TCP)</string> + <string name="state_auth_failed">Autentificare a eşuat</string> + <string name="state_nonetwork">Se aşteaptă o reţea utilizabilă</string> + <string name="statusline_bytecount">↓%2$s/s %1$s - ↑%4$s/s %3$s</string> + <string name="notifcation_title_notconnect">Nu este conectat</string> + <string name="start_vpn_title">Conectare la VPN %s</string> + <string name="start_vpn_ticker">Conectare la VPN %s</string> + <string name="jelly_keystore_alphanumeric_bug">Unele versiuni de Android 4.1 au probleme dacă numele certificatului keystore conţine caractere non-alfanumerice (cum ar fi spaţii, linii de subliniere sau cratime). Încercaţi să reimportaţi certificatul fără caractere speciale</string> + <string name="encryption_cipher">Cifru criptare</string> + <string name="packet_auth">Autentificare pachete</string> + <string name="auth_dialog_title">Introduceţi metoda de autentificare de pachete</string> + <string name="mobile_info_extended">Rulează pe %1$s (%2$s) %3$s, Android API %4$d, versiunea %5$s, %6$s</string> + <string name="built_by">compilat de %s</string> + <string name="debug_build">versiune debug</string> + <string name="official_build">versiune oficială</string> + <string name="make_selection_inline">Copiaţi în profil</string> + <string name="crashdump">Crashdump</string> + <string name="add">Adauga</string> + <string name="send_config">Trimite fişierul de configurare</string> + <string name="complete_dn">DN Complet</string> + <string name="remotetlsnote">Configuraţia importată foloseşte opţiunea ÎNVECHITĂ tls-remote ce utilizează un format DN diferit.</string> + <string name="rdn">RDN (nume comun)</string> + <string name="rdn_prefix">Prefix RDN</string> + <string name="tls_remote_deprecated">tls-remote (ÎNVECHIT)</string> + <string name="help_translate">Puteţi ajuta la traducere vizitând http://crowdin.net/project/ics-openvpn/invite</string> + <string name="prompt">%1$s încercări de a controla %2$s</string> + <string name="remote_trust">Am încredere în această aplicaţie.</string> + <string name="no_external_app_allowed">Nici o aplicaţie nu are permisiunea de a folosi API-ul extern</string> + <string name="allowed_apps">Aplicaţii permise: %s</string> + <string name="clearappsdialog">Şterge lista aplicaţilor permise?\nLista curentă a aplicaţilor ce au permisiune:\n\n%s</string> + <string name="screenoff_summary">\"Suspendă VPN atunci când ecranul este oprit şi au fost transferaţi mai puţin de 64 kB în 60s. Când \"Tun persistent\" este activat suspendarea conexiunii VPN va lăsa aparatul dvs. FĂRĂ conexiune la reţea. Fără opţiunea \"Tun persistent\" aparatul nu va beneficia de conexiune/protecţie VPN.</string> + <string name="screenoff_title">Suspendă conexiunea VPN după închiderea ecranului</string> + <string name="screenoff_pause">Se suspendă conexiunea în starea ecran oprit: mai puţin de %1$s în %2$s</string> + <string name="screen_nopersistenttun">Atenție: TUN persistent nu este activat pentru acest VPN. Traficul va utiliza conexiunea Internet normala atunci când ecranul este oprit.</string> + <string name="save_password">Salvare parola</string> +</resources> diff --git a/main/src/main/res/values-ru/arrays.xml b/main/src/main/res/values-ru/arrays.xml new file mode 100755 index 00000000..ea6527ce --- /dev/null +++ b/main/src/main/res/values-ru/arrays.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string-array name="vpn_types"> + <item>Сертификаты</item> + <item>Файл PKCS12</item> + <item>Сертификат Андроид-устройства</item> + <item>Логин/Пароль</item> + <item>Статичные ключи</item> + <item>Логин/пароль + Сертификаты</item> + <item>Логин/пароль + PKCS12 </item> + <item>Логин/пароль + сертификат Android</item> + </string-array> + <string-array name="tls_directions_entries"> + <item>0</item> + <item>1</item> + <item>Не указан</item> + </string-array> + <string-array name="crm_entries"> + <item>No reconnection retries</item> + <item>One reconnection retry</item> + <item>Five reconnection retries</item> + <item>Fifty reconnection retries</item> + <item>Unlimited reconnection retries</item> + </string-array> +</resources> diff --git a/main/src/main/res/values-ru/strings.xml b/main/src/main/res/values-ru/strings.xml new file mode 100755 index 00000000..dd2d2b2c --- /dev/null +++ b/main/src/main/res/values-ru/strings.xml @@ -0,0 +1,295 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string name="app">OpenVPN для Android</string> + <string name="address">Адрес сервера:</string> + <string name="port">Порт сервера:</string> + <string name="location">Расположение</string> + <string name="cant_read_folder">Не могу прочитать директорию</string> + <string name="select">Выбрать</string> + <string name="cancel">Отмена</string> + <string name="no_data">Нет данных</string> + <string name="useLZO">Сжатие LZO</string> + <string name="client_no_certificate">Нет сертификата</string> + <string name="client_certificate_title">Сертификат клиента</string> + <string name="client_key_title">Ключ сертификата клиента</string> + <string name="client_pkcs12_title">PKCS12 файл</string> + <string name="ca_title">CA сертификат</string> + <string name="no_certificate">Вам необходимо выбрать сертификат</string> + <string name="copyright_guicode">Исходники и информация о версиях находятся по адресу http://code.google.com/p/ics-openvpn/</string> + <string name="copyright_others">Данная программа использует следующие компоненты; смотрите исходный код для получения подробной информации о лицензии</string> + <string name="about">О программе</string> + <string name="vpn_list_title">Профили</string> + <string name="vpn_type">Тип</string> + <string name="pkcs12pwquery">Пароль для PKCS12</string> + <string name="file_select">Выбрать…</string> + <string name="file_nothing_selected">Вы должны выбрать файл</string> + <string name="useTLSAuth">Использовать аутентификацию TLS</string> + <string name="tls_direction">TLS Direction</string> + <string name="ipv6_dialog_tile">Введите адрес/маску подсети IPv6 в формате CIDR (например 2000:dd::23/64)</string> + <string name="ipv4_dialog_title">Введите адрес/маску подсети IPv4 в формате CIDR (например 1.2.3.4/24)</string> + <string name="ipv4_address">Адрес IPv4</string> + <string name="ipv6_address">Адрес IPv6</string> + <string name="custom_option_warning">Введите дополнительные параметры OpenVPN. Используйте эту возможность с большой осторожностью. Если вы считаете, что отсутствует важный параметр, свяжитесь с автором</string> + <string name="auth_username">Имя пользователя</string> + <string name="auth_pwquery">Пароль</string> + <string name="static_keys_info">Для конфигурации с статичными сертификатами будут использоваться ключи TLS</string> + <string name="configure_the_vpn">Настройка VPN-туннеля</string> + <string name="menu_add_profile">Добавить конфигурацию</string> + <string name="add_profile_name_prompt">Введите имя новой конфигурации</string> + <string name="duplicate_profile_name">Пожалуйста, введите уникальное имя профиля</string> + <string name="profilename">Имя конфигурации</string> + <string name="no_keystore_cert_selected">Необходимо выбрать сертификат пользователя</string> + <string name="no_error_found">Ошибок не найдено</string> + <string name="config_error_found">Ошибка в конфигурации</string> + <string name="ipv4_format_error">Невозможно прочесть IPv4 адрес</string> + <string name="custom_route_format_error">Невозможно примениить пользовательские маршруты</string> + <string name="pw_query_hint">(оставьте пустым для запроса по требованию)</string> + <string name="vpn_shortcut">Ярлык OpenVPN</string> + <string name="vpn_launch_title">Подключиться к VPN</string> + <string name="shortcut_profile_notfound">Не найден профиль, указанный в ярлыке</string> + <string name="random_host_prefix">Случайный префикс узла</string> + <string name="random_host_summary">Добавляет 6 случайных символов перед именем хоста</string> + <string name="custom_config_title">Включить пользовательские параметры</string> + <string name="custom_config_summary">Пользовательские параметры. Используйте с осторожностью!</string> + <string name="route_rejected">Маршрут отвергнут Android</string> + <string name="cancel_connection">Отключение</string> + <string name="cancel_connection_long">Отключить VPN</string> + <string name="clear_log">очистить журнал</string> + <string name="title_cancel">Подтверждение отмены</string> + <string name="cancel_connection_query">Отключение активных VPN/Отмена попыток подключения?</string> + <string name="remove_vpn">Удалить VPN</string> + <string name="check_remote_tlscert">Проверяет, использует ли сервер сертификаты TLS (--remote-cert-tls server)</string> + <string name="check_remote_tlscert_title">Ожидать сертификата TLS от сервера</string> + <string name="remote_tlscn_check_summary">Проверка DN объекта удаленного сертификата</string> + <string name="remote_tlscn_check_title">Проверка имени хоста сертификата</string> + <string name="enter_tlscn_dialog">Переключатель способа проверки DN сертификата (e.g. C=DE, L=Paderborn, OU=Avian IP Carriers, CN=openvpn.blinkt.de)\n\nВозможные значения: полный DN, RDN (для примера openvpn.blinkt.de) или только преффикс RDN для проверки.\n\nПри использовании преффикса RDN, например \"Server\", значения будут \"Server-1\", \"Server-2\" и т.д.\n\nПри пустом текстовом поле проверка будет проводиться по имени хоста.\n\nДля подробностей смотрите руководство для OpenVPN 2.3.1+, раздел —verify-x509-name</string> + <string name="enter_tlscn_title">Объект удаленного сертификата</string> + <string name="tls_key_auth">Включить аутентификацию по TLS ключу</string> + <string name="tls_auth_file">Файл аутентификации TLS</string> + <string name="pull_on_summary">Запрос IP-адреса, маршрутов и параметров от сервера.</string> + <string name="pull_off_summary">Игнорировать все параметры сервера. Параметры должны быть указаны ниже.</string> + <string name="use_pull">Запрашивать параметры</string> + <string name="dns">DNS</string> + <string name="override_dns">Переопределить параметры DNS от сервера</string> + <string name="dns_override_summary">Использовать ваши DNS</string> + <string name="searchdomain">Домен поиска</string> + <string name="dns1_summary">DNS-сервер для использования.</string> + <string name="dns_server">DNS-сервер</string> + <string name="secondary_dns_message">Вторичный DNS-сервер используется, если не получен ответ от первого сервера DNS.</string> + <string name="backup_dns">Резервный сервер DNS</string> + <string name="ignored_pushed_routes">Игнорировать посылаемые маршруты</string> + <string name="ignore_routes_summary">Игнорировать маршруты, посылаемые сервером.</string> + <string name="default_route_summary">Перенаправляет весь трафик через VPN</string> + <string name="use_default_title">Использовать маршрут по-умолчанию</string> + <string name="custom_route_message">Введите пользовательские маршруты. Только введите адрес назначения в формате CIDR. \"10.0.0.0/8 2002::/16\" будет использовано для 10.0.0.0/8 и 2002::/16 сетей через VPN.</string> + <string name="custom_routes_title">Пользовательские маршруты</string> + <string name="log_verbosity_level">Уровень детализации лога</string> + <string name="float_summary">Разрешить пакеты аутентификации с любого IP-адреса</string> + <string name="float_title">Разрешать \"плавающие\" сервера</string> + <string name="custom_options_title">Пользовательские параметры</string> + <string name="edit_vpn">Редактирование параметров VPN</string> + <string name="remove_vpn_query">Удаление профиля VPN %s?</string> + <string name="tun_error_helpful">На некторых костомных сборках права на /dev/tun могут быть неверными или tun-модуль может быть не включен. Для прошивки CM9 можете попробовать исправить владельца прямо из настроек программы</string> + <string name="tun_open_error">Открытие интерфейса tun окончилось неудачей</string> + <string name="error">"Ошибка: "</string> + <string name="clear">Очистить</string> + <string name="last_openvpn_tun_config">Открытие tun-интерфейса:</string> + <string name="local_ip_info">Адрес IPv4: %1$s/%2$d IPv6: %3$s MTU: %4$d</string> + <string name="dns_server_info">DNS-сервер: %1$s, Домен: %2$s</string> + <string name="ip_not_cidr">Получена информация интерфейса %1$s и %2$s, второй адрес является удалённым адресом канала. Используется сетевая маска /32 для локального IP адреса. Режим, установленный OpenVPN: \"%3$s\".</string> + <string name="route_not_cidr">Невозможно использовать выражения %1$s и %2$s как маршрут по стандарту CIDR. используется /32 как маска подсети.</string> + <string name="route_not_netip">Маршрут исправлен с %1$s/%2$s на %3$s/%2$s</string> + <string name="keychain_access">Не удается получить доступ к хранилищу ключей и сертификатов Android. Это может быть вызвано обновлением прошивки или восстановления старой копии приложения или его настроек. Пожалуйста, отредактируйте профиль VPN и заново укажите ключи и сертификаты в разделе Основные параметры.</string> + <string name="version_info">%1$s %2$s</string> + <string name="send_logfile">Отправить файл журнала</string> + <string name="send">Отправить</string> + <string name="ics_openvpn_log_file">ICS OpenVPN файла лога</string> + <string name="copied_entry">Скопировать лог в буфер обмена</string> + <string name="tap_mode">Режим TAP</string> + <string name="faq_tap_mode">Режим TAP невозможен на устройствах без root-а. Поэтому это приложение не поддерживает TAP</string> + <string name="tap_faq2">Снова? Вы издеваетесь? Не поддерживается режим TAP и просьбы к автору об этом не помогут ему реализоваться.</string> + <string name="tap_faq3">Третий раз? На самом деле можно было бы писать эмулятор tap, основанные на tun, который бы добавлял информацию 2 уровня при отправке и извлекал бы ее при получении. Но этот эмулятор потребует также ARP и, возможно, клиента DHCP. Я не знаю никого, кто мог бы этим заняться. Свяжитесь со мной, если вы хотите заняться этим.</string> + <string name="faq">Вопросы и ответы</string> + <string name="copying_log_entries">Копирование записей лога</string> + <string name="faq_copying">Для копирования одного элемента журнала необходимо нажать и удерживать. Для копирования/передачи всего файла журнала используйте опцию \"Отправить файл журнала\". Используйте hardware кнопку меню, если вы не в графическом интерфейсе.</string> + <string name="faq_shortcut">Ярлык для запуска</string> + <string name="faq_howto_shortcut">Вы можете создать ярлык для запуска OpenVPN на рабочем столе. В зависимости от вашего окружения необходимо добавить ярлык или виджет.</string> + <string name="no_vpn_support_image">Ваша прошивка не поддерживает VPNService API, извините :(</string> + <string name="encryption">Шифрование</string> + <string name="cipher_dialog_title">Укажите метод шифрования</string> + <string name="chipher_dialog_message">Укажите алгоритм шифрования, используемый OpenVPN. Оставьте пустым, чтобы использовать шифрование по-умолчанию.</string> + <string name="auth_dialog_message">Введите the authentication digest для OpenVPN. Оставьте пустым для использования значения по-умолчанию.</string> + <string name="settings_auth">Авторизация/шифрование</string> + <string name="file_explorer_tab">Обзор файлов</string> + <string name="inline_file_tab">Встроенный файл</string> + <string name="error_importing_file">Ошибка при импорте файла</string> + <string name="import_error_message">Не удалось импортировать файл из файловой системы</string> + <string name="inline_file_data">[[Встроенный файл данных]]</string> + <string name="opentun_no_ipaddr">Отказ в открытии устройства tun без информации об IP-адресе</string> + <string name="menu_import">Импорта конфигурации из файла .ovpn</string> + <string name="menu_import_short">Импорт</string> + <string name="import_content_resolve_error">Не удалось прочитать конфигурацию для импорта</string> + <string name="error_reading_config_file">Ошибка чтения файла конфигурации</string> + <string name="add_profile">добавить конфигурацию</string> + <string name="import_could_not_open">Не удалось найти файл %1$s, указанный в файле конфигурации</string> + <string name="importing_config">Импорт файла конфигурации из исходного %1$s</string> + <string name="import_warning_custom_options">Ваша конфигурация имел несколько параметров, которые не входят в параметры стандартной конфигурации. Эти параметры были вынесены в пользовательскую конфигурацию. Пользовательская конфигурация отображается ниже:</string> + <string name="import_done">Файла конфигурации успешно прочитан.</string> + <string name="nobind_summary">Не привязываться к локальному адресу и порту</string> + <string name="no_bind">Не использовать привязки</string> + <string name="import_configuration_file">Импорт файла конфигурации</string> + <string name="faq_security_title">Соображения безопасности</string> + <string name="faq_security">"Так как OpenVPN чувствителен к безопасности, то будут разумными несколько замечаний относительно защиты. Все данные на sd карте по сути не защищены. Каждое приложение может прочесть их (например эта программа не требует специальных привилегий на sd карту). Данные этого приложения могут быть прочитаны только им самим. При использовании опции импорта для cacert/cert/key в диалоговом окне файл, данные сохраняются в VPN профиле. VPN профили доступны только этому приложению. (Потом не забудьте удалить копии на sd карте). Несмотря на то, что данные доступны только этому приложению, они все еще незашифрованы. Путем получения прав администратора (рута) на телефоне или другими эксплойтами возможно извлечь данные. Также сохраненные пароли хранятся в обычном текстовом виде. Настоятельно рекомендуется pkcs12 файлы импортировать в android keystore."</string> + <string name="import_vpn">Импорт</string> + <string name="broken_image_cert_title">Ошибка вывода выбранного сертификата</string> + <string name="broken_image_cert">Произошла ошибка при попытке вызова системного диалога выбора сертификатов Android 4.0+ Этого не должно было случиться на стандартной прошивке. Может быть в вашей прошивке испорчено хранилище сертификатов</string> + <string name="ipv4">IPv4</string> + <string name="ipv6">IPv6</string> + <string name="speed_waiting">Ожидание сообщения о состоянии…</string> + <string name="converted_profile">импортируемый профиль</string> + <string name="converted_profile_i">импортируемый профиль %d</string> + <string name="broken_images">Сломанные прошивки</string> + <string name="broken_images_faq"><p>Извествно, что официальные прошивки HTC имеют странные проблемы с маршрутизацией, приводящей к тому, что трафик не идёт через туннель (см. <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=18\">Issue 18</a> в баг-трекере).</p><p>Также сообщалось, что в старых официальных прошивках SONY от Xperia Arc S и Xperia Ray полностью отсутствует сервис VPNService (см. <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=29\">Issue 29</a> в баг-трекере).</p><p>В некоторых встроенных прошивках модуль tun может отсутствовать или иметь неправильные права на файл устройства /dev/tun. Некоторые CM9 прошивки могут требовать исправлений опции прав в главных настройках.</p><p>И самое главное: Если у вас прошивка с указанными проблемами, сообщите об этом производителю устройства. Чем больше пользователей сообщит о проблеме, тем больше шансов, что этот производитель исправит прошивку.</p></string> + <string name="pkcs12_file_encryption_key">Файл PKCS12-ключа</string> + <string name="private_key_password">Пароль закрытого ключа</string> + <string name="password">Пароль</string> + <string name="file_icon">файл значка</string> + <string name="tls_authentication">TLS-аутентификация</string> + <string name="generated_config">Сгенерированая конфигурация</string> + <string name="generalsettings">Настройки</string> + <string name="owner_fix_summary">Попытаться изменить владельца для /dev/tun. Некоторые прошивки CM9 требуют этого для корректной работы API OpenVPN. Требуется root.</string> + <string name="owner_fix">Исправить права для /dev/tun</string> + <string name="generated_config_summary">Показать сгенерированный файл конфигурации OpenVPN</string> + <string name="edit_profile_title">Правка \"%s\"</string> + <string name="building_configration">Создание конфигурации…</string> + <string name="netchange_summary">Включение этого параметра заставит переподключиться, если состояние сети изменения (WIFI с мобильного)</string> + <string name="netchange">Переподключение при изменении сети</string> + <string name="netstatus">Статус сети: %s</string> + <string name="extracahint">Сертификат CA обычно возвращается из хранилища Android Keystore. Укажите отдельный сертификат, если у вас возникли ошибки при проверке сертификата.</string> + <string name="select_file">Выбрать</string> + <string name="keychain_nocacert">Не удалось получить CA из хранилища ключей Android. Аутентификация не удалась.</string> + <string name="show_log_summary">Показывает окно журнала при подключении. Окно журнала всегда может быть доступно из панели уведомлений.</string> + <string name="show_log_window">Показать окно журнала</string> + <string name="mobile_info">Работает на %1$s (%2$s) %3$s, Android API %4$d</string> + <string name="error_rsa_sign">Ошибка подписи с использованием ключа из хранилища Android %1$s: %2$s</string> + <string name="faq_system_dialogs">Предупреждение VPN соединения сообщает вам, что это приложение может перехватывать весь сетевой трафик, и сообщается системой предупреждений VPNService API.\nИзвещение о VPN соединении (символ \"Ключа\") также формируется системой Android для сигнализации исходящего VPN соединения. В некоторых прошивках это оповещение сопровождается сигналом.\nAndroid использует эти оповещения для вашей собственной безопасности и из нельзя обойти. (К сожалению, на некоторых прошивках также издается оповещение звуком)</string> + <string name="faq_system_dialogs_title">Сообщение о подключении и звук уведомления</string> + <string name="translationby">Русский перевод от RusFox <horonitel@gmail.com></string> + <string name="ipdns">IP-адрес и DNS</string> + <string name="basic">Основные</string> + <string name="routing">Маршрутизация</string> + <string name="obscure">Скрытые параметры OpenVPN. Обычно не требуются.</string> + <string name="advanced">Расширенные</string> + <string name="export_config_title">ICS Openvpn конфигурация</string> + <string name="warn_no_dns">Серверы DNS не используются. Разрешение имен может не работать. Рассмотрите возможность установки пользовательских DNS-серверов. Также обратите внимание, что Android будет продолжать использовать параметры, указанные для вашего мобильного/Wi-Fi соединения, если не указаны DNS-серверы.</string> + <string name="dns_add_error">Не удалось добавить DNS-сервер \"%1$s\", отклонен системой: %2$s</string> + <string name="ip_add_error">Не удалось настроить IP-адрес \"%1$s\", сообщение системы: %2$s</string> + <string name="faq_howto"><p>Используйте готовую конфигурацию (протестированную на вашем компьютере или полученную от вашего провайдера)</p><p>Если это простой файл без pem/pks12 вы можете отправить его по email на свое устройство. Если же это несколько файлов, вы можете использовать их со своей карты памяти.</p><p>Просто кликните на .conf файл или выберите его с помощью меню в программе для импорта конфигурации</p><p>Если программа выдаст ошибку о нехватке некоторых файлов, просто поместите эти файлы на карту памяти</p><p>Нажмите кнопку сохранения для добавления импортируемой конфигурации в программу</p><p>Запустите ваш VPN-тоннель нажав на его название в списке</p><p>Если при запуске возникли ошибки попробуйте разобраться и устранить их.</p> </string> + <string name="faq_howto_title">Быстрый старт</string> + <string name="setting_loadtun_summary">Попробуйте загрузить модуль ядра tun.ko прежде чем пытаться подключиться. Требуется root-доступ на устройстве.</string> + <string name="setting_loadtun">Загрузить tun-модуль</string> + <string name="importpkcs12fromconfig">Импорт PKCS12 из хранилища ключей Android</string> + <string name="getproxy_error">Ошибка при получении параметров прокси-сервера: %s</string> + <string name="using_proxy">Используется прокси-сервер %1$s %2$d</string> + <string name="use_system_proxy">Использовать прокси-сервер системы</string> + <string name="use_system_proxy_summary">Использовать системную конфигурацию прокси HTTP/HTTPS для соединения.</string> + <string name="donatewithpaypal">Вы можете <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;cmd=_s-xclick\">пожертвовать с PayPal</a> </string> + <string name="onbootrestartsummary">OpenVPN будет переподключаться, если он был активен в момент выключения/перезагрузки. Пожалуйста, прочтите FAQ перед тем, как использовать эту настройку.</string> + <string name="onbootrestart">Переподключение после перезагрузки</string> + <string name="ignore">Игнорировать</string> + <string name="restart">Перезапуск</string> + <string name="restart_vpn_after_change">Изменения конфигурации применяются после перезапуска VPN. (Пере)запустить VPN сейчас?</string> + <string name="configuration_changed">Конфигурация изменена</string> + <string name="log_no_last_vpn">Не удалось определить последний используемый профиль для редактирования</string> + <string name="faq_duplicate_notification_title">Дублирующиеся уведомления</string> + <string name="faq_duplicate_notification">Если в Android возникает нехватка оперативной памяти (RAM), ненужные службы и приложения останавливаются. Из-за этого прерывается установленное VPN-соединение. Чтобы избежать этого, приложение нужно запускать с повышенным приоритетом. Для запуска с высоким приоритетом приложение должно вывести предупреждение. Основная иконка приложения будет закреплена наверху панели уведомлений самой системой, как описано в предыдущем вопросе. Она не является собственно уведомлением, это ограничение распространяется на все приложения, запущенные с высоким приоритетом.</string> + <string name="no_vpn_profiles_defined">Профили VPN не указаны.</string> + <string name="add_new_vpn_hint">Используйте <img src=\"ic_menu_add\"/> иконку для добавления нового VPN</string> + <string name="vpn_import_hint">Используйте <img src=\"ic_menu_archive\"/> кнопку для импорта существующих профилей (.ovpn or .conf) с вашей карты памяти.</string> + <string name="faq_hint">Не забудьте заглянуть в FAQ. Также имеется краткое руководство.</string> + <string name="faq_routing_title">Конфигурация маршрутизации/интерфейса</string> + <string name="faq_routing">Настройка интерфейса и маршрутизации происходит не привычными ifconfig/route, а через VPNService API. Это приводит к несколько отличающейся настройке маршрутизации, нежели в других ОС. Конфигурация состоит только из IP туннельного интерфейса и сетей, которые должны быть маршрутизированы через этот туннель. Указание адреса источника и шлюза не требуется. Указывать особые настройки для доступа к VPN-серверу (например, которые задаются в redirect-gateway) тоже не требуются. При импорте конфигурационного файла, эти настройки будут проигнорированы. Приложение использует VPNService API для проверки того, что соединение до сервера не будет проходить через VPN туннель. Маршруты, которые направляют трафик вне туннеля, также не поддерживаются (например route x.x.x.x y.y.y.y net_gateway). Окно лога показывает текущую конфигурацию VPNService во время установки соединения. </string> + <string name="persisttun_summary">Не открывать диалог, когда происходит переподключение VPN.</string> + <string name="persistent_tun_title">Постоянный tun</string> + <string name="openvpn_log">OpenVPN Журнал</string> + <string name="import_config">Импорт конфигурации OpenVPN</string> + <string name="battery_consumption_title">Потребление батареи</string> + <string name="baterry_consumption">В моих тестах, главным источником высокого потребления электроэнергии батареи были keepalive пакеты. Большинство OpenVPN-серверов содержат директиву вроде \'keepalive 10 60\', которая отправляет keepalive-пакет с клиента на сервер и с сервера на клиент каждые 10 секунд. <p> Хоть эти пакеты и маленькие и не расходуют много трафика, они заставляют радиомодуль потреблять много энергии. (см. <a href=\"http://developer.android.com/training/efficient-downloads/efficient-network-access.html#RadioStateMachine\">The Radio State Machine | Android Developers</a>) <p> Настройки keepalive не могут быть изменены на клиенте, это может сделать только системный администратор OpenVPN.lt;pgt; К сожалению, использование keepalive более, чем 60 секунд с UDP, может вносить проблемы с некоторыми типами NAT, которые удаляют информацию о соединении через короткое время (в моем случае, это было 60 секунд). Использование TCP с большим keepalive-таймаутом будет работать, но производительность туннелирования TCP через TCP в сетях с высокой вероятностью потери пакета крайне низкая (см. <a href=\"http://sites.inka.de/bigred/devel/tcp-tcp.html\">Why TCP Over TCP Is A Bad Idea</a>).</string> + <string name="faq_tethering">Тетеринг функция Android (через WiFi, USB или Bluetooth) и VPNService API (используемое этой программой) не работают вместе. Подробней в <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=34\">проблеме №34</a></string> + <string name="vpn_tethering_title">VPN и Tethering</string> + <string name="connection_retries">Попытки подключения</string> + <string name="reconnection_settings">Параметры переподключения</string> + <string name="connectretrymessage">Количество секунд между попытками подключения.</string> + <string name="connectretrywait">Секунд между соединениями</string> + <string name="minidump_generated">OpenVPN завершилась неожиданно. Пожалуйста, посмотрите опцию \"Отправить Minidump\" в главном меню</string> + <string name="send_minidump">Отправить Minidump разработчику</string> + <string name="send_minidump_summary">Отправка отладочной информации разработчику о последнем аварийном завершении</string> + <string name="notifcation_title">OpenVPN - %s</string> + <string name="session_ipv4string">%1$s - %2$s</string> + <string name="session_ipv6string">%1$s - %3$s, %2$s</string> + <string name="state_connecting">Подключение</string> + <string name="state_wait">Ожидание ответа сервера</string> + <string name="state_auth">Проверка подлинности</string> + <string name="state_get_config">Получение конфигурации клиента</string> + <string name="state_assign_ip">Назначение IP-адресов</string> + <string name="state_add_routes">Добавление маршрутов</string> + <string name="state_connected">Подключено</string> + <string name="state_disconnected">Отключиться</string> + <string name="state_reconnecting">Повторное подключение</string> + <string name="state_exiting">Выход</string> + <string name="state_noprocess">Не запущено</string> + <string name="state_resolve">Разрешение имен узлов</string> + <string name="state_tcp_connect">Подключение (TCP)</string> + <string name="state_auth_failed">Ошибка аутентификации</string> + <string name="state_nonetwork">Ожидание работы сети</string> + <string name="statusline_bytecount">↓%2$s/s %1$s - ↑%4$s/s %3$s</string> + <string name="notifcation_title_notconnect">Разъединено</string> + <string name="start_vpn_title">Подключение к VPN %s</string> + <string name="start_vpn_ticker">Подключение к VPN %s</string> + <string name="jelly_keystore_alphanumeric_bug">В некоторых версиях Android 4.1 есть проблемы, если имя сертификата содержит не буквенно-цифровые символы (например, пробелы, подчеркивания или тире). Попробуйте переустановить сертификат без использования специальных символов.</string> + <string name="encryption_cipher">Алгоритм шифрования</string> + <string name="packet_auth">Проверка подлинности пакетов</string> + <string name="auth_dialog_title">Укажите метод проверки подлинности пакетов</string> + <string name="mobile_info_extended">Запущен на %1$s (%2$s) %3$s, Android API %4$d, версии %5$s, %6$s</string> + <string name="built_by">создан %s</string> + <string name="debug_build">сборка для отладки</string> + <string name="official_build">официальная сборка</string> + <string name="make_selection_inline">Скопировать в профиль</string> + <string name="crashdump">Отчет о падении</string> + <string name="add">Добавить</string> + <string name="send_config">Отправить конфигурационный файл</string> + <string name="complete_dn">Полное DN</string> + <string name="remotetlsnote">Импортированнаяе конфигурация использует устаревшую опцию tls-remote которая имеет другой формат DN.</string> + <string name="rdn">RDN (полное имя)</string> + <string name="rdn_prefix">Префикс RDN</string> + <string name="tls_remote_deprecated">tls-remote (УСТАРЕВШЕЕ)</string> + <string name="help_translate">Вы можете улучшить перевод, посетив http://crowdin.net/project/ics-openvpn/invite</string> + <string name="prompt">%1$s пытается управлять %2$s</string> + <string name="remote_warning">Продолжая, вы даете приложению права на управление \"OpenVPN для Android\" и перехват всего сетевого трафика. <b> Не продолжайте, если не доверяете полностью этому приложению. </b> В противном случае вы рискуете утечкой и использованием ваших данных злоумышленниками.</string> + <string name="remote_trust">Я доверяю этому приложению.</string> + <string name="no_external_app_allowed">Нет приложений, авторизованных для внешнего API</string> + <string name="allowed_apps">Авторизованные приложения: %s</string> + <string name="clearappsdialog">Очистить список авторизованных внешних приложений?\nСписок разрешенных приложений:\n\n%s</string> + <string name="screenoff_summary">VPN-соединение приостанавливается, если экран выключен или объем данных меньше 64kb за 60сек. Если включена опция \"Удержание соединения\", VPN-соединение будет постоянно активным. Без этого параметра оно будет приостанавливаться при этих условиях..</string> + <string name="screenoff_title">Приостановить VPN-соединение при выключенном экране</string> + <string name="screenoff_pause">Приостановка соединения при выключенном экране: меньше, чем %1$s за %2$sс</string> + <string name="screen_nopersistenttun">Внимание: постоянный tun не включен для этого VPN. Трафик будет проходить через обычный доступ в Интернет, когда экран выключен.</string> + <string name="save_password">Сохранить пароль</string> + <string name="pauseVPN">Приостановить VPN</string> + <string name="resumevpn">Продолжить VPN</string> + <string name="state_userpause">VPN приостановлен по запросу пользователя</string> + <string name="state_screenoff">VPN приостановлен - выкл. экран</string> + <string name="cannotparsecert">Не удается отобразить сведения о сертификате</string> + <string name="appbehaviour">Поведение приложения</string> + <string name="vpnbehaviour">Поведение VPN</string> + <string name="allow_vpn_changes">Разрешить изменение VPN-профилей</string> + <string name="hwkeychain">Аппаратное хранилище ключей:</string> + <string name="faq_vpndialog43_title">Окно подтверждения VPN для Android 4.3 и позже</string> + <string name="thanks_for_donation">Спасибо за пожертвование %s!</string> + <string name="logCleared">Журнал очищен.</string> + <string name="show_password">Показать пароль</string> + <string name="uploaded_data">Выгружено</string> + <string name="downloaded_data">Загружено</string> + <string name="vpn_status">Статус VPN</string> +</resources> diff --git a/main/src/main/res/values-sv/arrays.xml b/main/src/main/res/values-sv/arrays.xml new file mode 100755 index 00000000..8a451629 --- /dev/null +++ b/main/src/main/res/values-sv/arrays.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string-array name="vpn_types"> + <item>Certifikat</item> + <item>PKCS12 fil</item> + <item>Android certifikat</item> + <item>Användarnamn/lösenord</item> + <item>Statiska nycklar</item> + <item>Användare/PW + certifikat</item> + <item>Användare/PW + PKCS12 </item> + <item>Användare/PW + Android</item> + </string-array> + <string-array name="tls_directions_entries"> + <item>0</item> + <item>1</item> + <item>Ospecificerad</item> + </string-array> + <string-array name="crm_entries"> + <item>No reconnection retries</item> + <item>One reconnection retry</item> + <item>Five reconnection retries</item> + <item>Fifty reconnection retries</item> + <item>Unlimited reconnection retries</item> + </string-array> +</resources> diff --git a/main/src/main/res/values-sv/strings.xml b/main/src/main/res/values-sv/strings.xml new file mode 100755 index 00000000..5c5e4abf --- /dev/null +++ b/main/src/main/res/values-sv/strings.xml @@ -0,0 +1,274 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string name="app">OpenVPN för Android</string> + <string name="address">Serveradress:</string> + <string name="port">Serverport:</string> + <string name="location">Plats</string> + <string name="cant_read_folder">Katalogen kan inte läsas</string> + <string name="select">Välj</string> + <string name="cancel">Avbryt</string> + <string name="no_data">Inga Data</string> + <string name="useLZO">LZO komprimering</string> + <string name="client_no_certificate">Inget certifikat</string> + <string name="client_certificate_title">Klientcertifikat</string> + <string name="client_key_title">Klientcertifikatsnyckel</string> + <string name="client_pkcs12_title">PKCS12 fil</string> + <string name="ca_title">CA-certifikat</string> + <string name="no_certificate">Du måste välja ett certifikat</string> + <string name="copyright_guicode">Källkod och incidenthantering finns på http://code.google.com/p/ics-openvpn/</string> + <string name="copyright_others">Programmet använder följande komponenter, se källkoden för fullständig information om licenser</string> + <string name="about">Om</string> + <string name="vpn_list_title">Profiler</string> + <string name="vpn_type">Typ</string> + <string name="pkcs12pwquery">PKCS12 lösenord</string> + <string name="file_select">Välj…</string> + <string name="file_nothing_selected">Du måste välja en fil</string> + <string name="useTLSAuth">Använd TLS-autentisering</string> + <string name="tls_direction">TLS riktning</string> + <string name="ipv6_dialog_tile">Ange IPv6-adress/Netmask i CIDR Format (t.ex. 2000:dd::23 / 64)</string> + <string name="ipv4_dialog_title">Ange IPv4-adressen/Netmask i CIDR Format (t.ex. 1.2.3.4/24)</string> + <string name="ipv4_address">IPv4-adress</string> + <string name="ipv6_address">IPv6-adress</string> + <string name="custom_option_warning">Ange anpassade OpenVPN alternativ. Använd med försiktighet! Tänk också på att många av de tun relaterade OpenVPN inställningarna inte kan stödjas genom utformningen av VPNSettings. Om du anser att ett viktigt alternativ saknas kontakta författaren</string> + <string name="auth_username">Användarnamn</string> + <string name="auth_pwquery">Lösenord</string> + <string name="static_keys_info">Vid statisk konfiguration används TLS Auth nycklarna som statiska nycklar</string> + <string name="configure_the_vpn">Konfigurera VPN-anslutningen</string> + <string name="menu_add_profile">Lägga till en profil</string> + <string name="add_profile_name_prompt">Ange ett namn som identifierar den nya profilen</string> + <string name="duplicate_profile_name">Vänligen ange ett unikt Profilnamn</string> + <string name="profilename">Profilnamn</string> + <string name="no_keystore_cert_selected">Du måste välja ett användarcertifikat</string> + <string name="no_error_found">Inga fel hittades</string> + <string name="config_error_found">Fel i konfigurationen</string> + <string name="ipv4_format_error">Det går inte att tolka IPv4-adressen</string> + <string name="custom_route_format_error">Det går inte att tolka de anpassade rutterna</string> + <string name="pw_query_hint">(lämna tom för förfrågan vid behov)</string> + <string name="vpn_shortcut">OpenVPN genväg</string> + <string name="vpn_launch_title">Ansluta till VPN</string> + <string name="shortcut_profile_notfound">Profilen som anges i genvägen hittades inte</string> + <string name="random_host_prefix">Slumpmässigt värd-prefix</string> + <string name="random_host_summary">Lägger till 6 slumpmässiga tecken framför hostname</string> + <string name="custom_config_title">Aktivera anpassade alternativ</string> + <string name="custom_config_summary">Ange anpassade inställningar. Använd med försiktighet!</string> + <string name="route_rejected">Rutten avvisades av Android</string> + <string name="cancel_connection">Koppla från</string> + <string name="cancel_connection_long">Koppla från VPN</string> + <string name="clear_log">rensa loggen</string> + <string name="title_cancel">Avbryt bekräftelse</string> + <string name="cancel_connection_query">Koppla från det anslutna VPN/Avbryt anslutningen?</string> + <string name="remove_vpn">Ta bort VPN</string> + <string name="check_remote_tlscert">Kontrollerar om servern använder ett certifikat med TLS server tillägg (--remote-cert-tls server)</string> + <string name="check_remote_tlscert_title">Förvänta TLS servercertifikat</string> + <string name="remote_tlscn_check_summary">Verifierar Remote Server Certificate Subject DN</string> + <string name="remote_tlscn_check_title">Certifikat Hostname kontroll</string> + <string name="enter_tlscn_dialog">Ange den kontroll som används för att verifiera Fjärrcertifikat DN (e.g. C=DE, L=Paderborn, OU=Avian IP Carriers, CN=openvpn.blinkt.de)\n\nSpecificera en komplett DN eller RDN (openvpn.blinkt.de i exemplet) eller ett RDN prefix för verifiering.\n\nOm RDN prefix används matchar \"Server\" både \"Server-1\" och \"Server-2\" \n\nLämnas textfältet tomt matchas RDN mot server hostname.\n\nFor mer information se OpenVPN 2.3.1+ manpage under —verify-x509-name</string> + <string name="enter_tlscn_title">Fjärrcertifikats ämne</string> + <string name="tls_key_auth">Aktiverar TLS Key Authetication</string> + <string name="tls_auth_file">TLS Auth fil</string> + <string name="pull_on_summary">Begär IP-adresser, rutter och tidsalternativ från servern.</string> + <string name="pull_off_summary">Ingen information begärs från servern. Inställningar behöver specificeras nedan.</string> + <string name="use_pull">Hämta inställningar</string> + <string name="dns">DNS</string> + <string name="override_dns">Använd DNS-inställningarna från servern</string> + <string name="dns_override_summary">Använda dina egen DNS-servrar</string> + <string name="searchdomain">searchDomain</string> + <string name="dns1_summary">DNS-Server som ska användas.</string> + <string name="dns_server">DNS-server</string> + <string name="secondary_dns_message">Sekundära DNS-servern används om den normala DNS-servern inte kan nås.</string> + <string name="backup_dns">Sekundär DNS-Server</string> + <string name="ignored_pushed_routes">Ignorera tilldelade rutter</string> + <string name="ignore_routes_summary">Ignorera rutter tilldelade av servern.</string> + <string name="default_route_summary">Omdirigerar all trafik över VPN-anslutningen</string> + <string name="use_default_title">Använd standardrutt</string> + <string name="custom_route_message">Ange anpassade rutter. Skriv destination i CIDR-format. \"10.0.0.0/8 2002:: / 16\" dirigerar nätverk 10.0.0.0/8 och 2002:: / 16 över VPN.</string> + <string name="custom_routes_title">Anpassade rutter</string> + <string name="log_verbosity_level">Utförlighetsnivå för log</string> + <string name="float_summary">Tillåter autentiserade paket från alla IP-adresser</string> + <string name="float_title">Tillåt flytande server</string> + <string name="custom_options_title">Anpassade alternativ</string> + <string name="edit_vpn">Redigera VPN-inställningar</string> + <string name="remove_vpn_query">Ta bort VPN-profilen \'%s\'?</string> + <string name="tun_error_helpful">På vissa anpassade ICS ROM kan behörigheten på /dev/tun vara fel eller så kan tun modulen saknas helt. För CM9 ROM prova alternativet fixa ägande under allmänna inställningar</string> + <string name="tun_open_error">Det gick inte att öppna tun gränssnittet</string> + <string name="error">"Fel:"</string> + <string name="clear">Klart</string> + <string name="last_openvpn_tun_config">Öppnar tun gränssnittet:</string> + <string name="local_ip_info">Lokal IPv4: %1$s/%2$d IPv6: %3$s MTU: %4$d</string> + <string name="dns_server_info">DNS-Server: %1$s, Domän: %2$s</string> + <string name="ip_not_cidr">Fick gränssnitts informationen %1$s och %2$s, förutsätter att andra adressen är peer adressen på fjärrservern. Använder nätmask /32 för lokal IP. Satus på OpenVPN är \"%3$s\".</string> + <string name="route_not_cidr">Förstår inte %1$s och %2$s som IP rutt med CIDR netmask, där /32 används som nätmask.</string> + <string name="route_not_netip">Korrigerad rutt %1$s/%2$s till %3$s/%2$s</string> + <string name="keychain_access">Åtkomst nekas till certifikat i Android nyckelring. Detta kan orsakas av en firmware-uppgradering eller en återställning från säkerhetskopia av app/app inställningar. Vänligen redigera VPN och välj på nytt certifikatet under grundinställningar för att återskapa åtkomstbehörigheten till certifikatet.</string> + <string name="version_info">%1$s %2$s</string> + <string name="send_logfile">Skicka loggfilen</string> + <string name="send">Skicka</string> + <string name="ics_openvpn_log_file">ICS OpenVPN loggfil</string> + <string name="copied_entry">Kopierade loggpost till klippboken</string> + <string name="tap_mode">Tap-läge</string> + <string name="faq_tap_mode">Tap-läge är inte möjligt med icke root VPN-API. Därför kan inte denna applikation stödja tap-läge</string> + <string name="tap_faq2">Igen? Skämtar du? Nej, tap-läge stöds verkligen inte och det hjälper inte att skicka fler mail och fråga om det kommer att stödjas i framtiden.</string> + <string name="tap_faq3">En tredje gång? Man skulle kunda skriva en tap-emulator baserat på tun som skulle lägga till layer2 information vid skicka och ta bort layer2 information vid ta emot. Men denna tap emulator skulle också behöva implementera ARP och eventuellt också en DHCP-klient. Jag är inte medveten om att någon gjort något arbete i denna riktning. Kontakta mig om du vill börja koda på detta.</string> + <string name="faq">FAQ</string> + <string name="copying_log_entries">Kopierar loggposter</string> + <string name="faq_copying">För att kopiera en enda logg post tryck och håll på loggposten. Om du vill kopiera/skicka hela loggen använd alternativet Skicka loggen. Använd hårdvarumenyknappen om menyn inte syns i GUI.</string> + <string name="faq_shortcut">Genväg för att starta</string> + <string name="faq_howto_shortcut">Du kan placera en genväg för att starta OpenVPN på skrivbordet. Beroende på ditt hemskärmsprogram måste du lägga till antingen en genväg eller en widget.</string> + <string name="no_vpn_support_image">Din ROM stöder inte VPNService API, ledsen :(</string> + <string name="encryption">Kryptering</string> + <string name="cipher_dialog_title">Ange krypteringsmetod</string> + <string name="auth_dialog_message">Ange den autentiserings digest som används för OpenVPN. Lämna tom för att använda standard digest.</string> + <string name="settings_auth">Autentisering/kryptering</string> + <string name="file_explorer_tab">Filutforskare</string> + <string name="inline_file_tab">Inline-fil</string> + <string name="error_importing_file">Fel vid import av fil</string> + <string name="import_error_message">Kunde inte importera filen från filsystemet</string> + <string name="inline_file_data">[[Inline-fil data]]</string> + <string name="opentun_no_ipaddr">Vägrar att öppna tun enhet utan IP-information</string> + <string name="menu_import">Importera profil från ovpn fil</string> + <string name="menu_import_short">Import</string> + <string name="import_content_resolve_error">Kunde inte läsa profil att importera</string> + <string name="error_reading_config_file">Fel vid läsning av konfigurationsfil</string> + <string name="add_profile">lägg till profil</string> + <string name="import_could_not_open">Kunde inte hitta filen %1$s som omnämns i den importerade konfigurationsfilen</string> + <string name="importing_config">Importerar konfigurationsfilen från %1$s</string> + <string name="import_warning_custom_options">Din konfiguration hade några konfigurationsalternativ som inte är kopplade till UI konfigurationer. Dessa alternativ lades till som anpassade konfigurationsalternativ. Den anpassade konfigurationen visas nedan:</string> + <string name="import_done">Färdig med att läsa konfigurationsfilen.</string> + <string name="nobind_summary">Bind inte till lokal adress och port</string> + <string name="no_bind">Ingen lokal bindning</string> + <string name="import_configuration_file">Importera konfigurationsfil</string> + <string name="faq_security_title">Säkerhetsaspekter</string> + <string name="faq_security">"Eftersom OpenVPN är säkerhets känslig kan några om säkerhet vara vettiga. Alla data på sd-kortet är potentiellt osäkra. Varje app kan läsa datan (till exempel kräver detta program inga särskilda sd-korts rättigheter). Datat som tillhör denna applikation kan endast läsas av applikationen själv. Genom att använda alternativet import för cacerts/cert/nyckel i fildialogrutan lagras datat i VPN-profilen. VPN-profiler kan bara läsas av denna applikation. (Glöm inte att ta bort kopiorna på sd-kortet efteråt). Även om datat endast är tillgängligt för denna applikation så är data fortfarande okrypterat. Genom att roota telefon eller med andra hack kan det vara möjligt att få åtkomst till datat. Sparade lösenord lagras också i klartext. För pkcs12 filer rekommenderas det starkt att du importerar dem till Android nyckering."</string> + <string name="import_vpn">Import</string> + <string name="broken_image_cert_title">Fel vid visning av certifikatval</string> + <string name="broken_image_cert">Fick ett undantag när Android 4.0+ dialogrutan för val av certifikat försökte visas. Detta bör aldrig ske eftersom detta en standardfunktion hos Android 4.0+. Kanske är stödet för lagring av certifikat i din Android ROM trasigt</string> + <string name="ipv4">IPv4</string> + <string name="ipv6">IPv6</string> + <string name="speed_waiting">Väntar på tillstånds meddelande…</string> + <string name="converted_profile">importerad profil</string> + <string name="converted_profile_i">importerad profil %d</string> + <string name="broken_images">Trasiga ROM</string> + <string name="broken_images_faq">lt;pgt;Officiella HTC ROM är kända för att ha ett konstigt rutt problem som orsakar att trafik inte går genom tunneln (Se även <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=18\">Ärende 18</a> i äredehanteringen.)</p><p>Äldre officiella SONY ROM för Xperia Arc S och Xperia Ray har rapporterats sakna VPNService helt. (Se även <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=29\">Ärende 29</a> i ärendehanteringen.)</p><p>I anpassade/modifierade ROM kan tun modulen saknas eller rättigheterna på /dev/tun kan vara fel. Vissa CM9 ROM behöver alternativet \"Fixa ägande\" under \"Modellanpassade hack\" ikryssat.</p><p>Viktigt: Om du har en trasig ROM, rapportera det till din leverantör. Ju fler människor som rapportera problemet till leverantören desto mer sannolikt är det att det kommer en rättning.</p></string> + <string name="pkcs12_file_encryption_key">Krypteringsnyckel för PKCS12-filen</string> + <string name="private_key_password">Lösenord för privat nyckel</string> + <string name="password">Lösenord</string> + <string name="file_icon">filikon</string> + <string name="tls_authentication">TLS-autentisering</string> + <string name="generated_config">Genererad konfiguration</string> + <string name="generalsettings">Inställningar</string> + <string name="owner_fix_summary">Försöker att sätta ägaren av /dev/tun till system. Vissa CM9 ROM behöver detta för att VPNService API ska fungera. Detta kräver root.</string> + <string name="owner_fix">Fixa ägande av /dev/tun</string> + <string name="generated_config_summary">Visar den genererade OpenVPN-konfigurationsfilen</string> + <string name="edit_profile_title">Redigerar \"%s\"</string> + <string name="building_configration">Bygger konfiguration…</string> + <string name="netchange_summary">Aktivering av detta alternativ kommer att tvinga en återanslutning om nätverksanslutningen ändras (t.ex. WiFi <-> mobildata)</string> + <string name="netchange">Återanslut vid förändring av nätverksanslutning</string> + <string name="netstatus">Nätverksstatus: %s</string> + <string name="extracahint">CA certifikat hämtas vanligtvis från Android Keystore. Ange ett separat certifikat om du får verifieringsfel på certifikatet.</string> + <string name="select_file">Välj</string> + <string name="keychain_nocacert">Inget CA certifikat returnerades från Android Keystore. Autenticering kommer troligen att misslyckas.</string> + <string name="show_log_summary">Visar loggfönstret vid anslutning. Loggfönstret kan alltid nås från statusgardinen.</string> + <string name="show_log_window">Visa loggfönstret</string> + <string name="mobile_info">Kör på %1$s (%2$s) %3$s, Android API %4$d</string> + <string name="error_rsa_sign">Fel vid signering med Android keystore nyckeln %1$s: %2$s</string> + <string name="faq_system_dialogs">Varningen vid VPN-anslutning som berättar att denna app kan avlyssna all trafik utfärdas av systemet för att förhindra missbruk av VPNService API.\nNotifieringen om VPN-anslutning (nyckelsymbolen) tillhandahålles också av Android-systemet för att signalera en pågående VPN-anslutning. På vissa ROM spelar denna notifiering ett ljud.\nAndroid har infört dessa dialogrutor och notifieringar för din egen säkerhet och kan inte undvikas. (På vissa ROM innehåller dessa tyvärr ljud)</string> + <string name="faq_system_dialogs_title">Anslutnings varning och ljud</string> + <string name="translationby">Svensk översättning av Zapp och Mr_Arrow</string> + <string name="ipdns">IP och DNS</string> + <string name="basic">Grundläggande</string> + <string name="routing">Rutter</string> + <string name="obscure">Obskyra OpenVPN inställningar. Behövs normalt inte.</string> + <string name="advanced">Avancerad</string> + <string name="export_config_title">ICS OpenVPN konfiguration</string> + <string name="warn_no_dns">Inga DNS-servrar används. Namnuppslag kommer kanske inte fungera. Överväg att namnge egna DNS-servrar. Observera även att Android kommer att fortsätta att använda dina proxyinställningar som anges för din mobildata/Wi-Fi-anslutning när inga DNS-servrar är konfigurerade.</string> + <string name="dns_add_error">Kunde inte lägga till DNS-servern \"%1$s\", förkastades av systemet: %2$s</string> + <string name="faq_howto"><p>Hämta en fungerande konfiguration (testad på din dator eller nerladdad från din leverantör/organisation)</p><p>Om det är en enda fil utan extra pem/pks12 filer kan du maila den till dig själv och öppna den bifogade filen. Om du har flera filer lägg dem på ditt sd-kort.</p><p>Klicka på den i mailet bifogade filen/Användning mappikonen i VPN-listan för att importera konfigurationsfilen</p><p>Om det ger fel ang. saknade filer lägg dessa på ditt sd-kort.</p><p>Klicka på spara symbolen för att lägga till den importerade konfigurationen i VPN-listan</p><p>Anslut din VPN genom att klicka på konfigurationsnamnet</p><p>Om det finns fel eller varningar i loggen försöka förstå dessa varningar/fel och försök att åtgärda dem</p> </string> + <string name="faq_howto_title">Snabbstart</string> + <string name="setting_loadtun_summary">Prova att ladda kärnmodulen tun.ko innan du försöker ansluta. Kräver root.</string> + <string name="setting_loadtun">Ladda tun modul</string> + <string name="importpkcs12fromconfig">Importera PKCS12 från konfigurationen till Android Keystore</string> + <string name="getproxy_error">Fel vid hämtning av proxyinställningar: %s</string> + <string name="using_proxy">Använder proxy %1$s %2$d</string> + <string name="use_system_proxy">Använd system proxy</string> + <string name="use_system_proxy_summary">Använda systemkonfigurationen för HTTP/HTTPS proxy för att ansluta.</string> + <string name="donatewithpaypal">Du kan <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;cmd=_s-xclick\">donera via PayPal</a> </string> + <string name="onbootrestartsummary">OpenVPN återansluter VPN om den var aktiv vid avstängning/omstart. Läs FAQ om anslutningsvarning innan du använder detta alternativ.</string> + <string name="onbootrestart">Återanslut vid omstart</string> + <string name="ignore">Ignorera</string> + <string name="restart">Starta om</string> + <string name="restart_vpn_after_change">Konfigurationsändringar tillämpas efter omstart av VPN. Starta(om) VPN nu?</string> + <string name="configuration_changed">Konfigurationen ändrades</string> + <string name="log_no_last_vpn">Kunde inte avgöra vilken den sista anslutna profilen var för redigering</string> + <string name="faq_duplicate_notification_title">Dubblerade meddelanden</string> + <string name="faq_duplicate_notification">Om Android tillfälligt har brist på systemminne (RAM), tas program och tjänster som inte behövs just nu bort från aktiva minnet. Detta avslutar en pågående VPN-anslutning. För att se till att pågående anslutning/OpenVPN överlever körs denna tjänst med högre prioritet. För att köra med högre prioritet måste applikationen visa en notifikation. Nyckelikonen visas av systemet, som beskrivs i FAQ tidigare, och räknas inte som ett meddelande som ger rättighet att köra med högre prioritet.</string> + <string name="no_vpn_profiles_defined">Inga VPN-profiler har definierats.</string> + <string name="add_new_vpn_hint">Använd <img src=\"ic_menu_add\"/> ikonen för att lägga till en ny VPN</string> + <string name="vpn_import_hint">Använd <img src=\"ic_menu_archive\"/> ikonen för att importera en befintlig (.ovpn eller .conf) profil från ditt sd-kort.</string> + <string name="faq_hint">Tänk på att titta i FAQ\'n. Där finns en snabbstartguide.</string> + <string name="faq_routing_title">Konfiguration för rutter/gränssnitt</string> + <string name="faq_routing">Rutt och gränssnitts konfiguration görs inte via det traditionella ifconfig/route-kommandot utan med hjälp av VPNService API. Detta resulterar i en anorlunda ruttkonfiguration än på andra operativsystem. Konfigurationen består endast av IP-nummret för tunnel gränssnittet och de nätverk som ska ruttas över gränssnittet. Speciellt behövs ingen särskild peer partner adress eller gateway-adress. Särskilda rutter för att nå VPN-servern (tillagda exempelvis när du använder omdirigering-gateway) behövs inte heller. Applikationen kommer konsekvent att ignorera dessa inställningar när du importerar en konfiguration. Appen säkerställer med hjälp av VPNService API att anslutningen till servern inte ruttas via VPN-tunneln. Eftersom endast specificering av nätverk som ska skickas via tunneln stöds så stöds inte extra rutter som inte pekar på tunneln heller. (t.ex. rutten x.x.x.x y.y.y.y net_gateway). Loggfönstret visar den aktuella konfigurationen för VPNService under upprättandet av en anslutning. </string> + <string name="persisttun_summary">Fall inte tillbaka till ingen VPN-anslutning när OpenVPN återansluter.</string> + <string name="persistent_tun_title">Ihållande tun</string> + <string name="openvpn_log">OpenVPN Log</string> + <string name="import_config">Importera OpenVPN konfiguration</string> + <string name="battery_consumption_title">Batteriförbrukning</string> + <string name="faq_tethering">Funktionen Internetdelning i Android (över WiFi, USB eller Bluetooth) och VPNService API (används av denna applikation) fungerar inte tillsammans. För mer information se <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=34\">ärende #34</a></string> + <string name="vpn_tethering_title">VPN och Internetdelning</string> + <string name="connection_retries">Anslutningsförsök</string> + <string name="reconnection_settings">Inställningar för återanslutning</string> + <string name="connectretrymessage">Antal sekunder att vänta mellan anslutningsförsök.</string> + <string name="connectretrywait">Sekunder mellan anslutningar</string> + <string name="minidump_generated">OpenVPN kraschade oväntat. Försök att använda skicka Minidump alternativet i huvudmenyn</string> + <string name="send_minidump">Skicka Minidump till utvecklare</string> + <string name="send_minidump_summary">Skickar felsökningsinformation om senaste krasch till utvecklare</string> + <string name="notifcation_title">OpenVPN - %s</string> + <string name="session_ipv4string">%1$s - %2$s</string> + <string name="session_ipv6string">%1$s - %3$s, %2$s</string> + <string name="state_connecting">Ansluter</string> + <string name="state_wait">Väntar på svar från servern</string> + <string name="state_auth">Autentiserar</string> + <string name="state_get_config">Hämtar klientkonfiguration</string> + <string name="state_assign_ip">Tilldelar IP-adresser</string> + <string name="state_add_routes">Lägger till rutter</string> + <string name="state_connected">Ansluten</string> + <string name="state_disconnected">Koppla ifrån</string> + <string name="state_reconnecting">Återansluter</string> + <string name="state_exiting">Avslutar</string> + <string name="state_noprocess">Kör inte</string> + <string name="state_resolve">Slår upp värdnamn</string> + <string name="state_tcp_connect">Ansluter (TCP)</string> + <string name="state_auth_failed">Autentisering misslyckades</string> + <string name="state_nonetwork">Väntar på användbart nätverk</string> + <string name="statusline_bytecount">↓%2$s/s %1$s - ↑%4$s/s %3$s</string> + <string name="notifcation_title_notconnect">Inte ansluten</string> + <string name="start_vpn_title">Ansluter till VPN %s</string> + <string name="start_vpn_ticker">Ansluter till VPN %s</string> + <string name="jelly_keystore_alphanumeric_bug">Vissa versioner av Android 4.1 har problem om namnet på keystore certifikatet innehåller icke alfanumeriska tecken (som mellanslag, understreck eller bindestreck). Försök att omimportera certifikatet utan specialtecken</string> + <string name="encryption_cipher">Krypteringschiffer</string> + <string name="packet_auth">Paketautentisering</string> + <string name="auth_dialog_title">Ange autentiseringsmetod för paket</string> + <string name="mobile_info_extended">Kör på %1$s (%2$s) %3$s, Android API %4$d, version %5$s, %6$s</string> + <string name="built_by">byggd av %s</string> + <string name="debug_build">felsöknings bygge</string> + <string name="official_build">officiellt bygge</string> + <string name="make_selection_inline">Kopiera till profil</string> + <string name="crashdump">Crashdump</string> + <string name="add">Lägg till</string> + <string name="send_config">Skicka konfigurationsfilen</string> + <string name="complete_dn">Komplett DN</string> + <string name="remotetlsnote">Din importerade konfiguration innehåller gamla, ej längre i bruk, tls-remote optioner som använder ett annat DN-format.</string> + <string name="rdn">RDN (vanligt namn)</string> + <string name="rdn_prefix">RDN prefix</string> + <string name="tls_remote_deprecated">TLS-remote (ej längre i bruk)</string> + <string name="help_translate">Du kan hjälpa till med översättningen genom att besöka http://crowdin.net/project/ics-openvpn/invite</string> + <string name="prompt">%1$s försöker styra %2$s</string> + <string name="remote_trust">Jag litar på denna applikation.</string> + <string name="no_external_app_allowed">Ingen app får använda externa API</string> + <string name="allowed_apps">Tillåtna apps: %s</string> + <string name="clearappsdialog">Rensa lista över tillåtna externa apps? \nNuvarande lista över tillåtna apps:\n\n%s</string> + <string name="screenoff_title">Pausa VPN-anslutningen efter att skärmen stängts av</string> + <string name="screenoff_pause">Pausa anslutning när skärmen är avstängd: mindre än %1$s i %2$ss</string> + <string name="screen_nopersistenttun">Varning: Permanent tun är inte aktiverat för denna VPN. Trafiken kommer att använda den normala Internet-anslutning när skärmen är avstängd.</string> + <string name="save_password">Spara lösenord</string> +</resources> diff --git a/main/src/main/res/values-sw600dp/dimens.xml b/main/src/main/res/values-sw600dp/dimens.xml new file mode 100644 index 00000000..b83bb856 --- /dev/null +++ b/main/src/main/res/values-sw600dp/dimens.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <bool name="logSildersAlwaysVisible">true</bool> + +</resources>
\ No newline at end of file diff --git a/main/src/main/res/values-sw600dp/styles.xml b/main/src/main/res/values-sw600dp/styles.xml new file mode 100644 index 00000000..de0bb55d --- /dev/null +++ b/main/src/main/res/values-sw600dp/styles.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + + <dimen name="stdpadding">16dp</dimen> + +</resources>
\ No newline at end of file diff --git a/main/src/main/res/values-tr/arrays.xml b/main/src/main/res/values-tr/arrays.xml new file mode 100755 index 00000000..bf5c3e66 --- /dev/null +++ b/main/src/main/res/values-tr/arrays.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string-array name="vpn_types"> + <item>Sertifikalar</item> + <item>PCKCS12 Dosyası</item> + <item>Android Sertifikası</item> + <item>Kullanıcı Adı/Parola</item> + <item>Statik Anahtarlar(Şifre)</item> + <item>Kullanıcı/Parola + Sertifikalar</item> + <item>Kullanıcı/Parola + PKCS12 </item> + <item>Kullanıcı/Parola + Android</item> + </string-array> + <string-array name="tls_directions_entries"> + <item>0</item> + <item>1 +</item> + <item>Belirtilmemiş</item> + </string-array> + <string-array name="crm_entries"> + <item>No reconnection retries</item> + <item>One reconnection retry</item> + <item>Five reconnection retries</item> + <item>Fifty reconnection retries</item> + <item>Unlimited reconnection retries</item> + </string-array> +</resources> diff --git a/main/src/main/res/values-tr/strings.xml b/main/src/main/res/values-tr/strings.xml new file mode 100755 index 00000000..a878dd04 --- /dev/null +++ b/main/src/main/res/values-tr/strings.xml @@ -0,0 +1,310 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string name="app">Android için OpenVPN</string> + <string name="address">Sunucu adresi:</string> + <string name="port">Sunucu Portu:</string> + <string name="location">Konum</string> + <string name="cant_read_folder">Dizin Okunamıyor</string> + <string name="select">Seçin</string> + <string name="cancel">İptal</string> + <string name="no_data">Veri Yok</string> + <string name="useLZO">LZO sıkıştırma</string> + <string name="client_no_certificate">Sertifika yok</string> + <string name="client_certificate_title">İstemci sertifikası</string> + <string name="client_key_title">İstemci sertifika anahtarı</string> + <string name="client_pkcs12_title">PCKCS12 Dosyası</string> + <string name="ca_title">CA Sertifikası</string> + <string name="no_certificate">Bir sertifika seçmelisiniz</string> + <string name="copyright_guicode">Kaynak kodu ve sorun izcisine http://code.google.com/p/ics-openvpn/ buradan ulaşablirsiniz</string> + <string name="copyright_others">Bu program, aşağıdaki bileşenleri kullanır; tam bilgi için lisanslardaki kaynak koduna bakınız</string> + <string name="about">Hakkında +</string> + <string name="vpn_list_title">Profiller</string> + <string name="vpn_type">Tür</string> + <string name="pkcs12pwquery">PKCS12 Şifresi</string> + <string name="file_select">Seçiniz…</string> + <string name="file_nothing_selected">Bir dosya seçmelisiniz</string> + <string name="useTLSAuth">TLS Kimlik Doğrulamasını Kullan</string> + <string name="tls_direction">TLS yönü</string> + <string name="ipv6_dialog_tile">CIDR formatında IPv6 Adresi/Ağ maskesi girin (örneğin 2000:dd::23/64)</string> + <string name="ipv4_dialog_title">IPv4 adresi/ağ maskesi CIDR biçimi (örneğin 1.2.3.4/24) girin</string> + <string name="ipv4_address">IPv4 Adresi</string> + <string name="ipv6_address">IPv6 adresi</string> + <string name="custom_option_warning">Özel OpenVPN seçenekleri girin.Dikkatli kullanın.Ayrıca tun kullanan VPN ler tasarlanan bu program tarafından desteklenmiyor.Eğer özel bir seçenek eksikliği olduğunu düşünüyorsanız geliştirici ile iletişime geçin</string> + <string name="auth_username">Kullanıcı Adı</string> + <string name="auth_pwquery">Şifre</string> + <string name="static_keys_info">Statik yapılandırma için TLS Auth Keys statik anahtar olarak kullanılacak</string> + <string name="configure_the_vpn">VPN\'i Yapılandırın</string> + <string name="menu_add_profile">Profil Ekle</string> + <string name="add_profile_name_prompt">Yeni profili tanımlayan bir isim girin</string> + <string name="duplicate_profile_name">Benzersiz bir profil adı girin</string> + <string name="profilename">Profil Adı</string> + <string name="no_keystore_cert_selected">Kullanıcı sertifikası seçmelisiniz</string> + <string name="no_error_found">Hiçbir hata bulunamadı</string> + <string name="config_error_found">Yapılandırma hatası</string> + <string name="ipv4_format_error">IPv4 adresi ayrıştırma hatası</string> + <string name="custom_route_format_error">Özel yolları ayrıştırma hatası</string> + <string name="pw_query_hint">(Talep üzerine sorgulamak için boş bırakın)</string> + <string name="vpn_shortcut">OpenVPN Kısayolu</string> + <string name="vpn_launch_title">VPN\'e Bağlan</string> + <string name="shortcut_profile_notfound">Kısayolu belirtilen profil bulunamadı</string> + <string name="random_host_prefix">Rastgele host ön eki</string> + <string name="random_host_summary">Host ismine 6 rasgele karakter ekler</string> + <string name="custom_config_title">Özel seçenekleri etkinleştir</string> + <string name="custom_config_summary">Özel seçenekleri belirleyin.Dikkatli kullanın!</string> + <string name="route_rejected">Yol Android tarafından reddedildi</string> + <string name="cancel_connection">Bağlantıyı kes</string> + <string name="cancel_connection_long">VPN bağlantısını kes</string> + <string name="clear_log">Kayıtları temizle</string> + <string name="title_cancel">Onayı İptal et</string> + <string name="cancel_connection_query">Bağlı VPN bağlantısını keseyim / bağlantı girişimini iptal edeyim mi?</string> + <string name="remove_vpn">VPN kaldırın</string> + <string name="check_remote_tlscert">(- Uzak-CERT-tls sunucu) sunucu TLS Sunucu uzantıları ile bir sertifika kullanır olmadığını kontrol eder</string> + <string name="check_remote_tlscert_title">TLS sunucu sertifikasını bekleyin</string> + <string name="remote_tlscn_check_summary">Uzak sunucu sertifika konusunu DN kontrol eder</string> + <string name="remote_tlscn_check_title">Sertifika sunucu adı kontrol</string> + <string name="enter_tlscn_dialog">Uzaktan sertifika DN doğrulamak için kullanılan onay belirtin (örneğin C = DE, L = Paderborn, OU = Kuş IP Taşıyıcılar, CN = openvpn.blinkt.de) \ n \ tam DN veya RDN (openvpn.blinkt.de nBuörnek) ya da doğrulama için bir RDN önek. \ n \ nWhen RDN önek \"Sunucu\" ile \"Sunucu-1\" ve \"Sunucu-2\" ile eşleşir \ n \ boş metin alanına ana bilgisayar adı, sunucu karşı RDN kontrol edecektir nLeaving. \ n \ nBu daha fazla bilgi OpenVPN 2.3.1 + man sayfasına altında-kontrol-x509-adını görmek</string> + <string name="enter_tlscn_title">Uzak sertifika konusu</string> + <string name="tls_key_auth">TLS Anahtar Kimlik Doğrulaması sağlar</string> + <string name="tls_auth_file">TLS Kimlik Doğrulama Dosyası</string> + <string name="pull_on_summary">İstekler IP adresleri, sunucudan yolları ve zamanlama seçenekleri.</string> + <string name="pull_off_summary">Herhangi bir bilgi sunucudan istenir. Ayarlar aşağıda belirtildiği gibidir.</string> + <string name="use_pull">Ayarlarını çekin</string> + <string name="dns">DNS</string> + <string name="override_dns">Sunucusu tarafından DNS ayarları geçersiz</string> + <string name="dns_override_summary">Kendi DNS Sunucularını kullanın</string> + <string name="searchdomain">Arama Etki Alanı</string> + <string name="dns1_summary">DNS Sunucusu kullanılacak.</string> + <string name="dns_server">DNS Serveri</string> + <string name="secondary_dns_message">Ikinci DNS Serveri Kullan Normal DNS Serveri Erişilmezse.</string> + <string name="backup_dns">DNS Sunucusunu Yedekle</string> + <string name="ignored_pushed_routes">Itilmiş rotalar göz ardı</string> + <string name="ignore_routes_summary">Yoksay sunucu tarafından itti yönlendirilir.</string> + <string name="default_route_summary">Tüm trafiği VPN üzerinden kullan</string> + <string name="use_default_title">Varsayılan Yolu kullan</string> + <string name="custom_route_message">Özel yolları girin. CIDR biçimde tek hedef girin. \"10.0.0.0 / 8 2002 :: / 16\" ağlar VPN üzerinden 10.0.0.0 / 8 ve 2002 :: / 16 doğrudan.</string> + <string name="custom_routes_title">Özel Yollar</string> + <string name="log_verbosity_level">Ayrıntı düzeyi Log</string> + <string name="float_summary">Herhangi bir IP kimlik doğrulaması paketlerini sağlar</string> + <string name="float_title">Herhangi bir IP kimlik doğrulaması paketlerini sağlar</string> + <string name="custom_options_title">Özel Seçenekler</string> + <string name="edit_vpn">VPN Ayarlarını düzenle</string> + <string name="remove_vpn_query">VPN profilleri kaldırılsın mı \'%s\'?</string> + <string name="tun_error_helpful">Bazı özel ICS görüntülerde / dev / tun üzerinde izni yanlış olabilir, ya da tun modülünü tamamen eksik olabilir. CM9 görüntüleri genel ayarlar altında düzeltme mülkiyet seçeneğini deneyin</string> + <string name="tun_open_error">Tun arayüzü açılamadı</string> + <string name="error">"Hata:"</string> + <string name="clear">Temizle</string> + <string name="last_openvpn_tun_config">Açılış tun arabirimi:</string> + <string name="local_ip_info">Yerel IPv4: %1$s/%2$d IPv6: %3$s MTU: %4$d</string> + <string name="dns_server_info">DNS sunucusu: %1$s, etki alanı: %2$s</string> + <string name="ip_not_cidr">Arabirim bilgileri %1$s ve %2$s var, tabii ikinci eş adresi uzaktan adresidir. /32 Kullanarak için yerel IP ağ maskesi. OpenVPN tarafından verilen \"%3$s\" modudur.</string> + <string name="route_not_cidr">%1$s ve %2$s olarak IP yolu ile CIDR ağ maskesi, ağ maskesi /32 kullanarak yapamazsınız.</string> + <string name="route_not_netip">Rota %1$s/%2$s %3$s/%2$s için düzeltilmiş</string> + <string name="keychain_access">Android Anahtarlık sertifika erişemiyor. Bu bir yazılım yükseltmesi veya app/app ayarları bir yedeğini geri yükleme tarafından kaynaklanabilir. Lütfen VPN düzenlemek ve sertifikanın sertifika erişim izni yeniden oluşturmak için temel ayarları altında yeniden seçin.</string> + <string name="version_info">%1$s %2$s</string> + <string name="send_logfile">Günlük dosyasını gönder</string> + <string name="send">Gönder</string> + <string name="ics_openvpn_log_file">ICS OpenVPN günlük dosyası</string> + <string name="copied_entry">Panoya kopyalanan günlük girdisi</string> + <string name="tap_mode">Moda dokunun</string> + <string name="faq_tap_mode">Dokunun modu olmayan kök VPN API ile mümkün değildir. Bu nedenle bu uygulama dokunun destek sağlayamaz</string> + <string name="tap_faq2">Yine? Dalga mı geçiyorsun? Hayır, dokunun modu gerçekten desteklenmez ve bu desteklenecektir soran daha fazla posta gönderme değil yardımcı olacaktır.</string> + <string name="tap_faq3">Üçüncü kez? Aslında, bir yazabilirsiniz bir Katman2 bilgi göndermek eklemek ve şerit Katman2 bilgi tun dayalı bir dokunun emülatör alırsınız. Ama bu dokunun emülatör da ARP ve muhtemelen bir DHCP istemci uygulamak gerekir. Herkes bu yönde herhangi bir işi farkında değilim. Bu konuda kodlama başlatmak istiyorsanız bana ulaşın.</string> + <string name="faq">Sık Sorulan Sorular</string> + <string name="copying_log_entries">Günlük girdisi kopyalama</string> + <string name="faq_copying">Bir tek günlük girişi basın kopyalamak ve günlük girdisi üzerinde tutun. Tüm günlük kopyala ve gönderme göndermek günlük seçeneğini kullanın. Görünür değil Eğer GUI donanım menü düğmesini kullanın.</string> + <string name="faq_shortcut">Kısayolları başlatmak için</string> + <string name="faq_howto_shortcut">Masaüstünüzde OpenVPN başlatmak için bir kısayol yerleştirebilirsiniz. Homescreen programınıza bağlı olarak bir kısayol ya da bir widget eklemeniz gerekecek.</string> + <string name="no_vpn_support_image">Görüntü VPNService API desteklemiyor, özür :(</string> + <string name="encryption">Şifreleme</string> + <string name="cipher_dialog_title">Şifreleme yöntemi girin</string> + <string name="chipher_dialog_message">OpenVPN tarafından kullanılan şifreleme algoritmasını girin. Varsayılan şifrelemeyi kullanmak için boş bırakın.</string> + <string name="auth_dialog_message">OpenVPN için kullanılan kimlik doğrulamasını özet girin. Varsayılan özeti kullanmak için boş bırakın.</string> + <string name="settings_auth">Kimlik doğrulama/şifreleme</string> + <string name="file_explorer_tab">Dosya Gezgini</string> + <string name="inline_file_tab">Satır içi dosya</string> + <string name="error_importing_file">Dosya alınırken hata oluştu</string> + <string name="import_error_message">Dosya sistemindeki dosya içe aktarılamadı</string> + <string name="inline_file_data">[[Satır içi dosya veri]]</string> + <string name="opentun_no_ipaddr">IP bilgisi olmadan tun cihazı açmayı reddediyor</string> + <string name="menu_import">Ovpn dosyası alma profili</string> + <string name="menu_import_short">Alma</string> + <string name="import_content_resolve_error">Profil alma için okunamadı</string> + <string name="error_reading_config_file">Yapılandırma dosyası okuma hatası</string> + <string name="add_profile">Profil ekle</string> + <string name="import_could_not_open">Alınan yapılandırma dosyasında belirtilen dosya %1$s bulunamadı</string> + <string name="importing_config">Kaynak %1$s yapılandırma dosyası alma</string> + <string name="import_warning_custom_options">Senin yapılandırma kullanıcı arabirimi yapılandırmaları için eşleştirilmemiş birkaç yapılandırma seçenekleri vardı. Bu seçenekler özel yapılandırma seçenekleri eklenmiştir. Özel yapılandırma aşağıda görüntülenir:</string> + <string name="import_done">Yapılandırma dosyası okuması bitmiş.</string> + <string name="nobind_summary">Yerel adresi ve bağlantı noktası için bağlama yapmak</string> + <string name="no_bind">Hiçbir yerel bağlama</string> + <string name="import_configuration_file">Yapılandırma dosyası al</string> + <string name="faq_security_title">Güvenlik konuları</string> + <string name="faq_security">OpenVPN güvenlik duyarlı olduğu gibi güvenlik hakkında birkaç not mantıklı bulunmaktadır. Sdcard üzerindeki tüm verileri doğal olarak güvensiz. Her app (örneğin bu program herhangi özel bir sd kartı hak gerektirir) okuyabilirsiniz. Bu uygulama verileri yalnızca uygulama tarafından okunabilir. Cacert/cert/anahtarında dosya iletişim kutusu için içe aktarma seçeneğini kullanarak verileri VPN profilinizde saklanır. VPN profilleri yalnızca bu uygulama tarafından erişilebilir. (Daha sonra sd kartta kopyaları sil unutmayın). Bile erişilebilir rağmen bu uygulama tarafından yalnızca verileri hala şifreli değildir. Telefon veya diğer olağanüstü köklenme tarafından veri almak mümkün olabilir. Kurtarmak parola düz metin olarak depolanır. Pkcs12 dosyaları için onları android deposunun almak önerilir.</string> + <string name="import_vpn">Alma</string> + <string name="broken_image_cert_title">Hata gösteren sertifika seçimi</string> + <string name="broken_image_cert">Android 4.0 + göstermeye çalışıyor bir istisna var sertifika seçimi iletişim. Bu hiç bu kadar standart bir özellik olarak Android 4.0 + gerçekleşmesi gerekir. Belki sertifika depolama ortamı için Android ROM destek bozuldu</string> + <string name="ipv4">IPv4</string> + <string name="ipv6">IPv6</string> + <string name="speed_waiting">Durum iletisi bekleniyor…</string> + <string name="converted_profile">içe aktarılan profil</string> + <string name="converted_profile_i">İçe aktarılan profil %d</string> + <string name="broken_images">Kırık görüntüleri</string> + <string name="broken_images_faq"><p> Resmi HTC görüntüleri tünelden değil trafiğe neden garip bir yönlendirme sorunu var için bilinen (Ayrıca bkz: < bir href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=18\" > sorunu 18 </a> hata izci içinde.)</p> <p> büyük resmi SONY Xperia Arc S ve görüntüleri Xperia Ray VPNService tamamen görüntüden eksik bildirilmiştir. (Ayrıca bkz: < bir href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=29\" > sayı 29 </a> hata izci içinde.)</p> <p> ya da eksik/dev haklarını tun modülü olabilir görüntüleri üzerinde özel yapı/tun-ebilmek var olmak yanlış. Bazı CM9 görüntü \"etkin aygıt belirli kesmek\" altında \"mülkiyet saptamak\" seçeneği gerek. </p> <p> en önemlisi: cihazınızda kopuk Android resmi varsa, senin satıcısına bildirin. Daha fazla kişi kim daha onlar bunu </p> düzeltmek için olabilir satıcıya, sorun bildir</string> + <string name="pkcs12_file_encryption_key">PKCS12 Dosya şifreleme anahtarı</string> + <string name="private_key_password">Özel Anahtar Şifresi</string> + <string name="password">Şifre</string> + <string name="file_icon">Dosya simgesi</string> + <string name="tls_authentication">TLS kimlik doğrulama</string> + <string name="generated_config">Oluşturulan yapılandırma</string> + <string name="generalsettings">Ayarlar</string> + <string name="owner_fix_summary">Sisteme /dev/tun sahibi çalışır. Bazı CM9 görüntüleri bu işe VPNService API yapmak gerekir. Kök gerektirir.</string> + <string name="owner_fix">/ Dev / tun sahipliğini düzeltmek</string> + <string name="generated_config_summary">Oluşturulan OpenVPN yapılandırma dosyası göster</string> + <string name="edit_profile_title">\"%s\" düzenleme</string> + <string name="building_configration">Yapılandırma binası…</string> + <string name="netchange_summary">Ağ durumu (örneğin WiFi üzerinden cep telefonlarına/cep) değiştirdiyseniz bu seçeneği açmak yeniden bağlantı zorlar</string> + <string name="netchange">Ağ değişikliği üzerinde yeniden bağlan</string> + <string name="netstatus">Ağ Durumu: %s</string> + <string name="extracahint">Sertifika yetkilisi sertifikası genellikle Android deposunun döndürülür. Sertifika doğrulama hataları alırsanız ayrı bir sertifika belirtin.</string> + <string name="select_file">Seçin</string> + <string name="keychain_nocacert">Hayır CA sertifikasını okurken Android deposunu döndürdü. Kimlik doğrulama muhtemelen başarısız olur.</string> + <string name="show_log_summary">Bağlama kütüğü penceresi üzerinde gösterir. Kütüğü penceresi her zaman bildirim durumu erişilebilir.</string> + <string name="show_log_window">Günlüğü penceresini göster</string> + <string name="mobile_info">%1$s (%2$s) %3$s, Android API %4$d d\'çalışması</string> + <string name="error_rsa_sign">Android deposunun anahtarı %1$s %2$s ile imzalama hatası</string> + <string name="faq_system_dialogs">Bu app tüm trafiği geçirebilir belirten VPN bağlantısı uyarı dayatılan VPNService API.\nThe VPN bağlantısının istismarını önlemek için sistem tarafından bildirim (anahtar simgesi) da devam eden bir VPN bağlantısı sinyal için Android sistem tarafından uygulanmaktadır. Bu bildirim çalış bazı görüntülerde ses. \nAndroid kendi güvenliğiniz için bu sistem diyaloglar tanıttı ve circumenvented olamaz emin oldum. (Bazı görüntülerde bu unfortunely notifciation ses içerir)</string> + <string name="faq_system_dialogs_title">Bağlantı uyarı ve bildirim sesi</string> + <string name="translationby">İngilizce Çeviri: Arne</string> + <string name="ipdns">IP ve DNS</string> + <string name="basic">Temel</string> + <string name="routing">Yönlendiriliyor</string> + <string name="obscure">OpenVPN ayarları belirsiz. Normalde gerekmez.</string> + <string name="advanced">Gelişmiş</string> + <string name="export_config_title">ICS Opnvpn Yapılandırma</string> + <string name="warn_no_dns">Kullanılan DNS sunucusu yok. Ad çözümlemesi çalışmıyor olabilir. Özel DNS sunucularını ayarlamayı düşünün. Ayrıca Android cep/Wi-Fi bağlantınız için DNS sunucusu ayarlandığında belirtilen proxy ayarlarını kullanmaya devam unutmayın.</string> + <string name="dns_add_error">DNS sunucusu sistem tarafından reddedilen %1$s, eklenemedi: %2$s</string> + <string name="ip_add_error">IP adresi \"%1$s\"yapılandırılamadı ,sistem tarafından reddedildi: %2$s</string> + <string name="faq_howto">(bilgisayarınızdaki veya sağlayıcı/organizasyon yüklenebilir test) bir çalışma config <p> olsun </p> <p> Hayır hiçbir ilave pem/pks12 ile tek bir dosya dosyaları ise dosyayı kendiniz e-posta ve eki açın. Birden çok dosya varsa koymak onları üstünde senin sd kartı </p> <p> e-posta eki/kullanım üzerinde klasör simgesini tıklatın, sd eksik dosyaları koyun dosyaları eksik hakkında hatalar varsa config dosyasının </p> <p> almak için vpn listedeki kayıt tıklayın kartı </p> <p> sembol alınan VPN </p> VPN listenize eklemek için <p > VPN varsa hata veya uyarılar günlüğüne uyarı/hata anlamak ve onları </p> gidermek çalışın VPN </p> <p> adını tıklatarak bağlanmak </string> + <string name="faq_howto_title">Hızlı Başlangıç</string> + <string name="setting_loadtun_summary">Bağlanmadan önce tun.ko yüklemeyi deneyin.Root edilmiş cihazlar gerekli.</string> + <string name="setting_loadtun">Tun modülünü yükle</string> + <string name="importpkcs12fromconfig">PKCS12 yapılandırma Android deposunun içine alma</string> + <string name="getproxy_error">Proxy ayarları alınırken hata oluştu: %s</string> + <string name="using_proxy">Proxy %1$s %2$d kullanarak</string> + <string name="use_system_proxy">Sistem proxy kullan</string> + <string name="use_system_proxy_summary">Sistem geniş yapılandırma HTTP/HTTPS proxy için bağlanmak için kullanın.</string> + <string name="donatewithpaypal">Şunları yapabilirsiniz <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;cmd=_s-xclick\">PayPal ile bağış </a> </string> + <string name="onbootrestartsummary">Sistem yeniden başlatma/kapatma üzerinde etkin OpenVPN bir VPN yeniden bağlanır. Bu seçeneği kullanmadan önce bağlantı uyarı SSS okuyun.</string> + <string name="onbootrestart">Yeniden başlatmada tekrar bağlan</string> + <string name="ignore">Yoksay</string> + <string name="restart">Yeniden Başlat</string> + <string name="restart_vpn_after_change">Yapılandırma değişiklikleri, VPN yeniden başlattıktan sonra geçerli olur. (Yeniden) VPN şimdi başlıyorsun?</string> + <string name="configuration_changed">Yapılandırma değişti</string> + <string name="log_no_last_vpn">Düzenleme için son bağlı profil belirlenemedi</string> + <string name="faq_duplicate_notification_title">Yinelenen bildirimler</string> + <string name="faq_duplicate_notification">Android sistem belleği (RAM) basınç altında ise, apps ve hizmet hangi anda gerekli değildir aktif bellekten kaldırılır. Bu devam eden bir VPN bağlantısını sonlandırır. Bağlantı/OpenVPN ile daha yüksek öncelikli hizmet çalışır hayatta emin olmak için. Daha yüksek öncelik ile çalıştırmak için uygulama bir bildirim görüntülemeniz gerekir. Anahtar bildirim simgesini, önceki SSS girdisi içinde açıklandığı gibi sistem tarafından uygulanmaktadır. Daha yüksek öncelik ile çalışan amaç için app bildirim olarak sayılmaz.</string> + <string name="no_vpn_profiles_defined">Tanımlanan VPN profili yok.</string> + <string name="add_new_vpn_hint">Kullanım < img src = \"ic_menu_add\" / > yeni bir VPN eklemek için simge</string> + <string name="vpn_import_hint">Kullanım < img src = \"ic_menu_archive\" / > simgesi sdcard (.ovpn veya .conf) bir profili almak için.</string> + <string name="faq_hint">Ayrıca SSS kontrol etmeyi unutmayın. Hızlı Başlangıç Kılavuzu vardır.</string> + <string name="faq_routing_title">Yönlendirme/arabirimi yapılandırması</string> + <string name="faq_routing">Yönlendirme ve arabirim yapılandırma traditionell ifconfig/rota komutu ile ama VPNService API kullanarak bitmiş değil. Diğer işletim sistemleri üzerinde farklı bir yönlendirme yapılandırmasını sonuçlanır. Yapılandırma yalnızca IP tünel arabirimi ve bu arabirim üzerinden yönlendirileceğini ağlar oluşur. Özellikle hiçbir eş ortak adresi ya da ağ geçidi adresi gereklidir. VPN sunucusunun (yönlendirme ağ geçidi kullanarak, örneğin eklendi) ulaşmak için özel yollar da gerekli değil. Uygulama, sonuç olarak bir yapılandırma alırken bu ayarları yoksayar. App VPNService API\'sı ile sunucuya bağlantı VPN tüneli yönlendirilmez sağlar. Tek belirterek üzerinden yönlendirilecek iletişim beri tünel desteklenir ilave rotalar tünele işaret değil olamaz ya desteklenen. (örneğin rota x.x.x.x y.y.y.y net_gateway). Windows\'ta oturum bağlantı kurma üzerine VPNService geçerli yapılandırmasını gösterir. </string> + <string name="persisttun_summary">OpenVPN yeniden bağlamadan zaman VPN bağlantısı değil geri dönüş yap</string> + <string name="persistent_tun_title">Kalıcı tun</string> + <string name="openvpn_log">OpenVPN kayıtları</string> + <string name="import_config">OpenVPN yapılandırması aktar</string> + <string name="battery_consumption_title">Pil tüketimi</string> + <string name="baterry_consumption">Benim kişisel testlerinde yüksek pil tüketimi OpenVPN ana sebebi canlı tutma paketleri var. Bir yapılandırma yönergesi gibi çoğu OpenVPN sunucusu var \' keepalive 10 60 istemci ve sunucu 10 saniyede canlı tutma paketleri alışverişi neden \'. <p> Bunlar süre paketleri küçük ve çok trafik kullanmayın, mobil radyo ağ meşgul ve enerji tüketimini artırır. (Ayrıca bkz: < bir href=\"http://developer.android.com/training/efficient-downloads/efficient-network-access.html#RadioStateMachine\" > Radyo durum makinesi | Android geliştiriciler </a>) <p> Bu canlı tutma ayarı istemcide değiştirilemez. Yalnızca sistem yöneticisinin OpenVPN in ayarı değiştirebilirsiniz. <p> Ne yazık ki 60 saniyeden daha büyük bir canlı tutma ile UDP kullanarak bazı NAT ağ geçitleri işlem zaman aşımı nedeniyle bağlantıyı kesmek neden olabilir. TCP kullanarak uzun canlı tutma zaman aşımı ile çalışır, ancak TCP TCP üzerinden tünel son derece kötü bağlantılarında yüksek paket kaybı ile gerçekleştirir. (Bkz: < bir href=\"http://sites.inka.de/bigred/devel/tcp-tcp.html\" > neden TCP üzerinden TCP A kötü düşünce </a>)</string> + <string name="faq_tethering">Android hayvan zinciri özelliğin (üzerindeki, WiFi, USB veya Bluetooth) ve VPNService (Bu program tarafından kullanılan) API birlikte çalışmayabilir. Daha fazla ayrıntı için bkz: < bir href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=34\" > #34 </a> yayın</string> + <string name="vpn_tethering_title">VPN ve Paylaşım</string> + <string name="connection_retries">Yeniden bağlantı denemesi</string> + <string name="reconnection_settings">Yeniden Bağlanma ayarları</string> + <string name="connectretrymessage">Bağlantı girişimleri arasında beklenecek saniye sayısı.</string> + <string name="connectretrywait">Bağlantılar arasındaki Saniye</string> + <string name="minidump_generated">OpenVPN beklenmedik biçimde düştü. Lütfen ana menüde gönder mini döküm seçeneği kullanmayı düşünün</string> + <string name="send_minidump">Geliştiriciye mini döküm gönder</string> + <string name="send_minidump_summary">Hata ayıklama bilgisini son hatayı geliştiriciye gönder</string> + <string name="notifcation_title">OpenVPN - %s</string> + <string name="session_ipv4string">%1$s - %2$s</string> + <string name="session_ipv6string">%1$s - %3$s, %2$s</string> + <string name="state_connecting">Bağlanıyor</string> + <string name="state_wait">Sunucudan yanıt bekleniyor</string> + <string name="state_auth">Kimlik Doğrulanıyor</string> + <string name="state_get_config">İstemci yapılandırma alınıyor</string> + <string name="state_assign_ip">IP Adresleri Atanıyor</string> + <string name="state_add_routes">Yollar ekleniyor</string> + <string name="state_connected">Bağlanıldı</string> + <string name="state_disconnected">Bağlantıyı kes</string> + <string name="state_reconnecting">Yeniden bağlanıyor</string> + <string name="state_exiting">Çıkılıyor</string> + <string name="state_noprocess">Çalışmıyor</string> + <string name="state_resolve">Ana bilgisayar adları çözümleniyor</string> + <string name="state_tcp_connect">(TCP) Bağlanıyor</string> + <string name="state_auth_failed">Kimlik doğrulaması başarısız</string> + <string name="state_nonetwork">Kullanılabilir ağ için bekleniyor</string> + <string name="statusline_bytecount">↓%2$s/s %1$s - ↑%4$s/s %3$s</string> + <string name="notifcation_title_notconnect">Bağlı değil</string> + <string name="start_vpn_title">%s VPN bağlanıyor</string> + <string name="start_vpn_ticker">%s VPN bağlanıyor</string> + <string name="jelly_keystore_alphanumeric_bug">Sertifika deposunun adını (gibi alanlarda, alt çizgi veya tire) sigara alfasayısal karakterler içeriyorsa, bazı yorum-in Android 4.1 sorunları var. Özel karakter içermeyen sertifika yeniden ithalat çalışın</string> + <string name="encryption_cipher">Şifre şifresi</string> + <string name="packet_auth">Paket kimlik doğrulama</string> + <string name="auth_dialog_title">Paket kimlik doğrulama yöntemini girin</string> + <string name="mobile_info_extended">Çalışan %1$s (%2$s) %3$s, Android API %4$d, sürüm %5$s, %6$s</string> + <string name="built_by">%s tarafından inşa</string> + <string name="debug_build">hata ayıklama yapı</string> + <string name="official_build">resmi yapı</string> + <string name="make_selection_inline">Profili kopyalayın</string> + <string name="crashdump">Crashdump</string> + <string name="add">Ekle</string> + <string name="send_config">Yapılandırma dosyasını gönderin</string> + <string name="complete_dn">Tam DN</string> + <string name="remotetlsnote">Alınan yapılandırmanızı farklı bir DN biçimini kullanan eski kullanım dışı tls-uzaktan seçeneği kullanılır.</string> + <string name="rdn">RDN (ortak ad)</string> + <string name="rdn_prefix">RDN öneki</string> + <string name="tls_remote_deprecated">TLS-uzaktan (kullanım dışı)</string> + <string name="help_translate">Http://crowdin.net/project/ics-openvpn/invite ziyaret ederek çeviri yardımcı olabilir</string> + <string name="prompt">%2$s denetlemek %1$s çalışır</string> + <string name="remote_warning">Devam, tamamen OpenVPN Android için kontrol etmek ve tüm ağ trafiğini kesişmek üzere uygulama izin veriyorsunuz. <b>Yapmak değil uygulama güvenmediğiniz sürece kabul.</b> Aksi takdirde, verilerinizi kötü amaçlı yazılım tarafından tehlikeye sahip riski çalıştırılır.\"</string> + <string name="remote_trust">Bu uygulamaya güveniyorum.</string> + <string name="no_external_app_allowed">Harici API\'yi kullanma izniniz yok</string> + <string name="allowed_apps">Uygulamalar izni: %s</string> + <string name="clearappsdialog">Açıkça izin verilen dış uygulamalar listesini? \nCurrent listesi izin verilen apps:\n\n%s</string> + <string name="screenoff_summary">\"Ekran kapalı iken VPN ve 60\'lar daha az 64 kB transfer verilerde duraklatın. VPN duraklatma \"Kalıcı Tun\" seçeneği etkinleştirildiğinde aygıtınız ağ bağlantısı sayesinde bırakacaktır. \"Kalıcı Tun\" seçeneği olmadan aygıt yok VPN bağlantısı/koruma olacak.</string> + <string name="screenoff_title">Ekran kapandıktan sonra VPN bağlantısını duraklat</string> + <string name="screenoff_pause">Duraklatma bağlantı durumu devre dışı ekran: %1$s %2$ss içinde daha az</string> + <string name="screen_nopersistenttun">Uyarı: kalıcı tun bu VPN için etkin değil. Ekran kapalı iken trafik normal Internet bağlantınızı kullanacak.</string> + <string name="save_password">Parolayı Kaydet</string> + <string name="pauseVPN">VPN duraklatın</string> + <string name="resumevpn">VPN yi çalıştırmaya devam edin</string> + <string name="state_userpause">Kullanıcı isteğiyle VPN duraklatıldı</string> + <string name="state_screenoff">Ekran kapalıyken VPN duraklat</string> + <string name="device_specific">Aygıt özellikleri kesmek</string> + <string name="cannotparsecert">Sertifika bilgilerini görüntüleyemiyor</string> + <string name="appbehaviour">Uygulama davranış</string> + <string name="vpnbehaviour">VPN davranış</string> + <string name="allow_vpn_changes">VPN Profillerinin değiştirilmesine izin ver +</string> + <string name="hwkeychain">Donanım deposu:</string> + <string name="permission_icon_app">Uygulama simgesi Android için OpenVPN kullanmaya çalışıyor</string> + <string name="faq_vpndialog43">"Android 4.3 ile VPN onay başlayan\"overlaying apps\"karşı korunuyor. Bu giriş dokunmaya tepki değil iletişim kutusunda olur. Bindirmeleri kullanan bir uygulama varsa, bu davranışa neden olabilir. Kusurlu bir app temas yazar app bulursanız. Bu sorun tüm VPN uygulamaları Android 4.3 ve daha sonra etkiler. Ayrıca bkz: < bir href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=185\" > sayı 185 <a> ek ayrıntılar için "</string> + <string name="faq_vpndialog43_title">VPN Onayla iletişim Android 4.3 ve üstü</string> + <string name="donatePlayStore">Alternatif olarak Play Store den bağış yapabilirsiniz.</string> + <string name="thanks_for_donation">Bağış için teşekkürler%s!</string> + <string name="logCleared">Kayıtlar temizlendi.</string> + <string name="show_password">Şifreyi göster</string> + <string name="keyChainAccessError">Anahtarlık erişim hatası: %s</string> + <string name="timestamp_short">Kısa</string> + <string name="timestamp_iso">ISO</string> + <string name="timestamps">Zaman damgaları</string> + <string name="timestamps_none">Hiçbiri</string> + <string name="uploaded_data">Yükleme</string> + <string name="downloaded_data">İndirme</string> + <string name="vpn_status">Vpn Durumu</string> + <string name="logview_options">Görünüm seçenekleri</string> + <string name="unhandled_exception">Kural dışı durum: %1$s\n\n%2$s</string> + <string name="unhandled_exception_context">%3$s: %1$s\n\n%2$s</string> + <string name="full_licenses">Lisanslar</string> +</resources> diff --git a/main/src/main/res/values-uk/arrays.xml b/main/src/main/res/values-uk/arrays.xml new file mode 100755 index 00000000..1727e2b2 --- /dev/null +++ b/main/src/main/res/values-uk/arrays.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string-array name="vpn_types"> + <item>Сертифікати</item> + <item>Файл PKCS12</item> + <item>Android сертифікат</item> + <item>Ім’я користувача/Пароль</item> + <item>Статичні ключі</item> + <item>Користувач/Пароль + Сертифікати</item> + <item>Користувач/Пароль + PKCS12 </item> + <item>Користувач/Пароль + Android</item> + </string-array> + <string-array name="tls_directions_entries"> + <item>0</item> + <item>1</item> + <item>Невказано</item> + </string-array> + <string-array name="crm_entries"> + <item>No reconnection retries</item> + <item>One reconnection retry</item> + <item>Five reconnection retries</item> + <item>Fifty reconnection retries</item> + <item>Unlimited reconnection retries</item> + </string-array> +</resources> diff --git a/main/src/main/res/values-uk/strings.xml b/main/src/main/res/values-uk/strings.xml new file mode 100755 index 00000000..eab6a5dc --- /dev/null +++ b/main/src/main/res/values-uk/strings.xml @@ -0,0 +1,276 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string name="app">OpenVPN для Android</string> + <string name="address">Адреса сервера:</string> + <string name="port">Порт сервера:</string> + <string name="location">Розташування</string> + <string name="cant_read_folder">Не вдалося прочитати каталог</string> + <string name="select">Вибрати</string> + <string name="cancel">Скасувати</string> + <string name="no_data">Немає даних</string> + <string name="useLZO">Стиснення LZO</string> + <string name="client_no_certificate">Немає сертифіката</string> + <string name="client_certificate_title">Сертифікат клієнта</string> + <string name="client_key_title">Ключ сертифіката клієнта</string> + <string name="client_pkcs12_title">Файл PKCS12</string> + <string name="ca_title">Сертифікат CA</string> + <string name="no_certificate">Потрібно вибрати сертифікат</string> + <string name="copyright_guicode">Початковий код і відстеження проблем доступні по http://code.google.com/p/ics-openvpn/</string> + <string name="copyright_others">Ця програма використовує такі компоненти; перегляньте вихідний код для повної інформації про ліцензії</string> + <string name="about">Про</string> + <string name="vpn_list_title">Профілі</string> + <string name="vpn_type">Тип</string> + <string name="pkcs12pwquery">Пароль PKCS12</string> + <string name="file_select">Виберіть…</string> + <string name="file_nothing_selected">Слід вибрати файл</string> + <string name="useTLSAuth">Використовувати TLS аутентифікацію</string> + <string name="tls_direction">TLS напрямок</string> + <string name="ipv6_dialog_tile">Введіть адресу IPv6/маску в CIDR форматі (напр., 2000:dd::23/64)</string> + <string name="ipv4_dialog_title">Введіть адресу IPv4/маску в CIDR форматі (напр., 1.2.3.4/24)</string> + <string name="ipv4_address">IPv4-адреса</string> + <string name="ipv6_address">IPv6-адреса</string> + <string name="custom_option_warning">Введіть додаткові параметри OpenVPN. Використовуйте цю можливість з великою обережністю. Якщо ви вважаєте, що відсутній важливий параметр, то зв\'яжіться з автором</string> + <string name="auth_username">Ім\'я користувача</string> + <string name="auth_pwquery">Пароль</string> + <string name="static_keys_info">Для статичної конфігурації ключі авторизації TLS будуть використовуватися як статичні ключі</string> + <string name="configure_the_vpn">Налаштувати VPN</string> + <string name="menu_add_profile">Додати профіль</string> + <string name="add_profile_name_prompt">Введіть ім\'я нового профілю</string> + <string name="duplicate_profile_name">Введіть унікальне ім\'я профілю</string> + <string name="profilename">Ім\'я профілю</string> + <string name="no_keystore_cert_selected">Потрібно вибрати сертифікат користувача</string> + <string name="no_error_found">Помилок не знайдено</string> + <string name="config_error_found">Помилка конфігурації</string> + <string name="ipv4_format_error">Помилка при розборі адреси IPv4</string> + <string name="custom_route_format_error">Помилка аналізу налаштованих маршрутів</string> + <string name="pw_query_hint">(залиште порожнім для запиту на вимогу)</string> + <string name="vpn_shortcut">Ярлик OpenVPN</string> + <string name="vpn_launch_title">Підключення до VPN</string> + <string name="shortcut_profile_notfound">Профіль, вказаний у ярлику, не знайдено</string> + <string name="random_host_prefix">Випадковий префікс вузла</string> + <string name="random_host_summary">Додає 6 випадкових символів перед іменем вузла</string> + <string name="custom_config_title">Увімкнути налаштовувані параметри</string> + <string name="custom_config_summary">Укажіть налаштовувані параметри. Використовуйте з обережністю!</string> + <string name="route_rejected">Маршрут відхилено Андроїдом</string> + <string name="cancel_connection">Від\'єднати</string> + <string name="cancel_connection_long">Відключити VPN</string> + <string name="clear_log">очистити журнал</string> + <string name="title_cancel">Підтвердження скасування</string> + <string name="cancel_connection_query">Відключення активних VPN/скасувати спробу підключення?</string> + <string name="remove_vpn">Видалити VPN</string> + <string name="check_remote_tlscert">Перевіряє, чи є сервер використовує сертифікат з сервера TLS розширень (--remote-cert-tls server)</string> + <string name="check_remote_tlscert_title">Очікувати TLS сертифікат сервера</string> + <string name="remote_tlscn_check_summary">Перевірка DN об\'єкта віддаленого сертифіката</string> + <string name="remote_tlscn_check_title">Перевірка імені вузла сертифікату</string> + <string name="enter_tlscn_dialog">Перемикач способу перевірки DN сертифікату (eg C = DE, L = Paderborn, OU = Avian IP Carriers, CN = openvpn.blinkt.de) \n \nМожливо значення: повний DN, RDN (для прикладу openvpn.blinkt.de) або тільки преффікс RDN для перевірки. \n \nПрі використанні преффікса RDN, наприклад \"Server\", значення будуть \"Server-1\", \"Server-2\" і т.д. \n \nПрі порожньому текстовому полі перевірка проводитиметься по імені хоста. \n \nДля подробиць дивіться керівництво для OpenVPN 2.3.1 +, розділ-verify-x509-name</string> + <string name="enter_tlscn_title">Об\'єкт віддаленого сертифіката</string> + <string name="tls_key_auth">Увімкнути автентифікацію по TLS ключу</string> + <string name="tls_auth_file">Файл авторизації TLS</string> + <string name="pull_on_summary">Запити IP адрес, маршрутів та параметрів часу від сервера.</string> + <string name="pull_off_summary">Не запитувати інформацію від сервера. Параметри необхідно вказати нижче.</string> + <string name="use_pull">Запитувати параметри</string> + <string name="dns">DNS</string> + <string name="override_dns">Переписати параметри DNS від сервера</string> + <string name="dns_override_summary">Використовувати ваші власні DNS сервери</string> + <string name="searchdomain">Домен пошуку</string> + <string name="dns1_summary">DNS сервер для використання.</string> + <string name="dns_server">DNS-сервер</string> + <string name="secondary_dns_message">Вторинний DNS-сервер використовується, якщо нормальний DNS-сервер недоступний.</string> + <string name="backup_dns">Резервний DNS-сервер</string> + <string name="ignored_pushed_routes">Ігнорувати надіслані маршрути</string> + <string name="ignore_routes_summary">Ігнорувати маршрути, надіслані сервером.</string> + <string name="default_route_summary">Перенаправляти увесь трафік через VPN</string> + <string name="use_default_title">Використовувати типовий маршрут</string> + <string name="custom_route_message"> Введіть користувацькі маршрути. Тільки введіть адресу призначення в форматі CIDR. \"10.0.0.0/8 2002::/16\" буде використано для 10.0.0.0/8 і 2002::/16 мереж через VPN.</string> + <string name="custom_routes_title">Власні маршрути</string> + <string name="log_verbosity_level">Рівень деталізації журналу</string> + <string name="float_summary">Дозволити пакети аутентифікації з будь-якої IP-адреси</string> + <string name="float_title">Дозволити \"плаваючий\" сервер</string> + <string name="custom_options_title">Власні параметри</string> + <string name="edit_vpn">Змінити налаштування VPN</string> + <string name="remove_vpn_query">Видалити VPN профіль \'%s\'?</string> + <string name="tun_error_helpful">На деяких користувацьких прошивках ICS права на /dev/tun можуть бути невірними або модуль tun може бути взагалі відсутнім. Для прошивок CM9 спробуйте виправити власника у загальних налаштуваннях</string> + <string name="tun_open_error">Не вдалося відкрити інтерфейс tun</string> + <string name="error">"Помилка: "</string> + <string name="clear">Очистити</string> + <string name="last_openvpn_tun_config">Відкриття tun інтерфейсу:</string> + <string name="local_ip_info">Адреса IPv4: %1$s/%2$d IPv6: %3$s MTU: %4$d</string> + <string name="dns_server_info">DNS-сервер: %1$s, Домен: %2$s</string> + <string name="ip_not_cidr">Отримано інформацію інтерфейсу %1$s і %2$s, друга адреса є віддаленою адресою каналу. Використовується мережева маска /32 для локальної IP-адреси. Режим, встановлений OpenVPN: \"%3$s\".</string> + <string name="route_not_cidr">Неможливо використовувати вирази %1$s і %2$s як маршрут за стандартом CIDR. використовується /32 як маска підмережі.</string> + <string name="route_not_netip">Виправлено маршрут з %1$s/%2$s на %3$s/%2$s</string> + <string name="keychain_access">Не можна отримати доступ до сховища ключів та сертифікатів Андроїд. Це можливо спричинено оновлення прошивки або відновленням резервної копії програми чи її налаштувань. Будь ласка, відредагуйте профіль VPN та заново виберіть сертифікат у основних параметрах для створення доступу до сертифікату.</string> + <string name="version_info">%1$s %2$s</string> + <string name="send_logfile">Надіслати файл журналу</string> + <string name="send">Надіслати</string> + <string name="ics_openvpn_log_file">ICS OpenVPN файл журналу</string> + <string name="copied_entry">Скопійовано запис журналу до буферу обміну</string> + <string name="tap_mode">TAP режим</string> + <string name="faq_tap_mode">TAP режим не можливий в VPN API без рут. З цієї причини цей додаток не може надати підтримку TAP</string> + <string name="tap_faq2">Знову? Жартуєш? Ні, TAP режим дійсно не підтримується і надсилання все більше листів з питаннями чи це буде підтримуватись не допоможе.</string> + <string name="tap_faq3">Втретє? Насправді можна було б написати TAP емулятор на основі TUN який додавав інформацію 2 рівня при відправці і віднімав її при отриманні. Проте для цього TAP емулятора потрібно реалізувати ARP і можливо DHCP клієнта. Я не знаю будь-кого хто міг би цим зайнятися. Зв’яжіться зі мною, якщо ви хочете це зробити.</string> + <string name="faq">ЧаПи</string> + <string name="copying_log_entries">Копіювання записів журналу</string> + <string name="faq_copying">Для копіювання одного запису журналу натисніть і утримуйте цей запис. Щоб скопіювати/надіслати увесь журнал використовуйте параметр Надіслати журнал. Використовуйте апаратну кнопку меню, якщо ви не бачите у графічному інтерфейсі.</string> + <string name="faq_shortcut">Ярлик для запуску</string> + <string name="faq_howto_shortcut">Ви можете розмістити ярлик для запуску OpenVPN на робочому столі. Залежно від програми домашнього екрану ви можете додати ярлик або віджет.</string> + <string name="no_vpn_support_image">Ваша прошивка не підтримує VPNService API, вибачте :(</string> + <string name="encryption">Шифрування</string> + <string name="cipher_dialog_title">Введіть метод шифрування</string> + <string name="auth_dialog_message">Введіть the authentication digest для OpenVPN. Залиште порожнім для використання стандартних значень.</string> + <string name="settings_auth">Автентифікація/Шифрування</string> + <string name="file_explorer_tab">Провідник файлів</string> + <string name="inline_file_tab">Вбудований файл</string> + <string name="error_importing_file">Помилка імпорту файлу</string> + <string name="import_error_message">Не вдалося імпортувати файл із файлової системи</string> + <string name="inline_file_data">[[Вбудований файл даних]]</string> + <string name="opentun_no_ipaddr">Відмова у відкритті пристрою tun без інформації про IP-адресу</string> + <string name="menu_import">Імпорт профілю з ovpn файлу</string> + <string name="menu_import_short">Імпорт</string> + <string name="import_content_resolve_error">Не вдалося прочитати профіль для імпорту</string> + <string name="error_reading_config_file">Помилка читання файлу конфігурації</string> + <string name="add_profile">додати профіль</string> + <string name="import_could_not_open">Не можливо знайти файл %1$s, згаданий у імпортованому файлі конфігурації</string> + <string name="importing_config">Імпорт файлу конфігурації з джерела %1$s</string> + <string name="import_warning_custom_options">Ваша конфігурація мала кілька варіантів конфігурації, які не відображені в інтерфейсі конфігурації. Ці варіанти були додані в якості користувача параметрів конфігурації. Призначена для користувача конфігурація відображається нижче:</string> + <string name="import_done">Файл конфігурації успішно прочитаний.</string> + <string name="nobind_summary">Не прив\'язувати до локальної адреси і порту</string> + <string name="no_bind">Нема локальної прив\'язки</string> + <string name="import_configuration_file">Імпорт файлу конфігурації</string> + <string name="faq_security_title">Вимоги до безпеки</string> + <string name="faq_security">"Так як OpenVPN чутливий до безпеки, то будуть розумними кілька зауважень щодо захисту. Всі дані на sd карті по суті не захищені. Кожний додаток може прочитати їх (наприклад ця програма не вимагає спеціальних привілеїв на sd карту). Дані цього додатка можуть бути прочитані тільки ним самим. При використанні опції імпорту для cacert/cert/key в діалоговому вікні файла, дані зберігаються в VPN профілі. VPN профілі доступні тільки цьому додатку. (Потім не забудьте видалити копії на sd карті). Незважаючи на те, що дані доступні тільки цьому додатку, вони все ще незашифровані. Шляхом отримання прав суперкористувача (root) на телефоні або іншими хитрощами можливо витягти дані. Також збережені паролі зберігаються в звичайному текстовому вигляді. Наполегливо рекомендується pkcs12 файли імпортувати в android сховище ключів. "</string> + <string name="import_vpn">Імпорт</string> + <string name="broken_image_cert_title">Помилка показу вибору сертифіката</string> + <string name="broken_image_cert">Відбулася помилка при спробі виклику системного діалогу вибору сертифікатів Android 4.0 + Цього не повинно було статися на стандартній прошивці. Можливо у вашій прошивці зіпсовано сховище сертифікатів</string> + <string name="ipv4">IPv4</string> + <string name="ipv6">IPv6</string> + <string name="speed_waiting">Очікування повідомлення стану…</string> + <string name="converted_profile">імпортований профіль</string> + <string name="converted_profile_i">імпортований профіль: %d</string> + <string name="broken_images">Пошкоджені зображення</string> + <string name="broken_images_faq"><p> Відомо, що офіційні прошивки HTC мають дивні проблеми з маршрутизацією, викликані тим, що трафік не йде через тунель (див. також <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=18\">Issue 18</a> в баг-трекері) </p> <p> Також повідомлялося, що в офіційних прошивках SONY для Xperia arc S і Xperia Ray повністю відсутній сервіс VPNService. Також інші прошивки від Sony можуть мати такі ж проблеми. (див. також <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=29\">Issue 29</a> в баг-трекері) </p> <p> У деяких вбудованих прошивках модуль tun може бути відсутнім або мати не правильні права файлу-пристрою /dev/tun. Деякі CM9 прошивки можуть вимагати виправлення власника в головних налаштуваннях. </p> <p> Важлива інформація: Якщо у вас прошивка із зазначеними проблемами, повідомте про це виробнику пристрою. Чим більше користувачів повідомить про проблему виробнику, тим більше шансів, що цей виробник зволить прибрати свої недоробки. </p></string> + <string name="pkcs12_file_encryption_key">PKCS12 Ключ шифрування файлу</string> + <string name="private_key_password">Пароль закритого ключа</string> + <string name="password">Пароль</string> + <string name="file_icon">Піктограма файлу</string> + <string name="tls_authentication">Аутентифікація TLS</string> + <string name="generated_config">Згенерована конфігурація</string> + <string name="generalsettings">Параметри</string> + <string name="owner_fix_summary">Спробуйте змінити власника для /dev/tun. Деякі прошивки CM9 вимагають цього для коректної роботи API OpenVPN. Потрібний root.</string> + <string name="owner_fix">Виправити власника /dev/tun</string> + <string name="generated_config_summary">Показує згенерований файл конфігурації OpenVPN</string> + <string name="edit_profile_title">Редагується \"%s\"</string> + <string name="building_configration">Побудова конфігурації…</string> + <string name="netchange_summary">Вмикання цього параметру примусить перепідключитися, якщо стан мережі змінився (напр. Wi-Fi/мобільний інтернет)</string> + <string name="netchange">Перепідключатися при зміні мережі</string> + <string name="netstatus">Статус мережі: %s</string> + <string name="extracahint">Сертифікат СА звичайно повертається з сховища ключів Андроїд. Вкажіть окремий сертифікат, якщо ви отримали помилки при перевірці сертифікату.</string> + <string name="select_file">Вибрати</string> + <string name="keychain_nocacert">Не вдалося отримати СА сертифікат при читанні із сховища ключів Андроїд. Автентифікація не вдалася.</string> + <string name="show_log_summary">Показати вікно журналу при з\'єднанні. Вікно журналу може бути завжди дрступним у панелі сповіщень.</string> + <string name="show_log_window">Показати вікно журналу</string> + <string name="mobile_info">Працює на %1$s (%2$s) %3$s, Android API %4$d</string> + <string name="error_rsa_sign">Помилка підпису з використанням ключа із сховища Андроїд %1$s: %2$s</string> + <string name="faq_system_dialogs">Попередження VPN з\'єднання повідомляє вам, що цей додаток може перехоплювати весь мережевий трафік, і повідомляється системою попереджень VPNService API. \nСповіщення про VPN з\'єднання (символ \"Ключа\") також формується системою Android для сигналізації про вихідне VPN з\'єднання. У деяких прошивках це сповіщення супроводжується сигналом. \nAndroid використовує ці cповіщення для вашої власної безпеки і їх не можна обійти. (На жаль, на деяких прошивках також сповіщення супроводжується звуком)</string> + <string name="faq_system_dialogs_title">Повідомлення про підключення та звук сповіщеня</string> + <string name="translationby">Переклад українською від wvolov</string> + <string name="ipdns">IP-адреса та DNS</string> + <string name="basic">Основне</string> + <string name="routing">Маршрутизація</string> + <string name="obscure">Приховані параметри OpenVPN. Зазвичай не потрібні.</string> + <string name="advanced">Додатково</string> + <string name="export_config_title">ICS Openvpn конфігурація</string> + <string name="warn_no_dns">Жодний DNS сервер не використовується. Дозвіл імен може не працювати. Розгляньте питання про створення користувацьких серверів DNS. Зверніть увагу, що Android буде продовжувати використовувати налаштування проксі-сервера, вказаного для вашого мобільного / Wi-Fi з\'єднання, коли не задано DNS сервери.</string> + <string name="dns_add_error">Не можливо додати DNS-сервер \"%1$s\", відхилено системою: %2$s</string> + <string name="faq_howto"><p> Використовуйте готову конфігурацію (протестовану на вашому комп\'ютері або отриману від вашого провайдера) </p> <p> Якщо це простий файл без pem/pks12 ви можете відправити його по email на свій пристрій. Якщо ж це декілька файлів, ви можете використовувати їх зі своєї карти пам\'яті. </p> <p> Просто натисніть на .сonf файл або виберіть його за допомогою меню в програмі для імпорту конфігурації </p> <p> Якщо програма видасть помилку про брак деяких файлів, просто помістіть ці файли на карту пам\'яті </p> <p> Натисніть Збереження для додавання імпортованої конфігурації в програму </p> <p> Запустіть ваш VPN-тунель, натиснувши на його назву в списку </p> <p> Якщо при запуску виникли помилки спробуйте розібратися і усунути їх. </p></string> + <string name="faq_howto_title">Швидкий старт</string> + <string name="setting_loadtun_summary">Спробуйте завантажити модуль ядра tun.ko перш ніж з\'єднатися. Необхідний пристрій з правами root.</string> + <string name="setting_loadtun">Завантажити tun-модуль</string> + <string name="importpkcs12fromconfig">Імпорт PKCS12 з конфігурації у сховищі ключів Андроїд</string> + <string name="getproxy_error">Помилка отримання параметрів проксі: %s</string> + <string name="using_proxy">Використовується проксі %1$s %2$d</string> + <string name="use_system_proxy">Використовувати системний проксі</string> + <string name="use_system_proxy_summary">Використовувати системну конфігурацію HTTP/HTTPS проксі для з\'єднання.</string> + <string name="donatewithpaypal">Ви можете <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;cmd=_s-xclick\">пожертвувати через PayPal</a> </string> + <string name="onbootrestartsummary">OpenVPN буде перепідключатися, якщо він був активний в момент вимикання/перезавантаження. Будь ласка, прочитайте ЧаП перед тим, як використовувати цей параметр.</string> + <string name="onbootrestart">Перепідключати при перезавантаженні</string> + <string name="ignore">Ігнорувати</string> + <string name="restart">Перезапустити</string> + <string name="restart_vpn_after_change">Після перезапуску VPN застосувати зміни конфігурації. (Пере)запустити VPN тепер?</string> + <string name="configuration_changed">Конфігурація змінена</string> + <string name="log_no_last_vpn">Не вдалося визначити останній підключений профіль для редагування</string> + <string name="faq_duplicate_notification_title">Дублювати сповіщення</string> + <string name="faq_duplicate_notification">Якщо в Android виникає нестача оперативної пам\'яті (RAM), непотрібні служби і програми зупиняються. Через це переривається встановлене VPN-з\'єднання. Щоб уникнути цього, програму потрібно запускати з підвищеним пріоритетом. Для запуску з високим пріоритетом програма повинна вивести попередження. Піктограма ключа сповіщення виводиться системою, як описано в попередньому пункті ЧаП. Це не вважається як програмне сповіщення з метою запуску з вищим пріоритетом.</string> + <string name="no_vpn_profiles_defined">VPN профіль не визначено.</string> + <string name="add_new_vpn_hint">Використовуйте <img src=\"ic_menu_add\"/> піктограму для додання нової VPN</string> + <string name="vpn_import_hint">Використовуйте <img src=\"ic_menu_archive\"/> піктограму для імпорту існуючого (.ovpn or .conf) профілю з вашої карти пам\'яті.</string> + <string name="faq_hint">Не забудьте заглянути у ЧаП. Там також є короткий посібник.</string> + <string name="faq_routing_title">Конфігурація маршрутизації/інтерфейсу</string> + <string name="faq_routing">Маршрутизація та інтерфейс конфігурації не були зроблені через традиційну команду ifconfig, але за допомогою VPNService API. Це призводить до різних маршрутизацій конфігурації ніж на інших операційних систем. Конфігурація складається тільки з IP інтерфейс тунелю і мереж, що має бути перенаправлено на цей інтерфейс. Необхідно особливо немає рівний партнер адреса або адреса шлюзу. Спеціальні маршрути, щоб дістатися до сервера VPN (наприклад, додані при використанні перенаправлення шлюз) або не потрібні. Отже ігнорувати ці параметри під час імпортування конфігурації. Програма гарантує з VPNService API, що підключення до сервера не прямує через VPN-тунель. Оскільки єдині вказані мережі прямують через тунель підтримуються додаткові маршрути без вказання тунелю, який не може бути підтриманий. (наприклад маршруту x.x.x.x y.y.y.y net_gateway). Журнал windows показує поточну конфігурацію VPNService після встановлення з\'єднання. </string> + <string name="persisttun_summary">Не повертатися до жодного VPN з\'єднання, коли OpenVPN перепідключається.</string> + <string name="persistent_tun_title">Стійкість tun</string> + <string name="openvpn_log">Журнал OpenVPN</string> + <string name="import_config">Імпорт конфігурації OpenVPN</string> + <string name="battery_consumption_title">Споживання акумулятора</string> + <string name="baterry_consumption">У моїх особистих тестах основна причина високого споживання батареї OpenVPN є підтримуючі пакети. Більшість OpenVPN сервера мають директиви конфігурації, як \"залишайся в живих 10 60\", які перекладаються як підтримуючий пакет від клієнта до сервера і від сервера до клієнта кожні десять секунд. <p> Хоча ці пакети є невеликими і не використовують багато трафіку, вони тримають мережі мобільного радіозв\'язку зайнятими і збільшвють споживання енергії. (Див. також <a href=\"http://developer.android.com/training/efficient-downloads/efficient-network-access.html#RadioStateMachine\">Радіо State Machine | Android Developers </a>) <p> Цей параметр надсилання пакетів не може бути змінений на клієнті. Тільки системний адміністратор OpenVPN може змінити настройки. <p> На жаль, використання цього параметру більше 60 секунд з UDP має проблеми з деякими шлюзами NAT, які закінчуються стан підключення після короткого тайм-ауту (60 с в моїх тестах). Використання TCP з довгими затримками працює, але має проблему TCP над TCP. (Див. <a href=\"http://sites.inka.de/bigred/devel/tcp-tcp.html\"> Чому TCP над TCP є поганим середовищем</a>)</string> + <string name="faq_tethering">Функція транзитного з\'єднання на Android (через WiFi, USB або Bluetooth) та VPNService API (використовуване цією програмою) не працюють разом. Детальніше в <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=34\"> Issue 34 </a></string> + <string name="vpn_tethering_title">VPN і тетерінг</string> + <string name="connection_retries">Спроб підключення</string> + <string name="reconnection_settings">Налаштування перепідключення</string> + <string name="connectretrymessage">Кількість секунд очікування між спробами підключення.</string> + <string name="connectretrywait">Секунд між підключеннями</string> + <string name="minidump_generated">OpenVPN впав несподівано. Будь ласка, розгляньте використання параметру \"Надіслати Мінідамп\" в головному меню</string> + <string name="send_minidump">Надіслати мінідамп розробнику</string> + <string name="send_minidump_summary">Відправляє налагоджувальну інформацію розробнику про останнє аварійне завершення</string> + <string name="notifcation_title">OpenVPN - %s</string> + <string name="session_ipv4string">%1$s - %2$s</string> + <string name="session_ipv6string">%1$s - %3$s, %2$s</string> + <string name="state_connecting">Підключення</string> + <string name="state_wait">Очікування відповіді сервера</string> + <string name="state_auth">Аутентифікація</string> + <string name="state_get_config">Отримання конфігурації клієнта</string> + <string name="state_assign_ip">Перепризначення IP-адрес</string> + <string name="state_add_routes">Додавання маршрутів</string> + <string name="state_connected">Підключено</string> + <string name="state_disconnected">Від\'єднати</string> + <string name="state_reconnecting">Повторне підключення</string> + <string name="state_exiting">Виходимо</string> + <string name="state_noprocess">Не працює</string> + <string name="state_resolve">Розпізнавання імен вузлів</string> + <string name="state_tcp_connect">Підключення (TCP)</string> + <string name="state_auth_failed">Помилка автентифікації</string> + <string name="state_nonetwork">Очікування на використання мережі</string> + <string name="statusline_bytecount">↓%2$s/s %1$s - ↑%4$s/s %3$s</string> + <string name="notifcation_title_notconnect">Не підключено</string> + <string name="start_vpn_title">Підключення до VPN %s</string> + <string name="start_vpn_ticker">Підключення до VPN %s</string> + <string name="jelly_keystore_alphanumeric_bug">У деяких версіях Android 4.1 є проблеми, якщо ім\'я сертифікату містить не буквено-цифрові символи (наприклад, пробіли, підкреслення або тире). Спробуйте перевстановити сертифікат без використання спеціальних символів.</string> + <string name="encryption_cipher">Алгоритм шифрування</string> + <string name="packet_auth">Пакети автентифікації</string> + <string name="auth_dialog_title">Введіть метод автентифікації пакетів</string> + <string name="mobile_info_extended">Запущено на %1$s (%2$s) %3$s, Android API %4$d, версії %5$s, %6$s</string> + <string name="built_by">побудована по %s</string> + <string name="debug_build">відлагоджувальна збірка</string> + <string name="official_build">Офіційна збірка</string> + <string name="make_selection_inline">Скопіювати в профіль</string> + <string name="crashdump">Звіт про крах</string> + <string name="add">Додати</string> + <string name="send_config">Надіслати файл конфігурації</string> + <string name="complete_dn">Повний DN</string> + <string name="remotetlsnote">Імпортована конфігурація використовує застарілий параметр tls-remote, який має інший формат DN.</string> + <string name="rdn">RDN (загальне ім\'я)</string> + <string name="rdn_prefix">RDN префікс</string> + <string name="tls_remote_deprecated">tls-remote (ЗАСТАРІЛЕ)</string> + <string name="help_translate">Ви можете допомогти в перекладі, відвідавши http://crowdin.net/project/ics-openvpn/invite</string> + <string name="prompt">%1$s спроб контролювати %2$s</string> + <string name="remote_trust">Я довіряю цьому додатку.</string> + <string name="no_external_app_allowed">Не дозволяється використовувати зовнішнє API</string> + <string name="allowed_apps">Дозволенi додатки: %s</string> + <string name="clearappsdialog">Очистити список дозволених зовнішніх програм \nПоточний список дозволених програм:\n\n%s</string> + <string name="screenoff_summary">"Пауза VPN, коли екран вимкнений і менш ніж 64 Кб переданих даних за 60с. Коли „Постійний тун“ увімкнений пауза VPN залишить ваш пристрій без відсутності мережевого підключення. Без параметра „Постійний тун“ пристрій не буде мати ніякого VPN підключення / захисту.</string> + <string name="screenoff_title">Пауза VPN з\'єднання після вимкнення екрану</string> + <string name="screenoff_pause">Призупинення зв\'язку в екрані вимкненого стану: менше %1$s у %2$sс.</string> + <string name="screen_nopersistenttun">Попередження: Постійний тут не увімкнений для цього VPN. Трафік буде використовувати звичайне інтернет-з\'єднання, коли екран вимкнений.</string> + <string name="save_password">Зберегти пароль</string> +</resources> diff --git a/main/src/main/res/values-zh-rCN/arrays.xml b/main/src/main/res/values-zh-rCN/arrays.xml new file mode 100755 index 00000000..04b40210 --- /dev/null +++ b/main/src/main/res/values-zh-rCN/arrays.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string-array name="vpn_types"> + <item>证书</item> + <item>PKCS12 加密文件</item> + <item>Android 证书</item> + <item>用户名/密码</item> + <item>静态密钥</item> + <item>用户名/密码 + 证书</item> + <item>用户名/密码 + PKCS12</item> + <item>用户名/密码 + Android 证书</item> + </string-array> + <string-array name="tls_directions_entries"> + <item>0</item> + <item>1</item> + <item>未指定</item> + </string-array> + <string-array name="crm_entries"> + <item>No reconnection retries</item> + <item>One reconnection retry</item> + <item>Five reconnection retries</item> + <item>Fifty reconnection retries</item> + <item>Unlimited reconnection retries</item> + </string-array> +</resources> diff --git a/main/src/main/res/values-zh-rCN/strings.xml b/main/src/main/res/values-zh-rCN/strings.xml new file mode 100755 index 00000000..a2fb95ce --- /dev/null +++ b/main/src/main/res/values-zh-rCN/strings.xml @@ -0,0 +1,274 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string name="app">OpenVPN for Android</string> + <string name="address">服务器地址:</string> + <string name="port">服务器端口:</string> + <string name="location">地点</string> + <string name="cant_read_folder">无法读取目录</string> + <string name="select">选择</string> + <string name="cancel">取消</string> + <string name="no_data">无数据</string> + <string name="useLZO">LZO 压缩</string> + <string name="client_no_certificate">无客户端证书</string> + <string name="client_certificate_title">客户端证书</string> + <string name="client_key_title">客户端证书密钥</string> + <string name="client_pkcs12_title">PKCS12 文件</string> + <string name="ca_title">CA 证书</string> + <string name="no_certificate">您必须选择一个证书</string> + <string name="copyright_guicode">请前往 http://code.google.com/p/ics-openvpn/ 查看源码或提供问题反馈</string> + <string name="copyright_others">本程序使用以下组件,请在 Licenses 查看源码获取更详细内容。</string> + <string name="about">关于</string> + <string name="vpn_list_title">配置文件</string> + <string name="vpn_type">类型</string> + <string name="pkcs12pwquery">PKCS12 密码</string> + <string name="file_select">请选择...</string> + <string name="file_nothing_selected">您必须选择一个文件</string> + <string name="useTLSAuth">使用 TLS 身份验证</string> + <string name="tls_direction">TLS 方向</string> + <string name="ipv6_dialog_tile">输入 CIDR 格式 IPv6 地址/子网掩码(例如:2000:dd::23/64)</string> + <string name="ipv4_dialog_title">输入 CIDR 格式 IPv4 地址/子网掩码(例如:1.2.3.4/24)</string> + <string name="ipv4_address">IPv4 地址</string> + <string name="ipv6_address">IPv6 地址</string> + <string name="custom_option_warning">请谨慎输入 OpenVPN 的自定义选项。此外请注意许多与 tun 模块有关的 OpenVPN 设置由于系统 VPN 功能的设计而不能得到支持。如果您缺少认为一个很重要的选项,请联系作者。</string> + <string name="auth_username">用户名</string> + <string name="auth_pwquery">密码</string> + <string name="static_keys_info">静态配置中 TLS 身份验证密钥将被用作静态密钥</string> + <string name="configure_the_vpn">配置 VPN</string> + <string name="menu_add_profile">添加配置文件</string> + <string name="add_profile_name_prompt">输入新配置文件名:</string> + <string name="duplicate_profile_name">请输入一个唯一的配置文件名称</string> + <string name="profilename">配置文件名称</string> + <string name="no_keystore_cert_selected">您必须选择一个用户证书</string> + <string name="no_error_found">未找到错误</string> + <string name="config_error_found">配置有错误</string> + <string name="ipv4_format_error">无法解析 IPv4 地址</string> + <string name="custom_route_format_error">无法解析自定义路由</string> + <string name="pw_query_hint">(根据需求留空)</string> + <string name="vpn_shortcut">OpenVPN 快捷方式</string> + <string name="vpn_launch_title">连接至 VPN</string> + <string name="shortcut_profile_notfound">未找到快捷方式中指定的配置文件</string> + <string name="random_host_prefix">随机主机前缀</string> + <string name="random_host_summary">在主机名前添加6个随机字符</string> + <string name="custom_config_title">启用自定义选项</string> + <string name="custom_config_summary">指定自定义选项。小心!</string> + <string name="route_rejected">Android 拒绝了路由</string> + <string name="cancel_connection">断开</string> + <string name="cancel_connection_long">断开连接</string> + <string name="clear_log">清除日志</string> + <string name="title_cancel">取消确认</string> + <string name="cancel_connection_query">断开已连接的 VPN / 取消连接尝试?</string> + <string name="remove_vpn">删除 VPN</string> + <string name="check_remote_tlscert">检查服务器是否使用 TLS 服务器证书</string> + <string name="check_remote_tlscert_title">除了 TLS 服务器</string> + <string name="remote_tlscn_check_summary">检查远程服务器证书的 DN 属性</string> + <string name="remote_tlscn_check_title">证书主机名检查</string> + <string name="enter_tlscn_dialog">勾选此项将验证远程证书的 DN 属性(例:C=DE, L=Paderborn, OU=Avian IP Carriers, CN=openvpn.blinkt.de)\n\n输入完整的 DN 或者 RDN 以便进行验证。\n\nRDN前缀 \"Server\" 可以匹配 \"Server-1\" 以及 \"SERVER-2\"\n\n若留空则将仅验证 RDN 而不验证主机名。\n\n有关更多信息请查看 OpenVPN 2.3.1+ 参考手册的 --verify-x509-name 小节</string> + <string name="enter_tlscn_title">远程证书主题</string> + <string name="tls_key_auth">启用 TLS 密钥认证</string> + <string name="tls_auth_file">TLS 认证文件</string> + <string name="pull_on_summary">从服务器请求 IP 地址、 路由规则和计时选项。</string> + <string name="pull_off_summary">没有从服务器请求信息。设置需要在下方被指定。</string> + <string name="use_pull">Pull 设置</string> + <string name="dns">DNS</string> + <string name="override_dns">覆盖服务器 DNS 设置</string> + <string name="dns_override_summary">使用自定义 DNS 服务器</string> + <string name="searchdomain">搜索域</string> + <string name="dns1_summary">要使用的 DNS 服务器</string> + <string name="dns_server">DNS 服务器</string> + <string name="secondary_dns_message">如果无法达到主 DNS 服务器,要使用辅助 DNS 服务器。</string> + <string name="backup_dns">备用 DNS 服务器</string> + <string name="ignored_pushed_routes">忽略推送路由</string> + <string name="ignore_routes_summary">忽略服务器推送的路由</string> + <string name="default_route_summary">重定向所有流量到VPN</string> + <string name="use_default_title">使用默认路由</string> + <string name="custom_route_message">输入自定义路由。输入 CIDR 格式地址。</string> + <string name="custom_routes_title">自定义路由</string> + <string name="log_verbosity_level">日志详细级别</string> + <string name="float_summary">允许来自任何 IP 的认证数据包</string> + <string name="float_title">允许浮服务器</string> + <string name="custom_options_title">自定义选项</string> + <string name="edit_vpn">编辑 VPN 设置</string> + <string name="remove_vpn_query">移除 VPN 配置文件 \'%s\' 吗?</string> + <string name="tun_error_helpful">在某些自定义 ICS 版本上,/dev/tun 的权限可能会有错误,或者根本就没有该文件。CM9 用户请尝试通过本程序的设置功能修复权限</string> + <string name="tun_open_error">未能打开 tun 模块</string> + <string name="error">错误</string> + <string name="clear">清除</string> + <string name="last_openvpn_tun_config">正在打开 tun 设备:</string> + <string name="local_ip_info">本地 IPv4: %1$s/%2$d IPv6: %3$s MTU: %4$d</string> + <string name="dns_server_info">DNS 服务器: %1$s, 域名: %2$s</string> + <string name="ip_not_cidr">已获得接口信息 %1$s 以及 %2$s,将第二个地址作为远程地址。使用 /32 作为本地掩码。OpenVPN 给出的模式是 \"%3$s\"。</string> + <string name="route_not_cidr">无法将 %1$s 和 %2$s 作为 CIDR 形式的路由,将使用 /32 的子网掩码。</string> + <string name="route_not_netip">纠正路由 %1$s/%2$s 为 %3$s/%2$s</string> + <string name="keychain_access">不能访问 Android 密钥链证书。这可能是由于固件升级或通过还原备份的应用程序/软件设置造成的。请编辑 VPN 配置文件并在基本设置中重新选择证书以重新创建证书访问权限。</string> + <string name="version_info">%1$s %2$s</string> + <string name="send_logfile">发送日志文件</string> + <string name="send">发送</string> + <string name="ics_openvpn_log_file">ICS OpenVPN 日志文件</string> + <string name="copied_entry">日志条目已复制剪贴板</string> + <string name="tap_mode">Tap 模式</string> + <string name="faq_tap_mode">Tap 模式在未 root 的机器上不可用。因此本程序无法提供 tap 模块支持</string> + <string name="tap_faq2">还来? 您在开玩笑嘛? tap 连接模式是不支持的,不要再发邮件问这些问题了。</string> + <string name="tap_faq3">这已经是第三次有人问这个问题了。好吧,虽然确实可以在 TAP 设备上写一个 TAP 模拟器,给发送出去的数据包添加第二层网络头,并去掉收到的数据包中的第二层网络头,但是这个 TAP 模拟器可能还需要实现 ARP 甚至 DHCP 客户端功能。我目前不知道有谁在做这方面的工作。如果你想开展这方面的编码工作的话,请联系我。</string> + <string name="faq">常见问题</string> + <string name="copying_log_entries">复制日志条目</string> + <string name="faq_copying">若要复制单条日志请在相应条目上轻按即可。若要复制/发送全部日志请使用发送日志功能。如果该功能在界面中没有显示,请使用设备原生的菜单按钮。</string> + <string name="faq_shortcut">启动快捷方式</string> + <string name="faq_howto_shortcut">您可以在主屏幕上放置一个 OpenVPN 的快捷方式。这取决于您的主屏幕管理程序,可能是快捷方式,也可能是一个小挂件。</string> + <string name="no_vpn_support_image">很遗憾,您目前的系统不支持 VPN 服务接口</string> + <string name="encryption">加密</string> + <string name="cipher_dialog_title">输入加密方法</string> + <string name="chipher_dialog_message">请输入 OpenVPN 使用的加密算法。留空为默认。</string> + <string name="auth_dialog_message">输入 OpenVPN 使用的认证摘要。留空则使用默认的摘要。</string> + <string name="settings_auth">认证/加密</string> + <string name="file_explorer_tab">文件浏览器</string> + <string name="inline_file_tab">内联文件</string> + <string name="error_importing_file">导入文件出错</string> + <string name="import_error_message">无法导入文件系统文件</string> + <string name="inline_file_data">[[内联文件数据]]</string> + <string name="opentun_no_ipaddr">无 IP 信息,拒绝打开 tun 设备</string> + <string name="menu_import">从 ovpn 文件中导入配置文件</string> + <string name="menu_import_short">导入</string> + <string name="import_content_resolve_error">无法读取要导入的配置文件</string> + <string name="error_reading_config_file">读取配置文件发生出错</string> + <string name="add_profile">添加配置文件</string> + <string name="import_could_not_open">无法找到导入配置文件参考的文件: %1$s</string> + <string name="importing_config">从 %1$s 中导入配置文件</string> + <string name="import_warning_custom_options">您的配置中有几个选项无法解析。这些选项是您自定义添加的。如下所示:</string> + <string name="import_done">读取配置文件完成</string> + <string name="nobind_summary">不关联到本地地址和端口</string> + <string name="no_bind">无本地绑定</string> + <string name="import_configuration_file">导入配置文件</string> + <string name="faq_security_title">安全注意</string> + <string name="faq_security">“OpenVPN 是非常注重安全的,所以在此提供一些安全方面的建议。所有保存在存储卡上的数据都是不安全的,任何应用都可以读取存储卡上的文件,即使这个应用没有‘写入存储卡’的权限也是如此。应用自身的数据只能被应用自己读取。在选择 CA 证书、证书文件或者密钥文件的时候请使用导入功能,这样这些数据就会保存在 OpenVPN 自身的数据文件中,保证不会被其他的应用恶意读取。当然导入证书之后记得要把证书从存储卡上删除掉。不过,虽然这些数据不能被其他应用读取,但是这些数据是明文保存的,如果你的系统是 rooted 的,那么这些数据将能够被任何拥有 root 权限的应用轻松地读取。保存在 OpenVPN 中的密码也是以明文保存的,如果设备被 rooted 了,这些密码也有可能被其他应用恶意读取。强烈建议使用 pkcs12 证书并将证书导入到 Android 自己的证书管理系统里。”</string> + <string name="import_vpn">导入</string> + <string name="broken_image_cert_title">显示证书发生错误</string> + <string name="broken_image_cert">尝试显示 Android 4.0 + 证书选择对话框时出现异常。Android 4.0 以上的系统不可能出现该问题,因为这是标准的系统功能。可能您当前 ROM 中的证书存储已经损坏。</string> + <string name="ipv4">IPv4</string> + <string name="ipv6">IPv6</string> + <string name="speed_waiting">等待状态消息</string> + <string name="converted_profile">已导入配置文件</string> + <string name="converted_profile_i">已导入配置文件 %d</string> + <string name="broken_images">图像已损坏</string> + <string name="broken_images_faq"><p>HTC 的官方固件存在问题,它无法将网络流量转发到隧道接口上(参见(英文网页): <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=18\">Issue 18</a> )</p><p>SONY 的 Xperia arc S 机型和 Xperia Ray 机型的固件上没有包含完整的 Android VPN 服务,其他 Sony 手机的固件可能也存在此问题。(参见(英文网页): <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=29\">Issue 29</a>)</p><p>在一些民间爱好者制作的固件上,可能缺少 /dev/tun 设备,或者 /dev/tun 的权限不正确。一些 CM9 固件需要设置 /dev/tun 的文件属主。.</p><p>重点是,如果你的固件存在问题,请向厂商或者固件制作者报告,如果报告问题的人足够多,就能引起厂商或者固件制作者的注意,他们就会去修复这些问题。</p></string> + <string name="pkcs12_file_encryption_key">PKCS12 文件加密密钥</string> + <string name="private_key_password">私钥密码</string> + <string name="password">密码</string> + <string name="file_icon">文件图标</string> + <string name="tls_authentication">TLS 认证</string> + <string name="generated_config">已生成的配置</string> + <string name="generalsettings">设置</string> + <string name="owner_fix_summary">尝试设定 /dev/tun 的属主为 system。一些 CM9 ROM 需要它以使 VPNService API 工作。本操作需要 root 权限。</string> + <string name="owner_fix">修复 /dev/tun 的权限</string> + <string name="generated_config_summary">显示已生成的 OpenVPN 配置文件</string> + <string name="edit_profile_title">编辑 %s</string> + <string name="building_configration">正在生成配置</string> + <string name="netchange_summary">启用该选项以在网络变化(例如从蜂窝数据到 WiFi)时强制重新连接</string> + <string name="netchange">当转换网络时重新连接</string> + <string name="netstatus">网络状态: %s</string> + <string name="extracahint">Android 密钥库通常会自带 CA 证书。如果您获取的证书发生验证错误,请单独指定一个证书。</string> + <string name="select_file">选择</string> + <string name="keychain_nocacert">在 Android 密钥库中未找到任何 CA 证书。可能验证失败。</string> + <string name="show_log_summary">连接时显示日志窗口。日志窗口可始终从通知栏访问。</string> + <string name="show_log_window">显示日志窗口</string> + <string name="mobile_info">运行 %1$s ( %2$s ) %3$s ,Android API %4$d</string> + <string name="error_rsa_sign">与 Android 密钥库 %1$s 签名时出错: %2$s</string> + <string name="faq_system_dialogs">VPN 连接警告会告诉你有程序正要拦截所有的网络流量,这是为了确保 VPN 服务的 API 不被恶意应用滥用。\nVPN 连接通知(通知栏上的钥匙图标)是 Android 系统内建的,如果当前有 VPN 连接,Android 系统就会自动显示这个通知图标。一些系统上还会在 VPN 连接建立的时候发出提示音。Android 这么做的原因是为了保护你不受恶意应用的欺骗。</string> + <string name="faq_system_dialogs_title">连接警告和通知声音</string> + <string name="translationby">中文翻译:Christopher Meng +<trans@cicku.me></string> + <string name="ipdns">IP 和 DNS 设置</string> + <string name="basic">基本</string> + <string name="routing">路由设置</string> + <string name="obscure">其他 OpenVPN 设置,一般不需要修改。</string> + <string name="advanced">高级设置</string> + <string name="export_config_title">ICS Openvpn 配置</string> + <string name="warn_no_dns">没有正在使用的 DNS 服务器。域名解析可能无法工作。请考虑设置自定义 DNS 服务器</string> + <string name="dns_add_error">无法添加 DNS 服务器 \"%1$s\",%2$s 拒绝了您的操作。</string> + <string name="faq_howto"><p>获取你的 VPN 配置文件,可以是在电脑上正在使用的 OpenVPN 客户端配置文件,也可以向你的 VPN 服务商索取配置文件。</p><p>如果配置文件只有一个,可以把配置文件发到你自己的邮箱然后从手机上下载。如果配置文件有很多个,可以将它们复制到存储卡内。</p><p>从邮件中下载附件,或者在 VPN 列表中点击文件夹图标来导入配置文件。</p><p>如果提示找不到文件,那就将缺失的文件复制到存储卡内。</p><p>点击保存,将配置文件保存到你的 VPN 列表中。</p><p>在 VPN 列表中点击 VPN 的连接的名字,就可以连接到 VPN 了。</p><p>如果发生错误,可以看日志窗口中的日志,然后设法解决问题。</p> </string> + <string name="faq_howto_title">快速入门</string> + <string name="setting_loadtun_summary">尝试在连接之前加载 tun.ko 内核模块。需要 root 权限。</string> + <string name="setting_loadtun">载入 tun 模块</string> + <string name="importpkcs12fromconfig">将 PKCS12 导入 Android 密钥库</string> + <string name="getproxy_error">获取代理设置时出错:%s</string> + <string name="using_proxy">使用代理 %1$s %2$d</string> + <string name="use_system_proxy">使用系统代理</string> + <string name="use_system_proxy_summary">使用系统设置连接 HTTP/HTTPS 代理服务器。</string> + <string name="donatewithpaypal">您可以 <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;cmd=_s-xclick\"> 通过 PayPal 捐助</a></string> + <string name="onbootrestartsummary">OpenVPN 将会在重启后自动重新连接 VPN。请在启用该选项前先阅读连接警告的常见问题解答。</string> + <string name="onbootrestart">重启时重新连接</string> + <string name="ignore">忽略</string> + <string name="restart">重启</string> + <string name="restart_vpn_after_change">配置的变更将在重启 VPN 后生效,是否立即重启?</string> + <string name="configuration_changed">配置已更改</string> + <string name="log_no_last_vpn">无法判断最后一次连接使用的是哪个配置文件,所以无法编辑配置文件</string> + <string name="faq_duplicate_notification_title">重复的通知</string> + <string name="faq_duplicate_notification">当 Android 系统的内存(RAM)即将耗尽的时候,不再需要的应用和服务将被关闭以腾出内存空间,这项机制也会影响到 VPN 进程。为了保证 OpenVPN 及其连接不被关闭,OpenVPN 服务会以较高的优先级运行,而为了以较高的优先级运行,OpenVPN 必须在状态栏显示一个图标。正如前面的问题中说过的,系统的“钥匙”图标是系统内建的,仅仅显示这个“钥匙”图标并不能让 OpenVPN 以更高的优先级运行。</string> + <string name="no_vpn_profiles_defined">没有定义 VPN 配置文件</string> + <string name="add_new_vpn_hint">点击 <img src=\"ic_menu_add\"/> 图标添加新的 VPN 配置</string> + <string name="vpn_import_hint">使用 <img src=\"ic_menu_archive\"/> 图标导入存储卡中已有的配置文件(.ovpn 或 .conf)。</string> + <string name="faq_hint">请确保阅读常见问题解答。这是一个快速向导。</string> + <string name="faq_routing_title">路由/接口配置</string> + <string name="faq_routing">路由表不是使用传统的 ifconfig 或 route 命令来设置的,而是通过 Android 的 VPN 服务的接口来进行设置的,所以路由的设置方法和在其他系统上的有些不同。设置中只需要包含通过隧道设备的 IP 地址以及网络,节点 IP 地址以及网关地址都不需要,指定通往 VPN 服务器的路由信息也不需要。OpenVPN for Android 会忽略配置文件中的这些设置。Android 的 VPN 服务接口保证了通往 VPN 服务器的流量不会被转发到隧道设备上。VPN 支持将通往特定网络的流量转发到隧道上,但不支持不要将通往指定网络的流量转发到隧道接口上(例:route x.x.x.x y.y.y.y net_gateway)。在日志窗口中的“显示连接信息”菜单内可以查看到当前由 Android 的 VPN 服务提供的网络配置信息。</string> + <string name="persisttun_summary">当 OpenVPN 重连时,也一直使用 VPN 连接。</string> + <string name="persistent_tun_title">保持 tun 通道</string> + <string name="openvpn_log">OpenVPN 日志</string> + <string name="import_config">导入 OpenVPN 配置文件</string> + <string name="battery_consumption_title">电池消耗</string> + <string name="baterry_consumption">在我的测试中,发现最能消耗电量的是 OpenVPN 的 keepalive 包。大多数 OpenVPN 服务器都在配置文件中使用了“keepalive 10 60”这样的选项,这会导致 OpenVPN 服务器和客户端每隔 10 秒就相互向对方发送一个数据包。<p>虽然这些包很小,几乎不会消耗多少流量,但是频繁地发送这些包会导致手机的无线模块长时间处于活跃状态,并消耗大量的电能。(请参见(英文网页): <a href=\"http://developer.android.com/training/efficient-downloads/efficient-network-access.html#RadioStateMachine\">)<p> keepalive 选项无法在客户端进行修改,只能在服务器上进行修改。<p>令人郁闷的是,如果发送 keepalive 的频率小于 60 秒,某些 NAT 网关可能会关闭 UDP 连接(我测试得到的结果是 60 秒)。使用 TCP 模式虽然可以将 keepalive 的频率设成很大,但是会造成 TCP over TCP 问题。(请参见(英文网页):<a href=\"http://sites.inka.de/bigred/devel/tcp-tcp.html\">)(TCP over TCP 问题指的是由于 TCP 协议的机制,在 TCP 协议上再次封装一个 TCP 协议时,如果上层 TCP 链路的速度比下层 TCP 协议的链路速度快,就会造成大量 TCP 重传,从而导致网络拥塞,对用户来说就是网络变成龟速 ——译者注)</string> + <string name="faq_tethering">Android 网络分享和便携式热点功能(通过 WiFi, USB 或蓝牙)无法与本程序所使用的 VPN 服务接口一同工作。详情请见 <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=34\">issue #34</a></string> + <string name="vpn_tethering_title">VPN 和中继</string> + <string name="connection_retries">连接重试次数</string> + <string name="reconnection_settings">重新连接设置</string> + <string name="connectretrymessage">每次尝试连接等待时间(秒)。</string> + <string name="connectretrywait">两次连接间隔时间(秒)</string> + <string name="minidump_generated">OpenVPN 意外崩溃。建议您使用主菜单中的发送转储文件功能向开发者发送转储文件</string> + <string name="send_minidump">向开发者发送转储信息</string> + <string name="send_minidump_summary">向开发人员发送上次崩溃的调试信息</string> + <string name="notifcation_title">OpenVPN - %s</string> + <string name="session_ipv4string">%1$s - %2$s</string> + <string name="session_ipv6string">%1$s - %3$s, %2$s</string> + <string name="state_connecting">连接中</string> + <string name="state_wait">等待服务器响应</string> + <string name="state_auth">验证中</string> + <string name="state_get_config">正在获取客户端配置</string> + <string name="state_assign_ip">正在分配 IP 地址</string> + <string name="state_add_routes">添加路由</string> + <string name="state_connected">已连接</string> + <string name="state_disconnected">断开</string> + <string name="state_reconnecting">正在重新连接</string> + <string name="state_exiting">正在退出</string> + <string name="state_noprocess">未运行</string> + <string name="state_resolve">正在解析主机名</string> + <string name="state_tcp_connect">连接中(TCP)</string> + <string name="state_auth_failed">验证失败</string> + <string name="state_nonetwork">等待可用网络</string> + <string name="statusline_bytecount">↓%2$s/s %1$s - ↑%4$s/s %3$s</string> + <string name="notifcation_title_notconnect">未连接</string> + <string name="start_vpn_title">正在连接 VPN %s</string> + <string name="start_vpn_ticker">正在连接 VPN %s</string> + <string name="jelly_keystore_alphanumeric_bug">某些版本的 Android 4.1 存在问题,如果密钥库证书的名称包含非字母和数字字符(如空格、 下划线或短划线)。请尝试重新导入不包含特殊字符的证书</string> + <string name="encryption_cipher">加密算法(cipher)</string> + <string name="packet_auth">数据包验证</string> + <string name="auth_dialog_title">数据包验证方式</string> + <string name="mobile_info_extended">当前运行环境 %1$s (%2$s) %3$s,Android API %4$d,版本 %5$s,%6$s</string> + <string name="built_by">由 %s 构建</string> + <string name="debug_build">调试版本</string> + <string name="official_build">正式版本</string> + <string name="make_selection_inline">复制进配置文件</string> + <string name="crashdump">故障转储</string> + <string name="add">添加</string> + <string name="send_config">发送配置文件</string> + <string name="complete_dn">完整的 DN</string> + <string name="remotetlsnote">您导入的配置包含不再使用的 tls-remote 选项,该选项使用了不同的 DN 格式。</string> + <string name="rdn">RDN (通用名称)</string> + <string name="rdn_prefix">RDN 前缀</string> + <string name="tls_remote_deprecated">tls-remote(不再使用)</string> + <string name="help_translate">你可以通过访问 http://crowdin.net/project/ics-openvpn/invite 来帮助翻译</string> + <string name="prompt">%1$s 正在试图控制 %2$s</string> + <string name="remote_warning">如果继续,你将允许该应用完全控制 OpenVPN for Android,并拦截所有网络流量。<b>除非你信任该应用,否则请不要继续。</b>如果该应用是恶意应用,你需要自行承担所有的后果。</string> + <string name="remote_trust">我信任此应用。</string> + <string name="no_external_app_allowed">没有允许使用外部 API 的应用</string> + <string name="allowed_apps">已授权的应用:%s</string> + <string name="clearappsdialog">清除已授权的应用列表?\n当前已授权的应用:\n\n%s</string> +</resources> diff --git a/main/src/main/res/values-zh-rTW/arrays.xml b/main/src/main/res/values-zh-rTW/arrays.xml new file mode 100755 index 00000000..5cf6a8bd --- /dev/null +++ b/main/src/main/res/values-zh-rTW/arrays.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string-array name="vpn_types"> + <item>證書</item> + <item>PKCS12檔案</item> + <item>Android證書</item> + <item>用戶名稱/密碼</item> + <item>固定金鑰(Static Keys)</item> + <item>用戶名稱/密碼 + 證書</item> + <item>用戶名稱/密碼 + PKCS12檔案</item> + <item>用戶名稱/密碼 + Android</item> + </string-array> + <string-array name="tls_directions_entries"> + <item>0</item> + <item>1</item> + <item>不指定</item> + </string-array> + <string-array name="crm_entries"> + <item>No reconnection retries</item> + <item>One reconnection retry</item> + <item>Five reconnection retries</item> + <item>Fifty reconnection retries</item> + <item>Unlimited reconnection retries</item> + </string-array> +</resources> diff --git a/main/src/main/res/values-zh-rTW/strings.xml b/main/src/main/res/values-zh-rTW/strings.xml new file mode 100755 index 00000000..75f72ecb --- /dev/null +++ b/main/src/main/res/values-zh-rTW/strings.xml @@ -0,0 +1,172 @@ +<?xml version="1.0" encoding="utf-8"?> +<!--Generated by crowdin.net--> +<resources> + <string name="app">OpenVPN for Android</string> + <string name="address">伺服器地址:</string> + <string name="port">伺服器端口:</string> + <string name="location">位置</string> + <string name="cant_read_folder">目法讀取檔案目錄</string> + <string name="select">選擇</string> + <string name="cancel">取消</string> + <string name="no_data">沒有資料</string> + <string name="useLZO">LZO壓縮</string> + <string name="client_no_certificate">沒有證書</string> + <string name="client_certificate_title">客戶端證書</string> + <string name="client_key_title">客戶端證書密碼</string> + <string name="client_pkcs12_title">PKCS12 檔案</string> + <string name="ca_title">CA證書</string> + <string name="no_certificate">您必須選擇一個憑證</string> + <string name="copyright_guicode">取得原始碼與個案追蹤,可上 http://code.google.com/p/ics-openvpn/</string> + <string name="copyright_others">本程序使用了以下元件,其作者和授權資訊如下</string> + <string name="about">關於</string> + <string name="vpn_type">類型</string> + <string name="pkcs12pwquery">PKCS12 密碼</string> + <string name="file_select">選擇…</string> + <string name="file_nothing_selected">你必須選擇一個檔案</string> + <string name="useTLSAuth">使用傳輸層防火牆(TLS-Auth)</string> + <string name="tls_direction">TLS方向</string> + <string name="ipv6_dialog_tile">以CIDR格式輸入IPv6地址/遮罩(例如 2000:dd::23/64)</string> + <string name="ipv4_dialog_title">以CIDR格式輸入IPv4地址/遮罩(例如 1.2.3.4/24)</string> + <string name="ipv4_address">IPv4地址</string> + <string name="ipv6_address">IPv6地址</string> + <string name="custom_option_warning">使用自訂的OpenVPN選項,請加倍緊慎。請注意因Android API限制,很多與Tun相關的OpenVPN設定皆無法正常使用。如果你認為我們遺忘了重要的OpenVPN選項,請向作者反映。</string> + <string name="auth_username">用戶名稱</string> + <string name="auth_pwquery">密碼</string> + <string name="configure_the_vpn">設定VPN</string> + <string name="menu_add_profile">新增設定檔</string> + <string name="add_profile_name_prompt">輸入新的設定檔名稱</string> + <string name="duplicate_profile_name">重複的設定檔名稱</string> + <string name="profilename">設定檔名稱</string> + <string name="no_keystore_cert_selected">你必須選取一個使用者證書</string> + <string name="no_error_found">未有找到錯誤</string> + <string name="config_error_found">設定中含有錯誤</string> + <string name="ipv4_format_error">解析IPv4地址時發生錯誤</string> + <string name="custom_route_format_error">解析自訂路由時發生錯誤</string> + <string name="vpn_shortcut">OpenVPN捷徑</string> + <string name="vpn_launch_title">連接到VPN</string> + <string name="shortcut_profile_notfound">在快捷方式找不到指定的設定檔</string> + <string name="random_host_prefix">隨機主機名稱字首</string> + <string name="random_host_summary">在主機名稱前加入6個隨機字符</string> + <string name="custom_config_title">啟用自訂選項</string> + <string name="custom_config_summary">自訂選項,使用時請小心!</string> + <string name="route_rejected">路由被Android拒絕</string> + <string name="cancel_connection">斷線</string> + <string name="clear_log">清除記錄檔</string> + <string name="title_cancel">確認取消</string> + <string name="remove_vpn">移除VPN</string> + <string name="check_remote_tlscert">檢查對方出示的是否TLS伺服器憑證</string> + <string name="check_remote_tlscert_title">預期對方出示TLS伺服器憑證</string> + <string name="tls_key_auth">啟用傳輸層防火牆(TLS-Auth)</string> + <string name="tls_auth_file">TLS驗證檔</string> + <string name="pull_on_summary">向伺服器請求IP地址, 路由和時間資訊</string> + <string name="use_pull">接受設定推送(Pull)</string> + <string name="dns">DNS</string> + <string name="override_dns">忽略伺服器提供的DNS設定</string> + <string name="dns_override_summary">使用自訂的DNS伺服器</string> + <string name="searchdomain">搜索網域</string> + <string name="dns1_summary">要使用的DNS伺服器。</string> + <string name="dns_server">DNS伺服器</string> + <string name="secondary_dns_message">當主要DNS伺服器無法使用,就會嘗試備用DNS伺服器</string> + <string name="backup_dns">後備VPN伺服器</string> + <string name="ignored_pushed_routes">忽略伺服器推送的路由</string> + <string name="ignore_routes_summary">忽略從伺服器推送的路由。</string> + <string name="default_route_summary">重定向所有流量到VPN</string> + <string name="use_default_title">使用VPN作為預設閘道</string> + <string name="custom_route_message">以CIDR格式輸入目的地路由,例如\"10.0.0.0/8 2002::/16\",以上兩個路由將導向到VPN。</string> + <string name="custom_routes_title">自訂路由</string> + <string name="log_verbosity_level">記錄的詳細級別</string> + <string name="float_summary">只要能夠經過驗證,接受從任何IP地址而來的伺服器訊息</string> + <string name="float_title">容許浮動的伺服器</string> + <string name="custom_options_title">自訂選項</string> + <string name="edit_vpn">編輯VPN設定</string> + <string name="remove_vpn_query">要移除VPN設定檔 %s 嗎?</string> + <string name="tun_error_helpful">一些自訂的Android4.0 ROM存在/dev/tun的擁有者權限問題,甚至完全沒有Tun模組。CM9用家請嘗試於\"全域設置\"下修正Tun擁有者。</string> + <string name="tun_open_error">無法開啟Tun網絡介面</string> + <string name="error">"錯誤: "</string> + <string name="clear">清除</string> + <string name="local_ip_info">本地IPv4: %1$s/%2$d IPv6: %3$s MTU: %4$d</string> + <string name="version_info">%1$s %2$s</string> + <string name="send_logfile">分享記錄檔</string> + <string name="send">分享</string> + <string name="ics_openvpn_log_file">ICS OpenVPN 記錄檔</string> + <string name="copied_entry">已將記錄複製到剪貼簿</string> + <string name="tap_mode">Tap模式</string> + <string name="faq_tap_mode">Android內置的VPN API並不支援Tap介面,故此本程序並不支援Tap模式。</string> + <string name="faq">FAQ</string> + <string name="copying_log_entries">複製記錄檔條目</string> + <string name="faq_shortcut">以快捷方式啟動</string> + <string name="no_vpn_support_image">你的Android ROM不支援VPN服務API,抱歉了。 :(</string> + <string name="encryption">加密</string> + <string name="cipher_dialog_title">輸入加密方法</string> + <string name="settings_auth">驗證/加密</string> + <string name="file_explorer_tab">檔案瀏覽器</string> + <string name="inline_file_tab">內嵌檔案</string> + <string name="error_importing_file">匯入過程中發生錯誤</string> + <string name="import_error_message">無法從檔案系統中匯入檔案</string> + <string name="inline_file_data"><內嵌於設定檔></string> + <string name="menu_import">匯入.ovpn檔案</string> + <string name="menu_import_short">匯入</string> + <string name="import_content_resolve_error">匯入過程中無法讀取設定檔</string> + <string name="error_reading_config_file">讀取設定檔時發生錯誤</string> + <string name="add_profile">新增設定檔</string> + <string name="import_done">成功讀取設定檔</string> + <string name="nobind_summary">不要綁定本地地址和端口</string> + <string name="no_bind">沒有本地綁定</string> + <string name="import_configuration_file">匯入設定檔</string> + <string name="faq_security_title">保安上的考慮</string> + <string name="import_vpn">匯入</string> + <string name="ipv4">IPv4</string> + <string name="ipv6">IPv6</string> + <string name="speed_waiting">等待狀態訊息…</string> + <string name="pkcs12_file_encryption_key">PKCS12檔加密金鑰</string> + <string name="private_key_password">私密金鑰密碼</string> + <string name="password">密碼</string> + <string name="file_icon">檔案圖標</string> + <string name="tls_authentication">傳輸層防火牆(TLS Firewall)</string> + <string name="generated_config">生成的設定檔</string> + <string name="owner_fix_summary">嘗試修正/dev/tun擁有者權限。已知有些CM9 ROM需要透過這個來才能使得VPN服務API得以運作。本功能需要Root。</string> + <string name="owner_fix">修正 /dev/tun 的擁有者</string> + <string name="generated_config_summary">顯示本程序生成的設定檔</string> + <string name="edit_profile_title">正在編輯\"%s\"</string> + <string name="building_configration">正在生成設定檔…</string> + <string name="netchange_summary">當網絡狀況變更時強制重新連接(例如從WiFi變成手機網絡,反之亦然)</string> + <string name="netchange">網絡異動時重新連接</string> + <string name="netstatus">網絡狀態: %s</string> + <string name="select_file">選擇</string> + <string name="show_log_window">顯示記錄視窗</string> + <string name="mobile_info">於 %1$s (%2$s) %3$s 上運行, Android API 版本: %4$d</string> + <string name="faq_system_dialogs_title">連線警告和通知時發出音效</string> + <string name="translationby">繁體中文 由 羊羊@自由網絡研究中心 <sora8964@gmail.com> 翻譯</string> + <string name="ipdns">IP和DNS</string> + <string name="basic">基本</string> + <string name="routing">路由</string> + <string name="obscure">鮮為人知的OpenVPN設定,一般情況下不需要派上用場。</string> + <string name="advanced">進階</string> + <string name="export_config_title">ICS Openvpn 設定</string> + <string name="warn_no_dns">沒有任何DNS伺服器可用,可能無法進行網域名稱解析。請考慮設置自訂的DNS伺服器</string> + <string name="faq_howto_title">快速入門</string> + <string name="setting_loadtun_summary">在連線前嘗試載入Tun模組,需要Root。</string> + <string name="setting_loadtun">載入Tun模組</string> + <string name="getproxy_error">取得代理伺服器資訊時發生錯誤: %s</string> + <string name="using_proxy">使用代理伺服器 %1$s %2$d</string> + <string name="use_system_proxy">使用系統代理</string> + <string name="use_system_proxy_summary">使用系統配置的 HTTP/HTTPS 代理伺服器進行連接。</string> + <string name="donatewithpaypal">你可以透過 <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;cmd=_s-xclick\">PayPal</a> 提供捐助</string> + <string name="onbootrestartsummary">如果在重新開機或關機前正連接VPN,開機時自動重新連接。在使用這個選項之前請先閱讀連線警告FAQ。</string> + <string name="onbootrestart">開機時重新連接</string> + <string name="ignore">忽略</string> + <string name="restart">重置</string> + <string name="restart_vpn_after_change">配置變更只會在重新啟動VPN時才生效,現在要(重新)啟動VPN嗎?</string> + <string name="configuration_changed">設定已變更</string> + <string name="faq_duplicate_notification_title">重複的通知</string> + <string name="faq_routing_title">路由/網絡介面 設定</string> + <string name="openvpn_log">OpenVPN 運作記錄</string> + <string name="import_config">匯入 OpenVPN 配置</string> + <string name="battery_consumption_title">電池消耗</string> + <string name="vpn_tethering_title">VPN與可攜式無線基地台</string> + <string name="connection_retries">連線重試次數</string> + <string name="connectretrymessage">嘗試重新連線之間的等待秒數</string> + <string name="connectretrywait">重新連接間隔時間</string> + <string name="minidump_generated">OpenVPN非預期地崩潰,你或者會考慮在主選單下傳送Minidump給開發人員。</string> + <string name="send_minidump">向開發人員傳送Minidump</string> +</resources> diff --git a/main/src/main/res/values/arrays.xml b/main/src/main/res/values/arrays.xml new file mode 100644 index 00000000..5f829971 --- /dev/null +++ b/main/src/main/res/values/arrays.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <!-- Keep the order the same as the TYPE_ constants in VPNProfile --> + <string-array name="vpn_types"> + <item>Certificates</item> + <item>PKCS12 File</item> + <item>Android Certificate</item> + <item>Username/Password</item> + <item>Static Keys</item> + <item>User/PW + Certificates</item> + <item>User/PW + PKCS12 </item> + <item>User/PW + Android</item> + </string-array> + <string-array name="tls_directions_entries"> + <item>0</item> + <item>1</item> + <item>Unspecified</item> + </string-array> + <string-array name="crm_entries"> + <item>No reconnection retries</item> + <item>One reconnection retry</item> + <item>Five reconnection retries</item> + <item>Fifty reconnection retries</item> + <item>Unlimited reconnection retries</item> + </string-array> +</resources> diff --git a/main/src/main/res/values/attrs.xml b/main/src/main/res/values/attrs.xml new file mode 100644 index 00000000..527664f8 --- /dev/null +++ b/main/src/main/res/values/attrs.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="utf-8"?> + +<resources> + <declare-styleable name="FileSelectLayout"> + <attr name="title" format="string|reference" /> + <attr name="certificate" format="boolean" /> +<!-- <attr name="taskid" format="integer" /> --> + </declare-styleable> +</resources> diff --git a/main/src/main/res/values/dimens.xml b/main/src/main/res/values/dimens.xml new file mode 100644 index 00000000..4f325078 --- /dev/null +++ b/main/src/main/res/values/dimens.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <dimen name="paddingItemsSidebarLog">20dp</dimen> + <dimen name="stdpadding">8dp</dimen> + <bool name="logSildersAlwaysVisible">false</bool> + +</resources>
\ No newline at end of file diff --git a/main/src/main/res/values/strings.xml b/main/src/main/res/values/strings.xml new file mode 100755 index 00000000..32839feb --- /dev/null +++ b/main/src/main/res/values/strings.xml @@ -0,0 +1,320 @@ +<?xml version="1.0" encoding="utf-8"?> <!-- Generated by crowdin.net --> +<resources> + + <string name="app">OpenVPN for Android</string> + <string name="address">Server Address:</string> + <string name="port">Server Port:</string> + <string name="location">Location</string> + <string name="cant_read_folder">Unable to read directory</string> + <string name="select">Select</string> + <string name="cancel">Cancel</string> + <string name="no_data">No Data</string> + <string name="useLZO">LZO Compression</string> + <string name="client_no_certificate">No Certificate</string> + <string name="client_certificate_title">Client Certificate</string> + <string name="client_key_title">Client Certificate Key</string> + <string name="client_pkcs12_title">PKCS12 File</string> + <string name="ca_title">CA Certificate</string> + <string name="no_certificate">You must select a certificate</string> + <string name="copyright_guicode">Source code and issue tracker available at http://code.google.com/p/ics-openvpn/</string> + <string name="copyright_others">This program uses the following components; see the source code for full details on the licenses</string> + <string name="about">About</string> + <string name="vpn_list_title">Profiles</string> + <string name="vpn_type">Type</string> + <string name="pkcs12pwquery">PKCS12 Password</string> + <string name="file_select">Select…</string> + <string name="file_nothing_selected">You must select a file</string> + <string name="useTLSAuth">Use TLS Authentication</string> + <string name="tls_direction">TLS Direction</string> + <string name="ipv6_dialog_tile">Enter IPv6 Address/Netmask in CIDR Format (e.g. 2000:dd::23/64)</string> + <string name="ipv4_dialog_title">Enter IPv4 Address/Netmask in CIDR Format (e.g. 1.2.3.4/24)</string> + <string name="ipv4_address">IPv4 Address</string> + <string name="ipv6_address">IPv6 Address</string> + <string name="custom_option_warning">Enter custom OpenVPN options. Use with caution. Also note that many of the tun related OpenVPN settings cannot be supported by design of the VPNSettings. If you think an important option is missing contact the author</string> + <string name="auth_username">Username</string> + <string name="auth_pwquery">Password</string> + <string name="static_keys_info">For the static configuration the TLS Auth Keys will be used as static keys</string> + <string name="configure_the_vpn">Configure the VPN</string> + <string name="menu_add_profile">Add Profile</string> + <string name="add_profile_name_prompt">Enter a name identifying the new Profile</string> + <string name="duplicate_profile_name">Please enter a unique Profile Name</string> + <string name="profilename">Profile Name</string> + <string name="no_keystore_cert_selected">You must select a User certificate</string> + <string name="no_error_found">No error found</string> + <string name="config_error_found">Error in Configuration</string> + <string name="ipv4_format_error">Error parsing the IPv4 address</string> + <string name="custom_route_format_error">Error parsing the custom routes</string> + <string name="pw_query_hint">(leave empty to query on demand)</string> + <string name="vpn_shortcut">OpenVPN Shortcut</string> + <string name="vpn_launch_title">Connect to VPN</string> + <string name="shortcut_profile_notfound">Profile specified in shortcut not found</string> + <string name="random_host_prefix">Random Host Prefix</string> + <string name="random_host_summary">Adds 6 random chars in front of hostname</string> + <string name="custom_config_title">Enable Custom Options</string> + <string name="custom_config_summary">Specify custom options. Use with care!</string> + <string name="route_rejected">Route rejected by Android</string> + <string name="cancel_connection">Disconnect</string> + <string name="cancel_connection_long">Disconnect VPN</string> + <string name="clear_log">clear log</string> + <string name="title_cancel">Cancel Confirmation</string> + <string name="cancel_connection_query">Disconnect the connected VPN/cancel the connection attempt?</string> + <string name="remove_vpn">Remove VPN</string> + <string name="check_remote_tlscert">Checks whether the server uses a certificate with TLS Server extensions (--remote-cert-tls server)</string> + <string name="check_remote_tlscert_title">Expect TLS server certificate</string> + <string name="remote_tlscn_check_summary">Checks the Remote Server Certificate Subject DN</string> + <string name="remote_tlscn_check_title">Certificate Hostname Check</string> + <string name="enter_tlscn_dialog">Specify the check used to verify the remote certificate DN (e.g. C=DE, L=Paderborn, OU=Avian IP Carriers, CN=openvpn.blinkt.de)\n\nSpecify the complete DN or the RDN (openvpn.blinkt.de in the example) or an RDN prefix for verification.\n\nWhen using RDN prefix \"Server\" matches \"Server-1\" and \"Server-2\"\n\nLeaving the text field empty will check the RDN against the server hostname.\n\nFor more details see the OpenVPN 2.3.1+ manpage under —verify-x509-name</string> + <string name="enter_tlscn_title">Remote certificate subject</string> + <string name="tls_key_auth">Enables the TLS Key Authentication</string> + <string name="tls_auth_file">TLS Auth File</string> + <string name="pull_on_summary">Requests IP addresses, routes and timing options from the server.</string> + <string name="pull_off_summary">No information is requested from the server. Settings need to be specified below.</string> + <string name="use_pull">Pull Settings</string> + <string name="dns">DNS</string> + <string name="override_dns">Override DNS Settings by Server</string> + <string name="dns_override_summary">Use your own DNS Servers</string> + <string name="searchdomain">searchDomain</string> + <string name="dns1_summary">DNS Server to be used.</string> + <string name="dns_server">DNS Server</string> + <string name="secondary_dns_message">Secondary DNS Server used if the normal DNS Server cannot be reached.</string> + <string name="backup_dns">Backup DNS Server</string> + <string name="ignored_pushed_routes">Ignore pushed routes</string> + <string name="ignore_routes_summary">Ignore routed pushed by the server.</string> + <string name="default_route_summary">Redirects all Traffic over the VPN</string> + <string name="use_default_title">Use default Route</string> + <string name="custom_route_message">Enter custom routes. Only enter destination in CIDR format. \"10.0.0.0/8 2002::/16\" would direct the networks 10.0.0.0/8 and 2002::/16 over the VPN.</string> + <string name="custom_route_message_excluded">Routes that should NOT be routed over the VPN. Use the same syntax as for included routes.</string> + <string name="custom_routes_title">Custom Routes</string> + <string name="custom_routes_title_excluded">Excluded Networks</string> + <string name="log_verbosity_level">Log verbosity level</string> + <string name="float_summary">Allows authenticated packets from any IP</string> + <string name="float_title">Allow floating server</string> + <string name="custom_options_title">Custom Options</string> + <string name="edit_vpn">Edit VPN Settings</string> + <string name="remove_vpn_query">Remove the VPN Profile \'%s\'?</string> + <string name="tun_error_helpful">On some custom ICS images the permission on /dev/tun might be wrong, or the tun module might be missing completely. For CM9 images try the fix ownership option under general settings</string> + <string name="tun_open_error">Failed to open the tun interface</string> + <string name="error">"Error: "</string> + <string name="clear">Clear</string> + <string name="last_openvpn_tun_config">Opening tun interface:</string> + <string name="local_ip_info">Local IPv4: %1$s/%2$d IPv6: %3$s MTU: %4$d</string> + <string name="dns_server_info">DNS Server: %1$s, Domain: %2$s</string> + <string name="routes_info_incl">Routes: %1$s %2$s</string> + <string name="routes_info_excl">Routes excluded: %1$s %2$s</string> + <string name="routes_debug">VpnService routes installed: %1$s %2$s</string> + <string name="ip_not_cidr">Got interface information %1$s and %2$s, assuming second address is peer address of remote. Using /32 netmask for local IP. Mode given by OpenVPN is \"%3$s\".</string> + <string name="route_not_cidr">Cannot make sense of %1$s and %2$s as IP route with CIDR netmask, using /32 as netmask.</string> + <string name="route_not_netip">Corrected route %1$s/%2$s to %3$s/%2$s</string> + <string name="keychain_access">Cannot access the Android Keychain Certificates. This can be caused by a firmware upgrade or by restoring a backup of the app/app settings. Please edit the VPN and reselect the certificate under basic settings to recreate the permission to access the certificate.</string> + <string name="version_info">%1$s %2$s</string> + <string name="send_logfile">Send log file</string> + <string name="send">Send</string> + <string name="ics_openvpn_log_file">ICS OpenVPN log file</string> + <string name="copied_entry">Copied log entry to clip board</string> + <string name="tap_mode">Tap Mode</string> + <string name="faq_tap_mode">Tap Mode is not possible with the non root VPN API. Therefore this application cannot provide tap support</string> + <string name="tap_faq2">Again? Are you kidding? No, tap mode is really not supported and sending more mail asking if it will be supported will not help.</string> + <string name="tap_faq3">A third time? Actually, one could write a a tap emulator based on tun that would add layer2 information on send and strip layer2 information on receive. But this tap emulator would also have to implement ARP and possibly a DHCP client. I am not aware of anybody doing any work in this direction. Contact me if you want to start coding on this.</string> + <string name="faq">FAQ</string> + <string name="copying_log_entries">Copying log entries</string> + <string name="faq_copying">To copy a single log entry press and hold on the log entry. To copy/send the whole log use the Send Log option. Use the hardware menu button if not visible in the GUI.</string> + <string name="faq_shortcut">Shortcut to start</string> + <string name="faq_howto_shortcut">You can place a shortcut to start OpenVPN on your desktop. Depending on your homescreen program you will have to add either a shortcut or a widget.</string> + <string name="no_vpn_support_image">Your image does not support the VPNService API, sorry :(</string> + <string name="encryption">Encryption</string> + <string name="cipher_dialog_title">Enter encryption method</string> + <string name="chipher_dialog_message">Enter the encryption cipher algorithm used by OpenVPN. Leave empty to use default cipher.</string> + <string name="auth_dialog_message">Enter the authentication digest used for OpenVPN. Leave empty to use default digest.</string> + <string name="settings_auth">Authentication/Encryption</string> + <string name="file_explorer_tab">File Explorer</string> + <string name="inline_file_tab">Inline File</string> + <string name="error_importing_file">Error importing File</string> + <string name="import_error_message">Could not import File from filesystem</string> + <string name="inline_file_data">[[Inline file data]]</string> + <string name="opentun_no_ipaddr">Refusing to open tun device without IP information</string> + <string name="menu_import">Import Profile from ovpn file</string> + <string name="menu_import_short">Import</string> + <string name="import_content_resolve_error">Could not read Profile to import</string> + <string name="error_reading_config_file">Error reading config file</string> + <string name="add_profile">add Profile</string> + <string name="import_could_not_open">Could not find file %1$s mentioned in the imported config file</string> + <string name="importing_config">Importing config file from source %1$s</string> + <string name="import_warning_custom_options">Your configuration had a few configuration options that are not mapped to UI configurations. These options were added as custom configuration options. The custom configuration is displayed below:</string> + <string name="import_done">Done reading config file.</string> + <string name="nobind_summary">Do not bind to local address and port</string> + <string name="no_bind">No local binding</string> + <string name="import_configuration_file">Import configuration file</string> + <string name="faq_security_title">Security considerations</string> + <string name="faq_security">"As OpenVPN is security sensitive a few notes about security are sensible. All data on the sdcard is inherently insecure. Every app can read it (for example this program requires no special sd card rights). The data of this application can only be read by the application itself. By using the import option for cacert/cert/key in the file dialog the data is stored in the VPN profile. The VPN profiles are only accessible by this application. (Do not forget to delete the copies on the sd card afterwards). Even though accessible only by this application the data is still unencrypted. By rooting the telephone or other exploits it may be possible to retrieve the data. Saved passwords are stored in plain text as well. For pkcs12 files it is highly recommended that you import them into the android keystore."</string> + <string name="import_vpn">Import</string> + <string name="broken_image_cert_title">Error showing certificate selection</string> + <string name="broken_image_cert">Got an exception trying to show the Android 4.0+ certificate selection dialog. This should never happen as this a standard feature of Android 4.0+. Maybe your Android ROM support for certificate storage is broken</string> + <string name="ipv4">IPv4</string> + <string name="ipv6">IPv6</string> + <string name="speed_waiting">Waiting for state message…</string> + <string name="converted_profile">imported profile</string> + <string name="converted_profile_i">imported profile %d</string> + <string name="broken_images">Broken Images</string> + <string name="broken_images_faq"><p>Official HTC images are known to have a strange routing problem causing traffic not to flow through the tunnel (See also <a href="http://code.google.com/p/ics-openvpn/issues/detail?id=18">Issue 18</a> in the bug tracker.)</p><p>Older official SONY images from Xperia Arc S and Xperia Ray have been reported to be missing the VPNService completely from the image. (See also <a href="http://code.google.com/p/ics-openvpn/issues/detail?id=29">Issue 29</a> in the bug tracker.)</p><p>On custom build images the tun module might be missing or the rights of /dev/tun might be wrong. Some CM9 images need the "Fix ownership" option under "Device specific hacks" enabled.</p><p>Most importantly: If your device has a broken Android image, report it to your vendor. The more people who report an issue to the vendor, the more likely they are to fix it.</p></string> + <string name="pkcs12_file_encryption_key">PKCS12 File Encryption Key</string> + <string name="private_key_password">Private Key Password</string> + <string name="password">Password</string> + <string name="file_icon">file icon</string> + <string name="tls_authentication">TLS Authentication</string> + <string name="generated_config">Generated Config</string> + <string name="generalsettings">Settings</string> + <string name="owner_fix_summary">Tries to set the owner of /dev/tun to system. Some CM9 images need this to make the VPNService API work. Requires root.</string> + <string name="owner_fix">Fix ownership of /dev/tun</string> + <string name="generated_config_summary">Shows the generated OpenVPN Configuration File</string> + <string name="edit_profile_title">Editing \"%s\"</string> + <string name="building_configration">Building configuration…</string> + <string name="netchange_summary">Turning this option on will force a reconnect if the network state is changed (e.g. WiFi to/from mobile)</string> + <string name="netchange">Reconnect on network change</string> + <string name="netstatus">Network Status: %s</string> + <string name="extracahint">The CA cert is usually returned from the Android Keystore. Specify a separate certificate if you get certificate verification errors.</string> + <string name="select_file">Select</string> + <string name="keychain_nocacert">No CA Certificate returned while reading from Android keystore. Auhtentication will probably fail.</string> + <string name="show_log_summary">Shows the log window on connect. The log window can always be accessed from the notification status.</string> + <string name="show_log_window">Show log window</string> + <string name="mobile_info">Running on %1$s (%2$s) %3$s, Android API %4$d</string> + <string name="error_rsa_sign">Error signing with Android keystore key %1$s: %2$s</string> + <string name="faq_system_dialogs">The VPN connection warning telling you that this app can intercept all traffic is imposed by the system to prevent abuse of the VPNService API.\nThe VPN connection notification (The key symbol) is also imposed by the Android system to signal an ongoing VPN connection. On some images this notification plays a sound.\nAndroid introduced these system dialogs for your own safety and made sure that they cannot be circumenvented. (On some images this unfortunely includes a notifciation sound)</string> + <string name="faq_system_dialogs_title">Connection warning and notification sound</string> + <string name="translationby">English translation by Arne Schwabe<arne@rfc2549.org></string> + <string name="ipdns">IP and DNS</string> + <string name="basic">Basic</string> + <string name="routing">Routing</string> + <string name="obscure">Obscure OpenVPN Settings. Normally not needed.</string> + <string name="advanced">Advanced</string> + <string name="export_config_title">ICS Openvpn Config</string> + <string name="warn_no_dns">No DNS servers being used. Name resolution may not work. Consider setting custom DNS Servers. Please also note that Android will keep using your proxy settings specified for your mobile/Wi-Fi connection when no DNS servers are set.</string> + <string name="dns_add_error">Could not add DNS Server \"%1$s\", rejected by the system: %2$s</string> + <string name="ip_add_error">Could not configure IP Address \"%1$s\", rejected by the system: %2$s</string> + <string name="faq_howto"><p>Get a working config (tested on your computer or download from your provider/organisation)</p><p>If it is a single file no with no extra pem/pks12 files you can email the file yourself and open the attachment. If you have multiple files put them on your sd card.</p><p>Click on the email attachment/Use the folder icon in the vpn list to import the config file</p><p>If there are errors about missing files put the missing files on your sd card.</p><p>Click on the save symbol to add the imported VPN to your VPN list</p><p>Connect the VPN by clicking on the name of the VPN</p><p>If there are error or warnings in the log try to understand the warnings/error and try to fix them</p> </string> + <string name="faq_howto_title">Quick Start</string> + <string name="setting_loadtun_summary">Try to load the tun.ko kernel module before trying to connect. Needs rooted devices.</string> + <string name="setting_loadtun">Load tun module</string> + <string name="importpkcs12fromconfig">Import PKCS12 from configuration into Android Keystore</string> + <string name="getproxy_error">Error getting proxy settings: %s</string> + <string name="using_proxy">Using proxy %1$s %2$d</string> + <string name="use_system_proxy">Use system proxy</string> + <string name="use_system_proxy_summary">Use the system wide configuration for HTTP/HTTPS proxies to connect.</string> + <string name="donatewithpaypal">You can <a href=\"https://www.paypal.com/cgi-bin/webscr?hosted_button_id=R2M6ZP9AF25LS&amp;cmd=_s-xclick\">donate with PayPal</a> </string> + <string name="onbootrestartsummary">OpenVPN will reconnect a VPN if it was active on system reboot/shutdown. Please read the Connection warning FAQ before using this option.</string> + <string name="onbootrestart">Reconnect on reboot</string> + <string name="ignore">Ignore</string> + <string name="restart">Restart</string> + <string name="restart_vpn_after_change">Configuration changes are applied after restarting the VPN. (Re)start the VPN now?</string> + <string name="configuration_changed">Configuration changed</string> + <string name="log_no_last_vpn">Could not determine last connected profile for editing</string> + <string name="faq_duplicate_notification_title">Duplicate notifications</string> + <string name="faq_duplicate_notification">If Android is under system memory (RAM) pressure, apps and service which are not needed at the moment are removed from active memory. This terminates an ongoing VPN connection. To ensure that the connection/OpenVPN survives the service runs with higher priority. To run with higher priority the application must display a notification. The key notification icon is imposed by the system as described in the previous FAQ entry. It does not count as app notification for purpose of running with higher priority.</string> + <string name="no_vpn_profiles_defined">No VPN profiles defined.</string> + <string name="add_new_vpn_hint">Use the <img src=\"ic_menu_add\"/> icon to add a new VPN</string> + <string name="vpn_import_hint">Use the <img src=\"ic_menu_archive\"/> icon to import an existing (.ovpn or .conf) profile from your sdcard.</string> + <string name="faq_hint">Be sure to also check out the FAQ. There is a quick start guide.</string> + <string name="faq_routing_title">Routing/Interface Configuration</string> + <string name="faq_routing">The Routing and interface configuration is not done via traditionell ifconfig/route command but by using the VPNService API. This results in a different routing configuration than on other OSes. The configuration only consists of the IP of the tunnel interface and the networks that should be routed over this interface. Especially no peer partner address or gateway address is needed. Special routes to reach the VPN Server (for example added when using redirect-gateway) are not needed either. The application will consequently ignore these settings when importing a configuration. The app ensures with the VPNService API that the connection to the server is not routed through the VPN tunnel. Since only specifing networks to be routed via tunnel is supported extra routes not pointing to the tunnel cannot be supported either. (e.g. route x.x.x.x y.y.y.y net_gateway). The log windows shows the current configuration of the VPNService upon establishing a connection.</string> + <string name="persisttun_summary">Do not fallback to no VPN connection when OpenVPN is reconnecting.</string> + <string name="persistent_tun_title">Persistent tun</string> + <string name="openvpn_log">OpenVPN Log</string> + <string name="import_config">Import OpenVPN configuration</string> + <string name="battery_consumption_title">Battery consumption</string> + <string name="baterry_consumption">In my personal tests the main reason for high battery consumption of OpenVPN are the keepalive packets. Most OpenVPN servers have a configuration directive like \'keepalive 10 60\' which causes the client and server to exchange keepalive packets every ten seconds. <p> While these packets are small and do not use much traffic, they keep the mobile radio network busy and increase the energy consumption. (See also <a href="http://developer.android.com/training/efficient-downloads/efficient-network-access.html#RadioStateMachine">The Radio State Machine | Android Developers</a>) <p> This keepalive setting cannot be changed on the client. Only the system administrator of the OpenVPN can change the setting. <p> Unfortunately using a keepalive larger than 60 seconds with UDP can cause some NAT gateways to drop the connection due to an inactivity timeout. Using TCP with a long keepalive timeout works, but tunneling TCP over TCP performs extremely poorly on connections with high packet loss. (See <a href="http://sites.inka.de/bigred/devel/tcp-tcp.html">Why TCP Over TCP Is A Bad Idea</a>)</string> + <string name="faq_tethering">The Android Tethering feature (over WiFi, USB or Bluetooth) and the VPNService API (used by this program) do not work together. For more details see the <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=34\">issue #34</a></string> + <string name="vpn_tethering_title">VPN and Tethering</string> + <string name="connection_retries">Connection retries</string> + <string name="reconnection_settings">Reconnection settings</string> + <string name="connectretrymessage">Number of seconds to wait between connection attempts.</string> + <string name="connectretrywait">Seconds between connections</string> + <string name="minidump_generated">OpenVPN crashed unexpectedly. Please consider using the send Minidump option in the main menu</string> + <string name="send_minidump">Send Minidump to developer</string> + <string name="send_minidump_summary">Sends debugging information about last crash to developer</string> + <string name="notifcation_title">OpenVPN - %s</string> + <string name="session_ipv4string">%1$s - %2$s</string> + <string name="session_ipv6string">%1$s - %3$s, %2$s</string> + <string name="state_connecting">Connecting</string> + <string name="state_wait">Waiting for server reply</string> + <string name="state_auth">Authenticating</string> + <string name="state_get_config">Getting client configuration</string> + <string name="state_assign_ip">Assigning IP addresses</string> + <string name="state_add_routes">Adding routes</string> + <string name="state_connected">Connected</string> + <string name="state_disconnected">Disconnect</string> + <string name="state_reconnecting">Reconnecting</string> + <string name="state_exiting">Exiting</string> + <string name="state_noprocess">Not running</string> + <string name="state_resolve">Resolving host names</string> + <string name="state_tcp_connect">Connecting (TCP)</string> + <string name="state_auth_failed">Authentication failed</string> + <string name="state_nonetwork">Waiting for usable network</string> + <string name="statusline_bytecount">↓%2$s/s %1$s - ↑%4$s/s %3$s</string> + <string name="notifcation_title_notconnect">Not connected</string> + <string name="start_vpn_title">Connecting to VPN %s</string> + <string name="start_vpn_ticker">Connecting to VPN %s</string> + <string name="jelly_keystore_alphanumeric_bug">Some versions of Android 4.1 have problems if the name of the keystore certificate contains non alphanumeric characters (like spaces, underscores or dashes). Try to reimport the certificate without special characters</string> + <string name="encryption_cipher">Encryption cipher</string> + <string name="packet_auth">Packets authentication</string> + <string name="auth_dialog_title">Enter packet authentication method</string> + <string name="mobile_info_extended">Running on %1$s (%2$s) %3$s, Android API %4$d, version %5$s, %6$s</string> + <string name="built_by">built by %s</string> + <string name="debug_build">debug build</string> + <string name="official_build">official build</string> + <string name="make_selection_inline">Copy into profile</string> + <string name="crashdump">Crashdump</string> + <string name="add">Add</string> + <string name="send_config">Send config file</string> + <string name="complete_dn">Complete DN</string> + <string name="remotetlsnote">Your imported configuration used the old DEPRECATED tls-remote option which uses a different DN format.</string> + <string name="rdn">RDN (common name)</string> + <string name="rdn_prefix">RDN prefix</string> + <string name="tls_remote_deprecated">tls-remote (DEPRECATED)</string> + <string name="help_translate">You can help translating by visiting http://crowdin.net/project/ics-openvpn/invite</string> + <string name="prompt">%1$s attempts to control %2$s</string> + <string name="remote_warning">By proceeding, you are giving the application permission to completely control OpenVPN for Android and to intercept all network traffic.<b>Do NOT accept unless you trust the application.</b> Otherwise, you run the risk of having your data compromised by malicious software."</string> + <string name="remote_trust">I trust this application.</string> + <string name="no_external_app_allowed">No app allowed to use external API</string> + <string name="allowed_apps">Allowed apps: %s</string> + <string name="clearappsdialog">Clear list of allowed external apps?\nCurrent list of allowed apps:\n\n%s</string> + <string name="screenoff_summary">"Pause VPN when screen is off and less than 64 kB transferred data in 60s. When the \"Persistent Tun\" option is enabled pausing the VPN will leave your device with NO network connectivity. Without the \"Persistent Tun\" option the device will have no VPN connection/protection.</string> + <string name="screenoff_title">Pause VPN connection after screen off</string> + <string name="screenoff_pause">Pausing connection in screen off state: less than %1$s in %2$ss</string> + <string name="screen_nopersistenttun">Warning: Persistent tun not enabled for this VPN. Traffic will use the normal Internet connection when the screen is off.</string> + <string name="save_password">Save Password</string> + <string name="pauseVPN">Pause VPN</string> + <string name="resumevpn">Resume VPN</string> + <string name="state_userpause">VPN pause requested by user</string> + <string name="state_screenoff">VPN paused - screen off</string> + <string name="device_specific">Device specifics Hacks</string> + <string name="cannotparsecert">Cannot display certificate information</string> + <string name="appbehaviour">Application behaviour</string> + <string name="vpnbehaviour">VPN behaviour</string> + <string name="allow_vpn_changes">Allow changes to VPN Profiles</string> + <string name="hwkeychain">Hardware Keystore:</string> + <string name="permission_icon_app">Icon of app trying to use OpenVPN for Android</string> + <string name="faq_vpndialog43">"Starting with Android 4.3 the VPN confirmation is guarded against \"overlaying apps\". This results in the dialog not reacting to touch input. If you have an app that uses overlays it may cause this behaviour. If you find an offending app contact the author of the app. This problem affect all VPN applications on Android 4.3 and later. See also <a href=\"http://code.google.com/p/ics-openvpn/issues/detail?id=185\">Issue 185<a> for additional details"</string> + <string name="faq_vpndialog43_title">Vpn Confirm Dialog on Android 4.3 and later</string> + <string name="donatePlayStore">Alternatively you can send me a donation with the Play Store:</string> + <string name="thanks_for_donation">Thanks for donating %s!</string> + <string name="logCleared">Log cleared.</string> + <string name="show_password">Show password</string> + <string name="keyChainAccessError">KeyChain Access error: %s</string> + <string name="timestamp_short">Short</string> + <string name="timestamp_iso">ISO</string> + <string name="timestamps">Timestamps</string> + <string name="timestamps_none">None</string> + <string name="uploaded_data">Upload</string> + <string name="downloaded_data">Download</string> + <string name="vpn_status">Vpn Status</string> + <string name="logview_options">View options</string> + <string name="unhandled_exception">Unhandled exception: %1$s\n\n%2$s</string> + <string name="unhandled_exception_context">%3$s: %1$s\n\n%2$s</string> + <string name="faq_system_dialog_xposed">If you have rooted your Android device you can install the <a href=\"http://xposed.info/\">Xposed framework</a> and a the <a href=\"http://repo.xposed.info/module/de.blinkt.vpndialogxposed\">VPN Dialog confirm module</a> at your own risk"</string> + <string name="full_licenses">Full licenses</string> + <string name="blocklocal_summary">Networks directly connected to the local interfaces will not be routed over the VPN. Unchecking this option will redirect all traffic indented for local networks to VPN.</string> + <string name="blocklocal_title">Bypass VPN for local networks</string> + <string name="userpw_file">Username/Password file</string> + <string name="imported_from_file">[Imported from: %s]</string> + <string name="files_missing_hint">Some files could not be found. Please select the files to import the profile:</string> + <string name="openvpn_is_no_free_vpn">To use this app you need a VPN provider/VPN gateway supporting OpenVPN (often provided by your employer .Check out http://community.openvpn.net/ for more information on OpenVPN and how to setup your own OpenVPN server.</string> +</resources> diff --git a/main/src/main/res/values/styles.xml b/main/src/main/res/values/styles.xml new file mode 100644 index 00000000..95e709b3 --- /dev/null +++ b/main/src/main/res/values/styles.xml @@ -0,0 +1,64 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2011 The Android Open Source Project + Copyright (C) 2012 Arne Schwabe + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<resources> + + <style name="item"> + <item name="android:layout_width">match_parent</item> + <item name="android:layout_height">wrap_content</item> + <item name="android:textAppearance">?android:attr/textAppearanceMedium</item> + <item name="android:singleLine">true</item> + </style> + + <style name="faqitem"> + <item name="android:layout_width">match_parent</item> + <item name="android:layout_height">wrap_content</item> + <item name="android:textAppearance">?android:attr/textAppearanceSmall</item> + </style> + + <style name="faqhead"> + <item name="android:paddingTop">10sp</item> + <item name="android:layout_width">match_parent</item> + <item name="android:layout_height">wrap_content</item> + <item name="android:textAppearance">?android:attr/textAppearanceMedium</item> + <!-- <item name="android:singleLine">true</item> --> + </style> + + <style name="accountSetupButton"> + <item name="android:layout_width">160sp</item> + <item name="android:layout_height">40sp</item> + <item name="android:textColor">?android:attr/textColorPrimary</item> + <item name="android:textAppearance">?android:attr/textAppearanceSmall</item> + </style> + + <style name="Theme.CreateShortCut" parent="android:Theme.Holo.DialogWhenLarge" /> + + <style name="logWindowStatusText"> + <item name="android:paddingLeft">@dimen/paddingItemsSidebarLog</item> + <item name="android:layout_width">wrap_content</item> + <item name="android:layout_height">wrap_content</item> + <item name="android:textAppearance">?android:attr/textAppearanceLarge</item> + </style> + + <style name="logWindowStatusTitle"> + <item name="android:layout_width">wrap_content</item> + <item name="android:layout_height">wrap_content</item> + </style> + + +</resources>
\ No newline at end of file diff --git a/main/src/main/res/values/untranslatable.xml b/main/src/main/res/values/untranslatable.xml new file mode 100644 index 00000000..7458bc33 --- /dev/null +++ b/main/src/main/res/values/untranslatable.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + + <string name="copyright_blinktgui" translatable="false">Copyright 2012–2013 Arne Schwabe <arne@rfc2549.org></string> + <string name="opevpn_copyright" translatable="false">Copyright © 2002–2010 OpenVPN Technologies, Inc. <sales@openvpn.net>\n + + "OpenVPN" is a trademark of OpenVPN Technologies, Inc.\n</string> + <string name="defaultserver" translatable="false">openvpn.uni-paderborn.de</string> + <string name="defaultport" translatable="false">1194</string> + <string name="copyright_file_dialog" translatable="false">File Dialog based on work by Alexander Ponomarev</string> + <string name="lzo_copyright" translatable="false">Copyright © 1996 – 2011 Markus Franz Xaver Johannes Oberhumer</string> + <string name="copyright_openssl" translatable="false"> This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit\n + Copyright © 1998-2008 The OpenSSL Project. All rights reserved.\n\n + This product includes cryptographic software written by Eric Young (eay@cryptsoft.com)\n + Copyright © 1995-1998 Eric Young (eay@cryptsoft.com) All rights reserved.</string> + <string name="openvpn" translatable="false">OpenVPN</string> + <string name="file_dialog" translatable="false">File Dialog</string> + <string name="lzo" translatable="false">LZO</string> + <string name="openssl" translatable="false">OpenSSL</string> + <string name="unknown_state" translatable="false">Unknown state</string> + <string name="permission_description">Allows another app to control OpenVPN</string> + <string name="bouncy_castle" translatable="false">Bouncy Castle Crypto APIs</string> + <string name="copyright_bouncycastle" translatable="false">Copyright © 2000–2012 The Legion Of The Bouncy Castle (http://www.bouncycastle.org)</string> + + <string-array name="tls_directions_values" translatable="false"> + <item>0</item> + <item>1</item> + <item></item> + </string-array> + <string-array name="crm_values" translatable="false"> + <item>1</item> + <item>2</item> + <item>5</item> + <item>50</item> + <item>-1</item> + </string-array> + + <!-- These strings should not be visible to the user --> + <string name="state_user_vpn_permission" translatable="false">Waiting for user permission to use VPN API</string> + <string name="state_user_vpn_password" translatable="false">Waiting for user VPN password</string> + <string name="state_user_vpn_password_cancelled" translatable="false">VPN password input dialog cancelled</string> + <string name="state_user_vpn_permission_cancelled" translatable="false">VPN API permission dialog cancelled</string> + +</resources>
\ No newline at end of file diff --git a/main/src/main/res/xml/general_settings.xml b/main/src/main/res/xml/general_settings.xml new file mode 100644 index 00000000..d43ab6a3 --- /dev/null +++ b/main/src/main/res/xml/general_settings.xml @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="utf-8"?> +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> + <PreferenceCategory android:title="@string/appbehaviour"> + <CheckBoxPreference + android:defaultValue="true" + android:key="showlogwindow" + android:summary="@string/show_log_summary" + android:title="@string/show_log_window"/> + + <CheckBoxPreference + android:defaultValue="false" + android:key="restartvpnonboot" + android:summary="@string/onbootrestartsummary" + android:title="@string/onbootrestart"/> + + <Preference + android:key="clearapi" + android:persistent="false" + android:title="Clear allowed external apps"/> + </PreferenceCategory> + + <PreferenceCategory android:title="@string/vpnbehaviour"> + <CheckBoxPreference + android:defaultValue="true" + android:key="usesystemproxy" + android:summary="@string/use_system_proxy_summary" + android:title="@string/use_system_proxy"/> + <CheckBoxPreference + android:defaultValue="true" + android:key="netchangereconnect" + android:summary="@string/netchange_summary" + android:title="@string/netchange"/> + + + <CheckBoxPreference + android:defaultValue="false" + android:key="screenoff" + android:summary="@string/screenoff_summary" + android:title="@string/screenoff_title"/> + + </PreferenceCategory> + + <PreferenceCategory android:title="@string/device_specific" android:key="device_hacks"> + <CheckBoxPreference + android:defaultValue="false" + android:key="useCM9Fix" + android:summary="@string/owner_fix_summary" + android:title="@string/owner_fix"/> + <CheckBoxPreference + android:defaultValue="false" + android:key="loadTunModule" + android:summary="@string/setting_loadtun_summary" + android:title="@string/setting_loadtun"/> + </PreferenceCategory> + +</PreferenceScreen>
\ No newline at end of file diff --git a/main/src/main/res/xml/vpn_authentification.xml b/main/src/main/res/xml/vpn_authentification.xml new file mode 100644 index 00000000..15a260c2 --- /dev/null +++ b/main/src/main/res/xml/vpn_authentification.xml @@ -0,0 +1,52 @@ +<?xml version="1.0" encoding="utf-8"?> +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" > + + <CheckBoxPreference + android:key="remoteServerTLS" + android:summary="@string/check_remote_tlscert" + android:title="@string/check_remote_tlscert_title" /> + <CheckBoxPreference + android:key="checkRemoteCN" + android:summary="@string/remote_tlscn_check_summary" + android:title="@string/remote_tlscn_check_title" /> + + <de.blinkt.openvpn.views.RemoteCNPreference + android:dependency="checkRemoteCN" + android:key="remotecn" + android:title="@string/enter_tlscn_title" /> + + <PreferenceCategory android:title="@string/tls_authentication" > + <SwitchPreference + android:key="useTLSAuth" + android:summary="@string/tls_key_auth" + android:title="@string/useTLSAuth" /> + + <Preference + android:dependency="useTLSAuth" + android:key="tlsAuthFile" + android:title="@string/tls_auth_file" /> + + <ListPreference + android:dependency="useTLSAuth" + android:entries="@array/tls_directions_entries" + android:entryValues="@array/tls_directions_values" + android:key="tls_direction" + android:persistent="false" + android:title="@string/tls_direction" /> + </PreferenceCategory> + <PreferenceCategory android:title="@string/encryption" > + <EditTextPreference + android:dialogMessage="@string/chipher_dialog_message" + android:dialogTitle="@string/cipher_dialog_title" + android:key="cipher" + android:persistent="false" + android:title="@string/encryption_cipher" /> + <EditTextPreference + android:dialogMessage="@string/auth_dialog_message" + android:dialogTitle="@string/auth_dialog_title" + android:key="auth" + android:persistent="false" + android:title="@string/packet_auth" /> + </PreferenceCategory> + +</PreferenceScreen>
\ No newline at end of file diff --git a/main/src/main/res/xml/vpn_headers.xml b/main/src/main/res/xml/vpn_headers.xml new file mode 100644 index 00000000..7f2a97d9 --- /dev/null +++ b/main/src/main/res/xml/vpn_headers.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8"?> +<preference-headers xmlns:android="http://schemas.android.com/apk/res/android" > + + <header + android:id="@+id/basicsettingsid" + android:fragment="de.blinkt.openvpn.fragments.Settings_Basic" + android:title="@string/basic" /> + <!-- android:icon="@drawable/ic_settings_applications" --> + + <header + android:fragment="de.blinkt.openvpn.fragments.Settings_IP" + android:title="@string/ipdns" /> + <header + android:fragment="de.blinkt.openvpn.fragments.Settings_Routing" + android:title="@string/routing" /> + <header + android:fragment="de.blinkt.openvpn.fragments.Settings_Authentication" + android:title="@string/settings_auth" /> + + <!-- android:icon="@drawable/ic_settings_display" --> + <header + android:fragment="de.blinkt.openvpn.fragments.Settings_Obscure" + android:summary="@string/obscure" + android:title="@string/advanced" > + </header> + <header + android:fragment="de.blinkt.openvpn.fragments.ShowConfigFragment" + android:summary="@string/generated_config_summary" + android:title="@string/generated_config" /> + +</preference-headers>
\ No newline at end of file diff --git a/main/src/main/res/xml/vpn_ipsettings.xml b/main/src/main/res/xml/vpn_ipsettings.xml new file mode 100644 index 00000000..d559c89b --- /dev/null +++ b/main/src/main/res/xml/vpn_ipsettings.xml @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="utf-8"?> +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" > + + <SwitchPreference + android:disableDependentsState="true" + android:key="usePull" + android:summaryOff="@string/pull_off_summary" + android:summaryOn="@string/pull_on_summary" + android:title="@string/use_pull" /> + + <PreferenceCategory android:title="IP" > + <EditTextPreference + android:dependency="usePull" + android:dialogMessage="@string/ipv4_dialog_title" + android:key="ipv4_address" + android:title="@string/ipv4_address" /> + <EditTextPreference + android:dependency="usePull" + android:dialogMessage="@string/ipv6_dialog_tile" + android:key="ipv6_address" + android:title="@string/ipv6_address" /> + + <CheckBoxPreference + android:key="nobind" + android:persistent="false" + android:summary="@string/nobind_summary" + android:title="@string/no_bind" /> + </PreferenceCategory> + <PreferenceCategory android:title="@string/dns" > + <CheckBoxPreference + android:key="overrideDNS" + android:summary="@string/dns_override_summary" + android:title="@string/override_dns" /> + + <EditTextPreference + android:key="searchdomain" + android:title="@string/searchdomain" /> + <EditTextPreference + android:dialogMessage="@string/dns1_summary" + android:key="dns1" + android:title="@string/dns_server" /> + <EditTextPreference + android:dialogMessage="@string/secondary_dns_message" + android:key="dns2" + android:title="@string/backup_dns" /> + </PreferenceCategory> + +</PreferenceScreen>
\ No newline at end of file diff --git a/main/src/main/res/xml/vpn_obscure.xml b/main/src/main/res/xml/vpn_obscure.xml new file mode 100644 index 00000000..6172dacb --- /dev/null +++ b/main/src/main/res/xml/vpn_obscure.xml @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="utf-8"?> +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" + android:title="Obscure Settings" > + + + <CheckBoxPreference + android:key="useRandomHostname" + android:persistent="false" + android:summary="@string/random_host_summary" + android:title="@string/random_host_prefix" /> + <CheckBoxPreference + android:key="useFloat" + android:persistent="false" + android:summary="@string/float_summary" + android:title="@string/float_title" /> + <CheckBoxPreference + android:key="usePersistTun" + android:summary="@string/persisttun_summary" + android:title="@string/persistent_tun_title" /> + + <PreferenceCategory android:title="@string/reconnection_settings" > + <ListPreference + android:entries="@array/crm_entries" + android:entryValues="@array/crm_values" + android:key="connectretrymax" + android:persistent="false" + android:title="@string/connection_retries" /> + + <EditTextPreference + android:dialogMessage="@string/connectretrymessage" + android:key="connectretry" + android:persistent="false" + android:title="@string/connectretrywait" /> + </PreferenceCategory> + <PreferenceCategory android:title="@string/custom_config_title" > + <CheckBoxPreference + android:key="enableCustomOptions" + android:persistent="false" + android:summary="@string/custom_config_summary" + android:title="@string/custom_config_title" /> + + <EditTextPreference + android:dependency="enableCustomOptions" + android:dialogMessage="@string/custom_option_warning" + android:key="customOptions" + android:persistent="false" + android:title="@string/custom_options_title" /> + </PreferenceCategory> + +</PreferenceScreen>
\ No newline at end of file diff --git a/main/src/main/res/xml/vpn_routing.xml b/main/src/main/res/xml/vpn_routing.xml new file mode 100644 index 00000000..0f006431 --- /dev/null +++ b/main/src/main/res/xml/vpn_routing.xml @@ -0,0 +1,56 @@ +<?xml version="1.0" encoding="utf-8"?> +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" > + + <CheckBoxPreference + android:key="routenopull" + android:summary="@string/ignore_routes_summary" + android:title="@string/ignored_pushed_routes" /> + + <CheckBoxPreference + android:title="@string/blocklocal_title" + android:summary="@string/blocklocal_summary" + android:key="unblockLocal" + /> + + <PreferenceCategory android:title="@string/ipv4" > + <CheckBoxPreference + android:disableDependentsState="true" + android:key="useDefaultRoute" + android:summary="@string/default_route_summary" + android:title="@string/use_default_title" /> + + <EditTextPreference + android:dependency="useDefaultRoute" + android:dialogMessage="@string/custom_route_message" + android:key="customRoutes" + android:title="@string/custom_routes_title" /> + + <EditTextPreference + android:dependency="useDefaultRoute" + android:dialogMessage="@string/custom_route_message_excluded" + android:key="excludedRoutes" + android:title="@string/custom_routes_title_excluded" /> + </PreferenceCategory> + <PreferenceCategory android:title="@string/ipv6" > + <CheckBoxPreference + android:disableDependentsState="true" + android:key="useDefaultRoutev6" + android:summary="@string/default_route_summary" + android:title="@string/use_default_title" /> + + <EditTextPreference + android:dependency="useDefaultRoutev6" + android:dialogMessage="@string/custom_route_message" + android:key="customRoutesv6" + android:title="@string/custom_routes_title" /> + + <!-- disable for now. Not supported by OpenVPN itself --> + <EditTextPreference + android:enabled="false" + android:dependency="useDefaultRoute" + android:dialogMessage="@string/custom_route_message_excluded" + android:key="excludedRoutesv6" + android:title="@string/custom_routes_title_excluded" /> + </PreferenceCategory> + +</PreferenceScreen>
\ No newline at end of file |