Revert "SSL Fix by default, Now use TLS (1.2, 1.1, 1) by default" (#339)

This commit is contained in:
flightlevel
2016-05-14 22:42:16 +10:00
parent 28199ab4be
commit 0746616b43
4 changed files with 175 additions and 197 deletions

View File

@@ -1,28 +1,13 @@
using System.Collections.ObjectModel; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CurlSharp namespace CurlSharp
{ {
/// <summary>
/// Our SSL FIX for CURL contain authorized Ciphers for SSL Communications
/// </summary>
public class SSLFix public class SSLFix
{ {
// Our CiphersList public const string CipherList = "rsa_aes_128_sha,ecdhe_rsa_aes_256_sha,ecdhe_ecdsa_aes_128_sha";
private static readonly ReadOnlyCollection<string> Ciphers = new ReadOnlyCollection<string>( new[] {
// Default supported ciphers by Jackett
"rsa_aes_128_sha",
"ecdhe_rsa_aes_256_sha",
"ecdhe_ecdsa_aes_128_sha"
});
/// <summary>
/// List of ciphers supported by Jackett
/// </summary>
/// <returns>Formatted string of ciphers</returns>
public static string CiphersList()
{
// Comma-Separated list of ciphers
return string.Join(",", Ciphers);
}
} }
} }

View File

@@ -127,11 +127,11 @@ namespace Jackett
} }
} }
if (Startup.DoSSLFix.GetValueOrDefault(true)) if (Startup.DoSSLFix == true)
{ {
// http://stackoverflow.com/questions/31107851/how-to-fix-curl-35-cannot-communicate-securely-with-peer-no-common-encryptio // http://stackoverflow.com/questions/31107851/how-to-fix-curl-35-cannot-communicate-securely-with-peer-no-common-encryptio
// https://git.fedorahosted.org/cgit/mod_nss.git/plain/docs/mod_nss.html // https://git.fedorahosted.org/cgit/mod_nss.git/plain/docs/mod_nss.html
easy.SslCipherList = SSLFix.CiphersList(); easy.SslCipherList = SSLFix.CipherList;
easy.FreshConnect = true; easy.FreshConnect = true;
easy.ForbidReuse = true; easy.ForbidReuse = true;
} }

View File

@@ -69,13 +69,6 @@ namespace Jackett.Utils.Clients
proxyServer = new WebProxy(Startup.ProxyConnection, false); proxyServer = new WebProxy(Startup.ProxyConnection, false);
useProxy = true; useProxy = true;
} }
// SecurityProtocolType values below not available in Mono < 4.3
const int SecurityProtocolTypeTls11 = 768;
const int SecurityProtocolTypeTls12 = 3072;
// Specify to use TLS 1.2 as default connection
ServicePointManager.SecurityProtocol |= (SecurityProtocolType)(SecurityProtocolTypeTls12 | SecurityProtocolTypeTls11);
var client = new HttpClient(new HttpClientHandler var client = new HttpClient(new HttpClientHandler
{ {
CookieContainer = cookies, CookieContainer = cookies,

View File

@@ -1,116 +1,116 @@
using AutoMapper; using AutoMapper;
using CurlSharp; using CurlSharp;
using Jackett.Models; using Jackett.Models;
using Jackett.Services; using Jackett.Services;
using NLog; using NLog;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Net.Http; using System.Net.Http;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Jackett.Utils.Clients namespace Jackett.Utils.Clients
{ {
public class UnixSafeCurlWebClient : IWebClient public class UnixSafeCurlWebClient : IWebClient
{ {
IProcessService processService; IProcessService processService;
Logger logger; Logger logger;
IConfigurationService configService; IConfigurationService configService;
public UnixSafeCurlWebClient(IProcessService p, Logger l, IConfigurationService c) public UnixSafeCurlWebClient(IProcessService p, Logger l, IConfigurationService c)
{ {
processService = p; processService = p;
logger = l; logger = l;
configService = c; configService = c;
} }
public void Init() public void Init()
{ {
} }
public async Task<WebClientByteResult> GetBytes(WebRequest request) public async Task<WebClientByteResult> GetBytes(WebRequest request)
{ {
logger.Debug(string.Format("UnixSafeCurlWebClient:GetBytes(Url:{0})", request.Url)); logger.Debug(string.Format("UnixSafeCurlWebClient:GetBytes(Url:{0})", request.Url));
var result = await Run(request); var result = await Run(request);
logger.Debug(string.Format("UnixSafeCurlWebClient: Returning {0} => {1} bytes", result.Status, (result.Content == null ? "<NULL>" : result.Content.Length.ToString()))); logger.Debug(string.Format("UnixSafeCurlWebClient: Returning {0} => {1} bytes", result.Status, (result.Content == null ? "<NULL>" : result.Content.Length.ToString())));
return result; return result;
} }
public async Task<WebClientStringResult> GetString(WebRequest request) public async Task<WebClientStringResult> GetString(WebRequest request)
{ {
logger.Debug(string.Format("UnixSafeCurlWebClient:GetString(Url:{0})", request.Url)); logger.Debug(string.Format("UnixSafeCurlWebClient:GetString(Url:{0})", request.Url));
var result = await Run(request); var result = await Run(request);
logger.Debug(string.Format("UnixSafeCurlWebClient: Returning {0} => {1}", result.Status, (result.Content == null ? "<NULL>" : Encoding.UTF8.GetString(result.Content)))); logger.Debug(string.Format("UnixSafeCurlWebClient: Returning {0} => {1}", result.Status, (result.Content == null ? "<NULL>" : Encoding.UTF8.GetString(result.Content))));
return Mapper.Map<WebClientStringResult>(result); return Mapper.Map<WebClientStringResult>(result);
} }
private async Task<WebClientByteResult> Run(WebRequest request) private async Task<WebClientByteResult> Run(WebRequest request)
{ {
var args = new StringBuilder(); var args = new StringBuilder();
if (Startup.ProxyConnection != null) if (Startup.ProxyConnection != null)
{ {
args.AppendFormat("-x " + Startup.ProxyConnection + " "); args.AppendFormat("-x " + Startup.ProxyConnection + " ");
} }
args.AppendFormat("--url \"{0}\" ", request.Url); args.AppendFormat("--url \"{0}\" ", request.Url);
if (request.EmulateBrowser) if (request.EmulateBrowser)
args.AppendFormat("-i -sS --user-agent \"{0}\" ", BrowserUtil.ChromeUserAgent); args.AppendFormat("-i -sS --user-agent \"{0}\" ", BrowserUtil.ChromeUserAgent);
else else
args.AppendFormat("-i -sS --user-agent \"{0}\" ", "Jackett/" + configService.GetVersion()); args.AppendFormat("-i -sS --user-agent \"{0}\" ", "Jackett/" + configService.GetVersion());
if (!string.IsNullOrWhiteSpace(request.Cookies)) if (!string.IsNullOrWhiteSpace(request.Cookies))
{ {
args.AppendFormat("--cookie \"{0}\" ", request.Cookies); args.AppendFormat("--cookie \"{0}\" ", request.Cookies);
} }
if (!string.IsNullOrWhiteSpace(request.Referer)) if (!string.IsNullOrWhiteSpace(request.Referer))
{ {
args.AppendFormat("--referer \"{0}\" ", request.Referer); args.AppendFormat("--referer \"{0}\" ", request.Referer);
} }
if (!string.IsNullOrEmpty(request.RawBody)) if (!string.IsNullOrEmpty(request.RawBody))
{ {
var postString = StringUtil.PostDataFromDict(request.PostData); var postString = StringUtil.PostDataFromDict(request.PostData);
args.AppendFormat("--data \"{0}\" ", request.RawBody.Replace("\"", "\\\"")); args.AppendFormat("--data \"{0}\" ", request.RawBody.Replace("\"", "\\\""));
} else if (request.PostData != null && request.PostData.Count() > 0) } else if (request.PostData != null && request.PostData.Count() > 0)
{ {
var postString = StringUtil.PostDataFromDict(request.PostData); var postString = StringUtil.PostDataFromDict(request.PostData);
args.AppendFormat("--data \"{0}\" ", postString); args.AppendFormat("--data \"{0}\" ", postString);
} }
var tempFile = Path.GetTempFileName(); var tempFile = Path.GetTempFileName();
args.AppendFormat("--output \"{0}\" ", tempFile); args.AppendFormat("--output \"{0}\" ", tempFile);
if (Startup.DoSSLFix.GetValueOrDefault(true)) if (Startup.DoSSLFix == true)
{ {
// http://stackoverflow.com/questions/31107851/how-to-fix-curl-35-cannot-communicate-securely-with-peer-no-common-encryptio // http://stackoverflow.com/questions/31107851/how-to-fix-curl-35-cannot-communicate-securely-with-peer-no-common-encryptio
// https://git.fedorahosted.org/cgit/mod_nss.git/plain/docs/mod_nss.html // https://git.fedorahosted.org/cgit/mod_nss.git/plain/docs/mod_nss.html
args.Append("--cipher " + SSLFix.CiphersList()); args.Append("--cipher " + SSLFix.CipherList);
} }
if (Startup.IgnoreSslErrors == true) if (Startup.IgnoreSslErrors == true)
{ {
args.Append("-k "); args.Append("-k ");
} }
args.Append("-H \"Accept-Language: en-US,en\" "); args.Append("-H \"Accept-Language: en-US,en\" ");
args.Append("-H \"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\" "); args.Append("-H \"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\" ");
string stdout = null; string stdout = null;
await Task.Run(() => await Task.Run(() =>
{ {
stdout = processService.StartProcessAndGetOutput(System.Environment.OSVersion.Platform == PlatformID.Unix ? "curl" : "curl.exe", args.ToString() , true); stdout = processService.StartProcessAndGetOutput(System.Environment.OSVersion.Platform == PlatformID.Unix ? "curl" : "curl.exe", args.ToString() , true);
}); });
var outputData = File.ReadAllBytes(tempFile); var outputData = File.ReadAllBytes(tempFile);
File.Delete(tempFile); File.Delete(tempFile);
stdout = Encoding.UTF8.GetString(outputData); stdout = Encoding.UTF8.GetString(outputData);
var result = new WebClientByteResult(); var result = new WebClientByteResult();
var headSplit = stdout.IndexOf("\r\n\r\n"); var headSplit = stdout.IndexOf("\r\n\r\n");
if (headSplit < 0) if (headSplit < 0)
throw new Exception("Invalid response"); throw new Exception("Invalid response");
var headers = stdout.Substring(0, headSplit); var headers = stdout.Substring(0, headSplit);
if (Startup.ProxyConnection != null) if (Startup.ProxyConnection != null)
{ {
// the proxy provided headers too so we need to split headers again // the proxy provided headers too so we need to split headers again
@@ -121,39 +121,39 @@ namespace Jackett.Utils.Clients
headSplit = headSplit1; headSplit = headSplit1;
} }
} }
var headerCount = 0; var headerCount = 0;
var cookieBuilder = new StringBuilder(); var cookieBuilder = new StringBuilder();
var cookies = new List<Tuple<string, string>>(); var cookies = new List<Tuple<string, string>>();
foreach (var header in headers.Split(new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries)) foreach (var header in headers.Split(new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries))
{ {
if (headerCount == 0) if (headerCount == 0)
{ {
var responseCode = int.Parse(header.Split(' ')[1]); var responseCode = int.Parse(header.Split(' ')[1]);
result.Status = (HttpStatusCode)responseCode; result.Status = (HttpStatusCode)responseCode;
} }
else else
{ {
var headerSplitIndex = header.IndexOf(':'); var headerSplitIndex = header.IndexOf(':');
if (headerSplitIndex > 0) if (headerSplitIndex > 0)
{ {
var name = header.Substring(0, headerSplitIndex).ToLowerInvariant(); var name = header.Substring(0, headerSplitIndex).ToLowerInvariant();
var value = header.Substring(headerSplitIndex + 1); var value = header.Substring(headerSplitIndex + 1);
switch (name) switch (name)
{ {
case "set-cookie": case "set-cookie":
var nameSplit = value.IndexOf('='); var nameSplit = value.IndexOf('=');
if (nameSplit > -1) if (nameSplit > -1)
{ {
cookies.Add(new Tuple<string, string>(value.Substring(0, nameSplit), value.Substring(0, value.IndexOf(';') + 1))); cookies.Add(new Tuple<string, string>(value.Substring(0, nameSplit), value.Substring(0, value.IndexOf(';') + 1)));
} }
break; break;
case "location": case "location":
result.RedirectingTo = value.Trim(); result.RedirectingTo = value.Trim();
break; break;
case "refresh": case "refresh":
//"Refresh: 8;URL=/cdn-cgi/l/chk_jschl?pass=1451000679.092-1vJFUJLb9R" //"Refresh: 8;URL=/cdn-cgi/l/chk_jschl?pass=1451000679.092-1vJFUJLb9R"
var redirval = ""; var redirval = "";
var start = value.IndexOf("="); var start = value.IndexOf("=");
var end = value.IndexOf(";"); var end = value.IndexOf(";");
var len = value.Length; var len = value.Length;
@@ -167,31 +167,31 @@ namespace Jackett.Utils.Clients
result.Status = System.Net.HttpStatusCode.Redirect; result.Status = System.Net.HttpStatusCode.Redirect;
var redirtime = Int32.Parse(value.Substring(0, end)); var redirtime = Int32.Parse(value.Substring(0, end));
System.Threading.Thread.Sleep(redirtime * 1000); System.Threading.Thread.Sleep(redirtime * 1000);
} }
break; break;
} }
} }
} }
headerCount++; headerCount++;
} }
foreach (var cookieGroup in cookies.GroupBy(c => c.Item1)) foreach (var cookieGroup in cookies.GroupBy(c => c.Item1))
{ {
cookieBuilder.AppendFormat("{0} ", cookieGroup.Last().Item2); cookieBuilder.AppendFormat("{0} ", cookieGroup.Last().Item2);
} }
result.Cookies = cookieBuilder.ToString().Trim(); result.Cookies = cookieBuilder.ToString().Trim();
result.Content = new byte[outputData.Length - (headSplit + 3)]; result.Content = new byte[outputData.Length - (headSplit + 3)];
var dest = 0; var dest = 0;
for (int i = headSplit + 4; i < outputData.Length; i++) for (int i = headSplit + 4; i < outputData.Length; i++)
{ {
result.Content[dest] = outputData[i]; result.Content[dest] = outputData[i];
dest++; dest++;
} }
logger.Debug("WebClientByteResult returned " + result.Status); logger.Debug("WebClientByteResult returned " + result.Status);
ServerUtil.ResureRedirectIsFullyQualified(request, result); ServerUtil.ResureRedirectIsFullyQualified(request, result);
return result; return result;
} }
} }
} }