]> git.ipfire.org Git - thirdparty/cups.git/blame - scheduler/cert.c
Mirror 1.1.x changes.
[thirdparty/cups.git] / scheduler / cert.c
CommitLineData
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
47void
48AddCert(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
141void
142DeleteCert(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
185void
186DeleteAllCerts(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
223const char * /* O - Matching username or NULL */
224FindCert(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
247void
248InitCerts(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 */