Annotation of embedaddon/strongswan/src/starter/starterstroke.c, revision 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>