2 * This file is part of the Nice GLib ICE library.
4 * (C) 2007 Nokia Corporation. All rights reserved.
5 * Contact: Rémi Denis-Courmont
7 * The contents of this file are subject to the Mozilla Public License Version
8 * 1.1 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://www.mozilla.org/MPL/
12 * Software distributed under the License is distributed on an "AS IS" basis,
13 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14 * for the specific language governing rights and limitations under the
17 * The Original Code is the Nice GLib ICE library.
19 * The Initial Developers of the Original Code are Collabora Ltd and Nokia
20 * Corporation. All Rights Reserved.
23 * Rémi Denis-Courmont, Nokia
25 * Alternatively, the contents of this file may be used under the terms of the
26 * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
27 * case the provisions of LGPL are applicable instead of those above. If you
28 * wish to allow use of your version of this file only under the terms of the
29 * LGPL and not to allow others to use your version of this file under the
30 * MPL, indicate your decision by deleting the provisions above and replace
31 * them with the notice and other provisions required by the LGPL. If you do
32 * not delete the provisions above, a recipient may use your version of this
33 * file under either the MPL or the LGPL.
40 #include <sys/types.h>
42 #include "stun/stunagent.h"
52 #include <sys/types.h>
53 #include <sys/socket.h>
54 #include <arpa/inet.h>
55 #include <netinet/in.h>
59 static void fatal (const char *msg, ...)
63 vfprintf (stderr, msg, ap);
69 static const uint8_t usr[] = "admin";
70 static const uint8_t pwd[] = "s3kr3t";
72 static bool dynamic_check_validater (StunAgent *agent,
73 StunMessage *message, uint8_t *username, uint16_t username_len,
74 uint8_t **password, size_t *password_len, void *user_data)
77 if (username_len != strlen ((char *) usr) ||
78 memcmp (username, usr, strlen ((char *) usr)) != 0)
79 fatal ("vector test : Validater received wrong username!");
81 *password = (uint8_t *) pwd;
82 *password_len = strlen ((char *) pwd);
88 dynamic_check (StunAgent *agent, StunMessage *msg, size_t len)
92 if (stun_agent_validate (agent, &msg2, msg->buffer, len, dynamic_check_validater, NULL) != STUN_VALIDATION_SUCCESS)
93 fatal ("Could not validate message");
95 printf ("Built message of %u bytes\n", (unsigned)len);
100 finish_check (StunAgent *agent, StunMessage *msg)
102 uint8_t buf[STUN_MAX_MESSAGE_SIZE + 8];
105 StunMessage msg2 = {0};
106 StunMessageReturn val;
108 msg2.agent = msg->agent;
110 msg2.buffer_len = sizeof(buf);
111 memcpy (msg2.buffer, msg->buffer, sizeof(buf) > msg->buffer_len ? msg->buffer_len : sizeof(buf));
113 len = stun_agent_finish_message (agent, msg, NULL, 0);
116 fatal ("Cannot finish message");
117 dynamic_check (agent, msg, len);
119 if (stun_message_find (&msg2, STUN_ATTRIBUTE_MESSAGE_INTEGRITY, &plen) != NULL)
120 fatal ("Missing HMAC test failed");
122 val = stun_message_append_string (&msg2, STUN_ATTRIBUTE_USERNAME, (char *) usr);
123 assert (val == STUN_MESSAGE_RETURN_SUCCESS);
125 len = stun_agent_finish_message (agent, &msg2, pwd, strlen ((char *) pwd));
128 fatal ("Cannot finish message with short-term creds");
129 dynamic_check (agent, &msg2, len);
135 check_af (const char *name, int family, socklen_t addrlen)
137 struct sockaddr_storage addr;
141 uint16_t known_attributes[] = {STUN_ATTRIBUTE_USERNAME, STUN_ATTRIBUTE_MESSAGE_INTEGRITY, STUN_ATTRIBUTE_ERROR_CODE, 0};
143 stun_agent_init (&agent, known_attributes,
144 STUN_COMPATIBILITY_RFC5389, STUN_AGENT_USAGE_USE_FINGERPRINT);
146 assert (addrlen <= sizeof (addr));
148 memset (&addr, 0, sizeof (addr));
149 stun_agent_init_request (&agent, &msg, buf, sizeof(buf), STUN_BINDING);
151 if (stun_message_append_addr (&msg, STUN_ATTRIBUTE_MAPPED_ADDRESS,
152 (struct sockaddr *) &addr, addrlen) !=
153 STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS)
154 fatal ("Unknown address family test failed");
155 if (stun_message_append_xor_addr (&msg, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS,
157 STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS)
158 fatal ("Unknown address family xor test failed");
160 addr.ss_family = family;
161 if (stun_message_append_addr (&msg, STUN_ATTRIBUTE_MAPPED_ADDRESS,
162 (struct sockaddr *) &addr, addrlen - 1) !=
163 STUN_MESSAGE_RETURN_INVALID)
164 fatal ("Too small %s sockaddr test failed", name);
166 if (stun_message_append_xor_addr (&msg, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS,
167 &addr, addrlen - 1) != STUN_MESSAGE_RETURN_INVALID)
168 fatal ("Too small %s sockaddr xor test failed", name);
170 if (stun_message_append_addr (&msg, STUN_ATTRIBUTE_MAPPED_ADDRESS,
171 (struct sockaddr *) &addr, addrlen) != STUN_MESSAGE_RETURN_SUCCESS)
172 fatal ("%s sockaddr test failed", name);
174 if (stun_message_append_xor_addr (&msg, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS,
175 &addr, addrlen) != STUN_MESSAGE_RETURN_SUCCESS)
176 fatal ("%s sockaddr xor test failed", name);
184 struct sockaddr_storage storage;
185 struct sockaddr addr;
190 uint16_t known_attributes[] = {STUN_ATTRIBUTE_USERNAME,
191 STUN_ATTRIBUTE_MESSAGE_INTEGRITY,
192 STUN_ATTRIBUTE_ERROR_CODE,
195 stun_agent_init (&agent, known_attributes,
196 STUN_COMPATIBILITY_RFC5389, STUN_AGENT_USAGE_USE_FINGERPRINT);
198 /* Request formatting test */
199 stun_agent_init_request (&agent, &msg, buf, sizeof(buf), STUN_BINDING);
200 finish_check (&agent, &msg);
201 if (memcmp (buf, "\x00\x01", 2))
202 fatal ("Request formatting test failed");
204 /* Response formatting test */
205 stun_agent_init_response (&agent, &msg, buf, sizeof (buf), &msg);
206 finish_check (&agent, &msg);
207 if (memcmp (buf, "\x01\x01", 2))
208 fatal ("Response formatting test failed");
210 /* Error formatting test */
211 stun_agent_init_request (&agent, &msg, buf, sizeof(buf), STUN_BINDING);
212 finish_check (&agent, &msg);
213 if (!stun_agent_init_error (&agent, &msg, buf, sizeof (buf), &msg, 400))
214 fatal ("Error initialization test failed");
215 finish_check (&agent, &msg);
216 if (memcmp (buf, "\x01\x11", 2))
217 fatal ("Error formatting test failed");
218 /* Unknown error formatting test */
219 stun_agent_init_request (&agent, &msg, buf, sizeof(buf), STUN_BINDING);
220 finish_check (&agent, &msg);
221 if (!stun_agent_init_error (&agent, &msg, buf, sizeof (buf), &msg, 666))
222 fatal ("Unknown error initialization test failed");
223 finish_check (&agent, &msg);
224 if (memcmp (buf, "\x01\x11", 2))
225 fatal ("Unknown error formatting test failed");
228 stun_agent_init_request (&agent, &msg, buf, sizeof(buf), STUN_BINDING);
231 stun_message_append_flag (&msg, 0xffff) !=
232 STUN_MESSAGE_RETURN_NOT_ENOUGH_SPACE;
236 fatal ("Overflow protection test failed");
239 if (stun_message_append32 (&msg, 0xffff, 0x12345678) !=
240 STUN_MESSAGE_RETURN_NOT_ENOUGH_SPACE)
241 fatal ("Double-word overflow test failed");
242 if (stun_message_append64 (&msg, 0xffff,
243 0x123456789abcdef0) != STUN_MESSAGE_RETURN_NOT_ENOUGH_SPACE)
244 fatal ("Quad-word overflow test failed");
245 if (stun_message_append_string (&msg, 0xffff, "foobar") !=
246 STUN_MESSAGE_RETURN_NOT_ENOUGH_SPACE)
247 fatal ("String overflow test failed");
249 memset (&addr, 0, sizeof (addr));
250 addr.addr.sa_family = AF_INET;
252 addr.addr.ss_len = sizeof (addr);
254 if (stun_message_append_xor_addr (&msg, 0xffff, &addr.storage,
255 sizeof (addr)) != STUN_MESSAGE_RETURN_NOT_ENOUGH_SPACE)
256 fatal ("Address overflow test failed");
258 if (stun_agent_finish_message (&agent, &msg, NULL, 0) != 0)
259 fatal ("Fingerprint overflow test failed");
260 if (stun_agent_finish_message (&agent, &msg, pwd, strlen ((char *) pwd)) != 0)
261 fatal ("Message integrity overflow test failed");
263 /* Address attributes tests */
264 check_af ("IPv4", AF_INET, sizeof (struct sockaddr_in));
266 check_af ("IPv6", AF_INET6, sizeof (struct sockaddr_in6));