f364da4efeed25998332f02ba7f8ecdc67bb3a3b
[platform/upstream/libnice.git] / stun / tests / test-format.c
1 /*
2  * This file is part of the Nice GLib ICE library.
3  *
4  * (C) 2007 Nokia Corporation. All rights reserved.
5  *  Contact: Rémi Denis-Courmont
6  *
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/
11  *
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
15  * License.
16  *
17  * The Original Code is the Nice GLib ICE library.
18  *
19  * The Initial Developers of the Original Code are Collabora Ltd and Nokia
20  * Corporation. All Rights Reserved.
21  *
22  * Contributors:
23  *   Rémi Denis-Courmont, Nokia
24  *
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.
34  */
35
36 #ifdef HAVE_CONFIG_H
37 # include <config.h>
38 #endif
39
40 #include <sys/types.h>
41
42 #include "stun/stunagent.h"
43 #include <stdio.h>
44 #include <string.h>
45 #include <stdlib.h>
46 #include <stdarg.h>
47 #include <assert.h>
48
49 #ifdef _WIN32
50 #include <winsock2.h>
51 #else
52 #include <sys/types.h>
53 #include <sys/socket.h>
54 #include <arpa/inet.h>
55 #include <netinet/in.h>
56 #endif
57
58
59 static void fatal (const char *msg, ...)
60 {
61   va_list ap;
62   va_start (ap, msg);
63   vfprintf (stderr, msg, ap);
64   va_end (ap);
65   fputc ('\n', stderr);
66   exit (1);
67 }
68
69 static const uint8_t usr[] = "admin";
70 static const uint8_t pwd[] = "s3kr3t";
71
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)
75 {
76
77   if (username_len != strlen ((char *) usr) ||
78       memcmp (username, usr, strlen ((char *) usr)) != 0)
79     fatal ("vector test : Validater received wrong username!");
80
81   *password = (uint8_t *) pwd;
82   *password_len = strlen ((char *) pwd);
83
84
85   return true;
86 }
87 static void
88 dynamic_check (StunAgent *agent, StunMessage *msg, size_t len)
89 {
90   StunMessage msg2;
91
92   if (stun_agent_validate (agent, &msg2, msg->buffer, len, dynamic_check_validater, NULL) != STUN_VALIDATION_SUCCESS)
93     fatal ("Could not validate message");
94
95   printf ("Built message of %u bytes\n", (unsigned)len);
96 }
97
98
99 static size_t
100 finish_check (StunAgent *agent, StunMessage *msg)
101 {
102   uint8_t buf[STUN_MAX_MESSAGE_SIZE + 8];
103   size_t len;
104   uint16_t plen;
105   StunMessage msg2 = {0};
106   StunMessageReturn val;
107
108   msg2.agent = msg->agent;
109   msg2.buffer = buf;
110   msg2.buffer_len = sizeof(buf);
111   memcpy (msg2.buffer, msg->buffer, sizeof(buf) > msg->buffer_len ? msg->buffer_len : sizeof(buf));
112
113   len = stun_agent_finish_message (agent, msg, NULL, 0);
114
115   if (len <= 0)
116     fatal ("Cannot finish message");
117   dynamic_check (agent, msg, len);
118
119   if (stun_message_find (&msg2, STUN_ATTRIBUTE_MESSAGE_INTEGRITY, &plen) != NULL)
120     fatal ("Missing HMAC test failed");
121
122   val = stun_message_append_string (&msg2, STUN_ATTRIBUTE_USERNAME, (char *) usr);
123   assert (val == STUN_MESSAGE_RETURN_SUCCESS);
124
125   len = stun_agent_finish_message (agent, &msg2, pwd, strlen ((char *) pwd));
126
127   if (len <= 0)
128     fatal ("Cannot finish message with short-term creds");
129   dynamic_check (agent, &msg2, len);
130
131   return len;
132 }
133
134 static void
135 check_af (const char *name, int family, socklen_t addrlen)
136 {
137   struct sockaddr_storage addr;
138   uint8_t buf[100];
139   StunAgent agent;
140   StunMessage msg;
141   uint16_t known_attributes[] = {STUN_ATTRIBUTE_USERNAME, STUN_ATTRIBUTE_MESSAGE_INTEGRITY, STUN_ATTRIBUTE_ERROR_CODE, 0};
142
143   stun_agent_init (&agent, known_attributes,
144       STUN_COMPATIBILITY_RFC5389, STUN_AGENT_USAGE_USE_FINGERPRINT);
145
146   assert (addrlen <= sizeof (addr));
147
148   memset (&addr, 0, sizeof (addr));
149   stun_agent_init_request (&agent, &msg, buf, sizeof(buf), STUN_BINDING);
150
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,
156           &addr, addrlen) !=
157       STUN_MESSAGE_RETURN_UNSUPPORTED_ADDRESS)
158     fatal ("Unknown address family xor test failed");
159
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);
165
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);
169
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);
173
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);
177 }
178
179 int main (void)
180 {
181   uint8_t buf[100];
182   size_t len;
183   union {
184     struct sockaddr_storage storage;
185     struct sockaddr addr;
186   } addr;
187
188   StunAgent agent;
189   StunMessage msg;
190   uint16_t known_attributes[] = {STUN_ATTRIBUTE_USERNAME,
191                                  STUN_ATTRIBUTE_MESSAGE_INTEGRITY,
192                                  STUN_ATTRIBUTE_ERROR_CODE,
193                                  0};
194
195   stun_agent_init (&agent, known_attributes,
196       STUN_COMPATIBILITY_RFC5389, STUN_AGENT_USAGE_USE_FINGERPRINT);
197
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");
203
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");
209
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");
226
227   /* Overflow tests */
228   stun_agent_init_request (&agent, &msg, buf, sizeof(buf), STUN_BINDING);
229
230   for (len = 0;
231        stun_message_append_flag (&msg, 0xffff) !=
232            STUN_MESSAGE_RETURN_NOT_ENOUGH_SPACE;
233        len += 4)
234   {
235     if (len > 0xffff)
236       fatal ("Overflow protection test failed");
237   }
238
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");
248
249   memset (&addr, 0, sizeof (addr));
250   addr.addr.sa_family = AF_INET;
251 #ifdef HAVE_SS_LEN
252   addr.addr.ss_len = sizeof (addr);
253 #endif
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");
257
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");
262
263   /* Address attributes tests */
264   check_af ("IPv4", AF_INET, sizeof (struct sockaddr_in));
265 #ifdef AF_INET6
266   check_af ("IPv6", AF_INET6, sizeof (struct sockaddr_in6));
267 #endif
268
269   return 0;
270 }