]>
Commit | Line | Data |
---|---|---|
a4ad3a11 | 1 | /* |
48033118 | 2 | * "$Id: cert.c,v 1.7.2.11 2004/04/20 13:40:30 mike Exp $" |
a4ad3a11 | 3 | * |
4 | * Authentication certificate routines for the Common UNIX | |
5 | * Printing System (CUPS). | |
6 | * | |
1d9595ab | 7 | * Copyright 1997-2003 by Easy Software Products. |
a4ad3a11 | 8 | * |
9 | * These coded instructions, statements, and computer programs are the | |
10 | * property of Easy Software Products and are protected by Federal | |
11 | * copyright law. Distribution and use rights are outlined in the file | |
12 | * "LICENSE.txt" which should have been included with this file. If this | |
13 | * file is missing or damaged please contact Easy Software Products | |
14 | * at: | |
15 | * | |
16 | * Attn: CUPS Licensing Information | |
17 | * Easy Software Products | |
18 | * 44141 Airport View Drive, Suite 204 | |
19 | * Hollywood, Maryland 20636-3111 USA | |
20 | * | |
21 | * Voice: (301) 373-9603 | |
22 | * EMail: cups-info@cups.org | |
23 | * WWW: http://www.cups.org | |
24 | * | |
25 | * Contents: | |
26 | * | |
27 | * AddCert() - Add a certificate. | |
28 | * DeleteCert() - Delete a single certificate. | |
29 | * DeleteAllCerts() - Delete all certificates... | |
30 | * FindCert() - Find a certificate. | |
31 | * InitCerts() - Initialize the certificate "system" and root | |
32 | * certificate. | |
33 | */ | |
34 | ||
35 | /* | |
36 | * Include necessary headers... | |
37 | */ | |
38 | ||
39 | #include "cupsd.h" | |
40 | #include <grp.h> | |
41 | ||
42 | ||
43 | /* | |
44 | * 'AddCert()' - Add a certificate. | |
45 | */ | |
46 | ||
47 | void | |
48 | AddCert(int pid, /* I - Process ID */ | |
49 | const char *username) /* I - Username */ | |
50 | { | |
51 | int i; /* Looping var */ | |
52 | cert_t *cert; /* Current certificate */ | |
901b295d | 53 | int fd; /* Certificate file */ |
a4ad3a11 | 54 | char filename[1024]; /* Certificate filename */ |
55 | struct group *grp; /* System group */ | |
6db7190f | 56 | static const char hex[] = "0123456789ABCDEF"; |
a4ad3a11 | 57 | /* Hex constants... */ |
58 | ||
59 | ||
434ddc80 | 60 | LogMessage(L_DEBUG2, "AddCert: adding certificate for pid %d", pid); |
61 | ||
a4ad3a11 | 62 | /* |
63 | * Allocate memory for the certificate... | |
64 | */ | |
65 | ||
66 | if ((cert = calloc(sizeof(cert_t), 1)) == NULL) | |
67 | return; | |
68 | ||
69 | /* | |
70 | * Fill in the certificate information... | |
71 | */ | |
72 | ||
73 | cert->pid = pid; | |
def978d5 | 74 | strlcpy(cert->username, username, sizeof(cert->username)); |
a4ad3a11 | 75 | |
76 | for (i = 0; i < 32; i ++) | |
77 | cert->certificate[i] = hex[random() & 15]; | |
78 | ||
79 | /* | |
80 | * Save the certificate to a file readable only by the User and Group | |
81 | * (or root and SystemGroup for PID == 0)... | |
82 | */ | |
83 | ||
a6988fb1 | 84 | snprintf(filename, sizeof(filename), "%s/certs/%d", ServerRoot, pid); |
901b295d | 85 | unlink(filename); |
a4ad3a11 | 86 | |
901b295d | 87 | if ((fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0400)) < 0) |
a4ad3a11 | 88 | { |
901b295d | 89 | LogMessage(L_ERROR, "AddCert: Unable to create certificate file %s - %s", |
90 | filename, strerror(errno)); | |
a4ad3a11 | 91 | free(cert); |
92 | return; | |
93 | } | |
94 | ||
95 | if (pid == 0) | |
96 | { | |
97 | /* | |
98 | * Root certificate... | |
99 | */ | |
100 | ||
901b295d | 101 | fchmod(fd, 0440); |
a4ad3a11 | 102 | |
753453e4 | 103 | if ((grp = getgrnam(SystemGroups[0])) == NULL) |
48033118 | 104 | fchown(fd, RunUser, 0); |
a4ad3a11 | 105 | else |
48033118 | 106 | fchown(fd, RunUser, grp->gr_gid); |
a4ad3a11 | 107 | |
108 | endgrent(); | |
109 | ||
110 | RootCertTime = time(NULL); | |
111 | } | |
112 | else | |
113 | { | |
114 | /* | |
115 | * CGI certificate... | |
116 | */ | |
117 | ||
901b295d | 118 | fchmod(fd, 0400); |
119 | fchown(fd, User, Group); | |
a4ad3a11 | 120 | } |
121 | ||
434ddc80 | 122 | DEBUG_printf(("ADD pid=%d, username=%s, cert=%s\n", pid, username, |
123 | cert->certificate)); | |
124 | ||
901b295d | 125 | write(fd, cert->certificate, strlen(cert->certificate)); |
126 | close(fd); | |
a4ad3a11 | 127 | |
128 | /* | |
129 | * Insert the certificate at the front of the list... | |
130 | */ | |
131 | ||
132 | cert->next = Certs; | |
133 | Certs = cert; | |
134 | } | |
135 | ||
136 | ||
137 | /* | |
138 | * 'DeleteCert()' - Delete a single certificate. | |
139 | */ | |
140 | ||
141 | void | |
142 | DeleteCert(int pid) /* I - Process ID */ | |
143 | { | |
144 | cert_t *cert, /* Current certificate */ | |
145 | *prev; /* Previous certificate */ | |
146 | char filename[1024]; /* Certificate file */ | |
147 | ||
148 | ||
149 | for (prev = NULL, cert = Certs; cert != NULL; prev = cert, cert = cert->next) | |
150 | if (cert->pid == pid) | |
151 | { | |
152 | /* | |
153 | * Remove this certificate from the list... | |
154 | */ | |
155 | ||
434ddc80 | 156 | LogMessage(L_DEBUG2, "DeleteCert: removing certificate for pid %d", pid); |
157 | ||
158 | DEBUG_printf(("DELETE pid=%d, username=%s, cert=%s\n", cert->pid, | |
159 | cert->username, cert->certificate)); | |
160 | ||
a4ad3a11 | 161 | if (prev == NULL) |
162 | Certs = cert->next; | |
163 | else | |
164 | prev->next = cert->next; | |
165 | ||
166 | free(cert); | |
167 | ||
168 | /* | |
169 | * Delete the file and return... | |
170 | */ | |
171 | ||
a6988fb1 | 172 | snprintf(filename, sizeof(filename), "%s/certs/%d", ServerRoot, pid); |
901b295d | 173 | if (unlink(filename)) |
174 | LogMessage(L_ERROR, "DeleteCert: Unable to remove %s!\n", filename); | |
c3c5af5e | 175 | |
a4ad3a11 | 176 | return; |
177 | } | |
178 | } | |
179 | ||
180 | ||
181 | /* | |
182 | * 'DeleteAllCerts()' - Delete all certificates... | |
183 | */ | |
184 | ||
185 | void | |
186 | DeleteAllCerts(void) | |
187 | { | |
188 | cert_t *cert, /* Current certificate */ | |
189 | *next; /* Next certificate */ | |
190 | char filename[1024]; /* Certificate file */ | |
191 | ||
192 | ||
193 | /* | |
194 | * Loop through each certificate, deleting them... | |
195 | */ | |
196 | ||
197 | for (cert = Certs; cert != NULL; cert = next) | |
198 | { | |
199 | /* | |
200 | * Delete the file... | |
201 | */ | |
202 | ||
a6988fb1 | 203 | snprintf(filename, sizeof(filename), "%s/certs/%d", ServerRoot, cert->pid); |
901b295d | 204 | if (unlink(filename)) |
205 | LogMessage(L_ERROR, "DeleteAllCerts: Unable to remove %s!\n", filename); | |
a4ad3a11 | 206 | |
207 | /* | |
208 | * Free memory... | |
209 | */ | |
210 | ||
211 | next = cert->next; | |
212 | free(cert); | |
213 | } | |
214 | ||
215 | Certs = NULL; | |
216 | } | |
217 | ||
218 | ||
219 | /* | |
220 | * 'FindCert()' - Find a certificate. | |
221 | */ | |
222 | ||
223 | const char * /* O - Matching username or NULL */ | |
224 | FindCert(const char *certificate) /* I - Certificate */ | |
225 | { | |
226 | cert_t *cert; /* Current certificate */ | |
227 | ||
228 | ||
434ddc80 | 229 | DEBUG_printf(("FindCert(certificate=%s)\n", certificate)); |
a4ad3a11 | 230 | for (cert = Certs; cert != NULL; cert = cert->next) |
231 | if (strcasecmp(certificate, cert->certificate) == 0) | |
434ddc80 | 232 | { |
233 | DEBUG_printf((" returning %s...\n", cert->username)); | |
a4ad3a11 | 234 | return (cert->username); |
434ddc80 | 235 | } |
236 | ||
237 | DEBUG_puts(" certificate not found!"); | |
a4ad3a11 | 238 | |
239 | return (NULL); | |
240 | } | |
241 | ||
242 | ||
243 | /* | |
244 | * 'InitCerts()' - Initialize the certificate "system" and root certificate. | |
245 | */ | |
246 | ||
247 | void | |
248 | InitCerts(void) | |
249 | { | |
7b0fde61 | 250 | cups_file_t *fp; /* /dev/random file */ |
9ddb6565 | 251 | unsigned seed; /* Seed for random number generator */ |
502b2e4a | 252 | struct timeval tod; /* Time of day */ |
253 | ||
254 | ||
255 | /* | |
9ddb6565 | 256 | * Initialize the random number generator using the random device or |
257 | * the current time, as available... | |
502b2e4a | 258 | */ |
259 | ||
7b0fde61 | 260 | if ((fp = cupsFileOpen("/dev/urandom", "rb")) == NULL) |
9ddb6565 | 261 | { |
262 | /* | |
263 | * Get the time in usecs and use it as the initial seed... | |
264 | */ | |
265 | ||
266 | gettimeofday(&tod, NULL); | |
267 | ||
268 | seed = (unsigned)(tod.tv_sec + tod.tv_usec); | |
269 | } | |
270 | else | |
271 | { | |
272 | /* | |
273 | * Read 4 random characters from the random device and use | |
274 | * them as the seed... | |
275 | */ | |
276 | ||
7b0fde61 | 277 | seed = cupsFileGetChar(fp); |
278 | seed = (seed << 8) | cupsFileGetChar(fp); | |
279 | seed = (seed << 8) | cupsFileGetChar(fp); | |
280 | seed = (seed << 8) | cupsFileGetChar(fp); | |
9ddb6565 | 281 | |
7b0fde61 | 282 | cupsFileClose(fp); |
9ddb6565 | 283 | } |
502b2e4a | 284 | |
9ddb6565 | 285 | srandom(seed); |
502b2e4a | 286 | |
a4ad3a11 | 287 | /* |
288 | * Create a root certificate and return... | |
289 | */ | |
290 | ||
291 | AddCert(0, "root"); | |
292 | } | |
293 | ||
294 | ||
295 | /* | |
48033118 | 296 | * End of "$Id: cert.c,v 1.7.2.11 2004/04/20 13:40:30 mike Exp $". |
a4ad3a11 | 297 | */ |