Add version info and optimize log for smart.log
This commit is contained in:
506
smart.cmake
506
smart.cmake
@@ -1,12 +1,13 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
|
||||
#
|
||||
# SMArT
|
||||
#
|
||||
# Main program file
|
||||
#
|
||||
# Copyright 2001 Wilmer van der Gaast
|
||||
#
|
||||
#
|
||||
#
|
||||
# Main web frontend
|
||||
#
|
||||
# Copyright 2001 Wilmer van der Gaast (lintux@lintux.cx)
|
||||
#
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
@@ -25,288 +26,295 @@
|
||||
|
||||
$redirected = 0;
|
||||
|
||||
$server_id = 'Server: SMArT/Perl/@MARS_NWE_VERSION@';
|
||||
$smart_version = '@MARS_NWE_VERSION@';
|
||||
$server_id = 'Server: SMArT/Perl/' . $smart_version;
|
||||
|
||||
do( '@MARS_NWE_INSTALL_FULL_CONFDIR@/smart.conf' )
|
||||
or die "Could not load @MARS_NWE_INSTALL_FULL_CONFDIR@/smart.conf: $@ $!";
|
||||
|
||||
close( STDERR );
|
||||
open( STDERR, '>>' . $smart_log_path )
|
||||
or die "Could not open $smart_log_path: $!";
|
||||
if( ! do('@MARS_NWE_INSTALL_FULL_CONFDIR@/smart.conf') )
|
||||
{
|
||||
die "Could not load @MARS_NWE_INSTALL_FULL_CONFDIR@/smart.conf: $@ $!";
|
||||
}
|
||||
|
||||
$ENV{HOME} = '@MARS_NWE_INSTALL_FULL_CONFDIR@';
|
||||
$smart_libexec_dir = '@MARS_NWE_INSTALL_FULL_LIBEXECDIR@';
|
||||
$smart_libexec_dir =~ s#/*$##;
|
||||
|
||||
close( STDERR );
|
||||
open( STDERR, '>>' . $smart_log_path ) or die "Could not open $smart_log_path: $!";
|
||||
select( STDERR ); $| = 1;
|
||||
select( STDOUT ); $| = 1;
|
||||
|
||||
sub log_timestamp()
|
||||
{
|
||||
my @t = localtime( time() );
|
||||
return sprintf(
|
||||
'%04d-%02d-%02d %02d:%02d:%02d',
|
||||
$t[5] + 1900, $t[4] + 1, $t[3],
|
||||
$t[2], $t[1], $t[0]
|
||||
);
|
||||
}
|
||||
|
||||
sub log_msg( $$ )
|
||||
{
|
||||
my( $level, $msg ) = @_;
|
||||
print STDERR '[' . log_timestamp() . '] [' . $level . '] [SMArT ' . $smart_version . '] ' . $msg . "\n";
|
||||
}
|
||||
|
||||
sub log_info( $ )
|
||||
{
|
||||
log_msg( 'INFO', $_[0] );
|
||||
}
|
||||
|
||||
sub log_error( $ )
|
||||
{
|
||||
log_msg( 'ERROR', $_[0] );
|
||||
}
|
||||
|
||||
log_info( 'starting' );
|
||||
log_info( 'loaded configuration from ' . '@MARS_NWE_INSTALL_FULL_CONFDIR@/smart.conf' );
|
||||
|
||||
$l = <STDIN>;
|
||||
if( ! defined( $l ) )
|
||||
{
|
||||
log_error( 'no request line received on stdin' );
|
||||
exit( 1 );
|
||||
}
|
||||
$l =~ s/[\n\r]//g;
|
||||
log_info( 'request: ' . $l );
|
||||
|
||||
@c = split( ' ', $l );
|
||||
if( scalar( @c ) > 2 )
|
||||
{
|
||||
while( keys( %h ) < 15 ) # Who would ever want to send more headers???
|
||||
{
|
||||
$l = <STDIN>;
|
||||
$l =~ s/[\n\r]//g;
|
||||
if( $l eq '' )
|
||||
{ last; }
|
||||
$n = $l;
|
||||
$n =~ s/:[^:]*$//g;
|
||||
$v = $l;
|
||||
$v =~ s/^[^:]*://g;
|
||||
$h{$n} = $v;
|
||||
}
|
||||
}
|
||||
|
||||
$c[0] = uc( $c[0] );
|
||||
|
||||
if( $h{Authorization} eq '' )
|
||||
{ error( 401 ); }
|
||||
else
|
||||
{
|
||||
@s = split( ' ', $h{Authorization} );
|
||||
if( $s[0] ne 'Basic' or length( $h{Authorization} ) > 80 ) # We can't be too careful, can we...
|
||||
{ error( 401 ); }
|
||||
else
|
||||
{
|
||||
$s[1] =~ tr#A-Za-z0-9+/##cd;
|
||||
$s[1] =~ tr#A-Za-z0-9+/# -_#;
|
||||
$s[1] = pack( 'c', 32 + 0.75 * length( $s[1] ) ) . $s[1];
|
||||
$s[1] = unpack( 'u', $s[1] );
|
||||
$s[1] =~ s/[\r\n]//g;
|
||||
@l = split( ':', $s[1] );
|
||||
if( $l[0] ne 'root' )
|
||||
{ error( 401 ); }
|
||||
else
|
||||
{ if( $x = system( $smart_check_login, @l ) )
|
||||
{ error( 401 ); } }
|
||||
}
|
||||
}
|
||||
|
||||
if( $c[0] ne 'GET' )
|
||||
{
|
||||
error( 501 );
|
||||
}
|
||||
|
||||
@p = split( '\?', $c[1] );
|
||||
$cc = $c[1];
|
||||
$cc =~ s/[^\?]*\?//;
|
||||
$c = substr( shift( @p ), 1 );
|
||||
@p = split( '&', $p[0] );
|
||||
foreach $p ( @p )
|
||||
{
|
||||
$n = $p;
|
||||
$n =~ s/=.*//;
|
||||
$v = $p;
|
||||
$v =~ s/.*=//;
|
||||
$v =~ s/\+/ /g;
|
||||
$v =~ s/%([0-9A-F][0-9A-F])/pack('c',hex($1))/gie;
|
||||
$p{$n} = $v;
|
||||
}
|
||||
@c = split( '/', $c );
|
||||
@c = split( '/', $c[1] );
|
||||
shift( @c );
|
||||
|
||||
if( $c[0] eq 'apply' )
|
||||
sub error( $ )
|
||||
{
|
||||
do( $smart_libexec_dir . '/readconfig.pl' );
|
||||
do( $smart_libexec_dir . '/apply.pl' );
|
||||
handle_request();
|
||||
exit;
|
||||
}
|
||||
elsif( $c[0] eq 'settings' )
|
||||
{
|
||||
do( $smart_libexec_dir . '/readconfig.pl' );
|
||||
}
|
||||
my( $e ) = @_;
|
||||
|
||||
drop_root();
|
||||
log_error( 'HTTP error ' . $e . ' for request ' . $cc );
|
||||
|
||||
if( $c[0] eq '' )
|
||||
{
|
||||
print <<EOF;
|
||||
HTTP/1.0 200 OK
|
||||
print <<EOF;
|
||||
HTTP/1.0 $e Error
|
||||
Content-Type: text/html
|
||||
$server_id
|
||||
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>SMArT</TITLE>
|
||||
</HEAD>
|
||||
<FRAMESET COLS="50%,50%">
|
||||
<FRAME NAME="MENU" SRC="/static/menu.html">
|
||||
<FRAME NAME="OPTS" SRC="/static/start.html">
|
||||
</FRAMESET>
|
||||
<BODY BGCOLOR=$COLOR_BACK>
|
||||
<H1>Error $e</H1>
|
||||
</BODY>
|
||||
</HTML>
|
||||
EOF
|
||||
exit;
|
||||
}
|
||||
elsif( $c[0] eq 'static' )
|
||||
{
|
||||
do( $smart_libexec_dir . '/static.pl' );
|
||||
}
|
||||
elsif( $c[0] eq 'settings' )
|
||||
{
|
||||
do( $smart_libexec_dir . '/settings.pl' );
|
||||
}
|
||||
else
|
||||
{
|
||||
error( 500 );
|
||||
}
|
||||
|
||||
handle_request();
|
||||
exit;
|
||||
|
||||
##########################################
|
||||
##### END OF MAIN PROCEDURES FOLLOW #####
|
||||
##########################################
|
||||
|
||||
sub error( $ )
|
||||
{
|
||||
if( $_[0] eq '401' )
|
||||
{
|
||||
print <<EOF;
|
||||
HTTP/1.0 401 Access denied
|
||||
Content-Type: text/plain
|
||||
WWW-Authenticate: Basic realm="SMArT"
|
||||
$server_id
|
||||
|
||||
You're not allowed to access this URL.
|
||||
EOF
|
||||
}
|
||||
elsif( $_[0] eq '404' )
|
||||
{
|
||||
print <<EOF;
|
||||
HTTP/1.0 404 File not found
|
||||
Content-Type: text/plain
|
||||
$server_id
|
||||
|
||||
The file you requested does not exist.
|
||||
EOF
|
||||
}
|
||||
elsif( $_[0] eq '501' )
|
||||
{
|
||||
print <<EOF;
|
||||
HTTP/1.0 501 Unknown command
|
||||
Content-Type: text/plain
|
||||
$server_id
|
||||
|
||||
Unknown command: $c[0]
|
||||
EOF
|
||||
}
|
||||
else
|
||||
{
|
||||
print <<EOF;
|
||||
HTTP/1.0 500 Internal server error
|
||||
Content-Type: text/plain
|
||||
$server_id
|
||||
|
||||
Something went wrong...
|
||||
EOF
|
||||
}
|
||||
exit;
|
||||
}
|
||||
|
||||
sub unix_userlist()
|
||||
{
|
||||
my( @c, @d, %e );
|
||||
|
||||
while( @d = getpwent )
|
||||
{
|
||||
unshift( @c, { name => $d[0], uid => $d[2] } );
|
||||
}
|
||||
return( sort( { $a->{"name"} cmp $b->{"name"} } @c ) );
|
||||
}
|
||||
|
||||
sub unix_grouplist()
|
||||
{
|
||||
my( @c, @d, %e );
|
||||
|
||||
while( @d = getgrent )
|
||||
{
|
||||
unshift( @c, { name => $d[0], gid => $d[2] } );
|
||||
}
|
||||
return( sort( { $a->{"name"} cmp $b->{"name"} } @c ) );
|
||||
exit;
|
||||
}
|
||||
|
||||
sub redirect( $ )
|
||||
{
|
||||
if( $redirected != 0 )
|
||||
{ return( 0 ); }
|
||||
$redirected = 1;
|
||||
print <<EOF;
|
||||
HTTP/1.0 302 Page relocated
|
||||
Content-Type: text/plain
|
||||
Location: $_[0]
|
||||
my( $u ) = @_;
|
||||
|
||||
print <<EOF;
|
||||
HTTP/1.0 302 Found
|
||||
Location: $u
|
||||
$server_id
|
||||
|
||||
EOF
|
||||
$redirected = 1;
|
||||
exit;
|
||||
}
|
||||
|
||||
sub get_server
|
||||
sub drop_root()
|
||||
{
|
||||
open( SFILE, '<' . $smart_nwclient_path );
|
||||
chomp( $line = <SFILE> );
|
||||
close( SFILE );
|
||||
|
||||
$line =~ s/\/.*//;
|
||||
return( $line );
|
||||
}
|
||||
|
||||
sub get_bindery_password
|
||||
{
|
||||
open( SFILE, '<' . $smart_nwclient_path );
|
||||
chomp( $line = <SFILE> );
|
||||
close( SFILE );
|
||||
|
||||
$line =~ s/.* //;
|
||||
return( $line );
|
||||
}
|
||||
|
||||
sub read_property_string
|
||||
{
|
||||
my @x = split( "\n", `nwbpvalues -c -o $_[0] -t $_[1] -p $_[2] -S $server` );
|
||||
my( $i, $s );
|
||||
|
||||
$i = 5;
|
||||
while( hex( $x[$i] ) > 0 )
|
||||
if( $> == 0 )
|
||||
{
|
||||
my $uid = getpwnam( $nonroot_user );
|
||||
if( ! defined( $uid ) )
|
||||
{
|
||||
$s .= pack( 'c', hex( $x[$i] ) );
|
||||
$i ++;
|
||||
log_error( 'could not resolve non-root user ' . $nonroot_user );
|
||||
error( 500 );
|
||||
}
|
||||
|
||||
return( $s );
|
||||
$> = $uid;
|
||||
}
|
||||
}
|
||||
|
||||
sub read_property_list
|
||||
sub get_server()
|
||||
{
|
||||
my @x = split( "\n", `nwbpvalues -c -o $_[0] -t $_[1] -p $_[2] -S $server` );
|
||||
my( $i, @l );
|
||||
|
||||
$i = 6;
|
||||
while( $x[$i] ne '' )
|
||||
{
|
||||
unshift( @l, $x[$i] );
|
||||
$i += 2;
|
||||
}
|
||||
|
||||
return( @l );
|
||||
open( SFILE, '<' . $smart_nwclient_path ) or do {
|
||||
log_error( 'could not open ' . $smart_nwclient_path . ': ' . $! );
|
||||
return '';
|
||||
};
|
||||
chomp( $line = <SFILE> );
|
||||
close( SFILE );
|
||||
|
||||
$line =~ s/\/.*//;
|
||||
return( $line );
|
||||
}
|
||||
|
||||
sub write_property_string
|
||||
sub get_bindery_password()
|
||||
{
|
||||
open( FILE, '|' . 'nwbpset -S ' . $server );
|
||||
print FILE <<EOF;
|
||||
000$_[1]
|
||||
$_[0]
|
||||
$_[2]
|
||||
$_[3]
|
||||
$_[4]
|
||||
open( SFILE, '<' . $smart_nwclient_path ) or do {
|
||||
log_error( 'could not open ' . $smart_nwclient_path . ': ' . $! );
|
||||
return '';
|
||||
};
|
||||
chomp( $line = <SFILE> );
|
||||
close( SFILE );
|
||||
|
||||
$line =~ s/.* //;
|
||||
return( $line );
|
||||
}
|
||||
|
||||
sub unix_userlist()
|
||||
{
|
||||
my( @l, @r, $u );
|
||||
open( FILE, '</etc/passwd' ) or return();
|
||||
while( <FILE> )
|
||||
{
|
||||
chomp;
|
||||
@l = split( /:/ );
|
||||
$u = {};
|
||||
$u->{name} = $l[0];
|
||||
$u->{uid} = $l[2];
|
||||
push( @r, $u );
|
||||
}
|
||||
close( FILE );
|
||||
return( @r );
|
||||
}
|
||||
|
||||
sub unix_grouplist()
|
||||
{
|
||||
my( @l, @r, $u );
|
||||
open( FILE, '</etc/group' ) or return();
|
||||
while( <FILE> )
|
||||
{
|
||||
chomp;
|
||||
@l = split( /:/ );
|
||||
$u = {};
|
||||
$u->{name} = $l[0];
|
||||
$u->{gid} = $l[2];
|
||||
push( @r, $u );
|
||||
}
|
||||
close( FILE );
|
||||
return( @r );
|
||||
}
|
||||
|
||||
sub write_property_string( $$$$$ )
|
||||
{
|
||||
my( $obj, $type, $prop, $seg, $len, $str ) = @_;
|
||||
|
||||
open( FILE, '|' . 'nwbpset -S ' . get_server() ) or return;
|
||||
print FILE <<EOF;
|
||||
000$type
|
||||
$obj
|
||||
$prop
|
||||
$seg
|
||||
$len
|
||||
$str
|
||||
EOF
|
||||
for $i ( 0 .. length( $_[5] ) - 1 )
|
||||
{
|
||||
print( FILE unpack( 'H2', substr( $_[5], $i, 1 ) ) . "\n" );
|
||||
}
|
||||
close( FILE );
|
||||
close( FILE );
|
||||
}
|
||||
|
||||
sub drop_root
|
||||
sub read_property_string( $$$ )
|
||||
{
|
||||
$< = $> = getpwnam( $nonroot_user );
|
||||
my( $obj, $type, $prop ) = @_;
|
||||
my( @l, $s );
|
||||
|
||||
open( FILE, 'nwbpvalues -S ' . get_server() . ' -o ' . $obj . ' -t ' . $type . ' -p ' . $prop . ' |' ) or return '';
|
||||
@l = <FILE>;
|
||||
close( FILE );
|
||||
|
||||
$s = join( '', @l );
|
||||
$s =~ s/[\r\n]+$//g;
|
||||
return( $s );
|
||||
}
|
||||
|
||||
sub authenticate()
|
||||
{
|
||||
my( @h, $auth, @l, $x );
|
||||
|
||||
while( $l = <STDIN> )
|
||||
{
|
||||
$l =~ s/[\n\r]//g;
|
||||
last if $l eq '';
|
||||
push( @h, $l );
|
||||
}
|
||||
|
||||
($auth) = grep( /^Authorization: /i, @h );
|
||||
if( $auth eq '' )
|
||||
{
|
||||
print <<EOF;
|
||||
HTTP/1.0 401 Unauthorized
|
||||
WWW-Authenticate: Basic realm="SMArT"
|
||||
$server_id
|
||||
|
||||
EOF
|
||||
exit;
|
||||
}
|
||||
|
||||
$auth =~ s/^Authorization:\s*Basic\s*//i;
|
||||
$auth = unpack( 'u', $auth ) if $auth =~ /^[\x20-\x7e]+$/ && $auth !~ /:/;
|
||||
$auth =~ s/[\r\n]//g;
|
||||
|
||||
@l = split( ':', $auth, 2 );
|
||||
if( $l[0] ne 'root' )
|
||||
{
|
||||
log_error( 'authentication failed for non-root user ' . $l[0] );
|
||||
error( 401 );
|
||||
}
|
||||
else
|
||||
{
|
||||
$x = system( $smart_check_login, @l );
|
||||
if( $x )
|
||||
{
|
||||
log_error( 'authentication failed for user root' );
|
||||
error( 401 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
authenticate();
|
||||
|
||||
if( $c[0] eq 'apply' )
|
||||
{
|
||||
do( $smart_libexec_dir . '/readconfig.pl' ) or do {
|
||||
log_error( 'could not load readconfig.pl: ' . $@ . ' ' . $! );
|
||||
error( 500 );
|
||||
};
|
||||
do( $smart_libexec_dir . '/apply.pl' ) or do {
|
||||
log_error( 'could not load apply.pl: ' . $@ . ' ' . $! );
|
||||
error( 500 );
|
||||
};
|
||||
handle_request();
|
||||
exit;
|
||||
}
|
||||
elsif( $c[0] eq 'settings' )
|
||||
{
|
||||
do( $smart_libexec_dir . '/readconfig.pl' ) or do {
|
||||
log_error( 'could not load readconfig.pl: ' . $@ . ' ' . $! );
|
||||
error( 500 );
|
||||
};
|
||||
}
|
||||
|
||||
drop_root();
|
||||
|
||||
if( $cc eq '/' or $cc eq '' )
|
||||
{
|
||||
redirect( '/static/start.html' );
|
||||
}
|
||||
elsif( $c[0] eq 'static' )
|
||||
{
|
||||
do( $smart_libexec_dir . '/static.pl' ) or do {
|
||||
log_error( 'could not load static.pl: ' . $@ . ' ' . $! );
|
||||
error( 500 );
|
||||
};
|
||||
handle_request();
|
||||
}
|
||||
elsif( $c[0] eq 'settings' )
|
||||
{
|
||||
do( $smart_libexec_dir . '/settings.pl' ) or do {
|
||||
log_error( 'could not load settings.pl: ' . $@ . ' ' . $! );
|
||||
error( 500 );
|
||||
};
|
||||
handle_request();
|
||||
}
|
||||
else
|
||||
{
|
||||
log_error( 'unknown path ' . $cc );
|
||||
error( 404 );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user