-rw-r--r-- | pwmanager/pwmanager/blowfish.h | 11 | ||||
-rw-r--r-- | pwmanager/pwmanager/gpasmanfile.cpp | 16 | ||||
-rw-r--r-- | pwmanager/pwmanager/htmlgen.cpp | 2 | ||||
-rw-r--r-- | pwmanager/pwmanager/ipc.cpp | 7 | ||||
-rw-r--r-- | pwmanager/pwmanager/ipc.h | 5 | ||||
-rw-r--r-- | pwmanager/pwmanager/libgcryptif.h | 7 | ||||
-rw-r--r-- | pwmanager/pwmanager/pwm.cpp | 1 | ||||
-rw-r--r-- | pwmanager/pwmanager/pwmanager.pro | 2 | ||||
-rw-r--r-- | pwmanager/pwmanager/pwmdoc.cpp | 9 | ||||
-rw-r--r-- | pwmanager/pwmanager/spinforsignal.h | 2 |
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("<"); break; case '>': ret.append(">"); break; case '&': ret.append("&"); break; case '\"': ret.append("""); break; case 'ä': ret.append("ä"); break; case 'Ä': ret.append("Ä"); break; case 'ü': ret.append("ü"); break; case 'Ü': ret.append("Ü"); break; case 'ö': ret.append("ö"); break; case 'Ö': ret.append("Ö"); break; case 'ß': ret.append("ß"); break; case '¿': ret.append("€"); 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 @@ -1221,245 +1221,246 @@ bool PwM::checkAndAskForKWalletEmu() 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,252 +1,253 @@ /*************************************************************************** * * * 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) { @@ -316,388 +317,390 @@ PwMDoc::PwMDoc(QObject *parent, const char *name) 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, ¤tPw, &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, ¤tPw, &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, ¤tPw, &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, ¤tPw, 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); @@ -2029,440 +2032,444 @@ void PwMDoc::findEntry(const QString &category, PwMDataItem find, unsigned int s 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; 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 |