Saved password security

This commit is contained in:
KZ 2015-08-07 20:09:13 +01:00
parent 1725550b21
commit 6d0aa05761
44 changed files with 340 additions and 62 deletions

View File

@ -54,6 +54,10 @@
<HintPath>..\packages\Autofac.WebApi2.Owin.3.2.0\lib\net45\Autofac.Integration.WebApi.Owin.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="AutoMapper, Version=4.0.4.0, Culture=neutral, PublicKeyToken=be96cd2c38ef1005, processorArchitecture=MSIL">
<HintPath>..\packages\AutoMapper.4.0.4\lib\net45\AutoMapper.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="CsQuery, Version=1.3.3.249, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\CsQuery.1.3.4\lib\net40\CsQuery.dll</HintPath>
<Private>True</Private>
@ -70,6 +74,7 @@
<HintPath>..\packages\Microsoft.AspNet.Identity.Core.2.2.1\lib\net45\Microsoft.AspNet.Identity.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.CSharp" />
<Reference Include="Microsoft.Owin, Version=3.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll</HintPath>
<Private>True</Private>
@ -155,6 +160,7 @@
<ItemGroup>
<Compile Include="Indexers\BakaBTTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Services\ProtectionServiceTests.cs" />
<Compile Include="TestBase.cs" />
<Compile Include="TestIIndexerManagerServiceHelper.cs" />
<Compile Include="TestUtil.cs" />
@ -162,7 +168,9 @@
<Compile Include="Util\ServerUtilTests.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="app.config">
<SubType>Designer</SubType>
</None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>

View File

@ -0,0 +1,30 @@
using Jackett.Services;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autofac;
namespace JackettTest.Services
{
[TestFixture]
class ProtectionServiceTests : TestBase
{
[Test]
public void Should_be_able_to_encrypt_and_decrypt()
{
var ss = TestUtil.Container.Resolve<IServerService>();
ss.Config.InstanceId = "12345678";
var ps = TestUtil.Container.Resolve<IProtectionService>();
var input = "test123";
var protectedInput = ps.Protect(input);
var output = ps.UnProtect(protectedInput);
Assert.AreEqual(output, input);
Assert.AreNotEqual(input, protectedInput);
}
}
}

View File

@ -22,6 +22,10 @@
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="AutoMapper" publicKeyToken="be96cd2c38ef1005" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.4.0" newVersion="4.0.4.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /></startup></configuration>

View File

@ -4,6 +4,7 @@
<package id="Autofac.Owin" version="3.1.0" targetFramework="net45" />
<package id="Autofac.WebApi2" version="3.4.0" targetFramework="net45" />
<package id="Autofac.WebApi2.Owin" version="3.2.0" targetFramework="net45" />
<package id="AutoMapper" version="4.0.4" targetFramework="net45" />
<package id="CsQuery" version="1.3.4" targetFramework="net45" />
<package id="FluentAssertions" version="3.4.1" targetFramework="net45" />
<package id="Microsoft.AspNet.Identity.Core" version="2.2.1" targetFramework="net45" />

View File

@ -153,7 +153,7 @@ namespace Jackett.Controllers
var postData = await ReadPostDataJson();
var indexer = indexerService.GetIndexer((string)postData["indexer"]);
var config = await indexer.GetConfigurationForSetup();
jsonReply["config"] = config.ToJson();
jsonReply["config"] = config.ToJson(null);
jsonReply["caps"] = indexer.TorznabCaps.CapsToJson();
jsonReply["name"] = indexer.DisplayName;
jsonReply["result"] = "success";
@ -192,7 +192,7 @@ namespace Jackett.Controllers
baseIndexer.ResetBaseConfig();
if (ex is ExceptionWithConfigData)
{
jsonReply["config"] = ((ExceptionWithConfigData)ex).ConfigData.ToJson();
jsonReply["config"] = ((ExceptionWithConfigData)ex).ConfigData.ToJson(null);
} else
{
logger.Error(ex, "Exception in Configure");

View File

@ -25,7 +25,7 @@ namespace Jackett.Indexers
private string DownloadUrl { get { return SiteLink + "torrents.php?action=download&id="; } }
private string GuidUrl { get { return SiteLink + "torrents.php?torrentid="; } }
public AlphaRatio(IIndexerManagerService i, IWebClient w, Logger l)
public AlphaRatio(IIndexerManagerService i, IWebClient w, Logger l, IProtectionService ps)
: base(name: "AlphaRatio",
description: "Legendary",
link: "https://alpharatio.cc/",
@ -33,6 +33,7 @@ namespace Jackett.Indexers
manager: i,
client: w,
logger: l,
p: ps,
configData: new ConfigurationDataBasicLogin())
{
webclient = w;

View File

@ -33,7 +33,7 @@ namespace Jackett.Indexers
set { base.configData = value; }
}
public AnimeBytes(IIndexerManagerService i, IWebClient client, Logger l)
public AnimeBytes(IIndexerManagerService i, IWebClient client, Logger l, IProtectionService ps)
: base(name: "AnimeBytes",
link: "https://animebytes.tv/",
description: "Powered by Tentacles",
@ -41,6 +41,7 @@ namespace Jackett.Indexers
client: client,
caps: new TorznabCapabilities(TorznabCatType.Anime),
logger: l,
p: ps,
configData: new ConfigurationDataAnimeBytes())
{
}

View File

@ -32,7 +32,7 @@ namespace Jackett.Indexers
set { base.configData = value; }
}
public BB(IIndexerManagerService i, Logger l, IWebClient w)
public BB(IIndexerManagerService i, Logger l, IWebClient w, IProtectionService ps)
: base(name: "bB",
description: "bB",
link: "http://www.reddit.com/r/baconbits/",
@ -40,6 +40,7 @@ namespace Jackett.Indexers
manager: i,
client: w,
logger: l,
p: ps,
configData: new ConfigurationDataBasicLogin())
{
}

View File

@ -28,7 +28,7 @@ namespace Jackett.Indexers
set { base.configData = value; }
}
public BakaBT(IIndexerManagerService i, IWebClient wc, Logger l)
public BakaBT(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
: base(name: "BakaBT",
description: "Anime Community",
link: "http://bakabt.me/",
@ -36,6 +36,7 @@ namespace Jackett.Indexers
manager: i,
client: wc,
logger: l,
p: ps,
configData: new ConfigurationDataBasicLogin())
{
}

View File

@ -29,6 +29,8 @@ namespace Jackett.Indexers
protected static List<CachedQueryResult> cache = new List<CachedQueryResult>();
protected static readonly TimeSpan cacheTime = new TimeSpan(0, 9, 0);
protected IWebClient webclient;
protected IProtectionService protectionService;
protected string CookieHeader
{
get { return configData.CookieHeader.Value; }
@ -39,7 +41,7 @@ namespace Jackett.Indexers
private List<CategoryMapping> categoryMapping = new List<CategoryMapping>();
public BaseIndexer(string name, string link, string description, IIndexerManagerService manager, IWebClient client, Logger logger, ConfigurationData configData, TorznabCapabilities caps = null)
public BaseIndexer(string name, string link, string description, IIndexerManagerService manager, IWebClient client, Logger logger, ConfigurationData configData, IProtectionService p, TorznabCapabilities caps = null)
{
if (!link.EndsWith("/"))
throw new Exception("Site link must end with a slash.");
@ -50,6 +52,7 @@ namespace Jackett.Indexers
this.logger = logger;
indexerService = manager;
webclient = client;
protectionService = p;
this.configData = configData;
@ -91,7 +94,7 @@ namespace Jackett.Indexers
protected virtual void SaveConfig()
{
indexerService.SaveConfig(this as IIndexer, configData.ToJson(forDisplay: false));
indexerService.SaveConfig(this as IIndexer, configData.ToJson(protectionService,forDisplay: false));
}
protected void OnParseError(string results, Exception ex)
@ -182,7 +185,7 @@ namespace Jackett.Indexers
{
if (jsonConfig is JArray)
{
configData.LoadValuesFromJson(jsonConfig);
configData.LoadValuesFromJson(jsonConfig, protectionService);
IsConfigured = true;
}
// read and upgrade old settings file format

View File

@ -28,7 +28,7 @@ namespace Jackett.Indexers
set { base.configData = value; }
}
public BeyondHD(IIndexerManagerService i, Logger l, IWebClient w)
public BeyondHD(IIndexerManagerService i, Logger l, IWebClient w, IProtectionService ps)
: base(name: "BeyondHD",
description: "Without BeyondHD, your HDTV is just a TV",
link: "https://beyondhd.me/",
@ -36,6 +36,7 @@ namespace Jackett.Indexers
manager: i,
client: w,
logger: l,
p: ps,
configData: new ConfigurationDataCookie())
{
}

View File

@ -30,7 +30,7 @@ namespace Jackett.Indexers
set { base.configData = value; }
}
public BitHdtv(IIndexerManagerService i, Logger l, IWebClient w)
public BitHdtv(IIndexerManagerService i, Logger l, IWebClient w, IProtectionService ps)
: base(name: "BIT-HDTV",
description: "Home of high definition invites",
link: "https://www.bit-hdtv.com/",
@ -38,6 +38,7 @@ namespace Jackett.Indexers
manager: i,
client: w,
logger: l,
p: ps,
configData: new ConfigurationDataBasicLogin())
{
}

View File

@ -32,7 +32,7 @@ namespace Jackett.Indexers
set { base.configData = value; }
}
public BitMeTV(IIndexerManagerService i, Logger l, IWebClient c)
public BitMeTV(IIndexerManagerService i, Logger l, IWebClient c, IProtectionService ps)
: base(name: "BitMeTV",
description: "TV Episode specialty tracker",
link: "http://www.bitmetv.org/",
@ -40,6 +40,7 @@ namespace Jackett.Indexers
manager: i,
client: c,
logger: l,
p: ps,
configData: new ConfigurationDataCaptchaLogin())
{
}

View File

@ -27,7 +27,7 @@ namespace Jackett.Indexers
set { base.configData = value; }
}
public Demonoid(IIndexerManagerService i, Logger l, IWebClient wc)
public Demonoid(IIndexerManagerService i, Logger l, IWebClient wc, IProtectionService ps)
: base(name: "Demonoid",
description: "Demonoid",
link: "http://www.demonoid.pw/",
@ -35,6 +35,7 @@ namespace Jackett.Indexers
manager: i,
client: wc,
logger: l,
p: ps,
configData: new ConfigurationDataBasicLogin())
{
}

View File

@ -24,7 +24,7 @@ namespace Jackett.Indexers
set { base.configData = value; }
}
public FrenchTorrentDb(IIndexerManagerService i, Logger l, IWebClient c)
public FrenchTorrentDb(IIndexerManagerService i, Logger l, IWebClient c, IProtectionService ps)
: base(name: "FrenchTorrentDb",
description: "One the biggest French Torrent Tracker",
link: "http://www.frenchtorrentdb.com/",
@ -32,6 +32,7 @@ namespace Jackett.Indexers
manager: i,
client: c,
logger: l,
p: ps,
configData: new ConfigurationDataCookie())
{
}

View File

@ -33,7 +33,7 @@ namespace Jackett.Indexers
set { base.configData = value; }
}
public Freshon(IIndexerManagerService i, Logger l, IWebClient c)
public Freshon(IIndexerManagerService i, Logger l, IWebClient c, IProtectionService ps)
: base(name: "FreshOnTV",
description: "Our goal is to provide the latest stuff in the TV show domain",
link: "https://freshon.tv/",
@ -41,6 +41,7 @@ namespace Jackett.Indexers
manager: i,
client: c,
logger: l,
p: ps,
configData: new ConfigurationDataBasicLogin())
{
}

View File

@ -28,7 +28,7 @@ namespace Jackett.Indexers
set { base.configData = value; }
}
public HDSpace(IIndexerManagerService i, IWebClient wc, Logger l)
public HDSpace(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
: base(name: "HD-Space",
description: "Sharing The Universe",
link: "https://hd-space.org/",
@ -36,6 +36,7 @@ namespace Jackett.Indexers
manager: i,
client: wc,
logger: l,
p: ps,
configData: new ConfigurationDataBasicLogin())
{
}

View File

@ -30,7 +30,7 @@ namespace Jackett.Indexers
set { base.configData = value; }
}
public HDTorrents(IIndexerManagerService i, Logger l, IWebClient w)
public HDTorrents(IIndexerManagerService i, Logger l, IWebClient w, IProtectionService ps)
: base(name: "HD-Torrents",
description: "HD-Torrents is a private torrent website with HD torrents and strict rules on their content.",
link: "http://hdts.ru/",// Of the accessible domains the .ru seems the most reliable. https://hdts.ru | https://hd-torrents.org | https://hd-torrents.net | https://hd-torrents.me
@ -38,6 +38,7 @@ namespace Jackett.Indexers
manager: i,
client: w,
logger: l,
p: ps,
configData: new ConfigurationDataBasicLogin())
{
}

View File

@ -29,7 +29,7 @@ namespace Jackett.Indexers
set { base.configData = value; }
}
public IPTorrents(IIndexerManagerService i, IWebClient wc, Logger l)
public IPTorrents(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
: base(name: "IPTorrents",
description: "Always a step ahead.",
link: "https://iptorrents.com/",
@ -37,6 +37,7 @@ namespace Jackett.Indexers
manager: i,
client: wc,
logger: l,
p: ps,
configData: new ConfigurationDataBasicLogin())
{
AddCategoryMapping(72, TorznabCatType.Movies);

View File

@ -30,7 +30,7 @@ namespace Jackett.Indexers
set { base.configData = value; }
}
public ImmortalSeed(IIndexerManagerService i, IWebClient wc, Logger l)
public ImmortalSeed(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
: base(name: "ImmortalSeed",
description: "ImmortalSeed",
link: "http://immortalseed.me/",
@ -38,6 +38,7 @@ namespace Jackett.Indexers
manager: i,
client: wc,
logger: l,
p: ps,
configData: new ConfigurationDataBasicLogin())
{
AddCategoryMapping(32, TorznabCatType.Anime);

View File

@ -31,7 +31,7 @@ namespace Jackett.Indexers
set { base.configData = value; }
}
public MoreThanTV(IIndexerManagerService i, IWebClient c, Logger l)
public MoreThanTV(IIndexerManagerService i, IWebClient c, Logger l, IProtectionService ps)
: base(name: "MoreThanTV",
description: "ROMANIAN Private Torrent Tracker for TV / MOVIES, and the internal tracker for the release group DRACULA.",
link: "https://www.morethan.tv/",
@ -39,6 +39,7 @@ namespace Jackett.Indexers
manager: i,
client: c,
logger: l,
p: ps,
configData: new ConfigurationDataBasicLogin())
{
}

View File

@ -27,7 +27,7 @@ namespace Jackett.Indexers
set { base.configData = value; }
}
public Pretome(IIndexerManagerService i, IWebClient wc, Logger l)
public Pretome(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
: base(name: "PreToMe",
description: "BitTorrent site for High Quality, High Definition (HD) movies and TV Shows",
link: "https://pretome.info/",
@ -35,6 +35,7 @@ namespace Jackett.Indexers
client: wc,
manager: i,
logger: l,
p: ps,
configData: new ConfigurationDataPinNumber())
{
}

View File

@ -29,7 +29,7 @@ namespace Jackett.Indexers
set { base.configData = value; }
}
public PrivateHD(IIndexerManagerService i, IWebClient wc, Logger l)
public PrivateHD(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
: base(name: "PrivateHD",
description: "BitTorrent site for High Quality, High Definition (HD) movies and TV Shows",
link: "https://privatehd.to/",
@ -37,6 +37,7 @@ namespace Jackett.Indexers
manager: i,
client: wc,
logger: l,
p: ps,
configData: new ConfigurationDataBasicLogin())
{
AddCategoryMapping(1, TorznabCatType.Movies);

View File

@ -32,7 +32,7 @@ namespace Jackett.Indexers
set { base.configData = value; }
}
public RuTor(IIndexerManagerService i, Logger l, IWebClient wc)
public RuTor(IIndexerManagerService i, Logger l, IWebClient wc, IProtectionService ps)
: base(name: "RUTor",
description: "Свободный торрент трекер",
link: "http://rutor.org/",
@ -40,6 +40,7 @@ namespace Jackett.Indexers
manager: i,
client: wc,
logger: l,
p: ps,
configData: new ConfigurationDataRuTor(defaultSiteLink))
{
TorznabCaps.Categories.Add(TorznabCatType.Anime);

View File

@ -27,7 +27,7 @@ namespace Jackett.Indexers
set { base.configData = value; }
}
public SceneAccess(IIndexerManagerService i, IWebClient c, Logger l)
public SceneAccess(IIndexerManagerService i, IWebClient c, Logger l, IProtectionService ps)
: base(name: "SceneAccess",
description: "Your gateway to the scene",
link: "https://sceneaccess.eu/",
@ -35,6 +35,7 @@ namespace Jackett.Indexers
manager: i,
client: c,
logger: l,
p: ps,
configData: new ConfigurationDataBasicLogin())
{
}

View File

@ -30,7 +30,7 @@ namespace Jackett.Indexers
set { base.configData = value; }
}
public SceneTime(IIndexerManagerService i, Logger l, IWebClient w)
public SceneTime(IIndexerManagerService i, Logger l, IWebClient w, IProtectionService ps)
: base(name: "SceneTime",
description: "Always on time",
link: "https://www.scenetime.com/",
@ -38,6 +38,7 @@ namespace Jackett.Indexers
manager: i,
client: w,
logger: l,
p: ps,
configData: new ConfigurationDataBasicLogin())
{
}

View File

@ -36,7 +36,7 @@ namespace Jackett.Indexers
set { base.configData = value; }
}
public ShowRSS(IIndexerManagerService i, Logger l, IWebClient wc)
public ShowRSS(IIndexerManagerService i, Logger l, IWebClient wc, IProtectionService ps)
: base(name: "ShowRSS",
description: "showRSS is a service that allows you to keep track of your favorite TV shows",
link: defaultSiteLink,
@ -44,6 +44,7 @@ namespace Jackett.Indexers
manager: i,
client: wc,
logger: l,
p: ps,
configData: new ConfigurationDataUrl(defaultSiteLink))
{
}

View File

@ -33,7 +33,7 @@ namespace Jackett.Indexers
set { base.configData = value; }
}
public SpeedCD(IIndexerManagerService i, Logger l, IWebClient wc)
public SpeedCD(IIndexerManagerService i, Logger l, IWebClient wc, IProtectionService ps)
: base(name: "Speed.cd",
description: "Your home now!",
link: "http://speed.cd/",
@ -41,6 +41,7 @@ namespace Jackett.Indexers
manager: i,
client: wc,
logger: l,
p: ps,
configData: new ConfigurationDataBasicLogin())
{
}

View File

@ -37,7 +37,7 @@ namespace Jackett.Indexers
}
public Strike(IIndexerManagerService i, Logger l, IWebClient wc)
public Strike(IIndexerManagerService i, Logger l, IWebClient wc, IProtectionService ps)
: base(name: "Strike",
description: "Torrent search engine",
link: defaultSiteLink,
@ -45,6 +45,7 @@ namespace Jackett.Indexers
manager: i,
client: wc,
logger: l,
p: ps,
configData: new ConfigurationDataUrl(defaultSiteLink))
{
}

View File

@ -35,7 +35,7 @@ namespace Jackett.Indexers
set { base.configData = value; }
}
public T411(IIndexerManagerService i, Logger l, IWebClient wc)
public T411(IIndexerManagerService i, Logger l, IWebClient wc, IProtectionService ps)
: base(name: "T411",
description: "French Torrent Tracker",
link: "http://www.t411.io/",
@ -43,6 +43,7 @@ namespace Jackett.Indexers
manager: i,
client: wc,
logger: l,
p: ps,
configData: new ConfigurationDataLoginTokin())
{
CommentsUrl = SiteLink + "/torrents/{0}";

View File

@ -37,7 +37,7 @@ namespace Jackett.Indexers
set { base.configData = value; }
}
public ThePirateBay(IIndexerManagerService i, Logger l, IWebClient wc)
public ThePirateBay(IIndexerManagerService i, Logger l, IWebClient wc, IProtectionService ps)
: base(name: "The Pirate Bay",
description: "The worlds largest bittorrent indexer",
link: defaultSiteLink,
@ -45,6 +45,7 @@ namespace Jackett.Indexers
manager: i,
client: wc,
logger: l,
p: ps,
configData: new ConfigurationDataUrl(defaultSiteLink))
{
}

View File

@ -30,7 +30,7 @@ namespace Jackett.Indexers
set { base.configData = value; }
}
public TorrentBytes(IIndexerManagerService i, IWebClient wc, Logger l)
public TorrentBytes(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
: base(name: "TorrentBytes",
description: "A decade of torrentbytes",
link: "https://www.torrentbytes.net/",
@ -38,6 +38,7 @@ namespace Jackett.Indexers
manager: i,
client: wc,
logger: l,
p: ps,
configData: new ConfigurationDataBasicLogin())
{

View File

@ -31,7 +31,7 @@ namespace Jackett.Indexers
set { base.configData = value; }
}
public TorrentDay(IIndexerManagerService i, Logger l, IWebClient wc)
public TorrentDay(IIndexerManagerService i, Logger l, IWebClient wc, IProtectionService ps)
: base(name: "TorrentDay",
description: "TorrentDay",
link: "https://torrentday.eu/",
@ -39,6 +39,7 @@ namespace Jackett.Indexers
manager: i,
client: wc,
logger: l,
p: ps,
configData: new ConfigurationDataBasicLogin())
{

View File

@ -29,7 +29,7 @@ namespace Jackett.Indexers
set { base.configData = value; }
}
public TorrentLeech(IIndexerManagerService i, Logger l, IWebClient wc)
public TorrentLeech(IIndexerManagerService i, Logger l, IWebClient wc, IProtectionService ps)
: base(name: "TorrentLeech",
description: "This is what happens when you seed",
link: "http://www.torrentleech.org/",
@ -37,6 +37,7 @@ namespace Jackett.Indexers
manager: i,
client: wc,
logger: l,
p: ps,
configData: new ConfigurationDataBasicLogin())
{
}

View File

@ -29,7 +29,7 @@ namespace Jackett.Indexers
set { base.configData = value; }
}
public TorrentShack(IIndexerManagerService i, Logger l, IWebClient wc)
public TorrentShack(IIndexerManagerService i, Logger l, IWebClient wc, IProtectionService ps)
: base(name: "TorrentShack",
description: "TorrentShack",
link: "http://torrentshack.me/",
@ -37,6 +37,7 @@ namespace Jackett.Indexers
client: wc,
manager: i,
logger: l,
p: ps,
configData: new ConfigurationDataBasicLogin())
{
}

View File

@ -37,7 +37,7 @@ namespace Jackett.Indexers
}
public Torrentz(IIndexerManagerService i, Logger l, IWebClient wc)
public Torrentz(IIndexerManagerService i, Logger l, IWebClient wc, IProtectionService ps)
: base(name: "Torrentz",
description: "Torrentz is a meta-search engine and a Multisearch. This means we just search other search engines.",
link: defaultSiteLink,
@ -45,6 +45,7 @@ namespace Jackett.Indexers
manager: i,
client: wc,
logger: l,
p: ps,
configData: new ConfigurationDataUrl(defaultSiteLink))
{
}

View File

@ -30,7 +30,7 @@ namespace Jackett.Indexers
set { base.configData = value; }
}
public NCore(IIndexerManagerService i, IWebClient wc, Logger l)
public NCore(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
: base(name: "nCore",
description: "A Hungarian private torrent site.",
link: "https://ncore.cc/",
@ -38,6 +38,7 @@ namespace Jackett.Indexers
manager: i,
client: wc,
logger: l,
p: ps,
configData: new ConfigurationDataNCore())
{
}

View File

@ -148,6 +148,7 @@
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http.WebRequest" />
<Reference Include="System.Security" />
<Reference Include="System.ServiceProcess" />
<Reference Include="System.Web" />
<Reference Include="System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
@ -207,6 +208,7 @@
<Compile Include="Indexers\TorrentLeech.cs" />
<Compile Include="Indexers\TorrentShack.cs" />
<Compile Include="Indexers\Torrentz.cs" />
<Compile Include="JackettProtectedAttribute.cs" />
<Compile Include="Models\CachedLog.cs" />
<Compile Include="Models\CachedResult.cs" />
<Compile Include="Models\CategoryMapping.cs" />
@ -228,6 +230,7 @@
<Compile Include="Models\TrackerCacheResult.cs" />
<Compile Include="Services\CacheService.cs" />
<Compile Include="Services\LogCacheService.cs" />
<Compile Include="Services\ProtectionService.cs" />
<Compile Include="Utils\Clients\BaseWebResult.cs" />
<Compile Include="Utils\Clients\UnixLibCurlWebClient.cs" />
<Compile Include="Utils\Clients\WebByteResult.cs" />

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Jackett
{
public class JackettProtectedAttribute : Attribute
{
}
}

View File

@ -19,6 +19,7 @@ namespace Jackett.Models.Config
public bool AllowExternal { get; set; }
public string APIKey { get; set; }
public string AdminPassword { get; set; }
public string InstanceId { get; set; }
public string[] GetListenAddresses(bool? external = null)
{
@ -38,19 +39,5 @@ namespace Jackett.Models.Config
};
}
}
public string GenerateApi()
{
var chars = "abcdefghijklmnopqrstuvwxyz0123456789";
var randBytes = new byte[32];
var rngCsp = new RNGCryptoServiceProvider();
rngCsp.GetBytes(randBytes);
var key = "";
foreach (var b in randBytes)
{
key += chars[b % chars.Length];
}
return key;
}
}
}

View File

@ -1,4 +1,5 @@
using Jackett.Utils;
using Jackett.Services;
using Jackett.Utils;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
@ -11,6 +12,8 @@ namespace Jackett.Models.IndexerConfig
{
public abstract class ConfigurationData
{
const string PASSWORD_REPLACEMENT = "|||%%PREVJACKPASSWD%%|||";
public enum ItemType
{
InputString,
@ -27,12 +30,12 @@ namespace Jackett.Models.IndexerConfig
}
public ConfigurationData(JToken json)
public ConfigurationData(JToken json, IProtectionService ps)
{
LoadValuesFromJson(json);
LoadValuesFromJson(json, ps);
}
public void LoadValuesFromJson(JToken json)
public void LoadValuesFromJson(JToken json, IProtectionService ps= null)
{
var arr = (JArray)json;
foreach (var item in GetItems(forDisplay: false))
@ -44,7 +47,21 @@ namespace Jackett.Models.IndexerConfig
switch (item.ItemType)
{
case ItemType.InputString:
((StringItem)item).Value = arrItem.Value<string>("value");
var sItem = (StringItem)item;
var newValue = arrItem.Value<string>("value");
if (string.Equals(item.Name, "password", StringComparison.InvariantCultureIgnoreCase))
{
if (newValue != PASSWORD_REPLACEMENT)
{
sItem.Value = newValue;
if (ps != null)
sItem.Value = ps.UnProtect(newValue);
}
} else
{
sItem.Value = newValue;
}
break;
case ItemType.HiddenData:
((HiddenItem)item).Value = arrItem.Value<string>("value");
@ -56,7 +73,7 @@ namespace Jackett.Models.IndexerConfig
}
}
public JToken ToJson(bool forDisplay = true)
public JToken ToJson(IProtectionService ps, bool forDisplay = true)
{
var items = GetItems(forDisplay);
var jArray = new JArray();
@ -71,7 +88,18 @@ namespace Jackett.Models.IndexerConfig
case ItemType.InputString:
case ItemType.HiddenData:
case ItemType.DisplayInfo:
jObject["value"] = ((StringItem)item).Value;
var value = ((StringItem)item).Value;
if (string.Equals(item.Name, "password", StringComparison.InvariantCultureIgnoreCase))
{
if (string.IsNullOrEmpty(value))
value = string.Empty;
else if (forDisplay)
value = PASSWORD_REPLACEMENT;
else if (ps != null)
value = ps.Protect(value);
}
jObject["value"] = value;
break;
case ItemType.InputBool:
jObject["value"] = ((BoolItem)item).Value;

View File

@ -0,0 +1,150 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace Jackett.Services
{
public interface IProtectionService
{
string Protect(string plainText);
string UnProtect(string plainText);
}
public class ProtectionService : IProtectionService
{
DataProtectionScope PROTECTION_SCOPE = DataProtectionScope.LocalMachine;
const string APPLICATION_KEY = "Dvz66r3n8vhTGip2/quiw5ISyM37f7L2iOdupzdKmzkvXGhAgQiWK+6F+4qpxjPVNks1qO7LdWuVqRlzgLzeW8mChC6JnBMUS1Fin4N2nS9lh4XPuCZ1che75xO92Nk2vyXUo9KSFG1hvEszAuLfG2Mcg1r0sVyVXd2gQDU/TbY=";
IServerService serverService;
public ProtectionService(IServerService s)
{
serverService = s;
if (System.Environment.OSVersion.Platform == PlatformID.Unix)
{
// We should not be running as root and will only have access to the local store.
PROTECTION_SCOPE = DataProtectionScope.CurrentUser;
}
}
public string Protect(string plainText)
{
if (string.IsNullOrEmpty(plainText))
return string.Empty;
var plainBytes = Encoding.UTF8.GetBytes(plainText);
var appKey = Convert.FromBase64String(APPLICATION_KEY);
var instanceKey = Encoding.UTF8.GetBytes(serverService.Config.InstanceId);
var entropy = new byte[appKey.Length + instanceKey.Length];
Buffer.BlockCopy(instanceKey, 0, entropy, 0, instanceKey.Length);
Buffer.BlockCopy(appKey, 0, entropy, instanceKey.Length, appKey.Length);
var protectedBytes = ProtectedData.Protect(plainBytes, entropy, PROTECTION_SCOPE);
using (MemoryStream ms = new MemoryStream())
{
using (RijndaelManaged AES = new RijndaelManaged())
{
AES.KeySize = 256;
AES.BlockSize = 128;
var key = new Rfc2898DeriveBytes(instanceKey, instanceKey.Reverse().ToArray(), 64);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);
AES.Mode = CipherMode.CBC;
using (var cs = new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(protectedBytes, 0, protectedBytes.Length);
cs.Close();
}
protectedBytes = ms.ToArray();
}
}
return Convert.ToBase64String(protectedBytes);
}
public string UnProtect(string plainText)
{
if (string.IsNullOrEmpty(plainText))
return string.Empty;
var protectedBytes = Convert.FromBase64String(plainText);
var instanceKey = Encoding.UTF8.GetBytes(serverService.Config.InstanceId);
using (MemoryStream ms = new MemoryStream())
{
using (RijndaelManaged AES = new RijndaelManaged())
{
AES.KeySize = 256;
AES.BlockSize = 128;
var key = new Rfc2898DeriveBytes(instanceKey, instanceKey.Reverse().ToArray(), 64);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);
AES.Mode = CipherMode.CBC;
using (var cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(protectedBytes, 0, protectedBytes.Length);
cs.Close();
}
protectedBytes = ms.ToArray();
}
}
var appKey = Convert.FromBase64String(APPLICATION_KEY);
var entropy = new byte[appKey.Length + instanceKey.Length];
Buffer.BlockCopy(instanceKey, 0, entropy, 0, instanceKey.Length);
Buffer.BlockCopy(appKey, 0, entropy, instanceKey.Length, appKey.Length);
var unprotectedBytes = ProtectedData.Unprotect(protectedBytes, entropy, PROTECTION_SCOPE);
return Encoding.UTF8.GetString(unprotectedBytes);
}
public void Protect<T>(T obj)
{
var type = obj.GetType();
foreach(var property in type.GetProperties(BindingFlags.SetProperty |BindingFlags.GetProperty | BindingFlags.Public))
{
if(property.GetCustomAttributes(typeof(JackettProtectedAttribute), false).Count() > 0)
{
var value = property.GetValue(obj);
if(value is string)
{
var protectedString = Protect(value as string);
property.SetValue(obj, protectedString);
}
}
}
}
public void UnProtect<T>(T obj)
{
var type = obj.GetType();
foreach (var property in type.GetProperties(BindingFlags.SetProperty | BindingFlags.GetProperty | BindingFlags.Public))
{
if (property.GetCustomAttributes(typeof(JackettProtectedAttribute), false).Count() > 0)
{
var value = property.GetValue(obj);
if (value is string)
{
var unprotectedString = UnProtect(value as string);
property.SetValue(obj, unprotectedString);
}
}
}
}
}
}

View File

@ -1,6 +1,7 @@
using Autofac;
using Jackett.Models.Config;
using Jackett.Services;
using Jackett.Utils;
using Jackett.Utils.Clients;
using Microsoft.Owin.Hosting;
using Newtonsoft.Json.Linq;
@ -16,6 +17,7 @@ using System.IO;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
@ -91,12 +93,16 @@ namespace Jackett.Services
}
if (string.IsNullOrWhiteSpace(config.APIKey))
{
config.APIKey = config.GenerateApi();
}
config.APIKey = StringUtil.GenerateRandom(32);
configService.SaveConfig<ServerConfig>(config);
}
if (string.IsNullOrWhiteSpace(config.InstanceId))
{
config.InstanceId = StringUtil.GenerateRandom(64);
configService.SaveConfig<ServerConfig>(config);
}
}
public void SaveConfig()

View File

@ -51,7 +51,6 @@ namespace Jackett.Utils
return sb.ToString();
}
public static string GetExceptionDetails(this Exception exception)
{
var properties = exception.GetType()
@ -74,5 +73,21 @@ namespace Jackett.Utils
{
return string.Join("&", collection.AllKeys.Select(a => a + "=" + HttpUtility.UrlEncode(collection[a])));
}
public static string GenerateRandom(int length)
{
var chars = "abcdefghijklmnopqrstuvwxyz0123456789";
var randBytes = new byte[length];
using (var rngCsp = new RNGCryptoServiceProvider())
{
rngCsp.GetBytes(randBytes);
var key = "";
foreach (var b in randBytes)
{
key += chars[b % chars.Length];
}
return key;
}
}
}
}