diff --git a/src/certificate.h b/src/certificate.h index 51f5cb2a5fac1b1d28937184159804c3abd853ec..a665939540cfcde1092bc5093d308e8911f6c331 100644 --- a/src/certificate.h +++ b/src/certificate.h @@ -93,27 +93,27 @@ public: * */ enum class Checks { - HAS_PRIVATE_KEY , /** This certificate has a build in private key */ - EXPIRED , /** This certificate is past its expiration date */ - STRONG_SIGNING , /** This certificate has been signed with a brute-force-able method */ - NOT_SELF_SIGNED , /** This certificate has been self signed */ - KEY_MATCH , /** The public and private keys provided don't match */ - PRIVATE_KEY_STORAGE_PERMISSION , /** The file hosting the private key isn't correctly secured */ - PUBLIC_KEY_STORAGE_PERMISSION , /** The file hosting the public key isn't correctly secured */ - PRIVATE_KEY_DIRECTORY_PERMISSIONS , /** The folder storing the private key isn't correctly secured */ - PUBLIC_KEY_DIRECTORY_PERMISSIONS , /** The folder storing the public key isn't correctly secured */ - PRIVATE_KEY_STORAGE_LOCATION , /** Some operating systems have extra policies for certificate storage */ - PUBLIC_KEY_STORAGE_LOCATION , /** Some operating systems have extra policies for certificate storage */ - PRIVATE_KEY_SELINUX_ATTRIBUTES , /** Some operating systems require keys to have extra attributes */ - PUBLIC_KEY_SELINUX_ATTRIBUTES , /** Some operating systems require keys to have extra attributes */ - EXIST , /** The certificate file doesn't exist or is not accessible */ - VALID , /** The file is not a certificate */ - VALID_AUTHORITY , /** The claimed authority did not sign the certificate */ - KNOWN_AUTHORITY , /** Some operating systems provide a list of trusted authorities, use it */ - NOT_REVOKED , /** The certificate has been revoked by the authority */ - AUTHORITY_MATCH , /** The certificate and authority mismatch */ - EXPECTED_OWNER , /** The certificate has an expected owner */ - ACTIVATED , /** The certificate has not been activated yet */ + HAS_PRIVATE_KEY , /*!< This certificate has a build in private key */ + EXPIRED , /*!< This certificate is past its expiration date */ + STRONG_SIGNING , /*!< This certificate has been signed with a brute-force-able method */ + NOT_SELF_SIGNED , /*!< This certificate has been self signed */ + KEY_MATCH , /*!< The public and private keys provided don't match */ + PRIVATE_KEY_STORAGE_PERMISSION , /*!< The file hosting the private key isn't correctly secured */ + PUBLIC_KEY_STORAGE_PERMISSION , /*!< The file hosting the public key isn't correctly secured */ + PRIVATE_KEY_DIRECTORY_PERMISSIONS , /*!< The folder storing the private key isn't correctly secured */ + PUBLIC_KEY_DIRECTORY_PERMISSIONS , /*!< The folder storing the public key isn't correctly secured */ + PRIVATE_KEY_STORAGE_LOCATION , /*!< Some operating systems have extra policies for certificate storage */ + PUBLIC_KEY_STORAGE_LOCATION , /*!< Some operating systems have extra policies for certificate storage */ + PRIVATE_KEY_SELINUX_ATTRIBUTES , /*!< Some operating systems require keys to have extra attributes */ + PUBLIC_KEY_SELINUX_ATTRIBUTES , /*!< Some operating systems require keys to have extra attributes */ + EXIST , /*!< The certificate file doesn't exist or is not accessible */ + VALID , /*!< The file is not a certificate */ + VALID_AUTHORITY , /*!< The claimed authority did not sign the certificate */ + KNOWN_AUTHORITY , /*!< Some operating systems provide a list of trusted authorities, use it */ + NOT_REVOKED , /*!< The certificate has been revoked by the authority */ + AUTHORITY_MATCH , /*!< The certificate and authority mismatch */ + EXPECTED_OWNER , /*!< The certificate has an expected owner */ + ACTIVATED , /*!< The certificate has not been activated yet */ COUNT__, }; @@ -121,9 +121,9 @@ public: * @enum Details Informative fields about a certificate */ enum class Details { - EXPIRATION_DATE , /** The certificate expiration date */ - ACTIVATION_DATE , /** The certificate activation date */ - REQUIRE_PRIVATE_KEY_PASSWORD , /** Does the private key require a password */ + EXPIRATION_DATE , /*!< The certificate expiration date */ + ACTIVATION_DATE , /*!< The certificate activation date */ + REQUIRE_PRIVATE_KEY_PASSWORD , /*!< Does the private key require a password */ PUBLIC_SIGNATURE , VERSION_NUMBER , SERIAL_NUMBER , @@ -138,7 +138,7 @@ public: PUBLIC_KEY_ID , ISSUER_DN , NEXT_EXPECTED_UPDATE_DATE , - OUTGOING_SERVER , /** The hostname/outgoing server used for this certificate */ + OUTGOING_SERVER , /*!< The hostname/outgoing server used for this certificate */ COUNT__ }; @@ -165,9 +165,9 @@ public: * new validated types are required. */ enum class CheckValues { - FAILED , /** Equivalent of a boolean "false" */ - PASSED , /** Equivalent of a boolean "true" */ - UNSUPPORTED, /** The operating system doesn't support or require the check */ + FAILED , /*!< Equivalent of a boolean "false" */ + PASSED , /*!< Equivalent of a boolean "true" */ + UNSUPPORTED, /*!< The operating system doesn't support or require the check */ COUNT__, }; Q_ENUMS(CheckValues) @@ -244,5 +244,7 @@ Q_SIGNALS: }; Q_DECLARE_METATYPE(Certificate*) Q_DECLARE_METATYPE(Certificate::CheckValues) +Q_DECLARE_METATYPE(Certificate::Checks) +Q_DECLARE_METATYPE(Certificate::Details) #endif diff --git a/src/certificatemodel.cpp b/src/certificatemodel.cpp index bedf46acdc22826f5b35d2289a0ca155e2f4664b..ebb09710f1402196382739151bdf67efa59fd52f 100644 --- a/src/certificatemodel.cpp +++ b/src/certificatemodel.cpp @@ -34,6 +34,13 @@ #include "account.h" #include "delegates/certificateserializationdelegate.h" +enum class DetailType : uchar +{ + NONE , + DETAIL, + CHECK , +}; + struct CertificateNode { CertificateNode(int index, CertificateModel::NodeType level, CertificateNode* parent, Certificate* cert); @@ -44,7 +51,9 @@ struct CertificateNode { CertificateNode* m_pParent ; Certificate* m_pCertificate ; CertificateModel::NodeType m_Level ; + DetailType m_DetailType ; int m_Index ; + int m_EnumClassDetail; QString m_Col1 ; QVariant m_Col2 ; QString m_ToolTip ; @@ -142,7 +151,8 @@ CertificateModelPrivate::~CertificateModelPrivate() } CertificateNode::CertificateNode(int index, CertificateModel::NodeType level, CertificateNode* parent, Certificate* cert) : - m_pParent(parent), m_pCertificate(cert), m_Level(level), m_Index(index), m_IsLoaded(true) + m_pParent(parent), m_pCertificate(cert), m_Level(level), m_Index(index), m_IsLoaded(true),m_DetailType(DetailType::NONE), + m_EnumClassDetail(0) { CertificateModel::instance()->d_ptr->m_hNodes[cert] = this; } @@ -213,6 +223,11 @@ QHash<int,QByteArray> CertificateModel::roleNames() const } roles[static_cast<int>(Role::DetailRoleBase)+static_cast<int>(d)] = name.toLatin1(); } + + roles[static_cast<int>(Role::isDetail)] = "isDetail"; + roles[static_cast<int>(Role::isCheck )] = "isCheck" ; + roles[static_cast<int>(Role::detail )] = "detail" ; + roles[static_cast<int>(Role::check )] = "check" ; } return roles; } @@ -316,6 +331,8 @@ CertificateNode* CertificateModelPrivate::addToTree(Certificate* cert, Certifica for (const Certificate::Details detail : EnumIterator<Certificate::Details>()) { CertificateNode* d = new CertificateNode(details->m_lChildren.size(), CertificateModel::NodeType::DETAILS, details, nullptr); d->setStrings(cert->getName(detail),cert->detailResult(detail),cert->getDescription(detail) ); + d->m_DetailType = DetailType::DETAIL; + d->m_EnumClassDetail = static_cast<int>(detail); details->m_lChildren << d; } q_ptr->endInsertRows(); @@ -327,6 +344,8 @@ CertificateNode* CertificateModelPrivate::addToTree(Certificate* cert, Certifica if (cert->checkResult(check) != Certificate::CheckValues::UNSUPPORTED) { CertificateNode* d = new CertificateNode(checks->m_lChildren.size(), CertificateModel::NodeType::DETAILS, checks, nullptr); d->setStrings(cert->getName(check),static_cast<bool>(cert->checkResult(check)),cert->getDescription(check)); + d->m_DetailType = DetailType::CHECK; + d->m_EnumClassDetail = static_cast<int>(check); checks->m_lChildren << d; } } @@ -353,6 +372,10 @@ QVariant CertificateModel::data( const QModelIndex& index, int role) const return QVariant(); const CertificateNode* node = static_cast<CertificateNode*>(index.internalPointer()); + if (!node) + return QVariant(); + + switch(role) { case Qt::DisplayRole: case Qt::EditRole: @@ -364,13 +387,38 @@ QVariant CertificateModel::data( const QModelIndex& index, int role) const }; //Add the details as roles for certificates - if (node && node->m_Level == NodeType::CERTIFICATE && role >= static_cast<int>(Role::DetailRoleBase) && role < static_cast<int>(Role::DetailRoleBase)+enum_class_size<Certificate::Details>()) { + if (node->m_Level == NodeType::CERTIFICATE && role >= static_cast<int>(Role::DetailRoleBase) && role < static_cast<int>(Role::DetailRoleBase)+enum_class_size<Certificate::Details>()) { Certificate* cert = node->m_pCertificate; if (cert) { return cert->detailResult(static_cast<Certificate::Details>(role - static_cast<int>(Role::DetailRoleBase))); } } + switch (node->m_Level) { + case CertificateModel::NodeType::DETAILS : + switch(role) { + case (int)Role::isDetail: + return node->m_DetailType == DetailType::DETAIL; + break; + case (int)Role::isCheck: + return node->m_DetailType == DetailType::CHECK; + break; + case (int)Role::detail: + if (node->m_DetailType == DetailType::DETAIL) + return QVariant::fromValue(static_cast<Certificate::Details>(node->m_EnumClassDetail)); + break; + case (int)Role::check: + if (node->m_DetailType == DetailType::CHECK) + return QVariant::fromValue(static_cast<Certificate::Checks>(node->m_EnumClassDetail)); + break; + } + break; + case CertificateModel::NodeType::CERTIFICATE : + case CertificateModel::NodeType::DETAILS_CATEGORY: + case CertificateModel::NodeType::CATEGORY : + break; + } + return QVariant(); } diff --git a/src/certificatemodel.h b/src/certificatemodel.h index 102a621734e0eec02c6978c12a05ca7505d3bcb0..608a2ac0cfe5640da0ca217dfd97b4fb6791b9e5 100644 --- a/src/certificatemodel.h +++ b/src/certificatemodel.h @@ -35,6 +35,10 @@ public: enum class Role { NodeType = 100, + isDetail = 101, + isCheck = 102, + detail = 103, + check = 104, DetailRoleBase = 1000, }; diff --git a/src/delegates/pixmapmanipulationdelegate.cpp b/src/delegates/pixmapmanipulationdelegate.cpp index d6a2d71a7a8e850f3156a0e2fd7d9eca36773cd5..1a68c09e87c7abf029b883565a333f098d3ea648 100644 --- a/src/delegates/pixmapmanipulationdelegate.cpp +++ b/src/delegates/pixmapmanipulationdelegate.cpp @@ -65,7 +65,7 @@ PixmapManipulationDelegate* PixmapManipulationDelegate::instance() return m_spInstance; } -QVariant PixmapManipulationDelegate::serurityIssueIcon(const QModelIndex& index) +QVariant PixmapManipulationDelegate::securityIssueIcon(const QModelIndex& index) { Q_UNUSED(index) return QVariant(); diff --git a/src/delegates/pixmapmanipulationdelegate.h b/src/delegates/pixmapmanipulationdelegate.h index 71c029e8463b170436c12b071943c36620726b95..8111563cd4d53af992369061a60d7619835283da 100644 --- a/src/delegates/pixmapmanipulationdelegate.h +++ b/src/delegates/pixmapmanipulationdelegate.h @@ -61,7 +61,7 @@ public: virtual QVariant callPhoto(Call* c, const QSize& size, bool displayPresence = true); virtual QVariant callPhoto(const ContactMethod* n, const QSize& size, bool displayPresence = true); virtual QVariant numberCategoryIcon(const QVariant& p, const QSize& size, bool displayPresence = false, bool isPresent = false); - virtual QVariant serurityIssueIcon(const QModelIndex& index); + virtual QVariant securityIssueIcon(const QModelIndex& index); virtual QByteArray toByteArray(const QVariant& pxm); virtual QVariant profilePhoto(const QByteArray& data, const QString& type = "PNG"); virtual QVariant collectionIcon(const CollectionInterface* interface, PixmapManipulationDelegate::CollectionIconHint hint = PixmapManipulationDelegate::CollectionIconHint::NONE) const; diff --git a/src/private/securityvalidationmodel_p.h b/src/private/securityvalidationmodel_p.h index 3fcf6bab78305ebdacb270ffae85a17f4e7287ac..b2709eb94e0a215225877284196b2e40b27c6f4f 100644 --- a/src/private/securityvalidationmodel_p.h +++ b/src/private/securityvalidationmodel_p.h @@ -22,6 +22,8 @@ class SecurityFlaw; class Account; class Certificate; +#include <certificate.h> + class SecurityValidationModelPrivate { public: @@ -46,6 +48,9 @@ public: static const TypedStateMachine< SecurityValidationModel::SecurityLevel , SecurityValidationModel::AccountSecurityFlaw > maximumSecurityLevel; static const TypedStateMachine< SecurityValidationModel::Severity , SecurityValidationModel::AccountSecurityFlaw > flawSeverity ; + static const TypedStateMachine< SecurityValidationModel::SecurityLevel , Certificate::Checks > maximumCertificateSecurityLevel; + static const TypedStateMachine< SecurityValidationModel::Severity , Certificate::Checks > certificateFlawSeverity ; + SecurityValidationModel* q_ptr; }; diff --git a/src/private/vcardutils.h b/src/private/vcardutils.h index 3a670a00c2cbb62bfd33c0bd74d045ec16331457..6f2afda1164c842e1030469d2f4d0c304834f275 100644 --- a/src/private/vcardutils.h +++ b/src/private/vcardutils.h @@ -23,7 +23,7 @@ #include <QStringList> #include "person.h" -class LIB_EXPORT VCardUtils +class VCardUtils { public: diff --git a/src/securityvalidationmodel.cpp b/src/securityvalidationmodel.cpp index d3dad72af2dc50f10ee807f161da308c0bc66e22..23cc52afbf8c965c9d1ee07901c3b4d637ba25d8 100644 --- a/src/securityvalidationmodel.cpp +++ b/src/securityvalidationmodel.cpp @@ -1,4 +1,4 @@ -/**************************************************************************** +/**************************************************************************** * Copyright (C) 2013-2015 by Savoir-Faire Linux * * Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> * * * @@ -22,6 +22,7 @@ //Ring #include "account.h" +#include "certificatemodel.h" #include "delegates/pixmapmanipulationdelegate.h" #include "private/securityvalidationmodel_p.h" #include "securityflaw.h" @@ -30,67 +31,97 @@ #include <QtAlgorithms> const QString SecurityValidationModelPrivate::messages[enum_class_size<SecurityValidationModel::AccountSecurityFlaw>()] = { - QObject::tr("Your communication negotiation is secured, but not the media stream, please enable ZRTP or SDES"), - QObject::tr("TLS is disabled, the negotiation wont be encrypted. Your communication will be vulnerable to " - "snooping"), - QObject::tr("Your certificate is expired, please contact your system administrator."), - QObject::tr("Your certificate is self signed. This break the chain of trust."), - QObject::tr("CA_CERTIFICATE_MISSING "), - QObject::tr("END_CERTIFICATE_MISSING "), - QObject::tr("None of your certificate provide a private key, this is required. Please select a private key" - " or use a certificate with one built-in"), - QObject::tr("CERTIFICATE_MISMATCH "), - QObject::tr("CERTIFICATE_STORAGE_PERMISSION "), - QObject::tr("CERTIFICATE_STORAGE_FOLDER "), - QObject::tr("CERTIFICATE_STORAGE_LOCATION "), - QObject::tr("OUTGOING_SERVER_MISMATCH "), - QObject::tr("VERIFY_INCOMING_DISABLED "), - QObject::tr("VERIFY_ANSWER_DISABLED "), - QObject::tr("REQUIRE_CERTIFICATE_DISABLED "), + /*SRTP_ENABLED */QObject::tr("Your communication negotiation is secured, but not the media stream, please enable ZRTP or SDES"), + /*TLS_ENABLED */QObject::tr("TLS is disabled, the negotiation wont be encrypted. Your communication will be vulnerable to " + "snooping"), + /*CERTIFICATE_MATCH */QObject::tr("Your certificate and authority don't match, if your certificate require an authority, it wont work"), + /*OUTGOING_SERVER_MATCH */QObject::tr("The outgoring server specified doesn't match the hostname or the one included in the certificate"), + /*VERIFY_INCOMING_ENABLED */QObject::tr("The \"verify incoming certificate\" option is disabled, this leave you vulnarable to man in the middle attack"), + /*VERIFY_ANSWER_ENABLED */QObject::tr("The \"verify answer certificate\" option is disabled, this leave you vulnarable to man in the middle attack"), + /*REQUIRE_CERTIFICATE_ENABLED */QObject::tr("None of your certificate provide a private key, this is required. Please select a private key" + " or use a certificate with one built-in"), + /*NOT_MISSING_CERTIFICATE */QObject::tr("No certificate authority is provided, it wont be possible to validate if the answer certificates are valid. Some account may also not work."), + /*NOT_MISSING_CERTIFICATE */QObject::tr("No certificate has been provided. This is, for now, unsupported by Ring"), }; +static const QString s1 = QObject::tr("Your certificate is expired, please contact your system administrator."); +static const QString s2 = QObject::tr("Your certificate is self signed. This break the chain of trust."); + const TypedStateMachine< SecurityValidationModel::SecurityLevel , SecurityValidationModel::AccountSecurityFlaw > SecurityValidationModelPrivate::maximumSecurityLevel = {{ - /* SRTP_DISABLED */ SecurityValidationModel::SecurityLevel::WEAK , - /* TLS_DISABLED */ SecurityValidationModel::SecurityLevel::WEAK , - /* CERTIFICATE_EXPIRED */ SecurityValidationModel::SecurityLevel::MEDIUM , - /* CERTIFICATE_SELF_SIGNED */ SecurityValidationModel::SecurityLevel::MEDIUM , - /* CA_CERTIFICATE_MISSING */ SecurityValidationModel::SecurityLevel::MEDIUM , - /* END_CERTIFICATE_MISSING */ SecurityValidationModel::SecurityLevel::MEDIUM , - /* PRIVATE_KEY_MISSING */ SecurityValidationModel::SecurityLevel::MEDIUM , - /* CERTIFICATE_MISMATCH */ SecurityValidationModel::SecurityLevel::NONE , - /* CERTIFICATE_STORAGE_PERMISSION */ SecurityValidationModel::SecurityLevel::ACCEPTABLE , - /* CERTIFICATE_STORAGE_FOLDER */ SecurityValidationModel::SecurityLevel::ACCEPTABLE , - /* CERTIFICATE_STORAGE_LOCATION */ SecurityValidationModel::SecurityLevel::ACCEPTABLE , - /* OUTGOING_SERVER_MISMATCH */ SecurityValidationModel::SecurityLevel::ACCEPTABLE , - /* VERIFY_INCOMING_DISABLED */ SecurityValidationModel::SecurityLevel::MEDIUM , - /* VERIFY_ANSWER_DISABLED */ SecurityValidationModel::SecurityLevel::MEDIUM , - /* REQUIRE_CERTIFICATE_DISABLED */ SecurityValidationModel::SecurityLevel::MEDIUM , - /* MISSING_CERTIFICATE */ SecurityValidationModel::SecurityLevel::NONE , - /* MISSING_AUTHORITY */ SecurityValidationModel::SecurityLevel::WEAK , + /* SRTP_ENABLED */ SecurityValidationModel::SecurityLevel::NONE , + /* TLS_ENABLED */ SecurityValidationModel::SecurityLevel::NONE , + /* CERTIFICATE_MATCH */ SecurityValidationModel::SecurityLevel::WEAK , + /* OUTGOING_SERVER_MATCH */ SecurityValidationModel::SecurityLevel::MEDIUM , + /* VERIFY_INCOMING_ENABLED */ SecurityValidationModel::SecurityLevel::MEDIUM , + /* VERIFY_ANSWER_ENABLED */ SecurityValidationModel::SecurityLevel::MEDIUM , + /* REQUIRE_CERTIFICATE_ENABLED */ SecurityValidationModel::SecurityLevel::WEAK , + /* NOT_MISSING_CERTIFICATE */ SecurityValidationModel::SecurityLevel::WEAK , + /* NOT_MISSING_AUTHORITY */ SecurityValidationModel::SecurityLevel::WEAK , }}; const TypedStateMachine< SecurityValidationModel::Severity , SecurityValidationModel::AccountSecurityFlaw > SecurityValidationModelPrivate::flawSeverity = {{ - /* SRTP_DISABLED */ SecurityValidationModel::Severity::ISSUE , - /* TLS_DISABLED */ SecurityValidationModel::Severity::ISSUE , - /* CERTIFICATE_EXPIRED */ SecurityValidationModel::Severity::WARNING , - /* CERTIFICATE_SELF_SIGNED */ SecurityValidationModel::Severity::WARNING , - /* CA_CERTIFICATE_MISSING */ SecurityValidationModel::Severity::ISSUE , - /* END_CERTIFICATE_MISSING */ SecurityValidationModel::Severity::ISSUE , - /* PRIVATE_KEY_MISSING */ SecurityValidationModel::Severity::ERROR , - /* CERTIFICATE_MISMATCH */ SecurityValidationModel::Severity::ERROR , - /* CERTIFICATE_STORAGE_PERMISSION */ SecurityValidationModel::Severity::WARNING , - /* CERTIFICATE_STORAGE_FOLDER */ SecurityValidationModel::Severity::INFORMATION , - /* CERTIFICATE_STORAGE_LOCATION */ SecurityValidationModel::Severity::INFORMATION , - /* OUTGOING_SERVER_MISMATCH */ SecurityValidationModel::Severity::WARNING , - /* VERIFY_INCOMING_DISABLED */ SecurityValidationModel::Severity::ISSUE , - /* VERIFY_ANSWER_DISABLED */ SecurityValidationModel::Severity::ISSUE , - /* REQUIRE_CERTIFICATE_DISABLED */ SecurityValidationModel::Severity::ISSUE , - /* MISSING_CERTIFICATE */ SecurityValidationModel::Severity::ERROR , - /* MISSING_AUTHORITY */ SecurityValidationModel::Severity::ERROR , + /* SRTP_ENABLED */ SecurityValidationModel::Severity::ISSUE , + /* TLS_ENABLED */ SecurityValidationModel::Severity::ISSUE , + /* CERTIFICATE_MATCH */ SecurityValidationModel::Severity::ERROR , + /* OUTGOING_SERVER_MATCH */ SecurityValidationModel::Severity::WARNING , + /* VERIFY_INCOMING_ENABLED */ SecurityValidationModel::Severity::ISSUE , + /* VERIFY_ANSWER_ENABLED */ SecurityValidationModel::Severity::ISSUE , + /* REQUIRE_CERTIFICATE_ENABLED */ SecurityValidationModel::Severity::ISSUE , + /* NOT_MISSING_CERTIFICATE */ SecurityValidationModel::Severity::WARNING , + /* NOT_MISSING_AUTHORITY */ SecurityValidationModel::Severity::ISSUE , +}}; + +const TypedStateMachine< SecurityValidationModel::SecurityLevel , Certificate::Checks > SecurityValidationModelPrivate::maximumCertificateSecurityLevel = {{ + /* HAS_PRIVATE_KEY */ SecurityValidationModel::SecurityLevel::NONE , + /* EXPIRED */ SecurityValidationModel::SecurityLevel::MEDIUM , + /* STRONG_SIGNING */ SecurityValidationModel::SecurityLevel::WEAK , + /* NOT_SELF_SIGNED */ SecurityValidationModel::SecurityLevel::MEDIUM , + /* KEY_MATCH */ SecurityValidationModel::SecurityLevel::NONE , + /* PRIVATE_KEY_STORAGE_PERMISSION */ SecurityValidationModel::SecurityLevel::MEDIUM , + /* PUBLIC_KEY_STORAGE_PERMISSION */ SecurityValidationModel::SecurityLevel::MEDIUM , + /* PRIVATE_KEY_DIRECTORY_PERMISSIONS */ SecurityValidationModel::SecurityLevel::MEDIUM , + /* PUBLIC_KEY_DIRECTORY_PERMISSIONS */ SecurityValidationModel::SecurityLevel::MEDIUM , + /* PRIVATE_KEY_STORAGE_LOCATION */ SecurityValidationModel::SecurityLevel::ACCEPTABLE , + /* PUBLIC_KEY_STORAGE_LOCATION */ SecurityValidationModel::SecurityLevel::ACCEPTABLE , + /* PRIVATE_KEY_SELINUX_ATTRIBUTES */ SecurityValidationModel::SecurityLevel::ACCEPTABLE , + /* PUBLIC_KEY_SELINUX_ATTRIBUTES */ SecurityValidationModel::SecurityLevel::ACCEPTABLE , + /* EXIST */ SecurityValidationModel::SecurityLevel::NONE , + /* VALID */ SecurityValidationModel::SecurityLevel::NONE , + /* VALID_AUTHORITY */ SecurityValidationModel::SecurityLevel::MEDIUM , + /* KNOWN_AUTHORITY */ SecurityValidationModel::SecurityLevel::ACCEPTABLE , //? + /* NOT_REVOKED */ SecurityValidationModel::SecurityLevel::WEAK , + /* AUTHORITY_MATCH */ SecurityValidationModel::SecurityLevel::NONE , + /* EXPECTED_OWNER */ SecurityValidationModel::SecurityLevel::MEDIUM , //? + /* ACTIVATED */ SecurityValidationModel::SecurityLevel::MEDIUM , //? +}}; + +const TypedStateMachine< SecurityValidationModel::Severity , Certificate::Checks > SecurityValidationModelPrivate::certificateFlawSeverity = {{ + /* HAS_PRIVATE_KEY */ SecurityValidationModel::Severity::ERROR , + /* EXPIRED */ SecurityValidationModel::Severity::WARNING , + /* STRONG_SIGNING */ SecurityValidationModel::Severity::ISSUE , + /* NOT_SELF_SIGNED */ SecurityValidationModel::Severity::WARNING , + /* KEY_MATCH */ SecurityValidationModel::Severity::ERROR , + /* PRIVATE_KEY_STORAGE_PERMISSION */ SecurityValidationModel::Severity::WARNING , + /* PUBLIC_KEY_STORAGE_PERMISSION */ SecurityValidationModel::Severity::WARNING , + /* PRIVATE_KEY_DIRECTORY_PERMISSIONS */ SecurityValidationModel::Severity::WARNING , + /* PUBLIC_KEY_DIRECTORY_PERMISSIONS */ SecurityValidationModel::Severity::WARNING , + /* PRIVATE_KEY_STORAGE_LOCATION */ SecurityValidationModel::Severity::INFORMATION , + /* PUBLIC_KEY_STORAGE_LOCATION */ SecurityValidationModel::Severity::INFORMATION , + /* PRIVATE_KEY_SELINUX_ATTRIBUTES */ SecurityValidationModel::Severity::INFORMATION , + /* PUBLIC_KEY_SELINUX_ATTRIBUTES */ SecurityValidationModel::Severity::INFORMATION , + /* EXIST */ SecurityValidationModel::Severity::ERROR , + /* VALID */ SecurityValidationModel::Severity::ERROR , + /* VALID_AUTHORITY */ SecurityValidationModel::Severity::WARNING , + /* KNOWN_AUTHORITY */ SecurityValidationModel::Severity::WARNING , + /* NOT_REVOKED */ SecurityValidationModel::Severity::ISSUE , + /* AUTHORITY_MATCH */ SecurityValidationModel::Severity::ISSUE , + /* EXPECTED_OWNER */ SecurityValidationModel::Severity::WARNING , + /* ACTIVATED */ SecurityValidationModel::Severity::WARNING , }}; + /** * This class add a prefix in front of Qt::DisplayRole to add a disambiguation * when there is multiple certificates in the same SecurityValidationModel and @@ -112,6 +143,34 @@ public: QString m_Name; }; +/** + * This model transform accounts attributes into security checks to validate if + * some options reduce the security level. + */ +class AccountChecksModel : public QAbstractTableModel +{ + Q_OBJECT + +public: + AccountChecksModel(const Account* a); + + //Model functions + virtual QVariant data ( const QModelIndex& index, int role = Qt::DisplayRole ) const override; + virtual int rowCount ( const QModelIndex& parent = QModelIndex() ) const override; + virtual int columnCount ( const QModelIndex& parent = QModelIndex() ) const override; + virtual Qt::ItemFlags flags ( const QModelIndex& index ) const override; + virtual bool setData ( const QModelIndex& index, const QVariant &value, int role) override; + virtual QHash<int,QByteArray> roleNames() const override; + +private: + //Attributes + const Account* m_pAccount; + Matrix1D<SecurityValidationModel::AccountSecurityFlaw, Certificate::CheckValues> m_lCachedResults; + + //Helpers + void update(); +}; + /** * This model take multiple listModels and append them one after the other * @@ -175,12 +234,21 @@ private: }; -SecurityValidationModelPrivate::SecurityValidationModelPrivate(Account* account, SecurityValidationModel* parent) : q_ptr(parent), -m_pAccount(account), m_CurrentSecurityLevel(SecurityValidationModel::SecurityLevel::NONE) +SecurityValidationModelPrivate::SecurityValidationModelPrivate(Account* account, SecurityValidationModel* parent) : +q_ptr(parent), m_pAccount(account), m_CurrentSecurityLevel(SecurityValidationModel::SecurityLevel::NONE) { } -PrefixAndSeverityProxyModel::PrefixAndSeverityProxyModel(const QString& prefix, QAbstractItemModel* parent) : QIdentityProxyModel(parent),m_Name(prefix) + + +/******************************************************************************* + * * + * PrefixAndSeverityProxyModel * + * * + ******************************************************************************/ + +PrefixAndSeverityProxyModel::PrefixAndSeverityProxyModel(const QString& prefix, QAbstractItemModel* parent) : + QIdentityProxyModel(parent),m_Name(prefix) { setSourceModel(parent); } @@ -203,13 +271,20 @@ QModelIndex PrefixAndSeverityProxyModel::index( int row, int column, const QMode QVariant PrefixAndSeverityProxyModel::data(const QModelIndex& index, int role) const { if (index.isValid()) { + + Certificate::Checks c; + if (QIdentityProxyModel::data(index,(int)CertificateModel::Role::isCheck).toBool() == true) + c = qvariant_cast<Certificate::Checks>(QIdentityProxyModel::data(index,(int)CertificateModel::Role::check)); + else if (index.column() != 2) //That column doesn't exist in the source, the wont exist + return QVariant(); + switch (index.column()) { case 0: switch(role) { case Qt::DecorationRole: - return PixmapManipulationDelegate::instance()->serurityIssueIcon(index); + return PixmapManipulationDelegate::instance()->securityIssueIcon(index); case (int)SecurityValidationModel::Role::Severity: - return QVariant::fromValue(SecurityValidationModel::Severity::WARNING); + return QVariant::fromValue(SecurityValidationModelPrivate::certificateFlawSeverity[c]); } break; // @@ -218,19 +293,21 @@ QVariant PrefixAndSeverityProxyModel::data(const QModelIndex& index, int role) c case Qt::DisplayRole: return m_Name; case (int)SecurityValidationModel::Role::Severity: - return QVariant::fromValue(SecurityValidationModel::Severity::WARNING); + return QVariant::fromValue(SecurityValidationModelPrivate::certificateFlawSeverity[c]); } return QVariant(); } break; //Map source column 1 to 2 case 2: { + const QModelIndex& srcIdx = sourceModel()->index(index.row(),1); + c = qvariant_cast<Certificate::Checks>(srcIdx.data((int)CertificateModel::Role::check)); + switch(role) { case (int)SecurityValidationModel::Role::Severity: - return QVariant::fromValue(SecurityValidationModel::Severity::WARNING); + return QVariant::fromValue(SecurityValidationModelPrivate::certificateFlawSeverity[c]); } - const QModelIndex& srcIdx = sourceModel()->index(index.row(),1); return srcIdx.data(role); } } @@ -239,6 +316,147 @@ QVariant PrefixAndSeverityProxyModel::data(const QModelIndex& index, int role) c return QIdentityProxyModel::data(index,role); } + + +/******************************************************************************* + * * + * AccountChecksModel * + * * + ******************************************************************************/ + +AccountChecksModel::AccountChecksModel(const Account* a) : QAbstractTableModel(const_cast<Account*>(a)), m_pAccount(a) +{ + update(); +} + +QVariant AccountChecksModel::data( const QModelIndex& index, int role ) const +{ + if ((!index.isValid()) + || (index.row() < 0) + || (index.row() >= enum_class_size<SecurityValidationModel::AccountSecurityFlaw>()) + ) + return QVariant(); + + const SecurityValidationModel::AccountSecurityFlaw f = static_cast<SecurityValidationModel::AccountSecurityFlaw>(index.row()); + + switch (index.column()) { + case 0: + switch(role) { + case Qt::DisplayRole: + return SecurityValidationModelPrivate::messages[index.row()]; + case Qt::DecorationRole: + return PixmapManipulationDelegate::instance()->securityIssueIcon(index); + case (int)SecurityValidationModel::Role::Severity: + return QVariant::fromValue(SecurityValidationModelPrivate::flawSeverity[f]); + }; + break; + case 1: + switch(role) { + case Qt::DisplayRole: + return tr("Configuration"); + case (int)SecurityValidationModel::Role::Severity: + return QVariant::fromValue(SecurityValidationModelPrivate::flawSeverity[f]); + }; + break; + case 2: + switch(role) { + case Qt::DisplayRole: + if (m_lCachedResults[f] != Certificate::CheckValues::UNSUPPORTED) + return m_lCachedResults[f] == Certificate::CheckValues::PASSED ? true : false; + break; + case (int)SecurityValidationModel::Role::Severity: + return QVariant::fromValue(SecurityValidationModelPrivate::flawSeverity[f]); + }; + break; + }; + + return QVariant(); +} + +int AccountChecksModel::rowCount( const QModelIndex& parent ) const +{ + return parent.isValid() ? 0 : enum_class_size<SecurityValidationModel::AccountSecurityFlaw>(); +} + +int AccountChecksModel::columnCount( const QModelIndex& parent ) const +{ + return parent.isValid() ? 0 : 3; +} + +Qt::ItemFlags AccountChecksModel::flags( const QModelIndex& index) const +{ + Q_UNUSED(index) + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; +} + +bool AccountChecksModel::setData( const QModelIndex& index, const QVariant &value, int role) +{ + Q_UNUSED(index) + Q_UNUSED(value) + Q_UNUSED(role ) + return false; +} + +QHash<int,QByteArray> AccountChecksModel::roleNames() const +{ + return {}; +} + +void AccountChecksModel::update() +{ + // AccountSecurityFlaw::SRTP_DISABLED + m_lCachedResults.setAt( SecurityValidationModel::AccountSecurityFlaw::SRTP_ENABLED , + m_pAccount->isSrtpEnabled () ? + Certificate::CheckValues::PASSED : Certificate::CheckValues::FAILED); + + // AccountSecurityFlaw::TLS_DISABLED + m_lCachedResults.setAt( SecurityValidationModel::AccountSecurityFlaw::TLS_ENABLED , + m_pAccount->isTlsEnabled () ? + Certificate::CheckValues::PASSED : Certificate::CheckValues::FAILED); + + // AccountSecurityFlaw::CERTIFICATE_MISMATCH + m_lCachedResults.setAt( SecurityValidationModel::AccountSecurityFlaw::CERTIFICATE_MATCH , + Certificate::CheckValues::UNSUPPORTED); //TODO + + // AccountSecurityFlaw::OUTGOING_SERVER_MISMATCH + m_lCachedResults.setAt( SecurityValidationModel::AccountSecurityFlaw::OUTGOING_SERVER_MATCH , + Certificate::CheckValues::UNSUPPORTED); //TODO + + // AccountSecurityFlaw::VERIFY_INCOMING_DISABLED + m_lCachedResults.setAt( SecurityValidationModel::AccountSecurityFlaw::VERIFY_INCOMING_ENABLED , + m_pAccount->isTlsVerifyServer () ? + Certificate::CheckValues::PASSED : Certificate::CheckValues::FAILED); + + // AccountSecurityFlaw::VERIFY_ANSWER_DISABLED + m_lCachedResults.setAt( SecurityValidationModel::AccountSecurityFlaw::VERIFY_ANSWER_ENABLED , + m_pAccount->isTlsVerifyClient () ? + Certificate::CheckValues::PASSED : Certificate::CheckValues::FAILED); + + // AccountSecurityFlaw::REQUIRE_CERTIFICATE_DISABLED + m_lCachedResults.setAt( SecurityValidationModel::AccountSecurityFlaw::REQUIRE_CERTIFICATE_ENABLED , + m_pAccount->isTlsRequireClientCertificate() ? + Certificate::CheckValues::PASSED : Certificate::CheckValues::FAILED); + + // AccountSecurityFlaw::MISSING_CERTIFICATE + m_lCachedResults.setAt( SecurityValidationModel::AccountSecurityFlaw::NOT_MISSING_CERTIFICATE , + m_pAccount->tlsCertificate () ? + Certificate::CheckValues::PASSED : Certificate::CheckValues::FAILED); + + // AccountSecurityFlaw::MISSING_AUTHORITY + m_lCachedResults.setAt( SecurityValidationModel::AccountSecurityFlaw::NOT_MISSING_AUTHORITY , + m_pAccount->tlsCaListCertificate () ? + Certificate::CheckValues::PASSED : Certificate::CheckValues::FAILED); + +} + + + +/******************************************************************************* + * * + * CombinaisonProxyModel * + * * + ******************************************************************************/ + CombinaisonProxyModel::CombinaisonProxyModel(QAbstractItemModel* publicCert, QAbstractItemModel* caCert , QAbstractItemModel* account , @@ -287,6 +505,14 @@ QHash<int,QByteArray> CombinaisonProxyModel::roleNames() const return {}; } + + +/******************************************************************************* + * * + * SecurityValidationModel * + * * + ******************************************************************************/ + SecurityValidationModel::SecurityValidationModel(Account* account) : QSortFilterProxyModel(account), d_ptr(new SecurityValidationModelPrivate(account,this)) { @@ -301,8 +527,9 @@ d_ptr(new SecurityValidationModelPrivate(account,this)) PrefixAndSeverityProxyModel* caProxy = caCert ? new PrefixAndSeverityProxyModel(tr("Authority" ),caCert->checksModel()) : nullptr; PrefixAndSeverityProxyModel* pkProxy = pkCert ? new PrefixAndSeverityProxyModel(tr("Public key"),pkCert->checksModel()) : nullptr; + AccountChecksModel* accChecks = new AccountChecksModel(account); - setSourceModel(new CombinaisonProxyModel(pkProxy,caProxy,nullptr,this)); + setSourceModel(new CombinaisonProxyModel(pkProxy,caProxy,accChecks,this)); setSortRole((int)Role::Severity); } diff --git a/src/securityvalidationmodel.h b/src/securityvalidationmodel.h index 09cd81afe842ba8ffda7a050fd4cf8170325a2fc..6950ae96bc233bdacb3218062f6fdadf0c81dcf7 100644 --- a/src/securityvalidationmodel.h +++ b/src/securityvalidationmodel.h @@ -89,23 +89,15 @@ public: ///Every supported flaws enum class AccountSecurityFlaw { - SRTP_DISABLED , - TLS_DISABLED , - CERTIFICATE_EXPIRED , - CERTIFICATE_SELF_SIGNED , - CA_CERTIFICATE_MISSING , - END_CERTIFICATE_MISSING , - PRIVATE_KEY_MISSING , - CERTIFICATE_MISMATCH , - CERTIFICATE_STORAGE_PERMISSION , - CERTIFICATE_STORAGE_FOLDER , - CERTIFICATE_STORAGE_LOCATION , - OUTGOING_SERVER_MISMATCH , - VERIFY_INCOMING_DISABLED , - VERIFY_ANSWER_DISABLED , - REQUIRE_CERTIFICATE_DISABLED , - MISSING_CERTIFICATE , - MISSING_AUTHORITY , + SRTP_ENABLED , + TLS_ENABLED , + CERTIFICATE_MATCH , + OUTGOING_SERVER_MATCH , + VERIFY_INCOMING_ENABLED , + VERIFY_ANSWER_ENABLED , + REQUIRE_CERTIFICATE_ENABLED , + NOT_MISSING_CERTIFICATE , + NOT_MISSING_AUTHORITY , COUNT__ }; diff --git a/src/typedefs.h b/src/typedefs.h index 25ace9797b0ba602d83be4794ba33f27ec799e92..dfb700f1c731e958fe3480ba1a3eab26eb7750a2 100644 --- a/src/typedefs.h +++ b/src/typedefs.h @@ -92,6 +92,7 @@ struct Matrix1D { Matrix1D(std::initializer_list< std::initializer_list<Value> > s); + explicit Matrix1D(); // Row is a built-in type ("int" by default) Value operator[](Row v); @@ -101,15 +102,18 @@ struct Matrix1D /** * An Iterator for enum classes */ - class EnumClassIter + class Matrix1DEnumClassIter { public: - EnumClassIter (const Matrix1D<Row, Value, A>* p_vec, int pos) + Matrix1DEnumClassIter (const Matrix1D<Row, Value, A>* p_vec, int pos) : pos_( pos ), p_vec_( p_vec ) {} - bool operator!= (const EnumClassIter& other) const; - Row operator* () const; - const EnumClassIter& operator++ (); + bool operator!= (const Matrix1DEnumClassIter& other) const; + bool operator== (const Matrix1DEnumClassIter& other) const; + void operator= (Value& other ) ; + void operator= (Value& other ) const; + //Row operator* () const; + //const Matrix1DEnumClassIter& operator++ (); private: int pos_; @@ -117,16 +121,19 @@ struct Matrix1D }; //Iterators - EnumClassIter begin(); - EnumClassIter end(); + Matrix1DEnumClassIter begin(); + Matrix1DEnumClassIter end(); // Only use for single reverse mappable arrays, will ASSERT otherwise Row fromValue(const Value& value) const; static void setReverseMapping(Matrix1D<Row,const char *> names); + //Setter + void setAt(Row,Value); + private: - const QVector<Value> m_lData; + QVector<Value> m_lData; static QMap<A, Row> m_hReverseMapping; }; diff --git a/src/typedefs.hpp b/src/typedefs.hpp index b24568f94232ab3e3f3335cd1da8610a0b3a6d83..ba15a29746a5c74307f357c3aad26c134f12b90a 100644 --- a/src/typedefs.hpp +++ b/src/typedefs.hpp @@ -58,6 +58,12 @@ typename EnumIterator<EnumClass>::EnumClassIter EnumIterator<EnumClass>::end() +template<class Row, typename Value, typename Accessor> +Matrix1D<Row,Value,Accessor>::Matrix1D() +{ + m_lData.resize(enum_class_size<Row>()); +} + template<class Row, typename Value, typename Accessor> Matrix1D<Row,Value,Accessor>::Matrix1D(std::initializer_list< std::initializer_list<Value>> s) : m_lData(*std::begin(s)) { @@ -113,3 +119,33 @@ Row Matrix1D<Row,Value,Accessor>::fromValue(const Value& value) const { } return m_hReverseMapping[value]; } + +template<class Row, typename Value, typename Accessor> +bool Matrix1D<Row,Value,Accessor>::Matrix1DEnumClassIter::operator!= (const Matrix1DEnumClassIter& other) const +{ + return pos_ != other.pos_; +} + +template<class Row, typename Value, typename Accessor> +bool Matrix1D<Row,Value,Accessor>::Matrix1DEnumClassIter::operator== (const Matrix1DEnumClassIter& other) const +{ + return pos_ == other.pos_; +} + +template<class Row, typename Value, typename Accessor> +void Matrix1D<Row,Value,Accessor>::Matrix1DEnumClassIter::operator= (Value& other) const +{ + m_lData[pos_] = other; +} + +template<class Row, typename Value, typename Accessor> +void Matrix1D<Row,Value,Accessor>::Matrix1DEnumClassIter::operator= (Value& other) +{ + m_lData[pos_] = other; +} + +template<class Row, typename Value, typename Accessor> +void Matrix1D<Row,Value,Accessor>::setAt(Row row,Value value) +{ + m_lData[(int)row] = value; +}