Changeset 1275 for pjproject/trunk/pjnath/src/pjnath/stun_msg.c
- Timestamp:
- May 15, 2007 10:42:56 AM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjnath/src/pjnath/stun_msg.c
r1266 r1275 18 18 */ 19 19 #include <pjnath/stun_msg.h> 20 #include <pjnath/stun_auth.h>21 20 #include <pjnath/errno.h> 22 21 #include <pjlib-util/crc32.h> … … 1949 1948 * MD5 digest of username, realm, and password. 1950 1949 */ 1951 void pj_stun_calc_md5_key(pj_uint8_t digest[16],1952 1953 1954 1950 static void calc_md5_key(pj_uint8_t digest[16], 1951 const pj_str_t *realm, 1952 const pj_str_t *username, 1953 const pj_str_t *passwd) 1955 1954 { 1956 1955 /* The 16-byte key for MESSAGE-INTEGRITY HMAC is formed by taking … … 1967 1966 1968 1967 #define REMOVE_QUOTE(s) if (s.slen && *s.ptr=='"') \ 1969 s.ptr++, s.slen--; \1970 if (s.slen && s.ptr[s.slen-1]=='"') \1971 s.slen--;1968 s.ptr++, s.slen--; \ 1969 if (s.slen && s.ptr[s.slen-1]=='"') \ 1970 s.slen--; 1972 1971 1973 1972 /* Add username */ … … 1998 1997 1999 1998 /* 1999 * Create authentication key to be used for encoding the message with 2000 * MESSAGE-INTEGRITY. 2001 */ 2002 PJ_DEF(void) pj_stun_create_key(pj_pool_t *pool, 2003 pj_str_t *key, 2004 const pj_str_t *realm, 2005 const pj_str_t *username, 2006 const pj_str_t *passwd) 2007 { 2008 PJ_ASSERT_ON_FAIL(pool && key && username && passwd, return); 2009 2010 if (realm && realm->slen) { 2011 key->ptr = (char*) pj_pool_alloc(pool, 16); 2012 calc_md5_key((pj_uint8_t*)key->ptr, realm, username, passwd); 2013 key->slen = 16; 2014 } else { 2015 pj_strdup(pool, key, passwd); 2016 } 2017 } 2018 2019 2020 /* 2000 2021 static char *print_binary(const pj_uint8_t *data, unsigned data_len) 2001 2022 { … … 2029 2050 pj_uint8_t *buf, unsigned buf_size, 2030 2051 unsigned options, 2031 const pj_str_t * password,2052 const pj_str_t *key, 2032 2053 unsigned *p_msg_len) 2033 2054 { 2034 pj_stun_msg_hdr *hdr;2035 2055 pj_uint8_t *start = buf; 2036 pj_stun_realm_attr *arealm = NULL;2037 pj_stun_username_attr *auname = NULL;2038 2056 pj_stun_msgint_attr *amsgint = NULL; 2039 2057 pj_stun_fingerprint_attr *afingerprint = NULL; 2040 unsigned printed = 0 ;2058 unsigned printed = 0, body_len; 2041 2059 pj_status_t status; 2042 2060 unsigned i; … … 2053 2071 if (buf_size < sizeof(pj_stun_msg_hdr)) 2054 2072 return PJ_ETOOSMALL; 2055 pj_memcpy(buf, &msg->hdr, sizeof(pj_stun_msg_hdr));2056 hdr = (pj_stun_msg_hdr*) buf;2057 hdr->magic = pj_htonl(hdr->magic);2058 hdr->type = pj_htons(hdr->type);2059 /* We'll fill in the length later */2073 2074 PUTVAL16H(buf, 0, msg->hdr.type); 2075 PUTVAL16H(buf, 2, 0); /* length will be calculated later */ 2076 PUTVAL32H(buf, 4, msg->hdr.magic); 2077 pj_memcpy(buf+8, msg->hdr.tsx_id, sizeof(msg->hdr.tsx_id)); 2060 2078 2061 2079 buf += sizeof(pj_stun_msg_hdr); 2062 2080 buf_size -= sizeof(pj_stun_msg_hdr); 2063 2081 2064 /* Print each attribute */2082 /* Encode each attribute to the message */ 2065 2083 for (i=0; i<msg->attr_count; ++i) { 2066 2084 const struct attr_desc *adesc; … … 2073 2091 /* Stop when encountering MESSAGE-INTEGRITY */ 2074 2092 break; 2075 2076 } else if (attr_hdr->type == PJ_STUN_ATTR_USERNAME) {2077 pj_assert(auname == NULL);2078 auname = (pj_stun_username_attr*) attr_hdr;2079 2080 } else if (attr_hdr->type == PJ_STUN_ATTR_REALM) {2081 pj_assert(arealm == NULL);2082 arealm = (pj_stun_realm_attr*) attr_hdr;2083 2093 2084 2094 } else if (attr_hdr->type == PJ_STUN_ATTR_FINGERPRINT) { … … 2124 2134 */ 2125 2135 if (amsgint && afingerprint) { 2126 msg->hdr.length= (pj_uint16_t)((buf - start) - 20 + 24 + 8);2136 body_len = (pj_uint16_t)((buf - start) - 20 + 24 + 8); 2127 2137 } else if (amsgint) { 2128 msg->hdr.length= (pj_uint16_t)((buf - start) - 20 + 24);2138 body_len = (pj_uint16_t)((buf - start) - 20 + 24); 2129 2139 } else if (afingerprint) { 2130 msg->hdr.length= (pj_uint16_t)((buf - start) - 20 + 8);2140 body_len = (pj_uint16_t)((buf - start) - 20 + 8); 2131 2141 } else { 2132 msg->hdr.length= (pj_uint16_t)((buf - start) - 20);2142 body_len = (pj_uint16_t)((buf - start) - 20); 2133 2143 } 2134 2144 2135 2145 /* hdr->length = pj_htons(length); */ 2136 start[2] = (pj_uint8_t)((msg->hdr.length >> 8) & 0x00FF); 2137 start[3] = (pj_uint8_t)(msg->hdr.length & 0x00FF); 2146 PUTVAL16H(start, 2, (pj_uint16_t)body_len); 2138 2147 2139 2148 /* Calculate message integrity, if present */ 2140 2149 if (amsgint != NULL) { 2141 2142 pj_uint8_t md5_key_buf[16];2143 2150 pj_hmac_sha1_context ctx; 2144 pj_str_t key; 2151 2152 /* Key MUST be specified */ 2153 PJ_ASSERT_RETURN(key, PJ_EINVALIDOP); 2145 2154 2146 2155 /* MESSAGE-INTEGRITY must be the last attribute in the message, or … … 2162 2171 } 2163 2172 2164 /* Must have USERNAME attribute */2165 if (auname == NULL) {2166 /* Should not happen for message generated by us */2167 pj_assert(PJ_FALSE);2168 return PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_MISSING_USERNAME);2169 }2170 2171 /* Password must be specified */2172 PJ_ASSERT_RETURN(password, PJ_EINVAL);2173 2174 /* Get the key to sign the message */2175 if (arealm == NULL ) {2176 /* For short term credential, the key is the password */2177 key = *password;2178 2179 } else {2180 pj_stun_calc_md5_key(md5_key_buf, &arealm->value,2181 &auname->value, password);2182 key.ptr = (char*) md5_key_buf;2183 key.slen = 16;2184 }2185 2186 2173 /* Calculate HMAC-SHA1 digest, add zero padding to input 2187 2174 * if necessary to make the input 64 bytes aligned. 2188 2175 */ 2189 pj_hmac_sha1_init(&ctx, (pj_uint8_t*)key .ptr, key.slen);2176 pj_hmac_sha1_init(&ctx, (pj_uint8_t*)key->ptr, key->slen); 2190 2177 pj_hmac_sha1_update(&ctx, (pj_uint8_t*)start, buf-start); 2191 2178 if ((buf-start) & 0x3F) { … … 2221 2208 } 2222 2209 2223 /* Done */ 2210 /* Update message length. */ 2211 msg->hdr.length = (pj_uint16_t) ((buf - start) - 20); 2212 2213 /* Return the length */ 2224 2214 if (p_msg_len) 2225 2215 *p_msg_len = (buf - start);
Note: See TracChangeset
for help on using the changeset viewer.