001/*
002 * Copyright 2014-2017 UnboundID Corp.
003 * All Rights Reserved.
004 */
005/*
006 * Copyright (C) 2014-2017 UnboundID Corp.
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  private 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    final String lowerName = StaticUtils.toLowerCase(name.replace('_', '-'));
107    for (final SASLQualityOfProtection p : values())
108    {
109      if (p.qopString.equals(lowerName))
110      {
111        return p;
112      }
113    }
114
115    return null;
116  }
117
118
119
120  /**
121   * Decodes the provided string as a comma-delimited list of SASL quality of
122   * protection values.
123   *
124   * @param  s  The string to be decoded.
125   *
126   * @return  The decoded list of SASL quality of protection values.  It will
127   *          not be {@code null} but may be empty if the provided string was
128   *          {@code null} or empty.
129   *
130   * @throws  LDAPException  If the provided string cannot be decoded as a valid
131   *                         list of SASL quality of protection values.
132   */
133  public static List<SASLQualityOfProtection> decodeQoPList(final String s)
134         throws LDAPException
135  {
136    final ArrayList<SASLQualityOfProtection> qopValues =
137         new ArrayList<SASLQualityOfProtection>(3);
138    if ((s == null) || (s.length() == 0))
139    {
140      return qopValues;
141    }
142
143    final StringTokenizer tokenizer = new StringTokenizer(s, ",");
144    while (tokenizer.hasMoreTokens())
145    {
146      final String token = tokenizer.nextToken().trim();
147      final SASLQualityOfProtection qop = forName(token);
148      if (qop == null)
149      {
150        throw new LDAPException(ResultCode.PARAM_ERROR,
151             LDAPMessages.ERR_SASL_QOP_DECODE_LIST_INVALID_ELEMENT.get(
152                  token, AUTH.qopString, AUTH_INT.qopString,
153                  AUTH_CONF.qopString));
154      }
155      else
156      {
157        qopValues.add(qop);
158      }
159    }
160
161    return qopValues;
162  }
163
164
165
166  /**
167   * Retrieves a string representation of this SASL quality of protection.
168   *
169   * @return  A string representation of this SASL quality of protection.
170   */
171  @Override()
172  public String toString()
173  {
174    return qopString;
175  }
176
177
178
179  /**
180   * Retrieves a string representation of the provided list of quality of
181   * protection values, as may be provided to a Java {@code SaslClient}.
182   *
183   * @param  qopValues  The list of values for which to create the string
184   *                    representation.
185   *
186   * @return  A string representation of the provided list of quality of
187   *          protection values, as may be provided to a Java
188   *          {@code SaslClient}.
189   */
190  public static String toString(final List<SASLQualityOfProtection> qopValues)
191  {
192    if ((qopValues == null) || qopValues.isEmpty())
193    {
194      return AUTH.qopString;
195    }
196
197    final StringBuilder buffer = new StringBuilder(23);
198    final Iterator<SASLQualityOfProtection> iterator = qopValues.iterator();
199    while (iterator.hasNext())
200    {
201      buffer.append(iterator.next().qopString);
202      if (iterator.hasNext())
203      {
204        buffer.append(',');
205      }
206    }
207    return buffer.toString();
208  }
209}