From 755296ad6d6d1b82144cb8bae43c5444bf2860e1 Mon Sep 17 00:00:00 2001 From: Alexander Zhirov Date: Wed, 17 Aug 2022 17:09:52 +0300 Subject: [PATCH] tftp with trq protocol --- APKBUILD | 45 +++++++++++++ fix-common.patch | 24 +++++++ in.tftpd.confd | 15 +++++ in.tftpd.initd | 21 ++++++ trq/trq.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++ trq/trq.h | 30 +++++++++ trq/trq.patch | 82 +++++++++++++++++++++++ 7 files changed, 383 insertions(+) create mode 100644 APKBUILD create mode 100644 fix-common.patch create mode 100644 in.tftpd.confd create mode 100644 in.tftpd.initd create mode 100644 trq/trq.c create mode 100644 trq/trq.h create mode 100644 trq/trq.patch diff --git a/APKBUILD b/APKBUILD new file mode 100644 index 0000000..dbdbf89 --- /dev/null +++ b/APKBUILD @@ -0,0 +1,45 @@ +# Maintainer: Natanael Copa +pkgname=tftp-hpa +pkgver=5.2 +pkgrel=4 +pkgdesc="Official tftp server" +url="https://www.kernel.org/pub/software/network/tftp/" +arch="all" +license="BSD" +subpackages="$pkgname-doc" +source="https://www.kernel.org/pub/software/network/tftp/tftp-hpa/$pkgname-$pkgver.tar.xz + in.tftpd.initd + in.tftpd.confd + fix-common.patch + trq/trq.patch + trq/trq.c + trq/trq.h + " + +build() { + ls $srcdir + cp $srcdir/trq.c $builddir/tftpd + cp $srcdir/trq.h $builddir/tftpd + + ./configure \ + --build=$CBUILD \ + --host=$CHOST \ + --prefix=/usr \ + --mandir=/usr/share/man + make +} + +package() { + make INSTALLROOT="$pkgdir" install + install -d "$pkgdir"/var/tftpboot + install -Dm755 "$srcdir"/in.tftpd.initd "$pkgdir"/etc/init.d/in.tftpd + install -Dm644 "$srcdir"/in.tftpd.confd "$pkgdir"/etc/conf.d/in.tftpd +} + +sha512sums="a5198e923a6e58281f749dc77b3f3ed8579e56b6f0fd6a17482cc88bdc8d34b6702c7c709717885b9b937ecae459d9a832328a49a2e3536dc7432cdb39d2a394 tftp-hpa-5.2.tar.xz +a836823eda80e43b8914b7b045b91703faded83d2b1482a0d17f0fb903cbc0ce17dd9e0c06a2f6e35724099614ef5a74d9ba8be80237fbbb29c632cea983779a in.tftpd.initd +8a5de40dde8a5e569fce4309e01341a77a4e36cdcb5fe602948d5b34ee2646bd83840158d7d61a45c17e71cc893f3e9bd04a38ebcc7a6a8fff98f46a50d74e96 in.tftpd.confd +40127e7ce276a2bc015255dbeef2665bfe8ff006b1e1d8fb79797e946d6030fd74606cffe0bea11eaad276a693f223faaaf1c1ccb5f276b40fdad40b366172b7 fix-common.patch +736e205531c25da2a1c3ad0311c2be6a95a2778ecbce976be057c3bf2b8da65cccce9e7013deded61217a61f32dd18bdea311807504d60cadbd16687471deb70 trq.patch +929749b3e2a297197b2be124df6364fad38f226d54fe6f006dc257457db5a247f6f5006063479b09ee20c7d8de7174e31db3d54b5956f841eee0f725edf31f3d trq.c +29cc72f3197bcaea4a88dace5c91d53dad5d20a397752198e601e2ed83fdb66fca50a5b4b03c4d3033ebd7a0be1e90801a692c514733412d8d96cafde26e0837 trq.h" diff --git a/fix-common.patch b/fix-common.patch new file mode 100644 index 0000000..1f082e8 --- /dev/null +++ b/fix-common.patch @@ -0,0 +1,24 @@ +diff -urN tftp-hpa-5.2.orig/tftp/main.c tftp-hpa-5.2/tftp/main.c +--- tftp-hpa-5.2.orig/tftp/main.c 2020-11-14 22:21:15.851650899 -0700 ++++ tftp-hpa-5.2/tftp/main.c 2020-11-14 22:21:41.878327755 -0700 +@@ -95,7 +95,7 @@ + int margc; + char *margv[20]; + const char *prompt = "tftp> "; +-sigjmp_buf toplevel; ++static sigjmp_buf toplevel; + void intr(int); + struct servent *sp; + int portrange = 0; +diff -urN tftp-hpa-5.2.orig/tftp/tftp.c tftp-hpa-5.2/tftp/tftp.c +--- tftp-hpa-5.2.orig/tftp/tftp.c 2020-11-14 22:21:15.851650899 -0700 ++++ tftp-hpa-5.2/tftp/tftp.c 2020-11-14 22:21:51.304998113 -0700 +@@ -48,7 +48,7 @@ + #define PKTSIZE SEGSIZE+4 + char ackbuf[PKTSIZE]; + int timeout; +-sigjmp_buf toplevel; ++static sigjmp_buf toplevel; + sigjmp_buf timeoutbuf; + + static void nak(int, const char *); diff --git a/in.tftpd.confd b/in.tftpd.confd new file mode 100644 index 0000000..5d74ac1 --- /dev/null +++ b/in.tftpd.confd @@ -0,0 +1,15 @@ +# /etc/init.d/in.tftpd + +# Path to server files from +# Depending on your application you may have to change this. +INTFTPD_PATH="/var/tftpboot/" +#INTFTPD_PATH="/var/tftp/" +#INTFTPD_PATH="/tftpboot/" +#INTFTPD_PATH="/tftproot/" + +# For more options, see in.tftpd(8) +# -R 4096:32767 solves problems with ARC firmware, and obsoletes +# the /proc/sys/net/ipv4/ip_local_port_range hack. +# -s causes $INTFTPD_PATH to be the root of the TFTP tree. +# -l is passed by the init script in addition to these options. +INTFTPD_OPTS="-R 4096:32767 -s ${INTFTPD_PATH}" diff --git a/in.tftpd.initd b/in.tftpd.initd new file mode 100644 index 0000000..399aea3 --- /dev/null +++ b/in.tftpd.initd @@ -0,0 +1,21 @@ +#!/sbin/openrc-run +# Copyright 1999-2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: /var/cvsroot/gentoo-x86/net-ftp/tftp-hpa/files/in.tftpd.rc6,v 1.2 2005/07/30 06:29:14 vapier Exp $ + +depend() { + need net + after firewall +} + +start() { + ebegin "Starting tftpd" + /usr/sbin/in.tftpd -l ${INTFTPD_OPTS} + eend $? +} + +stop() { + ebegin "Stopping tftpd" + start-stop-daemon --stop --exec /usr/sbin/in.tftpd + eend $? +} diff --git a/trq/trq.c b/trq/trq.c new file mode 100644 index 0000000..9ed58f3 --- /dev/null +++ b/trq/trq.c @@ -0,0 +1,166 @@ +/* + * trq.c + * + * Created on: 17 авг. 2022 г. + * Author: Alexander Zhirov + * Mail: alexander@zhirov.website + * Telegram: alexanderzhirov + */ + +#include "trq.h" + +#include +#include +#include +#include +#include + +void ts_free(ts_args *args) +{ + if (args) + { + if (args->command) + free(args->command); + if (args->file_src) + free(args->file_src); + if (args->file_dst) + free(args->file_dst); + if (args->path_src) + free(args->path_src); + if (args->command) + free(args->path_dst); + + free(args); + } +} + +static char* ts_concat_path(const char *file) +{ + if (!file) + { + syslog(LOG_NOTICE, "TRQ Invalid value file (ts_concat_path)\n"); + exit(3); + } + + const char *path_mac = "mac.cfg/"; + + size_t len1 = strlen(path_mac); + size_t len2 = strlen(file); + + char *result = (char*) malloc(sizeof(char) * (len1 + len2 + 1)); + + if (!result) + { + syslog(LOG_NOTICE, "TRQ Disk full or allocation exceeded (ts_concat_path)\n"); + exit(3); + } + + strncpy(result, path_mac, (len1 + 1)); + strncpy(result + len1, file, (len2 + 1)); + + return result; +} + +static char* ts_copy_string(const char *string) +{ + if (!string) + return NULL; + + int len = strlen(string); + char *tmp = (char*) calloc(1, sizeof(char) * (len + 1)); + if (!tmp) + { + syslog(LOG_NOTICE, "TRQ Disk full or allocation exceeded (ts_copy_string)\n"); + exit(3); + } + strncpy(tmp, string, (len + 1)); + + return tmp; +} + +ts_args* ts_get_arguments(const char *filename, const char *path) +{ + ts_args *args = (ts_args*) calloc(1, sizeof(ts_args)); + if (!args) + { + syslog(LOG_NOTICE, "TRQ Disk full or allocation exceeded (ts_get_arguments)\n"); + exit(3); + } + + char separator[2] = ";\0"; + char *part = NULL; + int len = strlen(filename); + + char *tmp_filename = (char*) calloc(1, sizeof(char) * (len + 1)); + if (!tmp_filename) + { + syslog(LOG_NOTICE, "TRQ Disk full or allocation exceeded (ts_copy_string)\n"); + exit(3); + } + strncpy(tmp_filename, filename, (len + 1)); + + part = strtok(tmp_filename, separator); + + while (part) + { + switch (args->size) + { + case 0: + args->file_dst = ts_copy_string(part); + args->path_dst = ts_concat_path(part); + break; + case 1: + args->command = ts_copy_string(part); + break; + case 2: + args->file_src = ts_copy_string(part); + args->path_src = ts_concat_path(part); + break; + default: + } + ++args->size; + part = strtok(NULL, separator); + } + + free(tmp_filename); + + if (!args->size) + { + free(args); + args = NULL; + } + + return args; +} + +void ts_syslog(const ts_args *args) +{ + if (args) + { + if (args->size > 2) + syslog(LOG_NOTICE, "TRQ Create symlink %s on %s\n", args->file_dst, args->file_src); + else + syslog(LOG_NOTICE, "TRQ Remove symlink %s\n", args->file_dst); + } +} + +void ts_symlink(const ts_args *args) +{ + if (args) + { + if (args->size > 2) + { + if (access(args->path_src, F_OK) == 0 && !symlink(args->file_src, args->path_dst)) + syslog(LOG_NOTICE, "TRQ A symbolic link %s has been created\n", args->file_dst); + else + syslog(LOG_NOTICE, "TRQ Failed to create symbolic link %s. %s\n", args->file_dst, strerror(errno)); + } + else + { + if (access(args->path_dst, F_OK) == 0 && !unlink(args->path_dst)) + syslog(LOG_NOTICE, "TRQ A symbolic link %s has been removed\n", args->file_dst); + else + syslog(LOG_NOTICE, "TRQ Failed to remove symbolic link %s. %s\n", args->file_dst, strerror(errno)); + } + } +} diff --git a/trq/trq.h b/trq/trq.h new file mode 100644 index 0000000..d6828c3 --- /dev/null +++ b/trq/trq.h @@ -0,0 +1,30 @@ +/* + * trq.h + * + * Created on: 17 авг. 2022 г. + * Author: Alexander Zhirov + * Mail: alexander@zhirov.website + * Telegram: alexanderzhirov + */ + +#ifndef TRQ_H_ +#define TRQ_H_ + +#define TRQ 06 /* Thinstation */ + +typedef struct +{ + int size; + char *command; + char *file_src; + char *file_dst; + char *path_src; + char *path_dst; +} ts_args; + +ts_args* ts_get_arguments(const char*, const char*); +void ts_free(ts_args*); +void ts_syslog(const ts_args*); +void ts_symlink(const ts_args*); + +#endif diff --git a/trq/trq.patch b/trq/trq.patch new file mode 100644 index 0000000..dbe9337 --- /dev/null +++ b/trq/trq.patch @@ -0,0 +1,82 @@ +diff --git a/tftpd/Makefile b/tftpd/Makefile +index a05335d..d4bfb15 100644 +--- a/tftpd/Makefile ++++ b/tftpd/Makefile +@@ -4,7 +4,7 @@ VERSION = $(shell cat ../version) + -include ../MCONFIG + include ../MRULES + +-OBJS = tftpd.$(O) recvfrom.$(O) misc.$(O) $(TFTPDOBJS) ++OBJS = tftpd.$(O) trq.o recvfrom.$(O) misc.$(O) $(TFTPDOBJS) + + all: tftpd$(X) tftpd.8 + +diff --git a/tftpd/tftpd.c b/tftpd/tftpd.c +index 1873e70..c3df336 100644 +--- a/tftpd/tftpd.c ++++ b/tftpd/tftpd.c +@@ -52,6 +52,7 @@ + #include "common/tftpsubs.h" + #include "recvfrom.h" + #include "remap.h" ++#include "trq.h" + + #ifdef HAVE_SYS_FILIO_H + #include /* Necessary for FIONBIO on Solaris */ +@@ -1038,7 +1039,7 @@ int main(int argc, char **argv) + + tp = (struct tftphdr *)buf; + tp_opcode = ntohs(tp->th_opcode); +- if (tp_opcode == RRQ || tp_opcode == WRQ) ++ if (tp_opcode == RRQ || tp_opcode == WRQ || tp_opcode == TRQ) + tftp(tp, n); + exit(0); + } +@@ -1077,6 +1078,7 @@ int tftp(struct tftphdr *tp, int size) + char *filename, *mode = NULL; + const char *errmsgptr; + u_short tp_opcode = ntohs(tp->th_opcode); ++ ts_args *args = NULL; + + char *val = NULL, *opt = NULL; + char *ap = ackbuf + 2; +@@ -1118,6 +1120,10 @@ int tftp(struct tftphdr *tp, int size) + nak(EACCESS, errmsgptr); /* File denied by mapping rule */ + exit(0); + } ++ if (tp_opcode == TRQ) /* Thinstation request */ ++ { ++ args = ts_get_arguments(filename, dirs[ndirs - 1]); ++ } + if (verbosity >= 1) { + tmp_p = (char *)inet_ntop(from.sa.sa_family, SOCKADDR_P(&from), + tmpbuf, INET6_ADDRSTRLEN); +@@ -1127,9 +1133,12 @@ int tftp(struct tftphdr *tp, int size) + } + if (filename == origfilename + || !strcmp(filename, origfilename)) +- syslog(LOG_NOTICE, "%s from %s filename %s\n", +- tp_opcode == WRQ ? "WRQ" : "RRQ", +- tmp_p, filename); ++ if (tp_opcode == TRQ) /* Thinstation request */ ++ ts_syslog(args); ++ else ++ syslog(LOG_NOTICE, "%s from %s filename %s\n", ++ tp_opcode == WRQ ? "WRQ" : "RRQ", ++ tmp_p, filename); + else + syslog(LOG_NOTICE, + "%s from %s filename %s remapped to %s\n", +@@ -1137,6 +1146,12 @@ int tftp(struct tftphdr *tp, int size) + tmp_p, origfilename, + filename); + } ++ if (tp_opcode == TRQ) ++ { ++ ts_symlink(args); ++ ts_free(args); ++ exit(0); ++ } + ecode = + (*pf->f_validate) (filename, tp_opcode, pf, &errmsgptr); + if (ecode) {