001/*
002 * Copyright 2014-2019 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright (C) 2014-2019 Ping Identity Corporation
007 *
008 * This program is free software; you can redistribute it and/or modify
009 * it under the terms of the GNU General Public License (GPLv2 only)
010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011 * as published by the Free Software Foundation.
012 *
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program; if not, see <http://www.gnu.org/licenses>.
020 */
021package com.unboundid.ldap.sdk;
022
023
024
025import java.util.ArrayList;
026import java.util.Iterator;
027import java.util.List;
028import java.util.StringTokenizer;
029
030import com.unboundid.util.StaticUtils;
031import com.unboundid.util.ThreadSafety;
032import com.unboundid.util.ThreadSafetyLevel;
033
034
035
036/**
037 * This enum defines the set of supported SASL quality of protection values.
038 */
039@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
040public enum SASLQualityOfProtection
041{
042  /**
043   * The quality of protection value that indicates that only authentication is
044   * to be performed, with no integrity or confidentiality protection for
045   * subsequent communication.
046   */
047  AUTH("auth"),
048
049
050
051  /**
052   * The quality of protection value that indicates that integrity protection
053   * will be provided for subsequent communication after authentication has
054   * completed.  While integrity protection does not ensure that third-party
055   * observers cannot decipher communication between the client and server, it
056   * does ensure that the communication cannot be altered in an undetectable
057   * manner.
058   */
059  AUTH_INT("auth-int"),
060
061
062
063  /**
064   * The quality of protection value that indicates that confidentiality
065   * protection will be provided for subsequent communication after
066   * authentication has completed.  This ensures that third-party observers will
067   * not be able to decipher communication between the client and server (i.e.,
068   * that the communication will be encrypted).
069   */
070  AUTH_CONF("auth-conf");
071
072
073
074  // The string representation that should be used for this QoP when interacting
075  // with the Java SASL framework.
076  private final String qopString;
077
078
079
080  /**
081   * Creates a new SASL quality of protection value with the provided string
082   * representation.
083   *
084   * @param  qopString  The string representation for this quality of protection
085   *                    that should be used when interacting with the Java SASL
086   *                    framework.
087   */
088  SASLQualityOfProtection(final String qopString)
089  {
090    this.qopString = qopString;
091  }
092
093
094
095  /**
096   * Retrieves the SASL quality of protection value with the given name.
097   *
098   * @param  name  The name of the SASL quality of protection value to retrieve.
099   *               It must not be {@code null}.
100   *
101   * @return  The requested SASL quality of protection value, or {@code null} if
102   *          there is no value with the provided name.
103   */
104  public static SASLQualityOfProtection forName(final String name)
105  {
106    switch (StaticUtils.toLowerCase(name))
107    {
108      case "auth":
109        return AUTH;
110      case "authint":
111      case "auth-int":
112      case "auth_int":
113        return AUTH_INT;
114      case "authconf":
115      case "auth-conf":
116      case "auth_conf":
117        return AUTH_CONF;
118      default:
119        return null;
120    }
121  }
122
123
124
125  /**
126   * Decodes the provided string as a comma-delimited list of SASL quality of
127   * protection values.
128   *
129   * @param  s  The string to be decoded.
130   *
131   * @return  The decoded list of SASL quality of protection values.  It will
132   *          not be {@code null} but may be empty if the provided string was
133   *          {@code null} or empty.
134   *
135   * @throws  LDAPException  If the provided string cannot be decoded as a valid
136   *                         list of SASL quality of protection values.
137   */
138  public static List<SASLQualityOfProtection> decodeQoPList(final String s)
139         throws LDAPException
140  {
141    final ArrayList<SASLQualityOfProtection> qopValues = new ArrayList<>(3);
142    if ((s == null) || s.isEmpty())
143    {
144      return qopValues;
145    }
146
147    final StringTokenizer tokenizer = new StringTokenizer(s, ",");
148    while (tokenizer.hasMoreTokens())
149    {
150      final String token = tokenizer.nextToken().trim();
151      final SASLQualityOfProtection qop = forName(token);
152      if (qop == null)
153      {
154        throw new LDAPException(ResultCode.PARAM_ERROR,
155             LDAPMessages.ERR_SASL_QOP_DECODE_LIST_INVALID_ELEMENT.get(
156                  token, AUTH.qopString, AUTH_INT.qopString,
157                  AUTH_CONF.qopString));
158      }
159      else
160      {
161        qopValues.add(qop);
162      }
163    }
164
165    return qopValues;
166  }
167
168
169
170  /**
171   * Retrieves a string representation of this SASL quality of protection.
172   *
173   * @return  A string representation of this SASL quality of protection.
174   */
175  @Override()
176  public String toString()
177  {
178    return qopString;
179  }
180
181
182
183  /**
184   * Retrieves a string representation of the provided list of quality of
185   * protection values, as may be provided to a Java {@code SaslClient}.
186   *
187   * @param  qopValues  The list of values for which to create the string
188   *                    representation.
189   *
190   * @return  A string representation of the provided list of quality of
191   *          protection values, as may be provided to a Java
192   *          {@code SaslClient}.
193   */
194  public static String toString(final List<SASLQualityOfProtection> qopValues)
195  {
196    if ((qopValues == null) || qopValues.isEmpty())
197    {
198      return AUTH.qopString;
199    }
200
201    final StringBuilder buffer = new StringBuilder(23);
202    final Iterator<SASLQualityOfProtection> iterator = qopValues.iterator();
203    while (iterator.hasNext())
204    {
205      buffer.append(iterator.next().qopString);
206      if (iterator.hasNext())
207      {
208        buffer.append(',');
209      }
210    }
211    return buffer.toString();
212  }
213}