-
Notifications
You must be signed in to change notification settings - Fork 304
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HPCC-30259 Use secrets for dafilesrv client connections #17821
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -667,7 +667,7 @@ void clientAddSocketToCache(SocketEndpoint &ep,ISocket *socket) | |
|
||
//--------------------------------------------------------------------------- | ||
|
||
void CRemoteBase::connectSocket(SocketEndpoint &ep, unsigned connectTimeoutMs, unsigned connectRetries) | ||
void CRemoteBase::connectSocket(SocketEndpoint &ep, unsigned connectTimeoutMs, unsigned connectRetries, bool secure) | ||
{ | ||
if (!connectTimeoutMs) | ||
connectTimeoutMs = dafsConnectTimeoutMs; | ||
|
@@ -696,10 +696,7 @@ void CRemoteBase::connectSocket(SocketEndpoint &ep, unsigned connectTimeoutMs, u | |
if (TF_TRACE_CLIENT_CONN) | ||
{ | ||
ep.getEndpointHostText(eps); | ||
if (ep.port == securitySettings.queryDaFileSrvSSLPort()) | ||
PROGLOG("Connecting SECURE to %s", eps.str()); | ||
else | ||
PROGLOG("Connecting to %s", eps.str()); | ||
PROGLOG("Connecting %sto %s", secure?"SECURE ":"", eps.str()); | ||
//PrintStackReport(); | ||
} | ||
bool ok = true; | ||
|
@@ -714,13 +711,36 @@ void CRemoteBase::connectSocket(SocketEndpoint &ep, unsigned connectTimeoutMs, u | |
} | ||
else | ||
socket.setown(ISocket::connect(ep)); | ||
if (ep.port == securitySettings.queryDaFileSrvSSLPort()) | ||
if (secure) | ||
{ | ||
#ifdef _USE_OPENSSL | ||
Owned<ISecureSocket> ssock; | ||
try | ||
{ | ||
ssock.setown(createSecureSocket(socket.getClear(), nullptr)); | ||
// instead of creating CRemoteFile/CRemoteBase with a secret, it could instead lookup, and create the ISecureSocketContext and pass that | ||
// into the ctor. That would avoid having to look the secret up, extract the certs and recreate the context on each connection. | ||
// The context would be 'owned' by the hook, and would expire when the mappings are removed (when removeMappedDafileSrvSecrets is called). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. NB: @ghalliday @mckellyln - in a subsequent PR I will be refactoring the below so that it uses the new ISecret interface and caching the security contexts |
||
if (storageSecret) | ||
{ | ||
Owned<IPropertyTree> secretPTree = getSecret("storage", storageSecret); | ||
if (!secretPTree) | ||
throw makeStringExceptionV(-1, "secret %s.%s not found", "storage", storageSecret.str()); | ||
|
||
StringBuffer certSecretBuf; | ||
getSecretKeyValue(certSecretBuf, secretPTree, "tls.crt"); | ||
|
||
StringBuffer privKeySecretBuf; | ||
getSecretKeyValue(privKeySecretBuf, secretPTree, "tls.key"); | ||
|
||
Owned<ISecureSocketContext> secureContext = createSecureSocketContextEx(certSecretBuf, privKeySecretBuf, nullptr, ClientSocket); | ||
int loglevel = SSLogNormal; | ||
#ifdef _DEBUG | ||
loglevel = SSLogMax; | ||
#endif | ||
ssock.setown(secureContext->createSecureSocket(socket.getClear(), loglevel)); | ||
} | ||
else | ||
ssock.setown(createSecureSocket(socket.getClear(), nullptr)); | ||
int status = ssock->secure_connect(); | ||
if (status < 0) | ||
throw createDafsException(DAFSERR_connection_failed, "Failure to establish secure connection"); | ||
|
@@ -787,10 +807,7 @@ void CRemoteBase::connectSocket(SocketEndpoint &ep, unsigned connectTimeoutMs, u | |
if (!timeExpired) | ||
{ | ||
Sleep(sleeptime); // prevent multiple retries beating | ||
if (ep.port == securitySettings.queryDaFileSrvSSLPort()) | ||
PROGLOG("Retrying SECURE connect"); | ||
else | ||
PROGLOG("Retrying connect"); | ||
PROGLOG("Retrying %sconnect", secure?"SECURE ":""); | ||
} | ||
} | ||
|
||
|
@@ -879,35 +896,41 @@ void CRemoteBase::sendRemoteCommand(MemoryBuffer & src, MemoryBuffer & reply, bo | |
|
||
if (!socket) | ||
{ | ||
bool doConnect = true; | ||
if (connectMethod == SSLFirst || connectMethod == UnsecureFirst) | ||
if (storageSecret) | ||
connectSocket(tep, 0, INFINITE, true); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should timeout be INFINITE or 0 (to use configured default) ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. timeout is 0.
Same as defaults, just explicit now. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok, sorry I read the args wrong. |
||
else | ||
{ | ||
// MCK - could maintain a list of 100 or so previous endpoints and if connection failed | ||
// then mark port down for a delay (like 15 min above) to avoid having to try every time ... | ||
try | ||
{ | ||
connectSocket(tep, 5000, 0); | ||
doConnect = false; | ||
} | ||
catch (IDAFS_Exception *e) | ||
bool doConnect = true; | ||
if (connectMethod == SSLFirst || connectMethod == UnsecureFirst) | ||
{ | ||
if (e->errorCode() == DAFSERR_connection_failed) | ||
bool secure = tep.port == securitySettings.queryDaFileSrvSSLPort(); | ||
// MCK - could maintain a list of 100 or so previous endpoints and if connection failed | ||
// then mark port down for a delay (like 15 min above) to avoid having to try every time ... | ||
try | ||
{ | ||
unsigned prevPort = tep.port; | ||
if (prevPort == securitySettings.queryDaFileSrvSSLPort()) | ||
tep.port = securitySettings.queryDaFileSrvPort(); | ||
connectSocket(tep, 5000, 0); | ||
doConnect = false; | ||
} | ||
catch (IDAFS_Exception *e) | ||
{ | ||
if (e->errorCode() == DAFSERR_connection_failed) | ||
{ | ||
unsigned prevPort = tep.port; | ||
if (secure) | ||
tep.port = securitySettings.queryDaFileSrvPort(); | ||
else | ||
tep.port = securitySettings.queryDaFileSrvSSLPort(); | ||
WARNLOG("Connect failed on port %d, retrying on port %d", prevPort, tep.port); | ||
doConnect = true; | ||
e->Release(); | ||
} | ||
else | ||
tep.port = securitySettings.queryDaFileSrvSSLPort(); | ||
WARNLOG("Connect failed on port %d, retrying on port %d", prevPort, tep.port); | ||
doConnect = true; | ||
e->Release(); | ||
throw e; | ||
} | ||
else | ||
throw e; | ||
} | ||
if (doConnect) | ||
connectSocket(tep, 0, INFINITE, tep.port == securitySettings.queryDaFileSrvSSLPort()); | ||
} | ||
if (doConnect) | ||
connectSocket(tep); | ||
} | ||
} | ||
|
||
|
@@ -979,6 +1002,11 @@ CRemoteBase::CRemoteBase(const SocketEndpoint &_ep, DAFSConnectCfg _connectMetho | |
connectMethod = _connectMethod; | ||
} | ||
|
||
CRemoteBase::CRemoteBase(const SocketEndpoint &_ep, const char *_storageSecret, const char * _filename) | ||
: ep(_ep), storageSecret(_storageSecret), filename(_filename) | ||
{ | ||
} | ||
|
||
void CRemoteBase::disconnect() | ||
{ | ||
CriticalBlock block(crit); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed - it may be simpler to avoid this code and always search for a secret, but for a follow up PR.