Пример #1
0
	def _write (self, process, string, neighbor=None):
		if string is None:
			return True

		# XXX: FIXME: This is potentially blocking
		while True:
			try:
				self._process[process].stdin.write(bytes_ascii('%s\n' % string))
			except IOError as exc:
				self._broken.append(process)
				if exc.errno == errno.EPIPE:
					self._broken.append(process)
					self.logger.debug('issue while sending data to our helper program','process')
					raise ProcessError()
				else:
					# Could it have been caused by a signal ? What to do.
					self.logger.debug('error received while sending data to helper program, retrying (%s)' % errstr(exc),'process')
					continue
			break

		try:
			self._process[process].stdin.flush()
		except IOError as exc:
			# AFAIK, the buffer should be flushed at the next attempt.
			self.logger.debug('error received while FLUSHING data to helper program, retrying (%s)' % errstr(exc),'process')

		return True
Пример #2
0
    def write(self, process, string, neighbor=None):
        if string is None:
            return True

        # XXX: FIXME: This is potentially blocking
        while True:
            try:
                self._process[process].stdin.write(bytes_ascii('%s\n' %
                                                               string))
            except IOError as exc:
                self._broken.append(process)
                if exc.errno == errno.EPIPE:
                    self._broken.append(process)
                    self.logger.debug(
                        'issue while sending data to our helper program',
                        'process')
                    raise ProcessError()
                else:
                    # Could it have been caused by a signal ? What to do.
                    self.logger.debug(
                        'error received while sending data to helper program, retrying (%s)'
                        % errstr(exc), 'process')
                    continue
            break

        try:
            self._process[process].stdin.flush()
        except IOError as exc:
            # AFAIK, the buffer should be flushed at the next attempt.
            self.logger.debug(
                'error received while FLUSHING data to helper program, retrying (%s)'
                % errstr(exc), 'process')

        return True
Пример #3
0
 def __init__(self, code, subcode, data=None):
     if data is None:
         data = self._str_subcode.get((code, subcode),
                                      'unknown notification type')
     if (code, subcode) in [(6, 2), (6, 4)]:
         data = chr(len(data)) + data
     Notification.__init__(self, code, subcode, bytes_ascii(data), False)
Пример #4
0
	def unpack_message (cls, data, _=None):
		version = ordinal(data[0])
		if version != 4:
			# Only version 4 is supported nowdays..
			raise Notify(2,1,bytes_ascii(data[0]))
		asn = unpack('!H',data[1:3])[0]
		hold_time = unpack('!H',data[3:5])[0]
		numeric = unpack('!L',data[5:9])[0]
		router_id = "%d.%d.%d.%d" % (numeric >> 24,(numeric >> 16) & 0xFF,(numeric >> 8) & 0xFF,numeric & 0xFF)
		return cls(
			Version(version),
			ASN(asn),
			HoldTime(hold_time),
			RouterID(router_id),
			Capabilities.unpack(data[9:])
		)
Пример #5
0
def MD5(io, ip, port, md5, md5_base64):
    platform_os = platform.system()
    if platform_os == 'FreeBSD':
        if md5:
            if md5 != 'kernel':
                raise MD5Error(
                    'FreeBSD requires that you set your MD5 key via ipsec.conf.\n'
                    'Something like:\n'
                    'flush;\n'
                    'add <local ip> <peer ip> tcp 0x1000 -A tcp-md5 "password";'
                )
            try:
                TCP_MD5SIG = 0x10
                io.setsockopt(socket.IPPROTO_TCP, TCP_MD5SIG, 1)
            except socket.error:
                raise MD5Error(
                    'FreeBSD requires that you rebuild your kernel to enable TCP MD5 Signatures:\n'
                    'options         IPSEC\n'
                    'options         TCP_SIGNATURE\n'
                    'device          crypto\n')
    elif platform_os == 'Linux':
        try:
            if md5:
                md5_bytes = None
                if md5_base64 is True:
                    try:
                        md5_bytes = base64.b64decode(md5)
                    except TypeError:
                        raise MD5Error("Failed to decode base 64 encoded PSK")
                elif md5_base64 is None:  # auto
                    options = [md5 + '==', md5 + '=', md5]
                    for md5 in options:
                        try:
                            md5_bytes = base64.b64decode(md5)
                            break
                        except TypeError:
                            pass

            # __kernel_sockaddr_storage
            n_af = IP.toaf(ip)
            n_addr = IP.pton(ip)
            n_port = socket.htons(port)

            # pack 'x' is padding, so we want the struct
            # Do not use '!' for the pack, the network (big) endian switch in
            # struct.pack is fighting against inet_pton and htons (note the n)

            if IP.toafi(ip) == AFI.ipv4:
                # SS_MAXSIZE is 128 but addr_family, port and ipaddr (8 bytes total) are written independently of the padding
                SS_MAXSIZE_PADDING = 128 - calcsize('HH4s')  # 8
                sockaddr = pack('HH4s%dx' % SS_MAXSIZE_PADDING, socket.AF_INET,
                                n_port, n_addr)
            else:
                SS_MAXSIZE_PADDING = 128 - calcsize('HI16sI')  # 28
                SIN6_FLOWINFO = 0
                SIN6_SCOPE_ID = 0
                sockaddr = pack('HHI16sI%dx' % SS_MAXSIZE_PADDING, n_af,
                                n_port, SIN6_FLOWINFO, n_addr, SIN6_SCOPE_ID)

            TCP_MD5SIG_MAXKEYLEN = 80
            if md5:
                if md5_bytes is None:
                    md5_bytes = bytes_ascii(md5)
                    key = pack('2xH4x%ds' % TCP_MD5SIG_MAXKEYLEN,
                               len(md5_bytes), md5_bytes)
                else:
                    key = pack('2xH4x%ds' % TCP_MD5SIG_MAXKEYLEN, 0, b'')

                TCP_MD5SIG = 14
                io.setsockopt(socket.IPPROTO_TCP, TCP_MD5SIG, sockaddr + key)
        except socket.error as exc:
            if exc.errno != errno.ENOENT:
                raise MD5Error(
                    'This linux machine does not support TCP_MD5SIG, you can not use MD5 (%s)'
                    % errstr(exc))
    elif md5:
        raise MD5Error('ExaBGP has no MD5 support for %s' % platform_os)
Пример #6
0
def MD5 (io, ip, port, md5, md5_base64):
	platform_os = platform.system()
	if platform_os == 'FreeBSD':
		if md5:
			if md5 != 'kernel':
				raise MD5Error(
					'FreeBSD requires that you set your MD5 key via ipsec.conf.\n'
					'Something like:\n'
					'flush;\n'
					'add <local ip> <peer ip> tcp 0x1000 -A tcp-md5 "password";'
					)
			try:
				TCP_MD5SIG = 0x10
				io.setsockopt(socket.IPPROTO_TCP, TCP_MD5SIG, 1)
			except socket.error:
				raise MD5Error(
					'FreeBSD requires that you rebuild your kernel to enable TCP MD5 Signatures:\n'
					'options         IPSEC\n'
					'options         TCP_SIGNATURE\n'
					'device          crypto\n'
				)
	elif platform_os == 'Linux':
		try:
			if md5:
				md5_bytes = None
				if md5_base64 is True:
					try:
						md5_bytes = base64.b64decode(md5)
					except TypeError:
						raise MD5Error("Failed to decode base 64 encoded PSK")
				elif md5_base64 is None and not re.match('.*[^a-f0-9].*', md5):  # auto
					options = [md5+'==', md5+'=', md5]
					for md5 in options:
						try:
							md5_bytes = base64.b64decode(md5)
							break
						except TypeError:
							pass

			# __kernel_sockaddr_storage
			n_af   = IP.toaf(ip)
			n_addr = IP.pton(ip)
			n_port = socket.htons(port)

			# pack 'x' is padding, so we want the struct
			# Do not use '!' for the pack, the network (big) endian switch in
			# struct.pack is fighting against inet_pton and htons (note the n)

			if IP.toafi(ip) == AFI.ipv4:
				# SS_MAXSIZE is 128 but addr_family, port and ipaddr (8 bytes total) are written independently of the padding
				SS_MAXSIZE_PADDING = 128 - calcsize('HH4s')  # 8
				sockaddr = pack('HH4s%dx' % SS_MAXSIZE_PADDING, socket.AF_INET, n_port, n_addr)
			else:
				SS_MAXSIZE_PADDING = 128 - calcsize('HI16sI')  # 28
				SIN6_FLOWINFO = 0
				SIN6_SCOPE_ID = 0
				sockaddr = pack('HHI16sI%dx' % SS_MAXSIZE_PADDING, n_af, n_port, SIN6_FLOWINFO, n_addr, SIN6_SCOPE_ID)

			TCP_MD5SIG_MAXKEYLEN = 80
			TCP_MD5SIG = 14

			if md5_bytes:
				key = pack('2xH4x%ds' % TCP_MD5SIG_MAXKEYLEN, len(md5_bytes), md5_bytes)
				io.setsockopt(socket.IPPROTO_TCP, TCP_MD5SIG, sockaddr + key)
			elif md5:
				md5_bytes = bytes_ascii(md5)
				key = pack('2xH4x%ds' % TCP_MD5SIG_MAXKEYLEN, len(md5_bytes), md5_bytes)
				io.setsockopt(socket.IPPROTO_TCP, TCP_MD5SIG, sockaddr + key)
			# else:
			# 	key = pack('2xH4x%ds' % TCP_MD5SIG_MAXKEYLEN, 0, b'')
			# 	io.setsockopt(socket.IPPROTO_TCP, TCP_MD5SIG, sockaddr + key)

		except socket.error as exc:
			if exc.errno != errno.ENOENT:
				raise MD5Error('This linux machine does not support TCP_MD5SIG, you can not use MD5 (%s)' % errstr(exc))
	elif md5:
		raise MD5Error('ExaBGP has no MD5 support for %s' % platform_os)
Пример #7
0
	def __init__ (self, code, subcode, data=None):
		if data is None:
			data = self._str_subcode.get((code,subcode),'unknown notification type')
		if (code, subcode) in [(6, 2), (6, 4)]:
			data = chr(len(data)) + data
		Notification.__init__(self,code,subcode,bytes_ascii(data),False)