Back to index

nordugrid-arc-nox  1.1.0~rc6
X509TokenSH.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 #include <iostream>
00006 #include <fstream>
00007 
00008 #include <arc/message/PayloadSOAP.h>
00009 #include <arc/XMLNode.h>
00010 #include <arc/ws-security/X509Token.h>
00011 #include <arc/xmlsec/XmlSecUtils.h>
00012 
00013 #include "X509TokenSH.h"
00014 
00015 static Arc::Logger logger(Arc::Logger::rootLogger, "X509TokenSH");
00016 
00017 Arc::Plugin* ArcSec::X509TokenSH::get_sechandler(Arc::PluginArgument* arg) {
00018     ArcSec::SecHandlerPluginArgument* shcarg =
00019             arg?dynamic_cast<ArcSec::SecHandlerPluginArgument*>(arg):NULL;
00020     if(!shcarg) return NULL;
00021     return new ArcSec::X509TokenSH((Arc::Config*)(*shcarg),(Arc::ChainContext*)(*shcarg));
00022 }
00023 
00024 /*
00025 sechandler_descriptors ARC_SECHANDLER_LOADER = {
00026     { "x509token.creator", 0, &get_sechandler},
00027     { NULL, 0, NULL }
00028 };
00029 */
00030 
00031 namespace ArcSec {
00032 using namespace Arc;
00033 
00034 X509TokenSH::X509TokenSH(Config *cfg,ChainContext*):SecHandler(cfg){
00035   if(!init_xmlsec()) return;
00036   process_type_=process_none;
00037   std::string process_type = (std::string)((*cfg)["Process"]);
00038   if(process_type == "generate") { 
00039     cert_file_=(std::string)((*cfg)["CertificatePath"]);
00040     if(cert_file_.empty()) {
00041       logger.msg(ERROR,"Missing or empty CertificatePath element");
00042       return;
00043     };
00044     key_file_=(std::string)((*cfg)["KeyPath"]);
00045     if(key_file_.empty()) {
00046       logger.msg(ERROR,"Missing or empty KeyPath element");
00047       return;
00048     };
00049     process_type_=process_generate;
00050   } else if(process_type == "extract") {
00051     //If ca file does not exist, we can only verify the signature by
00052     //using the certificate in the incoming wssecurity; we can not authenticate
00053     //the the message because we can not check the certificate chain without 
00054     //trusted ca.
00055     ca_file_=(std::string)((*cfg)["CACertificatePath"]);
00056     ca_dir_=(std::string)((*cfg)["CACertificatesDir"]);
00057     if(ca_file_.empty() && ca_dir_.empty()) {
00058       logger.msg(INFO,"Missing or empty CertificatePath or CACertificatesDir element; will only check the signature, will not do message authentication");
00059     };
00060     process_type_=process_extract;
00061   } else {
00062     logger.msg(ERROR,"Processing type not supported: %s",process_type);
00063     return;
00064   };
00065 }
00066 
00067 X509TokenSH::~X509TokenSH() {
00068   final_xmlsec();
00069 }
00070 
00071 bool X509TokenSH::Handle(Arc::Message* msg) const {
00072   if(process_type_ == process_extract) {
00073     try {
00074       PayloadSOAP* soap = dynamic_cast<PayloadSOAP*>(msg->Payload());
00075       X509Token xt(*soap);
00076       if(!xt) {
00077         logger.msg(ERROR,"Failed to parse X509 Token from incoming SOAP");
00078         return false;
00079       };
00080       if(!xt.Authenticate()) {
00081         logger.msg(ERROR, "Failed to verify X509 Token inside the incoming SOAP");
00082         return false;
00083       };
00084       if((!ca_file_.empty() || !ca_dir_.empty()) && !xt.Authenticate(ca_file_, ca_dir_)) {
00085         logger.msg(ERROR, "Failed to authenticate X509 Token inside the incoming SOAP");
00086         return false;
00087       };
00088       logger.msg(INFO, "Succeeded to authenticate X509Token");
00089     } catch(std::exception) {
00090       logger.msg(ERROR,"Incoming Message is not SOAP");
00091       return false;
00092     }  
00093   } else if(process_type_ == process_generate) {
00094     try {
00095       PayloadSOAP* soap = dynamic_cast<PayloadSOAP*>(msg->Payload());
00096       X509Token xt(*soap, cert_file_, key_file_);
00097       if(!xt) {
00098         logger.msg(ERROR,"Failed to generate X509 Token for outgoing SOAP");
00099         return false;
00100       };
00101       //Reset the soap message
00102       (*soap) = xt;
00103     } catch(std::exception) {
00104       logger.msg(ERROR,"Outgoing Message is not SOAP");
00105       return false;
00106     }
00107   } else {
00108     logger.msg(ERROR,"X509 Token handler is not configured");
00109     return false;
00110   } 
00111   return true;
00112 }
00113 
00114 }
00115 
00116