/*
    Copyright (c) 2007-2013 Contributors as noted in the AUTHORS file

    This file is part of 0MQ.

    0MQ is free software; you can redistribute it and/or modify it under
    the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.

    0MQ 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 Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef __ZMQ_GSSAPI_MECHANISM_BASE_HPP_INCLUDED__
#define __ZMQ_GSSAPI_MECHANISM_BASE_HPP_INCLUDED__

#include <gssapi/gssapi_generic.h>
#include <gssapi/gssapi_krb5.h>
#include <gssapi/gssapi_ext.h>

namespace zmq
{

    class msg_t;

    /// Both gssapi_server and gssapi_client need to produce and process
    /// GSSAPI tokens.  Common implementation is captured here.
    class gssapi_mechanism_base_t
    {
    public:
        gssapi_mechanism_base_t ();
        virtual ~gssapi_mechanism_base_t () = 0;

    protected:
        /// Produce a security context initialization token
        int produce_token (msg_t *msg_, int flags_, void *token_value_, size_t token_length_);
        /// Process a security context initialization token
        int process_token (msg_t *msg_, int &flags_, void **token_value_, size_t &token_length_);
        /// Produce a wrapped message using the established security context
        int produce_message (msg_t *msg_);
        /// Process a wrapped message using the established security context
        int process_message (msg_t *msg_);
        /// Acquire security context credentials
        static int acquire_credentials (char * service_name_, gss_cred_id_t * cred_);

    protected:
        const static int TOKEN_NOOP         = (1<<0);
        const static int TOKEN_CONTEXT      = (1<<1);
        const static int TOKEN_DATA         = (1<<2);
        const static int TOKEN_MIC          = (1<<3);
        const static int TOKEN_CONTEXT_NEXT = (1<<4);
        const static int TOKEN_WRAPPED      = (1<<5);
        const static int TOKEN_ENCRYPTED    = (1<<6);
        const static int TOKEN_SEND_MIC     = (1<<7);
        
        gss_buffer_desc send_tok;
        gss_buffer_desc recv_tok;
        gss_buffer_desc in_buf;
        gss_name_t target_name;
        char * service_name;
        OM_uint32 maj_stat;
        OM_uint32 min_stat;
        OM_uint32 init_sec_min_stat;
        OM_uint32 ret_flags;
        OM_uint32 gss_flags;
        int token_flags;
        gss_cred_id_t cred;
        gss_ctx_id_t context;
    };

}

#endif
