Annotation of src/usr.bin/tcfs/tcfsaddgroup.c, Revision 1.10
1.10 ! fgsch 1: /* $OpenBSD: tcfsaddgroup.c,v 1.9 2000/06/19 23:06:25 aaron 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];
1.9 aaron 38: unsigned char *S = NULL; /* Pointer to a 64-bit TCFS group key */
1.1 provos 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.9 aaron 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:
1.9 aaron 96: res = (unsigned char *)calloc(KEYSIZE + KEYSIZE / 8, sizeof(char));
1.1 provos 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:
1.9 aaron 125: obits.bf.b1 = tmp >> 8;
1.8 aaron 126: break;
127: case 1:
1.9 aaron 128: obits.bf.b2 = tmp >> 8;
1.8 aaron 129: break;
130: case 2:
1.9 aaron 131: obits.bf.b3 = tmp >> 8;
1.8 aaron 132: break;
133: case 3:
1.9 aaron 134: obits.bf.b4 = tmp >> 8;
1.8 aaron 135: break;
136: case 4:
1.9 aaron 137: obits.bf.b5 = tmp >> 8;
1.8 aaron 138: break;
139: case 5:
1.9 aaron 140: obits.bf.b6 = tmp >> 8;
1.8 aaron 141: break;
142: case 6:
1.9 aaron 143: obits.bf.b7 = tmp >> 8;
1.8 aaron 144: break;
145: case 7:
1.9 aaron 146: obits.bf.b8 = tmp >> 8;
1.8 aaron 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.9 aaron 194: tcfs_error(ER_CUSTOM,
195: "Nonexistent group.");
1.1 provos 196:
1.8 aaron 197: gid = group_id->gr_gid;
1.1 provos 198: }
199:
200: have_gid = TRUE;
201: break;
202: case 't':
203: threshold = atoi(optarg);
204: have_threshold = TRUE;
205: break;
206: case 'h':
1.10 ! fgsch 207: printf(addgroup_usage, argv[0]);
1.8 aaron 208: exit(OK);
1.1 provos 209: case 'v':
210: be_verbose = TRUE;
211: break;
212: default:
1.9 aaron 213: fprintf(stderr,
214: "Try %s --help for more information.\n", argv[0]);
1.8 aaron 215: exit(ER_UNKOPT);
1.1 provos 216: }
217:
218: if (argn-optind)
1.8 aaron 219: tcfs_error(ER_UNKOPT, NULL);
1.1 provos 220:
221: if (!have_gid) {
222: char *buff = NULL;
223: int len;
224:
1.9 aaron 225: buff = (char *)calloc(2048, sizeof(char));
1.1 provos 226: if (!buff)
1.8 aaron 227: tcfs_error(ER_MEM, NULL);
1.1 provos 228:
1.9 aaron 229: printf("Group ID (or name) of TCFS group to add to the database: ");
1.8 aaron 230: fgets(buff, 2048, stdin);
1.2 provos 231: len = strlen(buff) - 1;
1.1 provos 232: buff[len] = buff[len] == '\n' ? 0 : buff[len];
233: gid = atoi(buff);
234:
235: if (!gid && buff[0] != '0') { /* group name given */
236: struct group *group_id;
237:
238: group_id = getgrnam(buff);
239: if (!group_id)
1.8 aaron 240: tcfs_error(ER_CUSTOM, "Nonexistent group.");
1.1 provos 241:
1.2 provos 242: gid = group_id->gr_gid;
1.1 provos 243: }
244:
245: if (gid <= 0)
1.8 aaron 246: tcfs_error(ER_CUSTOM, "A positive ID please!");
1.1 provos 247:
1.8 aaron 248: free(buff);
1.1 provos 249: }
250:
251: if (!have_members) {
252: char *buff = NULL;
253: int len;
254:
1.9 aaron 255: buff = (char *)calloc(2048, sizeof(char));
1.1 provos 256: if (!buff)
1.8 aaron 257: tcfs_error(ER_MEM, NULL);
1.1 provos 258:
1.8 aaron 259: printf("Number of members for the TCFS group ID #%d: ", gid);
260: fgets(buff, 2048, stdin);
1.2 provos 261: len = strlen(buff) - 1;
1.1 provos 262: buff[len] = buff[len] == '\n' ? 0 : buff[len];
263: members = atoi(buff);
264:
265: free(buff);
266: }
267:
268: if (!have_threshold) {
269: char *buff = NULL;
270: int len;
271:
1.9 aaron 272: buff = (char *)calloc(2048, sizeof(char));
1.1 provos 273: if (!buff)
1.8 aaron 274: tcfs_error(ER_MEM, NULL);
1.1 provos 275:
1.8 aaron 276: printf("Threshold for the TCFS group ID #%d: ", gid);
277: fgets(buff, 2048, stdin);
1.2 provos 278: len = strlen(buff) - 1;
1.1 provos 279: buff[len] = buff[len] == '\n' ? 0 : buff[len];
280: threshold = atoi(buff);
281:
1.8 aaron 282: free(buff);
1.1 provos 283: }
284:
285: if (members < 2)
1.8 aaron 286: tcfs_error(ER_CUSTOM, "At least two members!");
1.1 provos 287:
288: if (threshold > members || threshold <= 0)
1.8 aaron 289: tcfs_error(ER_CUSTOM, "The threshold must be no greater than the number of members and greater than zero!");
1.1 provos 290:
291: S = gentcfskey();
292: #ifdef DEBUG_TCFS
293: {
294: int i;
295:
1.8 aaron 296: printf("La chiave segreta e':\n");
1.1 provos 297:
1.8 aaron 298: for (i = 0; i < KEYSIZE; i++)
299: printf("%u:", S[i]);
1.1 provos 300:
1.8 aaron 301: printf("\n");
1.1 provos 302: }
303: #endif
304:
305: gencoeff();
306:
307: temp_members = members;
308:
309: group_info = (tcfsgpwdb **)calloc(members, sizeof(tcfsgpwdb *));
310:
311: /*
312: * Creating user entry
313: */
314: while (members) {
315: char *user = NULL, *passwd = NULL;
316: unsigned char *newkey = NULL, *cryptedkey = NULL;
317: tcfsgpwdb *tmp = NULL;
1.9 aaron 318: int tmpmemb = temp_members, cont = 0;
1.1 provos 319:
1.9 aaron 320: group_info[members - 1] = (tcfsgpwdb *)calloc(1,
321: sizeof(tcfsgpwdb));
1.1 provos 322:
1.9 aaron 323: group_info[members - 1]->gid = gid;
324: group_info[members - 1]->n = members;
325: group_info[members - 1]->soglia = threshold;
1.1 provos 326:
1.8 aaron 327: if (!unix_auth(&user, &passwd, FALSE)) {
328: fprintf(stderr, "Invalid password or the user does not exist.\n");
1.1 provos 329: continue;
330: }
331:
1.8 aaron 332: if (tcfs_ggetpwnam(user, gid, &tmp))
1.1 provos 333: tcfs_error(ER_CUSTOM, "Group already exists.");
334:
335: while (tmpmemb > members) {
1.8 aaron 336: if (!strcmp(user, group_info[tmpmemb-1]->user)) {
337: fprintf(stderr, "User already present into the group.\n");
1.1 provos 338: cont = 1;
339: break;
340: }
341: tmpmemb--;
342: }
343:
344: if (cont)
345: continue;
346:
1.9 aaron 347: strcpy(group_info[members - 1]->user, user);
1.1 provos 348:
1.9 aaron 349: newkey = (unsigned char *)calloc(GKEYSIZE + 1, sizeof(char));
1.1 provos 350: if (!newkey)
1.8 aaron 351: tcfs_error(ER_MEM, NULL);
1.1 provos 352:
1.9 aaron 353: cryptedkey = (unsigned char *)calloc(UUGKEYSIZE, sizeof(char));
1.1 provos 354: if (!cryptedkey)
1.8 aaron 355: tcfs_error(ER_MEM, NULL);
1.1 provos 356:
1.8 aaron 357: memcpy(newkey, gengrpkey(user), GKEYSIZE);
1.2 provos 358: newkey[GKEYSIZE] = '\0';
1.1 provos 359:
360: /*
361: * Encrypt the just generated key with the user password
362: */
1.8 aaron 363: if (!tcfs_encrypt_key(passwd, newkey, GKEYSIZE, cryptedkey,
364: UUGKEYSIZE))
365: tcfs_error(ER_MEM, NULL);
366:
367: free(newkey);
368:
369: strlcpy(group_info[members - 1]->gkey, cryptedkey,
370: GKEYSIZE + 1);
371: free(cryptedkey);
1.1 provos 372:
373: members--;
374: }
375:
1.2 provos 376: members = temp_members;
1.1 provos 377:
378: while (members) {
379: if (be_verbose)
1.8 aaron 380: printf("Creating a new entry for group %d and user %s in the TCFS database...\n",
1.9 aaron 381: group_info[members - 1]->gid,
382: group_info[members - 1]->user);
1.1 provos 383:
1.9 aaron 384: if (!tcfs_gputpwnam(group_info[members - 1]->user,
385: group_info[members - 1], U_NEW)) {
1.1 provos 386: /* TODO: Remove the group entries saved before */
1.8 aaron 387: tcfs_error(ER_CUSTOM, "Error: cannot add a user to the group.");
1.1 provos 388: }
389:
390: if (be_verbose)
1.9 aaron 391: printf("TCFS group entry for user %s created.\n", group_info[members - 1]->user);
1.1 provos 392:
393: members--;
394: }
395:
1.8 aaron 396: tcfs_error(ER_CUSTOM, "\nAll group keys generated.");
1.1 provos 397:
1.8 aaron 398: return (0);
1.1 provos 399: }
400:
401:
402: int
403: eleva(int x, int y, int z)
404: {
405: int mask = 0x80000000;
1.8 aaron 406: int res = 1, i;
1.1 provos 407:
408: for (i = 0; i < 32; i++) {
1.8 aaron 409: res = (res * res) % z;
1.1 provos 410: if (y & mask)
1.8 aaron 411: res = (x * res) % z;
1.1 provos 412: mask = mask >> 1;
413: }
414:
1.8 aaron 415: return (res);
1.1 provos 416: }