parent
1ca3ff900d
commit
d1e591b448
@ -0,0 +1,39 @@ |
||||
/* |
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
* |
||||
* 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.arialyy.aria.core.common; |
||||
|
||||
import android.support.annotation.StringDef; |
||||
import java.lang.annotation.Retention; |
||||
import java.lang.annotation.RetentionPolicy; |
||||
|
||||
@StringDef({ |
||||
ProtocolType.Default, |
||||
ProtocolType.SSL, |
||||
ProtocolType.SSLv3, |
||||
ProtocolType.TLS, |
||||
ProtocolType.TLSv1, |
||||
ProtocolType.TLSv1_1, |
||||
ProtocolType.TLSv1_2 |
||||
}) |
||||
@Retention(RetentionPolicy.SOURCE) public @interface ProtocolType { |
||||
String Default = "Default"; |
||||
String SSL = "SSL"; |
||||
String SSLv3 = "SSLv3"; |
||||
String TLS = "TLS"; |
||||
String TLSv1 = "TLSv1"; |
||||
String TLSv1_1 = "TLSv1.1"; |
||||
String TLSv1_2 = "TLSv1.2"; |
||||
} |
@ -0,0 +1,104 @@ |
||||
/* |
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria)
|
||||
* |
||||
* 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.arialyy.aria.core.common.ftp; |
||||
|
||||
import android.text.TextUtils; |
||||
import com.arialyy.aria.core.FtpUrlEntity; |
||||
import com.arialyy.aria.core.common.ProtocolType; |
||||
import com.arialyy.aria.core.inf.AbsTarget; |
||||
import com.arialyy.aria.core.inf.ITarget; |
||||
|
||||
/** |
||||
* FTP SSL/TSL配置 |
||||
*/ |
||||
public class FTPSSLConfig<TARGET extends AbsTarget> implements ITarget { |
||||
private final String TAG = "FTPSSLConfig"; |
||||
private TARGET mTarget; |
||||
private FtpUrlEntity mUrlEntity; |
||||
|
||||
public FTPSSLConfig(TARGET target) { |
||||
mTarget = target; |
||||
mUrlEntity = mTarget.getTaskEntity().getUrlEntity(); |
||||
} |
||||
|
||||
/** |
||||
* 设置协议类型 |
||||
* |
||||
* @param protocol {@link ProtocolType} |
||||
*/ |
||||
public FTPSSLConfig setProtocol(@ProtocolType String protocol) { |
||||
if (TextUtils.isEmpty(protocol)) { |
||||
throw new NullPointerException("协议为空"); |
||||
} |
||||
mUrlEntity.SSLProtocol = protocol; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* 设置证书别名 |
||||
* |
||||
* @param keyAlias 别名 |
||||
*/ |
||||
public FTPSSLConfig setAlias(String keyAlias) { |
||||
if (TextUtils.isEmpty(keyAlias)) { |
||||
throw new NullPointerException("别名为空"); |
||||
} |
||||
mUrlEntity.keyAlias = keyAlias; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* 设置证书密码 |
||||
* |
||||
* @param storePass 私钥密码 |
||||
*/ |
||||
public FTPSSLConfig setStorePass(String storePass) { |
||||
if (TextUtils.isEmpty(storePass)) { |
||||
throw new NullPointerException("证书密码为空"); |
||||
} |
||||
mUrlEntity.storePass = storePass; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* 设置证书路径 |
||||
* |
||||
* @param storePath 证书路径 |
||||
*/ |
||||
public FTPSSLConfig setStorePath(String storePath) { |
||||
if (TextUtils.isEmpty(storePath)) { |
||||
throw new NullPointerException("证书路径为空"); |
||||
} |
||||
mUrlEntity.storePath = storePath; |
||||
return this; |
||||
} |
||||
|
||||
@Override public void start() { |
||||
mTarget.start(); |
||||
} |
||||
|
||||
@Override public void stop() { |
||||
mTarget.stop(); |
||||
} |
||||
|
||||
@Override public void resume() { |
||||
mTarget.resume(); |
||||
} |
||||
|
||||
@Override public void cancel() { |
||||
mTarget.cancel(); |
||||
} |
||||
} |
@ -0,0 +1,54 @@ |
||||
package com.arialyy.aria.core.common.ftp; |
||||
|
||||
import com.arialyy.aria.util.ALog; |
||||
import java.io.IOException; |
||||
import java.lang.reflect.Field; |
||||
import java.lang.reflect.Method; |
||||
import java.net.Socket; |
||||
import java.util.Locale; |
||||
import javax.net.ssl.SSLContext; |
||||
import javax.net.ssl.SSLSession; |
||||
import javax.net.ssl.SSLSessionContext; |
||||
import javax.net.ssl.SSLSocket; |
||||
import org.apache.commons.net.ftp.FTPSClient; |
||||
|
||||
public class SSLSessionReuseFTPSClient extends FTPSClient { |
||||
|
||||
SSLSessionReuseFTPSClient(boolean b, SSLContext context) { |
||||
super(b, context); |
||||
} |
||||
|
||||
// adapted from:
|
||||
// https://trac.cyberduck.io/browser/trunk/ftp/src/main/java/ch/cyberduck/core/ftp/FTPClient.java
|
||||
@Override |
||||
protected void _prepareDataSocket_(final Socket socket) throws IOException { |
||||
if (socket instanceof SSLSocket) { |
||||
// Control socket is SSL
|
||||
final SSLSession session = ((SSLSocket) _socket_).getSession(); |
||||
if (session.isValid()) { |
||||
final SSLSessionContext context = session.getSessionContext(); |
||||
try { |
||||
//final Field sessionHostPortCache = context.getClass().getDeclaredField("sessionHostPortCache");
|
||||
final Field sessionHostPortCache = |
||||
context.getClass().getDeclaredField("sessionsByHostAndPort"); |
||||
sessionHostPortCache.setAccessible(true); |
||||
final Object cache = sessionHostPortCache.get(context); |
||||
final Method method = |
||||
cache.getClass().getDeclaredMethod("put", Object.class, Object.class); |
||||
method.setAccessible(true); |
||||
method.invoke(cache, String.format("%s:%s", socket.getInetAddress().getHostName(), |
||||
String.valueOf(socket.getPort())).toLowerCase(Locale.ROOT), session); |
||||
method.invoke(cache, String.format("%s:%s", socket.getInetAddress().getHostAddress(), |
||||
String.valueOf(socket.getPort())).toLowerCase(Locale.ROOT), session); |
||||
ALog.d("tag", "GGGG"); |
||||
} catch (NoSuchFieldException e) { |
||||
throw new IOException(e); |
||||
} catch (Exception e) { |
||||
throw new IOException(e); |
||||
} |
||||
} else { |
||||
throw new IOException("Invalid SSL Session"); |
||||
} |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue