handle zero size Base64 conversions
[strongswan.git] / src / manager / storage.c
1 /*
2 * Copyright (C) 2007 Martin Willi
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #include "storage.h"
17
18 #include <library.h>
19 #include <crypto/hashers/hasher.h>
20
21
22 typedef struct private_storage_t private_storage_t;
23
24 /**
25 * private data of storage
26 */
27 struct private_storage_t {
28
29 /**
30 * public functions
31 */
32 storage_t public;
33
34 /**
35 * database connection
36 */
37 database_t *db;
38 };
39
40 /**
41 * Implementation of storage_t.login.
42 */
43 static int login(private_storage_t *this, char *username, char *password)
44 {
45 hasher_t *hasher;
46 chunk_t hash, data, hex_str;
47 size_t username_len, password_len;
48 int uid = 0;
49 enumerator_t *enumerator;
50
51 /* hash = SHA1( username | password ) */
52 hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
53 if (hasher == NULL)
54 {
55 return 0;
56 }
57 hash = chunk_alloca(hasher->get_hash_size(hasher));
58 username_len = strlen(username);
59 password_len = strlen(password);
60 data = chunk_alloca(username_len + password_len);
61 memcpy(data.ptr, username, username_len);
62 memcpy(data.ptr + username_len, password, password_len);
63 hasher->get_hash(hasher, data, hash.ptr);
64 hasher->destroy(hasher);
65 hex_str = chunk_to_hex(hash, NULL, FALSE);
66
67 enumerator = this->db->query(this->db,
68 "SELECT oid FROM users WHERE username = ? AND password = ?;",
69 DB_TEXT, username, DB_TEXT, hex_str.ptr,
70 DB_INT);
71 if (enumerator)
72 {
73 enumerator->enumerate(enumerator, &uid);
74 enumerator->destroy(enumerator);
75 }
76 free(hex_str.ptr);
77 return uid;
78 }
79
80 /**
81 * Implementation of storage_t.create_gateway_enumerator.
82 */
83 static enumerator_t* create_gateway_enumerator(private_storage_t *this, int user)
84 {
85 enumerator_t *enumerator;
86
87 enumerator = this->db->query(this->db,
88 "SELECT gateways.oid AS gid, name, port, address FROM "
89 "gateways, user_gateway AS ug ON gid = ug.gateway WHERE ug.user = ?;",
90 DB_INT, user,
91 DB_INT, DB_TEXT, DB_INT, DB_TEXT);
92 if (!enumerator)
93 {
94 enumerator = enumerator_create_empty();
95 }
96 return enumerator;
97 }
98
99 /**
100 * Implementation of storage_t.destroy
101 */
102 static void destroy(private_storage_t *this)
103 {
104 this->db->destroy(this->db);
105 free(this);
106 }
107
108 /*
109 * see header file
110 */
111 storage_t *storage_create(char *uri)
112 {
113 private_storage_t *this = malloc_thing(private_storage_t);
114
115 this->public.login = (int(*)(storage_t*, char *username, char *password))login;
116 this->public.create_gateway_enumerator = (enumerator_t*(*)(storage_t*,int))create_gateway_enumerator;
117 this->public.destroy = (void(*)(storage_t*))destroy;
118
119 this->db = lib->db->create(lib->db, uri);
120 if (this->db == NULL)
121 {
122 free(this);
123 return NULL;
124 }
125 return &this->public;
126 }
127