diff --git a/conf/settings.ini.dist b/conf/settings.ini.dist index 3f84e4e..34cee68 100644 --- a/conf/settings.ini.dist +++ b/conf/settings.ini.dist @@ -51,12 +51,6 @@ credentials = 'rest' ; Default to 0 ;demo = 0 -[cookie] -; Secret passphrase used to sign cookies. You must set this -;secret = '1zEewX24ZD%2RvtF%e' -; Cookie name, You shouldn't have to change this -;name = 'vroom' - [rooms] ; After this amount of time in minutes, rooms without any activity will be purged ;inactivity_timeout = '60' diff --git a/docs/database/schema.mysql b/docs/database/schema.mysql index e103968..cbfc7b5 100644 --- a/docs/database/schema.mysql +++ b/docs/database/schema.mysql @@ -6,7 +6,15 @@ CREATE TABLE `config` ( UNIQUE (`key`) ) ENGINE INNODB DEFAULT CHARSET=utf8; INSERT INTO `config` (`key`,`value`) - VALUES ('schema_version', '6'); + VALUES ('schema_version', '7'); + +CREATE TABLE `session_keys` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `key` VARCHAR(160) NOT NULL, + `date` DATETIME NOT NULL DEFAULT 0, + PRIMARY KEY (`id`), + INDEX (`date`) +) ENGINE INNODB DEFAULT CHARSET=utf8; CREATE TABLE `rooms` ( `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, diff --git a/lib/Vroom/Conf.pm b/lib/Vroom/Conf.pm index a4b6e0a..d282692 100644 --- a/lib/Vroom/Conf.pm +++ b/lib/Vroom/Conf.pm @@ -32,8 +32,6 @@ sub get_conf(){ $config->{'interface.template'} ||= 'default'; $config->{'interface.chrome_extension_id'} ||= 'ecicdpoejfllflombfanbhfpgcimjddn'; $config->{'interface.chrome_extension_id'} ||= 0; - $config->{'cookie.secret'} ||= 'secret'; - $config->{'cookie.name'} ||= 'vroom'; $config->{'rooms.inactivity_timeout'} ||= 60; $config->{'rooms.reserved_inactivity_timeout'} ||= 86400; $config->{'rooms.common_names'} ||= ''; diff --git a/lib/Vroom/Constants.pm b/lib/Vroom/Constants.pm index 10c5cd2..a63b15d 100644 --- a/lib/Vroom/Constants.pm +++ b/lib/Vroom/Constants.pm @@ -7,7 +7,7 @@ use base 'Exporter'; our @EXPORT = qw/DB_VERSION COMPONENTS MOH JS_STRINGS API_ACTIONS/; # Database version -use constant DB_VERSION => 6; +use constant DB_VERSION => 7; # Components used to generate the credits part use constant COMPONENTS => { diff --git a/scripts/db_upgrade.pl b/scripts/db_upgrade.pl index 4a3fd26..d647697 100644 --- a/scripts/db_upgrade.pl +++ b/scripts/db_upgrade.pl @@ -145,3 +145,24 @@ if ($cur_ver < 6){ print "Successfully upgraded to schema version 6\n"; } +if ($cur_ver < 7){ + print "Upgrading the schema to version 7\n"; + eval { + $dbh->begin_work; + $dbh->do(qq{ CREATE TABLE `session_keys` (`id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `key` VARCHAR(160) NOT NULL, + `date` DATETIME NOT NULL DEFAULT 0, + PRIMARY KEY (`id`), + INDEX (`date`)) + ENGINE INNODB DEFAULT CHARSET=utf8; }); + $dbh->do(qq{ UPDATE `config` SET `value`='7' WHERE `key`='schema_version' }); + $dbh->commit; + }; + if ($@){ + print "An error occurred: " . $dbh->errstr . "\n"; + local $dbh->{RaiseError} = 0; + $dbh->rollback; + exit 255; + }; + print "Successfully upgraded to schema version 7\n"; +} diff --git a/templates/default/documentation.html.ep b/templates/default/documentation.html.ep index 6f62c87..a7b489b 100644 --- a/templates/default/documentation.html.ep +++ b/templates/default/documentation.html.ep @@ -358,17 +358,6 @@ cp /opt/vroom/conf/settings.ini.dist /opt/vroom/conf/settings.ini

- -

- This section controls the cookie used for VROOM sessions. The available settings are -

-

-

rooms

diff --git a/vroom.pl b/vroom.pl index 1b737be..8663f43 100755 --- a/vroom.pl +++ b/vroom.pl @@ -143,6 +143,39 @@ helper check_db_version => sub { return ($ver eq Vroom::Constants::DB_VERSION) ? '1' : '0'; }; +# Generate and manage rotation of session keys +# used to sign cookies +helper update_session_keys => sub { + my $self = shift; + # First, delete obsolete session keys + my $sth = eval { + $self->db->prepare('DELETE FROM `session_keys` + WHERE `date` < DATE_SUB(CONVERT_TZ(NOW(), @@session.time_zone, \'+00:00\'), INTERVAL 72 HOUR)'); + }; + $sth->execute; + # Now, retrieve all remaining keys, to check if we have enough of them + $sth = eval { + $self->db->prepare('SELECT `key` FROM `session_keys` + ORDER BY `date` DESC'); + }; + $sth->execute; + my $keys = $sth->fetchall_hashref('key'); + my @keys = keys %$keys; + if (scalar @keys < 3){ + $self->app->log->debug("Generating a new key to sign session cookies"); + my $new_key = Session::Token->new(alphabet => ['a'..'z', 'A'..'Z', '0'..'9', '.:;,/!%$#~{([-_)]}=+*|'], entropy => 512)->get; + unshift @keys, $new_key; + $self->app->log->info("new key: $new_key"); + $sth = eval { + $self->db->prepare('INSERT INTO `session_keys` (`key`,`date`) + VALUES (?,NOW())'); + }; + $sth->execute($new_key); + } + $self->app->secrets(\@keys); + return 1; +}; + # Return human readable username if it exists, or just the session ID helper get_name => sub { my $self = shift; @@ -1231,6 +1264,11 @@ Mojo::IOLoop->recurring( 900 => sub { app->purge_invitations; }); +# Check every 24h if session keys needs updating +Mojo::IOLoop->recurring( 86400 => sub { + app->update_session_keys; +}); + # Route / to the index page get '/' => sub { my $self = shift; @@ -2070,10 +2108,12 @@ get '/:room' => sub { # use the templates defined in the config push @{app->renderer->paths}, 'templates/'.$config->{'interface.template'}; -# Set the secret used to sign cookies -app->secrets([$config->{'cookie.secret'}]); + +app->update_session_keys; +# Set log level +app->log->level($config->{'daemon.log_level'}); app->sessions->secure(1); -app->sessions->cookie_name($config->{'cookie.name'}); +app->sessions->cookie_name('vroom'); app->hook(before_dispatch => sub { my $self = shift; # Switch to the desired language @@ -2109,8 +2149,6 @@ app->config( } ); -# Set log level -app->log->level($config->{'daemon.log_level'}); app->log->info('Starting VROOM daemon'); # And start, lets VROOM !! app->start;