OSDN Git Service

aix feeadback
[openpts/openpts.git] / src / uuid.c
1 /*
2  * This file is part of the OpenPTS project.
3  *
4  * The Initial Developer of the Original Code is International
5  * Business Machines Corporation. Portions created by IBM
6  * Corporation are Copyright (C) 2010 International Business
7  * Machines Corporation. All Rights Reserved.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the Common Public License as published by
11  * IBM Corporation; either version 1 of the License, or (at your option)
12  * any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * Common Public License for more details.
18  *
19  * You should have received a copy of the Common Public License
20  * along with this program; if not, a copy can be viewed at
21  * http://www.opensource.org/licenses/cpl1.0.php.
22  */
23
24 /**
25  * \file src/uuid.c
26  * \brief UUID wrapper (Generic part, OPENPTS_UUID)
27  * @author Seiji Munetoh <munetoh@users.sourceforge.jp>
28  * @date 2010-11-29
29  * cleanup 2011-10-07 SM
30  *
31  * Linux uses libuuid
32  *
33  * UUID (as of v0.2.4)
34  *
35  * Program  UUID   Description         When               Files
36  * ---------------------------------------------------------------------------------------------------
37  * ptsc     CID    Colelctor ID        System install     => /var/lib/openpts/uuid (UUID of sign key)
38  *          RM     RM ID               RM Gen xid in RM,  path /var/lib/openpts/$UUID/rm_files
39  *          RunID  ID of this daemon   Daemon start       => /var/lib/openpts/run_uuid  TODO ptsc requires uuid file
40  * ---------------------------------------------------------------------------------------------------
41  * openpts  VID    Verifier ID         1st run            => 'HOME/.openpts/uuid
42  *          CID    Colelctor ID        Enrollment         => 'HOME/.openpts/$UUID  (dir name)
43  *          RM     Colelctor RM ID     Enrollment         => 'HOME/.openpts/$UUID/rm_uuid
44  *          NEWRM  Colelctor New RM ID Update             => 'HOME/.openpts/$UUID/newrm_uuid
45  *          OLDRM  Colelctor Old RM ID Update             => 'HOME/.openpts/$UUID/oldrm_uuid
46  * ---------------------------------------------------------------------------------------------------
47  *
48  * Unit Test: check_uuid.c
49  *
50  */
51
52 #include <stdio.h>
53 #include <string.h>
54 #include <time.h>
55 #include <sys/stat.h>
56
57 #include <sys/types.h>
58 #include <fcntl.h>
59
60 #include <errno.h>
61
62 // DIR
63 #include <unistd.h>
64 #include <dirent.h>
65
66 #include <openpts.h>
67
68 #define SEP_LINE "------------------------------------------------------------------------------------"
69
70
71 /******************************/
72 /* OPENPTS_UUID               */
73 /******************************/
74
75 /**
76  * Create new OPENPTS_UUID, no contents
77  *
78  * @return OPENPTS_UUID
79  */
80 OPENPTS_UUID *newOpenptsUuid() {
81     OPENPTS_UUID *uuid;
82
83     uuid = xmalloc(sizeof(OPENPTS_UUID));  // BYTE[16]
84     if (uuid == NULL) {
85         return NULL;
86     }
87     memset(uuid, 0, sizeof(OPENPTS_UUID));
88
89     return uuid;
90 }
91
92 /**
93  * Create new OPENPTS_UUID, with contents
94  *
95  * @return OPENPTS_UUID
96  */
97 OPENPTS_UUID *newOpenptsUuid2(PTS_UUID *pts_uuid) {
98     OPENPTS_UUID *uuid;
99
100     uuid = xmalloc(sizeof(OPENPTS_UUID));  // BYTE[16]
101     if (uuid == NULL) {
102         return NULL;
103     }
104     memset(uuid, 0, sizeof(OPENPTS_UUID));
105
106     uuid->uuid = xmalloc_assert(16);
107     memcpy(uuid->uuid, pts_uuid, 16);
108
109     uuid->str    = getStringOfUuid(uuid->uuid);
110     uuid->time   = getDateTimeOfUuid(uuid->uuid);
111     uuid->status = OPENPTS_UUID_UUID_ONLY;
112
113     return uuid;
114 }
115
116 /**
117  * init UUID from file
118  * status = OPENPTS_UUID_EMPTY
119  * @return OPENPTS_UUID
120  */
121 OPENPTS_UUID *newOpenptsUuidFromFile(char * filename) {
122     OPENPTS_UUID *uuid;
123     int rc;
124
125     uuid = newOpenptsUuid();
126     if (uuid == NULL) {
127         return NULL;
128     }
129
130     /* set the filename */
131     uuid->filename = smalloc_assert(filename);
132
133     /* load the filename */
134     rc = readOpenptsUuidFile(uuid);
135     if (rc != PTS_SUCCESS) {
136         ERROR("newOpenptsUuidFromFile() - readOpenptsUuidFile() fail rc=%d\n", rc);
137         freeOpenptsUuid(uuid);
138         return NULL;
139     }
140
141     return uuid;
142 }
143
144 /**
145  * free OPENPTS_UUID
146  */
147 void freeOpenptsUuid(OPENPTS_UUID *uuid) {
148     /* check */
149     if (uuid == NULL) {
150         ERROR("null input\n");
151         return;
152     }
153
154     if (uuid->filename != NULL) {
155         xfree(uuid->filename);
156     }
157     if (uuid->uuid  != NULL) {
158         xfree(uuid->uuid);
159     }
160     if (uuid->str  != NULL) {
161         xfree(uuid->str);
162     }
163     if (uuid->time  != NULL) {
164         xfree(uuid->time);
165     }
166
167     xfree(uuid);
168 }
169
170 /**
171  * generate new UUID
172  *
173  * @retval PTS_SUCCESS
174  * @retval PTS_INTERNAL_ERROR
175  */
176 int genOpenptsUuid(OPENPTS_UUID *uuid) {
177     /* check */
178     ASSERT(NULL != uuid, "uuid is NULL\n");
179
180     /* check the status */
181     if (uuid->status == OPENPTS_UUID_EMPTY) {
182         // hold UUID only, no binding with the file
183         uuid->status = OPENPTS_UUID_UUID_ONLY;
184     } else if (uuid->status == OPENPTS_UUID_FILENAME_ONLY) {
185         // TODO Re genenation happen, before load the UUID from file
186         DEBUG("genOpenptsUuid() %s filled, before load the UUID from file\n", uuid->str);
187         uuid->status = OPENPTS_UUID_FILLED;
188     } else if (uuid->status == OPENPTS_UUID_FILLED) {
189         // TODO Re genenation happen
190         uuid->status = OPENPTS_UUID_CHANGED;
191         ERROR("genOpenptsUuid() %s - changed\n", uuid->str);
192     } else if (uuid->status == OPENPTS_UUID_CHANGED) {
193         // TODO Re genenation happen
194         uuid->status = OPENPTS_UUID_CHANGED;
195         ERROR("genOpenptsUuid() %s - changed again\n", uuid->str);
196     } else if (uuid->status == OPENPTS_UUID_UUID_ONLY) {
197         // TODO Re genenation happen
198         uuid->status = OPENPTS_UUID_UUID_ONLY;
199         ERROR("genOpenptsUuid() %s - changed again (no binding to the file)\n", uuid->str);
200     } else {
201         ERROR("genOpenptsUuid() - bad status\n");
202     }
203
204
205     /* free */
206     if (uuid->uuid != NULL) {
207         xfree(uuid->uuid);
208     }
209     if (uuid->str != NULL) {
210         xfree(uuid->str);
211     }
212     if (uuid->time != NULL) {
213         xfree(uuid->time);
214     }
215
216     /* set */
217     uuid->uuid = newUuid();
218     uuid->str  = getStringOfUuid(uuid->uuid);
219     uuid->time = getDateTimeOfUuid(uuid->uuid);
220     // TODO check
221
222     DEBUG("genOpenptsUuid() - %s\n", uuid->str);
223
224     return PTS_SUCCESS;
225 }
226
227 /**
228  * read UUID from file(uuid->filename), and fill OPENPTS_UUID
229  *
230  * @retval PTS_SUCCESS
231  * @retval PTS_INTERNAL_ERROR
232  */
233 int readOpenptsUuidFile(OPENPTS_UUID *uuid) {
234     int rc = PTS_SUCCESS;
235     FILE *fp;
236     char line[BUF_SIZE];
237     int i;
238
239     /* check */
240     if (uuid == NULL) {
241         ERROR("\n");
242         return PTS_INTERNAL_ERROR;
243     }
244     if (uuid->filename == NULL) {
245         ERROR("\n");
246         return PTS_INTERNAL_ERROR;
247     }
248
249     DEBUG("readOpenptsUuidFile()      : %s\n", uuid->filename);
250
251     // TODO check UUID status?
252     if (uuid->status == OPENPTS_UUID_FILENAME_ONLY) {
253         // OK
254     } else {
255         //  reload UUID from same? file
256         DEBUG("reload UUID, current UUID=%s, filename=%s\n",
257             uuid->str, uuid->filename);
258     }
259
260     /* free */
261     if (uuid->uuid != NULL) {
262         xfree(uuid->uuid);
263     }
264     if (uuid->str != NULL) {
265         xfree(uuid->str);
266     }
267     if (uuid->time != NULL) {
268         xfree(uuid->time);
269     }
270
271     /* open */
272     if ((fp = fopen(uuid->filename, "r")) == NULL) {
273         // DEBUG("readUuidFile - UUID File %s open was failed\n", filename);
274         /* we don't want double free errors - we may have already freed these up
275            above. this was a genuine issue that caused multiple pointers to
276            reference the same area of memory. */
277         uuid->uuid = NULL;
278         uuid->str  = NULL;
279         uuid->time = NULL;
280         return PTS_DENIED;  // TODO
281     }
282
283     /* init buf */
284     memset(line, 0, BUF_SIZE);
285
286     /* read */
287     if (fgets(line, BUF_SIZE, fp) != NULL) {
288         /* trim \n */
289         /* remove LR at the end otherwise getUuidFromString() go bad */
290         for (i = 0; i < BUF_SIZE; i++) {
291             if (line[i] == 0x0a) {
292                 /* hit */
293                 line[i] = 0;
294             }
295         }
296         /* parse */
297         uuid->uuid = getUuidFromString(line);
298         if (uuid->uuid  == NULL) {
299             ERROR("readUuidFile() - UUID is NULL, file %s\n", uuid->filename);
300             rc = PTS_INTERNAL_ERROR;
301             goto close;
302         }
303         uuid->str = getStringOfUuid(uuid->uuid);
304         if (uuid->str == NULL) {
305             ERROR("readUuidFile() - STR UUID is NULL, file %s\n", uuid->filename);
306             rc = PTS_INTERNAL_ERROR;
307             goto close;
308         }
309         uuid->time = getDateTimeOfUuid(uuid->uuid);
310         if (uuid->time == NULL) {
311             ERROR("readUuidFile() - TIME UUID is NULL, file %s\n", uuid->filename);
312             rc = PTS_INTERNAL_ERROR;
313             goto close;
314         }
315         uuid->status = OPENPTS_UUID_FILLED;
316     } else {
317         fprintf(stderr, NLS(MS_OPENPTS, OPENPTS_UUID_READ_FAILED, "Failed to read the UUID file\n"));
318     }
319
320  close:
321     fclose(fp);
322     return rc;
323 }
324
325 /**
326  *
327  * @retval PTS_SUCCESS
328  * @retval PTS_INTERNAL_ERROR
329  */
330 int writeOpenptsUuidFile(OPENPTS_UUID *uuid, int overwrite) {
331     FILE *fp;
332     int fd;
333     int mode = S_IRUSR | S_IWUSR | S_IRGRP;
334
335     /* check */
336     if (uuid == NULL) {
337         ERROR("writeOpenptsUuidFile() - uuid == NULL\n");
338         return PTS_INTERNAL_ERROR;
339     }
340     if (uuid->filename == NULL) {
341         ERROR("writeOpenptsUuidFile() - uuid->filename == NULL\n");
342         return PTS_INTERNAL_ERROR;
343     }
344     if ((uuid->status != OPENPTS_UUID_FILLED) && (uuid->status != OPENPTS_UUID_CHANGED)) {
345         ERROR("writeOpenptsUuidFile() - uuid->status = %d (!= FILLED or CHANGED)\n", uuid->status);
346         // 1 => OPENPTS_UUID_FILENAME_ONLY, UUID is missing
347         return PTS_INTERNAL_ERROR;
348     }
349     if (uuid->str == NULL) {
350         ERROR("writeOpenptsUuidFile() - uuid->str == NULL\n");
351         return PTS_INTERNAL_ERROR;
352     }
353
354     /* open File */
355     if (overwrite == 1) {
356         /* overwrite */
357         if ((fp = fopen(uuid->filename, "w")) == NULL) {
358             fprintf(stderr, NLS(MS_OPENPTS, OPENPTS_UUID_FILE_OPEN_FAILED,
359                 "Failed to open UUID file %s\n"), uuid->filename);
360             return PTS_INTERNAL_ERROR;
361         }
362     } else {
363         /* new */
364         if ((fd = open(uuid->filename, O_CREAT | O_EXCL | O_WRONLY, mode)) == -1) {
365             if (errno == EEXIST) {
366                 /* exist, keep the current UUID file */
367                 fprintf(stderr, NLS(MS_OPENPTS, OPENPTS_UUID_FILE_EXISTS,
368                     "The UUID file '%s' already exists\n"), uuid->filename);
369                 // return PTS_SUCCESS;  // TODO
370                 return OPENPTS_FILE_EXISTS;
371             } else {
372                 fprintf(stderr, NLS(MS_OPENPTS, OPENPTS_UUID_FILE_OPEN_FAILED,
373                     "Failed to open UUID file %s\n"), uuid->filename);
374                 return PTS_INTERNAL_ERROR;
375             }
376         }
377         if ((fp = fdopen(fd, "w")) == NULL) {
378             fprintf(stderr,  NLS(MS_OPENPTS, OPENPTS_UUID_FILE_OPEN_FAILED,
379                 "Failed to open UUID file %s\n"), uuid->filename);
380             return PTS_INTERNAL_ERROR;
381         }
382     }
383
384     /* write UUID */
385     fprintf(fp, "%s", uuid->str);
386
387     fclose(fp);  // this close fd also
388
389     DEBUG("writeOpenptsUuidFile() %s -> %s\n", uuid->str, uuid->filename);
390
391     return PTS_SUCCESS;
392 }