modules/ims_qos: added patch for flow-description bug when request originates from...
[sip-router] / modules / auth / nonce.h
1 /*
2  * Digest Authentication Module
3  * Nonce related functions
4  *
5  * Copyright (C) 2001-2003 FhG Fokus
6  *
7  * This file is part of Kamailio, a free SIP server.
8  *
9  * Kamailio is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version
13  *
14  * Kamailio is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22  *
23  */
24
25 #ifndef NONCE_H
26 #define NONCE_H
27
28 #include "../../parser/msg_parser.h"
29 #include "../../parser/digest/digest.h"
30 #include "../../str.h"
31 #include "../../basex.h"
32 #include <time.h>
33
34
35 /* auth_extra_checks flags */
36
37 #define AUTH_CHECK_FULL_URI (1 << 0)
38 #define AUTH_CHECK_CALLID   (1 << 1)
39 #define AUTH_CHECK_FROMTAG  (1 << 2)
40 #define AUTH_CHECK_SRC_IP   (1 << 3)
41 /* nonce format:
42  * base64(bin_nonce)
43  * bin_nonce =  expire_timestamp(4) | since_timestamp(4) | \
44  *   MD5(expire | since | secret1) (16)  \
45  *   [|   MD5(info(auth_extra_checks) | secret2) (16) ]
46  * if nonce-count or one-time nonces are enabled, the format changes to:
47  *  bin_nonce =
48  * bin_nonce =  expire_timestamp(4) | since_timestamp(4) |
49  *  MD5(expire | since | nid | pf | secret1) [ | MD5... ] | nid(4) | pf(1)
50  * where pf is 1 byte, first 2 bits are flags, and the other 6 are
51  * the pool no:
52  * bit7 : on => nid & pool are valid for nonce-count
53  * bit6 : on => nid & pool are valid for one-time nonce
54  */
55 #if defined USE_NC || defined USE_OT_NONCE
56 #define NF_VALID_NC_ID 128
57 #define NF_VALID_OT_ID  64
58
59 #define NF_POOL_NO_MASK  63
60 #endif
61
62 #if defined USE_NC || defined USE_OT_NONCE
63 #define nonce_nid_extra_size (sizeof(unsigned int)+sizeof(unsigned char))
64
65 #else /* USE_NC || USE_OT_NONCE*/
66
67 #define nonce_nid_extra_size 0
68 #endif /* USE_NC || USE_OT_NONCE */
69
70 /* nonce structure, complete (maximum size) */
71 struct bin_nonce_str{
72         int expire;
73         int since;
74         char md5_1[16];
75         char md5_2[16]; /* optional */
76 #if defined USE_NC || defined USE_OT_NONCE
77         unsigned int nid_i;
78         unsigned char nid_pf; /* pool no & flags:
79                                                         * bits 7, 6 = flags, bits 5..0 pool no*/
80 #endif /* USE_NC || USE_OT_NONCE */
81 };
82
83 /* nonce structure, small version  (no auth_extra_checks secondary md5) */
84 struct bin_nonce_small_str{
85         int expire;
86         int since;
87         char md5_1[16];
88 #if defined USE_NC || defined USE_OT_NONCE
89         unsigned int nid_i;
90         unsigned char nid_pf; /* pool no & flags:
91                                                         * bits 7, 6 = flags, bits 5..0 pool no*/
92 #endif /* USE_NC || USE_OT_NONCE */
93 };
94
95 /* nonce union */
96 union bin_nonce{
97         struct bin_nonce_str n;
98         struct bin_nonce_small_str n_small;
99         unsigned char raw[sizeof(struct bin_nonce_str)];
100 };
101
102
103 /* fill an union bin_nonce*, before computing the md5 */
104 #define BIN_NONCE_PREPARE_COMMON(bn, expire_val, since_val) \
105         do{\
106                 (bn)->n.expire=htonl(expire_val); \
107                 (bn)->n.since=htonl(since_val); \
108         }while(0)
109
110 #if defined USE_NC || defined USE_OT_NONCE
111 #define BIN_NONCE_PREPARE(bn, expire_v, since_v, id_v, pf_v, cfg, msg)  \
112         do{ \
113                 BIN_NONCE_PREPARE_COMMON(bn, expire_v, since_v); \
114                 if (cfg && msg){ \
115                         (bn)->n.nid_i=htonl(id_v); \
116                         (bn)->n.nid_pf=(pf_v); \
117                 }else{ \
118                         (bn)->n_small.nid_i=htonl(id_v); \
119                         (bn)->n_small.nid_pf=(pf_v); \
120                 } \
121         }while(0)
122 #else /* USE_NC || USE_OT_NONCE */
123 #define BIN_NONCE_PREPARE(bn, expire, since, id, pf, cfg, msg)  \
124         BIN_NONCE_PREPARE_COMMON(bn, expire, since)
125 #endif /* USE_NC || USE_OT_NONCE */
126
127
128
129 /* maximum nonce length in binary form (not converted to base64/hex):
130  * expires_t | since_t | MD5(expires_t | since_t | s1) | \
131  *   MD5(info(auth_extra_checks, s2))   => 4  + 4 + 16 + 16 = 40 bytes
132  * or if nc_enabled:
133  * expires_t | since_t | MD5...| MD5... | nonce_id | flag+pool_no(1 byte)
134  * => 4 + 4 + 16 + 16 + 4 + 1 = 45 bytes
135  * (sizeof(struct) cannot be used safely since structs can be padded
136  *  by the compiler if not defined with special attrs)
137  */
138 #if defined USE_NC || defined USE_OT_NONCE
139 #define MAX_BIN_NONCE_LEN (4 + 4 + 16 + 16 + 4 +1)
140 #define MAX_NOCFG_BIN_NONCE_LEN (4 + 4 + 16 + 4 + 1)
141
142 #define get_bin_nonce_len(cfg, nid_enabled) \
143         ( ( (cfg)?MAX_BIN_NONCE_LEN:MAX_NOCFG_BIN_NONCE_LEN ) - \
144                 (!(nid_enabled))*nonce_nid_extra_size )
145
146 #else /* USE_NC || USE_OT_NONCE */
147 #define MAX_BIN_NONCE_LEN (4 + 4 + 16 + 16)
148 #define MAX_NOCFG_BIN_NONCE_LEN (4 + 4 + 16)
149
150 #define get_bin_nonce_len(cfg, nid_enabled) \
151                 ( (cfg)?MAX_BIN_NONCE_LEN:MAX_NOCFG_BIN_NONCE_LEN )
152
153 #endif /* USE_NC || USE_OT_NONCE */
154
155 /* minimum nonce length in binary form (not converted to base64/hex):
156  * expires_t | since_t | MD5(expires_t | since_t | s1) => 4 + 4 + 16 = 24
157  * If nc_enabled the nonce will be bigger:
158  * expires_t | since_t | MD5... | nonce_id | flag+pool_no(1 byte)
159  * => 4 + 4 + 16 + 4 + 1 = 29, but we always return the minimum */
160 #define MIN_BIN_NONCE_LEN (4 + 4 + 16)
161
162
163 /*
164  * Maximum length of nonce string in bytes
165  * nonce = expires_TIMESTAMP[4 chars] since_TIMESTAMP[4 chars] \
166  * MD5SUM(expires_TIMESTAMP, since_TIMESTAMP, SECRET1)[16 chars] \
167  * MD5SUM(info(auth_extra_checks), SECRET2)[16 chars] \
168  * [nid [4 chars]  pflags[1 char]]
169  */
170 #define MAX_NONCE_LEN  base64_enc_len(MAX_BIN_NONCE_LEN)
171 /*
172  * Minimum length of the nonce string
173  * nonce = expires_TIMESTAMP[4 chars] since_TIMESTAMP[4 chars]
174  * MD5SUM(expires_TIMESTAMP, since_TIMESTAMP, SECRET1)[16 chars]
175  */
176 #define MIN_NONCE_LEN base64_enc_len(MIN_BIN_NONCE_LEN)
177
178 /*
179  * length of nonces when no auth extra checks (cfg==0) are enabled
180  */
181 #define MAX_NOCFG_NONCE_LEN base64_enc_len(MAX_NOCFG_BIN_NONCE_LEN)
182
183
184 /* Extra authentication checks for REGISTER messages */
185 extern int auth_checks_reg;
186 /* Extra authentication checks for out-of-dialog requests */
187 extern int auth_checks_ood;
188 /* Extra authentication checks for in-dialog requests */
189 extern int auth_checks_ind;
190
191 /* maximum time drift accepted for the nonce creation time
192  * (e.g. nonce generated by another proxy in the same cluster with the
193  * clock slightly in the future)
194  */
195 extern unsigned int  nonce_auth_max_drift;
196
197
198 int get_auth_checks(struct sip_msg* msg);
199
200
201 /*
202  * get the configured nonce len
203  */
204 #define get_nonce_len(cfg, nid_enabled) \
205                 base64_enc_len(get_bin_nonce_len(cfg, nid_enabled))
206
207
208 /*
209  * Calculate nonce value
210  */
211 int calc_nonce(char* nonce, int* nonce_len, int cfg, int since, int expires,
212 #if defined USE_NC || defined USE_OT_NONCE
213                                 unsigned int n_id, unsigned char pf,
214 #endif /* USE_NC || USE_OT_NONCE */
215                                 str* secret1, str* secret2, struct sip_msg* msg);
216
217
218 /*
219  * Check nonce value received from UA
220  */
221 int check_nonce(auth_body_t* auth, str* secret1, str* secret2,
222                                         struct sip_msg* msg);
223
224
225
226 #endif /* NONCE_H */