Compare commits

...

26 Commits

Author SHA1 Message Date
jackettbot[bot]
3dd5b1e5f0 Update rudub 2025-11-19 01:29:18 +00:00
Garfield69
fb9845d1e3 magnetz: q -> query 2025-11-19 13:03:56 +13:00
Garfield69
70b0aa1f67 linuxtracker: new cat 2025-11-19 06:10:10 +13:00
Garfield69
368afcfc5a hdgalaktik: new size selector. resolves dd11b7e6cd 2025-11-18 16:42:57 +13:00
jackettbot[bot]
29d28e2607 Update rudub 2025-11-18 01:29:11 +00:00
Garfield69
b023e8fe6d clearjav: -> 9.1.7 drop info_hash 2025-11-18 06:56:48 +13:00
Garfield69
d51752f682 kickasstorrents-to: new cat 2025-11-18 06:36:40 +13:00
Garfield69
ec40699cdc hdgalaktik: restore previous size selector. reverts dd11b7e6cd 2025-11-18 06:36:24 +13:00
jackettbot[bot]
3c798127c5 Update rudub 2025-11-17 01:29:17 +00:00
Bogdan
61b263dd98 core: refactor obsolete calls (#16290)
* core: refactor obsolete hashing calls

* core: delete cert callback validation removal in update service

* core: remove deprecated ServicePointManager calls

- Avoid harcoding SSL protocols.
- Lowering DefaultConnectionLimit 1000 to MaxConnectionsPerServer 20

* core: avoid is only supported on windows warnings
2025-11-16 22:05:22 +02:00
ilike2burnthing
dd11b7e6cd hdgalaktik: update size selector & remove cert exception 2025-11-16 19:05:54 +00:00
jackettbot[bot]
bec42c4ac0 Update rudub 2025-11-16 01:29:39 +00:00
Garfield69
9b08d7ad46 hdgalaktik: new layout resolves #13186
necessitates switching to categorydesc
plus new selectors
2025-11-16 13:10:06 +13:00
Garfield69
9311af24b5 uztracker: update cats 2025-11-16 06:01:56 +13:00
jackettbot[bot]
9e5d79d2a4 Update rudub 2025-11-15 01:29:11 +00:00
jackettbot[bot]
15c64f9f66 Update rudub 2025-11-14 01:29:13 +00:00
ilike2burnthing
f1f8f0f756 mvgroup: add flaresolverr info (#16289) 2025-11-13 22:23:12 +00:00
ilike2burnthing
b3d4ec6f23 Update README.md 2025-11-13 17:30:03 +00:00
Garfield69
7f33664f97 sextorrent: new cats 2025-11-14 05:30:19 +13:00
Garfield69
43aaaf4142 torrentqq: bump domain 2025-11-14 05:15:02 +13:00
Garfield69
20a0bedc3b magnetcat: bump alternate domains 2025-11-14 05:13:55 +13:00
ilike2burnthing
31e0a19eeb amigosshare: remove possible trailing spaces (#16288) 2025-11-13 17:21:56 +13:00
jackettbot[bot]
ccb98cbe48 Update rudub 2025-11-13 01:29:07 +00:00
Garfield69
6560931e42 Revert "bump version to 0.25.*"
This reverts commit 46082db9b9.
2025-11-13 05:50:47 +13:00
Garfield69
46082db9b9 bump version to 0.25.* 2025-11-13 05:48:35 +13:00
Bogdan
89f4a9fb89 core: fixed constants usage to determine target framework (#16287) 2025-11-12 17:47:30 +02:00
31 changed files with 168 additions and 284 deletions

View File

@@ -831,7 +831,7 @@ Detailed instructions are available at [Jackett's Wiki](https://github.com/Jacke
## Running Jackett behind a reverse proxy
When running jackett behind a reverse proxy make sure that the original hostname of the request is passed to Jackett. If HTTPS is used also set the X-Forwarded-Proto header to "https". Don't forget to adjust the "Base path override" Jackett option accordingly.
When running Jackett behind a reverse proxy make sure that the original hostname of the request is passed to Jackett. If HTTPS is used also set the X-Forwarded-Proto header to "https". Don't forget to adjust the "Base path override" Jackett option accordingly.
Example config for apache:
```

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<TargetFrameworks>netstandard2.0;net9.0</TargetFrameworks>
<LangVersion>9</LangVersion>
<NoWarn />
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>

View File

@@ -152,7 +152,7 @@ search:
keywordsfilters:
# drop the year from searches since site titles do not include year
- name: re_replace
args: ["(\\b((19|20)\\d{2})\\b)", ""]
args: ["(\\s*\\b((19|20)\\d{2})\\b)", ""]
rows:
selector: "div#fancy-list-group ul.list-group li.list-group-item{{ if .Config.freeleech }}:has(span.badge-success:contains(\"FREE\")){{ else }}{{ end }}"

View File

@@ -94,8 +94,6 @@ search:
selector: details_link
download:
selector: download_link
infohash:
selector: info_hash
files:
selector: num_file
seeders:
@@ -145,4 +143,4 @@ search:
minimumseedtime:
# 7 days (as seconds = 7 x 24 x 60 x 60)
text: 604800
# json UNIT3D 9.1.5 (custom)
# json UNIT3D 9.1.7 (custom)

View File

@@ -5,8 +5,6 @@ description: "HDGalaKtik is a RUSSIAN Semi-Private tracker for MOVIES / TV / GEN
language: ru-RU
type: semi-private
encoding: UTF-8
certificates:
- 89cb539248b0d0cb0e92aa3f286ddfdd8347c3be # CN=mail.trackerpmr.com
links:
- https://www.trackerpmr.com/
- https://freetmd.com/
@@ -16,20 +14,20 @@ legacylinks:
caps:
categorymappings:
- {id: 13, cat: Movies, desc: "Фильмы (Movies)"}
- {id: 6, cat: TV, desc: "Мультфильмы (Cartoons)"}
- {id: 10, cat: Audio, desc: "Музыка (Music)"}
- {id: 26, cat: PC, desc: "Программы (Programs)"}
- {id: 5, cat: Console, desc: "Игры (Games)"}
- {id: 25, cat: Other, desc: "Картинки (Pictures)"}
- {id: 11, cat: TV, desc: "Сериалы (TV Series)"}
- {id: 12, cat: TV/Anime, desc: "Аниме (Anime)"}
- {id: 16, cat: Books, desc: "Книги (Books)"}
- {id: 18, cat: Audio/Video, desc: "Клипы / Ролики (Clips / Trailers)"}
- {id: 22, cat: TV, desc: "ТВ / Передачи (TV)"}
- {id: 27, cat: PC/Mobile-Other, desc: "Игры - Мобила / КПК (Mobile)"}
- {id: 1, cat: PC/ISO, desc: "Образы (ISO)"}
- {id: 4, cat: Other, desc: "Другое (Other)"}
- {id: 13, cat: Movies, desc: "Фильмы"}
- {id: 11, cat: TV, desc: "Сериалы"}
- {id: 6, cat: TV, desc: "Мультфильмы"}
- {id: 10, cat: Audio, desc: "Музыка"}
- {id: 26, cat: PC, desc: "Программы"}
- {id: 5, cat: Console, desc: "Игры"}
- {id: 25, cat: Other, desc: "Картинки"}
- {id: 12, cat: TV/Anime, desc: "Аниме"}
- {id: 16, cat: Books, desc: "Книги"}
- {id: 18, cat: Audio/Video, desc: "Клипы / Ролики"}
- {id: 22, cat: TV, desc: "ТВ / Передачи"}
- {id: 27, cat: PC/Mobile-Other, desc: "Игры - Мобила / КПК"}
- {id: 1, cat: PC/ISO, desc: "Образы"}
- {id: 4, cat: Other, desc: "Другое"}
modes:
search: [q]
@@ -117,24 +115,20 @@ search:
args: ["[^a-zA-Z0-9]+", "%"]
rows:
selector: table.table > tbody > tr.torcontduo
selector: div.torrent-card
fields:
category:
selector: a[href^="browse.php?cat="]
attribute: href
categorydesc:
selector: div.category-badge
optional: true
default: 4
default: Другое
filters:
- name: querystring
args: cat
- name: replace
args: ["---", "Другое"]
title:
selector: a[href^="details.php?id="]
selector: a.torrent-title-link
attribute: title
filters:
- name: regexp
args: \'>(.+?)</div
- name: htmldecode
# normalize to SXXEYY format
- name: re_replace
args: ["(?i)[CС]езоны?[\\s:]*(\\d+(?:-\\d+)?).+?(?:\\s*(?:[CС]ери[ияй]|Эпизод|Выпуски?))[\\s:]*(\\d+(?:-\\d+)?)\\s*из\\s*(\\w?)", "S$1E$2 of $3"]
@@ -193,16 +187,19 @@ search:
- name: append
args: "{{ if .Config.addrussiantotitle }} RUS{{ else }}{{ end }}"
details:
selector: a[href^="details.php?id="]
selector: a.torrent-title-link
attribute: href
# there is either a magnet or a download link
magnet:
selector: a[href^="magnet:?xt="]
attribute: href
optional: true
download:
selector: a[href^="details.php?id="]
selector: a[href^="download.php?id="]
attribute: href
filters:
- name: replace
args: ["details", "download"]
optional: true
poster:
selector: img.s
selector: img.torrent-poster
attribute: src
imdbid:
selector: a[href^="browse.php?imdb="]
@@ -211,46 +208,26 @@ search:
- name: querystring
args: imdb
size:
selector: td:nth-child(4)
selector: div.size-section
seeders:
selector: span[title="Раздают"]
selector: span.peers-seeders
leechers:
selector: span[title="Качают"]
date_day:
# Сегодня в 18:22
# Вчера в 20:52
selector: a[href^="browse.php?date="]:contains("Сегодня"), a[href^="browse.php?date="]:contains("Вчера")
optional: true
filters:
- name: regexp
args: "((Вчера в|Сегодня в)( \\d{2}:\\d{2}))"
- name: replace
args: ["Сегодня в", "Today"]
- name: replace
args: ["Вчера в", "Yesterday"]
- name: fuzzytime
date_year:
# 23:48 24/07
selector: a[href^="browse.php?date="]:contains("/")
optional: true
filters:
- name: regexp
args: "(\\d{2}:\\d{2} \\d{2}/\\d{2})"
- name: append
args: " +03:00" # MSK
- name: dateparse
args: "HH:mm dd/MM zzz"
selector: span.peers-leechers
grabs:
selector: span:has(i.fa-download)
date:
text: "{{ if or .Result.date_year .Result.date_day }}{{ or .Result.date_year .Result.date_day }}{{ else }}now{{ end }}"
selector: div.added-date
filters:
- name: timeago
downloadvolumefactor:
case:
img[src="/pic/freedownload.gif"]: 0
span.bg-success: 0
"*": 1
uploadvolumefactor:
text: 1
minimumratio:
text: 1.0
description:
selector: a[href*="?tag="]
selector: a.tag
attribute: title
# engine n/a

View File

@@ -39,6 +39,7 @@ caps:
- {id: "AnimeLiveAction[English-translated]", cat: TV/Anime, desc: "Anime Live Action English-translated"}
- {id: "AnimeLiveAction[Non-English]", cat: TV/Anime, desc: "Anime Live Action Non-English"}
- {id: "AnimeLiveAction[Raw]", cat: TV/Anime, desc: "Anime Live Action Raw"}
- {id: AnimePictures, cat: Other, desc: Anime Pictures}
- {id: AnimeRaw, cat: TV/Anime, desc: Anime Raw}
- {id: AnimeSubs, cat: TV/Anime, desc: Anime Subs}
- {id: Apps, cat: PC, desc: Apps}

View File

@@ -281,6 +281,7 @@ caps:
- {id: 2281, cat: PC/ISO, desc: "Web Security Dojo"}
- {id: 2246, cat: PC/ISO, desc: "Whonix"}
- {id: 2155, cat: PC/ISO, desc: "Wifislax"}
- {id: 2229, cat: PC/ISO, desc: "XiVa Studio"}
- {id: 2251, cat: PC/ISO, desc: "XigmaNAS"}
- {id: 607, cat: PC/ISO, desc: "Xubuntu"}
- {id: 612, cat: PC/ISO, desc: "Zen"}

View File

@@ -9,15 +9,12 @@ encoding: UTF-8
links:
- https://magnetcatcat.com/
- https://clmclm.com/
- https://www.8800517.xyz/
- https://www.8800518.xyz/
- https://www.8800519.xyz/
- https://www.8800520.xyz/
- https://www.8800521.xyz/
- https://www.8800522.xyz/
- https://www.8800523.xyz/
legacylinks:
- https://www.clm472.sbs/
- https://www.8800498.xyz/
- https://www.8800497.xyz/
- https://www.8800499.xyz/
- https://www.8800500.xyz/
- https://www.8800503.xyz/
- https://www.8800504.xyz/
@@ -31,6 +28,9 @@ legacylinks:
- https://www.8800514.xyz/
- https://www.8800515.xyz/
- https://www.8800516.xyz/
- https://www.8800517.xyz/
- https://www.8800518.xyz/
- https://www.8800520.xyz/
caps:
categorymappings:

View File

@@ -32,7 +32,7 @@ search:
paths:
- path: search
inputs:
q: "{{ if .Keywords }}{{ .Keywords }}{{ else }}*{{ end }}"
query: "{{ if .Keywords }}{{ .Keywords }}{{ else }}*{{ end }}"
rows:
selector: a.list-group-item

View File

@@ -26,6 +26,8 @@ settings:
- name: password
type: password
label: Password
- name: info_flaresolverr
type: info_flaresolverr
- name: info_category_8000
type: info_category_8000
- name: hidef

View File

@@ -26,6 +26,8 @@ settings:
- name: password
type: password
label: Password
- name: info_flaresolverr
type: info_flaresolverr
- name: info_category_8000
type: info_category_8000
- name: hidef

View File

@@ -9,22 +9,8 @@ type: semi-private
encoding: windows-1251
followredirect: true
links:
- https://nov12.rudub.pics/
- https://nov19.rudub.pics/
legacylinks:
- https://oct28.rudub.homes/
- http://oct29.rudub.homes/
- https://oct29.rudub.homes/
- http://oct30.rudub.homes/
- https://oct30.rudub.homes/
- http://oct31.rudub.homes/
- https://oct31.rudub.homes/
- http://nov01.rudub.homes/
- https://nov01.rudub.homes/
- http://nov02.rudub.homes/
- https://nov02.rudub.homes/
- http://nov03.rudub.homes/
- https://nov03.rudub.homes/
- http://nov04.rudub.homes/
- https://nov04.rudub.homes/
- http://nov05.rudub.homes/
- https://nov05.rudub.homes/
@@ -41,6 +27,20 @@ legacylinks:
- http://nov11.rudub.pics/
- https://nov11.rudub.pics/
- http://nov12.rudub.pics/
- https://nov12.rudub.pics/
- http://nov13.rudub.pics/
- https://nov13.rudub.pics/
- http://nov14.rudub.pics/
- https://nov14.rudub.pics/
- http://nov15.rudub.pics/
- https://nov15.rudub.pics/
- http://nov16.rudub.pics/
- https://nov16.rudub.pics/
- http://nov17.rudub.pics/
- https://nov17.rudub.pics/
- http://nov18.rudub.pics/
- https://nov18.rudub.pics/
- http://nov19.rudub.pics/
caps:
categorymappings:
- {id: 1, cat: TV, desc: "TV"}

View File

@@ -51,8 +51,10 @@ caps:
- {id: 41, cat: XXX, desc: "Homemade"}
- {id: 42, cat: XXX, desc: "Pregnant"}
- {id: 43, cat: XXX, desc: "Gay"}
- {id: 1, cat: Movies, desc: "Movie"}
- {id: 2, cat: TV, desc: "TV Show"}
- {id: 45, cat: XXX, desc: "Classic"}
- {id: 44, cat: XXX, desc: "SiteFan"}
- {id: 1, cat: Movies, desc: "Movies"}
- {id: 2, cat: TV, desc: "TV"}
modes:
search: [q]

View File

@@ -7,11 +7,10 @@ type: public
encoding: UTF-8
followredirect: true
links:
- https://torrentqq393.com/
- https://torrentqq394.com/
- https://torrentegg83.com/
legacylinks:
- https://torrentegg68.com/
- https://torrentqq378.com/
- https://torrentegg69.com/
- https://torrentqq379.com/
- https://torrentegg70.com/
@@ -40,6 +39,7 @@ legacylinks:
- https://torrentegg81.com/
- https://torrentqq392.com/
- https://torrentegg82.com/
- https://torrentqq393.com/
caps:
categorymappings:

View File

@@ -31,10 +31,8 @@ caps:
- {id: 190, cat: Movies, desc: " |- Фильмы в 4K и 3D"}
- {id: 34, cat: Movies, desc: " |- Перевод на узбекский"}
- {id: 25, cat: Movies, desc: "Узбекские кинофильмы"}
- {id: 32, cat: Movies, desc: " |- Новинки"}
- {id: 30, cat: Movies, desc: " |- Фильмы 2011-2024 годов"}
- {id: 29, cat: Movies, desc: " |- Фильмы 2000-2010 годов"}
- {id: 26, cat: Movies, desc: " |- Фильмы до 2000 года"}
- {id: 32, cat: Movies, desc: " |- Пр-во Узбекфильм (на русском)"}
- {id: 30, cat: Movies, desc: " |- Пр-во Узбекфильм (на узбекском языке)"}
# Сериалы, Видео и ТВ # Series, Videos and TV
- {id: 97, cat: TV, desc: "Сериалы"}
- {id: 333, cat: TV, desc: " |- Игра престолов / Game of Thrones"}
@@ -85,6 +83,7 @@ caps:
- {id: 132, cat: Audio, desc: " |- Классическая музыа"}
- {id: 125, cat: Audio, desc: " |- New Age, Relax, Meditative & Flamenco"}
- {id: 124, cat: Audio, desc: " |- Фольклор, Народная и Этническая музыка"}
- {id: 338, cat: Audio, desc: " |- Country"}
- {id: 231, cat: Audio, desc: " |- Сборники и альбомы выходившие неофициальными изданиями."}
- {id: 144, cat: Audio, desc: "♫ ROCK & METAL ♫"}
- {id: 201, cat: Audio, desc: " |- Русский Rock, Metal (mp3)"}
@@ -170,6 +169,7 @@ caps:
- {id: 289, cat: PC/Games, desc: " |- Horror"}
- {id: 307, cat: PC/Games, desc: " |- Logic"}
- {id: 304, cat: PC/Games, desc: " |- Lifestyle"}
- {id: 336, cat: PC/Games, desc: " |- Sports"}
- {id: 306, cat: PC/Games, desc: " |- Exploration"}
- {id: 305, cat: PC/Games, desc: " |- Management"}
- {id: 115, cat: PC/Games, desc: " |- Аркады"}

View File

@@ -0,0 +1,34 @@
using System.Security.Cryptography;
using System.Text;
namespace Jackett.Common.Extensions
{
public static class HashingExtensions
{
public static string SHA1Hash(this string input)
{
using var hash = SHA1.Create();
return GetHash(hash.ComputeHash(Encoding.UTF8.GetBytes(input)));
}
public static string SHA256Hash(this string input)
{
using var hash = SHA256.Create();
return GetHash(hash.ComputeHash(Encoding.UTF8.GetBytes(input)));
}
private static string GetHash(byte[] bytes)
{
var stringBuilder = new StringBuilder();
foreach (var b in bytes)
{
stringBuilder.Append(b.ToString("x2"));
}
return stringBuilder.ToString();
}
}
}

View File

@@ -104,7 +104,7 @@ namespace Jackett.Common.Indexers.Definitions
var maxPages = 2; // we scrape only 2 pages for recent torrents
if (!string.IsNullOrWhiteSpace(query.GetQueryString()))
{
searchString = Uri.EscapeUriString(query.GetQueryString());
searchString = Uri.EscapeDataString(query.GetQueryString());
maxPages = MaxSearchPageLimit;
}

View File

@@ -4,12 +4,11 @@ using System.Collections.Specialized;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using AngleSharp.Html.Parser;
using Jackett.Common.Extensions;
using Jackett.Common.Models;
using Jackett.Common.Models.IndexerConfig;
using Jackett.Common.Services.Interfaces;
@@ -253,11 +252,13 @@ namespace Jackett.Common.Indexers.Definitions
if (string.IsNullOrWhiteSpace(sessionId))
throw new ExceptionWithConfigData("Error getting the Session ID", configData);
await Task.Delay(3000);
// The second page send the login with the hash
// The hash is reverse engineering from https://www.zonaq.pw/retorno/2/smf/Themes/smf_ZQ/scripts/script.js
// doForm.hash_passwrd.value = hex_sha1(hex_sha1(doForm.user.value.php_to8bit().php_strtolower() + doForm.passwrd.value.php_to8bit()) + cur_session_id);
Thread.Sleep(3000);
var hashPassword = Sha1Hash(Sha1Hash(configData.Username.Value.ToLower() + configData.Password.Value) + sessionId);
var hashPassword = $"{(configData.Username.Value.ToLowerInvariant() + configData.Password.Value).SHA1Hash()}{sessionId}".SHA1Hash();
var pairs = new Dictionary<string, string> {
{ "user", configData.Username.Value },
{ "passwrd", configData.Password.Value },
@@ -288,11 +289,5 @@ namespace Jackett.Common.Indexers.Definitions
Thread.Sleep(3000);
await RequestWithCookiesAsync(Login4Url);
}
private static string Sha1Hash(string input)
{
var hash = new SHA1Managed().ComputeHash(Encoding.UTF8.GetBytes(input));
return string.Concat(hash.Select(b => b.ToString("x2")));
}
}
}

View File

@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<TargetFrameworks>netstandard2.0;net9.0</TargetFrameworks>
<Version>0.0.0</Version>
<LangVersion>9</LangVersion>
<NoWarn />

View File

@@ -1,13 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using Jackett.Common.Extensions;
using Jackett.Common.Indexers;
using Jackett.Common.Models;
using Jackett.Common.Models.Config;
using Jackett.Common.Services.Interfaces;
using Jackett.Common.Utils;
using Newtonsoft.Json;
using NLog;
@@ -36,8 +34,7 @@ namespace Jackett.Common.Services
{
private readonly Logger _logger;
private readonly ServerConfig _serverConfig;
private readonly SHA256Managed _sha256 = new SHA256Managed();
private readonly Dictionary<string, TrackerCache> _cache = new Dictionary<string, TrackerCache>();
private readonly Dictionary<string, TrackerCache> _cache = new();
public CacheService(Logger logger, ServerConfig serverConfig)
{
@@ -236,11 +233,11 @@ namespace Jackett.Common.Services
}
}
private string GetQueryHash(TorznabQuery query)
private static string GetQueryHash(TorznabQuery query)
{
var json = GetSerializedQuery(query);
// Compute the hash
return BitConverter.ToString(_sha256.ComputeHash(Encoding.UTF8.GetBytes(json)));
return json.SHA256Hash();
}
private static string GetSerializedQuery(TorznabQuery query)

View File

@@ -51,7 +51,8 @@ namespace Jackett.Common.Services
if (!Directory.Exists(GetAppDataFolder()))
{
var dir = Directory.CreateDirectory(GetAppDataFolder());
if (Environment.OSVersion.Platform != PlatformID.Unix)
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
var access = dir.GetAccessControl();
var directorySecurity = new DirectorySecurity(GetAppDataFolder(), AccessControlSections.All);
@@ -126,7 +127,7 @@ namespace Jackett.Common.Services
if (!Directory.Exists(destFolder))
{
var dir = Directory.CreateDirectory(destFolder);
if (Environment.OSVersion.Platform != PlatformID.Unix)
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
var directorySecurity = new DirectorySecurity(destFolder, AccessControlSections.All);
directorySecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), FileSystemRights.FullControl, InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit, PropagationFlags.None, AccessControlType.Allow));
@@ -137,7 +138,7 @@ namespace Jackett.Common.Services
{
File.Copy(file, destPath);
// The old files were created when running as admin so make sure they are editable by normal users / services.
if (Environment.OSVersion.Platform != PlatformID.Unix)
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
var fileInfo = new FileInfo(destFolder);
var fileSecurity = new FileSecurity(destPath, AccessControlSections.All);

View File

@@ -74,8 +74,6 @@ namespace Jackett.Common.Services
}
}
private bool AcceptCert(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) => true;
private async Task CheckForUpdates()
{
logger.Info($"Checking for updates... Jackett variant: {variant}");
@@ -180,14 +178,7 @@ namespace Jackett.Common.Services
}
catch (Exception e)
{
logger.Error($"Error checking for updates.\n{e}");
}
finally
{
if (!isWindows)
{
System.Net.ServicePointManager.ServerCertificateValidationCallback -= AcceptCert;
}
logger.Error(e, $"Error checking for updates.\n{e}");
}
}

View File

@@ -2,6 +2,7 @@ using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.Versioning;
using System.ServiceProcess;
using Jackett.Common.Services.Interfaces;
using Jackett.Common.Utils;
@@ -9,6 +10,9 @@ using NLog;
namespace Jackett.Common.Services
{
#if NET5_0_OR_GREATER
[SupportedOSPlatform("windows")]
#endif
public class WindowsServiceConfigService : IServiceConfigService
{
private const string NAME = "Jackett";

View File

@@ -29,8 +29,13 @@ namespace Jackett.Common.Utils.Clients
}
[DebuggerNonUserCode] // avoid "Exception User-Unhandled" Visual Studio messages
public static bool ValidateCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
public bool ValidateCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
if (serverConfig.RuntimeSettings.IgnoreSslErrors == true)
{
return true;
}
if (sender.GetType() != typeof(HttpWebRequest))
return sslPolicyErrors == SslPolicyErrors.None;
@@ -51,24 +56,11 @@ namespace Jackett.Common.Utils.Clients
public override void SetTimeout(int seconds) => ClientTimeout = seconds;
public override void Init()
{
base.Init();
// custom handler for our own internal certificates
if (serverConfig.RuntimeSettings.IgnoreSslErrors == true)
ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
else
ServicePointManager.ServerCertificateValidationCallback += ValidateCertificate;
}
protected override async Task<WebResult> Run(WebRequest webRequest)
{
ServicePointManager.SecurityProtocol = (SecurityProtocolType)192 | (SecurityProtocolType)768 | (SecurityProtocolType)3072;
var cookies = new CookieContainer
{
PerDomainCapacity = 100 // By default only 20 cookies are allowed per domain
PerDomainCapacity = 100 // By default, only 20 cookies are allowed per domain
};
if (!string.IsNullOrWhiteSpace(webRequest.Cookies))
{
@@ -86,14 +78,17 @@ namespace Jackett.Common.Utils.Clients
clearanceHandlr.ProxyUrl = serverConfig.GetProxyUrl(false);
clearanceHandlr.ProxyUsername = serverConfig.ProxyUsername;
clearanceHandlr.ProxyPassword = serverConfig.ProxyPassword;
using (var clientHandlr = new HttpClientHandler
{
CookieContainer = cookies,
AllowAutoRedirect = false, // Do not use this - Bugs ahoy! Lost cookies and more.
UseCookies = true,
Proxy = webProxy,
UseProxy = (webProxy != null),
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
UseProxy = webProxy != null,
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate,
MaxConnectionsPerServer = 20,
ServerCertificateCustomValidationCallback = ValidateCertificate,
})
{
clearanceHandlr.InnerHandler = clientHandlr;

View File

@@ -33,14 +33,19 @@ namespace Jackett.Common.Utils.Clients
{
cookies = new CookieContainer
{
PerDomainCapacity = 100 // By default only 20 cookies are allowed per domain
PerDomainCapacity = 100 // By default, only 20 cookies are allowed per domain
};
CreateClient();
}
[DebuggerNonUserCode] // avoid "Exception User-Unhandled" Visual Studio messages
public static bool ValidateCertificate(HttpRequestMessage request, X509Certificate2 certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
public bool ValidateCertificate(HttpRequestMessage request, X509Certificate2 certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
if (serverConfig.RuntimeSettings.IgnoreSslErrors == true)
{
return true;
}
var hash = certificate.GetCertHashString();
trustedCertificates.TryGetValue(hash, out var hosts);
@@ -70,16 +75,12 @@ namespace Jackett.Common.Utils.Clients
AllowAutoRedirect = false, // Do not use this - Bugs ahoy! Lost cookies and more.
UseCookies = true,
Proxy = webProxy,
UseProxy = (webProxy != null),
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
UseProxy = webProxy != null,
AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate,
MaxConnectionsPerServer = 20,
ServerCertificateCustomValidationCallback = ValidateCertificate,
};
// custom certificate validation handler (netcore version)
if (serverConfig.RuntimeSettings.IgnoreSslErrors == true)
clientHandlr.ServerCertificateCustomValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true;
else
clientHandlr.ServerCertificateCustomValidationCallback = ValidateCertificate;
clearanceHandlr.InnerHandler = clientHandlr;
client = new HttpClient(clearanceHandlr);
@@ -103,13 +104,6 @@ namespace Jackett.Common.Utils.Clients
client.Timeout = TimeSpan.FromSeconds(ClientTimeout);
}
public override void Init()
{
base.Init();
ServicePointManager.SecurityProtocol = (SecurityProtocolType)192 | (SecurityProtocolType)768 | (SecurityProtocolType)3072;
}
protected override async Task<WebResult> Run(WebRequest webRequest)
{
var request = new HttpRequestMessage();

View File

@@ -220,11 +220,7 @@ namespace Jackett.Common.Utils.Clients
return result;
}
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
protected virtual async Task<WebResult> Run(WebRequest webRequest) => throw new NotImplementedException();
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
public virtual void Init() => ServicePointManager.DefaultConnectionLimit = 1000;
protected virtual Task<WebResult> Run(WebRequest webRequest) => throw new NotImplementedException();
public virtual void OnCompleted() => throw new NotImplementedException();

View File

@@ -1,4 +1,5 @@
using System;
using System.Runtime.InteropServices;
using System.Security.Principal;
using Jackett.Common.Utils.Clients;
@@ -75,7 +76,11 @@ namespace Jackett.Common.Utils
public static bool IsUserAdministrator()
{
//bool value to hold our return value
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return false;
}
bool isAdmin;
try
{

View File

@@ -1,104 +0,0 @@
using System;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
namespace Jackett.Common.Utils
{
public static class StringCipher
{
// This constant is used to determine the keysize of the encryption algorithm in bits.
// We divide this by 8 within the code below to get the equivalent number of bytes.
private const int Keysize = 256;
// This constant determines the number of iterations for the password bytes generation function.
private const int DerivationIterations = 1000;
public static string Encrypt(string plainText, string passPhrase)
{
// Salt and IV is randomly generated each time, but is preprended to encrypted cipher text
// so that the same Salt and IV values can be used when decrypting.
var saltStringBytes = Generate256BitsOfRandomEntropy();
var ivStringBytes = Generate256BitsOfRandomEntropy();
var plainTextBytes = Encoding.UTF8.GetBytes(plainText);
using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
{
var keyBytes = password.GetBytes(Keysize / 8);
using (var symmetricKey = new RijndaelManaged())
{
symmetricKey.BlockSize = 256;
symmetricKey.Mode = CipherMode.CBC;
symmetricKey.Padding = PaddingMode.PKCS7;
using (var encryptor = symmetricKey.CreateEncryptor(keyBytes, ivStringBytes))
{
using (var memoryStream = new MemoryStream())
{
using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
{
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
cryptoStream.FlushFinalBlock();
// Create the final bytes as a concatenation of the random salt bytes, the random iv bytes and the cipher bytes.
var cipherTextBytes = saltStringBytes;
cipherTextBytes = cipherTextBytes.Concat(ivStringBytes).ToArray();
cipherTextBytes = cipherTextBytes.Concat(memoryStream.ToArray()).ToArray();
memoryStream.Close();
cryptoStream.Close();
return Convert.ToBase64String(cipherTextBytes);
}
}
}
}
}
}
public static string Decrypt(string cipherText, string passPhrase)
{
// Get the complete stream of bytes that represent:
// [32 bytes of Salt] + [32 bytes of IV] + [n bytes of CipherText]
var cipherTextBytesWithSaltAndIv = Convert.FromBase64String(cipherText);
// Get the saltbytes by extracting the first 32 bytes from the supplied cipherText bytes.
var saltStringBytes = cipherTextBytesWithSaltAndIv.Take(Keysize / 8).ToArray();
// Get the IV bytes by extracting the next 32 bytes from the supplied cipherText bytes.
var ivStringBytes = cipherTextBytesWithSaltAndIv.Skip(Keysize / 8).Take(Keysize / 8).ToArray();
// Get the actual cipher text bytes by removing the first 64 bytes from the cipherText string.
var cipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((Keysize / 8) * 2).Take(cipherTextBytesWithSaltAndIv.Length - ((Keysize / 8) * 2)).ToArray();
using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
{
var keyBytes = password.GetBytes(Keysize / 8);
using (var symmetricKey = new RijndaelManaged())
{
symmetricKey.BlockSize = 256;
symmetricKey.Mode = CipherMode.CBC;
symmetricKey.Padding = PaddingMode.PKCS7;
using (var decryptor = symmetricKey.CreateDecryptor(keyBytes, ivStringBytes))
{
using (var memoryStream = new MemoryStream(cipherTextBytes))
{
using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
{
var plainTextBytes = new byte[cipherTextBytes.Length];
var decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
memoryStream.Close();
cryptoStream.Close();
return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
}
}
}
}
}
}
private static byte[] Generate256BitsOfRandomEntropy()
{
var randomBytes = new byte[32]; // 32 Bytes will give us 256 bits.
using (var rngCsp = new RNGCryptoServiceProvider())
{
// Fill the array with cryptographically secure random bytes.
rngCsp.GetBytes(randomBytes);
}
return randomBytes;
}
}
}

View File

@@ -29,9 +29,7 @@ namespace Jackett.Server.Services
return null;
var ue = new UnicodeEncoding();
#pragma warning disable SYSLIB0021
var hashString = new SHA512Managed();
#pragma warning restore SYSLIB0021
var hashString = SHA512.Create();
// Append key as salt
input += _serverConfig.APIKey;

View File

@@ -341,7 +341,6 @@ namespace Jackett.Server.Services
// Load indexers
indexerService.InitIndexers(configService.GetCardigannDefinitionsFolders());
client.Init();
updater.CleanupTempDir();
updater.CheckUpdaterLock();

View File

@@ -48,9 +48,5 @@ namespace Jackett.Test.TestHelpers
});
throw new Exception($"You have to mock the URL {request.Url} with RegisterRequestCallback");
}
public override void Init()
{
}
}
}