Ejemplo n.º 1
0
static PyObject *affile_get_seg(affile *self, PyObject *args, PyObject *kwds) {
	PyObject *retdata;
	char *buf;
	size_t buflen=0;
	char *segname=NULL;
    static char *kwlist[] = {"segname", NULL};

    if(!PyArg_ParseTupleAndKeywords(args, kwds, "s", kwlist, &segname))
        return NULL;

    // first get the size
    if(af_get_seg(self->af, segname, 0, 0, &buflen) != 0) {
        return PyErr_Format(PyExc_IOError, "error reading libaff segment\n");
    }
    
    // allocate a string to return data in
    retdata = PyString_FromStringAndSize(NULL, buflen);
    buf = PyString_AsString(retdata);

    if(af_get_seg(self->af, segname, 0, (unsigned char *)buf, &buflen) != 0) {
        Py_DECREF(retdata);
        return PyErr_Format(PyExc_IOError, "error reading libaff segment\n");
    }
 
    return retdata;
}
Ejemplo n.º 2
0
/*
 * afm_get_seg:
 * If it is a page segment, satisfy it from the splitraw,
 * otherwise from the aff file.
 */
static int afm_get_seg(AFFILE *af,const char *name,uint32_t *arg,unsigned char *data,size_t *datalen)
{
    struct afm_private *ap = AFM_PRIVATE(af);
    int64_t page_num = af_segname_page_number(name);
    if(page_num>=0) return af_get_seg(ap->sr,name,arg,data,datalen);
    return af_get_seg(ap->aff,name,arg,data,datalen);

}
Ejemplo n.º 3
0
void affstats(const char *fname)
{
    AFFILE *af = af_open(fname,O_RDONLY,0);
    if(!af) af_err(1,"af_open(%s)",fname);

    printf("%s\t",fname);

    uint32_t segsize=0;

    int64_t imagesize=0;
    int64_t blanksectors=0;
    int64_t badsectors=0;
    af_get_segq(af,AF_IMAGESIZE,&imagesize);
    if(af_get_seg(af,AF_PAGESIZE,&segsize,0,0)){
	af_get_seg(af,AF_SEGSIZE_D,&segsize,0,0); // check for oldstype
    }
    af_get_segq(af,AF_BADSECTORS,&badsectors);
    af_get_segq(af,AF_BLANKSECTORS,&blanksectors);

    print_size(imagesize);
    printf("\t");
    fflush(stdout);

    int64_t compressed_bytes = 0;
    int64_t uncompressed_bytes = 0;

    /* Now read through all of the segments and count the number of
     * data segments. We know the uncompressed size...
     */
    af_rewind_seg(af);
    char segname[AF_MAX_NAME_LEN+1];
    size_t datalen;
    while(af_get_next_seg(af,segname,sizeof(segname),0,0,&datalen)==0){
	int64_t page_num = af_segname_page_number(segname);
	if(page_num>=0){
	    compressed_bytes += datalen;
	    uncompressed_bytes += segsize;
	}
    }
    if(uncompressed_bytes > imagesize) uncompressed_bytes = imagesize;

    print_size(compressed_bytes);
    printf("\t");
    print_size(uncompressed_bytes);
    printf(" %" I64d " %" I64d,blanksectors,badsectors);
    putchar('\n');
    
    
}
Ejemplo n.º 4
0
/* get_seg needs to figure out which of the individual EVF files
 * has the requested segment and call it.
 */
static int evd_get_seg(AFFILE *af,const char *name,unsigned long *arg,unsigned char *data,
		       size_t *datalen)
{
    AFFILE *af2 = evd_file_with_seg(af,name);
    if(af2){
	return af_get_seg(af2,name,arg,data,datalen); // use this one
    }
    return -1;				// not found
}
Ejemplo n.º 5
0
int af_get_page_raw(AFFILE *af,int64_t pagenum,unsigned long *arg,
		    unsigned char *data,size_t *bytes)
{
    char segname[AF_MAX_NAME_LEN];
    
    memset(segname,0,sizeof(segname));
    sprintf(segname,AF_PAGE,pagenum);
    int r = af_get_seg(af,segname,arg,data,bytes);
    if(r!=0){
	/* Couldn't read with AF_PAGE; try AF_SEG_D.
	 * This is legacy for the old AFF files. Perhaps we should delete it.
	 */
	sprintf(segname,AF_SEG_D,pagenum);
	r = af_get_seg(af,segname,arg,data,bytes);
    }
    /* Update the counters */
    if(r==0 && bytes && *bytes>0) af->pages_read++; // note that we read a page
    return r;
}
Ejemplo n.º 6
0
/* af_read_sizes:
 * Get the page sizes if they are set in the file.
 */
void af_read_sizes(AFFILE *af)
{
    af_get_seg(af,AF_SECTORSIZE,&af->image_sectorsize,0,0);
    if(af->image_sectorsize==0) af->image_sectorsize = 512; // reasonable default

    if(af_get_seg(af,AF_PAGESIZE,&af->image_pagesize,0,0)){
	af_get_seg(af,AF_SEGSIZE_D,&af->image_pagesize,0,0); // try old name
    }

    /* Read the badflag if it is present */
    size_t sectorsize = af->image_sectorsize;
    if(af->badflag==0) af->badflag = (unsigned char *)malloc(sectorsize);
    if(af_get_seg(af,AF_BADFLAG,0,af->badflag,(size_t *)&sectorsize)==0){
	af->badflag_set = 1;
    }

    /* Read the image file segment if it is present. 
     * If it isn't, scan through the disk image to figure out the size of the disk image.
     */

    if(af_get_segq(af,AF_IMAGESIZE,(int64_t *)&af->image_size)){

	/* Calculate the imagesize by scanning all of the pages that are in
	 * the disk image and finding the highest page number.
	 * Then read that page to find the last allocated byte.
	 */
	char segname[AF_MAX_NAME_LEN];
	size_t datalen = 0;
	af_rewind_seg(af);		//  start at the beginning
	int64_t highest_page_number = 0;
	while(af_get_next_seg(af,segname,sizeof(segname),0,0,&datalen)==0){
	    if(segname[0]==0) continue;	// ignore sector
	    int64_t pagenum = af_segname_page_number(segname);
	    if(pagenum > highest_page_number) highest_page_number = pagenum;
	}
	size_t highest_page_len = 0;
	if(af_get_page(af,highest_page_number,0,&highest_page_len)==0){
	    af->image_size = af->image_pagesize * highest_page_number + highest_page_len;
	}
    }
    af->image_size_in_file = af->image_size;
}
Ejemplo n.º 7
0
static AFFILE *evd_file_with_seg(AFFILE *af,const char *name)
{
    struct evd_private *ap = EVD_PRIVATE(af);
    for(unsigned int i=0;i<ap->num_evfs;i++){
	if(af_get_seg(ap->evfs[i],name,0,0,0)==0){
	    return ap->evfs[i];
	}
    }
    errno = ENOTDIR;			// get ready for error return
    return 0;
}
Ejemplo n.º 8
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;
}
Ejemplo n.º 9
0
int af_get_segq(AFFILE *af,const char *name,int64_t *aff_quad)
{
    unsigned char buf[8];
    size_t  bufsize = sizeof(buf);

    if(af_get_seg(af,name,0,(unsigned char *)&buf,&bufsize)){
	return -1;			// couldn't get it...
    }
    if(bufsize!=sizeof(struct aff_quad)){		// make sure size is good.
	return -1;
    }
	
    *aff_quad = af_decode_q(buf);
    return 0;
}
Ejemplo n.º 10
0
void xmlseg(BIO *bp,AFFILE *af,const char *segname)
{
    BIO_printf(bp,"  <segment>\n");
    BIO_printf(bp,"    <name>%s</name>\n",segname);
    /* Get the signature and base64 it (if we can) */
    u_char sigbuf[1024];
    size_t sigbuf_len = sizeof(sigbuf);
    char segname_sig[1024];
    strlcpy(segname_sig,segname,sizeof(segname_sig));
    strlcat(segname_sig,AF_SIG256_SUFFIX,sizeof(segname_sig));
    if(af_get_seg(af,segname_sig,0,sigbuf,&sigbuf_len)==0){
	char sigbuf48[2048];
	int  sigbuf48_len = b64_ntop(sigbuf,sigbuf_len,sigbuf48,sizeof(sigbuf48));
	sigbuf48[sigbuf48_len] = 0;	// null terminate
	BIO_printf(bp,"    <sig>%s</sig>\n",sigbuf48);
    }
    BIO_printf(bp,"  </segment>\n");
}
Ejemplo n.º 11
0
/* af_get_imagesize:
 * Return the byte # of last mapped byte in image, or size of device;
 * No locking is needed because individual elements of the af structure are not accessed.
 */
int64_t af_get_imagesize(AFFILE *af)
{
    int64_t ret = -1;
    struct af_vnode_info vni;
    memset(&vni,0,sizeof(vni));
    if(af_vstat(af,&vni)==0){
	/* If vni.imagesize is 0 and if there are encrypted segments and if there
	 * is no imagesize segment but there is an encrypted one, then we can't read this encrypted file...
	 */
	if(vni.imagesize<=0 && vni.segment_count_encrypted>0){
	    if(af_get_seg(af,AF_IMAGESIZE,0,0,0)!=0){
		errno = EPERM;
		goto done;
	    }
	}
	ret = vni.imagesize;
    }
 done:;
    return ret;
}
Ejemplo n.º 12
0
int af_get_next_seg(AFFILE *af,char *segname,size_t segname_len,unsigned long *arg,
			unsigned char *data,size_t *datalen)
{
    size_t datalen_orig = datalen ? *datalen : 0;
    AF_READLOCK(af);
    if(af->v->get_next_seg==0){
	errno = ENOTSUP;
	AF_UNLOCK(af);
	return -1;
    }
    int r = (*af->v->get_next_seg)(af,segname,segname_len,arg,data,datalen);
#ifdef HAVE_AES_ENCRYPT
    if(AF_SEALING_VNODE(af) 
       && ends_with(segname,AF_AES256_SUFFIX)
       && af->crypto->auto_decrypt){
	segname[strlen(segname)-strlen(AF_AES256_SUFFIX)] = 0;
	/* An encrypted segment was retrieved.
	 * If it fit, decrypt and return.
	 * If it doesn't fit, try to get it again (which will use our adaptive blocksize)
	 *
	 * Normaly it will fit becuase the caller doesn't know how long the 'next' segment is,
	 * so the caller normally leaves enough space.
	 */
	if(r==0){
	    af_aes_decrypt(af,segname,data,datalen);
	    AF_UNLOCK(af);
	    return 0;
	}
	if(r==AF_ERROR_DATASMALL && datalen && (*datalen % AES_BLOCK_SIZE !=0)){
	    *datalen = datalen_orig;
	    AF_UNLOCK(af);
	    return af_get_seg(af,segname,arg,data,datalen);
	}
	AF_UNLOCK(af);
	return r;			// not sure why we got this error
    }
#endif    
    AF_UNLOCK(af);
    return r;
}
Ejemplo n.º 13
0
/*  afm_split_raw_setup:
 * Sets up the parameters of the split-raw by reading from the metadata file.
 * The advantage of doing it this way is that a new file can be opened,
 * the metadata parmeters set, and then an af_write() call made, and the values.
 * get copied.
 */
static int afm_split_raw_setup(AFFILE *af)
{
    struct afm_private *ap = AFM_PRIVATE(af);
    if(ap->sr_initialized) return 0;		// already setup

    /* The size of AF_PAGES_PER_RAW_IMAGE_FILE indicates whether the file is split.
     * If it is not present, or if it is 0-length, assume that the file is not split.
     */
    uint64_t pages_per_file = 0;
    size_t len = 0;
    if (af_get_seg(ap->aff,AF_PAGES_PER_RAW_IMAGE_FILE,0,0,&len)) {

	/* Not in file; put it there based on maxsize and image_pagesize,
	 * both of which better be set at this point
	 */
	if (af->image_pagesize < 1) {
	    (*af->error_reporter)("afm_split_raw_setup: image_pagesize==0\n");
	    return -1;
	}
	if (af->maxsize % af->image_pagesize) {
	    (*af->error_reporter)("afm_split_raw_setup: maxsize (%"I64d") "
				  "not a multiple of image_pagesize (%d)\n",
				  af->maxsize,af->image_pagesize);
	    return -1;
	}
	pages_per_file = af->maxsize / af->image_pagesize;
	if (af_update_segq (af, AF_PAGES_PER_RAW_IMAGE_FILE, pages_per_file)) {
	    (*af->error_reporter)("split_raw_read_write_setup: %s: failed to write %s\n",
				  af_filename(af), AF_PAGES_PER_RAW_IMAGE_FILE);
	    return -1;
	}
    }

    /* Now, read the segment (which might have just been put there) and set up the split_raw file */
    if(af_get_segq(af,AF_PAGES_PER_RAW_IMAGE_FILE,(int64_t *)&pages_per_file)){
	(*af->error_reporter)("split_raw_read_write_setup: %s: failed to write %s\n",
			      af_filename(af), AF_PAGES_PER_RAW_IMAGE_FILE);
	return -1;
    }

    /* Verify that splitraw's notion of the rawfilesize is the same as the
     * metadata's notion if the AFF image_size has been set
     */
    if (ap->aff->image_size && ap->aff->image_size != ap->sr->image_size) {
	(*af->error_reporter)("afm_split_raw_setup: internal error. "
			      "AFF image_size %"I64d" != SR image_size %"I64d"\n",
			      ap->aff->image_size,ap->sr->image_size);
	return -1;
    }

    /* Uses pages_per_file to set the maxsize of the split_raw if it hasn't been set yet*/
    if(ap->sr->maxsize==0){
	ap->sr->maxsize = pages_per_file * af->image_pagesize;
    }

    /* Verify that the parameters make sense */
    if (ap->sr->maxsize != (pages_per_file * af->image_pagesize) && pages_per_file>0) {
	(*af->error_reporter)("afm_split_raw_setup: %s: per size indicated by metadata (%d * %d) "
			      "doesn't match maxsize (%"I64d")\n",
			      af_filename(af),pages_per_file,af->image_pagesize,ap->sr->maxsize);
	return -1;
    }

    /* Push down the image_pagesize from the AFM to the split_raw */
    uint32_t image_pagesize = af->image_pagesize; // default to what's in memory
    af_get_seg(af,AF_PAGESIZE,&image_pagesize,0,0); // get from the AFF file if possible
    ap->sr->image_pagesize = af->image_pagesize; // overwrite the default with what the AFM file

    ap->sr_initialized = 1;
    return 0;
}
Ejemplo n.º 14
0
static int afm_open(AFFILE *af)
{
    af->vnodeprivate = (void *)calloc(sizeof(struct afm_private),1);
    struct afm_private *ap = AFM_PRIVATE(af);
    ap->aff = af_open_with(af_filename(af),af->openflags,af->openmode,&vnode_aff);

    if(ap->aff==0){			// open failed?
	afm_close(af);
	return -1;
    }
    ap->aff->parent = af;

    /* If this is a new file, write out the default split raw extension */
    if(af->exists == 0){
	if(afm_create(af)) return -1;
    }

    /* If this is an old file, read the image_pagesize */
    if(af->exists){
	af->image_pagesize = ap->aff->image_pagesize;
    }

    /* Read the split raw extension */
    char raw_file_extension[4];
    size_t  len=3;				// don't overwrite the NUL

    memset(raw_file_extension,0,sizeof(raw_file_extension));
    if (af_get_seg(ap->aff,AF_RAW_IMAGE_FILE_EXTENSION,0,(unsigned char *)raw_file_extension,&len)) {
	(*af->error_reporter)("afm_open: %s: %s segment missing or too large\n",
			      af_filename(af),AF_RAW_IMAGE_FILE_EXTENSION);
	afm_close(af);
	return -1;
    }
    if(invalid_extension_char(raw_file_extension,len)){
	(*af->error_reporter)("afm_open: file extension contains invalid character\n",
		 af->fname, AF_RAW_IMAGE_FILE_EXTENSION);
	afm_close(af);
	return -1;
    }

    /* Now open the splitraw file */
    char *sr_filename = strdup(af_filename(af));
    char *ext = strrchr(sr_filename,'.');
    if(!ext){
	(*af->error_reporter)("afm_open: cannot find extension in '%s'",sr_filename);
	free(sr_filename);
	afm_close(af);
	return -1;
    }
    ext++;				// skip past '.'
    if(strlen(ext) != strlen(raw_file_extension)){
	(*af->error_reporter)("afm_open: file extension in '%s' too short",sr_filename);
	free(sr_filename);
	afm_close(af);
	return -1;
    }

    strcpy(ext,raw_file_extension);
    ap->sr  = af_open_with(sr_filename,af->openflags,af->openmode,&vnode_split_raw);
    if(ap->sr==0){
	(*af->error_reporter)("afm_open: could not open '%s'",sr_filename);
	free(sr_filename);
	afm_close(af);
	return -1;
    }
    ap->sr->parent = af;
    free(sr_filename);

    /* Additional setup will happen first time a data read/write call is made
     * by the function afm_read_write_setup().
     * This allows a new file to be created with af_open() and then to have
     * the parameters set with af_update_seg() calls, yet the split_raw
     * implementation gets the proper settings
     */
    return 0;
}
Ejemplo n.º 15
0
static void
aff_imgstat(TSK_IMG_INFO * img_info, FILE * hFile)
{
    IMG_AFF_INFO *aff_info = (IMG_AFF_INFO *) img_info;
    unsigned char buf[512];
    size_t buf_len = 512;


    tsk_fprintf(hFile, "IMAGE FILE INFORMATION\n");
    tsk_fprintf(hFile, "--------------------------------------------\n");
    tsk_fprintf(hFile, "Image Type: ");
    switch (aff_info->type) {
    case AF_IDENTIFY_AFF:
        tsk_fprintf(hFile, "AFF\n");
        break;
    case AF_IDENTIFY_AFD:
        tsk_fprintf(hFile, "AFD\n");
        break;
    case AF_IDENTIFY_AFM:
        tsk_fprintf(hFile, "AFM\n");
        break;
    default:
        tsk_fprintf(hFile, "AFFLIB (%d)\n", aff_info->type);
        break;
    }

    tsk_fprintf(hFile, "\nSize in bytes: %" PRIuOFF "\n", img_info->size);

    // we won't have the rest of the info for the non-AFF formats.
    if (img_info->itype == TSK_IMG_TYPE_AFF_ANY)
        return;

    tsk_fprintf(hFile, "\nMD5: ");
    if (af_get_seg(aff_info->af_file, AF_MD5, NULL, buf, &buf_len) == 0) {
        int i;
        for (i = 0; i < 16; i++) {
            tsk_fprintf(hFile, "%x", buf[i]);
        }
        tsk_fprintf(hFile, "\n");
    }
    else {
        tsk_fprintf(hFile, "Segment not found\n");
    }

    buf_len = 512;
    tsk_fprintf(hFile, "SHA1: ");
    if (af_get_seg(aff_info->af_file, AF_SHA1, NULL, buf, &buf_len) == 0) {
        int i;
        for (i = 0; i < 20; i++) {
            tsk_fprintf(hFile, "%x", buf[i]);
        }
        tsk_fprintf(hFile, "\n");
    }
    else {
        tsk_fprintf(hFile, "Segment not found\n");
    }

    /* Creator segment */
    buf_len = 512;
    if (af_get_seg(aff_info->af_file, AF_CREATOR, NULL, buf,
            &buf_len) == 0) {
        buf[buf_len] = '\0';
        tsk_fprintf(hFile, "Creator: %s\n", buf);
    }

    buf_len = 512;
    if (af_get_seg(aff_info->af_file, AF_CASE_NUM, NULL, buf,
            &buf_len) == 0) {
        buf[buf_len] = '\0';
        tsk_fprintf(hFile, "Case Number: %s\n", buf);
    }

    buf_len = 512;
    if (af_get_seg(aff_info->af_file, AF_IMAGE_GID, NULL, buf,
            &buf_len) == 0) {
        unsigned int i;
        tsk_fprintf(hFile, "Image GID: ");
        for (i = 0; i < buf_len; i++) {
            tsk_fprintf(hFile, "%X", buf[i]);
        }
        tsk_fprintf(hFile, "\n");
    }

    buf_len = 512;
    if (af_get_seg(aff_info->af_file, AF_ACQUISITION_DATE, NULL, buf,
            &buf_len) == 0) {
        buf[buf_len] = '\0';
        tsk_fprintf(hFile, "Acquisition Date: %s\n", buf);
    }

    buf_len = 512;
    if (af_get_seg(aff_info->af_file, AF_ACQUISITION_NOTES, NULL, buf,
            &buf_len) == 0) {
        buf[buf_len] = '\0';
        tsk_fprintf(hFile, "Acquisition Notes: %s\n", buf);
    }

    buf_len = 512;
    if (af_get_seg(aff_info->af_file, AF_ACQUISITION_DEVICE, NULL, buf,
            &buf_len) == 0) {
        buf[buf_len] = '\0';
        tsk_fprintf(hFile, "Acquisition Device: %s\n", buf);
    }

    buf_len = 512;
    if (af_get_seg(aff_info->af_file, AF_AFFLIB_VERSION, NULL, buf,
            &buf_len) == 0) {
        buf[buf_len] = '\0';
        tsk_fprintf(hFile, "AFFLib Version: %s\n", buf);
    }

    buf_len = 512;
    if (af_get_seg(aff_info->af_file, AF_DEVICE_MANUFACTURER, NULL, buf,
            &buf_len) == 0) {
        buf[buf_len] = '\0';
        tsk_fprintf(hFile, "Device Manufacturer: %s\n", buf);
    }

    buf_len = 512;
    if (af_get_seg(aff_info->af_file, AF_DEVICE_MODEL, NULL, buf,
            &buf_len) == 0) {
        buf[buf_len] = '\0';
        tsk_fprintf(hFile, "Device Model: %s\n", buf);
    }

    buf_len = 512;
    if (af_get_seg(aff_info->af_file, AF_DEVICE_SN, NULL, buf,
            &buf_len) == 0) {
        buf[buf_len] = '\0';
        tsk_fprintf(hFile, "Device SN: %s\n", buf);
    }

    return;
}
Ejemplo n.º 16
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);
}
Ejemplo n.º 17
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;
}
Ejemplo n.º 18
0
int		AffNode::addSegmentAttribute(Attributes* vmap, AFFILE* af, const char* segname)
{
#ifdef NEW_AFF_LIB
    uint32_t arg;
#else
    unsigned long arg;
#endif
    unsigned char *data = 0;
    if (segname[0] == 0)
        return (0);

    size_t data_len = 0;

    if(af_get_seg(af, segname, &arg, 0, &data_len))
    {
        return (0);
    }
    data = (unsigned char *)malloc(data_len);
    if(af_get_seg(af, segname, 0, data, &data_len))
    {
        free(data);
        return (0);
    }

    if(strcmp(segname, AF_ACQUISITION_SECONDS) == 0)
    {
        int hours = arg / 3600;
        int minutes = (arg / 60) % 60;
        int seconds = arg % 60;

        vtime*	time = new vtime;
        time->hour = hours;
        time->minute = minutes;
        time->second = seconds;
        (*vmap)[std::string(segname)] = new Variant(time);
        free(data);
        return (1);
    }

    if(((arg == AF_SEG_QUADWORD) && (data_len==8)) || af_display_as_quad(segname))
    {
        switch(data_len)
        {
        case 8:
            (*vmap)[segname] = new Variant(af_decode_q(data));
            break;
        case 0:
            (*vmap)[segname] = new Variant(0);
            break;
        default:
            (*vmap)[segname] = new Variant(std::string("Cannot decode segment"));
        }
        free(data);
        return (1);
    }
    if (data_len == 0 && arg != 0)
    {
        (*vmap)[std::string(segname)] = new Variant((uint64_t)arg);
        free(data);
        return (1);
    }

    if(af_display_as_hex(segname) || (data_len == 16 && strstr(segname, "md5")) || (data_len == 20 && strstr(segname, "sha1")))
    {
        char buf[80];

        af_hexbuf(buf, sizeof(buf), data, data_len, AF_HEXBUF_NO_SPACES);
        (*vmap)[std::string(segname)] = new Variant(std::string(buf));
        free(data);
        return (1);
    }
    else
    {
        (*vmap)[segname] = new Variant(std::string((char *)data));
        free(data);
        return (1);
    }
}
Ejemplo n.º 19
0
int fix(const char *infile)
{
    char buf[1024];
    int flags = (opt_fix ? O_RDWR : O_RDONLY) | O_BINARY;
    switch(af_identify_file_type(infile,1)){
    case AF_IDENTIFY_ERR:
	perror(infile);
	return 0;
    default:
	fprintf(stderr,"%s is not an AFF file\n",infile);
	return 0;
    case AF_IDENTIFY_AFF:
	break;
    }

    printf("%s  ",infile);
    int r=0;

    /* First see if the if the file begins with an AFF flag */
    int fd = open(infile,flags,0666);
    if(fd<0) err(1,"fopen(%s)",infile);
    if(read(fd,buf,strlen(AF_HEADER)+1)!=strlen(AF_HEADER)+1)
	err(1,"can't read AFF file header. Stop.");
    if(strcmp(buf,AF_HEADER)!=0)
	err(1,"%s does not begin with an AF_HEADER. Stop.",infile);
    if(read(fd,buf,strlen(AF_SEGHEAD)+1)!=strlen(AF_SEGHEAD)+1)
	err(1,"Can't read AF_SEGHEAD after AF_HEADER. Stop.");
    if(strcmp(buf,AF_SEGHEAD)!=0)
	err(1,"%s does not have an AF_SEGHEAD after AF_SEGEADER. Stop.",infile);

    /* Figure out length */
    off_t len = lseek(fd,0,SEEK_END);
    if(len<0) err(1,"Can't seek to end of %s. Stop.",infile);
    close(fd);
    
    AFFILE *af = af_open_with(infile,AF_HALF_OPEN|flags,0,&vnode_aff);
    printf("Scanning AFF file...\n");
    r = (*af->v->open)(af);
    /* See if we can build a TOC */
    if(r<0){
	printf("AFF file corrupt at %"I64d" out of %"I64d" (%"I64d" bytes from end)\n",
	       ftello(af->aseg),(int64_t)len,len-ftello(af->aseg));
	if(opt_fix){
	    printf("Truncating... %d \n",fileno(af->aseg));
	    if(ftruncate(fileno(af->aseg),ftello(af->aseg))){
		err(1,"ftruncate");
	    }
	}
    }

    /* See if it has a GID or an encrypted GID */
    if(af_get_seg(af,AF_IMAGE_GID,0,0,0)!=0 &&
       af_get_seg(af,AF_IMAGE_GID AF_AES256_SUFFIX,0,0,0)!=0){
	printf("AFF file is missing a GID. ");
	if(opt_fix){
	    printf("Making one...");
	    if(af_make_gid(af)<0) af_err(1,"af_make_gid");
	}
	putchar('\n');
    }

    af_close(af);

    return 0;
}
Ejemplo n.º 20
0
/* af_open_with is the real open routine.
 * It opens a particular file with a particular vnode implementation.
 */
AFFILE *af_open_with(const char *url,int flags,int mode, struct af_vnode *v)
{
    /* Alloate the space for the AFFILE structure */
    AFFILE *af = (AFFILE *)calloc(sizeof(AFFILE),1);
    af_crypto_allocate(af);
#ifdef HAVE_PTHREAD
    pthread_rwlock_init(&af->rwlock);
    AF_WRLOCK(af);
#endif
    af->v	  = v;
    af->version   = 2;
    af->openflags = flags | O_BINARY;	// make sure that we ask for binray
    af->openmode  = mode;
    af->image_sectorsize = 512;		// default size
    af->error_reporter = warnx;
    af->badflag   = (unsigned char *)malloc(af->image_sectorsize);

    /* Decode URL */
    af_parse_url(url,&af->protocol,&af->hostname,&af->username,&af->password,
		 &af->port,&af->fname);

    /* A null passphrase is the same as no passphrase*/
    if(af->password && af->password[0]==0){
	free(af->password);
	af->password=0;
    }
    /* If no password was set and the AFFLIB_PASSPHRASE environment variable is set, use that */
    if(af->password==0 && getenv(AFFLIB_PASSPHRASE)){
	af->password = strdup(getenv(AFFLIB_PASSPHRASE));
    }
    /* If no password is set and its in a file, get it there */
    if(af->password==0 && getenv(AFFLIB_PASSPHRASE_FILE)){
	int fd = open(AFFLIB_PASSPHRASE_FILE,O_RDONLY,0);
	if(fd>0){
	    struct stat sb;
	    if(fstat(fd,&sb)==0){
		af->password = (char *)malloc(sb.st_size);
		int r = read(fd,af->password,sb.st_size);
		if(r!=sb.st_size){
		    free(af->password);
		    af->password=0;	// couldn't read it
		}
		close(fd);
	    }
	}
    }
    /* If no password is set and its in a file, get it there */
    if(af->password==0 && getenv(AFFLIB_PASSPHRASE_FD)){
	int fd = atoi(AFFLIB_PASSPHRASE_FD);
	af->password = (char *)malloc(1);
	int buflen = 0;
	int rlen = 0;
	char mybuf[1024];

	while((rlen=read(fd,mybuf,sizeof(mybuf)))>0){
	    af->password = (char *)realloc(af->password,buflen+rlen+1);
	    memcpy(af->password+buflen,mybuf,rlen);
	    buflen += rlen;
	    af->password[buflen] = '\000';
	}
    }
		
    /* TK: If no password was set and the AFFLIB_ASK_PASS is set, ask for a passphrase */

    /* Note things for hard files */
    af->exists    = (access(af->fname,R_OK) == 0);	// does the file exist?

    /* Right now just set up the cache by hand */
    const char *cache_pages = getenv(AFFLIB_CACHE_PAGES);
    if(cache_pages) af->num_pbufs = atoi(cache_pages);
    if(af->num_pbufs<1) af->num_pbufs = AFFLIB_CACHE_PAGES_DEFAULT; // default valuen

    af->pbcache   = (struct aff_pagebuf *)calloc(af->num_pbufs,sizeof(struct aff_pagebuf));
    if(af->pbcache==0){			// if can't allocate the full amount
	af->num_pbufs = 2;		// try a significantly smaller cache
	af->pbcache   = (struct aff_pagebuf *)calloc(af->num_pbufs,sizeof(struct aff_pagebuf));
    }

    if(flags & AF_HALF_OPEN) return af;	// for low-level tools

    /* Try opening it! */
    if((*af->v->open)(af)){ 
	strlcpy(af_error_str,af->error_str,sizeof(af_error_str)); // make a copy of the error string
	af_deallocate(af);
	return 0;
    }

    /* If there is no AFFKEY and the file is read-only, don't use a password */
    if(af->password && (af_get_seg(af,AF_AFFKEY,0,0,0)!=0) && ((af->openflags & O_ACCMODE)==O_RDONLY)){
	af_sanitize_password(af);
    }

    /* Set up the encryption if requested and if this support metadata */
    if(AF_SEALING_VNODE(af) && ((flags & AF_NO_CRYPTO)==0)){
	bool can_decrypt = false;
	if(af->password){
	    struct af_vnode_info vni;
	    memset(&vni,0,sizeof(vni));
	    if((*af->v->vstat)(af,&vni)==0 && vni.supports_metadata){
		int r = 0;
		if(af_get_seg(af,AF_AFFKEY,0,0,0)!=0){ // it does not have a password
		    r = af_establish_aes_passphrase(af,af->password);
		}
		if(r==0){
		    r = af_use_aes_passphrase(af,af->password);
		    if(r==0) {
			can_decrypt = true;
		    } else {
			(*af->error_reporter)("af_open: invalid passphrase: '%s'",af->password);
		    }
		}
		af_sanitize_password(af);
	    }
	}
	
	/* Try public key... */
	if(can_decrypt==false){
	    const char *kf = getenv(AFFLIB_DECRYPTING_PRIVATE_KEYFILE);
	    if(kf){
		af_set_unseal_keyfile(af,kf);
	    }
	}
    }
	
    af_read_sizes(af);		// set up the metadata
    if(af_trace) fprintf(af_trace,"af_open_with(%s,%o,%o,%s)\n",url,flags,mode,v->name);
    return af;
}