24 #include <freeradius-devel/util/sha1.h>
25 #include <freeradius-devel/util/debug.h>
30 #include <freeradius-devel/util/talloc.h>
31 #include <freeradius-devel/util/dbuff.h>
32 #include <freeradius-devel/util/sbuff.h>
33 #include <freeradius-devel/util/base32.h>
35 #undef RDEBUG_ENABLED3
36 #define RDEBUG_ENABLED3 (!request)
38 #define RDEBUG3(fmt, ...) totp_log(fmt, ## __VA_ARGS__)
42 static void totp_log(
char const *
fmt, ...)
47 vfprintf(stdout,
fmt, ap);
112 padded = ((uint64_t) then) / cfg->
time_step;
113 data[0] = padded >> 56;
114 data[1] = padded >> 48;
115 data[2] = padded >> 40;
116 data[3] = padded >> 32;
117 data[4] = padded >> 24;
118 data[5] = padded >> 16;
119 data[6] = padded >> 8;
120 data[7] = padded & 0xff;
135 challenge = (digest[offset] & 0x7f) << 24;
136 challenge |= digest[offset + 1] << 16;
137 challenge |= digest[offset + 2] << 8;
138 challenge |= digest[offset + 3];
144 challenge % ((cfg->
otp_length == 6) ? 1000000 : 100000000));
147 char buf_now[32], buf_then[32];
164 if ((then < now) && (i <= cfg->lookforward_steps)) {
175 int main(
int argc,
char **argv)
184 .lookback_interval = 1,
188 fprintf(stderr,
"totp: Expected command 'decode' or 'totp'\n");
192 if (strcmp(argv[1],
"decode") == 0) {
194 fprintf(stderr,
"totp: Expected arguments as - decode <base32-data> \n");
199 printf(
"Decoded %ld %s\n", len, key);
201 for (p = key; p < (key + len); p++) {
212 if (strcmp(argv[1],
"totp") == 0) {
216 fprintf(stderr,
"totp: Expected arguments as - totp <time> <key> <totp>\n");
220 (void) sscanf(argv[2],
"%llu", &now);
222 if (
fr_totp_cmp(&totp, NULL, (time_t) now, (
uint8_t const *) argv[3], strlen(argv[3]), argv[4]) == 0) {
229 fprintf(stderr,
"Unknown command %s\n", argv[1]);
static int const char char buffer[256]
static int const char * fmt
#define fr_base32_decode(_out, _in, _expect_padding, _no_trailing)
#define FR_DBUFF_TMP(_start, _len_or_end)
Creates a compound literal to pass into functions which accept a dbuff.
int main(int argc, char **argv)
int fr_hmac_sha1(uint8_t digest[static SHA1_DIGEST_LENGTH], uint8_t const *in, size_t inlen, uint8_t const *key, size_t key_len)
Calculate HMAC using internal SHA1 implementation.
#define RDEBUG_ENABLED3
True if request debug level 1-3 messages are enabled.
int fr_digest_cmp(uint8_t const *a, uint8_t const *b, size_t length)
Do a comparison of two authentication digests by comparing the FULL data.
#define fr_sbuff_start(_sbuff_or_marker)
#define FR_SBUFF_IN(_start, _len_or_end)
#define SHA1_DIGEST_LENGTH
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
size_t fr_time_strftime_local(fr_sbuff_t *out, fr_time_t time, char const *fmt)
Copy a time string (local timezone) to an sbuff.
#define fr_time_wrap(_time)
int fr_totp_cmp(fr_totp_t const *cfg, request_t *request, time_t now, uint8_t const *key, size_t keylen, char const *totp)
Implement RFC 6238 TOTP algorithm (HMAC-SHA1).
uint32_t otp_length
forced to 6 or 8
uint32_t lookforward_steps
number of steps to look forwards
uint32_t lookback_interval
interval in seconds between steps
uint32_t lookback_steps
number of steps to look back
uint32_t time_step
seconds
#define fr_strerror_const(_msg)
int format(printf, 5, 0))