1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker * Authentication certificate routines for the CUPS scheduler.
3*5e7646d2SAndroid Build Coastguard Worker *
4*5e7646d2SAndroid Build Coastguard Worker * Copyright 2007-2016 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker * Copyright 1997-2006 by Easy Software Products.
6*5e7646d2SAndroid Build Coastguard Worker *
7*5e7646d2SAndroid Build Coastguard Worker * Licensed under Apache License v2.0. See the file "LICENSE" for more information.
8*5e7646d2SAndroid Build Coastguard Worker */
9*5e7646d2SAndroid Build Coastguard Worker
10*5e7646d2SAndroid Build Coastguard Worker /*
11*5e7646d2SAndroid Build Coastguard Worker * Include necessary headers...
12*5e7646d2SAndroid Build Coastguard Worker */
13*5e7646d2SAndroid Build Coastguard Worker
14*5e7646d2SAndroid Build Coastguard Worker #include "cupsd.h"
15*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_ACL_INIT
16*5e7646d2SAndroid Build Coastguard Worker # include <sys/acl.h>
17*5e7646d2SAndroid Build Coastguard Worker # ifdef HAVE_MEMBERSHIP_H
18*5e7646d2SAndroid Build Coastguard Worker # include <membership.h>
19*5e7646d2SAndroid Build Coastguard Worker # endif /* HAVE_MEMBERSHIP_H */
20*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_ACL_INIT */
21*5e7646d2SAndroid Build Coastguard Worker
22*5e7646d2SAndroid Build Coastguard Worker
23*5e7646d2SAndroid Build Coastguard Worker /*
24*5e7646d2SAndroid Build Coastguard Worker * Local functions...
25*5e7646d2SAndroid Build Coastguard Worker */
26*5e7646d2SAndroid Build Coastguard Worker
27*5e7646d2SAndroid Build Coastguard Worker static int ctcompare(const char *a, const char *b);
28*5e7646d2SAndroid Build Coastguard Worker
29*5e7646d2SAndroid Build Coastguard Worker
30*5e7646d2SAndroid Build Coastguard Worker /*
31*5e7646d2SAndroid Build Coastguard Worker * 'cupsdAddCert()' - Add a certificate.
32*5e7646d2SAndroid Build Coastguard Worker */
33*5e7646d2SAndroid Build Coastguard Worker
34*5e7646d2SAndroid Build Coastguard Worker void
cupsdAddCert(int pid,const char * username,int type)35*5e7646d2SAndroid Build Coastguard Worker cupsdAddCert(int pid, /* I - Process ID */
36*5e7646d2SAndroid Build Coastguard Worker const char *username, /* I - Username */
37*5e7646d2SAndroid Build Coastguard Worker int type) /* I - AuthType for username */
38*5e7646d2SAndroid Build Coastguard Worker {
39*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
40*5e7646d2SAndroid Build Coastguard Worker cupsd_cert_t *cert; /* Current certificate */
41*5e7646d2SAndroid Build Coastguard Worker int fd; /* Certificate file */
42*5e7646d2SAndroid Build Coastguard Worker char filename[1024]; /* Certificate filename */
43*5e7646d2SAndroid Build Coastguard Worker static const char hex[] = "0123456789ABCDEF";
44*5e7646d2SAndroid Build Coastguard Worker /* Hex constants... */
45*5e7646d2SAndroid Build Coastguard Worker
46*5e7646d2SAndroid Build Coastguard Worker
47*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdAddCert: Adding certificate for PID %d", pid);
48*5e7646d2SAndroid Build Coastguard Worker
49*5e7646d2SAndroid Build Coastguard Worker /*
50*5e7646d2SAndroid Build Coastguard Worker * Allocate memory for the certificate...
51*5e7646d2SAndroid Build Coastguard Worker */
52*5e7646d2SAndroid Build Coastguard Worker
53*5e7646d2SAndroid Build Coastguard Worker if ((cert = calloc(sizeof(cupsd_cert_t), 1)) == NULL)
54*5e7646d2SAndroid Build Coastguard Worker return;
55*5e7646d2SAndroid Build Coastguard Worker
56*5e7646d2SAndroid Build Coastguard Worker /*
57*5e7646d2SAndroid Build Coastguard Worker * Fill in the certificate information...
58*5e7646d2SAndroid Build Coastguard Worker */
59*5e7646d2SAndroid Build Coastguard Worker
60*5e7646d2SAndroid Build Coastguard Worker cert->pid = pid;
61*5e7646d2SAndroid Build Coastguard Worker cert->type = type;
62*5e7646d2SAndroid Build Coastguard Worker strlcpy(cert->username, username, sizeof(cert->username));
63*5e7646d2SAndroid Build Coastguard Worker
64*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < 32; i ++)
65*5e7646d2SAndroid Build Coastguard Worker cert->certificate[i] = hex[CUPS_RAND() & 15];
66*5e7646d2SAndroid Build Coastguard Worker
67*5e7646d2SAndroid Build Coastguard Worker /*
68*5e7646d2SAndroid Build Coastguard Worker * Save the certificate to a file readable only by the User and Group
69*5e7646d2SAndroid Build Coastguard Worker * (or root and SystemGroup for PID == 0)...
70*5e7646d2SAndroid Build Coastguard Worker */
71*5e7646d2SAndroid Build Coastguard Worker
72*5e7646d2SAndroid Build Coastguard Worker snprintf(filename, sizeof(filename), "%s/certs/%d", StateDir, pid);
73*5e7646d2SAndroid Build Coastguard Worker unlink(filename);
74*5e7646d2SAndroid Build Coastguard Worker
75*5e7646d2SAndroid Build Coastguard Worker if ((fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0400)) < 0)
76*5e7646d2SAndroid Build Coastguard Worker {
77*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR,
78*5e7646d2SAndroid Build Coastguard Worker "Unable to create certificate file %s - %s",
79*5e7646d2SAndroid Build Coastguard Worker filename, strerror(errno));
80*5e7646d2SAndroid Build Coastguard Worker free(cert);
81*5e7646d2SAndroid Build Coastguard Worker return;
82*5e7646d2SAndroid Build Coastguard Worker }
83*5e7646d2SAndroid Build Coastguard Worker
84*5e7646d2SAndroid Build Coastguard Worker if (pid == 0)
85*5e7646d2SAndroid Build Coastguard Worker {
86*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_ACL_INIT
87*5e7646d2SAndroid Build Coastguard Worker acl_t acl; /* ACL information */
88*5e7646d2SAndroid Build Coastguard Worker acl_entry_t entry; /* ACL entry */
89*5e7646d2SAndroid Build Coastguard Worker acl_permset_t permset; /* Permissions */
90*5e7646d2SAndroid Build Coastguard Worker # ifdef HAVE_MBR_UID_TO_UUID
91*5e7646d2SAndroid Build Coastguard Worker uuid_t group; /* Group ID */
92*5e7646d2SAndroid Build Coastguard Worker # endif /* HAVE_MBR_UID_TO_UUID */
93*5e7646d2SAndroid Build Coastguard Worker static int acls_not_supported = 0;
94*5e7646d2SAndroid Build Coastguard Worker /* Only warn once */
95*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_ACL_INIT */
96*5e7646d2SAndroid Build Coastguard Worker
97*5e7646d2SAndroid Build Coastguard Worker
98*5e7646d2SAndroid Build Coastguard Worker /*
99*5e7646d2SAndroid Build Coastguard Worker * Root certificate...
100*5e7646d2SAndroid Build Coastguard Worker */
101*5e7646d2SAndroid Build Coastguard Worker
102*5e7646d2SAndroid Build Coastguard Worker fchmod(fd, 0440);
103*5e7646d2SAndroid Build Coastguard Worker fchown(fd, RunUser, SystemGroupIDs[0]);
104*5e7646d2SAndroid Build Coastguard Worker
105*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddCert: NumSystemGroups=%d", NumSystemGroups);
106*5e7646d2SAndroid Build Coastguard Worker
107*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_ACL_INIT
108*5e7646d2SAndroid Build Coastguard Worker if (NumSystemGroups > 1)
109*5e7646d2SAndroid Build Coastguard Worker {
110*5e7646d2SAndroid Build Coastguard Worker /*
111*5e7646d2SAndroid Build Coastguard Worker * Set POSIX ACLs for the root certificate so that all system
112*5e7646d2SAndroid Build Coastguard Worker * groups can access it...
113*5e7646d2SAndroid Build Coastguard Worker */
114*5e7646d2SAndroid Build Coastguard Worker
115*5e7646d2SAndroid Build Coastguard Worker int j; /* Looping var */
116*5e7646d2SAndroid Build Coastguard Worker
117*5e7646d2SAndroid Build Coastguard Worker # ifdef HAVE_MBR_UID_TO_UUID
118*5e7646d2SAndroid Build Coastguard Worker /*
119*5e7646d2SAndroid Build Coastguard Worker * On macOS, ACLs use UUIDs instead of GIDs...
120*5e7646d2SAndroid Build Coastguard Worker */
121*5e7646d2SAndroid Build Coastguard Worker
122*5e7646d2SAndroid Build Coastguard Worker acl = acl_init(NumSystemGroups - 1);
123*5e7646d2SAndroid Build Coastguard Worker
124*5e7646d2SAndroid Build Coastguard Worker for (i = 1; i < NumSystemGroups; i ++)
125*5e7646d2SAndroid Build Coastguard Worker {
126*5e7646d2SAndroid Build Coastguard Worker /*
127*5e7646d2SAndroid Build Coastguard Worker * Add each group ID to the ACL...
128*5e7646d2SAndroid Build Coastguard Worker */
129*5e7646d2SAndroid Build Coastguard Worker
130*5e7646d2SAndroid Build Coastguard Worker for (j = 0; j < i; j ++)
131*5e7646d2SAndroid Build Coastguard Worker if (SystemGroupIDs[j] == SystemGroupIDs[i])
132*5e7646d2SAndroid Build Coastguard Worker break;
133*5e7646d2SAndroid Build Coastguard Worker
134*5e7646d2SAndroid Build Coastguard Worker if (j < i)
135*5e7646d2SAndroid Build Coastguard Worker continue; /* Skip duplicate groups */
136*5e7646d2SAndroid Build Coastguard Worker
137*5e7646d2SAndroid Build Coastguard Worker acl_create_entry(&acl, &entry);
138*5e7646d2SAndroid Build Coastguard Worker acl_get_permset(entry, &permset);
139*5e7646d2SAndroid Build Coastguard Worker acl_add_perm(permset, ACL_READ_DATA);
140*5e7646d2SAndroid Build Coastguard Worker acl_set_tag_type(entry, ACL_EXTENDED_ALLOW);
141*5e7646d2SAndroid Build Coastguard Worker mbr_gid_to_uuid((gid_t)SystemGroupIDs[i], group);
142*5e7646d2SAndroid Build Coastguard Worker acl_set_qualifier(entry, &group);
143*5e7646d2SAndroid Build Coastguard Worker acl_set_permset(entry, permset);
144*5e7646d2SAndroid Build Coastguard Worker }
145*5e7646d2SAndroid Build Coastguard Worker
146*5e7646d2SAndroid Build Coastguard Worker # else
147*5e7646d2SAndroid Build Coastguard Worker /*
148*5e7646d2SAndroid Build Coastguard Worker * POSIX ACLs need permissions for owner, group, other, and mask
149*5e7646d2SAndroid Build Coastguard Worker * in addition to the rest of the system groups...
150*5e7646d2SAndroid Build Coastguard Worker */
151*5e7646d2SAndroid Build Coastguard Worker
152*5e7646d2SAndroid Build Coastguard Worker acl = acl_init(NumSystemGroups + 3);
153*5e7646d2SAndroid Build Coastguard Worker
154*5e7646d2SAndroid Build Coastguard Worker /* Owner */
155*5e7646d2SAndroid Build Coastguard Worker acl_create_entry(&acl, &entry);
156*5e7646d2SAndroid Build Coastguard Worker acl_get_permset(entry, &permset);
157*5e7646d2SAndroid Build Coastguard Worker acl_add_perm(permset, ACL_READ);
158*5e7646d2SAndroid Build Coastguard Worker acl_set_tag_type(entry, ACL_USER_OBJ);
159*5e7646d2SAndroid Build Coastguard Worker acl_set_permset(entry, permset);
160*5e7646d2SAndroid Build Coastguard Worker
161*5e7646d2SAndroid Build Coastguard Worker /* Group */
162*5e7646d2SAndroid Build Coastguard Worker acl_create_entry(&acl, &entry);
163*5e7646d2SAndroid Build Coastguard Worker acl_get_permset(entry, &permset);
164*5e7646d2SAndroid Build Coastguard Worker acl_add_perm(permset, ACL_READ);
165*5e7646d2SAndroid Build Coastguard Worker acl_set_tag_type(entry, ACL_GROUP_OBJ);
166*5e7646d2SAndroid Build Coastguard Worker acl_set_permset(entry, permset);
167*5e7646d2SAndroid Build Coastguard Worker
168*5e7646d2SAndroid Build Coastguard Worker /* Others */
169*5e7646d2SAndroid Build Coastguard Worker acl_create_entry(&acl, &entry);
170*5e7646d2SAndroid Build Coastguard Worker acl_get_permset(entry, &permset);
171*5e7646d2SAndroid Build Coastguard Worker acl_add_perm(permset, 0);
172*5e7646d2SAndroid Build Coastguard Worker acl_set_tag_type(entry, ACL_OTHER);
173*5e7646d2SAndroid Build Coastguard Worker acl_set_permset(entry, permset);
174*5e7646d2SAndroid Build Coastguard Worker
175*5e7646d2SAndroid Build Coastguard Worker /* Mask */
176*5e7646d2SAndroid Build Coastguard Worker acl_create_entry(&acl, &entry);
177*5e7646d2SAndroid Build Coastguard Worker acl_get_permset(entry, &permset);
178*5e7646d2SAndroid Build Coastguard Worker acl_add_perm(permset, ACL_READ);
179*5e7646d2SAndroid Build Coastguard Worker acl_set_tag_type(entry, ACL_MASK);
180*5e7646d2SAndroid Build Coastguard Worker acl_set_permset(entry, permset);
181*5e7646d2SAndroid Build Coastguard Worker
182*5e7646d2SAndroid Build Coastguard Worker for (i = 1; i < NumSystemGroups; i ++)
183*5e7646d2SAndroid Build Coastguard Worker {
184*5e7646d2SAndroid Build Coastguard Worker /*
185*5e7646d2SAndroid Build Coastguard Worker * Add each group ID to the ACL...
186*5e7646d2SAndroid Build Coastguard Worker */
187*5e7646d2SAndroid Build Coastguard Worker
188*5e7646d2SAndroid Build Coastguard Worker for (j = 0; j < i; j ++)
189*5e7646d2SAndroid Build Coastguard Worker if (SystemGroupIDs[j] == SystemGroupIDs[i])
190*5e7646d2SAndroid Build Coastguard Worker break;
191*5e7646d2SAndroid Build Coastguard Worker
192*5e7646d2SAndroid Build Coastguard Worker if (j < i)
193*5e7646d2SAndroid Build Coastguard Worker continue; /* Skip duplicate groups */
194*5e7646d2SAndroid Build Coastguard Worker
195*5e7646d2SAndroid Build Coastguard Worker acl_create_entry(&acl, &entry);
196*5e7646d2SAndroid Build Coastguard Worker acl_get_permset(entry, &permset);
197*5e7646d2SAndroid Build Coastguard Worker acl_add_perm(permset, ACL_READ);
198*5e7646d2SAndroid Build Coastguard Worker acl_set_tag_type(entry, ACL_GROUP);
199*5e7646d2SAndroid Build Coastguard Worker acl_set_qualifier(entry, SystemGroupIDs + i);
200*5e7646d2SAndroid Build Coastguard Worker acl_set_permset(entry, permset);
201*5e7646d2SAndroid Build Coastguard Worker }
202*5e7646d2SAndroid Build Coastguard Worker
203*5e7646d2SAndroid Build Coastguard Worker if (acl_valid(acl))
204*5e7646d2SAndroid Build Coastguard Worker {
205*5e7646d2SAndroid Build Coastguard Worker char *text, *textptr; /* Temporary string */
206*5e7646d2SAndroid Build Coastguard Worker
207*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR, "ACL did not validate: %s",
208*5e7646d2SAndroid Build Coastguard Worker strerror(errno));
209*5e7646d2SAndroid Build Coastguard Worker text = acl_to_text(acl, NULL);
210*5e7646d2SAndroid Build Coastguard Worker for (textptr = strchr(text, '\n');
211*5e7646d2SAndroid Build Coastguard Worker textptr;
212*5e7646d2SAndroid Build Coastguard Worker textptr = strchr(textptr + 1, '\n'))
213*5e7646d2SAndroid Build Coastguard Worker *textptr = ',';
214*5e7646d2SAndroid Build Coastguard Worker
215*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR, "ACL: %s", text);
216*5e7646d2SAndroid Build Coastguard Worker acl_free(text);
217*5e7646d2SAndroid Build Coastguard Worker }
218*5e7646d2SAndroid Build Coastguard Worker # endif /* HAVE_MBR_UID_TO_UUID */
219*5e7646d2SAndroid Build Coastguard Worker
220*5e7646d2SAndroid Build Coastguard Worker if (acl_set_fd(fd, acl))
221*5e7646d2SAndroid Build Coastguard Worker {
222*5e7646d2SAndroid Build Coastguard Worker if (errno != EOPNOTSUPP || !acls_not_supported)
223*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR,
224*5e7646d2SAndroid Build Coastguard Worker "Unable to set ACLs on root certificate \"%s\" - %s",
225*5e7646d2SAndroid Build Coastguard Worker filename, strerror(errno));
226*5e7646d2SAndroid Build Coastguard Worker
227*5e7646d2SAndroid Build Coastguard Worker if (errno == EOPNOTSUPP)
228*5e7646d2SAndroid Build Coastguard Worker acls_not_supported = 1;
229*5e7646d2SAndroid Build Coastguard Worker }
230*5e7646d2SAndroid Build Coastguard Worker
231*5e7646d2SAndroid Build Coastguard Worker acl_free(acl);
232*5e7646d2SAndroid Build Coastguard Worker }
233*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_ACL_INIT */
234*5e7646d2SAndroid Build Coastguard Worker
235*5e7646d2SAndroid Build Coastguard Worker RootCertTime = time(NULL);
236*5e7646d2SAndroid Build Coastguard Worker }
237*5e7646d2SAndroid Build Coastguard Worker else
238*5e7646d2SAndroid Build Coastguard Worker {
239*5e7646d2SAndroid Build Coastguard Worker /*
240*5e7646d2SAndroid Build Coastguard Worker * CGI certificate...
241*5e7646d2SAndroid Build Coastguard Worker */
242*5e7646d2SAndroid Build Coastguard Worker
243*5e7646d2SAndroid Build Coastguard Worker fchmod(fd, 0400);
244*5e7646d2SAndroid Build Coastguard Worker fchown(fd, User, Group);
245*5e7646d2SAndroid Build Coastguard Worker }
246*5e7646d2SAndroid Build Coastguard Worker
247*5e7646d2SAndroid Build Coastguard Worker write(fd, cert->certificate, strlen(cert->certificate));
248*5e7646d2SAndroid Build Coastguard Worker close(fd);
249*5e7646d2SAndroid Build Coastguard Worker
250*5e7646d2SAndroid Build Coastguard Worker /*
251*5e7646d2SAndroid Build Coastguard Worker * Insert the certificate at the front of the list...
252*5e7646d2SAndroid Build Coastguard Worker */
253*5e7646d2SAndroid Build Coastguard Worker
254*5e7646d2SAndroid Build Coastguard Worker cert->next = Certs;
255*5e7646d2SAndroid Build Coastguard Worker Certs = cert;
256*5e7646d2SAndroid Build Coastguard Worker }
257*5e7646d2SAndroid Build Coastguard Worker
258*5e7646d2SAndroid Build Coastguard Worker
259*5e7646d2SAndroid Build Coastguard Worker /*
260*5e7646d2SAndroid Build Coastguard Worker * 'cupsdDeleteCert()' - Delete a single certificate.
261*5e7646d2SAndroid Build Coastguard Worker */
262*5e7646d2SAndroid Build Coastguard Worker
263*5e7646d2SAndroid Build Coastguard Worker void
cupsdDeleteCert(int pid)264*5e7646d2SAndroid Build Coastguard Worker cupsdDeleteCert(int pid) /* I - Process ID */
265*5e7646d2SAndroid Build Coastguard Worker {
266*5e7646d2SAndroid Build Coastguard Worker cupsd_cert_t *cert, /* Current certificate */
267*5e7646d2SAndroid Build Coastguard Worker *prev; /* Previous certificate */
268*5e7646d2SAndroid Build Coastguard Worker char filename[1024]; /* Certificate file */
269*5e7646d2SAndroid Build Coastguard Worker
270*5e7646d2SAndroid Build Coastguard Worker
271*5e7646d2SAndroid Build Coastguard Worker for (prev = NULL, cert = Certs; cert != NULL; prev = cert, cert = cert->next)
272*5e7646d2SAndroid Build Coastguard Worker if (cert->pid == pid)
273*5e7646d2SAndroid Build Coastguard Worker {
274*5e7646d2SAndroid Build Coastguard Worker /*
275*5e7646d2SAndroid Build Coastguard Worker * Remove this certificate from the list...
276*5e7646d2SAndroid Build Coastguard Worker */
277*5e7646d2SAndroid Build Coastguard Worker
278*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdDeleteCert: Removing certificate for PID %d.", pid);
279*5e7646d2SAndroid Build Coastguard Worker
280*5e7646d2SAndroid Build Coastguard Worker if (prev == NULL)
281*5e7646d2SAndroid Build Coastguard Worker Certs = cert->next;
282*5e7646d2SAndroid Build Coastguard Worker else
283*5e7646d2SAndroid Build Coastguard Worker prev->next = cert->next;
284*5e7646d2SAndroid Build Coastguard Worker
285*5e7646d2SAndroid Build Coastguard Worker free(cert);
286*5e7646d2SAndroid Build Coastguard Worker
287*5e7646d2SAndroid Build Coastguard Worker /*
288*5e7646d2SAndroid Build Coastguard Worker * Delete the file and return...
289*5e7646d2SAndroid Build Coastguard Worker */
290*5e7646d2SAndroid Build Coastguard Worker
291*5e7646d2SAndroid Build Coastguard Worker snprintf(filename, sizeof(filename), "%s/certs/%d", StateDir, pid);
292*5e7646d2SAndroid Build Coastguard Worker if (unlink(filename))
293*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to remove %s!", filename);
294*5e7646d2SAndroid Build Coastguard Worker
295*5e7646d2SAndroid Build Coastguard Worker return;
296*5e7646d2SAndroid Build Coastguard Worker }
297*5e7646d2SAndroid Build Coastguard Worker }
298*5e7646d2SAndroid Build Coastguard Worker
299*5e7646d2SAndroid Build Coastguard Worker
300*5e7646d2SAndroid Build Coastguard Worker /*
301*5e7646d2SAndroid Build Coastguard Worker * 'cupsdDeleteAllCerts()' - Delete all certificates...
302*5e7646d2SAndroid Build Coastguard Worker */
303*5e7646d2SAndroid Build Coastguard Worker
304*5e7646d2SAndroid Build Coastguard Worker void
cupsdDeleteAllCerts(void)305*5e7646d2SAndroid Build Coastguard Worker cupsdDeleteAllCerts(void)
306*5e7646d2SAndroid Build Coastguard Worker {
307*5e7646d2SAndroid Build Coastguard Worker cupsd_cert_t *cert, /* Current certificate */
308*5e7646d2SAndroid Build Coastguard Worker *next; /* Next certificate */
309*5e7646d2SAndroid Build Coastguard Worker char filename[1024]; /* Certificate file */
310*5e7646d2SAndroid Build Coastguard Worker
311*5e7646d2SAndroid Build Coastguard Worker
312*5e7646d2SAndroid Build Coastguard Worker /*
313*5e7646d2SAndroid Build Coastguard Worker * Loop through each certificate, deleting them...
314*5e7646d2SAndroid Build Coastguard Worker */
315*5e7646d2SAndroid Build Coastguard Worker
316*5e7646d2SAndroid Build Coastguard Worker for (cert = Certs; cert != NULL; cert = next)
317*5e7646d2SAndroid Build Coastguard Worker {
318*5e7646d2SAndroid Build Coastguard Worker /*
319*5e7646d2SAndroid Build Coastguard Worker * Delete the file...
320*5e7646d2SAndroid Build Coastguard Worker */
321*5e7646d2SAndroid Build Coastguard Worker
322*5e7646d2SAndroid Build Coastguard Worker snprintf(filename, sizeof(filename), "%s/certs/%d", StateDir, cert->pid);
323*5e7646d2SAndroid Build Coastguard Worker if (unlink(filename))
324*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to remove %s!", filename);
325*5e7646d2SAndroid Build Coastguard Worker
326*5e7646d2SAndroid Build Coastguard Worker /*
327*5e7646d2SAndroid Build Coastguard Worker * Free memory...
328*5e7646d2SAndroid Build Coastguard Worker */
329*5e7646d2SAndroid Build Coastguard Worker
330*5e7646d2SAndroid Build Coastguard Worker next = cert->next;
331*5e7646d2SAndroid Build Coastguard Worker free(cert);
332*5e7646d2SAndroid Build Coastguard Worker }
333*5e7646d2SAndroid Build Coastguard Worker
334*5e7646d2SAndroid Build Coastguard Worker Certs = NULL;
335*5e7646d2SAndroid Build Coastguard Worker RootCertTime = 0;
336*5e7646d2SAndroid Build Coastguard Worker }
337*5e7646d2SAndroid Build Coastguard Worker
338*5e7646d2SAndroid Build Coastguard Worker
339*5e7646d2SAndroid Build Coastguard Worker /*
340*5e7646d2SAndroid Build Coastguard Worker * 'cupsdFindCert()' - Find a certificate.
341*5e7646d2SAndroid Build Coastguard Worker */
342*5e7646d2SAndroid Build Coastguard Worker
343*5e7646d2SAndroid Build Coastguard Worker cupsd_cert_t * /* O - Matching certificate or NULL */
cupsdFindCert(const char * certificate)344*5e7646d2SAndroid Build Coastguard Worker cupsdFindCert(const char *certificate) /* I - Certificate */
345*5e7646d2SAndroid Build Coastguard Worker {
346*5e7646d2SAndroid Build Coastguard Worker cupsd_cert_t *cert; /* Current certificate */
347*5e7646d2SAndroid Build Coastguard Worker
348*5e7646d2SAndroid Build Coastguard Worker
349*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindCert(certificate=%s)", certificate);
350*5e7646d2SAndroid Build Coastguard Worker for (cert = Certs; cert != NULL; cert = cert->next)
351*5e7646d2SAndroid Build Coastguard Worker if (!ctcompare(certificate, cert->certificate))
352*5e7646d2SAndroid Build Coastguard Worker {
353*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindCert: Returning \"%s\".", cert->username);
354*5e7646d2SAndroid Build Coastguard Worker return (cert);
355*5e7646d2SAndroid Build Coastguard Worker }
356*5e7646d2SAndroid Build Coastguard Worker
357*5e7646d2SAndroid Build Coastguard Worker cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdFindCert: Certificate not found.");
358*5e7646d2SAndroid Build Coastguard Worker
359*5e7646d2SAndroid Build Coastguard Worker return (NULL);
360*5e7646d2SAndroid Build Coastguard Worker }
361*5e7646d2SAndroid Build Coastguard Worker
362*5e7646d2SAndroid Build Coastguard Worker
363*5e7646d2SAndroid Build Coastguard Worker /*
364*5e7646d2SAndroid Build Coastguard Worker * 'cupsdInitCerts()' - Initialize the certificate "system" and root
365*5e7646d2SAndroid Build Coastguard Worker * certificate.
366*5e7646d2SAndroid Build Coastguard Worker */
367*5e7646d2SAndroid Build Coastguard Worker
368*5e7646d2SAndroid Build Coastguard Worker void
cupsdInitCerts(void)369*5e7646d2SAndroid Build Coastguard Worker cupsdInitCerts(void)
370*5e7646d2SAndroid Build Coastguard Worker {
371*5e7646d2SAndroid Build Coastguard Worker #ifndef HAVE_ARC4RANDOM
372*5e7646d2SAndroid Build Coastguard Worker cups_file_t *fp; /* /dev/random file */
373*5e7646d2SAndroid Build Coastguard Worker
374*5e7646d2SAndroid Build Coastguard Worker
375*5e7646d2SAndroid Build Coastguard Worker /*
376*5e7646d2SAndroid Build Coastguard Worker * Initialize the random number generator using the random device or
377*5e7646d2SAndroid Build Coastguard Worker * the current time, as available...
378*5e7646d2SAndroid Build Coastguard Worker */
379*5e7646d2SAndroid Build Coastguard Worker
380*5e7646d2SAndroid Build Coastguard Worker if ((fp = cupsFileOpen("/dev/urandom", "rb")) == NULL)
381*5e7646d2SAndroid Build Coastguard Worker {
382*5e7646d2SAndroid Build Coastguard Worker struct timeval tod; /* Time of day */
383*5e7646d2SAndroid Build Coastguard Worker
384*5e7646d2SAndroid Build Coastguard Worker /*
385*5e7646d2SAndroid Build Coastguard Worker * Get the time in usecs and use it as the initial seed...
386*5e7646d2SAndroid Build Coastguard Worker */
387*5e7646d2SAndroid Build Coastguard Worker
388*5e7646d2SAndroid Build Coastguard Worker gettimeofday(&tod, NULL);
389*5e7646d2SAndroid Build Coastguard Worker
390*5e7646d2SAndroid Build Coastguard Worker CUPS_SRAND((unsigned)(tod.tv_sec + tod.tv_usec));
391*5e7646d2SAndroid Build Coastguard Worker }
392*5e7646d2SAndroid Build Coastguard Worker else
393*5e7646d2SAndroid Build Coastguard Worker {
394*5e7646d2SAndroid Build Coastguard Worker unsigned seed; /* Seed for random number generator */
395*5e7646d2SAndroid Build Coastguard Worker
396*5e7646d2SAndroid Build Coastguard Worker /*
397*5e7646d2SAndroid Build Coastguard Worker * Read 4 random characters from the random device and use
398*5e7646d2SAndroid Build Coastguard Worker * them as the seed...
399*5e7646d2SAndroid Build Coastguard Worker */
400*5e7646d2SAndroid Build Coastguard Worker
401*5e7646d2SAndroid Build Coastguard Worker seed = (unsigned)cupsFileGetChar(fp);
402*5e7646d2SAndroid Build Coastguard Worker seed = (seed << 8) | (unsigned)cupsFileGetChar(fp);
403*5e7646d2SAndroid Build Coastguard Worker seed = (seed << 8) | (unsigned)cupsFileGetChar(fp);
404*5e7646d2SAndroid Build Coastguard Worker CUPS_SRAND((seed << 8) | (unsigned)cupsFileGetChar(fp));
405*5e7646d2SAndroid Build Coastguard Worker
406*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(fp);
407*5e7646d2SAndroid Build Coastguard Worker }
408*5e7646d2SAndroid Build Coastguard Worker #endif /* !HAVE_ARC4RANDOM */
409*5e7646d2SAndroid Build Coastguard Worker
410*5e7646d2SAndroid Build Coastguard Worker /*
411*5e7646d2SAndroid Build Coastguard Worker * Create a root certificate and return...
412*5e7646d2SAndroid Build Coastguard Worker */
413*5e7646d2SAndroid Build Coastguard Worker
414*5e7646d2SAndroid Build Coastguard Worker if (!RunUser)
415*5e7646d2SAndroid Build Coastguard Worker cupsdAddCert(0, "root", cupsdDefaultAuthType());
416*5e7646d2SAndroid Build Coastguard Worker }
417*5e7646d2SAndroid Build Coastguard Worker
418*5e7646d2SAndroid Build Coastguard Worker
419*5e7646d2SAndroid Build Coastguard Worker /*
420*5e7646d2SAndroid Build Coastguard Worker * 'ctcompare()' - Compare two strings in constant time.
421*5e7646d2SAndroid Build Coastguard Worker */
422*5e7646d2SAndroid Build Coastguard Worker
423*5e7646d2SAndroid Build Coastguard Worker static int /* O - 0 on match, non-zero on non-match */
ctcompare(const char * a,const char * b)424*5e7646d2SAndroid Build Coastguard Worker ctcompare(const char *a, /* I - First string */
425*5e7646d2SAndroid Build Coastguard Worker const char *b) /* I - Second string */
426*5e7646d2SAndroid Build Coastguard Worker {
427*5e7646d2SAndroid Build Coastguard Worker int result = 0; /* Result */
428*5e7646d2SAndroid Build Coastguard Worker
429*5e7646d2SAndroid Build Coastguard Worker
430*5e7646d2SAndroid Build Coastguard Worker while (*a && *b)
431*5e7646d2SAndroid Build Coastguard Worker {
432*5e7646d2SAndroid Build Coastguard Worker result |= *a ^ *b;
433*5e7646d2SAndroid Build Coastguard Worker a ++;
434*5e7646d2SAndroid Build Coastguard Worker b ++;
435*5e7646d2SAndroid Build Coastguard Worker }
436*5e7646d2SAndroid Build Coastguard Worker
437*5e7646d2SAndroid Build Coastguard Worker // either both *a and *b == '\0', or one points inside a string,
438*5e7646d2SAndroid Build Coastguard Worker // so factor that in.
439*5e7646d2SAndroid Build Coastguard Worker result |= (*a ^ *b);
440*5e7646d2SAndroid Build Coastguard Worker
441*5e7646d2SAndroid Build Coastguard Worker return (result);
442*5e7646d2SAndroid Build Coastguard Worker }
443