Sync with TP.
[gnutls.git] / lib / gnutls_db.c
blobe136eaa19d30bb5093b80d79683da46f6849fc6f
1 /*
2 * Copyright (C) 2000, 2002, 2003, 2004, 2005, 2008, 2010 Free Software
3 * Foundation, Inc.
5 * Author: Nikos Mavrogiannopoulos
7 * This file is part of GNUTLS.
9 * The GNUTLS library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * as published by the Free Software Foundation; either version 2.1 of
12 * the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22 * USA
26 /* This file contains functions that manipulate a database backend for
27 * resumed sessions.
30 #include "gnutls_int.h"
31 #include "gnutls_errors.h"
32 #include <gnutls_db.h>
33 #include "debug.h"
34 #include <gnutls_session_pack.h>
35 #include <gnutls_datum.h>
37 /**
38 * gnutls_db_set_retrieve_function - Set the function that will be used to get data
39 * @session: is a #gnutls_session_t structure.
40 * @retr_func: is the function.
42 * Sets the function that will be used to retrieve data from the
43 * resumed sessions database. This function must return a
44 * gnutls_datum_t containing the data on success, or a gnutls_datum_t
45 * containing null and 0 on failure.
47 * The datum's data must be allocated using the function
48 * gnutls_malloc().
50 * The first argument to retr_func() will be null unless
51 * gnutls_db_set_ptr() has been called.
52 **/
53 void
54 gnutls_db_set_retrieve_function (gnutls_session_t session,
55 gnutls_db_retr_func retr_func)
57 session->internals.db_retrieve_func = retr_func;
60 /**
61 * gnutls_db_set_remove_function - Set the function that will be used to remove data
62 * @session: is a #gnutls_session_t structure.
63 * @rem_func: is the function.
65 * Sets the function that will be used to remove data from the
66 * resumed sessions database. This function must return 0 on success.
68 * The first argument to rem_func() will be null unless
69 * gnutls_db_set_ptr() has been called.
70 **/
71 void
72 gnutls_db_set_remove_function (gnutls_session_t session,
73 gnutls_db_remove_func rem_func)
75 session->internals.db_remove_func = rem_func;
78 /**
79 * gnutls_db_set_store_function - Set the function that will be used to put data
80 * @session: is a #gnutls_session_t structure.
81 * @store_func: is the function
83 * Sets the function that will be used to store data from the resumed
84 * sessions database. This function must remove 0 on success.
86 * The first argument to store_func() will be null unless
87 * gnutls_db_set_ptr() has been called.
88 **/
89 void
90 gnutls_db_set_store_function (gnutls_session_t session,
91 gnutls_db_store_func store_func)
93 session->internals.db_store_func = store_func;
96 /**
97 * gnutls_db_set_ptr - Set a pointer to be sent to db functions
98 * @session: is a #gnutls_session_t structure.
99 * @ptr: is the pointer
101 * Sets the pointer that will be provided to db store, retrieve and
102 * delete functions, as the first argument.
105 void
106 gnutls_db_set_ptr (gnutls_session_t session, void *ptr)
108 session->internals.db_ptr = ptr;
112 * gnutls_db_get_ptr - Returns the pointer which is sent to db functions
113 * @session: is a #gnutls_session_t structure.
115 * Get db function pointer.
117 * Returns: the pointer that will be sent to db store, retrieve and
118 * delete functions, as the first argument.
120 void *
121 gnutls_db_get_ptr (gnutls_session_t session)
123 return session->internals.db_ptr;
127 * gnutls_db_set_cache_expiration - Set the expiration time for resumed sessions.
128 * @session: is a #gnutls_session_t structure.
129 * @seconds: is the number of seconds.
131 * Set the expiration time for resumed sessions. The default is 3600
132 * (one hour) at the time writing this.
134 void
135 gnutls_db_set_cache_expiration (gnutls_session_t session, int seconds)
137 session->internals.expire_time = seconds;
141 * gnutls_db_check_entry - check if the given db entry has expired
142 * @session: is a #gnutls_session_t structure.
143 * @session_entry: is the session data (not key)
145 * Check if database entry has expired. This function is to be used
146 * when you want to clear unnesessary session which occupy space in
147 * your backend.
149 * Returns: Returns %GNUTLS_E_EXPIRED, if the database entry has
150 * expired or 0 otherwise.
153 gnutls_db_check_entry (gnutls_session_t session, gnutls_datum_t session_entry)
155 time_t timestamp;
157 timestamp = time (0);
159 if (session_entry.data != NULL)
160 if (timestamp -
161 ((security_parameters_st *) (session_entry.data))->timestamp <=
162 session->internals.expire_time
163 || ((security_parameters_st *) (session_entry.data))->timestamp >
164 timestamp
165 || ((security_parameters_st *) (session_entry.data))->timestamp == 0)
166 return GNUTLS_E_EXPIRED;
168 return 0;
171 /* The format of storing data is:
172 * (forget it). Check gnutls_session_pack.c
175 _gnutls_server_register_current_session (gnutls_session_t session)
177 gnutls_datum_t key;
178 gnutls_datum_t content;
179 int ret = 0;
181 key.data = session->security_parameters.session_id;
182 key.size = session->security_parameters.session_id_size;
184 if (session->internals.resumable == RESUME_FALSE)
186 gnutls_assert ();
187 return GNUTLS_E_INVALID_SESSION;
190 if (session->security_parameters.session_id == NULL
191 || session->security_parameters.session_id_size == 0)
193 gnutls_assert ();
194 return GNUTLS_E_INVALID_SESSION;
197 /* copy data */
198 ret = _gnutls_session_pack (session, &content);
199 if (ret < 0)
201 gnutls_assert ();
202 return ret;
205 ret = _gnutls_store_session (session, key, content);
206 _gnutls_free_datum (&content);
208 return ret;
211 /* Checks if both db_store and db_retrieve functions have
212 * been set up.
214 static int
215 _gnutls_db_func_is_ok (gnutls_session_t session)
217 if (session->internals.db_store_func != NULL &&
218 session->internals.db_retrieve_func != NULL &&
219 session->internals.db_remove_func != NULL)
220 return 0;
221 else
222 return GNUTLS_E_DB_ERROR;
227 _gnutls_server_restore_session (gnutls_session_t session,
228 uint8_t * session_id, int session_id_size)
230 gnutls_datum_t data;
231 gnutls_datum_t key;
232 int ret;
234 key.data = session_id;
235 key.size = session_id_size;
237 if (_gnutls_db_func_is_ok (session) != 0)
239 gnutls_assert ();
240 return GNUTLS_E_INVALID_SESSION;
243 data = _gnutls_retrieve_session (session, key);
245 if (data.data == NULL)
247 gnutls_assert ();
248 return GNUTLS_E_INVALID_SESSION;
251 /* expiration check is performed inside */
252 ret = gnutls_session_set_data (session, data.data, data.size);
253 if (ret < 0)
255 gnutls_assert ();
256 return ret;
259 gnutls_free (data.data);
261 return 0;
265 _gnutls_db_remove_session (gnutls_session_t session, uint8_t * session_id,
266 int session_id_size)
268 gnutls_datum_t key;
270 key.data = session_id;
271 key.size = session_id_size;
273 return _gnutls_remove_session (session, key);
277 /* Stores session data to the db backend.
280 _gnutls_store_session (gnutls_session_t session,
281 gnutls_datum_t session_id, gnutls_datum_t session_data)
283 int ret = 0;
285 if (session->internals.resumable == RESUME_FALSE)
287 gnutls_assert ();
288 return GNUTLS_E_INVALID_SESSION;
291 if (_gnutls_db_func_is_ok (session) != 0)
293 return GNUTLS_E_DB_ERROR;
296 if (session_id.data == NULL || session_id.size == 0)
298 gnutls_assert ();
299 return GNUTLS_E_INVALID_SESSION;
302 if (session_data.data == NULL || session_data.size == 0)
304 gnutls_assert ();
305 return GNUTLS_E_INVALID_SESSION;
307 /* if we can't read why bother writing? */
309 if (session->internals.db_store_func != NULL)
310 ret =
311 session->internals.db_store_func (session->internals.db_ptr,
312 session_id, session_data);
314 return (ret == 0 ? ret : GNUTLS_E_DB_ERROR);
318 /* Retrieves session data from the db backend.
320 gnutls_datum_t
321 _gnutls_retrieve_session (gnutls_session_t session, gnutls_datum_t session_id)
323 gnutls_datum_t ret = { NULL, 0 };
325 if (session_id.data == NULL || session_id.size == 0)
327 gnutls_assert ();
328 return ret;
331 if (session->internals.db_retrieve_func != NULL)
332 ret =
333 session->internals.db_retrieve_func (session->internals.db_ptr,
334 session_id);
336 return ret;
340 /* Removes session data from the db backend.
343 _gnutls_remove_session (gnutls_session_t session, gnutls_datum_t session_id)
345 int ret = 0;
347 if (_gnutls_db_func_is_ok (session) != 0)
349 return GNUTLS_E_DB_ERROR;
352 if (session_id.data == NULL || session_id.size == 0)
353 return GNUTLS_E_INVALID_SESSION;
355 /* if we can't read why bother writing? */
356 if (session->internals.db_remove_func != NULL)
357 ret =
358 session->internals.db_remove_func (session->internals.db_ptr,
359 session_id);
361 return (ret == 0 ? ret : GNUTLS_E_DB_ERROR);
366 * gnutls_db_remove_session - remove the current session data from the database
367 * @session: is a #gnutls_session_t structure.
369 * This function will remove the current session data from the
370 * session database. This will prevent future handshakes reusing
371 * these session data. This function should be called if a session
372 * was terminated abnormally, and before gnutls_deinit() is called.
374 * Normally gnutls_deinit() will remove abnormally terminated
375 * sessions.
377 void
378 gnutls_db_remove_session (gnutls_session_t session)
380 _gnutls_db_remove_session (session,
381 session->security_parameters.session_id,
382 session->security_parameters.session_id_size);