| /* |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| */ |
| |
| #include "qpid/SaslFactory.h" |
| |
| #include "qpid/Exception.h" |
| #include "qpid/framing/reply_exceptions.h" |
| #include "qpid/sys/SecurityLayer.h" |
| #include "qpid/sys/SecuritySettings.h" |
| #include "qpid/log/Statement.h" |
| |
| #include "boost/tokenizer.hpp" |
| |
| namespace qpid { |
| |
| using qpid::sys::SecurityLayer; |
| using qpid::sys::SecuritySettings; |
| using qpid::framing::InternalErrorException; |
| |
| struct WindowsSaslSettings |
| { |
| WindowsSaslSettings ( ) : |
| username ( std::string(0) ), |
| password ( std::string(0) ), |
| service ( std::string(0) ), |
| host ( std::string(0) ), |
| minSsf ( 0 ), |
| maxSsf ( 0 ) |
| { |
| } |
| |
| WindowsSaslSettings ( const std::string & user, const std::string & password, const std::string & service, const std::string & host, int minSsf, int maxSsf ) : |
| username(user), |
| password(password), |
| service(service), |
| host(host), |
| minSsf(minSsf), |
| maxSsf(maxSsf) |
| { |
| } |
| |
| std::string username, |
| password, |
| service, |
| host; |
| |
| int minSsf, |
| maxSsf; |
| }; |
| |
| class WindowsSasl : public Sasl |
| { |
| public: |
| WindowsSasl( const std::string &, const std::string &, const std::string &, const std::string &, int, int ); |
| ~WindowsSasl(); |
| bool start(const std::string& mechanisms, std::string& response, const SecuritySettings* externalSettings); |
| std::string step(const std::string& challenge); |
| std::string getMechanism(); |
| std::string getUserId(); |
| std::auto_ptr<SecurityLayer> getSecurityLayer(uint16_t maxFrameSize); |
| private: |
| WindowsSaslSettings settings; |
| std::string mechanism; |
| }; |
| |
| qpid::sys::Mutex SaslFactory::lock; |
| std::auto_ptr<SaslFactory> SaslFactory::instance; |
| |
| SaslFactory::SaslFactory() |
| { |
| } |
| |
| SaslFactory::~SaslFactory() |
| { |
| } |
| |
| SaslFactory& SaslFactory::getInstance() |
| { |
| qpid::sys::Mutex::ScopedLock l(lock); |
| if (!instance.get()) { |
| instance = std::auto_ptr<SaslFactory>(new SaslFactory()); |
| } |
| return *instance; |
| } |
| |
| std::auto_ptr<Sasl> SaslFactory::create( const std::string & username, const std::string & password, const std::string & serviceName, const std::string & hostName, int minSsf, int maxSsf, bool ) |
| { |
| std::auto_ptr<Sasl> sasl(new WindowsSasl( username, password, serviceName, hostName, minSsf, maxSsf )); |
| return sasl; |
| } |
| |
| namespace { |
| const std::string ANONYMOUS = "ANONYMOUS"; |
| const std::string PLAIN = "PLAIN"; |
| } |
| |
| WindowsSasl::WindowsSasl( const std::string & username, const std::string & password, const std::string & serviceName, const std::string & hostName, int minSsf, int maxSsf ) |
| : settings(username, password, serviceName, hostName, minSsf, maxSsf) |
| { |
| } |
| |
| WindowsSasl::~WindowsSasl() |
| { |
| } |
| |
| bool WindowsSasl::start(const std::string& mechanisms, std::string& response, |
| const SecuritySettings* /*externalSettings*/) |
| { |
| QPID_LOG(debug, "WindowsSasl::start(" << mechanisms << ")"); |
| |
| typedef boost::tokenizer<boost::char_separator<char> > tokenizer; |
| boost::char_separator<char> sep(" "); |
| bool havePlain = false; |
| bool haveAnon = false; |
| tokenizer mechs(mechanisms, sep); |
| for (tokenizer::iterator mech = mechs.begin(); |
| mech != mechs.end(); |
| ++mech) { |
| if (*mech == ANONYMOUS) |
| haveAnon = true; |
| else if (*mech == PLAIN) |
| havePlain = true; |
| } |
| if (!haveAnon && !havePlain) |
| throw InternalErrorException(QPID_MSG("Sasl error: no common mechanism")); |
| |
| if (havePlain) { |
| mechanism = PLAIN; |
| response = ((char)0) + settings.username + ((char)0) + settings.password; |
| } |
| else { |
| mechanism = ANONYMOUS; |
| response = ""; |
| } |
| return true; |
| } |
| |
| std::string WindowsSasl::step(const std::string& /*challenge*/) |
| { |
| // Shouldn't get this for PLAIN... |
| throw InternalErrorException(QPID_MSG("Sasl step error")); |
| } |
| |
| std::string WindowsSasl::getMechanism() |
| { |
| return mechanism; |
| } |
| |
| std::string WindowsSasl::getUserId() |
| { |
| return std::string(); // TODO - when GSSAPI is supported, return userId for connection. |
| } |
| |
| std::auto_ptr<SecurityLayer> WindowsSasl::getSecurityLayer(uint16_t /*maxFrameSize*/) |
| { |
| return std::auto_ptr<SecurityLayer>(0); |
| } |
| |
| } // namespace qpid |