Annotation of embedaddon/strongswan/src/starter/starterstroke.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2007-2015 Tobias Brunner
                      3:  * Copyright (C) 2006 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 <unistd.h>
                     18: #include <stdlib.h>
                     19: #include <stdint.h>
                     20: #include <string.h>
                     21: 
                     22: #include <credentials/auth_cfg.h>
                     23: 
                     24: #include <library.h>
                     25: #include <utils/debug.h>
                     26: 
                     27: #include <stroke_msg.h>
                     28: 
                     29: #include "starterstroke.h"
                     30: #include "confread.h"
                     31: #include "files.h"
                     32: 
                     33: #define IPV4_LEN        4
                     34: #define IPV6_LEN       16
                     35: 
                     36: static stroke_msg_t *create_stroke_msg(int type)
                     37: {
                     38:        stroke_msg_t *msg;
                     39: 
                     40:        INIT(msg,
                     41:                .type = type,
                     42:                .length = offsetof(stroke_msg_t, buffer),
                     43:        );
                     44:        return msg;
                     45: }
                     46: 
                     47: #define push_string(msg, field, str) \
                     48:        push_string_impl(msg, offsetof(stroke_msg_t, field), str)
                     49: #define push_string_end(msg, offset, field, str) \
                     50:        push_string_impl(msg, offset + offsetof(stroke_end_t, field), str)
                     51: 
                     52: static void push_string_impl(stroke_msg_t **msg, size_t offset, char *string)
                     53: {
                     54:        size_t cur_len = (*msg)->length, str_len;
                     55: 
                     56:        if (!string)
                     57:        {
                     58:                return;
                     59:        }
                     60:        str_len = strlen(string) + 1;
                     61:        if (cur_len + str_len >= UINT16_MAX)
                     62:        {
                     63:                (*msg)->length = UINT16_MAX;
                     64:                return;
                     65:        }
                     66:        while (cur_len + str_len > sizeof(stroke_msg_t) + (*msg)->buflen)
                     67:        {
                     68:                *msg = realloc(*msg, sizeof(stroke_msg_t) + (*msg)->buflen +
                     69:                                           STROKE_BUF_LEN_INC);
                     70:                (*msg)->buflen += STROKE_BUF_LEN_INC;
                     71:        }
                     72:        (*msg)->length += str_len;
                     73:        strcpy((char*)*msg + cur_len, string);
                     74:        *(char**)((char*)*msg + offset) = (char*)cur_len;
                     75: }
                     76: 
                     77: static int send_stroke_msg(stroke_msg_t *msg)
                     78: {
                     79:        stream_t *stream;
                     80:        char *uri, buffer[64];
                     81:        int count;
                     82: 
                     83:        if (msg->length == UINT16_MAX)
                     84:        {
                     85:                DBG1(DBG_APP, "stroke message exceeds maximum buffer size");
                     86:                free(msg);
                     87:                return -1;
                     88:        }
                     89: 
                     90:        /* starter is not called from commandline, and therefore absolutely silent */
                     91:        msg->output_verbosity = -1;
                     92: 
                     93:        uri = lib->settings->get_str(lib->settings, "%s.plugins.stroke.socket",
                     94:                                                                 "unix://" CHARON_CTL_FILE, daemon_name);
                     95:        stream = lib->streams->connect(lib->streams, uri);
                     96:        if (!stream)
                     97:        {
                     98:                DBG1(DBG_APP, "failed to connect to stroke socket '%s'", uri);
                     99:                free(msg);
                    100:                return -1;
                    101:        }
                    102: 
                    103:        if (!stream->write_all(stream, msg, msg->length))
                    104:        {
                    105:                DBG1(DBG_APP, "sending stroke message failed");
                    106:                stream->destroy(stream);
                    107:                free(msg);
                    108:                return -1;
                    109:        }
                    110:        while ((count = stream->read(stream, buffer, sizeof(buffer)-1, TRUE)) > 0)
                    111:        {
                    112:                buffer[count] = '\0';
                    113:                DBG1(DBG_APP, "%s", buffer);
                    114:        }
                    115:        if (count < 0)
                    116:        {
                    117:                DBG1(DBG_APP, "reading stroke response failed");
                    118:        }
                    119:        stream->destroy(stream);
                    120:        free(msg);
                    121:        return 0;
                    122: }
                    123: 
                    124: static char* connection_name(starter_conn_t *conn)
                    125: {
                    126:         /* if connection name is '%auto', create a new name like conn_xxxxx */
                    127:        static char buf[32];
                    128: 
                    129:        if (streq(conn->name, "%auto"))
                    130:        {
                    131:                sprintf(buf, "conn_%lu", conn->id);
                    132:                return buf;
                    133:        }
                    134:        return conn->name;
                    135: }
                    136: 
                    137: static void add_end(stroke_msg_t **msg, size_t offset, starter_end_t *conn_end)
                    138: {
                    139:        stroke_end_t *msg_end;
                    140: 
                    141:        push_string_end(msg, offset, auth, conn_end->auth);
                    142:        push_string_end(msg, offset, auth2, conn_end->auth2);
                    143:        push_string_end(msg, offset, id, conn_end->id);
                    144:        push_string_end(msg, offset, id2, conn_end->id2);
                    145:        push_string_end(msg, offset, rsakey, conn_end->rsakey);
                    146:        push_string_end(msg, offset, cert, conn_end->cert);
                    147:        push_string_end(msg, offset, cert2, conn_end->cert2);
                    148:        push_string_end(msg, offset, cert_policy, conn_end->cert_policy);
                    149:        push_string_end(msg, offset, ca, conn_end->ca);
                    150:        push_string_end(msg, offset, ca2, conn_end->ca2);
                    151:        push_string_end(msg, offset, groups, conn_end->groups);
                    152:        push_string_end(msg, offset, groups2, conn_end->groups2);
                    153:        push_string_end(msg, offset, updown, conn_end->updown);
                    154:        if (conn_end->host)
                    155:        {
                    156:                push_string_end(msg, offset, address, conn_end->host);
                    157:        }
                    158:        else
                    159:        {
                    160:                push_string_end(msg, offset, address, "%any");
                    161:        }
                    162:        push_string_end(msg, offset, subnets, conn_end->subnet);
                    163:        push_string_end(msg, offset, sourceip, conn_end->sourceip);
                    164:        push_string_end(msg, offset, dns, conn_end->dns);
                    165: 
                    166:        /* we can't assign it earlier as msg might change */
                    167:        msg_end = (stroke_end_t*)((char*)(*msg) + offset);
                    168:        msg_end->ikeport = conn_end->ikeport;
                    169:        msg_end->sendcert = conn_end->sendcert;
                    170:        msg_end->hostaccess = conn_end->hostaccess;
                    171:        msg_end->tohost = !conn_end->subnet;
                    172:        msg_end->allow_any = conn_end->allow_any;
                    173:        msg_end->protocol = conn_end->protocol;
                    174:        msg_end->from_port = conn_end->from_port;
                    175:        msg_end->to_port = conn_end->to_port;
                    176: }
                    177: 
                    178: int starter_stroke_add_conn(starter_config_t *cfg, starter_conn_t *conn)
                    179: {
                    180:        stroke_msg_t *msg;
                    181: 
                    182:        msg = create_stroke_msg(STR_ADD_CONN);
                    183:        msg->add_conn.version = conn->keyexchange;
                    184:        push_string(&msg, add_conn.name, connection_name(conn));
                    185:        push_string(&msg, add_conn.eap_identity, conn->eap_identity);
                    186:        push_string(&msg, add_conn.aaa_identity, conn->aaa_identity);
                    187:        push_string(&msg, add_conn.xauth_identity, conn->xauth_identity);
                    188: 
                    189:        msg->add_conn.mode = conn->mode;
                    190:        msg->add_conn.proxy_mode = conn->proxy_mode;
                    191: 
                    192:        if (!(conn->options & SA_OPTION_DONT_REKEY))
                    193:        {
                    194:                msg->add_conn.rekey.reauth = !(conn->options & SA_OPTION_DONT_REAUTH);
                    195:                msg->add_conn.rekey.ipsec_lifetime = conn->sa_ipsec_life_seconds;
                    196:                msg->add_conn.rekey.ike_lifetime = conn->sa_ike_life_seconds;
                    197:                msg->add_conn.rekey.margin = conn->sa_rekey_margin;
                    198:                msg->add_conn.rekey.life_bytes = conn->sa_ipsec_life_bytes;
                    199:                msg->add_conn.rekey.margin_bytes = conn->sa_ipsec_margin_bytes;
                    200:                msg->add_conn.rekey.life_packets = conn->sa_ipsec_life_packets;
                    201:                msg->add_conn.rekey.margin_packets = conn->sa_ipsec_margin_packets;
                    202:                msg->add_conn.rekey.fuzz = conn->sa_rekey_fuzz;
                    203:        }
                    204:        msg->add_conn.rekey.tries = conn->sa_keying_tries;
                    205: 
                    206:        msg->add_conn.mobike = conn->options & SA_OPTION_MOBIKE;
                    207:        msg->add_conn.force_encap = conn->options & SA_OPTION_FORCE_ENCAP;
                    208:        msg->add_conn.fragmentation = conn->fragmentation;
                    209:        msg->add_conn.ikedscp = conn->ikedscp;
                    210:        msg->add_conn.ipcomp = conn->options & SA_OPTION_COMPRESS;
                    211:        msg->add_conn.install_policy = conn->install_policy;
                    212:        msg->add_conn.aggressive = conn->aggressive;
                    213:        msg->add_conn.pushmode = conn->options & SA_OPTION_MODECFG_PUSH;
                    214:        msg->add_conn.crl_policy = (crl_policy_t)cfg->setup.strictcrlpolicy;
                    215:        msg->add_conn.unique = cfg->setup.uniqueids;
                    216:        push_string(&msg, add_conn.algorithms.ike, conn->ike);
                    217:        push_string(&msg, add_conn.algorithms.esp, conn->esp);
                    218:        push_string(&msg, add_conn.algorithms.ah, conn->ah);
                    219:        msg->add_conn.dpd.delay = conn->dpd_delay;
                    220:        msg->add_conn.dpd.timeout = conn->dpd_timeout;
                    221:        msg->add_conn.dpd.action = conn->dpd_action;
                    222:        msg->add_conn.close_action = conn->close_action;
                    223:        msg->add_conn.sha256_96 = conn->sha256_96;
                    224:        msg->add_conn.inactivity = conn->inactivity;
                    225:        msg->add_conn.ikeme.mediation = conn->me_mediation;
                    226:        push_string(&msg, add_conn.ikeme.mediated_by, conn->me_mediated_by);
                    227:        push_string(&msg, add_conn.ikeme.peerid, conn->me_peerid);
                    228:        msg->add_conn.reqid = conn->reqid;
                    229:        msg->add_conn.replay_window = conn->replay_window;
                    230:        msg->add_conn.mark_in.value = conn->mark_in.value;
                    231:        msg->add_conn.mark_in.mask = conn->mark_in.mask;
                    232:        msg->add_conn.mark_out.value = conn->mark_out.value;
                    233:        msg->add_conn.mark_out.mask = conn->mark_out.mask;
                    234:        msg->add_conn.tfc = conn->tfc;
                    235: 
                    236:        add_end(&msg, offsetof(stroke_msg_t, add_conn.me), &conn->left);
                    237:        add_end(&msg, offsetof(stroke_msg_t, add_conn.other), &conn->right);
                    238: 
                    239:        if (!msg->add_conn.me.auth && !msg->add_conn.other.auth &&
                    240:                 conn->authby)
                    241:        {       /* leftauth/rightauth not set, use legacy options */
                    242:                if (streq(conn->authby, "rsa")   || streq(conn->authby, "rsasig")   ||
                    243:                        streq(conn->authby, "ecdsa") || streq(conn->authby, "ecdsasig") ||
                    244:                        streq(conn->authby, "pubkey"))
                    245:                {
                    246:                        push_string(&msg, add_conn.me.auth, "pubkey");
                    247:                        push_string(&msg, add_conn.other.auth, "pubkey");
                    248:                }
                    249:                else if (streq(conn->authby, "secret") || streq(conn->authby, "psk"))
                    250:                {
                    251:                        push_string(&msg, add_conn.me.auth, "psk");
                    252:                        push_string(&msg, add_conn.other.auth, "psk");
                    253:                }
                    254:                else if (streq(conn->authby, "xauthrsasig"))
                    255:                {
                    256:                        push_string(&msg, add_conn.me.auth, "pubkey");
                    257:                        push_string(&msg, add_conn.other.auth, "pubkey");
                    258:                        if (conn->options & SA_OPTION_XAUTH_SERVER)
                    259:                        {
                    260:                                push_string(&msg, add_conn.other.auth2, "xauth");
                    261:                        }
                    262:                        else
                    263:                        {
                    264:                                push_string(&msg, add_conn.me.auth2, "xauth");
                    265:                        }
                    266:                }
                    267:                else if (streq(conn->authby, "xauthpsk"))
                    268:                {
                    269:                        push_string(&msg, add_conn.me.auth, "psk");
                    270:                        push_string(&msg, add_conn.other.auth, "psk");
                    271:                        if (conn->options & SA_OPTION_XAUTH_SERVER)
                    272:                        {
                    273:                                push_string(&msg, add_conn.other.auth2, "xauth");
                    274:                        }
                    275:                        else
                    276:                        {
                    277:                                push_string(&msg, add_conn.me.auth2, "xauth");
                    278:                        }
                    279:                }
                    280:        }
                    281:        return send_stroke_msg(msg);
                    282: }
                    283: 
                    284: int starter_stroke_del_conn(starter_conn_t *conn)
                    285: {
                    286:        stroke_msg_t *msg;
                    287: 
                    288:        msg = create_stroke_msg(STR_DEL_CONN);
                    289:        push_string(&msg, del_conn.name, connection_name(conn));
                    290:        return send_stroke_msg(msg);
                    291: }
                    292: 
                    293: int starter_stroke_route_conn(starter_conn_t *conn)
                    294: {
                    295:        stroke_msg_t *msg;
                    296: 
                    297:        msg = create_stroke_msg(STR_ROUTE);
                    298:        push_string(&msg, route.name, connection_name(conn));
                    299:        return send_stroke_msg(msg);
                    300: }
                    301: 
                    302: int starter_stroke_unroute_conn(starter_conn_t *conn)
                    303: {
                    304:        stroke_msg_t *msg;
                    305: 
                    306:        msg = create_stroke_msg(STR_UNROUTE);
                    307:        push_string(&msg, route.name, connection_name(conn));
                    308:        return send_stroke_msg(msg);
                    309: }
                    310: 
                    311: int starter_stroke_initiate_conn(starter_conn_t *conn)
                    312: {
                    313:        stroke_msg_t *msg;
                    314: 
                    315:        msg = create_stroke_msg(STR_INITIATE);
                    316:        push_string(&msg, initiate.name, connection_name(conn));
                    317:        return send_stroke_msg(msg);
                    318: }
                    319: 
                    320: int starter_stroke_add_ca(starter_ca_t *ca)
                    321: {
                    322:        stroke_msg_t *msg;
                    323: 
                    324:        msg = create_stroke_msg(STR_ADD_CA);
                    325:        push_string(&msg, add_ca.name, ca->name);
                    326:        push_string(&msg, add_ca.cacert, ca->cacert);
                    327:        push_string(&msg, add_ca.crluri, ca->crluri);
                    328:        push_string(&msg, add_ca.crluri2, ca->crluri2);
                    329:        push_string(&msg, add_ca.ocspuri, ca->ocspuri);
                    330:        push_string(&msg, add_ca.ocspuri2, ca->ocspuri2);
                    331:        push_string(&msg, add_ca.certuribase, ca->certuribase);
                    332:        return send_stroke_msg(msg);
                    333: }
                    334: 
                    335: int starter_stroke_del_ca(starter_ca_t *ca)
                    336: {
                    337:        stroke_msg_t *msg;
                    338: 
                    339:        msg = create_stroke_msg(STR_DEL_CA);
                    340:        push_string(&msg, del_ca.name, ca->name);
                    341:        return send_stroke_msg(msg);
                    342: }
                    343: 
                    344: int starter_stroke_configure(starter_config_t *cfg)
                    345: {
                    346:        stroke_msg_t *msg;
                    347: 
                    348:        if (cfg->setup.cachecrls)
                    349:        {
                    350:                msg = create_stroke_msg(STR_CONFIG);
                    351:                msg->config.cachecrl = 1;
                    352:                return send_stroke_msg(msg);
                    353:        }
                    354:        return 0;
                    355: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>