25 #include <sys/mount.h>
29 #include <libcryptsetup.h>
31 #include <QDataStream>
32 #include <QTextStream>
34 #include <QLatin1Char>
42 #define SIGNON_LUKS_DEFAULT_HASH "ripemd160"
44 #define SIGNON_LUKS_CIPHER_NAME "aes"
45 #define SIGNON_LUKS_CIPHER_MODE "xts-plain"
46 #define SIGNON_LUKS_CIPHER \
47 SIGNON_LUKS_CIPHER_NAME "-" SIGNON_LUKS_CIPHER_MODE
48 #define SIGNON_LUKS_KEY_SIZE 256
49 #define SIGNON_LUKS_BASE_KEYSLOT 0
51 #define SIGNON_EXTERNAL_PROCESS_READ_TIMEOUT 300
53 #define KILO_BYTE_SIZE 1024
54 #define MEGA_BYTE_SIZE (KILO_BYTE_SIZE * 1024)
60 connect(&m_process, SIGNAL(error(QProcess::ProcessError)),
61 this, SLOT(error(QProcess::ProcessError)));
69 const QStringList &args,
73 QTextStream stream(&trace);
74 stream << appPath << QLatin1Char(
' ') << args.join(QLatin1String(
" "));
77 m_process.start(appPath, args);
78 if (!m_process.waitForStarted()) {
79 BLAME() <<
"Wait for started failed";
87 if (!m_process.bytesAvailable()) {
88 BLAME() <<
"Coult not read output of external process ";
92 while(m_process.bytesAvailable())
93 m_output += m_process.readAllStandardOutput();
97 if (!m_process.waitForFinished()) {
98 TRACE() <<
"Wait for finished failed";
105 void SystemCommandLineCallHandler::error(QProcess::ProcessError err)
107 TRACE() <<
"Process erorr:" << err;
114 const quint32 fileSize)
116 int fd = open(fileName.toLatin1().data(),
121 BLAME() <<
"FAILED to create signon secure FS partition file. ERRNO:"
127 BLAME() <<
"FAILED to set signon secure FS partition file size. ERRNO:"
133 TRACE() <<
"Failed to close secure FS partition file after creation.";
136 TRACE() <<
"Failed to set file permissions "
137 "for the secure storage container.";
143 const quint32 fileSystemType)
145 QString mkfsApp = QString::fromLatin1(
"/sbin/mkfs.ext2");
146 switch (fileSystemType) {
147 case Ext2: mkfsApp = QString::fromLatin1(
"/sbin/mkfs.ext2");
break;
148 case Ext3: mkfsApp = QString::fromLatin1(
"/sbin/mkfs.ext3");
break;
149 case Ext4: mkfsApp = QString::fromLatin1(
"/sbin/mkfs.ext4");
break;
156 QStringList() << fileName);
163 const QString &mountPath,
164 const QString &fileSystemTtpe)
167 return (::
mount(toMount.toUtf8().constData(),
168 mountPath.toUtf8().constData(),
169 fileSystemTtpe.toUtf8().constData(),
170 MS_SYNCHRONOUS | MS_NOEXEC, NULL) == 0);
179 TRACE() << mountPath.toUtf8().constData();
180 int ret = ::umount2(mountPath.toUtf8().constData(), MNT_FORCE);
184 case EAGAIN:
TRACE() <<
"EAGAIN";
break;
185 case EBUSY:
TRACE() <<
"EBUSY";
break;
186 case EFAULT:
TRACE() <<
"EFAULT";
break;
187 case EINVAL:
TRACE() <<
"EINVAL";
break;
188 case ENAMETOOLONG:
TRACE() <<
"ENAMETOOLONG";
break;
189 case ENOENT:
TRACE() <<
"ENOENT";
break;
190 case ENOMEM:
TRACE() <<
"ENOMEM";
break;
191 case EPERM:
TRACE() <<
"EPERM";
break;
192 default:
TRACE() <<
"umount unknown error - ignoring.";
204 const QString &blockDevice)
208 QLatin1String(
"/sbin/losetup"),
209 QStringList() << deviceName << blockDevice);
217 QLatin1String(
"/sbin/losetup"),
218 QStringList() << QLatin1String(
"-f"),
221 deviceName = QString::fromLocal8Bit(handler.
output().trimmed());
232 return handler.
makeCall(QLatin1String(
"/sbin/losetup"),
234 QString::fromLatin1(
"-d") << deviceName);
242 static int yesDialog(
char *msg)
248 static void cmdLineLog(
int type,
char *msg)
251 case CRYPT_LOG_NORMAL:
254 case CRYPT_LOG_ERROR:
255 TRACE() <<
"Error: " << msg;
258 TRACE() <<
"Internal error on logging class for msg: " << msg;
263 static void log_wrapper(
int level,
const char *msg,
void *usrptr)
265 void (*xlog)(
int level,
char *msg) = (
void (*)(int,
char*)) usrptr;
266 xlog(level, (
char *)msg);
269 static int yesDialog_wrapper(
const char *msg,
void *usrptr)
271 int (*xyesDialog)(
char *msg) = (
int (*)(
char*)) usrptr;
272 return xyesDialog((
char*)msg);
279 struct crypt_device *cd = NULL;
280 struct crypt_params_luks1 cp = {
282 options->align_payload
286 if ((r = crypt_init(&cd, options->device)))
289 crypt_set_log_callback(cd, log_wrapper, (
void*) options->icb->log);
290 crypt_set_confirm_callback(cd, yesDialog_wrapper,
291 (
void*) options->icb->yesDialog);
293 crypt_set_timeout(cd, options->timeout);
294 crypt_set_password_retry(cd, options->tries);
295 crypt_set_iterarion_time(cd, options->iteration_time ?: 1000);
296 crypt_set_password_verify(cd, options->flags & CRYPT_FLAG_VERIFY);
298 r = crypt_format(cd, CRYPT_LUKS1,
300 NULL, NULL, options->key_size, &cp);
305 r = crypt_keyslot_add_by_volume_key(cd, options->key_slot, NULL, 0,
309 return (r < 0) ? r : 0;
314 const QString &deviceName)
316 struct crypt_options options;
321 char *localDeviceName = (
char *)malloc(deviceName.length() + 1);
322 Q_ASSERT(localDeviceName != NULL);
324 strcpy(localDeviceName, deviceName.toLatin1().constData());
325 options.device = localDeviceName;
328 options.new_key_file = NULL;
330 char *localKey = (
char *)malloc(key.length());
331 Q_ASSERT(localKey != NULL);
332 memcpy(localKey, key.constData(), key.length());
335 options.iteration_time = 1000;
337 options.align_payload = 0;
339 static struct interface_callbacks cmd_icb;
340 cmd_icb.yesDialog = 0;
342 options.icb = &cmd_icb;
344 TRACE() <<
"Device: [" << options.device <<
"]";
345 TRACE() <<
"Key size:" << key.length();
350 TRACE() <<
"LUKS format API call result:" << ret <<
"." <<
error();
353 free(localDeviceName);
356 memset(localKey, 0x00, key.length());
364 const char *pwd,
unsigned int pwdLen)
366 struct crypt_device *cd = NULL;
370 if ((r = crypt_init(&cd, options->device)))
373 crypt_set_log_callback(cd, log_wrapper, (
void*) options->icb->log);
374 crypt_set_confirm_callback(cd, yesDialog_wrapper,
375 (
void*) options->icb->yesDialog);
377 crypt_set_timeout(cd, options->timeout);
378 crypt_set_password_retry(cd, options->tries);
379 crypt_set_iterarion_time(cd, options->iteration_time ?: 1000);
380 crypt_set_password_verify(cd, options->flags & CRYPT_FLAG_VERIFY);
382 if ((r = crypt_load(cd, CRYPT_LUKS1, NULL))) {
387 if (options->flags & CRYPT_FLAG_READONLY)
388 flags |= CRYPT_ACTIVATE_READONLY;
390 if (options->flags & CRYPT_FLAG_NON_EXCLUSIVE_ACCESS)
391 flags |= CRYPT_ACTIVATE_NO_UUID;
393 if (options->key_file)
396 r = crypt_activate_by_passphrase(cd, options->name,
401 return (r < 0) ? r : 0;
405 const QString &deviceName,
406 const QString &deviceMap)
408 struct crypt_options options;
410 char *localDeviceMap = (
char *)malloc(deviceMap.length() + 1);
411 Q_ASSERT(localDeviceMap != NULL);
412 strcpy(localDeviceMap, deviceMap.toLatin1().constData());
413 options.name = localDeviceMap;
415 char *localDeviceName = (
char *)malloc(deviceName.length() + 1);
416 Q_ASSERT(localDeviceName != NULL);
417 strcpy(localDeviceName, deviceName.toLatin1().constData());
418 options.device = localDeviceName;
420 char *localKey = (
char *)malloc(key.length());
421 Q_ASSERT(localKey != NULL);
422 memcpy(localKey, key.constData(), key.length());
424 options.key_file = NULL;
436 static struct interface_callbacks cmd_icb;
437 cmd_icb.yesDialog = yesDialog;
438 cmd_icb.log = cmdLineLog;
439 options.icb = &cmd_icb;
441 TRACE() <<
"Device [" << options.device <<
"]";
442 TRACE() <<
"Map name [" << options.name <<
"]";
443 TRACE() <<
"Key size:" << key.length();
448 TRACE() <<
"LUKS open API call result:" << ret <<
"." <<
error() <<
".";
451 free(localDeviceName);
454 free(localDeviceMap);
457 memset(localKey, 0x00, key.length());
466 struct crypt_options options;
468 char *localDeviceMap = (
char *)malloc(deviceMap.length() + 1);
469 Q_ASSERT(localDeviceMap != NULL);
470 strcpy(localDeviceMap, deviceMap.toLatin1().constData());
471 options.name = localDeviceMap;
473 static struct interface_callbacks cmd_icb;
474 cmd_icb.yesDialog = yesDialog;
475 cmd_icb.log = cmdLineLog;
476 options.icb = &cmd_icb;
478 TRACE() <<
"Map name [" << options.name <<
"]";
480 int ret = crypt_remove_device(&options);
483 TRACE() <<
"Cryptsetup remove API call result:" << ret <<
487 free(localDeviceMap);
494 Q_UNUSED(deviceName);
500 const char *pwd,
unsigned int pwdLen,
501 const char *newPwd,
unsigned int newPwdLen)
503 struct crypt_device *cd = NULL;
506 if ((r = crypt_init(&cd, options->device)))
509 crypt_set_log_callback(cd, log_wrapper, (
void*) options->icb->log);
510 crypt_set_confirm_callback(cd, yesDialog_wrapper,
511 (
void*) options->icb->yesDialog);
513 crypt_set_timeout(cd, options->timeout);
514 crypt_set_password_retry(cd, options->tries);
515 crypt_set_iterarion_time(cd, options->iteration_time ?: 1000);
516 crypt_set_password_verify(cd, options->flags & CRYPT_FLAG_VERIFY);
518 if ((r = crypt_load(cd, CRYPT_LUKS1, NULL))) {
523 if (options->key_file || options->new_key_file)
526 r = crypt_keyslot_add_by_passphrase(cd, options->key_slot,
527 pwd, pwdLen, newPwd, newPwdLen);
530 return (r < 0) ? r : 0;
534 const QByteArray &key,
535 const QByteArray &existingKey)
537 struct crypt_options options;
542 char *localDeviceName = (
char *)malloc(deviceName.length() + 1);
543 Q_ASSERT(localDeviceName != NULL);
544 strcpy(localDeviceName, deviceName.toLatin1().constData());
546 options.device = localDeviceName;
547 options.new_key_file = NULL;
548 options.key_file = NULL;
549 options.key_slot = -1;
552 options.iteration_time = 1000;
556 static struct interface_callbacks cmd_icb;
557 cmd_icb.yesDialog = yesDialog;
558 cmd_icb.log = cmdLineLog;
559 options.icb = &cmd_icb;
562 existingKey.constData(),
563 existingKey.length(),
564 key.constData(), key.length());
567 free(localDeviceName);
570 TRACE() <<
"Cryptsetup add key API call result:" << ret <<
577 const char *pwdToRemove,
578 unsigned int pwdToRemoveLen)
580 struct crypt_device *cd = NULL;
584 if ((r = crypt_init(&cd, options->device)))
587 crypt_set_log_callback(cd, log_wrapper, (
void*) options->icb->log);
588 crypt_set_confirm_callback(cd, yesDialog_wrapper,
589 (
void*) options->icb->yesDialog);
591 crypt_set_timeout(cd, options->timeout);
592 crypt_set_password_retry(cd, options->tries);
593 crypt_set_iterarion_time(cd, options->iteration_time ?: 1000);
594 crypt_set_password_verify(cd, options->flags & CRYPT_FLAG_VERIFY);
596 if ((r = crypt_load(cd, CRYPT_LUKS1, NULL))) {
601 if ((key_slot = crypt_keyslot_by_passphrase(cd, NULL, pwdToRemove,
602 pwdToRemoveLen, 0, NULL)) < 0) {
607 r = crypt_keyslot_destroy(cd, key_slot);
611 return (r < 0) ? r : 0;
615 const QByteArray &key,
616 const QByteArray &remainingKey)
618 struct crypt_options options;
623 char *localDeviceName = (
char *)malloc(deviceName.length() + 1);
624 Q_ASSERT(localDeviceName != NULL);
625 strcpy(localDeviceName, deviceName.toLatin1().constData());
627 options.device = localDeviceName;
628 options.new_key_file = NULL;
629 options.key_file = NULL;
630 options.key_slot = -1;
635 static struct interface_callbacks cmd_icb;
636 cmd_icb.yesDialog = yesDialog;
637 cmd_icb.log = cmdLineLog;
638 options.icb = &cmd_icb;
643 free(localDeviceName);
646 TRACE() <<
"Cryptsetup remove key API call result:" << ret <<
656 QLatin1String(
"/sbin/modprobe"),
657 QStringList() << QString::fromLatin1(
"dm_mod"));
663 crypt_get_error(buf, 256);
664 return QString::fromLocal8Bit(buf);