You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
860 lines
22 KiB
C
860 lines
22 KiB
C
/**
|
|
* @internal
|
|
* @file pEp_internal.h
|
|
* @brief pEp internal structs, functions, defines, and values
|
|
* @license GNU General Public License 3.0 - see LICENSE.txt
|
|
*/
|
|
|
|
#ifndef PEP_INTERNAL_H
|
|
#define PEP_INTERNAL_H
|
|
|
|
// maximum attachment size to import as key 25MB, maximum of 20 attachments
|
|
#define MAX_KEY_SIZE (25 * 1024 * 1024)
|
|
#define MAX_KEYS_TO_IMPORT 20
|
|
|
|
#define KEY_EXPIRE_DELTA (60 * 60 * 24 * 365)
|
|
|
|
// this is 20 trustwords with 79 chars max
|
|
#define MAX_TRUSTWORDS_SPACE (20 * 80)
|
|
|
|
// XML parameters string
|
|
#define PARMS_MAX 32768
|
|
|
|
// maximum busy wait time in ms
|
|
#define BUSY_WAIT_TIME 5000
|
|
|
|
// default keyserver
|
|
#ifndef DEFAULT_KEYSERVER
|
|
#define DEFAULT_KEYSERVER "hkps://keys.openpgp.org"
|
|
#endif
|
|
|
|
// crashdump constants
|
|
#ifndef CRASHDUMP_DEFAULT_LINES
|
|
#define CRASHDUMP_DEFAULT_LINES 100
|
|
#endif
|
|
#define CRASHDUMP_MAX_LINES 32767
|
|
|
|
// p≡p full string, NUL-terminated
|
|
#ifndef PEP_SUBJ_STRING
|
|
#define PEP_SUBJ_STRING {0x70,0xE2,0x89,0xA1,0x70,0x00}
|
|
#define PEP_SUBJ_BYTELEN 5
|
|
#endif
|
|
|
|
#ifndef PEP_SUBJ_KEY
|
|
#define PEP_SUBJ_KEY "Subject: "
|
|
#define PEP_SUBJ_KEY_LC "subject: "
|
|
#define PEP_SUBJ_KEY_LEN 9
|
|
#endif
|
|
|
|
#ifndef PEP_MSG_WRAP_KEY
|
|
#define PEP_MSG_WRAP_KEY "pEp-Wrapped-Message-Info: "
|
|
#define PEP_MSG_WRAP_KEY_LC "pep-wrapped-message-info: "
|
|
#define PEP_MSG_WRAP_KEY_LEN 26
|
|
#endif
|
|
|
|
#ifndef X_PEP_MSG_WRAP_KEY
|
|
#define X_PEP_MSG_WRAP_KEY "X-pEp-Wrapped-Message-Info"
|
|
#endif
|
|
|
|
#ifndef X_PEP_SNDR_FPR_KEY
|
|
#define X_PEP_SNDR_FPR_KEY "X-pEp-Sender-FPR"
|
|
#endif
|
|
|
|
#ifndef X_PEP_MSG_VER_KEY
|
|
#define X_PEP_MSG_VER_KEY "X-pEp-Message-Version"
|
|
#endif
|
|
|
|
#define VER_1_0 "1.0"
|
|
#define VER_2_0 "2.0"
|
|
#define VER_2_1 "2.1"
|
|
#define VER_2_2 "2.2"
|
|
|
|
#include "platform.h"
|
|
|
|
#ifdef WIN32
|
|
#define KEYS_DB windoze_keys_db()
|
|
#define LOCAL_DB windoze_local_db()
|
|
#define SYSTEM_DB windoze_system_db()
|
|
#else // UNIX
|
|
#ifndef __MVS__
|
|
#define _POSIX_C_SOURCE 200809L
|
|
#endif
|
|
#include <dlfcn.h>
|
|
#define LOCAL_DB unix_local_db()
|
|
#ifdef ANDROID
|
|
#define SYSTEM_DB android_system_db()
|
|
#else
|
|
#define SYSTEM_DB unix_system_db()
|
|
#endif
|
|
#endif
|
|
|
|
#include <locale.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
#include <stdio.h>
|
|
#include <ctype.h>
|
|
#include <math.h>
|
|
|
|
#ifdef SQLITE3_FROM_OS
|
|
#include <sqlite3.h>
|
|
#else
|
|
#include "sqlite3.h"
|
|
#endif
|
|
|
|
#include "pEpEngine.h"
|
|
#include "key_reset.h"
|
|
|
|
#include "pEpEngine_internal.h"
|
|
#include "key_reset_internal.h"
|
|
#include "group_internal.h"
|
|
#include "keymanagement_internal.h"
|
|
#include "message_api_internal.h"
|
|
|
|
#if defined(USE_SEQUOIA)
|
|
#include "pgp_sequoia_internal.h"
|
|
#endif
|
|
|
|
#include "../asn.1/Distribution.h"
|
|
#include "../asn.1/Sync.h"
|
|
|
|
#include "keymanagement.h"
|
|
#include "cryptotech.h"
|
|
#include "transport.h"
|
|
#include "sync_api.h"
|
|
#include "Sync_func.h"
|
|
|
|
|
|
#define NOT_IMPLEMENTED assert(0); return PEP_UNKNOWN_ERROR;
|
|
|
|
struct _pEpSession;
|
|
typedef struct _pEpSession pEpSession;
|
|
/**
|
|
* @internal
|
|
* @struct _pEpSession
|
|
*
|
|
* @brief TODO
|
|
*
|
|
*/
|
|
struct _pEpSession {
|
|
const char *version;
|
|
messageToSend_t messageToSend;
|
|
|
|
#if defined(USE_SEQUOIA)
|
|
sqlite3 *key_db;
|
|
struct {
|
|
sqlite3_stmt *begin_transaction;
|
|
sqlite3_stmt *commit_transaction;
|
|
sqlite3_stmt *rollback_transaction;
|
|
sqlite3_stmt *cert_find;
|
|
sqlite3_stmt *tsk_find;
|
|
sqlite3_stmt *cert_find_by_keyid;
|
|
sqlite3_stmt *tsk_find_by_keyid;
|
|
sqlite3_stmt *cert_find_by_email;
|
|
sqlite3_stmt *tsk_find_by_email;
|
|
sqlite3_stmt *cert_all;
|
|
sqlite3_stmt *tsk_all;
|
|
sqlite3_stmt *cert_save_insert_primary;
|
|
sqlite3_stmt *cert_save_insert_subkeys;
|
|
sqlite3_stmt *cert_save_insert_userids;
|
|
sqlite3_stmt *delete_keypair;
|
|
} sq_sql;
|
|
|
|
pgp_policy_t policy;
|
|
#endif
|
|
|
|
PEP_cryptotech_t *cryptotech;
|
|
PEP_CIPHER_SUITE cipher_suite;
|
|
|
|
char* curr_passphrase;
|
|
bool new_key_pass_enable;
|
|
char* generation_passphrase;
|
|
|
|
PEP_transport_t *transports;
|
|
|
|
sqlite3 *db;
|
|
sqlite3 *system_db;
|
|
|
|
sqlite3_stmt *log;
|
|
sqlite3_stmt *trustword;
|
|
sqlite3_stmt *get_identity;
|
|
sqlite3_stmt *get_identity_without_trust_check;
|
|
sqlite3_stmt *get_identities_by_address;
|
|
sqlite3_stmt *get_identities_by_userid;
|
|
sqlite3_stmt *get_identities_by_main_key_id;
|
|
sqlite3_stmt *replace_identities_fpr;
|
|
sqlite3_stmt *replace_main_user_fpr;
|
|
sqlite3_stmt *replace_main_user_fpr_if_equal;
|
|
sqlite3_stmt *get_main_user_fpr;
|
|
sqlite3_stmt *set_default_identity_fpr;
|
|
sqlite3_stmt *get_default_identity_fpr;
|
|
sqlite3_stmt *refresh_userid_default_key;
|
|
sqlite3_stmt *delete_key;
|
|
sqlite3_stmt *remove_fpr_as_identity_default;
|
|
sqlite3_stmt *remove_fpr_as_user_default;
|
|
sqlite3_stmt *set_person;
|
|
sqlite3_stmt *update_person;
|
|
sqlite3_stmt *delete_person;
|
|
sqlite3_stmt *exists_person;
|
|
sqlite3_stmt *set_as_pEp_user;
|
|
sqlite3_stmt *is_pEp_user;
|
|
sqlite3_stmt *upgrade_pEp_version_by_user_id;
|
|
sqlite3_stmt *add_into_social_graph;
|
|
sqlite3_stmt *get_own_address_binding_from_contact;
|
|
sqlite3_stmt *set_revoke_contact_as_notified;
|
|
sqlite3_stmt *get_contacted_ids_from_revoke_fpr;
|
|
sqlite3_stmt *was_id_for_revoke_contacted;
|
|
sqlite3_stmt *has_id_contacted_address;
|
|
sqlite3_stmt *get_last_contacted;
|
|
// sqlite3_stmt *set_device_group;
|
|
// sqlite3_stmt *get_device_group;
|
|
sqlite3_stmt *set_pgp_keypair;
|
|
sqlite3_stmt *set_pgp_keypair_flags;
|
|
sqlite3_stmt *unset_pgp_keypair_flags;
|
|
sqlite3_stmt *set_identity_entry;
|
|
sqlite3_stmt *update_identity_entry;
|
|
sqlite3_stmt *exists_identity_entry;
|
|
sqlite3_stmt *force_set_identity_username;
|
|
sqlite3_stmt *set_identity_flags;
|
|
sqlite3_stmt *unset_identity_flags;
|
|
sqlite3_stmt *set_ident_enc_format;
|
|
sqlite3_stmt *set_pEp_version;
|
|
sqlite3_stmt *clear_trust_info;
|
|
sqlite3_stmt *set_trust;
|
|
sqlite3_stmt *update_trust;
|
|
sqlite3_stmt *exists_trust_entry;
|
|
sqlite3_stmt *update_trust_to_pEp;
|
|
sqlite3_stmt *update_trust_for_fpr;
|
|
sqlite3_stmt *get_trust;
|
|
sqlite3_stmt *get_trust_by_userid;
|
|
sqlite3_stmt *least_trust;
|
|
sqlite3_stmt *update_key_sticky_bit_for_user;
|
|
sqlite3_stmt *is_key_sticky_for_user;
|
|
sqlite3_stmt *mark_compromised;
|
|
sqlite3_stmt *reset_trust;
|
|
sqlite3_stmt *crashdump;
|
|
sqlite3_stmt *languagelist;
|
|
sqlite3_stmt *i18n_token;
|
|
sqlite3_stmt *replace_userid;
|
|
|
|
// Keys
|
|
sqlite3_stmt *own_key_is_listed;
|
|
sqlite3_stmt *is_own_address;
|
|
sqlite3_stmt *own_identities_retrieve;
|
|
sqlite3_stmt *own_keys_retrieve;
|
|
sqlite3_stmt *key_identities_retrieve;
|
|
sqlite3_stmt *get_user_default_key;
|
|
sqlite3_stmt *get_all_keys_for_user;
|
|
|
|
sqlite3_stmt *get_default_own_userid;
|
|
|
|
// groups
|
|
sqlite3_stmt *create_group;
|
|
sqlite3_stmt *enable_group;
|
|
sqlite3_stmt *disable_group;
|
|
sqlite3_stmt *exists_group_entry;
|
|
sqlite3_stmt *group_add_member;
|
|
sqlite3_stmt *group_delete_member;
|
|
sqlite3_stmt *group_join;
|
|
sqlite3_stmt *leave_group;
|
|
sqlite3_stmt *set_group_member_status;
|
|
sqlite3_stmt *get_all_members;
|
|
sqlite3_stmt *get_active_members;
|
|
sqlite3_stmt *get_active_groups;
|
|
sqlite3_stmt *get_all_groups;
|
|
sqlite3_stmt *add_own_membership_entry;
|
|
sqlite3_stmt *get_own_membership_status;
|
|
sqlite3_stmt *retrieve_own_membership_info_for_group_and_ident;
|
|
sqlite3_stmt *retrieve_own_membership_info_for_group;
|
|
sqlite3_stmt *get_group_manager;
|
|
sqlite3_stmt *is_invited_group_member;
|
|
sqlite3_stmt *is_active_group_member;
|
|
sqlite3_stmt *is_group_active;
|
|
|
|
// sqlite3_stmt *set_own_key;
|
|
|
|
// sequence value
|
|
sqlite3_stmt *sequence_value1;
|
|
sqlite3_stmt *sequence_value2;
|
|
|
|
// revoked keys
|
|
sqlite3_stmt *set_revoked;
|
|
sqlite3_stmt *get_revoked;
|
|
sqlite3_stmt *get_replacement_fpr;
|
|
|
|
// mistrusted
|
|
sqlite3_stmt* add_mistrusted_key;
|
|
sqlite3_stmt* is_mistrusted_key;
|
|
sqlite3_stmt* delete_mistrusted_key;
|
|
|
|
// aliases
|
|
sqlite3_stmt *get_userid_alias_default;
|
|
sqlite3_stmt *add_userid_alias;
|
|
|
|
// callbacks
|
|
notifyHandshake_t notifyHandshake;
|
|
inject_sync_event_t inject_sync_event;
|
|
retrieve_next_sync_event_t retrieve_next_sync_event;
|
|
ensure_passphrase_t ensure_passphrase;
|
|
|
|
// pEp Sync
|
|
void *sync_management;
|
|
void *sync_obj;
|
|
struct Sync_state_s sync_state;
|
|
|
|
// void* sync_state_payload;
|
|
// char sync_uuid[37];
|
|
// time_t LastCannotDecrypt;
|
|
// time_t LastUpdateRequest;
|
|
|
|
// runtime config
|
|
|
|
bool passive_mode;
|
|
bool unencrypted_subject;
|
|
bool service_log;
|
|
|
|
#ifndef NDEBUG
|
|
int debug_color;
|
|
#endif
|
|
};
|
|
|
|
|
|
/**
|
|
* @internal
|
|
* <!-- init_transport_system() -->
|
|
*
|
|
* @brief TODO
|
|
*
|
|
* @param[in] session session handle
|
|
* @param[in] in_first bool
|
|
*
|
|
* @retval PEP_STATUS_OK
|
|
*/
|
|
PEP_STATUS init_transport_system(PEP_SESSION session, bool in_first);
|
|
|
|
/**
|
|
* @internal
|
|
* <!-- release_transport_system() -->
|
|
*
|
|
* @brief TODO
|
|
*
|
|
* @param[in] session session handle
|
|
* @param[in] out_last bool
|
|
*
|
|
*/
|
|
void release_transport_system(PEP_SESSION session, bool out_last);
|
|
|
|
/**
|
|
* @internal
|
|
*
|
|
* <!-- encrypt_only() -->
|
|
*
|
|
* @brief TODO
|
|
*
|
|
* @param[in] session session handle
|
|
* @param[in] keylist const stringlist_t*
|
|
* @param[in] ptext const char*
|
|
* @param[in] psize size_t
|
|
* @param[in] ctext char**
|
|
* @param[in] csize size_t*
|
|
*
|
|
* @warning NOT to be exposed to the outside!!!!!
|
|
*/
|
|
PEP_STATUS encrypt_only(
|
|
PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
|
|
size_t psize, char **ctext, size_t *csize
|
|
);
|
|
|
|
/**
|
|
* @internal
|
|
* <!-- decorate_message() -->
|
|
*
|
|
* @brief TODO
|
|
*
|
|
* @param[in] msg message*
|
|
* @param[in] rating PEP_rating
|
|
* @param[in] keylist stringlist_t*
|
|
* @param[in] add_version bool
|
|
* @param[in] clobber bool
|
|
*
|
|
*/
|
|
void decorate_message(
|
|
PEP_SESSION session,
|
|
message *msg,
|
|
PEP_rating rating,
|
|
stringlist_t *keylist,
|
|
bool add_version,
|
|
bool clobber);
|
|
|
|
#if defined(NDEBUG) || defined(NOLOG)
|
|
#define DEBUG_LOG(TITLE, ENTITY, DESC)
|
|
#else
|
|
#ifdef ANDROID
|
|
#include <android/log.h>
|
|
#define LOG_MORE(...) __android_log_print(ANDROID_LOG_DEBUG, "pEpEngine", " %s :: %s :: %s :: %s ", __VA_ARGS__);
|
|
#else
|
|
#include <stdio.h>
|
|
#define LOG_MORE(...) fprintf(stderr, "pEpEngine DEBUG_LOG('%s','%s','%s','%s')\n", __VA_ARGS__);
|
|
#endif
|
|
#define DEBUG_LOG(TITLE, ENTITY, DESC) {\
|
|
log_event(session, (TITLE), (ENTITY), (DESC), "debug " __FILE__ ":" S_LINE);\
|
|
LOG_MORE((TITLE), (ENTITY), (DESC), __FILE__ ":" S_LINE)\
|
|
}
|
|
#endif
|
|
|
|
/**
|
|
* @internal
|
|
* @enum _normalize_hex_rest_t
|
|
*
|
|
* @brief TODO
|
|
*
|
|
*/
|
|
typedef enum _normalize_hex_rest_t {
|
|
accept_hex,
|
|
ignore_hex,
|
|
reject_hex
|
|
} normalize_hex_res_t;
|
|
|
|
/**
|
|
* @internal
|
|
*
|
|
* <!-- _normalize_hex(char *hex) -->
|
|
*
|
|
* @brief TODO
|
|
*
|
|
* @param[in] hex char*
|
|
*
|
|
* @retval accept_hex
|
|
* @retval irgnore_hex
|
|
* @retval reject_hex
|
|
*/
|
|
|
|
static inline normalize_hex_res_t _normalize_hex(char *hex)
|
|
{
|
|
if (*hex >= '0' && *hex <= '9')
|
|
return accept_hex;
|
|
|
|
if (*hex >= 'A' && *hex <= 'F') {
|
|
*hex += 'a' - 'A';
|
|
return accept_hex;
|
|
}
|
|
|
|
if (*hex >= 'a' && *hex <= 'f')
|
|
return accept_hex;
|
|
|
|
if (*hex == ' ')
|
|
return ignore_hex;
|
|
|
|
return reject_hex;
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
*
|
|
* <!-- _compare_fprs() -->
|
|
*
|
|
* @brief Space tolerant and case insensitive fingerprint string compare
|
|
*
|
|
* @param[in] fpra const char*
|
|
* @param[in] fpras size_t
|
|
* @param[in] fprb const char*
|
|
* @param[in] fprbs size_t
|
|
* @param[in] comparison int*
|
|
*
|
|
* @retval PEP_STATUS_OK
|
|
* @retval PEP_ILLEGAL_VALUE illegal parameter values
|
|
* @retval PEP_TRUSTWORDS_FPR_WRONG_LENGTH
|
|
*/
|
|
static inline PEP_STATUS _compare_fprs(
|
|
const char* fpra,
|
|
size_t fpras,
|
|
const char* fprb,
|
|
size_t fprbs,
|
|
int* comparison)
|
|
{
|
|
|
|
size_t ai = 0;
|
|
size_t bi = 0;
|
|
size_t significant = 0;
|
|
int _comparison = 0;
|
|
const int _FULL_FINGERPRINT_LENGTH = 40;
|
|
|
|
// First compare every non-ignored chars until an end is reached
|
|
while(ai < fpras && bi < fprbs)
|
|
{
|
|
char fprac = fpra[ai];
|
|
char fprbc = fprb[bi];
|
|
normalize_hex_res_t fprah = _normalize_hex(&fprac);
|
|
normalize_hex_res_t fprbh = _normalize_hex(&fprbc);
|
|
|
|
if(fprah == reject_hex || fprbh == reject_hex)
|
|
return PEP_ILLEGAL_VALUE;
|
|
|
|
if ( fprah == ignore_hex )
|
|
{
|
|
ai++;
|
|
}
|
|
else if ( fprbh == ignore_hex )
|
|
{
|
|
bi++;
|
|
}
|
|
else
|
|
{
|
|
if(fprac != fprbc && _comparison == 0 )
|
|
{
|
|
_comparison = fprac > fprbc ? 1 : -1;
|
|
}
|
|
|
|
significant++;
|
|
ai++;
|
|
bi++;
|
|
|
|
}
|
|
}
|
|
|
|
// Bail out if we didn't got enough significnt chars
|
|
if (significant != _FULL_FINGERPRINT_LENGTH )
|
|
return PEP_TRUSTWORDS_FPR_WRONG_LENGTH;
|
|
|
|
// Then purge remaining chars, all must be ignored chars
|
|
while ( ai < fpras )
|
|
{
|
|
char fprac = fpra[ai];
|
|
normalize_hex_res_t fprah = _normalize_hex(&fprac);
|
|
if( fprah == reject_hex )
|
|
return PEP_ILLEGAL_VALUE;
|
|
if ( fprah != ignore_hex )
|
|
return PEP_TRUSTWORDS_FPR_WRONG_LENGTH;
|
|
ai++;
|
|
}
|
|
while ( bi < fprbs )
|
|
{
|
|
char fprbc = fprb[bi];
|
|
normalize_hex_res_t fprbh = _normalize_hex(&fprbc);
|
|
if( fprbh == reject_hex )
|
|
return PEP_ILLEGAL_VALUE;
|
|
if ( fprbh != ignore_hex )
|
|
return PEP_TRUSTWORDS_FPR_WRONG_LENGTH;
|
|
bi++;
|
|
}
|
|
|
|
*comparison = _comparison;
|
|
return PEP_STATUS_OK;
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
*
|
|
* <!-- _same_fpr() -->
|
|
*
|
|
* @brief TODO
|
|
*
|
|
* @param[in] fpra const char*
|
|
* @param[in] fpras size_t
|
|
* @param[in] fprb const char*
|
|
* @param[in] fprbs size_t
|
|
*
|
|
* @retval 0 on equal fingerprints
|
|
* @retval non-zero if not equal
|
|
*/
|
|
static inline int _same_fpr(
|
|
const char* fpra,
|
|
size_t fpras,
|
|
const char* fprb,
|
|
size_t fprbs
|
|
)
|
|
{
|
|
// illegal values are ignored, and considered not same.
|
|
int comparison = 1;
|
|
|
|
_compare_fprs(fpra, fpras, fprb, fprbs, &comparison);
|
|
|
|
return comparison == 0;
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
*
|
|
* <!-- _unsigned_signed_strcmp() -->
|
|
*
|
|
* @brief Compare an unsigned sequence of bytes with the input string.
|
|
*
|
|
* This is really only intended for comparing two full strings.
|
|
* If charstr's length is different from bytestr_size,
|
|
* we'll return a non-zero value.
|
|
*
|
|
* @param[in] bytestr byte string (unsigned char data)
|
|
* @param[in] charstr character string (NUL-terminated)
|
|
* @param[in] bytestr_size length of byte string passed in
|
|
*
|
|
* @retval 0 if equal
|
|
* @retval non-zero if not equal
|
|
*
|
|
*/
|
|
static inline int _unsigned_signed_strcmp(const unsigned char* bytestr, const char* charstr, int bytestr_size) {
|
|
int charstr_len = strlen(charstr);
|
|
if (charstr_len != bytestr_size)
|
|
return -1; // we don't actually care except that it's non-zero
|
|
return memcmp(bytestr, charstr, bytestr_size);
|
|
}
|
|
|
|
// This is just a horrible example of C type madness. UTF-8 made me do it.
|
|
/**
|
|
* @internal
|
|
*
|
|
* <!-- _pEp_subj_copy() -->
|
|
*
|
|
* @brief TODO
|
|
*
|
|
*
|
|
*/
|
|
static inline char* _pEp_subj_copy() {
|
|
#ifndef WIN32
|
|
unsigned char pEpstr[] = PEP_SUBJ_STRING;
|
|
void* retval = calloc(1, sizeof(unsigned char)*PEP_SUBJ_BYTELEN + 1);
|
|
memcpy(retval, pEpstr, PEP_SUBJ_BYTELEN);
|
|
return (char*)retval;
|
|
#else
|
|
return strdup("pEp");
|
|
#endif
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
*
|
|
* <!-- is_me() -->
|
|
*
|
|
* @brief TODO
|
|
*
|
|
* @param[in] session session handle
|
|
* @param[in] test_ident const pEp_identity*
|
|
*
|
|
* @retval true
|
|
* @retval false
|
|
*/
|
|
static inline bool is_me(PEP_SESSION session, const pEp_identity* test_ident) {
|
|
bool retval = false;
|
|
if (test_ident && test_ident->user_id) {
|
|
char* def_id = NULL;
|
|
get_default_own_userid(session, &def_id);
|
|
if (test_ident->me ||
|
|
(def_id && strcmp(def_id, test_ident->user_id) == 0)) {
|
|
retval = true;
|
|
}
|
|
free(def_id);
|
|
}
|
|
return retval;
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
*
|
|
* <!-- pEp_version_numeric() -->
|
|
*
|
|
* @brief
|
|
*
|
|
* @param[in] version_str const char*
|
|
*
|
|
* @retval float version number
|
|
* @retval 0 on failure
|
|
*/
|
|
static inline float pEp_version_numeric(const char* version_str) {
|
|
float retval = 0;
|
|
|
|
if (!version_str || sscanf(version_str, "%f", &retval) != 1)
|
|
return 0;
|
|
|
|
return retval;
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
*
|
|
* <!-- pEp_version_major_minor() -->
|
|
*
|
|
* @brief get major and minor numbers as integers from version string
|
|
*
|
|
* @param[in] version_str const char*
|
|
* @param[out] major unsigned int*
|
|
* @param[out] minor unsigned int*
|
|
*
|
|
*/
|
|
static inline void pEp_version_major_minor(const char* version_str, unsigned int* major, unsigned int* minor) {
|
|
if (!major || !minor)
|
|
return;
|
|
|
|
if (!version_str || sscanf(version_str, "%u.%u", major, minor) != 2) {
|
|
*major = 0;
|
|
*minor = 0;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
*
|
|
* <!-- compare_versions() -->
|
|
*
|
|
* @brief compares two versions by major and minor version numbers
|
|
*
|
|
* @param[in] first_maj unsigned int
|
|
* @param[in] first_min unsigned int
|
|
* @param[in] second_maj unsigned int
|
|
* @param[in] second_min unsigned int
|
|
*
|
|
* @retval 1 when first is higher version
|
|
* @retval -1 when first is lower version
|
|
* @retval 0 when versions are equal
|
|
*/
|
|
static inline int compare_versions(unsigned int first_maj, unsigned int first_min,
|
|
unsigned int second_maj, unsigned int second_min) {
|
|
if (first_maj > second_maj)
|
|
return 1;
|
|
if (first_maj < second_maj)
|
|
return -1;
|
|
if (first_min > second_min)
|
|
return 1;
|
|
if (first_min < second_min)
|
|
return -1;
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
*
|
|
* <!-- set_min_version() -->
|
|
*
|
|
* @brief determine the smaler version from two versions
|
|
*
|
|
* @param[in] first_maj unsigned int
|
|
* @param[in] first_minor unsigned int
|
|
* @param[in] second_maj unsigned int
|
|
* @param[in] second_minor unsigned int
|
|
* @param[out] result_maj unsigned int*
|
|
* @param[out] result_minor unsigned int*
|
|
*
|
|
*/
|
|
static inline void set_min_version(unsigned int first_maj, unsigned int first_minor,
|
|
unsigned int second_maj, unsigned int second_minor,
|
|
unsigned int* result_maj, unsigned int* result_minor) {
|
|
int result = compare_versions(first_maj, first_minor, second_maj, second_minor);
|
|
if (result < 0) {
|
|
*result_maj = first_maj;
|
|
*result_minor = first_minor;
|
|
}
|
|
else {
|
|
*result_maj = second_maj;
|
|
*result_minor = second_minor;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
*
|
|
* <!-- set_max_version() -->
|
|
*
|
|
* @brief determine the greater version out of two versions
|
|
*
|
|
* @param[in] first_maj unsigned int
|
|
* @param[in] first_minor unsigned int
|
|
* @param[in] second_maj unsigned int
|
|
* @param[in] second_minor unsigned int
|
|
* @param[out] result_maj unsigned int*
|
|
* @param[out] result_minor unsigned int*
|
|
*
|
|
*/
|
|
static inline void set_max_version(unsigned int first_maj, unsigned int first_minor,
|
|
unsigned int second_maj, unsigned int second_minor,
|
|
unsigned int* result_maj, unsigned int* result_minor) {
|
|
int result = compare_versions(first_maj, first_minor, second_maj, second_minor);
|
|
if (result > 0) {
|
|
*result_maj = first_maj;
|
|
*result_minor = first_minor;
|
|
}
|
|
else {
|
|
*result_maj = second_maj;
|
|
*result_minor = second_minor;
|
|
}
|
|
}
|
|
|
|
#ifndef EMPTYSTR
|
|
#define EMPTYSTR(STR) ((STR) == NULL || (STR)[0] == '\0')
|
|
#endif
|
|
|
|
#ifndef PASS_ERROR
|
|
#define PASS_ERROR(ST) (ST == PEP_PASSPHRASE_REQUIRED || ST == PEP_WRONG_PASSPHRASE || ST == PEP_PASSPHRASE_FOR_NEW_KEYS_REQUIRED)
|
|
#endif
|
|
|
|
#ifndef IS_PGP_CT
|
|
#define IS_PGP_CT(CT) (((CT) | PEP_ct_confirmed) == PEP_ct_OpenPGP)
|
|
#endif
|
|
|
|
#ifndef _MIN
|
|
#define _MIN(A, B) ((B) > (A) ? (A) : (B))
|
|
#endif
|
|
#ifndef _MAX
|
|
#define _MAX(A, B) ((B) > (A) ? (B) : (A))
|
|
#endif
|
|
|
|
// These are globals used in generating message IDs and should only be
|
|
// computed once, as they're either really constants or OS-dependent
|
|
|
|
extern int _pEp_rand_max_bits;
|
|
extern double _pEp_log2_36;
|
|
|
|
/**
|
|
* <!-- _init_globals() -->
|
|
*
|
|
* @internal
|
|
*
|
|
* @brief TODO
|
|
*
|
|
* Please leave _patch_asn1_codec COMMENTED OUT unless you're working
|
|
* in a branch or patching the asn1 is a solution
|
|
*/
|
|
static inline void _init_globals() {
|
|
_pEp_rand_max_bits = (int) ceil(log2((double) RAND_MAX));
|
|
_pEp_log2_36 = log2(36);
|
|
}
|
|
|
|
|
|
// spinlock implementation
|
|
|
|
/**
|
|
* @internal
|
|
*
|
|
* <!-- Sqlite3_step() -->
|
|
*
|
|
* @brief TODO
|
|
*
|
|
* @param[in] stmt sqlite3_stmt*
|
|
*
|
|
*/
|
|
static inline int Sqlite3_step(sqlite3_stmt* stmt)
|
|
{
|
|
int rc;
|
|
do {
|
|
rc = sqlite3_step(stmt);
|
|
} while (rc == SQLITE_BUSY || rc == SQLITE_LOCKED);
|
|
return rc;
|
|
}
|
|
|
|
/**
|
|
* @internal
|
|
*
|
|
* <!-- _add_auto_consume() -->
|
|
*
|
|
* @brief TODO
|
|
*
|
|
* @param[in] *msg message
|
|
*
|
|
*/
|
|
static inline void _add_auto_consume(message* msg) {
|
|
add_opt_field(msg, "pEp-auto-consume", "yes");
|
|
msg->in_reply_to = stringlist_add(msg->in_reply_to, "pEp-auto-consume@pEp.foundation");
|
|
}
|
|
|
|
|
|
#endif
|