1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
<?php
$work_dir = dirname(dirname(__FILE__)) . '/work/';
if (isset($_GET['r'])) {
if (base64_decode($_GET['r'],true)===false)
die('Invalid base64');
if (!isset($_GET['t']))
die('Repository type not given');
if ($_GET['t']!='git')
die('Repository type not implemented');
if (!is_dir($work_dir . 'repositories/' . $_GET['t'] . '/' . $_GET['r'])) {
$wish_list = fopen($work_dir . 'wish-list','a');
if ($wish_list === false)
die('Cannot open wish-list');
fwrite($wish_list, $_GET['t'] . " " . $_GET['r'] . "\n");
fclose($wish_list);
die('I put repository onto wish-list');
}
if (isset($_GET['tag'])) {
if (base64_decode($_GET['tag'],true)===false)
$_GET['tag'] = base64_encode($_GET['tag']);
$commit_identifier = '$(' .
'echo "' . $_GET['tag'] . '" | ' .
'base64 -d' .
')';
} elseif (isset($_GET['commit'])) {
if (!preg_match('/^[A-Fa-f0-9]{40}$/', $_GET['commit']))
die('The given commit does not have exactly 40 hex digits');
$commit_identifier = $_GET['commit'];
}
function expand_key($key) {
if (preg_match('/^[A-Fa-f0-9]{16}$/', $key))
return '.\{24\}' . $key;
elseif (preg_match('/^[A-Fa-f0-9]{40}$/', $key))
return $key;
else
die('The given key does not have exactly 16 or 40 hex digits');
}
if (isset($commit_identifier)) {
if (isset($_GET['valid_keys'])) {
$key_regex = '\(' . implode(
'\|',
array_map(
'expand_key',
explode(
',',
$_GET['valid_keys']
)
)
) . '\)';
shell_exec(
'GNUPGHOME="' . $work_dir . 'gnupg" gpg ' .
'--keyserver=hkp://keys.gnupg.net ' .
'--recv-keys ' . implode(' ',explode(',',$_GET['valid_keys']))
);
if (trim(shell_exec(
'GNUPGHOME="' . $work_dir . 'gnupg" git -C "' . $work_dir . 'repositories/' . $_GET['t'] . '/' . $_GET['r'] . '" verify-tag --raw "' . $commit_identifier . '" 2>&1 | ' .
'grep -c "\[GNUPG:\] VALIDSIG ' . $key_regex . ' "'
)) == '0')
die('Commit ' . $commit_identifier . ' is not signed by ' . $_GET['valid_keys']);
}
if (isset($_GET['p'])) {
if (base64_decode($_GET['p'],true)===false)
die('Invalid base64');
$prefix = ' --prefix="$(' .
'echo "' . $_GET['p'] . '" | ' .
'base64 -d' .
')"';
} else {
$prefix = '';
}
$handle = popen(
'git -C "../work/repositories/' . $_GET['t'] . '/' . $_GET['r'] . '" archive' . $prefix . ' "' . $commit_identifier . '" | ' .
'gzip -nc',
'r'
);
if ($handle === false)
die('Unable to create archive');
header('Content-type: application/x-gzip');
header('Content-Disposition: attachment; filename="archive.tar.gz"');
fpassthru($handle);
pclose($handle);
die();
}
die('errrm, this is not yet implemented');
}
print 'Hi, this is an <a href="https://git.eckner.net/Erich/archive-server/">archive server</a>!<br>' . "\n";
print 'I provide archives of these upstreams:<br>' . "\n";
print
implode(
"<br>\n",
array_map(
"base64_decode",
explode(
"\n",
shell_exec(
'find "' . $work_dir . 'repositories" -mindepth 2 -maxdepth 2 -printf "%f\n" | sort'
)
)
)
);
die();
|