summaryrefslogtreecommitdiff
path: root/fs_sesmon/fs_session_server
diff options
context:
space:
mode:
Diffstat (limited to 'fs_sesmon/fs_session_server')
-rw-r--r--fs_sesmon/fs_session_server140
1 files changed, 140 insertions, 0 deletions
diff --git a/fs_sesmon/fs_session_server b/fs_sesmon/fs_session_server
new file mode 100644
index 0000000..00229f8
--- /dev/null
+++ b/fs_sesmon/fs_session_server
@@ -0,0 +1,140 @@
+#!/usr/bin/perl -Tw
+#
+# fs_session_server
+#
+
+use strict;
+use vars qw( $opt $Debug );
+use IO::Handle;
+use Net::SSH qw(sshopen2);
+use FS::UID qw(adminsuidsetup dbh);
+use FS::Record qw( qsearchs ); #qsearch );
+#use FS::cust_main_county;
+#use FS::cust_main;
+use FS::session;
+use FS::port;
+use FS::svc_acct;
+
+#require "configfile";
+$Debug = 1;
+
+my $user = shift or die &usage;
+&adminsuidsetup( $user );
+
+my $machine = shift or die &usage;
+
+my $fs_sessiond = "/usr/local/sbin/fs_sessiond";
+
+my $me = "[fs_session_server]";
+
+while (1) {
+ my($reader, $writer) = (new IO::Handle, new IO::Handle);
+ $writer->autoflush(1);
+ warn "$me Connecting to $machine\n" if $Debug;
+ sshopen2($machine,$reader,$writer,$fs_sessiond);
+
+ warn "$me Entering main loop\n" if $Debug;
+ while (1) {
+ warn "$me Reading (waiting for) data\n" if $Debug;
+ my $command = scalar(<$reader>);
+ chomp $command;
+ #DoS protection here too, to protect against a compromised client? *sigh*
+ my %hash;
+ while ( ( my $key = scalar(<$reader>) ) ne "END\n" ) {
+ chomp $key;
+ chomp( $hash{$key} = scalar(<$reader>) );
+ }
+
+ if ( $command eq 'login' ) {
+ my $error = &login(\%hash);
+ print $writer "$error\n";
+ } elsif ( $command eq 'logout' ) {
+ my $error = &logout(\%hash);
+ print $writer "$error\n";
+ } elsif ( $command eq 'portnum' ) {
+ my $port;
+ if ( exists $hash{'ip'} ) {
+ $hash{'ip'} =~ /^([\d\.]+)$/ or $1='nomatch';
+ $port = qsearchs('port', { 'ip' => $1 } );
+ } else {
+ $hash{'nasnum'} =~ /^(\d+)$/ and my $nasnum = $1;
+ $hash{'nasport'} =~ /^(\d+)$/ and my $nasport = $1;
+ $port = qsearchs('port', { 'nasnum'=>$nasnum, 'nasport'=>$nasport } );
+ }
+ print $writer ( $port ? $port->portnum : '' ), "\n";
+ } else {
+ warn "$me WARNING: unrecognized command: $command";
+ }
+ }
+ #won't ever reach without code above to throw out of loop, but...
+ close $writer;
+ close $reader;
+ warn "connection to $machine lost!\n";
+ sleep 5;
+ warn "reconnecting...\n";
+}
+
+sub login {
+ my $href = shift;
+ $href->{'username'} =~ /^([a-z0-9_\-\.]+)$/ or return "Illegal username";
+ my $username = $1;
+ my $svc_acct = qsearchs('svc_acct', { 'username' => $username } )
+ or return "Unknown user";
+ return "Incorrect password"
+ if exists($href->{'password'})
+ && $href->{'password'} ne $svc_acct->_password;
+ return "Time limit exceeded" unless $svc_acct->seconds;
+ my $session = new FS::session {
+ 'portnum' => $href->{'portnum'},
+ 'svcnum' => $svc_acct->svcnum,
+ 'login' => $href->{'login'},
+ };
+ $session->insert;
+}
+
+sub logout {
+ my $href = shift;
+ $href->{'username'} =~ /^([a-z0-9_\-\.]+)$/ or return "Illegal username";
+ my $username = $1;
+ local $FS::UID::AutoCommit = 0;
+ my $dbh = dbh;
+ my $svc_acct =
+ qsearchs('svc_acct', { 'username' => $username }, '', 'FOR UPDATE' )
+ or return "Unknown user";
+ return "Incorrect password"
+ if exists($href->{'password'})
+ && $href->{'password'} ne $svc_acct->_password;
+ my $session = qsearchs( 'session', {
+ 'portnum' => $href->{'portnum'},
+ 'svcnum' => $svc_acct->svcnum,
+ 'logout' => '',
+ },
+ '', 'FOR UPDATE'
+ );
+ unless ( $session ) {
+ $dbh->rollback;
+ return "No currently open sessions found for that user/port!";
+ }
+ my $nsession = new FS::session ( { $session->hash } );
+ warn "$nsession replacing $session";
+ my $error = $nsession->replace($session);
+ if ( $error ) {
+ $dbh->rollback;
+ return "can't logout: $error";
+ }
+ my $time = $nsession->logout - $nsession->login;
+ my $new_svc_acct = new FS::svc_acct ( { $svc_acct->hash } );
+ my $seconds = $new_svc_acct->seconds;
+ $seconds -= $time;
+ $seconds = 0 if $seconds < 0;
+ $new_svc_acct->seconds( $seconds );
+ $error = $new_svc_acct->replace( $svc_acct );
+ warn "can't debit time: $error\n"; #don't want to rollback, though
+ $dbh->commit or die $dbh->errstr;
+ ''
+}
+
+sub usage {
+ die "Usage:\n\n fs_session_server user machine\n";
+}
+