release
FongMi 1 year ago
parent 1b712b77fd
commit 0239fd601d
  1. 4
      catvod/src/main/java/com/github/catvod/net/OkHttp.java
  2. 89
      catvod/src/main/java/com/github/catvod/net/authenticator/CombineAuthenticator.java
  3. 54
      catvod/src/main/java/com/github/catvod/net/interceptor/AuthInterceptor.java
  4. 41
      catvod/src/main/java/com/github/catvod/utils/Util.java

@ -6,7 +6,7 @@ import android.text.TextUtils;
import androidx.collection.ArrayMap;
import com.github.catvod.bean.Doh;
import com.github.catvod.net.authenticator.CombineAuthenticator;
import com.github.catvod.net.interceptor.AuthInterceptor;
import com.github.catvod.net.interceptor.RequestInterceptor;
import com.github.catvod.net.interceptor.ResponseInterceptor;
import com.github.catvod.utils.Path;
@ -188,7 +188,7 @@ public class OkHttp {
}
private static OkHttpClient.Builder getBuilder() {
OkHttpClient.Builder builder = new OkHttpClient.Builder().authenticator(new CombineAuthenticator()).cookieJar(OkCookieJar.get()).addInterceptor(requestInterceptor()).addNetworkInterceptor(responseInterceptor()).connectTimeout(TIMEOUT, TimeUnit.MILLISECONDS).readTimeout(TIMEOUT, TimeUnit.MILLISECONDS).writeTimeout(TIMEOUT, TimeUnit.MILLISECONDS).dns(dns()).hostnameVerifier((hostname, session) -> true).sslSocketFactory(getSSLContext().getSocketFactory(), trustAllCertificates());
OkHttpClient.Builder builder = new OkHttpClient.Builder().cookieJar(OkCookieJar.get()).addInterceptor(requestInterceptor()).addInterceptor(new AuthInterceptor()).addNetworkInterceptor(responseInterceptor()).connectTimeout(TIMEOUT, TimeUnit.MILLISECONDS).readTimeout(TIMEOUT, TimeUnit.MILLISECONDS).writeTimeout(TIMEOUT, TimeUnit.MILLISECONDS).dns(dns()).hostnameVerifier((hostname, session) -> true).sslSocketFactory(getSSLContext().getSocketFactory(), trustAllCertificates());
HttpLoggingInterceptor logging = new HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY);
builder.proxySelector(get().proxy ? selector() : defaultSelector);
//builder.addNetworkInterceptor(logging);

@ -1,89 +0,0 @@
package com.github.catvod.net.authenticator;
import com.github.catvod.utils.Util;
import com.google.common.net.HttpHeaders;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import okhttp3.Authenticator;
import okhttp3.HttpUrl;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.Route;
public class CombineAuthenticator implements Authenticator {
private final Map<String, String> authCache;
public CombineAuthenticator() {
authCache = new ConcurrentHashMap<>();
}
@Override
public Request authenticate(Route route, Response response) {
if (response.code() != 401) return null;
HttpUrl url = response.request().url();
String userInfo = url.uri().getUserInfo();
String host = response.request().url().host();
String authHeader = response.header(HttpHeaders.WWW_AUTHENTICATE);
if (authCache.containsKey(host)) {
return response.request().newBuilder().header(HttpHeaders.AUTHORIZATION, authCache.get(host)).build();
}
if (userInfo == null) {
return null;
}
if (authHeader.startsWith("Digest")) {
Map<String, String> params = parseAuthHeader(authHeader.substring(7));
String[] parts = userInfo.split(":", 2);
String username = parts[0];
String password = parts[1];
String uri = url.encodedPath();
String qop = params.get("qop");
String realm = params.get("realm");
String nonce = params.get("nonce");
String opaque = params.get("opaque");
String method = response.request().method();
String digestAuth = getDigestAuth(username, password, realm, nonce, qop, opaque, method, uri);
authCache.put(host, digestAuth);
return response.request().newBuilder().header(HttpHeaders.AUTHORIZATION, digestAuth).build();
} else {
String basicAuth = Util.basic(userInfo);
authCache.put(host, basicAuth);
return response.request().newBuilder().header(HttpHeaders.AUTHORIZATION, basicAuth).build();
}
}
private String getDigestAuth(String username, String password, String realm, String nonce, String qop, String opaque, String method, String uri) {
String nc = "00000001";
String hash2 = Util.md5(method + ":" + uri);
String cnonce = Long.toHexString(System.currentTimeMillis());
String hash1 = Util.md5(username + ":" + realm + ":" + password);
String response = Util.md5(hash1 + ":" + nonce + ":" + nc + ":" + cnonce + ":" + (qop != null ? qop : "") + ":" + hash2);
StringBuilder authValue = new StringBuilder("Digest ");
authValue.append("username=\"").append(username).append("\", ");
if (realm != null) authValue.append("realm=\"").append(realm).append("\", ");
if (nonce != null) authValue.append("nonce=\"").append(nonce).append("\", ");
authValue.append("uri=\"").append(uri).append("\", ");
authValue.append("cnonce=\"").append(cnonce).append("\", ");
authValue.append("nc=").append(nc).append(", ");
if (qop != null) authValue.append("qop=\"").append(qop).append("\", ");
authValue.append("response=\"").append(response).append("\"");
if (opaque != null) authValue.append(", opaque=\"").append(opaque).append("\"");
return authValue.toString();
}
private Map<String, String> parseAuthHeader(String header) {
Map<String, String> params = new HashMap<>();
for (String part : header.split(",\\s*")) {
String[] kv = part.split("=", 2);
if (kv.length == 2) params.put(kv[0].trim(), kv[1].trim().replace("\"", ""));
}
return params;
}
}

@ -0,0 +1,54 @@
package com.github.catvod.net.interceptor;
import androidx.annotation.NonNull;
import com.github.catvod.utils.Util;
import com.google.common.net.HttpHeaders;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
public class AuthInterceptor implements Interceptor {
private final Map<String, String> authCache;
public AuthInterceptor() {
authCache = new ConcurrentHashMap<>();
}
@NonNull
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
String host = request.url().host();
String user = request.url().uri().getUserInfo();
if (authCache.containsKey(host)) {
return chain.proceed(request.newBuilder().header(HttpHeaders.AUTHORIZATION, authCache.get(host)).build());
}
Response response = chain.proceed(request);
if (response.code() != 401 || user == null) {
return response;
}
String authValue;
String authHeader = response.header(HttpHeaders.WWW_AUTHENTICATE);
if (authHeader != null && authHeader.startsWith("Digest")) {
authValue = Util.digest(authHeader, request);
} else {
authValue = Util.basic(user);
}
response.close();
authCache.put(host, authValue);
return chain.proceed(request.newBuilder().header(HttpHeaders.AUTHORIZATION, authValue).build());
}
}

@ -18,8 +18,11 @@ import java.net.SocketException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import okhttp3.OkHttp;
import okhttp3.Request;
public class Util {
@ -123,6 +126,35 @@ public class Util {
}
}
public static String digest(String authHeader, Request request) {
Map<String, String> params = parse(authHeader.substring(7));
String userInfo = request.url().uri().getUserInfo();
String[] parts = userInfo.split(":", 2);
String nc = "00000001";
String username = parts[0];
String password = parts[1];
String qop = params.get("qop");
String realm = params.get("realm");
String nonce = params.get("nonce");
String opaque = params.get("opaque");
String uri = request.url().encodedPath();
String hash1 = Util.md5(username + ":" + realm + ":" + password);
String hash2 = Util.md5(request.method() + ":" + uri);
String cnonce = Long.toHexString(System.currentTimeMillis());
String response = Util.md5(hash1 + ":" + nonce + ":" + nc + ":" + cnonce + ":" + (qop != null ? qop : "") + ":" + hash2);
StringBuilder auth = new StringBuilder("Digest ");
auth.append("username=\"").append(username).append("\", ");
if (realm != null) auth.append("realm=\"").append(realm).append("\", ");
if (nonce != null) auth.append("nonce=\"").append(nonce).append("\", ");
auth.append("uri=\"").append(uri).append("\", ");
auth.append("cnonce=\"").append(cnonce).append("\", ");
auth.append("nc=").append(nc).append(", ");
if (qop != null) auth.append("qop=\"").append(qop).append("\", ");
auth.append("response=\"").append(response).append("\"");
if (opaque != null) auth.append(", opaque=\"").append(opaque).append("\"");
return auth.toString();
}
private static String getHostAddress() throws SocketException {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
NetworkInterface interfaces = en.nextElement();
@ -135,4 +167,13 @@ public class Util {
}
return "";
}
private static Map<String, String> parse(String header) {
Map<String, String> params = new HashMap<>();
for (String part : header.split(",\\s*")) {
String[] kv = part.split("=", 2);
if (kv.length == 2) params.put(kv[0].trim(), kv[1].trim().replace("\"", ""));
}
return params;
}
}

Loading…
Cancel
Save