def _tx_string(self, s): """This is only safe if it's guaranteed the card won't send any data during the time of tx of the string !!!""" self._sl.write(s) r = self._sl.read(len(s)) if r != s: # TX and RX are tied, so we must clear the echo raise ProtocolError("Bad echo value (Expected: %s, got %s)" % (b2h(s), b2h(r)))
def getitem(path): if not os.path.exists(path) and not os.path.islink(path): return False name = os.path.basename(path) basepath = os.path.dirname(path) stat = os.lstat(path) mode = stat.st_mode try: uname = pwd.getpwuid(stat.st_uid).pw_name except: uname = '' try: gname = grp.getgrgid(stat.st_gid).gr_name except: gname = '' item = { 'name': name, 'isdir': S_ISDIR(mode), #'ischr': S_ISCHR(mode), #'isblk': S_ISBLK(mode), 'isreg': S_ISREG(mode), #'isfifo': S_ISFIFO(mode), 'islnk': S_ISLNK(mode), #'issock': S_ISSOCK(mode), 'perms': oct(stat.st_mode & 0777), 'uid': stat.st_uid, 'gid': stat.st_gid, 'uname': uname, 'gname': gname, 'size': b2h(stat.st_size), 'atime': ftime(stat.st_atime), 'mtime': ftime(stat.st_mtime), 'ctime': ftime(stat.st_ctime), }
def _parse(self, data, direction, cipher, decomp, buf): if cipher: data = rc4.crypt(data, cipher) if decomp: data = decomp.decompress(data) # Parse packet buf += data packets = [] while buf: data = buf opcode, data = parse_cui(data) length, data = parse_cui(data) if len(data) < length and decomp: log.msg("Not enough data...") break else: data, buf = data[:length], data[length:] assert len( data ) == length, "Real length - %s, expected - %s, data - %s" % ( len(data), length, utils.b2h(data)) self.log_packet(direction, opcode, data) if opcode in PARSE_TABLE: packet = PARSE_TABLE[opcode](data) else: packet = dict(unknown=data) packet['opcode'] = opcode packets.append(packet) return packets, buf
def unblock_chv(self, chv_no, code): self.select_file(['3f00', '7f20', '6f38']) fc = rpad(b2h(code.encode()), 16) if chv_no == 1: chv_no = 0 return self._tp.send_apdu_checksw("a02c00" + ('%02x' % chv_no) + "10" + fc)
def dataReceived(self, data): log.msg("Received data: %s" % utils.b2h(data)) try: self.handler.handle(data, self.is_in) except: log.err() self.closeConnection() return self._out.transport.write(data)
def mounts(self, detectdev=False): mounts = [] with open('/proc/mounts', 'r') as f: for line in f: dev, path, fstype = line.split()[0:3] if fstype in ('ext2', 'ext3', 'ext4', 'xfs', 'jfs', 'reiserfs', 'btrfs', 'simfs'): # simfs: filesystem in OpenVZ if not os.path.isdir(path): continue mounts.append({'dev': dev, 'path': path, 'fstype': fstype}) for mount in mounts: stat = os.statvfs(mount['path']) total = stat.f_blocks * stat.f_bsize free = stat.f_bfree * stat.f_bsize used = (stat.f_blocks - stat.f_bfree) * stat.f_bsize mount['total'] = b2h(total) mount['free'] = b2h(free) mount['used'] = b2h(used) mount['used_rate'] = div_percent(used, total) if detectdev: dev = os.stat(mount['path']).st_dev mount['major'], mount['minor'] = os.major(dev), os.minor(dev) return mounts
def log_packet(self, direction, opcode, data): if not ((self.log_opcodes and opcode not in self.log_opcodes) or (self.skip_opcodes and opcode in self.skip_opcodes)): # Packet will be logged: # if log_opcodes is not set # if log_opcodes is set and opcode present in log_opcodes # if skip_opcodes is not set # if skip_opcodes is set and opcode is not present into skip_opcodes l_time = time.ctime().split()[3] print >> self.out_stream, ' | '.join( (l_time, 'h', direction, '0x%X' % opcode, str(len(data)), utils.b2h(data))) print >> self.out_stream, ' | '.join( (l_time, 'a', direction, '0x%X' % opcode, str(len(data)), data))
def getitem(path): if not os.path.exists(path) and not os.path.islink(path): return False name = os.path.basename(path) basepath = os.path.dirname(path) stat = os.lstat(path) mode = stat.st_mode try: uname = pwd.getpwuid(stat.st_uid).pw_name except: uname = '' try: gname = grp.getgrgid(stat.st_gid).gr_name except: gname = '' item = { 'name': name, 'isdir': S_ISDIR(mode), #'ischr': S_ISCHR(mode), #'isblk': S_ISBLK(mode), 'isreg': S_ISREG(mode), #'isfifo': S_ISFIFO(mode), 'islnk': S_ISLNK(mode), #'issock': S_ISSOCK(mode), 'perms': oct(stat.st_mode & 0777), 'uid': stat.st_uid, 'gid': stat.st_gid, 'uname': uname, 'gname': gname, 'size': b2h(stat.st_size), 'atime': ftime(stat.st_atime), 'mtime': ftime(stat.st_mtime), 'ctime': ftime(stat.st_ctime), } if item['islnk']: linkfile = os.readlink(path) item['linkto'] = linkfile if not linkfile.startswith('/'): linkfile = os.path.abspath(os.path.join(basepath, linkfile)) try: stat = os.stat(linkfile) item['link_isdir'] = S_ISDIR(stat.st_mode) item['link_isreg'] = S_ISREG(stat.st_mode) item['link_broken'] = False except: item['link_broken'] = True return item
def program(self, p): # Go to dir self._scc.select_file(['3f00', '7f4d']) # Home PLMN in PLMN_Sel format hplmn = self._e_plmn(p['mcc'], p['mnc']) # Operator name ( 3f00/7f4d/8f0c ) self._scc.update_record( self._files['name'][0], 2, rpad(b2h(p['name']), 32) + ('%02x' % len(p['name'])) + '01') # ICCID/IMSI/Ki/HPLMN ( 3f00/7f4d/8f0d ) v = '' # inline Ki if self._ki_file is None: v += p['ki'] # ICCID v += '3f00' + '2fe2' + '0a' + self._e_iccid(p['iccid']) # IMSI v += '7f20' + '6f07' + '09' + self._e_imsi(p['imsi']) # Ki if self._ki_file: v += self._ki_file + '10' + p['ki'] # PLMN_Sel v += '6f30' + '18' + rpad(hplmn, 36) self._scc.update_record(self._files['b_ef'][0], 1, rpad(v, self._files['b_ef'][1] * 2)) # SMSP ( 3f00/7f4d/8f0e ) # FIXME # Write PLMN_Sel forcefully as well r = self._scc.select_file(['3f00', '7f20', '6f30']) tl = int(r[-1][4:8], 16) hplmn = self._e_plmn(p['mcc'], p['mnc']) self._scc.update_binary('6f30', hplmn + 'ff' * (tl - 3))
def meminfo(self): # OpenVZ may not have some varirables # so init them first mem_total = mem_free = mem_buffers = mem_cached = swap_total = swap_free = 0 with open('/proc/meminfo', 'r') as f: for line in f: if ':' not in line: continue item, value = line.split(':') value = int(value.split()[0]) * 1024 if item == 'MemTotal': mem_total = value elif item == 'MemFree': mem_free = value elif item == 'Buffers': mem_buffers = value elif item == 'Cached': mem_cached = value elif item == 'SwapTotal': swap_total = value elif item == 'SwapFree': swap_free = value mem_used = mem_total - mem_free swap_used = swap_total - swap_free return { 'mem_total': b2h(mem_total), 'mem_used': b2h(mem_used), 'mem_free': b2h(mem_free), 'mem_buffers': b2h(mem_buffers), 'mem_cached': b2h(mem_cached), 'swap_total': b2h(swap_total), 'swap_used': b2h(swap_used), 'swap_free': b2h(swap_free), 'mem_used_rate': div_percent(mem_used, mem_total), 'mem_free_rate': div_percent(mem_free, mem_total), 'swap_used_rate': div_percent(swap_used, swap_total), 'swap_free_rate': div_percent(swap_free, swap_total), }
def program(self, p): # Home PLMN r = self._scc.select_file(['3f00', '7f20', '6f30']) tl = int(r[-1][4:8], 16) hplmn = self._e_plmn(p['mcc'], p['mnc']) self._scc.update_binary('6f30', hplmn + 'ff' * (tl - 3)) # Get total number of entries and entry size rec_cnt, rec_len = self._get_infos() # Set first entry entry = ( '81' + # 1b Status: Valid & Active rpad(b2h(p['name'][0:14]), 28) + # 14b Entry Name self._e_iccid(p['iccid']) + # 10b ICCID self._e_imsi(p['imsi']) + # 9b IMSI_len + id_type(9) + IMSI p['ki'] + # 16b Ki lpad(p['smsp'], 80) # 40b SMSP (padded with ff if needed) ) self._scc.update_record('000c', 1, entry)
decomp.in_buf = p for exp in (7, 0, 5, 2, 0): real = decomp._get_bits(3) assert real == exp, "%s != %s" % (real, exp) #print "%s - OK" % exp #print decomp._get_bits(1) #print decomp._get_bits(1) if __name__ == "__main__": import cProfile import utils s = '04 1C 00 95 0D C8 00 01 5B 6F 00 1E 08 2F C4 00 5F FC 17 91 1E 23 C0' #s = 'E2 A0' p = ''.join(chr(int(i, 16)) for i in s.split()) #cProfile.run('for i in xrange(10000): test_bitstring(p)') #cProfile.run('for i in xrange(10000): test_get_bits(p)') decomp_gb = MPPCDecoder() d = decomp_gb.decompress(p) print utils.b2h(d) print len(d) == int('1c', 16) + 2 decomp_gen = mppc() d = decomp_gen.send(p) print utils.b2h(d) print len(d) == int('1c', 16) + 2 cProfile.run('for i in xrange(10000): decomp_gen.send(p)') cProfile.run('for i in xrange(10000): decomp_gb.decompress(p)')
def diskinfo(self): """Return a dictionary contain info of all disks and partitions. """ disks = { 'count': 0, 'totalsize': 0, 'partitions': [], 'lvm': { 'partcount': 0, 'unpartition': 0, 'partitions': [] } } # read mount points mounts = Server.mounts(True) # scan for uuid and filesystem of partitions blks = Server.partinfo() # OpenVZ may not have blk info if not blks: return disks for devname, blkinfo in blks.iteritems(): dev = os.stat('/dev/%s' % devname).st_rdev major, minor = os.major(dev), os.minor(dev) blks[devname]['major'] = major blks[devname]['minor'] = minor parts = [] with open('/proc/partitions', 'r') as f: for line in f: fields = line.split() if len(fields) == 0: continue if not fields[0].isdigit(): continue major, minor, blocks, name = fields major, minor, blocks = int(major), int(minor), int(blocks) parts.append({ 'name': name, 'major': major, 'minor': minor, 'blocks': blocks, }) # check if some unmounted partition is busy has_busy_part = False for i, part in enumerate(parts): # check if it appears in blkid list if not blks.has_key(part['name']): # don't check the part with child partition if i+1<len(parts) and parts[i+1]['name'].startswith(part['name']): continue # if dev name doesn't match, check the major and minor of the dev devfound = False for devname, blkinfo in blks.iteritems(): if blkinfo['major'] == part['major'] and blkinfo['minor'] == part['minor']: devfound = True break if devfound: continue # means that it is busy has_busy_part = True break # scan for lvm logical volume lvmlvs = [] lvmlvs_vname = {} if not has_busy_part and os.path.exists('/sbin/lvm'): p = subprocess.Popen(shlex.split('/sbin/lvm lvdisplay'), stdout=subprocess.PIPE, close_fds=True) lvs = p.stdout while True: line = lvs.readline() if not line: break if 'LV Name' in line or 'LV Path' in line: devlink = line.replace('LV Name', '').replace('LV Path', '').strip() if not os.path.exists(devlink): continue dev = os.readlink(devlink) dev = os.path.abspath(os.path.join(os.path.dirname(devlink), dev)) dev = dev.replace('/dev/', '') lvmlvs_vname[dev] = devlink.replace('/dev/', '') lvmlvs.append(dev) p.wait() # scan for the 'on' status swap partition swapptns = [] with open('/proc/swaps', 'r') as f: for line in f: if not line.startswith('/dev/'): continue fields = line.split() swapptns.append(fields[0].replace('/dev/', '')) for part in parts: name = part['name'] major = part['major'] minor = part['minor'] blocks = part['blocks'] # check if the partition is a hardware disk # we treat name with no digit as a hardware disk is_hw = True partcount = 0 unpartition = 0 if len([x for x in name if x.isdigit()]) > 0 or name in lvmlvs: is_hw = False # determine which disk this partition belong to # and calcular the unpartition disk space parent_part = disks parent_part_found = False for i, ptn in enumerate(disks['partitions']): if name.startswith(ptn['name']): parent_part_found = True parent_part = disks['partitions'][i] parent_part['partcount'] += 1 parent_part['unpartition'] -= blocks*1024 break if not is_hw and not parent_part_found: parent_part = disks['lvm'] if blks.has_key(name) and blks[name]['fstype'].startswith('LVM'): is_pv = True else: is_pv = False partition = { 'major': major, 'minor': minor, 'name': name, 'size': b2h(blocks*1024), 'is_hw': is_hw, 'is_pv': is_pv, 'partcount': partcount, } if blks.has_key(name): partition['fstype'] = blks[name]['fstype'] partition['uuid'] = blks[name]['uuid'] if name in lvmlvs: partition['is_lv'] = True partition['vname'] = lvmlvs_vname[name] else: partition['is_lv'] = False for mount in mounts: if mount['major'] == major and mount['minor'] == minor: partition['mount'] = mount['path'] # read filesystem type from blkid #partition['fstype'] = mount['fstype'] break if name in swapptns: partition['fstype'] = 'swap' partition['mount'] = 'swap' if is_hw: partition['partitions'] = [] partition['unpartition'] = blocks*1024 disks['count'] += 1 disks['totalsize'] += blocks*1024 parent_part['partitions'].append(partition) disks['totalsize'] = b2h(disks['totalsize']) disks['lvscount'] = len(lvmlvs) for i, part in enumerate(disks['partitions']): unpartition = part['unpartition'] if unpartition <= 10*1024**2: # ignore size < 10MB unpartition = '0' else: unpartition = b2h(unpartition) disks['partitions'][i]['unpartition'] = unpartition return disks
def verify_chv(self, chv_no, code): self.select_file(['3f00', '7f20']) fc = rpad(b2h(code.encode()), 16) return self._tp.send_apdu_checksw('a02000' + ('%02x' % chv_no) + '08' + fc)
def disable_chv(self, code): fc = rpad(b2h(code.encode()), 16) return self._tp.send_apdu_checksw('a026000108' + fc)
def netifaces(self): netifaces = [] with open('/proc/net/dev', 'r') as f: for line in f: if not ':' in line: continue name, data = line.split(':') name = name.strip() data = data.split() rx = int(data[0]) tx = int(data[8]) netifaces.append({ 'name': name, 'rx': b2h(rx), 'tx': b2h(tx), 'timestamp': int(time.time()), 'rx_bytes': rx, 'tx_bytes': tx, }) with open('/proc/net/route') as f: for line in f: fields = line.strip().split() if fields[1] != '00000000' or not int(fields[3], 16) & 2: continue gw = socket.inet_ntoa(struct.pack('<L', int(fields[2], 16))) for netiface in netifaces: if netiface['name'] == fields[0]: netiface['gw'] = gw break # REF: http://linux.about.com/library/cmd/blcmdl7_netdevice.htm for i, netiface in enumerate(netifaces): guess_iface = False while True: try: ifname = netiface['name'][:15] ifnamepack = struct.pack('256s', ifname) s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sfd = s.fileno() flags, = struct.unpack('H', fcntl.ioctl( sfd, 0x8913, # SIOCGIFFLAGS ifnamepack )[16:18]) netiface['status'] = ('down', 'up')[flags & 0x1] netiface['ip'] = socket.inet_ntoa(fcntl.ioctl( sfd, 0x8915, # SIOCGIFADDR ifnamepack )[20:24]) netiface['bcast'] = socket.inet_ntoa(fcntl.ioctl( sfd, 0x8919, # SIOCGIFBRDADDR ifnamepack )[20:24]) netiface['mask'] = socket.inet_ntoa(fcntl.ioctl( sfd, 0x891b, # SIOCGIFNETMASK ifnamepack )[20:24]) hwinfo = fcntl.ioctl( sfd, 0x8927, # SIOCSIFHWADDR ifnamepack) # REF: networking/interface.c, /usr/include/linux/if.h, /usr/include/linux/if_arp.h encaps = { '\xff\xff': 'UNSPEC', # -1 '\x01\x00': 'Ethernet', # 1 '\x00\x02': 'Point-to-Point Protocol', # 512 '\x04\x03': 'Local Loopback', # 772 '\x08\x03': 'IPv6-in-IPv4', # 776 '\x20\x00': 'InfiniBand', # 32 } hwtype = hwinfo[16:18] netiface['encap'] = encaps[hwtype] netiface['mac'] = ':'.join(['%02X' % ord(char) for char in hwinfo[18:24]]) if not netiface['name'].startswith('venet'): break # detect interface like venet0:0, venet0:1, etc. if not guess_iface: guess_iface = True guess_iface_name = netiface['name'] guess_iface_i = 0 else: netifaces.append(netiface) guest_iface_i += 1 netiface = { 'name': '%s:%d' % (guess_iface_name, guess_iface_i), 'rx': '0B', 'tx': '0B', 'timestamp': 0, 'rx_bytes': 0, 'tx_bytes': 0, } except: #netifaces[i] = None break netifaces = [ iface for iface in netifaces if iface.has_key('mac') ] return netifaces
def enable_chv(self, code): self.select_file(['3f00', '7f20', '6f38']) fc = rpad(b2h(code.encode()), 16) return self._tp.send_apdu_checksw("a028000108" + fc)
def log_packet(self, direction, opcode, data): if not ((self.log_opcodes and opcode not in self.log_opcodes) or (self.skip_opcodes and opcode in self.skip_opcodes)): # Packet will be logged: # if log_opcodes is not set # if log_opcodes is set and opcode present in log_opcodes # if skip_opcodes is not set # if skip_opcodes is set and opcode is not present into skip_opcodes l_time = time.ctime().split()[3] print >> self.out_stream, ' | '.join((l_time, 'h', direction, '0x%X' % opcode, str(len(data)), utils.b2h(data))) print >> self.out_stream, ' | '.join((l_time, 'a', direction, '0x%X' % opcode, str(len(data)), data))
def _parse(self, data, direction, cipher, decomp, buf): if cipher: data = rc4.crypt(data, cipher) if decomp: data = decomp.decompress(data) # Parse packet buf += data packets = [] while buf: data = buf opcode, data = parse_cui(data) length, data = parse_cui(data) if len(data) < length and decomp: log.msg("Not enough data...") break else: data, buf = data[:length], data[length:] assert len(data) == length, "Real length - %s, expected - %s, data - %s" % (len(data), length, utils.b2h(data)) self.log_packet(direction, opcode, data) if opcode in PARSE_TABLE: packet = PARSE_TABLE[opcode](data) else: packet = dict(unknown=data) packet['opcode'] = opcode packets.append(packet) return packets, buf
def change_chv(self, chv_no, curr_pin, new_pin): fc = rpad(b2h(curr_pin.encode()), 16) + rpad(b2h(new_pin.encode()), 16) return self._tp.send_apdu_checksw("a02400" + ('%02x' % chv_no) + "10" + fc)
def send_apdu_raw(self, pdu): """see LinkBase.send_apdu_raw""" self._dbg_print("Command:" + pdu) pdu1 = h2b(pdu) data_len = int(pdu[8:11], 16) # P3 # Send first CLASS,INS,P1,P2,P3 pdu2 = pdu1[0:5] self._tx_string(pdu1[0:5]) # Wait ack which can be # - INS: Command acked -> go ahead # - 0x60: NULL, just wait some more # - SW1: The card can apparently proceed ... while True: b = self._rx_byte() x = pdu[2:4] y = b2h(b) if x == y: break elif b != '\x60': # Ok, it 'could' be SW1 sw1 = b sw2 = self._rx_byte() nil = self._rx_byte() if (sw2 and not nil): return '', b2h(sw1 + sw2) raise ProtocolError() # Send data (if any) if len(pdu) > 5: pdu2 = pdu1[5:] self._tx_string(pdu2) # Receive data (including SW !) # length = [P3 - tx_data (=len(pdu)-len(hdr)) + 2 (SW1/2) ] to_recv = data_len - len(pdu) / 2 + 5 + 4 to_recv = data_len + 2 data = '' while (len(data) / 2 < to_recv + 1): b = self._rx_byte() if (to_recv == 2) and ( b == '\x60'): # Ignore NIL if we have no RX data (hack ?) continue if not b: break data += b2h(b) # Split datafield from SW if len(data) < 4: return None, None sw = data[-4:] data = data[0:-4] self._dbg_print("SW: " + sw) self._dbg_print("Data: " + data) # Return value return data, sw