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;
_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)))
#endif
if (level == CRYPT_LOG_ERROR)
- set_global_error(target);
+ crypt_set_error(cd, target);
}
va_end(argp);
cd->password_usrptr = usrptr;
}
-/* Deprecated global error interface */
-void crypt_get_error(char *buf, size_t size)
+static void _get_error(char *error, char *buf, size_t size)
{
if (!buf || size < 1)
- global_error[0] = '\0';
- else if (*global_error) {
- strncpy(buf, global_error, size - 1);
+ error[0] = '\0';
+ else if (*error) {
+ strncpy(buf, error, size - 1);
buf[size - 1] = '\0';
- global_error[0] = '\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)
+{
+ return _get_error(global_error, buf, size);
+}
+
const char *crypt_get_dir(void)
{
return dm_get_dir();
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();
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__); \
#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,
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));
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);
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);
}