diff options
| author | Anton <anton@picapica> | 2020-01-18 21:15:00 +0400 |
|---|---|---|
| committer | Anton <anton@picapica> | 2020-01-18 21:15:00 +0400 |
| commit | 98d106b3f74e5c2adc0218d10bdbadf8ffef5ee2 (patch) | |
| tree | fac1f2930b9ef18edb42e458d11a19e3a1bf5abe | |
| parent | 9302dc71e5efe8915d18e88a2e3e9567a7f8111a (diff) | |
| download | pica-pica-98d106b3f74e5c2adc0218d10bdbadf8ffef5ee2.tar.gz pica-pica-98d106b3f74e5c2adc0218d10bdbadf8ffef5ee2.zip | |
validate file name on incoming file tranfer requests
| -rw-r--r-- | PICA_client.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/PICA_client.c b/PICA_client.c index 14565dc..9938efc 100644 --- a/PICA_client.c +++ b/PICA_client.c @@ -997,6 +997,25 @@ int PICA_accept_file(struct PICA_c2c *chan, char *filename, unsigned int filenam return PICA_OK; } +static int validate_file_name(const char *buf, unsigned int len) +{ + int ret = PICA_OK; + char *str = malloc(len + 1); + memcpy(str, buf, len); + str[len] = '\0'; + + /* TODO Unicode canonicalization */ + + if (strchr(str, '*') != NULL + || strchr(str, ':') != NULL + || strchr(str, '/') != NULL + || strstr(str, "..") != NULL) + ret = PICA_ERRINVARG; + free(str); + + return ret; +} + static unsigned int procmsg_SENDFILEREQUEST(unsigned char* buf, unsigned int nb, void* p) { struct PICA_c2c *chan = (struct PICA_c2c *)p; @@ -1009,6 +1028,9 @@ static unsigned int procmsg_SENDFILEREQUEST(unsigned char* buf, unsigned int nb, if (chan->recvfilestate != PICA_CHANRECVFILESTATE_IDLE) return 0; + if (validate_file_name(filename, filenamesize) != PICA_OK) + return 0; + chan->recvfilestate = PICA_CHANRECVFILESTATE_WAITACCEPT; chan->recvfile_size = *(uint64_t*)(buf + 4); chan->recvfile_pos = 0; @@ -3609,7 +3631,11 @@ int PICA_recvfile_open_write(struct PICA_c2c *chn, const char *filename_utf8, un } #else - chn->recvfile_stream = fopen(filename_utf8, "wb"); + char *filename = malloc(filenamesize + 1); + memcpy(filename, filename_utf8, filenamesize); + filename[filenamesize] = '\0'; + chn->recvfile_stream = fopen(filename, "wb"); + free(filename); if (chn->recvfile_stream == NULL) return PICA_ERRFILEOPEN; |
