Changeset 3106 for pjproject/trunk/pjsip/src/pjsip/sip_transport_tls.c
- Timestamp:
- Feb 24, 2010 5:43:34 AM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip/src/pjsip/sip_transport_tls.c
r3039 r3106 25 25 #include <pj/ssl_sock.h> 26 26 #include <pj/assert.h> 27 #include <pj/hash.h> 27 28 #include <pj/lock.h> 28 29 #include <pj/log.h> … … 81 82 pjsip_transport base; 82 83 pj_bool_t is_server; 84 pj_str_t remote_name; 83 85 84 86 pj_bool_t is_registered; … … 87 89 pj_ssl_sock_t *ssock; 88 90 pj_bool_t has_pending_connect; 91 pj_bool_t verify_server; 89 92 90 93 /* Keep-alive timer. */ … … 136 139 const pj_sockaddr *rem_addr, 137 140 int addr_len, 141 pjsip_tx_data *tdata, 138 142 pjsip_transport **transport); 139 143 … … 145 149 const pj_sockaddr_in *local, 146 150 const pj_sockaddr_in *remote, 151 const pj_str_t *remote_name, 147 152 struct tls_transport **p_tls); 148 153 … … 169 174 } 170 175 176 177 static void tls_init_shutdown(struct tls_transport *tls, pj_status_t status) 178 { 179 pjsip_tp_state_callback *state_cb; 180 181 if (tls->close_reason == PJ_SUCCESS) 182 tls->close_reason = status; 183 184 if (tls->base.is_shutdown) 185 return; 186 187 /* Notify application of transport disconnected state */ 188 state_cb = pjsip_tpmgr_get_status_cb(tls->base.tpmgr); 189 if (state_cb) { 190 pjsip_transport_state_info state_info; 191 192 pj_bzero(&state_info, sizeof(state_info)); 193 state_info.status = tls->close_reason; 194 (*state_cb)(&tls->base, PJSIP_TP_STATE_DISCONNECTED, &state_info); 195 } 196 197 /* We can not destroy the transport since high level objects may 198 * still keep reference to this transport. So we can only 199 * instruct transport manager to gracefully start the shutdown 200 * procedure for this transport. 201 */ 202 pjsip_transport_shutdown(&tls->base); 203 } 171 204 172 205 … … 244 277 ssock_param.ioqueue = pjsip_endpt_get_ioqueue(endpt); 245 278 ssock_param.require_client_cert = listener->tls_setting.require_client_cert; 246 ssock_param.server_name = listener->tls_setting.server_name;247 279 ssock_param.timeout = listener->tls_setting.timeout; 248 280 ssock_param.user_data = listener; 249 ssock_param.verify_peer = listener->tls_setting.verify_client; 281 ssock_param.verify_peer = PJ_FALSE; /* avoid SSL socket closing the socket 282 * due to verification error */ 250 283 if (ssock_param.send_buffer_size < PJSIP_MAX_PKT_LEN) 251 284 ssock_param.send_buffer_size = PJSIP_MAX_PKT_LEN; … … 372 405 listener->endpt = endpt; 373 406 listener->tpmgr = pjsip_endpt_get_tpmgr(endpt); 374 listener->factory.create_transport = lis_create_transport;407 listener->factory.create_transport2 = lis_create_transport; 375 408 listener->factory.destroy = lis_destroy; 376 409 listener->is_registered = PJ_TRUE; … … 481 514 const pj_sockaddr_in *local, 482 515 const pj_sockaddr_in *remote, 516 const pj_str_t *remote_name, 483 517 struct tls_transport **p_tls) 484 518 { … … 502 536 tls = PJ_POOL_ZALLOC_T(pool, struct tls_transport); 503 537 tls->is_server = is_server; 538 tls->verify_server = listener->tls_setting.verify_server; 504 539 pj_list_init(&tls->delayed_list); 505 540 tls->base.pool = pool; … … 518 553 } 519 554 555 if (remote_name) 556 pj_strdup(pool, &tls->remote_name, remote_name); 557 520 558 tls->base.key.type = PJSIP_TRANSPORT_TLS; 521 559 pj_memcpy(&tls->base.key.rem_addr, remote, sizeof(pj_sockaddr_in)); 560 tls->base.key.hname = pj_hash_calc_tolower(0, (char*)tls->remote_name.ptr, 561 &tls->remote_name); 522 562 tls->base.type_name = "tls"; 523 563 tls->base.flag = pjsip_transport_get_flag_from_type(PJSIP_TRANSPORT_TLS); … … 770 810 const pj_sockaddr *rem_addr, 771 811 int addr_len, 812 pjsip_tx_data *tdata, 772 813 pjsip_transport **p_transport) 773 814 { … … 778 819 pj_ssl_sock_param ssock_param; 779 820 pj_sockaddr_in local_addr; 821 pj_str_t remote_name; 780 822 pj_status_t status; 781 823 … … 794 836 POOL_TP_INIT, POOL_TP_INC); 795 837 PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM); 838 839 /* Get remote host name from tdata */ 840 if (tdata) 841 remote_name = tdata->dest_info.name; 842 else 843 pj_bzero(&remote_name, sizeof(remote_name)); 796 844 797 845 /* Build SSL socket param */ … … 802 850 ssock_param.async_cnt = 1; 803 851 ssock_param.ioqueue = pjsip_endpt_get_ioqueue(listener->endpt); 804 PJ_TODO(set_proper_servername_based_on_target);805 852 PJ_TODO(synchronize_tls_cipher_type_with_ssl_sock_cipher_type); 806 ssock_param.server_name = listener->tls_setting.server_name;853 ssock_param.server_name = remote_name; 807 854 ssock_param.timeout = listener->tls_setting.timeout; 808 855 ssock_param.user_data = NULL; /* pending, must be set later */ 809 ssock_param.verify_peer = listener->tls_setting.verify_server; 856 ssock_param.verify_peer = PJ_FALSE; /* avoid SSL socket closing the socket 857 * due to verification error */ 810 858 if (ssock_param.send_buffer_size < PJSIP_MAX_PKT_LEN) 811 859 ssock_param.send_buffer_size = PJSIP_MAX_PKT_LEN; … … 851 899 /* Create the transport descriptor */ 852 900 status = tls_create(listener, pool, ssock, PJ_FALSE, &local_addr, 853 (pj_sockaddr_in*)rem_addr, & tls);901 (pj_sockaddr_in*)rem_addr, &remote_name, &tls); 854 902 if (status != PJ_SUCCESS) 855 903 return status; … … 929 977 struct tls_listener *listener; 930 978 struct tls_transport *tls; 979 pj_ssl_sock_info ssl_info; 931 980 char addr[PJ_INET6_ADDRSTRLEN+10]; 932 981 pj_status_t status; 982 983 pjsip_tp_state_callback *state_cb; 984 pj_bool_t tls_verif_ignored; 933 985 934 986 PJ_UNUSED_ARG(src_addr_len); … … 947 999 new_ssock)); 948 1000 1001 /* Retrieve SSL socket info, close the socket if this is failed 1002 * as the SSL socket info availability is rather critical here. 1003 */ 1004 status = pj_ssl_sock_get_info(new_ssock, &ssl_info); 1005 if (status != PJ_SUCCESS) { 1006 pj_ssl_sock_close(new_ssock); 1007 return PJ_TRUE; 1008 } 1009 949 1010 /* 950 1011 * Incoming connection! … … 953 1014 status = tls_create( listener, NULL, new_ssock, PJ_TRUE, 954 1015 (const pj_sockaddr_in*)&listener->factory.local_addr, 955 (const pj_sockaddr_in*)src_addr, &tls);1016 (const pj_sockaddr_in*)src_addr, NULL, &tls); 956 1017 957 if (status == PJ_SUCCESS) { 958 /* Set the "pending" SSL socket user data */ 959 pj_ssl_sock_set_user_data(new_ssock, tls); 960 961 status = tls_start_read(tls); 962 if (status != PJ_SUCCESS) { 963 PJ_LOG(3,(tls->base.obj_name, "New transport cancelled")); 964 tls_destroy(&tls->base, status); 1018 if (status != PJ_SUCCESS) 1019 return PJ_TRUE; 1020 1021 /* Set the "pending" SSL socket user data */ 1022 pj_ssl_sock_set_user_data(new_ssock, tls); 1023 1024 tls_verif_ignored = !listener->tls_setting.verify_client; 1025 1026 /* Notify transport state to application */ 1027 state_cb = pjsip_tpmgr_get_status_cb(tls->base.tpmgr); 1028 if (state_cb) { 1029 pjsip_transport_state_info state_info; 1030 pjsip_tls_state_info tls_info; 1031 pj_uint32_t tp_state = 0; 1032 1033 /* Init transport state notification callback */ 1034 pj_bzero(&tls_info, sizeof(tls_info)); 1035 pj_bzero(&state_info, sizeof(state_info)); 1036 1037 /* Set transport state based on verification status */ 1038 if (ssl_info.verify_status) { 1039 state_info.status = PJSIP_TLS_EACCEPT; 1040 tp_state |= PJSIP_TP_STATE_TLS_VERIF_ERROR; 1041 if (listener->tls_setting.verify_client) 1042 tp_state |= PJSIP_TP_STATE_REJECTED; 1043 else 1044 tp_state |= PJSIP_TP_STATE_ACCEPTED; 965 1045 } else { 966 /* Start keep-alive timer */ 967 if (PJSIP_TCP_KEEP_ALIVE_INTERVAL) { 968 pj_time_val delay = {PJSIP_TCP_KEEP_ALIVE_INTERVAL, 0}; 969 pjsip_endpt_schedule_timer(listener->endpt, 970 &tls->ka_timer, 971 &delay); 972 tls->ka_timer.id = PJ_TRUE; 973 pj_gettimeofday(&tls->last_activity); 974 } 1046 tp_state |= PJSIP_TP_STATE_ACCEPTED; 1047 } 1048 1049 tls_info.ssl_sock_info = &ssl_info; 1050 state_info.ext_info = &tls_info; 1051 1052 tls_verif_ignored = (*state_cb)(&tls->base, tp_state, &state_info); 1053 } 1054 1055 /* Transport should be destroyed when there is TLS verification error 1056 * and application doesn't want to ignore it. 1057 */ 1058 if (ssl_info.verify_status && 1059 (listener->tls_setting.verify_client || !tls_verif_ignored)) 1060 { 1061 tls_destroy(&tls->base, PJSIP_TLS_EACCEPT); 1062 return PJ_TRUE; 1063 } 1064 1065 status = tls_start_read(tls); 1066 if (status != PJ_SUCCESS) { 1067 PJ_LOG(3,(tls->base.obj_name, "New transport cancelled")); 1068 tls_init_shutdown(tls, status); 1069 tls_destroy(&tls->base, status); 1070 } else { 1071 /* Start keep-alive timer */ 1072 if (PJSIP_TCP_KEEP_ALIVE_INTERVAL) { 1073 pj_time_val delay = {PJSIP_TCP_KEEP_ALIVE_INTERVAL, 0}; 1074 pjsip_endpt_schedule_timer(listener->endpt, 1075 &tls->ka_timer, 1076 &delay); 1077 tls->ka_timer.id = PJ_TRUE; 1078 pj_gettimeofday(&tls->last_activity); 975 1079 } 976 1080 } … … 1020 1124 status = (bytes_sent == 0) ? PJ_RETURN_OS_ERROR(OSERR_ENOTCONN) : 1021 1125 -bytes_sent; 1022 if (tls->close_reason==PJ_SUCCESS) tls->close_reason = status; 1023 pjsip_transport_shutdown(&tls->base);1126 1127 tls_init_shutdown(tls, status); 1024 1128 1025 1129 return PJ_FALSE; … … 1116 1220 if (status == PJ_SUCCESS) 1117 1221 status = PJ_RETURN_OS_ERROR(OSERR_ENOTCONN); 1118 if (tls->close_reason==PJ_SUCCESS) tls->close_reason = status; 1119 pjsip_transport_shutdown(&tls->base);1222 1223 tls_init_shutdown(tls, status); 1120 1224 } 1121 1225 } … … 1205 1309 /* Transport is closed */ 1206 1310 PJ_LOG(4,(tls->base.obj_name, "TLS connection closed")); 1207 1208 /* We can not destroy the transport since high level objects may 1209 * still keep reference to this transport. So we can only 1210 * instruct transport manager to gracefully start the shutdown 1211 * procedure for this transport. 1212 */ 1213 if (tls->close_reason==PJ_SUCCESS) 1214 tls->close_reason = status; 1215 pjsip_transport_shutdown(&tls->base); 1311 1312 tls_init_shutdown(tls, status); 1216 1313 1217 1314 return PJ_FALSE; … … 1233 1330 { 1234 1331 struct tls_transport *tls; 1235 pj_ssl_sock_info info; 1236 1332 pj_ssl_sock_info ssl_info; 1333 pj_sockaddr_in addr, *tp_addr; 1334 1335 pjsip_tp_state_callback *state_cb; 1336 pj_bool_t tls_verif_ignored; 1337 1237 1338 tls = (struct tls_transport*) pj_ssl_sock_get_user_data(ssock); 1238 1339 … … 1255 1356 } 1256 1357 1257 /* We can not destroy the transport since high level objects may1258 * still keep reference to this transport. So we can only 1259 * instruct transport manager to gracefully start the shutdown 1260 * procedure for this transport. 1261 */ 1262 if (tls->close_reason==PJ_SUCCESS) tls->close_reason = status; 1263 pjsip_transport_shutdown(&tls->base);1264 return PJ_FALSE; 1265 } 1358 goto on_error; 1359 } 1360 1361 /* Retrieve SSL socket info, shutdown the transport if this is failed 1362 * as the SSL socket info availability is rather critical here. 1363 */ 1364 status = pj_ssl_sock_get_info(tls->ssock, &ssl_info); 1365 if (status != PJ_SUCCESS) 1366 goto on_error; 1266 1367 1267 1368 /* Update (again) local address, just in case local address currently … … 1269 1370 * on some systems, like old Win32 probably?). 1270 1371 */ 1271 1272 /* Retrieve the bound address */ 1273 status = pj_ssl_sock_get_info(tls->ssock, &info); 1274 if (status == PJ_SUCCESS) { 1275 pj_sockaddr_in addr; 1276 pj_sockaddr_in *tp_addr = (pj_sockaddr_in*)&tls->base.local_addr; 1277 1278 pj_sockaddr_cp((pj_sockaddr_t*)&addr, (pj_sockaddr_t*)&info.local_addr); 1279 if (tp_addr->sin_addr.s_addr != addr.sin_addr.s_addr) { 1280 tp_addr->sin_addr.s_addr = addr.sin_addr.s_addr; 1281 tp_addr->sin_port = addr.sin_port; 1282 sockaddr_to_host_port(tls->base.pool, &tls->base.local_name, 1283 tp_addr); 1372 tp_addr = (pj_sockaddr_in*)&tls->base.local_addr; 1373 pj_sockaddr_cp((pj_sockaddr_t*)&addr, 1374 (pj_sockaddr_t*)&ssl_info.local_addr); 1375 if (tp_addr->sin_addr.s_addr != addr.sin_addr.s_addr) { 1376 tp_addr->sin_addr.s_addr = addr.sin_addr.s_addr; 1377 tp_addr->sin_port = addr.sin_port; 1378 sockaddr_to_host_port(tls->base.pool, &tls->base.local_name, 1379 tp_addr); 1380 } 1381 1382 /* Server identity verification based on server certificate. */ 1383 if (ssl_info.remote_cert_info->version) { 1384 pj_str_t *remote_name; 1385 pj_ssl_cert_info *serv_cert = ssl_info.remote_cert_info; 1386 pj_bool_t matched = PJ_FALSE; 1387 unsigned i; 1388 1389 /* Remote name may be hostname or IP address */ 1390 if (tls->remote_name.slen) 1391 remote_name = &tls->remote_name; 1392 else 1393 remote_name = &tls->base.remote_name.host; 1394 1395 /* Start matching remote name with SubjectAltName fields of 1396 * server certificate. 1397 */ 1398 for (i = 0; i < serv_cert->subj_alt_name.cnt && !matched; ++i) { 1399 pj_str_t *cert_name = &serv_cert->subj_alt_name.entry[i].name; 1400 1401 switch (serv_cert->subj_alt_name.entry[i].type) { 1402 case PJ_SSL_CERT_NAME_DNS: 1403 case PJ_SSL_CERT_NAME_IP: 1404 matched = !pj_stricmp(remote_name, cert_name); 1405 break; 1406 case PJ_SSL_CERT_NAME_URI: 1407 if (pj_strnicmp2(cert_name, "sip:", 4) == 0 || 1408 pj_strnicmp2(cert_name, "sips:", 5) == 0) 1409 { 1410 pj_str_t host_part; 1411 char *p; 1412 1413 p = pj_strchr(cert_name, ':') + 1; 1414 pj_strset(&host_part, p, cert_name->slen - 1415 (p - cert_name->ptr)); 1416 matched = !pj_stricmp(remote_name, &host_part); 1417 } 1418 break; 1419 default: 1420 break; 1421 } 1284 1422 } 1285 } 1423 1424 /* When still not matched or no SubjectAltName fields in server 1425 * certificate, try with Common Name of Subject field. 1426 */ 1427 if (!matched) { 1428 matched = !pj_stricmp(remote_name, &serv_cert->subject.cn); 1429 } 1430 1431 if (!matched) 1432 ssl_info.verify_status |= PJ_SSL_CERT_EIDENTITY_NOT_MATCH; 1433 } 1434 1435 tls_verif_ignored = !tls->verify_server; 1436 1437 /* Notify transport state to application */ 1438 state_cb = pjsip_tpmgr_get_status_cb(tls->base.tpmgr); 1439 if (state_cb) { 1440 pjsip_transport_state_info state_info; 1441 pjsip_tls_state_info tls_info; 1442 pj_uint32_t tp_state = 0; 1443 1444 /* Init transport state notification callback */ 1445 pj_bzero(&state_info, sizeof(state_info)); 1446 pj_bzero(&tls_info, sizeof(tls_info)); 1447 1448 /* Set transport state info */ 1449 state_info.ext_info = &tls_info; 1450 tls_info.ssl_sock_info = &ssl_info; 1451 1452 /* Set transport state based on verification status */ 1453 if (ssl_info.verify_status) { 1454 state_info.status = PJSIP_TLS_ECONNECT; 1455 tp_state |= PJSIP_TP_STATE_TLS_VERIF_ERROR; 1456 if (tls->verify_server) 1457 tp_state |= PJSIP_TP_STATE_DISCONNECTED; 1458 else 1459 tp_state |= PJSIP_TP_STATE_CONNECTED; 1460 } else { 1461 tp_state |= PJSIP_TP_STATE_CONNECTED; 1462 } 1463 1464 tls_verif_ignored = (*state_cb)(&tls->base, tp_state, &state_info); 1465 } 1466 1467 /* Transport should be shutdown when there is TLS verification error 1468 * and application doesn't want to ignore it. 1469 */ 1470 if (ssl_info.verify_status && 1471 (tls->verify_server || !tls_verif_ignored)) 1472 { 1473 if (tls->close_reason == PJ_SUCCESS) 1474 tls->close_reason = PJSIP_TLS_ECONNECT; 1475 pjsip_transport_shutdown(&tls->base); 1476 return PJ_FALSE; 1477 } 1478 1479 /* Mark that pending connect() operation has completed. */ 1480 tls->has_pending_connect = PJ_FALSE; 1286 1481 1287 1482 PJ_LOG(4,(tls->base.obj_name, … … 1294 1489 tls->base.remote_name.port)); 1295 1490 1296 /* Mark that pending connect() operation has completed. */1297 tls->has_pending_connect = PJ_FALSE;1298 1299 1491 /* Start pending read */ 1300 1492 status = tls_start_read(tls); 1301 if (status != PJ_SUCCESS) { 1302 /* We can not destroy the transport since high level objects may 1303 * still keep reference to this transport. So we can only 1304 * instruct transport manager to gracefully start the shutdown 1305 * procedure for this transport. 1306 */ 1307 if (tls->close_reason==PJ_SUCCESS) tls->close_reason = status; 1308 pjsip_transport_shutdown(&tls->base); 1309 return PJ_FALSE; 1310 } 1493 if (status != PJ_SUCCESS) 1494 goto on_error; 1311 1495 1312 1496 /* Flush all pending send operations */ … … 1323 1507 1324 1508 return PJ_TRUE; 1509 1510 on_error: 1511 tls_init_shutdown(tls, status); 1512 1513 return PJ_FALSE; 1325 1514 } 1326 1515 … … 1366 1555 tls_perror(tls->base.obj_name, 1367 1556 "Error sending keep-alive packet", status); 1368 pjsip_transport_shutdown(&tls->base); 1557 1558 tls_init_shutdown(tls, status); 1369 1559 return; 1370 1560 }
Note: See TracChangeset
for help on using the changeset viewer.