"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/utils_tools.c" between
cryptsetup-2.3.6.tar.xz and cryptsetup-2.4.0.tar.xz

About: cryptsetup is a utility used to conveniently setup disk encryption based on the dm-crypt kernel module. These include plain dm-crypt volumes, LUKS volumes, loop-AES and TrueCrypt compatible format.

utils_tools.c  (cryptsetup-2.3.6.tar.xz):utils_tools.c  (cryptsetup-2.4.0.tar.xz)
skipping to change at line 28 skipping to change at line 28
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#include "cryptsetup.h" #include "cryptsetup.h"
#include <math.h> #include <math.h>
#include <signal.h> #include <signal.h>
int opt_verbose = 0;
int opt_debug = 0;
int opt_debug_json = 0;
int opt_batch_mode = 0;
int opt_progress_frequency = 0;
/* interrupt handling */ /* interrupt handling */
volatile int quit = 0; volatile int quit = 0;
static int signals_blocked = 0; static int signals_blocked = 0;
static void int_handler(int sig __attribute__((__unused__))) static void int_handler(int sig __attribute__((__unused__)))
{ {
quit++; quit++;
} }
int tools_signals_blocked(void) int tools_signals_blocked(void)
skipping to change at line 80 skipping to change at line 74
sigaction(SIGTERM, &sigaction_open, 0); sigaction(SIGTERM, &sigaction_open, 0);
set_int_block(block); set_int_block(block);
} }
void check_signal(int *r) void check_signal(int *r)
{ {
if (quit && !*r) if (quit && !*r)
*r = -EINTR; *r = -EINTR;
} }
#define LOG_MAX_LEN 4096 void tool_log(int level, const char *msg, void *usrptr)
__attribute__((format(printf, 5, 6)))
void clogger(struct crypt_device *cd, int level, const char *file, int line,
const char *format, ...)
{ {
va_list argp; struct tools_log_params *params = (struct tools_log_params *)usrptr;
char target[LOG_MAX_LEN + 2];
va_start(argp, format);
if (vsnprintf(&target[0], LOG_MAX_LEN, format, argp) > 0) { switch (level) {
/* All verbose and error messages in tools end with EOL. */
if (level == CRYPT_LOG_VERBOSE || level == CRYPT_LOG_ERROR ||
level == CRYPT_LOG_DEBUG || level == CRYPT_LOG_DEBUG_JSON)
strncat(target, "\n", LOG_MAX_LEN);
crypt_log(cd, level, target);
}
va_end(argp);
}
void tool_log(int level, const char *msg, void *usrptr __attribute__((unused)))
{
switch(level) {
case CRYPT_LOG_NORMAL: case CRYPT_LOG_NORMAL:
fprintf(stdout, "%s", msg); fprintf(stdout, "%s", msg);
break; break;
case CRYPT_LOG_VERBOSE: case CRYPT_LOG_VERBOSE:
if (opt_verbose) if (params && params->verbose)
fprintf(stdout, "%s", msg); fprintf(stdout, "%s", msg);
break; break;
case CRYPT_LOG_ERROR: case CRYPT_LOG_ERROR:
fprintf(stderr, "%s", msg); fprintf(stderr, "%s", msg);
break; break;
case CRYPT_LOG_DEBUG_JSON: case CRYPT_LOG_DEBUG_JSON:
case CRYPT_LOG_DEBUG: case CRYPT_LOG_DEBUG:
if (opt_debug) if (params && params->debug)
fprintf(stdout, "# %s", msg); fprintf(stdout, "# %s", msg);
break; break;
} }
} }
void quiet_log(int level, const char *msg, void *usrptr) void quiet_log(int level, const char *msg, void *usrptr)
{ {
if (!opt_verbose && (level == CRYPT_LOG_ERROR || level == CRYPT_LOG_NORMA struct tools_log_params *params = (struct tools_log_params *)usrptr;
L))
level = CRYPT_LOG_VERBOSE; if ((!params || !params->verbose) && (level == CRYPT_LOG_ERROR || level =
= CRYPT_LOG_NORMAL))
return;
tool_log(level, msg, usrptr); tool_log(level, msg, usrptr);
} }
static int _dialog(const char *msg, void *usrptr, int default_answer) static int _dialog(const char *msg, void *usrptr, int default_answer)
{ {
const char *fail_msg = (const char *)usrptr; const char *fail_msg = (const char *)usrptr;
char *answer = NULL; char *answer = NULL;
size_t size = 0; size_t size = 0;
int r = default_answer, block; int r = default_answer, block;
block = tools_signals_blocked(); block = tools_signals_blocked();
if (block) if (block)
set_int_block(0); set_int_block(0);
if (isatty(STDIN_FILENO) && !opt_batch_mode) { if (isatty(STDIN_FILENO)) {
log_std("\nWARNING!\n========\n"); log_std("\nWARNING!\n========\n");
log_std("%s\n\nAre you sure? (Type 'yes' in capital letters): ", msg); log_std("%s\n\nAre you sure? (Type 'yes' in capital letters): ", msg);
fflush(stdout); fflush(stdout);
if(getline(&answer, &size, stdin) == -1) { if(getline(&answer, &size, stdin) == -1) {
r = 0; r = 0;
/* Aborted by signal */ /* Aborted by signal */
if (!quit) if (!quit)
log_err(_("Error reading response from terminal." )); log_err(_("Error reading response from terminal." ));
else else
log_dbg("Query interrupted on signal."); log_dbg("Query interrupted on signal.");
skipping to change at line 182 skipping to change at line 157
int noDialog(const char *msg, void *usrptr) int noDialog(const char *msg, void *usrptr)
{ {
return _dialog(msg, usrptr, 0); return _dialog(msg, usrptr, 0);
} }
void show_status(int errcode) void show_status(int errcode)
{ {
char *crypt_error; char *crypt_error;
if(!opt_verbose) if (!errcode) {
return; log_verbose(_("Command successful."));
if(!errcode) {
log_std(_("Command successful.\n"));
return; return;
} }
if (errcode < 0) if (errcode < 0)
errcode = translate_errno(errcode); errcode = translate_errno(errcode);
if (errcode == 1) if (errcode == 1)
crypt_error = _("wrong or missing parameters"); crypt_error = _("wrong or missing parameters");
else if (errcode == 2) else if (errcode == 2)
crypt_error = _("no permission or bad passphrase"); crypt_error = _("no permission or bad passphrase");
else if (errcode == 3) else if (errcode == 3)
crypt_error = _("out of memory"); crypt_error = _("out of memory");
else if (errcode == 4) else if (errcode == 4)
crypt_error = _("wrong device or file specified"); crypt_error = _("wrong device or file specified");
else if (errcode == 5) else if (errcode == 5)
crypt_error = _("device already exists or device is busy"); crypt_error = _("device already exists or device is busy");
else else
crypt_error = _("unknown error"); crypt_error = _("unknown error");
log_std(_("Command failed with code %i (%s).\n"), -errcode, crypt_error); log_verbose(_("Command failed with code %i (%s)."), -errcode, crypt_error );
} }
const char *uuid_or_device(const char *spec) const char *uuid_or_device(const char *spec)
{ {
static char device[PATH_MAX]; static char device[PATH_MAX];
char s, *ptr; char s, *ptr;
int i = 0, uuid_len = 5; int i = 0, uuid_len = 5;
/* Check if it is correct UUID=<LUKS_UUID> format */ /* Check if it is correct UUID=<LUKS_UUID> format */
if (spec && !strncmp(spec, "UUID=", uuid_len)) { if (spec && !strncmp(spec, "UUID=", uuid_len)) {
skipping to change at line 302 skipping to change at line 274
{ {
if (token < 0) if (token < 0)
return; return;
if (op == CREATED) if (op == CREATED)
log_verbose(_("Token %i created."), token); log_verbose(_("Token %i created."), token);
else if (op == REMOVED) else if (op == REMOVED)
log_verbose(_("Token %i removed."), token); log_verbose(_("Token %i removed."), token);
} }
void tools_token_error_msg(int error, const char *type, int token, bool pin_prov
ided)
{
if (error >= 0)
return;
if (error == -ENOANO) {
if (pin_provided)
log_verbose(_("No token could be unlocked with this PIN."
));
else if (token != CRYPT_ANY_TOKEN)
log_verbose(_("Token %i requires PIN."), token);
else if (type)
log_verbose(_("Token (type %s) requires PIN."), type);
} else if (error == -EPERM) {
if (token != CRYPT_ANY_TOKEN)
log_verbose(_("Token %i cannot unlock assigned keyslot(s)
(wrong keyslot passphrase)."), token);
else if (type)
log_verbose(_("Token (type %s) cannot unlock assigned key
slot(s) (wrong keyslot passphrase)."), type);
} if (error == -EAGAIN) {
if (token != CRYPT_ANY_TOKEN)
log_verbose(_("Token %i requires additional missing resou
rce."), token);
else if (type)
log_verbose(_("Token (type %s) requires additional missin
g resource."), type);
} if (error == -ENOENT) {
if (type)
log_verbose(_("No usable token (type %s) is available."),
type);
else
log_verbose(_("No usable token is available."));
}
}
/* /*
* Device size string parsing, suffixes: * Device size string parsing, suffixes:
* s|S - 512 bytes sectors * s|S - 512 bytes sectors
* k |K |m |M |g |G |t |T - 1024 base * k |K |m |M |g |G |t |T - 1024 base
* kiB|KiB|miB|MiB|giB|GiB|tiB|TiB - 1024 base * kiB|KiB|miB|MiB|giB|GiB|tiB|TiB - 1024 base
* kb |KB |mM |MB |gB |GB |tB |TB - 1000 base * kb |KB |mM |MB |gB |GB |tB |TB - 1000 base
*/ */
int tools_string_to_size(struct crypt_device *cd, const char *s, uint64_t *size) int tools_string_to_size(const char *s, uint64_t *size)
{ {
char *endp = NULL; char *endp = NULL;
size_t len; size_t len;
uint64_t mult_base, mult, tmp; uint64_t mult_base, mult, tmp;
*size = strtoull(s, &endp, 10); *size = strtoull(s, &endp, 10);
if (!isdigit(s[0]) || if (!isdigit(s[0]) ||
(errno == ERANGE && *size == ULLONG_MAX) || (errno == ERANGE && *size == ULLONG_MAX) ||
(errno != 0 && *size == 0)) (errno != 0 && *size == 0))
return -EINVAL; return -EINVAL;
skipping to change at line 376 skipping to change at line 378
/* Time progress helper */ /* Time progress helper */
/* The difference in seconds between two times in "timeval" format. */ /* The difference in seconds between two times in "timeval" format. */
static double time_diff(struct timeval *start, struct timeval *end) static double time_diff(struct timeval *start, struct timeval *end)
{ {
return (end->tv_sec - start->tv_sec) return (end->tv_sec - start->tv_sec)
+ (end->tv_usec - start->tv_usec) / 1E6; + (end->tv_usec - start->tv_usec) / 1E6;
} }
void tools_clear_line(void) static void tools_clear_line(void)
{ {
if (opt_progress_frequency)
return;
/* vt100 code clear line */ /* vt100 code clear line */
log_std("\33[2K\r"); log_std("\33[2K\r");
} }
static void tools_time_progress(uint64_t device_size, uint64_t bytes, uint64_t * static void tools_time_progress(uint64_t device_size, uint64_t bytes, struct too
start_bytes, ls_progress_params *parms)
struct timeval *start_time, struct timeval *end_time)
{ {
struct timeval now_time; struct timeval now_time;
unsigned long long mbytes, eta; unsigned long long mbytes, eta;
double tdiff, uib, frequency; double tdiff, uib, frequency;
int final = (bytes == device_size); int final = (bytes == device_size);
const char *eol, *ustr = ""; const char *eol, *ustr = "";
if (opt_batch_mode)
return;
gettimeofday(&now_time, NULL); gettimeofday(&now_time, NULL);
if (start_time->tv_sec == 0 && start_time->tv_usec == 0) { if (parms->start_time.tv_sec == 0 && parms->start_time.tv_usec == 0) {
*start_time = now_time; parms->start_time = now_time;
*end_time = now_time; parms->end_time = now_time;
*start_bytes = bytes; parms->start_offset = bytes;
return; return;
} }
if (opt_progress_frequency) { if (parms->frequency) {
frequency = (double)opt_progress_frequency; frequency = (double)parms->frequency;
eol = "\n"; eol = "\n";
} else { } else {
frequency = 0.5; frequency = 0.5;
eol = ""; eol = "";
} }
if (!final && time_diff(end_time, &now_time) < frequency) if (!final && time_diff(&parms->end_time, &now_time) < frequency)
return; return;
*end_time = now_time; parms->end_time = now_time;
tdiff = time_diff(start_time, end_time); tdiff = time_diff(&parms->start_time, &parms->end_time);
if (!tdiff) if (!tdiff)
return; return;
mbytes = bytes / 1024 / 1024; mbytes = bytes / 1024 / 1024;
uib = (double)(bytes - *start_bytes) / tdiff; uib = (double)(bytes - parms->start_offset) / tdiff;
/* FIXME: calculate this from last minute only. */
eta = (unsigned long long)(device_size / uib - tdiff); eta = (unsigned long long)(device_size / uib - tdiff);
if (uib > 1073741824.0f) { if (uib > 1073741824.0f) {
uib /= 1073741824.0f; uib /= 1073741824.0f;
ustr = "Gi"; ustr = "Gi";
} else if (uib > 1048576.0f) { } else if (uib > 1048576.0f) {
uib /= 1048576.0f; uib /= 1048576.0f;
ustr = "Mi"; ustr = "Mi";
} else if (uib > 1024.0f) { } else if (uib > 1024.0f) {
uib /= 1024.0f; uib /= 1024.0f;
ustr = "Ki"; ustr = "Ki";
} }
tools_clear_line(); if (!parms->frequency)
tools_clear_line();
if (final) if (final)
log_std("Finished, time %02llu:%02llu.%03llu, " log_std("Finished, time %02llu:%02llu.%03llu, "
"%4llu MiB written, speed %5.1f %sB/s\n", "%4llu MiB written, speed %5.1f %sB/s\n",
(unsigned long long)tdiff / 60, (unsigned long long)tdiff / 60,
(unsigned long long)tdiff % 60, (unsigned long long)tdiff % 60,
(unsigned long long)((tdiff - floor(tdiff)) * 1000.0), (unsigned long long)((tdiff - floor(tdiff)) * 1000.0),
mbytes, uib, ustr); mbytes, uib, ustr);
else else
log_std("Progress: %5.1f%%, ETA %02llu:%02llu, " log_std("Progress: %5.1f%%, ETA %02llu:%02llu, "
"%4llu MiB written, speed %5.1f %sB/s%s", "%4llu MiB written, speed %5.1f %sB/s%s",
(double)bytes / device_size * 100, (double)bytes / device_size * 100,
eta / 60, eta % 60, mbytes, uib, ustr, eol); eta / 60, eta % 60, mbytes, uib, ustr, eol);
fflush(stdout); fflush(stdout);
} }
int tools_wipe_progress(uint64_t size, uint64_t offset, void *usrptr) int tools_wipe_progress(uint64_t size, uint64_t offset, void *usrptr)
{ {
static struct timeval start_time = {}, end_time = {};
static uint64_t start_offset = 0;
int r = 0; int r = 0;
struct tools_progress_params *parms = (struct tools_progress_params *)usr ptr;
tools_time_progress(size, offset, &start_offset, &start_time, &end_time); if (parms && !parms->batch_mode)
tools_time_progress(size, offset, parms);
check_signal(&r); check_signal(&r);
if (r) { if (r) {
tools_clear_line(); if (!parms || !parms->frequency)
tools_clear_line();
log_err(_("\nWipe interrupted.")); log_err(_("\nWipe interrupted."));
} }
return r; return r;
} }
static void report_partition(const char *value, const char *device)
{
if (opt_batch_mode)
log_dbg("Device %s already contains a '%s' partition signature.",
device, value);
else
log_std(_("WARNING: Device %s already contains a '%s' partition s
ignature.\n"), device, value);
}
static void report_superblock(const char *value, const char *device)
{
if (opt_batch_mode)
log_dbg("Device %s already contains a '%s' superblock signature."
, device, value);
else
log_std(_("WARNING: Device %s already contains a '%s' superblock
signature.\n"), device, value);
}
int tools_detect_signatures(const char *device, int ignore_luks, size_t *count)
{
int r;
size_t tmp_count;
struct blkid_handle *h;
blk_probe_status pr;
if (!count)
count = &tmp_count;
*count = 0;
if (!blk_supported()) {
log_dbg("Blkid support disabled.");
return 0;
}
if ((r = blk_init_by_path(&h, device))) {
log_err(_("Failed to initialize device signature probes."));
return -EINVAL;
}
blk_set_chains_for_full_print(h);
if (ignore_luks && blk_superblocks_filter_luks(h)) {
r = -EINVAL;
goto out;
}
while ((pr = blk_probe(h)) < PRB_EMPTY) {
if (blk_is_partition(h))
report_partition(blk_get_partition_type(h), device);
else if (blk_is_superblock(h))
report_superblock(blk_get_superblock_type(h), device);
else {
log_dbg("Internal tools_detect_signatures() error.");
r = -EINVAL;
goto out;
}
(*count)++;
}
if (pr == PRB_FAIL)
r = -EINVAL;
out:
blk_free(h);
return r;
}
int tools_wipe_all_signatures(const char *path)
{
int fd, flags, r;
blk_probe_status pr;
struct stat st;
struct blkid_handle *h = NULL;
if (!blk_supported()) {
log_dbg("Blkid support disabled.");
return 0;
}
if (stat(path, &st)) {
log_err(_("Failed to stat device %s."), path);
return -EINVAL;
}
flags = O_RDWR;
if (S_ISBLK(st.st_mode))
flags |= O_EXCL;
/* better than opening regular file with O_EXCL (undefined) */
/* coverity[toctou] */
fd = open(path, flags);
if (fd < 0) {
if (errno == EBUSY)
log_err(_("Device %s is in use. Can not proceed with form
at operation."), path);
else
log_err(_("Failed to open file %s in read/write mode."),
path);
return -EINVAL;
}
if ((r = blk_init_by_fd(&h, fd))) {
log_err(_("Failed to initialize device signature probes."));
r = -EINVAL;
goto out;
}
blk_set_chains_for_wipes(h);
while ((pr = blk_probe(h)) < PRB_EMPTY) {
if (blk_is_partition(h))
log_verbose(_("Existing '%s' partition signature (offset:
%" PRIi64 " bytes) on device %s will be wiped."),
blk_get_partition_type(h), blk_get_offset(h),
path);
if (blk_is_superblock(h))
log_verbose(_("Existing '%s' superblock signature (offset
: %" PRIi64 " bytes) on device %s will be wiped."),
blk_get_superblock_type(h), blk_get_offset(h)
, path);
if (blk_do_wipe(h)) {
log_err(_("Failed to wipe device signature."));
r = -EINVAL;
goto out;
}
}
if (pr != PRB_EMPTY) {
log_err(_("Failed to probe device %s for a signature."), path);
r = -EINVAL;
}
out:
close(fd);
blk_free(h);
return r;
}
/* /*
* Keyfile - is standard input treated as a binary file (no EOL handling). * Keyfile - is standard input treated as a binary file (no EOL handling).
*/ */
int tools_is_stdin(const char *key_file) int tools_is_stdin(const char *key_file)
{ {
if (!key_file) if (!key_file)
return 1; return 1;
return strcmp(key_file, "-") ? 0 : 1; return strcmp(key_file, "-") ? 0 : 1;
} }
int tools_reencrypt_progress(uint64_t size, uint64_t offset, void *usrptr) int tools_reencrypt_progress(uint64_t size, uint64_t offset, void *usrptr)
{ {
static struct timeval start_time = {}, end_time = {};
static uint64_t start_offset = 0;
int r = 0; int r = 0;
struct tools_progress_params *parms = (struct tools_progress_params *)usr ptr;
tools_time_progress(size, offset, &start_offset, &start_time, &end_time); if (parms && !parms->batch_mode)
tools_time_progress(size, offset, parms);
check_signal(&r); check_signal(&r);
if (r) { if (r) {
tools_clear_line(); if (!parms || !parms->frequency)
tools_clear_line();
log_err(_("\nReencryption interrupted.")); log_err(_("\nReencryption interrupted."));
} }
return r; return r;
} }
 End of changes. 33 change blocks. 
211 lines changed or deleted 77 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)