SMOLNET PORTAL home about changes
bitreich-httpd.c - bitreich-httpd - Bitreich HTTPD service
(URL) git clone git://bitreich.org/bitreich-httpd git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/bitreich-httpd (git://bitreich.org)
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) Tags
(DIR) README
(DIR) LICENSE
---
bitreich-httpd.c (6666B)
---
1 /*
2 * Copy me if you can.
3 * by 20h
4 */
5
6 #include <unistd.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <time.h>
10 #include <sys/types.h>
11 #include <sys/stat.h>
12 #include <fcntl.h>
13 #include <string.h>
14 #include <strings.h>
15 #include <sys/socket.h>
16 #include <sys/wait.h>
17 #include <netdb.h>
18 #include <time.h>
19
20 void *
21 xmalloc(size_t size)
22 {
23 void *p;
24
25 if (!(p = malloc(size))) {
26 perror("malloc");
27 exit(1);
28 }
29
30 return p;
31 }
32
33 void
34 print404(void)
35 {
36 printf("HTTP/1.1 404 Google Broke The Web\r\n");
37 printf("\r\n");
38 }
39
40 void
41 printheaders(char *ctype)
42 {
43 time_t t;
44
45 t = time(NULL);
46 if (t > 0)
47 printf("Date: %s", asctime(gmtime(&t)));
48 printf("X-Future: Gopher ftw!\r\n");
49 printf("Content-Type: %s\r\n", ctype);
50 printf("X-Irritate: Be irritated.\r\n");
51 printf("X-Use-Gopher: gopher://bitreich.org\r\n");
52 printf("If-By-Whiskey: Terrorist\r\n");
53 printf("Permission-Policy: interest-cohort=()\r\n");
54 printf("Fuck-Off: Google\r\n");
55 printf("Server: bitreich-httpd/2.0\r\n");
56 printf("X-Alarm: <script>window.alert(\"Turn off Javascript, it hurts me.\");</script>\r\n");
57 printf("X-Goat-0: (_(\r\n");
58 printf("X-Goat-1: /_/'_____/)\r\n");
59 printf("X-Goat-2: \" | |\r\n");
60 printf("X-Goat-3: |\"\"\"\"\"\"| \r\n");
61 printf("Host: bitreich.org\r\n");
62 printf("Connection: close\r\n");
63 }
64
65 int
66 servefile(char *path, char *ctype, int sock)
67 {
68 struct stat st;
69 char *sendb, *sendi;
70 size_t bufsiz = BUFSIZ;
71 int len, sent, fd;
72
73 fd = open(path, O_RDONLY);
74 if (fd < 0) {
75 print404();
76 return 1;
77 }
78
79 printf("HTTP/1.1 200 OK\r\n");
80 printheaders(ctype);
81
82 if (fstat(fd, &st) >= 0)
83 if ((bufsiz = st.st_blksize) < BUFSIZ)
84 bufsiz = BUFSIZ;
85
86 printf("Content-Length: %ld\r\n", st.st_size);
87 printf("\r\n");
88 fflush(stdout);
89
90 sendb = xmalloc(bufsiz);
91 while ((len = read(fd, sendb, bufsiz)) > 0) {
92 sendi = sendb;
93 while (len > 0) {
94 if ((sent = write(sock, sendi, len)) < 0) {
95 free(sendb);
96 return 1;
97 }
98 len -= sent;
99 sendi += sent;
100 }
101 }
102 free(sendb);
103
104 return 0;
105 }
106
107 char *
108 read_line(int fd, int *len, int maxread)
109 {
110 char *buf;
111 int r, rbytes;
112
113 buf = xmalloc(maxread+1);
114 memset(buf, 0, maxread+1);
115
116 rbytes = 0;
117 while (rbytes < maxread) {
118 r = read(fd, &buf[rbytes], 1);
119 if (r < 0) {
120 free(buf);
121 return NULL;
122 }
123 if (r == 0)
124 break;
125 if (buf[rbytes] == '\n') {
126 buf[rbytes] = '\0';
127 break;
128 }
129 rbytes += r;
130 }
131
132 *len = rbytes;
133 return buf;
134 }
135
136 int
137 main(int argc, char *argv[])
138 {
139 char *wwwbase, *wwwindex, *request, *ctype, *path, *le_file,
140 *le_base, clienth[NI_MAXHOST], clientp[NI_MAXSERV], *zuccbase,
141 *requested, *header, *headerval, *hosthdr;
142 int rlen, i, user_agent_script_pid;
143 struct sockaddr_storage clt;
144 socklen_t cltlen = sizeof(clt);
145 time_t tim;
146
147 hosthdr = NULL;
148 user_agent_script_pid = -1;
149
150 wwwbase = "/bitreich/www";
151 wwwindex = "index.html";
152
153 le_base = "/br/www/uacme";
154 zuccbase = "/br/www/zuccless";
155
156 if (!getpeername(0, (struct sockaddr *)&clt, &cltlen)) {
157 if (getnameinfo((struct sockaddr *)&clt, cltlen, clienth,
158 sizeof(clienth), clientp, sizeof(clientp),
159 NI_NUMERICHOST|NI_NUMERICSERV)) {
160 clienth[0] = clientp[0] = '\0';
161 }
162 if (!strncmp(clienth, "::ffff:", 7))
163 memmove(clienth, clienth+7, strlen(clienth)-6);
164 } else {
165 clienth[0] = clientp[0] = '\0';
166 }
167
168 request = read_line(0, &rlen, 512);
169 if (request == NULL)
170 return 1;
171 if (request[rlen-1] == '\r')
172 request[rlen-1] = '\0';
173
174 /* Header parsing. */
175 /* At max read 16 headers. Do not allow DDoS. */
176 for (i = 0; i < 16; i++) {
177 header = read_line(0, &rlen, 512);
178 if (header == NULL || rlen == 0)
179 break;
180 if (header[rlen-1] == '\r') {
181 header[rlen-1] = '\0';
182 if (rlen == 1) {
183 free(header);
184 break;
185 }
186 }
187 headerval = strchr(header, ':');
188 if (headerval == NULL) {
189 free(header);
190 continue;
191 }
192 *headerval = '\0';
193 headerval += 2;
194 if (headerval > (header + rlen)) {
195 free(header);
196 continue;
197 }
198 if (!strcasecmp(header, "user-agent")) {
199 user_agent_script_pid = fork();
200 switch (user_agent_script_pid) {
201 case -1:
202 perror("fork");
203 return 1;
204 case 0:
205 return execl("add-user-agent.sh",
206 "/home/annna/bin/modules/http-user-agent/add-user-agent.sh",
207 headerval, 0);
208 }
209 }
210 if (!strcasecmp(header, "host")) {
211 rlen = strlen(headerval);
212 hosthdr = xmalloc(rlen+1);
213 memset(hosthdr, 0, rlen+1);
214 strncpy(hosthdr, headerval, rlen);
215 }
216 free(header);
217 }
218
219 if (strncmp(request, "GET ", 4))
220 return 1;
221
222 if (strstr(request, "s/bitreich.sh")) {
223 asprintf(&path, "%s/s/bitreich.sh", wwwbase);
224 ctype = "text/plain";
225 } else if (strstr(request, "favicon.gif")) {
226 asprintf(&path, "%s/s/favicon.gif", wwwbase);
227 ctype = "image/gif";
228 } else if (strstr(request, "deep-thinker.gif")) {
229 asprintf(&path, "%s/s/deep-thinker.gif", wwwbase);
230 ctype = "image/gif";
231 } else if (strstr(request, "startup.mp3")) {
232 asprintf(&path, "%s/s/startup.mp3", wwwbase);
233 ctype = "audio/mpeg";
234 } else if (strstr(request, "padme-hum.mp3")) {
235 asprintf(&path, "%s/s/padme-hum.mp3", wwwbase);
236 ctype = "audio/mpeg";
237 } else if (strstr(request, "dickbutt")) {
238 asprintf(&path,
239 "/home/annna/bin/locate-cake-hater \"%s\" \"%s\"",
240 clienth, clientp);
241 system(path);
242 free(path);
243 asprintf(&path, "%s/s/dickbutt.jpg", wwwbase);
244 ctype = "image/jpeg";
245 } else if (strstr(request, "bitreich.css")) {
246 asprintf(&path, "%s/s/bitreich.css", wwwbase);
247 ctype = "text/css";
248 } else if (strstr(request, "yolo-css-")) {
249 /* We hate CSS in here. */
250 sleep(1);
251 asprintf(&path, "%s/s/yolo-css.css", wwwbase);
252 ctype = "text/css";
253 } else if ((le_file = strstr(request, ".well-known/acme-challenge/"))) {
254 /* Setup for Letsencrypt */
255 le_file += strlen(".well-known/acme-challenge/");
256 requested = strtok(le_file, " ");
257 if (strchr(requested, '/') != NULL) {
258 /* Get Zucced, no path exploitation. */
259 asprintf(&path, "%s/zucc-job.webm", zuccbase);
260 ctype = "video/webm";
261 } else {
262 /* Seems legit. */
263 asprintf(&path, "%s/%s", le_base, requested);
264 ctype = "text/plain";
265 }
266 } else {
267 if (strstr(hosthdr, "zuccless.org")) {
268 tim = time(NULL);
269 srandom(tim);
270 wwwbase = zuccbase;
271 switch (random() % 3) {
272 case 0:
273 asprintf(&path, "%s/zucc-job.webm", zuccbase);
274 break;
275 default:
276 asprintf(&path, "%s/zucc-meat.webm", zuccbase);
277 break;
278 }
279 ctype = "video/webm";
280 } else {
281 asprintf(&path, "%s/%s", wwwbase, wwwindex);
282 ctype = "text/html";
283 }
284 }
285 if (hosthdr != NULL)
286 free(hosthdr);
287 free(request);
288
289 rlen = servefile(path, ctype, 1);
290 free(path);
291
292 if (user_agent_script_pid != -1) {
293 if (waitpid(user_agent_script_pid, NULL, 0) < 0) {
294 perror("waitpid");
295 return 1;
296 }
297 }
298
299 return rlen;
300 }
301
Response: application/gopher-menu
Original URLgopher://bitreich.org/1/scm/bitreich-httpd/file/bitreich-...
Content-Typeapplication/gopher-menu; charset=utf-8