예제 #1
0
    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))
예제 #2
0
    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
예제 #3
0
    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