Skip to content
Snippets Groups Projects
Commit c2c3ea99 authored by Emmanuel Lepage Vallee's avatar Emmanuel Lepage Vallee
Browse files

securityeval: Add support for account config checks

Also:

 * Properly split the checks for accounts and certiticates
 * Fix account checks description
 * Define severity and security level for certificates checks

Refs #69834
parent 3fedf9f7
Branches
Tags
No related merge requests found
...@@ -93,27 +93,27 @@ public: ...@@ -93,27 +93,27 @@ public:
* *
*/ */
enum class Checks { enum class Checks {
HAS_PRIVATE_KEY , /** This certificate has a build in private key */ HAS_PRIVATE_KEY , /*!< This certificate has a build in private key */
EXPIRED , /** This certificate is past its expiration date */ EXPIRED , /*!< This certificate is past its expiration date */
STRONG_SIGNING , /** This certificate has been signed with a brute-force-able method */ STRONG_SIGNING , /*!< This certificate has been signed with a brute-force-able method */
NOT_SELF_SIGNED , /** This certificate has been self signed */ NOT_SELF_SIGNED , /*!< This certificate has been self signed */
KEY_MATCH , /** The public and private keys provided don't match */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ PUBLIC_KEY_SELINUX_ATTRIBUTES , /*!< Some operating systems require keys to have extra attributes */
EXIST , /** The certificate file doesn't exist or is not accessible */ EXIST , /*!< The certificate file doesn't exist or is not accessible */
VALID , /** The file is not a certificate */ VALID , /*!< The file is not a certificate */
VALID_AUTHORITY , /** The claimed authority did not sign the certificate */ VALID_AUTHORITY , /*!< The claimed authority did not sign the certificate */
KNOWN_AUTHORITY , /** Some operating systems provide a list of trusted authorities, use it */ KNOWN_AUTHORITY , /*!< Some operating systems provide a list of trusted authorities, use it */
NOT_REVOKED , /** The certificate has been revoked by the authority */ NOT_REVOKED , /*!< The certificate has been revoked by the authority */
AUTHORITY_MATCH , /** The certificate and authority mismatch */ AUTHORITY_MATCH , /*!< The certificate and authority mismatch */
EXPECTED_OWNER , /** The certificate has an expected owner */ EXPECTED_OWNER , /*!< The certificate has an expected owner */
ACTIVATED , /** The certificate has not been activated yet */ ACTIVATED , /*!< The certificate has not been activated yet */
COUNT__, COUNT__,
}; };
...@@ -121,9 +121,9 @@ public: ...@@ -121,9 +121,9 @@ public:
* @enum Details Informative fields about a certificate * @enum Details Informative fields about a certificate
*/ */
enum class Details { enum class Details {
EXPIRATION_DATE , /** The certificate expiration date */ EXPIRATION_DATE , /*!< The certificate expiration date */
ACTIVATION_DATE , /** The certificate activation date */ ACTIVATION_DATE , /*!< The certificate activation date */
REQUIRE_PRIVATE_KEY_PASSWORD , /** Does the private key require a password */ REQUIRE_PRIVATE_KEY_PASSWORD , /*!< Does the private key require a password */
PUBLIC_SIGNATURE , PUBLIC_SIGNATURE ,
VERSION_NUMBER , VERSION_NUMBER ,
SERIAL_NUMBER , SERIAL_NUMBER ,
...@@ -138,7 +138,7 @@ public: ...@@ -138,7 +138,7 @@ public:
PUBLIC_KEY_ID , PUBLIC_KEY_ID ,
ISSUER_DN , ISSUER_DN ,
NEXT_EXPECTED_UPDATE_DATE , 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__ COUNT__
}; };
...@@ -165,9 +165,9 @@ public: ...@@ -165,9 +165,9 @@ public:
* new validated types are required. * new validated types are required.
*/ */
enum class CheckValues { enum class CheckValues {
FAILED , /** Equivalent of a boolean "false" */ FAILED , /*!< Equivalent of a boolean "false" */
PASSED , /** Equivalent of a boolean "true" */ PASSED , /*!< Equivalent of a boolean "true" */
UNSUPPORTED, /** The operating system doesn't support or require the check */ UNSUPPORTED, /*!< The operating system doesn't support or require the check */
COUNT__, COUNT__,
}; };
Q_ENUMS(CheckValues) Q_ENUMS(CheckValues)
...@@ -244,5 +244,7 @@ Q_SIGNALS: ...@@ -244,5 +244,7 @@ Q_SIGNALS:
}; };
Q_DECLARE_METATYPE(Certificate*) Q_DECLARE_METATYPE(Certificate*)
Q_DECLARE_METATYPE(Certificate::CheckValues) Q_DECLARE_METATYPE(Certificate::CheckValues)
Q_DECLARE_METATYPE(Certificate::Checks)
Q_DECLARE_METATYPE(Certificate::Details)
#endif #endif
...@@ -34,6 +34,13 @@ ...@@ -34,6 +34,13 @@
#include "account.h" #include "account.h"
#include "delegates/certificateserializationdelegate.h" #include "delegates/certificateserializationdelegate.h"
enum class DetailType : uchar
{
NONE ,
DETAIL,
CHECK ,
};
struct CertificateNode { struct CertificateNode {
CertificateNode(int index, CertificateModel::NodeType level, CertificateNode* parent, Certificate* cert); CertificateNode(int index, CertificateModel::NodeType level, CertificateNode* parent, Certificate* cert);
...@@ -44,7 +51,9 @@ struct CertificateNode { ...@@ -44,7 +51,9 @@ struct CertificateNode {
CertificateNode* m_pParent ; CertificateNode* m_pParent ;
Certificate* m_pCertificate ; Certificate* m_pCertificate ;
CertificateModel::NodeType m_Level ; CertificateModel::NodeType m_Level ;
DetailType m_DetailType ;
int m_Index ; int m_Index ;
int m_EnumClassDetail;
QString m_Col1 ; QString m_Col1 ;
QVariant m_Col2 ; QVariant m_Col2 ;
QString m_ToolTip ; QString m_ToolTip ;
...@@ -142,7 +151,8 @@ CertificateModelPrivate::~CertificateModelPrivate() ...@@ -142,7 +151,8 @@ CertificateModelPrivate::~CertificateModelPrivate()
} }
CertificateNode::CertificateNode(int index, CertificateModel::NodeType level, CertificateNode* parent, Certificate* cert) : 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; CertificateModel::instance()->d_ptr->m_hNodes[cert] = this;
} }
...@@ -213,6 +223,11 @@ QHash<int,QByteArray> CertificateModel::roleNames() const ...@@ -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::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; return roles;
} }
...@@ -316,6 +331,8 @@ CertificateNode* CertificateModelPrivate::addToTree(Certificate* cert, Certifica ...@@ -316,6 +331,8 @@ CertificateNode* CertificateModelPrivate::addToTree(Certificate* cert, Certifica
for (const Certificate::Details detail : EnumIterator<Certificate::Details>()) { for (const Certificate::Details detail : EnumIterator<Certificate::Details>()) {
CertificateNode* d = new CertificateNode(details->m_lChildren.size(), CertificateModel::NodeType::DETAILS, details, nullptr); 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->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; details->m_lChildren << d;
} }
q_ptr->endInsertRows(); q_ptr->endInsertRows();
...@@ -327,6 +344,8 @@ CertificateNode* CertificateModelPrivate::addToTree(Certificate* cert, Certifica ...@@ -327,6 +344,8 @@ CertificateNode* CertificateModelPrivate::addToTree(Certificate* cert, Certifica
if (cert->checkResult(check) != Certificate::CheckValues::UNSUPPORTED) { if (cert->checkResult(check) != Certificate::CheckValues::UNSUPPORTED) {
CertificateNode* d = new CertificateNode(checks->m_lChildren.size(), CertificateModel::NodeType::DETAILS, checks, nullptr); 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->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; checks->m_lChildren << d;
} }
} }
...@@ -353,6 +372,10 @@ QVariant CertificateModel::data( const QModelIndex& index, int role) const ...@@ -353,6 +372,10 @@ QVariant CertificateModel::data( const QModelIndex& index, int role) const
return QVariant(); return QVariant();
const CertificateNode* node = static_cast<CertificateNode*>(index.internalPointer()); const CertificateNode* node = static_cast<CertificateNode*>(index.internalPointer());
if (!node)
return QVariant();
switch(role) { switch(role) {
case Qt::DisplayRole: case Qt::DisplayRole:
case Qt::EditRole: case Qt::EditRole:
...@@ -364,13 +387,38 @@ QVariant CertificateModel::data( const QModelIndex& index, int role) const ...@@ -364,13 +387,38 @@ QVariant CertificateModel::data( const QModelIndex& index, int role) const
}; };
//Add the details as roles for certificates //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; Certificate* cert = node->m_pCertificate;
if (cert) { if (cert) {
return cert->detailResult(static_cast<Certificate::Details>(role - static_cast<int>(Role::DetailRoleBase))); 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(); return QVariant();
} }
......
...@@ -35,6 +35,10 @@ public: ...@@ -35,6 +35,10 @@ public:
enum class Role { enum class Role {
NodeType = 100, NodeType = 100,
isDetail = 101,
isCheck = 102,
detail = 103,
check = 104,
DetailRoleBase = 1000, DetailRoleBase = 1000,
}; };
......
...@@ -65,7 +65,7 @@ PixmapManipulationDelegate* PixmapManipulationDelegate::instance() ...@@ -65,7 +65,7 @@ PixmapManipulationDelegate* PixmapManipulationDelegate::instance()
return m_spInstance; return m_spInstance;
} }
QVariant PixmapManipulationDelegate::serurityIssueIcon(const QModelIndex& index) QVariant PixmapManipulationDelegate::securityIssueIcon(const QModelIndex& index)
{ {
Q_UNUSED(index) Q_UNUSED(index)
return QVariant(); return QVariant();
......
...@@ -61,7 +61,7 @@ public: ...@@ -61,7 +61,7 @@ public:
virtual QVariant callPhoto(Call* c, const QSize& size, bool displayPresence = true); 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 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 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 QByteArray toByteArray(const QVariant& pxm);
virtual QVariant profilePhoto(const QByteArray& data, const QString& type = "PNG"); virtual QVariant profilePhoto(const QByteArray& data, const QString& type = "PNG");
virtual QVariant collectionIcon(const CollectionInterface* interface, PixmapManipulationDelegate::CollectionIconHint hint = PixmapManipulationDelegate::CollectionIconHint::NONE) const; virtual QVariant collectionIcon(const CollectionInterface* interface, PixmapManipulationDelegate::CollectionIconHint hint = PixmapManipulationDelegate::CollectionIconHint::NONE) const;
......
...@@ -22,6 +22,8 @@ class SecurityFlaw; ...@@ -22,6 +22,8 @@ class SecurityFlaw;
class Account; class Account;
class Certificate; class Certificate;
#include <certificate.h>
class SecurityValidationModelPrivate class SecurityValidationModelPrivate
{ {
public: public:
...@@ -46,6 +48,9 @@ public: ...@@ -46,6 +48,9 @@ public:
static const TypedStateMachine< SecurityValidationModel::SecurityLevel , SecurityValidationModel::AccountSecurityFlaw > maximumSecurityLevel; static const TypedStateMachine< SecurityValidationModel::SecurityLevel , SecurityValidationModel::AccountSecurityFlaw > maximumSecurityLevel;
static const TypedStateMachine< SecurityValidationModel::Severity , SecurityValidationModel::AccountSecurityFlaw > flawSeverity ; 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; SecurityValidationModel* q_ptr;
}; };
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
#include <QStringList> #include <QStringList>
#include "person.h" #include "person.h"
class LIB_EXPORT VCardUtils class VCardUtils
{ {
public: public:
......
/**************************************************************************** /****************************************************************************
* Copyright (C) 2013-2015 by Savoir-Faire Linux * * Copyright (C) 2013-2015 by Savoir-Faire Linux *
* Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> * * Author : Emmanuel Lepage Vallee <emmanuel.lepage@savoirfairelinux.com> *
* * * *
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
//Ring //Ring
#include "account.h" #include "account.h"
#include "certificatemodel.h"
#include "delegates/pixmapmanipulationdelegate.h" #include "delegates/pixmapmanipulationdelegate.h"
#include "private/securityvalidationmodel_p.h" #include "private/securityvalidationmodel_p.h"
#include "securityflaw.h" #include "securityflaw.h"
...@@ -30,67 +31,97 @@ ...@@ -30,67 +31,97 @@
#include <QtAlgorithms> #include <QtAlgorithms>
const QString SecurityValidationModelPrivate::messages[enum_class_size<SecurityValidationModel::AccountSecurityFlaw>()] = { 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"), /*SRTP_ENABLED */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 " /*TLS_ENABLED */QObject::tr("TLS is disabled, the negotiation wont be encrypted. Your communication will be vulnerable to "
"snooping"), "snooping"),
QObject::tr("Your certificate is expired, please contact your system administrator."), /*CERTIFICATE_MATCH */QObject::tr("Your certificate and authority don't match, if your certificate require an authority, it wont work"),
QObject::tr("Your certificate is self signed. This break the chain of trust."), /*OUTGOING_SERVER_MATCH */QObject::tr("The outgoring server specified doesn't match the hostname or the one included in the certificate"),
QObject::tr("CA_CERTIFICATE_MISSING "), /*VERIFY_INCOMING_ENABLED */QObject::tr("The \"verify incoming certificate\" option is disabled, this leave you vulnarable to man in the middle attack"),
QObject::tr("END_CERTIFICATE_MISSING "), /*VERIFY_ANSWER_ENABLED */QObject::tr("The \"verify answer certificate\" option is disabled, this leave you vulnarable to man in the middle attack"),
QObject::tr("None of your certificate provide a private key, this is required. Please select a private key" /*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"), " or use a certificate with one built-in"),
QObject::tr("CERTIFICATE_MISMATCH "), /*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."),
QObject::tr("CERTIFICATE_STORAGE_PERMISSION "), /*NOT_MISSING_CERTIFICATE */QObject::tr("No certificate has been provided. This is, for now, unsupported by Ring"),
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 "),
}; };
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 > const TypedStateMachine< SecurityValidationModel::SecurityLevel , SecurityValidationModel::AccountSecurityFlaw >
SecurityValidationModelPrivate::maximumSecurityLevel = {{ SecurityValidationModelPrivate::maximumSecurityLevel = {{
/* SRTP_DISABLED */ SecurityValidationModel::SecurityLevel::WEAK , /* SRTP_ENABLED */ SecurityValidationModel::SecurityLevel::NONE ,
/* TLS_DISABLED */ SecurityValidationModel::SecurityLevel::WEAK , /* TLS_ENABLED */ SecurityValidationModel::SecurityLevel::NONE ,
/* CERTIFICATE_EXPIRED */ SecurityValidationModel::SecurityLevel::MEDIUM , /* CERTIFICATE_MATCH */ SecurityValidationModel::SecurityLevel::WEAK ,
/* CERTIFICATE_SELF_SIGNED */ SecurityValidationModel::SecurityLevel::MEDIUM , /* OUTGOING_SERVER_MATCH */ SecurityValidationModel::SecurityLevel::MEDIUM ,
/* CA_CERTIFICATE_MISSING */ SecurityValidationModel::SecurityLevel::MEDIUM , /* VERIFY_INCOMING_ENABLED */ SecurityValidationModel::SecurityLevel::MEDIUM ,
/* END_CERTIFICATE_MISSING */ SecurityValidationModel::SecurityLevel::MEDIUM , /* VERIFY_ANSWER_ENABLED */ SecurityValidationModel::SecurityLevel::MEDIUM ,
/* PRIVATE_KEY_MISSING */ SecurityValidationModel::SecurityLevel::MEDIUM , /* REQUIRE_CERTIFICATE_ENABLED */ SecurityValidationModel::SecurityLevel::WEAK ,
/* CERTIFICATE_MISMATCH */ SecurityValidationModel::SecurityLevel::NONE , /* NOT_MISSING_CERTIFICATE */ SecurityValidationModel::SecurityLevel::WEAK ,
/* CERTIFICATE_STORAGE_PERMISSION */ SecurityValidationModel::SecurityLevel::ACCEPTABLE , /* NOT_MISSING_AUTHORITY */ SecurityValidationModel::SecurityLevel::WEAK ,
/* 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 ,
}}; }};
const TypedStateMachine< SecurityValidationModel::Severity , SecurityValidationModel::AccountSecurityFlaw > const TypedStateMachine< SecurityValidationModel::Severity , SecurityValidationModel::AccountSecurityFlaw >
SecurityValidationModelPrivate::flawSeverity = {{ SecurityValidationModelPrivate::flawSeverity = {{
/* SRTP_DISABLED */ SecurityValidationModel::Severity::ISSUE , /* SRTP_ENABLED */ SecurityValidationModel::Severity::ISSUE ,
/* TLS_DISABLED */ SecurityValidationModel::Severity::ISSUE , /* TLS_ENABLED */ SecurityValidationModel::Severity::ISSUE ,
/* CERTIFICATE_EXPIRED */ SecurityValidationModel::Severity::WARNING , /* CERTIFICATE_MATCH */ SecurityValidationModel::Severity::ERROR ,
/* CERTIFICATE_SELF_SIGNED */ SecurityValidationModel::Severity::WARNING , /* OUTGOING_SERVER_MATCH */ SecurityValidationModel::Severity::WARNING ,
/* CA_CERTIFICATE_MISSING */ SecurityValidationModel::Severity::ISSUE , /* VERIFY_INCOMING_ENABLED */ SecurityValidationModel::Severity::ISSUE ,
/* END_CERTIFICATE_MISSING */ SecurityValidationModel::Severity::ISSUE , /* VERIFY_ANSWER_ENABLED */ SecurityValidationModel::Severity::ISSUE ,
/* PRIVATE_KEY_MISSING */ SecurityValidationModel::Severity::ERROR , /* REQUIRE_CERTIFICATE_ENABLED */ SecurityValidationModel::Severity::ISSUE ,
/* CERTIFICATE_MISMATCH */ SecurityValidationModel::Severity::ERROR , /* NOT_MISSING_CERTIFICATE */ SecurityValidationModel::Severity::WARNING ,
/* CERTIFICATE_STORAGE_PERMISSION */ SecurityValidationModel::Severity::WARNING , /* NOT_MISSING_AUTHORITY */ SecurityValidationModel::Severity::ISSUE ,
/* CERTIFICATE_STORAGE_FOLDER */ SecurityValidationModel::Severity::INFORMATION , }};
/* CERTIFICATE_STORAGE_LOCATION */ SecurityValidationModel::Severity::INFORMATION ,
/* OUTGOING_SERVER_MISMATCH */ SecurityValidationModel::Severity::WARNING , const TypedStateMachine< SecurityValidationModel::SecurityLevel , Certificate::Checks > SecurityValidationModelPrivate::maximumCertificateSecurityLevel = {{
/* VERIFY_INCOMING_DISABLED */ SecurityValidationModel::Severity::ISSUE , /* HAS_PRIVATE_KEY */ SecurityValidationModel::SecurityLevel::NONE ,
/* VERIFY_ANSWER_DISABLED */ SecurityValidationModel::Severity::ISSUE , /* EXPIRED */ SecurityValidationModel::SecurityLevel::MEDIUM ,
/* REQUIRE_CERTIFICATE_DISABLED */ SecurityValidationModel::Severity::ISSUE , /* STRONG_SIGNING */ SecurityValidationModel::SecurityLevel::WEAK ,
/* MISSING_CERTIFICATE */ SecurityValidationModel::Severity::ERROR , /* NOT_SELF_SIGNED */ SecurityValidationModel::SecurityLevel::MEDIUM ,
/* MISSING_AUTHORITY */ SecurityValidationModel::Severity::ERROR , /* 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 * This class add a prefix in front of Qt::DisplayRole to add a disambiguation
* when there is multiple certificates in the same SecurityValidationModel and * when there is multiple certificates in the same SecurityValidationModel and
...@@ -112,6 +143,34 @@ public: ...@@ -112,6 +143,34 @@ public:
QString m_Name; 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 * This model take multiple listModels and append them one after the other
* *
...@@ -175,12 +234,21 @@ private: ...@@ -175,12 +234,21 @@ private:
}; };
SecurityValidationModelPrivate::SecurityValidationModelPrivate(Account* account, SecurityValidationModel* parent) : q_ptr(parent), SecurityValidationModelPrivate::SecurityValidationModelPrivate(Account* account, SecurityValidationModel* parent) :
m_pAccount(account), m_CurrentSecurityLevel(SecurityValidationModel::SecurityLevel::NONE) 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); setSourceModel(parent);
} }
...@@ -203,13 +271,20 @@ QModelIndex PrefixAndSeverityProxyModel::index( int row, int column, const QMode ...@@ -203,13 +271,20 @@ QModelIndex PrefixAndSeverityProxyModel::index( int row, int column, const QMode
QVariant PrefixAndSeverityProxyModel::data(const QModelIndex& index, int role) const QVariant PrefixAndSeverityProxyModel::data(const QModelIndex& index, int role) const
{ {
if (index.isValid()) { 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()) { switch (index.column()) {
case 0: case 0:
switch(role) { switch(role) {
case Qt::DecorationRole: case Qt::DecorationRole:
return PixmapManipulationDelegate::instance()->serurityIssueIcon(index); return PixmapManipulationDelegate::instance()->securityIssueIcon(index);
case (int)SecurityValidationModel::Role::Severity: case (int)SecurityValidationModel::Role::Severity:
return QVariant::fromValue(SecurityValidationModel::Severity::WARNING); return QVariant::fromValue(SecurityValidationModelPrivate::certificateFlawSeverity[c]);
} }
break; break;
// //
...@@ -218,19 +293,21 @@ QVariant PrefixAndSeverityProxyModel::data(const QModelIndex& index, int role) c ...@@ -218,19 +293,21 @@ QVariant PrefixAndSeverityProxyModel::data(const QModelIndex& index, int role) c
case Qt::DisplayRole: case Qt::DisplayRole:
return m_Name; return m_Name;
case (int)SecurityValidationModel::Role::Severity: case (int)SecurityValidationModel::Role::Severity:
return QVariant::fromValue(SecurityValidationModel::Severity::WARNING); return QVariant::fromValue(SecurityValidationModelPrivate::certificateFlawSeverity[c]);
} }
return QVariant(); return QVariant();
} }
break; break;
//Map source column 1 to 2 //Map source column 1 to 2
case 2: { case 2: {
const QModelIndex& srcIdx = sourceModel()->index(index.row(),1);
c = qvariant_cast<Certificate::Checks>(srcIdx.data((int)CertificateModel::Role::check));
switch(role) { switch(role) {
case (int)SecurityValidationModel::Role::Severity: 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); return srcIdx.data(role);
} }
} }
...@@ -239,6 +316,147 @@ QVariant PrefixAndSeverityProxyModel::data(const QModelIndex& index, int role) c ...@@ -239,6 +316,147 @@ QVariant PrefixAndSeverityProxyModel::data(const QModelIndex& index, int role) c
return QIdentityProxyModel::data(index,role); 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, CombinaisonProxyModel::CombinaisonProxyModel(QAbstractItemModel* publicCert,
QAbstractItemModel* caCert , QAbstractItemModel* caCert ,
QAbstractItemModel* account , QAbstractItemModel* account ,
...@@ -287,6 +505,14 @@ QHash<int,QByteArray> CombinaisonProxyModel::roleNames() const ...@@ -287,6 +505,14 @@ QHash<int,QByteArray> CombinaisonProxyModel::roleNames() const
return {}; return {};
} }
/*******************************************************************************
* *
* SecurityValidationModel *
* *
******************************************************************************/
SecurityValidationModel::SecurityValidationModel(Account* account) : QSortFilterProxyModel(account), SecurityValidationModel::SecurityValidationModel(Account* account) : QSortFilterProxyModel(account),
d_ptr(new SecurityValidationModelPrivate(account,this)) d_ptr(new SecurityValidationModelPrivate(account,this))
{ {
...@@ -301,8 +527,9 @@ 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* caProxy = caCert ? new PrefixAndSeverityProxyModel(tr("Authority" ),caCert->checksModel()) : nullptr;
PrefixAndSeverityProxyModel* pkProxy = pkCert ? new PrefixAndSeverityProxyModel(tr("Public key"),pkCert->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); setSortRole((int)Role::Severity);
} }
......
...@@ -89,23 +89,15 @@ public: ...@@ -89,23 +89,15 @@ public:
///Every supported flaws ///Every supported flaws
enum class AccountSecurityFlaw { enum class AccountSecurityFlaw {
SRTP_DISABLED , SRTP_ENABLED ,
TLS_DISABLED , TLS_ENABLED ,
CERTIFICATE_EXPIRED , CERTIFICATE_MATCH ,
CERTIFICATE_SELF_SIGNED , OUTGOING_SERVER_MATCH ,
CA_CERTIFICATE_MISSING , VERIFY_INCOMING_ENABLED ,
END_CERTIFICATE_MISSING , VERIFY_ANSWER_ENABLED ,
PRIVATE_KEY_MISSING , REQUIRE_CERTIFICATE_ENABLED ,
CERTIFICATE_MISMATCH , NOT_MISSING_CERTIFICATE ,
CERTIFICATE_STORAGE_PERMISSION , NOT_MISSING_AUTHORITY ,
CERTIFICATE_STORAGE_FOLDER ,
CERTIFICATE_STORAGE_LOCATION ,
OUTGOING_SERVER_MISMATCH ,
VERIFY_INCOMING_DISABLED ,
VERIFY_ANSWER_DISABLED ,
REQUIRE_CERTIFICATE_DISABLED ,
MISSING_CERTIFICATE ,
MISSING_AUTHORITY ,
COUNT__ COUNT__
}; };
......
...@@ -92,6 +92,7 @@ struct Matrix1D ...@@ -92,6 +92,7 @@ struct Matrix1D
{ {
Matrix1D(std::initializer_list< std::initializer_list<Value> > s); Matrix1D(std::initializer_list< std::initializer_list<Value> > s);
explicit Matrix1D();
// Row is a built-in type ("int" by default) // Row is a built-in type ("int" by default)
Value operator[](Row v); Value operator[](Row v);
...@@ -101,15 +102,18 @@ struct Matrix1D ...@@ -101,15 +102,18 @@ struct Matrix1D
/** /**
* An Iterator for enum classes * An Iterator for enum classes
*/ */
class EnumClassIter class Matrix1DEnumClassIter
{ {
public: 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 ) {} : pos_( pos ), p_vec_( p_vec ) {}
bool operator!= (const EnumClassIter& other) const; bool operator!= (const Matrix1DEnumClassIter& other) const;
Row operator* () const; bool operator== (const Matrix1DEnumClassIter& other) const;
const EnumClassIter& operator++ (); void operator= (Value& other ) ;
void operator= (Value& other ) const;
//Row operator* () const;
//const Matrix1DEnumClassIter& operator++ ();
private: private:
int pos_; int pos_;
...@@ -117,16 +121,19 @@ struct Matrix1D ...@@ -117,16 +121,19 @@ struct Matrix1D
}; };
//Iterators //Iterators
EnumClassIter begin(); Matrix1DEnumClassIter begin();
EnumClassIter end(); Matrix1DEnumClassIter end();
// Only use for single reverse mappable arrays, will ASSERT otherwise // Only use for single reverse mappable arrays, will ASSERT otherwise
Row fromValue(const Value& value) const; Row fromValue(const Value& value) const;
static void setReverseMapping(Matrix1D<Row,const char *> names); static void setReverseMapping(Matrix1D<Row,const char *> names);
//Setter
void setAt(Row,Value);
private: private:
const QVector<Value> m_lData; QVector<Value> m_lData;
static QMap<A, Row> m_hReverseMapping; static QMap<A, Row> m_hReverseMapping;
}; };
......
...@@ -58,6 +58,12 @@ typename EnumIterator<EnumClass>::EnumClassIter EnumIterator<EnumClass>::end() ...@@ -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> template<class Row, typename Value, typename Accessor>
Matrix1D<Row,Value,Accessor>::Matrix1D(std::initializer_list< std::initializer_list<Value>> s) Matrix1D<Row,Value,Accessor>::Matrix1D(std::initializer_list< std::initializer_list<Value>> s)
: m_lData(*std::begin(s)) { : m_lData(*std::begin(s)) {
...@@ -113,3 +119,33 @@ Row Matrix1D<Row,Value,Accessor>::fromValue(const Value& value) const { ...@@ -113,3 +119,33 @@ Row Matrix1D<Row,Value,Accessor>::fromValue(const Value& value) const {
} }
return m_hReverseMapping[value]; 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;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment