Annotation of src/usr.bin/tcfs/tcfsaddgroup.c, Revision 1.1
1.1 ! provos 1: /*
! 2: * Transparent Cryptographic File System (TCFS) for NetBSD
! 3: * Author and mantainer: Luigi Catuogno [luicat@tcfs.unisa.it]
! 4: *
! 5: * references: http://tcfs.dia.unisa.it
! 6: * tcfs-bsd@tcfs.unisa.it
! 7: */
! 8:
! 9: /*
! 10: * Base utility set v0.1
! 11: */
! 12:
! 13: #include <sys/types.h>
! 14: #include <stdio.h>
! 15: #include <unistd.h>
! 16: #include <stdlib.h>
! 17: #include <pwd.h>
! 18: #include <grp.h>
! 19:
! 20: #include <miscfs/tcfs/tcfs.h>
! 21: #include "tcfslib.h"
! 22: #include "tcfserrors.h"
! 23:
! 24: char *addgroup_usage="Usage: %s [OPTION]
! 25: Add a TCFS group to the TCFS group database.
! 26:
! 27: -g <group> Group id [or name] of the TCFS group
! 28: -m <members> Number of members of the group
! 29: -t <threshold> Threshold of the group
! 30: -v Makes the output a little more verbose
! 31: -h Shows this help\n";
! 32:
! 33: int threshold;
! 34: unsigned char coeff[KEYSIZE][256];
! 35: unsigned char *S=NULL; /* Pointer to a 64-bit TCFS group key */
! 36:
! 37: union bobbit
! 38: {
! 39: unsigned char byte;
! 40: struct
! 41: {
! 42: unsigned char b1:1;
! 43: unsigned char b2:1;
! 44: unsigned char b3:1;
! 45: unsigned char b4:1;
! 46: unsigned char b5:1;
! 47: unsigned char b6:1;
! 48: unsigned char b7:1;
! 49: unsigned char b8:1;
! 50: } bf;
! 51: };
! 52:
! 53: int
! 54: tcfsgetuid (char *login)
! 55: {
! 56: struct passwd *entry;
! 57:
! 58: setpwent();
! 59:
! 60: while ((entry = getpwent()) != NULL) {
! 61: if (strcmp (login, entry->pw_name) == 0)
! 62: return entry->pw_uid;
! 63: }
! 64:
! 65: endpwent();
! 66: free(entry);
! 67:
! 68: return -1;
! 69: }
! 70:
! 71: void
! 72: gencoeff (void)
! 73: {
! 74: int i, j;
! 75:
! 76: for (i = 0; i < KEYSIZE; i++){
! 77: for (j = 1; j < threshold; j++){
! 78: coeff[j][i] = arc4random();
! 79: }
! 80: }
! 81: }
! 82:
! 83: unsigned char *
! 84: gengrpkey (char *login)
! 85: {
! 86: int l, x1, i, j, k=0;
! 87: unsigned int x;
! 88:
! 89: unsigned char *res = NULL;
! 90: unsigned int tmp;
! 91: union bobbit obits;
! 92:
! 93: res = (unsigned char*)calloc(KEYSIZE + KEYSIZE/8, sizeof(char));
! 94: if (!res)
! 95: tcfs_error (ER_MEM, NULL);
! 96:
! 97: x1 = tcfsgetuid(login);
! 98: x = (x1 % 257);
! 99:
! 100: #ifdef DEBUG_TCFS
! 101: printf ("La chiave utente di %u e':\n", x);
! 102: #endif
! 103:
! 104: for (i = 0; i < KEYSIZE; i++) {
! 105: tmp = 0;
! 106: for (j = 1; j < threshold; j++) {
! 107: tmp += (eleva(x1,j,257)*coeff[j][i]) % 257;
! 108: #ifdef DEBUG_TCFS
! 109: printf ("x1= %u\tj=%d\tcoeff[%d][%d]=%u\ttmp=%u\tchiave: ", x1, j, j, i, coeff[j][i], tmp);
! 110: #endif
! 111: }
! 112: tmp += (unsigned int)S[i];
! 113: tmp %= 257;
! 114:
! 115: memcpy (res+k++, &tmp, 1);
! 116: #ifdef DEBUG_TCFS
! 117: printf ("%u\n", *(res+k-1));
! 118: #endif
! 119: switch (i % 8){
! 120: case 0:
! 121: obits.bf.b1=tmp>>8;
! 122: break;
! 123: case 1:
! 124: obits.bf.b2=tmp>>8;
! 125: break;
! 126: case 2:
! 127: obits.bf.b3=tmp>>8;
! 128: break;
! 129: case 3:
! 130: obits.bf.b4=tmp>>8;
! 131: break;
! 132: case 4:
! 133: obits.bf.b5=tmp>>8;
! 134: break;
! 135: case 5:
! 136: obits.bf.b6=tmp>>8;
! 137: break;
! 138: case 6:
! 139: obits.bf.b7=tmp>>8;
! 140: break;
! 141: case 7:
! 142: obits.bf.b8=tmp>>8;
! 143: break;
! 144: }
! 145:
! 146: if ((i%8) == 7) {
! 147: res[k] = obits.byte;
! 148: k++;
! 149:
! 150: #ifdef DEBUG_TCFS
! 151: printf ("%u\n", res[k-1]);
! 152: #endif
! 153:
! 154: obits.byte=0;
! 155: }
! 156: }
! 157:
! 158: /*
! 159: res[KEYSIZE]=obits.byte;
! 160: */
! 161: return res;
! 162: }
! 163:
! 164: int
! 165: addgroup_main (int argn, char *argv[])
! 166: {
! 167: int index, val;
! 168: gid_t gid;
! 169: int have_gid = FALSE, have_members = FALSE, have_threshold = FALSE;
! 170: int be_verbose = FALSE;
! 171: int temp_members, members;
! 172: tcfsgpwdb **group_info;
! 173:
! 174: /*
! 175: * Going to check the arguments
! 176: */
! 177: while ((val = getopt (argn, argv, "vg:m:t:h")) != EOF)
! 178: switch (val) {
! 179: case 'm':
! 180: members = atoi(optarg);
! 181: have_members = TRUE;
! 182: break;
! 183: case 'g':
! 184: gid = (gid_t)atoi(optarg);
! 185: if (!gid && optarg[0] != '0') { /* group name given */
! 186: struct group *group_id;
! 187:
! 188: group_id = getgrnam(optarg);
! 189: if (!group_id)
! 190: tcfs_error (ER_CUSTOM, "Nonexistent group.");
! 191:
! 192: gid=group_id->gr_gid;
! 193: }
! 194:
! 195: have_gid = TRUE;
! 196: break;
! 197: case 't':
! 198: threshold = atoi(optarg);
! 199: have_threshold = TRUE;
! 200: break;
! 201: case 'h':
! 202: show_usage (addgroup_usage, argv[0]);
! 203: exit (OK);
! 204: case 'v':
! 205: be_verbose = TRUE;
! 206: break;
! 207: default:
! 208: fprintf (stderr, "Try %s --help for more information.\n", argv[0]);
! 209: exit (ER_UNKOPT);
! 210: }
! 211:
! 212: if (argn-optind)
! 213: tcfs_error (ER_UNKOPT, NULL);
! 214:
! 215: if (!have_gid) {
! 216: char *buff = NULL;
! 217: int len;
! 218:
! 219: buff = (char*)calloc(2048, sizeof(char));
! 220: if (!buff)
! 221: tcfs_error (ER_MEM, NULL);
! 222:
! 223: printf ("Group id [or name] of the TCFS group to add to the database: ");
! 224: fgets (buff, 2048, stdin);
! 225: len = strlen(buff) - 2;
! 226: buff[len] = buff[len] == '\n' ? 0 : buff[len];
! 227: gid = atoi(buff);
! 228:
! 229: if (!gid && buff[0] != '0') { /* group name given */
! 230: struct group *group_id;
! 231:
! 232: group_id = getgrnam(buff);
! 233: if (!group_id)
! 234: tcfs_error (ER_CUSTOM, "Nonexistent group.");
! 235:
! 236: gid=group_id->gr_gid;
! 237: }
! 238:
! 239: if (gid <= 0)
! 240: tcfs_error (ER_CUSTOM, "A positive ID please!");
! 241:
! 242: free (buff);
! 243: }
! 244:
! 245: if (!have_members) {
! 246: char *buff = NULL;
! 247: int len;
! 248:
! 249: buff=(char*)calloc(2048, sizeof(char));
! 250: if (!buff)
! 251: tcfs_error (ER_MEM, NULL);
! 252:
! 253: printf ("Number of members for the TCFS group ID #%d: ", gid);
! 254: fgets (buff, 2048, stdin);
! 255: len = strlen(buff) - 2;
! 256: buff[len] = buff[len] == '\n' ? 0 : buff[len];
! 257: members = atoi(buff);
! 258:
! 259: free(buff);
! 260: }
! 261:
! 262: if (!have_threshold) {
! 263: char *buff = NULL;
! 264: int len;
! 265:
! 266: buff = (char*)calloc(2048, sizeof(char));
! 267: if (!buff)
! 268: tcfs_error (ER_MEM, NULL);
! 269:
! 270: printf ("Threshold for the TCFS group ID #%d: ", gid);
! 271: fgets (buff, 2048, stdin);
! 272: len = strlen(buff) - 2;
! 273: buff[len] = buff[len] == '\n' ? 0 : buff[len];
! 274: threshold = atoi(buff);
! 275:
! 276: free (buff);
! 277: }
! 278:
! 279: if (members < 2)
! 280: tcfs_error (ER_CUSTOM, "At least two members!");
! 281:
! 282: if (threshold > members || threshold <= 0)
! 283: tcfs_error (ER_CUSTOM, "The threshold must be no greater than the number of members and greater than zero!");
! 284:
! 285: S = gentcfskey();
! 286: #ifdef DEBUG_TCFS
! 287: {
! 288: int i;
! 289:
! 290: printf ("La chiave segreta e':\n");
! 291:
! 292: for (i=0;i<KEYSIZE;i++)
! 293: printf ("%u:", S[i]);
! 294:
! 295: printf ("\n");
! 296: }
! 297: #endif
! 298:
! 299: gencoeff();
! 300:
! 301: temp_members = members;
! 302:
! 303: group_info = (tcfsgpwdb **)calloc(members, sizeof(tcfsgpwdb *));
! 304:
! 305: /*
! 306: * Creating user entry
! 307: */
! 308: while (members) {
! 309: char *user = NULL, *passwd = NULL;
! 310: unsigned char *newkey = NULL, *cryptedkey = NULL;
! 311: tcfsgpwdb *tmp = NULL;
! 312: int tmpmemb = temp_members, cont=0;
! 313:
! 314: group_info[members-1] = (tcfsgpwdb *)calloc(1, sizeof(tcfsgpwdb));
! 315:
! 316: group_info[members-1]->gid = gid;
! 317: group_info[members-1]->n = members;
! 318: group_info[members-1]->soglia = threshold;
! 319:
! 320: if (!unix_auth (&user, &passwd, FALSE)) {
! 321: fprintf (stderr, "Invalid password or the user does not exist.\n");
! 322: continue;
! 323: }
! 324:
! 325: if (tcfs_ggetpwnam (user, gid, &tmp))
! 326: tcfs_error(ER_CUSTOM, "Group already exists.");
! 327:
! 328: while (tmpmemb > members) {
! 329: if (!strcmp (user, group_info[tmpmemb-1]->user)) {
! 330: fprintf (stderr, "User already present into the group.\n");
! 331: cont = 1;
! 332: break;
! 333: }
! 334: tmpmemb--;
! 335: }
! 336:
! 337: if (cont)
! 338: continue;
! 339:
! 340: strcpy (group_info[members-1]->user, user);
! 341:
! 342: newkey = (unsigned char*)calloc(KEYSIZE*2, sizeof (char));
! 343: if (!newkey)
! 344: tcfs_error (ER_MEM, NULL);
! 345:
! 346: cryptedkey = (unsigned char*)calloc(UUKEYSIZE, sizeof(char));
! 347: if (!cryptedkey)
! 348: tcfs_error (ER_MEM, NULL);
! 349:
! 350: memcpy (newkey, gengrpkey (user), KEYSIZE + KEYSIZE/8);
! 351: newkey[KEYSIZE + KEYSIZE/8] = '\0';
! 352: #ifdef DEBUG_TCFS
! 353: {
! 354: int i;
! 355:
! 356: printf ("%s newkey: ", user);
! 357: for (i = 0;i <= KEYSIZE; i++)
! 358: printf ("%u:", newkey[i]);
! 359: printf ("\n");
! 360: }
! 361: #endif
! 362:
! 363: /*
! 364: * Encrypt the just generated key with the user password
! 365: */
! 366: if (!tcfs_encrypt_key (user, passwd, newkey, cryptedkey, GROUPKEY))
! 367: tcfs_error (ER_MEM, NULL);
! 368:
! 369: #ifdef DEBUG_TCFS
! 370: {
! 371: unsigned char *key;
! 372: int i;
! 373:
! 374: key=(unsigned char *)calloc(UUKEYSIZE, sizeof(char));
! 375: if (!tcfs_decrypt_key (user, passwd, cryptedkey, key, GROUPKEY))
! 376: exit (0);
! 377:
! 378: printf ("%s key: ", user);
! 379: for (i=0;i<=KEYSIZE;i++)
! 380: printf ("%u:", key[i]);
! 381: printf ("\n");
! 382:
! 383: free (key);
! 384: }
! 385: #endif
! 386:
! 387: free (newkey);
! 388:
! 389: strcpy (group_info[members-1]->gkey, cryptedkey);
! 390: free (cryptedkey);
! 391:
! 392: members--;
! 393: }
! 394:
! 395: members=temp_members;
! 396:
! 397: while (members) {
! 398: if (be_verbose)
! 399: printf ("Creating a new entry for user %s in the TCFS database...\n", group_info[members-1]->user);
! 400:
! 401: if (!tcfs_gputpwnam (group_info[members-1]->user, group_info[members-1], U_NEW)) {
! 402: /* TODO: Remove the group entries saved before */
! 403: tcfs_error (ER_CUSTOM, "Error: cannot add a user to the group.");
! 404: }
! 405:
! 406: if (be_verbose)
! 407: printf ("TCFS group entry for user %s created.\n", group_info[members-1]->user);
! 408:
! 409: members--;
! 410: }
! 411:
! 412: tcfs_error (ER_CUSTOM, "\nAll group keys generated.");
! 413:
! 414: return 0;
! 415: }
! 416:
! 417:
! 418: int
! 419: eleva(int x, int y, int z)
! 420: {
! 421: int mask = 0x80000000;
! 422: int res = 1,i;
! 423:
! 424: for (i = 0; i < 32; i++) {
! 425: res = (res*res)%z;
! 426: if (y & mask)
! 427: res = (x*res)%z;
! 428: mask = mask >> 1;
! 429: }
! 430:
! 431: return res;
! 432: }