/*
 * T.C.F.S. Utils 2.0 $Revision: 2.5 $
 *
 * Authors:	Giuseppe Cattaneo, <cattaneo@udsab.dia.unisa.it>
 *		Giuseppe Persiano, <giuper@udsab.dia.unisa.it>
 *		Luigi Catuogno, <luicat@mikonos.dia.unisa.it>
 *		Angelo Celentano, <angcel@mikonos.dia.unisa.it>
 *		Andrea Cozzolino, <andcoz@mikonos.dia.unisa.it>
 *		Aniello Del Sorbo, <anidel@mikonos.dia.unisa.it>
 *		Ermelindo Mauriello, <ermmau@mikonos.dia.unisa.it>
 *		Raffaele Pisapia, <rafpis@mikonos.dia.unisa.it>
 *
 * Permission  to use,  copy,  and modify this  software  without fee
 * is hereby granted, provided that this entire notice is included in
 * all  copies  of  any  software  which  is  or includes  a copy  or
 * modification of this  software and in all copies of the supporting
 * documentation for such software.
 *
 * This  software maybe  be used for  any purpose provided  the above 
 * copyright  notice  is  retained.  It is  supplied as  is, with  no 
 * warranty expressed or implied.
 */

/*
 *       $Source: /home/anidel/Wip/TCFS-2.2.0a/tcfsutils-1.1/src/RCS/tcfsviewkey.c,v $
 *        $State: Exp $
 *
 *     $Revision: 2.5 $
 *       $Author: anidel $
 *         $Date: 1998/11/27 16:58:44 $
 *       $Locker:  $
 */

static const char *RCSid="$Id: tcfsviewkey.c,v 2.5 1998/11/27 16:58:44 anidel Exp $";
/* -+-_== */ 

#include <stdio.h>
#include <strings.h>
#include <getopt.h>
#include <unistd.h>
#include <tcfslib.h>
#include <grp.h>
#include <sys/types.h>

#include "tcfserrors.h"

/* Long command line options */
static struct option long_options[]=
{
	{ "help", 0, NULL, 'h' },
	{ "count", 0, NULL, 'c' },
	{ "group", 1, NULL, 'g' },
	{ "key", 0, NULL, 'k' },
	{ "permanent", 0, NULL, 'p' },
	{ "version", 0, NULL, 'V' },
	{ 0, 0, 0, 0 }
};

/* Usage output */
char *usage="Usage: %s [OPTION]
Shows some useful info about your TCFS login.

  -p [--permanent]     Shows the permanent flag
  -k [--key]           Shows the key from the database
  -c [--count]         Shows the key/share counter (default)
  -g [--group] <group> Shows all the above (except the key) referred to the TCFS <group>
  -V [--version]       Shows the TCFS version and the cipher algorithm
  -h [--help]          Shows this help\n";

int main (int argn, char *argv[])
{
	int val, index;
	int show_key=FALSE, show_counter=FALSE, show_permanent=FALSE;
	int show_group=FALSE, show_version=FALSE, groupid;
	char *user, *passwd;
	unsigned char *key, *uukey;
	tcfspwdb *userinfo;
	char buff[30];

	/*
	 * Check the command line parameters
	 */
	while((val=getopt_long (argn, argv, "hcg:pVk", long_options, &index)) !=EOF)
		switch (val)
		{
			case 'p':
				show_permanent=TRUE;
				break;
			case 'k':
				show_key=TRUE;
				break;
			case 'c':
				show_counter=TRUE;
				break;
			case 'g':
				show_group=TRUE;
				show_counter=TRUE;
				groupid=atoi(optarg);
				if (!groupid && optarg[0]!='0')
				{
					struct group *group_id;

					group_id=getgrnam(optarg);
					if (!group_id)
						tcfs_error (ER_CUSTOM, "Nonexistent group.");

					groupid=group_id->gr_gid;
				}
				break;
			case 'V':
				show_version=TRUE;
				break;
			case 'h':
				show_usage(usage, argv[0]);
				exit (OK);
				break;     /* Useless code */
			default:
				fprintf (stderr, "Try %s --help for more information.\n", argv[0]);
				exit (ER_UNKOPT);
				break;     /* Useless code */
		}

	if (argn-optind)
		tcfs_error (ER_UNKOPT, NULL);

	/* Default action */
	if (!show_counter && !show_key && !show_group &&!show_permanent)
		show_counter=TRUE;

	if (show_version)
	{
		tcfs_getversion (buff);
		printf ("%s\n", buff);
		exit (OK);
	}

	/*
	 * Authenticate the user if he want to show his key
	 */
	if (show_key)
	{
		if (!unix_auth(&user, &passwd, TRUE))
			tcfs_error (ER_CUSTOM, "Who are you?!");

		if (show_group)
		{
			int i;

			tcfsgpwdb *group_info;

			if (!tcfsgpwdbr_new (&group_info))
				tcfs_error (ER_MEM, NULL);

			if (!tcfs_ggetpwnam(user, groupid, &group_info))
				tcfs_error (ER_TCFS, NULL);

			if ((key=(char *) calloc(KEYSIZE*2, sizeof (char)))==NULL)
				tcfs_error (ER_MEM, NULL);
	
			/* Decrypt the tcfs user key */	
			if (!tcfs_decrypt_key(user, passwd, group_info->gkey, key, GROUPKEY))
				tcfs_error (ER_CUSTOM, "Error: unable to decrypt key.");

			uukey = tcfs_encode (key, KEYSIZE+1);
	
			printf("TCFS group key not uuencoded: ");
			for (i=0;i<=KEYSIZE;i++) {
				printf ("%u:", key[i]);
			}
			printf ("\n");
			printf("TCFS group key: %s\n", uukey);
		}
		else
		{
			if (!tcfspwdbr_new(&userinfo))
				tcfs_error (ER_MEM, NULL);

			if (!tcfs_getpwnam(user, &userinfo))
				tcfs_error (ER_TCFS, NULL);

			if ((key=(char *) calloc(KEYSIZE, sizeof (char)))==NULL)
				tcfs_error (ER_MEM, NULL);
	
			/* Decrypt the tcfs user key */
			if (!tcfs_decrypt_key(user, passwd, userinfo->upw, key, USERKEY))
				tcfs_error (ER_CUSTOM, "Error: unable to decrypt key.");

			uukey = tcfs_encode (key, KEYSIZE);

			printf("TCFS key: %s\n", uukey);
		}
	}

	if (show_counter)
	{
		if (show_group)
		{
			if ((val=tcfs_group_getcount (getlogin(), groupid))<0)
				tcfs_error (ER_CUSTOM, "TCFS counter: no TCFS filesystem mounted or no group key present.");
		}
		else
		{
			if((val=tcfs_getcount (getlogin()))<0)
				tcfs_error(ER_CUSTOM, "TCFS counter: no TCFS filesystem mounted or no key present.");
		}
		printf ("TCFS counter: %d\n", val);
	}

	if (show_permanent)
	{
		if (show_group)
		{
			if ((val=tcfs_group_getpermanent (getlogin(), groupid))<0)
				tcfs_error(ER_CUSTOM, "TCFS permanent: no TCFS filesystem mounted or no group key present.");
		}
		else
		{
			if((val=tcfs_getpermanent(getlogin()))<0)
				tcfs_error(ER_CUSTOM, "TCFS permanent: no TCFS filesystem mounted or no key present.");
		}
		printf ("TCFS permanent flag: %s\n", val?"set":"unset");
	}
}
