1 /*
2 * The Spread Toolkit.
3 *
4 * The contents of this file are subject to the Spread Open-Source
5 * License, Version 1.0 (the ``License''); you may not use
6 * this file except in compliance with the License. You may obtain a
7 * copy of the License at:
8 *
9 * http://www.spread.org/license/
10 *
11 * or in the file ``license.txt'' found in this distribution.
12 *
13 * Software distributed under the License is distributed on an AS IS basis,
14 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
15 * for the specific language governing rights and limitations under the
16 * License.
17 *
18 * The Creators of Spread are:
19 * Yair Amir, Michal Miskin-Amir, Jonathan Stanton.
20 *
21 * Copyright (C) 1993-2004 Spread Concepts LLC <spread@spreadconcepts.com>
22 *
23 * All Rights Reserved.
24 *
25 * Major Contributor(s):
26 * ---------------
27 * Cristina Nita-Rotaru crisn@cs.purdue.edu - group communication security.
28 * Theo Schlossnagle jesus@omniti.com - Perl, skiplists, autoconf.
29 * Dan Schoenblum dansch@cnds.jhu.edu - Java interface.
30 * John Schultz jschultz@cnds.jhu.edu - contribution to process group membership.
31 *
32 */
33
34
35 #include "arch.h"
36 #include <string.h>
37 #include <assert.h>
38
39 #include "acm.h"
40 #include "alarm.h"
41 #include "memory.h"
42 #include "objects.h"
43
44 struct auth_info {
45 char name[MAX_AUTH_NAME];
46 bool enabled;
47 bool required;
48 struct auth_ops ops;
49 };
50
51 struct acp_info {
52 char name[MAX_AUTH_NAME];
53 struct acp_ops ops;
54 };
55
56 static struct auth_info Auth_Methods[MAX_AUTH_METHODS];
57 static int Num_Auth_Methods;
58
59 static struct acp_info ACP_Methods[MAX_AUTH_METHODS];
60 static int Num_ACP_Methods;
61
62 static int AccessControlPolicy;
63
64
acm_authname_to_type(char * auth_name)65 static int acm_authname_to_type(char *auth_name)
66 {
67 int i;
68 for ( i=0; i < Num_Auth_Methods; i++)
69 {
70 if (!strncmp(Auth_Methods[i].name, auth_name, MAX_AUTH_NAME))
71 return( i );
72 }
73 return(-1);
74 }
75
acm_acpname_to_type(char * acp_name)76 static int acm_acpname_to_type(char *acp_name)
77 {
78 int i;
79 for ( i=0; i < Num_ACP_Methods; i++)
80 {
81 if (!strncmp(ACP_Methods[i].name, acp_name, MAX_AUTH_NAME))
82 return( i );
83 }
84 return(-1);
85 }
86
Acm_init()87 void Acm_init()
88 {
89 Mem_init_object( SESSION_AUTH_INFO, sizeof( struct session_auth_info ), 0, 0 );
90 /* establish default authentication -- allow all connections if nothing is configured.
91 * This is overridden by whatever is configured in the spread.conf file
92 */
93 Acm_auth_set_enabled("NULL");
94
95 /* establish default policy if one is not configured */
96 if (!Acm_acp_set_policy("PERMIT"))
97 Alarm(EXIT, "Acm_init: Unable to establish default PERMIT policy. Spread build is broken\n");
98 }
99
Acm_auth_create_sess_info_forIP(mailbox mbox)100 struct session_auth_info *Acm_auth_create_sess_info_forIP(mailbox mbox)
101 {
102 struct session_auth_info *sess_auth_p;
103
104 sess_auth_p = new( SESSION_AUTH_INFO );
105 if (sess_auth_p == NULL)
106 {
107 Alarm( EXIT, "Acm_auth_create_sess_info_forIP: Failed to allocate an struct session_auth_info\n");
108 return(NULL);
109 }
110
111 sess_auth_p->mbox = mbox;
112 sess_auth_p->completed_required_auths = 0;
113 sess_auth_p->num_required_auths = 1;
114 sess_auth_p->required_auth_methods[0] = acm_authname_to_type("IP");
115 sess_auth_p->required_auth_results[0] = 0;
116
117 return(sess_auth_p);
118 }
119
Acm_auth_create_sess_info(mailbox mbox,char * auth_name)120 struct session_auth_info *Acm_auth_create_sess_info(mailbox mbox, char *auth_name)
121 {
122 int num_auths, i, j, type;
123 struct session_auth_info *sess_auth_p;
124 bool meth_registered;
125
126 sess_auth_p = new( SESSION_AUTH_INFO );
127 if (sess_auth_p == NULL)
128 {
129 Alarm( EXIT, "Acm_auth_create_sess_info: Failed to allocate an struct session_auth_info\n");
130 return(NULL);
131 }
132
133 sess_auth_p->mbox = mbox;
134 sess_auth_p->completed_required_auths = 0;
135
136 num_auths = 0;
137 i = 0;
138 /* add methods client requested */
139 while( auth_name[i * MAX_AUTH_NAME] != '\0')
140 {
141 type = acm_authname_to_type( &auth_name[i * MAX_AUTH_NAME]);
142 if ( Auth_Methods[type].enabled )
143 {
144 sess_auth_p->required_auth_methods[num_auths] = type;
145 num_auths++;
146 }
147 i++;
148 }
149 if (num_auths == 0 )
150 {
151 Alarm( ACM, "Acm_auth_create_sess_info: Client on session mbox %d failed to request any valid methods: %s\n", mbox, auth_name);
152 dispose(sess_auth_p);
153 return(NULL);
154 }
155 /* Now add required methods that were not listed by client */
156 for ( i = 0; i < Num_Auth_Methods; i++)
157 {
158 if ( Auth_Methods[i].required )
159 {
160 for (meth_registered = FALSE, j=0; j < num_auths; j++)
161 {
162 if ( sess_auth_p->required_auth_methods[j] == i )
163 meth_registered = TRUE;
164 }
165 if ( ! meth_registered )
166 {
167 sess_auth_p->required_auth_methods[num_auths] = i;
168 num_auths++;
169 }
170 }
171 }
172 if (num_auths == 0 )
173 {
174 Alarm( ACM, "Acm_auth_create_sess_info: Failed to find any auth methods for session mbox %d which requested %s\n", mbox, auth_name);
175 dispose(sess_auth_p);
176 return(NULL);
177 }
178 sess_auth_p->num_required_auths = num_auths;
179 for (i=0; i< MAX_AUTH_METHODS; i++)
180 {
181 sess_auth_p->required_auth_results[i] = 0;
182 }
183 return(sess_auth_p);
184 }
Acm_auth_set_enabled(char * auth_name)185 bool Acm_auth_set_enabled(char *auth_name)
186 {
187 int auth_type;
188 assert(auth_name != NULL);
189 auth_type = acm_authname_to_type(auth_name);
190 if (auth_type == -1)
191 {
192 Alarm( ACM, "Acm_auth_set_enabled: unknown auth name %s\n", auth_name);
193 return( FALSE );
194 }
195 Auth_Methods[auth_type].enabled = TRUE;
196 return( TRUE );
197 }
Acm_auth_set_disabled(char * auth_name)198 bool Acm_auth_set_disabled(char *auth_name)
199 {
200 int auth_type;
201 assert(auth_name != NULL);
202 auth_type = acm_authname_to_type(auth_name);
203 if (auth_type == -1)
204 {
205 Alarm( ACM, "Acm_auth_set_disabled: unknown auth name %s\n", auth_name);
206 return( FALSE );
207 }
208 Auth_Methods[auth_type].enabled = FALSE;
209 return( TRUE );
210 }
211
Acm_auth_set_required(char * auth_name)212 bool Acm_auth_set_required(char *auth_name)
213 {
214 int auth_type;
215 assert(auth_name != NULL);
216 auth_type = acm_authname_to_type(auth_name);
217 if (auth_type == -1)
218 {
219 Alarm( ACM, "Acm_auth_set_required: unknown auth name %s\n", auth_name);
220 return( FALSE );
221 }
222 Auth_Methods[auth_type].required = TRUE;
223 return( TRUE );
224 }
225
Acm_auth_add_method(char * name,struct auth_ops * ops)226 bool Acm_auth_add_method(char *name, struct auth_ops *ops)
227 {
228 assert(name != NULL);
229 assert(ops != NULL);
230
231 if (Num_Auth_Methods == (MAX_AUTH_METHODS) )
232 return(FALSE);
233 memcpy(Auth_Methods[Num_Auth_Methods].name, name, MAX_AUTH_NAME);
234 Auth_Methods[Num_Auth_Methods].enabled = FALSE;
235 Auth_Methods[Num_Auth_Methods].required = FALSE;
236 Auth_Methods[Num_Auth_Methods].ops = *ops;
237
238 Num_Auth_Methods++;
239 return(TRUE);
240 }
241
Acm_auth_query_allowed(char * auth_name)242 bool Acm_auth_query_allowed(char *auth_name)
243 {
244 int auth_type;
245
246 assert(auth_name != NULL);
247
248 auth_type = acm_authname_to_type(auth_name);
249 if (auth_type == -1)
250 {
251 Alarm(ACM, "Acm_query_alloweds: unknown auth name %s\n", auth_name);
252 return(FALSE);
253 }
254 return(Auth_Methods[auth_type].enabled);
255 }
256
Acm_auth_get_auth_client_connection_byname(char * auth_name)257 void *Acm_auth_get_auth_client_connection_byname(char *auth_name)
258 {
259 int auth_type;
260
261 assert(auth_name != NULL);
262
263 auth_type = acm_authname_to_type(auth_name);
264 if (auth_type == -1)
265 {
266 Alarm(ACM, "Acm_auth_get_auth_client_connection_byname: unknown auth name %s\n", auth_name);
267 return(FALSE);
268 }
269 return(Acm_auth_get_auth_client_connection(auth_type));
270 }
271
Acm_auth_get_auth_client_connection(int authid)272 void *Acm_auth_get_auth_client_connection(int authid)
273 {
274 assert( authid >= 0 );
275 assert( authid < MAX_AUTH_METHODS );
276
277 return(Auth_Methods[authid].ops.auth_client_connection);
278 }
279
Acm_auth_get_allowed_list(void)280 char *Acm_auth_get_allowed_list(void)
281 {
282 int i;
283 static char list[MAX_AUTH_LIST_LEN];
284 char *c_ptr;
285
286 c_ptr = list;
287 for ( i=0; i < Num_Auth_Methods; i++)
288 {
289 if (Auth_Methods[i].enabled)
290 {
291 sprintf(c_ptr, "%s ", Auth_Methods[i].name);
292 c_ptr += strlen(Auth_Methods[i].name);
293 c_ptr++; /* for space */
294 }
295 }
296 *c_ptr = 0; /* null terminate */
297 return(list);
298 }
299
Acm_acp_add_method(char * name,struct acp_ops * ops)300 bool Acm_acp_add_method(char *name, struct acp_ops *ops)
301 {
302 assert(name != NULL);
303 assert(ops != NULL);
304
305 if (Num_ACP_Methods == (MAX_AUTH_METHODS) )
306 return(FALSE);
307 memcpy(ACP_Methods[Num_ACP_Methods].name, name, MAX_AUTH_NAME);
308 ACP_Methods[Num_ACP_Methods].ops = *ops;
309
310 Num_ACP_Methods++;
311 return(TRUE);
312 }
313
Acm_acp_query_allowed(char * acp_name)314 bool Acm_acp_query_allowed(char *acp_name)
315 {
316 int acp_type;
317
318 assert(acp_name != NULL);
319
320 acp_type = acm_acpname_to_type(acp_name);
321 if (acp_type == -1)
322 {
323 Alarm(ACM, "Acm_acp_query_alloweds: unknown acp name %s\n", acp_name);
324 return(FALSE);
325 }
326 return(TRUE);
327 }
328
Acm_acp_set_policy(char * policy_name)329 bool Acm_acp_set_policy(char *policy_name)
330 {
331 if (!Acm_acp_query_allowed(policy_name))
332 return(FALSE);
333 AccessControlPolicy = acm_acpname_to_type(policy_name);
334 return(TRUE);
335 }
336
Acm_acp_fill_ops_byname(char * acp_name,struct acp_ops * acp_ops_h)337 bool Acm_acp_fill_ops_byname(char *acp_name, struct acp_ops *acp_ops_h)
338 {
339 int acp_type;
340
341 assert(acp_name != NULL);
342 assert(acp_ops_h != NULL);
343
344 acp_type = acm_acpname_to_type(acp_name);
345 if (acp_type == -1)
346 {
347 Alarm(ACM, "Acm_fill_acp_ops: unknown access control policy name %s\n", acp_name);
348 return(FALSE);
349 }
350 *acp_ops_h = ACP_Methods[acp_type].ops;
351 return(TRUE);
352 }
353
Acm_acp_fill_ops(struct acp_ops * acp_ops_h)354 void Acm_acp_fill_ops(struct acp_ops *acp_ops_h)
355 {
356 assert(acp_ops_h != NULL);
357 assert( AccessControlPolicy >= 0 );
358 assert( AccessControlPolicy < Num_ACP_Methods );
359
360 *acp_ops_h = ACP_Methods[AccessControlPolicy].ops;
361 return;
362 }
363