initial commit
This commit is contained in:
commit
584aad56b8
19 changed files with 390 additions and 0 deletions
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
example.input -text
|
||||
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/build/
|
||||
24
README
Normal file
24
README
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
nobotgate
|
||||
=========
|
||||
|
||||
When you run a private site (that still uses a
|
||||
super-serve), you can use nobotgate to require users to
|
||||
provide an http bearer token. This way, bots won't flood
|
||||
your site with spam.
|
||||
|
||||
usage
|
||||
-----
|
||||
|
||||
use nobotgate(1) together with a super-server such as inetd(8),
|
||||
tcpserver(1) or s6-tcpserver:
|
||||
# tcpserver 0.0.0.0 80 nobotgate /etc/wwwtokens ./on-valid ./on-invalid
|
||||
where /etc/wwwtokens contains:
|
||||
|
||||
and ./on-valid contains:
|
||||
#!/bin/sh
|
||||
exec busybox httpd -i -h /var/www
|
||||
and ./on-invalid contains:
|
||||
#!/bin/sh
|
||||
exec nobotgate-access cat usage
|
||||
and usage contains:
|
||||
No bearer token specified!
|
||||
39
check_token.c
Normal file
39
check_token.c
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#include <libowfat/stralloc.h>
|
||||
#include <libowfat/errmsg.h>
|
||||
#include <libowfat/open.h>
|
||||
#include <libowfat/str.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "nobotgate.h"
|
||||
|
||||
int check_token(char *tokenfile, stralloc *token)
|
||||
{
|
||||
int fd;
|
||||
char buf[4096];
|
||||
buffer b;
|
||||
int r,found;
|
||||
stralloc line;
|
||||
fd = open_read(tokenfile);
|
||||
if (fd < 0)
|
||||
diesys(errno == ENOENT ? 100 : 111, "open_read ", tokenfile);
|
||||
buffer_init_read(&b, fd, buf, sizeof(buf));
|
||||
stralloc_init(&line);
|
||||
|
||||
found = 0;
|
||||
for (;;) {
|
||||
r = buffer_getnewline_sa(&b, &line);
|
||||
if (r == 0) break;
|
||||
if (r < 0) diesys(111, "failed reading tokenfile ", tokenfile);
|
||||
stralloc_chomp(&line);
|
||||
stralloc_0(&line);
|
||||
line.s[str_chr(line.s, ' ')] = 0;
|
||||
if (stralloc_equals(token, line.s)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
buffer_close(&b);
|
||||
stralloc_free(&line);
|
||||
return found;
|
||||
}
|
||||
2
example.input
Normal file
2
example.input
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
Authorization: Bearer 1234
|
||||
|
||||
4
example.service/on-invalid
Executable file
4
example.service/on-invalid
Executable file
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
exec \
|
||||
nobotgate-access \
|
||||
cat usage
|
||||
3
example.service/on-valid
Executable file
3
example.service/on-valid
Executable file
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
exec \
|
||||
busybox httpd -i -h .
|
||||
10
example.service/run
Executable file
10
example.service/run
Executable file
|
|
@ -0,0 +1,10 @@
|
|||
#!/bin/sh
|
||||
# service that runs a web server protected with nobotgate.
|
||||
# if the user provided a valid token, it will exec into
|
||||
# ./on-valid, if not, into ./on-invalid.
|
||||
exec \
|
||||
envuidgid www \
|
||||
tcpserver -U 127.0.0.1 80 \
|
||||
../build/nobotgate ./tokens \
|
||||
./on-valid \
|
||||
./on-invalid
|
||||
2
example.service/tokens
Normal file
2
example.service/tokens
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
1234 a pretty insecure token
|
||||
11aa this token is a lot more secure
|
||||
91
example.service/trace
Normal file
91
example.service/trace
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
2783 execve("/usr/bin/envuidgid", ["envuidgid", "www", "tcpserver", "-U", "127.0.0.1", "80"], 0x7ffed7055678 /* 11 vars */) = 0
|
||||
2783 brk(NULL) = 0x558000b69000
|
||||
2783 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
|
||||
2783 openat(AT_FDCWD</home/a/src/kento2/nobotgate/example.service>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3</etc/ld.so.cache>
|
||||
2783 fstat(3</etc/ld.so.cache>, {st_mode=S_IFREG|0644, st_size=129031, ...}) = 0
|
||||
2783 mmap(NULL, 129031, PROT_READ, MAP_PRIVATE, 3</etc/ld.so.cache>, 0) = 0x7f13d3dfa000
|
||||
2783 close(3</etc/ld.so.cache>) = 0
|
||||
2783 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f13d3df8000
|
||||
2783 openat(AT_FDCWD</home/a/src/kento2/nobotgate/example.service>, "/usr/lib/libc.so.6", O_RDONLY|O_CLOEXEC) = 3</usr/lib/libc.so.6>
|
||||
2783 read(3</usr/lib/libc.so.6>, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\300\255\2\0\0\0\0\0@\0\0\0\0\0\0\08\264\301\0\0\0\0\0\0\0\0\0@\08\0\16\0@\0G\0F\0\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0\20\3\0\0\0\0\0\0\20\3\0\0\0\0\0\0\10\0\0\0\0\0\0\0\3\0\0\0\4\0\0\0\240q\32\0\0\0\0\0\240q\32\0\0\0\0\0\240q\32\0\0\0\0\0 \0\0\0\0\0\0\0 \0\0\0\0\0\0\0 \0\0\0\0\0\0\0\1\0\0\0\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\210t\2\0\0\0\0\0\210t\2\0\0\0\0\0\0\20\0\0\0\0\0\0\1\0\0\0\5\0\0\0\0\200\2\0\0\0\0\0\0\200\2\0\0\0\0\0"..., 832) = 832
|
||||
2783 pread64(3</usr/lib/libc.so.6>, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0\20\3\0\0\0\0\0\0\20\3\0\0\0\0\0\0\10\0\0\0\0\0\0\0\3\0\0\0\4\0\0\0\240q\32\0\0\0\0\0\240q\32\0\0\0\0\0\240q\32\0\0\0\0\0 \0\0\0\0\0\0\0 \0\0\0\0\0\0\0 \0\0\0\0\0\0\0\1\0\0\0\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\210t\2\0\0\0\0\0\210t\2\0\0\0\0\0\0\20\0\0\0\0\0\0\1\0\0\0\5\0\0\0\0\200\2\0\0\0\0\0\0\200\2\0\0\0\0\0\0\200\2\0\0\0\0\0\235\216\25\0\0\0\0\0\235\216\25\0\0\0\0\0\0\20\0\0\0\0\0\0\1\0\0\0\4\0\0\0\0\20\30\0\0\0\0\0\0\20\30\0\0\0\0\0\0\20\30\0\0\0\0\0"..., 784, 64) = 784
|
||||
2783 fstat(3</usr/lib/libc.so.6>, {st_mode=S_IFREG|0755, st_size=12699128, ...}) = 0
|
||||
2783 pread64(3</usr/lib/libc.so.6>, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0\20\3\0\0\0\0\0\0\20\3\0\0\0\0\0\0\10\0\0\0\0\0\0\0\3\0\0\0\4\0\0\0\240q\32\0\0\0\0\0\240q\32\0\0\0\0\0\240q\32\0\0\0\0\0 \0\0\0\0\0\0\0 \0\0\0\0\0\0\0 \0\0\0\0\0\0\0\1\0\0\0\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\210t\2\0\0\0\0\0\210t\2\0\0\0\0\0\0\20\0\0\0\0\0\0\1\0\0\0\5\0\0\0\0\200\2\0\0\0\0\0\0\200\2\0\0\0\0\0\0\200\2\0\0\0\0\0\235\216\25\0\0\0\0\0\235\216\25\0\0\0\0\0\0\20\0\0\0\0\0\0\1\0\0\0\4\0\0\0\0\20\30\0\0\0\0\0\0\20\30\0\0\0\0\0\0\20\30\0\0\0\0\0"..., 784, 64) = 784
|
||||
2783 mmap(NULL, 2006680, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3</usr/lib/libc.so.6>, 0) = 0x7f13d3c0e000
|
||||
2783 mmap(0x7f13d3c36000, 1413120, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3</usr/lib/libc.so.6>, 0x28000) = 0x7f13d3c36000
|
||||
2783 mmap(0x7f13d3d8f000, 352256, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3</usr/lib/libc.so.6>, 0x181000) = 0x7f13d3d8f000
|
||||
2783 mmap(0x7f13d3de5000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3</usr/lib/libc.so.6>, 0x1d6000) = 0x7f13d3de5000
|
||||
2783 mmap(0x7f13d3deb000, 52888, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f13d3deb000
|
||||
2783 close(3</usr/lib/libc.so.6>) = 0
|
||||
2783 mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f13d3c0b000
|
||||
2783 arch_prctl(ARCH_SET_FS, 0x7f13d3c0b740) = 0
|
||||
2783 set_tid_address(0x7f13d3c0ba10) = 2783
|
||||
2783 set_robust_list(0x7f13d3c0ba20, 24) = 0
|
||||
2783 rseq({cpu_id_start=0, cpu_id=RSEQ_CPU_ID_UNINITIALIZED, rseq_cs=NULL, flags=0, node_id=0, mm_cid=0, slice_ctrl={request=0, granted=0, __reserved=0}, __reserved=0}, 32, 0, 0x53053053) = 0
|
||||
2783 mprotect(0x7f13d3de5000, 16384, PROT_READ) = 0
|
||||
2783 mprotect(0x557fcb203000, 4096, PROT_READ) = 0
|
||||
2783 mprotect(0x7f13d3e55000, 8192, PROT_READ) = 0
|
||||
2783 prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
|
||||
2783 munmap(0x7f13d3dfa000, 129031) = 0
|
||||
2783 getrandom("\x50\xa4\x5b\x1a\x33\xa9\x65\xde", 8, GRND_NONBLOCK) = 8
|
||||
2783 brk(NULL) = 0x558000b69000
|
||||
2783 brk(0x558000b8a000) = 0x558000b8a000
|
||||
2783 socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3<UNIX-STREAM:[57002340]>
|
||||
2783 connect(3<UNIX-STREAM:[57002340]>, {sa_family=AF_UNIX, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
|
||||
2783 close(3<UNIX-STREAM:[57002340]>) = 0
|
||||
2783 socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 3<UNIX-STREAM:[57002341]>
|
||||
2783 connect(3<UNIX-STREAM:[57002341]>, {sa_family=AF_UNIX, sun_path="/var/run/nscd/socket"}, 110) = -1 ENOENT (No such file or directory)
|
||||
2783 close(3<UNIX-STREAM:[57002341]>) = 0
|
||||
2783 newfstatat(AT_FDCWD</home/a/src/kento2/nobotgate/example.service>, "/etc/nsswitch.conf", {st_mode=S_IFREG|0644, st_size=216, ...}, 0) = 0
|
||||
2783 newfstatat(AT_FDCWD</home/a/src/kento2/nobotgate/example.service>, "/", {st_mode=S_IFDIR|0755, st_size=4096, ...}, 0) = 0
|
||||
2783 openat(AT_FDCWD</home/a/src/kento2/nobotgate/example.service>, "/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 3</etc/nsswitch.conf>
|
||||
2783 fstat(3</etc/nsswitch.conf>, {st_mode=S_IFREG|0644, st_size=216, ...}) = 0
|
||||
2783 read(3</etc/nsswitch.conf>, "# /etc/nsswitch.conf\n#\n# See nsswitch.conf(5) for information.\n#\npasswd: \tfiles\ngroup: \t\tfiles\nshadow: \tfiles\n\nhosts: \t\tfiles mdns dns\nnetworks: \tfiles\n\nprotocols: \tfiles\nservices: \tfiles\nethers: \tfiles\nrpc: \t\tfiles\n", 4096) = 216
|
||||
2783 read(3</etc/nsswitch.conf>, "", 4096) = 0
|
||||
2783 fstat(3</etc/nsswitch.conf>, {st_mode=S_IFREG|0644, st_size=216, ...}) = 0
|
||||
2783 close(3</etc/nsswitch.conf>) = 0
|
||||
2783 openat(AT_FDCWD</home/a/src/kento2/nobotgate/example.service>, "/etc/passwd", O_RDONLY|O_CLOEXEC) = 3</etc/passwd>
|
||||
2783 fstat(3</etc/passwd>, {st_mode=S_IFREG|0644, st_size=5894, ...}) = 0
|
||||
2783 lseek(3</etc/passwd>, 0, SEEK_SET) = 0
|
||||
2783 read(3</etc/passwd>, "root:x:0:0:root:/root:/bedrock/cross/bin/sh\nnobody:x:99:99:Unprivileged User:/dev/null:/bedrock/cross/bin/false\nchrony:x:999:999:chrony unprivileged user:/var/lib/chrony:/bedrock/cross/bin/nologin\n_dhcpcd:x:998:998:_dhcpcd unprivileged user:/var/db/dhcpcd:"..., 4096) = 4096
|
||||
2783 read(3</etc/passwd>, "6 unprivileged user:/var/empty:/bedrock/cross/bin/nologin\nnixbld7:x:979:952:nixbld7 unprivileged user:/var/empty:/bedrock/cross/bin/nologin\nnixbld8:x:978:952:nixbld8 unprivileged user:/var/empty:/bedrock/cross/bin/nologin\nnixbld9:x:977:952:nixbld9 unprivil"..., 4096) = 1798
|
||||
2783 close(3</etc/passwd>) = 0
|
||||
2783 execve("/home/a/.local/bin/tcpserver", ["tcpserver", "-U", "127.0.0.1", "80"], 0x557fcb2047f0 /* 13 vars */) = -1 ENOENT (No such file or directory)
|
||||
2783 execve("/bedrock/cross/pin/bin/tcpserver", ["tcpserver", "-U", "127.0.0.1", "80"], 0x557fcb2047f0 /* 13 vars */) = -1 ENOENT (No such file or directory)
|
||||
2783 execve("/bedrock/bin/tcpserver", ["tcpserver", "-U", "127.0.0.1", "80"], 0x557fcb2047f0 /* 13 vars */) = -1 ENOENT (No such file or directory)
|
||||
2783 execve("/home/a/.nix-profile/bin/tcpserver", ["tcpserver", "-U", "127.0.0.1", "80"], 0x557fcb2047f0 /* 13 vars */) = -1 ENOENT (No such file or directory)
|
||||
2783 execve("/nix/var/nix/profiles/default/bin/tcpserver", ["tcpserver", "-U", "127.0.0.1", "80"], 0x557fcb2047f0 /* 13 vars */) = -1 ENOENT (No such file or directory)
|
||||
2783 execve("/usr/local/bin/tcpserver", ["tcpserver", "-U", "127.0.0.1", "80"], 0x557fcb2047f0 /* 13 vars */) = -1 ENOENT (No such file or directory)
|
||||
2783 execve("/usr/local/sbin/tcpserver", ["tcpserver", "-U", "127.0.0.1", "80"], 0x557fcb2047f0 /* 13 vars */) = -1 ENOENT (No such file or directory)
|
||||
2783 execve("/usr/bin/tcpserver", ["tcpserver", "-U", "127.0.0.1", "80"], 0x557fcb2047f0 /* 13 vars */) = 0
|
||||
2783 brk(NULL) = 0x5605f057b000
|
||||
2783 access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
|
||||
2783 openat(AT_FDCWD</home/a/src/kento2/nobotgate/example.service>, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3</etc/ld.so.cache>
|
||||
2783 fstat(3</etc/ld.so.cache>, {st_mode=S_IFREG|0644, st_size=129031, ...}) = 0
|
||||
2783 mmap(NULL, 129031, PROT_READ, MAP_PRIVATE, 3</etc/ld.so.cache>, 0) = 0x7f9752158000
|
||||
2783 close(3</etc/ld.so.cache>) = 0
|
||||
2783 mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f9752156000
|
||||
2783 openat(AT_FDCWD</home/a/src/kento2/nobotgate/example.service>, "/usr/lib/libc.so.6", O_RDONLY|O_CLOEXEC) = 3</usr/lib/libc.so.6>
|
||||
2783 read(3</usr/lib/libc.so.6>, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\300\255\2\0\0\0\0\0@\0\0\0\0\0\0\08\264\301\0\0\0\0\0\0\0\0\0@\08\0\16\0@\0G\0F\0\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0\20\3\0\0\0\0\0\0\20\3\0\0\0\0\0\0\10\0\0\0\0\0\0\0\3\0\0\0\4\0\0\0\240q\32\0\0\0\0\0\240q\32\0\0\0\0\0\240q\32\0\0\0\0\0 \0\0\0\0\0\0\0 \0\0\0\0\0\0\0 \0\0\0\0\0\0\0\1\0\0\0\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\210t\2\0\0\0\0\0\210t\2\0\0\0\0\0\0\20\0\0\0\0\0\0\1\0\0\0\5\0\0\0\0\200\2\0\0\0\0\0\0\200\2\0\0\0\0\0"..., 832) = 832
|
||||
2783 pread64(3</usr/lib/libc.so.6>, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0\20\3\0\0\0\0\0\0\20\3\0\0\0\0\0\0\10\0\0\0\0\0\0\0\3\0\0\0\4\0\0\0\240q\32\0\0\0\0\0\240q\32\0\0\0\0\0\240q\32\0\0\0\0\0 \0\0\0\0\0\0\0 \0\0\0\0\0\0\0 \0\0\0\0\0\0\0\1\0\0\0\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\210t\2\0\0\0\0\0\210t\2\0\0\0\0\0\0\20\0\0\0\0\0\0\1\0\0\0\5\0\0\0\0\200\2\0\0\0\0\0\0\200\2\0\0\0\0\0\0\200\2\0\0\0\0\0\235\216\25\0\0\0\0\0\235\216\25\0\0\0\0\0\0\20\0\0\0\0\0\0\1\0\0\0\4\0\0\0\0\20\30\0\0\0\0\0\0\20\30\0\0\0\0\0\0\20\30\0\0\0\0\0"..., 784, 64) = 784
|
||||
2783 fstat(3</usr/lib/libc.so.6>, {st_mode=S_IFREG|0755, st_size=12699128, ...}) = 0
|
||||
2783 pread64(3</usr/lib/libc.so.6>, "\6\0\0\0\4\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0@\0\0\0\0\0\0\0\20\3\0\0\0\0\0\0\20\3\0\0\0\0\0\0\10\0\0\0\0\0\0\0\3\0\0\0\4\0\0\0\240q\32\0\0\0\0\0\240q\32\0\0\0\0\0\240q\32\0\0\0\0\0 \0\0\0\0\0\0\0 \0\0\0\0\0\0\0 \0\0\0\0\0\0\0\1\0\0\0\4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\210t\2\0\0\0\0\0\210t\2\0\0\0\0\0\0\20\0\0\0\0\0\0\1\0\0\0\5\0\0\0\0\200\2\0\0\0\0\0\0\200\2\0\0\0\0\0\0\200\2\0\0\0\0\0\235\216\25\0\0\0\0\0\235\216\25\0\0\0\0\0\0\20\0\0\0\0\0\0\1\0\0\0\4\0\0\0\0\20\30\0\0\0\0\0\0\20\30\0\0\0\0\0\0\20\30\0\0\0\0\0"..., 784, 64) = 784
|
||||
2783 mmap(NULL, 2006680, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, 3</usr/lib/libc.so.6>, 0) = 0x7f9751f6c000
|
||||
2783 mmap(0x7f9751f94000, 1413120, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3</usr/lib/libc.so.6>, 0x28000) = 0x7f9751f94000
|
||||
2783 mmap(0x7f97520ed000, 352256, PROT_READ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3</usr/lib/libc.so.6>, 0x181000) = 0x7f97520ed000
|
||||
2783 mmap(0x7f9752143000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3</usr/lib/libc.so.6>, 0x1d6000) = 0x7f9752143000
|
||||
2783 mmap(0x7f9752149000, 52888, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f9752149000
|
||||
2783 close(3</usr/lib/libc.so.6>) = 0
|
||||
2783 mmap(NULL, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f9751f69000
|
||||
2783 arch_prctl(ARCH_SET_FS, 0x7f9751f69740) = 0
|
||||
2783 set_tid_address(0x7f9751f69a10) = 2783
|
||||
2783 set_robust_list(0x7f9751f69a20, 24) = 0
|
||||
2783 rseq({cpu_id_start=0, cpu_id=RSEQ_CPU_ID_UNINITIALIZED, rseq_cs=NULL, flags=0, node_id=0, mm_cid=0, slice_ctrl={request=0, granted=0, __reserved=0}, __reserved=0}, 32, 0, 0x53053053) = 0
|
||||
2783 mprotect(0x7f9752143000, 16384, PROT_READ) = 0
|
||||
2783 mprotect(0x5605de88f000, 4096, PROT_READ) = 0
|
||||
2783 mprotect(0x7f97521b3000, 8192, PROT_READ) = 0
|
||||
2783 prlimit64(0, RLIMIT_STACK, NULL, {rlim_cur=8192*1024, rlim_max=RLIM64_INFINITY}) = 0
|
||||
2783 munmap(0x7f9752158000, 129031) = 0
|
||||
2783 write(2</dev/pts/1<char 136:1>>, "tcpserver: usage: tcpserver [ -461UXpPhHrRoOdDqQv ] [ -c limit ] [ -x rules.cdb ] [ -B banner ] [ -g gid ] [ -u uid ] [ -b backlog ] [ -l localname ] [ -t timeout ] [ -I interface ] host port program\n", 200) = 200
|
||||
2783 exit_group(100) = ?
|
||||
2783 +++ exited with 100 +++
|
||||
1
example.service/usage
Normal file
1
example.service/usage
Normal file
|
|
@ -0,0 +1 @@
|
|||
curl -H 'Authorization: Bearer <your token>' http://localhost:80
|
||||
28
meson.build
Normal file
28
meson.build
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
project(
|
||||
'nobotgate', 'c',
|
||||
default_options: [
|
||||
'c_std=c99',
|
||||
'warning_level=2',
|
||||
],
|
||||
)
|
||||
|
||||
cc = meson.get_compiler('c')
|
||||
deps = [
|
||||
cc.find_library('libowfat'),
|
||||
]
|
||||
|
||||
add_project_arguments(
|
||||
'-DPATH_TMP="'+get_option('path_tmp')+'"',
|
||||
language: 'c',
|
||||
)
|
||||
|
||||
executable('nobotgate', files(
|
||||
'./nobotgate.c',
|
||||
'./parse_token.c',
|
||||
'./check_token.c',
|
||||
'./send_headers.c',
|
||||
), dependencies:deps, install:true)
|
||||
|
||||
executable('nobotgate-access', files(
|
||||
'./nobotgate-access.c',
|
||||
), dependencies:deps, install:true)
|
||||
6
meson.options
Normal file
6
meson.options
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
option(
|
||||
'path_tmp',
|
||||
type : 'string',
|
||||
value : '/tmp',
|
||||
description : 'path to tmpfs',
|
||||
)
|
||||
36
nobotgate-access.c
Normal file
36
nobotgate-access.c
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#include <libowfat/buffer.h>
|
||||
#include <libowfat/errmsg.h>
|
||||
#include <libowfat/str.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define dieusage() die(100, argv0, " PROG ARGS");
|
||||
|
||||
static void consume_headers(void) {
|
||||
char buf[2048];
|
||||
int r;
|
||||
for (;;) {
|
||||
r=buffer_getline(buffer_0, buf, sizeof buf);
|
||||
if (r==0) die(100,"EOF before header end");
|
||||
if (buf[0]=='\r')
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
char *header;
|
||||
(void)argc;
|
||||
errmsg_iam(*argv);
|
||||
|
||||
if (argc<2) dieusage();
|
||||
|
||||
consume_headers();
|
||||
|
||||
header = "HTTP/1.0 200 OK\r\n"
|
||||
"Connection: close\r\n"
|
||||
"\r\n";
|
||||
if (write(1, header, str_len(header)) < 0)
|
||||
diesys(111, "write to stdout");
|
||||
execvp(argv[1], argv+1);
|
||||
diesys(111, "exec ", argv[1]);
|
||||
}
|
||||
57
nobotgate.c
Normal file
57
nobotgate.c
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
#define _XOPEN_SOURCE 700
|
||||
#include <libowfat/buffer.h>
|
||||
#include <libowfat/errmsg.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "nobotgate.h"
|
||||
|
||||
#define dieusage() die(100,"usage: ",argv0," tokenfile allowed-handler denied-handler")
|
||||
|
||||
static stralloc token;
|
||||
static char *tokenfile, *cmd_valid, *cmd_invalid;
|
||||
|
||||
static void run(void) {
|
||||
char tmp[] = PATH_TMP"/nobotgate.XXXXXX";
|
||||
int tmpfd;
|
||||
char buf[8192];
|
||||
buffer b;
|
||||
char *cmd;
|
||||
tmpfd = mkstemp(tmp);
|
||||
|
||||
buffer_init_write(&b,tmpfd,buf,sizeof buf);
|
||||
if (!send_headers(buffer_0, &b))
|
||||
die(111,"copy stdin to temporary file");
|
||||
|
||||
lseek(tmpfd,0,SEEK_SET);
|
||||
buffer_init_read(&b,tmpfd,buf,sizeof buf);
|
||||
if (!parse_token(&b,&token)) {
|
||||
carp("failed to parse token");
|
||||
goto err;
|
||||
}
|
||||
|
||||
cmd=check_token(tokenfile,&token)
|
||||
? cmd_valid
|
||||
: cmd_invalid;
|
||||
lseek(tmpfd,0,SEEK_SET);
|
||||
dup2(tmpfd,0);
|
||||
unlink(tmp);
|
||||
buffer_close(&b);
|
||||
stralloc_free(&token);
|
||||
carp("execing ",cmd);
|
||||
execlp(cmd,cmd,NULL);
|
||||
err:
|
||||
unlink(tmp);
|
||||
exit(111);
|
||||
}
|
||||
|
||||
int main(int argc,char **argv)
|
||||
{
|
||||
errmsg_iam(*argv);
|
||||
argv++; argc--;
|
||||
if (argc != 3) dieusage();
|
||||
tokenfile=argv[0];
|
||||
cmd_valid=argv[1];
|
||||
cmd_invalid=argv[2];
|
||||
run();
|
||||
}
|
||||
19
nobotgate.h
Normal file
19
nobotgate.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef NOBOTGATE
|
||||
#define NOBOTGATE
|
||||
|
||||
#include <libowfat/buffer.h>
|
||||
#include <libowfat/stralloc.h>
|
||||
|
||||
/* buffer shall stream an http request.
|
||||
* it stores the found bearer token to result or
|
||||
* returns 0 if none is found.
|
||||
* always succeeds. */
|
||||
int parse_token(buffer *b, stralloc *result);
|
||||
|
||||
/* return: 1 if the token is valid(i.e. in tokenfile),
|
||||
* 0 else */
|
||||
int check_token(char *tokenfile, stralloc *token);
|
||||
|
||||
int send_headers(buffer *from, buffer *to);
|
||||
|
||||
#endif
|
||||
34
parse_token.c
Normal file
34
parse_token.c
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
#include <libowfat/stralloc.h>
|
||||
#include <libowfat/buffer.h>
|
||||
#include <libowfat/errmsg.h>
|
||||
#include <libowfat/str.h>
|
||||
|
||||
#define AUTH_HEADER "Authorization: Bearer "
|
||||
#define AUTH_HEADER_LEN str_len(AUTH_HEADER)
|
||||
|
||||
// TODO make case insensitive according to https://www.rfc-editor.org/info/rfc7230/#section-3.2
|
||||
int parse_token(buffer *b, stralloc *result)
|
||||
{
|
||||
stralloc line;
|
||||
int r;
|
||||
stralloc_init(result);
|
||||
for (;;) {
|
||||
r=buffer_getnewline_sa(b,&line);
|
||||
if (r==0) break;
|
||||
if (r<0) { carpsys("read line"); goto err; }
|
||||
|
||||
if (stralloc_starts(&line,AUTH_HEADER)) {
|
||||
stralloc_chomp(&line);
|
||||
if (!stralloc_copyb(result, line.s+AUTH_HEADER_LEN,
|
||||
line.len-AUTH_HEADER_LEN)
|
||||
) { carpsys("out of memory"); goto err; }
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
stralloc_free(&line);
|
||||
return 1;
|
||||
err:
|
||||
stralloc_free(&line);
|
||||
return 0;
|
||||
}
|
||||
27
send_headers.c
Normal file
27
send_headers.c
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#include <unistd.h>
|
||||
#include <libowfat/errmsg.h>
|
||||
|
||||
#include "nobotgate.h"
|
||||
|
||||
int send_headers(buffer *from, buffer *to)
|
||||
{
|
||||
char buf[8192];
|
||||
int nread;
|
||||
for (;;) {
|
||||
nread=buffer_getline(from,buf,sizeof buf);
|
||||
if (nread==0) { carp("EOF before header end"); return 0; }
|
||||
if (nread<0) { carpsys("failed reading"); return 0; }
|
||||
/* include \n */
|
||||
nread++;
|
||||
|
||||
if (buffer_put(to,buf,nread)<0) return 0;
|
||||
if (buf[0]=='\r')
|
||||
break;
|
||||
}
|
||||
|
||||
if (buffer_flush(to)<0) {
|
||||
carpsys("buffer flush");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
5
tool/debug
Executable file
5
tool/debug
Executable file
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/sh
|
||||
set -eux
|
||||
gdb \
|
||||
-ex 'set args ./example.service/tokens ./example.service/on-valid ./example.service/on-invalid < ./example.input' \
|
||||
./build/nobotgate
|
||||
Loading…
Add table
Add a link
Reference in a new issue