diff options
author | Niels Provos <provos@cvs.openbsd.org> | 2000-06-18 22:07:26 +0000 |
---|---|---|
committer | Niels Provos <provos@cvs.openbsd.org> | 2000-06-18 22:07:26 +0000 |
commit | 48893562fdfa12c4f376d2556da18e817a34484f (patch) | |
tree | 033e9aaa47f5617ba6ffbcf7e071ffb8f8f71b07 /usr.bin/tcfs/tcfsaddgroup.c | |
parent | 47bc7a26b81967e77c0f021899f1544966df67e2 (diff) |
Initial import of very much rewritten TCFS userland. This code is still
nasty.
Diffstat (limited to 'usr.bin/tcfs/tcfsaddgroup.c')
-rw-r--r-- | usr.bin/tcfs/tcfsaddgroup.c | 432 |
1 files changed, 432 insertions, 0 deletions
diff --git a/usr.bin/tcfs/tcfsaddgroup.c b/usr.bin/tcfs/tcfsaddgroup.c new file mode 100644 index 00000000000..d9e850b08ab --- /dev/null +++ b/usr.bin/tcfs/tcfsaddgroup.c @@ -0,0 +1,432 @@ +/* + * 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 <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <pwd.h> +#include <grp.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 l, 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 index, 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) - 2; + 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) - 2; + 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) - 2; + 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(KEYSIZE*2, sizeof (char)); + if (!newkey) + tcfs_error (ER_MEM, NULL); + + cryptedkey = (unsigned char*)calloc(UUKEYSIZE, sizeof(char)); + if (!cryptedkey) + tcfs_error (ER_MEM, NULL); + + memcpy (newkey, gengrpkey (user), KEYSIZE + KEYSIZE/8); + newkey[KEYSIZE + KEYSIZE/8] = '\0'; +#ifdef DEBUG_TCFS + { + int i; + + printf ("%s newkey: ", user); + for (i = 0;i <= KEYSIZE; i++) + printf ("%u:", newkey[i]); + printf ("\n"); + } +#endif + + /* + * Encrypt the just generated key with the user password + */ + if (!tcfs_encrypt_key (user, passwd, newkey, cryptedkey, GROUPKEY)) + tcfs_error (ER_MEM, NULL); + +#ifdef DEBUG_TCFS + { + unsigned char *key; + int i; + + key=(unsigned char *)calloc(UUKEYSIZE, sizeof(char)); + if (!tcfs_decrypt_key (user, passwd, cryptedkey, key, GROUPKEY)) + exit (0); + + printf ("%s key: ", user); + for (i=0;i<=KEYSIZE;i++) + printf ("%u:", key[i]); + printf ("\n"); + + free (key); + } +#endif + + free (newkey); + + strcpy (group_info[members-1]->gkey, cryptedkey); + free (cryptedkey); + + members--; + } + + members=temp_members; + + while (members) { + if (be_verbose) + printf ("Creating a new entry for user %s in the TCFS database...\n", 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; +} |