certificates.c

Go to the documentation of this file.
00001 /* certificates.c  --  Certificate management
00002  *
00003  *  GPLv2 only - Copyright (C) 2008 - 2010
00004  *               David Sommerseth <dazo@users.sourceforge.net>
00005  *
00006  *  This program is free software; you can redistribute it and/or
00007  *  modify it under the terms of the GNU General Public License
00008  *  as published by the Free Software Foundation; version 2
00009  *  of the License.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00019  *
00020  */
00021 
00031 #include <string.h>
00032 #include <unistd.h>
00033 #include <assert.h>
00034 
00035 #include <libxml/tree.h>
00036 
00037 #include <sqlite3.h>
00038 
00039 #include <eurephia_nullsafe.h>
00040 #include <eurephia_context.h>
00041 #include <eurephia_log.h>
00042 #include <eurephia_xml.h>
00043 #include <eurephia_values.h>
00044 #include <eurephiadb_session_struct.h>
00045 #include <eurephiadb_mapping.h>
00046 #include <passwd.h>
00047 
00048 #ifndef DRIVER_MODE
00049 #define DRIVER_MODE
00050 #endif
00051 #include <eurephiadb_driver.h>
00052 
00053 #include "../sqlite.h"
00054 
00055 #define FMAP_CERTS              
00056 #include "../fieldmapping.h"
00057 
00058 
00069 static xmlDoc *certificate_list(eurephiaCTX *ctx, eDBfieldMap *srch_map, const char *sortkeys) {
00070         xmlDoc *certlist = NULL;
00071         xmlNode *cert_n = NULL, *tmp_n = NULL;
00072         eDBfieldMap *ptr = NULL;
00073         dbresult *res = NULL;
00074         xmlChar tmp[2050];
00075         int i;
00076 
00077         DEBUG(ctx, 21, "Function call: certificates_list(ctx, fieldMap, '%s')", sortkeys);
00078         assert( (ctx != NULL) && (srch_map != NULL) );
00079 
00080         // Replace spaces with underscore in common name and
00081         // in organisation fields, to comply with OpenVPN standards
00082         for( ptr = srch_map; ptr != NULL; ptr = ptr->next ) {
00083                 if( ptr->field_id & (FIELD_CNAME | FIELD_ORG) ) {
00084                         xmlReplaceChars((xmlChar *) ptr->value, ' ', '_');
00085                 }
00086         }
00087 
00088         res = sqlite_query_mapped(ctx, SQL_SELECT,
00089                                   "SELECT depth, lower(digest), common_name, organisation, email, "
00090                                   "       registered, certid"
00091                                   "  FROM openvpn_certificates", NULL, srch_map, sortkeys);
00092         if( res == NULL ) {
00093                 eurephia_log(ctx, LOG_ERROR, 0, "Could not query the certificate table");
00094                 return eurephiaXML_ResultMsg(ctx, exmlERROR, NULL,
00095                                              "Could not query the database for certificate info");
00096         }
00097 
00098         memset(&tmp, 0, 2050);
00099         eurephiaXML_CreateDoc(ctx, 1, "certificates", &certlist, &cert_n);
00100         xmlStrPrintf(tmp, 64, (xmlChar *) "%i", sqlite_get_numtuples(res));
00101         xmlNewProp(cert_n, (xmlChar *) "certificates", (xmlChar *) tmp);
00102 
00103         for( i = 0; i < sqlite_get_numtuples(res); i++ ) {
00104                 tmp_n = xmlNewChild(cert_n, NULL, (xmlChar *) "certificate", NULL);
00105 
00106                 sqlite_xml_value(tmp_n, XML_ATTR, "certid", res, i, 6);
00107                 sqlite_xml_value(tmp_n, XML_ATTR, "depth", res, i, 0);
00108                 sqlite_xml_value(tmp_n, XML_ATTR, "registered", res, i, 5);
00109                 sqlite_xml_value(tmp_n, XML_NODE, "digest", res, i, 1);
00110 
00111                 xmlStrPrintf(tmp, 2048, (xmlChar *) "%.2048s", sqlite_get_value(res, i, 2));
00112                 xmlReplaceChars(tmp, '_', ' ');
00113                 xmlNewChild(tmp_n, NULL, (xmlChar *) "common_name", tmp);
00114 
00115                 xmlStrPrintf(tmp, 2048, (xmlChar *) "%.2048s", sqlite_get_value(res, i, 3));
00116                 xmlReplaceChars(tmp, '_', ' ');
00117                 xmlNewChild(tmp_n, NULL, (xmlChar *) "organisation", tmp);
00118 
00119                 sqlite_xml_value(tmp_n, XML_NODE, "email", res, i, 4);
00120         }
00121         sqlite_free_results(res);
00122 
00123         return certlist;
00124 }
00125 
00126 
00136 static xmlDoc *certificate_add(eurephiaCTX *ctx, eDBfieldMap *crtinf_map) {
00137         xmlDoc *res_d = NULL;
00138         xmlNode *info_n = NULL;
00139         eDBfieldMap *ptr = NULL;
00140         dbresult *res = NULL;
00141 
00142         DEBUG(ctx, 21, "Function call: certificate_add(ctx, xmlDoc)");
00143         assert( (ctx != NULL) && (crtinf_map != NULL) );
00144 
00145         if( (ctx->context_type != ECTX_ADMIN_CONSOLE) && (ctx->context_type != ECTX_ADMIN_WEB) ) {
00146                 eurephia_log(ctx, LOG_CRITICAL, 0,
00147                              "eurephia admin function call attempted with wrong context type");
00148                 return NULL;
00149         }
00150 
00151         // Replace spaces with underscore in common name and
00152         // in organisation fields, to comply with OpenVPN standards
00153         for( ptr = crtinf_map; ptr != NULL; ptr = ptr->next ) {
00154                 if( ptr->field_id & (FIELD_CNAME | FIELD_ORG) ) {
00155                         xmlReplaceChars((xmlChar *) ptr->value, ' ', '_');
00156                 }
00157         }
00158 
00159         // Register the certificate
00160         res = sqlite_query_mapped(ctx, SQL_INSERT, "INSERT INTO openvpn_certificates",
00161                                   crtinf_map, NULL, NULL);
00162         if( res == NULL ) {
00163                 eurephia_log(ctx, LOG_FATAL, 0, "Could not register the certificate");
00164                 res_d = eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Could not register the certificate");
00165         } else {
00166                 xmlChar *certid = malloc_nullsafe(ctx, 34);
00167                 assert( certid != NULL );
00168 
00169                 // Prepare an information tag/node with the certid value
00170                 xmlStrPrintf(certid, 32, (xmlChar *) "%ld", res->last_insert_id);
00171                 info_n = xmlNewNode(NULL, (xmlChar *)"certificate");
00172                 xmlNewProp(info_n, (xmlChar *) "certid", certid);
00173 
00174                 res_d = eurephiaXML_ResultMsg(ctx, exmlRESULT, info_n,
00175                                               "Certificate registered (certid %ld)", res->last_insert_id);
00176                 xmlFreeNode(info_n);
00177         }
00178         sqlite_free_results(res);
00179 
00180         return res_d;
00181 }
00182 
00183 
00193 static xmlDoc *certificate_delete(eurephiaCTX *ctx, eDBfieldMap *crtinf_map) {
00194         xmlDoc *res_d = NULL;
00195         eDBfieldMap *ptr = NULL;
00196         dbresult *res = NULL;
00197 
00198         DEBUG(ctx, 21, "Function call: certificate_delete(ctx, xmlDoc)");
00199         assert( (ctx != NULL) && (crtinf_map != NULL) );
00200 
00201         if( (ctx->context_type != ECTX_ADMIN_CONSOLE) && (ctx->context_type != ECTX_ADMIN_WEB) ) {
00202                 eurephia_log(ctx, LOG_CRITICAL, 0,
00203                              "eurephia admin function call attempted with wrong context type");
00204                 return NULL;
00205         }
00206 
00207         // Replace spaces with underscore in common name and
00208         // in organisation fields, to comply with OpenVPN standards
00209         for( ptr = crtinf_map; ptr != NULL; ptr = ptr->next ) {
00210                 if( ptr->field_id & (FIELD_CNAME | FIELD_ORG) ) {
00211                         xmlReplaceChars((xmlChar *) ptr->value, ' ', '_');
00212                 }
00213         }
00214 
00215         // Register the certificate
00216         res = sqlite_query_mapped(ctx, SQL_DELETE, "DELETE FROM openvpn_certificates",
00217                                   NULL, crtinf_map, NULL);
00218         if( res == NULL ) {
00219                 eurephia_log(ctx, LOG_FATAL, 0, "Could not complete the delete certificate request");
00220                 res_d = eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Could not delete the certificate(s)");
00221         } else {
00222                 res_d = eurephiaXML_ResultMsg(ctx, exmlRESULT, NULL, "%i %s deleted",
00223                                               sqlite_get_affected_rows(res),
00224                                               (sqlite_get_affected_rows(res) != 1
00225                                                ? "certificates":"certificate")
00226                                               );
00227         }
00228         sqlite_free_results(res);
00229 
00230         return res_d;
00231 }
00232 
00236 xmlDoc *eDBadminCertificate(eurephiaCTX *ctx, xmlDoc *qryxml) {
00237         eDBfieldMap *fmap = NULL;
00238         char *mode = NULL;
00239         xmlDoc *resxml = NULL;
00240         xmlNode *root_n = NULL, *fieldmap_n = NULL;
00241 
00242         DEBUG(ctx, 20, "Function call: eDBadminCertificate(ctx, {xmlDoc})");
00243         assert( (ctx != NULL) && (qryxml != NULL) );
00244 
00245         if( (ctx->context_type != ECTX_ADMIN_CONSOLE) && (ctx->context_type != ECTX_ADMIN_WEB) ) {
00246                 eurephia_log(ctx, LOG_CRITICAL, 0,
00247                              "eurephia admin function call attempted with wrong context type");
00248                 return NULL;
00249         }
00250 
00251         root_n = eurephiaXML_getRoot(ctx, qryxml, "certificates", 1);
00252         if( root_n == NULL ) {
00253                 eurephia_log(ctx, LOG_CRITICAL, 0, "Invalid XML input.");
00254                 return NULL;
00255         }
00256         mode = xmlGetAttrValue(root_n->properties, "mode");
00257         if( mode == NULL ) {
00258                 eurephia_log(ctx, LOG_ERROR, 0, "Missing mode attribute");
00259                 return NULL;
00260         }
00261 
00262         fieldmap_n = xmlFindNode(root_n, "fieldMapping");
00263         if( fieldmap_n == NULL ) {
00264                 eurephia_log(ctx, LOG_ERROR, 0, "Missing fieldMapping");
00265                 return NULL;
00266         }
00267         fmap = eDBxmlMapping(ctx, tbl_sqlite_certs, NULL, fieldmap_n);
00268 
00269         if( strcmp(mode, "list") == 0 ) {
00270                 char *sortkeys = xmlGetNodeContent(root_n, "sortkeys");
00271                 resxml = certificate_list(ctx, fmap, eDBmkSortKeyString(fmap, sortkeys));
00272         } else if( strcmp(mode, "register") == 0 ) {
00273                 resxml = certificate_add(ctx, fmap);
00274         } else if( strcmp(mode, "delete") == 0 ) {
00275                 resxml = certificate_delete(ctx, fmap);
00276         } else {
00277                 eurephia_log(ctx, LOG_ERROR, 0, "Certificates - Unknown mode: '%s'", mode);
00278                 resxml = eurephiaXML_ResultMsg(ctx, exmlERROR, NULL, "Unknown mode '%s'", mode);
00279         }
00280         eDBfreeMapping(fmap);
00281         return resxml;
00282 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines