Annotation of src/usr.bin/tcfs/tcfsaddgroup.c, Revision 1.1.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: }