001/* 002 * Copyright 2014-2018 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2014-2018 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 = 142 new ArrayList<SASLQualityOfProtection>(3); 143 if ((s == null) || (s.length() == 0)) 144 { 145 return qopValues; 146 } 147 148 final StringTokenizer tokenizer = new StringTokenizer(s, ","); 149 while (tokenizer.hasMoreTokens()) 150 { 151 final String token = tokenizer.nextToken().trim(); 152 final SASLQualityOfProtection qop = forName(token); 153 if (qop == null) 154 { 155 throw new LDAPException(ResultCode.PARAM_ERROR, 156 LDAPMessages.ERR_SASL_QOP_DECODE_LIST_INVALID_ELEMENT.get( 157 token, AUTH.qopString, AUTH_INT.qopString, 158 AUTH_CONF.qopString)); 159 } 160 else 161 { 162 qopValues.add(qop); 163 } 164 } 165 166 return qopValues; 167 } 168 169 170 171 /** 172 * Retrieves a string representation of this SASL quality of protection. 173 * 174 * @return A string representation of this SASL quality of protection. 175 */ 176 @Override() 177 public String toString() 178 { 179 return qopString; 180 } 181 182 183 184 /** 185 * Retrieves a string representation of the provided list of quality of 186 * protection values, as may be provided to a Java {@code SaslClient}. 187 * 188 * @param qopValues The list of values for which to create the string 189 * representation. 190 * 191 * @return A string representation of the provided list of quality of 192 * protection values, as may be provided to a Java 193 * {@code SaslClient}. 194 */ 195 public static String toString(final List<SASLQualityOfProtection> qopValues) 196 { 197 if ((qopValues == null) || qopValues.isEmpty()) 198 { 199 return AUTH.qopString; 200 } 201 202 final StringBuilder buffer = new StringBuilder(23); 203 final Iterator<SASLQualityOfProtection> iterator = qopValues.iterator(); 204 while (iterator.hasNext()) 205 { 206 buffer.append(iterator.next().qopString); 207 if (iterator.hasNext()) 208 { 209 buffer.append(','); 210 } 211 } 212 return buffer.toString(); 213 } 214}