Commit 83d6a80b authored by Francesc Guasch's avatar Francesc Guasch
Browse files

Merge branch '197_password'

parents 10826a2d 5be1b2e6
......@@ -224,6 +224,7 @@ sub _upgrade_tables {
$self->_upgrade_table('file_base_images','target','varchar(64) DEFAULT NULL');
$self->_upgrade_table('vms','vm_type',"char(20) NOT NULL DEFAULT 'KVM'");
$self->_upgrade_table('requests','at_time','int(11) DEFAULT NULL');
$self->_upgrade_table('iso_images','md5_url','varchar(255)');
$self->_upgrade_table('iso_images','file_re','char(64)');
$self->_upgrade_table('iso_images','device','varchar(255)');
......@@ -235,6 +236,9 @@ sub _upgrade_tables {
);
$sth->execute;
}
$self->_upgrade_table('networks','requires_password','int(11)');
$self->_upgrade_table('domains','spice_password','varchar(20) DEFAULT NULL');
}
......
......@@ -452,6 +452,31 @@ sub _prepare_base_db {
$self->_select_domain_db();
}
sub _set_spice_password {
my $self = shift;
my $password = shift;
my $sth = $$CONNECTOR->dbh->prepare(
"UPDATE domains set spice_password=?"
." WHERE id=?"
);
$sth->execute($password, $self->id);
$sth->finish;
$self->{_data}->{spice_password} = $password;
}
=head2 spice_password
Returns the password defined for the spice viewers
=cut
sub spice_password {
my $self = shift;
return $self->_data('spice_password');
}
sub _insert_db {
my $self = shift;
my %field = @_;
......
......@@ -478,7 +478,20 @@ Starts the domain
sub start {
my $self = shift;
$self->_set_spice_ip();
my %arg;
if (!(scalar(@_) % 2)) {
%arg = @_;
}
my $set_password=0;
my $remote_ip = $arg{remote_ip};
if ($remote_ip) {
my $network = Ravada::Network->new(address => $remote_ip);
$set_password = 1 if $network->requires_password();
}
$self->_set_spice_ip($set_password);
# $self->domain($self->_vm->vm->get_domain_by_name($self->domain->get_name));
$self->domain->create();
}
......@@ -1119,6 +1132,7 @@ sub spinoff_volumes {
sub _set_spice_ip {
my $self = shift;
my $set_password = shift;
my $doc = XML::LibXML->load_xml(string
=> $self->domain->get_xml_description) ;
......@@ -1128,6 +1142,16 @@ sub _set_spice_ip {
for my $graphics ( $doc->findnodes('/domain/devices/graphics') ) {
$graphics->setAttribute('listen' => $ip);
my $password;
if ($set_password) {
$password = Ravada::Utils::random_name(4);
$graphics->setAttribute(passwd => $password);
} else {
$graphics->removeAttribute('passwd');
}
$self->_set_spice_password($password);
my $listen;
for my $child ( $graphics->childNodes()) {
$listen = $child if $child->getName() eq 'listen';
......
......@@ -9,6 +9,7 @@ Ravada::Network - Networks management library for Ravada
=cut
use Data::Dumper;
use Hash::Util qw(lock_hash);
use Moose;
use MooseX::Types::NetAddr::IP qw( NetAddrIP );
......@@ -93,6 +94,37 @@ sub allowed_anonymous {
return $self->allowed(@_,1);
}
=head2 requires_password
Returns true if running a domain from this network requires a password
if ($net->requires_password) {
.....
}
=cut
sub requires_password {
my $self = shift;
for my $network ( $self->list_networks ) {
my ($ip,$mask) = $network->{address} =~ m{(.*)/(.*)};
if (!$ip ) {
$ip = $network->{address};
$mask = 24;
}
my $netaddr;
eval { $netaddr = NetAddr::IP->new($ip,$mask) };
if ($@ ) {
warn "Error with newtork $network->{address} [ $ip / $mask ] $@";
return;
}
next if !$self->address->within($netaddr);
return 1 if $network->{requires_password};
return 0;
}
}
sub _allowed_domain {
my $self = shift;
my ($id_domain, $id_network) = @_;
......
......@@ -984,6 +984,7 @@ sub show_link {
_open_iptables($c,$domain)
if !$req;
$c->render(template => 'main/run', url => $uri , name => $domain->name
,password => $domain->spice_password
,login => $c->session('login'));
}
......
......@@ -12,6 +12,7 @@ CREATE TABLE `domains` (
`port` int(5),
`id_owner` int(11),
`vm` char(120) NOT NULL,
`spice_password` char(20) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `id_base` (`id_base`,`name`),
UNIQUE KEY `name` (`name`)
......
......@@ -5,6 +5,7 @@ CREATE TABLE `networks` (
`description` varchar(140) DEFAULT NULL,
`all_domains` int(11) DEFAULT '0',
`no_domains` int(11) DEFAULT '0',
`requires_password` int(11) DEFAULT '0',
`n_order` int(11) DEFAULT '0',
PRIMARY KEY (`id`)
);
......@@ -12,6 +12,7 @@ CREATE TABLE `domains` (
, `port` integer
, `id_owner` integer
, `vm` char(120) NOT NULL
, `spice_password` char(20) DEFAULT NULL
, UNIQUE (`id_base`,`name`)
, UNIQUE (`name`)
);
......@@ -5,5 +5,6 @@ CREATE TABLE `networks` (
, `description` varchar(140) DEFAULT NULL
, `all_domains` integer DEFAULT '0'
, `no_domains` integer DEFAULT '0'
, `requires_password` integer DEFAULT '0'
, `n_order` integer DEFAULT '0'
);
use warnings;
use strict;
use Carp qw(confess);
use Data::Dumper;
use IPC::Run3;
use Test::More;
use Test::SQL::Data;
use lib 't/lib';
use Test::Ravada;
my $test = Test::SQL::Data->new(config => 't/etc/sql.conf');
use_ok('Ravada');
my %ARG_CREATE_DOM = (
KVM => [ id_iso => 1 ]
);
my @VMS = reverse keys %ARG_CREATE_DOM;
init($test->connector);
my $USER = create_user("foo","bar");
#######################################################
sub test_domain_no_password {
my $vm_name = shift;
my $vm = rvd_back->search_vm($vm_name);
my $net = Ravada::Network->new(address => '127.0.0.1/32');
ok(!$net->requires_password);
my $domain_name = new_domain_name();
my $domain = $vm->create_domain( name => $domain_name
, id_iso => 1 , id_owner => $USER->id);
$domain->start(user => $USER, remote_ip => '127.0.0.1');
my $password = $domain->spice_password();
is($password,undef
,"Expecting no password, got '".($password or '')."'");
$domain->shutdown_now($USER);
for ( 1 .. 10 ) {
sleep 1;
last if !$domain->is_active();
}
is($domain->is_active,0) or return;
my $net2 = Ravada::Network->new(address => '10.0.0.1/32');
ok(!$net2->requires_password,"Expecting net requires password ");
$domain->start(user => $USER, remote_ip => '10.0.0.1');
my $vm2 = rvd_back->search_vm($vm_name);
my $domain2 = $vm2->search_domain($domain->name);
$password = $domain2->spice_password();
is($password,undef,"Expecting no password, got '".($password or '')."'");
$password = $domain->spice_password();
is($password,undef,"Expecting no password, got '".($password or '')."'") or exit;
my $domain_f = rvd_front()->search_domain($domain->name);
my $password_f;
eval { $password_f = $domain_f->spice_password() };
is($@,'');
is($password_f , $password,"Expecting password : '".($password or '')."'"
." got : '".($password_f or '')."'");
$domain->shutdown_now($USER);
}
sub test_domain_password2 {
my $vm_name = shift;
my $vm = rvd_back->search_vm($vm_name);
my $net = Ravada::Network->new(address => '127.0.0.1/32');
ok(!$net->requires_password) or return;
my $domain_name = new_domain_name();
my $domain = $vm->create_domain( name => $domain_name
, id_iso => 1 , id_owner => $USER->id);
$domain->start(user => $USER, remote_ip => '127.0.0.1');
my $password = $domain->spice_password();
is($password,undef
,"Expecting no password, got '".($password or '')."'");
$domain->shutdown_now($USER);
for ( 1 .. 10 ) {
sleep 1;
last if !$domain->is_active();
}
is($domain->is_active,0) or return;
my $net2 = Ravada::Network->new(address => '10.0.0.1/32');
ok($net2->requires_password,"Expecting net requires password ")
or return;
$domain->start(user => $USER, remote_ip => '10.0.0.1');
my $vm2 = rvd_back->search_vm($vm_name);
my $domain2 = $vm2->search_domain($domain->name);
$password = $domain2->spice_password();
like($password,qr/./,"Expecting a password, got '".($password or '')."'");
$password = $domain->spice_password();
like($password,qr/./,"Expecting a password, got '".($password or '')."'") or exit;
my $domain_f = rvd_front()->search_domain($domain->name);
my $password_f;
eval { $password_f = $domain_f->spice_password() };
is($@,'');
is($password_f , $password,"Expecting password : '".($password or '')."'"
." got : '".($password_f or '')."'");
$domain->shutdown_now($USER);
return $domain;
}
sub test_domain_password1 {
my $vm_name = shift;
my $vm = rvd_back->search_vm($vm_name);
my $net2 = Ravada::Network->new(address => '10.0.0.1/32');
ok($net2->requires_password,"Expecting net requires password ")
or return;
my $domain = $vm->create_domain( name => new_domain_name
, id_iso => 1 , id_owner => $USER->id);
$domain->start(user => $USER, remote_ip => '10.0.0.1');
my $vm2 = rvd_back->search_vm($vm_name);
my $domain2 = $vm2->search_domain($domain->name);
my $password = $domain2->spice_password();
like($password,qr/./,"Expecting a password, got '".($password or '')."'");
$password = $domain->spice_password();
like($password,qr/./,"Expecting a password, got '".($password or '')."'");
my $domain_f = rvd_front()->search_domain($domain->name);
my $password_f;
eval { $password_f = $domain_f->spice_password() };
ok(!$@, "Expecting no error, got : '".($@ or '')."'");
is($password_f , $password,"Expecting password : '".($password or '')."'"
." got : '".($password_f or '')."'");
$domain->shutdown_now($USER);
return $domain;
}
sub test_any_network_password {
my $vm_name = shift;
my $vm = rvd_back->search_vm($vm_name);
add_network_10(0);
add_network_any(1);
my $domain = $vm->create_domain( name => new_domain_name
, id_iso => 1 , id_owner => $USER->id);
$domain->start(user => $USER, remote_ip => '127.0.0.1');
my $password = $domain->spice_password();
is($password, undef ,"Expecting no password, got '".($password or '')."'");
$domain->shutdown_now($USER);
$domain->start(user => $USER, remote_ip => '10.0.0.1');
$password = $domain->spice_password();
is($password, undef ,"Expecting no password, got '".($password or '')."'");
$domain->shutdown_now($USER);
$domain->start(user => $USER, remote_ip => '1.2.3.4');
$password = $domain->spice_password();
like($password,qr/./,"Expecting a password, got '".($password or '')."'");
$domain->shutdown_now($USER);
}
sub test_any_network_password_hybernate{
my $vm_name = shift;
my $vm = rvd_back->search_vm($vm_name);
add_network_10(0);
add_network_any(1);
my $domain = $vm->create_domain( name => new_domain_name
, id_iso => 1 , id_owner => $USER->id);
$domain->start(user => $USER, remote_ip => '127.0.0.1');
my $password = $domain->spice_password();
is($password, undef ,"Expecting no password, got '".($password or '')."'");
$domain->hybernate($USER);
is($domain->is_active(),0);
eval { $domain->start(user => $USER, remote_ip => '10.0.0.1') };
is($@,'',"Expecting no error start hybernated domain, got : '".($@ or '')."'");
is($domain->is_active(),1);
$password = $domain->spice_password();
is($password, undef ,"Expecting no password, got '".($password or '')."'");
$domain->hybernate($USER);
is($domain->is_active(),0);
$domain->start(user => $USER, remote_ip => '1.2.3.4');
$password = $domain->spice_password();
like($password,qr/./,"Expecting a password, got '".($password or '')."'");
$domain->shutdown_now($USER);
}
sub add_network_10 {
my $requires_password = shift;
$requires_password = 1 if !defined $requires_password;
my $sth = $test->connector->dbh->prepare(
"INSERT INTO networks (name,address,all_domains,requires_password)"
."VALUES('10','10.0.0.0/24',1,?)"
);
$sth->execute($requires_password);
}
sub add_network_any {
my $requires_password = shift;
$requires_password = 1 if !defined $requires_password;
my $sth = $test->connector->dbh->prepare(
"INSERT INTO networks (name,address,all_domains,requires_password)"
."VALUES('any','0.0.0.0/0',1,?)"
);
$sth->execute($requires_password);
}
sub remove_network_10 {
my $sth = $test->connector->dbh->prepare(
"DELETE FROM networks where name='10'"
);
$sth->execute();
}
#######################################################
clean();
my $vm_name = 'KVM';
my $vm = rvd_back->search_vm($vm_name);
SKIP: {
my $msg = "SKIPPED: No virtual managers found";
if ($vm && $vm_name =~ /kvm/i && $>) {
$msg = "SKIPPED: Test must run as root";
$vm = undef;
}
skip($msg,10) if !$vm;
add_network_10();
my $domain1 = test_domain_password1($vm_name);
my $domain2 = test_domain_password2($vm_name);
remove_network_10();
$domain1->start(user => $USER, remote_ip => '10.0.0.1');
my $password = $domain1->spice_password();
is($password,undef,"Expecting no password, got : '".($password or '')."'");
$domain1->shutdown_now($USER);
$domain2->start(user => $USER, remote_ip => '10.0.0.1');
$password = $domain2->spice_password();
is($password,undef,"Expecting no password, got : '".($password or '')."'");
$domain2->shutdown_now($USER);
test_domain_no_password($vm_name);
test_any_network_password($vm_name);
test_any_network_password_hybernate($vm_name);
}
clean();
done_testing();
......@@ -7,9 +7,18 @@
<div class="container theme-showcase" role="main">
<div class="jumbotron">
<h2>Running <%= $name %></h2>
Hi <%= $login %>,
Hi <%= $login %>,
click <a href="<%= $url %>"><%= $url %></a> if your host won't come out.
% if ($password ) {
<div class="panel-body">
<div class="panel panel-warning">
<div class="panel-heading">
The password for this virtual machine connection is : <b><%= $password %></b>
</div>
</div>
</div>
% }
</div>
</div>
%= include 'bootstrap/scripts'
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment