/* * "$Id: cert.c,v 1.1.1.3 2002/06/06 22:13:14 jlovell Exp $" * * Authentication certificate routines for the Common UNIX * Printing System (CUPS). * * Copyright 1997-2002 by Easy Software Products. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal * copyright law. Distribution and use rights are outlined in the file * "LICENSE.txt" which should have been included with this file. If this * file is missing or damaged please contact Easy Software Products * at: * * Attn: CUPS Licensing Information * Easy Software Products * 44141 Airport View Drive, Suite 204 * Hollywood, Maryland 20636-3111 USA * * Voice: (301) 373-9603 * EMail: cups-info@cups.org * WWW: http://www.cups.org * * Contents: * * AddCert() - Add a certificate. * DeleteCert() - Delete a single certificate. * DeleteAllCerts() - Delete all certificates... * FindCert() - Find a certificate. * InitCerts() - Initialize the certificate "system" and root * certificate. */ /* * Include necessary headers... */ #include "cupsd.h" #include <grp.h> /* * 'AddCert()' - Add a certificate. */ void AddCert(int pid, /* I - Process ID */ const char *username) /* I - Username */ { int i; /* Looping var */ cert_t *cert; /* Current certificate */ FILE *fp; /* Certificate file */ char filename[1024]; /* Certificate filename */ struct group *grp; /* System group */ static const char *hex = "0123456789ABCDEF"; /* Hex constants... */ /* * Allocate memory for the certificate... */ if ((cert = calloc(sizeof(cert_t), 1)) == NULL) return; /* * Fill in the certificate information... */ cert->pid = pid; strlcpy(cert->username, username, sizeof(cert->username)); for (i = 0; i < 32; i ++) cert->certificate[i] = hex[random() & 15]; /* * Save the certificate to a file readable only by the User and Group * (or root and SystemGroup for PID == 0)... */ snprintf(filename, sizeof(filename), "%s/certs/%d", ServerRoot, pid); if ((fp = fopen(filename, "w")) == NULL) { free(cert); return; } if (pid == 0) { /* * Root certificate... */ fchmod(fileno(fp), 0440); if ((grp = getgrnam(SystemGroups[0])) == NULL) fchown(fileno(fp), getuid(), 0); else fchown(fileno(fp), getuid(), grp->gr_gid); endgrent(); RootCertTime = time(NULL); } else { /* * CGI certificate... */ fchmod(fileno(fp), 0400); fchown(fileno(fp), User, Group); } fputs(cert->certificate, fp); fclose(fp); /* * Insert the certificate at the front of the list... */ cert->next = Certs; Certs = cert; } /* * 'DeleteCert()' - Delete a single certificate. */ void DeleteCert(int pid) /* I - Process ID */ { cert_t *cert, /* Current certificate */ *prev; /* Previous certificate */ char filename[1024]; /* Certificate file */ for (prev = NULL, cert = Certs; cert != NULL; prev = cert, cert = cert->next) if (cert->pid == pid) { /* * Remove this certificate from the list... */ if (prev == NULL) Certs = cert->next; else prev->next = cert->next; free(cert); /* * Delete the file and return... */ snprintf(filename, sizeof(filename), "%s/certs/%d", ServerRoot, pid); unlink(filename); return; } } /* * 'DeleteAllCerts()' - Delete all certificates... */ void DeleteAllCerts(void) { cert_t *cert, /* Current certificate */ *next; /* Next certificate */ char filename[1024]; /* Certificate file */ /* * Loop through each certificate, deleting them... */ for (cert = Certs; cert != NULL; cert = next) { /* * Delete the file... */ snprintf(filename, sizeof(filename), "%s/certs/%d", ServerRoot, cert->pid); unlink(filename); /* * Free memory... */ next = cert->next; free(cert); } Certs = NULL; } /* * 'FindCert()' - Find a certificate. */ const char * /* O - Matching username or NULL */ FindCert(const char *certificate) /* I - Certificate */ { cert_t *cert; /* Current certificate */ for (cert = Certs; cert != NULL; cert = cert->next) if (strcasecmp(certificate, cert->certificate) == 0) return (cert->username); return (NULL); } /* * 'InitCerts()' - Initialize the certificate "system" and root certificate. */ void InitCerts(void) { FILE *fp; /* /dev/random file */ unsigned seed; /* Seed for random number generator */ struct timeval tod; /* Time of day */ /* * Initialize the random number generator using the random device or * the current time, as available... */ if ((fp = fopen("/dev/urandom", "rb")) == NULL) { /* * Get the time in usecs and use it as the initial seed... */ gettimeofday(&tod, NULL); seed = (unsigned)(tod.tv_sec + tod.tv_usec); } else { /* * Read 4 random characters from the random device and use * them as the seed... */ seed = getc(fp); seed = (seed << 8) | getc(fp); seed = (seed << 8) | getc(fp); seed = (seed << 8) | getc(fp); fclose(fp); } srandom(seed); /* * Create a root certificate and return... */ AddCert(0, "root"); } /* * End of "$Id: cert.c,v 1.1.1.3 2002/06/06 22:13:14 jlovell Exp $". */