summaryrefslogtreecommitdiffabout
authorzautrix <zautrix>2004-10-23 17:05:41 (UTC)
committer zautrix <zautrix>2004-10-23 17:05:41 (UTC)
commit13d274c37baaae48a1c93081077cf3035459c6a8 (patch) (side-by-side diff)
treecf49d1c5bec1fb4cd8bbd7fc9a007304634676a8
parentfbdad188bd7048148cc60c90325efcccb0417060 (diff)
downloadkdepimpi-13d274c37baaae48a1c93081077cf3035459c6a8.zip
kdepimpi-13d274c37baaae48a1c93081077cf3035459c6a8.tar.gz
kdepimpi-13d274c37baaae48a1c93081077cf3035459c6a8.tar.bz2
made pwm compile on windows. now the cryptolibs are still missing
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--pwmanager/pwmanager/blowfish.h11
-rw-r--r--pwmanager/pwmanager/gpasmanfile.cpp16
-rw-r--r--pwmanager/pwmanager/htmlgen.cpp2
-rw-r--r--pwmanager/pwmanager/ipc.cpp7
-rw-r--r--pwmanager/pwmanager/ipc.h5
-rw-r--r--pwmanager/pwmanager/libgcryptif.h7
-rw-r--r--pwmanager/pwmanager/pwm.cpp1
-rw-r--r--pwmanager/pwmanager/pwmanager.pro2
-rw-r--r--pwmanager/pwmanager/pwmdoc.cpp9
-rw-r--r--pwmanager/pwmanager/spinforsignal.h2
10 files changed, 50 insertions, 12 deletions
diff --git a/pwmanager/pwmanager/blowfish.h b/pwmanager/pwmanager/blowfish.h
index c05de77..5129eab 100644
--- a/pwmanager/pwmanager/blowfish.h
+++ b/pwmanager/pwmanager/blowfish.h
@@ -1,120 +1,129 @@
/***************************************************************************
* *
* copyright (C) 2003, 2004 by Michael Buesch *
* email: mbuesch@freenet.de *
* *
* blowfish.c - Blowfish encryption *
* Copyright (C) 1998, 2001, 2002 Free Software Foundation, Inc. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 *
* as published by the Free Software Foundation. *
* *
***************************************************************************/
/***************************************************************************
* copyright (C) 2004 by Ulf Schenk
* This file is originaly based on version 1.0.1 of pwmanager
* and was modified to run on embedded devices that run microkde
*
* $Id$
**************************************************************************/
#ifndef BLOWFISH_H
#define BLOWFISH_H
#include "pwmexception.h"
-
+#ifndef _WIN32_
#include <stdint.h>
+#else
+
+#endif
#include <string>
using std::string;
#define BLOWFISH_BLOCKSIZE 8
#define BLOWFISH_ROUNDS 16
#define CIPHER_ALGO_BLOWFISH 4 /* blowfish 128 bit key */
+#ifndef _WIN32_
typedef uint8_t byte;
+#else
+#define uint8_t Q_UINT8
+#define byte Q_UINT8
+#define uint32_t Q_UINT32
+#endif
/** blowfish encryption algorithm.
* Derived from libgcrypt-1.1.12
*/
class Blowfish
{
struct BLOWFISH_context
{
uint32_t s0[256];
uint32_t s1[256];
uint32_t s2[256];
uint32_t s3[256];
uint32_t p[BLOWFISH_ROUNDS+2];
};
public:
Blowfish() {}
static bool selfTest();
/** set key to encrypt. if return == 1, it is a weak key. */
int bf_setkey( byte *key, unsigned int keylen );
/** encrypt inbuf and return it in outbuf.
* inbuf and outbuf have to be: buf % 8 == 0
* You may check this with getPaddedLen() and pad with NULL.
*/
int bf_encrypt( byte *outbuf, byte *inbuf, unsigned int inbuf_len );
/** decrypt inbuf and return it in outbuf.
* inbuf and outbuf have to be: buf % 8 == 0
* You may check this with getPaddedLen() and pad with NULL.
*/
int bf_decrypt( byte *outbuf, byte *inbuf, unsigned int inbuf_len );
/** returns the length, the sting has to be padded to */
static unsigned int getPaddedLen(unsigned int inLen)
{ return ((8 - (inLen % 8)) + inLen); }
/** pad up to 8 bytes. */
static void padNull(string *buf);
/** remove padded data */
static bool unpadNull(string *buf);
protected:
#if BLOWFISH_ROUNDS != 16
uint32_t function_F( uint32_t x)
{
uint16_t a, b, c, d;
#ifdef BIG_ENDIAN_HOST
a = ((byte *) & x)[0];
b = ((byte *) & x)[1];
c = ((byte *) & x)[2];
d = ((byte *) & x)[3];
#else
a = ((byte *) & x)[3];
b = ((byte *) & x)[2];
c = ((byte *) & x)[1];
d = ((byte *) & x)[0];
#endif
return ((bc.s0[a] + bc.s1[b]) ^ bc.s2[c]) + bc.s3[d];
}
#endif
void R(uint32_t &l, uint32_t &r, uint32_t i, uint32_t *p,
uint32_t *s0, uint32_t *s1, uint32_t *s2, uint32_t *s3)
{
l ^= p[i];
#ifdef BIG_ENDIAN_HOST
r ^= (( s0[((byte*)&l)[0]] + s1[((byte*)&l)[1]])
^ s2[((byte*)&l)[2]]) + s3[((byte*)&l)[3]];
#else
r ^= (( s0[((byte*)&l)[3]] + s1[((byte*)&l)[2]])
^ s2[((byte*)&l)[1]]) + s3[((byte*)&l)[0]];
#endif
}
void encrypt_block(byte *outbuf, byte *inbuf);
void decrypt_block(byte *outbuf, byte *inbuf);
void burn_stack(int bytes);
void do_encrypt(uint32_t *ret_xl, uint32_t *ret_xr);
void do_decrypt(uint32_t *ret_xl, uint32_t *ret_xr);
void do_encrypt_block(byte *outbuf, byte *inbuf);
void do_decrypt_block(byte *outbuf, byte *inbuf);
int do_bf_setkey(byte *key, unsigned int keylen);
protected:
struct BLOWFISH_context bc;
};
#endif
diff --git a/pwmanager/pwmanager/gpasmanfile.cpp b/pwmanager/pwmanager/gpasmanfile.cpp
index f80bc13..ae34c83 100644
--- a/pwmanager/pwmanager/gpasmanfile.cpp
+++ b/pwmanager/pwmanager/gpasmanfile.cpp
@@ -1,437 +1,447 @@
/* Gpasman, a password manager
Copyright (C) 1998-1999 Olivier Sessink, olivier@lx.student.wau.nl
file.c, handles file opening and closing
Other code contributors:
Dave Rudder
Chris Halverson
Matthew Palmer
Guide Berning
Jimmy Mason
website at http://www.student.wau.nl/~olivier/gpasman/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* 2003/06/10:
* modified by Michael Buesch to work together
* with PwM as import/export module.
*/
/***************************************************************************
* copyright (C) 2004 by Ulf Schenk
* This file is originaly based on version 1.0.1 of pwmanager
* and was modified to run on embedded devices that run microkde
*
* $Id$
**************************************************************************/
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
+#ifndef _WIN32_
#include <unistd.h>
+#else
+#include <io.h>
+#define S_IRUSR _S_IREAD
+#define S_IWUSR _S_IWRITE
+#define creat _creat
+#endif
#include <string.h>
#include <errno.h>
#include "gpasmanfile.h"
#include "globalstuff.h"
#define SAVE_BUFFER_LENGTH 1024
#define LOAD_BUFFER_LENGTH 2048
#ifndef S_IAMB
#define S_IAMB 00777
#endif
// enable/disable debug output
//#define GPASMANFILE_DEBUG
#undef GPASMANFILE_DEBUG
-
+#ifndef _WIN32_
#if defined(PWM_DEBUG) && defined(GPASMANFILE_DEBUG)
# define DBG(msg,x...) do { fprintf(stderr, msg "\n" , ##x); } while (0)
#else
# define DBG(msg,x...) do { } while (0)
#endif
+#else
+# define DBG
+#endif
#ifdef BIG_ENDIAN_HOST
# define WORDS_BIGENDIAN
#else
# undef WORDS_BIGENDIAN
#endif
GpasmanFile::GpasmanFile()
{
}
GpasmanFile::~GpasmanFile()
{
}
int GpasmanFile::save_init(const char *filename, const char *password)
{
/*
* returncodes:
* 1 = success
* 0 = can't open filedescriptor / can't create file
* -1 = permissions are bad
* -2 = is a symlink
* -3 = can't get file status
*/
unsigned char key[128];
unsigned int j = 0;
unsigned int keylength;
int val, count2;
/* first we should check the permissions of the filename */
if (file_exists(filename)) {
val = check_file(filename);
if (val != 1) {
DBG("save_init, return %d", val);
return val;
}
} else {
val = creat(filename, (S_IRUSR | S_IWUSR));
if (val == -1) {
DBG("%s", "save_init, return 0");
return 0;
} else {
close(val);
}
}
fd = fopen(filename, "wb");
if (fd == NULL) {
return 0;
}
buffer = (char*)malloc(SAVE_BUFFER_LENGTH);
/* make the key ready */
DBG("save_init, password=%s", password);
for (j = 0; password[j] != '\0'; j++) {
key[j] = password[j];
}
keylength = j;
rc2.rc2_expandkey((char*)key, (int)keylength, 128);
/* First, we make the IV */
for (count2 = 0; count2 < 4; count2++) {
iv[count2] = rand();
putc((unsigned char) (iv[count2] >> 8), fd);
putc((unsigned char) (iv[count2] & 0xff), fd);
}
bufferIndex = 0;
return 1;
}
int GpasmanFile::save_entry(char *entry[4])
{
char *text1;
int count2, count3;
unsigned short ciphertext[4];
buffer = (char*)memset(buffer, '\0', SAVE_BUFFER_LENGTH);
for (count2 = 0; count2 < 4; count2++) {
text1 = entry[count2];
if (strlen(text1) == 0) {
strncpy(text1, " ", strlen(" "));
}
strncat(buffer, text1, strlen(text1));
/* Use 255 as the marker. \n is too tough to test for */
buffer[strlen(buffer)] = 255;
} /*for (count2 = 0; count2 < 4; count2++) */
DBG("save_entry, buffer contains %s", buffer);
count2 = 0;
/* I'm using CBC mode and encrypting the data straight from top down.
* At the bottom, encrypted, I will append an MD5 hash of the file, eventually.
* PKCS 5 padding (explained at the code section
*/
while (count2 < (int)strlen(buffer)) {
#ifndef WORDS_BIGENDIAN
plaintext[bufferIndex] = buffer[count2 + 1] << 8;
plaintext[bufferIndex] += buffer[count2] & 0xff;
#else
plaintext[bufferIndex] = buffer[count2] << 8;
plaintext[bufferIndex] += buffer[count2 + 1] & 0xff;
#endif
bufferIndex++;
if (bufferIndex == 4) {
rc2.rc2_encrypt(plaintext);
for (count3 = 0; count3 < 4; count3++) {
ciphertext[count3] =
iv[count3] ^ plaintext[count3];
/* Now store the ciphertext as the iv */
iv[count3] = plaintext[count3];
/* reset the buffer index */
bufferIndex = 0;
if (putc
((unsigned char) (ciphertext[count3] >> 8),
fd) == EOF)
return -1;
if (putc
((unsigned char) (ciphertext[count3] &
0xff), fd) == EOF)
return -1;
} /*for (count3 = 0; count3 < 4; count3++) */
}
/*if (bufferIndex == 4) */
/* increment a short, not a byte */
count2 += 2;
} /*while (count2 < strlen (buffer)) */
return 1;
}
int GpasmanFile::save_finalize(void)
{
int count1, retval = 1;
unsigned short ciphertext[4];
/* Tack on the PKCS 5 padding
How it works is we fill up the last n bytes with the value n
So, if we have, say, 13 bytes, 8 of which are used, we have 5 left
over, leaving us 3 short, so we fill it in with 3's.
If we come out even, we fill it with 8 8s
um, except that in this instance we are using 4 shorts instead of 8 bytes.
so, half everything
*/
for (count1 = bufferIndex; count1 < 4; count1++) {
plaintext[count1] = (4 - bufferIndex);
}
DBG("save_finalize, 4 - bufferIndex = %d",
4 - bufferIndex);
DBG("save_finalize, plaintext[3]=%c", plaintext[3]);
rc2.rc2_encrypt(plaintext);
for (count1 = 0; count1 < 4; count1++) {
ciphertext[count1] = iv[count1] ^ plaintext[count1];
if (putc((unsigned char) (ciphertext[count1] >> 8), fd) == EOF)
retval = -1;
if (putc((unsigned char) (ciphertext[count1] & 0xff), fd) ==
EOF)
retval = -1;
}
fclose(fd);
DBG("%s", "save_finalize, fd is closed");
free(buffer);
return retval;
}
int GpasmanFile::load_init(const char *filename, const char *password)
{
/*
* returncodes:
* 1 = success
* 0 = can't open filedescriptor / can't create file
* -1 = permissions are bad
* -2 = is a symlink
* -3 = can't get file status
*/
unsigned int j = 0;
unsigned int keylength = 0;
int count = 0, count2 = 0, count3 = 0;
unsigned char charbuf[8];
unsigned short ciphertext[4];
int val = 0;
unsigned char key[128];
/* first we should check the file permissions */
if (file_exists(filename)) {
val = check_file(filename);
if (val != 1) {
return val;
}
} else {
return 0;
}
fd = fopen(filename, "rb");
if (fd == NULL) {
return 0;
}
buffer = (char*)malloc(LOAD_BUFFER_LENGTH);
DBG("load_init, password=\"%s\"", password);
for (j = 0; password[j] != '\0'; j++) {
key[j] = password[j];
}
keylength = j;
rc2.rc2_expandkey((char*)key, (int)keylength, 128);
size = read(fileno(fd), (unsigned char *) (charbuf + count), 8);
DBG("load_init, size=%d, keylength=%d", size, keylength);
if (size < 8) {
fclose(fd);
free(buffer);
return -1;
}
for (count = 0; count < 4; count++) {
count2 = count << 1;
iv[count] = charbuf[count2] << 8;
iv[count] += charbuf[count2 + 1];
DBG("load_init iv[%d]=%d", count, iv[count]);
}
size = 0;
bufferIndex = 0;
while ((count = read(fileno(fd), (unsigned char *) charbuf, 8)) > 0) {
DBG("load_init A, count=%d, count2=%d", count, count2);
while (count < 8) {
count2 = read(fileno(fd), (unsigned char *) (charbuf +
count), 8);
DBG("load_init B, count=%d, count2=%d",
count, count2);
if (count2 == 0) {
printf("bad EOF\n");
fclose(fd);
free(buffer);
return -1;
}
count += count2;
} /* while (count < 8) */
size += 8;
DBG("load_init charbuf[1]=%c", charbuf[1]);
for (count2 = 0; count2 < 8; count2 += 2) {
count3 = count2 >> 1;
ciphertext[count3] = charbuf[count2] << 8;
ciphertext[count3] += charbuf[count2 + 1];
plaintext[count3] = ciphertext[count3] ^ iv[count3];
iv[count3] = plaintext[count3];
}
rc2.rc2_decrypt(plaintext);
memcpy((unsigned char *) (buffer + bufferIndex), plaintext, 8);
bufferIndex += 8;
buffer[bufferIndex + 1] = '\0';
DBG("bufferIndex=%d, buffer=%s", bufferIndex,
buffer);
} /* while ((count = read (fileno (fd), (unsigned char *) charbuf, 8)) > 0) */
DBG("load_init, size=%d, buffer[size-1]=%d,", size,
buffer[size - 1]);
size -= buffer[size - 1];
DBG("size=%d", size);
lastcount = 0;
/* This will point to the starting index */
bufferIndex = 0;
return 1;
}
int GpasmanFile::load_entry(char *entry[4])
{
/* Strip off PKCS 5 padding
Should check to make sure it's good here
*/
int count, count1 = 0;
DBG("load_entry, lastcount=%d, size=%d, entry=%p",
lastcount, size, entry);
for (count = lastcount; count < size; count++) {
if ((unsigned char) (buffer[count]) == 255) {
if (buffer[bufferIndex] == '\0') {
bufferIndex++;
}
entry[count1] =
(char *) malloc(count - bufferIndex + 1);
DBG("load_entry, entry[%d]=%p", count1,
entry[count1]);
memcpy(entry[count1],
(unsigned char *) (buffer + bufferIndex),
count - bufferIndex);
entry[count1][count - bufferIndex] = '\0';
DBG("load_entry, entry[%d]=%s", count1,
entry[count1]);
count++;
bufferIndex = count;
count1++;
if (count1 == 4) {
lastcount = count;
DBG("%s", "load_entry, return 1, entry ready");
return 1;
}
} /* if ((unsigned char) (buffer[count]) == 255) */
} /* for (count = 0; count < size; count++) */
DBG("%s", "load_entry, ended no entry anymore");
return 2;
}
void GpasmanFile::load_finalize(void)
{
fclose(fd);
free(buffer);
}
int GpasmanFile::check_file(const char *filename)
{
struct stat naamstat;
if (stat(filename, &naamstat) == -1) {
return (-3);
}
if (((naamstat.st_mode & S_IAMB) | (S_IRUSR | S_IWUSR)) != (S_IRUSR |
S_IWUSR)) {
DBG("%s perms are bad, they are: %ld, should be -rw------",
filename, (naamstat.st_mode & (S_IREAD | S_IWRITE)));
return (-1);
}
-
+#ifndef _WIN32_
if (!S_ISREG(naamstat.st_mode)) {
lstat(filename, &naamstat);
if (S_ISLNK(naamstat.st_mode)) {
DBG("%s is a symlink", filename);
return (-2);
}
}
-
+#endif
return (1);
}
int GpasmanFile::file_exists(const char *tfile)
{
struct stat naamstat;
if ((stat(tfile, &naamstat) == -1) && (errno == ENOENT)) {
DBG("file_exists, %s does NOT exist", tfile);
return (0);
} else {
DBG("file_exists, %s DOES exist", tfile);
return (1);
}
}
diff --git a/pwmanager/pwmanager/htmlgen.cpp b/pwmanager/pwmanager/htmlgen.cpp
index 166b987..bee8198 100644
--- a/pwmanager/pwmanager/htmlgen.cpp
+++ b/pwmanager/pwmanager/htmlgen.cpp
@@ -1,248 +1,248 @@
/***************************************************************************
* *
* copyright (C) 2004 by Michael Buesch *
* email: mbuesch@freenet.de *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 *
* as published by the Free Software Foundation. *
* *
***************************************************************************/
/***************************************************************************
* copyright (C) 2004 by Ulf Schenk
* This file is originaly based on version 1.0.1 of pwmanager
* and was modified to run on embedded devices that run microkde
*
* $Id$
**************************************************************************/
#include "htmlgen.h"
#include "pwmexception.h"
#include <kstandarddirs.h>
/** enable/disable HTML-generator debugging (0/1) */
#define HTMLGEN_DEBUG 0
#define HTML_DOCTYPE_HDR "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n"
#define HTML_PWM_HDR "<!-- PwManager generated HTML -->"
#define HTML_COMMENT_HDR "<!-- type: comment -->"
#define HTML_COMMENTVER_HDR "<!-- ver: 0.1 -->"
#define HTML_STYLESHEET_DUMMY "@STYLESHEET@"
#define HTML_GLOBTBL_CLASS "\"globtable\""
#define HTML_GLOBTITLE_CLASS "\"globtitle\""
#define HTML_SUBTBL_CLASS "\"subtable\""
#define HTML_SUBTITLE_CLASS "\"subtitle\""
#define HTML_ENTRY_CLASS "\"entry\""
#define HTML_VALUE_CLASS "\"value\""
#define PATH_COMMENTSTYLE_CSS "pwmanager/html/htmlcomment_style.css"
#if defined(PWM_DEBUG) && HTMLGEN_DEBUG != 0
#define HTML_ENDL "\n"
#else // defined(PWM_DEBUG) && ...
#define HTML_ENDL ""
#endif // defined(PWM_DEBUG) && ...
HtmlGen::HtmlGen()
{
useSSDummy = true;
}
HtmlGen::~HtmlGen()
{
}
QString HtmlGen::escapeHtmlText(const QString &str)
{
QString ret;
unsigned int len = str.length(), i;
char c;
for (i = 0; i < len; ++i) {
- c = str[i];
+ c = str.at(i);
switch (c) {
case '<':
ret.append("&lt;");
break;
case '>':
ret.append("&gt;");
break;
case '&':
ret.append("&amp;");
break;
case '\"':
ret.append("&quot;");
break;
case 'ä':
ret.append("&auml;");
break;
case 'Ä':
ret.append("&Auml;");
break;
case 'ü':
ret.append("&uuml;");
break;
case 'Ü':
ret.append("&Uuml;");
break;
case 'ö':
ret.append("&ouml;");
break;
case 'Ö':
ret.append("&Ouml;");
break;
case 'ß':
ret.append("&szlig;");
break;
case '¿':
ret.append("&euro;");
break;
default:
ret.append(c);
}
}
return ret;
}
bool HtmlGen::isHtml(const QString &dta)
{
int ret;
ret = dta.find("<html>", 0, false);
if (ret == -1)
return false;
ret = dta.find("<head>", ret, false);
if (ret == -1)
return false;
return true;
}
QString HtmlGen::getStyleSheetHtml()
{
QString ret;
ret = "<link rel=\"stylesheet\" href=\"";
QString cssPath(::locate("data", PATH_COMMENTSTYLE_CSS));
if ((cssPath == QString::null) || (cssPath == "")) {
printDebug("HtmlGen::getStyleSheetHtml(): not found");
return "";
}
ret += cssPath;
ret += "\" type=\"text/css\">" HTML_ENDL;
return ret;
}
bool HtmlGen::replaceSSDummy(QString *doc)
{
int beginPos = doc->find(HTML_STYLESHEET_DUMMY);
if (beginPos == -1) {
printDebug("HtmlGen::replaceSSDummy(): not found");
return false;
}
*doc = doc->replace(beginPos, strlen(HTML_STYLESHEET_DUMMY),
getStyleSheetHtml());
return true;
}
QString HtmlGen::genHtmlComment(const HtmlComment *dta)
{
QString ret(HTML_DOCTYPE_HDR
HTML_PWM_HDR HTML_ENDL
HTML_COMMENT_HDR HTML_ENDL
HTML_COMMENTVER_HDR HTML_ENDL);
ret += "<html>" HTML_ENDL;
if (!appendCommentHeader(&ret))
return "";
if (!appendCommentBody(&ret, dta))
return "";
ret += "</html>" HTML_ENDL;
#if defined(PWM_DEBUG) && HTMLGEN_DEBUG != 0
printDebug("<BEGIN HtmlGen::genHtmlComment() dump>");
cout << ret << endl;
printDebug("<END HtmlGen::genHtmlComment() dump>");
#endif // DEBUG
return ret;
}
bool HtmlGen::appendCommentHeader(QString *str)
{
*str += "<head>" HTML_ENDL;
if (useSSDummy) {
*str += HTML_STYLESHEET_DUMMY HTML_ENDL;
} else {
QString ssLine(getStyleSheetHtml());
if (ssLine.isEmpty())
return false;
*str += ssLine;
}
*str += "</head>" HTML_ENDL;
return true;
}
bool HtmlGen::appendCommentBody(QString *str,
const HtmlComment *dta)
{
*str += "<body>" HTML_ENDL;
if (!appendCommentGlobTbl(str, dta))
return false;
*str += "</body>" HTML_ENDL;
return true;
}
bool HtmlGen::appendCommentGlobTbl(QString *str,
const HtmlComment *dta)
{
*str += "<table class=" HTML_GLOBTBL_CLASS ">" HTML_ENDL;
*str += "<tr><th class=" HTML_GLOBTITLE_CLASS ">";
*str += escapeHtmlText(dta->getTitle());
*str += "</th></tr>" HTML_ENDL;
const vector<HtmlComment::SubTable> *subTbls = dta->getSubTableList();
vector<HtmlComment::SubTable>::const_iterator i = subTbls->begin(),
end = subTbls->end();
while (i != end) {
*str += "<tr><td>" HTML_ENDL;
if (!appendCommentSubTbl(str, &(*i)))
return false;
++i;
*str += "</td></tr>" HTML_ENDL;
}
*str += "</table>" HTML_ENDL;
return true;
}
bool HtmlGen::appendCommentSubTbl(QString *str,
const HtmlComment::SubTable *dta)
{
*str += "<table class=" HTML_SUBTBL_CLASS ">" HTML_ENDL;
*str += "<tr><th colspan=\"2\" class=" HTML_SUBTITLE_CLASS ">";
*str += escapeHtmlText(dta->getTitle());
*str += "</th></tr>" HTML_ENDL;
const vector< pair<QString, QString> > *entries = dta->getEntryList();
vector< pair<QString, QString> >::const_iterator i = entries->begin(),
end = entries->end();
while (i != end) {
*str += "<tr>" HTML_ENDL;
if (!appendCommentSubTblEntry(str, &(*i)))
return false;
*str += "</tr>" HTML_ENDL;
++i;
}
*str += "</table>" HTML_ENDL;
return true;
}
bool HtmlGen::appendCommentSubTblEntry(QString *str,
const pair<QString, QString> *dta)
{
*str += "<td class=" HTML_ENTRY_CLASS ">";
*str += escapeHtmlText(dta->first);
*str += "</td>" HTML_ENDL;
*str += "<td class=" HTML_VALUE_CLASS ">";
*str += escapeHtmlText(dta->second);
*str += "</td>" HTML_ENDL;
return true;
}
diff --git a/pwmanager/pwmanager/ipc.cpp b/pwmanager/pwmanager/ipc.cpp
index b1d2c68..643b022 100644
--- a/pwmanager/pwmanager/ipc.cpp
+++ b/pwmanager/pwmanager/ipc.cpp
@@ -1,216 +1,217 @@
/***************************************************************************
* *
* copyright (C) 2004 by Michael Buesch *
* email: mbuesch@freenet.de *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 *
* as published by the Free Software Foundation. *
* *
***************************************************************************/
/***************************************************************************
* copyright (C) 2004 by Ulf Schenk
* This file is originaly based on version 1.0.1 of pwmanager
* and was modified to run on embedded devices that run microkde
*
* $Id$
**************************************************************************/
#include "ipc.h"
#include "pwmexception.h"
#include <qsocketnotifier.h>
-
+#ifndef _WIN32_
#include <sys/socket.h>
-
+#endif
#ifndef PWM_EMBEDDED
#include <sys/types.h>
#include <stdio.h>
#else
#include <qsocket.h>
#endif
#define END_OF_LINE '\n'
#define INIT_LINEBUF_LEN 64 /* byte */
#ifndef PWM_EMBEDDED
Ipc::Ipc()
: stream (0)
, notifier (0)
, rdBuf (0)
{
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sock)) {
throw PwMException(PwMException::EX_GENERIC,
"Ipc: socketpair() failed");
}
rdBufSize = INIT_LINEBUF_LEN;
rdBuf = static_cast<char *>(malloc(rdBufSize));
if (!rdBuf) {
close(sock[0]);
close(sock[1]);
throw PwMException(PwMException::EX_GENERIC,
"Ipc: OOM");
}
stream = fdopen(sock[0], "r");
if (!stream) {
close(sock[0]);
close(sock[1]);
free(rdBuf);
throw PwMException(PwMException::EX_GENERIC,
"Ipc: fdopen() failed");
}
notifier = new QSocketNotifier(sock[0], QSocketNotifier::Read);
connect(notifier, SIGNAL(activated(int)),
this, SLOT(receiveData(int)));
host = true;
}
#else
Ipc::Ipc()
: notifier (0)
, rdBuf (0)
{
+#ifndef _WIN32_
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sock)) {
qDebug("Ipc: socketpair() failed");
}
-
+#endif
QSocket* qsock = new QSocket();
qsock->setSocket(sock[0]);
rdBufSize = INIT_LINEBUF_LEN;
rdBuf = (char *)(malloc(rdBufSize));
if (!rdBuf) {
close(sock[0]);
close(sock[1]);
qDebug("Ipc: OOM");
}
qsock = new QSocket();
qsock->setSocket(sock[0]);
/*US
stream = fdopen(sock[0], "r");
if (!stream) {
close(sock[0]);
close(sock[1]);
free(rdBuf);
qDebug("Ipc: fdopen() failed");
}
*/
notifier = new QSocketNotifier(sock[0], QSocketNotifier::Read);
connect(notifier, SIGNAL(activated(int)),
this, SLOT(receiveData(int)));
host = true;
}
#endif
#ifndef PWM_EMBEDDED
Ipc::Ipc(const Ipc *ipc)
: stream (0)
, notifier (0)
, rdBuf (0)
{
rdBufSize = INIT_LINEBUF_LEN;
rdBuf = static_cast<char *>(malloc(rdBufSize));
if (!rdBuf) {
throw PwMException(PwMException::EX_GENERIC,
"Ipc: OOM");
}
sock[0] = ipc->sock[1];
sock[1] = ipc->sock[0];
stream = fdopen(sock[0], "r");
if (!stream) {
free(rdBuf);
throw PwMException(PwMException::EX_GENERIC,
"Ipc: fdopen() failed");
}
notifier = new QSocketNotifier(sock[0], QSocketNotifier::Read);
connect(notifier, SIGNAL(activated(int)),
this, SLOT(receiveData(int)));
host = false;
}
#else
Ipc::Ipc(const Ipc *ipc)
: notifier (0)
, rdBuf (0)
{
rdBufSize = INIT_LINEBUF_LEN;
rdBuf = (char *)(malloc(rdBufSize));
if (!rdBuf) {
qDebug("Ipc: OOM");
}
sock[0] = ipc->sock[1];
sock[1] = ipc->sock[0];
qSock = new QSocket();
qSock->setSocket(sock[0]);
/*US
stream = fdopen(sock[0], "r");
if (!stream) {
free(rdBuf);
qDebug("Ipc: fdopen() failed");
}
*/
notifier = new QSocketNotifier(sock[0], QSocketNotifier::Read);
connect(notifier, SIGNAL(activated(int)),
this, SLOT(receiveData(int)));
host = false;
}
#endif
Ipc::~Ipc()
{
#ifdef PWM_EMBEDDED
delete qSock;
#endif
delete_ifnot_null(notifier);
if (rdBuf)
free(rdBuf);
#ifndef PWM_EMBEDDED
if (stream)
fclose(stream);
#endif
if (host) {
close(sock[0]);
close(sock[1]);
}
}
void Ipc::receiveData(int s)
{
PWM_ASSERT(s == sock[0]);
PARAM_UNUSED(s);
#ifndef PWM_EMBEDDED
ssize_t rd;
rd = ::getline(&rdBuf, &rdBufSize, stream);
if (likely(rd > 0)) {
emit lineAvailable(rdBuf, rd);
}
#else
int rd;
rd = qSock->readLine(rdBuf, rdBufSize);
if (rd > 0) {
emit lineAvailable(rdBuf, rd);
}
#endif
qDebug("void Ipc::receiveData(int s) has to be implemented.");
}
#ifndef PWM_EMBEDDED
#include "ipc.moc"
#endif
diff --git a/pwmanager/pwmanager/ipc.h b/pwmanager/pwmanager/ipc.h
index e5a496d..7bfca02 100644
--- a/pwmanager/pwmanager/ipc.h
+++ b/pwmanager/pwmanager/ipc.h
@@ -1,89 +1,92 @@
/***************************************************************************
* *
* copyright (C) 2004 by Michael Buesch *
* email: mbuesch@freenet.de *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 *
* as published by the Free Software Foundation. *
* *
***************************************************************************/
/***************************************************************************
* copyright (C) 2004 by Ulf Schenk
* This file is originaly based on version 1.0.1 of pwmanager
* and was modified to run on embedded devices that run microkde
*
* $Id$
**************************************************************************/
#ifndef __PWM_IPC_H
#define __PWM_IPC_H
#include <qobject.h>
+#ifndef _WIN32_
#include <unistd.h>
-
+#else
+#include <io.h>
+#endif
#ifndef PWM_EMBEDDED
#include <stdio.h>
#else
#include <qsocket.h>
#endif
class QSocketNotifier;
/** very simple interprocess communication class */
class Ipc : public QObject
{
Q_OBJECT
public:
/** create a new Ipc communication object */
Ipc();
/** create a new Ipc communication object and
* connect it to "ipc"
*/
Ipc(const Ipc *ipc);
/** destructor */
~Ipc();
/** send data to the other socket end
* (To the connected ipc object)
*/
#ifndef PWM_EMBEDDED
void send(const char *buf, size_t size)
{ write(sock[0], buf, size); }
#else
void send(const char *buf, size_t size)
{ qSock->writeBlock(buf, size); }
#endif
signals:
/** a line is available */
void lineAvailable(const char *buf, size_t size);
protected slots:
/** received data on socket */
void receiveData(int s);
protected:
#ifndef PWM_EMBEDDED
/** stream on "this" end of the socket (sock[0]) */
FILE *stream;
/** current receive buffer size */
size_t rdBufSize;
#else
QSocket* qSock;
/** current receive buffer size */
unsigned int rdBufSize;
#endif
/** full-duplex socket file desciptors */
int sock[2];
/** socket notifier */
QSocketNotifier *notifier;
/** are we the host or the client object? */
bool host;
/** receive buffer */
char *rdBuf;
};
#endif // __PWM_IPC_H
diff --git a/pwmanager/pwmanager/libgcryptif.h b/pwmanager/pwmanager/libgcryptif.h
index dffd55b..1a7b658 100644
--- a/pwmanager/pwmanager/libgcryptif.h
+++ b/pwmanager/pwmanager/libgcryptif.h
@@ -1,166 +1,171 @@
/***************************************************************************
* *
* copyright (C) 2004 by Michael Buesch *
* email: mbuesch@freenet.de *
* *
* hashPassphrase() is derived from GnuPG and is *
* Copyright (C) 1998, 1999, 2000, 2001, 2003 *
* Free Software Foundation, Inc. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 *
* as published by the Free Software Foundation. *
* *
***************************************************************************/
/***************************************************************************
* copyright (C) 2004 by Ulf Schenk
* This file is originaly based on version 1.1 of pwmanager
* and was modified to run on embedded devices that run microkde
*
* $Id$
**************************************************************************/
#ifndef __LIBGCRYPTIF_H
#define __LIBGCRYPTIF_H
#include "pwmexception.h"
//#undef CONFIG_PWMANAGER_GCRY // for debugging only.
#ifdef CONFIG_PWMANAGER_GCRY
#include <stddef.h>
#include <sys/types.h>
+#ifndef _WIN32_
#include <stdint.h>
-
+#else
+#define uint8_t Q_UINT8
+#define byte Q_UINT8
+#define uint32_t Q_UINT32
+#endif
#define STRING2KEY_SALTLEN 8
/** interface class for the libgcrypt cipher and hash algorithms
* NOTE: Always allocate 1024 extra bytes for the inBuf (for padding)
*/
class LibGCryptIf
{
protected:
struct STRING2KEY
{
int mode;
int hash_algo;
uint8_t salt[STRING2KEY_SALTLEN];
uint32_t count;
};
struct DEK
{
size_t keylen;
uint8_t key[32]; // this is the largest used keylen (256 bit)
};
public:
LibGCryptIf() { }
/** is libgcrypt available? */
static bool available()
{ return true; }
/** encrypt data. _algo is the PWM_CRYPT_* ID
* of the algorithm.
*/
PwMerror encrypt(unsigned char **outBuf,
size_t *outBufLen,
unsigned char *inBuf,
size_t inBufLen,
const unsigned char *key,
size_t keylen,
char _algo);
/** decrypt data. _algo is the PWM_CRYPT_* ID
* of the algorithm.
*/
PwMerror decrypt(unsigned char **outBuf,
size_t *outBufLen,
const unsigned char *inBuf,
size_t inBufLen,
const unsigned char *key,
size_t keylen,
char _algo);
/** hash data. _algo is the PWM_HASH_* ID of the hash */
PwMerror hash(unsigned char **outBuf,
size_t *outBufLen,
const unsigned char *inBuf,
size_t inBufLen,
char _algo);
/** returns the length of the hash. _algo is the PWM_HASH_*
* id of the hash. returns 0 on error.
*/
unsigned int hashLength(char _algo);
protected:
/** returns the total buffer length */
size_t getBufLen(size_t inBufLen, size_t boundary)
{
return ((boundary - (inBufLen % boundary)) + inBufLen);
}
/** pad the data up to the given boundary.
* "buf" has to be big enough!
*/
void padData(unsigned char *buf,
size_t bufLen,
size_t boundary);
/** unpad the data */
void unpadData(const unsigned char *buf,
size_t *bufLen);
/** maps the PWM_CRYPT_* ID of an algorithm
* to the libgcrypt GCRY_CIPHER_* ID
*/
int mapCipherId(char algo);
/** maps the PWM_HASH_* ID of an algorithm
* to the libgcrypt GCRY_MD_* ID
*/
int mapHashId(char algo);
/** hash a passphrase to a cipher key */
bool hashPassphrase(const unsigned char *pw,
size_t pwlen,
unsigned char *salt,
unsigned char *key,
size_t keylen,
bool create);
/** hash a passphrase to a cipher key */
bool doHashPassphrase(DEK *dek,
const unsigned char *pw,
size_t pwlen,
STRING2KEY *s2k,
bool create);
};
#else // CONFIG_PWMANAGER_GCRY
/** libgcrypt is not installed. This is a NOP wrapper. */
class LibGCryptIf
{
public:
LibGCryptIf() { }
static bool available()
{ return false; }
PwMerror encrypt(unsigned char **,
size_t *,
unsigned char *,
size_t,
const unsigned char *,
size_t,
char)
{ return e_cryptNotImpl; }
PwMerror decrypt(unsigned char **,
size_t *,
const unsigned char *,
size_t,
const unsigned char *,
size_t,
char)
{ return e_cryptNotImpl; }
PwMerror hash(unsigned char **,
size_t *,
const unsigned char *,
size_t,
char)
{ return e_hashNotImpl; }
unsigned int hashLength(char)
{ return 0; }
};
#endif // CONFIG_PWMANAGER_GCRY
#endif // __LIBGCRYPTIF_H
diff --git a/pwmanager/pwmanager/pwm.cpp b/pwmanager/pwmanager/pwm.cpp
index d92c90d..1ab2b71 100644
--- a/pwmanager/pwmanager/pwm.cpp
+++ b/pwmanager/pwmanager/pwm.cpp
@@ -1029,437 +1029,438 @@ void PwM::exportToGpasman()
i18n("Error: Couldn't write to file.\n"
"Please check if you have permission to write "
"to the file in that directory."),
i18n("error while writing"));
} else
showStatMsg(i18n("Successfully exported data."));
curDoc()->timer()->putLock(DocTimer::id_autoLockTimer);
}
void PwM::exportToCsv()
{
PWM_ASSERT(curDoc());
if (curDoc()->isDocEmpty()) {
KMessageBox::information(this,
i18n
("Sorry, there is nothing to export;\n"
"please add some passwords first."),
i18n("Nothing to Do"));
return;
}
curDoc()->timer()->getLock(DocTimer::id_autoLockTimer);
QString fn(KFileDialog::getSaveFileName("*.csv", i18n("*|CSV Text File"), this));
if (fn.isEmpty()) {
curDoc()->timer()->putLock(DocTimer::id_autoLockTimer);
return;
}
Csv csv(this);
if (!csv.exportData(fn, curDoc())) {
curDoc()->timer()->putLock(DocTimer::id_autoLockTimer);
showStatMsg(i18n("CSV file export failed."));
return;
}
showStatMsg(i18n("Successfully exported data."));
curDoc()->timer()->putLock(DocTimer::id_autoLockTimer);
}
bool PwM::importCsv()
{
Csv csv(this);
if (!isVirgin()) {
if (KMessageBox::questionYesNo(this,
i18n("Do you want to import the data\n"
"into the current document? (If you\n"
"select \"no\", a new document will be\n"
"opened.)"),
i18n("Import into This Document?"))
== KMessageBox::No) {
// import the data to a new window.
PwM *newInstance = init->createMainWnd();
bool ok = newInstance->importCsv();
if (!ok) {
newInstance->setForceQuit(true);
delete_and_null(newInstance);
}
return ok;
}
}
QString filename = KFileDialog::getOpenFileName("*.csv", i18n("*|CSV Text File"), this);
if (filename.isEmpty())
return false;
curDoc()->timer()->getLock(DocTimer::id_autoLockTimer);
if (!csv.importData(filename, curDoc())) {
curDoc()->timer()->putLock(DocTimer::id_autoLockTimer);
showStatMsg(i18n("CSV file import failed."));
return false;
}
curDoc()->timer()->putLock(DocTimer::id_autoLockTimer);
KMessageBox::information(this,
i18n("Successfully imported the CSV data\n"
"into the current document."), i18n("Successfully Imported"));
showStatMsg(i18n("Successfully imported"));
setVirgin(false);
return true;
}
void PwM::exportToKWallet()
{
#ifdef CONFIG_KWALLETIF
if (!checkAndAskForKWalletEmu())
return;
PWM_ASSERT(curDoc());
if (curDoc()->isDocEmpty()) {
KMessageBox::information(this,
i18n
("Sorry, there's nothing to export.\n"
"Please first add some passwords."),
i18n("nothing to do"));
init->initKWalletEmu();
return;
}
curDoc()->timer()->getLock(DocTimer::id_autoLockTimer);
KWalletIf walletIf(this);
if (walletIf.kwalletExport(curDoc())) {
KMessageBox::information(this,
i18n("Successfully exported the data of the current "
"document to KWallet."),
i18n("Successfully exported data."));
showStatMsg(i18n("Successfully exported data."));
}
init->initKWalletEmu();
curDoc()->timer()->putLock(DocTimer::id_autoLockTimer);
#endif // CONFIG_KWALLETIF
}
bool PwM::importFromGpasman()
{
if (!isVirgin()) {
if (KMessageBox::questionYesNo(this,
i18n("Do you want to import the data\n"
"into the current document? (If you\n"
"select \"no\", a new document will be\n"
"opened.)"),
i18n("import into this document?"))
== KMessageBox::No) {
// import the data to a new window.
PwM *newInstance = init->createMainWnd();
bool ok = newInstance->importFromGpasman();
if (!ok) {
newInstance->setForceQuit(true);
delete_and_null(newInstance);
}
return ok;
}
}
curDoc()->timer()->getLock(DocTimer::id_autoLockTimer);
PwMerror ret;
QString path(KFileDialog::getOpenFileName(QString::null,
i18n("*|Gpasman or Kpasman file"), this));
if (path == "")
goto cancelImport;
ret = curDoc()->importFromGpasman(&path);
if (ret == e_wrongPw) {
if (KMessageBox::questionYesNo(this,
i18n
("This is probably the wrong master-password\n"
"you have typed in.\n"
"There is no real way to determine the\n"
"correctness of the password in the Gpasman\n"
"file-format. But I think this\n"
"password ist wrong.\n"
"Do you want to continue nevertheless?"),
i18n("password error"))
== KMessageBox::No) {
goto cancelImport;
}
} else if (ret != e_success) {
KMessageBox::error(this,
i18n("Could not import file!\n"
"Do you have permission to read this file?"),
i18n("import failed"));
goto cancelImport;
}
setVirgin(false);
curDoc()->timer()->putLock(DocTimer::id_autoLockTimer);
return true;
cancelImport:
curDoc()->timer()->putLock(DocTimer::id_autoLockTimer);
return false;
}
#ifdef CONFIG_KWALLETIF
bool PwM::checkAndAskForKWalletEmu()
{
if (init->kwalletEmu()) {
/* KWallet emulation is enabled. We can't import/export
* data from/to it, while emulation is active.
*/
if (KMessageBox::questionYesNo(this,
i18n("KWallet emulation is enabled.\n"
"You can't import or export data from/to "
"the original KWallet, while the emulation "
"is active.\n"
"Do you want to tempoarly disable the KWallet emulation?"),
i18n("Tempoarly disable KWallet emulation?"))
== KMessageBox::Yes) {
init->initKWalletEmu(true);
PWM_ASSERT(!init->kwalletEmu());
return true;
}
return false;
}
return true;
}
#endif // CONFIG_KWALLETIF
bool PwM::importKWallet()
{
#ifdef CONFIG_KWALLETIF
if (!checkAndAskForKWalletEmu())
return false;
KWalletIf walletIf(this);
if (!isVirgin()) {
if (KMessageBox::questionYesNo(this,
i18n("Do you want to import the data "
"into the current document? (If you "
"select \"no\", a new document will be "
"opened.)"),
i18n("import into this document?"))
== KMessageBox::No) {
// import the data to a new window.
PwM *newInstance = init->createMainWnd();
bool ok = newInstance->importKWallet();
if (!ok) {
newInstance->setForceQuit(true);
delete_and_null(newInstance);
goto exit_fail;
} else {
goto exit_ok;
}
}
}
curDoc()->timer()->getLock(DocTimer::id_autoLockTimer);
if (!walletIf.kwalletImport(curDoc())) {
curDoc()->timer()->putLock(DocTimer::id_autoLockTimer);
showStatMsg(i18n("KWallet import failed"));
goto exit_fail;
}
KMessageBox::information(this,
i18n("Successfully imported the KWallet data "
"into the current document."),
i18n("successfully imported"));
showStatMsg(i18n("successfully imported"));
setVirgin(false);
curDoc()->timer()->putLock(DocTimer::id_autoLockTimer);
exit_ok:
init->initKWalletEmu();
return true;
exit_fail:
init->initKWalletEmu();
#endif // CONFIG_KWALLETIF
return false;
}
void PwM::print_slot()
{
curDoc()->timer()->getLock(DocTimer::id_autoLockTimer);
#ifndef PWM_EMBEDDED
PwMPrint p(curDoc(), this);
p.printNow();
#else
qDebug("PwM::print_slot , PRINTING IS NOT IMPLEMENTED");
#endif
curDoc()->timer()->putLock(DocTimer::id_autoLockTimer);
}
void PwM::genNewCard_slot()
{
#ifdef CONFIG_KEYCARD
init->keycard()->genNewCard();
#endif
}
void PwM::eraseCard_slot()
{
#ifdef CONFIG_KEYCARD
init->keycard()->eraseCard();
#endif
}
void PwM::readCardId_slot()
{
#ifdef CONFIG_KEYCARD
init->keycard()->displayKey();
#endif
}
void PwM::makeCardBackup_slot()
{
#ifdef CONFIG_KEYCARD
init->keycard()->makeBackupImage();
#endif
}
void PwM::replayCardBackup_slot()
{
#ifdef CONFIG_KEYCARD
init->keycard()->replayBackupImage();
#endif
}
void PwM::execLauncher_slot()
{
PWM_ASSERT(curDoc());
if (curDoc()->isDeepLocked())
return;
unsigned int curEntryIndex;
if (!view->getCurEntryIndex(&curEntryIndex))
return;
bool ret = curDoc()->execLauncher(view->getCurrentCategory(),
curEntryIndex);
if (ret)
showStatMsg(i18n("Executed the \"Launcher\"."));
else
showStatMsg(i18n("ERROR: Couldn't execute the \"Launcher\"!"));
}
void PwM::goToURL_slot()
{
PWM_ASSERT(curDoc());
if (curDoc()->isDeepLocked())
return;
unsigned int curEntryIndex;
if (!view->getCurEntryIndex(&curEntryIndex))
return;
bool ret = curDoc()->goToURL(view->getCurrentCategory(),
curEntryIndex);
if (ret)
showStatMsg(i18n("started browser with current URL."));
else
showStatMsg(i18n("ERROR: Couldn't start browser! Maybe invalid URL?"));
}
void PwM::copyToClipboard(const QString &s)
{
QClipboard *cb = QApplication::clipboard();
#ifndef PWM_EMBEDDED
if (cb->supportsSelection())
cb->setText(s, QClipboard::Selection);
cb->setText(s, QClipboard::Clipboard);
#else
cb->setText(s);
#endif
}
void PwM::showStatMsg(const QString &msg)
{
#ifdef DESKTOP_VERSION
statusBar()->message(msg, STATUSBAR_MSG_TIMEOUT * 1000);
#else
qDebug("Statusbar : %s",msg.latin1());
Global::statusMessage(msg);
#endif
}
void PwM::focusInEvent(QFocusEvent *e)
{
if (e->gotFocus()) {
emit gotFocus(this);
} else if (e->lostFocus()) {
emit lostFocus(this);
}
}
#ifdef PWM_EMBEDDED
void PwM::whatsnew_slot()
{
KApplication::showFile( "KDE-Pim/Pi Version Info", "kdepim/WhatsNew.txt" );
}
void PwM::showLicense_slot()
{
KApplication::showLicence();
}
void PwM::faq_slot()
{
KApplication::showFile( "PWM/Pi FAQ", "kdepim/pwmanager/pwmanagerFAQ.txt" );
}
void PwM::syncHowTo_slot()
{
KApplication::showFile( "KDE-Pim/Pi Synchronization HowTo", "kdepim/SyncHowto.txt" );
}
void PwM::createAboutData_slot()
{
QString version;
#include <../version>
+;
QMessageBox::about( this, "About PwManager/Pi",
"PwManager/Platform-independent\n"
"(PWM/Pi) " +version + " - " +
#ifdef DESKTOP_VERSION
"Desktop Edition\n"
#else
"PDA-Edition\n"
"for: Zaurus 5500 / 7x0 / 8x0\n"
#endif
"(c) 2004 Ulf Schenk\n"
"(c) 2004 Lutz Rogowski\n"
"(c) 1997-2004, The KDE PIM Team\n"
"(c) Michael Buesch - main programming\nand current maintainer\nmbuesch@freenet.de\n"
"Matt Scifo - mscifo@o1.com\n"
"Elias Probst - elias.probst@gmx.de\n"
"George Staikos - staikos@kde.org\n"
"Matthew Palmer - mjp16@uow.edu.au\n"
"Olivier Sessink - gpasman@nl.linux.org\n"
"The libgcrypt developers -\nBlowfish and SHA1 algorithms\nftp://ftp.gnupg.org/gcrypt/alpha/libgcrypt/\n"
"Troy Engel - tengel@sonic.net\n"
"Wickey - wickey@gmx.at\n"
"Ian MacGregor - original documentation author.\n"
);
}
//this are the overwritten callbackmethods from the syncinterface
bool PwM::sync(KSyncManager* manager, QString filename, int mode)
{
PWM_ASSERT(curDoc());
bool ret = curDoc()->sync(manager, filename, mode);
qDebug("PwM::sync save now: ret=%i", ret);
if (ret == true) {
//US BUG: what can we call here to update the view of the current doc?
//mViewManager->refreshView();
//US curDoc()->sync sets the dirtyFlag in case the sync was successfull.
save();
}
return ret;
}
#endif
#ifndef PWM_EMBEDDED
#include "pwm.moc"
#endif
diff --git a/pwmanager/pwmanager/pwmanager.pro b/pwmanager/pwmanager/pwmanager.pro
index 80b2519..fbc0554 100644
--- a/pwmanager/pwmanager/pwmanager.pro
+++ b/pwmanager/pwmanager/pwmanager.pro
@@ -1,175 +1,175 @@
TEMPLATE = app
CONFIG += qt warn_off
DESTDIR= ../../bin
TARGET = pwmpi
include( ../../variables.pri )
-INCLUDEPATH += . ../../ ../../libkdepim ../../microkde ../../microkde/kdecore ../../microkde/kdeui ../../microkde/kutils
+INCLUDEPATH += . ../../ ../../libkdepim ../../microkde ../../microkde/kdecore ../../microkde/kdeui ../../microkde/kutils ../libcrypt/crypt ../libcrypt/error ../libcrypt/zlib
DEFINES += PWM_EMBEDDED CONFIG_PWMANAGER_GCRY DESKTOP_VERSION
#enable this setting if you want debugoutput for pwmanager
#DEFINES += CONFIG_DEBUG
LIBS += -L../libcrypt/
LIBS += -L../../bin/
LIBS += -lmicrokde
LIBS += -lmicrokdepim
LIBS += -lzlib
LIBS += -lkpmicrocipher
LIBS += -lkpmicroerror
LIBS += -lkpmicrompi
LIBS += -lstdc++
unix:{
OBJECTS_DIR = obj/unix
MOC_DIR = moc/unix
}
win32:{
DEFINES += _WIN32_
OBJECTS_DIR = obj/win
MOC_DIR = moc/win
QMAKE_LINK += /NODEFAULTLIB:LIBC
QMAKE_CXXFLAGS += /TP /GX /GR /Ehsc
}
#INTERFACES = \
#addentrywnd.ui \
#configwnd.ui \
#findwnd.ui \
#getmasterpwwnd.ui \
#pwgenwnd.ui \
#setmasterpwwnd.ui \
#subtbledit.ui
#INTERFACES = \
#subtbledit.ui \
#HEADERS = \
#configuration_31compat.h \
#configuration.h \
#configwnd.h \
#configwndimpl.h \
#selftest.h
#subtbledit.h \
#subtbleditimpl.h \
#compressbzip2.h \
HEADERS = \
addentrywnd_emb.h \
addentrywndimpl.h \
base64.h \
binentrygen.h \
blowfish.h \
commentbox.h \
compiler.h \
compressgzip.h \
csv.h \
findwnd_emb.h \
findwndimpl.h \
genpasswd.h \
getkeycardwnd.h \
getmasterpwwnd_emb.h \
getmasterpwwndimpl.h \
globalstuff.h \
gpasmanfile.h \
htmlgen.h \
htmlparse.h \
ipc.h \
libgcryptif.h \
listobjselectwnd.h \
listviewpwm.h \
printtext.h \
pwgenwnd_emb.h \
pwgenwndimpl.h \
pwmdoc.h \
pwmdocui.h \
pwmexception.h \
pwm.h \
pwminit.h \
pwmprefs.h \
pwmprint.h \
pwmtray.h \
pwmview.h \
pwmviewstyle_0.h \
pwmviewstyle_1.h \
pwmviewstyle.h \
randomizer.h \
rc2.h \
rencatwnd.h \
serializer.h \
setmasterpwwnd_emb.h \
setmasterpwwndimpl.h \
sha1.h \
waitwnd.h \
kcmconfigs/kcmpwmconfig.h \
kcmconfigs/pwmconfigwidget.h
#sources that need not be build
#SOURCES = \
#advcommeditimpl.cpp \
#configuration.cpp \
#configwnd.cpp \
#configwndimpl.cpp \
#configuration_31compat.cpp \
#htmlparse.cpp \
#printtext.cpp \
#selftest.cpp \
#pwmprint.cpp \
#spinforsignal.cpp
#subtbledit.cpp \
#subtbleditimpl.cpp \
#compressbzip2.cpp
SOURCES = \
addentrywnd_emb.cpp \
addentrywndimpl.cpp \
base64.cpp \
binentrygen.cpp \
blowfish.cpp \
commentbox.cpp \
compressgzip.cpp \
csv.cpp \
findwnd_emb.cpp \
findwndimpl.cpp \
genpasswd.cpp \
getkeycardwnd.cpp \
getmasterpwwnd_emb.cpp \
getmasterpwwndimpl.cpp \
globalstuff.cpp \
gpasmanfile.cpp \
htmlgen.cpp \
ipc.cpp \
libgcryptif.cpp \
listobjselectwnd.cpp \
listviewpwm.cpp \
main.cpp \
pwgenwnd_emb.cpp \
pwgenwndimpl.cpp \
pwm.cpp \
pwmdoc.cpp \
pwmdocui.cpp \
pwmexception.cpp \
pwminit.cpp \
pwmprefs.cpp \
pwmtray.cpp \
pwmview.cpp \
pwmviewstyle_0.cpp \
pwmviewstyle_1.cpp \
pwmviewstyle.cpp \
randomizer.cpp \
rc2.cpp \
rencatwnd.cpp \
serializer.cpp \
setmasterpwwnd_emb.cpp \
setmasterpwwndimpl.cpp \
sha1.cpp \
waitwnd.cpp \
kcmconfigs/kcmpwmconfig.cpp \
kcmconfigs/pwmconfigwidget.cpp
diff --git a/pwmanager/pwmanager/pwmdoc.cpp b/pwmanager/pwmanager/pwmdoc.cpp
index 86b6273..129bf7b 100644
--- a/pwmanager/pwmanager/pwmdoc.cpp
+++ b/pwmanager/pwmanager/pwmdoc.cpp
@@ -1,895 +1,898 @@
/***************************************************************************
* *
* copyright (C) 2003, 2004 by Michael Buesch *
* email: mbuesch@freenet.de *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 *
* as published by the Free Software Foundation. *
* *
***************************************************************************/
/***************************************************************************
* copyright (C) 2004 by Ulf Schenk
* This file is originaly based on version 1.1 of pwmanager
* and was modified to run on embedded devices that run microkde
*
* $Id$
**************************************************************************/
#include "pwmdoc.h"
#include "pwmview.h"
#include "blowfish.h"
#include "sha1.h"
#include "globalstuff.h"
#include "gpasmanfile.h"
#include "serializer.h"
#include "compressgzip.h"
//US#include "compressbzip2.h"
#include "randomizer.h"
#include "pwminit.h"
#include "libgcryptif.h"
#ifdef PWM_EMBEDDED
#include "pwmprefs.h"
#include "kglobal.h"
#endif
#include <kmessagebox.h>
#include <libkcal/syncdefines.h>
#ifdef CONFIG_KWALLETIF
# include "kwalletemu.h"
#endif // CONFIG_KWALLETIF
#include <qdatetime.h>
#include <qsize.h>
#include <qfileinfo.h>
#include <qfile.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
//US#include <iostream>
#include <algorithm>
#include <sys/types.h>
#include <sys/stat.h>
+#ifndef _WIN32_
#include <unistd.h>
#include <stdint.h>
-
+#endif
#ifdef PWM_EMBEDDED
#ifndef Q_LONG
#define Q_LONG long
#endif
#ifndef Q_ULONG
#define Q_ULONG unsigned long
#endif
#endif //PWM_EMBEDDED
//TODO: reset to its normal value.
#define META_CHECK_TIMER_INTERVAL 10/*300*/ /* sek */
using namespace std;
void PwMDocList::add(PwMDoc *doc, const string &id)
{
#ifdef PWM_DEBUG
// check for existance of object in debug mode only.
vector<listItem>::iterator begin = docList.begin(),
end = docList.end(),
i = begin;
while (i != end) {
if (i->doc == doc) {
BUG();
return;
}
++i;
}
#endif
listItem newItem;
newItem.doc = doc;
newItem.docId = id;
docList.push_back(newItem);
}
void PwMDocList::edit(PwMDoc *doc, const string &newId)
{
vector<listItem>::iterator begin = docList.begin(),
end = docList.end(),
i = begin;
while (i != end) {
if (i->doc == doc) {
i->docId = newId;
return;
}
++i;
}
}
void PwMDocList::del(PwMDoc *doc)
{
vector<listItem>::iterator begin = docList.begin(),
end = docList.end(),
i = begin;
while (i != end) {
if (i->doc == doc) {
docList.erase(i);
return;
}
++i;
}
}
bool PwMDocList::find(const string &id, listItem *ret)
{
vector<listItem>::iterator begin = docList.begin(),
end = docList.end(),
i = begin;
while (i != end) {
if (i->docId == id) {
if (ret)
*ret = *i;
return true;
}
++i;
}
return false;
}
DocTimer::DocTimer(PwMDoc *_doc)
: doc (_doc)
, mpwLock (0)
, autoLockLock (0)
, metaCheckLock (0)
{
mpwTimer = new QTimer;
autoLockTimer = new QTimer;
metaCheckTimer = new QTimer;
connect(mpwTimer, SIGNAL(timeout()),
this, SLOT(mpwTimeout()));
connect(autoLockTimer, SIGNAL(timeout()),
this, SLOT(autoLockTimeout()));
connect(metaCheckTimer, SIGNAL(timeout()),
this, SLOT(metaCheckTimeout()));
}
DocTimer::~DocTimer()
{
delete mpwTimer;
delete autoLockTimer;
delete metaCheckTimer;
}
void DocTimer::start(TimerIDs timer)
{
switch (timer) {
case id_mpwTimer:
if (mpwTimer->isActive())
mpwTimer->stop();
doc->setDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW);
mpwTimer->start(conf()->confGlobPwTimeout() * 1000, true);
break;
case id_autoLockTimer:
if (autoLockTimer->isActive())
autoLockTimer->stop();
if (conf()->confGlobLockTimeout() > 0)
autoLockTimer->start(conf()->confGlobLockTimeout() * 1000, true);
break;
case id_metaCheckTimer:
if (metaCheckTimer->isActive())
metaCheckTimer->stop();
metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true);
break;
}
}
void DocTimer::stop(TimerIDs timer)
{
switch (timer) {
case id_mpwTimer:
mpwTimer->stop();
break;
case id_autoLockTimer:
autoLockTimer->stop();
break;
case id_metaCheckTimer:
metaCheckTimer->stop();
break;
}
}
void DocTimer::getLock(TimerIDs timer)
{
switch (timer) {
case id_mpwTimer:
++mpwLock;
break;
case id_autoLockTimer:
++autoLockLock;
break;
case id_metaCheckTimer:
++metaCheckLock;
break;
}
}
void DocTimer::putLock(TimerIDs timer)
{
switch (timer) {
case id_mpwTimer:
if (mpwLock)
--mpwLock;
break;
case id_autoLockTimer:
if (autoLockLock)
--autoLockLock;
break;
case id_metaCheckTimer:
if (metaCheckLock)
--metaCheckLock;
break;
}
}
void DocTimer::mpwTimeout()
{
if (mpwLock) {
mpwTimer->start(1000, true);
return;
}
doc->unsetDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW);
}
void DocTimer::autoLockTimeout()
{
if (autoLockLock) {
autoLockTimer->start(1000, true);
return;
}
if (conf()->confGlobAutoDeepLock() &&
doc->filename != QString::null &&
doc->filename != "") {
doc->deepLock(true);
} else {
doc->lockAll(true);
}
}
void DocTimer::metaCheckTimeout()
{
if (metaCheckLock) {
// check again in one second.
metaCheckTimer->start(1000, true);
return;
}
if (doc->isDeepLocked()) {
metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true);
return;
}
if (doc->isDocEmpty()) {
metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true);
return;
}
#ifdef CONFIG_KWALLETIF
KWalletEmu *kwlEmu = doc->init->kwalletEmu();
if (kwlEmu)
kwlEmu->suspendDocSignals();
#endif // CONFIG_KWALLETIF
/* We simply trigger all views to update their
* displayed values. This way they have a chance
* to get notified when some meta changes over time.
* (for example an entry expired).
* The _view_ is responsive for not updating its
* contents if nothing really changed!
*/
emit doc->dataChanged(doc);
#ifdef CONFIG_KWALLETIF
if (kwlEmu)
kwlEmu->resumeDocSignals();
#endif // CONFIG_KWALLETIF
metaCheckTimer->start(META_CHECK_TIMER_INTERVAL * 1000, true);
}
PwMDocList PwMDoc::openDocList;
unsigned int PwMDocList::unnamedDocCnt = 1;
PwMDoc::PwMDoc(QObject *parent, const char *name)
: PwMDocUi(parent, name)
, dataChangedLock (0)
{
deleted = false;
unnamedNum = 0;
getOpenDocList()->add(this, getTitle().latin1());
curDocStat = 0;
setMaxNumEntries();
_timer = new DocTimer(this);
timer()->start(DocTimer::id_mpwTimer);
timer()->start(DocTimer::id_autoLockTimer);
timer()->start(DocTimer::id_metaCheckTimer);
addCategory(DEFAULT_CATEGORY, 0, false);
listView = 0;
emit docCreated(this);
}
PwMDoc::~PwMDoc()
{
emit docClosed(this);
getOpenDocList()->del(this);
delete _timer;
}
PwMerror PwMDoc::saveDoc(char compress, const QString *file)
{
PwMerror ret, e;
string serialized;
QFile f;
QString tmpFileMoved(QString::null);
bool wasDeepLocked;
QString savedFilename(filename);
if (!file) {
if (filename == "")
return e_filename;
if (isDeepLocked()) {
/* We don't need to save any data.
* It's already all on disk, because
* we are deeplocked.
*/
unsetDocStatFlag(DOC_STAT_DISK_DIRTY);
ret = e_success;
return ret;
}
} else {
if (*file == "" && filename == "")
return e_filename;
if (*file != "")
filename = *file;
}
wasDeepLocked = isDeepLocked();
if (wasDeepLocked) {
/* We are deeplocked. That means all data is already
* on disk. BUT we need to do saving procedure,
* because *file != savedFilename.
* Additionally we need to tempoarly restore
* the old "filename", because deepLock() references it.
*/
QString newFilename(filename);
filename = savedFilename;
getDataChangedLock();
e = deepLock(false);
putDataChangedLock();
filename = newFilename;
switch (e) {
case e_success:
break;
case e_wrongPw:
case e_noPw:
emitDataChanged(this);
return e;
default:
emitDataChanged(this);
return e_openFile;
}
}
if (!isPwAvailable()) {
/* password is not available. This means, the
* document wasn't saved, yet.
*/
bool useChipcard = getDocStatFlag(DOC_STAT_USE_CHIPCARD);
QString pw(requestNewMpw(&useChipcard));
if (pw != "") {
currentPw = pw;
} else {
return e_noPw;
}
if (useChipcard) {
setDocStatFlag(DOC_STAT_USE_CHIPCARD);
} else {
unsetDocStatFlag(DOC_STAT_USE_CHIPCARD);
}
}
int _cryptAlgo = conf()->confGlobCryptAlgo();
int _hashAlgo = conf()->confGlobHashAlgo();
// sanity check for the selected algorithms
if (_cryptAlgo < PWM_CRYPT_BLOWFISH ||
_cryptAlgo > PWM_CRYPT_TWOFISH128) {
printWarn("Invalid Crypto-Algorithm selected! "
"Config-file seems to be corrupt. "
"Falling back to Blowfish.");
_cryptAlgo = PWM_CRYPT_BLOWFISH;
}
if (_hashAlgo < PWM_HASH_SHA1 ||
_hashAlgo > PWM_HASH_TIGER) {
printWarn("Invalid Hash-Algorithm selected! "
"Config-file seems to be corrupt. "
"Falling back to SHA1.");
_hashAlgo = PWM_HASH_SHA1;
}
char cryptAlgo = static_cast<char>(_cryptAlgo);
char hashAlgo = static_cast<char>(_hashAlgo);
if (conf()->confGlobMakeFileBackup()) {
if (!backupFile(filename))
return e_fileBackup;
}
if (QFile::exists(filename)) {
/* Move the existing file to some tmp file.
* When saving file succeeds, delete tmp file. Otherwise
* move tmp file back. See below.
*/
Randomizer *rnd = Randomizer::obj();
char rnd_buf[5];
sprintf(rnd_buf, "%X%X%X%X", rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF,
rnd->genRndChar() & 0xFF, rnd->genRndChar() & 0xFF);
tmpFileMoved = filename + "." + rnd_buf + ".mv";
if (!copyFile(filename, tmpFileMoved))
return e_openFile;
if (!QFile::remove(filename)) {
printWarn(string("removing orig file ")
+ filename.latin1()
+ " failed!");
}
}
f.setName(filename);
if (!f.open(IO_ReadWrite)) {
ret = e_openFile;
goto out_moveback;
}
e = writeFileHeader(hashAlgo, hashAlgo,
cryptAlgo, compress,
&currentPw, &f);
if (e == e_hashNotImpl) {
printDebug("PwMDoc::saveDoc(): writeFileHeader() failed: e_hashNotImpl");
f.close();
ret = e_hashNotImpl;
goto out_moveback;
} else if (e != e_success) {
printDebug("PwMDoc::saveDoc(): writeFileHeader() failed");
f.close();
ret = e_writeHeader;
goto out_moveback;
}
if (!serializeDta(&serialized)) {
printDebug("PwMDoc::saveDoc(): serializeDta() failed");
f.close();
ret = e_serializeDta;
goto out_moveback;
}
e = writeDataHash(hashAlgo, &serialized, &f);
if (e == e_hashNotImpl) {
printDebug("PwMDoc::saveDoc(): writeDataHash() failed: e_hashNotImpl");
f.close();
ret = e_hashNotImpl;
goto out_moveback;
} else if (e != e_success) {
printDebug("PwMDoc::saveDoc(): writeDataHash() failed");
f.close();
ret = e_writeHeader;
goto out_moveback;
}
if (!compressDta(&serialized, compress)) {
printDebug("PwMDoc::saveDoc(): compressDta() failed");
f.close();
ret = e_enc;
goto out_moveback;
}
e = encrypt(&serialized, &currentPw, &f, cryptAlgo);
if (e == e_weakPw) {
printDebug("PwMDoc::saveDoc(): encrypt() failed: e_weakPw");
f.close();
ret = e_weakPw;
goto out_moveback;
} else if (e == e_cryptNotImpl) {
printDebug("PwMDoc::saveDoc(): encrypt() failed: e_cryptNotImpl");
f.close();
ret = e_cryptNotImpl;
goto out_moveback;
} else if (e != e_success) {
printDebug("PwMDoc::saveDoc(): encrypt() failed");
f.close();
ret = e_enc;
goto out_moveback;
}
unsetDocStatFlag(DOC_STAT_DISK_DIRTY);
f.close();
+#ifndef _WIN32_
if (chmod(filename.latin1(),
conf()->confGlobFilePermissions())) {
printWarn(string("chmod failed: ") + strerror(errno));
}
+#endif
openDocList.edit(this, getTitle().latin1());
if (wasDeepLocked) {
/* Do _not_ save the data with the deepLock()
* call, because this will recurse
* into saveDoc()
*/
deepLock(true, false);
/* We don't check return value here, because
* it won't fail. See NOTE in deepLock()
*/
}
if (tmpFileMoved != QString::null) {
// now remove the moved file.
if (!QFile::remove(tmpFileMoved)) {
printWarn(string("removing file ")
+ tmpFileMoved.latin1()
+ " failed!");
}
}
ret = e_success;
printDebug(string("writing file { name: ")
+ filename.latin1() + " compress: "
+ tostr(static_cast<int>(compress)) + " cryptAlgo: "
+ tostr(static_cast<int>(cryptAlgo)) + " hashAlgo: "
+ tostr(static_cast<int>(hashAlgo))
+ " }");
goto out;
out_moveback:
if (tmpFileMoved != QString::null) {
if (copyFile(tmpFileMoved, filename)) {
if (!QFile::remove(tmpFileMoved)) {
printWarn(string("removing tmp file ")
+ filename.latin1()
+ " failed!");
}
} else {
printWarn(string("couldn't copy file ")
+ tmpFileMoved.latin1()
+ " back to "
+ filename.latin1());
}
}
out:
return ret;
}
PwMerror PwMDoc::openDoc(const QString *file, int openLocked)
{
PWM_ASSERT(file);
PWM_ASSERT(openLocked == 0 || openLocked == 1 || openLocked == 2);
string decrypted, dataHash;
PwMerror ret;
char cryptAlgo, dataHashType, compress;
unsigned int headerLen;
if (*file == "")
return e_readFile;
filename = *file;
/* check if this file is already open.
* This does not catch symlinks!
*/
if (!isDeepLocked()) {
if (getOpenDocList()->find(filename.latin1()))
return e_alreadyOpen;
}
QFile f(filename);
if (openLocked == 2) {
// open deep-locked
if (!QFile::exists(filename))
return e_openFile;
if (deepLock(true, false) != e_success)
return e_openFile;
goto out_success;
}
if (!f.open(IO_ReadOnly))
return e_openFile;
ret = checkHeader(&cryptAlgo, &currentPw, &compress, &headerLen,
&dataHashType, &dataHash, &f);
if (ret != e_success) {
printDebug("PwMDoc::openDoc(): checkHeader() failed");
f.close();
if (ret == e_wrongPw) {
wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
return ret;
} else if (ret == e_noPw ||
ret == e_fileVer ||
ret == e_fileFormat ||
ret == e_hashNotImpl) {
return ret;
} else
return e_readFile;
}
ret = decrypt(&decrypted, headerLen, &currentPw, cryptAlgo, &f);
if (ret == e_cryptNotImpl) {
printDebug("PwMDoc::openDoc(): decrypt() failed: e_cryptNotImpl");
f.close();
return e_cryptNotImpl;
} else if (ret != e_success) {
printDebug("PwMDoc::openDoc(): decrypt() failed");
f.close();
return e_readFile;
}
if (!decompressDta(&decrypted, compress)) {
printDebug("PwMDoc::openDoc(): decompressDta() failed");
f.close();
return e_fileCorrupt;
}
ret = checkDataHash(dataHashType, &dataHash, &decrypted);
if (ret == e_hashNotImpl) {
printDebug("PwMDoc::openDoc(): checkDataHash() failed: e_hashNotImpl");
f.close();
return e_hashNotImpl;
} else if (ret != e_success) {
printDebug("PwMDoc::openDoc(): checkDataHash() failed");
f.close();
return e_fileCorrupt;
}
if (!deSerializeDta(&decrypted, openLocked == 1)) {
printDebug("PwMDoc::openDoc(): deSerializeDta() failed");
f.close();
return e_readFile;
}
f.close();
timer()->start(DocTimer::id_mpwTimer);
timer()->start(DocTimer::id_autoLockTimer);
out_success:
openDocList.edit(this, getTitle().latin1());
emit docOpened(this);
return e_success;
}
PwMerror PwMDoc::writeFileHeader(char keyHash, char dataHash, char crypt, char compress,
QString *pw, QFile *f)
{
PWM_ASSERT(pw);
PWM_ASSERT(f);
//US ENH: or maybe a bug: checking here for listView does not make sense because we do not check anywhere else
//Wenn I sync, I open a doc without a view => listView is 0 => Assertion
//US PWM_ASSERT(listView);
if (f->writeBlock(FILE_ID_HEADER, strlen(FILE_ID_HEADER)) !=
static_cast<Q_LONG>(strlen(FILE_ID_HEADER))) {
return e_writeFile;
}
if (f->putch(PWM_FILE_VER) == -1 ||
f->putch(keyHash) == -1 ||
f->putch(dataHash) == -1 ||
f->putch(crypt) == -1 ||
f->putch(compress) == -1 ||
f->putch((getDocStatFlag(DOC_STAT_USE_CHIPCARD)) ?
(static_cast<char>(0x01)) : (static_cast<char>(0x00))) == -1) {
return e_writeFile;
}
// write bytes of NUL-data. These bytes are reserved for future-use.
const int bufSize = 64;
char tmp_buf[bufSize];
memset(tmp_buf, 0x00, bufSize);
if (f->writeBlock(tmp_buf, bufSize) != bufSize)
return e_writeFile;
switch (keyHash) {
case PWM_HASH_SHA1: {
const int hashlen = SHA1_HASH_LEN_BYTE;
Sha1 hash;
hash.sha1_write(reinterpret_cast<const byte *>(pw->latin1()), pw->length());
string ret = hash.sha1_read();
if (f->writeBlock(ret.c_str(), hashlen) != hashlen)
return e_writeFile;
break;
}
case PWM_HASH_SHA256:
/*... fall through */
case PWM_HASH_SHA384:
case PWM_HASH_SHA512:
case PWM_HASH_MD5:
case PWM_HASH_RMD160:
case PWM_HASH_TIGER:
{
if (!LibGCryptIf::available())
return e_hashNotImpl;
LibGCryptIf gc;
PwMerror err;
unsigned char *buf;
size_t hashLen;
err = gc.hash(&buf,
&hashLen,
reinterpret_cast<const unsigned char *>(pw->latin1()),
pw->length(),
keyHash);
if (err != e_success)
return e_hashNotImpl;
if (f->writeBlock(reinterpret_cast<const char *>(buf), hashLen)
!= static_cast<Q_LONG>(hashLen)) {
delete [] buf;
return e_hashNotImpl;
}
delete [] buf;
break;
}
default: {
return e_hashNotImpl;
} }
return e_success;
}
PwMerror PwMDoc::checkHeader(char *cryptAlgo, QString *pw, char *compress,
unsigned int *headerLength, char *dataHashType,
string *dataHash, QFile *f)
{
PWM_ASSERT(cryptAlgo);
PWM_ASSERT(pw);
PWM_ASSERT(headerLength);
PWM_ASSERT(dataHashType);
PWM_ASSERT(dataHash);
PWM_ASSERT(f);
int tmpRet;
// check "magic" header
const char magicHdr[] = FILE_ID_HEADER;
const int hdrLen = array_size(magicHdr) - 1;
char tmp[hdrLen];
if (f->readBlock(tmp, hdrLen) != hdrLen)
return e_readFile;
if (memcmp(tmp, magicHdr, hdrLen) != 0)
return e_fileFormat;
// read and check file ver
int fileV = f->getch();
if (fileV == -1)
return e_fileFormat;
if (fileV != PWM_FILE_VER)
return e_fileVer;
// read hash hash type
int keyHash = f->getch();
if (keyHash == -1)
return e_fileFormat;
// read data hash type
tmpRet = f->getch();
if (tmpRet == -1)
return e_fileFormat;
*dataHashType = tmpRet;
// read crypt algo
tmpRet = f->getch();
if (tmpRet == -1)
return e_fileFormat;
*cryptAlgo = tmpRet;
// get compression-algo
tmpRet = f->getch();
if (tmpRet == -1)
return e_fileFormat;
*compress = tmpRet;
// get the MPW-flag
int mpw_flag = f->getch();
if (mpw_flag == -1)
return e_fileFormat;
if (mpw_flag == 0x01)
setDocStatFlag(DOC_STAT_USE_CHIPCARD);
else
unsetDocStatFlag(DOC_STAT_USE_CHIPCARD);
// skip the "RESERVED"-bytes
if (!(f->at(f->at() + 64)))
return e_fileFormat;
*pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD));
if (*pw == "") {
/* the user didn't give a master-password
* or didn't insert a chipcard
*/
return e_noPw;
}
// verify key-hash
switch (keyHash) {
case PWM_HASH_SHA1: {
// read hash from header
const int hashLen = SHA1_HASH_LEN_BYTE;
string readHash;
int i;
for (i = 0; i < hashLen; ++i)
readHash.push_back(f->getch());
Sha1 hash;
hash.sha1_write(reinterpret_cast<const byte *>(pw->latin1()), pw->length());
string ret = hash.sha1_read();
if (ret != readHash)
return e_wrongPw; // hash doesn't match (wrong key)
break;
}
case PWM_HASH_SHA256:
/*... fall through */
case PWM_HASH_SHA384:
case PWM_HASH_SHA512:
case PWM_HASH_MD5:
case PWM_HASH_RMD160:
case PWM_HASH_TIGER: {
if (!LibGCryptIf::available())
return e_hashNotImpl;
LibGCryptIf gc;
PwMerror err;
unsigned char *buf;
size_t hashLen;
err = gc.hash(&buf,
&hashLen,
reinterpret_cast<const unsigned char *>(pw->latin1()),
pw->length(),
keyHash);
if (err != e_success)
return e_hashNotImpl;
string calcHash(reinterpret_cast<const char *>(buf),
static_cast<string::size_type>(hashLen));
delete [] buf;
// read hash from header
string readHash;
size_t i;
for (i = 0; i < hashLen; ++i)
readHash.push_back(f->getch());
if (calcHash != readHash)
return e_wrongPw; // hash doesn't match (wrong key)
break;
}
default: {
return e_hashNotImpl;
} }
// read the data-hash from the file
unsigned int hashLen, i;
switch (*dataHashType) {
case PWM_HASH_SHA1:
hashLen = SHA1_HASH_LEN_BYTE;
break;
case PWM_HASH_SHA256:
/*... fall through */
case PWM_HASH_SHA384:
case PWM_HASH_SHA512:
case PWM_HASH_MD5:
case PWM_HASH_RMD160:
case PWM_HASH_TIGER: {
if (!LibGCryptIf::available())
return e_hashNotImpl;
LibGCryptIf gc;
hashLen = gc.hashLength(*dataHashType);
if (hashLen == 0)
return e_hashNotImpl;
break;
}
default:
return e_hashNotImpl;
}
*dataHash = "";
for (i = 0; i < hashLen; ++i) {
tmpRet = f->getch();
if (tmpRet == -1)
return e_fileFormat;
dataHash->push_back(static_cast<char>(tmpRet));
}
*headerLength = f->at();
#ifndef PWM_EMBEDDED
printDebug(string("opening file { compress: ")
+ tostr(static_cast<int>(*compress)) + " cryptAlgo: "
+ tostr(static_cast<int>(*cryptAlgo)) + " keyHashAlgo: "
+ tostr(static_cast<int>(keyHash))
+ " }");
#else
printDebug(string("opening file { compress: ")
+ tostr((int)(*compress)) + " cryptAlgo: "
+ tostr((int)(*cryptAlgo)) + " keyHashAlgo: "
+ tostr((int)(keyHash))
+ " }");
#endif
return e_success;
}
PwMerror PwMDoc::writeDataHash(char dataHash, string *d, QFile *f)
{
PWM_ASSERT(d);
PWM_ASSERT(f);
switch (dataHash) {
case PWM_HASH_SHA1: {
const int hashLen = SHA1_HASH_LEN_BYTE;
Sha1 h;
h.sha1_write(reinterpret_cast<const byte *>(d->c_str()), d->size());
string hRet = h.sha1_read();
if (f->writeBlock(hRet.c_str(), hashLen) != hashLen)
return e_writeFile;
@@ -1837,824 +1840,828 @@ PwMerror PwMDoc::deepLock(bool lock, bool saveToFile)
} else if (ret != e_success) {
return e_lock;
}
}
timer()->stop(DocTimer::id_autoLockTimer);
clearDoc();
PwMDataItem d;
d.desc = IS_DEEPLOCKED_SHORTMSG.latin1();
d.comment = IS_DEEPLOCKED_MSG.latin1();
d.listViewPos = 0;
addEntry(DEFAULT_CATEGORY, &d, true);
lockAt(DEFAULT_CATEGORY, 0, true);
unsetDocStatFlag(DOC_STAT_DISK_DIRTY);
setDocStatFlag(DOC_STAT_DEEPLOCKED);
} else {
if (!isDeepLocked())
return e_lock;
ret = openDoc(&filename, (conf()->confGlobUnlockOnOpen())
? 0 : 1);
if (ret == e_wrongPw) {
return e_wrongPw;
} else if (ret != e_success) {
printDebug(string("PwMDoc::deepLock(false): ERR! openDoc() == ")
+ tostr(static_cast<int>(ret)));
return e_lock;
}
unsetDocStatFlag(DOC_STAT_DEEPLOCKED);
timer()->start(DocTimer::id_autoLockTimer);
}
emitDataChanged(this);
return e_success;
}
void PwMDoc::_deepUnlock()
{
deepLock(false);
}
void PwMDoc::clearDoc()
{
dti.clear();
PwMCategoryItem d;
d.name = DEFAULT_CATEGORY.latin1();
dti.dta.push_back(d);
currentPw = "";
unsetDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW);
}
void PwMDoc::changeCurrentPw()
{
if (currentPw == "")
return; // doc hasn't been saved. No mpw available.
bool useChipcard = getDocStatFlag(DOC_STAT_USE_CHIPCARD);
QString pw = requestMpwChange(&currentPw, &useChipcard);
if (pw == "")
return;
if (useChipcard)
setDocStatFlag(DOC_STAT_USE_CHIPCARD);
else
unsetDocStatFlag(DOC_STAT_USE_CHIPCARD);
setCurrentPw(pw);
}
void PwMDoc::setListViewPos(const QString &category, unsigned int index,
int pos)
{
unsigned int cat = 0;
if (!findCategory(category, &cat)) {
BUG();
return;
}
setListViewPos(cat, index, pos);
}
void PwMDoc::setListViewPos(unsigned int category, unsigned int index,
int pos)
{
dti.dta[category].d[index].listViewPos = pos;
/* FIXME workaround: don't flag dirty, because this function sometimes
* get's called when it shouldn't. It's because PwMView assumes
* the user resorted the UI on behalf of signal layoutChanged().
* This is somewhat broken and incorrect, but I've no other
* solution for now.
*/
// setDocStatFlag(DOC_STAT_DISK_DIRTY);
}
int PwMDoc::getListViewPos(const QString &category, unsigned int index)
{
unsigned int cat = 0;
if (!findCategory(category, &cat)) {
BUG();
return -1;
}
return dti.dta[cat].d[index].listViewPos;
}
void PwMDoc::findEntry(unsigned int category, PwMDataItem find, unsigned int searchIn,
vector<unsigned int> *foundPositions, bool breakAfterFound,
bool caseSensitive, bool exactWordMatch, bool sortByLvp)
{
PWM_ASSERT(foundPositions);
PWM_ASSERT(searchIn);
foundPositions->clear();
unsigned int i, entries = numEntries(category);
for (i = 0; i < entries; ++i) {
if (searchIn & SEARCH_IN_DESC) {
if (!compareString(find.desc, dti.dta[category].d[i].desc,
caseSensitive, exactWordMatch)) {
continue;
}
}
if (searchIn & SEARCH_IN_NAME) {
if (!compareString(find.name, dti.dta[category].d[i].name,
caseSensitive, exactWordMatch)) {
continue;
}
}
if (searchIn & SEARCH_IN_PW) {
bool wasLocked = isLocked(category, i);
getDataChangedLock();
lockAt(category, i, false);
if (!compareString(find.pw, dti.dta[category].d[i].pw,
caseSensitive, exactWordMatch)) {
lockAt(category, i, wasLocked);
putDataChangedLock();
continue;
}
lockAt(category, i, wasLocked);
putDataChangedLock();
}
if (searchIn & SEARCH_IN_COMMENT) {
if (!compareString(find.comment, dti.dta[category].d[i].comment,
caseSensitive, exactWordMatch)) {
continue;
}
}
if (searchIn & SEARCH_IN_URL) {
if (!compareString(find.url, dti.dta[category].d[i].url,
caseSensitive, exactWordMatch)) {
continue;
}
}
if (searchIn & SEARCH_IN_LAUNCHER) {
if (!compareString(find.launcher, dti.dta[category].d[i].launcher,
caseSensitive, exactWordMatch)) {
continue;
}
}
// all selected "searchIn" matched.
foundPositions->push_back(i);
if (breakAfterFound)
break;
}
if (sortByLvp && foundPositions->size() > 1) {
vector< pair<unsigned int /* foundPosition (real doc pos) */,
unsigned int /* lvp-pos */> > tmp_vec;
unsigned int i, items = foundPositions->size();
pair<unsigned int, unsigned int> tmp_pair;
for (i = 0; i < items; ++i) {
tmp_pair.first = (*foundPositions)[i];
tmp_pair.second = dti.dta[category].d[(*foundPositions)[i]].listViewPos;
tmp_vec.push_back(tmp_pair);
}
sort(tmp_vec.begin(), tmp_vec.end(), dta_lvp_greater());
foundPositions->clear();
for (i = 0; i < items; ++i) {
foundPositions->push_back(tmp_vec[i].first);
}
}
}
void PwMDoc::findEntry(const QString &category, PwMDataItem find, unsigned int searchIn,
vector<unsigned int> *foundPositions, bool breakAfterFound,
bool caseSensitive, bool exactWordMatch, bool sortByLvp)
{
PWM_ASSERT(foundPositions);
unsigned int cat = 0;
if (!findCategory(category, &cat)) {
foundPositions->clear();
return;
}
findEntry(cat, find, searchIn, foundPositions, breakAfterFound,
caseSensitive, exactWordMatch, sortByLvp);
}
bool PwMDoc::compareString(const string &s1, const string &s2, bool caseSensitive,
bool exactWordMatch)
{
QString _s1(s1.c_str());
QString _s2(s2.c_str());
if (!caseSensitive) {
_s1 = _s1.lower();
_s2 = _s2.lower();
}
if (exactWordMatch ? (_s1 == _s2) : (_s2.find(_s1) != -1))
return true;
return false;
}
bool PwMDoc::findCategory(const QString &name, unsigned int *index)
{
vector<PwMCategoryItem>::iterator i = dti.dta.begin(),
end = dti.dta.end();
while (i != end) {
if ((*i).name == name.latin1()) {
if (index) {
*index = i - dti.dta.begin();
}
return true;
}
++i;
}
return false;
}
bool PwMDoc::renameCategory(const QString &category, const QString &newName)
{
unsigned int cat = 0;
if (!findCategory(category, &cat))
return false;
return renameCategory(cat, newName);
}
bool PwMDoc::renameCategory(unsigned int category, const QString &newName,
bool dontFlagDirty)
{
if (category > numCategories() - 1)
return false;
dti.dta[category].name = newName.latin1();
if (!dontFlagDirty)
flagDirty();
return true;
}
bool PwMDoc::delCategory(const QString &category)
{
unsigned int cat = 0;
if (!findCategory(category, &cat))
return false;
return delCategory(cat);
}
bool PwMDoc::delCategory(unsigned int category, bool dontFlagDirty)
{
if (category > numCategories() - 1)
return false;
// We don't delete it, if it is the last existing
// category! Instead we rename it to "Default".
if (numCategories() > 1) {
dti.dta.erase(dti.dta.begin() + category);
} else {
renameCategory(category, DEFAULT_CATEGORY, dontFlagDirty);
return true;
}
if (!dontFlagDirty)
flagDirty();
return true;
}
void PwMDoc::delAllEmptyCat(bool dontFlagDirty)
{
vector<PwMCategoryItem>::iterator begin = dti.dta.begin(),
end = dti.dta.end(),
i = begin;
while (i != end) {
if (i->d.empty()) {
delCategory(begin - i, dontFlagDirty);
}
++i;
}
}
void PwMDoc::getCategoryList(vector<string> *list)
{
PWM_ASSERT(list);
list->clear();
vector<PwMCategoryItem>::iterator i = dti.dta.begin(),
end = dti.dta.end();
while (i != end) {
list->push_back(i->name);
++i;
}
}
void PwMDoc::getCategoryList(QStringList *list)
{
PWM_ASSERT(list);
list->clear();
vector<PwMCategoryItem>::iterator i = dti.dta.begin(),
end = dti.dta.end();
while (i != end) {
#ifndef PWM_EMBEDDED
list->push_back(i->name.c_str());
#else
list->append(i->name.c_str());
#endif
++i;
}
}
void PwMDoc::getEntryList(const QString &category, QStringList *list)
{
PWM_ASSERT(list);
unsigned int cat = 0;
if (!findCategory(category, &cat)) {
list->clear();
return;
}
getEntryList(cat, list);
}
void PwMDoc::getEntryList(const QString &category, vector<string> *list)
{
PWM_ASSERT(list);
unsigned int cat = 0;
if (!findCategory(category, &cat)) {
list->clear();
return;
}
getEntryList(cat, list);
}
void PwMDoc::getEntryList(unsigned int category, vector<string> *list)
{
PWM_ASSERT(list);
list->clear();
vector<PwMDataItem>::iterator begin = dti.dta[category].d.begin(),
end = dti.dta[category].d.end(),
i = begin;
while (i != end) {
list->push_back(i->desc);
++i;
}
}
void PwMDoc::getEntryList(unsigned int category, QStringList *list)
{
PWM_ASSERT(list);
list->clear();
vector<PwMDataItem>::iterator begin = dti.dta[category].d.begin(),
end = dti.dta[category].d.end(),
i = begin;
while (i != end) {
#ifndef PWM_EMBEDDED
list->push_back(i->desc.c_str());
#else
list->append(i->desc.c_str());
#endif
++i;
}
}
bool PwMDoc::execLauncher(const QString &category, unsigned int entryIndex)
{
unsigned int cat = 0;
if (!findCategory(category, &cat))
return false;
return execLauncher(cat, entryIndex);
}
bool PwMDoc::execLauncher(unsigned int category, unsigned int entryIndex)
{
+#ifndef _WIN32_
if (geteuid() == 0) {
rootAlertMsgBox();
return false;
}
+#endif
QString command(dti.dta[category].d[entryIndex].launcher.c_str());
bool wasLocked = isLocked(category, entryIndex);
if (command.find("$p") != -1) {
/* the user requested the password to be included
* into the command. We have to ask for the password,
* if it's locked. We do that by unlocking the entry
*/
if (!lockAt(category, entryIndex, false))
return false;
}
#ifndef PWM_EMBEDDED
command.replace("$d", dti.dta[category].d[entryIndex].desc.c_str());
command.replace("$n", dti.dta[category].d[entryIndex].name.c_str());
command.replace("$p", dti.dta[category].d[entryIndex].pw.c_str());
command.replace("$u", dti.dta[category].d[entryIndex].url.c_str());
command.replace("$c", dti.dta[category].d[entryIndex].comment.c_str());
#else
command.replace(QRegExp("$d"), dti.dta[category].d[entryIndex].desc.c_str());
command.replace(QRegExp("$n"), dti.dta[category].d[entryIndex].name.c_str());
command.replace(QRegExp("$p"), dti.dta[category].d[entryIndex].pw.c_str());
command.replace(QRegExp("$u"), dti.dta[category].d[entryIndex].url.c_str());
command.replace(QRegExp("$c"), dti.dta[category].d[entryIndex].comment.c_str());
#endif
command.append(" &");
QString customXterm(conf()->confGlobXtermCommand());
if (!customXterm.isEmpty())
command = customXterm + " " + command;
system(command.latin1());
lockAt(category, entryIndex, wasLocked);
return true;
}
bool PwMDoc::goToURL(const QString &category, unsigned int entryIndex)
{
unsigned int cat = 0;
if (!findCategory(category, &cat))
return false;
return goToURL(cat, entryIndex);
}
bool PwMDoc::goToURL(unsigned int category, unsigned int entryIndex)
{
+#ifndef _WIN32_
if (geteuid() == 0) {
rootAlertMsgBox();
return false;
}
+#endif
QString url(dti.dta[category].d[entryIndex].url.c_str());
if (url.isEmpty())
return false;
QString customBrowser(conf()->confGlobBrowserCommand());
if (!customBrowser.isEmpty()) {
browserProc.clearArguments();
browserProc << customBrowser << url;
if (browserProc.start(KProcess::DontCare))
return true;
}
browserProc.clearArguments();
browserProc << "konqueror" << url;
if (browserProc.start(KProcess::DontCare))
return true;
browserProc.clearArguments();
browserProc << "mozilla" << url;
if (browserProc.start(KProcess::DontCare))
return true;
browserProc.clearArguments();
browserProc << "opera" << url;
if (browserProc.start(KProcess::DontCare))
return true;
return false;
}
PwMerror PwMDoc::exportToText(const QString *file)
{
PWM_ASSERT(file);
if (QFile::exists(*file)) {
if (!QFile::remove(*file))
return e_accessFile;
}
QFile f(*file);
if (!f.open(IO_ReadWrite))
return e_openFile;
if (!unlockAll_tempoary()) {
f.close();
return e_lock;
}
// write header
string header = i18n("Password table generated by\nPwM v").latin1();
header += PACKAGE_VER;
header += i18n("\non ").latin1();
QDate currDate = QDate::currentDate();
QTime currTime = QTime::currentTime();
#ifndef PWM_EMBEDDED
header += currDate.toString("ddd MMMM d ").latin1();
header += currTime.toString("hh:mm:ss ").latin1();
#else
QString dfs = KGlobal::locale()->dateFormatShort();
bool ampm = KGlobal::locale()->use12Clock();
KGlobal::locale()->setDateFormatShort("%A %B %d");
KGlobal::locale()->setHore24Format(true);
header += KGlobal::locale()->formatDate(currDate, true, KLocale::Userdefined).latin1();
header += KGlobal::locale()->formatTime(currTime, true).latin1();
KGlobal::locale()->setDateFormatShort(dfs);
KGlobal::locale()->setHore24Format(!ampm);
#endif
header += tostr(currDate.year());
header += "\n==============================\n\n";
#ifndef PWM_EMBEDDED
if (f.writeBlock(header.c_str(), header.length()) != (Q_LONG)header.length()) {
unlockAll_tempoary(true);
f.close();
return e_writeFile;
}
#else
if (f.writeBlock(header.c_str(), header.length()) != (long)header.length()) {
unlockAll_tempoary(true);
f.close();
return e_writeFile;
}
#endif
unsigned int i, numCat = numCategories();
unsigned int j, numEnt;
string exp;
for (i = 0; i < numCat; ++i) {
numEnt = numEntries(i);
exp = "\n== Category: ";
exp += dti.dta[i].name;
exp += " ==\n";
#ifndef PWM_EMBEDDED
if (f.writeBlock(exp.c_str(), exp.length()) != (Q_LONG)exp.length()) {
unlockAll_tempoary(true);
f.close();
return e_writeFile;
}
#else
if (f.writeBlock(exp.c_str(), exp.length()) != (long)exp.length()) {
unlockAll_tempoary(true);
f.close();
return e_writeFile;
}
#endif
for (j = 0; j < numEnt; ++j) {
exp = "\n-- ";
exp += dti.dta[i].d[j].desc;
exp += " --\n";
exp += i18n("Username: ").latin1();
exp += dti.dta[i].d[j].name;
exp += "\n";
exp += i18n("Password: ").latin1();
exp += dti.dta[i].d[j].pw;
exp += "\n";
exp += i18n("Comment: ").latin1();
exp += dti.dta[i].d[j].comment;
exp += "\n";
exp += i18n("URL: ").latin1();
exp += dti.dta[i].d[j].url;
exp += "\n";
exp += i18n("Launcher: ").latin1();
exp += dti.dta[i].d[j].launcher;
exp += "\n";
#ifndef PWM_EMBEDDED
if (f.writeBlock(exp.c_str(), exp.length()) != (Q_LONG)exp.length()) {
unlockAll_tempoary(true);
f.close();
return e_writeFile;
}
#else
if (f.writeBlock(exp.c_str(), exp.length()) != (long)exp.length()) {
unlockAll_tempoary(true);
f.close();
return e_writeFile;
}
#endif
}
}
unlockAll_tempoary(true);
f.close();
return e_success;
}
PwMerror PwMDoc::importFromText(const QString *file, int format)
{
PWM_ASSERT(file);
if (format == 0)
return importText_PwM(file);
else if (format == -1) {
// probe for all formats
if (importText_PwM(file) == e_success)
return e_success;
dti.clear();
emitDataChanged(this);
// add next format here...
return e_fileFormat;
}
return e_invalidArg;
}
PwMerror PwMDoc::importText_PwM(const QString *file)
{
#ifndef PWM_EMBEDDED
PWM_ASSERT(file);
FILE *f;
int tmp;
ssize_t ret;
string curCat;
unsigned int entriesRead = 0;
PwMDataItem currItem;
f = fopen(file->latin1(), "r");
if (!f)
return e_openFile;
size_t ch_tmp_size = 1024;
char *ch_tmp = (char*)malloc(ch_tmp_size);
if (!ch_tmp) {
fclose(f);
return e_outOfMem;
}
// - check header
if (getline(&ch_tmp, &ch_tmp_size, f) == -1) // skip first line.
goto formatError;
// check version-string and return version in "ch_tmp".
if (fscanf(f, "PwM v%s", ch_tmp) != 1) {
// header not recognized as PwM generated header
goto formatError;
}
// set filepointer behind version-string-line previously checked
if (getline(&ch_tmp, &ch_tmp_size, f) == -1)
goto formatError;
// skip next line containing the build-date
if (getline(&ch_tmp, &ch_tmp_size, f) == -1)
goto formatError;
// read header termination line
if (getline(&ch_tmp, &ch_tmp_size, f) == -1)
goto formatError;
if (strcmp(ch_tmp, "==============================\n"))
goto formatError;
// - read entries
do {
// find beginning of next category
do {
tmp = fgetc(f);
} while (tmp == '\n' && tmp != EOF);
if (tmp == EOF)
break;
// decrement filepos by one
fseek(f, -1, SEEK_CUR);
// read cat-name
if (getline(&ch_tmp, &ch_tmp_size, f) == -1)
goto formatError;
// check cat-name format
if (memcmp(ch_tmp, "== Category: ", 13) != 0)
goto formatError;
if (memcmp(ch_tmp + (strlen(ch_tmp) - 1 - 3), " ==", 3) != 0)
goto formatError;
// copy cat-name
curCat.assign(ch_tmp + 13, strlen(ch_tmp) - 1 - 16);
do {
// find beginning of next entry
do {
tmp = fgetc(f);
} while (tmp == '\n' && tmp != EOF && tmp != '=');
if (tmp == EOF)
break;
if (tmp == '=') {
fseek(f, -1, SEEK_CUR);
break;
}
// decrement filepos by one
fseek(f, -1, SEEK_CUR);
// read desc-line
if (getline(&ch_tmp, &ch_tmp_size, f) == -1)
goto formatError;
// check desc-line format
if (memcmp(ch_tmp, "-- ", 3) != 0)
goto formatError;
if (memcmp(ch_tmp + (strlen(ch_tmp) - 1 - 3), " --", 3) != 0)
goto formatError;
// add desc-line
currItem.desc.assign(ch_tmp + 3, strlen(ch_tmp) - 1 - 6);
// read username-line
if ((ret = getline(&ch_tmp, &ch_tmp_size, f)) == -1)
goto formatError;
if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.name))
goto formatError;
// read pw-line
if ((ret = getline(&ch_tmp, &ch_tmp_size, f)) == -1)
goto formatError;
if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.pw))
goto formatError;
// read comment-line
if ((ret = getline(&ch_tmp, &ch_tmp_size, f)) == -1)
goto formatError;
if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.comment))
goto formatError;
// read URL-line
if ((ret = getline(&ch_tmp, &ch_tmp_size, f)) == -1)
goto formatError;
if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.url))
goto formatError;
// read launcher-line
if ((ret = getline(&ch_tmp, &ch_tmp_size, f)) == -1)
goto formatError;
if (!textExtractEntry_PwM(ch_tmp, ret, &currItem.launcher))
goto formatError;
currItem.lockStat = true;
currItem.listViewPos = -1;
addEntry(curCat.c_str(), &currItem, true);
++entriesRead;
} while (1);
} while (1);
if (!entriesRead)
goto formatError;
free(ch_tmp);
fclose(f);
flagDirty();
return e_success;
formatError:
free(ch_tmp);
fclose(f);
return e_fileFormat;
#else
PWM_ASSERT(file);
QFile f(file->latin1());
int tmp;
ssize_t ret;
string curCat;
unsigned int entriesRead = 0;
PwMDataItem currItem;
bool res = f.open(IO_ReadOnly);
if (res == false)
return e_openFile;
unsigned int ch_tmp_size = 1024;
char *ch_tmp = (char*)malloc(ch_tmp_size);
if (!ch_tmp) {
f.close();
return e_outOfMem;
}
// - check header
if (f.readLine(ch_tmp, ch_tmp_size) == -1) // skip first line.
goto formatError;
//US read fileversion first, then check if ok.
if (f.readLine(ch_tmp, ch_tmp_size) == -1)
goto formatError;
// check version-string and return version in "ch_tmp".
//US if (fscanf(f, "PwM v%s", ch_tmp) != 1) {
//US // header not recognized as PwM generated header
//US goto formatError;
//US }
//US set filepointer behind version-string-line previously checked
//US if (f.readLine(ch_tmp, ch_tmp_size) == -1)
//US goto formatError;
// skip next line containing the build-date
if (f.readLine(ch_tmp, ch_tmp_size) == -1)
goto formatError;
// read header termination line
if (f.readLine(ch_tmp, ch_tmp_size) == -1)
goto formatError;
if (strcmp(ch_tmp, "==============================\n"))
goto formatError;
// - read entries
do {
// find beginning of next category
do {
tmp = f.getch();
} while (tmp == '\n' && tmp != EOF);
if (tmp == EOF)
break;
// decrement filepos by one
f.at(f.at()-1);
// read cat-name
if (f.readLine(ch_tmp, ch_tmp_size) == -1)
goto formatError;
// check cat-name format
if (memcmp(ch_tmp, "== Category: ", 13) != 0)
goto formatError;
if (memcmp(ch_tmp + (strlen(ch_tmp) - 1 - 3), " ==", 3) != 0)
goto formatError;
// copy cat-name
curCat.assign(ch_tmp + 13, strlen(ch_tmp) - 1 - 16);
do {
// find beginning of next entry
do {
tmp = f.getch();
} while (tmp == '\n' && tmp != EOF && tmp != '=');
if (tmp == EOF)
break;
if (tmp == '=') {
f.at(f.at()-1);
break;
}
// decrement filepos by one
f.at(f.at()-1);
// read desc-line
if (f.readLine(ch_tmp, ch_tmp_size) == -1)
diff --git a/pwmanager/pwmanager/spinforsignal.h b/pwmanager/pwmanager/spinforsignal.h
index ec6103b..f3cabee 100644
--- a/pwmanager/pwmanager/spinforsignal.h
+++ b/pwmanager/pwmanager/spinforsignal.h
@@ -1,55 +1,57 @@
/***************************************************************************
* *
* copyright (C) 2003, 2004 by Michael Buesch *
* email: mbuesch@freenet.de *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 *
* as published by the Free Software Foundation. *
* *
***************************************************************************/
/***************************************************************************
* copyright (C) 2004 by Ulf Schenk
* This file is originaly based on version 1.0.1 of pwmanager
* and was modified to run on embedded devices that run microkde
*
* $Id$
**************************************************************************/
#ifndef SPINFORSIGNAL_H
#define SPINFORSIGNAL_H
#include <qobject.h>
+#ifndef _WIN32_
#include <stdint.h>
+#endif
#include <string>
using std::string;
/** non-ui-blocking spin for a QT-signal */
class SpinForSignal : public QObject
{
Q_OBJECT
public:
SpinForSignal();
~SpinForSignal() {}
/** do spin for signal */
void spin(uint32_t *u32, string *str);
/** cancel spinning */
void cancelSpin();
public slots:
void u32_str_slot(uint32_t u32, const string &str);
protected:
volatile bool doSpin;
uint32_t u32_storage;
string str_storage;
protected:
inline void spinSleep();
void _spin();
};
#endif