/* * 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 #include #include #include #include #include #include #include "tcfslib.h" #include "tcfserrors.h" char *addgroup_usage="Usage: %s [OPTION] Add a TCFS group to the TCFS group database. -g Group id [or name] of the TCFS group -m Number of members of the group -t 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;igid = 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; }