Commit 11f06dbe authored by Kevin Atkinson's avatar Kevin Atkinson

Add support for authorization.

parent 9764b311
......@@ -12,22 +12,32 @@ SUBDIR = collab/exp-vis
include $(OBJDIR)/Makeconf
CGI_SCRIPTS = fetch-vis
LIBEXEC_SCRIPTS = write-vis-auth-boss
CTRL_LIBEXEC_SCRIPTS = write-vis-auth-ops
SETUID_LIBX_SCRIPTS = write-vis-auth-boss
#
# Force dependencies on the scripts so that they will be rerun through
# configure if the .in file is changed.
#
all: $(CGI_SCRIPTS)
all: $(CGI_SCRIPTS) $(LIBEXEC_SCRIPTS) $(CTRL_LIBEXEC_SCRIPTS)
include $(TESTBED_SRCDIR)/GNUmakerules
install: \
$(addprefix $(TBROOT)/opsdir/www/cgi-bin/, $(CGI_SCRIPTS))
$(addprefix $(INSTALL_LIBEXECDIR)/, $(LIBEXEC_SCRIPTS)) \
$(addprefix $(TBROOT)/opsdir/www/cgi-bin/, $(CGI_SCRIPTS)) \
$(addprefix $(INSTALL_DIR)/opsdir/libexec/, $(CTRL_LIBEXEC_SCRIPTS))
$(TBROOT)/opsdir/www/cgi-bin/fetch-vis: fetch-vis
-$(SUDO) mkdir -m 775 $(TBROOT)/opsdir/www/cgi-bin
$(SUDO) $(INSTALL) -o root -m 4775 $< $@
$(INSTALL_DIR)/opsdir/libexec/write-vis-auth-ops: write-vis-auth-ops
-mkdir -p $(INSTALL_DIR)/opsdir/libexec
$(INSTALL) $< $@
post-install:
clean:
......
#!/usr/bin/perl -T
#
# XXX: Add support for returning file modification times in the head
# Also support HEAD requests
#
use strict;
use warnings;
use POSIX qw(setuid setgid);
use Cwd qw(realpath);
use CGI;
use CGI::Cookie;
use Data::Dumper;
#print "\n\n";
#print Dumper(\%ENV);
#print STDERR Dumper(\%ENV);
my $FSDIR_PROJ = "@FSDIR_PROJ@";
my $FSDIR_GROUPS = "@FSDIR_GROUPS@";
sub error($) {
print "Content-Type: text/plain\n";
......@@ -23,32 +31,43 @@ sub error($) {
my $SCRIPT_URL = $ENV{SCRIPT_URL};
my ($proj,$dir,$file);
# Parse URL
my ($proj,$group,$exp,$dir,$file);
local $_ = $SCRIPT_URL;
if (/^\/proj-vis\/([a-zA-Z0-9-]+)\/?(.*)$/) {
$proj = $1;
$dir = "/proj/$1/www/proj-vis";
$group = $1;
$file = $2;
} elsif (/^\/group-vis\/([a-zA-Z0-9-]+)\/?([a-zA-Z0-9-]+)\/?(.*)$/) {
$proj = $1;
$group = $2;
$file = $3;
} elsif (/^\/exp-vis\/([a-zA-Z0-9-]+)\/?([a-zA-Z0-9-]+)\/?(.*)$/) {
$proj = $1;
$dir = "/proj/$1/www/exp-vis/$2";
$exp = $2;
$file = $3;
} else {
error("Malformed URL");
}
if (defined $exp) {
my $exp_dir = "/proj/$proj/exp/$exp";
local $_ = realpath $exp_dir;
if (/^$FSDIR_PROJ\/$proj\//) {
$group = $proj;
} elsif (/^$FSDIR_GROUPS\/$proj\/(.+?)\//) {
$group = $1;
}
$dir = "/groups/$proj/$group/www/exp-vis/$exp";
} else {
$dir = "/groups/$proj/$group/www/group-vis";
}
# Lookup up the gid from the project name and make that the
# only group we have access to
my ($name, undef, $gid) = getgrnam($proj);
error("Invalid proj: $proj") if $proj ne $name;
undef $!;
$) = "$gid $gid";
setgid($gid);
die $! if $!;
# Now drop privileges, using setuid to make sure the saved uid
# is also changes, ie, so that the change is permanent.
setuid($<) or die $!;
# Lookup up the Unix GID for the proj and the group
my (undef,undef,undef,undef,undef,$gid) = stat("/proj/$proj") or die;
my ($gid_name,undef,undef,$gid_members) = getgrgid($gid);
die "Error: Bad proj GID: $gid_name != $proj" unless $gid_name eq $proj;
my (undef,undef,undef,undef,undef,$gid2) = stat("/groups/$proj/$group") or die;
my ($gid2_name,undef,undef,$gid2_members) = getgrgid($gid2);
# For security remove any ".." from the path and abort if we would
# leave $dir
......@@ -65,11 +84,9 @@ foreach my $d (@dirs) {
}
}
# Create the path
$file = join ('/', @res);
my $path = "$dir/$file";
error("File Doesn't Exist: $path") unless -e $path;
if (-d $path) {
my $orig_path = $path;
$path .= "/index.html" if -e "$path/index.html";
......@@ -77,10 +94,64 @@ if (-d $path) {
error("Can't index dir: $path") unless $path ne $orig_path;
}
error("File Doesn't Exist: $path") unless -e $path;
# Make sure that the path, after resolving any symbolic links,
# still resides is /proj/<pid>
# still resides is /proj/<proj> or /groups/<proj>/<group>
my $realpath = realpath $path;
error("Invalid path: $realpath") unless $realpath =~ /^$FSDIR_PROJ\/$proj/;
error("Invalid path: $realpath") unless $realpath =~ /^$FSDIR_PROJ\/$proj|^$FSDIR_GROUPS\/$proj\/$group/;
#
# Special rule for boss. Since we are bypassing authorization, don't
# show anything, just let boss know that the url is valid.
#
if ($ENV{REMOTE_ADDR} eq "@BOSSNODE_IP@") {
print "Content-Type: text/plain\n";
print "\n";
print "I exist!";
}
#
# Get session cookie and make sure user is logged in and authorized to
# view.
#
my %cookies = raw_fetch CGI::Cookie;
my $session_key = $cookies{exp_vis_session};
error("Not logged in.") unless defined $session_key;
my $user;
open F, "/var/run/exp-vis.auth" or die;
foreach (<F>) {
chop;
my ($key, $u) = split / /;
if ($key eq $session_key) {
$user = $u;
last;
}
}
error("Login Timed Out.") unless defined $user;
my (undef, undef, $uid, $user_gid) = getpwnam($user);
die if $user_gid == 0;
error("You do not have permission to view $proj files")
unless $gid == $user_gid || grep {$_ eq $user} split /\s+/, $gid_members;
error("You do not have permission to view $proj/$group files")
unless $gid2 == $user_gid || grep {$_ eq $user} split /\s+/, $gid2_members;
# OK, Now we are sure the user has permission to view this file.
# Now become a member of the GID for the proj and group and clear out
# any other GIDs
undef $!;
setgid($gid);
$) = "$gid $gid $gid2";
die $! if $!;
# Now drop privileges, using setuid to make sure the saved uid
# is also changes, ie, so that the change is permanent.
setuid($<) or die $!;
my %mime_map =
qw(html text/html htm text/html
......@@ -99,7 +170,7 @@ print "Content-Type: $mime_type\n" if defined $mime_type;
print "\n";
$/ = undef;
open F, "$path" or error "Can't open file: $path";
open F, "$path" or error "Can't read file: $path";
print <F>;
exit 0;
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2007 University of Utah and the Flux Group.
# All rights reserved.
#
use strict;
use English;
use Getopt::Std;
#
# ...
#
#
# Configure variables
#
my $TB = "@prefix@";
my $TBOPS = "@TBOPSEMAIL@";
my $USERNODE = "@USERNODE@";
#
# Load the Testbed support stuff.
#
use lib "@prefix@/lib";
use libdb;
use libtestbed;
# un-taint path
$ENV{'PATH'} = '/bin:/usr/bin:/usr/local/bin';
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
# Turn off line buffering on output
$| = 1;
# become root, needed for ssh
$< = $>;
my $db_result =
DBQueryFatal("select opskey, uid from login");
open O, "| ssh root\@$USERNODE $TB/libexec/write-vis-auth-ops";
my $prev_opskey = '';
while (my ($opskey,$uid) = $db_result->fetchrow_array) {
print O "$opskey $uid\n";
}
close O;
exit(0);
#!/bin/sh
set -e
TEMPFILE=`mktemp /var/run/exp-vis.XXXXXX`
cat > $TEMPFILE
mv $TEMPFILE /var/run/exp-vis.auth
......@@ -952,6 +952,7 @@ function DOLOGIN_MAGIC($uid, $uid_idx, $email = null, $adminon = 0)
global $TBMAIL_OPS, $TBMAIL_AUDIT, $TBMAIL_WWW;
global $WIKISUPPORT, $WIKICOOKIENAME;
global $BUGDBSUPPORT, $BUGDBCOOKIENAME, $TRACSUPPORT, $TRACCOOKIENAME;
global $TBLIBEXEC_DIR;
# Caller makes these checks too.
if (!TBvalid_uid($uid)) {
......@@ -970,10 +971,11 @@ function DOLOGIN_MAGIC($uid, $uid_idx, $email = null, $adminon = 0)
$timeout = $now + $TBAUTHTIMEOUT;
$hashkey = GENHASH();
$crc = bin2hex(mhash(MHASH_CRC32, $hashkey));
$opskey = GENHASH();
DBQueryFatal("replace into login ".
" (uid,uid_idx,hashkey,hashhash,timeout,adminon) values ".
" ('$uid', $uid_idx, '$hashkey', '$crc', '$timeout', $adminon)");
" (uid,uid_idx,hashkey,hashhash,timeout,adminon,opskey) values ".
" ('$uid', $uid_idx, '$hashkey', '$crc', '$timeout', $adminon, '$opskey')");
#
# Issue the cookie requests so that subsequent pages come back
......@@ -1062,6 +1064,10 @@ function DOLOGIN_MAGIC($uid, $uid_idx, $email = null, $adminon = 0)
" weblogin_failcount=0,weblogin_failstamp=0 ".
"where uid_idx='$uid_idx'");
# Proj-vis cookies
setcookie("exp_vis_session", $opskey, 0, "/", $TBAUTHDOMAIN, 0);
exec("$TBLIBEXEC_DIR/write-vis-auth-boss");
return 0;
}
......@@ -1095,6 +1101,7 @@ function DOLOGOUT($user) {
global $TBAUTHCOOKIE, $TBLOGINCOOKIE, $TBAUTHDOMAIN, $WWWHOST;
global $WIKISUPPORT, $WIKICOOKIENAME, $HTTP_COOKIE_VARS;
global $BUGDBSUPPORT, $BUGDBCOOKIENAME, $TRACSUPPORT, $TRACCOOKIENAME;
global $TBLIBEXEC_DIR;
if (! $CHECKLOGIN_USER)
return 1;
......@@ -1170,6 +1177,9 @@ function DOLOGOUT($user) {
setcookie($BUGDBCOOKIENAME, "", $timeout, "/", $TBAUTHDOMAIN, 0);
}
#
exec("$TBLIBEXEC_DIR/write-vis-auth-boss");
return 0;
}
......
Markdown is supported
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