/*
* Copyright 2011 yingxinwu.g@gmail.com
*
* 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 xink.vpn.wrapper;
import java.lang.reflect.Method;
import xink.vpn.AppException;
import xink.vpn.R;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
public class L2tpProfile extends VpnProfile {
/** Key prefix for L2TP VPN. */
public static final String KEY_PREFIX_L2TP_SECRET = "VPN_l";
private KeyStore keyStore;
protected L2tpProfile(final Context ctx, final String stubClass) {
super(ctx, stubClass);
}
public L2tpProfile(final Context ctx) {
super(ctx, "android.net.vpn.L2tpProfile");
}
@Override
public VpnType getType() {
return VpnType.L2TP;
}
/**
* Enables/disables the secret for authenticating tunnel connection.
*/
public void setSecretEnabled(final boolean enabled) {
try {
Method m = getStubClass().getMethod("setSecretEnabled", boolean.class);
m.invoke(getStub(), enabled);
} catch (Throwable e) {
throw new AppException("setSecretEnabled failed", e);
}
}
public boolean isSecretEnabled() {
return this.<Boolean>invokeStubMethod("isSecretEnabled");
}
public void setSecretString(final String secret) {
invokeStubMethod("setSecretString", secret);
}
public String getSecretString() {
return invokeStubMethod("getSecretString");
}
@Override
public void validate() {
super.validate();
if (isSecretEnabled() && TextUtils.isEmpty(getSecretString())) {
throw new InvalidProfileException("secret is empty", R.string.err_empty_secret);
}
}
@Override
public void postConstruct() {
super.postConstruct();
processSecret();
}
@Override
public void postUpdate() {
super.postUpdate();
processSecret();
}
@Override
public void preConnect() {
super.preConnect();
processSecret();
}
protected void processSecret() {
String key = makeKey();
if (isSecretEnabled()) {
String secret = getSecretString();
if (!getKeyStore().put(key, secret)) {
Log.e("xink", "keystore write failed: key=" + key);
}
} else {
getKeyStore().delete(key);
}
}
private String makeKey() {
return KEY_PREFIX_L2TP_SECRET + getId();
}
@Override
public boolean needKeyStoreToSave() {
return isSecretEnabled() && !TextUtils.isEmpty(getSecretString());
}
@Override
public boolean needKeyStoreToConnect() {
return isSecretEnabled();
}
protected KeyStore getKeyStore() {
if (keyStore == null) {
keyStore = new KeyStore(getContext());
}
return keyStore;
}
@Override
public L2tpProfile dulicateToConnect() {
L2tpProfile p = (L2tpProfile) super.dulicateToConnect();
boolean secretEnabled = isSecretEnabled();
p.setSecretEnabled(secretEnabled);
if (secretEnabled) {
p.setSecretString(makeKey());
}
return p;
}
}