/*
* Copyright (C) 2012 10gen, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*
* As a special exception, the copyright holders give permission to link the
* code of portions of this program with the OpenSSL library under certain
* conditions as described in each individual source file and distribute
* linked combinations including the program with the OpenSSL library. You
* must comply with the GNU Affero General Public License in all respects for
* all of the code used other than as permitted herein. If you modify file(s)
* with this exception, you may extend this exception to your version of the
* file(s), but you are not obligated to do so. If you do not wish to do so,
* delete this exception statement from your version. If you delete this
* exception statement from all source files in the program, then also delete
* it in the license file.
*/
#pragma once
#include
#include
#include "mongo/base/disallow_copying.h"
#include "mongo/base/status.h"
#include "mongo/base/string_data.h"
#include "mongo/db/auth/authentication_session.h"
#include "mongo/db/auth/authorization_session.h"
#include "mongo/platform/cstdint.h"
#include "mongo/stdx/functional.h"
namespace mongo {
class AuthorizationSession;
class OperationContext;
/**
* Authentication session data for the server side of SASL authentication.
*/
class SaslAuthenticationSession : public AuthenticationSession {
MONGO_DISALLOW_COPYING(SaslAuthenticationSession);
public:
typedef stdx::function
SaslAuthenticationSessionFactoryFn;
static SaslAuthenticationSessionFactoryFn create;
// Mechanism name constants.
static const char mechanismCRAMMD5[];
static const char mechanismDIGESTMD5[];
static const char mechanismSCRAMSHA1[];
static const char mechanismGSSAPI[];
static const char mechanismPLAIN[];
explicit SaslAuthenticationSession(AuthorizationSession* authSession);
virtual ~SaslAuthenticationSession();
/**
* Start the server side of a SASL authentication.
*
* "authenticationDatabase" is the database against which the user is authenticating.
* "mechanism" is the SASL mechanism to use.
* "serviceName" is the SASL service name to use.
* "serviceHostname" is the FQDN of this server.
* "conversationId" is the conversation identifier to use for this session.
*
* If "autoAuthorize" is set to true, the server will automatically acquire all privileges
* for a successfully authenticated user. If it is false, the client will need to
* explicilty acquire privileges on resources it wishes to access.
*
* Must be called only once on an instance.
*/
virtual Status start(StringData authenticationDatabase,
StringData mechanism,
StringData serviceName,
StringData serviceHostname,
int64_t conversationId,
bool autoAuthorize) = 0;
/**
* Perform one step of the server side of the authentication session,
* consuming "inputData" and producing "*outputData".
*
* A return of Status::OK() indiciates succesful progress towards authentication.
* Any other return code indicates that authentication has failed.
*
* Must not be called before start().
*/
virtual Status step(StringData inputData, std::string* outputData) = 0;
/**
* Returns the the operation context associated with the currently executing command.
* Authentication commands must set this on their associated
* SaslAuthenticationSession.
*/
OperationContext* getOpCtxt() const {
return _txn;
}
void setOpCtxt(OperationContext* txn) {
_txn = txn;
}
/**
* Gets the name of the database against which this authentication conversation is running.
*
* Not meaningful before a successful call to start().
*/
StringData getAuthenticationDatabase() const;
/**
* Get the conversation id for this authentication session.
*
* Must not be called before start().
*/
int64_t getConversationId() const {
return _conversationId;
}
/**
* If the last call to step() returned Status::OK(), this method returns true if the
* authentication conversation has completed, from the server's perspective. If it returns
* false, the server expects more input from the client. If the last call to step() did not
* return Status::OK(), returns true.
*
* Behavior is undefined if step() has not been called.
*/
bool isDone() const {
return _done;
}
/**
* Gets the string identifier of the principal being authenticated.
*
* Returns the empty string if the session does not yet know the identity being
* authenticated.
*/
virtual std::string getPrincipalId() const = 0;
/**
* Gets the name of the SASL mechanism in use.
*
* Returns "" if start() has not been called or if start() did not return Status::OK().
*/
virtual const char* getMechanism() const = 0;
/**
* Returns true if automatic privilege acquisition should be used for this principal, after
* authentication. Not meaningful before a successful call to start().
*/
bool shouldAutoAuthorize() const {
return _autoAuthorize;
}
AuthorizationSession* getAuthorizationSession() {
return _authzSession;
}
protected:
OperationContext* _txn;
AuthorizationSession* _authzSession;
std::string _authenticationDatabase;
std::string _serviceName;
std::string _serviceHostname;
int _saslStep;
int64_t _conversationId;
bool _autoAuthorize;
bool _done;
};
} // namespace mongo