At work we use a print solution that consists of two parts:

  • A Konica Minolta bizhub C284e printer
  • An EFI Fiery E100 print server

Each user has his own account on the printer and these credentials are needed for printing. EFI provides drivers for Windows and Mac OS X. As a Linux user, you can grab a Mac OS X PPD file from the vendor and hope that CUPS can deal with it. As long as you do not use any sort of authentication on the print server, the vendor’s PPD file works quite nice.

The Problem

The Fiery driver (on Mac OS X) brings some sort of proprietary CUPS filter that mixes account credentials to the actual document sent to the printer. Without this proprietary filter, one can’t print on such a device. This problem may be solved by sniffing the communication between an authenticated user and the print server and by writing a custom CUPS filter. Download the files described below.

Get hold of an authenticated PostScript document

Either use tcpdump/wireshark or netcat to get hold of an authenticated PostScript document.

nc -l -p 9100 > sniffed.file

Change the IP address for a configured printer and print any document you wish.

Extract required data

You need some data from the following sections of the sniffed file.

[snipped]

%%EFIUATag: some_base64_encoded_blob"

[snipped]

%%BeginSetup
%%BeginFeature: *EFUserAuthName username
 /XJXsetUserName where { pop <username_hash> XJXsetUserName} if
%%EndFeature
%%BeginFeature: *EFUserAuthPwd password
 /XJXsetAccessCode where { pop <password_hash> XJXsetAccessCode} if
%%EndFeature"
[snipped]

Use the following script to extract the required data and generate a config file for the CUPS filter described in the next section. Run it on the sniffed file and store the results in /etc/cups/ppd/fieryauth.conf.

#!/bin/sh
# extract fiery account credentials and print them to stdout
sed -n -r -e 's/%%EFIUATag: (.*)/TAG="\1"/p' "$1"
sed -n -r -e 's/.*EFUserAuthName (.*)/USERNAME="\1"/p' "$1"
sed -n -r -e 's/.*XJXsetUserName.*<(.*)>.*/USERNAME_HASH="\1"/p' "$1"
sed -n -r -e 's/.*EFUserAuthPwd (.*)/PASSWORD="\1"/p' "$1"
sed -n -r -e 's/.*XJXsetAccessCode.*<(.*)>.*/PASSWORD_HASH="\1"/p' "$1"
$ ./extract.sh sniffed.file
TAG="some_base64_encoded_blob"
USERNAME="username"
USERNAME_HASH="username_hash"
PASSWORD="password"
PASSWORD_HASH="password_hash"

A custom CUPS filter

The purpose of the custom CUPS filter is to mix the authentication data to each PostScript document, that you send to the print server. Copy the following to /usr/lib/cups/filter/fieryauth and make the file executable.

#!/bin/sh
# user configuration
. /etc/cups/ppd/fieryauth.conf

# insert EFIUATag afer line 10 and insert credentials after 'BeginSetup'
sed -e "10a %%EFIUATag: ${TAG}" -e "/BeginSetup/a %%BeginFeature: *EFUserAuthName ${USERNAME}\n
 /XJXsetUserName where { pop <${USERNAME_HASH}> XJXsetUserName} if\n
%%EndFeature\n
%%BeginFeature: *EFUserAuthPwd ${PASSWORD}\n
 /XJXsetAccessCode where { pop <${PASSWORD_HASH}> XJXsetAccessCode} if\n
%%EndFeature"

Modify the PPD from the vendor

One step remains, you need to modify the PPD from the vendor in order to get CUPS to use your custom filter. Get it from EFI’s website and append the following lines at the end of the PPD file:

*cupsFilter: "application/vnd.cups-raw 0 fieryauth"
*cupsFilter: "application/vnd.cups-command 0 commandtops"
*cupsFilter: "application/vnd.cups-postscript 0 fieryauth"

The rest is easy, set up your printer with CUPS as usual, select the modified PPD and you’re done.

A last note

Currently, we do not know how the proprietary Fiery CUPS filter calculates the values from above (EFIUATag, USERNAME_HASH, PASSWORD, PASSWORD_HASH). If you know it, please get in contact with me!

Additional reference and credits