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