xref: /aosp_15_r20/external/libcups/scheduler/cert.c (revision 5e7646d21f1134fb0638875d812ef646c12ab91e)
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