Ejemplo n.º 1
0
int SLNSessionCreateUserInternal(SLNSessionRef const session, DB_txn *const txn, strarg_t const username, strarg_t const password, SLNMode const mode_unsafe) {
	if(!session) return DB_EINVAL;
	if(!txn) return DB_EINVAL;
	if(!username) return DB_EINVAL;
	if(!password) return DB_EINVAL;
	size_t const ulen = strlen(username);
	size_t const plen = strlen(password);
	if(ulen < USER_MIN || ulen > USER_MAX) return DB_EINVAL;
	if(plen < PASS_MIN || plen > PASS_MAX) return DB_EINVAL;

	SLNMode const mode = mode_unsafe & session->mode;
	if(!mode) return DB_EINVAL;
	uint64_t const parent = session->userID;
	uint64_t const time = uv_now(async_loop); // TODO: Appropriate timestamp?

	uint64_t const userID = db_next_id(SLNUserByID, txn);
	if(!userID) return DB_EACCES;
	str_t *passhash = pass_hash(password);
	if(!passhash) return DB_ENOMEM;

	DB_val username_key[1], userID_val[1];
	SLNUserIDByNameKeyPack(username_key, txn, username);
	SLNUserIDByNameValPack(userID_val, txn, userID);
	int rc = db_put(txn, username_key, userID_val, DB_NOOVERWRITE);
	if(rc < 0) return rc;

	DB_val userID_key[1], user_val[1];
	SLNUserByIDKeyPack(userID_key, txn, userID);
	SLNUserByIDValPack(user_val, txn, username, passhash, NULL, mode, parent, time);
	rc = db_put(txn, userID_key, user_val, DB_NOOVERWRITE);
	if(rc < 0) return rc;

	return 0;
}
Ejemplo n.º 2
0
int SLNSessionCreateSession(SLNSessionRef const session, SLNSessionRef *const out) {
	assert(out);
	if(!session) return DB_EACCES;

	SLNSessionCacheRef const cache = session->cache;
	uint64_t const userID = session->userID;
	SLNMode const mode = session->mode;
	strarg_t const username = session->username;
	DB_env *db = NULL;
	DB_txn *txn = NULL;
	SLNSessionRef alt = NULL;

	byte_t key_raw[SESSION_KEY_LEN];
	int rc = async_random(key_raw, sizeof(key_raw));
	if(rc < 0) goto cleanup;

	byte_t key_enc[SHA256_DIGEST_LENGTH];
	SHA256(key_raw, sizeof(key_raw), key_enc);

	str_t key_str[SESSION_KEY_HEX+1];
	tohex(key_str, key_enc, SESSION_KEY_LEN);
	key_str[SESSION_KEY_HEX] = '\0';

	rc = SLNSessionDBOpen(session, SLN_RDWR, &db); // TODO: Custom permission?
	if(rc < 0) goto cleanup;
	rc = db_txn_begin(db, NULL, DB_RDWR, &txn);
	if(rc < 0) goto cleanup;

	uint64_t const sessionID = db_next_id(SLNSessionByID, txn);
	DB_val key[1], val[1];
	SLNSessionByIDKeyPack(key, txn, sessionID);
	SLNSessionByIDValPack(val, txn, userID, key_str);
	rc = db_put(txn, key, val, DB_NOOVERWRITE_FAST);
	if(rc < 0) goto cleanup;

	rc = db_txn_commit(txn); txn = NULL;
	SLNSessionDBClose(session, &db);
	if(rc < 0) goto cleanup;

	rc = SLNSessionCreateInternal(cache, sessionID, key_raw, key_enc, userID, mode, username, &alt);
	if(rc < 0) goto cleanup;

	*out = alt; alt = NULL;

cleanup:
	db_txn_abort(txn); txn = NULL;
	SLNSessionDBClose(session, &db);
	SLNSessionRelease(&alt);
	return rc;
}
Ejemplo n.º 3
0
int SLNSubmissionStore(SLNSubmissionRef const sub, DB_txn *const txn) {
	assert(sub);
	assert(txn);
	assert(!sub->tmppath);
	// Session permissions were already checked when the sub was created.

	int64_t fileID = db_next_id(SLNFileByID, txn);
	int rc;

	DB_val dupFileID_val[1];
	SLNFileIDByInfoValPack(dupFileID_val, txn, fileID);

	DB_val fileInfo_key[1];
	SLNFileIDByInfoKeyPack(fileInfo_key, txn, sub->internalHash, sub->type);
	rc = db_put(txn, fileInfo_key, dupFileID_val, DB_NOOVERWRITE);
	if(rc >= 0) {
		DB_val fileID_key[1];
		SLNFileByIDKeyPack(fileID_key, txn, fileID);
		DB_val file_val[1];
		SLNFileByIDValPack(file_val, txn, sub->internalHash, sub->type, sub->size);
		rc = db_put(txn, fileID_key, file_val, DB_NOOVERWRITE_FAST);
		if(rc < 0) return rc;
	} else if(DB_KEYEXIST == rc) {
		fileID = db_read_uint64(dupFileID_val);
	} else return rc;

	for(size_t i = 0; sub->URIs[i]; ++i) {
		strarg_t const URI = sub->URIs[i];
		DB_val null = { 0, NULL };

		DB_val fwd[1];
		SLNFileIDAndURIKeyPack(fwd, txn, fileID, URI);
		rc = db_put(txn, fwd, &null, DB_NOOVERWRITE_FAST);
		if(rc < 0 && DB_KEYEXIST != rc) return rc;

		DB_val rev[1];
		SLNURIAndFileIDKeyPack(rev, txn, URI, fileID);
		rc = db_put(txn, rev, &null, DB_NOOVERWRITE_FAST);
		if(rc < 0 && DB_KEYEXIST != rc) return rc;
	}

	rc = SLNSubmissionParseMetaFile(sub, fileID, txn, &sub->metaFileID);
	if(rc < 0) {
		alogf("Submission meta-file error: %s\n", sln_strerror(rc));
		return rc;
	}

	return 0;
}
Ejemplo n.º 4
0
static uint64_t add_metafile(DB_txn *const txn, uint64_t const fileID, strarg_t const targetURI) {
	uint64_t const metaFileID = fileID;
	uint64_t const latestMetaFileID = db_next_id(SLNMetaFileByID, txn);
	if(metaFileID < latestMetaFileID) return 0;
	// If it's not a new file, then it's not a new meta-file.
	// Note that ordinary files can't be "promoted" to meta-files later
	// because that would break the ordering.

	DB_val null = { 0, NULL };
	DB_cursor *cursor = NULL;
	int rc = db_txn_cursor(txn, &cursor);
	assert(rc >= 0);

	DB_val metaFileID_key[1];
	SLNMetaFileByIDKeyPack(metaFileID_key, txn, metaFileID);
	DB_val metaFile_val[1];
	SLNMetaFileByIDValPack(metaFile_val, txn, fileID, targetURI);
	rc = db_put(txn, metaFileID_key, metaFile_val, DB_NOOVERWRITE_FAST);
	assert(rc >= 0);

	DB_range alts[1];
	SLNTargetURIAndMetaFileIDRange1(alts, txn, targetURI);
	rc = db_cursor_firstr(cursor, alts, NULL, NULL, +1);
	assert(rc >= 0 || DB_NOTFOUND == rc);
	if(DB_NOTFOUND == rc) {
		DB_val unique[1];
		SLNFirstUniqueMetaFileIDKeyPack(unique, txn, metaFileID);
		rc = db_put(txn, unique, &null, DB_NOOVERWRITE_FAST);
		assert(rc >= 0);
	}

	DB_val targetURI_key[1];
	SLNTargetURIAndMetaFileIDKeyPack(targetURI_key, txn, targetURI, metaFileID);
	rc = db_put(txn, targetURI_key, &null, DB_NOOVERWRITE_FAST);
	assert(rc >= 0);

	return metaFileID;
}