int main(int argc, char ** argv) { int retv = 0; if (argc < 2) { usage(); return 0; } if (init_param(argc, argv) < 0) return -1; if (open_crypto_dev() < 0) return -1; if (crypto_method == CRYPTO_SHA1){ retv = sha(); return retv; } if (crypto_method == CRYPTO_MD5){ retv = md5(); return retv; } if (autotest_flag) { retv = auto_test(algoname); return retv; } if (crypto_method == CRYPTO_ENCRYPTE) { if (do_encryption(algoname) < 0) return -1; } else { if (do_decryption(algoname) < 0) return -1; } close_crypto_dev(); return 0; }
/* OK, this function is getting a bit out of control. One problem is that, if you give deflateInit2 compression=0, it still writes gzip headers and footers, so I had to add extra if(compression) and if(!compression) bits all over the place that would skip the actual compression. This is needed for the case where encryption is on and compression is off. Encryption off and compression off uses send_whole_file(). Perhaps a separate function is needed for encryption on compression off. */ int send_whole_file_gzl(struct asfd *asfd, const char *datapth, int quick_read, uint64_t *bytes, const char *encpassword, struct cntr *cntr, int compression, struct BFILE *bfd, const char *extrameta, size_t elen) { int ret=0; int zret=0; MD5_CTX md5; size_t metalen=0; const char *metadata=NULL; struct iobuf wbuf; int have; z_stream strm; int flush=Z_NO_FLUSH; uint8_t in[ZCHUNK]; uint8_t out[ZCHUNK]; int eoutlen; uint8_t eoutbuf[ZCHUNK+EVP_MAX_BLOCK_LENGTH]; EVP_CIPHER_CTX *enc_ctx=NULL; #ifdef HAVE_WIN32 int do_known_byte_count=0; size_t datalen=bfd->datalen; if(datalen>0) do_known_byte_count=1; #endif if(encpassword && !(enc_ctx=enc_setup(1, encpassword))) return -1; if(!MD5_Init(&md5)) { logp("MD5_Init() failed\n"); return -1; } //logp("send_whole_file_gz: %s%s\n", fname, extrameta?" (meta)":""); if((metadata=extrameta)) { metalen=elen; } /* allocate deflate state */ strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; if((zret=deflateInit2(&strm, compression, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY))!=Z_OK) { return -1; } do { if(metadata) { if(metalen>ZCHUNK) strm.avail_in=ZCHUNK; else strm.avail_in=metalen; memcpy(in, metadata, strm.avail_in); metadata+=strm.avail_in; metalen-=strm.avail_in; } else { // Windows VSS headers give us how much data to // expect to read. #ifdef HAVE_WIN32 if(do_known_byte_count) { if(datalen<=0) strm.avail_in=0; else strm.avail_in= (uint32_t)bfd->read(bfd, in, min((size_t)ZCHUNK, datalen)); datalen-=strm.avail_in; } else #endif strm.avail_in= (uint32_t)bfd->read(bfd, in, ZCHUNK); } if(!compression && !strm.avail_in) break; *bytes+=strm.avail_in; // The checksum needs to be later if encryption is being used. if(!enc_ctx) { if(!MD5_Update(&md5, in, strm.avail_in)) { logp("MD5_Update() failed\n"); ret=-1; break; } } #ifdef HAVE_WIN32 if(do_known_byte_count && datalen<=0) flush=Z_FINISH; else #endif if(strm.avail_in) flush=Z_NO_FLUSH; else flush=Z_FINISH; strm.next_in=in; /* run deflate() on input until output buffer not full, finish compression if all of source has been read in */ do { if(compression) { strm.avail_out = ZCHUNK; strm.next_out = out; zret = deflate(&strm, flush); /* no bad return value */ if(zret==Z_STREAM_ERROR) /* state not clobbered */ { logp("z_stream_error\n"); ret=-1; break; } have = ZCHUNK-strm.avail_out; } else { have=strm.avail_in; memcpy(out, in, have); } if(enc_ctx) { if(do_encryption(asfd, enc_ctx, out, have, eoutbuf, &eoutlen, &md5)) { ret=-1; break; } } else { iobuf_set(&wbuf, CMD_APPEND, (char *)out, have); if(asfd->write(asfd, &wbuf)) { ret=-1; break; } } if(quick_read && datapth) { int qr; if((qr=do_quick_read(asfd, datapth, cntr))<0) { ret=-1; break; } if(qr) // client wants to interrupt { goto cleanup; } } if(!compression) break; } while (!strm.avail_out); if(ret) break; if(!compression) continue; if(strm.avail_in) /* all input will be used */ { ret=-1; logp("strm.avail_in=%d\n", strm.avail_in); break; } } while(flush!=Z_FINISH); if(!ret) { if(compression && zret!=Z_STREAM_END) { logp("ret OK, but zstream not finished: %d\n", zret); ret=-1; } else if(enc_ctx) { if(!EVP_CipherFinal_ex(enc_ctx, eoutbuf, &eoutlen)) { logp("Encryption failure at the end\n"); ret=-1; } else if(eoutlen>0) { iobuf_set(&wbuf, CMD_APPEND, (char *)eoutbuf, (size_t)eoutlen); if(asfd->write(asfd, &wbuf)) ret=-1; else if(!MD5_Update(&md5, eoutbuf, eoutlen)) { logp("MD5_Update() failed\n"); ret=-1; } } } } cleanup: deflateEnd(&strm); if(enc_ctx) { EVP_CIPHER_CTX_cleanup(enc_ctx); free(enc_ctx); } if(!ret) { uint8_t checksum[MD5_DIGEST_LENGTH]; if(!MD5_Final(checksum, &md5)) { logp("MD5_Final() failed\n"); return -1; } return write_endfile(asfd, *bytes, checksum); } //logp("end of send\n"); return ret; }