/*
 *  Copyright (C) 2006 Sensory Networks, Inc.
 *	      (C) 2007 Tomasz Kojm <tkojm@clamav.net>
 *	      Written by Tomasz Kojm
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 *
 *  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
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *  MA 02110-1301, USA.
 */


#if HAVE_CONFIG_H
#include "clamav-config.h"
#endif

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#include "misc.h"
#include "output.h"
#include "cdiff.h"
#include "sha256.h"

#include "str.h"
#include "others.h"
#include "cvd.h"

#include "zlib.h"

#ifdef HAVE_GMP
#include "dsig.h"

#define PSS_NSTR "14783905874077467090262228516557917570254599638376203532031989214105552847269687489771975792123442185817287694951949800908791527542017115600501303394778618535864845235700041590056318230102449612217458549016089313306591388590790796515819654102320725712300822356348724011232654837503241736177907784198700834440681124727060540035754699658105895050096576226753008596881698828185652424901921668758326578462003247906470982092298106789657211905488986281078346361469524484829559560886227198091995498440676639639830463593211386055065360288422394053998134458623712540683294034953818412458362198117811990006021989844180721010947"
#define PSS_ESTR "100002053"
#define PSS_NBITS 2048
#define PSS_DIGEST_LENGTH 32
#endif /* HAVE_GMP */

struct cdiff_node {
    unsigned int lineno;
    char *str, *str2;
    struct cdiff_node *next;
};

struct cdiff_ctx {
    char *open_db;
    struct cdiff_node *add_start, *add_last;
    struct cdiff_node *del_start;
    struct cdiff_node *xchg_start;
};

struct cdiff_cmd {
    const char *name;
    unsigned short argc;
    int (*handler)(const char *, struct cdiff_ctx *);
};

static int cdiff_cmd_open(const char *cmdstr, struct cdiff_ctx *ctx);
static int cdiff_cmd_add(const char *cmdstr, struct cdiff_ctx *ctx);
static int cdiff_cmd_del(const char *cmdstr, struct cdiff_ctx *ctx);
static int cdiff_cmd_xchg(const char *cmdstr, struct cdiff_ctx *ctx);
static int cdiff_cmd_close(const char *cmdstr, struct cdiff_ctx *ctx);
static int cdiff_cmd_move(const char *cmdstr, struct cdiff_ctx *ctx);
static int cdiff_cmd_unlink(const char *cmdstr, struct cdiff_ctx *ctx);

static struct cdiff_cmd commands[] = {
    /* OPEN db_name */
    { "OPEN", 1, &cdiff_cmd_open },

    /* ADD newsig */
    { "ADD", 1, &cdiff_cmd_add },

    /* DEL line_no some_first_bytes */
    { "DEL", 2, &cdiff_cmd_del },

    /* XCHG line_no some_first_bytes_of_old_line new_line */
    { "XCHG", 3, &cdiff_cmd_xchg },

    /* CLOSE */
    { "CLOSE", 0, &cdiff_cmd_close },

    /* MOVE src_db dst_db start_line first_16b end_line first_16b */
    { "MOVE", 6, &cdiff_cmd_move },

    /* UNLINK db_name */
    { "UNLINK", 1, &cdiff_cmd_unlink },

    { NULL, 0, NULL }
};

static void cdiff_ctx_free(struct cdiff_ctx *ctx)
{
	struct cdiff_node *pt;


    if(ctx->open_db) {
	free(ctx->open_db);
	ctx->open_db = NULL;
    }

    while(ctx->add_start) {
	free(ctx->add_start->str);
	pt = ctx->add_start;
	ctx->add_start = ctx->add_start->next;
	free(pt);
    }
    ctx->add_last = NULL;

    while(ctx->del_start) {
	free(ctx->del_start->str);
	pt = ctx->del_start;
	ctx->del_start = ctx->del_start->next;
	free(pt);
    }

    while(ctx->xchg_start) {
	free(ctx->xchg_start->str);
	free(ctx->xchg_start->str2);
	pt = ctx->xchg_start;
	ctx->xchg_start = ctx->xchg_start->next;
	free(pt);
    }
}

static char *cdiff_token(const char *line, unsigned int token, unsigned int last)
{
	unsigned int counter = 0, i, j;
	char *buffer;


    for(i = 0; line[i] && counter != token; i++)
	if(line[i] == ' ')
	    counter++;

    if(!line[i])
	return NULL;

    if(last)
	return strdup(&line[i]);

    for(j = i; line[j]; j++)
	if(line[j] == ' ')
	    break;

    if(i == j)
	return NULL;

    buffer = malloc(j - i + 1);
    if(!buffer)
	return NULL;

    strncpy(buffer, line + i, j - i);
    buffer[j - i] = '\0';

    return buffer;
}

static int cdiff_cmd_open(const char *cmdstr, struct cdiff_ctx *ctx)
{
	char *db;
	unsigned int i;


    if(!(db = cdiff_token(cmdstr, 1, 1))) {
	logg("!cdiff_cmd_open: Can't get first argument\n");
	return -1;
    }

    if(ctx->open_db) {
	logg("!cdiff_cmd_open: %s not closed before opening %s\n", ctx->open_db, db);
	free(db);
	return -1;
    }

    for(i = 0; i < strlen(db); i++) {
	if((db[i] != '.' && !isalnum(db[i])) || strchr("/\\", db[i])) {
	    logg("!cdiff_cmd_open: Forbidden characters found in database name\n");
	    free(db);
	    return -1;
	}
    }

    ctx->open_db = db;
    return 0;
}

static int cdiff_cmd_add(const char *cmdstr, struct cdiff_ctx *ctx)
{
	char *sig;
	struct cdiff_node *new;


    if(!(sig = cdiff_token(cmdstr, 1, 1))) {
	logg("!cdiff_cmd_add: Can't get first argument\n");
	return -1;
    }

    new = (struct cdiff_node *) calloc(1, sizeof(struct cdiff_node));
    if(!new) {
	logg("!cdiff_cmd_add: Can't allocate memory for cdiff_node\n");
	free(sig);
	return -1;
    }
    new->str = sig;

    if(!ctx->add_last) {
	ctx->add_start = ctx->add_last = new;
    } else { 
	ctx->add_last->next = new;
	ctx->add_last = new;
    }

    return 0;
}

static int cdiff_cmd_del(const char *cmdstr, struct cdiff_ctx *ctx)
{
	char *arg;
	struct cdiff_node *pt, *last, *new;
	unsigned int lineno;


    if(!(arg = cdiff_token(cmdstr, 1, 0))) {
	logg("!cdiff_cmd_del: Can't get first argument\n");
	return -1;
    }
    lineno = (unsigned int) atoi(arg);
    free(arg);

    if(!(arg = cdiff_token(cmdstr, 2, 1))) {
	logg("!cdiff_cmd_del: Can't get second argument\n");
	return -1;
    }

    new = (struct cdiff_node *) calloc(1, sizeof(struct cdiff_node));
    if(!new) {
	logg("!cdiff_cmd_del: Can't allocate memory for cdiff_node\n");
	free(arg);
	return -1;
    }
    new->str = arg;
    new->lineno = lineno;

    if(!ctx->del_start) {

	ctx->del_start = new;

    } else { 

	if(lineno < ctx->del_start->lineno) {
	    new->next = ctx->del_start;
	    ctx->del_start = new;

	} else {
	    pt = ctx->del_start;

	    while(pt) {
		last = pt;
		if((pt->lineno < lineno) && (!pt->next || lineno < pt->next->lineno))
		    break;

		pt = pt->next;
	    }

	    new->next = last->next;
	    last->next = new;
	}
    }

    return 0;
}

static int cdiff_cmd_xchg(const char *cmdstr, struct cdiff_ctx *ctx)
{
	char *arg, *arg2;
	struct cdiff_node *pt, *last, *new;
	unsigned int lineno;


    if(!(arg = cdiff_token(cmdstr, 1, 0))) {
	logg("!cdiff_cmd_xchg: Can't get first argument\n");
	return -1;
    }
    lineno = (unsigned int) atoi(arg);
    free(arg);

    if(!(arg = cdiff_token(cmdstr, 2, 0))) {
	logg("!cdiff_cmd_xchg: Can't get second argument\n");
	return -1;
    }

    if(!(arg2 = cdiff_token(cmdstr, 3, 1))) {
	free(arg);
	logg("!cdiff_cmd_xchg: Can't get second argument\n");
	return -1;
    }

    new = (struct cdiff_node *) calloc(1, sizeof(struct cdiff_node));
    if(!new) {
	logg("!cdiff_cmd_xchg: Can't allocate memory for cdiff_node\n");
	free(arg);
	free(arg2);
	return -1;
    }
    new->str = arg;
    new->str2 = arg2;
    new->lineno = lineno;

    if(!ctx->xchg_start) {

	ctx->xchg_start = new;

    } else { 

	if(lineno < ctx->xchg_start->lineno) {
	    new->next = ctx->xchg_start;
	    ctx->xchg_start = new;

	} else {
	    pt = ctx->xchg_start;

	    while(pt) {
		last = pt;
		if((pt->lineno < lineno) && (!pt->next || lineno < pt->next->lineno))
		    break;

		pt = pt->next;
	    }

	    new->next = last->next;
	    last->next = new;
	}
    }

    return 0;
}

static int cdiff_cmd_close(const char *cmdstr, struct cdiff_ctx *ctx)
{
	struct cdiff_node *add, *del, *xchg;
	unsigned int lines = 0;
	char *tmp, line[1024];
	FILE *fh, *tmpfh;


    if(!ctx->open_db) {
	logg("!cdiff_cmd_close: No database to close\n");
	return -1;
    }

    add = ctx->add_start;
    del = ctx->del_start;
    xchg = ctx->xchg_start;

    if(del || xchg) {

	if(!(fh = fopen(ctx->open_db, "r"))) {
	    logg("!cdiff_cmd_close: Can't open file %s for reading\n", ctx->open_db);
	    return -1;
	}

	if(!(tmp = cli_gentemp("."))) {
	    logg("!cdiff_cmd_close: Can't generate temporary name\n");
	    fclose(fh);
	    return -1;
	}

	if(!(tmpfh = fopen(tmp, "w"))) {
	    logg("!cdiff_cmd_close: Can't open file %s for writing\n", tmp);
	    fclose(fh);
	    free(tmp);
	    return -1;
	}

	while(fgets(line, sizeof(line), fh)) {
	    lines++;

	    if(del && del->lineno == lines) {
		if(strncmp(line, del->str, strlen(del->str))) {
		    fclose(fh);
		    fclose(tmpfh);
		    unlink(tmp);
		    free(tmp);
		    logg("!cdiff_cmd_close: Can't apply DEL at line %d of %s\n", lines, ctx->open_db);
		    return -1;
		}

		del = del->next;
		continue;
	    }

	    if(xchg && xchg->lineno == lines) {
		if(strncmp(line, xchg->str, strlen(xchg->str))) {
		    fclose(fh);
		    fclose(tmpfh);
		    unlink(tmp);
		    free(tmp);
		    logg("!cdiff_cmd_close: Can't apply XCHG at line %d of %s\n", lines, ctx->open_db);
		    return -1;
		}

		if(fputs(xchg->str2, tmpfh) == EOF || fputc('\n', tmpfh) == EOF) {
		    fclose(fh);
		    fclose(tmpfh);
		    unlink(tmp);
		    logg("!cdiff_cmd_close: Can't write to %s\n", tmp);
		    free(tmp);
		    return -1;
		}
		xchg = xchg->next;
		continue;
	    }

	    if(fputs(line, tmpfh) == EOF) {
		fclose(fh);
		fclose(tmpfh);
		unlink(tmp);
		logg("!cdiff_cmd_close: Can't write to %s\n", tmp);
		free(tmp);
		return -1;
	    }
	}

	fclose(fh);
	fclose(tmpfh);

	if(del || xchg) {
	    logg("!cdiff_cmd_close: Not all DEL/XCHG have been executed\n");
	    unlink(tmp);
	    free(tmp);
	    return -1;
	}

	if(unlink(ctx->open_db) == -1) {
	    logg("!cdiff_cmd_close: Can't unlink %s\n", ctx->open_db);
	    unlink(tmp);
	    free(tmp);
	    return -1;
	}

	if(rename(tmp, ctx->open_db) == -1) {
	    logg("!cdiff_cmd_close: Can't rename %s to %s\n", tmp, ctx->open_db);
	    unlink(tmp);
	    free(tmp);
	    return -1;
	}

	free(tmp);
    }

    if(add) {

	if(!(fh = fopen(ctx->open_db, "a"))) {
	    logg("!cdiff_cmd_close: Can't open file %s for appending\n", ctx->open_db);
	    return -1;
	}

	while(add) {
	    if(fputs(add->str, fh) == EOF || fputc('\n', fh) == EOF) {
		fclose(fh);
		logg("!cdiff_cmd_close: Can't write to %s\n", ctx->open_db);
		return -1;
	    }
	    add = add->next;
	}

	fclose(fh);
    }

    cdiff_ctx_free(ctx);

    return 0;
}

static int cdiff_cmd_move(const char *cmdstr, struct cdiff_ctx *ctx)
{
	unsigned int lines = 0, start_line, end_line;
	char *arg, *srcdb, *dstdb, *tmpdb, line[1024], *start_str, *end_str;
	FILE *src, *dst, *tmp;


    if(ctx->open_db) {
	logg("!cdiff_cmd_move: Database %s is still open\n", ctx->open_db);
	return -1;
    }

    if(!(arg = cdiff_token(cmdstr, 3, 0))) {
	logg("!cdiff_cmd_move: Can't get third argument\n");
	return -1;
    }
    start_line = atoi(arg);
    free(arg);

    if(!(arg = cdiff_token(cmdstr, 5, 0))) {
	logg("!cdiff_cmd_move: Can't get fifth argument\n");
	return -1;
    }
    end_line = atoi(arg);
    free(arg);

    if(end_line < start_line) {
	logg("!cdiff_cmd_move: end_line < start_line\n");
	return -1;
    }

    if(!(start_str = cdiff_token(cmdstr, 4, 0))) {
	logg("!cdiff_cmd_move: Can't get fourth argument\n");
	return -1;
    }

    if(!(end_str = cdiff_token(cmdstr, 6, 0))) {
	logg("!cdiff_cmd_move: Can't get sixth argument\n");
	free(start_str);
	return -1;
    }

    if(!(srcdb = cdiff_token(cmdstr, 1, 0))) {
	logg("!cdiff_cmd_move: Can't get first argument\n");
	free(start_str);
	free(end_str);
	return -1;
    }

    if(!(src = fopen(srcdb, "r"))) {
	logg("!cdiff_cmd_move: Can't open %s for reading\n", srcdb);
	free(start_str);
	free(end_str);
	free(srcdb);
	return -1;
    }

    if(!(dstdb = cdiff_token(cmdstr, 2, 0))) {
	logg("!cdiff_cmd_move: Can't get second argument\n");
	free(start_str);
	free(end_str);
	free(srcdb);
	fclose(src);
	return -1;
    }

    if(!(dst = fopen(dstdb, "a"))) {
	logg("!cdiff_cmd_move: Can't open %s for appending\n", dstdb);
	free(start_str);
	free(end_str);
	free(srcdb);
	fclose(src);
	free(dstdb);
	return -1;
    }

    if(!(tmpdb = cli_gentemp("."))) {
	logg("!cdiff_cmd_move: Can't generate temporary name\n");
	free(start_str);
	free(end_str);
	free(srcdb);
	fclose(src);
	free(dstdb);
	fclose(dst);
	return -1;
    }

    if(!(tmp = fopen(tmpdb, "w"))) {
	logg("!cdiff_cmd_move: Can't open file %s for writing\n", tmpdb);
	free(start_str);
	free(end_str);
	free(srcdb);
	fclose(src);
	free(dstdb);
	fclose(dst);
	free(tmpdb);
	return -1;
    }

    while(fgets(line, sizeof(line), src)) {
	lines++;

	if(lines == start_line) {
	    if(strncmp(line, start_str, strlen(start_str))) {
		free(start_str);
		free(end_str);
		free(srcdb);
		fclose(src);
		free(dstdb);
		fclose(dst);
		fclose(tmp);
		unlink(tmpdb);
		free(tmpdb);
		logg("!cdiff_cmd_close: Can't apply MOVE due to conflict at line %d\n", lines);
		return -1;
	    }

	    do {
		if(fputs(line, dst) == EOF) {
		    free(start_str);
		    free(end_str);
		    free(srcdb);
		    fclose(src);
		    fclose(dst);
		    fclose(tmp);
		    unlink(tmpdb);
		    free(tmpdb);
		    logg("!cdiff_cmd_move: Can't write to %s\n", dstdb);
		    free(dstdb);
		    return -1;
		}
	    } while((lines < end_line) && fgets(line, sizeof(line), src) && lines++);

	    fclose(dst);
	    free(dstdb);
	    dstdb = NULL;
	    free(start_str);

	    if(strncmp(line, end_str, strlen(end_str))) {
		free(end_str);
		free(srcdb);
		fclose(src);
		fclose(tmp);
		unlink(tmpdb);
		free(tmpdb);
		logg("!cdiff_cmd_close: Can't apply MOVE due to conflict at line %d\n", lines);
		return -1;
	    }

	    free(end_str);
	    continue;
	}

	if(fputs(line, tmp) == EOF) {
	    free(srcdb);
	    fclose(src);
	    fclose(tmp);
	    unlink(tmpdb);
	    logg("!cdiff_cmd_move: Can't write to %s\n", tmpdb);
	    free(tmpdb);
	    return -1;
	}
    }

    fclose(src);
    fclose(tmp);

    if(dstdb) {
	fclose(dst);
	free(start_str);
	free(end_str);
	unlink(tmpdb);
	free(tmpdb);
	logg("!cdiff_cmd_move: No data was moved from %s to %s\n", srcdb, dstdb);
	free(srcdb);
	free(dstdb);
	return -1;
    }

    if(unlink(srcdb) == -1) {
	logg("!cdiff_cmd_move: Can't unlink %s\n", srcdb);
	free(srcdb);
	unlink(tmpdb);
	free(tmpdb);
	return -1;
    }

    if(rename(tmpdb, srcdb) == -1) {
	logg("!cdiff_cmd_move: Can't rename %s to %s\n", tmpdb, srcdb);
	free(srcdb);
	unlink(tmpdb);
	free(tmpdb);
	return -1;
    }

    free(srcdb);
    free(tmpdb);

    return 0;
}

static int cdiff_cmd_unlink(const char *cmdstr, struct cdiff_ctx *ctx)
{
	char *db;
	unsigned int i;


    if(ctx->open_db) {
	logg("!cdiff_cmd_unlink: Database %s is still open\n", ctx->open_db);
	return -1;
    }

    if(!(db = cdiff_token(cmdstr, 1, 1))) {
	logg("!cdiff_cmd_unlink: Can't get first argument\n");
	return -1;
    }

    for(i = 0; i < strlen(db); i++) {
	if((db[i] != '.' && !isalnum(db[i])) || strchr("/\\", db[i])) {
	    logg("!cdiff_cmd_unlink: Forbidden characters found in database name\n");
	    free(db);
	    return -1;
	}
    }

    if(unlink(db) == -1) {
	logg("!cdiff_cmd_unlink: Can't unlink %s\n", db);
	free(db);
	return -1;
    }

    free(db);
    return 0;
}

static int cdiff_execute(const char *cmdstr, struct cdiff_ctx *ctx)
{
	char *cmd_name, *tmp;
	int (*cmd_handler)(const char *, struct cdiff_ctx *) = NULL;
	unsigned int i;


    cmd_name = cdiff_token(cmdstr, 0, 0);
    if(!cmd_name) {
	logg("!cdiff_apply: Problem parsing line\n");
	return -1;
    }

    for(i = 0; commands[i].name; i++) {
	if(!strcmp(commands[i].name, cmd_name)) {
	    cmd_handler = commands[i].handler;
	    break;
	}
    }

    if(!cmd_handler) {
	logg("!cdiff_apply: Unknown command %s\n", cmd_name);
	free(cmd_name);
	return -1;
    }

    if(!(tmp = cdiff_token(cmdstr, commands[i].argc, 1))) {
	logg("!cdiff_apply: Not enough arguments for %s\n", cmd_name);
	free(cmd_name);
	return -1;
    }
    free(tmp);

    if(cmd_handler(cmdstr, ctx)) {
	logg("!cdiff_apply: Can't execute command %s\n", cmd_name);
	free(cmd_name);
	return -1;
    }

    free(cmd_name);
    return 0;
}

#ifdef HAVE_GMP
static void pss_mgf(unsigned char *in, unsigned int inlen, unsigned char *out, unsigned int outlen)
{
	SHA256_CTX ctx;
	unsigned int i, laps;
	unsigned char cnt[4], digest[PSS_DIGEST_LENGTH];


    laps = (outlen + PSS_DIGEST_LENGTH - 1) / PSS_DIGEST_LENGTH;

    for(i = 0; i < laps; i++) {
	cnt[0] = (unsigned char) 0;
	cnt[1] = (unsigned char) 0;
	cnt[2] = (unsigned char) (i / 256);
	cnt[3] = (unsigned char) i;

	sha256_init(&ctx);
	sha256_update(&ctx, in, inlen);
	sha256_update(&ctx, cnt, sizeof(cnt));
	sha256_final(&ctx);
	sha256_digest(&ctx, digest);

	if(i != laps - 1)
	    memcpy(&out[i * PSS_DIGEST_LENGTH], digest, PSS_DIGEST_LENGTH);
	else
	    memcpy(&out[i * PSS_DIGEST_LENGTH], digest, outlen - i * PSS_DIGEST_LENGTH);
    }
}

static int pss_versig(const unsigned char *sha256, const char *dsig)
{
	mpz_t n, e;
	SHA256_CTX ctx;
	unsigned char *pt, digest1[PSS_DIGEST_LENGTH], digest2[PSS_DIGEST_LENGTH], *salt;
	unsigned int plen = PSS_NBITS / 8, hlen, slen, i;
	unsigned char dblock[PSS_NBITS / 8 - PSS_DIGEST_LENGTH - 1];
	unsigned char mblock[PSS_NBITS / 8 - PSS_DIGEST_LENGTH - 1];
	unsigned char fblock[8 + 2 * PSS_DIGEST_LENGTH];


    hlen = slen = PSS_DIGEST_LENGTH;
    mpz_init_set_str(n, PSS_NSTR, 10);
    mpz_init_set_str(e, PSS_ESTR, 10);

    if(!(pt = cli_decodesig(dsig, plen, e, n))) {
	mpz_clear(n);
	mpz_clear(e);
	return -1;
    }

    mpz_clear(n);
    mpz_clear(e);

    if(pt[plen - 1] != 0xbc) {
	/* cli_dbgmsg("cli_versigpss: Incorrect signature syntax (0xbc)\n"); */
	free(pt);
	return -1;
    }

    memcpy(mblock, pt, plen - hlen - 1);
    memcpy(digest2, &pt[plen - hlen - 1], hlen);
    free(pt);

    pss_mgf(digest2, hlen, dblock, plen - hlen - 1);

    for(i = 0; i < plen - hlen - 1; i++)
	dblock[i] ^= mblock[i];

    dblock[0] &= (0xff >> 1);

    salt = memchr(dblock, 0x01, sizeof(dblock));
    if(!salt) {
	/* cli_dbgmsg("cli_versigpss: Can't find salt\n"); */
	return -1;
    }
    salt++;

    if((unsigned int) (dblock + sizeof(dblock) - salt) != slen) {
	/* cli_dbgmsg("cli_versigpss: Bad salt size\n"); */
	return -1;
    }

    memset(fblock, 0, 8);
    memcpy(&fblock[8], sha256, hlen);
    memcpy(&fblock[8 + hlen], salt, slen);

    sha256_init(&ctx);
    sha256_update(&ctx, fblock, sizeof(fblock));
    sha256_final(&ctx);
    sha256_digest(&ctx, digest1);

    if(memcmp(digest1, digest2, hlen)) {
	/* cli_dbgmsg("cli_versigpss: Signature doesn't match.\n"); */
	return -1;
    }

    return 0;
}
#endif /* HAVE_GMP */

int cdiff_apply(int fd, unsigned short mode)
{
	struct cdiff_ctx ctx;
	FILE *fh;
	gzFile *gzh;
	char line[1024], buff[FILEBUFF], *dsig = NULL;
	unsigned int lines = 0, cmds = 0;
	unsigned int difflen, diffremain;
	int end, i, n;
	struct stat sb;
	int desc;
#ifdef HAVE_GMP
	SHA256_CTX sha256ctx;
	unsigned char digest[32];
	int sum, bread;
#endif
#define DSIGBUFF 350

    memset(&ctx, 0, sizeof(ctx));

    if((desc = dup(fd)) == -1) {
	logg("!cdiff_apply: Can't duplicate descriptor %d\n", fd);
	return -1;
    }

    if(mode == 1) { /* .cdiff */

	if(lseek(desc, -DSIGBUFF, SEEK_END) == -1) {
	    logg("!cdiff_apply: lseek(desc, %d, SEEK_END) failed\n", -DSIGBUFF);
	    close(desc);
	    return -1;
	}

	memset(line, 0, sizeof(line));
	if(read(desc, line, DSIGBUFF) != DSIGBUFF) {
	    logg("!cdiff_apply: Can't read %d bytes\n", DSIGBUFF);
	    close(desc);
	    return -1;
	}

	for(i = DSIGBUFF - 1; i >= 0; i--) {
	    if(line[i] == ':') {
		dsig = &line[i + 1];
		break;
	    }
	}

	if(!dsig) {
	    logg("!cdiff_apply: No digital signature in cdiff file\n");
	    close(desc);
	    return -1;
	}

	if(fstat(desc, &sb) == -1) {
	    logg("!cdiff_apply: Can't fstat file\n");
	    close(desc);
	    return -1;
	}

	end = sb.st_size - (DSIGBUFF - i);
	if(end < 0) {
	    logg("!cdiff_apply: compressed data end offset < 0\n");
	    close(desc);
	    return -1;
	}

	if(lseek(desc, 0, SEEK_SET) == -1) {
	    logg("!cdiff_apply: lseek(desc, 0, SEEK_SET) failed\n");
	    close(desc);
	    return -1;
	}

#ifdef HAVE_GMP
	sha256_init(&sha256ctx);
	sum = 0;
	while((bread = read(desc, buff, FILEBUFF)) > 0) {
	    if(sum + bread >= end) {
		sha256_update(&sha256ctx, (unsigned char *) buff, end - sum);
		break;
	    } else {
		sha256_update(&sha256ctx, (unsigned char *) buff, bread);
	    }
	    sum += bread;
	}
	sha256_final(&sha256ctx);
	sha256_digest(&sha256ctx, digest);

	if(pss_versig(digest, dsig)) {
	    logg("!cdiff_apply: Incorrect digital signature\n");
	    close(desc);
	    return -1;
	}
#endif

	if(lseek(desc, 0, SEEK_SET) == -1) {
	    logg("!cdiff_apply: lseek(desc, 0, SEEK_SET) failed\n");
	    close(desc);
	    return -1;
	}

	i = 0;
	n = 0;
	while(n < FILEBUFF - 1 && read(desc, &buff[n], 1) > 0) {
	    if(buff[n++] == ':')
		if(++i == 3)
		    break;
	}
	buff[n] = 0;

	if(sscanf(buff, "ClamAV-Diff:%*u:%u:", &difflen) != 1) {
	    logg("!cdiff_apply: Incorrect file format\n");
	    close(desc);
	    return -1;
	}

	if(!(gzh = gzdopen(desc, "rb"))) {
	    logg("!cdiff_apply: Can't gzdopen descriptor %d\n", desc);
	    close(desc);
	    return -1;
	}

	diffremain = difflen;
	while(diffremain) {
	    unsigned int bufsize = diffremain < sizeof(line) ? diffremain + 1 : sizeof(line);

	    if(!gzgets(gzh, line, bufsize)) {
		logg("!cdiff_apply: Premature EOF at line %d\n", lines + 1);
		cdiff_ctx_free(&ctx);
		gzclose(gzh);
		return -1;
	    }
	    diffremain -= strlen(line);
	    lines++;
	    cli_chomp(line);

	    if(line[0] == '#' || !strlen(line))
		continue;

	    if(cdiff_execute(line, &ctx) == -1) {
		logg("!cdiff_apply: Error executing command at line %d\n", lines);
		cdiff_ctx_free(&ctx);
		gzclose(gzh);
		return -1;
	    } else {
		cmds++;
	    }
	}
	gzclose(gzh);

    } else { /* .script */

	if(!(fh = fdopen(desc, "r"))) {
	    logg("!cdiff_apply: fdopen() failed for descriptor %d\n", desc);
	    close(desc);
	    return -1;
	}

	while(fgets(line, sizeof(line), fh)) {
	    lines++;
	    cli_chomp(line);

	    if(line[0] == '#' || !strlen(line))
		continue;

	    if(cdiff_execute(line, &ctx) == -1) {
		logg("!cdiff_apply: Error executing command at line %d\n", lines);
		cdiff_ctx_free(&ctx);
		fclose(fh);
		return -1;
	    } else {
		cmds++;
	    }
	}

	fclose(fh);
    }

    if(ctx.open_db) {
	logg("*cdiff_apply: File %s was not properly closed\n", ctx.open_db);
	cdiff_ctx_free(&ctx);
	return -1;
    }

    logg("*cdiff_apply: Parsed %d lines and executed %d commands\n", lines, cmds);
    return 0;
}
