aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--Makefile2
-rw-r--r--README.md15
-rw-r--r--vexnc.c81
4 files changed, 96 insertions, 4 deletions
diff --git a/.gitignore b/.gitignore
index 81c4d8b..8009b21 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
vexnc
compile_commands.json
+logs/
+.cache/
diff --git a/Makefile b/Makefile
index c699ac2..6bca4df 100644
--- a/Makefile
+++ b/Makefile
@@ -4,4 +4,4 @@ vexnc: vexnc.c
$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $^ $(LDFLAGS) $(LIBS)
clean:
- rm vexnc \ No newline at end of file
+ rm vexnc
diff --git a/README.md b/README.md
index a83ecd0..0e54d2d 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,15 @@
# vexnc
-Single-purpose VNC server that simply displays a static image to all clients.
+Dumb VNC server that simply displays a static image of your choosing to all clients on port 5900.
+It can also log keypresses to a file. Useful for catching bots that scan the entire internet for exposed VNC servers.
+
+## Usage
+Requires libvncserver.
+
+```
+$ make CFLAGS="-O2 -march=native"
+$ ./vexnc dipshit.png 'insert funny desktop name here' ~/vexnclogs
+```
+
+## TODO
+- Allow choosing other ports than 5900
+- Add compression to log files (you can just handle this with a cronjob though)
diff --git a/vexnc.c b/vexnc.c
index 51cd483..3ef1383 100644
--- a/vexnc.c
+++ b/vexnc.c
@@ -1,16 +1,90 @@
-// gcc -O2 -march=native -o vexnc vexnc.c -lvncserver -lm
+#include <stdio.h>
+#include <stdint.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
#include <rfb/rfb.h>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
+int logdirenabled = 0;
+int fdlog = -1;
+char logfn[64] = "";
+
+int mkderp(const char *name) {
+ int ret = mkdir(name, S_IRWXU | S_IRWXG | S_IRWXO);
+ if (ret < 0 && errno == EEXIST) {
+ return 0;
+ }
+ return ret;
+}
+
+int spewchr(int fd, uint16_t chr) {
+ char buf[4];
+ int i = 0;
+ if (chr < 0x80) {
+ buf[i++] = chr;
+ } else if (chr < 0x800) {
+ buf[i++] = 0xC0 | chr >> 6;
+ buf[i++] = 0x80 | chr & 0x3F;
+ } else {
+ buf[i++] = 0xE0 | chr >> 12;
+ buf[i++] = 0x80 | (chr >> 6) & 0x3F;
+ buf[i++] = 0x80 | chr & 0x3F;
+ }
+ return write(fd, buf, i);
+}
+
+int openlogfile() {
+ char curfn[64];
+ time_t now;
+ time(&now);
+ strftime(curfn, 64, "%Y-%m-%d_%H", localtime(&now));
+ if (!strncmp(curfn, logfn, 64))
+ return 0;
+
+ int fd = open(curfn, O_CREAT | O_APPEND | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+ if (fd < 0) {
+ perror("open logfile");
+ return 1;
+ }
+
+ if (fdlog != -1 && close(fdlog) < 0) {
+ perror("close logfile");
+ }
+
+ fdlog = fd;
+ return 0;
+}
+
+void keylog(rfbBool down, rfbKeySym keySym, rfbClientRec* cl) {
+ if (!down) return; // only log key downs
+ if (openlogfile()) return; // ensure log file opened
+
+ if (spewchr(fdlog, (uint16_t) keySym) < 0)
+ perror("spewchr");
+}
+
int main(int argc, char const *argv[]) {
if (argc < 3) {
- printf("usage: %s IMAGEFILE TITLE\n", argv[0]);
+ printf("usage: %s IMAGEFILE TITLE [LOGDIR]\n", argv[0]);
return 0;
}
+ if (argc >= 4) {
+ if (mkderp(argv[3]) < 0) {
+ perror("mkdir logdir");
+ return 1;
+ }
+ if (chdir(argv[3]) < 0) {
+ perror("chdir logdir");
+ return 1;
+ }
+ logdirenabled = 1;
+ }
+
int imx, imy, imc;
unsigned char *im = stbi_load(argv[1], &imx, &imy, &imc, 4);
if (im == NULL) {
@@ -22,6 +96,9 @@ int main(int argc, char const *argv[]) {
rfbScreen->desktopName = argv[2] ? argv[2] : "";
rfbScreen->frameBuffer = (char*)im;
rfbScreen->alwaysShared = TRUE;
+ if (logdirenabled) {
+ rfbScreen->kbdAddEvent = keylog;
+ }
rfbInitServer(rfbScreen);
rfbRunEventLoop(rfbScreen, -1, FALSE);