- Timestamp:
- Mar 3, 2007 2:16:36 AM (18 years ago)
- Location:
- pjproject/trunk/pjlib-util
- Files:
-
- 2 added
- 2 deleted
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjlib-util/build/pjlib_util.dsp
r1008 r1037 146 146 # Begin Source File 147 147 148 SOURCE="..\src\pjlib-util\stun_auth.c" 149 # End Source File 150 # Begin Source File 151 148 152 SOURCE="..\src\pjlib-util\stun_endpoint.c" 149 153 # End Source File … … 155 159 156 160 SOURCE="..\src\pjlib-util\stun_msg_dump.c" 157 # End Source File158 # Begin Source File159 160 SOURCE="..\src\pjlib-util\stun_server.c"161 161 # End Source File 162 162 # Begin Source File … … 250 250 # Begin Source File 251 251 252 SOURCE="..\include\pjlib-util\stun_auth.h" 253 # End Source File 254 # Begin Source File 255 252 256 SOURCE="..\include\pjlib-util\stun_doc.h" 253 257 # End Source File … … 259 263 260 264 SOURCE="..\include\pjlib-util\stun_msg.h" 261 # End Source File262 # Begin Source File263 264 SOURCE="..\include\pjlib-util\stun_server.h"265 265 # End Source File 266 266 # Begin Source File -
pjproject/trunk/pjlib-util/build/pjlib_util.vcproj
r1002 r1037 416 416 </File> 417 417 <File 418 RelativePath="..\src\pjlib-util\stun_auth.c" 419 > 420 </File> 421 <File 418 422 RelativePath="..\src\pjlib-util\stun_endpoint.c" 419 423 > … … 428 432 </File> 429 433 <File 430 RelativePath="..\src\pjlib-util\stun_se rver.c"434 RelativePath="..\src\pjlib-util\stun_session.c" 431 435 > 432 436 </File> … … 553 557 </File> 554 558 <File 559 RelativePath="..\include\pjlib-util\stun_auth.h" 560 > 561 </File> 562 <File 555 563 RelativePath="..\include\pjlib-util\stun_doc.h" 556 564 > … … 565 573 </File> 566 574 <File 567 RelativePath="..\include\pjlib-util\stun_se rver.h"575 RelativePath="..\include\pjlib-util\stun_session.h" 568 576 > 569 577 </File> -
pjproject/trunk/pjlib-util/build/pjstun_srv_test.dsp
r1005 r1037 94 94 95 95 # PROP Default_Filter "h;hpp;hxx;hm;inl" 96 # Begin Source File97 98 SOURCE="..\src\pjstun-srv-test\server.h"99 # End Source File100 96 # End Group 101 97 # Begin Group "Resource Files" -
pjproject/trunk/pjlib-util/include/pjlib-util.h
r1008 r1037 50 50 51 51 /* New STUN */ 52 #include <pjlib-util/stun_auth.h> 52 53 #include <pjlib-util/stun_endpoint.h> 53 54 #include <pjlib-util/stun_msg.h> 54 #include <pjlib-util/stun_server.h>55 55 #include <pjlib-util/stun_session.h> 56 56 #include <pjlib-util/stun_transaction.h> -
pjproject/trunk/pjlib-util/include/pjlib-util/errno.h
r1030 r1037 262 262 /** 263 263 * @hideinitializer 264 * Invalid STUN attribute265 */266 #define PJLIB_UTIL_ESTUNINATTR (PJLIB_UTIL_ERRNO_START+110)/* 320110 */267 /**268 * @hideinitializer269 264 * Too many STUN attributes. 270 265 */ 271 #define PJLIB_UTIL_ESTUNTOOMANYATTR (PJLIB_UTIL_ERRNO_START+111)/* 320111 */ 272 /** 273 * @hideinitializer 274 * Unknown STUN attribute. 275 */ 276 #define PJLIB_UTIL_ESTUNUNKNOWNATTR (PJLIB_UTIL_ERRNO_START+112)/* 320112 */ 266 #define PJLIB_UTIL_ESTUNTOOMANYATTR (PJLIB_UTIL_ERRNO_START+110)/* 320110 */ 267 /** 268 * @hideinitializer 269 * Unknown STUN attribute. This error happens when the decoder encounters 270 * mandatory attribute type which it doesn't understand. 271 */ 272 #define PJLIB_UTIL_ESTUNUNKNOWNATTR (PJLIB_UTIL_ERRNO_START+111)/* 320111 */ 277 273 /** 278 274 * @hideinitializer 279 275 * Invalid STUN socket address length. 280 276 */ 281 #define PJLIB_UTIL_ESTUNINADDRLEN (PJLIB_UTIL_ERRNO_START+11 3)/* 320113*/277 #define PJLIB_UTIL_ESTUNINADDRLEN (PJLIB_UTIL_ERRNO_START+112)/* 320112 */ 282 278 /** 283 279 * @hideinitializer … … 320 316 */ 321 317 #define PJLIB_UTIL_ESTUNNOUSERNAME (PJLIB_UTIL_ERRNO_START+120)/* 320120 */ 322 323 324 #define PJ_STATUS_FROM_STUN_CODE(code) (PJLIB_UTIL_ERRNO_START+code) 318 /** 319 * @hideinitializer 320 * Unknown STUN username/credential. 321 */ 322 #define PJLIB_UTIL_ESTUNUSERNAME (PJLIB_UTIL_ERRNO_START+121)/* 320121 */ 323 /** 324 * @hideinitializer 325 * Missing/invalidSTUN MESSAGE-INTEGRITY attribute. 326 */ 327 #define PJLIB_UTIL_ESTUNMSGINT (PJLIB_UTIL_ERRNO_START+122)/* 320122 */ 328 /** 329 * @hideinitializer 330 * Found duplicate STUN attribute. 331 */ 332 #define PJLIB_UTIL_ESTUNDUPATTR (PJLIB_UTIL_ERRNO_START+123)/* 320123 */ 333 /** 334 * @hideinitializer 335 * Missing STUN REALM attribute. 336 */ 337 #define PJLIB_UTIL_ESTUNNOREALM (PJLIB_UTIL_ERRNO_START+124)/* 320124 */ 338 /** 339 * @hideinitializer 340 * Missing/stale STUN NONCE attribute value. 341 */ 342 #define PJLIB_UTIL_ESTUNNONCE (PJLIB_UTIL_ERRNO_START+125)/* 320125 */ 343 /** 344 * @hideinitializer 345 * STUN transaction terminates with failure. 346 */ 347 #define PJLIB_UTIL_ESTUNTSXFAILED (PJLIB_UTIL_ERRNO_START+126)/* 320126 */ 348 349 350 //#define PJ_STATUS_FROM_STUN_CODE(code) (PJLIB_UTIL_ERRNO_START+code) 325 351 326 352 -
pjproject/trunk/pjlib-util/include/pjlib-util/stun_msg.h
r1021 r1037 511 511 \endverbatim 512 512 */ 513 typedef struct pj_stun_ generic_ip_addr_attr513 typedef struct pj_stun_ip_addr_attr 514 514 { 515 515 /** … … 527 527 } addr; 528 528 529 } pj_stun_ generic_ip_addr_attr;529 } pj_stun_ip_addr_attr; 530 530 531 531 … … 549 549 * NONCE attributes, the text MUST be quoted with. 550 550 */ 551 typedef struct pj_stun_ generic_string_attr551 typedef struct pj_stun_string_attr 552 552 { 553 553 /** … … 561 561 pj_str_t value; 562 562 563 } pj_stun_ generic_string_attr;563 } pj_stun_string_attr; 564 564 565 565 … … 568 568 * integer value, such as STUN FINGERPRINT and REFRESH-INTERVAL attributes. 569 569 */ 570 typedef struct pj_stun_ generic_uint_attr570 typedef struct pj_stun_uint_attr 571 571 { 572 572 /** … … 580 580 pj_uint32_t value; 581 581 582 } pj_stun_ generic_uint_attr;582 } pj_stun_uint_attr; 583 583 584 584 … … 614 614 * bytes. 615 615 */ 616 typedef struct pj_stun_msg _integrity_attr616 typedef struct pj_stun_msgint_attr 617 617 { 618 618 /** … … 626 626 pj_uint8_t hmac[20]; 627 627 628 } pj_stun_msg _integrity_attr;628 } pj_stun_msgint_attr; 629 629 630 630 … … 635 635 * attribute itself, xor-d with the 32 bit value 0x5354554e 636 636 */ 637 typedef struct pj_stun_ generic_uint_attr pj_stun_fingerprint_attr;637 typedef struct pj_stun_uint_attr pj_stun_fingerprint_attr; 638 638 639 639 … … 656 656 \endverbatim 657 657 */ 658 typedef struct pj_stun_err or_code_attr658 typedef struct pj_stun_errcode_attr 659 659 { 660 660 /** … … 683 683 pj_str_t reason; 684 684 685 } pj_stun_err or_code_attr;685 } pj_stun_errcode_attr; 686 686 687 687 … … 693 693 * quotes). 694 694 */ 695 typedef struct pj_stun_ generic_string_attr pj_stun_realm_attr;695 typedef struct pj_stun_string_attr pj_stun_realm_attr; 696 696 697 697 … … 703 703 * values in a server. 704 704 */ 705 typedef struct pj_stun_ generic_string_attr pj_stun_nonce_attr;705 typedef struct pj_stun_string_attr pj_stun_nonce_attr; 706 706 707 707 … … 740 740 * The MAPPED-ADDRESS attribute indicates the mapped transport address. 741 741 */ 742 typedef struct pj_stun_ generic_ip_addr_attr pj_stun_mapped_addr_attr;742 typedef struct pj_stun_ip_addr_attr pj_stun_mapped_addr_attr; 743 743 744 744 … … 752 752 * through NATs which would otherwise interfere with STUN. 753 753 */ 754 typedef struct pj_stun_ generic_ip_addr_attr pj_stun_xor_mapped_addr_attr;754 typedef struct pj_stun_ip_addr_attr pj_stun_xor_mapped_addr_attr; 755 755 756 756 … … 763 763 * SERVER is variable length. 764 764 */ 765 typedef struct pj_stun_ generic_string_attr pj_stun_server_attr;765 typedef struct pj_stun_string_attr pj_stun_server_attr; 766 766 767 767 … … 772 772 * MAPPED-ADDRESS. 773 773 */ 774 typedef struct pj_stun_ generic_ip_addr_attr pj_stun_alt_server_attr;774 typedef struct pj_stun_ip_addr_attr pj_stun_alt_server_attr; 775 775 776 776 … … 781 781 * bindings between the client and server. 782 782 */ 783 typedef struct pj_stun_ generic_uint_attr pj_stun_refresh_interval_attr;783 typedef struct pj_stun_uint_attr pj_stun_refresh_interval_attr; 784 784 785 785 … … 793 793 * RFC 3489-bis standard. 794 794 */ 795 typedef struct pj_stun_ generic_ip_addr_attr pj_stun_response_addr_attr;795 typedef struct pj_stun_ip_addr_attr pj_stun_response_addr_attr; 796 796 797 797 … … 808 808 * RFC 3489-bis standard. 809 809 */ 810 typedef struct pj_stun_ generic_ip_addr_attr pj_stun_changed_addr_attr;810 typedef struct pj_stun_ip_addr_attr pj_stun_changed_addr_attr; 811 811 812 812 … … 828 828 * RFC 3489-bis standard. 829 829 */ 830 typedef struct pj_stun_ generic_uint_attr pj_stun_change_request_attr;830 typedef struct pj_stun_uint_attr pj_stun_change_request_attr; 831 831 832 832 /** … … 840 840 * RFC 3489-bis standard. 841 841 */ 842 typedef struct pj_stun_ generic_ip_addr_attr pj_stun_src_addr_attr;842 typedef struct pj_stun_ip_addr_attr pj_stun_src_addr_attr; 843 843 844 844 … … 852 852 * denial-of-service attacks. 853 853 */ 854 typedef struct pj_stun_ generic_ip_addr_attr pj_stun_reflected_from_attr;854 typedef struct pj_stun_ip_addr_attr pj_stun_reflected_from_attr; 855 855 856 856 … … 862 862 * MESSAGE-INTEGRITY attribute. 863 863 */ 864 typedef struct pj_stun_ generic_string_attr pj_stun_username_attr;864 typedef struct pj_stun_string_attr pj_stun_username_attr; 865 865 866 866 … … 870 870 * PASSWORD attribute. 871 871 */ 872 typedef struct pj_stun_ generic_string_attr pj_stun_password_attr;872 typedef struct pj_stun_string_attr pj_stun_password_attr; 873 873 874 874 … … 880 880 * of seconds remaining until expiration. 881 881 */ 882 typedef struct pj_stun_ generic_uint_attr pj_stun_lifetime_attr;882 typedef struct pj_stun_uint_attr pj_stun_lifetime_attr; 883 883 884 884 … … 889 889 * value represents the sum in the receive and send directions. 890 890 */ 891 typedef struct pj_stun_ generic_uint_attr pj_stun_bandwidth_attr;891 typedef struct pj_stun_uint_attr pj_stun_bandwidth_attr; 892 892 893 893 … … 897 897 * from the STUN relay server. 898 898 */ 899 typedef struct pj_stun_ generic_ip_addr_attr pj_stun_remote_addr_attr;899 typedef struct pj_stun_ip_addr_attr pj_stun_remote_addr_attr; 900 900 901 901 … … 915 915 * address and port that the server allocated to the client. 916 916 */ 917 typedef struct pj_stun_ generic_ip_addr_attr pj_stun_relay_addr_attr;917 typedef struct pj_stun_ip_addr_attr pj_stun_relay_addr_attr; 918 918 919 919 … … 934 934 \endverbatim 935 935 */ 936 typedef struct pj_stun_ generic_uint_attr pj_stun_requested_addr_type;936 typedef struct pj_stun_uint_attr pj_stun_requested_addr_type; 937 937 938 938 /** … … 954 954 \endverbatim 955 955 */ 956 typedef struct pj_stun_ generic_uint_attr pj_stun_requested_port_props_attr;956 typedef struct pj_stun_uint_attr pj_stun_requested_port_props_attr; 957 957 958 958 … … 963 963 * unsigned integer. Its values are: 0x0000 for UDP and 0x0000 for TCP. 964 964 */ 965 typedef struct pj_stun_ generic_uint_attr pj_stun_requested_transport_attr;965 typedef struct pj_stun_uint_attr pj_stun_requested_transport_attr; 966 966 967 967 … … 971 971 * specific IP address be allocated to it. 972 972 */ 973 typedef struct pj_stun_ generic_ip_addr_attr pj_stun_requested_ip_attr;973 typedef struct pj_stun_ip_addr_attr pj_stun_requested_ip_attr; 974 974 975 975 /** … … 983 983 * to XOR-MAPPED-ADDRESS. 984 984 */ 985 typedef struct pj_stun_ generic_ip_addr_attr pj_stun_xor_reflected_from_attr;985 typedef struct pj_stun_ip_addr_attr pj_stun_xor_reflected_from_attr; 986 986 987 987 /** … … 992 992 * type of 0x0024. 993 993 */ 994 typedef struct pj_stun_ generic_uint_attr pj_stun_priority_attr;994 typedef struct pj_stun_uint_attr pj_stun_priority_attr; 995 995 996 996 /** … … 1011 1011 * the STUN-aware NATs along the path. 1012 1012 */ 1013 typedef pj_stun_ generic_ip_addr_attr pj_stun_xor_internal_addr_attr;1013 typedef pj_stun_ip_addr_attr pj_stun_xor_internal_addr_attr; 1014 1014 1015 1015 /** … … 1019 1019 * client, the value of the timer used in the server state machine. 1020 1020 */ 1021 typedef struct pj_stun_ generic_uint_attr pj_stun_timer_val_attr;1021 typedef struct pj_stun_uint_attr pj_stun_timer_val_attr; 1022 1022 1023 1023 … … 1048 1048 1049 1049 /** STUN decoding options */ 1050 enum pj_stun_ options1050 enum pj_stun_decode_options 1051 1051 { 1052 1052 /** … … 1063 1063 PJ_STUN_CHECK_PACKET = 2 1064 1064 }; 1065 1065 1066 1066 1067 /** … … 1208 1209 * @param pdu_len The length of the packet buffer. 1209 1210 * @param options Additional options to be applied in the checking, 1210 * which can be taken from pj_stun_ options. One of the1211 * useful option is PJ_STUN_IS_DATAGRAM which means that1212 * the pdu represents a whole STUN packet.1211 * which can be taken from pj_stun_decode_options. One 1212 * of the useful option is PJ_STUN_IS_DATAGRAM which 1213 * means that the pdu represents a whole STUN packet. 1213 1214 * 1214 1215 * @return PJ_SUCCESS if the PDU is a potentially valid STUN 1215 1216 * message. 1216 1217 */ 1217 PJ_DECL(pj_status_t) pj_stun_msg_check(const pj_uint8_t *pdu, unsigned pdu_len,1218 unsigned options);1218 PJ_DECL(pj_status_t) pj_stun_msg_check(const pj_uint8_t *pdu, 1219 unsigned pdu_len, unsigned options); 1219 1220 1220 1221 … … 1225 1226 * @param pdu The incoming packet to be parsed. 1226 1227 * @param pdu_len The length of the incoming packet. 1227 * @param options Parsing flags, according to pj_stun_ options.1228 * @param options Parsing flags, according to pj_stun_decode_options. 1228 1229 * @param p_msg Pointer to receive the parsed message. 1229 1230 * @param p_parsed_len Optional pointer to receive how many bytes have … … 1248 1249 pj_stun_msg **p_response); 1249 1250 1250 typedef enum pj_stun_auth_policy_type1251 {1252 PJ_STUN_POLICY_NONE,1253 PJ_STUN_POLICY_STATIC_SHORT_TERM,1254 PJ_STUN_POLICY_STATIC_LONG_TERM,1255 PJ_STUN_POLICY_DYNAMIC1256 } pj_stun_auth_policy_type;1257 1258 typedef struct pj_stun_auth_policy1259 {1260 pj_stun_auth_policy_type type;1261 void *user_data;1262 1263 union1264 {1265 struct1266 {1267 pj_str_t username;1268 pj_str_t password;1269 pj_str_t nonce;1270 } static_short_term;1271 1272 struct1273 {1274 pj_str_t realm;1275 pj_str_t username;1276 pj_str_t password;1277 pj_str_t nonce;1278 } static_long_term;1279 1280 struct1281 {1282 /**1283 * This callback is called by pj_stun_verify_credential() when1284 * server needs to challenge the request with 401 response.1285 *1286 * @param user_data The user data as specified in the policy.1287 * @param pool Pool to allocate memory.1288 * @param realm On return, the function should fill in with1289 * realm if application wants to use long term1290 * credential. Otherwise application should set1291 * empty string for the realm.1292 * @param nonce On return, if application wants to use long1293 * term credential, it MUST fill in the nonce1294 * with some value. Otherwise if short term1295 * credential is wanted, it MAY set this value.1296 * If short term credential is wanted and the1297 * application doesn't want to include NONCE,1298 * then it must set this to empty string.1299 *1300 * @return The callback should return PJ_SUCCESS, or1301 * otherwise response message will not be1302 * created.1303 */1304 pj_status_t (*get_auth)(void *user_data,1305 pj_pool_t *pool,1306 pj_str_t *realm,1307 pj_str_t *nonce);1308 1309 /**1310 * Get the password for the specified username. This function1311 * is also used to check whether the username is valid.1312 *1313 * @param user_data The user data as specified in the policy.1314 * @param realm The realm as specified in the message.1315 * @param username The username as specified in the message.1316 * @param pool Pool to allocate memory when necessary.1317 * @param password On return, application should fill up this1318 * argument with the password.1319 *1320 * @return The callback should return PJ_SUCCESS if1321 * username has been successfully verified1322 * and password was obtained. If non-PJ_SUCCESS1323 * is returned, it is assumed that the1324 * username is not valid.1325 */1326 pj_status_t (*get_password)(void *user_data,1327 const pj_str_t *realm,1328 const pj_str_t *username,1329 pj_pool_t *pool,1330 pj_str_t *password);1331 pj_bool_t (*require_nonce)(void *user_data,1332 const pj_str_t *realm,1333 const pj_str_t *username);1334 pj_bool_t (*verify_nonce)(void *data,1335 const pj_str_t *realm,1336 const pj_str_t *username,1337 const pj_str_t *nonce);1338 pj_status_t (*make_nonce)(void *user_data,1339 const pj_str_t *realm,1340 const pj_str_t *username,1341 pj_pool_t *pool,1342 pj_str_t *nonce);1343 } dynamic;1344 1345 } data;1346 1347 } pj_stun_auth_policy;1348 1349 1350 /**1351 * Verify credential in the STUN message. Note that before calling this1352 * function, application must have checked that the message contains1353 * PJ_STUN_ATTR_MESSAGE_INTEGRITY attribute by calling pj_stun_msg_find_attr()1354 * function, because this function will reject the message with 401 error1355 * if it doesn't contain PJ_STUN_ATTR_MESSAGE_INTEGRITY attribute.1356 *1357 * @param pkt The original packet which has been parsed into1358 * the message. This packet MUST NOT have been modified1359 * after the parsing.1360 * @param pkt_len The length of the packet.1361 * @param msg The parsed message to be verified.1362 * @param policy Pointer to authentication policy.1363 * @param pool If response is to be created, then memory will1364 * be allocated from this pool.1365 * @param p_response Optional pointer to receive the response message1366 * then the credential in the request fails to1367 * authenticate.1368 *1369 * @return PJ_SUCCESS if credential is verified successfully.1370 * If the verification fails and \a p_response is not1371 * NULL, an appropriate response will be returned in1372 * \a p_response.1373 */1374 PJ_DECL(pj_status_t) pj_stun_verify_credential(const pj_uint8_t *pkt,1375 unsigned pkt_len,1376 const pj_stun_msg *msg,1377 pj_stun_auth_policy *policy,1378 pj_pool_t *pool,1379 pj_stun_msg **p_response);1380 1381 1382 1251 /** 1383 1252 * Dump STUN message to a printable string output. … … 1431 1300 * @return PJ_SUCCESS on success or the appropriate error code. 1432 1301 */ 1433 PJ_DECL(pj_status_t) 1434 pj_stun_generic_ip_addr_attr_create(pj_pool_t *pool, 1435 int attr_type, 1436 pj_bool_t xor_ed, 1437 const pj_sockaddr_t *addr, 1438 unsigned addr_len, 1439 pj_stun_generic_ip_addr_attr **p_attr); 1302 PJ_DECL(pj_status_t) pj_stun_ip_addr_attr_create(pj_pool_t *pool, 1303 int attr_type, 1304 pj_bool_t xor_ed, 1305 const pj_sockaddr_t *addr, 1306 unsigned addr_len, 1307 pj_stun_ip_addr_attr **p_attr); 1440 1308 1441 1309 … … 1455 1323 * @return PJ_SUCCESS on success or the appropriate error code. 1456 1324 */ 1457 PJ_DECL(pj_status_t) 1458 pj_stun_msg_add_generic_ip_addr_attr(pj_pool_t *pool, 1459 pj_stun_msg *msg, 1460 int attr_type, 1461 pj_bool_t xor_ed, 1462 const pj_sockaddr_t *addr, 1463 unsigned addr_len); 1325 PJ_DECL(pj_status_t) pj_stun_msg_add_ip_addr_attr(pj_pool_t *pool, 1326 pj_stun_msg *msg, 1327 int attr_type, 1328 pj_bool_t xor_ed, 1329 const pj_sockaddr_t *addr, 1330 unsigned addr_len); 1464 1331 1465 1332 /** … … 1473 1340 * @return PJ_SUCCESS on success or the appropriate error code. 1474 1341 */ 1475 PJ_DECL(pj_status_t) 1476 pj_stun_generic_string_attr_create(pj_pool_t *pool, 1477 int attr_type, 1478 const pj_str_t *value, 1479 pj_stun_generic_string_attr **p_attr); 1342 PJ_DECL(pj_status_t) pj_stun_string_attr_create(pj_pool_t *pool, 1343 int attr_type, 1344 const pj_str_t *value, 1345 pj_stun_string_attr **p_attr); 1480 1346 1481 1347 /** … … 1489 1355 * @return PJ_SUCCESS on success or the appropriate error code. 1490 1356 */ 1491 PJ_DECL(pj_status_t) 1492 pj_stun_msg_add_generic_string_attr(pj_pool_t *pool, 1493 pj_stun_msg *msg, 1494 int attr_type, 1495 const pj_str_t *value); 1357 PJ_DECL(pj_status_t) pj_stun_msg_add_string_attr(pj_pool_t *pool, 1358 pj_stun_msg *msg, 1359 int attr_type, 1360 const pj_str_t *value); 1496 1361 1497 1362 /** … … 1505 1370 * @return PJ_SUCCESS on success or the appropriate error code. 1506 1371 */ 1507 PJ_DECL(pj_status_t) 1508 pj_stun_generic_uint_attr_create(pj_pool_t *pool, 1509 int attr_type, 1510 pj_uint32_t value, 1511 pj_stun_generic_uint_attr **p_attr); 1372 PJ_DECL(pj_status_t) pj_stun_uint_attr_create(pj_pool_t *pool, 1373 int attr_type, 1374 pj_uint32_t value, 1375 pj_stun_uint_attr **p_attr); 1512 1376 1513 1377 /** … … 1521 1385 * @return PJ_SUCCESS on success or the appropriate error code. 1522 1386 */ 1523 PJ_DECL(pj_status_t) 1524 pj_stun_msg_add_generic_uint_attr(pj_pool_t *pool, 1525 pj_stun_msg *msg, 1526 int attr_type, 1527 pj_uint32_t value); 1387 PJ_DECL(pj_status_t) pj_stun_msg_add_uint_attr(pj_pool_t *pool, 1388 pj_stun_msg *msg, 1389 int attr_type, 1390 pj_uint32_t value); 1528 1391 1529 1392 … … 1536 1399 * @return PJ_SUCCESS on success or the appropriate error code. 1537 1400 */ 1538 PJ_DECL(pj_status_t) 1539 pj_stun_msg_integrity_attr_create(pj_pool_t *pool, 1540 pj_stun_msg_integrity_attr **p_attr); 1401 PJ_DECL(pj_status_t) pj_stun_msgint_attr_create(pj_pool_t *pool, 1402 pj_stun_msgint_attr **p_attr); 1403 1404 /** 1405 * Create and add STUN MESSAGE-INTEGRITY attribute. 1406 * 1407 * @param pool The pool to allocate memory from. 1408 * @param msg The STUN message 1409 * 1410 * @return PJ_SUCCESS on success or the appropriate error code. 1411 */ 1412 PJ_DECL(pj_status_t) pj_stun_msg_add_msgint_attr(pj_pool_t *pool, 1413 pj_stun_msg *msg); 1541 1414 1542 1415 /** … … 1551 1424 * @return PJ_SUCCESS on success or the appropriate error code. 1552 1425 */ 1553 PJ_DECL(pj_status_t) 1554 pj_stun_error_code_attr_create(pj_pool_t *pool, 1555 int err_code, 1556 const pj_str_t *err_reason, 1557 pj_stun_error_code_attr **p_attr); 1558 1426 PJ_DECL(pj_status_t) pj_stun_errcode_attr_create(pj_pool_t *pool, 1427 int err_code, 1428 const pj_str_t *err_reason, 1429 pj_stun_errcode_attr **p_attr); 1430 1431 1432 /** 1433 * Create and add STUN ERROR-CODE attribute to the message. 1434 * 1435 * @param pool The pool to allocate memory from. 1436 * @param msg The STUN mesage. 1437 * @param err_code STUN error code. 1438 * @param err_reason Optional STUN error reason. If NULL is given, the 1439 * standard error reason will be given. 1440 * 1441 * @return PJ_SUCCESS on success or the appropriate error code. 1442 */ 1443 PJ_DECL(pj_status_t) pj_stun_msg_add_errcode_attr(pj_pool_t *pool, 1444 pj_stun_msg *msg, 1445 int err_code, 1446 const pj_str_t *err_reason); 1559 1447 1560 1448 /** … … 1569 1457 * @return PJ_SUCCESS on success or the appropriate error code. 1570 1458 */ 1571 PJ_DECL(pj_status_t) 1572 pj_stun_unknown_attr_create(pj_pool_t *pool, 1573 unsigned attr_cnt, 1574 const pj_uint16_t attr[], 1575 pj_stun_unknown_attr **p_attr); 1459 PJ_DECL(pj_status_t) pj_stun_unknown_attr_create(pj_pool_t *pool, 1460 unsigned attr_cnt, 1461 const pj_uint16_t attr[], 1462 pj_stun_unknown_attr **p_attr); 1576 1463 1577 1464 /** … … 1585 1472 * @return PJ_SUCCESS on success or the appropriate error code. 1586 1473 */ 1587 PJ_DECL(pj_status_t) 1588 pj_stun_msg_add_unknown_attr(pj_pool_t *pool, 1589 pj_stun_msg *msg, 1590 unsigned attr_cnt, 1591 const pj_uint16_t attr[]); 1474 PJ_DECL(pj_status_t) pj_stun_msg_add_unknown_attr(pj_pool_t *pool, 1475 pj_stun_msg *msg, 1476 unsigned attr_cnt, 1477 const pj_uint16_t attr[]); 1592 1478 1593 1479 /** … … 1604 1490 * @return PJ_SUCCESS on success or the appropriate error code. 1605 1491 */ 1606 PJ_DECL(pj_status_t) 1607 pj_stun_binary_attr_create(pj_pool_t *pool, 1608 int attr_type, 1609 const pj_uint8_t *data, 1610 unsigned length, 1611 pj_stun_binary_attr **p_attr); 1492 PJ_DECL(pj_status_t) pj_stun_binary_attr_create(pj_pool_t *pool, 1493 int attr_type, 1494 const pj_uint8_t *data, 1495 unsigned length, 1496 pj_stun_binary_attr **p_attr); 1612 1497 1613 1498 /** … … 1625 1510 * @return PJ_SUCCESS on success or the appropriate error code. 1626 1511 */ 1627 PJ_DECL(pj_status_t) 1628 pj_stun_msg_add_binary_attr(pj_pool_t *pool, 1629 pj_stun_msg *msg, 1630 int attr_type, 1631 const pj_uint8_t *data, 1632 unsigned length); 1512 PJ_DECL(pj_status_t) pj_stun_msg_add_binary_attr(pj_pool_t *pool, 1513 pj_stun_msg *msg, 1514 int attr_type, 1515 const pj_uint8_t *data, 1516 unsigned length); 1633 1517 1634 1518 -
pjproject/trunk/pjlib-util/include/pjlib-util/stun_session.h
r1034 r1037 21 21 22 22 #include <pjlib-util/stun_msg.h> 23 #include <pjlib-util/stun_auth.h> 23 24 #include <pjlib-util/stun_endpoint.h> 24 25 #include <pjlib-util/stun_transaction.h> … … 148 149 unsigned pkt_size; /**< The actual length of STUN pkt. */ 149 150 150 unsigned options; /**< Options specified when sending */151 151 unsigned addr_len; /**< Length of destination address. */ 152 152 const pj_sockaddr_t *dst_addr; /**< Destination address. */ … … 157 157 158 158 /** 159 * Options that can be specified when creating or sending outgoing STUN160 * messages. These options may be specified as bitmask.161 */162 enum pj_stun_session_send_option163 {164 /**165 * Add short term credential to the message. This option may not be used166 * together with PJ_STUN_USE_LONG_TERM_CRED option.167 */168 PJ_STUN_USE_SHORT_TERM_CRED = 1,169 170 /**171 * Add long term credential to the message. This option may not be used172 * together with PJ_STUN_USE_SHORT_TERM_CRED option.173 */174 PJ_STUN_USE_LONG_TERM_CRED = 2,175 176 /**177 * Add STUN fingerprint to the message.178 */179 PJ_STUN_USE_FINGERPRINT = 4,180 181 /**182 * Instruct the session to cache outgoing response. This can only be183 * used when sending outgoing response message, and when it's specified,184 * the session will use \a res_cache_msec settings in pj_stun_endpoint185 * as the duration of the cache.186 */187 PJ_STUN_CACHE_RESPONSE = 8188 };189 190 191 /**192 159 * Create a STUN session. 193 160 * 194 * @param endpt The STUN endpoint, to be used to register timers etc. 195 * @param name Optional name to be associated with this instance. The 196 * name will be used for example for logging purpose. 197 * @param cb Session callback. 198 * @param p_sess Pointer to receive STUN session instance. 161 * @param endpt The STUN endpoint, to be used to register timers etc. 162 * @param name Optional name to be associated with this instance. The 163 * name will be used for example for logging purpose. 164 * @param cb Session callback. 165 * @param fingerprint Enable message fingerprint for outgoing messages. 166 * @param p_sess Pointer to receive STUN session instance. 199 167 * 200 168 * @return PJ_SUCCESS on success, or the appropriate error code. … … 203 171 const char *name, 204 172 const pj_stun_session_cb *cb, 173 pj_bool_t fingerprint, 205 174 pj_stun_session **p_sess); 206 175 … … 236 205 237 206 /** 238 * Save a long term credential to be used by this STUN session when sending 239 * outgoing messages. After long term credential is configured, application 240 * may specify PJ_STUN_USE_LONG_TERM_CRED option when sending outgoing STUN 241 * message to send the long term credential in the message. 242 * 243 * @param sess The STUN session instance. 244 * @param realm Realm of the long term credential. 245 * @param user The user name. 246 * @param passwd The pain-text password. 247 * 248 * @return PJ_SUCCESS on success, or the appropriate error code. 249 */ 250 PJ_DECL(pj_status_t) 251 pj_stun_session_set_long_term_credential(pj_stun_session *sess, 252 const pj_str_t *realm, 253 const pj_str_t *user, 254 const pj_str_t *passwd); 255 256 257 /** 258 * Save a short term credential to be used by this STUN session when sending 259 * outgoing messages. After short term credential is configured, application 260 * may specify PJ_STUN_USE_SHORT_TERM_CRED option when sending outgoing STUN 261 * message to send the short term credential in the message. 262 * 263 * @param sess The STUN session instance. 264 * @param user The user name. 265 * @param passwd The pain-text password. 266 * 267 * @return PJ_SUCCESS on success, or the appropriate error code. 268 */ 269 PJ_DECL(pj_status_t) 270 pj_stun_session_set_short_term_credential(pj_stun_session *sess, 271 const pj_str_t *user, 272 const pj_str_t *passwd); 273 207 * Set server name to be included in all response. 208 * 209 * @param sess The STUN session instance. 210 * @param srv_name Server name string. 211 * 212 * @return The user data associated with this STUN session. 213 */ 214 PJ_DECL(pj_status_t) pj_stun_session_set_server_name(pj_stun_session *sess, 215 const pj_str_t *srv_name); 216 217 /** 218 * Set credential to be used by this session. Once credential is set, all 219 * outgoing messages will include MESSAGE-INTEGRITY, and all incoming 220 * message will be authenticated against this credential. 221 * 222 * To disable authentication after it has been set, call this function 223 * again with NULL as the argument. 224 * 225 * @param sess The STUN session instance. 226 * @param cred The credential to be used by this session. If NULL 227 * is specified, authentication will be disabled. 228 * 229 * @return PJ_SUCCESS on success, or the appropriate error code. 230 */ 231 PJ_DECL(void) pj_stun_session_set_credential(pj_stun_session *sess, 232 const pj_stun_auth_cred *cred); 274 233 275 234 /** … … 410 369 * 411 370 * @param sess The STUN session instance. 412 * @param options Optional flags, from pj_stun_session_send_option.371 * @param cache_res If PJ_TRUE then response will be cached. 413 372 * @param dst_addr The destination socket address. 414 373 * @param addr_len Length of destination address. … … 419 378 */ 420 379 PJ_DECL(pj_status_t) pj_stun_session_send_msg(pj_stun_session *sess, 421 unsigned options,380 pj_bool_t cache_res, 422 381 const pj_sockaddr_t *dst_addr, 423 382 unsigned addr_len, -
pjproject/trunk/pjlib-util/src/pjlib-util/errno.c
r974 r1037 69 69 PJ_BUILD_ERR( PJLIB_UTIL_EDNS_NOTAUTH, "DNS \"Not authorized\""), 70 70 PJ_BUILD_ERR( PJLIB_UTIL_EDNS_NOTZONE, "DNS \"The zone specified is not a zone\""), 71 72 /* STUN */ 73 PJ_BUILD_ERR( PJLIB_UTIL_ESTUNTOOMANYATTR, "Too many STUN attributes"), 74 PJ_BUILD_ERR( PJLIB_UTIL_ESTUNUNKNOWNATTR, "Unknown STUN attribute"), 75 PJ_BUILD_ERR( PJLIB_UTIL_ESTUNINADDRLEN, "Invalid STUN socket address length"), 76 PJ_BUILD_ERR( PJLIB_UTIL_ESTUNIPV6NOTSUPP, "STUN IPv6 attribute not supported"), 77 PJ_BUILD_ERR( PJLIB_UTIL_ESTUNNOTRESPONSE, "Expecting STUN response message"), 78 PJ_BUILD_ERR( PJLIB_UTIL_ESTUNINVALIDID, "STUN transaction ID mismatch"), 79 PJ_BUILD_ERR( PJLIB_UTIL_ESTUNNOHANDLER, "Unable to find STUN handler for the request"), 80 PJ_BUILD_ERR( PJLIB_UTIL_ESTUNMSGINTPOS, "Found non-FINGERPRINT attr. after MESSAGE-INTEGRITY"), 81 PJ_BUILD_ERR( PJLIB_UTIL_ESTUNFINGERPOS, "Found STUN attribute after FINGERPRINT"), 82 PJ_BUILD_ERR( PJLIB_UTIL_ESTUNNOUSERNAME, "Missing STUN USERNAME attribute"), 83 PJ_BUILD_ERR( PJLIB_UTIL_ESTUNMSGINT, "Missing/invalid STUN MESSAGE-INTEGRITY attribute"), 84 PJ_BUILD_ERR( PJLIB_UTIL_ESTUNDUPATTR, "Found duplicate STUN attribute"), 85 PJ_BUILD_ERR( PJLIB_UTIL_ESTUNNOREALM, "Missing STUN REALM attribute"), 86 PJ_BUILD_ERR( PJLIB_UTIL_ESTUNNONCE, "Missing/stale STUN NONCE attribute value"), 87 PJ_BUILD_ERR( PJLIB_UTIL_ESTUNTSXFAILED, "STUN transaction terminates with failure"), 71 88 }; 72 89 #endif /* PJ_HAS_ERROR_STRING */ -
pjproject/trunk/pjlib-util/src/pjlib-util/stun_msg.c
r1030 r1037 22 22 #include <pjlib-util/hmac_sha1.h> 23 23 #include <pjlib-util/md5.h> 24 #include <pjlib-util/sha1.h>25 24 #include <pj/assert.h> 26 25 #include <pj/log.h> … … 89 88 }; 90 89 91 static pj_status_t decode_ generic_ip_addr_attr(pj_pool_t *pool,92 93 94 static pj_status_t encode_ generic_ip_addr_attr(const void *a, pj_uint8_t *buf,95 96 97 static pj_status_t decode_ generic_string_attr(pj_pool_t *pool,98 99 100 static pj_status_t encode_ generic_string_attr(const void *a, pj_uint8_t *buf,101 102 static pj_status_t decode_msg _integrity_attr(pj_pool_t *pool,103 104 105 static pj_status_t encode_msg _integrity_attr(const void *a, pj_uint8_t *buf,106 107 static pj_status_t decode_err or_code_attr(pj_pool_t *pool,108 109 110 static pj_status_t encode_err or_code_attr(const void *a, pj_uint8_t *buf,111 90 static pj_status_t decode_ip_addr_attr(pj_pool_t *pool, 91 const pj_uint8_t *buf, 92 void **p_attr); 93 static pj_status_t encode_ip_addr_attr(const void *a, pj_uint8_t *buf, 94 unsigned len, 95 unsigned *printed); 96 static pj_status_t decode_string_attr(pj_pool_t *pool, 97 const pj_uint8_t *buf, 98 void **p_attr); 99 static pj_status_t encode_string_attr(const void *a, pj_uint8_t *buf, 100 unsigned len, unsigned *printed); 101 static pj_status_t decode_msgint_attr(pj_pool_t *pool, 102 const pj_uint8_t *buf, 103 void **p_attr); 104 static pj_status_t encode_msgint_attr(const void *a, pj_uint8_t *buf, 105 unsigned len, unsigned *printed); 106 static pj_status_t decode_errcode_attr(pj_pool_t *pool, 107 const pj_uint8_t *buf, 108 void **p_attr); 109 static pj_status_t encode_errcode_attr(const void *a, pj_uint8_t *buf, 110 unsigned len, unsigned *printed); 112 111 static pj_status_t decode_unknown_attr(pj_pool_t *pool, 113 112 const pj_uint8_t *buf, … … 115 114 static pj_status_t encode_unknown_attr(const void *a, pj_uint8_t *buf, 116 115 unsigned len, unsigned *printed); 117 static pj_status_t decode_ generic_uint_attr(pj_pool_t *pool,118 119 120 static pj_status_t encode_ generic_uint_attr(const void *a, pj_uint8_t *buf,121 116 static pj_status_t decode_uint_attr(pj_pool_t *pool, 117 const pj_uint8_t *buf, 118 void **p_attr); 119 static pj_status_t encode_uint_attr(const void *a, pj_uint8_t *buf, 120 unsigned len, unsigned *printed); 122 121 static pj_status_t decode_binary_attr(pj_pool_t *pool, 123 122 const pj_uint8_t *buf, … … 143 142 /* PJ_STUN_ATTR_MAPPED_ADDR, */ 144 143 "MAPPED-ADDRESS", 145 &decode_ generic_ip_addr_attr,146 &encode_ generic_ip_addr_attr144 &decode_ip_addr_attr, 145 &encode_ip_addr_attr 147 146 }, 148 147 { 149 148 /* PJ_STUN_ATTR_RESPONSE_ADDR, */ 150 149 "RESPONSE-ADDRESS", 151 &decode_ generic_ip_addr_attr,152 &encode_ generic_ip_addr_attr150 &decode_ip_addr_attr, 151 &encode_ip_addr_attr 153 152 }, 154 153 { 155 154 /* PJ_STUN_ATTR_CHANGE_REQUEST, */ 156 155 "CHANGE-REQUEST", 157 &decode_ generic_uint_attr,158 &encode_ generic_uint_attr156 &decode_uint_attr, 157 &encode_uint_attr 159 158 }, 160 159 { 161 160 /* PJ_STUN_ATTR_SOURCE_ADDR, */ 162 161 "SOURCE-ADDRESS", 163 &decode_ generic_ip_addr_attr,164 &encode_ generic_ip_addr_attr162 &decode_ip_addr_attr, 163 &encode_ip_addr_attr 165 164 }, 166 165 { 167 166 /* PJ_STUN_ATTR_CHANGED_ADDR, */ 168 167 "CHANGED-ADDRESS", 169 &decode_ generic_ip_addr_attr,170 &encode_ generic_ip_addr_attr168 &decode_ip_addr_attr, 169 &encode_ip_addr_attr 171 170 }, 172 171 { 173 172 /* PJ_STUN_ATTR_USERNAME, */ 174 173 "USERNAME", 175 &decode_ generic_string_attr,176 &encode_ generic_string_attr174 &decode_string_attr, 175 &encode_string_attr 177 176 }, 178 177 { 179 178 /* PJ_STUN_ATTR_PASSWORD, */ 180 179 "PASSWORD", 181 &decode_ generic_string_attr,182 &encode_ generic_string_attr180 &decode_string_attr, 181 &encode_string_attr 183 182 }, 184 183 { 185 184 /* PJ_STUN_ATTR_MESSAGE_INTEGRITY, */ 186 185 "MESSAGE-INTEGRITY", 187 &decode_msg _integrity_attr,188 &encode_msg _integrity_attr186 &decode_msgint_attr, 187 &encode_msgint_attr 189 188 }, 190 189 { 191 190 /* PJ_STUN_ATTR_ERROR_CODE, */ 192 191 "ERROR-CODE", 193 &decode_err or_code_attr,194 &encode_err or_code_attr192 &decode_errcode_attr, 193 &encode_errcode_attr 195 194 }, 196 195 { … … 203 202 /* PJ_STUN_ATTR_REFLECTED_FROM, */ 204 203 "REFLECTED-FROM", 205 &decode_ generic_ip_addr_attr,206 &encode_ generic_ip_addr_attr204 &decode_ip_addr_attr, 205 &encode_ip_addr_attr 207 206 }, 208 207 { … … 215 214 /* PJ_STUN_ATTR_LIFETIME, */ 216 215 "LIFETIME", 217 &decode_ generic_uint_attr,218 &encode_ generic_uint_attr216 &decode_uint_attr, 217 &encode_uint_attr 219 218 }, 220 219 { … … 233 232 /* PJ_STUN_ATTR_BANDWIDTH, */ 234 233 "BANDWIDTH", 235 &decode_ generic_uint_attr,236 &encode_ generic_uint_attr234 &decode_uint_attr, 235 &encode_uint_attr 237 236 }, 238 237 { … … 245 244 /* PJ_STUN_ATTR_REMOTE_ADDRESS, */ 246 245 "REMOTE-ADDRESS", 247 &decode_ generic_ip_addr_attr,248 &encode_ generic_ip_addr_attr246 &decode_ip_addr_attr, 247 &encode_ip_addr_attr 249 248 }, 250 249 { … … 257 256 /* PJ_STUN_ATTR_REALM, */ 258 257 "REALM", 259 &decode_ generic_string_attr,260 &encode_ generic_string_attr258 &decode_string_attr, 259 &encode_string_attr 261 260 }, 262 261 { 263 262 /* PJ_STUN_ATTR_NONCE, */ 264 263 "NONCE", 265 &decode_ generic_string_attr,266 &encode_ generic_string_attr264 &decode_string_attr, 265 &encode_string_attr 267 266 }, 268 267 { 269 268 /* PJ_STUN_ATTR_RELAY_ADDRESS, */ 270 269 "RELAY-ADDRESS", 271 &decode_ generic_ip_addr_attr,272 &encode_ generic_ip_addr_attr270 &decode_ip_addr_attr, 271 &encode_ip_addr_attr 273 272 }, 274 273 { 275 274 /* PJ_STUN_ATTR_REQUESTED_ADDR_TYPE, */ 276 275 "REQUESTED-ADDRESS-TYPE", 277 &decode_ generic_uint_attr,278 &encode_ generic_uint_attr276 &decode_uint_attr, 277 &encode_uint_attr 279 278 }, 280 279 { 281 280 /* PJ_STUN_ATTR_REQUESTED_PORT_PROPS, */ 282 281 "REQUESTED-PORT-PROPS", 283 &decode_ generic_uint_attr,284 &encode_ generic_uint_attr282 &decode_uint_attr, 283 &encode_uint_attr 285 284 }, 286 285 { 287 286 /* PJ_STUN_ATTR_REQUESTED_TRANSPORT, */ 288 287 "REQUESTED-TRANSPORT", 289 &decode_ generic_uint_attr,290 &encode_ generic_uint_attr288 &decode_uint_attr, 289 &encode_uint_attr 291 290 }, 292 291 { … … 329 328 /* PJ_STUN_ATTR_XOR_MAPPED_ADDRESS, */ 330 329 "XOR-MAPPED-ADDRESS", 331 &decode_ generic_ip_addr_attr,332 &encode_ generic_ip_addr_attr330 &decode_ip_addr_attr, 331 &encode_ip_addr_attr 333 332 }, 334 333 { 335 334 /* PJ_STUN_ATTR_TIMER_VAL, */ 336 335 "TIMER-VAL", 337 &decode_ generic_uint_attr,338 &encode_ generic_uint_attr336 &decode_uint_attr, 337 &encode_uint_attr 339 338 }, 340 339 { 341 340 /* PJ_STUN_ATTR_REQUESTED_IP, */ 342 341 "REQUESTED-IP", 343 &decode_ generic_ip_addr_attr,344 &encode_ generic_ip_addr_attr342 &decode_ip_addr_attr, 343 &encode_ip_addr_attr 345 344 }, 346 345 { 347 346 /* PJ_STUN_ATTR_XOR_REFLECTED_FROM, */ 348 347 "XOR-REFLECTED-FROM", 349 &decode_ generic_ip_addr_attr,350 &encode_ generic_ip_addr_attr348 &decode_ip_addr_attr, 349 &encode_ip_addr_attr 351 350 }, 352 351 { 353 352 /* PJ_STUN_ATTR_PRIORITY, */ 354 353 "PRIORITY", 355 &decode_ generic_uint_attr,356 &encode_ generic_uint_attr354 &decode_uint_attr, 355 &encode_uint_attr 357 356 }, 358 357 { … … 365 364 /* PJ_STUN_ATTR_XOR_INTERNAL_ADDR, */ 366 365 "XOR-INTERNAL-ADDRESS", 367 &decode_ generic_ip_addr_attr,368 &encode_ generic_ip_addr_attr366 &decode_ip_addr_attr, 367 &encode_ip_addr_attr 369 368 }, 370 369 … … 383 382 /* PJ_STUN_ATTR_FINGERPRINT, */ 384 383 "FINGERPRINT", 385 &decode_ generic_uint_attr,386 &encode_ generic_uint_attr384 &decode_uint_attr, 385 &encode_uint_attr 387 386 }, 388 387 { 389 388 /* PJ_STUN_ATTR_SERVER, */ 390 389 "SERVER", 391 &decode_ generic_string_attr,392 &encode_ generic_string_attr390 &decode_string_attr, 391 &encode_string_attr 393 392 }, 394 393 { 395 394 /* PJ_STUN_ATTR_ALTERNATE_SERVER, */ 396 395 "ALTERNATE-SERVER", 397 &decode_ generic_ip_addr_attr,398 &encode_ generic_ip_addr_attr396 &decode_ip_addr_attr, 397 &encode_ip_addr_attr 399 398 }, 400 399 { 401 400 /* PJ_STUN_ATTR_REFRESH_INTERVAL, */ 402 401 "REFRESH-INTERVAL", 403 &decode_ generic_uint_attr,404 &encode_ generic_uint_attr402 &decode_uint_attr, 403 &encode_uint_attr 405 404 }, 406 405 }; … … 515 514 */ 516 515 PJ_DEF(pj_status_t) 517 pj_stun_ generic_ip_addr_attr_create(pj_pool_t *pool,518 519 520 521 522 pj_stun_generic_ip_addr_attr **p_attr)523 { 524 pj_stun_ generic_ip_addr_attr *attr;516 pj_stun_ip_addr_attr_create(pj_pool_t *pool, 517 int attr_type, 518 pj_bool_t xor_ed, 519 const pj_sockaddr_t *addr, 520 unsigned addr_len, 521 pj_stun_ip_addr_attr **p_attr) 522 { 523 pj_stun_ip_addr_attr *attr; 525 524 526 525 PJ_ASSERT_RETURN(pool && addr_len && addr && p_attr, PJ_EINVAL); … … 528 527 addr_len == sizeof(pj_sockaddr_in6), PJ_EINVAL); 529 528 530 attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_ generic_ip_addr_attr);529 attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_ip_addr_attr); 531 530 INIT_ATTR(attr, attr_type, STUN_GENERIC_IP_ADDR_LEN); 532 531 … … 556 555 */ 557 556 PJ_DEF(pj_status_t) 558 pj_stun_msg_add_ generic_ip_addr_attr(pj_pool_t *pool,559 560 561 562 563 564 { 565 pj_stun_ generic_ip_addr_attr *attr;557 pj_stun_msg_add_ip_addr_attr(pj_pool_t *pool, 558 pj_stun_msg *msg, 559 int attr_type, 560 pj_bool_t xor_ed, 561 const pj_sockaddr_t *addr, 562 unsigned addr_len) 563 { 564 pj_stun_ip_addr_attr *attr; 566 565 pj_status_t status; 567 566 568 status = pj_stun_ generic_ip_addr_attr_create(pool, attr_type, xor_ed,567 status = pj_stun_ip_addr_attr_create(pool, attr_type, xor_ed, 569 568 addr, addr_len, &attr); 570 569 if (status != PJ_SUCCESS) … … 574 573 } 575 574 576 static pj_status_t decode_ generic_ip_addr_attr(pj_pool_t *pool,577 578 579 { 580 pj_stun_ generic_ip_addr_attr *attr;575 static pj_status_t decode_ip_addr_attr(pj_pool_t *pool, 576 const pj_uint8_t *buf, 577 void **p_attr) 578 { 579 pj_stun_ip_addr_attr *attr; 581 580 pj_uint32_t val; 582 581 583 582 /* Create the attribute */ 584 attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_ generic_ip_addr_attr);583 attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_ip_addr_attr); 585 584 pj_memcpy(attr, buf, ATTR_HDR_LEN); 586 585 … … 612 611 613 612 614 static pj_status_t encode_ generic_ip_addr_attr(const void *a, pj_uint8_t *buf,615 613 static pj_status_t encode_ip_addr_attr(const void *a, pj_uint8_t *buf, 614 unsigned len, unsigned *printed) 616 615 { 617 616 enum { … … 619 618 }; 620 619 pj_uint8_t *start_buf = buf; 621 const pj_stun_ generic_ip_addr_attr *ca =622 (const pj_stun_ generic_ip_addr_attr *)a;623 pj_stun_ generic_ip_addr_attr *attr;620 const pj_stun_ip_addr_attr *ca = 621 (const pj_stun_ip_addr_attr *)a; 622 pj_stun_ip_addr_attr *attr; 624 623 625 624 if (len < ATTR_LEN) … … 628 627 /* Copy and convert headers to network byte order */ 629 628 pj_memcpy(buf, a, ATTR_HDR_LEN); 630 attr = (pj_stun_ generic_ip_addr_attr*) buf;629 attr = (pj_stun_ip_addr_attr*) buf; 631 630 attr->hdr.type = pj_htons(attr->hdr.type); 632 631 attr->hdr.length = pj_htons((pj_uint16_t)STUN_GENERIC_IP_ADDR_LEN); … … 666 665 */ 667 666 PJ_DEF(pj_status_t) 668 pj_stun_ generic_string_attr_create(pj_pool_t *pool,669 670 671 pj_stun_generic_string_attr **p_attr)672 { 673 pj_stun_ generic_string_attr *attr;667 pj_stun_string_attr_create(pj_pool_t *pool, 668 int attr_type, 669 const pj_str_t *value, 670 pj_stun_string_attr **p_attr) 671 { 672 pj_stun_string_attr *attr; 674 673 675 674 PJ_ASSERT_RETURN(pool && value && p_attr, PJ_EINVAL); 676 675 677 attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_ generic_string_attr);676 attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_string_attr); 678 677 INIT_ATTR(attr, attr_type, value->slen); 679 678 pj_strdup(pool, &attr->value, value); … … 689 688 */ 690 689 PJ_DEF(pj_status_t) 691 pj_stun_msg_add_ generic_string_attr(pj_pool_t *pool,692 693 694 695 { 696 pj_stun_ generic_string_attr *attr;690 pj_stun_msg_add_string_attr(pj_pool_t *pool, 691 pj_stun_msg *msg, 692 int attr_type, 693 const pj_str_t *value) 694 { 695 pj_stun_string_attr *attr; 697 696 pj_status_t status; 698 697 699 status = pj_stun_ generic_string_attr_create(pool, attr_type, value,698 status = pj_stun_string_attr_create(pool, attr_type, value, 700 699 &attr); 701 700 if (status != PJ_SUCCESS) … … 706 705 707 706 708 static pj_status_t decode_ generic_string_attr(pj_pool_t *pool,709 710 711 { 712 pj_stun_ generic_string_attr *attr;707 static pj_status_t decode_string_attr(pj_pool_t *pool, 708 const pj_uint8_t *buf, 709 void **p_attr) 710 { 711 pj_stun_string_attr *attr; 713 712 pj_str_t value; 714 713 715 714 /* Create the attribute */ 716 attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_ generic_string_attr);715 attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_string_attr); 717 716 718 717 /* Copy the header */ … … 738 737 739 738 740 static pj_status_t encode_ generic_string_attr(const void *a, pj_uint8_t *buf,741 742 { 743 const pj_stun_ generic_string_attr *ca =744 (const pj_stun_ generic_string_attr*)a;739 static pj_status_t encode_string_attr(const void *a, pj_uint8_t *buf, 740 unsigned len, unsigned *printed) 741 { 742 const pj_stun_string_attr *ca = 743 (const pj_stun_string_attr*)a; 745 744 pj_stun_attr_hdr *attr; 746 745 … … 857 856 */ 858 857 PJ_DEF(pj_status_t) 859 pj_stun_ generic_uint_attr_create(pj_pool_t *pool,860 861 862 pj_stun_generic_uint_attr **p_attr)863 { 864 pj_stun_ generic_uint_attr *attr;858 pj_stun_uint_attr_create(pj_pool_t *pool, 859 int attr_type, 860 pj_uint32_t value, 861 pj_stun_uint_attr **p_attr) 862 { 863 pj_stun_uint_attr *attr; 865 864 866 865 PJ_ASSERT_RETURN(pool && p_attr, PJ_EINVAL); 867 866 868 attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_ generic_uint_attr);867 attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_uint_attr); 869 868 INIT_ATTR(attr, attr_type, STUN_UINT_LEN); 870 869 attr->value = value; … … 877 876 /* Create and add STUN generic 32bit value attribute to the message. */ 878 877 PJ_DEF(pj_status_t) 879 pj_stun_msg_add_ generic_uint_attr(pj_pool_t *pool,880 881 882 883 { 884 pj_stun_ generic_uint_attr *attr;878 pj_stun_msg_add_uint_attr(pj_pool_t *pool, 879 pj_stun_msg *msg, 880 int attr_type, 881 pj_uint32_t value) 882 { 883 pj_stun_uint_attr *attr; 885 884 pj_status_t status; 886 885 887 status = pj_stun_ generic_uint_attr_create(pool, attr_type, value, &attr);886 status = pj_stun_uint_attr_create(pool, attr_type, value, &attr); 888 887 if (status != PJ_SUCCESS) 889 888 return status; … … 892 891 } 893 892 894 static pj_status_t decode_ generic_uint_attr(pj_pool_t *pool,895 896 893 static pj_status_t decode_uint_attr(pj_pool_t *pool, 894 const pj_uint8_t *buf, 895 void **p_attr) 897 896 { 898 897 enum … … 900 899 ATTR_LEN = STUN_UINT_LEN + ATTR_HDR_LEN 901 900 }; 902 pj_stun_ generic_uint_attr *attr;901 pj_stun_uint_attr *attr; 903 902 904 903 /* Check that the struct address is valid */ 905 pj_assert(sizeof(pj_stun_ generic_uint_attr) == ATTR_LEN);904 pj_assert(sizeof(pj_stun_uint_attr) == ATTR_LEN); 906 905 907 906 /* Create the attribute */ 908 attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_ generic_uint_attr);907 attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_uint_attr); 909 908 pj_memcpy(attr, buf, ATTR_LEN); 910 909 … … 925 924 926 925 927 static pj_status_t encode_ generic_uint_attr(const void *a, pj_uint8_t *buf,928 926 static pj_status_t encode_uint_attr(const void *a, pj_uint8_t *buf, 927 unsigned len, unsigned *printed) 929 928 { 930 929 enum … … 932 931 ATTR_LEN = STUN_UINT_LEN + ATTR_HDR_LEN 933 932 }; 934 pj_stun_ generic_uint_attr *attr;933 pj_stun_uint_attr *attr; 935 934 936 935 if (len < ATTR_LEN) … … 939 938 /* Copy and convert attribute to network byte order */ 940 939 pj_memcpy(buf, a, ATTR_LEN); 941 attr = (pj_stun_ generic_uint_attr*) buf;940 attr = (pj_stun_uint_attr*) buf; 942 941 attr->hdr.type = pj_htons(attr->hdr.type); 943 942 pj_assert(attr->hdr.length == STUN_UINT_LEN); … … 962 961 */ 963 962 PJ_DEF(pj_status_t) 964 pj_stun_msg _integrity_attr_create(pj_pool_t *pool,965 pj_stun_msg_integrity_attr **p_attr)966 { 967 pj_stun_msg _integrity_attr *attr;963 pj_stun_msgint_attr_create(pj_pool_t *pool, 964 pj_stun_msgint_attr **p_attr) 965 { 966 pj_stun_msgint_attr *attr; 968 967 969 968 PJ_ASSERT_RETURN(pool && p_attr, PJ_EINVAL); 970 969 971 attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_msg _integrity_attr);970 attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_msgint_attr); 972 971 INIT_ATTR(attr, PJ_STUN_ATTR_MESSAGE_INTEGRITY, STUN_MSG_INTEGRITY_LEN); 973 972 … … 978 977 979 978 980 static pj_status_t decode_msg_integrity_attr(pj_pool_t *pool, 981 const pj_uint8_t *buf, 982 void **p_attr) 979 PJ_DEF(pj_status_t) pj_stun_msg_add_msgint_attr(pj_pool_t *pool, 980 pj_stun_msg *msg) 981 { 982 pj_stun_msgint_attr *attr; 983 pj_status_t status; 984 985 status = pj_stun_msgint_attr_create(pool, &attr); 986 if (status != PJ_SUCCESS) 987 return status; 988 989 return pj_stun_msg_add_attr(msg, &attr->hdr); 990 } 991 992 static pj_status_t decode_msgint_attr(pj_pool_t *pool, 993 const pj_uint8_t *buf, 994 void **p_attr) 983 995 { 984 996 enum … … 986 998 ATTR_LEN = STUN_MSG_INTEGRITY_LEN + ATTR_HDR_LEN 987 999 }; 988 pj_stun_msg _integrity_attr *attr;1000 pj_stun_msgint_attr *attr; 989 1001 990 1002 /* Check that struct size is valid */ 991 pj_assert(sizeof(pj_stun_msg _integrity_attr)==ATTR_LEN);1003 pj_assert(sizeof(pj_stun_msgint_attr)==ATTR_LEN); 992 1004 993 1005 /* Create attribute */ 994 attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_msg _integrity_attr);995 pj_memcpy(attr, buf, sizeof(pj_stun_msg _integrity_attr));1006 attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_msgint_attr); 1007 pj_memcpy(attr, buf, sizeof(pj_stun_msgint_attr)); 996 1008 attr->hdr.type = pj_ntohs(attr->hdr.type); 997 1009 attr->hdr.length = pj_ntohs(attr->hdr.length); … … 1007 1019 1008 1020 1009 static pj_status_t encode_msg _integrity_attr(const void *a, pj_uint8_t *buf,1010 1021 static pj_status_t encode_msgint_attr(const void *a, pj_uint8_t *buf, 1022 unsigned len, unsigned *printed) 1011 1023 { 1012 1024 enum … … 1014 1026 ATTR_LEN = STUN_MSG_INTEGRITY_LEN + ATTR_HDR_LEN 1015 1027 }; 1016 pj_stun_msg _integrity_attr *attr;1028 pj_stun_msgint_attr *attr; 1017 1029 1018 1030 if (len < ATTR_LEN) … … 1021 1033 /* Copy and convert attribute to network byte order */ 1022 1034 pj_memcpy(buf, a, ATTR_LEN); 1023 attr = (pj_stun_msg _integrity_attr*) buf;1035 attr = (pj_stun_msgint_attr*) buf; 1024 1036 attr->hdr.type = pj_htons(attr->hdr.type); 1025 1037 pj_assert(attr->hdr.length == STUN_MSG_INTEGRITY_LEN); … … 1041 1053 */ 1042 1054 PJ_DEF(pj_status_t) 1043 pj_stun_err or_code_attr_create(pj_pool_t *pool,1044 1045 1046 pj_stun_error_code_attr **p_attr)1047 { 1048 pj_stun_err or_code_attr *attr;1055 pj_stun_errcode_attr_create(pj_pool_t *pool, 1056 int err_code, 1057 const pj_str_t *err_reason, 1058 pj_stun_errcode_attr **p_attr) 1059 { 1060 pj_stun_errcode_attr *attr; 1049 1061 char err_buf[80]; 1050 1062 pj_str_t str; … … 1062 1074 } 1063 1075 1064 attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_err or_code_attr);1076 attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_errcode_attr); 1065 1077 INIT_ATTR(attr, PJ_STUN_ATTR_ERROR_CODE, 4+err_reason->slen); 1066 1078 attr->err_class = (pj_uint8_t)(err_code / 100); … … 1074 1086 1075 1087 1076 static pj_status_t decode_error_code_attr(pj_pool_t *pool, 1077 const pj_uint8_t *buf, 1078 void **p_attr) 1079 { 1080 pj_stun_error_code_attr *attr; 1088 PJ_DEF(pj_status_t) pj_stun_msg_add_errcode_attr(pj_pool_t *pool, 1089 pj_stun_msg *msg, 1090 int err_code, 1091 const pj_str_t *err_reason) 1092 { 1093 pj_stun_errcode_attr *err_attr; 1094 pj_status_t status; 1095 1096 status = pj_stun_errcode_attr_create(pool, err_code, err_reason, 1097 &err_attr); 1098 if (status != PJ_SUCCESS) 1099 return status; 1100 1101 return pj_stun_msg_add_attr(msg, &err_attr->hdr); 1102 } 1103 1104 static pj_status_t decode_errcode_attr(pj_pool_t *pool, 1105 const pj_uint8_t *buf, 1106 void **p_attr) 1107 { 1108 pj_stun_errcode_attr *attr; 1081 1109 pj_str_t value; 1082 1110 1083 1111 /* Create the attribute */ 1084 attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_err or_code_attr);1112 attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_errcode_attr); 1085 1113 1086 1114 /* Copy the header */ … … 1105 1133 1106 1134 1107 static pj_status_t encode_err or_code_attr(const void *a, pj_uint8_t *buf,1108 1109 { 1110 const pj_stun_err or_code_attr *ca =1111 (const pj_stun_err or_code_attr*)a;1112 pj_stun_err or_code_attr *attr;1135 static pj_status_t encode_errcode_attr(const void *a, pj_uint8_t *buf, 1136 unsigned len, unsigned *printed) 1137 { 1138 const pj_stun_errcode_attr *ca = 1139 (const pj_stun_errcode_attr*)a; 1140 pj_stun_errcode_attr *attr; 1113 1141 1114 1142 if (len < ATTR_HDR_LEN + 4 + (unsigned)ca->reason.slen) … … 1119 1147 1120 1148 /* Update length */ 1121 attr = (pj_stun_err or_code_attr*) buf;1149 attr = (pj_stun_errcode_attr*) buf; 1122 1150 attr->hdr.length = (pj_uint16_t)(4 + ca->reason.slen); 1123 1151 … … 1508 1536 unsigned msg_type = req_msg->hdr.type; 1509 1537 pj_stun_msg *response; 1510 pj_stun_error_code_attr *err_attr;1511 1538 pj_status_t status; 1512 1539 … … 1530 1557 /* Add error code attribute */ 1531 1558 if (err_code) { 1532 status = pj_stun_ error_code_attr_create(pool, err_code, err_msg,1533 &err_attr);1559 status = pj_stun_msg_add_errcode_attr(pool, response, 1560 err_code, err_msg); 1534 1561 if (status != PJ_SUCCESS) { 1535 1562 return status; 1536 1563 } 1537 1538 pj_stun_msg_add_attr(response, &err_attr->hdr);1539 1564 } 1540 1565 … … 1703 1728 NULL, p_response); 1704 1729 } 1705 return PJ _STATUS_FROM_STUN_CODE(PJ_STUN_STATUS_BAD_REQUEST);1730 return PJLIB_UTIL_ESTUNDUPATTR; 1706 1731 } 1707 1732 has_msg_int = PJ_TRUE; … … 1717 1742 NULL, p_response); 1718 1743 } 1719 return PJ _STATUS_FROM_STUN_CODE(PJ_STUN_STATUS_BAD_REQUEST);1744 return PJLIB_UTIL_ESTUNDUPATTR; 1720 1745 } 1721 1746 has_fingerprint = PJ_TRUE; … … 1731 1756 NULL, p_response); 1732 1757 } 1733 return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_STATUS_BAD_REQUEST); 1758 return has_fingerprint ? PJLIB_UTIL_ESTUNFINGERPOS : 1759 PJLIB_UTIL_ESTUNMSGINTPOS; 1734 1760 } 1735 1761 } … … 1767 1793 * MD5 digest of username, realm, and password. 1768 1794 */ 1769 static voidcalc_md5_key(pj_uint8_t digest[16],1770 const pj_str_t *realm,1771 const pj_str_t *username,1772 const pj_str_t *passwd)1795 void pj_stun_calc_md5_key(pj_uint8_t digest[16], 1796 const pj_str_t *realm, 1797 const pj_str_t *username, 1798 const pj_str_t *passwd) 1773 1799 { 1774 1800 /* The 16-byte key for MESSAGE-INTEGRITY HMAC is formed by taking … … 1828 1854 pj_stun_realm_attr *arealm = NULL; 1829 1855 pj_stun_username_attr *auname = NULL; 1830 pj_stun_msg _integrity_attr *amsg_integrity= NULL;1856 pj_stun_msgint_attr *amsgint = NULL; 1831 1857 pj_stun_fingerprint_attr *afingerprint = NULL; 1832 1858 unsigned printed; … … 1860 1886 1861 1887 if (attr_hdr->type == PJ_STUN_ATTR_MESSAGE_INTEGRITY) { 1862 pj_assert(amsg _integrity== NULL);1863 amsg _integrity = (pj_stun_msg_integrity_attr*) attr_hdr;1888 pj_assert(amsgint == NULL); 1889 amsgint = (pj_stun_msgint_attr*) attr_hdr; 1864 1890 1865 1891 /* Stop when encountering MESSAGE-INTEGRITY */ … … 1902 1928 if (attr_hdr->type == PJ_STUN_ATTR_MESSAGE_INTEGRITY) { 1903 1929 /* There mustn't be MESSAGE-INTEGRITY before */ 1904 PJ_ASSERT_RETURN(amsg _integrity== NULL,1930 PJ_ASSERT_RETURN(amsgint == NULL, 1905 1931 PJLIB_UTIL_ESTUNMSGINTPOS); 1906 amsg _integrity = (pj_stun_msg_integrity_attr*) attr_hdr;1932 amsgint = (pj_stun_msgint_attr*) attr_hdr; 1907 1933 1908 1934 } else if (attr_hdr->type == PJ_STUN_ATTR_FINGERPRINT) { … … 1915 1941 * Note that length is not including the 20 bytes header. 1916 1942 */ 1917 if (amsg _integrity&& afingerprint) {1943 if (amsgint && afingerprint) { 1918 1944 msg->hdr.length = (pj_uint16_t)((buf - start) - 20 + 24 + 8); 1919 } else if (amsg _integrity) {1945 } else if (amsgint) { 1920 1946 msg->hdr.length = (pj_uint16_t)((buf - start) - 20 + 24); 1921 1947 } else if (afingerprint) { … … 1930 1956 1931 1957 /* Calculate message integrity, if present */ 1932 if (amsg _integrity!= NULL) {1958 if (amsgint != NULL) { 1933 1959 1934 1960 pj_uint8_t md5_key_buf[16]; … … 1969 1995 1970 1996 } else { 1971 calc_md5_key(md5_key_buf, &arealm->value, &auname->value,1972 password);1997 pj_stun_calc_md5_key(md5_key_buf, &arealm->value, 1998 &auname->value, password); 1973 1999 key.ptr = (char*) md5_key_buf; 1974 2000 key.slen = 16; … … 1978 2004 pj_hmac_sha1((pj_uint8_t*)buf, buf-start, 1979 2005 (pj_uint8_t*)key.ptr, key.slen, 1980 amsg _integrity->hmac);2006 amsgint->hmac); 1981 2007 1982 2008 /* Put this attribute in the message */ 1983 status = encode_msg _integrity_attr(amsg_integrity, buf, buf_size,1984 2009 status = encode_msgint_attr(amsgint, buf, buf_size, 2010 &printed); 1985 2011 if (status != PJ_SUCCESS) 1986 2012 return status; … … 1996 2022 1997 2023 /* Put this attribute in the message */ 1998 status = encode_ generic_uint_attr(afingerprint, buf, buf_size,2024 status = encode_uint_attr(afingerprint, buf, buf_size, 1999 2025 &printed); 2000 2026 if (status != PJ_SUCCESS) … … 2025 2051 for (; index < msg->attr_count; ++index) { 2026 2052 if (msg->attr[index]->type == attr_type) 2027 return (pj_stun_attr_hdr*) &msg->attr[index];2053 return (pj_stun_attr_hdr*) msg->attr[index]; 2028 2054 } 2029 2055 … … 2031 2057 } 2032 2058 2033 2034 /**************************************************************************/2035 /*2036 * Authentication2037 */2038 2039 2040 /* Send 401 response */2041 static pj_status_t create_challenge(pj_pool_t *pool,2042 const pj_stun_msg *msg,2043 int err_code,2044 const pj_str_t *err_msg,2045 const pj_str_t *realm,2046 const pj_str_t *nonce,2047 pj_stun_msg **p_response)2048 {2049 pj_stun_msg *response;2050 pj_status_t rc;2051 2052 rc = pj_stun_msg_create_response(pool, msg,2053 err_code, err_msg, &response);2054 if (rc != PJ_SUCCESS)2055 return rc;2056 2057 2058 if (realm && realm->slen) {2059 rc = pj_stun_msg_add_generic_string_attr(pool, response,2060 PJ_STUN_ATTR_REALM,2061 realm);2062 if (rc != PJ_SUCCESS)2063 return rc;2064 }2065 2066 if (nonce && nonce->slen) {2067 rc = pj_stun_msg_add_generic_string_attr(pool, response,2068 PJ_STUN_ATTR_NONCE,2069 nonce);2070 if (rc != PJ_SUCCESS)2071 return rc;2072 }2073 2074 *p_response = response;2075 2076 return PJ_SUCCESS;2077 }2078 2079 /* Verify credential */2080 PJ_DEF(pj_status_t) pj_stun_verify_credential( const pj_uint8_t *pkt,2081 unsigned pkt_len,2082 const pj_stun_msg *msg,2083 pj_stun_auth_policy *pol,2084 pj_pool_t *pool,2085 pj_stun_msg **p_response)2086 {2087 pj_str_t realm, nonce, password;2088 const pj_stun_msg_integrity_attr *amsgi;2089 unsigned amsgi_pos;2090 const pj_stun_username_attr *auser;2091 pj_bool_t username_ok;2092 const pj_stun_realm_attr *arealm;2093 const pj_stun_realm_attr *anonce;2094 pj_uint8_t digest[PJ_SHA1_DIGEST_SIZE];2095 pj_uint8_t md5_digest[16];2096 pj_str_t key;2097 pj_status_t status;2098 2099 /* msg and policy MUST be specified */2100 PJ_ASSERT_RETURN(pkt && pkt_len && msg && pol, PJ_EINVAL);2101 2102 /* If p_response is specified, pool MUST be specified. */2103 PJ_ASSERT_RETURN(!p_response || pool, PJ_EINVAL);2104 2105 if (p_response)2106 *p_response = NULL;2107 2108 if (!PJ_STUN_IS_REQUEST(msg->hdr.type))2109 p_response = NULL;2110 2111 /* Get realm and nonce */2112 realm.slen = nonce.slen = 0;2113 if (pol->type == PJ_STUN_POLICY_STATIC_SHORT_TERM) {2114 realm.slen = 0;2115 nonce = pol->data.static_short_term.nonce;2116 } else if (pol->type == PJ_STUN_POLICY_STATIC_LONG_TERM) {2117 realm = pol->data.static_long_term.realm;2118 nonce = pol->data.static_long_term.nonce;2119 } else if (pol->type == PJ_STUN_POLICY_DYNAMIC) {2120 status = pol->data.dynamic.get_auth(pol->user_data, pool,2121 &realm, &nonce);2122 if (status != PJ_SUCCESS)2123 return status;2124 } else {2125 pj_assert(!"Unexpected");2126 return PJ_EBUG;2127 }2128 2129 /* First check that MESSAGE-INTEGRITY is present */2130 amsgi = (const pj_stun_msg_integrity_attr*)2131 pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_MESSAGE_INTEGRITY, 0);2132 if (amsgi == NULL) {2133 if (p_response) {2134 create_challenge(pool, msg, PJ_STUN_STATUS_UNAUTHORIZED, NULL,2135 &realm, &nonce, p_response);2136 }2137 return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_STATUS_UNAUTHORIZED);2138 }2139 2140 /* Next check that USERNAME is present */2141 auser = (const pj_stun_username_attr*)2142 pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_USERNAME, 0);2143 if (auser == NULL) {2144 if (p_response) {2145 create_challenge(pool, msg, PJ_STUN_STATUS_MISSING_USERNAME, NULL,2146 &realm, &nonce, p_response);2147 }2148 return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_STATUS_MISSING_USERNAME);2149 }2150 2151 /* Get REALM, if any */2152 arealm = (const pj_stun_realm_attr*)2153 pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_REALM, 0);2154 2155 /* Check if username match */2156 if (pol->type == PJ_STUN_POLICY_STATIC_SHORT_TERM) {2157 username_ok = !pj_strcmp(&auser->value,2158 &pol->data.static_short_term.username);2159 password = pol->data.static_short_term.password;2160 } else if (pol->type == PJ_STUN_POLICY_STATIC_LONG_TERM) {2161 username_ok = !pj_strcmp(&auser->value,2162 &pol->data.static_long_term.username);2163 password = pol->data.static_long_term.password;2164 } else if (pol->type == PJ_STUN_POLICY_DYNAMIC) {2165 pj_status_t rc;2166 rc = pol->data.dynamic.get_password(pol->user_data,2167 (arealm?&arealm->value:NULL),2168 &auser->value, pool,2169 &password);2170 username_ok = (rc == PJ_SUCCESS);2171 } else {2172 username_ok = PJ_TRUE;2173 password.slen = 0;2174 }2175 2176 if (!username_ok) {2177 /* Username mismatch */2178 if (p_response) {2179 create_challenge(pool, msg, PJ_STUN_STATUS_UNKNOWN_USERNAME, NULL,2180 &realm, &nonce, p_response);2181 }2182 return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_STATUS_UNKNOWN_USERNAME);2183 }2184 2185 2186 /* Get NONCE attribute */2187 anonce = (pj_stun_nonce_attr*)2188 pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_NONCE, 0);2189 2190 /* Check for long term/short term requirements. */2191 if (realm.slen != 0 && arealm == NULL) {2192 /* Long term credential is required and REALM is not present */2193 if (p_response) {2194 create_challenge(pool, msg, PJ_STUN_STATUS_MISSING_REALM, NULL,2195 &realm, &nonce, p_response);2196 }2197 return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_STATUS_MISSING_REALM);2198 2199 } else if (realm.slen != 0 && arealm != NULL) {2200 /* We want long term, and REALM is present */2201 2202 /* NONCE must be present. */2203 if (anonce == NULL) {2204 if (p_response) {2205 create_challenge(pool, msg, PJ_STUN_STATUS_MISSING_NONCE,2206 NULL, &realm, &nonce, p_response);2207 }2208 return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_STATUS_MISSING_NONCE);2209 }2210 2211 /* Verify REALM matches */2212 if (pj_stricmp(&arealm->value, &realm)) {2213 /* REALM doesn't match */2214 if (p_response) {2215 create_challenge(pool, msg, PJ_STUN_STATUS_MISSING_REALM,2216 NULL, &realm, &nonce, p_response);2217 }2218 return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_STATUS_MISSING_REALM);2219 }2220 2221 /* Valid case, will validate the message integrity later */2222 2223 } else if (realm.slen == 0 && arealm != NULL) {2224 /* We want to use short term credential, but client uses long2225 * term credential. The draft doesn't mention anything about2226 * switching between long term and short term.2227 */2228 2229 /* For now just accept the credential, anyway it will probably2230 * cause wrong message integrity value later.2231 */2232 } else if (realm.slen==0 && arealm == NULL) {2233 /* Short term authentication is wanted, and one is supplied */2234 2235 /* Application MAY request NONCE to be supplied */2236 if (nonce.slen != 0) {2237 if (p_response) {2238 create_challenge(pool, msg, PJ_STUN_STATUS_MISSING_NONCE,2239 NULL, &realm, &nonce, p_response);2240 }2241 return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_STATUS_MISSING_NONCE);2242 }2243 }2244 2245 /* If NONCE is present, validate it */2246 if (anonce) {2247 pj_bool_t ok;2248 2249 if (pol->type == PJ_STUN_POLICY_DYNAMIC) {2250 ok = pol->data.dynamic.verify_nonce(pol->user_data,2251 (arealm?&arealm->value:NULL),2252 &auser->value,2253 &anonce->value);2254 } else {2255 if (nonce.slen) {2256 ok = !pj_strcmp(&anonce->value, &nonce);2257 } else {2258 ok = PJ_TRUE;2259 }2260 }2261 2262 if (!ok) {2263 if (p_response) {2264 create_challenge(pool, msg, PJ_STUN_STATUS_STALE_NONCE,2265 NULL, &realm, &nonce, p_response);2266 }2267 return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_STATUS_STALE_NONCE);2268 }2269 }2270 2271 /* Get the position of MESSAGE-INTEGRITY in the packet */2272 amsgi_pos = 20+msg->hdr.length-22;2273 if (GET_VAL16(pkt, amsgi_pos) == PJ_STUN_ATTR_MESSAGE_INTEGRITY) {2274 /* Found MESSAGE-INTEGRITY as the last attribute */2275 } else {2276 amsgi_pos = 0;2277 }2278 2279 if (amsgi_pos==0) {2280 amsgi_pos = 20+msg->hdr.length-8-22;2281 if (GET_VAL16(pkt, amsgi_pos) == PJ_STUN_ATTR_MESSAGE_INTEGRITY) {2282 /* Found MESSAGE-INTEGRITY before FINGERPRINT */2283 } else {2284 amsgi_pos = 0;2285 }2286 }2287 2288 if (amsgi_pos==0) {2289 pj_assert(!"Unable to find MESSAGE-INTEGRITY in the message!");2290 return PJ_EBUG;2291 }2292 2293 /* Determine which key to use */2294 if (realm.slen) {2295 calc_md5_key(md5_digest, &realm, &auser->value, &password);2296 key.ptr = (char*)md5_digest;2297 key.slen = 16;2298 } else {2299 key = password;2300 }2301 2302 /* Now calculate HMAC of the message */2303 pj_hmac_sha1(pkt, amsgi_pos, (pj_uint8_t*)key.ptr, key.slen, digest);2304 2305 /* Compare HMACs */2306 if (pj_memcmp(amsgi->hmac, digest, 20)) {2307 /* HMAC value mismatch */2308 if (p_response) {2309 create_challenge(pool, msg, PJ_STUN_STATUS_INTEGRITY_CHECK_FAILURE,2310 NULL, &realm, &nonce, p_response);2311 }2312 return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_STATUS_INTEGRITY_CHECK_FAILURE);2313 }2314 2315 /* Everything looks okay! */2316 return PJ_SUCCESS;2317 }2318 2319 -
pjproject/trunk/pjlib-util/src/pjlib-util/stun_msg_dump.c
r996 r1037 54 54 case PJ_STUN_ATTR_ALTERNATE_SERVER: 55 55 { 56 const pj_stun_ generic_ip_addr_attr *attr;57 58 attr = (const pj_stun_ generic_ip_addr_attr*)ahdr;56 const pj_stun_ip_addr_attr *attr; 57 58 attr = (const pj_stun_ip_addr_attr*)ahdr; 59 59 60 60 if (attr->addr.addr.sa_family == PJ_AF_INET) { … … 85 85 case PJ_STUN_ATTR_REFRESH_INTERVAL: 86 86 { 87 const pj_stun_ generic_uint_attr *attr;88 89 attr = (const pj_stun_ generic_uint_attr*)ahdr;87 const pj_stun_uint_attr *attr; 88 89 attr = (const pj_stun_uint_attr*)ahdr; 90 90 len = pj_ansi_snprintf(p, end-p, 91 91 ", value=%d (0x%x)\n", … … 101 101 case PJ_STUN_ATTR_SERVER: 102 102 { 103 const pj_stun_ generic_string_attr *attr;104 105 attr = (pj_stun_ generic_string_attr*)ahdr;103 const pj_stun_string_attr *attr; 104 105 attr = (pj_stun_string_attr*)ahdr; 106 106 len = pj_ansi_snprintf(p, end-p, 107 107 ", value=\"%.*s\"\n", … … 113 113 case PJ_STUN_ATTR_ERROR_CODE: 114 114 { 115 const pj_stun_err or_code_attr *attr;116 117 attr = (const pj_stun_err or_code_attr*) ahdr;115 const pj_stun_errcode_attr *attr; 116 117 attr = (const pj_stun_errcode_attr*) ahdr; 118 118 len = pj_ansi_snprintf(p, end-p, 119 119 ", err_code=%d, reason=\"%.*s\"\n", -
pjproject/trunk/pjlib-util/src/pjlib-util/stun_session.c
r1034 r1037 28 28 void *user_data; 29 29 30 /* Long term credential */ 31 pj_str_t l_realm; 32 pj_str_t l_username; 33 pj_str_t l_password; 34 35 /* Short term credential */ 36 pj_str_t s_username; 37 pj_str_t s_password; 30 pj_bool_t use_fingerprint; 31 pj_stun_auth_cred *cred; 32 pj_str_t srv_name; 38 33 39 34 pj_stun_tx_data pending_request_list; … … 214 209 } 215 210 211 static pj_str_t *get_passwd(pj_stun_session *sess) 212 { 213 if (sess->cred == NULL) 214 return NULL; 215 else if (sess->cred->type == PJ_STUN_AUTH_CRED_STATIC) 216 return &sess->cred->data.static_cred.data; 217 else 218 return NULL; 219 } 220 216 221 static pj_status_t apply_msg_options(pj_stun_session *sess, 217 222 pj_pool_t *pool, 218 unsigned options, 219 pj_stun_msg *msg, 220 pj_str_t **p_passwd) 221 { 222 pj_status_t status; 223 pj_stun_msg *msg) 224 { 225 pj_status_t status = 0; 226 227 /* The server SHOULD include a SERVER attribute in all responses */ 228 if (PJ_STUN_IS_RESPONSE(msg->hdr.type) || 229 PJ_STUN_IS_ERROR_RESPONSE(msg->hdr.type)) 230 { 231 pj_stun_msg_add_string_attr(pool, msg, PJ_STUN_ATTR_SERVER, 232 &sess->srv_name); 233 } 223 234 224 235 /* From draft-ietf-behave-rfc3489bis-05.txt 225 236 * Section 8.3.1. Formulating the Request Message 237 * 238 * Note: only put MESSAGE-INTEGRITY in non error response. 226 239 */ 227 if (options & PJ_STUN_USE_LONG_TERM_CRED) { 228 pj_stun_generic_string_attr *auname; 229 pj_stun_msg_integrity_attr *amsgi; 230 pj_stun_generic_string_attr *arealm; 231 232 *p_passwd = &sess->l_password; 240 if (sess->cred && sess->cred->type == PJ_STUN_AUTH_CRED_STATIC && 241 !PJ_STUN_IS_ERROR_RESPONSE(msg->hdr.type)) 242 { 243 const pj_str_t *username; 233 244 234 245 /* Create and add USERNAME attribute */ 235 status = pj_stun_generic_string_attr_create(pool,236 PJ_STUN_ATTR_USERNAME,237 &sess->l_username,238 &auname);246 username = &sess->cred->data.static_cred.username; 247 status = pj_stun_msg_add_string_attr(pool, msg, 248 PJ_STUN_ATTR_USERNAME, 249 username); 239 250 PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 240 251 241 status = pj_stun_msg_add_attr(msg, &auname->hdr); 252 /* Add REALM only when long term credential is used */ 253 if (sess->cred->data.static_cred.realm.slen) { 254 const pj_str_t *realm = &sess->cred->data.static_cred.realm; 255 status = pj_stun_msg_add_string_attr(pool, msg, 256 PJ_STUN_ATTR_REALM, 257 realm); 258 } 259 260 /* Add MESSAGE-INTEGRITY attribute */ 261 status = pj_stun_msg_add_msgint_attr(pool, msg); 242 262 PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 243 263 244 /* Add REALM only when long term credential is used */ 245 status = pj_stun_generic_string_attr_create(pool, 246 PJ_STUN_ATTR_REALM, 247 &sess->l_realm, 248 &arealm); 249 PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 250 251 status = pj_stun_msg_add_attr(msg, &arealm->hdr); 252 PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 253 254 /* Add MESSAGE-INTEGRITY attribute */ 255 status = pj_stun_msg_integrity_attr_create(pool, &amsgi); 256 PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 257 258 status = pj_stun_msg_add_attr(msg, &amsgi->hdr); 259 PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 260 261 } else if (options & PJ_STUN_USE_SHORT_TERM_CRED) { 262 pj_stun_generic_string_attr *auname; 263 pj_stun_msg_integrity_attr *amsgi; 264 265 *p_passwd = &sess->s_password; 266 267 /* Create and add USERNAME attribute */ 268 status = pj_stun_generic_string_attr_create(pool, 269 PJ_STUN_ATTR_USERNAME, 270 &sess->s_username, 271 &auname); 272 PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 273 274 status = pj_stun_msg_add_attr(msg, &auname->hdr); 275 PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 276 277 /* Add MESSAGE-INTEGRITY attribute */ 278 status = pj_stun_msg_integrity_attr_create(pool, &amsgi); 279 PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 280 281 status = pj_stun_msg_add_attr(msg, &amsgi->hdr); 282 PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 283 284 } else { 285 *p_passwd = NULL; 286 } 264 } 287 265 288 266 /* Add FINGERPRINT attribute if necessary */ 289 if (options & PJ_STUN_USE_FINGERPRINT) { 290 pj_stun_fingerprint_attr *af; 291 292 status = pj_stun_generic_uint_attr_create(pool, 293 PJ_STUN_ATTR_FINGERPRINT, 294 0, &af); 295 PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 296 297 status = pj_stun_msg_add_attr(msg, &af->hdr); 267 if (sess->use_fingerprint) { 268 status = pj_stun_msg_add_uint_attr(pool, msg, 269 PJ_STUN_ATTR_FINGERPRINT, 0); 298 270 PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 299 271 } … … 334 306 const char *name, 335 307 const pj_stun_session_cb *cb, 308 pj_bool_t fingerprint, 336 309 pj_stun_session **p_sess) 337 310 { … … 352 325 sess->pool = pool; 353 326 pj_memcpy(&sess->cb, cb, sizeof(*cb)); 327 sess->use_fingerprint = fingerprint; 328 329 sess->srv_name.ptr = pj_pool_alloc(pool, 32); 330 sess->srv_name.slen = pj_ansi_snprintf(sess->srv_name.ptr, 32, 331 "pj_stun-%s", PJ_VERSION); 354 332 355 333 pj_list_init(&sess->pending_request_list); … … 394 372 } 395 373 396 PJ_DEF(pj_status_t) 397 pj_stun_session_set_long_term_credential(pj_stun_session *sess, 398 const pj_str_t *realm, 399 const pj_str_t *user, 400 const pj_str_t *passwd) 401 { 402 pj_str_t nil = { NULL, 0 }; 403 404 PJ_ASSERT_RETURN(sess, PJ_EINVAL); 405 406 pj_mutex_lock(sess->mutex); 407 pj_strdup_with_null(sess->pool, &sess->l_realm, realm ? realm : &nil); 408 pj_strdup_with_null(sess->pool, &sess->l_username, user ? user : &nil); 409 pj_strdup_with_null(sess->pool, &sess->l_password, passwd ? passwd : &nil); 410 pj_mutex_unlock(sess->mutex); 411 412 return PJ_SUCCESS; 413 } 414 415 416 PJ_DEF(pj_status_t) 417 pj_stun_session_set_short_term_credential(pj_stun_session *sess, 418 const pj_str_t *user, 419 const pj_str_t *passwd) 420 { 421 pj_str_t nil = { NULL, 0 }; 422 423 PJ_ASSERT_RETURN(sess, PJ_EINVAL); 424 425 pj_mutex_lock(sess->mutex); 426 pj_strdup_with_null(sess->pool, &sess->s_username, user ? user : &nil); 427 pj_strdup_with_null(sess->pool, &sess->s_password, passwd ? passwd : &nil); 428 pj_mutex_unlock(sess->mutex); 429 430 return PJ_SUCCESS; 374 PJ_DEF(pj_status_t) pj_stun_session_set_server_name(pj_stun_session *sess, 375 const pj_str_t *srv_name) 376 { 377 PJ_ASSERT_RETURN(sess && srv_name, PJ_EINVAL); 378 pj_strdup(sess->pool, &sess->srv_name, srv_name); 379 return PJ_SUCCESS; 380 } 381 382 PJ_DEF(void) pj_stun_session_set_credential(pj_stun_session *sess, 383 const pj_stun_auth_cred *cred) 384 { 385 PJ_ASSERT_ON_FAIL(sess, return); 386 if (cred) { 387 if (!sess->cred) 388 sess->cred = pj_pool_alloc(sess->pool, sizeof(pj_stun_auth_cred)); 389 pj_stun_auth_cred_dup(sess->pool, sess->cred, cred); 390 } else { 391 sess->cred = NULL; 392 } 431 393 } 432 394 … … 570 532 571 533 PJ_DEF(pj_status_t) pj_stun_session_send_msg( pj_stun_session *sess, 572 unsigned options,534 pj_bool_t cache_res, 573 535 const pj_sockaddr_t *server, 574 536 unsigned addr_len, 575 537 pj_stun_tx_data *tdata) 576 538 { 577 pj_str_t *password;578 539 pj_status_t status; 579 540 580 541 PJ_ASSERT_RETURN(sess && addr_len && server && tdata, PJ_EINVAL); 581 582 tdata->options = options;583 542 584 543 /* Allocate packet */ … … 590 549 591 550 /* Apply options */ 592 status = apply_msg_options(sess, tdata->pool, options, 593 tdata->msg, &password); 551 status = apply_msg_options(sess, tdata->pool, tdata->msg); 594 552 if (status != PJ_SUCCESS) { 595 553 pj_stun_msg_destroy_tdata(sess, tdata); … … 601 559 /* Encode message */ 602 560 status = pj_stun_msg_encode(tdata->msg, tdata->pkt, tdata->max_len, 603 0, password, &tdata->pkt_size);561 0, get_passwd(sess), &tdata->pkt_size); 604 562 if (status != PJ_SUCCESS) { 605 563 pj_stun_msg_destroy_tdata(sess, tdata); … … 641 599 642 600 } else { 643 if ( (options & PJ_STUN_CACHE_RESPONSE)&&601 if (cache_res && 644 602 (PJ_STUN_IS_RESPONSE(tdata->msg->hdr.type) || 645 603 PJ_STUN_IS_ERROR_RESPONSE(tdata->msg->hdr.type))) … … 688 646 689 647 648 /* Send response */ 649 static pj_status_t send_response(pj_stun_session *sess, 650 pj_pool_t *pool, pj_stun_msg *response, 651 pj_bool_t retransmission, 652 const pj_sockaddr_t *addr, unsigned addr_len) 653 { 654 pj_uint8_t *out_pkt; 655 unsigned out_max_len, out_len; 656 pj_status_t status; 657 658 /* Alloc packet buffer */ 659 out_max_len = PJ_STUN_MAX_PKT_LEN; 660 out_pkt = pj_pool_alloc(pool, out_max_len); 661 662 /* Apply options */ 663 if (!retransmission) { 664 apply_msg_options(sess, pool, response); 665 } 666 667 /* Encode */ 668 status = pj_stun_msg_encode(response, out_pkt, out_max_len, 0, 669 get_passwd(sess), &out_len); 670 if (status != PJ_SUCCESS) { 671 LOG_ERR_(sess, "Error encoding message", status); 672 return status; 673 } 674 675 /* Print log */ 676 dump_tx_msg(sess, response, out_len, addr); 677 678 /* Send packet */ 679 status = sess->cb.on_send_msg(sess, out_pkt, out_len, addr, addr_len); 680 681 return status; 682 } 683 684 /* Authenticate incoming message */ 685 static pj_status_t authenticate_msg(pj_stun_session *sess, 686 const pj_uint8_t *pkt, 687 unsigned pkt_len, 688 const pj_stun_msg *msg, 689 pj_pool_t *tmp_pool, 690 const pj_sockaddr_t *src_addr, 691 unsigned src_addr_len) 692 { 693 pj_stun_msg *response; 694 pj_status_t status; 695 696 if (PJ_STUN_IS_ERROR_RESPONSE(msg->hdr.type) || sess->cred == NULL) 697 return PJ_SUCCESS; 698 699 status = pj_stun_verify_credential(pkt, pkt_len, msg, sess->cred, 700 tmp_pool, &response); 701 if (status != PJ_SUCCESS && response != NULL) { 702 send_response(sess, tmp_pool, response, PJ_FALSE, 703 src_addr, src_addr_len); 704 } 705 706 return status; 707 } 708 709 690 710 /* Handle incoming response */ 691 711 static pj_status_t on_incoming_response(pj_stun_session *sess, … … 724 744 725 745 726 /* Send response */ 727 static pj_status_t send_response(pj_stun_session *sess, unsigned options, 728 pj_pool_t *pool, pj_stun_msg *response, 729 const pj_sockaddr_t *addr, unsigned addr_len) 730 { 731 pj_uint8_t *out_pkt; 732 unsigned out_max_len, out_len; 733 pj_str_t *passwd; 734 pj_status_t status; 735 736 /* Alloc packet buffer */ 737 out_max_len = PJ_STUN_MAX_PKT_LEN; 738 out_pkt = pj_pool_alloc(pool, out_max_len); 739 740 /* Apply options */ 741 apply_msg_options(sess, pool, options, response, &passwd); 742 743 /* Encode */ 744 status = pj_stun_msg_encode(response, out_pkt, out_max_len, 0, 745 passwd, &out_len); 746 if (status != PJ_SUCCESS) { 747 LOG_ERR_(sess, "Error encoding message", status); 748 return status; 749 } 750 751 /* Print log */ 752 dump_tx_msg(sess, response, out_len, addr); 753 754 /* Send packet */ 755 status = sess->cb.on_send_msg(sess, out_pkt, out_len, addr, addr_len); 756 757 return status; 758 } 759 760 /* Handle incoming request */ 761 static pj_status_t on_incoming_request(pj_stun_session *sess, 762 pj_pool_t *tmp_pool, 763 const pj_uint8_t *in_pkt, 764 unsigned in_pkt_len, 765 const pj_stun_msg *msg, 766 const pj_sockaddr_t *src_addr, 767 unsigned src_addr_len) 746 /* For requests, check if we cache the response */ 747 static pj_status_t check_cached_response(pj_stun_session *sess, 748 pj_pool_t *tmp_pool, 749 const pj_stun_msg *msg, 750 const pj_sockaddr_t *src_addr, 751 unsigned src_addr_len) 768 752 { 769 753 pj_stun_tx_data *t; 770 pj_status_t status;771 754 772 755 /* First lookup response in response cache */ … … 784 767 if (t != &sess->cached_response_list) { 785 768 /* Found response in the cache */ 786 unsigned options;787 769 788 770 PJ_LOG(5,(SNAME(sess), 789 771 "Request retransmission, sending cached response")); 790 772 791 options = t->options; 792 options &= ~PJ_STUN_CACHE_RESPONSE; 793 pj_stun_session_send_msg(sess, options, src_addr, src_addr_len, t); 773 send_response(sess, tmp_pool, t->msg, PJ_TRUE, 774 src_addr, src_addr_len); 794 775 return PJ_SUCCESS; 795 776 } 777 778 return PJ_ENOTFOUND; 779 } 780 781 /* Handle incoming request */ 782 static pj_status_t on_incoming_request(pj_stun_session *sess, 783 pj_pool_t *tmp_pool, 784 const pj_uint8_t *in_pkt, 785 unsigned in_pkt_len, 786 const pj_stun_msg *msg, 787 const pj_sockaddr_t *src_addr, 788 unsigned src_addr_len) 789 { 790 pj_status_t status; 796 791 797 792 /* Distribute to handler, or respond with Bad Request */ … … 800 795 src_addr, src_addr_len); 801 796 } else { 802 pj_stun_msg *response = NULL;797 pj_stun_msg *response; 803 798 804 799 status = pj_stun_msg_create_response(tmp_pool, msg, … … 806 801 &response); 807 802 if (status == PJ_SUCCESS && response) { 808 status = send_response(sess, 0,tmp_pool, response,809 src_addr, src_addr_len);803 status = send_response(sess, tmp_pool, response, 804 PJ_FALSE, src_addr, src_addr_len); 810 805 } 811 806 } … … 862 857 LOG_ERR_(sess, "STUN msg_decode() error", status); 863 858 if (response) { 864 send_response(sess, 0,tmp_pool, response,865 src_addr, src_addr_len);859 send_response(sess, tmp_pool, response, 860 PJ_FALSE, src_addr, src_addr_len); 866 861 } 867 862 pj_pool_release(tmp_pool); … … 880 875 pj_mutex_lock(sess->mutex); 881 876 877 /* For requests, check if we have cached response */ 878 status = check_cached_response(sess, tmp_pool, msg, 879 src_addr, src_addr_len); 880 if (status == PJ_SUCCESS) { 881 goto on_return; 882 } 883 884 /* Authenticate the message */ 885 status = authenticate_msg(sess, packet, pkt_size, msg, tmp_pool, 886 src_addr, src_addr_len); 887 if (status != PJ_SUCCESS) 888 goto on_return; 889 890 /* Handle message */ 882 891 if (PJ_STUN_IS_RESPONSE(msg->hdr.type) || 883 892 PJ_STUN_IS_ERROR_RESPONSE(msg->hdr.type)) … … 900 909 } 901 910 911 on_return: 902 912 pj_mutex_unlock(sess->mutex); 903 913 -
pjproject/trunk/pjlib-util/src/pjlib-util/stun_transaction.c
r996 r1037 260 260 const pj_stun_msg *msg) 261 261 { 262 pj_stun_err or_code_attr *err_attr;262 pj_stun_errcode_attr *err_attr; 263 263 pj_status_t status; 264 264 … … 282 282 283 283 /* Find STUN error code attribute */ 284 err_attr = (pj_stun_err or_code_attr*)284 err_attr = (pj_stun_errcode_attr*) 285 285 pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_ERROR_CODE, 0); 286 286 … … 301 301 status = PJ_SUCCESS; 302 302 } else { 303 status = PJ_STATUS_FROM_STUN_CODE(err_attr->err_class * 100 + 304 err_attr->number); 303 status = PJLIB_UTIL_ESTUNTSXFAILED; 305 304 } 306 305 -
pjproject/trunk/pjlib-util/src/pjstun-client/client_main.c
r1030 r1037 30 30 pj_timer_heap_t *th; 31 31 pj_stun_session *sess; 32 unsigned sess_options;33 32 pj_sock_t sock; 34 33 pj_thread_t *thread; … … 46 45 char *user_name; 47 46 char *password; 47 char *nonce; 48 48 pj_bool_t use_fingerprint; 49 49 } o; … … 181 181 stun_cb.on_request_complete = &on_request_complete; 182 182 183 status = pj_stun_session_create(g.endpt, NULL, &stun_cb, &g.sess); 184 pj_assert(status == PJ_SUCCESS); 185 186 if (o.realm) { 187 pj_str_t r, u, p; 188 189 if (o.user_name == NULL) { 190 printf("error: username must be specified\n"); 191 return PJ_EINVAL; 192 } 193 if (o.password == NULL) 194 o.password = ""; 195 g.sess_options = PJ_STUN_USE_LONG_TERM_CRED; 196 pj_stun_session_set_long_term_credential(g.sess, pj_cstr(&r, o.realm), 197 pj_cstr(&u, o.user_name), 198 pj_cstr(&p, o.password)); 199 puts("Using long term credential"); 200 } else if (o.user_name) { 201 pj_str_t u, p; 202 203 if (o.password == NULL) 204 o.password = ""; 205 g.sess_options = PJ_STUN_USE_SHORT_TERM_CRED; 206 pj_stun_session_set_short_term_credential(g.sess, 207 pj_cstr(&u, o.user_name), 208 pj_cstr(&p, o.password)); 209 puts("Using short term credential"); 183 status = pj_stun_session_create(g.endpt, NULL, &stun_cb, 184 o.use_fingerprint!=0, &g.sess); 185 pj_assert(status == PJ_SUCCESS); 186 187 if (o.user_name) { 188 pj_stun_auth_cred cred; 189 190 pj_bzero(&cred, sizeof(cred)); 191 192 cred.type = PJ_STUN_AUTH_CRED_STATIC; 193 cred.data.static_cred.realm = pj_str(o.realm); 194 cred.data.static_cred.username = pj_str(o.user_name); 195 cred.data.static_cred.data_type = 0; 196 cred.data.static_cred.data = pj_str(o.password); 197 cred.data.static_cred.nonce = pj_str(o.nonce); 198 199 pj_stun_session_set_credential(g.sess, &cred); 200 puts("Session credential set"); 210 201 } else { 211 202 puts("Credential not set"); 212 203 } 213 214 if (o.use_fingerprint)215 g.sess_options |= PJ_STUN_USE_FINGERPRINT;216 204 217 205 status = pj_thread_create(g.pool, "stun", &worker_thread, NULL, … … 276 264 pj_assert(rc == PJ_SUCCESS); 277 265 278 rc = pj_stun_session_send_msg(g.sess, g.sess_options,266 rc = pj_stun_session_send_msg(g.sess, PJ_FALSE, 279 267 &g.dst_addr, sizeof(g.dst_addr), 280 268 tdata); … … 303 291 puts(" --username, -u Set username of the credential"); 304 292 puts(" --password, -p Set password of the credential"); 293 puts(" --nonce, -N Set NONCE"); 305 294 puts(" --fingerprint, -F Use fingerprint for outgoing requests"); 306 295 puts(" --help, -h"); … … 313 302 { "username", 1, 0, 'u'}, 314 303 { "password", 1, 0, 'p'}, 304 { "nonce", 1, 0, 'N'}, 315 305 { "fingerprint",0, 0, 'F'}, 316 306 { "help", 0, 0, 'h'} … … 331 321 o.password = pj_optarg; 332 322 break; 323 case 'N': 324 o.nonce = pj_optarg; 325 break; 333 326 case 'h': 334 327 usage(); -
pjproject/trunk/pjlib-util/src/pjstun-srv-test/server_main.c
r1034 r1037 62 62 pj_thread_t *threads[16]; 63 63 64 64 65 } server; 65 66 67 static struct options 68 { 69 char *realm; 70 char *user_name; 71 char *password; 72 char *nonce; 73 pj_bool_t use_fingerprint; 74 } o; 66 75 67 76 static pj_status_t server_perror(const char *sender, const char *title, … … 132 141 133 142 /* Create MAPPED-ADDRESS attribute */ 134 status = pj_stun_msg_add_ generic_ip_addr_attr(tdata->pool, tdata->msg,135 136 137 143 status = pj_stun_msg_add_ip_addr_attr(tdata->pool, tdata->msg, 144 PJ_STUN_ATTR_MAPPED_ADDR, 145 PJ_FALSE, 146 src_addr, src_addr_len); 138 147 if (status != PJ_SUCCESS) { 139 148 server_perror(THIS_FILE, "Error creating response", status); … … 145 154 if (msg->hdr.magic == PJ_STUN_MAGIC) { 146 155 status = 147 pj_stun_msg_add_ generic_ip_addr_attr(tdata->pool, tdata->msg,148 149 150 156 pj_stun_msg_add_ip_addr_attr(tdata->pool, tdata->msg, 157 PJ_STUN_ATTR_XOR_MAPPED_ADDRESS, 158 PJ_TRUE, 159 src_addr, src_addr_len); 151 160 if (status != PJ_SUCCESS) { 152 161 server_perror(THIS_FILE, "Error creating response", status); … … 157 166 158 167 /* Send */ 159 status = pj_stun_session_send_msg(sess, PJ_ STUN_CACHE_RESPONSE,168 status = pj_stun_session_send_msg(sess, PJ_TRUE, 160 169 src_addr, src_addr_len, tdata); 161 170 return status; … … 264 273 sess_cb.on_rx_request = &on_rx_request; 265 274 status = pj_stun_session_create(server.endpt, "session", 266 &sess_cb, &svc->sess); 275 &sess_cb, 276 o.use_fingerprint!=0, 277 &svc->sess); 267 278 if (status != PJ_SUCCESS) 268 279 goto on_error; 269 280 270 281 pj_stun_session_set_user_data(svc->sess, (void*)svc); 282 283 if (o.user_name) { 284 pj_stun_auth_cred cred; 285 286 pj_bzero(&cred, sizeof(cred)); 287 288 cred.type = PJ_STUN_AUTH_CRED_STATIC; 289 cred.data.static_cred.realm = pj_str(o.realm); 290 cred.data.static_cred.username = pj_str(o.user_name); 291 cred.data.static_cred.data_type = 0; 292 cred.data.static_cred.data = pj_str(o.password); 293 cred.data.static_cred.nonce = pj_str(o.nonce); 294 295 pj_stun_session_set_credential(svc->sess, &cred); 296 puts("Session credential set"); 297 } else { 298 puts("Credential not set"); 299 } 271 300 272 301 pj_bzero(&service_callback, sizeof(service_callback)); … … 438 467 439 468 440 int main() 441 { 469 static void usage(void) 470 { 471 puts("Usage: pjstun_srv_test [OPTIONS]"); 472 puts(""); 473 puts("where OPTIONS:"); 474 puts(" --realm, -r Set realm of the credential"); 475 puts(" --username, -u Set username of the credential"); 476 puts(" --password, -p Set password of the credential"); 477 puts(" --nonce, -N Set NONCE"); 478 puts(" --fingerprint, -F Use fingerprint for outgoing requests"); 479 puts(" --help, -h"); 480 } 481 482 483 int main(int argc, char *argv[]) 484 { 485 struct pj_getopt_option long_options[] = { 486 { "realm", 1, 0, 'r'}, 487 { "username", 1, 0, 'u'}, 488 { "password", 1, 0, 'p'}, 489 { "nonce", 1, 0, 'N'}, 490 { "fingerprint",0, 0, 'F'}, 491 { "help", 0, 0, 'h'} 492 }; 493 int c, opt_id; 494 495 while((c=pj_getopt_long(argc,argv, "r:u:p:hF", long_options, &opt_id))!=-1) { 496 switch (c) { 497 case 'r': 498 o.realm = pj_optarg; 499 break; 500 case 'u': 501 o.user_name = pj_optarg; 502 break; 503 case 'p': 504 o.password = pj_optarg; 505 break; 506 case 'N': 507 o.nonce = pj_optarg; 508 break; 509 case 'h': 510 usage(); 511 return 0; 512 case 'F': 513 o.use_fingerprint = PJ_TRUE; 514 break; 515 default: 516 printf("Argument \"%s\" is not valid. Use -h to see help", 517 argv[pj_optind]); 518 return 1; 519 } 520 } 521 522 if (pj_optind != argc) { 523 puts("Error: invalid arguments"); 524 return 1; 525 } 526 527 442 528 if (server_init()) { 443 529 server_destroy();
Note: See TracChangeset
for help on using the changeset viewer.