* create secpolicy structure from sadb_x_policy structure. * NOTE: `state', `secpolicyindex' and 'id' in secpolicy structure * are not set, so must be set properly later. */
| 1471 | * are not set, so must be set properly later. |
| 1472 | */ |
| 1473 | struct secpolicy * |
| 1474 | key_msg2sp(struct sadb_x_policy *xpl0, size_t len, int *error) |
| 1475 | { |
| 1476 | struct secpolicy *newsp; |
| 1477 | |
| 1478 | IPSEC_ASSERT(xpl0 != NULL, ("null xpl0")); |
| 1479 | IPSEC_ASSERT(len >= sizeof(*xpl0), ("policy too short: %zu", len)); |
| 1480 | |
| 1481 | if (len != PFKEY_EXTLEN(xpl0)) { |
| 1482 | ipseclog((LOG_DEBUG, "%s: Invalid msg length.\n", __func__)); |
| 1483 | *error = EINVAL; |
| 1484 | return NULL; |
| 1485 | } |
| 1486 | |
| 1487 | if ((newsp = key_newsp()) == NULL) { |
| 1488 | *error = ENOBUFS; |
| 1489 | return NULL; |
| 1490 | } |
| 1491 | |
| 1492 | newsp->spidx.dir = xpl0->sadb_x_policy_dir; |
| 1493 | newsp->policy = xpl0->sadb_x_policy_type; |
| 1494 | newsp->priority = xpl0->sadb_x_policy_priority; |
| 1495 | newsp->tcount = 0; |
| 1496 | |
| 1497 | /* check policy */ |
| 1498 | switch (xpl0->sadb_x_policy_type) { |
| 1499 | case IPSEC_POLICY_DISCARD: |
| 1500 | case IPSEC_POLICY_NONE: |
| 1501 | case IPSEC_POLICY_ENTRUST: |
| 1502 | case IPSEC_POLICY_BYPASS: |
| 1503 | break; |
| 1504 | |
| 1505 | case IPSEC_POLICY_IPSEC: |
| 1506 | { |
| 1507 | struct sadb_x_ipsecrequest *xisr; |
| 1508 | struct ipsecrequest *isr; |
| 1509 | int tlen; |
| 1510 | |
| 1511 | /* validity check */ |
| 1512 | if (PFKEY_EXTLEN(xpl0) < sizeof(*xpl0)) { |
| 1513 | ipseclog((LOG_DEBUG, "%s: Invalid msg length.\n", |
| 1514 | __func__)); |
| 1515 | key_freesp(&newsp); |
| 1516 | *error = EINVAL; |
| 1517 | return NULL; |
| 1518 | } |
| 1519 | |
| 1520 | tlen = PFKEY_EXTLEN(xpl0) - sizeof(*xpl0); |
| 1521 | xisr = (struct sadb_x_ipsecrequest *)(xpl0 + 1); |
| 1522 | |
| 1523 | while (tlen > 0) { |
| 1524 | /* length check */ |
| 1525 | if (xisr->sadb_x_ipsecrequest_len < sizeof(*xisr) || |
| 1526 | xisr->sadb_x_ipsecrequest_len > tlen) { |
| 1527 | ipseclog((LOG_DEBUG, "%s: invalid ipsecrequest " |
| 1528 | "length.\n", __func__)); |
| 1529 | key_freesp(&newsp); |
| 1530 | *error = EINVAL; |
no test coverage detected