mirror of
https://bitbucket.org/jsuto/piler.git
synced 2024-12-24 19:10:13 +01:00
restructured the pilerget utility
This commit is contained in:
parent
05c379a163
commit
94660cf32f
2
configure
vendored
2
configure
vendored
@ -4147,7 +4147,7 @@ echo; echo
|
|||||||
|
|
||||||
CFLAGS="$static -O2 -Wall -g"
|
CFLAGS="$static -O2 -Wall -g"
|
||||||
LIBS="$antispam_libs $sunos_libs "
|
LIBS="$antispam_libs $sunos_libs "
|
||||||
OBJS="dirs.o misc.o counters.o cfg.o sig.o decoder.o list.o parser.o parser_utils.o rules.o session.o message.o attachment.o digest.o store.o tai.o $objs"
|
OBJS="dirs.o misc.o counters.o cfg.o sig.o decoder.o list.o parser.o parser_utils.o rules.o session.o message.o attachment.o digest.o store.o archive.o tai.o $objs"
|
||||||
|
|
||||||
ac_config_files="$ac_config_files Makefile src/Makefile etc/Makefile"
|
ac_config_files="$ac_config_files Makefile src/Makefile etc/Makefile"
|
||||||
|
|
||||||
|
@ -271,7 +271,7 @@ echo; echo
|
|||||||
|
|
||||||
CFLAGS="$static -O2 -Wall -g"
|
CFLAGS="$static -O2 -Wall -g"
|
||||||
LIBS="$antispam_libs $sunos_libs "
|
LIBS="$antispam_libs $sunos_libs "
|
||||||
OBJS="dirs.o misc.o counters.o cfg.o sig.o decoder.o list.o parser.o parser_utils.o rules.o session.o message.o attachment.o digest.o store.o tai.o $objs"
|
OBJS="dirs.o misc.o counters.o cfg.o sig.o decoder.o list.o parser.o parser_utils.o rules.o session.o message.o attachment.o digest.o store.o archive.o tai.o $objs"
|
||||||
|
|
||||||
AC_CONFIG_FILES([Makefile src/Makefile etc/Makefile])
|
AC_CONFIG_FILES([Makefile src/Makefile etc/Makefile])
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
|
48
etc/Makefile
48
etc/Makefile
@ -1,48 +0,0 @@
|
|||||||
SHELL = /bin/bash
|
|
||||||
|
|
||||||
prefix = /usr/local
|
|
||||||
exec_prefix = ${prefix}
|
|
||||||
bindir = ${exec_prefix}/bin
|
|
||||||
sbindir = ${exec_prefix}/sbin
|
|
||||||
includedir = ${prefix}/include
|
|
||||||
libdir = ${exec_prefix}/lib
|
|
||||||
libexecdir = ${exec_prefix}/libexec
|
|
||||||
srcdir = .
|
|
||||||
sysconfdir = ${prefix}/etc
|
|
||||||
mandir = ${datarootdir}/man
|
|
||||||
datarootdir = ${prefix}/share
|
|
||||||
localstatedir = /var
|
|
||||||
|
|
||||||
CC = gcc
|
|
||||||
CFLAGS = -O2 -Wall -g
|
|
||||||
DEFS = -DHAVE_MYSQL -D_GNU_SOURCE -DHAVE_ANTISPAM -DUSERS_IN_MYSQL -DHAVE_USERS -DNEED_MYSQL
|
|
||||||
INCDIR = -I. -I../.. -I../../src -I/usr/include/mysql -DBIG_JOINS=1 -fno-strict-aliasing -DUNIV_LINUX -DUNIV_LINUX
|
|
||||||
LIBDIR = -L. -L../../src
|
|
||||||
LIBS = -lm -ldl -rdynamic -L/usr/lib/mysql -lmysqlclient_r
|
|
||||||
LDAP_LIBS =
|
|
||||||
CLAPF_USER = clapf
|
|
||||||
CLAPF_GROUP = `id -gn $(CLAPF_USER)`
|
|
||||||
|
|
||||||
INSTALL = /usr/bin/install -c
|
|
||||||
|
|
||||||
all:
|
|
||||||
sed -e 's%pidfile=.*%pidfile=$(localstatedir)/run/clapf/clapf.pid%g' \
|
|
||||||
-e 's%sqlite3=.*%sqlite3=$(localstatedir)/lib/clapf/data/tokens.sdb%g' \
|
|
||||||
-e 's%workdir=.*%workdir=$(localstatedir)/spool/clapf/tmp%g' \
|
|
||||||
-e 's%queuedir=.*%queuedir=$(localstatedir)/lib/clapf/queue%g' \
|
|
||||||
-e 's%mydbfile=.*%mydbfile=$(localstatedir)/lib/clapf/tokens.mydb%g' < $(srcdir)/example.conf > $(srcdir)/clapf.conf
|
|
||||||
|
|
||||||
sed -e 's%LOCALSTATEDIR%$(localstatedir)%g' \
|
|
||||||
-e 's%LIBEXECDIR%$(libexecdir)%g' \
|
|
||||||
-e 's%SYSCONFDIR%$(sysconfdir)%g' \
|
|
||||||
-e 's%SBINDIR%$(sbindir)%g' \
|
|
||||||
-e 's%DATAROOTDIR%$(datarootdir)%g' < $(srcdir)/cron.jobs.in > $(srcdir)/cron.jobs
|
|
||||||
|
|
||||||
install:
|
|
||||||
if [ ! -f "$(DESTDIR)$(sysconfdir)/clapf.conf" ]; then $(INSTALL) -m 0640 $(srcdir)/clapf.conf $(DESTDIR)$(sysconfdir)/clapf.conf; chgrp $(CLAPF_GROUP) $(DESTDIR)$(sysconfdir)/clapf.conf; fi
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f clapf.conf cron.jobs
|
|
||||||
|
|
||||||
distclean: clean
|
|
||||||
rm -f Makefile
|
|
@ -48,8 +48,8 @@ libpiler.a: $(OBJS) $(MYSQL_OBJS)
|
|||||||
ln -sf libpiler.so.$(LIBPILER_VERSION) libpiler.so.$(PILER_VERSION)
|
ln -sf libpiler.so.$(LIBPILER_VERSION) libpiler.so.$(PILER_VERSION)
|
||||||
|
|
||||||
|
|
||||||
pilerget: pilerget.c cfg.o misc.o tai.o store.o attachment.o digest.o
|
pilerget: pilerget.c libpiler.a
|
||||||
$(CC) $(CFLAGS) $(INCDIR) $(DEFS) -o $@ $^ $(LIBS) $(LIBDIR)
|
$(CC) $(CFLAGS) $(INCDIR) $(DEFS) -o $@ $^ -lpiler $(LIBS) $(LIBDIR)
|
||||||
|
|
||||||
pilerimport: pilerimport.c libpiler.a
|
pilerimport: pilerimport.c libpiler.a
|
||||||
$(CC) $(CFLAGS) $(INCDIR) $(DEFS) -o $@ $^ -lpiler $(LIBS) $(LIBDIR)
|
$(CC) $(CFLAGS) $(INCDIR) $(DEFS) -o $@ $^ -lpiler $(LIBS) $(LIBDIR)
|
||||||
|
263
src/archive.c
Normal file
263
src/archive.c
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
/*
|
||||||
|
* archive.c, SJ
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <locale.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <openssl/blowfish.h>
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
#include <zlib.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <piler.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void zerr(int ret){
|
||||||
|
|
||||||
|
fputs("zpipe: ", stderr);
|
||||||
|
|
||||||
|
switch (ret) {
|
||||||
|
case Z_ERRNO:
|
||||||
|
fputs("I/O error\n", stderr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Z_STREAM_ERROR:
|
||||||
|
fputs("invalid compression level\n", stderr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case Z_DATA_ERROR:
|
||||||
|
fputs("invalid or incomplete deflate data\n", stderr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Z_MEM_ERROR:
|
||||||
|
fputs("out of memory\n", stderr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Z_VERSION_ERROR:
|
||||||
|
fputs("zlib version mismatch!\n", stderr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int inf(unsigned char *in, int len, int mode, char **buffer, FILE *dest){
|
||||||
|
int ret, pos=0;
|
||||||
|
unsigned have;
|
||||||
|
z_stream strm;
|
||||||
|
char *new_ptr;
|
||||||
|
unsigned char out[REALLYBIGBUFSIZE];
|
||||||
|
|
||||||
|
/* allocate inflate state */
|
||||||
|
|
||||||
|
strm.zalloc = Z_NULL;
|
||||||
|
strm.zfree = Z_NULL;
|
||||||
|
strm.opaque = Z_NULL;
|
||||||
|
strm.avail_in = 0;
|
||||||
|
strm.next_in = Z_NULL;
|
||||||
|
ret = inflateInit(&strm);
|
||||||
|
|
||||||
|
|
||||||
|
if(ret != Z_OK) return ret;
|
||||||
|
|
||||||
|
strm.avail_in = len;
|
||||||
|
strm.next_in = in;
|
||||||
|
|
||||||
|
if(mode == WRITE_TO_BUFFER){
|
||||||
|
*buffer = malloc(REALLYBIGBUFSIZE);
|
||||||
|
if(!*buffer) return Z_MEM_ERROR;
|
||||||
|
memset(*buffer, 0, REALLYBIGBUFSIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
do {
|
||||||
|
strm.avail_out = REALLYBIGBUFSIZE;
|
||||||
|
strm.next_out = out;
|
||||||
|
ret = inflate(&strm, Z_NO_FLUSH);
|
||||||
|
|
||||||
|
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
|
||||||
|
switch (ret) {
|
||||||
|
case Z_NEED_DICT:
|
||||||
|
ret = Z_DATA_ERROR; /* and fall through */
|
||||||
|
case Z_DATA_ERROR:
|
||||||
|
case Z_MEM_ERROR:
|
||||||
|
(void)inflateEnd(&strm);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
have = REALLYBIGBUFSIZE - strm.avail_out;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* write the uncompressed result either to stdout
|
||||||
|
* or to the buffer
|
||||||
|
*/
|
||||||
|
|
||||||
|
if(mode == WRITE_TO_STDOUT){
|
||||||
|
if(fwrite(out, 1, have, dest) != have){
|
||||||
|
(void)inflateEnd(&strm);
|
||||||
|
return Z_ERRNO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
memcpy(*buffer+pos, out, have);
|
||||||
|
pos += have;
|
||||||
|
new_ptr = realloc(*buffer, pos+REALLYBIGBUFSIZE);
|
||||||
|
if(!new_ptr){
|
||||||
|
(void)inflateEnd(&strm);
|
||||||
|
return Z_MEM_ERROR;
|
||||||
|
}
|
||||||
|
*buffer = new_ptr;
|
||||||
|
memset(*buffer+pos, 0, REALLYBIGBUFSIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} while (strm.avail_out == 0);
|
||||||
|
|
||||||
|
|
||||||
|
(void)inflateEnd(&strm);
|
||||||
|
|
||||||
|
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int retrieve_file_from_archive(char *filename, int mode, char **buffer, FILE *dest, struct __config *cfg){
|
||||||
|
int rc=0, n, olen, tlen, len, fd=-1;
|
||||||
|
unsigned char *s=NULL, inbuf[REALLYBIGBUFSIZE];
|
||||||
|
struct stat st;
|
||||||
|
EVP_CIPHER_CTX ctx;
|
||||||
|
|
||||||
|
|
||||||
|
if(filename == NULL) return 1;
|
||||||
|
|
||||||
|
|
||||||
|
fd = open(filename, O_RDONLY);
|
||||||
|
if(fd == -1){
|
||||||
|
printf("error reading file: %s\n", filename);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(fstat(fd, &st)){
|
||||||
|
printf("cannot fstat() on %s\n", filename);
|
||||||
|
close(fd);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EVP_CIPHER_CTX_init(&ctx);
|
||||||
|
EVP_DecryptInit_ex(&ctx, EVP_bf_cbc(), NULL, cfg->key, cfg->iv);
|
||||||
|
|
||||||
|
len = st.st_size+EVP_MAX_BLOCK_LENGTH;
|
||||||
|
|
||||||
|
s = malloc(len);
|
||||||
|
|
||||||
|
if(!s){
|
||||||
|
printf("malloc()\n");
|
||||||
|
goto CLEANUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
tlen = 0;
|
||||||
|
|
||||||
|
while((n = read(fd, inbuf, sizeof(inbuf)))){
|
||||||
|
|
||||||
|
if(!EVP_DecryptUpdate(&ctx, s+tlen, &olen, inbuf, n)){
|
||||||
|
printf("EVP_DecryptUpdate()\n");
|
||||||
|
goto CLEANUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
tlen += olen;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(EVP_DecryptFinal(&ctx, s + tlen, &olen) != 1){
|
||||||
|
printf("EVP_DecryptFinal()\n");
|
||||||
|
goto CLEANUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
tlen += olen;
|
||||||
|
|
||||||
|
|
||||||
|
rc = inf(s, tlen, mode, buffer, dest);
|
||||||
|
if(rc != Z_OK) zerr(rc);
|
||||||
|
|
||||||
|
|
||||||
|
CLEANUP:
|
||||||
|
if(fd != -1) close(fd);
|
||||||
|
if(s) free(s);
|
||||||
|
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int retrieve_email_from_archive(struct session_data *sdata, FILE *dest, struct __config *cfg){
|
||||||
|
int i, rc, attachments;
|
||||||
|
char *buffer=NULL, *saved_buffer, *p, filename[SMALLBUFSIZE], pointer[SMALLBUFSIZE];
|
||||||
|
struct ptr_array ptr_arr[MAX_ATTACHMENTS];
|
||||||
|
|
||||||
|
if(strlen(sdata->ttmpfile) != RND_STR_LEN){
|
||||||
|
printf("invalid piler-id: %s\n", sdata->ttmpfile);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
attachments = query_attachments(sdata, &ptr_arr[0], cfg);
|
||||||
|
|
||||||
|
if(attachments == -1){
|
||||||
|
printf("problem querying the attachment of %s\n", sdata->ttmpfile);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(filename, sizeof(filename)-1, "%s/%c%c/%c%c/%c%c/%s.m", cfg->queuedir, *(sdata->ttmpfile+RND_STR_LEN-6), *(sdata->ttmpfile+RND_STR_LEN-5), *(sdata->ttmpfile+RND_STR_LEN-4), *(sdata->ttmpfile+RND_STR_LEN-3), *(sdata->ttmpfile+RND_STR_LEN-2), *(sdata->ttmpfile+RND_STR_LEN-1), sdata->ttmpfile);
|
||||||
|
|
||||||
|
if(attachments == 0){
|
||||||
|
rc = retrieve_file_from_archive(filename, WRITE_TO_STDOUT, &buffer, dest, cfg);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rc = retrieve_file_from_archive(filename, WRITE_TO_BUFFER, &buffer, dest, cfg);
|
||||||
|
|
||||||
|
if(buffer){
|
||||||
|
saved_buffer = buffer;
|
||||||
|
|
||||||
|
for(i=1; i<=attachments; i++){
|
||||||
|
snprintf(pointer, sizeof(pointer)-1, "ATTACHMENT_POINTER_%s.a%d_XXX_PILER", sdata->ttmpfile, i);
|
||||||
|
|
||||||
|
p = strstr(buffer, pointer);
|
||||||
|
if(p){
|
||||||
|
*p = '\0';
|
||||||
|
fwrite(buffer, 1, p - buffer, dest);
|
||||||
|
buffer = p + strlen(pointer);
|
||||||
|
|
||||||
|
if(strlen(ptr_arr[i].piler_id) == RND_STR_LEN){
|
||||||
|
snprintf(filename, sizeof(filename)-1, "%s/%c%c/%c%c/%c%c/%s.a%d", cfg->queuedir, ptr_arr[i].piler_id[RND_STR_LEN-6], ptr_arr[i].piler_id[RND_STR_LEN-5], ptr_arr[i].piler_id[RND_STR_LEN-4], ptr_arr[i].piler_id[RND_STR_LEN-3], ptr_arr[i].piler_id[RND_STR_LEN-2], ptr_arr[i].piler_id[RND_STR_LEN-1], ptr_arr[i].piler_id, ptr_arr[i].attachment_id);
|
||||||
|
|
||||||
|
rc = retrieve_file_from_archive(filename, WRITE_TO_STDOUT, NULL, dest, cfg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if(buffer){
|
||||||
|
fwrite(buffer, 1, strlen(buffer), dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = saved_buffer;
|
||||||
|
free(buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -31,6 +31,7 @@
|
|||||||
#define MAXBUFSIZE 8192
|
#define MAXBUFSIZE 8192
|
||||||
#define SMALLBUFSIZE 512
|
#define SMALLBUFSIZE 512
|
||||||
#define BIGBUFSIZE 65536
|
#define BIGBUFSIZE 65536
|
||||||
|
#define REALLYBIGBUFSIZE 524288
|
||||||
#define TINYBUFSIZE 128
|
#define TINYBUFSIZE 128
|
||||||
#define MAXVAL 256
|
#define MAXVAL 256
|
||||||
#define RANDOM_POOL "/dev/urandom"
|
#define RANDOM_POOL "/dev/urandom"
|
||||||
@ -99,5 +100,8 @@
|
|||||||
#define DIRECTION_OUTGOING 2
|
#define DIRECTION_OUTGOING 2
|
||||||
#define DIRECTION_INTERNAL_AND_OUTGOING 3
|
#define DIRECTION_INTERNAL_AND_OUTGOING 3
|
||||||
|
|
||||||
|
#define WRITE_TO_STDOUT 0
|
||||||
|
#define WRITE_TO_BUFFER 1
|
||||||
|
|
||||||
#endif /* _CONFIG_H */
|
#endif /* _CONFIG_H */
|
||||||
|
|
||||||
|
@ -45,5 +45,8 @@ void check_and_create_directories(struct __config *cfg, uid_t uid, gid_t gid);
|
|||||||
|
|
||||||
void update_counters(struct session_data *sdata, struct __data *data, struct __counters *counters, struct __config *cfg);
|
void update_counters(struct session_data *sdata, struct __data *data, struct __counters *counters, struct __config *cfg);
|
||||||
|
|
||||||
|
int retrieve_email_from_archive(struct session_data *sdata, FILE *dest, struct __config *cfg);
|
||||||
|
|
||||||
|
|
||||||
#endif /* _PILER_H */
|
#endif /* _PILER_H */
|
||||||
|
|
||||||
|
254
src/pilerget.c
254
src/pilerget.c
@ -13,263 +13,9 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include <openssl/blowfish.h>
|
|
||||||
#include <openssl/evp.h>
|
|
||||||
#include <zlib.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <piler.h>
|
#include <piler.h>
|
||||||
|
|
||||||
|
|
||||||
#define WRITE_TO_STDOUT 0
|
|
||||||
#define WRITE_TO_BUFFER 1
|
|
||||||
#define REALLYBIGBUFSIZE 524288
|
|
||||||
|
|
||||||
int fd=-1;
|
|
||||||
EVP_CIPHER_CTX ctx;
|
|
||||||
unsigned char *s=NULL;
|
|
||||||
|
|
||||||
|
|
||||||
void clean_exit(){
|
|
||||||
if(s) free(s);
|
|
||||||
|
|
||||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
|
||||||
|
|
||||||
if(fd != -1) close(fd);
|
|
||||||
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void zerr(int ret){
|
|
||||||
fputs("zpipe: ", stderr);
|
|
||||||
switch (ret) {
|
|
||||||
case Z_ERRNO:
|
|
||||||
if (ferror(stdin))
|
|
||||||
fputs("error reading stdin\n", stderr);
|
|
||||||
if (ferror(stdout))
|
|
||||||
fputs("error writing stdout\n", stderr);
|
|
||||||
break;
|
|
||||||
case Z_STREAM_ERROR:
|
|
||||||
fputs("invalid compression level\n", stderr);
|
|
||||||
break;
|
|
||||||
case Z_DATA_ERROR:
|
|
||||||
fputs("invalid or incomplete deflate data\n", stderr);
|
|
||||||
break;
|
|
||||||
case Z_MEM_ERROR:
|
|
||||||
fputs("out of memory\n", stderr);
|
|
||||||
break;
|
|
||||||
case Z_VERSION_ERROR:
|
|
||||||
fputs("zlib version mismatch!\n", stderr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int inf(unsigned char *in, int len, int mode, char **buffer, FILE *dest){
|
|
||||||
int ret, pos=0;
|
|
||||||
unsigned have;
|
|
||||||
z_stream strm;
|
|
||||||
char *new_ptr;
|
|
||||||
unsigned char out[REALLYBIGBUFSIZE];
|
|
||||||
|
|
||||||
/* allocate inflate state */
|
|
||||||
strm.zalloc = Z_NULL;
|
|
||||||
strm.zfree = Z_NULL;
|
|
||||||
strm.opaque = Z_NULL;
|
|
||||||
strm.avail_in = 0;
|
|
||||||
strm.next_in = Z_NULL;
|
|
||||||
ret = inflateInit(&strm);
|
|
||||||
|
|
||||||
|
|
||||||
if(ret != Z_OK) return ret;
|
|
||||||
|
|
||||||
strm.avail_in = len;
|
|
||||||
strm.next_in = in;
|
|
||||||
|
|
||||||
if(mode == WRITE_TO_BUFFER){
|
|
||||||
*buffer = malloc(REALLYBIGBUFSIZE);
|
|
||||||
if(!*buffer) return Z_MEM_ERROR;
|
|
||||||
memset(*buffer, 0, REALLYBIGBUFSIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
do {
|
|
||||||
strm.avail_out = REALLYBIGBUFSIZE;
|
|
||||||
strm.next_out = out;
|
|
||||||
ret = inflate(&strm, Z_NO_FLUSH);
|
|
||||||
|
|
||||||
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
|
|
||||||
switch (ret) {
|
|
||||||
case Z_NEED_DICT:
|
|
||||||
ret = Z_DATA_ERROR; /* and fall through */
|
|
||||||
case Z_DATA_ERROR:
|
|
||||||
case Z_MEM_ERROR:
|
|
||||||
(void)inflateEnd(&strm);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
have = REALLYBIGBUFSIZE - strm.avail_out;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* write the uncompressed result either to stdout
|
|
||||||
* or to the buffer
|
|
||||||
*/
|
|
||||||
|
|
||||||
if(mode == WRITE_TO_STDOUT){
|
|
||||||
if(fwrite(out, 1, have, dest) != have){
|
|
||||||
(void)inflateEnd(&strm);
|
|
||||||
return Z_ERRNO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
memcpy(*buffer+pos, out, have);
|
|
||||||
pos += have;
|
|
||||||
new_ptr = realloc(*buffer, pos+REALLYBIGBUFSIZE);
|
|
||||||
if(!new_ptr){
|
|
||||||
(void)inflateEnd(&strm);
|
|
||||||
return Z_MEM_ERROR;
|
|
||||||
}
|
|
||||||
*buffer = new_ptr;
|
|
||||||
memset(*buffer+pos, 0, REALLYBIGBUFSIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} while (strm.avail_out == 0);
|
|
||||||
|
|
||||||
|
|
||||||
(void)inflateEnd(&strm);
|
|
||||||
|
|
||||||
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int retrieve_file_from_archive(char *filename, int mode, char **buffer, FILE *dest, struct __config *cfg){
|
|
||||||
int rc=0, n, olen, tlen, len;
|
|
||||||
unsigned char inbuf[REALLYBIGBUFSIZE];
|
|
||||||
struct stat st;
|
|
||||||
|
|
||||||
|
|
||||||
if(filename == NULL) return 1;
|
|
||||||
|
|
||||||
|
|
||||||
fd = open(filename, O_RDONLY);
|
|
||||||
if(fd == -1){
|
|
||||||
printf("error reading file: %s\n", filename);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if(fstat(fd, &st)){
|
|
||||||
perror("fstat()");
|
|
||||||
close(fd);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
EVP_CIPHER_CTX_init(&ctx);
|
|
||||||
EVP_DecryptInit_ex(&ctx, EVP_bf_cbc(), NULL, cfg->key, cfg->iv);
|
|
||||||
|
|
||||||
len = st.st_size+EVP_MAX_BLOCK_LENGTH;
|
|
||||||
|
|
||||||
s = malloc(len);
|
|
||||||
|
|
||||||
if(!s){
|
|
||||||
perror("malloc");
|
|
||||||
clean_exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
tlen = 0;
|
|
||||||
|
|
||||||
while((n = read(fd, inbuf, sizeof(inbuf)))){
|
|
||||||
|
|
||||||
if(!EVP_DecryptUpdate(&ctx, s+tlen, &olen, inbuf, n)){
|
|
||||||
printf("EVP_DecryptUpdate()\n");
|
|
||||||
clean_exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
tlen += olen;
|
|
||||||
}
|
|
||||||
|
|
||||||
close(fd);
|
|
||||||
|
|
||||||
if(EVP_DecryptFinal(&ctx, s + tlen, &olen) != 1){
|
|
||||||
printf("EVP_DecryptFinal()\n");
|
|
||||||
clean_exit();
|
|
||||||
}
|
|
||||||
|
|
||||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
|
||||||
|
|
||||||
tlen += olen;
|
|
||||||
|
|
||||||
|
|
||||||
rc = inf(s, tlen, mode, buffer, dest);
|
|
||||||
if(rc != Z_OK) zerr(rc);
|
|
||||||
|
|
||||||
|
|
||||||
if(s) free(s);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int retrieve_email_from_archive(struct session_data *sdata, FILE *dest, struct __config *cfg){
|
|
||||||
int i, rc, attachments;
|
|
||||||
char *buffer=NULL, *saved_buffer, *p, filename[SMALLBUFSIZE], pointer[SMALLBUFSIZE];
|
|
||||||
struct ptr_array ptr_arr[MAX_ATTACHMENTS];
|
|
||||||
|
|
||||||
if(strlen(sdata->ttmpfile) != RND_STR_LEN){
|
|
||||||
printf("invalid piler-id: %s\n", sdata->ttmpfile);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
attachments = query_attachments(sdata, &ptr_arr[0], cfg);
|
|
||||||
|
|
||||||
if(attachments == -1){
|
|
||||||
printf("problem querying the attachment of %s\n", sdata->ttmpfile);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(filename, sizeof(filename)-1, "%s/%c%c/%c%c/%c%c/%s.m", cfg->queuedir, *(sdata->ttmpfile+RND_STR_LEN-6), *(sdata->ttmpfile+RND_STR_LEN-5), *(sdata->ttmpfile+RND_STR_LEN-4), *(sdata->ttmpfile+RND_STR_LEN-3), *(sdata->ttmpfile+RND_STR_LEN-2), *(sdata->ttmpfile+RND_STR_LEN-1), sdata->ttmpfile);
|
|
||||||
|
|
||||||
if(attachments == 0){
|
|
||||||
rc = retrieve_file_from_archive(filename, WRITE_TO_STDOUT, &buffer, dest, cfg);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
rc = retrieve_file_from_archive(filename, WRITE_TO_BUFFER, &buffer, dest, cfg);
|
|
||||||
|
|
||||||
if(buffer){
|
|
||||||
saved_buffer = buffer;
|
|
||||||
|
|
||||||
for(i=1; i<=attachments; i++){
|
|
||||||
snprintf(pointer, sizeof(pointer)-1, "ATTACHMENT_POINTER_%s.a%d_XXX_PILER", sdata->ttmpfile, i);
|
|
||||||
|
|
||||||
p = strstr(buffer, pointer);
|
|
||||||
if(p){
|
|
||||||
*p = '\0';
|
|
||||||
fwrite(buffer, 1, p - buffer, dest);
|
|
||||||
buffer = p + strlen(pointer);
|
|
||||||
|
|
||||||
if(strlen(ptr_arr[i].piler_id) == RND_STR_LEN){
|
|
||||||
snprintf(filename, sizeof(filename)-1, "%s/%c%c/%c%c/%c%c/%s.a%d", cfg->queuedir, ptr_arr[i].piler_id[RND_STR_LEN-6], ptr_arr[i].piler_id[RND_STR_LEN-5], ptr_arr[i].piler_id[RND_STR_LEN-4], ptr_arr[i].piler_id[RND_STR_LEN-3], ptr_arr[i].piler_id[RND_STR_LEN-2], ptr_arr[i].piler_id[RND_STR_LEN-1], ptr_arr[i].piler_id, ptr_arr[i].attachment_id);
|
|
||||||
|
|
||||||
rc = retrieve_file_from_archive(filename, WRITE_TO_STDOUT, NULL, dest, cfg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if(buffer){
|
|
||||||
fwrite(buffer, 1, strlen(buffer), dest);
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer = saved_buffer;
|
|
||||||
free(buffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint64 get_id_by_piler_id(struct session_data *sdata, char *digest, char *bodydigest, struct __config *cfg){
|
uint64 get_id_by_piler_id(struct session_data *sdata, char *digest, char *bodydigest, struct __config *cfg){
|
||||||
char s[SMALLBUFSIZE];
|
char s[SMALLBUFSIZE];
|
||||||
|
Loading…
Reference in New Issue
Block a user