Spaces:
Runtime error
Runtime error
# Xlib.xauth -- ~/.Xauthority access | |
# | |
# Copyright (C) 2000 Peter Liljenberg <petli@ctrl-c.liu.se> | |
# | |
# This library is free software; you can redistribute it and/or | |
# modify it under the terms of the GNU Lesser General Public License | |
# as published by the Free Software Foundation; either version 2.1 | |
# of the License, or (at your option) any later version. | |
# | |
# This library is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | |
# See the GNU Lesser General Public License for more details. | |
# | |
# You should have received a copy of the GNU Lesser General Public | |
# License along with this library; if not, write to the | |
# Free Software Foundation, Inc., | |
# 59 Temple Place, | |
# Suite 330, | |
# Boston, MA 02111-1307 USA | |
import os | |
import struct | |
from Xlib import X, error | |
FamilyInternet = X.FamilyInternet | |
FamilyDECnet = X.FamilyDECnet | |
FamilyChaos = X.FamilyChaos | |
FamilyServerInterpreted = X.FamilyServerInterpreted | |
FamilyInternetV6 = X.FamilyInternetV6 | |
FamilyLocal = 256 | |
class Xauthority(object): | |
def __init__(self, filename = None): | |
if filename is None: | |
filename = os.environ.get('XAUTHORITY') | |
if filename is None: | |
try: | |
filename = os.path.join(os.environ['HOME'], '.Xauthority') | |
except KeyError: | |
raise error.XauthError( | |
'$HOME not set, cannot find ~/.Xauthority') | |
try: | |
with open(filename, 'rb') as fp: | |
raw = fp.read() | |
except IOError as err: | |
raise error.XauthError('could not read from {0}: {1}'.format(filename, err)) | |
self.entries = [] | |
# entry format (all shorts in big-endian) | |
# short family; | |
# short addrlen; | |
# char addr[addrlen]; | |
# short numlen; | |
# char num[numlen]; | |
# short namelen; | |
# char name[namelen]; | |
# short datalen; | |
# char data[datalen]; | |
n = 0 | |
try: | |
while n < len(raw): | |
family, = struct.unpack('>H', raw[n:n+2]) | |
n = n + 2 | |
length, = struct.unpack('>H', raw[n:n+2]) | |
n = n + length + 2 | |
addr = raw[n - length : n] | |
length, = struct.unpack('>H', raw[n:n+2]) | |
n = n + length + 2 | |
num = raw[n - length : n] | |
length, = struct.unpack('>H', raw[n:n+2]) | |
n = n + length + 2 | |
name = raw[n - length : n] | |
length, = struct.unpack('>H', raw[n:n+2]) | |
n = n + length + 2 | |
data = raw[n - length : n] | |
if len(data) != length: | |
break | |
self.entries.append((family, addr, num, name, data)) | |
except struct.error: | |
print("Xlib.xauth: warning, failed to parse part of xauthority file {0}, aborting all further parsing".format(filename)) | |
if len(self.entries) == 0: | |
print("Xlib.xauth: warning, no xauthority details available") | |
# raise an error? this should get partially caught by the XNoAuthError in get_best_auth.. | |
def __len__(self): | |
return len(self.entries) | |
def __getitem__(self, i): | |
return self.entries[i] | |
def get_best_auth(self, family, address, dispno, | |
types = ( b"MIT-MAGIC-COOKIE-1", )): | |
"""Find an authentication entry matching FAMILY, ADDRESS and | |
DISPNO. | |
The name of the auth scheme must match one of the names in | |
TYPES. If several entries match, the first scheme in TYPES | |
will be choosen. | |
If an entry is found, the tuple (name, data) is returned, | |
otherwise XNoAuthError is raised. | |
""" | |
num = str(dispno).encode() | |
matches = {} | |
for efam, eaddr, enum, ename, edata in self.entries: | |
if enum == b'' and ename not in matches: | |
enum = num | |
if efam == family and eaddr == address and num == enum: | |
matches[ename] = edata | |
for t in types: | |
try: | |
return (t, matches[t]) | |
except KeyError: | |
pass | |
raise error.XNoAuthError((family, address, dispno)) | |