Commit 44934daf authored by Tigran Mkrtchyan's avatar Tigran Mkrtchyan
Browse files

rpc: tie together rpc request's credential and verifier

Each RPC request has a two authentication fields - the credential
and verifier. While they looks like independent for AUTH_SYS (unix),
GSS authentication ( and possibly others ) binds them together and
make value of verifier to be changed depending on state of credential.

Acked-By: Paul
Patch: http://rb.dcache.org/r/1719/
parent f0c7a431
......@@ -195,11 +195,11 @@ public class HimeraNfsUtils {
int gid = -1;
int[] gids = null;
if( call.getAuth().type() == RpcAuthType.UNIX) {
if( call.getCredential().type() == RpcAuthType.UNIX) {
uid = ((RpcAuthTypeUnix)call.getAuth()).uid();
gid = ((RpcAuthTypeUnix)call.getAuth()).gid();
gids = ((RpcAuthTypeUnix)call.getAuth()).gids();
uid = ((RpcAuthTypeUnix)call.getCredential()).uid();
gid = ((RpcAuthTypeUnix)call.getCredential()).gid();
gids = ((RpcAuthTypeUnix)call.getCredential()).gids();
}
......
......@@ -29,11 +29,11 @@ public class HimeraNFS4Utils {
int gid = -1;
int[] gids = null;
if( call.getAuth().type() == RpcAuthType.UNIX) {
if( call.getCredential().type() == RpcAuthType.UNIX) {
uid = ((RpcAuthTypeUnix)call.getAuth()).uid();
gid = ((RpcAuthTypeUnix)call.getAuth()).gid();
gids = ((RpcAuthTypeUnix)call.getAuth()).gids();
uid = ((RpcAuthTypeUnix)call.getCredential()).uid();
gid = ((RpcAuthTypeUnix)call.getCredential()).gid();
gids = ((RpcAuthTypeUnix)call.getCredential()).gids();
}
String host = call.getTransport().getRemoteSocketAddress().getAddress().getHostName();
......
......@@ -59,8 +59,8 @@ public class nfs4_prot_NFS4_PROGRAM_Client {
XdrTransport transport;
transport = rpcClient.connect();
RpcAuth auth = new RpcAuthTypeUnix(3750, 1000, new int[]{1000}, (int) (System.currentTimeMillis() / 1000), "nairi");
client = new RpcCall(100003, 4, auth, auth, transport);
RpcAuth credential = new RpcAuthTypeUnix(3750, 1000, new int[]{1000}, (int) (System.currentTimeMillis() / 1000), "nairi");
client = new RpcCall(100003, 4, credential, transport);
}
/**
......
......@@ -19,5 +19,25 @@ package org.dcache.xdr;
public interface RpcAuth extends XdrAble {
/**
* Get the authentication flavor. The rfc 1831 defines the following flavors:
* <pre>
* AUTH_NONE = 0
* AUTH_SYS = 1
* AUTH_SHORT = 2
* </pre>
*
* @return auth flavor.
*/
int type();
/**
* Get authentication verified corresponding to this credentials.
* In case of AUTH_NONE or AUTH_SYS the verifier is empty. Some other
* auth flavors may have non empty verifies ( RPCGSS_SEC contains the CRC
* of RPC header ).
*
* @return verifier.
*/
RpcAuthVerifier getVerifier();
}
......@@ -17,12 +17,14 @@
package org.dcache.xdr;
import java.io.IOException;
import java.util.logging.Logger;
public class RpcAuthTypeNone implements RpcAuth, XdrAble {
private final int _type = RpcAuthType.NONE;
private byte[] body;
private RpcAuthVerifier _verifier = new RpcAuthVerifier(RpcAuthType.NONE, new byte[0]);
private final static Logger _log = Logger.getLogger(RpcAuthTypeNone.class.getName());
......@@ -34,19 +36,27 @@ public class RpcAuthTypeNone implements RpcAuth, XdrAble {
this.body = body;
}
@Override
public int type() {
return _type;
}
@Override
public void xdrDecode(XdrDecodingStream xdr) {
public RpcAuthVerifier getVerifier() {
return _verifier;
}
@Override
public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException {
body = xdr.xdrDecodeDynamicOpaque();
_verifier = new RpcAuthVerifier(xdr);
}
@Override
public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException {
public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException {
xdr.xdrEncodeInt(_type);
xdr.xdrEncodeDynamicOpaque(body);
_verifier.xdrEncode(xdr);
}
}
......@@ -17,12 +17,14 @@
package org.dcache.xdr;
import java.io.IOException;
import java.util.logging.Logger;
import java.util.Arrays;
public class RpcAuthTypeUnix implements RpcAuth, XdrAble {
private final int _type = RpcAuthType.UNIX;
private RpcAuthVerifier _verifier = new RpcAuthVerifier(RpcAuthType.NONE, new byte[0]);
private int _len;
private int _uid;
......@@ -43,7 +45,7 @@ public class RpcAuthTypeUnix implements RpcAuth, XdrAble {
_machine = machine;
}
public void xdrDecode(XdrDecodingStream xdr) {
public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException {
_len = xdr.xdrDecodeInt();
_stamp = xdr.xdrDecodeInt();
......@@ -51,12 +53,19 @@ public class RpcAuthTypeUnix implements RpcAuth, XdrAble {
_uid = xdr.xdrDecodeInt();
_gid = xdr.xdrDecodeInt();
_gids = xdr.xdrDecodeIntVector();
_verifier.xdrDecode(xdr);
}
@Override
public int type() {
return _type;
}
@Override
public RpcAuthVerifier getVerifier() {
return _verifier;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
......@@ -70,7 +79,7 @@ public class RpcAuthTypeUnix implements RpcAuth, XdrAble {
}
@Override
public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException {
public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException {
xdr.xdrEncodeInt(_type);
xdr.xdrEncodeInt(_len);
xdr.xdrEncodeInt(_stamp);
......@@ -78,6 +87,7 @@ public class RpcAuthTypeUnix implements RpcAuth, XdrAble {
xdr.xdrEncodeInt(_uid);
xdr.xdrEncodeInt(_gid);
xdr.xdrEncodeIntVector(_gids);
_verifier.xdrEncode(xdr);
}
public int uid() {
......
/*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program (see the file COPYING.LIB for more
* details); if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.dcache.xdr;
import java.io.IOException;
/**
* Authentication verifier. Depending of status of credentials the content may
* change ( for example, in case of RPCGSS_SEC contains the checksum of RPC header).
*/
public class RpcAuthVerifier implements XdrAble {
private int _type;
private byte[] _body;
public RpcAuthVerifier(int type, byte[] body) {
_type = type;
_body = body;
}
public RpcAuthVerifier(XdrDecodingStream xdr) throws OncRpcException, IOException {
xdrDecode(xdr);
}
public int getType() {
return _type;
}
public void xdrDecode(XdrDecodingStream xdr) throws OncRpcException, IOException {
_type = xdr.xdrDecodeInt();
_body = xdr.xdrDecodeDynamicOpaque();
}
public void xdrEncode(XdrEncodingStream xdr) throws OncRpcException, IOException {
xdr.xdrEncodeInt(_type);
xdr.xdrEncodeDynamicOpaque(_body);
}
}
......@@ -64,11 +64,6 @@ public class RpcCall {
*/
private RpcAuth _cred;
/**
* Authentication verifier.
*/
private RpcAuth _verf;
/**
* RPC call transport.
*/
......@@ -79,11 +74,10 @@ public class RpcCall {
*/
private final Xdr _xdr;
public RpcCall(int prog, int ver, RpcAuth auth, RpcAuth verif, XdrTransport transport) {
public RpcCall(int prog, int ver, RpcAuth cred, XdrTransport transport) {
_prog = prog;
_version = ver;
_cred = auth;
_verf = verif;
_cred = cred;
_transport = transport;
_xdr = new Xdr(Xdr.MAX_XDR_SIZE);
}
......@@ -100,34 +94,7 @@ public class RpcCall {
_version = xdr.xdrDecodeInt();
_proc = xdr.xdrDecodeInt();
int authType = xdr.xdrDecodeInt();
_log.log(Level.FINEST, "Auth type: {0}", authType);
switch (authType) {
case RpcAuthType.UNIX:
_cred = new RpcAuthTypeUnix();
break;
case RpcAuthType.NONE:
_cred = new RpcAuthTypeNone();
break;
default:
throw new RpcAuthMissmatch(RpcAuthStat.AUTH_FAILED);
}
_cred.xdrDecode(xdr);
authType = xdr.xdrDecodeInt();
_log.log(Level.FINEST, "Auth Verifier type: {0}", authType);
switch (authType) {
case RpcAuthType.UNIX:
_verf = new RpcAuthTypeUnix();
break;
case RpcAuthType.NONE:
_verf = new RpcAuthTypeNone();
break;
default:
throw new RpcAuthMissmatch(RpcAuthStat.AUTH_FAILED);
}
_verf.xdrDecode(xdr);
_cred = RpcCredential.decode(xdr);
}
/**
......@@ -153,14 +120,10 @@ public class RpcCall {
return _proc;
}
public RpcAuth getAuth() {
public RpcAuth getCredential() {
return _cred;
}
public RpcAuth getAuthVerf() {
return _verf;
}
/**
* Get RPC {@XdrTransport} used by this call.
* @return transport
......@@ -178,7 +141,6 @@ public class RpcCall {
sb.append("Version : ").append(_version).append("\n");
sb.append("Procedure: ").append(_proc).append("\n");
sb.append("cred : ").append(_cred).append("\n");
sb.append("verf : ").append(_verf).append("\n");
return sb.toString();
}
......@@ -200,7 +162,7 @@ public class RpcCall {
xdr.beginEncoding();
replyMessage.xdrEncode(_xdr);
xdr.xdrEncodeInt(RpcReplyStatus.MSG_ACCEPTED);
getAuthVerf().xdrEncode(xdr);
_cred.getVerifier().xdrEncode(xdr);
xdr.xdrEncodeInt(state);
reply.xdrEncode(xdr);
xdr.endEncoding();
......@@ -290,7 +252,6 @@ public class RpcCall {
_xdr.xdrEncodeInt(_version);
_xdr.xdrEncodeInt(procedure);
_cred.xdrEncode(_xdr);
_verf.xdrEncode(_xdr);
args.xdrEncode(_xdr);
_xdr.endEncoding();
......
/*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program (see the file COPYING.LIB for more
* details); if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.dcache.xdr;
import java.io.IOException;
/**
* The RPC call message has two authentication fields - the credential and verifier.
* The verifier may change it's value depending on state of credential (RPCGSS_SEC).
* A reply uses only verifier.
*/
public class RpcCredential {
private RpcCredential() {}
public static RpcAuth decode(XdrDecodingStream xdr) throws OncRpcException, IOException {
int authType = xdr.xdrDecodeInt();
RpcAuth credential;
switch (authType) {
case RpcAuthType.UNIX:
credential = new RpcAuthTypeUnix();
break;
case RpcAuthType.NONE:
credential = new RpcAuthTypeNone();
break;
default:
throw new RpcAuthMissmatch(RpcAuthStat.AUTH_FAILED);
}
credential.xdrDecode(xdr);
return credential;
}
}
......@@ -35,7 +35,7 @@ public class SimpleRpcClient {
XdrTransport transport = rpcClient.connect();
RpcAuth auth = new RpcAuthTypeNone();
RpcCall call = new RpcCall(100017, 1, auth, auth, transport);
RpcCall call = new RpcCall(100017, 1, auth, transport);
/*
* call PROC_NULL (ping)
......
......@@ -25,6 +25,7 @@ import java.util.logging.Logger;
import org.dcache.xdr.IpProtocolType;
import org.dcache.xdr.OncRpcClient;
import org.dcache.xdr.OncRpcException;
import org.dcache.xdr.RpcAuth;
import org.dcache.xdr.RpcAuthTypeNone;
import org.dcache.xdr.RpcCall;
import org.dcache.xdr.XdrTransport;
......@@ -32,14 +33,16 @@ import org.dcache.xdr.XdrTransport;
public class GenericPortmapClient implements OncPortmapClient {
private final static Logger _log = Logger.getLogger(GenericPortmapClient.class.getName());
private final RpcAuthTypeNone _auth = new RpcAuthTypeNone();
private final RpcAuth _auth = new RpcAuthTypeNone();
private final OncPortmapClient _portmapClient;
public GenericPortmapClient(XdrTransport transport) {
OncPortmapClient portmapClient = new RpcbindV4Client(new RpcCall(100000, 4, _auth, _auth, transport));
OncPortmapClient portmapClient = new RpcbindV4Client(new RpcCall(100000, 4,
_auth, transport));
if( !portmapClient.ping() ) {
portmapClient = new PortmapV2Client( new RpcCall(100000, 2, _auth, _auth, transport) );
portmapClient = new PortmapV2Client( new RpcCall(100000, 2,
_auth, transport) );
if(!portmapClient.ping()) {
// FIXME: return correct exception
throw new IllegalStateException("portmap service not available");
......
......@@ -52,7 +52,7 @@ public class OncRpcEmbeddedPortmap {
/* check for version 2, 3 and 4 */
for (int i = 2; i < 5; i++) {
RpcCall call = new RpcCall(OncRpcPortmap.PORTMAP_PROGRAMM,
i, _auth, _auth, transport);
i, _auth, transport);
try {
call.call(0, XdrVoid.XDR_VOID, XdrVoid.XDR_VOID, 2000);
} catch (OncRpcException ex) {}
......
Supports Markdown
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