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