diff options
Diffstat (limited to 'eurephiadm')
-rw-r--r-- | eurephiadm/commands/users.c | 97 |
1 files changed, 91 insertions, 6 deletions
diff --git a/eurephiadm/commands/users.c b/eurephiadm/commands/users.c index d9d856d..c31834f 100644 --- a/eurephiadm/commands/users.c +++ b/eurephiadm/commands/users.c @@ -43,16 +43,20 @@ #include <eurephia_admin_struct.h> #include <eurephiadb_mapping.h> #include <eurephiadb_driver.h> +#include <certinfo.h> #include "../argparser.h" #include "../get_console_input.h" #include "../field_print.h" +#include "../parse_certificate_files.h" // Reuse code which is in certificats.c #define SHOWCERTS_FIREWALL 0x001 #define SHOWCERTS_DIGEST 0x002 void xmlPrint_certs(xmlXPathContext *certsXP, const char *xpath, int show_flags); +int register_certificate(eurephiaCTX *ctx, int depth, const char *digest, + const char *cname, const char *org, const char *email); void display_users_help(int page) { printf("\n%s -- Administer user accounts\n\n", MODULE); @@ -97,13 +101,14 @@ void display_users_help(int page) { printf("The add user mode registers a new user account.\n" "Both of the following arguments are required:\n\n" " -u | --username User name to use for the new account (required)\n" - " -P | --password Assign a new password via the command line\n\n" + " -P | --password Assign a new password via the command line.\n\n" "(not implemented yet) To register this new account against a certificate\n" "you can use the following arguments. These arguments cannot be used together.\n\n" - " -C | --certid Use already registered certificate, identified by certid\n" - " -D | --digest Use already registered certificate, identified by digest\n" + " -C | --certid Use already registered certificate, identified by certid.\n" + " -D | --digest Use already registered certificate, identified by digest.\n" " -c | --certfile Use the given certificate file and register it along with\n" - " the account\n\n"); + " the account.\n" + " -2 | --pkcs12 Certificate file is using the PKCS#12 format.\n\n"); break; case 'D': @@ -720,7 +725,7 @@ int add_user(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int a xmlDoc *user_xml = NULL; xmlNode *node = NULL, *node2 = NULL; struct stat cert_stat; - int i = 0, certid = 0, uid = 0; + int i = 0, certid = 0, uid = 0, certfile_format = CERTFILE_PEM; char *uname = NULL, *passwd = NULL, *certfile = NULL, *digest = NULL; e_options addu_args[] = { @@ -729,6 +734,7 @@ int add_user(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int a {"--certid", "-C", 1}, {"--certfile", "-c", 1}, {"--digest", "-d", 1}, + {"--pkcs12", "-2", 0}, {"--help", "-h", 0}, {NULL, NULL, 0} }; @@ -780,6 +786,10 @@ int add_user(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int a } break; + case '2': + certfile_format = CERTFILE_PKCS12; + break; + case 'd': if( strlen_nullsafe(optargs[0]) < 59 ) { fprintf(stderr, "%s: Certificate digest is too short\n", MODULE); @@ -861,8 +871,83 @@ int add_user(eurephiaCTX *ctx, eurephiaSESSION *sess, eurephiaVALUES *cfg, int a free_nullsafe(passwd); xmlFreeDoc(user_xml); - // FIXME: Register certificate info + if( (digest != NULL) || (certfile != NULL) ) { + if( digest != NULL ) { + xmlDoc *cert_xml = NULL, *certlist = NULL; + xmlNode *cert_n = NULL; + int certcount = 0; + + // when we have certificate digest, look that up + eurephiaXML_CreateDoc(ctx, 1, "certificate_info", &cert_xml, &cert_n); + cert_n = xmlNewChild(cert_n, NULL, (xmlChar *) "fieldMapping", NULL); + xmlNewProp(cert_n, (xmlChar *) "table", (xmlChar *) "certificates"); + xmlNewChild(cert_n, NULL, (xmlChar *) "digest", (xmlChar *) digest); + + certlist = eDBadminGetCertificateInfo(ctx, cert_xml, "certid"); + if( certlist == NULL ) { + fprintf(stderr, "%s: Error while looking up certificate info.\n" + "%s: User account is not associated with any certificates\n", + MODULE, MODULE); + xmlFreeDoc(cert_xml); + goto exit; + } + xmlFreeDoc(cert_xml); + cert_n = eurephiaXML_getRoot(ctx, certlist, "certificates", 1); + if( cert_n == NULL ) { + fprintf(stderr, "%s: Could not find certificates root node in XML document. " + "No association done.\n", MODULE); + xmlFreeDoc(certlist); + goto exit; + } + certcount = atoi_nullsafe(xmlGetAttrValue(cert_n->properties, "certficates")); + if( certcount == 0) { + fprintf(stderr, "%s: No certificates was found. No association is done.\n", + MODULE); + xmlFreeDoc(certlist); + goto exit; + } else if( certcount > 1 ) { + fprintf(stderr, "%s: More than one certificates was found. " + "No association is done.\n", MODULE); + xmlFreeDoc(certlist); + goto exit; + } + + // Get the first and only certificate node + cert_n = xmlFindNode(cert_n, "certificate"); + if( cert_n == NULL ) { + fprintf(stderr, "%s: Could not find certificate node in XML document. " + "No association done.\n", MODULE); + xmlFreeDoc(certlist); + goto exit; + } + // finally, we should have located the certid in the XML + certid = atoi_nullsafe(xmlGetAttrValue(cert_n->properties, "certid")); + xmlFreeDoc(certlist); + } else if( certfile != NULL ) { + // when we have certfile - register the certificate and register the link + certinfo *ci = NULL; + + ci = Cert_ParseFile(certfile, certfile_format); + if( ci == NULL ) { + fprintf(stderr, "%s: Could not parse the certificate file. " + "No association done.\n", MODULE); + goto exit; + } + + certid = register_certificate(ctx, 0, ci->digest, ci->common_name, ci->org, ci->email); + if( certid == 0 ) { + fprintf(stderr, "%s: Failed to register certificate file. No association done.", + MODULE); + } + } + } + + // If we have a certificate id, register a certificate link to the user account + if( certid > 0 ) { + // FIXME: Implement this feature when available in db driver API + } + exit: return (uid > 0); } |