001    /*
002     * Copyright 2014-2015 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2014-2015 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     */
021    package com.unboundid.ldap.sdk;
022    
023    
024    
025    import java.util.ArrayList;
026    import java.util.Iterator;
027    import java.util.List;
028    import java.util.StringTokenizer;
029    
030    import com.unboundid.util.StaticUtils;
031    import com.unboundid.util.ThreadSafety;
032    import 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)
040    public 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    }