contact_list.h 5.4 KB
Newer Older
1
/*
2
 *  Copyright (C) 2004-2020 Savoir-faire Linux Inc.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
 *
 *  Author: Adrien Béraud <adrien.beraud@savoirfairelinux.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, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
 */
#pragma once

#include "jami_contact.h"
#include "security/certstore.h"

#include <opendht/infohash.h>
#include <opendht/crypto.h>

#include <map>
#include <mutex>
#include <chrono>

namespace jami {

Sébastien Blin's avatar
Sébastien Blin committed
34 35
class ContactList
{
36
public:
37 38
    using clock = std::chrono::system_clock;
    using time_point = clock::time_point;
39 40
    using VerifyResult = dht::crypto::TrustList::VerifyResult;

41
    using OnContactAdded = std::function<void(const std::string&, bool)>;
42
    using OnContactRemoved = std::function<void(const std::string&, bool)>;
Sébastien Blin's avatar
Sébastien Blin committed
43 44
    using OnIncomingTrustRequest
        = std::function<void(const std::string&, const std::vector<uint8_t>&, time_t)>;
45
    using OnDevicesChanged = std::function<void(const std::map<dht::InfoHash, KnownDevice>&)>;
46

Sébastien Blin's avatar
Sébastien Blin committed
47 48
    struct OnChangeCallback
    {
49 50 51 52 53 54
        OnContactAdded contactAdded;
        OnContactRemoved contactRemoved;
        OnIncomingTrustRequest trustRequest;
        OnDevicesChanged devicesChanged;
    };

Sébastien Blin's avatar
Sébastien Blin committed
55 56 57
    ContactList(const std::shared_ptr<crypto::Certificate>& cert,
                const std::string& path,
                OnChangeCallback cb);
58 59 60 61 62 63 64 65 66 67
    ~ContactList();

    void load();
    void save();

    /* Contacts */
    std::map<std::string, std::string> getContactDetails(const dht::InfoHash&) const;
    bool removeContact(const dht::InfoHash&, bool ban);
    bool addContact(const dht::InfoHash&, bool confirmed = false);

Sébastien Blin's avatar
Sébastien Blin committed
68 69 70 71 72
    bool setCertificateStatus(const std::string& cert_id,
                              const tls::TrustStore::PermissionStatus status);
    bool setCertificateStatus(const std::shared_ptr<crypto::Certificate>& cert,
                              tls::TrustStore::PermissionStatus status,
                              bool local = true);
73

Sébastien Blin's avatar
Sébastien Blin committed
74 75
    tls::TrustStore::PermissionStatus getCertificateStatus(const std::string& cert_id) const
    {
76 77 78
        return trust_.getCertificateStatus(cert_id);
    }

Sébastien Blin's avatar
Sébastien Blin committed
79 80
    std::vector<std::string> getCertificatesByStatus(tls::TrustStore::PermissionStatus status) const
    {
81 82 83
        return trust_.getCertificatesByStatus(status);
    }

Sébastien Blin's avatar
Sébastien Blin committed
84 85
    bool isAllowed(const crypto::Certificate& crt, bool allowPublic)
    {
86 87 88
        return trust_.isAllowed(crt, allowPublic);
    }

Sébastien Blin's avatar
Sébastien Blin committed
89 90
    VerifyResult isValidAccountDevice(const crypto::Certificate& crt) const
    {
91 92 93 94 95 96 97 98 99
        return accountTrust_.verify(crt);
    }

    const std::map<dht::InfoHash, Contact>& getContacts() const;
    void setContacts(const std::map<dht::InfoHash, Contact>&);
    void updateContact(const dht::InfoHash&, const Contact&);

    /* Contact requests */

Sébastien Blin's avatar
Sébastien Blin committed
100 101 102 103 104 105 106
    /** Inform of a new contact request. Returns true if the request should be immediatly accepted
     * (already a contact) */
    bool onTrustRequest(const dht::InfoHash& peer_account,
                        const dht::InfoHash& peer_device,
                        time_t received,
                        bool confirm,
                        std::vector<uint8_t>&& payload);
107 108 109 110 111 112
    std::vector<std::map<std::string, std::string>> getTrustRequests() const;
    bool acceptTrustRequest(const dht::InfoHash& from);
    bool discardTrustRequest(const dht::InfoHash& from);

    /* Devices */
    const std::map<dht::InfoHash, KnownDevice>& getKnownDevices() const { return knownDevices_; }
Sébastien Blin's avatar
Sébastien Blin committed
113
    void foundAccountDevice(const dht::InfoHash& device,
114
                            const std::string& name = {},
Sébastien Blin's avatar
Sébastien Blin committed
115 116
                            const time_point& last_sync = time_point::min());
    bool foundAccountDevice(const std::shared_ptr<dht::crypto::Certificate>& crt,
117
                            const std::string& name = {},
Sébastien Blin's avatar
Sébastien Blin committed
118
                            const time_point& last_sync = time_point::min());
119 120
    bool removeAccountDevice(const dht::InfoHash& device);
    void setAccountDeviceName(const dht::InfoHash& device, const std::string& name);
121
    std::string getAccountDeviceName(const dht::InfoHash& device) const;
122 123 124

    DeviceSync getSyncData() const;
    bool syncDevice(const dht::InfoHash& device, const time_point& syncDate);
Sébastien Blin's avatar
Sébastien Blin committed
125
    // void onSyncData(DeviceSync&& device);
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150

private:
    mutable std::mutex lock;
    std::map<dht::InfoHash, Contact> contacts_;
    std::map<dht::InfoHash, TrustRequest> trustRequests_;
    std::map<dht::InfoHash, KnownDevice> knownDevices_;

    // Trust store with account main certificate as the only CA
    dht::crypto::TrustList accountTrust_;
    // Trust store for to match peer certificates
    tls::TrustStore trust_;
    std::string path_;

    OnChangeCallback callbacks_;

    void loadContacts();
    void saveContacts() const;

    void loadTrustRequests();
    void saveTrustRequests() const;

    void loadKnownDevices();
    void saveKnownDevices() const;
};

Sébastien Blin's avatar
Sébastien Blin committed
151
} // namespace jami