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