Added --key-gen to allow KEY_BASE64 and HMAC_KEY_BASE64 keys to be created from reading random data from /dev/random. These keys can be placed within server access.conf files and corresponding client .fwknoprc files for SPA communications. The HMAC key is not used yet with this commit, but that is coming.
217 lines
5.1 KiB
C
217 lines
5.1 KiB
C
/*
|
|
*****************************************************************************
|
|
*
|
|
* File: getpasswd.c
|
|
*
|
|
* Author: Damien S. Stuart
|
|
*
|
|
* Purpose: Routines for obtaining a password from a user.
|
|
*
|
|
* Copyright 2009-2010 Damien Stuart (dstuart@dstuart.org)
|
|
*
|
|
* License (GNU Public License):
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
*
|
|
* 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>
|
|
|
|
#ifdef WIN32
|
|
#include <conio.h>
|
|
#else
|
|
#include <termios.h>
|
|
#endif
|
|
|
|
#include "fwknop_common.h"
|
|
#include "getpasswd.h"
|
|
|
|
/* Function for accepting password input from users
|
|
*/
|
|
char*
|
|
getpasswd(const char *prompt)
|
|
{
|
|
static char pwbuf[MAX_KEY_LEN + 1] = {0};
|
|
char *ptr;
|
|
int c;
|
|
|
|
#ifndef WIN32
|
|
FILE *fp;
|
|
sigset_t sig, old_sig;
|
|
struct termios ts, old_ts;
|
|
|
|
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);
|
|
#endif
|
|
|
|
/* Read in the password.
|
|
*/
|
|
ptr = pwbuf;
|
|
#ifdef WIN32
|
|
_cputs(prompt);
|
|
while((c = _getch()) != '\r')
|
|
{
|
|
/* Handle a backspace without backing up too far.
|
|
*/
|
|
if(c == '\b')
|
|
{
|
|
if(ptr != pwbuf)
|
|
*ptr--;
|
|
|
|
continue;
|
|
}
|
|
|
|
/* Handle a Ctrl-U to clear the password entry and start over
|
|
* (like it works under Unix).
|
|
*/
|
|
if(c == 0x15)
|
|
{
|
|
ptr = pwbuf;
|
|
continue;
|
|
}
|
|
#else
|
|
while((c = getc(fp)) != EOF && c != '\n')
|
|
{
|
|
#endif
|
|
if(ptr < &pwbuf[MAX_KEY_LEN])
|
|
*ptr++ = c;
|
|
}
|
|
|
|
/* Null terminate the password.
|
|
*/
|
|
*ptr = 0;
|
|
|
|
#ifndef WIN32
|
|
/* 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);
|
|
#else
|
|
/* In Windows, it would be a CR-LF
|
|
*/
|
|
_putch('\r');
|
|
_putch('\n');
|
|
#endif
|
|
|
|
return(pwbuf);
|
|
}
|
|
|
|
/* Function for accepting password input from from a file
|
|
*/
|
|
char*
|
|
getpasswd_file(const char *pw_file, const char *server_str)
|
|
{
|
|
FILE *pwfile_ptr;
|
|
unsigned int numLines = 0, i = 0, found_dst;
|
|
|
|
static char pwbuf[MAX_KEY_LEN + 1] = {0};
|
|
char conf_line_buf[MAX_LINE_LEN] = {0};
|
|
char tmp_char_buf[MAX_LINE_LEN] = {0};
|
|
char *lptr;
|
|
|
|
if ((pwfile_ptr = fopen(pw_file, "r")) == NULL)
|
|
{
|
|
fprintf(stderr, "Could not open config file: %s\n", pw_file);
|
|
exit(1);
|
|
}
|
|
|
|
while ((fgets(conf_line_buf, MAX_LINE_LEN, pwfile_ptr)) != NULL)
|
|
{
|
|
numLines++;
|
|
conf_line_buf[MAX_LINE_LEN-1] = '\0';
|
|
lptr = conf_line_buf;
|
|
|
|
memset(tmp_char_buf, 0x0, MAX_LINE_LEN);
|
|
|
|
while (*lptr == ' ' || *lptr == '\t' || *lptr == '=')
|
|
lptr++;
|
|
|
|
/* Get past comments and empty lines.
|
|
*/
|
|
if (*lptr == '#' || *lptr == '\n' || *lptr == '\r' || *lptr == '\0' || *lptr == ';')
|
|
continue;
|
|
|
|
/* Look for a line like "<SPA destination IP>: <password>" - this allows
|
|
* multiple keys to be placed within the same file, and the client will
|
|
* reference the matching one for the SPA server we are contacting
|
|
*/
|
|
found_dst = 1;
|
|
for (i=0; i < strlen(server_str); i++)
|
|
if (*lptr++ != server_str[i])
|
|
found_dst = 0;
|
|
|
|
if (! found_dst)
|
|
continue;
|
|
|
|
if (*lptr == ':')
|
|
lptr++;
|
|
else
|
|
continue;
|
|
|
|
/* Skip whitespace until we get to the password
|
|
*/
|
|
while (*lptr == ' ' || *lptr == '\t' || *lptr == '=')
|
|
lptr++;
|
|
|
|
i = 0;
|
|
while (*lptr != '\0' && *lptr != '\n') {
|
|
pwbuf[i] = *lptr;
|
|
lptr++;
|
|
i++;
|
|
}
|
|
pwbuf[i] = '\0';
|
|
}
|
|
|
|
fclose(pwfile_ptr);
|
|
|
|
if (pwbuf[0] == '\0') {
|
|
fprintf(stderr, "Could not get password for IP: %s from: %s\n",
|
|
server_str, pw_file);
|
|
exit(1);
|
|
}
|
|
|
|
return pwbuf;
|
|
}
|
|
|
|
/***EOF***/
|