////////////////////////////////////////////////////////////
//
// Declaration of a class
// DceCallee
//
// Copyright 2001
//
////////////////////////////////////////////////////////////
#ifndef __DCECALLEE_H__
#define __DCECALLEE_H__
#include <dce/rpc.h>
#include <dce/id_base.h>
#include <dce/sec_cred.h>
const int CLIENT_PRINCIPAL_NAME_SIZE = 1023;
// DceCalleeSecurityData
// used by DceCallee internally
struct DceCalleeSecurityData
{
unsigned_char_t *server_principal_name;
unsigned32 protection_level,
authentication_service,
authorization_service;
rpc_authz_cred_handle_t callers_identity;
DceCalleeSecurityData():
server_principal_name(0),
protection_level(0),
authentication_service(0),
authorization_service(0)
{}
~DceCalleeSecurityData()
{ unsigned32 s; rpc_string_free(&server_principal_name,&s); }
};
// DceCalleeOption
struct DceCalleeOption
{
unsigned32 protection_level,
authentication_service,
authorization_service;
DceCalleeOption():
protection_level(rpc_c_protect_level_none),
authentication_service(rpc_c_authn_none),
authorization_service(rpc_c_authz_none)
{}
};
// DceCalleeReport
// any securyty layer can set "authorized" to false
struct DceCalleeReport
{
// a pair of zero terminated strings
char client_principal_name[CLIENT_PRINCIPAL_NAME_SIZE+1],
*client_principal_name_overflow;
bool authorized;
DceCalleeReport():
client_principal_name_overflow(0),
authorized(true)
{client_principal_name[0]=0;}
~DceCalleeReport()
{ delete client_principal_name_overflow; }
int set_name(unsigned_char_t * );
};
// DceCallee
// security handler
class DceCallee
{
DceCallee(const DceCallee&);
DceCallee& operator=(const DceCallee&);
public:
DceCallee();
~DceCallee();
// checked if set
int set_server_principal_name(const char *z);
// defualt is true
int run_level1_check(bool z)
{ level1_check=z; return 0;}
// defualt is true
int run_level2_check(bool z)
{ level2_check=z; return 0;}
// up to 10 such options
int allow_option(const DceCalleeOption& z);
void start_dce_response(handle_t binding_habdle,DceCalleeReport& report,error_status_t *rpc_error_status);
protected:
bool level1_check,level2_check;
unsigned_char_t *server_principal_name;
DceCalleeOption options[10];
int option_count;
// true - passed
virtual bool check_client_principal_name(const char * )
{return true;}
// sets security_data
void check_level1(DceCalleeSecurityData& security_data,DceCalleeReport& report);
virtual void check_level2(handle_t ,DceCalleeSecurityData&,DceCalleeReport&,error_status_t *rpc_error_status)
{*rpc_error_status=rpc_s_ok; }
// default implementation writes to stdout
// provide a custom logging function, if needed
virtual int dce_log(const char *message, error_status_t status);
};
#endif
/*
A declaration of an interface's functionality and security
in a file1.h
class SomeImplementation
{
public:
int set(...);
int fun(int z);
private:
data, mutexes
};
class SomeSecurity:public DceCallee
{
public:
int set(...);
void security_check(handle_t binding_handle,const DceCalleeSecurityData,error_status_t *rpc_error_status);
private:
data, mutexes
}
An implementation of an interface's functionality and security
in a file1.C:
int SomeImplementation::fun(int z)
{
use data (do not change it)
}
void SomeSecurity::security_check(handle_t h,const DceCalleeSecurityData& z,error_status_t *s)
{
use data (do not change it)
}
A formal implementation of an interface on a file2.C:
extern SomeSecurity *some_security;
extern SomeImplementation *some_implementation;
int fun(handle_t binding_handle,int z,error_status_t *rpc_error_status) - global function
{
DceCalleeReport report;
some_security->start_dce_response(binding_handle,report,rpc_error_status)
if(rpc_error_status!=rpc_s_ok) return -1;
return some_implementation->fun(z);
}
A setup in a main function:
SomeSecurity *some_security;
SomeImplementation *some_implementation;
int main()
{
SomeSecurity z;
some_security=&z;
some_security->set(...);
SomeImplementation zz;
some_implementation=&zz;
some_implementation->set(...);
}
*/