diff options
-rw-r--r-- | eurephiadm/commands/certificates.c | 154 |
1 files changed, 153 insertions, 1 deletions
diff --git a/eurephiadm/commands/certificates.c b/eurephiadm/commands/certificates.c index 8a73c11..3b87e28 100644 --- a/eurephiadm/commands/certificates.c +++ b/eurephiadm/commands/certificates.c @@ -22,6 +22,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <ctype.h> #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> @@ -72,8 +73,159 @@ int help_Certificates2(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES * return 0; } +int register_certificate(eurephiaCTX *ctx, int depth, const char *digest, + const char *cname, const char *org, const char *email) +{ + xmlDoc *cert_xml = NULL; + xmlNode *cert_n = NULL; + char tmp[66]; + int rc = 0; + + assert( ctx != NULL ); + + eurephiaXML_CreateDoc(ctx, 1, "register_certificate", &cert_xml, &cert_n); + assert( (cert_xml != NULL) || (cert_n != NULL) ); + + cert_n = xmlNewChild(cert_n, NULL, (xmlChar *) "fieldMapping", NULL); + xmlNewProp(cert_n, (xmlChar *) "table", (xmlChar *) "certificates"); + + memset(&tmp, 0, 66); + snprintf(tmp, 64, "%i", depth); + + xmlNewChild(cert_n, NULL, (xmlChar *) "depth", (xmlChar *) tmp); + xmlNewChild(cert_n, NULL, (xmlChar *) "digest", (xmlChar *) digest); + xmlNewChild(cert_n, NULL, (xmlChar *) "common_name", (xmlChar *) cname); + xmlNewChild(cert_n, NULL, (xmlChar *) "organisation", (xmlChar *) org); + xmlNewChild(cert_n, NULL, (xmlChar *) "email", (xmlChar *) email); + + // Register the certificate + xmlSaveFormatFileEnc("-", cert_xml, "UTF-8", 1); + rc = eDBadminAddCertificate(ctx, cert_xml); + fprintf(stdout, "%s: %s\n", MODULE, + (rc == 1 ? "Certificate registered successfully" : "Failed to register certificate")); + xmlFreeDoc(cert_xml); + + return (rc != 1); +} + int add_cert(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int argc, char **argv) { - return 1; + char *digest = NULL, *cname = NULL, *org = NULL, *email = NULL, *certfile = NULL; + int depth = -1, i = 0, j = 0, chk = 0, certfile_format = 0; + struct stat cert_stat; + + e_options addcertargs[] = { + {"--depth", "-d", 1}, + {"--digest", "-D", 1}, + {"--common-name", "-C", 1}, + {"--organisation", "-O", 1}, + {"--email", "-E", 1}, + {"--certfile", "-f", 1}, + {"--pkcs12", "-p", 0}, + {"--help", "-h", 0}, + {NULL, NULL, 0} + }; + + for( i = 1; i < argc ; i++ ) { + switch( eurephia_getopt(&i, argc, argv, addcertargs) ) { + case 'd': // Certificate depth + + // Check if argument is a number + chk = 1; + for( j = 0; j < strlen_nullsafe(optargs[0]); j++ ) { + if( !isdigit(optargs[0][j]) ) { + chk = 0; + break; + } + } + if( chk == 0 ) { + fprintf(stderr, "%s: Certificate depth must be a number\n", MODULE); + return 1; + } + + depth = atoi_nullsafe(optargs[0]); + if( (depth < 0) || (depth > 99) ) { + fprintf(stderr, "%s: Certificate depth must be between 0-99\n", MODULE); + return 1; + } + break; + + case 'D': // Certificate digest + digest = optargs[0]; + break; + case 'C': // Certificate - common_name / CN + cname = optargs[0]; + break; + case 'O': // Certificate - organisation / O + org = optargs[0]; + break; + case 'E': // Certificate - e-mail / emailAddr + email = optargs[0]; + break; + + case 'p': // Certfile is in PKCS#12 format + certfile_format = 1; + break; + + case 'f': // Load certificate info from a certificate file + if( strlen_nullsafe(optargs[0]) < 1 ) { + fprintf(stderr, "%s: certfile is too short\n", MODULE); + return 1; + } + certfile = optargs[0]; + + if( stat(certfile, &cert_stat) == -1 ) { + fprintf(stderr, "%s: Could not access certfile: %s (%s)\n", MODULE, + certfile, strerror(errno)); + return 1; + } + + if( cert_stat.st_size == 0 ) { + fprintf(stderr, "%s: certfile '%s' is empty\n", MODULE, certfile); + return 1; + } + + case 'h': + display_certs_help('A'); + break; + default: + return 2; + } + } + + // Sanity check of input parameters + if( (certfile != NULL) && ((depth>-1) || (digest!=NULL)|| (cname!=NULL) || (org!=NULL) || (email!=NULL)) ){ + fprintf(stderr, + "%s: You cannot combine --certfile with --depth, --common-name,\n" + "--organisation or --email\n", MODULE); + return 1; + } + + if( (certfile == NULL) && ((depth<0)||(digest==NULL)||(cname==NULL)||(org==NULL)||(email==NULL)) ) { + fprintf(stderr, + "%s: You must use either --certfile or --depth, --common-name,\n" + "--organisation and --email\n", MODULE); + return 1; + } + + if( strlen_nullsafe(digest) < 59 ) { + fprintf(stderr, "%s: Certificate digest is too short\n", MODULE); + return 1; + } + + // If we have a certfile - open it and fetch the info we want + if( certfile != NULL ) { + switch( certfile_format ) { + case 0: // PEM/DER format + break; + case 1: // PKCS#12 format + break; + default: // Unknown + fprintf(stderr, "%s: Unknown certificate file format\n", MODULE); + return 1; + } + } + + return register_certificate(ctx, depth, digest, cname, org, email); } |