def cmd_open(self, args): if len(args) != 4: raise Exception('usage: OPEN cardid username password') if self.cardid >= 0: raise Exception('already connected to card ' + str(self.cardid)) cardid = int(args[1]) allowed = self.server.check_open_access(cardid, self.addr, args[2], args[3], self.salt) if not allowed: log_error('client {0}: OPEN {1} {2} ***** - permission denied'.format( self.addr, args[1], args[2])) self.send('ERROR permission denied\n') return open8055io.open(cardid) cardio = Open8055Reader(self, cardid) cardio.start() self.cardid = cardid self.cardio = cardio # ---- # We send a GETCONFIG message to the card and the reader # is going to suppress INPUT messages until OUTPUT and CONFIG1 # have been reported. # ---- open8055io.write(cardid, struct.pack('B', 0x04))
def cmd_send(self, args): if self.cardid < 0: raise Exception('not connected to a card') # ---- # Get the HID command message format by type # ---- hid_type = int(args[1]) if hid_type == 0x01: # OUTPUT msg_fmt = '!BB8H2HB' num_val = 13 elif hid_type == 0x02: # GETINPUT msg_fmt = '!B' num_val = 1 elif hid_type == 0x03: # SETCONFIG1 msg_fmt = '!B2B5B8B2B5HB' num_val = 24 elif hid_type == 0x04: # GETCONFIG msg_fmt = '!B' num_val = 1 elif hid_type == 0x05: # SAVECONFIG msg_fmt = '!B' num_val = 1 elif hid_type == 0x06: # SAVEALL msg_fmt = '!B' num_val = 1 elif hid_type == 0x7F: # RESET log_info('client {0} sent RESET command'.format(self.addr)) msg_fmt = '!B' num_val = 1 else: raise Exception('invalid HID command type 0x{0:02X}'.format( hid_type)) # ---- # Create a sequence of integers for that format. Add zeroes # for missing members at the end (telnet debugging aid) # ---- vals = [int(x) for x in args[1:]] while len(vals) < num_val: vals.append(0) # ---- # Pack this into the binary message and send it to the card. # ---- data = struct.pack(msg_fmt, *vals) try: open8055io.write(self.cardid, data) except Exception as err: self.set_status(MODE_STOP) try: self.client.send('ERROR from write ' + str(err) + '\n') except: pass
def run(self): # ---- # Send HELLO and SALT messages to new client. # ---- try: self.send('HELLO {0} {1}\n'.format( Open8055Server.SERVERNAME, Open8055Server.VERSION)) self.send('SALT ' + self.salt + '\n') except Exception as err: log_error('client {0}: {1}'.format(str(self.addr), str(err))) self.set_status(MODE_STOPPED) return # ---- # Run until the main server thread tells us to STOP or # the remote disconnects. # ---- while self.get_status() == MODE_RUN: # ---- # See if we still have another command in the input buffer. # ---- idx = self.inbuf.find('\n') if idx < 0: # ---- # No NEWLINE in there, wait for more data. # ---- try: rdy, _dummy, _dummy = select.select( (self.conn,), (), (), 2.0) except Exception as err: log_error('client {0}: {1}'.format( str(self.addr), str(err))) break if self.cardio: if self.cardio.get_status() == MODE_STOPPED: log_error('client {0}: {1}'.format( str(self.addr), 'cardio stopped unexpected')) break # ---- # If rdy is empty then this was just a timeout to check # for STOP flag. # ---- if len(rdy) == 0: continue # ---- # Receive new data # ---- try: data = self.conn.recv(256) except Exception as err: log_error('client {0}: {1}'.format( str(self.addr), str(err))) break # ---- # Check of EOF # ---- if len(data) == 0: break # ---- # Add the data to the input buffer. If there's still # no NEWLINE, wait for more. # ---- self.inbuf += data idx = self.inbuf.find('\n') if idx < 0: continue # ---- # We have a NEWLINE in the input buffer. Consume the # first line. # ---- line = self.inbuf[0:idx] self.inbuf = self.inbuf[idx + 1:] # ---- # Split the command line by spaces and process it. # ---- args = line.strip().split(' ') try: if args[0].upper() == 'SEND': self.cmd_send(args) elif args[0].upper() == 'LIST': self.cmd_list(args) elif args[0].upper() == 'OPEN': self.cmd_open(args) elif args[0].upper() == 'QUIT': self.set_status(MODE_STOP) break else: self.send('ERROR unknown command \'' + args[0].upper() + '\'\n') except Exception as err: log_error('client {0}: {1}'.format(str(self.addr), str(err))) try: self.send('ERROR ' + str(err) + '\n') except: pass # ---- # Stop the reader thread if one exists. # ---- if self.cardio is not None: try: if self.cardio.get_status() != MODE_STOPPED: self.cardio.set_status(MODE_STOP) try: open8055io.write(self.cardid, struct.pack('B', 0x02)) except Exception as err: log_error('client {0}: {1}'.format( str(self.addr), str(err))) self.cardio.join() except Exception as err: log_error('client {0}: {1}'.format(str(self.addr), str(err))) try: self.send('ERROR ' + str(err)) except: pass # ---- # Close the Open8055 # ---- try: if self.cardid >= 0: open8055io.close(self.cardid) except Exception as err: log_error('client {0}: {1}'.format(self.addr, str(err))) # ---- # Close the remote connection. # ---- try: if self.conn is not None: self.conn.shutdown(socket.SHUT_RDWR) self.conn.close() except Exception as err: log_error('client {0}: {1}'.format(self.addr, str(err))) # ---- # Set the run status to STOPPED and end this thread. # ---- self.set_status(MODE_STOPPED) return