/* * 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 * * 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 #include #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; }