org.acplt.oncrpc.server.OncRpcServerAuthSchemes Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of remotetea-oncrpc Show documentation
Show all versions of remotetea-oncrpc Show documentation
The runtime environment for ONC/RPC programs, both client and server side.
/*
* Copyright (c) 2014, 2015
* NDE Netzdesign und -entwicklung AG, Hamburg, Germany
* All rights reserved.
*
* 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 LICENSE.txt for more
* details); if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.acplt.oncrpc.server;
import org.acplt.oncrpc.OncRpcAuthType;
/**
* Repository auf supported authentication schemes, which are intended to
* be provided by an ONC/RPC server.
*
* By default the authentication schemesnone, short
* and unix (system) are supported by ONC/RPC servers.
*
* This class is designed to be used internally by this package. Registration of custom
* authentication schemes will be available through a concrete instance of an implementation
* of an ONC/RPC server stub. Concrete authentication handler instances will be requested on demand
* with respect to the desired authentication type.
*
* @author Harald Wirths {@literal }
*
*/
final class OncRpcServerAuthSchemes {
/**
* Registers a custom authentication scheme to this authentication scheme repository.
*
* @param authenticationScheme A custom authentication scheme.
* @return true, if the passed authentication scheme has been added
* to the list of custom authentication schemes, false, if either
* nullhas been passed or there is already an authentication scheme
* registered for the authentication type of the passed one.
*/
boolean registerScheme(OncRpcServerAuthScheme authenticationScheme)
{
boolean registered = false;
/*
* We cancel the call, if the authentication type indicates either one of
* the standard schemes or one of the already registered custom schemes.
* But let's ensure, that the caller has passed a valid object.
*/
if ( authenticationScheme != null )
{
switch(authenticationScheme.getAuthenticationType())
{
case OncRpcAuthType.ONCRPC_AUTH_NONE:
case OncRpcAuthType.ONCRPC_AUTH_SHORT:
case OncRpcAuthType.ONCRPC_AUTH_UNIX:
/*
* A request to override a standard scheme is skipped.
*/
break;
default:
/*
* Now we look at the list of already registered schemes.
* If the list is still empty, the new authentication scheme
* is inserted as the first entry.
* If there is already a scheme with the same authentication type
* as the passed one, we skip the request.
* Otherwise we insert the new scheme with respect to the ordering.
*/
if ( this.head == null )
{
/*
* The passed authentication scheme gets the first custom authentication scheme.
*/
this.head = new Node(authenticationScheme);
}
else
{
Node actualNode = this.head;
Node predecessorNode = null;
/*
* Do we find an authentication scheme in the list
* with same authentication type?
*/
while ( actualNode != null )
{
if ( actualNode.scheme.getAuthenticationType() == authenticationScheme.getAuthenticationType() )
{
/*
* We are done.
*/
actualNode = null;
}
else if ( actualNode.scheme.getAuthenticationType() < authenticationScheme.getAuthenticationType() )
{
/*
* Let's continue with the next node.
* We remind the actual node, as it possibly
* will be the new predecessor node of the passed authentication scheme.
*/
predecessorNode = actualNode;
actualNode = actualNode.next;
}
else
{
/*
* The number of the authentication type of the actual node is greater than the
* one of the passed authentication scheme. With respect to the ordering of the list
* we found the successor node of the new authentication scheme. The reminded
* predecessor node will be the predecessor node of the passed authentication scheme,
* except the actual node is the head. Then the passed authentication scheme
* will be inserted at the head of the list.
*/
if ( actualNode == this.head )
{
predecessorNode = new Node(authenticationScheme);
predecessorNode.next = this.head;
this.head = predecessorNode;
}
else
{
predecessorNode.next = new Node(authenticationScheme);
predecessorNode.next.next = actualNode;
}
/*
* At this point the passed authentication scheme has been registered.
*/
registered = true;
}
}
}
}
}
return registered;
}
/**
* Delivers a new authentication handler with respect to the passed authentication type.
*
* @param desiredAuthenticationType The desired authentication type, the new authentication handler
* shall provide.
* @return null, if there either is no authentication scheme registered for the passed authentication type
* or the corresponding authentication scheme does not deliver a new authentication handler instance.
* Otherwise an authentication handler created by the corresponding authentication scheme is returned.
*/
OncRpcServerAuth getNewHandler(int desiredAuthenticationType)
{
OncRpcServerAuth authenticationHandler = null;
/*
* Let's see, whether we are able to provide an authentication handler
* to the passed authentication type.
*
* First we check the passed authentication type for the standard authentication
* schemes. If neither of them match, the list of custom authentication schemes
* is searched for the requested authentication type.
*/
switch ( desiredAuthenticationType ) {
case OncRpcAuthType.ONCRPC_AUTH_NONE:
authenticationHandler = OncRpcServerAuthNone.AUTH_NONE;
break;
case OncRpcAuthType.ONCRPC_AUTH_SHORT:
authenticationHandler = new OncRpcServerAuthShort();
break;
case OncRpcAuthType.ONCRPC_AUTH_UNIX:
authenticationHandler = new OncRpcServerAuthUnix();
break;
default:
/*
* ok, let's see, whether an appropriate authentication scheme is
* registered.
*/
Node actualNode = this.head;
while ( (authenticationHandler == null)
&& (actualNode != null) )
{
if ( actualNode.scheme.getAuthenticationType() == desiredAuthenticationType )
{
/*
* The scheme is provided!
* Then ask for a new handler.
* This will end the search.
*/
authenticationHandler = actualNode.scheme.getNewHandler();
}
else if ( actualNode.scheme.getAuthenticationType() > desiredAuthenticationType )
{
/*
* The number of the desired authentication type is smaller than
* the number of the authenitcation type of the actual node.
* As the list is ordered by the number of the authentication type,
* there can't be another authentication scheme in the list, that
* may match the desired one. Therefore the search ends up at this point.
*/
actualNode = null;
}
else
{
/*
* Maybe we have luck with the next node...
*/
actualNode = actualNode.next;
}
}
}
return authenticationHandler;
}
static OncRpcServerAuthSchemes getDefaultRepository()
{
return defaultRepository;
}
/**
* Simple node used by the repository to build and parse the custom authentication
* scheme list.
*
* @author hwirths
*
*/
private class Node {
/**
* The provided authentication scheme.
*/
OncRpcServerAuthScheme scheme = null;
/**
* The successor node, containing the next supported
* authentication scheme.
*/
Node next = null;
/**
* Constructs a new node taking over the passed authentication scheme.
*
* @param authenticationScheme An instance of an implementation oof {@link OncRpcServerAuthScheme}.
*/
Node(OncRpcServerAuthScheme authenticationScheme)
{
this.scheme = authenticationScheme;
}
}
/**
* The global default repository of authentication schemes.
*/
private static final OncRpcServerAuthSchemes defaultRepository = new OncRpcServerAuthSchemes();
/**
* The head of the custom authentication scheme list.
*/
private Node head = null;
}