/* This file is part of ssp https://lila.oss/ssp
* Copyright (C) 2023 Olivier Brunel jjk@jjacky.com */
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef SSP_SSP_H
#define SSP_SSP_H
#include <limb/cdb.h>
#include <limb/cdbmake.h>
#include <limb/int.h>
#include <limb/stralloc.h>
enum {
OPT_HELP = 1 << 0,
};
#define SSP_MAGIC 0xa5e9f801
#define KEY_LEN 32
#define SALT_LEN 32
#define NONCE_LEN 12
#define PWD_MAX 136
#define ITER_MIN 50000
#define ITER_DEF 500000
struct ssp {
stralloc sa;
cdb cdb;
cdb_data key;
cdb_data val;
size_t cdboff;
unsigned int options;
u32 iter;
u32 pos;
char pwd[PWD_MAX + 1];
};
enum {
TYPE_COUNTER = 0,
TYPE_TIME,
TYPE_UNKNOWN = (u8) -1,
};
#define ALGO_UNKNOWN ((u8) -1)
struct otp
{
u64 slen; /* length of secret within data; or offset to comments */
u64 n; /* next counter or time precision */
u8 algo;
u8 type;
u8 digits;
char data[];
};
#define OTP_DEFAULT { .slen = 0, .n = 1, .algo = ALGO_SHA1, .type = TYPE_COUNTER, .digits = 6 }
/* ssp.c */
int exitcode_from_errno(int e);
int run_command(const char *name, int argc, const char *argv[], const char *env[], void *ctx);
/* database.c */
int rebuild_cdb(cdbmaker_sa *mkr, const char *oldkey, const char *newkey,
const struct otp *otp, struct ssp *ctx);
int write_db(char *data, size_t dlen, struct ssp *ctx);
void rebuild_db(const char *oldkey, const char *newkey, const struct otp *otp, struct ssp *ctx);
int open_db(struct ssp *ctx, int is_needed);
void close_db(struct ssp *ctx);
#define db_file(ctx) (ctx)->sa.s
#define db_reset(ctx) (ctx)->pos = CDB_TRAVERSE_INIT()
#define db_next(ctx) cdb_traverse_next(&(ctx)->cdb, &(ctx)->key, &(ctx)->val, &(ctx)->pos)
#define db_find(entry,ctx) ((ctx)->key.s = entry, (ctx)->key.len = strlen(entry) + 1, \
cdb_find(&(ctx)->cdb, &(ctx)->val, (ctx)->key.s, (ctx)->key.len))
#define db_entry(ctx) (ctx)->key.s
#define db_otp(ctx) ((const struct otp *) (ctx)->val.s)
/* add.c */
int validate_algo(int *first, const char *data, size_t len);
int validate_digits(const char *data, size_t dlen);
int validate_counter(u64 *c, const char *data, size_t dlen);
int validate_precision(const char *data, size_t dlen);
/* show.c */
void show_entry(unsigned options, struct ssp *ctx);
void show_entry_ini(unsigned options, struct ssp *ctx);
#endif /* SSP_SSP_H */