00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include <biosphere_module.h>
00036 #include <io.h>
00037 #include <list.h>
00038 #include <str.h>
00039 #include <type.h>
00040
00041 #include <apr_strings.h>
00042 #include <stdio.h>
00043 #include <openssl/sha.h>
00044
00045
00052 #define BSMOD_PASSWORD_FILE "passwd"
00053
00054 apr_pool_t *password_pool;
00055 bs_list *password_list;
00056
00057
00058 bs_module bsmod_symtable;
00059
00060
00065 typedef struct password_entry {
00066 const char *username;
00067 const char *hash;
00068 } password_entry;
00069
00070
00077 static char *hash_string(const char *str)
00078 {
00079 unsigned char md[SHA_DIGEST_LENGTH];
00080 char *ret = "";
00081 unsigned i;
00082
00083 SHA1((unsigned char *) str, strlen(str), md);
00084 for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
00085 char *d = apr_psprintf(password_pool, "%02x", md[i] & 0xff);
00086 ret = apr_pstrcat(password_pool, ret, d, NULL);
00087 }
00088 return ret;
00089 }
00090
00091
00099 static bs_status add_user(const char *name, const char *pass)
00100 {
00101 char *hash;
00102 unsigned i;
00103 password_entry *entry;
00104
00105
00106 for (i = 0; i < list_size(password_list); i++) {
00107 password_entry *e = (password_entry *) list_index(password_list, i);
00108 if (streq(e->username, name)) return BS_ERROR;
00109 }
00110
00111 hash = hash_string(pass);
00112 entry = (password_entry *) apr_palloc(password_pool,
00113 sizeof(password_entry));
00114 entry->username = apr_pstrdup(password_pool, name);
00115 entry->hash = hash;
00116 list_append(password_list, entry);
00117 return BS_OK;
00118 }
00119
00120
00126 static bs_status remove_user(const char *name)
00127 {
00128 unsigned i;
00129 for (i = 0; i < list_size(password_list); i++) {
00130 password_entry *e = (password_entry *) list_index(password_list, i);
00131 if (streq(e->username, name)) {
00132 list_remove(password_list, i);
00133 return BS_OK;
00134 }
00135 }
00136 return BS_OK;
00137 }
00138
00139
00144 static bs_status bsmod_password_init(void)
00145 {
00146 char *pfilename, *pfilecontents;
00147 bs_uint64 len;
00148 bs_status rv;
00149 bs_list *list;
00150
00151
00152 apr_pool_create(&password_pool, NULL);
00153 pfilename = apr_pstrcat(password_pool,
00154 "/usr/local/biosphere/modules/", BSMOD_PASSWORD_FILE, NULL);
00155 rv = read_file_into_buf(pfilename, &pfilecontents, &len, password_pool);
00156 if (rv != BS_OK || len == 0) {
00157 apr_pool_destroy(password_pool);
00158 return BS_ERROR;
00159 }
00160
00161
00162 list = new_list(password_pool);
00163 strtokenize(list, pfilecontents, NULL);
00164 if (list_size(list) % 2 == 1) {
00165 apr_pool_destroy(password_pool);
00166 return BS_ERROR;
00167 }
00168 else {
00169 unsigned i;
00170
00171
00172 password_list = new_list(password_pool);
00173 for (i = 0 ; i < list_size(list); i += 2) {
00174 password_entry *entry;
00175
00176 entry = (password_entry *) apr_palloc(password_pool,
00177 sizeof(password_entry));
00178 entry->username = apr_pstrdup(password_pool,
00179 (char *) list_index(list, i));
00180 entry->hash = apr_pstrdup(password_pool,
00181 (char *) list_index(list, i + 1));
00182 list_append(password_list, entry);
00183 }
00184 }
00185
00186 return BS_OK;
00187 }
00188
00189
00193 static bs_status bsmod_password_cleanup(void)
00194 {
00195 char *passes = "", *pfilename;
00196 unsigned i;
00197 bs_status rv;
00198
00199
00200 for (i = 0; i < list_size(password_list); i++) {
00201 password_entry *e = (password_entry *) list_index(password_list, i);
00202 passes = apr_pstrcat(password_pool, passes,
00203 e->username, " ", e->hash, "\n", NULL);
00204 }
00205 pfilename = apr_pstrcat(password_pool,
00206 "/usr/local/biosphere/modules/", BSMOD_PASSWORD_FILE, NULL);
00207 rv = write_buf_into_file(pfilename, passes, password_pool);
00208 if (rv != BS_OK) return rv;
00209
00210 apr_pool_destroy(password_pool);
00211 return BS_OK;
00212 }
00213
00214
00215 static bs_service_response *create_status_response(
00216 const bs_service_request *request, bs_status status)
00217 {
00218 bs_service_response *resp;
00219 bs_message_instance *output = NULL;
00220 bs_part_instance *part = NULL;
00221 bs_data_type *type = NULL;
00222 char *data;
00223 apr_pool_t *mp = password_pool;
00224
00225 data = apr_psprintf(mp, "%u", status);
00226 type = new_bs_data_type(mp, "bs_uint32");
00227 if (!type) return NULL;
00228 part = new_bs_part_instance(mp, "status", type,
00229 data, strlen(data));
00230 if (!part) return NULL;
00231 output = new_bs_message_instance(mp, "BSStatusMessage", 1);
00232 if (!output) return NULL;
00233 output->parts[0] = part;
00234 resp = new_bs_service_response(mp, request->uuid,
00235 request->service, request->port, request->operation,
00236 output, NULL);
00237
00238 return resp;
00239 }
00240
00241
00245 static bs_status bsmod_password_handle_service(
00246 const bs_service_request *request,
00247 bs_service_response **response, void *extra)
00248 {
00249 bs_status rv;
00250
00251
00252 if (!streq(request->service, "BSModPasswordServices"))
00253 return BS_NO_SERVICE;
00254 if (!streq(request->port, "Password"))
00255 return BS_NO_SERVICE;
00256
00257
00258 if (streq(request->operation, "verify_user")) {
00259 char *name, *pass;
00260 unsigned i;
00261
00262 rv = 0;
00263 if (request->input->num_parts != 2) return BS_ERROR;
00264 name = request->input->parts[0]->data;
00265 pass = request->input->parts[1]->data;
00266 for (i = 0; i < list_size(password_list); i++) {
00267 password_entry *e = (password_entry *) list_index(password_list, i);
00268 if (streq(e->username, name) && streq(e->hash, hash_string(pass))) {
00269
00270 rv = 1;
00271 }
00272 }
00273 *response = create_status_response(request, rv);
00274 return BS_OK;
00275 }
00276 else if (streq(request->operation, "add_user")) {
00277 if (request->input->num_parts != 2) return BS_ERROR;
00278 rv = add_user(request->input->parts[0]->data,
00279 request->input->parts[1]->data);
00280 *response = create_status_response(request, rv);
00281 return BS_OK;
00282 }
00283 else if (streq(request->operation, "remove_user")) {
00284 if (request->input->num_parts != 1) return BS_ERROR;
00285 rv = remove_user(request->input->parts[0]->data);
00286 *response = create_status_response(request, rv);
00287 return BS_OK;
00288 }
00289
00290 return BS_NO_SERVICE;
00291 }
00292
00293
00294
00295 bs_module bsmod_symtable = {
00296
00297 0,
00298 0,
00299
00300
00301 0,
00302 1,
00303
00304
00305 "password module",
00306 "M.A.Hartman",
00307 "may 9, 2007",
00308 "(c) 2007, M.A.Hartman. See distributed LICENSE file for more information.",
00309 "A module which offers password functions. ",
00310
00311
00312 bsmod_password_init,
00313 bsmod_password_cleanup,
00314
00315
00316 bsmod_password_handle_service,
00317 NULL,
00318 "bsmod_password.wsdl"
00319 };
00320