Skip to content

Commit

Permalink
srm-client: support srm operations with bearer token
Browse files Browse the repository at this point in the history
Motivation:

The common srm-client now supports non-X.509 bearer token.  The
command-line client should be updated to take advantage of this new
feature.

NB. file transfers are NOT adjusted by this patch.  By default, gsiftp
is used, which requires X.509 authentication.  Therefore transfers
(srmcp) will fail with OpenID-Connect authentication.

Modification:

Update configation to make X.509 client authentication optional.

Update wrapper script so that the auto-detected X.509 is only done if no
bearer_token argument is supplied.

The user can supply a bearer token on the command-line, which srm-client
will use in the Authorization HTTP request header.

Result:

The SRM command-line clients now support bearer token authentication in
addition to supporting X.509 authentication.  NOTE SRM transfers with
bearer token are not yet supported.

Target: master
Requires-notes: yes (srm-client)
Requires-book: yes
Patch: https://rb.dcache.org/r/12568/
Acked-by: Dmitry Litvintsev
  • Loading branch information
paulmillar committed Sep 15, 2020
1 parent c39689b commit 73a7a7c
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 32 deletions.
39 changes: 27 additions & 12 deletions modules/srm-client/src/main/bin/srmfs
Expand Up @@ -11,17 +11,28 @@ else
logbackDefn="-Dlogback.configurationFile=$conf_dir/logback.xml"
fi

if [ -n "$X509_USER_PROXY" ]; then
x509_user_proxy="$X509_USER_PROXY"
elif [ -r /tmp/x509up_u$(id -u) ]; then
x509_user_proxy=/tmp/x509up_u$(id -u)
else
(echo "Could not find X.509 proxy credential."
echo
echo "Either create a proxy credential if one does not already exist or"
echo "use the X509_USER_PROXY environment variable to specify the path"
echo "if the proxy is in a non-standard location.") >&2
exit 1
hasBearerToken=0
for arg in "$@"; do
case "$arg" in
-bearer_token=*)
hasBearerToken=1
;;
esac
done

if [ $hasBearerToken = 0 ]; then
if [ -n "$X509_USER_PROXY" ]; then
x509_user_proxy="$X509_USER_PROXY"
elif [ -r /tmp/x509up_u$(id -u) ]; then
x509_user_proxy=/tmp/x509up_u$(id -u)
else
(echo "Could not find X.509 proxy credential."
echo
echo "Either create a proxy credential if one does not already exist or"
echo "use the X509_USER_PROXY environment variable to specify the path"
echo "if the proxy is in a non-standard location.") >&2
exit 1
fi
fi

if [ -n "$X509_CERT_DIR" ]; then
Expand All @@ -32,11 +43,15 @@ else
x509_user_trusted_certs=/etc/grid-security/certificates
fi

if [ -n "$x509_user_proxy" ]; then
x509_user_proxy_arg="-x509_user_proxy=\"$x509_user_proxy\""
fi

CLASSPATH="$SRM_PATH/lib/*" exec java -Dlog=${DELEGATION_LOG:-warn} \
-client \
-Djava.awt.headless=true \
-DwantLog4jSetup=n \
"$logbackDefn" \
-XX:+TieredCompilation \
-XX:TieredStopAtLevel=1 \
org.dcache.srm.shell.SrmShell -x509_user_proxy="$x509_user_proxy" -x509_user_trusted_certificates="$x509_user_trusted_certs" "$@"
org.dcache.srm.shell.SrmShell $x509_user_proxy_arg -x509_user_trusted_certificates="$x509_user_trusted_certs" "$@"
Expand Up @@ -1692,6 +1692,7 @@ public final String usage() {
"wsdl_url",
"webservice_path",
"webservice_protocol",
"bearer_token",
"use_proxy",
"x509_user_proxy",
"x509_user_cert",
Expand Down
Expand Up @@ -19,6 +19,19 @@ public void setUseproxy(boolean useproxy)
this.useproxy = useproxy;
}

@Option(name="bearer_token", description="The bearer token to use for authentication")
private String bearerToken;

public String getBearerToken()
{
return bearerToken;
}

public void setBearerToken(String token)
{
bearerToken = token;
}

@Option(name="x509_user_proxy", description="absolute path to user proxy",
required=false, log=true, save=true)
private String x509_user_proxy;
Expand Down
18 changes: 14 additions & 4 deletions modules/srm-client/src/main/java/gov/fnal/srm/util/SRMClient.java
Expand Up @@ -75,6 +75,7 @@ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
import java.security.KeyStoreException;
import java.security.cert.CertificateException;
import java.util.Date;
import java.util.Optional;

import org.dcache.srm.Logger;
import org.dcache.srm.client.SRMClientV2;
Expand All @@ -96,7 +97,7 @@ public abstract class SRMClient
protected final Logger logger;

protected Report report;
private X509Credential cred;
private Optional<X509Credential> cred;
protected ISRM srm;

public SRMClient(Configuration configuration)
Expand Down Expand Up @@ -147,6 +148,7 @@ public void connect() throws Exception

srm = new SRMClientV2(uri,
getCredential(),
getBearerToken(),
configuration.getRetry_timeout(),
configuration.getRetry_num(),
configuration.isDelegate(),
Expand All @@ -159,14 +161,18 @@ public void connect() throws Exception

public abstract void start() throws Exception;

private X509Credential getCredential() throws IOException, KeyStoreException,
private Optional<X509Credential> getCredential() throws IOException, KeyStoreException,
CertificateException
{
if (cred == null) {
if (configuration.isUseproxy()) {
cred = new PEMCredential(configuration.getX509_user_proxy(), (char[]) null);
cred = configuration.getX509_user_proxy() == null
? Optional.<X509Credential>empty()
: Optional.of(new PEMCredential(configuration.getX509_user_proxy(), (char[]) null));
} else {
cred = new PEMCredential(configuration.getX509_user_key(), configuration.getX509_user_cert(), null);
cred = configuration.getX509_user_key() == null || configuration.getX509_user_cert() == null
? Optional.<X509Credential>empty()
: Optional.of(new PEMCredential(configuration.getX509_user_key(), configuration.getX509_user_cert(), null));
}
}

Expand All @@ -180,6 +186,10 @@ protected void checkCredentialValid() throws IOException
}
}

public Optional<String> getBearerToken()
{
return Optional.ofNullable(configuration.getBearerToken());
}

private void setReportSuccessStatusBySource(URI url){
if(report == null) {
Expand Down
Expand Up @@ -30,6 +30,7 @@
import java.rmi.RemoteException;
import java.util.Collections;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

import org.dcache.srm.SRMException;
Expand Down Expand Up @@ -98,7 +99,7 @@ public class AxisSrmFileSystem implements SrmFileSystem

private final ISRM srm;
private final SrmTransferAgent srmAgent = new SrmTransferAgent();
private X509Credential credential;
private Optional<X509Credential> credential = Optional.empty();

private boolean haveTunedLsSize;
private int maxLsResponse = DEFAULT_MAX_LS_RESPONSE;
Expand All @@ -111,14 +112,14 @@ public AxisSrmFileSystem(ISRM srm)
@Override
public void setCredential(X509Credential credential)
{
this.credential = credential;
this.credential = Optional.of(credential);
}

@Override
public void start()
{
ExtendableFileTransferAgent transferAgent = new ExtendableFileTransferAgent();
transferAgent.setCredential(credential);
credential.ifPresent(transferAgent::setCredential);
transferAgent.start();

srmAgent.setSrm(srm);
Expand Down
Expand Up @@ -7,6 +7,7 @@
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.ServiceLoader;


Expand All @@ -23,12 +24,12 @@ public class ExtendableFileTransferAgent implements FileTransferAgent, Credentia

private ImmutableMap<String,FileTransferAgent> _protocolAgent;
private ImmutableMap<String,Integer> _protocolPriority;
private X509Credential _credential;
private Optional<X509Credential> _credential = Optional.empty();

@Override
public void setCredential(X509Credential credential)
{
_credential = credential;
_credential = Optional.of(credential);
}

@Override
Expand Down Expand Up @@ -80,7 +81,12 @@ public void start()
{
for (FileTransferAgent agent : agents) {
if (agent instanceof CredentialAware) {
((CredentialAware)agent).setCredential(_credential);
CredentialAware credentialAgent = (CredentialAware)agent;
if (_credential.isPresent()) {
credentialAgent.setCredential(_credential.get());
} else {
continue;
}
}

agent.start();
Expand All @@ -95,6 +101,10 @@ private void buildProtocols()
Map<String,Integer> protocolPriority = new HashMap<>();

for (FileTransferAgent agent : agents) {
if (agent instanceof CredentialAware && !_credential.isPresent()) {
continue;
}

for (Map.Entry<String,Integer> e : agent.getSupportedProtocols().entrySet()) {
String protocol = e.getKey();
int priority = e.getValue();
Expand Down
Expand Up @@ -64,6 +64,7 @@
import java.rmi.RemoteException;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
Expand Down Expand Up @@ -348,12 +349,18 @@ public SrmShell(URI uri, Args args) throws Exception

X509Credential credential;
if (configuration.isUseproxy()) {
credential = new PEMCredential(configuration.getX509_user_proxy(), (char[]) null);
credential = configuration.getX509_user_proxy() == null
? null
: new PEMCredential(configuration.getX509_user_proxy(), (char[]) null);
} else {
credential = new PEMCredential(configuration.getX509_user_key(), configuration.getX509_user_cert(), null);
credential = configuration.getX509_user_key() == null || configuration.getX509_user_cert() == null
? null
: new PEMCredential(configuration.getX509_user_proxy(), (char[]) null);
}

fs = new AxisSrmFileSystem(decorateWithMonitoringProxy(new Class<?>[]{ISRM.class},
new SRMClientV2(srmUrl, credential,
new SRMClientV2(srmUrl, Optional.ofNullable(credential),
Optional.ofNullable(configuration.getBearerToken()),
configuration.getRetry_timeout(),
configuration.getRetry_num(),
configuration.isDelegate(),
Expand All @@ -363,7 +370,9 @@ public SrmShell(URI uri, Args args) throws Exception
configuration.getX509_user_trusted_certificates(),
Transport.GSI),
counters, gauges));
fs.setCredential(credential);
if (credential != null) {
fs.setCredential(credential);
}
fs.start();
cd(srmUrl.toASCIIString());
home = pwd;
Expand Down
25 changes: 19 additions & 6 deletions modules/srm-client/src/main/lib/srm
Expand Up @@ -96,12 +96,25 @@ else
fi
java_options="$java_options \"-Dlogback.configurationFile=$SRM_PATH/conf/$logback\""

if [ -n "$X509_USER_PROXY" ]; then
enforced_srm_options="-use_proxy=true \"-x509_user_proxy=$X509_USER_PROXY\""
elif [ -r /tmp/x509up_u$(id -u) ]; then
srm_options="-use_proxy=true -x509_user_proxy=/tmp/x509up_u$(id -u)"
else
srm_options="-use_proxy=false \"-x509_user_cert=$HOME/.globus/usercert.pem\" \"-x509_user_key=$HOME/.globus/userkey.pem\""

hasBearerToken=0
for arg in "$@"; do
case "$arg" in
-bearer_token=*)
hasBearerToken=1
;;
esac
done

if [ $hasBearerToken = 0 ]; then
# Auto-detect X.509
if [ -n "$X509_USER_PROXY" ]; then
enforced_srm_options="-use_proxy=true \"-x509_user_proxy=$X509_USER_PROXY\""
elif [ -r /tmp/x509up_u$(id -u) ]; then
srm_options="-use_proxy=true -x509_user_proxy=/tmp/x509up_u$(id -u)"
else
srm_options="-use_proxy=false \"-x509_user_cert=$HOME/.globus/usercert.pem\" \"-x509_user_key=$HOME/.globus/userkey.pem\""
fi
fi

if [ -n "$X509_CERT_DIR" ]; then
Expand Down

0 comments on commit 73a7a7c

Please sign in to comment.