blob: 53d825771b09c7f6292d4d5a2a77a48977e59bbb [file] [log] [blame]
/*
*
* 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