OSDN Git Service

cleanup
[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 2012-01-05 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         LOG(LOG_ERR, "no memory");
86         return NULL;
87     }
88     memset(uuid, 0, sizeof(OPENPTS_UUID));
89
90     return uuid;
91 }
92
93 /**
94  * Create new OPENPTS_UUID, with contents
95  *
96  * @return OPENPTS_UUID
97  */
98 OPENPTS_UUID *newOpenptsUuid2(PTS_UUID *pts_uuid) {
99     OPENPTS_UUID *uuid;
100
101     /* check */
102     if (pts_uuid == NULL) {
103         LOG(LOG_ERR, "null input");
104         return NULL;
105     }
106
107     uuid = xmalloc(sizeof(OPENPTS_UUID));  // BYTE[16]
108     if (uuid == NULL) {
109         LOG(LOG_ERR, "no memory");
110         return NULL;
111     }
112     memset(uuid, 0, sizeof(OPENPTS_UUID));
113
114     uuid->uuid = xmalloc_assert(16);
115     memcpy(uuid->uuid, pts_uuid, 16);
116
117     uuid->str    = getStringOfUuid(uuid->uuid);
118     uuid->time   = getDateTimeOfUuid(uuid->uuid);
119     uuid->status = OPENPTS_UUID_UUID_ONLY;
120
121     return uuid;
122 }
123
124 /**
125  * init UUID from file
126  * status = OPENPTS_UUID_EMPTY
127  * @return OPENPTS_UUID
128  */
129 OPENPTS_UUID *newOpenptsUuidFromFile(char * filename) {
130     OPENPTS_UUID *uuid;
131     int rc;
132
133     /* check */
134     if (filename == NULL) {
135         LOG(LOG_ERR, "null input");
136         return NULL;
137     }
138
139     uuid = newOpenptsUuid();
140     if (uuid == NULL) {
141         LOG(LOG_ERR, "no memory");
142         return NULL;
143     }
144
145     /* set the filename */
146     uuid->filename = smalloc_assert(filename);
147
148     /* load the filename */
149     rc = readOpenptsUuidFile(uuid);
150     if (rc != PTS_SUCCESS) {
151         LOG(LOG_ERR, "newOpenptsUuidFromFile() - readOpenptsUuidFile() fail rc=%d\n", rc);
152         freeOpenptsUuid(uuid);
153         return NULL;
154     }
155
156     return uuid;
157 }
158
159 /**
160  * free OPENPTS_UUID
161  */
162 void freeOpenptsUuid(OPENPTS_UUID *uuid) {
163     /* check */
164     if (uuid == NULL) {
165         LOG(LOG_ERR, "null input\n");
166         return;
167     }
168
169     if (uuid->filename != NULL) {
170         xfree(uuid->filename);
171     }
172     if (uuid->uuid  != NULL) {
173         xfree(uuid->uuid);
174     }
175     if (uuid->str  != NULL) {
176         xfree(uuid->str);
177     }
178     if (uuid->time  != NULL) {
179         xfree(uuid->time);
180     }
181
182     xfree(uuid);
183 }
184
185 /**
186  * generate new UUID
187  *
188  * @retval PTS_SUCCESS
189  * @retval PTS_INTERNAL_ERROR
190  */
191 int genOpenptsUuid(OPENPTS_UUID *uuid) {
192     /* check */
193     if (uuid == NULL) {
194         LOG(LOG_ERR, "null input");
195         return PTS_FATAL;
196     }
197
198     /* check the status */
199     if (uuid->status == OPENPTS_UUID_EMPTY) {
200         // hold UUID only, no binding with the file
201         uuid->status = OPENPTS_UUID_UUID_ONLY;
202     } else if (uuid->status == OPENPTS_UUID_FILENAME_ONLY) {
203         // TODO Re genenation happen, before load the UUID from file
204         DEBUG("genOpenptsUuid() %s filled, before load the UUID from file\n", uuid->str);
205         uuid->status = OPENPTS_UUID_FILLED;
206     } else if (uuid->status == OPENPTS_UUID_FILLED) {
207         // TODO Re genenation happen
208         uuid->status = OPENPTS_UUID_CHANGED;
209         LOG(LOG_ERR, "genOpenptsUuid() %s - changed\n", uuid->str);
210     } else if (uuid->status == OPENPTS_UUID_CHANGED) {
211         // TODO Re genenation happen
212         uuid->status = OPENPTS_UUID_CHANGED;
213         LOG(LOG_ERR, "genOpenptsUuid() %s - changed again\n", uuid->str);
214     } else if (uuid->status == OPENPTS_UUID_UUID_ONLY) {
215         // TODO Re genenation happen
216         uuid->status = OPENPTS_UUID_UUID_ONLY;
217         LOG(LOG_ERR, "genOpenptsUuid() %s - changed again (no binding to the file)\n", uuid->str);
218     } else {
219         LOG(LOG_ERR, "genOpenptsUuid() - bad status\n");
220     }
221
222
223     /* free */
224     if (uuid->uuid != NULL) {
225         xfree(uuid->uuid);
226     }
227     if (uuid->str != NULL) {
228         xfree(uuid->str);
229     }
230     if (uuid->time != NULL) {
231         xfree(uuid->time);
232     }
233
234     /* set */
235     uuid->uuid = newUuid();
236     uuid->str  = getStringOfUuid(uuid->uuid);
237     uuid->time = getDateTimeOfUuid(uuid->uuid);
238     // TODO check
239
240     DEBUG("genOpenptsUuid() - %s\n", uuid->str);
241
242     return PTS_SUCCESS;
243 }
244
245 /**
246  * read UUID from file(uuid->filename), and fill OPENPTS_UUID
247  *
248  * @retval PTS_SUCCESS
249  * @retval PTS_INTERNAL_ERROR
250  */
251 int readOpenptsUuidFile(OPENPTS_UUID *uuid) {
252     int rc = PTS_SUCCESS;
253     FILE *fp;
254     char line[BUF_SIZE];
255     int i;
256
257     /* check */
258     if (uuid == NULL) {
259         LOG(LOG_ERR, "null input");
260         return PTS_FATAL;
261     }
262     if (uuid->filename == NULL) {
263         LOG(LOG_ERR, "null input");
264         return PTS_FATAL;
265     }
266
267     DEBUG("readOpenptsUuidFile()      : %s\n", uuid->filename);
268
269     // TODO check UUID status?
270     if (uuid->status == OPENPTS_UUID_FILENAME_ONLY) {
271         // OK
272     } else {
273         //  reload UUID from same? file
274         DEBUG("reload UUID, current UUID=%s, filename=%s\n",
275             uuid->str, uuid->filename);
276     }
277
278     /* free */
279     if (uuid->uuid != NULL) {
280         xfree(uuid->uuid);
281     }
282     if (uuid->str != NULL) {
283         xfree(uuid->str);
284     }
285     if (uuid->time != NULL) {
286         xfree(uuid->time);
287     }
288
289     /* open */
290     if ((fp = fopen(uuid->filename, "r")) == NULL) {
291         // DEBUG("readUuidFile - UUID File %s open was failed\n", filename);
292         /* we don't want double free errors - we may have already freed these up
293            above. this was a genuine issue that caused multiple pointers to
294            reference the same area of memory. */
295         uuid->uuid = NULL;
296         uuid->str  = NULL;
297         uuid->time = NULL;
298         return PTS_DENIED;  // TODO
299     }
300
301     /* init buf */
302     memset(line, 0, BUF_SIZE);
303
304     /* read */
305     if (fgets(line, BUF_SIZE, fp) != NULL) {
306         /* trim \n */
307         /* remove LR at the end otherwise getUuidFromString() go bad */
308         for (i = 0; i < BUF_SIZE; i++) {
309             if (line[i] == 0x0a) {
310                 /* hit */
311                 line[i] = 0;
312             }
313         }
314         /* parse */
315         uuid->uuid = getUuidFromString(line);
316         if (uuid->uuid  == NULL) {
317             LOG(LOG_ERR, "readUuidFile() - UUID is NULL, file %s\n", uuid->filename);
318             rc = PTS_INTERNAL_ERROR;
319             goto close;
320         }
321         uuid->str = getStringOfUuid(uuid->uuid);
322         if (uuid->str == NULL) {
323             LOG(LOG_ERR, "readUuidFile() - STR UUID is NULL, file %s\n", uuid->filename);
324             rc = PTS_INTERNAL_ERROR;
325             goto close;
326         }
327         uuid->time = getDateTimeOfUuid(uuid->uuid);
328         if (uuid->time == NULL) {
329             LOG(LOG_ERR, "readUuidFile() - TIME UUID is NULL, file %s\n", uuid->filename);
330             rc = PTS_INTERNAL_ERROR;
331             goto close;
332         }
333         uuid->status = OPENPTS_UUID_FILLED;
334     } else {
335         ERROR(NLS(MS_OPENPTS, OPENPTS_UUID_READ_FAILED, "Failed to read the UUID file\n"));
336     }
337
338  close:
339     fclose(fp);
340     return rc;
341 }
342
343 /**
344  *
345  * @retval PTS_SUCCESS
346  * @retval PTS_INTERNAL_ERROR
347  */
348 int writeOpenptsUuidFile(OPENPTS_UUID *uuid, int overwrite) {
349     FILE *fp;
350     int fd;
351     int mode = S_IRUSR | S_IWUSR | S_IRGRP;
352
353     /* check */
354     if (uuid == NULL) {
355         LOG(LOG_ERR, "null input");
356         return PTS_FATAL;
357     }
358     if (uuid->filename == NULL) {
359         LOG(LOG_ERR, "null input\n");
360         return PTS_FATAL;
361     }
362     if ((uuid->status != OPENPTS_UUID_FILLED) && (uuid->status != OPENPTS_UUID_CHANGED)) {
363         LOG(LOG_ERR, "writeOpenptsUuidFile() - uuid->status = %d (!= FILLED or CHANGED)\n", uuid->status);
364         // 1 => OPENPTS_UUID_FILENAME_ONLY, UUID is missing
365         return PTS_INTERNAL_ERROR;
366     }
367     if (uuid->str == NULL) {
368         LOG(LOG_ERR, "writeOpenptsUuidFile() - uuid->str == NULL\n");
369         return PTS_INTERNAL_ERROR;
370     }
371
372     /* open File */
373     if (overwrite == 1) {
374         /* overwrite */
375         if ((fp = fopen(uuid->filename, "w")) == NULL) {
376             ERROR(NLS(MS_OPENPTS, OPENPTS_UUID_FILE_OPEN_FAILED,
377                 "Failed to open UUID file %s\n"), uuid->filename);
378             return PTS_INTERNAL_ERROR;
379         }
380     } else {
381         /* new */
382         if ((fd = open(uuid->filename, O_CREAT | O_EXCL | O_WRONLY, mode)) == -1) {
383             if (errno == EEXIST) {
384                 /* exist, keep the current UUID file */
385                 ERROR(NLS(MS_OPENPTS, OPENPTS_UUID_FILE_EXISTS,
386                     "The UUID file '%s' already exists\n"), uuid->filename);
387                 // return PTS_SUCCESS;  // TODO
388                 return OPENPTS_FILE_EXISTS;
389             } else {
390                 ERROR(NLS(MS_OPENPTS, OPENPTS_UUID_FILE_OPEN_FAILED,
391                     "Failed to open UUID file %s\n"), uuid->filename);
392                 return PTS_INTERNAL_ERROR;
393             }
394         }
395         if ((fp = fdopen(fd, "w")) == NULL) {
396             ERROR(NLS(MS_OPENPTS, OPENPTS_UUID_FILE_OPEN_FAILED,
397                 "Failed to open UUID file %s\n"), uuid->filename);
398             return PTS_INTERNAL_ERROR;
399         }
400     }
401
402     /* write UUID */
403     fprintf(fp, "%s", uuid->str);
404
405     fclose(fp);  // this close fd also
406
407     DEBUG("writeOpenptsUuidFile() %s -> %s\n", uuid->str, uuid->filename);
408
409     return PTS_SUCCESS;
410 }