Printer Encryption on AIX
I recently had to confront an unusual security issue:
a report coming
through our lp spooler contained sensitive information
could not be broadcast to the company at large. Since
all of our programmers
needed root access, permissions were not the answer.
And, since the
data actually resided on a remote system accessed via
a Sun, tampering
with the data was not an issue. What I had to do was
make sure that
while the document was on my system, it was never in
a readable form.
I also needed to make the process as transparent to
the end user as
The solution I came up with is an encode/decode scheme.
would come from the Sun in a encoded form and would
sit in my spooler
in this form until it was released to the printer. During
of the report, the backend process would decode the
file and print
it correctly. The scheme has two parts: one process
must encode the
report when it is submitted, and another process must
decode the report
when it is printed.
You can create your own encode/decode routines by using
code in cdr.c (Listing 1) and dcdr.c (Listing
one thing to avoid is changing characters outside the
The function isgraph() can tell whether a character
the ASCII range of printable characters (isgraph() differs
from the isprint() function in that it returns FALSE
space character). This range is from hexadecimal 21
7E. If you do use characters outside the printable range,
and decoder programs will function correctly as filters,
but the formatter
for the printer will give strange results, since it
the nonprintable characters for printer control. If
you do use the
two sample programs to work out an encoding/decoding
scheme for your
system, be aware that this scheme has its limits. Try
to keep the
process as simple as possible. Do not, for example,
count on the next
20 printable characters. If you need that complex an
system, you may need more than this scheme can offer.
The technique in the sample programs first changes the
case of all
of the characters. It then starts at the middle of the
range of printable
characters, which is hexadecimal 4F or character "O,"
exchanges each with its corresponding member on the
This encryption/decryption scheme will encode the string
World" as "7ZSSPs (PMS[q".
A major problem with this technique is that the text
remains in the
same form. Even though the characters are different,
have the same number of characters organized in two
scheme that would encode the characters in groups of
number with a character in between would make the encoding
much harder to break. Another feature that would add
to the encoded file would be to change the carriage
characters so that the lines run into each other.
I implement this encoding/decoding scheme in two parts.
part, encoding, is simple, and is system independent.
has to be run through the encryption algorithm before
it is sent to
my system. Since the sending machine is another UNIX
box, it was easy
enough to use the cdr program as a filter during the
of the report.
The second part, decoding, is somewhat trickier. The
AIX backend process
uses what IBM refers to as a "printer formatter"
the spooled output to a form that the printer can recognize.
that IBM provides are in the directory /usr/lib/lpd/pio/fmtrs
under AIX 3.2. The queue colon files, which resides
in the directory
/var/spool/lpd/pio/custom, define which of these printer
are to be used. The colon files define printer functionality
the formatter then passes to the printer device. For
purposes of this
article, only the references to the print formatter
must be changed.
The Print Formatter
I used the sample formatter in C found in InfoExplorer
as a template
for the encoding formatter I present here (Listing 3,
Listing 4, piocrypt.imp; Listing 5,
Listing 6, piocrypt.c).
The driver for the print formatter, pioformat, requires
the formatter contain five routines: initialize, lineout,
passthru, restore, and setup.
The initialize routine uses the piocmdout subroutine
to send the initialization string to the printer. This
set the printer to the proper state for printing. The
string is kept in the colon file for the printer under
The lineout routine is invoked by the formatter driver
horizontal lines on the page. The lineout routine should
output a printer command that causes a vertical movement
of the page;
instead, it should update the shared variables that
keep track of
The passthru routine takes the input stream and passes
the formatter driver unmodified.
The restore routine uses the piocmdout subroutine to
send the restore string to the printer. The restore
string is kept in the colon file for the printer under
A fifth routine, setup, reads the colon file for information
about how the printer should behave. This routine is
if the printer is to be used in passthru mode.
These routines provide all of the functionality for
a simple printer
formatter. They can be expanded to add more complex
encoding and decoding
as well as more functionality.
The header file piostruct.h (Listing 3) contains the
for the structures that the formatter must access.
The setup routine uses the attrparms structure to hold
the data from the colon files. For each two-character
from the colon file, an attrparms structure must be
This array is passed to the piogetvals subroutine, which
the information from the colon files.
The structure shar_vars (see Figure 1) is used to pass
between the print formatter and the formatter driver.
The print formatter
must initialize these variables if they are to be trusted.
driver takes no responsibility for these values and
them as necessary.
Compiling the Formatter
Use the following command to compile and link the print
cc -o piocrypt -bI:piocrypt.imp -bE:piocrypt.exp \
Place the resulting file in the /usr/lib/lpd/pio/fmtrs
directory with bin as the owner and group. Set the permissions
Changing the Colon File
The colon files, which reside in the directory /var/spool/lpd/pio/custom
on AIX 3.2, are named after the queue and the physical
IBM terminology this constitutes a virtual printer.
The first step is to set up a virtual printer using
the ASCII setting.
This will give you a good base colon file to begin work
The five lines to be changed are the sh, st, ia,
ip, and mf variables. The sh variable defines
the pipeline for the header page; the -J flag tells
to use the passthru routine. The st variable defines
the trailer page and is also sent through the passthru
The ia and ip variables define the pipeline for the
input data stream for the extended ASCII and passthru
respectively. The mf command defines the pathname for
These lines, which contain the default formatter, piofasci,
must be changed to contain the new formatter. To make
vi the colon file and use the command:
to replace the old formatter with the new one. Then
the new file with the chvirprt command, as follows:
chvirprt -d [physical device name] -q [queue name]
The new formatter should now be in place.
Keeping sensitive data private can be a very complicated
a system administrator, and the spooler is a particularly
device, since the report is simply sitting there waiting
to be printed.
This encode/decode scheme is a very nice means of protecting
information from curious eyes.
About the Author
Jeff Courington has worked on various forms of UNIX
over the past 8 years, including
AIX, SCO, HP/UX, and SVR3 variants from Silicon Valley
Software and Versyss
Corporation. He presently has a network of 11 IBM RS/6000s
HP/UX machines connected over the wide area with TCP/IP
through the use
of Cisco routers. Jeff graduated from Virginia Polytechnical
and State University with a BS in Computer Science.
He is currently working
on his MS in Computer Science at Virginia Commonwealth
University and can
be reached from the Internet at attmail.com!aix!jeff.