/*************************************** $Header: /home/amb/CVS/wwwoffle/src/certinfo.c,v 1.13 2007-11-27 17:32:09 amb Exp $ WWWOFFLE - World Wide Web Offline Explorer - Version 2.9d. Generate information about the contents of the web pages that are cached in the system. ******************/ /****************** Written by Andrew M. Bishop This file Copyright 2002,03,04,05,06,07 Andrew M. Bishop It may be distributed under the GNU Public License, version 2, or any higher version. See section COPYING of the GNU Public license for conditions under which this file may be redistributed. ***************************************/ #include "autoconfig.h" #include #include #include #include #if HAVE_DIRENT_H # include #else # define dirent direct # if HAVE_SYS_NDIR_H # include # endif # if HAVE_SYS_DIR_H # include # endif # if HAVE_NDIR_H # include # endif #endif #include #include #if USE_GNUTLS #include #include #endif #include "wwwoffle.h" #include "errors.h" #include "io.h" #include "misc.h" #include "config.h" #include "certificates.h" /*+ Need this for Win32 to use binary mode +*/ #ifndef O_BINARY #define O_BINARY 0 #endif #if USE_GNUTLS /*+ The trusted root certificate authority certificates. +*/ extern gnutls_x509_crt_t *trusted_x509_crts; /*+ The number of trusted root certificate authority certificates. +*/ extern int n_trusted_x509_crts; static void CertificatesIndexPage(int fd); static void CertificatesRootPage(int fd,int download); static void CertificatesServerPage(int fd,URL *Url); static void CertificatesFakePage(int fd,URL *Url); static void CertificatesRealPage(int fd,URL *Url); static void CertificatesTrustedPage(int fd,URL *Url); static void load_display_certificate(int fd,char *certfile,char *type,char *name); static void display_certificate(int fd,gnutls_x509_crt_t crt); /*++++++++++++++++++++++++++++++++++++++ Display the certificates that are stored. int fd The file descriptor to write the output to. URL *Url The URL that was requested for the info. Header *request_head The header of the original request. ++++++++++++++++++++++++++++++++++++++*/ void CertificatesPage(int fd,URL *Url,/*@unused@*/ Header *request_head) { if(!strcmp(Url->path,"/certificates") || !strcmp(Url->path,"/certificates/")) CertificatesIndexPage(fd); else if(!strcmp(Url->path,"/certificates/root")) CertificatesRootPage(fd,0); else if(!strcmp(Url->path,"/certificates/root-cert.pem")) CertificatesRootPage(fd,1); else if(!strcmp(Url->path,"/certificates/server") && Url->args) CertificatesServerPage(fd,Url); else if(!strcmp(Url->path,"/certificates/fake") && Url->args) CertificatesFakePage(fd,Url); else if(!strcmp(Url->path,"/certificates/real") && Url->args) CertificatesRealPage(fd,Url); else if(!strcmp(Url->path,"/certificates/trusted") && Url->args) CertificatesTrustedPage(fd,Url); else HTMLMessage(fd,404,"WWWOFFLE Illegal Certificates Page",NULL,"CertIllegal", "url",Url->pathp, NULL); } /*++++++++++++++++++++++++++++++++++++++ Display the main certificates listing page. int fd The file descriptor to write the output to. ++++++++++++++++++++++++++++++++++++++*/ static void CertificatesIndexPage(int fd) { DIR *dir; struct dirent* ent; int i; HTMLMessageHead(fd,200,"WWWOFFLE Certificates Index", NULL); HTMLMessageBody(fd,"CertIndex-Head", NULL); HTMLMessageBody(fd,"CertIndex-Body", "type","root", "name","WWWOFFLE CA", NULL); /* Read in all of the certificates in the server directory. */ dir=opendir("certificates/server"); if(dir) { ent=readdir(dir); if(ent) { do { if(ent->d_name[0]=='.' && (ent->d_name[1]==0 || (ent->d_name[1]=='.' && ent->d_name[2]==0))) continue; /* skip . & .. */ if(strlen(ent->d_name)>9 && !strcmp(ent->d_name+strlen(ent->d_name)-9,"-cert.pem")) { char *server=(char*)malloc(strlen(ent->d_name)+1); strcpy(server,ent->d_name); server[strlen(ent->d_name)-9]=0; #if defined(__CYGWIN__) for(i=0;server[i];i++) if(server[i]=='!') server[i]=':'; #endif HTMLMessageBody(fd,"CertIndex-Body", "type","server", "name",server, NULL); free(server); } } while((ent=readdir(dir))); } closedir(dir); } /* Read in all of the certificates in the fake directory. */ dir=opendir("certificates/fake"); if(dir) { ent=readdir(dir); if(ent) { do { if(ent->d_name[0]=='.' && (ent->d_name[1]==0 || (ent->d_name[1]=='.' && ent->d_name[2]==0))) continue; /* skip . & .. */ if(strlen(ent->d_name)>9 && !strcmp(ent->d_name+strlen(ent->d_name)-9,"-cert.pem")) { char *fake=(char*)malloc(strlen(ent->d_name)+1); strcpy(fake,ent->d_name); fake[strlen(ent->d_name)-9]=0; #if defined(__CYGWIN__) for(i=0;fake[i];i++) if(fake[i]=='!') fake[i]=':'; #endif HTMLMessageBody(fd,"CertIndex-Body", "type","fake", "name",fake, NULL); free(fake); } } while((ent=readdir(dir))); } closedir(dir); } /* Read in all of the certificates in the real directory. */ dir=opendir("certificates/real"); if(dir) { ent=readdir(dir); if(ent) { do { if(ent->d_name[0]=='.' && (ent->d_name[1]==0 || (ent->d_name[1]=='.' && ent->d_name[2]==0))) continue; /* skip . & .. */ if(strlen(ent->d_name)>9 && !strcmp(ent->d_name+strlen(ent->d_name)-9,"-cert.pem")) { char *real=(char*)malloc(strlen(ent->d_name)+1); strcpy(real,ent->d_name); real[strlen(ent->d_name)-9]=0; #if defined(__CYGWIN__) for(i=0;real[i];i++) if(real[i]=='!') real[i]=':'; #endif HTMLMessageBody(fd,"CertIndex-Body", "type","real", "name",real, NULL); free(real); } } while((ent=readdir(dir))); } closedir(dir); } /* List all of the trusted certificates */ for(i=0;i0) write_data(fd,buffer,nbytes); close(cert_fd); } else load_display_certificate(fd,certfile,"root","root"); } /*++++++++++++++++++++++++++++++++++++++ Display the certificate for one of the WWWOFFLE server aliases. int fd The file descriptor to write the output to. URL *Url The exact URL given to reach this page, specifies the server certificate. ++++++++++++++++++++++++++++++++++++++*/ static void CertificatesServerPage(int fd,URL *Url) { char *name=Url->args; char *certfile=(char*)malloc(32+strlen(name)); #if defined(__CYGWIN__) int i; #endif sprintf(certfile,"certificates/server/%s-cert.pem",name); #if defined(__CYGWIN__) for(i=0;certfile[i];i++) if(certfile[i]==':') certfile[i]='!'; #endif load_display_certificate(fd,certfile,"server",name); free(certfile); } /*++++++++++++++++++++++++++++++++++++++ Display the fake certificate for one of the cached servers. int fd The file descriptor to write the output to. URL *Url The exact URL given to reach this page, specifies the fake certificate. ++++++++++++++++++++++++++++++++++++++*/ static void CertificatesFakePage(int fd,URL *Url) { char *name=Url->args; char *certfile=(char*)malloc(32+strlen(name)); #if defined(__CYGWIN__) int i; #endif sprintf(certfile,"certificates/fake/%s-cert.pem",name); #if defined(__CYGWIN__) for(i=0;certfile[i];i++) if(certfile[i]==':') certfile[i]='!'; #endif load_display_certificate(fd,certfile,"fake",name); free(certfile); } /*++++++++++++++++++++++++++++++++++++++ Display the real certificate for one of the cached pages. int fd The file descriptor to write the output to. URL *Url The exact URL given to reach this page, specifies the real certificate. ++++++++++++++++++++++++++++++++++++++*/ static void CertificatesRealPage(int fd,URL *Url) { gnutls_x509_crt_t *crt_list,trusted; int i=0; char *name=Url->args; char *certfile=(char*)malloc(32+strlen(name)); char dn[256]; sprintf(certfile,"certificates/real/%s-cert.pem",name); #if defined(__CYGWIN__) for(i=0;certfile[i];i++) if(certfile[i]==':') certfile[i]='!'; #endif crt_list=LoadCertificates(certfile); free(certfile); if(!crt_list || !crt_list[0]) { HTMLMessage(fd,500,"WWWOFFLE Certificate Page Error",NULL,"ServerError", "error","Cannot open specified certificate file", NULL); return; } HTMLMessageHead(fd,200,"WWWOFFLE Certificate Information", NULL); HTMLMessageBody(fd,"CertInfo-Head", "type","real", "name",name, NULL); while(crt_list[i]) { display_certificate(fd,crt_list[i]); gnutls_x509_crt_deinit(crt_list[i]); i++; } /* Check if certificate is trusted */ *dn=0; trusted=VerifyCertificates(name); if(trusted) { size_t size; size=sizeof(dn); gnutls_x509_crt_get_dn(trusted,dn,&size); } HTMLMessageBody(fd,"CertInfo-Tail", "trustedby",dn, NULL); } /*++++++++++++++++++++++++++++++++++++++ Display the certificate for one of the trusted certificate authorities. int fd The file descriptor to write the output to. URL *Url The exact URL given to reach this page, specifies the trusted certificate. ++++++++++++++++++++++++++++++++++++++*/ static void CertificatesTrustedPage(int fd,URL *Url) { int i; char *name=URLDecodeFormArgs(Url->args); for(i=0;i0) key_ca="Yes"; else if(err==0) key_ca="No"; else if(err==GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) key_ca="Unknown"; else key_ca="Error"; /* Formatted certificate */ gnutls_x509_crt_print(crt,GNUTLS_X509_CRT_FULL,&txt); /* Output the information. */ HTMLMessageBody(fd,"CertInfo-Body", "dn",dn, "issuer_dn",issuer_dn, "activation",activation_str, "expiration",expiration_str, "key_algo",key_algo, "key_usage",key_usage, "key_ca",key_ca, "info",txt.data, NULL); /* Tidy up and exit */ free(dn); free(issuer_dn); free(txt.data); } #endif /* USE_GNUTLS */ .