00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "dhcpd.h"
00031
00032 #include <omapip/omapip_p.h>
00033
00034 OMAPI_OBJECT_ALLOC (omapi_protocol, omapi_protocol_object_t,
00035 omapi_type_protocol)
00036 OMAPI_OBJECT_ALLOC (omapi_protocol_listener, omapi_protocol_listener_object_t,
00037 omapi_type_protocol_listener)
00038
00039 isc_result_t omapi_protocol_connect (omapi_object_t *h,
00040 const char *server_name,
00041 unsigned port,
00042 omapi_object_t *a)
00043 {
00044 isc_result_t rstatus, status;
00045 omapi_protocol_object_t *obj;
00046
00047 #ifdef DEBUG_PROTOCOL
00048 log_debug ("omapi_protocol_connect(%s port=%d)", server_name, port);
00049 #endif
00050
00051 obj = (omapi_protocol_object_t *)0;
00052 status = omapi_protocol_allocate (&obj, MDL);
00053 if (status != ISC_R_SUCCESS)
00054 return status;
00055
00056 rstatus = omapi_connect ((omapi_object_t *)obj, server_name, port);
00057 if (rstatus != ISC_R_SUCCESS && rstatus != DHCP_R_INCOMPLETE) {
00058 omapi_protocol_dereference (&obj, MDL);
00059 return rstatus;
00060 }
00061 status = omapi_object_reference (&h -> outer,
00062 (omapi_object_t *)obj, MDL);
00063 if (status != ISC_R_SUCCESS) {
00064 omapi_protocol_dereference (&obj, MDL);
00065 return status;
00066 }
00067 status = omapi_object_reference (&obj -> inner, h, MDL);
00068 if (status != ISC_R_SUCCESS) {
00069 omapi_protocol_dereference (&obj, MDL);
00070 return status;
00071 }
00072
00073
00074
00075 if (a) {
00076 obj -> default_auth =
00077 dmalloc (sizeof(omapi_remote_auth_t), MDL);
00078 if (!obj -> default_auth) {
00079 omapi_protocol_dereference (&obj, MDL);
00080 return ISC_R_NOMEMORY;
00081 }
00082
00083 obj -> default_auth -> next = (omapi_remote_auth_t *)0;
00084 status = omapi_object_reference (&obj -> default_auth -> a,
00085 a, MDL);
00086 if (status != ISC_R_SUCCESS) {
00087 dfree (obj -> default_auth, MDL);
00088 omapi_protocol_dereference (&obj, MDL);
00089 return status;
00090 }
00091
00092 obj -> insecure = 0;
00093 rstatus = DHCP_R_INCOMPLETE;
00094 } else {
00095 obj -> insecure = 1;
00096 #if 0
00097 status = ISC_R_SUCCESS;
00098 #endif
00099 }
00100
00101 omapi_protocol_dereference (&obj, MDL);
00102 return rstatus;
00103 }
00104
00105
00106 isc_result_t omapi_protocol_send_intro (omapi_object_t *h,
00107 unsigned ver,
00108 unsigned hsize)
00109 {
00110 isc_result_t status;
00111 omapi_protocol_object_t *p;
00112
00113 #ifdef DEBUG_PROTOCOL
00114 log_debug ("omapi_protocol_send_intro()");
00115 #endif
00116
00117 if (h -> type != omapi_type_protocol)
00118 return DHCP_R_INVALIDARG;
00119 p = (omapi_protocol_object_t *)h;
00120
00121 if (!h -> outer || h -> outer -> type != omapi_type_connection)
00122 return ISC_R_NOTCONNECTED;
00123
00124 status = omapi_connection_put_uint32 (h -> outer, ver);
00125 if (status != ISC_R_SUCCESS)
00126 return status;
00127
00128 status = omapi_connection_put_uint32 (h -> outer, hsize);
00129
00130 if (status != ISC_R_SUCCESS)
00131 return status;
00132
00133
00134
00135 p -> state = omapi_protocol_intro_wait;
00136 status = omapi_connection_require (h -> outer, 8);
00137 if (status != ISC_R_SUCCESS && status != DHCP_R_NOTYET)
00138 return status;
00139
00140
00141 p -> next_xid = random ();
00142 return ISC_R_SUCCESS;
00143 }
00144
00145 #ifdef DEBUG_PROTOCOL
00146 extern const char *omapi_message_op_name(int);
00147 #endif
00148
00149 isc_result_t omapi_protocol_send_message (omapi_object_t *po,
00150 omapi_object_t *id,
00151 omapi_object_t *mo,
00152 omapi_object_t *omo)
00153 {
00154 omapi_protocol_object_t *p;
00155 omapi_object_t *c;
00156 omapi_message_object_t *m, *om;
00157 omapi_remote_auth_t *ra;
00158 omapi_value_t *signature;
00159 isc_result_t status;
00160 unsigned auth_len;
00161
00162 if (po -> type != omapi_type_protocol ||
00163 !po -> outer || po -> outer -> type != omapi_type_connection ||
00164 mo -> type != omapi_type_message)
00165 return DHCP_R_INVALIDARG;
00166 if (omo && omo -> type != omapi_type_message)
00167 return DHCP_R_INVALIDARG;
00168 p = (omapi_protocol_object_t *)po;
00169 c = (omapi_object_t *)(po -> outer);
00170 m = (omapi_message_object_t *)mo;
00171 om = (omapi_message_object_t *)omo;
00172
00173 #ifdef DEBUG_PROTOCOL
00174 log_debug ("omapi_protocol_send_message(): "
00175 "op=%s handle=%#lx id=%#lx rid=%#lx",
00176 omapi_message_op_name (m->op),
00177 (long)(m -> object ? m -> object -> handle : m -> handle),
00178 (long)p -> next_xid, (long)m -> rid);
00179 #endif
00180
00181
00182 if (id) {
00183 for (ra = p -> remote_auth_list; ra; ra = ra -> next) {
00184 if (ra -> a == id) {
00185 break;
00186 }
00187 }
00188
00189 if (!ra)
00190 return DHCP_R_KEY_UNKNOWN;
00191 } else if (p -> remote_auth_list) {
00192 ra = p -> default_auth;
00193 } else {
00194 ra = (omapi_remote_auth_t *)0;
00195 }
00196
00197 if (ra) {
00198 m -> authid = ra -> remote_handle;
00199 status = omapi_object_reference (&m -> id_object,
00200 ra -> a, MDL);
00201 if (status != ISC_R_SUCCESS)
00202 return status;
00203 }
00204
00205
00206 status = omapi_connection_put_uint32 (c, ra ? ra -> remote_handle : 0);
00207 if (status != ISC_R_SUCCESS) {
00208 omapi_disconnect (c, 1);
00209 return status;
00210 }
00211
00212
00213 auth_len = 0;
00214 if (ra) {
00215 status = omapi_set_object_value (c, (omapi_object_t *)0,
00216 "output-authenticator",
00217 ra -> a);
00218 if (status != ISC_R_SUCCESS) {
00219 omapi_disconnect (c, 1);
00220 return status;
00221 }
00222
00223 status = omapi_connection_output_auth_length (c, &auth_len);
00224 if (status != ISC_R_SUCCESS) {
00225 omapi_disconnect (c, 1);
00226 return status;
00227 }
00228 }
00229
00230
00231 status = omapi_connection_put_uint32 (c, auth_len);
00232 if (status != ISC_R_SUCCESS) {
00233 omapi_disconnect (c, 1);
00234 return status;
00235 }
00236
00237
00238 status = omapi_connection_put_uint32 (c, m -> op);
00239 if (status != ISC_R_SUCCESS) {
00240 omapi_disconnect (c, 1);
00241 return status;
00242 }
00243
00244
00245
00246
00247
00248 status = omapi_connection_put_uint32 (c, (m -> h
00249 ? m -> h
00250 : (m -> object
00251 ? m -> object -> handle
00252 : 0)));
00253 if (status != ISC_R_SUCCESS) {
00254 omapi_disconnect (c, 1);
00255 return status;
00256 }
00257
00258
00259 m -> id = p -> next_xid++;
00260 status = omapi_connection_put_uint32 (c, m -> id);
00261 if (status != ISC_R_SUCCESS) {
00262 omapi_disconnect (c, 1);
00263 return status;
00264 }
00265
00266
00267
00268 status = omapi_connection_put_uint32 (c, om ? om -> id : m -> rid);
00269 if (status != ISC_R_SUCCESS) {
00270 omapi_disconnect (c, 1);
00271 return status;
00272 }
00273
00274
00275 status = omapi_stuff_values (c, id, (omapi_object_t *)m);
00276 if (status != ISC_R_SUCCESS) {
00277 omapi_disconnect (c, 1);
00278 return status;
00279 }
00280
00281
00282
00283 status = omapi_connection_put_uint16 (c, 0);
00284 if (status != ISC_R_SUCCESS) {
00285 omapi_disconnect (c, 1);
00286 return status;
00287 }
00288
00289
00290
00291 if (m -> object) {
00292 status = omapi_stuff_values (c, id, m -> object);
00293 if (status != ISC_R_SUCCESS) {
00294 omapi_disconnect (c, 1);
00295 return status;
00296 }
00297 }
00298
00299
00300
00301 status = omapi_connection_put_uint16 (c, 0);
00302 if (status != ISC_R_SUCCESS) {
00303 omapi_disconnect (c, 1);
00304 return status;
00305 }
00306
00307 if (ra) {
00308
00309 signature = (omapi_value_t *)0;
00310 status = omapi_get_value_str (c, (omapi_object_t *)0,
00311 "output-signature", &signature);
00312 if (status != ISC_R_SUCCESS) {
00313 omapi_disconnect (c, 1);
00314 return status;
00315 }
00316
00317
00318 status = (omapi_connection_copyin
00319 (c, signature -> value -> u.buffer.value,
00320 signature -> value -> u.buffer.len));
00321 omapi_value_dereference (&signature, MDL);
00322 if (status != ISC_R_SUCCESS) {
00323 omapi_disconnect (c, 1);
00324 return status;
00325 }
00326
00327
00328 status = omapi_set_value_str (c, (omapi_object_t *)0,
00329 "output-authenticator",
00330 (omapi_typed_data_t *)0);
00331 if (status != ISC_R_SUCCESS) {
00332 omapi_disconnect (c, 1);
00333 return status;
00334 }
00335 }
00336
00337 if (!omo) {
00338 omapi_protocol_reference (&m -> protocol_object, p, MDL);
00339 }
00340 return ISC_R_SUCCESS;
00341 }
00342
00343
00344 isc_result_t omapi_protocol_signal_handler (omapi_object_t *h,
00345 const char *name, va_list ap)
00346 {
00347 isc_result_t status;
00348 omapi_protocol_object_t *p;
00349 omapi_object_t *c;
00350 omapi_message_object_t *m;
00351 omapi_value_t *signature = NULL;
00352 u_int16_t nlen;
00353 u_int32_t vlen;
00354 u_int32_t th;
00355 #if defined (DEBUG_MEMORY_LEAKAGE)
00356 unsigned long previous_outstanding = 0xDEADBEEF;
00357 unsigned long connect_outstanding = 0xDEADBEEF;
00358 #endif
00359
00360 if (h -> type != omapi_type_protocol) {
00361
00362 return ISC_R_UNEXPECTED;
00363 }
00364 p = (omapi_protocol_object_t *)h;
00365
00366 if (!strcmp (name, "connect")) {
00367 #if defined (DEBUG_MEMORY_LEAKAGE)
00368 connect_outstanding = dmalloc_outstanding;
00369 #endif
00370
00371 status = omapi_protocol_send_intro
00372 (h, OMAPI_PROTOCOL_VERSION,
00373 sizeof (omapi_protocol_header_t));
00374 if (status != ISC_R_SUCCESS) {
00375 omapi_disconnect (p -> outer, 1);
00376 return status;
00377 }
00378 return ISC_R_SUCCESS;
00379 }
00380
00381
00382 if (!strcmp (name, "status")) {
00383 status = va_arg (ap, isc_result_t);
00384 if (status != ISC_R_SUCCESS) {
00385 omapi_signal_in (h -> inner, "status", status,
00386 (omapi_object_t *)0);
00387 omapi_disconnect (p -> outer, 1);
00388 return status;
00389 } else {
00390 return omapi_signal_in (h -> inner, "ready");
00391 }
00392 }
00393
00394
00395 if (!strcmp (name, "disconnect")) {
00396 #if defined (DEBUG_MEMORY_LEAKAGE)
00397 if (connect_outstanding != 0xDEADBEEF) {
00398 log_info ("generation %ld: %ld new, %ld outstanding, %ld%s",
00399 dmalloc_generation,
00400 dmalloc_outstanding - previous_outstanding,
00401 dmalloc_outstanding, dmalloc_longterm, " long-term");
00402 }
00403 #endif
00404 #if defined (DEBUG_MEMORY_LEAKAGE)
00405 dmalloc_dump_outstanding ();
00406 #endif
00407 #if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY)
00408 dump_rc_history (h);
00409 #endif
00410 for (m = omapi_registered_messages; m; m = m -> next) {
00411 if (m -> protocol_object == p) {
00412 if (m -> object)
00413 omapi_signal (m -> object, "disconnect");
00414 }
00415 }
00416
00417
00418 return ISC_R_SUCCESS;
00419 }
00420
00421
00422 if (strcmp (name, "ready")) {
00423 if (p -> inner && p -> inner -> type -> signal_handler)
00424 return (*(p -> inner -> type -> signal_handler)) (h,
00425 name,
00426 ap);
00427 return ISC_R_NOTFOUND;
00428 }
00429
00430 if (!p -> outer || p -> outer -> type != omapi_type_connection)
00431 return DHCP_R_INVALIDARG;
00432 c = p -> outer;
00433
00434
00435
00436
00437 switch (p -> state) {
00438 case omapi_protocol_intro_wait:
00439
00440
00441 omapi_connection_get_uint32 (c, &p -> protocol_version);
00442 omapi_connection_get_uint32 (c, &p -> header_size);
00443
00444
00445 if (p -> protocol_version != OMAPI_PROTOCOL_VERSION) {
00446 omapi_disconnect (c, 1);
00447 return DHCP_R_VERSIONMISMATCH;
00448 }
00449
00450 if (p -> header_size < sizeof (omapi_protocol_header_t)) {
00451 omapi_disconnect (c, 1);
00452 return DHCP_R_PROTOCOLERROR;
00453 }
00454
00455 if (p -> default_auth) {
00456 status = omapi_protocol_send_open
00457 (h, (omapi_object_t *)0, "authenticator",
00458 p -> default_auth -> a,
00459 OMAPI_NOTIFY_PROTOCOL);
00460 if (status != ISC_R_SUCCESS) {
00461 omapi_disconnect (c, 1);
00462 return status;
00463 }
00464 } else {
00465 status = omapi_signal_in (h -> inner, "ready");
00466 }
00467
00468 to_header_wait:
00469
00470 p -> state = omapi_protocol_header_wait;
00471
00472
00473
00474
00475 if ((omapi_connection_require (c, p -> header_size)) !=
00476 ISC_R_SUCCESS)
00477 break;
00478
00479
00480 case omapi_protocol_header_wait:
00481 #if defined (DEBUG_MEMORY_LEAKAGE)
00482 if (previous_outstanding != 0xDEADBEEF) {
00483 log_info ("%s %ld: %ld new, %ld outstanding, %ld%s",
00484 "generation", dmalloc_generation,
00485 dmalloc_outstanding - previous_outstanding,
00486 dmalloc_outstanding, dmalloc_longterm,
00487 " long-term");
00488 #endif
00489 #if (defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL))
00490 dmalloc_dump_outstanding ();
00491 #endif
00492 #if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY)
00493 dump_rc_history (h);
00494 #endif
00495 #if defined (DEBUG_MEMORY_LEAKAGE)
00496 }
00497 previous_outstanding = dmalloc_outstanding;
00498 #endif
00499 status = omapi_message_new ((omapi_object_t **)&p -> message,
00500 MDL);
00501 if (status != ISC_R_SUCCESS) {
00502 omapi_disconnect (c, 1);
00503 return status;
00504 }
00505
00506 p -> verify_result = ISC_R_SUCCESS;
00507
00508
00509 omapi_connection_get_uint32 (c, &p -> message -> authid);
00510
00511
00512 if (p -> message -> authid) {
00513 status = (omapi_protocol_lookup_auth
00514 (&p -> message -> id_object, h,
00515 p -> message -> authid));
00516 if (status != ISC_R_SUCCESS)
00517 p -> verify_result = status;
00518
00519
00520 status = omapi_set_object_value
00521 (c, (omapi_object_t *)0, "input-authenticator",
00522 p -> message -> id_object);
00523 if (status != ISC_R_SUCCESS) {
00524 omapi_disconnect (c, 1);
00525 return status;
00526 }
00527 }
00528
00529 omapi_connection_get_uint32 (c, &p -> message -> authlen);
00530 omapi_connection_get_uint32 (c, &p -> message -> op);
00531 omapi_connection_get_uint32 (c, &th);
00532 p -> message -> h = th;
00533 omapi_connection_get_uint32 (c, &p -> message -> id);
00534 omapi_connection_get_uint32 (c, &p -> message -> rid);
00535
00536
00537 if (p -> header_size > sizeof (omapi_protocol_header_t)) {
00538 omapi_connection_copyout
00539 (0, c, (p -> header_size -
00540 sizeof (omapi_protocol_header_t)));
00541 }
00542
00543
00544
00545
00546
00547
00548
00549
00550 p -> reading_message_values = 1;
00551
00552 need_name_length:
00553
00554
00555 p -> state = omapi_protocol_name_length_wait;
00556
00557
00558 if ((omapi_connection_require (c, 2)) != ISC_R_SUCCESS)
00559 break;
00560
00561
00562 case omapi_protocol_name_length_wait:
00563 omapi_connection_get_uint16 (c, &nlen);
00564
00565
00566 if (nlen == 0) {
00567
00568
00569
00570
00571
00572 if (p -> reading_message_values) {
00573 p -> reading_message_values = 0;
00574 goto need_name_length;
00575 }
00576
00577
00578
00579
00580 if (p -> message -> authlen == 0)
00581 goto message_done;
00582
00583
00584
00585 p -> state = omapi_protocol_signature_wait;
00586
00587
00588
00589
00590 if (omapi_connection_require
00591 (c, p -> message -> authlen) == ISC_R_SUCCESS)
00592 goto signature_wait;
00593 break;
00594 }
00595
00596
00597 status = (omapi_data_string_new (&p -> name, nlen, MDL));
00598 if (status != ISC_R_SUCCESS) {
00599 omapi_disconnect (c, 1);
00600 return ISC_R_NOMEMORY;
00601 }
00602 p -> state = omapi_protocol_name_wait;
00603 if (omapi_connection_require (c, nlen) != ISC_R_SUCCESS)
00604 break;
00605
00606
00607 case omapi_protocol_name_wait:
00608 omapi_connection_copyout (p -> name -> value, c,
00609 p -> name -> len);
00610
00611 p -> state = omapi_protocol_value_length_wait;
00612 if ((omapi_connection_require (c, 4)) != ISC_R_SUCCESS)
00613 break;
00614
00615
00616 case omapi_protocol_value_length_wait:
00617 omapi_connection_get_uint32 (c, &vlen);
00618
00619
00620
00621
00622 if (!vlen)
00623 goto insert_new_value;
00624
00625 status = omapi_typed_data_new (MDL, &p -> value,
00626 omapi_datatype_data,
00627 vlen);
00628 if (status != ISC_R_SUCCESS) {
00629 omapi_disconnect (c, 1);
00630 return ISC_R_NOMEMORY;
00631 }
00632
00633 p -> state = omapi_protocol_value_wait;
00634 if (omapi_connection_require (c, vlen) != ISC_R_SUCCESS)
00635 break;
00636
00637
00638 case omapi_protocol_value_wait:
00639 omapi_connection_copyout (p -> value -> u.buffer.value, c,
00640 p -> value -> u.buffer.len);
00641
00642 insert_new_value:
00643 if (p -> reading_message_values) {
00644 status = (omapi_set_value
00645 ((omapi_object_t *)p -> message,
00646 p -> message -> id_object,
00647 p -> name, p -> value));
00648 } else {
00649 if (!p -> message -> object) {
00650
00651
00652 status = (omapi_generic_new
00653 (&p -> message -> object, MDL));
00654 if (status != ISC_R_SUCCESS) {
00655 omapi_disconnect (c, 1);
00656 return status;
00657 }
00658 }
00659 status = (omapi_set_value
00660 ((omapi_object_t *)p -> message -> object,
00661 p -> message -> id_object,
00662 p -> name, p -> value));
00663 }
00664 if (status != ISC_R_SUCCESS) {
00665 omapi_disconnect (c, 1);
00666 return status;
00667 }
00668 omapi_data_string_dereference (&p -> name, MDL);
00669 if (p -> value)
00670 omapi_typed_data_dereference (&p -> value, MDL);
00671 goto need_name_length;
00672
00673 signature_wait:
00674 case omapi_protocol_signature_wait:
00675 if (p -> message -> id_object) {
00676
00677 status = omapi_get_value_str (c, (omapi_object_t *)0,
00678 "input-signature",
00679 &signature);
00680 if (status != ISC_R_SUCCESS) {
00681 omapi_disconnect (c, 1);
00682 return status;
00683 }
00684
00685
00686 status = omapi_set_value_str (c, (omapi_object_t *)0,
00687 "input-authenticator",
00688 (omapi_typed_data_t *)0);
00689 if (status != ISC_R_SUCCESS) {
00690 omapi_value_dereference (&signature, MDL);
00691 omapi_disconnect (c, 1);
00692 return status;
00693 }
00694 }
00695
00696
00697 status = omapi_typed_data_new (MDL,
00698 &p -> message -> authenticator,
00699 omapi_datatype_data,
00700 p -> message -> authlen);
00701
00702 if (status != ISC_R_SUCCESS) {
00703 if (signature != NULL) {
00704 omapi_value_dereference (&signature, MDL);
00705 }
00706 omapi_disconnect (c, 1);
00707 return ISC_R_NOMEMORY;
00708 }
00709 omapi_connection_copyout
00710 (p -> message -> authenticator -> u.buffer.value, c,
00711 p -> message -> authlen);
00712
00713
00714 if (p -> message -> id_object &&
00715 ((signature -> value -> u.buffer.len !=
00716 p -> message -> authlen) ||
00717 (memcmp (signature -> value -> u.buffer.value,
00718 p -> message -> authenticator -> u.buffer.value,
00719 p -> message -> authlen) != 0))) {
00720
00721 p->verify_result = DHCP_R_INVALIDKEY;
00722 }
00723
00724 if (signature != NULL) {
00725 omapi_value_dereference (&signature, MDL);
00726 }
00727
00728
00729 message_done:
00730 if (p -> verify_result != ISC_R_SUCCESS) {
00731 status = omapi_protocol_send_status
00732 (h, (omapi_object_t *)0, p -> verify_result,
00733 p -> message -> id, (char *)0);
00734 } else {
00735 status = omapi_message_process
00736 ((omapi_object_t *)p -> message, h);
00737 }
00738 if (status != ISC_R_SUCCESS) {
00739 omapi_disconnect (c, 1);
00740 return ISC_R_NOMEMORY;
00741 }
00742
00743 omapi_message_dereference (&p -> message, MDL);
00744 #if defined (DEBUG_MEMORY_LEAKAGE)
00745 log_info ("generation %ld: %ld new, %ld outstanding, %ld%s",
00746 dmalloc_generation,
00747 dmalloc_outstanding - previous_outstanding,
00748 dmalloc_outstanding, dmalloc_longterm, " long-term");
00749 #endif
00750 #if (defined (DEBUG_MEMORY_LEAKAGE) || defined (DEBUG_MALLOC_POOL))
00751 dmalloc_dump_outstanding ();
00752 #endif
00753 #if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY)
00754 dump_rc_history (h);
00755 #endif
00756 #if defined (DEBUG_MEMORY_LEAKAGE)
00757 previous_outstanding = 0xDEADBEEF;
00758 #endif
00759
00760 goto to_header_wait;
00761
00762 default:
00763
00764 break;
00765 }
00766 return ISC_R_SUCCESS;
00767 }
00768
00769 isc_result_t omapi_protocol_add_auth (omapi_object_t *po,
00770 omapi_object_t *ao,
00771 omapi_handle_t handle)
00772 {
00773 omapi_protocol_object_t *p;
00774 omapi_remote_auth_t *r;
00775 isc_result_t status;
00776
00777 if (ao -> type != omapi_type_auth_key &&
00778 (!ao -> inner || ao -> inner -> type != omapi_type_auth_key))
00779 return DHCP_R_INVALIDARG;
00780
00781 if (po -> type != omapi_type_protocol)
00782 return DHCP_R_INVALIDARG;
00783 p = (omapi_protocol_object_t *)po;
00784
00785 #ifdef DEBUG_PROTOCOL
00786 log_debug ("omapi_protocol_add_auth(name=%s)",
00787 ((omapi_auth_key_t *)ao) -> name);
00788 #endif
00789
00790 if (p -> verify_auth) {
00791 status = (p -> verify_auth) (po, (omapi_auth_key_t *)ao);
00792 if (status != ISC_R_SUCCESS)
00793 return status;
00794 }
00795
00796
00797
00798
00799 if (p -> default_auth && !p -> remote_auth_list) {
00800 if (p -> default_auth -> a != ao) {
00801
00802 omapi_disconnect (p -> outer, 1);
00803 return ISC_R_UNEXPECTED;
00804 }
00805
00806 p -> remote_auth_list = p -> default_auth;
00807 p -> default_auth -> remote_handle = handle;
00808
00809 return omapi_signal_in (p -> inner, "ready");
00810 }
00811
00812 r = dmalloc (sizeof(*r), MDL);
00813 if (!r)
00814 return ISC_R_NOMEMORY;
00815
00816 status = omapi_object_reference (&r -> a, ao, MDL);
00817 if (status != ISC_R_SUCCESS) {
00818 dfree (r, MDL);
00819 return status;
00820 }
00821
00822 r -> remote_handle = handle;
00823 r -> next = p -> remote_auth_list;
00824 p -> remote_auth_list = r;
00825
00826 return ISC_R_SUCCESS;
00827 }
00828
00829 isc_result_t omapi_protocol_lookup_auth (omapi_object_t **a,
00830 omapi_object_t *po,
00831 omapi_handle_t handle)
00832 {
00833 omapi_protocol_object_t *p;
00834 omapi_remote_auth_t *r;
00835
00836 if (po -> type != omapi_type_protocol)
00837 return DHCP_R_INVALIDARG;
00838 p = (omapi_protocol_object_t *)po;
00839
00840 for (r = p -> remote_auth_list; r; r = r -> next)
00841 if (r -> remote_handle == handle)
00842 return omapi_object_reference (a, r -> a, MDL);
00843
00844 return DHCP_R_KEY_UNKNOWN;
00845 }
00846
00847 isc_result_t omapi_protocol_set_value (omapi_object_t *h,
00848 omapi_object_t *id,
00849 omapi_data_string_t *name,
00850 omapi_typed_data_t *value)
00851 {
00852 omapi_protocol_object_t *p;
00853 omapi_remote_auth_t *r;
00854
00855 if (h -> type != omapi_type_protocol)
00856 return DHCP_R_INVALIDARG;
00857 p = (omapi_protocol_object_t *)h;
00858
00859 if (omapi_ds_strcmp (name, "default-authenticator") == 0) {
00860 if (!value || value -> type != omapi_datatype_object)
00861 return DHCP_R_INVALIDARG;
00862
00863 if (!value -> u.object) {
00864 p -> default_auth = (omapi_remote_auth_t *)0;
00865 } else {
00866 for (r = p -> remote_auth_list; r; r = r -> next)
00867 if (r -> a == value -> u.object)
00868 break;
00869
00870 if (!r)
00871 return DHCP_R_KEY_UNKNOWN;
00872
00873 p -> default_auth = r;
00874 }
00875
00876 return ISC_R_SUCCESS;
00877 }
00878
00879 if (h -> inner && h -> inner -> type -> set_value)
00880 return (*(h -> inner -> type -> set_value))
00881 (h -> inner, id, name, value);
00882 return ISC_R_NOTFOUND;
00883 }
00884
00885 isc_result_t omapi_protocol_get_value (omapi_object_t *h,
00886 omapi_object_t *id,
00887 omapi_data_string_t *name,
00888 omapi_value_t **value)
00889 {
00890 omapi_protocol_object_t *p;
00891
00892 if (h -> type != omapi_type_protocol)
00893 return DHCP_R_INVALIDARG;
00894 p = (omapi_protocol_object_t *)h;
00895
00896 if (omapi_ds_strcmp (name, "default-authenticator") == 0) {
00897 if (!p -> default_auth)
00898 return ISC_R_NOTFOUND;
00899
00900 return omapi_make_object_value (value, name,
00901 p -> default_auth -> a, MDL);
00902 }
00903
00904 if (h -> inner && h -> inner -> type -> get_value)
00905 return (*(h -> inner -> type -> get_value))
00906 (h -> inner, id, name, value);
00907 return ISC_R_NOTFOUND;
00908 }
00909
00910 isc_result_t omapi_protocol_destroy (omapi_object_t *h,
00911 const char *file, int line)
00912 {
00913 omapi_protocol_object_t *p;
00914 if (h -> type != omapi_type_protocol)
00915 return DHCP_R_INVALIDARG;
00916 p = (omapi_protocol_object_t *)h;
00917 if (p -> message)
00918 omapi_message_dereference (&p -> message, file, line);
00919
00920
00921
00922
00923 if (p -> default_auth && !p -> remote_auth_list)
00924 dfree (p -> default_auth, file, line);
00925
00926 while (p -> remote_auth_list) {
00927 omapi_remote_auth_t *r = p -> remote_auth_list;
00928 p -> remote_auth_list = p -> remote_auth_list -> next;
00929 omapi_object_dereference (&r -> a, file, line);
00930 dfree (r, file, line);
00931 }
00932 return ISC_R_SUCCESS;
00933 }
00934
00935
00936
00937
00938 isc_result_t omapi_protocol_stuff_values (omapi_object_t *c,
00939 omapi_object_t *id,
00940 omapi_object_t *p)
00941 {
00942 if (p -> type != omapi_type_protocol)
00943 return DHCP_R_INVALIDARG;
00944
00945 if (p -> inner && p -> inner -> type -> stuff_values)
00946 return (*(p -> inner -> type -> stuff_values)) (c, id,
00947 p -> inner);
00948 return ISC_R_SUCCESS;
00949 }
00950
00951
00952
00953
00954 isc_boolean_t omapi_protocol_authenticated (omapi_object_t *h)
00955 {
00956 if (h -> type != omapi_type_protocol)
00957 return isc_boolean_false;
00958 if (((omapi_protocol_object_t *)h) -> insecure)
00959 return isc_boolean_false;
00960 else
00961 return isc_boolean_true;
00962 }
00963
00964
00965
00966
00967 isc_result_t omapi_protocol_configure_security (omapi_object_t *h,
00968 isc_result_t (*verify_addr)
00969 (omapi_object_t *,
00970 omapi_addr_t *),
00971 isc_result_t (*verify_auth)
00972 (omapi_object_t *,
00973 omapi_auth_key_t *))
00974 {
00975 omapi_protocol_listener_object_t *l;
00976
00977 if (h -> outer && h -> outer -> type == omapi_type_protocol_listener)
00978 h = h -> outer;
00979
00980 if (h -> type != omapi_type_protocol_listener)
00981 return DHCP_R_INVALIDARG;
00982 l = (omapi_protocol_listener_object_t *)h;
00983
00984 l -> verify_auth = verify_auth;
00985 l -> insecure = 0;
00986
00987 if (h -> outer != NULL) {
00988 return omapi_listener_configure_security (h -> outer, verify_addr);
00989 } else {
00990 return DHCP_R_INVALIDARG;
00991 }
00992 }
00993
00994
00995
00996
00997
00998 isc_result_t omapi_protocol_listen (omapi_object_t *h,
00999 unsigned port,
01000 int max)
01001 {
01002 isc_result_t status;
01003 omapi_protocol_listener_object_t *obj;
01004
01005 obj = (omapi_protocol_listener_object_t *)0;
01006 status = omapi_protocol_listener_allocate (&obj, MDL);
01007 if (status != ISC_R_SUCCESS)
01008 return status;
01009
01010 status = omapi_object_reference (&h -> outer,
01011 (omapi_object_t *)obj, MDL);
01012 if (status != ISC_R_SUCCESS) {
01013 omapi_protocol_listener_dereference (&obj, MDL);
01014 return status;
01015 }
01016 status = omapi_object_reference (&obj -> inner, h, MDL);
01017 if (status != ISC_R_SUCCESS) {
01018 omapi_protocol_listener_dereference (&obj, MDL);
01019 return status;
01020 }
01021
01022
01023 obj -> insecure = 1;
01024
01025 status = omapi_listen ((omapi_object_t *)obj, port, max);
01026 omapi_protocol_listener_dereference (&obj, MDL);
01027 return status;
01028 }
01029
01030
01031
01032
01033 isc_result_t omapi_protocol_listener_signal (omapi_object_t *o,
01034 const char *name, va_list ap)
01035 {
01036 isc_result_t status;
01037 omapi_object_t *c;
01038 omapi_protocol_object_t *obj;
01039 omapi_protocol_listener_object_t *p;
01040
01041 if (!o || o -> type != omapi_type_protocol_listener)
01042 return DHCP_R_INVALIDARG;
01043 p = (omapi_protocol_listener_object_t *)o;
01044
01045
01046 if (strcmp (name, "connect")) {
01047 if (p -> inner && p -> inner -> type -> signal_handler)
01048 return (*(p -> inner -> type -> signal_handler))
01049 (p -> inner, name, ap);
01050 return ISC_R_NOTFOUND;
01051 }
01052
01053 c = va_arg (ap, omapi_object_t *);
01054 if (!c || c -> type != omapi_type_connection)
01055 return DHCP_R_INVALIDARG;
01056
01057 obj = (omapi_protocol_object_t *)0;
01058 status = omapi_protocol_allocate (&obj, MDL);
01059 if (status != ISC_R_SUCCESS)
01060 return status;
01061
01062 obj -> verify_auth = p -> verify_auth;
01063 obj -> insecure = p -> insecure;
01064
01065 status = omapi_object_reference (&obj -> outer, c, MDL);
01066 if (status != ISC_R_SUCCESS) {
01067 lose:
01068 omapi_protocol_dereference (&obj, MDL);
01069 omapi_disconnect (c, 1);
01070 return status;
01071 }
01072
01073 status = omapi_object_reference (&c -> inner,
01074 (omapi_object_t *)obj, MDL);
01075 if (status != ISC_R_SUCCESS)
01076 goto lose;
01077
01078
01079 status = omapi_protocol_send_intro ((omapi_object_t *)obj,
01080 OMAPI_PROTOCOL_VERSION,
01081 sizeof (omapi_protocol_header_t));
01082 if (status != ISC_R_SUCCESS)
01083 goto lose;
01084
01085 omapi_protocol_dereference (&obj, MDL);
01086 return status;
01087 }
01088
01089 isc_result_t omapi_protocol_listener_set_value (omapi_object_t *h,
01090 omapi_object_t *id,
01091 omapi_data_string_t *name,
01092 omapi_typed_data_t *value)
01093 {
01094 if (h -> type != omapi_type_protocol_listener)
01095 return DHCP_R_INVALIDARG;
01096
01097 if (h -> inner && h -> inner -> type -> set_value)
01098 return (*(h -> inner -> type -> set_value))
01099 (h -> inner, id, name, value);
01100 return ISC_R_NOTFOUND;
01101 }
01102
01103 isc_result_t omapi_protocol_listener_get_value (omapi_object_t *h,
01104 omapi_object_t *id,
01105 omapi_data_string_t *name,
01106 omapi_value_t **value)
01107 {
01108 if (h -> type != omapi_type_protocol_listener)
01109 return DHCP_R_INVALIDARG;
01110
01111 if (h -> inner && h -> inner -> type -> get_value)
01112 return (*(h -> inner -> type -> get_value))
01113 (h -> inner, id, name, value);
01114 return ISC_R_NOTFOUND;
01115 }
01116
01117 isc_result_t omapi_protocol_listener_destroy (omapi_object_t *h,
01118 const char *file, int line)
01119 {
01120 if (h -> type != omapi_type_protocol_listener)
01121 return DHCP_R_INVALIDARG;
01122 return ISC_R_SUCCESS;
01123 }
01124
01125
01126
01127
01128 isc_result_t omapi_protocol_listener_stuff (omapi_object_t *c,
01129 omapi_object_t *id,
01130 omapi_object_t *p)
01131 {
01132 if (p -> type != omapi_type_protocol_listener)
01133 return DHCP_R_INVALIDARG;
01134
01135 if (p -> inner && p -> inner -> type -> stuff_values)
01136 return (*(p -> inner -> type -> stuff_values)) (c, id,
01137 p -> inner);
01138 return ISC_R_SUCCESS;
01139 }
01140
01141 isc_result_t omapi_protocol_send_status (omapi_object_t *po,
01142 omapi_object_t *id,
01143 isc_result_t waitstatus,
01144 unsigned rid, const char *msg)
01145 {
01146 isc_result_t status;
01147 omapi_message_object_t *message = (omapi_message_object_t *)0;
01148 omapi_object_t *mo;
01149
01150 if (po -> type != omapi_type_protocol)
01151 return DHCP_R_INVALIDARG;
01152
01153 status = omapi_message_new ((omapi_object_t **)&message, MDL);
01154 if (status != ISC_R_SUCCESS)
01155 return status;
01156 mo = (omapi_object_t *)message;
01157
01158 status = omapi_set_int_value (mo, (omapi_object_t *)0,
01159 "op", OMAPI_OP_STATUS);
01160 if (status != ISC_R_SUCCESS) {
01161 omapi_message_dereference (&message, MDL);
01162 return status;
01163 }
01164
01165 status = omapi_set_int_value (mo, (omapi_object_t *)0,
01166 "rid", (int)rid);
01167 if (status != ISC_R_SUCCESS) {
01168 omapi_message_dereference (&message, MDL);
01169 return status;
01170 }
01171
01172 status = omapi_set_int_value (mo, (omapi_object_t *)0,
01173 "result", (int)waitstatus);
01174 if (status != ISC_R_SUCCESS) {
01175 omapi_message_dereference (&message, MDL);
01176 return status;
01177 }
01178
01179
01180 if (msg) {
01181 status = omapi_set_string_value (mo, (omapi_object_t *)0,
01182 "message", msg);
01183 if (status != ISC_R_SUCCESS) {
01184 omapi_message_dereference (&message, MDL);
01185 return status;
01186 }
01187 }
01188
01189 status = omapi_protocol_send_message (po, id, mo, (omapi_object_t *)0);
01190 omapi_message_dereference (&message, MDL);
01191 return status;
01192 }
01193
01194
01195
01196
01197
01198 isc_result_t omapi_protocol_send_open (omapi_object_t *po,
01199 omapi_object_t *id,
01200 const char *type,
01201 omapi_object_t *object,
01202 unsigned flags)
01203 {
01204 isc_result_t status;
01205 omapi_message_object_t *message = (omapi_message_object_t *)0;
01206 omapi_object_t *mo;
01207
01208 if (po -> type != omapi_type_protocol)
01209 return DHCP_R_INVALIDARG;
01210
01211 status = omapi_message_new ((omapi_object_t **)&message, MDL);
01212 mo = (omapi_object_t *)message;
01213
01214 if (status == ISC_R_SUCCESS)
01215 status = omapi_set_int_value (mo, (omapi_object_t *)0,
01216 "op", OMAPI_OP_OPEN);
01217
01218 if (status == ISC_R_SUCCESS)
01219 status = omapi_set_object_value (mo, (omapi_object_t *)0,
01220 "object", object);
01221
01222 if ((flags & OMAPI_CREATE) && (status == ISC_R_SUCCESS))
01223 status = omapi_set_boolean_value (mo, (omapi_object_t *)0,
01224 "create", 1);
01225
01226 if ((flags & OMAPI_UPDATE) && (status == ISC_R_SUCCESS))
01227 status = omapi_set_boolean_value (mo, (omapi_object_t *)0,
01228 "update", 1);
01229
01230 if ((flags & OMAPI_EXCL) && (status == ISC_R_SUCCESS))
01231 status = omapi_set_boolean_value (mo, (omapi_object_t *)0,
01232 "exclusive", 1);
01233
01234 if ((flags & OMAPI_NOTIFY_PROTOCOL) && (status == ISC_R_SUCCESS))
01235 status = omapi_set_object_value (mo, (omapi_object_t *)0,
01236 "notify-object", po);
01237
01238 if (type && (status == ISC_R_SUCCESS))
01239 status = omapi_set_string_value (mo, (omapi_object_t *)0,
01240 "type", type);
01241
01242 if (status == ISC_R_SUCCESS)
01243 status = omapi_message_register (mo);
01244
01245 if (status == ISC_R_SUCCESS) {
01246 status = omapi_protocol_send_message (po, id, mo,
01247 (omapi_object_t *)0);
01248 if (status != ISC_R_SUCCESS)
01249 omapi_message_unregister (mo);
01250 }
01251
01252 if (message)
01253 omapi_message_dereference (&message, MDL);
01254
01255 return status;
01256 }
01257
01258 isc_result_t omapi_protocol_send_update (omapi_object_t *po,
01259 omapi_object_t *id,
01260 unsigned rid,
01261 omapi_object_t *object)
01262 {
01263 isc_result_t status;
01264 omapi_message_object_t *message = (omapi_message_object_t *)0;
01265 omapi_object_t *mo;
01266
01267 if (po -> type != omapi_type_protocol)
01268 return DHCP_R_INVALIDARG;
01269
01270 status = omapi_message_new ((omapi_object_t **)&message, MDL);
01271 if (status != ISC_R_SUCCESS)
01272 return status;
01273 mo = (omapi_object_t *)message;
01274
01275 status = omapi_set_int_value (mo, (omapi_object_t *)0,
01276 "op", OMAPI_OP_UPDATE);
01277 if (status != ISC_R_SUCCESS) {
01278 omapi_message_dereference (&message, MDL);
01279 return status;
01280 }
01281
01282 if (rid) {
01283 omapi_handle_t handle;
01284 status = omapi_set_int_value (mo, (omapi_object_t *)0,
01285 "rid", (int)rid);
01286 if (status != ISC_R_SUCCESS) {
01287 omapi_message_dereference (&message, MDL);
01288 return status;
01289 }
01290
01291 status = omapi_object_handle (&handle, object);
01292 if (status != ISC_R_SUCCESS) {
01293 omapi_message_dereference (&message, MDL);
01294 return status;
01295 }
01296 status = omapi_set_int_value (mo, (omapi_object_t *)0,
01297 "handle", (int)handle);
01298 if (status != ISC_R_SUCCESS) {
01299 omapi_message_dereference (&message, MDL);
01300 return status;
01301 }
01302 }
01303
01304 status = omapi_set_object_value (mo, (omapi_object_t *)0,
01305 "object", object);
01306 if (status != ISC_R_SUCCESS) {
01307 omapi_message_dereference (&message, MDL);
01308 return status;
01309 }
01310
01311 status = omapi_protocol_send_message (po, id, mo, (omapi_object_t *)0);
01312 omapi_message_dereference (&message, MDL);
01313 return status;
01314 }