From d3925ba5bd25224bc4a60d3d6a107c464994a1ea Mon Sep 17 00:00:00 2001 From: ulf69 Date: Wed, 15 Sep 2004 17:53:22 +0000 Subject: initial revision --- diff --git a/pwmanager/BUGS b/pwmanager/BUGS new file mode 100644 index 0000000..2856a41 --- a/dev/null +++ b/pwmanager/BUGS @@ -0,0 +1,3 @@ +PwManager BUGS +============== + diff --git a/pwmanager/COPYING.LGPL b/pwmanager/COPYING.LGPL new file mode 100644 index 0000000..cd46641 --- a/dev/null +++ b/pwmanager/COPYING.LGPL @@ -0,0 +1,517 @@ +All source-files explicitly marked as LGPL licensed in their header, +are distributed under the conditions of the following license: + + + + + + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations +below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. +^L + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it +becomes a de-facto standard. To achieve this, non-free programs must +be allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. +^L + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control +compilation and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. +^L + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. +^L + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at least + three years, to give the same user the materials specified in + Subsection 6a, above, for a charge no more than the cost of + performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. +^L + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. +^L + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply, and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License +may add an explicit geographical distribution limitation excluding those +countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. +^L + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS +^L + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms +of the ordinary General Public License). + + To apply these terms, attach the following notices to the library. +It is safest to attach them to the start of each source file to most +effectively convey the exclusion of warranty; and each file should +have at least the "copyright" line and a pointer to where the full +notice is found. + + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or +your school, if any, to sign a "copyright disclaimer" for the library, +if necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James + Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/pwmanager/CodingStyle b/pwmanager/CodingStyle new file mode 100644 index 0000000..67beae8 --- a/dev/null +++ b/pwmanager/CodingStyle @@ -0,0 +1,36 @@ + + PwManager coding style + +This program is being developed with the linux-kernel coding-style +in mind. Please read these guidelines first, to get a basic +knowledge of the style. You can find it in +/usr/src/linux/Documentation/CodingStyle for example. + +A few other guidelines apply to this program, too: + +- Please use new-style C++ casts, if you need to make a cast. + +- The class PwMDoc is _only_ for internal document-data- + management. Don't put any view- or user-interface-stuff in + it. Not even a MessageBox. You may use the class PwMDocUi + to add UI-functionality to the document. + +- Don't add any document related stuff to another class + than PwMDoc. Exception: Put it into its own class and + invoke this class from within PwMDoc. + +- This program makes extensive use of inline functions, for + example to access data-members from outside of the class. + Please try to do so, too. + +- Don't try to optimize code for speed, where speed doesn't + matter. Instead optimize it for readability. + +- In the code we use the string "PwM" instead of "PwManager", + where needed. This has two reasons. The original name of + this program was "PwM". The second reason is that it's shorter. + +- It's an absolute requirement to have fun while developing + code for this application. + + Michael Buesch diff --git a/pwmanager/Makefile.am b/pwmanager/Makefile.am new file mode 100644 index 0000000..91202d2 --- a/dev/null +++ b/pwmanager/Makefile.am @@ -0,0 +1,26 @@ +SUBDIRS = pwmanager + +AUTOMAKE_OPTIONS = dist-bzip2 + +MAINTAINERCLEANFILES = subdirs configure.in acinclude.m4 configure.files + +EXTRA_DIST = rpm debian file-format keycard-format COPYING.LGPL CodingStyle + +# target to generate a .pot file manually (without scripty) +messages_manually: + extractrc `find . -name "*.rc" -o -name "*.ui"` > rc.cpp + LIST=`find . -name \*.h -o -name \*.hh -o -name \*.H -o -name \*.hxx -o -name \*.hpp -o -name \*.cpp -o -name \*.cc -o -name \*.cxx -o -name \*.ecpp -o -name \*.C`; \ + if test -n "$$LIST"; then \ + xgettext -ki18n -kI18N_NOOP -o ./pwmanager.pot $$LIST ; \ + fi + rm -f rc.cpp + +# target for automatic .pot file merging by scripty. +# disable this target to disable automatic merging. +#messages: rc.cpp +# $(EXTRACTRC) `find . -name "*.rc" -o -name "*.ui"` > rc.cpp +# LIST=`find . -name \*.h -o -name \*.hh -o -name \*.H -o -name \*.hxx -o -name \*.hpp -o -name \*.cpp -o -name \*.cc -o -name \*.cxx -o -name \*.ecpp -o -name \*.C`; \ +# if test -n "$$LIST"; then \ +# $(XGETTEXT) $$LIST -o $(podir)/pwmanager.pot; \ +# fi +# rm -f rc.cpp diff --git a/pwmanager/NEWS b/pwmanager/NEWS new file mode 100644 index 0000000..8d1c8b6 --- a/dev/null +++ b/pwmanager/NEWS @@ -0,0 +1 @@ + diff --git a/pwmanager/VERSION b/pwmanager/VERSION new file mode 100644 index 0000000..df6f065 --- a/dev/null +++ b/pwmanager/VERSION @@ -0,0 +1 @@ +PwManager 1.0 diff --git a/pwmanager/configure.in.bot b/pwmanager/configure.in.bot new file mode 100644 index 0000000..f281f69 --- a/dev/null +++ b/pwmanager/configure.in.bot @@ -0,0 +1,34 @@ +dnl Put here things to be done at the very end - telling users +dnl about additional packages to install. + +if test "${keycard_available}" != "yes" ; then + echo "" + echo "PwManager is built without chipcard (Smartcard) support." + echo "Either libchipcard is unavailable, or you have manually" + echo "disabled compiling of chipcard support." + echo "" +fi + +if test "${kwallet_available}" != "yes" ; then + echo "" + echo "PwManager is built without KWallet support." + echo "Either KWallet is unavailable (KDE-3.2 not installed), or" + echo "you have manually disabled compiling of KWallet support." + echo "" +fi + +if test "${bzlib_available}" != "yes" ; then + echo "" + echo "PwManager: FATAL! libbzip2 not found!" +fi + +if test "${zlib_available}" != "yes" ; then + echo "" + echo "PwManager: FATAL! zlib not found!" +fi + +if test "`echo ${DO_NOT_COMPILE} | grep "pwmanager" | awk '{print $0}'`" != "" ; then + echo "" + echo "PwManager compilation is disabled because of missing required libraries!" + echo "" +fi diff --git a/pwmanager/file-format b/pwmanager/file-format new file mode 100644 index 0000000..610ab51 --- a/dev/null +++ b/pwmanager/file-format @@ -0,0 +1,137 @@ +<========================> +< Format of *.pwm file > +<========================> +fileversion: 0x05 revision: 0x01 + +(note: another revision doesn't change fore- or + backward compatibility) + + +The file has a header and a data-body. + +**************************************************** +* The header is build from the following elements: * +**************************************************** +PWM_PASSWORD_FILE +[FILEVER] +[KEY-HASH-ALGO] +[DATA-HASH-ALGO] +[CRYPT-ALGO] +[COMPRESSED-FLAG] +[MPW-FLAG] +[BYTES-RESERVED] +[KEY-HASH] +[DATA-HASH] + + +(note: fields marked with ~ were added _after_ + revision 0x01) + + +PWM_PASSWORD_FILE is a magic string to indentify the file. +This string is put directly at offset 0x00 of the file. + +[FILEVER] is one byte for holding the file-version. +This byte is directly appended to the "magic-string". +(no newline or other separators between these fields) + +[HASH-ALGO] is one byte for holding the type of the hash-algorithm +used to hash the key. +0x01 => SHA1 + +[DATA-HASH-ALGO] is one byte for holding the type of the +hash-algorithm used to hash the raw data-stream. +0x01 => SHA1 + +[CRYPT-ALGO] is one byte containing the type of the crypt-algorithm +used to encrypt the data. +0x01 => Blowfish + +[COMPRESSED-FLAG] is one byte which can be +0x00 => not compressed +0x01 => compressed with gzip +0x02 => compressed with bzip2 + +[MPW-FLAG] is one byte, either 0x00 if +we used a master password to encrypt the data, +or 0x01, if we used a chipcard to encrypt the data. + +[BYTES-RESERVED] +64-bytes reserved for future-use. +Set all these to 0x00. + +[KEY-HASH] is the hash of the key. This field has no constant +length, because it's length depends on the algorithm +used in HASH-ALGO. + +[DATA-HASH] is a hash of the raw, unencrypted, serialized +data stream. + + +************** +* Data-body: * +************** + +The data-body follows the header directly. +It contains the encrypted serialized data in XML-format. +It may be compressed. +For an example +how to serialize the data, have a look at: +PwMDoc::serializeDta(); +PwMDoc::deSerializeDta(); +The class "Serializer" +PwMDoc::encrypt(); +PwMDoc::decrypt(); + +These functions are called by: +PwMDoc::saveDoc(); +PwMDoc::openDoc(); +so, please have a look at these two functions, too. + + + +Example of an XML-data-block: + + + + + + sampleDesc + sampleName + samplePw + sampleComment + sampleUrl + sampleLauncher + sampleListViewPos + 0 + + + sampleDesc + sampleName + samplePw + sampleComment + sampleUrl + sampleLauncher + sampleListViewPos + 1 + + + + + +2004-06-05: +So I introduced shorter names for the entries. We also have to support +the old names to be backward compatibel. +New names are: +PwM-xml-dat = P + = + = + = + = + = + =

+ = + = + = + = + = diff --git a/pwmanager/keycard-format b/pwmanager/keycard-format new file mode 100644 index 0000000..1ae1b5e --- a/dev/null +++ b/pwmanager/keycard-format @@ -0,0 +1,55 @@ +<=========================> +< Format of PwM-KeyCard > +<=========================> +cardformat version: 0x01 + +The keycard has a small header area and a key-data body. + +The header is built with the following scheme: + +PWMKEYCARD +[CARDVER] +[CARD-ID] +[KEYDATA-LENGTH] + + +After this header, the key-data-body with the length +[KEYDATA-LENGTH] follows. + +Explanation of the header-fields: + +PWMKEYCARD is a magic string at the beginning of the card +to indentify the chipcard as a "pwm-keycard". + +[CARDVER] is one byte for holding the card-format version. + +[CARD-ID] are 4 bytes (an unsigned BIG-ENDIAN value) +to hold an ID number for the card. + +[KEYDATA-LENGTH] are 2 bytes (an unsigned short) for holding +the length of the key-data in BIG-ENDIAN format. + + +******************************* +* KeyCard backup-image format * +******************************* +backup image version: 0x01 + +PWMKEYCARD_BACKUPIMAGE +[IMAGEVER] +[CARD-ID] +[KEYDATA] + + +PWMKEYCARD_BACKUPIMAGE +magic header. + +[IMAGEVER] +version indentifier of the backup-image. + +[CARD-ID] +card-ID. see keycard-format. + +[KEYDATA] +All data after CARD-ID until the end of the file +is treated as the key itself. diff --git a/pwmanager/pwmanager/addentrywnd.cpp b/pwmanager/pwmanager/addentrywnd.cpp new file mode 100644 index 0000000..fa98075 --- a/dev/null +++ b/pwmanager/pwmanager/addentrywnd.cpp @@ -0,0 +1,203 @@ +/**************************************************************************** +** Form implementation generated from reading ui file 'addentrywnd.ui' +** +** Created: Tue Sep 14 13:42:03 2004 +** by: The User Interface Compiler ($Id$) +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ + +#include "addentrywnd.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Constructs a addEntryWnd as a child of 'parent', with the + * name 'name' and widget flags set to 'f'. + * + * The dialog will by default be modeless, unless you set 'modal' to + * TRUE to construct a modal dialog. + */ +addEntryWnd::addEntryWnd( QWidget* parent, const char* name, bool modal, WFlags fl ) + : QDialog( parent, name, modal, fl ) +{ + if ( !name ) + setName( "addEntryWnd" ); + + launcherLineEdit = new QLineEdit( this, "launcherLineEdit" ); + launcherLineEdit->setGeometry( QRect( 310, 90, 250, 21 ) ); + + cancelButton = new QPushButton( this, "cancelButton" ); + cancelButton->setGeometry( QRect( 290, 320, 260, 27 ) ); + + generateButton = new QPushButton( this, "generateButton" ); + generateButton->setGeometry( QRect( 137, 210, 120, 27 ) ); + + descLineEdit = new QLineEdit( this, "descLineEdit" ); + descLineEdit->setGeometry( QRect( 10, 30, 250, 20 ) ); + + categoryComboBox = new QComboBox( FALSE, this, "categoryComboBox" ); + categoryComboBox->setGeometry( QRect( 10, 80, 250, 27 ) ); + categoryComboBox->setEditable( TRUE ); + categoryComboBox->setSizeLimit( 100 ); + categoryComboBox->setAutoCompletion( TRUE ); + categoryComboBox->setDuplicatesEnabled( FALSE ); + + usernameLineEdit = new QLineEdit( this, "usernameLineEdit" ); + usernameLineEdit->setGeometry( QRect( 10, 140, 250, 20 ) ); + + pwLineEdit = new QLineEdit( this, "pwLineEdit" ); + pwLineEdit->setGeometry( QRect( 10, 190, 250, 20 ) ); + pwLineEdit->setEchoMode( QLineEdit::Password ); + + urlLineEdit = new QLineEdit( this, "urlLineEdit" ); + urlLineEdit->setGeometry( QRect( 10, 269, 250, 20 ) ); + + textLabel1_3 = new QLabel( this, "textLabel1_3" ); + textLabel1_3->setGeometry( QRect( 276, 10, 20, 280 ) ); + textLabel1_3->setFrameShape( QLabel::VLine ); + + textLabel1 = new QLabel( this, "textLabel1" ); + textLabel1->setGeometry( QRect( 10, 10, 250, 20 ) ); + + textLabel1_2 = new QLabel( this, "textLabel1_2" ); + textLabel1_2->setGeometry( QRect( 10, 60, 250, 20 ) ); + + textLabel2 = new QLabel( this, "textLabel2" ); + textLabel2->setGeometry( QRect( 10, 120, 250, 20 ) ); + textLabel2->setFrameShape( QLabel::NoFrame ); + textLabel2->setFrameShadow( QLabel::Plain ); + + textLabel3 = new QLabel( this, "textLabel3" ); + textLabel3->setGeometry( QRect( 10, 170, 250, 20 ) ); + + textLabel2_2 = new QLabel( this, "textLabel2_2" ); + textLabel2_2->setGeometry( QRect( 10, 248, 250, 20 ) ); + + textLabel3_2 = new QLabel( this, "textLabel3_2" ); + textLabel3_2->setGeometry( QRect( 309, 8, 250, 20 ) ); + + textLabel1_4 = new QLabel( this, "textLabel1_4" ); + textLabel1_4->setGeometry( QRect( 310, 30, 250, 16 ) ); + + textLabel3_3 = new QLabel( this, "textLabel3_3" ); + textLabel3_3->setGeometry( QRect( 310, 50, 130, 16 ) ); + + textLabel2_3 = new QLabel( this, "textLabel2_3" ); + textLabel2_3->setGeometry( QRect( 310, 70, 130, 16 ) ); + + textLabel5 = new QLabel( this, "textLabel5" ); + textLabel5->setGeometry( QRect( 440, 70, 120, 16 ) ); + + textLabel4_2 = new QLabel( this, "textLabel4_2" ); + textLabel4_2->setGeometry( QRect( 440, 50, 120, 16 ) ); + + revealButton = new QPushButton( this, "revealButton" ); + revealButton->setGeometry( QRect( 10, 210, 120, 27 ) ); + revealButton->setToggleButton( TRUE ); + + okButton = new QPushButton( this, "okButton" ); + okButton->setGeometry( QRect( 20, 320, 260, 27 ) ); + + groupBox1 = new QGroupBox( this, "groupBox1" ); + groupBox1->setGeometry( QRect( 300, 140, 260, 150 ) ); + + commentDummy = new QLabel( groupBox1, "commentDummy" ); + commentDummy->setGeometry( QRect( 10, 20, 240, 80 ) ); + + advancedCommentButton = new QPushButton( groupBox1, "advancedCommentButton" ); + advancedCommentButton->setGeometry( QRect( 10, 110, 240, 30 ) ); + advancedCommentButton->setToggleButton( TRUE ); + languageChange(); + resize( QSize(570, 357).expandedTo(minimumSizeHint()) ); + clearWState( WState_Polished ); + + // signals and slots connections + connect( generateButton, SIGNAL( clicked() ), this, SLOT( generateButton_slot() ) ); + connect( revealButton, SIGNAL( toggled(bool) ), this, SLOT( revealButton_slot() ) ); + connect( cancelButton, SIGNAL( clicked() ), this, SLOT( cancelButton_slot() ) ); + connect( okButton, SIGNAL( clicked() ), this, SLOT( okButton_slot() ) ); + connect( advancedCommentButton, SIGNAL( toggled(bool) ), this, SLOT( advancedCommentButton_slot(bool) ) ); + + // tab order + setTabOrder( descLineEdit, categoryComboBox ); + setTabOrder( categoryComboBox, usernameLineEdit ); + setTabOrder( usernameLineEdit, pwLineEdit ); + setTabOrder( pwLineEdit, revealButton ); + setTabOrder( revealButton, generateButton ); + setTabOrder( generateButton, urlLineEdit ); + setTabOrder( urlLineEdit, launcherLineEdit ); + setTabOrder( launcherLineEdit, okButton ); + setTabOrder( okButton, cancelButton ); + +} + +/* + * Destroys the object and frees any allocated resources + */ +addEntryWnd::~addEntryWnd() +{ + // no need to delete child widgets, Qt does it all for us +} + +/* + * Sets the strings of the subwidgets using the current + * language. + */ +void addEntryWnd::languageChange() +{ + setCaption( tr( "edit/add a password-entry" ) ); + cancelButton->setText( tr( "&Cancel" ) ); + generateButton->setText( tr( "&Generate" ) ); + textLabel1_3->setText( QString::null ); + textLabel1->setText( tr( "Description:" ) ); + textLabel1_2->setText( tr( "Category:" ) ); + textLabel2->setText( tr( "Username:" ) ); + textLabel3->setText( tr( "Password:" ) ); + textLabel2_2->setText( tr( "URL:" ) ); + textLabel3_2->setText( tr( "Launcher:" ) ); + textLabel1_4->setText( tr( "$d = Description" ) ); + textLabel3_3->setText( tr( "$n = Username" ) ); + textLabel2_3->setText( tr( "$c = Comment" ) ); + textLabel5->setText( tr( "$u = URL" ) ); + textLabel4_2->setText( tr( "$p = Password" ) ); + revealButton->setText( tr( "&Reveal" ) ); + okButton->setText( tr( "&OK" ) ); + groupBox1->setTitle( tr( "Comment:" ) ); + commentDummy->setText( QString::null ); + advancedCommentButton->setText( tr( "advanced comment" ) ); +} + +void addEntryWnd::okButton_slot() +{ + qWarning( "addEntryWnd::okButton_slot(): Not implemented yet" ); +} + +void addEntryWnd::cancelButton_slot() +{ + qWarning( "addEntryWnd::cancelButton_slot(): Not implemented yet" ); +} + +void addEntryWnd::revealButton_slot() +{ + qWarning( "addEntryWnd::revealButton_slot(): Not implemented yet" ); +} + +void addEntryWnd::generateButton_slot() +{ + qWarning( "addEntryWnd::generateButton_slot(): Not implemented yet" ); +} + +void addEntryWnd::advancedCommentButton_slot(bool) +{ + qWarning( "addEntryWnd::advancedCommentButton_slot(bool): Not implemented yet" ); +} + diff --git a/pwmanager/pwmanager/addentrywnd.h b/pwmanager/pwmanager/addentrywnd.h new file mode 100644 index 0000000..905e265 --- a/dev/null +++ b/pwmanager/pwmanager/addentrywnd.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** Form interface generated from reading ui file 'addentrywnd.ui' +** +** Created: Tue Sep 14 13:42:03 2004 +** by: The User Interface Compiler ($Id$) +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ + +#ifndef ADDENTRYWND_H +#define ADDENTRYWND_H + +#include +#include + +class QVBoxLayout; +class QHBoxLayout; +class QGridLayout; +class QSpacerItem; +class QLineEdit; +class QPushButton; +class QComboBox; +class QLabel; +class QGroupBox; + +class addEntryWnd : public QDialog +{ + Q_OBJECT + +public: + addEntryWnd( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~addEntryWnd(); + + QLineEdit* launcherLineEdit; + QPushButton* cancelButton; + QPushButton* generateButton; + QLineEdit* descLineEdit; + QComboBox* categoryComboBox; + QLineEdit* usernameLineEdit; + QLineEdit* pwLineEdit; + QLineEdit* urlLineEdit; + QLabel* textLabel1_3; + QLabel* textLabel1; + QLabel* textLabel1_2; + QLabel* textLabel2; + QLabel* textLabel3; + QLabel* textLabel2_2; + QLabel* textLabel3_2; + QLabel* textLabel1_4; + QLabel* textLabel3_3; + QLabel* textLabel2_3; + QLabel* textLabel5; + QLabel* textLabel4_2; + QPushButton* revealButton; + QPushButton* okButton; + QGroupBox* groupBox1; + QLabel* commentDummy; + QPushButton* advancedCommentButton; + +public slots: + virtual void okButton_slot(); + virtual void cancelButton_slot(); + virtual void revealButton_slot(); + virtual void generateButton_slot(); + virtual void advancedCommentButton_slot(bool on); + +protected: + +protected slots: + virtual void languageChange(); + +}; + +#endif // ADDENTRYWND_H diff --git a/pwmanager/pwmanager/addentrywnd.ui b/pwmanager/pwmanager/addentrywnd.ui new file mode 100644 index 0000000..7ea7342 --- a/dev/null +++ b/pwmanager/pwmanager/addentrywnd.ui @@ -0,0 +1,483 @@ + +addEntryWnd + + + addEntryWnd + + + + 0 + 0 + 570 + 357 + + + + edit/add a password-entry + + + + launcherLineEdit + + + + 310 + 90 + 250 + 21 + + + + + + cancelButton + + + + 290 + 320 + 260 + 27 + + + + &Cancel + + + + + generateButton + + + + 137 + 210 + 120 + 27 + + + + &Generate + + + + + descLineEdit + + + + 10 + 30 + 250 + 20 + + + + + + categoryComboBox + + + + 10 + 80 + 250 + 27 + + + + true + + + 100 + + + true + + + false + + + + + usernameLineEdit + + + + 10 + 140 + 250 + 20 + + + + + + pwLineEdit + + + + 10 + 190 + 250 + 20 + + + + Password + + + + + urlLineEdit + + + + 10 + 269 + 250 + 20 + + + + + + textLabel1_3 + + + + 276 + 10 + 20 + 280 + + + + VLine + + + + + + + + textLabel1 + + + + 10 + 10 + 250 + 20 + + + + Description: + + + + + textLabel1_2 + + + + 10 + 60 + 250 + 20 + + + + Category: + + + + + textLabel2 + + + + 10 + 120 + 250 + 20 + + + + NoFrame + + + Plain + + + Username: + + + + + textLabel3 + + + + 10 + 170 + 250 + 20 + + + + Password: + + + + + textLabel2_2 + + + + 10 + 248 + 250 + 20 + + + + URL: + + + + + textLabel3_2 + + + + 309 + 8 + 250 + 20 + + + + Launcher: + + + + + textLabel1_4 + + + + 310 + 30 + 250 + 16 + + + + $d = Description + + + + + textLabel3_3 + + + + 310 + 50 + 130 + 16 + + + + $n = Username + + + + + textLabel2_3 + + + + 310 + 70 + 130 + 16 + + + + $c = Comment + + + + + textLabel5 + + + + 440 + 70 + 120 + 16 + + + + $u = URL + + + + + textLabel4_2 + + + + 440 + 50 + 120 + 16 + + + + $p = Password + + + + + revealButton + + + + 10 + 210 + 120 + 27 + + + + &Reveal + + + true + + + + + okButton + + + + 20 + 320 + 260 + 27 + + + + &OK + + + + + groupBox1 + + + + 300 + 140 + 260 + 150 + + + + Comment: + + + + commentDummy + + + + 10 + 20 + 240 + 80 + + + + + + + + + advancedCommentButton + + + + 10 + 110 + 240 + 30 + + + + advanced comment + + + true + + + + + + + generateButton + clicked() + addEntryWnd + generateButton_slot() + + + revealButton + toggled(bool) + addEntryWnd + revealButton_slot() + + + cancelButton + clicked() + addEntryWnd + cancelButton_slot() + + + okButton + clicked() + addEntryWnd + okButton_slot() + + + advancedCommentButton + toggled(bool) + addEntryWnd + advancedCommentButton_slot(bool) + + + + descLineEdit + categoryComboBox + usernameLineEdit + pwLineEdit + revealButton + generateButton + urlLineEdit + launcherLineEdit + okButton + cancelButton + + + okButton_slot() + cancelButton_slot() + revealButton_slot() + generateButton_slot() + advancedCommentButton_slot(bool on) + + + diff --git a/pwmanager/pwmanager/addentrywndimpl.cpp b/pwmanager/pwmanager/addentrywndimpl.cpp new file mode 100644 index 0000000..9e0fde9 --- a/dev/null +++ b/pwmanager/pwmanager/addentrywndimpl.cpp @@ -0,0 +1,174 @@ +/*************************************************************************** + * * + * copyright (C) 2003, 2004 by Michael Buesch * + * email: mbuesch@freenet.de * + * * + * Many very good improvements and the original implementations of * + * them came from Matt Scifo * + * * + * 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 "addentrywndimpl.h" +#include "pwmexception.h" +#include "pwgenwndimpl.h" +#ifndef PWM_EMBEDDED +#include "advcommeditimpl.h" +#endif +#include "htmlgen.h" + +#include +#include + +#include +#include + + +AddEntryWndImpl::AddEntryWndImpl() +{ + editAdvCommentButton = 0; + commentTextEdit = 0; + switchComment(false); + pwGen = new PwGenWndImpl(this); +} + +AddEntryWndImpl::~AddEntryWndImpl() +{ + delete_ifnot_null(editAdvCommentButton); + delete_ifnot_null(commentTextEdit); + delete pwGen; +} + +void AddEntryWndImpl::okButton_slot() +{ + if (pwLineEdit->text().isEmpty()) { + KMessageBox::error(this, + i18n("Sorry, you haven't set a password."), + i18n("no password")); + return; + } + if (descLineEdit->text().isEmpty()) { + KMessageBox::error(this, + i18n + ("You haven't set a \"Description\"."), + i18n("Description not set")); + return; + } + done(1); +} + +void AddEntryWndImpl::cancelButton_slot() +{ + done(2); +} + +void AddEntryWndImpl::setCurrCategory(const QString &cat) +{ + int i, count = categoryComboBox->count(); + + for (i = 0; i < count; ++i) { + if (categoryComboBox->text(i) == cat) { + categoryComboBox->setCurrentItem(i); + return; + } + } + BUG(); +} + +void AddEntryWndImpl::revealButton_slot() +{ + if (revealButton->isOn()) { + pwLineEdit->setEchoMode(QLineEdit::Normal); + } else { + pwLineEdit->setEchoMode(QLineEdit::Password); + } +} + +void AddEntryWndImpl::generateButton_slot() +{ + if (!pwGen->exec()) + return; + setPassword(pwGen->getPassword()); +} + +QString AddEntryWndImpl::getComment() +{ + if (isAdvancedComment()) { + return advCommentDta; + } + return commentTextEdit->text(); +} + +void AddEntryWndImpl::setComment(const QString &comm) +{ + if (HtmlGen::isHtml(comm)) { + advancedCommentButton->setOn(true); + advCommentDta = comm; + } else { + advancedCommentButton->setOn(false); + commentTextEdit->setText(comm); + } +} + +void AddEntryWndImpl::advancedCommentButton_slot(bool on) +{ + switchComment(on); +} + +void AddEntryWndImpl::switchComment(bool toAdvanced) +{ + useAdvComment = toAdvanced; + if (toAdvanced) { + if (commentTextEdit) { + savedCommentText = commentTextEdit->text(); + delete_and_null(commentTextEdit); + } + if (editAdvCommentButton) + return; + editAdvCommentButton = new QPushButton(i18n("Edit advanced comment..."), + commentDummy); + editAdvCommentButton->resize(commentDummy->size().width(), 50); + connect(editAdvCommentButton, SIGNAL(clicked()), + this, SLOT(editAdvCommentButton_slot())); + editAdvCommentButton->show(); + } else { + delete_ifnot_null(editAdvCommentButton); + if (commentTextEdit) + return; +#ifndef PWM_EMBEDDED + commentTextEdit = new QTextEdit(commentDummy); + commentTextEdit->setTextFormat(Qt::PlainText); +#else + commentTextEdit = new QMultiLineEdit(commentDummy); +#endif + commentTextEdit->resize(commentDummy->size()); + commentTextEdit->setText(savedCommentText); + commentTextEdit->show(); + } +} + +void AddEntryWndImpl::editAdvCommentButton_slot() +{ +#ifndef PWM_EMBEDDED + AdvCommEditImpl editor(this); + editor.setHtmlDta(advCommentDta); + if (editor.exec()) + return; + advCommentDta = editor.getHtmlDta(); +#endif +} + +#ifndef PWM_EMBEDDED +#include "addentrywndimpl.moc" +#endif diff --git a/pwmanager/pwmanager/addentrywndimpl.h b/pwmanager/pwmanager/addentrywndimpl.h new file mode 100644 index 0000000..c0bfcee --- a/dev/null +++ b/pwmanager/pwmanager/addentrywndimpl.h @@ -0,0 +1,114 @@ +/*************************************************************************** + * * + * 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 __ADDENTRYWNDIMPL_H +#define __ADDENTRYWNDIMPL_H + +#include "addentrywnd.h" + +#include +#ifndef PWM_EMBEDDED +#include +#else +#include +#endif + +#include +#include + +class PwGenWndImpl; + +/** "add/edit" Window */ +class AddEntryWndImpl : public addEntryWnd +{ + Q_OBJECT +public: + AddEntryWndImpl(); + ~AddEntryWndImpl(); + + /* get... functions */ + QString getDescription() + { return descLineEdit->text(); } + QString getCategory() + { return categoryComboBox->currentText(); } + QString getUsername() + { return usernameLineEdit->text(); } + QString getPassword() + { return pwLineEdit->text(); } + QString getUrl() + { return urlLineEdit->text(); } + QString getLauncher() + { return launcherLineEdit->text(); } + QString getComment(); + + /* set... functions */ + void setDescription(const QString &desc) + { descLineEdit->setText(desc); } + void setCurrCategory(const QString &cat); + void addCategory(const QString &cat) + { categoryComboBox->insertItem(cat); } + void setUsername(const QString &name) + { usernameLineEdit->setText(name); } + void setPassword(const QString &pw) + { pwLineEdit->setText(pw); } + void setUrl(const QString &url) + { urlLineEdit->setText(url); } + void setLauncher(const QString launcher) + { launcherLineEdit->setText(launcher); } + void setComment(const QString &comm); + + /** are we using an advanced comment */ + bool isAdvancedComment() + { return useAdvComment; } + +public slots: + /** OK button pressed */ + void okButton_slot(); + /** cancel button pressed */ + void cancelButton_slot(); + /** Reveal button pressed */ + void revealButton_slot(); + /** Generate button pressed */ + void generateButton_slot(); + /** advanced comment button pressed */ + void advancedCommentButton_slot(bool on); + /** edit advanced comment button pressed */ + void editAdvCommentButton_slot(); + +protected: + void switchComment(bool toAdvanced); + +protected: + QPushButton *editAdvCommentButton; +#ifndef PWM_EMBEDDED + QTextEdit *commentTextEdit; +#else + QMultiLineEdit * commentTextEdit; +#endif + /** saved data from normal comment text edit box */ + QString savedCommentText; + /** use an advanced comment? */ + bool useAdvComment; + /** data of advanced comment (if available) */ + QString advCommentDta; + /** password generation object */ + PwGenWndImpl *pwGen; +}; + +#endif diff --git a/pwmanager/pwmanager/advcommedit.cpp b/pwmanager/pwmanager/advcommedit.cpp new file mode 100644 index 0000000..93e4468 --- a/dev/null +++ b/pwmanager/pwmanager/advcommedit.cpp @@ -0,0 +1,10 @@ +/**************************************************************************** +** Form implementation generated from reading ui file 'advcommedit.ui' +** +** Created: Fri Sep 10 13:16:20 2004 +** by: The User Interface Compiler (uic) +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ +#include "advcommedit.h" + diff --git a/pwmanager/pwmanager/advcommedit.h b/pwmanager/pwmanager/advcommedit.h new file mode 100644 index 0000000..eb3bf6e --- a/dev/null +++ b/pwmanager/pwmanager/advcommedit.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** Form interface generated from reading ui file 'advcommedit.ui' +** +** Created: Mon Sep 13 14:27:05 2004 +** by: The User Interface Compiler ($Id$) +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ + +#ifndef ADVCOMMEDIT_H +#define ADVCOMMEDIT_H + +#include +#include + +class QVBoxLayout; +class QHBoxLayout; +class QGridLayout; +class QSpacerItem; +class QLabel; +class QGroupBox; +class QPushButton; +class QLineEdit; +class QListBox; +class QListBoxItem; + +class advCommEdit : public QDialog +{ + Q_OBJECT + +public: + advCommEdit( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~advCommEdit(); + + QLabel* textLabel2; + QGroupBox* groupBox1; + QLabel* previewDummy; + QPushButton* okButton; + QPushButton* cancelButton; + QPushButton* refreshPreviewButton; + QLineEdit* titleLineEdit; + QLabel* textLabel3; + QListBox* entryListBox; + QPushButton* editButton; + QPushButton* delButton; + QPushButton* addTblButton; + +public slots: + virtual void okButton_slot(); + virtual void cancelButton_slot(); + virtual void updatePreview(); + virtual void addSubtblButton_slot(); + virtual void editButton_slot(); + virtual void delButton_slot(); + +protected: + +protected slots: + virtual void languageChange(); + +}; + +#endif // ADVCOMMEDIT_H diff --git a/pwmanager/pwmanager/advcommedit.ui b/pwmanager/pwmanager/advcommedit.ui new file mode 100644 index 0000000..4e8d7e9 --- a/dev/null +++ b/pwmanager/pwmanager/advcommedit.ui @@ -0,0 +1,274 @@ + +advCommEdit + + + advCommEdit + + + + 0 + 0 + 685 + 326 + + + + Advanced HTML-comment editor + + + + textLabel2 + + + + 20 + 10 + 310 + 20 + + + + Global title: + + + AlignCenter + + + + + groupBox1 + + + + 360 + 10 + 310 + 250 + + + + preview + + + + previewDummy + + + + 10 + 20 + 290 + 220 + + + + + + + + + + okButton + + + + 20 + 280 + 180 + 31 + + + + &OK + + + + + cancelButton + + + + 490 + 280 + 180 + 31 + + + + &Cancel + + + + + refreshPreviewButton + + + + 240 + 280 + 210 + 31 + + + + Refresh preview + + + + + titleLineEdit + + + + 20 + 30 + 310 + 26 + + + + + + textLabel3 + + + + 20 + 70 + 310 + 20 + + + + NoFrame + + + Plain + + + Current entries: + + + AlignCenter + + + + + entryListBox + + + + 20 + 90 + 180 + 130 + + + + + + editButton + + + + 210 + 140 + 121 + 31 + + + + edit + + + + + delButton + + + + 210 + 180 + 121 + 31 + + + + delete + + + + + addTblButton + + + + 210 + 100 + 120 + 31 + + + + Add + + + + + + okButton + clicked() + advCommEdit + okButton_slot() + + + cancelButton + clicked() + advCommEdit + cancelButton_slot() + + + refreshPreviewButton + clicked() + advCommEdit + updatePreview() + + + addTblButton + clicked() + advCommEdit + addSubtblButton_slot() + + + editButton + clicked() + advCommEdit + editButton_slot() + + + delButton + clicked() + advCommEdit + delButton_slot() + + + + titleLineEdit + entryListBox + addTblButton + editButton + delButton + okButton + refreshPreviewButton + cancelButton + + + okButton_slot() + cancelButton_slot() + updatePreview() + addSubtblButton_slot() + editButton_slot() + delButton_slot() + + + diff --git a/pwmanager/pwmanager/advcommeditimpl.cpp b/pwmanager/pwmanager/advcommeditimpl.cpp new file mode 100644 index 0000000..59e5e5b --- a/dev/null +++ b/pwmanager/pwmanager/advcommeditimpl.cpp @@ -0,0 +1,149 @@ +/*************************************************************************** + * * + * 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 "advcommeditimpl.h" +#include "htmlgen.h" +#include "htmlparse.h" +#include "pwmexception.h" +#include "subtbleditimpl.h" + +#include +#include + +#include +#include + + +AdvCommEditImpl::AdvCommEditImpl(QWidget* parent, + const char* name, + WFlags fl) + : advCommEdit(parent, name, fl) +{ + dta = new HtmlComment; + preview = new KHTMLPart(previewDummy); + preview->view()->resize(previewDummy->size()); + preview->show(); +} + +AdvCommEditImpl::~AdvCommEditImpl() +{ + delete dta; + delete preview; +} + +void AdvCommEditImpl::okButton_slot() +{ + updateTitle(); + done(0); +} + +void AdvCommEditImpl::cancelButton_slot() +{ + done(1); +} + +void AdvCommEditImpl::addSubtblButton_slot() +{ + SubTblEditImpl editor(this); + if (editor.exec()) + return; + QString subTitle(editor.getTitle()); + HtmlComment::SubTable subTbl; + subTbl.setTitle(subTitle); + subTbl.setEntries(editor.getEntries()); + dta->addSubtable(subTbl); + entryListBox->insertItem(subTitle); + updatePreview(); +} + +void AdvCommEditImpl::editButton_slot() +{ + int index = curIndex(); + if (index == -1) + return; + SubTblEditImpl editor(this); + HtmlComment::SubTable subTbl = dta->subtableAt(index); + editor.setContent(subTbl.getTitle(), subTbl.getEntryList()); + if (editor.exec()) + return; + QString subTitle(editor.getTitle()); + subTbl.setTitle(subTitle); + subTbl.setEntries(editor.getEntries()); + dta->setSubtblAt(index, subTbl); + entryListBox->changeItem(subTitle, index); + updatePreview(); +} + +void AdvCommEditImpl::delButton_slot() +{ + int index = curIndex(); + if (index == -1) + return; + dta->eraseSubtable(index); + entryListBox->removeItem(index); + updatePreview(); +} + +void AdvCommEditImpl::updatePreview() +{ + updateTitle(); + HtmlGen htmlGen; + htmlGen.styleSheetDummy(false); + QString code(htmlGen.genHtmlComment(dta)); + if (code.isEmpty()) + return; + preview->begin(); + preview->write(code); + preview->end(); +} + +void AdvCommEditImpl::updateTitle() +{ + dta->setTitle(titleLineEdit->text()); +} + +QString AdvCommEditImpl::getHtmlDta() +{ + HtmlGen htmlGen; + return htmlGen.genHtmlComment(dta); +} + +void AdvCommEditImpl::setHtmlDta(const QString &str) +{ + if (str.isEmpty()) + return; + PWM_ASSERT(HtmlGen::isHtml(str)); + HtmlParse htmlParse; + if (!htmlParse.parseHtmlComment(str, dta)) { + printWarn("AdvCommEditImpl::setHtmlDta(): parseHtmlComment() failed!"); + return; + } + titleLineEdit->setText(dta->getTitle()); + const vector *subTbls = dta->getSubTableList(); + vector::const_iterator i = subTbls->begin(), + end = subTbls->end(); + while (i != end) { + entryListBox->insertItem(i->getTitle()); + ++i; + } + updatePreview(); +} + +#include "advcommeditimpl.moc" diff --git a/pwmanager/pwmanager/advcommeditimpl.h b/pwmanager/pwmanager/advcommeditimpl.h new file mode 100644 index 0000000..67f3ac6 --- a/dev/null +++ b/pwmanager/pwmanager/advcommeditimpl.h @@ -0,0 +1,79 @@ +/*************************************************************************** + * * + * 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 ADVCOMMEDITIMPL_H +#define ADVCOMMEDITIMPL_H + +#include + +#include "advcommedit.h" + +class HtmlComment; +class KHTMLPart; + +class AdvCommEditImpl : public advCommEdit +{ + Q_OBJECT +public: + AdvCommEditImpl(QWidget* parent = 0, + const char* name = 0, + WFlags fl = 0); + ~AdvCommEditImpl(); + + /** returns the HTML data for the comment */ + QString getHtmlDta(); + /** sets the HTML data, parses and displays it */ + void setHtmlDta(const QString &str); + +public slots: + /** sync preview with dta */ + void updatePreview(); + /** ok button pressed */ + void okButton_slot(); + /** cancel button pressed */ + void cancelButton_slot(); + /** add subtbl button pressed */ + void addSubtblButton_slot(); + /** edit button pressed */ + void editButton_slot(); + /** delete button pressed */ + void delButton_slot(); + +protected slots: + +protected: + /** read the title from the line-edit and update dta */ + void updateTitle(); + /** returns the index of the currently selected entry */ + int curIndex() +#ifndef PWM_EMBEDDED + { return entryListBox->index(entryListBox->selectedItem()); } +#else + { return entryListBox->currentItem(); } +#endif +protected: + /** current internal representation structure + * of the comment + */ + HtmlComment *dta; + /** preview browser */ + KHTMLPart *preview; +}; + +#endif diff --git a/pwmanager/pwmanager/base64.cpp b/pwmanager/pwmanager/base64.cpp new file mode 100644 index 0000000..0360678 --- a/dev/null +++ b/pwmanager/pwmanager/base64.cpp @@ -0,0 +1,207 @@ +/******************************************************************* + * base64.h + * © Copyright 1995 John Halleck + * All Rights Reserved + * + * ported to c++ by Michael Buesch + * + * --ABSTRACT-- base64.h + * Do the base 64 encoding as used by PEM and MIME. + * + * --KEYWORDS-- base64.h + * + * --CONTENTS-- base64.h + * Date, Department, Author + * 23nov1994, John Halleck + * Revision history + * For each revision: Date, change summary, authorizing document, + * change department, section, author + * 23nov1994, Initial Creation, John Halleck + * 8apr1995, split library into hex and base64 libraries, John Halleck + * Unit purpose + * (What does this do?) + * [Nothing] + * External Units accessed + * Name, purpose, access summary + * [None] + * Exceptions propagated by this unit + * [None] + * Machine-dependencies + * Access type, purpose, and justification + * [None] + * Compiler-dependencies + * [None] + *********************************************************************/ + +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include "base64.h" +#include "globalstuff.h" + + +static const char prtcode[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + +string Base64::encode(const string &data) +{ + initCtx(); + string::const_iterator i = data.begin(), + end = data.end(); + while (i != end) { + encodeChar(*i); + ++i; + } + encFinalizeCtx(); + return ctx.buf; +} + +string Base64::decode(const string &data) +{ + initCtx(); + string::const_iterator i = data.begin(), + end = data.end(); + while (i != end) { + decodeChar(*i); + ++i; + } + decFinalizeCtx(); + return ctx.buf; +} + +void Base64::initCtx() +{ + ctx.temp = 0; + ctx.bytes = 0; + ctx.buf = ""; +} + +void Base64::encFinalizeCtx() +{ + /* flush the output side of things, by putting out the last characters */ + switch (ctx.bytes) { + case 0: + /* nothing in progress */ + break; + case 2: + ctx.buf.append(1, static_cast(prtcode[ctx.temp << 2 & 0x3F])); + ctx.buf.append(1, '='); + break; + case 1: + ctx.buf.append(1, static_cast(prtcode[ctx.temp << 4 & 0x3F])); + ctx.buf.append(1, '='); + ctx.buf.append(1, '='); + } +} + +void Base64::decFinalizeCtx() +{ + if (ctx.bytes == 1) + decodeChar('A'); +} + +void Base64::encodeChar(unsigned char c) +{ + int result; + + /* Add this 8 bit byte to what we have...*/ + result = ctx.temp; + result = (result << 8) | (c & 0xFF); + + /* And output all 6 bit base 64 characters now formed */ + switch (ctx.bytes++) { + case 0: + ctx.buf.append(1, static_cast(prtcode[result >> 2 & 0x3F])); + result &= 0x3; + break; + case 1: + ctx.buf.append(1, static_cast(prtcode[result >> 4 & 0x3F])); + result &= 0xF; + break; + case 2: + ctx.buf.append(1, static_cast(prtcode[result >> 6 & 0x3F])); + ctx.buf.append(1, static_cast(prtcode[result & 0x3F])); + result = 0; + ctx.bytes = 0; + } + ctx.temp = result; +} + +void Base64::decodeChar(char c) +{ + int result; + + result = ctx.temp; + + /* Convert Base64 character to its 6 bit nibble */ + if (c == '/') { + result = (result << 6) | 63; + } else if (c == '+') { + result = (result << 6) | 62; + } else if (c >= 'A' && c <= 'Z') { + result = (result << 6) | (c - 'A'); + } else if (c >= 'a' && c <= 'z') { + result = (result << 6) | (c - 'a' + 26); + } else if (c >= '0' && c <= '9') { + result = (result << 6) | (c - '0' + 52); + } else if (c == '=') { + ctx.bytes = 0; + ctx.temp = 0; + } + + /* Add that nibble to the output, outputting any complete 8 bit bytes formed */ + switch (ctx.bytes++) { + case 0: + break; + case 1: + ctx.buf.append(1, static_cast(result >> 4 & 0xFF)); + result &= 0xF; + break; + case 2: + ctx.buf.append(1, static_cast(result >> 2 & 0xFF)); + result &= 0x3; + break; + case 3: + ctx.buf.append(1, static_cast(result & 0xFF)); + ctx.bytes = 0; + result = 0; + } + if (c == '=') { + ctx.bytes = 0; + result = 0; + } + + ctx.temp = result; +} + +bool Base64::selfTest() +{ + string plain1("Base64"); + string plain2("abcdefghijklmnopqrstuvwxyz"); + string enc1("QmFzZTY0"); + string enc2("YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXo="); + string buf; + + Base64 base64; + + buf = base64.encode(plain1); + if (unlikely(buf != enc1)) + return false; + buf = base64.decode(buf); + if (unlikely(buf != plain1)) + return false; + + buf = base64.encode(plain2); + if (unlikely(buf != enc2)) + return false; + buf = base64.decode(buf); + if (unlikely(buf != plain2)) + return false; + return true; +} diff --git a/pwmanager/pwmanager/base64.h b/pwmanager/pwmanager/base64.h new file mode 100644 index 0000000..f497b9e --- a/dev/null +++ b/pwmanager/pwmanager/base64.h @@ -0,0 +1,97 @@ +/******************************************************************* + * base64.h + * © Copyright 1995 John Halleck + * All Rights Reserved + * + * ported to c++ by Michael Buesch + * + * --ABSTRACT-- base64.h + * Do the base 64 encoding as used by PEM and MIME. + * + * --KEYWORDS-- base64.h + * + * --CONTENTS-- base64.h + * Date, Department, Author + * 23nov1994, John Halleck + * Revision history + * For each revision: Date, change summary, authorizing document, + * change department, section, author + * 23nov1994, Initial Creation, John Halleck + * 8apr1995, split library into hex and base64 libraries, John Halleck + * Unit purpose + * (What does this do?) + * [Nothing] + * External Units accessed + * Name, purpose, access summary + * [None] + * Exceptions propagated by this unit + * [None] + * Machine-dependencies + * Access type, purpose, and justification + * [None] + * Compiler-dependencies + * [None] + *********************************************************************/ + +/*************************************************************************** + * * + * 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 __BASE64_H +#define __BASE64_H + +#include + +using std::string; + +class Base64 +{ +protected: + struct Base64Ctx + { + int temp; // Working value for input + int bytes; // which input byte we are working on + string buf; // Data buffer + }; + +public: + Base64() {} + /** run algorithm self test */ + static bool selfTest(); + + /** encode "data" */ + string encode(const string &data); + /** decode "data" */ + string decode(const string &data); + +protected: + /** initialize the context */ + void initCtx(); + /** finalize the context */ + void encFinalizeCtx(); + /** finalize the context */ + void decFinalizeCtx(); + /** encode a character */ + void encodeChar(unsigned char c); + /** decode a character */ + void decodeChar(char c); + +protected: + /** Base64 context */ + Base64Ctx ctx; +}; + +#endif // __BASE64_H diff --git a/pwmanager/pwmanager/binentrygen.cpp b/pwmanager/pwmanager/binentrygen.cpp new file mode 100644 index 0000000..7d5ae45 --- a/dev/null +++ b/pwmanager/pwmanager/binentrygen.cpp @@ -0,0 +1,71 @@ +/*************************************************************************** + * * + * 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 "binentrygen.h" +#include "base64.h" +#include "pwmexception.h" + + +void BinEntryGen::encode(const QByteArray &data, + PwMDataItem *ret, + DataType type) +{ + ret->clear(); + ret->name = tostr(static_cast(type)); + ret->binary = true; + if (data.size() == 0) + return; + Base64 b64; + string d(data.data(), data.size()); + ret->pw = b64.encode(d); +} + +void BinEntryGen::decode(const PwMDataItem &data, + QByteArray *ret, + DataType *type) +{ + BUG_ON(!data.binary); + int t = strtol(data.name.c_str(), 0, 10); + *type = static_cast(t); + switch (*type) { + case None: + case KWalletMap: + case KWalletStream: + break; + default: + *type = None; + } + if (data.pw == "") { + ret->fill(0); + ret->resize(0); + return; + } + Base64 b64; + string d(b64.decode(data.pw)); + ret->duplicate(d.c_str(), d.length()); +} + +BinEntryGen::DataType BinEntryGen::binType(const PwMDataItem &data) +{ + if (!data.binary) + return None; + int type = strtol(data.name.c_str(), 0, 10); + return (static_cast(type)); +} diff --git a/pwmanager/pwmanager/binentrygen.h b/pwmanager/pwmanager/binentrygen.h new file mode 100644 index 0000000..a58cd42 --- a/dev/null +++ b/pwmanager/pwmanager/binentrygen.h @@ -0,0 +1,65 @@ +/*************************************************************************** + * * + * 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 __BINENTRYGEN_H +#define __BINENTRYGEN_H + +#include "pwmdoc.h" + +#include + + +/** Binary entry generator. + * This generator generates a normal struct PwMDataItem + * from binary data (using base64 encoding). + * This mechanism is used to support the binary interface functions + * of the KWallet emulation, for example. + * + * The format of the encoded binary data as a PwMDataItem is as follows: + * + * PwMDataItem::desc contains the normal description string for + * this entry. Nothing surprising. + * PwMDataItem::name contains the "DataType" number in ascii format. + * PwMDataItem::pw contains the base64 encoded data stream. + * PwMDataItem::binary is always true for binary entries. + * All other PwMDataItems are currently unused by BinEntryGen. + */ +class BinEntryGen +{ +public: + enum DataType + { + None = 0, + KWalletMap, + KWalletStream + }; + +public: + BinEntryGen() { } + + /** Encode the binary "data" and return it in "ret" */ + void encode(const QByteArray &data, PwMDataItem *ret, DataType type); + /** Decode the "data" and return it as binary "ret" */ + void decode(const PwMDataItem &data, QByteArray *ret, DataType *type); + + /** Return the data type for this binary data item */ + DataType binType(const PwMDataItem &data); +}; + +#endif // __BINENTRYGEN_H diff --git a/pwmanager/pwmanager/blowfish.cpp b/pwmanager/pwmanager/blowfish.cpp new file mode 100644 index 0000000..2ca58ce --- a/dev/null +++ b/pwmanager/pwmanager/blowfish.cpp @@ -0,0 +1,579 @@ +/* 2003.05.02: Derived from libgcrypt-1.1.12 by Michael Buesch */ + +/* blowfish.c - Blowfish encryption + * Copyright (C) 1998, 2001, 2002 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser general Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + * + * For a description of the algorithm, see: + * Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996. + * ISBN 0-471-11709-9. Pages 336 ff. + */ + +/* Test values: + * key "abcdefghijklmnopqrstuvwxyz"; + * plain "BLOWFISH" + * cipher 32 4E D0 FE F4 13 A2 03 + * + */ + +/*************************************************************************** + * 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 +#include + +#include "blowfish.h" +#include "globalstuff.h" + + +/* precomputed S boxes */ +static const uint32_t ks0[256] = { + 0xD1310BA6, 0x98DFB5AC, 0x2FFD72DB, 0xD01ADFB7, 0xB8E1AFED, 0x6A267E96, + 0xBA7C9045, 0xF12C7F99, 0x24A19947, 0xB3916CF7, 0x0801F2E2, 0x858EFC16, + 0x636920D8, 0x71574E69, 0xA458FEA3, 0xF4933D7E, 0x0D95748F, 0x728EB658, + 0x718BCD58, 0x82154AEE, 0x7B54A41D, 0xC25A59B5, 0x9C30D539, 0x2AF26013, + 0xC5D1B023, 0x286085F0, 0xCA417918, 0xB8DB38EF, 0x8E79DCB0, 0x603A180E, + 0x6C9E0E8B, 0xB01E8A3E, 0xD71577C1, 0xBD314B27, 0x78AF2FDA, 0x55605C60, + 0xE65525F3, 0xAA55AB94, 0x57489862, 0x63E81440, 0x55CA396A, 0x2AAB10B6, + 0xB4CC5C34, 0x1141E8CE, 0xA15486AF, 0x7C72E993, 0xB3EE1411, 0x636FBC2A, + 0x2BA9C55D, 0x741831F6, 0xCE5C3E16, 0x9B87931E, 0xAFD6BA33, 0x6C24CF5C, + 0x7A325381, 0x28958677, 0x3B8F4898, 0x6B4BB9AF, 0xC4BFE81B, 0x66282193, + 0x61D809CC, 0xFB21A991, 0x487CAC60, 0x5DEC8032, 0xEF845D5D, 0xE98575B1, + 0xDC262302, 0xEB651B88, 0x23893E81, 0xD396ACC5, 0x0F6D6FF3, 0x83F44239, + 0x2E0B4482, 0xA4842004, 0x69C8F04A, 0x9E1F9B5E, 0x21C66842, 0xF6E96C9A, + 0x670C9C61, 0xABD388F0, 0x6A51A0D2, 0xD8542F68, 0x960FA728, 0xAB5133A3, + 0x6EEF0B6C, 0x137A3BE4, 0xBA3BF050, 0x7EFB2A98, 0xA1F1651D, 0x39AF0176, + 0x66CA593E, 0x82430E88, 0x8CEE8619, 0x456F9FB4, 0x7D84A5C3, 0x3B8B5EBE, + 0xE06F75D8, 0x85C12073, 0x401A449F, 0x56C16AA6, 0x4ED3AA62, 0x363F7706, + 0x1BFEDF72, 0x429B023D, 0x37D0D724, 0xD00A1248, 0xDB0FEAD3, 0x49F1C09B, + 0x075372C9, 0x80991B7B, 0x25D479D8, 0xF6E8DEF7, 0xE3FE501A, 0xB6794C3B, + 0x976CE0BD, 0x04C006BA, 0xC1A94FB6, 0x409F60C4, 0x5E5C9EC2, 0x196A2463, + 0x68FB6FAF, 0x3E6C53B5, 0x1339B2EB, 0x3B52EC6F, 0x6DFC511F, 0x9B30952C, + 0xCC814544, 0xAF5EBD09, 0xBEE3D004, 0xDE334AFD, 0x660F2807, 0x192E4BB3, + 0xC0CBA857, 0x45C8740F, 0xD20B5F39, 0xB9D3FBDB, 0x5579C0BD, 0x1A60320A, + 0xD6A100C6, 0x402C7279, 0x679F25FE, 0xFB1FA3CC, 0x8EA5E9F8, 0xDB3222F8, + 0x3C7516DF, 0xFD616B15, 0x2F501EC8, 0xAD0552AB, 0x323DB5FA, 0xFD238760, + 0x53317B48, 0x3E00DF82, 0x9E5C57BB, 0xCA6F8CA0, 0x1A87562E, 0xDF1769DB, + 0xD542A8F6, 0x287EFFC3, 0xAC6732C6, 0x8C4F5573, 0x695B27B0, 0xBBCA58C8, + 0xE1FFA35D, 0xB8F011A0, 0x10FA3D98, 0xFD2183B8, 0x4AFCB56C, 0x2DD1D35B, + 0x9A53E479, 0xB6F84565, 0xD28E49BC, 0x4BFB9790, 0xE1DDF2DA, 0xA4CB7E33, + 0x62FB1341, 0xCEE4C6E8, 0xEF20CADA, 0x36774C01, 0xD07E9EFE, 0x2BF11FB4, + 0x95DBDA4D, 0xAE909198, 0xEAAD8E71, 0x6B93D5A0, 0xD08ED1D0, 0xAFC725E0, + 0x8E3C5B2F, 0x8E7594B7, 0x8FF6E2FB, 0xF2122B64, 0x8888B812, 0x900DF01C, + 0x4FAD5EA0, 0x688FC31C, 0xD1CFF191, 0xB3A8C1AD, 0x2F2F2218, 0xBE0E1777, + 0xEA752DFE, 0x8B021FA1, 0xE5A0CC0F, 0xB56F74E8, 0x18ACF3D6, 0xCE89E299, + 0xB4A84FE0, 0xFD13E0B7, 0x7CC43B81, 0xD2ADA8D9, 0x165FA266, 0x80957705, + 0x93CC7314, 0x211A1477, 0xE6AD2065, 0x77B5FA86, 0xC75442F5, 0xFB9D35CF, + 0xEBCDAF0C, 0x7B3E89A0, 0xD6411BD3, 0xAE1E7E49, 0x00250E2D, 0x2071B35E, + 0x226800BB, 0x57B8E0AF, 0x2464369B, 0xF009B91E, 0x5563911D, 0x59DFA6AA, + 0x78C14389, 0xD95A537F, 0x207D5BA2, 0x02E5B9C5, 0x83260376, 0x6295CFA9, + 0x11C81968, 0x4E734A41, 0xB3472DCA, 0x7B14A94A, 0x1B510052, 0x9A532915, + 0xD60F573F, 0xBC9BC6E4, 0x2B60A476, 0x81E67400, 0x08BA6FB5, 0x571BE91F, + 0xF296EC6B, 0x2A0DD915, 0xB6636521, 0xE7B9F9B6, 0xFF34052E, 0xC5855664, + 0x53B02D5D, 0xA99F8FA1, 0x08BA4799, 0x6E85076A +}; + +static const uint32_t ks1[256] = { + 0x4B7A70E9, 0xB5B32944, 0xDB75092E, 0xC4192623, 0xAD6EA6B0, 0x49A7DF7D, + 0x9CEE60B8, 0x8FEDB266, 0xECAA8C71, 0x699A17FF, 0x5664526C, 0xC2B19EE1, + 0x193602A5, 0x75094C29, 0xA0591340, 0xE4183A3E, 0x3F54989A, 0x5B429D65, + 0x6B8FE4D6, 0x99F73FD6, 0xA1D29C07, 0xEFE830F5, 0x4D2D38E6, 0xF0255DC1, + 0x4CDD2086, 0x8470EB26, 0x6382E9C6, 0x021ECC5E, 0x09686B3F, 0x3EBAEFC9, + 0x3C971814, 0x6B6A70A1, 0x687F3584, 0x52A0E286, 0xB79C5305, 0xAA500737, + 0x3E07841C, 0x7FDEAE5C, 0x8E7D44EC, 0x5716F2B8, 0xB03ADA37, 0xF0500C0D, + 0xF01C1F04, 0x0200B3FF, 0xAE0CF51A, 0x3CB574B2, 0x25837A58, 0xDC0921BD, + 0xD19113F9, 0x7CA92FF6, 0x94324773, 0x22F54701, 0x3AE5E581, 0x37C2DADC, + 0xC8B57634, 0x9AF3DDA7, 0xA9446146, 0x0FD0030E, 0xECC8C73E, 0xA4751E41, + 0xE238CD99, 0x3BEA0E2F, 0x3280BBA1, 0x183EB331, 0x4E548B38, 0x4F6DB908, + 0x6F420D03, 0xF60A04BF, 0x2CB81290, 0x24977C79, 0x5679B072, 0xBCAF89AF, + 0xDE9A771F, 0xD9930810, 0xB38BAE12, 0xDCCF3F2E, 0x5512721F, 0x2E6B7124, + 0x501ADDE6, 0x9F84CD87, 0x7A584718, 0x7408DA17, 0xBC9F9ABC, 0xE94B7D8C, + 0xEC7AEC3A, 0xDB851DFA, 0x63094366, 0xC464C3D2, 0xEF1C1847, 0x3215D908, + 0xDD433B37, 0x24C2BA16, 0x12A14D43, 0x2A65C451, 0x50940002, 0x133AE4DD, + 0x71DFF89E, 0x10314E55, 0x81AC77D6, 0x5F11199B, 0x043556F1, 0xD7A3C76B, + 0x3C11183B, 0x5924A509, 0xF28FE6ED, 0x97F1FBFA, 0x9EBABF2C, 0x1E153C6E, + 0x86E34570, 0xEAE96FB1, 0x860E5E0A, 0x5A3E2AB3, 0x771FE71C, 0x4E3D06FA, + 0x2965DCB9, 0x99E71D0F, 0x803E89D6, 0x5266C825, 0x2E4CC978, 0x9C10B36A, + 0xC6150EBA, 0x94E2EA78, 0xA5FC3C53, 0x1E0A2DF4, 0xF2F74EA7, 0x361D2B3D, + 0x1939260F, 0x19C27960, 0x5223A708, 0xF71312B6, 0xEBADFE6E, 0xEAC31F66, + 0xE3BC4595, 0xA67BC883, 0xB17F37D1, 0x018CFF28, 0xC332DDEF, 0xBE6C5AA5, + 0x65582185, 0x68AB9802, 0xEECEA50F, 0xDB2F953B, 0x2AEF7DAD, 0x5B6E2F84, + 0x1521B628, 0x29076170, 0xECDD4775, 0x619F1510, 0x13CCA830, 0xEB61BD96, + 0x0334FE1E, 0xAA0363CF, 0xB5735C90, 0x4C70A239, 0xD59E9E0B, 0xCBAADE14, + 0xEECC86BC, 0x60622CA7, 0x9CAB5CAB, 0xB2F3846E, 0x648B1EAF, 0x19BDF0CA, + 0xA02369B9, 0x655ABB50, 0x40685A32, 0x3C2AB4B3, 0x319EE9D5, 0xC021B8F7, + 0x9B540B19, 0x875FA099, 0x95F7997E, 0x623D7DA8, 0xF837889A, 0x97E32D77, + 0x11ED935F, 0x16681281, 0x0E358829, 0xC7E61FD6, 0x96DEDFA1, 0x7858BA99, + 0x57F584A5, 0x1B227263, 0x9B83C3FF, 0x1AC24696, 0xCDB30AEB, 0x532E3054, + 0x8FD948E4, 0x6DBC3128, 0x58EBF2EF, 0x34C6FFEA, 0xFE28ED61, 0xEE7C3C73, + 0x5D4A14D9, 0xE864B7E3, 0x42105D14, 0x203E13E0, 0x45EEE2B6, 0xA3AAABEA, + 0xDB6C4F15, 0xFACB4FD0, 0xC742F442, 0xEF6ABBB5, 0x654F3B1D, 0x41CD2105, + 0xD81E799E, 0x86854DC7, 0xE44B476A, 0x3D816250, 0xCF62A1F2, 0x5B8D2646, + 0xFC8883A0, 0xC1C7B6A3, 0x7F1524C3, 0x69CB7492, 0x47848A0B, 0x5692B285, + 0x095BBF00, 0xAD19489D, 0x1462B174, 0x23820E00, 0x58428D2A, 0x0C55F5EA, + 0x1DADF43E, 0x233F7061, 0x3372F092, 0x8D937E41, 0xD65FECF1, 0x6C223BDB, + 0x7CDE3759, 0xCBEE7460, 0x4085F2A7, 0xCE77326E, 0xA6078084, 0x19F8509E, + 0xE8EFD855, 0x61D99735, 0xA969A7AA, 0xC50C06C2, 0x5A04ABFC, 0x800BCADC, + 0x9E447A2E, 0xC3453484, 0xFDD56705, 0x0E1E9EC9, 0xDB73DBD3, 0x105588CD, + 0x675FDA79, 0xE3674340, 0xC5C43465, 0x713E38D8, 0x3D28F89E, 0xF16DFF20, + 0x153E21E7, 0x8FB03D4A, 0xE6E39F2B, 0xDB83ADF7 +}; + +static const uint32_t ks2[256] = { + 0xE93D5A68, 0x948140F7, 0xF64C261C, 0x94692934, 0x411520F7, 0x7602D4F7, + 0xBCF46B2E, 0xD4A20068, 0xD4082471, 0x3320F46A, 0x43B7D4B7, 0x500061AF, + 0x1E39F62E, 0x97244546, 0x14214F74, 0xBF8B8840, 0x4D95FC1D, 0x96B591AF, + 0x70F4DDD3, 0x66A02F45, 0xBFBC09EC, 0x03BD9785, 0x7FAC6DD0, 0x31CB8504, + 0x96EB27B3, 0x55FD3941, 0xDA2547E6, 0xABCA0A9A, 0x28507825, 0x530429F4, + 0x0A2C86DA, 0xE9B66DFB, 0x68DC1462, 0xD7486900, 0x680EC0A4, 0x27A18DEE, + 0x4F3FFEA2, 0xE887AD8C, 0xB58CE006, 0x7AF4D6B6, 0xAACE1E7C, 0xD3375FEC, + 0xCE78A399, 0x406B2A42, 0x20FE9E35, 0xD9F385B9, 0xEE39D7AB, 0x3B124E8B, + 0x1DC9FAF7, 0x4B6D1856, 0x26A36631, 0xEAE397B2, 0x3A6EFA74, 0xDD5B4332, + 0x6841E7F7, 0xCA7820FB, 0xFB0AF54E, 0xD8FEB397, 0x454056AC, 0xBA489527, + 0x55533A3A, 0x20838D87, 0xFE6BA9B7, 0xD096954B, 0x55A867BC, 0xA1159A58, + 0xCCA92963, 0x99E1DB33, 0xA62A4A56, 0x3F3125F9, 0x5EF47E1C, 0x9029317C, + 0xFDF8E802, 0x04272F70, 0x80BB155C, 0x05282CE3, 0x95C11548, 0xE4C66D22, + 0x48C1133F, 0xC70F86DC, 0x07F9C9EE, 0x41041F0F, 0x404779A4, 0x5D886E17, + 0x325F51EB, 0xD59BC0D1, 0xF2BCC18F, 0x41113564, 0x257B7834, 0x602A9C60, + 0xDFF8E8A3, 0x1F636C1B, 0x0E12B4C2, 0x02E1329E, 0xAF664FD1, 0xCAD18115, + 0x6B2395E0, 0x333E92E1, 0x3B240B62, 0xEEBEB922, 0x85B2A20E, 0xE6BA0D99, + 0xDE720C8C, 0x2DA2F728, 0xD0127845, 0x95B794FD, 0x647D0862, 0xE7CCF5F0, + 0x5449A36F, 0x877D48FA, 0xC39DFD27, 0xF33E8D1E, 0x0A476341, 0x992EFF74, + 0x3A6F6EAB, 0xF4F8FD37, 0xA812DC60, 0xA1EBDDF8, 0x991BE14C, 0xDB6E6B0D, + 0xC67B5510, 0x6D672C37, 0x2765D43B, 0xDCD0E804, 0xF1290DC7, 0xCC00FFA3, + 0xB5390F92, 0x690FED0B, 0x667B9FFB, 0xCEDB7D9C, 0xA091CF0B, 0xD9155EA3, + 0xBB132F88, 0x515BAD24, 0x7B9479BF, 0x763BD6EB, 0x37392EB3, 0xCC115979, + 0x8026E297, 0xF42E312D, 0x6842ADA7, 0xC66A2B3B, 0x12754CCC, 0x782EF11C, + 0x6A124237, 0xB79251E7, 0x06A1BBE6, 0x4BFB6350, 0x1A6B1018, 0x11CAEDFA, + 0x3D25BDD8, 0xE2E1C3C9, 0x44421659, 0x0A121386, 0xD90CEC6E, 0xD5ABEA2A, + 0x64AF674E, 0xDA86A85F, 0xBEBFE988, 0x64E4C3FE, 0x9DBC8057, 0xF0F7C086, + 0x60787BF8, 0x6003604D, 0xD1FD8346, 0xF6381FB0, 0x7745AE04, 0xD736FCCC, + 0x83426B33, 0xF01EAB71, 0xB0804187, 0x3C005E5F, 0x77A057BE, 0xBDE8AE24, + 0x55464299, 0xBF582E61, 0x4E58F48F, 0xF2DDFDA2, 0xF474EF38, 0x8789BDC2, + 0x5366F9C3, 0xC8B38E74, 0xB475F255, 0x46FCD9B9, 0x7AEB2661, 0x8B1DDF84, + 0x846A0E79, 0x915F95E2, 0x466E598E, 0x20B45770, 0x8CD55591, 0xC902DE4C, + 0xB90BACE1, 0xBB8205D0, 0x11A86248, 0x7574A99E, 0xB77F19B6, 0xE0A9DC09, + 0x662D09A1, 0xC4324633, 0xE85A1F02, 0x09F0BE8C, 0x4A99A025, 0x1D6EFE10, + 0x1AB93D1D, 0x0BA5A4DF, 0xA186F20F, 0x2868F169, 0xDCB7DA83, 0x573906FE, + 0xA1E2CE9B, 0x4FCD7F52, 0x50115E01, 0xA70683FA, 0xA002B5C4, 0x0DE6D027, + 0x9AF88C27, 0x773F8641, 0xC3604C06, 0x61A806B5, 0xF0177A28, 0xC0F586E0, + 0x006058AA, 0x30DC7D62, 0x11E69ED7, 0x2338EA63, 0x53C2DD94, 0xC2C21634, + 0xBBCBEE56, 0x90BCB6DE, 0xEBFC7DA1, 0xCE591D76, 0x6F05E409, 0x4B7C0188, + 0x39720A3D, 0x7C927C24, 0x86E3725F, 0x724D9DB9, 0x1AC15BB4, 0xD39EB8FC, + 0xED545578, 0x08FCA5B5, 0xD83D7CD3, 0x4DAD0FC4, 0x1E50EF5E, 0xB161E6F8, + 0xA28514D9, 0x6C51133C, 0x6FD5C7E7, 0x56E14EC4, 0x362ABFCE, 0xDDC6C837, + 0xD79A3234, 0x92638212, 0x670EFA8E, 0x406000E0 +}; + +static const uint32_t ks3[256] = { + 0x3A39CE37, 0xD3FAF5CF, 0xABC27737, 0x5AC52D1B, 0x5CB0679E, 0x4FA33742, + 0xD3822740, 0x99BC9BBE, 0xD5118E9D, 0xBF0F7315, 0xD62D1C7E, 0xC700C47B, + 0xB78C1B6B, 0x21A19045, 0xB26EB1BE, 0x6A366EB4, 0x5748AB2F, 0xBC946E79, + 0xC6A376D2, 0x6549C2C8, 0x530FF8EE, 0x468DDE7D, 0xD5730A1D, 0x4CD04DC6, + 0x2939BBDB, 0xA9BA4650, 0xAC9526E8, 0xBE5EE304, 0xA1FAD5F0, 0x6A2D519A, + 0x63EF8CE2, 0x9A86EE22, 0xC089C2B8, 0x43242EF6, 0xA51E03AA, 0x9CF2D0A4, + 0x83C061BA, 0x9BE96A4D, 0x8FE51550, 0xBA645BD6, 0x2826A2F9, 0xA73A3AE1, + 0x4BA99586, 0xEF5562E9, 0xC72FEFD3, 0xF752F7DA, 0x3F046F69, 0x77FA0A59, + 0x80E4A915, 0x87B08601, 0x9B09E6AD, 0x3B3EE593, 0xE990FD5A, 0x9E34D797, + 0x2CF0B7D9, 0x022B8B51, 0x96D5AC3A, 0x017DA67D, 0xD1CF3ED6, 0x7C7D2D28, + 0x1F9F25CF, 0xADF2B89B, 0x5AD6B472, 0x5A88F54C, 0xE029AC71, 0xE019A5E6, + 0x47B0ACFD, 0xED93FA9B, 0xE8D3C48D, 0x283B57CC, 0xF8D56629, 0x79132E28, + 0x785F0191, 0xED756055, 0xF7960E44, 0xE3D35E8C, 0x15056DD4, 0x88F46DBA, + 0x03A16125, 0x0564F0BD, 0xC3EB9E15, 0x3C9057A2, 0x97271AEC, 0xA93A072A, + 0x1B3F6D9B, 0x1E6321F5, 0xF59C66FB, 0x26DCF319, 0x7533D928, 0xB155FDF5, + 0x03563482, 0x8ABA3CBB, 0x28517711, 0xC20AD9F8, 0xABCC5167, 0xCCAD925F, + 0x4DE81751, 0x3830DC8E, 0x379D5862, 0x9320F991, 0xEA7A90C2, 0xFB3E7BCE, + 0x5121CE64, 0x774FBE32, 0xA8B6E37E, 0xC3293D46, 0x48DE5369, 0x6413E680, + 0xA2AE0810, 0xDD6DB224, 0x69852DFD, 0x09072166, 0xB39A460A, 0x6445C0DD, + 0x586CDECF, 0x1C20C8AE, 0x5BBEF7DD, 0x1B588D40, 0xCCD2017F, 0x6BB4E3BB, + 0xDDA26A7E, 0x3A59FF45, 0x3E350A44, 0xBCB4CDD5, 0x72EACEA8, 0xFA6484BB, + 0x8D6612AE, 0xBF3C6F47, 0xD29BE463, 0x542F5D9E, 0xAEC2771B, 0xF64E6370, + 0x740E0D8D, 0xE75B1357, 0xF8721671, 0xAF537D5D, 0x4040CB08, 0x4EB4E2CC, + 0x34D2466A, 0x0115AF84, 0xE1B00428, 0x95983A1D, 0x06B89FB4, 0xCE6EA048, + 0x6F3F3B82, 0x3520AB82, 0x011A1D4B, 0x277227F8, 0x611560B1, 0xE7933FDC, + 0xBB3A792B, 0x344525BD, 0xA08839E1, 0x51CE794B, 0x2F32C9B7, 0xA01FBAC9, + 0xE01CC87E, 0xBCC7D1F6, 0xCF0111C3, 0xA1E8AAC7, 0x1A908749, 0xD44FBD9A, + 0xD0DADECB, 0xD50ADA38, 0x0339C32A, 0xC6913667, 0x8DF9317C, 0xE0B12B4F, + 0xF79E59B7, 0x43F5BB3A, 0xF2D519FF, 0x27D9459C, 0xBF97222C, 0x15E6FC2A, + 0x0F91FC71, 0x9B941525, 0xFAE59361, 0xCEB69CEB, 0xC2A86459, 0x12BAA8D1, + 0xB6C1075E, 0xE3056A0C, 0x10D25065, 0xCB03A442, 0xE0EC6E0E, 0x1698DB3B, + 0x4C98A0BE, 0x3278E964, 0x9F1F9532, 0xE0D392DF, 0xD3A0342B, 0x8971F21E, + 0x1B0A7441, 0x4BA3348C, 0xC5BE7120, 0xC37632D8, 0xDF359F8D, 0x9B992F2E, + 0xE60B6F47, 0x0FE3F11D, 0xE54CDA54, 0x1EDAD891, 0xCE6279CF, 0xCD3E7E6F, + 0x1618B166, 0xFD2C1D05, 0x848FD2C5, 0xF6FB2299, 0xF523F357, 0xA6327623, + 0x93A83531, 0x56CCCD02, 0xACF08162, 0x5A75EBB5, 0x6E163697, 0x88D273CC, + 0xDE966292, 0x81B949D0, 0x4C50901B, 0x71C65614, 0xE6C6C7BD, 0x327A140A, + 0x45E1D006, 0xC3F27B9A, 0xC9AA53FD, 0x62A80F00, 0xBB25BFE2, 0x35BDD2F6, + 0x71126905, 0xB2040222, 0xB6CBCF7C, 0xCD769C2B, 0x53113EC0, 0x1640E3D3, + 0x38ABBD60, 0x2547ADF0, 0xBA38209C, 0xF746CE76, 0x77AFA1C5, 0x20756060, + 0x85CBFE4E, 0x8AE88DD8, 0x7AAAF9B0, 0x4CF9AA7E, 0x1948C25C, 0x02FB8A8C, + 0x01C36AE4, 0xD6EBE1F9, 0x90D4F869, 0xA65CDEA0, 0x3F09252D, 0xC208E69F, + 0xB74E6132, 0xCE77E25B, 0x578FDFE3, 0x3AC372E6 +}; + +static const uint32_t ps[BLOWFISH_ROUNDS + 2] = { + 0x243F6A88, 0x85A308D3, 0x13198A2E, 0x03707344, 0xA4093822, 0x299F31D0, + 0x082EFA98, 0xEC4E6C89, 0x452821E6, 0x38D01377, 0xBE5466CF, 0x34E90C6C, + 0xC0AC29B7, 0xC97C50DD, 0x3F84D5B5, 0xB5470917, 0x9216D5D9, 0x8979FB1B +}; + +void Blowfish::burn_stack(int bytes) +{ + char buf[64]; + + memset(buf, 0, sizeof buf); + bytes -= sizeof buf; + if (bytes > 0) + burn_stack(bytes); +} + +void Blowfish::do_encrypt(uint32_t * ret_xl, uint32_t * ret_xr) +{ +#if BLOWFISH_ROUNDS == 16 + uint32_t xl, xr, *s0, *s1, *s2, *s3, *p; + + xl = *ret_xl; + xr = *ret_xr; + p = bc.p; + s0 = bc.s0; + s1 = bc.s1; + s2 = bc.s2; + s3 = bc.s3; + + R(xl, xr, 0, p, s0, s1, s2, s3); + R(xr, xl, 1, p, s0, s1, s2, s3); + R(xl, xr, 2, p, s0, s1, s2, s3); + R(xr, xl, 3, p, s0, s1, s2, s3); + R(xl, xr, 4, p, s0, s1, s2, s3); + R(xr, xl, 5, p, s0, s1, s2, s3); + R(xl, xr, 6, p, s0, s1, s2, s3); + R(xr, xl, 7, p, s0, s1, s2, s3); + R(xl, xr, 8, p, s0, s1, s2, s3); + R(xr, xl, 9, p, s0, s1, s2, s3); + R(xl, xr, 10, p, s0, s1, s2, s3); + R(xr, xl, 11, p, s0, s1, s2, s3); + R(xl, xr, 12, p, s0, s1, s2, s3); + R(xr, xl, 13, p, s0, s1, s2, s3); + R(xl, xr, 14, p, s0, s1, s2, s3); + R(xr, xl, 15, p, s0, s1, s2, s3); + + xl ^= p[BLOWFISH_ROUNDS]; + xr ^= p[BLOWFISH_ROUNDS + 1]; + + *ret_xl = xr; + *ret_xr = xl; + +#else + uint32_t xl, xr, temp, *p; + int i; + + xl = *ret_xl; + xr = *ret_xr; + p = bc.p; + + for (i = 0; i < BLOWFISH_ROUNDS; i++) { + xl ^= p[i]; + xr ^= function_F(xl); + temp = xl; + xl = xr; + xr = temp; + } + temp = xl; + xl = xr; + xr = temp; + + xr ^= p[BLOWFISH_ROUNDS]; + xl ^= p[BLOWFISH_ROUNDS + 1]; + + *ret_xl = xl; + *ret_xr = xr; +#endif +} + +void Blowfish::do_decrypt(uint32_t * ret_xl, uint32_t * ret_xr) +{ +#if BLOWFISH_ROUNDS == 16 + uint32_t xl, xr, *s0, *s1, *s2, *s3, *p; + + xl = *ret_xl; + xr = *ret_xr; + p = bc.p; + s0 = bc.s0; + s1 = bc.s1; + s2 = bc.s2; + s3 = bc.s3; + + R(xl, xr, 17, p, s0, s1, s2, s3); + R(xr, xl, 16, p, s0, s1, s2, s3); + R(xl, xr, 15, p, s0, s1, s2, s3); + R(xr, xl, 14, p, s0, s1, s2, s3); + R(xl, xr, 13, p, s0, s1, s2, s3); + R(xr, xl, 12, p, s0, s1, s2, s3); + R(xl, xr, 11, p, s0, s1, s2, s3); + R(xr, xl, 10, p, s0, s1, s2, s3); + R(xl, xr, 9, p, s0, s1, s2, s3); + R(xr, xl, 8, p, s0, s1, s2, s3); + R(xl, xr, 7, p, s0, s1, s2, s3); + R(xr, xl, 6, p, s0, s1, s2, s3); + R(xl, xr, 5, p, s0, s1, s2, s3); + R(xr, xl, 4, p, s0, s1, s2, s3); + R(xl, xr, 3, p, s0, s1, s2, s3); + R(xr, xl, 2, p, s0, s1, s2, s3); + + xl ^= p[1]; + xr ^= p[0]; + + *ret_xl = xr; + *ret_xr = xl; + +#else + uint32_t xl, xr, temp, *p; + int i; + + xl = *ret_xl; + xr = *ret_xr; + p = bc.p; + + for (i = BLOWFISH_ROUNDS + 1; i > 1; i--) { + xl ^= p[i]; + xr ^= function_F(xl); + temp = xl; + xl = xr; + xr = temp; + } + + temp = xl; + xl = xr; + xr = temp; + + xr ^= p[1]; + xl ^= p[0]; + + *ret_xl = xl; + *ret_xr = xr; +#endif +} + +void Blowfish::do_encrypt_block(byte * outbuf, byte * inbuf) +{ + uint32_t d1, d2; + + d1 = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3]; + d2 = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7]; + do_encrypt(&d1, &d2); + outbuf[0] = (d1 >> 24) & 0xff; + outbuf[1] = (d1 >> 16) & 0xff; + outbuf[2] = (d1 >> 8) & 0xff; + outbuf[3] = d1 & 0xff; + outbuf[4] = (d2 >> 24) & 0xff; + outbuf[5] = (d2 >> 16) & 0xff; + outbuf[6] = (d2 >> 8) & 0xff; + outbuf[7] = d2 & 0xff; +} + +void Blowfish::encrypt_block(byte * outbuf, byte * inbuf) +{ + do_encrypt_block(outbuf, inbuf); + burn_stack(64); +} + +void Blowfish::do_decrypt_block(byte * outbuf, byte * inbuf) +{ + uint32_t d1, d2; + + d1 = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3]; + d2 = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7]; + do_decrypt(&d1, &d2); + outbuf[0] = (d1 >> 24) & 0xff; + outbuf[1] = (d1 >> 16) & 0xff; + outbuf[2] = (d1 >> 8) & 0xff; + outbuf[3] = d1 & 0xff; + outbuf[4] = (d2 >> 24) & 0xff; + outbuf[5] = (d2 >> 16) & 0xff; + outbuf[6] = (d2 >> 8) & 0xff; + outbuf[7] = d2 & 0xff; +} + +void Blowfish::decrypt_block(byte * outbuf, byte * inbuf) +{ + do_decrypt_block(outbuf, inbuf); + burn_stack(64); +} + +bool Blowfish::selfTest() +{ + byte plain1[] = "BLOWFISH"; + byte key1[] = "abcdefghijklmnopqrstuvwxyz"; + byte cipher1[] = "\x32\x4E\xD0\xFE\xF4\x13\xA2\x03"; + byte plain2[] = "\xFE\xDC\xBA\x98\x76\x54\x32\x10"; + byte key2[] = "\x41\x79\x6E\xA0\x52\x61\x6E\xE4"; + byte cipher2[] = "\xE1\x13\xF4\x10\x2C\xFC\xCE\x43"; + byte buffer[8]; + + Blowfish blowfish; + + blowfish.bf_setkey(key1, array_size(key1) - 1); + blowfish.bf_encrypt(buffer, plain1, array_size(plain1) - 1); + if (unlikely(memcmp(buffer, cipher1, array_size(cipher1) - 1))) + return false; + + blowfish.bf_decrypt(buffer, buffer, array_size(buffer)); + if (unlikely(memcmp(buffer, plain1, array_size(plain1) - 1))) + return false; + + blowfish.bf_setkey(key2, array_size(key2) - 1); + blowfish.bf_encrypt(buffer, plain2, array_size(plain2) - 1); + if (unlikely(memcmp(buffer, cipher2, array_size(cipher2) - 1))) + return false; + + blowfish.bf_decrypt(buffer, buffer, array_size(buffer)); + if (unlikely(memcmp(buffer, plain2, array_size(plain2) - 1))) + return false; + + return true; +} + +int Blowfish::do_bf_setkey(byte * key, unsigned int keylen) +{ + int i, j; + uint32_t data, datal, datar; + + for (i = 0; i < BLOWFISH_ROUNDS + 2; ++i) + bc.p[i] = ps[i]; + for (i = 0; i < 256; ++i) { + bc.s0[i] = ks0[i]; + bc.s1[i] = ks1[i]; + bc.s2[i] = ks2[i]; + bc.s3[i] = ks3[i]; + } + + for (i = j = 0; i < BLOWFISH_ROUNDS + 2; ++i) { +#ifdef BIG_ENDIAN_HOST + ((byte *) & data)[0] = key[j]; + ((byte *) & data)[1] = key[(j + 1) % keylen]; + ((byte *) & data)[2] = key[(j + 2) % keylen]; + ((byte *) & data)[3] = key[(j + 3) % keylen]; +#else + ((byte *) & data)[3] = key[j]; + ((byte *) & data)[2] = key[(j + 1) % keylen]; + ((byte *) & data)[1] = key[(j + 2) % keylen]; + ((byte *) & data)[0] = key[(j + 3) % keylen]; +#endif + bc.p[i] ^= data; + j = (j + 4) % keylen; + } + + datal = datar = 0; + for (i = 0; i < BLOWFISH_ROUNDS + 2; i += 2) { + do_encrypt(&datal, &datar); + bc.p[i] = datal; + bc.p[i + 1] = datar; + } + for (i = 0; i < 256; i += 2) { + do_encrypt(&datal, &datar); + bc.s0[i] = datal; + bc.s0[i + 1] = datar; + } + for (i = 0; i < 256; i += 2) { + do_encrypt(&datal, &datar); + bc.s1[i] = datal; + bc.s1[i + 1] = datar; + } + for (i = 0; i < 256; i += 2) { + do_encrypt(&datal, &datar); + bc.s2[i] = datal; + bc.s2[i + 1] = datar; + } + for (i = 0; i < 256; i += 2) { + do_encrypt(&datal, &datar); + bc.s3[i] = datal; + bc.s3[i + 1] = datar; + } + + /* Check for weak key. A weak key is a key in which a value in */ + /* the P-array (here c) occurs more than once per table. */ + for (i = 0; i < 255; ++i) { + for (j = i + 1; j < 256; ++j) { + if ((bc.s0[i] == bc.s0[j]) || (bc.s1[i] == bc.s1[j]) || + (bc.s2[i] == bc.s2[j]) || (bc.s3[i] == bc.s3[j])) + return 1; + } + } + + return 0; +} + +int Blowfish::bf_setkey(byte * key, unsigned int keylen) +{ + int rc = do_bf_setkey(key, keylen); + burn_stack(64); + return rc; +} + +int Blowfish::bf_encrypt(byte * outbuf, byte * inbuf, unsigned int inbuf_len) +{ + if (unlikely(inbuf_len % 8)) + return 1; + + unsigned int i = 0; + while (i < inbuf_len) { + encrypt_block(outbuf + i, inbuf + i); + i += 8; + } + return 0; +} + +int Blowfish::bf_decrypt(byte * outbuf, byte * inbuf, unsigned int inbuf_len) +{ + if (unlikely(inbuf_len % 8)) + return 1; + + unsigned int i = 0; + while (i < inbuf_len) { + decrypt_block(outbuf + i, inbuf + i); + i += 8; + } + return 0; +} + +void Blowfish::padNull(string *buf) +{ + buf->append(1, (char)0x01); + string::size_type append_null = 8 - (buf->length() % 8); + buf->append(append_null, (char)0x00); +} + +bool Blowfish::unpadNull(string *buf) +{ + if (unlikely(buf->size() % 8)) + return false; + string::size_type pos = buf->length() - 1; + while ((*buf)[pos] != (char)0x01) { + if (unlikely(pos == 0)) + return false; + --pos; + } + buf->erase(pos, buf->length() - pos); + return true; +} diff --git a/pwmanager/pwmanager/blowfish.h b/pwmanager/pwmanager/blowfish.h new file mode 100644 index 0000000..c05de77 --- a/dev/null +++ b/pwmanager/pwmanager/blowfish.h @@ -0,0 +1,120 @@ +/*************************************************************************** + * * + * 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" + +#include +#include +using std::string; + +#define BLOWFISH_BLOCKSIZE 8 +#define BLOWFISH_ROUNDS 16 +#define CIPHER_ALGO_BLOWFISH 4 /* blowfish 128 bit key */ + +typedef uint8_t byte; + +/** 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/commentbox.cpp b/pwmanager/pwmanager/commentbox.cpp new file mode 100644 index 0000000..280b139 --- a/dev/null +++ b/pwmanager/pwmanager/commentbox.cpp @@ -0,0 +1,238 @@ +/*************************************************************************** + * * + * 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 "commentbox.h" +#include "pwmexception.h" +#include "htmlgen.h" + +#include + +#ifndef PWM_EMBEDDED +#include +#include +#include +#else +#include +#endif + +CommentBox::CommentBox(QWidget *_parentWidget) +{ + PWM_ASSERT(_parentWidget); + parentWidget = _parentWidget; + textDta = 0; +#ifndef PWM_EMBEDDED + htmlDta = 0; +#endif + mode = mode_notSet; +} + +CommentBox::~CommentBox() +{ + clearText(); + clearHtml(); +} + +void CommentBox::clear() +{ + clearText(); + clearHtml(); + mode = mode_notSet; +} + +void CommentBox::clearText() +{ + delete_ifnot_null(textDta); +} + +void CommentBox::clearHtml() +{ +#ifndef PWM_EMBEDDED + delete_ifnot_null(htmlDta); +#endif +} + +void CommentBox::setText(const QString &text) +{ + switchTo(mode_text); + PWM_ASSERT(textDta); + textDta->setText(i18n("Comment") + ": " + text); + if (!textDta->isVisible()) + textDta->show(); +} + +bool CommentBox::getText(QString *text) +{ + if (mode != mode_text) + return false; + PWM_ASSERT(text); + if (!textDta) { + *text = ""; + return true; + } + *text = textDta->text(); + return true; +} + +void CommentBox::setHtml(QString code) +{ +#ifndef PWM_EMBEDDED + switchTo(mode_html); + PWM_ASSERT(htmlDta); + if (!HtmlGen::replaceSSDummy(&code)) + printWarn("CommentBox::setHtml(): replaceSSDummy() failed!"); + htmlDta->begin(); + htmlDta->write(code); + htmlDta->end(); + htmlDta->show(); +#endif +} + +void CommentBox::setContent(const QString &dta) +{ + // if there's no data, hide the comment-box + if (dta.isEmpty()) { + clear(); + return; + } +#ifndef PWM_EMBEDDED + if (HtmlGen::isHtml(dta)) { + setHtml(dta); + return; + } +#endif + // we assume it's plain text + setText(dta); +} + +void CommentBox::switchTo(commentBoxMode newMode) +{ + if (newMode == mode) + return; + + // cleanup old mode + switch (mode) { + case mode_text: + clearText(); + break; + case mode_html: + clearHtml(); + break; + default: + break; + } + + // setup new mode + switch (newMode) { + case mode_text: +#ifndef PWM_EMBEDDED + textDta = new QTextEdit(parentWidget); + textDta->setTextFormat(Qt::PlainText); +#else + textDta = new QMultiLineEdit(parentWidget); +#endif + textDta->setReadOnly(true); + textDta->show(); + break; + case mode_html: +#ifndef PWM_EMBEDDED + htmlDta = new KHTMLPart(parentWidget, 0, + parentWidget); + htmlDta->show(); +#endif + break; + default: + BUG(); + break; + } + + mode = newMode; +} + +void CommentBox::show() +{ + switch (mode) { + case mode_text: + PWM_ASSERT(textDta); + textDta->show(); + break; + case mode_html: +#ifndef PWM_EMBEDDED + PWM_ASSERT(htmlDta); + htmlDta->show(); +#endif + break; + default: + break; + } +} + +void CommentBox::hide() +{ + switch (mode) { + case mode_text: + PWM_ASSERT(textDta); + textDta->hide(); + break; + case mode_html: +#ifndef PWM_EMBEDDED + PWM_ASSERT(htmlDta); + htmlDta->hide(); +#endif + break; + default: + break; + } +} + +void CommentBox::resize(const QSize &size) +{ + switch (mode) { + case mode_text: + PWM_ASSERT(textDta); + textDta->resize(size); + break; + case mode_html: +#ifndef PWM_EMBEDDED + PWM_ASSERT(htmlDta); + htmlDta->view()->resize(size); +#endif + break; + default: + break; + } +} + +QSize CommentBox::size() +{ + switch (mode) { + case mode_text: + PWM_ASSERT(textDta); + return textDta->size(); + break; + case mode_html: +#ifndef PWM_EMBEDDED + PWM_ASSERT(htmlDta); + return htmlDta->view()->size(); +#endif + break; + default: + break; + } + return QSize(); +} diff --git a/pwmanager/pwmanager/commentbox.h b/pwmanager/pwmanager/commentbox.h new file mode 100644 index 0000000..a220acd --- a/dev/null +++ b/pwmanager/pwmanager/commentbox.h @@ -0,0 +1,100 @@ +/*************************************************************************** + * * + * 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 COMMENTBOX_H +#define COMMENTBOX_H + +#include +#include + +class QWidget; +class QTextEdit; +class QMultiLineEdit; +class KHTMLPart; + +/** Implementation of the advanced HTML comment box */ +class CommentBox +{ +protected: + enum commentBoxMode + { + mode_notSet = 0, + mode_text, + mode_html + }; + +public: + CommentBox(QWidget *_parentWidget); + ~CommentBox(); + + /** clear all data in the comment box */ + void clear(); + /** show the comment box */ + void show(); + /** hide the comment box */ + void hide(); + /** resize the comment box */ + void resize(const QSize &size); + void resize(int w, int h) + { resize(QSize(w, h)); } + /** get the size of the comment box */ + QSize size(); + /** if neccessary switch to text-mode and + * insert this text into the comment box + */ + void setText(const QString &text); + /** get the text of the comment box. + * If it's not in text-mode it returns false + */ + bool getText(QString *text); + /** if neccessary switch to HTML-mode and + * insert this html code into the comment box + */ + void setHtml(QString code); + /** checks "dta" for its type, sets the correct + * mode and writes "dta" to the comment box + */ + void setContent(const QString &dta); + +protected: + /** switch the current mode */ + void switchTo(commentBoxMode newMode); + /** clear all text data */ + void clearText(); + /** clear all HTML data */ + void clearHtml(); + +protected: + /** parent widget for this comment box */ + QWidget *parentWidget; + /** current comment box usage type */ + commentBoxMode mode; +#ifndef PWM_EMBEDDED + /** if the comment box is a normal textbox, data is stored here */ + QTextEdit *textDta; + /** if the comment box is a HTML box, data is stored here */ + KHTMLPart *htmlDta; +#else + /** if the comment box is a normal textbox, data is stored here */ + QMultiLineEdit *textDta; +#endif + +}; + +#endif diff --git a/pwmanager/pwmanager/compiler.h b/pwmanager/pwmanager/compiler.h new file mode 100644 index 0000000..be08c6d --- a/dev/null +++ b/pwmanager/pwmanager/compiler.h @@ -0,0 +1,61 @@ +/*************************************************************************** + * * + * Derived from the linux-2.6 tree * + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef __PWMANAGER_COMPILER_H +#define __PWMANAGER_COMPILER_H + +#ifdef __deprecated +# undef __deprecated +#endif +#if __GNUC__ >= 3 +# if __GNUC_MINOR__ > 0 +# define __deprecated __attribute__((deprecated)) +# endif +#elif __GNUC__ == 2 +# if __GNUC_MINOR__ < 96 +# ifdef __builtin_expect +# undef __builtin_expect +# endif +# define __builtin_expect(x, expected_value) (x) +# endif +#else +# error "Sorry, your compiler is too old/not supported." +#endif + +/* + * Allow us to mark functions as 'deprecated' and have gcc emit a nice + * warning for each use, in hopes of speeding the functions removal. + * Usage is: + * int __deprecated foo(void) + */ +#ifndef __deprecated +# define __deprecated /* unimplemented */ +#endif + +/* define likely() and unlikely() */ +#ifdef likely +# undef likely +#endif +#ifdef unlikely +# undef unlikely +#endif +#define likely(x) __builtin_expect(!!(x), 1) +#define unlikely(x) __builtin_expect(!!(x), 0) + +#ifdef NOREGPARM +# undef NOREGPARM +#endif +#define NOREGPARM __attribute__((regparm(0))) +#ifdef REGPARM +# undef REGPARM +#endif +#define REGPARM __attribute__((regparm(3))) + +#endif // __PWMANAGER_COMPILER_H diff --git a/pwmanager/pwmanager/compressbzip2.cpp b/pwmanager/pwmanager/compressbzip2.cpp new file mode 100644 index 0000000..c3a9edd --- a/dev/null +++ b/pwmanager/pwmanager/compressbzip2.cpp @@ -0,0 +1,138 @@ +/*************************************************************************** + * * + * 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$ + **************************************************************************/ + +#include "compressbzip2.h" + +#include + +#define BZ_NO_STDIO +#include + +#define BZ_BLOCK_SIZE 9 +#define BZ_WORK_FACTOR 30 +#define EXPAND_COMPRESS_DESTBUF_BYTES 1024 +#define EXPAND_DECOMPRESS_DESTBUF_BYTES (1024 * 10) + + +bool CompressBzip2::compress(string *d) +{ + int ret; + char *dest, *source; + unsigned int sourceLen, destLen; + + sourceLen = d->length(); + destLen = calcCompressDestLen(sourceLen); + source = static_cast(malloc(sourceLen)); + if (!source) + return false; + memcpy(source, d->c_str(), sourceLen); + dest = static_cast(malloc(destLen)); + if (!dest) { + free(source); + return false; + } + while (1) { + ret = BZ2_bzBuffToBuffCompress(dest, + &destLen, + source, + sourceLen, + BZ_BLOCK_SIZE, + 0, + BZ_WORK_FACTOR); + switch (ret) { + case BZ_OK: + goto out; + case BZ_OUTBUFF_FULL: + /* we don't use realloc(), because it may + * (in this case) unneccessarily copy the old block + * to the new allocated block. + */ + free(dest); + destLen += EXPAND_COMPRESS_DESTBUF_BYTES; + dest = static_cast(malloc(destLen)); + if (!dest) { + free(source); + return false; + } + break; + default: + free(source), + free(dest); + return false; + } + } +out: + free(source); + d->assign(dest, destLen); + free(dest); + return true; +} + +bool CompressBzip2::decompress(string *d) +{ + int ret; + char *dest, *source; + unsigned int sourceLen, destLen; + + sourceLen = d->length(); + destLen = calcDecompressDestLen(sourceLen); + source = static_cast(malloc(sourceLen)); + if (!source) + return false; + memcpy(source, d->c_str(), sourceLen); + dest = static_cast(malloc(destLen)); + if (!dest) { + free(source); + return false; + } + while (1) { + ret = BZ2_bzBuffToBuffDecompress(dest, + &destLen, + source, + sourceLen, + 0, + 0); + switch (ret) { + case BZ_OK: + goto out; + case BZ_OUTBUFF_FULL: + /* we don't use realloc(), because it may + * (in this case) unneccessarily copy the old block + * to the new allocated block. + */ + free(dest); + destLen += EXPAND_DECOMPRESS_DESTBUF_BYTES; + dest = static_cast(malloc(destLen)); + if (!dest) { + free(source); + return false; + } + break; + default: + free(source), + free(dest); + return false; + } + } +out: + free(source); + d->assign(dest, destLen); + free(dest); + return true; +} diff --git a/pwmanager/pwmanager/compressbzip2.h b/pwmanager/pwmanager/compressbzip2.h new file mode 100644 index 0000000..4f4885c --- a/dev/null +++ b/pwmanager/pwmanager/compressbzip2.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * * + * 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 COMPRESSBZIP2_H +#define COMPRESSBZIP2_H + +#include +using std::string; + +/** bzip2 compression */ +class CompressBzip2 +{ +public: + CompressBzip2() {} + + /** compress the string d */ + bool compress(string *d); + /** decompress the string d */ + bool decompress(string *d); + +protected: + /** calculates the length of the dest-buffer + * for compress() using the size of the source-buffer + */ + unsigned int calcCompressDestLen(unsigned int sourceLen) + { return (sourceLen + (sourceLen / 100 + 600)); } + /** calculates the length of the dest-buffer + * for decompress() using the size of the source-buffer + */ + unsigned int calcDecompressDestLen(unsigned int sourceLen) + { return (sourceLen * 2); } +}; + +#endif diff --git a/pwmanager/pwmanager/compressgzip.cpp b/pwmanager/pwmanager/compressgzip.cpp new file mode 100644 index 0000000..0a325c6 --- a/dev/null +++ b/pwmanager/pwmanager/compressgzip.cpp @@ -0,0 +1,115 @@ +/*************************************************************************** + * * + * 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$ + **************************************************************************/ + +#include "compressgzip.h" + +#include +#include + +#define COMPRESSION_LEVEL Z_BEST_COMPRESSION +#define EXPAND_COMPRESS_DESTBUF_BYTES 1024 +#define EXPAND_DECOMPRESS_DESTBUF_BYTES (1024 * 10) + + +bool CompressGzip::compress(string *d) +{ + int ret; + Bytef *dest; + const Bytef *source; + unsigned long sourceLen, destLen; + + source = reinterpret_cast(d->c_str()); + sourceLen = d->length(); + destLen = calcCompressDestLen(sourceLen); + dest = static_cast(malloc(destLen)); + if (!dest) + return false; + while (1) { + ret = compress2(dest, + static_cast(&destLen), + source, + static_cast(sourceLen), + COMPRESSION_LEVEL); + switch (ret) { + case Z_OK: + goto out; + case Z_BUF_ERROR: + /* we don't use realloc(), because it may + * (in this case) unneccessarily copy the old block + * to the new allocated block. + */ + free(dest); + destLen += EXPAND_COMPRESS_DESTBUF_BYTES; + dest = static_cast(malloc(destLen)); + if (!dest) + return false; + break; + default: + free(dest); + return false; + } + } +out: + d->assign(reinterpret_cast(dest), destLen); + free(dest); + return true; +} + +bool CompressGzip::decompress(string *d) +{ + int ret; + Bytef *dest; + const Bytef *source; + unsigned long sourceLen, destLen; + + source = reinterpret_cast(d->c_str()); + sourceLen = d->length(); + destLen = calcDecompressDestLen(sourceLen); + dest = static_cast(malloc(destLen)); + if (!dest) + return false; + while (1) { + ret = uncompress(dest, + static_cast(&destLen), + source, + static_cast(sourceLen)); + switch (ret) { + case Z_OK: + goto out; + case Z_BUF_ERROR: + /* we don't use realloc(), because it may + * (in this case) unneccessarily copy the old block + * to the new allocated block. + */ + free(dest); + destLen += EXPAND_DECOMPRESS_DESTBUF_BYTES; + dest = static_cast(malloc(destLen)); + if (!dest) + return false; + break; + default: + free(dest); + return false; + } + } +out: + d->assign(reinterpret_cast(dest), destLen); + free(dest); + return true; +} diff --git a/pwmanager/pwmanager/compressgzip.h b/pwmanager/pwmanager/compressgzip.h new file mode 100644 index 0000000..78c71d4 --- a/dev/null +++ b/pwmanager/pwmanager/compressgzip.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * * + * 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 COMPRESSGZIP_H +#define COMPRESSGZIP_H + +#include +using std::string; + +/** gzip compression */ +class CompressGzip +{ +public: + CompressGzip() {} + + /** compress the string d */ + bool compress(string *d); + /** decompress the string d */ + bool decompress(string *d); + +protected: + /** calculates the length of the dest-buffer + * for compress() using the size of the source-buffer + */ + unsigned int calcCompressDestLen(unsigned int sourceLen) + { return (sourceLen + (sourceLen / 100 / 10 + 12)); } + /** calculates the length of the dest-buffer + * for decompress() using the size of the source-buffer + */ + unsigned int calcDecompressDestLen(unsigned int sourceLen) + { return (sourceLen * 2); } +}; + +#endif diff --git a/pwmanager/pwmanager/configuration.cpp b/pwmanager/pwmanager/configuration.cpp new file mode 100644 index 0000000..8d67977 --- a/dev/null +++ b/pwmanager/pwmanager/configuration.cpp @@ -0,0 +1,459 @@ +/*************************************************************************** + * * + * 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 2.0 of pwmanager + * and was modified to run on embedded devices that run microkde + * + * $Id$ + **************************************************************************/ + +#include "configuration.h" +#if KDE_VERSION >= KDE_MAKE_VERSION(3, 2, 0) + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define INITIAL_CONFWND_SIZE (QSize(600, 450)) + + +/********************************************************* + ** class Configuration ** + *********************************************************/ + +Configuration * Configuration::_obj (0); + +Configuration::Configuration() +{ + skel = new KConfigSkeleton; + initSkel(); + readConfig(); +} + +Configuration::~Configuration() +{ + writeConfig(); + delete_ifnot_null(skel); +} + +void Configuration::initSkel() +{ + skel->setCurrentGroup("GLOBAL"); + skel->addItemString("autoStart", cGlobAutoStart); + skel->addItemString("browserCommand", cGlobBrowserCommand, CONF_DEFAULT_BROWSERCOMMAND); + skel->addItemString("xtermCommand", cGlobXtermCommand, CONF_DEFAULT_XTERMCOMMAND); + skel->addItemFont("entryFont", cGlobEntryFont); + skel->addItemInt("pwTimeout", cGlobPwTimeout, CONF_DEFAULT_PWTIMEOUT); + skel->addItemInt("lockTimeout", cGlobLockTimeout, CONF_DEFAULT_LOCKTIMEOUT); + skel->addItemInt("compression", cGlobCompression, CONF_DEFAULT_COMPRESSION); + skel->addItemInt("filePermissions", cGlobFilePermissions, CONF_DEFAULT_FILEPERMISSIONS); + skel->addItemInt("minimizeLock", cGlobMinimizeLock, CONF_DEFAULT_MINIMIZELOCK); + skel->addItemBool("unlockOnOpen", cGlobUnlockOnOpen, CONF_DEFAULT_UNLOCKONOPEN); + skel->addItemBool("tray", cGlobTray, CONF_DEFAULT_TRAY); + skel->addItemBool("makeFileBackup", cGlobMakeFileBackup, CONF_DEFAULT_MAKEFILEBACKUP); + skel->addItemBool("autostartDeeplocked", cGlobAutostartDeepLocked, CONF_DEFAULT_AUTOSTART_DEEPL); + skel->addItemBool("autoDeepLock", cGlobAutoDeepLock, CONF_DEFAULT_AUTODEEPLOCK); + skel->addItemBool("kwalletEmu", cGlobKwalletEmu, CONF_DEFAULT_KWALLETEMU); + skel->addItemBool("newEntrLockStat", cGlobNewEntrLockStat, CONF_DEFAULT_NEWENTRLOCKSTAT); + + skel->setCurrentGroup("WND"); + skel->addItemSize("MainWndSize", cWndMainWndSize); + skel->addItemInt("MainViewStyle", cWndMainViewStyle, CONF_DEFAULT_MAINVIEWSTYLE); + skel->addItemBool("autoMinimizeOnStart", cWndAutoMinimizeOnStart, CONF_DEFAULT_AUTOMINIMIZE); + skel->addItemBool("close", cWndClose, CONF_DEFAULT_WNDCLOSE); +} + +bool Configuration::showConfWnd(QWidget *parent) +{ + bool ret = true; + KConfigDialog *confDlg; + confDlg = new KConfigDialog(parent, i18n("Main configuration").latin1(), skel, + KDialogBase::IconList, + KConfigDialog::Default | KConfigDialog::Ok | + KConfigDialog::Cancel | KConfigDialog::Help, + KConfigDialog::Ok, true); + ConfPageGlobal *confPageGlobal = new ConfPageGlobal; + ConfPageLookNFeel *confPageLookNFeel = new ConfPageLookNFeel; + ConfPageFile *confPageFile = new ConfPageFile; + ConfPageTimeouts *confPageTimeouts = new ConfPageTimeouts; + ConfPageExtApps *confPageExtApps = new ConfPageExtApps; + ConfPageAutostart *confPageAutostart = new ConfPageAutostart; + confDlg->addPage(confPageGlobal, i18n("General"), "pwmanager"); + confDlg->addPage(confPageLookNFeel, i18n("Look & Feel"), "fonts"); + confDlg->addPage(confPageFile, i18n("Files"), "filesave"); + confDlg->addPage(confPageTimeouts, i18n("Timeouts"), "clock"); + confDlg->addPage(confPageExtApps, i18n("External Applications"), "gear"); + confDlg->addPage(confPageAutostart, i18n("Autostart"), "fileopen"); + confDlg->resize(INITIAL_CONFWND_SIZE); + if (confDlg->exec() == 0) + ret = false; + delete confPageGlobal; + delete confPageLookNFeel; + delete confPageFile; + delete confPageTimeouts; + delete confPageExtApps; + delete confPageAutostart; + return ret; +} + + +/********************************************************* + ** class OctLineEdit ** + *********************************************************/ + +OctLineEdit::OctLineEdit(QWidget *parent, const char *name) + : QLineEdit(parent, name) +{ +} + +OctLineEdit::~OctLineEdit() +{ +} + +void OctLineEdit::setText(const QString &t) +{ + bool ok; + int tmp = t.toInt(&ok, 10); + if (!ok) + return; + QString ret; + ret.setNum(tmp, 8); + QLineEdit::setText(ret); +} + +QString OctLineEdit::text() const +{ + bool ok; + QString ret; + QString t(QLineEdit::text()); + int tmp = t.toInt(&ok, 8); + if (!ok) + return ret; + ret.setNum(tmp, 10); + return ret; +} + +void OctLineEdit::keyPressEvent(QKeyEvent *e) +{ + int key = e->key(); + switch (key) { + case Qt::Key_0: + case Qt::Key_1: + case Qt::Key_2: + case Qt::Key_3: + case Qt::Key_4: + case Qt::Key_5: + case Qt::Key_6: + case Qt::Key_7: + case Qt::Key_Escape: + case Qt::Key_Backtab: + case Qt::Key_Backspace: + case Qt::Key_Return: + case Qt::Key_Enter: + case Qt::Key_Insert: + case Qt::Key_Delete: + case Qt::Key_Home: + case Qt::Key_End: + case Qt::Key_Left: + case Qt::Key_Up: + case Qt::Key_Right: + case Qt::Key_Down: + e->accept(); + QLineEdit::keyPressEvent(e); + break; + default: + e->ignore(); + } +} + + +/********************************************************* + ** class ConfPageGlobal ** + *********************************************************/ + +ConfPageGlobal::ConfPageGlobal(QWidget *parent, const char *name, WFlags f) + : QWidget(parent, name, f) +{ + QCheckBox *kcfg_tray; + QCheckBox *kcfg_autoMinimizeOnStart; + QCheckBox *kcfg_unlockOnOpen; + QCheckBox *kcfg_newEntrLockStat; + QCheckBox *kcfg_close; + QComboBox *kcfg_minimizeLock; + QLabel *kcfg_minimizeLock_label; + + QBoxLayout *l = new QVBoxLayout(this); + l->setSpacing(4); + kcfg_tray = new QCheckBox(i18n("Show icon in system-tray"), this, "kcfg_tray"); + l->addWidget(kcfg_tray); + kcfg_autoMinimizeOnStart = new QCheckBox(i18n("auto-minimize to tray on startup"), + this, "kcfg_autoMinimizeOnStart"); + l->addWidget(kcfg_autoMinimizeOnStart); + kcfg_unlockOnOpen = new QCheckBox(i18n("Open document with passwords unlocked"), + this, "kcfg_unlockOnOpen"); + l->addWidget(kcfg_unlockOnOpen); +#ifdef CONFIG_KWALLETIF + QCheckBox *kcfg_kwalletEmu; + kcfg_kwalletEmu = new QCheckBox(i18n("KWallet emulation"), + this, "kcfg_kwalletEmu"); + l->addWidget(kcfg_kwalletEmu); +#endif // CONFIG_KWALLETIF + kcfg_newEntrLockStat = new QCheckBox(i18n("Automatically lock new entries"), + this, "kcfg_newEntrLockStat"); + l->addWidget(kcfg_newEntrLockStat); + kcfg_close = new QCheckBox(i18n("Do not minimize windows into tray. (Close the window)"), + this, "kcfg_close"); + l->addWidget(kcfg_close); + l->addSpacing(4); + QBoxLayout *hl = new QHBoxLayout(this); + hl->setSpacing(10); + kcfg_minimizeLock_label = new QLabel(i18n("auto-lock on minimize:"), this); + hl->addWidget(kcfg_minimizeLock_label); + kcfg_minimizeLock = new QComboBox(this, "kcfg_minimizeLock"); + hl->addStretch(); + hl->addWidget(kcfg_minimizeLock); + kcfg_minimizeLock->insertItem(i18n("don't lock")); + kcfg_minimizeLock->insertItem(i18n("normal lock")); + kcfg_minimizeLock->insertItem(i18n("deep-lock")); + l->addLayout(hl); + l->addStretch(); +} + + +/********************************************************* + ** class ConfPageLookNFeel ** + *********************************************************/ + +ConfPageLookNFeel::ConfPageLookNFeel(QWidget *parent, const char *name, WFlags f) + : QWidget(parent, name, f) +{ + QComboBox *kcfg_MainViewStyle; + QLabel *kcfg_MainViewStyle_label; + KFontRequester *kcfg_entryFont; + QGroupBox *kcfg_entryFont_box; + + QBoxLayout *l = new QVBoxLayout(this); + l->setSpacing(10); + // font + kcfg_entryFont_box = new QGroupBox(i18n("Font for the password entries:"), this); + l->addWidget(kcfg_entryFont_box); + kcfg_entryFont_box->setColumns(1); + kcfg_entryFont = new KFontRequester(kcfg_entryFont_box, "kcfg_entryFont", false); + // wnd style + QBoxLayout *hl = new QHBoxLayout(this); + hl->setSpacing(10); + kcfg_MainViewStyle_label = new QLabel(i18n("Window-style:"), this); + hl->addWidget(kcfg_MainViewStyle_label); + kcfg_MainViewStyle = new QComboBox(this, "kcfg_MainViewStyle"); + hl->addStretch(); + hl->addWidget(kcfg_MainViewStyle); + kcfg_MainViewStyle->insertItem(i18n("Category on top")); + kcfg_MainViewStyle->insertItem(i18n("Category-list left")); + l->addLayout(hl); + l->addStretch(); +} + + +/********************************************************* + ** class ConfPageFile ** + *********************************************************/ + +ConfPageFile::ConfPageFile(QWidget *parent, const char *name, WFlags f) + : QWidget(parent, name, f) +{ + QComboBox *kcfg_compression; + QLabel *kcfg_compression_label; + OctLineEdit *kcfg_filePermissions; + QLabel *kcfg_filePermissions_label; + QCheckBox *kcfg_makeFileBackup; + + QBoxLayout *l = new QVBoxLayout(this); + l->setSpacing(10); + // compression + QBoxLayout *hl = new QHBoxLayout(this); + hl->setSpacing(10); + kcfg_compression_label = new QLabel(i18n("*.pwm file compression:"), this); + hl->addWidget(kcfg_compression_label); + kcfg_compression = new QComboBox(this, "kcfg_compression"); + hl->addStretch(); + hl->addWidget(kcfg_compression); + kcfg_compression->insertItem(i18n("none")); + kcfg_compression->insertItem(i18n("gzip")); + kcfg_compression->insertItem(i18n("bzip2")); + l->addLayout(hl); + // permissions + hl = new QHBoxLayout(this); + hl->setSpacing(10); + kcfg_filePermissions_label = new QLabel(i18n("permissions:"), this); + hl->addWidget(kcfg_filePermissions_label); + kcfg_filePermissions = new OctLineEdit(this, "kcfg_filePermissions"); + hl->addStretch(); + hl->addWidget(kcfg_filePermissions); + kcfg_filePermissions->setMaxLength(3); + l->addLayout(hl); + // backup + kcfg_makeFileBackup = new QCheckBox(i18n("Make file backup before saving"), + this, "kcfg_makeFileBackup"); + l->addWidget(kcfg_makeFileBackup); + l->addStretch(); +} + + +/********************************************************* + ** class ConfPageTimeouts ** + *********************************************************/ + +ConfPageTimeouts::ConfPageTimeouts(QWidget *parent, const char *name, WFlags f) + : QWidget(parent, name, f) +{ + QSpinBox *kcfg_pwTimeout; + QLabel *kcfg_pwTimeout_label; + QSpinBox *kcfg_lockTimeout; + QLabel *kcfg_lockTimeout_label; + QCheckBox *kcfg_autoDeepLock; + + QBoxLayout *l = new QVBoxLayout(this); + l->setSpacing(10); + // pw timeout + QBoxLayout *hl = new QHBoxLayout(this); + hl->setSpacing(10); + kcfg_pwTimeout_label = new QLabel(i18n("Password timeout (timeout to hold " + "password in memory, so you don't have " + "to re-enter it, if you already have " + "entered it) [set to 0 to disable]:"), + this); + hl->addWidget(kcfg_pwTimeout_label); + kcfg_pwTimeout_label->setAlignment(QLabel::WordBreak); + kcfg_pwTimeout = new QSpinBox(this, "kcfg_pwTimeout"); + hl->addStretch(); + hl->addWidget(kcfg_pwTimeout); + l->addLayout(hl); + // lock timeout + hl = new QHBoxLayout(this); + hl->setSpacing(10); + kcfg_lockTimeout_label = new QLabel(i18n("Auto-lock timeout (auto lock document " + "after this amount of seconds) " + "[set to 0 to disable]:"), + this); + hl->addWidget(kcfg_lockTimeout_label); + kcfg_lockTimeout_label->setAlignment(QLabel::WordBreak); + kcfg_lockTimeout = new QSpinBox(this, "kcfg_lockTimeout"); + hl->addStretch(); + hl->addWidget(kcfg_lockTimeout); + l->addLayout(hl); + // auto deep lock checkbox + kcfg_autoDeepLock = new QCheckBox(i18n("deep-lock on autolock"), + this, "kcfg_autoDeepLock"); + l->addWidget(kcfg_autoDeepLock); + l->addStretch(); +} + + +/********************************************************* + ** class ConfPageExtApps ** + *********************************************************/ + +ConfPageExtApps::ConfPageExtApps(QWidget *parent, const char *name, WFlags f) + : QWidget(parent, name, f) +{ + QLineEdit *kcfg_browserCommand; + QLabel *kcfg_browserCommand_label; + QLineEdit *kcfg_xtermCommand; + QLabel *kcfg_xtermCommand_label; + + QBoxLayout *l = new QVBoxLayout(this); + l->setSpacing(4); + // browser command + QBoxLayout *hl = new QHBoxLayout(this); + hl->setSpacing(10); + kcfg_browserCommand_label = new QLabel(i18n("Favourite browser:"), this); + hl->addWidget(kcfg_browserCommand_label); + kcfg_browserCommand = new QLineEdit(this, "kcfg_browserCommand"); + hl->addStretch(); + hl->addWidget(kcfg_browserCommand); + l->addLayout(hl); + // xterm command + hl = new QHBoxLayout(this); + hl->setSpacing(10); + kcfg_xtermCommand_label = new QLabel(i18n("Favourite X-terminal:"), this); + hl->addWidget(kcfg_xtermCommand_label); + kcfg_xtermCommand = new QLineEdit(this, "kcfg_xtermCommand"); + hl->addStretch(); + hl->addWidget(kcfg_xtermCommand); + l->addLayout(hl); + l->addStretch(); +} + + +/********************************************************* + ** class ConfPageAutostart ** + *********************************************************/ + +ConfPageAutostart::ConfPageAutostart(QWidget *parent, const char *name, WFlags f) + : QWidget(parent, name, f) +{ + QGroupBox *kcfg_autoStart_box; + QPushButton *kcfg_autoStart_button; + QCheckBox *kcfg_autostartDeeplocked; + + QBoxLayout *l = new QVBoxLayout(this); + l->setSpacing(4); + // autostart + kcfg_autoStart_box = new QGroupBox(i18n("Open this file automatically on startup:"), + this); + l->addWidget(kcfg_autoStart_box); + kcfg_autoStart_box->setColumns(2); + kcfg_autoStart = new QLineEdit(kcfg_autoStart_box, "kcfg_autoStart"); + kcfg_autoStart_button = new QPushButton("...", kcfg_autoStart_box); + kcfg_autostartDeeplocked = new QCheckBox(i18n("open deeplocked"), + kcfg_autoStart_box, "kcfg_autostartDeeplocked"); + l->addStretch(); + // connections + connect(kcfg_autoStart_button, SIGNAL(clicked()), + this, SLOT(browseButton_slot())); +} + +void ConfPageAutostart::browseButton_slot() +{ + QString path(KFileDialog::getOpenFileName(QString::null, + i18n("*.pwm|PwM Password file\n" + "*|All files"), this)); + if (path == QString::null) + return; + kcfg_autoStart->setText(path); +} + + +#include "configuration.moc" + +#else // KDE_VERSION >= KDE_MAKE_VERSION(3, 2, 0) + /* XXX: This is the code for KDE-3.1 compatibility. */ +# include "configuration_31compat.cpp" +#endif // KDE_VERSION >= KDE_MAKE_VERSION(3, 2, 0) diff --git a/pwmanager/pwmanager/configuration.h b/pwmanager/pwmanager/configuration.h new file mode 100644 index 0000000..9001147 --- a/dev/null +++ b/pwmanager/pwmanager/configuration.h @@ -0,0 +1,336 @@ +/*************************************************************************** + * * + * 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 __CONFIGURATION_H +#define __CONFIGURATION_H + +#define CONF_DEFAULT_PWTIMEOUT 10 /* 10 sec */ +#define CONF_DEFAULT_LOCKTIMEOUT 0 /* 0 == disable */ +#define CONF_DEFAULT_TRAY true +#define CONF_DEFAULT_UNLOCKONOPEN false +#define CONF_DEFAULT_MAINVIEWSTYLE 0 +#define CONF_DEFAULT_COMPRESSION 0x01 /* gzip */ +#define CONF_DEFAULT_AUTOMINIMIZE false +#define CONF_DEFAULT_BROWSERCOMMAND "" +#define CONF_DEFAULT_XTERMCOMMAND "konsole -e" +#define CONF_DEFAULT_FILEPERMISSIONS 0600 +#define CONF_DEFAULT_MAKEFILEBACKUP false +#define CONF_DEFAULT_AUTOSTART_DEEPL true +#define CONF_DEFAULT_AUTODEEPLOCK true +#define CONF_DEFAULT_KWALLETEMU true +#define CONF_DEFAULT_MINIMIZELOCK 2 /* deep-lock */ +#define CONF_DEFAULT_NEWENTRLOCKSTAT true /* locked */ +#define CONF_DEFAULT_WNDCLOSE true /* don't minimize to tray */ + +/** This is just because I'm too lazy to always + * type this loooong statement, when accessing + * configuration parameters. + */ +#define conf() Configuration::obj() + +#include + +#ifndef PWM_EMBEDDED +#include +#else +#define KDE_VERSION 310 +#define KDE_MAKE_VERSION( a,b,c ) (((a) << 16) | ((b) << 8) | (c)) +#endif + +// Set this to 1 to debug the 3.1 compatibility interface +#if 0 +# warning configuration.h KDE_VERSION debugging enabled! +# undef KDE_VERSION +# define KDE_VERSION KDE_MAKE_VERSION(3, 1, 0) +#endif + +#if !defined(KDE_VERSION) || !defined(KDE_MAKE_VERSION) +# error "KDE_VERSION or KDE_MAKE_VERSION not defined" +#endif +#if KDE_VERSION >= KDE_MAKE_VERSION(3, 2, 0) + +#ifndef PWM_EMBEDDED +//MOC_SKIP_BEGIN +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "pwmexception.h" + +class QLabel; +class QGroupBox; +class QPushButton; +class QResizeEvent; + +/** New global configuration file interface + * using KDE-3.2 KConfigSkeleton model. + */ +class Configuration +{ +public: + Configuration(); + ~Configuration(); + + static Configuration * obj() + { + PWM_ASSERT(_obj); + return _obj; + } + static void init() + { + PWM_ASSERT(!_obj); + _obj = new Configuration; + } + static void cleanup() + { delete_ifnot_null(_obj); } + + + /** Read the configuration from the file. + * Normally this function has not to be called manually. + */ + void readConfig() + { skel->readConfig(); } + /** Write the configuration to the file. + * Normally this function has not to be called manually. + */ + void writeConfig() + { skel->writeConfig(); } + /** reset the whole configuration to its defaults */ + void resetConfig() + { skel->setDefaults(); } + /** show the configuration window */ + bool showConfWnd(QWidget *parent); + +public: + /* functions for reading the configuration settings */ + /* GLOBAL */ + QString confGlobAutoStart() + { return cGlobAutoStart; } + QString confGlobBrowserCommand() + { return cGlobBrowserCommand; } + QString confGlobXtermCommand() + { return cGlobXtermCommand; } + QFont confGlobEntryFont() + { return cGlobEntryFont; } + int confGlobPwTimeout() + { return cGlobPwTimeout; } + int confGlobLockTimeout() + { return cGlobLockTimeout; } + int confGlobCompression() + { return cGlobCompression; } + int confGlobFilePermissions() + { return cGlobFilePermissions; } + int confGlobMinimizeLock() + { return cGlobMinimizeLock; } + bool confGlobUnlockOnOpen() + { return cGlobUnlockOnOpen; } + bool confGlobTray() + { return cGlobTray; } + bool confGlobMakeFileBackup() + { return cGlobMakeFileBackup; } + bool confGlobAutostartDeepLocked() + { return cGlobAutostartDeepLocked; } + bool confGlobAutoDeepLock() + { return cGlobAutoDeepLock; } + bool confGlobKwalletEmu() + { return cGlobKwalletEmu; } + bool confGlobNewEntrLockStat() + { return cGlobNewEntrLockStat; } + /* WND */ + QSize confWndMainWndSize() + { return cWndMainWndSize; } + int confWndMainViewStyle() + { return cWndMainViewStyle; } + bool confWndAutoMinimizeOnStart() + { return cWndAutoMinimizeOnStart; } + bool confWndClose() + { return cWndClose; } + +public: + /* functions for writing the configuration settings */ + /* GLOBAL */ + void confGlobAutoStart(const QString &e) + { cGlobAutoStart = e; } + void confGlobBrowserCommand(const QString &e) + { cGlobBrowserCommand = e; } + void confGlobXtermCommand(const QString &e) + { cGlobXtermCommand = e; } + void confGlobEntryFont(const QFont &e) + { cGlobEntryFont = e; } + void confGlobPwTimeout(int e) + { cGlobPwTimeout = e; } + void confGlobLockTimeout(int e) + { cGlobLockTimeout = e; } + void confGlobCompression(int e) + { cGlobCompression = e; } + void confGlobFilePermissions(int e) + { cGlobFilePermissions = e; } + void confGlobMinimizeLock(int e) + { cGlobMinimizeLock = e; } + void confGlobUnlockOnOpen(bool e) + { cGlobUnlockOnOpen = e; } + void confGlobTray(bool e) + { cGlobTray = e; } + void confGlobMakeFileBackup(bool e) + { cGlobMakeFileBackup = e; } + void confGlobAutostartDeepLocked(bool e) + { cGlobAutostartDeepLocked = e; } + void confGlobAutoDeepLock(bool e) + { cGlobAutoDeepLock = e; } + void confGlobKwalletEmu(bool e) + { cGlobKwalletEmu = e; } + void confGlobNewEntrLockStat(bool e) + { cGlobNewEntrLockStat = e; } + /* WND */ + void confWndMainWndSize(const QSize &e) + { cWndMainWndSize = e; } + void confWndMainViewStyle(int e) + { cWndMainViewStyle = e; } + void confWndAutoMinimizeOnStart(bool e) + { cWndAutoMinimizeOnStart = e; } + void confWndClose(bool e) + { cWndClose = e; } + +protected: + /** initialize the skeleton */ + void initSkel(); + +protected: + /** static instance of this class returned by obj() */ + static Configuration *_obj; + /** main configuration access skeleton */ + KConfigSkeleton *skel; + +protected: + /* configuration variables. All prefixed with 'c'. */ + /* GLOBAL */ + QString cGlobAutoStart; + QString cGlobBrowserCommand; + QString cGlobXtermCommand; + QFont cGlobEntryFont; + int cGlobPwTimeout; + int cGlobLockTimeout; + int cGlobCompression; + int cGlobFilePermissions; + int cGlobMinimizeLock; + bool cGlobUnlockOnOpen; + bool cGlobTray; + bool cGlobMakeFileBackup; + bool cGlobAutostartDeepLocked; + bool cGlobAutoDeepLock; + bool cGlobKwalletEmu; + bool cGlobNewEntrLockStat; + /* WND */ + QSize cWndMainWndSize; + int cWndMainViewStyle; + bool cWndAutoMinimizeOnStart; + bool cWndClose; +}; + +/* Big fat note: Internal stuff follows. + * ============ Don't use the following classes outside of + * the Configuration code, because it's unavailable + * when compiled under KDE-3.1 + */ + +/** class for input of octal numbers (for example file permissions) */ +class OctLineEdit : public QLineEdit +{ + Q_OBJECT + Q_OVERRIDE( QString text READ text WRITE setText ) + +public: + OctLineEdit(QWidget *parent, const char *name = 0); + ~OctLineEdit(); + + void setText(const QString &t); + QString text() const; + +protected: + void keyPressEvent(QKeyEvent *e); +}; + +/** global configuration page */ +class ConfPageGlobal : public QWidget +{ +public: + ConfPageGlobal(QWidget *parent = 0, const char *name = 0, WFlags f = 0); +}; + +/** configuration page for look&feel */ +class ConfPageLookNFeel : public QWidget +{ +public: + ConfPageLookNFeel(QWidget *parent = 0, const char *name = 0, WFlags f = 0); +}; + +/** file configuration page */ +class ConfPageFile : public QWidget +{ +public: + ConfPageFile(QWidget *parent = 0, const char *name = 0, WFlags f = 0); +}; + +/** timeouts configuration page */ +class ConfPageTimeouts : public QWidget +{ +public: + ConfPageTimeouts(QWidget *parent = 0, const char *name = 0, WFlags f = 0); +}; + +/** configuration page for external apps */ +class ConfPageExtApps : public QWidget +{ +public: + ConfPageExtApps(QWidget *parent = 0, const char *name = 0, WFlags f = 0); +}; + +/** autostart configuration page */ +class ConfPageAutostart : public QWidget +{ + Q_OBJECT +public: + ConfPageAutostart(QWidget *parent = 0, const char *name = 0, WFlags f = 0); + +protected slots: + void browseButton_slot(); + +protected: + QLineEdit *kcfg_autoStart; +}; + + +#ifndef PWM_EMBEDDED +//MOC_SKIP_END +#endif + + +#else // KDE_VERSION >= KDE_MAKE_VERSION(3, 2, 0) + /* XXX: This is the code for KDE-3.1 compatibility. */ +# include "configuration_31compat.h" +#endif // KDE_VERSION >= KDE_MAKE_VERSION(3, 2, 0) +#endif // CONFIGURATION_H diff --git a/pwmanager/pwmanager/configuration_31compat.cpp b/pwmanager/pwmanager/configuration_31compat.cpp new file mode 100644 index 0000000..ffd522c --- a/dev/null +++ b/pwmanager/pwmanager/configuration_31compat.cpp @@ -0,0 +1,365 @@ +/*************************************************************************** + * * + * 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 "configuration_31compat.h" +#include "configwndimpl.h" +#include "pwmexception.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +#ifdef PWM_EMBEDDED +#include +#include +#endif + +Configuration_31compat * Configuration_31compat::_obj (0); + +Configuration_31compat::Configuration_31compat() +{ +#ifndef PWM_EMBEDDED + conf = KApplication::kApplication()->config(); +#else + conf = KGlobal::config(); +#endif +} + +Configuration_31compat::~Configuration_31compat() +{ +} + +bool Configuration_31compat::showConfWnd(QWidget * /*parent*/) +{ + ConfigWndImpl cfgWnd; + cfgWnd.pwTimeoutSpinBox->setValue(confGlobPwTimeout()); + cfgWnd.lockTimeoutSpinBox->setValue(confGlobLockTimeout()); + cfgWnd.trayCheckBox->setChecked(confGlobTray()); + cfgWnd.autoStartLineEdit->setText(confGlobAutoStart()); + cfgWnd.openUnlockedCheckBox->setChecked(confGlobUnlockOnOpen()); + cfgWnd.currentEntryFont = confGlobEntryFont(); + cfgWnd.currEntrFont->setText(cfgWnd.currentEntryFont.family()); + cfgWnd.currEntrFont->setFont(cfgWnd.currentEntryFont); + cfgWnd.windowStyleComboBox->setCurrentItem(confWndMainViewStyle()); + cfgWnd.compressionComboBox->setCurrentItem(confGlobCompression()); + cfgWnd.autoMinimizeCheckBox->setChecked(confWndAutoMinimizeOnStart()); + cfgWnd.browserLineEdit->setText(confGlobBrowserCommand()); + cfgWnd.xtermLineEdit->setText(confGlobXtermCommand()); + cfgWnd.setFilePermissions(confGlobFilePermissions()); + cfgWnd.fileBackupCheckBox->setChecked(confGlobMakeFileBackup()); + cfgWnd.autostartDeeplockedCheckBox->setChecked(confGlobAutostartDeepLocked()); + cfgWnd.autoDeepLockCheckBox->setChecked(confGlobAutoDeepLock()); + cfgWnd.minimizeLockComboBox->setCurrentItem(confGlobMinimizeLock()); + cfgWnd.wndCloseCheckBox->setChecked(confWndClose()); +#ifdef CONFIG_KWALLETIF + cfgWnd.kwalletEmuCheckBox->setChecked(confGlobKwalletEmu()); +#else // CONFIG_KWALLETIF + cfgWnd.kwalletEmuCheckBox->setChecked(false); + cfgWnd.kwalletEmuCheckBox->setEnabled(false); +#endif // CONFIG_KWALLETIF + + if (cfgWnd.exec()) + return false; + + confGlobPwTimeout(cfgWnd.pwTimeoutSpinBox->value()); + confGlobLockTimeout(cfgWnd.lockTimeoutSpinBox->value()); + confGlobTray(cfgWnd.trayCheckBox->isChecked()); + confGlobAutoStart(cfgWnd.autoStartLineEdit->text()); + confGlobUnlockOnOpen(cfgWnd.openUnlockedCheckBox->isChecked()); + confGlobEntryFont(cfgWnd.currentEntryFont); + confWndMainViewStyle(cfgWnd.windowStyleComboBox->currentItem()); + confGlobCompression(cfgWnd.compressionComboBox->currentItem()); + confWndAutoMinimizeOnStart(cfgWnd.autoMinimizeCheckBox->isChecked()); + confGlobBrowserCommand(cfgWnd.browserLineEdit->text()); + confGlobXtermCommand(cfgWnd.xtermLineEdit->text()); + confGlobFilePermissions(cfgWnd.getFilePermissions()); + confGlobMakeFileBackup(cfgWnd.fileBackupCheckBox->isChecked()); + confGlobAutostartDeepLocked(cfgWnd. + autostartDeeplockedCheckBox->isChecked()); + confGlobAutoDeepLock(cfgWnd.autoDeepLockCheckBox->isChecked()); + confGlobMinimizeLock(cfgWnd.minimizeLockComboBox->currentItem()); + confWndClose(cfgWnd.wndCloseCheckBox->isChecked()); +#ifdef CONFIG_KWALLETIF + confGlobKwalletEmu(cfgWnd.kwalletEmuCheckBox->isChecked()); +#endif // CONFIG_KWALLETIF + return true; +} + +/******************************************************************* + * functions for reading the configuration settings + *******************************************************************/ + +QString Configuration_31compat::confGlobAutoStart() +{ + conf->setGroup("GLOBAL"); + return conf->readEntry("autoStart"); +} + +QString Configuration_31compat::confGlobBrowserCommand() +{ + conf->setGroup("GLOBAL"); + return conf->readEntry("browserCommand", CONF_DEFAULT_BROWSERCOMMAND); +} + +QString Configuration_31compat::confGlobXtermCommand() +{ + conf->setGroup("GLOBAL"); + return conf->readEntry("xtermCommand", CONF_DEFAULT_XTERMCOMMAND); +} + +QFont Configuration_31compat::confGlobEntryFont() +{ + conf->setGroup("GLOBAL"); +#ifndef PWM_EMBEDDED + return conf->readFontEntry("entryFont"); +#else + QFont f; + return conf->readFontEntry("entryFont", &f); +#endif +} + +int Configuration_31compat::confGlobPwTimeout() +{ + conf->setGroup("GLOBAL"); + return conf->readNumEntry("pwTimeout", CONF_DEFAULT_PWTIMEOUT); +} + +int Configuration_31compat::confGlobLockTimeout() +{ + conf->setGroup("GLOBAL"); + return conf->readNumEntry("lockTimeout", CONF_DEFAULT_LOCKTIMEOUT); +} + +int Configuration_31compat::confGlobCompression() +{ + conf->setGroup("GLOBAL"); + return conf->readNumEntry("compression", CONF_DEFAULT_COMPRESSION); +} + +int Configuration_31compat::confGlobFilePermissions() +{ + conf->setGroup("GLOBAL"); + return conf->readNumEntry("filePermissions", CONF_DEFAULT_FILEPERMISSIONS); +} + +int Configuration_31compat::confGlobMinimizeLock() +{ + conf->setGroup("GLOBAL"); + return conf->readNumEntry("minimizeLock", CONF_DEFAULT_MINIMIZELOCK); +} + +bool Configuration_31compat::confGlobUnlockOnOpen() +{ + conf->setGroup("GLOBAL"); + return conf->readBoolEntry("unlockOnOpen", CONF_DEFAULT_UNLOCKONOPEN); +} + +bool Configuration_31compat::confGlobTray() +{ + conf->setGroup("GLOBAL"); + return conf->readBoolEntry("tray", CONF_DEFAULT_TRAY); +} + +bool Configuration_31compat::confGlobMakeFileBackup() +{ + conf->setGroup("GLOBAL"); + return conf->readBoolEntry("makeFileBackup", CONF_DEFAULT_MAKEFILEBACKUP); +} + +bool Configuration_31compat::confGlobAutostartDeepLocked() +{ + conf->setGroup("GLOBAL"); + return conf->readBoolEntry("autostartDeeplocked", CONF_DEFAULT_AUTOSTART_DEEPL); +} + +bool Configuration_31compat::confGlobAutoDeepLock() +{ + conf->setGroup("GLOBAL"); + return conf->readBoolEntry("autoDeepLock", CONF_DEFAULT_AUTODEEPLOCK); +} + +bool Configuration_31compat::confGlobKwalletEmu() +{ + conf->setGroup("GLOBAL"); + return conf->readBoolEntry("kwalletEmu", CONF_DEFAULT_KWALLETEMU); +} + +bool Configuration_31compat::confGlobNewEntrLockStat() +{ + conf->setGroup("GLOBAL"); + return conf->readBoolEntry("newEntrLockStat", CONF_DEFAULT_NEWENTRLOCKSTAT); +} + +QSize Configuration_31compat::confWndMainWndSize() +{ + conf->setGroup("WND"); +#ifndef PWM_EMBEDDED + return conf->readSizeEntry("MainWndSize"); +#else + return conf->readSizeEntry("MainWndSize", 0); +#endif +} + +int Configuration_31compat::confWndMainViewStyle() +{ + conf->setGroup("WND"); + return conf->readNumEntry("MainViewStyle", CONF_DEFAULT_MAINVIEWSTYLE); +} + +bool Configuration_31compat::confWndAutoMinimizeOnStart() +{ + conf->setGroup("WND"); + return conf->readBoolEntry("autoMinimizeOnStart", CONF_DEFAULT_AUTOMINIMIZE); +} + +bool Configuration_31compat::confWndClose() +{ + conf->setGroup("WND"); + return conf->readBoolEntry("close", CONF_DEFAULT_WNDCLOSE); +} + +/******************************************************************* + * functions for writing the configuration settings + *******************************************************************/ + +void Configuration_31compat::confGlobAutoStart(const QString &e) +{ + conf->setGroup("GLOBAL"); + conf->writeEntry("autoStart", e); +} + +void Configuration_31compat::confGlobBrowserCommand(const QString &e) +{ + conf->setGroup("GLOBAL"); + conf->writeEntry("browserCommand", e); +} + +void Configuration_31compat::confGlobXtermCommand(const QString &e) +{ + conf->setGroup("GLOBAL"); + conf->writeEntry("xtermCommand", e); +} + +void Configuration_31compat::confGlobEntryFont(const QFont &e) +{ + conf->setGroup("GLOBAL"); + conf->writeEntry("entryFont", e); +} + +void Configuration_31compat::confGlobPwTimeout(int e) +{ + conf->setGroup("GLOBAL"); + conf->writeEntry("pwTimeout", e); +} + +void Configuration_31compat::confGlobLockTimeout(int e) +{ + conf->setGroup("GLOBAL"); + conf->writeEntry("lockTimeout", e); +} + +void Configuration_31compat::confGlobCompression(int e) +{ + conf->setGroup("GLOBAL"); + conf->writeEntry("compression", e); +} + +void Configuration_31compat::confGlobFilePermissions(int e) +{ + conf->setGroup("GLOBAL"); + conf->writeEntry("filePermissions", e); +} + +void Configuration_31compat::confGlobMinimizeLock(int e) +{ + conf->setGroup("GLOBAL"); + conf->writeEntry("minimizeLock", e); +} + +void Configuration_31compat::confGlobUnlockOnOpen(bool e) +{ + conf->setGroup("GLOBAL"); + conf->writeEntry("unlockOnOpen", e); +} + +void Configuration_31compat::confGlobTray(bool e) +{ + conf->setGroup("GLOBAL"); + conf->writeEntry("tray", e); +} + +void Configuration_31compat::confGlobMakeFileBackup(bool e) +{ + conf->setGroup("GLOBAL"); + conf->writeEntry("makeFileBackup", e); +} + +void Configuration_31compat::confGlobAutostartDeepLocked(bool e) +{ + conf->setGroup("GLOBAL"); + conf->writeEntry("autostartDeeplocked", e); +} + +void Configuration_31compat::confGlobAutoDeepLock(bool e) +{ + conf->setGroup("GLOBAL"); + conf->writeEntry("autoDeepLock", e); +} + +void Configuration_31compat::confGlobKwalletEmu(bool e) +{ + conf->setGroup("GLOBAL"); + conf->writeEntry("kwalletEmu", e); +} + +void Configuration_31compat::confGlobNewEntrLockStat(bool e) +{ + conf->setGroup("GLOBAL"); + conf->writeEntry("newEntrLockStat", e); +} + +void Configuration_31compat::confWndMainWndSize(const QSize &e) +{ + conf->setGroup("WND"); + conf->writeEntry("MainWndSize", e); +} + +void Configuration_31compat::confWndMainViewStyle(int e) +{ + conf->setGroup("WND"); + conf->writeEntry("MainViewStyle", e); +} + +void Configuration_31compat::confWndAutoMinimizeOnStart(bool e) +{ + conf->setGroup("WND"); + conf->writeEntry("autoMinimizeOnStart", e); +} + +void Configuration_31compat::confWndClose(bool e) +{ + conf->setGroup("WND"); + conf->writeEntry("close", e); +} diff --git a/pwmanager/pwmanager/configuration_31compat.h b/pwmanager/pwmanager/configuration_31compat.h new file mode 100644 index 0000000..8ad6e09 --- a/dev/null +++ b/pwmanager/pwmanager/configuration_31compat.h @@ -0,0 +1,146 @@ +/*************************************************************************** + * * + * 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 CONFIGURATION_31COMPAT_H +#define CONFIGURATION_31COMPAT_H + +#include "pwmexception.h" + +#include +#include +#include + +#ifdef PWM_EMBEDDED +#include +#endif + +class KConfig; + +/** This class is the compatibility layer for + * running the new KDE-3.2 Configuration interface on KDE-3.1. + * We have to keep this class in sync with the real configuration + * interface. + */ +class Configuration_31compat +{ +public: + Configuration_31compat(); + ~Configuration_31compat(); + + static Configuration_31compat * obj() + { + PWM_ASSERT(_obj); + return _obj; + } + static void init() + { + PWM_ASSERT(!_obj); + _obj = new Configuration_31compat; + } + static void cleanup() + { delete_ifnot_null(_obj); } + + + /** Read the configuration from the file. + * Normally this function has not to be called manually. + * + * This function is a NOP in KDE-3.1 compatibility layer. + */ + void readConfig() + { } + /** Write the configuration to the file. + * Normally this function has not to be called manually. + * + * This function is a NOP in KDE-3.1 compatibility layer. + */ + void writeConfig() + { } + /** reset the whole configuration to its defaults. + * + * This function is a NOP in KDE-3.1 compatibility layer. + * It should not be, but it is. :) + */ + void resetConfig() + { } + /** show the configuration window */ + bool showConfWnd(QWidget *parent); + +public: + /* functions for reading the configuration settings */ + /* GLOBAL */ + QString confGlobAutoStart(); + QString confGlobBrowserCommand(); + QString confGlobXtermCommand(); + QFont confGlobEntryFont(); + int confGlobPwTimeout(); + int confGlobLockTimeout(); + int confGlobCompression(); + int confGlobFilePermissions(); + int confGlobMinimizeLock(); + bool confGlobUnlockOnOpen(); + bool confGlobTray(); + bool confGlobMakeFileBackup(); + bool confGlobAutostartDeepLocked(); + bool confGlobAutoDeepLock(); + bool confGlobKwalletEmu(); + bool confGlobNewEntrLockStat(); + /* WND */ + QSize confWndMainWndSize(); + int confWndMainViewStyle(); + bool confWndAutoMinimizeOnStart(); + bool confWndClose(); + +public: + /* functions for writing the configuration settings */ + /* GLOBAL */ + void confGlobAutoStart(const QString &e); + void confGlobBrowserCommand(const QString &e); + void confGlobXtermCommand(const QString &e); + void confGlobEntryFont(const QFont &e); + void confGlobPwTimeout(int e); + void confGlobLockTimeout(int e); + void confGlobCompression(int e); + void confGlobFilePermissions(int e); + void confGlobMinimizeLock(int e); + void confGlobUnlockOnOpen(bool e); + void confGlobTray(bool e); + void confGlobMakeFileBackup(bool e); + void confGlobAutostartDeepLocked(bool e); + void confGlobAutoDeepLock(bool e); + void confGlobKwalletEmu(bool e); + void confGlobNewEntrLockStat(bool e); + /* WND */ + void confWndMainWndSize(const QSize &e); + void confWndMainViewStyle(int e); + void confWndAutoMinimizeOnStart(bool e); + void confWndClose(bool e); + +protected: + /** static instance of this class returned by obj() */ + static Configuration_31compat *_obj; + /** configuration object */ + KConfig *conf; +}; + +#ifdef Configuration +# error "Configuration already defined!" +#endif +#define Configuration Configuration_31compat + +#endif diff --git a/pwmanager/pwmanager/configwnd.cpp b/pwmanager/pwmanager/configwnd.cpp new file mode 100644 index 0000000..230ca1b --- a/dev/null +++ b/pwmanager/pwmanager/configwnd.cpp @@ -0,0 +1,264 @@ +/**************************************************************************** +** Form implementation generated from reading ui file 'configwnd.ui' +** +** Created: Tue Sep 14 15:20:58 2004 +** by: The User Interface Compiler ($Id$) +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ + +#include "configwnd.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Constructs a configWnd as a child of 'parent', with the + * name 'name' and widget flags set to 'f'. + * + * The dialog will by default be modeless, unless you set 'modal' to + * TRUE to construct a modal dialog. + */ +configWnd::configWnd( QWidget* parent, const char* name, bool modal, WFlags fl ) + : QDialog( parent, name, modal, fl ) +{ + if ( !name ) + setName( "configWnd" ); + + okButton = new QPushButton( this, "okButton" ); + okButton->setGeometry( QRect( 10, 280, 107, 27 ) ); + + cancelButton = new QPushButton( this, "cancelButton" ); + cancelButton->setGeometry( QRect( 370, 280, 107, 27 ) ); + + tabWidget2 = new QTabWidget( this, "tabWidget2" ); + tabWidget2->setGeometry( QRect( 10, 10, 470, 260 ) ); + + tab = new QWidget( tabWidget2, "tab" ); + + windowStyleComboBox = new QComboBox( FALSE, tab, "windowStyleComboBox" ); + windowStyleComboBox->setGeometry( QRect( 220, 180, 210, 28 ) ); + + textLabel1_5 = new QLabel( tab, "textLabel1_5" ); + textLabel1_5->setGeometry( QRect( 30, 180, 180, 20 ) ); + textLabel1_5->setAlignment( int( QLabel::AlignVCenter | QLabel::AlignRight ) ); + + textLabel1_4 = new QLabel( tab, "textLabel1_4" ); + textLabel1_4->setGeometry( QRect( 30, 40, 400, 20 ) ); + + selEntrFontButton = new QPushButton( tab, "selEntrFontButton" ); + selEntrFontButton->setGeometry( QRect( 30, 90, 160, 27 ) ); + + currEntrFont = new QLabel( tab, "currEntrFont" ); + currEntrFont->setGeometry( QRect( 30, 70, 230, 20 ) ); + tabWidget2->insertTab( tab, QString("") ); + + TabPage = new QWidget( tabWidget2, "TabPage" ); + + compressionComboBox = new QComboBox( FALSE, TabPage, "compressionComboBox" ); + compressionComboBox->setGeometry( QRect( 290, 50, 150, 28 ) ); + + textLabel1_6 = new QLabel( TabPage, "textLabel1_6" ); + textLabel1_6->setGeometry( QRect( 10, 50, 270, 20 ) ); + textLabel1_6->setAlignment( int( QLabel::AlignVCenter | QLabel::AlignRight ) ); + + textLabel1_8 = new QLabel( TabPage, "textLabel1_8" ); + textLabel1_8->setGeometry( QRect( 10, 90, 270, 20 ) ); + textLabel1_8->setAlignment( int( QLabel::AlignVCenter | QLabel::AlignRight ) ); + + permissionLineEdit = new QLineEdit( TabPage, "permissionLineEdit" ); + permissionLineEdit->setGeometry( QRect( 290, 90, 142, 27 ) ); + permissionLineEdit->setMaxLength( 3 ); + + fileBackupCheckBox = new QCheckBox( TabPage, "fileBackupCheckBox" ); + fileBackupCheckBox->setGeometry( QRect( 80, 140, 360, 23 ) ); + tabWidget2->insertTab( TabPage, QString("") ); + + tab_2 = new QWidget( tabWidget2, "tab_2" ); + + pwTimeoutSpinBox = new QSpinBox( tab_2, "pwTimeoutSpinBox" ); + pwTimeoutSpinBox->setGeometry( QRect( 390, 50, 55, 23 ) ); + + textLabel1 = new QLabel( tab_2, "textLabel1" ); + textLabel1->setGeometry( QRect( 10, 20, 370, 80 ) ); + textLabel1->setAlignment( int( QLabel::WordBreak | QLabel::AlignVCenter ) ); + + textLabel1_7 = new QLabel( tab_2, "textLabel1_7" ); + textLabel1_7->setGeometry( QRect( 10, 110, 370, 80 ) ); + textLabel1_7->setAlignment( int( QLabel::WordBreak | QLabel::AlignVCenter ) ); + + lockTimeoutSpinBox = new QSpinBox( tab_2, "lockTimeoutSpinBox" ); + lockTimeoutSpinBox->setGeometry( QRect( 390, 140, 55, 23 ) ); + + autoDeepLockCheckBox = new QCheckBox( tab_2, "autoDeepLockCheckBox" ); + autoDeepLockCheckBox->setGeometry( QRect( 60, 180, 380, 25 ) ); + tabWidget2->insertTab( tab_2, QString("") ); + + tab_3 = new QWidget( tabWidget2, "tab_3" ); + + textLabel1_3 = new QLabel( tab_3, "textLabel1_3" ); + textLabel1_3->setGeometry( QRect( 30, 30, 400, 20 ) ); + + autoStartLineEdit = new QLineEdit( tab_3, "autoStartLineEdit" ); + autoStartLineEdit->setGeometry( QRect( 30, 50, 360, 20 ) ); + + browseAutoStButton = new QPushButton( tab_3, "browseAutoStButton" ); + browseAutoStButton->setGeometry( QRect( 400, 50, 30, 20 ) ); + + autostartDeeplockedCheckBox = new QCheckBox( tab_3, "autostartDeeplockedCheckBox" ); + autostartDeeplockedCheckBox->setGeometry( QRect( 40, 80, 390, 25 ) ); + tabWidget2->insertTab( tab_3, QString("") ); + + tab_4 = new QWidget( tabWidget2, "tab_4" ); + + textLabel2 = new QLabel( tab_4, "textLabel2" ); + textLabel2->setGeometry( QRect( 20, 40, 280, 20 ) ); + textLabel2->setAlignment( int( QLabel::AlignVCenter | QLabel::AlignRight ) ); + + browserLineEdit = new QLineEdit( tab_4, "browserLineEdit" ); + browserLineEdit->setGeometry( QRect( 310, 40, 130, 27 ) ); + + xtermLineEdit = new QLineEdit( tab_4, "xtermLineEdit" ); + xtermLineEdit->setGeometry( QRect( 310, 100, 130, 27 ) ); + + textLabel3 = new QLabel( tab_4, "textLabel3" ); + textLabel3->setGeometry( QRect( 20, 100, 280, 20 ) ); + textLabel3->setAlignment( int( QLabel::AlignVCenter | QLabel::AlignRight ) ); + tabWidget2->insertTab( tab_4, QString("") ); + + tab_5 = new QWidget( tabWidget2, "tab_5" ); + + trayCheckBox = new QCheckBox( tab_5, "trayCheckBox" ); + trayCheckBox->setGeometry( QRect( 30, 30, 400, 20 ) ); + + openUnlockedCheckBox = new QCheckBox( tab_5, "openUnlockedCheckBox" ); + openUnlockedCheckBox->setGeometry( QRect( 30, 80, 400, 20 ) ); + + autoMinimizeCheckBox = new QCheckBox( tab_5, "autoMinimizeCheckBox" ); + autoMinimizeCheckBox->setEnabled( FALSE ); + autoMinimizeCheckBox->setGeometry( QRect( 50, 50, 380, 25 ) ); + + minimizeLockComboBox = new QComboBox( FALSE, tab_5, "minimizeLockComboBox" ); + minimizeLockComboBox->setGeometry( QRect( 310, 170, 120, 27 ) ); + + textLabel1_9 = new QLabel( tab_5, "textLabel1_9" ); + textLabel1_9->setGeometry( QRect( 30, 180, 270, 20 ) ); + textLabel1_9->setAlignment( int( QLabel::AlignVCenter | QLabel::AlignRight ) ); + + kwalletEmuCheckBox = new QCheckBox( tab_5, "kwalletEmuCheckBox" ); + kwalletEmuCheckBox->setGeometry( QRect( 30, 110, 400, 25 ) ); + + wndCloseCheckBox = new QCheckBox( tab_5, "wndCloseCheckBox" ); + wndCloseCheckBox->setGeometry( QRect( 30, 140, 430, 24 ) ); + tabWidget2->insertTab( tab_5, QString("") ); + languageChange(); + resize( QSize(490, 318).expandedTo(minimumSizeHint()) ); + clearWState( WState_Polished ); + + // signals and slots connections + connect( okButton, SIGNAL( clicked() ), this, SLOT( okButton_slot() ) ); + connect( cancelButton, SIGNAL( clicked() ), this, SLOT( cancelButton_slot() ) ); + connect( browseAutoStButton, SIGNAL( clicked() ), this, SLOT( browseAutoStButton_slot() ) ); + connect( selEntrFontButton, SIGNAL( clicked() ), this, SLOT( selEntrFontButton_slot() ) ); + connect( trayCheckBox, SIGNAL( toggled(bool) ), autoMinimizeCheckBox, SLOT( setEnabled(bool) ) ); + + // tab order + setTabOrder( pwTimeoutSpinBox, trayCheckBox ); + setTabOrder( trayCheckBox, okButton ); + setTabOrder( okButton, cancelButton ); +} + +/* + * Destroys the object and frees any allocated resources + */ +configWnd::~configWnd() +{ + // no need to delete child widgets, Qt does it all for us +} + +/* + * Sets the strings of the subwidgets using the current + * language. + */ +void configWnd::languageChange() +{ + setCaption( tr( "PwManager Configuration" ) ); + okButton->setText( tr( "&OK" ) ); + //US ENH okButton->setAccel( QKeySequence( tr( "Alt+O" ) ) ); + cancelButton->setText( tr( "&Cancel" ) ); + //US ENH cancelButton->setAccel( QKeySequence( tr( "Alt+C" ) ) ); + windowStyleComboBox->clear(); + windowStyleComboBox->insertItem( tr( "Category on top" ) ); + windowStyleComboBox->insertItem( tr( "Category-list left" ) ); + textLabel1_5->setText( tr( "Window-style:" ) ); + textLabel1_4->setText( tr( "Font for the password entries:" ) ); + selEntrFontButton->setText( tr( "select Font" ) ); + currEntrFont->setText( QString::null ); + tabWidget2->changeTab( tab, tr( "Look && feel" ) ); + compressionComboBox->clear(); + compressionComboBox->insertItem( tr( "none" ) ); + compressionComboBox->insertItem( tr( "gzip" ) ); + compressionComboBox->insertItem( tr( "bzip2" ) ); + textLabel1_6->setText( tr( "*.pwm file compression:" ) ); + textLabel1_8->setText( tr( "permissions:" ) ); + fileBackupCheckBox->setText( tr( "Make file backup before saving" ) ); + tabWidget2->changeTab( TabPage, tr( "File" ) ); + textLabel1->setText( tr( "Password timeout (timeout to hold password in memory, so you don't have to re-enter it, if you already have entered it) [set to 0 to disable]:" ) ); + textLabel1_7->setText( tr( "Auto-lock timeout (auto lock document after this amount of seconds) [set to 0 to disable]:" ) ); + autoDeepLockCheckBox->setText( tr( "deep-lock on autolock" ) ); + tabWidget2->changeTab( tab_2, tr( "Timeout" ) ); + textLabel1_3->setText( tr( "Open this file automatically on startup:" ) ); + browseAutoStButton->setText( tr( "..." ) ); + autostartDeeplockedCheckBox->setText( tr( "open deeplocked" ) ); + tabWidget2->changeTab( tab_3, tr( "Autostart" ) ); + textLabel2->setText( tr( "Favourite browser:" ) ); + textLabel3->setText( tr( "Favourite X-terminal:" ) ); + tabWidget2->changeTab( tab_4, tr( "External apps" ) ); + trayCheckBox->setText( tr( "Show icon in system-tray" ) ); + openUnlockedCheckBox->setText( tr( "Open document with passwords unlocked" ) ); + autoMinimizeCheckBox->setText( tr( "auto-minimize to tray on startup" ) ); + minimizeLockComboBox->clear(); + minimizeLockComboBox->insertItem( tr( "don't lock" ) ); + minimizeLockComboBox->insertItem( tr( "normal lock" ) ); + minimizeLockComboBox->insertItem( tr( "deep-lock" ) ); + textLabel1_9->setText( tr( "auto-lock on minimize:" ) ); + kwalletEmuCheckBox->setText( tr( "KWallet emulation" ) ); + wndCloseCheckBox->setText( tr( "Do not minimize windows into tray. (Close the window)" ) ); + tabWidget2->changeTab( tab_5, tr( "Miscellaneous" ) ); +} + +void configWnd::okButton_slot() +{ + qWarning( "configWnd::okButton_slot(): Not implemented yet" ); +} + +void configWnd::cancelButton_slot() +{ + qWarning( "configWnd::cancelButton_slot(): Not implemented yet" ); +} + +void configWnd::browseBgButton_slot() +{ + qWarning( "configWnd::browseBgButton_slot(): Not implemented yet" ); +} + +void configWnd::browseAutoStButton_slot() +{ + qWarning( "configWnd::browseAutoStButton_slot(): Not implemented yet" ); +} + +void configWnd::selEntrFontButton_slot() +{ + qWarning( "configWnd::selEntrFontButton_slot(): Not implemented yet" ); +} + diff --git a/pwmanager/pwmanager/configwnd.h b/pwmanager/pwmanager/configwnd.h new file mode 100644 index 0000000..608a38b --- a/dev/null +++ b/pwmanager/pwmanager/configwnd.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** Form interface generated from reading ui file 'configwnd.ui' +** +** Created: Tue Sep 14 15:20:50 2004 +** by: The User Interface Compiler ($Id$) +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ + +#ifndef CONFIGWND_H +#define CONFIGWND_H + +#include +#include + +class QVBoxLayout; +class QHBoxLayout; +class QGridLayout; +class QSpacerItem; +class QPushButton; +class QTabWidget; +class QWidget; +class QComboBox; +class QLabel; +class QLineEdit; +class QCheckBox; +class QSpinBox; + +class configWnd : public QDialog +{ + Q_OBJECT + +public: + configWnd( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~configWnd(); + + QPushButton* okButton; + QPushButton* cancelButton; + QTabWidget* tabWidget2; + QWidget* tab; + QComboBox* windowStyleComboBox; + QLabel* textLabel1_5; + QLabel* textLabel1_4; + QPushButton* selEntrFontButton; + QLabel* currEntrFont; + QWidget* TabPage; + QComboBox* compressionComboBox; + QLabel* textLabel1_6; + QLabel* textLabel1_8; + QLineEdit* permissionLineEdit; + QCheckBox* fileBackupCheckBox; + QWidget* tab_2; + QSpinBox* pwTimeoutSpinBox; + QLabel* textLabel1; + QLabel* textLabel1_7; + QSpinBox* lockTimeoutSpinBox; + QCheckBox* autoDeepLockCheckBox; + QWidget* tab_3; + QLabel* textLabel1_3; + QLineEdit* autoStartLineEdit; + QPushButton* browseAutoStButton; + QCheckBox* autostartDeeplockedCheckBox; + QWidget* tab_4; + QLabel* textLabel2; + QLineEdit* browserLineEdit; + QLineEdit* xtermLineEdit; + QLabel* textLabel3; + QWidget* tab_5; + QCheckBox* trayCheckBox; + QCheckBox* openUnlockedCheckBox; + QCheckBox* autoMinimizeCheckBox; + QComboBox* minimizeLockComboBox; + QLabel* textLabel1_9; + QCheckBox* kwalletEmuCheckBox; + QCheckBox* wndCloseCheckBox; + +public slots: + virtual void okButton_slot(); + virtual void cancelButton_slot(); + virtual void browseBgButton_slot(); + virtual void browseAutoStButton_slot(); + virtual void selEntrFontButton_slot(); + +protected: + +protected slots: + virtual void languageChange(); + +}; + +#endif // CONFIGWND_H diff --git a/pwmanager/pwmanager/configwnd.ui b/pwmanager/pwmanager/configwnd.ui new file mode 100644 index 0000000..9e8d520 --- a/dev/null +++ b/pwmanager/pwmanager/configwnd.ui @@ -0,0 +1,687 @@ + +configWnd + + + configWnd + + + + 0 + 0 + 490 + 318 + + + + PwManager Configuration + + + + okButton + + + + 10 + 280 + 107 + 27 + + + + &OK + + + Alt+O + + + + + cancelButton + + + + 370 + 280 + 107 + 27 + + + + &Cancel + + + Alt+C + + + + + tabWidget2 + + + + 10 + 10 + 470 + 260 + + + + + tab + + + Look && feel + + + + + Category on top + + + + + Category-list left + + + + windowStyleComboBox + + + + 220 + 180 + 210 + 28 + + + + + + textLabel1_5 + + + + 30 + 180 + 180 + 20 + + + + Window-style: + + + AlignVCenter|AlignRight + + + + + textLabel1_4 + + + + 30 + 40 + 400 + 20 + + + + Font for the password entries: + + + + + selEntrFontButton + + + + 30 + 90 + 160 + 27 + + + + select Font + + + + + currEntrFont + + + + 30 + 70 + 230 + 20 + + + + + + + + + + TabPage + + + File + + + + + none + + + + + gzip + + + + + bzip2 + + + + compressionComboBox + + + + 290 + 50 + 150 + 28 + + + + + + textLabel1_6 + + + + 10 + 50 + 270 + 20 + + + + *.pwm file compression: + + + AlignVCenter|AlignRight + + + + + textLabel1_8 + + + + 10 + 90 + 270 + 20 + + + + permissions: + + + AlignVCenter|AlignRight + + + + + permissionLineEdit + + + + 290 + 90 + 142 + 27 + + + + 3 + + + + + fileBackupCheckBox + + + + 80 + 140 + 360 + 23 + + + + Make file backup before saving + + + + + + tab + + + Timeout + + + + pwTimeoutSpinBox + + + + 390 + 50 + 55 + 23 + + + + + + textLabel1 + + + + 10 + 20 + 370 + 80 + + + + Password timeout (timeout to hold password in memory, so you don't have to re-enter it, if you already have entered it) [set to 0 to disable]: + + + WordBreak|AlignVCenter + + + + + textLabel1_7 + + + + 10 + 110 + 370 + 80 + + + + Auto-lock timeout (auto lock document after this amount of seconds) [set to 0 to disable]: + + + WordBreak|AlignVCenter + + + + + lockTimeoutSpinBox + + + + 390 + 140 + 55 + 23 + + + + + + autoDeepLockCheckBox + + + + 60 + 180 + 380 + 25 + + + + deep-lock on autolock + + + + + + tab + + + Autostart + + + + textLabel1_3 + + + + 30 + 30 + 400 + 20 + + + + Open this file automatically on startup: + + + + + autoStartLineEdit + + + + 30 + 50 + 360 + 20 + + + + + + browseAutoStButton + + + + 400 + 50 + 30 + 20 + + + + ... + + + + + autostartDeeplockedCheckBox + + + + 40 + 80 + 390 + 25 + + + + open deeplocked + + + + + + tab + + + External apps + + + + textLabel2 + + + + 20 + 40 + 280 + 20 + + + + Favourite browser: + + + AlignVCenter|AlignRight + + + + + browserLineEdit + + + + 310 + 40 + 130 + 27 + + + + + + xtermLineEdit + + + + 310 + 100 + 130 + 27 + + + + + + textLabel3 + + + + 20 + 100 + 280 + 20 + + + + Favourite X-terminal: + + + AlignVCenter|AlignRight + + + + + + tab + + + Miscellaneous + + + + trayCheckBox + + + + 30 + 30 + 400 + 20 + + + + Show icon in system-tray + + + + + openUnlockedCheckBox + + + + 30 + 80 + 400 + 20 + + + + Open document with passwords unlocked + + + + + autoMinimizeCheckBox + + + false + + + + 50 + 50 + 380 + 25 + + + + auto-minimize to tray on startup + + + + + + don't lock + + + + + normal lock + + + + + deep-lock + + + + minimizeLockComboBox + + + + 310 + 170 + 120 + 27 + + + + + + textLabel1_9 + + + + 30 + 180 + 270 + 20 + + + + auto-lock on minimize: + + + AlignVCenter|AlignRight + + + + + kwalletEmuCheckBox + + + + 30 + 110 + 400 + 25 + + + + KWallet emulation + + + + + wndCloseCheckBox + + + + 30 + 140 + 430 + 24 + + + + Do not minimize windows into tray. (Close the window) + + + + + + + + okButton + clicked() + configWnd + okButton_slot() + + + cancelButton + clicked() + configWnd + cancelButton_slot() + + + browseAutoStButton + clicked() + configWnd + browseAutoStButton_slot() + + + selEntrFontButton + clicked() + configWnd + selEntrFontButton_slot() + + + trayCheckBox + toggled(bool) + autoMinimizeCheckBox + setEnabled(bool) + + + + pwTimeoutSpinBox + trayCheckBox + okButton + cancelButton + + + okButton_slot() + cancelButton_slot() + browseBgButton_slot() + browseAutoStButton_slot() + selEntrFontButton_slot() + + + diff --git a/pwmanager/pwmanager/configwndimpl.cpp b/pwmanager/pwmanager/configwndimpl.cpp new file mode 100644 index 0000000..5aa38d4 --- a/dev/null +++ b/pwmanager/pwmanager/configwndimpl.cpp @@ -0,0 +1,126 @@ +/*************************************************************************** + * * + * copyright (C) 2003 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 "configwndimpl.h" +#include "pwm.h" +#include "configuration.h" + +#include +#include + +#include +#include +#include + +#include +#include + +#ifdef PWM_EMBEDDED +#include +#endif + +ConfigWndImpl::ConfigWndImpl() +{ +} + +ConfigWndImpl::~ConfigWndImpl() +{ +} + +void ConfigWndImpl::okButton_slot() +{ + done(0); +} + +void ConfigWndImpl::cancelButton_slot() +{ + done(1); +} + +void ConfigWndImpl::browseAutoStButton_slot() +{ + QString path(KFileDialog::getOpenFileName(QString::null, + i18n("*.pwm|PwM Password file\n" + "*|All files"), this)); + if (path != QString::null) + autoStartLineEdit->setText(path); +} + +void ConfigWndImpl::selEntrFontButton_slot() +{ + bool ok; +#ifndef PWM_EMBEDDED + QFont fnt = QFontDialog::getFont(&ok, currentEntryFont, this); +#else + QFont fnt = KFontDialog::getFont(currentEntryFont, ok); +#endif + if (!ok) + return; + currEntrFont->setFont(fnt); + currEntrFont->setText(fnt.family()); + currentEntryFont = fnt; +} + +int ConfigWndImpl::getFilePermissions() +{ + char octalDigits[] = "01234567"; + bool isOctal; + QString permString(permissionLineEdit->text()); + int i, j, length = permString.length(); + if (length != 3) { + printWarn("Wrong permission string length! Please enter " + "the string like the following example: 600"); + return CONF_DEFAULT_FILEPERMISSIONS; + } + for (i = 0; i < length; ++i) { + isOctal = false; + for (j = 0; j < 8; ++j) { + if (permString.at(i) == octalDigits[j]) { + isOctal = true; + break; + } + } + if (!isOctal) { + printWarn("CONFIG: File-permissions: This is " + "not an octal number "); + return CONF_DEFAULT_FILEPERMISSIONS; + } + } + + int ret = strtol(permString.latin1(), 0, 8); + if (ret == 0) { + /* either an error occured, or the user did really type 000 */ + printWarn("CONFIG: File-permissions: Hm, either conversion error, " + "or you really typed 000. 8-)"); + return CONF_DEFAULT_FILEPERMISSIONS; + } + return ret; +} + +void ConfigWndImpl::setFilePermissions(int perm) +{ + char tmpBuf[30]; + sprintf(tmpBuf, "%o", perm); + permissionLineEdit->setText(tmpBuf); +} + +#ifndef PWM_EMBEDDED +#include "configwndimpl.moc" +#endif diff --git a/pwmanager/pwmanager/configwndimpl.h b/pwmanager/pwmanager/configwndimpl.h new file mode 100644 index 0000000..f67f459 --- a/dev/null +++ b/pwmanager/pwmanager/configwndimpl.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * * + * copyright (C) 2003 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 CONFIGWNDIMPL_H +#define CONFIGWNDIMPL_H + +#include + +#include "configwnd.h" + +/** "add" Window */ +class ConfigWndImpl : public configWnd +{ + Q_OBJECT +public: + ConfigWndImpl(); + ~ConfigWndImpl(); + + /** currently selected entry-font */ + QFont currentEntryFont; + + /** gets the content of permissionLineEdit */ + int getFilePermissions(); + /** sets the content of permissionLineEdit */ + void setFilePermissions(int perm); + +public slots: + /** OK button pressed */ + void okButton_slot(); + /** cancel button pressed */ + void cancelButton_slot(); + /** browse autostart file button pressed */ + void browseAutoStButton_slot(); + /** select entry-font button pressed */ + void selEntrFontButton_slot(); +}; + +#endif diff --git a/pwmanager/pwmanager/findwnd.cpp b/pwmanager/pwmanager/findwnd.cpp new file mode 100644 index 0000000..7767665 --- a/dev/null +++ b/pwmanager/pwmanager/findwnd.cpp @@ -0,0 +1,153 @@ +/**************************************************************************** +** Form implementation generated from reading ui file 'findwnd.ui' +** +** Created: Tue Sep 14 15:25:08 2004 +** by: The User Interface Compiler ($Id$) +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ + +#include "findwnd.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Constructs a findWnd as a child of 'parent', with the + * name 'name' and widget flags set to 'f'. + * + * The dialog will by default be modeless, unless you set 'modal' to + * TRUE to construct a modal dialog. + */ +findWnd::findWnd( QWidget* parent, const char* name, bool modal, WFlags fl ) + : QDialog( parent, name, modal, fl ) +{ + if ( !name ) + setName( "findWnd" ); + + textLabel1 = new QLabel( this, "textLabel1" ); + textLabel1->setGeometry( QRect( 20, 20, 340, 20 ) ); + textLabel1->setFrameShape( QLabel::NoFrame ); + textLabel1->setFrameShadow( QLabel::Plain ); + + findLineEdit = new QLineEdit( this, "findLineEdit" ); + findLineEdit->setGeometry( QRect( 20, 40, 340, 20 ) ); + + findButton = new QPushButton( this, "findButton" ); + findButton->setGeometry( QRect( 20, 230, 107, 27 ) ); + + closeButton = new QPushButton( this, "closeButton" ); + closeButton->setGeometry( QRect( 250, 230, 107, 27 ) ); + + exactCheckBox = new QCheckBox( this, "exactCheckBox" ); + exactCheckBox->setGeometry( QRect( 20, 200, 340, 20 ) ); + + caseSensCheckBox = new QCheckBox( this, "caseSensCheckBox" ); + caseSensCheckBox->setGeometry( QRect( 20, 180, 340, 20 ) ); + + buttonGroup1 = new QButtonGroup( this, "buttonGroup1" ); + buttonGroup1->setGeometry( QRect( 20, 70, 340, 90 ) ); + + descRadioButton = new QRadioButton( buttonGroup1, "descRadioButton" ); + descRadioButton->setGeometry( QRect( 30, 20, 150, 20 ) ); + descRadioButton->setChecked( TRUE ); + + pwRadioButton = new QRadioButton( buttonGroup1, "pwRadioButton" ); + pwRadioButton->setGeometry( QRect( 180, 20, 150, 20 ) ); + + commentRadioButton = new QRadioButton( buttonGroup1, "commentRadioButton" ); + commentRadioButton->setGeometry( QRect( 180, 40, 150, 20 ) ); + + nameRadioButton = new QRadioButton( buttonGroup1, "nameRadioButton" ); + nameRadioButton->setGeometry( QRect( 30, 40, 150, 20 ) ); + + urlRadioButton = new QRadioButton( buttonGroup1, "urlRadioButton" ); + urlRadioButton->setGeometry( QRect( 30, 60, 150, 20 ) ); + + launcherRadioButton = new QRadioButton( buttonGroup1, "launcherRadioButton" ); + launcherRadioButton->setGeometry( QRect( 180, 60, 150, 20 ) ); + languageChange(); + resize( QSize(381, 269).expandedTo(minimumSizeHint()) ); + clearWState( WState_Polished ); + + // signals and slots connections + connect( findButton, SIGNAL( clicked() ), this, SLOT( findButton_slot() ) ); + connect( closeButton, SIGNAL( clicked() ), this, SLOT( closeButton_slot() ) ); + connect( descRadioButton, SIGNAL( stateChanged(int) ), this, SLOT( selectionChanged_slot() ) ); + connect( nameRadioButton, SIGNAL( stateChanged(int) ), this, SLOT( selectionChanged_slot() ) ); + connect( pwRadioButton, SIGNAL( stateChanged(int) ), this, SLOT( selectionChanged_slot() ) ); + connect( commentRadioButton, SIGNAL( stateChanged(int) ), this, SLOT( selectionChanged_slot() ) ); + connect( findLineEdit, SIGNAL( textChanged(const QString&) ), this, SLOT( selectionChanged_slot() ) ); + connect( caseSensCheckBox, SIGNAL( stateChanged(int) ), this, SLOT( selectionChanged_slot() ) ); + connect( exactCheckBox, SIGNAL( stateChanged(int) ), this, SLOT( selectionChanged_slot() ) ); + + // tab order + setTabOrder( findLineEdit, descRadioButton ); + setTabOrder( descRadioButton, caseSensCheckBox ); + setTabOrder( caseSensCheckBox, exactCheckBox ); + setTabOrder( exactCheckBox, findButton ); + setTabOrder( findButton, closeButton ); + setTabOrder( closeButton, nameRadioButton ); + setTabOrder( nameRadioButton, pwRadioButton ); + setTabOrder( pwRadioButton, commentRadioButton ); +} + +/* + * Destroys the object and frees any allocated resources + */ +findWnd::~findWnd() +{ + // no need to delete child widgets, Qt does it all for us +} + +/* + * Sets the strings of the subwidgets using the current + * language. + */ +void findWnd::languageChange() +{ + setCaption( tr( "Find" ) ); + textLabel1->setText( tr( "Find:" ) ); + findButton->setText( tr( "&Find" ) ); + //US ENH findButton->setAccel( QKeySequence( tr( "Alt+F" ) ) ); + closeButton->setText( tr( "&Close" ) ); +//US ENH closeButton->setAccel( QKeySequence( tr( "Alt+C" ) ) ); + exactCheckBox->setText( tr( "&Exact match" ) ); +//US ENH exactCheckBox->setAccel( QKeySequence( tr( "Alt+E" ) ) ); + caseSensCheckBox->setText( tr( "&Case sensitive" ) ); +//US ENH caseSensCheckBox->setAccel( QKeySequence( tr( "Alt+C" ) ) ); + buttonGroup1->setTitle( tr( "Search in Column" ) ); + descRadioButton->setText( tr( "&Description" ) ); + pwRadioButton->setText( tr( "&Password" ) ); + commentRadioButton->setText( tr( "C&omment" ) ); + nameRadioButton->setText( tr( "&Username" ) ); +//US ENH nameRadioButton->setAccel( QKeySequence( tr( "Alt+U" ) ) ); + urlRadioButton->setText( tr( "U&RL" ) ); +//US ENH urlRadioButton->setAccel( QKeySequence( tr( "Alt+R" ) ) ); + launcherRadioButton->setText( tr( "&Launcher" ) ); +//US ENH launcherRadioButton->setAccel( QKeySequence( tr( "Alt+L" ) ) ); +} + +void findWnd::findButton_slot() +{ + qWarning( "findWnd::findButton_slot(): Not implemented yet" ); +} + +void findWnd::selectionChanged_slot() +{ + qWarning( "findWnd::selectionChanged_slot(): Not implemented yet" ); +} + +void findWnd::closeButton_slot() +{ + qWarning( "findWnd::closeButton_slot(): Not implemented yet" ); +} + diff --git a/pwmanager/pwmanager/findwnd.h b/pwmanager/pwmanager/findwnd.h new file mode 100644 index 0000000..d4ac8e0 --- a/dev/null +++ b/pwmanager/pwmanager/findwnd.h @@ -0,0 +1,61 @@ +/**************************************************************************** +** Form interface generated from reading ui file 'findwnd.ui' +** +** Created: Mon Sep 13 13:45:42 2004 +** by: The User Interface Compiler ($Id$) +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ + +#ifndef FINDWND_H +#define FINDWND_H + +#include +#include + +class QVBoxLayout; +class QHBoxLayout; +class QGridLayout; +class QSpacerItem; +class QLabel; +class QLineEdit; +class QPushButton; +class QCheckBox; +class QButtonGroup; +class QRadioButton; + +class findWnd : public QDialog +{ + Q_OBJECT + +public: + findWnd( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~findWnd(); + + QLabel* textLabel1; + QLineEdit* findLineEdit; + QPushButton* findButton; + QPushButton* closeButton; + QCheckBox* exactCheckBox; + QCheckBox* caseSensCheckBox; + QButtonGroup* buttonGroup1; + QRadioButton* descRadioButton; + QRadioButton* pwRadioButton; + QRadioButton* commentRadioButton; + QRadioButton* nameRadioButton; + QRadioButton* urlRadioButton; + QRadioButton* launcherRadioButton; + +public slots: + virtual void findButton_slot(); + virtual void selectionChanged_slot(); + virtual void closeButton_slot(); + +protected: + +protected slots: + virtual void languageChange(); + +}; + +#endif // FINDWND_H diff --git a/pwmanager/pwmanager/findwnd.ui b/pwmanager/pwmanager/findwnd.ui new file mode 100644 index 0000000..4572e0a --- a/dev/null +++ b/pwmanager/pwmanager/findwnd.ui @@ -0,0 +1,327 @@ + +findWnd + + + findWnd + + + + 0 + 0 + 381 + 269 + + + + Find + + + + textLabel1 + + + + 20 + 20 + 340 + 20 + + + + NoFrame + + + Plain + + + Find: + + + + + findLineEdit + + + + 20 + 40 + 340 + 20 + + + + + + findButton + + + + 20 + 230 + 107 + 27 + + + + &Find + + + Alt+F + + + + + closeButton + + + + 250 + 230 + 107 + 27 + + + + &Close + + + Alt+C + + + + + exactCheckBox + + + + 20 + 200 + 340 + 20 + + + + &Exact match + + + Alt+E + + + + + caseSensCheckBox + + + + 20 + 180 + 340 + 20 + + + + &Case sensitive + + + Alt+C + + + + + buttonGroup1 + + + + 20 + 70 + 340 + 90 + + + + Search in Column + + + + descRadioButton + + + + 30 + 20 + 150 + 20 + + + + &Description + + + true + + + + + pwRadioButton + + + + 180 + 20 + 150 + 20 + + + + &Password + + + + + commentRadioButton + + + + 180 + 40 + 150 + 20 + + + + C&omment + + + + + nameRadioButton + + + + 30 + 40 + 150 + 20 + + + + &Username + + + Alt+U + + + + + urlRadioButton + + + + 30 + 60 + 150 + 20 + + + + U&RL + + + Alt+R + + + + + launcherRadioButton + + + + 180 + 60 + 150 + 20 + + + + &Launcher + + + Alt+L + + + + + + + findButton + clicked() + findWnd + findButton_slot() + + + closeButton + clicked() + findWnd + closeButton_slot() + + + descRadioButton + stateChanged(int) + findWnd + selectionChanged_slot() + + + nameRadioButton + stateChanged(int) + findWnd + selectionChanged_slot() + + + pwRadioButton + stateChanged(int) + findWnd + selectionChanged_slot() + + + commentRadioButton + stateChanged(int) + findWnd + selectionChanged_slot() + + + findLineEdit + textChanged(const QString&) + findWnd + selectionChanged_slot() + + + caseSensCheckBox + stateChanged(int) + findWnd + selectionChanged_slot() + + + exactCheckBox + stateChanged(int) + findWnd + selectionChanged_slot() + + + + findLineEdit + descRadioButton + caseSensCheckBox + exactCheckBox + findButton + closeButton + nameRadioButton + pwRadioButton + commentRadioButton + + + findButton_slot() + selectionChanged_slot() + closeButton_slot() + + + diff --git a/pwmanager/pwmanager/findwndimpl.cpp b/pwmanager/pwmanager/findwndimpl.cpp new file mode 100644 index 0000000..fec1a6a --- a/dev/null +++ b/pwmanager/pwmanager/findwndimpl.cpp @@ -0,0 +1,125 @@ +/*************************************************************************** + * * + * copyright (C) 2003 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 "findwndimpl.h" +#include "pwmexception.h" +#include "pwmdoc.h" +#include "pwmview.h" + +#include +#include +#include + +#include +#include + +FindWndImpl::FindWndImpl(PwMView * _parent) + : findWnd() +{ + parent = _parent; + fAt = 0; + refVal = 0; + currFoundPos = -1; + numEntries = parent->document()->numEntries(parent->getCurrentCategory()); + connect(this, SIGNAL(foundAt(int)), parent, SLOT(selAt(int))); +} + +FindWndImpl::~FindWndImpl() +{ +} + +void FindWndImpl::findButton_slot() +{ + if (findLineEdit->text() == "") + return; + static vector foundPositions; + PwMDoc *doc = parent->document(); + + if (currFoundPos < 0) { + bool unlockedTempoary = false; + foundPositions.clear(); + PwMDataItem findThis; + unsigned int searchIn = 0; + + if (descRadioButton->isChecked()) { + searchIn = SEARCH_IN_DESC; + findThis.desc = findLineEdit->text().latin1(); + } else if (nameRadioButton->isChecked()) { + searchIn = SEARCH_IN_NAME; + findThis.name = findLineEdit->text().latin1(); + } else if (pwRadioButton->isChecked()) { + searchIn = SEARCH_IN_PW; + findThis.pw = findLineEdit->text().latin1(); + } else if (commentRadioButton->isChecked()) { + searchIn = SEARCH_IN_COMMENT; + findThis.comment = findLineEdit->text().latin1(); + } else if (urlRadioButton->isChecked()) { + searchIn = SEARCH_IN_URL; + findThis.url = findLineEdit->text().latin1(); + } else if (launcherRadioButton->isChecked()) { + searchIn = SEARCH_IN_LAUNCHER; + findThis.launcher = findLineEdit->text().latin1(); + } + + if (pwRadioButton->isChecked()) { + if (!doc->unlockAll_tempoary()) + return; + unlockedTempoary = true; + } + doc->findEntry(parent->getCurrentCategory(), findThis, + searchIn, &foundPositions, false, + caseSensCheckBox->isChecked(), + exactCheckBox->isChecked(), + true); + if (unlockedTempoary) { + doc->unlockAll_tempoary(true); + } + + if (!foundPositions.size()) { + KMessageBox::information(this, + i18n("No entry found."), + i18n("not found")); + return; + } + currFoundPos = 0; + } + + int lvp = doc->getListViewPos(parent->getCurrentCategory(), + foundPositions[currFoundPos++]); + emit foundAt(numEntries - 1 - lvp); + + if (currFoundPos + 1 > static_cast(foundPositions.size())) + currFoundPos = 0; +} + +void FindWndImpl::closeButton_slot() +{ + done(0); +} + +void FindWndImpl::selectionChanged_slot() +{ + fAt = 0; + refVal = 0; + currFoundPos = -1; +} + +#ifndef PWM_EMBEDDED +#include "findwndimpl.moc" +#endif diff --git a/pwmanager/pwmanager/findwndimpl.h b/pwmanager/pwmanager/findwndimpl.h new file mode 100644 index 0000000..d8cb65d --- a/dev/null +++ b/pwmanager/pwmanager/findwndimpl.h @@ -0,0 +1,61 @@ +/*************************************************************************** + * * + * copyright (C) 2003 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 FINDWNDIMPL_H +#define FINDWNDIMPL_H + +#include "findwnd.h" + +class PwMView; + +/** "add" Window */ +class FindWndImpl : public findWnd +{ + Q_OBJECT +public: + FindWndImpl(PwMView *_parent); + ~FindWndImpl(); + +signals: + void foundAt(int index); + +public slots: + /** find button pressed */ + void findButton_slot(); + /** close button pressed */ + void closeButton_slot(); + /** selection of one of the radio buttons changed */ + void selectionChanged_slot(); + +protected: + /** parent view */ + PwMView *parent; + /** entry found at */ + unsigned int fAt; + /** reference value */ + unsigned int refVal; + /** current position in the found-items-vector */ + int currFoundPos; + /** the number of entries in the current category */ + unsigned int numEntries; + /** index number of the current category */ + unsigned int catIndex; +}; + +#endif diff --git a/pwmanager/pwmanager/genpasswd.cpp b/pwmanager/pwmanager/genpasswd.cpp new file mode 100644 index 0000000..b0cceff --- a/dev/null +++ b/pwmanager/pwmanager/genpasswd.cpp @@ -0,0 +1,192 @@ +/*************************************************************************** + * * + * 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 "genpasswd.h" +#include "pwmexception.h" +#include "randomizer.h" + + +/* how often can a char of the same charset be reused in order */ +#define FILTER_MAX_CHARSET_REUSE 3 +/* re-randomize all charsets on every iteration (0/1) */ +#define RERAND_CHARSET 0 + + +struct staticCharsetStruct +{ + const char *lower; + const char *upper; + const char *num; + const char *special; + const char *blank; +}; + +static struct staticCharsetStruct staticCharset = { + "abcdefghijklmnopqrstuvwxyz", + "ABCDEFGHIJKLMNOPQRSTUVWXYZ", + "0123456789", + "!\"§$%&/()=?,.-;:_+", + " " +}; + + +GenPasswd::GenPasswd() + : length (8) + , useFilter (true) +{ + dynCharset.setAutoDelete(true); +} + +void GenPasswd::setCharset(bool lower, + bool upper, + bool num, + bool special, + bool blank, + QString user) +{ + unsigned int sanityCheck = 0; + dynCharset_element *tmpElement; + dynCharset.clear(); + if (lower) { + tmpElement = new dynCharset_element; + tmpElement->refCnt = 0; + tmpElement->data = staticCharset.lower; + dynCharset.append(tmpElement); + ++sanityCheck; + } + if (upper) { + tmpElement = new dynCharset_element; + tmpElement->refCnt = 0; + tmpElement->data = staticCharset.upper; + dynCharset.append(tmpElement); + ++sanityCheck; + } + if (num) { + tmpElement = new dynCharset_element; + tmpElement->refCnt = 0; + tmpElement->data = staticCharset.num; + dynCharset.append(tmpElement); + ++sanityCheck; + } + if (special) { + tmpElement = new dynCharset_element; + tmpElement->refCnt = 0; + tmpElement->data = staticCharset.special; + dynCharset.append(tmpElement); + ++sanityCheck; + } + if (blank) { + tmpElement = new dynCharset_element; + tmpElement->refCnt = 0; + tmpElement->data = staticCharset.blank; + dynCharset.append(tmpElement); + } + if (!user.isEmpty()) { + tmpElement = new dynCharset_element; + tmpElement->refCnt = 0; + tmpElement->data = user; + dynCharset.append(tmpElement); + if (likely(user.length() >= 2)) + ++sanityCheck; + } + BUG_ON(!sanityCheck); + rndDynCharset(); +} + +void GenPasswd::rndDynCharset() +{ + QString tmpData; + int pos; + Randomizer *rnd = Randomizer::obj(); + // QPtrList::iterator is not available in QT-3.1 + unsigned int i, cnt = dynCharset.count(); + dynCharset_element *p; + for (i = 0; i < cnt; ++i) { + p = dynCharset.at(i); + PWM_ASSERT(p); + tmpData = QString::null; + while (p->data.length()) { + pos = rnd->genRndInt() % p->data.length(); + tmpData.append(p->data.at(pos)); + p->data.remove(pos, 1); + } + p->data = tmpData; + } +} + +QString GenPasswd::gen() +{ + BUG_ON(dynCharset.count() <= 0); + BUG_ON(length < 1); + dynCharset_element *curCharset; + QString ret; + int i; + for (i = 0; i < length; ++i) { + curCharset = selectNextCharset(); +#if RERAND_CHARSET != 0 + rndDynCharset(); +#endif // RERAND_CHARSET + ret += genNewRandom(curCharset); + } + return ret; +} + +GenPasswd::dynCharset_element * GenPasswd::selectNextCharset() +{ + dynCharset_element *ret; + int numCharsets = dynCharset.count(); + BUG_ON(numCharsets <= 0); + if (numCharsets == 1) + return dynCharset.at(0); + Randomizer *rnd = Randomizer::obj(); + if (useFilter) { + // find out which charsets are allowed (filtering) + QPtrList allowedCharsets; + // QPtrList::iterator is not available in QT-3.1 + unsigned int i, cnt = dynCharset.count(); + dynCharset_element *p; + for (i = 0; i < cnt; ++i) { + p = dynCharset.at(i); + PWM_ASSERT(p); + if (p->refCnt < FILTER_MAX_CHARSET_REUSE) { + allowedCharsets.append(p); + } else { + p->refCnt = 0; + } + } + int numAllowedCharsets = allowedCharsets.count(); + BUG_ON(numAllowedCharsets <= 0); + // now get a random charset out of the allowed + unsigned int randomPos = rnd->genRndUInt() % numAllowedCharsets; + ret = allowedCharsets.at(randomPos); + ret->refCnt++; + return ret; + } + // all charsets are allowed here (no filtering). Get a random. + unsigned int randomPos = rnd->genRndUInt() % numCharsets; + ret = dynCharset.at(randomPos); + return ret; +} + +QChar GenPasswd::genNewRandom(const dynCharset_element *charset) +{ + Randomizer *rnd = Randomizer::obj(); + int pos = rnd->genRndInt() % charset->data.length(); + return charset->data.at(pos); +} diff --git a/pwmanager/pwmanager/genpasswd.h b/pwmanager/pwmanager/genpasswd.h new file mode 100644 index 0000000..3fa1607 --- a/dev/null +++ b/pwmanager/pwmanager/genpasswd.h @@ -0,0 +1,76 @@ +/*************************************************************************** + * * + * 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 __GENPASSWD_H +#define __GENPASSWD_H + +#include +#include + +/** internal password generator of PwManager */ +class GenPasswd +{ +protected: + struct dynCharset_element + { + /** charset data */ + QString data; + /** reference counter for the filter */ + unsigned int refCnt; + }; + +public: + GenPasswd(); + + /** set the charset to use */ + void setCharset(bool lower, + bool upper, + bool num, + bool special, + bool blank, + QString user); + /** set the password length */ + void setLen(int len) + { length = len; } + /** use the filter? */ + void setUseFilter(bool use) + { useFilter = use; } + /** start to generate a new password and return it. + * Returns an empty string on error. + */ + QString gen(); + +protected: + /** randomize the dynamic charset */ + void rndDynCharset(); + /** select the next charset (based on useFilter) */ + dynCharset_element * selectNextCharset(); + /** generate a new random char from the given charset */ + QChar genNewRandom(const dynCharset_element *charset); + +protected: + /** password length to generate */ + int length; + /** use the filter? */ + bool useFilter; + /** dynamic charset used for generating the password */ + QPtrList dynCharset; +}; + +#endif // __GENPASSWD_H diff --git a/pwmanager/pwmanager/getkeycardwnd.cpp b/pwmanager/pwmanager/getkeycardwnd.cpp new file mode 100644 index 0000000..89dada2 --- a/dev/null +++ b/pwmanager/pwmanager/getkeycardwnd.cpp @@ -0,0 +1,67 @@ +/*************************************************************************** + * * + * copyright (C) 2003 by Michael Buesch * + * email: fsdeveloper@yahoo.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 "getkeycardwnd.h" + +#include + +#include + + +GetKeyCardWnd::GetKeyCardWnd(QWidget *parent, + const char *name, bool modal, WFlags f) + : QDialog(parent, name, modal, f) +{ + vbox1 = new QVBox(this); + text_label = new QLabel(vbox1); + hbox1 = new QHBox(vbox1); + okButton = new QPushButton(i18n("&Ok"), hbox1); + cancelButton = new QPushButton(i18n("&Cancel"), hbox1); + + vbox1->setSpacing(10); + vbox1->setMargin(10); + hbox1->setSpacing(10); + + resize(500, 100); + + setCaption(i18n("Insert key-card")); + text_label->setText(i18n("Please insert the key-card " + "and press the OK button.")); + + connect(okButton, SIGNAL(clicked()), this, SLOT(okButton_slot())); + connect(cancelButton, SIGNAL(clicked()), this, SLOT(close())); +} + +GetKeyCardWnd::~GetKeyCardWnd() +{ +} + +void GetKeyCardWnd::resizeEvent(QResizeEvent *) +{ + vbox1->resize(size()); +} + +void GetKeyCardWnd::okButton_slot() +{ + done(1); +} + +#ifndef PWM_EMBEDDED +#include "getkeycardwnd.moc" +#endif diff --git a/pwmanager/pwmanager/getkeycardwnd.h b/pwmanager/pwmanager/getkeycardwnd.h new file mode 100644 index 0000000..fbe46ee --- a/dev/null +++ b/pwmanager/pwmanager/getkeycardwnd.h @@ -0,0 +1,53 @@ +/*************************************************************************** + * * + * copyright (C) 2003 by Michael Buesch * + * email: fsdeveloper@yahoo.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 GETKEYCARDWND_H +#define GETKEYCARDWND_H + +#include +#include +#include +#include +#include +#include + +/** The equivalent to GetMasterPwWndImpl for chipcards */ +class GetKeyCardWnd : public QDialog +{ + Q_OBJECT +public: + GetKeyCardWnd(QWidget *parent = 0, const char *name = 0, + bool modal = FALSE, WFlags f = 0); + ~GetKeyCardWnd(); + +protected slots: + void okButton_slot(); + +protected: + QVBox *vbox1; + QHBox *hbox1; + QLabel *text_label; + QPushButton *okButton; + QPushButton *cancelButton; + +protected: + void resizeEvent(QResizeEvent *); +}; + +#endif diff --git a/pwmanager/pwmanager/getmasterpwwnd.cpp b/pwmanager/pwmanager/getmasterpwwnd.cpp new file mode 100644 index 0000000..fb7c8b1 --- a/dev/null +++ b/pwmanager/pwmanager/getmasterpwwnd.cpp @@ -0,0 +1,88 @@ +/**************************************************************************** +** Form implementation generated from reading ui file 'getmasterpwwnd.ui' +** +** Created: Tue Sep 14 15:33:57 2004 +** by: The User Interface Compiler ($Id$) +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ + +#include "getmasterpwwnd.h" + +#include +#include +#include +#include +#include +#include +#include + +/* + * Constructs a getMasterPwWnd as a child of 'parent', with the + * name 'name' and widget flags set to 'f'. + * + * The dialog will by default be modeless, unless you set 'modal' to + * TRUE to construct a modal dialog. + */ +getMasterPwWnd::getMasterPwWnd( QWidget* parent, const char* name, bool modal, WFlags fl ) + : QDialog( parent, name, modal, fl ) +{ + if ( !name ) + setName( "getMasterPwWnd" ); + + okButton = new QPushButton( this, "okButton" ); + okButton->setGeometry( QRect( 10, 80, 107, 27 ) ); + + cancelButton = new QPushButton( this, "cancelButton" ); + cancelButton->setGeometry( QRect( 240, 80, 107, 27 ) ); + + textLabel1 = new QLabel( this, "textLabel1" ); + textLabel1->setGeometry( QRect( 10, 20, 340, 20 ) ); + textLabel1->setAlignment( int( QLabel::WordBreak | QLabel::AlignCenter ) ); + + pwLineEdit = new QLineEdit( this, "pwLineEdit" ); + pwLineEdit->setGeometry( QRect( 10, 50, 340, 20 ) ); + pwLineEdit->setEchoMode( QLineEdit::Password ); + languageChange(); + resize( QSize(361, 119).expandedTo(minimumSizeHint()) ); + clearWState( WState_Polished ); + + // signals and slots connections + connect( okButton, SIGNAL( clicked() ), this, SLOT( okButton_slot() ) ); + connect( cancelButton, SIGNAL( clicked() ), this, SLOT( cancelButton_slot() ) ); + + // tab order + setTabOrder( pwLineEdit, okButton ); + setTabOrder( okButton, cancelButton ); +} + +/* + * Destroys the object and frees any allocated resources + */ +getMasterPwWnd::~getMasterPwWnd() +{ + // no need to delete child widgets, Qt does it all for us +} + +/* + * Sets the strings of the subwidgets using the current + * language. + */ +void getMasterPwWnd::languageChange() +{ + setCaption( tr( "Master-password" ) ); + okButton->setText( tr( "&OK" ) ); + cancelButton->setText( tr( "&Cancel" ) ); + textLabel1->setText( tr( "Please enter the master-password:" ) ); +} + +void getMasterPwWnd::okButton_slot() +{ + qWarning( "getMasterPwWnd::okButton_slot(): Not implemented yet" ); +} + +void getMasterPwWnd::cancelButton_slot() +{ + qWarning( "getMasterPwWnd::cancelButton_slot(): Not implemented yet" ); +} + diff --git a/pwmanager/pwmanager/getmasterpwwnd.h b/pwmanager/pwmanager/getmasterpwwnd.h new file mode 100644 index 0000000..018628e --- a/dev/null +++ b/pwmanager/pwmanager/getmasterpwwnd.h @@ -0,0 +1,48 @@ +/**************************************************************************** +** Form interface generated from reading ui file 'getmasterpwwnd.ui' +** +** Created: Tue Sep 14 15:32:37 2004 +** by: The User Interface Compiler ($Id$) +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ + +#ifndef GETMASTERPWWND_H +#define GETMASTERPWWND_H + +#include +#include + +class QVBoxLayout; +class QHBoxLayout; +class QGridLayout; +class QSpacerItem; +class QPushButton; +class QLabel; +class QLineEdit; + +class getMasterPwWnd : public QDialog +{ + Q_OBJECT + +public: + getMasterPwWnd( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~getMasterPwWnd(); + + QPushButton* okButton; + QPushButton* cancelButton; + QLabel* textLabel1; + QLineEdit* pwLineEdit; + +public slots: + virtual void okButton_slot(); + virtual void cancelButton_slot(); + +protected: + +protected slots: + virtual void languageChange(); + +}; + +#endif // GETMASTERPWWND_H diff --git a/pwmanager/pwmanager/getmasterpwwnd.ui b/pwmanager/pwmanager/getmasterpwwnd.ui new file mode 100644 index 0000000..78e3dec --- a/dev/null +++ b/pwmanager/pwmanager/getmasterpwwnd.ui @@ -0,0 +1,110 @@ + +getMasterPwWnd + + + getMasterPwWnd + + + + 0 + 0 + 361 + 119 + + + + Master-password + + + + okButton + + + + 10 + 80 + 107 + 27 + + + + &OK + + + + + cancelButton + + + + 240 + 80 + 107 + 27 + + + + &Cancel + + + + + textLabel1 + + + + 10 + 20 + 340 + 20 + + + + Please enter the master-password: + + + WordBreak|AlignCenter + + + + + pwLineEdit + + + + 10 + 50 + 340 + 20 + + + + Password + + + + + + okButton + clicked() + getMasterPwWnd + okButton_slot() + + + cancelButton + clicked() + getMasterPwWnd + cancelButton_slot() + + + + pwLineEdit + okButton + cancelButton + + + okButton_slot() + cancelButton_slot() + + + diff --git a/pwmanager/pwmanager/getmasterpwwndimpl.cpp b/pwmanager/pwmanager/getmasterpwwndimpl.cpp new file mode 100644 index 0000000..db0223e --- a/dev/null +++ b/pwmanager/pwmanager/getmasterpwwndimpl.cpp @@ -0,0 +1,46 @@ +/*************************************************************************** + * * + * copyright (C) 2003 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 "getmasterpwwndimpl.h" + +#include + +GetMasterPwWndImpl::GetMasterPwWndImpl(QWidget * parent, const char *name) +: getMasterPwWnd(parent, name) +{ +} + +GetMasterPwWndImpl::~GetMasterPwWndImpl() +{ +} + +void GetMasterPwWndImpl::okButton_slot() +{ + if (pwLineEdit->text() != "") + done(1); +} + +void GetMasterPwWndImpl::cancelButton_slot() +{ + done(2); +} + +#ifndef PWM_EMBEDDED +#include "getmasterpwwndimpl.moc" +#endif diff --git a/pwmanager/pwmanager/getmasterpwwndimpl.h b/pwmanager/pwmanager/getmasterpwwndimpl.h new file mode 100644 index 0000000..28aa427 --- a/dev/null +++ b/pwmanager/pwmanager/getmasterpwwndimpl.h @@ -0,0 +1,40 @@ +/*************************************************************************** + * * + * copyright (C) 2003 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 GETMASTERPWWNDIMPL_H +#define GETMASTERPWWNDIMPL_H + +#include "getmasterpwwnd.h" + +/** set master pw wnd */ +class GetMasterPwWndImpl : public getMasterPwWnd +{ + Q_OBJECT +public: + GetMasterPwWndImpl(QWidget* parent = 0, const char *name = 0); + ~GetMasterPwWndImpl(); + +public slots: + /** ok button pressed */ + void okButton_slot(); + /** cancel button pressed */ + void cancelButton_slot(); +}; + +#endif diff --git a/pwmanager/pwmanager/globalstuff.cpp b/pwmanager/pwmanager/globalstuff.cpp new file mode 100644 index 0000000..b12d3a4 --- a/dev/null +++ b/pwmanager/pwmanager/globalstuff.cpp @@ -0,0 +1,35 @@ +/*************************************************************************** + * * + * 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 "globalstuff.h" + +#include +#include + +#ifndef CONFIG_KEYCARD +void no_keycard_support_msg_box(QWidget *parentWidget) +{ + KMessageBox::error(parentWidget, + i18n("No Chipcard-support available!\n" + "If you want to use a chipcard, " + "you have to compile PwManager with the " + "configure option --enable-keycard ."), + i18n("No Chipcard-support")); +} +#endif // CONFIG_KEYCARD diff --git a/pwmanager/pwmanager/globalstuff.h b/pwmanager/pwmanager/globalstuff.h new file mode 100644 index 0000000..7bc4173 --- a/dev/null +++ b/pwmanager/pwmanager/globalstuff.h @@ -0,0 +1,113 @@ +/*************************************************************************** + * * + * 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 __GLOBALSTUFF_H +#define __GLOBALSTUFF_H + +#ifndef PWM_EMBEDDED +#include "config.h" +#endif + +#include "compiler.h" + +#include +#include + +#ifndef CONFIG_KEYCARD +class QWidget; +void no_keycard_support_msg_box(QWidget *parentWidget); +#endif // CONFIG_KEYCARD + +#ifdef PROG_NAME +# undef PROG_NAME +#endif +#define PROG_NAME "PwManager" + +#ifdef PACKAGE_NAME +# undef PACKAGE_NAME +#endif +#define PACKAGE_NAME "pwmanager" + +#ifdef PACKAGE_VER +# undef PACKAGE_VER +#endif +#define PACKAGE_VER "1.0.1" + +#ifdef CONFIG_DEBUG +# define PWM_DEBUG +#else +# undef PWM_DEBUG +#endif + +#ifdef QT_MAKE_VERSION +# undef QT_MAKE_VERSION +#endif +#define QT_MAKE_VERSION(a,b,c) (((a) << 16) | ((b) << 8) | (c)) + +/** remove "unused parameter" warnings */ +#ifdef PARAM_UNUSED +# undef PARAM_UNUSED +#endif +#define PARAM_UNUSED(x) (void)x + +/** return the number of elements in an array */ +#ifdef array_size +# undef array_size +#endif +#define array_size(x) (sizeof(x) / sizeof((x)[0])) + +/** convert something to string using ostringstream */ +template inline +std::string tostr(const T &t) +{ + std::ostringstream s; + s << t; + return s.str(); +} + +/** delete the memory and NULL the pointer */ +template inline +void delete_and_null(T *&p) +{ + delete p; + p = 0; +} +/** delete the memory if the pointer isn't a NULL pointer */ +template inline +void delete_ifnot_null(T *&p) +{ + if (p) + delete_and_null(p); +} + +template inline +void delete_and_null_array(T *&p) +{ + delete [] p; + p = 0; +} + +template inline +void delete_ifnot_null_array(T *&p) +{ + if (p) + delete_and_null_array(p); +} + +#endif // GLOBALSTUFF_H diff --git a/pwmanager/pwmanager/gpasmanfile.cpp b/pwmanager/pwmanager/gpasmanfile.cpp new file mode 100644 index 0000000..f80bc13 --- a/dev/null +++ b/pwmanager/pwmanager/gpasmanfile.cpp @@ -0,0 +1,437 @@ +/* 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 +#include +#include +#include +#include +#include +#include +#include + +#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 + + +#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 + +#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); + } + + if (!S_ISREG(naamstat.st_mode)) { + lstat(filename, &naamstat); + if (S_ISLNK(naamstat.st_mode)) { + DBG("%s is a symlink", filename); + return (-2); + } + } + + 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/gpasmanfile.h b/pwmanager/pwmanager/gpasmanfile.h new file mode 100644 index 0000000..d2b7dc5 --- a/dev/null +++ b/pwmanager/pwmanager/gpasmanfile.h @@ -0,0 +1,67 @@ +/*************************************************************************** + * * + * copyright (C) 2003 by Michael Buesch * + * email: mbuesch@freenet.de * + * * + * Gpasman, a password manager * + * Copyright (C) 1998-1999 Olivier Sessink, olivier@lx.student.wau.nl * + * * + * 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 GPASMANFILE_H +#define GPASMANFILE_H + +#include "rc2.h" + +#include + +/** gpasman / kpasman file read/write module */ +class GpasmanFile +{ +public: + GpasmanFile(); + ~GpasmanFile(); + + /* + * one entry is a char *entry[4] + * this means we have 4 pointers to a char --> + * 0 = server + * 1 = username + * 2 = password + * 3 = comment + */ + + int save_init(const char *filename, const char *password); + int save_entry(char *entry[4]); + int save_finalize(void); + int load_init(const char *filename, const char *password); + int load_entry(char *entry[4]); + void load_finalize(void); + +protected: + int check_file(const char *filename); + int file_exists(const char *tfile); + +protected: + FILE *fd; + unsigned short iv[4]; + char *buffer; + int bufferIndex; + unsigned short plaintext[4]; + int lastcount, size; + Rc2 rc2; +}; + +#endif diff --git a/pwmanager/pwmanager/htmlgen.cpp b/pwmanager/pwmanager/htmlgen.cpp new file mode 100644 index 0000000..166b987 --- a/dev/null +++ b/pwmanager/pwmanager/htmlgen.cpp @@ -0,0 +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 + +/** enable/disable HTML-generator debugging (0/1) */ +#define HTMLGEN_DEBUG 0 + + +#define HTML_DOCTYPE_HDR "\n" +#define HTML_PWM_HDR "" +#define HTML_COMMENT_HDR "" +#define HTML_COMMENTVER_HDR "" +#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]; + 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("", 0, false); + if (ret == -1) + return false; + ret = dta.find("", ret, false); + if (ret == -1) + return false; + return true; +} + +QString HtmlGen::getStyleSheetHtml() +{ + QString ret; + ret = "" 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_ENDL; + if (!appendCommentHeader(&ret)) + return ""; + if (!appendCommentBody(&ret, dta)) + return ""; + ret += "" HTML_ENDL; + +#if defined(PWM_DEBUG) && HTMLGEN_DEBUG != 0 + printDebug(""); + cout << ret << endl; + printDebug(""); +#endif // DEBUG + return ret; +} + +bool HtmlGen::appendCommentHeader(QString *str) +{ + *str += "" HTML_ENDL; + if (useSSDummy) { + *str += HTML_STYLESHEET_DUMMY HTML_ENDL; + } else { + QString ssLine(getStyleSheetHtml()); + if (ssLine.isEmpty()) + return false; + *str += ssLine; + } + *str += "" HTML_ENDL; + return true; +} + +bool HtmlGen::appendCommentBody(QString *str, + const HtmlComment *dta) +{ + *str += "" HTML_ENDL; + if (!appendCommentGlobTbl(str, dta)) + return false; + *str += "" HTML_ENDL; + return true; +} + +bool HtmlGen::appendCommentGlobTbl(QString *str, + const HtmlComment *dta) +{ + *str += "" HTML_ENDL; + *str += "" HTML_ENDL; + + const vector *subTbls = dta->getSubTableList(); + vector::const_iterator i = subTbls->begin(), + end = subTbls->end(); + while (i != end) { + *str += "" HTML_ENDL; + } + + *str += "
"; + *str += escapeHtmlText(dta->getTitle()); + *str += "
" HTML_ENDL; + if (!appendCommentSubTbl(str, &(*i))) + return false; + ++i; + *str += "
" HTML_ENDL; + return true; +} + +bool HtmlGen::appendCommentSubTbl(QString *str, + const HtmlComment::SubTable *dta) +{ + *str += "" HTML_ENDL; + *str += "" HTML_ENDL; + + const vector< pair > *entries = dta->getEntryList(); + vector< pair >::const_iterator i = entries->begin(), + end = entries->end(); + while (i != end) { + *str += "" HTML_ENDL; + if (!appendCommentSubTblEntry(str, &(*i))) + return false; + *str += "" HTML_ENDL; + ++i; + } + + *str += "
"; + *str += escapeHtmlText(dta->getTitle()); + *str += "
" HTML_ENDL; + return true; +} + +bool HtmlGen::appendCommentSubTblEntry(QString *str, + const pair *dta) +{ + *str += ""; + *str += escapeHtmlText(dta->first); + *str += "" HTML_ENDL; + *str += ""; + *str += escapeHtmlText(dta->second); + *str += "" HTML_ENDL; + return true; +} diff --git a/pwmanager/pwmanager/htmlgen.h b/pwmanager/pwmanager/htmlgen.h new file mode 100644 index 0000000..5ec9626 --- a/dev/null +++ b/pwmanager/pwmanager/htmlgen.h @@ -0,0 +1,136 @@ +/*************************************************************************** + * * + * 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 HTMLGEN_H +#define HTMLGEN_H + +#include + +#include +#include + +using std::vector; +using std::pair; + +/** internal representation of the advanced HTML-comment */ +class HtmlComment +{ +public: + class SubTable + { + public: + SubTable() {} + ~SubTable() {} + + void clear() + { + title = ""; + entries.clear(); + } + void setTitle(const QString &_title) + { title = _title; } + QString getTitle() const + { return title; } + void addEntry(const pair &entry) + { entries.push_back(entry); } + void setEntries(const vector< pair > *_entries) + { entries = *_entries; } + const vector< pair > * getEntryList() const + { return &entries; } + + protected: + /** sub-title */ + QString title; + /** list of entries */ + vector< pair > entries; + }; + +public: + HtmlComment() {} + ~HtmlComment() {} + + void clear() + { + title = ""; + subTables.clear(); + } + void setTitle(const QString &_title) + { title = _title; } + QString getTitle() const + { return title; } + void addSubtable(const SubTable &subTable) + { subTables.push_back(subTable); } + void eraseSubtable(int index) + { subTables.erase(subTables.begin() + index); } + const SubTable & subtableAt(int index) + { return subTables[index]; } + void setSubtblAt(int index, const SubTable &entry) + { subTables[index] = entry; } + const vector * getSubTableList() const + { return &subTables; } + +protected: + /** global title */ + QString title; + /** list of sub-tables */ + vector subTables; +}; + +/** HTML generator for the comment-box */ +class HtmlGen +{ +public: + HtmlGen(); + ~HtmlGen(); + + /** replace the @STYLESHEET@ dummy in the "doc" HTML document */ + static bool replaceSSDummy(QString *doc); + /** check whether "dta" is HTML-code */ + static bool isHtml(const QString &dta); + + /** insert the stylesheet link as dummy? default is true */ + void styleSheetDummy(bool dummy) + { useSSDummy = dummy; } + /** generate a new html-comment */ + QString genHtmlComment(const HtmlComment *dta); + +protected: + /** converts the string "str" into HTML-text and ensures + * that there are no collisions with HTML-tags + */ + QString escapeHtmlText(const QString &str); + /** get the "stylesheet-line" to import the CSS style in HTML */ + static QString getStyleSheetHtml(); + /** append the HTML header to the data stream */ + bool appendCommentHeader(QString *str); + /** append the HTML body for the comment */ + bool appendCommentBody(QString *str, const HtmlComment *dta); + /** append a global comment table */ + bool appendCommentGlobTbl(QString *str, const HtmlComment *dta); + /** append a comment subtable */ + bool appendCommentSubTbl(QString *str, const HtmlComment::SubTable *dta); + /** append a subtable entry */ + bool appendCommentSubTblEntry(QString *str, const pair *dta); + +protected: + /** use stylesheet dummy */ + bool useSSDummy; +}; + +#endif diff --git a/pwmanager/pwmanager/htmlparse.cpp b/pwmanager/pwmanager/htmlparse.cpp new file mode 100644 index 0000000..acde2e3 --- a/dev/null +++ b/pwmanager/pwmanager/htmlparse.cpp @@ -0,0 +1,184 @@ +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include "htmlparse.h" +#include "pwmexception.h" + +#include +#include +#include + + +/** enable/disable HTML-parser debugging (0/1) */ +#define HTMLPARSE_DEBUG 1 + + +#if !defined(PWM_DEBUG) || HTMLPARSE_DEBUG == 0 +# undef printDebug +# define printDebug(x) do {} while (0) +#endif + +HtmlParse::HtmlParse() +{ +} + +HtmlParse::~HtmlParse() +{ +} + +bool HtmlParse::parseHtmlComment(const QString &dta, + HtmlComment *ret) +{ + PWM_ASSERT(ret); + ret->clear(); + DOM::HTMLDocument curDoc(static_cast(0)); + curDoc.open(); + curDoc.write(dta); + curDoc.close(); + DOM::HTMLElement body(curDoc.body()); + DOM::HTMLCollection children(body.children()); + + unsigned long i, numCh = children.length(); + if (numCh != 1) { + /* we currently support only one global table */ + printDebug("HtmlParse::parseHtmlComment(): global children cnt != 1"); + return false; + } + DOM::DOMString nodeName; + DOM::Node curNode; + for (i = 0; i < numCh; ++i) { + curNode = children.item(i); + nodeName = curNode.nodeName(); + if (nodeName == "table") { + if (!parseCommentGlobTbl(curNode, ret)) + return false; + } else { + // We don't support something else than tables, yet. + printDebug("HtmlParse::parseHtmlComment(): unknown node"); + } + } + return true; +} + +bool HtmlParse::parseCommentGlobTbl(const DOM::Node &node, + HtmlComment *ret) +{ + PWM_ASSERT(node.nodeName() == "table"); + DOM::Node bodyNode(node.firstChild()); + PWM_ASSERT(bodyNode.nodeName() == "tbody"); + DOM::Node curNode(bodyNode.firstChild()); + DOM::DOMString nodeName; + ret->clear(); + while (!curNode.isNull()) { + nodeName = curNode.nodeName(); + if (nodeName == "tr") { + if (!parseCommentGlobTblRow(curNode, ret)) + return false; + } else { + printDebug("HtmlParse::parseCommentGlobTbl(): node unknown"); + } + curNode = curNode.nextSibling(); + } + return true; +} + +bool HtmlParse::parseCommentGlobTblRow(const DOM::Node &node, + HtmlComment *ret) +{ + DOM::Node curNode(node.firstChild()), child; + DOM::DOMString nodeName; + HtmlComment::SubTable subTbl; + while (!curNode.isNull()) { + nodeName = curNode.nodeName(); + if (nodeName == "th") { + // global title + ret->setTitle(curNode.firstChild().nodeValue().string()); + } else if (nodeName == "td") { + child = curNode.firstChild(); + if (child.nodeName() == "table" && + child.firstChild().nodeName() == "tbody") { + // we have a sub-table + if (!parseCommentSubTbl(child.firstChild(), &subTbl)) + return false; + ret->addSubtable(subTbl); + } else { + printDebug("HtmlParse::parseCommentGlobTblRow(): subelement unknown"); + } + } else { + printDebug("HtmlParse::parseCommentGlobTblRow(): node unknown"); + } + curNode = curNode.nextSibling(); + } + return true; +} + +bool HtmlParse::parseCommentSubTbl(const DOM::Node &node, + HtmlComment::SubTable *ret) +{ + PWM_ASSERT(node.nodeName() == "tbody"); + DOM::Node curNode(node.firstChild()); + DOM::DOMString nodeName; + ret->clear(); + while (!curNode.isNull()) { + nodeName = curNode.nodeName(); + if (nodeName == "tr") { + if (!parseCommentSubTblRow(curNode, ret)) + return false; + } else { + printDebug("HtmlParse::parseCommentSubTbl(): node unknown"); + } + curNode = curNode.nextSibling(); + } + return true; +} + +bool HtmlParse::parseCommentSubTblRow(const DOM::Node &node, + HtmlComment::SubTable *ret) +{ + DOM::Node curNode(node.firstChild()), child; + DOM::DOMString nodeName; + pair curEntr; + while (!curNode.isNull()) { + nodeName = curNode.nodeName(); + if (nodeName == "th") { + // sub title + ret->setTitle(curNode.firstChild().nodeValue().string()); + } else if (nodeName == "td") { + child = curNode.firstChild(); + if (child.nodeName() == "#text") { + if (!parseCommentSubTblEntry(curNode, &curEntr)) + return false; + ret->addEntry(curEntr); + return true; + } else { + printDebug("HtmlParse::parseCommentSubTblRow(): subelement unknown"); + } + } else { + printDebug("HtmlParse::parseCommentGlobTblRow(): node unknown"); + } + curNode = curNode.nextSibling(); + } + return true; +} + +bool HtmlParse::parseCommentSubTblEntry(const DOM::Node &node, + pair *ret) +{ + DOM::Node curChild(node); + if (curChild.isNull()) + return false; + ret->first = curChild.firstChild().nodeValue().string(); + curChild = curChild.nextSibling(); + if (curChild.isNull()) + return false; + ret->second = curChild.firstChild().nodeValue().string(); + return true; +} diff --git a/pwmanager/pwmanager/htmlparse.h b/pwmanager/pwmanager/htmlparse.h new file mode 100644 index 0000000..bd92d0b --- a/dev/null +++ b/pwmanager/pwmanager/htmlparse.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef HTMLPARSE_H +#define HTMLPARSE_H + +#include "htmlgen.h" + +#include + +#include + +using std::pair; + +class HtmlParse +{ +public: + HtmlParse(); + ~HtmlParse(); + + /** parse the given HTML data and return the HtmlComment */ + bool parseHtmlComment(const QString &dta, HtmlComment *ret); + +protected: + /** parse a global html comment table */ + bool parseCommentGlobTbl(const DOM::Node &node, HtmlComment *ret); + /** parse a row of the global table */ + bool parseCommentGlobTblRow(const DOM::Node &node, HtmlComment *ret); + /** parse a comment sub table */ + bool parseCommentSubTbl(const DOM::Node &node, HtmlComment::SubTable *ret); + /** parse a row of comment sub table */ + bool parseCommentSubTblRow(const DOM::Node &node, HtmlComment::SubTable *ret); + /** parse a comment subtable entry */ + bool parseCommentSubTblEntry(const DOM::Node &node, pair *ret); +}; + +#endif diff --git a/pwmanager/pwmanager/ipc.cpp b/pwmanager/pwmanager/ipc.cpp new file mode 100644 index 0000000..7468357 --- a/dev/null +++ b/pwmanager/pwmanager/ipc.cpp @@ -0,0 +1,152 @@ +/*************************************************************************** + * * + * 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 + +#include +#include +#include + +#define END_OF_LINE '\n' +#define INIT_LINEBUF_LEN 64 /* byte */ + + +Ipc::Ipc() + : stream (0) + , notifier (0) + , rdBuf (0) +{ +#ifndef PWM_EMBEDDED + if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sock)) { + throw PwMException(PwMException::EX_GENERIC, + "Ipc: socketpair() failed"); + } + rdBufSize = INIT_LINEBUF_LEN; + rdBuf = static_cast(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"); + } +#else + if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sock)) { + qDebug("Ipc: socketpair() failed"); + } + rdBufSize = INIT_LINEBUF_LEN; + rdBuf = (char *)(malloc(rdBufSize)); + if (!rdBuf) { + close(sock[0]); + close(sock[1]); + qDebug("Ipc: OOM"); + } + stream = fdopen(sock[0], "r"); + if (!stream) { + close(sock[0]); + close(sock[1]); + free(rdBuf); + qDebug("Ipc: fdopen() failed"); + } +#endif + + notifier = new QSocketNotifier(sock[0], QSocketNotifier::Read); + connect(notifier, SIGNAL(activated(int)), + this, SLOT(receiveData(int))); + host = true; +} + +Ipc::Ipc(const Ipc *ipc) + : stream (0) + , notifier (0) + , rdBuf (0) +{ +#ifndef PWM_EMBEDDED + rdBufSize = INIT_LINEBUF_LEN; + rdBuf = static_cast(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"); + } +#else + rdBufSize = INIT_LINEBUF_LEN; + rdBuf = (char *)(malloc(rdBufSize)); + if (!rdBuf) { + qDebug("Ipc: OOM"); + } + sock[0] = ipc->sock[1]; + sock[1] = ipc->sock[0]; + stream = fdopen(sock[0], "r"); + if (!stream) { + free(rdBuf); + qDebug("Ipc: fdopen() failed"); + } +#endif + notifier = new QSocketNotifier(sock[0], QSocketNotifier::Read); + connect(notifier, SIGNAL(activated(int)), + this, SLOT(receiveData(int))); + host = false; +} + +Ipc::~Ipc() +{ + delete_ifnot_null(notifier); + if (rdBuf) + free(rdBuf); + if (stream) + fclose(stream); + if (host) { + close(sock[0]); + close(sock[1]); + } +} + +void Ipc::receiveData(int s) +{ + ssize_t rd; + + PWM_ASSERT(s == sock[0]); + PARAM_UNUSED(s); + rd = getline(&rdBuf, &rdBufSize, stream); + if (likely(rd > 0)) { + emit lineAvailable(rdBuf, rd); + } +} + +#ifndef PWM_EMBEDDED +#include "ipc.moc" +#endif diff --git a/pwmanager/pwmanager/ipc.h b/pwmanager/pwmanager/ipc.h new file mode 100644 index 0000000..ccdaafb --- a/dev/null +++ b/pwmanager/pwmanager/ipc.h @@ -0,0 +1,73 @@ +/*************************************************************************** + * * + * 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 + +#include +#include + +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) + */ + void send(const char *buf, size_t size) + { write(sock[0], buf, size); } + +signals: + /** a line is available */ + void lineAvailable(const char *buf, size_t size); + +protected slots: + /** received data on socket */ + void receiveData(int s); + +protected: + /** full-duplex socket file desciptors */ + int sock[2]; + /** stream on "this" end of the socket (sock[0]) */ + FILE *stream; + /** socket notifier */ + QSocketNotifier *notifier; + /** are we the host or the client object? */ + bool host; + /** receive buffer */ + char *rdBuf; + /** current receive buffer size */ + size_t rdBufSize; +}; + +#endif // __PWM_IPC_H diff --git a/pwmanager/pwmanager/listobjselectwnd.cpp b/pwmanager/pwmanager/listobjselectwnd.cpp new file mode 100644 index 0000000..59729f1 --- a/dev/null +++ b/pwmanager/pwmanager/listobjselectwnd.cpp @@ -0,0 +1,131 @@ +/*************************************************************************** + * * + * 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$ + **************************************************************************/ + +#include "listobjselectwnd.h" + +#include + + +ListObjSelectWnd::ListObjSelectWnd(const QString &caption, const QString &titleText, + QWidget *parent, bool multiSel, const char *name, + bool modal, WFlags f) + : QDialog(parent, name, modal, f) +{ + vbox1 = new QVBox(this); + title = new QLabel(vbox1); + list = new QListBox(vbox1); + if (multiSel) { + hbox2 = new QHBox(vbox1); + selAllButton = new QPushButton(i18n("&Select all"), hbox2); + unselAllButton = new QPushButton(i18n("&Unselect all"), hbox2); + } + hbox1 = new QHBox(vbox1); + okButton = new QPushButton(i18n("&Ok"), hbox1); + cancelButton = new QPushButton(i18n("&Cancel"), hbox1); + + vbox1->setSpacing(10); + vbox1->setMargin(10); + hbox1->setSpacing(10); + resize(250, 300); + setCaption(caption); + if (multiSel) { + list->setSelectionMode(QListBox::Multi); + } + + title->setAlignment(Qt::AlignHCenter | Qt::WordBreak); + title->setText(titleText); + + connect(okButton, SIGNAL(clicked()), + this, SLOT(okButton_slot())); + connect(cancelButton, SIGNAL(clicked()), + this, SLOT(cancelButton_slot())); + if (multiSel) { + connect(selAllButton, SIGNAL(clicked()), + this, SLOT(selAllButton_slot())); + connect(unselAllButton, SIGNAL(clicked()), + this, SLOT(unselAllButton_slot())); + } +} + +ListObjSelectWnd::~ListObjSelectWnd() +{ +} + +void ListObjSelectWnd::resizeEvent(QResizeEvent *) +{ + vbox1->resize(size()); +} + +void ListObjSelectWnd::okButton_slot() +{ + unsigned int cnt = list->count(), i; + for (i = 0; i < cnt; ++i) { + if (list->isSelected(i)) { + done(1); + return; + } + } +} + +void ListObjSelectWnd::cancelButton_slot() +{ + done(2); +} + +void ListObjSelectWnd::selAllButton_slot() +{ + unsigned int cnt = list->count(), i; + for (i = 0; i < cnt; ++i) { + list->setSelected(i, true); + } +} + +void ListObjSelectWnd::unselAllButton_slot() +{ + unsigned int cnt = list->count(), i; + for (i = 0; i < cnt; ++i) { + list->setSelected(i, false); + } +} + +QStringList ListObjSelectWnd::getSelectedList() +{ + QStringList ret; + unsigned int cnt = list->count(), i; + for (i = 0; i < cnt; ++i) { + if (list->isSelected(i)) { +#ifndef PWM_EMBEDDED + ret.push_back(list->text(i)); +#else + ret.append(list->text(i)); +#endif + } + } + return ret; +} + +void ListObjSelectWnd::setList(const QStringList &_list) +{ + list->clear(); + list->insertStringList(_list); +} + +#ifndef PWM_EMBEDDED +#include "listobjselectwnd.moc" +#endif diff --git a/pwmanager/pwmanager/listobjselectwnd.h b/pwmanager/pwmanager/listobjselectwnd.h new file mode 100644 index 0000000..3b5f1eb --- a/dev/null +++ b/pwmanager/pwmanager/listobjselectwnd.h @@ -0,0 +1,85 @@ +/*************************************************************************** + * * + * 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 LISTOBJSELECTWND_H +#define LISTOBJSELECTWND_H + +#include +#include +#include +#include +#include +#include +#include + + +/** Display a list-window for selection of some objects */ +class ListObjSelectWnd : public QDialog +{ + Q_OBJECT +public: + ListObjSelectWnd(const QString &caption, const QString &titleText, + QWidget *parent = 0, bool multiSel = false, + const char *name = 0, + bool modal = FALSE, WFlags f = 0); + ~ListObjSelectWnd(); + + void setList(const QStringList &_list); + void addObj(const QString &name) + { list->insertItem(name); } + void selectObj(const QString &name) +#ifndef PWM_EMBEDDED + { list->setCurrentItem(list->findItem(name, Qt::ExactMatch)); } +#else + { list->setCurrentItem(list->findItem(name)); } +#endif + QString getSelected() + { return list->currentText(); } + int getSelectedIndex() +#ifndef PWM_EMBEDDED + { return list->index(list->selectedItem()); } +#else + { return list->currentItem(); } +#endif + QStringList getSelectedList(); + void clearObjs() + { list->clear(); } + +protected: + QVBox *vbox1; + QHBox *hbox1; + QHBox *hbox2; + QLabel *title; + QListBox *list; + QPushButton *okButton; + QPushButton *cancelButton; + QPushButton *selAllButton; + QPushButton *unselAllButton; + +protected: + void resizeEvent(QResizeEvent *); + +protected slots: + void okButton_slot(); + void cancelButton_slot(); + void selAllButton_slot(); + void unselAllButton_slot(); +}; + +#endif diff --git a/pwmanager/pwmanager/listviewpwm.cpp b/pwmanager/pwmanager/listviewpwm.cpp new file mode 100644 index 0000000..b987c9e --- a/dev/null +++ b/pwmanager/pwmanager/listviewpwm.cpp @@ -0,0 +1,86 @@ +/*************************************************************************** + * * + * 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 "listviewpwm.h" +#include "pwmexception.h" + +#include +#include + +#include + + +ListViewPwM::ListViewPwM(QWidget *parent, const char *name) + : KListView(parent, name) +{ +// setResizeMode(QListView::AllColumns); +} + +bool ListViewPwM::event(QEvent *e) +{ + if (e->type() == QEvent::LayoutHint) + emit layoutChanged(); + return KListView::event(e); +} + + +QPixmap * ListViewItemPwM::onPix = 0; +QPixmap * ListViewItemPwM::offPix = 0; + +ListViewItemPwM::ListViewItemPwM(QListView *parent) + : QCheckListItem(parent, "", QCheckListItem::CheckBox) +{ + if (!onPix) { + PWM_ASSERT(!offPix); + KIconLoader il; + static QPixmap onP(il.loadIcon("button_ok", KIcon::Small)); + onPix = &onP; + static QPixmap offP(il.loadIcon("encrypted", KIcon::Small)); + offPix = &offP; + } +} + +void ListViewItemPwM::paintCell(QPainter *p, const QColorGroup &cg, + int column, int width, int align) +{ + if (!p) + return; + if (column != 0) { + QCheckListItem::paintCell(p, cg, column, width, align); + return; + } + QPixmap *curPix = isOn() ? onPix : offPix; + int pixSpace = curPix->width(); + pixSpace += 4; +#ifndef PWM_EMBEDDED + QRect window(p->viewport()); + // clear the rectangle (we have to clear it first. see QT doc) + p->eraseRect(0, 0, pixSpace, window.height()); + // now draw the pixmap + int y = (height() - curPix->height()) / 2; + p->drawPixmap(1, y, *curPix); + window.moveLeft(pixSpace); + p->setViewport(window); +#endif + QListViewItem::paintCell(p, cg, column, width - pixSpace, align); +} + +#ifndef PWM_EMBEDDED +#include "listviewpwm.moc" +#endif diff --git a/pwmanager/pwmanager/listviewpwm.h b/pwmanager/pwmanager/listviewpwm.h new file mode 100644 index 0000000..e6471c6 --- a/dev/null +++ b/pwmanager/pwmanager/listviewpwm.h @@ -0,0 +1,57 @@ +/*************************************************************************** + * * + * 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 __LISTVIEW_H +#define __LISTVIEW_H + +#include + +/** PwManager implementation of the list view. + * Derived from KListView. + */ +class ListViewPwM : public KListView +{ + Q_OBJECT +public: + ListViewPwM(QWidget *parent = 0, const char *name = 0); + +signals: + void layoutChanged(); + +protected: + virtual bool event(QEvent *e); +}; + +class ListViewItemPwM : public QCheckListItem +{ +public: + ListViewItemPwM(QListView *parent); + +protected: + void paintCell(QPainter *p, const QColorGroup &cg, + int column, int width, int align); + +protected: + /** pixmap to display for an item with state "on" */ + static QPixmap *onPix; + /** pixmap to display for an item with state "off" */ + static QPixmap *offPix; +}; + +#endif diff --git a/pwmanager/pwmanager/main.cpp b/pwmanager/pwmanager/main.cpp new file mode 100644 index 0000000..d720e1f --- a/dev/null +++ b/pwmanager/pwmanager/main.cpp @@ -0,0 +1,210 @@ +/*************************************************************************** + * * + * 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 PWM_EMBEDDED +#include +#include +#else +#include +#endif + +#include +#include + +#include "pwmexception.h" +#include "pwminit.h" + +#define LICENSE_FILE (::locate("data", "pwmanager/pwmanager_license_text")) + +int PwMApplication::newInstance() +{ + static bool initial = true; + if (initial) { + initial = false; + init = new PwMInit(this); + init->initializeApp(); + } else { + BUG_ON(!init); + printInfo("passing parameters to old instance."); + init->handleCmdLineArgs(false); + } + return EXIT_SUCCESS; +} + + +static const char *description = I18N_NOOP("PwManager\n" + "The convenient way of managing passwords"); + +#ifndef PWM_EMBEDDED +static KCmdLineOptions options[] = +{ + { "minimized", I18N_NOOP("Windows minimized"), 0 }, + { "mintray", I18N_NOOP("Windows minimized to tray"), 0 }, + { "open-deeplocked", I18N_NOOP("Open all \"files\" deeplocked"), 0 }, + { "skip-self-test", I18N_NOOP("Don't run a self-test on startup"), 0 }, + { "+[files...]", I18N_NOOP("Files to open on startup"), 0 }, + { 0, 0, 0 } +}; +#endif + +#ifdef PWM_DEBUG +static void printDebugConfigureInfo() +{ + cout << "================================" << endl; + cout << PROG_NAME " version " PACKAGE_VER << endl; +#ifdef CONFIG_KEYCARD + cout << "CONFIG_KEYCARD: enabled" << endl; +#else + cout << "CONFIG_KEYCARD: disabled" << endl; +#endif +#ifdef CONFIG_KWALLETIF + cout << "CONFIG_KWALLETIF: enabled" << endl; +#else + cout << "CONFIG_KWALLETIF: disabled" << endl; +#endif +#ifdef BIG_ENDIAN_HOST + cout << "Endianess: big-endian" << endl; +#else + cout << "Endianess: little-endian" << endl; +#endif + cout << "sizeof(long): " << sizeof(long) << endl; + cout << "================================" << endl; +} +#else // PWM_DEBUG +static inline void printDebugConfigureInfo() { /* nothing */ } +#endif // PWM_DEBUG + +#ifndef PWM_EMBEDDED +static void addAuthors(KAboutData *aboutData) +{ + aboutData->addAuthor("Michael Buesch", + I18N_NOOP( + "main programming and current maintainer"), + "mbuesch@freenet.de"); + aboutData->addAuthor("Matt Scifo", + I18N_NOOP( + "original implementaion of \n" + "\"categories\" and the password-tree \n" + "in the system-tray. Original implementations of \n" + "numerous view-improvements."), + "mscifo@o1.com"); + aboutData->addCredit("Elias Probst", + I18N_NOOP( + "Gentoo ebuild maintainer."), + "elias.probst@gmx.de"); + aboutData->addCredit("George Staikos", + I18N_NOOP("KWallet"), + "staikos@kde.org"); + aboutData->addCredit("Matthew Palmer", + I18N_NOOP("rc2 code"), + "mjp16@uow.edu.au"); + aboutData->addCredit("Olivier Sessink", + I18N_NOOP("gpasman"), + "gpasman@nl.linux.org"); + aboutData->addCredit("The libgcrypt developers", + I18N_NOOP("Blowfish and SHA1 algorithms"), + 0, "ftp://ftp.gnupg.org/gcrypt/alpha/libgcrypt/"); + aboutData->addCredit("Troy Engel", + I18N_NOOP("kpasman"), + "tengel@sonic.net"); + aboutData->addCredit("Wickey", + I18N_NOOP("graphics-design in older versions."), + "wickey@gmx.at"); + aboutData->addCredit("Ian MacGregor", + I18N_NOOP( + "original documentation author.")); +} +#endif + +int main(int argc, char *argv[]) +{ + printDebugConfigureInfo(); +#ifndef PWM_EMBEDDED + KAboutData aboutData(PACKAGE_NAME, PROG_NAME, + PACKAGE_VER, description, KAboutData::License_File, + "(c) 2003, 2004 Michael Buesch and the PwManager Team", 0, + "http://passwordmanager.sourceforge.net/", + "mbuesch@freenet.de"); + addAuthors(&aboutData); + + KCmdLineArgs::init(argc, argv, &aboutData); + KCmdLineArgs::addCmdLineOptions(options); + + KUniqueApplication::addCmdLineOptions(); + if (!KUniqueApplication::start()) { + printInfo("already running."); + return EXIT_SUCCESS; + } + PwMApplication a; + aboutData.setLicenseTextFile(LICENSE_FILE); + return a.exec(); +#else + + bool exitHelp = false; + if ( argc > 1 ) { + QString command = argv[1]; + if ( command == "-help" ){ + printf("PWM/PI command line commands:\n"); + printf(" no command: Start PWM/PI in usual way\n"); + printf(" -help: This output\n"); + printf(" PWM/PI is exiting now. Bye!\n"); + exitHelp = true; + } + } + if ( ! exitHelp ) { + + PwMApplication a(argc, argv); + + KGlobal::setAppName( "pwmanager" ); +#ifndef DESKTOP_VERSION + //US if ( QApplication::desktop()->width() > 320 ) + //US KGlobal::iconLoader()->setIconPath(QString(getenv("QPEDIR"))+"/pics/kdepim/pwmanager/icons22/"); + //US else + KGlobal::iconLoader()->setIconPath(QString(getenv("QPEDIR"))+"/pics/kdepim/pwmanager/icons16/"); +#else + QString fileName ; + fileName = qApp->applicationDirPath () + "/kdepim/pwmanager/icons22/"; + KGlobal::iconLoader()->setIconPath(QDir::convertSeparators(fileName)); + QApplication::addLibraryPath ( qApp->applicationDirPath () ); + +#endif + KStandardDirs::setAppDir( QDir::convertSeparators(locateLocal("data", "pwmanager"))); + + a.newInstance(); + + //US KAddressBookMain m ; + + //US QObject::connect(&a, SIGNAL (appMessage ( const QCString &, const QByteArray & )), ExternalAppHandler::instance(), SLOT (appMessage ( const QCString &, const QByteArray & ))); + /*US +#ifndef DESKTOP_VERSION + a.showMainWidget( &m ); +#else + a.setMainWidget( &m ); + m.resize (640, 480 ); + m.show(); +#endif + */ + a.exec(); + + } + qDebug("PWMPI: Bye! "); + +#endif + +} diff --git a/pwmanager/pwmanager/printtext.cpp b/pwmanager/pwmanager/printtext.cpp new file mode 100644 index 0000000..7590114 --- a/dev/null +++ b/pwmanager/pwmanager/printtext.cpp @@ -0,0 +1,107 @@ +/*************************************************************************** + * * + * copyright (C) 2003 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. * + * * + ***************************************************************************/ + +#include "printtext.h" +#include "pwmexception.h" + +#include + +#include + + +PrintText::PrintText() +{ + curYPos = 0; + paint = new QPainter; + metrics = new QPaintDeviceMetrics(this); +} + +PrintText::~PrintText() +{ + delete paint; + delete metrics; +} + +void PrintText::beginPrint() +{ + PWM_ASSERT(paint && metrics); + curYPos = 0; + page = 1; + paint->begin(this); + ls = paint->fontMetrics().lineSpacing(); + + // set printing border + int border = (metrics->width() / metrics->widthMM()) * 15; // 15 mm border + topLeft.setX(border); + topLeft.setY(border); + + // set body + body.setRect(topLeft.x(), ls * 2 + topLeft.y(), + metrics->width() - topLeft.x() * 2, + metrics->height() - ls * 2 - topLeft.y() * 2); + paint->setTabStops(paint->fontMetrics().width("M") * 8); + + printHeader(); +} + +void PrintText::printLine(QString t) +{ + if (curYPos == 0) + curYPos = ls * 2 + topLeft.y(); // skip header + if (t == "") + t = " "; + QRect r = paint->boundingRect(topLeft.x(), curYPos, body.width(), body.height(), + QPainter::ExpandTabs | QPainter::WordBreak, t); + int height = r.height(); + if (height + curYPos > metrics->height()) { + // next page + newPage(); + ++page; + headerRight = ""; + printHeader(); + curYPos = ls * 2 + topLeft.y(); + } + paint->drawText(topLeft.x(), curYPos, metrics->width(), metrics->height() - curYPos, + QPainter::ExpandTabs | QPainter::WordBreak, t); + curYPos += ls; +} + +void PrintText::printHeader() +{ + if (headerRight == "") + headerRight = i18n("Page #") + QString::number(page); + + paint->drawText(topLeft.x(), topLeft.y(), metrics->width() - topLeft.x() * 2, + ls, Qt::AlignLeft, headerLeft); + paint->drawText(topLeft.x(), topLeft.y(), metrics->width() - topLeft.x() * 2, + ls, Qt::AlignHCenter, headerMiddle); + paint->drawText(topLeft.x(), topLeft.y(), metrics->width() - topLeft.x() * 2, + ls, Qt::AlignRight, headerRight); + + QPen pen; + pen.setWidth(3); + paint->setPen(pen); + paint->drawLine(topLeft.x(), (ls + ls / 2) + topLeft.y(), + metrics->width() - topLeft.x(), + (ls + ls / 2) + topLeft.y()); +} + +void PrintText::setHeader(const QString &left, const QString &middle) +{ + headerLeft = left; + headerMiddle = middle; +} + +void PrintText::getHeader(QString *left, QString *middle) +{ + *left = headerLeft; + *middle = headerMiddle; +} diff --git a/pwmanager/pwmanager/printtext.h b/pwmanager/pwmanager/printtext.h new file mode 100644 index 0000000..82e31b0 --- a/dev/null +++ b/pwmanager/pwmanager/printtext.h @@ -0,0 +1,68 @@ +/*************************************************************************** + * * + * copyright (C) 2003 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. * + * * + ***************************************************************************/ + +#ifndef PRINTTEXT_H +#define PRINTTEXT_H + +#include + +#include +#include +#include +#include + +/** prints text "raw" to a printer */ +class PrintText : public KPrinter +{ +public: + PrintText(); + ~PrintText(); + + /** begin printing. Call this before drawing to the device! */ + void beginPrint(); + /** prints a line */ + void printLine(QString t); + /** returns a pointer to the paint object */ + QPainter* getPaint() + { return paint; } + /** sets the header-text */ + void setHeader(const QString &left, const QString &middle); + /** returns the header-text */ + void getHeader(QString *left, QString *middle); + +protected: + /** painter object */ + QPainter *paint; + /** metrics */ + QPaintDeviceMetrics *metrics; + /** left field of header */ + QString headerLeft; + /** middle field of header */ + QString headerMiddle; + /** right field of header */ + QString headerRight; + /** current Y-Position */ + int curYPos; + /** text-body rectangle */ + QRect body; + /** line-spacing */ + int ls; + /** top-left point for beginning printing */ + QPoint topLeft; + /** current page number */ + int page; + +protected: + /** prints the header on the page */ + void printHeader(); +}; + +#endif diff --git a/pwmanager/pwmanager/pwgenwnd.cpp b/pwmanager/pwmanager/pwgenwnd.cpp new file mode 100644 index 0000000..bb1ab92 --- a/dev/null +++ b/pwmanager/pwmanager/pwgenwnd.cpp @@ -0,0 +1,187 @@ +/**************************************************************************** +** Form implementation generated from reading ui file 'pwgenwnd.ui' +** +** Created: Tue Sep 14 15:34:41 2004 +** by: The User Interface Compiler ($Id$) +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ + +#include "pwgenwnd.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Constructs a pwGenWnd as a child of 'parent', with the + * name 'name' and widget flags set to 'f'. + * + * The dialog will by default be modeless, unless you set 'modal' to + * TRUE to construct a modal dialog. + */ +pwGenWnd::pwGenWnd( QWidget* parent, const char* name, bool modal, WFlags fl ) + : QDialog( parent, name, modal, fl ) +{ + if ( !name ) + setName( "pwGenWnd" ); + pwGenWndLayout = new QVBoxLayout( this, 11, 6, "pwGenWndLayout"); + + groupBox1 = new QGroupBox( this, "groupBox1" ); + groupBox1->setColumnLayout(0, Qt::Vertical ); + groupBox1->layout()->setSpacing( 6 ); + groupBox1->layout()->setMargin( 11 ); + groupBox1Layout = new QVBoxLayout( groupBox1->layout() ); + groupBox1Layout->setAlignment( Qt::AlignTop ); + + layout2 = new QHBoxLayout( 0, 0, 6, "layout2"); + + int_charLowerCheckBox = new QCheckBox( groupBox1, "int_charLowerCheckBox" ); + int_charLowerCheckBox->setChecked( TRUE ); + layout2->addWidget( int_charLowerCheckBox ); + spacer1 = new QSpacerItem( 40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ); + layout2->addItem( spacer1 ); + + textLabel4 = new QLabel( groupBox1, "textLabel4" ); + layout2->addWidget( textLabel4 ); + groupBox1Layout->addLayout( layout2 ); + + layout3 = new QHBoxLayout( 0, 0, 6, "layout3"); + + int_charUpperCheckBox = new QCheckBox( groupBox1, "int_charUpperCheckBox" ); + int_charUpperCheckBox->setChecked( TRUE ); + layout3->addWidget( int_charUpperCheckBox ); + spacer2 = new QSpacerItem( 40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ); + layout3->addItem( spacer2 ); + + textLabel5 = new QLabel( groupBox1, "textLabel5" ); + layout3->addWidget( textLabel5 ); + groupBox1Layout->addLayout( layout3 ); + + layout4 = new QHBoxLayout( 0, 0, 6, "layout4"); + + int_charNumCheckBox = new QCheckBox( groupBox1, "int_charNumCheckBox" ); + int_charNumCheckBox->setChecked( TRUE ); + layout4->addWidget( int_charNumCheckBox ); + spacer3 = new QSpacerItem( 40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ); + layout4->addItem( spacer3 ); + + textLabel6 = new QLabel( groupBox1, "textLabel6" ); + layout4->addWidget( textLabel6 ); + groupBox1Layout->addLayout( layout4 ); + + layout6 = new QHBoxLayout( 0, 0, 6, "layout6"); + + int_charSpecCheckBox = new QCheckBox( groupBox1, "int_charSpecCheckBox" ); + layout6->addWidget( int_charSpecCheckBox ); + spacer4 = new QSpacerItem( 40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ); + layout6->addItem( spacer4 ); + + textLabel7 = new QLabel( groupBox1, "textLabel7" ); + layout6->addWidget( textLabel7 ); + groupBox1Layout->addLayout( layout6 ); + + int_charBlankCheckBox = new QCheckBox( groupBox1, "int_charBlankCheckBox" ); + groupBox1Layout->addWidget( int_charBlankCheckBox ); + + layout7 = new QHBoxLayout( 0, 0, 6, "layout7"); + + int_charUserCheckBox = new QCheckBox( groupBox1, "int_charUserCheckBox" ); + layout7->addWidget( int_charUserCheckBox ); + spacer5 = new QSpacerItem( 40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum ); + layout7->addItem( spacer5 ); + + int_userDefLineEdit = new QLineEdit( groupBox1, "int_userDefLineEdit" ); + int_userDefLineEdit->setEnabled( FALSE ); + layout7->addWidget( int_userDefLineEdit ); + groupBox1Layout->addLayout( layout7 ); + pwGenWndLayout->addWidget( groupBox1 ); + + layout8 = new QHBoxLayout( 0, 0, 6, "layout8"); + + textLabel2 = new QLabel( this, "textLabel2" ); + layout8->addWidget( textLabel2 ); + + int_lenSpinBox = new QSpinBox( this, "int_lenSpinBox" ); + int_lenSpinBox->setMaxValue( 9999 ); + int_lenSpinBox->setMinValue( 1 ); + int_lenSpinBox->setValue( 8 ); + layout8->addWidget( int_lenSpinBox ); + pwGenWndLayout->addLayout( layout8 ); + + int_filterCheckBox = new QCheckBox( this, "int_filterCheckBox" ); + int_filterCheckBox->setChecked( TRUE ); + pwGenWndLayout->addWidget( int_filterCheckBox ); + + layout1 = new QHBoxLayout( 0, 0, 6, "layout1"); + + genButton = new QPushButton( this, "genButton" ); + layout1->addWidget( genButton ); + + cancelButton = new QPushButton( this, "cancelButton" ); + layout1->addWidget( cancelButton ); + pwGenWndLayout->addLayout( layout1 ); + languageChange(); + resize( QSize(450, 349).expandedTo(minimumSizeHint()) ); + clearWState( WState_Polished ); + + // signals and slots connections + connect( int_charUserCheckBox, SIGNAL( toggled(bool) ), int_userDefLineEdit, SLOT( setEnabled(bool) ) ); + connect( cancelButton, SIGNAL( clicked() ), this, SLOT( cancelButton_slot() ) ); + connect( genButton, SIGNAL( clicked() ), this, SLOT( genButton_slot() ) ); +} + +/* + * Destroys the object and frees any allocated resources + */ +pwGenWnd::~pwGenWnd() +{ + // no need to delete child widgets, Qt does it all for us +} + +/* + * Sets the strings of the subwidgets using the current + * language. + */ +void pwGenWnd::languageChange() +{ + setCaption( tr( "Password generator" ) ); + groupBox1->setTitle( tr( "Character set:" ) ); + int_charLowerCheckBox->setText( tr( "Lowercase:" ) ); + textLabel4->setText( tr( "abc" ) ); + int_charUpperCheckBox->setText( tr( "Uppercase:" ) ); + textLabel5->setText( tr( "ABC" ) ); + int_charNumCheckBox->setText( tr( "Numbers:" ) ); + textLabel6->setText( tr( "123" ) ); + int_charSpecCheckBox->setText( tr( "Special characters:" ) ); +#ifndef PWM_EMBEDDED + textLabel7->setText( trUtf8( "\x21\x22\xc2\xa7\x24\x25\x26\x2f\x28\x29\x3d\x3f\x2c\x2e\x2d\x3b\x3a\x5f\x2b" ) ); +#else + QString st("\x21\x22\xc2\xa7\x24\x25\x26\x2f\x28\x29\x3d\x3f\x2c\x2e\x2d\x3b\x3a\x5f\x2b"); + textLabel7->setText( st.utf8() ); +#endif + int_charBlankCheckBox->setText( tr( "Spaces (blank characters)" ) ); + int_charUserCheckBox->setText( tr( "User defined:" ) ); + textLabel2->setText( tr( "Password Length:" ) ); + int_filterCheckBox->setText( tr( "Enable Filtering to get better passwords" ) ); + genButton->setText( tr( "&Generate now" ) ); + cancelButton->setText( tr( "&Cancel" ) ); +} + +void pwGenWnd::cancelButton_slot() +{ + qWarning( "pwGenWnd::cancelButton_slot(): Not implemented yet" ); +} + +void pwGenWnd::genButton_slot() +{ + qWarning( "pwGenWnd::genButton_slot(): Not implemented yet" ); +} + diff --git a/pwmanager/pwmanager/pwgenwnd.h b/pwmanager/pwmanager/pwgenwnd.h new file mode 100644 index 0000000..3403d78 --- a/dev/null +++ b/pwmanager/pwmanager/pwgenwnd.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** Form interface generated from reading ui file 'pwgenwnd.ui' +** +** Created: Tue Sep 14 15:32:37 2004 +** by: The User Interface Compiler ($Id$) +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ + +#ifndef PWGENWND_H +#define PWGENWND_H + +#include +#include + +class QVBoxLayout; +class QHBoxLayout; +class QGridLayout; +class QSpacerItem; +class QGroupBox; +class QCheckBox; +class QLabel; +class QLineEdit; +class QSpinBox; +class QPushButton; + +class pwGenWnd : public QDialog +{ + Q_OBJECT + +public: + pwGenWnd( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~pwGenWnd(); + + QGroupBox* groupBox1; + QCheckBox* int_charLowerCheckBox; + QLabel* textLabel4; + QCheckBox* int_charUpperCheckBox; + QLabel* textLabel5; + QCheckBox* int_charNumCheckBox; + QLabel* textLabel6; + QCheckBox* int_charSpecCheckBox; + QLabel* textLabel7; + QCheckBox* int_charBlankCheckBox; + QCheckBox* int_charUserCheckBox; + QLineEdit* int_userDefLineEdit; + QLabel* textLabel2; + QSpinBox* int_lenSpinBox; + QCheckBox* int_filterCheckBox; + QPushButton* genButton; + QPushButton* cancelButton; + +public slots: + virtual void cancelButton_slot(); + virtual void genButton_slot(); + +protected: + QVBoxLayout* pwGenWndLayout; + QVBoxLayout* groupBox1Layout; + QHBoxLayout* layout2; + QSpacerItem* spacer1; + QHBoxLayout* layout3; + QSpacerItem* spacer2; + QHBoxLayout* layout4; + QSpacerItem* spacer3; + QHBoxLayout* layout6; + QSpacerItem* spacer4; + QHBoxLayout* layout7; + QSpacerItem* spacer5; + QHBoxLayout* layout8; + QHBoxLayout* layout1; + +protected slots: + virtual void languageChange(); + +}; + +#endif // PWGENWND_H diff --git a/pwmanager/pwmanager/pwgenwnd.ui b/pwmanager/pwmanager/pwgenwnd.ui new file mode 100644 index 0000000..cde874b --- a/dev/null +++ b/pwmanager/pwmanager/pwgenwnd.ui @@ -0,0 +1,363 @@ + +pwGenWnd + + + pwGenWnd + + + + 0 + 0 + 450 + 349 + + + + Password generator + + + + unnamed + + + + groupBox1 + + + Character set: + + + + unnamed + + + + layout2 + + + + unnamed + + + + int_charLowerCheckBox + + + Lowercase: + + + true + + + + + spacer1 + + + Horizontal + + + Expanding + + + + 40 + 20 + + + + + + textLabel4 + + + abc + + + + + + + layout3 + + + + unnamed + + + + int_charUpperCheckBox + + + Uppercase: + + + true + + + + + spacer2 + + + Horizontal + + + Expanding + + + + 40 + 20 + + + + + + textLabel5 + + + ABC + + + + + + + layout4 + + + + unnamed + + + + int_charNumCheckBox + + + Numbers: + + + true + + + + + spacer3 + + + Horizontal + + + Expanding + + + + 40 + 20 + + + + + + textLabel6 + + + 123 + + + + + + + layout6 + + + + unnamed + + + + int_charSpecCheckBox + + + Special characters: + + + + + spacer4 + + + Horizontal + + + Expanding + + + + 40 + 20 + + + + + + textLabel7 + + + !"§$%&/()=?,.-;:_+ + + + + + + + int_charBlankCheckBox + + + Spaces (blank characters) + + + + + layout7 + + + + unnamed + + + + int_charUserCheckBox + + + User defined: + + + + + spacer5 + + + Horizontal + + + Expanding + + + + 40 + 20 + + + + + + int_userDefLineEdit + + + false + + + + + + + + + layout8 + + + + unnamed + + + + textLabel2 + + + Password Length: + + + + + int_lenSpinBox + + + 9999 + + + 1 + + + 8 + + + + + + + int_filterCheckBox + + + Enable Filtering to get better passwords + + + true + + + + + layout1 + + + + unnamed + + + + genButton + + + &Generate now + + + + + cancelButton + + + &Cancel + + + + + + + + + int_charUserCheckBox + toggled(bool) + int_userDefLineEdit + setEnabled(bool) + + + cancelButton + clicked() + pwGenWnd + cancelButton_slot() + + + genButton + clicked() + pwGenWnd + genButton_slot() + + + + cancelButton_slot() + genButton_slot() + + + diff --git a/pwmanager/pwmanager/pwgenwndimpl.cpp b/pwmanager/pwmanager/pwgenwndimpl.cpp new file mode 100644 index 0000000..01f5740 --- a/dev/null +++ b/pwmanager/pwmanager/pwgenwndimpl.cpp @@ -0,0 +1,112 @@ +/*************************************************************************** + * * + * 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 "pwgenwndimpl.h" +#include "pwmexception.h" +#include "genpasswd.h" + +#include +#include +#include +#include + +#include +#include + + +PwGenWndImpl::PwGenWndImpl(QWidget *parent, + const char *name, + bool modal, + WFlags fl) + : pwGenWnd(parent, name, modal, fl) +{ +} + +PwGenWndImpl::~PwGenWndImpl() +{ +} + +void PwGenWndImpl::genButton_slot() +{ + // internal generator + if (!optionsSanityIntGen()) + return; + if (startIntGen()) + goto exit_success; + done(0); +exit_success: + done(1); +} + +void PwGenWndImpl::cancelButton_slot() +{ + done(0); +} + +bool PwGenWndImpl::optionsSanityIntGen() +{ + if (int_charLowerCheckBox->isChecked()) + return true; + if (int_charUpperCheckBox->isChecked()) + return true; + if (int_charNumCheckBox->isChecked()) + return true; + if (int_charSpecCheckBox->isChecked()) + return true; + if (int_charUserCheckBox->isChecked()) { + if (int_userDefLineEdit->text().length() >= 2) + return true; + if (int_charBlankCheckBox->isChecked()) + return true; + } + KMessageBox::error(this, + i18n("Incorrect Charset selection!\n" + "It's impossible to generate a sane " + "password with the selected charset(s).\n" + "Please select more charsets."), + i18n("Incorrect Charset selection")); + return false; +} + +bool PwGenWndImpl::startIntGen() +{ + GenPasswd gen; + gen.setLen(int_lenSpinBox->value()); + gen.setUseFilter(int_filterCheckBox->isChecked()); + gen.setCharset(int_charLowerCheckBox->isChecked(), + int_charUpperCheckBox->isChecked(), + int_charNumCheckBox->isChecked(), + int_charSpecCheckBox->isChecked(), + int_charBlankCheckBox->isChecked(), + int_charUserCheckBox->isChecked() ? + int_userDefLineEdit->text() : + QString::null); + QString pw(gen.gen()); + if (pw.isEmpty()) + return false; + password = pw; + return true; +} + +QString PwGenWndImpl::getPassword() +{ + QString ret(password); + password = QString::null; + return ret; +} diff --git a/pwmanager/pwmanager/pwgenwndimpl.h b/pwmanager/pwmanager/pwgenwndimpl.h new file mode 100644 index 0000000..5c25643 --- a/dev/null +++ b/pwmanager/pwmanager/pwgenwndimpl.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * * + * 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 __PWGENWNDIMPL_H +#define __PWGENWNDIMPL_H + +#include "pwgenwnd.h" + +class PwGenWndImpl : public pwGenWnd +{ +public: + PwGenWndImpl(QWidget *parent = 0, + const char *name = 0, + bool modal = FALSE, + WFlags fl = 0); + ~PwGenWndImpl(); + + /** returns the generated password */ + QString getPassword(); + +protected slots: + /** generate button pressed */ + void genButton_slot(); + /** cancel button pressed */ + void cancelButton_slot(); + +protected: + /** start the internal generator */ + bool startIntGen(); + /** check all options of the internal generator */ + bool optionsSanityIntGen(); + +protected: + /** the generated password */ + QString password; +}; + +#endif // __PWGENWNDIMPL_H diff --git a/pwmanager/pwmanager/pwm.cpp b/pwmanager/pwmanager/pwm.cpp new file mode 100644 index 0000000..0e57650 --- a/dev/null +++ b/pwmanager/pwmanager/pwm.cpp @@ -0,0 +1,1192 @@ +/*************************************************************************** + * * + * 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$ + **************************************************************************/ + +#include +#include +#include +#include +#include +#include + +#ifndef PWM_EMBEDDED +#include +#include +#include +#else +#include +#endif + +#include +#include +#include +#include +#include +#include + + +#include + +#include "pwm.h" +#include "pwminit.h" +#include "configwndimpl.h" +#include "pwmprint.h" +#include "addentrywndimpl.h" +#include "globalstuff.h" +#include "findwndimpl.h" +#include "configuration.h" + +#ifdef CONFIG_KWALLETIF +# include "kwalletif.h" +# include "kwalletemu.h" +#endif +#ifdef CONFIG_KEYCARD +# include "pwmkeycard.h" +#endif + + +#define DEFAULT_SIZE (QSize(700, 400)) + +// Button IDs for "file" popup menu +enum { + BUTTON_POPUP_FILE_NEW = 0, + BUTTON_POPUP_FILE_OPEN, + BUTTON_POPUP_FILE_CLOSE, + BUTTON_POPUP_FILE_SAVE, + BUTTON_POPUP_FILE_SAVEAS, + BUTTON_POPUP_FILE_EXPORT, + BUTTON_POPUP_FILE_IMPORT, + BUTTON_POPUP_FILE_PRINT, + BUTTON_POPUP_FILE_QUIT +}; +// Button IDs for "manage" popup menu +enum { + BUTTON_POPUP_MANAGE_ADD = 0, + BUTTON_POPUP_MANAGE_EDIT, + BUTTON_POPUP_MANAGE_DEL, + BUTTON_POPUP_MANAGE_CHANGEMP +}; +// Button IDs for chipcard popup menu +enum { +#ifdef CONFIG_KEYCARD + BUTTON_POPUP_CHIPCARD_GENNEW = 0, + BUTTON_POPUP_CHIPCARD_DEL, + BUTTON_POPUP_CHIPCARD_READID, + BUTTON_POPUP_CHIPCARD_SAVEBACKUP, + BUTTON_POPUP_CHIPCARD_REPLAYBACKUP +#else // CONFIG_KEYCARD + BUTTON_POPUP_CHIPCARD_NO = 0 +#endif // CONFIG_KEYCARD +}; +// Button IDs for "view" popup menu +enum { + BUTTON_POPUP_VIEW_FIND = 0, + BUTTON_POPUP_VIEW_LOCK, + BUTTON_POPUP_VIEW_DEEPLOCK, + BUTTON_POPUP_VIEW_UNLOCK +}; +// Button IDs for "options" popup menu +enum { + BUTTON_POPUP_OPTIONS_CONFIG = 0 +}; +// Button IDs for "export" popup menu (in "file" popup menu) +enum { + BUTTON_POPUP_EXPORT_TEXT = 0, + BUTTON_POPUP_EXPORT_GPASMAN +#ifdef CONFIG_KWALLETIF + ,BUTTON_POPUP_EXPORT_KWALLET +#endif +}; +// Button IDs for "import" popup menu (in "file" popup menu) +enum { + BUTTON_POPUP_IMPORT_TEXT = 0, + BUTTON_POPUP_IMPORT_GPASMAN +#ifdef CONFIG_KWALLETIF + ,BUTTON_POPUP_IMPORT_KWALLET +#endif +}; +// Button IDs for toolbar +enum { + BUTTON_TOOL_NEW = 0, + BUTTON_TOOL_OPEN, + BUTTON_TOOL_SAVE, + BUTTON_TOOL_SAVEAS, + BUTTON_TOOL_PRINT, + BUTTON_TOOL_ADD, + BUTTON_TOOL_EDIT, + BUTTON_TOOL_DEL, + BUTTON_TOOL_FIND, + BUTTON_TOOL_LOCK, + BUTTON_TOOL_DEEPLOCK, + BUTTON_TOOL_UNLOCK +}; + + +PwM::PwM(PwMInit *_init, PwMDoc *doc, + bool virginity, + QWidget *parent, const char *name) + : KMainWindow(parent, name) + , forceQuit (false) + , forceMinimizeToTray (false) +{ + init = _init; + connect(doc, SIGNAL(docClosed(PwMDoc *)), + this, SLOT(docClosed(PwMDoc *))); + initMenubar(); + initToolbar(); + initMetrics(); + setVirgin(virginity); + setFocusPolicy(QWidget::WheelFocus); +#ifndef PWM_EMBEDDED + statusBar()->show(); +#endif + view = makeNewListView(doc); + setCentralWidget(view); + updateCaption(); + showStatMsg(i18n("Ready.")); +} + +PwM::~PwM() +{ + disconnect(curDoc(), SIGNAL(docClosed(PwMDoc *)), + this, SLOT(docClosed(PwMDoc *))); + conf()->confWndMainWndSize(size()); + emit closed(this); + delete view; +} + +void PwM::initMenubar() +{ + KIconLoader icons; + + filePopup = new KPopupMenu(this); + importPopup = new KPopupMenu(filePopup); + exportPopup = new KPopupMenu(filePopup); + managePopup = new KPopupMenu(this); +#ifdef CONFIG_KEYCARD + chipcardPopup = new KPopupMenu(this); +#endif // CONFIG_KEYCARD + viewPopup = new KPopupMenu(this); + optionsPopup = new KPopupMenu(this); + +// "file" popup menu + filePopup->insertItem(QIconSet(icons.loadIcon("filenew", KIcon::Small)), + i18n("&New"), this, + SLOT(new_slot()), 0, BUTTON_POPUP_FILE_NEW); + filePopup->insertItem(QIconSet(icons.loadIcon("fileopen", KIcon::Small)), + i18n("&Open"), this, + SLOT(open_slot()), 0, BUTTON_POPUP_FILE_OPEN); + filePopup->insertItem(QIconSet(icons.loadIcon("fileclose", KIcon::Small)), + i18n("&Close"), this, + SLOT(close_slot()), 0, BUTTON_POPUP_FILE_CLOSE); + filePopup->insertSeparator(); + filePopup->insertItem(QIconSet(icons.loadIcon("filesave", KIcon::Small)), + i18n("&Save"), this, + SLOT(save_slot()), 0, BUTTON_POPUP_FILE_SAVE); + filePopup->insertItem(QIconSet(icons.loadIcon("filesaveas", KIcon::Small)), + i18n("Save &as..."), + this, SLOT(saveAs_slot()), 0, + BUTTON_POPUP_FILE_SAVEAS); + filePopup->insertSeparator(); + // "file/export" popup menu + exportPopup->insertItem(i18n("&Text-file..."), this, + SLOT(exportToText()), 0, BUTTON_POPUP_EXPORT_TEXT); + exportPopup->insertItem(i18n("&Gpasman / Kpasman ..."), this, + SLOT(exportToGpasman()), 0, BUTTON_POPUP_EXPORT_GPASMAN); +#ifdef CONFIG_KWALLETIF + exportPopup->insertItem(i18n("&KWallet..."), this, + SLOT(exportToKWallet()), 0, BUTTON_POPUP_EXPORT_KWALLET); +#endif + filePopup->insertItem(QIconSet(icons.loadIcon("fileexport", KIcon::Small)), + i18n("E&xport"), exportPopup, + BUTTON_POPUP_FILE_EXPORT); + // "file/import" popup menu + importPopup->insertItem(i18n("&Text-file..."), this, + SLOT(importFromText()), 0, BUTTON_POPUP_IMPORT_TEXT); + importPopup->insertItem(i18n("&Gpasman / Kpasman ..."), this, + SLOT(importFromGpasman()), 0, BUTTON_POPUP_IMPORT_GPASMAN); +#ifdef CONFIG_KWALLETIF + importPopup->insertItem(i18n("&KWallet..."), this, + SLOT(importKWallet()), 0, BUTTON_POPUP_IMPORT_KWALLET); +#endif + filePopup->insertItem(QIconSet(icons.loadIcon("fileimport", KIcon::Small)), + i18n("I&mport"), importPopup, + BUTTON_POPUP_FILE_IMPORT); + filePopup->insertSeparator(); + filePopup->insertItem(QIconSet(icons.loadIcon("fileprint", KIcon::Small)), + i18n("&Print..."), this, + SLOT(print_slot()), 0, BUTTON_POPUP_FILE_PRINT); + filePopup->insertSeparator(); + filePopup->insertItem(QIconSet(icons.loadIcon("exit", KIcon::Small)), + i18n("&Quit"), this, + SLOT(quitButton_slot()), 0, BUTTON_POPUP_FILE_QUIT); + menuBar()->insertItem(i18n("&File"), filePopup); +// "manage" popup menu + managePopup->insertItem(QIconSet(icons.loadIcon("pencil", KIcon::Small)), + i18n("&Add password"), this, + SLOT(addPwd_slot()), 0, + BUTTON_POPUP_MANAGE_ADD); + managePopup->insertItem(QIconSet(icons.loadIcon("edit", KIcon::Small)), + i18n("&Edit"), this, SLOT(editPwd_slot()), 0, + BUTTON_POPUP_MANAGE_EDIT); + managePopup->insertItem(QIconSet(icons.loadIcon("editdelete", KIcon::Small)), + i18n("&Delete"), this, SLOT(deletePwd_slot()), + 0, BUTTON_POPUP_MANAGE_DEL); + managePopup->insertSeparator(); + managePopup->insertItem(QIconSet(icons.loadIcon("rotate", KIcon::Small)), + i18n("Change &Master Password"), this, + SLOT(changeMasterPwd_slot()), 0, + BUTTON_POPUP_MANAGE_CHANGEMP); + menuBar()->insertItem(i18n("&Manage"), managePopup); +// "chipcard" popup menu +#ifdef CONFIG_KEYCARD + chipcardPopup->insertItem(QIconSet(icons.loadIcon("filenew", KIcon::Small)), + i18n("&Generate new key-card"), this, + SLOT(genNewCard_slot()), 0, + BUTTON_POPUP_CHIPCARD_GENNEW); + chipcardPopup->insertItem(QIconSet(icons.loadIcon("editdelete", KIcon::Small)), + i18n("&Erase key-card"), this, + SLOT(eraseCard_slot()), 0, + BUTTON_POPUP_CHIPCARD_DEL); + chipcardPopup->insertItem(QIconSet(icons.loadIcon("", KIcon::Small)), + i18n("Read card-&ID"), this, + SLOT(readCardId_slot()), 0, + BUTTON_POPUP_CHIPCARD_READID); + chipcardPopup->insertSeparator(); + chipcardPopup->insertItem(QIconSet(icons.loadIcon("2rightarrow", KIcon::Small)), + i18n("&Make card backup-image"), this, + SLOT(makeCardBackup_slot()), 0, + BUTTON_POPUP_CHIPCARD_SAVEBACKUP); + chipcardPopup->insertItem(QIconSet(icons.loadIcon("2leftarrow", KIcon::Small)), + i18n("&Replay card backup-image"), this, + SLOT(replayCardBackup_slot()), 0, + BUTTON_POPUP_CHIPCARD_REPLAYBACKUP); + menuBar()->insertItem(i18n("&Chipcard manager"), chipcardPopup); +#endif // CONFIG_KEYCARD +// "view" popup menu + viewPopup->insertItem(QIconSet(icons.loadIcon("find", KIcon::Small)), + i18n("&Find"), this, + SLOT(find_slot()), 0, BUTTON_POPUP_VIEW_FIND); + viewPopup->insertSeparator(); + viewPopup->insertItem(QIconSet(icons.loadIcon("halfencrypted", KIcon::Small)), + i18n("&Lock all entries"), this, + SLOT(lockWnd_slot()), 0, + BUTTON_POPUP_VIEW_LOCK); + viewPopup->insertItem(QIconSet(icons.loadIcon("encrypted", KIcon::Small)), + i18n("&Deep-lock all entries"), this, + SLOT(deepLockWnd_slot()), 0, + BUTTON_POPUP_VIEW_DEEPLOCK); + viewPopup->insertItem(QIconSet(icons.loadIcon("decrypted", KIcon::Small)), + i18n("&Unlock all entries"), this, + SLOT(unlockWnd_slot()), 0, + BUTTON_POPUP_VIEW_UNLOCK); + menuBar()->insertItem(i18n("&View"), viewPopup); +// "options" popup menu + optionsPopup->insertItem(QIconSet(icons.loadIcon("configure", KIcon::Small)), + i18n("&Configure..."), this, + SLOT(config_slot()), + BUTTON_POPUP_OPTIONS_CONFIG); + menuBar()->insertItem(i18n("&Options"), optionsPopup); +// "help" popup menu +#ifndef PWM_EMBEDDED + helpPopup = helpMenu(QString::null, false); + menuBar()->insertItem(i18n("&Help"), helpPopup); +#endif +} + +void PwM::initToolbar() +{ + KIconLoader icons; + + toolBar()->insertButton(icons.loadIcon("filenew", KIcon::Toolbar), + BUTTON_TOOL_NEW, SIGNAL(clicked(int)), this, + SLOT(new_slot()), true, i18n("New")); + toolBar()->insertButton(icons.loadIcon("fileopen", KIcon::Toolbar), + BUTTON_TOOL_OPEN, SIGNAL(clicked(int)), this, + SLOT(open_slot()), true, i18n("Open")); + toolBar()->insertSeparator(); + toolBar()->insertButton(icons.loadIcon("filesave", KIcon::Toolbar), + BUTTON_TOOL_SAVE, SIGNAL(clicked(int)), this, + SLOT(save_slot()), true, i18n("Save")); + toolBar()->insertButton(icons.loadIcon("filesaveas", KIcon::Toolbar), + BUTTON_TOOL_SAVEAS, SIGNAL(clicked(int)), this, + SLOT(saveAs_slot()), true, i18n("Save as")); + toolBar()->insertButton(icons.loadIcon("fileprint", KIcon::Toolbar), + BUTTON_TOOL_PRINT, SIGNAL(clicked(int)), this, + SLOT(print_slot()), true, i18n("Print...")); + toolBar()->insertSeparator(); + toolBar()->insertButton(icons.loadIcon("pencil", KIcon::Toolbar), + BUTTON_TOOL_ADD, SIGNAL(clicked(int)), this, + SLOT(addPwd_slot()), true, + i18n("Add password")); + toolBar()->insertButton(icons.loadIcon("edit", KIcon::Toolbar), + BUTTON_TOOL_EDIT, SIGNAL(clicked(int)), this, + SLOT(editPwd_slot()), true, + i18n("Edit password")); + toolBar()->insertButton(icons.loadIcon("editdelete", KIcon::Toolbar), + BUTTON_TOOL_DEL, SIGNAL(clicked(int)), this, + SLOT(deletePwd_slot()), true, + i18n("Delete password")); + toolBar()->insertSeparator(); + toolBar()->insertButton(icons.loadIcon("find", KIcon::Toolbar), + BUTTON_TOOL_FIND, SIGNAL(clicked(int)), this, + SLOT(find_slot()), true, i18n("Find entry")); + toolBar()->insertSeparator(); + toolBar()->insertButton(icons.loadIcon("halfencrypted", KIcon::Toolbar), + BUTTON_TOOL_LOCK, SIGNAL(clicked(int)), this, + SLOT(lockWnd_slot()), true, + i18n("Lock all entries")); + toolBar()->insertButton(icons.loadIcon("encrypted", KIcon::Toolbar), + BUTTON_TOOL_DEEPLOCK, SIGNAL(clicked(int)), this, + SLOT(deepLockWnd_slot()), true, + i18n("Deep-Lock all entries")); + toolBar()->insertButton(icons.loadIcon("decrypted", KIcon::Toolbar), + BUTTON_TOOL_UNLOCK, SIGNAL(clicked(int)), this, + SLOT(unlockWnd_slot()), true, + i18n("Unlock all entries")); +} + +void PwM::initMetrics() +{ + QSize s = conf()->confWndMainWndSize(); + if (s.isValid()) + resize(s); + else + resize(DEFAULT_SIZE); +} + +void PwM::updateCaption() +{ + setPlainCaption(curDoc()->getTitle() + " - " PROG_NAME " " PACKAGE_VER); +} + +void PwM::hideEvent(QHideEvent *) +{ + if (isMinimized()) { + if (init->tray()) { + forceMinimizeToTray = true; + close(); + } + int mmlock = conf()->confGlobMinimizeLock(); + switch (mmlock) { + case 0: // don't lock anything + break; + case 1: { // normal lock + curDoc()->lockAll(true); + break; + } case 2: { // deep-lock + curDoc()->deepLock(); + break; + } default: + WARN(); + } + } +} + +void PwM::setVirgin(bool v) +{ + if (virgin == v) + return; + virgin = v; + filePopup->setItemEnabled(BUTTON_POPUP_FILE_SAVE, !v); + filePopup->setItemEnabled(BUTTON_POPUP_FILE_SAVEAS, !v); + filePopup->setItemEnabled(BUTTON_POPUP_FILE_EXPORT, !v); + filePopup->setItemEnabled(BUTTON_POPUP_FILE_PRINT, !v); + managePopup->setItemEnabled(BUTTON_POPUP_MANAGE_EDIT, !v); + managePopup->setItemEnabled(BUTTON_POPUP_MANAGE_DEL, !v); + managePopup->setItemEnabled(BUTTON_POPUP_MANAGE_CHANGEMP, !v); + viewPopup->setItemEnabled(BUTTON_POPUP_VIEW_LOCK, !v); + viewPopup->setItemEnabled(BUTTON_POPUP_VIEW_DEEPLOCK, !v); + viewPopup->setItemEnabled(BUTTON_POPUP_VIEW_UNLOCK, !v); + viewPopup->setItemEnabled(BUTTON_POPUP_VIEW_FIND, !v); + toolBar()->setItemEnabled(BUTTON_TOOL_SAVE, !v); + toolBar()->setItemEnabled(BUTTON_TOOL_SAVEAS, !v); + toolBar()->setItemEnabled(BUTTON_TOOL_PRINT, !v); + toolBar()->setItemEnabled(BUTTON_TOOL_EDIT, !v); + toolBar()->setItemEnabled(BUTTON_TOOL_DEL, !v); + toolBar()->setItemEnabled(BUTTON_TOOL_LOCK, !v); + toolBar()->setItemEnabled(BUTTON_TOOL_DEEPLOCK, !v); + toolBar()->setItemEnabled(BUTTON_TOOL_UNLOCK, !v); + toolBar()->setItemEnabled(BUTTON_TOOL_FIND, !v); +} + +void PwM::new_slot() +{ + init->createMainWnd(); +} + +//US ENH +void PwM::open_slot() +{ + open_slot(""); +} + +void PwM::open_slot(QString fn) +{ + openDoc(fn); +} + +PwMDoc * PwM::openDoc(QString filename, bool openDeepLocked) +{ + if (!isVirgin()) { + // open the document in a new window. + PwM *newInstance = init->createMainWnd(); + PwMDoc *newDoc = newInstance->openDoc(filename, openDeepLocked); + if (!newDoc) { + newInstance->setForceQuit(true); + delete_and_null(newInstance); + } + return newDoc; + } + + if (!curDoc()->openDocUi(curDoc(), filename, openDeepLocked)) + return 0; + showStatMsg(i18n("Successfully opened file.")); + updateCaption(); + setVirgin(false); + return curDoc(); +} + +PwMView * PwM::makeNewListView(PwMDoc *doc) +{ + PwMView *ret = new PwMView(this, this, doc); + ret->setFont(conf()->confGlobEntryFont()); + ret->show(); + return ret; +} + +void PwM::close_slot() +{ + close(); +} + +void PwM::quitButton_slot() +{ + init->shutdownApp(0); +} + +void PwM::save_slot() +{ + save(); +} + +bool PwM::save() +{ + if (!curDoc()->saveDocUi(curDoc())) + return false; + showStatMsg(i18n("Successfully saved data.")); + updateCaption(); + return true; +} + +void PwM::saveAs_slot() +{ + saveAs(); +} + +bool PwM::saveAs() +{ + if (!curDoc()->saveAsDocUi(curDoc())) + return false; + showStatMsg(i18n("Successfully saved data.")); + updateCaption(); + return true; +} + +//US ENH : changed code to run with older MOC +void PwM::addPwd_slot() +{ + addPwd_slot(0, 0); +} + +void PwM::addPwd_slot(QString *pw, PwMDoc *_doc) +{ + PwMDoc *doc; + if (_doc) { + doc = _doc; + } else { + doc = curDoc(); + } + PWM_ASSERT(doc); + doc->timer()->getLock(DocTimer::id_autoLockTimer); + AddEntryWndImpl w; + vector catList; + doc->getCategoryList(&catList); + unsigned i, size = catList.size(); + for (i = 0; i < size; ++i) { + w.addCategory(catList[i].c_str()); + } + w.setCurrCategory(view->getCurrentCategory()); + if (pw) + w.pwLineEdit->setText(*pw); + + tryAgain: + if (w.exec() == 1) { + PwMDataItem d; + d.desc = w.getDescription().latin1(); + d.name = w.getUsername().latin1(); + d.pw = w.getPassword().latin1(); + d.comment = w.getComment().latin1(); + d.url = w.getUrl().latin1(); + d.launcher = w.getLauncher().latin1(); + PwMerror ret = doc->addEntry(w.getCategory(), &d); + if (ret == e_entryExists) { + KMessageBox::error(this, + i18n + ("An entry with this \"Description\", " + "does already exist.\n" + "Please select another description."), + i18n("entry already exists.")); + goto tryAgain; + } else if (ret == e_maxAllowedEntr) { + KMessageBox::error(this, i18n("The maximum possible number of entries " + "has been reached. You can't add more entries."), + i18n("maximum number of entries")); + doc->timer()->putLock(DocTimer::id_autoLockTimer); + return; + } + } + setVirgin(false); + doc->timer()->putLock(DocTimer::id_autoLockTimer); +} + +//US ENH : changed code to run with older MOC +void PwM::editPwd_slot() +{ + editPwd_slot(0,0,0); +} + +void PwM::editPwd_slot(const QString *category) +{ + editPwd_slot(category, 0, 0); +} + +void PwM::editPwd_slot(const QString *category, const int *index, + PwMDoc *_doc) +{ + PwMDoc *doc; + if (_doc) { + doc = _doc; + } else { + doc = curDoc(); + } + PWM_ASSERT(doc); + if (doc->isDocEmpty()) + return; + if (doc->isDeepLocked()) + return; + doc->timer()->getLock(DocTimer::id_autoLockTimer); + unsigned int curEntryIndex; + if (index) { + curEntryIndex = *index; + } else { + if (!(view->getCurEntryIndex(&curEntryIndex))) { + printDebug("couldn't get index. Maybe we have a binary entry here."); + doc->timer()->putLock(DocTimer::id_autoLockTimer); + return; + } + } + QString curCategory; + if (category) { + curCategory = *category; + } else { + curCategory = view->getCurrentCategory(); + } + PwMDataItem currItem; + if (!doc->getEntry(curCategory, curEntryIndex, &currItem, true)) { + doc->timer()->putLock(DocTimer::id_autoLockTimer); + return; + } + BUG_ON(currItem.binary); + + AddEntryWndImpl w; + vector catList; + doc->getCategoryList(&catList); + unsigned i, size = catList.size(); + for (i = 0; i < size; ++i) { + w.addCategory(catList[i].c_str()); + } + w.setCurrCategory(curCategory); + w.setDescription(currItem.desc.c_str()); + w.setUsername(currItem.name.c_str()); + w.setPassword(currItem.pw.c_str()); + w.setUrl(currItem.url.c_str()); + w.setLauncher(currItem.launcher.c_str()); + w.setComment(currItem.comment.c_str()); + if (w.exec() == 1) { + currItem.desc = w.getDescription().latin1(); + currItem.name = w.getUsername().latin1(); + currItem.pw = w.getPassword().latin1(); + currItem.comment = w.getComment().latin1(); + currItem.url = w.getUrl().latin1(); + currItem.launcher = w.getLauncher().latin1(); + if (!doc->editEntry(curCategory, w.getCategory(), + curEntryIndex, &currItem)) { + KMessageBox::error(this, + i18n("Couldn't edit the entry.\n" + "Maybe you changed the category and " + "this entry is already present in the new " + "category?"), + i18n("couldn't edit entry.")); + doc->timer()->putLock(DocTimer::id_autoLockTimer); + return; + } + } + doc->timer()->putLock(DocTimer::id_autoLockTimer); +} + +void PwM::deletePwd_slot() +{ + PWM_ASSERT(curDoc()); + if (curDoc()->isDocEmpty()) + return; + if (curDoc()->isDeepLocked()) + return; + curDoc()->timer()->getLock(DocTimer::id_autoLockTimer); + unsigned int curEntryIndex = 0; + if (!(view->getCurEntryIndex(&curEntryIndex))) { + printDebug("couldn't get index"); + curDoc()->timer()->putLock(DocTimer::id_autoLockTimer); + return; + } + + PwMDataItem currItem; + QString curCategory = view->getCurrentCategory(); + if (!curDoc()->getEntry(curCategory, curEntryIndex, &currItem)) { + printDebug("couldn't get entry"); + curDoc()->timer()->putLock(DocTimer::id_autoLockTimer); + return; + } + if (KMessageBox:: + questionYesNo(this, + i18n + ("Do you really want to delete the selected entry") + + " \"" + QString(currItem.desc.c_str()) + + "\" ?", i18n("delete?")) + == KMessageBox::Yes) { + + curDoc()->delEntry(curCategory, curEntryIndex); + } + curDoc()->timer()->putLock(DocTimer::id_autoLockTimer); +} + +void PwM::changeMasterPwd_slot() +{ + PWM_ASSERT(curDoc()); + curDoc()->changeCurrentPw(); +} + +void PwM::lockWnd_slot() +{ + PWM_ASSERT(curDoc()); + curDoc()->lockAll(true); +} + +void PwM::deepLockWnd_slot() +{ + PWM_ASSERT(curDoc()); + curDoc()->deepLock(); +} + +void PwM::unlockWnd_slot() +{ + PWM_ASSERT(curDoc()); + curDoc()->lockAll(false); +} + +void PwM::config_slot() +{ + Configuration *conf = Configuration::obj(); + int oldStyle = conf->confWndMainViewStyle(); + + // display the configuration window (modal mode) + if (!conf->showConfWnd(this)) + return; + + int newStyle = conf->confWndMainViewStyle(); + // reinitialize tray + init->initTray(); + // reinitialize KWallet emulation + init->initKWalletEmu(); + + PwMDocList *_dl = PwMDoc::getOpenDocList(); + const vector *dl = _dl->getList(); + vector::const_iterator i = dl->begin(), + end = dl->end(); + PwMDoc *doc; + while (i != end) { + doc = (*i).doc; + // unlock-without-mpw timeout + doc->timer()->start(DocTimer::id_mpwTimer); + // auto-lock timeout + doc->timer()->start(DocTimer::id_autoLockTimer); + ++i; + } + + const QValueList *ml = init->mainWndList(); +#ifndef PWM_EMBEDDED + QValueList::const_iterator i2 = ml->begin(), + end2 = ml->end(); +#else + QValueList::ConstIterator i2 = ml->begin(), + end2 = ml->end(); +#endif + PwM *pwm; + while (i2 != end2) { + pwm = *i2; + // reinitialize the window style. + if (oldStyle != newStyle) + pwm->curView()->initStyle(newStyle); + // set the new font + pwm->curView()->setFont(conf->confGlobEntryFont()); + ++i2; + } +} + +void PwM::activateMpButton(bool activate) +{ + managePopup->setItemEnabled(BUTTON_POPUP_MANAGE_CHANGEMP, activate); +} + +void PwM::closeEvent(QCloseEvent *e) +{ + e->accept(); +} + +void PwM::docClosed(PwMDoc *doc) +{ + PARAM_UNUSED(doc); + PWM_ASSERT(doc == curDoc()); + close(); +} + +void PwM::find_slot() +{ + PWM_ASSERT(curDoc()); + if (curDoc()->isDocEmpty()) + return; + if (curDoc()->isDeepLocked()) + return; + curDoc()->timer()->getLock(DocTimer::id_autoLockTimer); + FindWndImpl findWnd(view); + findWnd.exec(); + curDoc()->timer()->putLock(DocTimer::id_autoLockTimer); +} + +void PwM::exportToText() +{ + 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")); + return; + } + curDoc()->timer()->getLock(DocTimer::id_autoLockTimer); + QString fn(KFileDialog::getSaveFileName(QString::null, + i18n("*|plain-text file"), + this)); + if (fn == "") { + curDoc()->timer()->putLock(DocTimer::id_autoLockTimer); + return; + } + + PwMerror ret = curDoc()->exportToText(&fn); + if (ret != e_success) { + KMessageBox::error(this, + 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); +} + +bool PwM::importFromText() +{ + 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->importFromText(); + 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("*|PWM-exported text file"), + this)); + if (path == "") + goto cancelImport; + + ret = curDoc()->importFromText(&path, 0); + if (ret == e_fileFormat) { + KMessageBox::error(this, + i18n("Could not read file-format.\n" + "This seems to be _not_ a valid file " + "exported by PwM."), + i18n("invalid file-format")); + goto cancelImport; + } else if (ret == e_invalidArg) { + BUG(); + goto cancelImport; + } else if (ret != e_success) { + KMessageBox::error(this, + i18n("Could not import file!\n" + "Do you have permission to read this file? " + "Do you have enough free memory?"), + i18n("import failed")); + goto cancelImport; + } + setVirgin(false); + curDoc()->timer()->putLock(DocTimer::id_autoLockTimer); + return true; + +cancelImport: + curDoc()->timer()->putLock(DocTimer::id_autoLockTimer); + return false; +} + +void PwM::exportToGpasman() +{ + 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")); + return; + } + curDoc()->timer()->getLock(DocTimer::id_autoLockTimer); + QString fn(KFileDialog::getSaveFileName(QString::null, + i18n("*|Gpasman or Kpasman file"), + this)); + if (fn == "") { + curDoc()->timer()->putLock(DocTimer::id_autoLockTimer); + return; + } + + PwMerror ret = curDoc()->exportToGpasman(&fn); + if (ret != e_success) { + if (ret == e_noPw) { + curDoc()->timer()->putLock(DocTimer::id_autoLockTimer); + return; + } + KMessageBox::error(this, + 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::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 " + "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->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" + "you have typed in.\n" + "There is no real way to determine the " + "correctness of the password in the Gpasman " + "file-format. But I think this " + "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) +{ +#ifndef PWM_EMBEDDED + KStatusBar *statBar = statusBar(); + statBar->message(msg, STATUSBAR_MSG_TIMEOUT * 1000); +#else + qDebug("Statusbar : %s",msg.latin1()); +#endif +} + +void PwM::focusInEvent(QFocusEvent *e) +{ + if (e->gotFocus()) { + emit gotFocus(this); + } else if (e->lostFocus()) { + emit lostFocus(this); + } +} + +#ifndef PWM_EMBEDDED +#include "pwm.moc" +#endif diff --git a/pwmanager/pwmanager/pwm.h b/pwmanager/pwmanager/pwm.h new file mode 100644 index 0000000..3a79e67 --- a/dev/null +++ b/pwmanager/pwmanager/pwm.h @@ -0,0 +1,255 @@ +/*************************************************************************** + * * + * 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 __PWM_H +#define __PWM_H + + +#include +#include +#include + +#ifndef PWM_EMBEDDED +#include +#include +#include +#else +#endif + +#include + + +#include + +#include "pwmview.h" +#include "pwmexception.h" + + +/** timeout for displaying a message on the status-bar (in seconds) */ +#define STATUSBAR_MSG_TIMEOUT 5 + + +class PwMInit; + +/** PwM is the base class of the project */ +class PwM : public KMainWindow +{ + Q_OBJECT +public: + friend class PwMView; + /** construtor */ + PwM(PwMInit *_init, PwMDoc *doc, + bool virginity = true, + QWidget* parent = 0, const char *name = 0); + /** destructor */ + ~PwM(); + + /** copy some text to the global clipboard */ + static void copyToClipboard(const QString &s); + + /** returns pointer to the view */ + PwMView * curView() + { return view; } + /** returns pointer to the currently using document. */ + PwMDoc * curDoc() + { return curView()->document(); } + /** open a new doc with the given filename */ + PwMDoc * openDoc(QString filename, bool openDeepLocked = false); + /** show a message on the global status bar. + * The message times out after some seconds. + */ + void showStatMsg(const QString &msg); + /** ask the user where to save the doc (if it has not been saved, yet) + * and write the data to disk. + */ + bool save(); + /** ask the user where to save the doc + * and write the data to disk. + */ + bool saveAs(); + /** force quit. Quit this window, always! Don't minimize it */ + bool isForceQuit() + { return forceQuit; } + /** set forceQuit */ + void setForceQuit(bool force) + { forceQuit = force; } + /** force minimize this window */ + bool isForceMinimizeToTray() + { return forceMinimizeToTray; } + /** set forceMinimizeToTray */ + void setForceMinimizeToTray(bool force) + { forceMinimizeToTray = force; } + +public slots: + /** file/new triggered */ + void new_slot(); + /** file/open triggered */ +//US ENH + void open_slot(); + void open_slot(QString fn); + /** file/close triggered */ + void close_slot(); + /** file/quit triggered */ + void quitButton_slot(); + /** file/save triggered */ + void save_slot(); + /** file/saveAs triggered */ + void saveAs_slot(); + /** file/export/text triggered */ + void exportToText(); + /** file/export/gpasman triggered */ + void exportToGpasman(); + /** file/export/kwallet triggered */ + void exportToKWallet(); + /** file/import/text triggered */ + bool importFromText(); + /** file/import/gpasman triggered */ + bool importFromGpasman(); + /** file/import/kwallet triggered */ + bool importKWallet(); + /** file/print triggered */ + void print_slot(); + /** manage/add triggered */ + //US ENH : changed code to run with older MOC + void addPwd_slot(); + void addPwd_slot(QString *pw, PwMDoc *_doc); + /** manage/edit triggered */ + //US ENH : changed code to run with older MOC + void editPwd_slot(); + void editPwd_slot(const QString *category); + void editPwd_slot(const QString *category = 0, const int *index = 0, + PwMDoc *_doc = 0); + /** manage/delete triggered */ + void deletePwd_slot(); + /** execute the "Launcher" entry */ + void execLauncher_slot(); + /** open browser with URL entry */ + void goToURL_slot(); + /** manage/changeMasterPwd triggered */ + void changeMasterPwd_slot(); + /** lock current document */ + void lockWnd_slot(); + /** deeplock current document */ + void deepLockWnd_slot(); + /** window/unlock triggered */ + void unlockWnd_slot(); + /** find item */ + void find_slot(); + /** configure clicked */ + void config_slot(); + /** (de)activate the "change master pw" button in the menu-bar */ + void activateMpButton(bool activate = true); + /** generate a new chipcard */ + void genNewCard_slot(); + /** completely erase the current card */ + void eraseCard_slot(); + /** returns the ID number of the current card */ + void readCardId_slot(); + /** make backup image of the current card */ + void makeCardBackup_slot(); + /** write backup image to current card */ + void replayCardBackup_slot(); + +protected: + /** is this window virgin? */ + bool isVirgin() + { return virgin; } + /** add/remove virginity */ + void setVirgin(bool v); + /** initialize the menubar */ + void initMenubar(); + /** initialize the toolbar */ + void initToolbar(); + /** initialize the window-metrics */ + void initMetrics(); + /** close-event */ + void closeEvent(QCloseEvent *e); + /** creates a new PwM-ListView and returns it */ + PwMView * makeNewListView(PwMDoc *doc); + /** Window hide-event */ + void hideEvent(QHideEvent *); + /** is this window minimized? */ + bool isMinimized() + { +#ifndef PWM_EMBEDDED + #if KDE_VERSION >= KDE_MAKE_VERSION(3, 2, 0) + return KWin::windowInfo(winId()).isMinimized(); + #else // KDE_VERSION + return KWin::info(winId()).isIconified(); + #endif // KDE_VERSION +#else + return false; +#endif + } + /** window got the focus */ + void focusInEvent(QFocusEvent *e); + /** update the caption string */ + void updateCaption(); +#ifdef CONFIG_KWALLETIF + /** check if kwalletemu is enabled and ask the user what to do */ + bool checkAndAskForKWalletEmu(); +#endif // CONFIG_KWALLETIF + +protected slots: + /** doc got closed */ + void docClosed(PwMDoc *doc); + +signals: + /** window got closed (by user or someone else) */ + void closed(PwM *wnd); + /** window got the focus (was brought to foreground) */ + void gotFocus(PwM *wnd); + /** window lost the focus */ + void lostFocus(PwM *wnd); + +protected: + /** pointer to the view active in this KMainWindow */ + PwMView *view; + /** pointer to the init class */ + PwMInit *init; + /** has this window already lost its virginity? + * Means is there an open working document + */ + bool virgin; + /** "file" popup-menu */ + KPopupMenu *filePopup; + + /** "manage" popup-menu */ + KPopupMenu *managePopup; +#ifdef CONFIG_KEYCARD + /** "chipcard" popup-menu */ + KPopupMenu *chipcardPopup; +#endif // CONFIG_KEYCARD + /** "view" popup-menu */ + KPopupMenu *viewPopup; + /** "options" popup-menu */ + KPopupMenu *optionsPopup; + /** "help" popup-menu */ + KPopupMenu *helpPopup; + /** "export" popup-menu */ + KPopupMenu *exportPopup; + /** "import" popup-menu */ + KPopupMenu *importPopup; + /** force quit this window? */ + bool forceQuit; + /** force minimize this window to the tray */ + bool forceMinimizeToTray; +}; + +#endif diff --git a/pwmanager/pwmanager/pwmanagerE.pro b/pwmanager/pwmanager/pwmanagerE.pro new file mode 100644 index 0000000..3fa91ba --- a/dev/null +++ b/pwmanager/pwmanager/pwmanagerE.pro @@ -0,0 +1,143 @@ +TEMPLATE = app +CONFIG += qt warn_on + + +TARGET = pwmpi +OBJECTS_DIR = obj/$(PLATFORM) +MOC_DIR = moc/$(PLATFORM) +DESTDIR=$(QPEDIR)/bin + +INCLUDEPATH += . ../../qtcompat ../../qtcompat/xml ../../microkde ../../microkde/kdecore ../../microkde/kdeui $(QPEDIR)/include +DEFINES += PWM_EMBEDDED PWM_DEBUG +LIBS += -lmicrokde +LIBS += -lmicroqtcompat +LIBS += -L$(QPEDIR)/lib +LIBS += -lqpe +LIBS += -lbz2 + +#INTERFACES = \ +#addentrywnd.ui \ +#configwnd.ui \ +#findwnd.ui \ +#getmasterpwwnd.ui \ +#pwgenwnd.ui \ +#setmasterpwwnd.ui \ +#subtbledit.ui + +#INTERFACES = \ +#subtbledit.ui \ + + + +#HEADERS = \ +#selftest.h + +HEADERS = \ +addentrywnd.h \ +addentrywndimpl.h \ +base64.h \ +binentrygen.h \ +blowfish.h \ +commentbox.h \ +compiler.h \ +compressbzip2.h \ +compressgzip.h \ +configuration_31compat.h \ +configuration.h \ +configwnd.h \ +configwndimpl.h \ +findwnd.h \ +findwndimpl.h \ +genpasswd.h \ +getkeycardwnd.h \ +getmasterpwwnd.h \ +getmasterpwwndimpl.h \ +globalstuff.h \ +gpasmanfile.h \ +htmlgen.h \ +htmlparse.h \ +ipc.h \ +listobjselectwnd.h \ +listviewpwm.h \ +printtext.h \ +pwgenwnd.h \ +pwgenwndimpl.h \ +pwmdoc.h \ +pwmdocui.h \ +pwmexception.h \ +pwm.h \ +pwminit.h \ +pwmprint.h \ +pwmtray.h \ +pwmview.h \ +pwmviewstyle_0.h \ +pwmviewstyle_1.h \ +pwmviewstyle.h \ +randomizer.h \ +rc2.h \ +rencatwnd.h \ +serializer.h \ +setmasterpwwnd.h \ +setmasterpwwndimpl.h \ +sha1.h \ +subtbledit.h \ +subtbleditimpl.h \ +waitwnd.h + +#SOURCES = \ +#advcommeditimpl.cpp \ +#configuration_31compat.cpp \ +#htmlparse.cpp \ +#printtext.cpp \ +#selftest.cpp \ +#pwmprint.cpp \ +#spinforsignal.cpp + +SOURCES = \ +addentrywnd.cpp \ +addentrywndimpl.cpp \ +base64.cpp \ +binentrygen.cpp \ +blowfish.cpp \ +commentbox.cpp \ +compressbzip2.cpp \ +compressgzip.cpp \ +configuration.cpp \ +configwnd.cpp \ +configwndimpl.cpp \ +findwnd.cpp \ +findwndimpl.cpp \ +genpasswd.cpp \ +getkeycardwnd.cpp \ +getmasterpwwnd.cpp \ +getmasterpwwndimpl.cpp \ +globalstuff.cpp \ +gpasmanfile.cpp \ +htmlgen.cpp \ +ipc.cpp \ +listobjselectwnd.cpp \ +listviewpwm.cpp \ +main.cpp \ +pwgenwnd.cpp \ +pwgenwndimpl.cpp \ +pwm.cpp \ +pwmdoc.cpp \ +pwmdocui.cpp \ +pwmexception.cpp \ +pwminit.cpp \ +pwmtray.cpp \ +pwmview.cpp \ +pwmviewstyle_0.cpp \ +pwmviewstyle_1.cpp \ +pwmviewstyle.cpp \ +randomizer.cpp \ +rc2.cpp \ +rencatwnd.cpp \ +serializer.cpp \ +setmasterpwwnd.cpp \ +setmasterpwwndimpl.cpp \ +sha1.cpp \ +subtbledit.cpp \ +subtbleditimpl.cpp \ +waitwnd.cpp \ + diff --git a/pwmanager/pwmanager/pwmdoc.cpp b/pwmanager/pwmanager/pwmdoc.cpp new file mode 100644 index 0000000..04af360 --- a/dev/null +++ b/pwmanager/pwmanager/pwmdoc.cpp @@ -0,0 +1,2775 @@ +/*************************************************************************** + * * + * 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 2.0 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" +#include "compressbzip2.h" +#include "randomizer.h" +#include "pwminit.h" +#ifndef PWM_EMBEDDED +//US #include "libgryptif.h" +#else +#endif + +#ifdef CONFIG_KWALLETIF +# include "kwalletemu.h" +#endif // CONFIG_KWALLETIF + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//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::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::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::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::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; + if (!file) { + if (filename == "") + return e_filename; + } else { + if (*file == "" && filename == "") + return e_filename; + if (*file != "") + filename = *file; + } + + bool wasDeepLocked = isDeepLocked(); + if (wasDeepLocked) { + if (deepLock(false) != e_success) + return e_noPw; + } + + 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); + } + } +#ifndef PWM_EMBEDDED + int _cryptAlgo = conf()->confGlobCryptAlgo(); + int _hashAlgo = conf()->confGlobHashAlgo(); +#else + int _cryptAlgo = PWM_CRYPT_BLOWFISH; + int _hashAlgo = PWM_HASH_SHA1; +#endif + + // 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(_cryptAlgo); + char hashAlgo = static_cast(_hashAlgo); + + if (conf()->confGlobMakeFileBackup()) { + if (!backupFile(filename)) + return e_fileBackup; + } + QString tmpFileMoved(QString::null); + 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!"); + } + } + QFile f(filename); + string serialized; + 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(); + if (chmod(filename.latin1(), + conf()->confGlobFilePermissions())) { + printWarn(string("chmod failed: ") + strerror(errno)); + } + openDocList.edit(this, getTitle().latin1()); + if (wasDeepLocked) + deepLock(true); + 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 { compress: ") + + tostr(static_cast(compress)) + " cryptAlgo: " + + tostr(static_cast(cryptAlgo)) + " hashAlgo: " + + tostr(static_cast(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); + PWM_ASSERT(listView); +#ifndef PWM_EMBEDDED + if (f->writeBlock(FILE_ID_HEADER, strlen(FILE_ID_HEADER)) != + static_cast(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(0x01)) : (static_cast(0x00))) == -1) { + return e_writeFile; + } + +#else + if (f->writeBlock(FILE_ID_HEADER, strlen(FILE_ID_HEADER)) != + (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)) ? + ((char)(0x01)) : ((char)(0x00))) == -1) { + return e_writeFile; + } +#endif + // 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(pw->latin1()), pw->length()); + string ret = hash.sha1_read(); + if (f->writeBlock(ret.c_str(), hashlen) != hashlen) + return e_writeFile; + break; + } +#ifndef PWM_EMBEDDED + 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(pw->latin1()), + pw->length(), + keyHash); + if (err != e_success) + return e_hashNotImpl; + if (f->writeBlock(reinterpret_cast(buf), hashLen) + != static_cast(hashLen)) { + delete [] buf; + return e_hashNotImpl; + } + delete [] buf; + break; + } +#endif + 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(pw->latin1()), pw->length()); + string ret = hash.sha1_read(); + if (ret != readHash) + return e_wrongPw; // hash doesn't match (wrong key) + break; + } +#ifndef PWM_EMBEDDED + 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(pw->latin1()), + pw->length(), + keyHash); + if (err != e_success) + return e_hashNotImpl; + string calcHash(reinterpret_cast(buf), + static_cast(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; + } +#endif + 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; +#ifndef PWM_EMBEDDED + 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; + } +#endif + 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(tmpRet)); + } + *headerLength = f->at(); +#ifndef PWM_EMBEDDED + printDebug(string("opening file { compress: ") + + tostr(static_cast(*compress)) + " cryptAlgo: " + + tostr(static_cast(*cryptAlgo)) + " keyHashAlgo: " + + tostr(static_cast(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(d->c_str()), d->size()); + string hRet = h.sha1_read(); + if (f->writeBlock(hRet.c_str(), hashLen) != hashLen) + return e_writeFile; + break; + } +#ifndef PWM_EMBEDDED + 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(d->c_str()), + d->size(), + dataHash); + if (err != e_success) + return e_hashNotImpl; + if (f->writeBlock(reinterpret_cast(buf), hashLen) + != static_cast(hashLen)) { + delete [] buf; + return e_hashNotImpl; + } + delete [] buf; + break; + } +#endif + default: { + return e_hashNotImpl; + } } + + return e_success; +} + +bool PwMDoc::backupFile(const QString &filePath) +{ + QFileInfo fi(filePath); + if (!fi.exists()) + return true; // Yes, true is correct. + QString pathOnly(fi.dirPath(true)); + QString nameOnly(fi.fileName()); + QString backupPath = pathOnly + + "/~" + + nameOnly + + ".backup"; + return copyFile(filePath, backupPath); +} + +bool PwMDoc::copyFile(const QString &src, const QString &dst) +{ + QFileInfo fi(src); + if (!fi.exists()) + return false; + if (QFile::exists(dst)) { + if (!QFile::remove(dst)) + return false; + } + QFile srcFd(src); + if (!srcFd.open(IO_ReadOnly)) + return false; + QFile dstFd(dst); + if (!dstFd.open(IO_ReadWrite)) { + srcFd.close(); + return false; + } + const int tmpBuf_size = 512; + char tmpBuf[tmpBuf_size]; +#ifndef PWM_EMBEDDED + Q_LONG bytesRead, bytesWritten; +#else + long bytesRead, bytesWritten; +#endif + while (!srcFd.atEnd()) { +#ifndef PWM_EMBEDDED + bytesRead = srcFd.readBlock(tmpBuf, + static_cast(tmpBuf_size)); +#else + bytesRead = srcFd.readBlock(tmpBuf, + (unsigned long)(tmpBuf_size)); +#endif + if (bytesRead == -1) { + srcFd.close(); + dstFd.close(); + return false; + } +#ifndef PWM_EMBEDDED + bytesWritten = dstFd.writeBlock(tmpBuf, + static_cast(bytesRead)); +#else + bytesWritten = dstFd.writeBlock(tmpBuf, + (unsigned long)(bytesRead)); +#endif + if (bytesWritten != bytesRead) { + srcFd.close(); + dstFd.close(); + return false; + } + } + srcFd.close(); + dstFd.close(); + return true; +} + +PwMerror PwMDoc::addEntry(const QString &category, PwMDataItem *d, + bool dontFlagDirty, bool updateMeta) +{ + PWM_ASSERT(d); + unsigned int cat = 0; + + if (isDeepLocked()) { + PwMerror ret; + ret = deepLock(false); + if (ret != e_success) + return e_lock; + } + + addCategory(category, &cat); + + if (numEntries(category) >= maxEntries) + return e_maxAllowedEntr; + + vector foundPositions; + /* historically this was: + * const int searchIn = SEARCH_IN_DESC | SEARCH_IN_NAME | + * SEARCH_IN_URL | SEARCH_IN_LAUNCHER; + * But for now we only search in desc. + * That's a tweak to be KWallet compatible. But it should not add + * usability-drop onto PwManager, does it? + * (And yes, "int" was a bug. Correct is "unsigned int") + */ + const unsigned int searchIn = SEARCH_IN_DESC; + findEntry(cat, *d, searchIn, &foundPositions, true); + if (foundPositions.size()) { + // DOH! We found this entry. + return e_entryExists; + } + + d->listViewPos = -1; + d->lockStat = conf()->confGlobNewEntrLockStat(); + if (updateMeta) { + d->meta.create = QDateTime::currentDateTime(); + d->meta.update = d->meta.create; + } + dta[cat].d.push_back(*d); + + delAllEmptyCat(true); + + if (!dontFlagDirty) + flagDirty(); + return e_success; +} + +PwMerror PwMDoc::addCategory(const QString &category, unsigned int *categoryIndex, + bool checkIfExist) +{ + if (isDeepLocked()) { + PwMerror ret; + ret = deepLock(false); + if (ret != e_success) + return e_lock; + } + if (checkIfExist) { + if (findCategory(category, categoryIndex)) + return e_categoryExists; + } + PwMCategoryItem item; + item.name = category.latin1(); + dta.push_back(item); + if (categoryIndex) + *categoryIndex = dta.size() - 1; + return e_success; +} + +bool PwMDoc::delEntry(const QString &category, unsigned int index, bool dontFlagDirty) +{ + unsigned int cat = 0; + + if (!findCategory(category, &cat)) { + BUG(); + return false; + } + + return delEntry(cat, index, dontFlagDirty); +} + +bool PwMDoc::delEntry(unsigned int category, unsigned int index, bool dontFlagDirty) +{ + if (isDeepLocked()) + return false; + if (index > dta[category].d.size() - 1) + return false; + getDataChangedLock(); + if (!lockAt(category, index, false)) { + putDataChangedLock(); + return false; + } + putDataChangedLock(); + int lvPos = dta[category].d[index].listViewPos; + + // delete entry + dta[category].d.erase(dta[category].d.begin() + index); + + unsigned int i, entries = numEntries(category); + if (!entries) { + // no more entries in this category, so + // we can delete it, too. + BUG_ON(!delCategory(category)); + // delCategory() flags it dirty, so we need not to do so. + return true; + } + for (i = 0; i < entries; ++i) { + // decrement all listViewPositions that are greater than the deleted. + if (dta[category].d[i].listViewPos > lvPos) + --dta[category].d[i].listViewPos; + } + + if (!dontFlagDirty) + flagDirty(); + return true; +} + +bool PwMDoc::editEntry(const QString &oldCategory, const QString &newCategory, + unsigned int index, PwMDataItem *d, bool updateMeta) +{ + PWM_ASSERT(d); + unsigned int oldCat = 0; + + if (!findCategory(oldCategory, &oldCat)) { + BUG(); + return false; + } + + return editEntry(oldCat, newCategory, index, d, updateMeta); +} + +bool PwMDoc::editEntry(unsigned int oldCategory, const QString &newCategory, + unsigned int index, PwMDataItem *d, bool updateMeta) +{ + if (isDeepLocked()) + return false; + if (updateMeta) { + d->meta.update = QDateTime::currentDateTime(); + if (d->meta.create.isNull()) { + d->meta.create = d->meta.update; + } + } + if (dta[oldCategory].name != newCategory.latin1()) { + // the user changed the category. + PwMerror ret; + d->rev = 0; + ret = addEntry(newCategory, d, true, false); + if (ret != e_success) + return false; + if (!delEntry(oldCategory, index, true)) + return false; + } else { + d->rev = dta[oldCategory].d[index].rev + 1; // increment revision counter. + dta[oldCategory].d[index] = *d; + } + flagDirty(); + return true; +} + +unsigned int PwMDoc::numEntries(const QString &category) +{ + unsigned int cat = 0; + + if (!findCategory(category, &cat)) { + BUG(); + return 0; + } + + return numEntries(cat); +} + +bool PwMDoc::serializeDta(string *d) +{ + PWM_ASSERT(d); + Serializer ser; + if (!ser.serialize(dta)) + return false; + d->assign(ser.getXml()); + if (!d->size()) + return false; + return true; +} + +bool PwMDoc::deSerializeDta(const string *d, bool entriesLocked) +{ + PWM_ASSERT(d); + try { + Serializer ser(d->c_str()); + ser.setDefaultLockStat(entriesLocked); + if (!ser.deSerialize(&dta)) + return false; + } catch (PwMException) { + return false; + } + emitDataChanged(this); + return true; +} + +bool PwMDoc::getEntry(const QString &category, unsigned int index, + PwMDataItem * d, bool unlockIfLocked) +{ + PWM_ASSERT(d); + unsigned int cat = 0; + + if (!findCategory(category, &cat)) { + BUG(); + return false; + } + + return getEntry(cat, index, d, unlockIfLocked); +} + +bool PwMDoc::getEntry(unsigned int category, unsigned int index, + PwMDataItem *d, bool unlockIfLocked) +{ + if (index > dta[category].d.size() - 1) + return false; + + bool locked = isLocked(category, index); + if (locked) { + /* this entry is locked. We don't return a password, + * until it's unlocked by the user by inserting + * chipcard or entering the mpw + */ + if (unlockIfLocked) { + if (!lockAt(category, index, false)) { + return false; + } + locked = false; + } + } + + *d = dta[category].d[index]; + if (locked) + d->pw = LOCKED_STRING.latin1(); + + return true; +} + +PwMerror PwMDoc::getCommentByLvp(const QString &category, int listViewPos, + string *foundComment) +{ + PWM_ASSERT(foundComment); + unsigned int cat = 0; + + if (!findCategory(category, &cat)) + return e_invalidArg; + + unsigned int i, entries = numEntries(cat); + for (i = 0; i < entries; ++i) { + if (dta[cat].d[i].listViewPos == listViewPos) { + *foundComment = dta[cat].d[i].comment; + if (dta[cat].d[i].binary) + return e_binEntry; + return e_normalEntry; + } + } + BUG(); + return e_generic; +} + +bool PwMDoc::compressDta(string *d, char algo) +{ + PWM_ASSERT(d); + switch (algo) { + case PWM_COMPRESS_GZIP: { + CompressGzip comp; + return comp.compress(d); + } case PWM_COMPRESS_BZIP2: { + CompressBzip2 comp; + return comp.compress(d); + } case PWM_COMPRESS_NONE: { + return true; + } default: { + BUG(); + } + } + return false; +} + +bool PwMDoc::decompressDta(string *d, char algo) +{ + PWM_ASSERT(d); + switch (algo) { + case PWM_COMPRESS_GZIP: { + CompressGzip comp; + return comp.decompress(d); + } case PWM_COMPRESS_BZIP2: { + CompressBzip2 comp; + return comp.decompress(d); + } case PWM_COMPRESS_NONE: { + return true; + } + } + return false; +} + +PwMerror PwMDoc::encrypt(string *d, const QString *pw, QFile *f, char algo) +{ + PWM_ASSERT(d); + PWM_ASSERT(pw); + PWM_ASSERT(f); + + size_t encSize; + byte *encrypted = 0; + + switch (algo) { + case PWM_CRYPT_BLOWFISH: { + Blowfish::padNull(d); + encSize = d->length(); + encrypted = new byte[encSize]; + Blowfish bf; + if (bf.bf_setkey((byte *) pw->latin1(), pw->length())) { + delete [] encrypted; + return e_weakPw; + } + bf.bf_encrypt((byte *) encrypted, (byte *) d->c_str(), encSize); + break; + } +#ifndef PWM_EMBEDDED + case PWM_CRYPT_AES128: + /*... fall through */ + case PWM_CRYPT_AES192: + case PWM_CRYPT_AES256: + case PWM_CRYPT_3DES: + case PWM_CRYPT_TWOFISH: + case PWM_CRYPT_TWOFISH128: { + if (!LibGCryptIf::available()) + return e_cryptNotImpl; + LibGCryptIf gc; + PwMerror err; + unsigned char *plain = new unsigned char[d->length() + 1024]; + memcpy(plain, d->c_str(), d->length()); + err = gc.encrypt(&encrypted, + &encSize, + plain, + d->length(), + reinterpret_cast(pw->latin1()), + pw->length(), + algo); + delete [] plain; + if (err != e_success) + return e_cryptNotImpl; + break; + } +#endif + default: { + delete_ifnot_null_array(encrypted); + return e_cryptNotImpl; + } } + + // write encrypted data to file +#ifndef PWM_EMBEDDED + if (f->writeBlock(reinterpret_cast(encrypted), + static_cast(encSize)) + != static_cast(encSize)) { + delete_ifnot_null_array(encrypted); + return e_writeFile; + } +#else + if (f->writeBlock((const char *)(encrypted), + (unsigned long)(encSize)) + != (long)(encSize)) { + delete_ifnot_null_array(encrypted); + return e_writeFile; + } +#endif + delete_ifnot_null_array(encrypted); + return e_success; +} + +PwMerror PwMDoc::decrypt(string *d, unsigned int pos, const QString *pw, + char algo, QFile *f) +{ + PWM_ASSERT(d); + PWM_ASSERT(pw); + PWM_ASSERT(f); + + unsigned int cryptLen = f->size() - pos; + byte *encrypted = new byte[cryptLen]; + byte *decrypted = new byte[cryptLen]; + + f->at(pos); +#ifndef PWM_EMBEDDED + if (f->readBlock(reinterpret_cast(encrypted), + static_cast(cryptLen)) + != static_cast(cryptLen)) { + delete [] encrypted; + delete [] decrypted; + return e_readFile; + } +#else + if (f->readBlock((char *)(encrypted), + (unsigned long)(cryptLen)) + != (long)(cryptLen)) { + delete [] encrypted; + delete [] decrypted; + return e_readFile; + } +#endif + switch (algo) { + case PWM_CRYPT_BLOWFISH: { + Blowfish bf; + bf.bf_setkey((byte *) pw->latin1(), pw->length()); + bf.bf_decrypt(decrypted, encrypted, cryptLen); + break; + } +#ifndef PWM_EMBEDDED + case PWM_CRYPT_AES128: + /*... fall through */ + case PWM_CRYPT_AES192: + case PWM_CRYPT_AES256: + case PWM_CRYPT_3DES: + case PWM_CRYPT_TWOFISH: + case PWM_CRYPT_TWOFISH128: { + if (!LibGCryptIf::available()) + return e_cryptNotImpl; + LibGCryptIf gc; + PwMerror err; + err = gc.decrypt(&decrypted, + &cryptLen, + encrypted, + cryptLen, + reinterpret_cast(pw->latin1()), + pw->length(), + algo); + if (err != e_success) { + delete [] encrypted; + delete [] decrypted; + return e_cryptNotImpl; + } + break; + } +#endif + default: { + delete [] encrypted; + delete [] decrypted; + return e_cryptNotImpl; + } } + delete [] encrypted; +#ifndef PWM_EMBEDDED + d->assign(reinterpret_cast(decrypted), + static_cast(cryptLen)); +#else + d->assign((const char *)(decrypted), + (string::size_type)(cryptLen)); +#endif + delete [] decrypted; + if (algo == PWM_CRYPT_BLOWFISH) { + if (!Blowfish::unpadNull(d)) { + BUG(); + return e_readFile; + } + } + return e_success; +} + +PwMerror PwMDoc::checkDataHash(char dataHashType, const string *dataHash, + const string *dataStream) +{ + PWM_ASSERT(dataHash); + PWM_ASSERT(dataStream); + switch(dataHashType) { + case PWM_HASH_SHA1: { + Sha1 hash; + hash.sha1_write((byte*)dataStream->c_str(), dataStream->length()); + string ret = hash.sha1_read(); + if (ret != *dataHash) + return e_fileCorrupt; + break; + } +#ifndef PWM_EMBEDDED + 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(dataStream->c_str()), + dataStream->length(), + dataHashType); + if (err != e_success) + return e_hashNotImpl; + string calcHash(reinterpret_cast(buf), + static_cast(hashLen)); + delete [] buf; + if (calcHash != *dataHash) + return e_fileCorrupt; + break; + } +#endif + default: + return e_hashNotImpl; + } + return e_success; +} + +bool PwMDoc::lockAt(unsigned int category, unsigned int index, + bool lock) +{ + if (index >= numEntries(category)) { + BUG(); + return false; + } + if (lock == dta[category].d[index].lockStat) + return true; + + if (!lock && currentPw != "") { + // "unlocking" and "password is already set" + if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW)) { + // unlocking without pw not allowed + QString pw; + pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); + if (pw != "") { + if (pw != currentPw) { + wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); + return false; + } else { + timer()->start(DocTimer::id_mpwTimer); + } + } else { + return false; + } + } else { + timer()->start(DocTimer::id_mpwTimer); + } + } + + dta[category].d[index].lockStat = lock; + dta[category].d[index].rev++; // increment revision counter. + + emitDataChanged(this); + if (!lock) + timer()->start(DocTimer::id_autoLockTimer); + + return true; + +} + +bool PwMDoc::lockAt(const QString &category,unsigned int index, + bool lock) +{ + unsigned int cat = 0; + + if (!findCategory(category, &cat)) { + BUG(); + return false; + } + + return lockAt(cat, index, lock); +} + +bool PwMDoc::lockAll(bool lock) +{ + if (!lock && isDeepLocked()) { + PwMerror ret; + ret = deepLock(false); + if (ret != e_success) + return false; + return true; + } + if (isDocEmpty()) { + return true; + } + if (!lock && currentPw != "") { + // unlocking and password is already set + if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW)) { + // unlocking without pw not allowed + QString pw; + pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); + if (pw != "") { + if (pw != currentPw) { + wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); + return false; + } else { + timer()->start(DocTimer::id_mpwTimer); + } + } else { + return false; + } + } else { + timer()->start(DocTimer::id_mpwTimer); + } + } + + vector::iterator catBegin = dta.begin(), + catEnd = dta.end(), + catI = catBegin; + vector::iterator entrBegin, entrEnd, entrI; + while (catI != catEnd) { + entrBegin = catI->d.begin(); + entrEnd = catI->d.end(); + entrI = entrBegin; + while (entrI != entrEnd) { + entrI->lockStat = lock; + entrI->rev++; // increment revision counter. + ++entrI; + } + ++catI; + } + + emitDataChanged(this); + if (lock) + timer()->stop(DocTimer::id_autoLockTimer); + else + timer()->start(DocTimer::id_autoLockTimer); + + return true; +} + +bool PwMDoc::isLocked(const QString &category, unsigned int index) +{ + unsigned int cat = 0; + + if (!findCategory(category, &cat)) { + BUG(); + return false; + } + + return isLocked(cat, index); +} + +bool PwMDoc::unlockAll_tempoary(bool revert) +{ + static vector< vector > *oldLockStates = 0; + static bool wasDeepLocked; + + if (revert) { // revert the unlocking + if (oldLockStates) { + /* we actually _have_ unlocked something, because + * we have allocated space for the oldLockStates. + * So, go on and revert them! + */ + if (wasDeepLocked) { + PwMerror ret = deepLock(true); + if (ret == e_success) { + /* deep-lock succeed. We are save. + * (but if it failed, just go on + * lock them normally) + */ + delete_and_null(oldLockStates); + timer()->start(DocTimer::id_autoLockTimer); + printDebug("tempoary unlocking of dta " + "reverted by deep-locking."); + return true; + } + printDebug("deep-lock failed while reverting! " + "Falling back to normal-lock."); + } + if (unlikely(!wasDeepLocked && + numCategories() != oldLockStates->size())) { + /* DOH! We have modified "dta" while + * it was unlocked tempoary. DON'T DO THIS! + */ + BUG(); + delete_and_null(oldLockStates); + timer()->start(DocTimer::id_autoLockTimer); + return false; + } + vector::iterator catBegin = dta.begin(), + catEnd = dta.end(), + catI = catBegin; + vector::iterator entrBegin, entrEnd, entrI; + vector< vector >::iterator oldCatStatI = oldLockStates->begin(); + vector::iterator oldEntrStatBegin, + oldEntrStatEnd, + oldEntrStatI; + while (catI != catEnd) { + entrBegin = catI->d.begin(); + entrEnd = catI->d.end(); + entrI = entrBegin; + if (likely(!wasDeepLocked)) { + oldEntrStatBegin = oldCatStatI->begin(); + oldEntrStatEnd = oldCatStatI->end(); + oldEntrStatI = oldEntrStatBegin; + if (unlikely(catI->d.size() != oldCatStatI->size())) { + /* DOH! We have modified "dta" while + * it was unlocked tempoary. DON'T DO THIS! + */ + BUG(); + delete_and_null(oldLockStates); + timer()->start(DocTimer::id_autoLockTimer); + return false; + } + } + while (entrI != entrEnd) { + if (wasDeepLocked) { + /* this is an error-fallback if + * deeplock didn't succeed + */ + entrI->lockStat = true; + } else { + entrI->lockStat = *oldEntrStatI; + } + ++entrI; + if (likely(!wasDeepLocked)) + ++oldEntrStatI; + } + ++catI; + if (likely(!wasDeepLocked)) + ++oldCatStatI; + } + delete_and_null(oldLockStates); + if (unlikely(wasDeepLocked)) { + /* error fallback... */ + unsetDocStatFlag(DOC_STAT_DEEPLOCKED); + emitDataChanged(this); + printDebug("WARNING: unlockAll_tempoary(true) " + "deeplock fallback!"); + } + printDebug("tempoary unlocking of dta reverted."); + } else { + printDebug("unlockAll_tempoary(true): nothing to do."); + } + timer()->start(DocTimer::id_autoLockTimer); + } else { // unlock all data tempoary + if (unlikely(oldLockStates != 0)) { + /* DOH! We have already unlocked the data tempoarly. + * No need to do it twice. ;) + */ + BUG(); + return false; + } + wasDeepLocked = false; + bool mustUnlock = false; + if (isDeepLocked()) { + PwMerror ret; + while (1) { + ret = deepLock(false); + if (ret == e_success) { + break; + } else if (ret == e_wrongPw) { + wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); + } else { + printDebug("deep-unlocking failed while " + "tempoary unlocking!"); + return false; + } + } + wasDeepLocked = true; + mustUnlock = true; + } else { + // first check if it's needed to unlock some entries + vector::iterator catBegin = dta.begin(), + catEnd = dta.end(), + catI = catBegin; + vector::iterator entrBegin, entrEnd, entrI; + while (catI != catEnd) { + entrBegin = catI->d.begin(); + entrEnd = catI->d.end(); + entrI = entrBegin; + while (entrI != entrEnd) { + if (entrI->lockStat == true) { + mustUnlock = true; + break; + } + ++entrI; + } + if (mustUnlock) + break; + ++catI; + } + } + if (!mustUnlock) { + // nothing to do. + timer()->stop(DocTimer::id_autoLockTimer); + printDebug("unlockAll_tempoary(): nothing to do."); + return true; + } else if (!wasDeepLocked) { + if (!getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW) && + currentPw != "") { + /* we can't unlock without mpw, so + * we need to ask for it. + */ + QString pw; + while (1) { + pw = requestMpw(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); + if (pw == "") { + return false; + } else if (pw == currentPw) { + break; + } + wrongMpwMsgBox(getDocStatFlag(DOC_STAT_USE_CHIPCARD)); + } + } + } + timer()->stop(DocTimer::id_autoLockTimer); + oldLockStates = new vector< vector >; + vector tmp_vec; + vector::iterator catBegin = dta.begin(), + catEnd = dta.end(), + catI = catBegin; + vector::iterator entrBegin, entrEnd, entrI; + while (catI != catEnd) { + entrBegin = catI->d.begin(); + entrEnd = catI->d.end(); + entrI = entrBegin; + while (entrI != entrEnd) { + if (!wasDeepLocked) { + tmp_vec.push_back(entrI->lockStat); + } + entrI->lockStat = false; + ++entrI; + } + if (!wasDeepLocked) { + oldLockStates->push_back(tmp_vec); + tmp_vec.clear(); + } + ++catI; + } + printDebug("tempoary unlocked dta."); + } + + return true; +} + +PwMerror PwMDoc::deepLock(bool lock, bool saveToFile) +{ + PwMerror ret; + + if (lock) { + if (isDeepLocked()) + return e_lock; + if (saveToFile) { + if (isDocEmpty()) + return e_docIsEmpty; + ret = saveDoc(conf()->confGlobCompression()); + if (ret == e_filename) { + /* the doc wasn't saved to a file + * by the user, yet. + */ + cantDeeplock_notSavedMsgBox(); + return e_docNotSaved; + } 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(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() +{ + dta.clear(); + PwMCategoryItem d; + d.name = DEFAULT_CATEGORY.latin1(); + 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(¤tPw, &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) +{ + 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 dta[cat].d[index].listViewPos; +} + +void PwMDoc::findEntry(unsigned int category, PwMDataItem find, unsigned int searchIn, + vector *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, dta[category].d[i].desc, + caseSensitive, exactWordMatch)) { + continue; + } + } + if (searchIn & SEARCH_IN_NAME) { + if (!compareString(find.name, 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, 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, dta[category].d[i].comment, + caseSensitive, exactWordMatch)) { + continue; + } + } + if (searchIn & SEARCH_IN_URL) { + if (!compareString(find.url, dta[category].d[i].url, + caseSensitive, exactWordMatch)) { + continue; + } + } + if (searchIn & SEARCH_IN_LAUNCHER) { + if (!compareString(find.launcher, 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 > tmp_vec; + + unsigned int i, items = foundPositions->size(); + pair tmp_pair; + for (i = 0; i < items; ++i) { + tmp_pair.first = (*foundPositions)[i]; + tmp_pair.second = 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 *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::iterator i = dta.begin(), + end = dta.end(); + while (i != end) { + if ((*i).name == name.latin1()) { + if (index) { + *index = i - 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; + + 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) { + dta.erase(dta.begin() + category); + } else { + renameCategory(category, DEFAULT_CATEGORY, dontFlagDirty); + return true; + } + if (!dontFlagDirty) + flagDirty(); + + return true; +} + +void PwMDoc::delAllEmptyCat(bool dontFlagDirty) +{ + vector::iterator begin = dta.begin(), + end = dta.end(), + i = begin; + while (i != end) { + if (i->d.empty()) { + delCategory(begin - i, dontFlagDirty); + } + ++i; + } +} + +void PwMDoc::getCategoryList(vector *list) +{ + PWM_ASSERT(list); + list->clear(); + vector::iterator i = dta.begin(), + end = dta.end(); + while (i != end) { + list->push_back(i->name); + ++i; + } +} + +void PwMDoc::getCategoryList(QStringList *list) +{ + PWM_ASSERT(list); + list->clear(); + vector::iterator i = dta.begin(), + end = 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 *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 *list) +{ + PWM_ASSERT(list); + list->clear(); + vector::iterator begin = dta[category].d.begin(), + end = 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::iterator begin = dta[category].d.begin(), + end = 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) +{ + if (geteuid() == 0) { + rootAlertMsgBox(); + return false; + } + QString command(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", dta[category].d[entryIndex].desc.c_str()); + command.replace("$n", dta[category].d[entryIndex].name.c_str()); + command.replace("$p", dta[category].d[entryIndex].pw.c_str()); + command.replace("$u", dta[category].d[entryIndex].url.c_str()); + command.replace("$c", dta[category].d[entryIndex].comment.c_str()); +#else + command.replace(QRegExp("$d"), dta[category].d[entryIndex].desc.c_str()); + command.replace(QRegExp("$n"), dta[category].d[entryIndex].name.c_str()); + command.replace(QRegExp("$p"), dta[category].d[entryIndex].pw.c_str()); + command.replace(QRegExp("$u"), dta[category].d[entryIndex].url.c_str()); + command.replace(QRegExp("$c"), 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) +{ + if (geteuid() == 0) { + rootAlertMsgBox(); + return false; + } + QString url(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); + header += KGlobal::locale()->formatTime(currTime, true); + 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 += 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 += dta[i].d[j].desc; + exp += " --\n"; + + exp += i18n("Username: ").latin1(); + exp += dta[i].d[j].name; + exp += "\n"; + + exp += i18n("Password: ").latin1(); + exp += dta[i].d[j].pw; + exp += "\n"; + + exp += i18n("Comment: ").latin1(); + exp += dta[i].d[j].comment; + exp += "\n"; + + exp += i18n("URL: ").latin1(); + exp += dta[i].d[j].url; + exp += "\n"; + + exp += i18n("Launcher: ").latin1(); + exp += 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; + dta.clear(); + emitDataChanged(this); + // add next format here... + return e_fileFormat; + } + return e_invalidArg; +} + +PwMerror PwMDoc::importText_PwM(const QString *file) +{ + 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; +} + +bool PwMDoc::textExtractEntry_PwM(const char *in, ssize_t in_size, string *out) +{ + PWM_ASSERT(in && out); + ssize_t i = 0, len = in_size - 1; + while (i < len) { + if (in[i] == ':') + break; + ++i; + } + i += 2; + *out = ""; + out->append(in + i, in_size - i - 1); + return true; +} + +PwMerror PwMDoc::exportToGpasman(const QString *file) +{ + PWM_ASSERT(file); + GpasmanFile gp; + int ret; + + if (!unlockAll_tempoary()) + return e_lock; + + QString gpmPassword; + while (1) { + gpmPassword = requestNewMpw(0); + if (gpmPassword == "") { + unlockAll_tempoary(true); + return e_noPw; + } + if (gpmPassword.length() < 4) { + gpmPwLenErrMsgBox(); + } else { + break; + } + } + + ret = gp.save_init(file->latin1(), gpmPassword.latin1()); + if (ret != 1) { + unlockAll_tempoary(true); + return e_accessFile; + } + + char *entry[4]; + unsigned int numCat = numCategories(), i; + unsigned int numEntr, j; + int descLen, nameLen, pwLen, commentLen; + for (i = 0; i < numCat; ++i) { + numEntr = numEntries(i); + for (j = 0; j < numEntr; ++j) { + descLen = dta[i].d[j].desc.length(); + nameLen = dta[i].d[j].name.length(); + pwLen = dta[i].d[j].pw.length(); + commentLen = dta[i].d[j].comment.length(); + entry[0] = new char[descLen + 1]; + entry[1] = new char[nameLen + 1]; + entry[2] = new char[pwLen + 1]; + entry[3] = new char[commentLen + 1]; + strcpy(entry[0], descLen == 0 ? " " : dta[i].d[j].desc.c_str()); + strcpy(entry[1], nameLen == 0 ? " " : dta[i].d[j].name.c_str()); + strcpy(entry[2], pwLen == 0 ? " " : dta[i].d[j].pw.c_str()); + strcpy(entry[3], commentLen == 0 ? " " : dta[i].d[j].comment.c_str()); + entry[0][descLen == 0 ? descLen + 1 : descLen] = '\0'; + entry[1][nameLen == 0 ? nameLen + 1 : nameLen] = '\0'; + entry[2][pwLen == 0 ? pwLen + 1 : pwLen] = '\0'; + entry[3][commentLen == 0 ? commentLen + 1 : commentLen] = '\0'; + + ret = gp.save_entry(entry); + if (ret == -1){ + delete [] entry[0]; + delete [] entry[1]; + delete [] entry[2]; + delete [] entry[3]; + gp.save_finalize(); + unlockAll_tempoary(true); + return e_writeFile; + } + + delete [] entry[0]; + delete [] entry[1]; + delete [] entry[2]; + delete [] entry[3]; + } + } + unlockAll_tempoary(true); + if (gp.save_finalize() == -1) + return e_writeFile; + + return e_success; +} + +PwMerror PwMDoc::importFromGpasman(const QString *file) +{ + PWM_ASSERT(file); + QString pw = requestMpw(false); + if (pw == "") + return e_noPw; + GpasmanFile gp; + int ret, i; + PwMerror ret2; + char *entry[4]; + PwMDataItem tmpData; + ret = gp.load_init(file->latin1(), pw.latin1()); + if (ret != 1) + return e_accessFile; + + do { + ret = gp.load_entry(entry); + if(ret != 1) + break; + tmpData.desc = entry[0]; + tmpData.name = entry[1]; + tmpData.pw = entry[2]; + tmpData.comment = entry[3]; + tmpData.lockStat = true; + tmpData.listViewPos = -1; + ret2 = addEntry(DEFAULT_CATEGORY, &tmpData, true); + for (i = 0; i < 4; ++i) + free(entry[i]); + if (ret2 == e_maxAllowedEntr) { + gp.load_finalize(); + return e_maxAllowedEntr; + } + } while (1); + gp.load_finalize(); + if (isDocEmpty()) + return e_wrongPw; // we assume this. + + flagDirty(); + return e_success; +} + +void PwMDoc::ensureLvp() +{ + if (isDocEmpty()) + return; + + vector< vector::iterator > undefined; + vector< vector::iterator >::iterator undefBegin, + undefEnd, + undefI; + vector::iterator catBegin = dta.begin(), + catEnd = dta.end(), + catI = catBegin; + vector::iterator entrBegin, entrEnd, entrI; + int lvpTop, tmpLvp; + + while (catI != catEnd) { + lvpTop = -1; + undefined.clear(); + + entrBegin = catI->d.begin(); + entrEnd = catI->d.end(); + entrI = entrBegin; + + while (entrI != entrEnd) { + tmpLvp = entrI->listViewPos; + if (tmpLvp == -1) + undefined.push_back(entrI); + else if (tmpLvp > lvpTop) + lvpTop = tmpLvp; + ++entrI; + } + undefBegin = undefined.begin(); + undefEnd = undefined.end(); + undefI = undefBegin; + while (undefI != undefEnd) { + (*undefI)->listViewPos = ++lvpTop; + ++undefI; + } + ++catI; + } +} + +QString PwMDoc::getTitle() +{ + /* NOTE: We have to ensure, that the returned title + * is unique and not reused somewhere else while + * this document is valid (open). + */ + QString title(getFilename()); + if (title.isEmpty()) { + if (unnamedNum == 0) { + unnamedNum = PwMDocList::getNewUnnamedNumber(); + PWM_ASSERT(unnamedNum != 0); + } + title = DEFAULT_TITLE; + title += " "; + title += tostr(unnamedNum).c_str(); + } + return title; +} + +bool PwMDoc::tryDelete() +{ + if (deleted) + return true; + int ret; + if (isDirty()) { + ret = dirtyAskSave(getTitle()); + if (ret == 0) { // save to disk + if (!saveDocUi(this)) + goto out_ignore; + } else if (ret == 1) { // don't save and delete + goto out_accept; + } else { // cancel operation + goto out_ignore; + } + } +out_accept: + deleted = true; + delete this; + return true; +out_ignore: + return false; +} + +#ifndef PWM_EMBEDDED +#include "pwmdoc.moc" +#endif diff --git a/pwmanager/pwmanager/pwmdoc.h b/pwmanager/pwmanager/pwmdoc.h new file mode 100644 index 0000000..9650d55 --- a/dev/null +++ b/pwmanager/pwmanager/pwmdoc.h @@ -0,0 +1,701 @@ +/*************************************************************************** + * * + * 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 2.0 of pwmanager + * and was modified to run on embedded devices that run microkde + * + * $Id$ + **************************************************************************/ + +#ifndef __PWMDOC_H +#define __PWMDOC_H + +#define PWM_FILE_VER (static_cast(0x05)) + +#define PWM_HASH_SHA1 (static_cast(0x01)) +#define PWM_HASH_SHA256 (static_cast(0x02)) +#define PWM_HASH_SHA384 (static_cast(0x03)) +#define PWM_HASH_SHA512 (static_cast(0x04)) +#define PWM_HASH_MD5 (static_cast(0x05)) +#define PWM_HASH_RMD160 (static_cast(0x06)) +#define PWM_HASH_TIGER (static_cast(0x07)) + +#define PWM_CRYPT_BLOWFISH (static_cast(0x01)) +#define PWM_CRYPT_AES128 (static_cast(0x02)) +#define PWM_CRYPT_AES192 (static_cast(0x03)) +#define PWM_CRYPT_AES256 (static_cast(0x04)) +#define PWM_CRYPT_3DES (static_cast(0x05)) +#define PWM_CRYPT_TWOFISH (static_cast(0x06)) +#define PWM_CRYPT_TWOFISH128 (static_cast(0x07)) + +#define PWM_COMPRESS_NONE (static_cast(0x00)) +#define PWM_COMPRESS_GZIP (static_cast(0x01)) +#define PWM_COMPRESS_BZIP2 (static_cast(0x02)) + +#define DEFAULT_MAX_ENTRIES (~(static_cast(0))) +#define FILE_ID_HEADER "PWM_PASSWORD_FILE" + + +#include "pwmexception.h" +#include "pwmdocui.h" +#include "configuration.h" + +#include +#include +#include + +#include + +#ifndef PWM_EMBEDDED +#else +#include +#endif + +#include +#include +#include + +using std::vector; +using std::string; +using std::pair; + +/* used in findEntry() function */ +#define SEARCH_IN_DESC (1) +#define SEARCH_IN_NAME (1 << 1) +#define SEARCH_IN_PW (1 << 2) +#define SEARCH_IN_COMMENT (1 << 3) +#define SEARCH_IN_URL (1 << 4) +#define SEARCH_IN_LAUNCHER (1 << 5) +#define SEARCH_IN_ALL (SEARCH_IN_DESC | SEARCH_IN_NAME | \ + SEARCH_IN_PW | SEARCH_IN_COMMENT | \ + SEARCH_IN_URL | SEARCH_IN_LAUNCHER) + +/** document deeplocked. Data is out for lunch to disk */ +#define DOC_STAT_DEEPLOCKED (1) +/** encrypted document on disk is dirty. data has to go to disk. */ +#define DOC_STAT_DISK_DIRTY (1 << 1) +/** we are using a chipcard to encrypt the data */ +#define DOC_STAT_USE_CHIPCARD (1 << 2) +/** use "currentPw" to unlock. (This flag is set/unset by a timer) */ +#define DOC_STAT_UNLOCK_WITHOUT_PW (1 << 3) + +class PwMDoc; +class PwMView; +class QFile; + +/* meta data for a PwMDataItem */ +struct PwMMetaData +{ + PwMMetaData() + : updateInt (0) + { } + /** creation date of the PwMDataItem to which + * this meta data belongs. + */ + QDateTime create; + /** becomes valid on this date */ + QDateTime valid; + /** expire date */ + QDateTime expire; + /** update date (last updated at this date) */ + QDateTime update; + /** update interval (in minutes). Time since the + * last update to remind the user to update the item. + * 0 disables. + */ + unsigned long updateInt; + + //US ENH: enhancements of the filestructure + /* each entry gets a unique id assigned */ + QString uniqueid; + + + void clear() + { + create = QDateTime(); + expire = QDateTime(); + update = QDateTime(); + updateInt = 0; + uniqueid = KApplication::randomString(8); + } + inline bool isValid() const + { + if (valid.isNull()) + return true; + return (valid < QDateTime::currentDateTime()); + } + inline bool isExpired() const + { + if (expire.isNull()) + return false; + return (expire < QDateTime::currentDateTime()); + } + inline bool isUpdateIntOver() const + { + if (updateInt == 0 || + update.isNull()) + return false; + QDateTime d(update); + return (d.addSecs(updateInt * 60) < QDateTime::currentDateTime()); + } +}; + +struct PwMDataItem +{ + PwMDataItem() + : lockStat (true) + , listViewPos (-1) + , binary (false) + , rev (0) + { } + + /** password description */ + string desc; + /** user-name */ + string name; + /** the password itself */ + string pw; + /** some comment */ + string comment; + /** an URL string */ + string url; + /** launcher. Can be executed as a system() command */ + string launcher; + /** locking status. If locked (true), pw is not emitted through getEntry() */ + bool lockStat; + /** position of this item in main "list-view" + * If -1, the position is not yet specified and should be appended to the list + */ + int listViewPos; + /** does this entry contain binary data? */ + bool binary; + /** meta data for this data item. */ + PwMMetaData meta; + /** data revision counter. This counter can be used + * to easily, efficiently determine if this data item + * has changed since some time. + * This counter is incremented on every update. + */ + unsigned int rev; + + void clear(bool clearMeta = true) + { + /* NOTE: Don't use .clear() here to be + * backward compatible with gcc-2 (Debian Woody) + */ + desc = ""; + name = ""; + pw = ""; + comment = ""; + url = ""; + launcher = ""; + lockStat = true; + listViewPos = -1; + binary = false; + if (clearMeta) + meta.clear(); + } +}; + +struct PwMCategoryItem +{ + /** all PwMDataItems (all passwords) within this category */ + vector d; + /** category name/description */ + string name; + + void clear() + { + d.clear(); + name = ""; + } +}; + +/** "Function Object" for sort()ing PwMDataItem::listViewPos */ +class dta_lvp_greater +{ +public: + bool operator() (const pair &d1, + const pair &d2) + { + return d1.second > d2.second; + } +}; + +/** list of PwMDoc documents and it's IDs */ +class PwMDocList +{ +public: + struct listItem + { + /** document filename (known as ID, here) */ + string docId; + /** pointer to the document class */ + PwMDoc *doc; + }; + + PwMDocList() {} + + /** add a new item to the list */ + void add(PwMDoc *doc, const string &id); + /** changes the contents of an existing item */ + void edit(PwMDoc *doc, const string &newId); + /** remove the given item */ + void del(PwMDoc *doc); + /** get the item at index */ + listItem getAt(int index) + { return docList[index]; } + /** find an entry with this id */ + bool find(const string &id, listItem *ret = 0); + /** returns a copy of the list */ + const vector* getList() const + { return &docList; } + + + /** returns a new unique number to extend the name of + * an unnamed document. + */ + static unsigned int getNewUnnamedNumber() + { return unnamedDocCnt++; } + +protected: + /* Hm, I think we shouldn't really use a "list" here, should we? + * So I decided to actually use a vector. + */ + vector docList; + /** This value is used to get a new number for yet unnamed + * documents. It is incremented on every request. So it's + * theoretically possible to overflow it, but... :) + */ + static unsigned int unnamedDocCnt; +}; + +/** implements timers for the document */ +class DocTimer : public QObject +{ + Q_OBJECT +public: + enum TimerIDs + { + id_mpwTimer, + id_autoLockTimer, + id_metaCheckTimer + }; + +public: + DocTimer(PwMDoc *_doc); + ~DocTimer(); + + /** start the timer */ + void start(TimerIDs timer); + /** stop the timer */ + void stop(TimerIDs timer); + /** get the lock for a timer. + * This lock is a recursive lock. When a lock is + * held, the timer will be stopped and timeout is + * guaranteed to not happen + */ + void getLock(TimerIDs timer); + /** put a recursive timer lock */ + void putLock(TimerIDs timer); + +protected slots: + /** timeout slot for the mpw timer */ + void mpwTimeout(); + /** timeout slot for the autoLock timer */ + void autoLockTimeout(); + /** timeout slot for the metaCheck timer */ + void metaCheckTimeout(); + +protected: + /** pointer to the document associated with this timer. */ + PwMDoc *doc; + /** timer object for mpw timer */ + QTimer *mpwTimer; + /** timer object for the autoLock timer */ + QTimer *autoLockTimer; + /** timer object for the metaCheck timer */ + QTimer *metaCheckTimer; + /** lock counter for the mpw timer */ + unsigned int mpwLock; + /** lock counter for the autoLock timer */ + unsigned int autoLockLock; + /** lock counter for the metaCheck timer */ + unsigned int metaCheckLock; +}; + +/** Document class for PwM */ +class PwMDoc : public PwMDocUi +{ + Q_OBJECT + friend class DocTimer; + +public: + /** construtor */ + PwMDoc(QObject* parent = 0, const char *name = 0); + /** destructor */ + ~PwMDoc(); + + /** returns a pointer to a list of all open documents */ + static PwMDocList* getOpenDocList() + { return &openDocList; } + + /** flag document dirty. dta changed */ + void flagDirty() + { + setDocStatFlag(DOC_STAT_DISK_DIRTY); + emitDataChanged(this); + } + /** modified? */ + bool isDirty() + { return getDocStatFlag(DOC_STAT_DISK_DIRTY); } + /** save document to disk */ + PwMerror saveDoc(char compress, const QString *file = 0); + /** read document from file. + * "openLocked is must be set to either of these values: + * 0 == open with all entries unlocked + * 1 == open with all entries locked + * 2 == open deep-locked + */ + PwMerror openDoc(const QString *file, int openLocked); + /** export document to ascii-textfile */ + PwMerror exportToText(const QString *file); + /** export document to gpasman / kpasman file */ + PwMerror exportToGpasman(const QString *file); + /** import document from ascii-textfile */ + PwMerror importFromText(const QString *file, int format = -1); + /** import document from gpasman / kpasman file */ + PwMerror importFromGpasman(const QString *file); + /** add new entry */ + PwMerror addEntry(const QString &category, PwMDataItem *d, + bool dontFlagDirty = false, bool updateMeta = true); + /** add new category. This function doesn't flag the document dirty! */ + PwMerror addCategory(const QString &category, unsigned int *categoryIndex, + bool checkIfExist = true); + /** rename an existing category */ + bool renameCategory(const QString &category, const QString &newName); + /** rename an existing category */ + bool renameCategory(unsigned int category, const QString &newName, + bool dontFlagDirty = false); + /** delete an existing category */ + bool delCategory(const QString &category); + /** delete an existing category */ + bool delCategory(unsigned int category, bool dontFlagDirty = false); + /** returns a list of all category-names */ + void getCategoryList(vector *list); + /** returns a list of all category-names */ + void getCategoryList(QStringList *list); + /** returns a list of all entry-descs in the given category */ + void getEntryList(const QString &category, QStringList *list); + /** returns a list of all entry-descs in the given category */ + void getEntryList(const QString &category, vector *list); + /** returns a list of all entry-descs in the given category */ + void getEntryList(unsigned int category, vector *list); + /** returns a list of all entry-descs in the given category */ + void getEntryList(unsigned int category, QStringList *list); + /** delete entry */ + bool delEntry(const QString &category, unsigned int index, bool dontFlagDirty = false); + /** delete entry */ + bool delEntry(unsigned int category, unsigned int index, bool dontFlagDirty = false); + /** edit entry */ + bool editEntry(const QString &oldCategory, const QString &newCategory, + unsigned int index, PwMDataItem *d, bool updateMeta = true); + /** edit entry */ + bool editEntry(unsigned int oldCategory, const QString &newCategory, + unsigned int index, PwMDataItem *d, bool updateMeta = true); + /** finds the category with the "name" and return it's index */ + bool findCategory(const QString &name, unsigned int *index); + /** search for an entry "find" and check while searching only for + * the data-fields specified by "searchIn". To set the "searchIn" + * value, we may use one or more of the SEARCH_IN_* defines at + * the top of this header-file. It returns the positions of all + * matched entries in "foundPositions". If "breakAfterFound" is true, + * the function terminates after the first occurence of the entry + * and doesn't go on searching. So foundPositions->size() is never + * > 1 if breakAfterFound is true. + */ + void findEntry(unsigned int category, PwMDataItem find, unsigned int searchIn, + vector *foundPositions, bool breakAfterFound = false, + bool caseSensitive = true, bool exactWordMatch = true, + bool sortByLvp = false); + /** see the above funtion. This function allows to set the category by name. */ + void findEntry(const QString &category, PwMDataItem find, unsigned int searchIn, + vector *foundPositions, bool breakAfterFound = false, + bool caseSensitive = true, bool exactWordMatch = true, + bool sortByLvp = false); + /** returns number of entries */ + unsigned int numEntries(const QString &category); + unsigned int numEntries(unsigned int category) + { return dta[category].d.size(); } + /** returns number of categories */ + unsigned int numCategories() + { return dta.size(); } + /** returns the name of the category at "index" */ + const string* getCategory(unsigned int index) + { return (&(dta[index].name)); } + /** returns the data of item at "index". + * It unlocks the entry if it's locked and unlockIfLocked is true. + * If the entry is locked, but unlockIfLocked is false, it'll not return + * the pw. + */ + bool getEntry(const QString &category, unsigned int index, + PwMDataItem *d, bool unlockIfLocked = false); + bool getEntry(unsigned int category, unsigned int index, + PwMDataItem *d, bool unlockIfLocked = false); + /** returns the comment-string by looking at the category + * and the listViewPos + */ + PwMerror getCommentByLvp(const QString &category, int listViewPos, + string *foundComment); + /** checks if a password is already available. (currentPw) */ + bool isPwAvailable() + { return (currentPw != ""); } + /** un/lock entry at "index". If needed, ask for password. */ + bool lockAt(const QString &category, unsigned int index, + bool lock = true); + bool lockAt(unsigned int category, unsigned int index, + bool lock = true); + /** returns the lock-status at "index" */ + bool isLocked(const QString &category, unsigned int index); + bool isLocked(unsigned int category, unsigned int index) + { return dta[category].d[index].lockStat; } + /** returns the deeplock status */ + bool isDeepLocked() + { return getDocStatFlag(DOC_STAT_DEEPLOCKED); } + /** (un)lock all entries */ + bool lockAll(bool lock); + /** unlocks all entries tempoarly. + * 1st NOTE: Be very careful with this function! :) + * 2nd NOTE: After you have called unlockAll_Tempoary(); , + * please DON'T forget to call unlockAll_Tempoary(true); + * _before_ the user (or someone else) is able to change + * the document! + * 3rd NOTE: Please DON'T change "dta" while the data is tempoary + * unlocked! This will cause corruption. + */ + bool unlockAll_tempoary(bool revert = false); + /** deep-(un)locks the document. + * deep-locking writes all data to the file, deletes all data + * in memory, but doesn't close the document. + * deep-locking is only available, if the user previously saved + * the doc to a file (with a password). + * If "saveToFile" is false, it does NOT write the data to the file! + */ + PwMerror deepLock(bool lock = true, bool saveToFile = true); + /** is unlockable without pw? */ + bool unlockWoPw() + { return getDocStatFlag(DOC_STAT_UNLOCK_WITHOUT_PW); } + /** get the "currentPassword" */ + const QString& getCurrentPw() + { return currentPw; } + /** open a window and request the user to change the mpw */ + void changeCurrentPw(); + /** set the "listViewPos" variable of "dta" */ + void setListViewPos(const QString &category, unsigned int index, + int pos); + /** set the "listViewPos" variable of "dta" */ + void setListViewPos(unsigned int category, unsigned int index, + int pos); + /** get the "listViewPos" variable of "dta" */ + int getListViewPos(const QString &category, unsigned int index); + /** set the maximum number of entries allowed */ + void setMaxNumEntries(unsigned int num = DEFAULT_MAX_ENTRIES) + { maxEntries = num; } + /** get the maximum number of entries allowed */ + unsigned int getMaxNumEntries() + { return maxEntries; } + /** ensure all listViewPos of all dta items are set. (are ! -1). + * If there are some undefined entries, add them to the end of + * the listViewPos(itions). */ + void ensureLvp(); + /** execute the "launcher" of this entry */ + bool execLauncher(const QString &category, unsigned int entryIndex); + /** see above */ + bool execLauncher(unsigned int category, unsigned int entryIndex); + /** open a browser with the URL-section of the given entry */ + bool goToURL(const QString &category, unsigned int entryIndex); + /** see above */ + bool goToURL(unsigned int category, unsigned int entryIndex); + /** returns true if there is no entry present in the document. + * Note: The "default" Category is present everytime, so + * it's checked for it's entries. + */ + bool isDocEmpty() + { + if (numCategories() > 1) + return false; + if (numEntries(0)) + return false; + return true; + } + /** returns the filename of this doc */ + const QString& getFilename() + { return filename; } + /** returns the title of the doc */ + QString getTitle(); + /** sets the list-view-pointer hold in the doc */ + void setListViewPointer(PwMView *_listView) + { listView = _listView; } + /** returns the list-view-pointer */ + PwMView * getListViewPointer() + { return listView; } + /** try to delete the doc. The user may be asked to save + * the data. The user may cancel the whole operation. + * false is returned, then. + */ + bool tryDelete(); + /** is the doc deleted? (with tryDelete() ) */ + bool isDeleted() + { return deleted; } + /** returns the document timer object */ + DocTimer * timer() + { return _timer; } + /** get a lock on the dataChanged signal. + * If someone is holding a lock, the signal is not emitted. + */ + void getDataChangedLock() + { ++dataChangedLock; } + /** put the dataChanged lock */ + void putDataChangedLock() + { --dataChangedLock; } + /** returns the revision count of the item at cat/index */ + unsigned int getEntryRevCnt(unsigned int category, unsigned int index) + { return dta[category].d[index].rev; } + /** returns a const pointer to the entries meta */ + const PwMMetaData * getEntryMeta(unsigned int category, unsigned int index) + { return &(dta[category].d[index].meta); } + /** is the entry at "category" "index" a binary entry? */ + bool isBinEntry(unsigned int category, unsigned int index) + { return dta[category].d[index].binary; } + +public slots: + /** wrapper for PwMTray */ + void _deepUnlock(); + +signals: + /** the data of the document has changed and must be updated + * in all views. + * NOTE: use emitDataChanged(PwMDoc *document) to emit this signal! + */ + void dataChanged(PwMDoc *document); + /** the document class is going to close. This signal may be + * used to nofify all views, that the user closed the document, + * so the views can go down, too. + */ + void docClosed(PwMDoc *document); + /** somebody just opened the document */ + void docOpened(PwMDoc *document); + /** this document object just got created */ + void docCreated(PwMDoc *document); + +public: + /** emit the dataChanged signal after checking for a lock */ + void emitDataChanged(PwMDoc *document) + { + if (!dataChangedLock) + emit dataChanged(document); + } + +protected: + /** current file for this doc */ + QString filename; + /** holds all data */ + vector dta; + /** maximum number of entries */ + unsigned int maxEntries; + /** currently used password to encrypt data */ + QString currentPw; + /** current global document status flags */ + unsigned int curDocStat; + /** browser process for goToURL() */ + KProcess browserProc; + /** pointer to the list-view, using this document. + * As there can only be one list-view per doc, we + * don't need a list here. + */ + PwMView *listView; + /** unnamedNum is used to store the "unnamed counter" + * for this document, while it's unnamed. If it's 0, + * we have to get a new unique one. + */ + unsigned int unnamedNum; + /** is this doc going to be deleted (executing in destructor context) */ + bool deleted; + /** document timer */ + DocTimer *_timer; + /** lock counter for the "dataChanged" signal */ + unsigned int dataChangedLock; + + /** list of all open documents */ + static PwMDocList openDocList; + +protected: + /** serialize "dta" and return it in "d". */ + bool serializeDta(string *d); + /** de-serialize "d" and overwrite "dta" */ + bool deSerializeDta(const string *d, bool entriesLocked); + /** write header to file */ + PwMerror writeFileHeader(char keyHash, char dataHash, char crypt, char compress, + QString *pw, QFile *f); + /** write data-hash to file */ + PwMerror writeDataHash(char dataHash, string *d, QFile *f); + /** check header. Read header info and verify key-hash and filever. + * returns length of header in "headerLength" */ + PwMerror checkHeader(char *cryptAlgo, QString *pw, char *compress, + unsigned int *headerLength, char *dataHashType, + string *dataHash, QFile *f); + /** check the data-hash */ + PwMerror checkDataHash(char dataHashType, const string *dataHash, const string *dataStream); + /** encrypt data "d" and write to "filename" */ + PwMerror encrypt(string *d, const QString *pw, QFile *f, char algo); + /** read data from file beginning at "pos", decrypt and return it */ + PwMerror decrypt(string *d, unsigned int pos, const QString *pw, char algo, QFile *f); + /** compress the data */ + bool compressDta(string *d, char algo); + /** uncompress the data */ + bool decompressDta(string *d, char algo); + /** internal import function for a text-file generated by PwM. + * If this is not a valid PwM-exported file, it returns e_fileFormat */ + PwMerror importText_PwM(const QString *file); + /** PwM-text-import helper function to extract the name/pw/comment out + * of one entry-line */ + bool textExtractEntry_PwM(const char *in, ssize_t in_size, string *out); + /** compare two strings */ + bool compareString(const string &s1, const string &s2, bool caseSensitive, + bool exactWordMatch); + /** clears all document-data */ + void clearDoc(); + /** delete all empty categories */ + void delAllEmptyCat(bool dontFlagDirty); + /** set a document status flag */ + void setDocStatFlag(unsigned int statFlag) + { curDocStat |= statFlag; } + /** unset a document status flag */ + void unsetDocStatFlag(unsigned int statFlag) + { curDocStat &= ~statFlag; } + /** get a document status flag */ + bool getDocStatFlag(unsigned int statFlag) const + { return (curDocStat & statFlag); } + /** set the "currentPassword" */ + void setCurrentPw(const QString &pw) + { + currentPw = pw; + setDocStatFlag(DOC_STAT_DISK_DIRTY); + } + /** make a backup-copy of the given file */ + bool backupFile(const QString &filePath); + /** copy a file from src to dst */ + bool copyFile(const QString &src, const QString &dst); +}; + +#endif diff --git a/pwmanager/pwmanager/pwmdocui.cpp b/pwmanager/pwmanager/pwmdocui.cpp new file mode 100644 index 0000000..66a1b59 --- a/dev/null +++ b/pwmanager/pwmanager/pwmdocui.cpp @@ -0,0 +1,436 @@ +/*************************************************************************** + * * + * 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$ + **************************************************************************/ + +#include "pwmdocui.h" +#include "setmasterpwwndimpl.h" +#include "getmasterpwwndimpl.h" +#include "pwmexception.h" +#include "getkeycardwnd.h" +#include "pwm.h" +#include "globalstuff.h" +#include "spinforsignal.h" + +#include +#include + +#include +#include + +#ifndef PWM_EMBEDDED +#include +#else +#endif + + +#ifdef CONFIG_KEYCARD +# include "pwmkeycard.h" +#endif + + +PwMDocUi::PwMDocUi(QObject *parent, const char *name) + : QObject(parent, name) +{ + currentView = 0; + keyCard = 0; +} + +PwMDocUi::~PwMDocUi() +{ +} + +QString PwMDocUi::requestMpw(bool chipcard) +{ + QString pw; + + if (chipcard) { +#ifdef CONFIG_KEYCARD + PWM_ASSERT(keyCard); + uint32_t id; + string ret; + SpinForSignal *spinner = keyCard->getSpinner(); + connect(keyCard, SIGNAL(keyAvailable(uint32_t, const string &)), + spinner, SLOT(u32_str_slot(uint32_t, const string &))); + keyCard->getKey(); + spinner->spin(&id, &ret); + disconnect(keyCard, SIGNAL(keyAvailable(uint32_t, const string &)), + spinner, SLOT(u32_str_slot(uint32_t, const string &))); + if (ret == "") + return ""; + pw = ret.c_str(); +#else // CONFIG_KEYCARD + no_keycard_support_msg_box(currentView); +#endif // CONFIG_KEYCARD + } else { + GetMasterPwWndImpl pwWnd; +#ifndef PWM_EMBEDDED + KWin::setState(pwWnd.winId(), NET::StaysOnTop); +#endif + if (pwWnd.exec() != 1) + return ""; + pw = pwWnd.pwLineEdit->text(); + } + + return pw; +} + +QString PwMDocUi::requestNewMpw(bool *chipcard) +{ + QString pw; + SetMasterPwWndImpl pwWnd(currentView); + pwWnd.setPwMKeyCard(keyCard); +#ifndef PWM_EMBEDDED + if (!chipcard) { + pwWnd.mainTab->removePage(pwWnd.mainTab->page(1)); + } +#else + qDebug("PwMDocUi::requestNewMpw must be implemented"); +#endif + + if (pwWnd.exec() != 1) + return ""; + pw = pwWnd.getPw(chipcard).c_str(); + + return pw; +} + +QString PwMDocUi::requestMpwChange(const QString *currentPw, bool *chipcard) +{ + QString pw(requestMpw(*chipcard)); + if (pw == "") + return ""; + if (pw != *currentPw) { + wrongMpwMsgBox(*chipcard); + return ""; + } + + pw = requestNewMpw(chipcard); + if (pw == "") + return ""; + return pw; +} + +void PwMDocUi::wrongMpwMsgBox(bool chipcard, QString prefix, QString postfix) +{ + QString msg; + if (prefix != "") { + msg += prefix; + msg += "\n"; + } + + if (chipcard) { + msg += i18n("Wrong key-card!\n" + "Please try again with the " + "correct key-card."); + } else { + msg += i18n("Wrong master-password!\n" + "Please try again."); + } + + if (postfix != "") { + msg += "\n"; + msg += postfix; + } + KMessageBox::error(currentView, msg, + (chipcard) ? (i18n("wrong chipcard")) + : (i18n("password error"))); +} + +void PwMDocUi::noMpwMsgBox(bool chipcard, QString prefix, QString postfix) +{ + QString msg; + if (prefix != "") { + msg += prefix; + msg += "\n"; + } + + if (chipcard) { + msg += i18n("No key-card found!\n" + "Please insert the " + "correct key-card."); + } else { + msg += i18n("No master-password given!"); + } + + if (postfix != "") { + msg += "\n"; + msg += postfix; + } + KMessageBox::error(currentView, msg, + (chipcard) ? (i18n("no chipcard")) + : (i18n("password error"))); +} + +void PwMDocUi::rootAlertMsgBox() +{ + KMessageBox::error(currentView, + i18n("This feature is not available, " + "if you execute PwM with \"root\" " + "UID 0 privileges, for security reasons!"), + i18n("not allowed as root!")); +} + +void PwMDocUi::cantDeeplock_notSavedMsgBox() +{ + KMessageBox::error(currentView, + i18n("Can't deep-lock, because the document " + "hasn't been saved, yet. Please save " + "to a file and try again."), + i18n("not saved, yet")); +} + +void PwMDocUi::gpmPwLenErrMsgBox() +{ + KMessageBox::error(currentView, + i18n("GPasman does not support passwords " + "shorter than 4 characters! Please try " + "again with a longer password."), + i18n("password too short")); +} + +int PwMDocUi::dirtyAskSave(const QString &docTitle) +{ + int ret; +#ifndef PWM_EMBEDDED + ret = KMessageBox::questionYesNoCancel(currentView, + i18n("The list \"") + + docTitle + + i18n + ("\" has been modified.\n" + "Do you want to save it?"), + i18n("save?")); + if (ret == KMessageBox::Yes) { + return 0; + } else if (ret == KMessageBox::No) { + return 1; + } +#else + ret = KMessageBox::warningYesNoCancel(currentView, + i18n("The list \"") + + docTitle + + i18n + ("\" has been modified.\n" + "Do you want to save it?"), + i18n("save?")); + if (ret == KMessageBox::Yes) { + return 0; + } else if (ret == KMessageBox::No) { + return 1; + } + +#endif + + // cancel + return -1; +} + +bool PwMDocUi::saveDocUi(PwMDoc *doc) +{ + PWM_ASSERT(doc); + doc->timer()->getLock(DocTimer::id_autoLockTimer); + if (doc->isDocEmpty()) { + KMessageBox::information(currentView, + i18n + ("Sorry, there's nothing to save.\n" + "Please first add some passwords."), + i18n("nothing to do")); + doc->timer()->putLock(DocTimer::id_autoLockTimer); + return true; + } + PwMerror ret = doc->saveDoc(conf()->confGlobCompression()); + if (ret == e_filename) { + doc->timer()->putLock(DocTimer::id_autoLockTimer); + return saveAsDocUi(doc); + } else if (ret == e_weakPw) { + KMessageBox::error(currentView, + i18n("Error: This is a weak password.\n" + "Please select another password."), + i18n("weak password")); + doc->timer()->putLock(DocTimer::id_autoLockTimer); + return false; + } else if (ret == e_fileBackup) { + KMessageBox::error(currentView, + i18n("Error: Couldn't make backup-file!"), + i18n("backup failed")); + doc->timer()->putLock(DocTimer::id_autoLockTimer); + return false; + } else if (ret != e_success) { + KMessageBox::error(currentView, + 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")); + doc->timer()->putLock(DocTimer::id_autoLockTimer); + return false; + } + doc->timer()->putLock(DocTimer::id_autoLockTimer); + return true; +} + +bool PwMDocUi::saveAsDocUi(PwMDoc *doc) +{ + PWM_ASSERT(doc); + doc->timer()->getLock(DocTimer::id_autoLockTimer); + if (doc->isDocEmpty()) { + KMessageBox::information(currentView, + i18n + ("Sorry, there's nothing to save.\n" + "Please first add some passwords."), + i18n("nothing to do")); + doc->timer()->putLock(DocTimer::id_autoLockTimer); + return true; + } + QString fn(KFileDialog::getSaveFileName(QString::null, + i18n("*.pwm|PwManager Password file"), + currentView)); + if (fn == "") { + doc->timer()->putLock(DocTimer::id_autoLockTimer); + return false; + } + if (fn.right(4) != ".pwm") + fn += ".pwm"; + + PwMerror ret = doc->saveDoc(conf()->confGlobCompression(), &fn); + if (ret != e_success) { + KMessageBox::error(currentView, + 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")); + doc->timer()->putLock(DocTimer::id_autoLockTimer); + return false; + } + doc->timer()->putLock(DocTimer::id_autoLockTimer); + return true; +} + +bool PwMDocUi::openDocUi(PwMDoc *doc, + QString filename, + bool openDeepLocked) +{ + if (filename.isEmpty()) + filename = KFileDialog::getOpenFileName(QString::null, + i18n("*.pwm|PwManager Password file\n" + "*|All files"), getCurrentView()); + if (filename.isEmpty()) + goto cancelOpen; + PwMerror ret; + while (true) { + int lockStat = -1; + if (openDeepLocked) { + lockStat = 2; + } else { + if (conf()->confGlobUnlockOnOpen()) { + lockStat = 0; + } else { + lockStat = 1; + } + } + ret = doc->openDoc(&filename, lockStat); + if (ret != e_success) { + if (ret == e_readFile || ret == e_openFile) { + KMessageBox::error(getCurrentView(), + i18n("Could not read file!") + + "\n" + + filename, + i18n("file error")); + goto cancelOpen; + } + if (ret == e_alreadyOpen) { + KMessageBox::error(getCurrentView(), + i18n("This file is already open."), + i18n("already open")); + goto cancelOpen; + } + if (ret == e_fileVer) { + KMessageBox::error(getCurrentView(), + i18n + ("File-version is not supported!\n" + "Did you create this file with an older or newer version of PwM?"), + i18n + ("incompatible version")); + goto cancelOpen; + } + if (ret == e_wrongPw) { + continue; + } + if (ret == e_noPw) { + goto cancelOpen; + } + if (ret == e_fileFormat) { + KMessageBox::error(getCurrentView(), + i18n + ("Sorry, this file has not been recognized " + "as a PwM Password file.\n" + "Probably you have selected the wrong file."), + i18n + ("no PwM password-file")); + goto cancelOpen; + } + if (ret == e_fileCorrupt) { + KMessageBox::error(getCurrentView(), + i18n + ("File corrupt!\n" + "Maybe the media, you stored this file on, " + "had bad sectors?"), + i18n + ("checksum error")); + goto cancelOpen; + } + } + break; + } + return true; + + cancelOpen: + return false; +} + +QString PwMDocUi::string_defaultCategory() +{ + return i18n("Default"); +} + +QString PwMDocUi::string_locked() +{ + return i18n(""); +} + +QString PwMDocUi::string_deepLockedShort() +{ + return i18n("DEEP-LOCKED"); +} + +QString PwMDocUi::string_deepLockedLong() +{ + return i18n("This file is DEEP-LOCKED!\n" + "That means all data has been encrypted " + "and written out to the file. If you want " + "to see the entries, please UNLOCK the file. " + "While unlocking, you will be prompted for the " + "master-password or the key-card."); +} + +QString PwMDocUi::string_defaultTitle() +{ + return i18n("Untitled"); +} + +#ifndef PWM_EMBEDDED +#include "pwmdocui.moc" +#endif diff --git a/pwmanager/pwmanager/pwmdocui.h b/pwmanager/pwmanager/pwmdocui.h new file mode 100644 index 0000000..4ee0ad4 --- a/dev/null +++ b/pwmanager/pwmanager/pwmdocui.h @@ -0,0 +1,129 @@ +/*************************************************************************** + * * + * 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 __PWMDOCUI_H +#define __PWMDOCUI_H + +#include +#include + +/** string to display, if the pw-entry + * is locked, in place of the password. + */ +#define LOCKED_STRING PwMDocUi::string_locked() + +/** The name of the "default" category */ +#define DEFAULT_CATEGORY PwMDocUi::string_defaultCategory() + +/** deep-lock message to display in main-view, if it's locked */ +#define IS_DEEPLOCKED_SHORTMSG PwMDocUi::string_deepLockedShort() +#define IS_DEEPLOCKED_MSG PwMDocUi::string_deepLockedLong() + +/** default title. Display if the doc has no title, yet */ +#define DEFAULT_TITLE PwMDocUi::string_defaultTitle() + +class PwMKeyCard; +class PwMDoc; + +/** User-interface layer for PwMDoc. + * This class handles for example all Master-password related things (asking + * the user for the password od the chipcard) and some + * other UI-things, that PwMDoc is not allowed to + * handle. (PwMDoc is _NOT_ allowed to handle anything + * UI related.) + */ +class PwMDocUi : public QObject +{ + Q_OBJECT +public: + PwMDocUi(QObject* parent = 0, const char *name = 0); + ~PwMDocUi(); + + /** when a new view is activated, call this to + * inform the Master-password-layer about this. + */ + void setCurrentView(QWidget *view) + { currentView = view; } + /** return the currentView pointer */ + QWidget* getCurrentView() + { return currentView; } + /** set pointer to the keycard-access object */ + void setPwMKeyCard(PwMKeyCard *_keyCard) + { keyCard = _keyCard; } + /** saves the document (with user dialog) */ + bool saveDocUi(PwMDoc *doc); + /** save as (with user dialog) */ + bool saveAsDocUi(PwMDoc *doc); + /** opens a new document (with user dialog) */ + bool openDocUi(PwMDoc *doc, + QString filename = QString::null, + bool openDeepLocked = false); + + static QString string_defaultCategory(); + static QString string_locked(); + static QString string_deepLockedShort(); + static QString string_deepLockedLong(); + static QString string_defaultTitle(); + +protected: + /** request the user to enter the master-password or + * to insert his chipcard. + * If forcePw is true, it will always ask for a pw + * and never for a chipcard. + */ + QString requestMpw(bool chipcard); + /** request the user to enter a new master-password of + * to create a new chipcard. + * It "chipcard" is a NULL pointer, chipcards will not be + * allowed. + */ + QString requestNewMpw(bool *chipcard); + /** request a master-pw change.(or chipcard change). + * This function asks the user and requests the pw + */ + QString requestMpwChange(const QString *currentPw, bool *chipcard); + /** informs the user, that he entered the wrong mpw. + * It opens a message-box + */ + void wrongMpwMsgBox(bool chipcard, + QString prefix = "", + QString postfix = ""); + /** informs the user, that the mpw is needed, but he + * didn't enter one + */ + void noMpwMsgBox(bool chipcard, + QString prefix = "", + QString postfix = ""); + /** display "feature not availavle while UID 0" msg box */ + void rootAlertMsgBox(); + /** display "can't deeplock, because not saved yet" msg box */ + void cantDeeplock_notSavedMsgBox(); + /** gpasman-export password length error */ + void gpmPwLenErrMsgBox(); + /** ask for saving */ + int dirtyAskSave(const QString &docTitle); + +private: + /** the currently active view */ + QWidget *currentView; + /** pointer to the keycard-access object */ + PwMKeyCard *keyCard; +}; + +#endif diff --git a/pwmanager/pwmanager/pwmexception.cpp b/pwmanager/pwmanager/pwmexception.cpp new file mode 100644 index 0000000..4c00b04 --- a/dev/null +++ b/pwmanager/pwmanager/pwmexception.cpp @@ -0,0 +1,58 @@ +/*************************************************************************** + * * + * 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$ + **************************************************************************/ + + +#include "pwmexception.h" + +#include + + +void pwmFatal(const char *id, + const char *file, + int line) +{ + cerr << PROG_NAME " " << id << " at " + << file << ":" << line + << endl; +} + +void __printError(const string &msg) +{ + QString __msg(PROG_NAME " generated a fatal fault:\n"); + __msg += msg.c_str(); + cerr << "\n\n" << __msg.latin1() << endl; + KMessageBox::error(0, __msg, PROG_NAME " fatal ERROR!"); +} + +void __printInfo(const string &msg) +{ + cout << PROG_NAME " INFO: " << msg << endl; +} + +void __printWarn(const string &msg) +{ + cerr << PROG_NAME " WARNING: " << msg << endl; +} + +#ifdef PWM_DEBUG +void __printDebug(const string &msg) +{ + cout << PROG_NAME " DEBUG: " << msg << endl; +} +#endif // PWM_DEBUG diff --git a/pwmanager/pwmanager/pwmexception.h b/pwmanager/pwmanager/pwmexception.h new file mode 100644 index 0000000..c8a8c0f --- a/dev/null +++ b/pwmanager/pwmanager/pwmexception.h @@ -0,0 +1,216 @@ +/*************************************************************************** + * * + * 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 __PWMEXCEPTION_H +#define __PWMEXCEPTION_H + +#include "globalstuff.h" + +#include +#include +using std::string; +using std::cerr; +using std::cout; +using std::endl; + +/* This is an internal function to reduce code-overhead + * of the BUG(), WARN(), TOD0() and FiXME() macros. Please use + * these macros instead of calling this function directly. + */ +void pwmFatal(const char *id, + const char *file, + int line); + +/** Use PWM_ASSERT(condition) for debugging assertions. + * "condition" is eaten up and replaced with a NOP + * when debugging is disabled. + * + * PWM_ASSERT_NOEAT(condition) is the same as PWM_ASSERT(condition), + * but it does _not_ eat up "condition" and ensures that + * condition is always evaluated. + */ +#ifdef PWM_ASSERT +# undef PWM_ASSERT +#endif +#ifdef PWM_ASSERT_NOEAT +# undef PWM_ASSERT_NOEAT +#endif +#ifdef PWM_DEBUG +# define PWM_ASSERT(x) do { \ + if (unlikely(!(x))) { \ + cerr << "PWM_ASSERT failed: (" << #x \ + << ") in " << __FILE__ \ + << ":" << __LINE__ \ + << endl; \ + } \ + } while (0) +# define PWM_ASSERT_NOEAT(x) do { PWM_ASSERT(x); } while (0) +#else // PWM_DEBUG +# define PWM_ASSERT(x) do { } while (0) +# define PWM_ASSERT_NOEAT(x) do { if (x) ; } while (0) +#endif // PWM_DEBUG + +/** Insert a BUG() into code paths which clearly show + * a bug in the code and which should, under normal + * circumstances, never execute. + */ +#ifdef BUG +# undef BUG +#endif +#define BUG() do { pwmFatal("BUG", __FILE__, __LINE__); } while (0) + +/** Use BUG_ON(condition) to print a bug-message if "condition" + * is true. This is also enabled in non-debugging code. + */ +#ifdef BUG_ON +# undef BUG_ON +#endif +#define BUG_ON(x) do { if (unlikely(x)) BUG(); } while (0) + +/** Insert a WARN() into code-paths which should not + * execute normally, but if they do it's non-fatal. + */ +#ifdef WARN +# undef WARN +#endif +#define WARN() do { pwmFatal("badness", __FILE__, __LINE__); } while (0) + +/** Same as BUG_ON() but prints a warning-message */ +#ifdef WARN_ON +# undef WARN_ON +#endif +#define WARN_ON(x) do { if (unlikely(x)) WARN(); } while (0) + +/** Insert this into code which is incomplete */ +#ifdef TODO +# undef TODO +#endif +#define TODO() do { pwmFatal("TODO", __FILE__, __LINE__); } while (0) + +/** Insert this into code which likely contains bugs */ +#ifdef FIXME +# undef FIXME +#endif +#define FIXME() do { pwmFatal("FIXME", __FILE__, __LINE__); } while (0) + + +/** PwM error codes */ +enum PwMerror { + e_success = 0, + + // file access errors + e_filename, + e_readFile, + e_writeFile, + e_openFile, + e_accessFile, // permission error, etc... + e_fileGeneric, + e_alreadyOpen, + + // other file errors + e_fileVer, + e_fileFormat, // format error + e_unsupportedFormat, // completely unsupported format + e_setFilePointer, + e_fileBackup, + e_fileCorrupt, // file data has correct format, + // but is corrupt (checksum error, etc) + + // password errors + e_wrongPw, + e_getPw, + e_weakPw, + e_noPw, + + // action not implemented errors + e_hashNotImpl, + e_cryptNotImpl, + + // argument/parameter errors + e_incompleteArg, + e_invalidArg, + + // misc + e_writeHeader, + e_serializeDta, + e_enc, + e_entryExists, + e_categoryExists, + e_maxAllowedEntr, // no more entries can be added. + e_outOfMem, + e_lock, // error while (un)locking + e_docNotSaved, // doc wasn't saved to a file, yet. + e_docIsEmpty, + e_binEntry, + e_normalEntry, + + e_generic +}; + +/** can be used for general exception faults */ +class PwMException +{ +public: + enum exceptionId + { + EX_GENERIC = 0, + EX_OPEN, + EX_CLOSE, + EX_READ, + EX_WRITE, + EX_LOAD_MODULE, + EX_PARSE + }; + +public: + PwMException(exceptionId id = EX_GENERIC, + const char *message = "") + { + exId = id; + exMsg = message; + } + + exceptionId getId() + { return exId; } + const char* getMessage() + { return exMsg; } + +protected: + /** ID of this exception */ + exceptionId exId; + /** additional error-message for this exception */ + const char *exMsg; +}; + +void __printInfo(const string &msg); +void __printWarn(const string &msg); +void __printError(const string &msg); + +#ifdef PWM_DEBUG + void __printDebug(const string &msg); +# define printDebug(x) __printDebug(x) +#else +# define printDebug(x) do { } while (0) +#endif + +#define printInfo(x) __printInfo(x) +#define printWarn(x) __printWarn(x) +#define printError(x) __printError(x) + +#endif // __PWMEXCEPTION_H diff --git a/pwmanager/pwmanager/pwminit.cpp b/pwmanager/pwmanager/pwminit.cpp new file mode 100644 index 0000000..b0a78c2 --- a/dev/null +++ b/pwmanager/pwmanager/pwminit.cpp @@ -0,0 +1,617 @@ +/*************************************************************************** + * * + * 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 "pwminit.h" +#include "configuration.h" +#include "randomizer.h" + +#ifndef PWM_EMBEDDED +#include "selftest.h" +#endif + +#include "pwm.h" +#include "pwmexception.h" +#include "pwmtray.h" +#include "pwmdoc.h" + +#ifdef CONFIG_KWALLETIF +# include "kwalletemu.h" +#endif // CONFIG_KWALLETIF +#ifdef CONFIG_KEYCARD +# include "pwmkeycard.h" +#endif // CONFIG_KEYCARD + +#include + +#include +#ifndef PWM_EMBEDDED +#include +#include +#include +#endif + +#include +#include + +#include + +static PwMInit *sig_init_pointer; +static NOREGPARM void sig_handler(int signum) +{ + switch (signum) { + case SIGINT: + case SIGTERM: + sig_init_pointer->shutdownApp(20 + signum); + break; + default: + printDebug(string("unhandled signal ") + + tostr(signum)); + } +} + + + + +PwMInit::PwMInit(PwMApplication *_app) + : runStatus (unknown) + , _curWidget (0) + , _dcopClient (0) + , _kwalletEmu (0) + , _keycard (0) + , _tray (0) +{ + sig_init_pointer = this; + app = _app; +} + +PwMInit::~PwMInit() +{ +#ifndef PWM_EMBEDDED + SelfTest::cancel(); + // close all open mainwnds + QValueList::iterator i = _mainWndList.begin(), + end = _mainWndList.end(); + +#else + // close all open mainwnds + QValueList::Iterator i = _mainWndList.begin(), + end = _mainWndList.end(); +#endif + while (i != end) { + disconnect(*i, SIGNAL(closed(PwM *)), + this, SLOT(mainWndClosed(PwM *))); + delete *i; + ++i; + } + _mainWndList.clear(); + // close all remaining open documents + PwMDocList *_dl = PwMDoc::getOpenDocList(); + vector dl = *(_dl->getList()); + vector::iterator i2 = dl.begin(), + end2 = dl.end(); + while (i2 != end2) { + delete (*i2).doc; + ++i2; + } + +#ifdef CONFIG_KWALLETIF + delete_ifnot_null(_kwalletEmu); +#endif // CONFIG_KWALLETIF +#ifdef CONFIG_KEYCARD + delete_ifnot_null(_keycard); +#endif // CONFIG_KEYCARD + delete_ifnot_null(_tray); + + Randomizer::cleanup(); + Configuration::cleanup(); +} + +void PwMInit::initializeApp() +{ + PWM_ASSERT(runStatus == unknown); + runStatus = init; + initPosixSignalHandler(); + Randomizer::init(); + Configuration::init(); + initDCOP(); + initKWalletEmu(); + initKeycard(); + initTray(); + handleCmdLineArgs(); + + bool openDeeplocked = false; + if (conf()->confGlobAutostartDeepLocked() || + savedCmd.open_deeplocked) + openDeeplocked = true; + if (conf()->confWndAutoMinimizeOnStart() || + savedCmd.minToTray) { + PwMDoc *newDoc = createDoc(); + if (!newDoc->openDocUi(newDoc, + conf()->confGlobAutoStart(), + openDeeplocked)) { + delete newDoc; + } + } else { + createMainWnd(conf()->confGlobAutoStart(), + openDeeplocked, + true, + 0, + savedCmd.minimized); + } + + runStatus = running; +} + +void PwMInit::shutdownApp(int exitStatus) +{ + printDebug(string("PwMInit::shutdownApp(") + + tostr(exitStatus) + ") called."); + PWM_ASSERT((runStatus == running) || (runStatus == init)); + runStatus = shutdown; + QApplication::exit(exitStatus); + /* The destructor of PwMInit is called when control + * leaves main() + */ +} + +void PwMInit::initPosixSignalHandler() +{ + signal(SIGINT, sig_handler); + signal(SIGTERM, sig_handler); +} + +void PwMInit::initDCOP() +{ +#ifndef PWM_EMBEDDED + _dcopClient = app->dcopClient(); + _dcopClient->setNotifications(true); +#else + qDebug("PwMInit::initDCOP() has to be implemented"); +#endif + +} + +void PwMInit::initKWalletEmu(bool forceDisable, bool forceReload) +{ +#ifdef CONFIG_KWALLETIF + if (!conf()->confGlobKwalletEmu() || + forceDisable) { + delete_ifnot_null(_kwalletEmu); + return; + } + try { + if (_kwalletEmu && forceReload) + delete_and_null(_kwalletEmu); + if (!_kwalletEmu) + _kwalletEmu = new KWalletEmu(this); + } catch (PwMException e) { + string errMsg("initializing KWallet emulation failed. ID: "); + errMsg += tostr(static_cast(e.getId())); + errMsg += " err-message: "; + errMsg += e.getMessage(); + printWarn(errMsg); + return; + } +#else // CONFIG_KWALLETIF + PARAM_UNUSED(forceDisable); + PARAM_UNUSED(forceReload); +#endif // CONFIG_KWALLETIF +} + +void PwMInit::initKeycard() +{ +#ifdef CONFIG_KEYCARD + PWM_ASSERT(!_keycard); + _keycard = new PwMKeyCard(this); +#endif // CONFIG_KEYCARD +} + +void PwMInit::initTray() +{ +#ifdef PWM_EMBEDDED + //US ENH : embedded version does not support a tray + return; +#endif + + if (!conf()->confGlobTray()) { + if (!_tray) + return; + _tray->hide(); + delete_and_null(_tray); + return; + } + if (_tray) + return; + _tray = new PwMTray(this); + connect(_tray, SIGNAL(quitSelected()), + this, SLOT(removeTrayAndQuit())); + connect(_tray, SIGNAL(closed(PwMTray *)), + this, SLOT(trayIconClosed(PwMTray *))); + KIconLoader icons; +#ifndef PWM_EMBEDDED + _tray->setPixmap(icons.loadIcon(PACKAGE_NAME, KIcon::Small)); +#endif + _tray->show(); + // connect the signals of all open documents. + const vector *dl = PwMDoc::getOpenDocList()->getList(); + vector::const_iterator i = dl->begin(), + end = dl->end(); + while (i != end) { + _tray->connectDocToTray((*i).doc); + ++i; + } +} + +void PwMInit::removeTrayAndQuit() +{ + PWM_ASSERT(_tray); + // _tray is deleted in ~PwMInit + shutdownApp(0); +} + +PwM * PwMInit::createMainWnd(const QString &loadFile, + bool loadFileDeepLocked, + bool virginity, + PwMDoc *doc, + bool minimized) +{ + PwM *newWnd; + if (!doc) + doc = createDoc(); + newWnd = new PwM(this, doc, virginity); +#ifndef PWM_EMBEDDED + _mainWndList.push_back(newWnd); +#else + _mainWndList.append(newWnd); +#endif + connect(newWnd, SIGNAL(closed(PwM *)), + this, SLOT(mainWndClosed(PwM *))); + connect(newWnd, SIGNAL(gotFocus(PwM *)), + this, SLOT(setCurWidget(PwM *))); + connect(newWnd, SIGNAL(lostFocus(PwM *)), + this, SLOT(resetCurWidget())); + + //US ENH +#ifndef PWM_EMBEDDED + if (minimized) + newWnd->showMinimized(); + else + newWnd->show(); + +#else //PWM_EMBEDDED + +#ifndef DESKTOP_VERSION + app->showMainWidget( newWnd ); +#else //DESKTOP_VERSION + app->setMainWidget( newWnd ); + newWnd->resize (640, 480 ); + newWnd->show(); +#endif //DESKTOP_VERSION + +#endif //PWM_EMBEDDED + + if (loadFile != QString::null && + loadFile != "") { + newWnd->openDoc(loadFile, loadFileDeepLocked); + } + return newWnd; +} + +PwMDoc * PwMInit::createDoc() +{ + PwMDoc *doc = new PwMDoc(this); +#ifdef CONFIG_KEYCARD + doc->setPwMKeyCard(keycard()); +#endif +#ifdef CONFIG_KWALLETIF + if (kwalletEmu()) + kwalletEmu()->connectDocSignals(doc); +#endif + + if (_tray) + _tray->connectDocToTray(doc); + + return doc; + +} + +void PwMInit::mainWndClosed(PwM *wnd) +{ + bool doMinimizeToTray = false; + bool doDeleteDoc = false; +#ifndef PWM_EMBEDDED + dcopClient()->suspend(); + dcopClient()->setAcceptCalls(false); +#endif +again: + + if (wnd->isForceMinimizeToTray()) { + if (unlikely(!_tray)) { + /* This should not happen! If we set forceMinimizeToTray , + * we must be sure that _tray exists. + */ + BUG(); + wnd->setForceMinimizeToTray(false); + goto again; + } + doMinimizeToTray = true; + } else { + // Ask to minimize to tray. If not, delete doc. + if (_tray && + runStatus != shutdown && + !wnd->isForceQuit() && + !wnd->curDoc()->isDeleted()) { + if (conf()->confWndClose()) + doDeleteDoc = true; + else + doMinimizeToTray = true; + } else { + doDeleteDoc = true; + } + } + + if (doMinimizeToTray) { + + PWM_ASSERT(_tray); + int mmlock = conf()->confGlobMinimizeLock(); + switch (mmlock) { + case 0: // don't lock anything + break; + case 1: // normal lock + wnd->curDoc()->lockAll(true); + break; + case 2: // deep-lock + wnd->curDoc()->deepLock(); + break; + default: + WARN(); + } + } else if (doDeleteDoc) { + if (!wnd->curDoc()->tryDelete()) { + /* We failed deleting the doc, + * so open a new window with it, again. + */ + createMainWnd(QString::null, false, + false, wnd->curDoc()); + } + } +#ifndef PWM_EMBEDDED + // find the closed window in the "mainWndList" and delete it. + QValueList::iterator i = _mainWndList.begin(), + end = _mainWndList.end(); +#else + // find the closed window in the "mainWndList" and delete it. + QValueList::Iterator i = _mainWndList.begin(), + end = _mainWndList.end(); +#endif + while (i != end) { + if (*i == wnd) { +#ifndef PWM_EMBEDDED + _mainWndList.erase(i); +#else + _mainWndList.remove(i); +#endif + goto out_success; + } + ++i; + } + BUG(); +out_success: +#ifndef PWM_EMBEDDED + if (!_mainWndList.size()) +#else + if (!_mainWndList.count()) +#endif + + { + /* If there's no main window and no tray icon + * left, we have no user interface, so we can + * shut down the application. + */ + if (!_tray) { +#ifndef PWM_EMBEDDED + dcopClient()->setAcceptCalls(true); + dcopClient()->resume(); +#endif + shutdownApp(0); + return; + } + /* There is no widget left, so set + * _curWidget to 0 + */ + resetCurWidget(); + } +#ifndef PWM_EMBEDDED + dcopClient()->setAcceptCalls(true); + dcopClient()->resume(); +#endif +} + +void PwMInit::trayIconClosed(PwMTray *tray) +{ + if (runStatus != running) + return; + PARAM_UNUSED(tray); + PWM_ASSERT(tray == _tray); + /* If there's no main wnd left we have to + * shutdown the app (same as in mainWndClosed()) + */ +#ifndef PWM_EMBEDDED + if (!_mainWndList.size()) + shutdownApp(0); +#else + if (!_mainWndList.count()) + shutdownApp(0); +#endif +} + +void PwMInit::handleCmdLineArgs(bool initial) +{ +#ifndef PWM_EMBEDDED + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + PWM_ASSERT(args); + int i, numArgs = args->count(); + const char *curArg; + + // read all cmdline options + savedCmd.open_deeplocked = args->isSet("open-deeplocked"); + savedCmd.minimized = args->isSet("minimized"); + savedCmd.minToTray = args->isSet("mintray"); + savedCmd.skipSelfTest = args->isSet("skip-self-test"); + if (savedCmd.minimized && + savedCmd.minToTray) { + printInfo(i18n("Commandline option \"--minimized\" and " + "\"--mintray\" selected. These are incompatible. " + "\"--mintray\" will be selected.").latin1()); + } + /* Iterate through all non-option arguments. + * Every non-option arg is a filename to open. + */ + for (i = 0; i < numArgs; ++i) { + curArg = args->arg(i); + PWM_ASSERT(curArg); + if (savedCmd.minToTray) { + PwMDoc *newDoc = createDoc(); + if (!newDoc->openDocUi(newDoc, + curArg, + savedCmd.open_deeplocked)) { + delete newDoc; + } + } else { + PwM *newInstance = createMainWnd(QString::null, + false, + true, + 0, + savedCmd.minimized); + PwMDoc *newDoc = newInstance->openDoc(curArg, + savedCmd.open_deeplocked); + if (!newDoc) { + newInstance->setForceQuit(true); + delete_and_null(newInstance); + } + } + } + + if (savedCmd.minToTray) { + minimizeAllMainWnd(true); + } else if (savedCmd.minimized) { + minimizeAllMainWnd(false); + } + if (!savedCmd.skipSelfTest && initial) { + SelfTest::schedule(); + } + args->clear(); +#endif +} + +void PwMInit::minimizeAllMainWnd(bool toTray) +{ +#ifndef PWM_EMBEDDED + if (!_mainWndList.size()) + return; +#else + if (!_mainWndList.count()) + return; +#endif + const QValueList *ml = mainWndList(); +#ifndef PWM_EMBEDDED + QValueList::const_iterator it = ml->begin(), + end = ml->end(); +#else + QValueList::ConstIterator it = ml->begin(), + end = ml->end(); +#endif + PwM *wnd; + if (toTray && _tray) { + /* minimize to tray. + * close all mainWnd. + */ + while (it != end) { + wnd = *it; + wnd->setForceMinimizeToTray(true); + wnd->close_slot(); + ++it; + } + } else { + // normal minimize + while (it != end) { + wnd = *it; + wnd->hide(); + wnd->showMinimized(); + ++it; + } + } +} + +#ifdef PWM_EMBEDDED + +#ifndef DESKTOP_VERSION + +PwMApplication::PwMApplication(int & argc, char ** argv) + : QPEApplication( argc, argv ) + , init (0) +{ + this->setKeepRunning (); +} + +PwMApplication::~PwMApplication() +{ + delete_ifnot_null(init); +} +#else //DESKTOP_VERSION + +PwMApplication::PwMApplication(int & argc, char ** argv) + : QApplication( argc, argv ) + , init (0) +{ + setStyle( new QPlatinumStyle ()); + QString hdir = QDir::homeDirPath(); + // there is a bug when creating dirs for WIN 98 + // it is difficult to fix, because we have no WIN 98 runnung + // such that we try it to create the dirs at startup here + if ( hdir == "C:\\" ) + { + // win 98 or ME + QDir app_dir; + if ( !app_dir.exists("C:\\kdepim") ) + app_dir.mkdir ("C:\\kdepim"); + if ( !app_dir.exists("C:\\kdepim\\apps") ) + app_dir.mkdir ("C:\\kdepim\\apps"); + if ( !app_dir.exists("C:\\kdepim\\config") ) + app_dir.mkdir ("C:\\kdepim\\config"); + if ( !app_dir.exists("C:\\kdepim\\apps\\pwmanager") ) + app_dir.mkdir ("C:\\kdepim\\apps\\pwmanager"); + } +} + +PwMApplication::~PwMApplication() +{ + delete_ifnot_null(init); +} + +#endif //DESKTOP_VERSION + +#endif //PWM_EMBEDDED + + + + +#ifndef PWM_EMBEDDED +#include "pwminit.moc" +#endif diff --git a/pwmanager/pwmanager/pwminit.h b/pwmanager/pwmanager/pwminit.h new file mode 100644 index 0000000..bf72093 --- a/dev/null +++ b/pwmanager/pwmanager/pwminit.h @@ -0,0 +1,222 @@ +/*************************************************************************** + * * + * 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 __PWMINIT_H +#define __PWMINIT_H + +#include +#include +#ifndef PWM_EMBEDDED +#include +#else //PWM_EMBEDDED + +#ifndef DESKTOP_VERSION +#include +#else //DESKTOP_VERSION +#include +#include +#endif //DESKTOP_VERSION + +#include +#endif //PWM_EMBEDDED + +#include "globalstuff.h" + +class DCOPClient; +class KWalletEmu; +class PwMKeyCard; +class KApplication; +class QWidget; +class PwM; +class PwMTray; +class PwMDoc; +class PwMInit; + +/** main application class */ +#ifndef PWM_EMBEDDED +//MOC_SKIP_BEGIN +class PwMApplication : public KUniqueApplication +{ +public: + PwMApplication(bool allowStyles=true, + bool GUIenabled=true, + bool configUnique=false) + : KUniqueApplication(allowStyles, GUIenabled, configUnique) + , init (0) + { } + ~PwMApplication() + { delete_ifnot_null(init); } + + int newInstance(); + +protected: + PwMInit *init; +}; +//MOC_SKIP_END +#else //PWM_EMBEDDED + +#ifndef DESKTOP_VERSION +class PwMApplication : public QPEApplication +{ +public: + PwMApplication(int & argc, char ** argv); + ~PwMApplication(); + + int newInstance(); + +protected: + PwMInit *init; +}; +#else //DESKTOP_VERSION + +class PwMApplication : public QApplication +{ +public: + PwMApplication(int & argc, char ** argv); + ~PwMApplication(); + + int newInstance(); + +protected: + PwMInit *init; +}; + +#endif +#endif + +/** PwManager initialisation class. + * This class sets up a new instance of PwManager and finally + * starts the user interface. + */ +class PwMInit : public QObject +{ + Q_OBJECT + friend class PwMApplication; + +protected: + enum RunStatus + { + unknown, + init, + running, + shutdown, + }; + + /* saved command line options. */ + class savedCmd_t + { + public: + bool open_deeplocked; + bool minimized; + bool minToTray; + bool skipSelfTest; + // initial open paths are not saved here. + }; + +public: + PwMInit(PwMApplication *_app); + ~PwMInit(); + + /** Initialize the application. */ + void initializeApp(); + /** shutdown PwManager */ + void shutdownApp(int exitStatus); + + /** returns a pointer to the current widget */ + QWidget * curWidget() + { return _curWidget; } + /** returns a pointer to the dcop client */ + DCOPClient * dcopClient() + { return _dcopClient; } + /** returns a pointer to the KWallet emulation */ + KWalletEmu * kwalletEmu() + { return _kwalletEmu; } + /** returns a pointer to the keycard interface */ + PwMKeyCard * keycard() + { return _keycard; } + /** returns a pointer to the tray icon */ + PwMTray * tray() + { return _tray; } + /** returns a list of all open main windows */ + const QValueList * mainWndList() + { return &_mainWndList; } + /** create a new document */ + PwMDoc * createDoc(); + /** create a new PwM main window */ + PwM * createMainWnd(const QString &loadFile = QString::null, + bool loadFileDeepLocked = false, + bool virginity = true, + PwMDoc *doc = 0, + bool minimized = false); + + /** (re)initialize the KWallet emulation */ + void initKWalletEmu(bool forceDisable = false, bool forceReload = false); + /** (re)initialize the tray icon */ + void initTray(); + +protected: + /** initialize the DCOP connection */ + void initDCOP(); + /** initialize the keycard interface */ + void initKeycard(); + /** initialize posix signal handling */ + void initPosixSignalHandler(); + /** handle the commandline args */ + void handleCmdLineArgs(bool initial = true); + /** minimize all open mainWnds to tray (or if + * no tray is present, minimize them the normal way) + */ + void minimizeAllMainWnd(bool toTray); + +protected slots: + /** a main window got closed */ + void mainWndClosed(PwM *wnd); + /** the tray icon got closed */ + void trayIconClosed(PwMTray *tray); + /** sets _curWidget on behalf of a PwM signal */ + void setCurWidget(PwM *w) + { _curWidget = reinterpret_cast(w); } + /** resets _curWidget to nothing */ + void resetCurWidget() + { _curWidget = 0; } + /** remove the tray and quit the app */ + void removeTrayAndQuit(); + +protected: + /** run-status of the app */ + RunStatus runStatus; + /** PwMApplication pointer */ + PwMApplication *app; + /** pointer to the current widget the user is dealing with */ + QWidget *_curWidget; + /** pointer to the dcop client */ + DCOPClient *_dcopClient; + /** pointer to the KWallet emulation */ + KWalletEmu *_kwalletEmu; + /** pointer to the keycard interface */ + PwMKeyCard *_keycard; + /** pointer to the tray icon */ + PwMTray *_tray; + /** list of all open main windows */ + QValueList _mainWndList; + /** saved command line options. */ + savedCmd_t savedCmd; +}; + +#endif // __PWMINIT_H diff --git a/pwmanager/pwmanager/pwmprint.cpp b/pwmanager/pwmanager/pwmprint.cpp new file mode 100644 index 0000000..1d26b10 --- a/dev/null +++ b/pwmanager/pwmanager/pwmprint.cpp @@ -0,0 +1,188 @@ +/*************************************************************************** + * * + * 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$ + **************************************************************************/ + +#include "pwmprint.h" +#include "pwmexception.h" +#include "pwm.h" +#include "pwmdoc.h" +#include "configuration.h" +#include "printtext.h" +#include "globalstuff.h" +#include "listobjselectwnd.h" + +#include +#include +#include +#include + + +PwMPrint::PwMPrint(PwMDoc *_doc, QWidget *_parent) +{ + PWM_ASSERT(_doc); + PWM_ASSERT(_parent); + doc = _doc; + parent = _parent; +} + +PwMPrint::~PwMPrint() +{ +} + +void PwMPrint::printNow() +{ + QString docTitle(doc->getTitle()); + if (!doc->unlockAll_tempoary()) + return; + if (doc->isDocEmpty()) { + KMessageBox::information(parent, + i18n("Sorry, there are no entries to print " + "in the document \"") + + docTitle + "\".", + i18n("nothing to do")); + doc->unlockAll_tempoary(true); + return; + } + QStringList printCategories(selCategories()); + if (printCategories.isEmpty()) { + doc->unlockAll_tempoary(true); + return; + } + doc->ensureLvp(); + + PrintText prn; + if (!prn.setup(parent)) { + doc->unlockAll_tempoary(true); + return; + } + prn.setFullPage(false); + prn.setCreator(PROG_NAME); + prn.setDocName(docTitle); + + prn.setHeader(genDateString(), docTitle); + prn.beginPrint(); + + prn.printLine(""); + prn.printLine(QString(PROG_NAME " v" PACKAGE_VER " ") + i18n("password table:")); + prn.printLine(""); + + vector tmp; + PwMCategoryItem catItem; + catItem.clear(); + PwMDataItem item; + item.clear(); + unsigned int numEntr, j, i = 0; + QStringList::iterator catI = printCategories.begin(), + catEnd = printCategories.end(); + // Sort items on lvp and store them in tempoary "tmp". + while (catI != catEnd) { + catItem.clear(); + catItem.name = (*catI).latin1(); + tmp.push_back(catItem); + item.clear(); + numEntr = doc->numEntries(*catI); + tmp[i].d.insert(tmp[i].d.begin(), numEntr, item); + for (j = 0; j < numEntr; ++j) { + doc->getEntry(*catI, j, &item); + tmp[i].d[numEntr - item.listViewPos - 1] = item; + } + ++catI; + ++i; + } + doc->unlockAll_tempoary(true); + + QString currLine; + vector::iterator cat_it = tmp.begin(), + cat_end = tmp.end(); + unsigned int size; + while (cat_it != cat_end) { + i = 0; + size = cat_it->d.size(); + prn.printLine(""); + currLine = "== "; + currLine += i18n("Category: "); + currLine += cat_it->name.c_str(); + currLine += " =="; + prn.printLine(currLine); + prn.printLine(""); + while (true) { + item = cat_it->d[i]; + currLine = "-- "; + currLine += item.desc.c_str(); + currLine += " --"; + prn.printLine(currLine); + if (item.name.size()) { + currLine = i18n("Username"); + currLine += ": "; + currLine += item.name.c_str(); + prn.printLine(currLine); + } + if (item.pw.size()) { + currLine = i18n("Password"); + currLine += ": "; + currLine += item.pw.c_str(); + prn.printLine(currLine); + } + if (item.comment.size()) { + currLine = i18n("Comment"); + currLine += ": "; + currLine += item.comment.c_str(); + prn.printLine(currLine); + } + if (item.url.size()) { + currLine = i18n("URL"); + currLine += ": "; + currLine += item.url.c_str(); + prn.printLine(currLine); + } + if (item.launcher.size()) { + currLine = i18n("Launcher"); + currLine += ": "; + currLine += item.launcher.c_str(); + prn.printLine(currLine); + } + + ++i; + if (i >= size) + break; + prn.printLine(""); + } + ++cat_it; + } +} + +QString PwMPrint::genDateString() +{ + QDateTime dt = QDateTime::currentDateTime(); + QString ret(dt.toString(Qt::LocalDate)); + return ret; +} + +QStringList PwMPrint::selCategories() +{ + ListObjSelectWnd selWnd(i18n("Print categories"), + i18n("Please select the categories " + "you want to print."), + parent, true); + QStringList catList; + doc->getCategoryList(&catList); + selWnd.setList(catList); + if (selWnd.exec() != 1) + return QStringList(); + return selWnd.getSelectedList(); +} diff --git a/pwmanager/pwmanager/pwmprint.h b/pwmanager/pwmanager/pwmprint.h new file mode 100644 index 0000000..4b7c4d2 --- a/dev/null +++ b/pwmanager/pwmanager/pwmprint.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * * + * 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 PWMPRINT_H +#define PWMPRINT_H + +#include + +#include +#include + +class PwMDoc; + +class PwMPrint +{ +public: + PwMPrint(PwMDoc *_doc, QWidget *_parent); + ~PwMPrint(); + + /** start printing now */ + void printNow(); + /** set document */ + void setDoc(PwMDoc *_doc) + { doc = _doc; } + +protected: + /** generate a date-string */ + QString genDateString(); + /** request the user to select all categories to print */ + QStringList selCategories(); + +protected: + /** document */ + PwMDoc *doc; + /** parent widget */ + QWidget *parent; +}; + +#endif diff --git a/pwmanager/pwmanager/pwmtray.cpp b/pwmanager/pwmanager/pwmtray.cpp new file mode 100644 index 0000000..0f286c1 --- a/dev/null +++ b/pwmanager/pwmanager/pwmtray.cpp @@ -0,0 +1,482 @@ +/*************************************************************************** + * * + * copyright (C) 2003, 2004 by Michael Buesch * + * email: mbuesch@freenet.de * + * * + * Original implementation of the tray-tree * + * (c) by Matt Scifo * + * * + * 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 "pwmtray.h" +#include "pwmexception.h" +#include "pwm.h" +#include "pwmdoc.h" +#include "pwminit.h" +#include "configuration.h" + +#include + + +void ActiveTreeItem::execIt() +{ +#ifndef PWM_EMBEDDED + unsigned int entr = static_cast(entry); + unsigned int cat = static_cast(category); +#else + unsigned int entr = (unsigned int)(entry); + unsigned int cat = (unsigned int)(category); +#endif + switch (task) { + case pwToClipboard: { + PwMDataItem d; + doc->getDataChangedLock(); + bool wasLocked = doc->isLocked(cat, entr); + doc->getEntry(cat, entr, &d, true); + if (wasLocked) + doc->lockAt(cat, entr, true); + doc->putDataChangedLock(); + PwM::copyToClipboard(d.pw.c_str()); + break; + } case nameToClipboard: { + PwMDataItem d; + doc->getEntry(cat, entr, &d); + PwM::copyToClipboard(d.name.c_str()); + break; + } case descToClipboard: { + PwMDataItem d; + doc->getEntry(cat, entr, &d); + PwM::copyToClipboard(d.desc.c_str()); + break; + } case urlToClipboard: { + PwMDataItem d; + doc->getEntry(cat, entr, &d); + PwM::copyToClipboard(d.url.c_str()); + break; + } case launcherToClipboard: { + PwMDataItem d; + doc->getEntry(cat, entr, &d); + PwM::copyToClipboard(d.launcher.c_str()); + break; + } case commentToClipboard: { + PwMDataItem d; + doc->getEntry(cat, entr, &d); + PwM::copyToClipboard(d.comment.c_str()); + break; + } case execLauncher: { + doc->execLauncher(cat, entr); + break; + } case goToURL: { + doc->goToURL(cat, entr); + break; + } case openMainWnd: { + // search if there is already an open window. + const QValueList *wl = tray->init->mainWndList(); +#ifndef PWM_EMBEDDED + QValueList::const_iterator i = wl->begin(), + end = wl->end(); +#else + QValueList::ConstIterator i = wl->begin(), + end = wl->end(); +#endif + PwM *wnd; + while (i != end) { + wnd = *i; + if (wnd->curDoc() == doc) { + // now bring this window to the foreground. + if (!wnd->hasFocus()) { + wnd->hide(); + wnd->showNormal(); + wnd->setFocus(); + } + return; + } + ++i; + } + // there is no open window, so open a new one. + tray->init->createMainWnd(QString::null, false, false, doc); + break; + } case closeDoc: { + doc->tryDelete(); + break; + } case lock: { + doc->lockAll(true); + break; + } case deepLock: { + doc->deepLock(); + break; + } case unlock: { + doc->lockAll(false); + break; + } default: { + BUG(); + } + } +} + + + +#ifndef PWM_EMBEDDED +PwMTray::PwMTray(PwMInit *_init, QWidget * parent, const char *name) + : KSystemTray(parent, name) +#else +PwMTray::PwMTray(PwMInit *_init, QWidget * parent, const char *name) + : QWidget(parent, name) +#endif +{ + init = _init; + buildMain(); +} + +PwMTray::~PwMTray() +{ + emit closed(this); +} + +//US ENH for embedded tray class +KPopupMenu* PwMTray::contextMenu() +{ + if (m_ctxMenu == 0) + { + m_ctxMenu = new KPopupMenu(); + } + + return m_ctxMenu; +} + + +void PwMTray::buildMain() +{ + KPopupMenu *ctxMenu = contextMenu(); + + ctxMenu->insertSeparator(); + ctxMenu->insertItem(i18n("&New main window..."), this, + SLOT(newMainWnd())); + ctxMenu->insertItem(i18n("&Open file..."), this, + SLOT(openDoc())); + ctxMenu->insertSeparator(); + ctxMenu->insertItem(i18n("&Remove from tray"), this, + SLOT(undock())); +} + +void PwMTray::insertActiveTreeItem(KPopupMenu *insertIn, const QString &text, + ActiveTreeItem::Task task, PwMDoc *doc, + int docCategory, int docEntry, + QValueList *activeItemsList) +{ + ActiveTreeItem *activeItem; + int id; + + activeItem = new ActiveTreeItem(text, insertIn->font(), task, + doc, docCategory, docEntry, + this); + id = insertIn->insertItem(activeItem); + insertIn->connectItem(id, activeItem, SLOT(execIt())); +#ifndef PWM_EMBEDDED + activeItemsList->push_back(id); +#else + activeItemsList->append(id); +#endif +} + +void PwMTray::rebuildTree(KPopupMenu *popup, PwMDoc *doc, + QValueList *activeItems) +{ + PWM_ASSERT(doc); + PWM_ASSERT(popup); + activeItems->clear(); + popup->clear(); +#ifndef PWM_EMBEDDED + popup->insertTitle(i18n("Categories:")); +#endif + vector catList; + vector entrList; + doc->getCategoryList(&catList); + KPopupMenu *newCatMenu; + KPopupMenu *newEntrMenu; + int i, size = catList.size(); + int j, entries; + for (i = 0; i < size; ++i) { + newCatMenu = new KPopupMenu(popup); + popup->insertItem(catList[i].c_str(), newCatMenu); + doc->getEntryList(i, &entrList); + + entries = entrList.size(); + for (j = 0; j < entries; ++j) { + newEntrMenu = new KPopupMenu(newCatMenu); + newCatMenu->insertItem(entrList[j].c_str(), newEntrMenu); + + if (doc->isBinEntry(i, j)) { + /* This is a binary entry. Don't insert the usual + * menu items. + */ +#ifndef PWM_EMBEDDED + newEntrMenu->insertTitle(i18n("This is a binary entry.\n" + "It is not a normal password-entry, as it contains " + "binary data, which PwManager can't display here.")); +#endif + continue; + } + + insertActiveTreeItem(newEntrMenu, + i18n("copy password to clipboard"), + ActiveTreeItem::pwToClipboard, doc, i, j, + activeItems); + + insertActiveTreeItem(newEntrMenu, + i18n("copy username to clipboard"), + ActiveTreeItem::nameToClipboard, doc, i, j, + activeItems); + + insertActiveTreeItem(newEntrMenu, + i18n("copy description to clipboard"), + ActiveTreeItem::descToClipboard, doc, i, j, + activeItems); + + insertActiveTreeItem(newEntrMenu, + i18n("copy url to clipboard"), + ActiveTreeItem::urlToClipboard, doc, i, j, + activeItems); + + insertActiveTreeItem(newEntrMenu, + i18n("copy launcher to clipboard"), + ActiveTreeItem::launcherToClipboard, doc, i, j, + activeItems); + + insertActiveTreeItem(newEntrMenu, + i18n("copy comment to clipboard"), + ActiveTreeItem::commentToClipboard, doc, i, j, + activeItems); + + newEntrMenu->insertSeparator(); + + insertActiveTreeItem(newEntrMenu, + i18n("Execute \"Launcher\""), + ActiveTreeItem::execLauncher, doc, i, j, + activeItems); + + insertActiveTreeItem(newEntrMenu, + i18n("Go to \"URL\""), + ActiveTreeItem::goToURL, doc, i, j, + activeItems); + } + } + insertMainWndCtrl(popup, doc); +} + +void PwMTray::insertMainWndCtrl(KPopupMenu *menu, PwMDoc *doc) +{ + ActiveTreeItem *activeItem; + int id; + +#ifndef PWM_EMBEDDED + menu->insertTitle(i18n("Manager:")); +#endif + activeItem = new ActiveTreeItem(i18n("&Open main manager window ..."), + menu->font(), ActiveTreeItem::openMainWnd, + doc, 0, 0, this); + id = menu->insertItem(activeItem); + menu->connectItem(id, activeItem, SLOT(execIt())); + + activeItem = new ActiveTreeItem(i18n("&Close this document ..."), + menu->font(), ActiveTreeItem::closeDoc, + doc, 0, 0, this); + id = menu->insertItem(activeItem); + menu->connectItem(id, activeItem, SLOT(execIt())); + + menu->insertSeparator(); + + activeItem = new ActiveTreeItem(i18n("&Lock all entries"), + menu->font(), ActiveTreeItem::lock, + doc, 0, 0, this); + id = menu->insertItem(activeItem); + menu->connectItem(id, activeItem, SLOT(execIt())); + + activeItem = new ActiveTreeItem(i18n("&Deep-lock all entries"), + menu->font(), ActiveTreeItem::deepLock, + doc, 0, 0, this); + id = menu->insertItem(activeItem); + menu->connectItem(id, activeItem, SLOT(execIt())); + + activeItem = new ActiveTreeItem(i18n("&Unlock all entries"), + menu->font(), ActiveTreeItem::unlock, + doc, 0, 0, this); + id = menu->insertItem(activeItem); + menu->connectItem(id, activeItem, SLOT(execIt())); +} + +void PwMTray::updateTree(PwMDoc *document) +{ + PWM_ASSERT(document); + KPopupMenu *treeEntry; + int treeItemNum = -1; + int id = findTreeEntry(document, &treeEntry, &treeItemNum); + if (id == -1) { + // tree-entry doesn't exist, yet. + id = insertTreeEntry(document, &treeEntry); + } + if (treeItemNum != -1) { + // delete all *old* active items + KPopupMenu *ctxMenu = contextMenu(); + QValueList *oldItems = &tree[treeItemNum].activeItems; +#ifndef PWM_EMBEDDED + QValueList::iterator i = oldItems->begin(); +#else + QValueList::Iterator i = oldItems->begin(); +#endif + while (i != oldItems->end()) { + ctxMenu->removeItem(*i); + ++i; + } + oldItems->clear(); + ctxMenu->changeItem(id, document->getTitle()); + } + + treeItem newTreeItem; + if (document->isDeepLocked()) { + treeEntry->clear(); +#ifndef PWM_EMBEDDED + treeEntry->insertTitle(i18n("Categories:")); +#endif + QString msg(IS_DEEPLOCKED_SHORTMSG); + msg += " "; + msg += i18n("(Click here to unlock)"); + treeEntry->insertItem(msg, document, + SLOT(_deepUnlock())); + insertMainWndCtrl(treeEntry, document); + } else { + rebuildTree(treeEntry, document, &newTreeItem.activeItems); + } + newTreeItem.menuId = id; + newTreeItem.doc = document; + newTreeItem.menu = treeEntry; + if (treeItemNum == -1) { +#ifndef PWM_EMBEDDED + tree.push_back(newTreeItem); +#else + tree.append(newTreeItem); +#endif + } else { + tree[treeItemNum] = newTreeItem; + } +} + +void PwMTray::closeTreeEntry(PwMDoc *document) +{ + KPopupMenu *menu; + int treeItem; + int id = findTreeEntry(document, &menu, &treeItem); + if (id != -1) { + removeTreeEntry(id, treeItem, &menu); + } +} + +int PwMTray::findTreeEntry(PwMDoc *doc, KPopupMenu **menu, int *treeItem) +{ + PWM_ASSERT(doc); +#ifndef PWM_EMBEDDED + int i, count = tree.size(); +#else + int i, count = tree.count(); +#endif + for (i = 0; i < count; ++i) { + if (tree[i].doc == doc) { + if (menu) + *menu = tree[i].menu; + if (treeItem) + *treeItem = i; + return tree[i].menuId; + } + } + if (menu) + *menu = 0; + if (treeItem) + *treeItem = -1; + return -1; +} + +int PwMTray::insertTreeEntry(PwMDoc *doc, KPopupMenu **popup) +{ + PWM_ASSERT(doc); + PWM_ASSERT(popup); + KPopupMenu *ctxMenu = contextMenu(); + *popup = new KPopupMenu(ctxMenu); + return ctxMenu->insertItem(doc->getTitle(), *popup, -1, 1); +} + +void PwMTray::removeTreeEntry(int menuId, int treeItem, KPopupMenu **menu) +{ + PWM_ASSERT(menu); + KPopupMenu *ctxMenu = contextMenu(); + ctxMenu->removeItem(menuId); + delete_and_null(*menu); +#ifndef PWM_EMBEDDED + tree.erase(tree.at(treeItem)); +#else + tree.remove(tree.at(treeItem)); +#endif +} + +void PwMTray::mouseReleaseEvent(QMouseEvent *e) +{ + QWidget *curWnd = init->curWidget(); + KPopupMenu *ctxMenu = contextMenu(); + // give focus to init->curWidget() + if (curWnd && !curWnd->hasFocus()) { + curWnd->hide(); + curWnd->showNormal(); + curWnd->setFocus(); + } + // popup the context menu + ctxMenu->popup(e->globalPos()); + emit clickedIcon(this); +} + +void PwMTray::connectDocToTray(PwMDoc *doc) +{ + connect(doc, SIGNAL(dataChanged(PwMDoc *)), + this, SLOT(updateTree(PwMDoc *))); + connect(doc, SIGNAL(docClosed(PwMDoc *)), + this, SLOT(closeTreeEntry(PwMDoc *))); + // fake a dataChanged signal for this doc to update the tray tree. + updateTree(doc); +} + +void PwMTray::openDoc() +{ + // open the document in a new window. + PwM *newInstance = init->createMainWnd(); + PwMDoc *newDoc = newInstance->openDoc(""); + if (!newDoc) { + newInstance->setForceQuit(true); + delete_and_null(newInstance); + } +} + +void PwMTray::newMainWnd() +{ + init->createMainWnd(); +} + +void PwMTray::undock() +{ + conf()->confGlobTray(false); + init->initTray(); + // Attention! "this" is already deleted here! +} + +#ifndef PWM_EMBEDDED +#include "pwmtray.moc" +#endif diff --git a/pwmanager/pwmanager/pwmtray.h b/pwmanager/pwmanager/pwmtray.h new file mode 100644 index 0000000..ffb625e --- a/dev/null +++ b/pwmanager/pwmanager/pwmtray.h @@ -0,0 +1,292 @@ +/*************************************************************************** + * * + * 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 __PWMTRAY_H +#define __PWMTRAY_H + +#ifndef PWM_EMBEDDED +#include +#endif + +#include + +#include +#include + +//#include "pwmexception.h" + +class PwMInit; +class PwMDoc; +class PwMTray; + +/* wrapper to workaround MOC problems */ +class __ActiveTreeItem : public QCustomMenuItem + , public QObject +{ +public: + __ActiveTreeItem() {} +}; + +/** implements the "active" part of the tree */ +class ActiveTreeItem : public __ActiveTreeItem +{ + Q_OBJECT + +public: + enum Task + { + pwToClipboard, + nameToClipboard, + descToClipboard, + urlToClipboard, + launcherToClipboard, + commentToClipboard, + execLauncher, + goToURL, + openMainWnd, + closeDoc, + lock, + deepLock, + unlock + }; + +public: + ActiveTreeItem(const QString &_text, const QFont &_font, + Task _task, PwMDoc * _doc, + int _category, int _entry, + PwMTray *_tray) + : text (_text) + , font (_font) + , task (_task) + , doc (_doc) + , category (_category) + , entry (_entry) + , tray (_tray) + { } + +/* ~ActiveTreeItem() + { cout << "deleted \"" << text << "\"" << endl; } */ + + void paint(QPainter *p, const QColorGroup & /*cg*/, bool /*act*/, + bool /*enabled*/, int x, int y, int w, int h) + { + p->setFont(font); + p->drawText(x, y, w, h, AlignLeft | AlignVCenter | + DontClip | ShowPrefix, text); + } + + QSize sizeHint() + { + return QFontMetrics(font).size(AlignLeft | AlignVCenter | + ShowPrefix | DontClip, text); + } + + bool fullSpan() const + { return false; } + + bool isSeparator() const + { return false; } + + void setFont(const QFont &f) + { font = f; } + +public slots: + /** this is the executive part, that is triggered, when the user clicks it */ + void execIt(); + +protected: + QString text; + QFont font; + Task task; + PwMDoc *doc; + int category; + int entry; + PwMTray *tray; +}; + +/** tray icon implementation */ +#ifndef PWM_EMBEDDED +//MOC_SKIP_BEGIN +class PwMTray : public KSystemTray +{ + Q_OBJECT + + friend class ActiveTreeItem; + + struct treeItem + { + int menuId; + PwMDoc *doc; + KPopupMenu *menu; + QValueList activeItems; // ids of all active items + }; + +public: + PwMTray(PwMInit *_init, QWidget* parent = 0, const char* name = 0); + ~PwMTray(); + + /** connect all signals for this document to the tray */ + void connectDocToTray(PwMDoc *doc); + +public slots: + /** for update-notification from all open documents */ + void updateTree(PwMDoc *document); + /** when a document has been closed, call this func + * to delete its tray-entry + */ + void closeTreeEntry(PwMDoc *document); + +protected slots: + /** open a new document */ + void openDoc(); + /** open a new mainwnd */ + void newMainWnd(); + /** undock this tray icon */ + void undock(); + +signals: + /** this icon got deleted */ + void closed(PwMTray *); + /** the user clicked on the tray icon */ + void clickedIcon(PwMTray *); + +protected: + /** holds a list of all open files, its documents and + * its menuIDs + */ + QValueList tree; + /** pointer to init */ + PwMInit *init; + +protected: + /** search if an entry with for the given document + * exists and resturn its ID and a pointer to the main + * KPopupMenu. If no item is found, + * it returns -1 as ID and a NULL-pointer. + */ + int findTreeEntry(PwMDoc *doc, KPopupMenu **menu, int *treeItem); + /** build the main menu-items */ + void buildMain(); + /** rebuilds the tree for the given KPopupMenu entry */ + void rebuildTree(KPopupMenu *popup, PwMDoc *doc, + QValueList *activeItems); + /** insert a new tree-entry for the given doc and returns the ID.*/ + int insertTreeEntry(PwMDoc *doc, KPopupMenu **popup); + /** removes a tree entry */ + void removeTreeEntry(int menuId, int treeItem, KPopupMenu **menu); + /** inserts a new active-tree-item into the given tree entry */ + void insertActiveTreeItem(KPopupMenu *insertIn, const QString &text, + ActiveTreeItem::Task task, PwMDoc *doc, + int docCategory, int docEntry, + QValueList *activeItemsList); + /** mouse event on icon */ + void mouseReleaseEvent(QMouseEvent *e); + /** inserts the items for the main window control + * into the popup menu. + */ + void insertMainWndCtrl(KPopupMenu *menu, PwMDoc *doc); +}; +//MOC_SKIP_END +#else +class PwMTray : public QWidget +{ + Q_OBJECT + + friend class ActiveTreeItem; + + struct treeItem + { + int menuId; + PwMDoc *doc; + KPopupMenu *menu; + QValueList activeItems; // ids of all active items + }; + +public: + PwMTray(PwMInit *_init, QWidget* parent = 0, const char* name = 0); + ~PwMTray(); + + //US ENH needed for embedde version. + KPopupMenu* contextMenu(); + KPopupMenu* m_ctxMenu; + + /** connect all signals for this document to the tray */ + void connectDocToTray(PwMDoc *doc); + +public slots: + /** for update-notification from all open documents */ + void updateTree(PwMDoc *document); + /** when a document has been closed, call this func + * to delete its tray-entry + */ + void closeTreeEntry(PwMDoc *document); + +protected slots: + /** open a new document */ + void openDoc(); + /** open a new mainwnd */ + void newMainWnd(); + /** undock this tray icon */ + void undock(); + +signals: + /** this icon got deleted */ + void closed(PwMTray *); + /** the user clicked on the tray icon */ + void clickedIcon(PwMTray *); + +protected: + /** holds a list of all open files, its documents and + * its menuIDs + */ + QValueList tree; + /** pointer to init */ + PwMInit *init; + +protected: + /** search if an entry with for the given document + * exists and resturn its ID and a pointer to the main + * KPopupMenu. If no item is found, + * it returns -1 as ID and a NULL-pointer. + */ + int findTreeEntry(PwMDoc *doc, KPopupMenu **menu, int *treeItem); + /** build the main menu-items */ + void buildMain(); + /** rebuilds the tree for the given KPopupMenu entry */ + void rebuildTree(KPopupMenu *popup, PwMDoc *doc, + QValueList *activeItems); + /** insert a new tree-entry for the given doc and returns the ID.*/ + int insertTreeEntry(PwMDoc *doc, KPopupMenu **popup); + /** removes a tree entry */ + void removeTreeEntry(int menuId, int treeItem, KPopupMenu **menu); + /** inserts a new active-tree-item into the given tree entry */ + void insertActiveTreeItem(KPopupMenu *insertIn, const QString &text, + ActiveTreeItem::Task task, PwMDoc *doc, + int docCategory, int docEntry, + QValueList *activeItemsList); + /** mouse event on icon */ + void mouseReleaseEvent(QMouseEvent *e); + /** inserts the items for the main window control + * into the popup menu. + */ + void insertMainWndCtrl(KPopupMenu *menu, PwMDoc *doc); +}; +#endif + +#endif diff --git a/pwmanager/pwmanager/pwmview.cpp b/pwmanager/pwmanager/pwmview.cpp new file mode 100644 index 0000000..c09fbf5 --- a/dev/null +++ b/pwmanager/pwmanager/pwmview.cpp @@ -0,0 +1,452 @@ +/*************************************************************************** + * * + * 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$ + **************************************************************************/ + +#include "pwmview.h" +#include "pwmexception.h" +#include "globalstuff.h" +#include "pwm.h" +#include "rencatwnd.h" +#include "configuration.h" +#include "commentbox.h" + +#include +#include + +#include +#include +#include + +#define COLUMN_DESC 0 +#define COLUMN_NAME 1 +#define COLUMN_PW 2 +#define COLUMN_URL 3 +#define COLUMN_LAUNCHER 4 + + +PwMView::PwMView(PwM *_mainClass, + QWidget *parent, PwMDoc *_doc, + const char *name) + : PwMViewStyle(parent, name) +{ + PWM_ASSERT(_mainClass); + PWM_ASSERT(parent); + PWM_ASSERT(_doc); + setView(this); + doc = _doc; + doc->setListViewPointer(this); + mainClass = _mainClass; + resize(_mainClass->size()); + initStyle(conf()->confWndMainViewStyle()); + initCtxMenu(); + doc->setCurrentView(this); + connect(doc, SIGNAL(dataChanged(PwMDoc *)), this, SLOT(updateView())); +} + +PwMView::~PwMView() +{ +} + +void PwMView::initCtxMenu() +{ + ctxMenu = new QPopupMenu(this); + ctxMenu->insertItem(i18n("&Add password"), mainClass, SLOT(addPwd_slot())); + ctxMenu->insertSeparator(); + ctxMenu->insertItem(i18n("&Edit"), mainClass, SLOT(editPwd_slot())); + ctxMenu->insertItem(i18n("&Delete"), mainClass, SLOT(deletePwd_slot())); + ctxMenu->insertSeparator(); + ctxMenu->insertItem(i18n("copy password to clipboard"), + this, SLOT(copyPwToClip())); + ctxMenu->insertItem(i18n("copy username to clipboard"), + this, SLOT(copyNameToClip())); + ctxMenu->insertItem(i18n("copy description to clipboard"), + this, SLOT(copyDescToClip())); + ctxMenu->insertItem(i18n("copy url to clipboard"), + this, SLOT(copyUrlToClip())); + ctxMenu->insertItem(i18n("copy launcher to clipboard"), + this, SLOT(copyLauncherToClip())); + ctxMenu->insertItem(i18n("copy comment to clipboard"), + this, SLOT(copyCommentToClip())); + ctxMenu->insertSeparator(); + ctxMenu->insertItem(i18n("Execute \"Launcher\""), mainClass, + SLOT(execLauncher_slot())); + ctxMenu->insertItem(i18n("Go to \"URL\""), mainClass, + SLOT(goToURL_slot())); +} + +void PwMView::resizeEvent(QResizeEvent *) +{ + resizeView(size()); +} + +void PwMView::refreshCommentTextEdit(QListViewItem *curItem) +{ + PWM_ASSERT(commentBox); + if (!curItem) + return; + string comment; + PwMerror ret; + ret = document()->getCommentByLvp(getCurrentCategory(), + lv->childCount() - lv->itemIndex(curItem) - 1, + &comment); + if (ret == e_binEntry) { + commentBox->setContent(i18n("This is a binary entry.\n" + "It is not a normal password-entry, as it contains " + "binary data, which PwManager can't display here.")); + } else if (ret == e_normalEntry) { + commentBox->setContent(comment.c_str()); + } else { + BUG(); + return; + } + lv->ensureItemVisible(curItem); +} + +void PwMView::keyReleaseEvent(QKeyEvent * /*e*/) +{ + refreshCommentTextEdit(lv->currentItem()); +} + +bool PwMView::getCurEntryIndex(unsigned int *index) +{ + QListViewItem *current = lv->currentItem(); + if (!current) + return false; + return getDocEntryIndex(index, current); +} + +bool PwMView::getDocEntryIndex(unsigned int *index, + const QListViewItem *item) +{ + vector foundPositions; + PwMDataItem curItem; + curItem.desc = item->text(COLUMN_DESC).latin1(); + curItem.name = item->text(COLUMN_NAME).latin1(); + document()->getCommentByLvp(getCurrentCategory(), + lv->childCount() - lv->itemIndex(item) - 1, + &curItem.comment); + curItem.url = item->text(COLUMN_URL).latin1(); + curItem.launcher = item->text(COLUMN_LAUNCHER).latin1(); + document()->findEntry(getCurrentCategory(), curItem, SEARCH_IN_DESC | + SEARCH_IN_NAME | SEARCH_IN_COMMENT | SEARCH_IN_URL | + SEARCH_IN_LAUNCHER, + &foundPositions, true); + if (foundPositions.size()) { + *index = foundPositions[0]; + return true; + } + + return false; +} + +void PwMView::handleToggle(QListViewItem *item) +{ + PWM_ASSERT(doc); + if (!item) + return; + QCheckListItem *clItem = (QCheckListItem *)item; + QString curCat(getCurrentCategory()); + + // find document position of this entry. + unsigned int curEntryDocIndex; + if (!getDocEntryIndex(&curEntryDocIndex, item)) + return; + + // hack to refresh the comment, if only one item is present + if (lv->childCount() == 1) + refreshCommentTextEdit(lv->currentItem()); + + if (doc->isLocked(curCat, curEntryDocIndex) != clItem->isOn()) + return; // this is just a click somewhere on the entry + if (doc->isDeepLocked()) { + PwMerror ret; + ret = doc->deepLock(false); + if (ret != e_success) + clItem->setOn(false); + return; + } + doc->lockAt(curCat, curEntryDocIndex, !clItem->isOn()); +} + +void PwMView::handleRightClick(QListViewItem *item, const QPoint &point, int) +{ + if (!item) + return; + ctxMenu->move(point); + /* don't use ctxMenu->exec() here, as it generates race conditions + * with the card interface code. Believe it or not. :) + */ + ctxMenu->show(); +} + +void PwMView::updateCategories() +{ + QString oldSel(getCurrentCategory()); + delAllCategories(); + QStringList catList; + document()->getCategoryList(&catList); + catList.sort(); +#ifndef PWM_EMBEDDED + QStringList::iterator i = catList.begin(), + end = catList.end(); +#else + QStringList::Iterator i = catList.begin(), + end = catList.end(); +#endif + while (i != end) { + addCategory(*i); + ++i; + } + selectCategory(oldSel); +} + +void PwMView::shiftToView() +{ + int cX = lv->contentsX(); + int cY = lv->contentsY(); + commentBox->clear(); + + unsigned int catDocIndex; + if (unlikely( + !(document()->findCategory(getCurrentCategory(), + &catDocIndex)))) { + BUG(); + } + + // ensure all listViewPos are set + doc->ensureLvp(); + + // clear all tmp-data vectors + unsigned int i, entries = doc->numEntries(catDocIndex); + if (entries) { + mainClass->setVirgin(false); + } + vector tmpSorted; + PwMDataItem currItem; + currItem.clear(); + tmpSorted.insert(tmpSorted.begin(), entries, currItem); + + // Sort items and store them in tempoary tmpSorted. + for (i = 0; i < entries; ++i) { + doc->getEntry(catDocIndex, i, &currItem); + tmpSorted[currItem.listViewPos] = currItem; + } + + // shift tempoary data to ListView. + tmpDisableSort(); + lv->clear(); + QCheckListItem *newItem; + vector::iterator it = tmpSorted.begin(), + end = tmpSorted.end(); + while (it != end) { + newItem = new ListViewItemPwM(lv); + newItem->setText(COLUMN_DESC, (*it).desc.c_str()); + if ((*it).binary) { + newItem->setText(COLUMN_NAME, ""); + newItem->setText(COLUMN_PW, i18n("")); + newItem->setText(COLUMN_URL, ""); + newItem->setText(COLUMN_LAUNCHER, (*it).launcher.c_str()); + } else { + newItem->setText(COLUMN_NAME, (*it).name.c_str()); + if ((*it).lockStat) { + newItem->setText(COLUMN_PW, QString((*it).pw.c_str()) + + " " + + i18n("To unlock click the icon on the left.")); + } else { + newItem->setText(COLUMN_PW, (*it).pw.c_str()); + } + newItem->setText(COLUMN_URL, (*it).url.c_str()); + newItem->setText(COLUMN_LAUNCHER, (*it).launcher.c_str()); + } + newItem->setOn(!((*it).lockStat)); + lv->insertItem(newItem); + ++it; + } + tmpReEnableSort(); + + if (cY || cX) + lv->setContentsPos(cX, cY); +} + +void PwMView::reorgLp() +{ + if (!lv->childCount()) + return; + PWM_ASSERT(doc); + PWM_ASSERT(!doc->isDocEmpty()); + QListViewItem *currItem; + vector foundPos; + /* This searchIn _should_ be: + * const unsigned int searchIn = SEARCH_IN_DESC; + * But we want backward compatibility (see comment in PwMDoc::addEntry()). + * So we need to search again, if we don't find the entry. (see below) + */ + const unsigned int searchIn = SEARCH_IN_DESC | SEARCH_IN_NAME | + SEARCH_IN_URL | SEARCH_IN_LAUNCHER; + QString curCat(getCurrentCategory()); + PwMDataItem findThis; + unsigned int i, cnt = lv->childCount(); + for (i = 0; i < cnt; ++i) { + currItem = lv->itemAtIndex(i); + findThis.desc = currItem->text(COLUMN_DESC).latin1(); + findThis.name = currItem->text(COLUMN_NAME).latin1(); + findThis.url = currItem->text(COLUMN_URL).latin1(); + findThis.launcher = currItem->text(COLUMN_LAUNCHER).latin1(); + doc->findEntry(curCat, findThis, searchIn, + &foundPos, true); + if (!foundPos.size()) { + /* Did not find the entry. We seem to have a binary + * entry here (pray for it!). So search again with + * the "correct" searchIn flags. + */ + const unsigned int searchIn2 = SEARCH_IN_DESC; + doc->findEntry(curCat, findThis, searchIn2, + &foundPos, true); + if (unlikely(!foundPos.size())) { + BUG(); + continue; + } + /* We assert that it's a binary entry, now. + * No chance to efficiently verify it here. + */ + } + doc->setListViewPos(curCat, foundPos[0], cnt - i - 1); + } +} + +void PwMView::selAt(int index) +{ + QListViewItem *item = lv->itemAtIndex(index); + if (!item) + return; + lv->setCurrentItem(item); + lv->ensureItemVisible(item); +} + +void PwMView::renCatButton_slot() +{ + if (doc->isDeepLocked()) + return; + RenCatWnd wnd(this); + if (wnd.exec() == 1) { + QString newName(wnd.getNewName()); + if (newName == "") + return; + document()->renameCategory(getCurrentCategory(), + newName); + } +} + +void PwMView::delCatButton_slot() +{ + if (doc->isDeepLocked()) + return; + if (numCategories() <= 1) { + mainClass->showStatMsg(i18n("Can't remove the last category.")); + return; + } + if (KMessageBox::questionYesNo(this, + i18n("Do you really want to " + "delete the selected " + "category? All password-" + "entries will be lost in " + "this category!"), + i18n("Delete category?")) + == KMessageBox::No) { + return; + } + document()->delCategory(getCurrentCategory()); +} + +void PwMView::copyPwToClip() +{ + if (doc->isDeepLocked()) + return; + unsigned int curIndex = 0; + if (!getCurEntryIndex(&curIndex)) + return; + PwMDataItem d; + document()->getDataChangedLock(); + document()->getEntry(getCurrentCategory(), curIndex, &d, true); + document()->putDataChangedLock(); + PwM::copyToClipboard(d.pw.c_str()); +} + +void PwMView::copyNameToClip() +{ + if (doc->isDeepLocked()) + return; + unsigned int curIndex = 0; + if (!getCurEntryIndex(&curIndex)) + return; + PwMDataItem d; + document()->getEntry(getCurrentCategory(), curIndex, &d); + PwM::copyToClipboard(d.name.c_str()); +} + +void PwMView::copyDescToClip() +{ + if (doc->isDeepLocked()) + return; + unsigned int curIndex = 0; + if (!getCurEntryIndex(&curIndex)) + return; + PwMDataItem d; + document()->getEntry(getCurrentCategory(), curIndex, &d); + PwM::copyToClipboard(d.desc.c_str()); +} + +void PwMView::copyUrlToClip() +{ + if (doc->isDeepLocked()) + return; + unsigned int curIndex = 0; + if (!getCurEntryIndex(&curIndex)) + return; + PwMDataItem d; + document()->getEntry(getCurrentCategory(), curIndex, &d); + PwM::copyToClipboard(d.url.c_str()); +} + +void PwMView::copyLauncherToClip() +{ + if (doc->isDeepLocked()) + return; + unsigned int curIndex = 0; + if (!getCurEntryIndex(&curIndex)) + return; + PwMDataItem d; + document()->getEntry(getCurrentCategory(), curIndex, &d); + PwM::copyToClipboard(d.launcher.c_str()); +} + +void PwMView::copyCommentToClip() +{ + if (doc->isDeepLocked()) + return; + unsigned int curIndex = 0; + if (!getCurEntryIndex(&curIndex)) + return; + PwMDataItem d; + document()->getEntry(getCurrentCategory(), curIndex, &d); + PwM::copyToClipboard(d.comment.c_str()); +} + +#ifndef PWM_EMBEDDED +#include "pwmview.moc" +#endif diff --git a/pwmanager/pwmanager/pwmview.h b/pwmanager/pwmanager/pwmview.h new file mode 100644 index 0000000..b4cec65 --- a/dev/null +++ b/pwmanager/pwmanager/pwmview.h @@ -0,0 +1,140 @@ +/*************************************************************************** + * * + * 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 PWMVIEW_H +#define PWMVIEW_H + +#include "listviewpwm.h" +#include "pwmdoc.h" +#include "pwmviewstyle.h" + +#include +#include + +#include +#include +#include + +#include +#include + +using std::string; +using std::vector; + +class PwM; +class ConfFile; +class PwMStatusBar; + + +/** View class for PwM */ +class PwMView : public PwMViewStyle +{ + Q_OBJECT + friend class PwMViewStyle; +public: + /** construtor */ + PwMView(PwM *_mainClass, QWidget* parent, PwMDoc *_doc, + const char *name = 0); + /** destructor */ + ~PwMView(); + + /** returns pointer to the document */ + PwMDoc* document() + { return doc; } + /** returns the index of the currently selected entry. + * (index as represented in PwMDoc !) + */ + bool getCurEntryIndex(unsigned int *index); + /** returns the position of the given item in the document + * Note: This func only serches in the current category. + */ + bool getDocEntryIndex(unsigned int *index, + const QListViewItem *item); + +public slots: + /** update the view (call if dirty) */ + void updateView() + { + updateCategories(); + shiftToView(); + } + /** (re)sort all items and (re)shift them to listView. */ + void shiftToView(); + /** handle clicking on an item */ + void handleToggle(QListViewItem *item); + /** handle right-clicking on an item */ + void handleRightClick(QListViewItem *item, const QPoint &point, int); + /** selects the item at "index" */ + void selAt(int index); + /** rename category button pressed */ + void renCatButton_slot(); + /** delete category button pressed */ + void delCatButton_slot(); + +protected: + /** right-click context-menu */ + QPopupMenu *ctxMenu; + +protected: + /** update the categories from document */ + void updateCategories(); + /** widget resize event */ + void resizeEvent(QResizeEvent *); + /** initialize context-menu */ + void initCtxMenu(); + /** tempoarly disable auto-sorting and user-sorting */ + void tmpDisableSort() + { lv->setSorting(-1); } + /** re-enable tempoarly disabled sorting */ + void tmpReEnableSort() + { + lv->setSorting(lv->columns() + 1, + true/*lv->sortOrder() == Qt::Ascending*/); + } + /** The user pressed and released a key. */ + void keyReleaseEvent(QKeyEvent *e); + +protected slots: + /** changes the comment text-edit, because a new item has been selected */ + void refreshCommentTextEdit(QListViewItem *curItem); + /** copy pw to clipboard */ + void copyPwToClip(); + /** copy name to clipboard */ + void copyNameToClip(); + /** copy desc to clipboard */ + void copyDescToClip(); + /** copy url to clipboard */ + void copyUrlToClip(); + /** copy launcher to clipboard */ + void copyLauncherToClip(); + /** copy comment to clipboard */ + void copyCommentToClip(); + /** reorganize the "listViewPos" positions in the document + * (for the current category only!) + */ + void reorgLp(); + +private: + /** document */ + PwMDoc *doc; + /** pointer to the main class "PwM" */ + PwM *mainClass; +}; + +#endif diff --git a/pwmanager/pwmanager/pwmviewstyle.cpp b/pwmanager/pwmanager/pwmviewstyle.cpp new file mode 100644 index 0000000..67b5197 --- a/dev/null +++ b/pwmanager/pwmanager/pwmviewstyle.cpp @@ -0,0 +1,205 @@ +/*************************************************************************** + * * + * 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 "pwmviewstyle.h" +#include "pwmexception.h" +#include "pwmviewstyle_0.h" +#include "pwmviewstyle_1.h" +#include "listviewpwm.h" +#include "pwmview.h" +#include "commentbox.h" + + +PwMViewStyle::PwMViewStyle(QWidget *parent, const char *name) + : QWidget(parent, name) +{ + curStyle = style_notset; + s0 = 0; + s1 = 0; +} + +PwMViewStyle::~PwMViewStyle() +{ + delete_ifnot_null(s0); + delete_ifnot_null(s1); +} + +void PwMViewStyle::initStyle(style_t style) +{ + printDebug(string("initializing style ") + tostr(style)); + bool wasMaximized = v->isMaximized(); + if (v->isVisible()) + v->hide(); + switch (style) { + case style_0: + delete_ifnot_null(s0); + delete_ifnot_null(s1); + s0 = new PwMViewStyle_0(v); + lv = s0->getLv(); + commentBox = s0->getCommentBox(); + break; + case style_1: + delete_ifnot_null(s0); + delete_ifnot_null(s1); + s1 = new PwMViewStyle_1(v); + lv = s1->getLv(); + commentBox = s1->getCommentBox(); + break; + default: + BUG(); + return; + } + curStyle = style; + connect(lv, SIGNAL(pressed(QListViewItem *)), + v, SLOT(handleToggle(QListViewItem *))); + connect(lv, SIGNAL(rightButtonClicked(QListViewItem *, const QPoint &, int)), + v, SLOT(handleRightClick(QListViewItem *, const QPoint &, int))); + connect(lv, SIGNAL(clicked(QListViewItem *)), + v, SLOT(refreshCommentTextEdit(QListViewItem *))); + lv->addColumn(i18n("Description"), 180); + lv->addColumn(i18n("Username"), 150); + lv->addColumn(i18n("Password"), 150); + lv->addColumn(i18n("URL"), 180); + lv->addColumn(i18n("Launcher"), 120); + v->tmpReEnableSort(); + resizeView(v->size()); + v->updateView(); + if (wasMaximized) { + v->showMaximized(); + } else { + v->show(); + } + connect(lv, SIGNAL(layoutChanged()), + v, SLOT(reorgLp())); +} + +void PwMViewStyle::resizeView(const QSize &size) +{ + switch (curStyle) { + case style_0: + PWM_ASSERT(s0); + s0->resize(size); + return; + case style_1: + PWM_ASSERT(s1); + s1->resize(size); + return; + default: + BUG(); + } +} + +QString PwMViewStyle::getCurrentCategory() +{ + switch (curStyle) { + case style_0: + PWM_ASSERT(s0); + return s0->getCurrentCategory(); + case style_1: + PWM_ASSERT(s1); + return s1->getCurrentCategory(); + default: + BUG(); + } + return ""; +} + +void PwMViewStyle::addCategory(const QString &cat) +{ + switch (curStyle) { + case style_0: + PWM_ASSERT(s0); + s0->addCategory(cat); + return; + case style_1: + PWM_ASSERT(s1); + s1->addCategory(cat); + return; + default: + BUG(); + } +} + +void PwMViewStyle::delCategory(const QString &cat) +{ + switch (curStyle) { + case style_0: + PWM_ASSERT(s0); + s0->delCategory(cat); + return; + case style_1: + PWM_ASSERT(s1); + s1->delCategory(cat); + return; + default: + BUG(); + } +} + +void PwMViewStyle::delAllCategories() +{ + switch (curStyle) { + case style_0: + PWM_ASSERT(s0); + s0->delAllCategories(); + return; + case style_1: + PWM_ASSERT(s1); + s1->delAllCategories(); + return; + default: + BUG(); + } +} + +void PwMViewStyle::selectCategory(const QString &cat) +{ + switch (curStyle) { + case style_0: + PWM_ASSERT(s0); + s0->selectCategory(cat); + return; + case style_1: + PWM_ASSERT(s1); + s1->selectCategory(cat); + return; + default: + BUG(); + } +} + +int PwMViewStyle::numCategories() +{ + switch (curStyle) { + case style_0: + PWM_ASSERT(s0); + return s0->numCategories(); + case style_1: + PWM_ASSERT(s1); + return s1->numCategories(); + default: + BUG(); + } + return 0; +} + +#ifndef PWM_EMBEDDED +#include "pwmviewstyle.moc" +#endif diff --git a/pwmanager/pwmanager/pwmviewstyle.h b/pwmanager/pwmanager/pwmviewstyle.h new file mode 100644 index 0000000..bf5ce91 --- a/dev/null +++ b/pwmanager/pwmanager/pwmviewstyle.h @@ -0,0 +1,108 @@ +/*************************************************************************** + * * + * 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 PWMVIEWSTYLE_H +#define PWMVIEWSTYLE_H + +#include +#include +#include +#include +#include +#include +#ifndef PWM_EMBEDDED +#include +#else +#include +#endif + +#include +#include +#include +#include + +class ListViewPwM; +class PwMViewStyle_0; +class PwMViewStyle_1; +class PwMView; +class CommentBox; + +class PwMViewStyle : public QWidget +{ + Q_OBJECT + +public: + enum style_t + { + style_notset = -1, + style_0 = 0, + style_1 = 1 + }; + +public: + PwMViewStyle(QWidget *parent = 0, const char *name = 0); + ~PwMViewStyle(); + + /** initialize a new style */ + void initStyle(style_t style); + void initStyle(int style) + { initStyle(static_cast(style)); } + /** returns the currently used style */ + style_t getCurStyle() + { return curStyle; } + void setView(PwMView *view) + { v = view; } + + /** returns the currently selected category */ + QString getCurrentCategory(); + +protected: + /** add Category to the view */ + void addCategory(const QString &cat); + /** delete Category from view */ + void delCategory(const QString &cat); + /** delete all categories from view */ + void delAllCategories(); + /** select the specified category */ + void selectCategory(const QString &cat); + /** returns the number of categories in this view. + * This value dosn't say anything about the number of + * categories in the document. + */ + int numCategories(); + /** resize the view */ + void resizeView(const QSize &size); + +private: + /** which style has the view? + * KListBox on the left, + * or QComboBox on the top? + */ + style_t curStyle; + + PwMViewStyle_0 *s0; + PwMViewStyle_1 *s1; + PwMView *v; + +protected: + ListViewPwM *lv; + CommentBox *commentBox; +}; +#endif diff --git a/pwmanager/pwmanager/pwmviewstyle_0.cpp b/pwmanager/pwmanager/pwmviewstyle_0.cpp new file mode 100644 index 0000000..6d46ac6 --- a/dev/null +++ b/pwmanager/pwmanager/pwmviewstyle_0.cpp @@ -0,0 +1,93 @@ +/*************************************************************************** + * * + * 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 "pwmviewstyle_0.h" +#include "pwmview.h" +#include "listviewpwm.h" +#include "commentbox.h" + +#include + + +PwMViewStyle_0::PwMViewStyle_0(PwMView *view) + : QObject() +{ + vbox1 = new QVBox(view); + vbox1->setSpacing(3); + hbox1 = new QHBox(vbox1); + hbox1->setSpacing(10); + categoriesTitle = new QLabel(hbox1); + categoriesTitle->setText(i18n("Categories:")); + categoriesCombo = new QComboBox(hbox1); + renCatButton = new QPushButton(i18n("&Rename"), hbox1); + delCatButton = new QPushButton(i18n("&Delete"), hbox1); +#ifndef PWM_EMBEDDED + splitter1 = new QSplitter(vbox1); + splitter1->setOrientation(Qt::Vertical); +#else + splitter1 = new KDGanttMinimizeSplitter( Qt::Vertical, vbox1); + splitter1->setMinimizeDirection ( KDGanttMinimizeSplitter::Up ); + + //US topLayout->addWidget(mMiniSplitter ); +#endif + lv = new ListViewPwM(splitter1); + commentBox = new CommentBox(splitter1); + // set sizes and styles + commentBox->resize(commentBox->size().width(), 60); + categoriesTitle->setAlignment(Qt::AlignVCenter | Qt::AlignRight); + // connections + connect(categoriesCombo, SIGNAL(activated(int)), + view, SLOT(shiftToView())); + connect(renCatButton, SIGNAL(clicked()), + view, SLOT(renCatButton_slot())); + connect(delCatButton, SIGNAL(clicked()), + view, SLOT(delCatButton_slot())); +} + +PwMViewStyle_0::~PwMViewStyle_0() +{ + delete vbox1; +} + +void PwMViewStyle_0::delCategory(const QString &cat) +{ + PWM_ASSERT(categoriesCombo); + int i, count = categoriesCombo->count(); + for (i = 0; i < count; ++i) { + if (categoriesCombo->text(i) == cat) { + categoriesCombo->removeItem(i); + return; + } + } + BUG(); +} + +void PwMViewStyle_0::selectCategory(const QString &cat) +{ + PWM_ASSERT(categoriesCombo); + int i, count = categoriesCombo->count(); + for (i = 0; i < count; ++i) { + if (categoriesCombo->text(i) == cat) { + categoriesCombo->setCurrentItem(i); + return; + } + } + // fall back to 0 + categoriesCombo->setCurrentItem(0); +} diff --git a/pwmanager/pwmanager/pwmviewstyle_0.h b/pwmanager/pwmanager/pwmviewstyle_0.h new file mode 100644 index 0000000..cc564c3 --- a/dev/null +++ b/pwmanager/pwmanager/pwmviewstyle_0.h @@ -0,0 +1,99 @@ +/*************************************************************************** + * * + * 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 PWMVIEWSTYLE_0_H +#define PWMVIEWSTYLE_0_H + +#include +#include +#include +#ifndef PWM_EMBEDDED +#include +#include +#else +#include +#include +#endif +#include +#include + +class PwMView; +class ListViewPwM; +class CommentBox; + +class PwMViewStyle_0 : public QObject +{ +public: + PwMViewStyle_0(PwMView *view); + ~PwMViewStyle_0(); + + ListViewPwM * getLv() + { return lv; } + CommentBox * getCommentBox() + { return commentBox; } + + /** returns the currently selected category */ + QString getCurrentCategory() + { return categoriesCombo->currentText(); } + /** add Category to the view */ + void addCategory(const QString &cat) + { categoriesCombo->insertItem(cat); } + /** delete Category from view */ + void delCategory(const QString &cat); + /** delete all categories from view */ + void delAllCategories() + { categoriesCombo->clear(); } + /** select the specified category */ + void selectCategory(const QString &cat); + /** returns the number of categories in this view. + * This value dosn't say anything about the number of + * categories in the document. + */ + int numCategories() + { return categoriesCombo->count(); } + /** resize the view */ + void resize(const QSize &size) + { vbox1->resize(size); } + +protected: + /** main list view */ + ListViewPwM *lv; + /** categories combo-box */ + QComboBox *categoriesCombo; + /** title string for the categories combo or list box */ + QLabel *categoriesTitle; + /** hbox1 for widget style */ + QHBox *hbox1; + /** vbox1 for widget style */ + QVBox *vbox1; + /** splitter for commentTextEdit */ +#ifndef PWM_EMBEDDED + QSplitter *splitter1; +#else + KDGanttMinimizeSplitter * splitter1; +#endif + /** push button to change the category name */ + QPushButton *renCatButton; + /** push button to delete the category */ + QPushButton *delCatButton; + /** comment box */ + CommentBox *commentBox; +}; + +#endif diff --git a/pwmanager/pwmanager/pwmviewstyle_1.cpp b/pwmanager/pwmanager/pwmviewstyle_1.cpp new file mode 100644 index 0000000..4c24bc4 --- a/dev/null +++ b/pwmanager/pwmanager/pwmviewstyle_1.cpp @@ -0,0 +1,130 @@ +/*************************************************************************** + * * + * 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 "pwmviewstyle_1.h" +#include "pwmview.h" +#include "listviewpwm.h" +#include "commentbox.h" + +#include + +#define INITIAL_CATEGORIES_WIDTH 100 + +PwMViewStyle_1::PwMViewStyle_1(PwMView *view) + : QObject() +{ +#ifndef PWM_EMBEDDED + splitter = new QSplitter(view); +#else + splitter = new KDGanttMinimizeSplitter( Qt::Horizontal, view); + splitter->setMinimizeDirection ( KDGanttMinimizeSplitter::Right ); + + //US topLayout->addWidget(mMiniSplitter ); +#endif + + vbox1 = new QVBox(splitter); + categoriesTitle = new QLabel(vbox1); + categoriesList = new QListBox(vbox1); +#ifndef PWM_EMBEDDED + splitter2 = new QSplitter(splitter); + splitter2->setOrientation(Qt::Vertical); +#else + splitter2 = new KDGanttMinimizeSplitter( Qt::Vertical, splitter); + splitter2->setMinimizeDirection ( KDGanttMinimizeSplitter::Right ); + + //US topLayout->addWidget(mMiniSplitter ); +#endif + lv = new ListViewPwM(splitter2); + commentBox = new CommentBox(splitter2); + // set sizes and styles + commentBox->resize(commentBox->size().width(), 60); + QValueList sizes; +#ifndef PWM_EMBEDDED + sizes.push_back(INITIAL_CATEGORIES_WIDTH); + sizes.push_back(view->height() - INITIAL_CATEGORIES_WIDTH); +#else + sizes.append(INITIAL_CATEGORIES_WIDTH); + sizes.append(view->height() - INITIAL_CATEGORIES_WIDTH); +#endif + splitter->setSizes(sizes); + categoriesTitle->setAlignment(Qt::AlignHCenter); +#ifndef PWM_EMBEDDED + categoriesTitle->setFrameShape(QFrame::MenuBarPanel); +#else + categoriesTitle->setFrameShape(QFrame::StyledPanel); +#endif + categoriesTitle->setText(i18n("Categories:")); + catCtxMenu = new QPopupMenu(view); + catCtxMenu->insertItem(i18n("&Rename"), + view, SLOT(renCatButton_slot())); + catCtxMenu->insertItem(i18n("&Delete"), + view, SLOT(delCatButton_slot())); + // connections + connect(categoriesList, SIGNAL(highlighted(int)), + view, SLOT(shiftToView())); + connect(categoriesList, + SIGNAL(rightButtonClicked(QListBoxItem *, const QPoint &)), + this, + SLOT(catRightClick(QListBoxItem *, const QPoint &))); +} + +PwMViewStyle_1::~PwMViewStyle_1() +{ + delete catCtxMenu; + delete splitter; +} + +void PwMViewStyle_1::catRightClick(QListBoxItem *item, const QPoint &point) +{ + if (!item) + return; + catCtxMenu->move(point); + catCtxMenu->show(); +} + +void PwMViewStyle_1::delCategory(const QString &cat) +{ + PWM_ASSERT(categoriesList); + int i, count = categoriesList->count(); + for (i = 0; i < count; ++i) { + if (categoriesList->text(i) == cat) { + categoriesList->removeItem(i); + return; + } + } + BUG(); +} + +void PwMViewStyle_1::selectCategory(const QString &cat) +{ + PWM_ASSERT(categoriesList); + int i, count = categoriesList->count(); + for (i = 0; i < count; ++i) { + if (categoriesList->text(i) == cat) { + categoriesList->setCurrentItem(i); + return; + } + } + // fall back to 0 + categoriesList->setCurrentItem(0); +} + +#ifndef PWM_EMBEDDED +#include "pwmviewstyle_1.moc" +#endif diff --git a/pwmanager/pwmanager/pwmviewstyle_1.h b/pwmanager/pwmanager/pwmviewstyle_1.h new file mode 100644 index 0000000..a50f587 --- a/dev/null +++ b/pwmanager/pwmanager/pwmviewstyle_1.h @@ -0,0 +1,107 @@ +/*************************************************************************** + * * + * 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 PWMVIEWSTYLE_1_H +#define PWMVIEWSTYLE_1_H + +#include + +#ifndef PWM_EMBEDDED +#include +#include +#else +#include +#include +#endif + +#include +#include +#include + +class PwMView; +class ListViewPwM; +class CommentBox; + +class PwMViewStyle_1 : public QObject +{ + Q_OBJECT +public: + PwMViewStyle_1(PwMView *view); + ~PwMViewStyle_1(); + + ListViewPwM * getLv() + { return lv; } + CommentBox * getCommentBox() + { return commentBox; } + + /** returns the currently selected category */ + QString getCurrentCategory() + { return categoriesList->currentText(); } + /** add Category to the view */ + void addCategory(const QString &cat) + { categoriesList->insertItem(cat); } + /** delete Category from view */ + void delCategory(const QString &cat); + /** delete all categories from view */ + void delAllCategories() + { categoriesList->clear(); } + /** select the specified category */ + void selectCategory(const QString &cat); + /** returns the number of categories in this view. + * This value dosn't say anything about the number of + * categories in the document. + */ + int numCategories() + { return categoriesList->count(); } + /** resize the view */ + void resize(const QSize &size) + { splitter->resize(size); } + +protected slots: + /** user clicked right button in category list */ + void catRightClick(QListBoxItem *item, const QPoint &point); + +protected: + /** main list view */ + ListViewPwM *lv; +#ifndef PWM_EMBEDDED + /** main splitter widget */ + QSplitter *splitter; + /** commentTextEdit splitter */ + QSplitter *splitter2; +#else + /** main splitter widget */ + KDGanttMinimizeSplitter *splitter; + /** commentTextEdit splitter */ + KDGanttMinimizeSplitter *splitter2; +#endif + + /** categories list-box */ + QListBox *categoriesList; + /** title string for the categories combo or list box */ + QLabel *categoriesTitle; + /** hbox1 for widget style */ + QVBox *vbox1; + /** text-edit to display the comment */ + CommentBox *commentBox; + /** category list context menu */ + QPopupMenu *catCtxMenu; +}; + +#endif diff --git a/pwmanager/pwmanager/randomizer.cpp b/pwmanager/pwmanager/randomizer.cpp new file mode 100644 index 0000000..e623f51 --- a/dev/null +++ b/pwmanager/pwmanager/randomizer.cpp @@ -0,0 +1,124 @@ +/*************************************************************************** + * * + * 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$ + **************************************************************************/ + +#include "randomizer.h" +#include "pwmexception.h" + +#include +#include + + +Randomizer * Randomizer::rndObj (0); + +Randomizer::Randomizer() +{ + // probe for random devices + rndDev = fopen("/dev/urandom", "r"); + if (rndDev) + return; + rndDev = fopen("/dev/random", "r"); + if (rndDev) + return; + // fall back to rand_r() + seed = time(0); +} + +Randomizer::~Randomizer() +{ + if (rndDev) { + if (fclose(rndDev)) { + printWarn("failed closing the random-device!"); + } + } +} + +char Randomizer::genRndChar() +{ + if (rndDev) { + /* we have a rand-device-node */ + return (getc(rndDev)); + } else { + /* we don't have a random-device-node. + * so fall back to rand_r() + */ + return (rand_r(&seed) % 0xFF); + } +} + +int Randomizer::genRndInt() +{ + if(rndDev) { + int ret; + if (sizeof(int) == 4) { + (reinterpret_cast(&ret))[0] = getc(rndDev); + (reinterpret_cast(&ret))[1] = getc(rndDev); + (reinterpret_cast(&ret))[2] = getc(rndDev); + (reinterpret_cast(&ret))[3] = getc(rndDev); + } else if (sizeof(int) == 8) { + (reinterpret_cast(&ret))[0] = getc(rndDev); + (reinterpret_cast(&ret))[1] = getc(rndDev); + (reinterpret_cast(&ret))[2] = getc(rndDev); + (reinterpret_cast(&ret))[3] = getc(rndDev); + (reinterpret_cast(&ret))[4] = getc(rndDev); + (reinterpret_cast(&ret))[5] = getc(rndDev); + (reinterpret_cast(&ret))[6] = getc(rndDev); + (reinterpret_cast(&ret))[7] = getc(rndDev); + } else { + printWarn(string(__FILE__) + ":" + tostr(__LINE__) + + ": sizeof(int) != 4 && sizeof(int) != 8"); + rndDev = 0; + seed = time(0); + return genRndInt(); + } + return ret; + } else { + return rand_r(&seed); + } +} + +unsigned int Randomizer::genRndUInt() +{ + if(rndDev) { + unsigned int ret; + if (sizeof(unsigned int) == 4) { + (reinterpret_cast(&ret))[0] = getc(rndDev); + (reinterpret_cast(&ret))[1] = getc(rndDev); + (reinterpret_cast(&ret))[2] = getc(rndDev); + (reinterpret_cast(&ret))[3] = getc(rndDev); + } else if (sizeof(unsigned int) == 8) { + (reinterpret_cast(&ret))[0] = getc(rndDev); + (reinterpret_cast(&ret))[1] = getc(rndDev); + (reinterpret_cast(&ret))[2] = getc(rndDev); + (reinterpret_cast(&ret))[3] = getc(rndDev); + (reinterpret_cast(&ret))[4] = getc(rndDev); + (reinterpret_cast(&ret))[5] = getc(rndDev); + (reinterpret_cast(&ret))[6] = getc(rndDev); + (reinterpret_cast(&ret))[7] = getc(rndDev); + } else { + printWarn(string(__FILE__) + ":" + tostr(__LINE__) + + ": sizeof(unsigned int) != 4 && sizeof(unsigned int) != 8"); + rndDev = 0; + seed = time(0); + return genRndUInt(); + } + return ret; + } else { + return static_cast(rand_r(&seed)); + } +} diff --git a/pwmanager/pwmanager/randomizer.h b/pwmanager/pwmanager/randomizer.h new file mode 100644 index 0000000..db17334 --- a/dev/null +++ b/pwmanager/pwmanager/randomizer.h @@ -0,0 +1,67 @@ +/*************************************************************************** + * * + * 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 RANDOMIZER_H +#define RANDOMIZER_H + +#include "pwmexception.h" + +#include + +/** simple randomizer + * This class is *NOT* reentrant save! + */ +class Randomizer +{ +public: + Randomizer(); + ~Randomizer(); + + static Randomizer * obj() + { + PWM_ASSERT(rndObj); + return rndObj; + } + static void init() + { + PWM_ASSERT(!rndObj); + rndObj = new Randomizer; + } + static void cleanup() + { + delete_ifnot_null(rndObj); + } + + /** generate random char */ + char genRndChar(); + /** generate random int */ + int genRndInt(); + /** generate random unsigned int */ + unsigned int genRndUInt(); + +protected: + /** random-device-node (if available. Otherwise NULL) */ + FILE *rndDev; + /** seed value for fallback - rand_r() */ + unsigned int seed; + /** static Randomier object returned by obj() */ + static Randomizer *rndObj; +}; + +#endif diff --git a/pwmanager/pwmanager/rc2.cpp b/pwmanager/pwmanager/rc2.cpp new file mode 100644 index 0000000..3b85a3c --- a/dev/null +++ b/pwmanager/pwmanager/rc2.cpp @@ -0,0 +1,222 @@ +/*************************************************************************** + * * + * C implementation of RC2 encryption algorithm, as described in RFC2268 * + * By Matthew Palmer * + * * + * 2003/06/10: * + * Converted to C++ and modified to run with PwM * + * By Michael Buesch * + * * + * 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 "rc2.h" + +static const unsigned char +_rc2_pitable[] = { 0xd9, 0x78, 0xf9, 0xc4, 0x19, 0xdd, 0xb5, 0xed, + 0x28, 0xe9, 0xfd, 0x79, 0x4a, 0xa0, 0xd8, 0x9d, + 0xc6, 0x7e, 0x37, 0x83, 0x2b, 0x76, 0x53, 0x8e, + 0x62, 0x4c, 0x64, 0x88, 0x44, 0x8b, 0xfb, 0xa2, + 0x17, 0x9a, 0x59, 0xf5, 0x87, 0xb3, 0x4f, 0x13, + 0x61, 0x45, 0x6d, 0x8d, 0x09, 0x81, 0x7d, 0x32, + 0xbd, 0x8f, 0x40, 0xeb, 0x86, 0xb7, 0x7b, 0x0b, + 0xf0, 0x95, 0x21, 0x22, 0x5c, 0x6b, 0x4e, 0x82, + 0x54, 0xd6, 0x65, 0x93, 0xce, 0x60, 0xb2, 0x1c, + 0x73, 0x56, 0xc0, 0x14, 0xa7, 0x8c, 0xf1, 0xdc, + 0x12, 0x75, 0xca, 0x1f, 0x3b, 0xbe, 0xe4, 0xd1, + 0x42, 0x3d, 0xd4, 0x30, 0xa3, 0x3c, 0xb6, 0x26, + 0x6f, 0xbf, 0x0e, 0xda, 0x46, 0x69, 0x07, 0x57, + 0x27, 0xf2, 0x1d, 0x9b, 0xbc, 0x94, 0x43, 0x03, + 0xf8, 0x11, 0xc7, 0xf6, 0x90, 0xef, 0x3e, 0xe7, + 0x06, 0xc3, 0xd5, 0x2f, 0xc8, 0x66, 0x1e, 0xd7, + 0x08, 0xe8, 0xea, 0xde, 0x80, 0x52, 0xee, 0xf7, + 0x84, 0xaa, 0x72, 0xac, 0x35, 0x4d, 0x6a, 0x2a, + 0x96, 0x1a, 0xd2, 0x71, 0x5a, 0x15, 0x49, 0x74, + 0x4b, 0x9f, 0xd0, 0x5e, 0x04, 0x18, 0xa4, 0xec, + 0xc2, 0xe0, 0x41, 0x6e, 0x0f, 0x51, 0xcb, 0xcc, + 0x24, 0x91, 0xaf, 0x50, 0xa1, 0xf4, 0x70, 0x39, + 0x99, 0x7c, 0x3a, 0x85, 0x23, 0xb8, 0xb4, 0x7a, + 0xfc, 0x02, 0x36, 0x5b, 0x25, 0x55, 0x97, 0x31, + 0x2d, 0x5d, 0xfa, 0x98, 0xe3, 0x8a, 0x92, 0xae, + 0x05, 0xdf, 0x29, 0x10, 0x67, 0x6c, 0xba, 0xc9, + 0xd3, 0x00, 0xe6, 0xcf, 0xe1, 0x9e, 0xa8, 0x2c, + 0x63, 0x16, 0x01, 0x3f, 0x58, 0xe2, 0x89, 0xa9, + 0x0d, 0x38, 0x34, 0x1b, 0xab, 0x33, 0xff, 0xb0, + 0xbb, 0x48, 0x0c, 0x5f, 0xb9, 0xb1, 0xcd, 0x2e, + 0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77, + 0x0a, 0xa6, 0x20, 0x68, 0xfe, 0x7f, 0xc1, 0xad + }; + +static const int _rc2_s[] = { 1, 2, 3, 5 }; + +Rc2::Rc2() +{ +} + +Rc2::~Rc2() +{ +} + +void Rc2::rc2_expandkey(char key[], int length, int ekl) +{ + int ekl8, keymask, i; + + /* Put supplied key into first length - 1 bytes of the key buffer */ + for (i = 0; i < length; i++) { + _rc2_expkey[i] = key[i]; + } + + ekl8 = (ekl + 7) / 8; + i = _rc2_pow(2, (8 + ekl - 8 * ekl8)); + keymask = 255 % i; + + /* First expansion step */ + for (i = length; i < 128; i++) { + _rc2_expkey[i] = _rc2_pitable[(_rc2_expkey[i - 1] + _rc2_expkey[i - length]) % 256]; + } + + /* Expansion intermediate step */ + _rc2_expkey[128 - ekl8] = _rc2_pitable[_rc2_expkey[128 - ekl8] & keymask]; + + /* Third Expansion step */ + for (i = 127 - ekl8; i >= 0; i--) { + _rc2_expkey[i] = _rc2_pitable[_rc2_expkey[i + 1] ^ _rc2_expkey[i + ekl8]]; + } +} + +void Rc2::rc2_encrypt(unsigned short input[4]) +{ + int i; + + _rc2_counter = 0; + for (i = 0; i < 5; i++) { + _rc2_mix(input); + } + _rc2_mash(input); + for (i = 0; i < 6; i++) { + _rc2_mix(input); + } + _rc2_mash(input); + for (i = 0; i < 5; i++) { + _rc2_mix(input); + } +} + +void Rc2::_rc2_mix(unsigned short input[]) +{ + unsigned short K, i; + + for (i = 0; i < 4; i++) { + K = _rc2_expkey[_rc2_counter * 2] + 256 * _rc2_expkey[_rc2_counter * 2 + 1]; + input[i] = input[i] + K + (input[(i + 3) % 4] & input[(i + 2) % 4]) + ((~input[(i + 3) % 4]) & input[(i + 1) % 4]); + _rc2_counter++; + input[i] = _rc2_rol(input[i], _rc2_s[i]); + } +} + +void Rc2::_rc2_mash(unsigned short input[]) +{ + unsigned short K, i, x; + + for (i = 0; i < 4; i++) { + x = input[(i + 3) % 4] & 63; + K = _rc2_expkey[2 * x] + 256 * _rc2_expkey[2 * x + 1]; + input[i] = input[i] + K; + } +} + +void Rc2::rc2_decrypt(unsigned short input[4]) +{ + int i; + + _rc2_counter = 63; + for (i = 0; i < 5; i++) { + _rc2_rmix(input); + } + _rc2_rmash(input); + for (i = 0; i < 6; i++) { + _rc2_rmix(input); + } + _rc2_rmash(input); + for (i = 0; i < 5; i++) { + _rc2_rmix(input); + } +} + +void Rc2::_rc2_rmix(unsigned short input[]) +{ + unsigned short K; + int i; + + for (i = 3; i >= 0; i--) { + input[i] = _rc2_ror(input[i], _rc2_s[i]); + K = _rc2_expkey[_rc2_counter * 2] + 256 * _rc2_expkey[_rc2_counter * 2 + 1]; + input[i] = input[i] - K - (input[(i + 3) % 4] & input[(i + 2) % 4]) - ((~input[(i + 3) % 4]) & input[(i + 1) % 4]); + _rc2_counter--; + } +} + +void Rc2::_rc2_rmash(unsigned short input[]) +{ + unsigned short K, x; + int i; + + for (i = 3; i >= 0; i--) { + x = input[(i + 3) % 4] & 63; + K = _rc2_expkey[2 * x] + 256 * _rc2_expkey[2 * x + 1]; + input[i] = input[i] - K; + } +} +int Rc2::_rc2_pow(int base, int exponent) +{ + int i, result; + + if (exponent == 0) { + return 1; + } + result = 1; + for (i = 0; i < exponent; i++) { + result = result * base; + } + return result; +} + +unsigned short Rc2::_rc2_rol(unsigned short input, int places) +{ + unsigned short temp, i; + + for (i = 0; i < places; i++) { + temp = input & 0x8000; + input = input << 1; + if (temp) { + input++; + } + } + return input; +} + +unsigned short Rc2::_rc2_ror(unsigned short input, int places) +{ + unsigned short temp, i; + + for (i = 0; i < places; i++) { + temp = input & 0x1; + input = input >> 1; + if (temp) { + input = input + 0x8000; + } + } + return input; +} + diff --git a/pwmanager/pwmanager/rc2.h b/pwmanager/pwmanager/rc2.h new file mode 100644 index 0000000..d321da6 --- a/dev/null +++ b/pwmanager/pwmanager/rc2.h @@ -0,0 +1,50 @@ +/*************************************************************************** + * * + * Header file for rc2 implementation by Matthew Palmer * + * Modified to run with PwM by Michael Buesch * + * * + * 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 RC2_H +#define RC2_H + +/** implementation of the RC2 encryption algorithm. */ +class Rc2 +{ +public: + Rc2(); + ~Rc2(); + + void rc2_expandkey(char key[], int length, int ekl); + void rc2_encrypt(unsigned short input[4]); + void rc2_decrypt(unsigned short input[4]); + +protected: + void _rc2_mix(unsigned short *); + void _rc2_mash(unsigned short *); + void _rc2_rmix(unsigned short *); + void _rc2_rmash(unsigned short *); + int _rc2_pow(int, int); + unsigned short _rc2_ror(unsigned short, int); + unsigned short _rc2_rol(unsigned short, int); + +protected: + /** Expanded Key */ + unsigned char _rc2_expkey[128]; + /** global integer variable used in mixing */ + int _rc2_counter; +}; + +#endif diff --git a/pwmanager/pwmanager/rencatwnd.cpp b/pwmanager/pwmanager/rencatwnd.cpp new file mode 100644 index 0000000..1e8f9e9 --- a/dev/null +++ b/pwmanager/pwmanager/rencatwnd.cpp @@ -0,0 +1,70 @@ +/*************************************************************************** + * * + * copyright (C) 2003 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 "rencatwnd.h" + +#include + + +RenCatWnd::RenCatWnd(QWidget *parent, + const char *name, bool modal, WFlags f) + : QDialog(parent, name, modal, f) +{ + vbox1 = new QVBox(this); + label = new QLabel(vbox1); + newName = new QLineEdit(vbox1); + hbox1 = new QHBox(vbox1); + okButton = new QPushButton(i18n("&Ok"), hbox1); + cancelButton = new QPushButton(i18n("&Cancel"), hbox1); + + vbox1->setSpacing(10); + vbox1->setMargin(10); + hbox1->setSpacing(10); + + resize(400, 100); + + setCaption(i18n("rename category")); + label->setText(i18n("New category name:")); + + connect(okButton, SIGNAL(clicked()), this, SLOT(okButton_slot())); + connect(cancelButton, SIGNAL(clicked()), this, SLOT(cancelButton_slot())); +} + +RenCatWnd::~RenCatWnd() +{ +} + +void RenCatWnd::resizeEvent(QResizeEvent *) +{ + vbox1->resize(size()); +} + +void RenCatWnd::okButton_slot() +{ + done(1); +} + +void RenCatWnd::cancelButton_slot() +{ + done(2); +} + +#ifndef PWM_EMBEDDED +#include "rencatwnd.moc" +#endif diff --git a/pwmanager/pwmanager/rencatwnd.h b/pwmanager/pwmanager/rencatwnd.h new file mode 100644 index 0000000..37b6725 --- a/dev/null +++ b/pwmanager/pwmanager/rencatwnd.h @@ -0,0 +1,60 @@ +/*************************************************************************** + * * + * copyright (C) 2003 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 RENCATWND_H +#define RENCATWND_H + +#include +#include +#include +#include +#include +#include +#include + + +/** rename category window */ +class RenCatWnd : public QDialog +{ + Q_OBJECT +public: + RenCatWnd(QWidget *parent = 0, const char *name = 0, + bool modal = FALSE, WFlags f = 0); + ~RenCatWnd(); + + QString getNewName() + { return newName->text(); } + +protected slots: + void okButton_slot(); + void cancelButton_slot(); + +protected: + QVBox *vbox1; + QHBox *hbox1; + QLabel *label; + QLineEdit *newName; + QPushButton *okButton; + QPushButton *cancelButton; + +protected: + void resizeEvent(QResizeEvent *); +}; + +#endif diff --git a/pwmanager/pwmanager/selftest.cpp b/pwmanager/pwmanager/selftest.cpp new file mode 100644 index 0000000..45179d8 --- a/dev/null +++ b/pwmanager/pwmanager/selftest.cpp @@ -0,0 +1,105 @@ +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#include "selftest.h" +#include "pwmexception.h" +#include "sha1.h" +#include "blowfish.h" +#include "base64.h" + +#include + + +static SelfTest *st = 0; +static pthread_mutex_t st_mutex = PTHREAD_MUTEX_INITIALIZER; + + +SelfTest::SelfTest() +{ + connect(&schedTimer, SIGNAL(timeout()), + this, SLOT(doSelfTest())); +} + +SelfTest::~SelfTest() +{ +} + +void SelfTest::run() +{ +// printDebug("running self-test..."); + if (unlikely(!Sha1::selfTest())) { + failed("SHA1"); + return; + } + if (unlikely(!Blowfish::selfTest())) { + failed("BLOWFISH"); + return; + } + if (unlikely(!Base64::selfTest())) { + failed("BASE64"); + return; + } +// printDebug("self-test done."); + if (!pthread_mutex_trylock(&st_mutex)) { + /* only cancel (delete) this thread, if there's currently + * noone else doing this job. Otherwise we will deadlock. + * we use a timer here, to do some kind of context-switch. + */ + QTimer::singleShot(0, st, SLOT(doCancel())); + } +} + +void SelfTest::failed(const char *algo) +{ + string msg("\n\n\n" + "PwManager FATAL ERROR:\n" + "Self-test for algorithm \""); + msg += algo; + msg += "\" failed!\n\n"; + msg += "It's likely to be either a PwManager BUG or " + "bad hardware in your machine. Please contact the " + "maintainer of PwManager for this issue."; + std::cerr << msg << std::endl; + ::exit(1); +} + +void SelfTest::schedule() +{ + if (pthread_mutex_lock(&st_mutex)) + return; + if (st) + goto out; + st = new SelfTest; + st->startTimer(); +out: + pthread_mutex_unlock(&st_mutex); +} + +void SelfTest::cancel() +{ + if (pthread_mutex_lock(&st_mutex)) + return; + if (!st) { + pthread_mutex_unlock(&st_mutex); + return; + } + st->doCancel(); +} + +void SelfTest::doCancel() +{ + st->stopTimer(); + st->wait(); + delete_and_null(st); + pthread_mutex_unlock(&st_mutex); +} + +#include "selftest.moc" diff --git a/pwmanager/pwmanager/selftest.h b/pwmanager/pwmanager/selftest.h new file mode 100644 index 0000000..4f3ea51 --- a/dev/null +++ b/pwmanager/pwmanager/selftest.h @@ -0,0 +1,67 @@ +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef __SELFTEST_H +#define __SELFTEST_H + +#include +#include +#include + +// timeout in seconds +#define SCHEDULE_TIMEOUT 3 + +/* internal wrapper to workaround MOC issues */ +class __SelfTest : public QThread + , public QObject +{ +public: + __SelfTest() {} +}; + +/** PwManager algorithm selftest */ +class SelfTest : public __SelfTest +{ + Q_OBJECT +public: + SelfTest(); + ~SelfTest(); + + /** schedule a new test. Only one test can run at once! */ + static void schedule(); + /** cancel the running test (if there is one) */ + static void cancel(); + +protected: + /** start the sched timer */ + void startTimer() + { schedTimer.start(SCHEDULE_TIMEOUT * 1000, true); } + /** stop the sched timer */ + void stopTimer() + { schedTimer.stop(); } + +protected slots: + void doSelfTest() + { start(); } + void doCancel(); + +protected: + /** print the "failed" message and exit the app */ + void failed(const char *algo); + /** worker thread */ + void run(); + +protected: + /** schedule timer */ + QTimer schedTimer; +}; + +#endif diff --git a/pwmanager/pwmanager/serializer.cpp b/pwmanager/pwmanager/serializer.cpp new file mode 100644 index 0000000..65e442d --- a/dev/null +++ b/pwmanager/pwmanager/serializer.cpp @@ -0,0 +1,664 @@ +/*************************************************************************** + * * + * 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 2.0 of pwmanager + * and was modified to run on embedded devices that run microkde + * + * $Id$ + **************************************************************************/ + +#include "serializer.h" +#include "pwmexception.h" + +#ifdef PWM_EMBEDDED +#include +#endif + +/* enable/disable serializer debugging (0/1) */ +#define SERIALIZER_DEBUG 0 +/* use the old xml tags for writing (0/1) */ +#define USE_OLD_TAGS 0 +/* write a CDATA section (0/1) */ +#define WRITE_CDATA_SEC 0 + + +#define META_CREATE_DATE "c" +#define META_VALID_DATE "v" +#define META_EXPIRE_DATE "e" +#define META_UPDATE_DATE "u" +#define META_UPDATE_INT "i" +//US ENH : uniqueid +#define META_UNIQUEID "n" + +/* This is compatibility stuff. + * The names of the entries have changed and here are the + * new and old ones + */ +#define ROOT_MAGIC_OLD "PwM-xml-dat" +#define VER_STR_OLD "ver" +#define COMPAT_VER_OLD "0x02" +#define CAT_ROOT_OLD "categories" +#define CAT_PREFIX_OLD "cat_" +#define CAT_NAME_OLD "name" +#define ENTRY_PREFIX_OLD "entry_" +#define ENTRY_DESC_OLD "desc" +#define ENTRY_NAME_OLD "name" +#define ENTRY_PW_OLD "pw" +#define ENTRY_COMMENT_OLD "comment" +#define ENTRY_URL_OLD "url" +#define ENTRY_LAUNCHER_OLD "launcher" +#define ENTRY_LVP_OLD "listViewPos" +#define ENTRY_BIN_OLD "b" +#define ENTRY_META_OLD "m" + +#define ROOT_MAGIC_NEW "P" +#define VER_STR_NEW "v" +#define COMPAT_VER_NEW "2" +#define CAT_ROOT_NEW "c" +#define CAT_PREFIX_NEW "c" +#define CAT_NAME_NEW "n" +#define ENTRY_PREFIX_NEW "e" +#define ENTRY_DESC_NEW "d" +#define ENTRY_NAME_NEW "n" +#define ENTRY_PW_NEW "p" +#define ENTRY_COMMENT_NEW "c" +#define ENTRY_URL_NEW "u" +#define ENTRY_LAUNCHER_NEW "l" +#define ENTRY_LVP_NEW "v" +#define ENTRY_BIN_NEW ENTRY_BIN_OLD +#define ENTRY_META_NEW ENTRY_META_OLD + +#if USE_OLD_TAGS != 0 +# define ROOT_MAGIC_WR ROOT_MAGIC_OLD +# define VER_STR_WR VER_STR_OLD +# define COMPAT_VER_WR COMPAT_VER_OLD +# define CAT_ROOT_WR CAT_ROOT_OLD +# define CAT_PREFIX_WR CAT_PREFIX_OLD +# define CAT_NAME_WR CAT_NAME_OLD +# define ENTRY_PREFIX_WR ENTRY_PREFIX_OLD +# define ENTRY_DESC_WR ENTRY_DESC_OLD +# define ENTRY_NAME_WR ENTRY_NAME_OLD +# define ENTRY_PW_WR ENTRY_PW_OLD +# define ENTRY_COMMENT_WR ENTRY_COMMENT_OLD +# define ENTRY_URL_WR ENTRY_URL_OLD +# define ENTRY_LAUNCHER_WR ENTRY_LAUNCHER_OLD +# define ENTRY_LVP_WR ENTRY_LVP_OLD +# define ENTRY_BIN_WR ENTRY_BIN_OLD +# define ENTRY_META_WR ENTRY_META_OLD +#else +# define ROOT_MAGIC_WR ROOT_MAGIC_NEW +# define VER_STR_WR VER_STR_NEW +# define COMPAT_VER_WR COMPAT_VER_NEW +# define CAT_ROOT_WR CAT_ROOT_NEW +# define CAT_PREFIX_WR CAT_PREFIX_NEW +# define CAT_NAME_WR CAT_NAME_NEW +# define ENTRY_PREFIX_WR ENTRY_PREFIX_NEW +# define ENTRY_DESC_WR ENTRY_DESC_NEW +# define ENTRY_NAME_WR ENTRY_NAME_NEW +# define ENTRY_PW_WR ENTRY_PW_NEW +# define ENTRY_COMMENT_WR ENTRY_COMMENT_NEW +# define ENTRY_URL_WR ENTRY_URL_NEW +# define ENTRY_LAUNCHER_WR ENTRY_LAUNCHER_NEW +# define ENTRY_LVP_WR ENTRY_LVP_NEW +# define ENTRY_BIN_WR ENTRY_BIN_NEW +# define ENTRY_META_WR ENTRY_META_NEW +#endif + + +Serializer::Serializer() +{ + defaultLockStat = true; + domDoc = new QDomDocument; +} + +Serializer::Serializer(const QCString &buffer) +{ + defaultLockStat = true; + domDoc = new QDomDocument; + if (!parseXml(buffer)) { + delete domDoc; +#ifndef PWM_EMBEDDED + throw PwMException(PwMException::EX_PARSE); +#else + qDebug("Serializer::Serializer : Parse Exception "); +#endif + } +} + +Serializer::~Serializer() +{ + delete_ifnot_null(domDoc); +} + +void Serializer::clear() +{ + delete_ifnot_null(domDoc); + domDoc = new QDomDocument; +} + +bool Serializer::parseXml(const QCString &buffer) +{ + PWM_ASSERT(domDoc); +#ifndef PWM_EMBEDDED + if (!domDoc->setContent(buffer, true)) + return false; +#else + if (!domDoc->setContent(buffer)) + return false; +#endif + if (!checkValid()) + return false; + return true; +} + +QCString Serializer::getXml() +{ + PWM_ASSERT(domDoc); + +#ifndef PWM_EMBEDDED +#if defined(PWM_DEBUG) && SERIALIZER_DEBUG != 0 + QCString tmp(domDoc->toCString(8)); + printDebug("\n"); + cout << tmp << endl; + printDebug(""); +#endif // DEBUG + + QCString ret(domDoc->toCString(0)); + ret.replace('\n', ""); + return ret; +#else + +#if defined(PWM_DEBUG) && SERIALIZER_DEBUG != 0 + QCString tmp(" " + domDoc->toCString()); + printDebug("\n"); + cout << tmp << endl; + printDebug(""); +#endif // DEBUG + + QCString ret(domDoc->toCString()); + ret.replace(QRegExp("\n"), ""); + return ret; + +#endif +} + +bool Serializer::serialize(const vector &dta) +{ + PWM_ASSERT(domDoc); + QDomElement root(genNewRoot()); + QDomElement catNode(domDoc->createElement(CAT_ROOT_WR)); + root.appendChild(catNode); + if (!addCategories(&catNode, dta)) + return false; + return true; +} + +bool Serializer::deSerialize(vector *dta) +{ + PWM_ASSERT(domDoc); + PWM_ASSERT(dta); + QDomElement root(domDoc->documentElement()); + QDomNode n; + + dta->clear(); + for (n = root.firstChild(); !n.isNull(); n = n.nextSibling()) { + // find ... + // ... + if (n.nodeName() == CAT_ROOT_NEW || + n.nodeName() == CAT_ROOT_OLD) { + if (!readCategories(n, dta)) { + return false; + } + + /* NOTE: We can stop processing here, as we + * don't have more nodes in root, yet. + */ + return true; + } + } + return false; +} + +bool Serializer::readCategories(const QDomNode &n, + vector *dta) +{ + QDomNodeList nl(n.childNodes()); + QDomNode cur; + QString name; + unsigned int numCat = nl.count(), i; + PwMCategoryItem curCat; + vector curEntr; + + if (!numCat) { + printDebug("Serializer::readCategories(): empty"); + return false; + } + for (i = 0; i < numCat; ++i) { + cur = nl.item(i); + if (cur.nodeName().left(1) == CAT_PREFIX_NEW || + cur.nodeName().left(4) == CAT_PREFIX_OLD) { + name = cur.toElement().attribute(CAT_NAME_NEW); + if (name == QString::null) + name = cur.toElement().attribute(CAT_NAME_OLD); + PWM_ASSERT(name != QString::null); + PWM_ASSERT(name != ""); + curCat.clear(); + curCat.name = name.latin1(); + if (!readEntries(cur, &curEntr)) { + dta->clear(); + return false; + } + curCat.d = curEntr; + dta->push_back(curCat); + } else { + printDebug("Serializer::readCategories(): uh? not a category?"); + } + } + return true; +} + +bool Serializer::readEntries(const QDomNode &n, + vector *dta) +{ + QDomNodeList nl(n.childNodes()); + QDomNode cur; + unsigned int numEntr = nl.count(), i; + PwMDataItem curEntr; + + dta->clear(); + for (i = 0; i < numEntr; ++i) { + cur = nl.item(i); + if (cur.nodeName().left(1) == ENTRY_PREFIX_NEW || + cur.nodeName().left(6) == ENTRY_PREFIX_OLD) { + if (!extractEntry(cur, &curEntr)) { + return false; + } + dta->push_back(curEntr); + } else { + printDebug("Serializer::readEntries(): hm? not an entry?"); + } + } + return true; +} + +bool Serializer::extractEntry(const QDomNode &n, + PwMDataItem *dta) +{ + QDomNodeList nl(n.childNodes()); + QDomNode cur, cdata; + unsigned int cnt = nl.count(), i; + QString name, text; + + if (!cnt) { + printDebug("Serializer::extractEntry(): empty"); + return false; + } + dta->clear(); + for (i = 0; i < cnt; ++i) { + cur = nl.item(i); + name = cur.nodeName(); + cdata = cur.firstChild(); + if (unlikely(cdata.isCDATASection())) { + text = cdata.toCDATASection().data(); + } else if (likely(cur.isElement())) { + text = cur.toElement().text(); + } else { + printDebug("Serializer::extractEntry(): neither CDATA nor element."); + return false; + } + if (text == " ") + text = ""; // for backward compatibility. + if (name == ENTRY_DESC_NEW || + name == ENTRY_DESC_OLD) { + dta->desc = unescapeEntryData(text).latin1(); + } else if (name == ENTRY_NAME_NEW || + name == ENTRY_NAME_OLD) { + dta->name = unescapeEntryData(text).latin1(); + } else if (name == ENTRY_PW_NEW || + name == ENTRY_PW_OLD) { + dta->pw = unescapeEntryData(text).latin1(); + } else if (name == ENTRY_COMMENT_NEW || + name == ENTRY_COMMENT_OLD) { + dta->comment = unescapeEntryData(text).latin1(); + } else if (name == ENTRY_URL_NEW || + name == ENTRY_URL_OLD) { + dta->url = unescapeEntryData(text).latin1(); + } else if (name == ENTRY_LAUNCHER_NEW || + name == ENTRY_LAUNCHER_OLD) { + dta->launcher = unescapeEntryData(text).latin1(); + } else if (name == ENTRY_LVP_NEW || + name == ENTRY_LVP_OLD) { + dta->listViewPos = strtol(text.latin1(), 0, 10); + } else if (name == ENTRY_BIN_NEW) { + // ENTRY_BIN_NEW == ENTRY_BIN_OLD + if (text == "0") { + dta->binary = false; + } else { + dta->binary = true; + } + } else if (name == ENTRY_META_NEW) { + // ENTRY_META_NEW == ENTRY_META_OLD + if (!extractMeta(cur, &dta->meta)) + return false; + } else { + printDebug(string("Serializer::extractEntry(): invalid: ") + + name.latin1()); + } + } + dta->lockStat = defaultLockStat; + return true; +} + +bool Serializer::extractMeta(const QDomNode &n, + PwMMetaData *dta) +{ + QDomNode cur(n.firstChild()); + QString name, val; + while (!cur.isNull()) { + name = cur.nodeName(); + val = cur.toElement().text(); + if (val == "") { + cur = cur.nextSibling(); + continue; + } +#ifndef PWM_EMBEDDED + if (name == META_CREATE_DATE) { + dta->create = QDateTime::fromString(val, Qt::ISODate); + } else if (name == META_VALID_DATE) { + dta->valid = QDateTime::fromString(val, Qt::ISODate); + } else if (name == META_EXPIRE_DATE) { + dta->expire = QDateTime::fromString(val, Qt::ISODate); + } else if (name == META_UPDATE_DATE) { + dta->update = QDateTime::fromString(val, Qt::ISODate); + } else if (name == META_UPDATE_INT) { + dta->updateInt = strtoul(val.latin1(), 0, 10); + } else if (name == META_UNIQUEID) { + dta->uniqueid = unescapeEntryData(val).latin1(); + } else { + printDebug(string("extractMeta(): invalid: ") + + name.latin1()); + } +#else + + QDateTime m_dt; + + if ((name == META_CREATE_DATE) || + (name == META_VALID_DATE) || + (name == META_EXPIRE_DATE) || + (name == META_UPDATE_DATE)) + { + int pos = val.find("T"); + QString date = val.left(pos); + QString time = val.mid(pos+1); + qDebug("Serializer::extractMeta : date=%s ,time=%s",date.latin1(), time.latin1() ); + bool ok1, ok2; + + QDate m_date = KGlobal::locale()->readDate(date, &ok1); + QTime m_time = KGlobal::locale()->readTime(time, &ok2); + if ((ok1 == false) || (ok2 == false)) + qDebug("Serializer::extractMeta invalid date or time !!!!!!!!!!!!!"); + m_dt.setDate(m_date); + m_dt.setTime(m_time); + } + + + if (name == META_CREATE_DATE) { + dta->create = m_dt; + } else if (name == META_VALID_DATE) { + dta->valid = m_dt; + } else if (name == META_EXPIRE_DATE) { + dta->expire = m_dt; + } else if (name == META_UPDATE_DATE) { + dta->update = m_dt; + } else if (name == META_UPDATE_INT) { + dta->updateInt = strtoul(val.latin1(), 0, 10); + } else if (name == META_UNIQUEID) { + dta->uniqueid = unescapeEntryData(val).latin1(); + } else { + printDebug(string("extractMeta(): invalid: ") + + name.latin1()); + } +#endif + cur = cur.nextSibling(); + } + return true; +} + +bool Serializer::checkValid() +{ + PWM_ASSERT(domDoc); + QDomElement root(domDoc->documentElement()); + if (root.nodeName() != ROOT_MAGIC_NEW && + root.nodeName() != ROOT_MAGIC_OLD) { + printDebug("Serializer: wrong magic"); + return false; + } + if (root.attribute(VER_STR_NEW) != COMPAT_VER_NEW && + root.attribute(VER_STR_OLD) != COMPAT_VER_OLD) { + printDebug("Serializer: wrong version"); + return false; + } + return true; +} + +QDomElement Serializer::genNewRoot() +{ + PWM_ASSERT(domDoc); + QDomElement root(domDoc->createElement(ROOT_MAGIC_WR)); + root.setAttribute(VER_STR_WR, COMPAT_VER_WR); + domDoc->appendChild(root); + return root; +} + +bool Serializer::addCategories(QDomElement *e, + const vector &dta) +{ + unsigned int numCat = dta.size(), i; + QString curId, curName; + QDomElement curCat; + + for (i = 0; i < numCat; ++i) { + curId = CAT_PREFIX_WR; + curId += tostr(i).c_str(); + curName = dta[i].name.c_str(); + curCat = domDoc->createElement(curId); + curCat.setAttribute(CAT_NAME_WR, curName); + if (!addEntries(&curCat, dta[i].d)) { + return false; + } + e->appendChild(curCat); + } + return true; +} + +bool Serializer::addEntries(QDomElement *e, + const vector &dta) +{ + unsigned int numEntr = dta.size(), i; + QString curId; + QDomElement curEntr; + + for (i = 0; i < numEntr; ++i) { + curId = ENTRY_PREFIX_WR; + curId += tostr(i).c_str(); + curEntr = domDoc->createElement(curId); + if (!writeEntry(&curEntr, dta[i])) { + return false; + } + e->appendChild(curEntr); + } + return true; +} + +bool Serializer::writeEntry(QDomElement *e, + const PwMDataItem &_dta) +{ +#if WRITE_CDATA_SEC != 0 +# define new_text(x) domDoc->createCDATASection(x) + QDomCDATASection curText; +#else +# define new_text(x) domDoc->createTextNode(x) + QDomText curText; +#endif + + QDomText plainText; + QDomElement tag; + + // begin -- This is for compatibility with the old serializer + PwMDataItem dta = _dta; + if (!dta.desc.size()) + dta.desc = " "; + if (!dta.name.size()) + dta.name = " "; + if (!dta.pw.size()) + dta.pw = " "; + if (!dta.comment.size()) + dta.comment = " "; + if (!dta.url.size()) + dta.url = " "; + if (!dta.launcher.size()) + dta.launcher = " "; + // end -- This is for compatibility with the old serializer + + tag = domDoc->createElement(ENTRY_DESC_WR); + curText = new_text(escapeEntryData(dta.desc.c_str())); + tag.appendChild(curText); + e->appendChild(tag); + + tag = domDoc->createElement(ENTRY_NAME_WR); + curText = new_text(escapeEntryData(dta.name.c_str())); + tag.appendChild(curText); + e->appendChild(tag); + + tag = domDoc->createElement(ENTRY_PW_WR); + curText = new_text(escapeEntryData(dta.pw.c_str())); + tag.appendChild(curText); + e->appendChild(tag); + + tag = domDoc->createElement(ENTRY_COMMENT_WR); + curText = new_text(escapeEntryData(dta.comment.c_str())); + tag.appendChild(curText); + e->appendChild(tag); + + tag = domDoc->createElement(ENTRY_URL_WR); + curText = new_text(escapeEntryData(dta.url.c_str())); + tag.appendChild(curText); + e->appendChild(tag); + + tag = domDoc->createElement(ENTRY_LAUNCHER_WR); + curText = new_text(escapeEntryData(dta.launcher.c_str())); + tag.appendChild(curText); + e->appendChild(tag); + + tag = domDoc->createElement(ENTRY_LVP_WR); + plainText = domDoc->createTextNode(tostr(dta.listViewPos).c_str()); + tag.appendChild(plainText); + e->appendChild(tag); + + tag = domDoc->createElement(ENTRY_BIN_WR); + if (dta.binary) + plainText = domDoc->createTextNode("1"); + else + plainText = domDoc->createTextNode("0"); + tag.appendChild(plainText); + e->appendChild(tag); + + tag = domDoc->createElement(ENTRY_META_WR); + if (!writeMeta(&tag, dta.meta)) + return false; + e->appendChild(tag); + +#undef new_text + return true; +} + +bool Serializer::writeMeta(QDomElement *e, + const PwMMetaData &dta) +{ + QDomText text; + QDomElement tag; + + tag = domDoc->createElement(META_CREATE_DATE); +#ifndef PWM_EMBEDDED + text = domDoc->createTextNode(dta.create.toString(Qt::ISODate)); +#else + text = domDoc->createTextNode(KGlobal::locale()->formatDateTime(dta.create, KLocale::ISODate)); +#endif + tag.appendChild(text); + e->appendChild(tag); + + tag = domDoc->createElement(META_VALID_DATE); +#ifndef PWM_EMBEDDED + text = domDoc->createTextNode(dta.valid.toString(Qt::ISODate)); +#else + text = domDoc->createTextNode(KGlobal::locale()->formatDateTime(dta.valid, KLocale::ISODate)); +#endif + tag.appendChild(text); + e->appendChild(tag); + + tag = domDoc->createElement(META_EXPIRE_DATE); +#ifndef PWM_EMBEDDED + text = domDoc->createTextNode(dta.expire.toString(Qt::ISODate)); +#else + text = domDoc->createTextNode(KGlobal::locale()->formatDateTime(dta.expire, KLocale::ISODate)); +#endif + tag.appendChild(text); + e->appendChild(tag); + + tag = domDoc->createElement(META_UPDATE_DATE); +#ifndef PWM_EMBEDDED + text = domDoc->createTextNode(dta.update.toString(Qt::ISODate)); +#else + text = domDoc->createTextNode(KGlobal::locale()->formatDateTime(dta.update, KLocale::ISODate)); +#endif + tag.appendChild(text); + e->appendChild(tag); + + tag = domDoc->createElement(META_UPDATE_INT); + text = domDoc->createTextNode(tostr(dta.updateInt).c_str()); + tag.appendChild(text); + e->appendChild(tag); + + tag = domDoc->createElement(META_UNIQUEID); + text = domDoc->createTextNode(escapeEntryData(dta.uniqueid)); + tag.appendChild(text); + e->appendChild(tag); + +#undef new_text + return true; +} + +QString Serializer::escapeEntryData(QString dta) +{ +#ifndef PWM_EMBEDDED + dta.replace('\n', "$>--endl--<$"); + dta.replace("]]>", "||>"); +#else + dta.replace(QRegExp("\n"), "$>--endl--<$"); + dta.replace(QRegExp("]]>"), "||>"); +#endif + return dta; +} + +QString Serializer::unescapeEntryData(QString dta) +{ +#ifndef PWM_EMBEDDED + dta.replace("$>--endl--<$", "\n"); + dta.replace("||>", "]]>"); +#else + dta.replace(QRegExp("$>--endl--<$"), "\n"); + dta.replace(QRegExp("||>"), "]]>"); +#endif + return dta; +} diff --git a/pwmanager/pwmanager/serializer.h b/pwmanager/pwmanager/serializer.h new file mode 100644 index 0000000..245fcee --- a/dev/null +++ b/pwmanager/pwmanager/serializer.h @@ -0,0 +1,102 @@ +/*************************************************************************** + * * + * 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 2.0 of pwmanager + * and was modified to run on embedded devices that run microkde + * + * $Id$ + **************************************************************************/ + +#ifndef __SERIALIZER_H +#define __SERIALIZER_H + +#include "pwmdoc.h" + +#include +#include + +#include + +using std::vector; + +/** This serializes its input data into + * the PwManager-XML-datastream, that becomes + * encrypted and maybe compressed + */ +class Serializer +{ +public: + /** construct an empty serializer document */ + Serializer(); + /** construct a serializer document and parse "buffer" */ + Serializer(const QCString &buffer); + /** destructor */ + virtual ~Serializer(); + + /** clears all data */ + void clear(); + /** parse the given data buffer */ + bool parseXml(const QCString &buffer); + /** returns the current XML data */ + QCString getXml(); + /** serialize "dta" and store it as XML data */ + bool serialize(const vector &dta); + /** deserialize the (parsed) XML data and store it in "dta" */ + bool deSerialize(vector *dta); + /** sets the initial default lockStat we should assign */ + void setDefaultLockStat(bool stat) + { defaultLockStat = stat; } + +protected: + /** main data holder */ + QDomDocument *domDoc; + /** default lockStat to assign */ + bool defaultLockStat; + +protected: + /** check if this is valid PwManager XML data */ + bool checkValid(); + /** read the categories in the node "n" */ + bool readCategories(const QDomNode &n, + vector *dta); + /** read the entries in the node "n" */ + bool readEntries(const QDomNode &n, + vector *dta); + /** extract the data out of the given item at "n" */ + bool extractEntry(const QDomNode &n, + PwMDataItem *dta); + /** extract the meta-data */ + bool extractMeta(const QDomNode &n, + PwMMetaData *dta); + /** generates a new root node and sets all initial parameters */ + QDomElement genNewRoot(); + /** add new categories to the XML data stream in e */ + bool addCategories(QDomElement *e, + const vector &dta); + /** add the given new entries to the XML data stream in e */ + bool addEntries(QDomElement *e, + const vector &dta); + /** do serialize and write the given entry to the XML stream */ + bool writeEntry(QDomElement *e, + const PwMDataItem &_dta); + /** write the entry meta data to the xml stream */ + bool writeMeta(QDomElement *e, + const PwMMetaData &dta); + /** escape illegal characters out of the given entry data string */ + QString escapeEntryData(QString dta); + /** un-escape illegal characters out of the given entry data string */ + QString unescapeEntryData(QString dta); +}; + +#endif // __SERIALIZER_H diff --git a/pwmanager/pwmanager/setmasterpwwnd.cpp b/pwmanager/pwmanager/setmasterpwwnd.cpp new file mode 100644 index 0000000..c7e0bad --- a/dev/null +++ b/pwmanager/pwmanager/setmasterpwwnd.cpp @@ -0,0 +1,150 @@ +/**************************************************************************** +** Form implementation generated from reading ui file 'setmasterpwwnd.ui' +** +** Created: Tue Sep 14 15:43:34 2004 +** by: The User Interface Compiler ($Id$) +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ + +#include "setmasterpwwnd.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Constructs a setMasterPwWnd as a child of 'parent', with the + * name 'name' and widget flags set to 'f'. + * + * The dialog will by default be modeless, unless you set 'modal' to + * TRUE to construct a modal dialog. + */ +setMasterPwWnd::setMasterPwWnd( QWidget* parent, const char* name, bool modal, WFlags fl ) + : QDialog( parent, name, modal, fl ) +{ + if ( !name ) + setName( "setMasterPwWnd" ); + + okButton = new QPushButton( this, "okButton" ); + okButton->setGeometry( QRect( 10, 280, 107, 27 ) ); + + cancelButton = new QPushButton( this, "cancelButton" ); + cancelButton->setGeometry( QRect( 290, 280, 107, 27 ) ); + + mainTab = new QTabWidget( this, "mainTab" ); + mainTab->setGeometry( QRect( 10, 10, 390, 260 ) ); + + tab = new QWidget( mainTab, "tab" ); + + textLabel2 = new QLabel( tab, "textLabel2" ); + textLabel2->setGeometry( QRect( 20, 90, 340, 20 ) ); + + textLabel3 = new QLabel( tab, "textLabel3" ); + textLabel3->setGeometry( QRect( 20, 160, 340, 20 ) ); + + textLabel1 = new QLabel( tab, "textLabel1" ); + textLabel1->setGeometry( QRect( 10, 20, 370, 40 ) ); + textLabel1->setFrameShape( QLabel::Box ); + textLabel1->setAlignment( int( QLabel::WordBreak | QLabel::AlignCenter ) ); + + pwEdit_1 = new QLineEdit( tab, "pwEdit_1" ); + pwEdit_1->setGeometry( QRect( 20, 120, 340, 20 ) ); + pwEdit_1->setEchoMode( QLineEdit::Password ); + + pwEdit_2 = new QLineEdit( tab, "pwEdit_2" ); + pwEdit_2->setGeometry( QRect( 20, 190, 340, 20 ) ); + pwEdit_2->setEchoMode( QLineEdit::Password ); + mainTab->insertTab( tab, QString("") ); + + tab_2 = new QWidget( mainTab, "tab_2" ); + + textLabel1_2 = new QLabel( tab_2, "textLabel1_2" ); + textLabel1_2->setGeometry( QRect( 10, 20, 370, 40 ) ); + textLabel1_2->setFrameShape( QLabel::Box ); + textLabel1_2->setAlignment( int( QLabel::WordBreak | QLabel::AlignCenter ) ); + + textLabel2_2 = new QLabel( tab_2, "textLabel2_2" ); + textLabel2_2->setGeometry( QRect( 20, 190, 170, 20 ) ); + textLabel2_2->setAlignment( int( QLabel::AlignVCenter | QLabel::AlignRight ) ); + + selCardButton = new QPushButton( tab_2, "selCardButton" ); + selCardButton->setGeometry( QRect( 20, 130, 350, 40 ) ); + + genCardButton = new QPushButton( tab_2, "genCardButton" ); + genCardButton->setGeometry( QRect( 80, 90, 230, 28 ) ); + + curCardIdLabel = new QLabel( tab_2, "curCardIdLabel" ); + curCardIdLabel->setGeometry( QRect( 200, 190, 170, 20 ) ); + mainTab->insertTab( tab_2, QString("") ); + languageChange(); + resize( QSize(411, 313).expandedTo(minimumSizeHint()) ); + clearWState( WState_Polished ); + + // signals and slots connections + connect( okButton, SIGNAL( clicked() ), this, SLOT( okButton_slot() ) ); + connect( cancelButton, SIGNAL( clicked() ), this, SLOT( cancelButton_slot() ) ); + connect( genCardButton, SIGNAL( clicked() ), this, SLOT( genCardButton_slot() ) ); + connect( selCardButton, SIGNAL( clicked() ), this, SLOT( selCardButton_slot() ) ); + + // tab order + setTabOrder( pwEdit_1, pwEdit_2 ); + setTabOrder( pwEdit_2, okButton ); + setTabOrder( okButton, cancelButton ); +} + +/* + * Destroys the object and frees any allocated resources + */ +setMasterPwWnd::~setMasterPwWnd() +{ + // no need to delete child widgets, Qt does it all for us +} + +/* + * Sets the strings of the subwidgets using the current + * language. + */ +void setMasterPwWnd::languageChange() +{ + setCaption( tr( "Set master-password" ) ); + okButton->setText( tr( "&OK" ) ); + cancelButton->setText( tr( "&Cancel" ) ); + textLabel2->setText( tr( "Please enter the new master-password:" ) ); + textLabel3->setText( tr( "Please enter the password again:" ) ); + textLabel1->setText( tr( "Using a normal password-string to encrypt the data." ) ); + mainTab->changeTab( tab, tr( "Normal password" ) ); + textLabel1_2->setText( tr( "Using a PwM key-card to encrypt the data." ) ); + textLabel2_2->setText( tr( "selected card:" ) ); + selCardButton->setText( tr( "&Select the currently inserted card as key-card" ) ); + genCardButton->setText( tr( "&generate new key-card" ) ); + curCardIdLabel->setText( QString::null ); + mainTab->changeTab( tab_2, tr( "Key-card (chipcard)" ) ); +} + +void setMasterPwWnd::okButton_slot() +{ + qWarning( "setMasterPwWnd::okButton_slot(): Not implemented yet" ); +} + +void setMasterPwWnd::cancelButton_slot() +{ + qWarning( "setMasterPwWnd::cancelButton_slot(): Not implemented yet" ); +} + +void setMasterPwWnd::genCardButton_slot() +{ + qWarning( "setMasterPwWnd::genCardButton_slot(): Not implemented yet" ); +} + +void setMasterPwWnd::selCardButton_slot() +{ + qWarning( "setMasterPwWnd::selCardButton_slot(): Not implemented yet" ); +} + diff --git a/pwmanager/pwmanager/setmasterpwwnd.h b/pwmanager/pwmanager/setmasterpwwnd.h new file mode 100644 index 0000000..c0b1a27 --- a/dev/null +++ b/pwmanager/pwmanager/setmasterpwwnd.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** Form interface generated from reading ui file 'setmasterpwwnd.ui' +** +** Created: Tue Sep 14 15:32:37 2004 +** by: The User Interface Compiler ($Id$) +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ + +#ifndef SETMASTERPWWND_H +#define SETMASTERPWWND_H + +#include +#include + +class QVBoxLayout; +class QHBoxLayout; +class QGridLayout; +class QSpacerItem; +class QPushButton; +class QTabWidget; +class QWidget; +class QLabel; +class QLineEdit; + +class setMasterPwWnd : public QDialog +{ + Q_OBJECT + +public: + setMasterPwWnd( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~setMasterPwWnd(); + + QPushButton* okButton; + QPushButton* cancelButton; + QTabWidget* mainTab; + QWidget* tab; + QLabel* textLabel2; + QLabel* textLabel3; + QLabel* textLabel1; + QLineEdit* pwEdit_1; + QLineEdit* pwEdit_2; + QWidget* tab_2; + QLabel* textLabel1_2; + QLabel* textLabel2_2; + QPushButton* selCardButton; + QPushButton* genCardButton; + QLabel* curCardIdLabel; + +public slots: + virtual void okButton_slot(); + virtual void cancelButton_slot(); + virtual void genCardButton_slot(); + virtual void selCardButton_slot(); + +protected: + +protected slots: + virtual void languageChange(); + +}; + +#endif // SETMASTERPWWND_H diff --git a/pwmanager/pwmanager/setmasterpwwnd.ui b/pwmanager/pwmanager/setmasterpwwnd.ui new file mode 100644 index 0000000..4f6cd5d --- a/dev/null +++ b/pwmanager/pwmanager/setmasterpwwnd.ui @@ -0,0 +1,294 @@ + +setMasterPwWnd + + + setMasterPwWnd + + + + 0 + 0 + 411 + 313 + + + + Set master-password + + + + okButton + + + + 10 + 280 + 107 + 27 + + + + &OK + + + + + cancelButton + + + + 290 + 280 + 107 + 27 + + + + &Cancel + + + + + mainTab + + + + 10 + 10 + 390 + 260 + + + + + tab + + + Normal password + + + + textLabel2 + + + + 20 + 90 + 340 + 20 + + + + Please enter the new master-password: + + + + + textLabel3 + + + + 20 + 160 + 340 + 20 + + + + Please enter the password again: + + + + + textLabel1 + + + + 10 + 20 + 370 + 40 + + + + Box + + + Using a normal password-string to encrypt the data. + + + WordBreak|AlignCenter + + + + + pwEdit_1 + + + + 20 + 120 + 340 + 20 + + + + Password + + + + + pwEdit_2 + + + + 20 + 190 + 340 + 20 + + + + Password + + + + + + tab + + + Key-card (chipcard) + + + + textLabel1_2 + + + + 10 + 20 + 370 + 40 + + + + Box + + + Using a PwM key-card to encrypt the data. + + + WordBreak|AlignCenter + + + + + textLabel2_2 + + + + 20 + 190 + 170 + 20 + + + + selected card: + + + AlignVCenter|AlignRight + + + + + selCardButton + + + + 20 + 130 + 350 + 40 + + + + &Select the currently inserted card as key-card + + + + + genCardButton + + + + 80 + 90 + 230 + 28 + + + + &generate new key-card + + + + + curCardIdLabel + + + + 200 + 190 + 170 + 20 + + + + + + + + + + + + okButton + clicked() + setMasterPwWnd + okButton_slot() + + + cancelButton + clicked() + setMasterPwWnd + cancelButton_slot() + + + genCardButton + clicked() + setMasterPwWnd + genCardButton_slot() + + + selCardButton + clicked() + setMasterPwWnd + selCardButton_slot() + + + + pwEdit_1 + pwEdit_2 + okButton + cancelButton + + + okButton_slot() + cancelButton_slot() + genCardButton_slot() + selCardButton_slot() + + + diff --git a/pwmanager/pwmanager/setmasterpwwndimpl.cpp b/pwmanager/pwmanager/setmasterpwwndimpl.cpp new file mode 100644 index 0000000..aac0408 --- a/dev/null +++ b/pwmanager/pwmanager/setmasterpwwndimpl.cpp @@ -0,0 +1,152 @@ +/*************************************************************************** + * * + * 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$ + **************************************************************************/ + +#include "setmasterpwwndimpl.h" +#include "pwm.h" +#include "globalstuff.h" + +#include + +#include +#include +#include + +#include + +#ifdef CONFIG_KEYCARD +# include "pwmkeycard.h" +#endif + +#define STRING_CARD_NONE (SetMasterPwWndImpl::string_cardNone()) + + +SetMasterPwWndImpl::SetMasterPwWndImpl(QWidget * parent, const char *name) +: setMasterPwWnd(parent, name) +{ +#ifdef CONFIG_KEYCARD + curCardIdLabel->setText(STRING_CARD_NONE); +#else // CONFIG_KEYCARD +#ifndef PWM_EMBEDDED + mainTab->removePage(mainTab->page(1)); +#else + qDebug("SetMasterPwWndImpl::SetMasterPwWndImpl has to be fixed"); +#endif +#endif // CONFIG_KEYCARD + keyCard = 0; +} + +SetMasterPwWndImpl::~SetMasterPwWndImpl() +{ +} + +void SetMasterPwWndImpl::okButton_slot() +{ + int index = mainTab->currentPageIndex(); + if (index == 0) { + // normal password + if (pwEdit_1->text() != pwEdit_2->text()) { + KMessageBox::error(this, + i18n + ("The two passwords you have entered don't match.\n" + "Please try entering them again."), + i18n("Different passwords")); + return; + } + if (pwEdit_1->text() == "") { + KMessageBox::error(this, + i18n("No password entered. " + "Please type in a password, that " + "you want to use for the encryption."), + i18n("no password")); + return; + } + } else { + // key-card + if (curCardIdLabel->text() == STRING_CARD_NONE) { + KMessageBox::error(this, + i18n("You didn't select a card as " + "PwM-key-card."), + i18n("no card")); + return; + } + } + done(1); +} + +void SetMasterPwWndImpl::cancelButton_slot() +{ + done(2); +} + +void SetMasterPwWndImpl::genCardButton_slot() +{ +#ifdef CONFIG_KEYCARD + PWM_ASSERT(keyCard); + keyCard->genNewCard(); +#endif // CONFIG_KEYCARD +} + +void SetMasterPwWndImpl::selCardButton_slot() +{ +#ifdef CONFIG_KEYCARD + PWM_ASSERT(keyCard); + connect(keyCard, SIGNAL(keyAvailable(uint32_t, const string &)), + this, SLOT(keyAvailable_slot(uint32_t, const string &))); + keyCard->getKey(); +#endif // CONFIG_KEYCARD +} + +void SetMasterPwWndImpl::keyAvailable_slot(uint32_t cardId, + const string &key) +{ + if (key == "") + return; + curCardKey = key; + char id_buf[(sizeof(cardId) * 2) + 2 /* "0x" */ + 1 /* NULL */]; + memcpy(id_buf, "0x", 2); + sprintf(id_buf + 2, "%X", cardId); + curCardIdLabel->setText(id_buf); +} + +string SetMasterPwWndImpl::getPw(bool *useCard) +{ + int index = mainTab->currentPageIndex(); + if (index == 0) { + // normal password + if (useCard) + *useCard = false; + PWM_ASSERT(pwEdit_1->text() == pwEdit_2->text()); + return pwEdit_1->text().latin1(); + } else { +#ifdef CONFIG_KEYCARD + // key-card + if (useCard) + *useCard = true; + PWM_ASSERT(curCardKey != ""); + PWM_ASSERT(curCardIdLabel->text() != STRING_CARD_NONE); + return curCardKey; +#endif // CONFIG_KEYCARD + } + return ""; +} + +#ifndef PWM_EMBEDDED +#include "setmasterpwwndimpl.moc" +#endif diff --git a/pwmanager/pwmanager/setmasterpwwndimpl.h b/pwmanager/pwmanager/setmasterpwwndimpl.h new file mode 100644 index 0000000..56effc1 --- a/dev/null +++ b/pwmanager/pwmanager/setmasterpwwndimpl.h @@ -0,0 +1,72 @@ +/*************************************************************************** + * * + * copyright (C) 2003 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 SETMASTERPWWNDIMPL_H +#define SETMASTERPWWNDIMPL_H + +#include "setmasterpwwnd.h" + +#include + +#include +#include +using std::string; + +class PwMKeyCard; + +/** set master pw wnd */ +class SetMasterPwWndImpl : public setMasterPwWnd +{ + Q_OBJECT +public: + SetMasterPwWndImpl(QWidget* parent = 0, const char *name = 0); + ~SetMasterPwWndImpl(); + + static QString string_cardNone() + { return i18n("NONE"); } + + /** returns the selected pw (or the key on the card) */ + string getPw(bool *useCard); + /** set pointer to the keycard-access object */ + void setPwMKeyCard(PwMKeyCard *_keyCard) + { keyCard = _keyCard; } + +public slots: + /** ok button pressed */ + void okButton_slot(); + /** cancel button pressed */ + void cancelButton_slot(); + /** "generate a new card" button pressed */ + void genCardButton_slot(); + /** "select current card" button pressed */ + void selCardButton_slot(); + +protected slots: + /** key from PwMKeyCard is available */ + void keyAvailable_slot(uint32_t cardId, const string &key); + +protected: + /** key of currently inserted card */ + string curCardKey; + /** pointer to the keycard-access object */ + PwMKeyCard *keyCard; +}; + +#endif diff --git a/pwmanager/pwmanager/sha1.cpp b/pwmanager/pwmanager/sha1.cpp new file mode 100644 index 0000000..b2eeb4d --- a/dev/null +++ b/pwmanager/pwmanager/sha1.cpp @@ -0,0 +1,355 @@ +/* 2003.05.02: Derived from libgcrypt-1.1.12 by Michael Buesch */ + +/* sha1.c - SHA1 hash function + * Copyright (C) 1998, 2001, 2002 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + */ + +/* Test vectors: + * + * "abc" + * A999 3E36 4706 816A BA3E 2571 7850 C26C 9CD0 D89D + * + * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + * 8498 3E44 1C3B D26E BAAE 4AA1 F951 29E5 E546 70F1 + */ + +/*************************************************************************** + * 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 "sha1.h" +#include "pwmexception.h" + +#include +#include + + +void Sha1::burn_stack(int bytes) +{ + char buf[128]; + + memset(buf, 0, sizeof buf); + bytes -= sizeof buf; + if (bytes > 0) + burn_stack(bytes); +} + +void Sha1::sha1_init() +{ + ctx.h0 = 0x67452301; + ctx.h1 = 0xefcdab89; + ctx.h2 = 0x98badcfe; + ctx.h3 = 0x10325476; + ctx.h4 = 0xc3d2e1f0; + ctx.nblocks = 0; + ctx.count = 0; +} + +/**************** + * Transform the message X which consists of 16 32-bit-words + */ +void Sha1::transform(const byte *data) +{ + register uint32_t a, b, c, d, e, tm; + uint32_t x[16]; + + /* get values from the chaining vars */ + a = ctx.h0; + b = ctx.h1; + c = ctx.h2; + d = ctx.h3; + e = ctx.h4; + +#ifdef BIG_ENDIAN_HOST + memcpy(x, data, 64); +#else + { + int i; + byte *p2; + for (i = 0, p2 = (byte *) x; i < 16; i++, p2 += 4) { + p2[3] = *data++; + p2[2] = *data++; + p2[1] = *data++; + p2[0] = *data++; + } + } +#endif + +#define K1 0x5A827999L +#define K2 0x6ED9EBA1L +#define K3 0x8F1BBCDCL +#define K4 0xCA62C1D6L +#define F1(x,y,z) ( z ^ ( x & ( y ^ z ) ) ) +#define F2(x,y,z) ( x ^ y ^ z ) +#define F3(x,y,z) ( ( x & y ) | ( z & ( x | y ) ) ) +#define F4(x,y,z) ( x ^ y ^ z ) + +#define M(i) ( tm = x[i&0x0f] ^ x[(i-14)&0x0f] \ + ^ x[(i-8)&0x0f] ^ x[(i-3)&0x0f] \ + , (x[i&0x0f] = rol(tm, 1)) ) + +#define R(a,b,c,d,e,f,k,m) do { e += rol( a, 5 ) \ + + f( b, c, d ) \ + + k \ + + m; \ + b = rol( b, 30 ); \ + } while(0) + R(a, b, c, d, e, F1, K1, x[0]); + R(e, a, b, c, d, F1, K1, x[1]); + R(d, e, a, b, c, F1, K1, x[2]); + R(c, d, e, a, b, F1, K1, x[3]); + R(b, c, d, e, a, F1, K1, x[4]); + R(a, b, c, d, e, F1, K1, x[5]); + R(e, a, b, c, d, F1, K1, x[6]); + R(d, e, a, b, c, F1, K1, x[7]); + R(c, d, e, a, b, F1, K1, x[8]); + R(b, c, d, e, a, F1, K1, x[9]); + R(a, b, c, d, e, F1, K1, x[10]); + R(e, a, b, c, d, F1, K1, x[11]); + R(d, e, a, b, c, F1, K1, x[12]); + R(c, d, e, a, b, F1, K1, x[13]); + R(b, c, d, e, a, F1, K1, x[14]); + R(a, b, c, d, e, F1, K1, x[15]); + R(e, a, b, c, d, F1, K1, M(16)); + R(d, e, a, b, c, F1, K1, M(17)); + R(c, d, e, a, b, F1, K1, M(18)); + R(b, c, d, e, a, F1, K1, M(19)); + R(a, b, c, d, e, F2, K2, M(20)); + R(e, a, b, c, d, F2, K2, M(21)); + R(d, e, a, b, c, F2, K2, M(22)); + R(c, d, e, a, b, F2, K2, M(23)); + R(b, c, d, e, a, F2, K2, M(24)); + R(a, b, c, d, e, F2, K2, M(25)); + R(e, a, b, c, d, F2, K2, M(26)); + R(d, e, a, b, c, F2, K2, M(27)); + R(c, d, e, a, b, F2, K2, M(28)); + R(b, c, d, e, a, F2, K2, M(29)); + R(a, b, c, d, e, F2, K2, M(30)); + R(e, a, b, c, d, F2, K2, M(31)); + R(d, e, a, b, c, F2, K2, M(32)); + R(c, d, e, a, b, F2, K2, M(33)); + R(b, c, d, e, a, F2, K2, M(34)); + R(a, b, c, d, e, F2, K2, M(35)); + R(e, a, b, c, d, F2, K2, M(36)); + R(d, e, a, b, c, F2, K2, M(37)); + R(c, d, e, a, b, F2, K2, M(38)); + R(b, c, d, e, a, F2, K2, M(39)); + R(a, b, c, d, e, F3, K3, M(40)); + R(e, a, b, c, d, F3, K3, M(41)); + R(d, e, a, b, c, F3, K3, M(42)); + R(c, d, e, a, b, F3, K3, M(43)); + R(b, c, d, e, a, F3, K3, M(44)); + R(a, b, c, d, e, F3, K3, M(45)); + R(e, a, b, c, d, F3, K3, M(46)); + R(d, e, a, b, c, F3, K3, M(47)); + R(c, d, e, a, b, F3, K3, M(48)); + R(b, c, d, e, a, F3, K3, M(49)); + R(a, b, c, d, e, F3, K3, M(50)); + R(e, a, b, c, d, F3, K3, M(51)); + R(d, e, a, b, c, F3, K3, M(52)); + R(c, d, e, a, b, F3, K3, M(53)); + R(b, c, d, e, a, F3, K3, M(54)); + R(a, b, c, d, e, F3, K3, M(55)); + R(e, a, b, c, d, F3, K3, M(56)); + R(d, e, a, b, c, F3, K3, M(57)); + R(c, d, e, a, b, F3, K3, M(58)); + R(b, c, d, e, a, F3, K3, M(59)); + R(a, b, c, d, e, F4, K4, M(60)); + R(e, a, b, c, d, F4, K4, M(61)); + R(d, e, a, b, c, F4, K4, M(62)); + R(c, d, e, a, b, F4, K4, M(63)); + R(b, c, d, e, a, F4, K4, M(64)); + R(a, b, c, d, e, F4, K4, M(65)); + R(e, a, b, c, d, F4, K4, M(66)); + R(d, e, a, b, c, F4, K4, M(67)); + R(c, d, e, a, b, F4, K4, M(68)); + R(b, c, d, e, a, F4, K4, M(69)); + R(a, b, c, d, e, F4, K4, M(70)); + R(e, a, b, c, d, F4, K4, M(71)); + R(d, e, a, b, c, F4, K4, M(72)); + R(c, d, e, a, b, F4, K4, M(73)); + R(b, c, d, e, a, F4, K4, M(74)); + R(a, b, c, d, e, F4, K4, M(75)); + R(e, a, b, c, d, F4, K4, M(76)); + R(d, e, a, b, c, F4, K4, M(77)); + R(c, d, e, a, b, F4, K4, M(78)); + R(b, c, d, e, a, F4, K4, M(79)); + + /* update chainig vars */ + ctx.h0 += a; + ctx.h1 += b; + ctx.h2 += c; + ctx.h3 += d; + ctx.h4 += e; +#undef K1 +#undef K2 +#undef K3 +#undef K4 +#undef F1 +#undef F2 +#undef F3 +#undef F4 +#undef M +#undef R +} + +/* Update the message digest with the contents + * of INBUF with length INLEN. + */ +void Sha1::sha1_write(const byte * inbuf, uint32_t inlen) +{ + if (ctx.count == 64) { /* flush the buffer */ + transform(ctx.buf); + burn_stack(88 + 4 * sizeof(void *)); + ctx.count = 0; + ctx.nblocks++; + } + if (!inbuf) + return; + if (ctx.count) { + for (; inlen && ctx.count < 64; inlen--) + ctx.buf[ctx.count++] = *inbuf++; + sha1_write(NULL, 0); + if (!inlen) + return; + } + + while (inlen >= 64) { + transform(inbuf); + ctx.count = 0; + ctx.nblocks++; + inlen -= 64; + inbuf += 64; + } + burn_stack(88 + 4 * sizeof(void *)); + for (; inlen && ctx.count < 64; inlen--) + ctx.buf[ctx.count++] = *inbuf++; +} + +/* The routine final terminates the computation and + * returns the digest. + * The handle is prepared for a new cycle, but adding bytes to the + * handle will the destroy the returned buffer. + * Returns: 20 bytes representing the digest. + */ + +void Sha1::sha1_final() +{ + uint32_t t, msb, lsb; + byte *p; + + sha1_write(NULL, 0); /* flush */ ; + + t = ctx.nblocks; + /* multiply by 64 to make a byte count */ + lsb = t << 6; + msb = t >> 26; + /* add the count */ + t = lsb; + if ((lsb += ctx.count) < t) + msb++; + /* multiply by 8 to make a bit count */ + t = lsb; + lsb <<= 3; + msb <<= 3; + msb |= t >> 29; + + if (ctx.count < 56) { /* enough room */ + ctx.buf[ctx.count++] = 0x80; /* pad */ + while (ctx.count < 56) + ctx.buf[ctx.count++] = 0; /* pad */ + } else { /* need one extra block */ + ctx.buf[ctx.count++] = 0x80; /* pad character */ + while (ctx.count < 64) + ctx.buf[ctx.count++] = 0; + sha1_write(NULL, 0); /* flush */ ; + memset(ctx.buf, 0, 56); /* fill next block with zeroes */ + } + /* append the 64 bit count */ + ctx.buf[56] = msb >> 24; + ctx.buf[57] = msb >> 16; + ctx.buf[58] = msb >> 8; + ctx.buf[59] = msb; + ctx.buf[60] = lsb >> 24; + ctx.buf[61] = lsb >> 16; + ctx.buf[62] = lsb >> 8; + ctx.buf[63] = lsb; + transform(ctx.buf); + burn_stack(88 + 4 * sizeof(void *)); + + p = ctx.buf; +#ifdef BIG_ENDIAN_HOST +#define X(a) do { *(uint32_t*)p = ctx.h##a ; p += 4; } while(0) +#else /* little endian */ +#define X(a) do { *p++ = ctx.h##a >> 24; *p++ = ctx.h##a >> 16; \ + *p++ = ctx.h##a >> 8; *p++ = ctx.h##a; } while(0) +#endif + X(0); + X(1); + X(2); + X(3); + X(4); +#undef X + +} + +string Sha1::sha1_read() +{ + sha1_final(); + string ret; + ret.assign((const char*)ctx.buf, SHA1_HASH_LEN_BYTE); + sha1_init(); + return ret; +} + +bool Sha1::selfTest() +{ + const char test1[] = { 'a', 'b', 'c' }; + const uint32_t test1_len = array_size(test1); + const char test1_md[] = { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E, + 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D }; + const char test2[] = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; + const uint32_t test2_len = array_size(test2) - 1; + const char test2_md[] = { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE, + 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 }; + const uint32_t test3_len = 640; + const char test3_single[] = { '0', '1', '2', '3', '4', '5', '6', '7' }; + const uint32_t test3_single_len = array_size(test3_single); + char test3[test3_len]; + uint32_t i; + for (i = 0; i < test3_len / test3_single_len; ++i) + memcpy(test3 + (i * test3_single_len), test3_single, test3_single_len); + const char test3_md[] = { 0xDE, 0xA3, 0x56, 0xA2, 0xCD, 0xDD, 0x90, 0xC7, 0xA7, 0xEC, + 0xED, 0xC5, 0xEB, 0xB5, 0x63, 0x93, 0x4F, 0x46, 0x04, 0x52 }; + Sha1 sha1; + sha1.sha1_write(reinterpret_cast(test1), test1_len); + if (unlikely(memcmp(sha1.sha1_read().c_str(), test1_md, SHA1_HASH_LEN_BYTE))) + return false; + sha1.sha1_write(reinterpret_cast(test2), test2_len); + if (unlikely(memcmp(sha1.sha1_read().c_str(), test2_md, SHA1_HASH_LEN_BYTE))) + return false; + sha1.sha1_write(reinterpret_cast(test3), test3_len); + if (unlikely(memcmp(sha1.sha1_read().c_str(), test3_md, SHA1_HASH_LEN_BYTE))) + return false; + return true; +} diff --git a/pwmanager/pwmanager/sha1.h b/pwmanager/pwmanager/sha1.h new file mode 100644 index 0000000..29442a7 --- a/dev/null +++ b/pwmanager/pwmanager/sha1.h @@ -0,0 +1,75 @@ +/*************************************************************************** + * * + * copyright (C) 2003 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 SHA1_H +#define SHA1_H + +#include +#include +using std::string; + +typedef uint8_t byte; + +#define SHA1_HASH_LEN_BIT 160 +#define SHA1_HASH_LEN_BYTE (SHA1_HASH_LEN_BIT / 8) + +/** sha1 hash algorithm. + * Derived from libgcrypt-1.1.12 + */ +class Sha1 +{ + struct SHA1_CONTEXT + { + uint32_t h0,h1,h2,h3,h4; + uint32_t nblocks; + byte buf[64]; + int count; + }; + +public: + Sha1() { sha1_init(); } + static bool selfTest(); + + void sha1_write(const byte *inbuf, uint32_t inlen); + string sha1_read(); + +protected: + void sha1_init(); + void sha1_final(); + void burn_stack (int bytes); + void transform(const byte *data); + + /** Rotate a 32 bit integer by n bytes */ + uint32_t rol(uint32_t x, int n) + { +#if defined(__GNUC__) && defined(__i386__) + __asm__("roll %%cl,%0" + :"=r" (x) + :"0" (x),"c" (n)); + return x; +#else + return ((x) << (n)) | ((x) >> (32-(n))); +#endif + } + +protected: + struct SHA1_CONTEXT ctx; +}; + +#endif diff --git a/pwmanager/pwmanager/spinforsignal.cpp b/pwmanager/pwmanager/spinforsignal.cpp new file mode 100644 index 0000000..0401d43 --- a/dev/null +++ b/pwmanager/pwmanager/spinforsignal.cpp @@ -0,0 +1,91 @@ +/*************************************************************************** + * * + * 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$ + **************************************************************************/ + +#include "spinforsignal.h" +#include "pwmexception.h" + +#ifndef PWM_EMBEDDED +#include +#endif + +#include +#include + +static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + + +SpinForSignal::SpinForSignal() + : QObject() +{ + doSpin = false; +} + +void SpinForSignal::spinSleep() +{ + const struct timespec t = { 0, 100 }; + nanosleep(&t, 0); +} + +void SpinForSignal::_spin() +{ + doSpin = true; + printDebug("spinning for signal."); + do { + kapp->processEvents(); + spinSleep(); + } while (doSpin); + printDebug("spinning stopped."); +} + +void SpinForSignal::spin(uint32_t *u32, string *str) +{ + _spin(); + if (pthread_mutex_lock(&mutex)) { + printError("spin(uint32_t *u32, string *str): pthread_mutex_lock failed"); + return; + } + *u32 = u32_storage; + *str = str_storage; + pthread_mutex_unlock(&mutex); +} + +void SpinForSignal::u32_str_slot(uint32_t u32, const string &str) +{ + if (doSpin) { + printDebug("ul_str_slot(unsigned long ul, const string &str)"); + u32_storage = u32; + str_storage = str; + doSpin = false; + } +} + +void SpinForSignal::cancelSpin() +{ + if (pthread_mutex_lock(&mutex)) { + printError("cancelSpin(): pthread_mutex_lock failed"); + return; + } + printDebug("spinning cancelled."); + u32_storage = 0; + str_storage = ""; + doSpin = false; + pthread_mutex_unlock(&mutex); +} + +#include "spinforsignal.moc" diff --git a/pwmanager/pwmanager/spinforsignal.h b/pwmanager/pwmanager/spinforsignal.h new file mode 100644 index 0000000..ec6103b --- a/dev/null +++ b/pwmanager/pwmanager/spinforsignal.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * * + * 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 + +#include +#include +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 diff --git a/pwmanager/pwmanager/subtbledit.cpp b/pwmanager/pwmanager/subtbledit.cpp new file mode 100644 index 0000000..e4d805c --- a/dev/null +++ b/pwmanager/pwmanager/subtbledit.cpp @@ -0,0 +1,140 @@ +/**************************************************************************** +** Form implementation generated from reading ui file 'subtbledit.ui' +** +** Created: Tue Sep 14 15:44:17 2004 +** by: The User Interface Compiler ($Id$) +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ + +#include "subtbledit.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Constructs a subTblEdit as a child of 'parent', with the + * name 'name' and widget flags set to 'f'. + * + * The dialog will by default be modeless, unless you set 'modal' to + * TRUE to construct a modal dialog. + */ +subTblEdit::subTblEdit( QWidget* parent, const char* name, bool modal, WFlags fl ) + : QDialog( parent, name, modal, fl ) +{ + if ( !name ) + setName( "subTblEdit" ); + + textLabel4 = new QLabel( this, "textLabel4" ); + textLabel4->setGeometry( QRect( 20, 10, 310, 20 ) ); + textLabel4->setAlignment( int( QLabel::AlignCenter ) ); + + textLabel5 = new QLabel( this, "textLabel5" ); + textLabel5->setGeometry( QRect( 20, 70, 310, 20 ) ); + textLabel5->setAlignment( int( QLabel::AlignCenter ) ); + + titleLineEdit = new QLineEdit( this, "titleLineEdit" ); + titleLineEdit->setGeometry( QRect( 20, 30, 310, 26 ) ); + + okButton = new QPushButton( this, "okButton" ); + okButton->setGeometry( QRect( 20, 420, 140, 31 ) ); + + cancelButton = new QPushButton( this, "cancelButton" ); + cancelButton->setGeometry( QRect( 190, 420, 140, 31 ) ); + + groupBox3 = new QGroupBox( this, "groupBox3" ); + groupBox3->setGeometry( QRect( 20, 210, 310, 200 ) ); + + textLabel6 = new QLabel( groupBox3, "textLabel6" ); + textLabel6->setGeometry( QRect( 20, 30, 270, 20 ) ); + + textLabel7 = new QLabel( groupBox3, "textLabel7" ); + textLabel7->setGeometry( QRect( 20, 90, 270, 20 ) ); + + addButton = new QPushButton( groupBox3, "addButton" ); + addButton->setGeometry( QRect( 30, 150, 250, 31 ) ); + + valueLineEdit = new QLineEdit( groupBox3, "valueLineEdit" ); + valueLineEdit->setGeometry( QRect( 20, 110, 270, 26 ) ); + + nameLineEdit = new QLineEdit( groupBox3, "nameLineEdit" ); + nameLineEdit->setGeometry( QRect( 20, 50, 270, 26 ) ); + + entryListBox = new QListBox( this, "entryListBox" ); + entryListBox->setGeometry( QRect( 20, 90, 310, 80 ) ); + + delButton = new QPushButton( this, "delButton" ); + delButton->setGeometry( QRect( 110, 170, 130, 31 ) ); + languageChange(); + resize( QSize(351, 464).expandedTo(minimumSizeHint()) ); + clearWState( WState_Polished ); + + // signals and slots connections + connect( okButton, SIGNAL( clicked() ), this, SLOT( okButton_slot() ) ); + connect( cancelButton, SIGNAL( clicked() ), this, SLOT( cancelButton_slot() ) ); + connect( addButton, SIGNAL( clicked() ), this, SLOT( addButton_slot() ) ); + connect( delButton, SIGNAL( clicked() ), this, SLOT( delButton_slot() ) ); + + // tab order + setTabOrder( titleLineEdit, entryListBox ); + setTabOrder( entryListBox, delButton ); + setTabOrder( delButton, nameLineEdit ); + setTabOrder( nameLineEdit, valueLineEdit ); + setTabOrder( valueLineEdit, addButton ); + setTabOrder( addButton, okButton ); + setTabOrder( okButton, cancelButton ); +} + +/* + * Destroys the object and frees any allocated resources + */ +subTblEdit::~subTblEdit() +{ + // no need to delete child widgets, Qt does it all for us +} + +/* + * Sets the strings of the subwidgets using the current + * language. + */ +void subTblEdit::languageChange() +{ + setCaption( tr( "HTML-comment subtable editor" ) ); + textLabel4->setText( tr( "Sub-title:" ) ); + textLabel5->setText( tr( "Current subtable-entries:" ) ); + okButton->setText( tr( "&OK" ) ); + cancelButton->setText( tr( "&Cancel" ) ); + groupBox3->setTitle( tr( "New entry" ) ); + textLabel6->setText( tr( "Entry name:" ) ); + textLabel7->setText( tr( "Entry value:" ) ); + addButton->setText( tr( "Add..." ) ); + delButton->setText( tr( "Delete" ) ); +} + +void subTblEdit::okButton_slot() +{ + qWarning( "subTblEdit::okButton_slot(): Not implemented yet" ); +} + +void subTblEdit::cancelButton_slot() +{ + qWarning( "subTblEdit::cancelButton_slot(): Not implemented yet" ); +} + +void subTblEdit::addButton_slot() +{ + qWarning( "subTblEdit::addButton_slot(): Not implemented yet" ); +} + +void subTblEdit::delButton_slot() +{ + qWarning( "subTblEdit::delButton_slot(): Not implemented yet" ); +} + diff --git a/pwmanager/pwmanager/subtbledit.h b/pwmanager/pwmanager/subtbledit.h new file mode 100644 index 0000000..601621d --- a/dev/null +++ b/pwmanager/pwmanager/subtbledit.h @@ -0,0 +1,62 @@ +/**************************************************************************** +** Form interface generated from reading ui file 'subtbledit.ui' +** +** Created: Tue Sep 14 15:32:37 2004 +** by: The User Interface Compiler ($Id$) +** +** WARNING! All changes made in this file will be lost! +****************************************************************************/ + +#ifndef SUBTBLEDIT_H +#define SUBTBLEDIT_H + +#include +#include + +class QVBoxLayout; +class QHBoxLayout; +class QGridLayout; +class QSpacerItem; +class QLabel; +class QLineEdit; +class QPushButton; +class QGroupBox; +class QListBox; +class QListBoxItem; + +class subTblEdit : public QDialog +{ + Q_OBJECT + +public: + subTblEdit( QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~subTblEdit(); + + QLabel* textLabel4; + QLabel* textLabel5; + QLineEdit* titleLineEdit; + QPushButton* okButton; + QPushButton* cancelButton; + QGroupBox* groupBox3; + QLabel* textLabel6; + QLabel* textLabel7; + QPushButton* addButton; + QLineEdit* valueLineEdit; + QLineEdit* nameLineEdit; + QListBox* entryListBox; + QPushButton* delButton; + +public slots: + virtual void okButton_slot(); + virtual void cancelButton_slot(); + virtual void addButton_slot(); + virtual void delButton_slot(); + +protected: + +protected slots: + virtual void languageChange(); + +}; + +#endif // SUBTBLEDIT_H diff --git a/pwmanager/pwmanager/subtbledit.ui b/pwmanager/pwmanager/subtbledit.ui new file mode 100644 index 0000000..1cf1826 --- a/dev/null +++ b/pwmanager/pwmanager/subtbledit.ui @@ -0,0 +1,264 @@ + +subTblEdit + + + subTblEdit + + + + 0 + 0 + 351 + 464 + + + + HTML-comment subtable editor + + + + textLabel4 + + + + 20 + 10 + 310 + 20 + + + + Sub-title: + + + AlignCenter + + + + + textLabel5 + + + + 20 + 70 + 310 + 20 + + + + Current subtable-entries: + + + AlignCenter + + + + + titleLineEdit + + + + 20 + 30 + 310 + 26 + + + + + + okButton + + + + 20 + 420 + 140 + 31 + + + + &OK + + + + + cancelButton + + + + 190 + 420 + 140 + 31 + + + + &Cancel + + + + + groupBox3 + + + + 20 + 210 + 310 + 200 + + + + New entry + + + + textLabel6 + + + + 20 + 30 + 270 + 20 + + + + Entry name: + + + + + textLabel7 + + + + 20 + 90 + 270 + 20 + + + + Entry value: + + + + + addButton + + + + 30 + 150 + 250 + 31 + + + + Add... + + + + + valueLineEdit + + + + 20 + 110 + 270 + 26 + + + + + + nameLineEdit + + + + 20 + 50 + 270 + 26 + + + + + + + entryListBox + + + + 20 + 90 + 310 + 80 + + + + + + delButton + + + + 110 + 170 + 130 + 31 + + + + Delete + + + + + + okButton + clicked() + subTblEdit + okButton_slot() + + + cancelButton + clicked() + subTblEdit + cancelButton_slot() + + + addButton + clicked() + subTblEdit + addButton_slot() + + + delButton + clicked() + subTblEdit + delButton_slot() + + + + titleLineEdit + entryListBox + delButton + nameLineEdit + valueLineEdit + addButton + okButton + cancelButton + + + okButton_slot() + cancelButton_slot() + addButton_slot() + delButton_slot() + + + diff --git a/pwmanager/pwmanager/subtbleditimpl.cpp b/pwmanager/pwmanager/subtbleditimpl.cpp new file mode 100644 index 0000000..cfc66dd --- a/dev/null +++ b/pwmanager/pwmanager/subtbleditimpl.cpp @@ -0,0 +1,138 @@ +/*************************************************************************** + * * + * 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 "subtbleditimpl.h" +#include "pwmexception.h" + +#include + +#include + + +SubTblEditImpl::SubTblEditImpl(QWidget* parent, + const char* name, + WFlags fl) + : subTblEdit(parent, name, fl) +{ + prevSelection = -1; + connect(entryListBox, SIGNAL(currentChanged(QListBoxItem *)), + this, SLOT(selectedEntry_slot())); +} + +SubTblEditImpl::~SubTblEditImpl() +{ +} + +void SubTblEditImpl::okButton_slot() +{ + if (getTitle().isEmpty()) { + QMessageBox::information(this, + i18n("no title"), + i18n("Please enter a title.")); + return; + } + if (!entries.size()) { + QMessageBox::information(this, + i18n("no entries"), + i18n("Please add some entries.")); + return; + } + int index = curIndex(); + if (index != -1) { + entries[index].first = nameLineEdit->text(); + entries[index].second = valueLineEdit->text(); + } + done(0); +} + +void SubTblEditImpl::cancelButton_slot() +{ + done(1); +} + +void SubTblEditImpl::addButton_slot() +{ + QString name(nameLineEdit->text()); + if (name.isEmpty()) + return; + QString value(valueLineEdit->text()); + prevSelection = -1; + nameLineEdit->clear(); + valueLineEdit->clear(); +#ifndef PWM_EMBEDDED + entryListBox->setSelected(entryListBox->index( + entryListBox->selectedItem()), + false); +#else + entryListBox->setSelected(entryListBox->currentItem(), + false); +#endif + pair p; + p.first = name; + p.second = value; + entries.push_back(p); + entryListBox->insertItem(name); +} + +void SubTblEditImpl::delButton_slot() +{ + int index = curIndex(); + if (index == -1) + return; + entries.erase(entries.begin() + index); + entryListBox->removeItem(index); +} + +void SubTblEditImpl::selectedEntry_slot() +{ + int index = curIndex(); + if (index == -1) + return; + disconnect(entryListBox, SIGNAL(currentChanged(QListBoxItem *)), + this, SLOT(selectedEntry_slot())); + if ((prevSelection != -1) && (prevSelection != index)) { + entries[prevSelection].first = nameLineEdit->text(); + entries[prevSelection].second = valueLineEdit->text(); + entryListBox->changeItem(nameLineEdit->text(), prevSelection); + } + pair p(entries[index]); + nameLineEdit->setText(p.first); + valueLineEdit->setText(p.second); + prevSelection = index; + entryListBox->setSelected(index, true); + connect(entryListBox, SIGNAL(currentChanged(QListBoxItem *)), + this, SLOT(selectedEntry_slot())); +} + +void SubTblEditImpl::setContent(const QString &title, + const vector< pair > *_entries) +{ + entries = *_entries; + titleLineEdit->setText(title); + vector< pair >::iterator i = entries.begin(), + end = entries.end(); + while (i != end) { + entryListBox->insertItem(i->first); + ++i; + } +} + +#ifndef PWM_EMBEDDED +#include "subtbleditimpl.moc" +#endif diff --git a/pwmanager/pwmanager/subtbleditimpl.h b/pwmanager/pwmanager/subtbleditimpl.h new file mode 100644 index 0000000..0755fbf --- a/dev/null +++ b/pwmanager/pwmanager/subtbleditimpl.h @@ -0,0 +1,84 @@ +/*************************************************************************** + * * + * 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 SUBTBLEDITIMPL_H +#define SUBTBLEDITIMPL_H + +#include "subtbledit.h" + +#include +#include + +#include +#include + +using std::vector; +using std::pair; + + +class SubTblEditImpl : public subTblEdit +{ + Q_OBJECT +public: + SubTblEditImpl(QWidget* parent = 0, + const char* name = 0, + WFlags fl = 0); + ~SubTblEditImpl(); + + /** returns the title */ + QString getTitle() const + { return titleLineEdit->text(); } + /** returns a pointer to the data */ + const vector< pair > * getEntries() const + { return &entries; } + /** sets the content of the subtable editor */ + void setContent(const QString &title, + const vector< pair > *_entries); + +public slots: + /** on button pressed */ + void okButton_slot(); + /** cancel button pressed */ + void cancelButton_slot(); + /** add button pressed */ + void addButton_slot(); + /** delete button pressed */ + void delButton_slot(); + +protected slots: + /** the user selected another entry */ + void selectedEntry_slot(); + +protected: + /** returns the index of the currently selected entry */ + int curIndex() +#ifndef PWM_EMBEDDED + { return entryListBox->index(entryListBox->selectedItem()); } +#else + { return entryListBox->currentItem(); } +#endif + +protected: + /** internal storage for all entries */ + vector< pair > entries; + /** stores the previous selection */ + int prevSelection; +}; + +#endif diff --git a/pwmanager/pwmanager/waitwnd.cpp b/pwmanager/pwmanager/waitwnd.cpp new file mode 100644 index 0000000..a3f25cc --- a/dev/null +++ b/pwmanager/pwmanager/waitwnd.cpp @@ -0,0 +1,94 @@ +/*************************************************************************** + * * + * copyright (C) 2003 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 "waitwnd.h" +#include "globalstuff.h" +#include "pwmexception.h" + +#include + +#include + + +WaitWnd::WaitWnd(QString caption, QString _staticText, + bool showCancelButton, bool showGenericText, + QWidget *parent, + const char *name, bool modal, WFlags f) + : QDialog(parent, name, modal, f) +{ + canClose = false; + vbox1 = new QVBox(this); + staticText = new QLabel(vbox1); + if (showGenericText) { + genericText = new QLabel(vbox1); + genericText->setAlignment(Qt::AlignHCenter | Qt::WordBreak); + } else { + genericText = 0; + } + if (showCancelButton) { + cancelButton = new QPushButton(vbox1); + connect(cancelButton, SIGNAL(clicked()), + this, SLOT(cancel_slot())); + cancelButton->setText(i18n("&Cancel")); + } else { + cancelButton = 0; + } + + vbox1->setSpacing(10); + vbox1->setMargin(10); + resize(300, 150); + setCaption(caption); + staticText->setText(_staticText); + staticText->setAlignment(Qt::AlignHCenter | Qt::WordBreak); +} + +WaitWnd::~WaitWnd() +{ +} + +void WaitWnd::resizeEvent(QResizeEvent *) +{ + vbox1->resize(size()); +} + +void WaitWnd::closeEvent(QCloseEvent *e) +{ + if (canClose) { + emit goingToClose(); + e->accept(); + } else { + e->ignore(); + } +} + +void WaitWnd::cancel_slot() +{ + canClose = true; + close(); +} + +void WaitWnd::updateGenericText(const QString &text) +{ + if (genericText) + genericText->setText(text); +} + +#ifndef PWM_EMBEDDED +#include "waitwnd.moc" +#endif diff --git a/pwmanager/pwmanager/waitwnd.h b/pwmanager/pwmanager/waitwnd.h new file mode 100644 index 0000000..ae86c8b --- a/dev/null +++ b/pwmanager/pwmanager/waitwnd.h @@ -0,0 +1,61 @@ +/*************************************************************************** + * * + * copyright (C) 2003 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 WAITWND_H +#define WAITWND_H + +#include +#include +#include +#include +#include + +/** window to ask the user to wait */ +class WaitWnd : public QDialog +{ + Q_OBJECT +public: + WaitWnd(QString caption, QString _staticText, + bool showCancelButton, bool showGenericText, + QWidget *parent = 0, const char *name = 0, + bool modal = FALSE, WFlags f = 0); + ~WaitWnd(); + + void updateGenericText(const QString &text); + +signals: + void goingToClose(); + +protected slots: + void cancel_slot(); + +protected: + QVBox *vbox1; + QLabel *staticText; + QLabel *genericText; + QPushButton *cancelButton; + /** can we safely close the widget? */ + bool canClose; + +protected: + void resizeEvent(QResizeEvent *); + void closeEvent(QCloseEvent *e); +}; + +#endif -- cgit v0.9.0.2