Imported Upstream version 0.1.17
[platform/upstream/libnice.git] / stun / stunagent.h
1 /*
2  * This file is part of the Nice GLib ICE library.
3  *
4  * (C) 2008-2009 Collabora Ltd.
5  *  Contact: Youness Alaoui
6  * (C) 2008-2009 Nokia Corporation. All rights reserved.
7  *
8  * The contents of this file are subject to the Mozilla Public License Version
9  * 1.1 (the "License"); you may not use this file except in compliance with
10  * the License. You may obtain a copy of the License at
11  * http://www.mozilla.org/MPL/
12  *
13  * Software distributed under the License is distributed on an "AS IS" basis,
14  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
15  * for the specific language governing rights and limitations under the
16  * License.
17  *
18  * The Original Code is the Nice GLib ICE library.
19  *
20  * The Initial Developers of the Original Code are Collabora Ltd and Nokia
21  * Corporation. All Rights Reserved.
22  *
23  * Contributors:
24  *   Youness Alaoui, Collabora Ltd.
25  *
26  * Alternatively, the contents of this file may be used under the terms of the
27  * the GNU Lesser General Public License Version 2.1 (the "LGPL"), in which
28  * case the provisions of LGPL are applicable instead of those above. If you
29  * wish to allow use of your version of this file only under the terms of the
30  * LGPL and not to allow others to use your version of this file under the
31  * MPL, indicate your decision by deleting the provisions above and replace
32  * them with the notice and other provisions required by the LGPL. If you do
33  * not delete the provisions above, a recipient may use your version of this
34  * file under either the MPL or the LGPL.
35  */
36
37 #ifndef _STUN_AGENT_H
38 #define _STUN_AGENT_H
39
40 /**
41  * SECTION:stunagent
42  * @short_description: STUN agent for building and validating STUN messages
43  * @include: stun/stunagent.h
44  * @see_also: #StunMessage
45  * @stability: Stable
46  *
47  * The STUN Agent allows you to create and validate STUN messages easily.
48  * It's main purpose is to make sure the building and validation methods used
49  * are compatible with the RFC you create it with. It also tracks the transaction
50  * ids of the requests you send, so you can validate if a STUN response you
51  * received should be processed by that agent or not.
52  *
53  */
54
55
56 #ifdef _WIN32
57 #include "win32_common.h"
58 #else
59 #include <stdint.h>
60 #endif
61
62 #include <stdbool.h>
63 #include <sys/types.h>
64
65 /**
66  * StunAgent:
67  *
68  * An opaque structure representing the STUN agent.
69  */
70 typedef struct stun_agent_t StunAgent;
71
72 #include "stunmessage.h"
73 #include "debug.h"
74
75 /**
76  * StunCompatibility:
77  * @STUN_COMPATIBILITY_RFC3489: Use the STUN specifications compatible with
78  * RFC 3489
79  * @STUN_COMPATIBILITY_RFC5389: Use the STUN specifications compatible with
80  * RFC 5389
81  * @STUN_COMPATIBILITY_MSICE2: Use the STUN specifications compatible with
82  * [MS-ICE2] (a mix between RFC3489 and RFC5389)
83  * @STUN_COMPATIBILITY_OC2007: Use the STUN specifications compatible with
84  * Microsoft Office Communicator 2007 (basically RFC3489 with swapped
85  * REALM and NONCE attribute hex IDs, attributes are not aligned)
86  * @STUN_COMPATIBILITY_WLM2009: An alias for @STUN_COMPATIBILITY_MSICE2
87  * @STUN_COMPATIBILITY_LAST: Dummy last compatibility mode
88  *
89  * Enum that specifies the STUN compatibility mode of the #StunAgent
90  *
91  * <warning>@STUN_COMPATIBILITY_WLM2009 is deprecated and should not be used
92  * in newly-written code. It is kept for compatibility reasons and represents
93  * the same compatibility as @STUN_COMPATIBILITY_MSICE2.</warning>
94  */
95 typedef enum {
96   STUN_COMPATIBILITY_RFC3489,
97   STUN_COMPATIBILITY_RFC5389,
98   STUN_COMPATIBILITY_MSICE2,
99   STUN_COMPATIBILITY_OC2007,
100   STUN_COMPATIBILITY_WLM2009 = STUN_COMPATIBILITY_MSICE2,
101   STUN_COMPATIBILITY_LAST = STUN_COMPATIBILITY_OC2007
102 } StunCompatibility;
103
104
105 /**
106  * StunValidationStatus:
107  * @STUN_VALIDATION_SUCCESS: The message is validated
108  * @STUN_VALIDATION_NOT_STUN: This is not a valid STUN message
109  * @STUN_VALIDATION_INCOMPLETE_STUN: The message seems to be valid but incomplete
110  * @STUN_VALIDATION_BAD_REQUEST: The message does not have the cookie or the
111  * fingerprint while the agent needs it with its usage
112  * @STUN_VALIDATION_UNAUTHORIZED_BAD_REQUEST: The message is valid but
113  * unauthorized with no username and message-integrity attributes.
114  * A BAD_REQUEST error must be generated
115  * @STUN_VALIDATION_UNAUTHORIZED: The message is valid but unauthorized as
116  * the username/password do not match.
117  * An UNAUTHORIZED error must be generated
118  * @STUN_VALIDATION_UNMATCHED_RESPONSE: The message is valid but this is a
119  * response/error that doesn't match a previously sent request
120  * @STUN_VALIDATION_UNKNOWN_REQUEST_ATTRIBUTE: The message is valid but
121  * contains one or more unknown comprehension attributes.
122  * stun_agent_build_unknown_attributes_error() should be called
123  * @STUN_VALIDATION_UNKNOWN_ATTRIBUTE: The message is valid but contains one
124  * or more unknown comprehension attributes. This is a response, or error,
125  * or indication message and no error response should be sent
126  *
127  * This enum is used as the return value of stun_agent_validate() and represents
128  * the status result of the validation of a STUN message.
129  */
130 typedef enum {
131   STUN_VALIDATION_SUCCESS,
132   STUN_VALIDATION_NOT_STUN,
133   STUN_VALIDATION_INCOMPLETE_STUN,
134   STUN_VALIDATION_BAD_REQUEST,
135   STUN_VALIDATION_UNAUTHORIZED_BAD_REQUEST,
136   STUN_VALIDATION_UNAUTHORIZED,
137   STUN_VALIDATION_UNMATCHED_RESPONSE,
138   STUN_VALIDATION_UNKNOWN_REQUEST_ATTRIBUTE,
139   STUN_VALIDATION_UNKNOWN_ATTRIBUTE,
140 } StunValidationStatus;
141
142 /**
143  * StunAgentUsageFlags:
144  * @STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS: The agent should be using the short
145  * term credentials mechanism for authenticating STUN messages
146  * @STUN_AGENT_USAGE_LONG_TERM_CREDENTIALS: The agent should be using the long
147  * term credentials mechanism for authenticating STUN messages
148  * @STUN_AGENT_USAGE_USE_FINGERPRINT: The agent should add the FINGERPRINT
149  * attribute to the STUN messages it creates.
150  * @STUN_AGENT_USAGE_ADD_SOFTWARE: The agent should add the SOFTWARE attribute
151  * to the STUN messages it creates. Calling nice_agent_set_software() will have
152  * the same effect as enabling this Usage. STUN Indications do not have the
153  * SOFTWARE attributes added to them though. The SOFTWARE attribute is only
154  * added for the RFC5389 and MSICE2 compatibility modes.
155  * @STUN_AGENT_USAGE_IGNORE_CREDENTIALS: The agent should ignore any credentials
156  * in the STUN messages it receives (the MESSAGE-INTEGRITY attribute
157  * will never be validated by stun_agent_validate())
158  * @STUN_AGENT_USAGE_NO_INDICATION_AUTH: The agent should ignore credentials
159  * in the STUN messages it receives if the #StunClass of the message is
160  * #STUN_INDICATION (some implementation require #STUN_INDICATION messages to
161  * be authenticated, while others never add a MESSAGE-INTEGRITY attribute to a
162  * #STUN_INDICATION message)
163  * @STUN_AGENT_USAGE_FORCE_VALIDATER: The agent should always try to validate
164  * the password of a STUN message, even if it already knows what the password
165  * should be (a response to a previously created request). This means that the
166  * #StunMessageIntegrityValidate callback will always be called when there is
167  * a MESSAGE-INTEGRITY attribute.
168  * @STUN_AGENT_USAGE_NO_ALIGNED_ATTRIBUTES: The agent should not assume STUN
169  * attributes are aligned on 32-bit boundaries when parsing messages and also
170  * do not add padding when creating messages.
171  *
172  * This enum defines a bitflag usages for a #StunAgent and they will define how
173  * the agent should behave, independently of the compatibility mode it uses.
174  * <para> See also: stun_agent_init() </para>
175  * <para> See also: stun_agent_validate() </para>
176  */
177 typedef enum {
178   STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS    = (1 << 0),
179   STUN_AGENT_USAGE_LONG_TERM_CREDENTIALS     = (1 << 1),
180   STUN_AGENT_USAGE_USE_FINGERPRINT           = (1 << 2),
181   STUN_AGENT_USAGE_ADD_SOFTWARE              = (1 << 3),
182   STUN_AGENT_USAGE_IGNORE_CREDENTIALS        = (1 << 4),
183   STUN_AGENT_USAGE_NO_INDICATION_AUTH        = (1 << 5),
184   STUN_AGENT_USAGE_FORCE_VALIDATER           = (1 << 6),
185   STUN_AGENT_USAGE_NO_ALIGNED_ATTRIBUTES     = (1 << 7),
186 } StunAgentUsageFlags;
187
188
189 typedef struct {
190   StunTransactionId id;
191   StunMethod method;
192   uint8_t *key;
193   size_t key_len;
194   uint8_t long_term_key[16];
195   bool long_term_valid;
196   bool valid;
197 } StunAgentSavedIds;
198
199 struct stun_agent_t {
200   StunCompatibility compatibility;
201   StunAgentSavedIds sent_ids[STUN_AGENT_MAX_SAVED_IDS];
202   uint16_t *known_attributes;
203   StunAgentUsageFlags usage_flags;
204   const char *software_attribute;
205   bool ms_ice2_send_legacy_connchecks;
206 };
207
208 /**
209  * StunDefaultValidaterData:
210  * @username: The username
211  * @username_len: The length of the @username
212  * @password: The password
213  * @password_len: The length of the @password
214  *
215  * This structure is used as an element of the user_data to the
216  * stun_agent_default_validater() function for authenticating a STUN
217  * message during validationg.
218  * <para> See also: stun_agent_default_validater() </para>
219  */
220 typedef struct {
221   uint8_t *username;
222   size_t username_len;
223   uint8_t *password;
224   size_t password_len;
225 } StunDefaultValidaterData;
226
227
228 /**
229  * StunMessageIntegrityValidate:
230  * @agent: The #StunAgent
231  * @message: The #StunMessage being validated
232  * @username: The username found in the @message
233  * @username_len: The length of @username
234  * @password: The password associated with that username. This argument is a
235  * pointer to a byte array that must be set by the validater function.
236  * @password_len: The length of @password which must also be set by the
237  * validater function.
238  * @user_data: Data to give the function
239  *
240  * This is the prototype for the @validater argument of the stun_agent_validate()
241  * function.
242  * <para> See also: stun_agent_validate() </para>
243  * Returns: %TRUE if the authentication was successful,
244  * %FALSE if the authentication failed
245  */
246 typedef bool (*StunMessageIntegrityValidate) (StunAgent *agent,
247     StunMessage *message, uint8_t *username, uint16_t username_len,
248     uint8_t **password, size_t *password_len, void *user_data);
249
250 /**
251  * stun_agent_default_validater:
252  * @agent: The #StunAgent
253  * @message: The #StunMessage being validated
254  * @username: The username found in the @message
255  * @username_len: The length of @username
256  * @password: The password associated with that username. This argument is a
257  * pointer to a byte array that must be set by the validater function.
258  * @password_len: The length of @password which must also be set by the
259  * validater function.
260  * @user_data: This must be an array of #StunDefaultValidaterData structures.
261  * The last element in the array must have a username set to NULL
262  *
263  * This is a helper function to be used with stun_agent_validate(). If no
264  * complicated processing of the username needs to be done, this function can
265  * be used with stun_agent_validate() to quickly and easily match the username
266  * of a STUN message with its password. Its @user_data argument must be an array
267  * of #StunDefaultValidaterData which will allow us to map a username to a
268  * password
269  * <para> See also: stun_agent_validate() </para>
270  * Returns: %TRUE if the authentication was successful,
271  * %FALSE if the authentication failed
272  */
273 bool stun_agent_default_validater (StunAgent *agent,
274     StunMessage *message, uint8_t *username, uint16_t username_len,
275     uint8_t **password, size_t *password_len, void *user_data);
276
277 /**
278  * stun_agent_init:
279  * @agent: The #StunAgent to initialize
280  * @known_attributes: An array of #uint16_t specifying which attributes should
281  * be known by the agent. Any STUN message received that contains a mandatory
282  * attribute that is not in this array will yield a
283  * #STUN_VALIDATION_UNKNOWN_REQUEST_ATTRIBUTE or a
284  * #STUN_VALIDATION_UNKNOWN_ATTRIBUTE error when calling stun_agent_validate()
285  * @compatibility: The #StunCompatibility to use for this agent. This will affect
286  * how the agent builds and validates the STUN messages
287  * @usage_flags: A bitflag using #StunAgentUsageFlags values to define which
288  * STUN usages the agent should use.
289  *
290  * This function must be called to initialize an agent before it is being used.
291  *
292  <note>
293    <para>
294     The @known_attributes data must exist in memory as long as the @agent is used
295     </para>
296     <para>
297     If the #STUN_AGENT_USAGE_SHORT_TERM_CREDENTIALS and
298     #STUN_AGENT_USAGE_LONG_TERM_CREDENTIALS usage flags are not set, then the
299     agent will default in using the short term credentials mechanism
300     </para>
301     <para>
302     The #STUN_AGENT_USAGE_USE_FINGERPRINT and #STUN_AGENT_USAGE_ADD_SOFTWARE
303     usage flags are only valid if the #STUN_COMPATIBILITY_RFC5389 or
304     #STUN_COMPATIBILITY_MSICE2 @compatibility is used
305     </para>
306  </note>
307  */
308 void stun_agent_init (StunAgent *agent, const uint16_t *known_attributes,
309     StunCompatibility compatibility, StunAgentUsageFlags usage_flags);
310
311 /**
312  * stun_agent_validate:
313  * @agent: The #StunAgent
314  * @msg: The #StunMessage to build
315  * @buffer: The data buffer of the STUN message
316  * @buffer_len: The length of @buffer
317  * @validater: A #StunMessageIntegrityValidate function callback that will
318  * be called if the agent needs to validate a MESSAGE-INTEGRITY attribute. It
319  * will only be called if the agent finds a message that needs authentication
320  * and a USERNAME is present in the STUN message, but no password is known.
321  * The validater will not be called if the #STUN_AGENT_USAGE_IGNORE_CREDENTIALS
322  * usage flag is set on the agent, and it will always be called if the
323  * #STUN_AGENT_USAGE_FORCE_VALIDATER usage flag is set on the agent.
324  * @validater_data: A user data to give to the @validater callback when it gets
325  * called.
326  *
327  * This function is used to validate an inbound STUN message and transform its
328  * data buffer into a #StunMessage. It will take care of various validation
329  * algorithms to make sure that the STUN message is valid and correctly
330  * authenticated.
331  * <para> See also: stun_agent_default_validater() </para>
332  * Returns: A #StunValidationStatus
333  <note>
334    <para>
335    if the return value is different from #STUN_VALIDATION_NOT_STUN or
336    #STUN_VALIDATION_INCOMPLETE_STUN, then the @msg argument will contain a valid
337    STUN message that can be used.
338    This means that you can use the @msg variable as the @request argument to
339    functions like stun_agent_init_error() or
340    stun_agent_build_unknown_attributes_error().
341    If the return value is #STUN_VALIDATION_BAD_REQUEST,
342    #STUN_VALIDATION_UNAUTHORIZED or #STUN_VALIDATION_UNAUTHORIZED_BAD_REQUEST
343    then the @key in the #StunMessage will not be set, so that error responses
344    will not have a MESSAGE-INTEGRITY attribute.
345    </para>
346  </note>
347  */
348 StunValidationStatus stun_agent_validate (StunAgent *agent, StunMessage *msg,
349     const uint8_t *buffer, size_t buffer_len,
350     StunMessageIntegrityValidate validater, void * validater_data);
351
352 /**
353  * stun_agent_init_request:
354  * @agent: The #StunAgent
355  * @msg: The #StunMessage to build
356  * @buffer: The buffer to use in the #StunMessage
357  * @buffer_len: The length of the buffer
358  * @m: The #StunMethod of the request
359  *
360  * Creates a new STUN message of class #STUN_REQUEST and with the method @m
361  * Returns: %TRUE if the message was initialized correctly, %FALSE otherwise
362  */
363 bool stun_agent_init_request (StunAgent *agent, StunMessage *msg,
364     uint8_t *buffer, size_t buffer_len, StunMethod m);
365
366 /**
367  * stun_agent_init_indication:
368  * @agent: The #StunAgent
369  * @msg: The #StunMessage to build
370  * @buffer: The buffer to use in the #StunMessage
371  * @buffer_len: The length of the buffer
372  * @m: The #StunMethod of the indication
373  *
374  * Creates a new STUN message of class #STUN_INDICATION and with the method @m
375  * Returns: %TRUE if the message was initialized correctly, %FALSE otherwise
376  */
377 bool stun_agent_init_indication (StunAgent *agent, StunMessage *msg,
378     uint8_t *buffer, size_t buffer_len, StunMethod m);
379
380 /**
381  * stun_agent_init_response:
382  * @agent: The #StunAgent
383  * @msg: The #StunMessage to build
384  * @buffer: The buffer to use in the #StunMessage
385  * @buffer_len: The length of the buffer
386  * @request: The #StunMessage of class #STUN_REQUEST that this response is for
387  *
388  * Creates a new STUN message of class #STUN_RESPONSE and with the same method
389  * and transaction ID as the message @request. This will also copy the pointer
390  * to the key that was used to authenticate the request, so you won't need to
391  * specify the key with stun_agent_finish_message()
392  * Returns: %TRUE if the message was initialized correctly, %FALSE otherwise
393  */
394 bool stun_agent_init_response (StunAgent *agent, StunMessage *msg,
395     uint8_t *buffer, size_t buffer_len, const StunMessage *request);
396
397 /**
398  * stun_agent_init_error:
399  * @agent: The #StunAgent
400  * @msg: The #StunMessage to build
401  * @buffer: The buffer to use in the #StunMessage
402  * @buffer_len: The length of the buffer
403  * @request: The #StunMessage of class #STUN_REQUEST that this error response
404  * is for
405  * @err: The #StunError to put in the ERROR-CODE attribute of the error response
406  *
407  * Creates a new STUN message of class #STUN_ERROR and with the same method
408  * and transaction ID as the message @request. This will also copy the pointer
409  * to the key that was used to authenticate the request (if authenticated),
410  * so you won't need to specify the key with stun_agent_finish_message().
411  * It will then add the ERROR-CODE attribute with code @err and the associated
412  * string.
413  * Returns: %TRUE if the message was initialized correctly, %FALSE otherwise
414  */
415 bool stun_agent_init_error (StunAgent *agent, StunMessage *msg,
416     uint8_t *buffer, size_t buffer_len, const StunMessage *request,
417     StunError err);
418
419 /**
420  * stun_agent_build_unknown_attributes_error:
421  * @agent: The #StunAgent
422  * @msg: The #StunMessage to build
423  * @buffer: The buffer to use in the #StunMessage
424  * @buffer_len: The length of the buffer
425  * @request: The #StunMessage of class #STUN_REQUEST that this response is for
426  *
427  * Creates a new STUN message of class #STUN_ERROR and with the same method
428  * and transaction ID as the message @request.  It will then add the ERROR-CODE
429  * attribute with code #STUN_ERROR_UNKNOWN_ATTRIBUTE and add all the unknown
430  * mandatory attributes from the @request STUN message in the
431  * #STUN_ATTRIBUTE_UNKNOWN_ATTRIBUTES attribute, it will then finish the message
432  * by calling stun_agent_finish_message()
433  * Returns: The size of the message built
434  */
435 size_t stun_agent_build_unknown_attributes_error (StunAgent *agent,
436     StunMessage *msg, uint8_t *buffer, size_t buffer_len,
437     const StunMessage *request);
438
439
440 /**
441  * stun_agent_finish_message:
442  * @agent: The #StunAgent
443  * @msg: The #StunMessage to finish
444  * @key: The key to use for the MESSAGE-INTEGRITY attribute
445  * @key_len: The length of the @key
446  *
447  * This function will 'finish' a message and make it ready to be sent. It will
448  * add the MESSAGE-INTEGRITY and FINGERPRINT attributes if necessary. If the
449  * STUN message has a #STUN_REQUEST class, it will save the transaction id of
450  * the message in the agent for future matching of the response.
451  * <para>See also: stun_agent_forget_transaction()</para>
452  * Returns: The final size of the message built or 0 if an error occured
453  * <note>
454      <para>
455        The return value must always be checked. a value of 0 means the either
456        the buffer's size is too small to contain the finishing attributes
457        (MESSAGE-INTEGRITY, FINGERPRINT), or that there is no more free slots
458        for saving the sent id in the agent's state.
459      </para>
460      <para>
461        Everytime stun_agent_finish_message() is called for a #STUN_REQUEST
462        message, you must make sure to call stun_agent_forget_transaction() in
463        case the response times out and is never received. This is to avoid
464        filling up the #StunAgent's sent ids state preventing any further
465        use of the stun_agent_finish_message()
466      </para>
467    </note>
468  */
469 size_t stun_agent_finish_message (StunAgent *agent, StunMessage *msg,
470    const uint8_t *key, size_t key_len);
471
472 /**
473  * stun_agent_forget_transaction:
474  * @agent: The #StunAgent
475  * @id: The #StunTransactionId of the transaction to forget
476  *
477  * This function is used to make the #StunAgent forget about a previously
478  * created transaction.
479  * <para>
480  * This function should be called when a STUN request was previously
481  * created with stun_agent_finish_message() and for which no response was ever
482  * received (timed out). The #StunAgent keeps a list of the sent transactions
483  * in order to validate the responses received. If the response is never received
484  * this will allow the #StunAgent to forget about the timed out transaction and
485  * free its slot for future transactions.
486  * </para>
487  * Since: 0.0.6
488  * Returns: %TRUE if the transaction was found, %FALSE otherwise
489  */
490 bool stun_agent_forget_transaction (StunAgent *agent, StunTransactionId id);
491
492
493 /**
494  * stun_agent_set_software:
495  * @agent: The #StunAgent
496  * @software: The value of the SOFTWARE attribute to add.
497  *
498  * This function will set the value of the SOFTWARE attribute to be added to
499  * STUN requests, responses and error responses.
500  * <para>
501  * Calling this function will automatically enable the addition of the SOFTWARE
502  * attribute for RFC5389 and MSICE2 compatibility modes.
503  *
504  * </para>
505  * <note>
506      <para>
507        The @software argument must be in UTF-8 encoding and only the first
508        128 characters will be sent.
509      </para>
510      <para>
511        The value of the @software argument must stay valid throughout the life of
512        the StunAgent's life. Do not free its content.
513      </para>
514    </note>
515  *
516  * Since: 0.0.10
517  *
518  */
519 void stun_agent_set_software (StunAgent *agent, const char *software);
520
521 #endif /* _STUN_AGENT_H */