Пример #1
0
static int aff_vstat(AFFILE *af,struct af_vnode_info *vni)
{
    memset(vni,0,sizeof(*vni));		// clear it
    vni->imagesize = af->image_size;	// we can just return this
    vni->pagesize = af->image_pagesize;
    vni->supports_compression = 1;
    vni->has_pages            = 1;
    vni->supports_metadata    = 1;
    vni->cannot_decrypt       = af_cannot_decrypt(af) ? 1 : 0;

    /* Check for an encrypted page */
    if(af->toc){
	for(int i=0;i<af->toc_count;i++){
	    if(af->toc[i].name){
		bool is_page = false;
		vni->segment_count_total++;
		if(af_segname_page_number(af->toc[i].name)>=0){
		    vni->page_count_total++;
		    is_page = true;
		}
		if(af_is_encrypted_segment(af->toc[i].name)){
		    vni->segment_count_encrypted++;
		    if(is_page) vni->page_count_encrypted++;
		}
		if(af_is_signature_segment(af->toc[i].name)){
		    vni->segment_count_signed++;
		}
	    }
	}
    }
    return 0;
}
Пример #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);

}
Пример #3
0
/*
 * afm_del_seg:
 * If it is a page segment, generate an error.
 * otherwise from the aff file.
 */
static int afm_del_seg(AFFILE *af,const char *segname)
{
    struct afm_private *ap = AFM_PRIVATE(af);
    int64_t page_num = af_segname_page_number(segname);
    if(page_num>=0){
	errno = ENOTSUP;
	return -1;
    }
    return af_del_seg(ap->aff,segname);
}
Пример #4
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);
}
Пример #5
0
int64_t	af_segname_hash_page_number(const char *name,char *hash,int hashlen)
{
  const char *cc = strchr((char *)name,'_');
    if(!cc) return -1;			// not possibly correct
    char *copy = strdup(name);		// get a local copy
    char *dd = strchr(copy,'_');
    if(!dd){free(copy);return -1;}	// really weird; shouldn't happen
    *dd++ = '\000';			// terminate at _
    if(strcmp(dd,"md5")!=0){free(copy);return -1;} // not a valid hash
    int64_t page = af_segname_page_number(copy);
    if(page<0){free(copy);return -1;}	// wasn't what we wanted
    strlcpy(hash,dd,hashlen);
    return page;
}
Пример #6
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');
    
    
}
Пример #7
0
int64_t	af_segname_hash_page_number(const char *name,char *hash,int hashlen)
{
    char copy[AF_MAX_NAME_LEN];
    const char *cc = strchr((char *)name,'_');
    if(!cc) return -1;			// not possibly correct
    strlcpy(copy,name,sizeof(copy));
    char *dd = strchr(copy,'_');
    if(!dd) return -1;		        // really weird; shouldn't happen
    *dd++ = '\000';			// terminate at _
    if(strcmp(dd,"md5")!=0) return -1;	// not a valid hash
    int64_t page = af_segname_page_number(copy);
    if(page<0) return -1;		// wasn't what we wanted
    strlcpy(hash,dd,hashlen);
    return page;
}
Пример #8
0
int raw_update_seg(AFFILE *af, const char *name,
		    unsigned long arg,const void *value,unsigned int vallen,int append)
{
    struct raw_private *rp = RAW_PRIVATE(af);

    /* Simple implementation; only updates data segments */
    int64 pagenum = af_segname_page_number(name);
    if(pagenum<0){
	errno = ENOTSUP;
	return -1;			// not a segment number
    }
    int64 pos = pagenum * af->image_pagesize; // where we are to start reading
    fseeko(rp->raw,pos,SEEK_SET);

    if(fwrite(value,vallen,1,rp->raw)==1){
	return 0;
    }
    return -1;				// some kind of error...
}
Пример #9
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;
}
Пример #10
0
static int raw_get_seg(AFFILE *af,const char *name,
		       unsigned long *arg,unsigned char *data,size_t *datalen)
{
    struct raw_private *rp = RAW_PRIVATE(af);

    /* Right now, this only supports page segments */
    int64 segnum = af_segname_page_number(name);
    if(segnum<0) return -1;		// unknown segment number

    fflush(rp->raw);			// make sure that any buffers are flushed

    int64 pos = (int64)segnum * af->image_pagesize; // where we are to start reading
    int64 bytes_left = af->image_size - pos;	// how many bytes left in the file

    int bytes_to_read = af->image_pagesize; // copy this many bytes, unless
    if(bytes_to_read > bytes_left) bytes_to_read = bytes_left; // only this much is left
    
    if(arg) *arg = 0;			// arg is always 0
    if(datalen){
	if(*datalen==0 && data==0){ // asked for 0 bytes, so give the actual size
	    *datalen = bytes_to_read;
	    return 0;
	}
	if(*datalen < (unsigned)bytes_to_read){
	    *datalen = bytes_to_read;
	    return AF_ERROR_DATASMALL;
	}
    }
    if(data){
	fseeko(rp->raw,pos,SEEK_SET);    
	int bytes_read = fread(data,1,bytes_to_read,rp->raw);
	if(bytes_read==bytes_to_read){
	    if(datalen) *datalen = bytes_read;
	    return 0;
	}
	return -1;			// some kind of EOF?
    }
    return 0;				// no problems!
}
Пример #11
0
static int raw_get_seg(AFFILE *af,const char *name,
		       uint32_t *arg,unsigned char *data,size_t *datalen)
{
    struct raw_private *rp = RAW_PRIVATE(af);

    int64_t segnum = af_segname_page_number(name);
    if(segnum<0){
	/* See if PAGESIZE or IMAGESIZE is being requested; we can fake those */
	if(strcmp(name,AF_PAGESIZE)==0){
	    if(arg) *arg = af->image_pagesize;
	    if(datalen) *datalen = 0;
	    return 0;
	}
	if(strcmp(name,AF_IMAGESIZE)==0){
	    struct aff_quad q;
	    if(data && *datalen>=8){
		q.low = htonl((uint32_t)(af->image_size & 0xffffffff));
		q.high = htonl((uint32_t)(af->image_size >> 32));
		memcpy(data,&q,8);
		*datalen = 8;
	    }
	    return 0;
	}
	if(strcmp(name,AF_SECTORSIZE)==0){
	    if(arg) *arg = af->image_sectorsize;
	    if(datalen) *datalen = 0;
	    return 0;
	}
	if(strcmp(name,AF_DEVICE_SECTORS)==0){
	    int64_t devicesectors = af->image_size / af->image_sectorsize;
	    struct aff_quad q;
	    if(data && *datalen>=8){
		q.low = htonl((uint32_t)(devicesectors & 0xffffffff));
		q.high = htonl((uint32_t)(devicesectors >> 32));
		memcpy(data,&q,8);
		*datalen = 8;
	    }
Пример #12
0
Attributes	AffNode::_attributes()
{
    Attributes 	vmap;
    struct af_vnode_info vni;
    unsigned long total_segs = 0;
    unsigned long total_pages = 0;
    unsigned long total_hashes = 0;
    unsigned long total_signatures =0;
    unsigned long total_nulls = 0;

    vmap["orignal path"] =  new Variant(this->originalPath);
    AFFILE*  affile = af_open(this->originalPath.c_str(), O_RDONLY, 0);
    if (affile)
    {
        vmap["dump type"] = new Variant(std::string(af_identify_file_name(this->originalPath.c_str(), 1)));
        if (af_vstat(affile, &vni) == 0)
        {
            if (vni.segment_count_encrypted > 0 || vni.segment_count_signed > 0)
            {
                vmap["encrypted segments"] = new Variant(vni.segment_count_encrypted);
                vmap["signed segments"] = new Variant(vni.segment_count_signed);
            }
            vector <string> segments;
            char segname[AF_MAX_NAME_LEN];
            af_rewind_seg(affile);
            int64_t total_datalen = 0;
            size_t total_segname_len = 0;
            size_t datalen = 0;
            int aes_segs=0;
            while(af_get_next_seg(affile, segname, sizeof(segname), 0, 0, &datalen)==0)
            {
                total_segs++;
                total_datalen += datalen;
                total_segname_len += strlen(segname);
                if(segname[0]==0)
                    total_nulls++;

                char hash[64];
                int64_t page_num = af_segname_page_number(segname);
                int64_t hash_num = af_segname_hash_page_number(segname,hash,sizeof(hash));
                if(page_num>=0)
                    total_pages++;
                if(hash_num>=0)
                    total_hashes++;
                if(strstr(segname,AF_SIG256_SUFFIX))
                    total_signatures++;
                if(strstr(segname,AF_AES256_SUFFIX))
                    aes_segs++;
                if((page_num>=0||hash_num>=0))
                    continue;
                if(af_is_encrypted_segment(segname))
                    continue;
                this->addSegmentAttribute(&vmap, affile, segname);
            }
            vmap["Total segments"] = new Variant((uint64_t)total_segs);
            vmap["Total segments real"] = new Variant((uint64_t)(total_segs - total_nulls));
            if (aes_segs)
                vmap["Encrypted segments"] = new Variant(aes_segs);
            vmap["Page segments"] = new Variant((uint64_t)total_pages);
            vmap["Hash segments"] = new Variant((uint64_t)total_hashes);
            vmap["Signature segments"] = new Variant((uint64_t)total_signatures);
            vmap["Null segments"] = new Variant((uint64_t)total_nulls);
            vmap["Total data bytes"] = new Variant((uint64_t)total_datalen);
        }

    }

    af_close(affile);

    return vmap;
}