Annotation of embedaddon/ipsec-tools/src/setkey/parse.y, revision 1.1.1.1

1.1       misho       1: /*     $NetBSD: parse.y,v 1.14 2010/12/03 14:32:52 tteras Exp $        */
                      2: 
                      3: /*     $KAME: parse.y,v 1.81 2003/07/01 04:01:48 itojun Exp $  */
                      4: 
                      5: /*
                      6:  * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
                      7:  * All rights reserved.
                      8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  * 2. Redistributions in binary form must reproduce the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer in the
                     16:  *    documentation and/or other materials provided with the distribution.
                     17:  * 3. Neither the name of the project nor the names of its contributors
                     18:  *    may be used to endorse or promote products derived from this software
                     19:  *    without specific prior written permission.
                     20:  *
                     21:  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
                     22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
                     25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     31:  * SUCH DAMAGE.
                     32:  */
                     33: 
                     34: %{
                     35: #ifdef HAVE_CONFIG_H
                     36: #include "config.h"
                     37: #endif
                     38: 
                     39: #include <sys/types.h>
                     40: #include <sys/param.h>
                     41: #include <sys/socket.h>
                     42: 
                     43: #include <netinet/in.h>
                     44: #include <net/pfkeyv2.h>
                     45: #include PATH_IPSEC_H
                     46: #include <arpa/inet.h>
                     47: 
                     48: #include <string.h>
                     49: #include <unistd.h>
                     50: #include <stdio.h>
                     51: #include <netdb.h>
                     52: #include <ctype.h>
                     53: #include <errno.h>
                     54: #include <stdlib.h>
                     55: 
                     56: #include "libpfkey.h"
                     57: #include "vchar.h"
                     58: #include "extern.h"
                     59: 
                     60: #define DEFAULT_NATT_PORT      4500
                     61: 
                     62: #ifndef UDP_ENCAP_ESPINUDP
                     63: #define UDP_ENCAP_ESPINUDP     2
                     64: #endif
                     65: 
                     66: #define ATOX(c) \
                     67:   (isdigit((int)c) ? (c - '0') : \
                     68:     (isupper((int)c) ? (c - 'A' + 10) : (c - 'a' + 10)))
                     69: 
                     70: u_int32_t p_spi;
                     71: u_int p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode;
                     72: u_int32_t p_reqid;
                     73: u_int p_key_enc_len, p_key_auth_len;
                     74: const char *p_key_enc;
                     75: const char *p_key_auth;
                     76: time_t p_lt_hard, p_lt_soft;
                     77: size_t p_lb_hard, p_lb_soft;
                     78: 
                     79: struct security_ctx {
                     80:        u_int8_t doi;
                     81:        u_int8_t alg;
                     82:        u_int16_t len;
                     83:        char *buf;
                     84: };
                     85: 
                     86: struct security_ctx sec_ctx;
                     87: 
                     88: static u_int p_natt_type;
                     89: static struct addrinfo * p_natt_oa = NULL;
                     90: 
                     91: static int p_aiflags = 0, p_aifamily = PF_UNSPEC;
                     92: 
                     93: static struct addrinfo *parse_addr __P((char *, char *));
                     94: static int fix_portstr __P((int, vchar_t *, vchar_t *, vchar_t *));
                     95: static int setvarbuf __P((char *, int *, struct sadb_ext *, int, 
                     96:     const void *, int));
                     97: void parse_init __P((void));
                     98: void free_buffer __P((void));
                     99: 
                    100: int setkeymsg0 __P((struct sadb_msg *, unsigned int, unsigned int, size_t));
                    101: static int setkeymsg_spdaddr __P((unsigned int, unsigned int, vchar_t *,
                    102:        struct addrinfo *, int, struct addrinfo *, int));
                    103: static int setkeymsg_spdaddr_tag __P((unsigned int, char *, vchar_t *));
                    104: static int setkeymsg_addr __P((unsigned int, unsigned int,
                    105:        struct addrinfo *, struct addrinfo *, int));
                    106: static int setkeymsg_add __P((unsigned int, unsigned int,
                    107:        struct addrinfo *, struct addrinfo *));
                    108: %}
                    109: 
                    110: %union {
                    111:        int num;
                    112:        unsigned long ulnum;
                    113:        vchar_t val;
                    114:        struct addrinfo *res;
                    115: }
                    116: 
                    117: %token EOT SLASH BLCL ELCL
                    118: %token ADD GET DELETE DELETEALL FLUSH DUMP EXIT
                    119: %token PR_ESP PR_AH PR_IPCOMP PR_ESPUDP PR_TCP
                    120: %token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI
                    121: %token F_MODE MODE F_REQID
                    122: %token F_EXT EXTENSION NOCYCLICSEQ
                    123: %token ALG_AUTH ALG_AUTH_NOKEY
                    124: %token ALG_ENC ALG_ENC_NOKEY ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD
                    125: %token ALG_COMP
                    126: %token F_LIFETIME_HARD F_LIFETIME_SOFT
                    127: %token F_LIFEBYTE_HARD F_LIFEBYTE_SOFT
                    128: %token DECSTRING QUOTEDSTRING HEXSTRING STRING ANY
                    129:        /* SPD management */
                    130: %token SPDADD SPDUPDATE SPDDELETE SPDDUMP SPDFLUSH
                    131: %token F_POLICY PL_REQUESTS
                    132: %token F_AIFLAGS
                    133: %token TAGGED
                    134: %token SECURITY_CTX
                    135: 
                    136: %type <num> prefix protocol_spec upper_spec
                    137: %type <num> ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD ALG_ENC_NOKEY
                    138: %type <num> ALG_AUTH ALG_AUTH_NOKEY
                    139: %type <num> ALG_COMP
                    140: %type <num> PR_ESP PR_AH PR_IPCOMP PR_ESPUDP PR_TCP
                    141: %type <num> EXTENSION MODE
                    142: %type <ulnum> DECSTRING
                    143: %type <val> PL_REQUESTS portstr key_string
                    144: %type <val> policy_requests
                    145: %type <val> QUOTEDSTRING HEXSTRING STRING
                    146: %type <val> F_AIFLAGS
                    147: %type <val> upper_misc_spec policy_spec
                    148: %type <res> ipaddr ipandport
                    149: 
                    150: %%
                    151: commands
                    152:        :       /*NOTHING*/
                    153:        |       commands command
                    154:                {
                    155:                        free_buffer();
                    156:                        parse_init();
                    157:                }
                    158:        ;
                    159: 
                    160: command
                    161:        :       add_command
                    162:        |       get_command
                    163:        |       delete_command
                    164:        |       deleteall_command
                    165:        |       flush_command
                    166:        |       dump_command
                    167:        |       exit_command
                    168:        |       spdadd_command
                    169:        |       spdupdate_command
                    170:        |       spddelete_command
                    171:        |       spddump_command
                    172:        |       spdflush_command
                    173:        ;
                    174:        /* commands concerned with management, there is in tail of this file. */
                    175: 
                    176:        /* add command */
                    177: add_command
                    178:        :       ADD ipaddropts ipandport ipandport protocol_spec spi extension_spec algorithm_spec EOT
                    179:                {
                    180:                        int status;
                    181: 
                    182:                        status = setkeymsg_add(SADB_ADD, $5, $3, $4);
                    183:                        if (status < 0)
                    184:                                return -1;
                    185:                }
                    186:        ;
                    187: 
                    188:        /* delete */
                    189: delete_command
                    190:        :       DELETE ipaddropts ipandport ipandport protocol_spec spi extension_spec EOT
                    191:                {
                    192:                        int status;
                    193: 
                    194:                        if ($3->ai_next || $4->ai_next) {
                    195:                                yyerror("multiple address specified");
                    196:                                return -1;
                    197:                        }
                    198:                        if (p_mode != IPSEC_MODE_ANY)
                    199:                                yyerror("WARNING: mode is obsolete");
                    200: 
                    201:                        status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 0);
                    202:                        if (status < 0)
                    203:                                return -1;
                    204:                }
                    205:        ;
                    206: 
                    207:        /* deleteall command */
                    208: deleteall_command
                    209:        :       DELETEALL ipaddropts ipaddr ipaddr protocol_spec EOT
                    210:                {
                    211: #ifndef __linux__
                    212:                        if (setkeymsg_addr(SADB_DELETE, $5, $3, $4, 1) < 0)
                    213:                                return -1;
                    214: #else /* __linux__ */
                    215:                        /* linux strictly adheres to RFC2367, and returns
                    216:                         * an error if we send an SADB_DELETE request without
                    217:                         * an SPI. Therefore, we must first retrieve a list
                    218:                         * of SPIs for all matching SADB entries, and then
                    219:                         * delete each one separately. */
                    220:                        u_int32_t *spi;
                    221:                        int i, n;
                    222: 
                    223:                        spi = sendkeymsg_spigrep($5, $3, $4, &n);
                    224:                        for (i = 0; i < n; i++) {
                    225:                                p_spi = spi[i];
                    226:                                if (setkeymsg_addr(SADB_DELETE,
                    227:                                                        $5, $3, $4, 0) < 0)
                    228:                                        return -1;
                    229:                        }
                    230:                        free(spi);
                    231: #endif /* __linux__ */
                    232:                }
                    233:        ;
                    234: 
                    235:        /* get command */
                    236: get_command
                    237:        :       GET ipaddropts ipandport ipandport protocol_spec spi extension_spec EOT
                    238:                {
                    239:                        int status;
                    240: 
                    241:                        if (p_mode != IPSEC_MODE_ANY)
                    242:                                yyerror("WARNING: mode is obsolete");
                    243: 
                    244:                        status = setkeymsg_addr(SADB_GET, $5, $3, $4, 0);
                    245:                        if (status < 0)
                    246:                                return -1;
                    247:                }
                    248:        ;
                    249: 
                    250:        /* flush */
                    251: flush_command
                    252:        :       FLUSH protocol_spec EOT
                    253:                {
                    254:                        struct sadb_msg msg;
                    255:                        setkeymsg0(&msg, SADB_FLUSH, $2, sizeof(msg));
                    256:                        sendkeymsg((char *)&msg, sizeof(msg));
                    257:                }
                    258:        ;
                    259: 
                    260:        /* dump */
                    261: dump_command
                    262:        :       DUMP protocol_spec EOT
                    263:                {
                    264:                        struct sadb_msg msg;
                    265:                        setkeymsg0(&msg, SADB_DUMP, $2, sizeof(msg));
                    266:                        sendkeymsg((char *)&msg, sizeof(msg));
                    267:                }
                    268:        ;
                    269: 
                    270: protocol_spec
                    271:        :       /*NOTHING*/
                    272:                {
                    273:                        $$ = SADB_SATYPE_UNSPEC;
                    274:                }
                    275:        |       PR_ESP
                    276:                {
                    277:                        $$ = SADB_SATYPE_ESP;
                    278:                        if ($1 == 1)
                    279:                                p_ext |= SADB_X_EXT_OLD;
                    280:                        else
                    281:                                p_ext &= ~SADB_X_EXT_OLD;
                    282:                }
                    283:        |       PR_AH
                    284:                {
                    285:                        $$ = SADB_SATYPE_AH;
                    286:                        if ($1 == 1)
                    287:                                p_ext |= SADB_X_EXT_OLD;
                    288:                        else
                    289:                                p_ext &= ~SADB_X_EXT_OLD;
                    290:                }
                    291:        |       PR_IPCOMP
                    292:                {
                    293:                        $$ = SADB_X_SATYPE_IPCOMP;
                    294:                }
                    295:        |       PR_ESPUDP
                    296:                {
                    297:                        $$ = SADB_SATYPE_ESP;
                    298:                        p_ext &= ~SADB_X_EXT_OLD;
                    299:                        p_natt_oa = 0;
                    300:                        p_natt_type = UDP_ENCAP_ESPINUDP;
                    301:                }
                    302:        |       PR_ESPUDP ipaddr
                    303:                {
                    304:                        $$ = SADB_SATYPE_ESP;
                    305:                        p_ext &= ~SADB_X_EXT_OLD;
                    306:                        p_natt_oa = $2;
                    307:                        p_natt_type = UDP_ENCAP_ESPINUDP;
                    308:                }
                    309:        |       PR_TCP
                    310:                {
                    311: #ifdef SADB_X_SATYPE_TCPSIGNATURE
                    312:                        $$ = SADB_X_SATYPE_TCPSIGNATURE;
                    313: #endif
                    314:                }
                    315:        ;
                    316:        
                    317: spi
                    318:        :       DECSTRING { p_spi = $1; }
                    319:        |       HEXSTRING
                    320:                {
                    321:                        char *ep;
                    322:                        unsigned long v;
                    323: 
                    324:                        ep = NULL;
                    325:                        v = strtoul($1.buf, &ep, 16);
                    326:                        if (!ep || *ep) {
                    327:                                yyerror("invalid SPI");
                    328:                                return -1;
                    329:                        }
                    330:                        if (v & ~0xffffffff) {
                    331:                                yyerror("SPI too big.");
                    332:                                return -1;
                    333:                        }
                    334: 
                    335:                        p_spi = v;
                    336:                }
                    337:        ;
                    338: 
                    339: algorithm_spec
                    340:        :       esp_spec
                    341:        |       ah_spec
                    342:        |       ipcomp_spec
                    343:        ;
                    344: 
                    345: esp_spec
                    346:        :       F_ENC enc_alg F_AUTH auth_alg
                    347:        |       F_ENC enc_alg
                    348:        ;
                    349: 
                    350: ah_spec
                    351:        :       F_AUTH auth_alg
                    352:        ;
                    353: 
                    354: ipcomp_spec
                    355:        :       F_COMP ALG_COMP
                    356:                {
                    357:                        if ($2 < 0) {
                    358:                                yyerror("unsupported algorithm");
                    359:                                return -1;
                    360:                        }
                    361:                        p_alg_enc = $2;
                    362:                }
                    363:        |       F_COMP ALG_COMP F_RAWCPI
                    364:                {
                    365:                        if ($2 < 0) {
                    366:                                yyerror("unsupported algorithm");
                    367:                                return -1;
                    368:                        }
                    369:                        p_alg_enc = $2;
                    370:                        p_ext |= SADB_X_EXT_RAWCPI;
                    371:                }
                    372:        ;
                    373: 
                    374: enc_alg
                    375:        :       ALG_ENC_NOKEY {
                    376:                        if ($1 < 0) {
                    377:                                yyerror("unsupported algorithm");
                    378:                                return -1;
                    379:                        }
                    380:                        p_alg_enc = $1;
                    381: 
                    382:                        p_key_enc_len = 0;
                    383:                        p_key_enc = "";
                    384:                        if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
                    385:                            p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
                    386:                                yyerror(ipsec_strerror());
                    387:                                return -1;
                    388:                        }
                    389:                }
                    390:        |       ALG_ENC key_string {
                    391:                        if ($1 < 0) {
                    392:                                yyerror("unsupported algorithm");
                    393:                                return -1;
                    394:                        }
                    395:                        p_alg_enc = $1;
                    396: 
                    397:                        p_key_enc_len = $2.len;
                    398:                        p_key_enc = $2.buf;
                    399:                        if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
                    400:                            p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
                    401:                                yyerror(ipsec_strerror());
                    402:                                return -1;
                    403:                        }
                    404:                }
                    405:        |       ALG_ENC_OLD {
                    406:                        if ($1 < 0) {
                    407:                                yyerror("unsupported algorithm");
                    408:                                return -1;
                    409:                        }
                    410:                        yyerror("WARNING: obsolete algorithm");
                    411:                        p_alg_enc = $1;
                    412: 
                    413:                        p_key_enc_len = 0;
                    414:                        p_key_enc = "";
                    415:                        if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
                    416:                            p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
                    417:                                yyerror(ipsec_strerror());
                    418:                                return -1;
                    419:                        }
                    420:                }
                    421:        |       ALG_ENC_DESDERIV key_string
                    422:                {
                    423:                        if ($1 < 0) {
                    424:                                yyerror("unsupported algorithm");
                    425:                                return -1;
                    426:                        }
                    427:                        p_alg_enc = $1;
                    428:                        if (p_ext & SADB_X_EXT_OLD) {
                    429:                                yyerror("algorithm mismatched");
                    430:                                return -1;
                    431:                        }
                    432:                        p_ext |= SADB_X_EXT_DERIV;
                    433: 
                    434:                        p_key_enc_len = $2.len;
                    435:                        p_key_enc = $2.buf;
                    436:                        if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
                    437:                            p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
                    438:                                yyerror(ipsec_strerror());
                    439:                                return -1;
                    440:                        }
                    441:                }
                    442:        |       ALG_ENC_DES32IV key_string
                    443:                {
                    444:                        if ($1 < 0) {
                    445:                                yyerror("unsupported algorithm");
                    446:                                return -1;
                    447:                        }
                    448:                        p_alg_enc = $1;
                    449:                        if (!(p_ext & SADB_X_EXT_OLD)) {
                    450:                                yyerror("algorithm mismatched");
                    451:                                return -1;
                    452:                        }
                    453:                        p_ext |= SADB_X_EXT_IV4B;
                    454: 
                    455:                        p_key_enc_len = $2.len;
                    456:                        p_key_enc = $2.buf;
                    457:                        if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT,
                    458:                            p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) {
                    459:                                yyerror(ipsec_strerror());
                    460:                                return -1;
                    461:                        }
                    462:                }
                    463:        ;
                    464: 
                    465: auth_alg
                    466:        :       ALG_AUTH key_string {
                    467:                        if ($1 < 0) {
                    468:                                yyerror("unsupported algorithm");
                    469:                                return -1;
                    470:                        }
                    471:                        p_alg_auth = $1;
                    472: 
                    473:                        p_key_auth_len = $2.len;
                    474:                        p_key_auth = $2.buf;
                    475: #ifdef SADB_X_AALG_TCP_MD5
                    476:                        if (p_alg_auth == SADB_X_AALG_TCP_MD5) {
                    477:                                if ((p_key_auth_len < 1) || 
                    478:                                    (p_key_auth_len > 80))
                    479:                                        return -1;
                    480:                        } else 
                    481: #endif
                    482:                        {
                    483:                                if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH,
                    484:                                    p_alg_auth, 
                    485:                                    PFKEY_UNUNIT64(p_key_auth_len)) < 0) {
                    486:                                        yyerror(ipsec_strerror());
                    487:                                        return -1;
                    488:                                }
                    489:                        }
                    490:                }
                    491:        |       ALG_AUTH_NOKEY {
                    492:                        if ($1 < 0) {
                    493:                                yyerror("unsupported algorithm");
                    494:                                return -1;
                    495:                        }
                    496:                        p_alg_auth = $1;
                    497: 
                    498:                        p_key_auth_len = 0;
                    499:                        p_key_auth = NULL;
                    500:                }
                    501:        ;
                    502: 
                    503: key_string
                    504:        :       QUOTEDSTRING
                    505:                {
                    506:                        $$ = $1;
                    507:                }
                    508:        |       HEXSTRING
                    509:                {
                    510:                        caddr_t pp_key;
                    511:                        caddr_t bp;
                    512:                        caddr_t yp = $1.buf;
                    513:                        int l;
                    514: 
                    515:                        l = strlen(yp) % 2 + strlen(yp) / 2;
                    516:                        if ((pp_key = malloc(l)) == 0) {
                    517:                                yyerror("not enough core");
                    518:                                return -1;
                    519:                        }
                    520:                        memset(pp_key, 0, l);
                    521: 
                    522:                        bp = pp_key;
                    523:                        if (strlen(yp) % 2) {
                    524:                                *bp = ATOX(yp[0]);
                    525:                                yp++, bp++;
                    526:                        }
                    527:                        while (*yp) {
                    528:                                *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]);
                    529:                                yp += 2, bp++;
                    530:                        }
                    531: 
                    532:                        $$.len = l;
                    533:                        $$.buf = pp_key;
                    534:                }
                    535:        ;
                    536: 
                    537: extension_spec
                    538:        :       /*NOTHING*/
                    539:        |       extension_spec extension
                    540:        ;
                    541: 
                    542: extension
                    543:        :       F_EXT EXTENSION { p_ext |= $2; }
                    544:        |       F_EXT NOCYCLICSEQ { p_ext &= ~SADB_X_EXT_CYCSEQ; }
                    545:        |       F_MODE MODE { p_mode = $2; }
                    546:        |       F_MODE ANY { p_mode = IPSEC_MODE_ANY; }
                    547:        |       F_REQID DECSTRING { p_reqid = $2; }
                    548:        |       F_REPLAY DECSTRING
                    549:                {
                    550:                        if ((p_ext & SADB_X_EXT_OLD) != 0) {
                    551:                                yyerror("replay prevention cannot be used with "
                    552:                                    "ah/esp-old");
                    553:                                return -1;
                    554:                        }
                    555:                        p_replay = $2;
                    556:                }
                    557:        |       F_LIFETIME_HARD DECSTRING { p_lt_hard = $2; }
                    558:        |       F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; }
                    559:        |       F_LIFEBYTE_HARD DECSTRING { p_lb_hard = $2; }
                    560:        |       F_LIFEBYTE_SOFT DECSTRING { p_lb_soft = $2; }
                    561:        |       SECURITY_CTX DECSTRING DECSTRING QUOTEDSTRING {
                    562:                sec_ctx.doi = $2;
                    563:                sec_ctx.alg = $3;
                    564:                sec_ctx.len = $4.len+1;
                    565:                sec_ctx.buf = $4.buf;
                    566:        }
                    567:        ;
                    568: 
                    569:        /* definition about command for SPD management */
                    570:        /* spdadd */
                    571: spdadd_command
                    572:        /* XXX merge with spdupdate ??? */
                    573:        :       SPDADD ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec context_spec policy_spec EOT
                    574:                {
                    575:                        int status;
                    576:                        struct addrinfo *src, *dst;
                    577: 
                    578: #ifdef HAVE_PFKEY_POLICY_PRIORITY
                    579:                        last_msg_type = SADB_X_SPDADD;
                    580: #endif
                    581: 
                    582:                        /* fixed port fields if ulp is icmp */
                    583:                        if (fix_portstr($9, &$10, &$5, &$8))
                    584:                                return -1;
                    585: 
                    586:                        src = parse_addr($3.buf, $5.buf);
                    587:                        dst = parse_addr($6.buf, $8.buf);
                    588:                        if (!src || !dst) {
                    589:                                /* yyerror is already called */
                    590:                                return -1;
                    591:                        }
                    592:                        if (src->ai_next || dst->ai_next) {
                    593:                                yyerror("multiple address specified");
                    594:                                freeaddrinfo(src);
                    595:                                freeaddrinfo(dst);
                    596:                                return -1;
                    597:                        }
                    598: 
                    599:                        status = setkeymsg_spdaddr(SADB_X_SPDADD, $9, &$12,
                    600:                            src, $4, dst, $7);
                    601:                        freeaddrinfo(src);
                    602:                        freeaddrinfo(dst);
                    603:                        if (status < 0)
                    604:                                return -1;
                    605:                }
                    606:        |       SPDADD TAGGED QUOTEDSTRING policy_spec EOT
                    607:                {
                    608:                        int status;
                    609: 
                    610:                        status = setkeymsg_spdaddr_tag(SADB_X_SPDADD,
                    611:                            $3.buf, &$4);
                    612:                        if (status < 0)
                    613:                                return -1;
                    614:                }
                    615:        ;
                    616: 
                    617: spdupdate_command
                    618:        /* XXX merge with spdadd ??? */
                    619:        :       SPDUPDATE ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec context_spec policy_spec EOT
                    620:                {
                    621:                        int status;
                    622:                        struct addrinfo *src, *dst;
                    623: 
                    624: #ifdef HAVE_PFKEY_POLICY_PRIORITY
                    625:                        last_msg_type = SADB_X_SPDUPDATE;
                    626: #endif
                    627: 
                    628:                        /* fixed port fields if ulp is icmp */
                    629:                        if (fix_portstr($9, &$10, &$5, &$8))
                    630:                                return -1;
                    631: 
                    632:                        src = parse_addr($3.buf, $5.buf);
                    633:                        dst = parse_addr($6.buf, $8.buf);
                    634:                        if (!src || !dst) {
                    635:                                /* yyerror is already called */
                    636:                                return -1;
                    637:                        }
                    638:                        if (src->ai_next || dst->ai_next) {
                    639:                                yyerror("multiple address specified");
                    640:                                freeaddrinfo(src);
                    641:                                freeaddrinfo(dst);
                    642:                                return -1;
                    643:                        }
                    644: 
                    645:                        status = setkeymsg_spdaddr(SADB_X_SPDUPDATE, $9, &$12,
                    646:                            src, $4, dst, $7);
                    647:                        freeaddrinfo(src);
                    648:                        freeaddrinfo(dst);
                    649:                        if (status < 0)
                    650:                                return -1;
                    651:                }
                    652:        |       SPDUPDATE TAGGED QUOTEDSTRING policy_spec EOT
                    653:                {
                    654:                        int status;
                    655: 
                    656:                        status = setkeymsg_spdaddr_tag(SADB_X_SPDUPDATE,
                    657:                            $3.buf, &$4);
                    658:                        if (status < 0)
                    659:                                return -1;
                    660:                }
                    661:        ;
                    662: 
                    663: spddelete_command
                    664:        :       SPDDELETE ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec context_spec policy_spec EOT
                    665:                {
                    666:                        int status;
                    667:                        struct addrinfo *src, *dst;
                    668: 
                    669:                        /* fixed port fields if ulp is icmp */
                    670:                        if (fix_portstr($9, &$10, &$5, &$8))
                    671:                                return -1;
                    672: 
                    673:                        src = parse_addr($3.buf, $5.buf);
                    674:                        dst = parse_addr($6.buf, $8.buf);
                    675:                        if (!src || !dst) {
                    676:                                /* yyerror is already called */
                    677:                                return -1;
                    678:                        }
                    679:                        if (src->ai_next || dst->ai_next) {
                    680:                                yyerror("multiple address specified");
                    681:                                freeaddrinfo(src);
                    682:                                freeaddrinfo(dst);
                    683:                                return -1;
                    684:                        }
                    685: 
                    686:                        status = setkeymsg_spdaddr(SADB_X_SPDDELETE, $9, &$12,
                    687:                            src, $4, dst, $7);
                    688:                        freeaddrinfo(src);
                    689:                        freeaddrinfo(dst);
                    690:                        if (status < 0)
                    691:                                return -1;
                    692:                }
                    693:        ;
                    694: 
                    695: spddump_command:
                    696:                SPDDUMP EOT
                    697:                {
                    698:                        struct sadb_msg msg;
                    699:                        setkeymsg0(&msg, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC,
                    700:                            sizeof(msg));
                    701:                        sendkeymsg((char *)&msg, sizeof(msg));
                    702:                }
                    703:        ;
                    704: 
                    705: spdflush_command
                    706:        :
                    707:                SPDFLUSH EOT
                    708:                {
                    709:                        struct sadb_msg msg;
                    710:                        setkeymsg0(&msg, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC,
                    711:                            sizeof(msg));
                    712:                        sendkeymsg((char *)&msg, sizeof(msg));
                    713:                }
                    714:        ;
                    715: 
                    716: ipaddropts
                    717:        :       /* nothing */
                    718:        |       ipaddropts ipaddropt
                    719:        ;
                    720: 
                    721: ipaddropt
                    722:        :       F_AIFLAGS
                    723:                {
                    724:                        char *p;
                    725: 
                    726:                        for (p = $1.buf + 1; *p; p++)
                    727:                                switch (*p) {
                    728:                                case '4':
                    729:                                        p_aifamily = AF_INET;
                    730:                                        break;
                    731: #ifdef INET6
                    732:                                case '6':
                    733:                                        p_aifamily = AF_INET6;
                    734:                                        break;
                    735: #endif
                    736:                                case 'n':
                    737:                                        p_aiflags = AI_NUMERICHOST;
                    738:                                        break;
                    739:                                default:
                    740:                                        yyerror("invalid flag");
                    741:                                        return -1;
                    742:                                }
                    743:                }
                    744:        ;
                    745: 
                    746: ipaddr
                    747:        :       STRING
                    748:                {
                    749:                        $$ = parse_addr($1.buf, NULL);
                    750:                        if ($$ == NULL) {
                    751:                                /* yyerror already called by parse_addr */
                    752:                                return -1;
                    753:                        }
                    754:                }
                    755:        ;
                    756: 
                    757: ipandport
                    758:        :       STRING
                    759:                {
                    760:                        $$ = parse_addr($1.buf, NULL);
                    761:                        if ($$ == NULL) {
                    762:                                /* yyerror already called by parse_addr */
                    763:                                return -1;
                    764:                        }
                    765:                }
                    766:        |       STRING portstr
                    767:                {
                    768:                        $$ = parse_addr($1.buf, $2.buf);
                    769:                        if ($$ == NULL) {
                    770:                                /* yyerror already called by parse_addr */
                    771:                                return -1;
                    772:                        }
                    773:                }
                    774:        ;
                    775: 
                    776: prefix
                    777:        :       /*NOTHING*/ { $$ = -1; }
                    778:        |       SLASH DECSTRING { $$ = $2; }
                    779:        ;
                    780: 
                    781: portstr
                    782:        :       /*NOTHING*/
                    783:                {
                    784:                        $$.buf = strdup("0");
                    785:                        if (!$$.buf) {
                    786:                                yyerror("insufficient memory");
                    787:                                return -1;
                    788:                        }
                    789:                        $$.len = strlen($$.buf);
                    790:                }
                    791:        |       BLCL ANY ELCL
                    792:                {
                    793:                        $$.buf = strdup("0");
                    794:                        if (!$$.buf) {
                    795:                                yyerror("insufficient memory");
                    796:                                return -1;
                    797:                        }
                    798:                        $$.len = strlen($$.buf);
                    799:                }
                    800:        |       BLCL DECSTRING ELCL
                    801:                {
                    802:                        char buf[20];
                    803:                        snprintf(buf, sizeof(buf), "%lu", $2);
                    804:                        $$.buf = strdup(buf);
                    805:                        if (!$$.buf) {
                    806:                                yyerror("insufficient memory");
                    807:                                return -1;
                    808:                        }
                    809:                        $$.len = strlen($$.buf);
                    810:                }
                    811:        |       BLCL STRING ELCL
                    812:                {
                    813:                        $$ = $2;
                    814:                }
                    815:        ;
                    816: 
                    817: upper_spec
                    818:        :       DECSTRING { $$ = $1; }
                    819:        |       ANY { $$ = IPSEC_ULPROTO_ANY; }
                    820:        |       PR_TCP { 
                    821:                                $$ = IPPROTO_TCP; 
                    822:                        }
                    823:        |       STRING
                    824:                {
                    825:                        struct protoent *ent;
                    826: 
                    827:                        ent = getprotobyname($1.buf);
                    828:                        if (ent)
                    829:                                $$ = ent->p_proto;
                    830:                        else {
                    831:                                if (strcmp("icmp6", $1.buf) == 0) {
                    832:                                        $$ = IPPROTO_ICMPV6;
                    833:                                } else if(strcmp("ip4", $1.buf) == 0) {
                    834:                                        $$ = IPPROTO_IPV4;
                    835:                                } else {
                    836:                                        yyerror("invalid upper layer protocol");
                    837:                                        return -1;
                    838:                                }
                    839:                        }
                    840:                        endprotoent();
                    841:                }
                    842:        ;
                    843: 
                    844: upper_misc_spec
                    845:        :       /*NOTHING*/
                    846:                {
                    847:                        $$.buf = NULL;
                    848:                        $$.len = 0;
                    849:                }
                    850:        |       STRING
                    851:                {
                    852:                        $$.buf = strdup($1.buf);
                    853:                        if (!$$.buf) {
                    854:                                yyerror("insufficient memory");
                    855:                                return -1;
                    856:                        }
                    857:                        $$.len = strlen($$.buf);
                    858:                }
                    859:        ;
                    860: 
                    861: context_spec
                    862:        :       /* NOTHING */
                    863:        |       SECURITY_CTX DECSTRING DECSTRING QUOTEDSTRING {
                    864:                        sec_ctx.doi = $2;
                    865:                        sec_ctx.alg = $3;
                    866:                        sec_ctx.len = $4.len+1;
                    867:                        sec_ctx.buf = $4.buf;
                    868:                }
                    869:        ;
                    870: 
                    871: policy_spec
                    872:        :       F_POLICY policy_requests
                    873:                {
                    874:                        char *policy;
                    875: #ifdef HAVE_PFKEY_POLICY_PRIORITY
                    876:                        struct sadb_x_policy *xpl;
                    877: #endif
                    878: 
                    879:                        policy = ipsec_set_policy($2.buf, $2.len);
                    880:                        if (policy == NULL) {
                    881:                                yyerror(ipsec_strerror());
                    882:                                return -1;
                    883:                        }
                    884: 
                    885:                        $$.buf = policy;
                    886:                        $$.len = ipsec_get_policylen(policy);
                    887: 
                    888: #ifdef HAVE_PFKEY_POLICY_PRIORITY
                    889:                        xpl = (struct sadb_x_policy *) $$.buf;
                    890:                        last_priority = xpl->sadb_x_policy_priority;
                    891: #endif
                    892:                }
                    893:        ;
                    894: 
                    895: policy_requests
                    896:        :       PL_REQUESTS { $$ = $1; }
                    897:        ;
                    898: 
                    899:        /* exit */
                    900: exit_command
                    901:        :       EXIT EOT
                    902:                {
                    903:                        exit_now = 1;
                    904:                        YYACCEPT;
                    905:                }
                    906:        ;
                    907: %%
                    908: 
                    909: int
                    910: setkeymsg0(msg, type, satype, l)
                    911:        struct sadb_msg *msg;
                    912:        unsigned int type;
                    913:        unsigned int satype;
                    914:        size_t l;
                    915: {
                    916: 
                    917:        msg->sadb_msg_version = PF_KEY_V2;
                    918:        msg->sadb_msg_type = type;
                    919:        msg->sadb_msg_errno = 0;
                    920:        msg->sadb_msg_satype = satype;
                    921:        msg->sadb_msg_reserved = 0;
                    922:        msg->sadb_msg_seq = 0;
                    923:        msg->sadb_msg_pid = getpid();
                    924:        msg->sadb_msg_len = PFKEY_UNIT64(l);
                    925:        return 0;
                    926: }
                    927: 
                    928: /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
                    929: static int
                    930: setkeymsg_spdaddr(type, upper, policy, srcs, splen, dsts, dplen)
                    931:        unsigned int type;
                    932:        unsigned int upper;
                    933:        vchar_t *policy;
                    934:        struct addrinfo *srcs;
                    935:        int splen;
                    936:        struct addrinfo *dsts;
                    937:        int dplen;
                    938: {
                    939:        struct sadb_msg *msg;
                    940:        char buf[BUFSIZ];
                    941:        int l, l0;
                    942:        struct sadb_address m_addr;
                    943:        struct addrinfo *s, *d;
                    944:        int n;
                    945:        int plen;
                    946:        struct sockaddr *sa;
                    947:        int salen;
                    948:        struct sadb_x_policy *sp;
                    949: #ifdef HAVE_POLICY_FWD
                    950:        struct sadb_x_ipsecrequest *ps = NULL;
                    951:        int saved_level, saved_id = 0;
                    952: #endif
                    953: 
                    954:        msg = (struct sadb_msg *)buf;
                    955: 
                    956:        if (!srcs || !dsts)
                    957:                return -1;
                    958: 
                    959:        /* fix up length afterwards */
                    960:        setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0);
                    961:        l = sizeof(struct sadb_msg);
                    962: 
                    963:        sp = (struct sadb_x_policy*) (buf + l);
                    964:        memcpy(buf + l, policy->buf, policy->len);
                    965:        l += policy->len;
                    966: 
                    967:        l0 = l;
                    968:        n = 0;
                    969: 
                    970:        /* do it for all src/dst pairs */
                    971:        for (s = srcs; s; s = s->ai_next) {
                    972:                for (d = dsts; d; d = d->ai_next) {
                    973:                        /* rewind pointer */
                    974:                        l = l0;
                    975: 
                    976:                        if (s->ai_addr->sa_family != d->ai_addr->sa_family)
                    977:                                continue;
                    978:                        switch (s->ai_addr->sa_family) {
                    979:                        case AF_INET:
                    980:                                plen = sizeof(struct in_addr) << 3;
                    981:                                break;
                    982: #ifdef INET6
                    983:                        case AF_INET6:
                    984:                                plen = sizeof(struct in6_addr) << 3;
                    985:                                break;
                    986: #endif
                    987:                        default:
                    988:                                continue;
                    989:                        }
                    990: 
                    991:                        /* set src */
                    992:                        sa = s->ai_addr;
                    993:                        salen = sysdep_sa_len(s->ai_addr);
                    994:                        m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
                    995:                            PFKEY_ALIGN8(salen));
                    996:                        m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
                    997:                        m_addr.sadb_address_proto = upper;
                    998:                        m_addr.sadb_address_prefixlen =
                    999:                            (splen >= 0 ? splen : plen);
                   1000:                        m_addr.sadb_address_reserved = 0;
                   1001: 
                   1002:                        setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
                   1003:                            sizeof(m_addr), (caddr_t)sa, salen);
                   1004: 
                   1005:                        /* set dst */
                   1006:                        sa = d->ai_addr;
                   1007:                        salen = sysdep_sa_len(d->ai_addr);
                   1008:                        m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
                   1009:                            PFKEY_ALIGN8(salen));
                   1010:                        m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
                   1011:                        m_addr.sadb_address_proto = upper;
                   1012:                        m_addr.sadb_address_prefixlen =
                   1013:                            (dplen >= 0 ? dplen : plen);
                   1014:                        m_addr.sadb_address_reserved = 0;
                   1015: 
                   1016:                        setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
                   1017:                            sizeof(m_addr), sa, salen);
                   1018: #ifdef SADB_X_EXT_SEC_CTX
                   1019:                        /* Add security context label */
                   1020:                        if (sec_ctx.doi) {
                   1021:                                struct sadb_x_sec_ctx m_sec_ctx;
                   1022:                                u_int slen = sizeof(struct sadb_x_sec_ctx);
                   1023: 
                   1024:                                memset(&m_sec_ctx, 0, slen);
                   1025: 
                   1026:                                m_sec_ctx.sadb_x_sec_len =
                   1027:                                PFKEY_UNIT64(slen + PFKEY_ALIGN8(sec_ctx.len));
                   1028: 
                   1029:                                m_sec_ctx.sadb_x_sec_exttype = 
                   1030:                                        SADB_X_EXT_SEC_CTX;
                   1031:                                m_sec_ctx.sadb_x_ctx_len = sec_ctx.len;/*bytes*/
                   1032:                                m_sec_ctx.sadb_x_ctx_doi = sec_ctx.doi;
                   1033:                                m_sec_ctx.sadb_x_ctx_alg = sec_ctx.alg;
                   1034:                                setvarbuf(buf, &l, 
                   1035:                                          (struct sadb_ext *)&m_sec_ctx, slen, 
                   1036:                                          (caddr_t)sec_ctx.buf, sec_ctx.len);
                   1037:                        }
                   1038: #endif
                   1039:                        msg->sadb_msg_len = PFKEY_UNIT64(l);
                   1040: 
                   1041:                        sendkeymsg(buf, l);
                   1042: 
                   1043: #ifdef HAVE_POLICY_FWD
                   1044:                        /* create extra call for FWD policy */
                   1045:                        if (f_rfcmode && sp->sadb_x_policy_dir == IPSEC_DIR_INBOUND) {
                   1046:                                sp->sadb_x_policy_dir = IPSEC_DIR_FWD;
                   1047:                                ps = (struct sadb_x_ipsecrequest*) (sp+1);
                   1048: 
                   1049:                                /* if request level is unique, change it to
                   1050:                                 * require for fwd policy */
                   1051:                                /* XXX: currently, only first policy is updated
                   1052:                                 * only. Update following too... */
                   1053:                                saved_level = ps->sadb_x_ipsecrequest_level;
                   1054:                                if (saved_level == IPSEC_LEVEL_UNIQUE) {
                   1055:                                        saved_id = ps->sadb_x_ipsecrequest_reqid;
                   1056:                                        ps->sadb_x_ipsecrequest_reqid=0;
                   1057:                                        ps->sadb_x_ipsecrequest_level=IPSEC_LEVEL_REQUIRE;
                   1058:                                }
                   1059: 
                   1060:                                sendkeymsg(buf, l);
                   1061:                                /* restoring for next message */
                   1062:                                sp->sadb_x_policy_dir = IPSEC_DIR_INBOUND;
                   1063:                                if (saved_level == IPSEC_LEVEL_UNIQUE) {
                   1064:                                        ps->sadb_x_ipsecrequest_reqid = saved_id;
                   1065:                                        ps->sadb_x_ipsecrequest_level = saved_level;
                   1066:                                }
                   1067:                        }
                   1068: #endif
                   1069: 
                   1070:                        n++;
                   1071:                }
                   1072:        }
                   1073: 
                   1074:        if (n == 0)
                   1075:                return -1;
                   1076:        else
                   1077:                return 0;
                   1078: }
                   1079: 
                   1080: static int
                   1081: setkeymsg_spdaddr_tag(type, tag, policy)
                   1082:        unsigned int type;
                   1083:        char *tag;
                   1084:        vchar_t *policy;
                   1085: {
                   1086:        struct sadb_msg *msg;
                   1087:        char buf[BUFSIZ];
                   1088:        int l, l0;
                   1089: #ifdef SADB_X_EXT_TAG
                   1090:        struct sadb_x_tag m_tag;
                   1091: #endif
                   1092:        int n;
                   1093: 
                   1094:        msg = (struct sadb_msg *)buf;
                   1095: 
                   1096:        /* fix up length afterwards */
                   1097:        setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0);
                   1098:        l = sizeof(struct sadb_msg);
                   1099: 
                   1100:        memcpy(buf + l, policy->buf, policy->len);
                   1101:        l += policy->len;
                   1102: 
                   1103:        l0 = l;
                   1104:        n = 0;
                   1105: 
                   1106: #ifdef SADB_X_EXT_TAG
                   1107:        memset(&m_tag, 0, sizeof(m_tag));
                   1108:        m_tag.sadb_x_tag_len = PFKEY_UNIT64(sizeof(m_tag));
                   1109:        m_tag.sadb_x_tag_exttype = SADB_X_EXT_TAG;
                   1110:        if (strlcpy(m_tag.sadb_x_tag_name, tag,
                   1111:            sizeof(m_tag.sadb_x_tag_name)) >= sizeof(m_tag.sadb_x_tag_name))
                   1112:                return -1;
                   1113:        memcpy(buf + l, &m_tag, sizeof(m_tag));
                   1114:        l += sizeof(m_tag);
                   1115: #endif
                   1116: 
                   1117:        msg->sadb_msg_len = PFKEY_UNIT64(l);
                   1118: 
                   1119:        sendkeymsg(buf, l);
                   1120: 
                   1121:        return 0;
                   1122: }
                   1123: 
                   1124: /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
                   1125: static int
                   1126: setkeymsg_addr(type, satype, srcs, dsts, no_spi)
                   1127:        unsigned int type;
                   1128:        unsigned int satype;
                   1129:        struct addrinfo *srcs;
                   1130:        struct addrinfo *dsts;
                   1131:        int no_spi;
                   1132: {
                   1133:        struct sadb_msg *msg;
                   1134:        char buf[BUFSIZ];
                   1135:        int l, l0, len;
                   1136:        struct sadb_sa m_sa;
                   1137:        struct sadb_x_sa2 m_sa2;
                   1138:        struct sadb_address m_addr;
                   1139:        struct addrinfo *s, *d;
                   1140:        int n;
                   1141:        int plen;
                   1142:        struct sockaddr *sa;
                   1143:        int salen;
                   1144: 
                   1145:        msg = (struct sadb_msg *)buf;
                   1146: 
                   1147:        if (!srcs || !dsts)
                   1148:                return -1;
                   1149: 
                   1150:        /* fix up length afterwards */
                   1151:        setkeymsg0(msg, type, satype, 0);
                   1152:        l = sizeof(struct sadb_msg);
                   1153: 
                   1154:        if (!no_spi) {
                   1155:                len = sizeof(struct sadb_sa);
                   1156:                m_sa.sadb_sa_len = PFKEY_UNIT64(len);
                   1157:                m_sa.sadb_sa_exttype = SADB_EXT_SA;
                   1158:                m_sa.sadb_sa_spi = htonl(p_spi);
                   1159:                m_sa.sadb_sa_replay = p_replay;
                   1160:                m_sa.sadb_sa_state = 0;
                   1161:                m_sa.sadb_sa_auth = p_alg_auth;
                   1162:                m_sa.sadb_sa_encrypt = p_alg_enc;
                   1163:                m_sa.sadb_sa_flags = p_ext;
                   1164: 
                   1165:                memcpy(buf + l, &m_sa, len);
                   1166:                l += len;
                   1167: 
                   1168:                len = sizeof(struct sadb_x_sa2);
                   1169:                m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
                   1170:                m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
                   1171:                m_sa2.sadb_x_sa2_mode = p_mode;
                   1172:                m_sa2.sadb_x_sa2_reqid = p_reqid;
                   1173: 
                   1174:                memcpy(buf + l, &m_sa2, len);
                   1175:                l += len;
                   1176:        }
                   1177: 
                   1178:        l0 = l;
                   1179:        n = 0;
                   1180: 
                   1181:        /* do it for all src/dst pairs */
                   1182:        for (s = srcs; s; s = s->ai_next) {
                   1183:                for (d = dsts; d; d = d->ai_next) {
                   1184:                        /* rewind pointer */
                   1185:                        l = l0;
                   1186: 
                   1187:                        if (s->ai_addr->sa_family != d->ai_addr->sa_family)
                   1188:                                continue;
                   1189:                        switch (s->ai_addr->sa_family) {
                   1190:                        case AF_INET:
                   1191:                                plen = sizeof(struct in_addr) << 3;
                   1192:                                break;
                   1193: #ifdef INET6
                   1194:                        case AF_INET6:
                   1195:                                plen = sizeof(struct in6_addr) << 3;
                   1196:                                break;
                   1197: #endif
                   1198:                        default:
                   1199:                                continue;
                   1200:                        }
                   1201: 
                   1202:                        /* set src */
                   1203:                        sa = s->ai_addr;
                   1204:                        salen = sysdep_sa_len(s->ai_addr);
                   1205:                        m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
                   1206:                            PFKEY_ALIGN8(salen));
                   1207:                        m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
                   1208:                        m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
                   1209:                        m_addr.sadb_address_prefixlen = plen;
                   1210:                        m_addr.sadb_address_reserved = 0;
                   1211: 
                   1212:                        setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
                   1213:                            sizeof(m_addr), sa, salen);
                   1214: 
                   1215:                        /* set dst */
                   1216:                        sa = d->ai_addr;
                   1217:                        salen = sysdep_sa_len(d->ai_addr);
                   1218:                        m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
                   1219:                            PFKEY_ALIGN8(salen));
                   1220:                        m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
                   1221:                        m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
                   1222:                        m_addr.sadb_address_prefixlen = plen;
                   1223:                        m_addr.sadb_address_reserved = 0;
                   1224: 
                   1225:                        setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
                   1226:                            sizeof(m_addr), sa, salen);
                   1227: 
                   1228:                        msg->sadb_msg_len = PFKEY_UNIT64(l);
                   1229: 
                   1230:                        sendkeymsg(buf, l);
                   1231: 
                   1232:                        n++;
                   1233:                }
                   1234:        }
                   1235: 
                   1236:        if (n == 0)
                   1237:                return -1;
                   1238:        else
                   1239:                return 0;
                   1240: }
                   1241: 
                   1242: #ifdef SADB_X_EXT_NAT_T_TYPE
                   1243: static u_int16_t get_port (struct addrinfo *addr)
                   1244: {
                   1245:        struct sockaddr *s = addr->ai_addr;
                   1246:        u_int16_t port = 0;
                   1247: 
                   1248:        switch (s->sa_family) {
                   1249:        case AF_INET:
                   1250:          {
                   1251:                struct sockaddr_in *sin4 = (struct sockaddr_in *)s;
                   1252:                port = ntohs(sin4->sin_port);
                   1253:                break;
                   1254:          }
                   1255:        case AF_INET6:
                   1256:          {
                   1257:                struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)s;
                   1258:                port = ntohs(sin6->sin6_port);
                   1259:                break;
                   1260:          }
                   1261:        }
                   1262: 
                   1263:        if (port == 0)
                   1264:                port = DEFAULT_NATT_PORT;
                   1265: 
                   1266:        return port;
                   1267: }
                   1268: #endif
                   1269: 
                   1270: /* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */
                   1271: static int
                   1272: setkeymsg_add(type, satype, srcs, dsts)
                   1273:        unsigned int type;
                   1274:        unsigned int satype;
                   1275:        struct addrinfo *srcs;
                   1276:        struct addrinfo *dsts;
                   1277: {
                   1278:        struct sadb_msg *msg;
                   1279:        char buf[BUFSIZ];
                   1280:        int l, l0, len;
                   1281:        struct sadb_sa m_sa;
                   1282:        struct sadb_x_sa2 m_sa2;
                   1283:        struct sadb_address m_addr;
                   1284:        struct addrinfo *s, *d;
                   1285:        int n;
                   1286:        int plen;
                   1287:        struct sockaddr *sa;
                   1288:        int salen;
                   1289: 
                   1290:        msg = (struct sadb_msg *)buf;
                   1291: 
                   1292:        if (!srcs || !dsts)
                   1293:                return -1;
                   1294: 
                   1295:        /* fix up length afterwards */
                   1296:        setkeymsg0(msg, type, satype, 0);
                   1297:        l = sizeof(struct sadb_msg);
                   1298: 
                   1299:        /* set encryption algorithm, if present. */
                   1300:        if (satype != SADB_X_SATYPE_IPCOMP && p_key_enc) {
                   1301:                union {
                   1302:                        struct sadb_key key;
                   1303:                        struct sadb_ext ext;
                   1304:                } m;
                   1305: 
                   1306:                m.key.sadb_key_len =
                   1307:                        PFKEY_UNIT64(sizeof(m.key)
                   1308:                                   + PFKEY_ALIGN8(p_key_enc_len));
                   1309:                m.key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT;
                   1310:                m.key.sadb_key_bits = p_key_enc_len * 8;
                   1311:                m.key.sadb_key_reserved = 0;
                   1312: 
                   1313:                setvarbuf(buf, &l, &m.ext, sizeof(m.key),
                   1314:                        p_key_enc, p_key_enc_len);
                   1315:        }
                   1316: 
                   1317:        /* set authentication algorithm, if present. */
                   1318:        if (p_key_auth) {
                   1319:                union {
                   1320:                        struct sadb_key key;
                   1321:                        struct sadb_ext ext;
                   1322:                } m;
                   1323: 
                   1324:                m.key.sadb_key_len =
                   1325:                        PFKEY_UNIT64(sizeof(m.key)
                   1326:                                   + PFKEY_ALIGN8(p_key_auth_len));
                   1327:                m.key.sadb_key_exttype = SADB_EXT_KEY_AUTH;
                   1328:                m.key.sadb_key_bits = p_key_auth_len * 8;
                   1329:                m.key.sadb_key_reserved = 0;
                   1330: 
                   1331:                setvarbuf(buf, &l, &m.ext, sizeof(m.key),
                   1332:                        p_key_auth, p_key_auth_len);
                   1333:        }
                   1334: 
                   1335:        /* set lifetime for HARD */
                   1336:        if (p_lt_hard != 0 || p_lb_hard != 0) {
                   1337:                struct sadb_lifetime m_lt;
                   1338:                u_int slen = sizeof(struct sadb_lifetime);
                   1339: 
                   1340:                m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen);
                   1341:                m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
                   1342:                m_lt.sadb_lifetime_allocations = 0;
                   1343:                m_lt.sadb_lifetime_bytes = p_lb_hard;
                   1344:                m_lt.sadb_lifetime_addtime = p_lt_hard;
                   1345:                m_lt.sadb_lifetime_usetime = 0;
                   1346: 
                   1347:                memcpy(buf + l, &m_lt, slen);
                   1348:                l += slen;
                   1349:        }
                   1350: 
                   1351:        /* set lifetime for SOFT */
                   1352:        if (p_lt_soft != 0 || p_lb_soft != 0) {
                   1353:                struct sadb_lifetime m_lt;
                   1354:                u_int slen = sizeof(struct sadb_lifetime);
                   1355: 
                   1356:                m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen);
                   1357:                m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT;
                   1358:                m_lt.sadb_lifetime_allocations = 0;
                   1359:                m_lt.sadb_lifetime_bytes = p_lb_soft;
                   1360:                m_lt.sadb_lifetime_addtime = p_lt_soft;
                   1361:                m_lt.sadb_lifetime_usetime = 0;
                   1362: 
                   1363:                memcpy(buf + l, &m_lt, slen);
                   1364:                l += slen;
                   1365:        }
                   1366: 
                   1367: #ifdef SADB_X_EXT_SEC_CTX
                   1368:        /* Add security context label */
                   1369:        if (sec_ctx.doi) {
                   1370:                struct sadb_x_sec_ctx m_sec_ctx;
                   1371:                u_int slen = sizeof(struct sadb_x_sec_ctx);
                   1372: 
                   1373:                memset(&m_sec_ctx, 0, slen);
                   1374: 
                   1375:                m_sec_ctx.sadb_x_sec_len = PFKEY_UNIT64(slen +
                   1376:                                        PFKEY_ALIGN8(sec_ctx.len));
                   1377:                m_sec_ctx.sadb_x_sec_exttype = SADB_X_EXT_SEC_CTX;
                   1378:                m_sec_ctx.sadb_x_ctx_len = sec_ctx.len; /* bytes */
                   1379:                m_sec_ctx.sadb_x_ctx_doi = sec_ctx.doi;
                   1380:                m_sec_ctx.sadb_x_ctx_alg = sec_ctx.alg;
                   1381:                setvarbuf(buf, &l, (struct sadb_ext *)&m_sec_ctx, slen,
                   1382:                          (caddr_t)sec_ctx.buf, sec_ctx.len); 
                   1383:        }
                   1384: #endif
                   1385: 
                   1386:        len = sizeof(struct sadb_sa);
                   1387:        m_sa.sadb_sa_len = PFKEY_UNIT64(len);
                   1388:        m_sa.sadb_sa_exttype = SADB_EXT_SA;
                   1389:        m_sa.sadb_sa_spi = htonl(p_spi);
                   1390:        m_sa.sadb_sa_replay = p_replay;
                   1391:        m_sa.sadb_sa_state = 0;
                   1392:        m_sa.sadb_sa_auth = p_alg_auth;
                   1393:        m_sa.sadb_sa_encrypt = p_alg_enc;
                   1394:        m_sa.sadb_sa_flags = p_ext;
                   1395: 
                   1396:        memcpy(buf + l, &m_sa, len);
                   1397:        l += len;
                   1398: 
                   1399:        len = sizeof(struct sadb_x_sa2);
                   1400:        m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len);
                   1401:        m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2;
                   1402:        m_sa2.sadb_x_sa2_mode = p_mode;
                   1403:        m_sa2.sadb_x_sa2_reqid = p_reqid;
                   1404: 
                   1405:        memcpy(buf + l, &m_sa2, len);
                   1406:        l += len;
                   1407: 
                   1408: #ifdef SADB_X_EXT_NAT_T_TYPE
                   1409:        if (p_natt_type) {
                   1410:                struct sadb_x_nat_t_type natt_type;
                   1411: 
                   1412:                len = sizeof(struct sadb_x_nat_t_type);
                   1413:                memset(&natt_type, 0, len);
                   1414:                natt_type.sadb_x_nat_t_type_len = PFKEY_UNIT64(len);
                   1415:                natt_type.sadb_x_nat_t_type_exttype = SADB_X_EXT_NAT_T_TYPE;
                   1416:                natt_type.sadb_x_nat_t_type_type = p_natt_type;
                   1417: 
                   1418:                memcpy(buf + l, &natt_type, len);
                   1419:                l += len;
                   1420: 
                   1421:                if (p_natt_oa) {
                   1422:                        sa = p_natt_oa->ai_addr;
                   1423:                        switch (sa->sa_family) {
                   1424:                        case AF_INET:
                   1425:                                plen = sizeof(struct in_addr) << 3;
                   1426:                                break;
                   1427: #ifdef INET6
                   1428:                        case AF_INET6:
                   1429:                                plen = sizeof(struct in6_addr) << 3;
                   1430:                                break;
                   1431: #endif
                   1432:                        default:
                   1433:                                return -1;
                   1434:                        }
                   1435:                        salen = sysdep_sa_len(sa);
                   1436:                        m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
                   1437:                            PFKEY_ALIGN8(salen));
                   1438:                        m_addr.sadb_address_exttype = SADB_X_EXT_NAT_T_OA;
                   1439:                        m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
                   1440:                        m_addr.sadb_address_prefixlen = plen;
                   1441:                        m_addr.sadb_address_reserved = 0;
                   1442: 
                   1443:                        setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
                   1444:                            sizeof(m_addr), sa, salen);
                   1445:                }
                   1446:        }
                   1447: #endif
                   1448: 
                   1449:        l0 = l;
                   1450:        n = 0;
                   1451: 
                   1452:        /* do it for all src/dst pairs */
                   1453:        for (s = srcs; s; s = s->ai_next) {
                   1454:                for (d = dsts; d; d = d->ai_next) {
                   1455:                        /* rewind pointer */
                   1456:                        l = l0;
                   1457: 
                   1458:                        if (s->ai_addr->sa_family != d->ai_addr->sa_family)
                   1459:                                continue;
                   1460:                        switch (s->ai_addr->sa_family) {
                   1461:                        case AF_INET:
                   1462:                                plen = sizeof(struct in_addr) << 3;
                   1463:                                break;
                   1464: #ifdef INET6
                   1465:                        case AF_INET6:
                   1466:                                plen = sizeof(struct in6_addr) << 3;
                   1467:                                break;
                   1468: #endif
                   1469:                        default:
                   1470:                                continue;
                   1471:                        }
                   1472: 
                   1473:                        /* set src */
                   1474:                        sa = s->ai_addr;
                   1475:                        salen = sysdep_sa_len(s->ai_addr);
                   1476:                        m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
                   1477:                            PFKEY_ALIGN8(salen));
                   1478:                        m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC;
                   1479:                        m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
                   1480:                        m_addr.sadb_address_prefixlen = plen;
                   1481:                        m_addr.sadb_address_reserved = 0;
                   1482: 
                   1483:                        setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
                   1484:                            sizeof(m_addr), sa, salen);
                   1485: 
                   1486:                        /* set dst */
                   1487:                        sa = d->ai_addr;
                   1488:                        salen = sysdep_sa_len(d->ai_addr);
                   1489:                        m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) +
                   1490:                            PFKEY_ALIGN8(salen));
                   1491:                        m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST;
                   1492:                        m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY;
                   1493:                        m_addr.sadb_address_prefixlen = plen;
                   1494:                        m_addr.sadb_address_reserved = 0;
                   1495: 
                   1496:                        setvarbuf(buf, &l, (struct sadb_ext *)&m_addr,
                   1497:                            sizeof(m_addr), sa, salen);
                   1498: 
                   1499: #ifdef SADB_X_EXT_NAT_T_TYPE
                   1500:                        if (p_natt_type) {
                   1501:                                struct sadb_x_nat_t_port natt_port;
                   1502: 
                   1503:                                /* NATT_SPORT */
                   1504:                                len = sizeof(struct sadb_x_nat_t_port);
                   1505:                                memset(&natt_port, 0, len);
                   1506:                                natt_port.sadb_x_nat_t_port_len = PFKEY_UNIT64(len);
                   1507:                                natt_port.sadb_x_nat_t_port_exttype =
                   1508:                                        SADB_X_EXT_NAT_T_SPORT;
                   1509:                                natt_port.sadb_x_nat_t_port_port = htons(get_port(s));
                   1510:                                
                   1511:                                memcpy(buf + l, &natt_port, len);
                   1512:                                l += len;
                   1513: 
                   1514:                                /* NATT_DPORT */
                   1515:                                natt_port.sadb_x_nat_t_port_exttype =
                   1516:                                        SADB_X_EXT_NAT_T_DPORT;
                   1517:                                natt_port.sadb_x_nat_t_port_port = htons(get_port(d));
                   1518:                                
                   1519:                                memcpy(buf + l, &natt_port, len);
                   1520:                                l += len;
                   1521:                        }
                   1522: #endif
                   1523:                        msg->sadb_msg_len = PFKEY_UNIT64(l);
                   1524: 
                   1525:                        sendkeymsg(buf, l);
                   1526: 
                   1527:                        n++;
                   1528:                }
                   1529:        }
                   1530: 
                   1531:        if (n == 0)
                   1532:                return -1;
                   1533:        else
                   1534:                return 0;
                   1535: }
                   1536: 
                   1537: static struct addrinfo *
                   1538: parse_addr(host, port)
                   1539:        char *host;
                   1540:        char *port;
                   1541: {
                   1542:        struct addrinfo hints, *res = NULL;
                   1543:        int error;
                   1544: 
                   1545:        memset(&hints, 0, sizeof(hints));
                   1546:        hints.ai_family = p_aifamily;
                   1547:        hints.ai_socktype = SOCK_DGRAM;         /*dummy*/
                   1548:        hints.ai_protocol = IPPROTO_UDP;        /*dummy*/
                   1549:        hints.ai_flags = p_aiflags;
                   1550:        error = getaddrinfo(host, port, &hints, &res);
                   1551:        if (error != 0) {
                   1552:                yyerror(gai_strerror(error));
                   1553:                return NULL;
                   1554:        }
                   1555:        return res;
                   1556: }
                   1557: 
                   1558: static int
                   1559: fix_portstr(ulproto, spec, sport, dport)
                   1560:        int ulproto;
                   1561:        vchar_t *spec, *sport, *dport;
                   1562: {
                   1563:        char sp[16], dp[16];
                   1564:        int a, b, c, d;
                   1565:        unsigned long u;
                   1566: 
                   1567:        if (spec->buf == NULL)
                   1568:                return 0;
                   1569: 
                   1570:        switch (ulproto) {
                   1571:        case IPPROTO_ICMP:
                   1572:        case IPPROTO_ICMPV6:
                   1573:        case IPPROTO_MH:
                   1574:                if (sscanf(spec->buf, "%d,%d", &a, &b) == 2) {
                   1575:                        sprintf(sp, "%d", a);
                   1576:                        sprintf(dp, "%d", b);
                   1577:                } else if (sscanf(spec->buf, "%d", &a) == 1) {
                   1578:                        sprintf(sp, "%d", a);
                   1579:                } else {
                   1580:                        yyerror("invalid an upper layer protocol spec");
                   1581:                        return -1;
                   1582:                }
                   1583:                break;
                   1584:        case IPPROTO_GRE:
                   1585:                if (sscanf(spec->buf, "%d.%d.%d.%d", &a, &b, &c, &d) == 4) {
                   1586:                        sprintf(sp, "%d", (a << 8) + b);
                   1587:                        sprintf(dp, "%d", (c << 8) + d);
                   1588:                } else if (sscanf(spec->buf, "%lu", &u) == 1) {
                   1589:                        sprintf(sp, "%d", (int) (u >> 16));
                   1590:                        sprintf(dp, "%d", (int) (u & 0xffff));
                   1591:                } else {
                   1592:                        yyerror("invalid an upper layer protocol spec");
                   1593:                        return -1;
                   1594:                }
                   1595:                break;
                   1596:        }
                   1597: 
                   1598:        free(sport->buf);
                   1599:        sport->buf = strdup(sp);
                   1600:        if (!sport->buf) {
                   1601:                yyerror("insufficient memory");
                   1602:                return -1;
                   1603:        }
                   1604:        sport->len = strlen(sport->buf);
                   1605: 
                   1606:        free(dport->buf);
                   1607:        dport->buf = strdup(dp);
                   1608:        if (!dport->buf) {
                   1609:                yyerror("insufficient memory");
                   1610:                return -1;
                   1611:        }
                   1612:        dport->len = strlen(dport->buf);
                   1613: 
                   1614:        return 0;
                   1615: }
                   1616: 
                   1617: static int
                   1618: setvarbuf(buf, off, ebuf, elen, vbuf, vlen)
                   1619:        char *buf;
                   1620:        int *off;
                   1621:        struct sadb_ext *ebuf;
                   1622:        int elen;
                   1623:        const void *vbuf;
                   1624:        int vlen;
                   1625: {
                   1626:        memset(buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len));
                   1627:        memcpy(buf + *off, (caddr_t)ebuf, elen);
                   1628:        memcpy(buf + *off + elen, vbuf, vlen);
                   1629:        (*off) += PFKEY_ALIGN8(elen + vlen);
                   1630: 
                   1631:        return 0;
                   1632: }
                   1633: 
                   1634: void
                   1635: parse_init()
                   1636: {
                   1637:        p_spi = 0;
                   1638: 
                   1639:        p_ext = SADB_X_EXT_CYCSEQ;
                   1640:        p_alg_enc = SADB_EALG_NONE;
                   1641:        p_alg_auth = SADB_AALG_NONE;
                   1642:        p_mode = IPSEC_MODE_ANY;
                   1643:        p_reqid = 0;
                   1644:        p_replay = 0;
                   1645:        p_key_enc_len = p_key_auth_len = 0;
                   1646:        p_key_enc = p_key_auth = 0;
                   1647:        p_lt_hard = p_lt_soft = 0;
                   1648:        p_lb_hard = p_lb_soft = 0;
                   1649: 
                   1650:        memset(&sec_ctx, 0, sizeof(struct security_ctx));
                   1651: 
                   1652:        p_aiflags = 0;
                   1653:        p_aifamily = PF_UNSPEC;
                   1654: 
                   1655:        /* Clear out any natt OA information */
                   1656:        if (p_natt_oa)
                   1657:                freeaddrinfo (p_natt_oa);
                   1658:        p_natt_oa = NULL;
                   1659:        p_natt_type = 0;
                   1660: 
                   1661:        return;
                   1662: }
                   1663: 
                   1664: void
                   1665: free_buffer()
                   1666: {
                   1667:        /* we got tons of memory leaks in the parser anyways, leave them */
                   1668: 
                   1669:        return;
                   1670: }

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