sipaccount.h 25.7 KB
Newer Older
yanmorin's avatar
 
yanmorin committed
1
/*
Adrien Béraud's avatar
Adrien Béraud committed
2
 *  Copyright (C) 2004-2015 Savoir-Faire Linux Inc.
3 4
 *
 *  Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
5
 *  Author: Alexandre Bourget <alexandre.bourget@savoirfairelinux.com>
yanmorin's avatar
 
yanmorin committed
6
 *  Author: Yan Morin <yan.morin@savoirfairelinux.com>
7 8
 *  Author: Pierre-Luc Bacon <pierre-luc.bacon@savoirfairelinux.com>
 *
yanmorin's avatar
 
yanmorin committed
9 10
 *  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
11
 *  the Free Software Foundation; either version 3 of the License, or
yanmorin's avatar
 
yanmorin committed
12
 *  (at your option) any later version.
Julien Bonjean's avatar
Julien Bonjean committed
13
 *
yanmorin's avatar
 
yanmorin committed
14 15 16 17
 *  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.
Julien Bonjean's avatar
Julien Bonjean committed
18
 *
yanmorin's avatar
 
yanmorin committed
19 20
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
21
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.
22 23 24 25 26 27 28 29 30 31 32
 *
 *  Additional permission under GNU GPL version 3 section 7:
 *
 *  If you modify this program, or any covered work, by linking or
 *  combining it with the OpenSSL project's OpenSSL library (or a
 *  modified version of that library), containing parts covered by the
 *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
 *  grants you additional permission to convey the resulting work.
 *  Corresponding Source for a non-source form of such a combination
 *  shall include the source code for the parts of OpenSSL used as well
 *  as that of the covered work.
yanmorin's avatar
 
yanmorin committed
33
 */
34

yanmorin's avatar
 
yanmorin committed
35 36 37
#ifndef SIPACCOUNT_H
#define SIPACCOUNT_H

38 39 40
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
41

42
#include "sipaccountbase.h"
43
#include "siptransport.h"
44
#include "noncopyable.h"
45
#include "ring_types.h" // enable_if_base_of
46 47 48 49 50 51 52 53

#include <pjsip/sip_transport_tls.h>
#include <pjsip/sip_types.h>
#include <pjsip-ua/sip_regc.h>

#include <vector>
#include <map>

Guillaume Roguez's avatar
Guillaume Roguez committed
54 55 56 57 58 59
namespace YAML {
    class Node;
    class Emitter;
}

namespace ring {
60

61
namespace Conf {
62
    const char *const KEEP_ALIVE_ENABLED = "keepAlive";
Adrien Béraud's avatar
Adrien Béraud committed
63 64 65 66 67 68 69 70 71 72 73 74 75

    // TODO: write an object to store credential which implement serializable
    const char *const SRTP_KEY = "srtp";
    const char *const SRTP_ENABLE_KEY = "enable";
    const char *const KEY_EXCHANGE_KEY = "keyExchange";
    const char *const RTP_FALLBACK_KEY = "rtpFallback";

    // TODO: wirte an object to store zrtp params wich implement serializable
    const char *const ZRTP_KEY = "zrtp";
    const char *const DISPLAY_SAS_KEY = "displaySas";
    const char *const DISPLAY_SAS_ONCE_KEY = "displaySasOnce";
    const char *const HELLO_HASH_ENABLED_KEY = "helloHashEnabled";
    const char *const NOT_SUPP_WARNING_KEY = "notSuppWarning";
76
}
77

Guillaume Roguez's avatar
Guillaume Roguez committed
78
typedef std::vector<pj_ssl_cipher> CipherArray;
Tristan Matthews's avatar
Tristan Matthews committed
79

80
class SIPPresence;
81
class SIPCall;
82

yanmorin's avatar
 
yanmorin committed
83
/**
84
 * @file sipaccount.h
85
 * @brief A SIP Account specify SIP specific functions and object = SIPCall/SIPVoIPLink)
86
 */
87
class SIPAccount : public SIPAccountBase {
88
    public:
89 90
        constexpr static const char * const IP2IP_PROFILE = "IP2IP";
        constexpr static const char * const ACCOUNT_TYPE = "SIP";
91

92 93 94 95
        /**
         * Constructor
         * @param accountID The account identifier
         */
96
        SIPAccount(const std::string& accountID, bool presenceEnabled);
Guillaume Roguez's avatar
Guillaume Roguez committed
97

98
        ~SIPAccount();
Yun Liu's avatar
Yun Liu committed
99

Alexandre Lision's avatar
Alexandre Lision committed
100
        const char* getAccountType() const override {
101 102 103
            return ACCOUNT_TYPE;
        }

104 105
        pjsip_host_port getHostPortFromSTUN(pj_pool_t *pool);

106
        std::string getUserAgentName() const;
107 108 109
        void setRegistrationStateDetailed(const std::pair<int, std::string> &details) {
            registrationStateDetailed_ = details;
        }
110

111 112
        void updateDialogViaSentBy(pjsip_dialog *dlg);

113 114 115
        void resetAutoRegistration();
        bool checkNATAddress(pjsip_regc_cbparam *param, pj_pool_t *pool);

116 117 118
        /**
         * Returns true if this is the IP2IP account
         */
Alexandre Lision's avatar
Alexandre Lision committed
119
        bool isIP2IP() const override;
120

121 122
        /**
         * Serialize internal state of this account for configuration
Tristan Matthews's avatar
Tristan Matthews committed
123
         * @param out Emitter to which state will be saved
124
         */
Alexandre Lision's avatar
Alexandre Lision committed
125
        virtual void serialize(YAML::Emitter &out) override;
126

127 128 129 130
        /**
         * Populate the internal state for this account based on info stored in the configuration file
         * @param The configuration node for this account
         */
Alexandre Lision's avatar
Alexandre Lision committed
131
        virtual void unserialize(const YAML::Node &node) override;
132

133 134 135 136 137
        /**
         * Return an map containing the internal state of this account. Client application can use this method to manage
         * account info.
         * @return A map containing the account information.
         */
Alexandre Lision's avatar
Alexandre Lision committed
138
        virtual std::map<std::string, std::string> getAccountDetails() const override;
139

140 141 142 143
        /**
         * Retrieve volatile details such as recent registration errors
         * @return std::map< std::string, std::string > The account volatile details
         */
Alexandre Lision's avatar
Alexandre Lision committed
144
        virtual std::map<std::string, std::string> getVolatileAccountDetails() const override;
145

146 147 148
        /**
         * Return the information for the default IP to IP account
         */
149
        std::map<std::string, std::string> getIp2IpDetails() const;
150 151 152 153 154

        /**
         * Return the TLS settings, mainly used to return security information to
         * a client application
         */
155
        std::map<std::string, std::string> getTlsSettings() const;
156

Julien Bonjean's avatar
Julien Bonjean committed
157 158
        /**
         * Actually useless, since config loading is done in init()
159
         */
Alexandre Lision's avatar
Alexandre Lision committed
160
        void loadConfig() override;
yanmorin's avatar
 
yanmorin committed
161

162 163
        /**
         * Initialize the SIP voip link with the account parameters and send registration
Julien Bonjean's avatar
Julien Bonjean committed
164
         */
Alexandre Lision's avatar
Alexandre Lision committed
165
        void doRegister() override;
166

167
        /**
168
         * Send unregistration.
169
         */
Alexandre Lision's avatar
Alexandre Lision committed
170
        void doUnregister(std::function<void(bool)> cb = std::function<void(bool)>()) override;
171

172 173 174 175 176 177 178 179 180 181 182
        /**
         * Start the keep alive function, once started, the account will be registered periodically
         * a new REGISTER request is sent bey the client application. The account must be initially
         * registered for this call to be effective.
         */
        void startKeepAliveTimer();

        /**
         * Stop the keep alive timer. Once canceled, no further registration will be scheduled
         */
        void stopKeepAliveTimer();
183

184 185 186 187 188 189 190 191 192
        /**
         * Build and send SIP registration request
         */
        void sendRegister();

        /**
         * Build and send SIP unregistration request
         * @param destroy_transport If true, attempt to destroy the transport.
         */
Adrien Béraud's avatar
Adrien Béraud committed
193
        void sendUnregister();
194

195
        const pjsip_cred_info* getCredInfo() const {
196
            return cred_.data();
Julien Bonjean's avatar
Julien Bonjean committed
197 198
        }

199 200 201 202 203 204
        /**
         * Get the number of credentials defined for
         * this account.
         * @param none
         * @return int The number of credentials set for this account.
         */
205
        unsigned getCredentialCount() const {
206 207 208
            return credentials_.size();
        }

209 210 211 212
        bool hasCredentials() const {
            return not credentials_.empty();
        }

213
        void setCredentials(const std::vector<std::map<std::string, std::string> >& details);
214

215
        std::vector<std::map<std::string, std::string>>
216
        getCredentials() const;
217

218
        virtual void setRegistrationState(RegistrationState state, unsigned code=0, const std::string& detail_str={}) override;
219

Julien Bonjean's avatar
Julien Bonjean committed
220 221 222 223 224
        /**
         * A client sendings a REGISTER request MAY suggest an expiration
         * interval that indicates how long the client would like the
         * registration to be valid.
         *
Rafaël Carré's avatar
Rafaël Carré committed
225
         * @return the expiration value.
Julien Bonjean's avatar
Julien Bonjean committed
226
         */
227
        unsigned getRegistrationExpire() const {
228 229 230 231
            if (registrationExpire_ == 0)
                return PJSIP_REGC_EXPIRATION_NOT_SPECIFIED;

            return registrationExpire_;
Julien Bonjean's avatar
Julien Bonjean committed
232 233
        }

234
        /**
235
         * Set the expiration for this account as found in
236
         * the "Expire" sip header or the CONTACT's "expire" param.
237 238
         */
        void setRegistrationExpire(int expire) {
239
            if (expire > 0)
240 241 242
                registrationExpire_ = expire;
        }

Julien Bonjean's avatar
Julien Bonjean committed
243
        /**
244
         * Doubles the Expiration Interval sepecified for registration.
Julien Bonjean's avatar
Julien Bonjean committed
245
         */
246
        void doubleRegistrationExpire() {
247 248 249 250
            registrationExpire_ *= 2;

            if (registrationExpire_ < 0)
                registrationExpire_ = 0;
Julien Bonjean's avatar
Julien Bonjean committed
251 252
        }

253 254
        /**
         * Registration flag
255
         */
256
        bool isRegistered() const {
257
            return bRegister_;
Julien Bonjean's avatar
Julien Bonjean committed
258
        }
259

260
        /**
261 262
         * Set registration flag
         */
263
        void setRegister(bool result) {
264
            bRegister_ = result;
Julien Bonjean's avatar
Julien Bonjean committed
265 266
        }

267 268 269 270 271 272
        /**
         * Get the registration stucture that is used
         * for PJSIP in the registration process.
         * Settings are loaded from configuration file.
         * @return pjsip_regc* A pointer to the registration structure
         */
273
        pjsip_regc* getRegistrationInfo() {
274
            return regc_;
275 276 277 278 279 280 281 282
        }

        /**
         * Set the registration structure that is used
         * for PJSIP in the registration process;
         * @pram A pointer to the new registration structure
         * @return void
         */
283
        void setRegistrationInfo(pjsip_regc *regc) {
284
            if (regc_) destroyRegistrationInfo();
285
            regc_ = regc;
286 287
        }

288 289
        void destroyRegistrationInfo();

290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306
        /**
         * Get the port on which the transport/listener should use, or is
         * actually using.
         * @return pj_uint16 The port used for that account
         */
        pj_uint16_t getLocalPort() const {
            return localPort_;
        }

        /**
         * Set the new port on which this account is running over.
         * @pram port The port used by this account.
         */
        void setLocalPort(pj_uint16_t port) {
            localPort_ = port;
        }

307 308
        /**
         * @return pjsip_tls_setting structure, filled from the configuration
Julien Bonjean's avatar
Julien Bonjean committed
309
         * file, that can be used directly by PJSIP to initialize
310 311
         * TLS transport.
         */
312
        pjsip_tls_setting * getTlsSetting() {
313
            return &tlsSetting_;
Julien Bonjean's avatar
Julien Bonjean committed
314 315
        }

316 317 318 319 320 321 322 323
        /**
         * Get the local port for TLS listener.
         * @return pj_uint16 The port used for that account
         */
        pj_uint16_t getTlsListenerPort() const {
            return tlsListenerPort_;
        }

Alexandre Lision's avatar
Alexandre Lision committed
324
        pj_str_t getStunServerName() const override {
325
            return stunServerName_;
Julien Bonjean's avatar
Julien Bonjean committed
326
        }
327

328 329
        static const std::vector<std::string>& getSupportedTlsCiphers();
        static const std::vector<std::string>& getSupportedTlsProtocols();
330

Julien Bonjean's avatar
Julien Bonjean committed
331
        /**
332
         * @return pj_uint8_t structure, filled from the configuration
Julien Bonjean's avatar
Julien Bonjean committed
333
         * file, that can be used directly by PJSIP to initialize
334 335
         * an alternate UDP transport.
         */
Alexandre Lision's avatar
Alexandre Lision committed
336
        pj_uint16_t getStunPort() const override {
337
            return stunPort_;
Julien Bonjean's avatar
Julien Bonjean committed
338 339 340
        }

        /**
341 342 343
         * @return bool Tells if current transport for that
         * account is set to OTHER.
         */
Alexandre Lision's avatar
Alexandre Lision committed
344
        bool isStunEnabled() const override {
345
            return stunEnabled_;
Julien Bonjean's avatar
Julien Bonjean committed
346
        }
347

348
        /**
349 350 351 352 353 354 355 356
         * @return pj_str_t "From" uri based on account information.
         * From RFC3261: "The To header field first and foremost specifies the desired
         * logical" recipient of the request, or the address-of-record of the
         * user or resource that is the target of this request. [...]  As such, it is
         * very important that the From URI not contain IP addresses or the FQDN
         * of the host on which the UA is running, since these are not logical
         * names."
         */
357
        std::string getFromUri() const;
Julien Bonjean's avatar
Julien Bonjean committed
358

359
        /**
360 361
         * This method adds the correct scheme, hostname and append
         * the ;transport= parameter at the end of the uri, in accordance with RFC3261.
362
         * It is expected that "port" is present in the internal hostname_.
363 364 365 366
         *
         * @return pj_str_t "To" uri based on @param username
         * @param username A string formatted as : "username"
         */
Alexandre Lision's avatar
Alexandre Lision committed
367
        std::string getToUri(const std::string& username) const override;
368

369
        /**
370
         * In the current version of Ring, "srv" uri is obtained in the preformated
371 372 373 374 375 376
         * way: hostname:port. This method adds the correct scheme and append
         * the ;transport= parameter at the end of the uri, in accordance with RFC3261.
         *
         * @return pj_str_t "server" uri based on @param hostPort
         * @param hostPort A string formatted as : "hostname:port"
         */
377
        std::string getServerUri() const;
Julien Bonjean's avatar
Julien Bonjean committed
378

379
        /**
380
         * Get the contact header for
381 382
         * @return pj_str_t The contact header based on account information
         */
Alexandre Lision's avatar
Alexandre Lision committed
383
        pj_str_t getContactHeader(pjsip_transport* = nullptr) override;
384

385

386
        std::string getServiceRoute() const {
387
            return serviceRoute_;
Julien Bonjean's avatar
Julien Bonjean committed
388
        }
389

390 391
        bool hasServiceRoute() const { return not serviceRoute_.empty(); }

Alexandre Lision's avatar
Alexandre Lision committed
392
        virtual bool isTlsEnabled() const override {
Adrien Béraud's avatar
Adrien Béraud committed
393 394 395
            return tlsEnable_;
        }

Alexandre Lision's avatar
Alexandre Lision committed
396
        virtual sip_utils::KeyExchangeProtocol getSrtpKeyExchange() const override {
397
            return srtpKeyExchange_;
Adrien Béraud's avatar
Adrien Béraud committed
398 399
        }

Alexandre Lision's avatar
Alexandre Lision committed
400
        virtual bool getSrtpFallback() const override {
Adrien Béraud's avatar
Adrien Béraud committed
401 402
            return srtpFallback_;
        }
Julien Bonjean's avatar
Julien Bonjean committed
403

404
        bool getZrtpHelloHash() const {
405
            return zrtpHelloHash_;
Julien Bonjean's avatar
Julien Bonjean committed
406 407
        }

Tristan Matthews's avatar
Tristan Matthews committed
408
        void setReceivedParameter(const std::string &received) {
409
            receivedParameter_ = received;
410 411
            via_addr_.host.ptr = (char *) receivedParameter_.c_str();
            via_addr_.host.slen = receivedParameter_.size();
412 413
        }

Tristan Matthews's avatar
Tristan Matthews committed
414
        std::string getReceivedParameter() const {
415 416 417
            return receivedParameter_;
        }

418 419 420 421 422
        pjsip_host_port *
        getViaAddr() {
            return &via_addr_;
        }

423 424 425 426 427 428 429
        int getRPort() const {
            if (rPort_ == -1)
                return localPort_;
            else
                return rPort_;
        }

430 431 432 433
        void setRPort(int rPort) {
            rPort_ = rPort;
            via_addr_.port = rPort;
        }
434

435 436 437 438 439 440
        /**
         * Timer used to periodically send re-register request based
         * on the "Expire" sip header (or the "expire" Contact parameter)
         */
        static void keepAliveRegistrationCb(pj_timer_heap_t *th, pj_timer_entry *te);

441 442 443 444
        bool isKeepAliveEnabled() const {
            return keepAliveEnabled_;
        }

445 446 447 448 449 450 451 452 453 454 455 456 457 458
        void setTransport(const std::shared_ptr<SipTransport>& = nullptr);

        virtual inline std::shared_ptr<SipTransport> getTransport() {
            return transport_;
        }

        inline pjsip_transport_type_e getTransportType() const {
            return transportType_;
        }

        /**
         * Shortcut for SipTransport::getTransportSelector(account.getTransport()).
         */
        pjsip_tpselector getTransportSelector();
459

460
        /* Returns true if the username and/or hostname match this account */
461
        MatchRank matches(const std::string &username, const std::string &hostname, pjsip_endpoint *endpt, pj_pool_t *pool) const;
462

463 464 465
        /**
         * Presence management
         */
466 467
        SIPPresence * getPresence() const;

468 469 470 471 472
        /**
         * Activate the module.
         * @param function Publish or subscribe to enable
         * @param enable Flag
         */
473 474 475 476 477
        void enablePresence(const bool& enable);
        /**
         * Activate the publish/subscribe.
         * @param enable Flag
         */
Tristan Matthews's avatar
Tristan Matthews committed
478
        void supportPresence(int function, bool enable);
479

480 481
        void scheduleReregistration(pjsip_endpoint *endpt);

Guillaume Roguez's avatar
Guillaume Roguez committed
482 483 484 485
        /**
         * Implementation of Account::newOutgoingCall()
         * Note: keep declaration before newOutgoingCall template.
         */
Alexandre Lision's avatar
Alexandre Lision committed
486
        std::shared_ptr<Call> newOutgoingCall(const std::string& toUrl) override;
Guillaume Roguez's avatar
Guillaume Roguez committed
487 488 489 490 491 492 493 494 495 496

        /**
         * Create outgoing SIPCall.
         * @param[in] toUrl The address to call
         * @return std::shared_ptr<T> A shared pointer on the created call.
         *      The type of this instance is given in template argument.
         *      This type can be any base class of SIPCall class (included).
         */
        template <class T=SIPCall>
        std::shared_ptr<enable_if_base_of<T, SIPCall> >
497
        newOutgoingCall(const std::string& toUrl);
Guillaume Roguez's avatar
Guillaume Roguez committed
498 499 500

        /**
         * Create incoming SIPCall.
501
         * @param[in] from The origin uri of the call
Guillaume Roguez's avatar
Guillaume Roguez committed
502 503 504 505
         * @return std::shared_ptr<T> A shared pointer on the created call.
         *      The type of this instance is given in template argument.
         *      This type can be any base class of SIPCall class (included).
         */
506
        std::shared_ptr<SIPCall>
Alexandre Lision's avatar
Alexandre Lision committed
507
        newIncomingCall(const std::string& from) override;
Guillaume Roguez's avatar
Guillaume Roguez committed
508

509 510
        void onRegister(pjsip_regc_cbparam *param);

Alexandre Lision's avatar
Alexandre Lision committed
511
        virtual void sendTextMessage(const std::string& /* to */, const std::string& /* message */) override;
512

Julien Bonjean's avatar
Julien Bonjean committed
513
    private:
Stepan Salenikovich's avatar
Stepan Salenikovich committed
514 515
        void doRegister1_();
        void doRegister2_();
516

517 518 519 520
        /**
         * Set the internal state for this account, mainly used to manage account details from the client application.
         * @param The map containing the account information.
         */
Alexandre Lision's avatar
Alexandre Lision committed
521
        void setAccountDetails(const std::map<std::string, std::string> &details) override;
522

523
        NON_COPYABLE(SIPAccount);
Julien Bonjean's avatar
Julien Bonjean committed
524

525 526 527 528 529 530 531 532 533 534
        std::shared_ptr<Call> newRegisteredAccountCall(const std::string& id,
                                                       const std::string& toUrl);

        /**
         * Start a SIP Call
         * @param call  The current call
         * @return true if all is correct
         */
        bool SIPStartCall(std::shared_ptr<SIPCall>& call);

535
        void usePublishedAddressPortInVIA();
Stepan Salenikovich's avatar
Stepan Salenikovich committed
536
        void useUPnPAddressPortInVIA();
537
        bool fullMatch(const std::string &username, const std::string &hostname, pjsip_endpoint *endpt, pj_pool_t *pool) const;
538
        bool userMatch(const std::string &username) const;
539 540
        bool hostnameMatch(const std::string &hostname, pjsip_endpoint *endpt, pj_pool_t *pool) const;
        bool proxyMatch(const std::string &hostname, pjsip_endpoint *endpt, pj_pool_t *pool) const;
541

542 543 544 545
        bool isSrtpEnabled() const {
            return srtpKeyExchange_ != sip_utils::KeyExchangeProtocol::NONE;
        }

546 547 548 549 550 551
        /**
         * Callback called by the transport layer when the registration
         * transport state changes.
         */
        virtual void onTransportStateChanged(pjsip_transport_state state, const pjsip_transport_state_info *info);

552 553 554 555 556 557 558
        struct {
            pj_bool_t    active;    /**< Flag of reregister status. */
            pj_timer_entry   timer;     /**< Timer for reregistration.  */
            void        *reg_tp;    /**< Transport for registration.    */
            unsigned     attempt_cnt; /**< Attempt counter.     */
        } auto_rereg_;           /**< Reregister/reconnect data. */

Adrien Béraud's avatar
Adrien Béraud committed
559 560 561
        std::uniform_int_distribution<decltype(pj_time_val::msec)> delay10ZeroDist_ {-10000, 10000};
        std::uniform_int_distribution<decltype(pj_time_val::msec)> delay10PosDist_ {0, 10000};

562 563
        static void autoReregTimerCb(pj_timer_heap_t *th, pj_timer_entry *te);

564
        /**
Tristan Matthews's avatar
Tristan Matthews committed
565
         * Map of credential for this account
566
         */
567 568 569 570 571 572 573 574 575 576
        struct Credentials {
            std::string realm {};
            std::string username {};
            std::string password {};
            std::string password_h {};
            Credentials(const std::string& r, const std::string& u, const std::string& p)
             : realm(r), username(u), password(p) {}
            void computePasswordHash();
        };
        std::vector<Credentials> credentials_;
577

578 579 580 581 582 583 584 585 586 587 588 589
        std::shared_ptr<SipTransport> transport_ {};

        std::shared_ptr<TlsListener> tlsListener_ {};

        /**
         * Transport type used for this sip account. Currently supported types:
         *    PJSIP_TRANSPORT_UNSPECIFIED
         *    PJSIP_TRANSPORT_UDP
         *    PJSIP_TRANSPORT_TLS
         */
        pjsip_transport_type_e transportType_ {PJSIP_TRANSPORT_UNSPECIFIED};

590
#if HAVE_TLS
591

Tristan Matthews's avatar
Tristan Matthews committed
592
        /**
593
         * Maps a string description of the SSL method
594
         * to the corresponding enum value in pjsip_ssl_method.
Julien Bonjean's avatar
Julien Bonjean committed
595
         * @param method The string representation
596 597
         * @return pjsip_ssl_method The corresponding value in the enum
         */
598
        static pj_uint32_t tlsProtocolFromString(const std::string& method);
Julien Bonjean's avatar
Julien Bonjean committed
599

600
        /**
601
         * Initializes tls settings from configuration file.
Julien Bonjean's avatar
Julien Bonjean committed
602
         */
603
        void initTlsConfiguration();
Julien Bonjean's avatar
Julien Bonjean committed
604

605
        /**
606 607
         * PJSIP aborts if the string length of our cipher list is too
         * great, so this function forces our cipher list to fit this constraint.
608
         */
609
        void trimCiphers();
610

611
#endif
612

613
        /**
Julien Bonjean's avatar
Julien Bonjean committed
614 615
         * Initializes STUN config from the config file
         */
616
        void initStunConfiguration();
Julien Bonjean's avatar
Julien Bonjean committed
617

618
        /**
Julien Bonjean's avatar
Julien Bonjean committed
619 620 621
         * If username is not provided, as it happens for Direct ip calls,
         * fetch the Real Name field of the user that is currently
         * running this program.
622
         * @return std::string The login name under which Ring is running.
Julien Bonjean's avatar
Julien Bonjean committed
623
         */
624
        static std::string getLoginName();
Julien Bonjean's avatar
Julien Bonjean committed
625

Stepan Salenikovich's avatar
Stepan Salenikovich committed
626 627 628 629 630
        /**
         * Maps require port via UPnP
         */
        bool mapPortUPnP();

631 632 633 634 635
        /**
         * Resolved IP of hostname_ (for registration)
         */
        IpAddr hostIp_;

636 637
        /**
         * The pjsip client registration information
638
         */
639
        pjsip_regc *regc_;
640 641

        /**
642
         * To check if the account is registered
643
         */
644
        bool bRegister_;
645

Tristan Matthews's avatar
Tristan Matthews committed
646
        /**
647 648
         * Network settings
         */
Rafaël Carré's avatar
Rafaël Carré committed
649
        int registrationExpire_;
650

651
        /**
Tristan Matthews's avatar
Tristan Matthews committed
652
         * Optional list of SIP service this
653
         */
654
        std::string serviceRoute_;
655

656
        /**
657
         * Credential information stored for further registration.
658
         * Points to credentials_ members.
659
         */
660
        std::vector<pjsip_cred_info> cred_;
661

662 663 664
        /**
         * The TLS settings, used only if tls is chosen as a sip transport.
         */
665
        pjsip_tls_setting tlsSetting_;
666

667
        /**
Tristan Matthews's avatar
Tristan Matthews committed
668
         * Allocate a vector to be used by pjsip to store the supported ciphers on this system.
669
         */
670
        CipherArray ciphers_;
671

672
        /**
673
         * The STUN server name (hostname)
674
         */
675
        pj_str_t stunServerName_ {nullptr, 0};
676

677
        /**
678
         * The STUN server port
679
         */
680 681
        pj_uint16_t stunPort_ {PJ_STUN_PORT};

682 683 684 685 686 687 688 689 690 691
        /**
         * Local port to whih this account is bound
         */
        pj_uint16_t localPort_ {sip_utils::DEFAULT_SIP_PORT};

        /**
         * The TLS listener port
         */
        pj_uint16_t tlsListenerPort_ {sip_utils::DEFAULT_SIP_TLS_PORT};

Adrien Béraud's avatar
Adrien Béraud committed
692
        bool tlsEnable_ {false};
693 694 695 696 697 698 699 700
        std::string tlsMethod_;
        std::string tlsCiphers_;
        std::string tlsServerName_;
        bool tlsVerifyServer_;
        bool tlsVerifyClient_;
        bool tlsRequireClientCertificate_;
        std::string tlsNegotiationTimeoutSec_;

Adrien Béraud's avatar
Adrien Béraud committed
701
        /**
702 703
         * Specifies the type of key exchange used for SRTP  (sdes/zrtp), if any.
         * This only determine if the media channel is secured.
Adrien Béraud's avatar
Adrien Béraud committed
704
         */
705
        sip_utils::KeyExchangeProtocol srtpKeyExchange_ {sip_utils::KeyExchangeProtocol::NONE};
Adrien Béraud's avatar
Adrien Béraud committed
706 707 708 709 710 711 712 713

        /**
         * Determine if the softphone should fallback on non secured media channel if SRTP negotiation fails.
         * Make sure other SIP endpoints share the same behavior since it could result in encrypted data to be
         * played through the audio device.
         */
        bool srtpFallback_ {};

714 715 716 717
        /**
         * Determine if the SAS sould be displayed on client side. SAS is a 4-charcter string
         * that end users should verbaly validate to ensure the channel is secured. Used especially
         * to prevent man-in-the-middle attack.
718
         */
719
        bool zrtpDisplaySas_;
720 721 722 723

        /**
         * Only display SAS 4-character string once at the begining of the call.
         */
724
        bool zrtpDisplaySasOnce_;
725

726 727
        bool zrtpHelloHash_;
        bool zrtpNotSuppWarning_;
728 729 730 731 732

        /**
         * Details about the registration state.
         * This is a protocol Code:Description pair.
         */
733
        std::pair<int, std::string> registrationStateDetailed_;
734

735 736 737 738 739
        /**
         * Determine if the keep alive timer will be activated or not
         */
        bool keepAliveEnabled_;

740 741 742
        /**
         * Timer used to regularrly send re-register request based
         * on the "Expire" sip header (or the "expire" Contact parameter)
743
         */
744
        pj_timer_entry keepAliveTimer_;
Adrien Béraud's avatar
Adrien Béraud committed
745
        std::uniform_int_distribution<decltype(pj_timer_entry::id)> timerIdDist_ {};
746

747 748 749 750 751
        /**
         * Once enabled, this variable tells if the keepalive timer is activated
         * for this accout
         */
        bool keepAliveTimerActive_;
752

753
        /**
754
         * Optional: "received" parameter from VIA header
755 756
         */
        std::string receivedParameter_;
757 758 759 760 761

        /**
         * Optional: "rport" parameter from VIA header
         */
        int rPort_;
762 763 764 765 766

        /**
         * Optional: via_addr construct from received parameters
         */
        pjsip_host_port via_addr_;
767

768 769 770 771 772 773
        /**
         * Temporary storage for getUPnPIpAddress().toString()
         * Used only by useUPnPAddressPortInVIA().
         */
        std::string upnpIpAddr_;

774
        char contactBuffer_[PJSIP_MAX_URL_SIZE];
775 776 777
        pj_str_t contact_;
        int contactRewriteMethod_;
        bool allowViaRewrite_;
778 779
        /* Undocumented feature in pjsip, this can == 2 */
        int allowContactRewrite_;
780
        bool contactOverwritten_;
781 782
        pjsip_transport *via_tp_;

783 784 785 786
        /**
         * Presence data structure
         */
        SIPPresence * presence_;
Stepan Salenikovich's avatar
Stepan Salenikovich committed
787 788 789 790 791 792 793

        /**
         * SIP port actually used,
         * this holds the actual port used for SIP, which may not be the port
         * selected in the configuration in the case that UPnP is used and the
         * configured port is already used by another client
         */
794
        pj_uint16_t publishedPortUsed_ {sip_utils::DEFAULT_SIP_PORT};
yanmorin's avatar
 
yanmorin committed
795 796
};

Guillaume Roguez's avatar
Guillaume Roguez committed
797 798
} // namespace ring

yanmorin's avatar
 
yanmorin committed
799
#endif