From 4e3bfee214ef3396fd9f126efb6ba0c00d9224a5 Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Tue, 15 Oct 2019 18:23:51 +0100 Subject: [PATCH] Add TACACS+ support per #660 (#662) --- Build.PL | 1 + lib/App/Netdisco/DB.pm | 2 +- lib/App/Netdisco/DB/Result/User.pm | 2 ++ .../Netdisco/DB/Result/Virtual/UserRole.pm | 3 +++ lib/App/Netdisco/Web/Auth/Provider/DBIC.pm | 24 +++++++++++++++++++ .../Netdisco/Web/Plugin/AdminTask/Users.pm | 2 ++ .../App-Netdisco-DB-60-61-PostgreSQL.sql | 5 ++++ share/views/ajax/admintask/users.tt | 5 ++++ share/views/ajax/admintask/users_csv.tt | 3 ++- 9 files changed, 45 insertions(+), 2 deletions(-) create mode 100644 share/schema_versions/App-Netdisco-DB-60-61-PostgreSQL.sql diff --git a/Build.PL b/Build.PL index 7c05c67b..9a6689a8 100644 --- a/Build.PL +++ b/Build.PL @@ -27,6 +27,7 @@ Module::Build->new( 'App::local::lib::helper' => '0.07', 'Archive::Extract' => '0', 'Authen::Radius' => '0', + 'Authen::TacacsPlus' => '0', 'CGI::Expand' => '2.05', 'Data::Printer' => '0', 'DBD::Pg' => '0', diff --git a/lib/App/Netdisco/DB.pm b/lib/App/Netdisco/DB.pm index 49a54131..18abc8d2 100644 --- a/lib/App/Netdisco/DB.pm +++ b/lib/App/Netdisco/DB.pm @@ -11,7 +11,7 @@ __PACKAGE__->load_namespaces( ); our # try to hide from kwalitee - $VERSION = 60; # schema version used for upgrades, keep as integer + $VERSION = 61; # schema version used for upgrades, keep as integer use Path::Class; use File::ShareDir 'dist_dir'; diff --git a/lib/App/Netdisco/DB/Result/User.pm b/lib/App/Netdisco/DB/Result/User.pm index 6e525547..b1de5921 100644 --- a/lib/App/Netdisco/DB/Result/User.pm +++ b/lib/App/Netdisco/DB/Result/User.pm @@ -31,6 +31,8 @@ __PACKAGE__->add_columns( { data_type => "boolean", default_value => \"false", is_nullable => 1 }, "radius", { data_type => "boolean", default_value => \"false", is_nullable => 1 }, + "tacacs", + { data_type => "boolean", default_value => \"false", is_nullable => 1 }, "admin", { data_type => "boolean", default_value => \"false", is_nullable => 1 }, "fullname", diff --git a/lib/App/Netdisco/DB/Result/Virtual/UserRole.pm b/lib/App/Netdisco/DB/Result/Virtual/UserRole.pm index 7e9f2910..16ca8420 100644 --- a/lib/App/Netdisco/DB/Result/Virtual/UserRole.pm +++ b/lib/App/Netdisco/DB/Result/Virtual/UserRole.pm @@ -23,6 +23,9 @@ __PACKAGE__->result_source_instance->view_definition(<radius) { $pwmatch_result = $self->match_with_radius($password, $username); } + elsif ($user->tacacs) { + $pwmatch_result = $self->match_with_tacacs($password, $username); + } else { $pwmatch_result = $self->match_with_local_pass($password, $user); } @@ -251,4 +255,24 @@ sub match_with_radius { return $radius_return; } +sub match_with_tacacs { + my($self, $pass, $user) = @_; + return unless setting('tacacs') and ref {} eq ref setting('tacacs'); + + my $conf = setting('tacacs'); + my $tacacs = new Authen::TacacsPlus(Host => $conf->{server}, Key => $conf->{key}); + if (not $tacacs) { + debug sprintf('auth error: Authen::TacacsPlus: %s', Authen::TacacsPlus::errmsg()); + return undef; + } + + my $tacacs_return = $tacacs->authen($user,$pass); + if (not $tacacs_return) { + debug sprintf('error: Authen::TacacsPlus: %s', Authen::TacacsPlus::errmsg()); + } + $tacacs->close(); + + return $tacacs_return; +} + 1; diff --git a/lib/App/Netdisco/Web/Plugin/AdminTask/Users.pm b/lib/App/Netdisco/Web/Plugin/AdminTask/Users.pm index 712e26ca..458ecd90 100644 --- a/lib/App/Netdisco/Web/Plugin/AdminTask/Users.pm +++ b/lib/App/Netdisco/Web/Plugin/AdminTask/Users.pm @@ -42,6 +42,7 @@ ajax '/ajax/control/admin/users/add' => require_role setting('defanged_admin') = fullname => param('fullname'), ldap => (param('ldap') ? \'true' : \'false'), radius => (param('radius') ? \'true' : \'false'), + tacacs => (param('tacacs') ? \'true' : \'false'), port_control => (param('port_control') ? \'true' : \'false'), admin => (param('admin') ? \'true' : \'false'), note => param('note'), @@ -73,6 +74,7 @@ ajax '/ajax/control/admin/users/update' => require_role setting('defanged_admin' fullname => param('fullname'), ldap => (param('ldap') ? \'true' : \'false'), radius => (param('radius') ? \'true' : \'false'), + tacacs => (param('tacacs') ? \'true' : \'false'), port_control => (param('port_control') ? \'true' : \'false'), admin => (param('admin') ? \'true' : \'false'), note => param('note'), diff --git a/share/schema_versions/App-Netdisco-DB-60-61-PostgreSQL.sql b/share/schema_versions/App-Netdisco-DB-60-61-PostgreSQL.sql new file mode 100644 index 00000000..46fbc8f7 --- /dev/null +++ b/share/schema_versions/App-Netdisco-DB-60-61-PostgreSQL.sql @@ -0,0 +1,5 @@ +BEGIN; + +ALTER TABLE users ADD COLUMN "tacacs" boolean DEFAULT false; + +COMMIT; diff --git a/share/views/ajax/admintask/users.tt b/share/views/ajax/admintask/users.tt index 809eeec6..a4b76511 100644 --- a/share/views/ajax/admintask/users.tt +++ b/share/views/ajax/admintask/users.tt @@ -6,6 +6,7 @@ Password LDAP Auth RADIUS Auth + TACACS+ Auth Port Control Administrator Created @@ -21,6 +22,7 @@ + @@ -50,6 +52,9 @@ + + + diff --git a/share/views/ajax/admintask/users_csv.tt b/share/views/ajax/admintask/users_csv.tt index 5005c6e8..d08bace7 100644 --- a/share/views/ajax/admintask/users_csv.tt +++ b/share/views/ajax/admintask/users_csv.tt @@ -1,6 +1,6 @@ [% USE CSV -%] [% CSV.dump([ 'Full Name' 'Username' - 'LDAP Auth' 'RADIUS Auth' 'Port Control' 'Administrator' 'Created' + 'LDAP Auth' 'RADIUS Auth' 'TACACS+ Auth' 'Port Control' 'Administrator' 'Created' 'Last Login' 'Note']) %] [% FOREACH row IN results %] @@ -9,6 +9,7 @@ [% mylist.push(row.username) %] [% mylist.push(row.ldap) %] [% mylist.push(row.radius) %] + [% mylist.push(row.tacacs) %] [% mylist.push(row.port_control) %] [% mylist.push(row.admin) %] [% mylist.push(row.created) %]