Search in sources :

Example 1 with ParseException

use of org.dcache.xrootd.util.ParseException in project dcache by dCache.

the class XrootdPoolRequestHandler method doOnOpen.

/**
 * Obtains the right mover channel using an opaque token in the request. The mover channel is
 * wrapped by a file descriptor. The file descriptor is stored for subsequent access.
 * <p>
 * In the case that this is a write request as destination in a third party copy, a third-party
 * client is started.  The client issues login, open and read requests to the source server, and
 * writes the responses to the file descriptor.
 * <p>
 * The third-party client also sends a sync response back to the client when the transfer has
 * completed.
 */
@Override
protected XrootdResponse<OpenRequest> doOnOpen(ChannelHandlerContext ctx, OpenRequest msg) throws XrootdException {
    try {
        Map<String, String> opaqueMap = getOpaqueMap(msg.getOpaque());
        UUID uuid = getUuid(opaqueMap);
        if (uuid == null) {
            _log.info("Request to open {} contains no UUID.", msg.getPath());
            throw new XrootdException(kXR_NotAuthorized, "Request lacks the " + UUID_PREFIX + " property.");
        }
        enforceClientTlsIfDestinationRequiresItForTpc(opaqueMap);
        NettyTransferService<XrootdProtocolInfo>.NettyMoverChannel file = _server.openFile(uuid, false);
        if (file == null) {
            _log.info("No mover found for {} with UUID {}.", msg.getPath(), uuid);
            return redirectToDoor(ctx, msg, () -> {
                throw new XrootdException(kXR_NotAuthorized, UUID_PREFIX + " is no longer valid.");
            });
        }
        /*
             *  Stop any timer in case this is a reconnect.
             */
        _server.cancelReconnectTimeoutForMover(uuid);
        _log.debug("doOnOpen, called cancel on reconnect timers for {}", uuid);
        XrootdProtocolInfo protocolInfo = file.getProtocolInfo();
        try {
            FileDescriptor descriptor;
            boolean isWrite = file.getIoMode().contains(StandardOpenOption.WRITE);
            if (msg.isNew() && !isWrite) {
                throw new XrootdException(kXR_FileNotOpen, "File exists.");
            } else if (msg.isDelete() && !isWrite) {
                throw new XrootdException(kXR_Unsupported, "File exists.");
            /*
                     *  Some clients express only kXR_delete when then intend to write
                     *  so we need to consider delete as a write request here.
                     */
            } else if ((msg.isNew() || msg.isReadWrite() || msg.isDelete()) && isWrite) {
                boolean posc = (msg.getOptions() & kXR_posc) == kXR_posc || protocolInfo.getFlags().contains(XrootdProtocolInfo.Flags.POSC);
                if (opaqueMap.containsKey("tpc.src")) {
                    _log.debug("Request to open {} is as third-party destination.", msg);
                    XrootdTpcInfo tpcInfo = new XrootdTpcInfo(opaqueMap);
                    tpcInfo.setDelegatedProxy(protocolInfo.getDelegatedCredential());
                    tpcInfo.setUid(protocolInfo.getTpcUid());
                    tpcInfo.setGid(protocolInfo.getTpcGid());
                    descriptor = new TpcWriteDescriptor(file, posc, ctx, _server, opaqueMap.get("org.dcache.xrootd.client"), tpcInfo, tlsSessionInfo);
                } else {
                    descriptor = new WriteDescriptor(file, posc);
                }
            } else {
                descriptor = new ReadDescriptor(file);
            }
            FileStatus stat = msg.isRetStat() ? stat(file) : null;
            int fd = addDescriptor(descriptor);
            _redirectingDoor = protocolInfo.getDoorAddress();
            file = null;
            _hasOpenedFiles = true;
            return new OpenResponse(msg, fd, null, null, stat);
        } finally {
            if (file != null) {
                file.release();
            }
        }
    } catch (ParseException e) {
        throw new XrootdException(kXR_ArgInvalid, e.getMessage());
    } catch (IOException e) {
        throw new XrootdException(kXR_IOError, e.getMessage());
    }
}
Also used : NettyTransferService(org.dcache.pool.movers.NettyTransferService) FileStatus(org.dcache.xrootd.util.FileStatus) XrootdProtocolInfo(org.dcache.vehicles.XrootdProtocolInfo) IOException(java.io.IOException) TpcWriteDescriptor(org.dcache.xrootd.tpc.TpcWriteDescriptor) XrootdTpcInfo(org.dcache.xrootd.tpc.XrootdTpcInfo) OpenResponse(org.dcache.xrootd.protocol.messages.OpenResponse) ParseException(org.dcache.xrootd.util.ParseException) UUID(java.util.UUID) XrootdException(org.dcache.xrootd.core.XrootdException) TpcWriteDescriptor(org.dcache.xrootd.tpc.TpcWriteDescriptor)

Example 2 with ParseException

use of org.dcache.xrootd.util.ParseException in project xrootd4j by dCache.

the class XrootdAuthorizationHandler method authorize.

/**
 * Performs authorization check and path mapping.
 *
 * @param ctx The ChannelHandlerContext
 * @param request The xrootd message
 * @param neededPerm The permission level that is required for the operation
 * @param path The path to which access is requested
 * @param opaque Opaque data sent with the request
 * @return The path to which access is granted.
 * @throws XrootdException if the request is denied
 */
private String authorize(ChannelHandlerContext ctx, XrootdRequest request, FilePerm neededPerm, String path, String opaque) throws XrootdException {
    try {
        InetSocketAddress destinationAddress = getDestinationAddress();
        InetSocketAddress sourceAddress = getSourceAddress();
        AuthorizationHandler handler = _authorizationFactory.createHandler(ctx);
        /*
             *  check to see if we need TLS.
             */
        if (handler instanceof RequiresTLS && !isTLSOn(ctx)) {
            throw new XrootdException(kXR_Unsupported, "TLS is required " + "for " + _authorizationFactory.getName());
        }
        return handler.authorize(request.getSubject(), destinationAddress, sourceAddress, path, OpaqueStringParser.getOpaqueMap(opaque), request.getRequestId(), neededPerm);
    } catch (GeneralSecurityException e) {
        throw new XrootdException(kXR_NotAuthorized, "Authorization check failed: " + e.getMessage());
    } catch (SecurityException e) {
        throw new XrootdException(kXR_NotAuthorized, "Permission denied: " + e.getMessage());
    } catch (ParseException e) {
        throw new XrootdException(kXR_InvalidRequest, "Invalid opaque data: " + e.getMessage());
    }
}
Also used : AuthorizationHandler(org.dcache.xrootd.plugins.AuthorizationHandler) InetSocketAddress(java.net.InetSocketAddress) GeneralSecurityException(java.security.GeneralSecurityException) RequiresTLS(org.dcache.xrootd.security.RequiresTLS) GeneralSecurityException(java.security.GeneralSecurityException) ParseException(org.dcache.xrootd.util.ParseException)

Example 3 with ParseException

use of org.dcache.xrootd.util.ParseException in project xrootd4j by dCache.

the class AbstractClientRequestHandler method doOnAttnResponse.

protected void doOnAttnResponse(ChannelHandlerContext ctx, InboundAttnResponse response) throws XrootdException {
    String message;
    switch(response.getActnum()) {
        case kXR_asyncab:
            /*
                 * The client should immediately disconnect (i.e., close
                 * the socket connection) from the server and abort
                 * further execution.
                 */
            message = "Received abort from source server: " + response.getMessage();
            throw new XrootdException(kXR_ServerError, message);
        case kXR_asyncms:
            /*
                 * The client should send the indicated message to the console.
                 * The parameters contain the message text.
                 */
            LOGGER.info("Received from source server: {}.", response.getMessage());
            break;
        case kXR_asyncgo:
        /*
                 * The client may start sending requests. This code is sent to
                 * cancel the effects of a previous kXR_asyncwt code.
                 *
                 * Fall through to handle future cancellation.
                 */
        case kXR_asynresp:
            /*
                 * The client should use the response data in the message to
                 * complete the request associated with the indicated streamid.
                 *
                 * For this to be valid, there has to be a waiting request
                 * for this pipeline.  If future is null here, we skip it.
                 */
            synchronized (this) {
                if (future != null) {
                    future.cancel(true);
                    doOnAsynResponse(ctx, response);
                    future = null;
                }
            }
            break;
        case kXR_asyncwt:
            /*
                 * The client should hold off sending any new requests until the
                 * indicated amount of time has passed or until receiving a
                 * kXR_asyncgo action code.
                 */
            doOnWaitResponse(ctx, response);
            break;
        case kXR_asyncrd:
        /*
                 * The client should immediately disconnect (i.e., close the
                 * socket connection) and reconnect to the indicated server.
                 *
                 * NOTE:  without opaque data in the parameters, this redirect
                 * probably will not work here, but we will allow this to fail
                 * downstream.
                 *
                 * Fall through to redirect.
                 */
        case kXR_asyncdi:
            /*
                 * The client should immediately disconnect
                 * (i.e., close the socket connection) from the server.
                 * Parameters indicate when a reconnect may be attempted.
                 *
                 * This is essentially a delayed redirect to the same
                 * endpoint.
                 */
            try {
                doOnRedirectResponse(ctx, new InboundRedirectResponse(response));
            } catch (ParseException e) {
                throw new XrootdException(kXR_InvalidRequest, "bad redirect data from kXR_asyncdi");
            }
            break;
        case kXR_asyncav:
        /*
                 * The file or file(s) the client previously
                 * requested to be prepared are now available.
                 *
                 * We do not issue prepare requests.  NR.
                 */
        case kXR_asynunav:
            /*
                 * The file or file(s) the client previously requested to
                 * be prepared cannot be made available.
                 *
                 * We do not issue prepare requests.  NR.
                 */
            throw new XrootdException(kXR_Unsupported, "tpc client does not support this option: " + response.getActnum());
        default:
            throw new XrootdException(kXR_ArgInvalid, "unrecognized kXR_attn action: " + response.getActnum());
    }
}
Also used : ParseException(org.dcache.xrootd.util.ParseException) XrootdException(org.dcache.xrootd.core.XrootdException) InboundRedirectResponse(org.dcache.xrootd.tpc.protocol.messages.InboundRedirectResponse)

Example 4 with ParseException

use of org.dcache.xrootd.util.ParseException in project xrootd4j by dCache.

the class XrootdClientDecoder method decode.

@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) {
    ChannelId id = ctx.channel().id();
    int readable = in.readableBytes();
    if (readable < SERVER_RESPONSE_LEN) {
        return;
    }
    int pos = in.readerIndex();
    int headerFrameLength = in.getInt(pos + 4);
    if (headerFrameLength < 0) {
        LOGGER.error("Decoder {}, channel {}: received illegal " + "frame length in " + "xrootd header: {}." + " Closing channel.", sourceUrn, id, headerFrameLength);
        ctx.channel().close();
        return;
    }
    int length = SERVER_RESPONSE_LEN + headerFrameLength;
    if (readable < length) {
        return;
    }
    ByteBuf frame = in.readSlice(length);
    int requestId = client.getExpectedResponse();
    try {
        switch(frame.getUnsignedShort(2)) {
            case kXR_error:
                LOGGER.debug("Decoder {}, channel {}: adding error response.", sourceUrn, id);
                out.add(new InboundErrorResponse(frame));
                return;
            case kXR_wait:
                LOGGER.debug("Decoder {}, channel {}: adding wait response.", sourceUrn, id);
                out.add(new InboundWaitResponse(frame, requestId));
                return;
            case kXR_waitresp:
                LOGGER.debug("Decoder {}, channel {}: adding waitresp response.", sourceUrn, id);
                out.add(new InboundWaitRespResponse(frame, requestId));
                return;
            case kXR_redirect:
                LOGGER.debug("Decoder {}, channel {}: adding redirect response.", sourceUrn, id);
                out.add(new InboundRedirectResponse(frame, requestId));
                return;
            case kXR_attn:
                LOGGER.debug("Decoder {}, channel {}: adding attn response.", sourceUrn, id);
                out.add(new InboundAttnResponse(frame, requestId));
                return;
        }
        switch(requestId) {
            case kXR_handshake:
                LOGGER.debug("Decoder {}, channel {}: adding handshake response.", sourceUrn, id);
                out.add(new InboundHandshakeResponse(frame));
                break;
            case kXR_protocol:
                LOGGER.debug("Decoder {}, channel {}: adding protocol response.", sourceUrn, id);
                out.add(new InboundProtocolResponse(frame));
                break;
            case kXR_login:
                LOGGER.debug("Decoder {}, channel {}: adding login response.", sourceUrn, id);
                out.add(new InboundLoginResponse(frame));
                break;
            case kXR_auth:
                LOGGER.debug("Decoder {}, channel {}: adding authentication response.", sourceUrn, id);
                out.add(new InboundAuthenticationResponse(frame));
                break;
            case kXR_open:
                LOGGER.debug("Decoder {}, channel {}: adding open response.", sourceUrn, id);
                out.add(new InboundOpenReadOnlyResponse(frame));
                break;
            case kXR_read:
                LOGGER.debug("Decoder {}, channel {}: adding read response.", sourceUrn, id);
                out.add(new InboundReadResponse(frame));
                break;
            case kXR_query:
                LOGGER.debug("Decoder {}, channel {}: adding query response.", sourceUrn, id);
                out.add(new InboundChecksumResponse(frame));
                break;
            case kXR_close:
                LOGGER.debug("Decoder {}, channel {}: adding close response.", sourceUrn, id);
                out.add(new InboundCloseResponse(frame));
                break;
            case kXR_endsess:
                LOGGER.debug("Decoder {}, channel {}: adding endsess response.", sourceUrn, id);
                out.add(new InboundEndSessionResponse(frame));
                break;
            default:
                LOGGER.debug("Decoder {}, channel {}, received incorrect " + "response of request type {}.", sourceUrn, id, requestId);
                throw new XrootdException(kXR_error, "received incorrect response type.");
        }
    } catch (ParseException | XrootdException e) {
        LOGGER.error("Decoder {}, channel {}: error for request type {}: {}. " + "Closing channel.", requestId, id, e.getMessage());
        client.setError(e);
        client.shutDown(ctx);
    }
}
Also used : InboundReadResponse(org.dcache.xrootd.tpc.protocol.messages.InboundReadResponse) InboundProtocolResponse(org.dcache.xrootd.tpc.protocol.messages.InboundProtocolResponse) InboundCloseResponse(org.dcache.xrootd.tpc.protocol.messages.InboundCloseResponse) InboundChecksumResponse(org.dcache.xrootd.tpc.protocol.messages.InboundChecksumResponse) InboundErrorResponse(org.dcache.xrootd.tpc.protocol.messages.InboundErrorResponse) InboundWaitResponse(org.dcache.xrootd.tpc.protocol.messages.InboundWaitResponse) InboundHandshakeResponse(org.dcache.xrootd.tpc.protocol.messages.InboundHandshakeResponse) InboundLoginResponse(org.dcache.xrootd.tpc.protocol.messages.InboundLoginResponse) ChannelId(io.netty.channel.ChannelId) ByteBuf(io.netty.buffer.ByteBuf) InboundAttnResponse(org.dcache.xrootd.tpc.protocol.messages.InboundAttnResponse) InboundRedirectResponse(org.dcache.xrootd.tpc.protocol.messages.InboundRedirectResponse) InboundWaitRespResponse(org.dcache.xrootd.tpc.protocol.messages.InboundWaitRespResponse) InboundEndSessionResponse(org.dcache.xrootd.tpc.protocol.messages.InboundEndSessionResponse) InboundOpenReadOnlyResponse(org.dcache.xrootd.tpc.protocol.messages.InboundOpenReadOnlyResponse) ParseException(org.dcache.xrootd.util.ParseException) XrootdException(org.dcache.xrootd.core.XrootdException) InboundAuthenticationResponse(org.dcache.xrootd.tpc.protocol.messages.InboundAuthenticationResponse)

Example 5 with ParseException

use of org.dcache.xrootd.util.ParseException in project xrootd4j by dCache.

the class InboundRedirectResponse method parseRedirectString.

private void parseRedirectString(String redirect) throws ParseException {
    if (port == -1) {
        try {
            url = new URL(redirect);
        } catch (MalformedURLException e) {
            throw new ParseException("redirect : " + e.getMessage());
        }
    } else {
        int index = redirect.indexOf("?");
        if (index == -1) {
            host = redirect;
        } else {
            host = redirect.substring(0, index);
            redirect = redirect.substring(index);
            while (redirect.startsWith("?")) {
                redirect = redirect.substring(1);
            }
            if (redirect.contains("=")) {
                String[] parts = redirect.split("[?]");
                opaque = parts[0];
                if (parts.length > 1) {
                    token = parts[1];
                }
            } else {
                opaque = "";
                token = redirect;
            }
        }
    }
}
Also used : MalformedURLException(java.net.MalformedURLException) ParseException(org.dcache.xrootd.util.ParseException) URL(java.net.URL)

Aggregations

ParseException (org.dcache.xrootd.util.ParseException)7 XrootdException (org.dcache.xrootd.core.XrootdException)5 InetSocketAddress (java.net.InetSocketAddress)2 UUID (java.util.UUID)2 InboundRedirectResponse (org.dcache.xrootd.tpc.protocol.messages.InboundRedirectResponse)2 CacheException (diskCacheV111.util.CacheException)1 FileExistsCacheException (diskCacheV111.util.FileExistsCacheException)1 FileIsNewCacheException (diskCacheV111.util.FileIsNewCacheException)1 FileNotFoundCacheException (diskCacheV111.util.FileNotFoundCacheException)1 FsPath (diskCacheV111.util.FsPath)1 NotFileCacheException (diskCacheV111.util.NotFileCacheException)1 PermissionDeniedCacheException (diskCacheV111.util.PermissionDeniedCacheException)1 TimeoutCacheException (diskCacheV111.util.TimeoutCacheException)1 ByteBuf (io.netty.buffer.ByteBuf)1 ChannelId (io.netty.channel.ChannelId)1 IOException (java.io.IOException)1 MalformedURLException (java.net.MalformedURLException)1 URL (java.net.URL)1 GeneralSecurityException (java.security.GeneralSecurityException)1 HashMap (java.util.HashMap)1