
org.globus.ftp.extended.GridFTPControlChannel Maven / Gradle / Ivy
The newest version!
/*
* Copyright 1999-2006 University of Chicago
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.globus.ftp.extended;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.globus.ftp.GridFTPSession;
import org.globus.ftp.exception.ServerException;
import org.globus.ftp.exception.UnexpectedReplyCodeException;
import org.globus.ftp.exception.FTPReplyParseException;
import org.globus.ftp.vanilla.Reply;
import org.globus.ftp.vanilla.FTPControlChannel;
import org.globus.ftp.vanilla.Command;
import org.globus.common.ChainedIOException;
import org.globus.gsi.gssapi.auth.Authorization;
import org.globus.gsi.gssapi.auth.GSSAuthorization;
import org.globus.gsi.gssapi.auth.HostAuthorization;
import org.globus.gsi.gssapi.auth.AuthorizationException;
import org.globus.gsi.gssapi.GSSConstants;
import org.gridforum.jgss.ExtendedGSSManager;
import org.ietf.jgss.GSSManager;
import org.ietf.jgss.GSSContext;
import org.ietf.jgss.GSSException;
import org.ietf.jgss.GSSCredential;
import org.ietf.jgss.GSSName;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/** GridFTP control channel, unlike the vanilla control channel,
uses GSI autentication.
**/
public class GridFTPControlChannel extends FTPControlChannel {
private static Log logger =
LogFactory.getLog(GridFTPControlChannel.class.getName());
protected static final int TIMEOUT = 120000;
//maybe this is useless
protected GSSCredential credentials = null;
protected Authorization authorization =
HostAuthorization.getInstance();
protected int protection = GridFTPSession.PROTECTION_PRIVATE;
public GridFTPControlChannel(String host, int port) {
super(host,port);
}
public GridFTPControlChannel(InputStream in, OutputStream out) {
super(in, out);
}
/**
* Sets data channel protection level.
*
* @param protection should be
* {@link GridFTPSession#PROTECTION_CLEAR CLEAR},
* {@link GridFTPSession#PROTECTION_SAFE SAFE}, or
* {@link GridFTPSession#PROTECTION_PRIVATE PRIVATE}, or
* {@link GridFTPSession#PROTECTION_CONFIDENTIAL CONFIDENTIAL}.
**/
public void setProtection(int protection) {
switch(protection) {
case GridFTPSession.PROTECTION_CLEAR:
throw new IllegalArgumentException("Unsupported protection: " +
protection);
case GridFTPSession.PROTECTION_SAFE:
case GridFTPSession.PROTECTION_CONFIDENTIAL:
case GridFTPSession.PROTECTION_PRIVATE:
break;
default:
throw new IllegalArgumentException("Bad protection: " +
protection);
}
this.protection = protection;
}
/**
* Returns control channel protection level.
*
* @return control channel protection level:
* {@link GridFTPSession#PROTECTION_CLEAR CLEAR},
* {@link GridFTPSession#PROTECTION_SAFE SAFE}, or
* {@link GridFTPSession#PROTECTION_PRIVATE PRIVATE}, or
* {@link GridFTPSession#PROTECTION_CONFIDENTIAL CONFIDENTIAL}.
**/
public int getProtection() {
return this.protection;
}
/**
* Sets authorization method for the control channel.
*
* @param authorization authorization method.
*/
public void setAuthorization(Authorization authorization) {
this.authorization = authorization;
}
/**
* Returns authorization method for the control channel.
*
* @return authorization method performed on the control channel.
*/
public Authorization getAuthorization() {
return this.authorization;
}
/**
* Performs authentication with specified user credentials.
*
* @param credential user credentials to use.
* @throws IOException on i/o error
* @throws ServerException on server refusal or faulty server behavior
*/
public void authenticate(GSSCredential credential)
throws IOException, ServerException {
authenticate(credential, null);
}
/**
* Performs authentication with specified user credentials and
* a specific username (assuming the user dn maps to the passed username).
*
* @param credential user credentials to use.
* @param username specific username to authenticate as.
* @throws IOException on i/o error
* @throws ServerException on server refusal or faulty server behavior
*/
public void authenticate(GSSCredential credential,
String username)
throws IOException, ServerException {
setCredentials( credential );
write(new Command("AUTH", "GSSAPI"));
Reply reply0 = null;
try {
reply0 = read();
} catch (FTPReplyParseException rpe) {
throw ServerException.embedFTPReplyParseException(
rpe,
"Received faulty reply to AUTH GSSAPI");
}
if (! Reply.isPositiveIntermediate(reply0)) {
close();
throw ServerException.embedUnexpectedReplyCodeException(
new UnexpectedReplyCodeException(reply0),
"Server refused GSSAPI authentication.");
}
GSSManager manager = ExtendedGSSManager.getInstance();
GSSContext context = null;
GridFTPOutputStream gssout = null;
GridFTPInputStream gssin = null;
try {
String host = this.socket.getInetAddress().getHostAddress();
GSSName expectedName = null;
if (this.authorization instanceof GSSAuthorization) {
GSSAuthorization auth = (GSSAuthorization)this.authorization;
expectedName = auth.getExpectedName(credential, host);
}
context = manager.createContext(expectedName,
GSSConstants.MECH_OID,
credential,
GSSContext.DEFAULT_LIFETIME);
context.requestCredDeleg(true);
context.requestConf(this.protection ==
GridFTPSession.PROTECTION_PRIVATE);
gssout = new GridFTPOutputStream(ftpOut, context);
gssin = new GridFTPInputStream(rawFtpIn, context);
byte [] inToken = new byte[0];
byte [] outToken = null;
while( !context.isEstablished() ) {
outToken = context.initSecContext(inToken, 0, inToken.length);
if (outToken != null) {
gssout.writeHandshakeToken(outToken);
}
if (!context.isEstablished()) {
inToken = gssin.readHandshakeToken();
}
}
} catch (GSSException e) {
throw new ChainedIOException("Authentication failed", e);
}
if (this.authorization != null) {
try {
this.authorization.authorize(context, host);
} catch (AuthorizationException e) {
throw new ChainedIOException("Authorization failed", e);
}
}
// this should be authentication success msg (plain)
// 234 (ok, no further data required)
Reply reply1 = null;
try {
reply1 = read();
} catch (FTPReplyParseException rpe) {
throw ServerException.embedFTPReplyParseException(
rpe,
"Received faulty reply to authentication");
}
if ( ! Reply.isPositiveCompletion(reply1)) {
close();
throw ServerException.embedUnexpectedReplyCodeException(
new UnexpectedReplyCodeException(reply1),
"GSSAPI authentication failed.");
}
// enter secure mode - send MIC commands
setInputStream(gssin);
setOutputStream(gssout);
//from now on, the commands and replies
//are protected and pass through gsi wrapped socket
write(new Command("USER",
(username == null) ? ":globus-mapping:" : username));
Reply reply2 = null;
try {
reply2 = read();
} catch (FTPReplyParseException rpe) {
throw ServerException.embedFTPReplyParseException(
rpe,
"Received faulty reply to USER command");
}
if (Reply.isPositiveCompletion(reply2) ||
Reply.isPositiveIntermediate(reply2)) {
// wu-gsiftp sends intermediate code while
// gssftp send completion reply code
} else {
close();
throw ServerException.embedUnexpectedReplyCodeException(
new UnexpectedReplyCodeException(reply2),
"User authorization failed.");
}
write(new Command("PASS", "dummy"));
Reply reply3 = null;
try {
reply3=read();
} catch (FTPReplyParseException rpe) {
throw ServerException.embedFTPReplyParseException(
rpe,
"Received faulty reply to PASS command");
}
if (!Reply.isPositiveCompletion(reply3)) {
close();
throw ServerException.embedUnexpectedReplyCodeException(
new UnexpectedReplyCodeException(reply3),
"Bad password.");
}
}
protected void setCredentials( GSSCredential credentials ) {
this.credentials = credentials;
}
protected GSSCredential getCredentials() {
return credentials;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy