Добавлены проверки MAC-адреса и команд создания/удаления символической ссылки
This commit is contained in:
parent
755296ad6d
commit
fcc3f73807
2
APKBUILD
2
APKBUILD
|
@ -41,5 +41,5 @@ a836823eda80e43b8914b7b045b91703faded83d2b1482a0d17f0fb903cbc0ce17dd9e0c06a2f6e3
|
|||
8a5de40dde8a5e569fce4309e01341a77a4e36cdcb5fe602948d5b34ee2646bd83840158d7d61a45c17e71cc893f3e9bd04a38ebcc7a6a8fff98f46a50d74e96 in.tftpd.confd
|
||||
40127e7ce276a2bc015255dbeef2665bfe8ff006b1e1d8fb79797e946d6030fd74606cffe0bea11eaad276a693f223faaaf1c1ccb5f276b40fdad40b366172b7 fix-common.patch
|
||||
736e205531c25da2a1c3ad0311c2be6a95a2778ecbce976be057c3bf2b8da65cccce9e7013deded61217a61f32dd18bdea311807504d60cadbd16687471deb70 trq.patch
|
||||
929749b3e2a297197b2be124df6364fad38f226d54fe6f006dc257457db5a247f6f5006063479b09ee20c7d8de7174e31db3d54b5956f841eee0f725edf31f3d trq.c
|
||||
314eea07339e7c8605a69db65638aacfb488077f39b127bdc81369202d0edae6545a456705cebe08fde3729293b7609892a09d91ec2f7dc93b63d693b10ff833 trq.c
|
||||
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.
43
trq/trq.c
43
trq/trq.c
|
@ -14,6 +14,7 @@
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <regex.h>
|
||||
|
||||
void ts_free(ts_args *args)
|
||||
{
|
||||
|
@ -29,7 +30,6 @@ void ts_free(ts_args *args)
|
|||
free(args->path_src);
|
||||
if (args->command)
|
||||
free(args->path_dst);
|
||||
|
||||
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");
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -65,7 +59,6 @@ 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)
|
||||
|
@ -74,7 +67,6 @@ static char* ts_copy_string(const char *string)
|
|||
exit(3);
|
||||
}
|
||||
strncpy(tmp, string, (len + 1));
|
||||
|
||||
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");
|
||||
exit(3);
|
||||
}
|
||||
|
||||
char separator[2] = ";\0";
|
||||
char *part = NULL;
|
||||
int len = strlen(filename);
|
||||
|
||||
int next = 1; /* reading the next iteration */
|
||||
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");
|
||||
syslog(LOG_NOTICE, "TRQ Disk full or allocation exceeded (ts_get_arguments)\n");
|
||||
exit(3);
|
||||
}
|
||||
strncpy(tmp_filename, filename, (len + 1));
|
||||
|
||||
part = strtok(tmp_filename, separator);
|
||||
|
||||
while (part)
|
||||
{
|
||||
switch (args->size)
|
||||
{
|
||||
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->path_dst = ts_concat_path(part);
|
||||
break;
|
||||
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);
|
||||
break;
|
||||
case 2:
|
||||
|
@ -117,19 +122,21 @@ ts_args* ts_get_arguments(const char *filename, const char *path)
|
|||
args->path_src = ts_concat_path(part);
|
||||
break;
|
||||
default:
|
||||
syslog(LOG_NOTICE, "TRQ Invalid request format (ts_get_arguments)\n");
|
||||
exit(100);
|
||||
}
|
||||
++args->size;
|
||||
part = strtok(NULL, separator);
|
||||
if (next)
|
||||
part = strtok(NULL, separator);
|
||||
else
|
||||
part = NULL;
|
||||
}
|
||||
|
||||
free(tmp_filename);
|
||||
|
||||
if (!args->size)
|
||||
{
|
||||
free(args);
|
||||
args = NULL;
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue