]> git.ipfire.org Git - thirdparty/cups.git/blob - scheduler/cert.c
Mirror 1.1.x changes...
[thirdparty/cups.git] / scheduler / cert.c
1 /*
2 * "$Id: cert.c,v 1.7.2.9 2003/01/24 20:45:18 mike Exp $"
3 *
4 * Authentication certificate routines for the Common UNIX
5 * Printing System (CUPS).
6 *
7 * Copyright 1997-2003 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-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 */
53 int fd; /* Certificate file */
54 char filename[1024]; /* Certificate filename */
55 struct group *grp; /* System group */
56 static const char hex[] = "0123456789ABCDEF";
57 /* Hex constants... */
58
59
60 LogMessage(L_DEBUG2, "AddCert: adding certificate for pid %d", pid);
61
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;
74 strlcpy(cert->username, username, sizeof(cert->username));
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
84 snprintf(filename, sizeof(filename), "%s/certs/%d", ServerRoot, pid);
85 unlink(filename);
86
87 if ((fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0400)) < 0)
88 {
89 LogMessage(L_ERROR, "AddCert: 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
103 if ((grp = getgrnam(SystemGroups[0])) == NULL)
104 fchown(fd, getuid(), 0);
105 else
106 fchown(fd, getuid(), grp->gr_gid);
107
108 endgrent();
109
110 RootCertTime = time(NULL);
111 }
112 else
113 {
114 /*
115 * CGI certificate...
116 */
117
118 fchmod(fd, 0400);
119 fchown(fd, User, Group);
120 }
121
122 DEBUG_printf(("ADD pid=%d, username=%s, cert=%s\n", pid, username,
123 cert->certificate));
124
125 write(fd, cert->certificate, strlen(cert->certificate));
126 close(fd);
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
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
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
172 snprintf(filename, sizeof(filename), "%s/certs/%d", ServerRoot, pid);
173 if (unlink(filename))
174 LogMessage(L_ERROR, "DeleteCert: Unable to remove %s!\n", filename);
175
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
203 snprintf(filename, sizeof(filename), "%s/certs/%d", ServerRoot, cert->pid);
204 if (unlink(filename))
205 LogMessage(L_ERROR, "DeleteAllCerts: Unable to remove %s!\n", filename);
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
229 DEBUG_printf(("FindCert(certificate=%s)\n", certificate));
230 for (cert = Certs; cert != NULL; cert = cert->next)
231 if (strcasecmp(certificate, cert->certificate) == 0)
232 {
233 DEBUG_printf((" returning %s...\n", cert->username));
234 return (cert->username);
235 }
236
237 DEBUG_puts(" certificate not found!");
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 {
250 FILE *fp; /* /dev/random file */
251 unsigned seed; /* Seed for random number generator */
252 struct timeval tod; /* Time of day */
253
254
255 /*
256 * Initialize the random number generator using the random device or
257 * the current time, as available...
258 */
259
260 if ((fp = fopen("/dev/urandom", "rb")) == NULL)
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
277 seed = getc(fp);
278 seed = (seed << 8) | getc(fp);
279 seed = (seed << 8) | getc(fp);
280 seed = (seed << 8) | getc(fp);
281
282 fclose(fp);
283 }
284
285 srandom(seed);
286
287 /*
288 * Create a root certificate and return...
289 */
290
291 AddCert(0, "root");
292 }
293
294
295 /*
296 * End of "$Id: cert.c,v 1.7.2.9 2003/01/24 20:45:18 mike Exp $".
297 */