/*
* The Spread Toolkit.
*
* The contents of this file are subject to the Spread Open-Source
* License, Version 1.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.spread.org/license/
*
* or in the file ``license.txt'' found in this distribution.
*
* Software distributed under the License is distributed on an AS IS basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Creators of Spread are:
* Yair Amir, Michal Miskin-Amir, Jonathan Stanton.
*
* Copyright (C) 1993-2004 Spread Concepts LLC <spread@spreadconcepts.com>
*
* All Rights Reserved.
*
* Major Contributor(s):
* ---------------
* Cristina Nita-Rotaru crisn@cs.purdue.edu - group communication security.
* Theo Schlossnagle jesus@omniti.com - Perl, skiplists, autoconf.
* Dan Schoenblum dansch@cnds.jhu.edu - Java interface.
* John Schultz jschultz@cnds.jhu.edu - contribution to process group membership.
*
*/
#include "arch.h"
#include <string.h>
#include <assert.h>
#include "acm.h"
#include "alarm.h"
#include "memory.h"
#include "objects.h"
struct auth_info {
char name[MAX_AUTH_NAME];
bool enabled;
bool required;
struct auth_ops ops;
};
struct acp_info {
char name[MAX_AUTH_NAME];
struct acp_ops ops;
};
static struct auth_info Auth_Methods[MAX_AUTH_METHODS];
static int Num_Auth_Methods;
static struct acp_info ACP_Methods[MAX_AUTH_METHODS];
static int Num_ACP_Methods;
static int AccessControlPolicy;
static int acm_authname_to_type(char *auth_name)
{
int i;
for ( i=0; i < Num_Auth_Methods; i++)
{
if (!strncmp(Auth_Methods[i].name, auth_name, MAX_AUTH_NAME))
return( i );
}
return(-1);
}
static int acm_acpname_to_type(char *acp_name)
{
int i;
for ( i=0; i < Num_ACP_Methods; i++)
{
if (!strncmp(ACP_Methods[i].name, acp_name, MAX_AUTH_NAME))
return( i );
}
return(-1);
}
void Acm_init()
{
Mem_init_object( SESSION_AUTH_INFO, sizeof( struct session_auth_info ), 0, 0 );
/* establish default authentication -- allow all connections if nothing is configured.
* This is overridden by whatever is configured in the spread.conf file
*/
Acm_auth_set_enabled("NULL");
/* establish default policy if one is not configured */
if (!Acm_acp_set_policy("PERMIT"))
Alarm(EXIT, "Acm_init: Unable to establish default PERMIT policy. Spread build is broken\n");
}
struct session_auth_info *Acm_auth_create_sess_info_forIP(mailbox mbox)
{
struct session_auth_info *sess_auth_p;
sess_auth_p = new( SESSION_AUTH_INFO );
if (sess_auth_p == NULL)
{
Alarm( EXIT, "Acm_auth_create_sess_info_forIP: Failed to allocate an struct session_auth_info\n");
return(NULL);
}
sess_auth_p->mbox = mbox;
sess_auth_p->completed_required_auths = 0;
sess_auth_p->num_required_auths = 1;
sess_auth_p->required_auth_methods[0] = acm_authname_to_type("IP");
sess_auth_p->required_auth_results[0] = 0;
return(sess_auth_p);
}
struct session_auth_info *Acm_auth_create_sess_info(mailbox mbox, char *auth_name)
{
int num_auths, i, j, type;
struct session_auth_info *sess_auth_p;
bool meth_registered;
sess_auth_p = new( SESSION_AUTH_INFO );
if (sess_auth_p == NULL)
{
Alarm( EXIT, "Acm_auth_create_sess_info: Failed to allocate an struct session_auth_info\n");
return(NULL);
}
sess_auth_p->mbox = mbox;
sess_auth_p->completed_required_auths = 0;
num_auths = 0;
i = 0;
/* add methods client requested */
while( auth_name[i * MAX_AUTH_NAME] != '\0')
{
type = acm_authname_to_type( &auth_name[i * MAX_AUTH_NAME]);
if ( Auth_Methods[type].enabled )
{
sess_auth_p->required_auth_methods[num_auths] = type;
num_auths++;
}
i++;
}
if (num_auths == 0 )
{
Alarm( ACM, "Acm_auth_create_sess_info: Client on session mbox %d failed to request any valid methods: %s\n", mbox, auth_name);
dispose(sess_auth_p);
return(NULL);
}
/* Now add required methods that were not listed by client */
for ( i = 0; i < Num_Auth_Methods; i++)
{
if ( Auth_Methods[i].required )
{
for (meth_registered = FALSE, j=0; j < num_auths; j++)
{
if ( sess_auth_p->required_auth_methods[j] == i )
meth_registered = TRUE;
}
if ( ! meth_registered )
{
sess_auth_p->required_auth_methods[num_auths] = i;
num_auths++;
}
}
}
if (num_auths == 0 )
{
Alarm( ACM, "Acm_auth_create_sess_info: Failed to find any auth methods for session mbox %d which requested %s\n", mbox, auth_name);
dispose(sess_auth_p);
return(NULL);
}
sess_auth_p->num_required_auths = num_auths;
for (i=0; i< MAX_AUTH_METHODS; i++)
{
sess_auth_p->required_auth_results[i] = 0;
}
return(sess_auth_p);
}
bool Acm_auth_set_enabled(char *auth_name)
{
int auth_type;
assert(auth_name != NULL);
auth_type = acm_authname_to_type(auth_name);
if (auth_type == -1)
{
Alarm( ACM, "Acm_auth_set_enabled: unknown auth name %s\n", auth_name);
return( FALSE );
}
Auth_Methods[auth_type].enabled = TRUE;
return( TRUE );
}
bool Acm_auth_set_disabled(char *auth_name)
{
int auth_type;
assert(auth_name != NULL);
auth_type = acm_authname_to_type(auth_name);
if (auth_type == -1)
{
Alarm( ACM, "Acm_auth_set_disabled: unknown auth name %s\n", auth_name);
return( FALSE );
}
Auth_Methods[auth_type].enabled = FALSE;
return( TRUE );
}
bool Acm_auth_set_required(char *auth_name)
{
int auth_type;
assert(auth_name != NULL);
auth_type = acm_authname_to_type(auth_name);
if (auth_type == -1)
{
Alarm( ACM, "Acm_auth_set_required: unknown auth name %s\n", auth_name);
return( FALSE );
}
Auth_Methods[auth_type].required = TRUE;
return( TRUE );
}
bool Acm_auth_add_method(char *name, struct auth_ops *ops)
{
assert(name != NULL);
assert(ops != NULL);
if (Num_Auth_Methods == (MAX_AUTH_METHODS) )
return(FALSE);
memcpy(Auth_Methods[Num_Auth_Methods].name, name, MAX_AUTH_NAME);
Auth_Methods[Num_Auth_Methods].enabled = FALSE;
Auth_Methods[Num_Auth_Methods].required = FALSE;
Auth_Methods[Num_Auth_Methods].ops = *ops;
Num_Auth_Methods++;
return(TRUE);
}
bool Acm_auth_query_allowed(char *auth_name)
{
int auth_type;
assert(auth_name != NULL);
auth_type = acm_authname_to_type(auth_name);
if (auth_type == -1)
{
Alarm(ACM, "Acm_query_alloweds: unknown auth name %s\n", auth_name);
return(FALSE);
}
return(Auth_Methods[auth_type].enabled);
}
void *Acm_auth_get_auth_client_connection_byname(char *auth_name)
{
int auth_type;
assert(auth_name != NULL);
auth_type = acm_authname_to_type(auth_name);
if (auth_type == -1)
{
Alarm(ACM, "Acm_auth_get_auth_client_connection_byname: unknown auth name %s\n", auth_name);
return(FALSE);
}
return(Acm_auth_get_auth_client_connection(auth_type));
}
void *Acm_auth_get_auth_client_connection(int authid)
{
assert( authid >= 0 );
assert( authid < MAX_AUTH_METHODS );
return(Auth_Methods[authid].ops.auth_client_connection);
}
char *Acm_auth_get_allowed_list(void)
{
int i;
static char list[MAX_AUTH_LIST_LEN];
char *c_ptr;
c_ptr = list;
for ( i=0; i < Num_Auth_Methods; i++)
{
if (Auth_Methods[i].enabled)
{
sprintf(c_ptr, "%s ", Auth_Methods[i].name);
c_ptr += strlen(Auth_Methods[i].name);
c_ptr++; /* for space */
}
}
*c_ptr = 0; /* null terminate */
return(list);
}
bool Acm_acp_add_method(char *name, struct acp_ops *ops)
{
assert(name != NULL);
assert(ops != NULL);
if (Num_ACP_Methods == (MAX_AUTH_METHODS) )
return(FALSE);
memcpy(ACP_Methods[Num_ACP_Methods].name, name, MAX_AUTH_NAME);
ACP_Methods[Num_ACP_Methods].ops = *ops;
Num_ACP_Methods++;
return(TRUE);
}
bool Acm_acp_query_allowed(char *acp_name)
{
int acp_type;
assert(acp_name != NULL);
acp_type = acm_acpname_to_type(acp_name);
if (acp_type == -1)
{
Alarm(ACM, "Acm_acp_query_alloweds: unknown acp name %s\n", acp_name);
return(FALSE);
}
return(TRUE);
}
bool Acm_acp_set_policy(char *policy_name)
{
if (!Acm_acp_query_allowed(policy_name))
return(FALSE);
AccessControlPolicy = acm_acpname_to_type(policy_name);
return(TRUE);
}
bool Acm_acp_fill_ops_byname(char *acp_name, struct acp_ops *acp_ops_h)
{
int acp_type;
assert(acp_name != NULL);
assert(acp_ops_h != NULL);
acp_type = acm_acpname_to_type(acp_name);
if (acp_type == -1)
{
Alarm(ACM, "Acm_fill_acp_ops: unknown access control policy name %s\n", acp_name);
return(FALSE);
}
*acp_ops_h = ACP_Methods[acp_type].ops;
return(TRUE);
}
void Acm_acp_fill_ops(struct acp_ops *acp_ops_h)
{
assert(acp_ops_h != NULL);
assert( AccessControlPolicy >= 0 );
assert( AccessControlPolicy < Num_ACP_Methods );
*acp_ops_h = ACP_Methods[AccessControlPolicy].ops;
return;
}
syntax highlighted by Code2HTML, v. 0.9.1