Print this page
Current snapshot of OpenSolaris port.
Checkpoint
Checkpoint
Merge from parent.
Merge with WIDE update.
Pull from WIDE.
Pull from WIDE.
Checkpoint
Re-update.
blah
WIDE update
Update from WIDE.


  39 #  include <time.h>
  40 #else
  41 #  if HAVE_SYS_TIME_H
  42 #    include <sys/time.h>
  43 #  else
  44 #    include <time.h>
  45 #  endif
  46 #endif
  47 #include <sys/socket.h>
  48 #include <sys/errno.h>
  49 
  50 #include <netinet/in.h>
  51 #include <netdb.h>
  52 
  53 #ifdef HAVE_NETINET6_IPSEC_H
  54 # include <netinet6/ipsec.h>
  55 #else
  56 # ifdef HAVE_NETIPSEC_IPSEC_H
  57 #  include <netipsec/ipsec.h>
  58 # else

  59 #  include <linux/ipsec.h>
  60 # endif

  61 #endif
  62 




  63 #include "racoon.h"
  64 
  65 #include "isakmp.h"
  66 #include "ikev2.h"
  67 #include "keyed_hash.h"
  68 #include "isakmp_impl.h"
  69 #include "ikev1_impl.h"
  70 #include "ipsec_doi.h"
  71 #include "isakmp_ident.h"
  72 /* #include "isakmp_agg.h" */
  73 /* #include "isakmp_base.h" */
  74 #include "isakmp_quick.h"
  75 #include "isakmp_inf.h"
  76 #include "vendorid.h"
  77 #include "pfkey.h"
  78 #ifdef ENABLE_NATT
  79 #  include "ikev1_natt.h"
  80 #endif
  81 
  82 #include "var.h"


 292 
 293 #ifdef ENABLE_NATT
 294                 /* Floating ports for NAT-T */
 295                 if (NATT_AVAILABLE(iph1) &&
 296                     !(iph1->natt_flags & NAT_PORTS_CHANGED) &&
 297                     ((rcs_cmpsa(iph1->remote, remote) != 0) ||
 298                     (rcs_cmpsa(iph1->local, local) != 0))) {
 299                         /* prevent memory leak */
 300                         racoon_free(iph1->remote);
 301                         racoon_free(iph1->local);
 302 
 303                         /* copy-in new addresses */
 304                         iph1->remote = rcs_sadup(remote);
 305                         iph1->local = rcs_sadup(local);
 306 
 307                         /*
 308                          * set the flag to prevent further port floating.
 309                          * (FIXME: should we allow it? E.g. when the NAT gw 
 310                          * is rebooted?)
 311                          */



 312                         iph1->natt_flags |= NAT_PORTS_CHANGED | NAT_ADD_NON_ESP_MARKER;

 313                 }
 314 #endif
 315 
 316                 /* must be same addresses in one stream of a phase at least. */
 317                 if (rcs_cmpsa(iph1->remote, remote) != 0) {
 318                         char *saddr_db, *saddr_act;
 319 
 320                         saddr_db = strdup(rcs_sa2str(iph1->remote));
 321                         saddr_act = strdup(rcs_sa2str(remote));
 322 
 323                         plog(PLOG_PROTOWARN, PLOGLOC, 0,
 324                              "remote address mismatched. db=%s, act=%s\n",
 325                              saddr_db, saddr_act);
 326 
 327                         racoon_free(saddr_db);
 328                         racoon_free(saddr_act);
 329                 }
 330                 /*
 331                  * don't check of exchange type here because other type will be
 332                  * with same index, for example, informational exchange.


 818                         return 0;
 819                 isakmp_info_send_n1(iph2->ph1, error, NULL);
 820                 return -1;
 821         }
 822 
 823         /* when using commit bit, status will be reached here. */
 824         if (iph2->status == PHASE2ST_ADDSA)
 825                 return 0;
 826 
 827         /* free resend buffer */
 828         if (iph2->sendbuf == NULL) {
 829                 plog(PLOG_INTERR, PLOGLOC, NULL, "no buffer found as sendbuf\n");
 830                 return -1;
 831         }
 832         VPTRINIT(iph2->sendbuf);
 833 
 834         /* turn off schedule */
 835         if (iph2->scr)
 836                 SCHED_KILL(iph2->scr);
 837 






 838         /* send */
 839         plog(PLOG_DEBUG, PLOGLOC, NULL, "===\n");
 840         if ((ph2exchange[etypesw2(isakmp->etype)]
 841              [iph2->side]
 842              [iph2->status]) (iph2, msg) != 0) {
 843                 plog(PLOG_PROTOERR, PLOGLOC, 0,
 844                      "failed to process packet.\n");
 845                 return -1;
 846         }
 847 #ifdef ENABLE_STATS
 848         gettimeofday(&end, NULL);
 849         syslog(LOG_NOTICE, "%s(%s): %8.6f",
 850                "phase2",
 851                s_isakmp_state(ISAKMP_ETYPE_QUICK, iph2->side, iph2->status),
 852                timedelta(&start, &end));
 853 #endif
 854 
 855         return 0;
 856 }
 857 


1119 #ifdef ENABLE_STATS
1120         gettimeofday(&iph2->start, NULL);
1121 #endif
1122         /* found isakmp-sa */
1123         bindph12(iph1, iph2);
1124         iph2->status = PHASE2ST_STATUS2;
1125 
1126         if ((ph2exchange[etypesw2(ISAKMP_ETYPE_QUICK)]
1127              [iph2->side]
1128              [iph2->status]) (iph2, NULL) < 0) {
1129                 /* release ipsecsa handler due to internal error. */
1130                 plog(PLOG_INTERR, PLOGLOC, 0,
1131                      "failed to initiate phase 2 negotiation for %s\n",
1132                      rcs_sa2str_wop(iph2->dst));
1133                 isakmp_fail_initiate_ph2(iph2);
1134                 return;
1135         }
1136         return;
1137 }
1138 

































































1139 /* new negotiation of phase 2 for responder */
1140 static int
1141 isakmp_ph2begin_r(struct ph1handle *iph1, rc_vchar_t *msg)
1142 {
1143         struct isakmp *isakmp = (struct isakmp *)msg->v;
1144         struct ph2handle *iph2 = 0;
1145         int error;
1146 #ifdef ENABLE_STATS
1147         struct timeval start, end;
1148 #endif
1149         extern struct sadb_response_method ikev1_sadb_callback;
1150 
1151         iph2 = newph2();
1152         if (iph2 == NULL) {
1153                 plog(PLOG_INTERR, PLOGLOC, NULL,
1154                      "failed to allocate phase2 entry.\n");
1155                 return -1;
1156         }
1157 
1158         iph2->ph1 = iph1;


1189 
1190         /* add new entry to isakmp status table */
1191         insph2(iph2);
1192         bindph12(iph1, iph2);
1193 
1194         plog(PLOG_DEBUG, PLOGLOC, NULL, "===\n");
1195         {
1196                 char *a;
1197 
1198                 a = strdup(rcs_sa2str(iph2->src));
1199                 plog(PLOG_INFO, PLOGLOC, NULL,
1200                      "respond new phase 2 negotiation: %s<=>%s\n",
1201                      a, rcs_sa2str(iph2->dst));
1202                 racoon_free(a);
1203         }
1204 
1205 #ifdef ENABLE_STATS
1206         gettimeofday(&start, NULL);
1207 #endif
1208 

1209         error = (ph2exchange[etypesw2(ISAKMP_ETYPE_QUICK)]
1210                  [iph2->side]
1211                  [iph2->status]) (iph2, msg);
1212         if (error != 0) {
1213                 plog(PLOG_INTERR, PLOGLOC, 0,
1214                      "failed to pre-process packet.\n");
1215                 if (error != ISAKMP_INTERNAL_ERROR)
1216                         isakmp_info_send_n1(iph2->ph1, error, NULL);
1217                 /*
1218                  * release handler because it's wrong that ph2handle is kept
1219                  * after failed to check message for responder's.
1220                  */
1221                 unbindph12(iph2);
1222                 remph2(iph2);
1223                 delph2(iph2);
1224                 return -1;
1225         }
1226 



























1227         /* send */
1228         plog(PLOG_DEBUG, PLOGLOC, NULL, "===\n");
1229         if ((ph2exchange[etypesw2(isakmp->etype)]
1230              [iph2->side]
1231              [iph2->status]) (iph2, msg) < 0) {
1232                 plog(PLOG_PROTOERR, PLOGLOC, 0,
1233                      "failed to process packet.\n");
1234                 /* don't release handler */
1235                 return -1;
1236         }
1237 #ifdef ENABLE_STATS
1238         gettimeofday(&end, NULL);
1239         syslog(LOG_NOTICE, "%s(%s): %8.6f",
1240                "phase2",
1241                s_isakmp_state(ISAKMP_ETYPE_QUICK, iph2->side, iph2->status),
1242                timedelta(&start, &end));
1243 #endif

1244 
1245         return 0;
1246 }
1247 
1248 /* called from scheduler */
1249 static void
1250 isakmp_ph1resend_stub(void *p)
1251 {
1252         (void)isakmp_ph1resend((struct ph1handle *)p);
1253 }
1254 
1255 int
1256 isakmp_ph1resend(struct ph1handle *iph1)
1257 {
1258         if (iph1->retry_counter < 0) {
1259                 plog(PLOG_PROTOERR, PLOGLOC, NULL,
1260                      "phase1 negotiation failed due to time up (index %s).\n",
1261                      isakmp_pindex(&iph1->index, iph1->msgid));
1262 
1263                 remph1(iph1);




  39 #  include <time.h>
  40 #else
  41 #  if HAVE_SYS_TIME_H
  42 #    include <sys/time.h>
  43 #  else
  44 #    include <time.h>
  45 #  endif
  46 #endif
  47 #include <sys/socket.h>
  48 #include <sys/errno.h>
  49 
  50 #include <netinet/in.h>
  51 #include <netdb.h>
  52 
  53 #ifdef HAVE_NETINET6_IPSEC_H
  54 # include <netinet6/ipsec.h>
  55 #else
  56 # ifdef HAVE_NETIPSEC_IPSEC_H
  57 #  include <netipsec/ipsec.h>
  58 # else
  59 #  ifndef sun   /* XXX KEBE SAYS OpenSolaris */
  60 #    include <linux/ipsec.h>
  61 #  endif
  62 # endif
  63 #endif
  64 
  65 #ifdef sun      /* XXX KEBE SAYS OpenSolaris */
  66 #define IPSEC_ULPROTO_ANY 0
  67 #endif
  68 
  69 #include "racoon.h"
  70 
  71 #include "isakmp.h"
  72 #include "ikev2.h"
  73 #include "keyed_hash.h"
  74 #include "isakmp_impl.h"
  75 #include "ikev1_impl.h"
  76 #include "ipsec_doi.h"
  77 #include "isakmp_ident.h"
  78 /* #include "isakmp_agg.h" */
  79 /* #include "isakmp_base.h" */
  80 #include "isakmp_quick.h"
  81 #include "isakmp_inf.h"
  82 #include "vendorid.h"
  83 #include "pfkey.h"
  84 #ifdef ENABLE_NATT
  85 #  include "ikev1_natt.h"
  86 #endif
  87 
  88 #include "var.h"


 298 
 299 #ifdef ENABLE_NATT
 300                 /* Floating ports for NAT-T */
 301                 if (NATT_AVAILABLE(iph1) &&
 302                     !(iph1->natt_flags & NAT_PORTS_CHANGED) &&
 303                     ((rcs_cmpsa(iph1->remote, remote) != 0) ||
 304                     (rcs_cmpsa(iph1->local, local) != 0))) {
 305                         /* prevent memory leak */
 306                         racoon_free(iph1->remote);
 307                         racoon_free(iph1->local);
 308 
 309                         /* copy-in new addresses */
 310                         iph1->remote = rcs_sadup(remote);
 311                         iph1->local = rcs_sadup(local);
 312 
 313                         /*
 314                          * set the flag to prevent further port floating.
 315                          * (FIXME: should we allow it? E.g. when the NAT gw 
 316                          * is rebooted?)
 317                          */
 318 #ifdef sun
 319                         iph1->natt_flags |= NAT_PORTS_CHANGED;
 320 #else
 321                         iph1->natt_flags |= NAT_PORTS_CHANGED | NAT_ADD_NON_ESP_MARKER;
 322 #endif
 323                 }
 324 #endif
 325 
 326                 /* must be same addresses in one stream of a phase at least. */
 327                 if (rcs_cmpsa(iph1->remote, remote) != 0) {
 328                         char *saddr_db, *saddr_act;
 329 
 330                         saddr_db = strdup(rcs_sa2str(iph1->remote));
 331                         saddr_act = strdup(rcs_sa2str(remote));
 332 
 333                         plog(PLOG_PROTOWARN, PLOGLOC, 0,
 334                              "remote address mismatched. db=%s, act=%s\n",
 335                              saddr_db, saddr_act);
 336 
 337                         racoon_free(saddr_db);
 338                         racoon_free(saddr_act);
 339                 }
 340                 /*
 341                  * don't check of exchange type here because other type will be
 342                  * with same index, for example, informational exchange.


 828                         return 0;
 829                 isakmp_info_send_n1(iph2->ph1, error, NULL);
 830                 return -1;
 831         }
 832 
 833         /* when using commit bit, status will be reached here. */
 834         if (iph2->status == PHASE2ST_ADDSA)
 835                 return 0;
 836 
 837         /* free resend buffer */
 838         if (iph2->sendbuf == NULL) {
 839                 plog(PLOG_INTERR, PLOGLOC, NULL, "no buffer found as sendbuf\n");
 840                 return -1;
 841         }
 842         VPTRINIT(iph2->sendbuf);
 843 
 844         /* turn off schedule */
 845         if (iph2->scr)
 846                 SCHED_KILL(iph2->scr);
 847 
 848 #ifdef sun
 849         /* Bail now to await inverse-ACQUIRE response. */
 850         if (iph2->status == PHASE2ST_START && iph2->side == RESPONDER)
 851                 return (0);
 852 #endif /* sun/OpenSolaris */
 853 
 854         /* send */
 855         plog(PLOG_DEBUG, PLOGLOC, NULL, "===\n");
 856         if ((ph2exchange[etypesw2(isakmp->etype)]
 857              [iph2->side]
 858              [iph2->status]) (iph2, msg) != 0) {
 859                 plog(PLOG_PROTOERR, PLOGLOC, 0,
 860                      "failed to process packet.\n");
 861                 return -1;
 862         }
 863 #ifdef ENABLE_STATS
 864         gettimeofday(&end, NULL);
 865         syslog(LOG_NOTICE, "%s(%s): %8.6f",
 866                "phase2",
 867                s_isakmp_state(ISAKMP_ETYPE_QUICK, iph2->side, iph2->status),
 868                timedelta(&start, &end));
 869 #endif
 870 
 871         return 0;
 872 }
 873 


1135 #ifdef ENABLE_STATS
1136         gettimeofday(&iph2->start, NULL);
1137 #endif
1138         /* found isakmp-sa */
1139         bindph12(iph1, iph2);
1140         iph2->status = PHASE2ST_STATUS2;
1141 
1142         if ((ph2exchange[etypesw2(ISAKMP_ETYPE_QUICK)]
1143              [iph2->side]
1144              [iph2->status]) (iph2, NULL) < 0) {
1145                 /* release ipsecsa handler due to internal error. */
1146                 plog(PLOG_INTERR, PLOGLOC, 0,
1147                      "failed to initiate phase 2 negotiation for %s\n",
1148                      rcs_sa2str_wop(iph2->dst));
1149                 isakmp_fail_initiate_ph2(iph2);
1150                 return;
1151         }
1152         return;
1153 }
1154 
1155 #ifdef sun
1156 static int
1157 isakmp_ph2_inv_acquire(invacq_t *invacq)
1158 {
1159         struct ph2handle *iph2 = invacq->iph2;
1160         struct rcpfk_msg *param = invacq->answer;
1161         struct isakmp *isakmp = (struct isakmp *)iph2->msg1->v;
1162 
1163         sadb_request_finish(&invacq->request);
1164         free(invacq);
1165 
1166         /* 
1167          * Initialize iph2->selector, iph2->proposal, and iph2-> with the results of an
1168          * inverse-ACQUIRE.
1169          *
1170          * XXX KEBE SAYS -- We need a way to figure out a p2_pfs equivalent
1171          * for racoon2.  We store this in Phase I/PAD state in in.iked.
1172          */
1173 
1174         /* Then send the Quick Mode reply. */
1175         /* assert(iph2->status == PHASE2ST_STATUS2); */
1176 
1177         /* change status of isakmp status entry */
1178         iph2->status = PHASE2ST_STATUS2;
1179 
1180         if (extract_extended_acquire(param, &iph2->selector, NULL) != 0) {
1181                 /* XXX KEBE SAYS MORE ERROR HANDLING? */
1182                 return (-1);
1183         }
1184 
1185         /* XXX KEBE SAYS FILL ME IN XXX */
1186 
1187         if (set_proposal_from_policy(iph2, iph2->ph1->rmconf,
1188             iph2->selector->pl) != 0) {
1189                 /* XXX KEBE SAYS MORE ERROR HANDLING? */
1190                 return (-1);
1191         }
1192 
1193         if (ipsecdoi_selectph2proposal(iph2) < 0) {
1194                 /* XXX KEBE SAYS MORE ERROR HANDLING?  PROPER RETURN? */
1195                 isakmp_info_send_n1(iph2->ph1, ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN,
1196                     NULL);
1197                 return (-1);
1198         }
1199 
1200         /* The following was moved here from quick_main(). */
1201         plog(PLOG_DEBUG, PLOGLOC, NULL, "===\n");
1202         if ((ph2exchange[etypesw2(isakmp->etype)]
1203              [iph2->side]
1204              [iph2->status]) (iph2, iph2->msg1) < 0) {
1205                 plog(PLOG_PROTOERR, PLOGLOC, 0,
1206                      "failed to process packet.\n");
1207                 /* don't release handler */
1208                 return -1;
1209         }
1210 #ifdef ENABLE_STATS
1211         gettimeofday(&end, NULL);
1212         syslog(LOG_NOTICE, "%s(%s): %8.6f",
1213                "phase2",
1214                s_isakmp_state(ISAKMP_ETYPE_QUICK, iph2->side, iph2->status),
1215                timedelta(&start, &end));
1216 #endif
1217 }
1218 #endif
1219 
1220 /* new negotiation of phase 2 for responder */
1221 static int
1222 isakmp_ph2begin_r(struct ph1handle *iph1, rc_vchar_t *msg)
1223 {
1224         struct isakmp *isakmp = (struct isakmp *)msg->v;
1225         struct ph2handle *iph2 = 0;
1226         int error;
1227 #ifdef ENABLE_STATS
1228         struct timeval start, end;
1229 #endif
1230         extern struct sadb_response_method ikev1_sadb_callback;
1231 
1232         iph2 = newph2();
1233         if (iph2 == NULL) {
1234                 plog(PLOG_INTERR, PLOGLOC, NULL,
1235                      "failed to allocate phase2 entry.\n");
1236                 return -1;
1237         }
1238 
1239         iph2->ph1 = iph1;


1270 
1271         /* add new entry to isakmp status table */
1272         insph2(iph2);
1273         bindph12(iph1, iph2);
1274 
1275         plog(PLOG_DEBUG, PLOGLOC, NULL, "===\n");
1276         {
1277                 char *a;
1278 
1279                 a = strdup(rcs_sa2str(iph2->src));
1280                 plog(PLOG_INFO, PLOGLOC, NULL,
1281                      "respond new phase 2 negotiation: %s<=>%s\n",
1282                      a, rcs_sa2str(iph2->dst));
1283                 racoon_free(a);
1284         }
1285 
1286 #ifdef ENABLE_STATS
1287         gettimeofday(&start, NULL);
1288 #endif
1289 
1290 
1291         error = (ph2exchange[etypesw2(ISAKMP_ETYPE_QUICK)]
1292                  [iph2->side]
1293                  [iph2->status]) (iph2, msg);
1294         if (error != 0) {
1295                 plog(PLOG_INTERR, PLOGLOC, 0,
1296                      "failed to pre-process packet.\n");
1297                 if (error != ISAKMP_INTERNAL_ERROR)
1298                         isakmp_info_send_n1(iph2->ph1, error, NULL);
1299                 /*
1300                  * release handler because it's wrong that ph2handle is kept
1301                  * after failed to check message for responder's.
1302                  */
1303                 unbindph12(iph2);
1304                 remph2(iph2);
1305                 delph2(iph2);
1306                 return -1;
1307         }
1308 
1309 #ifdef sun
1310         /* XXX KEBE ASKS - how do you insert inverse-ACQUIRE here? */
1311 
1312         /* Assume iph2->msg1 contains a copy of "msg" we passed-in. */
1313         {
1314                 invacq_t *invacq = malloc(sizeof (*invacq));
1315                 uint32_t newseq = sadb_new_seq();
1316 
1317                 /*
1318                  * Use newseq to avoid using iph2's, which already has a
1319                  * record via a previous sadb_request_initalize() call.
1320                  */
1321 
1322                 if (invacq == NULL)
1323                         return (-1);
1324 
1325                 invacq->iph2 = iph2;
1326                 sadb_request_initialize(&invacq->request,
1327                     NULL /* KEBE - reqmethod */, NULL /* KEBE - respmethod */,
1328                     newseq, invacq);
1329                 invacq->receiver = isakmp_ph2_inv_acquire;
1330 
1331                 /* Okay, now we send the inverse-ACQUIRE itself. */
1332                 /* XXX KEBE SAYS CODE ME */
1333                 ikev1_send_inverse_acquire(iph2, newseq);
1334         }
1335 #else
1336         /* send */
1337         plog(PLOG_DEBUG, PLOGLOC, NULL, "===\n");
1338         if ((ph2exchange[etypesw2(isakmp->etype)]
1339              [iph2->side]
1340              [iph2->status]) (iph2, msg) < 0) {
1341                 plog(PLOG_PROTOERR, PLOGLOC, 0,
1342                      "failed to process packet.\n");
1343                 /* don't release handler */
1344                 return -1;
1345         }
1346 #ifdef ENABLE_STATS
1347         gettimeofday(&end, NULL);
1348         syslog(LOG_NOTICE, "%s(%s): %8.6f",
1349                "phase2",
1350                s_isakmp_state(ISAKMP_ETYPE_QUICK, iph2->side, iph2->status),
1351                timedelta(&start, &end));
1352 #endif
1353 #endif /* sun/OpenSolaris */
1354 
1355         return 0;
1356 }
1357 
1358 /* called from scheduler */
1359 static void
1360 isakmp_ph1resend_stub(void *p)
1361 {
1362         (void)isakmp_ph1resend((struct ph1handle *)p);
1363 }
1364 
1365 int
1366 isakmp_ph1resend(struct ph1handle *iph1)
1367 {
1368         if (iph1->retry_counter < 0) {
1369                 plog(PLOG_PROTOERR, PLOGLOC, NULL,
1370                      "phase1 negotiation failed due to time up (index %s).\n",
1371                      isakmp_pindex(&iph1->index, iph1->msgid));
1372 
1373                 remph1(iph1);