- Started new way of logging, with configurable level for each subsystem
- Added -q, --quiet (speaks for itself) - Added -l, --loglevel subsystem=LEVEL,subsystem2=LEVEL2,... - Quell winsock 10035 error. (Equivalent of EINPROGRESS, but winsock likes to have its own error numbers.) - Hide SSL certificate debug stuff unless gajim.c.x.transports loglevel is DEBUG or lower - Avoid unicode problems if we set a profile - Move fingerprint checks from _register_handlers to _connect_success - Some enhancements to fpr checking code
This commit is contained in:
parent
44674f7e75
commit
9deb76a8ad
|
@ -104,6 +104,10 @@ def init():
|
||||||
gajimpaths = init()
|
gajimpaths = init()
|
||||||
|
|
||||||
def init_profile(profile, paths=gajimpaths):
|
def init_profile(profile, paths=gajimpaths):
|
||||||
|
# no unicode
|
||||||
|
if isinstance(profile, unicode):
|
||||||
|
profile = profile.encode(sys.getfilesystemencoding())
|
||||||
|
|
||||||
conffile = windowsify('config')
|
conffile = windowsify('config')
|
||||||
pidfile = windowsify('gajim')
|
pidfile = windowsify('gajim')
|
||||||
|
|
||||||
|
|
|
@ -43,14 +43,7 @@ USE_GPG = GnuPG.USE_GPG
|
||||||
from common.rst_xhtml_generator import create_xhtml
|
from common.rst_xhtml_generator import create_xhtml
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
h = logging.StreamHandler()
|
log = logging.getLogger('gajim.c.connection')
|
||||||
f = logging.Formatter('%(asctime)s %(name)s: %(levelname)s: %(message)s')
|
|
||||||
h.setFormatter(f)
|
|
||||||
log = logging.getLogger('Gajim.connection')
|
|
||||||
log.addHandler(h)
|
|
||||||
log.setLevel(logging.DEBUG)
|
|
||||||
log.propagate = False
|
|
||||||
del h, f
|
|
||||||
|
|
||||||
import gtkgui_helpers
|
import gtkgui_helpers
|
||||||
|
|
||||||
|
@ -120,7 +113,7 @@ class Connection(ConnectionHandlers):
|
||||||
# Do not try to reco while we are already trying
|
# Do not try to reco while we are already trying
|
||||||
self.time_to_reconnect = None
|
self.time_to_reconnect = None
|
||||||
if self.connected < 2: #connection failed
|
if self.connected < 2: #connection failed
|
||||||
gajim.log.debug('reconnect')
|
log.debug('reconnect')
|
||||||
self.connected = 1
|
self.connected = 1
|
||||||
self.dispatch('STATUS', 'connecting')
|
self.dispatch('STATUS', 'connecting')
|
||||||
self.retrycount += 1
|
self.retrycount += 1
|
||||||
|
@ -147,7 +140,7 @@ class Connection(ConnectionHandlers):
|
||||||
|
|
||||||
def _disconnectedReconnCB(self):
|
def _disconnectedReconnCB(self):
|
||||||
'''Called when we are disconnected'''
|
'''Called when we are disconnected'''
|
||||||
gajim.log.debug('disconnectedReconnCB')
|
log.debug('disconnectedReconnCB')
|
||||||
if gajim.account_is_connected(self.name):
|
if gajim.account_is_connected(self.name):
|
||||||
# we cannot change our status to offline or connecting
|
# we cannot change our status to offline or connecting
|
||||||
# after we auth to server
|
# after we auth to server
|
||||||
|
@ -168,7 +161,7 @@ class Connection(ConnectionHandlers):
|
||||||
self.last_time_to_reconnect *= 1.5
|
self.last_time_to_reconnect *= 1.5
|
||||||
self.last_time_to_reconnect += randomsource.randint(0, 5)
|
self.last_time_to_reconnect += randomsource.randint(0, 5)
|
||||||
self.time_to_reconnect = int(self.last_time_to_reconnect)
|
self.time_to_reconnect = int(self.last_time_to_reconnect)
|
||||||
gajim.log.info("Reconnect to %s in %ss", self.name, self.time_to_reconnect)
|
log.info("Reconnect to %s in %ss", self.name, self.time_to_reconnect)
|
||||||
gajim.idlequeue.set_alarm(self._reconnect_alarm,
|
gajim.idlequeue.set_alarm(self._reconnect_alarm,
|
||||||
self.time_to_reconnect)
|
self.time_to_reconnect)
|
||||||
elif self.on_connect_failure:
|
elif self.on_connect_failure:
|
||||||
|
@ -393,13 +386,13 @@ class Connection(ConnectionHandlers):
|
||||||
if self.on_connect_success == self._on_new_account:
|
if self.on_connect_success == self._on_new_account:
|
||||||
con.RegisterDisconnectHandler(self._on_new_account)
|
con.RegisterDisconnectHandler(self._on_new_account)
|
||||||
|
|
||||||
gajim.log.info("Connecting to %s: [%s:%d]", self.name, host['host'], host['port'])
|
log.info("Connecting to %s: [%s:%d]", self.name, host['host'], host['port'])
|
||||||
con.connect((host['host'], host['port']), proxy = self._proxy,
|
con.connect((host['host'], host['port']), proxy = self._proxy,
|
||||||
secure = self._secure)
|
secure = self._secure)
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
if not retry and self.retrycount == 0:
|
if not retry and self.retrycount == 0:
|
||||||
gajim.log.error("Out of hosts, giving up connecting to %s", self.name)
|
log.debug("Out of hosts, giving up connecting to %s", self.name)
|
||||||
self.time_to_reconnect = None
|
self.time_to_reconnect = None
|
||||||
if self.on_connect_failure:
|
if self.on_connect_failure:
|
||||||
self.on_connect_failure()
|
self.on_connect_failure()
|
||||||
|
@ -427,21 +420,15 @@ class Connection(ConnectionHandlers):
|
||||||
return
|
return
|
||||||
self.hosts = []
|
self.hosts = []
|
||||||
if not con_type:
|
if not con_type:
|
||||||
gajim.log.debug('Could not connect to %s:%s' % (self._current_host['host'],
|
log.debug('Could not connect to %s:%s' % (self._current_host['host'],
|
||||||
self._current_host['port']))
|
self._current_host['port']))
|
||||||
self.connected_hostname = self._current_host['host']
|
self.connected_hostname = self._current_host['host']
|
||||||
self.on_connect_failure = None
|
self.on_connect_failure = None
|
||||||
con.RegisterDisconnectHandler(self._disconnectedReconnCB)
|
con.RegisterDisconnectHandler(self._disconnectedReconnCB)
|
||||||
gajim.log.debug(_('Connected to server %s:%s with %s') % (self._current_host['host'],
|
log.debug(_('Connected to server %s:%s with %s') % (self._current_host['host'],
|
||||||
self._current_host['port'], con_type))
|
self._current_host['port'], con_type))
|
||||||
self._register_handlers(con, con_type)
|
self._register_handlers(con, con_type)
|
||||||
return True
|
|
||||||
|
|
||||||
def _register_handlers(self, con, con_type):
|
|
||||||
self.peerhost = con.get_peerhost()
|
|
||||||
# notify the gui about con_type
|
|
||||||
self.dispatch('CON_TYPE', con_type)
|
|
||||||
ConnectionHandlers._register_handlers(self, con, con_type)
|
|
||||||
name = gajim.config.get_per('accounts', self.name, 'name')
|
name = gajim.config.get_per('accounts', self.name, 'name')
|
||||||
hostname = gajim.config.get_per('accounts', self.name, 'hostname')
|
hostname = gajim.config.get_per('accounts', self.name, 'hostname')
|
||||||
resource = gajim.config.get_per('accounts', self.name, 'resource')
|
resource = gajim.config.get_per('accounts', self.name, 'resource')
|
||||||
|
@ -463,19 +450,23 @@ class Connection(ConnectionHandlers):
|
||||||
log.debug("sha1: %s", repr(sha1))
|
log.debug("sha1: %s", repr(sha1))
|
||||||
log.debug("md5: %s", repr(md5))
|
log.debug("md5: %s", repr(md5))
|
||||||
|
|
||||||
|
sv = servers.get(hostname)
|
||||||
|
if sv:
|
||||||
for got in (sha1, md5):
|
for got in (sha1, md5):
|
||||||
svent = servers.get(hostname)
|
expected = sv[2]['digest'].get(got.algo)
|
||||||
if not svent: continue
|
|
||||||
expected = svent[2]['digest'].get(got.algo)
|
|
||||||
if expected:
|
if expected:
|
||||||
fpr_good = got == expected
|
fpr_good = (got == expected)
|
||||||
break
|
break
|
||||||
|
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
|
if con_type in ('ssl', 'tls'):
|
||||||
|
log.error(_("Missing fingerprint in SSL connection to %s") + ':', hostname, exc_info=True)
|
||||||
|
# fpr_good = False # FIXME: enable this when sequence is sorted
|
||||||
|
else:
|
||||||
log.debug("Connection to %s doesn't seem to have a fingerprint:", hostname, exc_info=True)
|
log.debug("Connection to %s doesn't seem to have a fingerprint:", hostname, exc_info=True)
|
||||||
|
|
||||||
if fpr_good == False:
|
if fpr_good == False:
|
||||||
log.error("Fingerprint mismatch for %s: Got %s, expected %s", hostname, got, expected)
|
log.error(_("Fingerprint mismatch for %s: Got %s, expected %s"), hostname, got, expected)
|
||||||
self.disconnect(on_purpose = True)
|
self.disconnect(on_purpose = True)
|
||||||
self.dispatch('STATUS', 'offline')
|
self.dispatch('STATUS', 'offline')
|
||||||
self.dispatch('CONNECTION_LOST',
|
self.dispatch('CONNECTION_LOST',
|
||||||
|
@ -490,10 +481,18 @@ class Connection(ConnectionHandlers):
|
||||||
log.warning(_("No fingerprint in database for %s. Connection could be insecure."), hostname)
|
log.warning(_("No fingerprint in database for %s. Connection could be insecure."), hostname)
|
||||||
|
|
||||||
if fpr_good == True:
|
if fpr_good == True:
|
||||||
log.debug("Fingerprint found and matched for %s.", hostname)
|
log.info("Fingerprint found and matched for %s.", hostname)
|
||||||
|
|
||||||
con.auth(name, self.password, resource, 1, self.__on_auth)
|
con.auth(name, self.password, resource, 1, self.__on_auth)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def _register_handlers(self, con, con_type):
|
||||||
|
self.peerhost = con.get_peerhost()
|
||||||
|
# notify the gui about con_type
|
||||||
|
self.dispatch('CON_TYPE', con_type)
|
||||||
|
ConnectionHandlers._register_handlers(self, con, con_type)
|
||||||
|
|
||||||
def __on_auth(self, con, auth):
|
def __on_auth(self, con, auth):
|
||||||
if not con:
|
if not con:
|
||||||
self.disconnect(on_purpose = True)
|
self.disconnect(on_purpose = True)
|
||||||
|
@ -853,14 +852,14 @@ class Connection(ConnectionHandlers):
|
||||||
def ack_subscribed(self, jid):
|
def ack_subscribed(self, jid):
|
||||||
if not self.connection:
|
if not self.connection:
|
||||||
return
|
return
|
||||||
gajim.log.debug('ack\'ing subscription complete for %s' % jid)
|
log.debug('ack\'ing subscription complete for %s' % jid)
|
||||||
p = common.xmpp.Presence(jid, 'subscribe')
|
p = common.xmpp.Presence(jid, 'subscribe')
|
||||||
self.connection.send(p)
|
self.connection.send(p)
|
||||||
|
|
||||||
def ack_unsubscribed(self, jid):
|
def ack_unsubscribed(self, jid):
|
||||||
if not self.connection:
|
if not self.connection:
|
||||||
return
|
return
|
||||||
gajim.log.debug('ack\'ing unsubscription complete for %s' % jid)
|
log.debug('ack\'ing unsubscription complete for %s' % jid)
|
||||||
p = common.xmpp.Presence(jid, 'unsubscribe')
|
p = common.xmpp.Presence(jid, 'unsubscribe')
|
||||||
self.connection.send(p)
|
self.connection.send(p)
|
||||||
|
|
||||||
|
@ -868,7 +867,7 @@ class Connection(ConnectionHandlers):
|
||||||
auto_auth = False, user_nick = ''):
|
auto_auth = False, user_nick = ''):
|
||||||
if not self.connection:
|
if not self.connection:
|
||||||
return
|
return
|
||||||
gajim.log.debug('subscription request for %s' % jid)
|
log.debug('subscription request for %s' % jid)
|
||||||
if auto_auth:
|
if auto_auth:
|
||||||
self.jids_for_auto_auth.append(jid)
|
self.jids_for_auto_auth.append(jid)
|
||||||
# RFC 3921 section 8.2
|
# RFC 3921 section 8.2
|
||||||
|
|
|
@ -30,14 +30,7 @@ import traceback
|
||||||
import thread
|
import thread
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
h = logging.StreamHandler()
|
log = logging.getLogger('gajim.c.x.transports')
|
||||||
f = logging.Formatter('%(asctime)s %(name)s: %(levelname)s: %(message)s')
|
|
||||||
h.setFormatter(f)
|
|
||||||
log = logging.getLogger('Gajim.transports')
|
|
||||||
log.addHandler(h)
|
|
||||||
log.setLevel(logging.DEBUG)
|
|
||||||
log.propagate = False
|
|
||||||
del h, f
|
|
||||||
|
|
||||||
USE_PYOPENSSL = False
|
USE_PYOPENSSL = False
|
||||||
|
|
||||||
|
@ -534,7 +527,8 @@ class NonBlockingTcp(PlugIn, IdleObject):
|
||||||
self._sock.connect(self._server)
|
self._sock.connect(self._server)
|
||||||
except socket.error, e:
|
except socket.error, e:
|
||||||
errnum = e[0]
|
errnum = e[0]
|
||||||
if errnum != errno.EINPROGRESS:
|
# 10035 - winsock equivalent of EINPROGRESS
|
||||||
|
if errnum not in (errno.EINPROGRESS, 10035):
|
||||||
log.error("_do_connect:", exc_info=True)
|
log.error("_do_connect:", exc_info=True)
|
||||||
#traceback.print_exc()
|
#traceback.print_exc()
|
||||||
# in progress, or would block
|
# in progress, or would block
|
||||||
|
@ -747,7 +741,7 @@ class NonBlockingTLS(PlugIn):
|
||||||
tcpsock.serverDigestSHA1 = cert.digest('sha1')
|
tcpsock.serverDigestSHA1 = cert.digest('sha1')
|
||||||
tcpsock.serverDigestMD5 = cert.digest('md5')
|
tcpsock.serverDigestMD5 = cert.digest('md5')
|
||||||
|
|
||||||
# FIXME: remove debug prints
|
if log.getEffectiveLevel() <= logging.DEBUG:
|
||||||
peercert = tcpsock._sslObj.get_peer_certificate()
|
peercert = tcpsock._sslObj.get_peer_certificate()
|
||||||
ciphers = tcpsock._sslObj.get_cipher_list()
|
ciphers = tcpsock._sslObj.get_cipher_list()
|
||||||
|
|
||||||
|
|
94
src/gajim.py
94
src/gajim.py
|
@ -21,8 +21,83 @@ import sys
|
||||||
import os
|
import os
|
||||||
import urllib
|
import urllib
|
||||||
|
|
||||||
|
import logging
|
||||||
|
consoleloghandler = logging.StreamHandler()
|
||||||
|
consoleloghandler.setLevel(logging.WARNING)
|
||||||
|
consoleloghandler.setFormatter(
|
||||||
|
logging.Formatter('%(asctime)s %(name)s: %(levelname)s: %(message)s'))
|
||||||
|
log = logging.getLogger('gajim')
|
||||||
|
log.setLevel(logging.INFO)
|
||||||
|
log.addHandler(consoleloghandler)
|
||||||
|
log.propagate = False
|
||||||
|
log = logging.getLogger('gajim.gajim')
|
||||||
|
|
||||||
|
# create intermediate loggers
|
||||||
|
logging.getLogger('gajim.c')
|
||||||
|
logging.getLogger('gajim.c.x')
|
||||||
|
|
||||||
|
import getopt
|
||||||
from common import i18n
|
from common import i18n
|
||||||
|
|
||||||
|
def parseLogLevel(arg):
|
||||||
|
if arg.isdigit():
|
||||||
|
return int(arg)
|
||||||
|
if arg.isupper():
|
||||||
|
return getattr(logging, arg)
|
||||||
|
raise ValueError(_("%s is not a valid loglevel"), repr(arg))
|
||||||
|
|
||||||
|
def parseLogTarget(arg):
|
||||||
|
arg = arg.lower()
|
||||||
|
if arg.startswith('.'): return arg[1:]
|
||||||
|
if arg.startswith('gajim'): return arg
|
||||||
|
return 'gajim.' + arg
|
||||||
|
|
||||||
|
def parseAndSetLogLevels(arg):
|
||||||
|
directives = arg.split(',')
|
||||||
|
for directive in directives:
|
||||||
|
directive = directive.strip()
|
||||||
|
target, level = directive.split('=')
|
||||||
|
target = parseLogTarget(target.strip())
|
||||||
|
level = parseLogLevel(level.strip())
|
||||||
|
|
||||||
|
if target == '':
|
||||||
|
consoleloghandler.setLevel(level)
|
||||||
|
print "consoleloghandler level set to %s" % level
|
||||||
|
else:
|
||||||
|
logger = logging.getLogger(target)
|
||||||
|
logger.setLevel(level)
|
||||||
|
print "Logger %s level set to %d" % (target, level)
|
||||||
|
|
||||||
|
def parseOpts():
|
||||||
|
profile = ''
|
||||||
|
verbose = False
|
||||||
|
|
||||||
|
try:
|
||||||
|
shortargs = 'hqvl:p:'
|
||||||
|
longargs = 'help quiet verbose loglevel= profile='
|
||||||
|
opts, args = getopt.getopt(sys.argv[1:], shortargs, longargs.split())
|
||||||
|
except getopt.error, msg:
|
||||||
|
print msg
|
||||||
|
print 'for help use --help'
|
||||||
|
sys.exit(2)
|
||||||
|
for o, a in opts:
|
||||||
|
if o in ('-h', '--help'):
|
||||||
|
print 'gajim [--help] [--quiet] [--verbose] [--loglevel subsystem=level[,subsystem=level[...]]] [--profile name]'
|
||||||
|
sys.exit()
|
||||||
|
elif o in ('-q', '--quiet'):
|
||||||
|
consoleloghandler.setLevel(logging.CRITICAL)
|
||||||
|
verbose = False
|
||||||
|
elif o in ('-v', '--verbose'):
|
||||||
|
consoleloghandler.setLevel(logging.INFO)
|
||||||
|
verbose = True
|
||||||
|
elif o in ('-p', '--profile'): # gajim --profile name
|
||||||
|
profile = a
|
||||||
|
elif o in ('-l', '--loglevel'):
|
||||||
|
parseAndSetLogLevels(a)
|
||||||
|
return profile, verbose
|
||||||
|
|
||||||
|
profile, verbose = parseOpts()
|
||||||
|
|
||||||
import message_control
|
import message_control
|
||||||
|
|
||||||
from chat_control import ChatControlBase
|
from chat_control import ChatControlBase
|
||||||
|
@ -116,24 +191,7 @@ from common import gajim
|
||||||
from common import helpers
|
from common import helpers
|
||||||
from common import optparser
|
from common import optparser
|
||||||
|
|
||||||
profile = ''
|
if verbose: gajim.verbose = True
|
||||||
try:
|
|
||||||
opts, args = getopt.getopt(sys.argv[1:], 'hvp:', ['help', 'verbose',
|
|
||||||
'profile=', 'sm-config-prefix=', 'sm-client-id='])
|
|
||||||
except getopt.error, msg:
|
|
||||||
print msg
|
|
||||||
print 'for help use --help'
|
|
||||||
sys.exit(2)
|
|
||||||
for o, a in opts:
|
|
||||||
if o in ('-h', '--help'):
|
|
||||||
print 'gajim [--help] [--verbose] [--profile name]'
|
|
||||||
sys.exit()
|
|
||||||
elif o in ('-v', '--verbose'):
|
|
||||||
gajim.verbose = True
|
|
||||||
elif o in ('-p', '--profile'): # gajim --profile name
|
|
||||||
profile = a
|
|
||||||
del opts
|
|
||||||
del args
|
|
||||||
|
|
||||||
import locale
|
import locale
|
||||||
profile = unicode(profile, locale.getpreferredencoding())
|
profile = unicode(profile, locale.getpreferredencoding())
|
||||||
|
|
|
@ -260,27 +260,22 @@ def resize_window(window, w, h):
|
||||||
|
|
||||||
class HashDigest:
|
class HashDigest:
|
||||||
def __init__(self, algo, digest):
|
def __init__(self, algo, digest):
|
||||||
self.algo = self.cleanAlgo(algo)
|
self.algo = self.cleanID(algo)
|
||||||
self.digest = self.cleanDigest(digest)
|
self.digest = self.cleanID(digest)
|
||||||
|
|
||||||
def cleanAlgo(self, algo):
|
def cleanID(self, id):
|
||||||
algo = algo.strip().lower()
|
id = id.strip().lower()
|
||||||
for strip in (' :.-_'): algo = algo.replace(strip, '')
|
for strip in (' :.-_'): id = id.replace(strip, '')
|
||||||
return algo
|
return id
|
||||||
|
|
||||||
def cleanDigest(self, digest):
|
|
||||||
digest = digest.strip().lower()
|
|
||||||
for strip in (' :.'): digest = digest.replace(strip, '')
|
|
||||||
return digest
|
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
sa, sd = self.algo, self.digest
|
sa, sd = self.algo, self.digest
|
||||||
if isinstance(other, self.__class__):
|
if isinstance(other, self.__class__):
|
||||||
oa, od = other.algo, other.digest
|
oa, od = other.algo, other.digest
|
||||||
elif isinstance(other, basestring):
|
elif isinstance(other, basestring):
|
||||||
sa, oa, od = None, None, self.cleanDigest(other)
|
sa, oa, od = None, None, self.cleanID(other)
|
||||||
elif isinstance(other, tuple) and len(other) == 2:
|
elif isinstance(other, tuple) and len(other) == 2:
|
||||||
oa, od = self.cleanAlgo(other[0]), self.cleanDigest(other[1])
|
oa, od = self.cleanID(other[0]), self.cleanID(other[1])
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -318,7 +313,7 @@ class ServersXMLHandler(xml.sax.ContentHandler):
|
||||||
sitem[0] = jid
|
sitem[0] = jid
|
||||||
elif attribute == 'hidden':
|
elif attribute == 'hidden':
|
||||||
hidden = attributes.getValue(attribute)
|
hidden = attributes.getValue(attribute)
|
||||||
if hidden.lower() in ('1', 'yes', 'true'):
|
if hidden.lower() in ('1', 'y', 'yes', 't', 'true', 'on'):
|
||||||
sitem[2]['hidden'] = True
|
sitem[2]['hidden'] = True
|
||||||
self.servers.append(sitem)
|
self.servers.append(sitem)
|
||||||
elif name == 'active':
|
elif name == 'active':
|
||||||
|
@ -329,8 +324,7 @@ class ServersXMLHandler(xml.sax.ContentHandler):
|
||||||
# number to the last jid in the list
|
# number to the last jid in the list
|
||||||
self.servers[-1][1] = port
|
self.servers[-1][1] = port
|
||||||
elif name == 'digest':
|
elif name == 'digest':
|
||||||
algo=None
|
algo, digest = None, None
|
||||||
digest=None
|
|
||||||
for attribute in attributes.getNames():
|
for attribute in attributes.getNames():
|
||||||
if attribute == 'algo':
|
if attribute == 'algo':
|
||||||
algo = attributes.getValue(attribute)
|
algo = attributes.getValue(attribute)
|
||||||
|
|
Loading…
Reference in New Issue