Annotation of embedaddon/strongswan/src/libcharon/plugins/stroke/stroke_socket.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Copyright (C) 2011-2013 Tobias Brunner
3: * Copyright (C) 2008 Martin Willi
4: * HSR Hochschule fuer Technik Rapperswil
5: *
6: * This program is free software; you can redistribute it and/or modify it
7: * under the terms of the GNU General Public License as published by the
8: * Free Software Foundation; either version 2 of the License, or (at your
9: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
10: *
11: * This program is distributed in the hope that it will be useful, but
12: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14: * for more details.
15: */
16:
17: #include "stroke_socket.h"
18:
19: #include <stdlib.h>
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:
27: #include <daemon.h>
28:
29: #include "stroke_config.h"
30: #include "stroke_control.h"
31: #include "stroke_cred.h"
32: #include "stroke_ca.h"
33: #include "stroke_attribute.h"
34: #include "stroke_handler.h"
35: #include "stroke_list.h"
36: #include "stroke_counter.h"
37:
38: /**
39: * To avoid clogging the thread pool with (blocking) jobs, we limit the number
40: * of concurrently handled stroke commands.
41: */
42: #define MAX_CONCURRENT_DEFAULT 4
43:
44: typedef struct stroke_job_context_t stroke_job_context_t;
45: typedef struct private_stroke_socket_t private_stroke_socket_t;
46:
47: /**
48: * private data of stroke_socket
49: */
50: struct private_stroke_socket_t {
51:
52: /**
53: * public functions
54: */
55: stroke_socket_t public;
56:
57: /**
58: * Service accepting stroke connections
59: */
60: stream_service_t *service;
61:
62: /**
63: * configuration backend
64: */
65: stroke_config_t *config;
66:
67: /**
68: * attribute provider
69: */
70: stroke_attribute_t *attribute;
71:
72: /**
73: * attribute handler (requests only)
74: */
75: stroke_handler_t *handler;
76:
77: /**
78: * controller to control daemon
79: */
80: stroke_control_t *control;
81:
82: /**
83: * credential set
84: */
85: stroke_cred_t *cred;
86:
87: /**
88: * CA sections
89: */
90: stroke_ca_t *ca;
91:
92: /**
93: * status information logging
94: */
95: stroke_list_t *list;
96:
97: /**
98: * Counter values for IKE events
99: */
100: stroke_counter_t *counter;
101:
102: /**
103: * TRUE if log level changes are not allowed
104: */
105: bool prevent_loglevel_changes;
106: };
107:
108: /**
109: * Helper macro to log configuration options, but only if they are defined.
110: */
111: #define DBG_OPT(...) VA_ARGS_DISPATCH(DBG_OPT, __VA_ARGS__)(__VA_ARGS__)
112: #define DBG_OPT2(fmt, val) ({ \
113: typeof(val) _val = val; \
114: if (_val) { DBG2(DBG_CFG, fmt, _val); } \
115: })
116: #define DBG_OPT3(fmt, label, val) ({ \
117: typeof(val) _val = val; \
118: if (_val) { DBG2(DBG_CFG, fmt, label, _val); } \
119: })
120:
121: /**
122: * Helper function which corrects the string pointers
123: * in a stroke_msg_t. Strings in a stroke_msg sent over "wire"
124: * contains RELATIVE addresses (relative to the beginning of the
125: * stroke_msg). They must be corrected if they reach our address
126: * space...
127: */
128: static void pop_string(stroke_msg_t *msg, char **string)
129: {
130: if (*string == NULL)
131: {
132: return;
133: }
134:
135: /* check for sanity of string pointer and string */
136: if (string < (char**)msg ||
137: string > (char**)((char*)msg + sizeof(stroke_msg_t)) ||
138: (unsigned long)*string < (unsigned long)((char*)msg->buffer - (char*)msg) ||
139: (unsigned long)*string > msg->length)
140: {
141: *string = "(invalid pointer in stroke msg)";
142: }
143: else
144: {
145: *string = (char*)msg + (unsigned long)*string;
146: }
147: }
148:
149: /**
150: * Pop the strings of a stroke_end_t struct and log them for debugging purposes
151: */
152: static void pop_end(stroke_msg_t *msg, const char* label, stroke_end_t *end)
153: {
154: pop_string(msg, &end->address);
155: pop_string(msg, &end->subnets);
156: pop_string(msg, &end->sourceip);
157: pop_string(msg, &end->dns);
158: pop_string(msg, &end->auth);
159: pop_string(msg, &end->auth2);
160: pop_string(msg, &end->id);
161: pop_string(msg, &end->id2);
162: pop_string(msg, &end->rsakey);
163: pop_string(msg, &end->cert);
164: pop_string(msg, &end->cert2);
165: pop_string(msg, &end->ca);
166: pop_string(msg, &end->ca2);
167: pop_string(msg, &end->groups);
168: pop_string(msg, &end->groups2);
169: pop_string(msg, &end->cert_policy);
170: pop_string(msg, &end->updown);
171:
172: DBG_OPT(" %s=%s", label, end->address);
173: DBG_OPT(" %ssubnet=%s", label, end->subnets);
174: DBG_OPT(" %ssourceip=%s", label, end->sourceip);
175: DBG_OPT(" %sdns=%s", label, end->dns);
176: DBG_OPT(" %sauth=%s", label, end->auth);
177: DBG_OPT(" %sauth2=%s", label, end->auth2);
178: DBG_OPT(" %sid=%s", label, end->id);
179: DBG_OPT(" %sid2=%s", label, end->id2);
180: DBG_OPT(" %srsakey=%s", label, end->rsakey);
181: DBG_OPT(" %scert=%s", label, end->cert);
182: DBG_OPT(" %scert2=%s", label, end->cert2);
183: DBG_OPT(" %sca=%s", label, end->ca);
184: DBG_OPT(" %sca2=%s", label, end->ca2);
185: DBG_OPT(" %sgroups=%s", label, end->groups);
186: DBG_OPT(" %sgroups2=%s", label, end->groups2);
187: DBG_OPT(" %supdown=%s", label, end->updown);
188: }
189:
190: /**
191: * Add a connection to the configuration list
192: */
193: static void stroke_add_conn(private_stroke_socket_t *this, stroke_msg_t *msg)
194: {
195: pop_string(msg, &msg->add_conn.name);
196: DBG1(DBG_CFG, "received stroke: add connection '%s'", msg->add_conn.name);
197:
198: DBG2(DBG_CFG, "conn %s", msg->add_conn.name);
199: pop_end(msg, "left", &msg->add_conn.me);
200: pop_end(msg, "right", &msg->add_conn.other);
201: pop_string(msg, &msg->add_conn.eap_identity);
202: pop_string(msg, &msg->add_conn.aaa_identity);
203: pop_string(msg, &msg->add_conn.xauth_identity);
204: pop_string(msg, &msg->add_conn.algorithms.ike);
205: pop_string(msg, &msg->add_conn.algorithms.esp);
206: pop_string(msg, &msg->add_conn.algorithms.ah);
207: pop_string(msg, &msg->add_conn.ikeme.mediated_by);
208: pop_string(msg, &msg->add_conn.ikeme.peerid);
209: DBG_OPT(" eap_identity=%s", msg->add_conn.eap_identity);
210: DBG_OPT(" aaa_identity=%s", msg->add_conn.aaa_identity);
211: DBG_OPT(" xauth_identity=%s", msg->add_conn.xauth_identity);
212: DBG_OPT(" ike=%s", msg->add_conn.algorithms.ike);
213: DBG_OPT(" esp=%s", msg->add_conn.algorithms.esp);
214: DBG_OPT(" ah=%s", msg->add_conn.algorithms.ah);
215: DBG_OPT(" dpddelay=%d", msg->add_conn.dpd.delay);
216: DBG_OPT(" dpdtimeout=%d", msg->add_conn.dpd.timeout);
217: DBG_OPT(" dpdaction=%d", msg->add_conn.dpd.action);
218: DBG_OPT(" closeaction=%d", msg->add_conn.close_action);
219: DBG_OPT(" sha256_96=%s", msg->add_conn.sha256_96 ? "yes" : "no");
220: DBG_OPT(" mediation=%s", msg->add_conn.ikeme.mediation ? "yes" : "no");
221: DBG_OPT(" mediated_by=%s", msg->add_conn.ikeme.mediated_by);
222: DBG_OPT(" me_peerid=%s", msg->add_conn.ikeme.peerid);
223: DBG_OPT(" keyexchange=ikev%u", msg->add_conn.version);
224:
225: this->config->add(this->config, msg);
226: this->attribute->add_dns(this->attribute, msg);
227: this->handler->add_attributes(this->handler, msg);
228: }
229:
230: /**
231: * Delete a connection from the list
232: */
233: static void stroke_del_conn(private_stroke_socket_t *this, stroke_msg_t *msg)
234: {
235: pop_string(msg, &msg->del_conn.name);
236: DBG1(DBG_CFG, "received stroke: delete connection '%s'", msg->del_conn.name);
237:
238: this->config->del(this->config, msg);
239: this->attribute->del_dns(this->attribute, msg);
240: this->handler->del_attributes(this->handler, msg);
241: }
242:
243: /**
244: * initiate a connection by name
245: */
246: static void stroke_initiate(private_stroke_socket_t *this, stroke_msg_t *msg, FILE *out)
247: {
248: pop_string(msg, &msg->initiate.name);
249: DBG1(DBG_CFG, "received stroke: initiate '%s'", msg->initiate.name);
250:
251: this->control->initiate(this->control, msg, out);
252: }
253:
254: /**
255: * terminate a connection by name
256: */
257: static void stroke_terminate(private_stroke_socket_t *this, stroke_msg_t *msg, FILE *out)
258: {
259: pop_string(msg, &msg->terminate.name);
260: DBG1(DBG_CFG, "received stroke: terminate '%s'", msg->terminate.name);
261:
262: this->control->terminate(this->control, msg, out);
263: }
264:
265: /**
266: * terminate a connection by peers virtual IP
267: */
268: static void stroke_terminate_srcip(private_stroke_socket_t *this,
269: stroke_msg_t *msg, FILE *out)
270: {
271: pop_string(msg, &msg->terminate_srcip.start);
272: pop_string(msg, &msg->terminate_srcip.end);
273: DBG1(DBG_CFG, "received stroke: terminate-srcip %s-%s",
274: msg->terminate_srcip.start, msg->terminate_srcip.end);
275:
276: this->control->terminate_srcip(this->control, msg, out);
277: }
278:
279: /**
280: * rekey a connection by name/id
281: */
282: static void stroke_rekey(private_stroke_socket_t *this, stroke_msg_t *msg, FILE *out)
283: {
284: pop_string(msg, &msg->terminate.name);
285: DBG1(DBG_CFG, "received stroke: rekey '%s'", msg->rekey.name);
286:
287: this->control->rekey(this->control, msg, out);
288: }
289:
290: /**
291: * route a policy (install SPD entries)
292: */
293: static void stroke_route(private_stroke_socket_t *this, stroke_msg_t *msg, FILE *out)
294: {
295: pop_string(msg, &msg->route.name);
296: DBG1(DBG_CFG, "received stroke: route '%s'", msg->route.name);
297:
298: this->control->route(this->control, msg, out);
299: }
300:
301: /**
302: * unroute a policy
303: */
304: static void stroke_unroute(private_stroke_socket_t *this, stroke_msg_t *msg, FILE *out)
305: {
306: pop_string(msg, &msg->terminate.name);
307: DBG1(DBG_CFG, "received stroke: unroute '%s'", msg->route.name);
308:
309: this->control->unroute(this->control, msg, out);
310: }
311:
312: /**
313: * Add a ca information record to the cainfo list
314: */
315: static void stroke_add_ca(private_stroke_socket_t *this,
316: stroke_msg_t *msg, FILE *out)
317: {
318: pop_string(msg, &msg->add_ca.name);
319: DBG1(DBG_CFG, "received stroke: add ca '%s'", msg->add_ca.name);
320:
321: pop_string(msg, &msg->add_ca.cacert);
322: pop_string(msg, &msg->add_ca.crluri);
323: pop_string(msg, &msg->add_ca.crluri2);
324: pop_string(msg, &msg->add_ca.ocspuri);
325: pop_string(msg, &msg->add_ca.ocspuri2);
326: pop_string(msg, &msg->add_ca.certuribase);
327: DBG2(DBG_CFG, "ca %s", msg->add_ca.name);
328: DBG_OPT(" cacert=%s", msg->add_ca.cacert);
329: DBG_OPT(" crluri=%s", msg->add_ca.crluri);
330: DBG_OPT(" crluri2=%s", msg->add_ca.crluri2);
331: DBG_OPT(" ocspuri=%s", msg->add_ca.ocspuri);
332: DBG_OPT(" ocspuri2=%s", msg->add_ca.ocspuri2);
333: DBG_OPT(" certuribase=%s", msg->add_ca.certuribase);
334:
335: this->ca->add(this->ca, msg);
336: }
337:
338: /**
339: * Delete a ca information record from the cainfo list
340: */
341: static void stroke_del_ca(private_stroke_socket_t *this,
342: stroke_msg_t *msg, FILE *out)
343: {
344: pop_string(msg, &msg->del_ca.name);
345: DBG1(DBG_CFG, "received stroke: delete ca '%s'", msg->del_ca.name);
346:
347: this->ca->del(this->ca, msg);
348: }
349:
350:
351: /**
352: * show status of daemon
353: */
354: static void stroke_status(private_stroke_socket_t *this,
355: stroke_msg_t *msg, FILE *out, bool all, bool wait)
356: {
357: pop_string(msg, &(msg->status.name));
358:
359: this->list->status(this->list, msg, out, all, wait);
360: }
361:
362: /**
363: * list various information
364: */
365: static void stroke_list(private_stroke_socket_t *this, stroke_msg_t *msg,
366: FILE *out)
367: {
368: if (msg->list.flags & LIST_CAINFOS)
369: {
370: this->ca->list(this->ca, msg, out);
371: }
372: this->list->list(this->list, msg, out);
373: }
374:
375: /**
376: * reread various information
377: */
378: static void stroke_reread(private_stroke_socket_t *this,
379: stroke_msg_t *msg, FILE *out)
380: {
381: this->cred->reread(this->cred, msg, out);
382: }
383:
384: /**
385: * purge various information
386: */
387: static void stroke_purge(private_stroke_socket_t *this,
388: stroke_msg_t *msg, FILE *out)
389: {
390: if (msg->purge.flags & PURGE_OCSP)
391: {
392: lib->credmgr->flush_cache(lib->credmgr, CERT_X509_OCSP_RESPONSE);
393: }
394: if (msg->purge.flags & PURGE_CRLS)
395: {
396: lib->credmgr->flush_cache(lib->credmgr, CERT_X509_CRL);
397: }
398: if (msg->purge.flags & PURGE_CERTS)
399: {
400: lib->credmgr->flush_cache(lib->credmgr, CERT_X509);
401: }
402: if (msg->purge.flags & PURGE_IKE)
403: {
404: this->control->purge_ike(this->control, msg, out);
405: }
406: }
407:
408: /**
409: * Print a certificate in PEM to out
410: */
411: static void print_pem_cert(FILE *out, certificate_t *cert)
412: {
413: chunk_t encoded;
414:
415: if (cert->get_encoding(cert, CERT_PEM, &encoded))
416: {
417: fprintf(out, "%.*s", (int)encoded.len, encoded.ptr);
418: free(encoded.ptr);
419: }
420: }
421:
422: /**
423: * Export in-memory credentials
424: */
425: static void stroke_export(private_stroke_socket_t *this,
426: stroke_msg_t *msg, FILE *out)
427: {
428: pop_string(msg, &msg->export.selector);
429:
430: if (msg->export.flags & EXPORT_X509)
431: {
432: enumerator_t *enumerator;
433: identification_t *id;
434: certificate_t *cert;
435:
436: id = identification_create_from_string(msg->export.selector);
437: enumerator = lib->credmgr->create_cert_enumerator(lib->credmgr,
438: CERT_X509, KEY_ANY, id, FALSE);
439: while (enumerator->enumerate(enumerator, &cert))
440: {
441: print_pem_cert(out, cert);
442: }
443: enumerator->destroy(enumerator);
444: id->destroy(id);
445: }
446:
447: if (msg->export.flags & (EXPORT_CONN_CERT | EXPORT_CONN_CHAIN))
448: {
449: enumerator_t *sas, *auths, *certs;
450: ike_sa_t *ike_sa;
451: auth_cfg_t *auth;
452: certificate_t *cert;
453: auth_rule_t rule;
454:
455: sas = charon->ike_sa_manager->create_enumerator(
456: charon->ike_sa_manager, TRUE);
457: while (sas->enumerate(sas, &ike_sa))
458: {
459: if (streq(msg->export.selector, ike_sa->get_name(ike_sa)))
460: {
461: auths = ike_sa->create_auth_cfg_enumerator(ike_sa, FALSE);
462: while (auths->enumerate(auths, &auth))
463: {
464: bool got_subject = FALSE;
465:
466: certs = auth->create_enumerator(auth);
467: while (certs->enumerate(certs, &rule, &cert))
468: {
469: switch (rule)
470: {
471: case AUTH_RULE_CA_CERT:
472: case AUTH_RULE_IM_CERT:
473: if (msg->export.flags & EXPORT_CONN_CHAIN)
474: {
475: print_pem_cert(out, cert);
476: }
477: break;
478: case AUTH_RULE_SUBJECT_CERT:
479: if (!got_subject)
480: {
481: print_pem_cert(out, cert);
482: got_subject = TRUE;
483: }
484: break;
485: default:
486: break;
487: }
488: }
489: certs->destroy(certs);
490: }
491: auths->destroy(auths);
492: }
493: }
494: sas->destroy(sas);
495: }
496: }
497:
498: /**
499: * list pool leases
500: */
501: static void stroke_leases(private_stroke_socket_t *this,
502: stroke_msg_t *msg, FILE *out)
503: {
504: pop_string(msg, &msg->leases.pool);
505: pop_string(msg, &msg->leases.address);
506:
507: this->list->leases(this->list, msg, out);
508: }
509:
510: /**
511: * Callback function for usage report
512: */
513: static void report_usage(FILE *out, int count, size_t bytes,
514: backtrace_t *bt, bool detailed)
515: {
516: fprintf(out, "%zu bytes total, %d allocations, %zu bytes average:\n",
517: bytes, count, bytes / count);
518: bt->log(bt, out, detailed);
519: }
520:
521: /**
522: * Callback function for memusage summary
523: */
524: static void sum_usage(FILE *out, int count, size_t bytes, int whitelisted)
525: {
526: fprintf(out, "Total memory usage: %zu\n", bytes);
527: }
528:
529: /**
530: * Show memory usage
531: */
532: static void stroke_memusage(private_stroke_socket_t *this,
533: stroke_msg_t *msg, FILE *out)
534: {
535: if (lib->leak_detective)
536: {
537: lib->leak_detective->usage(lib->leak_detective,
538: (leak_detective_report_cb_t)report_usage,
539: (leak_detective_summary_cb_t)sum_usage, out);
540: }
541: }
542:
543: /**
544: * Set username and password for a connection
545: */
546: static void stroke_user_creds(private_stroke_socket_t *this,
547: stroke_msg_t *msg, FILE *out)
548: {
549: pop_string(msg, &msg->user_creds.name);
550: pop_string(msg, &msg->user_creds.username);
551: pop_string(msg, &msg->user_creds.password);
552:
553: DBG1(DBG_CFG, "received stroke: user-creds '%s'", msg->user_creds.name);
554:
555: this->config->set_user_credentials(this->config, msg, out);
556: }
557:
558: /**
559: * Print stroke counter values
560: */
561: static void stroke_counters(private_stroke_socket_t *this,
562: stroke_msg_t *msg, FILE *out)
563: {
564: pop_string(msg, &msg->counters.name);
565:
566: if (msg->counters.reset)
567: {
568: this->counter->reset(this->counter, msg->counters.name);
569: }
570: else
571: {
572: this->counter->print(this->counter, out, msg->counters.name);
573: }
574: }
575:
576: /**
577: * set the verbosity debug output
578: */
579: static void stroke_loglevel(private_stroke_socket_t *this,
580: stroke_msg_t *msg, FILE *out)
581: {
582: debug_t group;
583:
584: pop_string(msg, &(msg->loglevel.type));
585: DBG1(DBG_CFG, "received stroke: loglevel %d for %s",
586: msg->loglevel.level, msg->loglevel.type);
587:
588: if (this->prevent_loglevel_changes)
589: {
590: DBG1(DBG_CFG, "prevented log level change");
591: fprintf(out, "command not allowed!\n");
592: return;
593: }
594: if (!enum_from_name(debug_names, msg->loglevel.type, &group))
595: {
596: fprintf(out, "unknown type '%s'!\n", msg->loglevel.type);
597: return;
598: }
599: charon->set_level(charon, group, msg->loglevel.level);
600: }
601:
602: /**
603: * set various config options
604: */
605: static void stroke_config(private_stroke_socket_t *this,
606: stroke_msg_t *msg, FILE *out)
607: {
608: this->cred->cachecrl(this->cred, msg->config.cachecrl);
609: }
610:
611: /**
612: * process a stroke request
613: */
614: static bool on_accept(private_stroke_socket_t *this, stream_t *stream)
615: {
616: stroke_msg_t *msg;
617: uint16_t len;
618: FILE *out;
619:
620: /* read length */
621: if (!stream->read_all(stream, &len, sizeof(len)))
622: {
623: if (errno != EWOULDBLOCK)
624: {
625: DBG1(DBG_CFG, "reading length of stroke message failed: %s",
626: strerror(errno));
627: }
628: return FALSE;
629: }
630: if (len < offsetof(stroke_msg_t, buffer))
631: {
632: DBG1(DBG_CFG, "invalid stroke message length %d", len);
633: return FALSE;
634: }
635:
636: /* read message (we need an additional byte to terminate the buffer) */
637: msg = malloc(len + 1);
638: msg->length = len;
639: if (!stream->read_all(stream, (char*)msg + sizeof(len), len - sizeof(len)))
640: {
641: if (errno != EWOULDBLOCK)
642: {
643: DBG1(DBG_CFG, "reading stroke message failed: %s", strerror(errno));
644: }
645: free(msg);
646: return FALSE;
647: }
648: /* make sure even incorrectly unterminated strings don't extend over the
649: * message boundaries */
650: ((char*)msg)[len] = '\0';
651:
652: DBG3(DBG_CFG, "stroke message %b", (void*)msg, len);
653:
654: out = stream->get_file(stream);
655: if (!out)
656: {
657: DBG1(DBG_CFG, "creating stroke output stream failed");
658: free(msg);
659: return FALSE;
660: }
661: switch (msg->type)
662: {
663: case STR_INITIATE:
664: stroke_initiate(this, msg, out);
665: break;
666: case STR_ROUTE:
667: stroke_route(this, msg, out);
668: break;
669: case STR_UNROUTE:
670: stroke_unroute(this, msg, out);
671: break;
672: case STR_TERMINATE:
673: stroke_terminate(this, msg, out);
674: break;
675: case STR_TERMINATE_SRCIP:
676: stroke_terminate_srcip(this, msg, out);
677: break;
678: case STR_REKEY:
679: stroke_rekey(this, msg, out);
680: break;
681: case STR_STATUS:
682: stroke_status(this, msg, out, FALSE, TRUE);
683: break;
684: case STR_STATUS_ALL:
685: stroke_status(this, msg, out, TRUE, TRUE);
686: break;
687: case STR_STATUS_ALL_NOBLK:
688: stroke_status(this, msg, out, TRUE, FALSE);
689: break;
690: case STR_ADD_CONN:
691: stroke_add_conn(this, msg);
692: break;
693: case STR_DEL_CONN:
694: stroke_del_conn(this, msg);
695: break;
696: case STR_ADD_CA:
697: stroke_add_ca(this, msg, out);
698: break;
699: case STR_DEL_CA:
700: stroke_del_ca(this, msg, out);
701: break;
702: case STR_LOGLEVEL:
703: stroke_loglevel(this, msg, out);
704: break;
705: case STR_CONFIG:
706: stroke_config(this, msg, out);
707: break;
708: case STR_LIST:
709: stroke_list(this, msg, out);
710: break;
711: case STR_REREAD:
712: stroke_reread(this, msg, out);
713: break;
714: case STR_PURGE:
715: stroke_purge(this, msg, out);
716: break;
717: case STR_EXPORT:
718: stroke_export(this, msg, out);
719: break;
720: case STR_LEASES:
721: stroke_leases(this, msg, out);
722: break;
723: case STR_MEMUSAGE:
724: stroke_memusage(this, msg, out);
725: break;
726: case STR_USER_CREDS:
727: stroke_user_creds(this, msg, out);
728: break;
729: case STR_COUNTERS:
730: stroke_counters(this, msg, out);
731: break;
732: default:
733: DBG1(DBG_CFG, "received unknown stroke");
734: break;
735: }
736: free(msg);
737: fclose(out);
738: return FALSE;
739: }
740:
741: METHOD(stroke_socket_t, destroy, void,
742: private_stroke_socket_t *this)
743: {
744: DESTROY_IF(this->service);
745: lib->credmgr->remove_set(lib->credmgr, &this->ca->set);
746: lib->credmgr->remove_set(lib->credmgr, &this->cred->set);
747: charon->backends->remove_backend(charon->backends, &this->config->backend);
748: charon->attributes->remove_provider(charon->attributes,
749: &this->attribute->provider);
750: charon->attributes->remove_handler(charon->attributes,
751: &this->handler->handler);
752: this->cred->destroy(this->cred);
753: this->ca->destroy(this->ca);
754: this->config->destroy(this->config);
755: this->attribute->destroy(this->attribute);
756: this->handler->destroy(this->handler);
757: this->control->destroy(this->control);
758: this->list->destroy(this->list);
759: this->counter->destroy(this->counter);
760: free(this);
761: }
762:
763: /*
764: * see header file
765: */
766: stroke_socket_t *stroke_socket_create()
767: {
768: private_stroke_socket_t *this;
769: int max_concurrent;
770: char *uri;
771:
772: INIT(this,
773: .public = {
774: .destroy = _destroy,
775: },
776: .prevent_loglevel_changes = lib->settings->get_bool(lib->settings,
777: "%s.plugins.stroke.prevent_loglevel_changes", FALSE, lib->ns),
778: );
779:
780: this->ca = stroke_ca_create();
781: this->cred = stroke_cred_create(this->ca);
782: this->attribute = stroke_attribute_create();
783: this->handler = stroke_handler_create();
784: this->config = stroke_config_create(this->ca, this->cred, this->attribute);
785: this->control = stroke_control_create();
786: this->list = stroke_list_create(this->attribute);
787: this->counter = stroke_counter_create();
788:
789: lib->credmgr->add_set(lib->credmgr, &this->ca->set);
790: lib->credmgr->add_set(lib->credmgr, &this->cred->set);
791: charon->backends->add_backend(charon->backends, &this->config->backend);
792: charon->attributes->add_provider(charon->attributes,
793: &this->attribute->provider);
794: charon->attributes->add_handler(charon->attributes,
795: &this->handler->handler);
796:
797:
798: max_concurrent = lib->settings->get_int(lib->settings,
799: "%s.plugins.stroke.max_concurrent", MAX_CONCURRENT_DEFAULT,
800: lib->ns);
801: uri = lib->settings->get_str(lib->settings,
802: "%s.plugins.stroke.socket", "unix://" STROKE_SOCKET, lib->ns);
803: this->service = lib->streams->create_service(lib->streams, uri, 10);
804: if (!this->service)
805: {
806: DBG1(DBG_CFG, "creating stroke socket failed");
807: destroy(this);
808: return NULL;
809: }
810: this->service->on_accept(this->service, (stream_service_cb_t)on_accept,
811: this, JOB_PRIO_CRITICAL, max_concurrent);
812:
813: return &this->public;
814: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>