コード例 #1
0
ファイル: capabilities.py プロジェクト: KatsuragiCSL/PRET
 def ipp(self, host, lang):
     try:
         # poor man's way to get printer info via IPP
         sys.stdout.write("Checking for IPP support:         ")
         body = (
             "\x01\x01\x00\x0b\x00\x01\xab\x10\x01G\x00\x12attributes-charset\x00\x05utf-8H"
             +
             "\x00\x1battributes-natural-language\x00\x02enE\x00\x0bprinter-uri\x00\x14ipp:"
             +
             "//localhost/ipp/D\x00\x14requested-attributes\x00\x13printer-description\x03"
         ).encode()
         request = urllib.request.Request(
             "http://" + host + ":631/",
             data=body,
             headers={'Content-type': 'application/ipp'})
         response = urllib.request.urlopen(
             request, timeout=self.timeout).read().decode()
         # get name of device
         model = item(re.findall("MDL:(.+?);",
                                 response))  # e.g. MDL:hp LaserJet 4250
         # get language support
         langs = item(re.findall("CMD:(.+?);",
                                 response))  # e.g. CMD:PCL,PJL,POSTSCRIPT
         self.support = [
             _f for _f in
             [re.findall(re.escape(pdl), langs, re.I) for pdl in lang] if _f
         ]
         self.set_support(model)
         output().green("found")
     except Exception as e:
         output().errmsg("not found", e)
コード例 #2
0
 def do_hold(self, arg):
   "Enable job retention."
   self.chitchat("Setting job retention, reconnecting to see if still enabled")
   self.do_set('HOLD=ON', False)
   self.do_reconnect()
   self.logger.raw("Retention for future print jobs: ", '')
   hold = self.do_info('variables', '^HOLD', False)
   self.logger.info(item(re.findall("=(.*)\s+\[", item(item(hold)))) or 'NOT AVAILABLE')
コード例 #3
0
ファイル: printer.py プロジェクト: xiju2003/PRET
 def do_print(self, arg):
     'Print image file or raw text:  print <file>|"text"'
     '''
 ┌──────────────────────────────────────────────────────────┐
 │ Poor man's driverless PCL based printing (experimental)  │
 ├──────────────────────────────────────────────────────────┤
 │ Warning: ImageMagick and Ghostscript are used to convert │
 │ the document to be printed into a language understood be │
 │ the printer. Don't print anything from untrusted sources │
 │ as it may be a security risk (CVE-2016–3714, 2016-7976). │
 └──────────────────────────────────────────────────────────┘
 '''
     if not arg: arg = raw_input('File or "text": ')
     if arg.startswith('"'): data = arg.strip('"')  # raw text string
     elif arg.endswith('.ps'): data = file().read(arg)  # postscript file
     else:  # anything else…
         try:
             self.chitchat("Converting '" + arg + "' to PCL")
             pdf = ['-density', '300'] if arg.endswith('.pdf') else []
             cmd = ['convert'
                    ] + pdf + [arg, '-quality', '100', 'pcl' + ':-']
             out, err = subprocess.PIPE, subprocess.PIPE
             p = subprocess.Popen(cmd, stdout=out, stderr=err)
             data, stderr = p.communicate()
         except:
             stderr = "ImageMagick or Ghostscript missing"
         if stderr:
             output().errmsg("Cannot convert", item(stderr.splitlines()))
     if data:
         self.send(c.UEL + data + c.UEL)  # send pcl datastream to printer
コード例 #4
0
 def snmp(self, host, lang):
   try:
     sys.stdout.write("Checking for SNMP support:        ")
     # query device description and supported languages
     desc, desc_oid = [], '1.3.6.1.2.1.25.3.2.1.3'    # HOST-RESOURCES-MIB → hrDeviceDescr
     pdls, pdls_oid = [], '1.3.6.1.2.1.43.15.1.1.5.1' # Printer-MIB → prtInterpreterDescription
     error, error_status, idx, binds = cmdgen.CommandGenerator().nextCmd(
       cmdgen.CommunityData('public', mpModel=0), cmdgen.UdpTransportTarget(
         (host, 161), timeout=self.timeout, retries=0), desc_oid, pdls_oid)
     # exit on error
     if error: raise Exception(error)
     if error_status: raise Exception(error_status.prettyPrint())
     # parse response
     for row in binds:
       for key, val in row:
         if desc_oid in str(key): desc.append(str(val))
         if pdls_oid in str(key): pdls.append(str(val))
     # get name of device
     model = item(desc)
     # get language support
     langs = ','.join(pdls)
     self.support = filter(None, [re.findall(re.escape(pdl), langs, re.I) for pdl in lang])
     self.set_support(model)
     output().green("found")
   except NameError:
     output().errmsg("not found", "pysnmp module not installed")
   except Exception as e:
     output().errmsg("not found", str(e))
コード例 #5
0
  def cmd(self, str_send, wait=True, crop=True, binary=False):
    str_recv = "" # response buffer
    str_stat = "" # status buffer
    token = c.DELIMITER + str(random.randrange(2**16)) # unique delimiter
    status = '@PJL INFO STATUS' + c.EOL if self.status and wait else ''
    footer = '@PJL ECHO ' + token + c.EOL + c.EOL if wait else ''
    # send command to printer device
    try:
      cmd_send = c.UEL + str_send + c.EOL + status + footer + c.UEL
      # write to logfile
      
      #self.logger.write(os.linesep + "%%%%%%%%%%%%%%%%%%%%%%%%%% Sending Payload %%%%%%%%%%%%%%%%%%%%%%%%%%" + os.linesep)
      #self.logger.write("%%% Timestamp: " + time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime()) + os.linesep)
      #self.logger.write(os.linesep + str_send + os.linesep)
      #self.logger.write("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%" + os.linesep + os.linesep)
      
      # sent to printer
      self.send(cmd_send)
      # for commands that expect a response
      if wait:
        # use random token as delimiter PJL responses
        str_recv = self.recv('(@PJL ECHO\s+)?' + token + '.*$', wait, True, binary)
        if self.status:
          # get status messages and remove them from received buffer
          str_stat = item(re.findall("@PJL INFO STATUS.*", str_recv, re.DOTALL))
          str_recv = re.compile('\x0c?@PJL INFO STATUS.*', re.DOTALL).sub('', str_recv)
        if crop:
          # crop very first PJL line which is echoed by most interpreters
          str_recv = re.sub(r'^\x04?(\x00+)?@PJL.*' + c.EOL, '', str_recv)
      return self.pjl_err(str_recv, str_stat)

    # handle CTRL+C and exceptions
    except (KeyboardInterrupt, Exception) as e:
      if not self.fuzz or not str(e): self.reconnect(str(e))
      return ""
コード例 #6
0
ファイル: pcl.py プロジェクト: xfox64x/PRET
 def idlist(self):
   list = []
   str_send = '*s4T'          # set location type (downloaded)
   str_send += c.ESC + '*s0U' # set location unit (all units)
   str_send += c.ESC + '*s1I' # set inquire entity (macros)
   str_recv = self.cmd(str_send)
   idlist = re.findall('IDLIST="(.*),?"', str_recv) ### maybe this can
   for id in item(idlist).split(","):               ### be packed into
     if id.startswith('1'): list.append(int(id))    ### a single regex
   return list
コード例 #7
0
 def http(self, host):
   try:
     # poor man's way get http title
     sys.stdout.write("Checking for HTTP support:        ")
     html = urllib2.urlopen("http://" + host, timeout=self.timeout).read()
     # cause we are to parsimonious to import BeautifulSoup ;)
     title = re.findall("<title.*?>\n?(.+?)\n?</title>", html, re.I|re.M|re.S)
     # get name of device
     model = item(title)
     # get language support
     self.set_support(model)
     output().green("found")
   except Exception as e:
     output().errmsg("not found", str(e))
コード例 #8
0
ファイル: pcl.py プロジェクト: xfox64x/PRET
 def put(self, path, data):
   path = self.basename(path)
   pclfs = self.dirlist()
   # re-use macro id if file name already present
   if path in pclfs: id = pclfs[path][0]
   # find free macro id not already reserved for file
   else: id = str(item(set(c.BLOCKRANGE).difference(self.idlist())))
   # abort if we have used up the whole macro id space
   if not id: return self.logger.warning("Out of macro slots.")
   self.chitchat("Using macro id #" + id)
   # retrieve and update superblock
   size = str(len(data))
   date = str(conv().now())
   pclfs[path] = [id, size, date]
   self.update_superblock(pclfs)
   # save data as pcl macro on printer
   self.define_macro(id, data)
コード例 #9
0
 def showstatus(self, str_stat):
   codes = {}; messages = {}
   # get status codes
   for (num, code) in re.findall('CODE(\d+)?\s*=\s*(\d+)', str_stat):
     codes[num] = code
   # get status messages
   for (num, mstr) in re.findall('DISPLAY(\d+)?\s*=\s*"(.*)"', str_stat):
     messages[num] = mstr
   # show codes and messages
   for num, code in codes.items():
     message = messages[num] if num in messages else "UNKNOWN STATUS"
     # workaround for hp printers with wrong range
     if code.startswith("32"):
       code = str(int(code) - 2000)
     # show status from display and codebook
     error = item(codebook().get_errors(code), 'Unknown status')
     self.logger.errmsg("CODE " + code + ": " + message, error)
コード例 #10
0
 def file_exists(self, path):
   str_recv = self.cmd('@PJL FSQUERY NAME="' + path + '"', True, False)
   size = re.findall("TYPE\s*=\s*FILE\s+SIZE\s*=\s*(\d*)", str_recv)
   # return file size
   return conv().int(item(size, c.NONEXISTENT))