/**
 * Copyright (C) 2006 International Business Machines
 * Author(s): Trevor S. Highland <trevor.highland@gmail.com>
 *            Michael C. Thompson <mcthomps@us.ibm.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA.
 */

#include <errno.h>
#include <gcrypt.h>
#include <getopt.h>
#include <keyutils.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include "ecryptfs.h"
#include "io.h"

int main(int argc, char **argv)
{
	int quit, rc, selection;
	char passphrase[ECRYPTFS_MAX_PASSWORD_LENGTH];
	char salt[ECRYPTFS_SALT_SIZE];
	struct ecryptfs_ctx ecryptfs_ctx;
	struct ecryptfs_pki_elem *selected_pki = NULL;
	char auth_tok_sig[ECRYPTFS_SIG_SIZE_HEX+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:
		memset(&ecryptfs_ctx, 0, sizeof(struct ecryptfs_ctx));
		if ((rc = ecryptfs_get_pki_list(&ecryptfs_ctx)))
			goto out_wipe;
		if (ecryptfs_select_pki(&ecryptfs_ctx, &selected_pki))
			goto out_wipe;
		printf("PKI parameters for [%s]; default values in brackets:\n",
		       selected_pki->pki_name);
		if (ecryptfs_set_name_value_pairs(&selected_pki->nvp_head))
			goto out;
		rc = add_public_key_key_to_keyring(auth_tok_sig, selected_pki);
		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);
		break;
	case MME_GEN_PUBKEY:
		rc = generate_key();
		if (rc)
			goto out;
		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)
		rc = ecryptfs_free_pki_list(&ecryptfs_ctx);
	return rc;
}
