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