Annotation of embedaddon/strongswan/src/medsrv/controller/user_controller.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2008 Martin Willi
! 3: * Copyright (C) 2008 Philip Boetschi, Adrian Doerig
! 4: * HSR Hochschule fuer Technik Rapperswil
! 5: *
! 6: * This program is free software; you can redistribute it and/or modify it
! 7: * under the terms of the GNU General Public License as published by the
! 8: * Free Software Foundation; either version 2 of the License, or (at your
! 9: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
! 10: *
! 11: * This program is distributed in the hope that it will be useful, but
! 12: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! 13: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
! 14: * for more details.
! 15: */
! 16:
! 17: #define _GNU_SOURCE
! 18: #include <string.h>
! 19:
! 20: #include "user_controller.h"
! 21:
! 22: #include <library.h>
! 23:
! 24: typedef struct private_user_controller_t private_user_controller_t;
! 25:
! 26: /**
! 27: * private data of the user_controller
! 28: */
! 29: struct private_user_controller_t {
! 30:
! 31: /**
! 32: * public functions
! 33: */
! 34: user_controller_t public;
! 35:
! 36: /**
! 37: * database connection
! 38: */
! 39: database_t *db;
! 40:
! 41: /**
! 42: * user session
! 43: */
! 44: user_t *user;
! 45:
! 46: /**
! 47: * minimum required password length
! 48: */
! 49: u_int password_length;
! 50: };
! 51:
! 52: /**
! 53: * hash the password for database storage
! 54: */
! 55: static chunk_t hash_password(char *login, char *password)
! 56: {
! 57: hasher_t *hasher;
! 58: chunk_t hash, data;
! 59:
! 60: hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
! 61: if (!hasher)
! 62: {
! 63: return chunk_empty;
! 64: }
! 65: data = chunk_cata("cc", chunk_create(login, strlen(login)),
! 66: chunk_create(password, strlen(password)));
! 67: if (!hasher->allocate_hash(hasher, data, &hash))
! 68: {
! 69: hasher->destroy(hasher);
! 70: return chunk_empty;
! 71: }
! 72: hasher->destroy(hasher);
! 73: return hash;
! 74: }
! 75:
! 76: /**
! 77: * Login a user.
! 78: */
! 79: static void login(private_user_controller_t *this, fast_request_t *request)
! 80: {
! 81: if (request->get_query_data(request, "submit"))
! 82: {
! 83: char *login, *password;
! 84:
! 85: login = request->get_query_data(request, "login");
! 86: password = request->get_query_data(request, "password");
! 87:
! 88: if (login && password)
! 89: {
! 90: enumerator_t *query;
! 91: u_int id = 0;
! 92: chunk_t hash;
! 93:
! 94: hash = hash_password(login, password);
! 95: query = this->db->query(this->db,
! 96: "SELECT id FROM user WHERE login = ? AND password = ?",
! 97: DB_TEXT, login, DB_BLOB, hash, DB_UINT);
! 98: if (query)
! 99: {
! 100: query->enumerate(query, &id);
! 101: query->destroy(query);
! 102: }
! 103: free(hash.ptr);
! 104: if (id)
! 105: {
! 106: this->user->set_user(this->user, id);
! 107: return request->redirect(request, "peer/list");
! 108: }
! 109: }
! 110: request->setf(request, "error=Invalid username or password.");
! 111: }
! 112: request->render(request, "templates/user/login.cs");
! 113: }
! 114:
! 115: /**
! 116: * Logout a user.
! 117: */
! 118: static void logout(private_user_controller_t *this, fast_request_t *request)
! 119: {
! 120: request->redirect(request, "user/login");
! 121: request->close_session(request);
! 122: }
! 123:
! 124: /**
! 125: * verify a user entered username for validity
! 126: */
! 127: static bool verify_login(private_user_controller_t *this,
! 128: fast_request_t *request, char *login)
! 129: {
! 130: if (!login || *login == '\0')
! 131: {
! 132: request->setf(request, "error=Username is missing.");
! 133: return FALSE;
! 134: }
! 135: while (*login != '\0')
! 136: {
! 137: switch (*login)
! 138: {
! 139: case 'a' ... 'z':
! 140: case 'A' ... 'Z':
! 141: case '0' ... '9':
! 142: case '-':
! 143: case '_':
! 144: case '@':
! 145: case '.':
! 146: login++;
! 147: continue;
! 148: default:
! 149: request->setf(request, "error=Username invalid, "
! 150: "valid characters: A-Z a-z 0-9 - _ @ .");
! 151: }
! 152: }
! 153: return TRUE;
! 154: }
! 155:
! 156: /**
! 157: * verify a user entered password for validity
! 158: */
! 159: static bool verify_password(private_user_controller_t *this,
! 160: fast_request_t *request,
! 161: char *password, char *confirm)
! 162: {
! 163: if (!password || *password == '\0')
! 164: {
! 165: request->setf(request, "error=Password is missing.");
! 166: return FALSE;
! 167: }
! 168: if (strlen(password) < this->password_length)
! 169: {
! 170: request->setf(request, "error=Password requires at least %d characters.",
! 171: this->password_length);
! 172: return FALSE;
! 173: }
! 174: if (!confirm || !streq(password, confirm))
! 175: {
! 176: request->setf(request, "error=Password not confirmed.");
! 177: return FALSE;
! 178: }
! 179: return TRUE;
! 180: }
! 181:
! 182: /**
! 183: * Register a user.
! 184: */
! 185: static void add(private_user_controller_t *this, fast_request_t *request)
! 186: {
! 187: char *login = "";
! 188:
! 189: while (request->get_query_data(request, "register"))
! 190: {
! 191: char *password, *confirm;
! 192: chunk_t hash;
! 193: u_int id;
! 194:
! 195: login = request->get_query_data(request, "new_login");
! 196: password = request->get_query_data(request, "new_password");
! 197: confirm = request->get_query_data(request, "confirm_password");
! 198:
! 199: if (!verify_login(this, request, login) ||
! 200: !verify_password(this, request, password, confirm))
! 201: {
! 202: break;
! 203: }
! 204:
! 205: hash = hash_password(login, password);
! 206: if (!hash.ptr || this->db->execute(this->db, &id,
! 207: "INSERT INTO user (login, password) VALUES (?, ?)",
! 208: DB_TEXT, login, DB_BLOB, hash) < 0)
! 209: {
! 210: request->setf(request, "error=Username already exists.");
! 211: free(hash.ptr);
! 212: break;
! 213: }
! 214: free(hash.ptr);
! 215: this->user->set_user(this->user, id);
! 216: return request->redirect(request, "peer/list");
! 217: }
! 218: request->set(request, "new_login", login);
! 219: request->setf(request, "password_length=%d", this->password_length);
! 220: request->render(request, "templates/user/add.cs");
! 221: }
! 222:
! 223: /**
! 224: * Edit the logged in user
! 225: */
! 226: static void edit(private_user_controller_t *this, fast_request_t *request)
! 227: {
! 228: enumerator_t *query;
! 229: char *old_login;
! 230:
! 231: /* lookup old login */
! 232: query = this->db->query(this->db, "SELECT login FROM user WHERE id = ?",
! 233: DB_INT, this->user->get_user(this->user),
! 234: DB_TEXT);
! 235: if (!query || !query->enumerate(query, &old_login))
! 236: {
! 237: DESTROY_IF(query);
! 238: request->close_session(request);
! 239: return request->redirect(request, "user/login");
! 240: }
! 241: old_login = strdupa(old_login);
! 242: query->destroy(query);
! 243:
! 244: /* back pressed */
! 245: if (request->get_query_data(request, "back"))
! 246: {
! 247: return request->redirect(request, "peer/list");
! 248: }
! 249: /* delete pressed */
! 250: if (request->get_query_data(request, "delete"))
! 251: {
! 252: this->db->execute(this->db, NULL, "DELETE FROM user WHERE id = ?",
! 253: DB_UINT, this->user->get_user(this->user));
! 254: this->db->execute(this->db, NULL,
! 255: "DELETE FROM peer WHERE user = ?",
! 256: DB_UINT, this->user->get_user(this->user));
! 257: return logout(this, request);
! 258: }
! 259: /* save pressed */
! 260: while (request->get_query_data(request, "save"))
! 261: {
! 262: char *new_login, *old_pass, *new_pass, *confirm;
! 263: chunk_t old_hash, new_hash;
! 264:
! 265: new_login = request->get_query_data(request, "old_login");
! 266: old_pass = request->get_query_data(request, "old_password");
! 267: new_pass = request->get_query_data(request, "new_password");
! 268: confirm = request->get_query_data(request, "confirm_password");
! 269:
! 270: if (!verify_login(this, request, new_login) ||
! 271: !verify_password(this, request, new_pass, confirm))
! 272: {
! 273: old_login = new_login;
! 274: break;
! 275: }
! 276: old_hash = hash_password(old_login, old_pass);
! 277: new_hash = hash_password(new_login, new_pass);
! 278:
! 279: if (this->db->execute(this->db, NULL,
! 280: "UPDATE user SET login = ?, password = ? "
! 281: "WHERE id = ? AND password = ?",
! 282: DB_TEXT, new_login, DB_BLOB, new_hash,
! 283: DB_UINT, this->user->get_user(this->user), DB_BLOB, old_hash) <= 0)
! 284: {
! 285: free(new_hash.ptr);
! 286: free(old_hash.ptr);
! 287: old_login = new_login;
! 288: request->setf(request, "error=Password verification failed.");
! 289: break;
! 290: }
! 291: free(new_hash.ptr);
! 292: free(old_hash.ptr);
! 293: return request->redirect(request, "peer/list");
! 294: }
! 295: /* on error/template rendering */
! 296: request->set(request, "old_login", old_login);
! 297: request->setf(request, "password_length=%d", this->password_length);
! 298: request->render(request, "templates/user/edit.cs");
! 299: }
! 300:
! 301: METHOD(fast_controller_t, get_name, char*,
! 302: private_user_controller_t *this)
! 303: {
! 304: return "user";
! 305: }
! 306:
! 307: METHOD(fast_controller_t, handle, void,
! 308: private_user_controller_t *this, fast_request_t *request, char *action,
! 309: char *p2, char *p3, char *p4, char *p5)
! 310: {
! 311: if (action)
! 312: {
! 313: if (streq(action, "add"))
! 314: {
! 315: return add(this, request);
! 316: }
! 317: if (streq(action, "login"))
! 318: {
! 319: return login(this, request);
! 320: }
! 321: else if (streq(action, "logout"))
! 322: {
! 323: return logout(this, request);
! 324: }
! 325: else if (streq(action, "edit"))
! 326: {
! 327: return edit(this, request);
! 328: }
! 329: else if (streq(action, "help"))
! 330: {
! 331: return request->render(request, "templates/user/help.cs");
! 332: }
! 333: }
! 334: request->redirect(request, "user/login");
! 335: }
! 336:
! 337: METHOD(fast_controller_t, destroy, void,
! 338: private_user_controller_t *this)
! 339: {
! 340: free(this);
! 341: }
! 342:
! 343: /*
! 344: * see header file
! 345: */
! 346: fast_controller_t *user_controller_create(user_t *user, database_t *db)
! 347: {
! 348: private_user_controller_t *this;
! 349:
! 350: INIT(this,
! 351: .public = {
! 352: .controller = {
! 353: .get_name = _get_name,
! 354: .handle = _handle,
! 355: .destroy = _destroy,
! 356: },
! 357: },
! 358: .user = user,
! 359: .db = db,
! 360: .password_length = lib->settings->get_int(lib->settings,
! 361: "medsrv.password_length", 6),
! 362: );
! 363:
! 364: return &this->public.controller;
! 365: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>