def create_subscriber_info(payload_: asn1.SkrAbonentInfo): oid = payload_['id'] if oid == asn1.sorm_report_abonent_person: item, rest = ber_decode(payload_['data'], asn1.SkrAbonentPerson()) return PersonInfo.create(item) if oid == asn1.sorm_report_abonent_organization: item, rest = ber_decode(payload_['data'], asn1.SkrAbonentOrganization()) return OrganizationInfo.create(item) raise exceptions.GeneralFault( f'unable to create subscriber info by the "{str(oid)}" OID')
def create(payload_): item, rest = ber_decode(payload_, asn1.SkrReportedVoipIdentifier()) ip_bytes = tools.get_optional_bytes(item['ip-address']) return ReportedVoipIdentifier( network.IPAddress(ip_bytes) if ip_bytes is not None else None, tools.get_optional_str(item['originator-name']), tools.get_optional_str(item['calling-number']))
def encode_decode(lm): """Simulate transmission over the network""" raw = ber_encode(lm) response, raw = ber_decode(raw, asn1Spec=rfc4511.LDAPMessage()) if raw: raise Exception('Unexpected leftover bits') return response
def read_sent(self): """Read the first sent message in the queue""" lm, raw = ber_decode(self._incoming_queue.popleft(), asn1Spec=rfc4511.LDAPMessage()) if raw: raise Exception('unexpected leftover bits') return lm
def create(payload_): item, rest = ber_decode(payload_, asn1.SkrReportedCdmaIdentifier()) return ReportedCdmaIdentifier(str(item['directory-number']), str(item['imsi']), tools.get_optional_str(item['esn']), tools.get_optional_str(item['min']), tools.get_optional_str(item['icc']))
def handle(self, ctrl_value): real_ctrl_value, raw = ber_decode(ctrl_value, asn1Spec=RealSearchControlValue()) if raw: raise LDAPError( 'Unexpected leftover bits in response control value') cookie = get_string_component(real_ctrl_value, 'cookie') return cookie
def create_typed_message(raw_message_): payload_id = str(raw_message_['id']) descriptor = message_descriptors.get(payload_id, None) if descriptor is None: raise exceptions.GeneralFault( 'unable to recognize message with id: "{payload_id}"') payload, rest = ber_decode(raw_message_['data'], descriptor.descriptor_reference()) return descriptor.creator(raw_message_, payload)
def data_received(self, data): self._buffer += data try: message, self._buffer = ber_decode(self._buffer) except SubstrateUnderrunError: pass else: message_id = int(message[0]) self._pending_messages[message_id].set_result(message[1]) del self._pending_messages[message_id]
def create(raw_message_, message_payload_, report_payload_): sequence_of, rest = ber_decode(bytes(report_payload_), asn1.SkrReportServiceData()) records = tools.sequence_of_to_list(sequence_of, Service.create) return ServiceReport( raw_message_['version'], raw_message_['message-id'], raw_message_['message-time'], tools.get_optional_str(raw_message_['operator-name']), raw_message_['id'], int(message_payload_['request-id']), int(message_payload_['task-id']), int(message_payload_['total-blocks-number']), int(message_payload_['block-number']), records)
def parse_ed_pubkey(public_key): try: public_key, _ = ber_decode(public_key, asn1Spec=EdPublicKey()) except Exception: raise ParseError("Not a BER encoded Edwards curve public key") if not public_key["key_info"]["key_type"] == univ.ObjectIdentifier("1.3.101.112"): raise ParseError("Not a BER encoded Edwards curve public key") public_key = bytes(public_key["public_key"].asOctets()) return public_key
def recv_messages(self, want_message_id): while self._outgoing_queue: raw = self._outgoing_queue.popleft() lm, raw = ber_decode(raw, asn1Spec=rfc4511.LDAPMessage()) if raw: raise Exception('Unexpected leftover bits') have_message_id = lm.getComponentByName('messageID') if have_message_id != want_message_id: raise Exception( 'Unexpected message ID in mock queue (have={0} want={1})'. format(have_message_id, want_message_id)) yield lm raise Exception('No messages in mock queue')
def create(payload_): item, rest = ber_decode(payload_, asn1.SkrReportedDataNetworkIdentifier()) return ReportedDataNetworkIdentifier( tools.get_optional_value(item['user-equipment'], network.DataNetworkEquipment.create), tools.get_optional_str(item['login']), tools.get_optional_ip_address(item['ip-address']), tools.get_optional_str(item['e-mail']), tools.get_optional_str(item['pin']), tools.get_optional_str(item['phone-number']), tools.get_optional_str(item['user-domain']), tools.get_optional_str(item['reserved']), tools.get_optional_value(item['ip-mask'], network.IPMask.create))
async def run(self): """Handle the client's requests forever""" self.log.debug('Started new client') buffer = b'' while True: try: data = await self.reader.read(self.RECV_BUFFER) if not data: self.log.info('Client has exited') return buffer += data while len(buffer) > 0: _request, buffer = ber_decode( buffer, asn1Spec=rfc4511.LDAPMessage()) req = Request(_request) self.log.info( f'Received message_id={req.id} operation={req.operation}' ) if req.operation == 'unbindRequest': self.authenticated_name = None self.log.info('Client has unbound') return elif req.operation == 'abandonRequest': # As of right now I can't fathom a way to actually get abandon to work with asyncio # # Unfortunately RFC4511 specifies that interrupting result entries is the one thing we MUST # do, but it also says clients MUST NOT care if the abandon worked, so ... ? self.log.warning('Received abandon request - ignoring') else: await self._respond_to_request(req) except SubstrateUnderrunError: continue except (PyAsn1Error, DisconnectionProtocolError) as e: self.log.exception('Caught fatal disconnect error', e) xr = ldap_result(rfc4511.ExtendedResponse, 'protocolError', message=str(e)) xr.setComponentByName('responseName', constants.OID_NOTICE_OF_DISCONNECTION) op = protocol_op('extendedResp', xr) lm = pack(0, op) await self.send(lm) return
def parse_ec_pubkey(public_key): try: public_key, _ = ber_decode(public_key, asn1Spec=EcPublicKey()) except Exception: raise ParseError("Not a BER encoded named elliptic curve public key") if not public_key["key_info"]["key_type"] == univ.ObjectIdentifier( "1.2.840.10045.2.1"): raise ParseError("Not a BER encoded named elliptic curve public key") curve_identifier = public_key["key_info"]["curve_name"] curve_name = get_curve_name_by_identifier(curve_identifier) if curve_name is None: raise NotSupported( "Unsupported named elliptic curve: {}".format(curve_identifier)) try: public_key = bytes(public_key["public_key"].asOctets()) except: raise ParseError("Not a BER encoded named elliptic curve public key") return curve_name, public_key
def wait_for_message(self): def append_data(data_): self.undecoded_data = self.undecoded_data + data_ raw_message = None while True: if self.stop_message_dispatching_event.is_set(): return self.receive_data(append_data) try: raw_message, rest = ber_decode(self.undecoded_data, asn1.SkrMessage()) self.undecoded_data = rest break except asn1_error.SubstrateUnderrunError: continue message = base.create_typed_message(raw_message) self.lg.diagnostic( f'The {message.__class__.__name__} message has been received ' + f'on the channel {self.get_full_name()} ...') self.lg.debug(f'The message body: {message}') return message
def recv_messages(self, want_message_id): """Iterate all messages with ``want_message_id`` being sent by the server. :param int want_message_id: The desired message ID. :return: An iterator over :class:`.rfc4511.LDAPMessage`. """ flush_queue = True raw = b'' while True: if flush_queue: if want_message_id in self._message_queues: q = self._message_queues[want_message_id] while True: if len(q) == 0: break obj = q.popleft() if len(q) == 0: del self._message_queues[want_message_id] yield obj else: flush_queue = True if want_message_id in self.abandoned_mids: raise StopIteration() try: newraw = self._sock.recv(LDAPSocket.RECV_BUFFER) if self._has_sasl_client(): newraw = self._sasl_client.unwrap(newraw) raw += newraw while len(raw) > 0: response, raw = ber_decode(raw, asn1Spec=LDAPMessage()) have_message_id = response.getComponentByName('messageID') if want_message_id == have_message_id: yield response elif have_message_id == 0: msg = 'Received unsolicited message (default message - should never be seen)' try: mid, xr, ctrls = unpack('extendedResp', response) res_code = xr.getComponentByName('resultCode') xr_oid = six.text_type( xr.getComponentByName('responseName')) if xr_oid == LDAPSocket.OID_DISCONNECTION_NOTICE: mtype = 'Notice of Disconnection' else: mtype = 'Unhandled ({0})'.format(xr_oid) diag = xr.getComponentByName('diagnosticMessage') msg = 'Got unsolicited message: {0}: {1}: {2}'.format( mtype, res_code, diag) if res_code == ResultCode('protocolError'): msg += ( ' (This may indicate an incompatability between laurelin-ldap and your server ' 'distribution)') elif res_code == ResultCode( 'strongerAuthRequired'): # this is a direct quote from RFC 4511 sec 4.4.1 msg += ( ' (The server has detected that an established security association between the' 'client and server has unexpectedly failed or been compromised)' ) except UnexpectedResponseType: msg = 'Unhandled unsolicited message from server' finally: raise LDAPUnsolicitedMessage(response, msg) else: if have_message_id not in self._message_queues: self._message_queues[have_message_id] = deque() self._message_queues[have_message_id].append(response) except SubstrateUnderrunError: flush_queue = False continue
def create(payload_): item, rest = ber_decode(payload_, asn1.SkrReportedPstnIdentifier()) return ReportedPstnIdentifier( str(item['directory-number']), tools.get_optional_str(item['internal-number']))
def recv_messages(self, want_message_id): """Iterate all messages with ``want_message_id`` being sent by the server. :param int want_message_id: The desired message ID. :return: An iterator over :class:`.rfc4511.LDAPMessage`. """ flush_queue = True raw = b'' while True: if flush_queue: if want_message_id in self._message_queues: q = self._message_queues[want_message_id] while True: if len(q) == 0: break obj = q.popleft() if len(q) == 0: del self._message_queues[want_message_id] yield obj else: flush_queue = True if want_message_id in self.abandoned_mids: return try: newraw = self._sock.recv(LDAPSocket.RECV_BUFFER) if self._has_sasl_client(): newraw = self._sasl_client.unwrap(newraw) raw += newraw while len(raw) > 0: response, raw = ber_decode(raw, asn1Spec=LDAPMessage()) have_message_id = response.getComponentByName('messageID') if want_message_id == have_message_id: yield response elif have_message_id == 0: msg = 'Received unsolicited message (default message - should never be seen)' try: mid, xr, ctrls = unpack('extendedResp', response) res_code = xr.getComponentByName('resultCode') xr_oid = six.text_type(xr.getComponentByName('responseName')) if xr_oid == LDAPSocket.OID_DISCONNECTION_NOTICE: mtype = 'Notice of Disconnection' else: mtype = 'Unhandled ({0})'.format(xr_oid) diag = xr.getComponentByName('diagnosticMessage') msg = 'Got unsolicited message: {0}: {1}: {2}'.format(mtype, res_code, diag) if res_code == ResultCode('protocolError'): msg += (' (This may indicate an incompatability between laurelin-ldap and your server ' 'distribution)') elif res_code == ResultCode('strongerAuthRequired'): # this is a direct quote from RFC 4511 sec 4.4.1 msg += (' (The server has detected that an established security association between the' ' client and server has unexpectedly failed or been compromised)') except UnexpectedResponseType: msg = 'Unhandled unsolicited message from server' finally: raise LDAPUnsolicitedMessage(response, msg) else: if have_message_id not in self._message_queues: self._message_queues[have_message_id] = deque() self._message_queues[have_message_id].append(response) except SubstrateUnderrunError: flush_queue = False continue
def handle(self, ctrl_value): real_ctrl_value, raw = ber_decode(ctrl_value, asn1Spec=RealSearchControlValue()) if raw: raise LDAPError('Unexpected leftover bits in response control value') cookie = get_string_component(real_ctrl_value, 'cookie') return cookie