xref: /minix3/external/bsd/dhcp/dist/omapip/protocol.c (revision 83ee113ee0d94f3844d44065af2311604e9a30ad)
1*83ee113eSDavid van Moolenbroek /*	$NetBSD: protocol.c,v 1.1.1.3 2014/07/12 11:58:00 spz Exp $	*/
2*83ee113eSDavid van Moolenbroek /* protocol.c
3*83ee113eSDavid van Moolenbroek 
4*83ee113eSDavid van Moolenbroek    Functions supporting the object management protocol... */
5*83ee113eSDavid van Moolenbroek 
6*83ee113eSDavid van Moolenbroek /*
7*83ee113eSDavid van Moolenbroek  * Copyright (c) 2009,2012,2014 by Internet Systems Consortium, Inc. ("ISC")
8*83ee113eSDavid van Moolenbroek  * Copyright (c) 2004-2007 by Internet Systems Consortium, Inc. ("ISC")
9*83ee113eSDavid van Moolenbroek  * Copyright (c) 1999-2003 by Internet Software Consortium
10*83ee113eSDavid van Moolenbroek  *
11*83ee113eSDavid van Moolenbroek  * Permission to use, copy, modify, and distribute this software for any
12*83ee113eSDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
13*83ee113eSDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
14*83ee113eSDavid van Moolenbroek  *
15*83ee113eSDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
16*83ee113eSDavid van Moolenbroek  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
17*83ee113eSDavid van Moolenbroek  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
18*83ee113eSDavid van Moolenbroek  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19*83ee113eSDavid van Moolenbroek  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20*83ee113eSDavid van Moolenbroek  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21*83ee113eSDavid van Moolenbroek  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22*83ee113eSDavid van Moolenbroek  *
23*83ee113eSDavid van Moolenbroek  *   Internet Systems Consortium, Inc.
24*83ee113eSDavid van Moolenbroek  *   950 Charter Street
25*83ee113eSDavid van Moolenbroek  *   Redwood City, CA 94063
26*83ee113eSDavid van Moolenbroek  *   <info@isc.org>
27*83ee113eSDavid van Moolenbroek  *   https://www.isc.org/
28*83ee113eSDavid van Moolenbroek  *
29*83ee113eSDavid van Moolenbroek  */
30*83ee113eSDavid van Moolenbroek 
31*83ee113eSDavid van Moolenbroek #include <sys/cdefs.h>
32*83ee113eSDavid van Moolenbroek __RCSID("$NetBSD: protocol.c,v 1.1.1.3 2014/07/12 11:58:00 spz Exp $");
33*83ee113eSDavid van Moolenbroek 
34*83ee113eSDavid van Moolenbroek #include "dhcpd.h"
35*83ee113eSDavid van Moolenbroek 
36*83ee113eSDavid van Moolenbroek #include <omapip/omapip_p.h>
37*83ee113eSDavid van Moolenbroek 
OMAPI_OBJECT_ALLOC(omapi_protocol,omapi_protocol_object_t,omapi_type_protocol)38*83ee113eSDavid van Moolenbroek OMAPI_OBJECT_ALLOC (omapi_protocol, omapi_protocol_object_t,
39*83ee113eSDavid van Moolenbroek 		    omapi_type_protocol)
40*83ee113eSDavid van Moolenbroek OMAPI_OBJECT_ALLOC (omapi_protocol_listener, omapi_protocol_listener_object_t,
41*83ee113eSDavid van Moolenbroek 		    omapi_type_protocol_listener)
42*83ee113eSDavid van Moolenbroek 
43*83ee113eSDavid van Moolenbroek isc_result_t omapi_protocol_connect (omapi_object_t *h,
44*83ee113eSDavid van Moolenbroek 				     const char *server_name,
45*83ee113eSDavid van Moolenbroek 				     unsigned port,
46*83ee113eSDavid van Moolenbroek 				     omapi_object_t *a)
47*83ee113eSDavid van Moolenbroek {
48*83ee113eSDavid van Moolenbroek 	isc_result_t rstatus, status;
49*83ee113eSDavid van Moolenbroek 	omapi_protocol_object_t *obj;
50*83ee113eSDavid van Moolenbroek 
51*83ee113eSDavid van Moolenbroek #ifdef DEBUG_PROTOCOL
52*83ee113eSDavid van Moolenbroek 	log_debug ("omapi_protocol_connect(%s port=%d)", server_name, port);
53*83ee113eSDavid van Moolenbroek #endif
54*83ee113eSDavid van Moolenbroek 
55*83ee113eSDavid van Moolenbroek 	obj = (omapi_protocol_object_t *)0;
56*83ee113eSDavid van Moolenbroek 	status = omapi_protocol_allocate (&obj, MDL);
57*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS)
58*83ee113eSDavid van Moolenbroek 		return status;
59*83ee113eSDavid van Moolenbroek 
60*83ee113eSDavid van Moolenbroek 	rstatus = omapi_connect ((omapi_object_t *)obj, server_name, port);
61*83ee113eSDavid van Moolenbroek 	if (rstatus != ISC_R_SUCCESS && rstatus != DHCP_R_INCOMPLETE) {
62*83ee113eSDavid van Moolenbroek 		omapi_protocol_dereference (&obj, MDL);
63*83ee113eSDavid van Moolenbroek 		return rstatus;
64*83ee113eSDavid van Moolenbroek 	}
65*83ee113eSDavid van Moolenbroek 	status = omapi_object_reference (&h -> outer,
66*83ee113eSDavid van Moolenbroek 					 (omapi_object_t *)obj, MDL);
67*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
68*83ee113eSDavid van Moolenbroek 		omapi_protocol_dereference (&obj, MDL);
69*83ee113eSDavid van Moolenbroek 		return status;
70*83ee113eSDavid van Moolenbroek 	}
71*83ee113eSDavid van Moolenbroek 	status = omapi_object_reference (&obj -> inner, h, MDL);
72*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
73*83ee113eSDavid van Moolenbroek 		omapi_protocol_dereference (&obj, MDL);
74*83ee113eSDavid van Moolenbroek 		return status;
75*83ee113eSDavid van Moolenbroek 	}
76*83ee113eSDavid van Moolenbroek 
77*83ee113eSDavid van Moolenbroek 	/* If we were passed a default authenticator, store it now.  We'll
78*83ee113eSDavid van Moolenbroek 	   open it once we're connected. */
79*83ee113eSDavid van Moolenbroek 	if (a) {
80*83ee113eSDavid van Moolenbroek 		obj -> default_auth =
81*83ee113eSDavid van Moolenbroek 			dmalloc (sizeof(omapi_remote_auth_t), MDL);
82*83ee113eSDavid van Moolenbroek 		if (!obj -> default_auth) {
83*83ee113eSDavid van Moolenbroek 			omapi_protocol_dereference (&obj, MDL);
84*83ee113eSDavid van Moolenbroek 			return ISC_R_NOMEMORY;
85*83ee113eSDavid van Moolenbroek 		}
86*83ee113eSDavid van Moolenbroek 
87*83ee113eSDavid van Moolenbroek 		obj -> default_auth -> next = (omapi_remote_auth_t *)0;
88*83ee113eSDavid van Moolenbroek 		status = omapi_object_reference (&obj -> default_auth -> a,
89*83ee113eSDavid van Moolenbroek 						 a, MDL);
90*83ee113eSDavid van Moolenbroek 		if (status != ISC_R_SUCCESS) {
91*83ee113eSDavid van Moolenbroek 			dfree (obj -> default_auth, MDL);
92*83ee113eSDavid van Moolenbroek 			omapi_protocol_dereference (&obj, MDL);
93*83ee113eSDavid van Moolenbroek 			return status;
94*83ee113eSDavid van Moolenbroek 		}
95*83ee113eSDavid van Moolenbroek 
96*83ee113eSDavid van Moolenbroek 		obj -> insecure = 0;
97*83ee113eSDavid van Moolenbroek 		rstatus = DHCP_R_INCOMPLETE;
98*83ee113eSDavid van Moolenbroek 	} else {
99*83ee113eSDavid van Moolenbroek 		obj -> insecure = 1;
100*83ee113eSDavid van Moolenbroek #if 0
101*83ee113eSDavid van Moolenbroek 		status = ISC_R_SUCCESS;
102*83ee113eSDavid van Moolenbroek #endif
103*83ee113eSDavid van Moolenbroek 	}
104*83ee113eSDavid van Moolenbroek 
105*83ee113eSDavid van Moolenbroek 	omapi_protocol_dereference (&obj, MDL);
106*83ee113eSDavid van Moolenbroek 	return rstatus;
107*83ee113eSDavid van Moolenbroek }
108*83ee113eSDavid van Moolenbroek 
109*83ee113eSDavid van Moolenbroek /* Send the protocol introduction message. */
omapi_protocol_send_intro(omapi_object_t * h,unsigned ver,unsigned hsize)110*83ee113eSDavid van Moolenbroek isc_result_t omapi_protocol_send_intro (omapi_object_t *h,
111*83ee113eSDavid van Moolenbroek 					unsigned ver,
112*83ee113eSDavid van Moolenbroek 					unsigned hsize)
113*83ee113eSDavid van Moolenbroek {
114*83ee113eSDavid van Moolenbroek 	isc_result_t status;
115*83ee113eSDavid van Moolenbroek 	omapi_protocol_object_t *p;
116*83ee113eSDavid van Moolenbroek 
117*83ee113eSDavid van Moolenbroek #ifdef DEBUG_PROTOCOL
118*83ee113eSDavid van Moolenbroek 	log_debug ("omapi_protocol_send_intro()");
119*83ee113eSDavid van Moolenbroek #endif
120*83ee113eSDavid van Moolenbroek 
121*83ee113eSDavid van Moolenbroek 	if (h -> type != omapi_type_protocol)
122*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
123*83ee113eSDavid van Moolenbroek 	p = (omapi_protocol_object_t *)h;
124*83ee113eSDavid van Moolenbroek 
125*83ee113eSDavid van Moolenbroek 	if (!h -> outer || h -> outer -> type != omapi_type_connection)
126*83ee113eSDavid van Moolenbroek 		return ISC_R_NOTCONNECTED;
127*83ee113eSDavid van Moolenbroek 
128*83ee113eSDavid van Moolenbroek 	status = omapi_connection_put_uint32 (h -> outer, ver);
129*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS)
130*83ee113eSDavid van Moolenbroek 		return status;
131*83ee113eSDavid van Moolenbroek 
132*83ee113eSDavid van Moolenbroek 	status = omapi_connection_put_uint32 (h -> outer, hsize);
133*83ee113eSDavid van Moolenbroek 
134*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS)
135*83ee113eSDavid van Moolenbroek 		return status;
136*83ee113eSDavid van Moolenbroek 
137*83ee113eSDavid van Moolenbroek 	/* Require the other end to send an intro - this kicks off the
138*83ee113eSDavid van Moolenbroek 	   protocol input state machine. */
139*83ee113eSDavid van Moolenbroek 	p -> state = omapi_protocol_intro_wait;
140*83ee113eSDavid van Moolenbroek 	status = omapi_connection_require (h -> outer, 8);
141*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS && status != DHCP_R_NOTYET)
142*83ee113eSDavid van Moolenbroek 		return status;
143*83ee113eSDavid van Moolenbroek 
144*83ee113eSDavid van Moolenbroek 	/* Make up an initial transaction ID for this connection. */
145*83ee113eSDavid van Moolenbroek 	p -> next_xid = random ();
146*83ee113eSDavid van Moolenbroek 	return ISC_R_SUCCESS;
147*83ee113eSDavid van Moolenbroek }
148*83ee113eSDavid van Moolenbroek 
149*83ee113eSDavid van Moolenbroek #ifdef DEBUG_PROTOCOL
150*83ee113eSDavid van Moolenbroek extern const char *omapi_message_op_name(int);
151*83ee113eSDavid van Moolenbroek #endif /* DEBUG_PROTOCOL */
152*83ee113eSDavid van Moolenbroek 
omapi_protocol_send_message(omapi_object_t * po,omapi_object_t * id,omapi_object_t * mo,omapi_object_t * omo)153*83ee113eSDavid van Moolenbroek isc_result_t omapi_protocol_send_message (omapi_object_t *po,
154*83ee113eSDavid van Moolenbroek 					  omapi_object_t *id,
155*83ee113eSDavid van Moolenbroek 					  omapi_object_t *mo,
156*83ee113eSDavid van Moolenbroek 					  omapi_object_t *omo)
157*83ee113eSDavid van Moolenbroek {
158*83ee113eSDavid van Moolenbroek 	omapi_protocol_object_t *p;
159*83ee113eSDavid van Moolenbroek 	omapi_object_t *c;
160*83ee113eSDavid van Moolenbroek 	omapi_message_object_t *m, *om;
161*83ee113eSDavid van Moolenbroek 	omapi_remote_auth_t *ra;
162*83ee113eSDavid van Moolenbroek 	omapi_value_t *signature;
163*83ee113eSDavid van Moolenbroek 	isc_result_t status;
164*83ee113eSDavid van Moolenbroek 	unsigned auth_len;
165*83ee113eSDavid van Moolenbroek 
166*83ee113eSDavid van Moolenbroek 	if (po -> type != omapi_type_protocol ||
167*83ee113eSDavid van Moolenbroek 	    !po -> outer || po -> outer -> type != omapi_type_connection ||
168*83ee113eSDavid van Moolenbroek 	    mo -> type != omapi_type_message)
169*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
170*83ee113eSDavid van Moolenbroek 	if (omo && omo -> type != omapi_type_message)
171*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
172*83ee113eSDavid van Moolenbroek 	p = (omapi_protocol_object_t *)po;
173*83ee113eSDavid van Moolenbroek 	c = (omapi_object_t *)(po -> outer);
174*83ee113eSDavid van Moolenbroek 	m = (omapi_message_object_t *)mo;
175*83ee113eSDavid van Moolenbroek 	om = (omapi_message_object_t *)omo;
176*83ee113eSDavid van Moolenbroek 
177*83ee113eSDavid van Moolenbroek #ifdef DEBUG_PROTOCOL
178*83ee113eSDavid van Moolenbroek 	log_debug ("omapi_protocol_send_message(): "
179*83ee113eSDavid van Moolenbroek 		   "op=%s  handle=%#lx  id=%#lx  rid=%#lx",
180*83ee113eSDavid van Moolenbroek 		   omapi_message_op_name (m->op),
181*83ee113eSDavid van Moolenbroek 		   (long)(m -> object ? m -> object -> handle : m -> handle),
182*83ee113eSDavid van Moolenbroek 		   (long)p -> next_xid, (long)m -> rid);
183*83ee113eSDavid van Moolenbroek #endif
184*83ee113eSDavid van Moolenbroek 
185*83ee113eSDavid van Moolenbroek 	/* Find the authid to use for this message. */
186*83ee113eSDavid van Moolenbroek 	if (id) {
187*83ee113eSDavid van Moolenbroek 		for (ra = p -> remote_auth_list; ra; ra = ra -> next) {
188*83ee113eSDavid van Moolenbroek 			if (ra -> a == id) {
189*83ee113eSDavid van Moolenbroek 				break;
190*83ee113eSDavid van Moolenbroek 			}
191*83ee113eSDavid van Moolenbroek 		}
192*83ee113eSDavid van Moolenbroek 
193*83ee113eSDavid van Moolenbroek 		if (!ra)
194*83ee113eSDavid van Moolenbroek 			return DHCP_R_KEY_UNKNOWN;
195*83ee113eSDavid van Moolenbroek 	} else if (p -> remote_auth_list) {
196*83ee113eSDavid van Moolenbroek 		ra = p -> default_auth;
197*83ee113eSDavid van Moolenbroek 	} else {
198*83ee113eSDavid van Moolenbroek 		ra = (omapi_remote_auth_t *)0;
199*83ee113eSDavid van Moolenbroek 	}
200*83ee113eSDavid van Moolenbroek 
201*83ee113eSDavid van Moolenbroek 	if (ra) {
202*83ee113eSDavid van Moolenbroek 		m -> authid = ra -> remote_handle;
203*83ee113eSDavid van Moolenbroek 		status = omapi_object_reference (&m -> id_object,
204*83ee113eSDavid van Moolenbroek 						 ra -> a, MDL);
205*83ee113eSDavid van Moolenbroek 		if (status != ISC_R_SUCCESS)
206*83ee113eSDavid van Moolenbroek 			return status;
207*83ee113eSDavid van Moolenbroek 	}
208*83ee113eSDavid van Moolenbroek 
209*83ee113eSDavid van Moolenbroek 	/* Write the ID of the authentication key we're using. */
210*83ee113eSDavid van Moolenbroek 	status = omapi_connection_put_uint32 (c, ra ? ra -> remote_handle : 0);
211*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
212*83ee113eSDavid van Moolenbroek 		omapi_disconnect (c, 1);
213*83ee113eSDavid van Moolenbroek 		return status;
214*83ee113eSDavid van Moolenbroek 	}
215*83ee113eSDavid van Moolenbroek 
216*83ee113eSDavid van Moolenbroek 	/* Activate the authentication key on the connection. */
217*83ee113eSDavid van Moolenbroek 	auth_len = 0;
218*83ee113eSDavid van Moolenbroek 	if (ra) {
219*83ee113eSDavid van Moolenbroek 		status = omapi_set_object_value (c, (omapi_object_t *)0,
220*83ee113eSDavid van Moolenbroek 						 "output-authenticator",
221*83ee113eSDavid van Moolenbroek 						 ra -> a);
222*83ee113eSDavid van Moolenbroek 		if (status != ISC_R_SUCCESS) {
223*83ee113eSDavid van Moolenbroek 			omapi_disconnect (c, 1);
224*83ee113eSDavid van Moolenbroek 			return status;
225*83ee113eSDavid van Moolenbroek 		}
226*83ee113eSDavid van Moolenbroek 
227*83ee113eSDavid van Moolenbroek 		status = omapi_connection_output_auth_length (c, &auth_len);
228*83ee113eSDavid van Moolenbroek 		if (status != ISC_R_SUCCESS) {
229*83ee113eSDavid van Moolenbroek 			omapi_disconnect (c, 1);
230*83ee113eSDavid van Moolenbroek 			return status;
231*83ee113eSDavid van Moolenbroek 		}
232*83ee113eSDavid van Moolenbroek 	}
233*83ee113eSDavid van Moolenbroek 
234*83ee113eSDavid van Moolenbroek 	/* Write the authenticator length */
235*83ee113eSDavid van Moolenbroek 	status = omapi_connection_put_uint32 (c, auth_len);
236*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
237*83ee113eSDavid van Moolenbroek 		omapi_disconnect (c, 1);
238*83ee113eSDavid van Moolenbroek 		return status;
239*83ee113eSDavid van Moolenbroek 	}
240*83ee113eSDavid van Moolenbroek 
241*83ee113eSDavid van Moolenbroek 	/* Write the opcode. */
242*83ee113eSDavid van Moolenbroek 	status = omapi_connection_put_uint32 (c, m -> op);
243*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
244*83ee113eSDavid van Moolenbroek 		omapi_disconnect (c, 1);
245*83ee113eSDavid van Moolenbroek 		return status;
246*83ee113eSDavid van Moolenbroek 	}
247*83ee113eSDavid van Moolenbroek 
248*83ee113eSDavid van Moolenbroek 	/* Write the handle.  If we've been given an explicit handle, use
249*83ee113eSDavid van Moolenbroek 	   that.   Otherwise, use the handle of the object we're sending.
250*83ee113eSDavid van Moolenbroek 	   The caller is responsible for arranging for one of these handles
251*83ee113eSDavid van Moolenbroek 	   to be set (or not). */
252*83ee113eSDavid van Moolenbroek 	status = omapi_connection_put_uint32 (c, (m -> h
253*83ee113eSDavid van Moolenbroek 						  ? m -> h
254*83ee113eSDavid van Moolenbroek 						  : (m -> object
255*83ee113eSDavid van Moolenbroek 						     ? m -> object -> handle
256*83ee113eSDavid van Moolenbroek 						     : 0)));
257*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
258*83ee113eSDavid van Moolenbroek 		omapi_disconnect (c, 1);
259*83ee113eSDavid van Moolenbroek 		return status;
260*83ee113eSDavid van Moolenbroek 	}
261*83ee113eSDavid van Moolenbroek 
262*83ee113eSDavid van Moolenbroek 	/* Set and write the transaction ID. */
263*83ee113eSDavid van Moolenbroek 	m -> id = p -> next_xid++;
264*83ee113eSDavid van Moolenbroek 	status = omapi_connection_put_uint32 (c, m -> id);
265*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
266*83ee113eSDavid van Moolenbroek 		omapi_disconnect (c, 1);
267*83ee113eSDavid van Moolenbroek 		return status;
268*83ee113eSDavid van Moolenbroek 	}
269*83ee113eSDavid van Moolenbroek 
270*83ee113eSDavid van Moolenbroek 	/* Write the transaction ID of the message to which this is a
271*83ee113eSDavid van Moolenbroek 	   response, if there is such a message. */
272*83ee113eSDavid van Moolenbroek 	status = omapi_connection_put_uint32 (c, om ? om -> id : m -> rid);
273*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
274*83ee113eSDavid van Moolenbroek 		omapi_disconnect (c, 1);
275*83ee113eSDavid van Moolenbroek 		return status;
276*83ee113eSDavid van Moolenbroek 	}
277*83ee113eSDavid van Moolenbroek 
278*83ee113eSDavid van Moolenbroek 	/* Stuff out the name/value pairs specific to this message. */
279*83ee113eSDavid van Moolenbroek 	status = omapi_stuff_values (c, id, (omapi_object_t *)m);
280*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
281*83ee113eSDavid van Moolenbroek 		omapi_disconnect (c, 1);
282*83ee113eSDavid van Moolenbroek 		return status;
283*83ee113eSDavid van Moolenbroek 	}
284*83ee113eSDavid van Moolenbroek 
285*83ee113eSDavid van Moolenbroek 	/* Write the zero-length name that terminates the list of name/value
286*83ee113eSDavid van Moolenbroek 	   pairs specific to the message. */
287*83ee113eSDavid van Moolenbroek 	status = omapi_connection_put_uint16 (c, 0);
288*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
289*83ee113eSDavid van Moolenbroek 		omapi_disconnect (c, 1);
290*83ee113eSDavid van Moolenbroek 		return status;
291*83ee113eSDavid van Moolenbroek 	}
292*83ee113eSDavid van Moolenbroek 
293*83ee113eSDavid van Moolenbroek 	/* Stuff out all the published name/value pairs in the object that's
294*83ee113eSDavid van Moolenbroek 	   being sent in the message, if there is one. */
295*83ee113eSDavid van Moolenbroek 	if (m -> object) {
296*83ee113eSDavid van Moolenbroek 		status = omapi_stuff_values (c, id, m -> object);
297*83ee113eSDavid van Moolenbroek 		if (status != ISC_R_SUCCESS) {
298*83ee113eSDavid van Moolenbroek 			omapi_disconnect (c, 1);
299*83ee113eSDavid van Moolenbroek 			return status;
300*83ee113eSDavid van Moolenbroek 		}
301*83ee113eSDavid van Moolenbroek 	}
302*83ee113eSDavid van Moolenbroek 
303*83ee113eSDavid van Moolenbroek 	/* Write the zero-length name that terminates the list of name/value
304*83ee113eSDavid van Moolenbroek 	   pairs for the associated object. */
305*83ee113eSDavid van Moolenbroek 	status = omapi_connection_put_uint16 (c, 0);
306*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
307*83ee113eSDavid van Moolenbroek 		omapi_disconnect (c, 1);
308*83ee113eSDavid van Moolenbroek 		return status;
309*83ee113eSDavid van Moolenbroek 	}
310*83ee113eSDavid van Moolenbroek 
311*83ee113eSDavid van Moolenbroek 	if (ra) {
312*83ee113eSDavid van Moolenbroek 		/* Calculate the message signature. */
313*83ee113eSDavid van Moolenbroek 		signature = (omapi_value_t *)0;
314*83ee113eSDavid van Moolenbroek 		status = omapi_get_value_str (c, (omapi_object_t *)0,
315*83ee113eSDavid van Moolenbroek 					      "output-signature", &signature);
316*83ee113eSDavid van Moolenbroek 		if (status != ISC_R_SUCCESS) {
317*83ee113eSDavid van Moolenbroek 			omapi_disconnect (c, 1);
318*83ee113eSDavid van Moolenbroek 			return status;
319*83ee113eSDavid van Moolenbroek 		}
320*83ee113eSDavid van Moolenbroek 
321*83ee113eSDavid van Moolenbroek 		/* Write the authenticator... */
322*83ee113eSDavid van Moolenbroek 		status = (omapi_connection_copyin
323*83ee113eSDavid van Moolenbroek 			  (c, signature -> value -> u.buffer.value,
324*83ee113eSDavid van Moolenbroek 			   signature -> value -> u.buffer.len));
325*83ee113eSDavid van Moolenbroek 		omapi_value_dereference (&signature, MDL);
326*83ee113eSDavid van Moolenbroek 		if (status != ISC_R_SUCCESS) {
327*83ee113eSDavid van Moolenbroek 			omapi_disconnect (c, 1);
328*83ee113eSDavid van Moolenbroek 			return status;
329*83ee113eSDavid van Moolenbroek 		}
330*83ee113eSDavid van Moolenbroek 
331*83ee113eSDavid van Moolenbroek 		/* Dectivate the authentication key on the connection. */
332*83ee113eSDavid van Moolenbroek 		status = omapi_set_value_str (c, (omapi_object_t *)0,
333*83ee113eSDavid van Moolenbroek 						 "output-authenticator",
334*83ee113eSDavid van Moolenbroek 						 (omapi_typed_data_t *)0);
335*83ee113eSDavid van Moolenbroek 		if (status != ISC_R_SUCCESS) {
336*83ee113eSDavid van Moolenbroek 			omapi_disconnect (c, 1);
337*83ee113eSDavid van Moolenbroek 			return status;
338*83ee113eSDavid van Moolenbroek 		}
339*83ee113eSDavid van Moolenbroek 	}
340*83ee113eSDavid van Moolenbroek 
341*83ee113eSDavid van Moolenbroek 	if (!omo) {
342*83ee113eSDavid van Moolenbroek 		omapi_protocol_reference (&m -> protocol_object, p, MDL);
343*83ee113eSDavid van Moolenbroek 	}
344*83ee113eSDavid van Moolenbroek 	return ISC_R_SUCCESS;
345*83ee113eSDavid van Moolenbroek }
346*83ee113eSDavid van Moolenbroek 
347*83ee113eSDavid van Moolenbroek 
omapi_protocol_signal_handler(omapi_object_t * h,const char * name,va_list ap)348*83ee113eSDavid van Moolenbroek isc_result_t omapi_protocol_signal_handler (omapi_object_t *h,
349*83ee113eSDavid van Moolenbroek 					    const char *name, va_list ap)
350*83ee113eSDavid van Moolenbroek {
351*83ee113eSDavid van Moolenbroek 	isc_result_t status;
352*83ee113eSDavid van Moolenbroek 	omapi_protocol_object_t *p;
353*83ee113eSDavid van Moolenbroek 	omapi_object_t *c;
354*83ee113eSDavid van Moolenbroek 	omapi_message_object_t *m;
355*83ee113eSDavid van Moolenbroek 	omapi_value_t *signature = NULL;
356*83ee113eSDavid van Moolenbroek 	u_int16_t nlen;
357*83ee113eSDavid van Moolenbroek 	u_int32_t vlen;
358*83ee113eSDavid van Moolenbroek 	u_int32_t th;
359*83ee113eSDavid van Moolenbroek #if defined (DEBUG_MEMORY_LEAKAGE)
360*83ee113eSDavid van Moolenbroek 	unsigned long previous_outstanding = 0xDEADBEEF;
361*83ee113eSDavid van Moolenbroek 	unsigned long connect_outstanding = 0xDEADBEEF;
362*83ee113eSDavid van Moolenbroek #endif
363*83ee113eSDavid van Moolenbroek 
364*83ee113eSDavid van Moolenbroek 	if (h -> type != omapi_type_protocol) {
365*83ee113eSDavid van Moolenbroek 		/* XXX shouldn't happen.   Put an assert here? */
366*83ee113eSDavid van Moolenbroek 		return ISC_R_UNEXPECTED;
367*83ee113eSDavid van Moolenbroek 	}
368*83ee113eSDavid van Moolenbroek 	p = (omapi_protocol_object_t *)h;
369*83ee113eSDavid van Moolenbroek 
370*83ee113eSDavid van Moolenbroek 	if (!strcmp (name, "connect")) {
371*83ee113eSDavid van Moolenbroek #if defined (DEBUG_MEMORY_LEAKAGE)
372*83ee113eSDavid van Moolenbroek 		connect_outstanding = dmalloc_outstanding;
373*83ee113eSDavid van Moolenbroek #endif
374*83ee113eSDavid van Moolenbroek 		/* Send the introductory message. */
375*83ee113eSDavid van Moolenbroek 		status = omapi_protocol_send_intro
376*83ee113eSDavid van Moolenbroek 			(h, OMAPI_PROTOCOL_VERSION,
377*83ee113eSDavid van Moolenbroek 			 sizeof (omapi_protocol_header_t));
378*83ee113eSDavid van Moolenbroek 		if (status != ISC_R_SUCCESS) {
379*83ee113eSDavid van Moolenbroek 			omapi_disconnect (p -> outer, 1);
380*83ee113eSDavid van Moolenbroek 			return status;
381*83ee113eSDavid van Moolenbroek 		}
382*83ee113eSDavid van Moolenbroek 		return ISC_R_SUCCESS;
383*83ee113eSDavid van Moolenbroek 	}
384*83ee113eSDavid van Moolenbroek 
385*83ee113eSDavid van Moolenbroek 	/* Should only receive these when opening the initial authenticator. */
386*83ee113eSDavid van Moolenbroek 	if (!strcmp (name, "status")) {
387*83ee113eSDavid van Moolenbroek 		status = va_arg (ap, isc_result_t);
388*83ee113eSDavid van Moolenbroek 		if (status != ISC_R_SUCCESS) {
389*83ee113eSDavid van Moolenbroek 			omapi_signal_in (h -> inner, "status", status,
390*83ee113eSDavid van Moolenbroek 					 (omapi_object_t *)0);
391*83ee113eSDavid van Moolenbroek 			omapi_disconnect (p -> outer, 1);
392*83ee113eSDavid van Moolenbroek 			return status;
393*83ee113eSDavid van Moolenbroek 		} else {
394*83ee113eSDavid van Moolenbroek 			return omapi_signal_in (h -> inner, "ready");
395*83ee113eSDavid van Moolenbroek 		}
396*83ee113eSDavid van Moolenbroek 	}
397*83ee113eSDavid van Moolenbroek 
398*83ee113eSDavid van Moolenbroek 	/* If we get a disconnect, dump memory usage. */
399*83ee113eSDavid van Moolenbroek 	if (!strcmp (name, "disconnect")) {
400*83ee113eSDavid van Moolenbroek #if defined (DEBUG_MEMORY_LEAKAGE)
401*83ee113eSDavid van Moolenbroek 	    if (connect_outstanding != 0xDEADBEEF) {
402*83ee113eSDavid van Moolenbroek 		log_info ("generation %ld: %ld new, %ld outstanding, %ld%s",
403*83ee113eSDavid van Moolenbroek 			  dmalloc_generation,
404*83ee113eSDavid van Moolenbroek 			  dmalloc_outstanding - previous_outstanding,
405*83ee113eSDavid van Moolenbroek 			  dmalloc_outstanding, dmalloc_longterm, " long-term");
406*83ee113eSDavid van Moolenbroek 	    }
407*83ee113eSDavid van Moolenbroek #endif
408*83ee113eSDavid van Moolenbroek #if defined (DEBUG_MEMORY_LEAKAGE)
409*83ee113eSDavid van Moolenbroek 	    dmalloc_dump_outstanding ();
410*83ee113eSDavid van Moolenbroek #endif
411*83ee113eSDavid van Moolenbroek #if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY)
412*83ee113eSDavid van Moolenbroek 	    dump_rc_history (h);
413*83ee113eSDavid van Moolenbroek #endif
414*83ee113eSDavid van Moolenbroek 	    for (m = omapi_registered_messages; m; m = m -> next) {
415*83ee113eSDavid van Moolenbroek 		if (m -> protocol_object == p) {
416*83ee113eSDavid van Moolenbroek 		    if (m -> object)
417*83ee113eSDavid van Moolenbroek 			omapi_signal (m -> object, "disconnect");
418*83ee113eSDavid van Moolenbroek 		}
419*83ee113eSDavid van Moolenbroek 	    }
420*83ee113eSDavid van Moolenbroek 
421*83ee113eSDavid van Moolenbroek 	    /* XXX */
422*83ee113eSDavid van Moolenbroek 	    return ISC_R_SUCCESS;
423*83ee113eSDavid van Moolenbroek 	}
424*83ee113eSDavid van Moolenbroek 
425*83ee113eSDavid van Moolenbroek 	/* Not a signal we recognize? */
426*83ee113eSDavid van Moolenbroek 	if (strcmp (name, "ready")) {
427*83ee113eSDavid van Moolenbroek 		if (p -> inner && p -> inner -> type -> signal_handler)
428*83ee113eSDavid van Moolenbroek 			return (*(p -> inner -> type -> signal_handler)) (h,
429*83ee113eSDavid van Moolenbroek 									  name,
430*83ee113eSDavid van Moolenbroek 									  ap);
431*83ee113eSDavid van Moolenbroek 		return ISC_R_NOTFOUND;
432*83ee113eSDavid van Moolenbroek 	}
433*83ee113eSDavid van Moolenbroek 
434*83ee113eSDavid van Moolenbroek 	if (!p -> outer || p -> outer -> type != omapi_type_connection)
435*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
436*83ee113eSDavid van Moolenbroek 	c = p -> outer;
437*83ee113eSDavid van Moolenbroek 
438*83ee113eSDavid van Moolenbroek 	/* We get here because we requested that we be woken up after
439*83ee113eSDavid van Moolenbroek            some number of bytes were read, and that number of bytes
440*83ee113eSDavid van Moolenbroek            has in fact been read. */
441*83ee113eSDavid van Moolenbroek 	switch (p -> state) {
442*83ee113eSDavid van Moolenbroek 	      case omapi_protocol_intro_wait:
443*83ee113eSDavid van Moolenbroek 		/* Get protocol version and header size in network
444*83ee113eSDavid van Moolenbroek 		   byte order. */
445*83ee113eSDavid van Moolenbroek 		omapi_connection_get_uint32 (c, &p -> protocol_version);
446*83ee113eSDavid van Moolenbroek 		omapi_connection_get_uint32 (c, &p -> header_size);
447*83ee113eSDavid van Moolenbroek 
448*83ee113eSDavid van Moolenbroek 		/* We currently only support the current protocol version. */
449*83ee113eSDavid van Moolenbroek 		if (p -> protocol_version != OMAPI_PROTOCOL_VERSION) {
450*83ee113eSDavid van Moolenbroek 			omapi_disconnect (c, 1);
451*83ee113eSDavid van Moolenbroek 			return DHCP_R_VERSIONMISMATCH;
452*83ee113eSDavid van Moolenbroek 		}
453*83ee113eSDavid van Moolenbroek 
454*83ee113eSDavid van Moolenbroek 		if (p -> header_size < sizeof (omapi_protocol_header_t)) {
455*83ee113eSDavid van Moolenbroek 			omapi_disconnect (c, 1);
456*83ee113eSDavid van Moolenbroek 			return DHCP_R_PROTOCOLERROR;
457*83ee113eSDavid van Moolenbroek 		}
458*83ee113eSDavid van Moolenbroek 
459*83ee113eSDavid van Moolenbroek 		if (p -> default_auth) {
460*83ee113eSDavid van Moolenbroek 			status = omapi_protocol_send_open
461*83ee113eSDavid van Moolenbroek 				(h, (omapi_object_t *)0, "authenticator",
462*83ee113eSDavid van Moolenbroek 				 p -> default_auth -> a,
463*83ee113eSDavid van Moolenbroek 				 OMAPI_NOTIFY_PROTOCOL);
464*83ee113eSDavid van Moolenbroek 			if (status != ISC_R_SUCCESS) {
465*83ee113eSDavid van Moolenbroek 				omapi_disconnect (c, 1);
466*83ee113eSDavid van Moolenbroek 				return status;
467*83ee113eSDavid van Moolenbroek 			}
468*83ee113eSDavid van Moolenbroek 		} else {
469*83ee113eSDavid van Moolenbroek 			status = omapi_signal_in (h -> inner, "ready");
470*83ee113eSDavid van Moolenbroek 		}
471*83ee113eSDavid van Moolenbroek 
472*83ee113eSDavid van Moolenbroek 	      to_header_wait:
473*83ee113eSDavid van Moolenbroek 		/* The next thing we're expecting is a message header. */
474*83ee113eSDavid van Moolenbroek 		p -> state = omapi_protocol_header_wait;
475*83ee113eSDavid van Moolenbroek 
476*83ee113eSDavid van Moolenbroek 		/* Register a need for the number of bytes in a
477*83ee113eSDavid van Moolenbroek 		   header, and if we already have that many, process
478*83ee113eSDavid van Moolenbroek 		   them immediately. */
479*83ee113eSDavid van Moolenbroek 		if ((omapi_connection_require (c, p -> header_size)) !=
480*83ee113eSDavid van Moolenbroek 		    ISC_R_SUCCESS)
481*83ee113eSDavid van Moolenbroek 			break;
482*83ee113eSDavid van Moolenbroek 		/* If we already have the data, fall through. */
483*83ee113eSDavid van Moolenbroek 
484*83ee113eSDavid van Moolenbroek 	      case omapi_protocol_header_wait:
485*83ee113eSDavid van Moolenbroek #if defined (DEBUG_MEMORY_LEAKAGE)
486*83ee113eSDavid van Moolenbroek 		if (previous_outstanding != 0xDEADBEEF) {
487*83ee113eSDavid van Moolenbroek 			log_info ("%s %ld: %ld new, %ld outstanding, %ld%s",
488*83ee113eSDavid van Moolenbroek 				  "generation", dmalloc_generation,
489*83ee113eSDavid van Moolenbroek 				  dmalloc_outstanding - previous_outstanding,
490*83ee113eSDavid van Moolenbroek 				  dmalloc_outstanding, dmalloc_longterm,
491*83ee113eSDavid van Moolenbroek 				  " long-term");
492*83ee113eSDavid van Moolenbroek #endif
493*83ee113eSDavid van Moolenbroek #if (defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL))
494*83ee113eSDavid van Moolenbroek 			dmalloc_dump_outstanding ();
495*83ee113eSDavid van Moolenbroek #endif
496*83ee113eSDavid van Moolenbroek #if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY)
497*83ee113eSDavid van Moolenbroek 			dump_rc_history (h);
498*83ee113eSDavid van Moolenbroek #endif
499*83ee113eSDavid van Moolenbroek #if defined (DEBUG_MEMORY_LEAKAGE)
500*83ee113eSDavid van Moolenbroek 		}
501*83ee113eSDavid van Moolenbroek 		previous_outstanding = dmalloc_outstanding;
502*83ee113eSDavid van Moolenbroek #endif
503*83ee113eSDavid van Moolenbroek 		status = omapi_message_new ((omapi_object_t **)&p -> message,
504*83ee113eSDavid van Moolenbroek 					    MDL);
505*83ee113eSDavid van Moolenbroek 		if (status != ISC_R_SUCCESS) {
506*83ee113eSDavid van Moolenbroek 			omapi_disconnect (c, 1);
507*83ee113eSDavid van Moolenbroek 			return status;
508*83ee113eSDavid van Moolenbroek 		}
509*83ee113eSDavid van Moolenbroek 
510*83ee113eSDavid van Moolenbroek 		p -> verify_result = ISC_R_SUCCESS;
511*83ee113eSDavid van Moolenbroek 
512*83ee113eSDavid van Moolenbroek 		/* Swap in the header... */
513*83ee113eSDavid van Moolenbroek 		omapi_connection_get_uint32 (c, &p -> message -> authid);
514*83ee113eSDavid van Moolenbroek 
515*83ee113eSDavid van Moolenbroek 		/* Bind the authenticator to the message object. */
516*83ee113eSDavid van Moolenbroek 		if (p -> message -> authid) {
517*83ee113eSDavid van Moolenbroek 			status = (omapi_protocol_lookup_auth
518*83ee113eSDavid van Moolenbroek 				  (&p -> message -> id_object, h,
519*83ee113eSDavid van Moolenbroek 				   p -> message -> authid));
520*83ee113eSDavid van Moolenbroek 			if (status != ISC_R_SUCCESS)
521*83ee113eSDavid van Moolenbroek 				p -> verify_result = status;
522*83ee113eSDavid van Moolenbroek 
523*83ee113eSDavid van Moolenbroek 			/* Activate the authentication key. */
524*83ee113eSDavid van Moolenbroek 			status = omapi_set_object_value
525*83ee113eSDavid van Moolenbroek 				(c, (omapi_object_t *)0, "input-authenticator",
526*83ee113eSDavid van Moolenbroek 				 p -> message -> id_object);
527*83ee113eSDavid van Moolenbroek 			if (status != ISC_R_SUCCESS) {
528*83ee113eSDavid van Moolenbroek 				omapi_disconnect (c, 1);
529*83ee113eSDavid van Moolenbroek 				return status;
530*83ee113eSDavid van Moolenbroek 			}
531*83ee113eSDavid van Moolenbroek 		}
532*83ee113eSDavid van Moolenbroek 
533*83ee113eSDavid van Moolenbroek 		omapi_connection_get_uint32 (c, &p -> message -> authlen);
534*83ee113eSDavid van Moolenbroek 		omapi_connection_get_uint32 (c, &p -> message -> op);
535*83ee113eSDavid van Moolenbroek 		omapi_connection_get_uint32 (c, &th);
536*83ee113eSDavid van Moolenbroek 		p -> message -> h = th;
537*83ee113eSDavid van Moolenbroek 		omapi_connection_get_uint32 (c, &p -> message -> id);
538*83ee113eSDavid van Moolenbroek 		omapi_connection_get_uint32 (c, &p -> message -> rid);
539*83ee113eSDavid van Moolenbroek 
540*83ee113eSDavid van Moolenbroek 		/* If there was any extra header data, skip over it. */
541*83ee113eSDavid van Moolenbroek 		if (p -> header_size > sizeof (omapi_protocol_header_t)) {
542*83ee113eSDavid van Moolenbroek 			omapi_connection_copyout
543*83ee113eSDavid van Moolenbroek 				(0, c, (p -> header_size -
544*83ee113eSDavid van Moolenbroek 					sizeof (omapi_protocol_header_t)));
545*83ee113eSDavid van Moolenbroek 		}
546*83ee113eSDavid van Moolenbroek 
547*83ee113eSDavid van Moolenbroek 		/* XXX must compute partial signature across the
548*83ee113eSDavid van Moolenbroek                    XXX preceding bytes.    Also, if authenticator
549*83ee113eSDavid van Moolenbroek 		   specifies encryption as well as signing, we may
550*83ee113eSDavid van Moolenbroek 		   have to decrypt the data on the way in. */
551*83ee113eSDavid van Moolenbroek 
552*83ee113eSDavid van Moolenbroek 		/* First we read in message-specific values, then object
553*83ee113eSDavid van Moolenbroek 		   values. */
554*83ee113eSDavid van Moolenbroek 		p -> reading_message_values = 1;
555*83ee113eSDavid van Moolenbroek 
556*83ee113eSDavid van Moolenbroek 	      need_name_length:
557*83ee113eSDavid van Moolenbroek 		/* The next thing we're expecting is length of the
558*83ee113eSDavid van Moolenbroek 		   first name. */
559*83ee113eSDavid van Moolenbroek 		p -> state = omapi_protocol_name_length_wait;
560*83ee113eSDavid van Moolenbroek 
561*83ee113eSDavid van Moolenbroek 		/* Wait for a 16-bit length. */
562*83ee113eSDavid van Moolenbroek 		if ((omapi_connection_require (c, 2)) != ISC_R_SUCCESS)
563*83ee113eSDavid van Moolenbroek 			break;
564*83ee113eSDavid van Moolenbroek 		/* If it's already here, fall through. */
565*83ee113eSDavid van Moolenbroek 
566*83ee113eSDavid van Moolenbroek 	      case omapi_protocol_name_length_wait:
567*83ee113eSDavid van Moolenbroek 		omapi_connection_get_uint16 (c, &nlen);
568*83ee113eSDavid van Moolenbroek 		/* A zero-length name means that we're done reading name+value
569*83ee113eSDavid van Moolenbroek 		   pairs. */
570*83ee113eSDavid van Moolenbroek 		if (nlen == 0) {
571*83ee113eSDavid van Moolenbroek 			/* If we've already read in the object, we are
572*83ee113eSDavid van Moolenbroek 			   done reading the message, but if we've just
573*83ee113eSDavid van Moolenbroek 			   finished reading in the values associated
574*83ee113eSDavid van Moolenbroek 			   with the message, we need to read the
575*83ee113eSDavid van Moolenbroek 			   object. */
576*83ee113eSDavid van Moolenbroek 			if (p -> reading_message_values) {
577*83ee113eSDavid van Moolenbroek 				p -> reading_message_values = 0;
578*83ee113eSDavid van Moolenbroek 				goto need_name_length;
579*83ee113eSDavid van Moolenbroek 			}
580*83ee113eSDavid van Moolenbroek 
581*83ee113eSDavid van Moolenbroek 			/* If the authenticator length is zero, there's no
582*83ee113eSDavid van Moolenbroek 			   signature to read in, so go straight to processing
583*83ee113eSDavid van Moolenbroek 			   the message. */
584*83ee113eSDavid van Moolenbroek 			if (p -> message -> authlen == 0)
585*83ee113eSDavid van Moolenbroek 				goto message_done;
586*83ee113eSDavid van Moolenbroek 
587*83ee113eSDavid van Moolenbroek 			/* The next thing we're expecting is the
588*83ee113eSDavid van Moolenbroek                            message signature. */
589*83ee113eSDavid van Moolenbroek 			p -> state = omapi_protocol_signature_wait;
590*83ee113eSDavid van Moolenbroek 
591*83ee113eSDavid van Moolenbroek 			/* Wait for the number of bytes specified for
592*83ee113eSDavid van Moolenbroek 			   the authenticator.  If we already have it,
593*83ee113eSDavid van Moolenbroek 			   go read it in. */
594*83ee113eSDavid van Moolenbroek 			if (omapi_connection_require
595*83ee113eSDavid van Moolenbroek 			    (c, p -> message -> authlen) == ISC_R_SUCCESS)
596*83ee113eSDavid van Moolenbroek 				goto signature_wait;
597*83ee113eSDavid van Moolenbroek 			break;
598*83ee113eSDavid van Moolenbroek 		}
599*83ee113eSDavid van Moolenbroek 
600*83ee113eSDavid van Moolenbroek 		/* Allocate a buffer for the name. */
601*83ee113eSDavid van Moolenbroek 		status = (omapi_data_string_new (&p -> name, nlen, MDL));
602*83ee113eSDavid van Moolenbroek 		if (status != ISC_R_SUCCESS) {
603*83ee113eSDavid van Moolenbroek 			omapi_disconnect (c, 1);
604*83ee113eSDavid van Moolenbroek 			return ISC_R_NOMEMORY;
605*83ee113eSDavid van Moolenbroek 		}
606*83ee113eSDavid van Moolenbroek 		p -> state = omapi_protocol_name_wait;
607*83ee113eSDavid van Moolenbroek 		if (omapi_connection_require (c, nlen) != ISC_R_SUCCESS)
608*83ee113eSDavid van Moolenbroek 			break;
609*83ee113eSDavid van Moolenbroek 		/* If it's already here, fall through. */
610*83ee113eSDavid van Moolenbroek 
611*83ee113eSDavid van Moolenbroek 	      case omapi_protocol_name_wait:
612*83ee113eSDavid van Moolenbroek 		omapi_connection_copyout (p -> name -> value, c,
613*83ee113eSDavid van Moolenbroek 					  p -> name -> len);
614*83ee113eSDavid van Moolenbroek 		/* Wait for a 32-bit length. */
615*83ee113eSDavid van Moolenbroek 		p -> state = omapi_protocol_value_length_wait;
616*83ee113eSDavid van Moolenbroek 		if ((omapi_connection_require (c, 4)) != ISC_R_SUCCESS)
617*83ee113eSDavid van Moolenbroek 			break;
618*83ee113eSDavid van Moolenbroek 		/* If it's already here, fall through. */
619*83ee113eSDavid van Moolenbroek 
620*83ee113eSDavid van Moolenbroek 	      case omapi_protocol_value_length_wait:
621*83ee113eSDavid van Moolenbroek 		omapi_connection_get_uint32 (c, &vlen);
622*83ee113eSDavid van Moolenbroek 
623*83ee113eSDavid van Moolenbroek 		/* Zero-length values are allowed - if we get one, we
624*83ee113eSDavid van Moolenbroek 		   don't have to read any data for the value - just
625*83ee113eSDavid van Moolenbroek 		   get the next one, if there is a next one. */
626*83ee113eSDavid van Moolenbroek 		if (!vlen)
627*83ee113eSDavid van Moolenbroek 			goto insert_new_value;
628*83ee113eSDavid van Moolenbroek 
629*83ee113eSDavid van Moolenbroek 		status = omapi_typed_data_new (MDL, &p -> value,
630*83ee113eSDavid van Moolenbroek 					       omapi_datatype_data,
631*83ee113eSDavid van Moolenbroek 					       vlen);
632*83ee113eSDavid van Moolenbroek 		if (status != ISC_R_SUCCESS) {
633*83ee113eSDavid van Moolenbroek 			omapi_disconnect (c, 1);
634*83ee113eSDavid van Moolenbroek 			return ISC_R_NOMEMORY;
635*83ee113eSDavid van Moolenbroek 		}
636*83ee113eSDavid van Moolenbroek 
637*83ee113eSDavid van Moolenbroek 		p -> state = omapi_protocol_value_wait;
638*83ee113eSDavid van Moolenbroek 		if (omapi_connection_require (c, vlen) != ISC_R_SUCCESS)
639*83ee113eSDavid van Moolenbroek 			break;
640*83ee113eSDavid van Moolenbroek 		/* If it's already here, fall through. */
641*83ee113eSDavid van Moolenbroek 
642*83ee113eSDavid van Moolenbroek 	      case omapi_protocol_value_wait:
643*83ee113eSDavid van Moolenbroek 		omapi_connection_copyout (p -> value -> u.buffer.value, c,
644*83ee113eSDavid van Moolenbroek 					  p -> value -> u.buffer.len);
645*83ee113eSDavid van Moolenbroek 
646*83ee113eSDavid van Moolenbroek 	      insert_new_value:
647*83ee113eSDavid van Moolenbroek 		if (p -> reading_message_values) {
648*83ee113eSDavid van Moolenbroek 			status = (omapi_set_value
649*83ee113eSDavid van Moolenbroek 				  ((omapi_object_t *)p -> message,
650*83ee113eSDavid van Moolenbroek 				   p -> message -> id_object,
651*83ee113eSDavid van Moolenbroek 				   p -> name, p -> value));
652*83ee113eSDavid van Moolenbroek 		} else {
653*83ee113eSDavid van Moolenbroek 			if (!p -> message -> object) {
654*83ee113eSDavid van Moolenbroek 				/* We need a generic object to hang off of the
655*83ee113eSDavid van Moolenbroek 				   incoming message. */
656*83ee113eSDavid van Moolenbroek 				status = (omapi_generic_new
657*83ee113eSDavid van Moolenbroek 					  (&p -> message -> object, MDL));
658*83ee113eSDavid van Moolenbroek 				if (status != ISC_R_SUCCESS) {
659*83ee113eSDavid van Moolenbroek 					omapi_disconnect (c, 1);
660*83ee113eSDavid van Moolenbroek 					return status;
661*83ee113eSDavid van Moolenbroek 				}
662*83ee113eSDavid van Moolenbroek 			}
663*83ee113eSDavid van Moolenbroek 			status = (omapi_set_value
664*83ee113eSDavid van Moolenbroek 				  ((omapi_object_t *)p -> message -> object,
665*83ee113eSDavid van Moolenbroek 				   p -> message -> id_object,
666*83ee113eSDavid van Moolenbroek 				   p -> name, p -> value));
667*83ee113eSDavid van Moolenbroek 		}
668*83ee113eSDavid van Moolenbroek 		if (status != ISC_R_SUCCESS) {
669*83ee113eSDavid van Moolenbroek 			omapi_disconnect (c, 1);
670*83ee113eSDavid van Moolenbroek 			return status;
671*83ee113eSDavid van Moolenbroek 		}
672*83ee113eSDavid van Moolenbroek 		omapi_data_string_dereference (&p -> name, MDL);
673*83ee113eSDavid van Moolenbroek 		if (p -> value)
674*83ee113eSDavid van Moolenbroek 			omapi_typed_data_dereference (&p -> value, MDL);
675*83ee113eSDavid van Moolenbroek 		goto need_name_length;
676*83ee113eSDavid van Moolenbroek 
677*83ee113eSDavid van Moolenbroek 	      signature_wait:
678*83ee113eSDavid van Moolenbroek 	      case omapi_protocol_signature_wait:
679*83ee113eSDavid van Moolenbroek 		if (p -> message -> id_object) {
680*83ee113eSDavid van Moolenbroek 			/* Compute the signature of the message. */
681*83ee113eSDavid van Moolenbroek 			status = omapi_get_value_str (c, (omapi_object_t *)0,
682*83ee113eSDavid van Moolenbroek 						      "input-signature",
683*83ee113eSDavid van Moolenbroek 						      &signature);
684*83ee113eSDavid van Moolenbroek 			if (status != ISC_R_SUCCESS) {
685*83ee113eSDavid van Moolenbroek 				omapi_disconnect (c, 1);
686*83ee113eSDavid van Moolenbroek 				return status;
687*83ee113eSDavid van Moolenbroek 			}
688*83ee113eSDavid van Moolenbroek 
689*83ee113eSDavid van Moolenbroek 			/* Disable the authentication key on the connection. */
690*83ee113eSDavid van Moolenbroek 			status = omapi_set_value_str (c, (omapi_object_t *)0,
691*83ee113eSDavid van Moolenbroek 						      "input-authenticator",
692*83ee113eSDavid van Moolenbroek 						      (omapi_typed_data_t *)0);
693*83ee113eSDavid van Moolenbroek 			if (status != ISC_R_SUCCESS) {
694*83ee113eSDavid van Moolenbroek 				omapi_value_dereference (&signature, MDL);
695*83ee113eSDavid van Moolenbroek 				omapi_disconnect (c, 1);
696*83ee113eSDavid van Moolenbroek 				return status;
697*83ee113eSDavid van Moolenbroek 			}
698*83ee113eSDavid van Moolenbroek 		}
699*83ee113eSDavid van Moolenbroek 
700*83ee113eSDavid van Moolenbroek 		/* Read the authenticator. */
701*83ee113eSDavid van Moolenbroek 		status = omapi_typed_data_new (MDL,
702*83ee113eSDavid van Moolenbroek 					       &p -> message -> authenticator,
703*83ee113eSDavid van Moolenbroek 					       omapi_datatype_data,
704*83ee113eSDavid van Moolenbroek 					       p -> message -> authlen);
705*83ee113eSDavid van Moolenbroek 
706*83ee113eSDavid van Moolenbroek 		if (status != ISC_R_SUCCESS) {
707*83ee113eSDavid van Moolenbroek 			if (signature != NULL) {
708*83ee113eSDavid van Moolenbroek 				omapi_value_dereference (&signature, MDL);
709*83ee113eSDavid van Moolenbroek 			}
710*83ee113eSDavid van Moolenbroek 			omapi_disconnect (c, 1);
711*83ee113eSDavid van Moolenbroek 			return ISC_R_NOMEMORY;
712*83ee113eSDavid van Moolenbroek 		}
713*83ee113eSDavid van Moolenbroek 		omapi_connection_copyout
714*83ee113eSDavid van Moolenbroek 			(p -> message -> authenticator -> u.buffer.value, c,
715*83ee113eSDavid van Moolenbroek 			 p -> message -> authlen);
716*83ee113eSDavid van Moolenbroek 
717*83ee113eSDavid van Moolenbroek 		/* Verify the signature. */
718*83ee113eSDavid van Moolenbroek 		if (p -> message -> id_object &&
719*83ee113eSDavid van Moolenbroek 		    ((signature -> value -> u.buffer.len !=
720*83ee113eSDavid van Moolenbroek 		      p -> message -> authlen) ||
721*83ee113eSDavid van Moolenbroek 		     (memcmp (signature -> value -> u.buffer.value,
722*83ee113eSDavid van Moolenbroek 			      p -> message -> authenticator -> u.buffer.value,
723*83ee113eSDavid van Moolenbroek 			      p -> message -> authlen) != 0))) {
724*83ee113eSDavid van Moolenbroek 			/* Invalid signature. */
725*83ee113eSDavid van Moolenbroek 			p->verify_result = DHCP_R_INVALIDKEY;
726*83ee113eSDavid van Moolenbroek 		}
727*83ee113eSDavid van Moolenbroek 
728*83ee113eSDavid van Moolenbroek 		if (signature != NULL) {
729*83ee113eSDavid van Moolenbroek 			omapi_value_dereference (&signature, MDL);
730*83ee113eSDavid van Moolenbroek 		}
731*83ee113eSDavid van Moolenbroek 
732*83ee113eSDavid van Moolenbroek 		/* Process the message. */
733*83ee113eSDavid van Moolenbroek 	      message_done:
734*83ee113eSDavid van Moolenbroek 		if (p -> verify_result != ISC_R_SUCCESS) {
735*83ee113eSDavid van Moolenbroek 			status = omapi_protocol_send_status
736*83ee113eSDavid van Moolenbroek 				(h, (omapi_object_t *)0, p -> verify_result,
737*83ee113eSDavid van Moolenbroek 				 p -> message -> id, (char *)0);
738*83ee113eSDavid van Moolenbroek 		} else {
739*83ee113eSDavid van Moolenbroek 			status = omapi_message_process
740*83ee113eSDavid van Moolenbroek 				((omapi_object_t *)p -> message, h);
741*83ee113eSDavid van Moolenbroek 		}
742*83ee113eSDavid van Moolenbroek 		if (status != ISC_R_SUCCESS) {
743*83ee113eSDavid van Moolenbroek 			omapi_disconnect (c, 1);
744*83ee113eSDavid van Moolenbroek 			return ISC_R_NOMEMORY;
745*83ee113eSDavid van Moolenbroek 		}
746*83ee113eSDavid van Moolenbroek 
747*83ee113eSDavid van Moolenbroek 		omapi_message_dereference (&p -> message, MDL);
748*83ee113eSDavid van Moolenbroek #if defined (DEBUG_MEMORY_LEAKAGE)
749*83ee113eSDavid van Moolenbroek 		log_info ("generation %ld: %ld new, %ld outstanding, %ld%s",
750*83ee113eSDavid van Moolenbroek 			  dmalloc_generation,
751*83ee113eSDavid van Moolenbroek 			  dmalloc_outstanding - previous_outstanding,
752*83ee113eSDavid van Moolenbroek 			  dmalloc_outstanding, dmalloc_longterm, " long-term");
753*83ee113eSDavid van Moolenbroek #endif
754*83ee113eSDavid van Moolenbroek #if (defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL))
755*83ee113eSDavid van Moolenbroek 		dmalloc_dump_outstanding ();
756*83ee113eSDavid van Moolenbroek #endif
757*83ee113eSDavid van Moolenbroek #if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY)
758*83ee113eSDavid van Moolenbroek 		dump_rc_history (h);
759*83ee113eSDavid van Moolenbroek #endif
760*83ee113eSDavid van Moolenbroek #if defined (DEBUG_MEMORY_LEAKAGE)
761*83ee113eSDavid van Moolenbroek 		previous_outstanding = 0xDEADBEEF;
762*83ee113eSDavid van Moolenbroek #endif
763*83ee113eSDavid van Moolenbroek 		/* Now wait for the next message. */
764*83ee113eSDavid van Moolenbroek 		goto to_header_wait;
765*83ee113eSDavid van Moolenbroek 
766*83ee113eSDavid van Moolenbroek 	      default:
767*83ee113eSDavid van Moolenbroek 		/* XXX should never get here.   Assertion? */
768*83ee113eSDavid van Moolenbroek 		break;
769*83ee113eSDavid van Moolenbroek 	}
770*83ee113eSDavid van Moolenbroek 	return ISC_R_SUCCESS;
771*83ee113eSDavid van Moolenbroek }
772*83ee113eSDavid van Moolenbroek 
omapi_protocol_add_auth(omapi_object_t * po,omapi_object_t * ao,omapi_handle_t handle)773*83ee113eSDavid van Moolenbroek isc_result_t omapi_protocol_add_auth (omapi_object_t *po,
774*83ee113eSDavid van Moolenbroek 				      omapi_object_t *ao,
775*83ee113eSDavid van Moolenbroek 				      omapi_handle_t handle)
776*83ee113eSDavid van Moolenbroek {
777*83ee113eSDavid van Moolenbroek 	omapi_protocol_object_t *p;
778*83ee113eSDavid van Moolenbroek 	omapi_remote_auth_t *r;
779*83ee113eSDavid van Moolenbroek 	isc_result_t status;
780*83ee113eSDavid van Moolenbroek 
781*83ee113eSDavid van Moolenbroek 	if (ao -> type != omapi_type_auth_key &&
782*83ee113eSDavid van Moolenbroek 	    (!ao -> inner || ao -> inner -> type != omapi_type_auth_key))
783*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
784*83ee113eSDavid van Moolenbroek 
785*83ee113eSDavid van Moolenbroek 	if (po -> type != omapi_type_protocol)
786*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
787*83ee113eSDavid van Moolenbroek 	p = (omapi_protocol_object_t *)po;
788*83ee113eSDavid van Moolenbroek 
789*83ee113eSDavid van Moolenbroek #ifdef DEBUG_PROTOCOL
790*83ee113eSDavid van Moolenbroek 	log_debug ("omapi_protocol_add_auth(name=%s)",
791*83ee113eSDavid van Moolenbroek 		   ((omapi_auth_key_t *)ao) -> name);
792*83ee113eSDavid van Moolenbroek #endif
793*83ee113eSDavid van Moolenbroek 
794*83ee113eSDavid van Moolenbroek 	if (p -> verify_auth) {
795*83ee113eSDavid van Moolenbroek 		status = (p -> verify_auth) (po, (omapi_auth_key_t *)ao);
796*83ee113eSDavid van Moolenbroek 		if (status != ISC_R_SUCCESS)
797*83ee113eSDavid van Moolenbroek 			return status;
798*83ee113eSDavid van Moolenbroek 	}
799*83ee113eSDavid van Moolenbroek 
800*83ee113eSDavid van Moolenbroek 	/* If omapi_protocol_connect() was called with a default
801*83ee113eSDavid van Moolenbroek 	   authenticator, p -> default_auth will already be set,
802*83ee113eSDavid van Moolenbroek 	   but p -> remote_auth_list will not yet be initialized. */
803*83ee113eSDavid van Moolenbroek 	if (p -> default_auth && !p -> remote_auth_list) {
804*83ee113eSDavid van Moolenbroek 		if (p -> default_auth -> a != ao) {
805*83ee113eSDavid van Moolenbroek 			/* Something just went horribly wrong. */
806*83ee113eSDavid van Moolenbroek 			omapi_disconnect (p -> outer, 1);
807*83ee113eSDavid van Moolenbroek 			return ISC_R_UNEXPECTED;
808*83ee113eSDavid van Moolenbroek 		}
809*83ee113eSDavid van Moolenbroek 
810*83ee113eSDavid van Moolenbroek 		p -> remote_auth_list = p -> default_auth;
811*83ee113eSDavid van Moolenbroek 		p -> default_auth -> remote_handle = handle;
812*83ee113eSDavid van Moolenbroek 
813*83ee113eSDavid van Moolenbroek 		return omapi_signal_in (p -> inner, "ready");
814*83ee113eSDavid van Moolenbroek 	}
815*83ee113eSDavid van Moolenbroek 
816*83ee113eSDavid van Moolenbroek 	r = dmalloc (sizeof(*r), MDL);
817*83ee113eSDavid van Moolenbroek 	if (!r)
818*83ee113eSDavid van Moolenbroek 		return ISC_R_NOMEMORY;
819*83ee113eSDavid van Moolenbroek 
820*83ee113eSDavid van Moolenbroek 	status = omapi_object_reference (&r -> a, ao, MDL);
821*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
822*83ee113eSDavid van Moolenbroek 		dfree (r, MDL);
823*83ee113eSDavid van Moolenbroek 		return status;
824*83ee113eSDavid van Moolenbroek 	}
825*83ee113eSDavid van Moolenbroek 
826*83ee113eSDavid van Moolenbroek 	r -> remote_handle = handle;
827*83ee113eSDavid van Moolenbroek 	r -> next = p -> remote_auth_list;
828*83ee113eSDavid van Moolenbroek 	p -> remote_auth_list = r;
829*83ee113eSDavid van Moolenbroek 
830*83ee113eSDavid van Moolenbroek 	return ISC_R_SUCCESS;
831*83ee113eSDavid van Moolenbroek }
832*83ee113eSDavid van Moolenbroek 
omapi_protocol_lookup_auth(omapi_object_t ** a,omapi_object_t * po,omapi_handle_t handle)833*83ee113eSDavid van Moolenbroek isc_result_t omapi_protocol_lookup_auth (omapi_object_t **a,
834*83ee113eSDavid van Moolenbroek 					 omapi_object_t *po,
835*83ee113eSDavid van Moolenbroek 					 omapi_handle_t handle)
836*83ee113eSDavid van Moolenbroek {
837*83ee113eSDavid van Moolenbroek 	omapi_protocol_object_t *p;
838*83ee113eSDavid van Moolenbroek 	omapi_remote_auth_t *r;
839*83ee113eSDavid van Moolenbroek 
840*83ee113eSDavid van Moolenbroek 	if (po -> type != omapi_type_protocol)
841*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
842*83ee113eSDavid van Moolenbroek 	p = (omapi_protocol_object_t *)po;
843*83ee113eSDavid van Moolenbroek 
844*83ee113eSDavid van Moolenbroek 	for (r = p -> remote_auth_list; r; r = r -> next)
845*83ee113eSDavid van Moolenbroek 		if (r -> remote_handle == handle)
846*83ee113eSDavid van Moolenbroek 			return omapi_object_reference (a, r -> a, MDL);
847*83ee113eSDavid van Moolenbroek 
848*83ee113eSDavid van Moolenbroek 	return DHCP_R_KEY_UNKNOWN;
849*83ee113eSDavid van Moolenbroek }
850*83ee113eSDavid van Moolenbroek 
omapi_protocol_set_value(omapi_object_t * h,omapi_object_t * id,omapi_data_string_t * name,omapi_typed_data_t * value)851*83ee113eSDavid van Moolenbroek isc_result_t omapi_protocol_set_value (omapi_object_t *h,
852*83ee113eSDavid van Moolenbroek 				       omapi_object_t *id,
853*83ee113eSDavid van Moolenbroek 				       omapi_data_string_t *name,
854*83ee113eSDavid van Moolenbroek 				       omapi_typed_data_t *value)
855*83ee113eSDavid van Moolenbroek {
856*83ee113eSDavid van Moolenbroek 	omapi_protocol_object_t *p;
857*83ee113eSDavid van Moolenbroek 	omapi_remote_auth_t *r;
858*83ee113eSDavid van Moolenbroek 
859*83ee113eSDavid van Moolenbroek 	if (h -> type != omapi_type_protocol)
860*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
861*83ee113eSDavid van Moolenbroek 	p = (omapi_protocol_object_t *)h;
862*83ee113eSDavid van Moolenbroek 
863*83ee113eSDavid van Moolenbroek 	if (omapi_ds_strcmp (name, "default-authenticator") == 0) {
864*83ee113eSDavid van Moolenbroek 		if (!value || value -> type != omapi_datatype_object)
865*83ee113eSDavid van Moolenbroek 			return DHCP_R_INVALIDARG;
866*83ee113eSDavid van Moolenbroek 
867*83ee113eSDavid van Moolenbroek 		if (!value -> u.object) {
868*83ee113eSDavid van Moolenbroek 			p -> default_auth = (omapi_remote_auth_t *)0;
869*83ee113eSDavid van Moolenbroek 		} else {
870*83ee113eSDavid van Moolenbroek 			for (r = p -> remote_auth_list; r; r = r -> next)
871*83ee113eSDavid van Moolenbroek 				if (r -> a == value -> u.object)
872*83ee113eSDavid van Moolenbroek 					break;
873*83ee113eSDavid van Moolenbroek 
874*83ee113eSDavid van Moolenbroek 			if (!r)
875*83ee113eSDavid van Moolenbroek 				return DHCP_R_KEY_UNKNOWN;
876*83ee113eSDavid van Moolenbroek 
877*83ee113eSDavid van Moolenbroek 			p -> default_auth = r;
878*83ee113eSDavid van Moolenbroek 		}
879*83ee113eSDavid van Moolenbroek 
880*83ee113eSDavid van Moolenbroek 		return ISC_R_SUCCESS;
881*83ee113eSDavid van Moolenbroek 	}
882*83ee113eSDavid van Moolenbroek 
883*83ee113eSDavid van Moolenbroek 	if (h -> inner && h -> inner -> type -> set_value)
884*83ee113eSDavid van Moolenbroek 		return (*(h -> inner -> type -> set_value))
885*83ee113eSDavid van Moolenbroek 			(h -> inner, id, name, value);
886*83ee113eSDavid van Moolenbroek 	return ISC_R_NOTFOUND;
887*83ee113eSDavid van Moolenbroek }
888*83ee113eSDavid van Moolenbroek 
omapi_protocol_get_value(omapi_object_t * h,omapi_object_t * id,omapi_data_string_t * name,omapi_value_t ** value)889*83ee113eSDavid van Moolenbroek isc_result_t omapi_protocol_get_value (omapi_object_t *h,
890*83ee113eSDavid van Moolenbroek 				       omapi_object_t *id,
891*83ee113eSDavid van Moolenbroek 				       omapi_data_string_t *name,
892*83ee113eSDavid van Moolenbroek 				       omapi_value_t **value)
893*83ee113eSDavid van Moolenbroek {
894*83ee113eSDavid van Moolenbroek 	omapi_protocol_object_t *p;
895*83ee113eSDavid van Moolenbroek 
896*83ee113eSDavid van Moolenbroek 	if (h -> type != omapi_type_protocol)
897*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
898*83ee113eSDavid van Moolenbroek 	p = (omapi_protocol_object_t *)h;
899*83ee113eSDavid van Moolenbroek 
900*83ee113eSDavid van Moolenbroek 	if (omapi_ds_strcmp (name, "default-authenticator") == 0) {
901*83ee113eSDavid van Moolenbroek 		if (!p -> default_auth)
902*83ee113eSDavid van Moolenbroek 			return ISC_R_NOTFOUND;
903*83ee113eSDavid van Moolenbroek 
904*83ee113eSDavid van Moolenbroek 		return omapi_make_object_value (value, name,
905*83ee113eSDavid van Moolenbroek 						p -> default_auth -> a, MDL);
906*83ee113eSDavid van Moolenbroek 	}
907*83ee113eSDavid van Moolenbroek 
908*83ee113eSDavid van Moolenbroek 	if (h -> inner && h -> inner -> type -> get_value)
909*83ee113eSDavid van Moolenbroek 		return (*(h -> inner -> type -> get_value))
910*83ee113eSDavid van Moolenbroek 			(h -> inner, id, name, value);
911*83ee113eSDavid van Moolenbroek 	return ISC_R_NOTFOUND;
912*83ee113eSDavid van Moolenbroek }
913*83ee113eSDavid van Moolenbroek 
omapi_protocol_destroy(omapi_object_t * h,const char * file,int line)914*83ee113eSDavid van Moolenbroek isc_result_t omapi_protocol_destroy (omapi_object_t *h,
915*83ee113eSDavid van Moolenbroek 				     const char *file, int line)
916*83ee113eSDavid van Moolenbroek {
917*83ee113eSDavid van Moolenbroek 	omapi_protocol_object_t *p;
918*83ee113eSDavid van Moolenbroek 	if (h -> type != omapi_type_protocol)
919*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
920*83ee113eSDavid van Moolenbroek 	p = (omapi_protocol_object_t *)h;
921*83ee113eSDavid van Moolenbroek 	if (p -> message)
922*83ee113eSDavid van Moolenbroek 		omapi_message_dereference (&p -> message, file, line);
923*83ee113eSDavid van Moolenbroek 
924*83ee113eSDavid van Moolenbroek 	/* This will happen if: 1) A default authenticator is supplied to
925*83ee113eSDavid van Moolenbroek 	   omapi_protocol_connect(), and 2) something goes wrong before
926*83ee113eSDavid van Moolenbroek 	   the authenticator can be opened. */
927*83ee113eSDavid van Moolenbroek 	if (p -> default_auth && !p -> remote_auth_list)
928*83ee113eSDavid van Moolenbroek 		dfree (p -> default_auth, file, line);
929*83ee113eSDavid van Moolenbroek 
930*83ee113eSDavid van Moolenbroek 	while (p -> remote_auth_list) {
931*83ee113eSDavid van Moolenbroek 		omapi_remote_auth_t *r = p -> remote_auth_list;
932*83ee113eSDavid van Moolenbroek 		p -> remote_auth_list =  p -> remote_auth_list -> next;
933*83ee113eSDavid van Moolenbroek 		omapi_object_dereference (&r -> a, file, line);
934*83ee113eSDavid van Moolenbroek 		dfree (r, file, line);
935*83ee113eSDavid van Moolenbroek 	}
936*83ee113eSDavid van Moolenbroek 	return ISC_R_SUCCESS;
937*83ee113eSDavid van Moolenbroek }
938*83ee113eSDavid van Moolenbroek 
939*83ee113eSDavid van Moolenbroek /* Write all the published values associated with the object through the
940*83ee113eSDavid van Moolenbroek    specified connection. */
941*83ee113eSDavid van Moolenbroek 
omapi_protocol_stuff_values(omapi_object_t * c,omapi_object_t * id,omapi_object_t * p)942*83ee113eSDavid van Moolenbroek isc_result_t omapi_protocol_stuff_values (omapi_object_t *c,
943*83ee113eSDavid van Moolenbroek 					  omapi_object_t *id,
944*83ee113eSDavid van Moolenbroek 					  omapi_object_t *p)
945*83ee113eSDavid van Moolenbroek {
946*83ee113eSDavid van Moolenbroek 	if (p -> type != omapi_type_protocol)
947*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
948*83ee113eSDavid van Moolenbroek 
949*83ee113eSDavid van Moolenbroek 	if (p -> inner && p -> inner -> type -> stuff_values)
950*83ee113eSDavid van Moolenbroek 		return (*(p -> inner -> type -> stuff_values)) (c, id,
951*83ee113eSDavid van Moolenbroek 								p -> inner);
952*83ee113eSDavid van Moolenbroek 	return ISC_R_SUCCESS;
953*83ee113eSDavid van Moolenbroek }
954*83ee113eSDavid van Moolenbroek 
955*83ee113eSDavid van Moolenbroek /* Returns a boolean indicating whether this protocol requires that
956*83ee113eSDavid van Moolenbroek    messages be authenticated or not. */
957*83ee113eSDavid van Moolenbroek 
omapi_protocol_authenticated(omapi_object_t * h)958*83ee113eSDavid van Moolenbroek isc_boolean_t omapi_protocol_authenticated (omapi_object_t *h)
959*83ee113eSDavid van Moolenbroek {
960*83ee113eSDavid van Moolenbroek 	if (h -> type != omapi_type_protocol)
961*83ee113eSDavid van Moolenbroek 		return isc_boolean_false;
962*83ee113eSDavid van Moolenbroek 	if (((omapi_protocol_object_t *)h) -> insecure)
963*83ee113eSDavid van Moolenbroek 		return isc_boolean_false;
964*83ee113eSDavid van Moolenbroek 	else
965*83ee113eSDavid van Moolenbroek 		return isc_boolean_true;
966*83ee113eSDavid van Moolenbroek }
967*83ee113eSDavid van Moolenbroek 
968*83ee113eSDavid van Moolenbroek /* Sets the address and authenticator verification callbacks.  The handle
969*83ee113eSDavid van Moolenbroek    is to a listener object, not a protocol object. */
970*83ee113eSDavid van Moolenbroek 
omapi_protocol_configure_security(omapi_object_t * h,isc_result_t (* verify_addr)(omapi_object_t *,omapi_addr_t *),isc_result_t (* verify_auth)(omapi_object_t *,omapi_auth_key_t *))971*83ee113eSDavid van Moolenbroek isc_result_t omapi_protocol_configure_security (omapi_object_t *h,
972*83ee113eSDavid van Moolenbroek 						isc_result_t (*verify_addr)
973*83ee113eSDavid van Moolenbroek 						 (omapi_object_t *,
974*83ee113eSDavid van Moolenbroek 						  omapi_addr_t *),
975*83ee113eSDavid van Moolenbroek 						isc_result_t (*verify_auth)
976*83ee113eSDavid van Moolenbroek 						 (omapi_object_t *,
977*83ee113eSDavid van Moolenbroek 						  omapi_auth_key_t *))
978*83ee113eSDavid van Moolenbroek {
979*83ee113eSDavid van Moolenbroek 	omapi_protocol_listener_object_t *l;
980*83ee113eSDavid van Moolenbroek 
981*83ee113eSDavid van Moolenbroek 	if (h -> outer && h -> outer -> type == omapi_type_protocol_listener)
982*83ee113eSDavid van Moolenbroek 		h = h -> outer;
983*83ee113eSDavid van Moolenbroek 
984*83ee113eSDavid van Moolenbroek 	if (h -> type != omapi_type_protocol_listener)
985*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
986*83ee113eSDavid van Moolenbroek 	l = (omapi_protocol_listener_object_t *)h;
987*83ee113eSDavid van Moolenbroek 
988*83ee113eSDavid van Moolenbroek 	l -> verify_auth = verify_auth;
989*83ee113eSDavid van Moolenbroek 	l -> insecure = 0;
990*83ee113eSDavid van Moolenbroek 
991*83ee113eSDavid van Moolenbroek 	if (h -> outer != NULL) {
992*83ee113eSDavid van Moolenbroek 		return omapi_listener_configure_security (h -> outer, verify_addr);
993*83ee113eSDavid van Moolenbroek 	} else {
994*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
995*83ee113eSDavid van Moolenbroek 	}
996*83ee113eSDavid van Moolenbroek }
997*83ee113eSDavid van Moolenbroek 
998*83ee113eSDavid van Moolenbroek 
999*83ee113eSDavid van Moolenbroek /* Set up a listener for the omapi protocol.    The handle stored points to
1000*83ee113eSDavid van Moolenbroek    a listener object, not a protocol object. */
1001*83ee113eSDavid van Moolenbroek 
omapi_protocol_listen(omapi_object_t * h,unsigned port,int max)1002*83ee113eSDavid van Moolenbroek isc_result_t omapi_protocol_listen (omapi_object_t *h,
1003*83ee113eSDavid van Moolenbroek 				    unsigned port,
1004*83ee113eSDavid van Moolenbroek 				    int max)
1005*83ee113eSDavid van Moolenbroek {
1006*83ee113eSDavid van Moolenbroek 	isc_result_t status;
1007*83ee113eSDavid van Moolenbroek 	omapi_protocol_listener_object_t *obj;
1008*83ee113eSDavid van Moolenbroek 
1009*83ee113eSDavid van Moolenbroek 	obj = (omapi_protocol_listener_object_t *)0;
1010*83ee113eSDavid van Moolenbroek 	status = omapi_protocol_listener_allocate (&obj, MDL);
1011*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS)
1012*83ee113eSDavid van Moolenbroek 		return status;
1013*83ee113eSDavid van Moolenbroek 
1014*83ee113eSDavid van Moolenbroek 	status = omapi_object_reference (&h -> outer,
1015*83ee113eSDavid van Moolenbroek 					 (omapi_object_t *)obj, MDL);
1016*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
1017*83ee113eSDavid van Moolenbroek 		omapi_protocol_listener_dereference (&obj, MDL);
1018*83ee113eSDavid van Moolenbroek 		return status;
1019*83ee113eSDavid van Moolenbroek 	}
1020*83ee113eSDavid van Moolenbroek 	status = omapi_object_reference (&obj -> inner, h, MDL);
1021*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
1022*83ee113eSDavid van Moolenbroek 		omapi_protocol_listener_dereference (&obj, MDL);
1023*83ee113eSDavid van Moolenbroek 		return status;
1024*83ee113eSDavid van Moolenbroek 	}
1025*83ee113eSDavid van Moolenbroek 
1026*83ee113eSDavid van Moolenbroek 	/* What a terrible default. */
1027*83ee113eSDavid van Moolenbroek 	obj -> insecure = 1;
1028*83ee113eSDavid van Moolenbroek 
1029*83ee113eSDavid van Moolenbroek 	status = omapi_listen ((omapi_object_t *)obj, port, max);
1030*83ee113eSDavid van Moolenbroek 	omapi_protocol_listener_dereference (&obj, MDL);
1031*83ee113eSDavid van Moolenbroek 	return status;
1032*83ee113eSDavid van Moolenbroek }
1033*83ee113eSDavid van Moolenbroek 
1034*83ee113eSDavid van Moolenbroek /* Signal handler for protocol listener - if we get a connect signal,
1035*83ee113eSDavid van Moolenbroek    create a new protocol connection, otherwise pass the signal down. */
1036*83ee113eSDavid van Moolenbroek 
omapi_protocol_listener_signal(omapi_object_t * o,const char * name,va_list ap)1037*83ee113eSDavid van Moolenbroek isc_result_t omapi_protocol_listener_signal (omapi_object_t *o,
1038*83ee113eSDavid van Moolenbroek 					     const char *name, va_list ap)
1039*83ee113eSDavid van Moolenbroek {
1040*83ee113eSDavid van Moolenbroek 	isc_result_t status;
1041*83ee113eSDavid van Moolenbroek 	omapi_object_t *c;
1042*83ee113eSDavid van Moolenbroek 	omapi_protocol_object_t *obj;
1043*83ee113eSDavid van Moolenbroek 	omapi_protocol_listener_object_t *p;
1044*83ee113eSDavid van Moolenbroek 
1045*83ee113eSDavid van Moolenbroek 	if (!o || o -> type != omapi_type_protocol_listener)
1046*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
1047*83ee113eSDavid van Moolenbroek 	p = (omapi_protocol_listener_object_t *)o;
1048*83ee113eSDavid van Moolenbroek 
1049*83ee113eSDavid van Moolenbroek 	/* Not a signal we recognize? */
1050*83ee113eSDavid van Moolenbroek 	if (strcmp (name, "connect")) {
1051*83ee113eSDavid van Moolenbroek 		if (p -> inner && p -> inner -> type -> signal_handler)
1052*83ee113eSDavid van Moolenbroek 			return (*(p -> inner -> type -> signal_handler))
1053*83ee113eSDavid van Moolenbroek 				(p -> inner, name, ap);
1054*83ee113eSDavid van Moolenbroek 		return ISC_R_NOTFOUND;
1055*83ee113eSDavid van Moolenbroek 	}
1056*83ee113eSDavid van Moolenbroek 
1057*83ee113eSDavid van Moolenbroek 	c = va_arg (ap, omapi_object_t *);
1058*83ee113eSDavid van Moolenbroek 	if (!c || c -> type != omapi_type_connection)
1059*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
1060*83ee113eSDavid van Moolenbroek 
1061*83ee113eSDavid van Moolenbroek 	obj = (omapi_protocol_object_t *)0;
1062*83ee113eSDavid van Moolenbroek 	status = omapi_protocol_allocate (&obj, MDL);
1063*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS)
1064*83ee113eSDavid van Moolenbroek 		return status;
1065*83ee113eSDavid van Moolenbroek 
1066*83ee113eSDavid van Moolenbroek 	obj -> verify_auth = p -> verify_auth;
1067*83ee113eSDavid van Moolenbroek 	obj -> insecure = p -> insecure;
1068*83ee113eSDavid van Moolenbroek 
1069*83ee113eSDavid van Moolenbroek 	status = omapi_object_reference (&obj -> outer, c, MDL);
1070*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
1071*83ee113eSDavid van Moolenbroek 	      lose:
1072*83ee113eSDavid van Moolenbroek 		omapi_protocol_dereference (&obj, MDL);
1073*83ee113eSDavid van Moolenbroek 		omapi_disconnect (c, 1);
1074*83ee113eSDavid van Moolenbroek 		return status;
1075*83ee113eSDavid van Moolenbroek 	}
1076*83ee113eSDavid van Moolenbroek 
1077*83ee113eSDavid van Moolenbroek 	status = omapi_object_reference (&c -> inner,
1078*83ee113eSDavid van Moolenbroek 					 (omapi_object_t *)obj, MDL);
1079*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS)
1080*83ee113eSDavid van Moolenbroek 		goto lose;
1081*83ee113eSDavid van Moolenbroek 
1082*83ee113eSDavid van Moolenbroek 	/* Send the introductory message. */
1083*83ee113eSDavid van Moolenbroek 	status = omapi_protocol_send_intro ((omapi_object_t *)obj,
1084*83ee113eSDavid van Moolenbroek 					    OMAPI_PROTOCOL_VERSION,
1085*83ee113eSDavid van Moolenbroek 					    sizeof (omapi_protocol_header_t));
1086*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS)
1087*83ee113eSDavid van Moolenbroek 		goto lose;
1088*83ee113eSDavid van Moolenbroek 
1089*83ee113eSDavid van Moolenbroek 	omapi_protocol_dereference (&obj, MDL);
1090*83ee113eSDavid van Moolenbroek 	return status;
1091*83ee113eSDavid van Moolenbroek }
1092*83ee113eSDavid van Moolenbroek 
omapi_protocol_listener_set_value(omapi_object_t * h,omapi_object_t * id,omapi_data_string_t * name,omapi_typed_data_t * value)1093*83ee113eSDavid van Moolenbroek isc_result_t omapi_protocol_listener_set_value (omapi_object_t *h,
1094*83ee113eSDavid van Moolenbroek 						omapi_object_t *id,
1095*83ee113eSDavid van Moolenbroek 						omapi_data_string_t *name,
1096*83ee113eSDavid van Moolenbroek 						omapi_typed_data_t *value)
1097*83ee113eSDavid van Moolenbroek {
1098*83ee113eSDavid van Moolenbroek 	if (h -> type != omapi_type_protocol_listener)
1099*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
1100*83ee113eSDavid van Moolenbroek 
1101*83ee113eSDavid van Moolenbroek 	if (h -> inner && h -> inner -> type -> set_value)
1102*83ee113eSDavid van Moolenbroek 		return (*(h -> inner -> type -> set_value))
1103*83ee113eSDavid van Moolenbroek 			(h -> inner, id, name, value);
1104*83ee113eSDavid van Moolenbroek 	return ISC_R_NOTFOUND;
1105*83ee113eSDavid van Moolenbroek }
1106*83ee113eSDavid van Moolenbroek 
omapi_protocol_listener_get_value(omapi_object_t * h,omapi_object_t * id,omapi_data_string_t * name,omapi_value_t ** value)1107*83ee113eSDavid van Moolenbroek isc_result_t omapi_protocol_listener_get_value (omapi_object_t *h,
1108*83ee113eSDavid van Moolenbroek 						omapi_object_t *id,
1109*83ee113eSDavid van Moolenbroek 						omapi_data_string_t *name,
1110*83ee113eSDavid van Moolenbroek 						omapi_value_t **value)
1111*83ee113eSDavid van Moolenbroek {
1112*83ee113eSDavid van Moolenbroek 	if (h -> type != omapi_type_protocol_listener)
1113*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
1114*83ee113eSDavid van Moolenbroek 
1115*83ee113eSDavid van Moolenbroek 	if (h -> inner && h -> inner -> type -> get_value)
1116*83ee113eSDavid van Moolenbroek 		return (*(h -> inner -> type -> get_value))
1117*83ee113eSDavid van Moolenbroek 			(h -> inner, id, name, value);
1118*83ee113eSDavid van Moolenbroek 	return ISC_R_NOTFOUND;
1119*83ee113eSDavid van Moolenbroek }
1120*83ee113eSDavid van Moolenbroek 
omapi_protocol_listener_destroy(omapi_object_t * h,const char * file,int line)1121*83ee113eSDavid van Moolenbroek isc_result_t omapi_protocol_listener_destroy (omapi_object_t *h,
1122*83ee113eSDavid van Moolenbroek 					      const char *file, int line)
1123*83ee113eSDavid van Moolenbroek {
1124*83ee113eSDavid van Moolenbroek 	if (h -> type != omapi_type_protocol_listener)
1125*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
1126*83ee113eSDavid van Moolenbroek 	return ISC_R_SUCCESS;
1127*83ee113eSDavid van Moolenbroek }
1128*83ee113eSDavid van Moolenbroek 
1129*83ee113eSDavid van Moolenbroek /* Write all the published values associated with the object through the
1130*83ee113eSDavid van Moolenbroek    specified connection. */
1131*83ee113eSDavid van Moolenbroek 
omapi_protocol_listener_stuff(omapi_object_t * c,omapi_object_t * id,omapi_object_t * p)1132*83ee113eSDavid van Moolenbroek isc_result_t omapi_protocol_listener_stuff (omapi_object_t *c,
1133*83ee113eSDavid van Moolenbroek 					    omapi_object_t *id,
1134*83ee113eSDavid van Moolenbroek 					    omapi_object_t *p)
1135*83ee113eSDavid van Moolenbroek {
1136*83ee113eSDavid van Moolenbroek 	if (p -> type != omapi_type_protocol_listener)
1137*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
1138*83ee113eSDavid van Moolenbroek 
1139*83ee113eSDavid van Moolenbroek 	if (p -> inner && p -> inner -> type -> stuff_values)
1140*83ee113eSDavid van Moolenbroek 		return (*(p -> inner -> type -> stuff_values)) (c, id,
1141*83ee113eSDavid van Moolenbroek 								p -> inner);
1142*83ee113eSDavid van Moolenbroek 	return ISC_R_SUCCESS;
1143*83ee113eSDavid van Moolenbroek }
1144*83ee113eSDavid van Moolenbroek 
omapi_protocol_send_status(omapi_object_t * po,omapi_object_t * id,isc_result_t waitstatus,unsigned rid,const char * msg)1145*83ee113eSDavid van Moolenbroek isc_result_t omapi_protocol_send_status (omapi_object_t *po,
1146*83ee113eSDavid van Moolenbroek 					 omapi_object_t *id,
1147*83ee113eSDavid van Moolenbroek 					 isc_result_t waitstatus,
1148*83ee113eSDavid van Moolenbroek 					 unsigned rid, const char *msg)
1149*83ee113eSDavid van Moolenbroek {
1150*83ee113eSDavid van Moolenbroek 	isc_result_t status;
1151*83ee113eSDavid van Moolenbroek 	omapi_message_object_t *message = (omapi_message_object_t *)0;
1152*83ee113eSDavid van Moolenbroek 	omapi_object_t *mo;
1153*83ee113eSDavid van Moolenbroek 
1154*83ee113eSDavid van Moolenbroek 	if (po -> type != omapi_type_protocol)
1155*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
1156*83ee113eSDavid van Moolenbroek 
1157*83ee113eSDavid van Moolenbroek 	status = omapi_message_new ((omapi_object_t **)&message, MDL);
1158*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS)
1159*83ee113eSDavid van Moolenbroek 		return status;
1160*83ee113eSDavid van Moolenbroek 	mo = (omapi_object_t *)message;
1161*83ee113eSDavid van Moolenbroek 
1162*83ee113eSDavid van Moolenbroek 	status = omapi_set_int_value (mo, (omapi_object_t *)0,
1163*83ee113eSDavid van Moolenbroek 				      "op", OMAPI_OP_STATUS);
1164*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
1165*83ee113eSDavid van Moolenbroek 		omapi_message_dereference (&message, MDL);
1166*83ee113eSDavid van Moolenbroek 		return status;
1167*83ee113eSDavid van Moolenbroek 	}
1168*83ee113eSDavid van Moolenbroek 
1169*83ee113eSDavid van Moolenbroek 	status = omapi_set_int_value (mo, (omapi_object_t *)0,
1170*83ee113eSDavid van Moolenbroek 				      "rid", (int)rid);
1171*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
1172*83ee113eSDavid van Moolenbroek 		omapi_message_dereference (&message, MDL);
1173*83ee113eSDavid van Moolenbroek 		return status;
1174*83ee113eSDavid van Moolenbroek 	}
1175*83ee113eSDavid van Moolenbroek 
1176*83ee113eSDavid van Moolenbroek 	status = omapi_set_int_value (mo, (omapi_object_t *)0,
1177*83ee113eSDavid van Moolenbroek 				      "result", (int)waitstatus);
1178*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
1179*83ee113eSDavid van Moolenbroek 		omapi_message_dereference (&message, MDL);
1180*83ee113eSDavid van Moolenbroek 		return status;
1181*83ee113eSDavid van Moolenbroek 	}
1182*83ee113eSDavid van Moolenbroek 
1183*83ee113eSDavid van Moolenbroek 	/* If a message has been provided, send it. */
1184*83ee113eSDavid van Moolenbroek 	if (msg) {
1185*83ee113eSDavid van Moolenbroek 		status = omapi_set_string_value (mo, (omapi_object_t *)0,
1186*83ee113eSDavid van Moolenbroek 						 "message", msg);
1187*83ee113eSDavid van Moolenbroek 		if (status != ISC_R_SUCCESS) {
1188*83ee113eSDavid van Moolenbroek 			omapi_message_dereference (&message, MDL);
1189*83ee113eSDavid van Moolenbroek 			return status;
1190*83ee113eSDavid van Moolenbroek 		}
1191*83ee113eSDavid van Moolenbroek 	}
1192*83ee113eSDavid van Moolenbroek 
1193*83ee113eSDavid van Moolenbroek 	status = omapi_protocol_send_message (po, id, mo, (omapi_object_t *)0);
1194*83ee113eSDavid van Moolenbroek 	omapi_message_dereference (&message, MDL);
1195*83ee113eSDavid van Moolenbroek 	return status;
1196*83ee113eSDavid van Moolenbroek }
1197*83ee113eSDavid van Moolenbroek 
1198*83ee113eSDavid van Moolenbroek /* The OMAPI_NOTIFY_PROTOCOL flag will cause the notify-object for the
1199*83ee113eSDavid van Moolenbroek    message to be set to the protocol object.  This is used when opening
1200*83ee113eSDavid van Moolenbroek    the default authenticator. */
1201*83ee113eSDavid van Moolenbroek 
omapi_protocol_send_open(omapi_object_t * po,omapi_object_t * id,const char * type,omapi_object_t * object,unsigned flags)1202*83ee113eSDavid van Moolenbroek isc_result_t omapi_protocol_send_open (omapi_object_t *po,
1203*83ee113eSDavid van Moolenbroek 				       omapi_object_t *id,
1204*83ee113eSDavid van Moolenbroek 				       const char *type,
1205*83ee113eSDavid van Moolenbroek 				       omapi_object_t *object,
1206*83ee113eSDavid van Moolenbroek 				       unsigned flags)
1207*83ee113eSDavid van Moolenbroek {
1208*83ee113eSDavid van Moolenbroek 	isc_result_t status;
1209*83ee113eSDavid van Moolenbroek 	omapi_message_object_t *message = (omapi_message_object_t *)0;
1210*83ee113eSDavid van Moolenbroek 	omapi_object_t *mo;
1211*83ee113eSDavid van Moolenbroek 
1212*83ee113eSDavid van Moolenbroek 	if (po -> type != omapi_type_protocol)
1213*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
1214*83ee113eSDavid van Moolenbroek 
1215*83ee113eSDavid van Moolenbroek 	status = omapi_message_new ((omapi_object_t **)&message, MDL);
1216*83ee113eSDavid van Moolenbroek 	mo = (omapi_object_t *)message;
1217*83ee113eSDavid van Moolenbroek 
1218*83ee113eSDavid van Moolenbroek 	if (status == ISC_R_SUCCESS)
1219*83ee113eSDavid van Moolenbroek 		status = omapi_set_int_value (mo, (omapi_object_t *)0,
1220*83ee113eSDavid van Moolenbroek 					      "op", OMAPI_OP_OPEN);
1221*83ee113eSDavid van Moolenbroek 
1222*83ee113eSDavid van Moolenbroek 	if (status == ISC_R_SUCCESS)
1223*83ee113eSDavid van Moolenbroek 		status = omapi_set_object_value (mo, (omapi_object_t *)0,
1224*83ee113eSDavid van Moolenbroek 						 "object", object);
1225*83ee113eSDavid van Moolenbroek 
1226*83ee113eSDavid van Moolenbroek 	if ((flags & OMAPI_CREATE) && (status == ISC_R_SUCCESS))
1227*83ee113eSDavid van Moolenbroek 		status = omapi_set_boolean_value (mo, (omapi_object_t *)0,
1228*83ee113eSDavid van Moolenbroek 						  "create", 1);
1229*83ee113eSDavid van Moolenbroek 
1230*83ee113eSDavid van Moolenbroek 	if ((flags & OMAPI_UPDATE) && (status == ISC_R_SUCCESS))
1231*83ee113eSDavid van Moolenbroek 		status = omapi_set_boolean_value (mo, (omapi_object_t *)0,
1232*83ee113eSDavid van Moolenbroek 						  "update", 1);
1233*83ee113eSDavid van Moolenbroek 
1234*83ee113eSDavid van Moolenbroek 	if ((flags & OMAPI_EXCL) && (status == ISC_R_SUCCESS))
1235*83ee113eSDavid van Moolenbroek 		status = omapi_set_boolean_value (mo, (omapi_object_t *)0,
1236*83ee113eSDavid van Moolenbroek 						  "exclusive", 1);
1237*83ee113eSDavid van Moolenbroek 
1238*83ee113eSDavid van Moolenbroek 	if ((flags & OMAPI_NOTIFY_PROTOCOL) && (status == ISC_R_SUCCESS))
1239*83ee113eSDavid van Moolenbroek 		status = omapi_set_object_value (mo, (omapi_object_t *)0,
1240*83ee113eSDavid van Moolenbroek 						 "notify-object", po);
1241*83ee113eSDavid van Moolenbroek 
1242*83ee113eSDavid van Moolenbroek 	if (type && (status == ISC_R_SUCCESS))
1243*83ee113eSDavid van Moolenbroek 		status = omapi_set_string_value (mo, (omapi_object_t *)0,
1244*83ee113eSDavid van Moolenbroek 						 "type", type);
1245*83ee113eSDavid van Moolenbroek 
1246*83ee113eSDavid van Moolenbroek 	if (status == ISC_R_SUCCESS)
1247*83ee113eSDavid van Moolenbroek 		status = omapi_message_register (mo);
1248*83ee113eSDavid van Moolenbroek 
1249*83ee113eSDavid van Moolenbroek 	if (status == ISC_R_SUCCESS) {
1250*83ee113eSDavid van Moolenbroek 		status = omapi_protocol_send_message (po, id, mo,
1251*83ee113eSDavid van Moolenbroek 						      (omapi_object_t *)0);
1252*83ee113eSDavid van Moolenbroek 		if (status != ISC_R_SUCCESS)
1253*83ee113eSDavid van Moolenbroek 			omapi_message_unregister (mo);
1254*83ee113eSDavid van Moolenbroek 	}
1255*83ee113eSDavid van Moolenbroek 
1256*83ee113eSDavid van Moolenbroek 	if (message)
1257*83ee113eSDavid van Moolenbroek 		omapi_message_dereference (&message, MDL);
1258*83ee113eSDavid van Moolenbroek 
1259*83ee113eSDavid van Moolenbroek 	return status;
1260*83ee113eSDavid van Moolenbroek }
1261*83ee113eSDavid van Moolenbroek 
omapi_protocol_send_update(omapi_object_t * po,omapi_object_t * id,unsigned rid,omapi_object_t * object)1262*83ee113eSDavid van Moolenbroek isc_result_t omapi_protocol_send_update (omapi_object_t *po,
1263*83ee113eSDavid van Moolenbroek 					 omapi_object_t *id,
1264*83ee113eSDavid van Moolenbroek 					 unsigned rid,
1265*83ee113eSDavid van Moolenbroek 					 omapi_object_t *object)
1266*83ee113eSDavid van Moolenbroek {
1267*83ee113eSDavid van Moolenbroek 	isc_result_t status;
1268*83ee113eSDavid van Moolenbroek 	omapi_message_object_t *message = (omapi_message_object_t *)0;
1269*83ee113eSDavid van Moolenbroek 	omapi_object_t *mo;
1270*83ee113eSDavid van Moolenbroek 
1271*83ee113eSDavid van Moolenbroek 	if (po -> type != omapi_type_protocol)
1272*83ee113eSDavid van Moolenbroek 		return DHCP_R_INVALIDARG;
1273*83ee113eSDavid van Moolenbroek 
1274*83ee113eSDavid van Moolenbroek 	status = omapi_message_new ((omapi_object_t **)&message, MDL);
1275*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS)
1276*83ee113eSDavid van Moolenbroek 		return status;
1277*83ee113eSDavid van Moolenbroek 	mo = (omapi_object_t *)message;
1278*83ee113eSDavid van Moolenbroek 
1279*83ee113eSDavid van Moolenbroek 	status = omapi_set_int_value (mo, (omapi_object_t *)0,
1280*83ee113eSDavid van Moolenbroek 				      "op", OMAPI_OP_UPDATE);
1281*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
1282*83ee113eSDavid van Moolenbroek 		omapi_message_dereference (&message, MDL);
1283*83ee113eSDavid van Moolenbroek 		return status;
1284*83ee113eSDavid van Moolenbroek 	}
1285*83ee113eSDavid van Moolenbroek 
1286*83ee113eSDavid van Moolenbroek 	if (rid) {
1287*83ee113eSDavid van Moolenbroek 		omapi_handle_t handle;
1288*83ee113eSDavid van Moolenbroek 		status = omapi_set_int_value (mo, (omapi_object_t *)0,
1289*83ee113eSDavid van Moolenbroek 					      "rid", (int)rid);
1290*83ee113eSDavid van Moolenbroek 		if (status != ISC_R_SUCCESS) {
1291*83ee113eSDavid van Moolenbroek 			omapi_message_dereference (&message, MDL);
1292*83ee113eSDavid van Moolenbroek 			return status;
1293*83ee113eSDavid van Moolenbroek 		}
1294*83ee113eSDavid van Moolenbroek 
1295*83ee113eSDavid van Moolenbroek 		status = omapi_object_handle (&handle, object);
1296*83ee113eSDavid van Moolenbroek 		if (status != ISC_R_SUCCESS) {
1297*83ee113eSDavid van Moolenbroek 			omapi_message_dereference (&message, MDL);
1298*83ee113eSDavid van Moolenbroek 			return status;
1299*83ee113eSDavid van Moolenbroek 		}
1300*83ee113eSDavid van Moolenbroek 		status = omapi_set_int_value (mo, (omapi_object_t *)0,
1301*83ee113eSDavid van Moolenbroek 					      "handle", (int)handle);
1302*83ee113eSDavid van Moolenbroek 		if (status != ISC_R_SUCCESS) {
1303*83ee113eSDavid van Moolenbroek 			omapi_message_dereference (&message, MDL);
1304*83ee113eSDavid van Moolenbroek 			return status;
1305*83ee113eSDavid van Moolenbroek 		}
1306*83ee113eSDavid van Moolenbroek 	}
1307*83ee113eSDavid van Moolenbroek 
1308*83ee113eSDavid van Moolenbroek 	status = omapi_set_object_value (mo, (omapi_object_t *)0,
1309*83ee113eSDavid van Moolenbroek 					 "object", object);
1310*83ee113eSDavid van Moolenbroek 	if (status != ISC_R_SUCCESS) {
1311*83ee113eSDavid van Moolenbroek 		omapi_message_dereference (&message, MDL);
1312*83ee113eSDavid van Moolenbroek 		return status;
1313*83ee113eSDavid van Moolenbroek 	}
1314*83ee113eSDavid van Moolenbroek 
1315*83ee113eSDavid van Moolenbroek 	status = omapi_protocol_send_message (po, id, mo, (omapi_object_t *)0);
1316*83ee113eSDavid van Moolenbroek 	omapi_message_dereference (&message, MDL);
1317*83ee113eSDavid van Moolenbroek 	return status;
1318*83ee113eSDavid van Moolenbroek }
1319