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