Skip to content

Commit

Permalink
dcap: Refactor javatunnel
Browse files Browse the repository at this point in the history
Motivation:

DCAP uses server socket factories to support different authentication schemes
(SSL, GSI, Kerberos). The current implementation mixes framing (base64 + newlines)
with encoding (GSI, etc), making reuse of the encoding part outside of the
javatunnel difficult.

Modification:

Refactored the javatunnel package such that the encoding and the framing are
separated. Rather than relying directly on the GSSAPI, the intermediate DssApi
abstraction is introduced. Is is structurally similar to GSSAPI, although much
simpler.

Result:

Future patches will introduce an implementation around GsiEngine, decoupling
gsidcap from the JGlobus GSI implementation. Future patches will update the
FTP doors to rely on the same DssApi, thus allowing the code to be reused.

Target: trunk
Require-notes: no
Require-book: no
Acked-by: Paul Millar <paul.millar@desy.de>
Patch: https://rb.dcache.org/r/8475/
  • Loading branch information
gbehrmann committed Aug 24, 2015
1 parent 14f23b2 commit 666b447
Show file tree
Hide file tree
Showing 32 changed files with 1,299 additions and 1,052 deletions.
Expand Up @@ -106,25 +106,6 @@ public TelnetStreamEngine( Socket socket ,
_writer = new TelnetOutputStreamWriter( _telnetOutputStream ) ;
_reader = new TelnetInputStreamReader( _telnetInputStream , _writer ) ;

try{
Method meth = socket.getClass().getMethod("verify");
boolean verified = (Boolean)meth.invoke(socket);
if (!verified) {
String hostAddress = (socket.getInetAddress()).getHostAddress();
socket.close();
throw new TelnetAuthenticationException("Host "+hostAddress+": Tunnel verification failed!" ) ;
}

meth = socket.getClass().getMethod("getSubject", new Class[0]);
Subject subject = (Subject) meth.invoke(socket);

setSubject(subject);

}catch(NoSuchMethodException nsm){
// nsm.printStackTrace();
// it's not a tunnel...still OK
}

if( _serverAuth != null ) {
doAuthentication();
}
Expand Down
26 changes: 26 additions & 0 deletions modules/cells/src/main/java/dmg/protocols/telnet/TunnelSocket.java
@@ -0,0 +1,26 @@
/* dCache - http://www.dcache.org/
*
* Copyright (C) 2015 Deutsches Elektronen-Synchrotron
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package dmg.protocols.telnet;

import javax.security.auth.Subject;

public interface TunnelSocket
{
Subject getSubject();
boolean verify();
}
25 changes: 12 additions & 13 deletions modules/cells/src/main/java/dmg/util/DummyStreamEngine.java
Expand Up @@ -12,7 +12,6 @@
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.net.Socket;
import java.nio.ByteBuffer;
Expand All @@ -21,6 +20,8 @@
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;

import dmg.protocols.telnet.TunnelSocket;

public class DummyStreamEngine implements StreamEngine
{
private final static Logger _logger =
Expand All @@ -35,25 +36,23 @@ public class DummyStreamEngine implements StreamEngine
private Reader _reader;
private Writer _writer;

public DummyStreamEngine(Socket socket)
public DummyStreamEngine(Socket socket) throws IOException
{
_socket = socket;

if (socket instanceof TunnelSocket) {
if (!((TunnelSocket) socket).verify()) {
String hostAddress = (socket.getInetAddress()).getHostAddress();
socket.close();
throw new IOException("Host " + hostAddress + ": Tunnel verification failed!");
}
setSubject(((TunnelSocket) socket).getSubject());
}

SocketChannel channel = _socket.getChannel();
if (channel != null) {
_channel = wrapChannel(channel);
}

try {
Method meth = _socket.getClass().getMethod("getSubject", new Class[0]);
Subject subject = (Subject)meth.invoke(_socket);

setSubject(subject);
} catch (NoSuchMethodException nsm) {

} catch (Exception e) {
_logger.warn("Failed to initialize user name in DummyStreamEngine", e);
}
}

public void setSubject(Subject subject)
Expand Down
21 changes: 0 additions & 21 deletions modules/javatunnel/src/main/java/javatunnel/Convertable.java

This file was deleted.

69 changes: 69 additions & 0 deletions modules/javatunnel/src/main/java/javatunnel/DssServerSocket.java
@@ -0,0 +1,69 @@
/* dCache - http://www.dcache.org/
*
* Copyright (C) 2015 Deutsches Elektronen-Synchrotron
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package javatunnel;

import javatunnel.dss.DssContextFactory;

import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;

class DssServerSocket extends ServerSocket
{
private final DssContextFactory _factory;

public DssServerSocket(DssContextFactory factory) throws IOException
{
super();
_factory = factory;
}

public DssServerSocket(int port, DssContextFactory factory) throws IOException
{
super(port);
_factory = factory;
}

public DssServerSocket(int port, int backlog, DssContextFactory factory) throws IOException
{
super(port, backlog);
_factory = factory;
}

public DssServerSocket(int port, int backlog, InetAddress bindAddr, DssContextFactory factory) throws IOException
{
super(port, backlog, bindAddr);
_factory = factory;
}

@Override
public Socket accept() throws IOException
{
if (isClosed()) {
throw new SocketException("Socket is closed");
}
if (!isBound()) {
throw new SocketException("Socket is not bound yet");
}
Socket s = new DssSocket(_factory);
implAccept(s);
return s;
}
}
@@ -0,0 +1,70 @@
/* dCache - http://www.dcache.org/
*
* Copyright (C) 2015 Deutsches Elektronen-Synchrotron
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package javatunnel;

import javatunnel.dss.DssContextFactory;

import javax.net.ServerSocketFactory;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.net.InetAddress;
import java.net.ServerSocket;

public class DssServerSocketCreator extends ServerSocketFactory
{
private final DssContextFactory factory;

public DssServerSocketCreator(String[] args) throws Throwable
{
Class<? extends DssContextFactory> factory = Class.forName(args[0]).asSubclass(DssContextFactory.class);
Constructor<? extends DssContextFactory> cc = factory.getConstructor(String.class);
try {
this.factory = cc.newInstance(args[1]);
} catch (InvocationTargetException e) {
throw e.getCause();
}
}

@Override
public ServerSocket createServerSocket(int port) throws IOException
{
return new DssServerSocket(port, factory);
}

@Override
public ServerSocket createServerSocket() throws IOException
{
return new DssServerSocket(factory);
}

@Override
public ServerSocket createServerSocket(int port, int backlog)
throws IOException
{
return new DssServerSocket(port, backlog, factory);
}

@Override
public ServerSocket createServerSocket(int port, int backlog, InetAddress ifAddress)
throws IOException
{
return new DssServerSocket(port, backlog, ifAddress, factory);
}
}

0 comments on commit 666b447

Please sign in to comment.