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:
parent
56fd425a2f
commit
606d6f38c6
6 changed files with 167 additions and 59 deletions
|
@ -537,6 +537,9 @@
|
|||
<Unit filename="src/mrstock.c">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Unit filename="src/mrtoken.c">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
<Unit filename="src/mrtools.c">
|
||||
<Option compilerVar="CC" />
|
||||
</Unit>
|
||||
|
|
|
@ -33,6 +33,7 @@ lib_src = [
|
|||
'mrsmtp.c',
|
||||
'mrsqlite3.c',
|
||||
'mrstock.c',
|
||||
'mrtoken.c',
|
||||
'mrtools.c',
|
||||
'mruudecode.c',
|
||||
]
|
||||
|
|
|
@ -28,60 +28,12 @@
|
|||
#include "mrmimeparser.h"
|
||||
#include "mrmimefactory.h"
|
||||
#include "mrjob.h"
|
||||
#include "mrtoken.h"
|
||||
|
||||
#define LOCK { mrsqlite3_lock (mailbox->m_sql); locked = 1; }
|
||||
#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
|
||||
******************************************************************************/
|
||||
|
@ -424,13 +376,22 @@ char* mrmailbox_get_securejoin_qr(mrmailbox_t* mailbox, uint32_t group_chat_id)
|
|||
|
||||
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);
|
||||
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 ) {
|
||||
mrmailbox_log_error(mailbox, 0, "Not configured.");
|
||||
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", "");
|
||||
|
||||
store_tag__(mailbox, "secureJoin.invitenumbers", invitenumber);
|
||||
store_tag__(mailbox, "secureJoin.auths", auth);
|
||||
|
||||
mrsqlite3_unlock(mailbox->m_sql);
|
||||
locked = 0;
|
||||
|
||||
|
@ -658,7 +616,7 @@ int mrmailbox_handle_securejoin_handshake(mrmailbox_t* mailbox, mrmimeparser_t*
|
|||
}
|
||||
|
||||
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
|
||||
goto cleanup;
|
||||
}
|
||||
|
@ -750,7 +708,7 @@ int mrmailbox_handle_securejoin_handshake(mrmailbox_t* mailbox, mrmimeparser_t*
|
|||
}
|
||||
|
||||
LOCK
|
||||
if( lookup_tag__(mailbox, "secureJoin.auths", auth) == 0 ) {
|
||||
if( mrtoken_exists__(mailbox, MRT_AUTH, auth) == 0 ) {
|
||||
mrsqlite3_unlock(mailbox->m_sql);
|
||||
locked = 0;
|
||||
could_not_establish_secure_connection(mailbox, contact_chat_id, "Auth invalid.");
|
||||
|
|
|
@ -383,9 +383,15 @@ int mrsqlite3_open__(mrsqlite3_t* ths, const char* dbfile, int flags)
|
|||
}
|
||||
#undef NEW_DB_VERSION
|
||||
|
||||
#define NEW_DB_VERSION 38
|
||||
#define NEW_DB_VERSION 39
|
||||
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_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);");
|
||||
|
|
90
src/mrtoken.c
Normal file
90
src/mrtoken.c
Normal 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
50
src/mrtoken.h
Normal 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__ */
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue