support transparent encryption for feed passwords, bump schema to drop length limit of ttrss_feeds.auth_pass
This commit is contained in:
@@ -6,7 +6,7 @@ class Config {
|
||||
const T_STRING = 2;
|
||||
const T_INT = 3;
|
||||
|
||||
const SCHEMA_VERSION = 147;
|
||||
const SCHEMA_VERSION = 148;
|
||||
|
||||
/** override default values, defined below in _DEFAULTS[], prefixing with _ENVVAR_PREFIX:
|
||||
*
|
||||
@@ -192,7 +192,8 @@ class Config {
|
||||
/** disables login form controls except HOOK_LOGINFORM_ADDITIONAL_BUTTONS (for SSO providers), also prevents logging in through auth_internal */
|
||||
const DISABLE_LOGIN_FORM = "DISABLE_LOGIN_FORM";
|
||||
|
||||
/** optional key to transparently encrypt sensitive data (currently limited to sessions); key is a 32 byte hex string may be generated using update.php --gen-encryption-key */
|
||||
/** optional key to transparently encrypt sensitive data (currently limited to sessions and feed passwords),
|
||||
* key is a 32 byte hex string which may be generated using `update.php --gen-encryption-key` */
|
||||
const ENCRYPTION_KEY = "ENCRYPTION_KEY";
|
||||
|
||||
/** default values for all global configuration options */
|
||||
|
||||
@@ -2376,5 +2376,29 @@ class Feeds extends Handler_Protected {
|
||||
return [$query, $skip_first_id];
|
||||
}
|
||||
|
||||
|
||||
/** decrypts encrypted feed password if possible (key is available and data is a base64-encoded serialized object)
|
||||
*
|
||||
* @param $auth_pass possibly encrypted feed password
|
||||
*
|
||||
* @return string plaintext representation of an encrypted feed password if encrypted or plaintext password otherwise
|
||||
* */
|
||||
static function decrypt_feed_pass(string $auth_pass) : string {
|
||||
$key = Config::get(Config::ENCRYPTION_KEY);
|
||||
|
||||
if ($auth_pass && $key) {
|
||||
$auth_pass_serialized = @base64_decode($auth_pass);
|
||||
|
||||
if ($auth_pass_serialized) {
|
||||
$unserialized_data = @unserialize($auth_pass_serialized);
|
||||
|
||||
if ($unserialized_data !== false)
|
||||
return Crypt::decrypt_string($unserialized_data);
|
||||
}
|
||||
}
|
||||
|
||||
return $auth_pass;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -560,6 +560,7 @@ class Pref_Feeds extends Handler_Protected {
|
||||
ob_end_clean();
|
||||
|
||||
$row["icon"] = Feeds::_get_icon($feed_id);
|
||||
$row["auth_pass"] = Feeds::decrypt_feed_pass($row["auth_pass"]);
|
||||
|
||||
$local_update_intervals = $update_intervals;
|
||||
$local_update_intervals[0] .= sprintf(" (%s)", $update_intervals[Prefs::get(Prefs::DEFAULT_UPDATE_INTERVAL, $_SESSION['uid'])]);
|
||||
@@ -746,6 +747,11 @@ class Pref_Feeds extends Handler_Protected {
|
||||
|
||||
$feed_language = clean($_POST["feed_language"] ?? "");
|
||||
|
||||
$key = Config::get(Config::ENCRYPTION_KEY);
|
||||
|
||||
if ($key && $auth_pass)
|
||||
$auth_pass = base64_encode(serialize(Crypt::encrypt_string($auth_pass)));
|
||||
|
||||
if (!$batch) {
|
||||
|
||||
/* $sth = $this->pdo->prepare("SELECT feed_url FROM ttrss_feeds WHERE id = ?");
|
||||
|
||||
@@ -331,6 +331,8 @@ class RSSUtils {
|
||||
$pluginhost->load((string)$user_plugins, PluginHost::KIND_USER, $feed->owner_uid);
|
||||
//$pluginhost->load_data();
|
||||
|
||||
$feed_auth_pass_plaintext = Feeds::decrypt_feed_pass($feed->auth_pass);
|
||||
|
||||
$basic_info = [];
|
||||
|
||||
$pluginhost->run_hooks_callback(PluginHost::HOOK_FEED_BASIC_INFO, function ($result) use (&$basic_info) {
|
||||
@@ -338,13 +340,13 @@ class RSSUtils {
|
||||
$basic_info = $result;
|
||||
return true;
|
||||
}
|
||||
}, $basic_info, $feed->feed_url, $feed->owner_uid, $feed_id, $feed->auth_login, $feed->auth_pass);
|
||||
}, $basic_info, $feed->feed_url, $feed->owner_uid, $feed_id, $feed->auth_login, $feed_auth_pass_plaintext);
|
||||
|
||||
if (!$basic_info) {
|
||||
$feed_data = UrlHelper::fetch([
|
||||
'url' => $feed->feed_url,
|
||||
'login' => $feed->auth_login,
|
||||
'pass' => $feed->auth_pass,
|
||||
'pass' => $feed_auth_pass_plaintext,
|
||||
'timeout' => Config::get(Config::FEED_FETCH_TIMEOUT),
|
||||
]);
|
||||
|
||||
@@ -458,12 +460,14 @@ class RSSUtils {
|
||||
$hff_owner_uid = $feed_obj->owner_uid;
|
||||
$hff_feed_url = $feed_obj->feed_url;
|
||||
|
||||
$feed_auth_pass_plaintext = Feeds::decrypt_feed_pass($feed_obj->auth_pass);
|
||||
|
||||
$pluginhost->chain_hooks_callback(PluginHost::HOOK_FETCH_FEED,
|
||||
function ($result, $plugin) use (&$feed_data, $start_ts) {
|
||||
$feed_data = $result;
|
||||
Debug::log(sprintf("=== %.4f (sec) %s", microtime(true) - $start_ts, get_class($plugin)), Debug::LOG_VERBOSE);
|
||||
},
|
||||
$feed_data, $hff_feed_url, $hff_owner_uid, $feed, $last_article_timestamp, $feed_obj->auth_login, $feed_obj->auth_pass);
|
||||
$feed_data, $hff_feed_url, $hff_owner_uid, $feed, $last_article_timestamp, $feed_obj->auth_login, $feed_auth_pass_plaintext);
|
||||
|
||||
if ($feed_data) {
|
||||
Debug::log("feed data has been modified by a plugin.", Debug::LOG_VERBOSE);
|
||||
@@ -510,7 +514,7 @@ class RSSUtils {
|
||||
$feed_data = UrlHelper::fetch([
|
||||
"url" => $feed_obj->feed_url,
|
||||
"login" => $feed_obj->auth_login,
|
||||
"pass" => $feed_obj->auth_pass,
|
||||
"pass" => $feed_auth_pass_plaintext,
|
||||
"timeout" => $no_cache ? Config::get(Config::FEED_FETCH_NO_CACHE_TIMEOUT) : Config::get(Config::FEED_FETCH_TIMEOUT),
|
||||
"last_modified" => $force_refetch ? "" : $feed_obj->last_modified
|
||||
]);
|
||||
|
||||
3
sql/mysql/migrations/148.sql
Normal file
3
sql/mysql/migrations/148.sql
Normal file
@@ -0,0 +1,3 @@
|
||||
alter table ttrss_feeds change auth_pass auth_pass text not null;
|
||||
|
||||
update ttrss_version set schema_version = 148;
|
||||
@@ -121,7 +121,7 @@ create table ttrss_feeds (id integer not null auto_increment primary key,
|
||||
favicon_is_custom boolean default null,
|
||||
site_url varchar(250) not null default '',
|
||||
auth_login varchar(250) not null default '',
|
||||
auth_pass varchar(250) not null default '',
|
||||
auth_pass text not null default '',
|
||||
parent_feed integer default null,
|
||||
private bool not null default false,
|
||||
rtl_content bool not null default false,
|
||||
|
||||
7
sql/pgsql/migrations/148.sql
Normal file
7
sql/pgsql/migrations/148.sql
Normal file
@@ -0,0 +1,7 @@
|
||||
alter table ttrss_feeds rename column auth_pass to auth_pass_old;
|
||||
alter table ttrss_feeds add column auth_pass text;
|
||||
update ttrss_feeds set auth_pass = auth_pass_old;
|
||||
alter table ttrss_feeds alter column auth_pass set not null;
|
||||
alter table ttrss_feeds drop column auth_pass_old;
|
||||
|
||||
update ttrss_version set schema_version = 148;
|
||||
@@ -92,7 +92,7 @@ create table ttrss_feeds (id serial not null primary key,
|
||||
auth_login varchar(250) not null default '',
|
||||
parent_feed integer default null references ttrss_feeds(id) on delete set null,
|
||||
private boolean not null default false,
|
||||
auth_pass varchar(250) not null default '',
|
||||
auth_pass text not null default '',
|
||||
hidden boolean not null default false,
|
||||
include_in_digest boolean not null default true,
|
||||
rtl_content boolean not null default false,
|
||||
|
||||
Reference in New Issue
Block a user