Beispiel #1
0
/* Update:
 * If this segment is in any of the existing files, update it there.
 * Otherwise, if the last file isn't too big, add it there.
 * Otherwise, ada a new file.
 */
static int afd_update_seg(AFFILE *af, const char *name,
		    unsigned long arg,const u_char *value,unsigned int vallen)
    
{
    struct afd_private *ap = AFD_PRIVATE(af);
    AFFILE *af2 = afd_file_with_seg(af,name);
    if(af2){
	return af_update_seg(af2,name,arg,value,vallen); // update where it was found
    }
    /* Segment doesn't exist anywhere... */
    /* Append to the last file if there is space and a space limitation... */
    if(ap->num_afs>0){
	AFFILE *af3 = ap->afs[ap->num_afs-1];
	FILE *aseg = af3->aseg;

	uint64_t offset = ftello(aseg);
	fseeko(aseg,0,SEEK_END);

	uint64_t len = ftello(aseg);
	fseeko(aseg,offset,SEEK_SET);

	if((len + vallen + 1024 < af->maxsize) && (af->maxsize!=0)){
	    /* It should fit with room left over! */
	    return af_update_seg(af3,name,arg,value,vallen);
	}
    }

    /* Create a new file and add the segment to it.*/
    if(afd_add_file(af,0)) return -1;
    AFFILE *af4 = ap->afs[ap->num_afs-1]; // this is the one just added
    return af_update_seg(af4,name,arg,value,vallen);
}
Beispiel #2
0
/* For afm_update_seg, hand off page updates to the split_raw implementation
 * and metadata updates to the AFF implementation.
 */
static int afm_update_seg(AFFILE *af, const char *name,
			  uint32_t arg,const u_char *value,uint32_t vallen)

{
    struct afm_private *ap = AFM_PRIVATE(af);
    int64_t page_num = af_segname_page_number(name); // <0 means update metadata
    if(page_num<0){
	return af_update_seg(ap->aff,name,arg,value,vallen);
    }
    return af_update_seg(ap->sr,name,arg,value,vallen);
}
Beispiel #3
0
static int afm_create(AFFILE *af)
{
    if (af_update_seg (af, AF_RAW_IMAGE_FILE_EXTENSION, 0, (const u_char *)SPLITRAW_DEFAULT_EXTENSION,
		       strlen(SPLITRAW_DEFAULT_EXTENSION))) {
	(*af->error_reporter)("split_raw_read_write_setup: %s: failed to write %s\n",
			      af->fname, AF_RAW_IMAGE_FILE_EXTENSION);
	afm_close(af);		// close the sub-file
	return -1;			// we failed
    }
    af_set_pagesize(af,AFM_DEFAULT_PAGESIZE);
    af_update_seg(af,AF_AFF_FILE_TYPE,0,(const u_char *)"AFM",3);
    return 0;
}
Beispiel #4
0
/*
 * af_set_pagesize:
 * Sets the pagesize. Fails with -1 if it can't be changed.
 */
int af_set_pagesize(AFFILE *af,u_long pagesize)
{
    /* Allow the pagesize to be changed if it hasn't been set yet
     * and if this format doesn't support metadata updating (which is the raw formats)
     */
    struct af_vnode_info vni;

    af_vstat(af,&vni);

    if(vni.changable_pagesize==0 && af->image_size>0){
	if(pagesize==af->image_pagesize) return 0; // it's already set to this, so let it pass
	errno = EINVAL;
	return -1;
    }
    if(pagesize % af->image_sectorsize != 0){
	(*af->error_reporter)("Cannot set pagesize to %d (sectorsize=%d)\n",
			      pagesize,af->image_sectorsize);
	errno = EINVAL;
	return -1;
    }

    af->image_pagesize = pagesize;
    if(af_update_seg(af,AF_PAGESIZE,pagesize,0,0)){
	if(errno != ENOTSUP) return -1;	// error updating (don't report ENOTSUP);
    }
    return 0;
}
Beispiel #5
0
/* Requires no locking */
int	af_update_seg_frombio(AFFILE *af,const char *segname,unsigned long arg,BIO *bio)
{
    /* Get the buffer to write out */
    u_char *buf=0;
    size_t buflen = BIO_get_mem_data(bio,&buf);
    return af_update_seg(af,segname,0,buf,buflen);
}
Beispiel #6
0
/* 
 * af_make_badflag:
 * Create a randomized bag flag and
 * leave an empty segment of how many badsectors there are
 * in the image...
 */
int af_make_badflag(AFFILE *af)
{
#ifdef HAVE_OPENSSL_RAND_H
    /* Use a good random number generator if we have it */
    RAND_pseudo_bytes(af->badflag,af->image_sectorsize);
    strcpy((char *)af->badflag,"BAD SECTOR");
#else
    /* Otherwise use a bad one */
    for(int i=0;i<af->image_sectorsize;i++){
      af->badflag[i] = rand() & 0xff;
    }
#endif

    AF_WRLOCK(af);
    af->badflag_set = 1;
    if(af_update_seg(af,AF_BADFLAG,0,af->badflag,af->image_sectorsize)){
	AF_UNLOCK(af);
	return -1;
    }
    if(af_update_segq(af,AF_BADSECTORS,0)){
	AF_UNLOCK(af);
	return -1;
    }
    AF_UNLOCK(af);
    return 0;
}
Beispiel #7
0
int af_update_segq(AFFILE *af, const char *name, int64_t value)
{
    struct aff_quad  q;
    q.low  = htonl((uint32_t)(value & 0xffffffff));
    q.high = htonl((uint32_t)(value >> 32));
    return af_update_seg(af,name,AF_SEG_QUADWORD,(const u_char *)&q,8);
}
Beispiel #8
0
int sequential_test()
{
    char buf[1024];
    const char *fmt = "this is line %d\n";

    printf("Sequential test...\n");
    
    AFFILE *af = open_testfile("test_sequential",1);
    for(int i=0;i<MAX_FMTS;i++){
	if(i%250==0) printf("\rwriting %d/%d...",i,MAX_FMTS);
	sprintf(buf,fmt,i);
	if(af_write(af,(unsigned char *)buf,strlen(buf))!=(int)strlen(buf)){
	    err(1,"Attempt to write buffer %d failed\n",i);
	}
    }
    /* Test for a random bug that was reported */
    af_update_seg(af,"test",0,(const u_char *)"foo",3);
    af_update_seg(af,"test",0,(const u_char *)"bar",3);
    af_del_seg(af,"test");
    af_del_seg(af,"test");
    af_close(af);

    printf("\nSequential file written.\n");
    printf("\n");
    printf("Now verifying the string...\n");
    af = open_testfile("test_sequential",0);
    if(!af) err(1,"af_open");
    for(int i=0;i<MAX_FMTS;i++){
	char rbuf[1024];
	sprintf(buf,fmt,i);
	int len = strlen(buf);
	if(af_read(af,(unsigned char *)rbuf,len)!=len){
	    err(1,"Attempt to read entry %d failed\n",i);
	}
	rbuf[len] = 0;			// terminate the string
	if(strcmp(buf,rbuf)!=0){
	    err(1,"Attempt to verify entry %d failed.\nExpected: (len=%zd) '%s'\nGot: (len=%zd) '%s'\n",
		i,strlen(buf),buf,strlen(rbuf),rbuf);
	}
    }
    af_close(af);

    printf("===========================\n\n");
    return 0;
}
Beispiel #9
0
/*
 * make the IMAGE_GID segment if it doesn't exist
 * Returns -1 if an error, 0 if the GID exists, and 1 if one is made.
 */
int af_make_gid(AFFILE *af)
{
    int ret = 0;
    AF_WRLOCK(af);
    if(af_get_seg(af,AF_IMAGE_GID,0,0,0)!=0){
	unsigned char bit128[16];
	RAND_pseudo_bytes(bit128,sizeof(bit128));
	int r = af_update_seg(af,AF_IMAGE_GID,0,bit128,sizeof(bit128));
	if(r<0) ret = -1;
	else ret = 1;
    }
    AF_UNLOCK(af);
    return ret;
}
Beispiel #10
0
/* af_set_sectorsize:
 * Sets the sectorsize.
 * Fails with -1 if imagesize >=0 unless these changes permitted
 */
int af_set_sectorsize(AFFILE *af,int sectorsize)
{
    struct af_vnode_info vni;
    af_vstat(af,&vni);
    if(vni.changable_pagesize==0 && af->image_size>0){
	errno = EINVAL;
	return -1;
    }
    af->image_sectorsize =sectorsize;
    if(af->badflag==0) af->badflag = (unsigned char *)malloc(sectorsize);
    else af->badflag = (unsigned char *)realloc(af->badflag,sectorsize);
    af->badflag_set = 0;

    if(af_update_seg(af,AF_SECTORSIZE,sectorsize,0,0)){
	if(errno != ENOTSUP) return -1;
    }
    return 0;
}
Beispiel #11
0
void maxsize_test()
{
    printf("Maxsize test. This test is designed to test creation of files\n");
    printf("Larger than 4GB. Currently it's disabled, though.\n");
#if 0
    char segname[16];
    char buf[1024];
    char fn[1024];
    int numpages = 1000;

    AFFILE *af = af_open(filename(fn,sizeof(fn),"maxsize"),O_CREAT|O_RDWR|O_TRUNC,0666);
    memset(buf,0,sizeof(buf));
    for(int64_t i=0;i<numpages;i++){
	sprintf(buf,"This is page %"I64d". ****************************************************\n",i);
	sprintf(segname,AF_PAGE,i);
	af_update_seg(af,segname,0,buf,sizeof(buf));
    }
    af_close(af);
    printf("\nMaxsize test passes.\n");
#endif
    printf("\n====================\n");
}
Beispiel #12
0
int af_set_acquisition_date(AFFILE *af,time_t t)
{
    char timebuf[64];
    strftime(timebuf,sizeof(timebuf),"%Y-%m-%d %H:%M:%S\n",localtime(&t));
    return af_update_seg(af,AF_ACQUISITION_DATE,0,(const u_char *)timebuf,strlen(timebuf));
}
Beispiel #13
0
/* Add a file to the AFF system.
 * if fname==0, create a new one and copy over the relevant metadata...
 */
static int afd_add_file(AFFILE *af,const char *fname_)
{
    struct afd_private *ap = AFD_PRIVATE(af);
    const char *segs_to_copy[] = {AF_BADFLAG,
				  AF_CASE_NUM,
				  AF_IMAGE_GID,
				  AF_ACQUISITION_ISO_COUNTRY,
				  AF_ACQUISITION_COMMAND_LINE,
				  AF_ACQUISITION_DATE,
				  AF_ACQUISITION_NOTES,
				  AF_ACQUISITION_DEVICE,
				  AF_ACQUISITION_TECHNICIAN,
				  AF_DEVICE_MANUFACTURER,
				  AF_DEVICE_MODEL,
				  AF_DEVICE_SN,
				  AF_DEVICE_FIRMWARE,
				  AF_DEVICE_SOURCE,
				  AF_CYLINDERS,
				  AF_HEADS,
				  AF_SECTORS_PER_TRACK,
				  AF_LBA_SIZE,
				  AF_HPA_PRESENT,
				  AF_DCO_PRESENT,
				  AF_LOCATION_IN_COMPUTER,
				  AF_DEVICE_CAPABILITIES,
				  0};

    char fname[MAXPATHLEN+1];
    memset(fname,0,sizeof(fname));
    if(fname_){
	strlcpy(fname,fname_,sizeof(fname));
    }
    else {
	aff_filename(af,fname,sizeof(fname),ap->num_afs);
    }

    int new_file = access(fname,F_OK)!=0;	// Is this a new file?

    AFFILE *af2 = af_open(fname,af->openflags|AF_NO_CRYPTO,af->openmode); 
    if(af2==0){
	(*af->error_reporter)("open(%s,%d,%d) failed: %s\n",
			      fname,af->openflags,af->openmode,strerror(errno));
	return -1;			// this is bad
    }

    ap->num_afs += 1;
    ap->afs = (AFFILE **)realloc(ap->afs,sizeof(AFFILE *) * ap->num_afs);
    ap->afs[ap->num_afs-1] = af2;

    if(new_file){
	/* Copy over configuration from AFD vnode*/
	af_enable_compression(af2,af->compression_type,af->compression_level);
	af_set_pagesize(af2,af->image_pagesize);		//
	af_set_sectorsize(af2,af->image_sectorsize);
	af_update_seg(af,AF_AFF_FILE_TYPE,0,(const u_char *)"AFD",3);
	
	/* If this is the second file, copy over additional metadata from first... */
	if(ap->num_afs>1){
	    AFFILE *af0 = ap->afs[0];
	    memcpy(af2->badflag,af0->badflag,af->image_sectorsize);
	    af2->bytes_memcpy += af->image_sectorsize;
	    
	    for(const char **segname=segs_to_copy;*segname;segname++){
		unsigned char data[65536];	// big enough for most metadata
		size_t datalen = sizeof(data);
		unsigned long arg=0;
		
		if(af_get_seg(af0,*segname,&arg,data,&datalen)==0){
		    int r = af_update_seg(af2,*segname,arg,data,datalen);
		    if(r!=0){
			(*af->error_reporter)("afd_add_file: could not update %s in %s (r=%d)",
					      *segname,af_filename(af2),r);
		    }
		}
	    }
	}
    }
    
    return 0;
}
Beispiel #14
0
int aestest()
{
    unsigned char keyblock[32];
     
    /* Make a key; doesn't need to be a good key; make it 256 bits */
    for(int i=0;i<32;i++){
	keyblock[i] = i;
    }

    AFFILE *af = af_open("crypto.aff",O_CREAT|O_RDWR|O_TRUNC,0666);
    if(!af) err(1,"af_open");
    if(af_set_aes_key(af,keyblock,256)) err(1,"af_set_aes_key");
    af_set_pagesize(af,65536);

    /* Now, let's write some data of various sizes */

    u_char test[1024],buf[1024],rbuf[1024];
    size_t  buflen = sizeof(buf);
    make_test_seg(test,0);
    for(u_int len=0;len<=strlen((const char *)test);len++){
	if(af_update_seg(af,"page0",0,test,len)) err(1,"af_update_seg len=%d",len);
	
	/* Now try to read the segment */
	memset(buf,0,sizeof(buf));
	buflen = sizeof(buf);
	if(af_get_seg(af,"page0",0,(unsigned char *)buf,&buflen)){
	    err(1,"Could not read encrypted segment with length %d.\n",len);
	}
	if(buflen!=len){
	    printf("size of returned segment = %zd ",buflen);
	    printf("(should be %d) \n",len);
	    exit(0);
	}
	if(memcmp(buf,test,len)!=0){
	    printf("does not match\n");
	    printf("  wanted: %s\n",test);
	    printf("  got: %s\n",buf);
	    exit(0);
	}
    }
    if(af_close(af)) err(1,"af_close");

    /* Now re-open the file, do not set the encryption key, and see if we can read it */
    int r;
    memset(buf,0,sizeof(buf));
    af = af_open("crypto.aff",O_RDONLY,0666);
    buflen = sizeof(buf);
    r = af_get_seg(af,"page0",0,(unsigned char *)buf,&buflen);
    if(r!=-1) {
	errx(1,"Error; attempt to read segment 'encrypted' succeded. It should have failed.");
    }

    /* Try to read 'encrypted/aes' */
    r = af_get_seg(af,"encrypted/aes",0,(unsigned char *)buf,&buflen);
    if(memcmp(buf,test,buflen)==0){
	errx(1,"Error: segment encrypted/aes wasn't actually encrypted.");
    }
    af_close(af);
    
    /* Now set the correct encryption key and see if we can read it */
    af = af_open("crypto.aff",O_RDONLY,0666);
    if(af_set_aes_key(af,keyblock,256)) err(1,"af_set_aes_key");
    buflen = sizeof(buf);
    memset(buf,0,sizeof(buf));
    r = af_get_seg(af,"page0",0,(unsigned char *)buf,&buflen);
    if(buflen != strlen((const char *)test)){
	errx(1,"Error: Could not read encrypted segment after re-opening file");
    }
    if(memcmp(buf,test,buflen)!=0) errx(1,"Error: Re-read of file produces wrong data.");
    printf("encrypted data read and decrypted: '%s'\n",buf);
    /* Try to read a segment that doesn't eixst */
    buflen = 0;
    if(af_get_seg(af,"encrypted2",0,0,&buflen)==0){
	errx(1,"Error: Attempt to get size of non-existant segment 'encrypted2' got %zd\n",buflen);
    }
    af_close(af);


    /* Now set the wrong encryption key and see if we can read it */
    memset(buf,0,sizeof(buf));
    af = af_open("crypto.aff",O_RDONLY,0666);
    keyblock[3] = 42;
    if(af_set_aes_key(af,keyblock,256)) err(1,"af_set_aes_key");
    buflen = sizeof(buf);
    r = af_get_seg(af,"page0",0,(unsigned char *)buf,&buflen);
    if(memcmp(buf,test,buflen)==0) errx(1,"Error: Setting wrong key still produces correct data.");
    af_close(af);

    printf("Basic crypto checks. Now check passphrase....\n");

    /* Write the data with a passphrase and try to read it back */ 
    af = af_open("crypto_pass.aff",O_CREAT|O_RDWR|O_TRUNC,0666);
    if(!af) err(1,"af_open 3");
    af_set_pagesize(af,65536);
    if(af_establish_aes_passphrase(af,"yummy")) err(1,"af_establish_aes_passphrase");
    if(af_use_aes_passphrase(af,"yummy")) err(1,"af_use_aes_passphrase");
    if(af_update_seg(af,"page0",0,(const u_char *)test,strlen((const char *)test))) err(1,"af_update_seg failed at 3");
    if(af_close(af)) err(1,"af_close at 3");


    /* Now try to read it back */
    memset(rbuf,0,sizeof(rbuf));
    size_t rbuflen = sizeof(rbuf);
    af = af_open("crypto_pass.aff",O_RDONLY,0666);
    if(!af) err(1,"af_open 4");
    if(af_get_seg(af,"page0",0,(unsigned char *)buf,&buflen)==0){
	errx(1,"af_get_seg should have failed and didn't");
    }
    if(af_use_aes_passphrase(af,"yummy")) err(1,"af_set_passphrase 2");
    rbuflen=sizeof(rbuf);
    if(af_get_seg(af,"page0",0,(unsigned char *)rbuf,&rbuflen)){
	errx(1,"af_get_seg failed");
    }
    if(rbuflen!=strlen((const char *)test)) errx(1,"Reading encrypted data returned wrong size");
    if(memcmp(rbuf,test,rbuflen)!=0) errx(1,"Error: wrong data");
    printf("encrypted data read with passphrase 'yummy': %s\n",rbuf);
    af_close(af);

    /* Try to change the passphrase */
    af = af_open("crypto_pass.aff",O_RDWR,0666);
    if(!af) err(1,"af_open 5");
    if(af_change_aes_passphrase(af,"yummy","dummy")) err(1,"could not change passphrase");
    af_close(af);

    /* Try to read with new passphrase */
    af = af_open("crypto_pass.aff",O_RDONLY,0666);
    if(!af) err(1,"af_open 5");
    memset(rbuf,0,sizeof(rbuf));
    rbuflen = sizeof(rbuf);
    if(af_use_aes_passphrase(af,"dummy")) err(1,"af_set_passphrase 2");
    rbuflen=sizeof(rbuf);
    if(af_get_seg(af,"page0",0,(unsigned char *)rbuf,&rbuflen)){
	errx(1,"af_get_seg failed");
    }
    if(rbuflen!=strlen((const char *)test)) errx(1,"Reading encrypted with new passphrase data returned wrong size");
    if(memcmp(rbuf,test,rbuflen)!=0) errx(1,"Error: wrong data");
    printf("encrypted data read with new passphrase 'dummy': %s\n",rbuf);
    af_close(af);
    exit(0);
    
    
    /* Now try to read with the wrong passphrase */
    af = af_open("crypto.aff",O_RDONLY,0666);
    if(af_use_aes_passphrase(af,"yummy2")) err(1,"af_set_passphrase 3");
    buflen=sizeof(buf);
    memset(buf,0,sizeof(buf));
    if(af_get_seg(af,"page0",0,(unsigned char *)buf,&buflen)){
	printf("Couldn't get data with wrong passphrase (that's good)\n");
    }
    printf("data read with wrong passphrase: %s\n",buf);
    if(buflen>0 && memcmp(buf,test,buflen)==0){
	errx(1,"Error: data fetched with wrong passphrase was not scrambled.");
    }
    af_close(af);
    exit(0);
}