diff options
-rw-r--r-- | cmds/keystore/keymgmt.c | 66 | ||||
-rw-r--r-- | cmds/keystore/tests/Android.mk | 28 | ||||
-rw-r--r-- | cmds/keystore/tests/netkeystore_test.c | 249 | ||||
-rw-r--r-- | include/utils/ResourceTypes.h | 6 | ||||
-rw-r--r-- | libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp | 3 | ||||
-rw-r--r-- | libs/surfaceflinger/SurfaceFlinger.cpp | 21 | ||||
-rw-r--r-- | libs/surfaceflinger/SurfaceFlinger.h | 1 | ||||
-rw-r--r-- | libs/utils/ResourceTypes.cpp | 11 | ||||
-rw-r--r-- | vpn/java/android/net/vpn/PptpProfile.java | 26 | ||||
-rw-r--r-- | vpn/java/android/net/vpn/VpnManager.java | 4 |
10 files changed, 396 insertions, 19 deletions
diff --git a/cmds/keystore/keymgmt.c b/cmds/keystore/keymgmt.c index 66edd56..9a1f845 100644 --- a/cmds/keystore/keymgmt.c +++ b/cmds/keystore/keymgmt.c @@ -79,14 +79,26 @@ static int encrypt_n_save(AES_KEY *enc_key, DATA_BLOB *blob, { int size, fd, ret = -1; unsigned char enc_blob[MAX_BLOB_LEN]; - char tmpfile[KEYFILE_LEN]; + + if ((keyfile == NULL) || (strlen(keyfile) >= (KEYFILE_LEN - 4))) { + LOGE("keyfile name is too long or null"); + return -1; + } strcpy(tmpfile, keyfile); strcat(tmpfile, ".tmp"); // prepare the blob + if (IV_LEN > USER_KEY_LEN) { + LOGE("iv length is too long."); + return -1; + } memcpy(blob->iv, iv, IV_LEN); blob->blob_size = get_blob_size(blob); + if (blob->blob_size > MAX_BLOB_LEN) { + LOGE("blob data size is too large."); + return -1; + } memcpy(enc_blob, blob->blob, blob->blob_size); AES_cbc_encrypt((unsigned char *)enc_blob, (unsigned char *)blob->blob, blob->blob_size, enc_key, iv, AES_ENCRYPT); @@ -133,8 +145,13 @@ static int store_master_key(char *upasswd, unsigned char *master_key) DATA_BLOB blob; // prepare the blob + if (strlen(MASTER_KEY_TAG) >= USER_KEY_LEN) return -1; strlcpy(blob.keyname, MASTER_KEY_TAG, USER_KEY_LEN); blob.value_size = USER_KEY_LEN; + if (USER_KEY_LEN > MAX_KEY_VALUE_LENGTH) { + LOGE("master_key length is too long."); + return -1; + } memcpy((void*)blob.value, (const void*)master_key, USER_KEY_LEN); // generate the encryption key @@ -150,6 +167,10 @@ static int get_master_key(char *upasswd, unsigned char *master_key) get_decrypt_key(upasswd, &key); ret = load_n_decrypt(MASTER_KEY_TAG, MASTER_KEY, &key, &blob); + if (blob.value_size > USER_KEY_LEN) { + LOGE("the blob's value size is too large"); + return -1; + } if (!ret) memcpy(master_key, blob.value, blob.value_size); return ret; } @@ -207,6 +228,11 @@ int remove_key(const char *namespace, const char *keyname) char keyfile[KEYFILE_LEN]; if (state != UNLOCKED) return -state; + if ((strlen(namespace) >= MAX_KEY_NAME_LENGTH) || + (strlen(keyname) >= MAX_KEY_NAME_LENGTH)) { + LOGE("keyname is too long."); + return -1; + } sprintf(keyfile, KEYFILE_NAME, namespace, keyname); return unlink(keyfile); } @@ -222,10 +248,18 @@ int put_key(const char *namespace, const char *keyname, LOGE("Can not store key with current state %d\n", state); return -state; } + if ((strlen(namespace) >= MAX_KEY_NAME_LENGTH) || + (strlen(keyname) >= MAX_KEY_NAME_LENGTH)) { + LOGE("keyname is too long."); + return -1; + } sprintf(keyfile, KEYFILE_NAME, namespace, keyname); - // flatten the args strcpy(blob.keyname, keyname); blob.value_size = size; + if (size > MAX_KEY_VALUE_LENGTH) { + LOGE("the data size is too large."); + return -1; + } memcpy(blob.value, data, size); return encrypt_n_save(&encryptKey, &blob, keyfile); } @@ -242,10 +276,16 @@ int get_key(const char *namespace, const char *keyname, LOGE("Can not retrieve key value with current state %d\n", state); return -state; } + if ((strlen(namespace) >= MAX_KEY_NAME_LENGTH) || + (strlen(keyname) >= MAX_KEY_NAME_LENGTH)) { + LOGE("keyname is too long."); + return -1; + } sprintf(keyfile, KEYFILE_NAME, namespace, keyname); ret = load_n_decrypt(keyname, keyfile, &decryptKey, &blob); if (!ret) { if ((blob.value_size > MAX_KEY_VALUE_LENGTH)) { + LOGE("blob value size is too large."); ret = -1; } else { *size = blob.value_size; @@ -269,6 +309,13 @@ int list_keys(const char *namespace, char reply[BUFFER_MAX]) LOGE("cannot open keystore dir or namespace is null\n"); return -1; } + + if (strlen(namespace) >= MAX_KEY_NAME_LENGTH) { + LOGE("namespace is too long."); + return -1; + } + + reply[0] = 0; while ((de = readdir(d))) { char *prefix, *name, *keyfile = de->d_name; char *context = NULL; @@ -337,6 +384,7 @@ KEYSTORE_STATE get_state() int reset_keystore() { + int ret = 0; DIR *d; struct dirent *de; @@ -344,18 +392,24 @@ int reset_keystore() LOGE("cannot open keystore dir\n"); return -1; } - while ((de = readdir(d))) unlink(de->d_name); + while ((de = readdir(d))) { + if (unlink(de->d_name) != 0) ret = -1; + } closedir(d); state = UNINITIALIZED; - LOGI("keystore is reset."); - return 0; + if (ret == 0) { + LOGI("keystore is reset."); + } else { + LOGI("keystore can not be cleaned up entirely."); + } + return ret; } int init_keystore(const char *dir) { int fd; - if (!dir) mkdir(dir, 0770); + if (dir) mkdir(dir, 0770); if (!dir || chdir(dir)) { LOGE("Can not open/create the keystore directory %s\n", dir ? dir : "(null)"); diff --git a/cmds/keystore/tests/Android.mk b/cmds/keystore/tests/Android.mk new file mode 100644 index 0000000..33541cc --- /dev/null +++ b/cmds/keystore/tests/Android.mk @@ -0,0 +1,28 @@ +# Copyright (C) 2009 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. +# +# define the KEYSTORE_TESTS environment variable to build the test programs +ifdef KEYSTORE_TESTS +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) +LOCAL_SRC_FILES:= netkeystore_test.c ../keymgmt.c +LOCAL_SHARED_LIBRARIES := libcutils libssl +LOCAL_MODULE:= netkeystore_test +LOCAL_MODULE_TAGS := optional +LOCAL_C_INCLUDES := external/openssl/include \ + frameworks/base/cmds/keystore +EXTRA_CFLAGS := -g -O0 -DGTEST_OS_LINUX -DGTEST_HAS_STD_STRING +include $(BUILD_EXECUTABLE) + +endif #KEYSTORE_TESTS diff --git a/cmds/keystore/tests/netkeystore_test.c b/cmds/keystore/tests/netkeystore_test.c new file mode 100644 index 0000000..e7e686b --- /dev/null +++ b/cmds/keystore/tests/netkeystore_test.c @@ -0,0 +1,249 @@ +/* + * Copyright (C) 2009 The Android Open Source 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: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * + * 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 OWNER 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. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include "common.h" +#include "keymgmt.h" + +typedef int FUNC_PTR(); +typedef struct { + const char *name; + FUNC_PTR *func; +} TESTFUNC; + +#define FUNC_NAME(x) { #x, test_##x } +#define FUNC_BODY(x) int test_##x() + +#define TEST_PASSWD "12345678" +#define TEST_NPASSWD "11111111" +#define TEST_DIR "/data/local/tmp/keystore" +#define READONLY_DIR "/proc/keystore" +#define TEST_NAMESPACE "test" +#define TEST_KEYNAME "key" +#define TEST_KEYNAME2 "key2" +#define TEST_KEYVALUE "ANDROID" + +void setup() +{ + if (init_keystore(TEST_DIR) != 0) { + fprintf(stderr, "Can not create the test directory %s\n", TEST_DIR); + exit(-1); + } +} + +void teardown() +{ + reset_keystore(); + rmdir(TEST_DIR); +} + +FUNC_BODY(init_keystore) +{ + if (init_keystore(READONLY_DIR) == 0) return -1; + + return EXIT_SUCCESS; +} + +FUNC_BODY(reset_keystore) +{ + chdir("/procx"); + if (reset_keystore() == 0) return -1; + chdir(TEST_DIR); + return EXIT_SUCCESS; +} + +FUNC_BODY(get_state) +{ + if (get_state() != UNINITIALIZED) return -1; + passwd(TEST_PASSWD); + if (get_state() != UNLOCKED) return -1; + lock(); + if (get_state() != LOCKED) return -1; + reset_keystore(); + if (get_state() != UNINITIALIZED) return -1; + return EXIT_SUCCESS; +} + +FUNC_BODY(passwd) +{ + char buf[512]; + + if (passwd(" 23432dsfsdf") == 0) return -1; + if (passwd("dsfsdf") == 0) return -1; + passwd(TEST_PASSWD); + lock(); + if (unlock("55555555") == 0) return -1; + if (unlock(TEST_PASSWD) != 0) return -1; + + // change the password + sprintf(buf, "%s %s", "klfdjdsklfjg", "abcdefghi"); + if (passwd(buf) == 0) return -1; + + sprintf(buf, "%s %s", TEST_PASSWD, TEST_NPASSWD); + if (passwd(buf) != 0) return -1; + lock(); + + if (unlock(TEST_PASSWD) == 0) return -1; + if (unlock(TEST_NPASSWD) != 0) return -1; + + return EXIT_SUCCESS; +} + +FUNC_BODY(lock) +{ + if (lock() == 0) return -1; + passwd(TEST_PASSWD); + if (lock() != 0) return -1; + if (lock() != 0) return -1; + return EXIT_SUCCESS; +} + +FUNC_BODY(unlock) +{ + int i = MAX_RETRY_COUNT; + passwd(TEST_PASSWD); + lock(); + while (i > 1) { + if (unlock(TEST_NPASSWD) != --i) return -1; + } + if (unlock(TEST_NPASSWD) != -1) return -1; + return EXIT_SUCCESS; +} + +FUNC_BODY(put_key) +{ + int i = 0; + char keyname[512]; + + if (put_key(TEST_NAMESPACE, TEST_KEYNAME, (unsigned char *)TEST_KEYVALUE, + strlen(TEST_KEYVALUE)) == 0) return -1; + passwd(TEST_PASSWD); + if (put_key(TEST_NAMESPACE, TEST_KEYNAME, (unsigned char *)TEST_KEYVALUE, + strlen(TEST_KEYVALUE)) != 0) return -1; + + for(i = 0; i < 500; i++) keyname[i] = 'K'; + keyname[i] = 0; + if (put_key(TEST_NAMESPACE, keyname, (unsigned char *)TEST_KEYVALUE, + strlen(TEST_KEYVALUE)) == 0) return -1; + if (put_key(TEST_NAMESPACE, TEST_KEYNAME, (unsigned char *)TEST_KEYVALUE, + MAX_KEY_VALUE_LENGTH + 1) == 0) return -1; + return EXIT_SUCCESS; +} + +FUNC_BODY(get_key) +{ + int size; + unsigned char data[MAX_KEY_VALUE_LENGTH]; + + if (get_key(TEST_NAMESPACE, TEST_KEYNAME, data, &size) == 0) return -1; + + passwd(TEST_PASSWD); + put_key(TEST_NAMESPACE, TEST_KEYNAME, (unsigned char *)TEST_KEYVALUE, + strlen(TEST_KEYVALUE)); + if (get_key(TEST_NAMESPACE, TEST_KEYNAME, data, &size) != 0) return -1; + if (memcmp(data, TEST_KEYVALUE, size) != 0) return -1; + + return EXIT_SUCCESS; +} + +FUNC_BODY(remove_key) +{ + if (remove_key(TEST_NAMESPACE, TEST_KEYNAME) == 0) return -1; + + passwd(TEST_PASSWD); + if (remove_key(TEST_NAMESPACE, TEST_KEYNAME) == 0) return -1; + + put_key(TEST_NAMESPACE, TEST_KEYNAME, (unsigned char *)TEST_KEYVALUE, + strlen(TEST_KEYVALUE)); + if (remove_key(TEST_NAMESPACE, TEST_KEYNAME) != 0) return -1; + + return EXIT_SUCCESS; +} + +FUNC_BODY(list_keys) +{ + int i; + char buf[128]; + char reply[BUFFER_MAX]; + + for(i = 0; i < 100; i++) buf[i] = 'K'; + buf[i] = 0; + + if (list_keys(TEST_NAMESPACE, reply) == 0) return -1; + + passwd(TEST_PASSWD); + if (list_keys(buf, reply) == 0) return -1; + + if (list_keys(TEST_NAMESPACE, reply) != 0) return -1; + if (strcmp(reply, "") != 0) return -1; + + put_key(TEST_NAMESPACE, TEST_KEYNAME, (unsigned char *)TEST_KEYVALUE, + strlen(TEST_KEYVALUE)); + if (list_keys(TEST_NAMESPACE, reply) != 0) return -1; + if (strcmp(reply, TEST_KEYNAME) != 0) return -1; + + put_key(TEST_NAMESPACE, TEST_KEYNAME2, (unsigned char *)TEST_KEYVALUE, + strlen(TEST_KEYVALUE)); + + if (list_keys(TEST_NAMESPACE, reply) != 0) return -1; + sprintf(buf, "%s %s", TEST_KEYNAME2, TEST_KEYNAME); + if (strcmp(reply, buf) != 0) return -1; + + return EXIT_SUCCESS; +} + +TESTFUNC all_tests[] = { + FUNC_NAME(init_keystore), + FUNC_NAME(reset_keystore), + FUNC_NAME(get_state), + FUNC_NAME(passwd), + FUNC_NAME(lock), + FUNC_NAME(unlock), + FUNC_NAME(put_key), + FUNC_NAME(get_key), + FUNC_NAME(remove_key), + FUNC_NAME(list_keys), +}; + +int main(int argc, char **argv) { + int i, ret; + for (i = 0 ; i < (int)(sizeof(all_tests)/sizeof(TESTFUNC)) ; ++i) { + setup(); + if ((ret = all_tests[i].func()) != EXIT_SUCCESS) { + fprintf(stderr, "ERROR in function %s\n", all_tests[i].name); + return ret; + } else { + fprintf(stderr, "function %s PASSED!\n", all_tests[i].name); + } + teardown(); + } + return EXIT_SUCCESS; +} diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h index edd0cae..e524e2a 100644 --- a/include/utils/ResourceTypes.h +++ b/include/utils/ResourceTypes.h @@ -1655,7 +1655,8 @@ public: ssize_t resolveReference(Res_value* inOutValue, ssize_t blockIndex, uint32_t* outLastRef = NULL, - uint32_t* inoutTypeSpecFlags = NULL) const; + uint32_t* inoutTypeSpecFlags = NULL, + ResTable_config* outConfig = NULL) const; enum { TMP_BUFFER_SIZE = 16 @@ -1729,7 +1730,8 @@ public: */ ssize_t resolveAttributeReference(Res_value* inOutValue, ssize_t blockIndex, uint32_t* outLastRef = NULL, - uint32_t* inoutTypeSpecFlags = NULL) const; + uint32_t* inoutTypeSpecFlags = NULL, + ResTable_config* inoutConfig = NULL) const; void dumpToLog() const; diff --git a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp index eec645e..ab02fa0 100644 --- a/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp +++ b/libs/surfaceflinger/DisplayHardware/DisplayHardware.cpp @@ -197,6 +197,9 @@ void DisplayHardware::init(uint32_t dpy) LOGW("ro.sf.lcd_density not defined, using 160 dpi by default."); strcpy(property, "160"); } + } else { + /* for the emulator case, reset the dpi values too */ + mDpiX = mDpiY = atoi(property); } mDensity = atoi(property) * (1.0f/160.0f); diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp index bbaeedc..7a277fe 100644 --- a/libs/surfaceflinger/SurfaceFlinger.cpp +++ b/libs/surfaceflinger/SurfaceFlinger.cpp @@ -692,9 +692,14 @@ void SurfaceFlinger::handleTransaction(uint32_t transactionFlags) // some layers might have been removed, so // we need to update the regions they're exposing. - size_t c = mRemovedLayers.size(); + const SortedVector<LayerBase*>& removedLayers(mRemovedLayers); + size_t c = removedLayers.size(); if (c) { mVisibleRegionsDirty = true; + while (c--) { + mDirtyRegionRemovedLayer.orSelf( + removedLayers[c]->visibleRegionScreen); + } } const LayerVector& currentLayers = mCurrentState.layersSortedByZ; @@ -734,17 +739,15 @@ void SurfaceFlinger::computeVisibleRegions( layer->validateVisibility(planeTransform); // start with the whole surface at its current location - const Layer::State& s = layer->drawingState(); - const Rect bounds(layer->visibleBounds()); + const Layer::State& s(layer->drawingState()); // handle hidden surfaces by setting the visible region to empty Region opaqueRegion; Region visibleRegion; Region coveredRegion; - if (UNLIKELY((s.flags & ISurfaceComposer::eLayerHidden) || !s.alpha)) { - visibleRegion.clear(); - } else { + if (LIKELY(!(s.flags & ISurfaceComposer::eLayerHidden) && s.alpha)) { const bool translucent = layer->needsBlending(); + const Rect bounds(layer->visibleBounds()); visibleRegion.set(bounds); coveredRegion = visibleRegion; @@ -791,12 +794,16 @@ void SurfaceFlinger::computeVisibleRegions( layer->setVisibleRegion(visibleRegion); layer->setCoveredRegion(coveredRegion); - // If a secure layer is partially visible, lockdown the screen! + // If a secure layer is partially visible, lock-down the screen! if (layer->isSecure() && !visibleRegion.isEmpty()) { secureFrameBuffer = true; } } + // invalidate the areas where a layer was removed + dirtyRegion.orSelf(mDirtyRegionRemovedLayer); + mDirtyRegionRemovedLayer.clear(); + mSecureFrameBuffer = secureFrameBuffer; opaqueRegion = aboveOpaqueLayers; } diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h index 15913f2..0d63e1d 100644 --- a/libs/surfaceflinger/SurfaceFlinger.h +++ b/libs/surfaceflinger/SurfaceFlinger.h @@ -351,6 +351,7 @@ private: // Can only accessed from the main thread, these members // don't need synchronization Region mDirtyRegion; + Region mDirtyRegionRemovedLayer; Region mInvalidRegion; Region mWormholeRegion; Client* mLastScheduledBroadcast; diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp index 4dca8bd..0831f4a 100644 --- a/libs/utils/ResourceTypes.cpp +++ b/libs/utils/ResourceTypes.cpp @@ -1486,7 +1486,7 @@ ssize_t ResTable::Theme::getAttribute(uint32_t resID, Res_value* outValue, ssize_t ResTable::Theme::resolveAttributeReference(Res_value* inOutValue, ssize_t blockIndex, uint32_t* outLastRef, - uint32_t* inoutTypeSpecFlags) const + uint32_t* inoutTypeSpecFlags, ResTable_config* inoutConfig) const { //printf("Resolving type=0x%x\n", inOutValue->dataType); if (inOutValue->dataType == Res_value::TYPE_ATTRIBUTE) { @@ -1498,7 +1498,8 @@ ssize_t ResTable::Theme::resolveAttributeReference(Res_value* inOutValue, return blockIndex; } } - return mTable.resolveReference(inOutValue, blockIndex, outLastRef); + return mTable.resolveReference(inOutValue, blockIndex, outLastRef, + inoutTypeSpecFlags, inoutConfig); } void ResTable::Theme::dumpToLog() const @@ -1891,7 +1892,8 @@ ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag } ssize_t ResTable::resolveReference(Res_value* value, ssize_t blockIndex, - uint32_t* outLastRef, uint32_t* inoutTypeSpecFlags) const + uint32_t* outLastRef, uint32_t* inoutTypeSpecFlags, + ResTable_config* outConfig) const { int count=0; while (blockIndex >= 0 && value->dataType == value->TYPE_REFERENCE @@ -1899,7 +1901,8 @@ ssize_t ResTable::resolveReference(Res_value* value, ssize_t blockIndex, if (outLastRef) *outLastRef = value->data; uint32_t lastRef = value->data; uint32_t newFlags = 0; - const ssize_t newIndex = getResource(value->data, value, true, &newFlags); + const ssize_t newIndex = getResource(value->data, value, true, &newFlags, + outConfig); //LOGI("Resolving reference d=%p: newIndex=%d, t=0x%02x, d=%p\n", // (void*)lastRef, (int)newIndex, (int)value->dataType, (void*)value->data); //printf("Getting reference 0x%08x: newIndex=%d\n", value->data, newIndex); diff --git a/vpn/java/android/net/vpn/PptpProfile.java b/vpn/java/android/net/vpn/PptpProfile.java index c68bb71..b4b7be5 100644 --- a/vpn/java/android/net/vpn/PptpProfile.java +++ b/vpn/java/android/net/vpn/PptpProfile.java @@ -16,15 +16,41 @@ package android.net.vpn; +import android.os.Parcel; + /** * The profile for PPTP type of VPN. * {@hide} */ public class PptpProfile extends VpnProfile { private static final long serialVersionUID = 1L; + private boolean mEncryption = true; @Override public VpnType getType() { return VpnType.PPTP; } + + /** + * Enables/disables the encryption for PPTP tunnel. + */ + public void setEncryptionEnabled(boolean enabled) { + mEncryption = enabled; + } + + public boolean isEncryptionEnabled() { + return mEncryption; + } + + @Override + protected void readFromParcel(Parcel in) { + super.readFromParcel(in); + mEncryption = in.readInt() > 0; + } + + @Override + public void writeToParcel(Parcel parcel, int flags) { + super.writeToParcel(parcel, flags); + parcel.writeInt(mEncryption ? 1 : 0); + } } diff --git a/vpn/java/android/net/vpn/VpnManager.java b/vpn/java/android/net/vpn/VpnManager.java index 0bf2346..e448e5a 100644 --- a/vpn/java/android/net/vpn/VpnManager.java +++ b/vpn/java/android/net/vpn/VpnManager.java @@ -50,6 +50,10 @@ public class VpnManager { public static final int VPN_ERROR_CONNECTION_FAILED = 2; /** Error code to indicate the server is not known. */ public static final int VPN_ERROR_UNKNOWN_SERVER = 3; + /** Error code to indicate an error from challenge response. */ + public static final int VPN_ERROR_CHALLENGE = 4; + /** Error code to indicate an error of remote server hanging up. */ + public static final int VPN_ERROR_REMOTE_HUNG_UP = 5; private static final int VPN_ERROR_NO_ERROR = 0; public static final String PROFILES_PATH = "/data/misc/vpn/profiles"; |