updated libtasn1
[gnutls.git] / lib / gnutls_db.c
blob9946c8e88bd91e7fa4eb05b5bb49ea8a41bc7705
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 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:
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:
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:
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:
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.
104 void
105 gnutls_db_set_ptr (gnutls_session_t session, void *ptr)
107 session->internals.db_ptr = ptr;
111 * gnutls_db_get_ptr:
112 * @session: is a #gnutls_session_t structure.
114 * Get db function pointer.
116 * Returns: the pointer that will be sent to db store, retrieve and
117 * delete functions, as the first argument.
119 void *
120 gnutls_db_get_ptr (gnutls_session_t session)
122 return session->internals.db_ptr;
126 * gnutls_db_set_cache_expiration:
127 * @session: is a #gnutls_session_t structure.
128 * @seconds: is the number of seconds.
130 * Set the expiration time for resumed sessions. The default is 3600
131 * (one hour) at the time writing this.
133 void
134 gnutls_db_set_cache_expiration (gnutls_session_t session, int seconds)
136 session->internals.expire_time = seconds;
140 * gnutls_db_check_entry:
141 * @session: is a #gnutls_session_t structure.
142 * @session_entry: is the session data (not key)
144 * Check if database entry has expired. This function is to be used
145 * when you want to clear unnesessary session which occupy space in
146 * your backend.
148 * Returns: Returns %GNUTLS_E_EXPIRED, if the database entry has
149 * expired or 0 otherwise.
152 gnutls_db_check_entry (gnutls_session_t session, gnutls_datum_t session_entry)
154 time_t timestamp;
156 timestamp = gnutls_time (0);
158 if (session_entry.data != NULL)
159 if (timestamp -
160 ((security_parameters_st *) (session_entry.data))->timestamp <=
161 session->internals.expire_time
162 || ((security_parameters_st *) (session_entry.data))->timestamp >
163 timestamp
164 || ((security_parameters_st *) (session_entry.data))->timestamp == 0)
165 return GNUTLS_E_EXPIRED;
167 return 0;
170 /* The format of storing data is:
171 * (forget it). Check gnutls_session_pack.c
174 _gnutls_server_register_current_session (gnutls_session_t session)
176 gnutls_datum_t key;
177 gnutls_datum_t content;
178 int ret = 0;
180 key.data = session->security_parameters.session_id;
181 key.size = session->security_parameters.session_id_size;
183 if (session->internals.resumable == RESUME_FALSE)
185 gnutls_assert ();
186 return GNUTLS_E_INVALID_SESSION;
189 if (session->security_parameters.session_id == NULL
190 || session->security_parameters.session_id_size == 0)
192 gnutls_assert ();
193 return GNUTLS_E_INVALID_SESSION;
196 /* copy data */
197 ret = _gnutls_session_pack (session, &content);
198 if (ret < 0)
200 gnutls_assert ();
201 return ret;
204 ret = _gnutls_store_session (session, key, content);
205 _gnutls_free_datum (&content);
207 return ret;
210 /* Checks if both db_store and db_retrieve functions have
211 * been set up.
213 static int
214 _gnutls_db_func_is_ok (gnutls_session_t session)
216 if (session->internals.db_store_func != NULL &&
217 session->internals.db_retrieve_func != NULL &&
218 session->internals.db_remove_func != NULL)
219 return 0;
220 else
221 return GNUTLS_E_DB_ERROR;
226 _gnutls_server_restore_session (gnutls_session_t session,
227 uint8_t * session_id, int session_id_size)
229 gnutls_datum_t data;
230 gnutls_datum_t key;
231 int ret;
233 key.data = session_id;
234 key.size = session_id_size;
236 if (_gnutls_db_func_is_ok (session) != 0)
238 gnutls_assert ();
239 return GNUTLS_E_INVALID_SESSION;
242 data = _gnutls_retrieve_session (session, key);
244 if (data.data == NULL)
246 gnutls_assert ();
247 return GNUTLS_E_INVALID_SESSION;
250 /* expiration check is performed inside */
251 ret = gnutls_session_set_data (session, data.data, data.size);
252 if (ret < 0)
254 gnutls_assert ();
255 return ret;
258 gnutls_free (data.data);
260 return 0;
264 _gnutls_db_remove_session (gnutls_session_t session, uint8_t * session_id,
265 int session_id_size)
267 gnutls_datum_t key;
269 key.data = session_id;
270 key.size = session_id_size;
272 return _gnutls_remove_session (session, key);
276 /* Stores session data to the db backend.
279 _gnutls_store_session (gnutls_session_t session,
280 gnutls_datum_t session_id, gnutls_datum_t session_data)
282 int ret = 0;
284 if (session->internals.resumable == RESUME_FALSE)
286 gnutls_assert ();
287 return GNUTLS_E_INVALID_SESSION;
290 if (_gnutls_db_func_is_ok (session) != 0)
292 return GNUTLS_E_DB_ERROR;
295 if (session_id.data == NULL || session_id.size == 0)
297 gnutls_assert ();
298 return GNUTLS_E_INVALID_SESSION;
301 if (session_data.data == NULL || session_data.size == 0)
303 gnutls_assert ();
304 return GNUTLS_E_INVALID_SESSION;
306 /* if we can't read why bother writing? */
308 if (session->internals.db_store_func != NULL)
309 ret =
310 session->internals.db_store_func (session->internals.db_ptr,
311 session_id, session_data);
313 return (ret == 0 ? ret : GNUTLS_E_DB_ERROR);
317 /* Retrieves session data from the db backend.
319 gnutls_datum_t
320 _gnutls_retrieve_session (gnutls_session_t session, gnutls_datum_t session_id)
322 gnutls_datum_t ret = { NULL, 0 };
324 if (session_id.data == NULL || session_id.size == 0)
326 gnutls_assert ();
327 return ret;
330 if (session->internals.db_retrieve_func != NULL)
331 ret =
332 session->internals.db_retrieve_func (session->internals.db_ptr,
333 session_id);
335 return ret;
339 /* Removes session data from the db backend.
342 _gnutls_remove_session (gnutls_session_t session, gnutls_datum_t session_id)
344 int ret = 0;
346 if (_gnutls_db_func_is_ok (session) != 0)
348 return GNUTLS_E_DB_ERROR;
351 if (session_id.data == NULL || session_id.size == 0)
352 return GNUTLS_E_INVALID_SESSION;
354 /* if we can't read why bother writing? */
355 if (session->internals.db_remove_func != NULL)
356 ret =
357 session->internals.db_remove_func (session->internals.db_ptr,
358 session_id);
360 return (ret == 0 ? ret : GNUTLS_E_DB_ERROR);
365 * gnutls_db_remove_session:
366 * @session: is a #gnutls_session_t structure.
368 * This function will remove the current session data from the
369 * session database. This will prevent future handshakes reusing
370 * these session data. This function should be called if a session
371 * was terminated abnormally, and before gnutls_deinit() is called.
373 * Normally gnutls_deinit() will remove abnormally terminated
374 * sessions.
376 void
377 gnutls_db_remove_session (gnutls_session_t session)
379 _gnutls_db_remove_session (session,
380 session->security_parameters.session_id,
381 session->security_parameters.session_id_size);