* replaced __thread with pthread_key_t/pthread_setspecific
[strongswan.git] / src / manager / database.c
1 /**
2 * @file database.c
3 *
4 * @brief Implementation of database_t.
5 *
6 */
7
8 /*
9 * Copyright (C) 2007 Martin Willi
10 * Hochschule fuer Technik Rapperswil
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
21 */
22
23 #include "database.h"
24
25 #include <sqlite3.h>
26 #include <library.h>
27 #include <crypto/hashers/hasher.h>
28
29
30 typedef struct private_database_t private_database_t;
31
32 /**
33 * private data of database
34 */
35 struct private_database_t {
36
37 /**
38 * public functions
39 */
40 database_t public;
41
42 /**
43 * SQLite database handle
44 */
45 sqlite3 *db;
46 };
47
48 /**
49 * database enumerator implements enumerator_t
50 */
51 typedef struct {
52 enumerator_t enumerator;
53 sqlite3_stmt *stmt;
54 } db_enumerator_t;
55
56 /**
57 * destroy a database enumerator
58 */
59 static void db_enumerator_destroy(db_enumerator_t* this)
60 {
61 sqlite3_finalize(this->stmt);
62 free(this);
63 }
64
65 /**
66 * create a database enumerator
67 */
68 static enumerator_t *db_enumerator_create(bool(*enumerate)(db_enumerator_t*,void*,...),
69 sqlite3_stmt *stmt)
70 {
71 db_enumerator_t *this = malloc_thing(db_enumerator_t);
72 this->enumerator.enumerate = (void*)enumerate;
73 this->enumerator.destroy = (void*)db_enumerator_destroy;
74 this->stmt = stmt;
75 return &this->enumerator;
76 }
77
78 /**
79 * Implementation of database_t.login.
80 */
81 static int login(private_database_t *this, char *username, char *password)
82 {
83 sqlite3_stmt *stmt;
84 hasher_t *hasher;
85 chunk_t hash, data;
86 size_t username_len, password_len;
87 int uid = 0;
88 char *str;
89
90 /* hash = SHA1( username | password ) */
91 hasher = hasher_create(HASH_SHA1);
92 hash = chunk_alloca(hasher->get_hash_size(hasher));
93 username_len = strlen(username);
94 password_len = strlen(password);
95 data = chunk_alloca(username_len + password_len);
96 memcpy(data.ptr, username, username_len);
97 memcpy(data.ptr + username_len, password, password_len);
98 hasher->get_hash(hasher, data, hash.ptr);
99 hasher->destroy(hasher);
100 str = chunk_to_hex(hash, FALSE);
101
102 if (sqlite3_prepare_v2(this->db,
103 "SELECT oid FROM users WHERE username = ? AND password = ?;",
104 -1, &stmt, NULL) == SQLITE_OK)
105 {
106 if (sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC) == SQLITE_OK &&
107 sqlite3_bind_text(stmt, 2, str, -1, SQLITE_STATIC) == SQLITE_OK &&
108 sqlite3_step(stmt) == SQLITE_ROW)
109 {
110 uid = sqlite3_column_int(stmt, 0);
111 }
112 sqlite3_finalize(stmt);
113 }
114 free(str);
115 return uid;
116 }
117
118 /**
119 * enumerate function for gateway enumrator
120 */
121 static bool gateway_enumerate(db_enumerator_t* e, int *id, const char **name,
122 int *port, const char **address)
123 {
124 if (sqlite3_step(e->stmt) == SQLITE_ROW)
125 {
126 *id = sqlite3_column_int(e->stmt, 0);
127 *name = sqlite3_column_text(e->stmt, 1);
128 *port = sqlite3_column_int(e->stmt, 2);
129 *address = sqlite3_column_text(e->stmt, 3);
130 return TRUE;
131 }
132 return FALSE;
133 }
134
135 /**
136 * Implementation of database_t.create_gateway_enumerator.
137 */
138 static enumerator_t* create_gateway_enumerator(private_database_t *this, int user)
139 {
140 sqlite3_stmt *stmt;
141
142 if (sqlite3_prepare_v2(this->db,
143 "SELECT gateways.oid AS gid, name, port, address FROM "
144 "gateways, user_gateway AS ug ON gid = ug.gateway WHERE ug.user = ?;",
145 -1, &stmt, NULL) == SQLITE_OK)
146 {
147 if (sqlite3_bind_int(stmt, 1, user) == SQLITE_OK)
148 {
149 return db_enumerator_create((void*)gateway_enumerate, stmt);
150 }
151 sqlite3_finalize(stmt);
152 }
153 return enumerator_create_empty();
154 }
155
156 /**
157 * Implementation of database_t.destroy
158 */
159 static void destroy(private_database_t *this)
160 {
161 sqlite3_close(this->db);
162 free(this);
163 }
164
165 /*
166 * see header file
167 */
168 database_t *database_create(char *dbfile)
169 {
170 private_database_t *this = malloc_thing(private_database_t);
171
172 this->public.login = (int(*)(database_t*, char *username, char *password))login;
173 this->public.create_gateway_enumerator = (enumerator_t*(*)(database_t*,int))create_gateway_enumerator;
174 this->public.destroy = (void(*)(database_t*))destroy;
175
176 if (sqlite3_open(dbfile, &this->db) != SQLITE_OK)
177 {
178 destroy(this);
179 return NULL;
180 }
181 return &this->public;
182 }
183