Annotation of embedaddon/strongswan/src/libcharon/plugins/smp/smp.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2007 Martin Willi
3: * HSR Hochschule fuer Technik Rapperswil
4: *
5: * This program is free software; you can redistribute it and/or modify it
6: * under the terms of the GNU General Public License as published by the
7: * Free Software Foundation; either version 2 of the License, or (at your
8: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9: *
10: * This program is distributed in the hope that it will be useful, but
11: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13: * for more details.
14: */
15:
16: #include <stdlib.h>
17:
18: #include "smp.h"
19:
20: #include <sys/types.h>
21: #include <sys/stat.h>
22: #include <sys/socket.h>
23: #include <sys/un.h>
24: #include <unistd.h>
25: #include <errno.h>
26: #include <signal.h>
27: #include <inttypes.h>
28: #include <libxml/xmlreader.h>
29: #include <libxml/xmlwriter.h>
30:
31: #include <library.h>
32: #include <daemon.h>
33: #include <threading/thread.h>
34: #include <processing/jobs/callback_job.h>
35:
36:
37: typedef struct private_smp_t private_smp_t;
38:
39: /**
40: * Private data of an smp_t object.
41: */
42: struct private_smp_t {
43:
44: /**
45: * Public part of smp_t object.
46: */
47: smp_t public;
48:
49: /**
50: * XML unix socket fd
51: */
52: int socket;
53: };
54:
55: ENUM(ike_sa_state_lower_names, IKE_CREATED, IKE_DELETING,
56: "created",
57: "connecting",
58: "established",
59: "passive",
60: "rekeying",
61: "rekeyed",
62: "deleting",
63: );
64:
65: /**
66: * write a bool into element
67: */
68: static void write_bool(xmlTextWriterPtr writer, char *element, bool val)
69: {
70: xmlTextWriterWriteElement(writer, element, val ? "true" : "false");
71: }
72:
73: /**
74: * write a identification_t into element
75: */
76: static void write_id(xmlTextWriterPtr writer, char *element, identification_t *id)
77: {
78: xmlTextWriterStartElement(writer, element);
79: switch (id->get_type(id))
80: {
81: {
82: char *type;
83:
84: while (TRUE)
85: {
86: case ID_ANY:
87: type = "any";
88: break;
89: case ID_IPV4_ADDR:
90: type = "ipv4";
91: break;
92: case ID_IPV6_ADDR:
93: type = "ipv6";
94: break;
95: case ID_FQDN:
96: type = "fqdn";
97: break;
98: case ID_RFC822_ADDR:
99: type = "email";
100: break;
101: case ID_DER_ASN1_DN:
102: type = "asn1dn";
103: break;
104: case ID_DER_ASN1_GN:
105: type = "asn1gn";
106: break;
107: }
108: xmlTextWriterWriteAttribute(writer, "type", type);
109: xmlTextWriterWriteFormatString(writer, "%Y", id);
110: break;
111: }
112: default:
113: /* TODO: base64 keyid */
114: xmlTextWriterWriteAttribute(writer, "type", "keyid");
115: break;
116: }
117: xmlTextWriterEndElement(writer);
118: }
119:
120: /**
121: * write a host_t address into an element
122: */
123: static void write_address(xmlTextWriterPtr writer, char *element, host_t *host)
124: {
125: xmlTextWriterStartElement(writer, element);
126: xmlTextWriterWriteAttribute(writer, "type",
127: host->get_family(host) == AF_INET ? "ipv4" : "ipv6");
128: if (host->is_anyaddr(host))
129: { /* do not use %any for XML */
130: xmlTextWriterWriteFormatString(writer, "%s",
131: host->get_family(host) == AF_INET ? "0.0.0.0" : "::");
132: }
133: else
134: {
135: xmlTextWriterWriteFormatString(writer, "%H", host);
136: }
137: xmlTextWriterEndElement(writer);
138: }
139:
140: /**
141: * write networks element
142: */
143: static void write_networks(xmlTextWriterPtr writer, char *element,
144: linked_list_t *list)
145: {
146: enumerator_t *enumerator;
147: traffic_selector_t *ts;
148:
149: xmlTextWriterStartElement(writer, element);
150: enumerator = list->create_enumerator(list);
151: while (enumerator->enumerate(enumerator, (void**)&ts))
152: {
153: xmlTextWriterStartElement(writer, "network");
154: xmlTextWriterWriteAttribute(writer, "type",
155: ts->get_type(ts) == TS_IPV4_ADDR_RANGE ? "ipv4" : "ipv6");
156: xmlTextWriterWriteFormatString(writer, "%R", ts);
157: xmlTextWriterEndElement(writer);
158: }
159: enumerator->destroy(enumerator);
160: xmlTextWriterEndElement(writer);
161: }
162:
163: /**
164: * write a childEnd
165: */
166: static void write_childend(xmlTextWriterPtr writer, child_sa_t *child, bool local)
167: {
168: linked_list_t *list;
169:
170: xmlTextWriterWriteFormatElement(writer, "spi", "%x",
171: htonl(child->get_spi(child, local)));
172: list = linked_list_create_from_enumerator(
173: child->create_ts_enumerator(child, local));
174: write_networks(writer, "networks", list);
175: list->destroy(list);
176: }
177:
178: /**
179: * write a child_sa_t
180: */
181: static void write_child(xmlTextWriterPtr writer, child_sa_t *child)
182: {
183: child_cfg_t *config;
184:
185: config = child->get_config(child);
186:
187: xmlTextWriterStartElement(writer, "childsa");
188: xmlTextWriterWriteFormatElement(writer, "reqid", "%d",
189: child->get_reqid(child));
190: xmlTextWriterWriteFormatElement(writer, "childconfig", "%s",
191: config->get_name(config));
192: xmlTextWriterStartElement(writer, "local");
193: write_childend(writer, child, TRUE);
194: xmlTextWriterEndElement(writer);
195: xmlTextWriterStartElement(writer, "remote");
196: write_childend(writer, child, FALSE);
197: xmlTextWriterEndElement(writer);
198: xmlTextWriterEndElement(writer);
199: }
200:
201: /**
202: * process a ikesalist query request message
203: */
204: static void request_query_ikesa(xmlTextReaderPtr reader, xmlTextWriterPtr writer)
205: {
206: enumerator_t *enumerator;
207: ike_sa_t *ike_sa;
208:
209: /* <ikesalist> */
210: xmlTextWriterStartElement(writer, "ikesalist");
211:
212: enumerator = charon->controller->create_ike_sa_enumerator(
213: charon->controller, TRUE);
214: while (enumerator->enumerate(enumerator, &ike_sa))
215: {
216: ike_sa_id_t *id;
217: host_t *local, *remote;
218: enumerator_t *children;
219: child_sa_t *child_sa;
220:
221: id = ike_sa->get_id(ike_sa);
222:
223: xmlTextWriterStartElement(writer, "ikesa");
224: xmlTextWriterWriteFormatElement(writer, "id", "%d",
225: ike_sa->get_unique_id(ike_sa));
226: xmlTextWriterWriteFormatElement(writer, "status", "%N",
227: ike_sa_state_lower_names, ike_sa->get_state(ike_sa));
228: xmlTextWriterWriteElement(writer, "role",
229: id->is_initiator(id) ? "initiator" : "responder");
230: xmlTextWriterWriteElement(writer, "peerconfig", ike_sa->get_name(ike_sa));
231:
232: /* <local> */
233: local = ike_sa->get_my_host(ike_sa);
234: xmlTextWriterStartElement(writer, "local");
235: xmlTextWriterWriteFormatElement(writer, "spi", "%.16"PRIx64,
236: be64toh(id->is_initiator(id) ? id->get_initiator_spi(id)
237: : id->get_responder_spi(id)));
238: write_id(writer, "identification", ike_sa->get_my_id(ike_sa));
239: write_address(writer, "address", local);
240: xmlTextWriterWriteFormatElement(writer, "port", "%d",
241: local->get_port(local));
242: if (ike_sa->supports_extension(ike_sa, EXT_NATT))
243: {
244: write_bool(writer, "nat", ike_sa->has_condition(ike_sa, COND_NAT_HERE));
245: }
246: xmlTextWriterEndElement(writer);
247: /* </local> */
248:
249: /* <remote> */
250: remote = ike_sa->get_other_host(ike_sa);
251: xmlTextWriterStartElement(writer, "remote");
252: xmlTextWriterWriteFormatElement(writer, "spi", "%.16"PRIx64,
253: be64toh(id->is_initiator(id) ? id->get_responder_spi(id)
254: : id->get_initiator_spi(id)));
255: write_id(writer, "identification", ike_sa->get_other_id(ike_sa));
256: write_address(writer, "address", remote);
257: xmlTextWriterWriteFormatElement(writer, "port", "%d",
258: remote->get_port(remote));
259: if (ike_sa->supports_extension(ike_sa, EXT_NATT))
260: {
261: write_bool(writer, "nat", ike_sa->has_condition(ike_sa, COND_NAT_THERE));
262: }
263: xmlTextWriterEndElement(writer);
264: /* </remote> */
265:
266: /* <childsalist> */
267: xmlTextWriterStartElement(writer, "childsalist");
268: children = ike_sa->create_child_sa_enumerator(ike_sa);
269: while (children->enumerate(children, (void**)&child_sa))
270: {
271: write_child(writer, child_sa);
272: }
273: children->destroy(children);
274: /* </childsalist> */
275: xmlTextWriterEndElement(writer);
276:
277: /* </ikesa> */
278: xmlTextWriterEndElement(writer);
279: }
280: enumerator->destroy(enumerator);
281:
282: /* </ikesalist> */
283: xmlTextWriterEndElement(writer);
284: }
285:
286: /**
287: * process a configlist query request message
288: */
289: static void request_query_config(xmlTextReaderPtr reader, xmlTextWriterPtr writer)
290: {
291: enumerator_t *enumerator;
292: peer_cfg_t *peer_cfg;
293:
294: /* <configlist> */
295: xmlTextWriterStartElement(writer, "configlist");
296:
297: enumerator = charon->backends->create_peer_cfg_enumerator(charon->backends,
298: NULL, NULL, NULL, NULL, IKE_ANY);
299: while (enumerator->enumerate(enumerator, &peer_cfg))
300: {
301: enumerator_t *children;
302: child_cfg_t *child_cfg;
303: ike_cfg_t *ike_cfg;
304: linked_list_t *list;
305:
306: /* <peerconfig> */
307: xmlTextWriterStartElement(writer, "peerconfig");
308: xmlTextWriterWriteElement(writer, "name", peer_cfg->get_name(peer_cfg));
309:
310: /* TODO: write auth_cfgs */
311:
312: /* <ikeconfig> */
313: ike_cfg = peer_cfg->get_ike_cfg(peer_cfg);
314: xmlTextWriterStartElement(writer, "ikeconfig");
315: xmlTextWriterWriteElement(writer, "local",
316: ike_cfg->get_my_addr(ike_cfg));
317: xmlTextWriterWriteElement(writer, "remote",
318: ike_cfg->get_other_addr(ike_cfg));
319: xmlTextWriterEndElement(writer);
320: /* </ikeconfig> */
321:
322: /* <childconfiglist> */
323: xmlTextWriterStartElement(writer, "childconfiglist");
324: children = peer_cfg->create_child_cfg_enumerator(peer_cfg);
325: while (children->enumerate(children, &child_cfg))
326: {
327: /* <childconfig> */
328: xmlTextWriterStartElement(writer, "childconfig");
329: xmlTextWriterWriteElement(writer, "name",
330: child_cfg->get_name(child_cfg));
331: list = child_cfg->get_traffic_selectors(child_cfg, TRUE, NULL,
332: NULL, FALSE);
333: write_networks(writer, "local", list);
334: list->destroy_offset(list, offsetof(traffic_selector_t, destroy));
335: list = child_cfg->get_traffic_selectors(child_cfg, FALSE, NULL,
336: NULL, FALSE);
337: write_networks(writer, "remote", list);
338: list->destroy_offset(list, offsetof(traffic_selector_t, destroy));
339: xmlTextWriterEndElement(writer);
340: /* </childconfig> */
341: }
342: children->destroy(children);
343: /* </childconfiglist> */
344: xmlTextWriterEndElement(writer);
345: /* </peerconfig> */
346: xmlTextWriterEndElement(writer);
347: }
348: enumerator->destroy(enumerator);
349: /* </configlist> */
350: xmlTextWriterEndElement(writer);
351: }
352:
353: /**
354: * callback which logs to a XML writer
355: */
356: static bool xml_callback(xmlTextWriterPtr writer, debug_t group, level_t level,
357: ike_sa_t* ike_sa, char* message)
358: {
359: if (level <= 1)
360: {
361: /* <item> */
362: xmlTextWriterStartElement(writer, "item");
363: xmlTextWriterWriteFormatAttribute(writer, "level", "%d", level);
364: xmlTextWriterWriteFormatAttribute(writer, "source", "%N", debug_names, group);
365: xmlTextWriterWriteFormatAttribute(writer, "thread", "%u", thread_current_id());
366: xmlTextWriterWriteString(writer, message);
367: xmlTextWriterEndElement(writer);
368: /* </item> */
369: }
370: return TRUE;
371: }
372:
373: /**
374: * process a *terminate control request message
375: */
376: static void request_control_terminate(xmlTextReaderPtr reader,
377: xmlTextWriterPtr writer, bool ike)
378: {
379: if (xmlTextReaderRead(reader) &&
380: xmlTextReaderNodeType(reader) == XML_READER_TYPE_TEXT)
381: {
382: const char *str;
383: uint32_t id;
384: status_t status;
385:
386: str = xmlTextReaderConstValue(reader);
387: if (str == NULL)
388: {
389: DBG1(DBG_CFG, "error parsing XML id string");
390: return;
391: }
392: id = atoi(str);
393: if (!id)
394: {
395: enumerator_t *enumerator;
396: ike_sa_t *ike_sa;
397:
398: enumerator = charon->controller->create_ike_sa_enumerator(
399: charon->controller, TRUE);
400: while (enumerator->enumerate(enumerator, &ike_sa))
401: {
402: if (streq(str, ike_sa->get_name(ike_sa)))
403: {
404: ike = TRUE;
405: id = ike_sa->get_unique_id(ike_sa);
406: break;
407: }
408: }
409: enumerator->destroy(enumerator);
410: }
411: if (!id)
412: {
413: DBG1(DBG_CFG, "error parsing XML id string");
414: return;
415: }
416:
417: DBG1(DBG_CFG, "terminating %s_SA %d", ike ? "IKE" : "CHILD", id);
418:
419: /* <log> */
420: xmlTextWriterStartElement(writer, "log");
421: if (ike)
422: {
423: status = charon->controller->terminate_ike(
424: charon->controller, id, FALSE,
425: (controller_cb_t)xml_callback, writer, 0);
426: }
427: else
428: {
429: status = charon->controller->terminate_child(
430: charon->controller, id,
431: (controller_cb_t)xml_callback, writer, 0);
432: }
433: /* </log> */
434: xmlTextWriterEndElement(writer);
435: xmlTextWriterWriteFormatElement(writer, "status", "%d", status);
436: }
437: }
438:
439: /**
440: * process a *initiate control request message
441: */
442: static void request_control_initiate(xmlTextReaderPtr reader,
443: xmlTextWriterPtr writer, bool ike)
444: {
445: if (xmlTextReaderRead(reader) &&
446: xmlTextReaderNodeType(reader) == XML_READER_TYPE_TEXT)
447: {
448: const char *str;
449: status_t status = FAILED;
450: peer_cfg_t *peer;
451: child_cfg_t *child = NULL;
452: enumerator_t *enumerator;
453:
454: str = xmlTextReaderConstValue(reader);
455: if (str == NULL)
456: {
457: DBG1(DBG_CFG, "error parsing XML config name string");
458: return;
459: }
460: DBG1(DBG_CFG, "initiating %s_SA %s", ike ? "IKE" : "CHILD", str);
461:
462: /* <log> */
463: xmlTextWriterStartElement(writer, "log");
464: peer = charon->backends->get_peer_cfg_by_name(charon->backends,
465: (char*)str);
466: if (peer)
467: {
468: enumerator = peer->create_child_cfg_enumerator(peer);
469: if (ike)
470: {
471: if (enumerator->enumerate(enumerator, &child))
472: {
473: child->get_ref(child);
474: }
475: else
476: {
477: child = NULL;
478: }
479: }
480: else
481: {
482: while (enumerator->enumerate(enumerator, &child))
483: {
484: if (streq(child->get_name(child), str))
485: {
486: child->get_ref(child);
487: break;
488: }
489: child = NULL;
490: }
491: }
492: enumerator->destroy(enumerator);
493: if (child)
494: {
495: status = charon->controller->initiate(charon->controller,
496: peer, child, (controller_cb_t)xml_callback,
497: writer, 0, FALSE);
498: }
499: else
500: {
501: peer->destroy(peer);
502: }
503: }
504: /* </log> */
505: xmlTextWriterEndElement(writer);
506: xmlTextWriterWriteFormatElement(writer, "status", "%d", status);
507: }
508: }
509:
510: /**
511: * process a query request
512: */
513: static void request_query(xmlTextReaderPtr reader, xmlTextWriterPtr writer)
514: {
515: /* <query> */
516: xmlTextWriterStartElement(writer, "query");
517: while (xmlTextReaderRead(reader))
518: {
519: if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT)
520: {
521: if (streq(xmlTextReaderConstName(reader), "ikesalist"))
522: {
523: request_query_ikesa(reader, writer);
524: break;
525: }
526: if (streq(xmlTextReaderConstName(reader), "configlist"))
527: {
528: request_query_config(reader, writer);
529: break;
530: }
531: }
532: }
533: /* </query> */
534: xmlTextWriterEndElement(writer);
535: }
536:
537: /**
538: * process a control request
539: */
540: static void request_control(xmlTextReaderPtr reader, xmlTextWriterPtr writer)
541: {
542: /* <control> */
543: xmlTextWriterStartElement(writer, "control");
544: while (xmlTextReaderRead(reader))
545: {
546: if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT)
547: {
548: if (streq(xmlTextReaderConstName(reader), "ikesaterminate"))
549: {
550: request_control_terminate(reader, writer, TRUE);
551: break;
552: }
553: if (streq(xmlTextReaderConstName(reader), "childsaterminate"))
554: {
555: request_control_terminate(reader, writer, FALSE);
556: break;
557: }
558: if (streq(xmlTextReaderConstName(reader), "ikesainitiate"))
559: {
560: request_control_initiate(reader, writer, TRUE);
561: break;
562: }
563: if (streq(xmlTextReaderConstName(reader), "childsainitiate"))
564: {
565: request_control_initiate(reader, writer, FALSE);
566: break;
567: }
568: }
569: }
570: /* </control> */
571: xmlTextWriterEndElement(writer);
572: }
573:
574: /**
575: * process a request message
576: */
577: static void request(xmlTextReaderPtr reader, char *id, int fd)
578: {
579: xmlTextWriterPtr writer;
580:
581: writer = xmlNewTextWriter(xmlOutputBufferCreateFd(fd, NULL));
582: if (writer == NULL)
583: {
584: DBG1(DBG_CFG, "opening SMP XML writer failed");
585: return;
586: }
587:
588: xmlTextWriterStartDocument(writer, NULL, NULL, NULL);
589: /* <message xmlns="http://www.strongswan.org/smp/1.0"
590: id="id" type="response"> */
591: xmlTextWriterStartElement(writer, "message");
592: xmlTextWriterWriteAttribute(writer, "xmlns",
593: "http://www.strongswan.org/smp/1.0");
594: xmlTextWriterWriteAttribute(writer, "id", id);
595: xmlTextWriterWriteAttribute(writer, "type", "response");
596:
597: while (xmlTextReaderRead(reader))
598: {
599: if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT)
600: {
601: if (streq(xmlTextReaderConstName(reader), "query"))
602: {
603: request_query(reader, writer);
604: break;
605: }
606: if (streq(xmlTextReaderConstName(reader), "control"))
607: {
608: request_control(reader, writer);
609: break;
610: }
611: }
612: }
613: /* </message> and close document */
614: xmlTextWriterEndDocument(writer);
615: xmlFreeTextWriter(writer);
616: }
617:
618: /**
619: * cleanup helper function for open file descriptors
620: */
621: static void closefdp(int *fd)
622: {
623: close(*fd);
624: }
625:
626: /**
627: * read from a opened connection and process it
628: */
629: static job_requeue_t process(int *fdp)
630: {
631: int fd = *fdp;
632: bool oldstate;
633: char buffer[4096];
634: ssize_t len;
635: xmlTextReaderPtr reader;
636: char *id = NULL, *type = NULL;
637:
638: thread_cleanup_push((thread_cleanup_t)closefdp, (void*)&fd);
639: oldstate = thread_cancelability(TRUE);
640: len = read(fd, buffer, sizeof(buffer));
641: thread_cancelability(oldstate);
642: thread_cleanup_pop(FALSE);
643: if (len <= 0)
644: {
645: close(fd);
646: DBG2(DBG_CFG, "SMP XML connection closed");
647: return JOB_REQUEUE_NONE;
648: }
649: DBG3(DBG_CFG, "got XML request: %b", buffer, (u_int)len);
650:
651: reader = xmlReaderForMemory(buffer, len, NULL, NULL, 0);
652: if (reader == NULL)
653: {
654: DBG1(DBG_CFG, "opening SMP XML reader failed");
655: return JOB_REQUEUE_FAIR;;
656: }
657:
658: /* read message type and id */
659: while (xmlTextReaderRead(reader))
660: {
661: if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_ELEMENT &&
662: streq(xmlTextReaderConstName(reader), "message"))
663: {
664: id = xmlTextReaderGetAttribute(reader, "id");
665: type = xmlTextReaderGetAttribute(reader, "type");
666: break;
667: }
668: }
669:
670: /* process message */
671: if (id && type)
672: {
673: if (streq(type, "request"))
674: {
675: request(reader, id, fd);
676: }
677: else
678: {
679: /* response(reader, id) */
680: }
681: }
682: xmlFreeTextReader(reader);
683: return JOB_REQUEUE_FAIR;;
684: }
685:
686: /**
687: * accept from XML socket and create jobs to process connections
688: */
689: static job_requeue_t dispatch(private_smp_t *this)
690: {
691: struct sockaddr_un strokeaddr;
692: int fd, *fdp, strokeaddrlen = sizeof(strokeaddr);
693: callback_job_t *job;
694: bool oldstate;
695:
696: /* wait for connections, but allow thread to terminate */
697: oldstate = thread_cancelability(TRUE);
698: fd = accept(this->socket, (struct sockaddr *)&strokeaddr, &strokeaddrlen);
699: thread_cancelability(oldstate);
700:
701: if (fd < 0)
702: {
703: DBG1(DBG_CFG, "accepting SMP XML socket failed: %s", strerror(errno));
704: sleep(1);
705: return JOB_REQUEUE_FAIR;;
706: }
707:
708: fdp = malloc_thing(int);
709: *fdp = fd;
710: job = callback_job_create((callback_job_cb_t)process, fdp, free,
711: (callback_job_cancel_t)return_false);
712: lib->processor->queue_job(lib->processor, (job_t*)job);
713:
714: return JOB_REQUEUE_DIRECT;
715: }
716:
717: METHOD(plugin_t, get_name, char*,
718: private_smp_t *this)
719: {
720: return "smp";
721: }
722:
723: METHOD(plugin_t, get_features, int,
724: private_smp_t *this, plugin_feature_t *features[])
725: {
726: static plugin_feature_t f[] = {
727: PLUGIN_NOOP,
728: PLUGIN_PROVIDE(CUSTOM, "smp"),
729: };
730: *features = f;
731: return countof(f);
732: }
733:
734: METHOD(plugin_t, destroy, void,
735: private_smp_t *this)
736: {
737: close(this->socket);
738: free(this);
739: }
740:
741: /*
742: * Described in header file
743: */
744: plugin_t *smp_plugin_create()
745: {
746: struct sockaddr_un unix_addr;
747: private_smp_t *this;
748: mode_t old;
749:
750: if (!lib->caps->check(lib->caps, CAP_CHOWN))
751: { /* required to chown(2) control socket */
752: DBG1(DBG_CFG, "smp plugin requires CAP_CHOWN capability");
753: return NULL;
754: }
755:
756: INIT(this,
757: .public = {
758: .plugin = {
759: .get_name = _get_name,
760: .get_features = _get_features,
761: .destroy = _destroy,
762: },
763: },
764: );
765:
766: /* set up unix socket */
767: this->socket = socket(AF_UNIX, SOCK_STREAM, 0);
768: if (this->socket == -1)
769: {
770: DBG1(DBG_CFG, "could not create XML socket");
771: free(this);
772: return NULL;
773: }
774:
775: strlcpy(unix_addr.sun_path, IPSEC_PIDDIR "/charon.xml",
776: sizeof(unix_addr.sun_path));
777: unix_addr.sun_len = sizeof(unix_addr);
778: unix_addr.sun_family = PF_LOCAL;
779:
780: unlink(unix_addr.sun_path);
781: old = umask(S_IRWXO);
782: if (bind(this->socket, (struct sockaddr *)&unix_addr, sizeof(unix_addr)) < 0)
783: {
784: DBG1(DBG_CFG, "could not bind XML socket: %s", strerror(errno));
785: close(this->socket);
786: free(this);
787: return NULL;
788: }
789: umask(old);
790: if (chown(unix_addr.sun_path, lib->caps->get_uid(lib->caps),
791: lib->caps->get_gid(lib->caps)) != 0)
792: {
793: DBG1(DBG_CFG, "changing XML socket permissions failed: %s", strerror(errno));
794: }
795:
796: if (listen(this->socket, 5) < 0)
797: {
798: DBG1(DBG_CFG, "could not listen on XML socket: %s", strerror(errno));
799: close(this->socket);
800: free(this);
801: return NULL;
802: }
803:
804: lib->processor->queue_job(lib->processor,
805: (job_t*)callback_job_create_with_prio((callback_job_cb_t)dispatch, this,
806: NULL, (callback_job_cancel_t)return_false, JOB_PRIO_CRITICAL));
807:
808: return &this->public.plugin;
809: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>