summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnton <anton@picapica>2020-01-18 21:15:00 +0400
committerAnton <anton@picapica>2020-01-18 21:15:00 +0400
commit98d106b3f74e5c2adc0218d10bdbadf8ffef5ee2 (patch)
treefac1f2930b9ef18edb42e458d11a19e3a1bf5abe
parent9302dc71e5efe8915d18e88a2e3e9567a7f8111a (diff)
downloadpica-pica-98d106b3f74e5c2adc0218d10bdbadf8ffef5ee2.tar.gz
pica-pica-98d106b3f74e5c2adc0218d10bdbadf8ffef5ee2.zip
validate file name on incoming file tranfer requests
-rw-r--r--PICA_client.c28
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;