stun_auth.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. /*
  2. * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
  3. * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. */
  19. #ifndef __PJNATH_STUN_AUTH_H__
  20. #define __PJNATH_STUN_AUTH_H__
  21. /**
  22. * @file stun_auth.h
  23. * @brief STUN authentication.
  24. */
  25. #include <pjnath/stun_msg.h>
  26. PJ_BEGIN_DECL
  27. /* **************************************************************************/
  28. /**
  29. * @defgroup PJNATH_STUN_AUTH STUN Authentication
  30. * @brief STUN authentication helper
  31. * @ingroup PJNATH_STUN_BASE
  32. * @{
  33. */
  34. /**
  35. * Type of authentication.
  36. */
  37. typedef enum pj_stun_auth_type
  38. {
  39. /**
  40. * No authentication.
  41. */
  42. PJ_STUN_AUTH_NONE = 0,
  43. /**
  44. * Authentication using short term credential.
  45. */
  46. PJ_STUN_AUTH_SHORT_TERM = 1,
  47. /**
  48. * Authentication using long term credential.
  49. */
  50. PJ_STUN_AUTH_LONG_TERM = 2
  51. } pj_stun_auth_type;
  52. /**
  53. * Type of authentication data in the credential.
  54. */
  55. typedef enum pj_stun_auth_cred_type
  56. {
  57. /**
  58. * The credential data contains a static credential to be matched
  59. * against the credential in the message. A static credential can be
  60. * used as both client side or server side authentication.
  61. */
  62. PJ_STUN_AUTH_CRED_STATIC,
  63. /**
  64. * The credential data contains callbacks to be called to verify the
  65. * credential in the message. A dynamic credential is suitable when
  66. * performing server side authentication where server does not know
  67. * in advance the identity of the user requesting authentication.
  68. */
  69. PJ_STUN_AUTH_CRED_DYNAMIC
  70. } pj_stun_auth_cred_type;
  71. /**
  72. * Type of encoding applied to the password stored in the credential.
  73. */
  74. typedef enum pj_stun_passwd_type
  75. {
  76. /**
  77. * Plain text password.
  78. */
  79. PJ_STUN_PASSWD_PLAIN = 0,
  80. /**
  81. * Hashed password, valid for long term credential only. The hash value
  82. * of the password is calculated as MD5(USERNAME ":" REALM ":" PASSWD)
  83. * with all quotes removed from the username and realm values.
  84. */
  85. PJ_STUN_PASSWD_HASHED = 1
  86. } pj_stun_passwd_type;
  87. /**
  88. * This structure contains the descriptions needed to perform server side
  89. * authentication. Depending on the \a type set in the structure, application
  90. * may specify a static username/password combination, or to have callbacks
  91. * called by the function to authenticate the credential dynamically.
  92. */
  93. typedef struct pj_stun_auth_cred
  94. {
  95. /**
  96. * The type of authentication information in this structure.
  97. */
  98. pj_stun_auth_cred_type type;
  99. /**
  100. * This union contains the authentication data.
  101. */
  102. union
  103. {
  104. /**
  105. * This structure contains static data for performing authentication.
  106. * A non-empty realm indicates whether short term or long term
  107. * credential is used.
  108. */
  109. struct
  110. {
  111. /**
  112. * If not-empty, it indicates that this is a long term credential.
  113. */
  114. pj_str_t realm;
  115. /**
  116. * The username of the credential.
  117. */
  118. pj_str_t username;
  119. /**
  120. * Data type to indicate the type of password in the \a data field.
  121. */
  122. pj_stun_passwd_type data_type;
  123. /**
  124. * The data, which depends depends on the value of \a data_type
  125. * field. When \a data_type is zero, this field will contain the
  126. * plaintext password.
  127. */
  128. pj_str_t data;
  129. /**
  130. * Optional NONCE.
  131. */
  132. pj_str_t nonce;
  133. } static_cred;
  134. /**
  135. * This structure contains callback to be called by the framework
  136. * to authenticate the incoming message.
  137. */
  138. struct
  139. {
  140. /**
  141. * User data which will be passed back to callback functions.
  142. */
  143. void *user_data;
  144. /**
  145. * This callback is called by pj_stun_verify_credential() when
  146. * server needs to challenge the request with 401 response.
  147. *
  148. * @param user_data The user data as specified in the credential.
  149. * @param pool Pool to allocate memory.
  150. * @param realm On return, the function should fill in with
  151. * realm if application wants to use long term
  152. * credential. Otherwise application should set
  153. * empty string for the realm.
  154. * @param nonce On return, if application wants to use long
  155. * term credential, it MUST fill in the nonce
  156. * with some value. Otherwise if short term
  157. * credential is wanted, it MAY set this value.
  158. * If short term credential is wanted and the
  159. * application doesn't want to include NONCE,
  160. * then it must set this to empty string.
  161. *
  162. * @return The callback should return PJ_SUCCESS, or
  163. * otherwise response message will not be
  164. * created.
  165. */
  166. pj_status_t (*get_auth)(void *user_data,
  167. pj_pool_t *pool,
  168. pj_str_t *realm,
  169. pj_str_t *nonce);
  170. /**
  171. * Get the credential to be put in outgoing request.
  172. *
  173. * @param msg The outgoing message where the credential is
  174. * to be applied.
  175. * @param user_data The user data as specified in the credential.
  176. * @param pool Pool where the callback can allocate memory
  177. * to fill in the credential.
  178. * @param realm On return, the callback may specify the realm
  179. * if long term credential is desired, otherwise
  180. * this string must be set to empty.
  181. * @param username On return, the callback must fill in with the
  182. * username.
  183. * @param nonce On return, the callback may optionally fill in
  184. * this argument with NONCE value if desired,
  185. * otherwise this argument must be set to empty.
  186. * @param data_type On return, the callback must set this argument
  187. * with the type of password in the data argument.
  188. * @param data On return, the callback must set this with
  189. * the password, encoded according to data_type
  190. * argument.
  191. *
  192. * @return The callback must return PJ_SUCCESS, otherwise
  193. * the message transmission will be cancelled.
  194. */
  195. pj_status_t (*get_cred)(const pj_stun_msg *msg,
  196. void *user_data,
  197. pj_pool_t *pool,
  198. pj_str_t *realm,
  199. pj_str_t *username,
  200. pj_str_t *nonce,
  201. pj_stun_passwd_type *data_type,
  202. pj_str_t *data);
  203. /**
  204. * Get the password for the specified username. This function
  205. * is also used to check whether the username is valid.
  206. *
  207. * @param msg The STUN message where the password will be
  208. * applied to.
  209. * @param user_data The user data as specified in the credential.
  210. * @param realm The realm as specified in the message.
  211. * @param username The username as specified in the message.
  212. * @param pool Pool to allocate memory when necessary.
  213. * @param data_type On return, application should fill up this
  214. * argument with the type of data (which should
  215. * be zero if data is a plaintext password).
  216. * @param data On return, application should fill up this
  217. * argument with the password according to
  218. * data_type.
  219. *
  220. * @return The callback should return PJ_SUCCESS if
  221. * username has been successfully verified
  222. * and password was obtained. If non-PJ_SUCCESS
  223. * is returned, it is assumed that the
  224. * username is not valid.
  225. */
  226. pj_status_t (*get_password)(const pj_stun_msg *msg,
  227. void *user_data,
  228. const pj_str_t *realm,
  229. const pj_str_t *username,
  230. pj_pool_t *pool,
  231. pj_stun_passwd_type *data_type,
  232. pj_str_t *data);
  233. /**
  234. * This callback will be called to verify that the NONCE given
  235. * in the message can be accepted. If this callback returns
  236. * PJ_FALSE, 438 (Stale Nonce) response will be created.
  237. *
  238. * This callback is optional.
  239. *
  240. * @param msg The STUN message where the nonce was received.
  241. * @param user_data The user data as specified in the credential.
  242. * @param realm The realm as specified in the message.
  243. * @param username The username as specified in the message.
  244. * @param nonce The nonce to be verified.
  245. *
  246. * @return The callback MUST return non-zero if the
  247. * NONCE can be accepted.
  248. */
  249. pj_bool_t (*verify_nonce)(const pj_stun_msg *msg,
  250. void *user_data,
  251. const pj_str_t *realm,
  252. const pj_str_t *username,
  253. const pj_str_t *nonce);
  254. } dyn_cred;
  255. } data;
  256. } pj_stun_auth_cred;
  257. /**
  258. * This structure contains the credential information that is found and
  259. * used to authenticate incoming requests. Application may use this
  260. * information when generating authentication for the outgoing response.
  261. */
  262. typedef struct pj_stun_req_cred_info
  263. {
  264. /**
  265. * The REALM value found in the incoming request. If short term
  266. * credential is used, the value will be empty.
  267. */
  268. pj_str_t realm;
  269. /**
  270. * The USERNAME value found in the incoming request.
  271. */
  272. pj_str_t username;
  273. /**
  274. * Optional NONCE.
  275. */
  276. pj_str_t nonce;
  277. /**
  278. * Authentication key that was used to authenticate the incoming
  279. * request. This key is created with #pj_stun_create_key(), and
  280. * it can be used to encode the credential of the outgoing
  281. * response.
  282. */
  283. pj_str_t auth_key;
  284. } pj_stun_req_cred_info;
  285. /**
  286. * Duplicate authentication credential.
  287. *
  288. * @param pool Pool to be used to allocate memory.
  289. * @param dst Destination credential.
  290. * @param src Source credential.
  291. */
  292. PJ_DECL(void) pj_stun_auth_cred_dup(pj_pool_t *pool,
  293. pj_stun_auth_cred *dst,
  294. const pj_stun_auth_cred *src);
  295. /**
  296. * Duplicate request credential.
  297. *
  298. * @param pool Pool to be used to allocate memory.
  299. * @param dst Destination credential.
  300. * @param src Source credential.
  301. */
  302. PJ_DECL(void) pj_stun_req_cred_info_dup(pj_pool_t *pool,
  303. pj_stun_req_cred_info *dst,
  304. const pj_stun_req_cred_info *src);
  305. /**
  306. * Create authentication key to be used for encoding the message with
  307. * MESSAGE-INTEGRITY. If short term credential is used (i.e. the realm
  308. * argument is NULL or empty), the key will be copied from the password.
  309. * If long term credential is used, the key will be calculated from the
  310. * MD5 hash of the realm, username, and password.
  311. *
  312. * @param pool Pool to allocate memory for the key.
  313. * @param key String to receive the key.
  314. * @param realm The realm of the credential, if long term credential
  315. * is to be used. If short term credential is wanted,
  316. * application can put NULL or empty string here.
  317. * @param username The username.
  318. * @param data_type Password encoding.
  319. * @param data The password.
  320. */
  321. PJ_DECL(void) pj_stun_create_key(pj_pool_t *pool,
  322. pj_str_t *key,
  323. const pj_str_t *realm,
  324. const pj_str_t *username,
  325. pj_stun_passwd_type data_type,
  326. const pj_str_t *data);
  327. /**
  328. * Verify credential in the STUN request. Note that before calling this
  329. * function, application must have checked that the message contains
  330. * PJ_STUN_ATTR_MESSAGE_INTEGRITY attribute by calling pj_stun_msg_find_attr()
  331. * function, because this function will reject the message with 401 error
  332. * if it doesn't contain PJ_STUN_ATTR_MESSAGE_INTEGRITY attribute.
  333. *
  334. * @param pkt The original packet which has been parsed into
  335. * the message. This packet MUST NOT have been modified
  336. * after the parsing.
  337. * @param pkt_len The length of the packet.
  338. * @param msg The parsed message to be verified.
  339. * @param cred Pointer to credential to be used to authenticate
  340. * the message.
  341. * @param pool If response is to be created, then memory will
  342. * be allocated from this pool.
  343. * @param info Optional pointer to receive authentication information
  344. * found in the request and the credential that is used
  345. * to authenticate the request.
  346. * @param p_response Optional pointer to receive the response message
  347. * then the credential in the request fails to
  348. * authenticate.
  349. *
  350. * @return PJ_SUCCESS if credential is verified successfully.
  351. * If the verification fails and \a p_response is not
  352. * NULL, an appropriate response will be returned in
  353. * \a p_response.
  354. */
  355. PJ_DECL(pj_status_t) pj_stun_authenticate_request(const pj_uint8_t *pkt,
  356. unsigned pkt_len,
  357. const pj_stun_msg *msg,
  358. pj_stun_auth_cred *cred,
  359. pj_pool_t *pool,
  360. pj_stun_req_cred_info *info,
  361. pj_stun_msg **p_response);
  362. /**
  363. * Determine if STUN message can be authenticated. Some STUN error
  364. * responses cannot be authenticated since they cannot contain STUN
  365. * MESSAGE-INTEGRITY attribute. STUN Indication messages also cannot
  366. * be authenticated.
  367. *
  368. * @param msg The STUN message.
  369. *
  370. * @return Non-zero if the STUN message can be authenticated.
  371. */
  372. PJ_DECL(pj_bool_t) pj_stun_auth_valid_for_msg(const pj_stun_msg *msg);
  373. /**
  374. * Verify credential in the STUN response. Note that before calling this
  375. * function, application must have checked that the message contains
  376. * PJ_STUN_ATTR_MESSAGE_INTEGRITY attribute by calling pj_stun_msg_find_attr()
  377. * function, because otherwise this function will report authentication
  378. * failure.
  379. *
  380. * @param pkt The original packet which has been parsed into
  381. * the message. This packet MUST NOT have been modified
  382. * after the parsing.
  383. * @param pkt_len The length of the packet.
  384. * @param msg The parsed message to be verified.
  385. * @param key Authentication key to calculate MESSAGE-INTEGRITY
  386. * value. Application can create this key by using
  387. * #pj_stun_create_key() function.
  388. *
  389. * @return PJ_SUCCESS if credential is verified successfully.
  390. */
  391. PJ_DECL(pj_status_t) pj_stun_authenticate_response(const pj_uint8_t *pkt,
  392. unsigned pkt_len,
  393. const pj_stun_msg *msg,
  394. const pj_str_t *key);
  395. /**
  396. * @}
  397. */
  398. PJ_END_DECL
  399. #endif /* __PJNATH_STUN_AUTH_H__ */