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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
<?php
require(__DIR__ . '/.config.php');
header('Content-Type: text/plain');
if (isset($_GET['df'])) {
system("df -h --output=avail / | tail -1");
exit;
}
if ($_SERVER['REQUEST_METHOD'] != 'POST' && $_SERVER['REQUEST_METHOD'] != 'PUT') {
header('Status: 405 Method Not Allowed');
echo "You must use PUT or POST to upload a file.\n";
exit;
}
$c_t = strtolower($_SERVER['HTTP_CONTENT_TYPE'] ?? '');
if ($c_t == 'multipart/form-data' || 0 === strpos($c_t, 'multipart/form-data;')) {
$FILES = remap_files();
foreach ($FILES['file'] as $file) {
if (!is_uploaded_file($file['tmp_name'])) {
die_error("Not an uploaded file: $file[tmp_name]");
}
$hash_str = hash_file(HASH_ALGO, $file['tmp_name']);
if (FALSE === $hash_str) {
die_error("Unable to hash uploaded file?!");
}
$filename = $hash_str . get_extension($file['name']);
$filepath = UPLOAD_DIR . '/' . $filename;
$real_filepath = UPLOAD_DIR . '/' . $hash_str . '/.realfile';
if (!is_dir(UPLOAD_DIR . '/' . $hash_str)) {
if (!mkdir(UPLOAD_DIR . '/' . $hash_str)) {
die_error("Making folder $hash_str failed");
}
}
if (FALSE === move_uploaded_file($file['tmp_name'], $real_filepath)) {
die_error("Renaming uploaded file $file[tmp_name] to $real_filepath failed");
}
symlink($real_filepath, $filepath);
echo UPLOAD_URL . $filename . "\n";
send_notification("[hostfil.es] $_SERVER[REMOTE_ADDR] uploaded $file[full_path] $file[type] -> https://g.hostfil.es/$filename");
}
} else {
$in_fh = fopen('php://input', 'r');
$tmp_path = tempnam(UPLOAD_DIR, '.up-');
$out_fh = fopen($tmp_path, 'w');
if (FALSE === $out_fh) {
die_error("Couldn't open temporary file $tmp_path");
}
$hash = hash_init(HASH_ALGO);
$size = 0;
while (!feof($in_fh) && FALSE !== ($data = fread($in_fh, 1024*1024))) {
hash_update($hash, $data);
$fwrite_status = fwrite($out_fh, $data);
if (FALSE === $fwrite_status || $fwrite_status < strlen($data)) {
die_error("Outputting to temporary file $tmp_path failed");
}
$size += $fwrite_status;
}
fclose($in_fh);
if (FALSE === fclose($out_fh)) {
die_error("Closing temporary file $tmp_path failed");
}
$hash_str = hash_final($hash);
$filename = $hash_str . get_extension($_SERVER['PATH_INFO']);
$filepath = UPLOAD_DIR . '/' . $filename;
$real_filepath = UPLOAD_DIR . '/' . $hash_str . '/.realfile';
if (file_exists($real_filepath)) {
unlink($tmp_path);
} else {
if (!is_dir(UPLOAD_DIR . '/' . $hash_str)) {
if (!mkdir(UPLOAD_DIR . '/' . $hash_str)) {
die_error("Making folder $hash_str failed");
}
}
if (FALSE === rename($tmp_path, $real_filepath)) {
die_error("Renaming temporary file $tmp_path to $real_filepath failed");
}
}
symlink($real_filepath, $filepath);
echo UPLOAD_URL . $filename . "\n";
send_notification("[hostfil.es] $_SERVER[REMOTE_ADDR] uploaded $_SERVER[PATH_INFO] $c_t -> https://g.hostfil.es/$filename");
}
function send_notification($note) {
$sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_connect($sock, gethostbyname(NOTIFICATION_ADDRESS), NOTIFICATION_PORT);
socket_write($sock, $note, strlen($note));
socket_close($sock);
}
function die_error($s) {
global $tmp_path, $filepath, $size;
header('Status: 500 Server Is 💩');
echo $s;
error_log($s);
@$debug = json_encode(array('s'=>$_SERVER, 'f'=>$_FILES, 't'=>$tmp_path, 'p'=>$filepath, 'size' => $size));
send_notification("[hostfil.es] $_SERVER[REMOTE_ADDR] ! $s\n$debug");
exit;
}
function unsafe_get_extension($file) {
if ($file == '') {
return '/file';
}
$ext = strrchr($file, '/');
if (FALSE === $ext) {
return '/'.$file;
}
if ($ext == '/') {
return '/file';
}
return $ext;
}
function get_extension($file) {
$ext = unsafe_get_extension($file);
if (preg_match('@^/\\.|^[^/]@', $ext)) {
return '/file';
}
return $ext;
}
function remap_files() {
$files = array();
foreach (array_keys($_FILES) as $input_name) {
$files[$input_name] = array();
foreach (array_keys($_FILES[$input_name]) as $file_info_key) {
if (is_array($_FILES[$input_name][$file_info_key])) {
foreach ($_FILES[$input_name][$file_info_key] as $i => $v) {
if (!isset($files[$input_name][$i])) $files[$input_name][$i] = array();
$files[$input_name][$i][$file_info_key] = $v;
}
} else {
if (!isset($files[$input_name][0])) $files[$input_name][0] = array();
$files[$input_name][0][$file_info_key] = $_FILES[$input_name][$file_info_key];
}
}
}
return $files;
}
|