Kiln » TortoiseHg » TortoiseHg
Clone URL:  
Pushed to one repository · View In Graph Contained in 1.9.2, 1.9.3, and 2.0

sync: add a method for querying and storing host fingerprints

Changeset c32aa44bcf96

Parent 2a633edea4b7

by Steve Borho

Changes to one file · Browse files at c32aa44bcf96 Showing diff from parent 2a633edea4b7 Diff from another changeset...

 
10
11
12
 
13
14
15
 
944
945
946
 
 
 
 
947
948
949
 
 
950
 
951
952
953
 
979
980
981
982
983
984
 
985
986
987
988
989
990
 
991
992
993
994
995
996
997
998
999
1000
 
1001
1002
1003
1004
1005
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1006
1007
1008
 
1012
1013
1014
1015
1016
1017
1018
1019
1020
 
1022
1023
1024
1025
1026
1027
1028
1029
 
1030
1031
1032
 
1047
1048
1049
1050
1051
 
 
 
 
1052
1053
1054
 
1059
1060
1061
 
 
 
 
1062
1063
1064
 
10
11
12
13
14
15
16
 
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
 
987
988
989
 
990
 
991
992
993
994
995
996
 
997
998
999
1000
1001
1002
 
 
 
 
 
1003
1004
1005
1006
1007
 
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
 
1037
1038
1039
 
 
 
1040
1041
1042
 
1044
1045
1046
 
 
 
 
 
1047
1048
1049
1050
 
1065
1066
1067
 
 
1068
1069
1070
1071
1072
1073
1074
 
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
@@ -10,6 +10,7 @@
 import re  import tempfile  import urlparse +import ssl    from PyQt4.QtCore import *  from PyQt4.QtGui import * @@ -944,10 +945,17 @@
 class AuthDialog(QDialog):   def __init__(self, repo, host, user, pw, parent):   super(AuthDialog, self).__init__(parent) + uhost = hglib.tounicode(host) + self.setWindowTitle(_('Authentication: ') + uhost) + self.setWindowFlags(self.windowFlags() & \ + ~Qt.WindowContextHelpButtonHint)   self.repo = repo   self.setLayout(QVBoxLayout())   + authbox = QGroupBox(_('User Authentication')) + self.layout().addWidget(authbox)   form = QFormLayout() + authbox.setLayout(form)   self.aliasentry = QLineEdit(host.split('.', 1)[0])   form.addRow(_('Site Alias'), self.aliasentry)   @@ -979,30 +987,47 @@
 site requires basic or digest authentication, the user will be prompted for  it.'''))   form.addRow(_('Password'), self.pwentry) - self.layout().addLayout(form)   - self.keyentry = QLineEdit(user) + self.keyentry = QLineEdit()   self.keyentry.setToolTip(  _('''Optional. PEM encoded client certificate key file. Environment variables  are expanded in the filename.'''))   form.addRow(_('User Certificate Key File'), self.keyentry)   - self.chainentry = QLineEdit(user) + self.chainentry = QLineEdit()   self.chainentry.setToolTip(  _('''Optional. PEM encoded client certificate chain file. Environment variables  are expanded in the filename.'''))   form.addRow(_('User Certificate Chain File'), self.chainentry)   - self.globalcb = QCheckBox(_('Save this configuration globally')) - self.globalcb.setChecked(True) - self.layout().addWidget(self.globalcb) - - txt = _('Auth section %smanual page%s') % ( + txt = _('Authentication section %smanual page%s') % (   '<a href="http://www.selenic.com/mercurial/hgrc.5.html#auth">',   '</a>')   self.lbl = QLabel(txt)   self.lbl.setOpenExternalLinks(True) - self.layout().addWidget(self.lbl) + form.addRow(self.lbl, None) + + def genfingerprint(): + pem = ssl.get_server_certificate( (host, 443) ) + der = ssl.PEM_cert_to_DER_cert(pem) + hash = util.sha1(der).hexdigest() + pretty = ":".join([hash[x:x + 2] for x in xrange(0, len(hash), 2)]) + le.setText(pretty) + + hostbox = QGroupBox(_('%s host certificate fingerprint') % uhost) + self.layout().addWidget(hostbox) + hbox = QHBoxLayout() + hostbox.setLayout(hbox) + self.host = host + cur = self.repo.ui.config('hostfingerprints', host, '') + self.fingerprintentry = le = QLineEdit(cur) + if hasattr(le, 'setPlaceholderText'): # Qt >= 4.7 + le.setPlaceholderText('### host certificate fingerprint ###') + hbox.addWidget(le) + qb = QPushButton(_('Query')) + qb.clicked.connect(genfingerprint) + hbox.addWidget(qb) +     BB = QDialogButtonBox   bb = QDialogButtonBox(BB.Help|BB.Save|BB.Cancel) @@ -1012,9 +1037,6 @@
  self.bb = bb   self.layout().addWidget(bb)   - self.setWindowTitle(_('Authentication: ') + host) - self.setWindowFlags(self.windowFlags() & \ - ~Qt.WindowContextHelpButtonHint)   self.userentry.selectAll()   QTimer.singleShot(0, lambda:self.userentry.setFocus())   @@ -1022,11 +1044,7 @@
  pass     def accept(self): - if self.globalcb: - path = util.user_rcpath() - else: - path = [self.repo.join('hgrc')] - + path = util.user_rcpath()   fn, cfg = loadIniFile(path, self)   if not hasattr(cfg, 'write'):   qtlib.WarningMsgBox(_('Unable to save authentication'), @@ -1047,8 +1065,10 @@
  'exists, replace?') % alias):   return   cfg.set('auth', alias+'.schemes', schemes) - cfg.set('auth', alias+'.username', username) - cfg.set('auth', alias+'.prefix', prefix) + if username: + cfg.set('auth', alias+'.username', username) + if prefix: + cfg.set('auth', alias+'.prefix', prefix)   def setorclear(item, value):   item = '.'.join([alias, item])   if value: @@ -1059,6 +1079,10 @@
  setorclear('key', key)   setorclear('cert', chain)   + fprint = hglib.fromunicode(self.fingerprintentry.text()) + if fprint: + cfg.set('hostfingerprints', self.host, fprint) +   self.repo.incrementBusyCount()   try:   wconfig.writefile(cfg, fn)