21.03.2013 Views

Problem - Kevin Tafuro

Problem - Kevin Tafuro

Problem - Kevin Tafuro

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Once getpass( ) or readpassphrase( ) return successfully, you should perform as<br />

quickly as possible whatever operation you need to perform with the password that<br />

was obtained. Then clear the contents of the returned buffer so that the cleartext<br />

password or passphrase will not be left visible in memory to a potential attacker.<br />

Prompting for a password on Unix without getpass( ) or readpassphrase( )<br />

The function presented in this subsection, spc_read_password( ), requires two arguments.<br />

The first is a prompt to be displayed to the user, and the second is the FILE<br />

object that points to the input source. If the input source is specified as NULL, spc_<br />

read_password( ) will use _PATH_TTY, which is usually defined to be /dev/tty.<br />

The function reads as much data from the input source as memory is available to<br />

hold. It allocates an internal buffer, which grows incrementally as it is filled. If the<br />

function is successful, the return value will be a pointer to this buffer; otherwise, it<br />

will be a NULL pointer.<br />

Note that we use the unbuffered I/O API for reading data from the input source. The<br />

unbuffered read is necessary to avoid potential odd side effects in the I/O. We cannot<br />

use the stream API because there is no way to save and restore the size of the<br />

stream buffer. That is, we cannot know whether the stream was previously buffered.<br />

#include <br />

#include <br />

#include <br />

#include <br />

#include <br />

#include <br />

#define BUF_STEP 1024 /* Allocate this much space for the password, and if it gets<br />

* this long, reallocate twice the space.<br />

* Rinse, lather, repeat.<br />

*/<br />

static unsigned char *read_password(int termfd) {<br />

unsigned char ch, *ret, *tmp;<br />

unsigned long ctr = 0;<br />

if (!(ret = (unsigned char *)malloc(BUF_STEP + 1))) return 0;<br />

for (;;) {<br />

switch (read(termfd, &ch, 1)) {<br />

case 1:<br />

if (ch != '\n') break;<br />

/* FALL THROUGH */<br />

case 0:<br />

ret[ctr] = 0;<br />

return ret;<br />

default:<br />

free(ret);<br />

return 0;<br />

}<br />

This is the Title of the Book, eMatter Edition<br />

Copyright © 2007 O’Reilly & Associates, Inc. All rights reserved.<br />

Prompting for a Password | 395

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!