1 /* 2 * hunt-amqp: AMQP library for D programming language, based on hunt-net. 3 * 4 * Copyright (C) 2018-2019 HuntLabs 5 * 6 * Website: https://www.huntlabs.net 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 module hunt.amqp.sasl.impl.ProtonSaslMechanismFinderImpl; 12 13 import hunt.collection.ArrayList; 14 import hunt.collection.Collections; 15 import hunt.collection.List; 16 import hunt.collection.Set; 17 import hunt.logging; 18 import hunt.amqp.sasl.ProtonSaslMechanism; 19 import hunt.amqp.sasl.ProtonSaslMechanismFactory; 20 import hunt.amqp.sasl.impl.ProtonSaslPlainImpl; 21 import hunt.amqp.sasl.impl.ProtonSaslAnonymousImpl; 22 import hunt.amqp.sasl.impl.ProtonSaslPlainFactoryImpl; 23 import hunt.amqp.sasl.impl.ProtonSaslAnonymousFactoryImpl; 24 import hunt.amqp.sasl.impl.ProtonSaslExternalImpl; 25 import hunt.amqp.sasl.impl.ProtonSaslExternalFactoryImpl; 26 27 class ProtonSaslMechanismFinderImpl { 28 29 //private static Logger LOG = LoggerFactory.getLogger(ProtonSaslMechanismFinderImpl.class); 30 31 /** 32 * Attempts to find a matching Mechanism implementation given a list of supported mechanisms from a remote peer. Can 33 * return null if no matching Mechanisms are found. 34 * 35 * @param username 36 * the username, or null if there is none 37 * @param password 38 * the password, or null if there is none 39 * @param mechRestrictions 40 * The possible mechanism(s) to which the client should restrict its mechanism selection to if offered by the 41 * server, or null/empty if there is no restriction 42 * @param remoteMechanisms 43 * list of mechanism names that are supported by the remote peer. 44 * 45 * @return the best matching Mechanism for the supported remote set. 46 */ 47 public static ProtonSaslMechanism findMatchingMechanism(string username, string password, 48 Set!string mechRestrictions, string [] remoteMechanisms) { 49 50 ProtonSaslMechanism match = null; 51 List!ProtonSaslMechanism found = new ArrayList!ProtonSaslMechanism(); 52 53 foreach (string remoteMechanism ; remoteMechanisms) { 54 ProtonSaslMechanismFactory factory = findMechanismFactory(remoteMechanism); 55 if (factory !is null) { 56 ProtonSaslMechanism mech = factory.createMechanism(); 57 if (mechRestrictions !is null && !mechRestrictions.isEmpty() && !mechRestrictions.contains(remoteMechanism)) { 58 //if (LOG.isTraceEnabled()) { 59 // LOG.trace("Skipping " + remoteMechanism + " mechanism because it is not in the configured mechanisms restriction set"); 60 //} 61 } else if (mech.isApplicable(username, password)) { 62 found.add(mech); 63 } else { 64 //if (LOG.isTraceEnabled()) { 65 // LOG.trace("Skipping " + mech + " mechanism because the available credentials are not sufficient"); 66 //} 67 } 68 } 69 } 70 71 if (!found.isEmpty()) { 72 // Sorts by priority using mechanism comparison and return the last value in 73 // list which is the mechanism deemed to be the highest priority match. 74 // Collections.sort(found); 75 match = found.get(found.size() - 1); 76 } 77 78 //if (LOG.isTraceEnabled()) { 79 // LOG.trace("Best match for SASL auth was: " + match); 80 //} 81 82 return match; 83 } 84 85 /** 86 * Searches for a mechanism factory by using the scheme from the given name. 87 * 88 * @param name 89 * The name of the authentication mechanism to search for. 90 * 91 * @return a mechanism factory instance matching the name, or null if none was created. 92 */ 93 protected static ProtonSaslMechanismFactory findMechanismFactory(string name) { 94 if (name is null || name.length ==0) { 95 // LOG.warn("No SASL mechanism name was specified"); 96 logError("No SASL mechanism name was specified"); 97 return null; 98 } 99 100 ProtonSaslMechanismFactory factory = null; 101 102 // TODO: make it pluggable? 103 if (ProtonSaslPlainImpl.MECH_NAME == (name)) { 104 factory = new ProtonSaslPlainFactoryImpl(); 105 } else if (ProtonSaslAnonymousImpl.MECH_NAME == (name)) { 106 factory = new ProtonSaslAnonymousFactoryImpl(); 107 } else if (ProtonSaslExternalImpl.MECH_NAME == (name)) { 108 factory = new ProtonSaslExternalFactoryImpl(); 109 } 110 111 return factory; 112 } 113 }