Compare commits
	
		
			20 Commits
		
	
	
		
			gnome-3-26
			...
			wip/waylan
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 28f4030aa2 | ||
|   | 67fe376564 | ||
|   | fb824131ae | ||
|   | 056375cbcf | ||
|   | 84431cbc65 | ||
|   | 92c283da4d | ||
|   | 6e27ef8ff9 | ||
|   | 0c511c884b | ||
|   | 7afb503666 | ||
|   | 0b9d01a1c0 | ||
|   | b978d99820 | ||
|   | 6d8d094e0c | ||
|   | 97e0175f48 | ||
|   | ebef4ff174 | ||
|   | 82b8b32355 | ||
|   | 5b4337f716 | ||
|   | 5eb377bd3b | ||
|   | 8173110842 | ||
|   | fee97da26b | ||
|   | 0cc10e0c5d | 
| @@ -2,7 +2,7 @@ | ||||
| Type=Application | ||||
| _Name=GNOME Shell (wayland compositor) | ||||
| _Comment=Window management and application launching | ||||
| Exec=@bindir@/mutter-launch -- gnome-shell-wayland --wayland | ||||
| Exec=@bindir@/gnome-shell-wayland --wayland --display-server | ||||
| X-GNOME-Bugzilla-Bugzilla=GNOME | ||||
| X-GNOME-Bugzilla-Product=gnome-shell | ||||
| X-GNOME-Bugzilla-Component=general | ||||
|   | ||||
| @@ -24,24 +24,10 @@ const AuthPromptMode = { | ||||
|     UNLOCK_OR_LOG_IN: 1 | ||||
| }; | ||||
|  | ||||
| const AuthPromptStatus = { | ||||
|     NOT_VERIFYING: 0, | ||||
|     VERIFYING: 1, | ||||
|     VERIFICATION_FAILED: 2, | ||||
|     VERIFICATION_SUCCEEDED: 3 | ||||
| }; | ||||
|  | ||||
| const BeginRequestType = { | ||||
|     PROVIDE_USERNAME: 0, | ||||
|     DONT_PROVIDE_USERNAME: 1 | ||||
| }; | ||||
|  | ||||
| const AuthPrompt = new Lang.Class({ | ||||
|     Name: 'AuthPrompt', | ||||
|  | ||||
|     _init: function(gdmClient, mode) { | ||||
|         this.verificationStatus = AuthPromptStatus.NOT_VERIFYING; | ||||
|  | ||||
|         this._gdmClient = gdmClient; | ||||
|         this._mode = mode; | ||||
|  | ||||
| @@ -53,14 +39,11 @@ const AuthPrompt = new Lang.Class({ | ||||
|  | ||||
|         this._userVerifier = new GdmUtil.ShellUserVerifier(this._gdmClient, { reauthenticationOnly: reauthenticationOnly }); | ||||
|  | ||||
|         this._userVerifier.connect('needs-username', Lang.bind(this, this._onNeedsUserName)); | ||||
|         this._userVerifier.connect('ask-question', Lang.bind(this, this._onAskQuestion)); | ||||
|         this._userVerifier.connect('show-message', Lang.bind(this, this._onShowMessage)); | ||||
|         this._userVerifier.connect('verification-failed', Lang.bind(this, this._onVerificationFailed)); | ||||
|         this._userVerifier.connect('verification-complete', Lang.bind(this, this._onVerificationComplete)); | ||||
|         this._userVerifier.connect('reset', Lang.bind(this, this._onReset)); | ||||
|         this._userVerifier.connect('smartcard-status-changed', Lang.bind(this, this._onSmartcardStatusChanged)); | ||||
|         this._userVerifier.connect('ovirt-user-authenticated', Lang.bind(this, this._onOVirtUserAuthenticated)); | ||||
|         this.smartcardDetected = this._userVerifier.smartcardDetected; | ||||
|  | ||||
|         this.connect('next', Lang.bind(this, function() { | ||||
|                          this.updateSensitivity(false); | ||||
| @@ -133,6 +116,10 @@ const AuthPrompt = new Lang.Class({ | ||||
|         this._defaultButtonWell.add_child(this._spinner.actor); | ||||
|     }, | ||||
|  | ||||
|     get verificationStatus() { | ||||
|         return this._userVerifier.verificationStatus; | ||||
|     }, | ||||
|  | ||||
|     _onDestroy: function() { | ||||
|         this._userVerifier.clear(); | ||||
|         this._userVerifier.disconnectAll(); | ||||
| @@ -193,6 +180,14 @@ const AuthPrompt = new Lang.Class({ | ||||
|         })); | ||||
|     }, | ||||
|  | ||||
|     _onNeedsUserName: function() { | ||||
|         this.emit('needs-username'); | ||||
|     }, | ||||
|  | ||||
|     gotUserName: function(userName) { | ||||
|         this._userVerifier.gotUserName(userName); | ||||
|     }, | ||||
|  | ||||
|     _onAskQuestion: function(verifier, serviceName, question, passwordChar) { | ||||
|         if (this._preemptiveAnswer) { | ||||
|             if (this._queryingService) | ||||
| @@ -221,30 +216,6 @@ const AuthPrompt = new Lang.Class({ | ||||
|         this.emit('prompted'); | ||||
|     }, | ||||
|  | ||||
|     _onOVirtUserAuthenticated: function() { | ||||
|         if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED) | ||||
|             this.reset(); | ||||
|     }, | ||||
|  | ||||
|     _onSmartcardStatusChanged: function() { | ||||
|         this.smartcardDetected = this._userVerifier.smartcardDetected; | ||||
|  | ||||
|         // Most of the time we want to reset if the user inserts or removes | ||||
|         // a smartcard. Smartcard insertion "preempts" what the user was | ||||
|         // doing, and smartcard removal aborts the preemption. | ||||
|         // The exceptions are: 1) Don't reset on smartcard insertion if we're already verifying | ||||
|         //                        with a smartcard | ||||
|         //                     2) Don't reset if we've already succeeded at verification and | ||||
|         //                        the user is getting logged in. | ||||
|         if (this._userVerifier.serviceIsDefault(GdmUtil.SMARTCARD_SERVICE_NAME) && | ||||
|             this.verificationStatus == AuthPromptStatus.VERIFYING && | ||||
|             this.smartcardDetected) | ||||
|             return; | ||||
|  | ||||
|         if (this.verificationStatus != AuthPromptStatus.VERIFICATION_SUCCEEDED) | ||||
|             this.reset(); | ||||
|     }, | ||||
|  | ||||
|     _onShowMessage: function(userVerifier, message, type) { | ||||
|         this.setMessage(message, type); | ||||
|         this.emit('prompted'); | ||||
| @@ -256,15 +227,11 @@ const AuthPrompt = new Lang.Class({ | ||||
|  | ||||
|         this.updateSensitivity(true); | ||||
|         this.setActorInDefaultButtonWell(null); | ||||
|         this.verificationStatus = AuthPromptStatus.VERIFICATION_FAILED; | ||||
|     }, | ||||
|  | ||||
|     _onVerificationComplete: function() { | ||||
|         this.verificationStatus = AuthPromptStatus.VERIFICATION_SUCCEEDED; | ||||
|         this.emit('failed'); | ||||
|     }, | ||||
|  | ||||
|     _onReset: function() { | ||||
|         this.verificationStatus = AuthPromptStatus.NOT_VERIFYING; | ||||
|         this.reset(); | ||||
|     }, | ||||
|  | ||||
| @@ -428,39 +395,13 @@ const AuthPrompt = new Lang.Class({ | ||||
|     }, | ||||
|  | ||||
|     reset: function() { | ||||
|         let oldStatus = this.verificationStatus; | ||||
|         this.verificationStatus = AuthPromptStatus.NOT_VERIFYING; | ||||
|  | ||||
|         if (oldStatus == AuthPromptStatus.VERIFYING) | ||||
|             this._userVerifier.cancel(); | ||||
|  | ||||
|         this._queryingService = null; | ||||
|         this.clear(); | ||||
|         this._message.opacity = 0; | ||||
|         this.setUser(null); | ||||
|         this.stopSpinning(); | ||||
|  | ||||
|         if (oldStatus == AuthPromptStatus.VERIFICATION_FAILED) | ||||
|             this.emit('failed'); | ||||
|  | ||||
|         let beginRequestType; | ||||
|  | ||||
|         if (this._mode == AuthPromptMode.UNLOCK_ONLY) { | ||||
|             // The user is constant at the unlock screen, so it will immediately | ||||
|             // respond to the request with the username | ||||
|             beginRequestType = BeginRequestType.PROVIDE_USERNAME; | ||||
|         } else if (this._userVerifier.serviceIsForeground(GdmUtil.OVIRT_SERVICE_NAME) || | ||||
|                    (this.smartcardDetected && | ||||
|                     this._userVerifier.serviceIsForeground(GdmUtil.SMARTCARD_SERVICE_NAME))) { | ||||
|             // We don't need to know the username if the user preempted the login screen | ||||
|             // with a smartcard or with preauthenticated oVirt credentials | ||||
|             beginRequestType = BeginRequestType.DONT_PROVIDE_USERNAME; | ||||
|         } else { | ||||
|             // In all other cases, we should get the username up front. | ||||
|             beginRequestType = BeginRequestType.PROVIDE_USERNAME; | ||||
|         } | ||||
|  | ||||
|         this.emit('reset', beginRequestType); | ||||
|         this.emit('reset'); | ||||
|     }, | ||||
|  | ||||
|     addCharacter: function(unichar) { | ||||
| @@ -471,18 +412,13 @@ const AuthPrompt = new Lang.Class({ | ||||
|         this._entry.clutter_text.insert_unichar(unichar); | ||||
|     }, | ||||
|  | ||||
|     begin: function(params) { | ||||
|         params = Params.parse(params, { userName: null, | ||||
|                                         hold: null }); | ||||
|  | ||||
|     begin: function() { | ||||
|         this.updateSensitivity(false); | ||||
|         this._userVerifier.begin(); | ||||
|     }, | ||||
|  | ||||
|         let hold = params.hold; | ||||
|         if (!hold) | ||||
|             hold = new Batch.Hold(); | ||||
|  | ||||
|         this._userVerifier.begin(params.userName, hold); | ||||
|         this.verificationStatus = AuthPromptStatus.VERIFYING; | ||||
|     needsUsername: function() { | ||||
|         this._userVerifier.begin(userName); | ||||
|     }, | ||||
|  | ||||
|     finish: function(onComplete) { | ||||
| @@ -500,7 +436,6 @@ const AuthPrompt = new Lang.Class({ | ||||
|  | ||||
|     cancel: function() { | ||||
|         this.reset(); | ||||
|         this.emit('cancelled'); | ||||
|     } | ||||
| }); | ||||
| Signals.addSignalMethods(AuthPrompt.prototype); | ||||
|   | ||||
| @@ -421,6 +421,7 @@ const LoginDialog = new Lang.Class({ | ||||
|         this._authPrompt = new AuthPrompt.AuthPrompt(gdmClient, AuthPrompt.AuthPromptMode.UNLOCK_OR_LOG_IN); | ||||
|         this._authPrompt.connect('prompted', Lang.bind(this, this._onPrompted)); | ||||
|         this._authPrompt.connect('reset', Lang.bind(this, this._onReset)); | ||||
|         this._authPrompt.connect('needs-username', Lang.bind(this, this._onNeedsUserName)); | ||||
|         this._authPrompt.hide(); | ||||
|         this.actor.add_child(this._authPrompt.actor); | ||||
|  | ||||
| @@ -469,14 +470,15 @@ const LoginDialog = new Lang.Class({ | ||||
|         this._sessionMenuButton.actor.show(); | ||||
|         this._authPrompt.addActorToDefaultButtonWell(this._sessionMenuButton.actor); | ||||
|  | ||||
|         this._disableUserList = undefined; | ||||
|         this._updateDisableUserList(); | ||||
|         this._userListLoaded = false; | ||||
|  | ||||
|         LoginManager.getLoginManager().getCurrentSessionProxy(Lang.bind(this, this._gotGreeterSessionProxy)); | ||||
|  | ||||
|         // If the user list is enabled, it should take key focus; make sure the | ||||
|         // screen shield is initialized first to prevent it from stealing the | ||||
|         // focus later | ||||
|         Main.layoutManager.connect('startup-complete', | ||||
|                                    Lang.bind(this, this._updateDisableUserList)); | ||||
|         Main.layoutManager.connect('startup-complete', Lang.bind(this, this._reset)); | ||||
|     }, | ||||
|  | ||||
|     _ensureUserListLoaded: function() { | ||||
| @@ -493,15 +495,20 @@ const LoginDialog = new Lang.Class({ | ||||
|             GLib.idle_add(GLib.PRIORITY_DEFAULT, Lang.bind(this, this._loadUserList)); | ||||
|     }, | ||||
|  | ||||
|     _reset: function() { | ||||
|         this._authPrompt.reset(); | ||||
|         this._authPrompt.begin(); | ||||
|     }, | ||||
|  | ||||
|     _updateDisableUserList: function() { | ||||
|         let disableUserList = this._settings.get_boolean(GdmUtil.DISABLE_USER_LIST_KEY); | ||||
|         if (disableUserList == this._disableUserList) | ||||
|             return; | ||||
|  | ||||
|         if (disableUserList != this._disableUserList) { | ||||
|             this._disableUserList = disableUserList; | ||||
|         this._disableUserList = disableUserList; | ||||
|  | ||||
|             if (this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING) | ||||
|                 this._authPrompt.reset(); | ||||
|         } | ||||
|         if (this._authPrompt.verificationStatus == GdmUtil.VerificationStatus.ASKING_FOR_USERNAME) | ||||
|             this._reset(); | ||||
|     }, | ||||
|  | ||||
|     _updateCancelButton: function() { | ||||
| @@ -509,7 +516,7 @@ const LoginDialog = new Lang.Class({ | ||||
|  | ||||
|         // Hide the cancel button if the user list is disabled and we're asking for | ||||
|         // a username | ||||
|         if (this._authPrompt.verificationStatus == AuthPrompt.AuthPromptStatus.NOT_VERIFYING && this._disableUserList) | ||||
|         if (this._authPrompt.verificationStatus == GdmUtil.VerificationStatus.ASKING_FOR_USERNAME && this._disableUserList) | ||||
|             cancelVisible = false; | ||||
|         else | ||||
|             cancelVisible = true; | ||||
| @@ -554,19 +561,18 @@ const LoginDialog = new Lang.Class({ | ||||
|         this._showPrompt(); | ||||
|     }, | ||||
|  | ||||
|     _onReset: function(authPrompt, beginRequest) { | ||||
|     _onReset: function() { | ||||
|         this._sessionMenuButton.updateSensitivity(true); | ||||
|  | ||||
|         this._user = null; | ||||
|  | ||||
|         if (beginRequest == AuthPrompt.BeginRequestType.PROVIDE_USERNAME) { | ||||
|             if (!this._disableUserList) | ||||
|                 this._showUserList(); | ||||
|             else | ||||
|                 this._hideUserListAskForUsernameAndBeginVerification(); | ||||
|         } else { | ||||
|             this._hideUserListAndBeginVerification(); | ||||
|         } | ||||
|         this._reset(); | ||||
|     }, | ||||
|  | ||||
|     _onNeedsUserName: function() { | ||||
|         if (!this._disableUserList) | ||||
|             this._showUserList(); | ||||
|         else | ||||
|             this._hideUserListAskForUsernameAndBeginVerification(); | ||||
|     }, | ||||
|  | ||||
|     _onDefaultSessionChanged: function(client, sessionId) { | ||||
| @@ -574,8 +580,8 @@ const LoginDialog = new Lang.Class({ | ||||
|     }, | ||||
|  | ||||
|     _shouldShowSessionMenuButton: function() { | ||||
|         if (this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.VERIFYING && | ||||
|             this._authPrompt.verificationStatus != AuthPrompt.AuthPromptStatus.VERIFICATION_FAILED) | ||||
|         if (this._authPrompt.verificationStatus != GdmUtil.VerificationStatus.VERIFYING && | ||||
|             this._authPrompt.verificationStatus != GdmUtil.VerificationStatus.VERIFICATION_FAILED) | ||||
|           return false; | ||||
|  | ||||
|         if (this._user && this._user.is_loaded && this._user.is_logged_in()) | ||||
| @@ -625,7 +631,7 @@ const LoginDialog = new Lang.Class({ | ||||
|                                                         this._user = this._userManager.get_user(answer); | ||||
|                                                         this._authPrompt.clear(); | ||||
|                                                         this._authPrompt.startSpinning(); | ||||
|                                                         this._authPrompt.begin({ userName: answer }); | ||||
|                                                         this._authPrompt.gotUserName(answer); | ||||
|                                                         this._updateCancelButton(); | ||||
|  | ||||
|                                                         realmManager.disconnect(realmSignalId) | ||||
| @@ -635,6 +641,32 @@ const LoginDialog = new Lang.Class({ | ||||
|         this._showPrompt(); | ||||
|     }, | ||||
|  | ||||
|     _sessionActivated: function() { | ||||
|         // We fade out the shell after logging in, and then re-set | ||||
|         // the greeter wen we're VT switched to again. | ||||
|  | ||||
|         // XXX: re-trigger startup animation | ||||
|         if (this._authPrompt.verificationStatus == GdmUtil.VerificationStatus.VERIFICATION_SUCCEEDED) { | ||||
|             this._reset(); | ||||
|  | ||||
|             // XXX: do something better here | ||||
|             this.actor.opacity = 255; | ||||
|  | ||||
|             let children = Main.layoutManager.uiGroup.get_children(); | ||||
|             for (let i = 0; i < children.length; i++) { | ||||
|                 if (children[i] != Main.layoutManager.screenShieldGroup) | ||||
|                     children[i].opacity = 255; | ||||
|             } | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     _gotGreeterSessionProxy: function(proxy) { | ||||
|         proxy.connect('g-properties-changed', Lang.bind(this, function() { | ||||
|             if (proxy.Active) | ||||
|                 this._sessionActivated(); | ||||
|         })); | ||||
|     }, | ||||
|  | ||||
|     _startSession: function(serviceName) { | ||||
|         Tweener.addTween(this.actor, | ||||
|                          { opacity: 0, | ||||
| @@ -805,11 +837,6 @@ const LoginDialog = new Lang.Class({ | ||||
|         this._askForUsernameAndBeginVerification(); | ||||
|     }, | ||||
|  | ||||
|     _hideUserListAndBeginVerification: function() { | ||||
|         this._hideUserList(); | ||||
|         this._authPrompt.begin(); | ||||
|     }, | ||||
|  | ||||
|     _showUserList: function() { | ||||
|         this._ensureUserListLoaded(); | ||||
|         this._authPrompt.hide(); | ||||
| @@ -823,11 +850,7 @@ const LoginDialog = new Lang.Class({ | ||||
|         this._authPrompt.setUser(item.user); | ||||
|  | ||||
|         let userName = item.user.get_user_name(); | ||||
|         let hold = new Batch.Hold(); | ||||
|  | ||||
|         this._authPrompt.begin({ userName: userName, | ||||
|                                  hold: hold }); | ||||
|         return hold; | ||||
|         this._authPrompt.gotUserName(userName); | ||||
|     }, | ||||
|  | ||||
|     _onUserListActivated: function(activatedItem) { | ||||
| @@ -842,9 +865,9 @@ const LoginDialog = new Lang.Class({ | ||||
|  | ||||
|         this._updateCancelButton(); | ||||
|  | ||||
|         let batch = new Batch.ConcurrentBatch(this, [new Batch.ConsecutiveBatch(this, tasks), | ||||
|                                                      this._beginVerificationForItem(activatedItem)]); | ||||
|         let batch = new Batch.ConsecutiveBatch(this, tasks); | ||||
|         batch.run(); | ||||
|         this._beginVerificationForItem(activatedItem); | ||||
|     }, | ||||
|  | ||||
|     _onDestroy: function() { | ||||
|   | ||||
							
								
								
									
										214
									
								
								js/gdm/util.js
									
									
									
									
									
								
							
							
						
						
									
										214
									
								
								js/gdm/util.js
									
									
									
									
									
								
							| @@ -119,6 +119,14 @@ function cloneAndFadeOutActor(actor) { | ||||
|     return hold; | ||||
| } | ||||
|  | ||||
| const VerificationStatus = { | ||||
|     NOT_VERIFYING: 0, | ||||
|     ASKING_FOR_USERNAME: 1, | ||||
|     VERIFYING: 2, | ||||
|     VERIFICATION_FAILED: 3, | ||||
|     VERIFICATION_SUCCEEDED: 4, | ||||
| }; | ||||
|  | ||||
| const ShellUserVerifier = new Lang.Class({ | ||||
|     Name: 'ShellUserVerifier', | ||||
|  | ||||
| @@ -131,7 +139,6 @@ const ShellUserVerifier = new Lang.Class({ | ||||
|         this._settings = new Gio.Settings({ schema: LOGIN_SCREEN_SCHEMA }); | ||||
|         this._settings.connect('changed', | ||||
|                                Lang.bind(this, this._updateDefaultService)); | ||||
|         this._updateDefaultService(); | ||||
|  | ||||
|         this._fprintManager = new Fprint.FprintManager(); | ||||
|         this._smartcardManager = SmartcardManager.getSmartcardManager(); | ||||
| @@ -152,45 +159,69 @@ const ShellUserVerifier = new Lang.Class({ | ||||
|         this.hasPendingMessages = false; | ||||
|         this.reauthenticating = false; | ||||
|  | ||||
|         this._failCounter = 0; | ||||
|  | ||||
|         this._oVirtCredentialsManager = OVirt.getOVirtCredentialsManager(); | ||||
|  | ||||
|         this._oVirtCredentialsManager.connect('user-authenticated', Lang.bind(this, this._oVirtUserAuthenticated)); | ||||
|         if (this._oVirtCredentialsManager.hasToken()) | ||||
|             this._oVirtUserAuthenticated(this._oVirtCredentialsManager.getToken()); | ||||
|  | ||||
|         this._oVirtCredentialsManager.connect('user-authenticated', | ||||
|                                               Lang.bind(this, this._oVirtUserAuthenticated)); | ||||
|         this._reset(); | ||||
|     }, | ||||
|  | ||||
|     begin: function(userName, hold) { | ||||
|         this._cancellable = new Gio.Cancellable(); | ||||
|         this._hold = hold; | ||||
|     _reset: function() { | ||||
|         // Clear previous attempts to authenticate | ||||
|         this.verificationStatus = VerificationStatus.NOT_VERIFYING; | ||||
|         this._userName = null; | ||||
|         this._failCounter = 0; | ||||
|         this._updateDefaultService(); | ||||
|         this.emit('reset'); | ||||
|     }, | ||||
|  | ||||
|     begin: function() { | ||||
|         if (this._mode == AuthPromptMode.UNLOCK_ONLY) { | ||||
|             // The user is constant at the unlock screen, so it will immediately | ||||
|             // respond to the request with the username | ||||
|             needsUsername = true; | ||||
|         } else if (this._serviceIsForeground(GdmUtil.OVIRT_SERVICE_NAME) || | ||||
|                    (this._smartcardDetected && | ||||
|                     this._serviceIsForeground(GdmUtil.SMARTCARD_SERVICE_NAME))) { | ||||
|             // We don't need to know the username if the user preempted the login screen | ||||
|             // with a smartcard or with preauthenticated oVirt credentials | ||||
|             needsUsername = false; | ||||
|         } else { | ||||
|             // In all other cases, we should get the username up front. | ||||
|             needsUsername = true; | ||||
|         } | ||||
|  | ||||
|         if (needsUsername) { | ||||
|             this.verificationStatus = VerificationStatus.ASKING_FOR_USERNAME; | ||||
|             this.emit('needs-username'); | ||||
|         } else { | ||||
|             this._beginAuthentication(); | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     gotUserName: function(userName) { | ||||
|         this._userName = userName; | ||||
|         this._beginAuthentication(); | ||||
|     }, | ||||
|  | ||||
|     _beginAuthentication: function() { | ||||
|         this.verificationStatus = VerificationStatus.VERIFYING; | ||||
|         this._cancellable = new Gio.Cancellable(); | ||||
|         this.reauthenticating = false; | ||||
|  | ||||
|         this._checkForFingerprintReader(); | ||||
|  | ||||
|         if (userName) { | ||||
|         if (this._userName) { | ||||
|             // If possible, reauthenticate an already running session, | ||||
|             // so any session specific credentials get updated appropriately | ||||
|             this._client.open_reauthentication_channel(userName, this._cancellable, | ||||
|             this._client.open_reauthentication_channel(this._userName, this._cancellable, | ||||
|                                                        Lang.bind(this, this._reauthenticationChannelOpened)); | ||||
|         } else { | ||||
|             this._client.get_user_verifier(this._cancellable, Lang.bind(this, this._userVerifierGot)); | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     cancel: function() { | ||||
|         if (this._cancellable) | ||||
|             this._cancellable.cancel(); | ||||
|  | ||||
|         if (this._userVerifier) { | ||||
|             this._userVerifier.call_cancel_sync(null); | ||||
|             this.clear(); | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     clear: function() { | ||||
|         if (this._cancellable) { | ||||
|             this._cancellable.cancel(); | ||||
| @@ -198,6 +229,7 @@ const ShellUserVerifier = new Lang.Class({ | ||||
|         } | ||||
|  | ||||
|         if (this._userVerifier) { | ||||
|             this._userVerifier.call_cancel_sync(null); | ||||
|             this._userVerifier.run_dispose(); | ||||
|             this._userVerifier = null; | ||||
|         } | ||||
| @@ -205,24 +237,29 @@ const ShellUserVerifier = new Lang.Class({ | ||||
|         this._clearMessageQueue(); | ||||
|     }, | ||||
|  | ||||
|     answerQuery: function(serviceName, answer) { | ||||
|         if (!this.hasPendingMessages) { | ||||
|             this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null); | ||||
|     _doAfterPendingMessages: function(func) { | ||||
|         if (this.hasPendingMessages) { | ||||
|             let signalId = this.connect('no-more-messages', Lang.bind(this, function() { | ||||
|                 this.disconnect(signalId); | ||||
|                 func(); | ||||
|             })); | ||||
|         } else { | ||||
|             let signalId = this.connect('no-more-messages', | ||||
|                                         Lang.bind(this, function() { | ||||
|                                             this.disconnect(signalId); | ||||
|                                             this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null); | ||||
|                                         })); | ||||
|             func(); | ||||
|         } | ||||
|     }, | ||||
|  | ||||
|     answerQuery: function(serviceName, answer) { | ||||
|         this._doAfterPendingMessages(Lang.bind(this, function() { | ||||
|             this._userVerifier.call_answer_query(serviceName, answer, this._cancellable, null); | ||||
|         })); | ||||
|     }, | ||||
|  | ||||
|     _getIntervalForMessage: function(message) { | ||||
|         // We probably could be smarter here | ||||
|         return message.length * USER_READ_TIME; | ||||
|     }, | ||||
|  | ||||
|     finishMessageQueue: function() { | ||||
|     _finishMessageQueue: function() { | ||||
|         if (!this.hasPendingMessages) | ||||
|             return; | ||||
|  | ||||
| @@ -234,7 +271,7 @@ const ShellUserVerifier = new Lang.Class({ | ||||
|  | ||||
|     _queueMessageTimeout: function() { | ||||
|         if (this._messageQueue.length == 0) { | ||||
|             this.finishMessageQueue(); | ||||
|             this._finishMessageQueue(); | ||||
|             return; | ||||
|         } | ||||
|  | ||||
| @@ -263,7 +300,7 @@ const ShellUserVerifier = new Lang.Class({ | ||||
|     }, | ||||
|  | ||||
|     _clearMessageQueue: function() { | ||||
|         this.finishMessageQueue(); | ||||
|         this._finishMessageQueue(); | ||||
|  | ||||
|         if (this._messageQueueTimeoutId != 0) { | ||||
|             GLib.source_remove(this._messageQueueTimeoutId); | ||||
| @@ -288,9 +325,9 @@ const ShellUserVerifier = new Lang.Class({ | ||||
|             })); | ||||
|     }, | ||||
|  | ||||
|     _oVirtUserAuthenticated: function(token) { | ||||
|         this._preemptingService = OVIRT_SERVICE_NAME; | ||||
|         this.emit('ovirt-user-authenticated'); | ||||
|     _oVirtUserAuthenticated: function() { | ||||
|         if (this.verificationStatus != GdmUtil.VerificationStatus.VERIFICATION_SUCCEEDED) | ||||
|             this._reset(); | ||||
|     }, | ||||
|  | ||||
|     _checkForSmartcard: function() { | ||||
| @@ -303,21 +340,29 @@ const ShellUserVerifier = new Lang.Class({ | ||||
|         else | ||||
|             smartcardDetected = this._smartcardManager.hasInsertedTokens(); | ||||
|  | ||||
|         if (smartcardDetected != this.smartcardDetected) { | ||||
|             this.smartcardDetected = smartcardDetected; | ||||
|         if (this._smartcardDetected == smartcardDetected) | ||||
|             return; | ||||
|  | ||||
|             if (this.smartcardDetected) | ||||
|                 this._preemptingService = SMARTCARD_SERVICE_NAME; | ||||
|             else if (this._preemptingService == SMARTCARD_SERVICE_NAME) | ||||
|                 this._preemptingService = null; | ||||
|         this._smartcardDetected = smartcardDetected; | ||||
|  | ||||
|             this.emit('smartcard-status-changed'); | ||||
|         } | ||||
|         // Most of the time we want to reset if the user inserts or removes | ||||
|         // a smartcard. Smartcard insertion "preempts" what the user was | ||||
|         // doing, and smartcard removal aborts the preemption. | ||||
|         // The exceptions are: 1) Don't reset on smartcard insertion if we're already verifying | ||||
|         //                        with a smartcard | ||||
|         //                     2) Don't reset if we've already succeeded at verification and | ||||
|         //                        the user is getting logged in. | ||||
|         if (this._serviceIsDefault(SMARTCARD_SERVICE_NAME) && | ||||
|             this.verificationStatus == VerificationStatus.VERIFYING && | ||||
|             this._smartcardDetected) | ||||
|             return; | ||||
|  | ||||
|         if (this.verificationStatus != VerificationStatus.VERIFICATION_SUCCEEDED) | ||||
|             this._reset(); | ||||
|     }, | ||||
|  | ||||
|     _reportInitError: function(where, error) { | ||||
|         logError(error, where); | ||||
|         this._hold.release(); | ||||
|  | ||||
|         this._queueMessage(_("Authentication error"), MessageType.ERROR); | ||||
|         this._verificationFailed(false); | ||||
| @@ -343,7 +388,6 @@ const ShellUserVerifier = new Lang.Class({ | ||||
|         this.reauthenticating = true; | ||||
|         this._connectSignals(); | ||||
|         this._beginVerification(); | ||||
|         this._hold.release(); | ||||
|     }, | ||||
|  | ||||
|     _userVerifierGot: function(client, result) { | ||||
| @@ -358,7 +402,6 @@ const ShellUserVerifier = new Lang.Class({ | ||||
|  | ||||
|         this._connectSignals(); | ||||
|         this._beginVerification(); | ||||
|         this._hold.release(); | ||||
|     }, | ||||
|  | ||||
|     _connectSignals: function() { | ||||
| @@ -372,31 +415,32 @@ const ShellUserVerifier = new Lang.Class({ | ||||
|     }, | ||||
|  | ||||
|     _getForegroundService: function() { | ||||
|         if (this._preemptingService) | ||||
|             return this._preemptingService; | ||||
|         if (this._oVirtCredentialsManager.hasToken()) | ||||
|             return OVIRT_SERVICE_NAME; | ||||
|         if (this._smartcardDetected) | ||||
|             return SMARTCARD_SERVICE_NAME; | ||||
|  | ||||
|         return this._defaultService; | ||||
|     }, | ||||
|  | ||||
|     serviceIsForeground: function(serviceName) { | ||||
|     _serviceIsForeground: function(serviceName) { | ||||
|         return serviceName == this._getForegroundService(); | ||||
|     }, | ||||
|  | ||||
|     serviceIsDefault: function(serviceName) { | ||||
|     _serviceIsDefault: function(serviceName) { | ||||
|         return serviceName == this._defaultService; | ||||
|     }, | ||||
|  | ||||
|     _updateDefaultService: function() { | ||||
|         if (this._settings.get_boolean(PASSWORD_AUTHENTICATION_KEY)) | ||||
|             this._defaultService = PASSWORD_SERVICE_NAME; | ||||
|         else if (this.smartcardDetected) | ||||
|         else if (this._smartcardDetected) | ||||
|             this._defaultService = SMARTCARD_SERVICE_NAME; | ||||
|         else if (this._haveFingerprintReader) | ||||
|             this._defaultService = FINGERPRINT_SERVICE_NAME; | ||||
|     }, | ||||
|  | ||||
|     _startService: function(serviceName) { | ||||
|         this._hold.acquire(); | ||||
|         if (this._userName) { | ||||
|            this._userVerifier.call_begin_verification_for_user(serviceName, | ||||
|                                                                this._userName, | ||||
| @@ -410,8 +454,6 @@ const ShellUserVerifier = new Lang.Class({ | ||||
|                    this._reportInitError('Failed to start verification for user', e); | ||||
|                    return; | ||||
|                } | ||||
|  | ||||
|                this._hold.release(); | ||||
|            })); | ||||
|         } else { | ||||
|            this._userVerifier.call_begin_verification(serviceName, | ||||
| @@ -425,8 +467,6 @@ const ShellUserVerifier = new Lang.Class({ | ||||
|                    this._reportInitError('Failed to start verification', e); | ||||
|                    return; | ||||
|                } | ||||
|  | ||||
|                this._hold.release(); | ||||
|            })); | ||||
|         } | ||||
|     }, | ||||
| @@ -434,12 +474,12 @@ const ShellUserVerifier = new Lang.Class({ | ||||
|     _beginVerification: function() { | ||||
|         this._startService(this._getForegroundService()); | ||||
|  | ||||
|         if (this._userName && this._haveFingerprintReader && !this.serviceIsForeground(FINGERPRINT_SERVICE_NAME)) | ||||
|         if (this._userName && this._haveFingerprintReader && !this._serviceIsForeground(FINGERPRINT_SERVICE_NAME)) | ||||
|             this._startService(FINGERPRINT_SERVICE_NAME); | ||||
|     }, | ||||
|  | ||||
|     _onInfo: function(client, serviceName, info) { | ||||
|         if (this.serviceIsForeground(serviceName)) { | ||||
|         if (this._serviceIsForeground(serviceName)) { | ||||
|             this._queueMessage(info, MessageType.INFO); | ||||
|         } else if (serviceName == FINGERPRINT_SERVICE_NAME && | ||||
|             this._haveFingerprintReader) { | ||||
| @@ -454,21 +494,21 @@ const ShellUserVerifier = new Lang.Class({ | ||||
|     }, | ||||
|  | ||||
|     _onProblem: function(client, serviceName, problem) { | ||||
|         if (!this.serviceIsForeground(serviceName)) | ||||
|         if (!this._serviceIsForeground(serviceName)) | ||||
|             return; | ||||
|  | ||||
|         this._queueMessage(problem, MessageType.ERROR); | ||||
|     }, | ||||
|  | ||||
|     _onInfoQuery: function(client, serviceName, question) { | ||||
|         if (!this.serviceIsForeground(serviceName)) | ||||
|         if (!this._serviceIsForeground(serviceName)) | ||||
|             return; | ||||
|  | ||||
|         this.emit('ask-question', serviceName, question, ''); | ||||
|     }, | ||||
|  | ||||
|     _onSecretInfoQuery: function(client, serviceName, secretQuestion) { | ||||
|         if (!this.serviceIsForeground(serviceName)) | ||||
|         if (!this._serviceIsForeground(serviceName)) | ||||
|             return; | ||||
|  | ||||
|         if (serviceName == OVIRT_SERVICE_NAME) { | ||||
| @@ -481,24 +521,11 @@ const ShellUserVerifier = new Lang.Class({ | ||||
|     }, | ||||
|  | ||||
|     _onReset: function() { | ||||
|         // Clear previous attempts to authenticate | ||||
|         this._failCounter = 0; | ||||
|         this._updateDefaultService(); | ||||
|  | ||||
|         this.emit('reset'); | ||||
|         this._reset(); | ||||
|     }, | ||||
|  | ||||
|     _onVerificationComplete: function() { | ||||
|         this.emit('verification-complete'); | ||||
|     }, | ||||
|  | ||||
|     _cancelAndReset: function() { | ||||
|         this.cancel(); | ||||
|         this._onReset(); | ||||
|     }, | ||||
|  | ||||
|     _retry: function() { | ||||
|         this.begin(this._userName, new Batch.Hold()); | ||||
|         this.verificationStatus = VerificationStatus.VERIFICATION_SUCCEEDED; | ||||
|     }, | ||||
|  | ||||
|     _verificationFailed: function(retry) { | ||||
| @@ -511,38 +538,23 @@ const ShellUserVerifier = new Lang.Class({ | ||||
|         let canRetry = retry && this._userName && | ||||
|             this._failCounter < this._settings.get_int(ALLOWED_FAILURES_KEY); | ||||
|  | ||||
|         if (canRetry) { | ||||
|             if (!this.hasPendingMessages) { | ||||
|                 this._retry(); | ||||
|             } else { | ||||
|                 let signalId = this.connect('no-more-messages', | ||||
|                                             Lang.bind(this, function() { | ||||
|                                                 this.disconnect(signalId); | ||||
|                                                 this._retry(); | ||||
|                                             })); | ||||
|             } | ||||
|         } else { | ||||
|             if (!this.hasPendingMessages) { | ||||
|                 this._cancelAndReset(); | ||||
|             } else { | ||||
|                 let signalId = this.connect('no-more-messages', | ||||
|                                             Lang.bind(this, function() { | ||||
|                                                 this.disconnect(signalId); | ||||
|                                                 this._cancelAndReset(); | ||||
|                                             })); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         this.verificationStatus = VerificationStatus.VERIFICATION_FAILED; | ||||
|         this.emit('verification-failed'); | ||||
|  | ||||
|         this._doAfterPendingMessages(Lang.bind(this, function() { | ||||
|             if (canRetry) | ||||
|                 this._beginAuthentication(); | ||||
|             else | ||||
|                 this.clear(); | ||||
|         })); | ||||
|     }, | ||||
|  | ||||
|     _onConversationStopped: function(client, serviceName) { | ||||
|         // If the login failed with the preauthenticated oVirt credentials | ||||
|         // then discard the credentials and revert to default authentication | ||||
|         // mechanism. | ||||
|         if (this.serviceIsForeground(OVIRT_SERVICE_NAME)) { | ||||
|         if (this._serviceIsForeground(OVIRT_SERVICE_NAME)) { | ||||
|             this._oVirtCredentialsManager.resetToken(); | ||||
|             this._preemptingService = null; | ||||
|             this._verificationFailed(false); | ||||
|             return; | ||||
|         } | ||||
| @@ -550,7 +562,7 @@ const ShellUserVerifier = new Lang.Class({ | ||||
|         // if the password service fails, then cancel everything. | ||||
|         // But if, e.g., fingerprint fails, still give | ||||
|         // password authentication a chance to succeed | ||||
|         if (this.serviceIsForeground(serviceName)) { | ||||
|         if (this._serviceIsForeground(serviceName)) { | ||||
|             this._verificationFailed(true); | ||||
|         } | ||||
|     }, | ||||
|   | ||||
| @@ -39,6 +39,7 @@ const SystemdLoginSessionIface = '<node> \ | ||||
| <interface name="org.freedesktop.login1.Session"> \ | ||||
| <signal name="Lock" /> \ | ||||
| <signal name="Unlock" /> \ | ||||
| <property name="Active" access="readonly" /> \ | ||||
| </interface> \ | ||||
| </node>'; | ||||
|  | ||||
|   | ||||
| @@ -203,6 +203,10 @@ function _initializeUI() { | ||||
|     ExtensionDownloader.init(); | ||||
|     ExtensionSystem.init(); | ||||
|  | ||||
|     layoutManager.connect('startup-prepared', function() { | ||||
|         Meta.activate_session(); | ||||
|     }); | ||||
|  | ||||
|     if (sessionMode.isGreeter && screenShield) { | ||||
|         layoutManager.connect('startup-prepared', function() { | ||||
|             screenShield.showDialog(); | ||||
|   | ||||
| @@ -53,8 +53,8 @@ const UnlockDialog = new Lang.Class({ | ||||
|  | ||||
|         this._authPrompt = new AuthPrompt.AuthPrompt(new Gdm.Client(), AuthPrompt.AuthPromptMode.UNLOCK_ONLY); | ||||
|         this._authPrompt.connect('failed', Lang.bind(this, this._fail)); | ||||
|         this._authPrompt.connect('cancelled', Lang.bind(this, this._fail)); | ||||
|         this._authPrompt.connect('reset', Lang.bind(this, this._onReset)); | ||||
|         this._authPrompt.connect('needs-username', Lang.bind(this, this._onNeedsUserName)); | ||||
|         this._authPrompt.setPasswordChar('\u25cf'); | ||||
|         this._authPrompt.nextButton.label = _("Unlock"); | ||||
|  | ||||
| @@ -101,6 +101,10 @@ const UnlockDialog = new Lang.Class({ | ||||
|     }, | ||||
|  | ||||
|     _onReset: function(authPrompt, beginRequest) { | ||||
|         this._authPrompt.begin(); | ||||
|     }, | ||||
|  | ||||
|     _onNeedsUserName: function() { | ||||
|         let userName; | ||||
|         if (beginRequest == AuthPrompt.BeginRequestType.PROVIDE_USERNAME) { | ||||
|             this._authPrompt.setUser(this._user); | ||||
| @@ -109,7 +113,7 @@ const UnlockDialog = new Lang.Class({ | ||||
|             userName = null; | ||||
|         } | ||||
|  | ||||
|         this._authPrompt.begin({ userName: userName }); | ||||
|         this._authPrompt.gotUserName(userName); | ||||
|     }, | ||||
|  | ||||
|     _escape: function() { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user