Skip to content

Commit

Permalink
Merge pull request #1612 from julsemaan/feature/fingerbank-mysql
Browse files Browse the repository at this point in the history
Add Fingerbank MySQL backend support for Upstream DB
  • Loading branch information
dwlfrth committed Jul 29, 2016
2 parents 8ee3d08 + b9e9f8d commit 4b38e21
Show file tree
Hide file tree
Showing 15 changed files with 291 additions and 20 deletions.
13 changes: 13 additions & 0 deletions bin/mysql_fingerbank_import.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/bash

cd /usr/local/fingerbank/
result=`make init-mysql 2>&1`
status=$?
if [ $status -ne 0 ]; then
perl -I/usr/local/pf/lib -Mpf::config::util -e "pfmailer(subject => 'Failed to import Fingerbank data inside MySQL', message => qq[Output of the command was : $result])"
else
perl -I/usr/local/pf/lib -Mpf::config::util -e "pfmailer(subject => 'Successfully imported the Fingerbank data inside MySQL')"
fi

exit 0

7 changes: 7 additions & 0 deletions docs/PacketFence_Clustering_Guide.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,13 @@ host=127.0.0.1
....
----

In `/usr/local/fingerbank/conf/fingerbank.conf`

----
[mysql]
host=127.0.0.1
----

Make sure you restart MySQL, packetfence-config and packetfence

# service mysqld restart
Expand Down
13 changes: 12 additions & 1 deletion html/pfappserver/lib/pfappserver/Base/Controller.pm
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Allow only authenticated users
sub auto :Private {
my ($self, $c) = @_;

unless ($c->user_in_realm('admin')) {
if (!$self->configurator_accessible($c) && !$c->user_in_realm('admin')) {
$c->response->status(HTTP_UNAUTHORIZED);
$c->response->location($c->req->referer);
$c->stash->{template} = 'admin/unauthorized.tt';
Expand All @@ -80,6 +80,17 @@ sub auto :Private {
return 1;
}

=head2 configurator_accessible
Check if the current action can be accessed within the configurator and if the current user is in the configurator realm
=cut

sub configurator_accessible {
my ($self, $c) = @_;
return $c->action->attributes->{AdminConfigurator} && $c->user_in_realm('configurator');
}

=head2 valid_param
Subroutines with the 'SimpleSearch' attribute will automatically stash
Expand Down
28 changes: 28 additions & 0 deletions html/pfappserver/lib/pfappserver/I18N/en.po
Original file line number Diff line number Diff line change
Expand Up @@ -8748,6 +8748,34 @@ msgstr "Redis Host"
msgid "redis.port"
msgstr "Redis Port"

# /usr/local/fingerbank/conf/fingerbank.conf.doc
msgid "mysql.state"
msgstr "MySQL state"

# /usr/local/fingerbank/conf/fingerbank.conf.doc
msgid "mysql.host"
msgstr "MySQL host"

# /usr/local/fingerbank/conf/fingerbank.conf.doc
msgid "mysql.port"
msgstr "MySQL port"

# /usr/local/fingerbank/conf/fingerbank.conf.doc
msgid "mysql.username"
msgstr "MySQL username"

# /usr/local/fingerbank/conf/fingerbank.conf.doc
msgid "mysql.password"
msgstr "MySQL password"

# /usr/local/fingerbank/conf/fingerbank.conf.doc
msgid "mysql.database"
msgstr "MySQL database name"

# /usr/local/fingerbank/conf/fingerbank.conf.doc
msgid "mysql.incrementals_url"
msgstr "MySQL incrementals URL"

# pf::action (VIOLATION_ACTIONS)
msgid "reevaluate_access_action"
msgstr "Reevaluate Access Action"
Expand Down
26 changes: 14 additions & 12 deletions html/pfappserver/lib/pfappserver/Model/DB.pm
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ sub assign {
my $status_msg;

my $graphitedb = $dbHandler->quote_identifier($db . "_graphite");
my $fingerbankdb = $dbHandler->quote_identifier($db . "_fingerbank");
$db = $dbHandler->quote_identifier($db);

# Create global PF user
Expand Down Expand Up @@ -71,23 +72,24 @@ sub assign {
$status_msg = ["Successfully created the user [_1] on database [_2]",$user,$db];

# Create pf_graphite database
$db = $graphitedb;
foreach my $host ("'%'","localhost") {
my $sql_query = "GRANT ALL PRIVILEGES ON $db.* TO ?\@${host} IDENTIFIED BY ?";
$dbHandler->do($sql_query, undef, $user, $password);
foreach my $db ($graphitedb, $fingerbankdb) {
foreach my $host ("'%'","localhost") {
my $sql_query = "GRANT ALL PRIVILEGES ON $db.* TO ?\@${host} IDENTIFIED BY ?";
$dbHandler->do($sql_query, undef, $user, $password);
if ( $DBI::errstr ) {
$status_msg = "Error creating the user $user on database $db";
$logger->warn("$DBI::errstr");
return ( $STATUS::INTERNAL_SERVER_ERROR, $status_msg );
}
}
# Apply the new privileges
$dbHandler->do("FLUSH PRIVILEGES");
if ( $DBI::errstr ) {
$status_msg = "Error creating the user $user on database $db";
$status_msg = ["Error creating the user [_1] on database [_2]",$user,$db];
$logger->warn("$DBI::errstr");
return ( $STATUS::INTERNAL_SERVER_ERROR, $status_msg );
}
}
# Apply the new privileges
$dbHandler->do("FLUSH PRIVILEGES");
if ( $DBI::errstr ) {
$status_msg = ["Error creating the user [_1] on database [_2]",$user,$db];
$logger->warn("$DBI::errstr");
return ( $STATUS::INTERNAL_SERVER_ERROR, $status_msg );
}

# return original status message
return ( $STATUS::OK, $status_msg );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ Customizations can be made using L<pfappserver::Controller::Config::Fingerbank::
use Moose; # automatically turns on strict and warnings
use namespace::autoclean;
use pf::constants;
use pf::util;
use pf::config::util;
use pf::error qw(is_success);

BEGIN { extends 'pfappserver::Base::Controller'; }

Expand Down Expand Up @@ -82,6 +85,33 @@ sub update_redis_db :Local :Args(0) :AdminRole('FINGERBANK_UPDATE') {
$c->stash->{status_msg} = $c->loc("Successfully dispatched update request for the redis DB. An email will follow for status");
}

=head2 initialize_mysql
Initialize the MySQL database
=cut

sub initialize_mysql :Local :AdminRole('FINGERBANK_UPDATE') :AdminConfigurator {
my ( $self, $c ) = @_;
# HACK alert !
# Need to launch this job through an async bash session since this can be executed in the context of the configurator which means our Apache process can be restarted at any time.
my $pid = fork();
if($pid) {
$c->session->{importing_fingerbank_mysql} = $TRUE;
$c->stash->{current_view} = 'JSON';
$c->stash->{status_msg} = $c->loc("Dispatched the import job to PID $pid. An e-mail will follow up for status.");
}
else {
close STDERR;
close STDIN;
close STDOUT;

use POSIX();
POSIX::setsid();
exec('bash -c "/usr/local/pf/bin/mysql_fingerbank_import.sh &"');
}
}

=head1 AUTHOR
Inverse inc. <info@inverse.ca>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ sub check_for_api_key :Private {
}
}

sub onboard :Local :Args(0) :AdminRole('FINGERBANK_UPDATE') {
sub onboard :Local :Args(0) :AdminRole('FINGERBANK_UPDATE') :AdminConfigurator {
my ( $self, $c ) = @_;
my $logger = get_logger();

Expand All @@ -61,8 +61,10 @@ sub onboard :Local :Args(0) :AdminRole('FINGERBANK_UPDATE') {
# Sync the config to the cluster if necessary
pf::fingerbank::sync_configuration();

$c->req->method('GET'); # We need to change the request method since there's a filter on it in the index part.
$c->go('index');
if (defined($c->req->header('accept')) && $c->req->header('accept') ne 'application/json'){
$c->req->method('GET'); # We need to change the request method since there's a filter on it in the index part.
$c->go('index');
}
}
}

Expand Down Expand Up @@ -108,6 +110,7 @@ sub index :Path :Args(0) :AdminRole('FINGERBANK_READ') {
( !$params->{'upstream'}{'interrogate'} ) ? $params->{'upstream'}{'interrogate'} = 'disabled':();
( !$params->{'query'}{'record_unmatched'} ) ? $params->{'query'}{'record_unmatched'} = 'disabled':();
( !$params->{'query'}{'use_tcp_fingerprinting'} ) ? $params->{'query'}{'use_tcp_fingerprinting'} = 'disabled':();
( !$params->{'mysql'}{'state'} ) ? $params->{'mysql'}{'state'} = 'disabled':();

( $status, $status_msg ) = fingerbank::Config::write_config($params);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use Moose;

use pf::config qw(%Config);
use List::MoreUtils qw(all);
use fingerbank::Config;
#use namespace::autoclean;

BEGIN { extends 'Catalyst::Controller'; }
Expand All @@ -38,6 +39,9 @@ my @steps = (
{ id => 'admin',
title => 'Administration',
description => 'Configure access to the admin interface' },
{ id => 'fingerbank',
title => 'Fingerbank',
description => 'Configure Fingerbank' },
{ id => 'services',
title => 'Confirmation',
description => 'Start the services' }
Expand Down Expand Up @@ -290,6 +294,7 @@ PacketFence minimal configuration (step 4)

sub configuration :Chained('object') :PathPart('configuration') :Args(0) {
my ( $self, $c ) = @_;
my $logger = $c->log;

my $pf_model = $c->model('Config::Pf');
if ($c->request->method eq 'GET') {
Expand All @@ -305,14 +310,18 @@ sub configuration :Chained('object') :PathPart('configuration') :Args(0) {
general.hostname
general.dhcpservers
alerting.emailaddr
alerting.smtpserver
advanced.hash_passwords
)} = (
@$general_ref{qw(
domain
hostname
dhcpservers
)},
@$alerting_ref{emailaddr},
@$alerting_ref{qw(
emailaddr
smtpserver
)},
@$advanced_ref{hash_passwords}
);
$c->stash->{'config'} = \%config;
Expand All @@ -327,6 +336,7 @@ sub configuration :Chained('object') :PathPart('configuration') :Args(0) {
my $general_hostname = $c->request->params->{'general.hostname'};
my $general_dhcpservers = $c->request->params->{'general.dhcpservers'};
my $alerting_emailaddr = $c->request->params->{'alerting.emailaddr'};
my $alerting_smtpserver = $c->request->params->{'alerting.smtpserver'};
my $advanced_hash_passwords = $c->request->params->{'advanced.hash_passwords'};

unless ($general_domain && $general_hostname && $general_dhcpservers &&
Expand All @@ -341,18 +351,30 @@ sub configuration :Chained('object') :PathPart('configuration') :Args(0) {
'dhcpservers' => $general_dhcpservers,
});
if (is_error($status)) {
$logger->error($message);
delete $c->session->{completed}->{$c->action->name};
}
( $status, $message ) = $pf_model->update('alerting' => {
'emailaddr' => $alerting_emailaddr
'emailaddr' => $alerting_emailaddr,
});
if (is_error($status)) {
$logger->error($message);
delete $c->session->{completed}->{$c->action->name};
}
if($alerting_smtpserver) {
( $status, $message ) = $pf_model->update('smtpserver' => {
'smtpserver' => $alerting_emailaddr,
});
if (is_error($status)) {
$logger->error($message);
delete $c->session->{completed}->{$c->action->name};
}
}
( $status, $message ) = $pf_model->update('advanced' => {
'hash_passwords' => $advanced_hash_passwords
});
if (is_error($status)) {
$logger->error($message);
delete $c->session->{completed}->{$c->action->name};
} else {
$pf_model->commit();
Expand All @@ -370,6 +392,7 @@ sub configuration :Chained('object') :PathPart('configuration') :Args(0) {

}
if (is_error($status)) {
$logger->error($message);
$c->response->status($status);
$c->stash->{status_msg} = $message;
}
Expand Down Expand Up @@ -414,6 +437,19 @@ sub admin :Chained('object') :PathPart('admin') :Args(0) {
}
}

=head2 fingerbank
Fingerbank setup (step 6)
=cut

sub fingerbank :Chained('object') :PathPart('fingerbank') :Args(0) {
my ($self, $c) = @_;
$c->session->{completed}->{$c->action->name} = 1;
my $config = fingerbank::Config::get_config;
$c->stash->{fingerbank_api_key} = $config->{'upstream'}{'api_key'};
}

=head2 services
Confirmation and services launch (step 6)
Expand Down
2 changes: 2 additions & 0 deletions html/pfappserver/lib/pfappserver/PacketFence/Controller/DB.pm
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use HTTP::Status qw(:constants is_error is_success);
use Moose;
use namespace::autoclean;
use pf::db;
use fingerbank::Config;

BEGIN {extends 'Catalyst::Controller'; }

Expand Down Expand Up @@ -71,6 +72,7 @@ sub assign :Path('assign') :Args(1) {
$db_model->commit();
my $pfconfig = $c->model('Config::Pfconfig');
$pfconfig->update_mysql_credentials($pf_user, $pf_password);
fingerbank::Config::write_config({ mysql => { 'username' => $pf_user, 'password' => $pf_password, 'database' => 'pf_fingerbank' } });
pf::db::db_disconnect();
}
}
Expand Down
1 change: 1 addition & 0 deletions html/pfappserver/root/config/fingerbank/header.tt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<a class="updates_section_status_msg" href="[%c.uri_for(c.controller('Config::Fingerbank::DB').action_for('submit') )%]" ><i class="icon-share"></i> [% l('Submit Unknown/Unmatched Fingerprints') %]</a>
[% IF can_access("FINGERBANK_UPDATE") %]
| <a class="updates_section_status_msg" href="[%c.uri_for(c.controller('Config::Fingerbank::DB').action_for('update_upstream_db') )%]" ><i class="icon-refresh"></i> [% l('Update Fingerbank DB') %]</a>
| <a class="updates_section_status_msg" href="[%c.uri_for(c.controller('Config::Fingerbank::DB').action_for('initialize_mysql') )%]" ><i class="icon-refresh"></i> [% l('Initialize MySQL database') %]</a>
| <a class="updates_section_status_msg" href="[%c.uri_for(c.controller('Config::Fingerbank::DB').action_for('update_redis_db') )%]" ><i class="icon-refresh"></i> [% l('Update Redis DB') %]</a>
| <a class="updates_section_status_msg" href="[%c.uri_for(c.controller('Config::Fingerbank::DB').action_for('update_p0f_map') )%]" ><i class="icon-refresh"></i> [% l('Update Fingebank p0f map') %]</a>
[% END %]
Expand Down
7 changes: 7 additions & 0 deletions html/pfappserver/root/configurator/configuration.tt
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@
<p class="help-block">[% l('Email address to which notifications for rogue DHCP servers, violations with an action of <i>email</i>, or any other PacketFence-related messages goes to.') | none %]</p>
</div>
</div>
<div class="control-group">
<label class="control-label" for="alerting_smtpserver"></label>
<div class="controls">
<input type="text" class="input" id="alerting_smtpserver" value="[% config.${"alerting.smtpserver"} | html %]" placeholder="localhost">
<p class="help-block">[% l('IP address of your SMTP server for e-mail relaying. Leaving empty to use the localy running SMTP server.') | none %]</p>
</div>
</div>
<h3>[% l('Local Database Passwords') %]</h3>
<div class="control-group">
<label class="control-label" for="hash_passwords">[% l('Encryption') %]</label>
Expand Down
Loading

0 comments on commit 4b38e21

Please sign in to comment.