Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
michael@0 | 1 | /* |
michael@0 | 2 | Copyright (c) 2007, Adobe Systems, Incorporated |
michael@0 | 3 | All rights reserved. |
michael@0 | 4 | |
michael@0 | 5 | Redistribution and use in source and binary forms, with or without |
michael@0 | 6 | modification, are permitted provided that the following conditions are |
michael@0 | 7 | met: |
michael@0 | 8 | |
michael@0 | 9 | * Redistributions of source code must retain the above copyright |
michael@0 | 10 | notice, this list of conditions and the following disclaimer. |
michael@0 | 11 | |
michael@0 | 12 | * Redistributions in binary form must reproduce the above copyright |
michael@0 | 13 | notice, this list of conditions and the following disclaimer in the |
michael@0 | 14 | documentation and/or other materials provided with the distribution. |
michael@0 | 15 | |
michael@0 | 16 | * Neither the name of Adobe Systems, Network Resonance nor the names of its |
michael@0 | 17 | contributors may be used to endorse or promote products derived from |
michael@0 | 18 | this software without specific prior written permission. |
michael@0 | 19 | |
michael@0 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
michael@0 | 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
michael@0 | 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
michael@0 | 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
michael@0 | 24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
michael@0 | 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
michael@0 | 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
michael@0 | 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
michael@0 | 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
michael@0 | 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
michael@0 | 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
michael@0 | 31 | */ |
michael@0 | 32 | |
michael@0 | 33 | |
michael@0 | 34 | static char *RCSSTRING __UNUSED__="$Id: stun_msg.c,v 1.2 2008/04/28 18:21:30 ekr Exp $"; |
michael@0 | 35 | |
michael@0 | 36 | #include <errno.h> |
michael@0 | 37 | #include <csi_platform.h> |
michael@0 | 38 | |
michael@0 | 39 | #ifdef WIN32 |
michael@0 | 40 | #include <winsock2.h> |
michael@0 | 41 | #include <stdlib.h> |
michael@0 | 42 | #include <io.h> |
michael@0 | 43 | #include <time.h> |
michael@0 | 44 | #else /* UNIX */ |
michael@0 | 45 | #include <string.h> |
michael@0 | 46 | #endif /* end UNIX */ |
michael@0 | 47 | #include <assert.h> |
michael@0 | 48 | |
michael@0 | 49 | #include "stun.h" |
michael@0 | 50 | |
michael@0 | 51 | |
michael@0 | 52 | int |
michael@0 | 53 | nr_stun_message_create(nr_stun_message **msg) |
michael@0 | 54 | { |
michael@0 | 55 | int _status; |
michael@0 | 56 | nr_stun_message *m = 0; |
michael@0 | 57 | |
michael@0 | 58 | m = RCALLOC(sizeof(*m)); |
michael@0 | 59 | if (!m) |
michael@0 | 60 | ABORT(R_NO_MEMORY); |
michael@0 | 61 | |
michael@0 | 62 | TAILQ_INIT(&m->attributes); |
michael@0 | 63 | |
michael@0 | 64 | *msg = m; |
michael@0 | 65 | |
michael@0 | 66 | _status=0; |
michael@0 | 67 | abort: |
michael@0 | 68 | return(_status); |
michael@0 | 69 | } |
michael@0 | 70 | |
michael@0 | 71 | int |
michael@0 | 72 | nr_stun_message_create2(nr_stun_message **msg, UCHAR *buffer, int length) |
michael@0 | 73 | { |
michael@0 | 74 | int r,_status; |
michael@0 | 75 | nr_stun_message *m = 0; |
michael@0 | 76 | |
michael@0 | 77 | if (length > sizeof(m->buffer)) { |
michael@0 | 78 | ABORT(R_BAD_DATA); |
michael@0 | 79 | } |
michael@0 | 80 | |
michael@0 | 81 | if ((r=nr_stun_message_create(&m))) |
michael@0 | 82 | ABORT(r); |
michael@0 | 83 | |
michael@0 | 84 | memcpy(m->buffer, buffer, length); |
michael@0 | 85 | m->length = length; |
michael@0 | 86 | |
michael@0 | 87 | *msg = m; |
michael@0 | 88 | |
michael@0 | 89 | _status=0; |
michael@0 | 90 | abort: |
michael@0 | 91 | return(_status); |
michael@0 | 92 | } |
michael@0 | 93 | |
michael@0 | 94 | int |
michael@0 | 95 | nr_stun_message_destroy(nr_stun_message **msg) |
michael@0 | 96 | { |
michael@0 | 97 | int _status; |
michael@0 | 98 | nr_stun_message_attribute_head *attrs; |
michael@0 | 99 | nr_stun_message_attribute *attr; |
michael@0 | 100 | |
michael@0 | 101 | if (msg && *msg) { |
michael@0 | 102 | attrs = &(*msg)->attributes; |
michael@0 | 103 | while (!TAILQ_EMPTY(attrs)) { |
michael@0 | 104 | attr = TAILQ_FIRST(attrs); |
michael@0 | 105 | nr_stun_message_attribute_destroy(*msg, &attr); |
michael@0 | 106 | } |
michael@0 | 107 | |
michael@0 | 108 | RFREE(*msg); |
michael@0 | 109 | |
michael@0 | 110 | *msg = 0; |
michael@0 | 111 | } |
michael@0 | 112 | |
michael@0 | 113 | _status=0; |
michael@0 | 114 | /* abort: */ |
michael@0 | 115 | return(_status); |
michael@0 | 116 | } |
michael@0 | 117 | |
michael@0 | 118 | int |
michael@0 | 119 | nr_stun_message_attribute_create(nr_stun_message *msg, nr_stun_message_attribute **attr) |
michael@0 | 120 | { |
michael@0 | 121 | int _status; |
michael@0 | 122 | nr_stun_message_attribute *a = 0; |
michael@0 | 123 | |
michael@0 | 124 | a = RCALLOC(sizeof(*a)); |
michael@0 | 125 | if (!a) |
michael@0 | 126 | ABORT(R_NO_MEMORY); |
michael@0 | 127 | |
michael@0 | 128 | TAILQ_INSERT_TAIL(&msg->attributes, a, entry); |
michael@0 | 129 | |
michael@0 | 130 | *attr = a; |
michael@0 | 131 | |
michael@0 | 132 | _status=0; |
michael@0 | 133 | abort: |
michael@0 | 134 | return(_status); |
michael@0 | 135 | } |
michael@0 | 136 | |
michael@0 | 137 | int |
michael@0 | 138 | nr_stun_message_attribute_destroy(nr_stun_message *msg, nr_stun_message_attribute **attr) |
michael@0 | 139 | { |
michael@0 | 140 | int _status; |
michael@0 | 141 | nr_stun_message_attribute *a = 0; |
michael@0 | 142 | |
michael@0 | 143 | if (attr && *attr) { |
michael@0 | 144 | a = *attr; |
michael@0 | 145 | TAILQ_REMOVE(&msg->attributes, a, entry); |
michael@0 | 146 | |
michael@0 | 147 | RFREE(a); |
michael@0 | 148 | |
michael@0 | 149 | *attr = 0; |
michael@0 | 150 | } |
michael@0 | 151 | |
michael@0 | 152 | _status=0; |
michael@0 | 153 | /* abort: */ |
michael@0 | 154 | return(_status); |
michael@0 | 155 | } |
michael@0 | 156 | |
michael@0 | 157 | int |
michael@0 | 158 | nr_stun_message_has_attribute(nr_stun_message *msg, UINT2 type, nr_stun_message_attribute **attribute) |
michael@0 | 159 | { |
michael@0 | 160 | nr_stun_message_attribute *attr = 0; |
michael@0 | 161 | |
michael@0 | 162 | if (attribute) |
michael@0 | 163 | *attribute = 0; |
michael@0 | 164 | |
michael@0 | 165 | TAILQ_FOREACH(attr, &msg->attributes, entry) { |
michael@0 | 166 | if (attr->type == type) |
michael@0 | 167 | break; |
michael@0 | 168 | } |
michael@0 | 169 | |
michael@0 | 170 | if (!attr || attr->invalid) |
michael@0 | 171 | return 0; /* does not have */ |
michael@0 | 172 | |
michael@0 | 173 | if (attribute) |
michael@0 | 174 | *attribute = attr; |
michael@0 | 175 | |
michael@0 | 176 | return 1; /* has */ |
michael@0 | 177 | } |
michael@0 | 178 | |
michael@0 | 179 | #define NR_STUN_MESSAGE_ADD_ATTRIBUTE(__type, __code) \ |
michael@0 | 180 | { \ |
michael@0 | 181 | int r,_status; \ |
michael@0 | 182 | nr_stun_message_attribute *attr = 0; \ |
michael@0 | 183 | if ((r=nr_stun_message_attribute_create(msg, &attr))) \ |
michael@0 | 184 | ABORT(r); \ |
michael@0 | 185 | attr->type = (__type); \ |
michael@0 | 186 | { __code } \ |
michael@0 | 187 | _status=0; \ |
michael@0 | 188 | abort: \ |
michael@0 | 189 | if (_status) RFREE(attr); \ |
michael@0 | 190 | return(_status); \ |
michael@0 | 191 | } |
michael@0 | 192 | |
michael@0 | 193 | |
michael@0 | 194 | int |
michael@0 | 195 | nr_stun_message_add_alternate_server_attribute(nr_stun_message *msg, nr_transport_addr *alternate_server) |
michael@0 | 196 | NR_STUN_MESSAGE_ADD_ATTRIBUTE( |
michael@0 | 197 | NR_STUN_ATTR_ALTERNATE_SERVER, |
michael@0 | 198 | { |
michael@0 | 199 | if ((r=nr_transport_addr_copy(&attr->u.alternate_server, alternate_server))) |
michael@0 | 200 | ABORT(r); |
michael@0 | 201 | } |
michael@0 | 202 | ) |
michael@0 | 203 | |
michael@0 | 204 | int |
michael@0 | 205 | nr_stun_message_add_error_code_attribute(nr_stun_message *msg, UINT2 number, char *reason) |
michael@0 | 206 | NR_STUN_MESSAGE_ADD_ATTRIBUTE( |
michael@0 | 207 | NR_STUN_ATTR_ERROR_CODE, |
michael@0 | 208 | { |
michael@0 | 209 | attr->u.error_code.number = number; |
michael@0 | 210 | strlcpy(attr->u.error_code.reason, reason, sizeof(attr->u.error_code.reason)); |
michael@0 | 211 | } |
michael@0 | 212 | ) |
michael@0 | 213 | |
michael@0 | 214 | int |
michael@0 | 215 | nr_stun_message_add_fingerprint_attribute(nr_stun_message *msg) |
michael@0 | 216 | NR_STUN_MESSAGE_ADD_ATTRIBUTE( |
michael@0 | 217 | NR_STUN_ATTR_FINGERPRINT, |
michael@0 | 218 | {} |
michael@0 | 219 | ) |
michael@0 | 220 | |
michael@0 | 221 | int |
michael@0 | 222 | nr_stun_message_add_message_integrity_attribute(nr_stun_message *msg, Data *password) |
michael@0 | 223 | NR_STUN_MESSAGE_ADD_ATTRIBUTE( |
michael@0 | 224 | NR_STUN_ATTR_MESSAGE_INTEGRITY, |
michael@0 | 225 | { |
michael@0 | 226 | if (sizeof(attr->u.message_integrity.password) < password->len) |
michael@0 | 227 | ABORT(R_BAD_DATA); |
michael@0 | 228 | |
michael@0 | 229 | memcpy(attr->u.message_integrity.password, password->data, password->len); |
michael@0 | 230 | attr->u.message_integrity.passwordlen = password->len; |
michael@0 | 231 | } |
michael@0 | 232 | ) |
michael@0 | 233 | |
michael@0 | 234 | int |
michael@0 | 235 | nr_stun_message_add_nonce_attribute(nr_stun_message *msg, char *nonce) |
michael@0 | 236 | NR_STUN_MESSAGE_ADD_ATTRIBUTE( |
michael@0 | 237 | NR_STUN_ATTR_NONCE, |
michael@0 | 238 | { strlcpy(attr->u.nonce, nonce, sizeof(attr->u.nonce)); } |
michael@0 | 239 | ) |
michael@0 | 240 | |
michael@0 | 241 | int |
michael@0 | 242 | nr_stun_message_add_realm_attribute(nr_stun_message *msg, char *realm) |
michael@0 | 243 | NR_STUN_MESSAGE_ADD_ATTRIBUTE( |
michael@0 | 244 | NR_STUN_ATTR_REALM, |
michael@0 | 245 | { strlcpy(attr->u.realm, realm, sizeof(attr->u.realm)); } |
michael@0 | 246 | ) |
michael@0 | 247 | |
michael@0 | 248 | int |
michael@0 | 249 | nr_stun_message_add_server_attribute(nr_stun_message *msg, char *server_name) |
michael@0 | 250 | NR_STUN_MESSAGE_ADD_ATTRIBUTE( |
michael@0 | 251 | NR_STUN_ATTR_SERVER, |
michael@0 | 252 | { strlcpy(attr->u.server_name, server_name, sizeof(attr->u.server_name)); } |
michael@0 | 253 | ) |
michael@0 | 254 | |
michael@0 | 255 | int |
michael@0 | 256 | nr_stun_message_add_unknown_attributes_attribute(nr_stun_message *msg, nr_stun_attr_unknown_attributes *unknown_attributes) |
michael@0 | 257 | NR_STUN_MESSAGE_ADD_ATTRIBUTE( |
michael@0 | 258 | NR_STUN_ATTR_UNKNOWN_ATTRIBUTES, |
michael@0 | 259 | { memcpy(&attr->u.unknown_attributes, unknown_attributes, sizeof(attr->u.unknown_attributes)); } |
michael@0 | 260 | ) |
michael@0 | 261 | |
michael@0 | 262 | int |
michael@0 | 263 | nr_stun_message_add_username_attribute(nr_stun_message *msg, char *username) |
michael@0 | 264 | NR_STUN_MESSAGE_ADD_ATTRIBUTE( |
michael@0 | 265 | NR_STUN_ATTR_USERNAME, |
michael@0 | 266 | { strlcpy(attr->u.username, username, sizeof(attr->u.username)); } |
michael@0 | 267 | ) |
michael@0 | 268 | |
michael@0 | 269 | int |
michael@0 | 270 | nr_stun_message_add_requested_transport_attribute(nr_stun_message *msg, UCHAR protocol) |
michael@0 | 271 | NR_STUN_MESSAGE_ADD_ATTRIBUTE( |
michael@0 | 272 | NR_STUN_ATTR_REQUESTED_TRANSPORT, |
michael@0 | 273 | { attr->u.requested_transport = protocol; } |
michael@0 | 274 | ) |
michael@0 | 275 | |
michael@0 | 276 | int |
michael@0 | 277 | nr_stun_message_add_xor_mapped_address_attribute(nr_stun_message *msg, nr_transport_addr *mapped_address) |
michael@0 | 278 | NR_STUN_MESSAGE_ADD_ATTRIBUTE( |
michael@0 | 279 | NR_STUN_ATTR_XOR_MAPPED_ADDRESS, |
michael@0 | 280 | { |
michael@0 | 281 | if ((r=nr_transport_addr_copy(&attr->u.xor_mapped_address.unmasked, mapped_address))) |
michael@0 | 282 | ABORT(r); |
michael@0 | 283 | } |
michael@0 | 284 | ) |
michael@0 | 285 | |
michael@0 | 286 | int |
michael@0 | 287 | nr_stun_message_add_xor_peer_address_attribute(nr_stun_message *msg, nr_transport_addr *peer_address) |
michael@0 | 288 | NR_STUN_MESSAGE_ADD_ATTRIBUTE( |
michael@0 | 289 | NR_STUN_ATTR_XOR_PEER_ADDRESS, |
michael@0 | 290 | { |
michael@0 | 291 | if ((r=nr_transport_addr_copy(&attr->u.xor_mapped_address.unmasked, peer_address))) |
michael@0 | 292 | ABORT(r); |
michael@0 | 293 | } |
michael@0 | 294 | ) |
michael@0 | 295 | |
michael@0 | 296 | #ifdef USE_ICE |
michael@0 | 297 | int |
michael@0 | 298 | nr_stun_message_add_ice_controlled_attribute(nr_stun_message *msg, UINT8 ice_controlled) |
michael@0 | 299 | NR_STUN_MESSAGE_ADD_ATTRIBUTE( |
michael@0 | 300 | NR_STUN_ATTR_ICE_CONTROLLED, |
michael@0 | 301 | { attr->u.ice_controlled = ice_controlled; } |
michael@0 | 302 | ) |
michael@0 | 303 | |
michael@0 | 304 | int |
michael@0 | 305 | nr_stun_message_add_ice_controlling_attribute(nr_stun_message *msg, UINT8 ice_controlling) |
michael@0 | 306 | NR_STUN_MESSAGE_ADD_ATTRIBUTE( |
michael@0 | 307 | NR_STUN_ATTR_ICE_CONTROLLING, |
michael@0 | 308 | { attr->u.ice_controlling = ice_controlling; } |
michael@0 | 309 | ) |
michael@0 | 310 | |
michael@0 | 311 | int |
michael@0 | 312 | nr_stun_message_add_priority_attribute(nr_stun_message *msg, UINT4 priority) |
michael@0 | 313 | NR_STUN_MESSAGE_ADD_ATTRIBUTE( |
michael@0 | 314 | NR_STUN_ATTR_PRIORITY, |
michael@0 | 315 | { attr->u.priority = priority; } |
michael@0 | 316 | ) |
michael@0 | 317 | |
michael@0 | 318 | int |
michael@0 | 319 | nr_stun_message_add_use_candidate_attribute(nr_stun_message *msg) |
michael@0 | 320 | NR_STUN_MESSAGE_ADD_ATTRIBUTE( |
michael@0 | 321 | NR_STUN_ATTR_USE_CANDIDATE, |
michael@0 | 322 | {} |
michael@0 | 323 | ) |
michael@0 | 324 | #endif /* USE_ICE */ |
michael@0 | 325 | |
michael@0 | 326 | #ifdef USE_TURN |
michael@0 | 327 | int |
michael@0 | 328 | nr_stun_message_add_data_attribute(nr_stun_message *msg, UCHAR *data, int length) |
michael@0 | 329 | |
michael@0 | 330 | NR_STUN_MESSAGE_ADD_ATTRIBUTE( |
michael@0 | 331 | NR_STUN_ATTR_DATA, |
michael@0 | 332 | { |
michael@0 | 333 | if (length > NR_STUN_MAX_MESSAGE_SIZE) |
michael@0 | 334 | ABORT(R_BAD_ARGS); |
michael@0 | 335 | |
michael@0 | 336 | memcpy(attr->u.data.data, data, length); |
michael@0 | 337 | attr->u.data.length=length; |
michael@0 | 338 | } |
michael@0 | 339 | ) |
michael@0 | 340 | |
michael@0 | 341 | int |
michael@0 | 342 | nr_stun_message_add_lifetime_attribute(nr_stun_message *msg, UINT4 lifetime_secs) |
michael@0 | 343 | NR_STUN_MESSAGE_ADD_ATTRIBUTE( |
michael@0 | 344 | NR_STUN_ATTR_LIFETIME, |
michael@0 | 345 | { attr->u.lifetime_secs = lifetime_secs; } |
michael@0 | 346 | ) |
michael@0 | 347 | |
michael@0 | 348 | #endif /* USE_TURN */ |
michael@0 | 349 | |
michael@0 | 350 | #ifdef USE_STUND_0_96 |
michael@0 | 351 | int |
michael@0 | 352 | nr_stun_message_add_change_request_attribute(nr_stun_message *msg, UINT4 change_request) |
michael@0 | 353 | NR_STUN_MESSAGE_ADD_ATTRIBUTE( |
michael@0 | 354 | NR_STUN_ATTR_OLD_CHANGE_REQUEST, |
michael@0 | 355 | { attr->u.change_request = change_request; } |
michael@0 | 356 | ) |
michael@0 | 357 | #endif /* USE_STUND_0_96 */ |
michael@0 | 358 |