Добавлены проверки MAC-адреса и команд создания/удаления символической ссылки
This commit is contained in:
parent
755296ad6d
commit
fcc3f73807
2
APKBUILD
2
APKBUILD
|
@ -41,5 +41,5 @@ a836823eda80e43b8914b7b045b91703faded83d2b1482a0d17f0fb903cbc0ce17dd9e0c06a2f6e3
|
||||||
8a5de40dde8a5e569fce4309e01341a77a4e36cdcb5fe602948d5b34ee2646bd83840158d7d61a45c17e71cc893f3e9bd04a38ebcc7a6a8fff98f46a50d74e96 in.tftpd.confd
|
8a5de40dde8a5e569fce4309e01341a77a4e36cdcb5fe602948d5b34ee2646bd83840158d7d61a45c17e71cc893f3e9bd04a38ebcc7a6a8fff98f46a50d74e96 in.tftpd.confd
|
||||||
40127e7ce276a2bc015255dbeef2665bfe8ff006b1e1d8fb79797e946d6030fd74606cffe0bea11eaad276a693f223faaaf1c1ccb5f276b40fdad40b366172b7 fix-common.patch
|
40127e7ce276a2bc015255dbeef2665bfe8ff006b1e1d8fb79797e946d6030fd74606cffe0bea11eaad276a693f223faaaf1c1ccb5f276b40fdad40b366172b7 fix-common.patch
|
||||||
736e205531c25da2a1c3ad0311c2be6a95a2778ecbce976be057c3bf2b8da65cccce9e7013deded61217a61f32dd18bdea311807504d60cadbd16687471deb70 trq.patch
|
736e205531c25da2a1c3ad0311c2be6a95a2778ecbce976be057c3bf2b8da65cccce9e7013deded61217a61f32dd18bdea311807504d60cadbd16687471deb70 trq.patch
|
||||||
929749b3e2a297197b2be124df6364fad38f226d54fe6f006dc257457db5a247f6f5006063479b09ee20c7d8de7174e31db3d54b5956f841eee0f725edf31f3d trq.c
|
314eea07339e7c8605a69db65638aacfb488077f39b127bdc81369202d0edae6545a456705cebe08fde3729293b7609892a09d91ec2f7dc93b63d693b10ff833 trq.c
|
||||||
29cc72f3197bcaea4a88dace5c91d53dad5d20a397752198e601e2ed83fdb66fca50a5b4b03c4d3033ebd7a0be1e90801a692c514733412d8d96cafde26e0837 trq.h"
|
29cc72f3197bcaea4a88dace5c91d53dad5d20a397752198e601e2ed83fdb66fca50a5b4b03c4d3033ebd7a0be1e90801a692c514733412d8d96cafde26e0837 trq.h"
|
||||||
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
# tftp-hpa
|
||||||
|
|
||||||
|
- [Описание](#описание)
|
||||||
|
- [Пример запроса на `php`](#пример-запроса-на-php)
|
||||||
|
- [Сборка пакета в Docker](#сборка-пакета-в-docker)
|
||||||
|
- [Безопасность](#безопасность)
|
||||||
|
|
||||||
|
![protocol](img/protocol.png)
|
||||||
|
|
||||||
|
## Описание
|
||||||
|
|
||||||
|
К [стандартным](http://isp.vsi.ru/library/Networking/TCPIPIllustrated/tftp_tri.htm) `opcodes` `RRQ` и `WRQ` был добавлен `TRQ` (*Thinstation Request*) со значением `6`, позволяющий создать символическую ссылку на файл-загрузчик для PXE-сервера.
|
||||||
|
|
||||||
|
Структура `filename` принимаемая TFTP-сервером состоит из частей, разделённая `;`:
|
||||||
|
```sh
|
||||||
|
01-<mac-address>;<command>;<source-file>
|
||||||
|
```
|
||||||
|
где
|
||||||
|
- `01` - указывается как префикс MAC-адреса тонкого клиента
|
||||||
|
- `mac-address` - MAC-адрес тонкого клиента в нижнем регистре, разделённого `-`, например `ff-ff-ff-ff-ff-ff`
|
||||||
|
- `command` - команда (`cr`/`rm`) для создания/удаления символической ссылки на файл
|
||||||
|
- `source-file` - основной файл, на который необходимо создать символическую ссылку
|
||||||
|
|
||||||
|
Символическая ссылка создаётся в директории `mac.cfg` с правами `drwxrwxrwx`, расположенной в корневой директории TFTP сервера.
|
||||||
|
Например, структура `filename` создания симолической ссылки на файл `thinstation`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
01-ff-ff-ff-ff-ff-ff;cr;thinstation
|
||||||
|
```
|
||||||
|
|
||||||
|
Удаление символической ссылки:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
01-ff-ff-ff-ff-ff-ff;rm
|
||||||
|
```
|
||||||
|
|
||||||
|
Структура каталога `tftpboot`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
.
|
||||||
|
└── tftpboot
|
||||||
|
└── [drwxrwxrwx] mac.cfg
|
||||||
|
├── 01-ff-ff-ff-ff-ff-ff -> thinstation
|
||||||
|
└── thinstation
|
||||||
|
```
|
||||||
|
|
||||||
|
## Пример запроса на PHP
|
||||||
|
|
||||||
|
Создание пакета на `php` для создания символической ссылки, отправляемого на TFTP-сервер:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$opcode = 6; // TRQ opcode
|
||||||
|
$request = '01-ff-ff-ff-ff-ff-ff;cr;thinstation';
|
||||||
|
$mode = 'octet';
|
||||||
|
$ip = '192.168.1.1';
|
||||||
|
$port = 69;
|
||||||
|
$sock = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
|
||||||
|
$package = chr(0) . chr($opcode) . $request . chr(0) . $mode . chr(0);
|
||||||
|
socket_sendto($sock, $package, strlen($package), MSG_EOF, $ip, $port);
|
||||||
|
socket_close($sock);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Сборка пакета в Docker
|
||||||
|
|
||||||
|
Склонировать репозиторий в удобное место:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
git clone https://git.zhirov.website/alexander/tftp-hpa.git tftp-hpa
|
||||||
|
```
|
||||||
|
|
||||||
|
Войти в оболочку `alpine` для сборки пакета запустив `docker` командой:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker run --rm -it -v $PWD/tftp-hpa:/home/packager/reposerve/main/tftp-hpa alpine:latest sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Установить инструменты разработчика:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
apk add sudo build-base alpine-sdk
|
||||||
|
```
|
||||||
|
|
||||||
|
Cоздать пользователя `packager` и добавьте его в список sudo
|
||||||
|
|
||||||
|
```sh
|
||||||
|
adduser -D packager
|
||||||
|
addgroup packager abuild
|
||||||
|
echo 'packager ALL=(ALL) NOPASSWD:ALL' >/etc/sudoers.d/packager
|
||||||
|
```
|
||||||
|
|
||||||
|
Войти под созданным пользователем `packager`:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo -u packager sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Сгенерировать ключи:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
abuild-keygen -a -i
|
||||||
|
```
|
||||||
|
|
||||||
|
Собрать пакет:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd /home/packager/reposerve/main/tftp-hpa
|
||||||
|
REPODEST=~/packages/latest abuild -r
|
||||||
|
```
|
||||||
|
|
||||||
|
Для установки в других экземплярах `alpine` возможно понадобятся сгенерированные ранее ключи для сборки пакета (`/home/packager/.abuild/{*.rsa,*.rsa.pub}`).
|
||||||
|
|
||||||
|
|
||||||
|
## Безопасность
|
||||||
|
|
||||||
|
Отсутствует проверка на источник запроса, так как сформировать запрос на создание/удаление символической ссылки выполняется в произвольной форме.
|
Binary file not shown.
After Width: | Height: | Size: 9.6 KiB |
Binary file not shown.
|
@ -0,0 +1 @@
|
||||||
|
PACKAGER_PRIVKEY="/home/packager/.abuild/packager-62fdf15d.rsa"
|
|
@ -0,0 +1,27 @@
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEpAIBAAKCAQEA7X2j1S7QDmBUQLyzytZ2GjpYYEgOq7drzyaGeYIL2GY8rm2C
|
||||||
|
ytHQxeo2OfSUESUb/sad9kBw2NXlA1AOi/9maES25+IxOGa0koBkRm8jmPPm5Wbe
|
||||||
|
h1zqWHIjNH3uaiPPZvgFqUL/boeuRDQ4cDjr8R3eHSAED+SwmnvSiJCFeMjGfHId
|
||||||
|
uc9k/L7F0l4RSs50WHFwzNXB4xebJnbwCUN1c/W4aBCew0k1vzXxVuwe2YpUoeGY
|
||||||
|
o0veNvKX5xKKNMhC6EJoVmjBDcXCOtN+F3GNvNaUO6JslC7nYAWxK5/CRUuICZaj
|
||||||
|
s5/+GaO7/rPC8vGnMGDw9aTOH7bISN+zHDHq9wIDAQABAoIBAQDKPSDEDO5OH8f/
|
||||||
|
rPIqfEDsitzxeMtNfZAIQpVnadAugrmQDF/B2bTApXdyGQ3yH7jcWETyC+RNMrCo
|
||||||
|
Boesvlx11HYxt1QU5JlG3KEHveMBgEoS9mvvt7c0hFXogIkDx+T5maIwhoZAmLhV
|
||||||
|
Cmc5Ya/Cj52zDa2H30Zo96LMes2+kQ9IPpNFJevY1pBB2d+B9Tg6QOHLxSFXdJ4H
|
||||||
|
+XXmtAFUvO5bEAicsRlMvav7FPPK3o7i5FQ6JCL5nDNGDbHw72WxKDpbqlhZsFN9
|
||||||
|
oIyx++4Vu94H3BE0b8UDcTQyF+V3TSjn9OXBKNsb8VcVt75HWw7A8iaSIJctofMh
|
||||||
|
v8jDRt/pAoGBAPgpwEEeJFLUOlH35IPOZ2MolnqnUzbwPW8VnzLk1PA9/8pqU8Xh
|
||||||
|
YljgOcI3hK755Pz3HTB8hQor6yTTR7lzIHGp3zGhAWw46qiqBzJVHzTGfols9i8b
|
||||||
|
2cx8ZUHkad4VpaB6KtKpfArfTkEk0QPNRFEYjg05mppqhfyG9bDV+HRrAoGBAPT9
|
||||||
|
nBuEN98FzhyBJBWtTCdnkJh8Eqw2HzI5OHGwVCdYv3GnapWIHHVLr2N4s2+sL7xP
|
||||||
|
WuKfyosVDj5WrANmQtkwyFxkVBapptV8Bw84lAGuVOfea3c7lgA6Zj15ldiFMbHU
|
||||||
|
0LhBYTfqZu7+3OhHbV+nCrY/cexqGYD8JuePFSalAoGBANXpx1taTB1J62u0rzoe
|
||||||
|
tWf4GJ5plYWJ2KrkjHImZpcgGlm1BblQ6qGJxr/vc2QQ7J5RtMuSymtWKD96EB1/
|
||||||
|
a7wOneH902giN8RjrAhq75dicrirQBqjez6VDAOcjNVu+3I1XKxyhAYrLx1gSvtn
|
||||||
|
+TeeXvRvbyEkKZLgEvD3wE85AoGANiPxorcWbcfno676XXv9r1uYvcn1im8vd7bj
|
||||||
|
fWRdRJC9Rg2cZU0+FMHUEaRz6wLfTbsvt5NefFv72NTokJvBvCOms5xMZPG698S/
|
||||||
|
/qIfOzvecZtanm/hl01QmNdMwRu2PrlsIrv4ExZPBxP1l7NpPVE58cqVj4xm9HVE
|
||||||
|
17lsEC0CgYAWgcAkEr2mBQ7BtOJZmmweDRe2q6VOuPVgVzS3knzaN59FvCNeImU2
|
||||||
|
Zmuz0fhiW1KSefOZ98AQA3Hl+uE06FEN5cJrI2qSnOkTJqyTc/x1Gi/rZLA0BWby
|
||||||
|
Th3eMMcnd7cpc8WDT5Dfg6YIwlw+OEIEXuxDzhIDej1BJDynR3izEA==
|
||||||
|
-----END RSA PRIVATE KEY-----
|
|
@ -0,0 +1,9 @@
|
||||||
|
-----BEGIN PUBLIC KEY-----
|
||||||
|
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7X2j1S7QDmBUQLyzytZ2
|
||||||
|
GjpYYEgOq7drzyaGeYIL2GY8rm2CytHQxeo2OfSUESUb/sad9kBw2NXlA1AOi/9m
|
||||||
|
aES25+IxOGa0koBkRm8jmPPm5Wbeh1zqWHIjNH3uaiPPZvgFqUL/boeuRDQ4cDjr
|
||||||
|
8R3eHSAED+SwmnvSiJCFeMjGfHIduc9k/L7F0l4RSs50WHFwzNXB4xebJnbwCUN1
|
||||||
|
c/W4aBCew0k1vzXxVuwe2YpUoeGYo0veNvKX5xKKNMhC6EJoVmjBDcXCOtN+F3GN
|
||||||
|
vNaUO6JslC7nYAWxK5/CRUuICZajs5/+GaO7/rPC8vGnMGDw9aTOH7bISN+zHDHq
|
||||||
|
9wIDAQAB
|
||||||
|
-----END PUBLIC KEY-----
|
Binary file not shown.
Binary file not shown.
41
trq/trq.c
41
trq/trq.c
|
@ -14,6 +14,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <regex.h>
|
||||||
|
|
||||||
void ts_free(ts_args *args)
|
void ts_free(ts_args *args)
|
||||||
{
|
{
|
||||||
|
@ -29,7 +30,6 @@ void ts_free(ts_args *args)
|
||||||
free(args->path_src);
|
free(args->path_src);
|
||||||
if (args->command)
|
if (args->command)
|
||||||
free(args->path_dst);
|
free(args->path_dst);
|
||||||
|
|
||||||
free(args);
|
free(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,23 +41,17 @@ static char* ts_concat_path(const char *file)
|
||||||
syslog(LOG_NOTICE, "TRQ Invalid value file (ts_concat_path)\n");
|
syslog(LOG_NOTICE, "TRQ Invalid value file (ts_concat_path)\n");
|
||||||
exit(3);
|
exit(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *path_mac = "mac.cfg/";
|
const char *path_mac = "mac.cfg/";
|
||||||
|
|
||||||
size_t len1 = strlen(path_mac);
|
size_t len1 = strlen(path_mac);
|
||||||
size_t len2 = strlen(file);
|
size_t len2 = strlen(file);
|
||||||
|
|
||||||
char *result = (char*) malloc(sizeof(char) * (len1 + len2 + 1));
|
char *result = (char*) malloc(sizeof(char) * (len1 + len2 + 1));
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
syslog(LOG_NOTICE, "TRQ Disk full or allocation exceeded (ts_concat_path)\n");
|
syslog(LOG_NOTICE, "TRQ Disk full or allocation exceeded (ts_concat_path)\n");
|
||||||
exit(3);
|
exit(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
strncpy(result, path_mac, (len1 + 1));
|
strncpy(result, path_mac, (len1 + 1));
|
||||||
strncpy(result + len1, file, (len2 + 1));
|
strncpy(result + len1, file, (len2 + 1));
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +59,6 @@ static char* ts_copy_string(const char *string)
|
||||||
{
|
{
|
||||||
if (!string)
|
if (!string)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
int len = strlen(string);
|
int len = strlen(string);
|
||||||
char *tmp = (char*) calloc(1, sizeof(char) * (len + 1));
|
char *tmp = (char*) calloc(1, sizeof(char) * (len + 1));
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
|
@ -74,7 +67,6 @@ static char* ts_copy_string(const char *string)
|
||||||
exit(3);
|
exit(3);
|
||||||
}
|
}
|
||||||
strncpy(tmp, string, (len + 1));
|
strncpy(tmp, string, (len + 1));
|
||||||
|
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,30 +78,43 @@ ts_args* ts_get_arguments(const char *filename, const char *path)
|
||||||
syslog(LOG_NOTICE, "TRQ Disk full or allocation exceeded (ts_get_arguments)\n");
|
syslog(LOG_NOTICE, "TRQ Disk full or allocation exceeded (ts_get_arguments)\n");
|
||||||
exit(3);
|
exit(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
char separator[2] = ";\0";
|
char separator[2] = ";\0";
|
||||||
char *part = NULL;
|
char *part = NULL;
|
||||||
int len = strlen(filename);
|
int len = strlen(filename);
|
||||||
|
int next = 1; /* reading the next iteration */
|
||||||
char *tmp_filename = (char*) calloc(1, sizeof(char) * (len + 1));
|
char *tmp_filename = (char*) calloc(1, sizeof(char) * (len + 1));
|
||||||
if (!tmp_filename)
|
if (!tmp_filename)
|
||||||
{
|
{
|
||||||
syslog(LOG_NOTICE, "TRQ Disk full or allocation exceeded (ts_copy_string)\n");
|
syslog(LOG_NOTICE, "TRQ Disk full or allocation exceeded (ts_get_arguments)\n");
|
||||||
exit(3);
|
exit(3);
|
||||||
}
|
}
|
||||||
strncpy(tmp_filename, filename, (len + 1));
|
strncpy(tmp_filename, filename, (len + 1));
|
||||||
|
|
||||||
part = strtok(tmp_filename, separator);
|
part = strtok(tmp_filename, separator);
|
||||||
|
|
||||||
while (part)
|
while (part)
|
||||||
{
|
{
|
||||||
switch (args->size)
|
switch (args->size)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
|
regex_t regex;
|
||||||
|
regcomp(®ex, "^01-[0-9a-f]{2}(-[0-9a-f]{2}){5}$", REG_EXTENDED);
|
||||||
|
int reti = regexec(®ex, part, 0, NULL, 0);
|
||||||
|
if (reti)
|
||||||
|
{
|
||||||
|
syslog(LOG_NOTICE, "TRQ The MAC address was entered incorrectly (ts_get_arguments)\n");
|
||||||
|
exit(100);
|
||||||
|
}
|
||||||
args->file_dst = ts_copy_string(part);
|
args->file_dst = ts_copy_string(part);
|
||||||
args->path_dst = ts_concat_path(part);
|
args->path_dst = ts_concat_path(part);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
|
if (!strncmp("cr", part, 3)) {}
|
||||||
|
else if (!strncmp("rm", part, 3))
|
||||||
|
next = 0;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
syslog(LOG_NOTICE, "TRQ The command was specified incorrectly (ts_get_arguments)\n");
|
||||||
|
exit(100);
|
||||||
|
}
|
||||||
args->command = ts_copy_string(part);
|
args->command = ts_copy_string(part);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
|
@ -117,19 +122,21 @@ ts_args* ts_get_arguments(const char *filename, const char *path)
|
||||||
args->path_src = ts_concat_path(part);
|
args->path_src = ts_concat_path(part);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
syslog(LOG_NOTICE, "TRQ Invalid request format (ts_get_arguments)\n");
|
||||||
|
exit(100);
|
||||||
}
|
}
|
||||||
++args->size;
|
++args->size;
|
||||||
|
if (next)
|
||||||
part = strtok(NULL, separator);
|
part = strtok(NULL, separator);
|
||||||
|
else
|
||||||
|
part = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(tmp_filename);
|
free(tmp_filename);
|
||||||
|
|
||||||
if (!args->size)
|
if (!args->size)
|
||||||
{
|
{
|
||||||
free(args);
|
free(args);
|
||||||
args = NULL;
|
args = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue