1
0
Fork 0
mirror of https://github.com/deltachat/deltachat-core.git synced 2025-10-05 10:39:27 +02:00

move INVITECODE and AUTH to tables and keep them per chat_id

This commit is contained in:
B. Petersen 2018-05-11 15:12:02 +02:00
parent 56fd425a2f
commit 606d6f38c6
6 changed files with 167 additions and 59 deletions

View file

@ -537,6 +537,9 @@
<Unit filename="src/mrstock.c"> <Unit filename="src/mrstock.c">
<Option compilerVar="CC" /> <Option compilerVar="CC" />
</Unit> </Unit>
<Unit filename="src/mrtoken.c">
<Option compilerVar="CC" />
</Unit>
<Unit filename="src/mrtools.c"> <Unit filename="src/mrtools.c">
<Option compilerVar="CC" /> <Option compilerVar="CC" />
</Unit> </Unit>

View file

@ -33,6 +33,7 @@ lib_src = [
'mrsmtp.c', 'mrsmtp.c',
'mrsqlite3.c', 'mrsqlite3.c',
'mrstock.c', 'mrstock.c',
'mrtoken.c',
'mrtools.c', 'mrtools.c',
'mruudecode.c', 'mruudecode.c',
] ]

View file

@ -28,60 +28,12 @@
#include "mrmimeparser.h" #include "mrmimeparser.h"
#include "mrmimefactory.h" #include "mrmimefactory.h"
#include "mrjob.h" #include "mrjob.h"
#include "mrtoken.h"
#define LOCK { mrsqlite3_lock (mailbox->m_sql); locked = 1; } #define LOCK { mrsqlite3_lock (mailbox->m_sql); locked = 1; }
#define UNLOCK if( locked ) { mrsqlite3_unlock(mailbox->m_sql); locked = 0; } #define UNLOCK if( locked ) { mrsqlite3_unlock(mailbox->m_sql); locked = 0; }
/*******************************************************************************
* Tools: Alice's invitenumber and auth mini-datastore
******************************************************************************/
/* the "mini-datastore is used to remember Alice's last few invitenumbers and
auths as they're written to a QR code. This is needed for later
comparison when the data are provided by Bob. */
static void store_tag__(mrmailbox_t* mailbox, const char* datastore_name, const char* to_add)
{
// prepend new tag to the list of all tags
#define MAX_REMEMBERED_TAGS 10
#define MAX_REMEMBERED_CHARS (MAX_REMEMBERED_TAGS*(MR_CREATE_ID_LEN+1))
char* old_tags = mrsqlite3_get_config__(mailbox->m_sql, datastore_name, "");
if( strlen(old_tags) > MAX_REMEMBERED_CHARS ) {
old_tags[MAX_REMEMBERED_CHARS] = 0; // the oldest tag may be incomplete and unrecognizable, however, this should not be a problem as it would be deleted soon anyway
}
char* new_tags = mr_mprintf("%s,%s", to_add, old_tags);
mrsqlite3_set_config__(mailbox->m_sql, datastore_name, new_tags);
free(old_tags);
free(new_tags);
}
static int lookup_tag__(mrmailbox_t* mailbox, const char* datastore_name, const char* to_lookup)
{
int found = 0;
char* old_tags = NULL;
carray* lines = NULL;
old_tags = mrsqlite3_get_config__(mailbox->m_sql, datastore_name, "");
mr_str_replace(&old_tags, ",", "\n");
lines = mr_split_into_lines(old_tags);
for( int i = 0; i < carray_count(lines); i++ ) {
char* tag = (char*)carray_get(lines, i); mr_trim(tag);
if( strlen(tag) >= 4 && strcmp(tag, to_lookup) == 0 ) {
found = 1;
}
}
mr_free_splitted_lines(lines);
free(old_tags);
return found;
}
/******************************************************************************* /*******************************************************************************
* Tools: Handle degraded keys and lost verificaton * Tools: Handle degraded keys and lost verificaton
******************************************************************************/ ******************************************************************************/
@ -424,13 +376,22 @@ char* mrmailbox_get_securejoin_qr(mrmailbox_t* mailbox, uint32_t group_chat_id)
mrmailbox_ensure_secret_key_exists(mailbox); mrmailbox_ensure_secret_key_exists(mailbox);
// invitenumber will be used to allow starting the handshake, auth will be used to verify the fingerprint
invitenumber = mr_create_id();
auth = mr_create_id();
mrsqlite3_lock(mailbox->m_sql); mrsqlite3_lock(mailbox->m_sql);
locked = 1; locked = 1;
// invitenumber will be used to allow starting the handshake, auth will be used to verify the fingerprint
invitenumber = mrtoken_lookup__(mailbox, MRT_INVITENUMBER, group_chat_id);
if( invitenumber == NULL ) {
invitenumber = mr_create_id();
mrtoken_save__(mailbox, MRT_INVITENUMBER, group_chat_id, invitenumber);
}
auth = mrtoken_lookup__(mailbox, MRT_AUTH, group_chat_id);
if( auth == NULL ) {
auth = mr_create_id();
mrtoken_save__(mailbox, MRT_AUTH, group_chat_id, auth);
}
if( (self_addr = mrsqlite3_get_config__(mailbox->m_sql, "configured_addr", NULL)) == NULL ) { if( (self_addr = mrsqlite3_get_config__(mailbox->m_sql, "configured_addr", NULL)) == NULL ) {
mrmailbox_log_error(mailbox, 0, "Not configured."); mrmailbox_log_error(mailbox, 0, "Not configured.");
goto cleanup; goto cleanup;
@ -438,9 +399,6 @@ char* mrmailbox_get_securejoin_qr(mrmailbox_t* mailbox, uint32_t group_chat_id)
self_name = mrsqlite3_get_config__(mailbox->m_sql, "displayname", ""); self_name = mrsqlite3_get_config__(mailbox->m_sql, "displayname", "");
store_tag__(mailbox, "secureJoin.invitenumbers", invitenumber);
store_tag__(mailbox, "secureJoin.auths", auth);
mrsqlite3_unlock(mailbox->m_sql); mrsqlite3_unlock(mailbox->m_sql);
locked = 0; locked = 0;
@ -658,7 +616,7 @@ int mrmailbox_handle_securejoin_handshake(mrmailbox_t* mailbox, mrmimeparser_t*
} }
LOCK LOCK
if( lookup_tag__(mailbox, "secureJoin.invitenumbers", invitenumber) == 0 ) { if( mrtoken_exists__(mailbox, MRT_INVITENUMBER, invitenumber) == 0 ) {
mrmailbox_log_warning(mailbox, 0, "Secure-join denied (bad invitenumber)."); // do not raise an error, this might just be spam or come from an old request mrmailbox_log_warning(mailbox, 0, "Secure-join denied (bad invitenumber)."); // do not raise an error, this might just be spam or come from an old request
goto cleanup; goto cleanup;
} }
@ -750,7 +708,7 @@ int mrmailbox_handle_securejoin_handshake(mrmailbox_t* mailbox, mrmimeparser_t*
} }
LOCK LOCK
if( lookup_tag__(mailbox, "secureJoin.auths", auth) == 0 ) { if( mrtoken_exists__(mailbox, MRT_AUTH, auth) == 0 ) {
mrsqlite3_unlock(mailbox->m_sql); mrsqlite3_unlock(mailbox->m_sql);
locked = 0; locked = 0;
could_not_establish_secure_connection(mailbox, contact_chat_id, "Auth invalid."); could_not_establish_secure_connection(mailbox, contact_chat_id, "Auth invalid.");

View file

@ -383,9 +383,15 @@ int mrsqlite3_open__(mrsqlite3_t* ths, const char* dbfile, int flags)
} }
#undef NEW_DB_VERSION #undef NEW_DB_VERSION
#define NEW_DB_VERSION 38 #define NEW_DB_VERSION 39
if( dbversion < NEW_DB_VERSION ) if( dbversion < NEW_DB_VERSION )
{ {
mrsqlite3_execute__(ths, "CREATE TABLE tokens ("
" id INTEGER PRIMARY KEY,"
" namespc INTEGER DEFAULT 0,"
" foreign_id INTEGER DEFAULT 0,"
" token TEXT DEFAULT '',"
" timestamp INTEGER DEFAULT 0);");
mrsqlite3_execute__(ths, "ALTER TABLE acpeerstates ADD COLUMN verified_key;"); mrsqlite3_execute__(ths, "ALTER TABLE acpeerstates ADD COLUMN verified_key;");
mrsqlite3_execute__(ths, "ALTER TABLE acpeerstates ADD COLUMN verified_key_fingerprint TEXT DEFAULT '';"); /* do not add `COLLATE NOCASE` case-insensivity is not needed as we force uppercase on store - otoh case-sensivity may be neeed for other/upcoming fingerprint formats */ mrsqlite3_execute__(ths, "ALTER TABLE acpeerstates ADD COLUMN verified_key_fingerprint TEXT DEFAULT '';"); /* do not add `COLLATE NOCASE` case-insensivity is not needed as we force uppercase on store - otoh case-sensivity may be neeed for other/upcoming fingerprint formats */
mrsqlite3_execute__(ths, "CREATE INDEX acpeerstates_index5 ON acpeerstates (verified_key_fingerprint);"); mrsqlite3_execute__(ths, "CREATE INDEX acpeerstates_index5 ON acpeerstates (verified_key_fingerprint);");

90
src/mrtoken.c Normal file
View file

@ -0,0 +1,90 @@
/*******************************************************************************
*
* Delta Chat Core
* Copyright (C) 2017 Björn Petersen
* Contact: r10s@b44t.com, http://b44t.com
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see http://www.gnu.org/licenses/ .
*
******************************************************************************/
#include "mrmailbox_internal.h"
#include "mrtoken.h"
void mrtoken_save__(mrmailbox_t* mailbox, mrtokennamespc_t namespc, uint32_t foreign_id, const char* token)
{
sqlite3_stmt* stmt = NULL;
if( mailbox == NULL || mailbox->m_magic != MR_MAILBOX_MAGIC || token == NULL ) { // foreign_id may be 0
goto cleanup;
}
stmt = mrsqlite3_prepare_v2_(mailbox->m_sql,
"INSERT INTO tokens (namespc, foreign_id, token, timestamp) VALUES (?, ?, ?, ?);");
sqlite3_bind_int (stmt, 1, (int)namespc);
sqlite3_bind_int (stmt, 2, (int)foreign_id);
sqlite3_bind_text (stmt, 3, token, -1, SQLITE_STATIC);
sqlite3_bind_int64(stmt, 4, time(NULL));
sqlite3_step(stmt);
cleanup:
if( stmt ) { sqlite3_finalize(stmt); }
}
char* mrtoken_lookup__(mrmailbox_t* mailbox, mrtokennamespc_t namespc, uint32_t foreign_id)
{
char* token = NULL;
sqlite3_stmt* stmt = NULL;
if( mailbox == NULL || mailbox->m_magic != MR_MAILBOX_MAGIC ) {
goto cleanup;
}
stmt = mrsqlite3_prepare_v2_(mailbox->m_sql,
"SELECT token FROM tokens WHERE namespc=? AND foreign_id=?;");
sqlite3_bind_int (stmt, 1, (int)namespc);
sqlite3_bind_int (stmt, 2, (int)foreign_id);
sqlite3_step(stmt);
token = strdup_keep_null((char*)sqlite3_column_text(stmt, 0));
cleanup:
if( stmt ) { sqlite3_finalize(stmt); }
return token;
}
int mrtoken_exists__(mrmailbox_t* mailbox, mrtokennamespc_t namespc, const char* token)
{
int exists = 0;
sqlite3_stmt* stmt = NULL;
if( mailbox == NULL || mailbox->m_magic != MR_MAILBOX_MAGIC || token == NULL ) {
goto cleanup;
}
stmt = mrsqlite3_prepare_v2_(mailbox->m_sql,
"SELECT id FROM tokens WHERE namespc=? AND token=?;");
sqlite3_bind_int (stmt, 1, (int)namespc);
sqlite3_bind_text(stmt, 2, token, -1, SQLITE_STATIC);
exists = (sqlite3_step(stmt)!=0);
cleanup:
if( stmt ) { sqlite3_finalize(stmt); }
return exists;
}

50
src/mrtoken.h Normal file
View file

@ -0,0 +1,50 @@
/*******************************************************************************
*
* Delta Chat Core
* Copyright (C) 2017 Björn Petersen
* Contact: r10s@b44t.com, http://b44t.com
*
* This program is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see http://www.gnu.org/licenses/ .
*
******************************************************************************/
#ifndef __MRTOKEN_H__
#define __MRTOKEN_H__
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _mrmailbox mrmailbox_t;
// Token namespaces
typedef enum {
MRT_INVITENUMBER = 100,
MRT_AUTH = 110
} mrtokennamespc_t;
// Functions to read/write token from/to the database. A token is any string associated with a key.
void mrtoken_save__ (mrmailbox_t*, mrtokennamespc_t, uint32_t foreign_id, const char* token);
char* mrtoken_lookup__ (mrmailbox_t*, mrtokennamespc_t, uint32_t foreign_id);
int mrtoken_exists__ (mrmailbox_t*, mrtokennamespc_t, const char* token);
#ifdef __cplusplus
} /* /extern "C" */
#endif
#endif /* __MRTOKEN_H__ */