mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-05 16:00:05 +01:00
Add crypt_last_error() API call (using crypt context).
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@623 36d66b0a-2a48-0410-832c-cd162a569da5
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
2011-10-05 Milan Broz <mbroz@redhat.com>
|
||||
* Support Nettle 2.4 crypto backend (for ripemd160).
|
||||
* If device is not rotational, do not use Gutmann wipe method.
|
||||
* Add crypt_last_error() API call.
|
||||
|
||||
2011-09-22 Milan Broz <mbroz@redhat.com>
|
||||
* Support key-slot option for luksOpen (use only explicit keyslot).
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#define SECTOR_SIZE (1 << SECTOR_SHIFT)
|
||||
#define DEFAULT_DISK_ALIGNMENT 1048576 /* 1MiB */
|
||||
#define DEFAULT_MEM_ALIGNMENT 4096
|
||||
#define MAX_ERROR_LENGTH 512
|
||||
|
||||
#define at_least(a, b) ({ __typeof__(a) __at_least = (a); (__at_least >= (b))?__at_least:(b); })
|
||||
|
||||
|
||||
@@ -882,6 +882,18 @@ int crypt_header_restore(struct crypt_device *cd,
|
||||
/**
|
||||
* Receives last reported error
|
||||
*
|
||||
* @param cd crypt device handle
|
||||
* @param buf buffef for message
|
||||
* @param size size of buffer
|
||||
*
|
||||
* @note Note that this is old API function using global context.
|
||||
* All error messages are reported also through log callback.
|
||||
*/
|
||||
void crypt_last_error(struct crypt_device *cd, char *buf, size_t size);
|
||||
|
||||
/**
|
||||
* Receives last reported error, DEPRECATED
|
||||
*
|
||||
* @param buf buffef for message
|
||||
* @param size size of buffer
|
||||
*
|
||||
|
||||
@@ -50,6 +50,7 @@ CRYPTSETUP_1.0 {
|
||||
|
||||
crypt_keyslot_max;
|
||||
crypt_keyslot_status;
|
||||
crypt_last_error;
|
||||
crypt_get_error;
|
||||
crypt_get_dir;
|
||||
crypt_set_debug_level;
|
||||
|
||||
49
lib/setup.c
49
lib/setup.c
@@ -71,11 +71,14 @@ struct crypt_device {
|
||||
void *confirm_usrptr;
|
||||
int (*password)(const char *msg, char *buf, size_t length, void *usrptr);
|
||||
void *password_usrptr;
|
||||
|
||||
/* last error message */
|
||||
char error[MAX_ERROR_LENGTH];
|
||||
};
|
||||
|
||||
/* Global error */
|
||||
/* FIXME: not thread safe, remove this later */
|
||||
static char global_error[512] = {0};
|
||||
static char global_error[MAX_ERROR_LENGTH] = {0};
|
||||
|
||||
/* Log helper */
|
||||
static void (*_default_log)(int level, const char *msg, void *usrptr) = NULL;
|
||||
@@ -100,14 +103,21 @@ void crypt_log(struct crypt_device *cd, int level, const char *msg)
|
||||
_default_log(level, msg, NULL);
|
||||
}
|
||||
|
||||
/* Set global error, ugly hack... */
|
||||
void set_global_error(const char *error)
|
||||
static void crypt_set_error(struct crypt_device *cd, const char *error)
|
||||
{
|
||||
size_t size = strlen(error);
|
||||
|
||||
strncpy(global_error, error, sizeof(global_error) - 2);
|
||||
if (size < sizeof(global_error) && global_error[size - 1] == '\n')
|
||||
/* Set global error, ugly hack... */
|
||||
strncpy(global_error, error, MAX_ERROR_LENGTH - 2);
|
||||
if (size < MAX_ERROR_LENGTH && global_error[size - 1] == '\n')
|
||||
global_error[size - 1] = '\0';
|
||||
|
||||
/* Set error string per context */
|
||||
if (cd) {
|
||||
strncpy(cd->error, error, MAX_ERROR_LENGTH - 2);
|
||||
if (size < MAX_ERROR_LENGTH && cd->error[size - 1] == '\n')
|
||||
cd->error[size - 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((format(printf, 5, 6)))
|
||||
@@ -131,7 +141,7 @@ void logger(struct crypt_device *cd, int level, const char *file,
|
||||
#endif
|
||||
|
||||
if (level == CRYPT_LOG_ERROR)
|
||||
set_global_error(target);
|
||||
crypt_set_error(cd, target);
|
||||
}
|
||||
|
||||
va_end(argp);
|
||||
@@ -429,17 +439,28 @@ void crypt_set_password_callback(struct crypt_device *cd,
|
||||
cd->password_usrptr = usrptr;
|
||||
}
|
||||
|
||||
static void _get_error(char *error, char *buf, size_t size)
|
||||
{
|
||||
if (!buf || size < 1)
|
||||
error[0] = '\0';
|
||||
else if (*error) {
|
||||
strncpy(buf, error, size - 1);
|
||||
buf[size - 1] = '\0';
|
||||
error[0] = '\0';
|
||||
} else
|
||||
buf[0] = '\0';
|
||||
}
|
||||
|
||||
void crypt_last_error(struct crypt_device *cd, char *buf, size_t size)
|
||||
{
|
||||
if (cd)
|
||||
return _get_error(cd->error, buf, size);
|
||||
}
|
||||
|
||||
/* Deprecated global error interface */
|
||||
void crypt_get_error(char *buf, size_t size)
|
||||
{
|
||||
if (!buf || size < 1)
|
||||
global_error[0] = '\0';
|
||||
else if (*global_error) {
|
||||
strncpy(buf, global_error, size - 1);
|
||||
buf[size - 1] = '\0';
|
||||
global_error[0] = '\0';
|
||||
} else
|
||||
buf[0] = '\0';
|
||||
return _get_error(global_error, buf, size);
|
||||
}
|
||||
|
||||
const char *crypt_get_dir(void)
|
||||
|
||||
@@ -441,24 +441,24 @@ static int _setup(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void check_ok(int status, int line, const char *func)
|
||||
void check_ok(struct crypt_device *cd, int status, int line, const char *func)
|
||||
{
|
||||
char buf[256];
|
||||
|
||||
if (status) {
|
||||
crypt_get_error(buf, sizeof(buf));
|
||||
crypt_last_error(cd, buf, sizeof(buf));
|
||||
printf("FAIL line %d [%s]: code %d, %s\n", line, func, status, buf);
|
||||
_cleanup();
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
void check_ko(int status, int line, const char *func)
|
||||
void check_ko(struct crypt_device *cd, int status, int line, const char *func)
|
||||
{
|
||||
char buf[256];
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
crypt_get_error(buf, sizeof(buf));
|
||||
crypt_last_error(cd, buf, sizeof(buf));
|
||||
if (status >= 0) {
|
||||
printf("FAIL line %d [%s]: code %d, %s\n", line, func, status, buf);
|
||||
_cleanup();
|
||||
@@ -483,11 +483,13 @@ void xlog(const char *msg, const char *tst, const char *func, int line, const ch
|
||||
printf(" [%s,%s:%d] %s\n", msg, func, line, tst);
|
||||
}
|
||||
}
|
||||
|
||||
/* crypt_device context must be "cd" to parse error properly here */
|
||||
#define OK_(x) do { xlog("(success)", #x, __FUNCTION__, __LINE__, NULL); \
|
||||
check_ok((x), __LINE__, __FUNCTION__); \
|
||||
check_ok(cd, (x), __LINE__, __FUNCTION__); \
|
||||
} while(0)
|
||||
#define FAIL_(x, y) do { xlog("(fail) ", #x, __FUNCTION__, __LINE__, y); \
|
||||
check_ko((x), __LINE__, __FUNCTION__); \
|
||||
check_ko(cd, (x), __LINE__, __FUNCTION__); \
|
||||
} while(0)
|
||||
#define EQ_(x, y) do { xlog("(equal) ", #x " == " #y, __FUNCTION__, __LINE__, NULL); \
|
||||
if ((x) != (y)) check_equal(__LINE__, __FUNCTION__); \
|
||||
@@ -495,11 +497,9 @@ void xlog(const char *msg, const char *tst, const char *func, int line, const ch
|
||||
|
||||
#define RUN_(x, y) do { printf("%s: %s\n", #x, (y)); x(); } while (0)
|
||||
|
||||
// NEW API tests
|
||||
|
||||
static void AddDevicePlain(void)
|
||||
{
|
||||
struct crypt_device *cd, *cd2;
|
||||
struct crypt_device *cd;
|
||||
struct crypt_params_plain params = {
|
||||
.hash = "sha1",
|
||||
.skip = 0,
|
||||
@@ -654,11 +654,12 @@ static void AddDevicePlain(void)
|
||||
OK_(crypt_init(&cd,DEVICE_1));
|
||||
OK_(crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode, NULL, NULL, key_size, ¶ms));
|
||||
OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0));
|
||||
FAIL_(crypt_init_by_name_and_header(&cd2, CDEVICE_1, H_DEVICE),"can't init plain device by header device");
|
||||
OK_(crypt_init_by_name(&cd2,CDEVICE_1));
|
||||
OK_(crypt_deactivate(cd,CDEVICE_1));
|
||||
crypt_free(cd);
|
||||
crypt_free(cd2);
|
||||
|
||||
FAIL_(crypt_init_by_name_and_header(&cd, CDEVICE_1, H_DEVICE),"can't init plain device by header device");
|
||||
OK_(crypt_init_by_name(&cd, CDEVICE_1));
|
||||
OK_(crypt_deactivate(cd, CDEVICE_1));
|
||||
crypt_free(cd);
|
||||
|
||||
OK_(crypt_init(&cd,DEVICE_1));
|
||||
OK_(crypt_format(cd,CRYPT_PLAIN,cipher,cipher_mode,NULL,NULL,key_size,¶ms));
|
||||
@@ -812,6 +813,7 @@ static void CallbacksTest(void)
|
||||
char *cipher = "aes";
|
||||
char *cipher_mode = "cbc-essiv:sha256";
|
||||
char *passphrase = PASSPHRASE;
|
||||
char buf1[256] = {0}, buf2[256] = {0};
|
||||
|
||||
OK_(crypt_init(&cd, DEVICE_1));
|
||||
crypt_set_log_callback(cd, &new_log, NULL);
|
||||
@@ -833,6 +835,22 @@ static void CallbacksTest(void)
|
||||
EQ_(crypt_status(cd, CDEVICE_1), CRYPT_ACTIVE);
|
||||
OK_(crypt_deactivate(cd, CDEVICE_1));
|
||||
|
||||
// Check error reporting.
|
||||
// This must fail and create error message
|
||||
crypt_deactivate(cd, CDEVICE_1);
|
||||
|
||||
// Here context must be the same
|
||||
crypt_get_error(buf1, sizeof(buf1));
|
||||
crypt_last_error(cd, buf2, sizeof(buf2));
|
||||
OK_(!*buf1);
|
||||
OK_(!*buf2);
|
||||
OK_(strcmp(buf1, buf2));
|
||||
|
||||
crypt_get_error(buf1, sizeof(buf1));
|
||||
crypt_last_error(cd, buf2, sizeof(buf2));
|
||||
OK_(*buf1);
|
||||
OK_(*buf2);
|
||||
|
||||
crypt_free(cd);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user