Bug Summary

File:root/firefox-clang/dom/media/webrtc/transport/third_party/nICEr/src/stun/stun_proc.cpp
Warning:line 429, column 14
Although the value stored to 'r' is used in the enclosing expression, the value is never actually read from 'r'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -O2 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name stun_proc.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/media/webrtc/transport/third_party/nICEr/nicer_nicer -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/media/webrtc/transport/third_party/nICEr/nicer_nicer -resource-dir /usr/lib/llvm-23/lib/clang/23 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -D _GLIBCXX_ASSERTIONS=1 -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D _FILE_OFFSET_BITS=64 -D CHROMIUM_BUILD -D USE_LIBJPEG_TURBO=1 -D USE_NSS=1 -D ENABLE_ONE_CLICK_SIGNIN -D GTK_DISABLE_SINGLE_INCLUDES=1 -D _ISOC99_SOURCE=1 -D ENABLE_REMOTING=1 -D ENABLE_WEBRTC=1 -D ENABLE_CONFIGURATION_POLICY -D ENABLE_INPUT_SPEECH -D ENABLE_NOTIFICATIONS -D ENABLE_GPU=1 -D ENABLE_EGLIMAGE=1 -D USE_SKIA=1 -D ENABLE_TASK_MANAGER=1 -D ENABLE_WEB_INTENTS=1 -D ENABLE_EXTENSIONS=1 -D ENABLE_PLUGIN_INSTALLATION=1 -D ENABLE_PROTECTOR_SERVICE=1 -D ENABLE_SESSION_SERVICE=1 -D ENABLE_THEMES=1 -D ENABLE_BACKGROUND=1 -D ENABLE_AUTOMATION=1 -D ENABLE_PRINTING=1 -D ENABLE_CAPTIVE_PORTAL_DETECTION=1 -D SANITY_CHECKS -D USE_TURN -D USE_ICE -D USE_RFC_3489_BACKWARDS_COMPATIBLE -D USE_STUN_PEDANTIC -D NR_SOCKET_IS_VOID_PTR -D restrict= -D R_PLATFORM_INT_TYPES=<stdint.h> -D R_DEFINED_INT2=int16_t -D R_DEFINED_UINT2=uint16_t -D R_DEFINED_INT4=int32_t -D R_DEFINED_UINT4=uint32_t -D R_DEFINED_INT8=int64_t -D R_DEFINED_UINT8=uint64_t -D LINUX -D HAVE_LIBM=1 -D HAVE_STRDUP=1 -D HAVE_STRLCPY=1 -D HAVE_SYS_TIME_H=1 -D HAVE_VFPRINTF=1 -D NEW_STDIORETSIGTYPE=void -D TIME_WITH_SYS_TIME_H=1 -D __UNUSED__=__attribute__((unused)) -D DYNAMIC_ANNOTATIONS_ENABLED=1 -D WTF_USE_DYNAMIC_ANNOTATIONS=1 -D _DEBUG -D MOZ_HAS_MOZGLUE -D MOZILLA_INTERNAL_API -D IMPL_LIBXUL -D MOZ_SUPPORT_LEAKCHECKING -D STATIC_EXPORTABLE_JS_API -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nICEr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dom/media/webrtc/transport/third_party/nICEr/nicer_nicer -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nrappkit/src/event -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nrappkit/src/log -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nrappkit/src/registry -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nrappkit/src/share -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nrappkit/src/util -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nrappkit/src/util/libekr -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nrappkit/src/port/generic/include -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nICEr/src/crypto -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nICEr/src/ice -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nICEr/src/net -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nICEr/src/stun -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nICEr/src/util -I /root/firefox-clang/dom/media/webrtc/transport/third_party/nrappkit/src/port/linux/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/ipc/ipdl/_ipdlheaders -I /root/firefox-clang/ipc/chromium/src -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -D MOZILLA_CLIENT -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/x86_64-linux-gnu/c++/16 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../include/c++/16/backward -internal-isystem /usr/lib/llvm-23/lib/clang/23/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-error=pessimizing-move -Wno-error=large-by-value-copy=128 -Wno-error=implicit-int-float-conversion -Wno-error=thread-safety-analysis -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -Wno-character-conversion -Wno-parentheses -Wno-format -Wno-format-security -std=gnu++20 -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fno-implicit-modules -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -fdiagnostics-absolute-paths -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -mllvm -dwarf-linkage-names=Abstract -faddrsig -fdwarf2-cfi-asm -o /tmp/scan-build-2026-10-17-231001-351276-1 -x c++ /root/firefox-clang/dom/media/webrtc/transport/third_party/nICEr/src/stun/stun_proc.cpp
1/*
2Copyright (c) 2007, Adobe Systems, Incorporated
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions are
7met:
8
9* Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12* Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16* Neither the name of Adobe Systems, Network Resonance nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
19
20THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*/
32
33#include <errno(*__errno_location ()).h>
34#include <csi_platform.h>
35
36#ifdef WIN32
37#include <winsock2.h>
38#include <stdlib.h>
39#include <io.h>
40#include <time.h>
41#else /* UNIX */
42#include <string.h>
43#endif /* end UNIX */
44#include <assert.h>
45
46#include "stun.h"
47#include "stun_reg.h"
48#include "registry.h"
49
50static int
51nr_stun_add_realm_and_nonce(int new_nonce, nr_stun_server_client *clnt, nr_stun_message *res);
52
53/* draft-ietf-behave-rfc3489bis-10.txt S 7.3 */
54int
55nr_stun_receive_message(nr_stun_message *req, nr_stun_message *msg)
56{
57 int _status;
58 nr_stun_message_attribute *attr;
59
60#ifdef USE_RFC_3489_BACKWARDS_COMPATIBLE1
61 /* if this message was generated by an RFC 3489 impementation,
62 * the call to nr_is_stun_message will fail, so skip that
63 * check and puke elsewhere if the message can't be decoded */
64 if (msg->header.magic_cookie == NR_STUN_MAGIC_COOKIE0x2112A442) {
65#endif /* USE_RFC_3489_BACKWARDS_COMPATIBLE */
66 if (!nr_is_stun_message(msg->buffer, msg->length)) {
67 r_log(NR_LOG_STUN, LOG_WARNING4, "Not a STUN message");
68 ABORT(R_REJECTED)do { int _r=11; if(!_r) _r=-1; _status=_r; goto abort;} while
(0)
;
69 }
70#ifdef USE_RFC_3489_BACKWARDS_COMPATIBLE1
71 }
72#endif /* USE_RFC_3489_BACKWARDS_COMPATIBLE */
73
74 if (req == 0) {
75 if (NR_STUN_GET_TYPE_CLASS(msg->header.type)((((msg->header.type) >> 7) & 0x002) | (((msg->
header.type) >> 4) & 0x001))
!= NR_CLASS_REQUEST0x0) {
76 r_log(NR_LOG_STUN,LOG_WARNING4,"Illegal message type: %03x", msg->header.type);
77 ABORT(R_REJECTED)do { int _r=11; if(!_r) _r=-1; _status=_r; goto abort;} while
(0)
;
78 }
79 }
80 else {
81 if (NR_STUN_GET_TYPE_CLASS(msg->header.type)((((msg->header.type) >> 7) & 0x002) | (((msg->
header.type) >> 4) & 0x001))
!= NR_CLASS_RESPONSE0x2
82 && NR_STUN_GET_TYPE_CLASS(msg->header.type)((((msg->header.type) >> 7) & 0x002) | (((msg->
header.type) >> 4) & 0x001))
!= NR_CLASS_ERROR_RESPONSE0x3) {
83 r_log(NR_LOG_STUN,LOG_WARNING4,"Illegal message class: %03x", msg->header.type);
84 ABORT(R_REJECTED)do { int _r=11; if(!_r) _r=-1; _status=_r; goto abort;} while
(0)
;
85 }
86
87 if (NR_STUN_GET_TYPE_METHOD(req->header.type)((((req->header.type) >> 2) & 0xf80) | (((req->
header.type) >> 1) & 0x070) | ((req->header.type
) & 0x00f))
!= NR_STUN_GET_TYPE_METHOD(msg->header.type)((((msg->header.type) >> 2) & 0xf80) | (((msg->
header.type) >> 1) & 0x070) | ((msg->header.type
) & 0x00f))
) {
88 r_log(NR_LOG_STUN,LOG_WARNING4,"Inconsistent message method: %03x expected %03x", msg->header.type, req->header.type);
89 ABORT(R_REJECTED)do { int _r=11; if(!_r) _r=-1; _status=_r; goto abort;} while
(0)
;
90 }
91
92 if (nr_stun_different_transaction(msg->buffer, msg->length, req)) {
93 r_log(NR_LOG_STUN, LOG_DEBUG7, "Unrecognized STUN transaction");
94 ABORT(R_REJECTED)do { int _r=11; if(!_r) _r=-1; _status=_r; goto abort;} while
(0)
;
95 }
96 }
97
98 switch (msg->header.magic_cookie) {
99 case NR_STUN_MAGIC_COOKIE0x2112A442:
100 /* basically draft-ietf-behave-rfc3489bis-10.txt S 6 rules */
101
102 if (nr_stun_message_has_attribute(msg, NR_STUN_ATTR_FINGERPRINT0x8028, &attr)
103 && !attr->u.fingerprint.valid) {
104 r_log(NR_LOG_STUN, LOG_WARNING4, "Invalid fingerprint");
105 ABORT(R_REJECTED)do { int _r=11; if(!_r) _r=-1; _status=_r; goto abort;} while
(0)
;
106 }
107
108 break;
109
110 default:
111#ifdef USE_RFC_3489_BACKWARDS_COMPATIBLE1
112 /* in RFC 3489 there is no magic cookie, it's part of the transaction ID */
113#else
114#ifdef NDEBUG
115 /* in deployment builds we should always see a recognized magic cookie */
116 r_log(NR_LOG_STUN, LOG_WARNING4, "Missing Magic Cookie");
117 ABORT(R_REJECTED)do { int _r=11; if(!_r) _r=-1; _status=_r; goto abort;} while
(0)
;
118#else
119 /* ignore this condition because sometimes we like to pretend we're
120 * a server talking to old clients and their messages don't contain
121 * a magic cookie at all but rather the magic cookie field is part
122 * of their ID and therefore random */
123#endif /* NDEBUG */
124#endif /* USE_RFC_3489_BACKWARDS_COMPATIBLE */
125 break;
126 }
127
128 _status=0;
129 abort:
130 return _status;
131}
132
133/* draft-ietf-behave-rfc3489bis-10.txt S 7.3.1 */
134int
135nr_stun_process_request(nr_stun_message *req, nr_stun_message *res)
136{
137 int _status;
138#ifdef USE_STUN_PEDANTIC1
139 int r;
140 nr_stun_attr_unknown_attributes unknown_attributes = { { 0 } };
141 nr_stun_message_attribute *attr;
142
143 if (req->comprehension_required_unknown_attributes > 0) {
144 nr_stun_form_error_response(req, res, 420, "Unknown Attributes");
145 r_log(NR_LOG_STUN, LOG_WARNING4, "Request contains comprehension required but unknown attributes");
146
147 TAILQ_FOREACH(attr, &req->attributes, entry)for ((attr) = (((&req->attributes))->tqh_first); (attr
); (attr) = (((attr))->entry.tqe_next))
{
148 if (attr->name == 0) {
149 /* unrecognized attribute */
150
151 /* should never happen, but truncate if it ever were to occur */
152 if (unknown_attributes.num_attributes >= NR_STUN_MAX_UNKNOWN_ATTRIBUTES16)
153 break;
154
155 unknown_attributes.attribute[unknown_attributes.num_attributes++] = attr->type;
156 }
157 }
158
159 assert(req->comprehension_required_unknown_attributes + req->comprehension_optional_unknown_attributes == unknown_attributes.num_attributes)(static_cast <bool> (req->comprehension_required_unknown_attributes
+ req->comprehension_optional_unknown_attributes == unknown_attributes
.num_attributes) ? void (0) : __assert_fail ("req->comprehension_required_unknown_attributes + req->comprehension_optional_unknown_attributes == unknown_attributes.num_attributes"
, __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__
))
;
160
161 if ((r=nr_stun_message_add_unknown_attributes_attribute(res, &unknown_attributes)))
162 ABORT(R_ALREADY)do { int _r=4; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
163
164 ABORT(R_ALREADY)do { int _r=4; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
165 }
166#endif /* USE_STUN_PEDANTIC */
167
168 _status=0;
169#ifdef USE_STUN_PEDANTIC1
170 abort:
171#endif /* USE_STUN_PEDANTIC */
172 return _status;
173}
174
175/* draft-ietf-behave-rfc3489bis-10.txt S 7.3.2 */
176int
177nr_stun_process_indication(nr_stun_message *ind)
178{
179 int _status;
180#ifdef USE_STUN_PEDANTIC1
181
182 if (ind->comprehension_required_unknown_attributes > 0) {
183 r_log(NR_LOG_STUN, LOG_WARNING4, "Indication contains comprehension required but unknown attributes");
184 ABORT(R_REJECTED)do { int _r=11; if(!_r) _r=-1; _status=_r; goto abort;} while
(0)
;
185 }
186#endif /* USE_STUN_PEDANTIC */
187
188 _status=0;
189#ifdef USE_STUN_PEDANTIC1
190 abort:
191#endif /* USE_STUN_PEDANTIC */
192 return _status;
193}
194
195/* RFC5389 S 7.3.3, except that we *also* allow a MAPPED_ADDRESS
196 to compensate for a bug in Google's STUN server where it
197 always returns MAPPED_ADDRESS.
198
199 Mozilla bug: 888274.
200 */
201int
202nr_stun_process_success_response(nr_stun_message *res)
203{
204 int _status;
205
206#ifdef USE_STUN_PEDANTIC1
207 if (res->comprehension_required_unknown_attributes > 0) {
208 r_log(NR_LOG_STUN, LOG_WARNING4, "Response contains comprehension required but unknown attributes");
209 ABORT(R_REJECTED)do { int _r=11; if(!_r) _r=-1; _status=_r; goto abort;} while
(0)
;
210 }
211#endif /* USE_STUN_PEDANTIC */
212
213 if (NR_STUN_GET_TYPE_METHOD(res->header.type)((((res->header.type) >> 2) & 0xf80) | (((res->
header.type) >> 1) & 0x070) | ((res->header.type
) & 0x00f))
== NR_METHOD_BINDING0x001) {
214 if (! nr_stun_message_has_attribute(res, NR_STUN_ATTR_XOR_MAPPED_ADDRESS0x0020, 0) &&
215 ! nr_stun_message_has_attribute(res, NR_STUN_ATTR_MAPPED_ADDRESS0x0001, 0)) {
216 r_log(NR_LOG_STUN, LOG_WARNING4, "Missing XOR-MAPPED-ADDRESS and MAPPED_ADDRESS");
217 ABORT(R_REJECTED)do { int _r=11; if(!_r) _r=-1; _status=_r; goto abort;} while
(0)
;
218 }
219 }
220
221 _status=0;
222 abort:
223 return _status;
224}
225
226/* draft-ietf-behave-rfc3489bis-10.txt S 7.3.4 */
227int
228nr_stun_process_error_response(nr_stun_message *res, UINT2 *error_code)
229{
230 int _status;
231 nr_stun_message_attribute *attr;
232
233 if (res->comprehension_required_unknown_attributes > 0) {
234 r_log(NR_LOG_STUN, LOG_WARNING4, "Error response contains comprehension required but unknown attributes");
235 ABORT(R_REJECTED)do { int _r=11; if(!_r) _r=-1; _status=_r; goto abort;} while
(0)
;
236 }
237
238 if (! nr_stun_message_has_attribute(res, NR_STUN_ATTR_ERROR_CODE0x0009, &attr)) {
239 r_log(NR_LOG_STUN, LOG_WARNING4, "Missing ERROR-CODE");
240 ABORT(R_REJECTED)do { int _r=11; if(!_r) _r=-1; _status=_r; goto abort;} while
(0)
;
241 }
242
243 *error_code = attr->u.error_code.number;
244
245 switch (attr->u.error_code.number / 100) {
246 case 3:
247 /* We do not treat STUN/300 as retryable. The TURN Allocate handling
248 * code will reset the ctx if appropriate. */
249 ABORT(R_REJECTED)do { int _r=11; if(!_r) _r=-1; _status=_r; goto abort;} while
(0)
;
250 break;
251
252 case 4:
253 /* If the error code is 400 through 499, the client declares the
254 * transaction failed; in the case of 420 (Unknown Attribute), the
255 * response should contain a UNKNOWN-ATTRIBUTES attribute that gives
256 * additional information. */
257 if (attr->u.error_code.number == 420)
258 ABORT(R_REJECTED)do { int _r=11; if(!_r) _r=-1; _status=_r; goto abort;} while
(0)
;
259
260 /* it may be possible to restart given the info that was received in
261 * this response, so retry */
262 ABORT(R_RETRY)do { int _r=15; if(!_r) _r=-1; _status=_r; goto abort;} while
(0)
;
263 break;
264
265 case 5:
266 /* If the error code is 500 through 599, the client MAY resend the
267 * request; clients that do so MUST limit the number of times they do
268 * this. */
269 /* let the retransmit mechanism handle resending the request */
270 break;
271
272 default:
273 ABORT(R_REJECTED)do { int _r=11; if(!_r) _r=-1; _status=_r; goto abort;} while
(0)
;
274 break;
275 }
276
277 /* the spec says: "The client then does any processing specified by the authentication
278 * mechanism (see Section 10). This may result in a new transaction
279 * attempt." -- but this is handled already elsewhere, so needn't be repeated
280 * in this function */
281
282 _status=0;
283 abort:
284 return _status;
285}
286
287/* draft-ietf-behave-rfc3489bis-10.txt S 10.1.2 */
288int
289nr_stun_receive_request_or_indication_short_term_auth(nr_stun_message *msg,
290 nr_stun_message *res)
291{
292 int _status;
293 nr_stun_message_attribute *attr;
294
295 switch (msg->header.magic_cookie) {
296 default:
297 /* in RFC 3489 there is no magic cookie, it's part of the transaction ID */
298 /* drop thru */
299 case NR_STUN_MAGIC_COOKIE0x2112A442:
300 if (!nr_stun_message_has_attribute(msg, NR_STUN_ATTR_MESSAGE_INTEGRITY0x0008, &attr)) {
301 nr_stun_form_error_response(msg, res, 400, "Missing MESSAGE-INTEGRITY");
302 ABORT(R_ALREADY)do { int _r=4; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
303 }
304
305 if (!nr_stun_message_has_attribute(msg, NR_STUN_ATTR_USERNAME0x0006, 0)) {
306 nr_stun_form_error_response(msg, res, 400, "Missing USERNAME");
307 ABORT(R_ALREADY)do { int _r=4; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
308 }
309
310 if (attr->u.message_integrity.unknown_user) {
311 nr_stun_form_error_response(msg, res, 401, "Unrecognized USERNAME");
312 ABORT(R_ALREADY)do { int _r=4; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
313 }
314
315 if (!attr->u.message_integrity.valid) {
316 nr_stun_form_error_response(msg, res, 401, "Bad MESSAGE-INTEGRITY");
317 ABORT(R_ALREADY)do { int _r=4; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
318 }
319
320 break;
321 }
322
323 _status=0;
324 abort:
325 return _status;
326}
327
328/* draft-ietf-behave-rfc3489bis-10.txt S 10.1.3 */
329int
330nr_stun_receive_response_short_term_auth(nr_stun_message *res)
331{
332 int _status;
333 nr_stun_message_attribute *attr;
334
335 switch (res->header.magic_cookie) {
336 default:
337 /* in RFC 3489 there is no magic cookie, it's part of the transaction ID */
338 /* drop thru */
339 case NR_STUN_MAGIC_COOKIE0x2112A442:
340 if (!nr_stun_message_has_attribute(res, NR_STUN_ATTR_MESSAGE_INTEGRITY0x0008, &attr)) {
341 r_log(NR_LOG_STUN, LOG_WARNING4, "Missing MESSAGE-INTEGRITY");
342 ABORT(R_REJECTED)do { int _r=11; if(!_r) _r=-1; _status=_r; goto abort;} while
(0)
;
343 }
344
345 if (!attr->u.message_integrity.valid) {
346 r_log(NR_LOG_STUN, LOG_WARNING4, "Bad MESSAGE-INTEGRITY");
347 ABORT(R_REJECTED)do { int _r=11; if(!_r) _r=-1; _status=_r; goto abort;} while
(0)
;
348 }
349
350 break;
351 }
352
353 _status=0;
354 abort:
355 return _status;
356}
357
358static int
359nr_stun_add_realm_and_nonce(int new_nonce, nr_stun_server_client *clnt, nr_stun_message *res)
360{
361 int r,_status;
362 char *realm = 0;
363 const char *nonce;
364 UINT2 size;
365
366 if ((r=NR_reg_alloc_string(NR_STUN_REG_PREF_SERVER_REALM"stun.server.realm", &realm)))
367 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
368
369 if ((r=nr_stun_message_add_realm_attribute(res, realm)))
370 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
371
372 if (clnt) {
373 if (strlen(clnt->nonce) < 1)
374 new_nonce = 1;
375
376 if (new_nonce) {
377 if (NR_reg_get_uint2(NR_STUN_REG_PREF_SERVER_NONCE_SIZE"stun.server.nonce_size", &size))
378 size = 48;
379
380 if (size > (sizeof(clnt->nonce) - 1))
381 size = sizeof(clnt->nonce) - 1;
382
383 nr_random_alphanum(clnt->nonce, size);
384 clnt->nonce[size] = '\0';
385 }
386
387 nonce = clnt->nonce;
388 }
389 else {
390 /* user is not known, so use a bogus nonce since there's no way to
391 * store a good nonce with the client-specific data -- this nonce
392 * will be recognized as stale if the client attempts another
393 * request */
394 nonce = "STALE";
395 }
396
397 if ((r=nr_stun_message_add_nonce_attribute(res, nonce)))
398 ABORT(r)do { int _r=r; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
399
400 _status=0;
401 abort:
402#ifdef USE_TURN1
403assert(_status == 0)(static_cast <bool> (_status == 0) ? void (0) : __assert_fail
("_status == 0", __builtin_FILE (), __builtin_LINE (), __extension__
__PRETTY_FUNCTION__))
; /* TODO: !nn! cleanup after I reimplmement TURN */
404#endif
405 free(realm);
406 return _status;
407}
408
409/* draft-ietf-behave-rfc3489bis-10.txt S 10.2.1 - 10.2.2 */
410int
411nr_stun_receive_request_long_term_auth(nr_stun_message *req, nr_stun_server_ctx *ctx, nr_stun_message *res)
412{
413 int r,_status;
414 nr_stun_message_attribute *mi;
415 nr_stun_message_attribute *n;
416 nr_stun_server_client *clnt = 0;
417
418 switch (req->header.magic_cookie) {
419 default:
420 /* in RFC 3489 there is no magic cookie, it's part of the transaction ID */
421 /* drop thru */
422 case NR_STUN_MAGIC_COOKIE0x2112A442:
423 if (!nr_stun_message_has_attribute(req, NR_STUN_ATTR_USERNAME0x0006, 0)) {
424 nr_stun_form_error_response(req, res, 400, "Missing USERNAME");
425 nr_stun_add_realm_and_nonce(0, 0, res);
426 ABORT(R_ALREADY)do { int _r=4; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
427 }
428
429 if ((r=nr_stun_get_message_client(ctx, req, &clnt))) {
Although the value stored to 'r' is used in the enclosing expression, the value is never actually read from 'r'
430 nr_stun_form_error_response(req, res, 401, "Unrecognized USERNAME");
431 nr_stun_add_realm_and_nonce(0, 0, res);
432 ABORT(R_ALREADY)do { int _r=4; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
433 }
434
435 if (!nr_stun_message_has_attribute(req, NR_STUN_ATTR_MESSAGE_INTEGRITY0x0008, &mi)) {
436 nr_stun_form_error_response(req, res, 401, "Missing MESSAGE-INTEGRITY");
437 nr_stun_add_realm_and_nonce(0, clnt, res);
438 ABORT(R_ALREADY)do { int _r=4; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
439 }
440
441 assert(!mi->u.message_integrity.unknown_user)(static_cast <bool> (!mi->u.message_integrity.unknown_user
) ? void (0) : __assert_fail ("!mi->u.message_integrity.unknown_user"
, __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__
))
;
442
443 if (!nr_stun_message_has_attribute(req, NR_STUN_ATTR_REALM0x0014, 0)) {
444 nr_stun_form_error_response(req, res, 400, "Missing REALM");
445 ABORT(R_ALREADY)do { int _r=4; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
446 }
447
448 if (!nr_stun_message_has_attribute(req, NR_STUN_ATTR_NONCE0x0015, &n)) {
449 nr_stun_form_error_response(req, res, 400, "Missing NONCE");
450 ABORT(R_ALREADY)do { int _r=4; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
451 }
452
453 assert(sizeof(clnt->nonce) == sizeof(n->u.nonce))(static_cast <bool> (sizeof(clnt->nonce) == sizeof(n
->u.nonce)) ? void (0) : __assert_fail ("sizeof(clnt->nonce) == sizeof(n->u.nonce)"
, __builtin_FILE (), __builtin_LINE (), __extension__ __PRETTY_FUNCTION__
))
;
454 if (strncmp(clnt->nonce, n->u.nonce, sizeof(n->u.nonce))) {
455 nr_stun_form_error_response(req, res, 438, "Stale NONCE");
456 nr_stun_add_realm_and_nonce(1, clnt, res);
457 ABORT(R_ALREADY)do { int _r=4; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
458 }
459
460 if (!mi->u.message_integrity.valid) {
461 nr_stun_form_error_response(req, res, 401, "Bad MESSAGE-INTEGRITY");
462 nr_stun_add_realm_and_nonce(0, clnt, res);
463 ABORT(R_ALREADY)do { int _r=4; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
464 }
465
466 break;
467 }
468
469 _status=0;
470 abort:
471
472 return _status;
473}
474
475/* draft-ietf-behave-rfc3489bis-10.txt S 10.2.3 */
476int
477nr_stun_receive_response_long_term_auth(nr_stun_message *res, nr_stun_client_ctx *ctx)
478{
479 int _status;
480 nr_stun_message_attribute *attr;
481
482 switch (res->header.magic_cookie) {
483 default:
484 /* in RFC 3489 there is no magic cookie, it's part of the transaction ID */
485 /* drop thru */
486 case NR_STUN_MAGIC_COOKIE0x2112A442:
487 if (nr_stun_message_has_attribute(res, NR_STUN_ATTR_REALM0x0014, &attr)) {
488 free(ctx->realm);
489 ctx->realm = strdup(attr->u.realm);
490 if (!ctx->realm)
491 ABORT(R_NO_MEMORY)do { int _r=1; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
492 }
493 else {
494 r_log(NR_LOG_STUN, LOG_WARNING4, "Missing REALM");
495 ABORT(R_REJECTED)do { int _r=11; if(!_r) _r=-1; _status=_r; goto abort;} while
(0)
;
496 }
497
498 if (nr_stun_message_has_attribute(res, NR_STUN_ATTR_NONCE0x0015, &attr)) {
499 free(ctx->nonce);
500 ctx->nonce = strdup(attr->u.nonce);
501 if (!ctx->nonce)
502 ABORT(R_NO_MEMORY)do { int _r=1; if(!_r) _r=-1; _status=_r; goto abort;} while(
0)
;
503 }
504 else {
505 r_log(NR_LOG_STUN, LOG_WARNING4, "Missing NONCE");
506 ABORT(R_REJECTED)do { int _r=11; if(!_r) _r=-1; _status=_r; goto abort;} while
(0)
;
507 }
508
509 if (nr_stun_message_has_attribute(res, NR_STUN_ATTR_MESSAGE_INTEGRITY0x0008, &attr)) {
510 if (!attr->u.message_integrity.valid) {
511 r_log(NR_LOG_STUN, LOG_WARNING4, "Bad MESSAGE-INTEGRITY");
512 ABORT(R_REJECTED)do { int _r=11; if(!_r) _r=-1; _status=_r; goto abort;} while
(0)
;
513 }
514 }
515
516 break;
517 }
518
519 _status=0;
520 abort:
521 return _status;
522}
523