Added getpasswd routine for getting a password from the user. A few updates to the lib to accomodate clearing the password after we are done with it. Update the fwknop program to reflect/use some of the new functionality.
git-svn-id: file:///home/mbr/svn/fwknop/trunk@59 510a4753-2344-4c79-9c09-4d669213fbeb
This commit is contained in:
+3
-2
@@ -31,7 +31,7 @@ AC_PROG_LIBTOOL
|
||||
# Checks for header files.
|
||||
#
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS([locale.h stdlib.h string.h sys/time.h unistd.h ctype.h])
|
||||
AC_CHECK_HEADERS([ctype.h netinet/in.h stdlib.h string.h strings.h sys/time.h termios.h unistd.h])
|
||||
|
||||
# Type checks.
|
||||
#
|
||||
@@ -52,7 +52,8 @@ AC_CHECK_SIZEOF(unsigned int)
|
||||
#
|
||||
AC_FUNC_MALLOC
|
||||
AC_FUNC_REALLOC
|
||||
AC_CHECK_FUNCS([bzero gettimeofday memmove memset strchr strcspn strdup strndup strrchr strspn])
|
||||
AC_FUNC_STAT
|
||||
AC_CHECK_FUNCS([bzero gettimeofday memmove memset socket strchr strcspn strdup strncasecmp strndup strrchr strspn])
|
||||
|
||||
# Check for gpgme
|
||||
#AM_PATH_GPGME
|
||||
|
||||
+4
-9
@@ -72,7 +72,7 @@ get_random_data(unsigned char *data, size_t len)
|
||||
* the Perl Crypt::CBC module's use of Rijndael.
|
||||
*/
|
||||
void
|
||||
rij_salt_and_iv(RIJNDAEL_context *ctx, const char *pass, unsigned char *data)
|
||||
rij_salt_and_iv(RIJNDAEL_context *ctx, char *pass, unsigned char *data)
|
||||
{
|
||||
char pw_buf[16];
|
||||
unsigned char tmp_buf[64]; /* How big does this need to be? */
|
||||
@@ -138,7 +138,7 @@ rij_salt_and_iv(RIJNDAEL_context *ctx, const char *pass, unsigned char *data)
|
||||
/* Initialization entry point.
|
||||
*/
|
||||
void
|
||||
rijndael_init(RIJNDAEL_context *ctx, const char *pass, unsigned char *data)
|
||||
rijndael_init(RIJNDAEL_context *ctx, char *pass, unsigned char *data)
|
||||
{
|
||||
|
||||
/* Use ECB mode to be compatible with the Crypt::CBC perl module.
|
||||
@@ -158,7 +158,7 @@ rijndael_init(RIJNDAEL_context *ctx, const char *pass, unsigned char *data)
|
||||
* module would.
|
||||
*/
|
||||
size_t
|
||||
rij_encrypt(unsigned char *in, size_t in_len, const char *pass, unsigned char *out)
|
||||
rij_encrypt(unsigned char *in, size_t in_len, char *pass, unsigned char *out)
|
||||
{
|
||||
RIJNDAEL_context ctx;
|
||||
unsigned char plaintext[16];
|
||||
@@ -212,7 +212,7 @@ rij_encrypt(unsigned char *in, size_t in_len, const char *pass, unsigned char *o
|
||||
/* Decrypt the given data.
|
||||
*/
|
||||
size_t
|
||||
rij_decrypt(unsigned char *in, size_t in_len, const char *pass, unsigned char *out)
|
||||
rij_decrypt(unsigned char *in, size_t in_len, char *pass, unsigned char *out)
|
||||
{
|
||||
RIJNDAEL_context ctx;
|
||||
unsigned char plaintext[16];
|
||||
@@ -274,9 +274,4 @@ rij_decrypt(unsigned char *in, size_t in_len, const char *pass, unsigned char *o
|
||||
return(ondx - out);
|
||||
}
|
||||
|
||||
/*** These are GPG-specific functions ***/
|
||||
|
||||
//--DSS TODO: Finish me
|
||||
|
||||
|
||||
/***EOF***/
|
||||
|
||||
+4
-6
@@ -34,14 +34,12 @@
|
||||
*/
|
||||
#define PREDICT_ENCSIZE(x) (1+(x>>4)+(x&0xf?1:0))<<4
|
||||
|
||||
size_t rij_encrypt(unsigned char *in, size_t len, const char *key, unsigned char *out);
|
||||
size_t rij_decrypt(unsigned char *in, size_t len, const char *key, unsigned char *out);
|
||||
size_t rij_encrypt(unsigned char *in, size_t len, char *key, unsigned char *out);
|
||||
size_t rij_decrypt(unsigned char *in, size_t len, char *key, unsigned char *out);
|
||||
|
||||
#if HAVE_LIBGPGME
|
||||
int gpg_encrypt(fko_ctx_t ctx, const char *enc_key);
|
||||
//int gpg_encrypt(unsigned char *in, size_t len, const char *signer, const char *recip, unsigned char **out, size_t *out_sz);
|
||||
//int gpg_decrypt(unsigned char *in, size_t len, const char *key, unsigned char **out, size_t *out_sz);
|
||||
int gpg_decrypt(fko_ctx_t ctx, const char *enc_key, size_t b64_len);
|
||||
int gpg_encrypt(fko_ctx_t ctx, char *enc_key);
|
||||
int gpg_decrypt(fko_ctx_t ctx, char *dec_key, size_t b64_len);
|
||||
#endif /* HAVE_LIBGPGME */
|
||||
|
||||
#endif /* CIPHER_FUNCS_H */
|
||||
|
||||
@@ -46,7 +46,7 @@ typedef enum {
|
||||
/* Supported digest types...
|
||||
*/
|
||||
typedef enum {
|
||||
FKO_DIGEST_MD5 = 0,
|
||||
FKO_DIGEST_MD5 = 1,
|
||||
FKO_DIGEST_SHA1,
|
||||
FKO_DIGEST_SHA256,
|
||||
FKO_LAST_DIGEST_TYPE /* Always leave this as the last one */
|
||||
@@ -55,7 +55,7 @@ typedef enum {
|
||||
/* Supported encryption types...
|
||||
*/
|
||||
typedef enum {
|
||||
FKO_ENCRYPTION_RIJNDAEL = 0,
|
||||
FKO_ENCRYPTION_RIJNDAEL = 1,
|
||||
FKO_ENCRYPTION_GPG,
|
||||
FKO_LAST_ENCRYPTION_TYPE /* Always leave this as the last one */
|
||||
} fko_encryption_type_t;
|
||||
@@ -131,9 +131,9 @@ typedef struct fko_context *fko_ctx_t;
|
||||
|
||||
/* General api calls */
|
||||
int fko_new(fko_ctx_t *ctx);
|
||||
int fko_new_with_data(fko_ctx_t *ctx, char *enc_msg, const char *dec_key);
|
||||
int fko_new_with_data(fko_ctx_t *ctx, char *enc_msg, char *dec_key);
|
||||
void fko_destroy(fko_ctx_t ctx);
|
||||
int fko_spa_data_final(fko_ctx_t ctx, const char *enc_key);
|
||||
int fko_spa_data_final(fko_ctx_t ctx, char *enc_key);
|
||||
|
||||
char* fko_get_spa_data(fko_ctx_t ctx);
|
||||
|
||||
@@ -155,8 +155,8 @@ const char* fko_errstr(int err_code);
|
||||
|
||||
int fko_encode_spa_data(fko_ctx_t ctx);
|
||||
int fko_decode_spa_data(fko_ctx_t ctx);
|
||||
int fko_encrypt_spa_data(fko_ctx_t ctx, const char *enc_key);
|
||||
int fko_decrypt_spa_data(fko_ctx_t ctx, const char *dec_key);
|
||||
int fko_encrypt_spa_data(fko_ctx_t ctx, char *enc_key);
|
||||
int fko_decrypt_spa_data(fko_ctx_t ctx, char *dec_key);
|
||||
char* fko_get_encoded_data(fko_ctx_t ctx);
|
||||
|
||||
/* Get context data functions */
|
||||
|
||||
+1
-1
@@ -39,7 +39,7 @@ fko_set_spa_digest_type(fko_ctx_t ctx, short digest_type)
|
||||
if(!CTX_INITIALIZED(ctx))
|
||||
return(FKO_ERROR_CTX_NOT_INITIALIZED);
|
||||
|
||||
if(digest_type < 0 || digest_type >= FKO_LAST_DIGEST_TYPE)
|
||||
if(digest_type < 1 || digest_type >= FKO_LAST_DIGEST_TYPE)
|
||||
return(FKO_ERROR_INVALID_DATA);
|
||||
|
||||
ctx->digest_type = digest_type;
|
||||
|
||||
+45
-24
@@ -34,10 +34,19 @@
|
||||
|
||||
#define B64_RIJNDAEL_SALT "U2FsdGVkX1"
|
||||
|
||||
/* Wipe out the password buffer.
|
||||
*/
|
||||
void
|
||||
wipe_pw(char *pw)
|
||||
{
|
||||
if(pw != NULL)
|
||||
bzero(pw, strlen(pw));
|
||||
}
|
||||
|
||||
/* Prep and encrypt using Rijndael
|
||||
*/
|
||||
int
|
||||
_rijndael_encrypt(fko_ctx_t ctx, const char *enc_key)
|
||||
_rijndael_encrypt(fko_ctx_t ctx, char *enc_key)
|
||||
{
|
||||
char *plain;
|
||||
char *b64cipher;
|
||||
@@ -89,7 +98,7 @@ _rijndael_encrypt(fko_ctx_t ctx, const char *enc_key)
|
||||
/* Decode, decrypt, and parse SPA data into the context.
|
||||
*/
|
||||
int
|
||||
_rijndael_decrypt(fko_ctx_t ctx, const char *dec_key, int b64_len)
|
||||
_rijndael_decrypt(fko_ctx_t ctx, char *dec_key, int b64_len)
|
||||
{
|
||||
char *tbuf;
|
||||
unsigned char *cipher;
|
||||
@@ -156,7 +165,7 @@ _rijndael_decrypt(fko_ctx_t ctx, const char *dec_key, int b64_len)
|
||||
/* Prep and encrypt using gpgme
|
||||
*/
|
||||
int
|
||||
gpg_encrypt(fko_ctx_t ctx, const char *enc_key)
|
||||
gpg_encrypt(fko_ctx_t ctx, char *enc_key)
|
||||
{
|
||||
int res;
|
||||
char *plain;
|
||||
@@ -221,7 +230,7 @@ gpg_encrypt(fko_ctx_t ctx, const char *enc_key)
|
||||
/* Prep and encrypt using gpgme
|
||||
*/
|
||||
int
|
||||
gpg_decrypt(fko_ctx_t ctx, const char *dec_key, size_t b64_len)
|
||||
gpg_decrypt(fko_ctx_t ctx, char *dec_key, size_t b64_len)
|
||||
{
|
||||
unsigned char *cipher;
|
||||
size_t cipher_len;
|
||||
@@ -307,61 +316,68 @@ fko_get_spa_encryption_type(fko_ctx_t ctx)
|
||||
/* Encrypt the encoded SPA data.
|
||||
*/
|
||||
int
|
||||
fko_encrypt_spa_data(fko_ctx_t ctx, const char *enc_key)
|
||||
fko_encrypt_spa_data(fko_ctx_t ctx, char *enc_key)
|
||||
{
|
||||
int res;
|
||||
|
||||
/* Must be initialized
|
||||
*/
|
||||
if(!CTX_INITIALIZED(ctx))
|
||||
return(FKO_ERROR_CTX_NOT_INITIALIZED);
|
||||
{
|
||||
res = FKO_ERROR_CTX_NOT_INITIALIZED;
|
||||
goto EWIPEOUT;
|
||||
}
|
||||
|
||||
/* If there is no encoded data or the SPA data has been modified,
|
||||
* go ahead and re-encode here.
|
||||
*/
|
||||
if(ctx->encoded_msg == NULL || FKO_IS_SPA_DATA_MODIFIED(ctx))
|
||||
{
|
||||
res = fko_encode_spa_data(ctx);
|
||||
|
||||
if(res != FKO_SUCCESS)
|
||||
return(res);
|
||||
}
|
||||
|
||||
/* Croak on invalid encoded message as well. At present this is a
|
||||
* check for a somewhat arbitrary minimum length for the encoded
|
||||
* data.
|
||||
*/
|
||||
if(strlen(ctx->encoded_msg) < MIN_SPA_ENCODED_MSG_SIZE)
|
||||
return(FKO_ERROR_MISSING_ENCODED_DATA);
|
||||
{
|
||||
res = FKO_ERROR_MISSING_ENCODED_DATA;
|
||||
goto EWIPEOUT;
|
||||
}
|
||||
|
||||
/* Encrypt according to type and return...
|
||||
*/
|
||||
if(ctx->encryption_type == FKO_ENCRYPTION_RIJNDAEL)
|
||||
return(_rijndael_encrypt(ctx, enc_key));
|
||||
|
||||
res = _rijndael_encrypt(ctx, enc_key);
|
||||
else if(ctx->encryption_type == FKO_ENCRYPTION_GPG)
|
||||
#if HAVE_LIBGPGME
|
||||
return(gpg_encrypt(ctx, enc_key));
|
||||
res = gpg_encrypt(ctx, enc_key);
|
||||
#else
|
||||
return(FKO_ERROR_UNSUPPORTED_FEATURE);
|
||||
res = FKO_ERROR_UNSUPPORTED_FEATURE;
|
||||
#endif
|
||||
|
||||
else
|
||||
return(FKO_ERROR_INVALID_ENCRYPTION_TYPE);
|
||||
res = FKO_ERROR_INVALID_ENCRYPTION_TYPE;
|
||||
|
||||
EWIPEOUT:
|
||||
wipe_pw(enc_key);
|
||||
|
||||
return(res);
|
||||
}
|
||||
|
||||
/* Decode, decrypt, and parse SPA data into the context.
|
||||
*/
|
||||
int
|
||||
fko_decrypt_spa_data(fko_ctx_t ctx, const char *dec_key)
|
||||
fko_decrypt_spa_data(fko_ctx_t ctx, char *dec_key)
|
||||
{
|
||||
int b64_len;
|
||||
int b64_len, res;
|
||||
|
||||
/* First, make sure we have data to work with.
|
||||
*/
|
||||
if(ctx->encrypted_msg == NULL
|
||||
|| strlen(ctx->encrypted_msg) < MIN_SPA_ENCODED_MSG_SIZE)
|
||||
return(FKO_ERROR_INVALID_DATA);
|
||||
{
|
||||
res = FKO_ERROR_INVALID_DATA;
|
||||
goto DWIPEOUT;
|
||||
}
|
||||
|
||||
/* Determine type of encryption used. For know, we are using the
|
||||
* size of the message.
|
||||
@@ -375,16 +391,21 @@ fko_decrypt_spa_data(fko_ctx_t ctx, const char *dec_key)
|
||||
{
|
||||
ctx->encryption_type = FKO_ENCRYPTION_GPG;
|
||||
#if HAVE_LIBGPGME
|
||||
return(gpg_decrypt(ctx, dec_key, b64_len));
|
||||
res = gpg_decrypt(ctx, dec_key, b64_len);
|
||||
#else
|
||||
return(FKO_ERROR_UNSUPPORTED_FEATURE);
|
||||
res = FKO_ERROR_UNSUPPORTED_FEATURE;
|
||||
#endif
|
||||
}
|
||||
else /* We are assuming the default of Rijndael */
|
||||
{
|
||||
ctx->encryption_type = FKO_ENCRYPTION_RIJNDAEL;
|
||||
return(_rijndael_decrypt(ctx, dec_key, b64_len));
|
||||
res = _rijndael_decrypt(ctx, dec_key, b64_len);
|
||||
}
|
||||
|
||||
DWIPEOUT:
|
||||
wipe_pw(dec_key);
|
||||
|
||||
return(res);
|
||||
}
|
||||
|
||||
/* Set the GPG recipient key name.
|
||||
|
||||
+2
-2
@@ -148,7 +148,7 @@ fko_new(fko_ctx_t *r_ctx)
|
||||
* and parsing the provided data into the context data.
|
||||
*/
|
||||
int
|
||||
fko_new_with_data(fko_ctx_t *r_ctx, char *enc_msg, const char *dec_key)
|
||||
fko_new_with_data(fko_ctx_t *r_ctx, char *enc_msg, char *dec_key)
|
||||
{
|
||||
fko_ctx_t ctx;
|
||||
|
||||
@@ -254,7 +254,7 @@ fko_version(fko_ctx_t ctx)
|
||||
* set.
|
||||
*/
|
||||
int
|
||||
fko_spa_data_final(fko_ctx_t ctx, const char *enc_key)
|
||||
fko_spa_data_final(fko_ctx_t ctx, char *enc_key)
|
||||
{
|
||||
/* Must be initialized
|
||||
*/
|
||||
|
||||
+3
-2
@@ -1,7 +1,8 @@
|
||||
bin_PROGRAMS = fwknop
|
||||
|
||||
fwknop_SOURCES = fwknop.c fwknop.h config_init.c config_init.h fwkop_common.h \
|
||||
spa_comm.c spa_comm.h utils.c utils.h
|
||||
fwknop_SOURCES = fwknop.c fwknop.h config_init.c config_init.h \
|
||||
fwkop_common.h spa_comm.c spa_comm.h utils.c utils.h \
|
||||
getpasswd.c getpasswd.h
|
||||
|
||||
fwknop_LDADD = $(top_builddir)/fko/libfko.la
|
||||
fwknop_CPPFLAGS = -I $(top_srcdir)/fko
|
||||
|
||||
@@ -335,6 +335,7 @@ usage(void)
|
||||
" --gpg-encryption - Use GPG encyrption (default is Rijndael).\n"
|
||||
" --gpg-recipient-key - Specify the recipient GPG key name or ID.\n"
|
||||
" --gpg-signer-key - Specify the signer's GPG key name or ID.\n"
|
||||
" --gpg-agent - Use GPG agent if available.\n"
|
||||
"\n"
|
||||
);
|
||||
|
||||
|
||||
+36
-2
@@ -27,12 +27,20 @@
|
||||
#include "config_init.h"
|
||||
#include "spa_comm.h"
|
||||
#include "utils.h"
|
||||
#include "getpasswd.h"
|
||||
|
||||
/* Used be the getpw function below.
|
||||
*/
|
||||
#define CRYPT_OP_ENCRYPT 1
|
||||
#define CRYPT_OP_DECRYPT 2
|
||||
char* getpw(fko_cli_options_t *options, int crypt_op);
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
fko_ctx_t ctx, ctx2;
|
||||
int res;
|
||||
char *pw;
|
||||
|
||||
fko_cli_options_t options;
|
||||
|
||||
@@ -55,6 +63,12 @@ main(int argc, char **argv)
|
||||
*/
|
||||
if(options.use_gpg)
|
||||
{
|
||||
/* If use-gpg-agent was not specified, then remove the GPG_AGENT_INFO
|
||||
* ENV variable if it exists.
|
||||
*/
|
||||
if(!options.use_gpg_agent)
|
||||
unsetenv("GPG_AGENT_INFO");
|
||||
|
||||
res = fko_set_spa_encryption_type(ctx, FKO_ENCRYPTION_GPG);
|
||||
if(res != FKO_SUCCESS)
|
||||
{
|
||||
@@ -144,7 +158,7 @@ main(int argc, char **argv)
|
||||
|
||||
/* Finalize the context data (encrypt and encode the SPA data)
|
||||
*/
|
||||
res = fko_spa_data_final(ctx, FKO_PW);
|
||||
res = fko_spa_data_final(ctx, getpw(&options, CRYPT_OP_ENCRYPT));
|
||||
if(res != FKO_SUCCESS)
|
||||
{
|
||||
fprintf(stderr,
|
||||
@@ -178,7 +192,8 @@ main(int argc, char **argv)
|
||||
|
||||
/* Now we create a new context based on data from the first one.
|
||||
*/
|
||||
res = fko_new_with_data(&ctx2, fko_get_spa_data(ctx), FKO_PW);
|
||||
res = fko_new_with_data(&ctx2, fko_get_spa_data(ctx),
|
||||
getpw(&options, CRYPT_OP_DECRYPT));
|
||||
if(res != FKO_SUCCESS)
|
||||
{
|
||||
fprintf(stderr,
|
||||
@@ -205,6 +220,25 @@ main(int argc, char **argv)
|
||||
return(0);
|
||||
}
|
||||
|
||||
char*
|
||||
getpw(fko_cli_options_t *options, int crypt_op)
|
||||
{
|
||||
if(options->use_gpg)
|
||||
{
|
||||
return(options->use_gpg_agent ? ""
|
||||
: getpasswd("Enter passphrase for secret key: "));
|
||||
}
|
||||
else
|
||||
{
|
||||
if(crypt_op == CRYPT_OP_ENCRYPT)
|
||||
return(getpasswd("Enter encryption password: "));
|
||||
else if(crypt_op == CRYPT_OP_DECRYPT)
|
||||
return(getpasswd("Enter decryption password: "));
|
||||
else
|
||||
return(getpasswd("Enter password: "));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
display_ctx(fko_ctx_t ctx)
|
||||
{
|
||||
|
||||
+21
-8
@@ -28,14 +28,29 @@
|
||||
|
||||
/* Common includes for our other fwknop client source files.
|
||||
*/
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#if STDC_HEADERS
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#elif HAVE_STRINGS_H
|
||||
#include <strings.h>
|
||||
#endif /* STDC_HEADERS*/
|
||||
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#include "fko.h"
|
||||
|
||||
@@ -55,8 +70,6 @@
|
||||
|
||||
/* Other common defines
|
||||
*/
|
||||
#define FKO_PW "BubbaWasHere" //--DSS Temp
|
||||
|
||||
#define FKO_DEFAULT_PROTO IPPROTO_UDP
|
||||
#define FKO_DEFAULT_PORT 62201
|
||||
#define MAX_IP_STR_LEN 16
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
/* $Id$
|
||||
*****************************************************************************
|
||||
*
|
||||
* File: getpasswd.c
|
||||
*
|
||||
* Author: Damien S. Stuart
|
||||
*
|
||||
* Purpose: Routines for obtaining a password from a user.
|
||||
*
|
||||
* Copyright (C) 2009 Damien Stuart (dstuart@dstuart.org)
|
||||
*
|
||||
* License (GNU Public License):
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA
|
||||
*
|
||||
*****************************************************************************
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "getpasswd.h"
|
||||
|
||||
#define MAX_PASS_LEN 128
|
||||
|
||||
/* Generic hex dump function.
|
||||
*/
|
||||
char*
|
||||
getpasswd(const char *prompt)
|
||||
{
|
||||
static char pwbuf[MAX_PASS_LEN + 1] = {0};
|
||||
char *ptr;
|
||||
sigset_t sig, old_sig;
|
||||
struct termios ts, old_ts;
|
||||
FILE *fp;
|
||||
int c;
|
||||
|
||||
if((fp = fopen(ctermid(NULL), "r+")) == NULL)
|
||||
return(NULL);
|
||||
|
||||
setbuf(fp, NULL);
|
||||
|
||||
/* Setup blocks for SIGINT and SIGTSTP and save the original signal
|
||||
* mask.
|
||||
*/
|
||||
sigemptyset(&sig);
|
||||
sigaddset(&sig, SIGINT);
|
||||
sigaddset(&sig, SIGTSTP);
|
||||
sigprocmask(SIG_BLOCK, &sig, &old_sig);
|
||||
|
||||
/* Save current tty state for later restoration after we disable echo
|
||||
* of characters to the tty.
|
||||
*/
|
||||
tcgetattr(fileno(fp), &ts);
|
||||
old_ts = ts;
|
||||
ts.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
|
||||
tcsetattr(fileno(fp), TCSAFLUSH, &ts);
|
||||
|
||||
fputs(prompt, fp);
|
||||
|
||||
/* Read in the password.
|
||||
*/
|
||||
ptr = pwbuf;
|
||||
while((c = getc(fp)) != EOF && c != '\n')
|
||||
if(ptr < &pwbuf[MAX_PASS_LEN])
|
||||
*ptr++ = c;
|
||||
|
||||
/* Null terminate the password.
|
||||
*/
|
||||
*ptr = 0;
|
||||
|
||||
/* we can go ahead and echo out a newline.
|
||||
*/
|
||||
putc('\n', fp);
|
||||
|
||||
/* Restore our tty state and signal handlers.
|
||||
*/
|
||||
tcsetattr(fileno(fp), TCSAFLUSH, &old_ts);
|
||||
sigprocmask(SIG_BLOCK, &old_sig, NULL);
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return(pwbuf);
|
||||
}
|
||||
|
||||
/***EOF***/
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
*****************************************************************************
|
||||
*
|
||||
* File: getpasswd.h
|
||||
*
|
||||
* Author: Damien Stuart (dstuart@dstuart.org)
|
||||
*
|
||||
* Purpose: Header file for getpasswd.c.
|
||||
*
|
||||
* Copyright (C) 2009 Damien Stuart (dstuart@dstuart.org)
|
||||
*
|
||||
* License (GNU Public License):
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
||||
* USA
|
||||
*
|
||||
*****************************************************************************
|
||||
*/
|
||||
#ifndef GETPASSWD_H
|
||||
#define GETPASSWD_H
|
||||
|
||||
/* Prototypes
|
||||
*/
|
||||
char* getpasswd(const char *prompt);
|
||||
|
||||
#endif /* GETPASSWD_H */
|
||||
Reference in New Issue
Block a user