/* * Copyright (C) 2016 Jolla Ltd * Contact: Andrew den Exter * * You may use this file under the terms of the BSD license as follows: * * "Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Nemo Mobile nor the names of its contributors * may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." */ #ifndef NEMODEVICELOCK_HOSTAUTHENTICATOR_H #define NEMODEVICELOCK_HOSTAUTHENTICATOR_H #include #include #include #include #include #include #include QT_BEGIN_NAMESPACE class QDBusConnection; QT_END_NAMESPACE namespace NemoDeviceLock { class HostAuthenticator; class HostAuthenticatorAdaptor : public QDBusAbstractAdaptor { Q_OBJECT Q_PROPERTY(uint AvailableMethods READ availableMethods) Q_CLASSINFO("D-Bus Interface", "org.nemomobile.devicelock.Authenticator") public: explicit HostAuthenticatorAdaptor(HostAuthenticator *authenticator); uint availableMethods() const; public slots: void Authenticate(const QDBusObjectPath &client, const QDBusVariant &challengeCode, uint methods); void RequestPermission( const QDBusObjectPath &path, const QString &message, const QVariantMap &properties, uint methods); void Cancel(const QDBusObjectPath &client); private: HostAuthenticator *m_authenticator; }; class HostSecurityCodeSettings; class HostSecurityCodeSettingsAdaptor : public QDBusAbstractAdaptor { Q_OBJECT Q_PROPERTY(bool SecurityCodeSet READ isSet NOTIFY setChanged) Q_CLASSINFO("D-Bus Interface", "org.nemomobile.devicelock.SecurityCodeSettings") public: explicit HostSecurityCodeSettingsAdaptor(HostAuthenticator *authenticator); bool isSet() const; public slots: void Change(const QDBusObjectPath &client, const QDBusVariant &challengeCode); void CancelChange(const QDBusObjectPath &client); void Clear(const QDBusObjectPath &client); void CancelClear(const QDBusObjectPath &client); signals: void setChanged(); private: HostAuthenticator * const m_authenticator; }; class HostAuthenticator : public HostAuthenticationInput { Q_OBJECT public: explicit HostAuthenticator( Authenticator::Methods supportedMethods = Authenticator::SecurityCode, QObject *parent = nullptr); ~HostAuthenticator(); // Authenticator virtual Authenticator::Methods availableMethods() const = 0; virtual QVariant authenticateChallengeCode( const QVariant &challengeCode, Authenticator::Method method, uint authenticatingPid) = 0; // SecurityCodeSettings virtual bool authorizeSecurityCodeSettings(unsigned long pid); virtual bool clearCode(const QString &code) = 0; // AuthenticationInput Availability availability(QVariantMap *feedbackData = nullptr) const override = 0; int checkCode(const QString &code) override = 0; int setCode(const QString &oldCode, const QString &newCode) override = 0; void enterSecurityCode(const QString &code) override; void requestSecurityCode() override; void authorize() override; void cancel() override; void confirmAuthentication(Authenticator::Method method) override; void abortAuthentication(AuthenticationInput::Error error) override; void authenticationStarted( Authenticator::Methods methods, uint authenticatingPid, AuthenticationInput::Feedback feedback) override; void authenticationEnded(bool confirmed) override; void checkCodeFinished(int result); void setCodeFinished(int result); // Signals void authenticated(const QVariant &authenticationToken); void aborted(); void securityCodeChanged(const QVariant &authenticationToken); void securityCodeChangeAborted(); void securityCodeCleared(); void securityCodeClearAborted(); void availableMethodsChanged(); void availabilityChanged(); private: enum StateFlag { ErrorFlag = 0x1000, EvaluatingFlag = 0x2000, CanceledFlag = 0x4000, CompletedFlag = 0x8000 }; enum State { Idle, Authenticating, AuthenticatingForChange, RequestingPermission, EnteringNewSecurityCode, RepeatingNewSecurityCode, ExpectingGeneratedSecurityCode, Changing, ChangeCanceled, AuthenticatingForClear, AuthenticationError = Authenticating | ErrorFlag, AuthenticationEvaluating = Authenticating | EvaluatingFlag, AuthenticationCanceled = Authenticating | CanceledFlag, AuthenticationCompleted = Authenticating | CompletedFlag, PermissionEvaluating = RequestingPermission | EvaluatingFlag, // The error and cancel states are shared with authenticating. ChangeError = AuthenticatingForChange | ErrorFlag, AuthenticationForChangeEvaluating = AuthenticatingForChange | EvaluatingFlag, AuthenticationForChangeCanceled = AuthenticatingForChange | CanceledFlag, ClearError = AuthenticatingForClear | ErrorFlag, AuthenticationForClearEvaluating = AuthenticatingForClear | EvaluatingFlag, AuthenticationForClearCanceled = AuthenticatingForClear | CanceledFlag, }; enum Request { NoRequest, AuthenticateRequest, PermissionRequest, ChangeRequest, ClearRequest }; inline bool isSecurityCodeSet() const; inline void authenticate( const QString &authenticator, const QVariant &challengeCode, Authenticator::Methods methods); inline void beginAuthenticate(uint pid, const QVariant &challengeCode, Authenticator::Methods methods); inline void requestPermission( const QString &client, const QString &message, const QVariantMap &properties, Authenticator::Methods methods); inline void beginRequestPermission( uint pid, const QString &message, const QVariantMap &properties, Authenticator::Methods methods); inline void handleChangeSecurityCode(const QString &client, const QVariant &challengeCode); inline void beginChangeSecurityCode(uint pid, const QVariant &challengeCode); inline void handleClearSecurityCode(const QString &client); inline void beginClearSecurityCode(uint pid); inline void handleCancel(const QString &client); inline void cancelPending(); inline void beginPending(); inline QVariantMap generatedCodeData(); inline void enterCodeChangeState( FeedbackFunction feedback, Authenticator::Methods methods = Authenticator::Methods()); friend class HostAuthenticatorAdaptor; friend class HostSecurityCodeSettingsAdaptor; HostAuthenticatorAdaptor m_adaptor; HostSecurityCodeSettingsAdaptor m_securityCodeAdaptor; struct Pending { QVariant challengeCode; QVariantMap properties; QString connection; QString client; QString message; uint pid = 0; Authenticator::Methods methods; Request request = NoRequest; void clear(); } m_pending; QVariant m_challengeCode; QString m_currentCode; QString m_newCode; QString m_generatedCode; int m_repeatsRequired; int m_authenticatingPid; State m_state; }; } #endif