18fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh#include <sepol/module.h>
28fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh#include <getopt.h>
38fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh#include <fcntl.h>
48fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh#include <stdio.h>
58fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh#include <stdlib.h>
68fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh#include <string.h>
78fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh#include <unistd.h>
88fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh#include <sys/types.h>
98fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh#include <sys/stat.h>
108fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh#include <sys/mman.h>
118fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh#include <fcntl.h>
128fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh#include <errno.h>
138fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh
148fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walshchar *progname = NULL;
158fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walshextern char *optarg;
168fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh
17e198427fe5d02b739f8bc1ece84185d76261ea83Nicolas Ioossstatic void usage(void)
188fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh{
198fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	printf("usage: %s ppfile modfile [fcfile]\n", progname);
208fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	exit(1);
218fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh}
228fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh
23188a028f747579fe74b817a997ae6209f3eb742fNicolas Ioossstatic int file_to_policy_file(const char *filename, struct sepol_policy_file **pf, const char *mode)
248fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh{
258fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	FILE *f;
268fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh
278fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	if (sepol_policy_file_create(pf)) {
288fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh		fprintf(stderr, "%s:  Out of memory\n", progname);
298fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh		return -1;
308fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	}
318fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh
328fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	f = fopen(filename, mode);
338fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	if (!f) {
348fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh		fprintf(stderr, "%s:  Could not open file %s:  %s\n", progname, strerror(errno), filename);
358fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh		return -1;
368fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	}
378fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	sepol_policy_file_set_fp(*pf, f);
388fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	return 0;
398fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh}
408fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh
418fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walshint main(int argc, char **argv)
428fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh{
438fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	struct sepol_module_package *pkg;
448fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	struct sepol_policy_file *in, *out;
458fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	FILE *fp;
468fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	size_t len;
478fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	char *ppfile, *modfile, *fcfile = NULL, *fcdata;
488fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh
498fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	progname = argv[0];
508fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh
518fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	if (argc < 3) {
52e198427fe5d02b739f8bc1ece84185d76261ea83Nicolas Iooss		usage();
538fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh		exit(1);
548fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	}
558fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh
568fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	ppfile = argv[1];
578fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	modfile = argv[2];
588fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	if (argc >= 3)
598fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh		fcfile = argv[3];
608fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh
618fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	if (file_to_policy_file(ppfile, &in, "r"))
628fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh		exit(1);
638fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh
648fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	if (sepol_module_package_create(&pkg)) {
658fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh                fprintf(stderr, "%s:  Out of memory\n", progname);
668fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh                exit(1);
678fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	}
688fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh
698fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	if (sepol_module_package_read(pkg, in, 0) == -1) {
708fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh                fprintf(stderr, "%s:  Error while reading policy module from %s\n",
718fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh			progname, ppfile);
728fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh                exit(1);
738fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	}
748fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh
758fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	if (file_to_policy_file(modfile, &out, "w"))
768fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh		exit(1);
778fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh
788fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh        if (sepol_policydb_write(sepol_module_package_get_policy(pkg), out)) {
798fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh                fprintf(stderr, "%s:  Error while writing module to %s\n", progname, modfile);
808fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh                exit(1);
818fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh        }
828fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh
838fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	sepol_policy_file_free(in);
848fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	sepol_policy_file_free(out);
858fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh
868fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	len = sepol_module_package_get_file_contexts_len(pkg);
878fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	if (fcfile && len) {
888fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh		fp = fopen(fcfile, "w");
898fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh		if (!fp) {
908fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh			fprintf(stderr, "%s:  Could not open file %s:  %s\n", progname, strerror(errno), fcfile);
918fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh			exit(1);
928fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh		}
938fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh		fcdata = sepol_module_package_get_file_contexts(pkg);
948fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh		if (fwrite(fcdata, 1, len, fp) != len) {
958fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh			fprintf(stderr, "%s:  Could not write file %s:  %s\n", progname, strerror(errno), fcfile);
968fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh			exit(1);
978fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh		}
988fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh		fclose(fp);
998fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	}
1008fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh
1018fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	sepol_module_package_free(pkg);
1028fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh	exit(0);
1038fb9a4571d3db8675ec12ba5ee1e2f2c3cefbeecDan Walsh}
104