Randomise extracted file names from tar file

git-svn: trunk@832
remotes/push_mirror/metadata
Nigel Horne 22 years ago
parent 95fb46e5ca
commit bb3fdd1ba7
  1. 48
      clamav-devel/libclamav/blob.c
  2. 1
      clamav-devel/libclamav/blob.h
  3. 112
      clamav-devel/libclamav/untar.c

@ -16,6 +16,9 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Log: blob.c,v $
* Revision 1.21 2004/09/06 08:34:47 nigelhorne
* Randomise extracted file names from tar file
*
* Revision 1.20 2004/08/30 11:35:45 nigelhorne
* Now compiles on AIX and OSF
*
@ -62,7 +65,7 @@
* Change LOG to Log
*
*/
static char const rcsid[] = "$Id: blob.c,v 1.20 2004/08/30 11:35:45 nigelhorne Exp $";
static char const rcsid[] = "$Id: blob.c,v 1.21 2004/09/06 08:34:47 nigelhorne Exp $";
#if HAVE_CONFIG_H
#include "clamav-config.h"
@ -165,27 +168,15 @@ blobSetFilename(blob *b, const char *dir, const char *filename)
assert(b->magic == BLOB);
assert(filename != NULL);
cli_dbgmsg("blobSetFilename: %s\n", filename);
if(b->name)
free(b->name);
b->name = strdup(filename);
if(b->name) {
char *ptr;
for(ptr = b->name; *ptr; ptr++) {
#ifdef C_DARWIN
*ptr &= '\177';
#endif
#if defined(MSDOS) || defined(C_CYGWIN) || defined(WIN32)
if(strchr("/*?<>|\"+=,;: ", *ptr))
#else
if(*ptr == '/')
#endif
*ptr = '_';
}
}
b->name = strdup(filename);
cli_dbgmsg("blobSetFilename: %s\n", filename);
if(b->name)
sanitiseName(b->name);
}
const char *
@ -470,3 +461,24 @@ fileblobGetFilename(const fileblob *fb)
{
return blobGetFilename(&(fb->b));
}
/*
* Different operating systems allow different characters in their filenames
*/
void
sanitiseName(char *name)
{
while(*name) {
#ifdef C_DARWIN
*name &= '\177';
#endif
#if defined(MSDOS) || defined(C_CYGWIN) || defined(WIN32)
if(strchr("/*?<>|\"+=,;: ", *name))
#else
if(*name == '/')
#endif
*name = '_';
name++;
}
}

@ -60,5 +60,6 @@ void fileblobDestroy(fileblob *fb);
void fileblobSetFilename(fileblob *fb, const char *dir, const char *filename);
const char *fileblobGetFilename(const fileblob *fb);
void fileblobAddData(fileblob *fb, const unsigned char *data, size_t len);
void sanitiseName(char *name);
#endif /*_BLOB_H*/

@ -15,11 +15,14 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Some of this code is based on minitar.c which is in the public domain.
* Much of this code is based on minitar.c which is in the public domain.
* Author: Charles G. Waldman (cgw@pgt.com), Aug 4 1998
*
* Change History:
* $Log: untar.c,v $
* Revision 1.3 2004/09/06 08:34:47 nigelhorne
* Randomise extracted file names from tar file
*
* Revision 1.2 2004/09/05 18:58:21 nigelhorne
* Extract files completed
*
@ -27,22 +30,25 @@
* First draft
*
*/
static char const rcsid[] = "$Id: untar.c,v 1.2 2004/09/05 18:58:21 nigelhorne Exp $";
static char const rcsid[] = "$Id: untar.c,v 1.3 2004/09/06 08:34:47 nigelhorne Exp $";
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/param.h> /* for NAME_MAX */
#include "clamav.h"
#include "others.h"
#include "untar.h"
#include "blob.h"
#define BLOCKSIZE 512
#define MAXNAMELEN 1024
static
int octal(const char *str)
static int
octal(const char *str)
{
int ret = -1;
@ -55,13 +61,12 @@ cli_untar(const char *dir, int desc)
{
int size = 0;
int in_block = 0;
int directory = 0;
char fullname[NAME_MAX + 1];
FILE *outfile = (FILE*)0;
cli_dbgmsg("In untar(%s, %d)\n", dir ? dir : "", desc);
for(;;) {
char fullname[MAXNAMELEN];
char block[BLOCKSIZE];
const int nread = read(desc, block, sizeof(block));
@ -74,9 +79,20 @@ cli_untar(const char *dir, int desc)
}
if(!in_block) {
char magic[7];
char name[101];
char type;
char *suffix;
size_t suffixLen = 0;
int fd, directory;
char magic[7], name[101], osize[13];
if(outfile) {
if(fclose(outfile)) {
cli_errmsg("cli_untar: cannot close file %s\n",
fullname);
return CL_EIO;
}
outfile = (FILE*)0;
}
if(block[0] == '\0') /* We're done */
break;
@ -88,10 +104,6 @@ cli_untar(const char *dir, int desc)
return CL_EDSIG;
}
strncpy(name, block, 100);
name[100] = '\0';
sprintf(fullname, "%s/%s", dir, name);
cli_dbgmsg("cli_untar: extracting %s\n", fullname);
type = block[156];
switch(type) {
@ -109,33 +121,59 @@ cli_untar(const char *dir, int desc)
if(directory)
continue;
else { /*file */
char osize[13];
in_block = 1;
if(outfile) {
if(fclose(outfile)) {
cli_errmsg("cli_untar: cannot close file %s\n",
fullname);
return CL_EIO;
}
outfile = (FILE*)0;
}
if(!(outfile = fopen(fullname,"wb"))) {
cli_errmsg("cli_untar: cannot create file %s\n",
fullname);
return CL_ETMPFILE;
}
strncpy(name, block, 100);
name[100] = '\0';
strncpy(osize, block+124, 12);
osize[12] = '\0';
size = octal(osize);
if(size < 0){
cli_errmsg("Invalid size in tar header\n");
return CL_EDSIG;
/*
* see also fileblobSetFilename()
* TODO: check if the suffix needs to be put back
*/
sanitiseName(name);
suffix = strrchr(name, '.');
if(suffix == NULL)
suffix = "";
else {
suffixLen = strlen(suffix);
if(suffixLen > 4) {
/* Found a full stop which isn't a suffix */
suffix = "";
suffixLen = 0;
}
}
snprintf(fullname, sizeof(fullname) - 1 - suffixLen, "%s/%.*sXXXXXX", dir,
(int)(sizeof(fullname) - 9 - suffixLen - strlen(dir)), name);
#if defined(C_LINUX) || defined(C_BSD) || defined(HAVE_MKSTEMP) || defined(C_SOLARIS) || defined(C_CYGWIN)
fd = mkstemp(fullname);
#else
(void)mktemp(fullname);
fd = open(fullname, O_WRONLY|O_CREAT|O_EXCL|O_TRUNC|O_BINARY, 0600);
#endif
if(fd < 0) {
cli_errmsg("Can't create temporary file %s: %s\n", fullname, strerror(errno));
cli_dbgmsg("%lu %d %d\n", suffixLen, sizeof(fullname), strlen(fullname));
return CL_ETMPFILE;
}
cli_dbgmsg("cli_untar: extracting %s\n", fullname);
in_block = 1;
if((outfile = fdopen(fd, "wb")) == NULL) {
cli_errmsg("cli_untar: cannot create file %s\n",
fullname);
close(fd);
return CL_ETMPFILE;
}
strncpy(osize, block+124, 12);
osize[12] = '\0';
size = octal(osize);
if(size < 0){
cli_errmsg("Invalid size in tar header\n");
fclose(outfile);
return CL_EDSIG;
}
} else { /* write or continue writing file contents */
const int nbytes = size>512? 512:size;
const int nwritten = fwrite(block, 1, nbytes, outfile);
@ -149,5 +187,7 @@ cli_untar(const char *dir, int desc)
in_block = 0;
}
}
if(outfile)
fclose(outfile);
return CL_CLEAN;
}

Loading…
Cancel
Save