////////////////////////////////////////////////////////////
//
// Declaration of a class
// DceServer
//
// Copyright 2001
//
////////////////////////////////////////////////////////////
#ifndef __DCESERVER_H__
#define __DCESERVER_H__
#include <dce/keymgmt.h>
#include <dce/sec_login.h>
#include "DceInterface.h"
#include "AFifo.C"
#include "AThread.h"
// DceKeyManager - a custom key retrieval
// a base class
struct DceKeyManager
{
virtual int get_key(void ** key,
char *server_princ_name, unsigned key_type, unsigned key_version)=0;
};
// DceServerAttributes
class DceServer;
class KeyManagerThread;
class DceServerAttributes
{
friend class DceServer;
friend class KeyManagerThread;
public:
DceServerAttributes();
DceServerAttributes(const DceServerAttributes&);
~DceServerAttributes();
DceServerAttributes& operator=(const DceServerAttributes&);
// default rpc_c_listen_max_calls_default
int set_max_exec_threads(unsigned z)
{ max_exec_threads=z; return 0;}
// queue size, default rpc_c_protseq_max_reqs_default
int set_max_call_requests(unsigned z)
{ max_call_requests=z; return 0;}
// default ncacn_ip_tcp
// an alternative protocol sequence is "ncadg_ip_udp"
int set_protocol_sequence(char* z)
{ protocol_sequence=(unsigned_char_t *)z; return 0;}
// read syntax code from an environment variable
// or use DCE syntax, if the variable is not set
int set_entry_name(const char *name);
// a random server id will be created, if it is not set
// string length is UUID_STRING_LEN
int set_id(const char *string_id)
{return id.set(string_id);}
// for example a site id, that a client can select a site
// cannot have interface types, when this is set
int associate_id(const char *string_id)
{return associated_id.set(string_id);}
int own_identity()
{ own_identity_flag=true; return 0;}
int set_principal_name(const char *name);
// default sec_login_no_flags
int set_login_flags(sec_login_flags_t z)
{login_flags=z; return 0;}
// if key file is not set
// DceKeyManager provides an access to a key
int use_key_file(const char *path);
// /krb/v5srvtab
int use_default_key_file()
{ key_file_flag = true; return 0;}
int set_annotation(const char *name);
int unexport_names()
{ unexport_names_flag=true; return 0; }
int no_names_export()
{ no_names_export_flag=true; return 0;}
int no_endpoint_replace()
{ no_endpoint_replace_flag=true; return 0;}
private:
unsigned32 max_exec_threads, max_call_requests;
unsigned_char_t *protocol_sequence;
unsigned32 entry_name_syntax;
unsigned_char_t *entry_name;
unsigned_char_t *principal_name;
sec_login_flags_t login_flags;
sec_key_mgmt_authn_service key_service;
char *key_file;
bool key_file_flag;
unsigned32 key_version_number;
bool own_identity_flag;
DceUuid id,associated_id;
unsigned_char_t * annotation;
bool unexport_names_flag;
bool no_endpoint_replace_flag;
bool no_names_export_flag;
};
// KeyManagerThread
// used internally
class KeyManagerThread: public AThread
{
KeyManagerThread(const KeyManagerThread&);
KeyManagerThread& operator=(const KeyManagerThread&);
public:
KeyManagerThread(DceServerAttributes& att, DceKeyManager * km);
~KeyManagerThread(){}
int loop(bool& continue_loop);
private:
DceServerAttributes *attributes;
void *arg;
};
// DceServer
class DceServer
{
DceServer(const DceServer&);
DceServer& operator=(const DceServer&);
public:
int status;
struct node
{
DceCalleeInterface interface;
rpc_binding_vector_t * binding_vector;
node():binding_vector(0){}
node(const DceCalleeInterface& z):interface(z),binding_vector(0){}
};
DceServer(DceServerAttributes& att, DceKeyManager * km=0);
~DceServer();
// sec_login_auth_src_network,
// sec_login_auth_src_local, sec_login_auth_src_overridden
int get_login_service(sec_login_auth_src_t& z)
{ z=login_service; return 0;}
// register interface with type id, or server id if there is no type id
int add_interface(const DceCalleeInterface& z);
int add_authentication_service(unsigned authentication_service_code);
// listen loop, blocking
int launch();
// called from a thread different from one,
// which drives a listen loop,
// for example, from an interface implementation
int stop();
// for a DceCall in a nested call
const sec_login_handle_t *login_context_pointer()
{ return &login_context;}
protected:
// a random id unique for each invocation
// of the server process
DceUuid linked_id;
DceServerAttributes & attributes;
AFifo<node> interfaces;
DceKeyManager *key_manager;
sec_login_handle_t login_context;
KeyManagerThread key_manager_thread;
AThreadControl thread_control;
sec_login_auth_src_t login_service; // output
int add_typeless(rpc_binding_vector_t *& binding_vector,const DceCalleeInterface& z);
int add_typed(rpc_binding_vector_t *& binding_vector,const DceCalleeInterface& z);
virtual int get_secret_key(){return 0;}
// default - write to stdout
// provide a custom logging function, if needed
virtual int log(const char *message, error_status_t status);
};
#endif
/* in main:
DceServerAttributes attr;
//set attributes here
DceServer server(attr);
DceCalleeInterface interface;
//set interface here
server.add_authentication_service(rpc_c_authn_dce_secret);
server.add_interface(interface);
while(1)
{
server.launch();
// handle listen loop interruptions here
// break the loop, if needed
}
*/