libclamav/uuencode.c
4c7e38d5
 /*
e1cbc270
  *  Copyright (C) 2013-2019 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
  *  Copyright (C) 2007-2013 Sourcefire, Inc.
2023340a
  *
  *  Authors: Nigel Horne
4c7e38d5
  *
  *  This program is free software; you can redistribute it and/or modify
2023340a
  *  it under the terms of the GNU General Public License version 2 as
  *  published by the Free Software Foundation.
4c7e38d5
  *
  *  This program is distributed in the hope that it will be useful,
  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  *  GNU General Public License for more details.
  *
  *  You should have received a copy of the GNU General Public License
  *  along with this program; if not, write to the Free Software
48b7b4a7
  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  *  MA 02110-1301, USA.
4c7e38d5
  */
2023340a
 
4c7e38d5
 #include "clamav.h"
 
288057e9
 #if HAVE_CONFIG_H
4c7e38d5
 #include "clamav-config.h"
 #endif
 
288057e9
 #ifdef HAVE_UNISTD_H
a8efe447
 #include <unistd.h>
 #endif
 
4c7e38d5
 #include <stdio.h>
 #include <memory.h>
 #include <sys/stat.h>
288057e9
 #ifdef HAVE_STRINGS_H
155a1c63
 #include <strings.h>
 #endif
b2e7c931
 
4c7e38d5
 #include "others.h"
d4a7dd82
 #include "str.h"
 
4c7e38d5
 #include "mbox.h"
 #include "uuencode.h"
 
 /* Maximum line length according to RFC821 */
288057e9
 #define RFC2821LENGTH 1000
4c7e38d5
 
288057e9
 int cli_uuencode(const char *dir, fmap_t *map)
4c7e38d5
 {
288057e9
     message *m;
     char buffer[RFC2821LENGTH + 1];
     size_t at = 0;
 
     if (!fmap_gets(map, buffer, &at, sizeof(buffer) - 1)) {
         /* empty message */
         return CL_CLEAN;
     }
     if (!isuuencodebegin(buffer)) {
         cli_dbgmsg("Message is not in uuencoded format\n");
         return CL_EFORMAT;
     }
 
     m = messageCreate();
     if (m == NULL) {
         return CL_EMEM;
     }
 
     cli_dbgmsg("found uuencode file\n");
 
     if (uudecodeFile(m, buffer, dir, map, &at) < 0) {
         messageDestroy(m);
         cli_dbgmsg("Message is not in uuencoded format\n");
         return CL_EFORMAT;
     }
     messageDestroy(m);
 
     return CL_CLEAN; /* a lie - but it gets things going */
4c7e38d5
 }
 
 /*
  * Save the uuencoded part of the file as it is read in since there's no need
  * to include it in the parse tree. Saves memory and parse time.
  * Return < 0 for failure
  */
288057e9
 int uudecodeFile(message *m, const char *firstline, const char *dir, fmap_t *map, size_t *at)
4c7e38d5
 {
288057e9
     fileblob *fb;
     char buffer[RFC2821LENGTH + 1];
     char *filename = cli_strtok(firstline, 2, " ");
4c7e38d5
 
288057e9
     if (filename == NULL)
         return -1;
4c7e38d5
 
288057e9
     fb = fileblobCreate();
     if (fb == NULL) {
         free(filename);
         return -1;
     }
4c7e38d5
 
288057e9
     fileblobSetFilename(fb, dir, filename);
     cli_dbgmsg("uudecode %s\n", filename);
     free(filename);
4c7e38d5
 
288057e9
     while (fmap_gets(map, buffer, at, sizeof(buffer) - 1)) {
         unsigned char data[1024];
         const unsigned char *uptr;
         size_t len;
4c7e38d5
 
288057e9
         cli_chomp(buffer);
         if (strcasecmp(buffer, "end") == 0)
             break;
         if (buffer[0] == '\0')
             break;
4c7e38d5
 
288057e9
         uptr = decodeLine(m, UUENCODE, buffer, data, sizeof(data));
         if (uptr == NULL)
             break;
4c7e38d5
 
288057e9
         len = (size_t)(uptr - data);
         if ((len > 62) || (len == 0))
             break;
4c7e38d5
 
288057e9
         if (fileblobAddData(fb, data, len) < 0)
             break;
     }
4c7e38d5
 
288057e9
     fileblobDestroy(fb);
4c7e38d5
 
288057e9
     return 1;
4c7e38d5
 }