Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 176186
Collapse All | Expand All

(-)standard/kup-server (-20 / +121 lines)
Lines 1-4 Link Here
1
#!/usr/bin/perl -T
1
#!/usr/bin/perl
2
## -----------------------------------------------------------------------
2
## -----------------------------------------------------------------------
3
##
3
##
4
##   Copyright 2011 Intel Corporation; author: H. Peter Anvin
4
##   Copyright 2011 Intel Corporation; author: H. Peter Anvin
Lines 68-79 Link Here
68
68
69
use Digest::SHA;
69
use Digest::SHA;
70
70
71
my $VERSION = '0.3.6';
71
use lib $ENV{GL_LIBDIR};
72
72
use Gitolite::Easy;
73
# Scrub the environment completely
73
use Gitolite::Conf::Load;
74
%ENV = ('PATH' => '/bin:/usr/bin',
74
75
		'LANG' => 'C',
75
my $VERSION = '0.3.6 (gitolite integrated)';
76
		'SHELL' => '/bin/false'); # Nothing in this program should shell out
76
77
# Scrub the environment completely, except gitolite variables and HOME
78
{
79
	my %env = %ENV;
80
	%ENV = ('PATH' => '/bin:/usr/bin',
81
			'LANG' => 'C',
82
			'SHELL' => '/bin/false'); # Nothing in this program should shell out
83
	$ENV{$_} = $env{$_} for ('HOME', grep(/^GL_/, keys %env));
84
}
77
85
78
# The standard function to call on bail
86
# The standard function to call on bail
79
sub fatal($) {
87
sub fatal($) {
Lines 88-103 Link Here
88
}
96
}
89
97
90
sub my_username() {
98
sub my_username() {
91
	my $whoami = getuid();
99
	return $ENV{GL_USER};
92
	my ($name,$passwd,$uid,$gid,$quota,$comment,$gcos,$dir,$shell,$expire) = getpwuid($whoami);
93
94
	if (!defined($name) || $whoami != $uid) {
95
		# We haven't called openlog() yet so we need to do it here
96
		openlog("kup-server($whoami)", 'ndelay,pid', LOG_LOCAL5);
97
		fatal("You don't exist, go away!");
98
	}
99
100
	return (defined($name) && $whoami == $uid) ? $name : $whoami;
101
}
100
}
102
101
103
my $user_name = my_username();
102
my $user_name = my_username();
Lines 106-112 Link Here
106
105
107
106
108
# Get config values from kup-server.cfg
107
# Get config values from kup-server.cfg
109
my $cfg_file = '/etc/kup/kup-server.cfg';
108
my $cfg_file = '/var/lib/gitolite3/.gitolite/local-code/configs/kup-server.cfg';
110
109
111
my $cfg = new Config::Simple($cfg_file);
110
my $cfg = new Config::Simple($cfg_file);
112
111
Lines 371-376 Link Here
371
	return 1;
370
	return 1;
372
}
371
}
373
372
373
# kup-server may "read" files from the kup data_path, or repos.  If a repo is
374
# supplied, we assume it's a gitolite repo and check access accordingly (while
375
# remembering that kup seems to add a leading slash).  If a repo is *not*
376
# supplied, we assume we're talking about the kup data_path, which means we
377
# make gitolite access rules from the "fake" repo called "@kup-server"
378
sub read_allowed
379
{
380
	Gitolite::Common::trace( 1, 'read_allowed', @_ );
381
	my $repo = shift || '@kup-server';
382
383
	# gitolite expects a "normalised" repo name; no leading slash, no trailing ".git"
384
	$repo =~ s(^/)(); $repo =~ s/\.git$//;
385
386
	return can_read($repo);
387
}
388
389
# kup-server does not write to normal repos, it only writes to files in the
390
# kup data_path.  So we don't have to worry about any repo other than
391
# "@kup-server", which is therefore hardcoded in here.
392
sub write_allowed
393
{
394
	Gitolite::Common::trace( 1, 'write_allowed', @_ );
395
	my($path, $perm) = @_;
396
397
	# other values for perm are + (rm) and C (mkdir), analogous to gitolite's
398
	# "+ means delete or rewind branch, C means create branch"
399
	$perm ||= 'W';
400
401
	my $repo = '@kup-server';
402
403
	# the paths that gitolite expects start with "refs/heads/", since we are
404
	# simply re-using the existing ACL for this.  (But remember $path, in
405
	# kup-land, already starts with a "/".)
406
	$path = "refs/heads" . $path;
407
408
	return can_write($repo, $perm, $path) ||
409
		   can_write($repo, $perm, "$path/");
410
	# the second check is because, when specifying a permission on a directory
411
	# in gitolite, you end with a "/", say "RW+C foo/ = user".  To exercise
412
	# that right, the user runs "kup mkdir foo" or "kup rm foo".  This fails,
413
	# because the regex "foo/" won't match.  (In a *git* repo it doesn't
414
	# matter, because git doesn't allow empty directories, so it never
415
	# happens).
416
}
417
374
# Return a percentage, valid even if the denominator is zero
418
# Return a percentage, valid even if the denominator is zero
375
sub percentage($$)
419
sub percentage($$)
376
{
420
{
Lines 526-531 Link Here
526
		fatal("Invalid pathname in TAR command");
570
		fatal("Invalid pathname in TAR command");
527
	}
571
	}
528
572
573
	if (!read_allowed($tree)) {
574
		fatal("Read access denied");
575
	}
576
529
	if (!is_clean_string($prefix)) {
577
	if (!is_clean_string($prefix)) {
530
		fatal("Invalid prefix string");
578
		fatal("Invalid prefix string");
531
	}
579
	}
Lines 569-574 Link Here
569
		fatal("Invalid pathname in DIFF command");
617
		fatal("Invalid pathname in DIFF command");
570
	}
618
	}
571
619
620
	if (!read_allowed($tree)) {
621
		fatal("Read access denied");
622
	}
623
572
	if ($tree !~ /\.git$/ || ! -d $git_path.$tree ||
624
	if ($tree !~ /\.git$/ || ! -d $git_path.$tree ||
573
		! -d $git_path.$tree.'/objects') {
625
		! -d $git_path.$tree.'/objects') {
574
		fatal("No such git tree");
626
		fatal("No such git tree");
Lines 788-795 Link Here
788
		or fatal("dup error");
840
		or fatal("dup error");
789
	close($devnull);
841
	close($devnull);
790
842
843
	my $gpgvbin = '/opt/gnupg22/bin/gpgv';
844
	if ( ! -x $gpgvbin) {
845
		$gpgvbin = '/usr/bin/gpgv';
846
	}
847
791
	my $status =
848
	my $status =
792
		system('/usr/bin/gpgv',
849
		system($gpgvbin,
793
			   '--quiet',
850
			   '--quiet',
794
			   '--homedir', $tmpdir,
851
			   '--homedir', $tmpdir,
795
			   '--keyring', $pgp_path."/${user_name}.gpg",
852
			   '--keyring', $pgp_path."/${user_name}.gpg",
Lines 839-844 Link Here
839
		fatal("Invalid filename in PUT command");
896
		fatal("Invalid filename in PUT command");
840
	}
897
	}
841
898
899
	if (!write_allowed($file)) {
900
		fatal("Write access denied");
901
	}
902
842
	my @install_ext;
903
	my @install_ext;
843
	my @conflic_ext;
904
	my @conflic_ext;
844
	my $stem;
905
	my $stem;
Lines 917-922 Link Here
917
		fatal("Invalid filename in MKDIR command");
978
		fatal("Invalid filename in MKDIR command");
918
	}
979
	}
919
980
981
	if (!write_allowed($file, 'C')) {
982
		fatal("MKDIR access denied");
983
	}
984
920
	my @badext = ('.sign', keys(%zformats));
985
	my @badext = ('.sign', keys(%zformats));
921
986
922
	foreach my $e (@badext) {
987
	foreach my $e (@badext) {
Lines 991-996 Link Here
991
		fatal("Invalid filename in $cmd command");
1056
		fatal("Invalid filename in $cmd command");
992
	}
1057
	}
993
1058
1059
	if ($cmd eq 'MOVE') {
1060
		if (!write_allowed($from, '+')) {
1061
			fatal("Delete (as part of MOVE) access denied");
1062
		}
1063
	}
1064
1065
	if (!write_allowed($to)) {
1066
		fatal("Write access denied");
1067
	}
1068
994
	if ($from =~ /\.gz$/) {
1069
	if ($from =~ /\.gz$/) {
995
		if ($to !~ /\.gz$/) {
1070
		if ($to !~ /\.gz$/) {
996
			fatal("$cmd of .gz file must itself end in .gz");
1071
			fatal("$cmd of .gz file must itself end in .gz");
Lines 1093-1098 Link Here
1093
		fatal("Invalid pathname in DELETE command");
1168
		fatal("Invalid pathname in DELETE command");
1094
	}
1169
	}
1095
1170
1171
	if (!write_allowed($file, "+")) {
1172
		fatal("Delete access denied");
1173
	}
1174
1096
	if ($file !~ /\.gz$/ &&
1175
	if ($file !~ /\.gz$/ &&
1097
		has_extension($file, '.sign', keys(%zformats))) {
1176
		has_extension($file, '.sign', keys(%zformats))) {
1098
		fatal("DELETE of auxiliary files not supported");
1177
		fatal("DELETE of auxiliary files not supported");
Lines 1222-1227 Link Here
1222
1301
1223
	my($dir) = @args;
1302
	my($dir) = @args;
1224
1303
1304
	if (!read_allowed()) {
1305
		fatal("Read access denied");
1306
	}
1307
1225
	# DIR / is permitted unlike any other command
1308
	# DIR / is permitted unlike any other command
1226
	$dir =~ s:/$::g;
1309
	$dir =~ s:/$::g;
1227
	if ($dir ne '' && !is_valid_filename($dir)) {
1310
	if ($dir ne '' && !is_valid_filename($dir)) {
Lines 1261-1267 Link Here
1261
1344
1262
sub do_info()
1345
sub do_info()
1263
{
1346
{
1264
	print "kup-server $VERSION\n";
1347
	print "kup-server $VERSION\n\n";
1348
1349
	my %xlat = (
1350
		R       =>	'ls',
1351
		RW      =>	'put',
1352
		'RW+'   =>	'put/rm/mv',
1353
		'RWC'   =>	'put/mkdir',
1354
		'RW+C'  =>	'put/rm/mv/mkdir',
1355
		'-'     =>	'(denied)',
1356
	);
1357
	Gitolite::Conf::Load::load('@kup-server');
1358
	my @rules = Gitolite::Conf::Load::rules('@kup-server', $ENV{GL_USER});
1359
	for my $r (@rules) {
1360
		my ($dummy, $perm, $ref) = @$r;
1361
		$ref =~ s(^refs/heads/)();
1362
		$ref =~ s(/USER/)(/$ENV{GL_USER}/);
1363
		$ref = ($ref eq 'refs/.*') ? '/*' : '/' . $ref . '*';
1364
		printf "%-24s %s\n", ($xlat{$perm} || $perm), $ref;
1365
	}
1265
}
1366
}
1266
1367
1267
sub get_command()
1368
sub get_command()

Return to bug 176186