Commit f39cb43b authored by Aleksandr Konstantinov's avatar Aleksandr Konstantinov

Merge branch 'bug_3927' into 'master'

Fix for VOMS REST. Fixes BUGZ-3927.

See merge request nordugrid/arc!1047
parents e13c29aa fea70756
Pipeline #8399 passed with stage
in 117 minutes and 34 seconds
......@@ -69,12 +69,17 @@ group<:role>. Specify ordering of attributes.
.TP
\fB\-G\fR
use GSI communication protocol for contacting VOMS services
use GSI wire protocol for contacting VOMS services instead of SSL/TLS
.TP
\fB\-H\fR
use HTTP communication protocol for contacting VOMS services that provide RESTful access
Note for RESTful access, 'list' command and multiple VOMS server are not supported
Note for RESTful access, 'list' command and multiple VOMS server are not supported.
This protocol is now default communicaton protocol and You do not need to specify this option.
.TP
\fB\-B\fR
use old communication protocol for contacting VOMS services instead of RESTful.
.TP
\fB\-O\fR
......
......@@ -356,9 +356,10 @@ static int runmain(int argc, char *argv[]) {
bool use_http_comm = false;
options.AddOption('H', "httpcom", istring("use HTTP communication protocol for contacting VOMS services that provide RESTful access \n"
" Note for RESTful access, \'list\' command and multiple VOMS server are not supported\n"
),
use_http_comm);
" Note for RESTful access, \'list\' command and multiple VOMS server are not supported\n"), use_http_comm);
bool use_old_comm = false;
options.AddOption('B', "oldcom", istring("use old communication protocol for contacting VOMS services instead of RESTful access\n"), use_old_comm);
bool use_gsi_proxy = false;
options.AddOption('O', "old", istring("this option is not functional (old GSI proxies are not supported anymore)"), use_gsi_proxy);
......@@ -447,6 +448,11 @@ static int runmain(int argc, char *argv[]) {
std::list<std::string> params = options.Parse(argc, argv);
if(use_http_comm && use_old_comm) {
logger.msg(Arc::ERROR, "RESTful and old VOMS communication protocols can't be requested simultaneously.");
return EXIT_FAILURE;
}
if (version) {
std::cout << Arc::IString("%s version %s", "arcproxy", VERSION) << std::endl;
return EXIT_SUCCESS;
......@@ -1144,7 +1150,7 @@ static int runmain(int argc, char *argv[]) {
write_proxy_file(tmp_proxy_path, tmp_proxy_cred_str);
if(!contact_voms_servers(vomscmdlist, orderlist, vomses_path, use_gsi_comm,
use_http_comm, voms_period, usercfg, logger, tmp_proxy_path, vomsacseq)) {
use_http_comm || !use_old_comm, voms_period, usercfg, logger, tmp_proxy_path, vomsacseq)) {
remove_proxy_file(tmp_proxy_path);
return EXIT_FAILURE;
}
......@@ -1248,7 +1254,7 @@ static int runmain(int argc, char *argv[]) {
logger.msg(Arc::INFO, "Myproxy server did not return proxy with VOMS AC included");
std::string vomsacseq;
contact_voms_servers(vomscmdlist, orderlist, vomses_path, use_gsi_comm,
use_http_comm, voms_period, usercfg, logger, proxy_path, vomsacseq);
use_http_comm || !use_old_comm, voms_period, usercfg, logger, proxy_path, vomsacseq);
if(!vomsacseq.empty()) {
Arc::Credential signer(proxy_path, proxy_path, "", "");
std::string proxy_cert;
......@@ -1298,7 +1304,7 @@ static int runmain(int argc, char *argv[]) {
create_tmp_proxy(tmp_proxy, signer);
write_proxy_file(tmp_proxy_path, tmp_proxy);
if(!contact_voms_servers(vomscmdlist, orderlist, vomses_path, use_gsi_comm,
use_http_comm, voms_period, usercfg, logger, tmp_proxy_path, vomsacseq)) {
use_http_comm || !use_old_comm, voms_period, usercfg, logger, tmp_proxy_path, vomsacseq)) {
remove_proxy_file(tmp_proxy_path);
std::cerr << Arc::IString("Proxy generation failed: Failed to retrieve VOMS information.") << std::endl;
return EXIT_FAILURE;
......
......@@ -405,6 +405,7 @@ namespace Arc {
http_entry(NULL),
default_url(url),
relative_uri(url.Option("relativeuri") == "yes"),
encoded_uri(url.Option("encodeduri") != "no"),
sec(http_url_to_sec(url,!cfg.otoken.empty())),
closed(false) {
XMLNode comp = ConfigMakeComponent(xmlcfg["Chain"], "http.client", "http",
......@@ -537,16 +538,16 @@ namespace Arc {
if(relative_uri) {
// Workaround for servers which can't handle full URLs in request
reqmsg.Attributes()->set("HTTP:HOST", url.Host() + ":" + tostring(url.Port()));
std::string rpath = url.FullPathURIEncoded();
std::string rpath = encoded_uri ? url.FullPathURIEncoded() : url.FullPath();
if(rpath[0] != '/') rpath.insert(0,"/");
reqmsg.Attributes()->set("HTTP:ENDPOINT", rpath);
} else {
reqmsg.Attributes()->set("HTTP:ENDPOINT", url.str(true));
reqmsg.Attributes()->set("HTTP:ENDPOINT", url.str(encoded_uri));
}
} else {
if(relative_uri) {
reqmsg.Attributes()->set("HTTP:HOST", default_url.Host() + ":" + tostring(default_url.Port()));
std::string rpath = default_url.FullPathURIEncoded();
std::string rpath = encoded_uri ? default_url.FullPathURIEncoded() : default_url.FullPath();
if(rpath[0] != '/') rpath.insert(0,"/");
reqmsg.Attributes()->set("HTTP:ENDPOINT", rpath);
}
......
......@@ -180,7 +180,7 @@ namespace Arc {
: public ClientTCP {
public:
ClientHTTP()
: http_entry(NULL), relative_uri(false), sec(NoSec), closed(false) {}
: http_entry(NULL), relative_uri(false), encoded_uri(true), sec(NoSec), closed(false) {}
ClientHTTP(const BaseConfig& cfg, const URL& url, int timeout = -1, const std::string& proxy_host = "", int proxy_port = 0);
virtual ~ClientHTTP();
MCC_Status process(const std::string& method, PayloadRawInterface *request,
......@@ -231,6 +231,7 @@ namespace Arc {
MCC *http_entry;
URL default_url;
bool relative_uri;
bool encoded_uri;
TCPSec sec;
bool closed;
MCC_Status process(const std::string& method, const std::string& path,
......
......@@ -37,6 +37,10 @@ static URL options_to_voms_url(const std::string& host, int port, const TCPSec&
url.ChangeHost(host);
url.ChangePort(port);
url.ChangePath("/generate-ac");
// VOMS server does not like absolute URL in request
url.AddOption("relativeuri","yes",true);
// And it does not understand encoding in HTTP options
url.AddOption("encodeduri","no",true);
return url;
}
......@@ -70,7 +74,7 @@ MCC_Status ClientVOMSRESTful::process(const std::string& principal,
URL url = GetURL();
if(!principal.empty()) url.AddHTTPOption("principal",principal,true);
if(!fqans.empty()) url.AddHTTPOption("fqans",join(fqans,","),true);
if(lifetime != 0) url.AddHTTPOption("lifetime",(std::string)lifetime,true);
if(lifetime != 0) url.AddHTTPOption("lifetime",Arc::tostring(lifetime.GetPeriod()),true);
if(!targets.empty()) url.AddHTTPOption("targets",join(targets,","),true);
PayloadRaw request;
PayloadStreamInterface* response = NULL;
......@@ -100,26 +104,32 @@ MCC_Status ClientVOMSRESTful::process(const std::string& principal,
if(resp_str.length() > 4*1024*1024) break; // Some sanity check
} while(true);
delete response;
//std::cerr<<"--- response: "<<resp_str<<std::endl;
XMLNode resp(resp_str);
if(!resp) {
return MCC_Status(GENERIC_ERROR,"VOMS","Response is not recognized as XML");
}
if(resp.Name() == "voms") {
if(resp.Name() == "error") {
return MCC_Status(GENERIC_ERROR,"VOMS",(std::string)resp["code"]+": "+(std::string)resp["message"]);
} else if(resp.Name() == "voms") {
if(resp["error"]) {
return MCC_Status(GENERIC_ERROR,"VOMS",(std::string)resp["error"]["code"]+": "+(std::string)resp["error"]["message"]);
}
if(resp["ac"]) {
result = (std::string)resp["ac"];
result = "-----BEGIN VOMS AC-----\n"+(std::string)resp["ac"]+"\n-----END VOMS AC-----";
} else {
result.resize(0);
}
XMLNode warning = resp["warning"];
std::string warn_str;
XMLNode warning = resp["warning"];
for(;(bool)warning;++warning) {
if(!warn_str.empty()) warn_str += " ; ";
warn_str += (std::string)warning;
}
if(info.code != 200) {
if(warn_str.empty()) warn_str = info.reason;
return MCC_Status(GENERIC_ERROR,"VOMS",warn_str);
}
return MCC_Status(STATUS_OK,"VOMS",warn_str);
} else if(resp.Name() == "error") {
return MCC_Status(GENERIC_ERROR,"VOMS",(std::string)resp["code"]+": "+(std::string)resp["message"]);
}
return MCC_Status(GENERIC_ERROR,"VOMS","Response is missing required 'voms' and 'error' elements");
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment