mirror of
https://github.com/gentoo-mirror/gentoo.git
synced 2026-08-24 18:58:08 -07:00
243 lines
6.4 KiB
Diff
243 lines
6.4 KiB
Diff
Upstream kup provided this patch, that was apparently written by the Gitolite
|
|
author.
|
|
|
|
--- standard/kup-server 2017-03-28 13:01:24.000000000 -0400
|
|
+++ gitolite/kup-server 2018-03-26 15:01:20.000000000 -0400
|
|
@@ -1,4 +1,4 @@
|
|
-#!/usr/bin/perl -T
|
|
+#!/usr/bin/perl
|
|
## -----------------------------------------------------------------------
|
|
##
|
|
## Copyright 2011 Intel Corporation; author: H. Peter Anvin
|
|
@@ -68,12 +68,20 @@
|
|
|
|
use Digest::SHA;
|
|
|
|
-my $VERSION = '0.3.6';
|
|
-
|
|
-# Scrub the environment completely
|
|
-%ENV = ('PATH' => '/bin:/usr/bin',
|
|
- 'LANG' => 'C',
|
|
- 'SHELL' => '/bin/false'); # Nothing in this program should shell out
|
|
+use lib $ENV{GL_LIBDIR};
|
|
+use Gitolite::Easy;
|
|
+use Gitolite::Conf::Load;
|
|
+
|
|
+my $VERSION = '0.3.6 (gitolite integrated)';
|
|
+
|
|
+# Scrub the environment completely, except gitolite variables and HOME
|
|
+{
|
|
+ my %env = %ENV;
|
|
+ %ENV = ('PATH' => '/bin:/usr/bin',
|
|
+ 'LANG' => 'C',
|
|
+ 'SHELL' => '/bin/false'); # Nothing in this program should shell out
|
|
+ $ENV{$_} = $env{$_} for ('HOME', grep(/^GL_/, keys %env));
|
|
+}
|
|
|
|
# The standard function to call on bail
|
|
sub fatal($) {
|
|
@@ -88,16 +96,7 @@
|
|
}
|
|
|
|
sub my_username() {
|
|
- my $whoami = getuid();
|
|
- my ($name,$passwd,$uid,$gid,$quota,$comment,$gcos,$dir,$shell,$expire) = getpwuid($whoami);
|
|
-
|
|
- if (!defined($name) || $whoami != $uid) {
|
|
- # We haven't called openlog() yet so we need to do it here
|
|
- openlog("kup-server($whoami)", 'ndelay,pid', LOG_LOCAL5);
|
|
- fatal("You don't exist, go away!");
|
|
- }
|
|
-
|
|
- return (defined($name) && $whoami == $uid) ? $name : $whoami;
|
|
+ return $ENV{GL_USER};
|
|
}
|
|
|
|
my $user_name = my_username();
|
|
@@ -106,7 +105,7 @@
|
|
|
|
|
|
# Get config values from kup-server.cfg
|
|
-my $cfg_file = '/etc/kup/kup-server.cfg';
|
|
+my $cfg_file = '/etc/kup/kup-server.cfg';
|
|
|
|
my $cfg = new Config::Simple($cfg_file);
|
|
|
|
@@ -371,6 +370,51 @@
|
|
return 1;
|
|
}
|
|
|
|
+# kup-server may "read" files from the kup data_path, or repos. If a repo is
|
|
+# supplied, we assume it's a gitolite repo and check access accordingly (while
|
|
+# remembering that kup seems to add a leading slash). If a repo is *not*
|
|
+# supplied, we assume we're talking about the kup data_path, which means we
|
|
+# make gitolite access rules from the "fake" repo called "@kup-server"
|
|
+sub read_allowed
|
|
+{
|
|
+ Gitolite::Common::trace( 1, 'read_allowed', @_ );
|
|
+ my $repo = shift || '@kup-server';
|
|
+
|
|
+ # gitolite expects a "normalised" repo name; no leading slash, no trailing ".git"
|
|
+ $repo =~ s(^/)(); $repo =~ s/\.git$//;
|
|
+
|
|
+ return can_read($repo);
|
|
+}
|
|
+
|
|
+# kup-server does not write to normal repos, it only writes to files in the
|
|
+# kup data_path. So we don't have to worry about any repo other than
|
|
+# "@kup-server", which is therefore hardcoded in here.
|
|
+sub write_allowed
|
|
+{
|
|
+ Gitolite::Common::trace( 1, 'write_allowed', @_ );
|
|
+ my($path, $perm) = @_;
|
|
+
|
|
+ # other values for perm are + (rm) and C (mkdir), analogous to gitolite's
|
|
+ # "+ means delete or rewind branch, C means create branch"
|
|
+ $perm ||= 'W';
|
|
+
|
|
+ my $repo = '@kup-server';
|
|
+
|
|
+ # the paths that gitolite expects start with "refs/heads/", since we are
|
|
+ # simply re-using the existing ACL for this. (But remember $path, in
|
|
+ # kup-land, already starts with a "/".)
|
|
+ $path = "refs/heads" . $path;
|
|
+
|
|
+ return can_write($repo, $perm, $path) ||
|
|
+ can_write($repo, $perm, "$path/");
|
|
+ # the second check is because, when specifying a permission on a directory
|
|
+ # in gitolite, you end with a "/", say "RW+C foo/ = user". To exercise
|
|
+ # that right, the user runs "kup mkdir foo" or "kup rm foo". This fails,
|
|
+ # because the regex "foo/" won't match. (In a *git* repo it doesn't
|
|
+ # matter, because git doesn't allow empty directories, so it never
|
|
+ # happens).
|
|
+}
|
|
+
|
|
# Return a percentage, valid even if the denominator is zero
|
|
sub percentage($$)
|
|
{
|
|
@@ -526,6 +570,10 @@
|
|
fatal("Invalid pathname in TAR command");
|
|
}
|
|
|
|
+ if (!read_allowed($tree)) {
|
|
+ fatal("Read access denied");
|
|
+ }
|
|
+
|
|
if (!is_clean_string($prefix)) {
|
|
fatal("Invalid prefix string");
|
|
}
|
|
@@ -569,6 +617,10 @@
|
|
fatal("Invalid pathname in DIFF command");
|
|
}
|
|
|
|
+ if (!read_allowed($tree)) {
|
|
+ fatal("Read access denied");
|
|
+ }
|
|
+
|
|
if ($tree !~ /\.git$/ || ! -d $git_path.$tree ||
|
|
! -d $git_path.$tree.'/objects') {
|
|
fatal("No such git tree");
|
|
@@ -788,8 +840,13 @@
|
|
or fatal("dup error");
|
|
close($devnull);
|
|
|
|
+ my $gpgvbin = '/opt/gnupg22/bin/gpgv';
|
|
+ if ( ! -x $gpgvbin) {
|
|
+ $gpgvbin = '/usr/bin/gpgv';
|
|
+ }
|
|
+
|
|
my $status =
|
|
- system('/usr/bin/gpgv',
|
|
+ system($gpgvbin,
|
|
'--quiet',
|
|
'--homedir', $tmpdir,
|
|
'--keyring', $pgp_path."/${user_name}.gpg",
|
|
@@ -839,6 +896,10 @@
|
|
fatal("Invalid filename in PUT command");
|
|
}
|
|
|
|
+ if (!write_allowed($file)) {
|
|
+ fatal("Write access denied");
|
|
+ }
|
|
+
|
|
my @install_ext;
|
|
my @conflic_ext;
|
|
my $stem;
|
|
@@ -917,6 +978,10 @@
|
|
fatal("Invalid filename in MKDIR command");
|
|
}
|
|
|
|
+ if (!write_allowed($file, 'C')) {
|
|
+ fatal("MKDIR access denied");
|
|
+ }
|
|
+
|
|
my @badext = ('.sign', keys(%zformats));
|
|
|
|
foreach my $e (@badext) {
|
|
@@ -991,6 +1056,16 @@
|
|
fatal("Invalid filename in $cmd command");
|
|
}
|
|
|
|
+ if ($cmd eq 'MOVE') {
|
|
+ if (!write_allowed($from, '+')) {
|
|
+ fatal("Delete (as part of MOVE) access denied");
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (!write_allowed($to)) {
|
|
+ fatal("Write access denied");
|
|
+ }
|
|
+
|
|
if ($from =~ /\.gz$/) {
|
|
if ($to !~ /\.gz$/) {
|
|
fatal("$cmd of .gz file must itself end in .gz");
|
|
@@ -1093,6 +1168,10 @@
|
|
fatal("Invalid pathname in DELETE command");
|
|
}
|
|
|
|
+ if (!write_allowed($file, "+")) {
|
|
+ fatal("Delete access denied");
|
|
+ }
|
|
+
|
|
if ($file !~ /\.gz$/ &&
|
|
has_extension($file, '.sign', keys(%zformats))) {
|
|
fatal("DELETE of auxiliary files not supported");
|
|
@@ -1222,6 +1301,10 @@
|
|
|
|
my($dir) = @args;
|
|
|
|
+ if (!read_allowed()) {
|
|
+ fatal("Read access denied");
|
|
+ }
|
|
+
|
|
# DIR / is permitted unlike any other command
|
|
$dir =~ s:/$::g;
|
|
if ($dir ne '' && !is_valid_filename($dir)) {
|
|
@@ -1261,7 +1344,25 @@
|
|
|
|
sub do_info()
|
|
{
|
|
- print "kup-server $VERSION\n";
|
|
+ print "kup-server $VERSION\n\n";
|
|
+
|
|
+ my %xlat = (
|
|
+ R => 'ls',
|
|
+ RW => 'put',
|
|
+ 'RW+' => 'put/rm/mv',
|
|
+ 'RWC' => 'put/mkdir',
|
|
+ 'RW+C' => 'put/rm/mv/mkdir',
|
|
+ '-' => '(denied)',
|
|
+ );
|
|
+ Gitolite::Conf::Load::load('@kup-server');
|
|
+ my @rules = Gitolite::Conf::Load::rules('@kup-server', $ENV{GL_USER});
|
|
+ for my $r (@rules) {
|
|
+ my ($dummy, $perm, $ref) = @$r;
|
|
+ $ref =~ s(^refs/heads/)();
|
|
+ $ref =~ s(/USER/)(/$ENV{GL_USER}/);
|
|
+ $ref = ($ref eq 'refs/.*') ? '/*' : '/' . $ref . '*';
|
|
+ printf "%-24s %s\n", ($xlat{$perm} || $perm), $ref;
|
|
+ }
|
|
}
|
|
|
|
sub get_command()
|