int main(int argc, char *argv[])
{
	char *passphrase;
	char auth_tok_sig_hex[ECRYPTFS_SIG_SIZE_HEX + 1];
	char salt[ECRYPTFS_SALT_SIZE];
	char salt_hex[ECRYPTFS_SALT_SIZE_HEX];
	int rc = 0;
	int fnek = 0;
	uint32_t version;

	if (argc == 1) {
		/* interactive mode */
		passphrase = ecryptfs_get_passphrase("Passphrase");
	} else if (argc == 2 &&
		   strlen(argv[1]) == 6 && strncmp(argv[1], "--fnek", 6) == 0) {
		/* interactive mode, plus fnek */
		passphrase = ecryptfs_get_passphrase("Passphrase");
		fnek = 1;
	} else if (argc == 2 &&
		   strlen(argv[1]) == 1 && strncmp(argv[1], "-", 1) == 0) {
		/* stdin mode */
		passphrase = ecryptfs_get_passphrase(NULL);
	} else if (argc == 3 &&
		/* stdin mode, plus fnek */
		   (strlen(argv[1])==6 && strncmp(argv[1], "--fnek", 6)==0) &&
		   (strlen(argv[2])==1 && strncmp(argv[2], "-", 1)==0)) {
		passphrase = ecryptfs_get_passphrase(NULL);
		fnek = 1;
	} else {
		usage();
		goto out;
	}
	if (passphrase == NULL ||
	    strlen(passphrase) > ECRYPTFS_MAX_PASSWORD_LENGTH) {
		usage();
		rc = 1;
		goto out;
	}
	if (fnek == 1) {
		rc = ecryptfs_get_version(&version);
		if (rc!=0 || !ecryptfs_supports_filename_encryption(version)) { 
			fprintf(stderr, "%s\n", ECRYPTFS_ERROR_FNEK_SUPPORT);
			rc = 1;
			goto out;
		}
	}

	rc = ecryptfs_read_salt_hex_from_rc(salt_hex);
	if (rc) {
		from_hex(salt, ECRYPTFS_DEFAULT_SALT_HEX, ECRYPTFS_SALT_SIZE);
	} else
		from_hex(salt, salt_hex, ECRYPTFS_SALT_SIZE);
	if ((rc = ecryptfs_add_passphrase_key_to_keyring(auth_tok_sig_hex,
							 passphrase,
							 salt)) < 0) {
		fprintf(stderr, "%s [%d]\n", ECRYPTFS_ERROR_INSERT_KEY, rc);
		fprintf(stderr, "%s\n", ECRYPTFS_INFO_CHECK_LOG);
		rc = 1;
		goto out;
	} else
		rc = 0;
	auth_tok_sig_hex[ECRYPTFS_SIG_SIZE_HEX] = '\0';
	printf("Inserted auth tok with sig [%s] into the user session "
	       "keyring\n", auth_tok_sig_hex);

	if (fnek == 0) {
		goto out;
	}

	/* If we make it here, filename encryption is enabled, and it has
	 * been requested that we add the fnek to the keyring too
	 */
	if ((rc = ecryptfs_add_passphrase_key_to_keyring(auth_tok_sig_hex,
				 passphrase,
				 ECRYPTFS_DEFAULT_SALT_FNEK_HEX)) < 0) {
		fprintf(stderr, "%s [%d]\n", ECRYPTFS_ERROR_INSERT_KEY, rc);
		fprintf(stderr, "%s\n", ECRYPTFS_INFO_CHECK_LOG);
		rc = 1;
		goto out;
	} else
		rc = 0;
	auth_tok_sig_hex[ECRYPTFS_SIG_SIZE_HEX] = '\0';
	printf("Inserted auth tok with sig [%s] into the user session "
	       "keyring\n", auth_tok_sig_hex);

out:
	return rc;
}
Example #2
0
int main(int argc, char **argv)
{
	static struct option long_options[] = {
		{"pidfile\0\tSet pid file name", required_argument, NULL, 'p'},
		{"foreground\0\t\tDon't fork into background", no_argument,
		 NULL, 'f'},
		{"chroot\0\t\tChroot to directory", required_argument, NULL,
		 'C'},
   		{"prompt-prog\0Program to execute for user prompt",
		 required_argument, NULL, 'R'},
		{"version\0\t\t\tShow version information", no_argument, NULL,
		 'V'},
		{"help\0\t\t\tShow usage information", no_argument, NULL, 'h'},
		{NULL, 0, NULL, 0}
	};
	static char *short_options = "p:fC:R:Vh";
	int long_options_ret;
	struct rlimit core = {0, 0};
	int foreground = 0;
	char *chrootdir = NULL;
	char *tty = NULL;
	uint32_t version;
	int rc = 0;
	
	while ((long_options_ret = getopt_long(argc, argv, short_options,
					       long_options, NULL)) != -1) {
		switch (long_options_ret) {
		case 'p':
			pidfile = strdup(optarg);
			break;
		case 'f':
			foreground = 1;
			break;
		case 'C':
			chrootdir = strdup(optarg);
			break;
		case 'R':
			prompt_prog = strdup(optarg);
  			break;
		case 'V':
			printf(("%s (%s) %s\n"
				"\n"
				"This is free software.  You may "
				"redistribute copies of it under the "
				"terms of\n"
				"the GNU General Public License "
				"<http://www.gnu.org/licenses/"
				"gpl.html>.\n"
				"There is NO WARRANTY, to the extent "
				"permitted by law.\n"),
			       basename(argv[0]),
			       PACKAGE_NAME,
			       PACKAGE_VERSION);
			exit(0);
			break;
		case 'h':
		default:
			usage(basename(argv[0]), long_options,
			      short_options);
			exit(1);
			break;
		}
	}
	rc = ecryptfs_get_version(&version);
	if (!rc && !(version & ECRYPTFS_VERSIONING_MISCDEV)) {
		rc = -EPROTONOSUPPORT;
		syslog(LOG_ERR, "%s: Current kernel does not have support for "
		       "/dev/ecryptfs; please use 2.6.26 or newer\n", __func__);
		exit(rc);
	}
	openlog(argv[0], LOG_PID | (foreground ? LOG_PERROR : 0), 0);
	if (rc) {
		syslog(LOG_WARNING, "%s: Unable to retrieve versioning "
		       "info from kernel module; assuming /dev/ecryptfs is "
		       "available\n " , __FUNCTION__);
	}
	tty = ttyname(0); /* We may need the tty name later */
	if (tty != NULL)
		setenv ("TERM_DEVICE", tty, 0);
	if (!foreground)
		daemonize(); /* This will exit if cannot be completed */
	/* Disallow core file; secret values may be in it */
	if (setrlimit(RLIMIT_CORE, &core) == -1) {
		rc = -errno;
		syslog(LOG_ERR, "Cannot setrlimit: %m");
		goto daemon_out;
	}
	if (chrootdir != NULL) {
		if (chroot(chrootdir) == -1) {
			rc = -errno;
			syslog(LOG_ERR, "Failed to chroot to '%s': %m\n",
			       chrootdir);
			goto daemon_out;
		}
		free(chrootdir);
		chrootdir = NULL;
	}
	if (pidfile != NULL) {
		FILE *fp = fopen(pidfile, "w");

		if (fp == NULL) {
			rc = -errno;
			syslog(LOG_ERR, "Failed to open pid file '%s': %m\n",
			       pidfile);
			goto daemon_out;
		}
		fprintf(fp, "%d", (int)getpid());
		fclose(fp);
	}
	if (signal(SIGTERM, sigterm_handler) == SIG_ERR) {
		rc = -ENOTSUP;
		syslog(LOG_ERR, "Failed to attach handler to SIGTERM");
		goto daemon_out;
	}
	if (signal(SIGINT, sigterm_handler) == SIG_ERR) {
		rc = -ENOTSUP;
		syslog(LOG_ERR, "Failed to attach handler to SIGINT");
		goto daemon_out;
	}
 	cryptfs_get_ctx_opts()->prompt = prompt_callback;
	pthread_mutex_init(&mctx_mux, NULL);
	pthread_mutex_lock(&mctx_mux);
	rc = ecryptfs_init_messaging(&mctx, ECRYPTFS_MESSAGING_TYPE_MISCDEV);
	if (rc) {
		syslog(LOG_ERR, "%s: Failed to initialize messaging; rc = "
		       "[%d]\n", __FUNCTION__, rc);
		pthread_mutex_unlock(&mctx_mux);
		goto daemon_out;
	}
	rc = ecryptfs_send_message(&mctx, NULL, ECRYPTFS_MSG_HELO, 0, 0);
	if (rc) {
		syslog(LOG_ERR, "%s: Error attempting to send message to "
		       "eCryptfs kernel module via /dev/ecryptfs; rc = [%d]\n",
		       __func__, rc);
		pthread_mutex_unlock(&mctx_mux);
		goto daemon_out;
	}
	mctx.state |= ECRYPTFS_MESSAGING_STATE_LISTENING;
	pthread_mutex_unlock(&mctx_mux);
	rc = ecryptfs_run_daemon(&mctx);
	pthread_mutex_lock(&mctx_mux);
	mctx.state &= ~ECRYPTFS_MESSAGING_STATE_LISTENING;
	pthread_mutex_unlock(&mctx_mux);
daemon_out:
	ecryptfsd_exit(&mctx, rc);
	return rc;
}
Example #3
0
int main(int argc, char **argv)
{
	int quit, rc, selection;
	uint32_t version;
	char passphrase[ECRYPTFS_MAX_PASSWORD_LENGTH];
	char salt[ECRYPTFS_SALT_SIZE];
	struct ecryptfs_ctx ecryptfs_ctx;
	struct val_node *dummy_mnt_params;
	char auth_tok_sig[ECRYPTFS_SIG_SIZE_HEX+1];

	if ((rc = ecryptfs_validate_keyring())) {
		printf("Error attempting to validate keyring integrity; "
		       "rc = [%d]\n", rc);
		return 1;
	}
	memset(passphrase, 0, ECRYPTFS_MAX_PASSWORD_LENGTH);
	memset(salt, 0, ECRYPTFS_SALT_SIZE);
selection:
	quit = 0;
	selection = manager_menu();
	switch (selection) {
	case MME_MOUNT_PASSPHRASE:
		if ((rc = read_passphrase_salt(passphrase, salt)))
			goto out_wipe;
		if (!(*salt))
			memcpy(salt, common_salt, ECRYPTFS_SALT_SIZE);
		rc = ecryptfs_add_passphrase_key_to_keyring(auth_tok_sig,
							    passphrase, salt);
		if (rc == 1) {
			rc = 0;
			printf("\nThat key was already in the keyring.\n\n");
		} else if (!rc)
			printf("\nAdded key to keyring with signature [%s]."
			       "\n\n", auth_tok_sig);
		memset(passphrase, 0, ECRYPTFS_MAX_PASSWORD_LENGTH);
		memset(salt, 0, ECRYPTFS_SALT_SIZE);
		break;
	case MME_MOUNT_PUBKEY:
		if ((rc = ecryptfs_get_version(&version))) {
			printf("\nUnable to get the version number of the kernel\n");
			printf("module. Please make sure that you have the eCryptfs\n");
			printf("kernel module loaded, you have sysfs mounted, and\n");
			printf("the sysfs mount point is in /etc/mtab. This is\n");
			printf("necessary so that the mount helper knows which \n");
			printf("kernel options are supported.\n\n");
			printf("Make sure that your system is set up to auto-load\n"
			       "your filesystem kernel module on mount.\n\n");
			printf("Enabling passphrase-mode only for now.\n\n");
			version = ECRYPTFS_VERSIONING_PASSPHRASE;
		}
		ecryptfs_ctx.get_string = &get_string_stdin;
		if ((dummy_mnt_params = malloc(sizeof(struct val_node)))
		    == NULL) {
			rc = -ENOMEM;
			goto out;
		}
		if ((rc = ecryptfs_process_decision_graph(
			     &ecryptfs_ctx, &dummy_mnt_params, version, "",
			     ECRYPTFS_KEY_MODULE_ONLY))) {
			printf("Error processing key generation decision graph;"
			       " rc = [%d]\n", rc);
			goto out;
		}
		if ((rc = ecryptfs_free_key_mod_list(&ecryptfs_ctx))) {
			printf("\nUnable to free key modules\n");
		}
		printf("Returning to main menu\n");
		break;
	case MME_GEN_PUBKEY:
		memset(&ecryptfs_ctx, 0, sizeof(struct ecryptfs_ctx));
		if ((rc = ecryptfs_get_version(&version))) {
			printf("\nUnable to get the version number of the kernel\n");
			printf("module. Please make sure that you have the eCryptfs\n");
			printf("kernel module loaded, you have sysfs mounted, and\n");
			printf("the sysfs mount point is in /etc/mtab. This is\n");
			printf("necessary so that the mount helper knows which \n");
			printf("kernel options are supported.\n\n");
			printf("Make sure that your system is set up to auto-load\n"
			       "your filesystem kernel module on mount.\n\n");
			printf("Enabling passphrase-mode only for now.\n\n");
			version = ECRYPTFS_VERSIONING_PASSPHRASE;
		}
		ecryptfs_ctx.get_string = &get_string_stdin;
		if ((rc = ecryptfs_process_key_gen_decision_graph(&ecryptfs_ctx,
								  version))) {
			printf("Error processing key generation decision graph;"
			       " rc = [%d]\n", rc);
			goto out;
		}
		if ((rc = ecryptfs_free_key_mod_list(&ecryptfs_ctx))) {
			printf("\nUnable to free key modules\n");
		}
		printf("Returning to main menu\n");
		goto selection;
	case MME_ABORT:
		quit = 1;
		goto out_wipe;
	default:
		fprintf(stderr, "Unknown option, aborting\n");
		quit = 1;
		rc = -1;
		goto out_wipe;
	}
out_wipe:
	memset(passphrase, 0, ECRYPTFS_MAX_PASSWORD_LENGTH);
	memset(salt, 0, ECRYPTFS_SALT_SIZE);
	if (!quit)
		goto selection;
out:
	if (selection == MME_MOUNT_PUBKEY || selection == MME_GEN_PUBKEY)
		rc = ecryptfs_free_key_mod_list(&ecryptfs_ctx);
	return rc;
}
int main(int argc, char **argv)
{
	uint32_t version;
	char *opts_str;
	struct val_node *mnt_params;
	struct ecryptfs_ctx ctx;
	int sig_cache = 1;
	int rc;
	struct passwd *pw;

	rc = mlockall(MCL_FUTURE);
	if (rc) {
		fprintf(stderr, "Exiting. Unable to mlockall address space: %m\n");
		return -1;
	}

	pw = getpwuid(getuid());
	if (!pw) {
		fprintf(stderr, "Exiting. Unable to obtain passwd info\n");
		rc = -EIO;
		goto out;
	}

	if (dump_args) {
		int i;

		for (i = 0; i < argc; i++)
			printf("argv[%d] = [%s]\n", i, argv[i]);
	}
	if (argc < NUM_REQUIRED_ARGS) {
		fprintf(stderr, "Insufficient number of arguments\n");
		usage();
		rc = -EINVAL;
		goto out;
	}
	rc = ecryptfs_get_version(&version);
	if (rc) {
		printf("\nUnable to get the version number of the kernel\n");
		printf("module. Please make sure that you have the eCryptfs\n");
		printf("kernel module loaded, you have sysfs mounted, and\n");
		printf("the sysfs mount point is in /etc/mtab. This is\n");
		printf("necessary so that the mount helper knows which \n");
		printf("kernel options are supported.\n\n");
		printf("Make sure that your system is set up to auto-load\n"
		       "your filesystem kernel module on mount.\n\n");
		printf("Enabling passphrase-mode only for now.\n\n");
		version = ECRYPTFS_VERSIONING_PASSPHRASE;
	}
	if ((rc = ecryptfs_validate_keyring())) {
		printf("Unable to link the KEY_SPEC_USER_KEYRING into the "
		       "KEY_SPEC_SESSION_KEYRING; there is something wrong "
		       "with your kernel keyring. Did you build key retention "
		       "support into your kernel?\n");
		goto out;
	}
	mnt_params = malloc(sizeof(struct val_node));
	memset(mnt_params, 0, sizeof(struct val_node));
	memset(&ctx, 0, sizeof(struct ecryptfs_ctx));
	ctx.get_string = &get_string_stdin;
	if ((rc = parse_arguments(argc, argv, NULL, NULL, &opts_str)))
		goto out;
	if (opts_str_contains_option(opts_str, "verbose"))
		ecryptfs_verbosity = 1;
	if (!opts_str_contains_option(opts_str, "remount")) {
		if (opts_str_contains_option(opts_str, "no_sig_cache"))
			sig_cache = 0;
		if (opts_str_contains_option(opts_str, "no_prompt")
		    || opts_str_contains_option(opts_str, "wild_ass_guess")) {
			if (!opts_str_contains_option(opts_str,
						      "verbosity=0")) {
				char *tmp;

				rc = asprintf(&tmp, "%s,verbosity=0", opts_str);
				if (rc == -1) {
					rc = -ENOMEM;
					goto out;
				}
				rc = 0;
				opts_str = tmp;
			}
		}
		if (opts_str_contains_option(opts_str, "verbosity=0"))
			sig_cache = 0;
		rc = ecryptfs_process_decision_graph(
			&ctx, &mnt_params, version, opts_str,
			ECRYPTFS_ASK_FOR_ALL_MOUNT_OPTIONS);
		if (rc) {
			if (rc > 0) 
				rc = -EINVAL;
			printf("Error attempting to evaluate mount options: "
			       "[%d] %s\nCheck your system logs for details "
			       "on why this happened.\nTry updating your "
			       "ecryptfs-utils package, and/or\nsubmit a bug "
			       "report on https://bugs.launchpad.net/ecryptfs\n",
				rc, strerror(-rc));
			goto out;
		}
		rc = ecryptfs_do_mount(argc, argv, mnt_params, sig_cache, pw);
		if (rc == ECANCELED) {
		    rc = 0;
		    goto out;
		}
		if (rc) {
			if (rc > 0)
				rc = -rc;
			printf("Error mounting eCryptfs: [%d] %s\n"
			       "Check your system logs; visit "
			       "<http://ecryptfs.org/support.html>\n",
			       rc, strerror(-rc));
			if (rc == -ENODEV)
				printf("Try ``modprobe ecryptfs''\n");
		} else
			printf("Mounted eCryptfs\n");
	} else {
		fprintf(stderr, "When remounting eCryptfs, you need "
			"to pass the mount utility the -i parameter to avoid "
			"calling the mount helper\n");
		rc = -EINVAL;
	}

out:
	munlockall();
	return rc;
}