Commit 4266014d authored by Volodymyr Yurchenko's avatar Volodymyr Yurchenko Committed by Nikola Hardi
Browse files

Adjust credentials management in TJAlien

parent d66aacce
Pipeline #946453 failed with stage
in 50 seconds
......@@ -130,10 +130,6 @@ private:
/* struct lws_context_creation_info creation_info; // Info to create logical connection */
struct lws *wsi; // WebSocket Instance - real connection object, created basing on context
struct session_data { // Needed by protocol, TODO: clarify if can be replaced by just int var
int fd;
};
#if !defined(__CINT__) && !defined(__MAKECINT__) && !defined(__ROOTCLING__) && !defined(__CLING__)
static int ws_service_callback( // Callback to handle connection
struct lws *wsi,
......
......@@ -3,6 +3,7 @@
#define ROOT_TJAlienCredentials
#include <string>
#include <map>
#include <termios.h>
#include "TObject.h"
#include "TJClientFile.h"
......@@ -20,6 +21,7 @@ struct TJAlienCredentialsObject {
string certpath;
string keypath;
string source;
string password;
CredentialsKind kind;
TJAlienCredentialsObject() {}
......@@ -35,8 +37,10 @@ struct TJAlienCredentialsObject {
};
bool exists() { return fileExists(certpath) && fileExists(keypath); }
string getKey();
string getCertificate();
const string getKey();
const string getCertificate();
const string getPassword();
void readPassword();
private:
bool fileExists(string filename)
......@@ -66,6 +70,8 @@ public:
bool has(CredentialsKind kind);
TJAlienCredentialsObject get(CredentialsKind kind);
void removeCredentials(CredentialsKind kind);
short count();
static const char *ENV_JOBTOKEN_KEY;
static const char *ENV_JOBTOKEN_CERT;
......
......@@ -60,6 +60,7 @@ TJAlien::TJAlien (const char* gridUrl, const char* uId, const char* passwd,
else
tmpdir = P_tmpdir;
creds.loadCredentials();
CreateConnection();
}
......@@ -82,44 +83,54 @@ void TJAlien::CreateConnection()
clearFlags();
creds.loadCredentials();
if(creds.has(cJOB_TOKEN)) {
co = creds.get(cJOB_TOKEN);
} else if(creds.has(cJBOX_TOKEN)) {
co = creds.get(cJBOX_TOKEN);
} else if (creds.has(cFULL_GRID_CERT)) {
co = creds.get(cFULL_GRID_CERT);
} else {
return;
}
if(co.kind == cJBOX_TOKEN || co.kind == cJOB_TOKEN) {
ConnectJBox();
}
if(connection_flag) return;
for (int i = 0; i < dns_jcentral.lenght(); i++)
{
current_host = dns_jcentral.get_next_host();
ConnectJCentral(co, current_host);
if (connection_flag)
{
// If connected directly to JCentral, immediately ask for token
if(gDebug > 0) {
Info("TJAlien", "Successfully connected to %s", current_host.c_str());
}
Token("", false);
fUser = Whoami();
return;
}
else
{
Error("TJAlien", "Failed to connect to %s - retrying...", current_host.c_str());
sleep(1);
}
}
while (creds.count() > 0) {
if (creds.has(cJOB_TOKEN)) {
co = creds.get(cJOB_TOKEN);
} else if (creds.has(cJBOX_TOKEN)) {
co = creds.get(cJBOX_TOKEN);
} else if (creds.has(cFULL_GRID_CERT)) {
co = creds.get(cFULL_GRID_CERT);
if (co.password.empty())
co.readPassword();
} else {
Error("TJAlien", "Failed to get any credentials");
return;
}
if (co.kind == cJBOX_TOKEN || co.kind == cJOB_TOKEN) {
ConnectJBox();
}
if (connection_flag) {
Info("TJAlien", "Successfully connected to JBox");
co.password = "";
return;
}
for (int i = 0; i < dns_jcentral.lenght(); i++)
{
current_host = dns_jcentral.get_next_host();
ConnectJCentral(co, current_host);
if (connection_flag)
{
// If connected directly to JCentral, immediately ask for token
Info("TJAlien", "Successfully connected to %s", current_host.c_str());
Token("", false);
fUser = Whoami();
co.password = "";
return;
}
else
{
if (gDebug > 0) {
Error("TJAlien", "Failed to connect to %s - retrying...", current_host.c_str());
}
sleep(1);
}
}
creds.removeCredentials(co.kind);
}
Error("TJAlien", "Failed to connect to any server! Giving up");
}
......@@ -167,7 +178,7 @@ void TJAlien::MakeWebsocketConnection(TJAlienCredentialsObject creds, string hos
}
// Use this for debugging
// lws_set_log_level(1023, NULL);//LLL_DEBUG | LLL_INFO | LLL_ERR | LLL_NOTICE, NULL);
//lws_set_log_level(LLL_EXT | LLL_USER | LLL_PARSER | LLL_INFO | LLL_ERR | LLL_NOTICE, NULL);
lws_set_log_level(gDebug, NULL);
// Reset context variables
......@@ -206,20 +217,18 @@ void TJAlien::MakeWebsocketConnection(TJAlienCredentialsObject creds, string hos
creation_info.uid = -1;
creation_info.options = 0;
creation_info.vhost_name = "tjalien-root";
// TODO (nhardi): switch to explicit key/cert contents
// see the context_creation_info
creation_info.client_ssl_cert_filepath = creds.certpath.c_str();
creation_info.client_ssl_private_key_filepath = creds.keypath.c_str();
// creation_info.client_ssl_cert_mem = creds.getCertificate().c_str();
// creation_info.client_ssl_cert_mem_len = creds.getCertificate().length();
if (use_ssl)
{
creation_info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
}
creation_info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT;
// TODO (nhardi): switch to explicit key/cert contents
// see the context_creation_info
creation_info.client_ssl_cert_filepath = creds.certpath.c_str();
creation_info.client_ssl_private_key_filepath = creds.keypath.c_str();
//creation_info.client_ssl_cert_mem = creds.getCertificate().c_str();
//creation_info.client_ssl_cert_mem_len = creds.getCertificate().length();
// TODO (yuw): switch to client_ssl_private_key_password starting from libwebsockets 3.1.0 and onward
creation_info.ssl_private_key_password = creds.password.c_str();
// Create context - only logical connection, no real connection yet
context = lws_create_context(&creation_info);
if (context == NULL) {
......@@ -266,6 +275,7 @@ void TJAlien::MakeWebsocketConnection(TJAlienCredentialsObject creds, string hos
}
}
creation_info.ssl_private_key_password = "";
return;
}
......@@ -1621,9 +1631,9 @@ int TJAlien::ws_service_callback(struct lws *wsi, enum lws_callback_reasons reas
if (gDebug > 1)
{
printf("[Websocket Callback] LWS_CALLBACK_OPENSSL_PERFORM_SERVER_CERT_VERIFICATION is called\n");
printf("[Websocket Callback] x509_ctx: %s\n", ((SSL_CTX*)user)->client_CA);
printf("[Websocket Callback] ssl: %s\n", in);
printf("[Websocket Callback] SSL_CTX_get_client_CA_list: %s\n", SSL_CTX_get_client_CA_list((SSL_CTX*)user));
//printf("[Websocket Callback] x509_ctx: %s\n", ((SSL_CTX*)user)->client_CA);
//printf("[Websocket Callback] ssl: %s\n", in);
//printf("[Websocket Callback] SSL_CTX_get_client_CA_list: %s\n", SSL_CTX_get_client_CA_list((SSL_CTX*)user));
}
break;
......
......@@ -18,49 +18,49 @@ const char* TJAlienCredentials::TMP_JOBTOKEN_KEY_FNAME = "tmpjobtokenkey.pem";
const char* TJAlienCredentials::TMP_JOBTOKEN_CERT_FNAME = "tmpjobtokencert.pem";
string TJAlienCredentials::getTmpDir() {
string tmpdir;
string tmpdir;
if (getenv("TMPDIR") != NULL)
tmpdir = getenv("TMPDIR");
else if (getenv("TMP") != NULL)
tmpdir = getenv("TMP");
else if (getenv("TEMP") != NULL)
tmpdir = getenv("TEMP");
else
tmpdir = P_tmpdir;
if (getenv("TMPDIR") != NULL)
tmpdir = getenv("TMPDIR");
else if (getenv("TMP") != NULL)
tmpdir = getenv("TMP");
else if (getenv("TEMP") != NULL)
tmpdir = getenv("TEMP");
else
tmpdir = P_tmpdir;
return tmpdir;
return tmpdir;
}
string TJAlienCredentials::getHomeDir() {
string homedir;
string homedir;
if (getenv("HOME") != NULL)
homedir = getenv("HOME");
else
homedir = "~";
if (getenv("HOME") != NULL)
homedir = getenv("HOME");
else
homedir = "~";
return homedir;
return homedir;
}
string TJAlienCredentials::getTokencertPath()
{
std::stringstream tokencert_s;
tokencert_s << tmpdir << "/tokencert_" << getuid() << ".pem";
std::string tokencert = tokencert_s.str();
std::string tokencertpath = std::getenv("JALIEN_TOKEN_CERT") ? : tokencert;
std::stringstream tokencert_s;
tokencert_s << tmpdir << "/tokencert_" << getuid() << ".pem";
std::string tokencert = tokencert_s.str();
std::string tokencertpath = std::getenv("JALIEN_TOKEN_CERT") ? : tokencert;
return tokencertpath;
return tokencertpath;
}
string TJAlienCredentials::getTokenkeyPath()
{
std::stringstream tokenkey_s;
tokenkey_s << tmpdir << "/tokenkey_" << getuid() << ".pem";
std::string tokenkey = tokenkey_s.str();
std::string tokenkeypath = std::getenv("JALIEN_TOKEN_KEY") ? : tokenkey;
std::stringstream tokenkey_s;
tokenkey_s << tmpdir << "/tokenkey_" << getuid() << ".pem";
std::string tokenkey = tokenkey_s.str();
std::string tokenkeypath = std::getenv("JALIEN_TOKEN_KEY") ? : tokenkey;
return tokenkeypath;
return tokenkeypath;
}
string TJAlienCredentials::getUsercertPath()
......@@ -80,14 +80,13 @@ string TJAlienCredentials::getUserkeyPath()
TJAlienCredentials::TJAlienCredentials() {
tmpdir = getTmpDir();
homedir = getHomeDir();
loadCredentials();
}
void TJAlienCredentials::loadCredentials() {
found_credentials.clear();
loadTokenCertificate();
loadFullGridCertificate();
loadJobTokenCertificate();
found_credentials.clear();
loadTokenCertificate();
loadFullGridCertificate();
loadJobTokenCertificate();
}
void TJAlienCredentials::loadTokenCertificate() {
......@@ -101,7 +100,7 @@ void TJAlienCredentials::loadTokenCertificate() {
void TJAlienCredentials::loadFullGridCertificate() {
TJAlienCredentialsObject grid_certificate(getUsercertPath(), getUserkeyPath(), cFULL_GRID_CERT);
if(grid_certificate.exists()) {
if (grid_certificate.exists()) {
found_credentials[cFULL_GRID_CERT] = grid_certificate;
}
}
......@@ -147,6 +146,16 @@ TJAlienCredentialsObject TJAlienCredentials::get(CredentialsKind kind) {
}
}
void TJAlienCredentials::removeCredentials(CredentialsKind kind) {
if (this->has(kind)) {
found_credentials.erase(kind);
}
}
short TJAlienCredentials::count() {
return found_credentials.size();
}
string readFile(const char* filename) {
string line;
stringstream contents;
......@@ -160,14 +169,43 @@ string readFile(const char* filename) {
return contents.str();
}
string TJAlienCredentialsObject::getKey() {
const string TJAlienCredentialsObject::getKey() {
return readFile(keypath.c_str());
}
string TJAlienCredentialsObject::getCertificate() {
const string TJAlienCredentialsObject::getCertificate() {
return readFile(certpath.c_str());
}
void TJAlienCredentialsObject::readPassword() {
if (this->kind == cFULL_GRID_CERT && this->getKey().find("ENCRYPTED") != std::string::npos)
{
printf("[Grid certificate password: ]");
struct termios termold, termnew;
tcgetattr(fileno(stdin), &termold);
termnew = termold;
termnew.c_lflag &= ~ECHO;
termnew.c_lflag |= ECHONL;
tcsetattr(fileno(stdin), TCSANOW, &termnew);
char password[64];
fgets(password, sizeof(password), stdin);
tcsetattr(0, TCSANOW, &termold);
password[strlen(password) - 1] = 0;
this->password = std::string(password);
}
}
const string TJAlienCredentialsObject::getPassword() {
if (this->password.empty())
readPassword();
//printf("this->password %s\n", this->password.c_str());
return this->password;
}
TJAlienCredentials::~TJAlienCredentials() {
if(has(cJOB_TOKEN)) {
TJAlienCredentialsObject creds = get(cJOB_TOKEN);
......
......@@ -62,7 +62,7 @@ vector<string> TJAlienDNSResolver::get_addr(const char *host, const char *port,
void TJAlienDNSResolver::reset() {
addr_ipv4 = get_addr(host.c_str(), port.c_str(), 4);
addr_ipv6 = get_addr(host.c_str(), port.c_str(), 6);
use_ipv6 = false;
use_ipv6 = true;
current_position = 0;
}
......
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