Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2012-2023 Ping Identity Corporation
* All Rights Reserved.
*/
/*
* Copyright 2012-2023 Ping Identity Corporation
*
* 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.
*/
/*
* Copyright (C) 2012-2023 Ping Identity Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License (GPLv2 only)
* or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
* as published by the Free Software Foundation.
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see .
*/
package com.unboundid.ldap.sdk.unboundidds;
import java.util.ArrayList;
import com.unboundid.asn1.ASN1Element;
import com.unboundid.asn1.ASN1OctetString;
import com.unboundid.asn1.ASN1Sequence;
import com.unboundid.ldap.sdk.BindResult;
import com.unboundid.ldap.sdk.Control;
import com.unboundid.ldap.sdk.InternalSDKHelper;
import com.unboundid.ldap.sdk.LDAPConnection;
import com.unboundid.ldap.sdk.LDAPException;
import com.unboundid.ldap.sdk.SASLBindRequest;
import com.unboundid.util.NotExtensible;
import com.unboundid.util.NotNull;
import com.unboundid.util.Nullable;
import com.unboundid.util.ThreadSafety;
import com.unboundid.util.ThreadSafetyLevel;
import com.unboundid.util.Validator;
/**
* This class provides support for an UnboundID-proprietary SASL mechanism that
* uses the time-based one-time password mechanism (TOTP) as described in
* RFC 6238, optionally (based
* on the server configuration) in conjunction with a static password for a form
* of multifactor authentication.
*
*
* NOTE: This class, and other classes within the
* {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
* supported for use against Ping Identity, UnboundID, and
* Nokia/Alcatel-Lucent 8661 server products. These classes provide support
* for proprietary functionality or for external specifications that are not
* considered stable or mature enough to be guaranteed to work in an
* interoperable way with other types of LDAP servers.
*
*
* The name for this SASL mechanism is "UNBOUNDID-TOTP". An UNBOUNDID-TOTP SASL
* bind request MUST include SASL credentials with the following ASN.1 encoding:
*
* Note that this class is abstract, with two different concrete
* implementations: the {@link SingleUseTOTPBindRequest} class may be used for
* cases in which the one-time password will be obtained from an external source
* (e.g., provided by the user, perhaps using the Google Authenticator
* application), and the {@link ReusableTOTPBindRequest} class may be used for
* cases in which the one-time password should be generated by the LDAP SDK
* itself. Because the {@code SingleUseTOTPBindRequest} class contains a
* point-in-time password, it cannot be used for re-authentication (e.g., for
* use with a connection pool, following referrals, or with the auto-reconnect
* feature). If TOTP authentication should be used in contexts where one or
* more of these may be needed, then the dynamic variant should be used.
*/
@NotExtensible()
@ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE)
public abstract class UnboundIDTOTPBindRequest
extends SASLBindRequest
{
/**
* The name for the UnboundID TOTP SASL mechanism.
*/
@NotNull public static final String UNBOUNDID_TOTP_MECHANISM_NAME =
"UNBOUNDID-TOTP";
/**
* The BER type for the authentication ID included in the request.
*/
static final byte TYPE_AUTHENTICATION_ID = (byte) 0x80;
/**
* The BER type for the authorization ID included in the request.
*/
static final byte TYPE_AUTHORIZATION_ID = (byte) 0x81;
/**
* The BER type for the TOTP password included in the request.
*/
static final byte TYPE_TOTP_PASSWORD = (byte) 0x82;
/**
* The BER type for the static password included in the request.
*/
static final byte TYPE_STATIC_PASSWORD = (byte) 0x83;
/**
* The serial version UID for this serializable class.
*/
private static final long serialVersionUID = -8751931123826994145L;
// The static password for the target user, if provided.
@Nullable private final ASN1OctetString staticPassword;
// The message ID from the last LDAP message sent from this request.
private volatile int messageID = -1;
// The authentication identity for the bind.
@NotNull private final String authenticationID;
// The authorization identity for the bind, if provided.
@Nullable private final String authorizationID;
/**
* Creates a new TOTP bind request with the provided information.
*
* @param authenticationID The authentication identity for the bind request.
* It must not be {@code null}, and must be in the
* form "u:" followed by a username, or "dn:"
* followed by a DN.
* @param authorizationID The authorization identity for the bind request.
* It may be {@code null} if the authorization
* identity should be the same as the authentication
* identity. If an authorization identity is
* specified, it must be in the form "u:" followed
* by a username, or "dn:" followed by a DN. The
* value "dn:" may indicate an authorization
* identity of the anonymous user.
* @param staticPassword The static password for the target user. It may
* be {@code null} if only the one-time password is
* to be used for authentication (which may or may
* not be allowed by the server).
* @param controls The set of controls to include in the bind
* request.
*/
protected UnboundIDTOTPBindRequest(@NotNull final String authenticationID,
@Nullable final String authorizationID,
@Nullable final String staticPassword,
@Nullable final Control... controls)
{
super(controls);
Validator.ensureNotNull(authenticationID);
this.authenticationID = authenticationID;
this.authorizationID = authorizationID;
if (staticPassword == null)
{
this.staticPassword = null;
}
else
{
this.staticPassword =
new ASN1OctetString(TYPE_STATIC_PASSWORD, staticPassword);
}
}
/**
* Creates a new TOTP bind request with the provided information.
*
* @param authenticationID The authentication identity for the bind request.
* It must not be {@code null}, and must be in the
* form "u:" followed by a username, or "dn:"
* followed by a DN.
* @param authorizationID The authorization identity for the bind request.
* It may be {@code null} if the authorization
* identity should be the same as the authentication
* identity. If an authorization identity is
* specified, it must be in the form "u:" followed
* by a username, or "dn:" followed by a DN. The
* value "dn:" may indicate an authorization
* identity of the anonymous user.
* @param staticPassword The static password for the target user. It may
* be {@code null} if only the one-time password is
* to be used for authentication (which may or may
* not be allowed by the server).
* @param controls The set of controls to include in the bind
* request.
*/
protected UnboundIDTOTPBindRequest(@NotNull final String authenticationID,
@Nullable final String authorizationID,
@Nullable final byte[] staticPassword,
@Nullable final Control... controls)
{
super(controls);
Validator.ensureNotNull(authenticationID);
this.authenticationID = authenticationID;
this.authorizationID = authorizationID;
if (staticPassword == null)
{
this.staticPassword = null;
}
else
{
this.staticPassword =
new ASN1OctetString(TYPE_STATIC_PASSWORD, staticPassword);
}
}
/**
* Creates a new TOTP bind request with the provided information.
*
* @param authenticationID The authentication identity for the bind request.
* It must not be {@code null}, and must be in the
* form "u:" followed by a username, or "dn:"
* followed by a DN.
* @param authorizationID The authorization identity for the bind request.
* It may be {@code null} if the authorization
* identity should be the same as the authentication
* identity. If an authorization identity is
* specified, it must be in the form "u:" followed
* by a username, or "dn:" followed by a DN. The
* value "dn:" may indicate an authorization
* identity of the anonymous user.
* @param staticPassword The static password for the target user. It may
* be {@code null} if only the one-time password is
* to be used for authentication (which may or may
* not be allowed by the server). If it is
* non-{@code null}, then it must have the
* appropriate BER type.
* @param controls The set of controls to include in the bind
* request.
*/
protected UnboundIDTOTPBindRequest(@NotNull final String authenticationID,
@Nullable final String authorizationID,
@Nullable final ASN1OctetString staticPassword,
@Nullable final Control... controls)
{
super(controls);
Validator.ensureNotNull(authenticationID);
if (staticPassword != null)
{
Validator.ensureTrue(staticPassword.getType() == TYPE_STATIC_PASSWORD);
}
this.authenticationID = authenticationID;
this.authorizationID = authorizationID;
this.staticPassword = staticPassword;
}
/**
* Retrieves the authentication ID for the bind request.
*
* @return The authentication ID for the bind request.
*/
@NotNull()
public final String getAuthenticationID()
{
return authenticationID;
}
/**
* Retrieves the authorization ID for the bind request, if one was provided.
*
* @return The authorization ID for the bind request, or {@code null} if the
* authorization ID should be the same as the authentication ID.
*/
@Nullable()
public final String getAuthorizationID()
{
return authorizationID;
}
/**
* Retrieves the static password for the bind request, if one was provided.
*
* @return The static password for the bind request, or {@code null} if no
* static password was provided and only the one-time password should
* be used for authentication.
*/
@Nullable()
public final ASN1OctetString getStaticPassword()
{
return staticPassword;
}
/**
* {@inheritDoc}
*/
@Override()
@NotNull()
public final String getSASLMechanismName()
{
return UNBOUNDID_TOTP_MECHANISM_NAME;
}
/**
* {@inheritDoc}
*/
@Override()
@NotNull()
protected final BindResult process(@NotNull final LDAPConnection connection,
final int depth)
throws LDAPException
{
setReferralDepth(depth);
messageID = InternalSDKHelper.nextMessageID(connection);
return sendBindRequest(connection, "", getSASLCredentials(), getControls(),
getResponseTimeoutMillis(connection));
}
/**
* Retrieves the encoded SASL credentials that may be included in an
* UNBOUNDID-TOTP SASL bind request.
*
* @return The encoded SASL credentials that may be included in an
* UNBOUNDID-TOTP SASL bind request.
*
* @throws LDAPException If a problem is encountered while attempting to
* obtain the encoded credentials.
*/
@NotNull()
protected abstract ASN1OctetString getSASLCredentials()
throws LDAPException;
/**
* Encodes the provided information in a form suitable for inclusion in an
* UNBOUNDID-TOTP SASL bind request.
*
* @param authenticationID The authentication identity for the bind request.
* It must not be {@code null}, and must be in the
* form "u:" followed by a username, or "dn:"
* followed by a DN.
* @param authorizationID The authorization identity for the bind request.
* It may be {@code null} if the authorization
* identity should be the same as the authentication
* identity. If an authorization identity is
* specified, it must be in the form "u:" followed
* by a username, or "dn:" followed by a DN. The
* value "dn:" may indicate an authorization
* identity of the anonymous user.
* @param totpPassword The TOTP password to include in the bind request.
* It must not be {@code null}.
* @param staticPassword The static password for the target user. It may
* be {@code null} if only the one-time password is
* to be used for authentication (which may or may
* not be allowed by the server).
*
* @return The encoded SASL credentials.
*/
@NotNull()
public static ASN1OctetString encodeCredentials(
@NotNull final String authenticationID,
@Nullable final String authorizationID,
@NotNull final String totpPassword,
@Nullable final ASN1OctetString staticPassword)
{
Validator.ensureNotNull(authenticationID);
Validator.ensureNotNull(totpPassword);
final ArrayList elements = new ArrayList<>(4);
elements.add(new ASN1OctetString(TYPE_AUTHENTICATION_ID, authenticationID));
if (authorizationID != null)
{
elements.add(new ASN1OctetString(TYPE_AUTHORIZATION_ID, authorizationID));
}
elements.add(new ASN1OctetString(TYPE_TOTP_PASSWORD, totpPassword));
if (staticPassword != null)
{
if (staticPassword.getType() == TYPE_STATIC_PASSWORD)
{
elements.add(staticPassword);
}
else
{
elements.add(new ASN1OctetString(TYPE_STATIC_PASSWORD,
staticPassword.getValue()));
}
}
return new ASN1OctetString(new ASN1Sequence(elements).encode());
}
/**
* {@inheritDoc}
*/
@Override()
public final int getLastMessageID()
{
return messageID;
}
/**
* {@inheritDoc}
*/
@Override()
public final void toString(@NotNull final StringBuilder buffer)
{
buffer.append("UnboundIDTOTPBindRequest(authID='");
buffer.append(authenticationID);
buffer.append("', ");
if (authorizationID != null)
{
buffer.append("authzID='");
buffer.append(authorizationID);
buffer.append("', ");
}
buffer.append("includesStaticPassword=");
buffer.append(staticPassword != null);
final Control[] controls = getControls();
if (controls.length > 0)
{
buffer.append(", controls={");
for (int i=0; i < controls.length; i++)
{
if (i > 0)
{
buffer.append(", ");
}
buffer.append(controls[i]);
}
buffer.append('}');
}
buffer.append(')');
}
}