Commit c414f1b9 authored by Robert Ricci's avatar Robert Ricci

Add support for loading code onto stargates by sshing into the

stargate and running uisp there.

Untested so far.

Unfortunately, tbuisp now needs to be setuid root because it has to
ssh into the stargates as root. So, take some precautions, like taint
checking and dropping root privs before running uisp locally, to
mitigate the risks.
parent d286c0cb
...@@ -52,6 +52,7 @@ post-install: ...@@ -52,6 +52,7 @@ post-install:
@$(MAKE) -C vis post-install @$(MAKE) -C vis post-install
@$(MAKE) -C www post-install @$(MAKE) -C www post-install
@$(MAKE) -C event post-install @$(MAKE) -C event post-install
@$(MAKE) -C mote post-install
# #
# For installation on the 'ops' or 'users' node (okay, plastic) # For installation on the 'ops' or 'users' node (okay, plastic)
......
...@@ -25,5 +25,7 @@ install: \ ...@@ -25,5 +25,7 @@ install: \
$(addprefix $(INSTALL_BINDIR)/, $(BIN_SCRIPTS)) $(addprefix $(INSTALL_BINDIR)/, $(BIN_SCRIPTS))
post-install: post-install:
chown root $(INSTALL_BINDIR)/tbuisp
chmod u+s $(INSTALL_BINDIR)/tbuisp
clean: clean:
#!/usr/bin/perl -w #!/usr/bin/perl -wT
# #
# EMULAB-COPYRIGHT # EMULAB-COPYRIGHT
# Copyright (c) 2004 University of Utah and the Flux Group. # Copyright (c) 2004 University of Utah and the Flux Group.
...@@ -11,18 +11,32 @@ ...@@ -11,18 +11,32 @@
use lib '@prefix@/lib'; use lib '@prefix@/lib';
my $TB = '@prefix@'; my $TB = '@prefix@';
use libdb; use libdb;
use English; use English;
use Getopt::Std; use Getopt::Std;
#
# We have to be setuid root so that we can ssh into stargates as root
#
if ($EUID != 0) {
die("*** $0:\n".
" Must be root! Maybe its a development version?\n");
}
# un-taint path
$ENV{'PATH'} = "/bin:/usr/bin:/usr/local/bin:$TB/bin";
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
use strict; use strict;
# #
# Constants # Constants
# #
my $UISP = "$TB/bin/uisp"; my $UISP = "$TB/bin/uisp";
my $DEBUG = 1; my $SGUISP = "/usr/local/bin/uisp";
my $SSHTB = "$TB/bin/sshtb";
my $DEBUG = 1;
# #
# Handle command-line arguments # Handle command-line arguments
...@@ -63,6 +77,26 @@ if (!@motes) { ...@@ -63,6 +77,26 @@ if (!@motes) {
exit usage(); exit usage();
} }
#
# Taint check the filename
#
if ($filename =~ /^([-\w\/.]+)$/) {
$filename = $1;
} else {
die("*** Tainted filename: $filename\n");
}
#
# Tait check the node names
#
@motes = map {
if (/^([-\w]+)$/) {
$1;
} else {
die("*** Tainted node name: $_\n");
}
} @motes;
# #
# Permission check # Permission check
# #
...@@ -71,10 +105,11 @@ if ($UID && !TBNodeAccessCheck($UID,TB_NODEACCESS_LOADIMAGE,@motes)) { ...@@ -71,10 +105,11 @@ if ($UID && !TBNodeAccessCheck($UID,TB_NODEACCESS_LOADIMAGE,@motes)) {
} }
# #
# Check the file to make sure it's readable # Check the file to make sure it's readable - note, we want to make sure it's
# readable by the real uid, since w'ere setuid root
# #
if ($filename) { if ($filename) {
if (!-r $filename) { if (!-R $filename) {
die "$filename not readable\n"; die "$filename not readable\n";
} }
} }
...@@ -115,6 +150,8 @@ MOTE: foreach my $mote (@motes) { ...@@ -115,6 +150,8 @@ MOTE: foreach my $mote (@motes) {
} }
my ($hosttype, $hostclass) = TBNodeType($host); my ($hosttype, $hostclass) = TBNodeType($host);
my $upload_method;
# #
# Figure out how we talk to the programming board, and what chipset it has # Figure out how we talk to the programming board, and what chipset it has
# #
...@@ -126,6 +163,24 @@ MOTE: foreach my $mote (@motes) { ...@@ -126,6 +163,24 @@ MOTE: foreach my $mote (@motes) {
push @uisp_args, "-dhost=$host"; push @uisp_args, "-dhost=$host";
# The type of programming board on a emote # The type of programming board on a emote
push @uisp_args, "-dprog=stk500"; push @uisp_args, "-dprog=stk500";
# We do the upload by running uisp directly on boss
$upload_method = "direct";
last TSWITCH;
};
/^sg/ && do {
# Stargate
# We have to ssh in to the stargate to do the programming
# The type of programming board on a stargate
push @uisp_args, "-dprog=stargate";
# We do the upload by sshing to the toe stargate and running
# uisp
$upload_method = "ssh";
last TSWITCH; last TSWITCH;
}; };
# Default # Default
...@@ -156,7 +211,12 @@ MOTE: foreach my $mote (@motes) { ...@@ -156,7 +211,12 @@ MOTE: foreach my $mote (@motes) {
my $opstring; my $opstring;
OSWITCH: for ($operation) { OSWITCH: for ($operation) {
/^upload$/ && do { /^upload$/ && do {
$opstring = "--wr_fuse_e=ff --erase --upload if=$filename"; $opstring = "--wr_fuse_e=ff --erase --upload ";
if ($upload_method eq "direct") {
$opstring .= "if=$filename";
} elsif ($upload_method eq "ssh") {
$opstring .= "if=-";
}
last OSWITCH; last OSWITCH;
}; };
...@@ -169,9 +229,30 @@ MOTE: foreach my $mote (@motes) { ...@@ -169,9 +229,30 @@ MOTE: foreach my $mote (@motes) {
# TODO - Allow for some parallelism # TODO - Allow for some parallelism
# #
print "Uploading code to $mote\n"; print "Uploading code to $mote\n";
my $commandstr = "$UISP " . join(" ",@uisp_args,$opstring); my $commandstr;
if ($upload_method eq "direct") {
#
# We're running uisp directly on this node
#
$commandstr = "$UISP " . join(" ",@uisp_args,$opstring);
# Drop root permission, no need ro it
$EUID = $UID;
} elsif ($upload_method eq "ssh") {
#
# We have to ssh into the mote host
#
$commandstr = "$SSHTB -host $host $SGUISP " .
join(" ",@uisp_args,$opstring) . " < $filename";
} else {
warn "Unsupported upload method for $mote - skipping";
$errors++;
next MOTE;
}
dprint("$commandstr\n"); dprint("$commandstr\n");
if (system($commandstr)) { if (system($commandstr)) {
$errors++;
warn "Failed to upload code to $mote";
} }
} }
......
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