Skip to content

Commit

Permalink
Merge branch 'master' of ssh://git.sv.gnu.org/srv/git/otpasswd
Browse files Browse the repository at this point in the history
  • Loading branch information
Tomasz bla Fortuna committed Dec 12, 2009
2 parents 2ea9bc5 + 4c361a5 commit e241d76
Show file tree
Hide file tree
Showing 8 changed files with 466 additions and 13 deletions.
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ INCLUDE_DIRECTORIES(${PAM_INCLUDE_DIR})
# src/state.c src/print.c src/passcards.c)

ADD_LIBRARY(libotp SHARED libotp/crypto.c libotp/num.c libotp/ppp.c
libotp/state.c libotp/print.c libotp/passcards.c)
libotp/state.c libotp/print.c libotp/passcards.c
libotp/config.c)

# As other targets require this include directory...
INCLUDE_DIRECTORIES(libotp/)
Expand Down
5 changes: 4 additions & 1 deletion ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ Trying to sort tasks according to their priority.
Also is there any reason to use SHA256 on RANDOM data?
Maybe few bytes from rng + some from prng and SHA out of it?
* [+] Place common functions inside a shared library
* [+] Check bit distribution for alphabets not divisible by 2
Added separate testcase evaluating character distribution
instead of bits. This testcase shows that distribution
is in correct range.
* [-] Keeping track of failures.
Started (place in state files created)
* [-] Implement static passwords;
Expand All @@ -75,7 +79,6 @@ Trying to sort tasks according to their priority.
more fine-grained is necessary.
* [-] Scan all FIXME/TODO entries
* [-] Manuals
* [-] Check bit distribution for alphabets not divisible by 2
* [-] Improve error messages when state file is not found.
* [?] Big thing - Move state files to /etc + SUID.
* [?] Use locales for user messages [_("")? ]
Expand Down
187 changes: 187 additions & 0 deletions libotp/config.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
/**********************************************************************
* otpasswd -- One-time password manager and PAM module.
* Copyright (C) 2009 by Tomasz bla Fortuna <bla@thera.be>
*
* 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 3 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 otpasswd. If not, see <http://www.gnu.org/licenses/>.
**********************************************************************/

#include <stdio.h>
#include <string.h>

#include "print.h"
#include "config.h"

int config_parse(options *opt, const char *config_path)
{
int retval = 1;
int line_count = 0;
FILE *f;

char line_buf[CONFIG_MAX_LINE_LEN];

if (config_path) {
f = fopen(config_path, "r");
} else {
f = fopen(CONFIG_PATH, "r");
}

if (!f) {
print_perror(PRINT_ERROR, "Unable to open config file!\n");
return 1;
}

do {
char *last_char = line_buf + sizeof(line_buf) - 2;
/* Mark the end of line */
*last_char = '\0';

/* Read line */
if (fgets(line_buf, sizeof(line_buf), f) == NULL)
break;

/* Check line too long condition */
if (*last_char != '\n' || *last_char != '\0') {
print(PRINT_ERROR, "Line in config file to long");
goto error;
}

line_count++;

/* Omit comments */
if (line_buf[0] == '#')
continue;

/* Omit all-whitespace */
char *ptr = line_buf;
for (; *ptr != '\0' && *ptr == '\n' && *ptr != ' ' &&
*ptr != '\t'; ptr++);

if (*ptr == '\0') {
/* We got to the end of line - it's all whitespace.
* Omit it */
continue;
}

/* Find = */
char *equality = strchr(line_buf, '=');

if (!equality) {
print(PRINT_ERROR, "Syntax error on line %d in config file.",
line_count);
goto error;
}

/* After those two lines equality points to the start
* of argument, and buf_line to the name of variable
* we are setting (nul-terminated)
*/
*equality = '\0';
equality++;

/* Try to parse argument as int */
int arg;
int arg_state = sscanf(equality, "%d", &arg);

/* Helper macro to ensure all parameters
* have correct values */
#define REQUIRE_ARG(from, to) \
do { \
if (arg_state != 1) { \
print(PRINT_ERROR, \
"Unable to parse int argument" \
" in config at line %d\n", \
line_count); \
goto error; \
} \
if (arg < (from) || arg > (to)) { \
print(PRINT_ERROR, \
"Number argument (%d) out of" \
" range (%d;%d) in config " \
"at line %d.\n", \
arg, from, to, line_count); \
goto error; \
} \
} while (0)


if (strcasecmp(line_buf, "show") == 0) {
REQUIRE_ARG(1,3);
opt->show = arg;
} else if (strcasecmp(line_buf, "enforce") == 0) {
REQUIRE_ARG(0, 1);
opt->enforce = arg;
} else if (strcasecmp(line_buf, "retry") == 0) {
REQUIRE_ARG(0, 3);
opt->retry = arg;
} else if (strcasecmp(line_buf, "debug") == 0) {
REQUIRE_ARG(0, 1);
opt->debug = arg;
} else if (strcasecmp(line_buf, "oob") == 0) {
REQUIRE_ARG(0, 2);
opt->oob = arg;
} else if (strcasecmp(line_buf, "oob_path") == 0) {
} else if (strcasecmp(line_buf, "uid") == 0) {
REQUIRE_ARG(0, 9999999);
opt->uid = arg;
} else if (strcasecmp(line_buf, "gid") == 0) {
REQUIRE_ARG(0, 9999999);
opt->gid = arg;
} else if (strcasecmp(line_buf, "use_global_db") == 0) {
REQUIRE_ARG(0, 1);
opt->use_global_db = arg;
} else if (strcasecmp(line_buf, "global_db") == 0) {
} else if (strcasecmp(line_buf, "user_db") == 0) {
} else if (strcasecmp(line_buf, "allow_skipping") == 0) {
REQUIRE_ARG(0, 1);
opt->allow_skipping = arg;
} else if (strcasecmp(line_buf, "allow_passode_print") == 0) {
REQUIRE_ARG(0, 1);
opt->allow_passcode_print = arg;
} else if (strcasecmp(line_buf, "allow_key_print") == 0) {
REQUIRE_ARG(0, 1);
opt->allow_key_print = arg;
} else if (strcasecmp(line_buf, "allow_key_generation") == 0) {
REQUIRE_ARG(0, 1);
opt->allow_key_generation = arg;
} else if (strcasecmp(line_buf, "min_passcode_length") == 0) {
REQUIRE_ARG(2, 16);
opt->min_passcode_length = arg;
} else if (strcasecmp(line_buf, "max_passcode_length") == 0) {
REQUIRE_ARG(2, 16);
opt->max_passcode_length = arg;
} else if (strcasecmp(line_buf, "min_alphabet_length") == 0) {
REQUIRE_ARG(64, 88);
opt->min_alphabet_length = arg;
} else if (strcasecmp(line_buf, "max_alphabet_length") == 0) {
REQUIRE_ARG(64, 88);
opt->max_alphabet_length = arg;
} else if (strcasecmp(line_buf, "salt") == 0) {
REQUIRE_ARG(0, 2);
opt->salt = arg;
} else {
/* Error */
print(PRINT_ERROR, "Unrecognized variable on line %d in config file\n",
line_count);
}

} while (!feof(f));

/* All ok */
retval = 0;
error:
fclose(f);
return retval;
}


112 changes: 112 additions & 0 deletions libotp/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/**********************************************************************
* otpasswd -- One-time password manager and PAM module.
* Copyright (C) 2009 by Tomasz bla Fortuna <bla@thera.be>
*
* 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 3 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 otpasswd. If not, see <http://www.gnu.org/licenses/>.
**********************************************************************/

#ifndef _CONFIG_H_
#define _CONFIG_H_

#define CONFIG_PATH "/etc/security/otpasswd.conf"
#define CONFIG_MAX_LINE_LEN 260
#define CONFIG_DEF_DB_GLOBAL "/etc/otshadow"
#define CONFIG_DEF_DB_USER ".otpasswd"
#define CONFIG_PATH_LEN 200

typedef struct {
/***
* General configuration
***/

int use_global_db;

/* Location of global database file */
char global_db_path[CONFIG_PATH_LEN];

/* Location of user database file */
char user_db_path[CONFIG_PATH_LEN];

/***
* PAM Configuration
***/

/* Enforced makes any user without key
* fail to login */
int enforce;

/* Do we allow dont-skip? 0 - yes */
int secure;

/* Turns on increased debugging (into syslog) */
int debug;

/* 0 - no retry
* 1 - retry with new passcode
* 2 - retry with the same passcode
* Will always retry 3 times...
*/
int retry;

/* Shall we echo entered passcode?
* 1 - user selected
* 0 - (noshow) echo disabled
* 2 - (show) echo enabled
*/
int show;

/* 0 - OOB disabled
* 1 - OOB on request
* 2 - OOB on request; request requires password
* 3 - OOB sent during all authentication sessions
*/
int oob;

/* Out-Of-Band script path */
/* Ensure that size of this field matches sscanf in _parse_options */
char oob_path[CONFIG_PATH_LEN];

/* Parameters determined from the environment and
* not options themselves */
int uid, gid; /* uid, gid of a safe, non-root user who can run OOB script */

/***
* Policy configuration
***/
/* Implemented */

/* Not-implemented */
int allow_key_generation;
int allow_skipping;
int allow_passcode_print;
int allow_key_print;
int min_passcode_length;
int max_passcode_length;
int min_alphabet_length;
int max_alphabet_length;
int salt;
} options;

/* Set all fields to default values */
extern void config_defaults(options *opt);

/* Parse config file and set fields in struct
* config_path might be NULL to read default config.
*/ppp
extern int config_parse(options *opt, const char *config_path);




#endif
2 changes: 1 addition & 1 deletion libotp/state.c
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,7 @@ int state_store(state *s)
counter = mpz_get_str(NULL, STATE_BASE, s->counter);
latest_card = mpz_get_str(NULL, STATE_BASE, s->latest_card);

if (s->spass)
if (s->spass_set)
spass = mpz_get_str(NULL, STATE_BASE, s->spass);
else
spass = strdup("");
Expand Down
Loading

0 comments on commit e241d76

Please sign in to comment.