parse.y (78064) | parse.y (122108) |
---|---|
1/* $FreeBSD: head/sbin/setkey/parse.y 78064 2001-06-11 12:39:29Z ume $ */ 2/* $KAME: kame/kame/kame/setkey/parse.y,v 1.36 2001/06/07 15:53:12 sakane Exp $ */ | 1/* $FreeBSD: head/sbin/setkey/parse.y 122108 2003-11-05 09:47:54Z ume $ */ 2/* $KAME: parse.y,v 1.81 2003/07/01 04:01:48 itojun Exp $ */ |
3 4/* 5 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: --- 37 unchanged lines hidden (view full) --- 48#include <netdb.h> 49#include <ctype.h> 50#include <errno.h> 51 52#include "libpfkey.h" 53#include "vchar.h" 54 55#define ATOX(c) \ | 3 4/* 5 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: --- 37 unchanged lines hidden (view full) --- 48#include <netdb.h> 49#include <ctype.h> 50#include <errno.h> 51 52#include "libpfkey.h" 53#include "vchar.h" 54 55#define ATOX(c) \ |
56 (isdigit(c) ? (c - '0') : (isupper(c) ? (c - 'A' + 10) : (c - 'a' + 10) )) | 56 (isdigit(c) ? (c - '0') : (isupper(c) ? (c - 'A' + 10) : (c - 'a' + 10))) |
57 | 57 |
58u_int p_type; | |
59u_int32_t p_spi; | 58u_int32_t p_spi; |
60int p_no_spi; 61struct sockaddr *p_src, *p_dst; 62u_int p_prefs, p_prefd, p_upper; 63u_int p_satype, p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode; | 59u_int p_ext, p_alg_enc, p_alg_auth, p_replay, p_mode; |
64u_int32_t p_reqid; 65u_int p_key_enc_len, p_key_auth_len; 66caddr_t p_key_enc, p_key_auth; 67time_t p_lt_hard, p_lt_soft; 68 | 60u_int32_t p_reqid; 61u_int p_key_enc_len, p_key_auth_len; 62caddr_t p_key_enc, p_key_auth; 63time_t p_lt_hard, p_lt_soft; 64 |
69u_int p_policy_len; 70char *p_policy; | 65static int p_aiflags = 0, p_aifamily = PF_UNSPEC; |
71 | 66 |
72/* temporary buffer */ 73static struct sockaddr *pp_addr; 74static u_int pp_prefix; 75static u_int pp_port; 76static caddr_t pp_key; 77 78extern u_char m_buf[BUFSIZ]; 79extern int m_len; 80extern char cmdarg[8192]; 81extern int f_debug; 82 83static struct addrinfo *parse_addr __P((char *, char *, int)); 84static int setvarbuf __P((int *, struct sadb_ext *, int, caddr_t, int)); | 67static struct addrinfo *parse_addr __P((char *, char *)); 68static int fix_portstr __P((vchar_t *, vchar_t *, vchar_t *)); 69static int setvarbuf __P((char *, int *, struct sadb_ext *, int, caddr_t, int)); |
85void parse_init __P((void)); 86void free_buffer __P((void)); 87 | 70void parse_init __P((void)); 71void free_buffer __P((void)); 72 |
88extern int setkeymsg __P((void)); 89extern int sendkeymsg __P((void)); | 73int setkeymsg0 __P((struct sadb_msg *, unsigned int, unsigned int, size_t)); 74static int setkeymsg_spdaddr __P((unsigned int, unsigned int, vchar_t *, 75 struct addrinfo *, int, struct addrinfo *, int)); 76static int setkeymsg_addr __P((unsigned int, unsigned int, 77 struct addrinfo *, struct addrinfo *, int)); 78static int setkeymsg_add __P((unsigned int, unsigned int, 79 struct addrinfo *, struct addrinfo *)); 80extern int setkeymsg __P((char *, size_t *)); 81extern int sendkeymsg __P((char *, size_t)); |
90 91extern int yylex __P((void)); 92extern void yyfatal __P((const char *)); 93extern void yyerror __P((const char *)); 94%} 95 96%union { | 82 83extern int yylex __P((void)); 84extern void yyfatal __P((const char *)); 85extern void yyerror __P((const char *)); 86%} 87 88%union { |
97 unsigned long num; | 89 int num; 90 unsigned long ulnum; |
98 vchar_t val; | 91 vchar_t val; |
92 struct addrinfo *res; |
|
99} 100 | 93} 94 |
101%token EOT 102%token ADD GET DELETE FLUSH DUMP 103%token ADDRESS PREFIX PORT PORTANY 104%token UP_PROTO PR_ESP PR_AH PR_IPCOMP | 95%token EOT SLASH BLCL ELCL 96%token ADD GET DELETE DELETEALL FLUSH DUMP 97%token PR_ESP PR_AH PR_IPCOMP |
105%token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI 106%token F_MODE MODE F_REQID 107%token F_EXT EXTENSION NOCYCLICSEQ | 98%token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI 99%token F_MODE MODE F_REQID 100%token F_EXT EXTENSION NOCYCLICSEQ |
108%token ALG_AUTH ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_COMP | 101%token ALG_AUTH ALG_AUTH_NOKEY 102%token ALG_ENC ALG_ENC_NOKEY ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD 103%token ALG_COMP |
109%token F_LIFETIME_HARD F_LIFETIME_SOFT 110%token DECSTRING QUOTEDSTRING HEXSTRING STRING ANY 111 /* SPD management */ 112%token SPDADD SPDDELETE SPDDUMP SPDFLUSH 113%token F_POLICY PL_REQUESTS | 104%token F_LIFETIME_HARD F_LIFETIME_SOFT 105%token DECSTRING QUOTEDSTRING HEXSTRING STRING ANY 106 /* SPD management */ 107%token SPDADD SPDDELETE SPDDUMP SPDFLUSH 108%token F_POLICY PL_REQUESTS |
109%token F_AIFLAGS 110%token TAGGED |
|
114 | 111 |
115%type <num> PORT PREFIX EXTENSION MODE 116%type <num> UP_PROTO PR_ESP PR_AH PR_IPCOMP 117%type <num> ALG_AUTH ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_COMP 118%type <num> DECSTRING 119%type <val> ADDRESS PL_REQUESTS 120%type <val> key_string policy_requests | 112%type <num> prefix protocol_spec upper_spec 113%type <num> ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_ENC_OLD ALG_ENC_NOKEY 114%type <num> ALG_AUTH ALG_AUTH_NOKEY 115%type <num> ALG_COMP 116%type <num> PR_ESP PR_AH PR_IPCOMP 117%type <num> EXTENSION MODE 118%type <ulnum> DECSTRING 119%type <val> PL_REQUESTS portstr key_string 120%type <val> policy_requests |
121%type <val> QUOTEDSTRING HEXSTRING STRING | 121%type <val> QUOTEDSTRING HEXSTRING STRING |
122%type <val> F_AIFLAGS 123%type <val> upper_misc_spec policy_spec 124%type <res> ipaddr |
|
122 123%% 124commands 125 : /*NOTHING*/ 126 | commands command 127 { | 125 126%% 127commands 128 : /*NOTHING*/ 129 | commands command 130 { |
128 if (f_debug) { 129 printf("cmdarg:\n%s\n", cmdarg); 130 } else { 131 setkeymsg(); 132 sendkeymsg(); 133 } | |
134 free_buffer(); 135 parse_init(); 136 } 137 ; 138 139command 140 : add_command 141 | get_command --- 5 unchanged lines hidden (view full) --- 147 | spddelete_command 148 | spddump_command 149 | spdflush_command 150 ; 151 /* commands concerned with management, there is in tail of this file. */ 152 153 /* add command */ 154add_command | 131 free_buffer(); 132 parse_init(); 133 } 134 ; 135 136command 137 : add_command 138 | get_command --- 5 unchanged lines hidden (view full) --- 144 | spddelete_command 145 | spddump_command 146 | spdflush_command 147 ; 148 /* commands concerned with management, there is in tail of this file. */ 149 150 /* add command */ 151add_command |
155 : ADD { p_type = SADB_ADD; } 156 sa_selector_spec extension_spec algorithm_spec EOT | 152 : ADD ipaddropts ipaddr ipaddr protocol_spec spi extension_spec algorithm_spec EOT 153 { 154 int status; 155 156 status = setkeymsg_add(SADB_ADD, $5, $3, $4); 157 if (status < 0) 158 return -1; 159 } |
157 ; 158 159 /* delete */ 160delete_command | 160 ; 161 162 /* delete */ 163delete_command |
161 : DELETE { p_type = SADB_DELETE; } 162 sa_selector_spec extension_spec | 164 : DELETE ipaddropts ipaddr ipaddr protocol_spec spi extension_spec EOT |
163 { | 165 { |
166 int status; 167 168 if ($3->ai_next || $4->ai_next) { 169 yyerror("multiple address specified"); 170 return -1; 171 } |
|
164 if (p_mode != IPSEC_MODE_ANY) | 172 if (p_mode != IPSEC_MODE_ANY) |
165 yyerror("WARNING: mode is obsoleted."); | 173 yyerror("WARNING: mode is obsolete"); 174 175 status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 0); 176 if (status < 0) 177 return -1; |
166 } | 178 } |
167 EOT | |
168 ; 169 170 /* deleteall command */ 171deleteall_command | 179 ; 180 181 /* deleteall command */ 182deleteall_command |
172 : DELETEALL { p_type = SADB_DELETE; } 173 ipaddress { p_src = pp_addr; } 174 ipaddress { p_dst = pp_addr; } 175 protocol_spec 176 { p_no_spi = 1; } 177 EOT | 183 : DELETEALL ipaddropts ipaddr ipaddr protocol_spec EOT 184 { 185 int status; 186 187 status = setkeymsg_addr(SADB_DELETE, $5, $3, $4, 1); 188 if (status < 0) 189 return -1; 190 } |
178 ; 179 180 /* get command */ 181get_command | 191 ; 192 193 /* get command */ 194get_command |
182 : GET { p_type = SADB_GET; } 183 sa_selector_spec extension_spec | 195 : GET ipaddropts ipaddr ipaddr protocol_spec spi extension_spec EOT |
184 { | 196 { |
197 int status; 198 |
|
185 if (p_mode != IPSEC_MODE_ANY) | 199 if (p_mode != IPSEC_MODE_ANY) |
186 yyerror("WARNING: mode is obsoleted."); | 200 yyerror("WARNING: mode is obsolete"); 201 202 status = setkeymsg_addr(SADB_GET, $5, $3, $4, 0); 203 if (status < 0) 204 return -1; |
187 } | 205 } |
188 EOT | |
189 ; 190 191 /* flush */ 192flush_command | 206 ; 207 208 /* flush */ 209flush_command |
193 : FLUSH { p_type = SADB_FLUSH; } 194 protocol_spec EOT | 210 : FLUSH protocol_spec EOT 211 { 212 struct sadb_msg msg; 213 setkeymsg0(&msg, SADB_FLUSH, $2, sizeof(msg)); 214 sendkeymsg((char *)&msg, sizeof(msg)); 215 } |
195 ; 196 197 /* dump */ 198dump_command | 216 ; 217 218 /* dump */ 219dump_command |
199 : DUMP { p_type = SADB_DUMP; } 200 protocol_spec EOT | 220 : DUMP protocol_spec EOT 221 { 222 struct sadb_msg msg; 223 setkeymsg0(&msg, SADB_DUMP, $2, sizeof(msg)); 224 sendkeymsg((char *)&msg, sizeof(msg)); 225 } |
201 ; 202 | 226 ; 227 |
203 /* sa_selector_spec */ 204sa_selector_spec 205 : ipaddress { p_src = pp_addr; } 206 ipaddress { p_dst = pp_addr; } 207 protocol_spec spi 208 ; 209 | |
210protocol_spec | 228protocol_spec |
211 : /*NOTHING*/ { p_satype = SADB_SATYPE_UNSPEC; } | 229 : /*NOTHING*/ 230 { 231 $$ = SADB_SATYPE_UNSPEC; 232 } |
212 | PR_ESP 213 { | 233 | PR_ESP 234 { |
214 p_satype = SADB_SATYPE_ESP; | 235 $$ = SADB_SATYPE_ESP; |
215 if ($1 == 1) 216 p_ext |= SADB_X_EXT_OLD; 217 else 218 p_ext &= ~SADB_X_EXT_OLD; 219 } 220 | PR_AH 221 { | 236 if ($1 == 1) 237 p_ext |= SADB_X_EXT_OLD; 238 else 239 p_ext &= ~SADB_X_EXT_OLD; 240 } 241 | PR_AH 242 { |
222 p_satype = SADB_SATYPE_AH; | 243 $$ = SADB_SATYPE_AH; |
223 if ($1 == 1) 224 p_ext |= SADB_X_EXT_OLD; 225 else 226 p_ext &= ~SADB_X_EXT_OLD; 227 } 228 | PR_IPCOMP 229 { | 244 if ($1 == 1) 245 p_ext |= SADB_X_EXT_OLD; 246 else 247 p_ext &= ~SADB_X_EXT_OLD; 248 } 249 | PR_IPCOMP 250 { |
230 p_satype = SADB_X_SATYPE_IPCOMP; | 251 $$ = SADB_X_SATYPE_IPCOMP; |
231 } 232 ; 233 234spi 235 : DECSTRING { p_spi = $1; } 236 | HEXSTRING 237 { | 252 } 253 ; 254 255spi 256 : DECSTRING { p_spi = $1; } 257 | HEXSTRING 258 { |
238 caddr_t bp; 239 caddr_t yp = $1.buf; 240 char buf0[4], buf[4]; 241 int i, j; | 259 char *ep; 260 unsigned long v; |
242 | 261 |
243 /* sanity check */ 244 if ($1.len > 4) { | 262 ep = NULL; 263 v = strtoul($1.buf, &ep, 16); 264 if (!ep || *ep) { 265 yyerror("invalid SPI"); 266 return -1; 267 } 268 if (v & ~0xffffffff) { |
245 yyerror("SPI too big."); | 269 yyerror("SPI too big."); |
246 free($1.buf); | |
247 return -1; 248 } 249 | 270 return -1; 271 } 272 |
250 bp = buf0; 251 while (*yp) { 252 *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]); 253 yp += 2, bp++; 254 } 255 256 /* initialize */ 257 for (i = 0; i < 4; i++) buf[i] = 0; 258 259 for (j = $1.len - 1, i = 3; j >= 0; j--, i--) 260 buf[i] = buf0[j]; 261 262 /* XXX: endian */ 263 p_spi = ntohl(*(u_int32_t *)buf); 264 265 free($1.buf); | 273 p_spi = v; |
266 } 267 ; 268 269algorithm_spec 270 : esp_spec 271 | ah_spec 272 | ipcomp_spec 273 ; 274 275esp_spec | 274 } 275 ; 276 277algorithm_spec 278 : esp_spec 279 | ah_spec 280 | ipcomp_spec 281 ; 282 283esp_spec |
276 : F_ENC enc_alg enc_key F_AUTH auth_alg auth_key 277 | F_ENC enc_alg enc_key | 284 : F_ENC enc_alg F_AUTH auth_alg 285 | F_ENC enc_alg |
278 ; 279 280ah_spec | 286 ; 287 288ah_spec |
281 : F_AUTH auth_alg auth_key | 289 : F_AUTH auth_alg |
282 ; 283 284ipcomp_spec | 290 ; 291 292ipcomp_spec |
285 : F_COMP ALG_COMP { p_alg_enc = $2; } 286 | F_COMP ALG_COMP { p_alg_enc = $2; } 287 F_RAWCPI { p_ext |= SADB_X_EXT_RAWCPI; } | 293 : F_COMP ALG_COMP 294 { 295 if ($2 < 0) { 296 yyerror("unsupported algorithm"); 297 return -1; 298 } 299 p_alg_enc = $2; 300 } 301 | F_COMP ALG_COMP F_RAWCPI 302 { 303 if ($2 < 0) { 304 yyerror("unsupported algorithm"); 305 return -1; 306 } 307 p_alg_enc = $2; 308 p_ext |= SADB_X_EXT_RAWCPI; 309 } |
288 ; 289 290enc_alg | 310 ; 311 312enc_alg |
291 : ALG_ENC { p_alg_enc = $1; } 292 | ALG_ENC_DESDERIV | 313 : ALG_ENC_NOKEY { 314 if ($1 < 0) { 315 yyerror("unsupported algorithm"); 316 return -1; 317 } 318 p_alg_enc = $1; 319 320 p_key_enc_len = 0; 321 p_key_enc = NULL; 322 } 323 | ALG_ENC key_string { 324 if ($1 < 0) { 325 yyerror("unsupported algorithm"); 326 return -1; 327 } 328 p_alg_enc = $1; 329 330 p_key_enc_len = $2.len; 331 p_key_enc = $2.buf; 332 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, 333 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { 334 yyerror(ipsec_strerror()); 335 return -1; 336 } 337 } 338 | ALG_ENC_OLD { 339 if ($1 < 0) { 340 yyerror("unsupported algorithm"); 341 return -1; 342 } 343 yyerror("WARNING: obsolete algorithm"); 344 p_alg_enc = $1; 345 346 p_key_enc_len = 0; 347 p_key_enc = NULL; 348 } 349 | ALG_ENC_DESDERIV key_string |
293 { | 350 { |
351 if ($1 < 0) { 352 yyerror("unsupported algorithm"); 353 return -1; 354 } |
|
294 p_alg_enc = $1; 295 if (p_ext & SADB_X_EXT_OLD) { | 355 p_alg_enc = $1; 356 if (p_ext & SADB_X_EXT_OLD) { |
296 yyerror("algorithm mismatched."); | 357 yyerror("algorithm mismatched"); |
297 return -1; 298 } 299 p_ext |= SADB_X_EXT_DERIV; | 358 return -1; 359 } 360 p_ext |= SADB_X_EXT_DERIV; |
361 362 p_key_enc_len = $2.len; 363 p_key_enc = $2.buf; 364 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, 365 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { 366 yyerror(ipsec_strerror()); 367 return -1; 368 } |
|
300 } | 369 } |
301 | ALG_ENC_DES32IV | 370 | ALG_ENC_DES32IV key_string |
302 { | 371 { |
372 if ($1 < 0) { 373 yyerror("unsupported algorithm"); 374 return -1; 375 } |
|
303 p_alg_enc = $1; 304 if (!(p_ext & SADB_X_EXT_OLD)) { | 376 p_alg_enc = $1; 377 if (!(p_ext & SADB_X_EXT_OLD)) { |
305 yyerror("algorithm mismatched."); | 378 yyerror("algorithm mismatched"); |
306 return -1; 307 } 308 p_ext |= SADB_X_EXT_IV4B; | 379 return -1; 380 } 381 p_ext |= SADB_X_EXT_IV4B; |
309 } 310 ; | |
311 | 382 |
312enc_key 313 : /*NOTHING*/ 314 { 315 if (p_alg_enc != SADB_EALG_NULL) { 316 yyerror("no key found."); 317 return -1; 318 } 319 } 320 | key_string 321 { 322 p_key_enc_len = $1.len; 323 p_key_enc = pp_key; 324 | 383 p_key_enc_len = $2.len; 384 p_key_enc = $2.buf; |
325 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, | 385 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_ENCRYPT, |
326 p_alg_enc, 327 PFKEY_UNUNIT64(p_key_enc_len)) < 0) { | 386 p_alg_enc, PFKEY_UNUNIT64(p_key_enc_len)) < 0) { |
328 yyerror(ipsec_strerror()); 329 return -1; 330 } 331 } 332 ; 333 334auth_alg | 387 yyerror(ipsec_strerror()); 388 return -1; 389 } 390 } 391 ; 392 393auth_alg |
335 : ALG_AUTH { p_alg_auth = $1; } 336 ; 337 338auth_key 339 : /*NOTHING*/ 340 { 341 if (p_alg_auth != SADB_X_AALG_NULL) { 342 yyerror("no key found."); | 394 : ALG_AUTH key_string { 395 if ($1 < 0) { 396 yyerror("unsupported algorithm"); |
343 return -1; 344 } | 397 return -1; 398 } |
345 } 346 | key_string 347 { 348 p_key_auth_len = $1.len; 349 p_key_auth = pp_key; | 399 p_alg_auth = $1; |
350 | 400 |
401 p_key_auth_len = $2.len; 402 p_key_auth = $2.buf; |
|
351 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH, | 403 if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH, |
352 p_alg_auth, 353 PFKEY_UNUNIT64(p_key_auth_len)) < 0) { | 404 p_alg_auth, PFKEY_UNUNIT64(p_key_auth_len)) < 0) { |
354 yyerror(ipsec_strerror()); 355 return -1; 356 } 357 } | 405 yyerror(ipsec_strerror()); 406 return -1; 407 } 408 } |
409 | ALG_AUTH_NOKEY { 410 if ($1 < 0) { 411 yyerror("unsupported algorithm"); 412 return -1; 413 } 414 p_alg_auth = $1; 415 416 p_key_auth_len = 0; 417 p_key_auth = NULL; 418 } |
|
358 ; 359 360key_string 361 : QUOTEDSTRING 362 { | 419 ; 420 421key_string 422 : QUOTEDSTRING 423 { |
363 pp_key = $1.buf; 364 /* free pp_key later */ | 424 $$ = $1; |
365 } 366 | HEXSTRING 367 { | 425 } 426 | HEXSTRING 427 { |
428 caddr_t pp_key; |
|
368 caddr_t bp; 369 caddr_t yp = $1.buf; | 429 caddr_t bp; 430 caddr_t yp = $1.buf; |
431 int l; |
|
370 | 432 |
371 if ((pp_key = malloc($1.len)) == 0) { 372 free($1.buf); | 433 l = strlen(yp) % 2 + strlen(yp) / 2; 434 if ((pp_key = malloc(l)) == 0) { |
373 yyerror("not enough core"); 374 return -1; 375 } | 435 yyerror("not enough core"); 436 return -1; 437 } |
376 memset(pp_key, 0, $1.len); | 438 memset(pp_key, 0, l); |
377 378 bp = pp_key; | 439 440 bp = pp_key; |
441 if (strlen(yp) % 2) { 442 *bp = ATOX(yp[0]); 443 yp++, bp++; 444 } |
|
379 while (*yp) { 380 *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]); 381 yp += 2, bp++; 382 } 383 | 445 while (*yp) { 446 *bp = (ATOX(yp[0]) << 4) | ATOX(yp[1]); 447 yp += 2, bp++; 448 } 449 |
384 free($1.buf); | 450 $$.len = l; 451 $$.buf = pp_key; |
385 } 386 ; 387 388extension_spec 389 : /*NOTHING*/ 390 | extension_spec extension 391 ; 392 393extension 394 : F_EXT EXTENSION { p_ext |= $2; } 395 | F_EXT NOCYCLICSEQ { p_ext &= ~SADB_X_EXT_CYCSEQ; } 396 | F_MODE MODE { p_mode = $2; } 397 | F_MODE ANY { p_mode = IPSEC_MODE_ANY; } 398 | F_REQID DECSTRING { p_reqid = $2; } 399 | F_REPLAY DECSTRING 400 { | 452 } 453 ; 454 455extension_spec 456 : /*NOTHING*/ 457 | extension_spec extension 458 ; 459 460extension 461 : F_EXT EXTENSION { p_ext |= $2; } 462 | F_EXT NOCYCLICSEQ { p_ext &= ~SADB_X_EXT_CYCSEQ; } 463 | F_MODE MODE { p_mode = $2; } 464 | F_MODE ANY { p_mode = IPSEC_MODE_ANY; } 465 | F_REQID DECSTRING { p_reqid = $2; } 466 | F_REPLAY DECSTRING 467 { |
401 if (p_ext & SADB_X_EXT_OLD) { 402 yyerror("replay prevention " 403 "only use on new spec."); | 468 if ((p_ext & SADB_X_EXT_OLD) != 0) { 469 yyerror("replay prevention cannot be used with " 470 "ah/esp-old"); |
404 return -1; 405 } 406 p_replay = $2; 407 } 408 | F_LIFETIME_HARD DECSTRING { p_lt_hard = $2; } 409 | F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; } 410 ; 411 412 /* definition about command for SPD management */ 413 /* spdadd */ 414spdadd_command | 471 return -1; 472 } 473 p_replay = $2; 474 } 475 | F_LIFETIME_HARD DECSTRING { p_lt_hard = $2; } 476 | F_LIFETIME_SOFT DECSTRING { p_lt_soft = $2; } 477 ; 478 479 /* definition about command for SPD management */ 480 /* spdadd */ 481spdadd_command |
415 : SPDADD | 482 : SPDADD ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec EOT |
416 { | 483 { |
417 p_type = SADB_X_SPDADD; 418 p_satype = SADB_SATYPE_UNSPEC; | 484 int status; 485 struct addrinfo *src, *dst; 486 487 /* fixed port fields if ulp is icmpv6 */ 488 if ($10.buf != NULL) { 489 if ($9 != IPPROTO_ICMPV6) 490 return -1; 491 free($5.buf); 492 free($8.buf); 493 if (fix_portstr(&$10, &$5, &$8)) 494 return -1; 495 } 496 497 src = parse_addr($3.buf, $5.buf); 498 dst = parse_addr($6.buf, $8.buf); 499 if (!src || !dst) { 500 /* yyerror is already called */ 501 return -1; 502 } 503 if (src->ai_next || dst->ai_next) { 504 yyerror("multiple address specified"); 505 freeaddrinfo(src); 506 freeaddrinfo(dst); 507 return -1; 508 } 509 510 status = setkeymsg_spdaddr(SADB_X_SPDADD, $9, &$11, 511 src, $4, dst, $7); 512 freeaddrinfo(src); 513 freeaddrinfo(dst); 514 if (status < 0) 515 return -1; |
419 } | 516 } |
420 sp_selector_spec policy_spec EOT | 517 | SPDADD TAGGED QUOTEDSTRING policy_spec EOT 518 { 519 return -1; 520 } |
421 ; 422 | 521 ; 522 |
423spddelete_command: 424 SPDDELETE | 523spddelete_command 524 : SPDDELETE ipaddropts STRING prefix portstr STRING prefix portstr upper_spec upper_misc_spec policy_spec EOT |
425 { | 525 { |
426 p_type = SADB_X_SPDDELETE; 427 p_satype = SADB_SATYPE_UNSPEC; | 526 int status; 527 struct addrinfo *src, *dst; 528 529 /* fixed port fields if ulp is icmpv6 */ 530 if ($10.buf != NULL) { 531 if ($9 != IPPROTO_ICMPV6) 532 return -1; 533 free($5.buf); 534 free($8.buf); 535 if (fix_portstr(&$10, &$5, &$8)) 536 return -1; 537 } 538 539 src = parse_addr($3.buf, $5.buf); 540 dst = parse_addr($6.buf, $8.buf); 541 if (!src || !dst) { 542 /* yyerror is already called */ 543 return -1; 544 } 545 if (src->ai_next || dst->ai_next) { 546 yyerror("multiple address specified"); 547 freeaddrinfo(src); 548 freeaddrinfo(dst); 549 return -1; 550 } 551 552 status = setkeymsg_spdaddr(SADB_X_SPDDELETE, $9, &$11, 553 src, $4, dst, $7); 554 freeaddrinfo(src); 555 freeaddrinfo(dst); 556 if (status < 0) 557 return -1; |
428 } | 558 } |
429 sp_selector_spec policy_spec EOT | |
430 ; 431 432spddump_command: | 559 ; 560 561spddump_command: |
433 SPDDUMP | 562 SPDDUMP EOT |
434 { | 563 { |
435 p_type = SADB_X_SPDDUMP; 436 p_satype = SADB_SATYPE_UNSPEC; | 564 struct sadb_msg msg; 565 setkeymsg0(&msg, SADB_X_SPDDUMP, SADB_SATYPE_UNSPEC, 566 sizeof(msg)); 567 sendkeymsg((char *)&msg, sizeof(msg)); |
437 } | 568 } |
438 EOT | |
439 ; 440 441spdflush_command: | 569 ; 570 571spdflush_command: |
442 SPDFLUSH | 572 SPDFLUSH EOT |
443 { | 573 { |
444 p_type = SADB_X_SPDFLUSH; 445 p_satype = SADB_SATYPE_UNSPEC; | 574 struct sadb_msg msg; 575 setkeymsg0(&msg, SADB_X_SPDFLUSH, SADB_SATYPE_UNSPEC, 576 sizeof(msg)); 577 sendkeymsg((char *)&msg, sizeof(msg)); |
446 } | 578 } |
447 EOT | |
448 ; 449 | 579 ; 580 |
450 /* sp_selector_spec */ 451sp_selector_spec 452 : ipaddress { p_src = pp_addr; } 453 prefix { p_prefs = pp_prefix; } 454 port | 581ipaddropts 582 : /* nothing */ 583 | ipaddropts ipaddropt 584 ; 585 586ipaddropt 587 : F_AIFLAGS |
455 { | 588 { |
456 switch (p_src->sa_family) { 457 case AF_INET: 458 ((struct sockaddr_in *)p_src)->sin_port = 459 htons(pp_port); 460 break; | 589 char *p; 590 591 for (p = $1.buf + 1; *p; p++) 592 switch (*p) { 593 case '4': 594 p_aifamily = AF_INET; 595 break; |
461#ifdef INET6 | 596#ifdef INET6 |
462 case AF_INET6: 463 ((struct sockaddr_in6 *)p_src)->sin6_port = 464 htons(pp_port); 465 break; | 597 case '6': 598 p_aifamily = AF_INET6; 599 break; |
466#endif | 600#endif |
467 default: 468 exit(1); /*XXX*/ 469 } 470 } 471 ipaddress { p_dst = pp_addr; } 472 prefix { p_prefd = pp_prefix; } 473 port 474 { 475 switch (p_dst->sa_family) { 476 case AF_INET: 477 ((struct sockaddr_in *)p_dst)->sin_port = 478 htons(pp_port); 479 break; 480#ifdef INET6 481 case AF_INET6: 482 ((struct sockaddr_in6 *)p_dst)->sin6_port = 483 htons(pp_port); 484 break; 485#endif 486 default: 487 exit(1); /*XXX*/ 488 } 489 } 490 upper_spec 491 { 492 /* XXX is it something userland should check? */ 493#if 0 494 switch (p_upper) { 495 case IPPROTO_ICMP: 496 case IPPROTO_ICMPV6: 497 if (_INPORTBYSA(p_src) != IPSEC_PORT_ANY 498 || _INPORTBYSA(p_dst) != IPSEC_PORT_ANY) { 499 yyerror("port number must be \"any\"."); | 601 case 'n': 602 p_aiflags = AI_NUMERICHOST; 603 break; 604 default: 605 yyerror("invalid flag"); |
500 return -1; 501 } | 606 return -1; 607 } |
502 if ((pp_addr->sa_family == AF_INET6 503 && p_upper == IPPROTO_ICMP) 504 || (pp_addr->sa_family == AF_INET 505 && p_upper == IPPROTO_ICMPV6)) { 506 yyerror("upper layer protocol " 507 "mismatched.\n"); 508 return -1; 509 } 510 break; 511 default: 512 break; 513 } 514#endif | |
515 } 516 ; 517 | 608 } 609 ; 610 |
518ipaddress 519 : ADDRESS | 611ipaddr 612 : STRING |
520 { | 613 { |
521 struct addrinfo *res; 522 523 res = parse_addr($1.buf, NULL, AI_NUMERICHOST); 524 if (res == NULL) { 525 free($1.buf); | 614 $$ = parse_addr($1.buf, NULL); 615 if ($$ == NULL) { 616 /* yyerror already called by parse_addr */ |
526 return -1; 527 } | 617 return -1; 618 } |
528 pp_addr = (struct sockaddr *)malloc(res->ai_addrlen); 529 if (!pp_addr) { 530 yyerror("not enough core"); 531 goto end; 532 } 533 534 memcpy(pp_addr, res->ai_addr, res->ai_addrlen); 535 end: 536 freeaddrinfo(res); 537 free($1.buf); | |
538 } 539 ; 540 541prefix | 619 } 620 ; 621 622prefix |
542 : /*NOTHING*/ { pp_prefix = ~0; } 543 | PREFIX { pp_prefix = $1; } | 623 : /*NOTHING*/ { $$ = -1; } 624 | SLASH DECSTRING { $$ = $2; } |
544 ; 545 | 625 ; 626 |
546port 547 : /*NOTHING*/ { pp_port = IPSEC_PORT_ANY; } 548 | PORT { pp_port = $1; } 549 | PORTANY { pp_port = IPSEC_PORT_ANY; } | 627portstr 628 : /*NOTHING*/ 629 { 630 $$.buf = strdup("0"); 631 if (!$$.buf) { 632 yyerror("insufficient memory"); 633 return -1; 634 } 635 $$.len = strlen($$.buf); 636 } 637 | BLCL ANY ELCL 638 { 639 $$.buf = strdup("0"); 640 if (!$$.buf) { 641 yyerror("insufficient memory"); 642 return -1; 643 } 644 $$.len = strlen($$.buf); 645 } 646 | BLCL DECSTRING ELCL 647 { 648 char buf[20]; 649 snprintf(buf, sizeof(buf), "%lu", $2); 650 $$.buf = strdup(buf); 651 if (!$$.buf) { 652 yyerror("insufficient memory"); 653 return -1; 654 } 655 $$.len = strlen($$.buf); 656 } 657 | BLCL STRING ELCL 658 { 659 $$ = $2; 660 } |
550 ; 551 552upper_spec | 661 ; 662 663upper_spec |
553 : DECSTRING { p_upper = $1; } 554 | UP_PROTO { p_upper = $1; } 555 | ANY { p_upper = IPSEC_ULPROTO_ANY; } | 664 : DECSTRING { $$ = $1; } 665 | ANY { $$ = IPSEC_ULPROTO_ANY; } |
556 | STRING 557 { 558 struct protoent *ent; 559 560 ent = getprotobyname($1.buf); 561 if (ent) | 666 | STRING 667 { 668 struct protoent *ent; 669 670 ent = getprotobyname($1.buf); 671 if (ent) |
562 p_upper = ent->p_proto; | 672 $$ = ent->p_proto; |
563 else { 564 if (strcmp("icmp6", $1.buf) == 0) { | 673 else { 674 if (strcmp("icmp6", $1.buf) == 0) { |
565 p_upper = IPPROTO_ICMPV6; | 675 $$ = IPPROTO_ICMPV6; |
566 } else if(strcmp("ip4", $1.buf) == 0) { | 676 } else if(strcmp("ip4", $1.buf) == 0) { |
567 p_upper = IPPROTO_IPV4; | 677 $$ = IPPROTO_IPV4; |
568 } else { 569 yyerror("invalid upper layer protocol"); | 678 } else { 679 yyerror("invalid upper layer protocol"); |
570 free($1.buf); | |
571 return -1; 572 } 573 } | 680 return -1; 681 } 682 } |
574 free($1.buf); | 683 endprotoent(); |
575 } 576 ; 577 | 684 } 685 ; 686 |
687upper_misc_spec 688 : /*NOTHING*/ 689 { 690 $$.buf = NULL; 691 $$.len = 0; 692 } 693 | STRING 694 { 695 $$.buf = strdup($1.buf); 696 if (!$$.buf) { 697 yyerror("insufficient memory"); 698 return -1; 699 } 700 $$.len = strlen($$.buf); 701 } 702 ; 703 |
|
578policy_spec 579 : F_POLICY policy_requests 580 { | 704policy_spec 705 : F_POLICY policy_requests 706 { |
581 p_policy = ipsec_set_policy($2.buf, $2.len); 582 if (p_policy == NULL) { 583 free($2.buf); 584 p_policy = NULL; | 707 char *policy; 708 709 policy = ipsec_set_policy($2.buf, $2.len); 710 if (policy == NULL) { |
585 yyerror(ipsec_strerror()); 586 return -1; 587 } 588 | 711 yyerror(ipsec_strerror()); 712 return -1; 713 } 714 |
589 p_policy_len = ipsec_get_policylen(p_policy); 590 591 free($2.buf); | 715 $$.buf = policy; 716 $$.len = ipsec_get_policylen(policy); |
592 } 593 ; 594 595policy_requests 596 : PL_REQUESTS { $$ = $1; } 597 ; 598 599%% 600 601int | 717 } 718 ; 719 720policy_requests 721 : PL_REQUESTS { $$ = $1; } 722 ; 723 724%% 725 726int |
602setkeymsg() | 727setkeymsg0(msg, type, satype, l) 728 struct sadb_msg *msg; 729 unsigned int type; 730 unsigned int satype; 731 size_t l; |
603{ | 732{ |
604 struct sadb_msg m_msg; | |
605 | 733 |
606 m_msg.sadb_msg_version = PF_KEY_V2; 607 m_msg.sadb_msg_type = p_type; 608 m_msg.sadb_msg_errno = 0; 609 m_msg.sadb_msg_satype = p_satype; 610 m_msg.sadb_msg_reserved = 0; 611 m_msg.sadb_msg_seq = 0; 612 m_msg.sadb_msg_pid = getpid(); | 734 msg->sadb_msg_version = PF_KEY_V2; 735 msg->sadb_msg_type = type; 736 msg->sadb_msg_errno = 0; 737 msg->sadb_msg_satype = satype; 738 msg->sadb_msg_reserved = 0; 739 msg->sadb_msg_seq = 0; 740 msg->sadb_msg_pid = getpid(); 741 msg->sadb_msg_len = PFKEY_UNIT64(l); 742 return 0; 743} |
613 | 744 |
614 m_len = sizeof(struct sadb_msg); 615 memcpy(m_buf, &m_msg, m_len); | 745/* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ 746static int 747setkeymsg_spdaddr(type, upper, policy, srcs, splen, dsts, dplen) 748 unsigned int type; 749 unsigned int upper; 750 vchar_t *policy; 751 struct addrinfo *srcs; 752 int splen; 753 struct addrinfo *dsts; 754 int dplen; 755{ 756 struct sadb_msg *msg; 757 char buf[BUFSIZ]; 758 int l, l0; 759 struct sadb_address m_addr; 760 struct addrinfo *s, *d; 761 int n; 762 int plen; 763 struct sockaddr *sa; 764 int salen; |
616 | 765 |
617 switch (p_type) { 618 case SADB_FLUSH: 619 case SADB_DUMP: 620 break; | 766 msg = (struct sadb_msg *)buf; |
621 | 767 |
622 case SADB_ADD: 623 /* set encryption algorithm, if present. */ 624 if (p_satype != SADB_X_SATYPE_IPCOMP && p_alg_enc != SADB_EALG_NONE) { 625 struct sadb_key m_key; | 768 if (!srcs || !dsts) 769 return -1; |
626 | 770 |
627 m_key.sadb_key_len = 628 PFKEY_UNIT64(sizeof(m_key) 629 + PFKEY_ALIGN8(p_key_enc_len)); 630 m_key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT; 631 m_key.sadb_key_bits = p_key_enc_len * 8; 632 m_key.sadb_key_reserved = 0; | 771 /* fix up length afterwards */ 772 setkeymsg0(msg, type, SADB_SATYPE_UNSPEC, 0); 773 l = sizeof(struct sadb_msg); |
633 | 774 |
634 setvarbuf(&m_len, 635 (struct sadb_ext *)&m_key, sizeof(m_key), 636 (caddr_t)p_key_enc, p_key_enc_len); 637 } | 775 memcpy(buf + l, policy->buf, policy->len); 776 l += policy->len; |
638 | 777 |
639 /* set authentication algorithm, if present. */ 640 if (p_alg_auth != SADB_AALG_NONE) { 641 struct sadb_key m_key; | 778 l0 = l; 779 n = 0; |
642 | 780 |
643 m_key.sadb_key_len = 644 PFKEY_UNIT64(sizeof(m_key) 645 + PFKEY_ALIGN8(p_key_auth_len)); 646 m_key.sadb_key_exttype = SADB_EXT_KEY_AUTH; 647 m_key.sadb_key_bits = p_key_auth_len * 8; 648 m_key.sadb_key_reserved = 0; | 781 /* do it for all src/dst pairs */ 782 for (s = srcs; s; s = s->ai_next) { 783 for (d = dsts; d; d = d->ai_next) { 784 /* rewind pointer */ 785 l = l0; |
649 | 786 |
650 setvarbuf(&m_len, 651 (struct sadb_ext *)&m_key, sizeof(m_key), 652 (caddr_t)p_key_auth, p_key_auth_len); 653 } | 787 if (s->ai_addr->sa_family != d->ai_addr->sa_family) 788 continue; 789 switch (s->ai_addr->sa_family) { 790 case AF_INET: 791 plen = sizeof(struct in_addr) << 3; 792 break; 793#ifdef INET6 794 case AF_INET6: 795 plen = sizeof(struct in6_addr) << 3; 796 break; 797#endif 798 default: 799 continue; 800 } |
654 | 801 |
655 /* set lifetime for HARD */ 656 if (p_lt_hard != 0) { 657 struct sadb_lifetime m_lt; 658 u_int len = sizeof(struct sadb_lifetime); | 802 /* set src */ 803 sa = s->ai_addr; 804 salen = s->ai_addr->sa_len; 805 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 806 PFKEY_ALIGN8(salen)); 807 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 808 m_addr.sadb_address_proto = upper; 809 m_addr.sadb_address_prefixlen = 810 (splen >= 0 ? splen : plen); 811 m_addr.sadb_address_reserved = 0; |
659 | 812 |
660 m_lt.sadb_lifetime_len = PFKEY_UNIT64(len); 661 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD; 662 m_lt.sadb_lifetime_allocations = 0; 663 m_lt.sadb_lifetime_bytes = 0; 664 m_lt.sadb_lifetime_addtime = p_lt_hard; 665 m_lt.sadb_lifetime_usetime = 0; | 813 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 814 sizeof(m_addr), (caddr_t)sa, salen); |
666 | 815 |
667 memcpy(m_buf + m_len, &m_lt, len); 668 m_len += len; 669 } | 816 /* set dst */ 817 sa = d->ai_addr; 818 salen = d->ai_addr->sa_len; 819 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 820 PFKEY_ALIGN8(salen)); 821 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 822 m_addr.sadb_address_proto = upper; 823 m_addr.sadb_address_prefixlen = 824 (dplen >= 0 ? dplen : plen); 825 m_addr.sadb_address_reserved = 0; |
670 | 826 |
671 /* set lifetime for SOFT */ 672 if (p_lt_soft != 0) { 673 struct sadb_lifetime m_lt; 674 u_int len = sizeof(struct sadb_lifetime); | 827 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 828 sizeof(m_addr), (caddr_t)sa, salen); |
675 | 829 |
676 m_lt.sadb_lifetime_len = PFKEY_UNIT64(len); 677 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT; 678 m_lt.sadb_lifetime_allocations = 0; 679 m_lt.sadb_lifetime_bytes = 0; 680 m_lt.sadb_lifetime_addtime = p_lt_soft; 681 m_lt.sadb_lifetime_usetime = 0; | 830 msg->sadb_msg_len = PFKEY_UNIT64(l); |
682 | 831 |
683 memcpy(m_buf + m_len, &m_lt, len); 684 m_len += len; | 832 sendkeymsg(buf, l); 833 834 n++; |
685 } | 835 } |
686 /* FALLTHROUGH */ | 836 } |
687 | 837 |
688 case SADB_DELETE: 689 case SADB_GET: 690 { 691 struct sadb_sa m_sa; 692 struct sadb_x_sa2 m_sa2; 693 struct sadb_address m_addr; 694 u_int len; | 838 if (n == 0) 839 return -1; 840 else 841 return 0; 842} |
695 | 843 |
696 if (p_no_spi == 0) { 697 len = sizeof(struct sadb_sa); 698 m_sa.sadb_sa_len = PFKEY_UNIT64(len); 699 m_sa.sadb_sa_exttype = SADB_EXT_SA; 700 m_sa.sadb_sa_spi = htonl(p_spi); 701 m_sa.sadb_sa_replay = p_replay; 702 m_sa.sadb_sa_state = 0; 703 m_sa.sadb_sa_auth = p_alg_auth; 704 m_sa.sadb_sa_encrypt = p_alg_enc; 705 m_sa.sadb_sa_flags = p_ext; | 844/* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ 845static int 846setkeymsg_addr(type, satype, srcs, dsts, no_spi) 847 unsigned int type; 848 unsigned int satype; 849 struct addrinfo *srcs; 850 struct addrinfo *dsts; 851 int no_spi; 852{ 853 struct sadb_msg *msg; 854 char buf[BUFSIZ]; 855 int l, l0, len; 856 struct sadb_sa m_sa; 857 struct sadb_x_sa2 m_sa2; 858 struct sadb_address m_addr; 859 struct addrinfo *s, *d; 860 int n; 861 int plen; 862 struct sockaddr *sa; 863 int salen; |
706 | 864 |
707 memcpy(m_buf + m_len, &m_sa, len); 708 m_len += len; | 865 msg = (struct sadb_msg *)buf; |
709 | 866 |
710 len = sizeof(struct sadb_x_sa2); 711 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len); 712 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2; 713 m_sa2.sadb_x_sa2_mode = p_mode; 714 m_sa2.sadb_x_sa2_reqid = p_reqid; | 867 if (!srcs || !dsts) 868 return -1; |
715 | 869 |
716 memcpy(m_buf + m_len, &m_sa2, len); 717 m_len += len; 718 } | 870 /* fix up length afterwards */ 871 setkeymsg0(msg, type, satype, 0); 872 l = sizeof(struct sadb_msg); |
719 | 873 |
720 /* set src */ 721 m_addr.sadb_address_len = 722 PFKEY_UNIT64(sizeof(m_addr) 723 + PFKEY_ALIGN8(p_src->sa_len)); 724 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 725 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 726 switch (p_src->sa_family) { 727 case AF_INET: 728 m_addr.sadb_address_prefixlen = 729 sizeof(struct in_addr) << 3; 730 break; 731#ifdef INET6 732 case AF_INET6: 733 m_addr.sadb_address_prefixlen = 734 sizeof(struct in6_addr) << 3; 735 break; 736#endif 737 default: 738 yyerror("unsupported address family"); 739 exit(1); /*XXX*/ 740 } 741 m_addr.sadb_address_reserved = 0; | 874 if (!no_spi) { 875 len = sizeof(struct sadb_sa); 876 m_sa.sadb_sa_len = PFKEY_UNIT64(len); 877 m_sa.sadb_sa_exttype = SADB_EXT_SA; 878 m_sa.sadb_sa_spi = htonl(p_spi); 879 m_sa.sadb_sa_replay = p_replay; 880 m_sa.sadb_sa_state = 0; 881 m_sa.sadb_sa_auth = p_alg_auth; 882 m_sa.sadb_sa_encrypt = p_alg_enc; 883 m_sa.sadb_sa_flags = p_ext; |
742 | 884 |
743 setvarbuf(&m_len, 744 (struct sadb_ext *)&m_addr, sizeof(m_addr), 745 (caddr_t)p_src, p_src->sa_len); | 885 memcpy(buf + l, &m_sa, len); 886 l += len; |
746 | 887 |
747 /* set dst */ 748 m_addr.sadb_address_len = 749 PFKEY_UNIT64(sizeof(m_addr) 750 + PFKEY_ALIGN8(p_dst->sa_len)); 751 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 752 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 753 switch (p_dst->sa_family) { 754 case AF_INET: 755 m_addr.sadb_address_prefixlen = 756 sizeof(struct in_addr) << 3; 757 break; | 888 len = sizeof(struct sadb_x_sa2); 889 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len); 890 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2; 891 m_sa2.sadb_x_sa2_mode = p_mode; 892 m_sa2.sadb_x_sa2_reqid = p_reqid; 893 894 memcpy(buf + l, &m_sa2, len); 895 l += len; 896 } 897 898 l0 = l; 899 n = 0; 900 901 /* do it for all src/dst pairs */ 902 for (s = srcs; s; s = s->ai_next) { 903 for (d = dsts; d; d = d->ai_next) { 904 /* rewind pointer */ 905 l = l0; 906 907 if (s->ai_addr->sa_family != d->ai_addr->sa_family) 908 continue; 909 switch (s->ai_addr->sa_family) { 910 case AF_INET: 911 plen = sizeof(struct in_addr) << 3; 912 break; |
758#ifdef INET6 | 913#ifdef INET6 |
759 case AF_INET6: 760 m_addr.sadb_address_prefixlen = 761 sizeof(struct in6_addr) << 3; 762 break; | 914 case AF_INET6: 915 plen = sizeof(struct in6_addr) << 3; 916 break; |
763#endif | 917#endif |
764 default: 765 yyerror("unsupported address family"); 766 exit(1); /*XXX*/ 767 } 768 m_addr.sadb_address_reserved = 0; | 918 default: 919 continue; 920 } |
769 | 921 |
770 setvarbuf(&m_len, 771 (struct sadb_ext *)&m_addr, sizeof(m_addr), 772 (caddr_t)p_dst, p_dst->sa_len); 773 } 774 break; | 922 /* set src */ 923 sa = s->ai_addr; 924 salen = s->ai_addr->sa_len; 925 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 926 PFKEY_ALIGN8(salen)); 927 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 928 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 929 m_addr.sadb_address_prefixlen = plen; 930 m_addr.sadb_address_reserved = 0; |
775 | 931 |
776 /* for SPD management */ 777 case SADB_X_SPDFLUSH: 778 case SADB_X_SPDDUMP: 779 break; | 932 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 933 sizeof(m_addr), (caddr_t)sa, salen); |
780 | 934 |
781 case SADB_X_SPDADD: 782 case SADB_X_SPDDELETE: 783 { 784 struct sadb_address m_addr; 785 u_int8_t plen; | 935 /* set dst */ 936 sa = d->ai_addr; 937 salen = d->ai_addr->sa_len; 938 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 939 PFKEY_ALIGN8(salen)); 940 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 941 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 942 m_addr.sadb_address_prefixlen = plen; 943 m_addr.sadb_address_reserved = 0; |
786 | 944 |
787 memcpy(m_buf + m_len, p_policy, p_policy_len); 788 m_len += p_policy_len; 789 free(p_policy); 790 p_policy = NULL; | 945 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 946 sizeof(m_addr), (caddr_t)sa, salen); |
791 | 947 |
792 /* set src */ 793 m_addr.sadb_address_len = 794 PFKEY_UNIT64(sizeof(m_addr) 795 + PFKEY_ALIGN8(p_src->sa_len)); 796 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 797 m_addr.sadb_address_proto = p_upper; 798 switch (p_src->sa_family) { 799 case AF_INET: 800 plen = sizeof(struct in_addr) << 3; 801 break; 802#ifdef INET6 803 case AF_INET6: 804 plen = sizeof(struct in6_addr) << 3; 805 break; 806#endif 807 default: 808 yyerror("unsupported address family"); 809 exit(1); /*XXX*/ | 948 msg->sadb_msg_len = PFKEY_UNIT64(l); 949 950 sendkeymsg(buf, l); 951 952 n++; |
810 } | 953 } |
811 m_addr.sadb_address_prefixlen = 812 (p_prefs != ~0 ? p_prefs : plen); 813 m_addr.sadb_address_reserved = 0; | 954 } |
814 | 955 |
815 setvarbuf(&m_len, 816 (struct sadb_ext *)&m_addr, sizeof(m_addr), 817 (caddr_t)p_src, p_src->sa_len); | 956 if (n == 0) 957 return -1; 958 else 959 return 0; 960} |
818 | 961 |
819 /* set dst */ 820 m_addr.sadb_address_len = 821 PFKEY_UNIT64(sizeof(m_addr) 822 + PFKEY_ALIGN8(p_dst->sa_len)); 823 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 824 m_addr.sadb_address_proto = p_upper; 825 switch (p_dst->sa_family) { 826 case AF_INET: 827 plen = sizeof(struct in_addr) << 3; 828 break; | 962/* XXX NO BUFFER OVERRUN CHECK! BAD BAD! */ 963static int 964setkeymsg_add(type, satype, srcs, dsts) 965 unsigned int type; 966 unsigned int satype; 967 struct addrinfo *srcs; 968 struct addrinfo *dsts; 969{ 970 struct sadb_msg *msg; 971 char buf[BUFSIZ]; 972 int l, l0, len; 973 struct sadb_sa m_sa; 974 struct sadb_x_sa2 m_sa2; 975 struct sadb_address m_addr; 976 struct addrinfo *s, *d; 977 int n; 978 int plen; 979 struct sockaddr *sa; 980 int salen; 981 982 msg = (struct sadb_msg *)buf; 983 984 if (!srcs || !dsts) 985 return -1; 986 987 /* fix up length afterwards */ 988 setkeymsg0(msg, type, satype, 0); 989 l = sizeof(struct sadb_msg); 990 991 /* set encryption algorithm, if present. */ 992 if (satype != SADB_X_SATYPE_IPCOMP && p_key_enc) { 993 struct sadb_key m_key; 994 995 m_key.sadb_key_len = 996 PFKEY_UNIT64(sizeof(m_key) 997 + PFKEY_ALIGN8(p_key_enc_len)); 998 m_key.sadb_key_exttype = SADB_EXT_KEY_ENCRYPT; 999 m_key.sadb_key_bits = p_key_enc_len * 8; 1000 m_key.sadb_key_reserved = 0; 1001 1002 setvarbuf(buf, &l, 1003 (struct sadb_ext *)&m_key, sizeof(m_key), 1004 (caddr_t)p_key_enc, p_key_enc_len); 1005 } 1006 1007 /* set authentication algorithm, if present. */ 1008 if (p_key_auth) { 1009 struct sadb_key m_key; 1010 1011 m_key.sadb_key_len = 1012 PFKEY_UNIT64(sizeof(m_key) 1013 + PFKEY_ALIGN8(p_key_auth_len)); 1014 m_key.sadb_key_exttype = SADB_EXT_KEY_AUTH; 1015 m_key.sadb_key_bits = p_key_auth_len * 8; 1016 m_key.sadb_key_reserved = 0; 1017 1018 setvarbuf(buf, &l, 1019 (struct sadb_ext *)&m_key, sizeof(m_key), 1020 (caddr_t)p_key_auth, p_key_auth_len); 1021 } 1022 1023 /* set lifetime for HARD */ 1024 if (p_lt_hard != 0) { 1025 struct sadb_lifetime m_lt; 1026 u_int slen = sizeof(struct sadb_lifetime); 1027 1028 m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen); 1029 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD; 1030 m_lt.sadb_lifetime_allocations = 0; 1031 m_lt.sadb_lifetime_bytes = 0; 1032 m_lt.sadb_lifetime_addtime = p_lt_hard; 1033 m_lt.sadb_lifetime_usetime = 0; 1034 1035 memcpy(buf + l, &m_lt, slen); 1036 l += len; 1037 } 1038 1039 /* set lifetime for SOFT */ 1040 if (p_lt_soft != 0) { 1041 struct sadb_lifetime m_lt; 1042 u_int slen = sizeof(struct sadb_lifetime); 1043 1044 m_lt.sadb_lifetime_len = PFKEY_UNIT64(slen); 1045 m_lt.sadb_lifetime_exttype = SADB_EXT_LIFETIME_SOFT; 1046 m_lt.sadb_lifetime_allocations = 0; 1047 m_lt.sadb_lifetime_bytes = 0; 1048 m_lt.sadb_lifetime_addtime = p_lt_soft; 1049 m_lt.sadb_lifetime_usetime = 0; 1050 1051 memcpy(buf + l, &m_lt, slen); 1052 l += len; 1053 } 1054 1055 len = sizeof(struct sadb_sa); 1056 m_sa.sadb_sa_len = PFKEY_UNIT64(len); 1057 m_sa.sadb_sa_exttype = SADB_EXT_SA; 1058 m_sa.sadb_sa_spi = htonl(p_spi); 1059 m_sa.sadb_sa_replay = p_replay; 1060 m_sa.sadb_sa_state = 0; 1061 m_sa.sadb_sa_auth = p_alg_auth; 1062 m_sa.sadb_sa_encrypt = p_alg_enc; 1063 m_sa.sadb_sa_flags = p_ext; 1064 1065 memcpy(buf + l, &m_sa, len); 1066 l += len; 1067 1068 len = sizeof(struct sadb_x_sa2); 1069 m_sa2.sadb_x_sa2_len = PFKEY_UNIT64(len); 1070 m_sa2.sadb_x_sa2_exttype = SADB_X_EXT_SA2; 1071 m_sa2.sadb_x_sa2_mode = p_mode; 1072 m_sa2.sadb_x_sa2_reqid = p_reqid; 1073 1074 memcpy(buf + l, &m_sa2, len); 1075 l += len; 1076 1077 l0 = l; 1078 n = 0; 1079 1080 /* do it for all src/dst pairs */ 1081 for (s = srcs; s; s = s->ai_next) { 1082 for (d = dsts; d; d = d->ai_next) { 1083 /* rewind pointer */ 1084 l = l0; 1085 1086 if (s->ai_addr->sa_family != d->ai_addr->sa_family) 1087 continue; 1088 switch (s->ai_addr->sa_family) { 1089 case AF_INET: 1090 plen = sizeof(struct in_addr) << 3; 1091 break; |
829#ifdef INET6 | 1092#ifdef INET6 |
830 case AF_INET6: 831 plen = sizeof(struct in6_addr) << 3; 832 break; | 1093 case AF_INET6: 1094 plen = sizeof(struct in6_addr) << 3; 1095 break; |
833#endif | 1096#endif |
834 default: 835 yyerror("unsupported address family"); 836 exit(1); /*XXX*/ 837 } 838 m_addr.sadb_address_prefixlen = 839 (p_prefd != ~0 ? p_prefd : plen); 840 m_addr.sadb_address_reserved = 0; | 1097 default: 1098 continue; 1099 } |
841 | 1100 |
842 setvarbuf(&m_len, 843 (struct sadb_ext *)&m_addr, sizeof(m_addr), 844 (caddr_t)p_dst, p_dst->sa_len); 845 } 846 break; 847 } | 1101 /* set src */ 1102 sa = s->ai_addr; 1103 salen = s->ai_addr->sa_len; 1104 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 1105 PFKEY_ALIGN8(salen)); 1106 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_SRC; 1107 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 1108 m_addr.sadb_address_prefixlen = plen; 1109 m_addr.sadb_address_reserved = 0; |
848 | 1110 |
849 ((struct sadb_msg *)m_buf)->sadb_msg_len = PFKEY_UNIT64(m_len); | 1111 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 1112 sizeof(m_addr), (caddr_t)sa, salen); |
850 | 1113 |
851 return 0; | 1114 /* set dst */ 1115 sa = d->ai_addr; 1116 salen = d->ai_addr->sa_len; 1117 m_addr.sadb_address_len = PFKEY_UNIT64(sizeof(m_addr) + 1118 PFKEY_ALIGN8(salen)); 1119 m_addr.sadb_address_exttype = SADB_EXT_ADDRESS_DST; 1120 m_addr.sadb_address_proto = IPSEC_ULPROTO_ANY; 1121 m_addr.sadb_address_prefixlen = plen; 1122 m_addr.sadb_address_reserved = 0; 1123 1124 setvarbuf(buf, &l, (struct sadb_ext *)&m_addr, 1125 sizeof(m_addr), (caddr_t)sa, salen); 1126 1127 msg->sadb_msg_len = PFKEY_UNIT64(l); 1128 1129 sendkeymsg(buf, l); 1130 1131 n++; 1132 } 1133 } 1134 1135 if (n == 0) 1136 return -1; 1137 else 1138 return 0; |
852} 853 854static struct addrinfo * | 1139} 1140 1141static struct addrinfo * |
855parse_addr(host, port, flag) | 1142parse_addr(host, port) |
856 char *host; 857 char *port; | 1143 char *host; 1144 char *port; |
858 int flag; | |
859{ 860 struct addrinfo hints, *res = NULL; 861 int error; 862 863 memset(&hints, 0, sizeof(hints)); | 1145{ 1146 struct addrinfo hints, *res = NULL; 1147 int error; 1148 1149 memset(&hints, 0, sizeof(hints)); |
864 hints.ai_family = PF_UNSPEC; 865 hints.ai_socktype = SOCK_DGRAM; 866 hints.ai_flags = flag; | 1150 hints.ai_family = p_aifamily; 1151 hints.ai_socktype = SOCK_DGRAM; /*dummy*/ 1152 hints.ai_protocol = IPPROTO_UDP; /*dummy*/ 1153 hints.ai_flags = p_aiflags; |
867 error = getaddrinfo(host, port, &hints, &res); 868 if (error != 0) { 869 yyerror(gai_strerror(error)); 870 return NULL; 871 } | 1154 error = getaddrinfo(host, port, &hints, &res); 1155 if (error != 0) { 1156 yyerror(gai_strerror(error)); 1157 return NULL; 1158 } |
872 if (res->ai_next != NULL) { 873 yyerror(gai_strerror(error)); 874 } | |
875 return res; 876} 877 878static int | 1159 return res; 1160} 1161 1162static int |
879setvarbuf(off, ebuf, elen, vbuf, vlen) 880 caddr_t vbuf; | 1163fix_portstr(spec, sport, dport) 1164 vchar_t *spec, *sport, *dport; 1165{ 1166 char *p, *p2; 1167 u_int l; 1168 1169 l = 0; 1170 for (p = spec->buf; *p != ',' && *p != '\0' && l < spec->len; p++, l++) 1171 ; 1172 if (*p == '\0') { 1173 p2 = "0"; 1174 } else { 1175 if (*p == ',') { 1176 *p = '\0'; 1177 p2 = ++p; 1178 } 1179 for (p = p2; *p != '\0' && l < spec->len; p++, l++) 1180 ; 1181 if (*p != '\0' || *p2 == '\0') { 1182 yyerror("invalid an upper layer protocol spec"); 1183 return -1; 1184 } 1185 } 1186 1187 sport->buf = strdup(spec->buf); 1188 if (!sport->buf) { 1189 yyerror("insufficient memory"); 1190 return -1; 1191 } 1192 sport->len = strlen(sport->buf); 1193 dport->buf = strdup(p2); 1194 if (!dport->buf) { 1195 yyerror("insufficient memory"); 1196 return -1; 1197 } 1198 dport->len = strlen(dport->buf); 1199 1200 return 0; 1201} 1202 1203static int 1204setvarbuf(buf, off, ebuf, elen, vbuf, vlen) 1205 char *buf; 1206 int *off; |
881 struct sadb_ext *ebuf; | 1207 struct sadb_ext *ebuf; |
882 int *off, elen, vlen; | 1208 int elen; 1209 caddr_t vbuf; 1210 int vlen; |
883{ | 1211{ |
884 memset(m_buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len)); 885 memcpy(m_buf + *off, (caddr_t)ebuf, elen); 886 memcpy(m_buf + *off + elen, vbuf, vlen); | 1212 memset(buf + *off, 0, PFKEY_UNUNIT64(ebuf->sadb_ext_len)); 1213 memcpy(buf + *off, (caddr_t)ebuf, elen); 1214 memcpy(buf + *off + elen, vbuf, vlen); |
887 (*off) += PFKEY_ALIGN8(elen + vlen); 888 889 return 0; 890} 891 892void 893parse_init() 894{ | 1215 (*off) += PFKEY_ALIGN8(elen + vlen); 1216 1217 return 0; 1218} 1219 1220void 1221parse_init() 1222{ |
895 p_type = 0; | |
896 p_spi = 0; | 1223 p_spi = 0; |
897 p_no_spi = 0; | |
898 | 1224 |
899 p_src = 0, p_dst = 0; 900 pp_prefix = p_prefs = p_prefd = ~0; 901 pp_port = IPSEC_PORT_ANY; 902 p_upper = 0; 903 904 p_satype = 0; | |
905 p_ext = SADB_X_EXT_CYCSEQ; 906 p_alg_enc = SADB_EALG_NONE; 907 p_alg_auth = SADB_AALG_NONE; 908 p_mode = IPSEC_MODE_ANY; 909 p_reqid = 0; 910 p_replay = 0; 911 p_key_enc_len = p_key_auth_len = 0; 912 p_key_enc = p_key_auth = 0; 913 p_lt_hard = p_lt_soft = 0; 914 | 1225 p_ext = SADB_X_EXT_CYCSEQ; 1226 p_alg_enc = SADB_EALG_NONE; 1227 p_alg_auth = SADB_AALG_NONE; 1228 p_mode = IPSEC_MODE_ANY; 1229 p_reqid = 0; 1230 p_replay = 0; 1231 p_key_enc_len = p_key_auth_len = 0; 1232 p_key_enc = p_key_auth = 0; 1233 p_lt_hard = p_lt_soft = 0; 1234 |
915 p_policy_len = 0; 916 p_policy = NULL; | 1235 p_aiflags = 0; 1236 p_aifamily = PF_UNSPEC; |
917 | 1237 |
918 memset(cmdarg, 0, sizeof(cmdarg)); 919 | |
920 return; 921} 922 923void 924free_buffer() 925{ | 1238 return; 1239} 1240 1241void 1242free_buffer() 1243{ |
926 if (p_src) free(p_src); 927 if (p_dst) free(p_dst); 928 if (p_key_enc) free(p_key_enc); 929 if (p_key_auth) free(p_key_auth); | 1244 /* we got tons of memory leaks in the parser anyways, leave them */ |
930 931 return; 932} | 1245 1246 return; 1247} |
933 | |