| 3184 | } |
| 3185 | |
| 3186 | static int |
| 3187 | key_updatelifetimes(struct secasvar *sav, const struct sadb_msghdr *mhp) |
| 3188 | { |
| 3189 | struct seclifetime *lft_h, *lft_s, *tmp; |
| 3190 | |
| 3191 | /* Lifetime extension is optional, check that it is present. */ |
| 3192 | if (SADB_CHECKHDR(mhp, SADB_EXT_LIFETIME_HARD) && |
| 3193 | SADB_CHECKHDR(mhp, SADB_EXT_LIFETIME_SOFT)) { |
| 3194 | /* |
| 3195 | * In case of SADB_UPDATE we may need to change |
| 3196 | * existing lifetimes. |
| 3197 | */ |
| 3198 | if (sav->state == SADB_SASTATE_MATURE) { |
| 3199 | lft_h = lft_s = NULL; |
| 3200 | goto reset; |
| 3201 | } |
| 3202 | return (0); |
| 3203 | } |
| 3204 | /* Both HARD and SOFT extensions must present */ |
| 3205 | if ((SADB_CHECKHDR(mhp, SADB_EXT_LIFETIME_HARD) && |
| 3206 | !SADB_CHECKHDR(mhp, SADB_EXT_LIFETIME_SOFT)) || |
| 3207 | (SADB_CHECKHDR(mhp, SADB_EXT_LIFETIME_SOFT) && |
| 3208 | !SADB_CHECKHDR(mhp, SADB_EXT_LIFETIME_HARD))) { |
| 3209 | ipseclog((LOG_DEBUG, |
| 3210 | "%s: invalid message: missing required header.\n", |
| 3211 | __func__)); |
| 3212 | return (EINVAL); |
| 3213 | } |
| 3214 | if (SADB_CHECKLEN(mhp, SADB_EXT_LIFETIME_HARD) || |
| 3215 | SADB_CHECKLEN(mhp, SADB_EXT_LIFETIME_SOFT)) { |
| 3216 | ipseclog((LOG_DEBUG, |
| 3217 | "%s: invalid message: wrong header size.\n", __func__)); |
| 3218 | return (EINVAL); |
| 3219 | } |
| 3220 | lft_h = key_dup_lifemsg((const struct sadb_lifetime *) |
| 3221 | mhp->ext[SADB_EXT_LIFETIME_HARD], M_IPSEC_MISC); |
| 3222 | if (lft_h == NULL) { |
| 3223 | PFKEYSTAT_INC(in_nomem); |
| 3224 | ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__)); |
| 3225 | return (ENOBUFS); |
| 3226 | } |
| 3227 | lft_s = key_dup_lifemsg((const struct sadb_lifetime *) |
| 3228 | mhp->ext[SADB_EXT_LIFETIME_SOFT], M_IPSEC_MISC); |
| 3229 | if (lft_s == NULL) { |
| 3230 | PFKEYSTAT_INC(in_nomem); |
| 3231 | free(lft_h, M_IPSEC_MISC); |
| 3232 | ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__)); |
| 3233 | return (ENOBUFS); |
| 3234 | } |
| 3235 | reset: |
| 3236 | if (sav->state != SADB_SASTATE_LARVAL) { |
| 3237 | /* |
| 3238 | * key_update() holds reference to this SA, |
| 3239 | * so it won't be deleted in meanwhile. |
| 3240 | */ |
| 3241 | SECASVAR_LOCK(sav); |
| 3242 | tmp = sav->lft_h; |
| 3243 | sav->lft_h = lft_h; |
no test coverage detected