2 * Copyright (C) 2000, 2002, 2003, 2004, 2005, 2008 Free Software Foundation
4 * Author: Nikos Mavrogiannopoulos
6 * This file is part of GNUTLS.
8 * The GNUTLS library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
25 /* This file contains functions that manipulate a database backend for
29 #include "gnutls_int.h"
30 #include "gnutls_errors.h"
31 #include <gnutls_db.h>
33 #include <gnutls_session_pack.h>
34 #include <gnutls_datum.h>
37 * gnutls_db_set_retrieve_function - Set the function that will be used to get data
38 * @session: is a #gnutls_session_t structure.
39 * @retr_func: is the function.
41 * Sets the function that will be used to retrieve data from the
42 * resumed sessions database. This function must return a
43 * gnutls_datum_t containing the data on success, or a gnutls_datum_t
44 * containing null and 0 on failure.
46 * The datum's data must be allocated using the function
49 * The first argument to retr_func() will be null unless
50 * gnutls_db_set_ptr() has been called.
53 gnutls_db_set_retrieve_function (gnutls_session_t session
,
54 gnutls_db_retr_func retr_func
)
56 session
->internals
.db_retrieve_func
= retr_func
;
60 * gnutls_db_set_remove_function - Set the function that will be used to remove data
61 * @session: is a #gnutls_session_t structure.
62 * @rem_func: is the function.
64 * Sets the function that will be used to remove data from the
65 * resumed sessions database. This function must return 0 on success.
67 * The first argument to rem_func() will be null unless
68 * gnutls_db_set_ptr() has been called.
71 gnutls_db_set_remove_function (gnutls_session_t session
,
72 gnutls_db_remove_func rem_func
)
74 session
->internals
.db_remove_func
= rem_func
;
78 * gnutls_db_set_store_function - Set the function that will be used to put data
79 * @session: is a #gnutls_session_t structure.
80 * @store_func: is the function
82 * Sets the function that will be used to store data from the resumed
83 * sessions database. This function must remove 0 on success.
85 * The first argument to store_func() will be null unless
86 * gnutls_db_set_ptr() has been called.
89 gnutls_db_set_store_function (gnutls_session_t session
,
90 gnutls_db_store_func store_func
)
92 session
->internals
.db_store_func
= store_func
;
96 * gnutls_db_set_ptr - Set a pointer to be sent to db functions
97 * @session: is a #gnutls_session_t structure.
98 * @ptr: is the pointer
100 * Sets the pointer that will be provided to db store, retrieve and
101 * delete functions, as the first argument.
105 gnutls_db_set_ptr (gnutls_session_t session
, void *ptr
)
107 session
->internals
.db_ptr
= ptr
;
111 * gnutls_db_get_ptr - Returns the pointer which is sent to db functions
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.
120 gnutls_db_get_ptr (gnutls_session_t session
)
122 return session
->internals
.db_ptr
;
126 * gnutls_db_set_cache_expiration - Set the expiration time for resumed sessions.
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.
134 gnutls_db_set_cache_expiration (gnutls_session_t session
, int seconds
)
136 session
->internals
.expire_time
= seconds
;
140 * gnutls_db_check_entry - check if the given db entry has expired
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
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
)
156 timestamp
= time (0);
158 if (session_entry
.data
!= NULL
)
160 ((security_parameters_st
*) (session_entry
.data
))->timestamp
<=
161 session
->internals
.expire_time
162 || ((security_parameters_st
*) (session_entry
.data
))->
163 timestamp
> timestamp
164 || ((security_parameters_st
*) (session_entry
.data
))->timestamp
== 0)
165 return GNUTLS_E_EXPIRED
;
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
)
177 gnutls_datum_t content
;
180 key
.data
= session
->security_parameters
.session_id
;
181 key
.size
= session
->security_parameters
.session_id_size
;
183 if (session
->internals
.resumable
== RESUME_FALSE
)
186 return GNUTLS_E_INVALID_SESSION
;
189 if (session
->security_parameters
.session_id
== NULL
190 || session
->security_parameters
.session_id_size
== 0)
193 return GNUTLS_E_INVALID_SESSION
;
197 ret
= _gnutls_session_pack (session
, &content
);
204 ret
= _gnutls_store_session (session
, key
, content
);
205 _gnutls_free_datum (&content
);
210 /* Checks if both db_store and db_retrieve functions have
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
)
221 return GNUTLS_E_DB_ERROR
;
226 _gnutls_server_restore_session (gnutls_session_t session
,
227 uint8_t * session_id
, int session_id_size
)
233 key
.data
= session_id
;
234 key
.size
= session_id_size
;
236 if (_gnutls_db_func_is_ok (session
) != 0)
239 return GNUTLS_E_INVALID_SESSION
;
242 data
= _gnutls_retrieve_session (session
, key
);
244 if (data
.data
== NULL
)
247 return GNUTLS_E_INVALID_SESSION
;
250 /* expiration check is performed inside */
251 ret
= gnutls_session_set_data (session
, data
.data
, data
.size
);
258 gnutls_free (data
.data
);
264 _gnutls_db_remove_session (gnutls_session_t session
, uint8_t * session_id
,
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
)
284 if (session
->internals
.resumable
== RESUME_FALSE
)
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)
298 return GNUTLS_E_INVALID_SESSION
;
301 if (session_data
.data
== NULL
|| session_data
.size
== 0)
304 return GNUTLS_E_INVALID_SESSION
;
306 /* if we can't read why bother writing? */
308 if (session
->internals
.db_store_func
!= NULL
)
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.
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)
330 if (session
->internals
.db_retrieve_func
!= NULL
)
332 session
->internals
.db_retrieve_func (session
->internals
.db_ptr
,
339 /* Removes session data from the db backend.
342 _gnutls_remove_session (gnutls_session_t session
, gnutls_datum_t session_id
)
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
)
357 session
->internals
.db_remove_func (session
->internals
.db_ptr
,
360 return (ret
== 0 ? ret
: GNUTLS_E_DB_ERROR
);
365 * gnutls_db_remove_session - remove the current session data from the database
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
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
);