[BACK]Return to tcfsaddgroup.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / tcfs

File: [local] / src / usr.bin / tcfs / Attic / tcfsaddgroup.c (download)

Revision 1.4, Mon Jun 19 20:25:30 2000 UTC (23 years, 11 months ago) by fgsch
Branch: MAIN
Changes since 1.3: +4 -3 lines

more cleaning. KNF

/*
 *	Transparent Cryptographic File System (TCFS) for NetBSD 
 *	Author and mantainer: 	Luigi Catuogno [luicat@tcfs.unisa.it]
 *	
 *	references:		http://tcfs.dia.unisa.it
 *				tcfs-bsd@tcfs.unisa.it
 */

/*
 *	Base utility set v0.1
 */

#include <sys/types.h>
#include <grp.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <miscfs/tcfs/tcfs.h>
#include "tcfslib.h"
#include "tcfserrors.h"

char *addgroup_usage="Usage: %s [OPTION]
Add a TCFS group to the TCFS group database.

  -g <group>          Group id [or name] of the TCFS group
  -m <members>        Number of members of the group
  -t <threshold>      Threshold of the group
  -v                  Makes the output a little more verbose
  -h                  Shows this help\n";

int threshold;
unsigned char coeff[KEYSIZE][256];
unsigned char *S=NULL;          /* Pointer to a 64-bit TCFS group key */

union bobbit
{
	unsigned char byte;
	struct
	{ 
		unsigned char b1:1;
		unsigned char b2:1;
		unsigned char b3:1;
		unsigned char b4:1;
		unsigned char b5:1;
		unsigned char b6:1;
		unsigned char b7:1;
		unsigned char b8:1;
	} bf;
};

int
tcfsgetuid (char *login) 
{    
	struct passwd *entry;

	setpwent();

	while ((entry = getpwent()) != NULL) {
		if (strcmp (login, entry->pw_name) == 0)
			return entry->pw_uid;
	}

	endpwent();
	free(entry);

	return -1;
}    

void
gencoeff (void)
{    
	int i, j;

	for (i = 0; i < KEYSIZE; i++){
		for (j = 1; j < threshold; j++){
			coeff[j][i] = arc4random();
		}
	}
}

unsigned char *
gengrpkey (char *login)
{
	int x1, i, j, k=0;
	unsigned int x;

	unsigned char *res = NULL;
	unsigned int tmp;
	union bobbit obits;

	res = (unsigned char*)calloc(KEYSIZE + KEYSIZE/8, sizeof(char));
	if (!res)
		tcfs_error (ER_MEM, NULL);

	x1 = tcfsgetuid(login);
	x = (x1 % 257);

#ifdef DEBUG_TCFS
	printf ("La chiave utente di %u e':\n", x);
#endif

	for (i = 0; i < KEYSIZE; i++) {
		tmp = 0;
		for (j = 1; j < threshold; j++) {
			tmp += (eleva(x1,j,257)*coeff[j][i]) % 257;
#ifdef DEBUG_TCFS
			printf ("x1= %u\tj=%d\tcoeff[%d][%d]=%u\ttmp=%u\tchiave: ", x1, j, j, i, coeff[j][i], tmp);
#endif
			}
		tmp += (unsigned int)S[i];
		tmp %= 257;

		memcpy (res+k++, &tmp, 1);
#ifdef DEBUG_TCFS
		printf ("%u\n", *(res+k-1));
#endif
		switch (i % 8){
			case 0:
				obits.bf.b1=tmp>>8;
				break;
			case 1:
				obits.bf.b2=tmp>>8;
				break;
			case 2:
				obits.bf.b3=tmp>>8;
				break;
			case 3:
				obits.bf.b4=tmp>>8;
				break;
			case 4:
				obits.bf.b5=tmp>>8;
				break;
			case 5:
				obits.bf.b6=tmp>>8;
				break;
			case 6:
				obits.bf.b7=tmp>>8;
				break;
			case 7:
				obits.bf.b8=tmp>>8;
				break;
		}

		if ((i%8) == 7) {
			res[k] = obits.byte;
			k++;

#ifdef DEBUG_TCFS
			printf ("%u\n", res[k-1]);
#endif

			obits.byte=0;
		}
	}

	/*
	res[KEYSIZE]=obits.byte;
	*/
	return res;
}

int 
addgroup_main (int argn, char *argv[])
{
	int val;
	gid_t gid;
	int have_gid = FALSE, have_members = FALSE, have_threshold = FALSE;
	int be_verbose = FALSE;
	int temp_members, members;
	tcfsgpwdb **group_info;

	/*
	 * Going to check the arguments
	 */
	while ((val = getopt (argn, argv, "vg:m:t:h")) != EOF)
		switch (val) {
		case 'm':
			members = atoi(optarg);
			have_members = TRUE;
			break;
		case 'g':
			gid = (gid_t)atoi(optarg);
			if (!gid && optarg[0] != '0') { /* group name given */
				struct group *group_id;

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

				gid=group_id->gr_gid;
			}

			have_gid = TRUE;
			break;
		case 't':
			threshold = atoi(optarg);
			have_threshold = TRUE;
			break;
		case 'h':
			show_usage (addgroup_usage, argv[0]);
			exit (OK);
		case 'v':
			be_verbose = TRUE;
			break;
		default:
			fprintf (stderr, "Try %s --help for more information.\n", argv[0]);
			exit (ER_UNKOPT);
		}

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

	if (!have_gid) {
		char *buff = NULL;
		int len;

		buff = (char*)calloc(2048, sizeof(char));
		if (!buff)
			tcfs_error (ER_MEM, NULL);

		printf ("Group id [or name] of the TCFS group to add to the database: ");
		fgets (buff, 2048, stdin);
		len = strlen(buff) - 1;
		buff[len] = buff[len] == '\n' ? 0 : buff[len];
		gid = atoi(buff);

		if (!gid && buff[0] != '0') { /* group name given */ 
			struct group *group_id;

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

			gid = group_id->gr_gid;
		}

		if (gid <= 0)
			tcfs_error (ER_CUSTOM, "A positive ID please!");

		free (buff);
	}

	if (!have_members) {
		char *buff = NULL;
		int len;

		buff=(char*)calloc(2048, sizeof(char));
		if (!buff)
			tcfs_error (ER_MEM, NULL);

		printf ("Number of members for the TCFS group ID #%d: ", gid);
		fgets (buff, 2048, stdin);
		len = strlen(buff) - 1;
		buff[len] = buff[len] == '\n' ? 0 : buff[len];
		members = atoi(buff);

		free(buff);
	}

	if (!have_threshold) {
		char *buff = NULL;
		int len;

		buff = (char*)calloc(2048, sizeof(char));
		if (!buff)
			tcfs_error (ER_MEM, NULL);

		printf ("Threshold for the TCFS group ID #%d: ", gid);
		fgets (buff, 2048, stdin);
		len = strlen(buff) - 1;
		buff[len] = buff[len] == '\n' ? 0 : buff[len];
		threshold = atoi(buff);

		free (buff);
	}

	if (members < 2)
		tcfs_error (ER_CUSTOM, "At least two members!");

	if (threshold > members || threshold <= 0)
		tcfs_error (ER_CUSTOM, "The threshold must be no greater than the number of members and greater than zero!");

	S = gentcfskey();
#ifdef DEBUG_TCFS
	{
		int i;

		printf ("La chiave segreta e':\n");

		for (i=0;i<KEYSIZE;i++)
			printf ("%u:", S[i]);

		printf ("\n");
	}
#endif

	gencoeff();

	temp_members = members;

	group_info = (tcfsgpwdb **)calloc(members, sizeof(tcfsgpwdb *));

	/*
	 * Creating user entry
	 */
	while (members) {
		char *user = NULL, *passwd = NULL;
		unsigned char *newkey = NULL, *cryptedkey = NULL;
		tcfsgpwdb *tmp = NULL;
		int tmpmemb = temp_members, cont=0;

		group_info[members-1] = (tcfsgpwdb *)calloc(1, sizeof(tcfsgpwdb));

		group_info[members-1]->gid = gid;
		group_info[members-1]->n = members;
		group_info[members-1]->soglia = threshold;

		if (!unix_auth (&user, &passwd, FALSE)) {
			fprintf (stderr, "Invalid password or the user does not exist.\n");
			continue;
		}

		if (tcfs_ggetpwnam (user, gid, &tmp))
			tcfs_error(ER_CUSTOM, "Group already exists.");

		while (tmpmemb > members) {
			if (!strcmp (user, group_info[tmpmemb-1]->user)) {
				fprintf (stderr, "User already present into the group.\n");
				cont = 1;
				break;
			}
			tmpmemb--;
		}

		if (cont)
			continue;

		strcpy (group_info[members-1]->user, user);

		newkey = (unsigned char*)calloc(GKEYSIZE + 1, sizeof (char));
		if (!newkey)
			tcfs_error (ER_MEM, NULL);

		cryptedkey = (unsigned char*)calloc(UUGKEYSIZE, sizeof(char));
		if (!cryptedkey)
			tcfs_error (ER_MEM, NULL);

		memcpy (newkey, gengrpkey (user), GKEYSIZE);
		newkey[GKEYSIZE] = '\0';

		/*
		 * Encrypt the just generated key with the user password
		 */
		if (!tcfs_encrypt_key (user, passwd, newkey, cryptedkey, GROUPKEY))
			tcfs_error (ER_MEM, NULL);

		free (newkey);

		strlcpy (group_info[members - 1]->gkey, cryptedkey,
			 GKEYSIZE + 1);
		free (cryptedkey);

		members--;
	}

	members = temp_members;

	while (members) {
		if (be_verbose)
			printf ("Creating a new entry for group %d and user %s in the TCFS database...\n", 
				group_info[members-1]->gid,
				group_info[members-1]->user);

		if (!tcfs_gputpwnam (group_info[members-1]->user,
				     group_info[members-1], U_NEW)) {
				/* TODO: Remove the group entries saved before */
			tcfs_error (ER_CUSTOM, "Error: cannot add a user to the group.");
		}

		if (be_verbose)
			printf ("TCFS group entry for user %s created.\n", group_info[members-1]->user);

		members--;
	}

	tcfs_error (ER_CUSTOM, "\nAll group keys generated.");

	return 0;
}


int
eleva(int x, int y, int z)
{
	int mask = 0x80000000;
	int res = 1,i;

	for (i = 0; i < 32; i++) {
		res = (res*res)%z;
		if (y & mask)
			res = (x*res)%z;
		mask = mask >> 1;
	}

	return res;
}