Beispiel #1
0
      void go() override
         {
         const std::string in_file = get_arg("file");
         std::string out_file, suffix;
         parse_extension(in_file, out_file, suffix);

         std::ifstream in(in_file);

         if(!in.good())
            throw CLI_IO_Error("reading", in_file);

         std::unique_ptr<Botan::Transform> decompress;

#if defined(BOTAN_HAS_COMPRESSION)
         decompress.reset(Botan::make_decompressor(suffix));
#endif

         if(!decompress)
            throw CLI_Error_Unsupported("Decompression", suffix);

         std::ofstream out(out_file);
         if(!out.good())
            throw CLI_IO_Error("writing", out_file);

         do_compress(*decompress, in, out, get_arg_sz("buf-size"));
         }
Beispiel #2
0
      void go() override
         {
         const std::string comp_type = get_arg("type");

         std::unique_ptr<Botan::Transform> compress;

#if defined(BOTAN_HAS_COMPRESSION)
         compress.reset(Botan::make_compressor(comp_type, get_arg_sz("level")));
#endif

         if(!compress)
            {
            throw CLI_Error_Unsupported("Compression", comp_type);
            }

         const std::string in_file = get_arg("file");
         std::ifstream in(in_file);

         if(!in.good())
            {
            throw CLI_IO_Error("reading", in_file);
            }

         const std::string out_file = output_filename(in_file, comp_type);
         std::ofstream out(out_file);
         if(!in.good())
            {
            throw CLI_IO_Error("writing", out_file);
            }

         do_compress(*compress, in, out, get_arg_sz("buf-size"));
         }
Beispiel #3
0
void send_block_list(Signature *sig)
{
        IOSBuf *ios, *ios1, *ios2;
        ProtoPutBlock pb;
        guint32 length;
        void *data;
        
        if(int_option(kOption_verbose) & VERBOSE_FLOW)
                g_message("sending block list");
        g_assert(sig);
        ios = block_list_to_stream(sig);
        g_assert(ios);
        SCsum_buffer(ios_buffer(ios), ios_buffer_size(ios),
                     sig->summary->block_list_sha1);
        memset(&pb, 0, sizeof(pb));
        pb.file_id = sig->summary->file_id;
        pb.block_id = 0;
        length = ios_buffer_size(ios);
        data = ios_buffer(ios);
        sig->summary->block_list_length = length;
        ios1 = ios_new();
        ios_set_buffer(ios1, data, length);
        ios2 = do_compress(ios1);
        pb.ios = encrypt(ios2);
        ios_free(ios1);
        ios_free(ios2);
        send_put_block(&pb);
        ios_free(ios);
        return;
}
Beispiel #4
0
int exomizer(unsigned char *srcbuf, int len, int load, int start, unsigned char *destbuf)
{
    int destlen;
    int max_offset = 65536;
    int max_passes = 65536;
    static match_ctx ctx;
    encode_match_data emd;
    encode_match_priv optimal_priv;
    search_nodep snp;

    match_ctx_init(ctx, srcbuf, len, max_offset);

    emd->out = NULL;
    emd->priv = optimal_priv;

    optimal_init(emd);

    snp = do_compress(ctx, emd, max_passes);

    destlen = generate_output(ctx, snp, sfx_c64ne, optimal_encode, emd,
                              load, len, start, destbuf);
    optimal_free(emd);

#if 0 /* RH */
    search_node_free(snp);
#endif /* RH */
    match_ctx_free(ctx);

    return destlen;
}
Beispiel #5
0
void crunch_backwards(struct membuf *inbuf,
                      struct membuf *outbuf,
                      struct crunch_options *options, /* IN */
                      struct crunch_info *info) /* OUT */
{
    static match_ctx ctx;
    encode_match_data emd;
    search_nodep snp;
    int outlen;
    int safety;
    int copy_used;

    if(options == NULL)
    {
        options = default_options;
    }

    outlen = membuf_memlen(outbuf);
    emd->out = NULL;
    optimal_init(emd);

    LOG(LOG_NORMAL,
        ("\nPhase 1: Instrumenting file"
         "\n-----------------------------\n"));
    LOG(LOG_NORMAL, (" Length of indata: %d bytes.\n", membuf_memlen(inbuf)));

    match_ctx_init(ctx, inbuf, options->max_len, options->max_offset,
                   options->use_imprecise_rle);

    LOG(LOG_NORMAL, (" Instrumenting file, done.\n"));

    emd->out = NULL;
    optimal_init(emd);

    LOG(LOG_NORMAL,
        ("\nPhase 2: Calculating encoding"
         "\n-----------------------------\n"));
    snp = do_compress(ctx, emd, options->exported_encoding,
                      options->max_passes, options->use_literal_sequences);
    LOG(LOG_NORMAL, (" Calculating encoding, done.\n"));

    LOG(LOG_NORMAL,
        ("\nPhase 3: Generating output file"
         "\n------------------------------\n"));
    LOG(LOG_NORMAL, (" Encoding: %s\n", optimal_encoding_export(emd)));
    safety = do_output(ctx, snp, emd, optimal_encode, outbuf, &copy_used);
    LOG(LOG_NORMAL, (" Length of crunched data: %d bytes.\n",
                     membuf_memlen(outbuf) - outlen));

    optimal_free(emd);
    search_node_free(snp);
    match_ctx_free(ctx);

    if(info != NULL)
    {
        info->literal_sequences_used = copy_used;
        info->needed_safety_offset = safety;
    }
}
Beispiel #6
0
bool compress_custom(void* input_data, InputFunc input_func,
    void* output_data, OutputFunc output_func, int sample_size)
{
  GifFileType* input_gif = NULL;
  GifFileType* output_gif = NULL;
  int result = GIF_ERROR;

  // Check sample
  if (sample_size <= 0) {
    return false;
  }

  input_gif = DGifOpen(input_data, input_func, &error_code);
  if (input_gif == NULL) {
    LOGE(EMSG("Can't open input gif"));
    return false;
  }

  DGifSlurp(input_gif);

  if (input_gif->ImageCount == 0) {
    LOGE(EMSG("Gif frame count is 0"));
    DGifCloseFile(input_gif, &error_code);
    return false;
  }

  // Save gif
  output_gif = EGifOpen(output_data, output_func, &error_code);
  if (output_gif == NULL) {
    LOGE(EMSG("Can't open output gif"));
    DGifCloseFile(input_gif, &error_code);
    return false;
  }

  if (do_compress(input_gif, output_gif, sample_size)) {
    result = EGifSpew(output_gif);
  }

  // Free
  GifFreeExtensions(&output_gif->ExtensionBlockCount, &output_gif->ExtensionBlocks);
  if (output_gif->SavedImages) {
    GifFreeSavedImages(output_gif);
    output_gif->SavedImages = NULL;
  }

  // Close gif
  DGifCloseFile(input_gif, &error_code);

  return result == GIF_OK;
}
Beispiel #7
0
/*
 * Traverse the entry tree, writing data for every item that has
 * non-null entry->compressed (i.e. every symlink and non-empty
 * regfile).
 */
static unsigned int write_data(struct entry *entry, char *base, unsigned int offset)
{
	do {
		if (entry->uncompressed) {
                        if(entry->same) {
                                set_data_offset(entry, base, entry->same->offset);
                                entry->offset=entry->same->offset;
                        } else {
                                set_data_offset(entry, base, offset);
                                entry->offset=offset;
                                offset = do_compress(base, offset, entry->name, entry->uncompressed, entry->size);
                        }
		}
		else if (entry->child)
			offset = write_data(entry->child, base, offset);
                entry=entry->next;
	} while (entry);
	return offset;
}
gint main (gint argc, gchar **argv)
{
	if (argc < 2)
		do_usage (argv[0]);

	camel_init (NULL, 0);

	if (!strcmp(argv[1], "compress"))
		return do_compress (argc, argv);
	else if (!strcmp(argv[1], "dump"))
		return do_dump (argc, argv);
	else if (!strcmp(argv[1], "info"))
		return do_info (argc, argv);
	else if (!strcmp(argv[1], "check"))
		return do_check (argc, argv);
	else if (!strcmp(argv[1], "perf"))
		return do_perf (argc, argv);

	do_usage (argv[0]);
	return 1;
}
Beispiel #9
0
/* Send blocks until the output buffer is sufficiently full.
 */
static void wt_send_blocks(WorkTicket *wt, IOSBuf *ios)
{
        DBBlock *dbb;
        ProtoPutBlock pb;
        IOSBuf *ios1, *ios2;
        
        g_assert(wt);
        g_assert(ios);
        /* g_assert(wt->action == wt_Archive); */
        g_assert(wt->dbf);

        while((ios_buffer_size(ios) < desired_queue_size)
              && (wt->next_block_to_queue < wt->sig.blockList->len)) {
                dbb = g_ptr_array_index(wt->sig.blockList,
                                        wt->next_block_to_queue++);
                g_assert(dbb);
                if(dbb->in_new_cover && !dbb->remote_id) {
                        /* If dbb->remote_id, then it's already in the
                           remote block store, so don't send. */
                        cover_fill_block(dbb, wt->fp);
                        memset(&pb, 0, sizeof(pb));
                        pb.file_id = wt->dbf->file_id;
                        pb.block_id = dbb->local_id;
                        ios1 = ios_new();
                        ios_set_buffer(ios1, dbb->data, dbb->length);
                        ios2 = do_compress(ios1);
                        pb.ios = encrypt(ios2);
                        ios_free(ios1);
                        ios_free(ios2);
                        send_put_block(&pb);
                        ios_free(pb.ios);
                        wt->num_blocks_moved++;
                        g_free(dbb->data);
                }
        }
        if(wt->next_block_to_queue >= wt->sig.blockList->len)
                wt->status = wt_AwaitingBlockConfirms;
        return;
}
   // not threadsafe, make sure there is only
   // one thread calling this
   void stat_helper::reset()
   {
      if (compressed_data != NULL && sent == false) return;

      tair_stat *new_stat = (tair_stat *) malloc(STAT_TOTAL_SIZE);
      assert (new_stat != NULL);
      memset(new_stat, 0, STAT_TOTAL_SIZE);

      if(curr_stat != NULL)
         free(curr_stat);

      curr_stat = stat;
      stat = new_stat;

      // fill persistent info
      if (storage_mgr != NULL) {
         storage_mgr->get_stats(curr_stat);
      }

      uint64_t now = tbsys::CTimeUtil::getTime();
      uint64_t interval = now - last_send_time;
      last_send_time = now;
      interval /= 1000000; // conver to second
      if (interval == 0) interval = 1;

      log_debug("start calculate ratio, interval: %d", interval);
      for (int i=0; i<STAT_LENGTH; i++) {
         tair_stat *cs = curr_stat + i;
         cs->set_get_count(cs->get_count() / interval);
         cs->set_put_count(cs->put_count() / interval);
         cs->set_remove_count(cs->remove_count() / interval);
         cs->set_hit_count(cs->hit_count() / interval);
      }

      // compress
      do_compress();
      sent = false;
   }
Beispiel #11
0
int main(int argc, char * const argv[])
{
	int c;
	int decompress = 0, files = 1;
	int selftest_compression = 0, selftest_decompression = 0;
	const char *ifile_name, *ofile_name;
	FILE *ifile, *ofile;

	while((c = getopt(argc, argv, "S:dc")) != -1) {
		switch (c) {
		case 'S':
			switch (optarg[0]) {
			case 'c':
				selftest_compression = 1;
				break;
			case 'd':
				selftest_decompression = 1;
				break;
			default:
				goto usage;
			}
			break;
		case 'd':
			decompress = 1;
			break;
		case 'c':
			files = 0;
			break;
		default:
			goto usage;
		}
	}
	if (selftest_compression)
		return do_selftest_compression();
	if (selftest_decompression)
		return do_selftest_decompression();
	ifile = stdin;
	ofile = stdout;
	if (files) {
		if (optind > argc - 2)
			goto usage;
		ifile_name = argv[optind];
		ofile_name = argv[optind + 1];
		if (!(ifile = fopen(ifile_name, "rb"))) {
			perror("fopen of ifile_name");
			return 2;
		}
		if (!(ofile = fopen(ofile_name, "wb"))) {
			perror("fopen of ofile_name");
			return 3;
		}
	}
	if (decompress)
		return do_decompress(ifile, ofile);
	else
		return do_compress(ifile, ofile);
usage:
	fprintf(stderr,
	"Usage:\n"
	"cl_tester [-d] infile outfile\t-\t[de]compress infile to outfile.\n"
	"cl_tester [-d] -c\t\t-\t[de]compress stdin to stdout.\n"
	"cl_tester -S c\t\t\t-\tSelf-test compression.\n"
	"cl_tester -S d\t\t\t-\tSelf-test decompression.\n");
	return 1;
}
Beispiel #12
0
/* Generate a seekable compressed stream. */
int SzipCompress::run(const char *name, Buffer &origBuf,
                      const char *outName, Buffer &outBuf)
{
  size_t origSize = origBuf.GetLength();
  if (origSize == 0) {
    log("Won't compress %s: it's empty", name);
    return 1;
  }
  if (SeekableZStreamHeader::validate(origBuf)) {
    log("Skipping %s: it's already a szip", name);
    return 0;
  }
  bool compressed = false;
  log("Size = %" PRIuSize, origSize);

  /* Allocate a buffer the size of the uncompressed data: we don't want
   * a compressed file larger than that anyways. */
  if (!outBuf.Resize(origSize)) {
    log("Couldn't allocate output buffer: %s", strerror(errno));
    return 1;
  }

  /* Find the most appropriate filter */
  SeekableZStream::FilterId firstFilter, lastFilter;
  bool scanFilters;
  if (filter == SeekableZStream::FILTER_MAX) {
    firstFilter = SeekableZStream::NONE;
    lastFilter = SeekableZStream::FILTER_MAX;
    scanFilters = true;
  } else {
    firstFilter = lastFilter = filter;
    ++lastFilter;
    scanFilters = false;
  }

  mozilla::ScopedDeletePtr<Buffer> filteredBuf;
  Buffer *origData;
  for (SeekableZStream::FilterId f = firstFilter; f < lastFilter; ++f) {
    FilteredBuffer *filteredTmp = NULL;
    Buffer tmpBuf;
    if (f != SeekableZStream::NONE) {
      debug("Applying filter \"%s\"", filterName[f]);
      filteredTmp = new FilteredBuffer();
      filteredTmp->Filter(origBuf, f, chunkSize);
      origData = filteredTmp;
    } else {
      origData = &origBuf;
    }
    if (dictSize  && !scanFilters) {
      filteredBuf = filteredTmp;
      break;
    }
    debug("Compressing with no dictionary");
    if (do_compress(*origData, tmpBuf, NULL, 0, f) == 0) {
      if (tmpBuf.GetLength() < outBuf.GetLength()) {
        outBuf.Fill(tmpBuf);
        compressed = true;
        filter = f;
        filteredBuf = filteredTmp;
        continue;
      }
    }
    delete filteredTmp;
  }

  origData = filteredBuf ? filteredBuf : &origBuf;

  if (dictSize) {
    Dictionary<uint64_t> dict(*origData, dictSize ? SzipCompress::winSize : 0);

    /* Find the most appropriate dictionary size */
    size_t firstDictSize, lastDictSize;
    if (dictSize == (size_t) -1) {
      /* If we scanned for filters, we effectively already tried dictSize=0 */
      firstDictSize = scanFilters ? 4096 : 0;
      lastDictSize = SzipCompress::winSize;
    } else {
      firstDictSize = lastDictSize = dictSize;
    }

    Buffer tmpBuf;
    for (size_t d = firstDictSize; d <= lastDictSize; d += 4096) {
      debug("Compressing with dictionary of size %" PRIuSize, d);
      if (do_compress(*origData, tmpBuf, static_cast<unsigned char *>(dict)
                      + SzipCompress::winSize - d, d, filter))
        continue;
      if (!compressed || tmpBuf.GetLength() < outBuf.GetLength()) {
        outBuf.Fill(tmpBuf);
        compressed = true;
        dictSize = d;
      }
    }
  }

  if (!compressed) {
    outBuf.Fill(origBuf);
    log("Not compressed");
    return 0;
  }

  if (dictSize == (size_t) -1)
    dictSize = 0;

  debug("Used filter \"%s\" and dictionary size of %" PRIuSize,
        filterName[filter], dictSize);
  log("Compressed size is %" PRIuSize, outBuf.GetLength());

  /* Sanity check */
  Buffer tmpBuf;
  SzipDecompress decompress;
  if (decompress.run("buffer", outBuf, "buffer", tmpBuf))
    return 1;

  size_t size = tmpBuf.GetLength();
  if (size != origSize) {
    log("Compression error: %" PRIuSize " != %" PRIuSize, size, origSize);
    return 1;
  }
  if (memcmp(static_cast<void *>(origBuf), static_cast<void *>(tmpBuf), size)) {
    log("Compression error: content mismatch");
    return 1;
  }
  return 0;
}
Beispiel #13
0
static
int process_file ( const compress_t *c, lzo_decompress_t decompress,
                   const char *method_name,
                   const char *file_name, lzo_uint l,
                   int t_loops, int c_loops, int d_loops )
{
	int i;
	unsigned blocks = 0;
	unsigned long compressed_len = 0;
	my_clock_t t_time = 0, c_time = 0, d_time = 0;
	my_clock_t t_start, c_start, d_start;
#ifdef USE_DUMP
	FILE *dump = NULL;

	if (opt_dump_compressed_data)
		dump = fopen(opt_dump_compressed_data,"wb");
#endif

/* process the file */

	t_start = my_clock();
	for (i = 0; i < t_loops; i++)
	{
		lzo_uint len, c_len, c_len_max, d_len = 0;
		lzo_byte *d = data;

		len = l;
		c_len = 0;
		blocks = 0;

		/* process blocks */
		if (len > 0 || opt_try_to_compress_0_bytes) do
		{
			int j;
			int r;

			const lzo_uint bl = len > opt_block_size ? opt_block_size : len;
			lzo_uint bl_overwrite = bl;
#if defined(__LZO_CHECKER)
			lzo_byte *dd = NULL;
			lzo_byte *b1 = NULL;
			lzo_byte *b2 = NULL;
			const lzo_uint b1_len = bl + bl / 64 + 16 + 3;
#else
			lzo_byte * const dd = d;
			lzo_byte * const b1 = block1;
			lzo_byte * const b2 = block2;
			const lzo_uint b1_len = sizeof(_block1) - 256;
			unsigned char random_byte;
			random_byte = (unsigned char) my_clock();
#endif

			blocks++;

			/* may overwrite 3 bytes past the end of the decompressed block */
			if (opt_use_asm_fast_decompressor)
				bl_overwrite += (lzo_uint) sizeof(int) - 1;

#if defined(__LZO_CHECKER)
			/* malloc a block of the exact size to detect any overrun */
			dd = malloc(bl_overwrite > 0 ? bl_overwrite : 1);
			b1 = malloc(b1_len);
			b2 = dd;
			if (dd == NULL || b1 == NULL)
			{
				perror("malloc");
				return EXIT_MEM;
			}
			if (bl > 0)
				memcpy(dd,d,bl);
#endif

		/* compress the block */
			c_len = c_len_max = 0;
			c_start = my_clock();
			for (j = r = 0; r == 0 && j < c_loops; j++)
			{
				c_len = b1_len;
				r = do_compress(c,dd,bl,b1,&c_len);
				if (r == 0 && c_len > c_len_max)
					c_len_max = c_len;
			}
			c_time += my_clock() - c_start;
			if (r != 0)
			{
				printf("  compression failed in block %d (%d) (%lu %lu)\n",
					blocks, r, (long)c_len, (long)bl);
				return EXIT_LZO_ERROR;
			}

		/* optimize the block */
			if (opt_optimize_compressed_data)
			{
				d_len = bl;
				r = do_optimize(c,b1,c_len,b2,&d_len);
				if (r != 0 || d_len != bl)
				{
					printf("  optimization failed in block %d (%d) "
						"(%lu %lu %lu)\n", blocks, r,
						(long)c_len, (long)d_len, (long)bl);
					return EXIT_LZO_ERROR;
				}
			}

#ifdef USE_DUMP
			/* dump compressed data to disk */
			if (dump)
			{
				lzo_fwrite(dump,b1,c_len);
				fflush(dump);
			}
#endif

		/* decompress the block and verify */
#if defined(__LZO_CHECKER)
			lzo_memset(b2,0,bl_overwrite);
#else
			init_mem_checker(b2,_block2,bl_overwrite,random_byte);
#endif
			d_start = my_clock();
			for (j = r = 0; r == 0 && j < d_loops; j++)
			{
				d_len = bl;
				r = do_decompress(c,decompress,b1,c_len,b2,&d_len);
				if (d_len != bl)
					break;
			}
			d_time += my_clock() - d_start;
			if (r != 0)
			{
				printf("  decompression failed in block %d (%d) "
					"(%lu %lu %lu)\n", blocks, r,
					(long)c_len, (long)d_len, (long)bl);
				return EXIT_LZO_ERROR;
			}
			if (d_len != bl)
			{
				printf("  decompression size error in block %d (%lu %lu %lu)\n",
					blocks, (long)c_len, (long)d_len, (long)bl);
				return EXIT_LZO_ERROR;
			}
			if (is_compressor(c))
			{
				if (lzo_memcmp(d,b2,bl) != 0)
				{
					lzo_uint x = 0;
					while (x < bl && b2[x] == d[x])
						x++;
					printf("  decompression data error in block %d at offset "
						"%lu (%lu %lu)\n", blocks, (long)x,
						(long)c_len, (long)d_len);
					if (opt_compute_adler32)
						printf("      checksum: 0x%08lx 0x%08lx\n",
							(long)adler_in, (long)adler_out);
#if 0
					printf("Orig:  ");
					r = (x >= 10) ? -10 : 0 - (int) x;
					for (j = r; j <= 10 && x + j < bl; j++)
						printf(" %02x", (int)d[x+j]);
					printf("\nDecomp:");
					for (j = r; j <= 10 && x + j < bl; j++)
						printf(" %02x", (int)b2[x+j]);
					printf("\n");
#endif
					return EXIT_LZO_ERROR;
				}
				if ((opt_compute_adler32 && adler_in != adler_out) ||
				    (opt_compute_crc32 && crc_in != crc_out))
				{
					printf("  checksum error in block %d (%lu %lu)\n",
						blocks, (long)c_len, (long)d_len);
					printf("      adler32: 0x%08lx 0x%08lx\n",
						(long)adler_in, (long)adler_out);
					printf("      crc32: 0x%08lx 0x%08lx\n",
						(long)crc_in, (long)crc_out);
					return EXIT_LZO_ERROR;
				}
			}

#if defined(__LZO_CHECKER)
			/* free in reverse order of allocations */
			free(b1);
			free(dd);
#else
			if (check_mem(b2,_block2,bl_overwrite,random_byte) != 0)
			{
				printf("  decompression overwrite error in block %d "
					"(%lu %lu %lu)\n",
					blocks, (long)c_len, (long)d_len, (long)bl);
				return EXIT_LZO_ERROR;
			}
#endif

			d += bl;
			len -= bl;
			compressed_len += c_len_max;
		}
		while (len > 0);
	}
	t_time += my_clock() - t_start;

#ifdef USE_DUMP
	if (dump)
		fclose(dump);
	opt_dump_compressed_data = NULL;	/* only dump the first file */
#endif

	print_stats(method_name, file_name,
	            t_loops, c_loops, d_loops,
	            t_time, c_time, d_time,
	            compressed_len, l, blocks);

	return EXIT_OK;
}
Beispiel #14
0
struct backend *backend_connect(struct backend *ret_backend, const char *server,
				struct protocol_t *prot, const char *userid,
				sasl_callback_t *cb, const char **auth_status)
{
    /* need to (re)establish connection to server or create one */
    int sock = -1;
    int r;
    int err = -1;
    int ask = 1; /* should we explicitly ask for capabilities? */
    struct addrinfo hints, *res0 = NULL, *res;
    struct sockaddr_un sunsock;
    char buf[2048];
    struct sigaction action;
    struct backend *ret;
    char rsessionid[MAX_SESSIONID_SIZE];

    if (!ret_backend) {
	ret = xzmalloc(sizeof(struct backend));
	strlcpy(ret->hostname, server, sizeof(ret->hostname));
	ret->timeout = NULL;
    }
    else
	ret = ret_backend;

    if (server[0] == '/') { /* unix socket */
	res0 = &hints;
	memset(res0, 0, sizeof(struct addrinfo));
	res0->ai_family = PF_UNIX;
	res0->ai_socktype = SOCK_STREAM;

 	res0->ai_addr = (struct sockaddr *) &sunsock;
 	res0->ai_addrlen = sizeof(sunsock.sun_family) + strlen(server) + 1;
#ifdef SIN6_LEN
 	res0->ai_addrlen += sizeof(sunsock.sun_len);
 	sunsock.sun_len = res0->ai_addrlen;
#endif
	sunsock.sun_family = AF_UNIX;
	strlcpy(sunsock.sun_path, server, sizeof(sunsock.sun_path));

	/* XXX set that we are preauthed */

	/* change hostname to 'config_servername' */
	strlcpy(ret->hostname, config_servername, sizeof(ret->hostname));
    }
    else { /* inet socket */
	memset(&hints, 0, sizeof(hints));
	hints.ai_family = PF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;
	err = getaddrinfo(server, prot->service, &hints, &res0);
	if (err) {
	    syslog(LOG_ERR, "getaddrinfo(%s) failed: %s",
		   server, gai_strerror(err));
	    goto error;
	}
    }

    /* Setup timeout */
    timedout = 0;
    action.sa_flags = 0;
    action.sa_handler = timed_out;
    sigemptyset(&action.sa_mask);
    if(sigaction(SIGALRM, &action, NULL) < 0) 
    {
	syslog(LOG_ERR, "Setting timeout in backend_connect failed: sigaction: %m");
	/* continue anyway */
    }
    
    for (res = res0; res; res = res->ai_next) {
	sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
	if (sock < 0)
	    continue;
	alarm(config_getint(IMAPOPT_CLIENT_TIMEOUT));
	if (connect(sock, res->ai_addr, res->ai_addrlen) >= 0)
	    break;
	if(errno == EINTR && timedout == 1)
	    errno = ETIMEDOUT;
	close(sock);
	sock = -1;
    }

    /* Remove timeout code */
    alarm(0);
    signal(SIGALRM, SIG_IGN);
    
    if (sock < 0) {
	if (res0 != &hints)
	    freeaddrinfo(res0);
	syslog(LOG_ERR, "connect(%s) failed: %m", server);
	goto error;
    }
    memcpy(&ret->addr, res->ai_addr, res->ai_addrlen);
    if (res0 != &hints)
	freeaddrinfo(res0);

    ret->in = prot_new(sock, 0);
    ret->out = prot_new(sock, 1);
    ret->sock = sock;
    prot_setflushonread(ret->in, ret->out);
    ret->prot = prot;

    /* use literal+ to send literals */
    prot_setisclient(ret->in, 1);
    prot_setisclient(ret->out, 1);
    
    if (prot->banner.auto_capa) {
	/* try to get the capabilities from the banner */
	r = ask_capability(ret, /*dobanner*/1, AUTO_CAPA_BANNER);
	if (r) {
	    /* found capabilities in banner -> don't ask */
	    ask = 0;
	}
    }
    else {
	do { /* read the initial greeting */
	    if (!prot_fgets(buf, sizeof(buf), ret->in)) {
		syslog(LOG_ERR,
		       "backend_connect(): couldn't read initial greeting: %s",
		       ret->in->error ? ret->in->error : "(null)");
		goto error;
	    }
	} while (strncasecmp(buf, prot->banner.resp,
			     strlen(prot->banner.resp)));
	strncpy(ret->banner, buf, 2048);
    }

    if (ask) {
	/* get the capabilities */
	ask_capability(ret, /*dobanner*/0, AUTO_CAPA_NO);
    }

    /* now need to authenticate to backend server,
       unless we're doing LMTP/CSYNC on a UNIX socket (deliver/sync_client) */
    if ((server[0] != '/') ||
	(strcmp(prot->sasl_service, "lmtp") &&
	 strcmp(prot->sasl_service, "csync"))) {
	char *old_mechlist = backend_get_cap_params(ret, CAPA_AUTH);
	const char *my_status;

	if ((r = backend_authenticate(ret, userid, cb, &my_status))) {
	    syslog(LOG_ERR, "couldn't authenticate to backend server: %s",
		   sasl_errstring(r, NULL, NULL));
	    free(old_mechlist);
	    goto error;
	}
	else {
	    const void *ssf;

	    sasl_getprop(ret->saslconn, SASL_SSF, &ssf);
	    if (*((sasl_ssf_t *) ssf)) {
		/* if we have a SASL security layer, compare SASL mech lists
		   before/after AUTH to check for a MITM attack */
		char *new_mechlist;
		int auto_capa = (prot->sasl_cmd.auto_capa == AUTO_CAPA_AUTH_SSF);

		if (!strcmp(prot->service, "sieve")) {
		    /* XXX  Hack to handle ManageSieve servers.
		     * No way to tell from protocol if server will
		     * automatically send capabilities, so we treat it
		     * as optional.
		     */
		    char ch;

		    /* wait and probe for possible auto-capability response */
		    usleep(250000);
		    prot_NONBLOCK(ret->in);
		    if ((ch = prot_getc(ret->in)) != EOF) {
			prot_ungetc(ch, ret->in);
		    } else {
			auto_capa = AUTO_CAPA_AUTH_NO;
		    }
		    prot_BLOCK(ret->in);
		}

		ask_capability(ret, /*dobanner*/0, auto_capa);
		new_mechlist = backend_get_cap_params(ret, CAPA_AUTH);
		if (new_mechlist &&
		    old_mechlist &&
		    strcmp(new_mechlist, old_mechlist)) {
		    syslog(LOG_ERR, "possible MITM attack:"
			   "list of available SASL mechanisms changed");
		    free(new_mechlist);
		    free(old_mechlist);
		    goto error;
		}
		free(new_mechlist);
	    }
	    else if (prot->sasl_cmd.auto_capa == AUTO_CAPA_AUTH_OK) {
		/* try to get the capabilities from the AUTH success response */
		forget_capabilities(ret);
		parse_capability(ret, my_status);
		post_parse_capability(ret);
	    }

	    if (!(strcmp(prot->service, "imap") &&
		 (strcmp(prot->service, "pop3")))) {
		parse_sessionid(my_status, rsessionid);
		syslog(LOG_NOTICE, "proxy %s sessionid=<%s> remote=<%s>", userid, session_id(), rsessionid);
	    }
	}

	if (auth_status) *auth_status = my_status;
	free(old_mechlist);
    }

    /* start compression if requested and both client/server support it */
    if (config_getswitch(IMAPOPT_PROXY_COMPRESS) && ret &&
	CAPA(ret, CAPA_COMPRESS) &&
	prot->compress_cmd.cmd &&
	do_compress(ret, &prot->compress_cmd)) {

	syslog(LOG_ERR, "couldn't enable compression on backend server");
	goto error;
    }

    return ret;

error:
    forget_capabilities(ret);
    if (ret->in) {
	prot_free(ret->in);
	ret->in = NULL;
    }
    if (ret->out) {
	prot_free(ret->out);
	ret->out = NULL;
    }
    if (sock >= 0)
	close(sock);
    if (ret->saslconn) {
	sasl_dispose(&ret->saslconn);
	ret->saslconn = NULL;
    }
    if (!ret_backend)
	free(ret);
    return NULL;
}
Beispiel #15
0
static int backend_login(struct backend *ret, const char *userid,
			 sasl_callback_t *cb, const char **auth_status,
			 int noauth)
{
    int r = 0;
    int ask = 1; /* should we explicitly ask for capabilities? */
    char buf[2048];
    struct protocol_t *prot = ret->prot;

    if (prot->type != TYPE_STD) return -1;

    if (prot->u.std.banner.auto_capa) {
	/* try to get the capabilities from the banner */
	r = ask_capability(ret, /*dobanner*/1, AUTO_CAPA_BANNER);
	if (r) {
	    /* found capabilities in banner -> don't ask */
	    ask = 0;
	}
    }
    else {
	do { /* read the initial greeting */
	    if (!prot_fgets(buf, sizeof(buf), ret->in)) {
		syslog(LOG_ERR,
		       "backend_login(): couldn't read initial greeting: %s",
		       ret->in->error ? ret->in->error : "(null)");
		return -1;
	    }
	} while (strncasecmp(buf, prot->u.std.banner.resp,
			     strlen(prot->u.std.banner.resp)));
	xstrncpy(ret->banner, buf, 2048);
    }

    if (ask) {
	/* get the capabilities */
	ask_capability(ret, /*dobanner*/0, AUTO_CAPA_NO);
    }

    /* now need to authenticate to backend server,
       unless we're doing LMTP/CSYNC on a UNIX socket (deliver/sync_client) */
    if (!noauth) {
	char *old_mechlist = backend_get_cap_params(ret, CAPA_AUTH);
	const char *my_status;

	if ((r = backend_authenticate(ret, userid, cb, &my_status))) {
	    syslog(LOG_ERR, "couldn't authenticate to backend server: %s",
		   sasl_errstring(r, NULL, NULL));
	    free(old_mechlist);
	    return -1;
	}
	else {
	    const void *ssf;

	    sasl_getprop(ret->saslconn, SASL_SSF, &ssf);
	    if (*((sasl_ssf_t *) ssf)) {
		/* if we have a SASL security layer, compare SASL mech lists
		   before/after AUTH to check for a MITM attack */
		char *new_mechlist;
		int auto_capa = (prot->u.std.sasl_cmd.auto_capa == AUTO_CAPA_AUTH_SSF);

		if (!strcmp(prot->service, "sieve")) {
		    /* XXX  Hack to handle ManageSieve servers.
		     * No way to tell from protocol if server will
		     * automatically send capabilities, so we treat it
		     * as optional.
		     */
		    char ch;

		    /* wait and probe for possible auto-capability response */
		    usleep(250000);
		    prot_NONBLOCK(ret->in);
		    if ((ch = prot_getc(ret->in)) != EOF) {
			prot_ungetc(ch, ret->in);
		    } else {
			auto_capa = AUTO_CAPA_AUTH_NO;
		    }
		    prot_BLOCK(ret->in);
		}

		ask_capability(ret, /*dobanner*/0, auto_capa);
		new_mechlist = backend_get_cap_params(ret, CAPA_AUTH);
		if (new_mechlist &&
		    old_mechlist &&
		    strcmp(new_mechlist, old_mechlist)) {
		    syslog(LOG_ERR, "possible MITM attack:"
			   "list of available SASL mechanisms changed");

		    if (new_mechlist) free(new_mechlist);
		    if (old_mechlist) free(old_mechlist);
		    return -1;
		}
		free(new_mechlist);
	    }
	    else if (prot->u.std.sasl_cmd.auto_capa == AUTO_CAPA_AUTH_OK) {
		/* try to get the capabilities from the AUTH success response */
		forget_capabilities(ret);
		parse_capability(ret, my_status);
		post_parse_capability(ret);
	    }

	    if (!(strcmp(prot->service, "imap") &&
		 (strcmp(prot->service, "pop3")))) {
		char rsessionid[MAX_SESSIONID_SIZE];
		parse_sessionid(my_status, rsessionid);
		syslog(LOG_NOTICE, "auditlog: proxy %s sessionid=<%s> remote=<%s>", userid, session_id(), rsessionid);
	    }
	}

	if (auth_status) *auth_status = my_status;
	free(old_mechlist);
    }

    /* start compression if requested and both client/server support it */
    if (config_getswitch(IMAPOPT_PROXY_COMPRESS) &&
	CAPA(ret, CAPA_COMPRESS) &&
	prot->u.std.compress_cmd.cmd) {
	r = do_compress(ret, &prot->u.std.compress_cmd);
	if (r) {
	    syslog(LOG_NOTICE, "couldn't enable compression on backend server: %s", error_message(r));
	    r = 0; /* not a fail-level error */
	}
    }

    return 0;
}
Beispiel #16
0
static int
compress_file(struct deflate_compressor *compressor, const tchar *path,
	      const struct options *options)
{
	tchar *newpath = NULL;
	struct file_stream in;
	struct file_stream out;
	struct stat stbuf;
	int ret;
	int ret2;

	if (path != NULL && !options->to_stdout) {
		size_t path_nchars, suffix_nchars;

		if (!options->force && has_suffix(path, options->suffix)) {
			msg("%"TS": already has .%"TS" suffix -- skipping",
			    path, options->suffix);
			ret = -2;
			goto out;
		}
		path_nchars = tstrlen(path);
		suffix_nchars = tstrlen(options->suffix);
		newpath = xmalloc((path_nchars + 1 + suffix_nchars + 1) *
					sizeof(tchar));
		tmemcpy(newpath, path, path_nchars);
		newpath[path_nchars] = '.';
		tmemcpy(&newpath[path_nchars + 1], options->suffix,
			suffix_nchars + 1);
	}

	ret = xopen_for_read(path, &in);
	if (ret != 0)
		goto out_free_newpath;

	ret = stat_file(&in, &stbuf, options->force || newpath == NULL);
	if (ret != 0)
		goto out_close_in;

	ret = xopen_for_write(newpath, options->force, &out);
	if (ret != 0)
		goto out_close_in;

	if (!options->force && isatty(out.fd)) {
		msg("Refusing to write compressed data to terminal. "
		    "Use -f to override.\nFor help, use -h.");
		ret = -1;
		goto out_close_out;
	}

	ret = map_file_contents(&in, stbuf.st_size);
	if (ret)
		goto out_close_out;

	ret = do_compress(compressor, &in, &out);
	if (ret != 0)
		goto out_close_out;

	if (path != NULL && newpath != NULL)
		restore_metadata(&out, newpath, &stbuf);
	ret = 0;
out_close_out:
	ret2 = xclose(&out);
	if (ret == 0)
		ret = ret2;
	if (ret != 0 && newpath != NULL)
		tunlink(newpath);
out_close_in:
	xclose(&in);
	if (ret == 0 && path != NULL && newpath != NULL && !options->keep)
		tunlink(path);
out_free_newpath:
	free(newpath);
out:
	return ret;
}
Beispiel #17
0
int
compress_filter( void *opaque, int control,
		 IOBUF a, byte *buf, size_t *ret_len)
{
    size_t size = *ret_len;
    compress_filter_context_t *zfx = opaque;
    z_stream *zs = zfx->opaque;
    int rc=0;

    if( control == IOBUFCTRL_UNDERFLOW ) {
	if( !zfx->status ) {
	    zs = zfx->opaque = m_alloc_clear( sizeof *zs );
	    init_uncompress( zfx, zs );
	    zfx->status = 1;
	}

#ifndef __riscos__
	zs->next_out = buf;
#else /* __riscos__ */
	zs->next_out = (Bytef *) buf;
#endif /* __riscos__ */
	zs->avail_out = size;
	zfx->outbufsize = size; /* needed only for calculation */
	rc = do_uncompress( zfx, zs, a, ret_len );
    }
    else if( control == IOBUFCTRL_FLUSH ) {
	if( !zfx->status ) {
	    PACKET pkt;
	    PKT_compressed cd;

	    if( !zfx->algo )
	        zfx->algo = DEFAULT_COMPRESS_ALGO;
	    if( zfx->algo != 1 && zfx->algo != 2 )
	      BUG();
	    memset( &cd, 0, sizeof cd );
	    cd.len = 0;
	    cd.algorithm = zfx->algo;
	    init_packet( &pkt );
	    pkt.pkttype = PKT_COMPRESSED;
	    pkt.pkt.compressed = &cd;
	    if( build_packet( a, &pkt ))
		log_bug("build_packet(PKT_COMPRESSED) failed\n");
	    zs = zfx->opaque = m_alloc_clear( sizeof *zs );
	    init_compress( zfx, zs );
	    zfx->status = 2;
	}

#ifndef __riscos__
	zs->next_in = buf;
#else /* __riscos__ */
	zs->next_in = (Bytef *) buf;
#endif /* __riscos__ */
	zs->avail_in = size;
	rc = do_compress( zfx, zs, Z_NO_FLUSH, a );
    }
    else if( control == IOBUFCTRL_FREE ) {
	if( zfx->status == 1 ) {
	    inflateEnd(zs);
	    m_free(zs);
	    zfx->opaque = NULL;
	    m_free(zfx->outbuf); zfx->outbuf = NULL;
	}
	else if( zfx->status == 2 ) {
#ifndef __riscos__
	    zs->next_in = buf;
#else /* __riscos__ */
	    zs->next_in = (Bytef *) buf;
#endif /* __riscos__ */
	    zs->avail_in = 0;
	    do_compress( zfx, zs, Z_FINISH, a );
	    deflateEnd(zs);
	    m_free(zs);
	    zfx->opaque = NULL;
	    m_free(zfx->outbuf); zfx->outbuf = NULL;
	}
        if (zfx->release)
          zfx->release (zfx);
    }
    else if( control == IOBUFCTRL_DESC )
	*(char**)buf = "compress_filter";
    return rc;
}
Beispiel #18
0
int
compress_filter_bz2( void *opaque, int control,
		     IOBUF a, byte *buf, size_t *ret_len)
{
  size_t size = *ret_len;
  compress_filter_context_t *zfx = opaque;
  bz_stream *bzs = zfx->opaque;
  int rc=0;

  if( control == IOBUFCTRL_UNDERFLOW )
    {
      if( !zfx->status )
	{
	  bzs = zfx->opaque = xmalloc_clear( sizeof *bzs );
	  init_uncompress( zfx, bzs );
	  zfx->status = 1;
	}

      bzs->next_out = buf;
      bzs->avail_out = size;
      zfx->outbufsize = size; /* needed only for calculation */
      rc = do_uncompress( zfx, bzs, a, ret_len );
    }
  else if( control == IOBUFCTRL_FLUSH )
    {
      if( !zfx->status )
	{
	  PACKET pkt;
	  PKT_compressed cd;

	  if( zfx->algo != COMPRESS_ALGO_BZIP2 )
	    BUG();
	  memset( &cd, 0, sizeof cd );
	  cd.len = 0;
	  cd.algorithm = zfx->algo;
	  init_packet( &pkt );
	  pkt.pkttype = PKT_COMPRESSED;
	  pkt.pkt.compressed = &cd;
/*	  if( build_packet( a, &pkt ))
	    log_bug("build_packet(PKT_COMPRESSED) failed\n"); */ //FIXME
	  bzs = zfx->opaque = xmalloc_clear( sizeof *bzs );
	  init_compress( zfx, bzs );
	  zfx->status = 2;
	}

      bzs->next_in = buf;
      bzs->avail_in = size;
      rc = do_compress( zfx, bzs, BZ_RUN, a );
    }
  else if( control == IOBUFCTRL_FREE )
    {
      if( zfx->status == 1 )
	{
	  BZ2_bzDecompressEnd(bzs);
	  xfree(bzs);
	  zfx->opaque = NULL;
	  xfree(zfx->outbuf); zfx->outbuf = NULL;
	}
      else if( zfx->status == 2 )
	{
	  bzs->next_in = buf;
	  bzs->avail_in = 0;
	  do_compress( zfx, bzs, BZ_FINISH, a );
	  BZ2_bzCompressEnd(bzs);
	  xfree(bzs);
	  zfx->opaque = NULL;
	  xfree(zfx->outbuf); zfx->outbuf = NULL;
	}
      if (zfx->release)
	zfx->release (zfx);
    }
  else if( control == IOBUFCTRL_DESC )
    *(char**)buf = "compress_filter";
  return rc;
}