// ==========================================================================
// METHOD limadb::createlist
// ==========================================================================
bool limadb::createlist (const statstring &listid, 
						 const string &owner, bool usemoderation,
						 bool usesubmoderation, const string &plistname,
						 const string &psubjecttag)
{
	// Filter format, reject doubles.
	if (!listid.sval().validate (VALID_LISTNAME))
	{
		::fprintf (stderr, "Invalid listame %s\n", listid.str());
		return false;
	}
	if (listexists (listid))
	{
		::fprintf (stderr, "List already exists\n");
		return false;
	}
	
	// Create a 64bits salt.
	string mysalt = gensalt();
	mysalt = mysalt.encode64 ();
	
	string listname = plistname;
	string subjecttag = psubjecttag;
	
	// If no listname is provided, use the 'user'-part of the
	// list's address.
	if (! listname.strlen())
	{
		listname = listid.sval().copyuntil ('@');
	}
	
	// If no subject tag is provided, use the listname.
	if (! subjecttag.strlen())
	{
		subjecttag = listname;
	}
	
	// Fill in database metadata.
	value data;
	data["address"] = listid;
	data["subjecttag"] = subjecttag;
	data["name"] = listname;
	data["moderation_posts"] = (int) usemoderation;
	data["moderation_subscriptions"] = usesubmoderation?1:0;
	data["replyto"] = 0;
	data["owner"] = owner;
	data["salt"] = mysalt;
	
	// Send create statement
	dbquery q (DB);
	q.insertinto (tlists).values (data);
		
	if (! q.execvoid())
	{
		::fprintf (stderr, "SQL query failed\n");
		return false;
	}
	return true;
};
Beispiel #2
0
/*
 * Generate 8 base64 ASCII characters of random salt.  If MD5_CRYPT_ENAB
 * in /etc/login.defs is "yes", the salt string will be prefixed by "$1$"
 * (magic) and pw_encrypt() will execute the MD5-based FreeBSD-compatible
 * version of crypt() instead of the standard one.
 * Other methods can be set with ENCRYPT_METHOD
 *
 * The method can be forced with the meth parameter.
 * If NULL, the method will be defined according to the MD5_CRYPT_ENAB and
 * ENCRYPT_METHOD login.defs variables.
 *
 * If meth is specified, an additional parameter can be provided.
 *  * For the SHA256 and SHA512 method, this specifies the number of rounds
 *    (if not NULL).
 */
/*@observer@*/const char *crypt_make_salt (/*@null@*/const char *meth, /*@null@*/void *arg)
{
	/* Max result size for the SHA methods:
	 *  +3		$5$
	 *  +17		rounds=999999999$
	 *  +16		salt
	 *  +1		\0
	 */
	static char result[40];
	size_t salt_len = 8;
	const char *method;

	result[0] = '\0';

	if (NULL != meth)
		method = meth;
	else {
		method = getdef_str ("ENCRYPT_METHOD");
		if (NULL == method) {
			method = getdef_bool ("MD5_CRYPT_ENAB") ? "MD5" : "DES";
		}
	}

	if (0 == strcmp (method, "MD5")) {
		MAGNUM(result, '1');
#ifdef USE_SHA_CRYPT
	} else if (0 == strcmp (method, "SHA256")) {
		MAGNUM(result, '5');
		strcat(result, SHA_salt_rounds((int *)arg));
		salt_len = SHA_salt_size();
	} else if (0 == strcmp (method, "SHA512")) {
		MAGNUM(result, '6');
		strcat(result, SHA_salt_rounds((int *)arg));
		salt_len = SHA_salt_size();
#endif /* USE_SHA_CRYPT */
	} else if (0 != strcmp (method, "DES")) {
		fprintf (stderr,
			 _("Invalid ENCRYPT_METHOD value: '%s'.\n"
			   "Defaulting to DES.\n"),
			 method);
		result[0] = '\0';
	}

	/*
	 * Concatenate a pseudo random salt.
	 */
	assert (sizeof (result) > strlen (result) + salt_len);
	strncat (result, gensalt (salt_len),
		 sizeof (result) - strlen (result) - 1);

	return result;
}
Beispiel #3
0
int main(int argc, char **argv){

	int err;
	char *err_msg;
	sqlite3 *db;
	char dbpath[PATH_MAX] = {0};

	char *dellabel = NULL;
	int addflag = 0;
	int showflag = 0;
	int delflag = 0;
	int listflag = 0;
	int initdb = 0;
	int c;

	while ((c = getopt (argc, argv, "asd:lh")) != -1){
		switch (c){
			case 'a':
				addflag = 1;
				break;
			case 's':
				showflag = 1;
				break;
			case 'd':
				delflag = 1;
				dellabel = optarg;
				break;
			case 'l':
				listflag = 1;
				break;
			case 'h':
			default:
				fprintf(stdout, usage);
				exit(0);
		}
	}

	if (addflag & delflag){
		fprintf(stderr, "Specify either -a or -d, not both\n");
		exit(1);
	}

	if (fs_datadir_init(DATA_DIR)){
		perror("Failed to open config directory");
		exit(1);
	}

	if (fs_exists_relative(DB_NAME) != 0){
		puts("First run, initializing db...");
		initdb = 1;
	}

	strcat(dbpath, fs_datadir_getpath());
	strcat(dbpath, "/");
	strcat(dbpath, DB_NAME);


	if ((err = sqlite3_open(dbpath, &db)) != SQLITE_OK){
		fprintf(stderr, "sqlite3_open failure: %s\n", sqlite3_errmsg(db));
		sqlite3_close(db);
		exit(1);
	}

	if (initdb){
		char *sql = "CREATE TABLE passwords (label TEXT, salt TEXT, hash TEXT, created DATETIME, last_success DATETIME);";
		err = sqlite3_exec(db, sql, 0, 0, &err_msg);
		if (err != SQLITE_OK){
			fprintf(stderr, "SQL error: %s\n", err_msg);
			sqlite3_free(err_msg);
			sqlite3_close(db);
			exit(1);
		}
	}

	if (listflag){

		int err;
		char *err_msg;

		err = sqlite3_exec(db, "SELECT created, label FROM passwords ORDER BY label ASC", passlist_cb, NULL, &err_msg);

		if (err != SQLITE_OK){
			fprintf(stderr, "SQL SELECT error: %s\n", err_msg);
			sqlite3_free(err_msg);
			sqlite3_close(db);
			exit(1);
		}

		exit(0);
	}

	if (delflag){

		int err;
		char *yn;

		if (sql_label_exists(db, dellabel) == 0){
			fprintf(stderr, "A password with that label does not exist\n");
			sqlite3_close(db);
			exit(1);
		}

		fprintf(stdout, "You are about to delete the entry labeled ``%s''\n", dellabel);

		err = stdin_prompt("Continue [yn]", &yn);
		if (err != 0){
			exit(0);
		}

		if (strcmp("y", yn) == 0){

			sql_label_delete(db, dellabel);

			puts("Entry deleted.");

		}

		exit(0);

	}

	if (addflag){

		char *label, *pass;
		time_t rawtime;
		struct tm *timeinfo;
		char timestr[24] = {0};
		char *sql_p = "INSERT INTO passwords (label, salt, hash, created, last_success) VALUES (?, ?, ?, ?, ?);";
		sqlite3_stmt *res;
		char hash[SHA512_OUTPUT];

		puts("Adding new password");

		if (stdin_prompt("label", &label)){
			sqlite3_close(db);
			fprintf(stderr, "entry canceled\n");
			exit(1);
		}

		if (sql_label_exists(db, label) != 0){
			fprintf(stderr, "A password with that label already exists.\n");
			exit(1);
		}

		if (stdin_prompt("pass", &pass)){
			sqlite3_close(db);
			fprintf(stderr, "entry canceled\n");
			exit(1);
		}

		time(&rawtime);
		timeinfo = localtime(&rawtime);
		strftime(timestr, sizeof(timestr), "%Y-%m-%d %H:%M:%S", timeinfo);

		err = sqlite3_prepare_v2(db, sql_p, -1, &res, 0);

		if (err == SQLITE_OK){
			char salt[SALT_LEN+1];
			gensalt(salt, SALT_LEN);
			sha512(pass, salt, hash);
			sqlite3_bind_text(res, 1, label, strlen(label), NULL);
			sqlite3_bind_text(res, 2, salt, SALT_LEN, NULL);
			sqlite3_bind_text(res, 3, hash, strlen(hash), NULL);
			sqlite3_bind_text(res, 4, timestr, strlen(timestr), NULL);
			sqlite3_bind_text(res, 5, timestr, strlen(timestr), NULL);
		}
		else {
			fprintf(stderr, "Failed to prepare insert statement: %s\n", sqlite3_errmsg(db));
			sqlite3_close(db);
			exit(1);
		}


		err = sqlite3_step(res);

		free(label);
		free(pass);

		if (err != SQLITE_OK && err != SQLITE_DONE){
			fprintf(stderr, "Failed to execute prepared insert: %s\n", sqlite3_errmsg(db));
			sqlite3_close(db);
			exit(1);
		}

		sqlite3_finalize(res);

		puts("Entry added successfully.");

	}
	else {

		int entries = 0;
		sqlite3_stmt *res;

		err = sqlite3_prepare_v2(db, "SELECT count(*) from passwords", -1, &res, 0);
		if (err != SQLITE_OK){
			fprintf(stderr, "SQL prepare failure: %s\n",  sqlite3_errmsg(db));
			sqlite3_close(db);
			exit(1);
		}

		err = sqlite3_step(res);

		if (err == SQLITE_ROW){
			entries = sqlite3_column_int(res, 0);
		}

		sqlite3_finalize(res);

		if (entries == 0){
			fprintf(stderr, "No passwords in db\n");
			exit(0);
		}

		fprintf(stdout, "%d passwords in db.\n", entries);

		err = sqlite3_exec(db, "SELECT label, salt, hash FROM passwords ORDER BY RANDOM()", passcheck_cb, &showflag, &err_msg);

		if (err != SQLITE_OK){
			fprintf(stderr, "SQL SELECT error: %s\n", err_msg);
			sqlite3_free(err_msg);
			sqlite3_close(db);
			exit(1);
		}

		puts("Finished.");

	}

	sqlite3_close(db);

	return 0;
}