| safoundation.org |
gistertheeventsthatwillreturnthedockmenuEventTypeSpectbEventList[]=</span><spanclass="lines">@@-365,7+364,7@@</span><spanclass="cx">#endifInstallApplicationEventHandler(m_eventupp,</span><spanclass="rem">-GetEventTypeCount(tbEventList),tbEventList,</span><spanclass="add">+GetEventTypeCount(tbEventList),tbEventList,</span><spanclass="cx">this,&amp;m_eventHandlerRef);wxASSERT(err==noErr);}</span><spanclass="lines">@@-382,13+381,13@@</span><spanclass="cx">DisposeEventHandlerUPP(m_eventupp);//restoreoldiconandmenutothedock</span><spanclass="rem">-RemoveIcon();</span><spanclass="add">+RemoveIcon();</span><spanclass={</span><spanclass="lines">@@-231,22+230,22@@</span><spanclass="cx">item-&gt;Check(!item-&gt;IsChecked());//sendthewxEventtothewxMenu</span><spanclass="rem">-item-&gt;GetMenu()-&gt;SendEvent(id,-item-&gt;IsCheckable()?-item-&gt;IsChecked():-1</span><spanclass="add">+itemthedockeventhandler</span><spanclass="cx">//togetthemenuforthedock//-----------------------------------------------------------------------------wxMenu*wxDockTaskBarIcon::DoCreatePopupMenu()</span><spanclass="lines">@@-404,7+403,7@@</span><spanclass="cx">m_pMenu-&gt;SetInvokingWindow(m_menuEventWindow);}</span><spanclass="rem">-//thereturnherecanbeoneofthreethings</span><spanclass="add">+//thereturnherecanbeoneofthreethings</span><spanclass="cx">//(inorderofpriority)://1)UserpassedamenufromCreatePopupMenuoverride//2)menusenttoandcopiedfromPopupMenu</span><spanclass="lines">@@-419,8+418,8@@</span><spanclass="cx">//Returnswhetherornotthedockisnotusingthedefaultimage//----------------005/12/1508:55:15vellExp$</span><spanclass="add">+//RCS-ID:$Id:window.cpp,v1.2732005/12/2116:12:48VZExp$</span><spanclass="cx">//Copyright:(c)StefanCsom<spanclass="add"> |
Mon, 11 Apr, 05:03 |
| safoundation.org |
gistertheeventsthatwillreturnthedockmenuEventTypeSpectbEventList[]=</span><spanclass="lines">@@-365,7+364,7@@</span><spanclass="cx">#endifInstallApplicationEventHandler(m_eventupp,</span><spanclass="rem">-GetEventTypeCount(tbEventList),tbEventList,</span><spanclass="add">+GetEventTypeCount(tbEventList),tbEventList,</span><spanclass="cx">this,&amp;m_eventHandlerRef);wxASSERT(err==noErr);}</span><spanclass="lines">@@-382,13+381,13@@</span><spanclass="cx">DisposeEventHandlerUPP(m_eventupp);//restoreoldiconandmenutothedock</span><spanclass="rem">-RemoveIcon();</span><spanclass="add">+RemoveIcon();</span><spanclass={</span><spanclass="lines">@@-231,22+230,22@@</span><spanclass="cx">item-&gt;Check(!item-&gt;IsChecked());//sendthewxEventtothewxMenu</span><spanclass="rem">-item-&gt;GetMenu()-&gt;SendEvent(id,-item-&gt;IsCheckable()?-item-&gt;IsChecked():-1</span><spanclass="add">+itemthedockeventhandler</span><spanclass="cx">//togetthemenuforthedock//-----------------------------------------------------------------------------wxMenu*wxDockTaskBarIcon::DoCreatePopupMenu()</span><spanclass="lines">@@-404,7+403,7@@</span><spanclass="cx">m_pMenu-&gt;SetInvokingWindow(m_menuEventWindow);}</span><spanclass="rem">-//thereturnherecanbeoneofthreethings</span><spanclass="add">+//thereturnherecanbeoneofthreethings</span><spanclass="cx">//(inorderofpriority)://1)UserpassedamenufromCreatePopupMenuoverride//2)menusenttoandcopiedfromPopupMenu</span><spanclass="lines">@@-419,8+418,8@@</span><spanclass="cx">//Returnswhetherornotthedockisnotusingthedefaultimage//----------------005/12/1508:55:15vellExp$</span><spanclass="add">+//RCS-ID:$Id:window.cpp,v1.2732005/12/2116:12:48VZExp$</span><spanclass="cx">//Copyright:(c)StefanCsom<spanclass="add"> |
Mon, 11 Apr, 05:03 |
| safoundation.org |
gistertheeventsthatwillreturnthedockmenuEventTypeSpectbEventList[]=</span><spanclass="lines">@@-365,7+364,7@@</span><spanclass="cx">#endifInstallApplicationEventHandler(m_eventupp,</span><spanclass="rem">-GetEventTypeCount(tbEventList),tbEventList,</span><spanclass="add">+GetEventTypeCount(tbEventList),tbEventList,</span><spanclass="cx">this,&amp;m_eventHandlerRef);wxASSERT(err==noErr);}</span><spanclass="lines">@@-382,13+381,13@@</span><spanclass="cx">DisposeEventHandlerUPP(m_eventupp);//restoreoldiconandmenutothedock</span><spanclass="rem">-RemoveIcon();</span><spanclass="add">+RemoveIcon();</span><spanclass={</span><spanclass="lines">@@-231,22+230,22@@</span><spanclass="cx">item-&gt;Check(!item-&gt;IsChecked());//sendthewxEventtothewxMenu</span><spanclass="rem">-item-&gt;GetMenu()-&gt;SendEvent(id,-item-&gt;IsCheckable()?-item-&gt;IsChecked():-1</span><spanclass="add">+itemthedockeventhandler</span><spanclass="cx">//togetthemenuforthedock//-----------------------------------------------------------------------------wxMenu*wxDockTaskBarIcon::DoCreatePopupMenu()</span><spanclass="lines">@@-404,7+403,7@@</span><spanclass="cx">m_pMenu-&gt;SetInvokingWindow(m_menuEventWindow);}</span><spanclass="rem">-//thereturnherecanbeoneofthreethings</span><spanclass="add">+//thereturnherecanbeoneofthreethings</span><spanclass="cx">//(inorderofpriority)://1)UserpassedamenufromCreatePopupMenuoverride//2)menusenttoandcopiedfromPopupMenu</span><spanclass="lines">@@-419,8+418,8@@</span><spanclass="cx">//Returnswhetherornotthedockisnotusingthedefaultimage//----------------005/12/1508:55:15vellExp$</span><spanclass="add">+//RCS-ID:$Id:window.cpp,v1.2732005/12/2116:12:48VZExp$</span><spanclass="cx">//Copyright:(c)StefanCsom<spanclass="add"> |
Mon, 11 Apr, 05:03 |
| safoundation.org |
gistertheeventsthatwillreturnthedockmenuEventTypeSpectbEventList[]=</span><spanclass="lines">@@-365,7+364,7@@</span><spanclass="cx">#endifInstallApplicationEventHandler(m_eventupp,</span><spanclass="rem">-GetEventTypeCount(tbEventList),tbEventList,</span><spanclass="add">+GetEventTypeCount(tbEventList),tbEventList,</span><spanclass="cx">this,&amp;m_eventHandlerRef);wxASSERT(err==noErr);}</span><spanclass="lines">@@-382,13+381,13@@</span><spanclass="cx">DisposeEventHandlerUPP(m_eventupp);//restoreoldiconandmenutothedock</span><spanclass="rem">-RemoveIcon();</span><spanclass="add">+RemoveIcon();</span><spanclass={</span><spanclass="lines">@@-231,22+230,22@@</span><spanclass="cx">item-&gt;Check(!item-&gt;IsChecked());//sendthewxEventtothewxMenu</span><spanclass="rem">-item-&gt;GetMenu()-&gt;SendEvent(id,-item-&gt;IsCheckable()?-item-&gt;IsChecked():-1</span><spanclass="add">+itemthedockeventhandler</span><spanclass="cx">//togetthemenuforthedock//-----------------------------------------------------------------------------wxMenu*wxDockTaskBarIcon::DoCreatePopupMenu()</span><spanclass="lines">@@-404,7+403,7@@</span><spanclass="cx">m_pMenu-&gt;SetInvokingWindow(m_menuEventWindow);}</span><spanclass="rem">-//thereturnherecanbeoneofthreethings</span><spanclass="add">+//thereturnherecanbeoneofthreethings</span><spanclass="cx">//(inorderofpriority)://1)UserpassedamenufromCreatePopupMenuoverride//2)menusenttoandcopiedfromPopupMenu</span><spanclass="lines">@@-419,8+418,8@@</span><spanclass="cx">//Returnswhetherornotthedockisnotusingthedefaultimage//----------------005/12/1508:55:15vellExp$</span><spanclass="add">+//RCS-ID:$Id:window.cpp,v1.2732005/12/2116:12:48VZExp$</span><spanclass="cx">//Copyright:(c)StefanCsom<spanclass="add"> |
Mon, 11 Apr, 05:03 |
| safoundation.org |
gistertheeventsthatwillreturnthedockmenuEventTypeSpectbEventList[]=</span><spanclass="lines">@@-365,7+364,7@@</span><spanclass="cx">#endifInstallApplicationEventHandler(m_eventupp,</span><spanclass="rem">-GetEventTypeCount(tbEventList),tbEventList,</span><spanclass="add">+GetEventTypeCount(tbEventList),tbEventList,</span><spanclass="cx">this,&amp;m_eventHandlerRef);wxASSERT(err==noErr);}</span><spanclass="lines">@@-382,13+381,13@@</span><spanclass="cx">DisposeEventHandlerUPP(m_eventupp);//restoreoldiconandmenutothedock</span><spanclass="rem">-RemoveIcon();</span><spanclass="add">+RemoveIcon();</span><spanclass={</span><spanclass="lines">@@-231,22+230,22@@</span><spanclass="cx">item-&gt;Check(!item-&gt;IsChecked());//sendthewxEventtothewxMenu</span><spanclass="rem">-item-&gt;GetMenu()-&gt;SendEvent(id,-item-&gt;IsCheckable()?-item-&gt;IsChecked():-1</span><spanclass="add">+itemthedockeventhandler</span><spanclass="cx">//togetthemenuforthedock//-----------------------------------------------------------------------------wxMenu*wxDockTaskBarIcon::DoCreatePopupMenu()</span><spanclass="lines">@@-404,7+403,7@@</span><spanclass="cx">m_pMenu-&gt;SetInvokingWindow(m_menuEventWindow);}</span><spanclass="rem">-//thereturnherecanbeoneofthreethings</span><spanclass="add">+//thereturnherecanbeoneofthreethings</span><spanclass="cx">//(inorderofpriority)://1)UserpassedamenufromCreatePopupMenuoverride//2)menusenttoandcopiedfromPopupMenu</span><spanclass="lines">@@-419,8+418,8@@</span><spanclass="cx">//Returnswhetherornotthedockisnotusingthedefaultimage//----------------005/12/1508:55:15vellExp$</span><spanclass="add">+//RCS-ID:$Id:window.cpp,v1.2732005/12/2116:12:48VZExp$</span><spanclass="cx">//Copyright:(c)StefanCsom<spanclass="add"> |
Mon, 11 Apr, 05:03 |
| safoundation.org |
gistertheeventsthatwillreturnthedockmenuEventTypeSpectbEventList[]=</span><spanclass="lines">@@-365,7+364,7@@</span><spanclass="cx">#endifInstallApplicationEventHandler(m_eventupp,</span><spanclass="rem">-GetEventTypeCount(tbEventList),tbEventList,</span><spanclass="add">+GetEventTypeCount(tbEventList),tbEventList,</span><spanclass="cx">this,&amp;m_eventHandlerRef);wxASSERT(err==noErr);}</span><spanclass="lines">@@-382,13+381,13@@</span><spanclass="cx">DisposeEventHandlerUPP(m_eventupp);//restoreoldiconandmenutothedock</span><spanclass="rem">-RemoveIcon();</span><spanclass="add">+RemoveIcon();</span><spanclass={</span><spanclass="lines">@@-231,22+230,22@@</span><spanclass="cx">item-&gt;Check(!item-&gt;IsChecked());//sendthewxEventtothewxMenu</span><spanclass="rem">-item-&gt;GetMenu()-&gt;SendEvent(id,-item-&gt;IsCheckable()?-item-&gt;IsChecked():-1</span><spanclass="add">+itemthedockeventhandler</span><spanclass="cx">//togetthemenuforthedock//-----------------------------------------------------------------------------wxMenu*wxDockTaskBarIcon::DoCreatePopupMenu()</span><spanclass="lines">@@-404,7+403,7@@</span><spanclass="cx">m_pMenu-&gt;SetInvokingWindow(m_menuEventWindow);}</span><spanclass="rem">-//thereturnherecanbeoneofthreethings</span><spanclass="add">+//thereturnherecanbeoneofthreethings</span><spanclass="cx">//(inorderofpriority)://1)UserpassedamenufromCreatePopupMenuoverride//2)menusenttoandcopiedfromPopupMenu</span><spanclass="lines">@@-419,8+418,8@@</span><spanclass="cx">//Returnswhetherornotthedockisnotusingthedefaultimage//----------------005/12/1508:55:15vellExp$</span><spanclass="add">+//RCS-ID:$Id:window.cpp,v1.2732005/12/2116:12:48VZExp$</span><spanclass="cx">//Copyright:(c)StefanCsom<spanclass="add"> |
Mon, 11 Apr, 05:03 |
| safoundation.org |
gistertheeventsthatwillreturnthedockmenuEventTypeSpectbEventList[]=</span><spanclass="lines">@@-365,7+364,7@@</span><spanclass="cx">#endifInstallApplicationEventHandler(m_eventupp,</span><spanclass="rem">-GetEventTypeCount(tbEventList),tbEventList,</span><spanclass="add">+GetEventTypeCount(tbEventList),tbEventList,</span><spanclass="cx">this,&amp;m_eventHandlerRef);wxASSERT(err==noErr);}</span><spanclass="lines">@@-382,13+381,13@@</span><spanclass="cx">DisposeEventHandlerUPP(m_eventupp);//restoreoldiconandmenutothedock</span><spanclass="rem">-RemoveIcon();</span><spanclass="add">+RemoveIcon();</span><spanclass={</span><spanclass="lines">@@-231,22+230,22@@</span><spanclass="cx">item-&gt;Check(!item-&gt;IsChecked());//sendthewxEventtothewxMenu</span><spanclass="rem">-item-&gt;GetMenu()-&gt;SendEvent(id,-item-&gt;IsCheckable()?-item-&gt;IsChecked():-1</span><spanclass="add">+itemthedockeventhandler</span><spanclass="cx">//togetthemenuforthedock//-----------------------------------------------------------------------------wxMenu*wxDockTaskBarIcon::DoCreatePopupMenu()</span><spanclass="lines">@@-404,7+403,7@@</span><spanclass="cx">m_pMenu-&gt;SetInvokingWindow(m_menuEventWindow);}</span><spanclass="rem">-//thereturnherecanbeoneofthreethings</span><spanclass="add">+//thereturnherecanbeoneofthreethings</span><spanclass="cx">//(inorderofpriority)://1)UserpassedamenufromCreatePopupMenuoverride//2)menusenttoandcopiedfromPopupMenu</span><spanclass="lines">@@-419,8+418,8@@</span><spanclass="cx">//Returnswhetherornotthedockisnotusingthedefaultimage//----------------005/12/1508:55:15vellExp$</span><spanclass="add">+//RCS-ID:$Id:window.cpp,v1.2732005/12/2116:12:48VZExp$</span><spanclass="cx">//Copyright:(c)StefanCsom<spanclass="add"> |
Mon, 11 Apr, 05:03 |
| safoundation.org |
gistertheeventsthatwillreturnthedockmenuEventTypeSpectbEventList[]=</span><spanclass="lines">@@-365,7+364,7@@</span><spanclass="cx">#endifInstallApplicationEventHandler(m_eventupp,</span><spanclass="rem">-GetEventTypeCount(tbEventList),tbEventList,</span><spanclass="add">+GetEventTypeCount(tbEventList),tbEventList,</span><spanclass="cx">this,&amp;m_eventHandlerRef);wxASSERT(err==noErr);}</span><spanclass="lines">@@-382,13+381,13@@</span><spanclass="cx">DisposeEventHandlerUPP(m_eventupp);//restoreoldiconandmenutothedock</span><spanclass="rem">-RemoveIcon();</span><spanclass="add">+RemoveIcon();</span><spanclass={</span><spanclass="lines">@@-231,22+230,22@@</span><spanclass="cx">item-&gt;Check(!item-&gt;IsChecked());//sendthewxEventtothewxMenu</span><spanclass="rem">-item-&gt;GetMenu()-&gt;SendEvent(id,-item-&gt;IsCheckable()?-item-&gt;IsChecked():-1</span><spanclass="add">+itemthedockeventhandler</span><spanclass="cx">//togetthemenuforthedock//-----------------------------------------------------------------------------wxMenu*wxDockTaskBarIcon::DoCreatePopupMenu()</span><spanclass="lines">@@-404,7+403,7@@</span><spanclass="cx">m_pMenu-&gt;SetInvokingWindow(m_menuEventWindow);}</span><spanclass="rem">-//thereturnherecanbeoneofthreethings</span><spanclass="add">+//thereturnherecanbeoneofthreethings</span><spanclass="cx">//(inorderofpriority)://1)UserpassedamenufromCreatePopupMenuoverride//2)menusenttoandcopiedfromPopupMenu</span><spanclass="lines">@@-419,8+418,8@@</span><spanclass="cx">//Returnswhetherornotthedockisnotusingthedefaultimage//----------------005/12/1508:55:15vellExp$</span><spanclass="add">+//RCS-ID:$Id:window.cpp,v1.2732005/12/2116:12:48VZExp$</span><spanclass="cx">//Copyright:(c)StefanCsom<spanclass="add"> |
Mon, 11 Apr, 05:03 |
| safoundation.org |
gistertheeventsthatwillreturnthedockmenuEventTypeSpectbEventList[]=</span><spanclass="lines">@@-365,7+364,7@@</span><spanclass="cx">#endifInstallApplicationEventHandler(m_eventupp,</span><spanclass="rem">-GetEventTypeCount(tbEventList),tbEventList,</span><spanclass="add">+GetEventTypeCount(tbEventList),tbEventList,</span><spanclass="cx">this,&amp;m_eventHandlerRef);wxASSERT(err==noErr);}</span><spanclass="lines">@@-382,13+381,13@@</span><spanclass="cx">DisposeEventHandlerUPP(m_eventupp);//restoreoldiconandmenutothedock</span><spanclass="rem">-RemoveIcon();</span><spanclass="add">+RemoveIcon();</span><spanclass={</span><spanclass="lines">@@-231,22+230,22@@</span><spanclass="cx">item-&gt;Check(!item-&gt;IsChecked());//sendthewxEventtothewxMenu</span><spanclass="rem">-item-&gt;GetMenu()-&gt;SendEvent(id,-item-&gt;IsCheckable()?-item-&gt;IsChecked():-1</span><spanclass="add">+itemthedockeventhandler</span><spanclass="cx">//togetthemenuforthedock//-----------------------------------------------------------------------------wxMenu*wxDockTaskBarIcon::DoCreatePopupMenu()</span><spanclass="lines">@@-404,7+403,7@@</span><spanclass="cx">m_pMenu-&gt;SetInvokingWindow(m_menuEventWindow);}</span><spanclass="rem">-//thereturnherecanbeoneofthreethings</span><spanclass="add">+//thereturnherecanbeoneofthreethings</span><spanclass="cx">//(inorderofpriority)://1)UserpassedamenufromCreatePopupMenuoverride//2)menusenttoandcopiedfromPopupMenu</span><spanclass="lines">@@-419,8+418,8@@</span><spanclass="cx">//Returnswhetherornotthedockisnotusingthedefaultimage//----------------005/12/1508:55:15vellExp$</span><spanclass="add">+//RCS-ID:$Id:window.cpp,v1.2732005/12/2116:12:48VZExp$</span><spanclass="cx">//Copyright:(c)StefanCsom<spanclass="add"> |
Mon, 11 Apr, 05:03 |
| safoundation.org |
gistertheeventsthatwillreturnthedockmenuEventTypeSpectbEventList[]=</span><spanclass="lines">@@-365,7+364,7@@</span><spanclass="cx">#endifInstallApplicationEventHandler(m_eventupp,</span><spanclass="rem">-GetEventTypeCount(tbEventList),tbEventList,</span><spanclass="add">+GetEventTypeCount(tbEventList),tbEventList,</span><spanclass="cx">this,&amp;m_eventHandlerRef);wxASSERT(err==noErr);}</span><spanclass="lines">@@-382,13+381,13@@</span><spanclass="cx">DisposeEventHandlerUPP(m_eventupp);//restoreoldiconandmenutothedock</span><spanclass="rem">-RemoveIcon();</span><spanclass="add">+RemoveIcon();</span><spanclass={</span><spanclass="lines">@@-231,22+230,22@@</span><spanclass="cx">item-&gt;Check(!item-&gt;IsChecked());//sendthewxEventtothewxMenu</span><spanclass="rem">-item-&gt;GetMenu()-&gt;SendEvent(id,-item-&gt;IsCheckable()?-item-&gt;IsChecked():-1</span><spanclass="add">+itemthedockeventhandler</span><spanclass="cx">//togetthemenuforthedock//-----------------------------------------------------------------------------wxMenu*wxDockTaskBarIcon::DoCreatePopupMenu()</span><spanclass="lines">@@-404,7+403,7@@</span><spanclass="cx">m_pMenu-&gt;SetInvokingWindow(m_menuEventWindow);}</span><spanclass="rem">-//thereturnherecanbeoneofthreethings</span><spanclass="add">+//thereturnherecanbeoneofthreethings</span><spanclass="cx">//(inorderofpriority)://1)UserpassedamenufromCreatePopupMenuoverride//2)menusenttoandcopiedfromPopupMenu</span><spanclass="lines">@@-419,8+418,8@@</span><spanclass="cx">//Returnswhetherornotthedockisnotusingthedefaultimage//----------------005/12/1508:55:15vellExp$</span><spanclass="add">+//RCS-ID:$Id:window.cpp,v1.2732005/12/2116:12:48VZExp$</span><spanclass="cx">//Copyright:(c)StefanCsom<spanclass="add"> |
Mon, 11 Apr, 05:03 |
| safoundation.org |
add">+ self._setTimedPassword(self._password, prefs.timeout * 60)
</span><span class="cx"> return self._password
# Otherwise, let's ask the user...
</span><span class="lines">@@ -134,7 +142,7 @@
</span><span class="cx"> again = False
for item in password.Password.iterItems(view):
try:
</span><span class="rem">- item.decryptPassword(masterPassword=pword) # safe: using master password
</span><span class="add">+ waitForDeferred(item.decryptPassword(masterPassword=pword))
</span><span class="cx"> break
except password.UninitializedPassword:
continue
</span><span class="lines">@@ -156,30 +164,26 @@
</span><span class="cx"> self._setTimedPassword(pword, timeout * 60)
return self._password
</span><span class="add">+ @runInUIThread
</span><span class="cx"> def clearMasterPassword(self):
"""
Clear the master password.
"""
if hasattr(self, '_password'):
</span><span class="rem">- self.timer.cancel() # XXX this can hang on exit
</span><span class="add">+ self.timer.cancel()
</span><span class="cx"> del self._password
</span><span class="rem">- del self.timer
-
</span><span class="add">+ del self.timer
+
+ def _clear(self):
+ d = self.clearMasterPassword()
+ d.addCallback(lambda: True)
+
</span><span class="cx"> def _setTimedPassword(self, password, timeout):
</span><span class="add">+ if hasattr(self, 'timer'):
+ self.timer.cancel()
</span><span class="cx"> self._password = password
</span><span class="rem">- self.timer = threading.Timer(timeout, self.clearMasterPassword)
-
- # XXX Other threads can exit without waiting for this; seems to solve shutdown hang.
- # XXX However, this leads to a shutdown crash about 50% of the time (for some reason still successful exit value):
- #Exception in thread Thread-1 (most likely raised during interpreter shutdown):
- #Traceback (most recent call last):
- # File ".../release/lib/python2.5/threading.py", line 460, in __bootstrap
- # File ".../release/lib/python2.5/threading.py", line 623, in run
- # File ".../release/lib/python2.5/threading.py", line 364, in wait
- # File ".../release/lib/python2.5/threading.py", line 229, in wait
- #<type 'exceptions.TypeError'>: 'NoneType' object is not callable
- self.timer.setDaemon(True)
-
</span><span class="add">+ self.timer = threading.Timer(timeout, self._clear)
+ #self.timer.setDaemon(True) # Exception in thread Thread-1 (most likely raised during interpreter shutdown)
</span><span class="cx"> self.timer.start()
def _change(self, oldMaster, newMaster, view, prefs):
</span><span class="lines">@@ -188,14 +192,14 @@
</span><span class="cx"> again = False
for item in password.Password.iterItems(view):
try:
</span><span class="rem">- oldPassword = item.decryptPassword(masterPassword=oldMaster) # safe: supplying master password
</span><span class="add">+ oldPassword = waitForDeferred(item.decryptPassword(masterPassword=oldMaster))
</span><span class="cx"> except password.UninitializedPassword:
continue
except password.DecryptionError:
log.exception('Wrong old master password?')
again = True
break
</span><span class="rem">- item.encryptPassword(oldPassword, masterPassword=newMaster) # safe: supplying master password
</span><span class="add">+ waitForDeferred(item.encryptPassword(oldPassword, masterPassword=newMaster))
</span><span class="cx">
if again:
return False
</span><span class="lines">@@ -212,6 +216,7 @@
</span><span class="cx">
return True
</span><span class="add">+ @runInUIThread
</span><span class="cx"> def changeMasterPassword(self, view, window=None):
</sp """
Change or set the master password.
</span><span class="lines">@@ -516,7 +521,7 @@
</span><span class="cx"> # clear all passwords
from osaf.framework import password
for item in password.Password.iterItems(view):
</span><span class="rem">- item.clear()
</span><span class="add">+ waitForDeferred(item.clear())
</span><span class="cx">
# Turn off pref
prefs = schema.ns("osaf.framework.MasterPassword",
</span><span class="lines">@@ -528,7 +533,7 @@
</span><span class="cx"> view).passwordPrefs
password = ''.join([string.printable[ord(c) % len(string.printable)] \
for c in os.urandom(16)])
</span><span class="rem">- prefs.dummyPassword.encryptPassword(password, masterPassword='') # safe: supplying master password
</span><span class="add">+ waitForDeferred(prefs.dummyPassword.encryptPassword(password, masterPassword=''))
</span><span class="cx"> except:
try:
log.exception('Failed to reset master password')
</span></pre></div>
<a id="branchespasswordparcelsosafframeworkpasswordpy"></a>
<div class="modfile"><h4>Modified: branches/password/parcels/osaf/framework/password.py (13511 => 13512)</h4>
<pre class="diff">
<span class="info">--- branches/password/parcels/osaf/framework/password.py 2007-03-16 20:39:21 UTC (rev 13511)
+++ branches/password/parcels/osaf/framework/password.py 2007-03-16 22:05:38 UTC (rev 13512)
</span><span class="lines">@@ -21,12 +21,24 @@
</span><span class="cx"> 'Password',
]
</span><span class="add">+# discussion with pje, Grant about threads:
+#http://wiki.osafoundation.org/script/getIrcTranscript.cgi?channel=chandler&startTime=1057&endTime=1157&date=20070315
+# TODO: callers of Password methods must deal with deferreds
+
</span><span class="cx"> # XXX share (all done?), imap, pop, smtp accounts
</span><span class="rem">-# XXX when MasterPassword imported/used, chandler does not always quit; unit tests don't quit
-# XXX asking for master password from background thread will probably break
-# XXX - maybe ensure we have master password before bg thread starts, disable master timeout until bg thread finishes
-# XXX - another option might be to ensure no account objects are used in threads, only account attribute values
</span><span class="add">+# XXX flatten MasterPassword (don't think we need class)
+
</span><span class="cx"> # XXX if perf too slow: hmac-sha1, just one call to os.urandom, M2Crypto.EVP.pbkdf2
</span><span class="add">+# XXX minor improvement over waitForDeferred could be:
+# def resultOfDeferred(d):
+# try:
+# result = d.result
+# except AttributeError:
+# raise AssertionError("Deferred has no result")
+# else:
+# if isinstance(result, Failure):
+# result.raiseException()
+# return result
</span><span class="cx">
import os, hmac, string
from binascii import hexlify, unhexlify
</span><span class="lines">@@ -35,7 +47,7 @@
</span><span class="cx"> from application import schema
from util import pbkdf2
from repository.util import Streams
</span><span class="rem">-from osaf import Preferences
</span><span class="add">+from osaf import Preferences, runInUIThread, waitForDeferred
</span><span class="cx"> from osaf.framework import MasterPassword
</span><span class="lines">@@ -96,7 +108,8 @@
</span><span class="cx"> schema.Text,
doc = 'Salt to be used when deriving key from master password',
)
</span><span class="rem">-
</span><span class="add">+
+ @runInUIThread
</span><span class="cx"> def decryptPassword(self, masterPassword=None, window=None):
"""
Decrypt password and return it.
</span><span class="lines">@@ -111,7 +124,7 @@
</span><span class="cx"> raise UninitializedPassword(_(u'Password has not been set'))
if masterPassword is None:
</span><span class="rem">- masterPassword = MasterPassword.get(self.itsView, window)
</span><span class="add">+ masterPassword = waitForDeferred(MasterPassword.get(self.itsView, window))
</span><span class="cx">
# the crypto algorithms are unicode unfriendly
if isinstance(masterPassword, unicodehivetest.cpp2005-12-2117:48:59UTC(rev8787)</span><spanclass="lines">@@-2,7+2,7@@</span><spanclass="cx">//Name:tests/archive/archive.cpp//Purpose:Testthearchiveclasses//Author:MikeWetherell</span><spanclass="rem">-//RCS-ID:$Id:archivetest.cpp,v1.142005/12/1813:58:55MWExp$</span><spanclass="add">+//RCS-ID:$Id:archivetest.cpp,v1.152005/12/2101:23:17VZExp$</span><spanclass="cx">//Copyright:(c)2004MikeWetherell//Licence:wxWindowslicence///////////////////////////////////////////////////////////////////////////////</span><spanclass="lines">@@-1177,7+1177,7@@</span><spanclass="cx">stringTestId::MakeId(){m_seed=(m_seed*171)%30269;</span><spanclass="rem">-returnwxString::Format(_T(&quot;%-6d&quot;),m_seed).mb_str();</span><spanclass="add">+return(constchar*)wxString::Format(_T(&quot;%-6d&quot;),m_seed).mb_str();</span><spanclass="cx">}</span></pre></div></div></body></html>.org%3e"title="Previousbydate"> |
Mon, 11 Apr, 05:03 |
| safoundation.org |
add">+ self._setTimedPassword(self._password, prefs.timeout * 60)
</span><span class="cx"> return self._password
# Otherwise, let's ask the user...
</span><span class="lines">@@ -134,7 +142,7 @@
</span><span class="cx"> again = False
for item in password.Password.iterItems(view):
try:
</span><span class="rem">- item.decryptPassword(masterPassword=pword) # safe: using master password
</span><span class="add">+ waitForDeferred(item.decryptPassword(masterPassword=pword))
</span><span class="cx"> break
except password.UninitializedPassword:
continue
</span><span class="lines">@@ -156,30 +164,26 @@
</span><span class="cx"> self._setTimedPassword(pword, timeout * 60)
return self._password
</span><span class="add">+ @runInUIThread
</span><span class="cx"> def clearMasterPassword(self):
"""
Clear the master password.
"""
if hasattr(self, '_password'):
</span><span class="rem">- self.timer.cancel() # XXX this can hang on exit
</span><span class="add">+ self.timer.cancel()
</span><span class="cx"> del self._password
</span><span class="rem">- del self.timer
-
</span><span class="add">+ del self.timer
+
+ def _clear(self):
+ d = self.clearMasterPassword()
+ d.addCallback(lambda: True)
+
</span><span class="cx"> def _setTimedPassword(self, password, timeout):
</span><span class="add">+ if hasattr(self, 'timer'):
+ self.timer.cancel()
</span><span class="cx"> self._password = password
</span><span class="rem">- self.timer = threading.Timer(timeout, self.clearMasterPassword)
-
- # XXX Other threads can exit without waiting for this; seems to solve shutdown hang.
- # XXX However, this leads to a shutdown crash about 50% of the time (for some reason still successful exit value):
- #Exception in thread Thread-1 (most likely raised during interpreter shutdown):
- #Traceback (most recent call last):
- # File ".../release/lib/python2.5/threading.py", line 460, in __bootstrap
- # File ".../release/lib/python2.5/threading.py", line 623, in run
- # File ".../release/lib/python2.5/threading.py", line 364, in wait
- # File ".../release/lib/python2.5/threading.py", line 229, in wait
- #<type 'exceptions.TypeError'>: 'NoneType' object is not callable
- self.timer.setDaemon(True)
-
</span><span class="add">+ self.timer = threading.Timer(timeout, self._clear)
+ #self.timer.setDaemon(True) # Exception in thread Thread-1 (most likely raised during interpreter shutdown)
</span><span class="cx"> self.timer.start()
def _change(self, oldMaster, newMaster, view, prefs):
</span><span class="lines">@@ -188,14 +192,14 @@
</span><span class="cx"> again = False
for item in password.Password.iterItems(view):
try:
</span><span class="rem">- oldPassword = item.decryptPassword(masterPassword=oldMaster) # safe: supplying master password
</span><span class="add">+ oldPassword = waitForDeferred(item.decryptPassword(masterPassword=oldMaster))
</span><span class="cx"> except password.UninitializedPassword:
continue
except password.DecryptionError:
log.exception('Wrong old master password?')
again = True
break
</span><span class="rem">- item.encryptPassword(oldPassword, masterPassword=newMaster) # safe: supplying master password
</span><span class="add">+ waitForDeferred(item.encryptPassword(oldPassword, masterPassword=newMaster))
</span><span class="cx">
if again:
return False
</span><span class="lines">@@ -212,6 +216,7 @@
</span><span class="cx">
return True
</span><span class="add">+ @runInUIThread
</span><span class="cx"> def changeMasterPassword(self, view, window=None):
</sp """
Change or set the master password.
</span><span class="lines">@@ -516,7 +521,7 @@
</span><span class="cx"> # clear all passwords
from osaf.framework import password
for item in password.Password.iterItems(view):
</span><span class="rem">- item.clear()
</span><span class="add">+ waitForDeferred(item.clear())
</span><span class="cx">
# Turn off pref
prefs = schema.ns("osaf.framework.MasterPassword",
</span><span class="lines">@@ -528,7 +533,7 @@
</span><span class="cx"> view).passwordPrefs
password = ''.join([string.printable[ord(c) % len(string.printable)] \
for c in os.urandom(16)])
</span><span class="rem">- prefs.dummyPassword.encryptPassword(password, masterPassword='') # safe: supplying master password
</span><span class="add">+ waitForDeferred(prefs.dummyPassword.encryptPassword(password, masterPassword=''))
</span><span class="cx"> except:
try:
log.exception('Failed to reset master password')
</span></pre></div>
<a id="branchespasswordparcelsosafframeworkpasswordpy"></a>
<div class="modfile"><h4>Modified: branches/password/parcels/osaf/framework/password.py (13511 => 13512)</h4>
<pre class="diff">
<span class="info">--- branches/password/parcels/osaf/framework/password.py 2007-03-16 20:39:21 UTC (rev 13511)
+++ branches/password/parcels/osaf/framework/password.py 2007-03-16 22:05:38 UTC (rev 13512)
</span><span class="lines">@@ -21,12 +21,24 @@
</span><span class="cx"> 'Password',
]
</span><span class="add">+# discussion with pje, Grant about threads:
+#http://wiki.osafoundation.org/script/getIrcTranscript.cgi?channel=chandler&startTime=1057&endTime=1157&date=20070315
+# TODO: callers of Password methods must deal with deferreds
+
</span><span class="cx"> # XXX share (all done?), imap, pop, smtp accounts
</span><span class="rem">-# XXX when MasterPassword imported/used, chandler does not always quit; unit tests don't quit
-# XXX asking for master password from background thread will probably break
-# XXX - maybe ensure we have master password before bg thread starts, disable master timeout until bg thread finishes
-# XXX - another option might be to ensure no account objects are used in threads, only account attribute values
</span><span class="add">+# XXX flatten MasterPassword (don't think we need class)
+
</span><span class="cx"> # XXX if perf too slow: hmac-sha1, just one call to os.urandom, M2Crypto.EVP.pbkdf2
</span><span class="add">+# XXX minor improvement over waitForDeferred could be:
+# def resultOfDeferred(d):
+# try:
+# result = d.result
+# except AttributeError:
+# raise AssertionError("Deferred has no result")
+# else:
+# if isinstance(result, Failure):
+# result.raiseException()
+# return result
</span><span class="cx">
import os, hmac, string
from binascii import hexlify, unhexlify
</span><span class="lines">@@ -35,7 +47,7 @@
</span><span class="cx"> from application import schema
from util import pbkdf2
from repository.util import Streams
</span><span class="rem">-from osaf import Preferences
</span><span class="add">+from osaf import Preferences, runInUIThread, waitForDeferred
</span><span class="cx"> from osaf.framework import MasterPassword
</span><span class="lines">@@ -96,7 +108,8 @@
</span><span class="cx"> schema.Text,
doc = 'Salt to be used when deriving key from master password',
)
</span><span class="rem">-
</span><span class="add">+
+ @runInUIThread
</span><span class="cx"> def decryptPassword(self, masterPassword=None, window=None):
"""
Decrypt password and return it.
</span><span class="lines">@@ -111,7 +124,7 @@
</span><span class="cx"> raise UninitializedPassword(_(u'Password has not been set'))
if masterPassword is None:
</span><span class="rem">- masterPassword = MasterPassword.get(self.itsView, window)
</span><span class="add">+ masterPassword = waitForDeferred(MasterPassword.get(self.itsView, window))
</span><span class="cx">
# the crypto algorithms are unicode unfriendly
if isinstance(masterPassword, unicodeThread:
+ try:
+ d.callback(func(*args, **kw))
+ except:
+ d.errback()
+ else:
+ def callback():
+ try:
+ result = func(*args, **kw)
+ except:
+ f = failure.Failure()
+ reactor.callFromThread(d.errback, f)
+ else:
+ reactor.callFromThread(d.callback, result)
+
+ try:
+ wx.GetApp().PostAsyncEvent(callback)
+ except AttributeError:
+ # We don't have app, so we can just do this instead
+ reactor.callFromThread(callback)
+
+ return d
+
+ decorate.__name__ = func.__name__
+ decorate.__dict__ = func.__dict__
+ decorate.__doc__ = func.__doc__
+
+ return decorate
+
+
+def waitForDeferred(d):
+ if threadable.isInIOThread():
+ raise RuntimeError("Can't wait on twisted thread")
+
+ if thread.get_ident() != Globals.UI_Thread:
+ raise RuntimeError("Should run on main thread only")
+
+ queue = Queue.Queue(1)
+ d.addBoth(queue.put)
+ result = queue.get(True)
+ if isinstance(result, failure.Failure):
+ result.raiseException()
+ return result
+
</span></pre></div>
<a id="branchespasswordparcelsosafframeworkMasterPasswordpy"></a>
<div class="modfile"><h4>Modified: branches/password/parcels/osaf/framework/MasterPassword.py (13511 => 13512)</h4>
<pre class="diff">
<span class="info">--- branches/password/parcels/osaf/framework/MasterPassword.py 2007-03-16 20:39:21 UTC (rev 13511)
+++ branches/password/parcels/osaf/framework/MasterPassword.py 2007-03-16 22:05:38 UTC (rev 13512)
</span><span class="lines">@@ -24,7 +24,7 @@
</span><span class="cx"> from i18n import ChandlerMessageFactory as _
from application import schema
from application.dialogs import Util
</span><span class="rem">-from osaf import Preferences
</span><span class="add">+from osaf import Preferences, runInUIThread, waitForDeferred
</span><span class="cx">
log = logging.getLogger(__name__)
masterPassword = None
</span><span class="lines">@@ -34,49 +34,56 @@
</span><span class="cx"> """
Get the master password.
</span><span class="add">+ Safe to call from from a background thread.
+
</span><span class="cx"> @param view: Repository view.
</span><span class="add">+ @return: deferred
</span><span class="cx"> """
</span><span class="rem">- prefs = schema.ns("osaf.framework.MasterPassword",
- view).masterPasswordPrefs
-
- if not prefs.masterPassword:
- password = ''
- else:
- global masterPassword
- if not masterPassword:
- masterPassword = MasterPassword()
-
- password = masterPassword.getMasterPassword(view, window)
</span><span class="add">+ global masterPassword
+ if not masterPassword:
+ masterPassword = MasterPassword()
</span><span class="cx">
</span><span class="rem">- return password
</span><span class="add">+ return masterPassword.getMasterPassword(view, window)
</span><span class="cx">
def change(view, window=None):
"""
Set or change the master password.
</span><span class="add/////////////e |
Mon, 11 Apr, 05:03 |
| safoundation.org |
add">+ self._setTimedPassword(self._password, prefs.timeout * 60)
</span><span class="cx"> return self._password
# Otherwise, let's ask the user...
</span><span class="lines">@@ -134,7 +142,7 @@
</span><span class="cx"> again = False
for item in password.Password.iterItems(view):
try:
</span><span class="rem">- item.decryptPassword(masterPassword=pword) # safe: using master password
</span><span class="add">+ waitForDeferred(item.decryptPassword(masterPassword=pword))
</span><span class="cx"> break
except password.UninitializedPassword:
continue
</span><span class="lines">@@ -156,30 +164,26 @@
</span><span class="cx"> self._setTimedPassword(pword, timeout * 60)
return self._password
</span><span class="add">+ @runInUIThread
</span><span class="cx"> def clearMasterPassword(self):
"""
Clear the master password.
"""
if hasattr(self, '_password'):
</span><span class="rem">- self.timer.cancel() # XXX this can hang on exit
</span><span class="add">+ self.timer.cancel()
</span><span class="cx"> del self._password
</span><span class="rem">- del self.timer
-
</span><span class="add">+ del self.timer
+
+ def _clear(self):
+ d = self.clearMasterPassword()
+ d.addCallback(lambda: True)
+
</span><span class="cx"> def _setTimedPassword(self, password, timeout):
</span><span class="add">+ if hasattr(self, 'timer'):
+ self.timer.cancel()
</span><span class="cx"> self._password = password
</span><span class="rem">- self.timer = threading.Timer(timeout, self.clearMasterPassword)
-
- # XXX Other threads can exit without waiting for this; seems to solve shutdown hang.
- # XXX However, this leads to a shutdown crash about 50% of the time (for some reason still successful exit value):
- #Exception in thread Thread-1 (most likely raised during interpreter shutdown):
- #Traceback (most recent call last):
- # File ".../release/lib/python2.5/threading.py", line 460, in __bootstrap
- # File ".../release/lib/python2.5/threading.py", line 623, in run
- # File ".../release/lib/python2.5/threading.py", line 364, in wait
- # File ".../release/lib/python2.5/threading.py", line 229, in wait
- #<type 'exceptions.TypeError'>: 'NoneType' object is not callable
- self.timer.setDaemon(True)
-
</span><span class="add">+ self.timer = threading.Timer(timeout, self._clear)
+ #self.timer.setDaemon(True) # Exception in thread Thread-1 (most likely raised during interpreter shutdown)
</span><span class="cx"> self.timer.start()
def _change(self, oldMaster, newMaster, view, prefs):
</span><span class="lines">@@ -188,14 +192,14 @@
</span><span class="cx"> again = False
for item in password.Password.iterItems(view):
try:
</span><span class="rem">- oldPassword = item.decryptPassword(masterPassword=oldMaster) # safe: supplying master password
</span><span class="add">+ oldPassword = waitForDeferred(item.decryptPassword(masterPassword=oldMaster))
</span><span class="cx"> except password.UninitializedPassword:
continue
except password.DecryptionError:
log.exception('Wrong old master password?')
again = True
break
</span><span class="rem">- item.encryptPassword(oldPassword, masterPassword=newMaster) # safe: supplying master password
</span><span class="add">+ waitForDeferred(item.encryptPassword(oldPassword, masterPassword=newMaster))
</span><span class="cx">
if again:
return False
</span><span class="lines">@@ -212,6 +216,7 @@
</span><span class="cx">
return True
</span><span class="add">+ @runInUIThread
</span><span class="cx"> def changeMasterPassword(self, view, window=None):
</sp """
Change or set the master password.
</span><span class="lines">@@ -516,7 +521,7 @@
</span><span class="cx"> # clear all passwords
from osaf.framework import password
for item in password.Password.iterItems(view):
</span><span class="rem">- item.clear()
</span><span class="add">+ waitForDeferred(item.clear())
</span><span class="cx">
# Turn off pref
prefs = schema.ns("osaf.framework.MasterPassword",
</span><span class="lines">@@ -528,7 +533,7 @@
</span><span class="cx"> view).passwordPrefs
password = ''.join([string.printable[ord(c) % len(string.printable)] \
for c in os.urandom(16)])
</span><span class="rem">- prefs.dummyPassword.encryptPassword(password, masterPassword='') # safe: supplying master password
</span><span class="add">+ waitForDeferred(prefs.dummyPassword.encryptPassword(password, masterPassword=''))
</span><span class="cx"> except:
try:
log.exception('Failed to reset master password')
</span></pre></div>
<a id="branchespasswordparcelsosafframeworkpasswordpy"></a>
<div class="modfile"><h4>Modified: branches/password/parcels/osaf/framework/password.py (13511 => 13512)</h4>
<pre class="diff">
<span class="info">--- branches/password/parcels/osaf/framework/password.py 2007-03-16 20:39:21 UTC (rev 13511)
+++ branches/password/parcels/osaf/framework/password.py 2007-03-16 22:05:38 UTC (rev 13512)
</span><span class="lines">@@ -21,12 +21,24 @@
</span><span class="cx"> 'Password',
]
</span><span class="add">+# discussion with pje, Grant about threads:
+#http://wiki.osafoundation.org/script/getIrcTranscript.cgi?channel=chandler&startTime=1057&endTime=1157&date=20070315
+# TODO: callers of Password methods must deal with deferreds
+
</span><span class="cx"> # XXX share (all done?), imap, pop, smtp accounts
</span><span class="rem">-# XXX when MasterPassword imported/used, chandler does not always quit; unit tests don't quit
-# XXX asking for master password from background thread will probably break
-# XXX - maybe ensure we have master password before bg thread starts, disable master timeout until bg thread finishes
-# XXX - another option might be to ensure no account objects are used in threads, only account attribute values
</span><span class="add">+# XXX flatten MasterPassword (don't think we need class)
+
</span><span class="cx"> # XXX if perf too slow: hmac-sha1, just one call to os.urandom, M2Crypto.EVP.pbkdf2
</span><span class="add">+# XXX minor improvement over waitForDeferred could be:
+# def resultOfDeferred(d):
+# try:
+# result = d.result
+# except AttributeError:
+# raise AssertionError("Deferred has no result")
+# else:
+# if isinstance(result, Failure):
+# result.raiseException()
+# return result
</span><span class="cx">
import os, hmac, string
from binascii import hexlify, unhexlify
</span><span class="lines">@@ -35,7 +47,7 @@
</span><span class="cx"> from application import schema
from util import pbkdf2
from repository.util import Streams
</span><span class="rem">-from osaf import Preferences
</span><span class="add">+from osaf import Preferences, runInUIThread, waitForDeferred
</span><span class="cx"> from osaf.framework import MasterPassword
</span><span class="lines">@@ -96,7 +108,8 @@
</span><span class="cx"> schema.Text,
doc = 'Salt to be used when deriving key from master password',
)
</span><span class="rem">-
</span><span class="add">+
+ @runInUIThread
</span><span class="cx"> def decryptPassword(self, masterPassword=None, window=None):
"""
Decrypt password and return it.
</span><span class="lines">@@ -111,7 +124,7 @@
</span><span class="cx"> raise UninitializedPassword(_(u'Password has not been set'))
if masterPassword is None:
</span><span class="rem">- masterPassword = MasterPassword.get(self.itsView, window)
</span><span class="add">+ masterPassword = waitForDeferred(MasterPassword.get(self.itsView, window))
</span><span class="cx">
# the crypto algorithms are unicode unfriendly
if isinstance(masterPassword, unicodehivetest.cpp2005-12-2117:48:59UTC(rev8787)</span><spanclass="lines">@@-2,7+2,7@@</span><spanclass="cx">//Name:tests/archive/archive.cpp//Purpose:Testthearchiveclasses//Author:MikeWetherell</span><spanclass="rem">-//RCS-ID:$Id:archivetest.cpp,v1.142005/12/1813:58:55MWExp$</span><spanclass="add">+//RCS-ID:$Id:archivetest.cpp,v1.152005/12/2101:23:17VZExp$</span><spanclass="cx">//Copyright:(c)2004MikeWetherell//Licence:wxWindowslicence///////////////////////////////////////////////////////////////////////////////</span><spanclass="lines">@@-1177,7+1177,7@@</span><spanclass="cx">stringTestId::MakeId(){m_seed=(m_seed*171)%30269;</span><spanclass="rem">-returnwxString::Format(_T(&quot;%-6d&quot;),m_seed).mb_str();</span><spanclass="add">+return(constchar*)wxString::Format(_T(&quot;%-6d&quot;),m_seed).mb_str();</span><spanclass="cx">}</span></pre></div></div></body></html>.org%3e"title="Previousbydate"> |
Mon, 11 Apr, 05:03 |
| safoundation.org |
add">+ self._setTimedPassword(self._password, prefs.timeout * 60)
</span><span class="cx"> return self._password
# Otherwise, let's ask the user...
</span><span class="lines">@@ -134,7 +142,7 @@
</span><span class="cx"> again = False
for item in password.Password.iterItems(view):
try:
</span><span class="rem">- item.decryptPassword(masterPassword=pword) # safe: using master password
</span><span class="add">+ waitForDeferred(item.decryptPassword(masterPassword=pword))
</span><span class="cx"> break
except password.UninitializedPassword:
continue
</span><span class="lines">@@ -156,30 +164,26 @@
</span><span class="cx"> self._setTimedPassword(pword, timeout * 60)
return self._password
</span><span class="add">+ @runInUIThread
</span><span class="cx"> def clearMasterPassword(self):
"""
Clear the master password.
"""
if hasattr(self, '_password'):
</span><span class="rem">- self.timer.cancel() # XXX this can hang on exit
</span><span class="add">+ self.timer.cancel()
</span><span class="cx"> del self._password
</span><span class="rem">- del self.timer
-
</span><span class="add">+ del self.timer
+
+ def _clear(self):
+ d = self.clearMasterPassword()
+ d.addCallback(lambda: True)
+
</span><span class="cx"> def _setTimedPassword(self, password, timeout):
</span><span class="add">+ if hasattr(self, 'timer'):
+ self.timer.cancel()
</span><span class="cx"> self._password = password
</span><span class="rem">- self.timer = threading.Timer(timeout, self.clearMasterPassword)
-
- # XXX Other threads can exit without waiting for this; seems to solve shutdown hang.
- # XXX However, this leads to a shutdown crash about 50% of the time (for some reason still successful exit value):
- #Exception in thread Thread-1 (most likely raised during interpreter shutdown):
- #Traceback (most recent call last):
- # File ".../release/lib/python2.5/threading.py", line 460, in __bootstrap
- # File ".../release/lib/python2.5/threading.py", line 623, in run
- # File ".../release/lib/python2.5/threading.py", line 364, in wait
- # File ".../release/lib/python2.5/threading.py", line 229, in wait
- #<type 'exceptions.TypeError'>: 'NoneType' object is not callable
- self.timer.setDaemon(True)
-
</span><span class="add">+ self.timer = threading.Timer(timeout, self._clear)
+ #self.timer.setDaemon(True) # Exception in thread Thread-1 (most likely raised during interpreter shutdown)
</span><span class="cx"> self.timer.start()
def _change(self, oldMaster, newMaster, view, prefs):
</span><span class="lines">@@ -188,14 +192,14 @@
</span><span class="cx"> again = False
for item in password.Password.iterItems(view):
try:
</span><span class="rem">- oldPassword = item.decryptPassword(masterPassword=oldMaster) # safe: supplying master password
</span><span class="add">+ oldPassword = waitForDeferred(item.decryptPassword(masterPassword=oldMaster))
</span><span class="cx"> except password.UninitializedPassword:
continue
except password.DecryptionError:
log.exception('Wrong old master password?')
again = True
break
</span><span class="rem">- item.encryptPassword(oldPassword, masterPassword=newMaster) # safe: supplying master password
</span><span class="add">+ waitForDeferred(item.encryptPassword(oldPassword, masterPassword=newMaster))
</span><span class="cx">
if again:
return False
</span><span class="lines">@@ -212,6 +216,7 @@
</span><span class="cx">
return True
</span><span class="add">+ @runInUIThread
</span><span class="cx"> def changeMasterPassword(self, view, window=None):
</sp """
Change or set the master password.
</span><span class="lines">@@ -516,7 +521,7 @@
</span><span class="cx"> # clear all passwords
from osaf.framework import password
for item in password.Password.iterItems(view):
</span><span class="rem">- item.clear()
</span><span class="add">+ waitForDeferred(item.clear())
</span><span class="cx">
# Turn off pref
prefs = schema.ns("osaf.framework.MasterPassword",
</span><span class="lines">@@ -528,7 +533,7 @@
</span><span class="cx"> view).passwordPrefs
password = ''.join([string.printable[ord(c) % len(string.printable)] \
for c in os.urandom(16)])
</span><span class="rem">- prefs.dummyPassword.encryptPassword(password, masterPassword='') # safe: supplying master password
</span><span class="add">+ waitForDeferred(prefs.dummyPassword.encryptPassword(password, masterPassword=''))
</span><span class="cx"> except:
try:
log.exception('Failed to reset master password')
</span></pre></div>
<a id="branchespasswordparcelsosafframeworkpasswordpy"></a>
<div class="modfile"><h4>Modified: branches/password/parcels/osaf/framework/password.py (13511 => 13512)</h4>
<pre class="diff">
<span class="info">--- branches/password/parcels/osaf/framework/password.py 2007-03-16 20:39:21 UTC (rev 13511)
+++ branches/password/parcels/osaf/framework/password.py 2007-03-16 22:05:38 UTC (rev 13512)
</span><span class="lines">@@ -21,12 +21,24 @@
</span><span class="cx"> 'Password',
]
</span><span class="add">+# discussion with pje, Grant about threads:
+#http://wiki.osafoundation.org/script/getIrcTranscript.cgi?channel=chandler&startTime=1057&endTime=1157&date=20070315
+# TODO: callers of Password methods must deal with deferreds
+
</span><span class="cx"> # XXX share (all done?), imap, pop, smtp accounts
</span><span class="rem">-# XXX when MasterPassword imported/used, chandler does not always quit; unit tests don't quit
-# XXX asking for master password from background thread will probably break
-# XXX - maybe ensure we have master password before bg thread starts, disable master timeout until bg thread finishes
-# XXX - another option might be to ensure no account objects are used in threads, only account attribute values
</span><span class="add">+# XXX flatten MasterPassword (don't think we need class)
+
</span><span class="cx"> # XXX if perf too slow: hmac-sha1, just one call to os.urandom, M2Crypto.EVP.pbkdf2
</span><span class="add">+# XXX minor improvement over waitForDeferred could be:
+# def resultOfDeferred(d):
+# try:
+# result = d.result
+# except AttributeError:
+# raise AssertionError("Deferred has no result")
+# else:
+# if isinstance(result, Failure):
+# result.raiseException()
+# return result
</span><span class="cx">
import os, hmac, string
from binascii import hexlify, unhexlify
</span><span class="lines">@@ -35,7 +47,7 @@
</span><span class="cx"> from application import schema
from util import pbkdf2
from repository.util import Streams
</span><span class="rem">-from osaf import Preferences
</span><span class="add">+from osaf import Preferences, runInUIThread, waitForDeferred
</span><span class="cx"> from osaf.framework import MasterPassword
</span><span class="lines">@@ -96,7 +108,8 @@
</span><span class="cx"> schema.Text,
doc = 'Salt to be used when deriving key from master password',
)
</span><span class="rem">-
</span><span class="add">+
+ @runInUIThread
</span><span class="cx"> def decryptPassword(self, masterPassword=None, window=None):
"""
Decrypt password and return it.
</span><span class="lines">@@ -111,7 +124,7 @@
</span><span class="cx"> raise UninitializedPassword(_(u'Password has not been set'))
if masterPassword is None:
</span><span class="rem">- masterPassword = MasterPassword.get(self.itsView, window)
</span><span class="add">+ masterPassword = waitForDeferred(MasterPassword.get(self.itsView, window))
</span><span class="cx">
# the crypto algorithms are unicode unfriendly
if isinstance(masterPassword, unicodeThread:
+ try:
+ d.callback(func(*args, **kw))
+ except:
+ d.errback()
+ else:
+ def callback():
+ try:
+ result = func(*args, **kw)
+ except:
+ f = failure.Failure()
+ reactor.callFromThread(d.errback, f)
+ else:
+ reactor.callFromThread(d.callback, result)
+
+ try:
+ wx.GetApp().PostAsyncEvent(callback)
+ except AttributeError:
+ # We don't have app, so we can just do this instead
+ reactor.callFromThread(callback)
+
+ return d
+
+ decorate.__name__ = func.__name__
+ decorate.__dict__ = func.__dict__
+ decorate.__doc__ = func.__doc__
+
+ return decorate
+
+
+def waitForDeferred(d):
+ if threadable.isInIOThread():
+ raise RuntimeError("Can't wait on twisted thread")
+
+ if thread.get_ident() != Globals.UI_Thread:
+ raise RuntimeError("Should run on main thread only")
+
+ queue = Queue.Queue(1)
+ d.addBoth(queue.put)
+ result = queue.get(True)
+ if isinstance(result, failure.Failure):
+ result.raiseException()
+ return result
+
</span></pre></div>
<a id="branchespasswordparcelsosafframeworkMasterPasswordpy"></a>
<div class="modfile"><h4>Modified: branches/password/parcels/osaf/framework/MasterPassword.py (13511 => 13512)</h4>
<pre class="diff">
<span class="info">--- branches/password/parcels/osaf/framework/MasterPassword.py 2007-03-16 20:39:21 UTC (rev 13511)
+++ branches/password/parcels/osaf/framework/MasterPassword.py 2007-03-16 22:05:38 UTC (rev 13512)
</span><span class="lines">@@ -24,7 +24,7 @@
</span><span class="cx"> from i18n import ChandlerMessageFactory as _
from application import schema
from application.dialogs import Util
</span><span class="rem">-from osaf import Preferences
</span><span class="add">+from osaf import Preferences, runInUIThread, waitForDeferred
</span><span class="cx">
log = logging.getLogger(__name__)
masterPassword = None
</span><span class="lines">@@ -34,49 +34,56 @@
</span><span class="cx"> """
Get the master password.
</span><span class="add">+ Safe to call from from a background thread.
+
</span><span class="cx"> @param view: Repository view.
</span><span class="add">+ @return: deferred
</span><span class="cx"> """
</span><span class="rem">- prefs = schema.ns("osaf.framework.MasterPassword",
- view).masterPasswordPrefs
-
- if not prefs.masterPassword:
- password = ''
- else:
- global masterPassword
- if not masterPassword:
- masterPassword = MasterPassword()
-
- password = masterPassword.getMasterPassword(view, window)
</span><span class="add">+ global masterPassword
+ if not masterPassword:
+ masterPassword = MasterPassword()
</span><span class="cx">
</span><span class="rem">- return password
</span><span class="add">+ return masterPassword.getMasterPassword(view, window)
</span><span class="cx">
def change(view, window=None):
"""
Set or change the master password.
</span><span class="add/////////////e |
Mon, 11 Apr, 05:03 |
| safoundation.org |
add">+ self._setTimedPassword(self._password, prefs.timeout * 60)
</span><span class="cx"> return self._password
# Otherwise, let's ask the user...
</span><span class="lines">@@ -134,7 +142,7 @@
</span><span class="cx"> again = False
for item in password.Password.iterItems(view):
try:
</span><span class="rem">- item.decryptPassword(masterPassword=pword) # safe: using master password
</span><span class="add">+ waitForDeferred(item.decryptPassword(masterPassword=pword))
</span><span class="cx"> break
except password.UninitializedPassword:
continue
</span><span class="lines">@@ -156,30 +164,26 @@
</span><span class="cx"> self._setTimedPassword(pword, timeout * 60)
return self._password
</span><span class="add">+ @runInUIThread
</span><span class="cx"> def clearMasterPassword(self):
"""
Clear the master password.
"""
if hasattr(self, '_password'):
</span><span class="rem">- self.timer.cancel() # XXX this can hang on exit
</span><span class="add">+ self.timer.cancel()
</span><span class="cx"> del self._password
</span><span class="rem">- del self.timer
-
</span><span class="add">+ del self.timer
+
+ def _clear(self):
+ d = self.clearMasterPassword()
+ d.addCallback(lambda: True)
+
</span><span class="cx"> def _setTimedPassword(self, password, timeout):
</span><span class="add">+ if hasattr(self, 'timer'):
+ self.timer.cancel()
</span><span class="cx"> self._password = password
</span><span class="rem">- self.timer = threading.Timer(timeout, self.clearMasterPassword)
-
- # XXX Other threads can exit without waiting for this; seems to solve shutdown hang.
- # XXX However, this leads to a shutdown crash about 50% of the time (for some reason still successful exit value):
- #Exception in thread Thread-1 (most likely raised during interpreter shutdown):
- #Traceback (most recent call last):
- # File ".../release/lib/python2.5/threading.py", line 460, in __bootstrap
- # File ".../release/lib/python2.5/threading.py", line 623, in run
- # File ".../release/lib/python2.5/threading.py", line 364, in wait
- # File ".../release/lib/python2.5/threading.py", line 229, in wait
- #<type 'exceptions.TypeError'>: 'NoneType' object is not callable
- self.timer.setDaemon(True)
-
</span><span class="add">+ self.timer = threading.Timer(timeout, self._clear)
+ #self.timer.setDaemon(True) # Exception in thread Thread-1 (most likely raised during interpreter shutdown)
</span><span class="cx"> self.timer.start()
def _change(self, oldMaster, newMaster, view, prefs):
</span><span class="lines">@@ -188,14 +192,14 @@
</span><span class="cx"> again = False
for item in password.Password.iterItems(view):
try:
</span><span class="rem">- oldPassword = item.decryptPassword(masterPassword=oldMaster) # safe: supplying master password
</span><span class="add">+ oldPassword = waitForDeferred(item.decryptPassword(masterPassword=oldMaster))
</span><span class="cx"> except password.UninitializedPassword:
continue
except password.DecryptionError:
log.exception('Wrong old master password?')
again = True
break
</span><span class="rem">- item.encryptPassword(oldPassword, masterPassword=newMaster) # safe: supplying master password
</span><span class="add">+ waitForDeferred(item.encryptPassword(oldPassword, masterPassword=newMaster))
</span><span class="cx">
if again:
return False
</span><span class="lines">@@ -212,6 +216,7 @@
</span><span class="cx">
return True
</span><span class="add">+ @runInUIThread
</span><span class="cx"> def changeMasterPassword(self, view, window=None):
</sp """
Change or set the master password.
</span><span class="lines">@@ -516,7 +521,7 @@
</span><span class="cx"> # clear all passwords
from osaf.framework import password
for item in password.Password.iterItems(view):
</span><span class="rem">- item.clear()
</span><span class="add">+ waitForDeferred(item.clear())
</span><span class="cx">
# Turn off pref
prefs = schema.ns("osaf.framework.MasterPassword",
</span><span class="lines">@@ -528,7 +533,7 @@
</span><span class="cx"> view).passwordPrefs
password = ''.join([string.printable[ord(c) % len(string.printable)] \
for c in os.urandom(16)])
</span><span class="rem">- prefs.dummyPassword.encryptPassword(password, masterPassword='') # safe: supplying master password
</span><span class="add">+ waitForDeferred(prefs.dummyPassword.encryptPassword(password, masterPassword=''))
</span><span class="cx"> except:
try:
log.exception('Failed to reset master password')
</span></pre></div>
<a id="branchespasswordparcelsosafframeworkpasswordpy"></a>
<div class="modfile"><h4>Modified: branches/password/parcels/osaf/framework/password.py (13511 => 13512)</h4>
<pre class="diff">
<span class="info">--- branches/password/parcels/osaf/framework/password.py 2007-03-16 20:39:21 UTC (rev 13511)
+++ branches/password/parcels/osaf/framework/password.py 2007-03-16 22:05:38 UTC (rev 13512)
</span><span class="lines">@@ -21,12 +21,24 @@
</span><span class="cx"> 'Password',
]
</span><span class="add">+# discussion with pje, Grant about threads:
+#http://wiki.osafoundation.org/script/getIrcTranscript.cgi?channel=chandler&startTime=1057&endTime=1157&date=20070315
+# TODO: callers of Password methods must deal with deferreds
+
</span><span class="cx"> # XXX share (all done?), imap, pop, smtp accounts
</span><span class="rem">-# XXX when MasterPassword imported/used, chandler does not always quit; unit tests don't quit
-# XXX asking for master password from background thread will probably break
-# XXX - maybe ensure we have master password before bg thread starts, disable master timeout until bg thread finishes
-# XXX - another option might be to ensure no account objects are used in threads, only account attribute values
</span><span class="add">+# XXX flatten MasterPassword (don't think we need class)
+
</span><span class="cx"> # XXX if perf too slow: hmac-sha1, just one call to os.urandom, M2Crypto.EVP.pbkdf2
</span><span class="add">+# XXX minor improvement over waitForDeferred could be:
+# def resultOfDeferred(d):
+# try:
+# result = d.result
+# except AttributeError:
+# raise AssertionError("Deferred has no result")
+# else:
+# if isinstance(result, Failure):
+# result.raiseException()
+# return result
</span><span class="cx">
import os, hmac, string
from binascii import hexlify, unhexlify
</span><span class="lines">@@ -35,7 +47,7 @@
</span><span class="cx"> from application import schema
from util import pbkdf2
from repository.util import Streams
</span><span class="rem">-from osaf import Preferences
</span><span class="add">+from osaf import Preferences, runInUIThread, waitForDeferred
</span><span class="cx"> from osaf.framework import MasterPassword
</span><span class="lines">@@ -96,7 +108,8 @@
</span><span class="cx"> schema.Text,
doc = 'Salt to be used when deriving key from master password',
)
</span><span class="rem">-
</span><span class="add">+
+ @runInUIThread
</span><span class="cx"> def decryptPassword(self, masterPassword=None, window=None):
"""
Decrypt password and return it.
</span><span class="lines">@@ -111,7 +124,7 @@
</span><span class="cx"> raise UninitializedPassword(_(u'Password has not been set'))
if masterPassword is None:
</span><span class="rem">- masterPassword = MasterPassword.get(self.itsView, window)
</span><span class="add">+ masterPassword = waitForDeferred(MasterPassword.get(self.itsView, window))
</span><span class="cx">
# the crypto algorithms are unicode unfriendly
if isinstance(masterPassword, unicodehivetest.cpp2005-12-2117:48:59UTC(rev8787)</span><spanclass="lines">@@-2,7+2,7@@</span><spanclass="cx">//Name:tests/archive/archive.cpp//Purpose:Testthearchiveclasses//Author:MikeWetherell</span><spanclass="rem">-//RCS-ID:$Id:archivetest.cpp,v1.142005/12/1813:58:55MWExp$</span><spanclass="add">+//RCS-ID:$Id:archivetest.cpp,v1.152005/12/2101:23:17VZExp$</span><spanclass="cx">//Copyright:(c)2004MikeWetherell//Licence:wxWindowslicence///////////////////////////////////////////////////////////////////////////////</span><spanclass="lines">@@-1177,7+1177,7@@</span><spanclass="cx">stringTestId::MakeId(){m_seed=(m_seed*171)%30269;</span><spanclass="rem">-returnwxString::Format(_T(&quot;%-6d&quot;),m_seed).mb_str();</span><spanclass="add">+return(constchar*)wxString::Format(_T(&quot;%-6d&quot;),m_seed).mb_str();</span><spanclass="cx">}</span></pre></div></div></body></html>.org%3e"title="Previousbydate"> |
Mon, 11 Apr, 05:03 |
| safoundation.org |
add">+ self._setTimedPassword(self._password, prefs.timeout * 60)
</span><span class="cx"> return self._password
# Otherwise, let's ask the user...
</span><span class="lines">@@ -134,7 +142,7 @@
</span><span class="cx"> again = False
for item in password.Password.iterItems(view):
try:
</span><span class="rem">- item.decryptPassword(masterPassword=pword) # safe: using master password
</span><span class="add">+ waitForDeferred(item.decryptPassword(masterPassword=pword))
</span><span class="cx"> break
except password.UninitializedPassword:
continue
</span><span class="lines">@@ -156,30 +164,26 @@
</span><span class="cx"> self._setTimedPassword(pword, timeout * 60)
return self._password
</span><span class="add">+ @runInUIThread
</span><span class="cx"> def clearMasterPassword(self):
"""
Clear the master password.
"""
if hasattr(self, '_password'):
</span><span class="rem">- self.timer.cancel() # XXX this can hang on exit
</span><span class="add">+ self.timer.cancel()
</span><span class="cx"> del self._password
</span><span class="rem">- del self.timer
-
</span><span class="add">+ del self.timer
+
+ def _clear(self):
+ d = self.clearMasterPassword()
+ d.addCallback(lambda: True)
+
</span><span class="cx"> def _setTimedPassword(self, password, timeout):
</span><span class="add">+ if hasattr(self, 'timer'):
+ self.timer.cancel()
</span><span class="cx"> self._password = password
</span><span class="rem">- self.timer = threading.Timer(timeout, self.clearMasterPassword)
-
- # XXX Other threads can exit without waiting for this; seems to solve shutdown hang.
- # XXX However, this leads to a shutdown crash about 50% of the time (for some reason still successful exit value):
- #Exception in thread Thread-1 (most likely raised during interpreter shutdown):
- #Traceback (most recent call last):
- # File ".../release/lib/python2.5/threading.py", line 460, in __bootstrap
- # File ".../release/lib/python2.5/threading.py", line 623, in run
- # File ".../release/lib/python2.5/threading.py", line 364, in wait
- # File ".../release/lib/python2.5/threading.py", line 229, in wait
- #<type 'exceptions.TypeError'>: 'NoneType' object is not callable
- self.timer.setDaemon(True)
-
</span><span class="add">+ self.timer = threading.Timer(timeout, self._clear)
+ #self.timer.setDaemon(True) # Exception in thread Thread-1 (most likely raised during interpreter shutdown)
</span><span class="cx"> self.timer.start()
def _change(self, oldMaster, newMaster, view, prefs):
</span><span class="lines">@@ -188,14 +192,14 @@
</span><span class="cx"> again = False
for item in password.Password.iterItems(view):
try:
</span><span class="rem">- oldPassword = item.decryptPassword(masterPassword=oldMaster) # safe: supplying master password
</span><span class="add">+ oldPassword = waitForDeferred(item.decryptPassword(masterPassword=oldMaster))
</span><span class="cx"> except password.UninitializedPassword:
continue
except password.DecryptionError:
log.exception('Wrong old master password?')
again = True
break
</span><span class="rem">- item.encryptPassword(oldPassword, masterPassword=newMaster) # safe: supplying master password
</span><span class="add">+ waitForDeferred(item.encryptPassword(oldPassword, masterPassword=newMaster))
</span><span class="cx">
if again:
return False
</span><span class="lines">@@ -212,6 +216,7 @@
</span><span class="cx">
return True
</span><span class="add">+ @runInUIThread
</span><span class="cx"> def changeMasterPassword(self, view, window=None):
</sp """
Change or set the master password.
</span><span class="lines">@@ -516,7 +521,7 @@
</span><span class="cx"> # clear all passwords
from osaf.framework import password
for item in password.Password.iterItems(view):
</span><span class="rem">- item.clear()
</span><span class="add">+ waitForDeferred(item.clear())
</span><span class="cx">
# Turn off pref
prefs = schema.ns("osaf.framework.MasterPassword",
</span><span class="lines">@@ -528,7 +533,7 @@
</span><span class="cx"> view).passwordPrefs
password = ''.join([string.printable[ord(c) % len(string.printable)] \
for c in os.urandom(16)])
</span><span class="rem">- prefs.dummyPassword.encryptPassword(password, masterPassword='') # safe: supplying master password
</span><span class="add">+ waitForDeferred(prefs.dummyPassword.encryptPassword(password, masterPassword=''))
</span><span class="cx"> except:
try:
log.exception('Failed to reset master password')
</span></pre></div>
<a id="branchespasswordparcelsosafframeworkpasswordpy"></a>
<div class="modfile"><h4>Modified: branches/password/parcels/osaf/framework/password.py (13511 => 13512)</h4>
<pre class="diff">
<span class="info">--- branches/password/parcels/osaf/framework/password.py 2007-03-16 20:39:21 UTC (rev 13511)
+++ branches/password/parcels/osaf/framework/password.py 2007-03-16 22:05:38 UTC (rev 13512)
</span><span class="lines">@@ -21,12 +21,24 @@
</span><span class="cx"> 'Password',
]
</span><span class="add">+# discussion with pje, Grant about threads:
+#http://wiki.osafoundation.org/script/getIrcTranscript.cgi?channel=chandler&startTime=1057&endTime=1157&date=20070315
+# TODO: callers of Password methods must deal with deferreds
+
</span><span class="cx"> # XXX share (all done?), imap, pop, smtp accounts
</span><span class="rem">-# XXX when MasterPassword imported/used, chandler does not always quit; unit tests don't quit
-# XXX asking for master password from background thread will probably break
-# XXX - maybe ensure we have master password before bg thread starts, disable master timeout until bg thread finishes
-# XXX - another option might be to ensure no account objects are used in threads, only account attribute values
</span><span class="add">+# XXX flatten MasterPassword (don't think we need class)
+
</span><span class="cx"> # XXX if perf too slow: hmac-sha1, just one call to os.urandom, M2Crypto.EVP.pbkdf2
</span><span class="add">+# XXX minor improvement over waitForDeferred could be:
+# def resultOfDeferred(d):
+# try:
+# result = d.result
+# except AttributeError:
+# raise AssertionError("Deferred has no result")
+# else:
+# if isinstance(result, Failure):
+# result.raiseException()
+# return result
</span><span class="cx">
import os, hmac, string
from binascii import hexlify, unhexlify
</span><span class="lines">@@ -35,7 +47,7 @@
</span><span class="cx"> from application import schema
from util import pbkdf2
from repository.util import Streams
</span><span class="rem">-from osaf import Preferences
</span><span class="add">+from osaf import Preferences, runInUIThread, waitForDeferred
</span><span class="cx"> from osaf.framework import MasterPassword
</span><span class="lines">@@ -96,7 +108,8 @@
</span><span class="cx"> schema.Text,
doc = 'Salt to be used when deriving key from master password',
)
</span><span class="rem">-
</span><span class="add">+
+ @runInUIThread
</span><span class="cx"> def decryptPassword(self, masterPassword=None, window=None):
"""
Decrypt password and return it.
</span><span class="lines">@@ -111,7 +124,7 @@
</span><span class="cx"> raise UninitializedPassword(_(u'Password has not been set'))
if masterPassword is None:
</span><span class="rem">- masterPassword = MasterPassword.get(self.itsView, window)
</span><span class="add">+ masterPassword = waitForDeferred(MasterPassword.get(self.itsView, window))
</span><span class="cx">
# the crypto algorithms are unicode unfriendly
if isinstance(masterPassword, unicodeThread:
+ try:
+ d.callback(func(*args, **kw))
+ except:
+ d.errback()
+ else:
+ def callback():
+ try:
+ result = func(*args, **kw)
+ except:
+ f = failure.Failure()
+ reactor.callFromThread(d.errback, f)
+ else:
+ reactor.callFromThread(d.callback, result)
+
+ try:
+ wx.GetApp().PostAsyncEvent(callback)
+ except AttributeError:
+ # We don't have app, so we can just do this instead
+ reactor.callFromThread(callback)
+
+ return d
+
+ decorate.__name__ = func.__name__
+ decorate.__dict__ = func.__dict__
+ decorate.__doc__ = func.__doc__
+
+ return decorate
+
+
+def waitForDeferred(d):
+ if threadable.isInIOThread():
+ raise RuntimeError("Can't wait on twisted thread")
+
+ if thread.get_ident() != Globals.UI_Thread:
+ raise RuntimeError("Should run on main thread only")
+
+ queue = Queue.Queue(1)
+ d.addBoth(queue.put)
+ result = queue.get(True)
+ if isinstance(result, failure.Failure):
+ result.raiseException()
+ return result
+
</span></pre></div>
<a id="branchespasswordparcelsosafframeworkMasterPasswordpy"></a>
<div class="modfile"><h4>Modified: branches/password/parcels/osaf/framework/MasterPassword.py (13511 => 13512)</h4>
<pre class="diff">
<span class="info">--- branches/password/parcels/osaf/framework/MasterPassword.py 2007-03-16 20:39:21 UTC (rev 13511)
+++ branches/password/parcels/osaf/framework/MasterPassword.py 2007-03-16 22:05:38 UTC (rev 13512)
</span><span class="lines">@@ -24,7 +24,7 @@
</span><span class="cx"> from i18n import ChandlerMessageFactory as _
from application import schema
from application.dialogs import Util
</span><span class="rem">-from osaf import Preferences
</span><span class="add">+from osaf import Preferences, runInUIThread, waitForDeferred
</span><span class="cx">
log = logging.getLogger(__name__)
masterPassword = None
</span><span class="lines">@@ -34,49 +34,56 @@
</span><span class="cx"> """
Get the master password.
</span><span class="add">+ Safe to call from from a background thread.
+
</span><span class="cx"> @param view: Repository view.
</span><span class="add">+ @return: deferred
</span><span class="cx"> """
</span><span class="rem">- prefs = schema.ns("osaf.framework.MasterPassword",
- view).masterPasswordPrefs
-
- if not prefs.masterPassword:
- password = ''
- else:
- global masterPassword
- if not masterPassword:
- masterPassword = MasterPassword()
-
- password = masterPassword.getMasterPassword(view, window)
</span><span class="add">+ global masterPassword
+ if not masterPassword:
+ masterPassword = MasterPassword()
</span><span class="cx">
</span><span class="rem">- return password
</span><span class="add">+ return masterPassword.getMasterPassword(view, window)
</span><span class="cx">
def change(view, window=None):
"""
Set or change the master password.
</span><span class="add/////////////e |
Mon, 11 Apr, 05:03 |
| safoundation.org |
add">+ self._setTimedPassword(self._password, prefs.timeout * 60)
</span><span class="cx"> return self._password
# Otherwise, let's ask the user...
</span><span class="lines">@@ -134,7 +142,7 @@
</span><span class="cx"> again = False
for item in password.Password.iterItems(view):
try:
</span><span class="rem">- item.decryptPassword(masterPassword=pword) # safe: using master password
</span><span class="add">+ waitForDeferred(item.decryptPassword(masterPassword=pword))
</span><span class="cx"> break
except password.UninitializedPassword:
continue
</span><span class="lines">@@ -156,30 +164,26 @@
</span><span class="cx"> self._setTimedPassword(pword, timeout * 60)
return self._password
</span><span class="add">+ @runInUIThread
</span><span class="cx"> def clearMasterPassword(self):
"""
Clear the master password.
"""
if hasattr(self, '_password'):
</span><span class="rem">- self.timer.cancel() # XXX this can hang on exit
</span><span class="add">+ self.timer.cancel()
</span><span class="cx"> del self._password
</span><span class="rem">- del self.timer
-
</span><span class="add">+ del self.timer
+
+ def _clear(self):
+ d = self.clearMasterPassword()
+ d.addCallback(lambda: True)
+
</span><span class="cx"> def _setTimedPassword(self, password, timeout):
</span><span class="add">+ if hasattr(self, 'timer'):
+ self.timer.cancel()
</span><span class="cx"> self._password = password
</span><span class="rem">- self.timer = threading.Timer(timeout, self.clearMasterPassword)
-
- # XXX Other threads can exit without waiting for this; seems to solve shutdown hang.
- # XXX However, this leads to a shutdown crash about 50% of the time (for some reason still successful exit value):
- #Exception in thread Thread-1 (most likely raised during interpreter shutdown):
- #Traceback (most recent call last):
- # File ".../release/lib/python2.5/threading.py", line 460, in __bootstrap
- # File ".../release/lib/python2.5/threading.py", line 623, in run
- # File ".../release/lib/python2.5/threading.py", line 364, in wait
- # File ".../release/lib/python2.5/threading.py", line 229, in wait
- #<type 'exceptions.TypeError'>: 'NoneType' object is not callable
- self.timer.setDaemon(True)
-
</span><span class="add">+ self.timer = threading.Timer(timeout, self._clear)
+ #self.timer.setDaemon(True) # Exception in thread Thread-1 (most likely raised during interpreter shutdown)
</span><span class="cx"> self.timer.start()
def _change(self, oldMaster, newMaster, view, prefs):
</span><span class="lines">@@ -188,14 +192,14 @@
</span><span class="cx"> again = False
for item in password.Password.iterItems(view):
try:
</span><span class="rem">- oldPassword = item.decryptPassword(masterPassword=oldMaster) # safe: supplying master password
</span><span class="add">+ oldPassword = waitForDeferred(item.decryptPassword(masterPassword=oldMaster))
</span><span class="cx"> except password.UninitializedPassword:
continue
except password.DecryptionError:
log.exception('Wrong old master password?')
again = True
break
</span><span class="rem">- item.encryptPassword(oldPassword, masterPassword=newMaster) # safe: supplying master password
</span><span class="add">+ waitForDeferred(item.encryptPassword(oldPassword, masterPassword=newMaster))
</span><span class="cx">
if again:
return False
</span><span class="lines">@@ -212,6 +216,7 @@
</span><span class="cx">
return True
</span><span class="add">+ @runInUIThread
</span><span class="cx"> def changeMasterPassword(self, view, window=None):
</sp """
Change or set the master password.
</span><span class="lines">@@ -516,7 +521,7 @@
</span><span class="cx"> # clear all passwords
from osaf.framework import password
for item in password.Password.iterItems(view):
</span><span class="rem">- item.clear()
</span><span class="add">+ waitForDeferred(item.clear())
</span><span class="cx">
# Turn off pref
prefs = schema.ns("osaf.framework.MasterPassword",
</span><span class="lines">@@ -528,7 +533,7 @@
</span><span class="cx"> view).passwordPrefs
password = ''.join([string.printable[ord(c) % len(string.printable)] \
for c in os.urandom(16)])
</span><span class="rem">- prefs.dummyPassword.encryptPassword(password, masterPassword='') # safe: supplying master password
</span><span class="add">+ waitForDeferred(prefs.dummyPassword.encryptPassword(password, masterPassword=''))
</span><span class="cx"> except:
try:
log.exception('Failed to reset master password')
</span></pre></div>
<a id="branchespasswordparcelsosafframeworkpasswordpy"></a>
<div class="modfile"><h4>Modified: branches/password/parcels/osaf/framework/password.py (13511 => 13512)</h4>
<pre class="diff">
<span class="info">--- branches/password/parcels/osaf/framework/password.py 2007-03-16 20:39:21 UTC (rev 13511)
+++ branches/password/parcels/osaf/framework/password.py 2007-03-16 22:05:38 UTC (rev 13512)
</span><span class="lines">@@ -21,12 +21,24 @@
</span><span class="cx"> 'Password',
]
</span><span class="add">+# discussion with pje, Grant about threads:
+#http://wiki.osafoundation.org/script/getIrcTranscript.cgi?channel=chandler&startTime=1057&endTime=1157&date=20070315
+# TODO: callers of Password methods must deal with deferreds
+
</span><span class="cx"> # XXX share (all done?), imap, pop, smtp accounts
</span><span class="rem">-# XXX when MasterPassword imported/used, chandler does not always quit; unit tests don't quit
-# XXX asking for master password from background thread will probably break
-# XXX - maybe ensure we have master password before bg thread starts, disable master timeout until bg thread finishes
-# XXX - another option might be to ensure no account objects are used in threads, only account attribute values
</span><span class="add">+# XXX flatten MasterPassword (don't think we need class)
+
</span><span class="cx"> # XXX if perf too slow: hmac-sha1, just one call to os.urandom, M2Crypto.EVP.pbkdf2
</span><span class="add">+# XXX minor improvement over waitForDeferred could be:
+# def resultOfDeferred(d):
+# try:
+# result = d.result
+# except AttributeError:
+# raise AssertionError("Deferred has no result")
+# else:
+# if isinstance(result, Failure):
+# result.raiseException()
+# return result
</span><span class="cx">
import os, hmac, string
from binascii import hexlify, unhexlify
</span><span class="lines">@@ -35,7 +47,7 @@
</span><span class="cx"> from application import schema
from util import pbkdf2
from repository.util import Streams
</span><span class="rem">-from osaf import Preferences
</span><span class="add">+from osaf import Preferences, runInUIThread, waitForDeferred
</span><span class="cx"> from osaf.framework import MasterPassword
</span><span class="lines">@@ -96,7 +108,8 @@
</span><span class="cx"> schema.Text,
doc = 'Salt to be used when deriving key from master password',
)
</span><span class="rem">-
</span><span class="add">+
+ @runInUIThread
</span><span class="cx"> def decryptPassword(self, masterPassword=None, window=None):
"""
Decrypt password and return it.
</span><span class="lines">@@ -111,7 +124,7 @@
</span><span class="cx"> raise UninitializedPassword(_(u'Password has not been set'))
if masterPassword is None:
</span><span class="rem">- masterPassword = MasterPassword.get(self.itsView, window)
</span><span class="add">+ masterPassword = waitForDeferred(MasterPassword.get(self.itsView, window))
</span><span class="cx">
# the crypto algorithms are unicode unfriendly
if isinstance(masterPassword, unicodehivetest.cpp2005-12-2117:48:59UTC(rev8787)</span><spanclass="lines">@@-2,7+2,7@@</span><spanclass="cx">//Name:tests/archive/archive.cpp//Purpose:Testthearchiveclasses//Author:MikeWetherell</span><spanclass="rem">-//RCS-ID:$Id:archivetest.cpp,v1.142005/12/1813:58:55MWExp$</span><spanclass="add">+//RCS-ID:$Id:archivetest.cpp,v1.152005/12/2101:23:17VZExp$</span><spanclass="cx">//Copyright:(c)2004MikeWetherell//Licence:wxWindowslicence///////////////////////////////////////////////////////////////////////////////</span><spanclass="lines">@@-1177,7+1177,7@@</span><spanclass="cx">stringTestId::MakeId(){m_seed=(m_seed*171)%30269;</span><spanclass="rem">-returnwxString::Format(_T(&quot;%-6d&quot;),m_seed).mb_str();</span><spanclass="add">+return(constchar*)wxString::Format(_T(&quot;%-6d&quot;),m_seed).mb_str();</span><spanclass="cx">}</span></pre></div></div></body></html>.org%3e"title="Previousbydate"> |
Mon, 11 Apr, 05:03 |
| safoundation.org |
add">+ self._setTimedPassword(self._password, prefs.timeout * 60)
</span><span class="cx"> return self._password
# Otherwise, let's ask the user...
</span><span class="lines">@@ -134,7 +142,7 @@
</span><span class="cx"> again = False
for item in password.Password.iterItems(view):
try:
</span><span class="rem">- item.decryptPassword(masterPassword=pword) # safe: using master password
</span><span class="add">+ waitForDeferred(item.decryptPassword(masterPassword=pword))
</span><span class="cx"> break
except password.UninitializedPassword:
continue
</span><span class="lines">@@ -156,30 +164,26 @@
</span><span class="cx"> self._setTimedPassword(pword, timeout * 60)
return self._password
</span><span class="add">+ @runInUIThread
</span><span class="cx"> def clearMasterPassword(self):
"""
Clear the master password.
"""
if hasattr(self, '_password'):
</span><span class="rem">- self.timer.cancel() # XXX this can hang on exit
</span><span class="add">+ self.timer.cancel()
</span><span class="cx"> del self._password
</span><span class="rem">- del self.timer
-
</span><span class="add">+ del self.timer
+
+ def _clear(self):
+ d = self.clearMasterPassword()
+ d.addCallback(lambda: True)
+
</span><span class="cx"> def _setTimedPassword(self, password, timeout):
</span><span class="add">+ if hasattr(self, 'timer'):
+ self.timer.cancel()
</span><span class="cx"> self._password = password
</span><span class="rem">- self.timer = threading.Timer(timeout, self.clearMasterPassword)
-
- # XXX Other threads can exit without waiting for this; seems to solve shutdown hang.
- # XXX However, this leads to a shutdown crash about 50% of the time (for some reason still successful exit value):
- #Exception in thread Thread-1 (most likely raised during interpreter shutdown):
- #Traceback (most recent call last):
- # File ".../release/lib/python2.5/threading.py", line 460, in __bootstrap
- # File ".../release/lib/python2.5/threading.py", line 623, in run
- # File ".../release/lib/python2.5/threading.py", line 364, in wait
- # File ".../release/lib/python2.5/threading.py", line 229, in wait
- #<type 'exceptions.TypeError'>: 'NoneType' object is not callable
- self.timer.setDaemon(True)
-
</span><span class="add">+ self.timer = threading.Timer(timeout, self._clear)
+ #self.timer.setDaemon(True) # Exception in thread Thread-1 (most likely raised during interpreter shutdown)
</span><span class="cx"> self.timer.start()
def _change(self, oldMaster, newMaster, view, prefs):
</span><span class="lines">@@ -188,14 +192,14 @@
</span><span class="cx"> again = False
for item in password.Password.iterItems(view):
try:
</span><span class="rem">- oldPassword = item.decryptPassword(masterPassword=oldMaster) # safe: supplying master password
</span><span class="add">+ oldPassword = waitForDeferred(item.decryptPassword(masterPassword=oldMaster))
</span><span class="cx"> except password.UninitializedPassword:
continue
except password.DecryptionError:
log.exception('Wrong old master password?')
again = True
break
</span><span class="rem">- item.encryptPassword(oldPassword, masterPassword=newMaster) # safe: supplying master password
</span><span class="add">+ waitForDeferred(item.encryptPassword(oldPassword, masterPassword=newMaster))
</span><span class="cx">
if again:
return False
</span><span class="lines">@@ -212,6 +216,7 @@
</span><span class="cx">
return True
</span><span class="add">+ @runInUIThread
</span><span class="cx"> def changeMasterPassword(self, view, window=None):
</sp """
Change or set the master password.
</span><span class="lines">@@ -516,7 +521,7 @@
</span><span class="cx"> # clear all passwords
from osaf.framework import password
for item in password.Password.iterItems(view):
</span><span class="rem">- item.clear()
</span><span class="add">+ waitForDeferred(item.clear())
</span><span class="cx">
# Turn off pref
prefs = schema.ns("osaf.framework.MasterPassword",
</span><span class="lines">@@ -528,7 +533,7 @@
</span><span class="cx"> view).passwordPrefs
password = ''.join([string.printable[ord(c) % len(string.printable)] \
for c in os.urandom(16)])
</span><span class="rem">- prefs.dummyPassword.encryptPassword(password, masterPassword='') # safe: supplying master password
</span><span class="add">+ waitForDeferred(prefs.dummyPassword.encryptPassword(password, masterPassword=''))
</span><span class="cx"> except:
try:
log.exception('Failed to reset master password')
</span></pre></div>
<a id="branchespasswordparcelsosafframeworkpasswordpy"></a>
<div class="modfile"><h4>Modified: branches/password/parcels/osaf/framework/password.py (13511 => 13512)</h4>
<pre class="diff">
<span class="info">--- branches/password/parcels/osaf/framework/password.py 2007-03-16 20:39:21 UTC (rev 13511)
+++ branches/password/parcels/osaf/framework/password.py 2007-03-16 22:05:38 UTC (rev 13512)
</span><span class="lines">@@ -21,12 +21,24 @@
</span><span class="cx"> 'Password',
]
</span><span class="add">+# discussion with pje, Grant about threads:
+#http://wiki.osafoundation.org/script/getIrcTranscript.cgi?channel=chandler&startTime=1057&endTime=1157&date=20070315
+# TODO: callers of Password methods must deal with deferreds
+
</span><span class="cx"> # XXX share (all done?), imap, pop, smtp accounts
</span><span class="rem">-# XXX when MasterPassword imported/used, chandler does not always quit; unit tests don't quit
-# XXX asking for master password from background thread will probably break
-# XXX - maybe ensure we have master password before bg thread starts, disable master timeout until bg thread finishes
-# XXX - another option might be to ensure no acc |