Esempio n. 1
0
static int list(const char *filename, int arglen, char *args[]) {
	xar_t x;
	xar_iter_t i;
	xar_file_t f;

	x = xar_open(filename, READ);
	if( !x ) {
		fprintf(stderr, "Error opening xar archive: %s\n", filename);
		exit(1);
	}

	i = xar_iter_new();
	if( !i ) {
		fprintf(stderr, "Error creating xar iterator\n");
		exit(1);
	}

	for(f = xar_file_first(x, i); f; f = xar_file_next(i)) {
		print_file(f);
	}

	xar_iter_free(i);
	xar_close(x);

	return Err;
}
bool InstallChecker::verifyPackage( const QString &filePath, bool )
{
	QProcess proc;
	proc.start( "hdiutil", QStringList() << "verify" << filePath );
	proc.waitForFinished();
	if( proc.exitCode() )
		return false;

	QString path = mountPackage( filePath );
	if( path.isEmpty() )
		return false;

	xar_t xar = xar_open( path.toUtf8().constData(), 0 );
	if( !xar )
		return false;

	QSslCertificate cert;
	xar_signature_t sig = xar_signature_first( xar );
	int32_t count = xar_signature_get_x509certificate_count( sig );
	for( int32_t i = 0; i < count; ++i )
	{
		uint32_t size = 0;
		const uint8_t *data = 0;
		if( xar_signature_get_x509certificate_data( sig, i, &data, &size ) )
			continue;
		QSslCertificate c( QByteArray( (const char*)data, size ), QSsl::Der );
#if QT_VERSION >= 0x050000
		QString cn = c.subjectInfo( QSslCertificate::CommonName ).value(0);
#else
		QString cn = c.subjectInfo( QSslCertificate::CommonName );
#endif
		if( cn == "Estonian Informatics Centre" ||
			cn == "Developer ID Installer: Riigi Infosüsteemi Amet" )
			cert = c;
	}

	if( cert.isNull() )
	{
		xar_close( xar );
		return false;
	}

	uint8_t *data = 0, *signature = 0;
	uint32_t dataSize = 0, signatureSize = 0;
	off_t offset = 0;
	if( xar_signature_copy_signed_data( sig, &data, &dataSize, &signature, &signatureSize, &offset ) )
	{
		xar_close( xar );
		return false;
	}

	int result = RSA_verify( NID_sha1, data, dataSize, signature, signatureSize, (RSA*)cert.publicKey().handle() );
	xar_close( xar );
	free( data );
	free( signature );

	return result;
}
Esempio n. 3
0
static int dumptoc(const char *filename, const char* tocfile) {
	xar_t x;
	x = xar_open(filename, READ);
	if( !x ) {
		fprintf(stderr, "Error opening xar archive: %s\n", filename);
		exit(1);
	}

	xar_serialize(x, tocfile);
	xar_close(x);
	return Err;
}
Esempio n. 4
0
bool IsXarFile(std::string file) {
#ifdef HAVE_LIBXAR
  xar_t x = xar_open(file.c_str(), READ);

  if (x == nullptr) return false;

  xar_close(x);
  return true;
#else
  return false;
#endif
}
Esempio n. 5
0
bool WriteTOC(std::string xarFile, std::string tocFile) {
#ifdef HAVE_LIBXAR
  xar_t x = xar_open(xarFile.c_str(), READ);

  if (x == nullptr) return false;

  xar_serialize(x, tocFile.c_str());
  xar_close(x);

  return true;
#else
  return false;
#endif
}
Esempio n. 6
0
/*	belated_sign
	Prepare a previously unsigned archive for signing by creating a signature placeholder and inserting the certificates.
	Since libxar is currently not capable of doing this directly, we have to create a new xar archive,
	copy all the files and options from the current archive, and sign the new archive
*/
static void belated_sign(const char *filename) {
	xar_t x = xar_open(filename, READ);
	if ( x == NULL ) {
		fprintf(stderr, "Could not open archive %s!\n", filename);
		exit(1);
	}
	xar_signature_t sig = xar_signature_first(x);
	if ( sig ) {
		fprintf(stderr, "Archive has already been signed. Use --replace-sign instead.\n");
		exit(E_SIGEXISTS);
	}
	xar_close(x);
	replace_sign(filename);
}
Esempio n. 7
0
static void extract_certs(char *filename, char *cert_base_path) {
	xar_signature_t sig;
	xar_t x;
	int32_t count;
	int i;
	const uint8_t *cert_data;
	uint32_t cert_len;
	FILE *file;
	char *cert_path;
	
	// open xar, get signature
	x = xar_open(filename, READ);
	if ( x == NULL ) {
		fprintf(stderr, "Could not open %s to extract certificates!\n", filename);
		exit(1);
	}
	sig = xar_signature_first(x);
	if ( !sig ) {
		fprintf(stderr, "No signatures found to extract data from.\n");
		exit(E_NOSIG);
	}
	
	// iterate through all certificates associated with that signature, write them to disk
	count = xar_signature_get_x509certificate_count(sig);
	if (!count) {
		fprintf(stderr, "Signature bears no certificates. Odd.\n");
		exit(1);
	}
	for (i=0; i<count; i++) {
		xar_signature_get_x509certificate_data(sig, i, &cert_data, &cert_len);
		asprintf(&cert_path, "%s/cert%02i", cert_base_path, i);
		file = fopen(cert_path, "w");
		if (!file) {
			fprintf(stderr, "Could not save certificate %i to %s.\n", i, cert_path);
			exit(1);
		}
		int n = fwrite(cert_data, cert_len, 1, file);
		if (n < 0) {
			fprintf(stderr, "Failed to write certificate to %s (fwrite() returned %i)!\n", cert_path, n);
			exit(1);
		}
		fclose(file);
		free(cert_path);
	}

	// clean up
	xar_close(x);
}
Esempio n. 8
0
static void inject_signature(const char *xar_path, const char *sig_path) {
	// since there is no API to insert a signature other than during signingCallback time, we have to
	// inject it by editing the raw file
	int buffer_size = 1024;
	void *buffer = malloc(buffer_size);
	FILE *sig, *xar;
	off_t signedDataOffset;
	xar_t x;
	int i;
	
	printf("inject_signature(%s, %s)",xar_path,sig_path);
	
	// open xar via the API first to determine the signature offset
	x = xar_open(xar_path, READ);
	if ( x == NULL ) {
		fprintf(stderr, "Could not open xar archive %s to get signature offset!\n", xar_path);
		exit(1);
	}
	signedDataOffset = get_sig_offset(x);
	xar_close(x);
	
	// then re-open xar and signature files raw...
	sig = fopen(sig_path, "r");
	if (!sig) {
		fprintf(stderr, "Could not open %s for reading signature!\n", sig_path);
		exit(1);
	}
	xar = fopen(xar_path, "r+");
	if (!xar) {
		fprintf(stderr, "Could not open xar archive %s for injecting signature!\n", xar_path);
		exit(1);
	}
	
	// ...and inject the signature
	fseek(xar, signedDataOffset, SEEK_SET);
	do {
		i = fread(buffer, 1, buffer_size, sig);
		if (ferror(sig)) {
			fprintf(stderr, "Failed to read signature from %s!\n", sig_path);
			exit(1);
		}
		fwrite(buffer, 1, i, xar);
	} while (!feof(sig));
	fclose(sig);
	fclose(xar);
	
	free(buffer);
}
Esempio n. 9
0
static int list_subdocs(const char *filename) {
	xar_t x;
	xar_subdoc_t s;

	x = xar_open(filename, READ);
	if( !x ) {
		fprintf(stderr, "Error opening xar archive: %s\n", filename);
		exit(1);
	}

	for(s = xar_subdoc_first(x); s; s = xar_subdoc_next(s)) {
		printf("%s\n", xar_subdoc_name(s));
	}
	xar_close(x);

	return Err;
}
Esempio n. 10
0
int main(int argc, char *argv[]) {
    char *file = argv[1];
    xar_t x;
    xar_iter_t ifile, iprop, iattr;
    xar_file_t f;
    const char *key;
    int fd;
    off_t off;
    xar_header_t hdr;

    x = xar_open(file, READ);
    if( !x ) {
        fprintf(stderr, "Error opening archive\n");
        exit(1);
    }

    fd = open(file, O_RDONLY);
    if( fd < 0 ) {
        fprintf(stderr, "Error opening archive\n");
        exit(1);
    }

    read(fd, &hdr, sizeof(hdr));
    hdr.size = htons(hdr.size);
    hdr.toc_length_compressed = xar_ntoh64(hdr.toc_length_compressed);
    HeapOff = hdr.size + hdr.toc_length_compressed;

    ifile = xar_iter_new();
    if( !ifile ) {
        fprintf(stderr, "Error creating file iterator");
        exit(1);
    }

    for(f = xar_file_first(x, ifile); f; f = xar_file_next(ifile)) {
        prop_check(fd, x, f);
    }

}
Esempio n. 11
0
static int archive(const char *filename, int arglen, char *args[]) {
	xar_t x;
	FTS *fts;
	FTSENT *ent;
	int flags;
	struct lnode *i;
	const char *default_compression;

	x = xar_open(filename, WRITE);
	if( !x ) {
		fprintf(stderr, "Error creating archive %s\n", filename);
		exit(1);
	}

	if ( SigSize ) {
		xar_signature_t sig = xar_signature_new(x, "RSA", SigSize, &signingCallback, NULL);
		if ( LeafCertPath )
			insert_cert(sig, LeafCertPath);
		if ( IntermediateCertPath )
			insert_cert(sig, IntermediateCertPath);
	}
	
	if( Toccksum )
		xar_opt_set(x, XAR_OPT_TOCCKSUM, Toccksum);

	if( Compression )
		xar_opt_set(x, XAR_OPT_COMPRESSION, Compression);

	if( Coalesce )
		xar_opt_set(x, XAR_OPT_COALESCE, "true");

	if( LinkSame )
		xar_opt_set(x, XAR_OPT_LINKSAME, "true");

	if ( Rsize != NULL )
		xar_opt_set(x, XAR_OPT_RSIZE, Rsize);

	xar_register_errhandler(x, err_callback, NULL);

	if( Subdoc )
		add_subdoc(x);

	if( Perms == SYMBOLIC ) {
		xar_opt_set(x, XAR_OPT_OWNERSHIP, XAR_OPT_VAL_SYMBOLIC);
	}
	if( Perms == NUMERIC ) {
		xar_opt_set(x, XAR_OPT_OWNERSHIP, XAR_OPT_VAL_NUMERIC);
	}

	default_compression = strdup(xar_opt_get(x, XAR_OPT_COMPRESSION));
	if( !default_compression )
		default_compression = strdup(XAR_OPT_VAL_GZIP);

	flags = FTS_PHYSICAL|FTS_NOSTAT|FTS_NOCHDIR;
	if( Local )
		flags |= FTS_XDEV;
	fts = fts_open(args, flags, NULL);
	if( !fts ) {
		fprintf(stderr, "Error traversing file tree\n");
		exit(1);
	}

	while( (ent = fts_read(fts)) ) {
		xar_file_t f;
		int exclude_match = 1;
		int nocompress_match = 1;
		if( ent->fts_info == FTS_DP )
			continue;

		if( strcmp(ent->fts_path, "/") == 0 )
			continue;
		if( strcmp(ent->fts_path, ".") == 0 )
			continue;
		
		for( i = Exclude; i; i=i->next ) {
			exclude_match = regexec(&i->reg, ent->fts_path, 0, NULL, 0);
			if( !exclude_match )
				break;
		}
		if( !exclude_match ) {
			if( Verbose )
				printf("Excluding %s\n", ent->fts_path);
			continue;
		}

		for( i = NoCompress; i; i=i->next ) {
			nocompress_match = regexec(&i->reg, ent->fts_path, 0, NULL, 0);
			if( !nocompress_match ) {
				xar_opt_set(x, XAR_OPT_COMPRESSION, XAR_OPT_VAL_NONE);
				break;
			}
		}
		f = xar_add(x, ent->fts_path);
		if( !f ) {
			fprintf(stderr, "Error adding file %s\n", ent->fts_path);
		} else {
			print_file(f);
		}
		if( !nocompress_match )
			xar_opt_set(x, XAR_OPT_COMPRESSION, default_compression);
	}
	fts_close(fts);
	if( xar_close(x) != 0 ) {
		fprintf(stderr, "Error creating the archive\n");
		if( !Err )
			Err = 42;
	}

	free((char *)default_compression);
	for( i = Exclude; i; ) {
		struct lnode *tmp;
		regfree(&i->reg);
		tmp = i;
		i = i->next;
		free(tmp);
	}
	for( i = NoCompress; i; ) {
		struct lnode *tmp;
		regfree(&i->reg);
		tmp = i;
		i = i->next;
		free(tmp);
	}

	if ( SigOffsetDumpPath ) {
		x = xar_open(filename, READ);
		if( !x ) {
			fprintf(stderr, "Error re-opening archive %s\n", filename);
			exit(1);
		}
		if (extract_sig_offset(x, SigOffsetDumpPath)) 
			exit(1);
	}
	
	return Err;
}
Esempio n. 12
0
int main(int argc, char *argv[]) {
	xar_t x;
	xar_iter_t i;
	xar_file_t f;
	xar_stream s;
	char buffer[8192];

	x = xar_open(argv[1], READ);
	if( !x ) {
		fprintf(stderr, "Error opening archive\n");
		exit(1);
	}

	xar_register_errhandler(x, err_callback, NULL);

	i = xar_iter_new();
	if( !i ) {
		fprintf(stderr, "Error creating xar iterator\n");
		exit(1);
	}

	for(f = xar_file_first(x, i); f; f = xar_file_next(i)) {
		char *path;
		const char *type;
		int32_t ret;
		int fd;

		path = xar_get_path(f);

		xar_prop_get(f, "type", &type);
		if( !type ) {
			fprintf(stderr, "File has no type %s\n", path);
			free(path);
			continue;
		}
		if( strcmp(type, "file") != 0 ) {
			fprintf(stderr, "Skipping %s\n", path);
			free(path);
			continue;
		}
	
		fprintf(stderr, "Extracting %s\n", path);
		if( xar_extract_tostream_init(x, f, &s) != XAR_STREAM_OK ) {
			fprintf(stderr, "Error initializing stream %s\n", path);
			free(path);
			continue;
		}
		
		fd = open(path, O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR);
		if( !fd ) {
			fprintf(stderr, "Error opening output file %s\n", path);
			free(path);
			continue;
		}
		s.avail_out = sizeof(buffer);
		s.next_out = buffer;

		while( (ret = xar_extract_tostream(&s)) != XAR_STREAM_END ) {
			if( ret == XAR_STREAM_ERR ) {
				fprintf(stderr, "Error extracting stream %s\n", path);
				exit(2);
			}

			write(fd, buffer, sizeof(buffer)-s.avail_out);

			s.avail_out = sizeof(buffer);
			s.next_out = buffer;
		}

		if( xar_extract_tostream_end(&s) != XAR_STREAM_OK ) {
			fprintf(stderr, "Error ending stream %s\n", path);
		}

		close(fd);
		free(path);
	}
}
Esempio n. 13
0
static int list(const char *filename, int arglen, char *args[]) {
	xar_t x;
	xar_iter_t i;
	xar_file_t f;
	int argi = 0;
	struct lnode *list_files = NULL;
	struct lnode *list_tail = NULL;
	struct lnode *lnodei = NULL;

	for(argi = 0; args[argi]; argi++) {
		struct lnode *tmp;
		int err;
		tmp = malloc(sizeof(struct lnode));
		tmp->str = strdup(args[argi]);
		tmp->next = NULL;
		err = regcomp(&tmp->reg, tmp->str, REG_NOSUB);
		if( err ) {
			char errstr[1024];
			regerror(err, &tmp->reg, errstr, sizeof(errstr));
			printf("Error with regular expression %s: %s\n", tmp->str, errstr);
			exit(1);
		}
		if( list_files == NULL ) {
			list_files = tmp;
			list_tail = tmp;
		} else {
			list_tail->next = tmp;
			list_tail = tmp;
		}
	}

	x = xar_open(filename, READ);
	if( !x ) {
		fprintf(stderr, "Error opening xar archive: %s\n", filename);
		exit(1);
	}

	i = xar_iter_new();
	if( !i ) {
		fprintf(stderr, "Error creating xar iterator\n");
		exit(1);
	}

	for(f = xar_file_first(x, i); f; f = xar_file_next(i)) {
		int matched = 0;

		if( args[0] ) {
			char *path = xar_get_path(f);
			
			if (xar_path_issane(path) == 0) {
				fprintf(stderr, "Warning, archive contains invalid path: %s\n", path);
				free(path);
				continue;
			}

			for(lnodei = list_files; lnodei != NULL; lnodei = lnodei->next) {
				int list_match = 1;

				list_match = regexec(&lnodei->reg, path, 0, NULL, 0);
				if( !list_match ) {
					matched = 1;
					break;
				}
			}
			free(path);
		} else {
			matched = 1;
		}

		if( matched )
			print_file(x, f);
	}

	xar_iter_free(i);
	xar_close(x);

	for(lnodei = list_files; lnodei != NULL; ) {
		struct lnode *tmp;
		free(lnodei->str);
		regfree(&lnodei->reg);
		tmp = lnodei;
		lnodei = lnodei->next;
		free(tmp);
	}

	return Err;
}
Esempio n. 14
0
int main(int argc, char *argv[]) {
	int ret;
	char *filename = NULL;
	char command = 0, c;
	char **args;
	const char *tocfile = NULL;
	int arglen, i, err;
	xar_t x;
	int loptind = 0;
	int required_dash_f = 0;  /* This release requires us to use -f */
	struct lnode *tmp;
	long int longtmp;
	struct option o[] = { 
		{"toc-cksum", 1, 0, 1},
		{"dump-toc", 1, 0, 'd'},
		{"compression", 1, 0, 2},
		{"list-subdocs", 0, 0, 3},
		{"help", 0, 0, 'h'},
		{"version", 0, 0, 4},
		{"dump-header", 0, 0, 5},
		{"extract-subdoc", 1, 0, 6},
		{"exclude", 1, 0, 7},
		{"rsize", 1, 0, 8},
		{"coalesce-heap", 0, 0, 9},
		{"link-same", 0, 0, 10},
		{"no-compress", 1, 0, 11},
		{"prop-include", 1, 0, 12},
		{"prop-exclude", 1, 0, 13},
		{"distribution", 0, 0, 14},
		{"keep-existing", 0, 0, 15},
		{"keep-setuid", 0, 0, 16},
		{"compression-args", 1, 0, 17},
		{ 0, 0, 0, 0}
	};

	if( argc < 2 ) {
		usage(argv[0]);
		exit(1);
	}

	while( (c = getopt_long(argc, argv, "axcC:vtjzf:hpPln:s:d:vk", o, &loptind)) != -1 ) {
		switch(c) {
		case  1 : if( !optarg ) {
		          	usage(argv[0]);
		          	exit(1);
		          }
		          if( (strcmp(optarg, XAR_OPT_VAL_NONE) != 0) &&
		              (strcmp(optarg, XAR_OPT_VAL_SHA1) != 0) &&
		              (strcmp(optarg, XAR_OPT_VAL_MD5)  != 0) ) {
		          	usage(argv[0]);
		          	exit(1);
		          }
		          Toccksum = optarg;
		
		          break;
		case  2 : if( !optarg ) {
		          	usage(argv[0]);
		          	exit(1);
		          }
		          if( (strcmp(optarg, XAR_OPT_VAL_NONE) != 0) &&
		              (strcmp(optarg, XAR_OPT_VAL_GZIP) != 0) &&
		              (strcmp(optarg, XAR_OPT_VAL_BZIP) != 0) &&
		              (strcmp(optarg, XAR_OPT_VAL_LZMA) != 0) ) {
		          	usage(argv[0]);
		          	exit(1);
		          }
		          Compression = optarg;
		          break;
		case  3 : if( command && (command != 3) ) {
		          	fprintf(stderr, "Conflicting commands specified\n");
				exit(1);
		          }
			  command = 3;
			  break;
		case  4 : print_version();
		          exit(0);
		case 'd':
			if( !optarg ) {
				usage(argv[0]);
				exit(1);
			}
			tocfile = optarg;
			command = 'd';
			break;
		case  5 : command = 5;
		          break;
		case  6 :
			SubdocName = optarg;
			asprintf(&Subdoc, "%s.xml", SubdocName);
			if( !command )
				command = 6;
			break;
		case  7 :
			tmp = malloc(sizeof(struct lnode));
			tmp->str = optarg;
			tmp->next = NULL;
			err = regcomp(&tmp->reg, tmp->str, REG_NOSUB);
			if( err ) {
				char errstr[1024];
				regerror(err, &tmp->reg, errstr, sizeof(errstr));
				printf("Error with regular expression %s: %s\n", tmp->str, errstr);
				exit(1);
			}
			if( Exclude == NULL ) {
				Exclude = tmp;
				Exclude_Tail = tmp;
			} else {
				Exclude_Tail->next = tmp;
				Exclude_Tail = tmp;
			}
			break;
		case  8 :
			if ( !optarg ) {
				usage(argv[0]);
				exit(1);
			}
			longtmp = strtol(optarg, NULL, 10);
			if( (((longtmp == LONG_MIN) || (longtmp == LONG_MAX)) && (errno == ERANGE)) || (longtmp < 1) ) {
				fprintf(stderr, "Invalid rsize value: %s\n", optarg);
				exit(5);
			}
			Rsize = optarg;
			break;
		case  9 : Coalesce = 1; break;
		case 10 : LinkSame = 1; break;
		case 11 :
			tmp = malloc(sizeof(struct lnode));
			tmp->str = optarg;
			tmp->next = NULL;
			err = regcomp(&tmp->reg, tmp->str, REG_NOSUB);
			if( err ) {
				char errstr[1024];
				regerror(err, &tmp->reg, errstr, sizeof(errstr));
				printf("Error with regular expression %s: %s\n", tmp->str, errstr);
				exit(1);
			}
			if( NoCompress == NULL ) {
				NoCompress = tmp;
				NoCompress_Tail = tmp;
			} else {
				NoCompress_Tail->next = tmp;
				NoCompress_Tail = tmp;
			}
			break;
		case 12 :
			tmp = malloc(sizeof(struct lnode));
			tmp->str = optarg;
			tmp->next = NULL;
			if( PropInclude == NULL ) {
				PropInclude = tmp;
				PropInclude_Tail = tmp;
			} else {
				PropInclude_Tail->next = tmp;
				PropInclude_Tail = tmp;
			}
			break;
		case 13 :
			tmp = malloc(sizeof(struct lnode));
			tmp->str = optarg;
			tmp->next = NULL;
			if( PropExclude == NULL ) {
				PropExclude = tmp;
				PropExclude_Tail = tmp;
			} else {
				PropExclude_Tail->next = tmp;
				PropExclude_Tail = tmp;
			}
			break;
		case 14 :
		{
			char *props[] = { "type", "data", "mode", "name" };
			int i;
			for( i = 0; i < 4; i++ ) {
				tmp = malloc(sizeof(struct lnode));
				tmp->str = strdup(props[i]);
				tmp->next = NULL;
				if( PropInclude == NULL ) {
					PropInclude = tmp;
					PropInclude_Tail = tmp;
				} else {
					PropInclude_Tail->next = tmp;
					PropInclude_Tail = tmp;
				}
			}
		}
			break;
		case 'k':
		case 15 :
			NoOverwrite++;
			break;
		case 16 :
			SaveSuid++;
			break;
		case 17 :
			CompressionArg = optarg;
			break;
		case 'C': if( !optarg ) {
		          	usage(argv[0]);
		          	exit(1);
		          }
		          Chdir = optarg;
		          break;
		case 'c':
		case 'x':
		case 't':
			if( command && (command != 's') ) {
				usage(argv[0]);
				fprintf(stderr, "Conflicting command flags: %c and %c specified\n", c, command);
				exit(1);
			}
			if( c == 't' )
				List = 1;
			command = c;
			break;
		case 'a':
			Compression = "lzma";
			break;
		case 'j':
			Compression = "bzip2";
			break;
		case 'z':
			Compression = "gzip";
			break;
		case 'f':
		        required_dash_f = 1;
			filename = optarg;
			break;
		case 'p':
			Perms = SYMBOLIC;
			break;
		case 'P':
			Perms = NUMERIC;
			break;
		case 'l':
			Local = 1;
			break;
		case 'n':
			SubdocName = optarg;
			break;
		case 's':
			Subdoc = optarg;
			if( !command )
				command = 's';
			break;
		case 'v':
			Verbose++;
			break;
		case 'h':
		default:
			usage(argv[0]);
			exit(1);
		}
	}

	if (! required_dash_f)	{
		usage(argv[0]);
		fprintf(stderr, "\n -f option is REQUIRED\n");
		exit(1);
	}

	switch(command) {
		case  5 : 
		        return dump_header(filename);
		case  3 : 
			return list_subdocs(filename);
		case 'c':
			if( optind == argc ) {
				usage(argv[0]);
				fprintf(stderr, "No files to operate on.\n");
				exit(1);
			}
			arglen = argc - optind;
			args = malloc(sizeof(char*) * (arglen+1));
			memset(args, 0, sizeof(char*) * (arglen+1));
			for( i = 0; i < arglen; i++ )
				args[i] = strdup(argv[optind + i]);

			return archive(filename, arglen, args);
		case 'd':
			if( !tocfile ) {
				usage(argv[0]);
				exit(1);
			}
			return dumptoc(filename, tocfile);
		case 'x':
			arglen = argc - optind;
			args = malloc(sizeof(char*) * (arglen+1));
			for( i = 0; i < arglen; i++ )
				args[i] = strdup(argv[optind + i]);
			args[i] = NULL;
			return extract(filename, arglen, args);
		case 't':
			arglen = argc - optind;
			args = calloc(sizeof(char*) * (arglen+1),1);
			for( i = 0; i < arglen; i++ )
				args[i] = strdup(argv[optind + i]);
			ret = list(filename, arglen, args);
			for( i = 0; i < arglen; i++ )
				free(args[i]);
		case  6 :
		case 's':
			x = xar_open(filename, READ);
			if( !x ) {
				fprintf(stderr, "Error opening xar archive: %s\n", filename);
				exit(1);
			}
			xar_register_errhandler(x, err_callback, NULL);
			extract_subdoc(x, SubdocName);
			xar_close(x);
			exit(Err);
			break;
		default:
			usage(argv[0]);
			fprintf(stderr, "Unrecognized command.\n");
			exit(1);
	}

	/* unreached */
	exit(0);
}
Esempio n. 15
0
static int extract(const char *filename, int arglen, char *args[]) {
	xar_t x;
	xar_iter_t i;
	xar_file_t f;
	int files_extracted = 0;
	int argi;
	struct lnode *extract_files = NULL;
	struct lnode *extract_tail = NULL;
	struct lnode *lnodei = NULL;
	struct lnode *dirs = NULL;

	for(argi = 0; args[argi]; argi++) {
		struct lnode *tmp;
		int err;
		tmp = malloc(sizeof(struct lnode));
		tmp->str = strdup(args[argi]);
		tmp->next = NULL;
		err = regcomp(&tmp->reg, tmp->str, REG_NOSUB);
		if( err ) {
			char errstr[1024];
			regerror(err, &tmp->reg, errstr, sizeof(errstr));
			printf("Error with regular expression %s: %s\n", tmp->str, errstr);
			exit(1);
		}
		if( extract_files == NULL ) {
			extract_files = tmp;
			extract_tail = tmp;
		} else {
			extract_tail->next = tmp;
			extract_tail = tmp;
		}
		
		/* Add a clause for recursive extraction */
		tmp = malloc(sizeof(struct lnode));
		asprintf(&tmp->str, "%s/.*", args[argi]);
		tmp->next = NULL;
		err = regcomp(&tmp->reg, tmp->str, REG_NOSUB);
		if( err ) {
			char errstr[1024];
			regerror(err, &tmp->reg, errstr, sizeof(errstr));
			printf("Error with regular expression %s: %s\n", tmp->str, errstr);
			exit(1);
		}
		if( extract_files == NULL ) {
			extract_files = tmp;
			extract_tail = tmp;
		} else {
			extract_tail->next = tmp;
			extract_tail = tmp;
		}
	}

	x = xar_open(filename, READ);
	if( !x ) {
		fprintf(stderr, "Error opening xar archive: %s\n", filename);
		exit(1);
	}

	if(Chdir) {
		if( chdir(Chdir) != 0 ) {
			fprintf(stderr, "Unable to chdir to %s\n", Chdir);
			exit(1);
		}
	}

	xar_register_errhandler(x, err_callback, NULL);

	if( Perms == SYMBOLIC ) {
		xar_opt_set(x, XAR_OPT_OWNERSHIP, XAR_OPT_VAL_SYMBOLIC);
	}
	if( Perms == NUMERIC ) {
		xar_opt_set(x, XAR_OPT_OWNERSHIP, XAR_OPT_VAL_NUMERIC);
	}
	if ( Rsize != NULL ) {
		xar_opt_set(x, XAR_OPT_RSIZE, Rsize);
	}
	if( SaveSuid ) {
		xar_opt_set(x, XAR_OPT_SAVESUID, XAR_OPT_VAL_TRUE);
	}
	
	i = xar_iter_new();
	if( !i ) {
		fprintf(stderr, "Error creating xar iterator\n");
		exit(1);
	}

	for(f = xar_file_first(x, i); f; f = xar_file_next(i)) {
		int matched = 0;
		int exclude_match = 1;
		struct lnode *i;

		char *path = xar_get_path(f);

		if( args[0] ) {
			for(i = extract_files; i != NULL; i = i->next) {
				int extract_match = 1;

				extract_match = regexec(&i->reg, path, 0, NULL, 0);
				if( !extract_match ) {
					matched = 1;
					break;
				}
			}
		} else {
			matched = 1;
		}

		for( i = Exclude; i; i=i->next ) {
			exclude_match = regexec(&i->reg, path, 0, NULL, 0);
			if( !exclude_match )
				break;
		}
		if( !exclude_match ) {
			if( Verbose )
				printf("Excluding %s\n", path);
			free(path);
			continue;
		}
		
		if (!xar_path_issane(path)) {
			if (Verbose)
				printf("Warning, not extracting file \"%s\" because it's path is invalid.\n", path);
			free(path);
			continue;
		}
		
		if( matched ) {
			struct stat sb;
			if( NoOverwrite && (lstat(path, &sb) == 0) ) {
				printf("%s already exists, not overwriting\n", path);
			} else {
				const char *prop = NULL;
				int deferred = 0;
				if( xar_prop_get(f, "type", &prop) == 0 ) {
					if( strcmp(prop, "directory") == 0 ) {
						struct lnode *tmpl = calloc(sizeof(struct lnode),1);
						tmpl->str = (char *)f;
						tmpl->next = dirs;
						dirs = tmpl;
						deferred = 1;
					}
				}
				if( ! deferred ) {
					files_extracted++;
					print_file(x, f);
					xar_extract(x, f);
				}
			}
		}
		free(path);
	}
	for(lnodei = dirs; lnodei; lnodei = lnodei->next) {
		files_extracted++;
		print_file(x,(xar_file_t)lnodei->str);
		xar_extract(x, (xar_file_t)lnodei->str);
	}
	if( args[0] && (files_extracted == 0) ) {
		fprintf(stderr, "No files matched extraction criteria.\n");
		Err = 3;
	}

	if( Subdoc )
		extract_subdoc(x, NULL);

	xar_iter_free(i);
	if( xar_close(x) != 0 ) {
		fprintf(stderr, "Error extracting the archive\n");
		if( !Err )
			Err = 42;
	}

	for(lnodei = extract_files; lnodei != NULL; ) {
		struct lnode *tmp;
		free(lnodei->str);
		regfree(&lnodei->reg);
		tmp = lnodei;
		lnodei = lnodei->next;
		free(tmp);
	}
	return Err;
}
Esempio n. 16
0
int main(int argc, char *argv[]) {
	char *filename = NULL;
	char *sig_path = NULL;
	char *cert_path = NULL;
	char command = 0, c;
	char **args;
	const char *tocfile = NULL;
	int arglen, i, err;
	xar_t x;
	int loptind = 0;
	int required_dash_f = 0;  /* This release requires us to use -f */
	struct lnode *tmp;
	long int longtmp;
	struct stat stat_struct;
	struct option o[] = { 
		{"toc-cksum", 1, 0, 1},
		{"dump-toc", 1, 0, 'd'},
		{"compression", 1, 0, 2},
		{"list-subdocs", 0, 0, 3},
		{"help", 0, 0, 'h'},
		{"version", 0, 0, 4},
		{"dump-header", 0, 0, 5},
		{"extract-subdoc", 1, 0, 6},
		{"exclude", 1, 0, 7},
		{"rsize", 1, 0, 8},
		{"coalesce-heap", 0, 0, 9},
		{"link-same", 0, 0, 10},
		{"no-compress", 1, 0, 11},
		{"sig-size", 1, 0, 12},
		{"data-to-sign", 1, 0, 13},
		{"sig-offset", 1, 0, 14},
		{"leaf-cert-loc", 1, 0, 15},
		{"intermediate-cert-loc", 1, 0, 16},
		{"extract-data-to-sign", 0, 0, 17},
		{"sign", 0, 0, 18},
		{"replace-sign", 0, 0, 19},
		{"inject-sig", 1, 0, 20},
		{"extract-certs", 1, 0, 21},
		{ 0, 0, 0, 0}
	};

	if( argc < 2 ) {
		usage(argv[0]);
		exit(1);
	}

	while( (c = getopt_long(argc, argv, "xcvtf:hpPln:s:d:v", o, &loptind)) != -1 ) {
		switch(c) {
		case  1 : if( !optarg ) {
		          	usage(argv[0]);
		          	exit(1);
		          }
		          if( (strcmp(optarg, XAR_OPT_VAL_NONE) != 0) &&
		              (strcmp(optarg, XAR_OPT_VAL_SHA1) != 0) &&
		              (strcmp(optarg, XAR_OPT_VAL_MD5)  != 0) ) {
		          	usage(argv[0]);
		          	exit(1);
		          }
		          Toccksum = optarg;
		
		          break;
		case  2 : if( !optarg ) {
		          	usage(argv[0]);
		          	exit(1);
		          }
		          if( (strcmp(optarg, XAR_OPT_VAL_NONE) != 0) &&
		              (strcmp(optarg, XAR_OPT_VAL_GZIP) != 0) &&
		              (strcmp(optarg, XAR_OPT_VAL_BZIP) != 0) ) {
		          	usage(argv[0]);
		          	exit(1);
		          }
		          Compression = optarg;
		          break;
		case  3 : if( command && (command != 3) ) {
		          	fprintf(stderr, "Conflicting commands specified\n");
				exit(1);
		          }
			  command = 3;
			  break;
		case  4 : print_version();
		          exit(0);
		case 'd':
			if( !optarg ) {
				usage(argv[0]);
				exit(1);
			}
			tocfile = optarg;
			command = 'd';
			break;
		case  5 : command = 5;
		          break;
		case  6 :
			SubdocName = optarg;
			asprintf(&Subdoc, "%s.xml", SubdocName);
			if( !command )
				command = 6;
			break;
		case  7 :
			tmp = malloc(sizeof(struct lnode));
			tmp->str = optarg;
			tmp->next = NULL;
			err = regcomp(&tmp->reg, tmp->str, REG_NOSUB);
			if( err ) {
				char errstr[1024];
				regerror(err, &tmp->reg, errstr, sizeof(errstr));
				printf("Error with regular expression %s: %s\n", tmp->str, errstr);
				exit(1);
			}
			if( Exclude == NULL ) {
				Exclude = tmp;
				Exclude_Tail = tmp;
			} else {
				Exclude_Tail->next = tmp;
				Exclude_Tail = tmp;
			}
			break;
		case  8 :
			if ( !optarg ) {
				usage(argv[0]);
				exit(1);
			}
			longtmp = strtol(optarg, NULL, 10);
			if( (((longtmp == LONG_MIN) || (longtmp == LONG_MAX)) && (errno == ERANGE)) || (longtmp < 1) ) {
				fprintf(stderr, "Invalid rsize value: %s\n", optarg);
				exit(5);
			}
			Rsize = optarg;
			break;
		case  9 : Coalesce = 1; break;
		case 10 : LinkSame = 1; break;
		case 11 :
			tmp = malloc(sizeof(struct lnode));
			tmp->str = optarg;
			tmp->next = NULL;
			err = regcomp(&tmp->reg, tmp->str, REG_NOSUB);
			if( err ) {
				char errstr[1024];
				regerror(err, &tmp->reg, errstr, sizeof(errstr));
				printf("Error with regular expression %s: %s\n", tmp->str, errstr);
				exit(1);
			}
			if( NoCompress == NULL ) {
				NoCompress = tmp;
				NoCompress_Tail = tmp;
			} else {
				NoCompress_Tail->next = tmp;
				NoCompress_Tail = tmp;
			}
			break;
		case  12 : 
			if( !optarg ) {
				usage(argv[0]);
				exit(1);
			}
			SigSize = strtol(optarg, (char **)NULL, 10);
			break;
		case  13 : 
			if( !optarg ) {
				usage(argv[0]);
				exit(1);
			}
			DataToSignDumpPath = optarg;
			break;
		case  14 : 
			if( !optarg ) {
				usage(argv[0]);
				exit(1);
			}
			SigOffsetDumpPath = optarg;
			break;
		case  15 : 
			if( !optarg ) {
				usage(argv[0]);
				exit(1);
			}
			LeafCertPath = optarg;
			break;
		case  16 : 
			if( !optarg ) {
				usage(argv[0]);
				exit(1);
			}
			IntermediateCertPath = optarg;
			break;
		case 17 :	// extract-data-to-sign
			command = 'e';
			break;
		case 18 :	// sign
			DoSign = 1;
			break;
		case 19 :	// replace-sign
			command = 'r';
			break;
		case 20 :	// inject signature
			if( !optarg ) {
				usage(argv[0]);
				exit(1);
			}
			sig_path = optarg;
			command = 'i';
			break;
		case 21 :	// extract-certs
			if( !optarg ) {
				usage(argv[0]);
				exit(1);
			}
			cert_path = optarg;
			stat(cert_path, &stat_struct);
			if (!(stat_struct.st_mode & S_IFDIR)) {
				usage(argv[0]);
				fprintf(stderr, "%s is not a directory.\n", cert_path);
				exit(1);
			}
			command = 'j';
			break;
		case 'c':
		case 'x':
		case 't':
			if( command && (command != 's') ) {
				usage(argv[0]);
				fprintf(stderr, "Conflicting command flags: %c and %c specified\n", c, command);
				exit(1);
			}
			if( c == 't' )
				Verbose++;
			command = c;
			break;
		case 'f':
			required_dash_f = 1;
			filename = optarg;
			break;
		case 'p':
			Perms = SYMBOLIC;
			break;
		case 'P':
			Perms = NUMERIC;
			break;
		case 'l':
			Local = 1;
			break;
		case 'n':
			SubdocName = optarg;
			break;
		case 's':
			Subdoc = optarg;
			if( !command )
				command = 's';
			break;
		case 'v':
			Verbose++;
			break;
		case 'h':
		default:
			usage(argv[0]);
			exit(1);
		}
	}

	if (! required_dash_f)	{
		usage(argv[0]);
		fprintf(stderr, "\n -f option is REQUIRED\n");
		exit(1);
	}

	// extract-data-to-sign
	if ( (command == 'e') && ((!filename) || (!DataToSignDumpPath) || (!SigOffsetDumpPath)) ) {
		usage(argv[0]);
		exit(1);
	}
	
	if ( DoSign ) {
		if (  ( !SigSize || !LeafCertPath || !IntermediateCertPath ) 
			  || ((command != 'c') && (!filename)) ) {
			usage(argv[0]);
			exit(1);
		}
		if (!command)
			command = 'n';
	}

	if (command == 'r') {
		/*if ( !SigSize || !LeafCertPath || !IntermediateCertPath || !filename) {
			usage(argv[0]);
			exit(1);
		}
		xar_t x = xar_open(filename, READ);
		if ( x == NULL ) {
			fprintf(stderr, "Could not open archive %s!\n", filename);
			exit(1);
		}
		xar_signature_t sig = xar_signature_first(x);
		if ( !sig ) {
			fprintf(stderr, "No signature found to replace.\n");
			exit(E_NOSIG);
		}
		xar_close(x);*/
	}
	
	if ((command == 'i') && ((!filename) || (!sig_path))) {
		usage(argv[0]);
		exit(1);
	}

	if ((command == 'j') && (!filename)) {
		usage(argv[0]);
		exit(1);
	}
	
	switch(command) {
		case  5 : 
		        return dump_header(filename);
		case  3 : 
			return list_subdocs(filename);
		case 'c':
			if( optind == argc ) {
				usage(argv[0]);
				fprintf(stderr, "No files to operate on.\n");
				exit(1);
			}
			arglen = argc - optind;
			args = malloc(sizeof(char*) * (arglen+1));
			memset(args, 0, sizeof(char*) * (arglen+1));
			for( i = 0; i < arglen; i++ )
				args[i] = strdup(argv[optind + i]);

			return archive(filename, arglen, args);
		case 'd':
			if( !tocfile ) {
				usage(argv[0]);
				exit(1);
			}
			return dumptoc(filename, tocfile);
		case 'x':
			arglen = argc - optind;
			args = malloc(sizeof(char*) * (arglen+1));
			for( i = 0; i < arglen; i++ )
				args[i] = strdup(argv[optind + i]);
			args[i] = NULL;
			return extract(filename, arglen, args);
		case 't':
			arglen = argc - optind;
			args = malloc(sizeof(char*) * (arglen+1));
			for( i = 0; i < arglen; i++ )
				args[i] = strdup(argv[optind + i]);
			return list(filename, arglen, args);
		case  6 :
		case 's':
			x = xar_open(filename, READ);
			if( !x ) {
				fprintf(stderr, "Error opening xar archive: %s\n", filename);
				exit(1);
			}
			xar_register_errhandler(x, err_callback, NULL);
			extract_subdoc(x, SubdocName);
			xar_close(x);
			exit(Err);
			break;
		case 'e':
			extract_data_to_sign(filename);
			exit(Err);
		case 'r':
			replace_sign(filename);
			exit(Err);
		case 'i':
			inject_signature(filename, sig_path);
			exit(Err);
		case 'n':
			belated_sign(filename);
			exit(Err);
		case 'j':
			extract_certs(filename, cert_path);
			exit(Err);
		default:
			usage(argv[0]);
			fprintf(stderr, "Unrecognized command.\n");
			exit(1);
	}

	/* unreached */
	exit(0);
}
Esempio n. 17
0
static void extract_data_to_sign(const char *filename) {
	xar_signature_t sig;
	off_t signatureOffset;
	FILE *file;
	xar_t x;
	int i;
	uint32_t dataToSignOffset = 0;
	uint32_t dataToSignSize = 0;
	char *buffer = NULL;
	const char *value;
	
	// find signature stub
	x = xar_open(filename, READ);
	if ( x == NULL ) {
		fprintf(stderr, "Could not open %s to extract data to sign!\n", filename);
		exit(1);
	}
	sig = xar_signature_first(x);
	if ( !sig ) {
		fprintf(stderr, "No signatures found to extract data from.\n");
		exit(E_NOSIG);
	}

	// locate data to sign
	if( 0 != xar_prop_get((xar_file_t)x, "checksum/offset" ,&value) ){
		fprintf(stderr, "Could not locate checksum/offset in archive.\n");
		exit(1);
	}
	dataToSignOffset = xar_get_heap_offset(x);
	dataToSignOffset += strtoull(value, (char **)NULL, 10);
	if( 0 != xar_prop_get((xar_file_t)x, "checksum/size" ,&value) ){
		fprintf(stderr, "Could not locate checksum/size in archive.\n");
		exit(1);
	}
	dataToSignSize = strtoull(value, (char **)NULL, 10);

	// get signature offset (inject signature here) 
	xar_signature_copy_signed_data(sig, NULL, NULL, NULL, NULL, &signatureOffset);
	signatureOffset += xar_get_heap_offset(x);
	xar_close(x);
	
	// now get data to be signed, using offset and size
	file = fopen(filename, "r");
	if (!file) {
		fprintf(stderr, "Could not open %s for reading data to sign!\n", filename);
		exit(1);
	}
	fseek(file, dataToSignOffset, SEEK_SET);
	buffer = malloc(dataToSignSize);
	i = fread(buffer, dataToSignSize, 1, file);
	if (i != 1) {
		fprintf(stderr, "Failed to read data to sign from %s!\n", filename);
		exit(1);
	}
	fclose(file);
	
	// save data to sign
	file = fopen(DataToSignDumpPath, "w");
	if (!file) {
		fprintf(stderr, "Could not open %s for saving data to sign!\n", DataToSignDumpPath);
		exit(1);
	}
	i = fwrite(buffer, dataToSignSize, 1, file);
	if (i != 1) {
		fprintf(stderr, "Failed to write data to sign to %s (fwrite() returned %i)!\n", DataToSignDumpPath, i);
		exit(1);
	}
	fclose(file);

	// save signature offset
	file = fopen(SigOffsetDumpPath, "w");
	if (!file) {
		fprintf(stderr, "Could not open %s for saving signature offset!\n", SigOffsetDumpPath);
		exit(1);
	}
	i = fprintf(file, "%lli\n", signatureOffset);
	if (i < 0) {
		fprintf(stderr, "Failed to write signature offset to %s (fprintf() returned %i)!\n", SigOffsetDumpPath, i);
		exit(1);
	}
	fclose(file);
	
	free(buffer);
}
Esempio n. 18
0
/* replace_sign: rip out all current signatures and certs and insert a new pair
		Since libxar is currently not capable of doing this directly, we have to create a new xar archive,
		copy all the files and options from the current archive, and sign the new archive
*/
static void replace_sign(const char *filename) {

	xar_t old_xar, new_xar;
	xar_signature_t sig;
	char *new_xar_path = (char *)malloc(15);
	strncpy(new_xar_path, "/tmp/xar.XXXXX", 15);
	new_xar_path = mktemp(new_xar_path);
	char *systemcall;
	int err;
	
	// open both archives
	old_xar = xar_open(filename, READ);
	if ( old_xar == NULL ) {
		fprintf(stderr, "Could not open archive %s!\n", filename);
		exit(1);
	}
	new_xar = xar_open(new_xar_path, WRITE);
	if( !new_xar ) {
		fprintf(stderr, "Error creating new archive %s\n", new_xar_path);
		exit(1);
	}
	
	// install new signature and new certs in new_xar
	sig = xar_signature_new(new_xar, "RSA", SigSize, &signingCallback, NULL);
	if ( LeafCertPath )
		insert_cert(sig, LeafCertPath);
	if ( IntermediateCertPath )
		insert_cert(sig, IntermediateCertPath);
	
	// copy options
	char *opts[6] = {XAR_OPT_TOCCKSUM, XAR_OPT_COMPRESSION, XAR_OPT_COALESCE, XAR_OPT_LINKSAME, XAR_OPT_RSIZE, XAR_OPT_OWNERSHIP};
	int i;
	const char *opt;
	for (i=0; i<6; i++) {
		opt = xar_opt_get(old_xar, opts[i]);
		if (opt)
			xar_opt_set(new_xar, opts[i], opt);
	}

	// skip copy subdocs for now since we don't use them yet
	
	// copy files
	xar_iter_t iter = xar_iter_new();
	xar_file_t f = xar_file_first(old_xar, iter);
		// xar_file_next iterates the archive depth-first, i.e. all children are enumerated before the siblings.
	const char *name;
	char *f_dirname, *stack_top_dirname;
	stack s_new = stack_new();
	stack s_old = stack_new();
	xar_file_t last_copied = NULL, last_added;
	
	xar_iter_t loopIter = xar_iter_new();
	xar_file_t current_xar_file;
	for (current_xar_file = xar_file_first(old_xar, loopIter); current_xar_file; current_xar_file = xar_file_next(loopIter))
	{
		printf("old_xar -> %s (parent: %s)\n",xar_get_path(current_xar_file),XAR_FILE(current_xar_file)->parent?xar_get_path(XAR_FILE(current_xar_file)->parent):"(nil)");
	}
	
	do {
		// parent is the parent in the new archive!
		// 3 cases:
		//  1. the file has no parent. Happens for every file at the top level of the archive.
		//  2. the file's parent is the last file we added. Happens while descending down a path
		//  3. the file's parent is one of the ancestors of the last file (and not NULL, that would be case 1)
		//		that means we either go back up the tree and add a sibling of one of the ancestors, or we add a
		//		sibling on the same level
		xar_prop_get(f, "name", &name);	// filename, without any path info
		if (!XAR_FILE(f)->parent) {	// case 1
			printf("root: %s\n",xar_get_path(f));
			last_added = xar_add_from_archive(new_xar, NULL, name, old_xar, f);
			last_copied = f;
			stack_push(s_new, (void *)last_added);
			stack_push(s_old, (void *)last_copied);
		} else if (f->parent == last_copied) {	// case 2			
			printf("child: %s -> %s\n",xar_get_path(f->parent),xar_get_path(f));
			last_added = xar_add_from_archive(new_xar, last_added, name, old_xar, f);
			last_copied = f;
			stack_push(s_new, (void *)last_added);
			stack_push(s_old, (void *)last_copied);
		} else {	// case 3
			printf("searching for parent: %s ?\n",xar_get_path(f));
			while (XAR_FILE(f)->parent != XAR_FILE(s_old->top->data)->parent) {
				printf("popping: %s\n",xar_get_path(XAR_FILE(s_old->top->data)));
				stack_pop(s_new);
				stack_pop(s_old);
			}
			printf("found: %s -> %s\n",xar_get_path(XAR_FILE(s_new->top->data)),xar_get_path(f));
			stack_pop(s_new);
			stack_pop(s_old);
			last_added = xar_add_from_archive(new_xar, (xar_file_t)(s_new->top->data), name, old_xar, f);
			last_copied = f;
			stack_push(s_new, (void *)last_added);
			stack_push(s_old, (void *)last_copied);
		}
	} while (f = xar_file_next(iter));
		
	loopIter = xar_iter_new();
	for (current_xar_file = xar_file_first(new_xar, loopIter); current_xar_file; current_xar_file = xar_file_next(loopIter))
	{
		char * current_path = xar_get_path(current_xar_file);
		printf("new_xar -> %s\n",current_path);
	}
	
	xar_iter_free(iter);
	stack_free(s_new);
	stack_free(s_old);
	if( xar_close(new_xar) != 0 ) {
		fprintf(stderr, "Error creating the archive\n");
		if( !Err )
			Err = 42;
	}
	xar_close(old_xar);
	
	// write signature offset to file (have to re-open so xar_close can figure out the correct offset)
	new_xar = xar_open(new_xar_path, READ);
	if( !new_xar ) {
		fprintf(stderr, "Error re-opening new archive %s\n", new_xar_path);
		unlink(new_xar_path);
		exit(1);
	}
	
	if (extract_sig_offset(new_xar, SigOffsetDumpPath)) {
		xar_close(new_xar);
		unlink(new_xar_path);
		exit(1);
	}
		
	xar_close(new_xar);
	
	// delete old archive, move new in its place
	unlink(filename);
	asprintf(&systemcall, "cp \"%s\" \"%s\"", new_xar_path, filename);
	err = system(systemcall);
	if (err) {
		fprintf(stderr, "Could not copy new archive to final location (system() returned %i)\n", err);
		unlink(new_xar_path);
		exit(1);
	}
	
	// Delete the tmp archive
	unlink(new_xar_path);
	
	free(systemcall);
}
Esempio n. 19
0
std::map<std::string, std::string> Extract(std::string file, std::string prefix) {
  std::map<std::string, std::string> files;
#ifdef HAVE_LIBXAR
  xar_t x;
  xar_iter_t xi;
  xar_file_t xf;
  xar_stream xs;
  char buffer[8192];

  x = xar_open(file.c_str(), READ);
  if (x == nullptr) {
    std::cerr << "Could not open xar archive" << std::endl;
  }

  xi = xar_iter_new();
  if (xi == nullptr) {
    xar_close(x);
    std::cerr << "Could not read xar archive" << std::endl;
  }

  for (xf = xar_file_first(x, xi); xf != nullptr; xf = xar_file_next(xi)) {
    char *path = xar_get_path(xf);
    const char *type;
    xar_prop_get(xf, "type", &type);

    if (type == nullptr) {
      std::cerr << "File has no type" << std::endl;
      free(path);
      continue;
    }

    if (std::strcmp(type, "file") != 0) {
      free(path);
      continue;
    }

    if (xar_extract_tostream_init(x, xf, &xs) != XAR_STREAM_OK) {
      std::cerr << "Error initializing stream" << std::endl;
      free(path);
      continue;
    }

    const std::string fileName = prefix + util::uuid::UuidToString(util::uuid::GenerateUUID());

    // Write bitcode to file
    std::FILE *output = std::fopen(fileName.c_str(), "wb");
    if (output == nullptr) {
      std::cerr << "Error opening output file" << std::endl;
      continue;
    }

    xs.avail_out = sizeof(buffer);
    xs.next_out = buffer;

    int32_t ret;
    while ((ret = xar_extract_tostream(&xs)) != XAR_STREAM_END) {
      if (ret == XAR_STREAM_ERR) {
        std::cerr << "Error extracting stream" << std::endl;
        break;
      }
      std::fwrite(buffer, sizeof(char), sizeof(buffer) - xs.avail_out, output);

      xs.avail_out = sizeof(buffer);
      xs.next_out = buffer;
    }

    if (xar_extract_tostream_end(&xs) != XAR_STREAM_OK) {
      std::cerr << "Error ending stream" << std::endl;
    }

    std::fclose(output);

    // Add to list of extracted files
    files[std::string(path)] = fileName;

    free(path);
  }

  xar_iter_free(xi);
  xar_close(x);
#endif
  return files;
}
Esempio n. 20
0
static int extract(const char *filename, int arglen, char *args[]) {
	xar_t x;
	xar_iter_t i;
	xar_file_t f;
	int files_extracted = 0;

	x = xar_open(filename, READ);
	if( !x ) {
		fprintf(stderr, "Error opening xar archive: %s\n", filename);
		exit(1);
	}

	xar_register_errhandler(x, err_callback, NULL);

	if( Perms == SYMBOLIC ) {
		xar_opt_set(x, XAR_OPT_OWNERSHIP, XAR_OPT_VAL_SYMBOLIC);
	}
	if( Perms == NUMERIC ) {
		xar_opt_set(x, XAR_OPT_OWNERSHIP, XAR_OPT_VAL_NUMERIC);
	}
	if ( Rsize != NULL ) {
		xar_opt_set(x, XAR_OPT_RSIZE, Rsize);
	}
	
	i = xar_iter_new();
	if( !i ) {
		fprintf(stderr, "Error creating xar iterator\n");
		exit(1);
	}

	for(f = xar_file_first(x, i); f; f = xar_file_next(i)) {
		int matched = 0;
		int exclude_match = 1;
		struct lnode *i;

		char *path = xar_get_path(f);

		if( args[0] ) {
			int i;
			for(i = 0; args[i]; i++) {
				if( strcmp(path, args[i]) == 0 ) {
					matched = 1;
					break;
				}
			}
		} else {
			matched = 1;
		}

		for( i = Exclude; i; i=i->next ) {
			exclude_match = regexec(&i->reg, path, 0, NULL, 0);
			if( !exclude_match )
				break;
		}
		if( !exclude_match ) {
			if( Verbose )
				printf("Excluding %s\n", path);
			free(path);
			continue;
		}
		
		if( matched ) {
			files_extracted++;
			print_file(f);
			xar_extract(x, f);
		}
		free(path);
	}
	if( args[0] && (files_extracted == 0) ) {
		fprintf(stderr, "No files matched extraction criteria.\n");
		Err = 3;
	}

	if( Subdoc )
		extract_subdoc(x, NULL);

	xar_iter_free(i);
	if( xar_close(x) != 0 ) {
		fprintf(stderr, "Error extracting the archive\n");
		if( !Err )
			Err = 42;
	}
	return Err;
}
Esempio n. 21
0
File: pkg_toc.c Progetto: nn/fs-pkg
int pkg_toc_process(const char *path, const char *toc) {
   u_int32_t   pkgid;
   xar_t       x;
   xar_iter_t  i;
   xar_file_t  f;
   struct vfs_fake_stat sb;

   if (!(x = xar_open(path, READ))) {
      Log(LOG_ERROR, "failed opening package %s", path);
      return EXIT_FAILURE;
   }

   xar_register_errhandler(x, pkg_xar_err_callback, NULL);

   if (!(i = xar_iter_new())) {
      Log(LOG_ERROR, "failed getting new xar iter in pkg %s", path);
      return EXIT_FAILURE;
   }

   db_pkg_remove(path);
   pkgid = db_pkg_add(path);
   fprintf(stderr, "id: %d\n", pkgid);

   for (f = xar_file_first(x, i); f; f = xar_file_next(i)) {
      char       *size = xar_get_size(x, f);
      char       *xpath = xar_get_path(f);
      char       *xtype = xar_get_type(x, f);
      char       *mode = xar_get_mode(x, f);
      char       *user = xar_get_owner(x, f);
      char       *group = xar_get_group(x, f);
      char       *mtime = xar_get_mtime(x, f);
      const char *offset;
      char        type = 'u';
/*    *	                  (f)ile, (d)irectory, (l)ink, (p)ipe
      *                    f(i)fo, (c)haracter, (b)lock, (s)ocket,
      *                   (u)ndefined
 */
      if (!strcasecmp(xtype, "file")) {
         xar_prop_get(f, "data/offset", &offset);
         type = 'f';
      } else {
         offset = "0";
         if (!strcasecmp(xtype, "directory"))
            type = 'd';
         else if (!strcasecmp(xtype, "hardlink"))
            type = 'l';
         else if (!strcasecmp(xtype, "symlink"))
            type = 'l';
      }

#if	0
      /*
       * what we gonna do with target? 
       */
      printf("%s: %s %8s/%-8s %10s %s %s @ %s\n", xtype, mode, user,
             group, size, mtime, xpath, offset);

      db_query(QUERY_INT,
               "INSERT INTO files (package, path, type, owner, group, size, offset, ctime, mode) VALUES (%lu, '%s', '%s', %s, %s, %s, %s, %s, %s, %s);",
               pkgid, xpath, type, user, group, size, offset, mtime);
#endif
      free(mtime);
      free(group);
      free(user);
      free(mode);
      free(xtype);
      free(xpath);
      free(size);
   }
   return EXIT_SUCCESS;
}
Esempio n. 22
0
int main(int argc, char *argv[])
{
	int fd;
	unsigned char *buffer;
	struct stat sb;
	ssize_t red;
	xar_t x;
	xar_file_t f, f2;

	if( argc < 2 ) {
		fprintf(stderr, "usage: %s <filename>\n", argv[0]);
		exit(1);
	}

	fd = open(argv[1], O_RDONLY);
	if( fd < 0 ) {
		fprintf(stderr, "Unable to open file %s\n", argv[1]);
		exit(2);
	}

	if( fstat(fd, &sb) < 0 ) {
		fprintf(stderr, "Unable to stat file %s\n", argv[1]);
		exit(3);
	}

	buffer = malloc(sb.st_size);
	if( buffer == NULL ) {
		fprintf(stderr, "Unable to allocate memory\n");
		exit(4);
	}

	red = read(fd, buffer, sb.st_size);
	if( red <= 0 ) {
		fprintf(stderr, "Error reading from file\n");
		exit(5);
	}
	if( red < sb.st_size )
		fprintf(stderr, "Incomplete read\n");

	x = xar_open("/tmp/test.xar", WRITE);
 	if( x == NULL ) {
		fprintf(stderr, "Error creating xarchive\n");
		exit(6);
	}

	xar_register_errhandler(x, err_callback, NULL);

	memset(&sb, 0, sizeof(sb));

	sb.st_mode = S_IFDIR | S_IRWXU;
	f = xar_add_folder(x, NULL, "mydir", &sb);
	if( !f ) {
		fprintf(stderr, "Error adding parent to archive\n");
		exit(7);
	}

	f2 = xar_add_frombuffer(x, f, "secondfile", buffer, red);
	if( !f ) {
		fprintf(stderr, "Error adding child to archive\n");
		exit(8);
	}

	xar_close(x);
	close(fd);
	exit(0);
}