From 434e6a5aa3f72333acb215edb128167aad7ea1e8 Mon Sep 17 00:00:00 2001 From: tariq Date: Tue, 11 Oct 2005 19:59:21 +0000 Subject: [PATCH] import comment git-svn-id: https://svn.code.sf.net/p/keepassx/code/trunk@1 b624d157-de02-0410-bad0-e51aec6abb33 --- keepass.pro | 9 + share/keepass/book.png | Bin 0 -> 1086 bytes share/keepass/clientic.png | Bin 0 -> 53490 bytes share/keepass/i18n.png | Bin 0 -> 2408 bytes share/keepass/i18n/english.qm | Bin 0 -> 20735 bytes share/keepass/key.png | Bin 0 -> 1630 bytes share/keepass/license.txt | 340 +++++ share/keepass/ok.png | Bin 0 -> 634 bytes share/keepass/search.png | Bin 0 -> 1983 bytes share/keepass/settings.png | Bin 0 -> 2373 bytes src/Database.cpp | 57 + src/Database.h | 99 ++ src/ListViews.cpp | 155 ++ src/ListViews.h | 108 ++ src/PwManager.cpp | 915 ++++++++++++ src/PwManager.h | 79 + src/PwmConfig.cpp | 135 ++ src/PwmConfig.h | 61 + src/crypto/blowfish.cpp | 541 +++++++ src/crypto/blowfish.h | 110 ++ src/crypto/rijndael.cpp | 1605 ++++++++++++++++++++ src/crypto/rijndael.h | 158 ++ src/crypto/sha1.cpp | 261 ++++ src/crypto/sha1.h | 99 ++ src/crypto/sha256.c | 369 +++++ src/crypto/sha256.h | 32 + src/crypto/twoclass.cpp | 148 ++ src/crypto/twoclass.h | 52 + src/crypto/twofish.cpp | 1705 ++++++++++++++++++++++ src/crypto/twofish.h | 179 +++ src/dialogs/AboutDlg.cpp | 98 ++ src/dialogs/AboutDlg.h | 57 + src/dialogs/ChangeKeyDlg.cpp | 225 +++ src/dialogs/ChangeKeyDlg.h | 71 + src/dialogs/DatabaseSettingsDlg.cpp | 84 ++ src/dialogs/DatabaseSettingsDlg.h | 54 + src/dialogs/EditEntryDlg.cpp | 371 +++++ src/dialogs/EditEntryDlg.h | 74 + src/dialogs/EditGroupDlg.cpp | 68 + src/dialogs/EditGroupDlg.h | 55 + src/dialogs/LanguageDlg.cpp | 149 ++ src/dialogs/LanguageDlg.h | 59 + src/dialogs/PasswordDlg.cpp | 206 +++ src/dialogs/PasswordDlg.h | 71 + src/dialogs/PasswordGenDlg.cpp | 236 +++ src/dialogs/PasswordGenDlg.h | 60 + src/dialogs/SearchDlg.cpp | 97 ++ src/dialogs/SearchDlg.h | 63 + src/dialogs/SettingsDlg.cpp | 125 ++ src/dialogs/SettingsDlg.h | 60 + src/dialogs/SimplePasswordDlg.cpp | 58 + src/dialogs/SimplePasswordDlg.h | 54 + src/forms/Qt4 Portierung.notiz | 2 + src/forms/ui_AboutDlg.ui | 196 +++ src/forms/ui_ChangeKeyDlg.ui | 345 +++++ src/forms/ui_DatabaseSettingsDlg.ui | 220 +++ src/forms/ui_EditEntryDlg.ui | 712 +++++++++ src/forms/ui_EditGroupDlg.ui | 174 +++ src/forms/ui_LanguageDlg.ui | 215 +++ src/forms/ui_MainWindow.ui | 1535 +++++++++++++++++++ src/forms/ui_PasswordDlg.ui | 328 +++++ src/forms/ui_PasswordGenDlg.ui | 551 +++++++ src/forms/ui_SearchDlg.ui | 327 +++++ src/forms/ui_SettingsDlg.ui | 492 +++++++ src/forms/ui_SimplePasswordDlg.ui | 154 ++ src/import/Import_KWalletXml.cpp | 121 ++ src/import/Import_KWalletXml.h | 32 + src/import/Import_PwManager.cpp | 165 +++ src/import/Import_PwManager.h | 41 + src/lib/IniReader.cpp | 488 +++++++ src/lib/IniReader.h | 180 +++ src/lib/PwmTime.cpp | 175 +++ src/lib/PwmTime.h | 51 + src/lib/SecString.cpp | 105 ++ src/lib/SecString.h | 51 + src/lib/UrlLabel.cpp | 55 + src/lib/UrlLabel.h | 45 + src/lib/random.cpp | 47 + src/lib/random.h | 20 + src/main.cpp | 92 ++ src/mainwindow.cpp | 1378 +++++++++++++++++ src/mainwindow.h | 167 +++ src/pwsafe.cpp | 33 + src/pwsafe.h | 48 + src/src.pro | 96 ++ src/translations/english.ts | 1702 +++++++++++++++++++++ src/translations/russian.ts | 2108 +++++++++++++++++++++++++++ 87 files changed, 22063 insertions(+) create mode 100755 keepass.pro create mode 100755 share/keepass/book.png create mode 100755 share/keepass/clientic.png create mode 100755 share/keepass/i18n.png create mode 100755 share/keepass/i18n/english.qm create mode 100755 share/keepass/key.png create mode 100755 share/keepass/license.txt create mode 100755 share/keepass/ok.png create mode 100755 share/keepass/search.png create mode 100755 share/keepass/settings.png create mode 100644 src/Database.cpp create mode 100644 src/Database.h create mode 100755 src/ListViews.cpp create mode 100755 src/ListViews.h create mode 100755 src/PwManager.cpp create mode 100755 src/PwManager.h create mode 100755 src/PwmConfig.cpp create mode 100755 src/PwmConfig.h create mode 100755 src/crypto/blowfish.cpp create mode 100755 src/crypto/blowfish.h create mode 100755 src/crypto/rijndael.cpp create mode 100755 src/crypto/rijndael.h create mode 100755 src/crypto/sha1.cpp create mode 100755 src/crypto/sha1.h create mode 100755 src/crypto/sha256.c create mode 100755 src/crypto/sha256.h create mode 100755 src/crypto/twoclass.cpp create mode 100755 src/crypto/twoclass.h create mode 100755 src/crypto/twofish.cpp create mode 100755 src/crypto/twofish.h create mode 100755 src/dialogs/AboutDlg.cpp create mode 100755 src/dialogs/AboutDlg.h create mode 100755 src/dialogs/ChangeKeyDlg.cpp create mode 100755 src/dialogs/ChangeKeyDlg.h create mode 100755 src/dialogs/DatabaseSettingsDlg.cpp create mode 100755 src/dialogs/DatabaseSettingsDlg.h create mode 100755 src/dialogs/EditEntryDlg.cpp create mode 100755 src/dialogs/EditEntryDlg.h create mode 100755 src/dialogs/EditGroupDlg.cpp create mode 100755 src/dialogs/EditGroupDlg.h create mode 100755 src/dialogs/LanguageDlg.cpp create mode 100755 src/dialogs/LanguageDlg.h create mode 100755 src/dialogs/PasswordDlg.cpp create mode 100755 src/dialogs/PasswordDlg.h create mode 100755 src/dialogs/PasswordGenDlg.cpp create mode 100755 src/dialogs/PasswordGenDlg.h create mode 100755 src/dialogs/SearchDlg.cpp create mode 100755 src/dialogs/SearchDlg.h create mode 100755 src/dialogs/SettingsDlg.cpp create mode 100755 src/dialogs/SettingsDlg.h create mode 100755 src/dialogs/SimplePasswordDlg.cpp create mode 100755 src/dialogs/SimplePasswordDlg.h create mode 100755 src/forms/Qt4 Portierung.notiz create mode 100755 src/forms/ui_AboutDlg.ui create mode 100755 src/forms/ui_ChangeKeyDlg.ui create mode 100755 src/forms/ui_DatabaseSettingsDlg.ui create mode 100755 src/forms/ui_EditEntryDlg.ui create mode 100755 src/forms/ui_EditGroupDlg.ui create mode 100755 src/forms/ui_LanguageDlg.ui create mode 100755 src/forms/ui_MainWindow.ui create mode 100755 src/forms/ui_PasswordDlg.ui create mode 100755 src/forms/ui_PasswordGenDlg.ui create mode 100755 src/forms/ui_SearchDlg.ui create mode 100755 src/forms/ui_SettingsDlg.ui create mode 100755 src/forms/ui_SimplePasswordDlg.ui create mode 100755 src/import/Import_KWalletXml.cpp create mode 100755 src/import/Import_KWalletXml.h create mode 100755 src/import/Import_PwManager.cpp create mode 100755 src/import/Import_PwManager.h create mode 100755 src/lib/IniReader.cpp create mode 100755 src/lib/IniReader.h create mode 100644 src/lib/PwmTime.cpp create mode 100644 src/lib/PwmTime.h create mode 100755 src/lib/SecString.cpp create mode 100755 src/lib/SecString.h create mode 100755 src/lib/UrlLabel.cpp create mode 100755 src/lib/UrlLabel.h create mode 100755 src/lib/random.cpp create mode 100755 src/lib/random.h create mode 100755 src/main.cpp create mode 100755 src/mainwindow.cpp create mode 100755 src/mainwindow.h create mode 100755 src/pwsafe.cpp create mode 100755 src/pwsafe.h create mode 100755 src/src.pro create mode 100755 src/translations/english.ts create mode 100755 src/translations/russian.ts diff --git a/keepass.pro b/keepass.pro new file mode 100755 index 0000000..6bce9ee --- /dev/null +++ b/keepass.pro @@ -0,0 +1,9 @@ +# Diese Datei wurde mit dem qmake-Manager von KDevelop erstellt. +# ------------------------------------------- +# Unterverzeichnis relativ zum Projektverzeichnis: . +# Das Target ist Projekt im Unterverzeichnis + +CONFIG += release \ + warn_on +TEMPLATE = subdirs +SUBDIRS += src diff --git a/share/keepass/book.png b/share/keepass/book.png new file mode 100755 index 0000000000000000000000000000000000000000..31f2bbb24d51a26fbc2b9744a022c27d0b9f2d37 GIT binary patch literal 1086 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 G<^KVS!)3z& literal 0 HcmV?d00001 diff --git a/share/keepass/key.png b/share/keepass/key.png new file mode 100755 index 0000000000000000000000000000000000000000..d6c284ad06651606075ecfe0eeb7d6991e4a72e6 GIT binary patch literal 1630 zcmV-k2BGMP9EyX9p#T%?IJV`K6=WAE62@i4T1hMI?96mGhnbz7*)`!ulA>#;-pp=Kf4}{G zuitwsAq3=`KR5@R2TlNWKHCukH-Piu()TV3FT8$k-^8vrU;fUsJb(Hqjgik5KkCN3 zePxlK{NgHWt@eu+IRDbOPx9PXpW>&#yvCL5cZt2DW(_rKutqa$4K<@!tJwV6+Wa>) z)Oz0=#TbLJn%^td7_1RS>NO4?nBe&{#|R;C;f>4ZEpX!OsiXYtt!r$rw|MQ9Q#3~` zDvBzoDk6fapgmi<7tw*|z7?TZM?`P|?)-g=`wuoad+I0`-ne|i0`+>$a^?D6zW>T| zJkhLI!9-CJMEl@RPBfXCY@#9n_z+mz?9$qa`y`}fa{_e{zBId=ON(pFOicpREr9cZ z#CZtN>83eQZ)d(B^2ND5%+KtmIZ_+)?cDxxcA|vat1VjFNkugYf(nQL0)z|`zyhSs zQ?rInoRWHjQ9(5nJ2tAE{qhv^2PZx@z?zL3&px$}J1dX)>qik9@{NQHTonRfjFLLv zC*Vp1oDZl`jCfQPV}x&gZT8=S_lAgY{BwJ0wO9Bk0u3G&MHDn-3K%1}oPhQeutwSG zrgRcV6uZnOjsp`-=4Xb%*EhF$|K2J~%MXgh%H!mbDSQ%p(zrV6@2!V^gzsY-x%hX4k)JH}czrD;ij?Z%J@N_Y+Ub7r%3Low` zjIo(ZbA^o2ssf2~SZnBX9e?`Z0qgB9aq1asSdL8Zt`PX`yLb5Gt$U12PScp2#_pOV zw!8V=(gy8Lw=(z0?0&X3HgF+iS4n}yxe|fI7fHqkxc%We54R$kjXIJawaitH-&|d! zHolKwM~Gb@agaDq5|rzIYgGssRW@6XNPQsnkOpue3&JERE08*j?PokuVfkU3t4j}g zu-@+P{@NmIn;oRFi^K)e{7ORR-Lr=K}VZKQ#!VofhuX_hyP zU_=oWq&bDAU7p@MOWPTu#N!Z*W&tRo0}3P_Yb7rl{lfCYS5GsucWmg0{Ws$;_glPm zr$w!1F(xA{Ic5<9aq22N?^U%=3J$Pm)Udj=P=NQcYg|?!j#I3feyPn%>ZdXUT+*$8 zOODwmkhmdmYqhe@)^>+?7VaXFB@+Y$=|7X%nl+sM%6yeWxs0no5aOhyKsRwi;MPnULJ<|RDN1%u#rAO?y>J_bCqQhg69;01xCl!`L~gFW1^0{S0-KTbIv zaD$3gV<76LJkhWfa5E5ub5nb{@ZFcuTp7t^8QSfz{#4pIRmFQx)GfInic{3oE8v4J zP*s|Z|E*>3H?x|zWkQt4fC6;mbO_uUE&8@kGMw|J?wY(?7P|3(0@hFgH%9r@%~cMM zlfMYr$*0Hx`KR|q;ey^=9|BiyEn;k~0xseU1&SE(NCn&&<=S$aOAl9x+AWOs&U-JV zX7#@3-y+$R0!~D*)^g|z$4lVQjjJ&bccQp{e{Gv%hZ+TVFS7T~%whEKW23#CUI&j_ z+2>_&5#inUSLsACKx}~3i)%*~$a~lG=4Fm)qfO3ok0rdnV zzZ4(bz|I|iURdGRe^}zt`Ub!a;f2@FshT&(#&JGCw*UYD07*qoM6N<$f{Wb)1poj5 literal 0 HcmV?d00001 diff --git a/share/keepass/license.txt b/share/keepass/license.txt new file mode 100755 index 0000000..5b6e7c6 --- /dev/null +++ b/share/keepass/license.txt @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 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. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, 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 or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +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 give any other recipients of the Program a copy of this License +along with the Program. + +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 Program or any portion +of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +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 Program, 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 Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) 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; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, 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 executable. However, as a +special exception, the source code 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. + +If distribution of executable or 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 counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program 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. + + 5. 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 Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program 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 to +this License. + + 7. 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 Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program 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 Program. + +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. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program 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. + + 9. The Free Software Foundation may publish revised and/or new versions +of the 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 Program +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 Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, 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 + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. 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 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 + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/share/keepass/ok.png b/share/keepass/ok.png new file mode 100755 index 0000000000000000000000000000000000000000..d19bd220f8219406a7d73f5f4cde072d6ec120a8 GIT binary patch literal 634 zcmV-=0)_pFP)Gd3}ao=&iZ}aXQ2Vf{qt%lX(JN6|l{*kA1Kjl;RToa5Q zw&e(n5j#ps=#WEdwW~DKO+EeYk?zCS>Ucf_Ql_9W!VsPvYoGx@Q%ARS^&S}(7Wu-% zo=|H(CPtQILnC$QQg6HepzX9eK0gJLpb?F|L;q_ZWsvKef)f&0C?)Vc`xZ}wVSF6O_{48wCxASmuqp-| z9_{%CI|EvxQK_nePN|221t_Tkg2*E$rXW)Sf}=dbeaV}pcmq@|@&dSuh1ak~8wlShOJ5*sBlNtZEQs z5iCQZf+b+uXu;@bJ= z4Gz!N^e?Q5JkkBQnIE3LAfM@Lo`MohYZ6zYGE!}Oy0k-3z+Sfe4+4OBy>eOn1xC2m U9Hfy)PXGV_07*qoM6N<$f`BR_^PRd$jImq#10%B>;fDdYz%+?{AKv^asVm+$`>IM_g93=Awl@&EsUV&DET{JVXff${b83;+K8bBvAkBFPZ| z0mK9%=FQvW@a^~i`uqI4405vU47@x{3u53j$3GO#f~ z9KrmLf#EkW5puEvEdwSzPM~F+AV&fn%mK_9APiE^%gfHdEiMcyFARuv06+jSv9q%Z z{AXi_WHVq={|mJ2|G)nX!0ZmjpMd=9z?2RO6>eb80LBahkODgngxR5(6-tXp3Ijvo z7tsy?2p|?VHa3R;Y!II_0uBE2=Rd=p$A1|3xER5~{uktPV332dpE%H`KcSYfKvOU* z9|PUV@E_{vU%&nk9R&aZ#Ps&<2ZrB&AO#G_Fi<)W0j9d&K$Czu4xHNAfHsOULwxuP z>T^~GL@2N!iT(fa3zQCsE(-txh~>?j4-A|?e*g;_Zg2>^di$3_T!fiHR)QHE-&{b4 z0iz!5vv)`qfkJ>8mXD!62j$8~cOC;n;MWCW9RLtOz(n|a!}li-!IpzCD6T&MBmUXz zzYOob{%3dxjFOKGkf3LVViu$jU`GmpKi_^Z+`e)bm=*sL?EruP0%gOE&(5D_`0?vM z*a4ud1ulA_Wj+(sVX*jSf?{U0XaG6t+S%)%1h`@L>}sN;03d*v7B6mE@afUL2M@2@ zWB3P*b8z|33P}$PP|F#SDh@_8hrpuZ$JZYWn^*1z`u@*EQVJq~00KuLuu3hww|yhS zo7dmK6$~G+v;lhB z36SCdfB-^i4}^wR^m7Ub6c~jCF{l|TG4Sy~idj}*7_%}WasUi}c>SJX-GVI)?_RuR zaCJ3jc>MS!ur%cQASNa_k@H-EJmaqqA1te{72 zX6g(aoGjqVhy@zwFM(O@{DE@}=Z;=rU}Irf;OuOgaPQvJ2bPw)3g5r~WZ-$cghAlT zK8F9lzcIY~&bz>=>3SkA2LJ>RBQ6P`LlS^gJPV@*I28AC4L#D{tKR?7`1?S3*)zj)4j22nJ|KNb|g6cn5TZzKoQ@z8h~h0t67%9RLD* zuD$(Xt0J=U>Q$g4nC?nQDFYoL1abr<$;t5n9r5;?frgl*0zd%K!~r01;MUt877D^E zuUz@!A;@x9LRwh{=m;HP1;PxD4zB;N8P46|Gyn)7nmGUjj^2Cw!%9gQ7!qGRIRD(0 zP*9TwJL1LD4-CuJJYwKAjAZ}_AeuS=1dc%+ar5R^kM~b*NeBzGF)W?L#pu|NDR7vgs$H;0RWERix@YU}RA3l681PCC;|Ns9p3?u*uFaSSpSPInL RO|<|3002ovPDHLkV1mTjV!HqU literal 0 HcmV?d00001 diff --git a/share/keepass/settings.png b/share/keepass/settings.png new file mode 100755 index 0000000000000000000000000000000000000000..430a62341c613b35c9dddc9bfa359615b2e60b39 GIT binary patch literal 2373 zcmV-L3A*-)P)~B^h21PFDZ`2+~PJ zK~#9!)mLe3T-6o+?!9lFeesO#7~Am{3~mCXNk~G{B0^dyEvPJ|i>NA9T~rl;P^GF; zDXj`ENTm`jC8(v)0zxzp$_|0BxdfclByr+8n={^*u|1n-dGoe=`(wtzAt4EhJ&dvI}qg=}nCr zZn&xG(yxEn%B6bKgCFFUU2~gf_05lLrcCiWW^vBUCHbcTKtB2)*whI^Da#HIxbd#_ zWc4q$y*#)ye#LZzAXWt0cOTwv92>Y#i??~pt*!T#H5O*a61$zz;d>8nz2mLi@SgG~ z0U&+!!4>zsyhK*LS08+S%iF{6y)f$7q4;D!LH-K_1qEO$+BO9nmn=s~Sfh37lF2$* ziq(B)Q;SJ+vK}}9U;=>nR3*6Z+qZ{m)^C1zxHf#N|NM(@Xk32TTEic_a5OCIZj?X} zARVA|DyI6!Yt&HA!)N-9t@&u2cl&mibNpor36AiowMLel%QozNUnhJO0eP@N;L|EBB5@~Flzcn zcDS-aT+J6O^>^QY@R4tA6Wn#rTmnKgs`=I>dLUaJfYl5X6+%D=XwgNidlsSL9Awu5 zNF^vjDWt;;vaZ5x3}B|kug_iD@fBMk5FBXqTz*k|>Cc|TGq?Q1H4Db60MO%KD3MDh z>a7U?Zv#jJZ~bJ|@GLSwg>W6irwJ5F1RMYyK%FcjJ~9t~qw2b5DeIO?a}eC6s>e?it%l07 z4%dYc0uBr`i~}`>AA8R6LQ9*-kMB9ex$T~ogdJD?Kwo?FpKfH1)fSIv=VdfTip>-d zKwz|lxNTUa@tx17_P+AB*K7_g3Ex90~%E@ z8B!26VqqDcU4_y2$3K>YUDw~XzTt=WzIlkcDi;D7iJ~Y`fC2S=DOY*@@kd9VzV&VZ zvjB&U01g3uYV1(dofQ?s!rO`{(O6UU{by z2%gWm3&9E692bdNos`yhw&~f9R{y@ije5hHK4W6{$ijPAxP2vA^}XM3IyS3anbm0} zE?&jx0*p!|l6OUJ&(^27W0g)JGJ-pnJG1kpqjJEzE52_1RkC0A6Awj*P)wE?a*V+Y zFv46d=FQ3lW1^>5I3*JRC;=ft2*&dO1^^rZFbu$`kgzN>pn2Jfy4BxYdAivlICm3| z{c(>mJ@}9uV1^t}fFMIiR00u60<*{<1zT4UNe?fSpBd>X5oqe_aN{e#nx3vEd9IoT zKfpm?Yl_?wYHd*^mry`XQ*G15Yp*R%0==_<;{Xs;Qbe>- z^DQ5S>^bVB2g=6*6laDCGy8Y!p6PpSr;$u_$6GGy$Oj|shFTR$4scG869mK;X{oJm z-q3QvB~X2VRCZ(_%N^@Dka*{3Y3G$Ut_eijuiiZhOqVMAU5^Yq680$~wu+iGWe&g4 z2Y@d$oiMY>yqQhrn>YPfa+oTEiV6>`MKuONf=FzFL^{rG`P_Z=ZEJqneEn^2IqBg+ zNhUc$94*j#(P~2uZFq4XFuh3q1tqX`73EkkE^)IBfCoVSr1LW0Xo&fL9O{(e|VmmSi*f-J2~aE_A8PcZAuj;<0Mu1Hv8)A_Oioz2(VBLL{0C8Oq&Oyoo`oBgEXW!OG?TOd=s#<%p zu+(&HN`?_xIp5%k+ffR?uuwmkHe^>YJHiMLQXpK-jQwC73{3oXj__~K7 z_l-|GyPkN^*niK%!YPg~uht%MJ3Kzmh0i9GxmjZ|; zz~+jMIM(yBGx^#Z5KiW-?gdtE@?iSlOWlRB-a!Cq;ad4}>d+DIit9dK?uak5gHnYf z4A8Shgx(!YtGzQt9`bpdxLV;%1WFzf7-g7rE zjvZRi|FZ({5neA!4d==nhZ*H?eH7lFw1t1a^J*#a?3;qyW7^=6hqM<%KjZm%N9=w7 z9qaHDe{nOt2dcsFPYU29<6}eH^~ZOFv{0 +#include "lib/PwmTime.h" +#include "lib/SecString.h" + +class CEntry{ +public: +CEntry(); +~CEntry(); +UINT8 ID[16]; +UINT32 sID; +UINT32 GroupID; +UINT32 ImageID; +QString Title; +QString URL; +QString UserName; +SecString Password; +QString Additional; +QString BinaryDesc; +CPwmTime Creation; +CPwmTime LastMod; +CPwmTime LastAccess; +CPwmTime Expire; +UINT8 *pBinaryData; +UINT32 BinaryDataLength; +UINT32 PasswordLength; +bool ReadEntryField(UINT16 FieldType, UINT32 FieldSize, UINT8 *pData); +}; + + +class CGroup{ +public: +CGroup(); +~CGroup(); +UINT32 ID; +UINT32 ImageID; +UINT32 NumEntries; +QString Name; +CPwmTime Creation; +CPwmTime LastMod; +CPwmTime LastAccess; +CPwmTime Expire; +UINT16 Level; +UINT32 Flags; +bool ReadGroupField(UINT16 FieldType, UINT32 FieldSize, UINT8 *pData); + +bool UI_ItemIsExpanded; +static bool UI_ExpandByDefault; + +}; + + +typedef vector::iterator EntryItr; +typedef vector::iterator GroupItr; + + +class AbstractDatabase{ +public: + vectorGroups; + vectorEntries; +}; + + + +class Database:public AbstractDatabase{ +public: + int CryptoAlgorithmus; + int KeyEncRounds; + QString filename; + bool modflag; + int SearchGroupID; + +protected: + UINT8 MasterKey[32]; + UINT8 TransformedMasterKey[32]; +}; + +#endif \ No newline at end of file diff --git a/src/ListViews.cpp b/src/ListViews.cpp new file mode 100755 index 0000000..2f6e5d4 --- /dev/null +++ b/src/ListViews.cpp @@ -0,0 +1,155 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * mail@tarek-saidi.de * + * * + * 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. * + ***************************************************************************/ +#include "ListViews.h" +#include "PwManager.h" +#include +#include + + + +GroupItem::GroupItem(CGroup* group, QListView * parent ) : QListViewItem(parent) +{ +pGroup=group; +setDropEnabled(true); +} + +GroupItem::GroupItem(CGroup* group, QListViewItem * parent ): QListViewItem(parent) +{ +pGroup=group; +setDropEnabled(true); +} + +GroupItem::GroupItem(CGroup* group, QListView * parent, QListViewItem * after ): QListViewItem(parent,after) +{ +pGroup=group; +setDropEnabled(true); +} + +GroupItem::GroupItem(CGroup* group, QListViewItem * parent, QListViewItem * after ): QListViewItem(parent,after) +{ +pGroup=group; +setDropEnabled(true); +} + +GroupItem::GroupItem(CGroup* group, QListView* parent, QString l1,QString l2,QString l3,QString l4, + QString l5,QString l6,QString l7,QString l8) + :QListViewItem(parent,l1,l2,l3,l4,l5,l6,l7,l8) +{ +pGroup=group; +setDropEnabled(true); +} + +GroupItem::GroupItem(CGroup* group, QListViewItem* parent, QString l1,QString l2,QString l3,QString l4, + QString l5,QString l6,QString l7,QString l8) + :QListViewItem(parent,l1,l2,l3,l4,l5,l6,l7,l8) +{ +pGroup=group; +setDropEnabled(true); +} + +GroupItem::GroupItem(CGroup* group, QListView* parent,QListViewItem* after, QString l1,QString l2,QString l3,QString l4, + QString l5,QString l6,QString l7,QString l8) + :QListViewItem(parent,after,l1,l2,l3,l4,l5,l6,l7,l8) +{ +pGroup=group; +setDropEnabled(true); +} + +GroupItem::GroupItem(CGroup* group, QListViewItem* parent,QListViewItem* after, QString l1,QString l2,QString l3,QString l4, + QString l5,QString l6,QString l7,QString l8) + :QListViewItem(parent,after,l1,l2,l3,l4,l5,l6,l7,l8) +{ +pGroup=group; +setDropEnabled(true); +} + +GroupItem::~GroupItem(){} + + +bool GroupItem::acceptDrop(const QMimeSource* mime){ +qDebug("DropEvent\n"); +return true; +} + + +/////////////////////////////// + +EntryItem::EntryItem(CEntry* entry, QListView * parent ) : QListViewItem(parent) +{ +pEntry=entry; +setDragEnabled(true); +} + +EntryItem::EntryItem(CEntry* entry, QListViewItem * parent ): QListViewItem(parent) +{ +pEntry=entry; +setDragEnabled(true); +} + +EntryItem::EntryItem(CEntry* entry, QListView * parent, QListViewItem * after ): QListViewItem(parent,after) +{ +pEntry=entry; +setDragEnabled(true); +} + +EntryItem::EntryItem(CEntry* entry, QListViewItem * parent, QListViewItem * after ): QListViewItem(parent,after) +{ +pEntry=entry; +setDragEnabled(true); +} + +EntryItem::EntryItem(CEntry* entry, QListView* parent, QString l1,QString l2,QString l3,QString l4, + QString l5,QString l6,QString l7,QString l8) + :QListViewItem(parent,l1,l2,l3,l4,l5,l6,l7,l8) +{ +pEntry=entry; +setDragEnabled(true); +} + +EntryItem::EntryItem(CEntry* entry, QListViewItem* parent, QString l1,QString l2,QString l3,QString l4, + QString l5,QString l6,QString l7,QString l8) + :QListViewItem(parent,l1,l2,l3,l4,l5,l6,l7,l8) +{ +pEntry=entry; +setDragEnabled(true); +} + +EntryItem::EntryItem(CEntry* entry, QListView* parent,QListViewItem* after, QString l1,QString l2,QString l3,QString l4, + QString l5,QString l6,QString l7,QString l8) + :QListViewItem(parent,after,l1,l2,l3,l4,l5,l6,l7,l8) +{ +pEntry=entry; +setDragEnabled(true); +} + +EntryItem::EntryItem(CEntry* entry, QListViewItem* parent,QListViewItem* after, QString l1,QString l2,QString l3,QString l4, + QString l5,QString l6,QString l7,QString l8) + :QListViewItem(parent,after,l1,l2,l3,l4,l5,l6,l7,l8) +{ +pEntry=entry; +setDragEnabled(true); +} + + + + +CGroupView::CGroupView(QWidget * parent, const char * name, WFlags f):QListView(parent,name,f){ + +}; \ No newline at end of file diff --git a/src/ListViews.h b/src/ListViews.h new file mode 100755 index 0000000..fd9762d --- /dev/null +++ b/src/ListViews.h @@ -0,0 +1,108 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * mail@tarek-saidi.de * + * * + * 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. * + ***************************************************************************/ +#ifndef _LISTVIEWS_H_ +#define _LISTVIEWS_H_ + +#include +#include +#include "PwManager.h" + +class GroupItem: public QListViewItem{ +public: +CGroup* pGroup; +virtual bool acceptDrop(const QMimeSource * mime); +/////////////////////////////////////////////////////////////////////// + GroupItem(CGroup*, QListView * parent ); + GroupItem(CGroup*, QListViewItem * parent ); + GroupItem(CGroup*, QListView * parent, QListViewItem * after ); + GroupItem(CGroup*, QListViewItem * parent, QListViewItem * after ); + + GroupItem(CGroup*, QListView * parent, + QString, QString = QString::null, + QString = QString::null, QString = QString::null, + QString = QString::null, QString = QString::null, + QString = QString::null, QString = QString::null ); + + GroupItem(CGroup*, QListViewItem * parent, + QString, QString = QString::null, + QString = QString::null, QString = QString::null, + QString = QString::null, QString = QString::null, + QString = QString::null, QString = QString::null ); + + GroupItem(CGroup*, QListView * parent, QListViewItem * after, + QString, QString = QString::null, + QString = QString::null, QString = QString::null, + QString = QString::null, QString = QString::null, + QString = QString::null, QString = QString::null ); + + GroupItem(CGroup*, QListViewItem * parent, QListViewItem * after, + QString, QString = QString::null, + QString = QString::null, QString = QString::null, + QString = QString::null, QString = QString::null, + QString = QString::null, QString = QString::null ); + ~GroupItem(); +///////////////////////////////////////////////////////////////////////// +}; + + +class EntryItem: public QListViewItem{ +public: +CEntry* pEntry; +/////////////////////////////////////////////////////////////////////// + EntryItem(CEntry*, QListView * parent ); + EntryItem(CEntry*, QListViewItem * parent ); + EntryItem(CEntry*, QListView * parent, QListViewItem * after ); + EntryItem(CEntry*, QListViewItem * parent, QListViewItem * after ); + + EntryItem(CEntry*, QListView * parent, + QString, QString = QString::null, + QString = QString::null, QString = QString::null, + QString = QString::null, QString = QString::null, + QString = QString::null, QString = QString::null ); + + EntryItem(CEntry*, QListViewItem * parent, + QString, QString = QString::null, + QString = QString::null, QString = QString::null, + QString = QString::null, QString = QString::null, + QString = QString::null, QString = QString::null ); + + EntryItem(CEntry*, QListView * parent, QListViewItem * after, + QString, QString = QString::null, + QString = QString::null, QString = QString::null, + QString = QString::null, QString = QString::null, + QString = QString::null, QString = QString::null ); + + EntryItem(CEntry*, QListViewItem * parent, QListViewItem * after, + QString, QString = QString::null, + QString = QString::null, QString = QString::null, + QString = QString::null, QString = QString::null, + QString = QString::null, QString = QString::null ); +///////////////////////////////////////////////////////////////////////// +}; + + +class CGroupView: public QListView{ +public: + CGroupView(QWidget * parent = 0, const char * name = 0, WFlags f = 0 ); + + +}; + +#endif \ No newline at end of file diff --git a/src/PwManager.cpp b/src/PwManager.cpp new file mode 100755 index 0000000..92b5d9b --- /dev/null +++ b/src/PwManager.cpp @@ -0,0 +1,915 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * tarek@linux * + * * + * 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. * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include "crypto/sha256.h" +#include "crypto/rijndael.h" +#include "crypto/twoclass.h" +#include "lib/random.h" + +#include "PwManager.h" + +bool PwDatabase::loadDatabase(QString _filename, QString& err){ +unsigned long total_size,crypto_size; +UINT32 Signature1,Signature2,Version,NumGroups,NumEntries,Flags; +UINT8 TrafoRandomSeed[32]; +UINT8 FinalRandomSeed[16]; +UINT8 ContentsHash[32]; +UINT8 EncryptionIV[16]; + +filename=_filename; +QFile file(filename); +file.open(IO_ReadOnly); +total_size=file.size(); +char* buffer = new char[total_size]; +file.readBlock(buffer,total_size); +file.close(); + +if(total_size < DB_HEADER_SIZE){ +err=trUtf8("Unerwartete Dateigröße (Dateigröße < DB_HEADER_SIZE)"); +return false; } + +memcpy(&Signature1,buffer,4); +memcpy(&Signature2,buffer+4,4); +memcpy(&Flags,buffer+8,4); +memcpy(&Version,buffer+12,4); +memcpy(FinalRandomSeed,buffer+16,16); +memcpy(EncryptionIV,buffer+32,16); +memcpy(&NumGroups,buffer+48,4); +memcpy(&NumEntries,buffer+52,4); +memcpy(ContentsHash,buffer+56,32); +memcpy(TrafoRandomSeed,buffer+88,32); +memcpy(&KeyEncRounds,buffer+120,4); + +if((Signature1!=PWM_DBSIG_1) || (Signature2!=PWM_DBSIG_2)){ +err=trUtf8("Falsche Signatur"); +return false;} + + +if((Version & 0xFFFFFF00) != (PWM_DBVER_DW & 0xFFFFFF00)){ + err=trUtf8("Nicht unterstüzte Dateiversion"); + return false;} + +if(Flags & PWM_FLAG_RIJNDAEL) CryptoAlgorithmus = ALGO_AES; +else if(Flags & PWM_FLAG_TWOFISH) CryptoAlgorithmus = ALGO_TWOFISH; +else { + err=trUtf8("Unbekannter Verschlüsselungsalgorithmus"); + return false; + } + +transformKey(MasterKey,TransformedMasterKey,TrafoRandomSeed,KeyEncRounds); +UINT8 FinalKey[32]; +sha256_context sha32; +sha256_starts(&sha32); +sha256_update(&sha32,FinalRandomSeed, 16); +sha256_update(&sha32,TransformedMasterKey, 32); +sha256_finish(&sha32,FinalKey); + +if(CryptoAlgorithmus == ALGO_AES) + { + Rijndael aes; + // Initialize Rijndael algorithm + if(aes.init(Rijndael::CBC, Rijndael::Decrypt, FinalKey, + Rijndael::Key32Bytes, EncryptionIV) != RIJNDAEL_SUCCESS) + {return false;} + // Decrypt! The first bytes aren't encrypted (that's the header) + crypto_size = (unsigned long)aes.padDecrypt((UINT8 *)buffer + DB_HEADER_SIZE, + total_size - DB_HEADER_SIZE, (UINT8 *)buffer + DB_HEADER_SIZE); + } +else if(CryptoAlgorithmus == ALGO_TWOFISH) + { + CTwofish twofish; + if(twofish.init(FinalKey, 32, EncryptionIV) != true){return false;} + crypto_size = (unsigned long)twofish.padDecrypt((UINT8 *)buffer + DB_HEADER_SIZE, + total_size - DB_HEADER_SIZE, (UINT8 *)buffer + DB_HEADER_SIZE); + } + +if((crypto_size > 2147483446) || (crypto_size == 0)){return false;} + +sha256_starts(&sha32); +sha256_update(&sha32,(unsigned char *)buffer + DB_HEADER_SIZE,crypto_size); +sha256_finish(&sha32,(unsigned char *)FinalKey); + +if(memcmp(ContentsHash, FinalKey, 32) != 0) +{ +err=trUtf8("Hash-Test fehlgeschlage: der Schlüssl ist falsch oder die Datei ist beschädigt."); +return false;} + + +Groups.resize(NumGroups); +Entries.resize(NumEntries); + +unsigned long tmp_id=0; +unsigned long pos = DB_HEADER_SIZE; +UINT16 FieldType; +UINT32 FieldSize; +char* pField; +bool bRet; + + + for(unsigned long CurGroup = 0; CurGroup < NumGroups; ) + { + pField = buffer+pos; + + memcpy(&FieldType, pField, 2); + pField += 2; pos += 2; + if(pos >= total_size) { + return false; } + + memcpy(&FieldSize, pField, 4); + pField += 4; pos += 4; + if(pos >= (total_size + FieldSize)) { + return false;} + + bRet = Groups[CurGroup].ReadGroupField(FieldType, FieldSize, (UINT8 *)pField); + if((FieldType == 0xFFFF) && (bRet == true)){ + CurGroup++;} // Now and ONLY now the counter gets increased + + pField += FieldSize; + pos += FieldSize; + if(pos >= total_size) { return false;} + } + + + for(unsigned long CurEntry = 0; CurEntry < NumEntries;) + { + pField = buffer+pos; + + memcpy(&FieldType, pField, 2); + pField += 2; pos += 2; + if(pos >= total_size){ + return false;} + + memcpy(&FieldSize, pField, 4); + pField += 4; pos += 4; + if(pos >= (total_size + FieldSize)) { + return false; } + + bRet = Entries[CurEntry].ReadEntryField(FieldType,FieldSize,(UINT8*)pField); + if((FieldType == 0xFFFF) && (bRet == true)){ + Entries[CurEntry].sID=tmp_id++; + CurEntry++;} // Now and ONLY now the counter gets increased + + pField += FieldSize; + pos += FieldSize; + if(pos >= total_size) { + return false; } + } + +unsigned long CurGID, g, e, z, num; +delete [] buffer; + +for(vector::iterator i=Entries.begin();i!=Entries.end();i++){ +if(IsMetaStream(*i)==true){ + ///@TODO Parse Metastreams + deleteEntry(i); + i--; +} +} +return true; +} + + +void PwDatabase::transformKey(UINT8* src,UINT8* dst,UINT8* KeySeed,int rounds){ +UINT8* tmp=new UINT8[32]; +Rijndael rijndael; +sha256_context sha2; +if(rijndael.init(Rijndael::ECB, Rijndael::Encrypt, (const UINT8 *)KeySeed, + Rijndael::Key32Bytes, 0) != RIJNDAEL_SUCCESS){ + cout << QString("unexpected error in %1, line %2").arg(__FILE__).arg(__LINE__) << endl; + exit(1);} + +memcpy(tmp,src,32); +for(int i=0;i::iterator PwDatabase::deleteEntry(vector::iterator iterator){ +return Entries.erase(iterator); +} + +vector::iterator PwDatabase::deleteEntry(CEntry* entry){ +return deleteEntry(getEntryIterator(entry)); +} + +bool PwDatabase::IsMetaStream(CEntry& p){ + +if(p.pBinaryData == NULL) return false; +if(p.Additional == NULL) return false; +if(p.BinaryDesc == NULL) return false; +if(p.BinaryDesc != "bin-stream") return false; +if(p.Title == NULL) return false; +if(p.Title != "Meta-Info") return false; +if(p.UserName == NULL) return false; +if(p.UserName != "SYSTEM") return false; +if(p.URL == NULL) return false; +if(p.URL != "$") return false; +if(p.ImageID != 0) return false; +return true; +} + + + +void PwDatabase::moveEntry(CEntry* entry,CGroup* dst){ +entry->GroupID=dst->ID; +} + + + +bool CGroup::ReadGroupField(UINT16 FieldType, UINT32 FieldSize, UINT8 *pData) +{ + + switch(FieldType) + { + case 0x0000: + // Ignore field + break; + case 0x0001: + memcpy(&ID, pData, 4); + break; + case 0x0002: + //Name.fromUtf8((char*)pData); + Name=QString::fromUtf8((char*)pData); + break; + case 0x0003: + Creation.Set(pData); + break; + case 0x0004: + LastMod.Set(pData); + break; + case 0x0005: + LastAccess.Set(pData); + break; + case 0x0006: + Expire.Set(pData); + break; + case 0x0007: + memcpy(&ImageID, pData, 4); + break; + case 0x0008: + memcpy(&Level, pData, 2); + break; + case 0x0009: + memcpy(&Flags, pData, 4); + break; + case 0xFFFF: + break; + default: + return false; // Field unsupported + } + + return true; // Field supported +} + +PwDatabase::PwDatabase(){ +SearchGroupID=-1; +} + +PwDatabase::~PwDatabase(){ + +} + + +bool CEntry::ReadEntryField(UINT16 FieldType, UINT32 FieldSize, UINT8 *pData){ + + +switch(FieldType) + { + case 0x0000: + // Ignore field + break; + case 0x0001: + memcpy(ID, pData, 16); + break; + case 0x0002: + memcpy(&GroupID, pData, 4); + break; + case 0x0003: + memcpy(&ImageID, pData, 4); + break; + case 0x0004: + //Title=(char*)pData; + Title=QString::fromUtf8((char*)pData); + break; + case 0x0005: + URL=QString::fromUtf8((char*)pData); + break; + case 0x0006: + UserName=QString::fromUtf8((char*)pData); + break; + case 0x0007:{ + QString s=QString::fromUtf8((char*)pData); + Password.setString(s,true); + break;} + case 0x0008: + Additional=QString::fromUtf8((char*)pData); + break; + case 0x0009: + Creation.Set(pData); + break; + case 0x000A: + LastMod.Set(pData); + break; + case 0x000B: + LastAccess.Set(pData); + break; + case 0x000C: + Expire.Set(pData); + break; + case 0x000D: + BinaryDesc=(char*)pData; + break; + case 0x000E: + if(FieldSize != 0) + { + ///@TODO: im Destruktor löschen + ///@TODO: im Konstruktor auf Null + pBinaryData = new UINT8[FieldSize]; + memcpy(pBinaryData, pData, FieldSize); + BinaryDataLength = FieldSize; + } + else + {pBinaryData=0;} + break; + case 0xFFFF: + ///@TODO: Alle Elemente geladen - Status setzen oder so was + break; + default: + return false; // Field unsupported + } + + return true; // Field processed +} + +bool PwDatabase::CloseDataBase(){ +Groups.clear(); +Entries.clear(); +return true; +} + +bool PwDatabase::SaveDataBase(QString filename){ +CGroup SearchGroup; +UINT32 NumGroups,NumEntries,Signature1,Signature2,Flags,Version; +UINT8 TrafoRandomSeed[32]; +UINT8 FinalRandomSeed[16]; +UINT8 ContentsHash[32]; +UINT8 EncryptionIV[16]; + +if(SearchGroupID!=-1){ + for(int i=0;iAdd Metastreams +FileSize=DB_HEADER_SIZE; +// Get the size of all groups (94 Byte + length of the name string) +for(int i = 0; i < Groups.size(); i++){ + FileSize += 94 + Groups[i].Name.utf8().length()+1; +} +// Get the size of all entries +for(int i = 0; i < Entries.size(); i++){ + FileSize += 134 + +Entries[i].Title.utf8().length()+1 + +Entries[i].UserName.utf8().length()+1 + +Entries[i].URL.utf8().length()+1 + +Entries[i].Password.length()+1 + +Entries[i].Additional.utf8().length()+1 + +Entries[i].BinaryDesc.utf8().length()+1 + +Entries[i].BinaryDataLength;} +// Round up filesize to 16-byte boundary for Rijndael/Twofish +FileSize = (FileSize + 16) - (FileSize % 16); +char* buffer=new char[FileSize+16]; + + +Signature1 = PWM_DBSIG_1; +Signature2 = PWM_DBSIG_2; +Flags = PWM_FLAG_SHA2; +if(CryptoAlgorithmus == ALGO_AES) Flags |= PWM_FLAG_RIJNDAEL; +else if(CryptoAlgorithmus == ALGO_TWOFISH) Flags |= PWM_FLAG_TWOFISH; +Version = PWM_DBVER_DW; +NumGroups = Groups.size(); //-> (+MetaStreams) +NumEntries = Entries.size(); + +getRandomBytes(FinalRandomSeed,1,16,false); +getRandomBytes(TrafoRandomSeed,1,32,false); +getRandomBytes(EncryptionIV,1,16,false); + +UINT16 FieldType; +UINT32 FieldSize; +int pos=DB_HEADER_SIZE; // Skip the header, it will be written later + +for(int i=0; i < Groups.size(); i++){ + FieldType = 0x0001; FieldSize = 4; + memcpy(buffer+pos, &FieldType, 2); pos += 2; + memcpy(buffer+pos, &FieldSize, 4); pos += 4; + memcpy(buffer+pos, &Groups[i].ID, 4); pos += 4; + + FieldType = 0x0002; FieldSize = Groups[i].Name.utf8().length() + 1; + memcpy(buffer+pos, &FieldType, 2); pos += 2; + memcpy(buffer+pos, &FieldSize, 4); pos += 4; + memcpy(buffer+pos, Groups[i].Name.utf8(),FieldSize); pos += FieldSize; + + FieldType = 0x0003; FieldSize = 5; + memcpy(buffer+pos, &FieldType, 2); pos += 2; + memcpy(buffer+pos, &FieldSize, 4); pos += 4; + Groups[i].Creation.GetPackedTime((unsigned char*)buffer+pos);pos += 5; + + FieldType = 0x0004; FieldSize = 5; + memcpy(buffer+pos, &FieldType, 2); pos += 2; + memcpy(buffer+pos, &FieldSize, 4); pos += 4; + Groups[i].LastMod.GetPackedTime((unsigned char*)buffer+pos);pos += 5; + + FieldType = 0x0005; FieldSize = 5; + memcpy(buffer+pos, &FieldType, 2); pos += 2; + memcpy(buffer+pos, &FieldSize, 4); pos += 4; + Groups[i].LastAccess.GetPackedTime((unsigned char*)buffer+pos);pos += 5; + + FieldType = 0x0006; FieldSize = 5; + memcpy(buffer+pos, &FieldType, 2); pos += 2; + memcpy(buffer+pos, &FieldSize, 4); pos += 4; + Groups[i].Expire.GetPackedTime((unsigned char*)buffer+pos);pos += 5; + + FieldType = 0x0007; FieldSize = 4; + memcpy(buffer+pos, &FieldType, 2); pos += 2; + memcpy(buffer+pos, &FieldSize, 4); pos += 4; + memcpy(buffer+pos, &Groups[i].ImageID, 4); pos += 4; + + FieldType = 0x0008; FieldSize = 2; + memcpy(buffer+pos, &FieldType, 2); pos += 2; + memcpy(buffer+pos, &FieldSize, 4); pos += 4; + memcpy(buffer+pos, &Groups[i].Level, 2); pos += 2; + + FieldType = 0x0009; FieldSize = 4; + memcpy(buffer+pos, &FieldType, 2); pos += 2; + memcpy(buffer+pos, &FieldSize, 4); pos += 4; + memcpy(buffer+pos, &Groups[i].Flags, 4); pos += 4; + + FieldType = 0xFFFF; FieldSize = 0; + memcpy(buffer+pos, &FieldType, 2); pos += 2; + memcpy(buffer+pos, &FieldSize, 4); pos += 4; +} + +for(int i = 0; i < Entries.size(); i++){ + FieldType = 0x0001; FieldSize = 16; + memcpy(buffer+pos, &FieldType, 2); pos += 2; + memcpy(buffer+pos, &FieldSize, 4); pos += 4; + memcpy(buffer+pos, &Entries[i].ID, 16); pos += 16; + + FieldType = 0x0002; FieldSize = 4; + memcpy(buffer+pos, &FieldType, 2); pos += 2; + memcpy(buffer+pos, &FieldSize, 4); pos += 4; + memcpy(buffer+pos, &Entries[i].GroupID, 4); pos += 4; + + FieldType = 0x0003; FieldSize = 4; + memcpy(buffer+pos, &FieldType, 2); pos += 2; + memcpy(buffer+pos, &FieldSize, 4); pos += 4; + memcpy(buffer+pos, &Entries[i].ImageID, 4); pos += 4; + + + FieldType = 0x0004; + FieldSize = Entries[i].Title.utf8().length() + 1; // Add terminating NULL character space + memcpy(buffer+pos, &FieldType, 2); pos += 2; + memcpy(buffer+pos, &FieldSize, 4); pos += 4; + memcpy(buffer+pos, Entries[i].Title.utf8(),FieldSize); pos += FieldSize; + + FieldType = 0x0005; + FieldSize = Entries[i].URL.utf8().length() + 1; // Add terminating NULL character space + memcpy(buffer+pos, &FieldType, 2); pos += 2; + memcpy(buffer+pos, &FieldSize, 4); pos += 4; + memcpy(buffer+pos, Entries[i].URL.utf8(),FieldSize); pos += FieldSize; + + FieldType = 0x0006; + FieldSize = Entries[i].UserName.utf8().length() + 1; // Add terminating NULL character space + memcpy(buffer+pos, &FieldType, 2); pos += 2; + memcpy(buffer+pos, &FieldSize, 4); pos += 4; + memcpy(buffer+pos, Entries[i].UserName.utf8(),FieldSize); pos += FieldSize; + + FieldType = 0x0007; + FieldSize = Entries[i].Password.length() + 1; // Add terminating NULL character space + memcpy(buffer+pos, &FieldType, 2); pos += 2; + memcpy(buffer+pos, &FieldSize, 4); pos += 4; + memcpy(buffer+pos, Entries[i].Password.getString(),FieldSize); pos += FieldSize; + Entries[i].Password.delRef(); + + FieldType = 0x0008; + FieldSize = Entries[i].Additional.utf8().length() + 1; // Add terminating NULL character space + memcpy(buffer+pos, &FieldType, 2); pos += 2; + memcpy(buffer+pos, &FieldSize, 4); pos += 4; + memcpy(buffer+pos, Entries[i].Additional.utf8(),FieldSize); pos += FieldSize; + + FieldType = 0x0009; FieldSize = 5; + memcpy(buffer+pos, &FieldType, 2); pos += 2; + memcpy(buffer+pos, &FieldSize, 4); pos += 4; + Entries[i].Creation.GetPackedTime((unsigned char*)buffer+pos); pos+=5; + + + FieldType = 0x000A; FieldSize = 5; + memcpy(buffer+pos, &FieldType, 2); pos += 2; + memcpy(buffer+pos, &FieldSize, 4); pos += 4; + Entries[i].LastMod.GetPackedTime((unsigned char*)buffer+pos); pos+=5; + + FieldType = 0x000B; FieldSize = 5; + memcpy(buffer+pos, &FieldType, 2); pos += 2; + memcpy(buffer+pos, &FieldSize, 4); pos += 4; + Entries[i].LastAccess.GetPackedTime((unsigned char*)buffer+pos); pos+=5; + + FieldType = 0x000C; FieldSize = 5; + memcpy(buffer+pos, &FieldType, 2); pos += 2; + memcpy(buffer+pos, &FieldSize, 4); pos += 4; + Entries[i].Expire.GetPackedTime((unsigned char*)buffer+pos); pos+=5; + + FieldType = 0x000D; + FieldSize = Entries[i].BinaryDesc.utf8().length() + 1; // Add terminating NULL character space + memcpy(buffer+pos, &FieldType, 2); pos += 2; + memcpy(buffer+pos, &FieldSize, 4); pos += 4; + memcpy(buffer+pos, Entries[i].BinaryDesc.utf8(),FieldSize); pos += FieldSize; + + FieldType = 0x000E; FieldSize = Entries[i].BinaryDataLength; + memcpy(buffer+pos, &FieldType, 2); pos += 2; + memcpy(buffer+pos, &FieldSize, 4); pos += 4; + if((Entries[i].pBinaryData != NULL) && (FieldSize != 0)) + memcpy(buffer+pos, Entries[i].pBinaryData, FieldSize); + pos += FieldSize; + + FieldType = 0xFFFF; FieldSize = 0; + memcpy(buffer+pos, &FieldType, 2); pos += 2; + memcpy(buffer+pos, &FieldSize, 4); pos += 4; +} +sha256_context context; +sha256_starts(&context); +sha256_update(&context,(unsigned char*)buffer+DB_HEADER_SIZE, pos - DB_HEADER_SIZE); +sha256_finish(&context,(unsigned char*)ContentsHash); +memcpy(buffer,&Signature1,4); +memcpy(buffer+4,&Signature2,4); +memcpy(buffer+8,&Flags,4); +memcpy(buffer+12,&Version,4); +memcpy(buffer+16,FinalRandomSeed,16); +memcpy(buffer+32,EncryptionIV,16); +memcpy(buffer+48,&NumGroups,4); +memcpy(buffer+52,&NumEntries,4); +memcpy(buffer+56,ContentsHash,32); +memcpy(buffer+88,TrafoRandomSeed,32); +memcpy(buffer+120,&KeyEncRounds,4); +transformKey(MasterKey,TransformedMasterKey,TrafoRandomSeed,KeyEncRounds); +UINT8 FinalKey[32]; +sha256_starts(&context); +sha256_update(&context,FinalRandomSeed, 16); +sha256_update(&context,TransformedMasterKey, 32); +sha256_finish(&context,FinalKey); + +unsigned long EncryptedPartSize; + +if(CryptoAlgorithmus == ALGO_AES){ +Rijndael aes; +// Initialize Rijndael/AES + if(aes.init(Rijndael::CBC, Rijndael::Encrypt, FinalKey,Rijndael::Key32Bytes, EncryptionIV) != RIJNDAEL_SUCCESS){ + //TODO:ERR_MSG + delete [] buffer; + return false;} +EncryptedPartSize = (unsigned long)aes.padEncrypt((UINT8*)buffer+DB_HEADER_SIZE, + pos - DB_HEADER_SIZE, + (UINT8*)buffer+DB_HEADER_SIZE); +}else if(CryptoAlgorithmus == ALGO_TWOFISH){ +CTwofish twofish; +if(twofish.init(FinalKey, 32, EncryptionIV) == false){ +//TODO:ERR_MSG +delete [] buffer; +return false;} +EncryptedPartSize = (unsigned long)twofish.padEncrypt((UINT8*)buffer+DB_HEADER_SIZE, + pos - DB_HEADER_SIZE, + (UINT8*)buffer+DB_HEADER_SIZE); +} + +if((EncryptedPartSize > 2147483446) || (EncryptedPartSize == 0)){ +//TODO:ERR_MSG +delete [] buffer; +return false; +} + +if(file.open(IO_ReadWrite | IO_Truncate)==false){ +//TODO:ERR_MSG +delete [] buffer; +return false; +} + +if(file.writeBlock(buffer,EncryptedPartSize+DB_HEADER_SIZE)!=EncryptedPartSize+DB_HEADER_SIZE){ +//TODO:ERR_MSG +file.close(); +delete [] buffer; +return false; +} + +file.close(); +delete [] buffer; +if(SearchGroupID!=-1)Groups.push_back(SearchGroup); +return true; +} + +bool PwDatabase::NewDataBase(){ +filename=""; +SearchGroupID=-1; +CryptoAlgorithmus=ALGO_AES; +KeyEncRounds=6000; + +CGroup g; +g.ID=1; +g.Name=QObject::trUtf8("Standardgruppe"); +Groups.push_back(g); +} + +GroupItr PwDatabase::getGroupIterator(CGroup* pGroup){ +//for(vector::iterator i=Groups.begin();i!=Groups.end();i++){ +//if((*i).ID==pGroup->ID)return i;} +return Groups.begin()+(pGroup-&Groups[0]); +} + + +EntryItr PwDatabase::getEntryIterator(CEntry* pEntry){ +return Entries.begin()+(pEntry-&Entries[0]); +} + +CGroup* PwDatabase::addGroup(CGroup* parent){ +CGroup group; +if(parent)group.Level=parent->Level+1; +group.ImageID=0; +group.ID=getNewGroupId(); + +if(!Groups.size() || !parent){ + Groups.push_back(group); + return &Groups.back(); +} +else { GroupItr groupIt; + groupIt=Groups.insert(getGroupIterator(parent)+1,group); + return &(*groupIt);} +} + + +GroupItr PwDatabase::deleteGroup(unsigned long id){ +for(int i=0;iLevel){ + last=i; + break;} +} + +for(GroupItr g=first;g!=last;g++){ + for(EntryItr e=Entries.begin();e!=Entries.end();){ + if((*g).ID==(*e).GroupID)e=deleteEntry(e); + else e++; + } +} + +return Groups.erase(first,last); +} + + + + +int PwDatabase::getGroupIndex(unsigned long ID){ +int i=0; +for(i;iGroups.size();i++){ + int NewGroupID; + if(isGroupIdInUse(db->Groups[i].ID)==true) NewGroupID=getNewGroupId(); + else NewGroupID=db->Groups[i].ID; + for(int j=0;jEntries.size();j++){ + if(db->Entries[j].GroupID==db->Groups[i].ID){ + Entries.push_back(db->Entries[j]); + Entries.back().GroupID=NewGroupID; + Entries.back().sID=getNewEntrySid();} + } + Groups.push_back(db->Groups[i]); + Groups.back().ID=NewGroupID; +} +} + +bool PwDatabase::isGroupIdInUse(UINT32 id){ +for(int i=0;i +#include +#include "lib/SecString.h" +#include "lib/PwmTime.h" +#include "Database.h" + + +class PwDatabase:QObject,public Database{ + Q_OBJECT +public: + PwDatabase(); + ~ PwDatabase(); + bool loadDatabase(QString filename, QString& err); + bool SaveDataBase(QString filename); + bool NewDataBase(); + bool CloseDataBase(); + bool CalcMasterKeyByPassword(QString& password); + bool CalcMasterKeyByFile(QString filename); + bool CalcMasterKeyByFileAndPw(QString filename, QString& password); + + CGroup* addGroup(CGroup* parent); + GroupItr deleteGroup(CGroup* pGroup); + GroupItr deleteGroup(unsigned long ID); + int getGroupIndex(unsigned long ID); + EntryItr deleteEntry(CEntry* pEntry); + void moveEntry(CEntry* pEntry,CGroup* pDstGroup); + CEntry* addEntry(); + void merge(PwDatabase* db2); + + + +private: + EntryItr deleteEntry(vector::iterator i); + EntryItr getEntryIterator(CEntry* pEntry); + GroupItr getGroupIterator(CGroup* pGroup); + bool IsMetaStream(CEntry& Entry); + void transformKey(UINT8* src,UINT8* dst,UINT8* seed,int rounds); + bool readHeader(char* raw); + bool isGroupIdInUse(UINT32 GroupID); + bool isEntrySidInUse(UINT32 sID); + UINT32 getNewGroupId(); + UINT32 getNewEntrySid(); +}; + +#endif diff --git a/src/PwmConfig.cpp b/src/PwmConfig.cpp new file mode 100755 index 0000000..d6e6479 --- /dev/null +++ b/src/PwmConfig.cpp @@ -0,0 +1,135 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * mail@tarek-saidi.de * + * * + * 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. * + ***************************************************************************/ + +#include "PwmConfig.h" +#include +#include +#include + +bool CConfig::loadFromIni(){ +CIniFile ini(QDir::homeDirPath()+"/.keepass/config"); +ini.ReadFile(); +ClipboardTimeOut=ini.GetValueI("Options","ClipboardTimeOut",20); +Toolbar=ini.GetValueB("UI","ShowToolbar",true); +EntryDetails=ini.GetValueB("UI","ShowEntryDetails",true); +OpenLast=ini.GetValueB("Options","OpenLast",true); +LastFile=ini.GetValue("Options","LastFile",""); +ParseColumnString(ini.GetValue("UI","Columns","1111100000"),Columns); +BannerColor1=ParseColorString(ini.GetValue("Options","BannerColor1","0,104,176")); +BannerColor2=ParseColorString(ini.GetValue("Options","BannerColor2","213,239,255")); +BannerTextColor=ParseColorString(ini.GetValue("Options","BannerTextColor","4,0,80")); +ShowPasswords=ini.GetValueB("Options","ShowPasswords",false); +OpenUrlCommand=ini.GetValue("Options","UrlCmd","kfmclient openURL %1"); +Language=ini.GetValue("Options","LangFile",""); +ParseBoolString(ini.GetValue("Options","SearchOptions","00110111"),SearchOptions,8); +ListView_HidePasswords=ini.GetValueB("UI","HidePasswords",true); +ListView_HideUsernames=ini.GetValueB("UI","HideUsernames",false); +ParseBoolString(ini.GetValue("Options","PwGenOptions","1111100001"),PwGenOptions,10); +PwGenLength=ini.GetValueI("Options","PwGenLength",25); +PwGenCharList=ini.GetValue("Options","PwGenCharList",""); +ExpandGroupTree=ini.GetValueB("Options","ExpandGroupTree",true); +return true; +} + +bool CConfig::saveToIni(){ +CIniFile ini(QDir::homeDirPath()+"/.keepass/config"); +ini.ReadFile(); +ini.SetValueI("Options","ClipboardTimeOut",ClipboardTimeOut); +ini.SetValueB("UI","ShowToolbar",Toolbar); +ini.SetValueB("UI","ShowEntryDetails",EntryDetails); + if(OpenLast)ini.SetValue("Options","LastFile",LastFile); + else ini.SetValue("Options","LastFile",""); +ini.SetValue("UI","Columns",CreateColumnString(),true); +ini.SetValue("Options","BannerColor1",CreateColorString(BannerColor1),true); +ini.SetValue("Options","BannerColor2",CreateColorString(BannerColor2),true); +ini.SetValue("Options","BannerTextColor",CreateColorString(BannerTextColor),true); +ini.SetValueB("Options","ShowPasswords",ShowPasswords,true); +ini.SetValue("Options","UrlCmd",OpenUrlCommand,true); +ini.SetValue("Options","LangFile",Language,true); +ini.SetValue("Options","SearchOptions",CreateBoolString(SearchOptions,8),true); +ini.SetValueB("UI","HidePasswords",ListView_HidePasswords); +ini.SetValueB("UI","HideUsernames",ListView_HideUsernames); +ini.SetValue("Options","PwGenOptions",CreateBoolString(PwGenOptions,10),true); +ini.SetValueI("Options","PwGenLength",PwGenLength,true); +ini.SetValue("Options","PwGenCharList",PwGenCharList,true); +ini.SetValueB("Options","ExpandGroupTree",ExpandGroupTree,true); +if(!ini.WriteFile())return false; +else return true; +} + +void CConfig::ParseColumnString(QString str, bool* dst){ +if(str.length()<10){ +bool _default[]={true,true,true,true,true,false,false,false,false,false}; +memcpy((char*)_default,(char*)dst,10*sizeof(bool));} +for(int i=0; i<10; i++){ +if(str[i]==QChar('0')) + *(dst+i)=false; +else + *(dst+i)=true; + +} + +} + +QString CConfig::CreateColumnString(){ +QString str=""; +for(int i=0;i<10;i++){ +if(Columns[i])str+="1"; +else str+="0"; +} +return str; +} + +QColor CConfig::ParseColorString(QString str){ +QStringList lst=QStringList::split(',',str); +if(lst.size()!=3){ + cout << QObject::trUtf8("Warnung:")+" CConfig::ParseColorString(QString):"+QObject::trUtf8("ungültiger RGB-Farbwert: ") << str << endl; + return QColor(0,0,0);} +bool err[3]; +int r=lst[0].toUInt(err); +int g=lst[1].toUInt(err+1); +int b=lst[2].toUInt(err+2); +if(!err[0] || !err[1] || !err[2]){ + cout << QObject::trUtf8("Warnung:")+" CConfig::ParseColorString(QString):"+QObject::trUtf8("ungültiger RGB-Farbwert: ") << str << endl; + return QColor(0,0,0);} +return QColor(r,g,b); +} + +QString CConfig::CreateColorString(QColor c){ +return (QString::number(c.red())+","+QString::number(c.green())+","+QString::number(c.blue())); +} + +void CConfig::ParseBoolString(const QString &str,bool* dst, int count){ +for(int i=0; i + +class CConfig{ +public: + int TimeFormat; + int ClipboardTimeOut; + bool Toolbar; + bool EntryDetails; + QString LastFile; + bool OpenLast; + bool Columns[10]; + QColor BannerColor1; + QColor BannerColor2; + QColor BannerTextColor; + bool ShowPasswords; + QString OpenUrlCommand; + QString Language; + bool SearchOptions[8]; + bool ListView_HidePasswords; + bool ListView_HideUsernames; + bool PwGenOptions[10]; + int PwGenLength; + QString PwGenCharList; + bool ExpandGroupTree; + + bool loadFromIni(); + bool saveToIni(); + +private: + void ParseColumnString(QString str, bool* dst); + void ParseBoolString(const QString &str,bool* dst, int count); + QString CreateBoolString(bool* src, int count); + QColor ParseColorString(QString str); + QString CreateColumnString(); + QString CreateColorString(QColor); +}; + +#endif \ No newline at end of file diff --git a/src/crypto/blowfish.cpp b/src/crypto/blowfish.cpp new file mode 100755 index 0000000..1ed0248 --- /dev/null +++ b/src/crypto/blowfish.cpp @@ -0,0 +1,541 @@ +/* 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 + * + */ + +#include +#include + +#include "blowfish.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 +}; + +Blowfish::Blowfish() +{ static bool mustSelfTest = false; +} + +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); +} + +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 (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 (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 (buf->size() % 8) + return false; + string::size_type pos = buf->length() - 1; + while ((*buf)[pos] != (char)0x01) { + if (pos == 0) + return false; + --pos; + } + buf->erase(pos, buf->length() - pos); + return true; +} diff --git a/src/crypto/blowfish.h b/src/crypto/blowfish.h new file mode 100755 index 0000000..6c64287 --- /dev/null +++ b/src/crypto/blowfish.h @@ -0,0 +1,110 @@ +/*************************************************************************** + * * + * 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. * + * * + ***************************************************************************/ + +#ifndef BLOWFISH_H +#define BLOWFISH_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(); + + /** 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/src/crypto/rijndael.cpp b/src/crypto/rijndael.cpp new file mode 100755 index 0000000..62f3cca --- /dev/null +++ b/src/crypto/rijndael.cpp @@ -0,0 +1,1605 @@ +// Slightly modified version of Szymon Stefanek's implementation of +// the Rijndael block cipher. + +// +// File : rijndael.cpp +// Creation date : Sun Nov 5 2000 03:22:10 CEST +// Author : Szymon Stefanek (stefanek@tin.it) +// +// Another implementation of the Rijndael cipher. +// This is intended to be an easily usable library file. +// This code is public domain. +// Based on the Vincent Rijmen and K.U.Leuven implementation 2.4. +// + +// +// Original Copyright notice: +// +// rijndael-alg-fst.c v2.4 April '2000 +// rijndael-alg-fst.h +// rijndael-api-fst.c +// rijndael-api-fst.h +// +// Optimised ANSI C code +// +// authors: v1.0: Antoon Bosselaers +// v2.0: Vincent Rijmen, K.U.Leuven +// v2.3: Paulo Barreto +// v2.4: Vincent Rijmen, K.U.Leuven +// +// This code is placed in the public domain. +// + +// +// This implementation works on 128 , 192 , 256 bit keys +// and on 128 bit blocks +// + +#define STRICT_ALIGN 0 +#include +#include "rijndael.h" + + +static UINT8 S[256]= +{ + 99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118, + 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192, + 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21, + 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117, + 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, + 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, + 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168, + 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210, + 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115, + 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, + 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, + 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, + 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, + 112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, + 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, + 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22 +}; + + +static UINT8 T1[256][4]= +{ + 0xc6,0x63,0x63,0xa5, 0xf8,0x7c,0x7c,0x84, 0xee,0x77,0x77,0x99, 0xf6,0x7b,0x7b,0x8d, + 0xff,0xf2,0xf2,0x0d, 0xd6,0x6b,0x6b,0xbd, 0xde,0x6f,0x6f,0xb1, 0x91,0xc5,0xc5,0x54, + 0x60,0x30,0x30,0x50, 0x02,0x01,0x01,0x03, 0xce,0x67,0x67,0xa9, 0x56,0x2b,0x2b,0x7d, + 0xe7,0xfe,0xfe,0x19, 0xb5,0xd7,0xd7,0x62, 0x4d,0xab,0xab,0xe6, 0xec,0x76,0x76,0x9a, + 0x8f,0xca,0xca,0x45, 0x1f,0x82,0x82,0x9d, 0x89,0xc9,0xc9,0x40, 0xfa,0x7d,0x7d,0x87, + 0xef,0xfa,0xfa,0x15, 0xb2,0x59,0x59,0xeb, 0x8e,0x47,0x47,0xc9, 0xfb,0xf0,0xf0,0x0b, + 0x41,0xad,0xad,0xec, 0xb3,0xd4,0xd4,0x67, 0x5f,0xa2,0xa2,0xfd, 0x45,0xaf,0xaf,0xea, + 0x23,0x9c,0x9c,0xbf, 0x53,0xa4,0xa4,0xf7, 0xe4,0x72,0x72,0x96, 0x9b,0xc0,0xc0,0x5b, + 0x75,0xb7,0xb7,0xc2, 0xe1,0xfd,0xfd,0x1c, 0x3d,0x93,0x93,0xae, 0x4c,0x26,0x26,0x6a, + 0x6c,0x36,0x36,0x5a, 0x7e,0x3f,0x3f,0x41, 0xf5,0xf7,0xf7,0x02, 0x83,0xcc,0xcc,0x4f, + 0x68,0x34,0x34,0x5c, 0x51,0xa5,0xa5,0xf4, 0xd1,0xe5,0xe5,0x34, 0xf9,0xf1,0xf1,0x08, + 0xe2,0x71,0x71,0x93, 0xab,0xd8,0xd8,0x73, 0x62,0x31,0x31,0x53, 0x2a,0x15,0x15,0x3f, + 0x08,0x04,0x04,0x0c, 0x95,0xc7,0xc7,0x52, 0x46,0x23,0x23,0x65, 0x9d,0xc3,0xc3,0x5e, + 0x30,0x18,0x18,0x28, 0x37,0x96,0x96,0xa1, 0x0a,0x05,0x05,0x0f, 0x2f,0x9a,0x9a,0xb5, + 0x0e,0x07,0x07,0x09, 0x24,0x12,0x12,0x36, 0x1b,0x80,0x80,0x9b, 0xdf,0xe2,0xe2,0x3d, + 0xcd,0xeb,0xeb,0x26, 0x4e,0x27,0x27,0x69, 0x7f,0xb2,0xb2,0xcd, 0xea,0x75,0x75,0x9f, + 0x12,0x09,0x09,0x1b, 0x1d,0x83,0x83,0x9e, 0x58,0x2c,0x2c,0x74, 0x34,0x1a,0x1a,0x2e, + 0x36,0x1b,0x1b,0x2d, 0xdc,0x6e,0x6e,0xb2, 0xb4,0x5a,0x5a,0xee, 0x5b,0xa0,0xa0,0xfb, + 0xa4,0x52,0x52,0xf6, 0x76,0x3b,0x3b,0x4d, 0xb7,0xd6,0xd6,0x61, 0x7d,0xb3,0xb3,0xce, + 0x52,0x29,0x29,0x7b, 0xdd,0xe3,0xe3,0x3e, 0x5e,0x2f,0x2f,0x71, 0x13,0x84,0x84,0x97, + 0xa6,0x53,0x53,0xf5, 0xb9,0xd1,0xd1,0x68, 0x00,0x00,0x00,0x00, 0xc1,0xed,0xed,0x2c, + 0x40,0x20,0x20,0x60, 0xe3,0xfc,0xfc,0x1f, 0x79,0xb1,0xb1,0xc8, 0xb6,0x5b,0x5b,0xed, + 0xd4,0x6a,0x6a,0xbe, 0x8d,0xcb,0xcb,0x46, 0x67,0xbe,0xbe,0xd9, 0x72,0x39,0x39,0x4b, + 0x94,0x4a,0x4a,0xde, 0x98,0x4c,0x4c,0xd4, 0xb0,0x58,0x58,0xe8, 0x85,0xcf,0xcf,0x4a, + 0xbb,0xd0,0xd0,0x6b, 0xc5,0xef,0xef,0x2a, 0x4f,0xaa,0xaa,0xe5, 0xed,0xfb,0xfb,0x16, + 0x86,0x43,0x43,0xc5, 0x9a,0x4d,0x4d,0xd7, 0x66,0x33,0x33,0x55, 0x11,0x85,0x85,0x94, + 0x8a,0x45,0x45,0xcf, 0xe9,0xf9,0xf9,0x10, 0x04,0x02,0x02,0x06, 0xfe,0x7f,0x7f,0x81, + 0xa0,0x50,0x50,0xf0, 0x78,0x3c,0x3c,0x44, 0x25,0x9f,0x9f,0xba, 0x4b,0xa8,0xa8,0xe3, + 0xa2,0x51,0x51,0xf3, 0x5d,0xa3,0xa3,0xfe, 0x80,0x40,0x40,0xc0, 0x05,0x8f,0x8f,0x8a, + 0x3f,0x92,0x92,0xad, 0x21,0x9d,0x9d,0xbc, 0x70,0x38,0x38,0x48, 0xf1,0xf5,0xf5,0x04, + 0x63,0xbc,0xbc,0xdf, 0x77,0xb6,0xb6,0xc1, 0xaf,0xda,0xda,0x75, 0x42,0x21,0x21,0x63, + 0x20,0x10,0x10,0x30, 0xe5,0xff,0xff,0x1a, 0xfd,0xf3,0xf3,0x0e, 0xbf,0xd2,0xd2,0x6d, + 0x81,0xcd,0xcd,0x4c, 0x18,0x0c,0x0c,0x14, 0x26,0x13,0x13,0x35, 0xc3,0xec,0xec,0x2f, + 0xbe,0x5f,0x5f,0xe1, 0x35,0x97,0x97,0xa2, 0x88,0x44,0x44,0xcc, 0x2e,0x17,0x17,0x39, + 0x93,0xc4,0xc4,0x57, 0x55,0xa7,0xa7,0xf2, 0xfc,0x7e,0x7e,0x82, 0x7a,0x3d,0x3d,0x47, + 0xc8,0x64,0x64,0xac, 0xba,0x5d,0x5d,0xe7, 0x32,0x19,0x19,0x2b, 0xe6,0x73,0x73,0x95, + 0xc0,0x60,0x60,0xa0, 0x19,0x81,0x81,0x98, 0x9e,0x4f,0x4f,0xd1, 0xa3,0xdc,0xdc,0x7f, + 0x44,0x22,0x22,0x66, 0x54,0x2a,0x2a,0x7e, 0x3b,0x90,0x90,0xab, 0x0b,0x88,0x88,0x83, + 0x8c,0x46,0x46,0xca, 0xc7,0xee,0xee,0x29, 0x6b,0xb8,0xb8,0xd3, 0x28,0x14,0x14,0x3c, + 0xa7,0xde,0xde,0x79, 0xbc,0x5e,0x5e,0xe2, 0x16,0x0b,0x0b,0x1d, 0xad,0xdb,0xdb,0x76, + 0xdb,0xe0,0xe0,0x3b, 0x64,0x32,0x32,0x56, 0x74,0x3a,0x3a,0x4e, 0x14,0x0a,0x0a,0x1e, + 0x92,0x49,0x49,0xdb, 0x0c,0x06,0x06,0x0a, 0x48,0x24,0x24,0x6c, 0xb8,0x5c,0x5c,0xe4, + 0x9f,0xc2,0xc2,0x5d, 0xbd,0xd3,0xd3,0x6e, 0x43,0xac,0xac,0xef, 0xc4,0x62,0x62,0xa6, + 0x39,0x91,0x91,0xa8, 0x31,0x95,0x95,0xa4, 0xd3,0xe4,0xe4,0x37, 0xf2,0x79,0x79,0x8b, + 0xd5,0xe7,0xe7,0x32, 0x8b,0xc8,0xc8,0x43, 0x6e,0x37,0x37,0x59, 0xda,0x6d,0x6d,0xb7, + 0x01,0x8d,0x8d,0x8c, 0xb1,0xd5,0xd5,0x64, 0x9c,0x4e,0x4e,0xd2, 0x49,0xa9,0xa9,0xe0, + 0xd8,0x6c,0x6c,0xb4, 0xac,0x56,0x56,0xfa, 0xf3,0xf4,0xf4,0x07, 0xcf,0xea,0xea,0x25, + 0xca,0x65,0x65,0xaf, 0xf4,0x7a,0x7a,0x8e, 0x47,0xae,0xae,0xe9, 0x10,0x08,0x08,0x18, + 0x6f,0xba,0xba,0xd5, 0xf0,0x78,0x78,0x88, 0x4a,0x25,0x25,0x6f, 0x5c,0x2e,0x2e,0x72, + 0x38,0x1c,0x1c,0x24, 0x57,0xa6,0xa6,0xf1, 0x73,0xb4,0xb4,0xc7, 0x97,0xc6,0xc6,0x51, + 0xcb,0xe8,0xe8,0x23, 0xa1,0xdd,0xdd,0x7c, 0xe8,0x74,0x74,0x9c, 0x3e,0x1f,0x1f,0x21, + 0x96,0x4b,0x4b,0xdd, 0x61,0xbd,0xbd,0xdc, 0x0d,0x8b,0x8b,0x86, 0x0f,0x8a,0x8a,0x85, + 0xe0,0x70,0x70,0x90, 0x7c,0x3e,0x3e,0x42, 0x71,0xb5,0xb5,0xc4, 0xcc,0x66,0x66,0xaa, + 0x90,0x48,0x48,0xd8, 0x06,0x03,0x03,0x05, 0xf7,0xf6,0xf6,0x01, 0x1c,0x0e,0x0e,0x12, + 0xc2,0x61,0x61,0xa3, 0x6a,0x35,0x35,0x5f, 0xae,0x57,0x57,0xf9, 0x69,0xb9,0xb9,0xd0, + 0x17,0x86,0x86,0x91, 0x99,0xc1,0xc1,0x58, 0x3a,0x1d,0x1d,0x27, 0x27,0x9e,0x9e,0xb9, + 0xd9,0xe1,0xe1,0x38, 0xeb,0xf8,0xf8,0x13, 0x2b,0x98,0x98,0xb3, 0x22,0x11,0x11,0x33, + 0xd2,0x69,0x69,0xbb, 0xa9,0xd9,0xd9,0x70, 0x07,0x8e,0x8e,0x89, 0x33,0x94,0x94,0xa7, + 0x2d,0x9b,0x9b,0xb6, 0x3c,0x1e,0x1e,0x22, 0x15,0x87,0x87,0x92, 0xc9,0xe9,0xe9,0x20, + 0x87,0xce,0xce,0x49, 0xaa,0x55,0x55,0xff, 0x50,0x28,0x28,0x78, 0xa5,0xdf,0xdf,0x7a, + 0x03,0x8c,0x8c,0x8f, 0x59,0xa1,0xa1,0xf8, 0x09,0x89,0x89,0x80, 0x1a,0x0d,0x0d,0x17, + 0x65,0xbf,0xbf,0xda, 0xd7,0xe6,0xe6,0x31, 0x84,0x42,0x42,0xc6, 0xd0,0x68,0x68,0xb8, + 0x82,0x41,0x41,0xc3, 0x29,0x99,0x99,0xb0, 0x5a,0x2d,0x2d,0x77, 0x1e,0x0f,0x0f,0x11, + 0x7b,0xb0,0xb0,0xcb, 0xa8,0x54,0x54,0xfc, 0x6d,0xbb,0xbb,0xd6, 0x2c,0x16,0x16,0x3a +}; + +static UINT8 T2[256][4]= +{ + 0xa5,0xc6,0x63,0x63, 0x84,0xf8,0x7c,0x7c, 0x99,0xee,0x77,0x77, 0x8d,0xf6,0x7b,0x7b, + 0x0d,0xff,0xf2,0xf2, 0xbd,0xd6,0x6b,0x6b, 0xb1,0xde,0x6f,0x6f, 0x54,0x91,0xc5,0xc5, + 0x50,0x60,0x30,0x30, 0x03,0x02,0x01,0x01, 0xa9,0xce,0x67,0x67, 0x7d,0x56,0x2b,0x2b, + 0x19,0xe7,0xfe,0xfe, 0x62,0xb5,0xd7,0xd7, 0xe6,0x4d,0xab,0xab, 0x9a,0xec,0x76,0x76, + 0x45,0x8f,0xca,0xca, 0x9d,0x1f,0x82,0x82, 0x40,0x89,0xc9,0xc9, 0x87,0xfa,0x7d,0x7d, + 0x15,0xef,0xfa,0xfa, 0xeb,0xb2,0x59,0x59, 0xc9,0x8e,0x47,0x47, 0x0b,0xfb,0xf0,0xf0, + 0xec,0x41,0xad,0xad, 0x67,0xb3,0xd4,0xd4, 0xfd,0x5f,0xa2,0xa2, 0xea,0x45,0xaf,0xaf, + 0xbf,0x23,0x9c,0x9c, 0xf7,0x53,0xa4,0xa4, 0x96,0xe4,0x72,0x72, 0x5b,0x9b,0xc0,0xc0, + 0xc2,0x75,0xb7,0xb7, 0x1c,0xe1,0xfd,0xfd, 0xae,0x3d,0x93,0x93, 0x6a,0x4c,0x26,0x26, + 0x5a,0x6c,0x36,0x36, 0x41,0x7e,0x3f,0x3f, 0x02,0xf5,0xf7,0xf7, 0x4f,0x83,0xcc,0xcc, + 0x5c,0x68,0x34,0x34, 0xf4,0x51,0xa5,0xa5, 0x34,0xd1,0xe5,0xe5, 0x08,0xf9,0xf1,0xf1, + 0x93,0xe2,0x71,0x71, 0x73,0xab,0xd8,0xd8, 0x53,0x62,0x31,0x31, 0x3f,0x2a,0x15,0x15, + 0x0c,0x08,0x04,0x04, 0x52,0x95,0xc7,0xc7, 0x65,0x46,0x23,0x23, 0x5e,0x9d,0xc3,0xc3, + 0x28,0x30,0x18,0x18, 0xa1,0x37,0x96,0x96, 0x0f,0x0a,0x05,0x05, 0xb5,0x2f,0x9a,0x9a, + 0x09,0x0e,0x07,0x07, 0x36,0x24,0x12,0x12, 0x9b,0x1b,0x80,0x80, 0x3d,0xdf,0xe2,0xe2, + 0x26,0xcd,0xeb,0xeb, 0x69,0x4e,0x27,0x27, 0xcd,0x7f,0xb2,0xb2, 0x9f,0xea,0x75,0x75, + 0x1b,0x12,0x09,0x09, 0x9e,0x1d,0x83,0x83, 0x74,0x58,0x2c,0x2c, 0x2e,0x34,0x1a,0x1a, + 0x2d,0x36,0x1b,0x1b, 0xb2,0xdc,0x6e,0x6e, 0xee,0xb4,0x5a,0x5a, 0xfb,0x5b,0xa0,0xa0, + 0xf6,0xa4,0x52,0x52, 0x4d,0x76,0x3b,0x3b, 0x61,0xb7,0xd6,0xd6, 0xce,0x7d,0xb3,0xb3, + 0x7b,0x52,0x29,0x29, 0x3e,0xdd,0xe3,0xe3, 0x71,0x5e,0x2f,0x2f, 0x97,0x13,0x84,0x84, + 0xf5,0xa6,0x53,0x53, 0x68,0xb9,0xd1,0xd1, 0x00,0x00,0x00,0x00, 0x2c,0xc1,0xed,0xed, + 0x60,0x40,0x20,0x20, 0x1f,0xe3,0xfc,0xfc, 0xc8,0x79,0xb1,0xb1, 0xed,0xb6,0x5b,0x5b, + 0xbe,0xd4,0x6a,0x6a, 0x46,0x8d,0xcb,0xcb, 0xd9,0x67,0xbe,0xbe, 0x4b,0x72,0x39,0x39, + 0xde,0x94,0x4a,0x4a, 0xd4,0x98,0x4c,0x4c, 0xe8,0xb0,0x58,0x58, 0x4a,0x85,0xcf,0xcf, + 0x6b,0xbb,0xd0,0xd0, 0x2a,0xc5,0xef,0xef, 0xe5,0x4f,0xaa,0xaa, 0x16,0xed,0xfb,0xfb, + 0xc5,0x86,0x43,0x43, 0xd7,0x9a,0x4d,0x4d, 0x55,0x66,0x33,0x33, 0x94,0x11,0x85,0x85, + 0xcf,0x8a,0x45,0x45, 0x10,0xe9,0xf9,0xf9, 0x06,0x04,0x02,0x02, 0x81,0xfe,0x7f,0x7f, + 0xf0,0xa0,0x50,0x50, 0x44,0x78,0x3c,0x3c, 0xba,0x25,0x9f,0x9f, 0xe3,0x4b,0xa8,0xa8, + 0xf3,0xa2,0x51,0x51, 0xfe,0x5d,0xa3,0xa3, 0xc0,0x80,0x40,0x40, 0x8a,0x05,0x8f,0x8f, + 0xad,0x3f,0x92,0x92, 0xbc,0x21,0x9d,0x9d, 0x48,0x70,0x38,0x38, 0x04,0xf1,0xf5,0xf5, + 0xdf,0x63,0xbc,0xbc, 0xc1,0x77,0xb6,0xb6, 0x75,0xaf,0xda,0xda, 0x63,0x42,0x21,0x21, + 0x30,0x20,0x10,0x10, 0x1a,0xe5,0xff,0xff, 0x0e,0xfd,0xf3,0xf3, 0x6d,0xbf,0xd2,0xd2, + 0x4c,0x81,0xcd,0xcd, 0x14,0x18,0x0c,0x0c, 0x35,0x26,0x13,0x13, 0x2f,0xc3,0xec,0xec, + 0xe1,0xbe,0x5f,0x5f, 0xa2,0x35,0x97,0x97, 0xcc,0x88,0x44,0x44, 0x39,0x2e,0x17,0x17, + 0x57,0x93,0xc4,0xc4, 0xf2,0x55,0xa7,0xa7, 0x82,0xfc,0x7e,0x7e, 0x47,0x7a,0x3d,0x3d, + 0xac,0xc8,0x64,0x64, 0xe7,0xba,0x5d,0x5d, 0x2b,0x32,0x19,0x19, 0x95,0xe6,0x73,0x73, + 0xa0,0xc0,0x60,0x60, 0x98,0x19,0x81,0x81, 0xd1,0x9e,0x4f,0x4f, 0x7f,0xa3,0xdc,0xdc, + 0x66,0x44,0x22,0x22, 0x7e,0x54,0x2a,0x2a, 0xab,0x3b,0x90,0x90, 0x83,0x0b,0x88,0x88, + 0xca,0x8c,0x46,0x46, 0x29,0xc7,0xee,0xee, 0xd3,0x6b,0xb8,0xb8, 0x3c,0x28,0x14,0x14, + 0x79,0xa7,0xde,0xde, 0xe2,0xbc,0x5e,0x5e, 0x1d,0x16,0x0b,0x0b, 0x76,0xad,0xdb,0xdb, + 0x3b,0xdb,0xe0,0xe0, 0x56,0x64,0x32,0x32, 0x4e,0x74,0x3a,0x3a, 0x1e,0x14,0x0a,0x0a, + 0xdb,0x92,0x49,0x49, 0x0a,0x0c,0x06,0x06, 0x6c,0x48,0x24,0x24, 0xe4,0xb8,0x5c,0x5c, + 0x5d,0x9f,0xc2,0xc2, 0x6e,0xbd,0xd3,0xd3, 0xef,0x43,0xac,0xac, 0xa6,0xc4,0x62,0x62, + 0xa8,0x39,0x91,0x91, 0xa4,0x31,0x95,0x95, 0x37,0xd3,0xe4,0xe4, 0x8b,0xf2,0x79,0x79, + 0x32,0xd5,0xe7,0xe7, 0x43,0x8b,0xc8,0xc8, 0x59,0x6e,0x37,0x37, 0xb7,0xda,0x6d,0x6d, + 0x8c,0x01,0x8d,0x8d, 0x64,0xb1,0xd5,0xd5, 0xd2,0x9c,0x4e,0x4e, 0xe0,0x49,0xa9,0xa9, + 0xb4,0xd8,0x6c,0x6c, 0xfa,0xac,0x56,0x56, 0x07,0xf3,0xf4,0xf4, 0x25,0xcf,0xea,0xea, + 0xaf,0xca,0x65,0x65, 0x8e,0xf4,0x7a,0x7a, 0xe9,0x47,0xae,0xae, 0x18,0x10,0x08,0x08, + 0xd5,0x6f,0xba,0xba, 0x88,0xf0,0x78,0x78, 0x6f,0x4a,0x25,0x25, 0x72,0x5c,0x2e,0x2e, + 0x24,0x38,0x1c,0x1c, 0xf1,0x57,0xa6,0xa6, 0xc7,0x73,0xb4,0xb4, 0x51,0x97,0xc6,0xc6, + 0x23,0xcb,0xe8,0xe8, 0x7c,0xa1,0xdd,0xdd, 0x9c,0xe8,0x74,0x74, 0x21,0x3e,0x1f,0x1f, + 0xdd,0x96,0x4b,0x4b, 0xdc,0x61,0xbd,0xbd, 0x86,0x0d,0x8b,0x8b, 0x85,0x0f,0x8a,0x8a, + 0x90,0xe0,0x70,0x70, 0x42,0x7c,0x3e,0x3e, 0xc4,0x71,0xb5,0xb5, 0xaa,0xcc,0x66,0x66, + 0xd8,0x90,0x48,0x48, 0x05,0x06,0x03,0x03, 0x01,0xf7,0xf6,0xf6, 0x12,0x1c,0x0e,0x0e, + 0xa3,0xc2,0x61,0x61, 0x5f,0x6a,0x35,0x35, 0xf9,0xae,0x57,0x57, 0xd0,0x69,0xb9,0xb9, + 0x91,0x17,0x86,0x86, 0x58,0x99,0xc1,0xc1, 0x27,0x3a,0x1d,0x1d, 0xb9,0x27,0x9e,0x9e, + 0x38,0xd9,0xe1,0xe1, 0x13,0xeb,0xf8,0xf8, 0xb3,0x2b,0x98,0x98, 0x33,0x22,0x11,0x11, + 0xbb,0xd2,0x69,0x69, 0x70,0xa9,0xd9,0xd9, 0x89,0x07,0x8e,0x8e, 0xa7,0x33,0x94,0x94, + 0xb6,0x2d,0x9b,0x9b, 0x22,0x3c,0x1e,0x1e, 0x92,0x15,0x87,0x87, 0x20,0xc9,0xe9,0xe9, + 0x49,0x87,0xce,0xce, 0xff,0xaa,0x55,0x55, 0x78,0x50,0x28,0x28, 0x7a,0xa5,0xdf,0xdf, + 0x8f,0x03,0x8c,0x8c, 0xf8,0x59,0xa1,0xa1, 0x80,0x09,0x89,0x89, 0x17,0x1a,0x0d,0x0d, + 0xda,0x65,0xbf,0xbf, 0x31,0xd7,0xe6,0xe6, 0xc6,0x84,0x42,0x42, 0xb8,0xd0,0x68,0x68, + 0xc3,0x82,0x41,0x41, 0xb0,0x29,0x99,0x99, 0x77,0x5a,0x2d,0x2d, 0x11,0x1e,0x0f,0x0f, + 0xcb,0x7b,0xb0,0xb0, 0xfc,0xa8,0x54,0x54, 0xd6,0x6d,0xbb,0xbb, 0x3a,0x2c,0x16,0x16 +}; + +static UINT8 T3[256][4]= +{ + 0x63,0xa5,0xc6,0x63, 0x7c,0x84,0xf8,0x7c, 0x77,0x99,0xee,0x77, 0x7b,0x8d,0xf6,0x7b, + 0xf2,0x0d,0xff,0xf2, 0x6b,0xbd,0xd6,0x6b, 0x6f,0xb1,0xde,0x6f, 0xc5,0x54,0x91,0xc5, + 0x30,0x50,0x60,0x30, 0x01,0x03,0x02,0x01, 0x67,0xa9,0xce,0x67, 0x2b,0x7d,0x56,0x2b, + 0xfe,0x19,0xe7,0xfe, 0xd7,0x62,0xb5,0xd7, 0xab,0xe6,0x4d,0xab, 0x76,0x9a,0xec,0x76, + 0xca,0x45,0x8f,0xca, 0x82,0x9d,0x1f,0x82, 0xc9,0x40,0x89,0xc9, 0x7d,0x87,0xfa,0x7d, + 0xfa,0x15,0xef,0xfa, 0x59,0xeb,0xb2,0x59, 0x47,0xc9,0x8e,0x47, 0xf0,0x0b,0xfb,0xf0, + 0xad,0xec,0x41,0xad, 0xd4,0x67,0xb3,0xd4, 0xa2,0xfd,0x5f,0xa2, 0xaf,0xea,0x45,0xaf, + 0x9c,0xbf,0x23,0x9c, 0xa4,0xf7,0x53,0xa4, 0x72,0x96,0xe4,0x72, 0xc0,0x5b,0x9b,0xc0, + 0xb7,0xc2,0x75,0xb7, 0xfd,0x1c,0xe1,0xfd, 0x93,0xae,0x3d,0x93, 0x26,0x6a,0x4c,0x26, + 0x36,0x5a,0x6c,0x36, 0x3f,0x41,0x7e,0x3f, 0xf7,0x02,0xf5,0xf7, 0xcc,0x4f,0x83,0xcc, + 0x34,0x5c,0x68,0x34, 0xa5,0xf4,0x51,0xa5, 0xe5,0x34,0xd1,0xe5, 0xf1,0x08,0xf9,0xf1, + 0x71,0x93,0xe2,0x71, 0xd8,0x73,0xab,0xd8, 0x31,0x53,0x62,0x31, 0x15,0x3f,0x2a,0x15, + 0x04,0x0c,0x08,0x04, 0xc7,0x52,0x95,0xc7, 0x23,0x65,0x46,0x23, 0xc3,0x5e,0x9d,0xc3, + 0x18,0x28,0x30,0x18, 0x96,0xa1,0x37,0x96, 0x05,0x0f,0x0a,0x05, 0x9a,0xb5,0x2f,0x9a, + 0x07,0x09,0x0e,0x07, 0x12,0x36,0x24,0x12, 0x80,0x9b,0x1b,0x80, 0xe2,0x3d,0xdf,0xe2, + 0xeb,0x26,0xcd,0xeb, 0x27,0x69,0x4e,0x27, 0xb2,0xcd,0x7f,0xb2, 0x75,0x9f,0xea,0x75, + 0x09,0x1b,0x12,0x09, 0x83,0x9e,0x1d,0x83, 0x2c,0x74,0x58,0x2c, 0x1a,0x2e,0x34,0x1a, + 0x1b,0x2d,0x36,0x1b, 0x6e,0xb2,0xdc,0x6e, 0x5a,0xee,0xb4,0x5a, 0xa0,0xfb,0x5b,0xa0, + 0x52,0xf6,0xa4,0x52, 0x3b,0x4d,0x76,0x3b, 0xd6,0x61,0xb7,0xd6, 0xb3,0xce,0x7d,0xb3, + 0x29,0x7b,0x52,0x29, 0xe3,0x3e,0xdd,0xe3, 0x2f,0x71,0x5e,0x2f, 0x84,0x97,0x13,0x84, + 0x53,0xf5,0xa6,0x53, 0xd1,0x68,0xb9,0xd1, 0x00,0x00,0x00,0x00, 0xed,0x2c,0xc1,0xed, + 0x20,0x60,0x40,0x20, 0xfc,0x1f,0xe3,0xfc, 0xb1,0xc8,0x79,0xb1, 0x5b,0xed,0xb6,0x5b, + 0x6a,0xbe,0xd4,0x6a, 0xcb,0x46,0x8d,0xcb, 0xbe,0xd9,0x67,0xbe, 0x39,0x4b,0x72,0x39, + 0x4a,0xde,0x94,0x4a, 0x4c,0xd4,0x98,0x4c, 0x58,0xe8,0xb0,0x58, 0xcf,0x4a,0x85,0xcf, + 0xd0,0x6b,0xbb,0xd0, 0xef,0x2a,0xc5,0xef, 0xaa,0xe5,0x4f,0xaa, 0xfb,0x16,0xed,0xfb, + 0x43,0xc5,0x86,0x43, 0x4d,0xd7,0x9a,0x4d, 0x33,0x55,0x66,0x33, 0x85,0x94,0x11,0x85, + 0x45,0xcf,0x8a,0x45, 0xf9,0x10,0xe9,0xf9, 0x02,0x06,0x04,0x02, 0x7f,0x81,0xfe,0x7f, + 0x50,0xf0,0xa0,0x50, 0x3c,0x44,0x78,0x3c, 0x9f,0xba,0x25,0x9f, 0xa8,0xe3,0x4b,0xa8, + 0x51,0xf3,0xa2,0x51, 0xa3,0xfe,0x5d,0xa3, 0x40,0xc0,0x80,0x40, 0x8f,0x8a,0x05,0x8f, + 0x92,0xad,0x3f,0x92, 0x9d,0xbc,0x21,0x9d, 0x38,0x48,0x70,0x38, 0xf5,0x04,0xf1,0xf5, + 0xbc,0xdf,0x63,0xbc, 0xb6,0xc1,0x77,0xb6, 0xda,0x75,0xaf,0xda, 0x21,0x63,0x42,0x21, + 0x10,0x30,0x20,0x10, 0xff,0x1a,0xe5,0xff, 0xf3,0x0e,0xfd,0xf3, 0xd2,0x6d,0xbf,0xd2, + 0xcd,0x4c,0x81,0xcd, 0x0c,0x14,0x18,0x0c, 0x13,0x35,0x26,0x13, 0xec,0x2f,0xc3,0xec, + 0x5f,0xe1,0xbe,0x5f, 0x97,0xa2,0x35,0x97, 0x44,0xcc,0x88,0x44, 0x17,0x39,0x2e,0x17, + 0xc4,0x57,0x93,0xc4, 0xa7,0xf2,0x55,0xa7, 0x7e,0x82,0xfc,0x7e, 0x3d,0x47,0x7a,0x3d, + 0x64,0xac,0xc8,0x64, 0x5d,0xe7,0xba,0x5d, 0x19,0x2b,0x32,0x19, 0x73,0x95,0xe6,0x73, + 0x60,0xa0,0xc0,0x60, 0x81,0x98,0x19,0x81, 0x4f,0xd1,0x9e,0x4f, 0xdc,0x7f,0xa3,0xdc, + 0x22,0x66,0x44,0x22, 0x2a,0x7e,0x54,0x2a, 0x90,0xab,0x3b,0x90, 0x88,0x83,0x0b,0x88, + 0x46,0xca,0x8c,0x46, 0xee,0x29,0xc7,0xee, 0xb8,0xd3,0x6b,0xb8, 0x14,0x3c,0x28,0x14, + 0xde,0x79,0xa7,0xde, 0x5e,0xe2,0xbc,0x5e, 0x0b,0x1d,0x16,0x0b, 0xdb,0x76,0xad,0xdb, + 0xe0,0x3b,0xdb,0xe0, 0x32,0x56,0x64,0x32, 0x3a,0x4e,0x74,0x3a, 0x0a,0x1e,0x14,0x0a, + 0x49,0xdb,0x92,0x49, 0x06,0x0a,0x0c,0x06, 0x24,0x6c,0x48,0x24, 0x5c,0xe4,0xb8,0x5c, + 0xc2,0x5d,0x9f,0xc2, 0xd3,0x6e,0xbd,0xd3, 0xac,0xef,0x43,0xac, 0x62,0xa6,0xc4,0x62, + 0x91,0xa8,0x39,0x91, 0x95,0xa4,0x31,0x95, 0xe4,0x37,0xd3,0xe4, 0x79,0x8b,0xf2,0x79, + 0xe7,0x32,0xd5,0xe7, 0xc8,0x43,0x8b,0xc8, 0x37,0x59,0x6e,0x37, 0x6d,0xb7,0xda,0x6d, + 0x8d,0x8c,0x01,0x8d, 0xd5,0x64,0xb1,0xd5, 0x4e,0xd2,0x9c,0x4e, 0xa9,0xe0,0x49,0xa9, + 0x6c,0xb4,0xd8,0x6c, 0x56,0xfa,0xac,0x56, 0xf4,0x07,0xf3,0xf4, 0xea,0x25,0xcf,0xea, + 0x65,0xaf,0xca,0x65, 0x7a,0x8e,0xf4,0x7a, 0xae,0xe9,0x47,0xae, 0x08,0x18,0x10,0x08, + 0xba,0xd5,0x6f,0xba, 0x78,0x88,0xf0,0x78, 0x25,0x6f,0x4a,0x25, 0x2e,0x72,0x5c,0x2e, + 0x1c,0x24,0x38,0x1c, 0xa6,0xf1,0x57,0xa6, 0xb4,0xc7,0x73,0xb4, 0xc6,0x51,0x97,0xc6, + 0xe8,0x23,0xcb,0xe8, 0xdd,0x7c,0xa1,0xdd, 0x74,0x9c,0xe8,0x74, 0x1f,0x21,0x3e,0x1f, + 0x4b,0xdd,0x96,0x4b, 0xbd,0xdc,0x61,0xbd, 0x8b,0x86,0x0d,0x8b, 0x8a,0x85,0x0f,0x8a, + 0x70,0x90,0xe0,0x70, 0x3e,0x42,0x7c,0x3e, 0xb5,0xc4,0x71,0xb5, 0x66,0xaa,0xcc,0x66, + 0x48,0xd8,0x90,0x48, 0x03,0x05,0x06,0x03, 0xf6,0x01,0xf7,0xf6, 0x0e,0x12,0x1c,0x0e, + 0x61,0xa3,0xc2,0x61, 0x35,0x5f,0x6a,0x35, 0x57,0xf9,0xae,0x57, 0xb9,0xd0,0x69,0xb9, + 0x86,0x91,0x17,0x86, 0xc1,0x58,0x99,0xc1, 0x1d,0x27,0x3a,0x1d, 0x9e,0xb9,0x27,0x9e, + 0xe1,0x38,0xd9,0xe1, 0xf8,0x13,0xeb,0xf8, 0x98,0xb3,0x2b,0x98, 0x11,0x33,0x22,0x11, + 0x69,0xbb,0xd2,0x69, 0xd9,0x70,0xa9,0xd9, 0x8e,0x89,0x07,0x8e, 0x94,0xa7,0x33,0x94, + 0x9b,0xb6,0x2d,0x9b, 0x1e,0x22,0x3c,0x1e, 0x87,0x92,0x15,0x87, 0xe9,0x20,0xc9,0xe9, + 0xce,0x49,0x87,0xce, 0x55,0xff,0xaa,0x55, 0x28,0x78,0x50,0x28, 0xdf,0x7a,0xa5,0xdf, + 0x8c,0x8f,0x03,0x8c, 0xa1,0xf8,0x59,0xa1, 0x89,0x80,0x09,0x89, 0x0d,0x17,0x1a,0x0d, + 0xbf,0xda,0x65,0xbf, 0xe6,0x31,0xd7,0xe6, 0x42,0xc6,0x84,0x42, 0x68,0xb8,0xd0,0x68, + 0x41,0xc3,0x82,0x41, 0x99,0xb0,0x29,0x99, 0x2d,0x77,0x5a,0x2d, 0x0f,0x11,0x1e,0x0f, + 0xb0,0xcb,0x7b,0xb0, 0x54,0xfc,0xa8,0x54, 0xbb,0xd6,0x6d,0xbb, 0x16,0x3a,0x2c,0x16 +}; + +static UINT8 T4[256][4]= +{ + 0x63,0x63,0xa5,0xc6, 0x7c,0x7c,0x84,0xf8, 0x77,0x77,0x99,0xee, 0x7b,0x7b,0x8d,0xf6, + 0xf2,0xf2,0x0d,0xff, 0x6b,0x6b,0xbd,0xd6, 0x6f,0x6f,0xb1,0xde, 0xc5,0xc5,0x54,0x91, + 0x30,0x30,0x50,0x60, 0x01,0x01,0x03,0x02, 0x67,0x67,0xa9,0xce, 0x2b,0x2b,0x7d,0x56, + 0xfe,0xfe,0x19,0xe7, 0xd7,0xd7,0x62,0xb5, 0xab,0xab,0xe6,0x4d, 0x76,0x76,0x9a,0xec, + 0xca,0xca,0x45,0x8f, 0x82,0x82,0x9d,0x1f, 0xc9,0xc9,0x40,0x89, 0x7d,0x7d,0x87,0xfa, + 0xfa,0xfa,0x15,0xef, 0x59,0x59,0xeb,0xb2, 0x47,0x47,0xc9,0x8e, 0xf0,0xf0,0x0b,0xfb, + 0xad,0xad,0xec,0x41, 0xd4,0xd4,0x67,0xb3, 0xa2,0xa2,0xfd,0x5f, 0xaf,0xaf,0xea,0x45, + 0x9c,0x9c,0xbf,0x23, 0xa4,0xa4,0xf7,0x53, 0x72,0x72,0x96,0xe4, 0xc0,0xc0,0x5b,0x9b, + 0xb7,0xb7,0xc2,0x75, 0xfd,0xfd,0x1c,0xe1, 0x93,0x93,0xae,0x3d, 0x26,0x26,0x6a,0x4c, + 0x36,0x36,0x5a,0x6c, 0x3f,0x3f,0x41,0x7e, 0xf7,0xf7,0x02,0xf5, 0xcc,0xcc,0x4f,0x83, + 0x34,0x34,0x5c,0x68, 0xa5,0xa5,0xf4,0x51, 0xe5,0xe5,0x34,0xd1, 0xf1,0xf1,0x08,0xf9, + 0x71,0x71,0x93,0xe2, 0xd8,0xd8,0x73,0xab, 0x31,0x31,0x53,0x62, 0x15,0x15,0x3f,0x2a, + 0x04,0x04,0x0c,0x08, 0xc7,0xc7,0x52,0x95, 0x23,0x23,0x65,0x46, 0xc3,0xc3,0x5e,0x9d, + 0x18,0x18,0x28,0x30, 0x96,0x96,0xa1,0x37, 0x05,0x05,0x0f,0x0a, 0x9a,0x9a,0xb5,0x2f, + 0x07,0x07,0x09,0x0e, 0x12,0x12,0x36,0x24, 0x80,0x80,0x9b,0x1b, 0xe2,0xe2,0x3d,0xdf, + 0xeb,0xeb,0x26,0xcd, 0x27,0x27,0x69,0x4e, 0xb2,0xb2,0xcd,0x7f, 0x75,0x75,0x9f,0xea, + 0x09,0x09,0x1b,0x12, 0x83,0x83,0x9e,0x1d, 0x2c,0x2c,0x74,0x58, 0x1a,0x1a,0x2e,0x34, + 0x1b,0x1b,0x2d,0x36, 0x6e,0x6e,0xb2,0xdc, 0x5a,0x5a,0xee,0xb4, 0xa0,0xa0,0xfb,0x5b, + 0x52,0x52,0xf6,0xa4, 0x3b,0x3b,0x4d,0x76, 0xd6,0xd6,0x61,0xb7, 0xb3,0xb3,0xce,0x7d, + 0x29,0x29,0x7b,0x52, 0xe3,0xe3,0x3e,0xdd, 0x2f,0x2f,0x71,0x5e, 0x84,0x84,0x97,0x13, + 0x53,0x53,0xf5,0xa6, 0xd1,0xd1,0x68,0xb9, 0x00,0x00,0x00,0x00, 0xed,0xed,0x2c,0xc1, + 0x20,0x20,0x60,0x40, 0xfc,0xfc,0x1f,0xe3, 0xb1,0xb1,0xc8,0x79, 0x5b,0x5b,0xed,0xb6, + 0x6a,0x6a,0xbe,0xd4, 0xcb,0xcb,0x46,0x8d, 0xbe,0xbe,0xd9,0x67, 0x39,0x39,0x4b,0x72, + 0x4a,0x4a,0xde,0x94, 0x4c,0x4c,0xd4,0x98, 0x58,0x58,0xe8,0xb0, 0xcf,0xcf,0x4a,0x85, + 0xd0,0xd0,0x6b,0xbb, 0xef,0xef,0x2a,0xc5, 0xaa,0xaa,0xe5,0x4f, 0xfb,0xfb,0x16,0xed, + 0x43,0x43,0xc5,0x86, 0x4d,0x4d,0xd7,0x9a, 0x33,0x33,0x55,0x66, 0x85,0x85,0x94,0x11, + 0x45,0x45,0xcf,0x8a, 0xf9,0xf9,0x10,0xe9, 0x02,0x02,0x06,0x04, 0x7f,0x7f,0x81,0xfe, + 0x50,0x50,0xf0,0xa0, 0x3c,0x3c,0x44,0x78, 0x9f,0x9f,0xba,0x25, 0xa8,0xa8,0xe3,0x4b, + 0x51,0x51,0xf3,0xa2, 0xa3,0xa3,0xfe,0x5d, 0x40,0x40,0xc0,0x80, 0x8f,0x8f,0x8a,0x05, + 0x92,0x92,0xad,0x3f, 0x9d,0x9d,0xbc,0x21, 0x38,0x38,0x48,0x70, 0xf5,0xf5,0x04,0xf1, + 0xbc,0xbc,0xdf,0x63, 0xb6,0xb6,0xc1,0x77, 0xda,0xda,0x75,0xaf, 0x21,0x21,0x63,0x42, + 0x10,0x10,0x30,0x20, 0xff,0xff,0x1a,0xe5, 0xf3,0xf3,0x0e,0xfd, 0xd2,0xd2,0x6d,0xbf, + 0xcd,0xcd,0x4c,0x81, 0x0c,0x0c,0x14,0x18, 0x13,0x13,0x35,0x26, 0xec,0xec,0x2f,0xc3, + 0x5f,0x5f,0xe1,0xbe, 0x97,0x97,0xa2,0x35, 0x44,0x44,0xcc,0x88, 0x17,0x17,0x39,0x2e, + 0xc4,0xc4,0x57,0x93, 0xa7,0xa7,0xf2,0x55, 0x7e,0x7e,0x82,0xfc, 0x3d,0x3d,0x47,0x7a, + 0x64,0x64,0xac,0xc8, 0x5d,0x5d,0xe7,0xba, 0x19,0x19,0x2b,0x32, 0x73,0x73,0x95,0xe6, + 0x60,0x60,0xa0,0xc0, 0x81,0x81,0x98,0x19, 0x4f,0x4f,0xd1,0x9e, 0xdc,0xdc,0x7f,0xa3, + 0x22,0x22,0x66,0x44, 0x2a,0x2a,0x7e,0x54, 0x90,0x90,0xab,0x3b, 0x88,0x88,0x83,0x0b, + 0x46,0x46,0xca,0x8c, 0xee,0xee,0x29,0xc7, 0xb8,0xb8,0xd3,0x6b, 0x14,0x14,0x3c,0x28, + 0xde,0xde,0x79,0xa7, 0x5e,0x5e,0xe2,0xbc, 0x0b,0x0b,0x1d,0x16, 0xdb,0xdb,0x76,0xad, + 0xe0,0xe0,0x3b,0xdb, 0x32,0x32,0x56,0x64, 0x3a,0x3a,0x4e,0x74, 0x0a,0x0a,0x1e,0x14, + 0x49,0x49,0xdb,0x92, 0x06,0x06,0x0a,0x0c, 0x24,0x24,0x6c,0x48, 0x5c,0x5c,0xe4,0xb8, + 0xc2,0xc2,0x5d,0x9f, 0xd3,0xd3,0x6e,0xbd, 0xac,0xac,0xef,0x43, 0x62,0x62,0xa6,0xc4, + 0x91,0x91,0xa8,0x39, 0x95,0x95,0xa4,0x31, 0xe4,0xe4,0x37,0xd3, 0x79,0x79,0x8b,0xf2, + 0xe7,0xe7,0x32,0xd5, 0xc8,0xc8,0x43,0x8b, 0x37,0x37,0x59,0x6e, 0x6d,0x6d,0xb7,0xda, + 0x8d,0x8d,0x8c,0x01, 0xd5,0xd5,0x64,0xb1, 0x4e,0x4e,0xd2,0x9c, 0xa9,0xa9,0xe0,0x49, + 0x6c,0x6c,0xb4,0xd8, 0x56,0x56,0xfa,0xac, 0xf4,0xf4,0x07,0xf3, 0xea,0xea,0x25,0xcf, + 0x65,0x65,0xaf,0xca, 0x7a,0x7a,0x8e,0xf4, 0xae,0xae,0xe9,0x47, 0x08,0x08,0x18,0x10, + 0xba,0xba,0xd5,0x6f, 0x78,0x78,0x88,0xf0, 0x25,0x25,0x6f,0x4a, 0x2e,0x2e,0x72,0x5c, + 0x1c,0x1c,0x24,0x38, 0xa6,0xa6,0xf1,0x57, 0xb4,0xb4,0xc7,0x73, 0xc6,0xc6,0x51,0x97, + 0xe8,0xe8,0x23,0xcb, 0xdd,0xdd,0x7c,0xa1, 0x74,0x74,0x9c,0xe8, 0x1f,0x1f,0x21,0x3e, + 0x4b,0x4b,0xdd,0x96, 0xbd,0xbd,0xdc,0x61, 0x8b,0x8b,0x86,0x0d, 0x8a,0x8a,0x85,0x0f, + 0x70,0x70,0x90,0xe0, 0x3e,0x3e,0x42,0x7c, 0xb5,0xb5,0xc4,0x71, 0x66,0x66,0xaa,0xcc, + 0x48,0x48,0xd8,0x90, 0x03,0x03,0x05,0x06, 0xf6,0xf6,0x01,0xf7, 0x0e,0x0e,0x12,0x1c, + 0x61,0x61,0xa3,0xc2, 0x35,0x35,0x5f,0x6a, 0x57,0x57,0xf9,0xae, 0xb9,0xb9,0xd0,0x69, + 0x86,0x86,0x91,0x17, 0xc1,0xc1,0x58,0x99, 0x1d,0x1d,0x27,0x3a, 0x9e,0x9e,0xb9,0x27, + 0xe1,0xe1,0x38,0xd9, 0xf8,0xf8,0x13,0xeb, 0x98,0x98,0xb3,0x2b, 0x11,0x11,0x33,0x22, + 0x69,0x69,0xbb,0xd2, 0xd9,0xd9,0x70,0xa9, 0x8e,0x8e,0x89,0x07, 0x94,0x94,0xa7,0x33, + 0x9b,0x9b,0xb6,0x2d, 0x1e,0x1e,0x22,0x3c, 0x87,0x87,0x92,0x15, 0xe9,0xe9,0x20,0xc9, + 0xce,0xce,0x49,0x87, 0x55,0x55,0xff,0xaa, 0x28,0x28,0x78,0x50, 0xdf,0xdf,0x7a,0xa5, + 0x8c,0x8c,0x8f,0x03, 0xa1,0xa1,0xf8,0x59, 0x89,0x89,0x80,0x09, 0x0d,0x0d,0x17,0x1a, + 0xbf,0xbf,0xda,0x65, 0xe6,0xe6,0x31,0xd7, 0x42,0x42,0xc6,0x84, 0x68,0x68,0xb8,0xd0, + 0x41,0x41,0xc3,0x82, 0x99,0x99,0xb0,0x29, 0x2d,0x2d,0x77,0x5a, 0x0f,0x0f,0x11,0x1e, + 0xb0,0xb0,0xcb,0x7b, 0x54,0x54,0xfc,0xa8, 0xbb,0xbb,0xd6,0x6d, 0x16,0x16,0x3a,0x2c +}; + +static UINT8 T5[256][4]= +{ + 0x51,0xf4,0xa7,0x50, 0x7e,0x41,0x65,0x53, 0x1a,0x17,0xa4,0xc3, 0x3a,0x27,0x5e,0x96, + 0x3b,0xab,0x6b,0xcb, 0x1f,0x9d,0x45,0xf1, 0xac,0xfa,0x58,0xab, 0x4b,0xe3,0x03,0x93, + 0x20,0x30,0xfa,0x55, 0xad,0x76,0x6d,0xf6, 0x88,0xcc,0x76,0x91, 0xf5,0x02,0x4c,0x25, + 0x4f,0xe5,0xd7,0xfc, 0xc5,0x2a,0xcb,0xd7, 0x26,0x35,0x44,0x80, 0xb5,0x62,0xa3,0x8f, + 0xde,0xb1,0x5a,0x49, 0x25,0xba,0x1b,0x67, 0x45,0xea,0x0e,0x98, 0x5d,0xfe,0xc0,0xe1, + 0xc3,0x2f,0x75,0x02, 0x81,0x4c,0xf0,0x12, 0x8d,0x46,0x97,0xa3, 0x6b,0xd3,0xf9,0xc6, + 0x03,0x8f,0x5f,0xe7, 0x15,0x92,0x9c,0x95, 0xbf,0x6d,0x7a,0xeb, 0x95,0x52,0x59,0xda, + 0xd4,0xbe,0x83,0x2d, 0x58,0x74,0x21,0xd3, 0x49,0xe0,0x69,0x29, 0x8e,0xc9,0xc8,0x44, + 0x75,0xc2,0x89,0x6a, 0xf4,0x8e,0x79,0x78, 0x99,0x58,0x3e,0x6b, 0x27,0xb9,0x71,0xdd, + 0xbe,0xe1,0x4f,0xb6, 0xf0,0x88,0xad,0x17, 0xc9,0x20,0xac,0x66, 0x7d,0xce,0x3a,0xb4, + 0x63,0xdf,0x4a,0x18, 0xe5,0x1a,0x31,0x82, 0x97,0x51,0x33,0x60, 0x62,0x53,0x7f,0x45, + 0xb1,0x64,0x77,0xe0, 0xbb,0x6b,0xae,0x84, 0xfe,0x81,0xa0,0x1c, 0xf9,0x08,0x2b,0x94, + 0x70,0x48,0x68,0x58, 0x8f,0x45,0xfd,0x19, 0x94,0xde,0x6c,0x87, 0x52,0x7b,0xf8,0xb7, + 0xab,0x73,0xd3,0x23, 0x72,0x4b,0x02,0xe2, 0xe3,0x1f,0x8f,0x57, 0x66,0x55,0xab,0x2a, + 0xb2,0xeb,0x28,0x07, 0x2f,0xb5,0xc2,0x03, 0x86,0xc5,0x7b,0x9a, 0xd3,0x37,0x08,0xa5, + 0x30,0x28,0x87,0xf2, 0x23,0xbf,0xa5,0xb2, 0x02,0x03,0x6a,0xba, 0xed,0x16,0x82,0x5c, + 0x8a,0xcf,0x1c,0x2b, 0xa7,0x79,0xb4,0x92, 0xf3,0x07,0xf2,0xf0, 0x4e,0x69,0xe2,0xa1, + 0x65,0xda,0xf4,0xcd, 0x06,0x05,0xbe,0xd5, 0xd1,0x34,0x62,0x1f, 0xc4,0xa6,0xfe,0x8a, + 0x34,0x2e,0x53,0x9d, 0xa2,0xf3,0x55,0xa0, 0x05,0x8a,0xe1,0x32, 0xa4,0xf6,0xeb,0x75, + 0x0b,0x83,0xec,0x39, 0x40,0x60,0xef,0xaa, 0x5e,0x71,0x9f,0x06, 0xbd,0x6e,0x10,0x51, + 0x3e,0x21,0x8a,0xf9, 0x96,0xdd,0x06,0x3d, 0xdd,0x3e,0x05,0xae, 0x4d,0xe6,0xbd,0x46, + 0x91,0x54,0x8d,0xb5, 0x71,0xc4,0x5d,0x05, 0x04,0x06,0xd4,0x6f, 0x60,0x50,0x15,0xff, + 0x19,0x98,0xfb,0x24, 0xd6,0xbd,0xe9,0x97, 0x89,0x40,0x43,0xcc, 0x67,0xd9,0x9e,0x77, + 0xb0,0xe8,0x42,0xbd, 0x07,0x89,0x8b,0x88, 0xe7,0x19,0x5b,0x38, 0x79,0xc8,0xee,0xdb, + 0xa1,0x7c,0x0a,0x47, 0x7c,0x42,0x0f,0xe9, 0xf8,0x84,0x1e,0xc9, 0x00,0x00,0x00,0x00, + 0x09,0x80,0x86,0x83, 0x32,0x2b,0xed,0x48, 0x1e,0x11,0x70,0xac, 0x6c,0x5a,0x72,0x4e, + 0xfd,0x0e,0xff,0xfb, 0x0f,0x85,0x38,0x56, 0x3d,0xae,0xd5,0x1e, 0x36,0x2d,0x39,0x27, + 0x0a,0x0f,0xd9,0x64, 0x68,0x5c,0xa6,0x21, 0x9b,0x5b,0x54,0xd1, 0x24,0x36,0x2e,0x3a, + 0x0c,0x0a,0x67,0xb1, 0x93,0x57,0xe7,0x0f, 0xb4,0xee,0x96,0xd2, 0x1b,0x9b,0x91,0x9e, + 0x80,0xc0,0xc5,0x4f, 0x61,0xdc,0x20,0xa2, 0x5a,0x77,0x4b,0x69, 0x1c,0x12,0x1a,0x16, + 0xe2,0x93,0xba,0x0a, 0xc0,0xa0,0x2a,0xe5, 0x3c,0x22,0xe0,0x43, 0x12,0x1b,0x17,0x1d, + 0x0e,0x09,0x0d,0x0b, 0xf2,0x8b,0xc7,0xad, 0x2d,0xb6,0xa8,0xb9, 0x14,0x1e,0xa9,0xc8, + 0x57,0xf1,0x19,0x85, 0xaf,0x75,0x07,0x4c, 0xee,0x99,0xdd,0xbb, 0xa3,0x7f,0x60,0xfd, + 0xf7,0x01,0x26,0x9f, 0x5c,0x72,0xf5,0xbc, 0x44,0x66,0x3b,0xc5, 0x5b,0xfb,0x7e,0x34, + 0x8b,0x43,0x29,0x76, 0xcb,0x23,0xc6,0xdc, 0xb6,0xed,0xfc,0x68, 0xb8,0xe4,0xf1,0x63, + 0xd7,0x31,0xdc,0xca, 0x42,0x63,0x85,0x10, 0x13,0x97,0x22,0x40, 0x84,0xc6,0x11,0x20, + 0x85,0x4a,0x24,0x7d, 0xd2,0xbb,0x3d,0xf8, 0xae,0xf9,0x32,0x11, 0xc7,0x29,0xa1,0x6d, + 0x1d,0x9e,0x2f,0x4b, 0xdc,0xb2,0x30,0xf3, 0x0d,0x86,0x52,0xec, 0x77,0xc1,0xe3,0xd0, + 0x2b,0xb3,0x16,0x6c, 0xa9,0x70,0xb9,0x99, 0x11,0x94,0x48,0xfa, 0x47,0xe9,0x64,0x22, + 0xa8,0xfc,0x8c,0xc4, 0xa0,0xf0,0x3f,0x1a, 0x56,0x7d,0x2c,0xd8, 0x22,0x33,0x90,0xef, + 0x87,0x49,0x4e,0xc7, 0xd9,0x38,0xd1,0xc1, 0x8c,0xca,0xa2,0xfe, 0x98,0xd4,0x0b,0x36, + 0xa6,0xf5,0x81,0xcf, 0xa5,0x7a,0xde,0x28, 0xda,0xb7,0x8e,0x26, 0x3f,0xad,0xbf,0xa4, + 0x2c,0x3a,0x9d,0xe4, 0x50,0x78,0x92,0x0d, 0x6a,0x5f,0xcc,0x9b, 0x54,0x7e,0x46,0x62, + 0xf6,0x8d,0x13,0xc2, 0x90,0xd8,0xb8,0xe8, 0x2e,0x39,0xf7,0x5e, 0x82,0xc3,0xaf,0xf5, + 0x9f,0x5d,0x80,0xbe, 0x69,0xd0,0x93,0x7c, 0x6f,0xd5,0x2d,0xa9, 0xcf,0x25,0x12,0xb3, + 0xc8,0xac,0x99,0x3b, 0x10,0x18,0x7d,0xa7, 0xe8,0x9c,0x63,0x6e, 0xdb,0x3b,0xbb,0x7b, + 0xcd,0x26,0x78,0x09, 0x6e,0x59,0x18,0xf4, 0xec,0x9a,0xb7,0x01, 0x83,0x4f,0x9a,0xa8, + 0xe6,0x95,0x6e,0x65, 0xaa,0xff,0xe6,0x7e, 0x21,0xbc,0xcf,0x08, 0xef,0x15,0xe8,0xe6, + 0xba,0xe7,0x9b,0xd9, 0x4a,0x6f,0x36,0xce, 0xea,0x9f,0x09,0xd4, 0x29,0xb0,0x7c,0xd6, + 0x31,0xa4,0xb2,0xaf, 0x2a,0x3f,0x23,0x31, 0xc6,0xa5,0x94,0x30, 0x35,0xa2,0x66,0xc0, + 0x74,0x4e,0xbc,0x37, 0xfc,0x82,0xca,0xa6, 0xe0,0x90,0xd0,0xb0, 0x33,0xa7,0xd8,0x15, + 0xf1,0x04,0x98,0x4a, 0x41,0xec,0xda,0xf7, 0x7f,0xcd,0x50,0x0e, 0x17,0x91,0xf6,0x2f, + 0x76,0x4d,0xd6,0x8d, 0x43,0xef,0xb0,0x4d, 0xcc,0xaa,0x4d,0x54, 0xe4,0x96,0x04,0xdf, + 0x9e,0xd1,0xb5,0xe3, 0x4c,0x6a,0x88,0x1b, 0xc1,0x2c,0x1f,0xb8, 0x46,0x65,0x51,0x7f, + 0x9d,0x5e,0xea,0x04, 0x01,0x8c,0x35,0x5d, 0xfa,0x87,0x74,0x73, 0xfb,0x0b,0x41,0x2e, + 0xb3,0x67,0x1d,0x5a, 0x92,0xdb,0xd2,0x52, 0xe9,0x10,0x56,0x33, 0x6d,0xd6,0x47,0x13, + 0x9a,0xd7,0x61,0x8c, 0x37,0xa1,0x0c,0x7a, 0x59,0xf8,0x14,0x8e, 0xeb,0x13,0x3c,0x89, + 0xce,0xa9,0x27,0xee, 0xb7,0x61,0xc9,0x35, 0xe1,0x1c,0xe5,0xed, 0x7a,0x47,0xb1,0x3c, + 0x9c,0xd2,0xdf,0x59, 0x55,0xf2,0x73,0x3f, 0x18,0x14,0xce,0x79, 0x73,0xc7,0x37,0xbf, + 0x53,0xf7,0xcd,0xea, 0x5f,0xfd,0xaa,0x5b, 0xdf,0x3d,0x6f,0x14, 0x78,0x44,0xdb,0x86, + 0xca,0xaf,0xf3,0x81, 0xb9,0x68,0xc4,0x3e, 0x38,0x24,0x34,0x2c, 0xc2,0xa3,0x40,0x5f, + 0x16,0x1d,0xc3,0x72, 0xbc,0xe2,0x25,0x0c, 0x28,0x3c,0x49,0x8b, 0xff,0x0d,0x95,0x41, + 0x39,0xa8,0x01,0x71, 0x08,0x0c,0xb3,0xde, 0xd8,0xb4,0xe4,0x9c, 0x64,0x56,0xc1,0x90, + 0x7b,0xcb,0x84,0x61, 0xd5,0x32,0xb6,0x70, 0x48,0x6c,0x5c,0x74, 0xd0,0xb8,0x57,0x42 +}; + +static UINT8 T6[256][4]= +{ + 0x50,0x51,0xf4,0xa7, 0x53,0x7e,0x41,0x65, 0xc3,0x1a,0x17,0xa4, 0x96,0x3a,0x27,0x5e, + 0xcb,0x3b,0xab,0x6b, 0xf1,0x1f,0x9d,0x45, 0xab,0xac,0xfa,0x58, 0x93,0x4b,0xe3,0x03, + 0x55,0x20,0x30,0xfa, 0xf6,0xad,0x76,0x6d, 0x91,0x88,0xcc,0x76, 0x25,0xf5,0x02,0x4c, + 0xfc,0x4f,0xe5,0xd7, 0xd7,0xc5,0x2a,0xcb, 0x80,0x26,0x35,0x44, 0x8f,0xb5,0x62,0xa3, + 0x49,0xde,0xb1,0x5a, 0x67,0x25,0xba,0x1b, 0x98,0x45,0xea,0x0e, 0xe1,0x5d,0xfe,0xc0, + 0x02,0xc3,0x2f,0x75, 0x12,0x81,0x4c,0xf0, 0xa3,0x8d,0x46,0x97, 0xc6,0x6b,0xd3,0xf9, + 0xe7,0x03,0x8f,0x5f, 0x95,0x15,0x92,0x9c, 0xeb,0xbf,0x6d,0x7a, 0xda,0x95,0x52,0x59, + 0x2d,0xd4,0xbe,0x83, 0xd3,0x58,0x74,0x21, 0x29,0x49,0xe0,0x69, 0x44,0x8e,0xc9,0xc8, + 0x6a,0x75,0xc2,0x89, 0x78,0xf4,0x8e,0x79, 0x6b,0x99,0x58,0x3e, 0xdd,0x27,0xb9,0x71, + 0xb6,0xbe,0xe1,0x4f, 0x17,0xf0,0x88,0xad, 0x66,0xc9,0x20,0xac, 0xb4,0x7d,0xce,0x3a, + 0x18,0x63,0xdf,0x4a, 0x82,0xe5,0x1a,0x31, 0x60,0x97,0x51,0x33, 0x45,0x62,0x53,0x7f, + 0xe0,0xb1,0x64,0x77, 0x84,0xbb,0x6b,0xae, 0x1c,0xfe,0x81,0xa0, 0x94,0xf9,0x08,0x2b, + 0x58,0x70,0x48,0x68, 0x19,0x8f,0x45,0xfd, 0x87,0x94,0xde,0x6c, 0xb7,0x52,0x7b,0xf8, + 0x23,0xab,0x73,0xd3, 0xe2,0x72,0x4b,0x02, 0x57,0xe3,0x1f,0x8f, 0x2a,0x66,0x55,0xab, + 0x07,0xb2,0xeb,0x28, 0x03,0x2f,0xb5,0xc2, 0x9a,0x86,0xc5,0x7b, 0xa5,0xd3,0x37,0x08, + 0xf2,0x30,0x28,0x87, 0xb2,0x23,0xbf,0xa5, 0xba,0x02,0x03,0x6a, 0x5c,0xed,0x16,0x82, + 0x2b,0x8a,0xcf,0x1c, 0x92,0xa7,0x79,0xb4, 0xf0,0xf3,0x07,0xf2, 0xa1,0x4e,0x69,0xe2, + 0xcd,0x65,0xda,0xf4, 0xd5,0x06,0x05,0xbe, 0x1f,0xd1,0x34,0x62, 0x8a,0xc4,0xa6,0xfe, + 0x9d,0x34,0x2e,0x53, 0xa0,0xa2,0xf3,0x55, 0x32,0x05,0x8a,0xe1, 0x75,0xa4,0xf6,0xeb, + 0x39,0x0b,0x83,0xec, 0xaa,0x40,0x60,0xef, 0x06,0x5e,0x71,0x9f, 0x51,0xbd,0x6e,0x10, + 0xf9,0x3e,0x21,0x8a, 0x3d,0x96,0xdd,0x06, 0xae,0xdd,0x3e,0x05, 0x46,0x4d,0xe6,0xbd, + 0xb5,0x91,0x54,0x8d, 0x05,0x71,0xc4,0x5d, 0x6f,0x04,0x06,0xd4, 0xff,0x60,0x50,0x15, + 0x24,0x19,0x98,0xfb, 0x97,0xd6,0xbd,0xe9, 0xcc,0x89,0x40,0x43, 0x77,0x67,0xd9,0x9e, + 0xbd,0xb0,0xe8,0x42, 0x88,0x07,0x89,0x8b, 0x38,0xe7,0x19,0x5b, 0xdb,0x79,0xc8,0xee, + 0x47,0xa1,0x7c,0x0a, 0xe9,0x7c,0x42,0x0f, 0xc9,0xf8,0x84,0x1e, 0x00,0x00,0x00,0x00, + 0x83,0x09,0x80,0x86, 0x48,0x32,0x2b,0xed, 0xac,0x1e,0x11,0x70, 0x4e,0x6c,0x5a,0x72, + 0xfb,0xfd,0x0e,0xff, 0x56,0x0f,0x85,0x38, 0x1e,0x3d,0xae,0xd5, 0x27,0x36,0x2d,0x39, + 0x64,0x0a,0x0f,0xd9, 0x21,0x68,0x5c,0xa6, 0xd1,0x9b,0x5b,0x54, 0x3a,0x24,0x36,0x2e, + 0xb1,0x0c,0x0a,0x67, 0x0f,0x93,0x57,0xe7, 0xd2,0xb4,0xee,0x96, 0x9e,0x1b,0x9b,0x91, + 0x4f,0x80,0xc0,0xc5, 0xa2,0x61,0xdc,0x20, 0x69,0x5a,0x77,0x4b, 0x16,0x1c,0x12,0x1a, + 0x0a,0xe2,0x93,0xba, 0xe5,0xc0,0xa0,0x2a, 0x43,0x3c,0x22,0xe0, 0x1d,0x12,0x1b,0x17, + 0x0b,0x0e,0x09,0x0d, 0xad,0xf2,0x8b,0xc7, 0xb9,0x2d,0xb6,0xa8, 0xc8,0x14,0x1e,0xa9, + 0x85,0x57,0xf1,0x19, 0x4c,0xaf,0x75,0x07, 0xbb,0xee,0x99,0xdd, 0xfd,0xa3,0x7f,0x60, + 0x9f,0xf7,0x01,0x26, 0xbc,0x5c,0x72,0xf5, 0xc5,0x44,0x66,0x3b, 0x34,0x5b,0xfb,0x7e, + 0x76,0x8b,0x43,0x29, 0xdc,0xcb,0x23,0xc6, 0x68,0xb6,0xed,0xfc, 0x63,0xb8,0xe4,0xf1, + 0xca,0xd7,0x31,0xdc, 0x10,0x42,0x63,0x85, 0x40,0x13,0x97,0x22, 0x20,0x84,0xc6,0x11, + 0x7d,0x85,0x4a,0x24, 0xf8,0xd2,0xbb,0x3d, 0x11,0xae,0xf9,0x32, 0x6d,0xc7,0x29,0xa1, + 0x4b,0x1d,0x9e,0x2f, 0xf3,0xdc,0xb2,0x30, 0xec,0x0d,0x86,0x52, 0xd0,0x77,0xc1,0xe3, + 0x6c,0x2b,0xb3,0x16, 0x99,0xa9,0x70,0xb9, 0xfa,0x11,0x94,0x48, 0x22,0x47,0xe9,0x64, + 0xc4,0xa8,0xfc,0x8c, 0x1a,0xa0,0xf0,0x3f, 0xd8,0x56,0x7d,0x2c, 0xef,0x22,0x33,0x90, + 0xc7,0x87,0x49,0x4e, 0xc1,0xd9,0x38,0xd1, 0xfe,0x8c,0xca,0xa2, 0x36,0x98,0xd4,0x0b, + 0xcf,0xa6,0xf5,0x81, 0x28,0xa5,0x7a,0xde, 0x26,0xda,0xb7,0x8e, 0xa4,0x3f,0xad,0xbf, + 0xe4,0x2c,0x3a,0x9d, 0x0d,0x50,0x78,0x92, 0x9b,0x6a,0x5f,0xcc, 0x62,0x54,0x7e,0x46, + 0xc2,0xf6,0x8d,0x13, 0xe8,0x90,0xd8,0xb8, 0x5e,0x2e,0x39,0xf7, 0xf5,0x82,0xc3,0xaf, + 0xbe,0x9f,0x5d,0x80, 0x7c,0x69,0xd0,0x93, 0xa9,0x6f,0xd5,0x2d, 0xb3,0xcf,0x25,0x12, + 0x3b,0xc8,0xac,0x99, 0xa7,0x10,0x18,0x7d, 0x6e,0xe8,0x9c,0x63, 0x7b,0xdb,0x3b,0xbb, + 0x09,0xcd,0x26,0x78, 0xf4,0x6e,0x59,0x18, 0x01,0xec,0x9a,0xb7, 0xa8,0x83,0x4f,0x9a, + 0x65,0xe6,0x95,0x6e, 0x7e,0xaa,0xff,0xe6, 0x08,0x21,0xbc,0xcf, 0xe6,0xef,0x15,0xe8, + 0xd9,0xba,0xe7,0x9b, 0xce,0x4a,0x6f,0x36, 0xd4,0xea,0x9f,0x09, 0xd6,0x29,0xb0,0x7c, + 0xaf,0x31,0xa4,0xb2, 0x31,0x2a,0x3f,0x23, 0x30,0xc6,0xa5,0x94, 0xc0,0x35,0xa2,0x66, + 0x37,0x74,0x4e,0xbc, 0xa6,0xfc,0x82,0xca, 0xb0,0xe0,0x90,0xd0, 0x15,0x33,0xa7,0xd8, + 0x4a,0xf1,0x04,0x98, 0xf7,0x41,0xec,0xda, 0x0e,0x7f,0xcd,0x50, 0x2f,0x17,0x91,0xf6, + 0x8d,0x76,0x4d,0xd6, 0x4d,0x43,0xef,0xb0, 0x54,0xcc,0xaa,0x4d, 0xdf,0xe4,0x96,0x04, + 0xe3,0x9e,0xd1,0xb5, 0x1b,0x4c,0x6a,0x88, 0xb8,0xc1,0x2c,0x1f, 0x7f,0x46,0x65,0x51, + 0x04,0x9d,0x5e,0xea, 0x5d,0x01,0x8c,0x35, 0x73,0xfa,0x87,0x74, 0x2e,0xfb,0x0b,0x41, + 0x5a,0xb3,0x67,0x1d, 0x52,0x92,0xdb,0xd2, 0x33,0xe9,0x10,0x56, 0x13,0x6d,0xd6,0x47, + 0x8c,0x9a,0xd7,0x61, 0x7a,0x37,0xa1,0x0c, 0x8e,0x59,0xf8,0x14, 0x89,0xeb,0x13,0x3c, + 0xee,0xce,0xa9,0x27, 0x35,0xb7,0x61,0xc9, 0xed,0xe1,0x1c,0xe5, 0x3c,0x7a,0x47,0xb1, + 0x59,0x9c,0xd2,0xdf, 0x3f,0x55,0xf2,0x73, 0x79,0x18,0x14,0xce, 0xbf,0x73,0xc7,0x37, + 0xea,0x53,0xf7,0xcd, 0x5b,0x5f,0xfd,0xaa, 0x14,0xdf,0x3d,0x6f, 0x86,0x78,0x44,0xdb, + 0x81,0xca,0xaf,0xf3, 0x3e,0xb9,0x68,0xc4, 0x2c,0x38,0x24,0x34, 0x5f,0xc2,0xa3,0x40, + 0x72,0x16,0x1d,0xc3, 0x0c,0xbc,0xe2,0x25, 0x8b,0x28,0x3c,0x49, 0x41,0xff,0x0d,0x95, + 0x71,0x39,0xa8,0x01, 0xde,0x08,0x0c,0xb3, 0x9c,0xd8,0xb4,0xe4, 0x90,0x64,0x56,0xc1, + 0x61,0x7b,0xcb,0x84, 0x70,0xd5,0x32,0xb6, 0x74,0x48,0x6c,0x5c, 0x42,0xd0,0xb8,0x57 +}; + +static UINT8 T7[256][4]= +{ + 0xa7,0x50,0x51,0xf4, 0x65,0x53,0x7e,0x41, 0xa4,0xc3,0x1a,0x17, 0x5e,0x96,0x3a,0x27, + 0x6b,0xcb,0x3b,0xab, 0x45,0xf1,0x1f,0x9d, 0x58,0xab,0xac,0xfa, 0x03,0x93,0x4b,0xe3, + 0xfa,0x55,0x20,0x30, 0x6d,0xf6,0xad,0x76, 0x76,0x91,0x88,0xcc, 0x4c,0x25,0xf5,0x02, + 0xd7,0xfc,0x4f,0xe5, 0xcb,0xd7,0xc5,0x2a, 0x44,0x80,0x26,0x35, 0xa3,0x8f,0xb5,0x62, + 0x5a,0x49,0xde,0xb1, 0x1b,0x67,0x25,0xba, 0x0e,0x98,0x45,0xea, 0xc0,0xe1,0x5d,0xfe, + 0x75,0x02,0xc3,0x2f, 0xf0,0x12,0x81,0x4c, 0x97,0xa3,0x8d,0x46, 0xf9,0xc6,0x6b,0xd3, + 0x5f,0xe7,0x03,0x8f, 0x9c,0x95,0x15,0x92, 0x7a,0xeb,0xbf,0x6d, 0x59,0xda,0x95,0x52, + 0x83,0x2d,0xd4,0xbe, 0x21,0xd3,0x58,0x74, 0x69,0x29,0x49,0xe0, 0xc8,0x44,0x8e,0xc9, + 0x89,0x6a,0x75,0xc2, 0x79,0x78,0xf4,0x8e, 0x3e,0x6b,0x99,0x58, 0x71,0xdd,0x27,0xb9, + 0x4f,0xb6,0xbe,0xe1, 0xad,0x17,0xf0,0x88, 0xac,0x66,0xc9,0x20, 0x3a,0xb4,0x7d,0xce, + 0x4a,0x18,0x63,0xdf, 0x31,0x82,0xe5,0x1a, 0x33,0x60,0x97,0x51, 0x7f,0x45,0x62,0x53, + 0x77,0xe0,0xb1,0x64, 0xae,0x84,0xbb,0x6b, 0xa0,0x1c,0xfe,0x81, 0x2b,0x94,0xf9,0x08, + 0x68,0x58,0x70,0x48, 0xfd,0x19,0x8f,0x45, 0x6c,0x87,0x94,0xde, 0xf8,0xb7,0x52,0x7b, + 0xd3,0x23,0xab,0x73, 0x02,0xe2,0x72,0x4b, 0x8f,0x57,0xe3,0x1f, 0xab,0x2a,0x66,0x55, + 0x28,0x07,0xb2,0xeb, 0xc2,0x03,0x2f,0xb5, 0x7b,0x9a,0x86,0xc5, 0x08,0xa5,0xd3,0x37, + 0x87,0xf2,0x30,0x28, 0xa5,0xb2,0x23,0xbf, 0x6a,0xba,0x02,0x03, 0x82,0x5c,0xed,0x16, + 0x1c,0x2b,0x8a,0xcf, 0xb4,0x92,0xa7,0x79, 0xf2,0xf0,0xf3,0x07, 0xe2,0xa1,0x4e,0x69, + 0xf4,0xcd,0x65,0xda, 0xbe,0xd5,0x06,0x05, 0x62,0x1f,0xd1,0x34, 0xfe,0x8a,0xc4,0xa6, + 0x53,0x9d,0x34,0x2e, 0x55,0xa0,0xa2,0xf3, 0xe1,0x32,0x05,0x8a, 0xeb,0x75,0xa4,0xf6, + 0xec,0x39,0x0b,0x83, 0xef,0xaa,0x40,0x60, 0x9f,0x06,0x5e,0x71, 0x10,0x51,0xbd,0x6e, + 0x8a,0xf9,0x3e,0x21, 0x06,0x3d,0x96,0xdd, 0x05,0xae,0xdd,0x3e, 0xbd,0x46,0x4d,0xe6, + 0x8d,0xb5,0x91,0x54, 0x5d,0x05,0x71,0xc4, 0xd4,0x6f,0x04,0x06, 0x15,0xff,0x60,0x50, + 0xfb,0x24,0x19,0x98, 0xe9,0x97,0xd6,0xbd, 0x43,0xcc,0x89,0x40, 0x9e,0x77,0x67,0xd9, + 0x42,0xbd,0xb0,0xe8, 0x8b,0x88,0x07,0x89, 0x5b,0x38,0xe7,0x19, 0xee,0xdb,0x79,0xc8, + 0x0a,0x47,0xa1,0x7c, 0x0f,0xe9,0x7c,0x42, 0x1e,0xc9,0xf8,0x84, 0x00,0x00,0x00,0x00, + 0x86,0x83,0x09,0x80, 0xed,0x48,0x32,0x2b, 0x70,0xac,0x1e,0x11, 0x72,0x4e,0x6c,0x5a, + 0xff,0xfb,0xfd,0x0e, 0x38,0x56,0x0f,0x85, 0xd5,0x1e,0x3d,0xae, 0x39,0x27,0x36,0x2d, + 0xd9,0x64,0x0a,0x0f, 0xa6,0x21,0x68,0x5c, 0x54,0xd1,0x9b,0x5b, 0x2e,0x3a,0x24,0x36, + 0x67,0xb1,0x0c,0x0a, 0xe7,0x0f,0x93,0x57, 0x96,0xd2,0xb4,0xee, 0x91,0x9e,0x1b,0x9b, + 0xc5,0x4f,0x80,0xc0, 0x20,0xa2,0x61,0xdc, 0x4b,0x69,0x5a,0x77, 0x1a,0x16,0x1c,0x12, + 0xba,0x0a,0xe2,0x93, 0x2a,0xe5,0xc0,0xa0, 0xe0,0x43,0x3c,0x22, 0x17,0x1d,0x12,0x1b, + 0x0d,0x0b,0x0e,0x09, 0xc7,0xad,0xf2,0x8b, 0xa8,0xb9,0x2d,0xb6, 0xa9,0xc8,0x14,0x1e, + 0x19,0x85,0x57,0xf1, 0x07,0x4c,0xaf,0x75, 0xdd,0xbb,0xee,0x99, 0x60,0xfd,0xa3,0x7f, + 0x26,0x9f,0xf7,0x01, 0xf5,0xbc,0x5c,0x72, 0x3b,0xc5,0x44,0x66, 0x7e,0x34,0x5b,0xfb, + 0x29,0x76,0x8b,0x43, 0xc6,0xdc,0xcb,0x23, 0xfc,0x68,0xb6,0xed, 0xf1,0x63,0xb8,0xe4, + 0xdc,0xca,0xd7,0x31, 0x85,0x10,0x42,0x63, 0x22,0x40,0x13,0x97, 0x11,0x20,0x84,0xc6, + 0x24,0x7d,0x85,0x4a, 0x3d,0xf8,0xd2,0xbb, 0x32,0x11,0xae,0xf9, 0xa1,0x6d,0xc7,0x29, + 0x2f,0x4b,0x1d,0x9e, 0x30,0xf3,0xdc,0xb2, 0x52,0xec,0x0d,0x86, 0xe3,0xd0,0x77,0xc1, + 0x16,0x6c,0x2b,0xb3, 0xb9,0x99,0xa9,0x70, 0x48,0xfa,0x11,0x94, 0x64,0x22,0x47,0xe9, + 0x8c,0xc4,0xa8,0xfc, 0x3f,0x1a,0xa0,0xf0, 0x2c,0xd8,0x56,0x7d, 0x90,0xef,0x22,0x33, + 0x4e,0xc7,0x87,0x49, 0xd1,0xc1,0xd9,0x38, 0xa2,0xfe,0x8c,0xca, 0x0b,0x36,0x98,0xd4, + 0x81,0xcf,0xa6,0xf5, 0xde,0x28,0xa5,0x7a, 0x8e,0x26,0xda,0xb7, 0xbf,0xa4,0x3f,0xad, + 0x9d,0xe4,0x2c,0x3a, 0x92,0x0d,0x50,0x78, 0xcc,0x9b,0x6a,0x5f, 0x46,0x62,0x54,0x7e, + 0x13,0xc2,0xf6,0x8d, 0xb8,0xe8,0x90,0xd8, 0xf7,0x5e,0x2e,0x39, 0xaf,0xf5,0x82,0xc3, + 0x80,0xbe,0x9f,0x5d, 0x93,0x7c,0x69,0xd0, 0x2d,0xa9,0x6f,0xd5, 0x12,0xb3,0xcf,0x25, + 0x99,0x3b,0xc8,0xac, 0x7d,0xa7,0x10,0x18, 0x63,0x6e,0xe8,0x9c, 0xbb,0x7b,0xdb,0x3b, + 0x78,0x09,0xcd,0x26, 0x18,0xf4,0x6e,0x59, 0xb7,0x01,0xec,0x9a, 0x9a,0xa8,0x83,0x4f, + 0x6e,0x65,0xe6,0x95, 0xe6,0x7e,0xaa,0xff, 0xcf,0x08,0x21,0xbc, 0xe8,0xe6,0xef,0x15, + 0x9b,0xd9,0xba,0xe7, 0x36,0xce,0x4a,0x6f, 0x09,0xd4,0xea,0x9f, 0x7c,0xd6,0x29,0xb0, + 0xb2,0xaf,0x31,0xa4, 0x23,0x31,0x2a,0x3f, 0x94,0x30,0xc6,0xa5, 0x66,0xc0,0x35,0xa2, + 0xbc,0x37,0x74,0x4e, 0xca,0xa6,0xfc,0x82, 0xd0,0xb0,0xe0,0x90, 0xd8,0x15,0x33,0xa7, + 0x98,0x4a,0xf1,0x04, 0xda,0xf7,0x41,0xec, 0x50,0x0e,0x7f,0xcd, 0xf6,0x2f,0x17,0x91, + 0xd6,0x8d,0x76,0x4d, 0xb0,0x4d,0x43,0xef, 0x4d,0x54,0xcc,0xaa, 0x04,0xdf,0xe4,0x96, + 0xb5,0xe3,0x9e,0xd1, 0x88,0x1b,0x4c,0x6a, 0x1f,0xb8,0xc1,0x2c, 0x51,0x7f,0x46,0x65, + 0xea,0x04,0x9d,0x5e, 0x35,0x5d,0x01,0x8c, 0x74,0x73,0xfa,0x87, 0x41,0x2e,0xfb,0x0b, + 0x1d,0x5a,0xb3,0x67, 0xd2,0x52,0x92,0xdb, 0x56,0x33,0xe9,0x10, 0x47,0x13,0x6d,0xd6, + 0x61,0x8c,0x9a,0xd7, 0x0c,0x7a,0x37,0xa1, 0x14,0x8e,0x59,0xf8, 0x3c,0x89,0xeb,0x13, + 0x27,0xee,0xce,0xa9, 0xc9,0x35,0xb7,0x61, 0xe5,0xed,0xe1,0x1c, 0xb1,0x3c,0x7a,0x47, + 0xdf,0x59,0x9c,0xd2, 0x73,0x3f,0x55,0xf2, 0xce,0x79,0x18,0x14, 0x37,0xbf,0x73,0xc7, + 0xcd,0xea,0x53,0xf7, 0xaa,0x5b,0x5f,0xfd, 0x6f,0x14,0xdf,0x3d, 0xdb,0x86,0x78,0x44, + 0xf3,0x81,0xca,0xaf, 0xc4,0x3e,0xb9,0x68, 0x34,0x2c,0x38,0x24, 0x40,0x5f,0xc2,0xa3, + 0xc3,0x72,0x16,0x1d, 0x25,0x0c,0xbc,0xe2, 0x49,0x8b,0x28,0x3c, 0x95,0x41,0xff,0x0d, + 0x01,0x71,0x39,0xa8, 0xb3,0xde,0x08,0x0c, 0xe4,0x9c,0xd8,0xb4, 0xc1,0x90,0x64,0x56, + 0x84,0x61,0x7b,0xcb, 0xb6,0x70,0xd5,0x32, 0x5c,0x74,0x48,0x6c, 0x57,0x42,0xd0,0xb8 +}; + +static UINT8 T8[256][4]= +{ + 0xf4,0xa7,0x50,0x51, 0x41,0x65,0x53,0x7e, 0x17,0xa4,0xc3,0x1a, 0x27,0x5e,0x96,0x3a, + 0xab,0x6b,0xcb,0x3b, 0x9d,0x45,0xf1,0x1f, 0xfa,0x58,0xab,0xac, 0xe3,0x03,0x93,0x4b, + 0x30,0xfa,0x55,0x20, 0x76,0x6d,0xf6,0xad, 0xcc,0x76,0x91,0x88, 0x02,0x4c,0x25,0xf5, + 0xe5,0xd7,0xfc,0x4f, 0x2a,0xcb,0xd7,0xc5, 0x35,0x44,0x80,0x26, 0x62,0xa3,0x8f,0xb5, + 0xb1,0x5a,0x49,0xde, 0xba,0x1b,0x67,0x25, 0xea,0x0e,0x98,0x45, 0xfe,0xc0,0xe1,0x5d, + 0x2f,0x75,0x02,0xc3, 0x4c,0xf0,0x12,0x81, 0x46,0x97,0xa3,0x8d, 0xd3,0xf9,0xc6,0x6b, + 0x8f,0x5f,0xe7,0x03, 0x92,0x9c,0x95,0x15, 0x6d,0x7a,0xeb,0xbf, 0x52,0x59,0xda,0x95, + 0xbe,0x83,0x2d,0xd4, 0x74,0x21,0xd3,0x58, 0xe0,0x69,0x29,0x49, 0xc9,0xc8,0x44,0x8e, + 0xc2,0x89,0x6a,0x75, 0x8e,0x79,0x78,0xf4, 0x58,0x3e,0x6b,0x99, 0xb9,0x71,0xdd,0x27, + 0xe1,0x4f,0xb6,0xbe, 0x88,0xad,0x17,0xf0, 0x20,0xac,0x66,0xc9, 0xce,0x3a,0xb4,0x7d, + 0xdf,0x4a,0x18,0x63, 0x1a,0x31,0x82,0xe5, 0x51,0x33,0x60,0x97, 0x53,0x7f,0x45,0x62, + 0x64,0x77,0xe0,0xb1, 0x6b,0xae,0x84,0xbb, 0x81,0xa0,0x1c,0xfe, 0x08,0x2b,0x94,0xf9, + 0x48,0x68,0x58,0x70, 0x45,0xfd,0x19,0x8f, 0xde,0x6c,0x87,0x94, 0x7b,0xf8,0xb7,0x52, + 0x73,0xd3,0x23,0xab, 0x4b,0x02,0xe2,0x72, 0x1f,0x8f,0x57,0xe3, 0x55,0xab,0x2a,0x66, + 0xeb,0x28,0x07,0xb2, 0xb5,0xc2,0x03,0x2f, 0xc5,0x7b,0x9a,0x86, 0x37,0x08,0xa5,0xd3, + 0x28,0x87,0xf2,0x30, 0xbf,0xa5,0xb2,0x23, 0x03,0x6a,0xba,0x02, 0x16,0x82,0x5c,0xed, + 0xcf,0x1c,0x2b,0x8a, 0x79,0xb4,0x92,0xa7, 0x07,0xf2,0xf0,0xf3, 0x69,0xe2,0xa1,0x4e, + 0xda,0xf4,0xcd,0x65, 0x05,0xbe,0xd5,0x06, 0x34,0x62,0x1f,0xd1, 0xa6,0xfe,0x8a,0xc4, + 0x2e,0x53,0x9d,0x34, 0xf3,0x55,0xa0,0xa2, 0x8a,0xe1,0x32,0x05, 0xf6,0xeb,0x75,0xa4, + 0x83,0xec,0x39,0x0b, 0x60,0xef,0xaa,0x40, 0x71,0x9f,0x06,0x5e, 0x6e,0x10,0x51,0xbd, + 0x21,0x8a,0xf9,0x3e, 0xdd,0x06,0x3d,0x96, 0x3e,0x05,0xae,0xdd, 0xe6,0xbd,0x46,0x4d, + 0x54,0x8d,0xb5,0x91, 0xc4,0x5d,0x05,0x71, 0x06,0xd4,0x6f,0x04, 0x50,0x15,0xff,0x60, + 0x98,0xfb,0x24,0x19, 0xbd,0xe9,0x97,0xd6, 0x40,0x43,0xcc,0x89, 0xd9,0x9e,0x77,0x67, + 0xe8,0x42,0xbd,0xb0, 0x89,0x8b,0x88,0x07, 0x19,0x5b,0x38,0xe7, 0xc8,0xee,0xdb,0x79, + 0x7c,0x0a,0x47,0xa1, 0x42,0x0f,0xe9,0x7c, 0x84,0x1e,0xc9,0xf8, 0x00,0x00,0x00,0x00, + 0x80,0x86,0x83,0x09, 0x2b,0xed,0x48,0x32, 0x11,0x70,0xac,0x1e, 0x5a,0x72,0x4e,0x6c, + 0x0e,0xff,0xfb,0xfd, 0x85,0x38,0x56,0x0f, 0xae,0xd5,0x1e,0x3d, 0x2d,0x39,0x27,0x36, + 0x0f,0xd9,0x64,0x0a, 0x5c,0xa6,0x21,0x68, 0x5b,0x54,0xd1,0x9b, 0x36,0x2e,0x3a,0x24, + 0x0a,0x67,0xb1,0x0c, 0x57,0xe7,0x0f,0x93, 0xee,0x96,0xd2,0xb4, 0x9b,0x91,0x9e,0x1b, + 0xc0,0xc5,0x4f,0x80, 0xdc,0x20,0xa2,0x61, 0x77,0x4b,0x69,0x5a, 0x12,0x1a,0x16,0x1c, + 0x93,0xba,0x0a,0xe2, 0xa0,0x2a,0xe5,0xc0, 0x22,0xe0,0x43,0x3c, 0x1b,0x17,0x1d,0x12, + 0x09,0x0d,0x0b,0x0e, 0x8b,0xc7,0xad,0xf2, 0xb6,0xa8,0xb9,0x2d, 0x1e,0xa9,0xc8,0x14, + 0xf1,0x19,0x85,0x57, 0x75,0x07,0x4c,0xaf, 0x99,0xdd,0xbb,0xee, 0x7f,0x60,0xfd,0xa3, + 0x01,0x26,0x9f,0xf7, 0x72,0xf5,0xbc,0x5c, 0x66,0x3b,0xc5,0x44, 0xfb,0x7e,0x34,0x5b, + 0x43,0x29,0x76,0x8b, 0x23,0xc6,0xdc,0xcb, 0xed,0xfc,0x68,0xb6, 0xe4,0xf1,0x63,0xb8, + 0x31,0xdc,0xca,0xd7, 0x63,0x85,0x10,0x42, 0x97,0x22,0x40,0x13, 0xc6,0x11,0x20,0x84, + 0x4a,0x24,0x7d,0x85, 0xbb,0x3d,0xf8,0xd2, 0xf9,0x32,0x11,0xae, 0x29,0xa1,0x6d,0xc7, + 0x9e,0x2f,0x4b,0x1d, 0xb2,0x30,0xf3,0xdc, 0x86,0x52,0xec,0x0d, 0xc1,0xe3,0xd0,0x77, + 0xb3,0x16,0x6c,0x2b, 0x70,0xb9,0x99,0xa9, 0x94,0x48,0xfa,0x11, 0xe9,0x64,0x22,0x47, + 0xfc,0x8c,0xc4,0xa8, 0xf0,0x3f,0x1a,0xa0, 0x7d,0x2c,0xd8,0x56, 0x33,0x90,0xef,0x22, + 0x49,0x4e,0xc7,0x87, 0x38,0xd1,0xc1,0xd9, 0xca,0xa2,0xfe,0x8c, 0xd4,0x0b,0x36,0x98, + 0xf5,0x81,0xcf,0xa6, 0x7a,0xde,0x28,0xa5, 0xb7,0x8e,0x26,0xda, 0xad,0xbf,0xa4,0x3f, + 0x3a,0x9d,0xe4,0x2c, 0x78,0x92,0x0d,0x50, 0x5f,0xcc,0x9b,0x6a, 0x7e,0x46,0x62,0x54, + 0x8d,0x13,0xc2,0xf6, 0xd8,0xb8,0xe8,0x90, 0x39,0xf7,0x5e,0x2e, 0xc3,0xaf,0xf5,0x82, + 0x5d,0x80,0xbe,0x9f, 0xd0,0x93,0x7c,0x69, 0xd5,0x2d,0xa9,0x6f, 0x25,0x12,0xb3,0xcf, + 0xac,0x99,0x3b,0xc8, 0x18,0x7d,0xa7,0x10, 0x9c,0x63,0x6e,0xe8, 0x3b,0xbb,0x7b,0xdb, + 0x26,0x78,0x09,0xcd, 0x59,0x18,0xf4,0x6e, 0x9a,0xb7,0x01,0xec, 0x4f,0x9a,0xa8,0x83, + 0x95,0x6e,0x65,0xe6, 0xff,0xe6,0x7e,0xaa, 0xbc,0xcf,0x08,0x21, 0x15,0xe8,0xe6,0xef, + 0xe7,0x9b,0xd9,0xba, 0x6f,0x36,0xce,0x4a, 0x9f,0x09,0xd4,0xea, 0xb0,0x7c,0xd6,0x29, + 0xa4,0xb2,0xaf,0x31, 0x3f,0x23,0x31,0x2a, 0xa5,0x94,0x30,0xc6, 0xa2,0x66,0xc0,0x35, + 0x4e,0xbc,0x37,0x74, 0x82,0xca,0xa6,0xfc, 0x90,0xd0,0xb0,0xe0, 0xa7,0xd8,0x15,0x33, + 0x04,0x98,0x4a,0xf1, 0xec,0xda,0xf7,0x41, 0xcd,0x50,0x0e,0x7f, 0x91,0xf6,0x2f,0x17, + 0x4d,0xd6,0x8d,0x76, 0xef,0xb0,0x4d,0x43, 0xaa,0x4d,0x54,0xcc, 0x96,0x04,0xdf,0xe4, + 0xd1,0xb5,0xe3,0x9e, 0x6a,0x88,0x1b,0x4c, 0x2c,0x1f,0xb8,0xc1, 0x65,0x51,0x7f,0x46, + 0x5e,0xea,0x04,0x9d, 0x8c,0x35,0x5d,0x01, 0x87,0x74,0x73,0xfa, 0x0b,0x41,0x2e,0xfb, + 0x67,0x1d,0x5a,0xb3, 0xdb,0xd2,0x52,0x92, 0x10,0x56,0x33,0xe9, 0xd6,0x47,0x13,0x6d, + 0xd7,0x61,0x8c,0x9a, 0xa1,0x0c,0x7a,0x37, 0xf8,0x14,0x8e,0x59, 0x13,0x3c,0x89,0xeb, + 0xa9,0x27,0xee,0xce, 0x61,0xc9,0x35,0xb7, 0x1c,0xe5,0xed,0xe1, 0x47,0xb1,0x3c,0x7a, + 0xd2,0xdf,0x59,0x9c, 0xf2,0x73,0x3f,0x55, 0x14,0xce,0x79,0x18, 0xc7,0x37,0xbf,0x73, + 0xf7,0xcd,0xea,0x53, 0xfd,0xaa,0x5b,0x5f, 0x3d,0x6f,0x14,0xdf, 0x44,0xdb,0x86,0x78, + 0xaf,0xf3,0x81,0xca, 0x68,0xc4,0x3e,0xb9, 0x24,0x34,0x2c,0x38, 0xa3,0x40,0x5f,0xc2, + 0x1d,0xc3,0x72,0x16, 0xe2,0x25,0x0c,0xbc, 0x3c,0x49,0x8b,0x28, 0x0d,0x95,0x41,0xff, + 0xa8,0x01,0x71,0x39, 0x0c,0xb3,0xde,0x08, 0xb4,0xe4,0x9c,0xd8, 0x56,0xc1,0x90,0x64, + 0xcb,0x84,0x61,0x7b, 0x32,0xb6,0x70,0xd5, 0x6c,0x5c,0x74,0x48, 0xb8,0x57,0x42,0xd0 +}; + +static UINT8 S5[256]= +{ + 0x52,0x09,0x6a,0xd5, + 0x30,0x36,0xa5,0x38, + 0xbf,0x40,0xa3,0x9e, + 0x81,0xf3,0xd7,0xfb, + 0x7c,0xe3,0x39,0x82, + 0x9b,0x2f,0xff,0x87, + 0x34,0x8e,0x43,0x44, + 0xc4,0xde,0xe9,0xcb, + 0x54,0x7b,0x94,0x32, + 0xa6,0xc2,0x23,0x3d, + 0xee,0x4c,0x95,0x0b, + 0x42,0xfa,0xc3,0x4e, + 0x08,0x2e,0xa1,0x66, + 0x28,0xd9,0x24,0xb2, + 0x76,0x5b,0xa2,0x49, + 0x6d,0x8b,0xd1,0x25, + 0x72,0xf8,0xf6,0x64, + 0x86,0x68,0x98,0x16, + 0xd4,0xa4,0x5c,0xcc, + 0x5d,0x65,0xb6,0x92, + 0x6c,0x70,0x48,0x50, + 0xfd,0xed,0xb9,0xda, + 0x5e,0x15,0x46,0x57, + 0xa7,0x8d,0x9d,0x84, + 0x90,0xd8,0xab,0x00, + 0x8c,0xbc,0xd3,0x0a, + 0xf7,0xe4,0x58,0x05, + 0xb8,0xb3,0x45,0x06, + 0xd0,0x2c,0x1e,0x8f, + 0xca,0x3f,0x0f,0x02, + 0xc1,0xaf,0xbd,0x03, + 0x01,0x13,0x8a,0x6b, + 0x3a,0x91,0x11,0x41, + 0x4f,0x67,0xdc,0xea, + 0x97,0xf2,0xcf,0xce, + 0xf0,0xb4,0xe6,0x73, + 0x96,0xac,0x74,0x22, + 0xe7,0xad,0x35,0x85, + 0xe2,0xf9,0x37,0xe8, + 0x1c,0x75,0xdf,0x6e, + 0x47,0xf1,0x1a,0x71, + 0x1d,0x29,0xc5,0x89, + 0x6f,0xb7,0x62,0x0e, + 0xaa,0x18,0xbe,0x1b, + 0xfc,0x56,0x3e,0x4b, + 0xc6,0xd2,0x79,0x20, + 0x9a,0xdb,0xc0,0xfe, + 0x78,0xcd,0x5a,0xf4, + 0x1f,0xdd,0xa8,0x33, + 0x88,0x07,0xc7,0x31, + 0xb1,0x12,0x10,0x59, + 0x27,0x80,0xec,0x5f, + 0x60,0x51,0x7f,0xa9, + 0x19,0xb5,0x4a,0x0d, + 0x2d,0xe5,0x7a,0x9f, + 0x93,0xc9,0x9c,0xef, + 0xa0,0xe0,0x3b,0x4d, + 0xae,0x2a,0xf5,0xb0, + 0xc8,0xeb,0xbb,0x3c, + 0x83,0x53,0x99,0x61, + 0x17,0x2b,0x04,0x7e, + 0xba,0x77,0xd6,0x26, + 0xe1,0x69,0x14,0x63, + 0x55,0x21,0x0c,0x7d +}; + +static UINT8 U1[256][4]= +{ + 0x00,0x00,0x00,0x00, 0x0e,0x09,0x0d,0x0b, 0x1c,0x12,0x1a,0x16, 0x12,0x1b,0x17,0x1d, + 0x38,0x24,0x34,0x2c, 0x36,0x2d,0x39,0x27, 0x24,0x36,0x2e,0x3a, 0x2a,0x3f,0x23,0x31, + 0x70,0x48,0x68,0x58, 0x7e,0x41,0x65,0x53, 0x6c,0x5a,0x72,0x4e, 0x62,0x53,0x7f,0x45, + 0x48,0x6c,0x5c,0x74, 0x46,0x65,0x51,0x7f, 0x54,0x7e,0x46,0x62, 0x5a,0x77,0x4b,0x69, + 0xe0,0x90,0xd0,0xb0, 0xee,0x99,0xdd,0xbb, 0xfc,0x82,0xca,0xa6, 0xf2,0x8b,0xc7,0xad, + 0xd8,0xb4,0xe4,0x9c, 0xd6,0xbd,0xe9,0x97, 0xc4,0xa6,0xfe,0x8a, 0xca,0xaf,0xf3,0x81, + 0x90,0xd8,0xb8,0xe8, 0x9e,0xd1,0xb5,0xe3, 0x8c,0xca,0xa2,0xfe, 0x82,0xc3,0xaf,0xf5, + 0xa8,0xfc,0x8c,0xc4, 0xa6,0xf5,0x81,0xcf, 0xb4,0xee,0x96,0xd2, 0xba,0xe7,0x9b,0xd9, + 0xdb,0x3b,0xbb,0x7b, 0xd5,0x32,0xb6,0x70, 0xc7,0x29,0xa1,0x6d, 0xc9,0x20,0xac,0x66, + 0xe3,0x1f,0x8f,0x57, 0xed,0x16,0x82,0x5c, 0xff,0x0d,0x95,0x41, 0xf1,0x04,0x98,0x4a, + 0xab,0x73,0xd3,0x23, 0xa5,0x7a,0xde,0x28, 0xb7,0x61,0xc9,0x35, 0xb9,0x68,0xc4,0x3e, + 0x93,0x57,0xe7,0x0f, 0x9d,0x5e,0xea,0x04, 0x8f,0x45,0xfd,0x19, 0x81,0x4c,0xf0,0x12, + 0x3b,0xab,0x6b,0xcb, 0x35,0xa2,0x66,0xc0, 0x27,0xb9,0x71,0xdd, 0x29,0xb0,0x7c,0xd6, + 0x03,0x8f,0x5f,0xe7, 0x0d,0x86,0x52,0xec, 0x1f,0x9d,0x45,0xf1, 0x11,0x94,0x48,0xfa, + 0x4b,0xe3,0x03,0x93, 0x45,0xea,0x0e,0x98, 0x57,0xf1,0x19,0x85, 0x59,0xf8,0x14,0x8e, + 0x73,0xc7,0x37,0xbf, 0x7d,0xce,0x3a,0xb4, 0x6f,0xd5,0x2d,0xa9, 0x61,0xdc,0x20,0xa2, + 0xad,0x76,0x6d,0xf6, 0xa3,0x7f,0x60,0xfd, 0xb1,0x64,0x77,0xe0, 0xbf,0x6d,0x7a,0xeb, + 0x95,0x52,0x59,0xda, 0x9b,0x5b,0x54,0xd1, 0x89,0x40,0x43,0xcc, 0x87,0x49,0x4e,0xc7, + 0xdd,0x3e,0x05,0xae, 0xd3,0x37,0x08,0xa5, 0xc1,0x2c,0x1f,0xb8, 0xcf,0x25,0x12,0xb3, + 0xe5,0x1a,0x31,0x82, 0xeb,0x13,0x3c,0x89, 0xf9,0x08,0x2b,0x94, 0xf7,0x01,0x26,0x9f, + 0x4d,0xe6,0xbd,0x46, 0x43,0xef,0xb0,0x4d, 0x51,0xf4,0xa7,0x50, 0x5f,0xfd,0xaa,0x5b, + 0x75,0xc2,0x89,0x6a, 0x7b,0xcb,0x84,0x61, 0x69,0xd0,0x93,0x7c, 0x67,0xd9,0x9e,0x77, + 0x3d,0xae,0xd5,0x1e, 0x33,0xa7,0xd8,0x15, 0x21,0xbc,0xcf,0x08, 0x2f,0xb5,0xc2,0x03, + 0x05,0x8a,0xe1,0x32, 0x0b,0x83,0xec,0x39, 0x19,0x98,0xfb,0x24, 0x17,0x91,0xf6,0x2f, + 0x76,0x4d,0xd6,0x8d, 0x78,0x44,0xdb,0x86, 0x6a,0x5f,0xcc,0x9b, 0x64,0x56,0xc1,0x90, + 0x4e,0x69,0xe2,0xa1, 0x40,0x60,0xef,0xaa, 0x52,0x7b,0xf8,0xb7, 0x5c,0x72,0xf5,0xbc, + 0x06,0x05,0xbe,0xd5, 0x08,0x0c,0xb3,0xde, 0x1a,0x17,0xa4,0xc3, 0x14,0x1e,0xa9,0xc8, + 0x3e,0x21,0x8a,0xf9, 0x30,0x28,0x87,0xf2, 0x22,0x33,0x90,0xef, 0x2c,0x3a,0x9d,0xe4, + 0x96,0xdd,0x06,0x3d, 0x98,0xd4,0x0b,0x36, 0x8a,0xcf,0x1c,0x2b, 0x84,0xc6,0x11,0x20, + 0xae,0xf9,0x32,0x11, 0xa0,0xf0,0x3f,0x1a, 0xb2,0xeb,0x28,0x07, 0xbc,0xe2,0x25,0x0c, + 0xe6,0x95,0x6e,0x65, 0xe8,0x9c,0x63,0x6e, 0xfa,0x87,0x74,0x73, 0xf4,0x8e,0x79,0x78, + 0xde,0xb1,0x5a,0x49, 0xd0,0xb8,0x57,0x42, 0xc2,0xa3,0x40,0x5f, 0xcc,0xaa,0x4d,0x54, + 0x41,0xec,0xda,0xf7, 0x4f,0xe5,0xd7,0xfc, 0x5d,0xfe,0xc0,0xe1, 0x53,0xf7,0xcd,0xea, + 0x79,0xc8,0xee,0xdb, 0x77,0xc1,0xe3,0xd0, 0x65,0xda,0xf4,0xcd, 0x6b,0xd3,0xf9,0xc6, + 0x31,0xa4,0xb2,0xaf, 0x3f,0xad,0xbf,0xa4, 0x2d,0xb6,0xa8,0xb9, 0x23,0xbf,0xa5,0xb2, + 0x09,0x80,0x86,0x83, 0x07,0x89,0x8b,0x88, 0x15,0x92,0x9c,0x95, 0x1b,0x9b,0x91,0x9e, + 0xa1,0x7c,0x0a,0x47, 0xaf,0x75,0x07,0x4c, 0xbd,0x6e,0x10,0x51, 0xb3,0x67,0x1d,0x5a, + 0x99,0x58,0x3e,0x6b, 0x97,0x51,0x33,0x60, 0x85,0x4a,0x24,0x7d, 0x8b,0x43,0x29,0x76, + 0xd1,0x34,0x62,0x1f, 0xdf,0x3d,0x6f,0x14, 0xcd,0x26,0x78,0x09, 0xc3,0x2f,0x75,0x02, + 0xe9,0x10,0x56,0x33, 0xe7,0x19,0x5b,0x38, 0xf5,0x02,0x4c,0x25, 0xfb,0x0b,0x41,0x2e, + 0x9a,0xd7,0x61,0x8c, 0x94,0xde,0x6c,0x87, 0x86,0xc5,0x7b,0x9a, 0x88,0xcc,0x76,0x91, + 0xa2,0xf3,0x55,0xa0, 0xac,0xfa,0x58,0xab, 0xbe,0xe1,0x4f,0xb6, 0xb0,0xe8,0x42,0xbd, + 0xea,0x9f,0x09,0xd4, 0xe4,0x96,0x04,0xdf, 0xf6,0x8d,0x13,0xc2, 0xf8,0x84,0x1e,0xc9, + 0xd2,0xbb,0x3d,0xf8, 0xdc,0xb2,0x30,0xf3, 0xce,0xa9,0x27,0xee, 0xc0,0xa0,0x2a,0xe5, + 0x7a,0x47,0xb1,0x3c, 0x74,0x4e,0xbc,0x37, 0x66,0x55,0xab,0x2a, 0x68,0x5c,0xa6,0x21, + 0x42,0x63,0x85,0x10, 0x4c,0x6a,0x88,0x1b, 0x5e,0x71,0x9f,0x06, 0x50,0x78,0x92,0x0d, + 0x0a,0x0f,0xd9,0x64, 0x04,0x06,0xd4,0x6f, 0x16,0x1d,0xc3,0x72, 0x18,0x14,0xce,0x79, + 0x32,0x2b,0xed,0x48, 0x3c,0x22,0xe0,0x43, 0x2e,0x39,0xf7,0x5e, 0x20,0x30,0xfa,0x55, + 0xec,0x9a,0xb7,0x01, 0xe2,0x93,0xba,0x0a, 0xf0,0x88,0xad,0x17, 0xfe,0x81,0xa0,0x1c, + 0xd4,0xbe,0x83,0x2d, 0xda,0xb7,0x8e,0x26, 0xc8,0xac,0x99,0x3b, 0xc6,0xa5,0x94,0x30, + 0x9c,0xd2,0xdf,0x59, 0x92,0xdb,0xd2,0x52, 0x80,0xc0,0xc5,0x4f, 0x8e,0xc9,0xc8,0x44, + 0xa4,0xf6,0xeb,0x75, 0xaa,0xff,0xe6,0x7e, 0xb8,0xe4,0xf1,0x63, 0xb6,0xed,0xfc,0x68, + 0x0c,0x0a,0x67,0xb1, 0x02,0x03,0x6a,0xba, 0x10,0x18,0x7d,0xa7, 0x1e,0x11,0x70,0xac, + 0x34,0x2e,0x53,0x9d, 0x3a,0x27,0x5e,0x96, 0x28,0x3c,0x49,0x8b, 0x26,0x35,0x44,0x80, + 0x7c,0x42,0x0f,0xe9, 0x72,0x4b,0x02,0xe2, 0x60,0x50,0x15,0xff, 0x6e,0x59,0x18,0xf4, + 0x44,0x66,0x3b,0xc5, 0x4a,0x6f,0x36,0xce, 0x58,0x74,0x21,0xd3, 0x56,0x7d,0x2c,0xd8, + 0x37,0xa1,0x0c,0x7a, 0x39,0xa8,0x01,0x71, 0x2b,0xb3,0x16,0x6c, 0x25,0xba,0x1b,0x67, + 0x0f,0x85,0x38,0x56, 0x01,0x8c,0x35,0x5d, 0x13,0x97,0x22,0x40, 0x1d,0x9e,0x2f,0x4b, + 0x47,0xe9,0x64,0x22, 0x49,0xe0,0x69,0x29, 0x5b,0xfb,0x7e,0x34, 0x55,0xf2,0x73,0x3f, + 0x7f,0xcd,0x50,0x0e, 0x71,0xc4,0x5d,0x05, 0x63,0xdf,0x4a,0x18, 0x6d,0xd6,0x47,0x13, + 0xd7,0x31,0xdc,0xca, 0xd9,0x38,0xd1,0xc1, 0xcb,0x23,0xc6,0xdc, 0xc5,0x2a,0xcb,0xd7, + 0xef,0x15,0xe8,0xe6, 0xe1,0x1c,0xe5,0xed, 0xf3,0x07,0xf2,0xf0, 0xfd,0x0e,0xff,0xfb, + 0xa7,0x79,0xb4,0x92, 0xa9,0x70,0xb9,0x99, 0xbb,0x6b,0xae,0x84, 0xb5,0x62,0xa3,0x8f, + 0x9f,0x5d,0x80,0xbe, 0x91,0x54,0x8d,0xb5, 0x83,0x4f,0x9a,0xa8, 0x8d,0x46,0x97,0xa3 +}; + +static UINT8 U2[256][4]= +{ + 0x00,0x00,0x00,0x00, 0x0b,0x0e,0x09,0x0d, 0x16,0x1c,0x12,0x1a, 0x1d,0x12,0x1b,0x17, + 0x2c,0x38,0x24,0x34, 0x27,0x36,0x2d,0x39, 0x3a,0x24,0x36,0x2e, 0x31,0x2a,0x3f,0x23, + 0x58,0x70,0x48,0x68, 0x53,0x7e,0x41,0x65, 0x4e,0x6c,0x5a,0x72, 0x45,0x62,0x53,0x7f, + 0x74,0x48,0x6c,0x5c, 0x7f,0x46,0x65,0x51, 0x62,0x54,0x7e,0x46, 0x69,0x5a,0x77,0x4b, + 0xb0,0xe0,0x90,0xd0, 0xbb,0xee,0x99,0xdd, 0xa6,0xfc,0x82,0xca, 0xad,0xf2,0x8b,0xc7, + 0x9c,0xd8,0xb4,0xe4, 0x97,0xd6,0xbd,0xe9, 0x8a,0xc4,0xa6,0xfe, 0x81,0xca,0xaf,0xf3, + 0xe8,0x90,0xd8,0xb8, 0xe3,0x9e,0xd1,0xb5, 0xfe,0x8c,0xca,0xa2, 0xf5,0x82,0xc3,0xaf, + 0xc4,0xa8,0xfc,0x8c, 0xcf,0xa6,0xf5,0x81, 0xd2,0xb4,0xee,0x96, 0xd9,0xba,0xe7,0x9b, + 0x7b,0xdb,0x3b,0xbb, 0x70,0xd5,0x32,0xb6, 0x6d,0xc7,0x29,0xa1, 0x66,0xc9,0x20,0xac, + 0x57,0xe3,0x1f,0x8f, 0x5c,0xed,0x16,0x82, 0x41,0xff,0x0d,0x95, 0x4a,0xf1,0x04,0x98, + 0x23,0xab,0x73,0xd3, 0x28,0xa5,0x7a,0xde, 0x35,0xb7,0x61,0xc9, 0x3e,0xb9,0x68,0xc4, + 0x0f,0x93,0x57,0xe7, 0x04,0x9d,0x5e,0xea, 0x19,0x8f,0x45,0xfd, 0x12,0x81,0x4c,0xf0, + 0xcb,0x3b,0xab,0x6b, 0xc0,0x35,0xa2,0x66, 0xdd,0x27,0xb9,0x71, 0xd6,0x29,0xb0,0x7c, + 0xe7,0x03,0x8f,0x5f, 0xec,0x0d,0x86,0x52, 0xf1,0x1f,0x9d,0x45, 0xfa,0x11,0x94,0x48, + 0x93,0x4b,0xe3,0x03, 0x98,0x45,0xea,0x0e, 0x85,0x57,0xf1,0x19, 0x8e,0x59,0xf8,0x14, + 0xbf,0x73,0xc7,0x37, 0xb4,0x7d,0xce,0x3a, 0xa9,0x6f,0xd5,0x2d, 0xa2,0x61,0xdc,0x20, + 0xf6,0xad,0x76,0x6d, 0xfd,0xa3,0x7f,0x60, 0xe0,0xb1,0x64,0x77, 0xeb,0xbf,0x6d,0x7a, + 0xda,0x95,0x52,0x59, 0xd1,0x9b,0x5b,0x54, 0xcc,0x89,0x40,0x43, 0xc7,0x87,0x49,0x4e, + 0xae,0xdd,0x3e,0x05, 0xa5,0xd3,0x37,0x08, 0xb8,0xc1,0x2c,0x1f, 0xb3,0xcf,0x25,0x12, + 0x82,0xe5,0x1a,0x31, 0x89,0xeb,0x13,0x3c, 0x94,0xf9,0x08,0x2b, 0x9f,0xf7,0x01,0x26, + 0x46,0x4d,0xe6,0xbd, 0x4d,0x43,0xef,0xb0, 0x50,0x51,0xf4,0xa7, 0x5b,0x5f,0xfd,0xaa, + 0x6a,0x75,0xc2,0x89, 0x61,0x7b,0xcb,0x84, 0x7c,0x69,0xd0,0x93, 0x77,0x67,0xd9,0x9e, + 0x1e,0x3d,0xae,0xd5, 0x15,0x33,0xa7,0xd8, 0x08,0x21,0xbc,0xcf, 0x03,0x2f,0xb5,0xc2, + 0x32,0x05,0x8a,0xe1, 0x39,0x0b,0x83,0xec, 0x24,0x19,0x98,0xfb, 0x2f,0x17,0x91,0xf6, + 0x8d,0x76,0x4d,0xd6, 0x86,0x78,0x44,0xdb, 0x9b,0x6a,0x5f,0xcc, 0x90,0x64,0x56,0xc1, + 0xa1,0x4e,0x69,0xe2, 0xaa,0x40,0x60,0xef, 0xb7,0x52,0x7b,0xf8, 0xbc,0x5c,0x72,0xf5, + 0xd5,0x06,0x05,0xbe, 0xde,0x08,0x0c,0xb3, 0xc3,0x1a,0x17,0xa4, 0xc8,0x14,0x1e,0xa9, + 0xf9,0x3e,0x21,0x8a, 0xf2,0x30,0x28,0x87, 0xef,0x22,0x33,0x90, 0xe4,0x2c,0x3a,0x9d, + 0x3d,0x96,0xdd,0x06, 0x36,0x98,0xd4,0x0b, 0x2b,0x8a,0xcf,0x1c, 0x20,0x84,0xc6,0x11, + 0x11,0xae,0xf9,0x32, 0x1a,0xa0,0xf0,0x3f, 0x07,0xb2,0xeb,0x28, 0x0c,0xbc,0xe2,0x25, + 0x65,0xe6,0x95,0x6e, 0x6e,0xe8,0x9c,0x63, 0x73,0xfa,0x87,0x74, 0x78,0xf4,0x8e,0x79, + 0x49,0xde,0xb1,0x5a, 0x42,0xd0,0xb8,0x57, 0x5f,0xc2,0xa3,0x40, 0x54,0xcc,0xaa,0x4d, + 0xf7,0x41,0xec,0xda, 0xfc,0x4f,0xe5,0xd7, 0xe1,0x5d,0xfe,0xc0, 0xea,0x53,0xf7,0xcd, + 0xdb,0x79,0xc8,0xee, 0xd0,0x77,0xc1,0xe3, 0xcd,0x65,0xda,0xf4, 0xc6,0x6b,0xd3,0xf9, + 0xaf,0x31,0xa4,0xb2, 0xa4,0x3f,0xad,0xbf, 0xb9,0x2d,0xb6,0xa8, 0xb2,0x23,0xbf,0xa5, + 0x83,0x09,0x80,0x86, 0x88,0x07,0x89,0x8b, 0x95,0x15,0x92,0x9c, 0x9e,0x1b,0x9b,0x91, + 0x47,0xa1,0x7c,0x0a, 0x4c,0xaf,0x75,0x07, 0x51,0xbd,0x6e,0x10, 0x5a,0xb3,0x67,0x1d, + 0x6b,0x99,0x58,0x3e, 0x60,0x97,0x51,0x33, 0x7d,0x85,0x4a,0x24, 0x76,0x8b,0x43,0x29, + 0x1f,0xd1,0x34,0x62, 0x14,0xdf,0x3d,0x6f, 0x09,0xcd,0x26,0x78, 0x02,0xc3,0x2f,0x75, + 0x33,0xe9,0x10,0x56, 0x38,0xe7,0x19,0x5b, 0x25,0xf5,0x02,0x4c, 0x2e,0xfb,0x0b,0x41, + 0x8c,0x9a,0xd7,0x61, 0x87,0x94,0xde,0x6c, 0x9a,0x86,0xc5,0x7b, 0x91,0x88,0xcc,0x76, + 0xa0,0xa2,0xf3,0x55, 0xab,0xac,0xfa,0x58, 0xb6,0xbe,0xe1,0x4f, 0xbd,0xb0,0xe8,0x42, + 0xd4,0xea,0x9f,0x09, 0xdf,0xe4,0x96,0x04, 0xc2,0xf6,0x8d,0x13, 0xc9,0xf8,0x84,0x1e, + 0xf8,0xd2,0xbb,0x3d, 0xf3,0xdc,0xb2,0x30, 0xee,0xce,0xa9,0x27, 0xe5,0xc0,0xa0,0x2a, + 0x3c,0x7a,0x47,0xb1, 0x37,0x74,0x4e,0xbc, 0x2a,0x66,0x55,0xab, 0x21,0x68,0x5c,0xa6, + 0x10,0x42,0x63,0x85, 0x1b,0x4c,0x6a,0x88, 0x06,0x5e,0x71,0x9f, 0x0d,0x50,0x78,0x92, + 0x64,0x0a,0x0f,0xd9, 0x6f,0x04,0x06,0xd4, 0x72,0x16,0x1d,0xc3, 0x79,0x18,0x14,0xce, + 0x48,0x32,0x2b,0xed, 0x43,0x3c,0x22,0xe0, 0x5e,0x2e,0x39,0xf7, 0x55,0x20,0x30,0xfa, + 0x01,0xec,0x9a,0xb7, 0x0a,0xe2,0x93,0xba, 0x17,0xf0,0x88,0xad, 0x1c,0xfe,0x81,0xa0, + 0x2d,0xd4,0xbe,0x83, 0x26,0xda,0xb7,0x8e, 0x3b,0xc8,0xac,0x99, 0x30,0xc6,0xa5,0x94, + 0x59,0x9c,0xd2,0xdf, 0x52,0x92,0xdb,0xd2, 0x4f,0x80,0xc0,0xc5, 0x44,0x8e,0xc9,0xc8, + 0x75,0xa4,0xf6,0xeb, 0x7e,0xaa,0xff,0xe6, 0x63,0xb8,0xe4,0xf1, 0x68,0xb6,0xed,0xfc, + 0xb1,0x0c,0x0a,0x67, 0xba,0x02,0x03,0x6a, 0xa7,0x10,0x18,0x7d, 0xac,0x1e,0x11,0x70, + 0x9d,0x34,0x2e,0x53, 0x96,0x3a,0x27,0x5e, 0x8b,0x28,0x3c,0x49, 0x80,0x26,0x35,0x44, + 0xe9,0x7c,0x42,0x0f, 0xe2,0x72,0x4b,0x02, 0xff,0x60,0x50,0x15, 0xf4,0x6e,0x59,0x18, + 0xc5,0x44,0x66,0x3b, 0xce,0x4a,0x6f,0x36, 0xd3,0x58,0x74,0x21, 0xd8,0x56,0x7d,0x2c, + 0x7a,0x37,0xa1,0x0c, 0x71,0x39,0xa8,0x01, 0x6c,0x2b,0xb3,0x16, 0x67,0x25,0xba,0x1b, + 0x56,0x0f,0x85,0x38, 0x5d,0x01,0x8c,0x35, 0x40,0x13,0x97,0x22, 0x4b,0x1d,0x9e,0x2f, + 0x22,0x47,0xe9,0x64, 0x29,0x49,0xe0,0x69, 0x34,0x5b,0xfb,0x7e, 0x3f,0x55,0xf2,0x73, + 0x0e,0x7f,0xcd,0x50, 0x05,0x71,0xc4,0x5d, 0x18,0x63,0xdf,0x4a, 0x13,0x6d,0xd6,0x47, + 0xca,0xd7,0x31,0xdc, 0xc1,0xd9,0x38,0xd1, 0xdc,0xcb,0x23,0xc6, 0xd7,0xc5,0x2a,0xcb, + 0xe6,0xef,0x15,0xe8, 0xed,0xe1,0x1c,0xe5, 0xf0,0xf3,0x07,0xf2, 0xfb,0xfd,0x0e,0xff, + 0x92,0xa7,0x79,0xb4, 0x99,0xa9,0x70,0xb9, 0x84,0xbb,0x6b,0xae, 0x8f,0xb5,0x62,0xa3, + 0xbe,0x9f,0x5d,0x80, 0xb5,0x91,0x54,0x8d, 0xa8,0x83,0x4f,0x9a, 0xa3,0x8d,0x46,0x97 +}; + +static UINT8 U3[256][4]= +{ + 0x00,0x00,0x00,0x00, 0x0d,0x0b,0x0e,0x09, 0x1a,0x16,0x1c,0x12, 0x17,0x1d,0x12,0x1b, + 0x34,0x2c,0x38,0x24, 0x39,0x27,0x36,0x2d, 0x2e,0x3a,0x24,0x36, 0x23,0x31,0x2a,0x3f, + 0x68,0x58,0x70,0x48, 0x65,0x53,0x7e,0x41, 0x72,0x4e,0x6c,0x5a, 0x7f,0x45,0x62,0x53, + 0x5c,0x74,0x48,0x6c, 0x51,0x7f,0x46,0x65, 0x46,0x62,0x54,0x7e, 0x4b,0x69,0x5a,0x77, + 0xd0,0xb0,0xe0,0x90, 0xdd,0xbb,0xee,0x99, 0xca,0xa6,0xfc,0x82, 0xc7,0xad,0xf2,0x8b, + 0xe4,0x9c,0xd8,0xb4, 0xe9,0x97,0xd6,0xbd, 0xfe,0x8a,0xc4,0xa6, 0xf3,0x81,0xca,0xaf, + 0xb8,0xe8,0x90,0xd8, 0xb5,0xe3,0x9e,0xd1, 0xa2,0xfe,0x8c,0xca, 0xaf,0xf5,0x82,0xc3, + 0x8c,0xc4,0xa8,0xfc, 0x81,0xcf,0xa6,0xf5, 0x96,0xd2,0xb4,0xee, 0x9b,0xd9,0xba,0xe7, + 0xbb,0x7b,0xdb,0x3b, 0xb6,0x70,0xd5,0x32, 0xa1,0x6d,0xc7,0x29, 0xac,0x66,0xc9,0x20, + 0x8f,0x57,0xe3,0x1f, 0x82,0x5c,0xed,0x16, 0x95,0x41,0xff,0x0d, 0x98,0x4a,0xf1,0x04, + 0xd3,0x23,0xab,0x73, 0xde,0x28,0xa5,0x7a, 0xc9,0x35,0xb7,0x61, 0xc4,0x3e,0xb9,0x68, + 0xe7,0x0f,0x93,0x57, 0xea,0x04,0x9d,0x5e, 0xfd,0x19,0x8f,0x45, 0xf0,0x12,0x81,0x4c, + 0x6b,0xcb,0x3b,0xab, 0x66,0xc0,0x35,0xa2, 0x71,0xdd,0x27,0xb9, 0x7c,0xd6,0x29,0xb0, + 0x5f,0xe7,0x03,0x8f, 0x52,0xec,0x0d,0x86, 0x45,0xf1,0x1f,0x9d, 0x48,0xfa,0x11,0x94, + 0x03,0x93,0x4b,0xe3, 0x0e,0x98,0x45,0xea, 0x19,0x85,0x57,0xf1, 0x14,0x8e,0x59,0xf8, + 0x37,0xbf,0x73,0xc7, 0x3a,0xb4,0x7d,0xce, 0x2d,0xa9,0x6f,0xd5, 0x20,0xa2,0x61,0xdc, + 0x6d,0xf6,0xad,0x76, 0x60,0xfd,0xa3,0x7f, 0x77,0xe0,0xb1,0x64, 0x7a,0xeb,0xbf,0x6d, + 0x59,0xda,0x95,0x52, 0x54,0xd1,0x9b,0x5b, 0x43,0xcc,0x89,0x40, 0x4e,0xc7,0x87,0x49, + 0x05,0xae,0xdd,0x3e, 0x08,0xa5,0xd3,0x37, 0x1f,0xb8,0xc1,0x2c, 0x12,0xb3,0xcf,0x25, + 0x31,0x82,0xe5,0x1a, 0x3c,0x89,0xeb,0x13, 0x2b,0x94,0xf9,0x08, 0x26,0x9f,0xf7,0x01, + 0xbd,0x46,0x4d,0xe6, 0xb0,0x4d,0x43,0xef, 0xa7,0x50,0x51,0xf4, 0xaa,0x5b,0x5f,0xfd, + 0x89,0x6a,0x75,0xc2, 0x84,0x61,0x7b,0xcb, 0x93,0x7c,0x69,0xd0, 0x9e,0x77,0x67,0xd9, + 0xd5,0x1e,0x3d,0xae, 0xd8,0x15,0x33,0xa7, 0xcf,0x08,0x21,0xbc, 0xc2,0x03,0x2f,0xb5, + 0xe1,0x32,0x05,0x8a, 0xec,0x39,0x0b,0x83, 0xfb,0x24,0x19,0x98, 0xf6,0x2f,0x17,0x91, + 0xd6,0x8d,0x76,0x4d, 0xdb,0x86,0x78,0x44, 0xcc,0x9b,0x6a,0x5f, 0xc1,0x90,0x64,0x56, + 0xe2,0xa1,0x4e,0x69, 0xef,0xaa,0x40,0x60, 0xf8,0xb7,0x52,0x7b, 0xf5,0xbc,0x5c,0x72, + 0xbe,0xd5,0x06,0x05, 0xb3,0xde,0x08,0x0c, 0xa4,0xc3,0x1a,0x17, 0xa9,0xc8,0x14,0x1e, + 0x8a,0xf9,0x3e,0x21, 0x87,0xf2,0x30,0x28, 0x90,0xef,0x22,0x33, 0x9d,0xe4,0x2c,0x3a, + 0x06,0x3d,0x96,0xdd, 0x0b,0x36,0x98,0xd4, 0x1c,0x2b,0x8a,0xcf, 0x11,0x20,0x84,0xc6, + 0x32,0x11,0xae,0xf9, 0x3f,0x1a,0xa0,0xf0, 0x28,0x07,0xb2,0xeb, 0x25,0x0c,0xbc,0xe2, + 0x6e,0x65,0xe6,0x95, 0x63,0x6e,0xe8,0x9c, 0x74,0x73,0xfa,0x87, 0x79,0x78,0xf4,0x8e, + 0x5a,0x49,0xde,0xb1, 0x57,0x42,0xd0,0xb8, 0x40,0x5f,0xc2,0xa3, 0x4d,0x54,0xcc,0xaa, + 0xda,0xf7,0x41,0xec, 0xd7,0xfc,0x4f,0xe5, 0xc0,0xe1,0x5d,0xfe, 0xcd,0xea,0x53,0xf7, + 0xee,0xdb,0x79,0xc8, 0xe3,0xd0,0x77,0xc1, 0xf4,0xcd,0x65,0xda, 0xf9,0xc6,0x6b,0xd3, + 0xb2,0xaf,0x31,0xa4, 0xbf,0xa4,0x3f,0xad, 0xa8,0xb9,0x2d,0xb6, 0xa5,0xb2,0x23,0xbf, + 0x86,0x83,0x09,0x80, 0x8b,0x88,0x07,0x89, 0x9c,0x95,0x15,0x92, 0x91,0x9e,0x1b,0x9b, + 0x0a,0x47,0xa1,0x7c, 0x07,0x4c,0xaf,0x75, 0x10,0x51,0xbd,0x6e, 0x1d,0x5a,0xb3,0x67, + 0x3e,0x6b,0x99,0x58, 0x33,0x60,0x97,0x51, 0x24,0x7d,0x85,0x4a, 0x29,0x76,0x8b,0x43, + 0x62,0x1f,0xd1,0x34, 0x6f,0x14,0xdf,0x3d, 0x78,0x09,0xcd,0x26, 0x75,0x02,0xc3,0x2f, + 0x56,0x33,0xe9,0x10, 0x5b,0x38,0xe7,0x19, 0x4c,0x25,0xf5,0x02, 0x41,0x2e,0xfb,0x0b, + 0x61,0x8c,0x9a,0xd7, 0x6c,0x87,0x94,0xde, 0x7b,0x9a,0x86,0xc5, 0x76,0x91,0x88,0xcc, + 0x55,0xa0,0xa2,0xf3, 0x58,0xab,0xac,0xfa, 0x4f,0xb6,0xbe,0xe1, 0x42,0xbd,0xb0,0xe8, + 0x09,0xd4,0xea,0x9f, 0x04,0xdf,0xe4,0x96, 0x13,0xc2,0xf6,0x8d, 0x1e,0xc9,0xf8,0x84, + 0x3d,0xf8,0xd2,0xbb, 0x30,0xf3,0xdc,0xb2, 0x27,0xee,0xce,0xa9, 0x2a,0xe5,0xc0,0xa0, + 0xb1,0x3c,0x7a,0x47, 0xbc,0x37,0x74,0x4e, 0xab,0x2a,0x66,0x55, 0xa6,0x21,0x68,0x5c, + 0x85,0x10,0x42,0x63, 0x88,0x1b,0x4c,0x6a, 0x9f,0x06,0x5e,0x71, 0x92,0x0d,0x50,0x78, + 0xd9,0x64,0x0a,0x0f, 0xd4,0x6f,0x04,0x06, 0xc3,0x72,0x16,0x1d, 0xce,0x79,0x18,0x14, + 0xed,0x48,0x32,0x2b, 0xe0,0x43,0x3c,0x22, 0xf7,0x5e,0x2e,0x39, 0xfa,0x55,0x20,0x30, + 0xb7,0x01,0xec,0x9a, 0xba,0x0a,0xe2,0x93, 0xad,0x17,0xf0,0x88, 0xa0,0x1c,0xfe,0x81, + 0x83,0x2d,0xd4,0xbe, 0x8e,0x26,0xda,0xb7, 0x99,0x3b,0xc8,0xac, 0x94,0x30,0xc6,0xa5, + 0xdf,0x59,0x9c,0xd2, 0xd2,0x52,0x92,0xdb, 0xc5,0x4f,0x80,0xc0, 0xc8,0x44,0x8e,0xc9, + 0xeb,0x75,0xa4,0xf6, 0xe6,0x7e,0xaa,0xff, 0xf1,0x63,0xb8,0xe4, 0xfc,0x68,0xb6,0xed, + 0x67,0xb1,0x0c,0x0a, 0x6a,0xba,0x02,0x03, 0x7d,0xa7,0x10,0x18, 0x70,0xac,0x1e,0x11, + 0x53,0x9d,0x34,0x2e, 0x5e,0x96,0x3a,0x27, 0x49,0x8b,0x28,0x3c, 0x44,0x80,0x26,0x35, + 0x0f,0xe9,0x7c,0x42, 0x02,0xe2,0x72,0x4b, 0x15,0xff,0x60,0x50, 0x18,0xf4,0x6e,0x59, + 0x3b,0xc5,0x44,0x66, 0x36,0xce,0x4a,0x6f, 0x21,0xd3,0x58,0x74, 0x2c,0xd8,0x56,0x7d, + 0x0c,0x7a,0x37,0xa1, 0x01,0x71,0x39,0xa8, 0x16,0x6c,0x2b,0xb3, 0x1b,0x67,0x25,0xba, + 0x38,0x56,0x0f,0x85, 0x35,0x5d,0x01,0x8c, 0x22,0x40,0x13,0x97, 0x2f,0x4b,0x1d,0x9e, + 0x64,0x22,0x47,0xe9, 0x69,0x29,0x49,0xe0, 0x7e,0x34,0x5b,0xfb, 0x73,0x3f,0x55,0xf2, + 0x50,0x0e,0x7f,0xcd, 0x5d,0x05,0x71,0xc4, 0x4a,0x18,0x63,0xdf, 0x47,0x13,0x6d,0xd6, + 0xdc,0xca,0xd7,0x31, 0xd1,0xc1,0xd9,0x38, 0xc6,0xdc,0xcb,0x23, 0xcb,0xd7,0xc5,0x2a, + 0xe8,0xe6,0xef,0x15, 0xe5,0xed,0xe1,0x1c, 0xf2,0xf0,0xf3,0x07, 0xff,0xfb,0xfd,0x0e, + 0xb4,0x92,0xa7,0x79, 0xb9,0x99,0xa9,0x70, 0xae,0x84,0xbb,0x6b, 0xa3,0x8f,0xb5,0x62, + 0x80,0xbe,0x9f,0x5d, 0x8d,0xb5,0x91,0x54, 0x9a,0xa8,0x83,0x4f, 0x97,0xa3,0x8d,0x46 +}; + +static UINT8 U4[256][4]= +{ + 0x00,0x00,0x00,0x00, 0x09,0x0d,0x0b,0x0e, 0x12,0x1a,0x16,0x1c, 0x1b,0x17,0x1d,0x12, + 0x24,0x34,0x2c,0x38, 0x2d,0x39,0x27,0x36, 0x36,0x2e,0x3a,0x24, 0x3f,0x23,0x31,0x2a, + 0x48,0x68,0x58,0x70, 0x41,0x65,0x53,0x7e, 0x5a,0x72,0x4e,0x6c, 0x53,0x7f,0x45,0x62, + 0x6c,0x5c,0x74,0x48, 0x65,0x51,0x7f,0x46, 0x7e,0x46,0x62,0x54, 0x77,0x4b,0x69,0x5a, + 0x90,0xd0,0xb0,0xe0, 0x99,0xdd,0xbb,0xee, 0x82,0xca,0xa6,0xfc, 0x8b,0xc7,0xad,0xf2, + 0xb4,0xe4,0x9c,0xd8, 0xbd,0xe9,0x97,0xd6, 0xa6,0xfe,0x8a,0xc4, 0xaf,0xf3,0x81,0xca, + 0xd8,0xb8,0xe8,0x90, 0xd1,0xb5,0xe3,0x9e, 0xca,0xa2,0xfe,0x8c, 0xc3,0xaf,0xf5,0x82, + 0xfc,0x8c,0xc4,0xa8, 0xf5,0x81,0xcf,0xa6, 0xee,0x96,0xd2,0xb4, 0xe7,0x9b,0xd9,0xba, + 0x3b,0xbb,0x7b,0xdb, 0x32,0xb6,0x70,0xd5, 0x29,0xa1,0x6d,0xc7, 0x20,0xac,0x66,0xc9, + 0x1f,0x8f,0x57,0xe3, 0x16,0x82,0x5c,0xed, 0x0d,0x95,0x41,0xff, 0x04,0x98,0x4a,0xf1, + 0x73,0xd3,0x23,0xab, 0x7a,0xde,0x28,0xa5, 0x61,0xc9,0x35,0xb7, 0x68,0xc4,0x3e,0xb9, + 0x57,0xe7,0x0f,0x93, 0x5e,0xea,0x04,0x9d, 0x45,0xfd,0x19,0x8f, 0x4c,0xf0,0x12,0x81, + 0xab,0x6b,0xcb,0x3b, 0xa2,0x66,0xc0,0x35, 0xb9,0x71,0xdd,0x27, 0xb0,0x7c,0xd6,0x29, + 0x8f,0x5f,0xe7,0x03, 0x86,0x52,0xec,0x0d, 0x9d,0x45,0xf1,0x1f, 0x94,0x48,0xfa,0x11, + 0xe3,0x03,0x93,0x4b, 0xea,0x0e,0x98,0x45, 0xf1,0x19,0x85,0x57, 0xf8,0x14,0x8e,0x59, + 0xc7,0x37,0xbf,0x73, 0xce,0x3a,0xb4,0x7d, 0xd5,0x2d,0xa9,0x6f, 0xdc,0x20,0xa2,0x61, + 0x76,0x6d,0xf6,0xad, 0x7f,0x60,0xfd,0xa3, 0x64,0x77,0xe0,0xb1, 0x6d,0x7a,0xeb,0xbf, + 0x52,0x59,0xda,0x95, 0x5b,0x54,0xd1,0x9b, 0x40,0x43,0xcc,0x89, 0x49,0x4e,0xc7,0x87, + 0x3e,0x05,0xae,0xdd, 0x37,0x08,0xa5,0xd3, 0x2c,0x1f,0xb8,0xc1, 0x25,0x12,0xb3,0xcf, + 0x1a,0x31,0x82,0xe5, 0x13,0x3c,0x89,0xeb, 0x08,0x2b,0x94,0xf9, 0x01,0x26,0x9f,0xf7, + 0xe6,0xbd,0x46,0x4d, 0xef,0xb0,0x4d,0x43, 0xf4,0xa7,0x50,0x51, 0xfd,0xaa,0x5b,0x5f, + 0xc2,0x89,0x6a,0x75, 0xcb,0x84,0x61,0x7b, 0xd0,0x93,0x7c,0x69, 0xd9,0x9e,0x77,0x67, + 0xae,0xd5,0x1e,0x3d, 0xa7,0xd8,0x15,0x33, 0xbc,0xcf,0x08,0x21, 0xb5,0xc2,0x03,0x2f, + 0x8a,0xe1,0x32,0x05, 0x83,0xec,0x39,0x0b, 0x98,0xfb,0x24,0x19, 0x91,0xf6,0x2f,0x17, + 0x4d,0xd6,0x8d,0x76, 0x44,0xdb,0x86,0x78, 0x5f,0xcc,0x9b,0x6a, 0x56,0xc1,0x90,0x64, + 0x69,0xe2,0xa1,0x4e, 0x60,0xef,0xaa,0x40, 0x7b,0xf8,0xb7,0x52, 0x72,0xf5,0xbc,0x5c, + 0x05,0xbe,0xd5,0x06, 0x0c,0xb3,0xde,0x08, 0x17,0xa4,0xc3,0x1a, 0x1e,0xa9,0xc8,0x14, + 0x21,0x8a,0xf9,0x3e, 0x28,0x87,0xf2,0x30, 0x33,0x90,0xef,0x22, 0x3a,0x9d,0xe4,0x2c, + 0xdd,0x06,0x3d,0x96, 0xd4,0x0b,0x36,0x98, 0xcf,0x1c,0x2b,0x8a, 0xc6,0x11,0x20,0x84, + 0xf9,0x32,0x11,0xae, 0xf0,0x3f,0x1a,0xa0, 0xeb,0x28,0x07,0xb2, 0xe2,0x25,0x0c,0xbc, + 0x95,0x6e,0x65,0xe6, 0x9c,0x63,0x6e,0xe8, 0x87,0x74,0x73,0xfa, 0x8e,0x79,0x78,0xf4, + 0xb1,0x5a,0x49,0xde, 0xb8,0x57,0x42,0xd0, 0xa3,0x40,0x5f,0xc2, 0xaa,0x4d,0x54,0xcc, + 0xec,0xda,0xf7,0x41, 0xe5,0xd7,0xfc,0x4f, 0xfe,0xc0,0xe1,0x5d, 0xf7,0xcd,0xea,0x53, + 0xc8,0xee,0xdb,0x79, 0xc1,0xe3,0xd0,0x77, 0xda,0xf4,0xcd,0x65, 0xd3,0xf9,0xc6,0x6b, + 0xa4,0xb2,0xaf,0x31, 0xad,0xbf,0xa4,0x3f, 0xb6,0xa8,0xb9,0x2d, 0xbf,0xa5,0xb2,0x23, + 0x80,0x86,0x83,0x09, 0x89,0x8b,0x88,0x07, 0x92,0x9c,0x95,0x15, 0x9b,0x91,0x9e,0x1b, + 0x7c,0x0a,0x47,0xa1, 0x75,0x07,0x4c,0xaf, 0x6e,0x10,0x51,0xbd, 0x67,0x1d,0x5a,0xb3, + 0x58,0x3e,0x6b,0x99, 0x51,0x33,0x60,0x97, 0x4a,0x24,0x7d,0x85, 0x43,0x29,0x76,0x8b, + 0x34,0x62,0x1f,0xd1, 0x3d,0x6f,0x14,0xdf, 0x26,0x78,0x09,0xcd, 0x2f,0x75,0x02,0xc3, + 0x10,0x56,0x33,0xe9, 0x19,0x5b,0x38,0xe7, 0x02,0x4c,0x25,0xf5, 0x0b,0x41,0x2e,0xfb, + 0xd7,0x61,0x8c,0x9a, 0xde,0x6c,0x87,0x94, 0xc5,0x7b,0x9a,0x86, 0xcc,0x76,0x91,0x88, + 0xf3,0x55,0xa0,0xa2, 0xfa,0x58,0xab,0xac, 0xe1,0x4f,0xb6,0xbe, 0xe8,0x42,0xbd,0xb0, + 0x9f,0x09,0xd4,0xea, 0x96,0x04,0xdf,0xe4, 0x8d,0x13,0xc2,0xf6, 0x84,0x1e,0xc9,0xf8, + 0xbb,0x3d,0xf8,0xd2, 0xb2,0x30,0xf3,0xdc, 0xa9,0x27,0xee,0xce, 0xa0,0x2a,0xe5,0xc0, + 0x47,0xb1,0x3c,0x7a, 0x4e,0xbc,0x37,0x74, 0x55,0xab,0x2a,0x66, 0x5c,0xa6,0x21,0x68, + 0x63,0x85,0x10,0x42, 0x6a,0x88,0x1b,0x4c, 0x71,0x9f,0x06,0x5e, 0x78,0x92,0x0d,0x50, + 0x0f,0xd9,0x64,0x0a, 0x06,0xd4,0x6f,0x04, 0x1d,0xc3,0x72,0x16, 0x14,0xce,0x79,0x18, + 0x2b,0xed,0x48,0x32, 0x22,0xe0,0x43,0x3c, 0x39,0xf7,0x5e,0x2e, 0x30,0xfa,0x55,0x20, + 0x9a,0xb7,0x01,0xec, 0x93,0xba,0x0a,0xe2, 0x88,0xad,0x17,0xf0, 0x81,0xa0,0x1c,0xfe, + 0xbe,0x83,0x2d,0xd4, 0xb7,0x8e,0x26,0xda, 0xac,0x99,0x3b,0xc8, 0xa5,0x94,0x30,0xc6, + 0xd2,0xdf,0x59,0x9c, 0xdb,0xd2,0x52,0x92, 0xc0,0xc5,0x4f,0x80, 0xc9,0xc8,0x44,0x8e, + 0xf6,0xeb,0x75,0xa4, 0xff,0xe6,0x7e,0xaa, 0xe4,0xf1,0x63,0xb8, 0xed,0xfc,0x68,0xb6, + 0x0a,0x67,0xb1,0x0c, 0x03,0x6a,0xba,0x02, 0x18,0x7d,0xa7,0x10, 0x11,0x70,0xac,0x1e, + 0x2e,0x53,0x9d,0x34, 0x27,0x5e,0x96,0x3a, 0x3c,0x49,0x8b,0x28, 0x35,0x44,0x80,0x26, + 0x42,0x0f,0xe9,0x7c, 0x4b,0x02,0xe2,0x72, 0x50,0x15,0xff,0x60, 0x59,0x18,0xf4,0x6e, + 0x66,0x3b,0xc5,0x44, 0x6f,0x36,0xce,0x4a, 0x74,0x21,0xd3,0x58, 0x7d,0x2c,0xd8,0x56, + 0xa1,0x0c,0x7a,0x37, 0xa8,0x01,0x71,0x39, 0xb3,0x16,0x6c,0x2b, 0xba,0x1b,0x67,0x25, + 0x85,0x38,0x56,0x0f, 0x8c,0x35,0x5d,0x01, 0x97,0x22,0x40,0x13, 0x9e,0x2f,0x4b,0x1d, + 0xe9,0x64,0x22,0x47, 0xe0,0x69,0x29,0x49, 0xfb,0x7e,0x34,0x5b, 0xf2,0x73,0x3f,0x55, + 0xcd,0x50,0x0e,0x7f, 0xc4,0x5d,0x05,0x71, 0xdf,0x4a,0x18,0x63, 0xd6,0x47,0x13,0x6d, + 0x31,0xdc,0xca,0xd7, 0x38,0xd1,0xc1,0xd9, 0x23,0xc6,0xdc,0xcb, 0x2a,0xcb,0xd7,0xc5, + 0x15,0xe8,0xe6,0xef, 0x1c,0xe5,0xed,0xe1, 0x07,0xf2,0xf0,0xf3, 0x0e,0xff,0xfb,0xfd, + 0x79,0xb4,0x92,0xa7, 0x70,0xb9,0x99,0xa9, 0x6b,0xae,0x84,0xbb, 0x62,0xa3,0x8f,0xb5, + 0x5d,0x80,0xbe,0x9f, 0x54,0x8d,0xb5,0x91, 0x4f,0x9a,0xa8,0x83, 0x46,0x97,0xa3,0x8d +}; + +static UINT32 rcon[30]= +{ + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, + 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, + 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, + 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, + 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91 +}; + + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// API +////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +Rijndael::Rijndael() +{ + m_state = Invalid; +} + +Rijndael::~Rijndael() +{ + // nothing here +} + +int Rijndael::init(Mode mode,Direction dir,const UINT8 * key,KeyLength keyLen,UINT8 * initVector) +{ + // Not initialized yet + m_state = Invalid; + + // Check the mode + if((mode != CBC) && (mode != ECB) && (mode != CFB1)) return RIJNDAEL_UNSUPPORTED_MODE; + m_mode = mode; + + // And the direction + if((dir != Encrypt) && (dir != Decrypt)) return RIJNDAEL_UNSUPPORTED_DIRECTION; + m_direction = dir; + + // Allow to set an init vector + if(initVector) + { + // specified init vector + for(int i = 0;i < MAX_IV_SIZE;i++) + { + m_initVector[i] = initVector[i]; + } + } else { + // zero init vector + for(int i = 0;i < MAX_IV_SIZE;i++) + { + m_initVector[i] = 0; + } + } + + UINT32 uKeyLenInBytes; + + // And check the key length + switch(keyLen) + { + case Key16Bytes: + uKeyLenInBytes = 16; + m_uRounds = 10; + break; + case Key24Bytes: + uKeyLenInBytes = 24; + m_uRounds = 12; + break; + case Key32Bytes: + uKeyLenInBytes = 32; + m_uRounds = 14; + break; + default: + return RIJNDAEL_UNSUPPORTED_KEY_LENGTH; + break; + } + // The number of rounds is calculated as + // m_uRounds = (m_uKeyLenInBits / 32) + 6; + + if(!key) return RIJNDAEL_BAD_KEY; + + UINT8 keyMatrix[_MAX_KEY_COLUMNS][4]; + + for(UINT32 i = 0;i < uKeyLenInBytes;i++)keyMatrix[i >> 2][i & 3] = key[i]; + + keySched(keyMatrix); + + if(m_direction == Decrypt)keyEncToDec(); + + m_state = Valid; + + return RIJNDAEL_SUCCESS; +} + +int Rijndael::blockEncrypt(const UINT8 *input,int inputLen,UINT8 *outBuffer) +{ + int i, k, numBlocks; + UINT8 block[16], iv[4][4]; + + if(m_state != Valid) return RIJNDAEL_NOT_INITIALIZED; + if(m_direction != Encrypt) return RIJNDAEL_BAD_DIRECTION; + + if(input == 0 || inputLen <= 0) return 0; + + numBlocks = inputLen/128; + + switch(m_mode){ + case ECB: + for(i = numBlocks;i > 0;i--) + { + encrypt(input,outBuffer); + input += 16; + outBuffer += 16; + } + break; + case CBC: + ((UINT32*)block)[0] = ((UINT32*)m_initVector)[0] ^ ((UINT32*)input)[0]; + ((UINT32*)block)[1] = ((UINT32*)m_initVector)[1] ^ ((UINT32*)input)[1]; + ((UINT32*)block)[2] = ((UINT32*)m_initVector)[2] ^ ((UINT32*)input)[2]; + ((UINT32*)block)[3] = ((UINT32*)m_initVector)[3] ^ ((UINT32*)input)[3]; + encrypt(block,outBuffer); + input += 16; + for(i = numBlocks - 1;i > 0;i--) + { + ((UINT32*)block)[0] = ((UINT32*)outBuffer)[0] ^ ((UINT32*)input)[0]; + ((UINT32*)block)[1] = ((UINT32*)outBuffer)[1] ^ ((UINT32*)input)[1]; + ((UINT32*)block)[2] = ((UINT32*)outBuffer)[2] ^ ((UINT32*)input)[2]; + ((UINT32*)block)[3] = ((UINT32*)outBuffer)[3] ^ ((UINT32*)input)[3]; + outBuffer += 16; + encrypt(block,outBuffer); + input += 16; + } + break; + case CFB1: +#if STRICT_ALIGN + memcpy(iv,m_initVector,16); +#else /* !STRICT_ALIGN */ + *((UINT32*)iv[0]) = *((UINT32*)(m_initVector )); + *((UINT32*)iv[1]) = *((UINT32*)(m_initVector + 4)); + *((UINT32*)iv[2]) = *((UINT32*)(m_initVector + 8)); + *((UINT32*)iv[3]) = *((UINT32*)(m_initVector +12)); +#endif /* ?STRICT_ALIGN */ + for(i = numBlocks; i > 0; i--) + { + for(k = 0; k < 128; k++) + { + *((UINT32*) block ) = *((UINT32*)iv[0]); + *((UINT32*)(block+ 4)) = *((UINT32*)iv[1]); + *((UINT32*)(block+ 8)) = *((UINT32*)iv[2]); + *((UINT32*)(block+12)) = *((UINT32*)iv[3]); + encrypt(block,block); + outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7); + iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7); + iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7); + iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7); + iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7); + iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7); + iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7); + iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7); + iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7); + iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7); + iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7); + iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7); + iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7); + iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7); + iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7); + iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7); + iv[3][3] = (iv[3][3] << 1) | (outBuffer[k/8] >> (7-(k&7))) & 1; + } + } + break; + default: + return -1; + break; + } + + return 128 * numBlocks; +} + +int Rijndael::padEncrypt(const UINT8 *input, int inputOctets, UINT8 *outBuffer) +{ + int i, numBlocks, padLen; + UINT8 block[16], *iv; + + if(m_state != Valid) return RIJNDAEL_NOT_INITIALIZED; + if(m_direction != Encrypt) return RIJNDAEL_NOT_INITIALIZED; + + if((input == 0) || (inputOctets <= 0)) return 0; + + numBlocks = inputOctets/16; + + switch(m_mode) + { + case ECB: + for(i = numBlocks; i > 0; i--) + { + encrypt(input, outBuffer); + input += 16; + outBuffer += 16; + } + padLen = 16 - (inputOctets - 16*numBlocks); +// assert(padLen > 0 && padLen <= 16); + memcpy(block, input, 16 - padLen); + memset(block + 16 - padLen, padLen, padLen); + encrypt(block,outBuffer); + break; + case CBC: + iv = m_initVector; + for(i = numBlocks; i > 0; i--) + { + ((UINT32*)block)[0] = ((UINT32*)input)[0] ^ ((UINT32*)iv)[0]; + ((UINT32*)block)[1] = ((UINT32*)input)[1] ^ ((UINT32*)iv)[1]; + ((UINT32*)block)[2] = ((UINT32*)input)[2] ^ ((UINT32*)iv)[2]; + ((UINT32*)block)[3] = ((UINT32*)input)[3] ^ ((UINT32*)iv)[3]; + encrypt(block, outBuffer); + iv = outBuffer; + input += 16; + outBuffer += 16; + } + padLen = 16 - (inputOctets - 16*numBlocks); +// assert(padLen > 0 && padLen <= 16); // DO SOMETHING HERE ? + for (i = 0; i < 16 - padLen; i++) { + block[i] = input[i] ^ iv[i]; + } + for (i = 16 - padLen; i < 16; i++) { + block[i] = (UINT8)padLen ^ iv[i]; + } + encrypt(block,outBuffer); + break; + default: + return -1; + break; + } + + return 16*(numBlocks + 1); +} + +int Rijndael::blockDecrypt(const UINT8 *input, int inputLen, UINT8 *outBuffer) +{ + int i, k, numBlocks; + UINT8 block[16], iv[4][4]; + + if(m_state != Valid) return RIJNDAEL_NOT_INITIALIZED; + if((m_mode != CFB1) && (m_direction == Encrypt)) return RIJNDAEL_BAD_DIRECTION; + + if((input == 0) || (inputLen <= 0)) return 0; + + numBlocks = inputLen/128; + + switch(m_mode) + { + case ECB: + for (i = numBlocks; i > 0; i--) + { + decrypt(input,outBuffer); + input += 16; + outBuffer += 16; + } + break; + case CBC: +#if STRICT_ALIGN + memcpy(iv,m_initVector,16); +#else + *((UINT32*)iv[0]) = *((UINT32*)(m_initVector )); + *((UINT32*)iv[1]) = *((UINT32*)(m_initVector+ 4)); + *((UINT32*)iv[2]) = *((UINT32*)(m_initVector+ 8)); + *((UINT32*)iv[3]) = *((UINT32*)(m_initVector+12)); +#endif + for (i = numBlocks; i > 0; i--) + { + decrypt(input, block); + ((UINT32*)block)[0] ^= *((UINT32*)iv[0]); + ((UINT32*)block)[1] ^= *((UINT32*)iv[1]); + ((UINT32*)block)[2] ^= *((UINT32*)iv[2]); + ((UINT32*)block)[3] ^= *((UINT32*)iv[3]); +#if STRICT_ALIGN + memcpy(iv, input, 16); + memcpy(outBuf, block, 16); +#else + *((UINT32*)iv[0]) = ((UINT32*)input)[0]; ((UINT32*)outBuffer)[0] = ((UINT32*)block)[0]; + *((UINT32*)iv[1]) = ((UINT32*)input)[1]; ((UINT32*)outBuffer)[1] = ((UINT32*)block)[1]; + *((UINT32*)iv[2]) = ((UINT32*)input)[2]; ((UINT32*)outBuffer)[2] = ((UINT32*)block)[2]; + *((UINT32*)iv[3]) = ((UINT32*)input)[3]; ((UINT32*)outBuffer)[3] = ((UINT32*)block)[3]; +#endif + input += 16; + outBuffer += 16; + } + break; + case CFB1: +#if STRICT_ALIGN + memcpy(iv, m_initVector, 16); +#else + *((UINT32*)iv[0]) = *((UINT32*)(m_initVector)); + *((UINT32*)iv[1]) = *((UINT32*)(m_initVector+ 4)); + *((UINT32*)iv[2]) = *((UINT32*)(m_initVector+ 8)); + *((UINT32*)iv[3]) = *((UINT32*)(m_initVector+12)); +#endif + for(i = numBlocks; i > 0; i--) + { + for(k = 0; k < 128; k++) + { + *((UINT32*) block ) = *((UINT32*)iv[0]); + *((UINT32*)(block+ 4)) = *((UINT32*)iv[1]); + *((UINT32*)(block+ 8)) = *((UINT32*)iv[2]); + *((UINT32*)(block+12)) = *((UINT32*)iv[3]); + encrypt(block, block); + iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7); + iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7); + iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7); + iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7); + iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7); + iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7); + iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7); + iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7); + iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7); + iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7); + iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7); + iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7); + iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7); + iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7); + iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7); + iv[3][3] = (iv[3][3] << 1) | (input[k/8] >> (7-(k&7))) & 1; + outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7); + } + } + break; + default: + return -1; + break; + } + + return 128*numBlocks; +} + +int Rijndael::padDecrypt(const UINT8 *input, int inputOctets, UINT8 *outBuffer) +{ + int i, numBlocks, padLen; + UINT8 block[16]; + UINT32 iv[4]; + + if(m_state != Valid) return RIJNDAEL_NOT_INITIALIZED; + if(m_direction != Decrypt) return RIJNDAEL_BAD_DIRECTION; + + if(input == 0 || inputOctets <= 0) return 0; + + if((inputOctets % 16) != 0) return RIJNDAEL_CORRUPTED_DATA; + + numBlocks = inputOctets/16; + + switch(m_mode){ + case ECB: + for (i = numBlocks - 1; i > 0; i--) + { + decrypt(input, outBuffer); + input += 16; + outBuffer += 16; + } + + decrypt(input, block); + padLen = block[15]; + if ((padLen <= 0) || (padLen > 16)) return RIJNDAEL_CORRUPTED_DATA; + for(i = 16 - padLen; i < 16; i++) + { + if(block[i] != padLen) return RIJNDAEL_CORRUPTED_DATA; + } + memcpy(outBuffer, block, 16 - padLen); + break; + case CBC: + memcpy(iv, m_initVector, 16); + /* all blocks but last */ + for (i = numBlocks - 1; i > 0; i--) + { + decrypt(input, block); + ((UINT32*)block)[0] ^= iv[0]; + ((UINT32*)block)[1] ^= iv[1]; + ((UINT32*)block)[2] ^= iv[2]; + ((UINT32*)block)[3] ^= iv[3]; + memcpy(iv, input, 16); + memcpy(outBuffer, block, 16); + input += 16; + outBuffer += 16; + } + /* last block */ + decrypt(input, block); + ((UINT32*)block)[0] ^= iv[0]; + ((UINT32*)block)[1] ^= iv[1]; + ((UINT32*)block)[2] ^= iv[2]; + ((UINT32*)block)[3] ^= iv[3]; + padLen = block[15]; + if((padLen <= 0) || (padLen > 16)) return RIJNDAEL_CORRUPTED_DATA; + for(i = 16 - padLen; i < 16; i++) + { + if(block[i] != padLen) return RIJNDAEL_CORRUPTED_DATA; + } + memcpy(outBuffer, block, 16 - padLen); + break; + + default: + return -1; + break; + } + + return 16*numBlocks - padLen; +} + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// ALGORITHM +////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +void Rijndael::keySched(UINT8 key[_MAX_KEY_COLUMNS][4]) +{ + int j,rconpointer = 0; + + // Calculate the necessary round keys + // The number of calculations depends on keyBits and blockBits + int uKeyColumns = m_uRounds - 6; + + UINT8 tempKey[_MAX_KEY_COLUMNS][4]; + + // Copy the input key to the temporary key matrix + + for(j = 0;j < uKeyColumns;j++) + { + *((UINT32*)(tempKey[j])) = *((UINT32*)(key[j])); + } + + int r = 0; + int t = 0; + + // copy values into round key array + for(j = 0;(j < uKeyColumns) && (r <= (int)m_uRounds); ) + { + for(;(j < uKeyColumns) && (t < 4); j++, t++) + { + *((UINT32*)m_expandedKey[r][t]) = *((UINT32*)tempKey[j]); + } + + + if(t == 4) + { + r++; + t = 0; + } + } + + while(r <= (int)m_uRounds) + { + tempKey[0][0] ^= S[tempKey[uKeyColumns-1][1]]; + tempKey[0][1] ^= S[tempKey[uKeyColumns-1][2]]; + tempKey[0][2] ^= S[tempKey[uKeyColumns-1][3]]; + tempKey[0][3] ^= S[tempKey[uKeyColumns-1][0]]; + tempKey[0][0] ^= rcon[rconpointer++]; + + if (uKeyColumns != 8) + { + for(j = 1; j < uKeyColumns; j++) + { + *((UINT32*)tempKey[j]) ^= *((UINT32*)tempKey[j-1]); + } + } else { + for(j = 1; j < uKeyColumns/2; j++) + { + *((UINT32*)tempKey[j]) ^= *((UINT32*)tempKey[j-1]); + } + tempKey[uKeyColumns/2][0] ^= S[tempKey[uKeyColumns/2 - 1][0]]; + tempKey[uKeyColumns/2][1] ^= S[tempKey[uKeyColumns/2 - 1][1]]; + tempKey[uKeyColumns/2][2] ^= S[tempKey[uKeyColumns/2 - 1][2]]; + tempKey[uKeyColumns/2][3] ^= S[tempKey[uKeyColumns/2 - 1][3]]; + for(j = uKeyColumns/2 + 1; j < uKeyColumns; j++) + { + *((UINT32*)tempKey[j]) ^= *((UINT32*)tempKey[j-1]); + } + } + for(j = 0; (j < uKeyColumns) && (r <= (int)m_uRounds); ) + { + for(; (j < uKeyColumns) && (t < 4); j++, t++) + { + *((UINT32*)m_expandedKey[r][t]) = *((UINT32*)tempKey[j]); + } + if(t == 4) + { + r++; + t = 0; + } + } + } +} + +void Rijndael::keyEncToDec() +{ + int r; + UINT8 *w; + + for(r = 1; r < (int)m_uRounds; r++) + { + w = m_expandedKey[r][0]; + *((UINT32*)w) = *((UINT32*)U1[w[0]]) ^ *((UINT32*)U2[w[1]]) ^ *((UINT32*)U3[w[2]]) ^ *((UINT32*)U4[w[3]]); + w = m_expandedKey[r][1]; + *((UINT32*)w) = *((UINT32*)U1[w[0]]) ^ *((UINT32*)U2[w[1]]) ^ *((UINT32*)U3[w[2]]) ^ *((UINT32*)U4[w[3]]); + w = m_expandedKey[r][2]; + *((UINT32*)w) = *((UINT32*)U1[w[0]]) ^ *((UINT32*)U2[w[1]]) ^ *((UINT32*)U3[w[2]]) ^ *((UINT32*)U4[w[3]]); + w = m_expandedKey[r][3]; + *((UINT32*)w) = *((UINT32*)U1[w[0]]) ^ *((UINT32*)U2[w[1]]) ^ *((UINT32*)U3[w[2]]) ^ *((UINT32*)U4[w[3]]); + } +} + +void Rijndael::encrypt(const UINT8 a[16], UINT8 b[16]) +{ + int r; + UINT8 temp[4][4]; + + *((UINT32*)temp[0]) = *((UINT32*)(a )) ^ *((UINT32*)m_expandedKey[0][0]); + *((UINT32*)temp[1]) = *((UINT32*)(a+ 4)) ^ *((UINT32*)m_expandedKey[0][1]); + *((UINT32*)temp[2]) = *((UINT32*)(a+ 8)) ^ *((UINT32*)m_expandedKey[0][2]); + *((UINT32*)temp[3]) = *((UINT32*)(a+12)) ^ *((UINT32*)m_expandedKey[0][3]); + *((UINT32*)(b )) = *((UINT32*)T1[temp[0][0]]) + ^ *((UINT32*)T2[temp[1][1]]) + ^ *((UINT32*)T3[temp[2][2]]) + ^ *((UINT32*)T4[temp[3][3]]); + *((UINT32*)(b + 4)) = *((UINT32*)T1[temp[1][0]]) + ^ *((UINT32*)T2[temp[2][1]]) + ^ *((UINT32*)T3[temp[3][2]]) + ^ *((UINT32*)T4[temp[0][3]]); + *((UINT32*)(b + 8)) = *((UINT32*)T1[temp[2][0]]) + ^ *((UINT32*)T2[temp[3][1]]) + ^ *((UINT32*)T3[temp[0][2]]) + ^ *((UINT32*)T4[temp[1][3]]); + *((UINT32*)(b +12)) = *((UINT32*)T1[temp[3][0]]) + ^ *((UINT32*)T2[temp[0][1]]) + ^ *((UINT32*)T3[temp[1][2]]) + ^ *((UINT32*)T4[temp[2][3]]); + for(r = 1; r < (int)m_uRounds-1; r++) + { + *((UINT32*)temp[0]) = *((UINT32*)(b )) ^ *((UINT32*)m_expandedKey[r][0]); + *((UINT32*)temp[1]) = *((UINT32*)(b+ 4)) ^ *((UINT32*)m_expandedKey[r][1]); + *((UINT32*)temp[2]) = *((UINT32*)(b+ 8)) ^ *((UINT32*)m_expandedKey[r][2]); + *((UINT32*)temp[3]) = *((UINT32*)(b+12)) ^ *((UINT32*)m_expandedKey[r][3]); + + *((UINT32*)(b )) = *((UINT32*)T1[temp[0][0]]) + ^ *((UINT32*)T2[temp[1][1]]) + ^ *((UINT32*)T3[temp[2][2]]) + ^ *((UINT32*)T4[temp[3][3]]); + *((UINT32*)(b + 4)) = *((UINT32*)T1[temp[1][0]]) + ^ *((UINT32*)T2[temp[2][1]]) + ^ *((UINT32*)T3[temp[3][2]]) + ^ *((UINT32*)T4[temp[0][3]]); + *((UINT32*)(b + 8)) = *((UINT32*)T1[temp[2][0]]) + ^ *((UINT32*)T2[temp[3][1]]) + ^ *((UINT32*)T3[temp[0][2]]) + ^ *((UINT32*)T4[temp[1][3]]); + *((UINT32*)(b +12)) = *((UINT32*)T1[temp[3][0]]) + ^ *((UINT32*)T2[temp[0][1]]) + ^ *((UINT32*)T3[temp[1][2]]) + ^ *((UINT32*)T4[temp[2][3]]); + } + *((UINT32*)temp[0]) = *((UINT32*)(b )) ^ *((UINT32*)m_expandedKey[m_uRounds-1][0]); + *((UINT32*)temp[1]) = *((UINT32*)(b+ 4)) ^ *((UINT32*)m_expandedKey[m_uRounds-1][1]); + *((UINT32*)temp[2]) = *((UINT32*)(b+ 8)) ^ *((UINT32*)m_expandedKey[m_uRounds-1][2]); + *((UINT32*)temp[3]) = *((UINT32*)(b+12)) ^ *((UINT32*)m_expandedKey[m_uRounds-1][3]); + b[ 0] = T1[temp[0][0]][1]; + b[ 1] = T1[temp[1][1]][1]; + b[ 2] = T1[temp[2][2]][1]; + b[ 3] = T1[temp[3][3]][1]; + b[ 4] = T1[temp[1][0]][1]; + b[ 5] = T1[temp[2][1]][1]; + b[ 6] = T1[temp[3][2]][1]; + b[ 7] = T1[temp[0][3]][1]; + b[ 8] = T1[temp[2][0]][1]; + b[ 9] = T1[temp[3][1]][1]; + b[10] = T1[temp[0][2]][1]; + b[11] = T1[temp[1][3]][1]; + b[12] = T1[temp[3][0]][1]; + b[13] = T1[temp[0][1]][1]; + b[14] = T1[temp[1][2]][1]; + b[15] = T1[temp[2][3]][1]; + *((UINT32*)(b )) ^= *((UINT32*)m_expandedKey[m_uRounds][0]); + *((UINT32*)(b+ 4)) ^= *((UINT32*)m_expandedKey[m_uRounds][1]); + *((UINT32*)(b+ 8)) ^= *((UINT32*)m_expandedKey[m_uRounds][2]); + *((UINT32*)(b+12)) ^= *((UINT32*)m_expandedKey[m_uRounds][3]); +} + +void Rijndael::decrypt(const UINT8 a[16], UINT8 b[16]) +{ + int r; + UINT8 temp[4][4]; + + *((UINT32*)temp[0]) = *((UINT32*)(a )) ^ *((UINT32*)m_expandedKey[m_uRounds][0]); + *((UINT32*)temp[1]) = *((UINT32*)(a+ 4)) ^ *((UINT32*)m_expandedKey[m_uRounds][1]); + *((UINT32*)temp[2]) = *((UINT32*)(a+ 8)) ^ *((UINT32*)m_expandedKey[m_uRounds][2]); + *((UINT32*)temp[3]) = *((UINT32*)(a+12)) ^ *((UINT32*)m_expandedKey[m_uRounds][3]); + + *((UINT32*)(b )) = *((UINT32*)T5[temp[0][0]]) + ^ *((UINT32*)T6[temp[3][1]]) + ^ *((UINT32*)T7[temp[2][2]]) + ^ *((UINT32*)T8[temp[1][3]]); + *((UINT32*)(b+ 4)) = *((UINT32*)T5[temp[1][0]]) + ^ *((UINT32*)T6[temp[0][1]]) + ^ *((UINT32*)T7[temp[3][2]]) + ^ *((UINT32*)T8[temp[2][3]]); + *((UINT32*)(b+ 8)) = *((UINT32*)T5[temp[2][0]]) + ^ *((UINT32*)T6[temp[1][1]]) + ^ *((UINT32*)T7[temp[0][2]]) + ^ *((UINT32*)T8[temp[3][3]]); + *((UINT32*)(b+12)) = *((UINT32*)T5[temp[3][0]]) + ^ *((UINT32*)T6[temp[2][1]]) + ^ *((UINT32*)T7[temp[1][2]]) + ^ *((UINT32*)T8[temp[0][3]]); + for(r = m_uRounds-1; r > 1; r--) + { + *((UINT32*)temp[0]) = *((UINT32*)(b )) ^ *((UINT32*)m_expandedKey[r][0]); + *((UINT32*)temp[1]) = *((UINT32*)(b+ 4)) ^ *((UINT32*)m_expandedKey[r][1]); + *((UINT32*)temp[2]) = *((UINT32*)(b+ 8)) ^ *((UINT32*)m_expandedKey[r][2]); + *((UINT32*)temp[3]) = *((UINT32*)(b+12)) ^ *((UINT32*)m_expandedKey[r][3]); + *((UINT32*)(b )) = *((UINT32*)T5[temp[0][0]]) + ^ *((UINT32*)T6[temp[3][1]]) + ^ *((UINT32*)T7[temp[2][2]]) + ^ *((UINT32*)T8[temp[1][3]]); + *((UINT32*)(b+ 4)) = *((UINT32*)T5[temp[1][0]]) + ^ *((UINT32*)T6[temp[0][1]]) + ^ *((UINT32*)T7[temp[3][2]]) + ^ *((UINT32*)T8[temp[2][3]]); + *((UINT32*)(b+ 8)) = *((UINT32*)T5[temp[2][0]]) + ^ *((UINT32*)T6[temp[1][1]]) + ^ *((UINT32*)T7[temp[0][2]]) + ^ *((UINT32*)T8[temp[3][3]]); + *((UINT32*)(b+12)) = *((UINT32*)T5[temp[3][0]]) + ^ *((UINT32*)T6[temp[2][1]]) + ^ *((UINT32*)T7[temp[1][2]]) + ^ *((UINT32*)T8[temp[0][3]]); + } + + *((UINT32*)temp[0]) = *((UINT32*)(b )) ^ *((UINT32*)m_expandedKey[1][0]); + *((UINT32*)temp[1]) = *((UINT32*)(b+ 4)) ^ *((UINT32*)m_expandedKey[1][1]); + *((UINT32*)temp[2]) = *((UINT32*)(b+ 8)) ^ *((UINT32*)m_expandedKey[1][2]); + *((UINT32*)temp[3]) = *((UINT32*)(b+12)) ^ *((UINT32*)m_expandedKey[1][3]); + b[ 0] = S5[temp[0][0]]; + b[ 1] = S5[temp[3][1]]; + b[ 2] = S5[temp[2][2]]; + b[ 3] = S5[temp[1][3]]; + b[ 4] = S5[temp[1][0]]; + b[ 5] = S5[temp[0][1]]; + b[ 6] = S5[temp[3][2]]; + b[ 7] = S5[temp[2][3]]; + b[ 8] = S5[temp[2][0]]; + b[ 9] = S5[temp[1][1]]; + b[10] = S5[temp[0][2]]; + b[11] = S5[temp[3][3]]; + b[12] = S5[temp[3][0]]; + b[13] = S5[temp[2][1]]; + b[14] = S5[temp[1][2]]; + b[15] = S5[temp[0][3]]; + *((UINT32*)(b )) ^= *((UINT32*)m_expandedKey[0][0]); + *((UINT32*)(b+ 4)) ^= *((UINT32*)m_expandedKey[0][1]); + *((UINT32*)(b+ 8)) ^= *((UINT32*)m_expandedKey[0][2]); + *((UINT32*)(b+12)) ^= *((UINT32*)m_expandedKey[0][3]); +} + + diff --git a/src/crypto/rijndael.h b/src/crypto/rijndael.h new file mode 100755 index 0000000..f5f299d --- /dev/null +++ b/src/crypto/rijndael.h @@ -0,0 +1,158 @@ +#ifndef _RIJNDAEL_H_ +#define _RIJNDAEL_H_ + +// This file is based on Szymon Stefanek's Rijndael implementation. +// All I have done is changed the variable type definitions, not more. +// The original header is below. + +// +// File : rijndael.h +// Creation date : Sun Nov 5 2000 03:21:05 CEST +// Author : Szymon Stefanek (stefanek@tin.it) +// +// Another implementation of the Rijndael cipher. +// This is intended to be an easily usable library file. +// This code is public domain. +// Based on the Vincent Rijmen and K.U.Leuven implementation 2.4. +// + +// +// Original Copyright notice: +// +// rijndael-alg-fst.c v2.4 April '2000 +// rijndael-alg-fst.h +// rijndael-api-fst.c +// rijndael-api-fst.h +// +// Optimised ANSI C code +// +// authors: v1.0: Antoon Bosselaers +// v2.0: Vincent Rijmen, K.U.Leuven +// v2.3: Paulo Barreto +// v2.4: Vincent Rijmen, K.U.Leuven +// +// This code is placed in the public domain. +// + +// +// This implementation works on 128 , 192 , 256 bit keys +// and on 128 bit blocks +// + +// +// Example of usage: +// +// // Input data +// unsigned char key[32]; // The key +// initializeYour256BitKey(); // Obviously initialized with sth +// const unsigned char * plainText = getYourPlainText(); // Your plain text +// int plainTextLen = strlen(plainText); // Plain text length +// +// // Encrypting +// Rijndael rin; +// unsigned char output[plainTextLen + 16]; +// +// rin.init(Rijndael::CBC,Rijndael::Encrypt,key,Rijndael::Key32Bytes); +// // It is a good idea to check the error code +// int len = rin.padEncrypt(plainText,len,output); +// if(len >= 0)useYourEncryptedText(); +// else encryptError(len); +// +// // Decrypting: we can reuse the same object +// unsigned char output2[len]; +// rin.init(Rijndael::CBC,Rijndael::Decrypt,key,Rijndael::Key32Bytes)); +// len = rin.padDecrypt(output,len,output2); +// if(len >= 0)useYourDecryptedText(); +// else decryptError(len); +// + +#define _MAX_KEY_COLUMNS (256/32) +#define _MAX_ROUNDS 14 +#define MAX_IV_SIZE 16 + +#include + +// Error codes +#define RIJNDAEL_SUCCESS 0 +#define RIJNDAEL_UNSUPPORTED_MODE -1 +#define RIJNDAEL_UNSUPPORTED_DIRECTION -2 +#define RIJNDAEL_UNSUPPORTED_KEY_LENGTH -3 +#define RIJNDAEL_BAD_KEY -4 +#define RIJNDAEL_NOT_INITIALIZED -5 +#define RIJNDAEL_BAD_DIRECTION -6 +#define RIJNDAEL_CORRUPTED_DATA -7 + +class Rijndael +{ +public: + enum Direction { Encrypt , Decrypt }; + enum Mode { ECB , CBC , CFB1 }; + enum KeyLength { Key16Bytes , Key24Bytes , Key32Bytes }; + // + // Creates a Rijndael cipher object + // You have to call init() before you can encrypt or decrypt stuff + // + Rijndael(); + ~Rijndael(); +protected: + // Internal stuff + enum State { Valid , Invalid }; + + State m_state; + Mode m_mode; + Direction m_direction; + UINT8 m_initVector[MAX_IV_SIZE]; + UINT32 m_uRounds; + UINT8 m_expandedKey[_MAX_ROUNDS+1][4][4]; +public: + ////////////////////////////////////////////////////////////////////////////////////////// + // API + ////////////////////////////////////////////////////////////////////////////////////////// + + // init(): Initializes the crypt session + // Returns RIJNDAEL_SUCCESS or an error code + // mode : Rijndael::ECB, Rijndael::CBC or Rijndael::CFB1 + // You have to use the same mode for encrypting and decrypting + // dir : Rijndael::Encrypt or Rijndael::Decrypt + // A cipher instance works only in one direction + // (Well , it could be easily modified to work in both + // directions with a single init() call, but it looks + // useless to me...anyway , it is a matter of generating + // two expanded keys) + // key : array of unsigned octets , it can be 16 , 24 or 32 bytes long + // this CAN be binary data (it is not expected to be null terminated) + // keyLen : Rijndael::Key16Bytes , Rijndael::Key24Bytes or Rijndael::Key32Bytes + // initVector: initialization vector, you will usually use 0 here + int init(Mode mode,Direction dir,const UINT8 *key,KeyLength keyLen,UINT8 * initVector = 0); + // Encrypts the input array (can be binary data) + // The input array length must be a multiple of 16 bytes, the remaining part + // is DISCARDED. + // so it actually encrypts inputLen / 128 blocks of input and puts it in outBuffer + // Input len is in BITS! + // outBuffer must be at least inputLen / 8 bytes long. + // Returns the encrypted buffer length in BITS or an error code < 0 in case of error + int blockEncrypt(const UINT8 *input, int inputLen, UINT8 *outBuffer); + // Encrypts the input array (can be binary data) + // The input array can be any length , it is automatically padded on a 16 byte boundary. + // Input len is in BYTES! + // outBuffer must be at least (inputLen + 16) bytes long + // Returns the encrypted buffer length in BYTES or an error code < 0 in case of error + int padEncrypt(const UINT8 *input, int inputOctets, UINT8 *outBuffer); + // Decrypts the input vector + // Input len is in BITS! + // outBuffer must be at least inputLen / 8 bytes long + // Returns the decrypted buffer length in BITS and an error code < 0 in case of error + int blockDecrypt(const UINT8 *input, int inputLen, UINT8 *outBuffer); + // Decrypts the input vector + // Input len is in BYTES! + // outBuffer must be at least inputLen bytes long + // Returns the decrypted buffer length in BYTES and an error code < 0 in case of error + int padDecrypt(const UINT8 *input, int inputOctets, UINT8 *outBuffer); +protected: + void keySched(UINT8 key[_MAX_KEY_COLUMNS][4]); + void keyEncToDec(); + void encrypt(const UINT8 a[16], UINT8 b[16]); + void decrypt(const UINT8 a[16], UINT8 b[16]); +}; + +#endif // _RIJNDAEL_H_ diff --git a/src/crypto/sha1.cpp b/src/crypto/sha1.cpp new file mode 100755 index 0000000..c6693c1 --- /dev/null +++ b/src/crypto/sha1.cpp @@ -0,0 +1,261 @@ +/* + 100% free public domain implementation of the SHA-1 algorithm + by Dominik Reichl + + Version 1.5 - 2005-01-01 + - 64-bit compiler compatibility added + - Made variable wiping optional (define SHA1_WIPE_VARIABLES) + - Removed unnecessary variable initializations + - ROL32 improvement for the Microsoft compiler (using _rotl) + + ======== Test Vectors (from FIPS PUB 180-1) ======== + + SHA1("abc") = + A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D + + SHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = + 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 + + SHA1(A million repetitions of "a") = + 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F +*/ + +#include "sha1.h" + +#define SHA1_MAX_FILE_BUFFER 8000 + +// Rotate x bits to the left +#ifndef ROL32 +#ifdef _MSC_VER +#define ROL32(_val32, _nBits) _rotl(_val32, _nBits) +#else +#define ROL32(_val32, _nBits) (((_val32)<<(_nBits))|((_val32)>>(32-(_nBits)))) +#endif +#endif + +#ifdef SHA1_LITTLE_ENDIAN +#define SHABLK0(i) (m_block->l[i] = \ + (ROL32(m_block->l[i],24) & 0xFF00FF00) | (ROL32(m_block->l[i],8) & 0x00FF00FF)) +#else +#define SHABLK0(i) (m_block->l[i]) +#endif + +#define SHABLK(i) (m_block->l[i&15] = ROL32(m_block->l[(i+13)&15] ^ m_block->l[(i+8)&15] \ + ^ m_block->l[(i+2)&15] ^ m_block->l[i&15],1)) + +// SHA-1 rounds +#define _R0(v,w,x,y,z,i) { z+=((w&(x^y))^y)+SHABLK0(i)+0x5A827999+ROL32(v,5); w=ROL32(w,30); } +#define _R1(v,w,x,y,z,i) { z+=((w&(x^y))^y)+SHABLK(i)+0x5A827999+ROL32(v,5); w=ROL32(w,30); } +#define _R2(v,w,x,y,z,i) { z+=(w^x^y)+SHABLK(i)+0x6ED9EBA1+ROL32(v,5); w=ROL32(w,30); } +#define _R3(v,w,x,y,z,i) { z+=(((w|x)&y)|(w&x))+SHABLK(i)+0x8F1BBCDC+ROL32(v,5); w=ROL32(w,30); } +#define _R4(v,w,x,y,z,i) { z+=(w^x^y)+SHABLK(i)+0xCA62C1D6+ROL32(v,5); w=ROL32(w,30); } + +CSHA1::CSHA1() +{ + m_block = (SHA1_WORKSPACE_BLOCK *)m_workspace; + + Reset(); +} + +CSHA1::~CSHA1() +{ + Reset(); +} + +void CSHA1::Reset() +{ + // SHA1 initialization constants + m_state[0] = 0x67452301; + m_state[1] = 0xEFCDAB89; + m_state[2] = 0x98BADCFE; + m_state[3] = 0x10325476; + m_state[4] = 0xC3D2E1F0; + + m_count[0] = 0; + m_count[1] = 0; +} +void CSHA1::Update(unsigned char* data, int len){ + + UINT_32 i, j; + + j = (m_count[0] >> 3) & 63; + + if((m_count[0] += len << 3) < (len << 3)) m_count[1]++; + + m_count[1] += (len >> 29); + + if((j + len) > 63) + { + i = 64 - j; + memcpy(&m_buffer[j], data, i); + Transform(m_state, m_buffer); + + for( ; i + 63 < len; i += 64) Transform(m_state, &data[i]); + + j = 0; + } + else i = 0; + + memcpy(&m_buffer[j], &data[i], len - i); + + +} + + +void CSHA1::Transform(UINT_32 *state, UINT_8 *buffer) +{ + // Copy state[] to working vars + UINT_32 a = state[0], b = state[1], c = state[2], d = state[3], e = state[4]; + + memcpy(m_block, buffer, 64); + + // 4 rounds of 20 operations each. Loop unrolled. + _R0(a,b,c,d,e, 0); _R0(e,a,b,c,d, 1); _R0(d,e,a,b,c, 2); _R0(c,d,e,a,b, 3); + _R0(b,c,d,e,a, 4); _R0(a,b,c,d,e, 5); _R0(e,a,b,c,d, 6); _R0(d,e,a,b,c, 7); + _R0(c,d,e,a,b, 8); _R0(b,c,d,e,a, 9); _R0(a,b,c,d,e,10); _R0(e,a,b,c,d,11); + _R0(d,e,a,b,c,12); _R0(c,d,e,a,b,13); _R0(b,c,d,e,a,14); _R0(a,b,c,d,e,15); + _R1(e,a,b,c,d,16); _R1(d,e,a,b,c,17); _R1(c,d,e,a,b,18); _R1(b,c,d,e,a,19); + _R2(a,b,c,d,e,20); _R2(e,a,b,c,d,21); _R2(d,e,a,b,c,22); _R2(c,d,e,a,b,23); + _R2(b,c,d,e,a,24); _R2(a,b,c,d,e,25); _R2(e,a,b,c,d,26); _R2(d,e,a,b,c,27); + _R2(c,d,e,a,b,28); _R2(b,c,d,e,a,29); _R2(a,b,c,d,e,30); _R2(e,a,b,c,d,31); + _R2(d,e,a,b,c,32); _R2(c,d,e,a,b,33); _R2(b,c,d,e,a,34); _R2(a,b,c,d,e,35); + _R2(e,a,b,c,d,36); _R2(d,e,a,b,c,37); _R2(c,d,e,a,b,38); _R2(b,c,d,e,a,39); + _R3(a,b,c,d,e,40); _R3(e,a,b,c,d,41); _R3(d,e,a,b,c,42); _R3(c,d,e,a,b,43); + _R3(b,c,d,e,a,44); _R3(a,b,c,d,e,45); _R3(e,a,b,c,d,46); _R3(d,e,a,b,c,47); + _R3(c,d,e,a,b,48); _R3(b,c,d,e,a,49); _R3(a,b,c,d,e,50); _R3(e,a,b,c,d,51); + _R3(d,e,a,b,c,52); _R3(c,d,e,a,b,53); _R3(b,c,d,e,a,54); _R3(a,b,c,d,e,55); + _R3(e,a,b,c,d,56); _R3(d,e,a,b,c,57); _R3(c,d,e,a,b,58); _R3(b,c,d,e,a,59); + _R4(a,b,c,d,e,60); _R4(e,a,b,c,d,61); _R4(d,e,a,b,c,62); _R4(c,d,e,a,b,63); + _R4(b,c,d,e,a,64); _R4(a,b,c,d,e,65); _R4(e,a,b,c,d,66); _R4(d,e,a,b,c,67); + _R4(c,d,e,a,b,68); _R4(b,c,d,e,a,69); _R4(a,b,c,d,e,70); _R4(e,a,b,c,d,71); + _R4(d,e,a,b,c,72); _R4(c,d,e,a,b,73); _R4(b,c,d,e,a,74); _R4(a,b,c,d,e,75); + _R4(e,a,b,c,d,76); _R4(d,e,a,b,c,77); _R4(c,d,e,a,b,78); _R4(b,c,d,e,a,79); + + // Add the working vars back into state + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + + // Wipe variables +#ifdef SHA1_WIPE_VARIABLES + a = b = c = d = e = 0; +#endif +} + + +// Hash in file contents +bool CSHA1::HashFile(char *szFileName) +{ + unsigned long ulFileSize, ulRest, ulBlocks; + unsigned long i; + UINT_8 uData[SHA1_MAX_FILE_BUFFER]; + FILE *fIn; + + if(szFileName == NULL) return false; + + fIn = fopen(szFileName, "rb"); + if(fIn == NULL) return false; + + fseek(fIn, 0, SEEK_END); + ulFileSize = (unsigned long)ftell(fIn); + fseek(fIn, 0, SEEK_SET); + + if(ulFileSize != 0) + { + ulBlocks = ulFileSize / SHA1_MAX_FILE_BUFFER; + ulRest = ulFileSize % SHA1_MAX_FILE_BUFFER; + } + else + { + ulBlocks = 0; + ulRest = 0; + } + + for(i = 0; i < ulBlocks; i++) + { + fread(uData, 1, SHA1_MAX_FILE_BUFFER, fIn); + Update((UINT_8 *)uData, SHA1_MAX_FILE_BUFFER); + } + + if(ulRest != 0) + { + fread(uData, 1, ulRest, fIn); + Update((UINT_8 *)uData, ulRest); + } + + fclose(fIn); fIn = NULL; + return true; +} + +void CSHA1::Final() +{ + UINT_32 i; + UINT_8 finalcount[8]; + + for(i = 0; i < 8; i++) + finalcount[i] = (UINT_8)((m_count[((i >= 4) ? 0 : 1)] + >> ((3 - (i & 3)) * 8) ) & 255); // Endian independent + + Update((UINT_8 *)"\200", 1); + + while ((m_count[0] & 504) != 448) + Update((UINT_8 *)"\0", 1); + + Update(finalcount, 8); // Cause a SHA1Transform() + + for(i = 0; i < 20; i++) + { + m_digest[i] = (UINT_8)((m_state[i >> 2] >> ((3 - (i & 3)) * 8) ) & 255); + } + + // Wipe variables for security reasons +#ifdef SHA1_WIPE_VARIABLES + i = 0; + memset(m_buffer, 0, 64); + memset(m_state, 0, 20); + memset(m_count, 0, 8); + memset(finalcount, 0, 8); + Transform(m_state, m_buffer); +#endif +} + +// Get the final hash as a pre-formatted string +void CSHA1::ReportHash(char *szReport, unsigned char uReportType) +{ + unsigned char i; + char szTemp[16]; + + if(szReport == NULL) return; + + if(uReportType == REPORT_HEX) + { + sprintf(szTemp, "%02X", m_digest[0]); + strcat(szReport, szTemp); + + for(i = 1; i < 20; i++) + { + sprintf(szTemp, " %02X", m_digest[i]); + strcat(szReport, szTemp); + } + } + else if(uReportType == REPORT_DIGIT) + { + sprintf(szTemp, "%u", m_digest[0]); + strcat(szReport, szTemp); + + for(i = 1; i < 20; i++) + { + sprintf(szTemp, " %u", m_digest[i]); + strcat(szReport, szTemp); + } + } + else strcpy(szReport, "Error: Unknown report type!"); +} + +// Get the raw message digest +void CSHA1::GetHash(UINT_8 *puDest) +{ + memcpy(puDest, m_digest, 20); +} diff --git a/src/crypto/sha1.h b/src/crypto/sha1.h new file mode 100755 index 0000000..c5c8f44 --- /dev/null +++ b/src/crypto/sha1.h @@ -0,0 +1,99 @@ +/* + 100% free public domain implementation of the SHA-1 algorithm + by Dominik Reichl + + Version 1.5 - 2005-01-01 + - 64-bit compiler compatibility added + - Made variable wiping optional (define SHA1_WIPE_VARIABLES) + - Removed unnecessary variable initializations + - ROL32 improvement for the Microsoft compiler (using _rotl) + + ======== Test Vectors (from FIPS PUB 180-1) ======== + + SHA1("abc") = + A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D + + SHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = + 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 + + SHA1(A million repetitions of "a") = + 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F +*/ + +#ifndef ___SHA1_HDR___ +#define ___SHA1_HDR___ + +#include // Needed for file access +#include // Needed for memset and memcpy +#include // Needed for strcat and strcpy + + +// If you're compiling big endian, just comment out the following line +#define SHA1_LITTLE_ENDIAN + +// #define or #undef this, if you want the CSHA1 class to wipe all +// temporary variables after processing +#define SHA1_WIPE_VARIABLES + +///////////////////////////////////////////////////////////////////////////// +// Define 8- and 32-bit variables + +#ifndef UINT_32 + #define UINT_8 unsigned char + #if (ULONG_MAX == 0xFFFFFFFF) + #define UINT_32 unsigned long + #else + #define UINT_32 unsigned int + #endif +#endif + + +///////////////////////////////////////////////////////////////////////////// +// Declare SHA1 workspace + +typedef union +{ + UINT_8 c[64]; + UINT_32 l[16]; +} SHA1_WORKSPACE_BLOCK; + +class CSHA1 +{ +public: + // Two different formats for ReportHash(...) + enum + { + REPORT_HEX = 0, + REPORT_DIGIT = 1 + }; + + // Constructor and Destructor + CSHA1(); + ~CSHA1(); + + UINT_32 m_state[5]; + UINT_32 m_count[2]; + UINT_8 m_buffer[64]; + UINT_8 m_digest[20]; + + void Reset(); + + // Update the hash value + void Update(unsigned char* data, int len); + bool HashFile(char *szFileName); + + // Finalize hash and report + void Final(); + void ReportHash(char *szReport, unsigned char uReportType = REPORT_HEX); + void GetHash(UINT_8 *puDest); + +private: + // Private SHA-1 transformation + void Transform(UINT_32 *state, UINT_8 *buffer); + + // Member variables + UINT_8 m_workspace[64]; + SHA1_WORKSPACE_BLOCK *m_block; // SHA1 pointer to the byte array above +}; + +#endif diff --git a/src/crypto/sha256.c b/src/crypto/sha256.c new file mode 100755 index 0000000..0b94581 --- /dev/null +++ b/src/crypto/sha256.c @@ -0,0 +1,369 @@ +/* + * FIPS-180-2 compliant SHA-256 implementation + * + * Copyright (C) 2001-2003 Christophe Devine + * + * 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 + */ + +#include + +#include "sha256.h" + +#define GET_UINT32(n,b,i) \ +{ \ + (n) = ( (uint32) (b)[(i) ] << 24 ) \ + | ( (uint32) (b)[(i) + 1] << 16 ) \ + | ( (uint32) (b)[(i) + 2] << 8 ) \ + | ( (uint32) (b)[(i) + 3] ); \ +} + +#define PUT_UINT32(n,b,i) \ +{ \ + (b)[(i) ] = (uint8) ( (n) >> 24 ); \ + (b)[(i) + 1] = (uint8) ( (n) >> 16 ); \ + (b)[(i) + 2] = (uint8) ( (n) >> 8 ); \ + (b)[(i) + 3] = (uint8) ( (n) ); \ +} + +void sha256_starts( sha256_context *ctx ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + ctx->state[0] = 0x6A09E667; + ctx->state[1] = 0xBB67AE85; + ctx->state[2] = 0x3C6EF372; + ctx->state[3] = 0xA54FF53A; + ctx->state[4] = 0x510E527F; + ctx->state[5] = 0x9B05688C; + ctx->state[6] = 0x1F83D9AB; + ctx->state[7] = 0x5BE0CD19; +} + +void sha256_process( sha256_context *ctx, uint8 data[64] ) +{ + uint32 temp1, temp2, W[64]; + uint32 A, B, C, D, E, F, G, H; + + GET_UINT32( W[0], data, 0 ); + GET_UINT32( W[1], data, 4 ); + GET_UINT32( W[2], data, 8 ); + GET_UINT32( W[3], data, 12 ); + GET_UINT32( W[4], data, 16 ); + GET_UINT32( W[5], data, 20 ); + GET_UINT32( W[6], data, 24 ); + GET_UINT32( W[7], data, 28 ); + GET_UINT32( W[8], data, 32 ); + GET_UINT32( W[9], data, 36 ); + GET_UINT32( W[10], data, 40 ); + GET_UINT32( W[11], data, 44 ); + GET_UINT32( W[12], data, 48 ); + GET_UINT32( W[13], data, 52 ); + GET_UINT32( W[14], data, 56 ); + GET_UINT32( W[15], data, 60 ); + +#define SHR(x,n) ((x & 0xFFFFFFFF) >> n) +#define ROTR(x,n) (SHR(x,n) | (x << (32 - n))) + +#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3)) +#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10)) + +#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22)) +#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25)) + +#define F0(x,y,z) ((x & y) | (z & (x | y))) +#define F1(x,y,z) (z ^ (x & (y ^ z))) + +#define R(t) \ +( \ + W[t] = S1(W[t - 2]) + W[t - 7] + \ + S0(W[t - 15]) + W[t - 16] \ +) + +#define P(a,b,c,d,e,f,g,h,x,K) \ +{ \ + temp1 = h + S3(e) + F1(e,f,g) + K + x; \ + temp2 = S2(a) + F0(a,b,c); \ + d += temp1; h = temp1 + temp2; \ +} + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + E = ctx->state[4]; + F = ctx->state[5]; + G = ctx->state[6]; + H = ctx->state[7]; + + P( A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98 ); + P( H, A, B, C, D, E, F, G, W[ 1], 0x71374491 ); + P( G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF ); + P( F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5 ); + P( E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B ); + P( D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1 ); + P( C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4 ); + P( B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5 ); + P( A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98 ); + P( H, A, B, C, D, E, F, G, W[ 9], 0x12835B01 ); + P( G, H, A, B, C, D, E, F, W[10], 0x243185BE ); + P( F, G, H, A, B, C, D, E, W[11], 0x550C7DC3 ); + P( E, F, G, H, A, B, C, D, W[12], 0x72BE5D74 ); + P( D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE ); + P( C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7 ); + P( B, C, D, E, F, G, H, A, W[15], 0xC19BF174 ); + P( A, B, C, D, E, F, G, H, R(16), 0xE49B69C1 ); + P( H, A, B, C, D, E, F, G, R(17), 0xEFBE4786 ); + P( G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6 ); + P( F, G, H, A, B, C, D, E, R(19), 0x240CA1CC ); + P( E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F ); + P( D, E, F, G, H, A, B, C, R(21), 0x4A7484AA ); + P( C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC ); + P( B, C, D, E, F, G, H, A, R(23), 0x76F988DA ); + P( A, B, C, D, E, F, G, H, R(24), 0x983E5152 ); + P( H, A, B, C, D, E, F, G, R(25), 0xA831C66D ); + P( G, H, A, B, C, D, E, F, R(26), 0xB00327C8 ); + P( F, G, H, A, B, C, D, E, R(27), 0xBF597FC7 ); + P( E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3 ); + P( D, E, F, G, H, A, B, C, R(29), 0xD5A79147 ); + P( C, D, E, F, G, H, A, B, R(30), 0x06CA6351 ); + P( B, C, D, E, F, G, H, A, R(31), 0x14292967 ); + P( A, B, C, D, E, F, G, H, R(32), 0x27B70A85 ); + P( H, A, B, C, D, E, F, G, R(33), 0x2E1B2138 ); + P( G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC ); + P( F, G, H, A, B, C, D, E, R(35), 0x53380D13 ); + P( E, F, G, H, A, B, C, D, R(36), 0x650A7354 ); + P( D, E, F, G, H, A, B, C, R(37), 0x766A0ABB ); + P( C, D, E, F, G, H, A, B, R(38), 0x81C2C92E ); + P( B, C, D, E, F, G, H, A, R(39), 0x92722C85 ); + P( A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1 ); + P( H, A, B, C, D, E, F, G, R(41), 0xA81A664B ); + P( G, H, A, B, C, D, E, F, R(42), 0xC24B8B70 ); + P( F, G, H, A, B, C, D, E, R(43), 0xC76C51A3 ); + P( E, F, G, H, A, B, C, D, R(44), 0xD192E819 ); + P( D, E, F, G, H, A, B, C, R(45), 0xD6990624 ); + P( C, D, E, F, G, H, A, B, R(46), 0xF40E3585 ); + P( B, C, D, E, F, G, H, A, R(47), 0x106AA070 ); + P( A, B, C, D, E, F, G, H, R(48), 0x19A4C116 ); + P( H, A, B, C, D, E, F, G, R(49), 0x1E376C08 ); + P( G, H, A, B, C, D, E, F, R(50), 0x2748774C ); + P( F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5 ); + P( E, F, G, H, A, B, C, D, R(52), 0x391C0CB3 ); + P( D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A ); + P( C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F ); + P( B, C, D, E, F, G, H, A, R(55), 0x682E6FF3 ); + P( A, B, C, D, E, F, G, H, R(56), 0x748F82EE ); + P( H, A, B, C, D, E, F, G, R(57), 0x78A5636F ); + P( G, H, A, B, C, D, E, F, R(58), 0x84C87814 ); + P( F, G, H, A, B, C, D, E, R(59), 0x8CC70208 ); + P( E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA ); + P( D, E, F, G, H, A, B, C, R(61), 0xA4506CEB ); + P( C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7 ); + P( B, C, D, E, F, G, H, A, R(63), 0xC67178F2 ); + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; + ctx->state[4] += E; + ctx->state[5] += F; + ctx->state[6] += G; + ctx->state[7] += H; +} + +void sha256_update( sha256_context *ctx, uint8 *input, uint32 length ) +{ + uint32 left, fill; + + if( ! length ) return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += length; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < length ) + ctx->total[1]++; + + if( left && length >= fill ) + { + memcpy( (void *) (ctx->buffer + left), + (void *) input, fill ); + sha256_process( ctx, ctx->buffer ); + length -= fill; + input += fill; + left = 0; + } + + while( length >= 64 ) + { + sha256_process( ctx, input ); + length -= 64; + input += 64; + } + + if( length ) + { + memcpy( (void *) (ctx->buffer + left), + (void *) input, length ); + } +} + +static uint8 sha256_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +void sha256_finish( sha256_context *ctx, uint8 digest[32] ) +{ + uint32 last, padn; + uint32 high, low; + uint8 msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_UINT32( high, msglen, 0 ); + PUT_UINT32( low, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + sha256_update( ctx, sha256_padding, padn ); + sha256_update( ctx, msglen, 8 ); + + PUT_UINT32( ctx->state[0], digest, 0 ); + PUT_UINT32( ctx->state[1], digest, 4 ); + PUT_UINT32( ctx->state[2], digest, 8 ); + PUT_UINT32( ctx->state[3], digest, 12 ); + PUT_UINT32( ctx->state[4], digest, 16 ); + PUT_UINT32( ctx->state[5], digest, 20 ); + PUT_UINT32( ctx->state[6], digest, 24 ); + PUT_UINT32( ctx->state[7], digest, 28 ); +} + +#ifdef TEST + +#include +#include + +/* + * those are the standard FIPS-180-2 test vectors + */ + +static char *msg[] = +{ + "abc", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + NULL +}; + +static char *val[] = +{ + "ba7816bf8f01cfea414140de5dae2223" \ + "b00361a396177a9cb410ff61f20015ad", + "248d6a61d20638b8e5c026930c3e6039" \ + "a33ce45964ff2167f6ecedd419db06c1", + "cdc76e5c9914fb9281a1c7e284d73e67" \ + "f1809a48a497200e046d39ccc7112cd0" +}; + +int main( int argc, char *argv[] ) +{ + FILE *f; + int i, j; + char output[65]; + sha256_context ctx; + unsigned char buf[1000]; + unsigned char sha256sum[32]; + + if( argc < 2 ) + { + printf( "\n SHA-256 Validation Tests:\n\n" ); + + for( i = 0; i < 3; i++ ) + { + printf( " Test %d ", i + 1 ); + + sha256_starts( &ctx ); + + if( i < 2 ) + { + sha256_update( &ctx, (uint8 *) msg[i], + strlen( msg[i] ) ); + } + else + { + memset( buf, 'a', 1000 ); + + for( j = 0; j < 1000; j++ ) + { + sha256_update( &ctx, (uint8 *) buf, 1000 ); + } + } + + sha256_finish( &ctx, sha256sum ); + + for( j = 0; j < 32; j++ ) + { + sprintf( output + j * 2, "%02x", sha256sum[j] ); + } + + if( memcmp( output, val[i], 64 ) ) + { + printf( "failed!\n" ); + return( 1 ); + } + + printf( "passed.\n" ); + } + + printf( "\n" ); + } + else + { + if( ! ( f = fopen( argv[1], "rb" ) ) ) + { + perror( "fopen" ); + return( 1 ); + } + + sha256_starts( &ctx ); + + while( ( i = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) + { + sha256_update( &ctx, buf, i ); + } + + sha256_finish( &ctx, sha256sum ); + + for( j = 0; j < 32; j++ ) + { + printf( "%02x", sha256sum[j] ); + } + + printf( " %s\n", argv[1] ); + } + + return( 0 ); +} + +#endif diff --git a/src/crypto/sha256.h b/src/crypto/sha256.h new file mode 100755 index 0000000..63db9a3 --- /dev/null +++ b/src/crypto/sha256.h @@ -0,0 +1,32 @@ +#ifndef _SHA256_H +#define _SHA256_H + +#ifndef uint8 +#define uint8 unsigned char +#endif + +#ifndef uint32 +#define uint32 unsigned long int +#endif + +typedef struct +{ + uint32 total[2]; + uint32 state[8]; + uint8 buffer[64]; +} +sha256_context; + +#ifdef __cplusplus +extern "C" { //Für C++ Kompalibilität +#endif + +extern void sha256_starts( sha256_context *ctx ); +extern void sha256_update( sha256_context *ctx, uint8 *input, uint32 length ); +extern void sha256_finish( sha256_context *ctx, uint8 digest[32] ); + +#ifdef __cplusplus +} +#endif + +#endif /* sha256.h */ diff --git a/src/crypto/twoclass.cpp b/src/crypto/twoclass.cpp new file mode 100755 index 0000000..796c299 --- /dev/null +++ b/src/crypto/twoclass.cpp @@ -0,0 +1,148 @@ +/* + Copyright (c) 2003/2004, Dominik Reichl + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + - Neither the name of ReichlSoft nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include "twoclass.h" + +static bool g_bInitialized = false; + +CTwofish::CTwofish() +{ +} + +CTwofish::~CTwofish() +{ +} + +bool CTwofish::init(UINT8 *pKey, unsigned long uKeyLen, UINT8 *initVector) +{ + //ASSERT(pKey != NULL); + if(pKey == NULL) return false; + //ASSERT(uKeyLen != 0); + if(uKeyLen == 0) return false; + + if(g_bInitialized == false) + { + Twofish_initialise(); + g_bInitialized = true; + } + + Twofish_prepare_key((Twofish_Byte *)pKey, uKeyLen, &m_key); + + if(initVector != NULL) memcpy(m_pInitVector, initVector, 16); + else memset(m_pInitVector, 0, 16); + + return true; +} + +int CTwofish::padEncrypt(UINT8 *pInput, int nInputOctets, UINT8 *pOutBuffer) +{ + int i, numBlocks, padLen; + UINT8 block[16], *iv; + + //ASSERT((pInput != NULL) && (nInputOctets != NULL) && (pOutBuffer != NULL)); + if((pInput == NULL) || (nInputOctets <= 0) || (pOutBuffer == NULL)) return 0; + + numBlocks = nInputOctets / 16; + + iv = m_pInitVector; + for(i = numBlocks; i > 0; i--) + { + ((UINT32*)block)[0] = ((UINT32*)pInput)[0] ^ ((UINT32*)iv)[0]; + ((UINT32*)block)[1] = ((UINT32*)pInput)[1] ^ ((UINT32*)iv)[1]; + ((UINT32*)block)[2] = ((UINT32*)pInput)[2] ^ ((UINT32*)iv)[2]; + ((UINT32*)block)[3] = ((UINT32*)pInput)[3] ^ ((UINT32*)iv)[3]; + + Twofish_encrypt(&m_key, (Twofish_Byte *)block, (Twofish_Byte *)pOutBuffer); + + iv = pOutBuffer; + pInput += 16; + pOutBuffer += 16; + } + + padLen = 16 - (nInputOctets - (16 * numBlocks)); + + for (i = 0; i < 16 - padLen; i++) + { + block[i] = (UINT8)(pInput[i] ^ iv[i]); + } + + for (i = 16 - padLen; i < 16; i++) + { + block[i] = (UINT8)((UINT8)padLen ^ iv[i]); + } + + Twofish_encrypt(&m_key, (Twofish_Byte *)block, (Twofish_Byte *)pOutBuffer); + + return 16 * (numBlocks + 1); +} + +int CTwofish::padDecrypt(UINT8 *pInput, int nInputOctets, UINT8 *pOutBuffer) +{ + int i, numBlocks, padLen; + UINT8 block[16]; + UINT32 iv[4]; + + //ASSERT((pInput != NULL) && (nInputOctets != NULL) && (pOutBuffer != NULL)); + if((pInput == NULL) || (nInputOctets <= 0) || (pOutBuffer == NULL)) return 0; + + if((nInputOctets % 16) != 0) { /*ASSERT(FALSE);*/ return -1; } + + numBlocks = nInputOctets / 16; + + memcpy(iv, m_pInitVector, 16); + + for(i = numBlocks - 1; i > 0; i--) + { + Twofish_decrypt(&m_key, (Twofish_Byte *)pInput, (Twofish_Byte *)block); + ((UINT32*)block)[0] ^= iv[0]; + ((UINT32*)block)[1] ^= iv[1]; + ((UINT32*)block)[2] ^= iv[2]; + ((UINT32*)block)[3] ^= iv[3]; + memcpy(iv, pInput, 16); + memcpy(pOutBuffer, block, 16); + pInput += 16; + pOutBuffer += 16; + } + + Twofish_decrypt(&m_key, (Twofish_Byte *)pInput, (Twofish_Byte *)block); + ((UINT32*)block)[0] ^= iv[0]; + ((UINT32*)block)[1] ^= iv[1]; + ((UINT32*)block)[2] ^= iv[2]; + ((UINT32*)block)[3] ^= iv[3]; + padLen = block[15]; + if(padLen <= 0 || padLen > 16) return -1; + for(i = 16 - padLen; i < 16; i++) + { + if(block[i] != padLen) return -1; + } + memcpy(pOutBuffer, block, 16 - padLen); + + return 16*numBlocks - padLen; +} diff --git a/src/crypto/twoclass.h b/src/crypto/twoclass.h new file mode 100755 index 0000000..86bde39 --- /dev/null +++ b/src/crypto/twoclass.h @@ -0,0 +1,52 @@ +/* + Copyright (c) 2003/2004, Dominik Reichl + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + - Neither the name of ReichlSoft nor the names of its contributors may be + used to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef ___TWOFISH_CLASS_H___ +#define ___TWOFISH_CLASS_H___ + +#include "twofish.h" +#include "crypto/rijndael.h" + +class CTwofish +{ +public: + CTwofish(); + virtual ~CTwofish(); + + bool init(UINT8 *pKey, unsigned long uKeyLen, UINT8 *initVector = NULL); + + int padEncrypt(UINT8 *pInput, int nInputOctets, UINT8 *pOutBuffer); + int padDecrypt(UINT8 *pInput, int nInputOctets, UINT8 *pOutBuffer); + +private: + Twofish_key m_key; + UINT8 m_pInitVector[16]; +}; + +#endif diff --git a/src/crypto/twofish.cpp b/src/crypto/twofish.cpp new file mode 100755 index 0000000..3123719 --- /dev/null +++ b/src/crypto/twofish.cpp @@ -0,0 +1,1705 @@ +/* + * Fast, portable, and easy-to-use Twofish implementation, + * Version 0.3. + * Copyright (c) 2002 by Niels Ferguson. + * (See further down for the almost-unrestricted licensing terms.) + * + * -------------------------------------------------------------------------- + * There are two files for this implementation: + * - twofish.h, the header file. + * - twofish.c, the code file. + * + * To incorporate this code into your program you should: + * - Check the licensing terms further down in this comment. + * - Fix the two type definitions in twofish.h to suit your platform. + * - Fix a few definitions in twofish.c in the section marked + * PLATFORM FIXES. There is one important ones that affects + * functionality, and then a few definitions that you can optimise + * for efficiency but those have no effect on the functionality. + * Don't change anything else. + * - Put the code in your project and compile it. + * + * To use this library you should: + * - Call Twofish_initialise() in your program before any other function in + * this library. + * - Use Twofish_prepare_key(...) to convert a key to internal form. + * - Use Twofish_encrypt(...) and Twofish_decrypt(...) to encrypt and decrypt + * data. + * See the comments in the header file for details on these functions. + * -------------------------------------------------------------------------- + * + * There are many Twofish implementation available for free on the web. + * Most of them are hard to integrate into your own program. + * As we like people to use our cipher, I thought I would make it easier. + * Here is a free and easy-to-integrate Twofish implementation in C. + * The latest version is always available from my personal home page at + * http://niels.ferguson.net/ + * + * Integrating library code into a project is difficult because the library + * header files interfere with the project's header files and code. + * And of course the project's header files interfere with the library code. + * I've tried to resolve these problems here. + * The header file of this implementation is very light-weight. + * It contains two typedefs, a structure, and a few function declarations. + * All names it defines start with "Twofish_". + * The header file is therefore unlikely to cause problems in your project. + * The code file of this implementation doesn't need to include the header + * files of the project. There is thus no danger of the project interfering + * with all the definitions and macros of the Twofish code. + * In most situations, all you need to do is fill in a few platform-specific + * definitions in the header file and code file, + * and you should be able to run the Twofish code in your project. + * I estimate it should take you less than an hour to integrate this code + * into your project, most of it spent reading the comments telling you what + * to do. + * + * For people using C++: it is very easy to wrap this library into a + * TwofishKey class. One of the big advantages is that you can automate the + * wiping of the key material in the destructor. I have not provided a C++ + * class because the interface depends too much on the abstract base class + * you use for block ciphers in your program, which I don't know about. + * + * This implementation is designed for use on PC-class machines. It uses the + * Twofish 'full' keying option which uses large tables. Total table size is + * around 5-6 kB for static tables plus 4.5 kB for each pre-processed key. + * If you need an implementation that uses less memory, + * take a look at Brian Gladman's code on his web site: + * http://fp.gladman.plus.com/cryptography_technology/aes/ + * He has code for all AES candidates. + * His Twofish code has lots of options trading off table size vs. speed. + * You can also take a look at the optimised code by Doug Whiting on the + * Twofish web site + * http://www.counterpane.com/twofish.html + * which has loads of options. + * I believe these existing implementations are harder to re-use because they + * are not clean libraries and they impose requirements on the environment. + * This implementation is very careful to minimise those, + * and should be easier to integrate into any larger program. + * + * The default mode of this implementation is fully portable as it uses no + * behaviour not defined in the C standard. (This is harder than you think.) + * If you have any problems porting the default mode, please let me know + * so that I can fix the problem. (But only if this code is at fault, I + * don't fix compilers.) + * Most of the platform fixes are related to non-portable but faster ways + * of implementing certain functions. + * + * In general I've tried to make the code as fast as possible, at the expense + * of memory and code size. However, C does impose limits, and this + * implementation will be slower than an optimised assembler implementation. + * But beware of assembler implementations: a good Pentium implementation + * uses completely different code than a good Pentium II implementation. + * You basically have to re-write the assembly code for every generation of + * processor. Unless you are severely pressed for speed, stick with C. + * + * The initialisation routine of this implementation contains a self-test. + * If initialisation succeeds without calling the fatal routine, then + * the implementation works. I don't think you can break the implementation + * in such a way that it still passes the tests, unless you are malicious. + * In other words: if the initialisation routine returns, + * you have successfully ported the implementation. + * (Or not implemented the fatal routine properly, but that is your problem.) + * + * I'm indebted to many people who helped me in one way or another to write + * this code. During the design of Twofish and the AES process I had very + * extensive discussions of all implementation issues with various people. + * Doug Whiting in particular provided a wealth of information. The Twofish + * team spent untold hours discussion various cipher features, and their + * implementation. Brian Gladman implemented all AES candidates in C, + * and we had some fruitful discussions on how to implement Twofish in C. + * Jan Nieuwenhuizen tested this code on Linux using GCC. + * + * Now for the license: + * The author hereby grants a perpetual license to everybody to + * use this code for any purpose as long as the copyright message is included + * in the source code of this or any derived work. + * + * Yes, this means that you, your company, your club, and anyone else + * can use this code anywhere you want. You can change it and distribute it + * under the GPL, include it in your commercial product without releasing + * the source code, put it on the web, etc. + * The only thing you cannot do is remove my copyright message, + * or distribute any source code based on this implementation that does not + * include my copyright message. + * + * I appreciate a mention in the documentation or credits, + * but I understand if that is difficult to do. + * I also appreciate it if you tell me where and why you used my code. + * + * Please send any questions or comments to niels@ferguson.net + * + * Have Fun! + * + * Niels + */ + +/* + * DISCLAIMER: As I'm giving away my work for free, I'm of course not going + * to accept any liability of any form. This code, or the Twofish cipher, + * might very well be flawed; you have been warned. + * This software is provided as-is, without any kind of warrenty or + * guarantee. And that is really all you can expect when you download + * code for free from the Internet. + * + * I think it is really sad that disclaimers like this seem to be necessary. + * If people only had a little bit more common sense, and didn't come + * whining like little children every time something happens.... + */ + +/* + * Version history: + * Version 0.0, 2002-08-30 + * First written. + * Version 0.1, 2002-09-03 + * Added disclaimer. Improved self-tests. + * Version 0.2, 2002-09-09 + * Removed last non-portabilities. Default now works completely within + * the C standard. UInt32 can be larger than 32 bits without problems. + * Version 0.3, 2002-09-28 + * Bugfix: use instead of to adhere to ANSI/ISO. + * Rename BIG_ENDIAN macro to CPU_IS_BIG_ENDIAN. The gcc library + * header already defines BIG_ENDIAN, even though it is not + * supposed to. + */ + + +/* + * Minimum set of include files. + * You should not need any application-specific include files for this code. + * In fact, adding you own header files could break one of the many macros or + * functions in this file. Be very careful. + * Standard include files will probably be ok. + */ + +#include /* for memset(), memcpy(), and memcmp() */ +#include "twofish.h" + + +/* + * PLATFORM FIXES + * ============== + * + * Fix the type definitions in twofish.h first! + * + * The following definitions have to be fixed for each particular platform + * you work on. If you have a multi-platform program, you no doubt have + * portable definitions that you can substitute here without changing the + * rest of the code. + */ + + +/* + * Function called if something is fatally wrong with the implementation. + * This fatal function is called when a coding error is detected in the + * Twofish implementation, or when somebody passes an obviously erroneous + * parameter to this implementation. There is not much you can do when + * the code contains bugs, so we just stop. + * + * The argument is a string. Ideally the fatal function prints this string + * as an error message. Whatever else this function does, it should never + * return. A typical implementation would stop the program completely after + * printing the error message. + * + * This default implementation is not very useful, + * but does not assume anything about your environment. + * It will at least let you know something is wrong.... + * I didn't want to include any libraries to print and error or so, + * as this makes the code much harder to integrate in a project. + * + * Note that the Twofish_fatal function may not return to the caller. + * Unfortunately this is not something the self-test can test for, + * so you have to make sure of this yourself. + * + * If you want to call an external function, be careful about including + * your own header files here. This code uses a lot of macros, and your + * header file could easily break it. Maybe the best solution is to use + * a separate extern statement for your fatal function. + */ + +//#define Twofish_fatal(pmsgx) { MessageBox(GetDesktopWindow(), _T(pmsgx), _T("Twofish Fatal Error"), MB_OK); } + + +/* + * The rest of the settings are not important for the functionality + * of this Twofish implementation. That is, their default settings + * work on all platforms. You can change them to improve the + * speed of the implementation on your platform. Erroneous settings + * will result in erroneous implementations, but the self-test should + * catch those. + */ + + +/* + * Macros to rotate a Twofish_UInt32 value left or right by the + * specified number of bits. This should be a 32-bit rotation, + * and not rotation of, say, 64-bit values. + * + * Every encryption or decryption operation uses 32 of these rotations, + * so it is a good idea to make these macros efficient. + * + * This fully portable definition has one piece of tricky stuff. + * The UInt32 might be larger than 32 bits, so we have to mask + * any higher bits off. The simplest way to do this is to 'and' the + * value first with 0xffffffff and then shift it right. An optimising + * compiler that has a 32-bit type can optimise this 'and' away. + * + * Unfortunately there is no portable way of writing the constant + * 0xffffffff. You don't know which suffix to use (U, or UL?) + * The UINT32_MASK definition uses a bit of trickery. Shift-left + * is only defined if the shift amount is strictly less than the size + * of the UInt32, so we can't use (1<<32). The answer it to take the value + * 2, cast it to a UInt32, shift it left 31 positions, and subtract one. + * Another example of how to make something very simple extremely difficult. + * I hate C. + * + * The rotation macros are straightforward. + * They are only applied to UInt32 values, which are _unsigned_ + * so the >> operator must do a logical shift that brings in zeroes. + * On most platforms you will only need to optimise the ROL32 macro; the + * ROR32 macro is not inefficient on an optimising compiler as all rotation + * amounts in this code are known at compile time. + * + * On many platforms there is a faster solution. + * For example, MS compilers have the __rotl and __rotr functions + * that generate x86 rotation instructions. + */ +#define UINT32_MASK ( (((Twofish_UInt32)2)<<31) - 1 ) + +#ifndef _MSC_VER +#define ROL32(x,n) ( (x)<<(n) | ((x) & UINT32_MASK) >> (32-(n)) ) +#define ROR32(x,n) ( (x)>>(n) | ((x) & UINT32_MASK) << (32-(n)) ) +#else +#define ROL32(x,n) (_lrotl((x), (n))) +#define ROR32(x,n) (_lrotr((x), (n))) +#endif + +/* + * Select data type for q-table entries. + * + * Larger entry types cost more memory (1.5 kB), and might be faster + * or slower depending on the CPU and compiler details. + * + * This choice only affects the static data size and the key setup speed. + * Functionality, expanded key size, or encryption speed are not affected. + * Define to 1 to get large q-table entries. + */ +#define LARGE_Q_TABLE 0 /* default = 0 */ + + +/* + * Method to select a single byte from a UInt32. + * WARNING: non-portable code if set; might not work on all platforms. + * + * Inside the inner loop of Twofish it is necessary to access the 4 + * individual bytes of a UInt32. This can be done using either shifts + * and masks, or memory accesses. + * + * Set to 0 to use shift and mask operations for the byte selection. + * This is more ALU intensive. It is also fully portable. + * + * Set to 1 to use memory accesses. The UInt32 is stored in memory and + * the individual bytes are read from memory one at a time. + * This solution is more memory-intensive, and not fully portable. + * It might be faster on your platform, or not. If you use this option, + * make sure you set the CPU_IS_BIG_ENDIAN flag appropriately. + * + * This macro does not affect the conversion of the inputs and outputs + * of the cipher. See the CONVERT_USING_CASTS macro for that. + */ +#define SELECT_BYTE_FROM_UINT32_IN_MEMORY 0 /* default = 0 */ + + +/* + * Method used to read the input and write the output. + * WARNING: non-portable code if set; might not work on all platforms. + * + * Twofish operates on 32-bit words. The input to the cipher is + * a byte array, as is the output. The portable method of doing the + * conversion is a bunch of rotate and mask operations, but on many + * platforms it can be done faster using a cast. + * This only works if your CPU allows UInt32 accesses to arbitrary Byte + * addresses. + * + * Set to 0 to use the shift and mask operations. This is fully + * portable. . + * + * Set to 1 to use a cast. The Byte * is cast to a UInt32 *, and a + * UInt32 is read. If necessary (as indicated by the CPU_IS_BIG_ENDIAN + * macro) the byte order in the UInt32 is swapped. The reverse is done + * to write the output of the encryption/decryption. Make sure you set + * the CPU_IS_BIG_ENDIAN flag appropriately. + * This option does not work unless a UInt32 is exactly 32 bits. + * + * This macro only changes the reading/writing of the plaintext/ciphertext. + * See the SELECT_BYTE_FROM_UINT32_IN_MEMORY to affect the way in which + * a UInt32 is split into 4 bytes for the S-box selection. + */ +#define CONVERT_USING_CASTS 0 /* default = 0 */ + + +/* + * Endianness switch. + * Only relevant if SELECT_BYTE_FROM_UINT32_IN_MEMORY or + * CONVERT_USING_CASTS is set. + * + * Set to 1 on a big-endian machine, and to 0 on a little-endian machine. + * Twofish uses the little-endian convention (least significant byte first) + * and big-endian machines (using most significant byte first) + * have to do a few conversions. + * + * CAUTION: This code has never been tested on a big-endian machine, + * because I don't have access to one. Feedback appreciated. + */ +#define CPU_IS_BIG_ENDIAN 0 + + +/* + * Macro to reverse the order of the bytes in a UInt32. + * Used to convert to little-endian on big-endian machines. + * This macro is always tested, but only used in the encryption and + * decryption if CONVERT_USING_CASTS, and CPU_IS_BIG_ENDIAN + * are both set. In other words: this macro is only speed-critical if + * both these flags have been set. + * + * This default definition of SWAP works, but on many platforms there is a + * more efficient implementation. + */ +#define BSWAP(x) (ROL32((x),8)&0x00ff00ff | ROR32((x),8) & 0xff00ff00) + + +/* + * END OF PLATFORM FIXES + * ===================== + * + * You should not have to touch the rest of this file. + */ + + +/* + * Convert the external type names to some that are easier to use inside + * this file. I didn't want to use the names Byte and UInt32 in the + * header file, because many programs already define them and using two + * conventions at once can be very difficult. + * Don't change these definitions! Change the originals + * in twofish.h instead. + */ +/* A Byte must be an unsigned integer, 8 bits long. */ +// typedef Twofish_Byte Byte; +/* A UInt32 must be an unsigned integer at least 32 bits long. */ +// typedef Twofish_UInt32 UInt32; + + +/* + * Define a macro ENDIAN_CONVERT. + * + * We define a macro ENDIAN_CONVERT that performs a BSWAP on big-endian + * machines, and is the identity function on little-endian machines. + * The code then uses this macro without considering the endianness. + */ + +#if CPU_IS_BIG_ENDIAN +#define ENDIAN_CONVERT(x) BSWAP(x) +#else +#define ENDIAN_CONVERT(x) (x) +#endif + + +/* + * Compute byte offset within a UInt32 stored in memory. + * + * This is only used when SELECT_BYTE_FROM_UINT32_IN_MEMORY is set. + * + * The input is the byte number 0..3, 0 for least significant. + * Note the use of sizeof() to support UInt32 types that are larger + * than 4 bytes. + */ +#if CPU_IS_BIG_ENDIAN +#define BYTE_OFFSET( n ) (sizeof(Twofish_UInt32) - 1 - (n) ) +#else +#define BYTE_OFFSET( n ) (n) +#endif + + +/* + * Macro to get Byte no. b from UInt32 value X. + * We use two different definition, depending on the settings. + */ +#if SELECT_BYTE_FROM_UINT32_IN_MEMORY + /* Pick the byte from the memory in which X is stored. */ +#define SELECT_BYTE( X, b ) (((Twofish_Byte *)(&(X)))[BYTE_OFFSET(b)]) +#else + /* Portable solution: Pick the byte directly from the X value. */ +#define SELECT_BYTE( X, b ) (((X) >> (8*(b))) & 0xff) +#endif + + +/* Some shorthands because we use byte selection in large formulae. */ +#define b0(X) SELECT_BYTE((X),0) +#define b1(X) SELECT_BYTE((X),1) +#define b2(X) SELECT_BYTE((X),2) +#define b3(X) SELECT_BYTE((X),3) + + +/* + * We need macros to load and store UInt32 from/to byte arrays + * using the least-significant-byte-first convention. + * + * GET32( p ) gets a UInt32 in lsb-first form from four bytes pointed to + * by p. + * PUT32( v, p ) writes the UInt32 value v at address p in lsb-first form. + */ +#if CONVERT_USING_CASTS + + /* Get UInt32 from four bytes pointed to by p. */ +#define GET32( p ) ENDIAN_CONVERT( *((Twofish_UInt32 *)(p)) ) + /* Put UInt32 into four bytes pointed to by p */ +#define PUT32( v, p ) *((Twofish_UInt32 *)(p)) = ENDIAN_CONVERT(v) + +#else + + /* Get UInt32 from four bytes pointed to by p. */ +#define GET32( p ) \ + ( \ + (Twofish_UInt32)((p)[0]) \ + | (Twofish_UInt32)((p)[1])<< 8 \ + | (Twofish_UInt32)((p)[2])<<16 \ + | (Twofish_UInt32)((p)[3])<<24 \ + ) + /* Put UInt32 into four bytes pointed to by p */ +#define PUT32( v, p ) \ + (p)[0] = (Twofish_Byte)(((v) ) & 0xff); \ + (p)[1] = (Twofish_Byte)(((v) >> 8) & 0xff); \ + (p)[2] = (Twofish_Byte)(((v) >> 16) & 0xff); \ + (p)[3] = (Twofish_Byte)(((v) >> 24) & 0xff) + +#endif + +#include +void Twofish_fatal(char* msg){ +QMessageBox::critical(0,"Interner Fehler",msg,"OK","Cancel",0,2,1); +} + + + +/* + * Test the platform-specific macros. + * This function tests the macros defined so far to make sure the + * definitions are appropriate for this platform. + * If you make any mistake in the platform configuration, this should detect + * that and inform you what went wrong. + * Somewhere, someday, this is going to save somebody a lot of time, + * because misbehaving macros are hard to debug. + */ +static void test_platform() + { + /* Buffer with test values. */ + Twofish_Byte buf[] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0}; + Twofish_UInt32 C; + Twofish_UInt32 x,y; + int i; + + /* + * Some sanity checks on the types that can't be done in compile time. + * A smart compiler will just optimise these tests away. + * The pre-processor doesn't understand different types, so we cannot + * do these checks in compile-time. + * + * I hate C. + * + * The first check in each case is to make sure the size is correct. + * The second check is to ensure that it is an unsigned type. + */ + if( ((Twofish_UInt32)((Twofish_UInt32)1 << 31) == 0) || ((Twofish_UInt32)-1 < 0 )) + { + Twofish_fatal( "Twofish code: Twofish_UInt32 type not suitable" ); + } + if( (sizeof( Twofish_Byte ) != 1) || (((Twofish_Byte)-1) < 0) ) + { + Twofish_fatal( "Twofish code: Twofish_Byte type not suitable" ); + } + + /* + * Sanity-check the endianness conversions. + * This is just an aid to find problems. If you do the endianness + * conversion macros wrong you will fail the full cipher test, + * but that does not help you find the error. + * Always make it easy to find the bugs! + * + * Detail: There is no fully portable way of writing UInt32 constants, + * as you don't know whether to use the U or UL suffix. Using only U you + * might only be allowed 16-bit constants. Using UL you might get 64-bit + * constants which cannot be stored in a UInt32 without warnings, and + * which generally behave subtly different from a true UInt32. + * As long as we're just comparing with the constant, + * we can always use the UL suffix and at worst lose some efficiency. + * I use a separate '32-bit constant' macro in most of my other code. + * + * I hate C. + * + * Start with testing GET32. We test it on all positions modulo 4 + * to make sure we can handly any position of inputs. (Some CPUs + * do not allow non-aligned accesses which we would do if you used + * the CONVERT_USING_CASTS option. + */ + if( (GET32( buf ) != 0x78563412UL) || (GET32(buf+1) != 0x9a785634UL) + || (GET32( buf+2 ) != 0xbc9a7856UL) || (GET32(buf+3) != 0xdebc9a78UL) ) + { + Twofish_fatal( "Twofish code: GET32 not implemented properly" ); + } + + /* + * We can now use GET32 to test PUT32. + * We don't test the shifted versions. If GET32 can do that then + * so should PUT32. + */ + C = GET32( buf ); + PUT32( 3*C, buf ); + if( GET32( buf ) != 0x69029c36UL ) + { + Twofish_fatal( "Twofish code: PUT32 not implemented properly" ); + } + + + /* Test ROL and ROR */ + for( i=1; i<32; i++ ) + { + /* Just a simple test. */ + x = ROR32( C, i ); + y = ROL32( C, i ); + x ^= (C>>i) ^ (C<<(32-i)); + y ^= (C<>(32-i)); + x |= y; + /* + * Now all we check is that x is zero in the least significant + * 32 bits. Using the UL suffix is safe here, as it doesn't matter + * if we get a larger type. + */ + if( (x & 0xffffffffUL) != 0 ) + { + Twofish_fatal( "Twofish ROL or ROR not properly defined." ); + } + } + + /* Test the BSWAP macro */ + if( BSWAP(C) != 0x12345678UL ) + { + /* + * The BSWAP macro should always work, even if you are not using it. + * A smart optimising compiler will just remove this entire test. + */ + Twofish_fatal( "BSWAP not properly defined." ); + } + + /* And we can test the b macros which use SELECT_BYTE. */ + if( (b0(C)!=0x12) || (b1(C) != 0x34) || (b2(C) != 0x56) || (b3(C) != 0x78) ) + { + /* + * There are many reasons why this could fail. + * Most likely is that CPU_IS_BIG_ENDIAN has the wrong value. + */ + Twofish_fatal( "Twofish code: SELECT_BYTE not implemented properly" ); + } + } + + +/* + * Finally, we can start on the Twofish-related code. + * You really need the Twofish specifications to understand this code. The + * best source is the Twofish book: + * "The Twofish Encryption Algorithm", by Bruce Schneier, John Kelsey, + * Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson. + * you can also use the AES submission document of Twofish, which is + * available from my list of publications on my personal web site at + * http://niels.ferguson.net/. + * + * The first thing we do is write the testing routines. This is what the + * implementation has to satisfy in the end. We only test the external + * behaviour of the implementation of course. + */ + + +/* + * Perform a single self test on a (plaintext,ciphertext,key) triple. + * Arguments: + * key array of key bytes + * key_len length of key in bytes + * p plaintext + * c ciphertext + */ +static void test_vector( Twofish_Byte key[], int key_len, Twofish_Byte p[16], Twofish_Byte c[16] ) + { + Twofish_Byte tmp[16]; /* scratch pad. */ + Twofish_key xkey; /* The expanded key */ + int i; + + + /* Prepare the key */ + Twofish_prepare_key( key, key_len, &xkey ); + + /* + * We run the test twice to ensure that the xkey structure + * is not damaged by the first encryption. + * Those are hideous bugs to find if you get them in an application. + */ + for( i=0; i<2; i++ ) + { + /* Encrypt and test */ + Twofish_encrypt( &xkey, p, tmp ); + if( memcmp( c, tmp, 16 ) != 0 ) + { + Twofish_fatal( "Twofish encryption failure" ); + } + + /* Decrypt and test */ + Twofish_decrypt( &xkey, c, tmp ); + if( memcmp( p, tmp, 16 ) != 0 ) + { + Twofish_fatal( "Twofish decryption failure" ); + } + } + + /* The test keys are not secret, so we don't need to wipe xkey. */ + } + + +/* + * Check implementation using three (key,plaintext,ciphertext) + * test vectors, one for each major key length. + * + * This is an absolutely minimal self-test. + * This routine does not test odd-sized keys. + */ +static void test_vectors() + { + /* + * We run three tests, one for each major key length. + * These test vectors come from the Twofish specification. + * One encryption and one decryption using randomish data and key + * will detect almost any error, especially since we generate the + * tables ourselves, so we don't have the problem of a single + * damaged table entry in the source. + */ + + /* 128-bit test is the I=3 case of section B.2 of the Twofish book. */ + static Twofish_Byte k128[] = { + 0x9F, 0x58, 0x9F, 0x5C, 0xF6, 0x12, 0x2C, 0x32, + 0xB6, 0xBF, 0xEC, 0x2F, 0x2A, 0xE8, 0xC3, 0x5A, + }; + static Twofish_Byte p128[] = { + 0xD4, 0x91, 0xDB, 0x16, 0xE7, 0xB1, 0xC3, 0x9E, + 0x86, 0xCB, 0x08, 0x6B, 0x78, 0x9F, 0x54, 0x19 + }; + static Twofish_Byte c128[] = { + 0x01, 0x9F, 0x98, 0x09, 0xDE, 0x17, 0x11, 0x85, + 0x8F, 0xAA, 0xC3, 0xA3, 0xBA, 0x20, 0xFB, 0xC3 + }; + + /* 192-bit test is the I=4 case of section B.2 of the Twofish book. */ + static Twofish_Byte k192[] = { + 0x88, 0xB2, 0xB2, 0x70, 0x6B, 0x10, 0x5E, 0x36, + 0xB4, 0x46, 0xBB, 0x6D, 0x73, 0x1A, 0x1E, 0x88, + 0xEF, 0xA7, 0x1F, 0x78, 0x89, 0x65, 0xBD, 0x44 + }; + static Twofish_Byte p192[] = { + 0x39, 0xDA, 0x69, 0xD6, 0xBA, 0x49, 0x97, 0xD5, + 0x85, 0xB6, 0xDC, 0x07, 0x3C, 0xA3, 0x41, 0xB2 + }; + static Twofish_Byte c192[] = { + 0x18, 0x2B, 0x02, 0xD8, 0x14, 0x97, 0xEA, 0x45, + 0xF9, 0xDA, 0xAC, 0xDC, 0x29, 0x19, 0x3A, 0x65 + }; + + /* 256-bit test is the I=4 case of section B.2 of the Twofish book. */ + static Twofish_Byte k256[] = { + 0xD4, 0x3B, 0xB7, 0x55, 0x6E, 0xA3, 0x2E, 0x46, + 0xF2, 0xA2, 0x82, 0xB7, 0xD4, 0x5B, 0x4E, 0x0D, + 0x57, 0xFF, 0x73, 0x9D, 0x4D, 0xC9, 0x2C, 0x1B, + 0xD7, 0xFC, 0x01, 0x70, 0x0C, 0xC8, 0x21, 0x6F + }; + static Twofish_Byte p256[] = { + 0x90, 0xAF, 0xE9, 0x1B, 0xB2, 0x88, 0x54, 0x4F, + 0x2C, 0x32, 0xDC, 0x23, 0x9B, 0x26, 0x35, 0xE6 + }; + static Twofish_Byte c256[] = { + 0x6C, 0xB4, 0x56, 0x1C, 0x40, 0xBF, 0x0A, 0x97, + 0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA + }; + + /* Run the actual tests. */ + test_vector( k128, 16, p128, c128 ); + test_vector( k192, 24, p192, c192 ); + test_vector( k256, 32, p256, c256 ); + } + + +/* + * Perform extensive test for a single key size. + * + * Test a single key size against the test vectors from section + * B.2 in the Twofish book. This is a sequence of 49 encryptions + * and decryptions. Each plaintext is equal to the ciphertext of + * the previous encryption. The key is made up from the ciphertext + * two and three encryptions ago. Both plaintext and key start + * at the zero value. + * We should have designed a cleaner recurrence relation for + * these tests, but it is too late for that now. At least we learned + * how to do it better next time. + * For details see appendix B of the book. + * + * Arguments: + * key_len Number of bytes of key + * final_value Final plaintext value after 49 iterations + */ +static void test_sequence( int key_len, Twofish_Byte final_value[] ) + { + Twofish_Byte buf[ (50+3)*16 ]; /* Buffer to hold our computation values. */ + Twofish_Byte tmp[16]; /* Temp for testing the decryption. */ + Twofish_key xkey; /* The expanded key */ + int i; + Twofish_Byte * p; + + /* Wipe the buffer */ + memset( buf, 0, sizeof( buf ) ); + + /* + * Because the recurrence relation is done in an inconvenient manner + * we end up looping backwards over the buffer. + */ + + /* Pointer in buffer points to current plaintext. */ + p = &buf[50*16]; + for( i=1; i<50; i++ ) + { + /* + * Prepare a key. + * This automatically checks that key_len is valid. + */ + Twofish_prepare_key( p+16, key_len, &xkey ); + + /* Compute the next 16 bytes in the buffer */ + Twofish_encrypt( &xkey, p, p-16 ); + + /* Check that the decryption is correct. */ + Twofish_decrypt( &xkey, p-16, tmp ); + if( memcmp( tmp, p, 16 ) != 0 ) + { + Twofish_fatal( "Twofish decryption failure in sequence" ); + } + /* Move on to next 16 bytes in the buffer. */ + p -= 16; + } + + /* And check the final value. */ + if( memcmp( p, final_value, 16 ) != 0 ) + { + Twofish_fatal( "Twofish encryption failure in sequence" ); + } + + /* None of the data was secret, so there is no need to wipe anything. */ + } + + +/* + * Run all three sequence tests from the Twofish test vectors. + * + * This checks the most extensive test vectors currently available + * for Twofish. The data is from the Twofish book, appendix B.2. + */ +static void test_sequences() + { + static Twofish_Byte r128[] = { + 0x5D, 0x9D, 0x4E, 0xEF, 0xFA, 0x91, 0x51, 0x57, + 0x55, 0x24, 0xF1, 0x15, 0x81, 0x5A, 0x12, 0xE0 + }; + static Twofish_Byte r192[] = { + 0xE7, 0x54, 0x49, 0x21, 0x2B, 0xEE, 0xF9, 0xF4, + 0xA3, 0x90, 0xBD, 0x86, 0x0A, 0x64, 0x09, 0x41 + }; + static Twofish_Byte r256[] = { + 0x37, 0xFE, 0x26, 0xFF, 0x1C, 0xF6, 0x61, 0x75, + 0xF5, 0xDD, 0xF4, 0xC3, 0x3B, 0x97, 0xA2, 0x05 + }; + + /* Run the three sequence test vectors */ + test_sequence( 16, r128 ); + test_sequence( 24, r192 ); + test_sequence( 32, r256 ); + } + + +/* + * Test the odd-sized keys. + * + * Every odd-sized key is equivalent to a one of 128, 192, or 256 bits. + * The equivalent key is found by padding at the end with zero bytes + * until a regular key size is reached. + * + * We just test that the key expansion routine behaves properly. + * If the expanded keys are identical, then the encryptions and decryptions + * will behave the same. + */ +static void test_odd_sized_keys() + { + Twofish_Byte buf[32]; + Twofish_key xkey; + Twofish_key xkey_two; + int i; + + /* + * We first create an all-zero key to use as PRNG key. + * Normally we would not have to fill the buffer with zeroes, as we could + * just pass a zero key length to the Twofish_prepare_key function. + * However, this relies on using odd-sized keys, and those are just the + * ones we are testing here. We can't use an untested function to test + * itself. + */ + memset( buf, 0, sizeof( buf ) ); + Twofish_prepare_key( buf, 16, &xkey ); + + /* Fill buffer with pseudo-random data derived from two encryptions */ + Twofish_encrypt( &xkey, buf, buf ); + Twofish_encrypt( &xkey, buf, buf+16 ); + + /* Create all possible shorter keys that are prefixes of the buffer. */ + for( i=31; i>=0; i-- ) + { + /* Set a byte to zero. This is the new padding byte */ + buf[i] = 0; + + /* Expand the key with only i bytes of length */ + Twofish_prepare_key( buf, i, &xkey ); + + /* Expand the corresponding padded key of regular length */ + Twofish_prepare_key( buf, i<=16 ? 16 : (i<= 24 ? 24 : 32), &xkey_two ); + + /* Compare the two */ + if( memcmp( &xkey, &xkey_two, sizeof( xkey ) ) != 0 ) + { + Twofish_fatal( "Odd sized keys do not expand properly" ); + } + } + + /* None of the key values are secret, so we don't need to wipe them. */ + } + + +/* + * Test the Twofish implementation. + * + * This routine runs all the self tests, in order of importance. + * It is called by the Twofish_initialise routine. + * + * In almost all applications the cost of running the self tests during + * initialisation is insignificant, especially + * compared to the time it takes to load the application from disk. + * If you are very pressed for initialisation performance, + * you could remove some of the tests. Make sure you did run them + * once in the software and hardware configuration you are using. + */ +static void self_test() + { + /* The three test vectors form an absolute minimal test set. */ + test_vectors(); + + /* + * If at all possible you should run these tests too. They take + * more time, but provide a more thorough coverage. + */ + test_sequences(); + + /* Test the odd-sized keys. */ + test_odd_sized_keys(); + } + + +/* + * And now, the actual Twofish implementation. + * + * This implementation generates all the tables during initialisation. + * I don't like large tables in the code, especially since they are easily + * damaged in the source without anyone noticing it. You need code to + * generate them anyway, and this way all the code is close together. + * Generating them in the application leads to a smaller executable + * (the code is smaller than the tables it generates) and a + * larger static memory footprint. + * + * Twofish can be implemented in many ways. I have chosen to + * use large tables with a relatively long key setup time. + * If you encrypt more than a few blocks of data it pays to pre-compute + * as much as possible. This implementation is relatively inefficient for + * applications that need to re-key every block or so. + */ + +/* + * We start with the t-tables, directly from the Twofish definition. + * These are nibble-tables, but merging them and putting them two nibbles + * in one byte is more work than it is worth. + */ +static Twofish_Byte t_table[2][4][16] = { + { + {0x8,0x1,0x7,0xD,0x6,0xF,0x3,0x2,0x0,0xB,0x5,0x9,0xE,0xC,0xA,0x4}, + {0xE,0xC,0xB,0x8,0x1,0x2,0x3,0x5,0xF,0x4,0xA,0x6,0x7,0x0,0x9,0xD}, + {0xB,0xA,0x5,0xE,0x6,0xD,0x9,0x0,0xC,0x8,0xF,0x3,0x2,0x4,0x7,0x1}, + {0xD,0x7,0xF,0x4,0x1,0x2,0x6,0xE,0x9,0xB,0x3,0x0,0x8,0x5,0xC,0xA} + }, + { + {0x2,0x8,0xB,0xD,0xF,0x7,0x6,0xE,0x3,0x1,0x9,0x4,0x0,0xA,0xC,0x5}, + {0x1,0xE,0x2,0xB,0x4,0xC,0x3,0x7,0x6,0xD,0xA,0x5,0xF,0x9,0x0,0x8}, + {0x4,0xC,0x7,0x5,0x1,0x6,0x9,0xA,0x0,0xE,0xD,0x8,0x2,0xB,0x3,0xF}, + {0xB,0x9,0x5,0x1,0xC,0x3,0xD,0xE,0x6,0x4,0x7,0xF,0x2,0x0,0x8,0xA} + } +}; + + +/* A 1-bit rotation of 4-bit values. Input must be in range 0..15 */ +#define ROR4BY1( x ) (((x)>>1) | (((x)<<3) & 0x8) ) + +/* + * The q-boxes are only used during the key schedule computations. + * These are 8->8 bit lookup tables. Some CPUs prefer to have 8->32 bit + * lookup tables as it is faster to load a 32-bit value than to load an + * 8-bit value and zero the rest of the register. + * The LARGE_Q_TABLE switch allows you to choose 32-bit entries in + * the q-tables. Here we just define the Qtype which is used to store + * the entries of the q-tables. + */ +#if LARGE_Q_TABLE +typedef Twofish_UInt32 Qtype; +#else +typedef Twofish_Byte Qtype; +#endif + +/* + * The actual q-box tables. + * There are two q-boxes, each having 256 entries. + */ +static Qtype q_table[2][256]; + + +/* + * Now the function that converts a single t-table into a q-table. + * + * Arguments: + * t[4][16] : four 4->4bit lookup tables that define the q-box + * q[256] : output parameter: the resulting q-box as a lookup table. + */ +static void make_q_table( Twofish_Byte t[4][16], Qtype q[256] ) + { + int ae,be,ao,bo; /* Some temporaries. */ + int i; + /* Loop over all input values and compute the q-box result. */ + for( i=0; i<256; i++ ) { + /* + * This is straight from the Twofish specifications. + * + * The ae variable is used for the a_i values from the specs + * with even i, and ao for the odd i's. Similarly for the b's. + */ + ae = i>>4; be = i&0xf; + ao = ae ^ be; bo = ae ^ ROR4BY1(be) ^ ((ae<<3)&8); + ae = t[0][ao]; be = t[1][bo]; + ao = ae ^ be; bo = ae ^ ROR4BY1(be) ^ ((ae<<3)&8); + ae = t[2][ao]; be = t[3][bo]; + + /* Store the result in the q-box table, the cast avoids a warning. */ + q[i] = (Qtype) ((be<<4) | ae); + } + } + + +/* + * Initialise both q-box tables. + */ +static void initialise_q_boxes() { + /* Initialise each of the q-boxes using the t-tables */ + make_q_table( t_table[0], q_table[0] ); + make_q_table( t_table[1], q_table[1] ); + } + + +/* + * Next up is the MDS matrix multiplication. + * The MDS matrix multiplication operates in the field + * GF(2)[x]/p(x) with p(x)=x^8+x^6+x^5+x^3+1. + * If you don't understand this, read a book on finite fields. You cannot + * follow the finite-field computations without some background. + * + * In this field, multiplication by x is easy: shift left one bit + * and if bit 8 is set then xor the result with 0x169. + * + * The MDS coefficients use a multiplication by 1/x, + * or rather a division by x. This is easy too: first make the + * value 'even' (i.e. bit 0 is zero) by xorring with 0x169 if necessary, + * and then shift right one position. + * Even easier: shift right and xor with 0xb4 if the lsbit was set. + * + * The MDS coefficients are 1, EF, and 5B, and we use the fact that + * EF = 1 + 1/x + 1/x^2 + * 5B = 1 + 1/x^2 + * in this field. This makes multiplication by EF and 5B relatively easy. + * + * This property is no accident, the MDS matrix was designed to allow + * this implementation technique to be used. + * + * We have four MDS tables, each mapping 8 bits to 32 bits. + * Each table performs one column of the matrix multiplication. + * As the MDS is always preceded by q-boxes, each of these tables + * also implements the q-box just previous to that column. + */ + +/* The actual MDS tables. */ +static Twofish_UInt32 MDS_table[4][256]; + +/* A small table to get easy conditional access to the 0xb4 constant. */ +static Twofish_UInt32 mds_poly_divx_const[] = {0,0xb4}; + +/* Function to initialise the MDS tables. */ +static void initialise_mds_tables() + { + int i; + Twofish_UInt32 q,qef,q5b; /* Temporary variables. */ + + /* Loop over all 8-bit input values */ + for( i=0; i<256; i++ ) + { + /* + * To save some work during the key expansion we include the last + * of the q-box layers from the h() function in these MDS tables. + */ + + /* We first do the inputs that are mapped through the q0 table. */ + q = q_table[0][i]; + /* + * Here we divide by x, note the table to get 0xb4 only if the + * lsbit is set. + * This sets qef = (1/x)*q in the finite field + */ + qef = (q >> 1) ^ mds_poly_divx_const[ q & 1 ]; + /* + * Divide by x again, and add q to get (1+1/x^2)*q. + * Note that (1+1/x^2) = 5B in the field, and addition in the field + * is exclusive or on the bits. + */ + q5b = (qef >> 1) ^ mds_poly_divx_const[ qef & 1 ] ^ q; + /* + * Add q5b to qef to set qef = (1+1/x+1/x^2)*q. + * Again, (1+1/x+1/x^2) = EF in the field. + */ + qef ^= q5b; + + /* + * Now that we have q5b = 5B * q and qef = EF * q + * we can fill two of the entries in the MDS matrix table. + * See the Twofish specifications for the order of the constants. + */ + MDS_table[1][i] = (q <<24) | (q5b<<16) | (qef<<8) | qef; + MDS_table[3][i] = (q5b<<24) | (qef<<16) | (q <<8) | q5b; + + /* Now we do it all again for the two columns that have a q1 box. */ + q = q_table[1][i]; + qef = (q >> 1) ^ mds_poly_divx_const[ q & 1 ]; + q5b = (qef >> 1) ^ mds_poly_divx_const[ qef & 1 ] ^ q; + qef ^= q5b; + + /* The other two columns use the coefficient in a different order. */ + MDS_table[0][i] = (qef<<24) | (qef<<16) | (q5b<<8) | q ; + MDS_table[2][i] = (qef<<24) | (q <<16) | (qef<<8) | q5b; + } + } + + +/* + * The h() function is the heart of the Twofish cipher. + * It is a complicated sequence of q-box lookups, key material xors, + * and finally the MDS matrix. + * We use lots of macros to make this reasonably fast. + */ + +/* First a shorthand for the two q-tables */ +#define q0 q_table[0] +#define q1 q_table[1] + +/* + * Each macro computes one column of the h for either 2, 3, or 4 stages. + * As there are 4 columns, we have 12 macros in all. + * + * The key bytes are stored in the Byte array L at offset + * 0,1,2,3, 8,9,10,11, [16,17,18,19, [24,25,26,27]] as this is the + * order we get the bytes from the user. If you look at the Twofish + * specs, you'll see that h() is applied to the even key words or the + * odd key words. The bytes of the even words appear in this spacing, + * and those of the odd key words too. + * + * These macros are the only place where the q-boxes and the MDS table + * are used. + */ +#define H02( y, L ) MDS_table[0][q0[q0[y]^L[ 8]]^L[0]] +#define H12( y, L ) MDS_table[1][q0[q1[y]^L[ 9]]^L[1]] +#define H22( y, L ) MDS_table[2][q1[q0[y]^L[10]]^L[2]] +#define H32( y, L ) MDS_table[3][q1[q1[y]^L[11]]^L[3]] +#define H03( y, L ) H02( q1[y]^L[16], L ) +#define H13( y, L ) H12( q1[y]^L[17], L ) +#define H23( y, L ) H22( q0[y]^L[18], L ) +#define H33( y, L ) H32( q0[y]^L[19], L ) +#define H04( y, L ) H03( q1[y]^L[24], L ) +#define H14( y, L ) H13( q0[y]^L[25], L ) +#define H24( y, L ) H23( q0[y]^L[26], L ) +#define H34( y, L ) H33( q1[y]^L[27], L ) + +/* + * Now we can define the h() function given an array of key bytes. + * This function is only used in the key schedule, and not to pre-compute + * the keyed S-boxes. + * + * In the key schedule, the input is always of the form k*(1+2^8+2^16+2^24) + * so we only provide k as an argument. + * + * Arguments: + * k input to the h() function. + * L pointer to array of key bytes at + * offsets 0,1,2,3, ... 8,9,10,11, [16,17,18,19, [24,25,26,27]] + * kCycles # key cycles, 2, 3, or 4. + */ +static Twofish_UInt32 h( int k, Twofish_Byte L[], int kCycles ) + { + switch( kCycles ) { + /* We code all 3 cases separately for speed reasons. */ + case 2: + return H02(k,L) ^ H12(k,L) ^ H22(k,L) ^ H32(k,L); + case 3: + return H03(k,L) ^ H13(k,L) ^ H23(k,L) ^ H33(k,L); + case 4: + return H04(k,L) ^ H14(k,L) ^ H24(k,L) ^ H34(k,L); + default: + /* This is always a coding error, which is fatal. */ + Twofish_fatal( "Twofish h(): Illegal argument" ); + return 0; + } + } + + +/* + * Pre-compute the keyed S-boxes. + * Fill the pre-computed S-box array in the expanded key structure. + * Each pre-computed S-box maps 8 bits to 32 bits. + * + * The S argument contains half the number of bytes of the full key, but is + * derived from the full key. (See Twofish specifications for details.) + * S has the weird byte input order used by the Hxx macros. + * + * This function takes most of the time of a key expansion. + * + * Arguments: + * S pointer to array of 8*kCycles Bytes containing the S vector. + * kCycles number of key words, must be in the set {2,3,4} + * xkey pointer to Twofish_key structure that will contain the S-boxes. + */ +static void fill_keyed_sboxes( Twofish_Byte S[], int kCycles, Twofish_key * xkey ) + { + int i; + switch( kCycles ) { + /* We code all 3 cases separately for speed reasons. */ + case 2: + for( i=0; i<256; i++ ) + { + xkey->s[0][i]= H02( i, S ); + xkey->s[1][i]= H12( i, S ); + xkey->s[2][i]= H22( i, S ); + xkey->s[3][i]= H32( i, S ); + } + break; + case 3: + for( i=0; i<256; i++ ) + { + xkey->s[0][i]= H03( i, S ); + xkey->s[1][i]= H13( i, S ); + xkey->s[2][i]= H23( i, S ); + xkey->s[3][i]= H33( i, S ); + } + break; + case 4: + for( i=0; i<256; i++ ) + { + xkey->s[0][i]= H04( i, S ); + xkey->s[1][i]= H14( i, S ); + xkey->s[2][i]= H24( i, S ); + xkey->s[3][i]= H34( i, S ); + } + break; + default: + /* This is always a coding error, which is fatal. */ + Twofish_fatal( "Twofish fill_keyed_sboxes(): Illegal argument" ); + } + } + + +/* A flag to keep track of whether we have been initialised or not. */ +static int Twofish_initialised = 0; + +/* + * Initialise the Twofish implementation. + * This function must be called before any other function in the + * Twofish implementation is called. + * This routine also does some sanity checks, to make sure that + * all the macros behave, and it tests the whole cipher. + */ +void Twofish_initialise() + { + /* First test the various platform-specific definitions. */ + test_platform(); + + /* We can now generate our tables, in the right order of course. */ + initialise_q_boxes(); + initialise_mds_tables(); + + /* We're finished with the initialisation itself. */ + Twofish_initialised = 1; + + /* + * And run some tests on the whole cipher. + * Yes, you need to do this every time you start your program. + * It is called assurance; you have to be certain that your program + * still works properly. + */ + self_test(); + } + + +/* + * The Twofish key schedule uses an Reed-Solomon code matrix multiply. + * Just like the MDS matrix, the RS-matrix is designed to be easy + * to implement. Details are below in the code. + * + * These constants make it easy to compute in the finite field used + * for the RS code. + * + * We use Bytes for the RS computation, but these are automatically + * widened to unsigned integers in the expressions. Having unsigned + * ints in these tables therefore provides the fastest access. + */ +static unsigned int rs_poly_const[] = {0, 0x14d}; +static unsigned int rs_poly_div_const[] = {0, 0xa6 }; + + +/* + * Prepare a key for use in encryption and decryption. + * Like most block ciphers, Twofish allows the key schedule + * to be pre-computed given only the key. + * Twofish has a fairly 'heavy' key schedule that takes a lot of time + * to compute. The main work is pre-computing the S-boxes used in the + * encryption and decryption. We feel that this makes the cipher much + * harder to attack. The attacker doesn't even know what the S-boxes + * contain without including the entire key schedule in the analysis. + * + * Unlike most Twofish implementations, this one allows any key size from + * 0 to 32 bytes. Odd key sizes are defined for Twofish (see the + * specifications); the key is simply padded with zeroes to the next real + * key size of 16, 24, or 32 bytes. + * Each odd-sized key is thus equivalent to a single normal-sized key. + * + * Arguments: + * key array of key bytes + * key_len number of bytes in the key, must be in the range 0,...,32. + * xkey Pointer to an Twofish_key structure that will be filled + * with the internal form of the cipher key. + */ +void Twofish_prepare_key( Twofish_Byte key[], int key_len, Twofish_key * xkey ) + { + /* We use a single array to store all key material in, + * to simplify the wiping of the key material at the end. + * The first 32 bytes contain the actual (padded) cipher key. + * The next 32 bytes contain the S-vector in its weird format, + * and we have 4 bytes of overrun necessary for the RS-reduction. + */ + Twofish_Byte K[32+32+4]; + + int kCycles; /* # key cycles, 2,3, or 4. */ + + int i; + Twofish_UInt32 A, B; /* Used to compute the round keys. */ + + Twofish_Byte * kptr; /* Three pointers for the RS computation. */ + Twofish_Byte * sptr; + Twofish_Byte * t; + + Twofish_Byte b,bx,bxx; /* Some more temporaries for the RS computation. */ + + /* Check that the Twofish implementation was initialised. */ + if( Twofish_initialised == 0 ) + { + /* + * You didn't call Twofish_initialise before calling this routine. + * This is a programming error, and therefore we call the fatal + * routine. + * + * I could of course call the initialisation routine here, + * but there are a few reasons why I don't. First of all, the + * self-tests have to be done at startup. It is no good to inform + * the user that the cipher implementation fails when he wants to + * write his data to disk in encrypted form. You have to warn him + * before he spends time typing his data. Second, the initialisation + * and self test are much slower than a single key expansion. + * Calling the initialisation here makes the performance of the + * cipher unpredictable. This can lead to really weird problems + * if you use the cipher for a real-time task. Suddenly it fails + * once in a while the first time you try to use it. Things like + * that are almost impossible to debug. + */ + Twofish_fatal( "Twofish implementation was not initialised." ); + + /* + * There is always a danger that the Twofish_fatal routine returns, + * in spite of the specifications that it should not. + * (A good programming rule: don't trust the rest of the code.) + * This would be disasterous. If the q-tables and MDS-tables have + * not been initialised, they are probably still filled with zeroes. + * Suppose the MDS-tables are all zero. The key expansion would then + * generate all-zero round keys, and all-zero s-boxes. The danger + * is that nobody would notice as the encryption function still + * mangles the input, and the decryption still 'decrypts' it, + * but now in a completely key-independent manner. + * To stop such security disasters, we use blunt force. + * If your program hangs here: fix the fatal routine! + */ + for(;;); /* Infinite loop, which beats being insecure. */ + } + + /* Check for valid key length. */ + if( key_len < 0 || key_len > 32 ) + { + /* + * This can only happen if a programmer didn't read the limitations + * on the key size. + */ + Twofish_fatal( "Twofish_prepare_key: illegal key length" ); + /* + * A return statement just in case the fatal macro returns. + * The rest of the code assumes that key_len is in range, and would + * buffer-overflow if it wasn't. + * + * Why do we still use a programming language that has problems like + * buffer overflows, when these problems were solved in 1960 with + * the development of Algol? Have we not leared anything? + */ + return; + } + + /* Pad the key with zeroes to the next suitable key length. */ + memcpy( K, key, key_len ); + memset( K+key_len, 0, sizeof(K)-key_len ); + + /* + * Compute kCycles: the number of key cycles used in the cipher. + * 2 for 128-bit keys, 3 for 192-bit keys, and 4 for 256-bit keys. + */ + kCycles = (key_len + 7) >> 3; + /* Handle the special case of very short keys: minimum 2 cycles. */ + if( kCycles < 2 ) + { + kCycles = 2; + } + + /* + * From now on we just pretend to have 8*kCycles bytes of + * key material in K. This handles all the key size cases. + */ + + /* + * We first compute the 40 expanded key words, + * formulas straight from the Twofish specifications. + */ + for( i=0; i<40; i+=2 ) + { + /* + * Due to the byte spacing expected by the h() function + * we can pick the bytes directly from the key K. + * As we use bytes, we never have the little/big endian + * problem. + * + * Note that we apply the rotation function only to simple + * variables, as the rotation macro might evaluate its argument + * more than once. + */ + A = h( i , K , kCycles ); + B = h( i+1, K+4, kCycles ); + B = ROL32( B, 8 ); + + /* Compute and store the round keys. */ + A += B; + B += A; + xkey->K[i] = A; + xkey->K[i+1] = ROL32( B, 9 ); + } + + /* Wipe variables that contained key material. */ + A=B=0; + + /* + * And now the dreaded RS multiplication that few seem to understand. + * The RS matrix is not random, and is specially designed to compute the + * RS matrix multiplication in a simple way. + * + * We work in the field GF(2)[x]/x^8+x^6+x^3+x^2+1. Note that this is a + * different field than used for the MDS matrix. + * (At least, it is a different representation because all GF(2^8) + * representations are equivalent in some form.) + * + * We take 8 consecutive bytes of the key and interpret them as + * a polynomial k_0 + k_1 y + k_2 y^2 + ... + k_7 y^7 where + * the k_i bytes are the key bytes and are elements of the finite field. + * We multiply this polynomial by y^4 and reduce it modulo + * y^4 + (x + 1/x)y^3 + (x)y^2 + (x + 1/x)y + 1. + * using straightforward polynomial modulo reduction. + * The coefficients of the result are the result of the RS + * matrix multiplication. When we wrote the Twofish specification, + * the original RS definition used the polynomials, + * but that requires much more mathematical knowledge. + * We were already using matrix multiplication in a finite field for + * the MDS matrix, so I re-wrote the RS operation as a matrix + * multiplication to reduce the difficulty of understanding it. + * Some implementors have not picked up on this simpler method of + * computing the RS operation, even though it is mentioned in the + * specifications. + * + * It is possible to perform these computations faster by using 32-bit + * word operations, but that is not portable and this is not a speed- + * critical area. + * + * We explained the 1/x computation when we did the MDS matrix. + * + * The S vector is stored in K[32..64]. + * The S vector has to be reversed, so we loop cross-wise. + * + * Note the weird byte spacing of the S-vector, to match the even + * or odd key words arrays. See the discussion at the Hxx macros for + * details. + */ + kptr = K + 8*kCycles; /* Start at end of key */ + sptr = K + 32; /* Start at start of S */ + + /* Loop over all key material */ + while( kptr > K ) + { + kptr -= 8; + /* + * Initialise the polynimial in sptr[0..12] + * The first four coefficients are 0 as we have to multiply by y^4. + * The next 8 coefficients are from the key material. + */ + memset( sptr, 0, 4 ); + memcpy( sptr+4, kptr, 8 ); + + /* + * The 12 bytes starting at sptr are now the coefficients of + * the polynomial we need to reduce. + */ + + /* Loop over the polynomial coefficients from high to low */ + t = sptr+11; + /* Keep looping until polynomial is degree 3; */ + while( t > sptr+3 ) + { + /* Pick up the highest coefficient of the poly. */ + b = *t; + + /* + * Compute x and (x+1/x) times this coefficient. + * See the MDS matrix implementation for a discussion of + * multiplication by x and 1/x. We just use different + * constants here as we are in a + * different finite field representation. + * + * These two statements set + * bx = (x) * b + * bxx= (x + 1/x) * b + */ + bx = (Twofish_Byte)((b<<1) ^ rs_poly_const[ b>>7 ]); + bxx= (Twofish_Byte)((b>>1) ^ rs_poly_div_const[ b&1 ] ^ bx); + + /* + * Subtract suitable multiple of + * y^4 + (x + 1/x)y^3 + (x)y^2 + (x + 1/x)y + 1 + * from the polynomial, except that we don't bother + * updating t[0] as it will become zero anyway. + */ + t[-1] ^= bxx; + t[-2] ^= bx; + t[-3] ^= bxx; + t[-4] ^= b; + + /* Go to the next coefficient. */ + t--; + } + + /* Go to next S-vector word, obeying the weird spacing rules. */ + sptr += 8; + } + + /* Wipe variables that contained key material. */ + b = bx = bxx = 0; + + /* And finally, we can compute the key-dependent S-boxes. */ + fill_keyed_sboxes( &K[32], kCycles, xkey ); + + /* Wipe array that contained key material. */ + memset( K, 0, sizeof( K ) ); + } + + +/* + * We can now start on the actual encryption and decryption code. + * As these are often speed-critical we will use a lot of macros. + */ + +/* + * The g() function is the heart of the round function. + * We have two versions of the g() function, one without an input + * rotation and one with. + * The pre-computed S-boxes make this pretty simple. + */ +#define g0(X,xkey) \ + (xkey->s[0][b0(X)]^xkey->s[1][b1(X)]^xkey->s[2][b2(X)]^xkey->s[3][b3(X)]) + +#define g1(X,xkey) \ + (xkey->s[0][b3(X)]^xkey->s[1][b0(X)]^xkey->s[2][b1(X)]^xkey->s[3][b2(X)]) + +/* + * A single round of Twofish. The A,B,C,D are the four state variables, + * T0 and T1 are temporaries, xkey is the expanded key, and r the + * round number. + * + * Note that this macro does not implement the swap at the end of the round. + */ +#define ENCRYPT_RND( A,B,C,D, T0, T1, xkey, r ) \ + T0 = g0(A,xkey); T1 = g1(B,xkey);\ + C ^= T0+T1+xkey->K[8+2*(r)]; C = ROR32(C,1);\ + D = ROL32(D,1); D ^= T0+2*T1+xkey->K[8+2*(r)+1] + +/* + * Encrypt a single cycle, consisting of two rounds. + * This avoids the swapping of the two halves. + * Parameter r is now the cycle number. + */ +#define ENCRYPT_CYCLE( A, B, C, D, T0, T1, xkey, r ) \ + ENCRYPT_RND( A,B,C,D,T0,T1,xkey,2*(r) );\ + ENCRYPT_RND( C,D,A,B,T0,T1,xkey,2*(r)+1 ) + +/* Full 16-round encryption */ +#define ENCRYPT( A,B,C,D,T0,T1,xkey ) \ + ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 0 );\ + ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 1 );\ + ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 2 );\ + ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 3 );\ + ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 4 );\ + ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 5 );\ + ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 6 );\ + ENCRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 7 ) + +/* + * A single round of Twofish for decryption. It differs from + * ENCRYTP_RND only because of the 1-bit rotations. + */ +#define DECRYPT_RND( A,B,C,D, T0, T1, xkey, r ) \ + T0 = g0(A,xkey); T1 = g1(B,xkey);\ + C = ROL32(C,1); C ^= T0+T1+xkey->K[8+2*(r)];\ + D ^= T0+2*T1+xkey->K[8+2*(r)+1]; D = ROR32(D,1) + +/* + * Decrypt a single cycle, consisting of two rounds. + * This avoids the swapping of the two halves. + * Parameter r is now the cycle number. + */ +#define DECRYPT_CYCLE( A, B, C, D, T0, T1, xkey, r ) \ + DECRYPT_RND( A,B,C,D,T0,T1,xkey,2*(r)+1 );\ + DECRYPT_RND( C,D,A,B,T0,T1,xkey,2*(r) ) + +/* Full 16-round decryption. */ +#define DECRYPT( A,B,C,D,T0,T1, xkey ) \ + DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 7 );\ + DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 6 );\ + DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 5 );\ + DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 4 );\ + DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 3 );\ + DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 2 );\ + DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 1 );\ + DECRYPT_CYCLE( A,B,C,D,T0,T1,xkey, 0 ) + +/* + * A macro to read the state from the plaintext and do the initial key xors. + * The koff argument allows us to use the same macro + * for the decryption which uses different key words at the start. + */ +#define GET_INPUT( src, A,B,C,D, xkey, koff ) \ + A = GET32(src )^xkey->K[ koff]; B = GET32(src+ 4)^xkey->K[1+koff]; \ + C = GET32(src+ 8)^xkey->K[2+koff]; D = GET32(src+12)^xkey->K[3+koff] + +/* + * Similar macro to put the ciphertext in the output buffer. + * We xor the keys into the state variables before we use the PUT32 + * macro as the macro might use its argument multiple times. + */ +#define PUT_OUTPUT( A,B,C,D, dst, xkey, koff ) \ + A ^= xkey->K[ koff]; B ^= xkey->K[1+koff]; \ + C ^= xkey->K[2+koff]; D ^= xkey->K[3+koff]; \ + PUT32( A, dst ); PUT32( B, dst+ 4 ); \ + PUT32( C, dst+8 ); PUT32( D, dst+12 ) + + +/* + * Twofish block encryption + * + * Arguments: + * xkey expanded key array + * p 16 bytes of plaintext + * c 16 bytes in which to store the ciphertext + */ +void Twofish_encrypt( Twofish_key * xkey, Twofish_Byte p[16], Twofish_Byte c[16]) + { + Twofish_UInt32 A,B,C,D,T0,T1; /* Working variables */ + + /* Get the four plaintext words xorred with the key */ + GET_INPUT( p, A,B,C,D, xkey, 0 ); + + /* Do 8 cycles (= 16 rounds) */ + ENCRYPT( A,B,C,D,T0,T1,xkey ); + + /* Store them with the final swap and the output whitening. */ + PUT_OUTPUT( C,D,A,B, c, xkey, 4 ); + } + + +/* + * Twofish block decryption. + * + * Arguments: + * xkey expanded key array + * p 16 bytes of plaintext + * c 16 bytes in which to store the ciphertext + */ +void Twofish_decrypt( Twofish_key * xkey, Twofish_Byte c[16], Twofish_Byte p[16]) + { + Twofish_UInt32 A,B,C,D,T0,T1; /* Working variables */ + + /* Get the four plaintext words xorred with the key */ + GET_INPUT( c, A,B,C,D, xkey, 4 ); + + /* Do 8 cycles (= 16 rounds) */ + DECRYPT( A,B,C,D,T0,T1,xkey ); + + /* Store them with the final swap and the output whitening. */ + PUT_OUTPUT( C,D,A,B, p, xkey, 0 ); + } + +/* + * Using the macros it is easy to make special routines for + * CBC mode, CTR mode etc. The only thing you might want to + * add is a XOR_PUT_OUTPUT which xors the outputs into the + * destinationa instead of overwriting the data. This requires + * a XOR_PUT32 macro as well, but that should all be trivial. + * + * I thought about including routines for the separate cipher + * modes here, but it is unclear which modes should be included, + * and each encryption or decryption routine takes up a lot of code space. + * Also, I don't have any test vectors for any cipher modes + * with Twofish. + */ diff --git a/src/crypto/twofish.h b/src/crypto/twofish.h new file mode 100755 index 0000000..f492016 --- /dev/null +++ b/src/crypto/twofish.h @@ -0,0 +1,179 @@ +/* + * Fast, portable, and easy-to-use Twofish implementation, + * Version 0.3. + * Copyright (c) 2002 by Niels Ferguson. + * + * See the twofish.c file for the details of the how and why of this code. + * + * The author hereby grants a perpetual license to everybody to + * use this code for any purpose as long as the copyright message is included + * in the source code of this or any derived work. + */ + + +/* + * PLATFORM FIXES + * ============== + * + * The following definitions have to be fixed for each particular platform + * you work on. If you have a multi-platform program, you no doubt have + * portable definitions that you can substitute here without changing + * the rest of the code. + * + * The defaults provided here should work on most PC compilers. + */ + + +/* + * A Twofish_Byte must be an unsigned 8-bit integer. + * It must also be the elementary data size of your C platform, + * i.e. sizeof( Twofish_Byte ) == 1. + */ +typedef unsigned char Twofish_Byte; + +/* + * A Twofish_UInt32 must be an unsigned integer of at least 32 bits. + * + * This type is used only internally in the implementation, so ideally it + * would not appear in the header file, but it is used inside the + * Twofish_key structure which means it has to be included here. + */ +typedef unsigned int Twofish_UInt32; + + +/* + * END OF PLATFORM FIXES + * ===================== + * + * You should not have to touch the rest of this file, but the code + * in twofish.c has a few things you need to fix too. + */ + + +/* + * Structure that contains a prepared Twofish key. + * A cipher key is used in two stages. In the first stage it is converted + * form the original form to an internal representation. + * This internal form is then used to encrypt and decrypt data. + * This structure contains the internal form. It is rather large: 4256 bytes + * on a platform with 32-bit unsigned values. + * + * Treat this as an opague structure, and don't try to manipulate the + * elements in it. I wish I could hide the inside of the structure, + * but C doesn't allow that. + */ +typedef + struct + { + Twofish_UInt32 s[4][256]; /* pre-computed S-boxes */ + Twofish_UInt32 K[40]; /* Round key words */ + } + Twofish_key; + + +/* + * Initialise and test the Twofish implementation. + * + * This function MUST be called before any other function in the + * Twofish implementation is called. + * It only needs to be called once. + * + * Apart from initialising the implementation it performs a self test. + * If the Twofish_fatal function is not called, the code passed the test. + * (See the twofish.c file for details on the Twofish_fatal function.) + */ +extern void Twofish_initialise(); + + +/* + * Convert a cipher key to the internal form used for + * encryption and decryption. + * + * The cipher key is an array of bytes; the Twofish_Byte type is + * defined above to a type suitable on your platform. + * + * Any key must be converted to an internal form in the Twofisk_key structure + * before it can be used. + * The encryption and decryption functions only work with the internal form. + * The conversion to internal form need only be done once for each key value. + * + * Be sure to wipe all key storage, including the Twofish_key structure, + * once you are done with the key data. + * A simple memset( TwofishKey, 0, sizeof( TwofishKey ) ) will do just fine. + * + * Unlike most implementations, this one allows any key size from 0 bytes + * to 32 bytes. According to the Twofish specifications, + * irregular key sizes are handled by padding the key with zeroes at the end + * until the key size is 16, 24, or 32 bytes, whichever + * comes first. Note that each key of irregular size is equivalent to exactly + * one key of 16, 24, or 32 bytes. + * + * WARNING: Short keys have low entropy, and result in low security. + * Anything less than 8 bytes is utterly insecure. For good security + * use at least 16 bytes. I prefer to use 32-byte keys to prevent + * any collision attacks on the key. + * + * The key length argument key_len must be in the proper range. + * If key_len is not in the range 0,...,32 this routine attempts to generate + * a fatal error (depending on the code environment), + * and at best (or worst) returns without having done anything. + * + * Arguments: + * key Array of key bytes + * key_len Number of key bytes, must be in the range 0,1,...,32. + * xkey Pointer to an Twofish_key structure that will be filled + * with the internal form of the cipher key. + */ +extern void Twofish_prepare_key( + Twofish_Byte key[], + int key_len, + Twofish_key * xkey + ); + + +/* + * Encrypt a single block of data. + * + * This function encrypts a single block of 16 bytes of data. + * If you want to encrypt a larger or variable-length message, + * you will have to use a cipher mode, such as CBC or CTR. + * These are outside the scope of this implementation. + * + * The xkey structure is not modified by this routine, and can be + * used for further encryption and decryption operations. + * + * Arguments: + * xkey pointer to Twofish_key, internal form of the key + * produces by Twofish_prepare_key() + * p Plaintext to be encrypted + * c Place to store the ciphertext + */ +extern void Twofish_encrypt( + Twofish_key * xkey, + Twofish_Byte p[16], + Twofish_Byte c[16] + ); + + +/* + * Decrypt a single block of data. + * + * This function decrypts a single block of 16 bytes of data. + * If you want to decrypt a larger or variable-length message, + * you will have to use a cipher mode, such as CBC or CTR. + * These are outside the scope of this implementation. + * + * The xkey structure is not modified by this routine, and can be + * used for further encryption and decryption operations. + * + * Arguments: + * xkey pointer to Twofish_key, internal form of the key + * produces by Twofish_prepare_key() + * c Ciphertext to be decrypted + * p Place to store the plaintext + */ +extern void Twofish_decrypt( + Twofish_key * xkey, + Twofish_Byte c[16], + Twofish_Byte p[16] + ); diff --git a/src/dialogs/AboutDlg.cpp b/src/dialogs/AboutDlg.cpp new file mode 100755 index 0000000..9f85f2b --- /dev/null +++ b/src/dialogs/AboutDlg.cpp @@ -0,0 +1,98 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * tarek@linux * + * * + * 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. * + ***************************************************************************/ + +#include "mainwindow.h" +#include +#include +#include +#include +#include + +#include "AboutDlg.h" + +CAboutDialog::CAboutDialog(QWidget* parent, const char* name, bool modal, WFlags fl) +: AboutDlg(parent,name, modal,fl) +{ +mainwnd=((CMainWindow*)parentWidget()); +mainwnd->CreateBanner(Banner,mainwnd->Icon_Key32x32,trUtf8("Keepass für Linux")); +Link_Homepage=new LinkLabel(this,"Link_Homepage",trUtf8("http://keepass.de.vu"),80,143); +Link_EMail=new LinkLabel(this,"Link_EMail",trUtf8("tarek.saidi@arcor.de"),80,163); +Link_License=new LinkLabel(this,"Link_License",trUtf8("Lizenz"),80,183); +connect(Link_License,SIGNAL(clicked()),this,SLOT(OnLicenseClicked())); +connect(Link_EMail,SIGNAL(clicked()),this,SLOT(OnEMailClicked())); +connect(Link_Homepage,SIGNAL(clicked()),this,SLOT(OnHomepageClicked())); +Label0->setText(Label0->text().arg(KEEPASS_VERSION)); + +} + +CAboutDialog::~CAboutDialog() +{ +delete Link_Homepage; +delete Link_EMail; +delete Link_License; +} + +void CAboutDialog::OnClose() +{ +close(); +} + +void CAboutDialog::OnLicenseClicked(){ + +QDialog dlg(this,NULL,true); +QScrollView scroll(&dlg); +QLabel label(&scroll,"License-Scroll"); +scroll.addChild(&label); +QFile gpl(((CMainWindow*)parentWidget())->appdir+"/../share/keepass/license.txt"); +if(!gpl.exists()){ +QMessageBox::critical(this,trUtf8("Fehler"),trUtf8("Die Datei '%1' konnte nicht gefunden werden.") + .arg("'license.txt'")+"\n"+trUtf8("Die Anwendung wurde möglicherweiße nicht korrekt installiert.") + ,trUtf8("OK"),0,0,2,1); +return; +} + +if(!gpl.open(IO_ReadOnly)){ +QMessageBox::critical(this,trUtf8("Fehler"),trUtf8("Die Datei '%1' konnte nicht geöffnet werden.") + .arg("'license.txt'")+trUtf8("Es trat folgender Fehler auf:\n%1").arg(gpl.errorString()) + ,trUtf8("OK"),0,0,2,1); +return; +} +char* buffer=new char[gpl.size()]; +long l=gpl.readBlock(buffer,gpl.size()); +gpl.close(); +label.setText(QString::fromUtf8(buffer,l)); +label.setGeometry(0,0,500,800); +dlg.setFixedWidth(500); +dlg.setFixedHeight(400); +dlg.setCaption(trUtf8("Lizenz")); +scroll.setGeometry(0,0,500,400); +dlg.exec(); +delete buffer; + +} + +void CAboutDialog::OnHomepageClicked(){ +mainwnd->OpenURL("http://keepass.de.vu"); +} + +void CAboutDialog::OnEMailClicked(){ +mainwnd->OpenURL("mailto:tarek.saidi@arcor.de"); +} + diff --git a/src/dialogs/AboutDlg.h b/src/dialogs/AboutDlg.h new file mode 100755 index 0000000..ba9f6f5 --- /dev/null +++ b/src/dialogs/AboutDlg.h @@ -0,0 +1,57 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * tarek@linux * + * * + * 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. * + ***************************************************************************/ +#ifndef _ABOUTDIALOG_H_ +#define _ABOUTDIALOG_H_ +#include "ui_AboutDlg.h" +#include "lib/UrlLabel.h" +#include "mainwindow.h" + + + +class CAboutDialog : public AboutDlg +{ + Q_OBJECT + + LinkLabel *Link_Homepage,*Link_EMail,*Link_License; +public: + CAboutDialog(QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~CAboutDialog(); + + CMainWindow* mainwnd; + /*$PUBLIC_FUNCTIONS$*/ + +public slots: + /*$PUBLIC_SLOTS$*/ + +protected: + /*$PROTECTED_FUNCTIONS$*/ + +protected slots: + /*$PROTECTED_SLOTS$*/ + +public slots: + virtual void OnClose(); + void OnHomepageClicked(); + void OnEMailClicked(); + void OnLicenseClicked(); +}; + +#endif + diff --git a/src/dialogs/ChangeKeyDlg.cpp b/src/dialogs/ChangeKeyDlg.cpp new file mode 100755 index 0000000..6fdf023 --- /dev/null +++ b/src/dialogs/ChangeKeyDlg.cpp @@ -0,0 +1,225 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * tarek@linux * + * * + * 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. * + ***************************************************************************/ +#include "mainwindow.h" +#include "PwManager.h" +#include "../lib/random.h" +#include "ChangeKeyDlg.h" +//QT +#include +#include +#include +#include +#include +#include +#include + + + +CChangeKeyDlg::CChangeKeyDlg(QWidget* parent,PwDatabase* _db,const char* name, bool modal, WFlags fl) +: ChangeKeyDialog(parent,name, modal,fl) +{ +db=_db; +parentwnd=((CMainWindow*)parentWidget()); +parentwnd->CreateBanner(Banner,parentwnd->Icon_Key32x32,trUtf8("Hauptschlüssel ändern")); +if(!parentwnd->config.ShowPasswords)ChangeEchoMode(); +///@PlatformSpecific +QDir media("/media"); +if(media.exists()){ +Paths=media.entryList("*",QDir::Dirs); +Paths.erase(Paths.begin()); // delete "." +Paths.erase(Paths.begin()); // delete ".." + +for(int i=0;i"); +} +for(int i=0;iinsertItem(0,Paths[i]); +IsFile.append(false); +} +} + +CChangeKeyDlg::~CChangeKeyDlg() +{ +} + +void CChangeKeyDlg::OnOK() +{ +if(CheckBox_Both->isChecked()){ + if(password==""){QMessageBox::warning(this,trUtf8("Fehler"),trUtf8("Bitte geben Sie ein Passwort ein.") + ,trUtf8("OK"),"","",0,0); + return;} + if(keyfile==""){QMessageBox::warning(this,trUtf8("Fehler"),trUtf8("Bitte wählen Sie eine Schlüsseldatei.") + ,trUtf8("OK"),"","",0,0); + return;} +} +else +{ + if(password=="" && keyfile==""){QMessageBox::warning(this,trUtf8("Fehler"),trUtf8("Geben Sie bitte ein Passwort ein oder wählen Sie eine Schlüsseldatei.") + ,trUtf8("OK"),"","",0,0); + return;} +} + +UINT8 file_key[32]={0}; +UINT8 pw_key[32]={0}; + +if(keyfile!=""){ +QFile file(keyfile); +if(file.exists()){ +int r=QMessageBox::warning(this,trUtf8("Vorhandene Datei überschreiben?"),trUtf8("Unter dem gewählten Dateinamen existiert bereits eine Datei.\nSoll sie überschrieben werden?"),"Ja","Nein",NULL,1,1); +if(r==1)return;} +getRandomBytes(file_key,1,32,true); +if(file.open(IO_WriteOnly | IO_Truncate)==false){ +QMessageBox::critical(this,trUtf8("Fehler"),trUtf8("Schlüsseldatei konnte nicht geöffnet werden."),"OK",0,0,2,1); +return; +} +if(file.writeBlock((char*)file_key,32)!=32){ +file.close(); +QMessageBox::critical(this,trUtf8("Fehler"),trUtf8("Das Schreiben der Schlüsseldatei ist fehlgeschlagen."),"OK",0,0,2,1); +return; +} +file.close(); +} + +if(CheckBox_Both->isChecked() || keyfile==""){ + if(password!=Edit_Password_2->text()){ + QMessageBox::critical(this,trUtf8("Fehler"),trUtf8("Passwort und Passwortwiederholung stimmen nicht überein.\nBitte prüfen Sie Ihre Eingabe."),"OK",0,0,2,1); + return;}} + +if(CheckBox_Both->isChecked())db->CalcMasterKeyByFileAndPw(keyfile, password); + else if(password=="")db->CalcMasterKeyByFile(keyfile); + else if(keyfile==""){db->CalcMasterKeyByPassword(password);} + +done(1); +} + +void CChangeKeyDlg::OnSelect() +{ +if(Button_Browse->isEnabled()){ +keyfile=QFileDialog::getSaveFileName(QDir::homeDirPath(),"",this,trUtf8("Schlüsseldatei öffnen")); +if(keyfile=="")return; +Combo_Dirs->insertItem(keyfile); +Combo_Dirs->setCurrentItem(Combo_Dirs->count()-1); +if(!CheckBox_Both->isChecked()){ + Edit_Password->setDisabled(true); + Edit_Password->setText(""); + password=""; +} +Paths.append(keyfile); +IsFile.append(true); +} +} + + +void CChangeKeyDlg::OnBrowse() +{ +QString dir=QFileDialog::getExistingDirectory(QDir::homeDirPath(),NULL,trUtf8("Verzeichnis wählen")); +if(dir=="")return; +keyfile=dir+"/pwsafe.key"; +Combo_Dirs->insertItem(dir); +Combo_Dirs->setCurrentItem(Combo_Dirs->count()-1); +if(!CheckBox_Both->isChecked()){ + Edit_Password->setDisabled(true); + Edit_Password_2->setDisabled(true); + Edit_Password->setText(""); + Edit_Password_2->setText(""); + password=""; +} +Paths.append(dir); +IsFile.append(false); +} + + +void CChangeKeyDlg::OnCancel() +{ +done(0); +} + +void CChangeKeyDlg::OnPasswordChanged(const QString& str) +{ +if(str!="" && !(CheckBox_Both->isChecked())){ +Combo_Dirs->setDisabled(true); +Button_Browse->setDisabled(true);} +else{ +Combo_Dirs->setEnabled(true); +Button_Browse->setEnabled(true);} +Edit_Password_2->setText(""); +password=str; +} + +void CChangeKeyDlg::OnPassword2Changed(const QString& str) +{ +} + +void CChangeKeyDlg::OnComboChanged(int i) +{ +if(i==0){ +keyfile=""; +Edit_Password->setEnabled(true); +Edit_Password_2->setEnabled(true); +return; +} +if(IsFile[i]==true)keyfile=Paths[i]; +else keyfile=Paths[i]+"/pwsafe.key"; + +if(!CheckBox_Both->isChecked()){ +Edit_Password->setText(""); +Edit_Password->setDisabled(true); +Edit_Password_2->setText(""); +Edit_Password_2->setDisabled(true);} + +} + +void CChangeKeyDlg::OnCheckBoxChanged(int i) +{ +if(i==QButton::NoChange)return; +if(i==QButton::On){ +Combo_Dirs->setEnabled(true); +Button_Browse->setEnabled(true); +Edit_Password->setEnabled(true); +Edit_Password_2->setEnabled(true); +} +} + +void CChangeKeyDlg::ChangeEchoMode() +{ +if(Edit_Password->echoMode()==QLineEdit::Normal){ +Edit_Password->setEchoMode(QLineEdit::Password); +Edit_Password_2->setEchoMode(QLineEdit::Password); +} +else +{ +Edit_Password->setEchoMode(QLineEdit::Normal); +Edit_Password_2->setEchoMode(QLineEdit::Normal); +} + +} + + + + + + +/*$SPECIALIZATION$*/ + + +//#include "changekeydlg.moc" + diff --git a/src/dialogs/ChangeKeyDlg.h b/src/dialogs/ChangeKeyDlg.h new file mode 100755 index 0000000..bbf673e --- /dev/null +++ b/src/dialogs/ChangeKeyDlg.h @@ -0,0 +1,71 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * tarek@linux * + * * + * 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. * + ***************************************************************************/ +#include "mainwindow.h" +#ifndef _CHANGEKEYDLG_H_ +#define _CHANGEKEYDLG_H_ +#include "ui_ChangeKeyDlg.h" +#include +#include +#include + +class CChangeKeyDlg : public ChangeKeyDialog +{ + Q_OBJECT + +public: + CChangeKeyDlg(QWidget* parent,PwDatabase* db, const char* name = 0, bool modal = true, WFlags fl = 0 ); + ~CChangeKeyDlg(); + /*$PUBLIC_FUNCTIONS$*/ + +public slots: + /*$PUBLIC_SLOTS$*/ + +protected: + /*$PROTECTED_FUNCTIONS$*/ + +protected slots: + /*$PROTECTED_SLOTS$*/ + +public slots: + virtual void OnSelect(); + virtual void OnBrowse(); + virtual void OnCancel(); + virtual void OnOK(); + virtual void OnComboChanged(int i); + virtual void OnCheckBoxChanged(int i); + virtual void OnPasswordChanged(const QString& str); + virtual void OnPassword2Changed(const QString& str); + virtual void ChangeEchoMode(); + + +private: +PwDatabase* db; +CMainWindow* parentwnd; +QStringList Paths; +QValueList IsFile; + +public: +QString keyfile; +QFile* pKeyFile; +QString password; +}; + +#endif + diff --git a/src/dialogs/DatabaseSettingsDlg.cpp b/src/dialogs/DatabaseSettingsDlg.cpp new file mode 100755 index 0000000..6a7acd7 --- /dev/null +++ b/src/dialogs/DatabaseSettingsDlg.cpp @@ -0,0 +1,84 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * tarek@linux * + * * + * 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. * + ***************************************************************************/ +#include +#include +#include +#include "mainwindow.h" +#include "DatabaseSettingsDlg.h" + + +CDbSettingsDlg::CDbSettingsDlg(CMainWindow* parent,Database* db, const char* name, bool modal, WFlags fl) +: dbsettingdlg_base(parent,name, modal,fl) +{ +database=db; +} + +CDbSettingsDlg::~CDbSettingsDlg() +{ +} + +void CDbSettingsDlg::showEvent(QShowEvent *event){ +if(event->spontaneous()==false){ +((CMainWindow*)parentWidget())->CreateBanner(Banner,((CMainWindow*)parentWidget())->Icon_Settings32x32,"Einstellungen"); +ComboAlgo->insertItem(trUtf8("AES(Rijndael): 256 Bit (Standard)"),0); +ComboAlgo->insertItem(trUtf8("Twofish: 256 Bit"),1); +ComboAlgo->setCurrentItem(database->CryptoAlgorithmus); //Achtung: AlgoID muss gleich dem ComboBox Index sein! +EditRounds->setText(QString::number(database->KeyEncRounds)); + +} +} + +void CDbSettingsDlg::OnCancel() +{ +close(); +} + + +void CDbSettingsDlg::OnOK() +{ +if(EditRounds->text()==""){ +QMessageBox::warning(NULL,trUtf8("Fehler"),trUtf8("Geben Sie bitte die Anzahl der Verschlüsselungsrunden an."),trUtf8("OK")); +return; +} +bool valid; +int rounds=EditRounds->text().toUInt(&valid,10); +if(valid==false){ +QMessageBox::warning(NULL,trUtf8("Fehler"),EditRounds->text()+trUtf8(" ist kein gültiger Zahlenwert"),trUtf8("OK")); +return; +} +if(rounds==0){ +QMessageBox::warning(NULL,trUtf8("Fehler"),trUtf8("Die Anzahl an Verschlüsselungsrunden muss mindestens 1 betragen."),trUtf8("OK")); +return; +} +database->KeyEncRounds=rounds; +database->CryptoAlgorithmus=ComboAlgo->currentItem(); + +close(); +} + + + + + +/*$SPECIALIZATION$*/ + + +//#include "databasesettingsdlg.moc" + diff --git a/src/dialogs/DatabaseSettingsDlg.h b/src/dialogs/DatabaseSettingsDlg.h new file mode 100755 index 0000000..0226d96 --- /dev/null +++ b/src/dialogs/DatabaseSettingsDlg.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * tarek@linux * + * * + * 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. * + ***************************************************************************/ +#ifndef DBSETTINGSDLG_H +#define DBSETTINGSDLG_H +#include "ui_DatabaseSettingsDlg.h" +#include "mainwindow.h" +#include "Database.h" + +class CDbSettingsDlg : public dbsettingdlg_base +{ + Q_OBJECT + +public: + CDbSettingsDlg(CMainWindow* parent,Database* db,const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~CDbSettingsDlg(); + virtual void showEvent(QShowEvent *); + /*$PUBLIC_FUNCTIONS$*/ + +public slots: + /*$PUBLIC_SLOTS$*/ + +protected: + /*$PROTECTED_FUNCTIONS$*/ + +protected slots: + /*$PROTECTED_SLOTS$*/ + +public slots: + virtual void OnCancel(); + virtual void OnOK(); + +private: + Database* database; +}; + +#endif + diff --git a/src/dialogs/EditEntryDlg.cpp b/src/dialogs/EditEntryDlg.cpp new file mode 100755 index 0000000..60fb2d0 --- /dev/null +++ b/src/dialogs/EditEntryDlg.cpp @@ -0,0 +1,371 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * tarek@linux * + * * + * 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. * + ***************************************************************************/ +#include "mainwindow.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "PasswordGenDlg.h" +#include "EditEntryDlg.h" + + + +CEditEntryDlg::CEditEntryDlg(QWidget* parent, const char* name, bool modal, WFlags fl) +: EditEntryDialog(parent,name, modal,fl) +{ + +pw=((CMainWindow*)parentWidget())->db; +mainwnd=((CMainWindow*)parentWidget()); +mainwnd->CreateBanner(Banner,mainwnd->Icon_Key32x32,trUtf8("Eintrag bearbeiten")); +ModFlag=false; +} + +CEditEntryDlg::~CEditEntryDlg() +{ + + +} + + +void CEditEntryDlg::showEvent(QShowEvent *event){ + +if(event->spontaneous()==false){ +if(entry->pBinaryData==NULL){ +ButtonSaveAttachment->setDisabled(true); +ButtonDeleteAttachment->setDisabled(true); +} +setCaption(entry->Title); +setIcon(mainwnd->EntryIcons[entry->ImageID]); +Edit_Title->setText(entry->Title); +Edit_UserName->setText(entry->UserName); +Edit_URL->setText(entry->URL); +Edit_Password->setText(entry->Password.getString()); +Edit_Password_w->setText(entry->Password.getString()); +entry->Password.delRef(); +if(!mainwnd->config.ShowPasswords)ChangeEchoMode(); +OnPasswordwLostFocus(); +int bits=(entry->Password.length()*8); +Label_Bits->setText(QString::number(bits)+" Bit"); +if(bits>128)bits=128; +Progress_Quali->setProgress(bits,128); +Progress_Quali->setPercentageVisible(false); +Edit_Attachment->setText(entry->BinaryDesc); +Edit_Comment->setText(entry->Additional); +InitGroupComboBox(); +InitIconComboBox(); +Edit_Expire_Date->setText((entry->Expire.GetString(0)).mid(0,10)); +Edit_Expire_Time->setText((entry->Expire.GetString(0)).mid(11,8)); +if(entry->BinaryDataLength==0){ +Label_AttachmentSize->setText(""); +} +else +{ +QString unit; +int faktor; +int prec; + if(entry->BinaryDataLength<1000){unit=" Byte";faktor=1;prec=0;} + else {if(entry->BinaryDataLength<1000000){unit=" kB";faktor=1000;prec=1;} + else{unit=" MB";faktor=1000000;prec=1;} + } +Label_AttachmentSize->setText(QString::number((float)entry->BinaryDataLength/(float)faktor,'f',prec)+unit); +} + +} +} + +void CEditEntryDlg::InitIconComboBox(){ +for(int i=0;i<52;i++){ +Combo_IconPicker->insertItem(((CMainWindow*)parentWidget())->EntryIcons[i],"",i); +} +Combo_IconPicker->setCurrentItem(entry->ImageID); +} + + +void CEditEntryDlg::InitGroupComboBox(){ +QString tmp; +int i; +for(i=0;i!=pw->Groups.size();i++){ +tmp=""; + for(int j=0;jGroups[i].Level;j++)tmp+=" "; +Combo_Group->insertItem(((CMainWindow*)parentWidget())->EntryIcons[pw->Groups[i].ImageID], + tmp+pw->Groups[i].Name,i); +} +Combo_Group->setCurrentItem(pw->getGroupIndex(entry->GroupID)); +} + +void CEditEntryDlg::OnButtonOK() +{ + +if(QString::compare(Edit_Password->text(),Edit_Password_w->text())!=0){ +QMessageBox::warning(NULL,"Stopp",QString::fromUtf8("Passwort und Passwortwiederholung stimmen\nnicht überein."),"OK"); +return; +} +QString str=Edit_Expire_Date->text(); +if(CPwmTime::IsValidDate(str)==false){ +QMessageBox::warning(NULL,"Stopp",QString::fromUtf8(str+" ist kein gültiges Datum."),"OK"); +return; +} + +str=Edit_Expire_Time->text(); +if(CPwmTime::IsValidTime(str)==false){ +QMessageBox::warning(NULL,"Stopp",QString::fromUtf8(str+" ist keine gültige Uhrzeit."),"OK"); +return; +} + +CPwmTime tmp_Expire; +tmp_Expire.SetDate(Edit_Expire_Date->text()); +tmp_Expire.SetTime(Edit_Expire_Time->text()); +if(tmp_Expire!=entry->Expire) + ModFlag=true; +if(entry->Title!=Edit_Title->text()) + ModFlag=true; +if(entry->UserName!=Edit_UserName->text()) + ModFlag=true; +if(entry->URL!=Edit_URL->text()) + ModFlag=true; +if(entry->Additional!=Edit_Comment->text()) + ModFlag=true; +QString& passw=entry->Password.getString(); +if(passw!=Edit_Password->text()) + ModFlag=true; +entry->Password.delRef(); + +entry->Expire.SetDate(Edit_Expire_Date->text()); +entry->Expire.SetTime(Edit_Expire_Time->text()); +entry->LastAccess.SetToNow(); +if(ModFlag)entry->LastMod.SetToNow(); +entry->Title=Edit_Title->text(); +entry->UserName=Edit_UserName->text(); +entry->URL=Edit_URL->text(); +QString s=Edit_Password->text(); +entry->Password.setString(s,true); +entry->Additional=Edit_Comment->text(); +if(Combo_Group->currentItem()!=pw->getGroupIndex(entry->GroupID)){ +pw->moveEntry(entry,&pw->Groups[Combo_Group->currentItem()]); +} +entry->ImageID=Combo_IconPicker->currentItem(); +done(1); +} + +void CEditEntryDlg::OnButtonCancel() +{ +entry->LastAccess.SetToNow(); +done(0); +} + +void CEditEntryDlg::ChangeEchoMode() +{ +if(Edit_Password->echoMode()==QLineEdit::Normal){ +Edit_Password->setEchoMode(QLineEdit::Password); +Edit_Password_w->setEchoMode(QLineEdit::Password); +} +else +{ +Edit_Password->setEchoMode(QLineEdit::Normal); +Edit_Password_w->setEchoMode(QLineEdit::Normal); +} + + +} + +void CEditEntryDlg::OnPasswordTextChanged(const QString& txt) +{ +Edit_Password_w->setText(""); +int bits=(Edit_Password->text().length()*8); +Label_Bits->setText(QString::number(bits)+" Bit"); +if(bits>128)bits=128; +Progress_Quali->setProgress(bits,128); +} + +void CEditEntryDlg::OnPasswordwTextChanged(const QString& w) +{ + +if(QString::compare(Edit_Password_w->text(),Edit_Password->text().mid(0,(Edit_Password_w->text().length())))!=0){ +Edit_Password_w->setPaletteBackgroundColor(QColor(255,125,125)); +}else +{ +Edit_Password_w->setPaletteBackgroundColor(QColor(255,255,255)); ///@FIXME Standart-Hintergrundfarbe nicht weiß +} + + + +} + +void CEditEntryDlg::OnPasswordwLostFocus() +{ +if(QString::compare(Edit_Password_w->text(),Edit_Password->text())!=0){ +Edit_Password_w->setPaletteBackgroundColor(QColor(255,125,125)); +} +else +{ +Edit_Password_w->setPaletteBackgroundColor(QColor(255,255,255)); ///@FIXME Standart-Hintergrundfarbe nicht weiß +} + + +} + +void CEditEntryDlg::OnExpDateLostFocus() +{ +QString str=Edit_Expire_Date->text(); +if(CPwmTime::IsValidDate(str)==false){ +Edit_Expire_Date->setPaletteBackgroundColor(QColor(255,125,125)); +} +else +{ +Edit_Expire_Date->setPaletteBackgroundColor(QColor(255,255,255));///@FIXME Standart-Hintergrundfarbe nicht weiß +} +} + +void CEditEntryDlg::OnExpTimeLostFocus() +{ +QString str=Edit_Expire_Time->text(); +if(CPwmTime::IsValidTime(str)==false){ +Edit_Expire_Time->setPaletteBackgroundColor(QColor(255,125,125)); +} +else +{ +Edit_Expire_Time->setPaletteBackgroundColor(QColor(255,255,255));///@FIXME Standart-Hintergrundfarbe nicht weiß +} +} + +void CEditEntryDlg::OnNewAttachment() +{ +QString filename=QFileDialog::getOpenFileName(QDir::homeDirPath(),"",this,QString::fromUtf8("Anhang hinzufügen...")); +if(filename=="")return; +QFile file(filename); +if(file.open(IO_ReadOnly)==false){ +file.close(); +QMessageBox::warning(NULL,trUtf8("Fehler"),trUtf8("Datei konnte nicht geöffnet werden."),"OK"); +return; +} +ModFlag=true; +if(entry->pBinaryData)delete [] entry->pBinaryData; +entry->pBinaryData = new UINT8 [file.size()]; + +if(entry->pBinaryData==NULL){ +file.close(); +QMessageBox::critical(NULL,"Fehler",QString::fromUtf8("Es ist nicht genügend Arbeitsspeicher für diesen Vorgang vorhanden."),"OK"); +return; +} +entry->BinaryDataLength=file.size(); +file.readBlock((char*)entry->pBinaryData,file.size()); +file.close(); +QFileInfo info(filename); +entry->BinaryDesc=info.fileName(); +file.close(); +Edit_Attachment->setText(entry->BinaryDesc); +QString unit; +int faktor; +int prec; + if(entry->BinaryDataLength<1000){unit=" Byte";faktor=1;prec=0;} + else {if(entry->BinaryDataLength<1000000){unit=" kB";faktor=1000;prec=1;} + else{unit=" MB";faktor=1000000;prec=1;} + } +Label_AttachmentSize->setText(QString::number((float)entry->BinaryDataLength/(float)faktor,'f',prec)+unit); +ButtonOpenAttachment->setEnabled(true); +ButtonSaveAttachment->setEnabled(true); +ButtonDeleteAttachment->setEnabled(true); +} + +void CEditEntryDlg::OnSaveAttachment() +{ +QString filename=QFileDialog::getSaveFileName(QDir::homeDirPath(),"",this,trUtf8("Anhang speichern...")); +if(filename=="")return; +QFile file(filename); +if(file.exists()){ +int r=QMessageBox::warning(this,QString::fromUtf8("Vorhandene Datei überschreiben?"),QString::fromUtf8("Unter dem gewählten Dateinamen existiert bereits eine Datei.\nSoll sie überschrieben werden?"),"Ja","Nein",NULL,1,1); +if(r==1)return; +if(file.remove()==false){ +QMessageBox::critical(NULL,"Fehler",QString::fromUtf8("Datei konnte nicht überschrieben werden."),"OK"); +return;} +} +if(file.open(IO_WriteOnly)==false){ +QMessageBox::critical(NULL,"Fehler",QString::fromUtf8("Datei konnte nicht erstellt werden."),"OK"); +return; +} + +int r=file.writeBlock((char*)entry->pBinaryData,entry->BinaryDataLength); +if(r==-1){ +file.close(); +QMessageBox::critical(NULL,"Fehler",QString::fromUtf8("Beim schreiben in der Datei ist ein Fehler aufgetreten."),"OK"); +return; +} +if(r!=entry->BinaryDataLength){ +file.close(); +QMessageBox::critical(NULL,"Fehler",QString::fromUtf8("Die Datei konnte nicht vollständig geschrieben werden."),"OK"); +return; +} +file.close(); +} + +void CEditEntryDlg::OnDeleteAttachment() +{ +int r=QMessageBox::warning(this,trUtf8("Anhang löschen?"),trUtf8("Sie sind dabei den Anhang zu löschen.\nSind Sie sicher, dass Sie dies tun wollen?"),trUtf8("Ja"),trUtf8("Nein"),NULL,1,1); +if(r==0){ +ModFlag=true; +delete[]entry->pBinaryData; +entry->pBinaryData=NULL; +entry->BinaryDataLength=0; +entry->BinaryDesc=""; +Edit_Attachment->setText(""); +Label_AttachmentSize->setText(""); +ButtonOpenAttachment->setEnabled(true); +ButtonSaveAttachment->setDisabled(true); +ButtonDeleteAttachment->setDisabled(true); +} +} + +void CEditEntryDlg::OnButtonGenPw() +{ +CGenPwDialog* pDlg=new CGenPwDialog(this,0,true); +pDlg->show(); +} + + + + + + + + + + + + + + +/*$SPECIALIZATION$*/ + + +//#include "editentrydlg.moc" + diff --git a/src/dialogs/EditEntryDlg.h b/src/dialogs/EditEntryDlg.h new file mode 100755 index 0000000..2ffcdbd --- /dev/null +++ b/src/dialogs/EditEntryDlg.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * tarek@linux * + * * + * 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. * + ***************************************************************************/ +#include "mainwindow.h" +#ifndef EDITENTRYDLG_H +#define EDITENTRYDLG_H +#include "ui_EditEntryDlg.h" + +class CEditEntryDlg : public EditEntryDialog +{ + Q_OBJECT + +public: + CEditEntryDlg(QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0); + ~CEditEntryDlg(); + virtual void showEvent(QShowEvent *); + /*$PUBLIC_FUNCTIONS$*/ + +public slots: + virtual void OnButtonOK(); + /*$PUBLIC_SLOTS$*/ + +protected: + /*$PROTECTED_FUNCTIONS$*/ + +protected slots: + /*$PROTECTED_SLOTS$*/ + +public: +CMainWindow* mainwnd; +CEntry* entry; +PwDatabase* pw; +QPixmap* banner_pixmap; +bool ModFlag; + + +void CreateBanner(); +void InitGroupComboBox(); +void InitIconComboBox(); + + +public slots: + virtual void OnExpTimeLostFocus(); + virtual void OnExpDateLostFocus(); + virtual void OnPasswordwLostFocus(); + virtual void OnPasswordwTextChanged(const QString&); + virtual void OnPasswordTextChanged(const QString&); + virtual void ChangeEchoMode(); + virtual void OnButtonCancel(); + virtual void OnNewAttachment(); + virtual void OnDeleteAttachment(); + virtual void OnSaveAttachment(); + virtual void OnButtonGenPw(); + +}; + +#endif + diff --git a/src/dialogs/EditGroupDlg.cpp b/src/dialogs/EditGroupDlg.cpp new file mode 100755 index 0000000..a3bcc23 --- /dev/null +++ b/src/dialogs/EditGroupDlg.cpp @@ -0,0 +1,68 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * tarek@linux * + * * + * 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. * + ***************************************************************************/ + +#include "mainwindow.h" + +#include +#include +#include "EditGroupDlg.h" + + +CEditGroupDialog::CEditGroupDialog(QWidget* parent, const char* name, bool modal, WFlags fl) +: EditGroupDialog(parent,name, modal,fl) +{ +IconID=0; +} + +CEditGroupDialog::~CEditGroupDialog() +{ +} + +void CEditGroupDialog::showEvent(QShowEvent *event){ +if(event->spontaneous()==false){ +EditTitle->setText(GroupName); +for(int i=0;i<52;i++){ +ComboIconPicker->insertItem(((CMainWindow*)parentWidget())->EntryIcons[i],"",i); +} +ComboIconPicker->setCurrentItem(IconID); +}} + +void CEditGroupDialog::OnOK() +{ +GroupName=EditTitle->text(); +IconID=ComboIconPicker->currentItem(); +OK=true; +close(); +} + +void CEditGroupDialog::OnCancel() +{ +OK=false; +close(); +} + + + + +/*$SPECIALIZATION$*/ + + +//#include "editgroupdlg.moc" + diff --git a/src/dialogs/EditGroupDlg.h b/src/dialogs/EditGroupDlg.h new file mode 100755 index 0000000..1a61aea --- /dev/null +++ b/src/dialogs/EditGroupDlg.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * tarek@linux * + * * + * 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. * + ***************************************************************************/ + +#ifndef EDITGROUPDLG_H +#define EDITGROUPDLG_H + +#include "ui_EditGroupDlg.h" +#include + +class CEditGroupDialog : public EditGroupDialog +{ + Q_OBJECT + +public: + CEditGroupDialog(QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~CEditGroupDialog(); +virtual void showEvent(QShowEvent *event); + /*$PUBLIC_FUNCTIONS$*/ + +protected: + /*$PROTECTED_FUNCTIONS$*/ + +protected slots: + /*$PROTECTED_SLOTS$*/ + +public: + int IconID; + QString GroupName; + bool OK; + + +public slots: + virtual void OnOK(); + virtual void OnCancel(); +}; + +#endif + diff --git a/src/dialogs/LanguageDlg.cpp b/src/dialogs/LanguageDlg.cpp new file mode 100755 index 0000000..6fd6591 --- /dev/null +++ b/src/dialogs/LanguageDlg.cpp @@ -0,0 +1,149 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * mail@tarek-saidi.de * + * * + * 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. * + ***************************************************************************/ +#include "mainwindow.h" +#include "LanguageDlg.h" +#include +#include +#include +#include +#include +#include + +const char* infostrings[]={ +QT_TRANSLATE_NOOP("_INFO","$TRANSL_AUTHOR"), +QT_TRANSLATE_NOOP("_INFO","$TRANSL_AUTHOR_CONTACT"), +QT_TRANSLATE_NOOP("_INFO","$TRANSL_LANGUAGE"), +QT_TRANSLATE_NOOP("_INFO","$TRANSL_VERSION")}; +const char* msg[]={QT_TRANSLATE_NOOP("_MSG","Die Änderung der Sprache wird erst nach einem Neustart von Keepass wirksam."), + QT_TRANSLATE_NOOP("_MSG","OK"), + QT_TRANSLATE_NOOP("_MSG","Hinweis")}; + +CLanguageDlg::CLanguageDlg(QWidget* parent, const char* name, WFlags fl) +: LanguageDlg(parent,name,fl) +{ +parentwnd=((CMainWindow*)parentWidget()); +parentwnd->CreateBanner(Banner,parentwnd->Icon_I18n32x32,trUtf8("Spracheinstellungen")); + +QListViewItem* item; +QString& config_lang=parentwnd->config.Language; +QStringList files; + +QString langdir=parentwnd->appdir+"/../share/keepass/i18n/"; +QDir dir(langdir); +if(dir.exists()){ +files=dir.entryList("*.qm",QDir::Files); +} + +List->insertItem(item=new QListViewItem(List,"","Deutsch","-","-")); +if(config_lang=="_DEUTSCH_")item->setPixmap(0,*parentwnd->Icon_Ok16x16); +pItems.push_back(item); +filenames.push_back("_DEUTSCH_"); + + +for(int i=0;iinsertItem(item=new QListViewItem(List,"",translator.findMessage("_INFO","$TRANSL_LANGUAGE").translation() + ,translator.findMessage("_INFO","$TRANSL_VERSION").translation() + ,translator.findMessage("_INFO","$TRANSL_AUTHOR").translation())); +if(config_lang==files[i])item->setPixmap(0,*parentwnd->Icon_Ok16x16); +pItems.push_back(item); +filenames.push_back(files[i]); +} +} + +CLanguageDlg::~CLanguageDlg() +{ +} + +void CLanguageDlg::showEvent(QShowEvent *event){ +if(event->spontaneous()==false){ +List->setColumnWidth(0,20); +int width=(List->width()-4-20)/3; +List->setColumnWidth(1,width); +List->setColumnWidth(2,width); +List->setColumnWidth(3,width); +} +} + +void CLanguageDlg::OnItemRightClick(QListViewItem* item) +{ +//CTX-MENU + +} + +void CLanguageDlg::OnItemDoubleClicked(QListViewItem* item) // == Slot für Button "wählen" +{ +int i; +QString langdir=parentwnd->appdir+"/../share/keepass/i18n/"; + +for(i=0;iconfig.Language=filenames[i]; + +for(int j=0;jsetPixmap(0,*parentwnd->Icon_Ok16x16); +else pItems[j]->setPixmap(0,0);} + +List->setColumnWidth(0,20); +int width=(List->width()-4-20)/3; +List->setColumnWidth(1,width); +List->setColumnWidth(2,width); +List->setColumnWidth(3,width); + +} + +void CLanguageDlg::OnApplyButtonClicked() +{ +QListViewItem* item=List->selectedItem(); +if(item)OnItemDoubleClicked(item); +else QMessageBox::information(this,tr("Hinweis"),trUtf8("Es ist keine Übersetzung aufsgewählt."),tr("OK"),0,0,2,1); +} + +void CLanguageDlg::OnButtonCloseClicked() +{ +done(0); +} + + + + + +/*$SPECIALIZATION$*/ + + diff --git a/src/dialogs/LanguageDlg.h b/src/dialogs/LanguageDlg.h new file mode 100755 index 0000000..5b6e79e --- /dev/null +++ b/src/dialogs/LanguageDlg.h @@ -0,0 +1,59 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * mail@tarek-saidi.de * + * * + * 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. * + ***************************************************************************/ +#include "mainwindow.h" +#ifndef _LANGUAGEDLG_H_ +#define _LANGUAGEDLG_H_ +#include "ui_LanguageDlg.h" +#include + + + +class CLanguageDlg : public LanguageDlg +{ + Q_OBJECT + +public: + CLanguageDlg(QWidget* parent = 0, const char* name = 0, WFlags fl = 0 ); + ~CLanguageDlg(); + CMainWindow* parentwnd; + vector filenames; + vector pItems; + /*$PUBLIC_FUNCTIONS$*/ + +public slots: + /*$PUBLIC_SLOTS$*/ + + +protected: + /*$PROTECTED_FUNCTIONS$*/ + + +protected slots: + /*$PROTECTED_SLOTS$*/ + virtual void showEvent(QShowEvent *e); + virtual void OnItemDoubleClicked(QListViewItem* item); + virtual void OnItemRightClick(QListViewItem* item); + virtual void OnButtonCloseClicked(); + virtual void OnApplyButtonClicked(); + +}; + +#endif + diff --git a/src/dialogs/PasswordDlg.cpp b/src/dialogs/PasswordDlg.cpp new file mode 100755 index 0000000..3d411d0 --- /dev/null +++ b/src/dialogs/PasswordDlg.cpp @@ -0,0 +1,206 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * tarek@linux * + * * + * 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. * + ***************************************************************************/ + +#include "mainwindow.h" + +#include "PasswordDlg.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +CPasswordDialog::CPasswordDialog(QWidget* parent, const char* name, bool modal, WFlags fl) +: PasswordDlg(parent,name, modal,fl) +{ +parentwnd=((CMainWindow*)parentWidget()); +parentwnd->CreateBanner(Banner,parentwnd->Icon_Key32x32,trUtf8("Datenbank öffnen")); +Label_select=new LinkLabel((QWidget*)groupframe,"Select",trUtf8("Datei manuell wählen..."),410,100); +connect(Label_select,SIGNAL(clicked()),this,SLOT(OnSelectClicked())); +///@PlatformSpecific +QDir media("/media"); +if(media.exists()){ +Paths=media.entryList("*",QDir::Dirs); +Paths.erase(Paths.begin()); // delete "." +Paths.erase(Paths.begin()); // delete ".." + +for(int i=0;i")); +} +for(int i=0;iinsertItem(0,Paths[i]); +IsFile.append(false); +} + +if(!parentwnd->config.ShowPasswords)ChangeEchoMode(); + +} + +CPasswordDialog::~CPasswordDialog() +{ +delete Label_select; +} + +void CPasswordDialog::OnComboSelectionChanged(int i) +{ +if(i==0){ +keyfile=""; +Edit_Password->setEnabled(true); +return; +} +QFile file; +if(IsFile[i]==true)file.setName(Paths[i]); +else file.setName(Paths[i]+"/pwsafe.key"); + +if(file.exists()){ +keyfile=file.name(); +if(!CheckBox_Both->isChecked()){ +Edit_Password->setText(""); +Edit_Password->setDisabled(true);} +return; +} +QMessageBox::warning(this,"Datei nicht gefunden",QString::fromUtf8("Im gewählten Verzeichnis konnte keine Schlüsseldatei gefunden werden.\nStellen Sie sicher, dass der Schlüssel-Datenträger ordnungsgemäß eingehängt (mounted) ist.\nSollte die Schlüsseldatei nicht den Dateinamen 'pwsafe.key' haben, nutzen Sie bitte die manuelle Dateiauswahl."),"OK","","",0,0); +Edit_Password->setEnabled(true); +Combo_Dirs->setCurrentItem(0); + +return; +} + + +void CPasswordDialog::OnButtonBrowse() +{ +///@PlatformSpecific +QString dir=QFileDialog::getExistingDirectory(QDir::homeDirPath(),NULL,QString::fromUtf8("Verzeichnis wählen")); +if(dir=="")return; + +QFile file(dir+"/pwsafe.key"); +if(file.exists()){ +keyfile=dir+"/pwsafe.key"; +Combo_Dirs->insertItem(dir); +Combo_Dirs->setCurrentItem(Combo_Dirs->count()-1); +if(!CheckBox_Both->isChecked()){ + Edit_Password->setDisabled(true); + Edit_Password->setText(""); + password=""; +} +Paths.append(dir); +IsFile.append(false); +return;} +QMessageBox::warning(this,"Datei nicht gefunden",QString::fromUtf8("Im gewählten Verzeichnis konnte keine Schlüsseldatei gefunden werden.\nStellen Sie sicher, dass der Schlüssel-Datenträger ordnungsgemäß eingehängt (mounted) ist.\nSollte die Schlüsseldatei nicht den Dateinamen 'pwsafe.key' haben, nutzen Sie bitte die manuelle Dateiauswahl."),"OK","","",0,0); +} + +void CPasswordDialog::OnSelectClicked() +{ +if(Button_Browse->isEnabled()){ +keyfile=QFileDialog::getOpenFileName(QDir::homeDirPath(),"",this,QString::fromUtf8("Schlüsseldatei öffnen")); +if(keyfile=="")return; +Combo_Dirs->insertItem(keyfile); +Combo_Dirs->setCurrentItem(Combo_Dirs->count()-1); +if(!CheckBox_Both->isChecked()){ + Edit_Password->setDisabled(true); + Edit_Password->setText(""); + password=""; +} +Paths.append(keyfile); +IsFile.append(true); +} +} + +void CPasswordDialog::OnCancel() +{ +canceled=true; +close(); +} + +void CPasswordDialog::OnOK() +{ +canceled=false; + +if(CheckBox_Both->isChecked()){ + if(password==""){QMessageBox::warning(this,trUtf8("Fehler"),trUtf8("Bitte geben Sie ein Passwort ein.") + ,trUtf8("OK"),"","",0,0); + return;} + if(keyfile==""){QMessageBox::warning(this,trUtf8("Fehler"),trUtf8("Bitte wählen Sie eine Schlüsseldatei.") + ,trUtf8("OK"),"","",0,0); + return;} +} +else +{ + if(password=="" && keyfile==""){QMessageBox::warning(this,trUtf8("Fehler"),trUtf8("Geben Sie bitte ein Passwort ein oder wählen Sie eine Schlüsseldatei.") + ,trUtf8("OK"),"","",0,0); + return;} +} +close(); +} + +void CPasswordDialog::OnPasswordChanged(const QString &txt) +{ +password=Edit_Password->text(); +if(txt!="" && !(CheckBox_Both->isChecked())){ +Combo_Dirs->setDisabled(true); +Button_Browse->setDisabled(true);} +else{ +Combo_Dirs->setEnabled(true); +Button_Browse->setEnabled(true);} + +} + +void CPasswordDialog::OnCheckBox_BothChanged(int state) +{ +if(state==QButton::On){ +Combo_Dirs->setEnabled(true); +Button_Browse->setEnabled(true); +Edit_Password->setEnabled(true);} +else{ +Edit_Password->setText(""); +} +} + +void CPasswordDialog::ChangeEchoMode() +{ + +if(Edit_Password->echoMode()==QLineEdit::Normal){ +Edit_Password->setEchoMode(QLineEdit::Password); +} +else +{ +Edit_Password->setEchoMode(QLineEdit::Normal); + +} + +} + + + + + +/*$SPECIALIZATION$*/ + + +//#include "passworddialog.moc" + diff --git a/src/dialogs/PasswordDlg.h b/src/dialogs/PasswordDlg.h new file mode 100755 index 0000000..b927ab8 --- /dev/null +++ b/src/dialogs/PasswordDlg.h @@ -0,0 +1,71 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * tarek@linux * + * * + * 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. * + ***************************************************************************/ +#include "mainwindow.h" +#ifndef PASSWORDDIALOG_H +#define PASSWORDDIALOG_H +#include "lib/UrlLabel.h" +#include "ui_PasswordDlg.h" + +class CPasswordDialog : public PasswordDlg +{ + Q_OBJECT + +private: +CMainWindow* parentwnd; +int NumComboEntries; +QStringList Paths; +QValueList IsFile; +LinkLabel* Label_select; + + +public: + +QString keyfile; +QString password; +bool canceled; + + +public: + CPasswordDialog(QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~CPasswordDialog(); + /*$PUBLIC_FUNCTIONS$*/ + +public slots: + /*$PUBLIC_SLOTS$*/ + + virtual void OnOK(); + virtual void OnCancel(); + virtual void OnSelectClicked(); + virtual void OnButtonBrowse(); +protected: + /*$PROTECTED_FUNCTIONS$*/ + +protected slots: + /*$PROTECTED_SLOTS$*/ + +public slots: + virtual void OnComboSelectionChanged(int); + virtual void OnPasswordChanged(const QString &txt); + virtual void OnCheckBox_BothChanged(int state); + virtual void ChangeEchoMode(); +}; + +#endif + diff --git a/src/dialogs/PasswordGenDlg.cpp b/src/dialogs/PasswordGenDlg.cpp new file mode 100755 index 0000000..d35b741 --- /dev/null +++ b/src/dialogs/PasswordGenDlg.cpp @@ -0,0 +1,236 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * tarek@linux * + * * + * 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. * + ***************************************************************************/ + +#include +#include +#include +#include "PasswordGenDlg.h" +#include +#include +#include +#include + +CGenPwDialog::CGenPwDialog(QWidget* parent, const char* name, bool modal, WFlags fl) +: GenPwDlg(parent,name, modal,fl) +{ +mainwnd=(CMainWindow*)(((CEditEntryDlg*)parentWidget())->parentWidget()); +mainwnd->CreateBanner(Banner,mainwnd->Icon_Key32x32,QString::fromUtf8("Passwort generieren")); + + + +Radio_1->setChecked(true); + +Edit_chars->setDisabled(true); +} + +CGenPwDialog::~CGenPwDialog() +{ +} + +void CGenPwDialog::OnRadio1StateChanged(int state) +{ +switch (state){ + case QButton::On: + Radio_2->setChecked(false); + checkBox1->setEnabled(true); + checkBox2->setEnabled(true); + checkBox3->setEnabled(true); + checkBox4->setEnabled(true); + checkBox5->setEnabled(true); + checkBox6->setEnabled(true); + checkBox7->setEnabled(true); + checkBox8->setEnabled(true); + break; + case QButton::Off: + if(Radio_2->isChecked()==false)Radio_2->setChecked(true); + checkBox1->setDisabled(true); + checkBox2->setDisabled(true); + checkBox3->setDisabled(true); + checkBox4->setDisabled(true); + checkBox5->setDisabled(true); + checkBox6->setDisabled(true); + checkBox7->setDisabled(true); + checkBox8->setDisabled(true); + + break; + case QButton::NoChange: + break; +} + +} + +void CGenPwDialog::OnRadio2StateChanged(int state) +{ +switch (state){ + case QButton::On: + Radio_1->setChecked(false); + Edit_chars->setEnabled(true); + break; + case QButton::Off: + if(Radio_1->isChecked()==false)Radio_1->setChecked(true); + Edit_chars->setDisabled(true); + break; + case QButton::NoChange: + break; +} + +} + +void CGenPwDialog::OnGeneratePw() +{ +/* +Großbuchstaben 65...90 +Kleinbuchstaben 97...122 +Zahlen 48...57 +Sonderzeichen 33...47;58...64;91...96;123...126 +Minus 45 +Unterstrich 95 +ANSI >127 +*/ + +int num=0; +char assoctable[255]; + +if(Radio_1->isChecked()){ +if(checkBox1->isChecked()){ +num+=AddToAssoctable(assoctable,65,90,num); +} + +if(checkBox2->isChecked()){ +num+=AddToAssoctable(assoctable,97,122,num); +} + +if(checkBox3->isChecked()){ +num+=AddToAssoctable(assoctable,48,57,num); +} + +if(checkBox4->isChecked()){ +num+=AddToAssoctable(assoctable,33,47,num); +num+=AddToAssoctable(assoctable,58,64,num); +num+=AddToAssoctable(assoctable,91,96,num); +num+=AddToAssoctable(assoctable,123,126,num); +} + +if(checkBox5->isChecked()){ +num+=AddToAssoctable(assoctable,32,32,num); +} + + +if(checkBox6->isChecked() && !checkBox4->isChecked()){ +num+=AddToAssoctable(assoctable,45,45,num); +} + +if(checkBox7->isChecked() && !checkBox4->isChecked()){ +num+=AddToAssoctable(assoctable,95,95,num); +} + +if(checkBox8->isChecked()){ +num+=AddToAssoctable(assoctable,128,255,num); +} +}else +{ +QString str=Edit_chars->text(); +int i=0; +while(str.length()>0){ +assoctable[i]=(char)((QChar)str[0]); +str.remove(str[0]); +i++; +num++; +} +} +if(num==0){ +if(Radio_2->isChecked())QMessageBox::information(this,"Hinweis",QString::fromUtf8("Es wird mindestens ein Zeichen benötigt"),"OK"); +else QMessageBox::information(this,"Hinweis",QString::fromUtf8("Es muss mindestens ein Gruppe von Zeichen gewählt werden"),"OK"); +return; +} +int length=Spin_Num->value(); +char* buffer=new char[length+1]; +buffer[length]=0; +FILE *dev_random; +if(Check_strongrandom->isChecked()){ +dev_random = fopen("/dev/random","r");} +else +{dev_random = fopen("/dev/urandom","r");} + +if (dev_random==NULL){ +QMessageBox::critical(this,"Fehler",QString::fromUtf8("'/dev/random' bzw. '/dev/urandom' konnte nicht zum lesen geöffnet werden."),"OK"); +return; +} +unsigned char tmp; + +for(int i=0;isetText(buffer); +delete [] buffer; +fclose(dev_random); + +int bits; +if(checkBox8->isChecked())bits=length*8; +else bits=length*7; +Label_Bits->setText(QString::number(bits)+" Bit"); +if(bits>128)bits=128; +Progress_Quali->setProgress(bits,128); +Progress_Quali->setPercentageVisible(false); +} + +int CGenPwDialog::AddToAssoctable(char* table,int start,int end,int pos){ +for(int i=start;i<=end;i++){ +table[pos]=i; +pos++; +} +return (end-start)+1; +} + + +bool CGenPwDialog::trim(unsigned char &x, int r){ +if(xEdit_Password->setText(Edit_dest->text()); +((CEditEntryDlg*)parentWidget())->Edit_Password_w->setText(Edit_dest->text()); +((CEditEntryDlg*)parentWidget())->ModFlag=true; +close(); +} + +void CGenPwDialog::OnCancel() +{ +close(); +} + + + + +/*$SPECIALIZATION$*/ + + +//#include "genpwdialog.moc" + diff --git a/src/dialogs/PasswordGenDlg.h b/src/dialogs/PasswordGenDlg.h new file mode 100755 index 0000000..14ac737 --- /dev/null +++ b/src/dialogs/PasswordGenDlg.h @@ -0,0 +1,60 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * tarek@linux * + * * + * 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. * + ***************************************************************************/ +#include "mainwindow.h" +#ifndef GENPWDIALOG_H +#define GENPWDIALOG_H +#include "ui_PasswordGenDlg.h" +#include "EditEntryDlg.h" + + + +class CGenPwDialog : public GenPwDlg +{ + Q_OBJECT +private: +int AddToAssoctable(char* table,int start,int end,int pos); +bool trim(unsigned char &value,int range); +public: + CGenPwDialog(QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~CGenPwDialog(); + /*$PUBLIC_FUNCTIONS$*/ + +public slots: + /*$PUBLIC_SLOTS$*/ + +protected: + /*$PROTECTED_FUNCTIONS$*/ + +protected slots: + /*$PROTECTED_SLOTS$*/ +public: +CMainWindow* mainwnd; +public slots: + virtual void OnGeneratePw(); +public slots: + virtual void OnRadio2StateChanged(int); +public slots: + virtual void OnRadio1StateChanged(int); + virtual void OnCancel(); + virtual void OnAccept(); +}; + +#endif + diff --git a/src/dialogs/SearchDlg.cpp b/src/dialogs/SearchDlg.cpp new file mode 100755 index 0000000..8df4d62 --- /dev/null +++ b/src/dialogs/SearchDlg.cpp @@ -0,0 +1,97 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * mail@tarek-saidi.de * + * * + * 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. * + ***************************************************************************/ + +#include "PwManager.h" +#include "SearchDlg.h" +#include +#include +#include +#include + +CSearchDlg::CSearchDlg(CGroup* pGroup,QWidget* parent, const char* name, bool modal, WFlags fl) +: Search_Dlg(parent,name, modal,fl) +{ +parentwnd=(CMainWindow*)parent; +parentwnd->CreateBanner(Banner,parentwnd->Icon_Search32x32,tr("Suchen")); +group=pGroup; +pw=parentwnd->db; + +checkBox_Cs->setChecked(parentwnd->config.SearchOptions[0]); +checkBox_regExp->setChecked(parentwnd->config.SearchOptions[1]); +checkBox_Title->setChecked(parentwnd->config.SearchOptions[2]); +checkBox_Username->setChecked(parentwnd->config.SearchOptions[3]); +checkBox_Password->setChecked(parentwnd->config.SearchOptions[4]); +checkBox_Comment->setChecked(parentwnd->config.SearchOptions[5]); +checkBox_URL->setChecked(parentwnd->config.SearchOptions[6]); +checkBox_Attachment->setChecked(parentwnd->config.SearchOptions[7]); +} + +CSearchDlg::~CSearchDlg() +{ +parentwnd->config.SearchOptions[0]=checkBox_Cs->isChecked(); +parentwnd->config.SearchOptions[1]=checkBox_regExp->isChecked(); +parentwnd->config.SearchOptions[2]=checkBox_Title->isChecked(); +parentwnd->config.SearchOptions[3]=checkBox_Username->isChecked(); +parentwnd->config.SearchOptions[4]=checkBox_Password->isChecked(); +parentwnd->config.SearchOptions[5]=checkBox_Comment->isChecked(); +parentwnd->config.SearchOptions[6]=checkBox_URL->isChecked(); +parentwnd->config.SearchOptions[7]=checkBox_Attachment->isChecked(); +} + +void CSearchDlg::OnButtonClose() +{ +done(0); +} + + +void CSearchDlg::OnButtonSearch() +{ +txt=Edit_Search->text(); +regexp=checkBox_regExp->isChecked(); +if(txt==""){ +QMessageBox::information(this,trUtf8("Hinweis"),trUtf8("Bitte geben Sie einen Suchbegriff ein."),"OK",0,0); +return;} + +for(int i=0;iEntries.size();i++){ + if(group){if(pw->Entries[i].GroupID != group->ID)continue;} + bool hit=false; + if(checkBox_Title->isChecked()) hit=hit||search(pw->Entries[i].Title); + if(checkBox_Username->isChecked()) hit=hit||search(pw->Entries[i].UserName); + if(checkBox_URL->isChecked()) hit=hit||search(pw->Entries[i].URL); + if(checkBox_Comment->isChecked()) hit=hit||search(pw->Entries[i].Additional); + if(checkBox_Attachment->isChecked()) hit=hit||search(pw->Entries[i].BinaryDesc); + if(checkBox_Password->isChecked()) hit=hit||search(pw->Entries[i].Password.getString()); + pw->Entries[i].Password.delRef(); + if(hit)hits.push_back(&pw->Entries[i]); +} +done(1); +} +bool CSearchDlg::search(QString& str){ +if(regexp){ + QRegExp exp(txt,checkBox_Cs->isChecked()); + if(str.contains(exp)==0)return false;} +else{ + if(str.contains(txt,checkBox_Cs->isChecked())==0)return false;} +return true; +} + +/*$SPECIALIZATION$*/ + + diff --git a/src/dialogs/SearchDlg.h b/src/dialogs/SearchDlg.h new file mode 100755 index 0000000..4efddd8 --- /dev/null +++ b/src/dialogs/SearchDlg.h @@ -0,0 +1,63 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * mail@tarek-saidi.de * + * * + * 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. * + ***************************************************************************/ +#include "mainwindow.h" +#ifndef SEARCHDLG_H +#define SEARCHDLG_H +#include "ui_SearchDlg.h" + +class CSearchDlg : public Search_Dlg +{ + Q_OBJECT + +public: + CSearchDlg(CGroup* pGroup=NULL,QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~CSearchDlg(); + /*$PUBLIC_FUNCTIONS$*/ + +public slots: + /*$PUBLIC_SLOTS$*/ + +protected: + /*$PROTECTED_FUNCTIONS$*/ + +protected slots: + /*$PROTECTED_SLOTS$*/ + +public slots: + virtual void OnButtonClose(); +public slots: + virtual void OnButtonSearch(); + + +private: + CMainWindow* parentwnd; + CGroup* group; + PwDatabase* pw; + QString txt; + bool regexp; + bool search(QString&); + +public: + vector hits; + +}; + +#endif + diff --git a/src/dialogs/SettingsDlg.cpp b/src/dialogs/SettingsDlg.cpp new file mode 100755 index 0000000..330bb1e --- /dev/null +++ b/src/dialogs/SettingsDlg.cpp @@ -0,0 +1,125 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * tarek@linux * + * * + * 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. * + ***************************************************************************/ +#include "mainwindow.h" +#include +#include +#include +#include +#include +#include "SettingsDlg.h" + + +CSettingsDlg::CSettingsDlg(QWidget* parent, const char* name, bool modal, WFlags fl) +: SettingsDialog(parent,name, modal,fl) +{ +pw=((CMainWindow*)parentWidget())->db; +mainwnd=((CMainWindow*)parentWidget()); +mainwnd->CreateBanner(Banner,mainwnd->Icon_Settings32x32,trUtf8("Einstellungen")); + +CheckBox_OpenLast->setChecked(mainwnd->config.OpenLast); +SpinBox_ClipboardTime->setValue(mainwnd->config.ClipboardTimeOut); +pixmTextColor->setPixmap(*(new QPixmap(pixmTextColor->width(),pixmTextColor->height()))); +pixmTextColor->pixmap()->fill(mainwnd->config.BannerTextColor); + +pixmColor1->setPixmap(*(new QPixmap(pixmColor1->width(),pixmColor1->height()))); +pixmColor1->pixmap()->fill(mainwnd->config.BannerColor1); + +pixmColor2->setPixmap(*(new QPixmap(pixmColor2->width(),pixmColor2->height()))); +pixmColor2->pixmap()->fill(mainwnd->config.BannerColor2); + +color1=mainwnd->config.BannerColor1; +color2=mainwnd->config.BannerColor2; +textcolor=mainwnd->config.BannerTextColor; + +CheckBox_ShowPasswords->setChecked(mainwnd->config.ShowPasswords); +Edit_BrowserCmd->setText(mainwnd->config.OpenUrlCommand); +CheckBox_ExpandGroupTree->setChecked(mainwnd->config.ExpandGroupTree); + +} + +CSettingsDlg::~CSettingsDlg() +{ +} + +void CSettingsDlg::OnOK() +{ +mainwnd->config.OpenLast=CheckBox_OpenLast->isChecked(); +mainwnd->config.ClipboardTimeOut=SpinBox_ClipboardTime->value(); +mainwnd->config.BannerColor1=color1; +mainwnd->config.BannerColor2=color2; +mainwnd->config.BannerTextColor=textcolor; +mainwnd->config.ShowPasswords=CheckBox_ShowPasswords->isChecked(); +mainwnd->config.OpenUrlCommand=Edit_BrowserCmd->text(); +mainwnd->config.ExpandGroupTree=CheckBox_ExpandGroupTree->isChecked(); +close(); +} + +void CSettingsDlg::OnCancel() +{ +close(); +} + +void CSettingsDlg::OnTextColor() +{ +QColor c=QColorDialog::getColor(textcolor,this); +if(c.isValid()){ +textcolor=c; +QPixmap *px=new QPixmap(pixmTextColor->width(),pixmTextColor->height()); +px->fill(c); +pixmTextColor->clear(); +pixmTextColor->setPixmap(*px); +mainwnd->CreateBanner(Banner,mainwnd->Icon_Settings32x32,trUtf8("Einstellungen"),color1,color2,textcolor);} +} + + +void CSettingsDlg::OnColor2() +{ +QColor c=QColorDialog::getColor(color2,this); +if(c.isValid()){ +color2=c; +QPixmap *px=new QPixmap(pixmColor2->width(),pixmColor2->height()); +px->fill(c); +pixmColor2->clear(); +pixmColor2->setPixmap(*px); +mainwnd->CreateBanner(Banner,mainwnd->Icon_Settings32x32,trUtf8("Einstellungen"),color1,color2,textcolor);} +} + + +void CSettingsDlg::OnColor1() +{ +QColor c=QColorDialog::getColor(color1,this); +if(c.isValid()){ +color1=c; +QPixmap *px=new QPixmap(pixmColor1->width(),pixmColor1->height()); +px->fill(c); +pixmColor1->clear(); +pixmColor1->setPixmap(*px); +mainwnd->CreateBanner(Banner,mainwnd->Icon_Settings32x32,trUtf8("Einstellungen"),color1,color2,textcolor); +} +} + + + + +/*$SPECIALIZATION$*/ + + +//#include "settingsdlg.moc" + diff --git a/src/dialogs/SettingsDlg.h b/src/dialogs/SettingsDlg.h new file mode 100755 index 0000000..eabfb4d --- /dev/null +++ b/src/dialogs/SettingsDlg.h @@ -0,0 +1,60 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * tarek@linux * + * * + * 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. * + ***************************************************************************/ +#include "mainwindow.h" +#ifndef SETTINGSDLG_H +#define SETTINGSDLG_H + +#include "ui_SettingsDlg.h" +#include + +class CSettingsDlg : public SettingsDialog +{ + Q_OBJECT + +public: + CMainWindow* mainwnd; + PwDatabase* pw; + CSettingsDlg(QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~CSettingsDlg(); + /*$PUBLIC_FUNCTIONS$*/ + +public slots: + /*$PUBLIC_SLOTS$*/ + +protected: + /*$PROTECTED_FUNCTIONS$*/ + +protected slots: + /*$PROTECTED_SLOTS$*/ + +public slots: + virtual void OnCancel(); +public slots: + virtual void OnOK(); + virtual void OnTextColor(); + virtual void OnColor2(); + virtual void OnColor1(); + +private: + QColor color1,color2,textcolor; +}; + +#endif + diff --git a/src/dialogs/SimplePasswordDlg.cpp b/src/dialogs/SimplePasswordDlg.cpp new file mode 100755 index 0000000..74af573 --- /dev/null +++ b/src/dialogs/SimplePasswordDlg.cpp @@ -0,0 +1,58 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * mail@tarek-saidi.de * + * * + * 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. * + ***************************************************************************/ + + +#include "SimplePasswordDlg.h" +#include +#include + +CSimplePasswordDialog::CSimplePasswordDialog(bool HidePw,QWidget* parent, const char* name, bool modal, WFlags fl) +: SimplePasswordDialog(parent,name, modal,fl) +{ +if(HidePw)Button_HidePassword->toggle(); +} + +CSimplePasswordDialog::~CSimplePasswordDialog() +{ +} + +void CSimplePasswordDialog::OnCancel() +{ +done(0); +} + + +void CSimplePasswordDialog::OnOK() +{ +password=EditPassword->text(); +done(1); +} + + +void CSimplePasswordDialog::OnHidePasswordToggled(bool state) +{ +if(state)EditPassword->setEchoMode(QLineEdit::Password); +else EditPassword->setEchoMode(QLineEdit::Normal); +} + + +/*$SPECIALIZATION$*/ + + diff --git a/src/dialogs/SimplePasswordDlg.h b/src/dialogs/SimplePasswordDlg.h new file mode 100755 index 0000000..616447d --- /dev/null +++ b/src/dialogs/SimplePasswordDlg.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * mail@tarek-saidi.de * + * * + * 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. * + ***************************************************************************/ + +#ifndef _SIMPLEPASSWORDDIALOG_H +#define _SIMPLEPASSWORDDIALOG_H + +#include "ui_SimplePasswordDlg.h" + +class CSimplePasswordDialog : public SimplePasswordDialog +{ + Q_OBJECT + +public: + CSimplePasswordDialog(bool HidePw,QWidget* parent = 0, const char* name = 0, bool modal = FALSE, WFlags fl = 0 ); + ~CSimplePasswordDialog(); + /*$PUBLIC_FUNCTIONS$*/ + +public slots: + /*$PUBLIC_SLOTS$*/ + +protected: + /*$PROTECTED_FUNCTIONS$*/ + +protected slots: + /*$PROTECTED_SLOTS$*/ +public: QString password; + +public slots: + virtual void OnCancel(); +public slots: + virtual void OnOK(); +public slots: + virtual void OnHidePasswordToggled(bool state); +}; + +#endif + diff --git a/src/forms/Qt4 Portierung.notiz b/src/forms/Qt4 Portierung.notiz new file mode 100755 index 0000000..349896c --- /dev/null +++ b/src/forms/Qt4 Portierung.notiz @@ -0,0 +1,2 @@ +Mit QMake 4.x bekommen die vom uic erstellten Header +automatisch den Präfix ui_* - also vor der Portierung entfernen! diff --git a/src/forms/ui_AboutDlg.ui b/src/forms/ui_AboutDlg.ui new file mode 100755 index 0000000..070fe55 --- /dev/null +++ b/src/forms/ui_AboutDlg.ui @@ -0,0 +1,196 @@ + +AboutDlg + + + AboutDlg + + + + 0 + 0 + 419 + 211 + + + + + 0 + 0 + 0 + 0 + + + + + 419 + 211 + + + + + 211 + 32767 + + + + Über... + + + + line1 + + + + 10 + 120 + 400 + 20 + + + + HLine + + + Sunken + + + Horizontal + + + + + Label3 + + + + 10 + 140 + 60 + 20 + + + + Homepage: + + + + + Banner + + + + 0 + 0 + 420 + 50 + + + + image0 + + + true + + + + + Label4 + + + + 10 + 160 + 54 + 20 + + + + EMail: + + + + + ButtonClose + + + + 326 + 183 + 80 + 20 + + + + Schlie&ßen + + + Alt+ß + + + + + Label2 + + + + 10 + 100 + 400 + 20 + + + + Keepass/L steht unter der General Public License. + + + + + Label1 + + + + 10 + 80 + 240 + 20 + + + + Copyright (c) Tarek Saidi 2005 + + + + + Label0 + + + + 10 + 60 + 220 + 20 + + + + Keepass/L Version %1 + + + + + + 789c8597596f23470e80dfe75718c3b7c182e9eabb11ec834fc9873cbeaf601fc86ec9966df994cfc5fef794483633934d10c836fcb9582cde55fee5dbd2d9de68e9db2f5f9ee7349fb64bed153d2d7deb5e66b38fdffef3efff7ef99aa64b8baf2c5b4abffeebcb57dc5c6a9720499290640b8613e110ff22eb941b07657e7256f90be742e4a7c6a9ed076791c7a1732efbd784d3f817615a71167db0e55c0a17ce95c88f8ced3c7e74d6f306cea29fd159f583b3e8a75367d18f5bce8df0b63389be67e3ccfcd97716fd78e22cfaf1d459edefedcbedbc63e75af4cf85b33edeb8616cfef1b5b39eb7e72cf6c28b7166fb53678df7b5b3fadf388b3d503a8b3d40c6b9eaa35767d9cf37c6a5e53f73d6f3769d55bedf5f2789ac6bfcf2de1fda33ce4cdfbb716eeb6fce1acf1de3c2f2bbe7acf573605cdafe2b67f5efd359f20bb97165febe38b3c453fd2bfa7cd0a67165fea97c9db416ff1de3b1e9d77a6d12567bf8c159ed9d1ab7969fc2b8d378e2ba304579c93769bd719457fd524f2184cae221f51bd250a8fd3c35ae4cfec1b8b6fa06e3c6eaffc859d651f215b2d0c7efdab8327b969d459e9e8d7bfd57c68df587c43be4c1e20b685c1b9f0b17c1e283cfce927f96f911ca40d63fcbce7afebd31eb3a91b3fa37376ead9e64dea5759606a94f546eb23499883d9bc69932bef4acf22cf594725c1f8bfca9b3c8d3aa711e82c82bb73de3817111a4fe2171d67e1a1b97ba8e87ce5a8f12bfb48b2cfae8ceb85206894f9666135bff2e5c45d6fae894a3393a3f5be13aaeb7729eca4ff2d6ce3f5b701ef2b1c95f0aa7715dfb4de657519675d0fc8d8c9ba0f527f12faab234fd8fc695f1ab716dfa3f84ebb2089dec5f779678d381711d74beae398b7f540b3751bfd6e39ab1c9033b6bbd07e326687dcb3c2da8ecf47cfa301e9bbe37e389c94b3c0a2edba0f5f361dc194b3c8b36eed77acf9c453fab7f6d95587e6e8d83c957c25dc9668fdc5fc538b2c6e3a6e754e7adcc836252b6a9d69bccffb2ad535d67e98fb2ab538befaab3e8439947e5b84e82f6ffa17165f1bd7096fcc1ccb8b67a981b375a0f20f92d2775b078493dd54c75aaef0de9dfba75167fea2eb2f683dc5771388d753fbe396b7fca7c6b52ea2c5e57ce621fcbfdd26464f1812767ed8f63e3ced665de34c464fe9e1bb3d5b3f45bc3dca67a7fc9fba7697b46a9bf66cc13cb8fcc8b66c2960f3832b6f3988dad1e2828b799c53371d6f9766b9c5b7f4afe286983f5c3aeb3be177ace6c1ecc9cb51f6a678def8a7169f351fca710f5a93d9db3d64febacf9981aa76a2f5e3b6b7d5d1af7f6df3aebfb67e4acf93f72d6f972675cd83c7d77d67cac3bebfdfce9acf7eb87b3c66b665cdabc5feed9f44bfd51caade59395dbc4fc3f33cecc9f9b9e35bf786fdccfffc459e7ffc059eb7fe2acefcfd459df13dbceda5f4367bddffed8affdf0665c243a6f769c351f6367f51f7ad6fcefcf9dd57e72567fd959e3dd3a6bbc3b677daf34ce6affadb3dadbdb57263a5f46ce7adf8e9dd5dededfbe5e2f9cb5de5b678df7bb71a5fa59f767dccf77cd57d6f7136c185b7e79d359f3159cf53df7e8acf19e19f7f57ee5acef9b0d67f5b733b6fa844b63f38f07ceea9fcc3fca5b9bef58199b3dbce5acefa53567bd6fee8c73d54f95b3fa3b34b6fcc3b3b3f6dba1b3f6afe6a788fb6bad9f1f3f08f19b90b18ddff0f3dafefc2fe4bb284948f1b7f1e2e73fca4ff012af708ad77883b77f2f8f33bc8b9aeff1011ff1099f718e2ff88a6ff88e1ff8196da33fc92fe30aaee21aaee3060e70889bb885dbb88323dc8d7a407df941be8dd2dfa3ec5e94dac7033cc4233cc6133cc5333cc78bffb327c18029669863812556d1ef1a9ba8168080a1850ec608daaf30814bb882296ec035dc486426700b33b8837b78c0213cc2133ce367af3f7a93c01c5e700b5ee10d6fe11d093ee01396610556f104d6601d36a2d77abf0da2f41036610bb6b1841d18c12e7c873dd887033884233886133885b318297d3fc558e114cee1021208d1e01432c8a180122aa8e3c5190f2322c63bb507995aea62bc37698c9f34a14bba822d9ad235ddd02dcde80e87744f0f7fc823d1233de1363d634d737aa1577aa3ebf8047ba70ffaa4655aa1555aa375b37f0c298e6923ca0fb0a1212cd3266dd136edd08876e93bedd13e1dd0211d997e88f6031dd3099d624e67744e17f15f8b40296594cb273ef61632aa5ff34515d5d43032707c19449fd6e993db283b8217ee62fc0630fa31bf1cdf037c493bb1724ef98a162d30e56bcae185467cc3b731dfa0f935f919dff13daef1033ff2133fc77d039e73d41da55ff90d268b8afba17ea27d30a18edff9833f7999577895d7a88421aff31b6fc0e04ff5c6314acc031ef2266cc4c7ce036ff12ca66a10ff75d95eacfd2ccf3b0bfd38e651ac93f7d83b77f84e47d1e6f1222e0bf9c5ef3ff7a3f690766f4ffd0490aa85affffbf5cbef985d44a8 + + + + + ButtonClose + clicked() + AboutDlg + OnClose() + + + + OnClose() + + + diff --git a/src/forms/ui_ChangeKeyDlg.ui b/src/forms/ui_ChangeKeyDlg.ui new file mode 100755 index 0000000..3884128 --- /dev/null +++ b/src/forms/ui_ChangeKeyDlg.ui @@ -0,0 +1,345 @@ + +ChangeKeyDialog + + + ChangeKeyDialog + + + + 0 + 0 + 560 + 270 + + + + Hauptschlüssel ändern + + + + Banner + + + + 0 + 0 + 560 + 50 + + + + image0 + + + true + + + + + textLabel1 + + + + 0 + 56 + 450 + 16 + + + + NoFrame + + + Plain + + + Geben Sie das Passwort ein und/oder wählen Sie eine Schlüsseldatei. + + + + + ButtonCancel + + + + 457 + 240 + 90 + 20 + + + + Abb&rechen + + + Alt+R + + + + + ButtonOK + + + + 360 + 240 + 90 + 20 + + + + O&K + + + Alt+K + + + + + groupBox1 + + + + 10 + 80 + 540 + 150 + + + + Schlüssel + + + + textLabel3 + + + + 10 + 90 + 177 + 20 + + + + Schlüsseldatei oder Datenträger: + + + + + textLabel2 + + + + 10 + 30 + 180 + 20 + + + + Passwort: + + + + + textLabel1_2 + + + + 30 + 118 + 300 + 18 + + + + Passwort <b>und</b> Schlüsseldatei verwenden + + + + + Combo_Dirs + + + + 201 + 90 + 240 + 21 + + + + + + Button_Browse + + + + 450 + 90 + 80 + 22 + + + + W&ählen... + + + Alt+ä + + + + + CheckBox_Both + + + + 10 + 120 + 16 + 16 + + + + + + + + + Edit_Password + + + + 200 + 30 + 310 + 20 + + + + + + Edit_Password_2 + + + + 200 + 60 + 310 + 20 + + + + + + ButtonChangeEchoMode + + + + 510 + 30 + 20 + 20 + + + + ... + + + + + textLabel1_3 + + + + 10 + 60 + 180 + 20 + + + + Passwortwiederholung: + + + + + + + 789c8597596f23470e80dfe75718c3b7c182e9eabb11ec834fc9873cbeaf601fc86ec9966df994cfc5fef794483633934d10c836fcb9582cde55fee5dbd2d9de68e9db2f5f9ee7349fb64bed153d2d7deb5e66b38fdffef3efff7ef99aa64b8baf2c5b4abffeebcb57dc5c6a9720499290640b8613e110ff22eb941b07657e7256f90be742e4a7c6a9ed076791c7a1732efbd784d3f817615a71167db0e55c0a17ce95c88f8ced3c7e74d6f306cea29fd159f583b3e8a75367d18f5bce8df0b63389be67e3ccfcd97716fd78e22cfaf1d459edefedcbedbc63e75af4cf85b33edeb8616cfef1b5b39eb7e72cf6c28b7166fb53678df7b5b3fadf388b3d503a8b3d40c6b9eaa35767d9cf37c6a5e53f73d6f3769d55bedf5f2789ac6bfcf2de1fda33ce4cdfbb716eeb6fce1acf1de3c2f2bbe7acf573605cdafe2b67f5efd359f20bb97165febe38b3c453fd2bfa7cd0a67165fea97c9db416ff1de3b1e9d77a6d12567bf8c159ed9d1ab7969fc2b8d378e2ba304579c93769bd719457fd524f2184cae221f51bd250a8fd3c35ae4cfec1b8b6fa06e3c6eaffc859d651f215b2d0c7efdab8327b969d459e9e8d7bfd57c68df587c43be4c1e20b685c1b9f0b17c1e283cfce927f96f911ca40d63fcbce7afebd31eb3a91b3fa37376ead9e64dea5759606a94f546eb23499883d9bc69932bef4acf22cf594725c1f8bfca9b3c8d3aa711e82c82bb73de3817111a4fe2171d67e1a1b97ba8e87ce5a8f12bfb48b2cfae8ceb85206894f9666135bff2e5c45d6fae894a3393a3f5be13aaeb7729eca4ff2d6ce3f5b701ef2b1c95f0aa7715dfb4de657519675d0fc8d8c9ba0f527f12faab234fd8fc695f1ab716dfa3f84ebb2089dec5f779678d381711d74beae398b7f540b3751bfd6e39ab1c9033b6bbd07e326687dcb3c2da8ecf47cfa301e9bbe37e389c94b3c0a2edba0f5f361dc194b3c8b36eed77acf9c453fab7f6d95587e6e8d83c957c25dc9668fdc5fc538b2c6e3a6e754e7adcc836252b6a9d69bccffb2ad535d67e98fb2ab538befaab3e8439947e5b84e82f6ffa17165f1bd7096fcc1ccb8b67a981b375a0f20f92d2775b078493dd54c75aaef0de9dfba75167fea2eb2f683dc5771388d753fbe396b7fca7c6b52ea2c5e57ce621fcbfdd26464f1812767ed8f63e3ced665de34c464fe9e1bb3d5b3f45bc3dca67a7fc9fba7697b46a9bf66cc13cb8fcc8b66c2960f3832b6f3988dad1e2828b799c53371d6f9766b9c5b7f4afe286983f5c3aeb3be177ace6c1ecc9cb51f6a678def8a7169f351fca710f5a93d9db3d64febacf9981aa76a2f5e3b6b7d5d1af7f6df3aebfb67e4acf93f72d6f972675cd83c7d77d67cac3bebfdfce9acf7eb87b3c66b665cdabc5feed9f44bfd51caade59395dbc4fc3f33cecc9f9b9e35bf786fdccfffc459e7ffc059eb7fe2acefcfd459df13dbceda5f4367bddffed8affdf0665c243a6f769c351f6367f51f7ad6fcefcf9dd57e72567fd959e3dd3a6bbc3b677daf34ce6affadb3dadbdb57263a5f46ce7adf8e9dd5dededfbe5e2f9cb5de5b678df7bb71a5fa59f767dccf77cd57d6f7136c185b7e79d359f3159cf53df7e8acf19e19f7f57ee5acef9b0d67f5b733b6fa844b63f38f07ceea9fcc3fca5b9bef58199b3dbce5acefa53567bd6fee8c73d54f95b3fa3b34b6fcc3b3b3f6dba1b3f6afe6a788fb6bad9f1f3f08f19b90b18ddff0f3dafefc2fe4bb284948f1b7f1e2e73fca4ff012af708ad77883b77f2f8f33bc8b9aeff1011ff1099f718e2ff88a6ff88e1ff8196da33fc92fe30aaee21aaee3060e70889bb885dbb88323dc8d7a407df941be8dd2dfa3ec5e94dac7033cc4233cc6133cc5333cc78bffb327c18029669863812556d1ef1a9ba8168080a1850ec608daaf30814bb882296ec035dc486426700b33b8837b78c0213cc2133ce367af3f7a93c01c5e700b5ee10d6fe11d093ee01396610556f104d6601d36a2d77abf0da2f41036610bb6b1841d18c12e7c873dd887033884233886133885b318297d3fc558e114cee1021208d1e01432c8a180122aa8e3c5190f2322c63bb507995aea62bc37698c9f34a14bba822d9ad235ddd02dcde80e87744f0f7fc823d1233de1363d634d737aa1577aa3ebf8047ba70ffaa4655aa1555aa375b37f0c298e6923ca0fb0a1212cd3266dd136edd08876e93bedd13e1dd0211d997e88f6031dd3099d624e67744e17f15f8b40296594cb273ef61632aa5ff34515d5d43032707c19449fd6e993db283b8217ee62fc0630fa31bf1cdf037c493bb1724ef98a162d30e56bcae185467cc3b731dfa0f935f919dff13daef1033ff2133fc77d039e73d41da55ff90d268b8afba17ea27d30a18edff9833f7999577895d7a88421aff31b6fc0e04ff5c6314acc031ef2266cc4c7ce036ff12ca66a10ff75d95eacfd2ccf3b0bfd38e651ac93f7d83b77f84e47d1e6f1222e0bf9c5ef3ff7a3f690766f4ffd0490aa85affffbf5cbef985d44a8 + + + + + ButtonOK + clicked() + ChangeKeyDialog + OnOK() + + + ButtonCancel + clicked() + ChangeKeyDialog + OnCancel() + + + Button_Browse + clicked() + ChangeKeyDialog + OnBrowse() + + + Edit_Password + textChanged(const QString&) + ChangeKeyDialog + OnPasswordChanged(const QString&) + + + Edit_Password_2 + textChanged(const QString&) + ChangeKeyDialog + OnPassword2Changed(const QString&) + + + Combo_Dirs + activated(int) + ChangeKeyDialog + OnComboChanged(int) + + + CheckBox_Both + stateChanged(int) + ChangeKeyDialog + OnCheckBoxChanged(int) + + + ButtonChangeEchoMode + clicked() + ChangeKeyDialog + ChangeEchoMode() + + + + Edit_Password + Edit_Password_2 + Combo_Dirs + Button_Browse + CheckBox_Both + ButtonOK + ButtonCancel + ButtonChangeEchoMode + + + OnOK() + OnCancel() + OnBrowse() + OnSelect() + OnPasswordChanged(const QString& str) + OnPassword2Changed(const QString& str) + OnCheckBoxChanged(int i) + OnComboChanged(int i) + ChangeEchoMode() + + + diff --git a/src/forms/ui_DatabaseSettingsDlg.ui b/src/forms/ui_DatabaseSettingsDlg.ui new file mode 100755 index 0000000..69b5402 --- /dev/null +++ b/src/forms/ui_DatabaseSettingsDlg.ui @@ -0,0 +1,220 @@ + +dbsettingdlg_base + + + dbsettingdlg_base + + + + 0 + 0 + 440 + 213 + + + + + 0 + 0 + 0 + 0 + + + + + 440 + 213 + + + + + 440 + 213 + + + + Datenbankeinstellungen + + + + groupBox1 + + + + 10 + 60 + 420 + 110 + + + + Verschlüsselung + + + + textLabel2 + + + + 10 + 30 + 90 + 20 + + + + Algorithmus: + + + + + pushButton1 + + + + 390 + 0 + 20 + 20 + + + + ? + + + + + + + + ComboAlgo + + + + 109 + 30 + 300 + 21 + + + + + + EditRounds + + + + 180 + 70 + 230 + 21 + + + + + + textLabel3 + + + + 10 + 70 + 150 + 20 + + + + Verschlüsselungsrunden: + + + + + + Banner + + + + 0 + 0 + 440 + 51 + + + + image0 + + + true + + + + + ButtonOK + + + + 210 + 180 + 102 + 23 + + + + O&K + + + Alt+K + + + + + ButtonCancel + + + + 320 + 180 + 102 + 23 + + + + Abbre&chen + + + Alt+C + + + + + + 789c8597596f23470e80dfe75718c3b7c182e9eabb11ec834fc9873cbeaf601fc86ec9966df994cfc5fef794483633934d10c836fcb9582cde55fee5dbd2d9de68e9db2f5f9ee7349fb64bed153d2d7deb5e66b38fdffef3efff7ef99aa64b8baf2c5b4abffeebcb57dc5c6a9720499290640b8613e110ff22eb941b07657e7256f90be742e4a7c6a9ed076791c7a1732efbd784d3f817615a71167db0e55c0a17ce95c88f8ced3c7e74d6f306cea29fd159f583b3e8a75367d18f5bce8df0b63389be67e3ccfcd97716fd78e22cfaf1d459edefedcbedbc63e75af4cf85b33edeb8616cfef1b5b39eb7e72cf6c28b7166fb53678df7b5b3fadf388b3d503a8b3d40c6b9eaa35767d9cf37c6a5e53f73d6f3769d55bedf5f2789ac6bfcf2de1fda33ce4cdfbb716eeb6fce1acf1de3c2f2bbe7acf573605cdafe2b67f5efd359f20bb97165febe38b3c453fd2bfa7cd0a67165fea97c9db416ff1de3b1e9d77a6d12567bf8c159ed9d1ab7969fc2b8d378e2ba304579c93769bd719457fd524f2184cae221f51bd250a8fd3c35ae4cfec1b8b6fa06e3c6eaffc859d651f215b2d0c7efdab8327b969d459e9e8d7bfd57c68df587c43be4c1e20b685c1b9f0b17c1e283cfce927f96f911ca40d63fcbce7afebd31eb3a91b3fa37376ead9e64dea5759606a94f546eb23499883d9bc69932bef4acf22cf594725c1f8bfca9b3c8d3aa711e82c82bb73de3817111a4fe2171d67e1a1b97ba8e87ce5a8f12bfb48b2cfae8ceb85206894f9666135bff2e5c45d6fae894a3393a3f5be13aaeb7729eca4ff2d6ce3f5b701ef2b1c95f0aa7715dfb4de657519675d0fc8d8c9ba0f527f12faab234fd8fc695f1ab716dfa3f84ebb2089dec5f779678d381711d74beae398b7f540b3751bfd6e39ab1c9033b6bbd07e326687dcb3c2da8ecf47cfa301e9bbe37e389c94b3c0a2edba0f5f361dc194b3c8b36eed77acf9c453fab7f6d95587e6e8d83c957c25dc9668fdc5fc538b2c6e3a6e754e7adcc836252b6a9d69bccffb2ad535d67e98fb2ab538befaab3e8439947e5b84e82f6ffa17165f1bd7096fcc1ccb8b67a981b375a0f20f92d2775b078493dd54c75aaef0de9dfba75167fea2eb2f683dc5771388d753fbe396b7fca7c6b52ea2c5e57ce621fcbfdd26464f1812767ed8f63e3ced665de34c464fe9e1bb3d5b3f45bc3dca67a7fc9fba7697b46a9bf66cc13cb8fcc8b66c2960f3832b6f3988dad1e2828b799c53371d6f9766b9c5b7f4afe286983f5c3aeb3be177ace6c1ecc9cb51f6a678def8a7169f351fca710f5a93d9db3d64febacf9981aa76a2f5e3b6b7d5d1af7f6df3aebfb67e4acf93f72d6f972675cd83c7d77d67cac3bebfdfce9acf7eb87b3c66b665cdabc5feed9f44bfd51caade59395dbc4fc3f33cecc9f9b9e35bf786fdccfffc459e7ffc059eb7fe2acefcfd459df13dbceda5f4367bddffed8affdf0665c243a6f769c351f6367f51f7ad6fcefcf9dd57e72567fd959e3dd3a6bbc3b677daf34ce6affadb3dadbdb57263a5f46ce7adf8e9dd5dededfbe5e2f9cb5de5b678df7bb71a5fa59f767dccf77cd57d6f7136c185b7e79d359f3159cf53df7e8acf19e19f7f57ee5acef9b0d67f5b733b6fa844b63f38f07ceea9fcc3fca5b9bef58199b3dbce5acefa53567bd6fee8c73d54f95b3fa3b34b6fcc3b3b3f6dba1b3f6afe6a788fb6bad9f1f3f08f19b90b18ddff0f3dafefc2fe4bb284948f1b7f1e2e73fca4ff012af708ad77883b77f2f8f33bc8b9aeff1011ff1099f718e2ff88a6ff88e1ff8196da33fc92fe30aaee21aaee3060e70889bb885dbb88323dc8d7a407df941be8dd2dfa3ec5e94dac7033cc4233cc6133cc5333cc78bffb327c18029669863812556d1ef1a9ba8168080a1850ec608daaf30814bb882296ec035dc486426700b33b8837b78c0213cc2133ce367af3f7a93c01c5e700b5ee10d6fe11d093ee01396610556f104d6601d36a2d77abf0da2f41036610bb6b1841d18c12e7c873dd887033884233886133885b318297d3fc558e114cee1021208d1e01432c8a180122aa8e3c5190f2322c63bb507995aea62bc37698c9f34a14bba822d9ad235ddd02dcde80e87744f0f7fc823d1233de1363d634d737aa1577aa3ebf8047ba70ffaa4655aa1555aa375b37f0c298e6923ca0fb0a1212cd3266dd136edd08876e93bedd13e1dd0211d997e88f6031dd3099d624e67744e17f15f8b40296594cb273ef61632aa5ff34515d5d43032707c19449fd6e993db283b8217ee62fc0630fa31bf1cdf037c493bb1724ef98a162d30e56bcae185467cc3b731dfa0f935f919dff13daef1033ff2133fc77d039e73d41da55ff90d268b8afba17ea27d30a18edff9833f7999577895d7a88421aff31b6fc0e04ff5c6314acc031ef2266cc4c7ce036ff12ca66a10ff75d95eacfd2ccf3b0bfd38e651ac93f7d83b77f84e47d1e6f1222e0bf9c5ef3ff7a3f690766f4ffd0490aa85affffbf5cbef985d44a8 + + + + + ButtonOK + clicked() + dbsettingdlg_base + OnOK() + + + ButtonCancel + clicked() + dbsettingdlg_base + OnCancel() + + + + ComboAlgo + EditRounds + ButtonOK + ButtonCancel + pushButton1 + + + OnOK() + OnCancel() + + + diff --git a/src/forms/ui_EditEntryDlg.ui b/src/forms/ui_EditEntryDlg.ui new file mode 100755 index 0000000..d922141 --- /dev/null +++ b/src/forms/ui_EditEntryDlg.ui @@ -0,0 +1,712 @@ + +EditEntryDialog + + + EditEntryDialog + + + + 0 + 0 + 493 + 526 + + + + + 1 + 1 + 0 + 0 + + + + + 493 + 526 + + + + + 493 + 526 + + + + Eintrag bearbeiten + + + true + + + + Edit_Title + + + + 111 + 90 + 370 + 21 + + + + + + Edit_Expire_Time + + + + 220 + 410 + 260 + 21 + + + + + + Label_Bits + + + + 400 + 228 + 44 + 14 + + + + 120 Bits + + + + + ButtonDeleteAttachment + + + + 450 + 440 + 31 + 21 + + + + + + + image0 + + + + + ButtonGenPw + + + + 450 + 200 + 31 + 21 + + + + Ge&n. + + + + + Edit_Password_w + + + + 111 + 200 + 330 + 21 + + + + + + Progress_Quali + + + true + + + + 111 + 226 + 280 + 22 + + + + 50 + + + + + Edit_UserName + + + + 111 + 120 + 370 + 21 + + + + + + Edit_Attachment + + + false + + + + 110 + 440 + 280 + 21 + + + + + + Edit_Password + + + + 111 + 180 + 330 + 21 + + + + + + textLabel1 + + + + 400 + 60 + 27 + 21 + + + + Icon: + + + + + ButtonEchoMode + + + + 450 + 180 + 31 + 21 + + + + ... + + + false + + + + + ButtonSaveAttachment + + + + 420 + 440 + 31 + 21 + + + + + + + image1 + + + + + ButtonOpenAttachment + + + + 390 + 440 + 30 + 21 + + + + + + + image2 + + + + + Combo_Group + + + + 110 + 60 + 220 + 21 + + + + + + Combo_IconPicker + + + + 431 + 60 + 50 + 21 + + + + + + textLabel5 + + + + 10 + 120 + 90 + 21 + + + + Benutzername: + + + + + textLabel8 + + + + 10 + 200 + 97 + 21 + + + + Passwort Wdhlg.: + + + + + textLabel4 + + + + 10 + 90 + 90 + 20 + + + + Titel: + + + + + textLabel7 + + + + 10 + 150 + 90 + 21 + + + + URL: + + + + + textLabel6 + + + + 10 + 180 + 100 + 21 + + + + Passwort: + + + + + textLabel9 + + + + 10 + 225 + 90 + 16 + + + + Qualität: + + + + + textLabel10 + + + + 10 + 250 + 100 + 21 + + + + Kommentar: + + + + + Edit_Expire_Date + + + + 110 + 410 + 110 + 21 + + + + 10 + + + + + textLabel11 + + + + 10 + 410 + 100 + 21 + + + + gültig bis: + + + + + textLabel12 + + + + 10 + 440 + 90 + 21 + + + + Anhang: + + + + + Edit_URL + + + + 111 + 150 + 370 + 21 + + + + + + textLabel3 + + + + 10 + 60 + 90 + 21 + + + + Gruppe: + + + + + Banner + + + + 0 + 0 + 493 + 50 + + + + + 7 + 5 + 0 + 0 + + + + true + + + + + line1 + + + + 0 + 476 + 490 + 16 + + + + HLine + + + Sunken + + + Horizontal + + + + + Label_AttachmentSize + + + + 110 + 461 + 120 + 16 + + + + 5,30 MB + + + + + ButtonCancel + + + + 380 + 497 + 104 + 23 + + + + Abbre&chen + + + Alt+C + + + + + ButtonOK + + + + 270 + 497 + 103 + 23 + + + + O&K + + + Alt+K + + + + + Edit_Comment + + + + 111 + 250 + 370 + 151 + + + + + + + 89504e470d0a1a0a0000000d49484452000000100000001008060000001ff3ff61000000a249444154388da553c10d8440081cece03ad0a74fb7246bf35ab00bf79e57c69530be301c82c62c09c926300303ac90448b754d684b50a5b04a79dcce41f0c5ef20ba02f8b8f819684261950c6c63a71968d0574a894986be61e2829efeed3d2550e0868933108249e66bb412862c2993a0952339b7123cf88ee44f82b6ad37e1b733e285b70cf11d58cdd10df8229ad379d08acfd5c85058c57678bac4a7d6fc1b77b26fedbde105cdd30000000049454e44ae426082 + + + 89504e470d0a1a0a0000000d49484452000000100000001008060000001ff3ff610000018049444154388d8d933d4b034110869f88c51e58ec818507165e619172c5346727dad8fa135269fe81a412ff820a622c84945ac6c6fa2c2eb8a5a58d7081087b85982902671192dce5fc7aab6566e7e19d99dd5a9ee714757e715e0ab8cce16b1ff7ee00f0577d5ac7adda34bf5cbcdcbdede6bd871eca5368fd4ab46d0856c1345e01b009f41e2d403e859400006b414ae7c800a6108dc0804d62dcd0e13237cb2c2d02aa8aca2c80f1fc5872202288d4c1447f73ffef602eed6fe1ad78a55865064abd80551317169e89b109c47d4b96851568053048039a9796413a98ad4e440008d6e5f716642c8c3e46d804d2b77456a8b59eb8f3d4df0ebc156f5658172112c1c8135bc021d516be1d625384589ee86001b0953dfe00983e90de6648b3714df7ea93ddfb3bccd11cb0d846750b9ee2604fd36c00ec40667197d0c1e0866eb2c6e55f0000f42dcfdc60fb8638310cd60394a708b526dc08699fb4bfff4c003212ba43cd7d7a80f635c17e40a875a9a8a8dae2773e3b3dcba7d89f8a8afa0278938fbf2fda853f0000000049454e44ae426082 + + + 89504e470d0a1a0a0000000d49484452000000100000001008060000001ff3ff61000000e949444154388da593416ec32010451f56b3e87140cd26d741e2465115247a9c6c9232c7e9a28be902db01ecda51fb25160cff7ffe8cc0a82affc14bbdc9d1356e2e64b3eba0aaa82a9f17ab3dc61a5bcba82a393a752103a9b3f7e4e8562f9ed2552df4e2522bc62d7274a4e0d4c76cda19c8196e3dfdbc9ac0be410a461f0642111f2dce8e69bebfe0f0ba544b02eb91bba95bb896deece9d1ce61f5f2990bd50c32f21b7b810c20c56498ab37e0f8845ac021c8fb073e6a3b44871d49d735699b60c4d09cd8d3ae784e3bc24c7fa17fc65b903bf8581e92a93f530acf994ce285c15f30ec53b6f103005182147f92e4240000000049454e44ae426082 + + + + + ButtonEchoMode + clicked() + EditEntryDialog + ChangeEchoMode() + + + Edit_Password + textChanged(const QString&) + EditEntryDialog + OnPasswordTextChanged(const QString&) + + + Edit_Password_w + textChanged(const QString&) + EditEntryDialog + OnPasswordwTextChanged(const QString&) + + + Edit_Password_w + lostFocus() + EditEntryDialog + OnPasswordwLostFocus() + + + Edit_Expire_Date + lostFocus() + EditEntryDialog + OnExpDateLostFocus() + + + Edit_Expire_Time + lostFocus() + EditEntryDialog + OnExpTimeLostFocus() + + + ButtonOpenAttachment + clicked() + EditEntryDialog + OnNewAttachment() + + + ButtonSaveAttachment + clicked() + EditEntryDialog + OnSaveAttachment() + + + ButtonDeleteAttachment + clicked() + EditEntryDialog + OnDeleteAttachment() + + + ButtonGenPw + clicked() + EditEntryDialog + OnButtonGenPw() + + + ButtonOK + clicked() + EditEntryDialog + OnButtonOK() + + + ButtonCancel + clicked() + EditEntryDialog + OnButtonCancel() + + + + Combo_Group + Combo_IconPicker + Edit_Title + Edit_UserName + Edit_URL + Edit_Password + Edit_Password_w + Edit_Comment + Edit_Expire_Date + Edit_Expire_Time + Edit_Attachment + ButtonOpenAttachment + ButtonSaveAttachment + ButtonDeleteAttachment + ButtonEchoMode + ButtonGenPw + + + OnButtonOK() + OnButtonCancel() + ChangeEchoMode() + OnPasswordTextChanged(const QString&) + OnPasswordwTextChanged(const QString&) + OnPasswordwLostFocus() + OnExpDateLostFocus() + OnExpTimeLostFocus() + OnNewAttachment() + OnSaveAttachment() + OnDeleteAttachment() + OnButtonGenPw() + + + diff --git a/src/forms/ui_EditGroupDlg.ui b/src/forms/ui_EditGroupDlg.ui new file mode 100755 index 0000000..f532e9d --- /dev/null +++ b/src/forms/ui_EditGroupDlg.ui @@ -0,0 +1,174 @@ + +EditGroupDialog + + + EditGroupDialog + + + + 0 + 0 + 302 + 105 + + + + + 200 + 105 + + + + + 302 + 100 + + + + Gruppeneigenschaften + + + + line1 + + + + 10 + 62 + 290 + 16 + + + + HLine + + + Sunken + + + Horizontal + + + + + EditTitle + + + + 70 + 10 + 230 + 21 + + + + + + Label1 + + + + 10 + 10 + 27 + 20 + + + + Titel: + + + + + Label2 + + + + 10 + 40 + 43 + 20 + + + + Symbol: + + + + + ComboIconPicker + + + + 70 + 40 + 50 + 21 + + + + + + ButtonCancel + + + + 226 + 80 + 70 + 20 + + + + Abbre&chen + + + Alt+C + + + + + ButtonOK + + + + 147 + 80 + 70 + 20 + + + + O&K + + + Alt+K + + + + + + ButtonOK + clicked() + EditGroupDialog + OnOK() + + + ButtonCancel + clicked() + EditGroupDialog + OnCancel() + + + + EditTitle + ComboIconPicker + ButtonOK + ButtonCancel + + + OnOK() + OnCancel() + + + diff --git a/src/forms/ui_LanguageDlg.ui b/src/forms/ui_LanguageDlg.ui new file mode 100755 index 0000000..612053e --- /dev/null +++ b/src/forms/ui_LanguageDlg.ui @@ -0,0 +1,215 @@ + +LanguageDlg + + + LanguageDlg + + + + 0 + 0 + 500 + 252 + + + + + 0 + 0 + 0 + 0 + + + + + 500 + 252 + + + + + 500 + 252 + + + + Keepass + + + false + + + + Banner + + + + 0 + 0 + 500 + 50 + + + + image0 + + + true + + + + + ButtonClose + + + + 407 + 220 + 80 + 23 + + + + Schlie&ßen + + + Alt+ß + + + + + + * + + + true + + + true + + + + + Sprache + + + true + + + true + + + + + Version + + + true + + + true + + + + + Autor + + + true + + + true + + + + List + + + + 10 + 60 + 480 + 150 + + + + true + + + true + + + NoColumn + + + + + ButtonApply + + + + 20 + 220 + 80 + 23 + + + + Fes&tlegen + + + Alt+T + + + + + + Legt die aktuell markierte Sprache +als Übersetzung für Keepass fest. + + + + + + 789c8597596f23470e80dfe75718c3b7c182e9eabb11ec834fc9873cbeaf601fc86ec9966df994cfc5fef794483633934d10c836fcb9582cde55fee5dbd2d9de68e9db2f5f9ee7349fb64bed153d2d7deb5e66b38fdffef3efff7ef99aa64b8baf2c5b4abffeebcb57dc5c6a9720499290640b8613e110ff22eb941b07657e7256f90be742e4a7c6a9ed076791c7a1732efbd784d3f817615a71167db0e55c0a17ce95c88f8ced3c7e74d6f306cea29fd159f583b3e8a75367d18f5bce8df0b63389be67e3ccfcd97716fd78e22cfaf1d459edefedcbedbc63e75af4cf85b33edeb8616cfef1b5b39eb7e72cf6c28b7166fb53678df7b5b3fadf388b3d503a8b3d40c6b9eaa35767d9cf37c6a5e53f73d6f3769d55bedf5f2789ac6bfcf2de1fda33ce4cdfbb716eeb6fce1acf1de3c2f2bbe7acf573605cdafe2b67f5efd359f20bb97165febe38b3c453fd2bfa7cd0a67165fea97c9db416ff1de3b1e9d77a6d12567bf8c159ed9d1ab7969fc2b8d378e2ba304579c93769bd719457fd524f2184cae221f51bd250a8fd3c35ae4cfec1b8b6fa06e3c6eaffc859d651f215b2d0c7efdab8327b969d459e9e8d7bfd57c68df587c43be4c1e20b685c1b9f0b17c1e283cfce927f96f911ca40d63fcbce7afebd31eb3a91b3fa37376ead9e64dea5759606a94f546eb23499883d9bc69932bef4acf22cf594725c1f8bfca9b3c8d3aa711e82c82bb73de3817111a4fe2171d67e1a1b97ba8e87ce5a8f12bfb48b2cfae8ceb85206894f9666135bff2e5c45d6fae894a3393a3f5be13aaeb7729eca4ff2d6ce3f5b701ef2b1c95f0aa7715dfb4de657519675d0fc8d8c9ba0f527f12faab234fd8fc695f1ab716dfa3f84ebb2089dec5f779678d381711d74beae398b7f540b3751bfd6e39ab1c9033b6bbd07e326687dcb3c2da8ecf47cfa301e9bbe37e389c94b3c0a2edba0f5f361dc194b3c8b36eed77acf9c453fab7f6d95587e6e8d83c957c25dc9668fdc5fc538b2c6e3a6e754e7adcc836252b6a9d69bccffb2ad535d67e98fb2ab538befaab3e8439947e5b84e82f6ffa17165f1bd7096fcc1ccb8b67a981b375a0f20f92d2775b078493dd54c75aaef0de9dfba75167fea2eb2f683dc5771388d753fbe396b7fca7c6b52ea2c5e57ce621fcbfdd26464f1812767ed8f63e3ced665de34c464fe9e1bb3d5b3f45bc3dca67a7fc9fba7697b46a9bf66cc13cb8fcc8b66c2960f3832b6f3988dad1e2828b799c53371d6f9766b9c5b7f4afe286983f5c3aeb3be177ace6c1ecc9cb51f6a678def8a7169f351fca710f5a93d9db3d64febacf9981aa76a2f5e3b6b7d5d1af7f6df3aebfb67e4acf93f72d6f972675cd83c7d77d67cac3bebfdfce9acf7eb87b3c66b665cdabc5feed9f44bfd51caade59395dbc4fc3f33cecc9f9b9e35bf786fdccfffc459e7ffc059eb7fe2acefcfd459df13dbceda5f4367bddffed8affdf0665c243a6f769c351f6367f51f7ad6fcefcf9dd57e72567fd959e3dd3a6bbc3b677daf34ce6affadb3dadbdb57263a5f46ce7adf8e9dd5dededfbe5e2f9cb5de5b678df7bb71a5fa59f767dccf77cd57d6f7136c185b7e79d359f3159cf53df7e8acf19e19f7f57ee5acef9b0d67f5b733b6fa844b63f38f07ceea9fcc3fca5b9bef58199b3dbce5acefa53567bd6fee8c73d54f95b3fa3b34b6fcc3b3b3f6dba1b3f6afe6a788fb6bad9f1f3f08f19b90b18ddff0f3dafefc2fe4bb284948f1b7f1e2e73fca4ff012af708ad77883b77f2f8f33bc8b9aeff1011ff1099f718e2ff88a6ff88e1ff8196da33fc92fe30aaee21aaee3060e70889bb885dbb88323dc8d7a407df941be8dd2dfa3ec5e94dac7033cc4233cc6133cc5333cc78bffb327c18029669863812556d1ef1a9ba8168080a1850ec608daaf30814bb882296ec035dc486426700b33b8837b78c0213cc2133ce367af3f7a93c01c5e700b5ee10d6fe11d093ee01396610556f104d6601d36a2d77abf0da2f41036610bb6b1841d18c12e7c873dd887033884233886133885b318297d3fc558e114cee1021208d1e01432c8a180122aa8e3c5190f2322c63bb507995aea62bc37698c9f34a14bba822d9ad235ddd02dcde80e87744f0f7fc823d1233de1363d634d737aa1577aa3ebf8047ba70ffaa4655aa1555aa375b37f0c298e6923ca0fb0a1212cd3266dd136edd08876e93bedd13e1dd0211d997e88f6031dd3099d624e67744e17f15f8b40296594cb273ef61632aa5ff34515d5d43032707c19449fd6e993db283b8217ee62fc0630fa31bf1cdf037c493bb1724ef98a162d30e56bcae185467cc3b731dfa0f935f919dff13daef1033ff2133fc77d039e73d41da55ff90d268b8afba17ea27d30a18edff9833f7999577895d7a88421aff31b6fc0e04ff5c6314acc031ef2266cc4c7ce036ff12ca66a10ff75d95eacfd2ccf3b0bfd38e651ac93f7d83b77f84e47d1e6f1222e0bf9c5ef3ff7a3f690766f4ffd0490aa85affffbf5cbef985d44a8 + + + + + List + doubleClicked(QListViewItem*) + LanguageDlg + OnItemDoubleClicked(QListViewItem*) + + + List + rightButtonClicked(QListViewItem*,const QPoint&,int) + LanguageDlg + OnItemRightClick(QListViewItem*,const QPoint&) + + + ButtonApply + clicked() + LanguageDlg + OnApplyButtonClicked() + + + ButtonClose + clicked() + LanguageDlg + OnButtonCloseClicked() + + + + List + ButtonApply + ButtonClose + + + OnItemRightClick(QListViewItem* item, const QPoint& p) + OnItemDoubleClicked(QListViewItem* item) + OnApplyButtonClicked() + OnButtonCloseClicked() + + + diff --git a/src/forms/ui_MainWindow.ui b/src/forms/ui_MainWindow.ui new file mode 100755 index 0000000..2c8b245 --- /dev/null +++ b/src/forms/ui_MainWindow.ui @@ -0,0 +1,1535 @@ + +MainFrame + + + MainFrame + + + + 0 + 0 + 780 + 450 + + + + + 5 + 5 + 0 + 0 + + + + + 206 + 236 + + + + + 0 + 0 + + + + + 800 + 450 + + + + Form1 + + + image0 + + + Neue Datenbank + + + + unnamed + + + + layout2 + + + + unnamed + + + 0 + + + + splitter + + + + 7 + 7 + 0 + 0 + + + + + 182 + 60 + + + + Horizontal + + + + GroupView + + + + 7 + 7 + 23 + 0 + + + + + 0 + 0 + + + + + 32767 + 32767 + + + + true + + + Manual + + + false + + + true + + + LastColumn + + + + + EntryView + + + + 7 + 7 + 100 + 0 + + + + + 0 + 0 + + + + Manual + + + true + + + true + + + AllColumns + + + + + + SummaryField + + + true + + + + 1 + 7 + 0 + 0 + + + + + 0 + 0 + + + + + 32767 + 50 + + + + Manual + + + true + + + false + + + + + + + + + menubar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Toolbar + + + Toolbar + + + + toolButtonNew + + + + + + image1 + + + neue Datenbank + + + + + tooButtonOpen + + + + + + image2 + + + Datenbank öffnen + + + + + toolButtonSave + + + true + + + + + + image3 + + + Datenbank speichern + + + + + + toolButtonAddEntry + + + + + + image4 + + + Eintrag hinzufügen + + + + + toolButtonEditEntry + + + + + + image5 + + + Eintrag bearbeiten + + + + + toolButtonDeleteEntry + + + + + + image6 + + + Eintrag löschen + + + + + + toolButtonUserNameToClipboard + + + + + + image7 + + + Benutzername in Zwischenablage kopieren + + + + + toolButtonPasswordToClipboard + + + + + + image8 + + + Passwort in Zwischenablage kopieren + + + + + + toolButtonSearch + + + + + + image9 + + + in Datenbank suchen + + + + + + toolButtonLockUI + + + + + + image10 + + + < PLATZHALTER > + + + + + + toolButtonAbout + + + + + + image11 + + + Hilfe anzeigen + + + + + toolSearch + + + Schnellsuche + + + + + + + + + File_Exit + + + Beenden + + + Beenden + + + + + File_New + + + &Neue Datenbank... + + + &Neue Datenbank... + + + + + File_Open + + + &Datenbank öffnen... + + + &Datenbank öffnen... + + + + + File_Close + + + Datenbank &schließen + + + Datenbank &schließen + + + + + File_Save + + + Datenbank s&peichern + + + Datenbank s&peichern + + + + + File_SaveAs + + + Datenbank speichern unter... + + + Datenbank speichern unter... + + + + + File_Settings + + + Datenbank-Einstellungen... + + + Datenbank-Einstellungen... + + + + + File_ChangeKey + + + Hauptschlüssel ändern... + + + Hauptschlüssel ändern... + + + + + Edit_NewGroup + + + &Neue Gruppe erstellen... + + + &Neue Gruppe erstellen... + + + + + Edit_NewSubGroup + + + Neue &Untergruppe ertellen... + + + Neue &Untergruppe ertellen... + + + + + Edit_GroupProperties + + + Gruppe &bearbeiten... + + + Gruppe &bearbeiten... + + + + + Edit_DeleteGroup + + + Gruppe &löschen + + + Gruppe &löschen + + + + + Edit_PasswordToClipboard + + + &Passwort in Zwischenablage kopieren + + + &Passwort in Zwischenablage kopieren + + + + + Edit_UserNameToClipboard + + + Ben&utzername in Zwischenablage kopieren + + + Ben&utzername in Zwischenablage kopieren + + + + + Edit_OpenURL + + + U&RL öffnen + + + U&RL öffnen + + + + + Edit_SaveAttachment + + + &Anhang speichern unter... + + + &Anhang speichern unter... + + + + + Edit_AddEntry + + + Eintrag &hinzufügen... + + + Eintrag &hinzufügen... + + + + + Edit_EditEntry + + + Eintrag bearbeiten/&anzeigen... + + + Eintrag bearbeiten/&anzeigen... + + + + + Edit_CopyEntry + + + Eintrag &duplizieren + + + Eintrag &duplizieren + + + + + Edit_DeleteEntry + + + Eintrag l&öschen + + + Eintrag l&öschen + + + + + Edit_GlobalSearch + + + In Datenbank &suchen... + + + In Datenbank &suchen... + + + + + Edit_GroupSearch + + + In dieser Gru&ppe suchen... + + + In dieser Gru&ppe suchen... + + + + + View_ShowToolBar + + + true + + + &Toolbar anzeigen + + + &Toolbar anzeigen + + + + + View_ShowEntryDetails + + + true + + + false + + + Eintragsansicht anzeigen + + + Eintragsansicht anzeigen + + + + + Extras_Settings + + + Einstellungen... + + + Einstellungen... + + + + + Help_About + + + Über Keepass... + + + Über Keepass... + + + + + View_Columns + + + Spalten + + + Spalten + + + + + View_Column_Title + + + true + + + Titel + + + Titel + + + + + View_Column_Username + + + true + + + Benutzername + + + Benutzername + + + + + View_Column_URL + + + true + + + URL + + + URL + + + + + View_Column_Password + + + true + + + Passwort + + + Passwort + + + + + View_Column_Comment + + + true + + + Kommentar + + + Kommentar + + + + + View_Column_Expire + + + true + + + Ablaufdatum + + + Ablaufdatum + + + + + View_Column_LastAccess + + + true + + + Letzter Zugriff + + + Letzter Zugriff + + + + + View_Column_LastMod + + + true + + + Letzte Änderung + + + Letzte Änderung + + + + + View_Column_Creation + + + true + + + Erstellungsdatum + + + Erstellungsdatum + + + + + View_Column_Attachment + + + true + + + Anhang + + + Anhang + + + + + Action + + + Unnamed + + + + + Extras_Language + + + Sprache... + + + Sprache... + + + + + hilfeDEBUGAction + + + DEBUG + + + DEBUG + + + + + DEBUG_DbStructure + + + Datenbankstruktur + + + Datenbankstruktur + + + + + dateiImportieren_ausAction + + + Importieren aus + + + Importieren aus + + + + + File_Import_PwManager + + + PwManager-Datei (*.pwm)... + + + PwManager-Datei (*.pwm)... + + + + + hilfeAction + + + + + + + + + + + Action_2 + + + Unnamed + + + + + Action_3 + + + Unnamed + + + + + hilfeAction_2 + + + + + + + + + + + hilfeDokumentationAction + + + false + + + Dokumentation... + + + Dokumentation... + + + + + Action_4 + + + Unnamed + + + + + View_HidePasswords + + + true + + + Passwörter verbergen + + + Passwörter verbergen + + + + + View_HideUsernames + + + true + + + Benutzernamen verbergen + + + Benutzernamen verbergen + + + + + File_ImportKWalletXML + + + KWallet XML-Datei (*.xml)... + + + KWallet XML-Datei (*.xml)... + + + + + Help_AboutQt + + + Über QT... + + + Über QT... + + + + + + 89504e470d0a1a0a0000000d49484452000001000000010008060000005c72a8660000200049444154789cecbd79bc5d557937fe5de7de9bdc0c642090811002842440002180ccc8248332285ac5be4eb5b6b6d5b755aa1da87d7db5b5d6da9f1d6cdf4f075b2d5571a48a03208a2828f33c43c29084cc842464bcf79cfdfcfed8eb99d6dee79cbdcfbd21a0599f9cdc3dacf159cff35dcf7ad6b3d60ed8135ee9613680fd00cc023013c0bef1b777fc4d063009c04400e3018c033016c00080be98470bc030809d00b603d806600b80cd003601d8107febe26f358055005602786e17b76f4fd88521ecee0aec0995c2be00e6033804c03c0007013810c05c0007ecbe6a010096017816c033009e06b014c012004f22078b3de1651cf600c0cb2fcc0270248023001c0ee0300087221fcd5f49610380c7003c0ae011000f017810b9e6b027bc4cc21e00d8fd612180c5f17774fcedb35b6bb4ebc27a00f7c5df3df1f7f86eadd1af78d803002f7d9805e084f87b3580e301ecb55b6bb4fbc28b00ee04700780dbe36f8f86f012863d00f0d28423019c0ae0140027239fc3ef09c5f034805f00f839805b904f19f6845d18f600c0ae0bc7003803c06be26fca6eadcd2b2f6c04f0d3f8bb09c0bdbbb536bfa4610f008c6e5800e06c00e700380b7b847eb4c246003702f811801f037862f756e79727ec018091870900ce07702e80f3902fcded09bb2e3c0be07a003f04701d80adbbb73aafecb007007a0f4702783d800b009cbe9bebf2ab1a7e06e05a00dfc71e7b414f610f00d40fe701b828fe76b713ce9e90876500be1b7fd7efe6baec09bf84611c805f07f035e4eeb2b4e7f7b2fced8c7df4ebb1cff6842ea1b6064044bba21e2fcb1042d81bc0a500de847c9eff8a09e79f7fc19a37bcf1d231af3aea55833367cd1c983071afc6b8c1c1d0d7d7171a8d0642080821ef7e220211a1956568355bb47dfb76dab2754bb67ad5eae1071eb87fc777be7df5d075d75d3b633737a96eb80ec0b7005c4d441b7677655eaac07d5a397edd027e1500200afe5b00bc19b955ff65198e3966f19a8f7ce48f06171f7bdcb8e933a6f78f1b1c6cf4f5f521848076dd446d6f3ac493878466ab85eddb77646bd7ac69de73cfdddbffbfbffdf48efbeebbf7e50c0e3f06f04d005fff5500823d00308210429800e0b2f83b673757c78533cf3c6bcd9f7df4cf271e71c4a2c1499326f70df40ff8dea38ef26ca3e5ff05141214d29764983ecab3210c0f37b169d3a6d6c30f3fb4e3537ff5175b7e7ad34f5e6ea0f023005f05f05522faa55d39d803003d8610c26500de06e0e2dd5d1700f8c30f7f78dd6ffcc67b261d3077ee98c1b183a11142a98013805041f83b09be8bd3e561db724c1d4220641961e78e9df4ccb26787aefce27f6efefbbffbdb7dbb54f1a50ad700b88a88bebabb2bb22bc21e00a8194208af05f0f6f86becae7a9c79e6596b3ef399cf4c5eb060e1d871e3c7858006a8c2982e82dde1bd93f9aac25f61f497e71dab99d78088b06ddb367ae28927765ef1271fdef4d39fee560d2103f025005f22a21b76633d463dec01808a2184b008c03be36fe6eea8c3273ff9a9e7dff1ce774c9e317d467f5f7f9f4858250a5788db4de8dbbeee61d46f976bce2e0c41f9df108066b385d56bd634affaf27f6ffad8ffb9625ae71aeeb2b01ac09500ae24a28777531d4635ec01802e21cef3df1d7fc7bdd4e5ffc33ffce386b7bef5b2c97b4fdbbbafd148148e8af3f8aa40d14d3b70af593eabd6a3abf0875c83e9a2490400ad2cc386f5cfb7bef18daf6dfac887ff60779c7b7017802f02f8e22bdd3eb007003a8410c2b900de03e0ad2f65b91fbafcf2f5977fe8f2293366ccec6ff4f5e90bf20a7a25235e45f28f54e5ef34eab77fcf821fafdde8dfbd5c068355ab5737ffe91fff6ee3e7fef1b32ff5b9085f03f09f44f4c397b8dc510b7b00a0248410f603f0def89bf35294397dfaf48dd75fffc3c1430f3b6cec98818150caf82108085499efd7b2f4bb8b92771d5ef426fcfcc62e418a5910a520d701740280a1a1217af4b1c776bee1a2f376ac5bb7f6a5da58b51cc0e7017c9e8856be44658e5ad803004908215c04e0b7015cf85294f7c9bffad4f3ef7bdffba64e993ca581909adca3c01b551ba826d45584bfca9cbf9ba5bfbef0fbb94327f6e8e68350988e4899848d1b3766fff1f97f7de1e31ffbb397ca5ef03d00ff4644df7d89ca1b95b007006208214c07f03bf1376b5797f7939b6eda7ae209278e1f33664c2067f4029cf4c8a83ff2d1bc6edc820026f8d4ebc84f200432aa7f95b2dbdfb62d330460e7ce21bafdf6dbb6bdfefc3327b4abee28865500fe05c0bf10d1da97a0bc11873d00002084701680df43eec2bbcbc2d4a95337df7aeb6d83071f3c6f4c9fcced0954206b77635869d815c6be360f3aae26b44d1c12d029a24a6d50ea52170ead560b4b972e1d3ae7cc93776cdcf8c2a40a494612be05e0ff11d18dbbb89c11875f79000821bc1fc007909fa4bb4bc2a2458bd67dff07d74e993d7bf64023a8259f9c00b477b5ab4ac12aa4aeabf61301ad16a19501ad56feaeaf01f4f5017d8d8050637ad2c9d85748db0d007bd4448832ac58f1dcf09b2f7dfdc6c71e7d78573a1b3d06e09f88e89f776119230ebfb2001042980fe07fc7df2e098b162d5a77ddf5d74f9d356b567f40809bfbe6b540d1f0e526b3a336df073a0bff7093d0cc802ccb053e23a095115a2d35d47132e2d50822341a21ff0542a32fa0bf01f4f7058c1948da4301d4c605b193b6d1b381b1c3fb5cf920ac5cb9aa79e91bce7f611703c1e7007c8e889edc8565f41c7e25012084701e80df07f0ba5d91fff4e9d337de7ec71d13e6ec3f672004bb761f85a96cbe8fe26d65e1efe0ae5bc88ba2b0b78066464ee0d9030fc847fe3c5f027101314e06762756231e598123426804f43742d4148031030d0c8ee95eb7b6ef4a1ed49b86b42b2bc3b2652b86cf3ee384adbb70e5e00700fe91885e76670ffcca014008e1b7017c10f90734463d3cf2c8a33be72f983fb611fa4adea666afc493261afc4653e56f6540b34568b580662b5f37cfb228dc194046e3e06979f95f030c30db82257d048a185f0181e459230003fd01fd7d01030301e3c6e4009110a5ec7674b402d3c6346494e1c9279ed879c2718bc676483e92f02880bf27a27fdb45f9f7147e650020843005c0e5f137ea16e11b6ef8d1d6d34f3f7d427fff8079aa237d2e2a76838ee5e87ace3d1cb19d7a3bdccc05be9501cd262113358105580187480554059ef2119eb709474127cac53d0320da82d50082f637396d22288824f51ed31f3030008c1d6860c2b8d04e2f1a9170bbc71d8186d06c3671cbcd3fdbfac68bcfdd15ab065b017c16c0678968e32ec8bf76f895008010c2a1003e0ce037473bef8f7ffc13ebfff00fff70dab871e3dbd0c6cef7f599dc1befbeca23bffc97872c03865b710e1f0d763a1273c46046e6288866fa908efa10f51f527f010bd11e7c7dec5f624d86d4c5d7b68f81487cff89d0d7d7c0980160ec40c0f8710163fa8329a070e969d28178d5a6180a9221005bb76da5cffdc3679fffebbffabfbbc2bbf03f00fc2d113db60bf2ae157ee9012084701a808f203f936fd4c2f4e9d337de7bdffd1367ce98d19fabeef6ad8e82fe45d9427a75e1679f200290511ce99b409305554663be086664f71a463eb2ab47a18cf4e67010cdc7a6f369d2b9bf078b207604896f32248ac6c560002952240460ec9880c1a819e446c532a2b83fed5e7719f9a501ee5d00b06af5eae66b4e59bc6517d807be0be0334474f328e75b2bfc52034008e112007f0ce0a4d1ccf7c61b7fb2f5b4d34e9b90fbe99b61b4843ce4d84947fb4a735a9f512ef4ad28f499199dc9f1af8ef446e8295af203bce18e44e73623b6cb37d6d9d826386bdbb5620f6057e5f832230f7b1acf0382d81692f4044223040c8e6960702c30694203fd7dc194db965c6d895b14fe14b03d5067ad166ef9f92d5bdf70e1d9a33d2db815c0a789e83ba39c6fe5f04b0b0021847701f8138ce2fafe79e79db7e66b5ffbfabe7b4d9ad4683b498daab68eeb254b7d35e7fc43cdb816df22645940165955d46d44ed2058c134063a8af37623f848d23bb0107b81d500f2915f80210a76c66909517bd061dc6b088a369949cfcf290118061c352ce6ed19e803c68d0d183fd8c0a409e5c73158302c7bab8e578c401db4b018a5d108d8b46973f69e77be75dd8d37fe7034cf26780cc05f13d17f8d629e95c32f250084103e00e04f01ec375a79de7adb6ddb8e3feeb8f1a111cdd6edb805a98bab5fd74f63b70b32af6fe5c2ef84d524761a006004894751337a933ecff332024e010876c92f681c2e5bd142340a2e53066f072a925532e21b904ad3707ea69e6576042260fcd880c1b10d4c9ed8c0d80136b6b6272cd9ab425f14a76765d95096e1aebbefda76fe39278f2f2fa5a7b012c0a788e89f4631cf4ae1970e0042081f01f05100a3e2ee79c20927acbdfefa1feeb3d7a449f970d3a139e5237e4c54451545be54970b7d862cb342184729ab40181028aae3c9fba44016464dc702161c88b021b02c9f82c59ff47d312e5c5b44c8192e296d43a2092000193930e14af5f5074c180cd86b7c037b8defa015c895dd5fd1c689a20d0000b9a6b569d3e6eccd6fb860fddd77df3ebd4db4ba613380bf24a2cf8c527e95c22f150084103e0ae0cf01b47139a917aebbeefa2d679f7df644bf27bf3cae9febb78948ed55cde1a8e60fb778f435a3b3cd2d1128be16018ebc1dc47b4f23ba69404c688d7a5c475d36cc9f672e0d1745ae0e4840c0e7af1525ab9170dd4dbd491e429c93241d97e9e285188f8000ec35ae0f13c6054c9ba47de6e8ed0679db67946243dbc0efb32cc34f6efcd196b7bef975133ba7a81c8600fc0511fde528e5d735fc52004008a10fc0ff89bf5109cfad5cd59c397346bf2ed795c7eb68bf4f1582926cd42bcf78d741a54118df241601cbb806bace2e459ab42294224866f4e6f9be8957a63928c804c92b1dc10b237f3aeac36fffcdac2dc40976ac11b7c119334dbe5c0641a62f0c7a13c7e5dac03e531a39454cc3daf65887515fda9884108095ab56378f3c74fffe0e49eb864f00f80411b54631cfd250170076db2198ed4214fe8f619484ff031ff8c0daeddbb7d3cc9933bb0abfa945f203d4bc5e4ee0e126b0632761e710e2ba3d1961b223270f4b2a2032170fb980c8121e8c912da6f5aabe8ea2ce0f41242faf3f672f6a3969d48ceb67c8c2f1327e66eb6a01c8b45f35048032f7d45ca9b620d5e43a89af03693b4d655fdc9661e5ba2696ac6862ed0bcdd23e70a1e2a89f868c80993367f6af58b395def35bef1fad2dc0ff07c0c7226fbfacc2cb4e0308217c1ca324fc37dd74d3d6534f3d6d42e0b3f7dc086e6ff4af1f5392f97fd2764254f53342b3654660978478a0f5c267aa21a331cc08c99b6d503e1a8bc059a13200a7f379adac58f8c5e0a7e051ba0fc0fcb5f9e47113cd43ea63c8247e01507080c993df659cb5d5124c7e528e1a2a278c0b9834a181e953cb65aa1d9b1a52179f2737840c3fbfe596ad6fbce8acd15a2efc04117d6c94f22a0dafe829409cf3ffc568e4b56cd9f2e6ecfd8d1a57906916fcfcda2d25d9e040431f35c5a29f08233c8d84e133cdc72ea1115104071dc179890e08a0cc9bb5d4b8a60221bbf20c4858a39a8edc3e5f44272176092eda21f819f9bc0c888976e004d9e6a52b11629fa0b2f7164c4aec0fce5331b685087b4d6860cac4be3835d03ab60b65ec5b26fc1c420358be7c45f398230e1cad29c19fef4a9bc02b1600a2b5ff2f314283dfc2850b9fbff3cebba64e9838d14f6f0ad52e1bf94b22266bfcf9669c1c002cb389da1e78ee6f4766cd56465e16726754d33cd2f932a72593871d1189084f3fb5048f3ff6109e5af238962f7f06ab563e871736acc7962d9bcb9bdf264c98380953f79e861933f7c7ecfde7e2c0831760fefc4538e0a0050501d6f6d836aaa1cffa03006a802c6812ac81244056001da6b9e49b973175af3eec3d295f422c0d6d80810a17c57701c08b5bb664e79e75c20b4b9e7c7ca447920d01f8e8ae5a1d784502405ce7ff2446b8d477c51557acfbd8c7feefbefd0303c91b1d71dd33f9bfccb9c7c7ce5d7573753f332a6b1e2ff8d10b108ef50061f044d4f73c964e9bad51ced4d4323e0114bd849e797a296ebfed66dc73d76db8ffde3bb16d5bfd53ad3b09018771e327e088a38ec351479f88638f3f1573e6cef300201b84942e7603918cf444c84453b2690da05aa1179ab15150e9eaa72a84febe06a6ecd5c08cbdfb303846fbbbe374a04ddbcb0073b8398cbff9d427d6fdc3df7d6aa4e70d6c06f067bbc24fe0150700d1c3efaf3042279fabafbe7af3c5175f3229d8b3f6db8efa7ce7b50027f8061386a3ab6ecb58c594b98349a64c6c85ca5683e2e67baf6e1bf55f31c518d3e00006203c70ff3df8d94f6ec0cf7e7a0356af5ad196c9ab043b7a5709d367cec649a79c83934e7b2d0e3b7c71892660962cf95d14641dc1ad60aa703bc044d16e00442d82851f88d3039d828d1f6c60eac48059fbf6b76d573be12f8d6eca22caf0fdef5db3f937dff5e691faa5ac0470c5687b0cbea20020faf6ff3546e8de7be79d776e5fbcf8d871b08d2ff47028dc1596fcdc6d402b23f1d5d7953c7f00a65d17f7aa293c9322176819cdcce8ef96ee908e6c3edfa7962ec10fafbb06375c770dd6ad5bede2f512aa8cfeeda24cdb6706ce38fb229c71cec59873c03cc8b4a7648990c152d6f881249edd6eec8144bd12ad51902f3ce0b2ed202360eaa43eec3ba50f53f7ea301bac30f2a7cf020877df73f7f60bce39715c3b5a550c8f01f893d1dc3bf08a0180b8abefd318e1c69e254b960e1d74f041630a4d690be55dcee08f1d3edccce7f9454bb857556599cd70aa1db1186c327e6fe28a41ce487a417b302070cdff7c0ddfbbe69b78ecd1077c337be8925ed2b58b7ec88223f1da0bde84732ff8b592b93ab7c90a7afe82c8d78305bb4ce8f37c8ace430204c1f455a6dac698fe80bd27f7e18019fd6884a40d1546fe766d0e0158baf4a9a1938e5b305227b55b01fcf168ed227c450040dccfff3718e196de95ab563567ce98d9df1ed1f986c7fb90bcb36a7f7eddcc80563c4fcf8dce44318a31bc09a0c08cea0213316b339a992aa9653d99d7c6b242dc7a4b043cf3f4525cfd8d2fe1db577f456bff128dfa95a2c508e75f78192eb8f8d7b1ff9c79aa921b2d47560b280556ab05f1fb92958318816c3cb762600082e3c6eb29131bd8776a1ff699d257daa02a237ffaae11f2edc5af3a7cc44e43df05f047a3719ec0cb1e00e2493e7f8b111ee6b17efdfad6de7b4feb73cc9c2cd7e94323700510d0cb2167e4e3d159055d54d0d405985559403ed5edec03f9713cfa2cbe779a02f9ea33e3def68b9bf0f5abaec45d77febc58eb1ebba24e1756157e0e472d3e0917bee19d587cfce971ae4e668930184da8c42f205e14f6224069644180f35050500096b20dbd07061ad867721f0e9a555c1db637a5acc46fecaa0d082104ac5fff7c6bd182192375f2f90f001f1ee9c94275016034dd1dab86cb3142e15fb9725573eaded3fcc85fda63d6c0d77e9dbf1577ea652dcb60a976c0ef52e1f7a0a832aec26fcfd6e3fdfb793c7f0c17fbec53c8b3b8eefbff832f5ff9ef78f6d9a53eff1e422fc93aa6512c73e1fe7b6ec5f3ebd660e3c61770c63997883087005d3d492df916240191741de98bd71e40185ced7224f96904014343199e5b9761dbce0cb3a6f561ea5ec99e10c343656d1763ad84bcdc7da64debbbefe115cda3178d4813f84de486c151737faf125e520d201ee0f9598ce00cbf7cce7fb09f77b5a912392e4d3936bfe7f3f6b24c0d4c8100ebcd9a8f6066c40610648d5b47338005b44ceda75266d6349a3765846f7ee3bf71e517fe051b5f78de37b107f23bdeae98becec85f1677f294bd71e95bdf870b2e7ebb1bcd95062af00444fa16d5fd4ce2c7b26464e7fba21763e1dc03a6bf59621d3f2e60fa947ecc99d1ef1ad1b6dd06780a2b49949f2fb074e95343271f3f229bc05600978fe4a0d197ed5e807874f7073102e1bfe3ce3bb7e706bf18524972ca19501cf525413e220c13869a8496b12e0386e92857ec29d34eb73601662619c598c9cd889fb308c7614048ad513a1a52065cf5e52fe0dfffe5efbdf0db0ad60845ca544f532542bbb89b366ec05557fe23aef9d617a2e005471732c2ef80548caa66b7a3937e7e14e2e62314e8cf1a9f5d5a64fd80a163eb76c2532b87f1f8b343181aa60ee4654d83df26aa66bccc32c2bc79078ff9fe0f6fdbde8d7c1dc204001f8cb2f29284970400e2473b7e1f2338bafbeaabafde7cece263c7b16a9d670c73e147fbe2a21fafb507b45a84a1e1fc84dd20520b117a49479cbb9ff7890a4f31d702bec432a340c3a4e5d14f989c19373ebfea2bff892ffec7e7b03d3af4507bceac172ae6331ac2cf61c7f6adf8c657fe19dfbbfa0b227cdc6e0158e73ecccb8822eb799a6069c5b4cd236456bbb0f94ab71a0da1e4b7eaf9261e7d6608eb37966fd453b5df0f260c5c366419e1d8638f1df7ef5ff8e6e62ea4e9140e03f0fb5166767978a93480ff8d117cb4e38a2bae5877f1c5174f72877516183a24afd20839470cb7287e35870c839841998c6a1f9cce5054d5293fa25b466f79a7c64392a2f56c3e355c39e4c1555ffa02bef8f9cf61fbf66dbd92ca052a5c548cdf738462d8b9633bbe71d53fe3bbdffaa2d2c908674ed79cd0995d1d400e9e7e14cf4775054d2bfcb1d763dc8c01c76807ecc7657f40c086cd2d3cf5dc3096ad1ed6a692e6e91b9e6e18f3e4c90878fd85174dfac01ffce9bafad492f03aecc22f5cd9b0cb6d00f15b7d3dbb3c2e5cb8f0f9071e78709a73ef7555e0ee286b8a97d8e12630d4520eb3d67dc94396a05480c5b7df09342753c9b7c76a012858fae1a2935371affaf217f291df08ffa818fc4679d4af986521c1d8c17178d3dbde8fd7bdf15d22902c80204246b99e9525742a1c2706a58b8b4ba66fe272ad1c7cc2fd6bc185fb9f207684be06306b5a3fe6cf19a3194b485693dad1245e349bc338f3b4639e5fba64447b073e4035bf45f8b25a068c5fe9fd678cc0d36ff3e617b3ee1b7bda3165fe54fcf8c5b1c7af51ab15d97af869167c694fc425973646354ca59e839c9819338fa81b6502befae5ff14e18f497b12feba825f391a955e564ec7690607c7e1d2b7bd1fafbbe45df9f3d480c7ff453af272ab7ee60c7ae438203b04edf260fec78041fc497fb0d61020f9535ca22464200a9831b50f87ec3f80c1b1aafeb713fcc22373f3e2962dd9c283a68e44cb7e0cc0fba9c657895f3646c010c274e49fe8ee59f8972d5bde14e12fd3c60aca988d10853f038687a928fc128755733d8843469f426e29a379b5dead3ac43881e08141d2111002be71d5174765e47723d068087fdaf0ead94ae4b42a3b766cc7d557fd33aebde6cac23b326932e4a70bf1b55de613628bff7ffe3c48dfa6be015693c8f3ca0b8cda5edca66d8db9ab37b4f0e8b343d8b03903e75a4600d786a4410460d25e131b77dcfb7485d34bda864301fc5e94a55d1276a50de07700bca9d7c437dd74d3d6d9fbcfee6f27f4f9551006d0a02a7dab85dcca9f9928a4137b3b57e7de97dccce841147246892388301e297310e70d030864d4d4585799bf06e0dbdfba0afff585ff27c2dfabc1af6e92caf17ba88bd0adcdeb1d3bb6e3db5fff57fcf8daaffbd13bd3f63b03208fda1cd75af5892dfd36ae56dd6a71887d28b6006b2894afa3aa43d7fa8d2d3cb97c182bd7b7e00ccf15e8c4b7190173e6ecdfffb5ab7f5c7f8ba686372197a55d1276090084102ec2082afd810f7c60eda9a79e36413c6224e8089b8efd2e4ed063b8b396654852f94f9934f8b5ffb23c73ee64953f98fb9cf372264c545a4e66849b0270e30dd7e2cb57fe1b5e7c719367d69aa1c764edd39580501d5caa126feb96cdf8eeb73e8fdb6eb9564136faf2bb79bba5192074b7829e870804315e66e84de2d20de99fe2c752f2780c2afc6ce3961696ad19c6864dc515022a5c94b73f23e0d4534f9df0aef78ce878b1df893235ea61d46d002184fd00fc2b800b7bac13b66ddf4e63c70c9aba7199c1dda170a74e39434384a68cf4b0ffb911de6dca0184b3989982c4d3740c14cc4caa0740e7958c55367dfc7befdd77e09f3ff7693cf1f8436d19a94aa0b63715d3748950ab4a1d46fd76e1c07987e3b2777d180b171dafd333115e1d8d4548cd88ce36026b4300e0c0c1017fdbe7394ff92dc6e4c066dae4060e3f680cc68f0d1d695e3a1cc5873b8776d2bcfd27d6963713be07e07d44b4b253a497832bf07b3102e17f6ee5aae6d8b183fd85e139067257768d967b38a8da9f24729b53e4958abfc8ac295b0c7fc60a6da719790e669f00783e6a477d757059b57239befed52f8c9ef0d7484b00e61e381f872c5884b9072e000178f6e9c7b1e4c947b0ece927eb5782f3ed510d797ac923b8ee9a2b3175da2cec337dff047c52e15790567b4a02e892d2eedbd03aba789483b537cc02e9f71789f2e9c0e3cb8671f47ce3e45741f8edc3b163c686bbee5fd63cee5507f42a73172297ad4ff498be348c2a008410ce455ec99ec2b5d75dbf65e68c19133d77a74e3e529a7f1ed30c35a3c18f73104661a6885e624eecfd286f9300666a90fa9cc3321d926770a3226b4edffcda95b8e5961b9388f5425de19f33771e161f772a8e3ce6441c71d471181c9ca0edce02b66fdf82871fb81b0fdc771beebdeb16ac58b6b4d7aa550e040242c0bd77fe04fb4e9f8dcbdefdc700804c680cc174b1d88b6f7f32f23bcd005170cda041bebfecf44fa608b65e0980138055eb9b18db0f1c7660172f74c3b2e9bbfd66cfeabff2aa1f6c79e7db7afeeec07b4308b711d10f7b4c5f08a3360508214c40bea3e9adbd54e484134e587bf32d3f9fded74837559991b9e0d71fb9232e0d0db7f273f9d36539bbb59673647f7f739ea6ef78f38c785489e5e96a825681392b3306233b9200c0b7affe2afeee331f774cd64bb075ed140e3b62314e3af5b538e994733063e66c398c434f0f3686b058d9356b9fc3ed3fff116ebbe5063cf6c8bd9deb311200338d0821e0edeffd28ce38f72d4e1577fb00f8196b02c630c87f49fa47c1ddb6cdccd84cfc9caf0a673230ad8c91b1af1170c89c01ccdb6f00a64a85c675224b96b570c9eb4f5f7befdd77f46ad9ff1a80df24a252c3e26ef30318a9c3cfc68d9bb2bdf6daab915649459dcb4d7db1f3fb56968ffebae34ceb2b79900511ee682fad76248779af601077b7c1328a4febf28cf3c807eebf0b9ffdccc7f1f4d2277a927d6a7b530c071c7808ce7cedc538e3ac8b306d9f19b11dbebe3252da674688d6af5f839b7ff25dfcecc7d760f9b2a585327a117e492206127d337be153a2d80000200049444154ce7cbcfdb73e8a43162e8e4f58f8b4ff32396c34e9df003d359842ee2b9021ffb869a6fd678f164ffb8e8f4ce7d8e2a26c7628128009e3fab0f08001cc9c56ef3872fb6ef38b9bb345874c1b8901bead83d06ef10308212c02f0ee5ed3df7aeb6ddbf6da6b5241f859a494a646f80922fc19f2913fcb0c1327290971be07b5d62b2778c1b70cc223808e0c79acf4ebbc762aa19ff1ca3fcbb57de7365cf39dafe3a9910a7f85c4e75df816fcc1473e8937bdf5bd98b6cf0cc8d2636cb3303337df8cb0713c06213feeeb9237ff267ef7439fc439e7ff9aaf4f4fc26fa5cefbd50301cf2d7f123fbde19bd8b9737b8ce647e58c8a8ccdf545966f36d20355b5af08d12d384eff541ba048078adbb00d5f65915fa40cf136c08bdb5a787655133b86a850992ac20f0053264f6afccff77f3e127fef7747991b7118ad65c0770238ae9784e79d77de9ae38e3f2e7e99d553b054e54f6200c0f070fe292eedc4a0c21b5572bbacc46abfc592c2e8cf7182aafa02160e10ecc80f338ae89ce3fbdff9267e785d6fc7be1584bf0d93cd993b0fbffbfb7f8e0f7ce8e358b0e008532f568583d4496892b65580410162defc23f0de0f7c0ceff9dd8f62f69c793dabfd5a98e84ee6457e7ddbcddfc5cd375e1dcbf7a335d33d7712b27dc0809eb641e320ee29707d9cb43f07197e1e579b1ca0a86be7da8d4d3cf6cc90d2cee655d2ec946659061c7bec71e34f3fe3dc353d5012c865ed9d3da67561c4538010c26b015c0960662f1528aafe64fe7725e54fc903c1509330d484c108cfe0b9baee5d7cadf0e76d628c371d5de67f6e3a3a05109916244cf6f8638fe0d39fbc024b97d43fed89dadef870dc09afc1256f7a275eb5f824a9ac7772b2ed34edb0ed29a15b1af781fb6ec5b5dff96fdc7bd7cfeab5a150f7f2c61080fd0f588877fece2730f7a0c3dc5e8914a43dd8b2c027aedcd23e92ef16baadda0c200e64940fd40ea065c0947fe8dc012c9833a6bdf0b779c18f5fdcb4395bb4a0e7a9c06a00ef24a21becc3dd3105783b7a14fe1b6ffcc9d654f5e7512b0f25ae0086dccdf8918e00c8b0ee3b98d4898b8ac2efd1d9680b89b3895894fdb4b5904766ca6775f4daef7fabb6f00b80146e8ae1b4332ec07bdef7111cbdf824232c467d46f0edb44204536f69bb7166e2bc62dc235e7512defe9e3fc449a79d5faf0dee497be1078015cb1ec72f6efa3632045d4e8d3fe7c1676c0194e5ea7f1ed96800f15e46766e5fcc51961ae34b5b43e5193fadc888e94358beb689352f946c23a676adf4fc3779caa4c657be7143af5e823391cbde88c2880020847059af95983e7dfac6534f3d4d0e07f1ac41fe2fc1e8edfaa8d92471ef24679de70e8650dc7ee8128063924c460cab4e16253c9d3733232af018e7150037df7403aeffc1b77b218f27439b70e4ab5e8d4bdff29bd8ff80831dc5b44e3c7af1811c8606e4ebcf6d978e90253792b80061d6ec83f1fa37fe060e3be2f86af5173d3caf47d7661270dbcfaec17d77fc3807267611968f8732a29b4d58c1d875b4ca71caa0fda2ed0ebe2f65aa489a6f6660c20223383ef0e2d60c4fad1c86abbea571bb76462536cb80934f396dc23efbecdbeb39806f8f32d873e81900e2b2dfdb7acde3de7bef9fd8d7d740715408e607fd9b087f7e6cb74dcd9d1fe497dfe7bf608a21b203069ff3cf2a70708784c888204260fe0286b9ac3a1ab07dfb36dc70fd776b7fa9870a17e561c6acfd71c99bdf85790b0e37a31bff2d3ab3b811130626c95f6714dcf21b0b00b8ad041c78f0229c7ff13bb1ef8cd9e52d705d9af6a76f6ba199213f48e4f65bbe87a19ddb75d9ce2462c0666144a65f50ce48234bfb1d87589a98f73cda73be89cb78ce4f06e42308ac5adfc2834b76bafa776c67d2e846a381efdf7077af7e010d006f8bb2d87306bd86cb005cdc4bc28f7ffc13eb67cc9c219feb4ebaa7c3757ed78aebfdf6bdfd4007b3b4170afbf34cea4607a8203b4bbf1192bc3ca367d8b96784f71fffe807f8d94df5fc3564e4e822fc0070d11bdf81134e3ad303a3197dbcd1cb4890c4b1b4d7fd0d14282eb9997c62cc8c28ff2419088b8f3f13e75e5854fe52404e29dfb1f126ca7d77fc0877fee2ba82b6a534d217ea9aaded532d287fc686c38c77114abf26da11f767526d5ba42524219f0a2c5fdbf4ca4e7bc2c45b5d59d86fbf99fd1ffcf0c7d6b7274ec770317259ec29f404002184bd4752e8e5975f3e2da4d6696b046cc3337c39dc24903dd1872c833093b4513799d18db017becc63cad291223846f0bb0a2dd8105ed8b8013ffee1f72ad343caab20f80070c14597e1e237bedd8fe6dc7ea181012c66f64ccbd145134f3f1e4dd37a65710424e2e914e1b5affb5f38ebbcb730114c5984f2551bdfe66ee1ae5f5c8b17376fd036dabac6fa677651c1b6cb4cc788ed094ee88d16600e24e563c79cc6873c535d3a0c515bca5f6edf497876d5b0d9f999d0af3468c5b32ce07dbff7a1911c1c725994c9daa1570de02d00cee925e10d37fc68ebf8f113028f3c7920ff37b1645a42e667f7c37b7411e94c21114a87de967b92c04020691221b06520fa13e4ffaccb69fef8a61bafc73d77dd5a9b3655c2e1471c8bd75dfc36a91bc8083620a3970514d15602dc3b92b4b9c03a4dc9206046166082d227049c75fe65987fe8b1e263a160ced73e1484a283943cfef06db8f7f61ba03bf83cb011208e3e19783d3fcf54da18db9f996b013e6e1f1b4dc9a789d810db1b248d6e02d3aaafded0c4834bcd54a04dfbac8669e93371c284f05f5fbdae5783e039c865b276a80d001169dedc4b610070dae9a79bf90a5327f5ee53aa59de68b58066335386b01198638379641ef34b1da42c40908b6cb3e477ee9c3f1e05a040c3695e7861036efad10f2ad343dad07ea8903076701ccebff02d38e0c0f970567bd31ebd37078e5ac695bfdcd6d8be14f19276818ae500c0fe071c8233cffd358c1d3b089f41510328087e17ba1080bb6fbb1e2f6e7e41ce5e2c64425e78631555d005cc496801f33e930406542c40c86b32c662cb07caaecfad6de2b9f54d4bc22e41012bcb08a79c727acf7379006fee450be84503b814c0d93da4c3c30f3fbab3bf7f8031dcbc319c46ede9967bfba9baaea319aba7063b0ad9f3031e492ca2c7ce0e291370de9a0f3b95c8019314e3c4b26ffee90db8ffbe3bbbd2a23a9368fc732f78135e73f6859238170a6e87014432f50754688571f9708c5c80b298563d06f5441e06bf9436a2060338f1f4d7e3b4b32e8537f85510fe366db78f973c7617eebff3c7a2c293fbe57de37cc0ccb29d3e67c155d05310d391dc40a2808aab2a997c01c8a942c8e9b575478667785520695bca929cb935d8f6f7f7e3fa9b1e2c51232a85b391cb66ad501700c6a1c7537ea64f9fbe71c182f963fdd34445247d9a126c48acfe3c070b3a8108a42318a725bd56616518b020a2ccead563f27361a37e027c9cb867a8eddbb7e1e69f7637fc51e1a27bfc43e62fc26bcfbf143257650622533fc3fcb65e7adcb6384544fae67905518b55a86cde20cad7da4d9d03e71297e94e3bfb4d987bf0e14c2d57f742336bba9fdd7fd78fb07de776a3c6c368335c4e10d0b2838002bc31f6d9b57d4743449f02c0da1b4a8f1e9723c9b82e390d9f5bd7c423ec256868e01a6fa610e9db050be68f9dd6fbb2e09b90cb68e5501700de08a0bb174849b8edf63b26840617674689ae4899d3ab6937f887c8ba9671c11d08d3596cb841f417d7ce726bffa4cb485aa520ef3cb8f8b932ccf52f6efe09eeba43bfe157167a117e0038e7bc3762ee418726ccc975643a7846b5fef40a5528cc87bd3091d048682329154c658d3e8e60fb1f301fa79e7149795bdb12a1f8b8ecd5630fdd8a87efb94980194479f7b021d86cf554151ddabfe03ef6a33b976a35476763b020af97d2ff59e2c0c6a0f9dc9a265edc969540213493366d0d68e07fbe7f6baf5381f391cb68e55017002ee91ea518162d5ab46ece9c390385b19d2950c40117868681ac65d65f2d6a839cd003506c916248bfd187c83fd663908351014cd5e0adbe9e214822013fbff9c76ddbe098a1a6f09f74ca3938f3dc4b8491f3ff640c4e463cd2bf6061d5e99233e2b9f671bbec7480333002e084270a407c7fd21917e39857b7991d9a3a766a6bbbf0e03d3f89c9f3913c13f051a0d2a3d9b89a3a45129673bb03e14772e1afa2e08b80bbbae6535201db58ccf39b5b787cd990c42932a7e5304f040270c09c39030b161edeeb77056ac9681d00380fc01bead5250fd75d77fdd410d8e90710094d7c7cca98a0d9cacff6b3ea376b502206a9d3464651c36217d100b76cc7ce2ee0fbe4b97434db06acb47819e011f29ebb6fc3ad3fef727a730701681706c78ec36bceb908838313b45ea4da097cd54480f35d724ca1bc2d16185873d0b4c1089182849ea76a4104a25dc9765c00630727e084532fc498b1e36a35b36b5c021ebaf7a778e291db3db859607334f0c0c6df7d643a58d0b4f11804b84ecece63cb13da87425d38c18ab54dac5c670f04567b41597b1d4f21e03fbff483a915485716de805c562b853a00701180da1f3e5cb468d1ba99b366f5abb802c252ce79a73c0c373dc12d6a04c010dd98738c0dca8e060a1e3977bb2fc5480790db77ce2f522683949ddfdd7eeb4dd8b97347a1fe12bf8644d8324e3bf37538e994d7e68c2ceeaae4183915024426cd00e32a6d0c8139aa010862f8934c42342ea66e19b2ea015d6e3380c0c0b9f8847370fcc917141bd4a59dddc2f0d00e3c7affcdb17d0165f378017398bfd07b3b4df2e5934f9b5903684e1f9eeec41141c112f62053dd57b16d27a99bb0304027df141ff69f3dabbf472d600c7259ad14aa02c0917532b5e1fbdfbf764a3efa0345ca77eefee126a1d922213aa04477429b649b7e6f8f55066bcde60cb4a355b0182824a9ec334841204fb5eab915b8fdd6e20e39828b5c29d8a893a7ec8dd3ce7c5d6c4762ad36a31fd3c58d6ab23a60dba86d96e904ccb40af14015f2c0019307238380a739ce9be97efcc9afc35e93a6756c7b259224e91f79e0663cbf66459ccb53b990dbe7dc77262b16d2cc3c144f42043d22dc7c7404422fd644234dc896698025265cb6ba8925cb874d53920619d029363de0dfaffcee942a642a09172197d9aea12a00bc1ec001756b3175ead4cdb367cfd66f7ad51486268ffe46f885b99939994159a5a590cfef831a88725020111a3e0ecc1e1e091174ab2e1a3137a022c21723de79c7cd58beec2957f70af8560869f4934f3b0f471d7d9261389ddf16a630d62fc0b4d50b87a15d66eb686c0976be0c150a617ea2dca06af2763c4dc0a18b4ec0e257b7f713ab4916619bb5ab9ec1e30fff42ca917691c6712abe1154a587962e8660430b4eebe998fa9c7840c9e9117cdaf8fed935cdf2f6762102013860cefe0393a74cede543a3072097d9aea10a004c007041d75825e117bfb86d3034acfb99eda8ce6168381ffd73c22baab3e06b67eb1ab87e6e2b17665597b56cee3c59578e6ff2343980144f01d2bfc1e593c7bbf3f65ba4de3531ae6d9ac953f6c6a9a79f1fcbb23e0ed696612dd6b6ae3aa2bb51463e8ca1ed2d0810a9abaf82433074092e5f4e273e04793138f6c4f3b1d7e4a25f4a25da7420e2630ffd3c117e034c11195dbbccd787414c4b0be0d66808d32e5e3634bc907a520af71830e0f4914eabd69bc3434cfbda35519ec73cbefe3f370f9644ab122e402ebb1d431500381fc0e9bdd4e0e079f3a2cda0e6c22ff2033e75434b89d12b0504bb14c40c1adf7be48e4c1a385e329af1a801152c5b70c64c14e33dfce03db8fbce92a5bfba289084134f792d0e3ff278c3e09cad012b766185d70e52c146cc03dc661806b7cd4b68c68c2c5a9252d790d48cb0e6048f430e3b16471f77b6495543f83ba479e2e1dbf0f492fb8c00b381d77a791a3a599a406923bce2d291bfb6da20f99ff081e343e4f625ee9ff86ed9da1a5f074b1a3def9079b5ed6e319c8e0a4bf65500e0dc5e4abff1c69bb6f635fa0c475567809df15b7ecc910435d86501c2f49227210ee976c9a7930a4c02286e544dbc0945588219097c66b8e7aedb30148d7fd2be8ac2df4e280607c7e3c453ced1f249e33363c2693dbc1c672342999247b2b8b64759048e4c69a4b4ca4527339b69f8208eccd04ce894a9cd840059920580571d7f36c60c8eaf8e85547ae9c2f0d00e2c91d500adbbdbaf60daeee8c76d0c76295909e0daa60487759316ecb0f973d4c0b4d5b85906ac79be85879f1af27997349d4a5e341a7df8efaffda8d73d025d65b71b002c408d25051b4e38f1c4f151322ba33f13a7193fe7653fe9c72a7b88ccafc73f7bd4cf0d44c17bf1f18f28e95c967d3baa6a3a6bed5575516d12cde116eebeeb17267eb58676a3c7ab4f3a13472f3ed94554a63373cd68c9726d2cb4198e4e7c382a33acd649e7f7f2b5234e9b08a6559d335b3e599a01871e79328e5a7c46778270c6156803004f3e721b9aada61174927285565227d6a0ecd445e3ab507afb0fe4990705c57e0f189cafd53c04404058b1d61f1c52687a9b461380e35f7dc2f82e246917ce432ec36d433700381bc0dcbaa57ef2939f7a7eecd831016036e91eb8d3869a941bff927799acf527aa1e771400dda1c5a9a5b7e25d6ae08a99275b7d95915c2d60e7c044c07df7dd8e871ebc5b3bb05a53bb100238fec4330564d89fbdf033b4b1539e74f4123208a392d104628c2ca741e9d262b2dc6669c1de42a245214440d069cb918bcfecdadeba747b66c9bd78eaf1bb20da50898066e4ebe67c069ce353ac067f223c0ab26c0b36d5b4e5b9552932c7c131bd61f89002566fc8f0c8d3892da04bd3f9ddd8c1c1f0a13ffacbe7eb5109402ebb1df7ed7403809eb6fcfef6fbde379589502558396bf2748951d54472820fe3a24a2c9c3e5d19f31248fcbdb57f48d11eda79aaf25ba31a49bef7df7ba7d6b56a5bbbbc3ff2e81370fc09677955d6419a116a2bb0806bbf3d35875578837f7e144bf3090a8abce7c10a809e9f000155a60d5810623d8e3ce6355870f809950851875f963e7e17f263d74ddb390fd11251e40b23d87e6a40f1a32340ba01cc6a097226828cf639e8e5a0e8354cca146c8808cbd7969f1fd8911604642dc2ff7ac76ff5ea18d451863b01c03100ceaa5bdaf4e9d3374e993ca5d18bf00f35d9f29f1a7000fdb44fa29a1a90b06a993c77c01151dffea4a37844d07c83980b580058fb20b45a191eb8ef8eca5cdba69ffd4b028e7df56b3030762c6454010b1c0392d6c1b6d532b8074192eb2c7d6fdda14d7c1608026b5e6c0f5020544657fada291b6fcce91b33168b8e3eadd85ee3ac057fd991881cefe927ee4296b5e4410eec1c272efd82c4f0d90e2c537e51353e5ffe5441f720c334e3848ec7a49e41f61f800256ad1fc663cf0e691e6d04bf8c167bef3da5d1e326a1b390cb7269e804006700a8ed8870ed753f1cac64f4a7220144f5b74c0ded149de7c56b8e62d6678c16e6981ba623cc234f7016302730aafadb9e7ef8a17bf0f083f754a24957e68e759e3e737f2c7ef5e920e2757e3234b087972a1d52e15305dc1ba32c401498d9aabc8e3e641c7d982ec6dfc0d050f27686c5fce2b0a34ec3b47df7f7c44885a96a88919f59721f9e7df2be82200968723d649a52044c396340e86ada61342662fe2175200ab2341be43d00d95a2d1aa3056c002bd6aaeda24dd34a099351c0e7fffb07bd2c094e412ecba5a11300bca687c270d8a1878ded1eabd87efb5d3f667e23eb7027efc4e143bd5589a7b18ee19d41c68d5eaadeab9aefeb944e1b40e4d4cd871eb8bb4a33bb33b7e9e8638e3d05b3671f6404cabaa4ea7e06e155c3b4bcfeed1818363db7c70828acd02b21d4926f371c91d2ced08700af4181eba1759931eb402c3ce2e40231ea08be008d09cf2cbdd7b4cd08b39c90e4bd006d0e3a952217c7ec98cebf0c2d4b8c5e83d0034a62ce76939a019b3c8eae223db7b6896757f965c10208b6a1d3a11565ab24b495e576007064a744edc2873e74f9fa316306da8fff8e117d680eeb3c3730c323363eced9559dca09ee545a79ce1d20d20ba0682c82ad877b96000474c391eda9471ebaaf2b3dea3038001c7deca9c9073129b6930a02664772cbb86210850104d356f7ad3b83244a570f306e0fbdd037d12e60d318079a984746f98a404f81b4ee6958b6f4fe429d88818b6c9b399f74ff40885f1a4aacfda4002180272047ae3c31d2c25e58faaa4e0622b432c2b3abdbaf087402c9b163c78477bff783bd1c1efa1ab4710d6e0700a7a207f5ff831fba7c4a3ba6b7aa621ab22ceef833c4d7514cc7f1209d482e9f824003c284f29cfcfe6d9bde7e70c21e0565ebcd75cb002c5ff6341e7da8cb9773bbbd4c607fe1a263f0aac527bbfaba0fa430b0c16b2fc2f4acea729bb8bea920c40a38410724adcb13dc07bebae51e88417704594189052f5c74120e9c7f4c21af6e44ec146fd9d2fbb16ecd3312a9c00764ce02e45f0a9e96291d084417e81084ee6e00117ed13ec9d98714685c19797f6614b06a7d0b2fbc989e17e06fca6894b580df78ef077bd91f3005b94c17423b0038a587423073e6ccfed2175d7a7b6838efa8b86e086bf4729d25dbff0c2c905e2bd30568c7184d02e62b315216006168af3958c1b1df2579ecd1fbf1e28b9bdab6a7abf0973c3aeae893d03f6630614e75bee1783a9a695edec8658d613e9d1fe1a01b7e4c794a37d69a821e1c9a22864dc7fd40c5519100f40f8cc582452754137c5b4c87b07ddb662c7fe621d777961f2c20a4a3bb1e77aef4d466793b86c5089b716e6b00ec40e3b7162b6df5b3e78417b7657872b9d10292c6766af7acfd6694cb58f7502ad36500300b406d7dedefffe11f37341a25d9754171801d7f14adf3744cd4e0191686f945cd6257e1a27acbf9725d720ce10e62e0b0aea46c414e18c670c9e38f3e58da8e8e4cdbe62501e8ebebc79147eb77fd4c89d2063f9278104c0fc67434826f83654ec3c9d276fe920e8c1a2f9f5d63ba04ed172f2cc619079a275fcf3fec44f4f575e75f5bf76e61c5d30f26a73995ccc59956a66e0a7470fcc160ea012eb6dd82424e98f89d04a8a664ca649671348e65acd9d0b495d1b6971244ebd0d7e8c3151ffbbb0dd5a8e3c2c9c865db8532003801c04175737fcb5b2e9b5c785841f8878609c32d42ba5fc08eeafc7f0ac264e352897a1fcb0fa41dc90769aa755bc1c03a8cc81920116014e5094f3c5604808eed6c23f8fc78d151c7e3d0458ba370a6745006b6f5c922e04118aee871e9545c617ebb998869c28c4b911e660a46a49a820314ad53e1c86e73d0826a0e0107ce3f1af31676fe88347524649186cf3dfb70d25eab191a5b85adbbd8299460eac094e72134b185d97cf95a764a7a3f12de78e5681f410304ac7abe892797753a3bb03c64045c78c95b8ab2d63d1c845cb65d680700b5c3b4697bf7c98d41ac6e6138fa46f80ed291dd76408aa68ec1a04c6cb58618cde4134c26eaf905db59a41a40fe94852fe0c9271e2e0580918445471eefb41af62af3a3b8ae29cb7c14d65740b504ab4965428fc4cb0db0db26a40cd9f927c06bfbc080844c0f821cb7e6f262fa89c0e5851ed40e002af28b890e0078ee9987b172d923b20a24a04ef69a60cf4650b0d37aaafa6e9cc404c44c7bb8aee65b0c16786cfbf38b609cb2bcbd60c5ba0e9b8492f26dd8779f697d2529aa844a00f0eabab9fee5273ff5bc55ff2974886c426efccb1c71002b78f0828ff4f04edd2d98a7f5aec03a1240084930a7fd16ce0c300221024646f8084b9e7cc4b5c1814b59a0e2ad7dd4080d1c7ee4f1f22e4b7c0eacb0f348cb3bd1e0da6c1954194e8f4137aa29d323d18220d70aa20c3a1694c8b8fddaa3b755a0c8fce0ca9eb7f038e8013109992a22401a6dd5f2471d61ddf26930b6119350466b2bec603e2cbeb73ca95342e535c9d3a00599f7aa616a5b57ae6f62cbf6eec6c0348446037ff0e1bfe8c535b820db694f2c0450e1b3af3ebce31def980c4ba80a1d49007636490efb44646a615ade028c44684a3a04f08c0698ce80ef181d1582ba04c3e7e7f7c35b340b58f2c4a3b61add1bd9fe1600b0f0f063b0f0b0c5895aad23983fa7308fc426ce2caa9f997e0f4b3ff56dda6debaaf95ae72115620b04f6e871110d5281f28ceecb723fb1290073e71d8d030f39da13a586e0a77c0000ab96e59f5f773624690bb7813790257c01882b780652d5ddf04ce13872331d746023f1144432039a9e3f092f6e236f0c2c696f7ac57dfc8637bfbd9769c0f1c8655c420a008b01ec5537d719d367f45b3ff34e41fa8dbce79f20ab533f4d02e9dcd8a1f15b008ef1928e8579a6ea6e30b91b26e13f0439279fdf71a76744787ae963351ae91f958543172d96f65a374632b756b258a00aa7dd42350737253042ece96304d8ce5f0d23c331b7d5ae54506c1ae91b6b0c143b0549fd793950fbbd664812ac7eee0903ec465b612075ab42dc1ed3bfce66a15da13a692eb01903a00c4c762bb4c484da635453d078d03a516e0b70ed2aa549e20447c0ac993dad06ec855cc625940140ad70c69967ade9ebef4b6b5c1ac85cb478edbf1081473f1653a305102335e23e74244c9a74accb8fd3e7f966c6106409ae1d6b3410ca8d44cf2d7f064b973c5a9b613bc55f70e8d179fe9911126e3f0b9605b8c86ccee8266d03ece1185cb81df5c134704b57e4e24859b60220d9eb9ed28cfb2933c640b8f23ce8cc3df8e8da824f850b0dab573c86f56b9f917e17982a38f83008a9a653baea237567ed94d12cc82a8869545216030f6fa6f27d07326513b07a430beb37da3d0ded2940921130d0df8f579f74c69a1a24e4d011008e46cdf0377ff399c976c46d17d2f743c339f2868c7c47c5c88ce46906d289e2fe6f3a21d9ed0641631618f51093392a5c5f3a352e670a45df679e7a0243436dbedc44e6973c6a17f6dbff202c38ec1858af475563f5c45e329b4a3c838a6846da68dd951995a610c6b40645255caa41c919fcd2377904ab6a5b832d0b94052cc3b3221c73e6bd0afbce38b003658aa4f5173e348787b076e5124f1f735682081ddb8aa4bdca03b6b31c7f50fc749ad8650c5842bf15e19cb46cdf585001d3470bdbb193f0cc2a3d38b4bcfd3a75e027ad0cf8f09f7eba97698093710b00b3d29755c282050b3bfa273b063444d65d7f76de0f211c441bd6a53959be61f59f4cb696f09121fd9e75e31094a2ad1d6d114146d6c355f09e79fac9f68d2c6b739770c88223317ee2a4bc8ca47cddcf1e8c3694782972bbed061d3bc218c621988d2a4c6fd9b8c36df4a375ba1108f0a7e98a2a2b6949854de2502c5bcb19376e12e61c744457fa383a7621e8da954bf2c339837585b642a802cd74129ac64876e547cb27e14907ff8eb39700002000494441547ca64e2ad86aa415502e698bb8b1c77aac7abecdc1a1a544d055acf9f317f4b237e068187f000b004702d8a76e6ee3c78fab68f3d7d0caf28d3f3084b2ea14dfe67fb9d3008555bdb4691cea423b862844174d0f1a5c909ddf7a6f322398042c7f764979836a53200ff3161c690429d640da65acd75cdf58376f94d2388e26f6574a1faf8a2aade2f3cc0876ba2bcee42123a25d9191fc4884823faaca6af5fe07760600c7f35d849f00ac5bfd94d088db04408ff7e6f6499420df7fc8a36921d6fb9241cc2269c1cd5a7e241b471cfd6d5ef604e2c877ab5fc8f0c28bc5b3028486259421001327d4973de4322efb022c007487e4245cfe871f5ed789fb052593360c35cd5ab4f5f433bbf954f0e2474045d54cd5219326f9814725f83464a485eba14b6b317de24e9b11956b0049fbbaf0aa0bf3e61fe947125215d5da2b88e01959c052dbe636e890b61fb12d7669ce1d9f6580c024443ea78f1a1a6b0a2ce84223f516d465363b55096a3813dae757b3e7b667b7aa34b4a45fb76a2932ca949700fd7620d72133d33eb2b483d024cfcfcee715383cc06adf64f161c6740d9caf0c2310e0e4f44169b6736786a757fad5000116bb1f24a10f21e0ddbf75792f1f0f11e25b0038bc6e2ebff11bef9954f69c19a05d4f0e376184d68fb29281413af90c36f1c0e43db16caf93726acad39e3962c731b820feb5876448bc0c58b1ec69ac58eecffe2f6b77d570d0bcc371f0fc237cfb19a8887217534313313c216fbfdbd30066b632e39f01111357e961e7ff3adf654160c6f5c06ca716569d8602a715a678653fd832fbc045d8ef80c3dad3b003ff9485f56b9ec6f36b9e717ce4048edb937a421a5ac181240347bc726ee886a671c46710607e8129cf9d0cc4d4c882ad0ad66e500d400628d87c8ac420022efdb57797ca609720b26e01a0d81b5dc20107cc754716bb3e6ba318108056337384d79377cca932c268e43bcb9cfbae651ad5559ea974b87ac9b39ca8ba5b4c472e247101c2732b12e12f63b48a81083870dee111c0cc729538d800ace9d83308bc4aa9a0a82a6632cdb1aabbe463563f1c282af828806aabd4bea05332ab02f3dfd48352b513e915a9d3ac0400d23eea48c39267cfaf7dd6d42bb56bf0325e499fdb782cb4803933116a744e8036d732985ebe7ed257414190e96a8f6c03016b5e68a195d91a059b936fb729e880b907f4726cb8109e01605f0087d6cd65707050c4bcd0796d3a71e710a1c91f6b8871f26f5892103b4f1ed19ab332dbf10cbf2ba2c60766302f32ba111ef0b7de383fe3bbed042332c68ae5cf6a23a8f4b27b307d79e0c1874967537cc9aaa2a58d8ce2662446cadc306de3a52a696ff0ef63196ec5c4a64bf22b9eb910a4de0ea448ba4e41474f7255cdca00c67e730ef564f1bcde918c6561c3da674c9c68c45592e6dd6e78c8029e7e0484b4ee80d909c9bc15845e0e40e03547b9b6806c5cb22544bedbbcb58527960d31b3175a59204dbc193f6eb0cd50db311c8a5ce60500e603287ec6a54338e3ccb3d684505276b9b6220d60df7f27cc865928a0b8eb0fca60da67a94004c780791a4aca8a1d26feeb46bd0d5a8e9113e9d8952b9e29f4425de1b7c9e71e74983084158c2c012d3e03c16ed8b1b4f1a3b8dd766a041eda4e55c3f34499b10f8444db92e4301e6d91589429cd3ccd6d5b493e346a69cda7e9ccdcff5003dee86a4ced880f046c58b74c6994a9ba6d01cd57d878061a9a70dd352d3b5e192d283e172c040307223f5a608934e39ee034894170cd06cbc12a488e4609014268f4e20fb0377299170038a46606f8b33ffbf389853ab5e921fba8c5077f246f6544321c94323b98c8ccd09c4334f058415204e6bffa8010d12411b6b2e51bbe5ab5d268007582a90b8759b3e7e28003174a04ae9a55fd45a0632cfb2933651acd5fda25cc499e0664d6ac23c1b9a55648b2b40c90ce6f23bdc4626e6827f536f416e1e1e8f67b844498317b01f6993ed7d3aa03193b86006c58bf5c4669fbf10fa115e76504367fcdcca74b8222d05c763228a58e5842ab989f82bbf2326c9fd85fd47ed76fe4d1b164146d2357ad8cf0bef75f31b11b794ac2218002c0bcbaa9172d5a34e8ead4a687ece32c9efbc72f9841d223af32464d4e4ffa377f68554bf398e34a7c3b3fe3114c9d63749798a9af19e9c44a3b3484d5ab96bb367565c80ea49933770106c68c49d443d34ead8c6a3bc6e3d1c663d0ca8cafbb8c3c80f36dcf935bbf0aada053e1dd7b635f311261b7cbaaa6e4eb2bbb160cb05861ecef1f8be9fbcdaf41c992602469e3f32bd01c1e2e7ec188a350d478a42994fb0e10f9ef1900a064fac0b60f29d23a13c1b459841d9a9776a782ae64ac40b366430b9bb7728ae0d296359bc3c24317f57258e83c4001e0a0baa9274f9edce7602c09658f879a46858522b130b510bca8baa9f0f2bb20474f737cc04e13083a2f3360c28020f4e77beeb46267af59bd02cfafaba96559204ac29cb9f3858994193591757c525afaf9b68ce8da2407269c47e6dedb512f52c3028116a6a0c020999491df18c021d2c35cb9de59021c281a35a7ef77487b2e3755aa12b66c5c8b8d1b9e83032dd326cb5320c4698cc93db689eb6b7954af8323840e28c6751c86234d5f69bb83f491d29130dcccf0ecea614d5f225f65723565cae45eb6071f0428001c5837757fff40474b7fd9c37cebaf771595b951889198211301721d67d1823b321508e7f9c7530435c2a4e0e23609c53af2bc77ddea955a878af4e9146ff69c7906804c5bb97e29701946f3792b181a968375c671c22fee954184db0a85035a19f521a395d22a6172f8b27210886fd9d84a3a05b1e9f79d717047fab5a563496710804d1b5619c127d7367d1c6921967debbca4f4d3f8c62b94f30c0aae4c23a633f35272b8b2eb7329079ea66b5e28f97848275a10303066a06d9a0ee1404001606e9d94c71cb3784d6863eceb149a2df62ee3b416a58327688c28c6ff54603899f9e5eff54d3e02d9e98451bd00d7e9768d3a4b1068edda95d59b9a305b1a4208d86fce219e6960d56412c605d78585d00aa9fb9119894dc384364a07197992ba6a3c2edf8c6889e55aeb1bccbcde4f396c3554d353c0e2baefbbdfbc7c1dd893d0fd2da371bb479b5f580964665bb4d10432432b22de4ecdb435b6180778a43f98f630bda1f4b4e7320a02c0f0430a58c45335b5af6cd8dc2a8f5bd6e0f83000386cd1d1750d817339ed6c002beaa4fcd257bebae9d7de5c3c9688d21b031284dcc8c14e1276bea9e8eaf3200609f1c9d77926e7e9d29012d2a7b771b44332e4c63535be0539789492b804ff3ca37c0441a69da8c06501299645da0e7e6ee31228fab2938c9a2c689c8a014dd3f3286b3c08f999a545cc844cbe407eafa360de61a9f110411d5b9426a4f7ec2958e6c599f40f65148d735cd7ccc4e3f62a2d2dfd341f9d1ef97b611b0544300870bdc89525f94adc486f52dadb7e2ce3093fa098c146fa55cfa1ccf90042f4321a0d8e09f8ed374c4623d1ae4b01c05c5ef3ed6f6cfae30fd63e2360ff0680fd6a26c2e2c5c78deb509fd287f9c9bf648842aee51c55ba358ec2ba366bfec2ce6d351f4678668a3c4a90026ca7a42366ae12e64b61dcd1b66ed6aa6dbdbe9c40d932c8fe4454a096662e375e9b937785b1844152d0533a0a0da00c4cb1dd5c0e013222bab96930ebfc327a1923298c571be745888e2d7e1a21f4e538420b8a74d67e15f08a8642eb022d153382261b899ce0c3c5f134d77cb98fad6153f2ca8ae9f3f28ac2cf1724d5d3c2c9f19e898f38c0c44459c6865af39119db8f44d8be23c3532bfdee40275b89e0f3ed11472d2ec86485b05f03252785760b33a64f778711940a7ff29ebffa2382e3045219dfad00d8ce31e42058bfa02042999b11522b3eb90e51fe2793775e985f9755cd208fc4f34020304c19b049b50c5f63cf2446fe8d40180f3d9f0d587dcf4430e2b09d697c5fbe010239ddd4682959ac8bf9968002550236314bf5b826a74a4b7a247362f0742238fa5850ccdb646862855557d0722dcbcec1898147692f5a92e129ae6b266063049da43bf33c65b392d23c05355d59f15323c75e693b23edc5406a0996f435db7fd658b760d8ccd1d6cf66df7d7b3a2064563f809975530d8e1b1417e2425da8f4321efdad6f524667a10600abf25b4115829161362368998be4d57219e983e958e4a7ffd8baca0826e5a8414ef77223c937a91f5495f5cf4d721664e13972f5f2795a01287baff56586b3929999826504cb8772cddb8ee451adcfa9a823981da51dbda042c8768cc0fd282fb49f2dbd81d827b23c17eb95d647fa3248621f47eb481462f95c84a79d000699483cf54bd57f475fa659ae3a916cfa3153c992be93fac682a4bf13fe61f97e61731b436032a5b661fcf8c14e9ff96b1766f623ba04d6097d8dbe8e825f165a99329c444fb841cea003ab70e67dc2e89a0777ae7a120209834b2d8cff407cf286f316556d820f5433be2dc3a924dcab45682fcdbf4da195eb42a59795d2558d9ff653c5ea547ed93ddb54e87c78ff5fdee5f8cf4e0b60fe6a36115c8c404b7a725eea8e4ef96b339871fe80e36de5893ccee6ade4eb9d34a2ac4d03fd3d7d2f64df9e0020984317da85f47db319a533808720474c6bacf192ecf352ba917f17d54605108bbe16d18d91b066bbdb36ae56321676beae985987685d73288950a709542372ad7c6bc4ed1c3fa1a9f4afa57392c28ebc65da5ad235195840cd40c6e58434bf3c8318d5817e61e013c1579edd60cf06a820fc2308fb3650730fc0f9e75fb0a65089645449dff3a7bfb8bd4aec104f7009269159abe71f0cadc8a435f1b97026b69445807aa5c548a22558479b7aa12ea37b604b4bac38fa8fb01e75e3bbe950ddbcbb0056c76c4b2274ae86a129a5c9cb843fda126046fbf847049978cf024ffd00bb9ccce5d8e5639d3ab09dc7fb17982aaa0d84c144a68201db761056ac6dbaaab7a5592cbb9501a79e717eed3d01b501e0924b2ed5ed8749adda759235003a220322e14a2482680702147a679d648874338bdb460c655ce9b214f119a5eb34ded6bb56ba025796645c7247e892ae4ad9c5cb4ad9d52cb350e75eb32d8950adbe71da08001d467e7eea5dc22dd091083ac0bcc2560d6fd014dc605eb27612f30c268d94c50e5f9c2e531e0508eb5e6863084c1a62df9d79f62575b706efdd0fa0d6dae191af3a6a30ad5537346f1ae7109fc658e89d31ce3b70e8086f97dcf89a12612f028cd235b8677502a1ad01b6639a62427e606b5c765721ef5d15bf06c851db9b9ac192a55296bd221b6400c90fe550d53f37e225cb8cf6afcd224ab313621351fa9ea7a6f0c021dc2e5aa8313003f2f5e0ce6df061e1e147d5dd1330b91f40ad134566ce9c355059f8e3fb56cb27b082ad23718eb46c9df5f32a8a7fa32a2f1a420cc91c4ceb95ab58d611c35ae12b714c8db656c9431f947bbf5529acee085eb9de0990d60a23ad6f49c4eaf5306edc1552666c38e68f9e328f3927325d79913cdbac649079a89ea75c46e4bdb2c1877d2ea838886dda266b0a85d0ae75d3a7cfaceb133ca91f40adad8413274eacb6dc606ad9b2ebebf0c2982fcb29e1ad930d533b0749eb01a779699e5ab0aa749c86cb2b2e77d56846f54010e6e263a13ae53caac2dfb3108d20ee288ffcd5b263d44f85bf7aa1d6d9ca9f5bc8459013eea830481c3b6ae7d1ec3d332620c01248784e7c2eb82db615046c6d07001d9a39a1aa6c6a98d80f607c9d148383f949a4ddd4131b273f03c008a15181d5534a1f3b4b2b024296b80e276528220b5a40886b00428c2d0ad01ddbd00b5f97e75dc2e5e64de707955e1522d4aa7b8db6d6a96fd7d725037679fc947e0aae3a9e769fa0d9b79919495878add06ad5d2e9a8e1b3e0df4bac84ff45f8cd92755e34976916c723ff6ede5a04806e7dd4c3e940e3fb01d47221ecefefeb5c886b7cded8dc0988e1d32cc921f96b3a841f92c94bf2a6f49921a853f5f543a0c54eb160516c434fc2ef2e526b3f95c76dfba0d2ab9a914696b48069a39067b53489074c30cbbc154b14fe4aa78b14855f0696d41188a79b450d21d73479f022c92be77193c66812e4d20b172bcf44b6dcbc35c3701318e0e5fd0a04edefefaf0b00e31a006a7d5ca0d16894d7c5f0babe0ff2019000b863a423f045374f4dc4c7735b9f71ce34b3794b3c13d78041cc1aa1642986b706b79b65f5ccbcbe7268a7fed7c9bfaef013aae75f6799af8ef057ca8c8a8fba966e24b08e195762b29f88e3073395a0e0f39581c058f24d55dc2e407e47e4f2d7fd2bc6eb324a84dd3d28f18302cbfa4dcd76e42ab48f90cb66cd30b601a096e1207430d59655b4d9ca89cbdf54f38262b2609434f95b7fec2cb501c0104cbd2dd4a02280927628775ac2fd8cd0bd3237d95ad570f4e910a56b5592b4b5aa5e23721de1efdae2b2beef9a5b6e276240a536c0dab62e04573111d6b8014b85590792745999778eb210abcbb2e6e1f8c76a97b6ecb43c00ea920d39d48210f0c2e6ccf172bb3672fe8d740b61f730d00fa0de692295976af2a74d9eff1b18b60365669eeb66124324e349e5e75231aa100c02207ebb2aa49338b32c5972e176d5137ed2b6d80699779632c527e94d31f75d15eab4b3aef0d78dd059f88dbe8e08f47529d32e3ab1dc140d70e4a3e5dba6a13ca40e44362fcf0fc28f969f93fa305f2b3091be20c2a6123b40a16986b14a0fe9ed1cfa7a70204e90adbc5a50555c4771046da45f3ae10710e12e58f01141d52c1d4a1cc84b1f5f881f1c68e8335397da2124e952e6a4c2550127da844ad54919a96a9a1a3cb22b85bfabe033f2c73eaf588a8fd526ba851400a04cd5f274beeefa513a52798dc4241e2473a711b4a99b96619c04248eae16746c63e9a8522ff40368a18e1640047b824b7b80cd9bd0d76090334b240c081c8b541582108fb580bc10f1f317ca1aaf2f22879e5ee04aacc782d81d1ad0950c569a0cd38e505276a9f0a33ad85505ab4a516ad138f18f4887cd2a4575013a31dec900620e5513b660deb41bd8cc1abf6332b50104a9b3176ca704731972f84b8c9e7c8064d284f239bd2389e585ac16a101a0d50f601835002077d6493703798adb536bfafbf4a9543c913d6f85b56599229850b0cb2864b393e429cfa4a7b4d8fc7b917f2f44e5a37ee9930e85d515fcbaa14ed25113fe0e2370f57af430c4754962adf81c3123ff4e3df4bc8bae1804e591e1478e6b9614534d40063e395f22cfd39dc814c3d464599fa07e086521ab8aee1a86fb01ec0450d985b09565e8ebb3154be0966b19eb32d0e719ca029757e575f4977796d0128c9660f335c0acc466a202ce36d0a3e0735adfd8b2eb92fc4759f8eba4a92770d50ae8997ea54f8c26d563c675404bf9c72e49b3a007b3119505d5f80148ec58dd8203915f924e055ff70030aff254a7685bd8674a715ca60ee0d66a75b61994849dfd00b6a3c67e8066b3497d7d76bdd1a018df9b568400f4357839d00b360cf101c8d766047103d400e3e64850a187d283326526e928d2bf051446c057bef3a0d4cb7969512476a279f067cc109945ce3030238805a0f2137eb5fede9a1c9f0732ede6b4c1e507181f0797af3192a6d3a824aea39fa3bdb19124204cd11ccedf342cb639ff9b9907e9197c453a50f40835710d4df3fc38a1a139a7e77c457d8e1ab59b16961c10037b1d048a9406863e49dded5fed5d48199c4ee4d5f092ce3e3855d07315e3d3c9131a18306246850b1f08b96cc28dc65dc3f67e00db6a24c08e1d3b68ecd84153555e9a21d3520f538d0640bcbb91942c05e1f046df84d0ea19c84ca3efa280c407ba73cbab6496a19cd04b6727c29cd9b8c65a1c85bf949973cef36062e6922eaed485a747d1702adf2da4e852ccc2188ae599bf797ebab6ec6818e08e3ce32ee276db959182f0dbe78af742074b17c99f818dfb2104b3c495082097615e38d061bea268ebe18f6da61b70a4fcd81ec713bedf21f74666c87f47c1ceff8b65d8fc7c3cf79e0c2f184d473c628992fecf339838aea1c53a2429067ebc6ddb8eba00b0ad1fc0961a09b0e5c52dd9e4c9531ab6566ab9b7d5d1c086c0fc2d375afda359e8849909caf84eb8e180864917ecd9009175f291a0d38e41ef43ae8cab2dcb1f713d60ca21652ac31800458bb2df16ea463f161e2838a8b0d9b666f19d1d0548f38eb42473678f0d73b4234a985ecb96da59fa07cdd3f719e7e7eb6247423d03d058d4e3b0ea8450fa41fb820f6475f5811d28000502a5881d8002d7172c7c90de74533f5260b17daf795a5e33360225a3d0918d8520d2410c267fced7d2c496237c4702ac13c7377c815d841f00b66cd992c17ff1bb5bd8d200b0b94602ac5abd2a3fb254886a853fb1e0c65f5f23369c0553e6e32afc4c6be26c846888e952145746771fbc047b077a26e384aa6128ea14ca97fcf2f6f1a890c58764f72600a6130ce31133870a3f0fe244be6c2f100c0621696f7eaf9fbd4a7cd749fb237f64ebc07998f61b41e56530c94ee811ccf70483d040dedbebc8e0a56d963ad9fc0ded63c1eeab413103cab46f60da2582c58213ffba034b9978917f2c0fd813aa6d3f160e0305dc544bda2dbca90473532882c93da7b734d22e222482cdf793c6f30089b681929bb56b59362b87cdfd0036d549f1c003f7ef38eeb8e3c70186c8d688531206fa9930468fe1f9bd35dc91124054eed4c2ea0435522828a32bf14b46377e6ff27ffb1b8e2cd4d7e52d4fdaeb6085a7e5d1da3dee18b1721a7866fae4bfdceb984c1932e45fbe8ea8961ebcaaf4e7d4019ffce0e2f6f52879d1b9ce86961164b4a7ba5bfc53a6af1a6cd4775d710774593a6895624c4707fb7facaf051f04d5ba145022880495740617cfa3907ca59498cfd4497d1ddb584687c71f7d7007eaededd9d400b0a146027cf79aff1902d0119dac40838081fe9c60baa34fd1d59ecd2ec46284857487cb5b89caa3580e14b0f9ca4809c9873584cccca5d39a7baf4553188a0df6352b7bd043708c5723593a92c4ff54f8815c5b92614b476c8e9394cd82500b84bac660a1b093ac8401aae45db152657de4a691c4bcc1c77be97443859ff709f094874c3e89264090f420e6c394c18bf563ad90f3993eb5dc47af200d26af9b7efc9da16a5491b0a11f3501e0faebae9d21c29036cc5d69181c13d06804b45a648ef3b6f1f386649639acca6f890a058ebc0b74ce2d3edaa255446000909eea9a95a097ba85b2b0a7ade9dcce4ea152fc3221ae92ac5344e1393fcce41ba52cf3c658acae93a545e77a76af6f029e3c0daa112cf0f7144c15e4cb3ff2aab84ac1695423d24cd41ae2d7eded09c04c4b8410bf8814efc96b5d4a62cd77dcd8060ee876ccbf03d1dccef6f39f5e37a31e51720058573351c27046d52e5450c3401fd06ae973cb78390d8ca1a7cd5fcba862618e2f451330530bc7d4d2936a3c2c0091a835b6f24520e8d6d68aafda46aa9cc66270fa3a9762a1adee4283d233157e63771006ae2875c558fcc4083ea900550d54b8a81edaf5938eba88b4f07409524f00087222b05d15b0e0e9d579b33a64788c84c63e81db361ceb30ade463bf85b618fe4eb2ac13d6f50400ad56137d7d6d362ab71930fafa8c6384133c3f32b5157e47405dea4a55d4b453d4e014a2fdc5748aa461c16766b58cdf9bf0ef32c1b7712b000f01f24d3e064a7ee1da1f184421915290ac57e776f693d190e49a49d23acbbd59ad1158086ee7a9ad7f6199dae6cdd9c8e004a4cb881c5f6d30b10ea49a2c409834a1cb4a9eab579e66b8d9feabc21dc2ba0680d575536ddfbec3b91c7562467e3cd06fadda6c6851f4ca2db82cd82ac4fc5db83c9d9db3c5a786cf8a68acf759e4fe8cf3242db7aaf1a9c054bda1eec8439572335d2d00725a5b775701d7d87ccafc9ab4d0c7a16baff555601f4d906b97864a6f7c9c9c07b85ecc87c1b49b943e94f39eee67575ef37f8df59f2cb8f878e900a8f5cd8160ef495efd9734646fdc4235b66edb5edb0d10c0ea0680557553ad59b3b6e92a577ae36fc70e78831d5b549d012a61141dc58d730b7942ca3211d9f8d6f06240da00bd12951fda51a077c9ee25759d34558d72799eba1cea48cc3490bfe99cd8d0d766585246f91d159ed515fcbac25f0ad06d2353fc8c797034217e2759b086a97f356b5d95e2b80c1499f566e4cf8799a21974d86e05d34fc808b3a6f515db14ec5d28bc5fbb4e65b24658d500b0b26eaa7beeb97bbbeba412c14fe93f7e30a0af01d8d35185094d1af1c41261367f893f1e8a64ae65189600598629c9a3c85c9659ed14c0b7a7f3838e8fcb239aba574d524b20084ec352a724f31e0c960c16415665ec54a1bbf0a74197f91c8854a97787323ba6a95e39c57d1662e7a3c2cf83a315bf14ed31fa4ee847533532cf0474671f0c3928e1471eacf287e3071b983f67c037412a9c4e0d34d6230fdcb3bd73ab4bc3ca0680e7002cab93eaef3efbe91d5d66291a62db02741ae0467fa0c070de8842c6e2af59820d5c42609d56585b039791596624db11ede7fd053eecc098b584bf661acb4055b2b7d554adc9d2c42eb206a599a30f7fe8b33cff622b828f411dc9d5b6ee230e758884c807f1a8ba00e627efa7c0d1f95420ed0bc333599029ac9c26e45cc9f38b10371b49399107998ff799daaf27fb70c1898f829505006884802bffe36f77542712805ce69f63b7c167eba4bcffbe7b675049ef960a8cb9548720df04cbac5615d3119bf22f00c5e74c514154f88ee2d18c3d046d0f3841f0a252684be7073543429c5e00a35654063f523b8ad2937df4959c0003ae01e324cff2aa940f0575c9c57d5237613b7e6b179759c1ed13894df01b9838ae8299829ae1bc04503d6f2a2d2daf7a95c1bbbb4f9b64845f2aee91405f29e83ef6c87d7597009f05d46ff8999a8931dcf45e879d68cfef06c7e4078ae608687cd48909adcc54981b250ceb970d8d51d1b8a30a792292678cb8c44b839debdb2d90f9758dd843fea07a7529a493f6221af90c434adef17ff97a53a465c642d26dd1ce5040fab262a5cbea5e230dd99bda69551bb5929af3a7f1f44bcae0e99453eb83beb3754aeba7a752f15fa6b6eea998b54f34003a5c0da6bd0ad77cbd73a8ae07308028f30c004fd74dbd69937ec4bc40ff8427388c1f8c478a92361dcc74067145d00d7cdad149b2270059622064ca477f7db57c33f9827cc3be8c513bb5a5762811fc4a599976d62ec6f08719970ccd72a10e7694b327d1b87a06582b76f75a90a6ab53f79a342e8dda257d59bfdaf6aab6185475a7249e1178378d35f6f7e274969497895762c8b59be38c190898377ba0841e3948e85f1f366edcdccb1ae0d38002c0d2baa91f79e8a11d5c3517fc60e0c2407fc0e018331f778455554858973c412d58cb686580c043fc0000200049444154e653fe9d7660663403c1d16ec2df85292bf36b5df0a8199f0a177960e31433181864e3e8952eb982801077602a53fad59462c9dc31dec058b51175358542ce15d3a7d118aa3c7db84e662954d2e64c65557edb00b51d98324a005cfb2a147834009839ad1f5326f621a56447c023e0f1c71eaa3bff07a2cc33002ca99bfaaffffa2fb6b4334a76ea9731030d27d896c8b21cc51d030606247b067409859701613a40f2241d91143cfcea4152f5ee0de8feba10a90b96149255895b1aefff6fefdbe3ed2aaafbbf73ceb9afe426b9213721ef40202f88f246345428220f11eccf62b5d45f5b51f858b4a85445adaf4a6bb5f407bea8288a60a96091b6082a5ab180011482f20391243c429e37c9cd9bdc3cee3d67affe31b366d6ccdefb9cbdf7393797c05df99cdc73f69ec79a99f59a356b66bc069199fff374c70956660049e53a4e404cb978f690aacc954b94a2991ae11fc3396b9e860fddaba4d76ebac9442876504234c9d0220b4b7718a8a04bc1c882276d19de01279c2e907c042db00f9dc81180497d49fe5f837ea9a4f0edafff63ae2dfd069e059c00780639f7043c70ffff1cea1d42d880f999e1bb3ac43656e5e69856a3074c1c46fb492de664b9f92e048b657ee232cc40cbfa480c78466898362830b3b00834482e48c8e784a59ba07a5a07b20f8cc784b83749f4635a65aeef0bf561ceb6d61576b9413ade84c75f0843fd5578f92df3b3e013ab5231fa0c98d5d6a39f85c203d0e1c733a78401402e7f4c28d8b18cb0ecd7f7e5de0300cdf35600f403589eb310ecddb7cf1b862c63326e6c09958a710646dc99ee5006ebbd076c0f293140d28c8fc8dffb1f71a8a671324ae78a95f004c108f14e4d6b442622a7ba3ff364cd96b62ebe095193264f38ad82607e6ff504758452cc89dab80516dd1c8dad2b83eaa4af57851b7fdfdc7745fbd349ee1bf61d59e61756a98a291db71cc867143821e32431d3f48471652c9edb6eb1b0e392d422ae13c09ebdfbea35350d96c36c019022e76900afcb53ca9ad5ab07172c5858f76ab170c01580ce7660701022fe9c6c5a692e852702394d25bcfe411ddcbf0aee02c8d8058f20b066fcc6ad4fb8f7e4caf22c44cee5092af2ea638b243c3a5a8730e8df91385686f3398d40fe73898b1562b2eda6f22086dfdb732e978dbc3a5dbb1494f59140e0013231eb047ce80bcb608fe222661cd1a74278d8faf476433ffec2eb2b1e4fee4f9ea220f91a6e4f28199a209bc3b44d5831e2afdc6c63fd2170675b7be3ce6327fa0ca2bdb28f6464a9f5038a3ee116d92324e1c64b83b330a6f5eaf57fc72a020ff948f40b00ac7e61cd20725eef07cdeb00fce3837e9fb3107cf7bbdfd925fa2a0621f33374b5976035936792878301b87b02c9580c01c34be6e35e26e7f8b3473599577cf720a70f359d15ce51703d945dfa7126739cb895bd779022d2fb0f9898e579785e1f71fb4227a6b45c443a3bef36ed1178c60ef700f90ed7a08dba9f0026ea4854c88ca8d393ed3b3f8e4294cdc286fb4839cb4c8e93cffc7269d28c5fa474de847c8e66b89ddc56ed0b52e41c75b67f5588a7c05178fc9d8210e1e9c14891fd5f94090aee9854d60a8d9826e0e3c04890783fa3b712d41740c2ab9252b8f38e9b729de865c0f2ba14316701f869de92760d5411935448677e00d8374858b56148df1a6c245d52c08595ac764cc91d6c09d9a942db190a93b702bb41d78fe4a9b2310120f3f049adc27710e2e831150110b1df569333817ba63697a3c47bbfcd2ead329a23c43bb04abce7e6990a76615a4b4779f8829938d1ba325602e7616ce5b878fb35449d697dc55f146c7c86a399b8dfc7d52935bfd85fa210ec7a94161fc4e9ce107d26fa853533913940d5686705ef70d8b02d62a8e02c05379ee421c18795fa75777594f0eef32760f2c412fc8854199118879202161f91f9447f096703f819e05b004f02d892b7a43d7bf6c47093cc167b07bd31a8b3c337cb24d37076369fedbc4b763a25e423c0f3f2878407724b82006c7c75c0c444b027f3bad5079f48fd2026d7685b7f24d24b7c21706442164cc81adbbee3fc060f197b9e78418ae827def146a6332de34b4b21e2f055e120054f654c9d96f92dbb7b8c60570f44df92bc3d8a04cee21fc0cccfbfdd9b386d90c5c5d64f24da01c8c031a7109468b779a75c5d4c933c3588a460840b87967cec7da78487a2cd30b42371728242ff9ede5b31cccf05c4238b92d605760fc4792f036c81e67500be0fa00fc0e300cecc53da8a152bf71f77dc715a0ca5482a06b2ff01633a4a7871a00a3bb722b267a8b90111d15aa27cfbf1048d263e5822158ccf83c1e7b70160ffc25ffde9abe33866014afc9a295fd6f494faa3415a001fbfe631f7c2f4ad3d83d10a32f2d2b000b321a78671bef2f1134cf9523b65c0252779e6696fae6441a20baff895792e95906eb35dd30ff27916a22897f8546b4f919097ceb36ec1c294eb52983d555ed02d9c04ce004884952b57e4bad4c7c0e3103b80c323841fcf59183ef9898fec740b1ce91076e8b8b10a25e53acbdfba2ae65b9246912059d9e426972ff9b002236444a83005086726a682cc4f750633a99aac9524bdf6b4ae72415014090d0a65b5b7ee1ee3b82443b47c5b0db28cb04811f45116c82b343257118c95475f7ccf1631ad91d75ebb822a8b9256279c9004f737c932259efcdcf7257575000b664b01908df9cb25852f5ffdf15c07fa1af0783c1400bfc95bda2f1ff89f4387aad5183349487ad7d95ec2982e0e0a22dbb9924bace946f03e6ec060a5b85062fa7de48af2ff921dacdc8c5c446048dc72a4cf52493d26e03a23d317b29f7c6d446e6a81f8c1ad31c99d0bf982590a08bcc444a9e3eba6696e22a09cf90f416752908220b79aeb5fbc8244d64e77cbd8eee39cb864cb2102661dda8669bde208308ff6d36170a88ac7f2afff03018f27098017f396280f0809419aef218ced54a2a3b4e49567c3ebfc81f30d643df93acacd77f6d8d0e0e0c211294cc23ddc7969b61ee3c5d2e648ecf15b837c8d8af4058ed178518267decb231c80523067c53d6747c69a98217fc3240909c247fe96715ed673d8489a61c2f3fc1b86ee14198b8a973f0307b59c4a383e50a24e85d9532b90cb8e59a1af6f539103405e440301b002c0a3794bbdf57bdfdda912bc14f5b4134098d05d166704f0125a82f4b51de9dc36ce936f24323bc922d8ce25519b47d019a5ac87b02b261bc841cf58454bc06a1c9f08ddfa37ac6580e0bdb3ae824098e1c63da390ccccfc147fe425b363495e1fc17366c28ca17018fb7242c8697f1a0b50c22dbe041781a87f4ee85638e6c80e8b4006b90f402fffddf55fb71431ff1f85e671575642a247f296fab9cffeeda448dc4c6aa5675d69acd05e01babb02ad64fe232f8763765dae120344b14e739e5ff204882c5b46bbd585967166c62a5ac5706c9692ec0f58c2b4d303d14736c4550add2cb86464e0c436646c6f66e6afffc87fe7d111ef9be0f792ae1c9b6b4340c4a3f805fa42c3cbc942d80981c3a6b76142779e9bbc74815154c3d7bff4e949f9320248e0eda4da7f5da0606cd9bab50664e874ef9b427757c976323fb5d38088e2cc0cf7ddcd57b9e3a5248d2f113a096ed225adad24239c8bc6b3a6f5d265c8543749f0d2b7a24c0f93d3789c4779fd4662e9d5e5af5b5d01c6cf93a588fc6d5487bf569fa040ec5fee37fe9855a4281092c15ffbb169c4522439ba9c3bbddde5cdd22e43b39bfbb7163a021809bc9d260056e52df98e1f7c5f9b2409bd9f48e88642278e2fa1bbb3e44c782105bcb55bdece6b77b6f903c3041f31fb93eface1f4e0b2006f1f773ac23909362f856729b360914c308ee945949b10aa8072ab4f1e312753a765fc02cc5fff4141c85b8ed1c476cbb429c3533432ea14ca2c214be100db07be1030541b4c376d1d66be3ffbd0361c3fbf5dbe6a080adafcfff1ddb71731ff5721a300e803f050ded2affcc8070e89a2068229413000c0982eb1de4f525391607aa9c584a966a52e5f71edb49ed4623c3793123a113f4afdd9b06d59e7fc8902b128a4e4b78fad75e45f7249464846b27f04115ba19b506e117c29fc51a70c0afed64d5860bc98b6ec6fa92482fd167ad9d4d10f586092ab2fccafb70fbb00276709380ce74cad646b23d76deaa8d56ab8e6f3571c92215b080f21e104f0b409c883052af03c93fe200a3119bc078049e3cb686b73e1ae2e7edaecf6835bdf0fa5ad5cd3b6f357b10946a6b767c1b3846e9106caec4c8c656c4992587a5f98fafd6023dbbcf1107d2189dfa613b810f26efd8f337f03c8146e94a24c32e123c851f60d00e1bc73836a9587f9cd370bbb8a253d894ee7f781b0193fb68ce31674641656b23f366cd858c4fb0fa4f0749a00580a6047de1aaefbda353b7835c0214d9067effb81251a3adb15c6752917af2d1c58ba086539d877ee851a5f99aacc0005b100366de4fc0a160a6892305f96a43ee1644c9bb16e0abe5b4666020e041fa7f1afe5e65d81b0841bc325679bb3e62334dfee6c202c4e7bfd38592b49ced939355b4f6693a387afdcefeff52d9715bc9b3bbd82293df1ebbf92da2999bf5c06fef53b5fcecd97d0bcbc34e9459a007812c0fd796bb9eeabd7f6ee1f1cf4a7c11e6351fca1f9d5d35d164e39b969863f32356bf8a03ce119b482827f40080c8eb24aa0b85cc44439d373051918216f19b13c764bad9c46b975ec0870fb1c48a68577ca5264fb360b627550cccfa5190a2d56ac158420db6e7f894ed0182b1a04e74b0a25e54853d2192b3a3f56a554565874587bb6311651c100b06fdf10dd7af3977b0b34f97e88f87f09f5d620720b000058fef4d3fb01985ee18e94bad6d7fedcc09e71254ce82e19291c98a1e6c3f3d588fcef3e113badc75ed7c8fa10cca044090e9af8cf7420875bc6e489f5e5861406482ad66e8b200505259ca3e6a5b73b4e12ba630ab9df3d2f9af51f646b430c04e914402ba89337e318e627d291819effc9a40d065b6f57969612f797d0f63aa3cb638a983fab0d471dee9c7fe9f8f9cc0f00cb971bdeca0fa9bc5c4f00dc8702d3803ffea373f6b9fd93dc1992e9d335ca84b125b87bd845e792234be9d696fa5fae7513bf17440db8729c82130394b58139b57edeb4a9e99d52ca5898d34e727bb1fe4aae3e6e8ff9cf9b1fb370cdd986fa0f0a42b31c6fca900e4ffdc8868e9a44cafb1356ed940d7934a87f92f331310d4b2205306fa68cfb4fc00fc97d5e52c0e5979c57e4f0cf1dd0bc9c08f504c06f01fc226f6dfdfd9b7bb6efd869f58bfcdf0221e929a64c2ceb9b518379aae57d72c11ade9c9e2530cc20f8246e0581130e4e3b26e1510f726bfdd88f26ca4deec6c484ced9270481646ec071bf255ed79fde125946d4a8ee834c4d6a98a8881c9016a2fe2d9ccaacf115392b094c2f6eee6f4d7e5bbff0f4938b57e1738608a44f593675008423a6b7e13547276fdeb3e498d2b8addb7644dbb6f6f7e46c3aa079f8b7692f1b8521fdbc4085f8ceb7bfb11de254170b6220d206b1a7bb6c89d31124cfa784fbc55bdf0ebe9bded4bfe541152e2da7cbccd005b4a157599dd77593242468cc04c6bc154240f68d6476b732c23e02b70d8d8546ab8190a50dc9f98ad42576eafacfa5c6f514837cc9cc694c7e9b5627d63f3d9737fcdd815c9fc2fcd9c9a67f23ba2a9580efffdb37b7e76ab883ba3cdcc8a89c0f7d72c89cbcb56edcb287dadbdb83097ffd41e47efffdaa41ec1c887c8606b9392a0527059196b83240882579783a0d9f1ac38ca0f39ad509af3e2120b87c7e2796261991485099ac9fac334ebcb3e53a6dc3ed02c16c71568231755ebdffc1ad537bb88aba5c59ae5d9ee353b6cdb65bc65a381c63c253381211e6f3fad81cf6118c9fcb17e06edb6efa451edb26dacaae3add5e05c8fdf8e1188a367045723cc3b1d6af12ca09fb9ac74550b3ab4f38a8ade2020e9bd6864bdf321e3168c0130030383848271d3dbe11af26c16ae893be56a625686401ac448163c200e0915fff6a8ffe26bca92969c379d984712561aaeb976cbe469474161f0485733e38e637e530a14791fb2d4fcdb128b0f46661c3ef6cbd3e6585c74001e4f0b46592680fac55c3ccc4f5478afcadcc96e049e0a5627845e6e6ca104f8ba62853f639df1920999fbb932cf2ca5de7663bd809076b2af33829d8dff0ca758282bf9143c4ece0642990cc7c7c123448333f456e6a67856dc8f8164f311e429bcb2bbbe4a6289739e837a1375d13c5e6338bb8a3497fcfbfc3439cbf92084a01cb1e655eca0d3f451de6670c1bc11f03f84191dab76cdf8f52b9dcd0c4497affbbe7f763e76eed4c8c282e952da31acde278d211a72352f01be79fb404e4a7d5f5092284635ab9579ea5bb63125fc3d92863cfdb4e7ebd5266056d7375701a3f428dcb73c760699c35ea82e91cbf26e461bc65bb449b3debc3b5d9e201ab80459b793c04b353829560fbcc8d07893a94d79fc2ba73dd6dc7d4d6cd65893a3c21e21ae2e3a1e085857bed1785ba63e4e5b824d72550c4e1332ab8e48209f177de976488a21a8e5b30b67ea274b810c01df51264d98a740f80078ad4feec73cf0fa631bfedc094f713c7958d9613ce3bb88e76c42dfc025293cbbfc444c8298d8327dcbf0dc7ec00d9f30624be92c8e47a300b1f4f38b180022f6d1a4116b1032958c62423242288f63173904764ba5c732682636530557a372619cdea0922c8b25d7fd933f7649fd88152120153956e3f6fcf965394c8324d421f8a3191cccf52d19e40cc6528510a31566e6f83dce5e8e8caf58b15a82a3e7d021f9526e9c56a74f8421cce1f25bb420205cf16cdf1e7fe44098952e099679f1b6c9c2a111e80e6ddba50699400c000809f00787d5e0cce39f375fb9e7b61733b520e0b486a3f3f9b3eb982ed2fd6b0ed4573aeba6568d2769137dfe5355972e5caf470f9c1cfcc8f8fbee7d8380e190626c437fea341da0c2fd3d31b66947f0dd166a2aa3055c6f6ca5ab3e6cddc9529cc942b7bc6cce75df6b03b30864d700ac6ddd09935efbd7941e0578961e22cc379b3da70ea315d3e9e1987498170c945a7ed03d03870200e3f81e6ddba907533f28f00acc98bc18e1ddbc7af5db72e7677715dab80bf90de230022ab95ac6416cceda2b4c47c1752924b0de33f4f12dd8598bf81346f28ec73513db321e0eddfcf5150a88933e741f6366786a09c229eaebc78d8732403adcf7acab6358a8b3c67b5401a234e808933061480c573833b3b32f41b2759bd66ddd0ce9ddb133c870d610d34cf3684ac02e0490077154004efb8f0cd3bfc0e4c4e47b12ffab6d4de0965932f8ccc309296fca3b42d937351242d037ff0c2c343b3d2913786cd6ac014cddf389f6e48b8af2253757919a6e183e43c79db5e44a6641d072f8f74320acbc32906f2663c568998ce4b32fded34432c392e9edb8e938feaf0cacfda9e92227cf0bd6f2912f70f685e4d0cfd0d21cf71247701c83d1f59befca9c9ebd7f755817ccccf5fa74c2ca35211f354b606006796b1f68f697893521cf5c4e546fee8e562fee41f0dd216293ff12dcfc385ef2363b945983fb1a02cf5e428a7a831c1edc99fd7cf247d38f2956578b0519fe0885432859516e81e53c2710b3a5d3919999f4775eddabeea73cffc7e72eea6691ecdacacf308809f02f8afdce800f893b79ebb9d52b8df76648a263c644219bde3cde9c120c1e4622a6012fb9ad989e358d5769cfc016f0445b44db6021b151b7fa3db9a4dfb3783b797b75502af15fd57546a98bc5261f827fd3a768f85a31bcb4049cb81cbb0be26fdf7e8c3dbb1704e5be62925333f01288170f9a56f2e1af8f35fc8b1749ff34032dc99333d006d05ac59b3d6f305a48d5fd2f319532ae81e53825c0ab21d6ed6f4c31b58f5d4c0dcf4021dff1f11affdf36065a3a1445c9b6186a0c0c6b4ac121236c3018d216fe94598bf700b0a697d9759f0abc54106f5f867a3c7f1b4370b5902e2d804fd7ec6940a4e7d7557668706057f57ad5e3b5450fb03397934af00f84f64585a4882b3de70ca0011af141bc84201a46f11d2be0063019815001bdb1e041b79261a89ef36f823c532c8021918bf21f317a9d39afd94b988b01f0a41abe44c82d02b544653e818ed4e017db03f090005cbce5ebdd67230cbb8cac52900649d8a471fde8149134a99100d93288af0aeb72f69e8bd4f817ba0793433e415007bd120b0200db6f46fee59b172a5dbce18b43c4dcbf2f3d9532b9834a1ec18dc8c207f97811b7ed08993e29cd8e66980730ca7166afd6c459a4cd60060e6cfe1f8cbc92d3123234ffa16e1905a8c084328062eb0c75dd96db95a5c146228c72a09e7f873a603396562ca0601471dde81d38f77cb7ef9b00396af78667fc14d3f80e6cdbd7932e4150000f01f00ee2d900fa7be667147b51a3fd12889f193ccbc69932ae868938e188e00744b80727986003b4570e1b5fe20678206545e54eba7e7e1373ae4357e414726b1918bf1f20abbccc56711f4598a698125e2cfefb938b1f5dc86351ada3208cb402437df97d1a7daaae8e92ee38485c1b25f221ec90faad52ade7efe318d0b48867ba1793317e4160044b40d05438301e0970f3c30202b4deb8ca4b1eeed2963724fd973bc784b397c5c331cc14426865d97499e70a8c79859b56021624ecd97c02d45a9be19666915f3b7284f737c2fe3431c1787f4636986d35a2bd27b087ec5710412c3c573db71d4618d6376d8d927db552e010f2e7da0a8e90f003f30bc990b8a580000f0ef28b855f86d6f3d6b2c5f6b9c87f901dde947cc6cc321e34bf63791bbd2595a69525ab3a967afc5360398b4d5d563fc563051124fa76610d17dc2b2c953e581d0fc990b25ff67ee6252fa301f2a41fc0800cf6c07891d852e1dd38fb7533436f777da7fdeec369c7d4ae398fdb4fedef5e21ebafc9237150dfaff39344fe6864202c0489adb8ae40580af7df59aadb1e8e07acccf1a1f849202a6f556d05ee1c18190d6808b1f676610db4a893c41519739334cb31bd26566e617296c2c3d0b846cc858c6cfc9fc39116c5c85443b1f3ac9e534c5fcf28bc3dc290af2969341709b828c00d62f9c6fc92d15c29a02e3c79670c2c20e541a9cf399d6945209b8e9862f6d2dd04486db8a687fa0b805006801f0c32219affec2677b37f489e38d1b697efb4653d6d443ca987a48c5b3d9dc1661e729f799decdd978a0a57e8d49e53a849789091a3f0ade2aef97ffadbeddd0b4d6cf983fb3c06b309e0d8ba1fc6d4a43c52edc93ec5ff34f86fe32ced6d1a8c7c45e210eb969c0a50580571fd9a1eff8cb820fff1083b07e7d5ff586eb3e57e4b04f40f36061655c580010d100805b1144d46685335e7ffceea8566bccfc4602bb54fafbfc396de8eda958ebc0fa02d86166bfbb13815c28b0d10494a0591b105d119a8ce74929456a97ace536c1248dd0c999a425d0bae60853cf3b6b4b0b03492f369fb01ced190f22ad4ea920f7032c3cac1d6f5e926cb96711b45154c39fbdf5e4dd059b1a01b8d5f0622168c6020011dd06e0962279b7f46fee59baf497034aa50c3ac9b121ff85f1dcce9a52c6d8ce12dc7c8c3c61200ffb9083ad6fc4d10f3d0dda0cf30752bd7e91822043c1550432668ce193a1cd998bcfd4ee0c45342901e22423995fec1a3569b84e76ecdb4dc0763c8ce99f608d4de929e3b52967fcb9da8226099d532e030f3db474a08965bf5b0c0f1686a6040023016063918c17fed1996377ecdc15b320fc357a9f22589b8308bd3d654ced2dc3ed9797c732931d60b1746bbcb72c44b2436b346048448e55f296df34b3e4101a0d1304cc5f0895a252c343430c742246acca955f9d340eec8127caa675db8279f7a97e7fdcc24e2c9893eef58fd511b471dbf65dd1fb2f3ebba8e36f230a2a5f09b9775f26c5f42ba5be08e0a3451038fd8cb336dd76fbdd872ac5f1fe5e6d024d61da07f0c4b38358bbb92a24b6cb6e9d3672d0c99cfa234fb711669e15320060ad057f302351873dab8f2d1088b284a2b7f8b0d7d9ee4ad3892291c63ef788551060508fecbb880cf9925fbf3b9108e63c052308edb44909dc18079dd706ced8be084ef921aedb8d8bdf0f09fd2dfebaef1494edf288657a2f8d9cea7139b6fddc7304c8b57b5b12c9facc7a3ff7934da77130e7868048e1c4451d78db19dd48024afde1bf78efbb2ed8f4ab07fffbd0b4140de09f88e8caf0a14a3a7ba30eb4c2020080ef02585624e37dbff8d9a1cb962ddb933c1570da3c2910841fcd9fdd86de09253d9822cc9788a701fe6ec248ac137ac4c84e2162c6d037c83a31a94091bc2126207249841247838c2346b13b3181f9bd330a957158f15426c6fc64ebf096aba440b36d65e1e142a1787994b1f58406b9bc11445d10c203413db1769836320e41f95e3fdab13202554a162f0d44992c0ce0211189f43c7600e9e3d87824382fc81e06c03859ca1381586ccecf9bd586b35f330621c4e83785f9cb658565cb1eddd304f32f83e6b9a6a1250280889e027053d1fc6f3efb756376ece0a980e4f474ad2f1f75b42bcc9eda86b15d254b4d3126910cc2d15f821823823855d71db4e1112d09cfb1255ec748962059f85824c5d1575612f173737868e4eaf3bccd4202c9aceeaf611405b8a8c1b885104189f3fb946da7bdc68a851da7970c27da0951a72cdf355ff83282fa8c6c72fd67573959400a9e574630454a584acabf2056f1b16d822ec8096129d074d9aebd2071d9ac8823717d67ea570e512260724f19a72ceec4f8b13eeb50f0378df90160dbf69dd17b2e7a7d5c8264879b0ccf350dadb200002d00be5f34f33b2e3c670b453548d7499d3ef481f4d2e0ac291554ca0a11f38f65e2f05c41416cfcd75a035a5844de3bc7d0e4a8c6d324b63eae470a0fb089cacce99bf5f0f0d2c8dbb310956b8727886cdbf8b76f927b72c63cb4e70f5a6e158c270427c8b9cae428386612c251d423ad0f37c50a98c2c93e3146ca0673d9645c8fd1d852caf03b1de6190a478262612ac68ebff8ce3cd987fa9932c8d9b30c89471a686f533869612716cf0dcef84300750897a886cb2e3e6f4b7a8a86f07d34a16c43689900304b113702585b24ff6f1e7b64ca2f7e71efee920daf841818518f7c14bc9f3ba30d33a65404d131a3b9399d230cc15411e0cc6316408229025cddea02c7ea1b0101c70c5a4e98fa23975e9e3bef1f472eea1516883cadd6758bbeefcfe7639ecb02cade78ebb7533f71f7d7bb25d2b07c38cbc0bee7a915d7cbc7b393cc6acb5284785f8b76789a5930a07ec887a68aa98c98222a1e5b2510b6c4a0b4df8efb584ce55d33d912103123e2233b42e277d2a24e9c566fa34f1dc607b4d7ffbefbeeddfdd4138f4ea99f3215d602b8b19965bf105ae204f40a54ead300feae2842bffddddaead4d55c1b5200001d57494441546953f561a509cc9ff640be7b6cf93eacdf5c8575ee9042e4b67fc5b4a3d36672e30de7f50588aecb9fcb3aad0447ace63c395d34599397ac494f3e03c0f52d97e339d41c6fd84c0e7f83b702d8fcf1cb85571fab604a4ae7090112f945fbc4df901cbc138765ffc6cae1746cb2cbba9457b7279f649f33c38bb2d889e7d204824714247d1f2cd448beb3f314c231f33a70d159e3208a0a1a1e3e88435f5f5ff5dcd30ecf72106f1a7c86883e572fc1483901257c0bc0dd45331fb7785665fffefdf5edff905083d70be77460f2c40ad8f48e4c2498674603563339e6176545523338eb419ade9ed232efedb5db227c1400bb158c26135303c9145c07549cf981d86e3519d8e4982e60eae0c3cf22914722a0d3b9d42471e7df82eb59dcb84359180fdf19ebf23b66e31a59c0ba9b84fc299aad52f4b36d93ed923acc2fea37324358447a0c222b505cad3c56f366b7e39c84387f95fa230efb07f75393cc7f37346fb5145a2e00886803806f02e82b5ac6673f75657fa85a28f6255de88eed543872661b2676eb43442c63045ac9deb063cb628d02be7886dbe418163e3189e3f7036c598b08e2159c2859ccfa1d2c810b229479c48d4608da63d3c2b294156e4ed03944955d0a6486f3d390c49bd7bfecd442580f09a3e0b468f0cc634437f797093de76320246dc7595c5d988d5d71b0d33e5f68d82f96f9c5d8989f726c18d1d9875670fa715d6e039a6c53ace56910e1ea7ff8587fe6e471e803f04dc35b2d85e1b00040447701b8be68fe9bbe7ddd94a54b7f39505229011b48e8fc80b97a7bca387c461b7ac689edc38231dc204b028233fbc968c9485440805b52543e330b0d2897f998c0bdb801f38ecf288877a058b6147ac9f90934ae8a5c5ba499ed9883f1158e3270db249328bf7fb87d411e974232b4f00df03be5972fc499c3df2eddf90c6cbbdaf697e34cefde3eb64a2ceec10a0bf935da7b12f95c088ba3bf1a24861ab30fad60c9abba70a4b9d2db61efa7f5fe06502e2b3cf8e0d2811fdcfaf5a2f37e00b8def054cba1e53e005bb0525300fc0bf4d56285e091c7575567cd9c5909ab4c647ee9b415b0797b0d2bd70e62e3d69ad300d6bc17cb7da25c69b23a026582f6e7ef4e00e859b5bda22a81011c93ba39a60c7491792cc15b5c180ff34cc57170dad1df25e9df5128ff92651ec6cbe220fa9619067cffa0580674e9a4e010e5880171be14d936b24b98b61fe05ffeea070071a14adc4604690cc4ea94ce3efd506cf105d7e1ac1a00983fbb1da71fe798dfd62da1012ba812b066f5baeaf96f38b219d3ff0e009711d1e62c89f3fa00864d001864ce00701d808579eb6158b96a7bd4dddd6d2d95c4da13185fa6dfb337c2ef9e1fc4da4d55439481a34a68006fae2abdf19e53d067b8486a20f88c10966bbf5bee50f64e3d27388460088895f3bb32c9d6ed7f474cb084b8bbb673813e13a40a24c3548ea1f999c08fa7184aa421cee7fa49b6c7eba74050295e989463eda591d301666a12979af2ca80b42242e1abdf1d3baf03e79c3236d1ec4f7e100702b0fbc5ddd11f9cd0db8c95bd1cc0fb88e8175933bc149c80160ce25f6ba68c73df78caf6a1aa3e50386920c279b05fbf4e33a6b384938feac41133da502919335ae4f518178e41f50943ce931f56e418dd5fc3b64ccc0c6d894cceb379be6a2ae3834e01849689dcb7ca6844e29d8bb853264e4136ce6f1308769d5c5929a65cdd62b9d4f50d3cadef8480ed058ff9e534cb319c910ac132af6ba3c0cf3c92a4ec4dad6cbb39abbfb4ca4fa557dfb681059992ab073a457b1bb0e4d55db8e8ac7196f98b0001a85587f0ce0b5f57f4686f86afe561fe2230ac02000088e83a005f2d9affb967574cbafa0b57f553ecfad6fc651d3bbf030b0f6bc3b8ae12bc33dfc0c4e59c7d0a4eb349e6b6bc4524fe9263ce4083e9acc2921044ef69cda06c6f7e2a184ab63f12f920b47378c885ec2bf993998a91b551133e4ffb1647d83eaf3dfcbf8821b07d2bfa0d88b547c801713128db23bce64f76ba10e93f1e83eb2ee0e98f132356e8c209627f5ea42fa039f3c43178cb1ff8de7e0a7f34a03b8d6d84af5e7b55ffea552b27d54f5d17be6a7867586158a700b612a5e601f8128037e5ce6ce01b37debeebfc0bfe687c489c31fcec7fe9efd76faee2d97583d8b8ad26184c98b749ebd024344aa0ed3c660fbf932bcf1166e0bc634226510fb86c9dde1e78c27371181a56ae1e8fb1052e0e5f02ef6cf3f1126631a7b5f5f8fe0ae937f04c72af9f443badd38ff1146321fa512e35da71f07914768fbe103548c8a3df2a91df3c576e6d5fd2f1bc59ed38e5e84e2c3ec245f8c5482823d9974ac0dd77dfb9eb131f7c7b913bfd187e0ce08344f44cde8c2f291f805791526703b816c0a2420500b8eb9e5fed3df1c413ba6a29479034424d32c3dec1084f3c3b88e7d70f9a77fe9cdb9b0f07449634a7f5d27a042c9826743e09c694b1063ed3f98cc23c1fc9a3ab842674f35ff879e118d3e2c6dfe16f70f2fbd39f2387d1914ee83063c122190a482f1f098fbac5555b5e912898f173b8bb0c9e70e3b461c427e7f08489b37a4e5cd489b35f332635b63f0be373924a197874d9637b2f7efb9262e7826b781ac0878828f3ed3e125eb202000094529702b80640d13dd0f8e5af560c1e71e4dcf6281002f5062cfece102b80dfafda8f551b86b06b2072d300b1a26009c77ac0e131724c40588d6cf27942836c591ce3afd3b8e98823fef8d483cbb35ad673fe715d4a3bbf6c1ec7f81c9fefba213eb5f0188971b7ef92ad2457b7c0d13269e00c9569c23ccaa58b099920bd27f81284965eed51eee45e727940c0e489651c3fbf13679ce85fdd9dbacc97029ca7545278e6d9e706fff89ca38a5ce5cd3000e00a22fa66d1025ed202000094529f03f0a966ca78ec091d2e9c644e4a6834904cc81bb654f1ccda21acdb3ce433be640840ec160cd248a6f718d237937d8d0f78ce4361057014a2f9ead09782c672853cafc09a02023f290cccfb040798c4c3fa130221e531bcc923660a961bdc3267d85ed9a7c24a11e3a3bf4b8b88c4f38049c9e12b52f9c236101a803ec6ebb58b3bb1704ef14d3df27549011b366cac9e7bda61cd2cf701c05544f4e9660a381804400f807f06f0ee66caf9ff4f6facf54e9a5496713a2150c273b2242412194a7c6cc57ebcb061087b06c906004946927375fd28be342589dfbe0b359d2c57e601c4d299abc769623117372f124d766f879cb33e9cd07108311e1e1326302c92d2c9f79ee0e3cc294b9836bf96324ec8face4329544042d0b01c93fde2d51ba75302306e4c09c7ccebc0f94bea38faea3e8c272929a07fcbd6da99af9dd1e04ce086f06d001f26a2a2578203380804000028a51602f82700e73753ceb227d656a74d9b5a09a703401af307df28feee85be2a9e5f3f84f5fd554b942efcd645933961c00c49f6bdcf145288b8ba1c33717a9197893cf271f3b61bdb3293e7c5ee16469520048232207049887790cc184e71647bb840fe1aee67b0f57bf3f4c01a62411b0851ae88b77a43f677287039b0c8d6a7037b4e58d88163e7f9a7f7c6a839237913f4651eeb376cac9efbfaa635ff5d003e4a44cb9b2ce7e0100000a094fa03005f04f0da66cab9ffe11583470a9f80875d8cc1f941823759402d027ebb623f56f70d61f75e829c0703f208f290e97ded1a49935c323c9886fd601a4ee40283fc433a384d285c9821e3cced6b55594e44c67ce7bf52034be1c0cb6ed2140fcaf2ad117f0545f8dbacb0747993a7064eca84169610209e35c6e3203ac48c4bcfd812161fd989734f19133bb73f9156624e80781e05bdb577e533cf373be7078087015c4944bf6cb21c000791000000a5d45b007c014d440a02c09d3f7978ef09279cd0c5bbc90024307ffc61bd9610016b376bdfc09a8d2e1029ae3985b614ef42b357fa055cfa04cfbc79ee96eba4e0e05d8282c1acc673657a0eba20ba4f5a2fd20497752732a96c1b5c5afbca2e6ff218840ec6606a043f7d6839e93f09530205fb0c2c70180bd11720854587b7e1c4459d38faf0388f26327f03e064e512b0ecb1a6bdfd808ef4fb1811e5bad2bb1e1c5402000094527f01e0f300a63753ced7bf75fbaef3cebb603c54b89c13e22b893019c2263ef1ec7eacde58c5961d35a7c92cb1298f99b8646fbe4c10f3fa24cfbda857323a3be1529724037c49303063620583931236bf7738a928df32a06448f2cbf1fc10c92b02ce59e74f93ecc8585c74a08f0aead6594d5da65c6e195b2e1a476769010a33a694b1f8f00efce109e9fc59580050849ffce4ae66d7f9016003804f10d1cd4d96e3c1412700004029f57e00ff00a0a94ebdecf28ff5ffcd473f3db9ade2766f3990ea2165cc299d16760e4478eaf941acd9388481bd11e4b6534524d6d17d46b33c2d359fd06a71df80af29ad769542cb94ede6d842939a42bd138e78e390141490e5b92dd0d627e1501578270907bfad1623d997a23c2790186fabd483fc8ef1fdcd407e1f4a27e2f8b1251c7d583b4e3da60bbd3dc93eb9b471af07fcba5a1dc2d7aebdaaffe61bfe6972fd1c0d611780bf25a2a6c2e493e0a0140000a094fa0880bf07d0d49c6aee110bb6def5d387278e1f37ae248ffee6b9ac207b1fea30bf24649e16ac5a3f2898d851b60917b03bd524915a4d28df3193dab4beb7ded7ba82018526678de8e12a962c6dc4a0774a119c392d0282ecde023e44c5768edcec2435bebfa4e8f5991434728f8162fcc4f1e5c1dc5bd625c7c6abc70827a580c54774e0f8051d58d4e09cfee41ff5d39614b06bd7eee89d17be6e7b93e1bd003008e09344747593e524c2412b00004029f5490057b5a2ac0797adaace993db35213274ca432789d268584cdb07cf52056f555b16e5355686a5fbb69e799fe6eef9817ae71f21884f38915053bc796df11686297c65a16924124f348ed4d700143009276027a792c93b2e92ebd7b4868bf2bc8a627217ea5d009eae1e002e14e8895cb96c0bc596d78d5dc769c7c54fa0d3d31c66fe0e893492b65e085179aded22be15344f4f72d2a2b0607b5000000a5d4df01682a1882e17b3fb87760c99253c7ba9963008d04439d97fcf8c9e7f663755f15ebb7543da6b14c1773baf9cc126352e83ef6cc62c1004271c3ad20f8cb7c04d8f9b490458e015980704090600a8713b9e5344fb0486b2159b8b090b061bde68dcbef32788ccfe9441090b2168b101c8a30777a1b8e32e67e3d481cbe8cda5f21c2834b970ebcefe2b30a47ae06f03922fa4c8bca4a849783002803f80c9a8c1664f8bf7ff9becd9ffaec1727b777b4c7da5a44f3c71e9b1f8f3fa30541dfd621adf9594791d3e0e9ccc2cc1b04e998bfce218880e984550058ad993c4d90bfc9327fb83f016021e12f6f4a61197affa543939f2b2e9385179488fce3f4814f46d601828a9473541adc0e9bd68e8573da70da71d91cf06942bf11ecdfbf9faefefcc7fa9b3cc947c25500fe8e886a2d2a2f110e7a01005821f069b4c8120080877fb3a63a63c6b44a14f9c49a0499983fe13d41af18bcd057d5a7122b9f8128600a56cd9e2667ed1791d3da5e7a6642df2fc01a5ac6c9784c1d4e21e477690158261442c0481f6f930e39e694fd495e2532ca2f5eafcc27fbd039085d1b8f98d9868573da71eaabb3afbce5657e8236f9d7aeebabbea9b9033c43f81cb4f61f56e6075e260280c1f8043e85261d830c37feeb8f76ffe1196fe80e970a2534140cde97c49f0080df3d3788359b740c4155eedce33a5820c8f05ec1e0cc291c8fcf26356b605d6710b823db20b4bd5baef4ad10d91e9b56fe163879b10541fe98f616d228b45a62e9346ac671ea7772b9a4307f763be6cd6cc3298bd3e7f82114d1faba0d35dcf73ff7eefed07b2f48bef42f3f0c42c7f70fdb9c3f8497950000eceac027d1e41221c3b1c79fbcf9e6effdb8b7a7674229920e39fb5f1c28e5476a4f08827f7ec310566d18c2bacd55ecdae35cf3d21cf798417055b8db4dae2c7867d8795682abdf0f3ef2ad052b3cc40ebcc42bbfc27d09f29dc7ccda52f0e321c4721d645afec179dc4382c284710a73a7b5e3a8c3dbb1786e7bddb109babdc183e43c9532b06ddbaee8b2779fb7a5894b3b42d805e0ef87cbdb9f062f3b0100d838818fa3c9602109b7dfb974cf09279e3846a9524302cb250028f9ddb65d352c7f61101bb6d6b4c3d06cfaf10482cceb99c1bcbce8826742e6f20447c87c21535330b7b668c41d75fe7b586163dd027c6848d2f97a62da110a0c00eeb871f360ced436cc9e56c109f33b30f990729d4e4e873c42800c128f3db66c4f9377f585b001c03f0ec73a7f2378590a00c0460c7e0c4d860d4b38f5b4376efada376e9ddc33617c29f57c819407f5dec77bc8513e0178fa8541acdd5cc3bacd43d62ab09a3149ab7adad53131b3ba3c461cf2b711200ae1fcddc78c4d765fc39b757fb947dfe02477dfb90b472d360237d17abb5ae1f7514f7709874f6bc31133da70fcc20ebfff326a70b15ae83fac93bf5c56d8b67d6774e507feacbf895b7a936039802fb43ac22f2bbc6c050060f70e5c892637108570f36dff3db064c9a9634b25173d964beb8b1749cc2fbde8ee8bc28b7b22ac583d88f5fd556cd852c5de41b21a56268f449e90593dcf3ec45980fc3f097e908206a18031e96cf00f33bbdfb6d8fe7b6b31b8faac40b37da06cd82281d0d951c29c43db70d8b40a5e3daf033ddd41f876335a3f43de28aae1a187960ebcffe2b35bb5bcc7f030802fb632b63f2fbcac050000de45f81134b995388449bd9377fcf09ec7baa74f9f5a91db588b9afc520dc50580af9e0840fff61a9e5b3f840dfd35f46dad62df60e4e6e4c152981f5b00211044b00d09533dd86ce431a84914117958c596126d7a4903fe0ebcd83908a2819d9d0a332757307b6a1b16cd69c3b4de74277b56128b256b90af5402d6adefabbef3ad27efdeb6b5bf275b2d99e12e0057b76a575f5178d90b00007c9ec087d1e4a12249f0d7577c66cba57ff5a149dddd635424166dea115b32f36bc67336b2642f0e4c4a2e64ebae08cfad1b44dfd61a366fab62fb6eb7d7d9d7e0222b89f224d37a1a99604372451ebb5f2072d385303edf5b1e14f8c6620dc4f79ef1654ceb2d63e6e40a16ce69c79489296766584195fc3a0d6246550a94cbc0ae17f7d04d375cbbf586ebaeeacd574b26f836807f6ec57efe66e115210000f0c94257984fab4d39dcf86ff70c2c39f5f5632be54a32f3fb91b089e0342c4310f8e27d09f219a845c0f21706d1b7a586cddbabd8bcad86fd55616ec3d7b8f65a6fe54c042ecf5b660b961eb9627b0d2071308f3f2590e63ffb17188fb6368569bd154c9d58c68c29151c7364074a190f9ecfa3f563d3fbc4871aaad52a1e7cf081810f5cf2a696d308f4197ed700b8a6d9937c5a05af1801c0600e1afd209a386db81efce8e74fec5fb0607e87173b906af6f373a7697dad2f983f85681b99b53b0722acda3084bead556cdf15a17f470d7bf691bb262b69df00ff25721180ec4fb0f8c63539055ca6e5898be81bd355c29489251c32be8c19932b9837b3cd9bcf67a5943c2495d9eca708cb573eb3ff1de71fd39192a259781ac0979a39c07338e015270000f091e397a3897b07eac1a4dec93b6ebff3a1b173e6cc6e931a3109c8fb2fcee1699a3fb1cc0c696a11f0dcfa216cdc52c5b6176bd8f162846dbbb450b08248ec03d0a889c83ec0313fff24701c0f7849b1ab5d61524f093ddd654c1a5fc6f4de32e6cd6a47b90c4873282f7548a1d3305ddd071a9422bcb07aedd0bbdebe646018e6f90c3f06f095a247770f27bc22050000be7ce4afcd675860de82a3fa6fb8f9471367ce9c5e7127df00cceceec00b7faedfc8ec6fc4fca93d5e87e1d66caa62f3f62ab6ed8cb073a086dd7b22ecda43d8b9bb66d7faa5df8019717c7709e3c794d03da68409634b38647c09530ea9e0b0a96da0586da67d14b42f036465fcd464c143a5086bd76da85e7ee9f9db9f7fe6f7cdeed7af075f85beb527f7a51d07025eb102804129f53e00ef470be305429837ffa8fe6fdc7457cfac5933da80926024c9f0f9e7fb490f8b30bf972c406ba846e8df5ec3b65d35ec34cec5f163b5193f7962196d1515cb4408a733715ceb4cc393b31435fb13187ff59a75431f7cef5b760c33e32f87beab6fd8afeb6a065ef1020000df4a7c199ab89a3c0b4ce899b8eb7b773cd079c41147b697cb6561010048d0970d054016cb80df3518867a4227f5710217fb222c107039357f5eadefa1221e2805d46a353cfbec738397fcd969fb76eedcde9230f13a7007807fa161bea8b315302a000c28a5a60078aff94c1beefabe73ebcf074e3ae935633a3b3b94dd7168ff4b8618f327325f3c5366cd5fef7d62a12a214d8a6ecfa9f963b3a346e9e51793af5c06f6ed1da4471efdd59ef7bdab657bf4eb411f80eb015c4f449b0f407d4dc3a800084029753e804b01bcf940d477f987afda7ad13b2f9d3869524fc95de1edded7ed3d6a9ca659cd9ff8cab35c740a9d266925c3219159f3532ede8f09c65209d8ba757bf4fdefddb0fdfa2f7fbad923b9b2c2dd00be4944771da0fa5a02a30220019452d301bcc77c661d883a27f54ede71fd777edcb968d1a28e8e8e76154509530220bbd99f41f31733fbe38ecb54cd9f638ae2a52960f6974bc0fe7d83f4f4f2e5fb3f70e979fb86d1a31fc25a00df02f02d22da7080ea6c198c0a803aa0943a0bc0c500de7e20ebfdf38b3fb8e52fdef3819ee9d3a756caa51272851a9b1799983f8fd99f30c9a64010f8c82538351bd4c5d184594129855aad860d1b36566fb9e9cb3b6ebdf9cbc311b5570fbe0fe04622fad901aeb765302a001a80526a2c80bf349f130f74fd577eeada6de75df0b60953264f2aab520949d79a49c864f237985fd77746eacc94c6f8227d9e91cfaaf94b4a218a6ad8d4bfb576cfddb7efbce61faf38244735ad8265006e027013110d8c40fd2d835101901194524703f873f3993a12385cfe37576dbde0adef9c306deaa195b6b6326aa13068a54fc07b20258638f62be96f4eb3df041bd6c5ab5c0206876ae8dbb8a97ad77fdeb2f300ceeb43d808e0bb00be4b444f8d100e2d855101901394526f04f04ef3c918b9de7a38e994d3375df1b12f4c98376f4147f7d82ea577e8a5a78f29f146698014675f8ae990d57129d2c496ed0c28a5c5cceedd7b69e5332bf67fe5ea8fef7cec91fb5ab9073f2f44006e01700b11fdf708e2d172181500054129f50e007f0ae08291c60500fefcdd1feaff3f6ffbcbf17366cf69ef1ad3a99452885d809acbd3cfffd5895308bcfc19aa89170fa05c52208ab067cf3e7a61cd9ac11fde71d3ae7ffbceb5c319a493077e08e05622ba6da411190e1815004d80f10fbcc37cce1c61743c38e994d3375d72d927ba172c3cbab3a76742b9bdad0d5048f421243bfb1cf327cff77d933feb2897949e420c0e0e61c78e9db5e5cb9fda77e3f59fdffdd8afef1f490d9f043f07701b80db0ef6797e3d1815002d00a5d42100fe04c08500de30c2e8a4c2c2a38eddf417eff970e7d1af3abe6bca9429953163ba4a954a597bd3c549c40ee4fa7e388ef50540b9a465c850b58a813dfba2fecd9baa4f3df99bbdfffaedffb76fc5d38fbfd4985dc2bd007e00e0df8968db482333dc302a005a084610bc153aa4f89c114627172c39ed9c4da7bfe12ded0b16bdaa73ca94696d63bbbb4b5d5d9daaad5251e572094a294b2c44842822d4a208d5a12aedd9bb8f76ef7e31dabc69e3d0cae54feebbffde3b071f7ce09e97329327c13dd021bcfff14a607c86bc026014b24117808ba0d789f7432bc8d1cf4befb3df8cd14566cc46a1018c8a8bfc7036f47984e703983dc2b88c828635d067f2dd05e025b747ffa50ca302a038bc0ac07900ce05f0fa11c6e5950a0f00f809801f01787284713928615400340f63a1fd0367415b077346169d973dac86d6f23f839ee7bf6c3dfa07024605406b613ef4aac19900ce0070a036b0bcdc6107805f402fe5dd0b60e5c8a2f3f2815101307c701c80d3019c663ea3c2201fec0070bff9dc07e0b7238acdcb144605c0818157013815c01200af0370f8c8a2f3928555001e02f02080a5189dd70f3b8c0a80030fd300bcc67c4e0670128071238ad1c8c18b001e05f008805f9b4fdf8862f40a83510130f2b000c0f1e673acf91ce87df0070ab60078dc7c7e633e2b4614a357388c0a80971e4c839e322c067014f485270b018cc43ef966601bf449ba4f03f83d80df419bf4a31afe2504a302e0e080c900e6013812c011d03e84c3a0971c473a18690df4d2dc0bd073f8e7003c0be01900fd2387d6286481510170f0c30c00d3a12d87a9d0c26232b4c57008800900c603e80630063a44b603401b00beadb30660083a94762f803d007603d8056027b436df06cdd0fdd00769f401d80060fd30b76f148611fe176a9e1a1cac36a62c0000000049454e44ae426082 + + + 89504e470d0a1a0a0000000d49484452000000100000001008060000001ff3ff610000020b49444154388d7593bb6b544114c67f73e76ef699a71215899b228a2044885629b4b253c15aac2c6c8282ff808da09da2a08d8d959a4682ad76568226c107161196e8c29aa82bd9c77dce1c8b3bcb2eb87be09b39c59cef7cdf9919250837eead49b53a87a714220c0d718bd28a284df9db687077e5bcf201f6cdce72f3d2d2f0ca1171fdd16b007c00add4c8832260012b602d680d28f03dd527b02374db5eb175b9001694067135fea8ced641acdb07f20868478c269081aee26004a214f0a00b74e3110476d0b373660c0406e21c680f6c088a2116acf4a58a1b600ac479481308be7ec4d73964e13871aefc3f8148bfb371c59d4e97bdad4d989cc75b7f02a5029d995b1c6b7c00963382de2d8a539108c429d83c74767f205f9e11c78728aa3f4850a4b07e9babd3abc00a1e4037c9081203610a6192e54904929fa165e729c51b4c4cb799daff8d72f486b5cd537d0bcd100c901a487ad3f7a155dfa6f3ee39e3c598c2448503178f82aeb1f3ea13a7cfd4d95eba205ecf7b0aa43643e260f518a650220c436cd04582008208935adacd0a24c54c81af357932cf9e01e388f2870f3256b942f2f629f9769dfacbf7140b01a5299fe66e9923f757b3cff4b3d9626347488c105bc91419a0a0d9db6a30febdc667965998de005ba2f67b8ec5e283fe0cce5673dc79bc86a715ca3d1e51000a11836a2d62fd492eff6a9310f0429de3dac9879c00fe01aeb8155bdc0972970000000049454e44ae426082 + + + 89504e470d0a1a0a0000000d49484452000000100000001008060000001ff3ff61000001db49444154388da5933168534118c77f2fa4522443842e0e6673a9387433d421545028e252a8150429eaa49d84d0ad824ba052c1cca2d28220a44e4a0cbc49de608582813864512c8894f499346d92f7eebdfb1ceee59598b60ebde3e338eeeef77ddffffbce1284938c24c0d3fc9921caf41d87f10be3d67f09cbf9b4f45c7bc896f369b16d5b84e3671240ed7d1b022f2c96281666d8cc1fe47858544900d1dd68ab8104a0f177bfb0b0581a80160b93fcb64b327565ca1a0068e58228b04600e8edbc67757debd094373f9aa82e5e7ec2b51b0fad08d0882f84bd1facae6ff1e0d10b1223e923b52b1666a07c5e0c2068c6079d660da3cb5744fb8046b40202badbef181d9b8eef56abd54883701780a0fb9db7e52ef7efdd45072d901011dfac3a40a99053aac9cbb50a4e3dc7cd89737d0d4c048d9db69132680121a2fdc8bb06d1784a381dee0390c96498bb356725fa22b6fefca4fca9c7fcedabe8a089562d24ec20e1be31dd416b78f5c6c1a9e7c866b30755d86eb4a9381e269d36f44b2f012241944a80e7cb80f71850713caee746193b3b81847b4638316183c4a08ae3e1d473ccce5e82e7c68755abd5e4c3ebc923cbf5eff8a5e65979b612379225081b9f37c4b66d5cd73df6712a9562e9f1d2402b5b27fdce7f0152c11ab027d928e10000000049454e44ae426082 + + + 89504e470d0a1a0a0000000d49484452000000100000001008060000001ff3ff610000022049444154388da5933f6b14511447cf7defcdcece6e920dc1241008688290ce4244edc4cf6163210a5af921fc001676b60a8295f65a6963218895844410b22412c96c662733efcfb59825d93eb7baef1587fbcefd3d5194cb940378f0e893ee9e0dd85c8c1820a992141445cef95d1342606f3a60532a3ebeb92f28ca9dc7dff5ed6fd5495babaa6aabaa95aa9641759aba73d4ae8eab137dfee140b71efe5045bb09f2dcd14c3c71c9c3a84f682144f0019a04d64166a09f43a83cd3b221cbecc51354133119c41910c8dc6c620b41a0f5d0002175fd707199228f170023a008624c776941000c480211f0b1038043c520764e6207117a56818e6c2d1492480902e045d1042a0d860233bf85cc40e5852ffb96a0011f95941231465252628044c2d9483853ca50e066ebe9243a655cc3b79f1961da8208215a0296183b1d675e382e2dfd654b3e82be9b035881a987a299f2e46ec5fabaa19a0a4ddbb9707de1d7bee7d9cb3e6b3717b123cb4cd74ca2852640e6221b5712afdf47eedd32dcbed1a3aea12884b656363784e4041f2097398000512178657c54f3ea5dc1206fd9d94a1c9730cc8593b2656d7581430b5580fe3cc03aa1f5109b447952b3733592d9c8d1a163520b75a654a791d515e1b015ea1a568ccc07097a4b50f70cd6045e3c4da0c2690d82a251b14ed9be3e60f78f10db2e9de700371e537d2dd072c2e7bf072c0c335a9f88b3101951aa56f8d7b30c2bcbb528f4f6f6816de4b2dff93f56ea256b775ccc240000000049454e44ae426082 + + + 89504e470d0a1a0a0000000d49484452000000100000001008060000001ff3ff610000025b49444154388da5524f48d3711c7d5ff7d3dccc6d51e9689698a69099899578c8ec60128654e421fa43484474104a0b0b91283ad4210f617509828c084cfb238c56569e6c3994feb839539b6d6a35d7981baef9db7eaf4330dca118f5dee573f8f03e9ff7788220fe0752224b87af3653b75c832815240981b9d03c76e494a1be669f4848409d29e3c291bd9847186aa4604af1a2f3de50e21fc8c93e3860c13cc270ce7961b28da238b5345ee083c9c46f9676f8e54c680cc528aade85acfc75a2f1ee7906b533b086dfc2e1f36060c6852fde30dc4e1f021d7e4a00e0714e72baad19d52df9c08a1c04260218ecb98cfe5b9ba92861e80b92105485a02082d55a2d5452080ef718cac50608827872ba866949e370cf6e445d8b0c4d6e290023c6bbfbe1086c85db10c5404637d66f326274d60bcbcb099c5bdb8aba2dfb051e361ee2c2400607afafe2a3a65a2e7ccf255946b281642b7bcf969220cc3633f7982bb8bbab9256a795c46f4a3fbd631091204aaa175092f61c480d018a0b72c80f29aa81c7978a1fee29566555893c4f1ed5296a187406114b98203a1b76326251911f418e80f480a15130f85ec7c064214d17b7f14dc7fdd8d5c58c0d9da76a69bf09d20a7218e40cc8afa0ec48a6e2c9e6584f31bb9a4ed0eb72c50989c555b6bf7acd4f3dd710f57f46ca9208f4ba711455ca589a0e440d7a441523fa6e2f83b6f024ca0f1e10310b7fe294ddce676d57f8b83e9b1c02952189caf41a3aee14b1f7463be32cfc8d237d7dec3e7394e66359e43b90c3e97c70bc8a0413ab72c1f60a51800ad85ef4f2e9a53a08fd4a48fa1c0088cfe01fa0fa05bf8e6aa3d3f891370000000049454e44ae426082 + + + 89504e470d0a1a0a0000000d49484452000000100000001008060000001ff3ff610000023949444154388d9d935d48d30114c57fffcdcf35ade821738b9ca1cc9820da97509a640841b12c1fc21e020bf321ea41a824c49e7ac928330b0529a228290c214c33d9a4482d9ae992d49ae6478a65d6cccfcdffed21d4c28ad6398f877bb8f7dc7b1541f0153b731a6562aa8792dc78145f0d0a8b9d12996aa6c209e3b5f7f0f3a5b8fae17b312e8b2040efc75acd1871692bd0f862f0faa3c2ea283d9d0310dafb887d7b5395f90e6acf9d959898167afb02e9e9d6111ebb95940399ca9c7ee6bc53f6582d3ceb8677d5351417a4ffd004a1dd669327792619694c1191d3229ecbd26dcb951b278e8a205c29ef94a60fb372a151c49ad729c2021541787c2a5e3c935e86c6b79091eb6249b40530f3b5ad858ba561acb11e67083db7ab267114052b3f8fa5351faa93dd396fd168be1110e8c1b4ed0d4ae020a0a20d8261cf769cd3ebb85401ae32ff5f8a01fcb4ba70dc3d0e22374e13a96b02af0ade6166c6461970ad6483398baee63e12d476206d51b09a8ca20aa5ae3e9d897ee08b0a83c0888a767280e6a77a4a6e7e26ce93cf61cbcbdf6e66fe90eee7658b21e41aeb93675082803078e58cc03dea6553e238ee5e23f6bb163667e76388312b8b0c00fa5adbc471ab90a94f2efcb5532cd77590b0c34db01e5443088abf9186f2507451c748ccdcbfb0c63f71a4bf5feaaf9648e54193c80b64f6b956d421a3745d8f155b59a908f277833976d8ed5279f288d4641944da1071e8e54e8e5504f9b75f884e4e52a249a2f5c12ea92ac884a5ab080a372dcee07ff01dd04c1d4b66996b2b0000000049454e44ae426082 + + + 89504e470d0a1a0a0000000d49484452000000100000001008060000001ff3ff610000026449444154388d9d925b48d36118c67fffcdc8b6999699d5569e401d74cea8b0360a82088c40826215459675d3e1223a5c5458108141572159515049211582845d848ba0c281f350d62ccb23a2357366693a9f2e965e1819f5bc37ef77f1fe78bff77910ff5ecdcf5f6ab437f117bdced9a4c0a54b1a7d07ae5ed7e0b562de151509c010fae3f09bc54b945950407b79393d191960b512ebf33177db565a8aae327ceaf4c40080b6ace572ac5b47f38b1784c3c3a4ba5d74d5bde6736e2ece5d3b8d31c0e3c2f3723afdb4b44ee6e3070b7316ac61ed768f01d03c2f594989098041c7b7ef741f3acca27d7b0c207283864aafacc162acf1dd64e727e139b79014879f5bc70e0a20140cd252e5a3d9ef27f4a507932d666c43134047c511fabed928bb96497fa00aa29a48766790e319a1296eba12bff6d16598e834ccc44599882bbcc0ab927b91d54bf2b2a586e97a7f3b5ecf0a57291c9a2569bea4dd6a9c91a0215000c66c7b9390a081d5d96a5fe392bfa651dc3bb845bd8f2c52a3596a374941a4219306837635f996ea9d61687c0e3ea6a5aafef45909455cb87f7487366c2cc132331cf9583c84c3505aea22b6570ccd4863a0379d2d274e18e35d1a73e1e1c97cd9636e90e5fe81110dcc829afa64423dc3ac58d54fa8c581b7743e2bf34f6177661abf01005a6beb547de722039f9a98641e609ae52dcbd687986283117b0cc624074faf4f25ca9e877b6f5e043251e63fb7b5e949d1653dd89522f950b8caac914e871a6f2e5065f115094d0c18adb75eaf1e1cdfaf8a3d76a90ea9daa6bb07364b88a80973fc4be96e97918e8bdaf21c959df140ec6ca2e7a4fc7e83ffd14f834f64403664fe630000000049454e44ae426082 + + + 89504e470d0a1a0a0000000d49484452000000100000001008060000001ff3ff61000002ca49444154388d6d925d685b7518c67fff9373d2248bb676b00f6dd5d1ad4e1c8ead6c4eda29534110d9ca1cde0c046f05c17b618848c50b1d03edcdc62e865e549ce0078a200c74438755182b69d636dbba6e4b9690e4e4e49c9caf7fceeb45596d5d9fe7e6bdfaf1f03e8f1284d55afcf68488ee907b74084b0534160b5c5970387a624ab19e64954b5fbd2dded29f222222892be2cd89347f13b9755a7e98785584076ddc07952f7c265b9e1b2737b00be216f80df05be0da90e478fdf8614ebefba2fc3fc00aa0ebcc91eddb08f5597017c1af426483f6d01d078914a37b36f3e5992fd640ccfb47a0352aac40d7006541a2a1eb91c41e5dd1845e9b2872a9d6efae9fe0ae6312d4af416c937865bafe3d74d0228a02bc8e43bb52e0d25f0506869e5d0350ab5b98fafc1d3972a01fac87d0a488e388d0ade3550accdcf438f7479ef3dffda4d6054cfc8884778a1c19ba80be7799b4b65104546b2e76df6efef1dfa2e96a0eefcbf0da2b236a0de083292d6fecf5315486a4cfa278f53a9b3e3c464f6986e2fb5f138e8db353c1963cfc7c7981016b8963e387148071ea7b2d234f25e8946270d064300f2f1d18a4fff1bde8ec4e0e8e3ec39bc330360c663ae4e0e876ceff7efbbf2716ee68240d2dc970c356d435346c9b874dc5135bfb712b559a0a2e966b2c388a5a0786f7bfccc427930260860a6aa14920066d0d190d46d9655ba341da695199bb4d7504666a364e33cfb64da0f27d5c9d5d5ade41ad6dd1d0064e085913520a7aaf9578ba54c42acd631766099ad093ecc08fa01143c555f87eb40c6897fee6fa9efd3c9203b30386806b3d46b97f3b65d7607e603752070921d30b150dd397e6797e7366b9855f7e9d96f7ce383c79e805366e4d91cb80b9018c3846475dccde0c89077e00ad06cc5dbc4277fa1485e9b36aa5c6e26c493efaf41b66ca59bad90da47ad28895c248194810a3c318dd7649fbb718db653139f9f1ca0efe055881729165195cec0000000049454e44ae426082 + + + 89504e470d0a1a0a0000000d49484452000000100000001008060000001ff3ff61000001fd49444154388da593cf6b13511080bfb749779bb8b16d48530bb5450fe28f5014a95ae91f2056416811bc088207ff0daf9e04ff02e94945aa07c19ebca80d8dbd08a2148c3d08268d25da52dcddec9bf1906d93f4a2d037bcdbe39b6fe6cd184539c8490394171e6bf0fe1eee688a9f1b0eb9913cdbbfc63939ff8013d397cc3f01b5ca12376e0534b6faa8bebc4969f233c7a64eb1f0e8398d6554e33879ae88288ee350afd7999b9f3369006ff30db8e017539466d6299c1ec60c1f65ecc816e7262fe07a0ed60a2a8215219b7579b1b8d83170cd160864c603ce4e2d0357810286ef7c5b5b676462945614a1aa582bb45afdc4899503b0cdf1b6a180c62ed00784442d8f438383d8384655111154db57c47600b67891da2a6020f80ad2a8f1e3f52b4219223be063ad45447aaeb5d201ccde7fc8db0fe721042f0dd5774dcae519ce5cbb8dd8b027b3aa26365d06fd39df142fdfa5be0a4e16a238cdd8f41586c62788a328511644b4cb423b0080d2ec75aa1f33601563a015fe210a4244da8db356f695617b01db1b1bf4e704d2a06ad05d6de95697bd72acdd07f00b057e6f16c12600059bfc7b77e3ba2df6e600c0cfe711c7050ffa5cc340ce273f7898d04ba13db50bbe9f41557b013bcd26ad9d1d080c6bab964fa925fc2f2b689209edac9d310e4110ec4e7727aa958a3eb953d295674f55f9bf30075de7bf28d866e8d0d326ce0000000049454e44ae426082 + + + 89504e470d0a1a0a0000000d49484452000000100000001008060000001ff3ff61000001d849444154388da5925b6b13511485bf73324934cd343655634cb0e0056c857a0163b120f80704fd07f6a50fd29f24228582226253f145f04dd497522b68241deb602a6d35499b4b2793ceccf6a1d6969a40d0759e360b3ef65a672b41f81f19fb8765eb8bd8b64d80020409023299939c1f1e56dd006a778385f979f9596b911a3a47f6a889d68a957293d2b245dc68737d7cbc234403584b9694ca4da2433962c96304c6217c1d259648629ebd4a3530793e37d731ab0150287cc23d31464b19541be04640015bdbe078e00e8c50292e74efc0f1141b413fe240e041737bc7747d68b4a1ea1918fde9ee0011211c828a035b6d888676ccb60f2d0fc26108e9cebf650044f030230d6ae12475075cef77411accc3908cf858eb7677403a9d666de53da7466fe2f481db0601a261e88bc246f1035a828e000d901bbba6aaab369b85d70ca826990464133068b4287f7c47a3be4e2a16a2f1eae55f39d4fe4bcc3f9b95afb68d792489d29acdf20fe2f138995a99d11b0ab3fa02c799e2f8ad3b7b37213dbc55cb92a5a9acc8db9cd4dfdc966ff927b2ebe98ec10e2875e6b472efe6f97c7f8d3825ccc1698a4f67e44f07bd68e4ca65e5df9b65f1418504dfb1161fee95d833e4d245a5271ff36826857f61023850e2bfe81707d3cfaf34cffed30000000049454e44ae426082 + + + 789c8595cb52dd461086f73cc529f7ce956acfe832922a95053636361873356052598c6646c0010c868331a4f2ee19fdddd22e15c4e27cd5fff4f44dad37af17a77b3b8bd76fd61e567e751916e1c2df2f5ec7c79b9be73ffffae3efb557d62dc6ffca2c8a57bfadbde2b78bb020833ff033b8c80f982ec0e5c46c954bb59f83ab997747b68589c642ff51d81a83fbe80bb83449ecb40daeb25d780b5ccffc49d9aabf43b0cb37089f823b5babff3370c809caf96fe098edc2a7ca4ef9049c6ca37c0c1e6cabfebe2a77ca4723e7cb95f9055cd8684ad82fc14d66b123fe2214ce54b03f8087a2547ff7ca95f2c6c8d938d97f283bf5bf07b685e64fef94a7fcd1cfb2c87ae1efe0b2e8f4fc0db82a7a8da707d7939d8f94bdeaaf9583ea311fa5cb2c76036e8aa99ebf94a3e859e2efcbd2d4e0f591f3b838e53bb02d3be370fe3db82ba77aac946b8d0ffdaa7c6544cfc8bfeacba4fe1c78a84ab53723d7b14aa60123de7aa882de378cec9aba352d18f3ea4266d1a33f2ed5c974b07f1eb931b5c64f87cabdeab795a3faf3e0ae1ec4ee85fb5af3f3048ef93ee4e779e476f427f5f3c2e3037f4f60eb7a8de74a391a8ff3e8675bd48dd6ef45d8d5723f75e032c723f1df0abb29ff165c3bed17a17e6deb1aad17eadbf6ceabbf1a1c5d92f34cc2e3037b0027a7f566cc6f3b34c10430ead999a6d27c70dee76c251fc63cf9a24d26213ff8f365f627f9b1705ba91ef979d7b6a607ef839b361ac4c3c8cf77ed74ffad70579901fe2a706c3bf147d8773e35d33c1e8087667abfe0bf2f9b5edf870f33a37f7e096e723ef2fe3c2a5badef0e788c47ea2ffabe75522f8f7dd2a756e78b2278c87ae175e1aed4fc8b9183ed6a9d07ecef507456fddf294ff529c1e564f7f01fea2e88dd63bf07d739e90fff548e5a3fecc7d0748dd83ddea7e0f37989a716f6c9cabe46bea1ef745e49e20dde697fb09f42f48df63b8193b71a2fea1b065f28635fc4d2b71a0ffa132baff342c82f3a1fd4ff9972143ba31fb19919fb37fabe9079e09572a9f3b1094e7d63e57b78addc2a3f287bcd774b3928e37b94ecc4847aa6a28f6abf529eea85fb52155a2bfb00f3915fa7bcf2711ef5493edb653f5e2a77ca98e71443d2f398879466c6be4843ecacec2f7cbf071b4b2bfb14fd1f8a5829e3fb38d4592feff3d3cc721efd1fdcccf8de0f5d4c56f643521e94f17d1afccc98bf21a6ca629ef651ff613066907e04e1d44c7626f6fff1d0fe4a7652fedd73e0c889073ee70bbee4255ff135df8c2ad9b3aaf89e15b77cc73ff89e1fb262c58ffc93bd6ac4c713ffe2677ee1757ecbef78232bdef38759238a4dfec89f782bdfb29d559fa1d899355fb26297f7b2651f711cf0211f41f175d61c67c5059ff0297fcb8a0d3e63c3968bac2867cd2e575cb3e3865bee8889c8534f814b8ab3a6a244039dd3793e8d872ef2734991969386122fe98aaee986bed32dddd10fbaa7075ad1921e673f4bfa494ff48b9ef9885e689dded23bdaa0f7f44873ee59b1491fe9136dd1367da61dfa929f5ddaa37d3a98359bbc418774445fe9984ee894bed1597e0c1d909d35059554514d8e1a6aa9cbcd24ef7d4fd607d5e49efae8931ffcb9bff097b4f4cbf11651484fff7736fef97ded5f4b926727 + + + 89504e470d0a1a0a0000000d49484452000000100000001008060000001ff3ff61000002fd49444154388d65934b6c54550086bf73df7766dae90c3815d1b6506bad16c11a303e92265523dd802cd09d0b97aedcb87163485cb9301a13c3c2981817ba2041029aba10931a35d1164c8c608382f6c10c43e7d1993b739fe71c174452d37ffbfff956ff27349aedf961e9a63eb7b84ebd0bb6eba19426ee470c9a09c766f772746ebfd8be17db016fbdffb38e9c22479e18c1cbf9f442459c40a60c1acd90952b6b14d33a1fbcfdacd80178fd9d9ff4f4e1491e7fb44ced564ca3de646fc9a61b4a5636624cbf887072ac57fb347f5be6f30fe7c45dc0a98f96f4eef1fdcc3c5266bd1691b41b3c7fa8c8dfb742ca050721149f5d6cd24d3d843bc0edb626b7b1c4e9779f13c6a5df6feb46e67370b2cc5607ea9b7da61ef0192cd85cf825e0d3ef3a5476e5993f3c44bb1bd16936314cc1aabc9f2fcfaf68ebecc57f187f78122da1174a6cdbe5d2f52daeac86b8b902ad6eca5f3743a6460bb8768b569091052deca121ce2efc8a756333a3b13b4f2213f6953442081ab14fab9ed0e9677846ccc87099adbea41b48e2d822e877c00d890281a54d9b46a0b97c35e0c50316f7160502816366cc4e593c33750fbb061dcefd58a51980cc22da9d0e5ec1c7351d2cad34a6902471ca579723262b06032e8c57042f3d5da217493e5ea87166718b5e941245014ac6a03cb4024b2409a6cec050289572754d42943234e3d18b25afbd779db56a88b0245aa5a0242885104018618c960dacb48fef18774a53814ab9568d38bf1cb0560bc1ccd03a03a5406608038484e17c86717c6e94a0ba41a5644396429680a9987d6c80a71ef278e14819a20c64062a059962fb3954bbc789f9318c2767f688897c4041f529977c88522cad39349e63e23e97e9b13c24e91d409662b91e361e634e979327a7c5dd2bbffac6b73add334e2b11346b9b8c0cbb1c7c7080ef976b3436db188e89ede5b184c7607d950b5f1c173b647af3d4a2fea3e543a9483bc8e807118ea5b01c132135ba1530e1f7f8e4f4fc4e99fecbc2377fea335fdf607d4b234d072d353a8ea9789213474778f99503ffd3f95f95697c0513b128840000000049454e44ae426082 + + + + + MainFrame + pixmapSizeChanged(bool) + MainFrame + OnMainWinResize() + + + File_Open + activated() + MainFrame + OnFileOpen() + + + GroupView + selectionChanged(QListViewItem*) + MainFrame + OnGroupChanged(QListViewItem*) + + + File_Close + activated() + MainFrame + OnMenu_closeDB() + + + File_Save + activated() + MainFrame + OnFileSave() + + + File_SaveAs + activated() + MainFrame + OnFileSaveAs() + + + tooButtonOpen + clicked() + MainFrame + OnFileOpen() + + + toolButtonSave + clicked() + MainFrame + OnFileSave() + + + File_Exit + activated() + MainFrame + OnMenuExit() + + + EntryView + selectionChanged(QListViewItem*) + MainFrame + OnEntryChanged(QListViewItem*) + + + EntryView + doubleClicked(QListViewItem*,const QPoint&,int) + MainFrame + OnEntryDoubleClicked(QListViewItem*,const QPoint&,int) + + + Edit_NewGroup + activated() + MainFrame + OnAddGroup() + + + Edit_NewSubGroup + activated() + MainFrame + OnAddSubGroup() + + + Edit_GroupProperties + activated() + MainFrame + OnEditGroup() + + + Edit_DeleteGroup + activated() + MainFrame + OnDeleteGroup() + + + Edit_PasswordToClipboard + activated() + MainFrame + OnPasswordToClipboard() + + + Edit_UserNameToClipboard + activated() + MainFrame + OnUserNameToClipboard() + + + Edit_OpenURL + activated() + MainFrame + OnOpenURL() + + + Edit_SaveAttachment + activated() + MainFrame + OnSaveAttachment() + + + Edit_AddEntry + activated() + MainFrame + OnAddEntry() + + + Edit_EditEntry + activated() + MainFrame + OnEditEntry() + + + Edit_CopyEntry + activated() + MainFrame + OnCopyEntry() + + + Edit_DeleteEntry + activated() + MainFrame + OnDeleteEntry() + + + Edit_GroupSearch + activated() + MainFrame + OnGroupSearch() + + + toolButtonAddEntry + clicked() + MainFrame + OnAddEntry() + + + toolButtonEditEntry + clicked() + MainFrame + OnEditEntry() + + + toolButtonDeleteEntry + clicked() + MainFrame + OnDeleteEntry() + + + toolButtonPasswordToClipboard + clicked() + MainFrame + OnPasswordToClipboard() + + + toolButtonUserNameToClipboard + clicked() + MainFrame + OnUserNameToClipboard() + + + EntryView + rightButtonClicked(QListViewItem*,const QPoint&,int) + MainFrame + OnEntryRightClicked(QListViewItem*,const QPoint&,int) + + + GroupView + rightButtonClicked(QListViewItem*,const QPoint&,int) + MainFrame + OnGroupRightClicked(QListViewItem*,const QPoint&,int) + + + File_Settings + activated() + MainFrame + OnDbSettings() + + + File_ChangeKey + activated() + MainFrame + OnChangeDbKey() + + + File_New + activated() + MainFrame + OnFileNew() + + + View_ShowToolBar + toggled(bool) + MainFrame + OnViewToolbarToggled(bool) + + + View_ShowEntryDetails + toggled(bool) + MainFrame + OnViewEntryDetailsToggled(bool) + + + toolButtonNew + clicked() + MainFrame + OnFileNew() + + + Extras_Settings + activated() + MainFrame + OnSettings() + + + Help_About + activated() + MainFrame + OnHelpAbout() + + + View_Column_Expire + toggled(bool) + MainFrame + OnView_ColumnExpireToggled(bool) + + + View_Column_Attachment + toggled(bool) + MainFrame + OnView_ColumnAttachmentToggled(bool) + + + View_Column_Username + toggled(bool) + MainFrame + OnView_ColumnUsernameToggled(bool) + + + View_Column_Comment + toggled(bool) + MainFrame + OnView_ColumnCommentToggled(bool) + + + View_Column_Creation + toggled(bool) + MainFrame + OnView_ColumnCreationToggled(bool) + + + View_Column_LastMod + toggled(bool) + MainFrame + OnView_ColumnLastModToggled(bool) + + + View_Column_Password + toggled(bool) + MainFrame + OnView_ColumnPasswordToggled(bool) + + + View_Column_LastAccess + toggled(bool) + MainFrame + OnView_ColumnLastAccessToggled(bool) + + + View_Column_URL + toggled(bool) + MainFrame + OnView_ColumnUrlToggled(bool) + + + View_Column_Title + toggled(bool) + MainFrame + OnView_ColumnTitleToggled(bool) + + + Edit_GlobalSearch + activated() + MainFrame + OnGlobalSearch() + + + Extras_Language + activated() + MainFrame + OnExtrasLanguage() + + + toolButtonSearch + clicked() + MainFrame + OnGlobalSearch() + + + toolSearch + returnPressed() + MainFrame + OnQickSearch() + + + DEBUG_DbStructure + activated() + MainFrame + DEBUG_OnPrintDbStucture() + + + File_Import_PwManager + activated() + MainFrame + OnImportPwManagerFile() + + + View_HidePasswords + toggled(bool) + MainFrame + OnView_HidePasswordsToggled(bool) + + + View_HideUsernames + toggled(bool) + MainFrame + OnView_HideUsernamesToggled(bool) + + + GroupView + dropped(QDropEvent*) + MainFrame + OnGroupViewDrop(QDropEvent*) + + + Help_AboutQt + activated() + MainFrame + OnHelpAboutQt() + + + File_ImportKWalletXML + activated() + MainFrame + OnImportKWalletXML() + + + + OnEntryDoubleClicked(QListViewItem*,const QPoint&,int) + OnMainWinResize() + OnFileOpen() + OnGroupChanged( QListViewItem * ) + OnEntryChanged(QListViewItem*) + OnMenu_closeDB() + OnFileSave() + OnFileSaveAs() + OnMenuExit() + OnAddGroup() + OnAddSubGroup() + OnEditGroup() + OnDeleteGroup() + OnPasswordToClipboard() + OnUserNameToClipboard() + OnOpenURL() + OnSaveAttachment() + OnView_ColumnUsernameToggled(bool value) + OnEditEntry() + OnCopyEntry() + OnDeleteEntry() + OnGlobalSearch() + OnGroupSearch() + OnEntryRightClicked(QListViewItem* item, const QPoint& pos,int column) + OnGroupRightClicked(QListViewItem* item, const QPoint& pos, int column) + OnDbSettings() + OnChangeDbKey() + OnFileNew() + OnViewToolbarToggled(bool toggled) + OnViewEntryDetailsToggled(bool toggled) + OnSettings() + OnHelpAbout() + OnView_ColumnExpireToggled(bool value) + OnView_ColumnAttachmentToggled(bool value) + OnView_ColumnPasswordToggled(bool value) + OnView_ColumnCommentToggled(bool value) + OnView_ColumnLastModToggled(bool value) + OnView_ColumnLastAccessToggled(bool value) + OnView_ColumnCreationToggled(bool value) + OnView_ColumnTitleToggled(bool value) + OnView_ColumnUrlToggled(bool value) + OnAddEntry() + OnExtrasLanguage() + OnQickSearch() + DEBUG_OnPrintDbStucture() + OnImportPwManagerFile() + OnView_HidePasswordsToggled(bool state) + OnView_HideUsernamesToggled(bool state) + OnGroupViewDrop(QDropEvent* e) + OnHelpAboutQt() + OnImportKWalletXML() + + + diff --git a/src/forms/ui_PasswordDlg.ui b/src/forms/ui_PasswordDlg.ui new file mode 100755 index 0000000..d1bb83e --- /dev/null +++ b/src/forms/ui_PasswordDlg.ui @@ -0,0 +1,328 @@ + +PasswordDlg + + + PasswordDlg + + + + 0 + 0 + 562 + 250 + + + + + 1 + 1 + 0 + 0 + + + + + 562 + 250 + + + + + 562 + 250 + + + + Datenbank öffnen + + + false + + + + textLabel1 + + + + 10 + 56 + 450 + 16 + + + + Geben Sie das Passwort ein oder wählen Sie eine Schlüsseldatei. + + + + + Banner + + + + 0 + 0 + 562 + 51 + + + + image0 + + + true + + + + + ButtonCancel + + + + 460 + 220 + 90 + 20 + + + + Abbre&chen + + + + + ButtonOK + + + + 360 + 220 + 90 + 20 + + + + O&K + + + Alt+K + + + + + groupframe + + + + 10 + 80 + 540 + 130 + + + + Schlüssel + + + + ButtonChangeEchoMode + + + + 510 + 30 + 20 + 20 + + + + ... + + + + + Button_Browse + + + + 450 + 70 + 80 + 22 + + + + W&ählen... + + + Alt+ä + + + + + Combo_Dirs + + + + 201 + 70 + 240 + 21 + + + + + + textLabel2 + + + + 10 + 30 + 180 + 20 + + + + Passwort: + + + + + textLabel3 + + + + 10 + 70 + 180 + 20 + + + + Schlüsseldatei oder Datenträger: + + + + + CheckBox_Both + + + + 10 + 100 + 16 + 16 + + + + + + + + + Edit_Password + + + + 200 + 30 + 310 + 20 + + + + + + textLabel1_2 + + + + 30 + 98 + 300 + 18 + + + + Passwort <b>und</b> Schlüsseldatei verwenden + + + + + + + 789c8597596f23470e80dfe75718c3b7c182e9eabb11ec834fc9873cbeaf601fc86ec9966df994cfc5fef794483633934d10c836fcb9582cde55fee5dbd2d9de68e9db2f5f9ee7349fb64bed153d2d7deb5e66b38fdffef3efff7ef99aa64b8baf2c5b4abffeebcb57dc5c6a9720499290640b8613e110ff22eb941b07657e7256f90be742e4a7c6a9ed076791c7a1732efbd784d3f817615a71167db0e55c0a17ce95c88f8ced3c7e74d6f306cea29fd159f583b3e8a75367d18f5bce8df0b63389be67e3ccfcd97716fd78e22cfaf1d459edefedcbedbc63e75af4cf85b33edeb8616cfef1b5b39eb7e72cf6c28b7166fb53678df7b5b3fadf388b3d503a8b3d40c6b9eaa35767d9cf37c6a5e53f73d6f3769d55bedf5f2789ac6bfcf2de1fda33ce4cdfbb716eeb6fce1acf1de3c2f2bbe7acf573605cdafe2b67f5efd359f20bb97165febe38b3c453fd2bfa7cd0a67165fea97c9db416ff1de3b1e9d77a6d12567bf8c159ed9d1ab7969fc2b8d378e2ba304579c93769bd719457fd524f2184cae221f51bd250a8fd3c35ae4cfec1b8b6fa06e3c6eaffc859d651f215b2d0c7efdab8327b969d459e9e8d7bfd57c68df587c43be4c1e20b685c1b9f0b17c1e283cfce927f96f911ca40d63fcbce7afebd31eb3a91b3fa37376ead9e64dea5759606a94f546eb23499883d9bc69932bef4acf22cf594725c1f8bfca9b3c8d3aa711e82c82bb73de3817111a4fe2171d67e1a1b97ba8e87ce5a8f12bfb48b2cfae8ceb85206894f9666135bff2e5c45d6fae894a3393a3f5be13aaeb7729eca4ff2d6ce3f5b701ef2b1c95f0aa7715dfb4de657519675d0fc8d8c9ba0f527f12faab234fd8fc695f1ab716dfa3f84ebb2089dec5f779678d381711d74beae398b7f540b3751bfd6e39ab1c9033b6bbd07e326687dcb3c2da8ecf47cfa301e9bbe37e389c94b3c0a2edba0f5f361dc194b3c8b36eed77acf9c453fab7f6d95587e6e8d83c957c25dc9668fdc5fc538b2c6e3a6e754e7adcc836252b6a9d69bccffb2ad535d67e98fb2ab538befaab3e8439947e5b84e82f6ffa17165f1bd7096fcc1ccb8b67a981b375a0f20f92d2775b078493dd54c75aaef0de9dfba75167fea2eb2f683dc5771388d753fbe396b7fca7c6b52ea2c5e57ce621fcbfdd26464f1812767ed8f63e3ced665de34c464fe9e1bb3d5b3f45bc3dca67a7fc9fba7697b46a9bf66cc13cb8fcc8b66c2960f3832b6f3988dad1e2828b799c53371d6f9766b9c5b7f4afe286983f5c3aeb3be177ace6c1ecc9cb51f6a678def8a7169f351fca710f5a93d9db3d64febacf9981aa76a2f5e3b6b7d5d1af7f6df3aebfb67e4acf93f72d6f972675cd83c7d77d67cac3bebfdfce9acf7eb87b3c66b665cdabc5feed9f44bfd51caade59395dbc4fc3f33cecc9f9b9e35bf786fdccfffc459e7ffc059eb7fe2acefcfd459df13dbceda5f4367bddffed8affdf0665c243a6f769c351f6367f51f7ad6fcefcf9dd57e72567fd959e3dd3a6bbc3b677daf34ce6affadb3dadbdb57263a5f46ce7adf8e9dd5dededfbe5e2f9cb5de5b678df7bb71a5fa59f767dccf77cd57d6f7136c185b7e79d359f3159cf53df7e8acf19e19f7f57ee5acef9b0d67f5b733b6fa844b63f38f07ceea9fcc3fca5b9bef58199b3dbce5acefa53567bd6fee8c73d54f95b3fa3b34b6fcc3b3b3f6dba1b3f6afe6a788fb6bad9f1f3f08f19b90b18ddff0f3dafefc2fe4bb284948f1b7f1e2e73fca4ff012af708ad77883b77f2f8f33bc8b9aeff1011ff1099f718e2ff88a6ff88e1ff8196da33fc92fe30aaee21aaee3060e70889bb885dbb88323dc8d7a407df941be8dd2dfa3ec5e94dac7033cc4233cc6133cc5333cc78bffb327c18029669863812556d1ef1a9ba8168080a1850ec608daaf30814bb882296ec035dc486426700b33b8837b78c0213cc2133ce367af3f7a93c01c5e700b5ee10d6fe11d093ee01396610556f104d6601d36a2d77abf0da2f41036610bb6b1841d18c12e7c873dd887033884233886133885b318297d3fc558e114cee1021208d1e01432c8a180122aa8e3c5190f2322c63bb507995aea62bc37698c9f34a14bba822d9ad235ddd02dcde80e87744f0f7fc823d1233de1363d634d737aa1577aa3ebf8047ba70ffaa4655aa1555aa375b37f0c298e6923ca0fb0a1212cd3266dd136edd08876e93bedd13e1dd0211d997e88f6031dd3099d624e67744e17f15f8b40296594cb273ef61632aa5ff34515d5d43032707c19449fd6e993db283b8217ee62fc0630fa31bf1cdf037c493bb1724ef98a162d30e56bcae185467cc3b731dfa0f935f919dff13daef1033ff2133fc77d039e73d41da55ff90d268b8afba17ea27d30a18edff9833f7999577895d7a88421aff31b6fc0e04ff5c6314acc031ef2266cc4c7ce036ff12ca66a10ff75d95eacfd2ccf3b0bfd38e651ac93f7d83b77f84e47d1e6f1222e0bf9c5ef3ff7a3f690766f4ffd0490aa85affffbf5cbef985d44a8 + + + + + Combo_Dirs + activated(int) + PasswordDlg + OnComboSelectionChanged(int) + + + Button_Browse + clicked() + PasswordDlg + OnButtonBrowse() + + + ButtonCancel + clicked() + PasswordDlg + OnCancel() + + + Edit_Password + textChanged(const QString&) + PasswordDlg + OnPasswordChanged(const QString&) + + + ButtonOK + clicked() + PasswordDlg + OnOK() + + + CheckBox_Both + stateChanged(int) + PasswordDlg + OnCheckBox_BothChanged(int) + + + ButtonChangeEchoMode + clicked() + PasswordDlg + ChangeEchoMode() + + + Edit_Password + returnPressed() + PasswordDlg + OnOK() + + + + Edit_Password + Combo_Dirs + Button_Browse + CheckBox_Both + ButtonOK + ButtonCancel + ButtonChangeEchoMode + + + OnComboSelectionChanged(int) + OnButtonBrowse() + OnSelectClicked() + OnCancel() + OnPasswordChanged(const QString &txt) + OnOK() + OnCheckBox_BothChanged(int state) + ChangeEchoMode() + + + diff --git a/src/forms/ui_PasswordGenDlg.ui b/src/forms/ui_PasswordGenDlg.ui new file mode 100755 index 0000000..6613afb --- /dev/null +++ b/src/forms/ui_PasswordGenDlg.ui @@ -0,0 +1,551 @@ + +GenPwDlg + + + GenPwDlg + + + + 0 + 0 + 460 + 470 + + + + + 0 + 0 + 0 + 0 + + + + + 460 + 470 + + + + + 460 + 470 + + + + Passwort Generator + + + + Progress_Quali + + + + 130 + 400 + 180 + 15 + + + + + + Edit_dest + + + + 130 + 370 + 250 + 21 + + + + + + Label_Bits + + + + 320 + 399 + 60 + 16 + + + + + + + + + Banner + + + + 0 + 0 + 460 + 50 + + + + image0 + + + true + + + + + ButtonOK + + + + 263 + 440 + 90 + 25 + + + + Akzep&tieren + + + + + Button_Cancel + + + + 360 + 440 + 90 + 25 + + + + Abbre&chen + + + + + ButtonGenerate + + + + 381 + 370 + 70 + 21 + + + + Generieren + + + + + textLabel4 + + + + 20 + 370 + 110 + 20 + + + + Neues Passwort: + + + + + textLabel5 + + + + 20 + 400 + 110 + 20 + + + + Qualität: + + + + + line3 + + + + 0 + 420 + 460 + 20 + + + + HLine + + + Sunken + + + Horizontal + + + + + groupBox1 + + + + 10 + 60 + 440 + 280 + + + + Optionen + + + + Edit_chars + + + + 30 + 170 + 400 + 21 + + + + + + Spin_Num + + + + 120 + 220 + 310 + 21 + + + + 1000 + + + 1 + + + 20 + + + + + checkBox1 + + + + 120 + 40 + 131 + 20 + + + + Gro&ßbuchstaben + + + Alt+ß + + + true + + + + + checkBox2 + + + + 120 + 60 + 140 + 20 + + + + &Kleinbuchstaben + + + Alt+K + + + true + + + + + checkBox3 + + + + 120 + 80 + 140 + 20 + + + + &Zahlen + + + Alt+Z + + + true + + + + + checkBox4 + + + + 120 + 100 + 140 + 20 + + + + S&onderzeichen + + + true + + + + + checkBox6 + + + + 260 + 60 + 170 + 20 + + + + Bindestriche + + + + + checkBox7 + + + + 260 + 80 + 170 + 20 + + + + &Unterstriche + + + Alt+U + + + + + checkBox8 + + + + 260 + 100 + 170 + 20 + + + + h&öhere ANSI-Zeichen + + + Alt+ö + + + + + Radio_2 + + + + 10 + 150 + 420 + 16 + + + + &nur folgende Zeichen benutzen: + + + Alt+N + + + + + textLabel1 + + + + 10 + 220 + 110 + 21 + + + + Zeichenanzahl: + + + + + Check_strongrandom + + + + 120 + 250 + 310 + 21 + + + + "/dev/rando&m" nutzen (empfohlen) + + + Alt+M + + + true + + + + + Radio_1 + + + + 10 + 20 + 420 + 21 + + + + folgende Zeichengruppen &verwenden: + + + Alt+V + + + + + checkBox5 + + + + 260 + 40 + 170 + 20 + + + + &Leerzeichen + + + Alt+L + + + + + + + 789c8597596f23470e80dfe75718c3b7c182e9eabb11ec834fc9873cbeaf601fc86ec9966df994cfc5fef794483633934d10c836fcb9582cde55fee5dbd2d9de68e9db2f5f9ee7349fb64bed153d2d7deb5e66b38fdffef3efff7ef99aa64b8baf2c5b4abffeebcb57dc5c6a9720499290640b8613e110ff22eb941b07657e7256f90be742e4a7c6a9ed076791c7a1732efbd784d3f817615a71167db0e55c0a17ce95c88f8ced3c7e74d6f306cea29fd159f583b3e8a75367d18f5bce8df0b63389be67e3ccfcd97716fd78e22cfaf1d459edefedcbedbc63e75af4cf85b33edeb8616cfef1b5b39eb7e72cf6c28b7166fb53678df7b5b3fadf388b3d503a8b3d40c6b9eaa35767d9cf37c6a5e53f73d6f3769d55bedf5f2789ac6bfcf2de1fda33ce4cdfbb716eeb6fce1acf1de3c2f2bbe7acf573605cdafe2b67f5efd359f20bb97165febe38b3c453fd2bfa7cd0a67165fea97c9db416ff1de3b1e9d77a6d12567bf8c159ed9d1ab7969fc2b8d378e2ba304579c93769bd719457fd524f2184cae221f51bd250a8fd3c35ae4cfec1b8b6fa06e3c6eaffc859d651f215b2d0c7efdab8327b969d459e9e8d7bfd57c68df587c43be4c1e20b685c1b9f0b17c1e283cfce927f96f911ca40d63fcbce7afebd31eb3a91b3fa37376ead9e64dea5759606a94f546eb23499883d9bc69932bef4acf22cf594725c1f8bfca9b3c8d3aa711e82c82bb73de3817111a4fe2171d67e1a1b97ba8e87ce5a8f12bfb48b2cfae8ceb85206894f9666135bff2e5c45d6fae894a3393a3f5be13aaeb7729eca4ff2d6ce3f5b701ef2b1c95f0aa7715dfb4de657519675d0fc8d8c9ba0f527f12faab234fd8fc695f1ab716dfa3f84ebb2089dec5f779678d381711d74beae398b7f540b3751bfd6e39ab1c9033b6bbd07e326687dcb3c2da8ecf47cfa301e9bbe37e389c94b3c0a2edba0f5f361dc194b3c8b36eed77acf9c453fab7f6d95587e6e8d83c957c25dc9668fdc5fc538b2c6e3a6e754e7adcc836252b6a9d69bccffb2ad535d67e98fb2ab538befaab3e8439947e5b84e82f6ffa17165f1bd7096fcc1ccb8b67a981b375a0f20f92d2775b078493dd54c75aaef0de9dfba75167fea2eb2f683dc5771388d753fbe396b7fca7c6b52ea2c5e57ce621fcbfdd26464f1812767ed8f63e3ced665de34c464fe9e1bb3d5b3f45bc3dca67a7fc9fba7697b46a9bf66cc13cb8fcc8b66c2960f3832b6f3988dad1e2828b799c53371d6f9766b9c5b7f4afe286983f5c3aeb3be177ace6c1ecc9cb51f6a678def8a7169f351fca710f5a93d9db3d64febacf9981aa76a2f5e3b6b7d5d1af7f6df3aebfb67e4acf93f72d6f972675cd83c7d77d67cac3bebfdfce9acf7eb87b3c66b665cdabc5feed9f44bfd51caade59395dbc4fc3f33cecc9f9b9e35bf786fdccfffc459e7ffc059eb7fe2acefcfd459df13dbceda5f4367bddffed8affdf0665c243a6f769c351f6367f51f7ad6fcefcf9dd57e72567fd959e3dd3a6bbc3b677daf34ce6affadb3dadbdb57263a5f46ce7adf8e9dd5dededfbe5e2f9cb5de5b678df7bb71a5fa59f767dccf77cd57d6f7136c185b7e79d359f3159cf53df7e8acf19e19f7f57ee5acef9b0d67f5b733b6fa844b63f38f07ceea9fcc3fca5b9bef58199b3dbce5acefa53567bd6fee8c73d54f95b3fa3b34b6fcc3b3b3f6dba1b3f6afe6a788fb6bad9f1f3f08f19b90b18ddff0f3dafefc2fe4bb284948f1b7f1e2e73fca4ff012af708ad77883b77f2f8f33bc8b9aeff1011ff1099f718e2ff88a6ff88e1ff8196da33fc92fe30aaee21aaee3060e70889bb885dbb88323dc8d7a407df941be8dd2dfa3ec5e94dac7033cc4233cc6133cc5333cc78bffb327c18029669863812556d1ef1a9ba8168080a1850ec608daaf30814bb882296ec035dc486426700b33b8837b78c0213cc2133ce367af3f7a93c01c5e700b5ee10d6fe11d093ee01396610556f104d6601d36a2d77abf0da2f41036610bb6b1841d18c12e7c873dd887033884233886133885b318297d3fc558e114cee1021208d1e01432c8a180122aa8e3c5190f2322c63bb507995aea62bc37698c9f34a14bba822d9ad235ddd02dcde80e87744f0f7fc823d1233de1363d634d737aa1577aa3ebf8047ba70ffaa4655aa1555aa375b37f0c298e6923ca0fb0a1212cd3266dd136edd08876e93bedd13e1dd0211d997e88f6031dd3099d624e67744e17f15f8b40296594cb273ef61632aa5ff34515d5d43032707c19449fd6e993db283b8217ee62fc0630fa31bf1cdf037c493bb1724ef98a162d30e56bcae185467cc3b731dfa0f935f919dff13daef1033ff2133fc77d039e73d41da55ff90d268b8afba17ea27d30a18edff9833f7999577895d7a88421aff31b6fc0e04ff5c6314acc031ef2266cc4c7ce036ff12ca66a10ff75d95eacfd2ccf3b0bfd38e651ac93f7d83b77f84e47d1e6f1222e0bf9c5ef3ff7a3f690766f4ffd0490aa85affffbf5cbef985d44a8 + + + + + Radio_1 + stateChanged(int) + GenPwDlg + OnRadio1StateChanged(int) + + + Radio_2 + stateChanged(int) + GenPwDlg + OnRadio2StateChanged(int) + + + ButtonGenerate + clicked() + GenPwDlg + OnGeneratePw() + + + ButtonOK + clicked() + GenPwDlg + OnAccept() + + + Button_Cancel + clicked() + GenPwDlg + OnCancel() + + + + Radio_1 + checkBox1 + checkBox2 + checkBox3 + checkBox4 + checkBox5 + checkBox6 + checkBox7 + checkBox8 + Radio_2 + Edit_chars + Spin_Num + Check_strongrandom + Edit_dest + ButtonGenerate + ButtonOK + Button_Cancel + + + OnRadio1StateChanged(int) + OnRadio2StateChanged(int) + OnGeneratePw() + OnAccept() + OnCancel() + + + diff --git a/src/forms/ui_SearchDlg.ui b/src/forms/ui_SearchDlg.ui new file mode 100755 index 0000000..ae996a9 --- /dev/null +++ b/src/forms/ui_SearchDlg.ui @@ -0,0 +1,327 @@ + +Search_Dlg + + + Search_Dlg + + + + 0 + 0 + 390 + 246 + + + + + 0 + 0 + 0 + 0 + + + + + 390 + 246 + + + + + 390 + 246 + + + + Suche... + + + + Banner + + + + 0 + 0 + 390 + 50 + + + + image0 + + + true + + + + + groupBox1 + + + + 10 + 130 + 370 + 70 + + + + Suche nach + + + + checkBox_Title + + + + 20 + 20 + 110 + 20 + + + + &Titel + + + Alt+T + + + + + checkBox_Username + + + + 20 + 40 + 110 + 20 + + + + Benut&zername + + + Alt+Z + + + + + checkBox_Comment + + + + 140 + 40 + 120 + 20 + + + + &Kommentar + + + Alt+K + + + + + checkBox_URL + + + + 260 + 20 + 100 + 20 + + + + &URL + + + Alt+U + + + + + checkBox_Attachment + + + + 260 + 40 + 100 + 20 + + + + A&nhang + + + Alt+N + + + + + checkBox_Password + + + + 140 + 20 + 110 + 20 + + + + Pass&wort + + + Alt+W + + + + + + Button_Close + + + + 280 + 210 + 97 + 23 + + + + S&chließen + + + Alt+C + + + + + textLabel1 + + + + 10 + 60 + 90 + 20 + + + + Suchbegriff: + + + + + Button_Search + + + + 170 + 210 + 97 + 23 + + + + Suchen + + + + + Edit_Search + + + + 110 + 60 + 270 + 21 + + + + + + checkBox_regExp + + + + 110 + 110 + 170 + 20 + + + + regul&ärer Ausdruck + + + Alt+ä + + + + + checkBox_Cs + + + + 110 + 90 + 250 + 20 + + + + Gro&ß- und Kleinschreibung beachten + + + Alt+ß + + + + + + 789c8597596f23470e80dfe75718c3b7c182e9eabb11ec834fc9873cbeaf601fc86ec9966df994cfc5fef794483633934d10c836fcb9582cde55fee5dbd2d9de68e9db2f5f9ee7349fb64bed153d2d7deb5e66b38fdffef3efff7ef99aa64b8baf2c5b4abffeebcb57dc5c6a9720499290640b8613e110ff22eb941b07657e7256f90be742e4a7c6a9ed076791c7a1732efbd784d3f817615a71167db0e55c0a17ce95c88f8ced3c7e74d6f306cea29fd159f583b3e8a75367d18f5bce8df0b63389be67e3ccfcd97716fd78e22cfaf1d459edefedcbedbc63e75af4cf85b33edeb8616cfef1b5b39eb7e72cf6c28b7166fb53678df7b5b3fadf388b3d503a8b3d40c6b9eaa35767d9cf37c6a5e53f73d6f3769d55bedf5f2789ac6bfcf2de1fda33ce4cdfbb716eeb6fce1acf1de3c2f2bbe7acf573605cdafe2b67f5efd359f20bb97165febe38b3c453fd2bfa7cd0a67165fea97c9db416ff1de3b1e9d77a6d12567bf8c159ed9d1ab7969fc2b8d378e2ba304579c93769bd719457fd524f2184cae221f51bd250a8fd3c35ae4cfec1b8b6fa06e3c6eaffc859d651f215b2d0c7efdab8327b969d459e9e8d7bfd57c68df587c43be4c1e20b685c1b9f0b17c1e283cfce927f96f911ca40d63fcbce7afebd31eb3a91b3fa37376ead9e64dea5759606a94f546eb23499883d9bc69932bef4acf22cf594725c1f8bfca9b3c8d3aa711e82c82bb73de3817111a4fe2171d67e1a1b97ba8e87ce5a8f12bfb48b2cfae8ceb85206894f9666135bff2e5c45d6fae894a3393a3f5be13aaeb7729eca4ff2d6ce3f5b701ef2b1c95f0aa7715dfb4de657519675d0fc8d8c9ba0f527f12faab234fd8fc695f1ab716dfa3f84ebb2089dec5f779678d381711d74beae398b7f540b3751bfd6e39ab1c9033b6bbd07e326687dcb3c2da8ecf47cfa301e9bbe37e389c94b3c0a2edba0f5f361dc194b3c8b36eed77acf9c453fab7f6d95587e6e8d83c957c25dc9668fdc5fc538b2c6e3a6e754e7adcc836252b6a9d69bccffb2ad535d67e98fb2ab538befaab3e8439947e5b84e82f6ffa17165f1bd7096fcc1ccb8b67a981b375a0f20f92d2775b078493dd54c75aaef0de9dfba75167fea2eb2f683dc5771388d753fbe396b7fca7c6b52ea2c5e57ce621fcbfdd26464f1812767ed8f63e3ced665de34c464fe9e1bb3d5b3f45bc3dca67a7fc9fba7697b46a9bf66cc13cb8fcc8b66c2960f3832b6f3988dad1e2828b799c53371d6f9766b9c5b7f4afe286983f5c3aeb3be177ace6c1ecc9cb51f6a678def8a7169f351fca710f5a93d9db3d64febacf9981aa76a2f5e3b6b7d5d1af7f6df3aebfb67e4acf93f72d6f972675cd83c7d77d67cac3bebfdfce9acf7eb87b3c66b665cdabc5feed9f44bfd51caade59395dbc4fc3f33cecc9f9b9e35bf786fdccfffc459e7ffc059eb7fe2acefcfd459df13dbceda5f4367bddffed8affdf0665c243a6f769c351f6367f51f7ad6fcefcf9dd57e72567fd959e3dd3a6bbc3b677daf34ce6affadb3dadbdb57263a5f46ce7adf8e9dd5dededfbe5e2f9cb5de5b678df7bb71a5fa59f767dccf77cd57d6f7136c185b7e79d359f3159cf53df7e8acf19e19f7f57ee5acef9b0d67f5b733b6fa844b63f38f07ceea9fcc3fca5b9bef58199b3dbce5acefa53567bd6fee8c73d54f95b3fa3b34b6fcc3b3b3f6dba1b3f6afe6a788fb6bad9f1f3f08f19b90b18ddff0f3dafefc2fe4bb284948f1b7f1e2e73fca4ff012af708ad77883b77f2f8f33bc8b9aeff1011ff1099f718e2ff88a6ff88e1ff8196da33fc92fe30aaee21aaee3060e70889bb885dbb88323dc8d7a407df941be8dd2dfa3ec5e94dac7033cc4233cc6133cc5333cc78bffb327c18029669863812556d1ef1a9ba8168080a1850ec608daaf30814bb882296ec035dc486426700b33b8837b78c0213cc2133ce367af3f7a93c01c5e700b5ee10d6fe11d093ee01396610556f104d6601d36a2d77abf0da2f41036610bb6b1841d18c12e7c873dd887033884233886133885b318297d3fc558e114cee1021208d1e01432c8a180122aa8e3c5190f2322c63bb507995aea62bc37698c9f34a14bba822d9ad235ddd02dcde80e87744f0f7fc823d1233de1363d634d737aa1577aa3ebf8047ba70ffaa4655aa1555aa375b37f0c298e6923ca0fb0a1212cd3266dd136edd08876e93bedd13e1dd0211d997e88f6031dd3099d624e67744e17f15f8b40296594cb273ef61632aa5ff34515d5d43032707c19449fd6e993db283b8217ee62fc0630fa31bf1cdf037c493bb1724ef98a162d30e56bcae185467cc3b731dfa0f935f919dff13daef1033ff2133fc77d039e73d41da55ff90d268b8afba17ea27d30a18edff9833f7999577895d7a88421aff31b6fc0e04ff5c6314acc031ef2266cc4c7ce036ff12ca66a10ff75d95eacfd2ccf3b0bfd38e651ac93f7d83b77f84e47d1e6f1222e0bf9c5ef3ff7a3f690766f4ffd0490aa85affffbf5cbef985d44a8 + + + + + Button_Search + clicked() + Search_Dlg + OnButtonSearch() + + + Button_Close + clicked() + Search_Dlg + OnButtonClose() + + + + Edit_Search + checkBox_Cs + checkBox_regExp + checkBox_Title + checkBox_Username + checkBox_Password + checkBox_Comment + checkBox_URL + checkBox_Attachment + Button_Search + Button_Close + + + OnButtonSearch() + OnButtonClose() + + + diff --git a/src/forms/ui_SettingsDlg.ui b/src/forms/ui_SettingsDlg.ui new file mode 100755 index 0000000..b9dde8d --- /dev/null +++ b/src/forms/ui_SettingsDlg.ui @@ -0,0 +1,492 @@ + +SettingsDialog + + + SettingsDialog + + + + 0 + 0 + 571 + 341 + + + + + 571 + 341 + + + + + 571 + 341 + + + + Einstellungen + + + + ButtonCancel + + + + 470 + 310 + 90 + 23 + + + + Abbre&chen + + + Alt+C + + + + + Banner + + + + 0 + 0 + 570 + 50 + + + + image0 + + + true + + + + + ButtonOK + + + + 380 + 310 + 80 + 23 + + + + O&K + + + Alt+K + + + + + tabWidget4 + + + + 10 + 60 + 550 + 240 + + + + + tab + + + Sicherhei&t + + + + textLabel1 + + + + 10 + 20 + 180 + 20 + + + + Zwischenablage löschen nach: + + + + + textLabel2 + + + + 280 + 20 + 100 + 20 + + + + Sekunden + + + + + SpinBox_ClipboardTime + + + + 190 + 20 + 80 + 20 + + + + + + CheckBox_ShowPasswords + + + + 10 + 50 + 420 + 20 + + + + Passw&örter standardmäßig in Klartext anzeigen + + + Alt+ö + + + + + + TabPage + + + E&rscheinungsbild + + + + groupBox1 + + + + 10 + 10 + 520 + 90 + + + + Bannerfarbverlauf + + + + textLabel1_3 + + + + 10 + 20 + 53 + 20 + + + + Farbe 1 + + + + + pixmColor1 + + + + 70 + 20 + 22 + 22 + + + + image0 + + + true + + + + + ButtonColor1 + + + + 100 + 20 + 60 + 23 + + + + &ändern... + + + Alt+ä + + + + + textLabel3 + + + + 190 + 20 + 60 + 20 + + + + Farbe 2 + + + + + pixmTextColor + + + + 70 + 50 + 22 + 22 + + + + image0 + + + true + + + + + ButtonTextColor + + + + 100 + 50 + 60 + 23 + + + + ändern... + + + + + + + + textLabel2_2 + + + + 10 + 50 + 54 + 20 + + + + Textfarbe + + + + + pixmColor2 + + + + 250 + 20 + 22 + 22 + + + + image0 + + + true + + + + + ButtonColor2 + + + + 280 + 20 + 60 + 23 + + + + ändern... + + + + + + + + + CheckBox_ExpandGroupTree + + + + 10 + 110 + 380 + 20 + + + + Gruppenbaum beim &Öffnen aufklappen + + + Alt+ö + + + + + + tab + + + S&onstiges + + + + CheckBox_OpenLast + + + + 10 + 20 + 380 + 20 + + + + zuletzt geöffnete Datei bei Programmstart &öffnen + + + Alt+ö + + + + + textLabel1_4 + + + + 10 + 50 + 110 + 20 + + + + Browseraufruf: + + + + + Edit_BrowserCmd + + + + 120 + 50 + 190 + 21 + + + + + + + + + 789c8597596f23470e80dfe75718c3b7c182e9eabb11ec834fc9873cbeaf601fc86ec9966df994cfc5fef794483633934d10c836fcb9582cde55fee5dbd2d9de68e9db2f5f9ee7349fb64bed153d2d7deb5e66b38fdffef3efff7ef99aa64b8baf2c5b4abffeebcb57dc5c6a9720499290640b8613e110ff22eb941b07657e7256f90be742e4a7c6a9ed076791c7a1732efbd784d3f817615a71167db0e55c0a17ce95c88f8ced3c7e74d6f306cea29fd159f583b3e8a75367d18f5bce8df0b63389be67e3ccfcd97716fd78e22cfaf1d459edefedcbedbc63e75af4cf85b33edeb8616cfef1b5b39eb7e72cf6c28b7166fb53678df7b5b3fadf388b3d503a8b3d40c6b9eaa35767d9cf37c6a5e53f73d6f3769d55bedf5f2789ac6bfcf2de1fda33ce4cdfbb716eeb6fce1acf1de3c2f2bbe7acf573605cdafe2b67f5efd359f20bb97165febe38b3c453fd2bfa7cd0a67165fea97c9db416ff1de3b1e9d77a6d12567bf8c159ed9d1ab7969fc2b8d378e2ba304579c93769bd719457fd524f2184cae221f51bd250a8fd3c35ae4cfec1b8b6fa06e3c6eaffc859d651f215b2d0c7efdab8327b969d459e9e8d7bfd57c68df587c43be4c1e20b685c1b9f0b17c1e283cfce927f96f911ca40d63fcbce7afebd31eb3a91b3fa37376ead9e64dea5759606a94f546eb23499883d9bc69932bef4acf22cf594725c1f8bfca9b3c8d3aa711e82c82bb73de3817111a4fe2171d67e1a1b97ba8e87ce5a8f12bfb48b2cfae8ceb85206894f9666135bff2e5c45d6fae894a3393a3f5be13aaeb7729eca4ff2d6ce3f5b701ef2b1c95f0aa7715dfb4de657519675d0fc8d8c9ba0f527f12faab234fd8fc695f1ab716dfa3f84ebb2089dec5f779678d381711d74beae398b7f540b3751bfd6e39ab1c9033b6bbd07e326687dcb3c2da8ecf47cfa301e9bbe37e389c94b3c0a2edba0f5f361dc194b3c8b36eed77acf9c453fab7f6d95587e6e8d83c957c25dc9668fdc5fc538b2c6e3a6e754e7adcc836252b6a9d69bccffb2ad535d67e98fb2ab538befaab3e8439947e5b84e82f6ffa17165f1bd7096fcc1ccb8b67a981b375a0f20f92d2775b078493dd54c75aaef0de9dfba75167fea2eb2f683dc5771388d753fbe396b7fca7c6b52ea2c5e57ce621fcbfdd26464f1812767ed8f63e3ced665de34c464fe9e1bb3d5b3f45bc3dca67a7fc9fba7697b46a9bf66cc13cb8fcc8b66c2960f3832b6f3988dad1e2828b799c53371d6f9766b9c5b7f4afe286983f5c3aeb3be177ace6c1ecc9cb51f6a678def8a7169f351fca710f5a93d9db3d64febacf9981aa76a2f5e3b6b7d5d1af7f6df3aebfb67e4acf93f72d6f972675cd83c7d77d67cac3bebfdfce9acf7eb87b3c66b665cdabc5feed9f44bfd51caade59395dbc4fc3f33cecc9f9b9e35bf786fdccfffc459e7ffc059eb7fe2acefcfd459df13dbceda5f4367bddffed8affdf0665c243a6f769c351f6367f51f7ad6fcefcf9dd57e72567fd959e3dd3a6bbc3b677daf34ce6affadb3dadbdb57263a5f46ce7adf8e9dd5dededfbe5e2f9cb5de5b678df7bb71a5fa59f767dccf77cd57d6f7136c185b7e79d359f3159cf53df7e8acf19e19f7f57ee5acef9b0d67f5b733b6fa844b63f38f07ceea9fcc3fca5b9bef58199b3dbce5acefa53567bd6fee8c73d54f95b3fa3b34b6fcc3b3b3f6dba1b3f6afe6a788fb6bad9f1f3f08f19b90b18ddff0f3dafefc2fe4bb284948f1b7f1e2e73fca4ff012af708ad77883b77f2f8f33bc8b9aeff1011ff1099f718e2ff88a6ff88e1ff8196da33fc92fe30aaee21aaee3060e70889bb885dbb88323dc8d7a407df941be8dd2dfa3ec5e94dac7033cc4233cc6133cc5333cc78bffb327c18029669863812556d1ef1a9ba8168080a1850ec608daaf30814bb882296ec035dc486426700b33b8837b78c0213cc2133ce367af3f7a93c01c5e700b5ee10d6fe11d093ee01396610556f104d6601d36a2d77abf0da2f41036610bb6b1841d18c12e7c873dd887033884233886133885b318297d3fc558e114cee1021208d1e01432c8a180122aa8e3c5190f2322c63bb507995aea62bc37698c9f34a14bba822d9ad235ddd02dcde80e87744f0f7fc823d1233de1363d634d737aa1577aa3ebf8047ba70ffaa4655aa1555aa375b37f0c298e6923ca0fb0a1212cd3266dd136edd08876e93bedd13e1dd0211d997e88f6031dd3099d624e67744e17f15f8b40296594cb273ef61632aa5ff34515d5d43032707c19449fd6e993db283b8217ee62fc0630fa31bf1cdf037c493bb1724ef98a162d30e56bcae185467cc3b731dfa0f935f919dff13daef1033ff2133fc77d039e73d41da55ff90d268b8afba17ea27d30a18edff9833f7999577895d7a88421aff31b6fc0e04ff5c6314acc031ef2266cc4c7ce036ff12ca66a10ff75d95eacfd2ccf3b0bfd38e651ac93f7d83b77f84e47d1e6f1222e0bf9c5ef3ff7a3f690766f4ffd0490aa85affffbf5cbef985d44a8 + + + + + ButtonOK + clicked() + SettingsDialog + OnOK() + + + ButtonCancel + clicked() + SettingsDialog + OnCancel() + + + ButtonColor1 + clicked() + SettingsDialog + OnColor1() + + + ButtonColor2 + clicked() + SettingsDialog + OnColor2() + + + ButtonTextColor + clicked() + SettingsDialog + OnTextColor() + + + + tabWidget4 + SpinBox_ClipboardTime + CheckBox_ShowPasswords + ButtonColor1 + ButtonTextColor + ButtonColor2 + CheckBox_OpenLast + Edit_BrowserCmd + ButtonOK + ButtonCancel + + + OnOK() + OnCancel() + OnColor1() + OnColor2() + OnTextColor() + newSlot() + + + diff --git a/src/forms/ui_SimplePasswordDlg.ui b/src/forms/ui_SimplePasswordDlg.ui new file mode 100755 index 0000000..1c0f52a --- /dev/null +++ b/src/forms/ui_SimplePasswordDlg.ui @@ -0,0 +1,154 @@ + +SimplePasswordDialog + + + SimplePasswordDialog + + + + 2 + 3 + 345 + 90 + + + + + 0 + 0 + 0 + 0 + + + + + 345 + 90 + + + + + 345 + 90 + + + + Passworteingabe + + + + textLabel1 + + + + 10 + 20 + 60 + 20 + + + + Passwort: + + + + + EditPassword + + + + 80 + 20 + 240 + 21 + + + + + + ButtonOK + + + + 170 + 60 + 80 + 23 + + + + O&K + + + Alt+K + + + + + ButtonCancel + + + + 257 + 60 + 80 + 23 + + + + Abbre&chen + + + Alt+C + + + + + Button_HidePassword + + + + 320 + 20 + 20 + 20 + + + + ... + + + + + + true + + + + + + Button_HidePassword + toggled(bool) + SimplePasswordDialog + OnHidePasswordToggled(bool) + + + ButtonOK + clicked() + SimplePasswordDialog + OnOK() + + + ButtonCancel + clicked() + SimplePasswordDialog + OnCancel() + + + + OnHidePasswordToggled(bool state) + OnOK() + OnCancel() + + + diff --git a/src/import/Import_KWalletXml.cpp b/src/import/Import_KWalletXml.cpp new file mode 100755 index 0000000..1506903 --- /dev/null +++ b/src/import/Import_KWalletXml.cpp @@ -0,0 +1,121 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * mail@tarek-saidi.de * + * * + * 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. * + ***************************************************************************/ + +#include "Import_KWalletXml.h" +#include +#include +#include +#include + +bool Import_KWalletXml::importFile(QString FileName,PwDatabase* pwm,QString& err){ +QFile file(FileName); +if(!file.exists()){ + err+=QObject::trUtf8("Datei nicht gefunden"); + return false;} +if(!file.open(IO_ReadOnly)){ + err+=QObject::trUtf8("Datei konnte nicht geöffnet werden"); + return false;} +int len=file.size(); +if(len==0){ + err+=QObject::trUtf8("Datei ist leer"); + return false;} +UINT8* buffer=new UINT8[len]; +file.readBlock((char*)buffer,len); +file.close(); +QDomDocument doc; +QString xmlerr; +int col,line; +if(!doc.setContent(QString::fromUtf8((char*)buffer,len),false,&xmlerr,&line,&col)){ + cout << "Import_PwManager::parseXmlContent():" << endl; + cout << (xmlerr+" (Line:%1 Column:%2)").arg(line).arg(col) << endl; + err+=QObject::trUtf8("Ungültiges XML-Dokument"); + delete [] buffer; + return false;} +delete [] buffer; +QDomElement root=doc.documentElement(); +if(root.tagName()!="wallet"){err+=QObject::trUtf8("Ungültiges XML-Dokument"); return false;} +QDomNodeList groups=root.elementsByTagName("folder"); +if(!groups.length()){err+=QObject::trUtf8("Dokument enthält keine Daten"); return false;} +for(int i=0;iaddGroup(NULL); + NewGroup->Name=CurrGroup.attribute("name"); + QDomNodeList entries=CurrGroup.elementsByTagName("password"); + for(int j=0;jaddEntry(); + NewEntry->Title=CurrEntry.attribute("name"); + NewEntry->GroupID=NewGroup->ID; + QString pw=CurrEntry.text(); + NewEntry->Password.setString(pw,true); + } +} +pwm->filename=""; +pwm->SearchGroupID=-1; +pwm->CryptoAlgorithmus=ALGO_AES; +pwm->KeyEncRounds=6000; +return true; +} + + +// unvollständiger Schnippsel zum Lesen des Binärformats +/* +QFile file(FileName); +if(!file.exists()){ + err+=QObject::trUtf8("Datei nicht gefunden"); + return false;} +if(!file.open(IO_ReadOnly)){ + err+=QObject::trUtf8("Datei konnte nicht geöffnet werden"); + return false;} +int len=file.size(); +int offset=0; +if(len<48){ + err+=QObject::trUtf8("Unerwartete Dateilänge"); + return false;} +UINT8* buffer=new UINT8[len]; +int df=file.readBlock((char*)buffer,len); +file.close(); + +if(memcmp(buffer,"KWALLET\n\r\0\r\n",12)){ + err+=QObject::trUtf8("Keine gültige KWallet-Datei"); + return false;} +offset+=12; +MajorVersion=buffer[offset]; +offset++; +MinorVersion=buffer[offset]; +offset++; +if(MajorVersion != 0 || MinorVersion !=0){ + err+=QObject::trUtf8("Nicht unterstützte Format Version"); + return false;} +CryptAlgo=buffer[offset]; +offset++; +if(CryptAlgo != 0){ + err+=QObject::trUtf8("Nicht unterstützter Verschlüsselungsalgorithmus"); + return false;} +HashAlgo=buffer[offset]; +offset++; +if(HashAlgo != 0){ + err+=QObject::trUtf8("Nicht unterstützter Hash-Algorithmus"); + return false;} +*/ diff --git a/src/import/Import_KWalletXml.h b/src/import/Import_KWalletXml.h new file mode 100755 index 0000000..be38e54 --- /dev/null +++ b/src/import/Import_KWalletXml.h @@ -0,0 +1,32 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * mail@tarek-saidi.de * + * * + * 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. * + ***************************************************************************/ +#ifndef _IMPORT_KWALLET_H_ +#define _IMPORT_KWALLET_H_ +#include +#include "PwManager.h" + +class Import_KWalletXml{ +public: + bool importFile(QString FileName,PwDatabase* db,QString& err); +private: + +}; + +#endif diff --git a/src/import/Import_PwManager.cpp b/src/import/Import_PwManager.cpp new file mode 100755 index 0000000..497f73e --- /dev/null +++ b/src/import/Import_PwManager.cpp @@ -0,0 +1,165 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * mail@tarek-saidi.de * + * * + * 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. * + ***************************************************************************/ + +#include +#include +#include +#include +#include "crypto/blowfish.h" +#include "crypto/sha1.h" +#include "Import_PwManager.h" + + +bool Import_PwManager::importFile(QString filename, QString password, PwDatabase* db, QString& err){ +database=db; +QFile file(filename); +char* buffer=NULL; +int offset=0; +int len=0; +if(!file.exists()){err+=QObject::trUtf8("Die angegebene Datei existiert nicht."); return false;} +if(!file.open(IO_ReadOnly)){err+=QObject::trUtf8("Datei konnte nicht geöffnet werden."); return false;} +if(len=file.size()) buffer=new char[len]; +else {err+=QObject::trUtf8("Datei ist leer"); return false;} +file.readBlock(buffer,len); +file.close(); +if(QString::fromAscii(buffer,17)!="PWM_PASSWORD_FILE") + {err+=QObject::trUtf8("Keine gültige PwManager-Datei"); return false;} +offset+=17; +if(buffer[offset]!=0x05) + {err+=QObject::trUtf8("Nicht unterstützte Version"); return false;} +offset++; +if(buffer[offset]!=0x01) + {err+=QObject::trUtf8("Nicht unterstützter Hash-Algorithmus"); return false;} +offset++; +if(buffer[offset]!=0x01) + {err+=QObject::trUtf8("Nicht unterstützter Hash-Algorithmus"); return false;} +offset++; +if(buffer[offset]!=0x01) + {err+=QObject::trUtf8("Nicht unterstützter Verschlüsselungs-Algorithmus"); return false;} +offset++; +if(buffer[offset]==0x00)Compression=0; +if(buffer[offset]==0x01)Compression=1; +if(buffer[offset]==0x02)Compression=2; + ///@TODO Compression + if(buffer[offset]) + {err+=QObject::trUtf8("Komprimierte PwManager-Dateien werden nicht unterstützt"); return false;} +offset++; +if(buffer[offset]==0x00)KeyFlag=true; +else KeyFlag=false; +offset++; +//Reserved Bytes (64) +offset+=64; +memcpy(KeyHash,buffer+offset,20); +offset+=20; +memcpy(DataHash,buffer+offset,20); +offset+=20; + +Blowfish blowfish; +int pwlen=password.length(); +byte* Key=new byte[pwlen]; +byte* xml=new byte[len-offset+1]; +xml[len-offset]=0; +memcpy(Key,password.ascii(),pwlen); + char* key_hash=new char[20]; + CSHA1 sha; + sha.Update(Key,pwlen); + sha.Final(); + sha.GetHash((unsigned char*)key_hash); + if(memcmp(key_hash,KeyHash,20)){ + delete[] Key; delete [] key_hash; delete [] buffer; + err+=QObject::trUtf8("Falsches Passwort"); + return false; +} +delete [] key_hash; +blowfish.bf_setkey(Key,password.length()); +blowfish.bf_decrypt(xml,(byte*)buffer+offset,len-offset); +delete [] Key; +delete [] buffer; + char* content_hash=new char[20]; + sha.Reset(); + sha.Update(xml,strlen((char*)xml)-1); + sha.Final(); + sha.GetHash((unsigned char*)content_hash); + if(memcmp(content_hash,DataHash,20)){ + delete [] content_hash; delete [] xml; + err+=QObject::trUtf8("Dateiinhalt ungültig (Hash-Test fehlgeschlagen)"); + return false; +} +delete[] content_hash; + +if(!parseXmlContent((char*)xml)){ + delete [] xml; + err+=QObject::trUtf8("Ungültiger XML-Inhalt"); return false;} +return true; +} + +bool Import_PwManager::parseXmlContent(char* content){ +QDomDocument db; +QString err; +int col,line; +if(!db.setContent(QString::fromUtf8(content,strlen(content)-1),false,&err,&line,&col)){ + cout << "Import_PwManager::parseXmlContent():" << endl; + cout << (err+" (Line:%1 Column:%2)").arg(line).arg(col) << endl; + return false;} +QDomElement root=db.documentElement(); +if(root.tagName()!="P")return false; +//Kommentar und Kategorie haben das selbe Tag "c" +if(!root.elementsByTagName("c").item(0).isElement())return false; +QDomElement groups=root.elementsByTagName("c").item(0).toElement(); + +int i=0; +while(1){ + QDomElement CurrGroup; + if(!groups.elementsByTagName("c"+QString::number(i)).length())break; + if(groups.elementsByTagName("c"+QString::number(i)).length()>1)return false; + if(!groups.elementsByTagName("c"+QString::number(i)).item(0).isElement())return false; + CurrGroup=groups.elementsByTagName("c"+QString::number(i)).item(0).toElement(); + if(!CurrGroup.hasAttribute("n"))return false; + CGroup* NewGroup=database->addGroup(NULL); + NewGroup->Name=CurrGroup.attribute("n"); + int j=0; + while(1){ + QDomElement CurrEntry; + if(!CurrGroup.elementsByTagName("e"+QString::number(j)).length())break; + if(CurrGroup.elementsByTagName("e"+QString::number(j)).length()>1)return false; + if(!CurrGroup.elementsByTagName("e"+QString::number(j)).item(0).isElement())return false; + CurrEntry=CurrGroup.elementsByTagName("e"+QString::number(j)).item(0).toElement(); + if(!xml_parseEntryAttributes(&CurrEntry,NewGroup))return false; + j++; + } + i++; +} + +return true; +} + +bool Import_PwManager::xml_parseEntryAttributes(QDomElement* EntryElement,CGroup* NewGroup){ +CEntry* e=database->addEntry(); +e->Title=EntryElement->elementsByTagName("d").item(0).toElement().text(); +e->UserName=EntryElement->elementsByTagName("n").item(0).toElement().text(); +QString pw=EntryElement->elementsByTagName("p").item(0).toElement().text(); +e->Password.setString(pw,true); +e->Additional=EntryElement->elementsByTagName("c").item(0).toElement().text(); +e->Additional=e->Additional.replace("$>--endl--<$","\n"); +e->URL=EntryElement->elementsByTagName("u").item(0).toElement().text(); +e->GroupID=NewGroup->ID; +return true; +} + diff --git a/src/import/Import_PwManager.h b/src/import/Import_PwManager.h new file mode 100755 index 0000000..dd4710b --- /dev/null +++ b/src/import/Import_PwManager.h @@ -0,0 +1,41 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * mail@tarek-saidi.de * + * * + * 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. * + ***************************************************************************/ + +#ifndef _IMPORT_PWMANAGER_ +#define _IMPORT_PWMANAGER_ +#include +#include +#include "PwManager.h" + +class Import_PwManager{ +public: +bool importFile(QString FileName, QString Password,PwDatabase* db,QString& err); +private: + bool KeyFlag; // true=Password, false=Chipcard + int Compression; // 0=none, 1=gzip, 2=bzip2 + unsigned char KeyHash[20]; + unsigned char DataHash[20]; + PwDatabase* database; + + bool parseXmlContent(char* content); + bool xml_parseEntryAttributes(QDomElement* EntryTag,CGroup* parent); +}; + +#endif \ No newline at end of file diff --git a/src/lib/IniReader.cpp b/src/lib/IniReader.cpp new file mode 100755 index 0000000..1e31505 --- /dev/null +++ b/src/lib/IniReader.cpp @@ -0,0 +1,488 @@ +// IniFile.cpp: Implementation of the CIniFile class. +// Written by: Adam Clauss +// Email: cabadam@houston.rr.com +// You may use this class/code as you wish in your programs. Feel free to distribute it, and +// email suggested changes to me. +// +// Rewritten by: Shane Hill +// Date: 21/08/2001 +// Email: Shane.Hill@dsto.defence.gov.au +// Reason: Remove dependancy on MFC. Code should compile on any +// platform. +////////////////////////////////////////////////////////////////////// + + +// C++ Includes +#include +#include +#include + +using namespace std; + +// C Includes +#include +#include +#include + +// Local Includes +#include "IniReader.h" + +#if defined(WIN32) +#define iniEOL endl +#else +#define iniEOL '\r' << endl +#endif + +CIniFile::CIniFile( string const iniPath) +{ + Path( iniPath); + caseInsensitive = true; +} + +bool CIniFile::ReadFile() +{ + // Normally you would use ifstream, but the SGI CC compiler has + // a few bugs with ifstream. So ... fstream used. + fstream f; + string line; + string keyname, valuename, value; + string::size_type pLeft, pRight; + + f.open( path.c_str(), ios::in); + if ( f.fail()) + return false; + + while( getline( f, line)) { + // To be compatible with Win32, check for existence of '\r'. + // Win32 files have the '\r' and Unix files don't at the end of a line. + // Note that the '\r' will be written to INI files from + // Unix so that the created INI file can be read under Win32 + // without change. + if ( line[line.length() - 1] == '\r') + line = line.substr( 0, line.length() - 1); + + if ( line.length()) { + // Check that the user hasn't openned a binary file by checking the first + // character of each line! + if ( !isprint( line[0])) { + printf( "Failing on char %d\n", line[0]); + f.close(); + return false; + } + if (( pLeft = line.find_first_of(";#[=")) != string::npos) { + switch ( line[pLeft]) { + case '[': + if ((pRight = line.find_last_of("]")) != string::npos && + pRight > pLeft) { + keyname = line.substr( pLeft + 1, pRight - pLeft - 1); + AddKeyName( keyname); + } + break; + + case '=': + valuename = line.substr( 0, pLeft); + value = line.substr( pLeft + 1); + SetValue( keyname, valuename, value); + break; + + case ';': + case '#': + if ( !names.size()) + HeaderComment( line.substr( pLeft + 1)); + else + KeyComment( keyname, line.substr( pLeft + 1)); + break; + } + } + } + } + + f.close(); + if ( names.size()) + return true; + return false; +} + +bool CIniFile::WriteFile() +{ + unsigned commentID, keyID, valueID; + // Normally you would use ofstream, but the SGI CC compiler has + // a few bugs with ofstream. So ... fstream used. + fstream f; + + f.open( path.c_str(), ios::out); + if ( f.fail()) + return false; + + // Write header comments. + for ( commentID = 0; commentID < comments.size(); ++commentID) + f << ';' << comments[commentID] << iniEOL; + if ( comments.size()) + f << iniEOL; + + // Write keys and values. + for ( keyID = 0; keyID < keys.size(); ++keyID) { + f << '[' << names[keyID] << ']' << iniEOL; + // Comments. + for ( commentID = 0; commentID < keys[keyID].comments.size(); ++commentID) + f << ';' << keys[keyID].comments[commentID] << iniEOL; + // Values. + for ( valueID = 0; valueID < keys[keyID].names.size(); ++valueID) + f << keys[keyID].names[valueID] << '=' << keys[keyID].values[valueID] << iniEOL; + f << iniEOL; + } + f.close(); + + return true; +} + +long CIniFile::FindKey( string const keyname) const +{ + for ( unsigned keyID = 0; keyID < names.size(); ++keyID) + if ( CheckCase( names[keyID]) == CheckCase( keyname)) + return long(keyID); + return noID; +} + +long CIniFile::FindValue( unsigned const keyID, string const valuename) const +{ + if ( !keys.size() || keyID >= keys.size()) + return noID; + + for ( unsigned valueID = 0; valueID < keys[keyID].names.size(); ++valueID) + if ( CheckCase( keys[keyID].names[valueID]) == CheckCase( valuename)) + return long(valueID); + return noID; +} + +unsigned CIniFile::AddKeyName( string const keyname) +{ + names.resize( names.size() + 1, keyname); + keys.resize( keys.size() + 1); + return names.size() - 1; +} + +string CIniFile::KeyName( unsigned const keyID) const +{ + if ( keyID < names.size()) + return names[keyID]; + else + return ""; +} + +unsigned CIniFile::NumValues( unsigned const keyID) +{ + if ( keyID < keys.size()) + return keys[keyID].names.size(); + return 0; +} + +unsigned CIniFile::NumValues( string const keyname) +{ + long keyID = FindKey( keyname); + if ( keyID == noID) + return 0; + return keys[keyID].names.size(); +} + +string CIniFile::ValueName( unsigned const keyID, unsigned const valueID) const +{ + if ( keyID < keys.size() && valueID < keys[keyID].names.size()) + return keys[keyID].names[valueID]; + return ""; +} + +string CIniFile::ValueName( string const keyname, unsigned const valueID) const +{ + long keyID = FindKey( keyname); + if ( keyID == noID) + return ""; + return ValueName( keyID, valueID); +} + +bool CIniFile::SetValue( unsigned const keyID, unsigned const valueID, string const value) +{ + if ( keyID < keys.size() && valueID < keys[keyID].names.size()) + keys[keyID].values[valueID] = value; + + return false; +} + +bool CIniFile::SetValue( string const keyname, string const valuename, string const value, bool const create) +{ + long keyID = FindKey( keyname); + if ( keyID == noID) { + if ( create) + keyID = long( AddKeyName( keyname)); + else + return false; + } + + long valueID = FindValue( unsigned(keyID), valuename); + if ( valueID == noID) { + if ( !create) + return false; + keys[keyID].names.resize( keys[keyID].names.size() + 1, valuename); + keys[keyID].values.resize( keys[keyID].values.size() + 1, value); + } else + keys[keyID].values[valueID] = value; + + return true; +} + +bool CIniFile::SetValueI( string const keyname, string const valuename, int const value, bool const create) +{ + char svalue[MAX_VALUEDATA]; + + sprintf( svalue, "%d", value); + return SetValue( keyname, valuename, svalue); +} + +bool CIniFile::SetValueF( string const keyname, string const valuename, double const value, bool const create) +{ + char svalue[MAX_VALUEDATA]; + + sprintf( svalue, "%f", value); + return SetValue( keyname, valuename, svalue); +} + +bool CIniFile::SetValueV( string const keyname, string const valuename, char *format, ...) +{ + va_list args; + char value[MAX_VALUEDATA]; + + va_start( args, format); + vsprintf( value, format, args); + va_end( args); + return SetValue( keyname, valuename, value); +} + +string CIniFile::GetValue( unsigned const keyID, unsigned const valueID, string const defValue) const +{ + if ( keyID < keys.size() && valueID < keys[keyID].names.size()) + return keys[keyID].values[valueID]; + return defValue; +} + +string CIniFile::GetValue( string const keyname, string const valuename, string const defValue) const +{ + long keyID = FindKey( keyname); + if ( keyID == noID) + return defValue; + + long valueID = FindValue( unsigned(keyID), valuename); + if ( valueID == noID) + return defValue; + + return keys[keyID].values[valueID]; +} + +int CIniFile::GetValueI(string const keyname, string const valuename, int const defValue) const +{ + char svalue[MAX_VALUEDATA]; + + sprintf( svalue, "%d", defValue); + return atoi( GetValue( keyname, valuename, svalue).c_str()); +} + +double CIniFile::GetValueF(string const keyname, string const valuename, double const defValue) const +{ + char svalue[MAX_VALUEDATA]; + + sprintf( svalue, "%f", defValue); + return atof( GetValue( keyname, valuename, svalue).c_str()); +} + +// 16 variables may be a bit of over kill, but hey, it's only code. +unsigned CIniFile::GetValueV( string const keyname, string const valuename, char *format, + void *v1, void *v2, void *v3, void *v4, + void *v5, void *v6, void *v7, void *v8, + void *v9, void *v10, void *v11, void *v12, + void *v13, void *v14, void *v15, void *v16) +{ + string value; + // va_list args; + unsigned nVals; + + + value = GetValue( keyname, valuename); + if ( !value.length()) + return false; + // Why is there not vsscanf() function. Linux man pages say that there is + // but no compiler I've seen has it defined. Bummer! + // + // va_start( args, format); + // nVals = vsscanf( value.c_str(), format, args); + // va_end( args); + + nVals = sscanf( value.c_str(), format, + v1, v2, v3, v4, v5, v6, v7, v8, + v9, v10, v11, v12, v13, v14, v15, v16); + + return nVals; +} + +bool CIniFile::DeleteValue( string const keyname, string const valuename) +{ + long keyID = FindKey( keyname); + if ( keyID == noID) + return false; + + long valueID = FindValue( unsigned(keyID), valuename); + if ( valueID == noID) + return false; + + // This looks strange, but is neccessary. + vector::iterator npos = keys[keyID].names.begin() + valueID; + vector::iterator vpos = keys[keyID].values.begin() + valueID; + keys[keyID].names.erase( npos, npos + 1); + keys[keyID].values.erase( vpos, vpos + 1); + + return true; +} + +bool CIniFile::DeleteKey( string const keyname) +{ + long keyID = FindKey( keyname); + if ( keyID == noID) + return false; + + // Now hopefully this destroys the vector lists within keys. + // Looking at source, this should be the case using the destructor. + // If not, I may have to do it explicitly. Memory leak check should tell. + // memleak_test.cpp shows that the following not required. + //keys[keyID].names.clear(); + //keys[keyID].values.clear(); + + vector::iterator npos = names.begin() + keyID; + vector::iterator kpos = keys.begin() + keyID; + names.erase( npos, npos + 1); + keys.erase( kpos, kpos + 1); + + return true; +} + +void CIniFile::Erase() +{ + // This loop not needed. The vector<> destructor seems to do + // all the work itself. memleak_test.cpp shows this. + //for ( unsigned i = 0; i < keys.size(); ++i) { + // keys[i].names.clear(); + // keys[i].values.clear(); + //} + names.clear(); + keys.clear(); + comments.clear(); +} + +void CIniFile::HeaderComment( string const comment) +{ + comments.resize( comments.size() + 1, comment); +} + +string CIniFile::HeaderComment( unsigned const commentID) const +{ + if ( commentID < comments.size()) + return comments[commentID]; + return ""; +} + +bool CIniFile::DeleteHeaderComment( unsigned commentID) +{ + if ( commentID < comments.size()) { + vector::iterator cpos = comments.begin() + commentID; + comments.erase( cpos, cpos + 1); + return true; + } + return false; +} + +unsigned CIniFile::NumKeyComments( unsigned const keyID) const +{ + if ( keyID < keys.size()) + return keys[keyID].comments.size(); + return 0; +} + +unsigned CIniFile::NumKeyComments( string const keyname) const +{ + long keyID = FindKey( keyname); + if ( keyID == noID) + return 0; + return keys[keyID].comments.size(); +} + +bool CIniFile::KeyComment( unsigned const keyID, string const comment) +{ + if ( keyID < keys.size()) { + keys[keyID].comments.resize( keys[keyID].comments.size() + 1, comment); + return true; + } + return false; +} + +bool CIniFile::KeyComment( string const keyname, string const comment) +{ + long keyID = FindKey( keyname); + if ( keyID == noID) + return false; + return KeyComment( unsigned(keyID), comment); +} + +string CIniFile::KeyComment( unsigned const keyID, unsigned const commentID) const +{ + if ( keyID < keys.size() && commentID < keys[keyID].comments.size()) + return keys[keyID].comments[commentID]; + return ""; +} + +string CIniFile::KeyComment( string const keyname, unsigned const commentID) const +{ + long keyID = FindKey( keyname); + if ( keyID == noID) + return ""; + return KeyComment( unsigned(keyID), commentID); +} + +bool CIniFile::DeleteKeyComment( unsigned const keyID, unsigned const commentID) +{ + if ( keyID < keys.size() && commentID < keys[keyID].comments.size()) { + vector::iterator cpos = keys[keyID].comments.begin() + commentID; + keys[keyID].comments.erase( cpos, cpos + 1); + return true; + } + return false; +} + +bool CIniFile::DeleteKeyComment( string const keyname, unsigned const commentID) +{ + long keyID = FindKey( keyname); + if ( keyID == noID) + return false; + return DeleteKeyComment( unsigned(keyID), commentID); +} + +bool CIniFile::DeleteKeyComments( unsigned const keyID) +{ + if ( keyID < keys.size()) { + keys[keyID].comments.clear(); + return true; + } + return false; +} + +bool CIniFile::DeleteKeyComments( string const keyname) +{ + long keyID = FindKey( keyname); + if ( keyID == noID) + return false; + return DeleteKeyComments( unsigned(keyID)); +} + +string CIniFile::CheckCase( string s) const +{ + if ( caseInsensitive) + for ( string::size_type i = 0; i < s.length(); ++i) + s[i] = tolower(s[i]); + return s; +} diff --git a/src/lib/IniReader.h b/src/lib/IniReader.h new file mode 100755 index 0000000..803d551 --- /dev/null +++ b/src/lib/IniReader.h @@ -0,0 +1,180 @@ +// IniFile.cpp: Implementation of the CIniFile class. +// Written by: Adam Clauss +// Email: cabadam@tamu.edu +// You may use this class/code as you wish in your programs. Feel free to distribute it, and +// email suggested changes to me. +// +// Rewritten by: Shane Hill +// Date: 21/08/2001 +// Email: Shane.Hill@dsto.defence.gov.au +// Reason: Remove dependancy on MFC. Code should compile on any +// platform. Tested on Windows/Linux/Irix +////////////////////////////////////////////////////////////////////// + +#ifndef CIniFile_H +#define CIniFile_H +using namespace std; +// C++ Includes +#include +#include + +// C Includes +#include + +#define MAX_KEYNAME 128 +#define MAX_VALUENAME 128 +#define MAX_VALUEDATA 2048 + +class CIniFile +{ +private: + bool caseInsensitive; + string path; + struct key { + vector names; + vector values; + vector comments; + }; + vector keys; + vector names; + vector comments; + string CheckCase( string s) const; + +public: + enum errors{ noID = -1}; + CIniFile( string const iniPath = ""); + virtual ~CIniFile() {} + + // Sets whether or not keynames and valuenames should be case sensitive. + // The default is case insensitive. + void CaseSensitive() {caseInsensitive = false;} + void CaseInsensitive() {caseInsensitive = true;} + + // Sets path of ini file to read and write from. + void Path(string const newPath) {path = newPath;} + string Path() const {return path;} + void SetPath(string const newPath) {Path( newPath);} + + // Reads ini file specified using path. + // Returns true if successful, false otherwise. + bool ReadFile(); + + // Writes data stored in class to ini file. + bool WriteFile(); + + // Deletes all stored ini data. + void Erase(); + void Clear() {Erase();} + void Reset() {Erase();} + + // Returns index of specified key, or noID if not found. + long FindKey( string const keyname) const; + + // Returns index of specified value, in the specified key, or noID if not found. + long FindValue( unsigned const keyID, string const valuename) const; + + // Returns number of keys currently in the ini. + unsigned NumKeys() const {return names.size();} + unsigned GetNumKeys() const {return NumKeys();} + + // Add a key name. + unsigned AddKeyName( string const keyname); + + // Returns key names by index. + string KeyName( unsigned const keyID) const; + string GetKeyName( unsigned const keyID) const {return KeyName(keyID);} + + // Returns number of values stored for specified key. + unsigned NumValues( unsigned const keyID); + unsigned GetNumValues( unsigned const keyID) {return NumValues( keyID);} + unsigned NumValues( string const keyname); + unsigned GetNumValues( string const keyname) {return NumValues( keyname);} + + // Returns value name by index for a given keyname or keyID. + string ValueName( unsigned const keyID, unsigned const valueID) const; + string GetValueName( unsigned const keyID, unsigned const valueID) const { + return ValueName( keyID, valueID); + } + string ValueName( string const keyname, unsigned const valueID) const; + string GetValueName( string const keyname, unsigned const valueID) const { + return ValueName( keyname, valueID); + } + + // Gets value of [keyname] valuename =. + // Overloaded to return string, int, and double. + // Returns defValue if key/value not found. + string GetValue( unsigned const keyID, unsigned const valueID, string const defValue = "") const; + string GetValue(string const keyname, string const valuename, string const defValue = "") const; + int GetValueI(string const keyname, string const valuename, int const defValue = 0) const; + bool GetValueB(string const keyname, string const valuename, bool const defValue = false) const { + return bool( GetValueI( keyname, valuename, int( defValue))); + } + double GetValueF(string const keyname, string const valuename, double const defValue = 0.0) const; + // This is a variable length formatted GetValue routine. All these voids + // are required because there is no vsscanf() like there is a vsprintf(). + // Only a maximum of 8 variable can be read. + unsigned GetValueV( string const keyname, string const valuename, char *format, + void *v1 = 0, void *v2 = 0, void *v3 = 0, void *v4 = 0, + void *v5 = 0, void *v6 = 0, void *v7 = 0, void *v8 = 0, + void *v9 = 0, void *v10 = 0, void *v11 = 0, void *v12 = 0, + void *v13 = 0, void *v14 = 0, void *v15 = 0, void *v16 = 0); + + // Sets value of [keyname] valuename =. + // Specify the optional paramter as false (0) if you do not want it to create + // the key if it doesn't exist. Returns true if data entered, false otherwise. + // Overloaded to accept string, int, and double. + bool SetValue( unsigned const keyID, unsigned const valueID, string const value); + bool SetValue( string const keyname, string const valuename, string const value, bool const create = true); + bool SetValueI( string const keyname, string const valuename, int const value, bool const create = true); + bool SetValueB( string const keyname, string const valuename, bool const value, bool const create = true) { + return SetValueI( keyname, valuename, int(value), create); + } + bool SetValueF( string const keyname, string const valuename, double const value, bool const create = true); + bool SetValueV( string const keyname, string const valuename, char *format, ...); + + // Deletes specified value. + // Returns true if value existed and deleted, false otherwise. + bool DeleteValue( string const keyname, string const valuename); + + // Deletes specified key and all values contained within. + // Returns true if key existed and deleted, false otherwise. + bool DeleteKey(string keyname); + + // Header comment functions. + // Header comments are those comments before the first key. + // + // Number of header comments. + unsigned NumHeaderComments() {return comments.size();} + // Add a header comment. + void HeaderComment( string const comment); + // Return a header comment. + string HeaderComment( unsigned const commentID) const; + // Delete a header comment. + bool DeleteHeaderComment( unsigned commentID); + // Delete all header comments. + void DeleteHeaderComments() {comments.clear();} + + // Key comment functions. + // Key comments are those comments within a key. Any comments + // defined within value names will be added to this list. Therefore, + // these comments will be moved to the top of the key definition when + // the CIniFile::WriteFile() is called. + // + // Number of key comments. + unsigned NumKeyComments( unsigned const keyID) const; + unsigned NumKeyComments( string const keyname) const; + // Add a key comment. + bool KeyComment( unsigned const keyID, string const comment); + bool KeyComment( string const keyname, string const comment); + // Return a key comment. + string KeyComment( unsigned const keyID, unsigned const commentID) const; + string KeyComment( string const keyname, unsigned const commentID) const; + // Delete a key comment. + bool DeleteKeyComment( unsigned const keyID, unsigned const commentID); + bool DeleteKeyComment( string const keyname, unsigned const commentID); + // Delete all comments for a key. + bool DeleteKeyComments( unsigned const keyID); + bool DeleteKeyComments( string const keyname); +}; + +#endif diff --git a/src/lib/PwmTime.cpp b/src/lib/PwmTime.cpp new file mode 100644 index 0000000..8a52658 --- /dev/null +++ b/src/lib/PwmTime.cpp @@ -0,0 +1,175 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * mail@tarek-saidi.de * + * * + * 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. * + ***************************************************************************/ +#include "PwmTime.h" + + +void CPwmTime::Set(unsigned char* pBytes){ +UINT32 dw1, dw2, dw3, dw4, dw5; +dw1 = (UINT32)pBytes[0]; dw2 = (UINT32)pBytes[1]; dw3 = (UINT32)pBytes[2]; +dw4 = (UINT32)pBytes[3]; dw5 = (UINT32)pBytes[4]; +// Unpack 5 byte structure to date and time +///@FIXME nicht Endian-sicher +Year = (dw1 << 6) | (dw2 >> 2); +Month = ((dw2 & 0x00000003) << 2) | (dw3 >> 6); +Day = (dw3 >> 1) & 0x0000001F; +Hour = ((dw3 & 0x00000001) << 4) | (dw4 >> 4); +Minute = ((dw4 & 0x0000000F) << 2) | (dw5 >> 6); +Second = dw5 & 0x0000003F; +} + +void CPwmTime::GetPackedTime(unsigned char* pBytes){ +///@FIXME nicht Endian-sicher +pBytes[0] = (UINT8)(((UINT32)Year >> 6) & 0x0000003F); +pBytes[1] = (UINT8)((((UINT32)Year & 0x0000003F) << 2) | (((UINT32)Month >> 2) & 0x00000003)); +pBytes[2] = (UINT8)((((UINT32)Month & 0x00000003) << 6) | (((UINT32)Day & 0x0000001F) << 1) | (((UINT32)Hour >> 4) & 0x00000001)); +pBytes[3] = (UINT8)((((UINT32)Hour & 0x0000000F) << 4) | (((UINT32)Minute >> 2) & 0x0000000F)); +pBytes[4] = (UINT8)((((UINT32)Minute & 0x00000003) << 6) | ((UINT32)Second & 0x0000003F)); +} + +QString CPwmTime::GetString(UINT16 format){ +QString str; +switch(format){ + case 0: + //DD.MM.YYYY HH:MM:SS + str=(QString)"%1.%2.%3 %4:%5:%6"; + break; + + case 1: + //MM/DD/YYYY HH:MM:SS + str=(QString)"%2/%1/%3 %4:%5:%6"; + break; +}; + + +if(Day<10){ +str=str.arg(((QString)"0"+QString::number(Day))); +}else{ +str=str.arg(Day);} + +if(Month<10){ +str=str.arg(((QString)"0"+QString::number(Month))); +}else{ +str=str.arg(Month);} + +str=str.arg(Year); + +if(Hour<10){ +str=str.arg(((QString)"0"+QString::number(Hour))); +}else{ +str=str.arg(Hour);} + +if(Minute<10){ +str=str.arg(((QString)"0"+QString::number(Minute))); +}else{ +str=str.arg(Minute);} + +if(Second<10){ +str=str.arg(((QString)"0"+QString::number(Second))); +}else{ +str=str.arg(Second);} + +return str; +} + +void CPwmTime::Set(UINT8 iDay,UINT8 iMonth,UINT16 iYear,UINT8 iHour,UINT8 iMinute,UINT8 iSecond){ +Day=iDay; +Month=iMonth; +Year=iYear; +Hour=iHour; +Minute=iMinute; +Second=iSecond; +} + +bool CPwmTime::IsValidDate(QString& s){ + +if(s.length()>10)return false; + +int count=0; +for(int i=0;i31 || day<1 || month>12 || month<1 || year<0 || year>2999)return false; +return true; +} + +bool CPwmTime::IsValidTime(QString& s){ + +if(s.length()>8)return false; + +int count=0; +for(int i=0;i23 || hour<0 || minute>59 || minute<0 || second>59 || second<0)return false; +return true; +} + +bool CPwmTime::SetDate(QString s){ +if(IsValidDate(s)==false)return false; +Day=s.section(".",0,0).toInt(); +Month=s.section(".",1,1).toInt(); +Year=s.section(".",2,2).toInt(); +return true; +} + +bool CPwmTime::SetTime(QString s){ +if(IsValidTime(s)==false)return false; +Hour=s.section(":",0,0).toInt(); +Minute=s.section(":",1,1).toInt(); +Second=s.section(":",2,2).toInt(); +return true; +} + +void CPwmTime::SetToNow(){ +time_t curTime=time(NULL); +tm* current=localtime(&curTime); +Year=current->tm_year+1900; +Month=current->tm_mon; +Day=current->tm_mday; +Hour=current->tm_hour; +Minute=current->tm_min; +Second=current->tm_sec; +} + +bool CPwmTime::operator==(const CPwmTime& t){ +if( Year==t.Year + && Month==t.Month + && Day==t.Day + && Hour==t.Hour + && Minute==t.Minute + && Second==t.Second) return true; +else return false; +} + +bool CPwmTime::operator!=(const CPwmTime& t){ +return !(*this==t); +} diff --git a/src/lib/PwmTime.h b/src/lib/PwmTime.h new file mode 100644 index 0000000..cd50b60 --- /dev/null +++ b/src/lib/PwmTime.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * mail@tarek-saidi.de * + * * + * 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. * + ***************************************************************************/ +#ifndef _PWMTIME_H_ +#define _PWMTIME_H_ + +#include +#include +class CPwmTime; +class CPwmTime{ +public: + UINT16 Year; + UINT8 Month; + UINT8 Day; + UINT8 Hour; + UINT8 Minute; + UINT8 Second; + + QString GetString(UINT16 format); + void Set(UINT8,UINT8,UINT16,UINT8,UINT8,UINT8); + void Set(unsigned char* packedTime); + void GetPackedTime(unsigned char* dst); + static bool IsValidDate(QString& string); + static bool IsValidTime(QString& string); + bool SetDate(QString string); + bool SetTime(QString string); + void SetToNow(); + bool operator==(const CPwmTime& t); + bool operator!=(const CPwmTime& t); +// bool operator>(const CPwmTime& t); +// bool operator<(const CPwmTime& t); + +}; + +#endif \ No newline at end of file diff --git a/src/lib/SecString.cpp b/src/lib/SecString.cpp new file mode 100755 index 0000000..2e45a37 --- /dev/null +++ b/src/lib/SecString.cpp @@ -0,0 +1,105 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * tarek@linux * + * * + * 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. * + ***************************************************************************/ + +#include "SecString.h" +#include +#include +#include "random.h" + +UINT8 SecString::Key[32]={0}; + +SecString::SecString(){ +data=NULL; +len=0; +cryptlen=0; +} + + +SecString::~SecString(){ +//if(data)delete [] data; ///@FIXME zerschießt den Stack, aber warum??? +overwrite(plaintext); +} + +void SecString::getString(QString & str){ +if(data){ +Rijndael aes; +int r=aes.init(Rijndael::CBC, Rijndael::Decrypt,Key,Rijndael::Key32Bytes); +if(r){ cout << "AES error, code " << r << endl; + exit(-1);} +char* out=new char[len]; +r=aes.padDecrypt((unsigned char*)data,cryptlen,(unsigned char*)out); +if(r!=len){ cout << "AES error in SecString::getString(), r!=length, r=" << r << endl; + exit(-1);} +str=QString::fromUtf8(out,len); +overwrite(out,len); +delete [] out; +} +} + +QString& SecString::getString(){ +getString(plaintext); +return plaintext; +} + +void SecString::delRef(){ +overwrite(plaintext); +} + +void SecString::setString(QString& str,bool DelSrc){ +Rijndael aes; +int r=aes.init(Rijndael::CBC, Rijndael::Encrypt,Key,Rijndael::Key32Bytes); +if(r){ cout << "AES error, code " << r << endl; + exit(-1);} +int il=str.length(); +char* input=new char[il]; +char* output=new char[il+16]; +memcpy(input,str.utf8(),il); +r=aes.padEncrypt((unsigned char*)input,il,(unsigned char*)output); +if(r<0){ cout << "AES error, code " << r << endl; + exit(-1);} +cryptlen=r; +len=il; +if(data)delete [] data; +data=output; +overwrite(input,il); +delete [] input; +if(DelSrc)overwrite(str); +} + +void SecString::overwrite(char* str,int strlen){ +if(strlen==0 || str==NULL)return; +getRandomBytes(str,strlen,1,false); +} + +void SecString::overwrite(QString &str){ +if(str.length()==0)return; +char* tmp=new char[str.length()]; +getRandomBytes(tmp,str.length(),1,false); +str=tmp; +delete [] tmp; +} + +int SecString::length(){ +return len; +} + +void SecString::generateSessionKey(){ +getRandomBytes(Key,32,1,false); +} \ No newline at end of file diff --git a/src/lib/SecString.h b/src/lib/SecString.h new file mode 100755 index 0000000..c7ed7c2 --- /dev/null +++ b/src/lib/SecString.h @@ -0,0 +1,51 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * tarek@linux * + * * + * 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. * + ***************************************************************************/ +#ifndef _SECSTRING_H_ +#define _SECSTRING_H_ + +#include +#include +#include "crypto/rijndael.h" + +class SecString{ +public: + SecString(unsigned char* key); + SecString(); + ~SecString(); + + void getString(QString& str); + QString& getString(); + void setString(QString& str, bool DelSrc=false); + void delRef(); + static void overwrite(char* str,int len); + static void overwrite(QString& str); + int length(); + static void generateSessionKey(); + +private: + static UINT8 Key[32]; + QString plaintext; + char* data; + int len; + int cryptlen; +}; + + +#endif \ No newline at end of file diff --git a/src/lib/UrlLabel.cpp b/src/lib/UrlLabel.cpp new file mode 100755 index 0000000..f86d102 --- /dev/null +++ b/src/lib/UrlLabel.cpp @@ -0,0 +1,55 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * tarek@linux * + * * + * 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. * + ***************************************************************************/ + + +#include "UrlLabel.h" +#include +#include +#include +#include + +LinkLabel::LinkLabel(QWidget *parent, const char* name,const QString& text, int x, int y,WFlags f) : QLabel(parent,name,f){ +QFont font(parentWidget()->font()); font.setUnderline(true); +setFont(font); +setPaletteForegroundColor(QColor(20,20,255)); +setCursor(PointingHandCursor); +setText(text); +setPos(x,y); +} + +LinkLabel::~LinkLabel(){ + +} + +void LinkLabel::mouseReleaseEvent(QMouseEvent* event){ +if(event->button()==LeftButton) +clicked(); +} + +void LinkLabel::setPos(int x,int y){ +QFontMetrics fm(font()); +setGeometry(x,y,fm.width(text()),fm.height()); + +} + +void LinkLabel::setText(const QString& text){ +QLabel::setText(text); +setPos(geometry().x(),geometry().y()); +} diff --git a/src/lib/UrlLabel.h b/src/lib/UrlLabel.h new file mode 100755 index 0000000..bd3dcb3 --- /dev/null +++ b/src/lib/UrlLabel.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * tarek@linux * + * * + * 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. * + ***************************************************************************/ + +#ifndef _LINKLABEL_H_ +#define _LINKLABEL_H_ +#include +#include + +class LinkLabel : public QLabel{ +Q_OBJECT +public: +LinkLabel(QWidget *parent, const char* name = 0,const QString& text=QString::null, int x=0, int y=0,WFlags f=0); +~LinkLabel(); +void setPos(int x,int y); + +public slots: +virtual void setText(const QString&); + + +signals: + void clicked(); + +protected: +virtual void mouseReleaseEvent(QMouseEvent* event); + +}; + +#endif \ No newline at end of file diff --git a/src/lib/random.cpp b/src/lib/random.cpp new file mode 100755 index 0000000..7336547 --- /dev/null +++ b/src/lib/random.cpp @@ -0,0 +1,47 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * mail@tarek-saidi.de * + * * + * 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. * + ***************************************************************************/ +#include +#include +#include +#include +#include "random.h" + +void getRandomBytes(void* buffer,int NumBlocks,int BlockSize,bool Strong){ +FILE *dev_random; +if(Strong){ +dev_random = fopen("/dev/random","r");} +else{ +dev_random = fopen("/dev/urandom","r");} + +if (dev_random==NULL){ + cout << QObject::tr("/dev/random konnte nicht geöffnet werden - nutze Standardbibliothek (stdlib)") << endl; + srand(QTime(0,0,0).secsTo(QTime::currentTime())); + for(int i=0;i + + + +int main(int argc, char **argv) +{ + QApplication app(argc,argv); + PwSafe *mainWin = 0; + /// @todo do something with the command line args here + mainWin = new PwSafe(&app); + app.setMainWidget( mainWin ); + mainWin->show(); + return app.exec(); +} + + + + +/********* KDE ************** +#include +#include +#include +#include + +static const char description[] = + I18N_NOOP("A KDE KPart Application"); + +static const char version[] = "0.1"; + +static KCmdLineOptions options[] = +{ +// { "+[URL]", I18N_NOOP( "Document to open" ), 0 }, + KCmdLineLastOption +}; + +int main(int argc, char **argv) +{ + KAboutData about("Keepass", I18N_NOOP("Keepass"), version, description, + KAboutData::License_BSD, "(C) %{YEAR} Tarek Saidi", 0, 0, "tareks@arcor.de"); + about.addAuthor( "Tarek Saidi", 0, "tareks@arcor.de" ); + KCmdLineArgs::init(argc, argv, &about); + KCmdLineArgs::addCmdLineOptions( options ); + KApplication app; + PwSafe *mainWin = 0; + + if (app.isRestored()) + { + RESTORE(PwSafe); + } + else + { + // no session.. just start up normally + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + + /// @todo do something with the command line args here + + mainWin = new PwSafe(); + app.setMainWidget( mainWin ); + mainWin->show(); + + args->clear(); + } + + // mainWin has WDestructiveClose flag by default, so it will delete itself. + return app.exec(); +} + +*/ + + diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp new file mode 100755 index 0000000..71c18e4 --- /dev/null +++ b/src/mainwindow.cpp @@ -0,0 +1,1378 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * tarek@linux * + * * + * 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. * + ***************************************************************************/ + +//QT +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//STD +#include +//local +#include "lib/random.h" +#include "lib/IniReader.h" +#include "ListViews.h" +#include + +#include "dialogs/AboutDlg.h" +#include "dialogs/EditGroupDlg.h" +#include "dialogs/SearchDlg.h" +#include "dialogs/ChangeKeyDlg.h" +#include "dialogs/LanguageDlg.h" +#include "dialogs/SettingsDlg.h" +#include "dialogs/DatabaseSettingsDlg.h" +#include "dialogs/PasswordDlg.h" +#include "dialogs/SimplePasswordDlg.h" +#include "dialogs/EditEntryDlg.h" +#include "dialogs/PasswordGenDlg.h" + +#include "import/Import_PwManager.h" +#include "import/Import_KWalletXml.h" + +CMainWindow::CMainWindow(QApplication* app,QWidget* parent,const char* name, WFlags fl) +: MainFrame(parent,name,fl) +{ +FileOpen=false; +App=app; +appdir=app->applicationDirPath(); +parentWidget()->setCaption(tr("Keepass Passwortsafe")); +SecString::generateSessionKey(); + +// Config // +if(!QDir(QDir::homeDirPath()+"/.keepass").exists()){ + QDir conf(QDir::homeDirPath()); + if(!conf.mkdir(".keepass")){ + cout << trUtf8("Warnung: Verzeichnis ~/.keepass konnte nicht erstellt werden.") << endl;} +} +config.loadFromIni(); +CGroup::UI_ExpandByDefault=config.ExpandGroupTree; + +// Language // +QLocale loc=QLocale::system(); +translator = 0; +translator =new QTranslator; + +if(config.Language==""){ + switch(loc.language()){ + case QLocale::German: + config.Language="_DEUTSCH_"; + break; + case QLocale::English: + config.Language="english.qm"; + break; + default: + config.Language="english.qm"; + break;} +} + +if(config.Language!="_DEUTSCH_"){ + if(!translator->load(appdir+"/../share/keepass/i18n/"+config.Language)){ + if(!translator->load(appdir+"/share/i18n/"+config.Language)){ + config.Language="_DEUTSCH_"; + QMessageBox::warning(this,tr("Warnung"), + trUtf8("Die Übersetzungsdatei '%1' konnte nicht geladen werden.\n Die Sprache wurde auf Deutsch zurückgesetzt.") + .arg(config.Language),tr("OK"),0,0,2,1); + delete translator; + translator=NULL;}} + else app->installTranslator(translator); +} + + +// Icons, Pixmaps // + +QImage tmpImg; +//----------------------- +LoadImg("clientic.png",tmpImg); +EntryIcons=new QPixmap[52]; +for(int i=0;i<52;i++){ +EntryIcons[i]=tmpImg.copy(i*16,0,16,16); +} + +//-------------------------- +LoadImg("key.png",tmpImg); +Icon_Key32x32=new QPixmap; +*Icon_Key32x32=tmpImg; + +//-------------------------- +LoadImg("settings.png",tmpImg); +Icon_Settings32x32=new QPixmap; +*Icon_Settings32x32=tmpImg; + +//-------------------------- +LoadImg("i18n.png",tmpImg); +Icon_I18n32x32=new QPixmap; +*Icon_I18n32x32=tmpImg; + +//-------------------------- +LoadImg("ok.png",tmpImg); +Icon_Ok16x16=new QPixmap; +*Icon_Ok16x16=tmpImg; + +//-------------------------- +LoadImg("search.png",tmpImg); +Icon_Search32x32=new QPixmap; +*Icon_Search32x32=tmpImg; +///nicht vergessen: die müssen im Destr. auch wieder gelöscht werden!/// + + +// Signal-Slot Connections // +connect(&ClipboardTimer, SIGNAL(timeout()), this, SLOT(OnClipboardTimerEvent())); +connect(GroupView,SIGNAL(collapsed(QListViewItem*)),this, SLOT(OnGroupItemCollapsed(QListViewItem*))); +connect(GroupView,SIGNAL(expanded(QListViewItem*)),this, SLOT(OnGroupItemExpanded(QListViewItem*))); + + +// MainWnd // +CurrentGroup=NULL; +CurrentEntry=NULL; +Clipboard=QApplication::clipboard(); +GroupView->setSorting(-1); + +if(config.Toolbar){ + View_ShowToolBar->setOn(true);} +else{ Toolbar->hide(); + View_ShowToolBar->setOn(false);} + +if(config.EntryDetails){ + View_ShowEntryDetails->setOn(true);} +else{ SummaryField->hide(); + View_ShowEntryDetails->setOn(false);} + + +if(config.Columns[0]){ + View_Column_Title->setOn(true);} +else{ + View_Column_Title->setOn(false);} + +if(config.Columns[1]){ + View_Column_Username->setOn(true);} +else{ + View_Column_Username->setOn(false);} + +if(config.Columns[2]){ + View_Column_URL->setOn(true);} +else{ + View_Column_URL->setOn(false);} + +if(config.Columns[3]){ + View_Column_Password->setOn(true);} +else{ + View_Column_Password->setOn(false);} + +if(config.Columns[4]){ + View_Column_Comment->setOn(true);} +else{ + View_Column_Comment->setOn(false);} + +if(config.Columns[5]){ + View_Column_Expire->setOn(true);} +else{ + View_Column_Expire->setOn(false);} + +if(config.Columns[6]){ + View_Column_Creation->setOn(true);} +else{ + View_Column_Creation->setOn(false);} + +if(config.Columns[7]){ + View_Column_LastMod->setOn(true);} +else{ + View_Column_LastMod->setOn(false);} + +if(config.Columns[8]){ + View_Column_LastAccess->setOn(true);} +else{ + View_Column_LastAccess->setOn(false);} + +if(config.Columns[9]){ + View_Column_Attachment->setOn(true);} +else{ + View_Column_Attachment->setOn(false);} + +if(config.ListView_HidePasswords){ + View_HidePasswords->setOn(true);} +else{ + View_HidePasswords->setOn(false);} + +if(config.ListView_HideUsernames){ + View_HideUsernames->setOn(true);} +else{ + View_HideUsernames->setOn(false);} + +} + +void CMainWindow::LoadImg(QString name,QImage& tmpImg){ +if(tmpImg.load(appdir+"/../share/keepass/"+name)==false){ + if(tmpImg.load(appdir+"/share/"+name)==false){ + QMessageBox::critical(this,trUtf8("Fehler"),trUtf8("Die Datei '%1' konnte nicht gefunden werden.") + .arg(name),trUtf8("OK"),0,0,2,1); + exit(-1); +}} + +} + + +CMainWindow::~CMainWindow() +{ +OnClose(); +if(!config.saveToIni()) + QMessageBox::warning(this,tr("Warnung"),trUtf8("Die Konfigurationsdatei konnte nicht gespeichert werden.Stellen Sie sicher, dass\nSie Schreibrechte im Verzeichnis ~/.keepass besitzen."),tr("OK"),"","",0.0); +if(translator)delete translator; +delete [] EntryIcons; +delete Icon_Key32x32; +delete Icon_Settings32x32; +delete Icon_Search32x32; +delete Icon_I18n32x32; +delete Icon_Ok16x16; +} + +void CMainWindow::OnClose() +{ +if(FileOpen) CloseDataBase(); +parentWidget()->close(); +} + +void CMainWindow::OnMainWinResize() +{ + +} + +void CMainWindow::OnFileOpen(){ +QString filename=QFileDialog::getOpenFileName(QDir::homeDirPath(),"*.kdb",this,trUtf8("Datenbank öffnen")); +if(filename=="")return; +OpenDatabase(filename); +} + + +void CMainWindow::OpenDatabase(QString filename) +{ +if(FileOpen==true) CloseDataBase(); +CPasswordDialog dlg(this,0,true); +dlg.setCaption(filename); +dlg.exec(); + +if(dlg.canceled)return; + +db = new PwDatabase(); + +if(dlg.password!="" && dlg.keyfile==""){ +db->CalcMasterKeyByPassword(dlg.password); +} +if(dlg.password=="" && dlg.keyfile!=""){ +db->CalcMasterKeyByFile(dlg.keyfile); +} +if(dlg.password!="" && dlg.keyfile!=""){ +db->CalcMasterKeyByFileAndPw(dlg.keyfile,dlg.password); +} +QString err; +if(db->loadDatabase(filename,err)==true){ +updateGroupView(); +SetFileMenuState(STATE_FileOpen); +setModFlag(false); +parentWidget()->setCaption(tr("Keepass - %1").arg(filename)); +FileOpen=true; +} +else{ +///@FIXME MessageBox erscheint im Hintergrund +//mgl parent MainWindow ist noch nicht offen +//mgl parent CPasswordDlg ist schon zu +//tritt nur mit libqtkde.so auf +delete db; +FileOpen=false; +QMessageBox::critical(NULL,trUtf8("Fehler"),trUtf8("Beim öffnen der Datenbank ist ein Fehler aufgetreten:\n%1") + .arg(err),trUtf8("OK"),0,0); +} +} + +void CMainWindow::updateGroupView(){ +GroupView->clear(); +GroupItems.clear(); +EntryView->clear(); +EntryItems.clear(); + +//Level==0 -> Parent=GroupView +//Level>lastLevel -> Parent=lastItem +//Level<=lastLevel -> Parent=last higher Item(reverse) + +for(GroupItr i=db->Groups.begin();i!=db->Groups.end();i++){ +if((*i).Level==0){ + if(GroupItems.size())GroupItems.push_back(new GroupItem(&(*i),GroupView,getLastSameLevelItem(0),(*i).Name)); + else GroupItems.push_back(new GroupItem(&(*i),GroupView,(*i).Name)); +} + else{ + if((*i).Level>(*(i-1)).Level){ + GroupItems.push_back(new GroupItem(&(*i),(*(GroupItems.end()-1)),getLastSameLevelItem((*i).Level),(*i).Name)); + } + if((*i).Level<=(*(i-1)).Level){ + GroupItemItr j; + for(j=GroupItems.end()-1;j!=GroupItems.begin();j--){ + if((*j)->pGroup->Level<(*i).Level)break;} + GroupItems.push_back(new GroupItem(&(*i),(*j),getLastSameLevelItem((*i).Level),(*i).Name)); + } + } +(*(GroupItems.end()-1))->setPixmap(0,EntryIcons[(*i).ImageID]); +} + +for(int i=0;isetOpen(GroupItems[i],GroupItems[i]->pGroup->UI_ItemIsExpanded); +} + +} + + +void CMainWindow::OnGroupChanged(QListViewItem* item){ +if(item){ +SetEditMenuState(STATE_SingleGroupSelected); +setCurrentGroup((GroupItem*)item); +} +else SetEditMenuState(STATE_NoGroupSelected); +SummaryField->setText(""); +SetEditMenuState(STATE_NoEntrySelected); +} + +void CMainWindow::setCurrentGroup(GroupItem* item){ +CurrentGroup=item; +updateEntryView(); +} + +void CMainWindow::SetupColumns(){ +int NumColumns=EntryView->columns(); +for(int i=0;iremoveColumn(0); +int columnID[10]; +int i=0; +if(config.Columns[0]){ +columnID[0]=EntryView->addColumn(trUtf8("Titel"),0); i++;} +if(config.Columns[1]){ +columnID[1]=EntryView->addColumn(trUtf8("Benutzername"),0); i++;} +if(config.Columns[2]){ +columnID[2]=EntryView->addColumn(trUtf8("URL"),0); i++;} +if(config.Columns[3]){ +columnID[3]=EntryView->addColumn(trUtf8("Passwort"),0); i++;} +if(config.Columns[4]){ +columnID[4]=EntryView->addColumn(trUtf8("Kommentare"),0); i++;} +if(config.Columns[5]){ +columnID[5]=EntryView->addColumn(trUtf8("Gültig bis"),0); i++;} +if(config.Columns[6]){ +columnID[6]=EntryView->addColumn(trUtf8("Erstellung"),0); i++;} +if(config.Columns[7]){ +columnID[7]=EntryView->addColumn(trUtf8("letzte Änderung"),0); i++;} +if(config.Columns[8]){ +columnID[8]=EntryView->addColumn(trUtf8("letzter Zugriff"),0); i++;} +if(config.Columns[9]){ +columnID[9]=EntryView->addColumn(trUtf8("Anhang"),0); i++;} +ResizeColumns(); + +} + +void CMainWindow::ResizeColumns(){ +int cols=EntryView->columns(); +int width=(EntryView->width()-4)/cols; //Ränder mit je 2 Px Breite??? +for(int i=0;isetColumnWidth(i,width); +} +} + + +void CMainWindow::updateEntryView(){ +// Achtung: +// Die ->pEntry bzw ->pGroup Zeiger sind zu diesem Zeitpunkt ungültig! +if(CurrentEntry){ + + +} +EntryView->clear(); +EntryItems.clear(); +if(!CurrentGroup)return; +EntryItem *tmp=NULL; +for(int i=0;iEntries.size();i++){ +CEntry* entry=&db->Entries[i]; +if((CurrentGroup->pGroup->ID==entry->GroupID) || (CurrentGroup->pGroup->ID==db->SearchGroupID && isInSearchResults(entry))){ +EntryItems.push_back(tmp=new EntryItem(entry,EntryView)); +int j=0; +if(config.Columns[0]){ +tmp->setText(j++,entry->Title);} +if(config.Columns[1]){ + if(config.ListView_HideUsernames) + tmp->setText(j++,"******"); + else + tmp->setText(j++,entry->UserName);} +if(config.Columns[2]){ +tmp->setText(j++,entry->URL);} +if(config.Columns[3]){ + if(config.ListView_HidePasswords) + tmp->setText(j++,"******"); + else{ + tmp->setText(j++,entry->Password.getString()); + entry->Password.delRef();}} +if(config.Columns[4]){ +tmp->setText(j++,entry->Additional.section('\n',0,0));} +if(config.Columns[5]){ +tmp->setText(j++,entry->Expire.GetString(0));} +if(config.Columns[6]){ +tmp->setText(j++,entry->Creation.GetString(0));} +if(config.Columns[7]){ +tmp->setText(j++,entry->LastMod.GetString(0));} +if(config.Columns[8]){ +tmp->setText(j++,entry->LastAccess.GetString(0));} +if(config.Columns[9]){ +tmp->setText(j++,entry->BinaryDesc);} + (*(EntryItems.end()-1))->setPixmap(0,EntryIcons[entry->ImageID]); + } +} +} + +void CMainWindow::OnEntryChanged(QListViewItem* item){ +SetEditMenuState(STATE_SingleEntrySelected); +CEntry& entry=*((EntryItem*)item)->pEntry; + +QString str=trUtf8("Gruppe: %1 Titel: %2 Benutzername: %3 URL: %4 Passwort: %5 Erstellt: %6 letzte Änderung: %7 letzter Zugriff: %8 gültig bis: %9"); + +str= str.arg(CurrentGroup->pGroup->Name) + .arg(entry.Title) + .arg(entry.UserName) + .arg(entry.URL) + .arg(entry.Password.getString()) + .arg(entry.Creation.GetString(0)) + .arg(entry.LastMod.GetString(0)) + .arg(entry.LastAccess.GetString(0)) + .arg(entry.Expire.GetString(0)); + +SummaryField->setText(str); +entry.Password.delRef(); +CurrentEntry=(EntryItem*)item; +} + + +void CMainWindow::showEvent(QShowEvent *event){ +if(event->spontaneous()==false){ +SetEditMenuState(STATE_NoGroupSelected); +QValueList s; +s.push_back(25); s.push_back(100); +parentWidget()->resize(750,450); +splitter->setSizes(s); +GroupView->addColumn(trUtf8("Gruppen")); +GroupView->setColumnWidth(0,GroupView->width()-4); +SetupColumns(); +InitMenus(); +if(config.OpenLast && config.LastFile!="") +{ QFileInfo file(config.LastFile); + if(file.exists() && file.isFile())OpenDatabase(config.LastFile); + else config.LastFile="";} + +//////////////////////////////////// +/*Beim öffnen der Datenbank ist ein Fehler aufgetreten. +if(db->IsOpen==true) CloseDataBase(); +QString filename="/home/tarek/Desktop/wallet.xml"; +Import_KWalletXml importer; +QString err; +if(!importer.importFile(filename,&pwmanager,err)){ + cout << err << endl; + return; +} +cout << "Erfolg" << endl; +updateGroupView(); +SetFileMenuState(STATE_FileOpen); +*/ +//////////////////////////////////// +} +} + +void CMainWindow::OnEntryDoubleClicked(QListViewItem* item,const QPoint& Point, int column){ +if(item && (column==0)){ +OnEditEntry(); +} +} + + +void CMainWindow::CreateBanner(QLabel *Banner,QPixmap* symbol,QString text){ +CreateBanner(Banner,symbol,text,config.BannerColor1 + ,config.BannerColor2 + ,config.BannerTextColor); //überladene Funktion wird aufgerufen +} + +void CMainWindow::CreateBanner(QLabel *Banner,QPixmap* symbol,QString text,QColor color1,QColor color2,QColor textcolor){ +int w=Banner->width(); +int h=Banner->height(); +QColor color; +float b1[3]; +float b2[3]; +float a1,a2; +QPixmap* banner_pixmap=new QPixmap(w,h); ///@FIXME löscht der Destruktor von QLabel die Pixmap zum schluss??? +QPainter painter(banner_pixmap,24); +QPen pen; +pen.setWidth(1); +painter.setPen(pen); +QFont font("Arial",16); +painter.setFont(font); +if(color1!=color2){ +b1[0]=color1.red(); +b1[1]=color1.green(); +b1[2]=color1.blue(); +b2[0]=color2.red(); +b2[1]=color2.green(); +b2[2]=color2.blue(); +///@FIXME Farbtiefe < 24 Bit (Dithering?) +for(int x=0;xfill(color1); +} + +painter.drawPixmap(10,10,*symbol); +pen.setColor(textcolor); +painter.setPen(pen); +painter.drawText(50,30,text); +Banner->setPixmap(*banner_pixmap); +} + + +void CMainWindow::CloseDataBase(){ +if(modflag){ +int r=QMessageBox::question(this,trUtf8("Datenbank speichern?"),trUtf8("Soll die aktuelle Datenbank vor dem Schließen gespeichert werden?") + ,trUtf8("Ja"),trUtf8("Nein"),trUtf8("Abbrechen"),2,2); +if(r==2)return; +if(r==0)OnFileSave();} +SummaryField->setText(""); +SetEditMenuState(STATE_NoEntrySelected); +SetEditMenuState(STATE_NoGroupSelected); +EntryView->clear(); +EntryItems.clear(); +GroupView->clear(); +GroupItems.clear(); +config.LastFile=db->filename; +db->CloseDataBase(); +delete db; +FileOpen=false; +} + +void CMainWindow::OnMenu_closeDB() +{ +CloseDataBase(); +SetFileMenuState(STATE_NoFileOpen); +SetEditMenuState(STATE_NoEntrySelected); +SetEditMenuState(STATE_NoGroupSelected); +parentWidget()->setCaption(tr("Keepass Passwortsafe")); +} + +void CMainWindow::OnFileSave() +{ +if(db->filename==""){ +OnFileSaveAs(); +return; +} +if(db->SaveDataBase(db->filename))setModFlag(false); +} + +void CMainWindow::OnFileSaveAs() +{ +QString filename=QFileDialog::getSaveFileName(QDir::homeDirPath(),"*.kdb",this,trUtf8("Datenbank öffnen")); +if(filename=="")return; +db->filename=filename; +config.LastFile=filename; +db->SaveDataBase(filename); +setModFlag(false); +parentWidget()->setCaption(tr("Keepass - %1").arg(filename)); +} + +void CMainWindow::InitMenus(){ +SetEditMenuState(STATE_NoEntrySelected); +SetEditMenuState(STATE_NoGroupSelected); +SetFileMenuState(STATE_NoFileOpen); +} + + +void CMainWindow::SetFileMenuState(FileMenuState status){ +switch(status){ + case STATE_FileOpen: + File_Save->setEnabled(true); + File_SaveAs->setEnabled(true); + File_Close->setEnabled(true); + File_ChangeKey->setEnabled(true); + File_Settings->setEnabled(true); + Edit_NewGroup->setEnabled(true); + Edit_GlobalSearch->setEnabled(true); + toolButtonSave->setEnabled(true); + toolButtonAddEntry->setEnabled(true); + GroupView->setEnabled(true); + EntryView->setEnabled(true); + SummaryField->setEnabled(true); + break; + case STATE_NoFileOpen: + File_Save->setDisabled(true); + File_SaveAs->setDisabled(true); + File_Close->setDisabled(true); + File_ChangeKey->setDisabled(true); + File_Settings->setDisabled(true); + Edit_NewGroup->setDisabled(true); + Edit_GlobalSearch->setDisabled(true); + toolButtonSave->setDisabled(true); + toolButtonAddEntry->setEnabled(false); + GroupView->setDisabled(true); + EntryView->setDisabled(true); + SummaryField->setDisabled(true); + break; +} +} + +void CMainWindow::SetEditMenuState(EditMenuState status){ +switch(status){ + case STATE_NoGroupSelected: + Edit_NewSubGroup->setDisabled(true); + Edit_GroupProperties->setDisabled(true); + Edit_DeleteGroup->setDisabled(true); + Edit_AddEntry->setDisabled(true); + Edit_GroupSearch->setDisabled(true); + toolButtonAddEntry->setEnabled(false); + break; + case STATE_NoEntrySelected: + Edit_UserNameToClipboard->setDisabled(true); + Edit_PasswordToClipboard->setDisabled(true); + Edit_SaveAttachment->setDisabled(true); + Edit_OpenURL->setDisabled(true); + Edit_DeleteEntry->setDisabled(true); + Edit_EditEntry->setDisabled(true); + Edit_CopyEntry->setDisabled(true); + toolButtonEditEntry->setDisabled(true); + toolButtonDeleteEntry->setDisabled(true); + toolButtonUserNameToClipboard->setDisabled(true); + toolButtonPasswordToClipboard->setDisabled(true); + break; + case STATE_SingleGroupSelected: + Edit_NewSubGroup->setEnabled(true); + Edit_GroupProperties->setEnabled(true); + Edit_DeleteGroup->setEnabled(true); + Edit_AddEntry->setEnabled(true); + Edit_GroupSearch->setEnabled(true); + toolButtonAddEntry->setEnabled(true); + break; + case STATE_SingleEntrySelected: + toolButtonEditEntry->setDisabled(false); + toolButtonDeleteEntry->setDisabled(false); + toolButtonUserNameToClipboard->setDisabled(false); + toolButtonPasswordToClipboard->setDisabled(false); + Edit_UserNameToClipboard->setEnabled(true); + Edit_PasswordToClipboard->setEnabled(true); + Edit_SaveAttachment->setEnabled(true); + Edit_OpenURL->setEnabled(true); + Edit_DeleteEntry->setEnabled(true); + Edit_EditEntry->setEnabled(true); + Edit_CopyEntry->setEnabled(true); + break; +} +} + +void CMainWindow::OnMenuExit() +{ +OnClose(); +} + +void CMainWindow::OnAddGroup() +{ +CEditGroupDialog dlg(this,trUtf8("Gruppeneigenschaften"),true,NULL); +dlg.exec(); +if(dlg.OK==false)return; +CGroup* NewGroup=db->addGroup(NULL); +NewGroup->Name=dlg.GroupName; +NewGroup->ImageID=dlg.IconID; +updateGroupView(); +setModFlag(true); +} + + +void CMainWindow::OnAddSubGroup() +{ +CEditGroupDialog dlg(this,trUtf8("Gruppeneigenschaften"),true,NULL); +dlg.exec(); +if(dlg.OK==false)return; +CGroup* NewGroup=db->addGroup(CurrentGroup->pGroup); +NewGroup->Name=dlg.GroupName; +NewGroup->ImageID=dlg.IconID; +//GroupItems.push_back(new GroupItem(NewGroup,CurrentGroup,NewGroup->Name)); +updateGroupView(); +setModFlag(true); +} + +void CMainWindow::OnEditGroup() +{ +GroupItem* item=CurrentGroup; +CGroup& group=*item->pGroup; +CEditGroupDialog dlg(this,trUtf8("Gruppeneigenschaften"),true,NULL); +dlg.GroupName=group.Name; +dlg.IconID=group.ImageID; +dlg.exec(); +if(dlg.OK==false)return; +group.Name=dlg.GroupName; +group.ImageID=dlg.IconID; +item->setText(0,group.Name); +item->setPixmap(0,EntryIcons[group.ImageID]); +setModFlag(true); +} + + + +void CMainWindow::OnDeleteGroup() +{ +db->deleteGroup(CurrentGroup->pGroup); +CurrentGroup=NULL; +SetEditMenuState(STATE_NoGroupSelected); +updateGroupView(); +updateEntryView(); +setModFlag(true); +} + + +void CMainWindow::OnPasswordToClipboard() +{ +Clipboard->setText(CurrentEntry->pEntry->Password.getString(),QClipboard::Clipboard); +ClipboardTimer.start(config.ClipboardTimeOut*1000,true); +CurrentEntry->pEntry->Password.delRef(); +} + +void CMainWindow::OnUserNameToClipboard() +{ +Clipboard->setText(CurrentEntry->pEntry->UserName, QClipboard::Clipboard); +ClipboardTimer.start(config.ClipboardTimeOut*1000,true); +} + +void CMainWindow::OnClipboardTimerEvent(){ +Clipboard->clear(QClipboard::Clipboard); //löscht nicht den KDE-Klipper +} + +void CMainWindow::OnOpenURL() +{ +OpenURL(CurrentEntry->pEntry->URL); +} + +void CMainWindow::OpenURL(QString url){ +QProcess browser; +browser.setArguments(QStringList::split(' ',config.OpenUrlCommand.arg(url))); +browser.start(); +} + +void CMainWindow::OnSaveAttachment() +{ +CEntry& entry=*CurrentEntry->pEntry; +if(entry.BinaryDataLength==0){ +QMessageBox::information(NULL,trUtf8("Hinweis"),trUtf8("Dieser Eintrag hat keinen Dateianhang."),"OK"); +return; +} +QString filename=QFileDialog::getSaveFileName(QDir::homeDirPath(),"",this,trUtf8("Anhang speichern...")); +if(filename=="")return; +QFile file(filename); +if(file.exists()){ +int r=QMessageBox::warning(this,trUtf8("Vorhandene Datei überschreiben?"),trUtf8("Unter dem gewählten Dateinamen existiert bereits eine Datei.\nSoll sie überschrieben werden?"),trUtf8("Ja"),trUtf8("Nein"),NULL,1,1); +if(r==1)return; +if(file.remove()==false){ +QMessageBox::critical(NULL,trUtf8("Fehler"),trUtf8("Datei konnte nicht überschrieben werden."),trUtf8("OK")); +return;} +} +if(file.open(IO_WriteOnly)==false){ +QMessageBox::critical(NULL,trUtf8("Fehler"),trUtf8("Datei konnte nicht erstellt werden."),trUtf8("OK")); +return; +} + +int r=file.writeBlock((char*)entry.pBinaryData,entry.BinaryDataLength); +if(r==-1){ +file.close(); +QMessageBox::critical(NULL,trUtf8("Fehler"),trUtf8("Beim schreiben in der Datei ist ein Fehler aufgetreten."),trUtf8("OK")); +return; +} +if(r!=entry.BinaryDataLength){ +file.close(); +QMessageBox::critical(NULL,trUtf8("Fehler"),trUtf8("Die Datei konnte nicht vollständig geschrieben werden."),trUtf8("OK")); +return; +} +file.close(); +} + +void CMainWindow::OnAddEntry() +{ +CEntry entry; +entry.ImageID=0; +entry.GroupID=CurrentGroup->pGroup->ID; +entry.Creation.SetToNow(); +entry.LastMod.SetToNow(); +entry.LastAccess.SetToNow(); +entry.Expire.Set(28,12,2999,0,0,0); +entry.BinaryDataLength=0; +entry.pBinaryData=NULL; +entry.PasswordLength=0; + +CEditEntryDlg* pDlg= new CEditEntryDlg(this,0,true); +pDlg->entry=&entry; +if(pDlg->exec()){ + if(db->Entries.size()==0){ + entry.sID=0; + getRandomBytes(&entry.ID,16,1,false); + } + else { + entry.sID=(*(db->Entries.end()-1)).sID+1; + while(1){ + bool used=false; + getRandomBytes(&entry.ID,16,1,false); + for(int j=0;jEntries.size();j++){ + int k; + for(k=0;k<16;k++){if(db->Entries[j].ID[k]!=entry.ID[k])k=0;break;} + if(k==15)used=true;} + if(used==false)break; + }} + db->Entries.push_back(entry); + updateEntryView(); + setModFlag(true); +} + +} + +void CMainWindow::OnEditEntry() +{ +CEditEntryDlg* pDlg= new CEditEntryDlg(this,0,true); +pDlg->entry=CurrentEntry->pEntry; +pDlg->exec(); +updateEntryView(); +if(pDlg->ModFlag)setModFlag(true); +} + +void CMainWindow::OnCopyEntry() +{ +CEntry &src=*CurrentEntry->pEntry; +CEntry entry=src; +entry.sID=(*(db->Entries.end()-1)).sID+1; +while(1){ +bool used=false; +getRandomBytes(&entry.ID,16,1,false); + for(int j=0;jEntries.size();j++){ + int k; + for(k=0;k<16;k++){if(db->Entries[j].ID[k]!=entry.ID[k])k=0;break;} + if(k==15)used=true;} +if(used==false)break; +} +entry.Creation.SetToNow(); +entry.LastMod.SetToNow(); +entry.LastAccess.SetToNow(); +entry.Expire.Set(28,12,2999,0,0,0); +db->Entries.push_back(entry); +if(entry.BinaryDataLength>0){ +CEntry &new_entry=(*(db->Entries.end()-1)); +new_entry.pBinaryData=new unsigned char[new_entry.BinaryDataLength]; +memcpy(new_entry.pBinaryData,src.pBinaryData,new_entry.BinaryDataLength); +} +updateEntryView(); +setModFlag(true); +} + +void CMainWindow::OnDeleteEntry() +{ +db->deleteEntry(CurrentEntry->pEntry); +updateEntryView(); +setModFlag(true); +} + +void CMainWindow::OnGlobalSearch() +{ +Search(); +} + +void CMainWindow::OnGroupSearch() +{ +Search(CurrentGroup->pGroup); +} + +void CMainWindow::Search(CGroup* pGroup){ +CSearchDlg dlg(pGroup,this,"SearchDialog",true); +if(!dlg.exec())return; +if(!dlg.hits.size()){ + QMessageBox::information(this,tr("Suche erfolglos"),trUtf8("Die Suche lieferte keine Ergebnisse."),trUtf8("OK"),0,0,2,1); + return;} +if(db->SearchGroupID!=-1){ + db->deleteGroup(db->SearchGroupID); + SearchResults.clear(); + db->SearchGroupID=-1; +} +CGroup* group=db->addGroup(NULL); +db->SearchGroupID=group->ID; +group->Name=tr("Suchergebnisse"); +SearchResults.clear(); +for(int i=0;isID); +} +updateGroupView(); + +} + +void CMainWindow::OnEntryRightClicked(QListViewItem* item, const QPoint& pos,int column) +{ +if(!FileOpen)return; +if(!CurrentGroup) return; +QPopupMenu menu; +connect(&menu, SIGNAL(activated(int)), this, SLOT(OnEntryCtxMenuClicked(int))); +menu.insertItem(trUtf8("Passwort in Zwischenablage kopieren"),1); +menu.insertItem(trUtf8("Benutzername in Zwischenablage kopieren"),2); +menu.insertItem(trUtf8("URL öffnen"),3); +menu.insertItem(trUtf8("Anhang speichern..."),4); +menu.insertSeparator(); +menu.insertItem(trUtf8("Eintrag hinzufügen..."),5); +menu.insertItem(trUtf8("Eintrag anzeigen/bearbeiten"),6); +menu.insertItem(trUtf8("Eintrag duplizieren"),7); +menu.insertItem(trUtf8("Eintrag löschen"),8); + +if(column==-1){ +menu.setItemEnabled(1,false); +menu.setItemEnabled(2,false); +menu.setItemEnabled(3,false); +menu.setItemEnabled(4,false); +menu.setItemEnabled(6,false); +menu.setItemEnabled(7,false); +menu.setItemEnabled(8,false);} + +if(CurrentGroup->pGroup->ID==db->SearchGroupID){ +menu.setItemEnabled(5,false); +menu.setItemEnabled(7,false); +} + +menu.exec(pos); + +} + +void CMainWindow::OnEntryCtxMenuClicked(int id){ +switch(id){ +case 1:OnPasswordToClipboard(); +break; +case 2:OnUserNameToClipboard(); +break; +case 3:OnOpenURL(); +break; +case 4:OnSaveAttachment(); +break; +case 5:OnAddEntry(); +break; +case 6:OnEditEntry(); +break; +case 7:OnCopyEntry(); +break; +case 8:OnDeleteEntry(); +break; +} +} + +void CMainWindow::OnGroupRightClicked(QListViewItem* item, const QPoint& pos, int column) +{ +if(!FileOpen)return; + +QPopupMenu menu; +if(column!=-1){ + if(((GroupItem*)item)->pGroup->ID!=db->SearchGroupID){ + connect(&menu, SIGNAL(activated(int)), this, SLOT(OnGroupCtxMenuClicked(int))); + //menu.insertItem(trUtf8("Gruppe hinzufügen..."),1); + menu.insertItem(trUtf8("Untergruppe hinzufügen..."),2); + menu.insertSeparator(); + menu.insertItem(trUtf8("Gruppe löschen"),3); + menu.insertItem(trUtf8("Eigenschaften"),4);} + else{ + connect(&menu, SIGNAL(activated(int)), this, SLOT(OnSearchGroupCtxMenuClicked(int))); + menu.insertItem(trUtf8("Ausblenden"),1);} +} +else +{ +connect(&menu, SIGNAL(activated(int)), this, SLOT(OnGroupCtxMenuClicked(int))); + menu.insertItem(trUtf8("Gruppe hinzufügen..."),1); +} +menu.exec(pos); +} + +void CMainWindow::OnSearchGroupCtxMenuClicked(int id){ +/*if(db->SearchGroupID!=-1){ + db->DeleteGroup(db->GetGroupIterator(db->SearchGroupID)); + SearchResults.clear(); + delete GetGroupItem(db->SearchGroupID); + DeleteGroupAssoc(db->SearchGroupID); + db->SearchGroupID=-1; + SetEditMenuState(STATE_NoGroupSelected); + RefreshEntryView(); +}*/ +} + +void CMainWindow::OnGroupCtxMenuClicked(int id){ +switch(id){ +case 1:OnAddGroup(); +break; +case 2:OnAddSubGroup(); +break; +case 3:OnDeleteGroup(); +break; +case 4:OnEditGroup(); +break; +} +} + +void CMainWindow::OnDbSettings() +{ +CDbSettingsDlg dlg(this,db,trUtf8("Einstellungen"),true); +dlg.exec(); +} + +void CMainWindow::OnChangeDbKey() +{ +CChangeKeyDlg dlg(this,db); +dlg.exec(); +setModFlag(true); +} + +void CMainWindow::OnFileNew() +{ +if(FileOpen==true) CloseDataBase(); +db=new PwDatabase(); +db->NewDataBase(); +CChangeKeyDlg dlg(this,db); +if(dlg.exec()==1){ +updateGroupView(); +SetFileMenuState(STATE_FileOpen); +setModFlag(true); +FileOpen=true; +} +else delete db; +} + +void CMainWindow::OnViewToolbarToggled(bool toggled) +{ +config.Toolbar=toggled; +if(toggled){ +Toolbar->show(); +} +else +{ +Toolbar->hide(); +} +} + +void CMainWindow::OnViewEntryDetailsToggled(bool toggled) +{ +config.EntryDetails=toggled; +if(toggled){ +SummaryField->show(); +} +else +{ +SummaryField->hide(); +} +} + +void CMainWindow::OnSettings() +{ +CSettingsDlg dlg(this,0,true); +dlg.exec(); + +} + +void CMainWindow::OnHelpAbout() +{ +CAboutDialog* pDlg= new CAboutDialog(this,0,true); +pDlg->show(); + +} + +void CMainWindow::OnView_ColumnExpireToggled(bool value) +{ +config.Columns[5]=value; +SetupColumns(); +updateEntryView(); + +} + +void CMainWindow::OnView_ColumnAttachmentToggled(bool value) +{ +config.Columns[9]=value; +SetupColumns(); +updateEntryView(); +} + +void CMainWindow::OnView_ColumnUrlToggled(bool value) +{ +config.Columns[2]=value; +SetupColumns(); +updateEntryView(); +} + + +void CMainWindow::OnView_ColumnTitleToggled(bool value) +{ +config.Columns[0]=value; +SetupColumns(); +updateEntryView(); +} + + +void CMainWindow::OnView_ColumnCreationToggled(bool value) +{ +config.Columns[6]=value; +SetupColumns(); +updateEntryView(); +} + + +void CMainWindow::OnView_ColumnLastAccessToggled(bool value) +{ +config.Columns[8]=value; +SetupColumns(); +updateEntryView(); +} + + +void CMainWindow::OnView_ColumnLastModToggled(bool value) +{ +config.Columns[7]=value; +SetupColumns(); +updateEntryView(); +} + + +void CMainWindow::OnView_ColumnCommentToggled(bool value) +{ +config.Columns[4]=value; +SetupColumns(); +updateEntryView(); +} + + +void CMainWindow::OnView_ColumnPasswordToggled(bool value) +{ +config.Columns[3]=value; +SetupColumns(); +updateEntryView(); +} + +void CMainWindow::OnView_ColumnUsernameToggled(bool value) +{ +config.Columns[1]=value; +SetupColumns(); +updateEntryView(); +} + +void CMainWindow::OnExtrasLanguage() +{ +CLanguageDlg dlg(this,0,true); +dlg.exec(); +} + +bool CMainWindow::isInSearchResults(CEntry* pEntry){ +for(int i=0; isID==SearchResults[i])return true;} +return false; +} + +void CMainWindow::OnQickSearch() +{ +QMessageBox::information(this,trUtf8("Platzhalter"),trUtf8("< noch nicht implementiert >"),trUtf8("OK"),0,0,2,1); +} + +void CMainWindow::setModFlag(bool flag){ +modflag=flag; +toolButtonSave->setEnabled(flag); +} + +void CMainWindow::OnGroupItemExpanded(QListViewItem* item){ +((GroupItem*)item)->pGroup->UI_ItemIsExpanded=true; +} + +void CMainWindow::OnGroupItemCollapsed(QListViewItem* item){ +((GroupItem*)item)->pGroup->UI_ItemIsExpanded=false; +} + +void CMainWindow::DEBUG_OnPrintDbStucture() +{ + +if(!FileOpen){cout << "db->IsOpen=false" << endl; return;} + +cout << "NumEntries=" << db->Entries.size() << endl; +cout << "NumGroups=" << db->Groups.size() << endl; +cout << "------------------Group Vector-----------------" << endl; +if(db->Groups.size()){ +//cout << "Start: 0x" << QString::number((unsigned int)&db->Groups.front(),16) << endl; +//cout << "End: 0x" << QString::number((unsigned int)&db->Groups.back(),16) << endl; +for(int i=0;iGroups.size();i++){ +cout << QString("(+%1) '%2', Level=%3, ID=%4").arg(i).arg(db->Groups[i].Name).arg(db->Groups[i].Level).arg(db->Groups[i].ID) + << endl; +} +} +cout << "------------------Entry Vector-----------------" << endl; +if(db->Entries.size()){ +//cout << "Start: 0x" << QString::number((unsigned int)&db->Entries.front(),16) << endl; +//cout << "End: 0x" << QString::number((unsigned int)&db->Entries.back(),16) << endl; +for(int i=0;iEntries.size();i++){ +QString groupname="???"; + for(int j=0;jGroups.size();j++){ + if(db->Groups[j].ID==db->Entries[i].GroupID){ + groupname="'"+db->Groups[j].Name+"'"; + break;} +} +cout << QString("(+%1) '%2', GroupID=%3 [%4], sID=%5").arg(i).arg(db->Entries[i].Title).arg(db->Entries[i].GroupID).arg(groupname).arg(db->Entries[i].sID) + << endl; +} +} +cout << endl; + +} + +GroupItem* CMainWindow::getLastSameLevelItem(int level){ +for(int i=GroupItems.size()-1;i>=0;i--){ + if(GroupItems[i]->pGroup->Level==level){ +return GroupItems[i];} +} +return GroupItems.back(); + +} + +void CMainWindow::OnImportPwManagerFile() +{ +bool merge=false; +if(FileOpen){ +int ret=QMessageBox::question(this,tr("Frage"), + trUtf8("Es ist noch eine andere Datenbank geöffnet. Soll sie mit der zu importierenden Datenbank zusammengeführt oder geschlossen werden werden?"), + trUtf8("Zusammenführen"),trUtf8("Schließen"),tr("Abbrechen"),1,2); +switch(ret){ + case 0: merge=true; + break; + case 1: CloseDataBase(); + break; + case 2: return; + } +} +QString filename=QFileDialog::getOpenFileName(QDir::homeDirPath(),"*.pwm",this,trUtf8("Datenbank importieren")); +if(filename=="")return; +CSimplePasswordDialog dlg(!config.ShowPasswords,this,"SimplePasswordDlg",true); +if(!dlg.exec())return; +Import_PwManager importer; +QString err; + +if(merge){ + PwDatabase* ImportDb=new PwDatabase(); + if(!importer.importFile(filename,dlg.password,ImportDb,err)){ + delete ImportDb; + QMessageBox::critical(this,trUtf8("Fehler"),trUtf8("Die Datei konnte nicht importiert werden.\n%1").arg(err),trUtf8("OK"),0,0,2,1); + return;} + db->merge(ImportDb); + delete ImportDb; +} +else{ + db=new PwDatabase(); + if(!importer.importFile(filename,dlg.password,db,err)){ + delete db; + QMessageBox::critical(this,trUtf8("Fehler"),trUtf8("Die Datei konnte nicht importiert werden.\n%1").arg(err),trUtf8("OK"),0,0,2,1); + return;} + CChangeKeyDlg dlg(this,db); + if(dlg.exec()!=1){ + delete db; + return; + } +} +updateGroupView(); +SetFileMenuState(STATE_FileOpen); +FileOpen=true; +} + +void CMainWindow::OnView_HideUsernamesToggled(bool state) +{ +config.ListView_HideUsernames=state; +updateEntryView(); +} + + +void CMainWindow::OnView_HidePasswordsToggled(bool state) +{ +config.ListView_HidePasswords=state; +updateEntryView(); +} + +void CMainWindow::OnGroupViewDrop(QDropEvent* e) +{ +} + +void CMainWindow::OnHelpAboutQt() +{ +QMessageBox::aboutQt(this); +} + +void CMainWindow::OnImportKWalletXML() +{ +bool merge=false; +if(FileOpen){ +int ret=QMessageBox::question(this,tr("Frage"), + trUtf8("Es ist noch eine andere Datenbank geöffnet. Soll sie mit der zu importierenden Datenbank zusammengeführt oder geschlossen werden werden?"), + trUtf8("Zusammenführen"),trUtf8("Schließen"),tr("Abbrechen"),1,2); +switch(ret){ + case 0: merge=true; + break; + case 1: CloseDataBase(); + break; + case 2: return; + } +} +QString filename=QFileDialog::getOpenFileName(QDir::homeDirPath(),"*.xml",this,trUtf8("Datenbank importieren")); +if(filename=="")return; +Import_KWalletXml importer; +QString err; +if(merge){ + PwDatabase* ImportDb=new PwDatabase(); + if(!importer.importFile(filename,ImportDb,err)){ + delete ImportDb; + QMessageBox::critical(this,trUtf8("Fehler"),trUtf8("Die Datei konnte nicht importiert werden.\n%1").arg(err),trUtf8("OK"),0,0,2,1); + return;} + db->merge(ImportDb); + delete ImportDb; +} +else{ + db=new PwDatabase(); + if(!importer.importFile(filename,db,err)){ + delete db; + QMessageBox::critical(this,trUtf8("Fehler"),trUtf8("Die Datei konnte nicht importiert werden.\n%1").arg(err),trUtf8("OK"),0,0,2,1); + return;} + CChangeKeyDlg dlg(this,db); + if(dlg.exec()!=1){ + delete db; + return; + } +} +updateGroupView(); +SetFileMenuState(STATE_FileOpen); +FileOpen=true; + +} + + diff --git a/src/mainwindow.h b/src/mainwindow.h new file mode 100755 index 0000000..2e47e89 --- /dev/null +++ b/src/mainwindow.h @@ -0,0 +1,167 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * tarek.saidi@arcor.de * + * * + * 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. * + ***************************************************************************/ + + +#ifndef MAINWINDOW_H +#define MAINWINDOW_H +#include +#include +#include +#include +#include +#include +#include +#include "ui_MainWindow.h" +#include "ListViews.h" +#include "PwmConfig.h" + +typedef vector::iterator GroupItemItr; +typedef vector::iterator EntryItemItr; + +class CMainWindow : public MainFrame{ +Q_OBJECT + +public: + /*$PUBLIC_FUNCTIONS$*/ + CMainWindow(QApplication* app, QWidget* parent = 0,const char* name = 0, WFlags fl = 0 ); + ~CMainWindow(); +protected: + /*$PROTECTED_FUNCTIONS$*/ + +protected slots: + /*$PROTECTED_SLOTS$*/ + virtual void showEvent(QShowEvent *e); + +public slots: + /*$PUBLIC_SLOTS$*/ + virtual void OnClose(); + virtual void OnMainWinResize(); + virtual void OnFileOpen(); + virtual void OnGroupChanged(QListViewItem*); + virtual void OnEntryChanged(QListViewItem*); + virtual void OnEntryDoubleClicked(QListViewItem*,const QPoint&,int); + virtual void OnMenu_closeDB(); + virtual void OnFileSaveAs(); + virtual void OnFileSave(); + virtual void OnMenuExit(); + virtual void OnAddGroup(); + virtual void OnUserNameToClipboard(); + virtual void OnPasswordToClipboard(); + virtual void OnDeleteGroup(); + virtual void OnEditGroup(); + virtual void OnAddSubGroup(); + virtual void OnClipboardTimerEvent(); + virtual void OnOpenURL(); + virtual void OnGroupSearch(); + virtual void OnGlobalSearch(); + virtual void OnDeleteEntry(); + virtual void OnCopyEntry(); + virtual void OnEditEntry(); + virtual void OnAddEntry(); + virtual void OnSaveAttachment(); + virtual void OnEntryRightClicked(QListViewItem* item, const QPoint& pos,int column); + virtual void OnEntryCtxMenuClicked(int id); + virtual void OnGroupRightClicked(QListViewItem* item, const QPoint& pos, int column); + virtual void OnGroupCtxMenuClicked(int id); + virtual void OnChangeDbKey(); + virtual void OnDbSettings(); + virtual void OnFileNew(); + virtual void OnViewToolbarToggled(bool toggled); + virtual void OnViewEntryDetailsToggled(bool toggled); + virtual void OnHelpAbout(); + virtual void OnSettings(); + virtual void OnView_ColumnUrlToggled(bool value); + virtual void OnView_ColumnTitleToggled(bool value); + virtual void OnView_ColumnCreationToggled(bool value); + virtual void OnView_ColumnLastAccessToggled(bool value); + virtual void OnView_ColumnLastModToggled(bool value); + virtual void OnView_ColumnCommentToggled(bool value); + virtual void OnView_ColumnPasswordToggled(bool value); + virtual void OnView_ColumnAttachmentToggled(bool value); + virtual void OnView_ColumnExpireToggled(bool value); + virtual void OnView_ColumnUsernameToggled(bool value); + virtual void OnExtrasLanguage(); + virtual void OnSearchGroupCtxMenuClicked(int); + virtual void OnQickSearch(); + virtual void OnGroupItemExpanded(QListViewItem* item); + virtual void OnGroupItemCollapsed(QListViewItem* item); + virtual void DEBUG_OnPrintDbStucture(); + virtual void OnImportPwManagerFile(); + virtual void OnView_HideUsernamesToggled(bool state); + virtual void OnView_HidePasswordsToggled(bool state); + virtual void OnGroupViewDrop(QDropEvent* e); + virtual void OnHelpAboutQt(); + virtual void OnImportKWalletXML(); + + +public: + PwDatabase* db; + vector GroupItems; + vector EntryItems; + vector SearchResults; + QString img_res_dir; + QPixmap* EntryIcons; + QPixmap* Icon_Key32x32; + QPixmap* Icon_Settings32x32; + QPixmap* Icon_Search32x32; + QPixmap* Icon_I18n32x32; + QPixmap* Icon_Ok16x16; + QTimer ClipboardTimer; + QString appdir; + CConfig config; + + enum FileMenuState{STATE_FileOpen, + STATE_NoFileOpen}; + enum EditMenuState{STATE_NoGroupSelected, + STATE_NoEntrySelected, + STATE_SingleGroupSelected, + STATE_SingleEntrySelected}; + void InitMenus(); + void SetFileMenuState(FileMenuState status); + void SetEditMenuState(EditMenuState status); + void LoadImg(QString name,QImage &tmpImg); + void SetupColumns(); + void ResizeColumns(); + void OpenDatabase(QString filename); + void CreateBanner(QLabel *Banner,QPixmap* symbol,QString text); + void CreateBanner(QLabel *Banner,QPixmap* symbol,QString text,QColor color1,QColor color2,QColor textcolor); + void CloseDataBase(); + void OpenURL(QString url); + GroupItem* getLastSameLevelItem(int i); + + void setCurrentGroup(GroupItem* item); + void updateEntryView(); + void updateGroupView(); + GroupItem* CurrentGroup; + EntryItem* CurrentEntry; + QClipboard* Clipboard; + +private: + bool isInSearchResults(CEntry*); + void Search(CGroup* pGroup=NULL); + QApplication* App; + QTranslator* translator; + bool modflag; + void setModFlag(bool); + bool FileOpen; +}; + +#endif + diff --git a/src/pwsafe.cpp b/src/pwsafe.cpp new file mode 100755 index 0000000..cecbea7 --- /dev/null +++ b/src/pwsafe.cpp @@ -0,0 +1,33 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * tarek@linux * + * * + * 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. * + ***************************************************************************/ + +#include "mainwindow.h" +#include "pwsafe.h" + +PwSafe::PwSafe(QApplication* app):QMainWindow( 0, "Keepass",WDestructiveClose) +{ mainWin=new CMainWindow(app,this); + setCentralWidget( mainWin ); +} + +PwSafe::~PwSafe() +{ + delete mainWin; +} + diff --git a/src/pwsafe.h b/src/pwsafe.h new file mode 100755 index 0000000..768b0c1 --- /dev/null +++ b/src/pwsafe.h @@ -0,0 +1,48 @@ +/*************************************************************************** + * Copyright (C) 2005 by Tarek Saidi * + * tarek@linux * + * * + * 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. * + ***************************************************************************/ + + +#ifndef _PWSAFE_H_ +#define _PWSAFE_H_ + +#include +#include + +class CMainWindow; + +class PwSafe : public QMainWindow +{ + Q_OBJECT +public: + /** + * Default Constructor + */ + PwSafe(QApplication*); + + /** + * Default Destructor + */ + virtual ~PwSafe(); + +private: + CMainWindow *mainWin; +}; + +#endif // _PWSAFE_H_ diff --git a/src/src.pro b/src/src.pro new file mode 100755 index 0000000..145a71f --- /dev/null +++ b/src/src.pro @@ -0,0 +1,96 @@ +# Diese Datei wurde mit dem qmake-Manager von KDevelop erstellt. +# ------------------------------------------- +# Unterordner relativ zum Projektordner: ./src +# Das Target ist eine Anwendung: ../bin/keepass + +INSTALLS += Share \ + target +target.path = /usr/local/bin +Share.files += ../share/keepass/* +Share.path = /usr/local/share/keepass +MOC_DIR = ../build/moc +UI_DIR = ../build/ui +OBJECTS_DIR = ../build/ +TARGET = ../bin/keepass +CONFIG += debug \ + warn_off \ + qt \ + thread \ + exceptions \ + stl +TEMPLATE = app +FORMS += forms/ui_EditGroupDlg.ui \ + forms/ui_SearchDlg.ui \ + forms/ui_AboutDlg.ui \ + forms/ui_LanguageDlg.ui \ + forms/ui_SettingsDlg.ui \ + forms/ui_ChangeKeyDlg.ui \ + forms/ui_MainWindow.ui \ + forms/ui_SimplePasswordDlg.ui \ + forms/ui_DatabaseSettingsDlg.ui \ + forms/ui_PasswordDlg.ui \ + forms/ui_EditEntryDlg.ui \ + forms/ui_PasswordGenDlg.ui +TRANSLATIONS += translations/english.ts \ + translations/russian.ts +HEADERS += lib/IniReader.h \ + lib/UrlLabel.h \ + mainwindow.h \ + PwManager.h \ + pwsafe.h \ + crypto/rijndael.h \ + lib/SecString.h \ + crypto/sha256.h \ + crypto/twoclass.h \ + crypto/twofish.h \ + ListViews.h \ + import/Import_PwManager.h \ + crypto/blowfish.h \ + crypto/sha1.h \ + import/Import_KWalletXml.h \ + PwmConfig.h \ + dialogs/AboutDlg.h \ + dialogs/EditGroupDlg.h \ + dialogs/SearchDlg.h \ + dialogs/ChangeKeyDlg.h \ + dialogs/LanguageDlg.h \ + dialogs/SettingsDlg.h \ + dialogs/DatabaseSettingsDlg.h \ + dialogs/PasswordDlg.h \ + dialogs/SimplePasswordDlg.h \ + dialogs/EditEntryDlg.h \ + dialogs/PasswordGenDlg.h \ + lib/random.h \ + Database.h \ + lib/PwmTime.h +SOURCES += lib/IniReader.cpp \ + lib/UrlLabel.cpp \ + main.cpp \ + mainwindow.cpp \ + PwManager.cpp \ + pwsafe.cpp \ + crypto/rijndael.cpp \ + lib/SecString.cpp \ + crypto/sha256.c \ + crypto/twoclass.cpp \ + crypto/twofish.cpp \ + ListViews.cpp \ + import/Import_PwManager.cpp \ + crypto/blowfish.cpp \ + crypto/sha1.cpp \ + import/Import_KWalletXml.cpp \ + PwmConfig.cpp \ + dialogs/AboutDlg.cpp \ + dialogs/EditGroupDlg.cpp \ + dialogs/SearchDlg.cpp \ + dialogs/ChangeKeyDlg.cpp \ + dialogs/LanguageDlg.cpp \ + dialogs/SettingsDlg.cpp \ + dialogs/DatabaseSettingsDlg.cpp \ + dialogs/PasswordDlg.cpp \ + dialogs/SimplePasswordDlg.cpp \ + dialogs/EditEntryDlg.cpp \ + dialogs/PasswordGenDlg.cpp \ + lib/random.cpp \ + Database.cpp \ + lib/PwmTime.cpp diff --git a/src/translations/english.ts b/src/translations/english.ts new file mode 100755 index 0000000..5d25e6b --- /dev/null +++ b/src/translations/english.ts @@ -0,0 +1,1702 @@ + + + AboutDlg + + Über... + About... + + + Homepage: + Homepage: + + + EMail: + email: + + + Schlie&ßen + &Close + + + Alt+ß + Alt+C + + + Keepass/L steht unter der General Public License. + Keepass/L is distributed under the terms of the General Public License. + + + Copyright (c) Tarek Saidi 2005 + Copyright (c) Tarek Saidi 2005 + + + Keepass/L Version %1 + Keepass/L version %1 + + + + CAboutDialog + + Keepass für Linux + Keepass for Linux + + + http://keepass.de.vu + http://keepass.de.vu + + + tarek.saidi@arcor.de + tarek.saidi@arcor.de + + + Lizenz + License + + + Fehler + Error + + + Die Datei '%1' konnte nicht gefunden werden. + '%1' - no such file or directory + + + Die Anwendung wurde möglicherweiße nicht korrekt installiert. + Maybe the program is not installed correctly. + + + OK + OK + + + Die Datei '%1' konnte nicht geöffnet werden. + Could not open file '%1'. + + + Es trat folgender Fehler auf: +%1 + The following error occured: +%1 + + + + CChangeKeyDlg + + Hauptschlüssel ändern + Change Master Key + + + Fehler + Error + + + Bitte geben Sie ein Passwort ein. + Please enter a password. + + + OK + OK + + + Bitte wählen Sie eine Schlüsseldatei. + Please select a key file. + + + Geben Sie bitte ein Passwort ein oder wählen Sie eine Schlüsseldatei. + Please select a key file or enter a password. + + + Vorhandene Datei überschreiben? + Overwrite existing file? + + + Unter dem gewählten Dateinamen existiert bereits eine Datei. +Soll sie überschrieben werden? + Overwrite existing file? + + + Schlüsseldatei konnte nicht geöffnet werden. + Could not open key file. + + + Das Schreiben der Schlüsseldatei ist fehlgeschlagen. + The key file could not be written. + + + Passwort und Passwortwiederholung stimmen nicht überein. +Bitte prüfen Sie Ihre Eingabe. + Password and password repetition are not equal. +Please check your input. + + + Schlüsseldatei öffnen + Open Key File + + + Verzeichnis wählen + Choose Directory + + + + CDbSettingsDlg + + AES(Rijndael): 256 Bit (Standard) + AES(Rijndael): 256 Bit (default) + + + Twofish: 256 Bit + Twofish: 256 Bit + + + Fehler + Error + + + Geben Sie bitte die Anzahl der Verschlüsselungsrunden an. + Please determine the number of encryption rounds. + + + OK + OK + + + ist kein gültiger Zahlenwert + is no valid number. + + + Die Anzahl an Verschlüsselungsrunden muss mindestens 1 betragen. + The number of encryption rounds have to be greater than 0. + + + + CEditEntryDlg + + Eintrag bearbeiten + Edit Entry + + + Fehler + Error + + + Datei konnte nicht geöffnet werden. + Could not open file. + + + Anhang speichern... + Save Attachment... + + + Anhang löschen? + Delete Attachment? + + + Sie sind dabei den Anhang zu löschen. +Sind Sie sicher, dass Sie dies tun wollen? + Are you sure? + + + Ja + Yes + + + Nein + No + + + + CLanguageDlg + + Spracheinstellungen + Language Settings... + + + Warnung + Warning + + + Die Datei '%1' konnte nicht geladen werden. + Could not load file '%1'. + + + OK + OK + + + Hinweis + Information + + + Es ist keine Übersetzung aufsgewählt. + There is no translation selected. + + + + CMainWindow + + Keepass Passwortsafe + Keepass Password Safe + + + Warnung + Warning + + + OK + OK + + + Fehler + Error + + + Die Datei '%1' konnte nicht gefunden werden. + Could not open file '%1': no such file or directory. + + + Datenbank öffnen + Open Database + + + Keepass - %1 + Keepass - %1 + + + Laden fehlgeschlagen. <TODO: Fehlerbeschreibung> + Loading failed. <TODO: Error Desc.> + + + Abbrechen + Cancel + + + Titel + Title + + + Benutzername + Username + + + URL + URL + + + Passwort + Password + + + Kommentare + Comments + + + Gültig bis + Expires + + + Erstellung + Creation + + + letzte Änderung + last Change + + + letzter Zugriff + last Access + + + Anhang + Attachment + + + <B>Gruppe: </B>%1 <B>Titel: </B>%2 <B>Benutzername: </B>%3 <B>URL: </B>%4 <B>Passwort: </B>%5 <B>Erstellt: </B>%6 <B>letzte Änderung: </B>%7 <B>letzter Zugriff: </B>%8 <B>gültig bis: </B>%9 + <B>Group: </B>%1 <B>Title: </B>%2 <B>Username: </B>%3 <B>URL: </B>%4 <B>Password: </B>%5 <B>Creation: </B>%6 <B>Last Change: </B>%7 <B>Last Access: </B>%8 <B>Expires: </B>%9 + + + Gruppen + Groups + + + Datenbank speichern? + Save Database? + + + Soll die aktuelle Datenbank vor dem Schließen gespeichert werden? + Do you want to save the current database before closing. + + + Ja + Yes + + + Nein + No + + + Gruppeneigenschaften + Properties + + + Hinweis + Information + + + Dieser Eintrag hat keinen Dateianhang. + This entry has no file attachment. + + + Anhang speichern... + Save Attachment... + + + Vorhandene Datei überschreiben? + Overwrite existing file? + + + Unter dem gewählten Dateinamen existiert bereits eine Datei. +Soll sie überschrieben werden? + Overwrite existing file? + + + Datei konnte nicht überschrieben werden. + Could not overwrite file. + + + Datei konnte nicht erstellt werden. + Could not create file. + + + Beim schreiben in der Datei ist ein Fehler aufgetreten. + An error occured while writing the file. + + + Die Datei konnte nicht vollständig geschrieben werden. + The file could not be written completely. + + + Suche erfolglos + Search finished + + + Die Suche lieferte keine Ergebnisse. + The search finished without any result. + + + Suchergebnisse + Search Results + + + Passwort in Zwischenablage kopieren + Copy Password to Clipboard + + + Benutzername in Zwischenablage kopieren + Copy Username to Clipboard + + + URL öffnen + Open URL + + + Eintrag hinzufügen... + Add Entry... + + + Eintrag anzeigen/bearbeiten + Show/Edit Entry + + + Eintrag duplizieren + Duplicate Entry + + + Eintrag löschen + Delete Entry + + + Gruppe hinzufügen... + Add Group... + + + Untergruppe hinzufügen... + Add Subgroup + + + Gruppe löschen + Delete Group + + + Eigenschaften + Properties + + + Ausblenden + Hide + + + Einstellungen + Settings + + + Platzhalter + <no translation> + + + < noch nicht implementiert > + < not implemented yet > + + + Beim öffnen der Datenbank ist ein Fehler aufgetreten. + Could not open database. + + + Datenbank importieren + Import Database + + + Warnung: Verzeichnis ~/.keepass konnte nicht erstellt werden. + Warnig: Could not create directory ~/.keepass. + + + Die Übersetzungsdatei '%1' konnte nicht geladen werden. + Die Sprache wurde auf Deutsch zurückgesetzt. + + + + Die Konfigurationsdatei konnte nicht gespeichert werden.Stellen Sie sicher, dass +Sie Schreibrechte im Verzeichnis ~/.keepass besitzen. + Could not save configuration file. + + + Beim öffnen der Datenbank ist ein Fehler aufgetreten: +%1 + An error occured while opening the database: + + + Frage + Question + + + Es ist noch eine andere Datenbank geöffnet. Soll sie mit der zu importierenden Datenbank zusammengeführt oder geschlossen werden werden? + Another database is still open. Do you want to merge it with the imported database or should it be closed. + + + Zusammenführen + Merge + + + Schließen + Close + + + Die Datei konnte nicht importiert werden. +%1 + File could not be imported. +%1 + + + + CPasswordDialog + + Datenbank öffnen + Open Database + + + Datei manuell wählen... + Select file manually... + + + < keiner > + < none > + + + Fehler + Error + + + Bitte geben Sie ein Passwort ein. + Please enter a password. + + + OK + OK + + + Bitte wählen Sie eine Schlüsseldatei. + Please select a key file. + + + Geben Sie bitte ein Passwort ein oder wählen Sie eine Schlüsseldatei. + Please select a key file or enter a password. + + + + CSearchDlg + + Suchen + Search + + + Hinweis + Information + + + Bitte geben Sie einen Suchbegriff ein. + Please enter at least one charakter. + + + + CSettingsDlg + + Einstellungen + Settings + + + + ChangeKeyDialog + + Hauptschlüssel ändern + Change Master Key + + + Geben Sie das Passwort ein und/oder wählen Sie eine Schlüsseldatei. + Enter a password and/or choose a key file. + + + Abbrechen + Cancel + + + O&K + O&K + + + Alt+K + Alt+K + + + Schlüssel + Key + + + Schlüsseldatei oder Datenträger: + Key file or drive: + + + Passwort: + Password: + + + Passwort <b>und</b> Schlüsseldatei verwenden + Use password <b>and</b> key file. + + + W&ählen... + &Browse... + + + Alt+ä + Alt+B + + + ... + ... + + + Passwortwiederholung: + Repeat Password: + + + Abb&rechen + Ca&ncel + + + Alt+R + Alt+R + + + + EditEntryDialog + + Eintrag bearbeiten + Edit Entry + + + 120 Bits + 120 Bit + + + Abbrechen + Cancel + + + Ge&n. + Ge&n. + + + Icon: + Icon: + + + ... + ... + + + O&K + O&K + + + Benutzername: + Username: + + + Passwort Wdhlg.: + Repeat Password: + + + Titel: + Title: + + + URL: + URL: + + + Passwort: + Password: + + + Qualität: + Quality: + + + Kommentar: + Comment: + + + gültig bis: + Expires: + + + Anhang: + Attachment: + + + Gruppe: + Group: + + + 5,30 MB + 5,30 MB + + + Abbre&chen + &Cancel + + + Alt+C + Alt+C + + + Alt+K + + + + + EditGroupDialog + + Gruppeneigenschaften + Group Properties + + + Titel: + Title: + + + Symbol: + Icon: + + + Abbre&chen + &Cancel + + + Alt+C + Alt+C + + + O&K + O&K + + + Alt+K + Alt+K + + + + Form1 + + Form1 + Form1 + + + + GenPwDlg + + Passwort Generator + Password Generator + + + Akzeptieren + Accept + + + Abbrechen + Cancel + + + Generieren + Generate + + + Neues Passwort: + New Password: + + + Qualität: + Quality: + + + Optionen + Options + + + Gro&ßbuchstaben + Upper &Letters + + + Alt+ß + Alt+L + + + &Kleinbuchstaben + L&ower Letters + + + Alt+K + Alt+O + + + &Zahlen + &Numbers + + + Alt+Z + Alt+N + + + Sonderzeichen + Special Charakters + + + Bindestriche + Minus + + + &Unterstriche + &Underline + + + Alt+U + Alt+U + + + h&öhere ANSI-Zeichen + &Higher ANSI Charakters + + + Alt+ö + Alt+H + + + &nur folgende Zeichen benutzen: + Use onl&y the following charakters: + + + Alt+N + Alt+Y + + + Zeichenanzahl: + Length: + + + "/dev/&random" nutzen (empfohlen) + use "/dev/&random" (recommend) + + + Alt+R + Alt+R + + + folgende Zeichengruppen &verwenden: + use the following &charakters: + + + Alt+V + Alt+C + + + &Leerzeichen + &Space + + + Alt+L + Alt+S + + + Akzep&tieren + Accep&t + + + Abbre&chen + &Cancel + + + S&onderzeichen + &Special Charakters + + + "/dev/rando&m" nutzen (empfohlen) + Use '/dev/rando&m' (recommend) + + + Alt+M + Alt+M + + + + LanguageDlg + + Keepass + Keepass + + + Schlie&ßen + &Close + + + Alt+ß + Alt+C + + + * + * + + + Sprache + Language + + + Version + Version + + + Autor + Author + + + Fes&tlegen + &Use + + + Alt+T + Alt+U + + + Legt die aktuell markierte Sprache +als Übersetzung für Keepass fest. + Use the selected language as the +active translation for Keepass. + + + + MainFrame + + Form1 + Form1 + + + Neue Datenbank + New Database + + + Datei + File + + + Bearbeiten + Edit + + + Ansicht + View + + + Spalten + Columns + + + Extras + Extras + + + Hilfe + Help + + + Toolbar + Toolbar + + + neue Datenbank + New Database + + + Datenbank öffnen + Open Database + + + Datenbank speichern + Save Database + + + Eintrag hinzufügen + Add Entry + + + Eintrag bearbeiten + Edit Entry + + + Eintrag löschen + Delete Entry + + + Benutzername in Zwischenablage kopieren + Copy Username to Clipboard + + + Passwort in Zwischenablage kopieren + Copy Password to Clipboard + + + in Datenbank suchen + Search + + + < PLATZHALTER > + < empty > + + + Hilfe anzeigen + Help + + + Schnellsuche + Quick Search + + + Beenden + Exit + + + &Neue Datenbank... + &New Database... + + + &Datenbank öffnen... + Open &Database... + + + Datenbank &schließen + Clo&se Database + + + Datenbank s&peichern + Save Data&base + + + Datenbank speichern unter... + Save Database As... + + + Datenbank-Einstellungen... + Database Settings... + + + Hauptschlüssel ändern... + Change Master Key... + + + &Neue Gruppe erstellen... + &New Group... + + + Neue &Untergruppe ertellen... + New S&ubgroup... + + + Gruppe &bearbeiten... + Edit Grou&p... + + + Gruppe &löschen + De&lete Group + + + &Passwort in Zwischenablage kopieren + Copy Pas&sword to Clipboard + + + Ben&utzername in Zwischenablage kopieren + C&opy Username to Clipboard + + + U&RL öffnen + Open U&RL + + + &Anhang speichern unter... + Save Attachment &As... + + + Eintrag &hinzufügen... + Add Entr&y... + + + Eintrag bearbeiten/&anzeigen... + Vie&w/Edit Entry + + + Eintrag &duplizieren + &Duplicate Entry + + + Eintrag l&öschen + Delet&e Entry + + + In Datenbank &suchen... + Search &in Database... + + + In dieser Gru&ppe suchen... + Search in t&his group... + + + &Toolbar anzeigen + Show &Toolbar + + + Eintragsansicht antzeigen + Show Entry View + + + Einstellungen... + Settings... + + + Über... + About... + + + Titel + Title + + + Benutzername + Username + + + URL + URL + + + Passwort + Password + + + Kommentar + Comment + + + Ablaufdatum + Expires + + + Letzter Zugriff + Last Access + + + Letzte Änderung + Last Change + + + Erstellungsdatum + Creation + + + Anhang + Attachment + + + Unnamed + Unnamed + + + Sprache... + Language... + + + DEBUG + DEBUG + + + Eintragsansicht anzeigen + Show Entry View + + + Datenbankstruktur + Database Structure + + + Importieren aus + Import From + + + PwManager-Datei (*.pwm)... + PwManager File (*.pwm)... + + + Über Keepass... + About Keepass... + + + Dokumentation... + Dockumentation... + + + Passwörter verbergen + Hide Passwords + + + Benutzernamen verbergen + Hide Usernames + + + KWallet XML-Datei (*.xml)... + KWallet XML File (*.xml)... + + + Über QT... + About QT... + + + + PasswordDlg + + Datenbank öffnen + Open Database + + + Geben Sie das Passwort ein oder wählen Sie eine Schlüsseldatei. + Please select a key file or enter a password. + + + Abb&rechen + Ca&ncel + + + O&K + O&K + + + Alt+K + Alt+K + + + Schlüssel + Key + + + Passwort: + Password: + + + Schlüsseldatei oder Datenträger: + Key file or drive: + + + ... + ... + + + W&ählen... + &Browse... + + + Alt+ä + Alt+B + + + Passwort <b>und</b> Schlüsseldatei verwenden + Use password <b>and</b> key file. + + + Abbre&chen + &Cancel + + + + PwDatabase + + Unerwartete Dateigröße (Dateigröße < DB_HEADER_SIZE) + Unexpected Filesize (Filesize < DB_HEADER_SIZE) + + + Falsche Signatur + Wrong Signature + + + Nicht unterstüzte Dateiversion + Unsupported File Format Version + + + Unbekannter Verschlüsselungsalgorithmus + Unknown Encryption Algorithm + + + Hash-Test fehlgeschlage: der Schlüssl ist falsch oder die Datei ist beschädigt. + Hash test failed: Wrong key or damaged file. + + + + QObject + + Fehler + Error + + + Das Datenbankformat Version 0.1 wird nicht unterstützt. + The database format version 0.1 is not supported. + + + OK + OK + + + Abbrechen + Cancel + + + Das Datenbankformat Version 0.2 wird nicht unterstützt. + The database format version 0.2 is not supported. + + + Standartgruppe + default group + + + Warnung: INI-Datei konnte nicht gespeichert werden. + Warning: ini file could not be saved. + + + Warnung: + Warning: + + + ungültiger RGB-Farbwert: + invalid RGB color value: + + + '/dev/random' bzw. '/dev/urandom' konnte nicht zum lesen geöffnet werden. + Could not open '/dev/random' or '/dev/urandom'. + + + Standardgruppe + default + + + Die angegebene Datei existiert nicht. + This file does not exist. + + + Datei konnte nicht geöffnet werden. + Could not open file. + + + Datei ist leer + File is empty + + + Nicht unterstützte Version + Unsupported Version + + + Nicht unterstützter Hash-Algorithmus + Unsupported Hash Algorithm + + + Nicht unterstützter Verschlüsselungs-Algorithmus + Unsupported Encryption Algorithm + + + Komprimierte PwManager-Dateien werden nicht unterstützt + Compressed PwManager files are not supported. + + + Falsches Passwort + Wrong Password + + + Dateiinhalt ungültig (Hash-Test fehlgeschlagen) + Invalid Content (Hash Check failed) + + + Ungültiger XML-Inhalt + Invalid XML content + + + Keine gültige PwManager-Datei + No valid PwManager file + + + Datei nicht gefunden + File not found + + + Datei konnte nicht geöffnet werden + CoCould not open file. + + + Ungültiges XML-Dokument + Invalid XML content + + + Dokument enthält keine Daten + Document is empty + + + /dev/random konnte nicht geöffnet werden - nutze Standardbibliothek (stdlib) + /dev/random could not be opened - using stdlib + + + + Search_Dlg + + Suche... + Search... + + + Suche nach + Search for: + + + &Titel + &Title + + + Alt+T + Alt+T + + + Benut&zername + U&sername + + + Alt+Z + Alt+S + + + &Kommentar + &Comment + + + Alt+K + Alt+C + + + &URL + &URL + + + Alt+U + Alt+U + + + A&nhang + &Attachment + + + Alt+N + Alt+A + + + Pass&wort + Pass&word + + + Alt+W + Alt+W + + + S&chließen + &Close + + + Alt+C + Alt+C + + + Suchbegriff: + search for: + + + Suchen + Search + + + regul&ärer Ausdruck + &Regular Expresion + + + Alt+ä + Alt+R + + + Gro&ß- und Kleinschreibung beachten + Case &sensivtive + + + Alt+ß + Alt+S + + + + SettingsDialog + + Einstellungen + Settings + + + Abbre&chen + &Cancel + + + Alt+C + Alt+C + + + O&K + O&K + + + Alt+K + Alt+K + + + Sicherhei&t + Securi&ty + + + Passw&örter standardmäßig in Klartext anzeigen + Show pass&words by default in plain text. + + + Alt+ö + Alt+W + + + Zwischenablage löschen nach: + Clear clipboard after: + + + Sekunden + Seconds + + + E&rscheinungsbild + Appea&rance + + + Bannerfarbverlauf: + Banner Color: + + + Farbe 1 + Color 1 + + + &ändern... + C&hange... + + + Alt+ä + Alt+H + + + Farbe 2 + Color 2 + + + Textfarbe + Text Color + + + ändern... + Change... + + + S&onstiges + &Other + + + zuletzt geöffnete Datei bei Programmstart &öffnen + Remember last file on pr&ogram start. + + + Browseraufruf: + Browser Command: + + + &Abbrechen + Can&cel + + + Alt+A + Alt+C + + + Erschei&nungsbild + Appea&rance + + + Bannerfarbverlauf + Banner Color + + + Gruppenbaum beim &Öffnen aufklappen + E&xpand group tree on database opening + + + + SimplePasswordDialog + + Passworteingabe + Password + + + Passwort: + Password: + + + O&K + O&K + + + Alt+K + Alt+K + + + Abbre&chen + &Cancel + + + Alt+C + Alt+C + + + ... + ... + + + + _INFO + + $TRANSL_AUTHOR + Tarek Saidi + + + $TRANSL_AUTHOR_CONTACT + tarek.saidi@arcor.de + + + $TRANSL_LANGUAGE + English + + + $TRANSL_VERSION + 0.1.2 + + + + _MSG + + Die Änderung der Sprache wird erst nach einem Neustart von Keepass wirksam. + You need to restart Keepass for the changes take effect. + + + OK + OK + + + Hinweis + Information + + + + dbsettingdlg_base + + Datenbankeinstellungen + Database Settings + + + Verschlüsselung + Encryption + + + Algorithmus: + Algorithm: + + + ? + ? + + + Verschlüsselungsrunden: + Encryption Rounds: + + + O&K + O&K + + + Alt+K + Alt+K + + + Abbrechen + Cancel + + + Abbre&chen + &Cancel + + + Alt+C + Alt+C + + + diff --git a/src/translations/russian.ts b/src/translations/russian.ts new file mode 100755 index 0000000..7c18843 --- /dev/null +++ b/src/translations/russian.ts @@ -0,0 +1,2108 @@ + + + AboutDlg + + Über... + О программе... + + + Homepage: + Дом. Страница : + + + EMail: + Email: + + + Schlie&ßen + &Закрыть + + + Alt+ß + Alt+C + + + Keepass/L steht unter der General Public License. + Keepass is distributed under the terms of the General Public License. + + + Copyright (c) Tarek Saidi 2005 + Copyright (c) Tarek Saidi 2005 + + + Keepass/L Version %1 + Keepass версия %1 + + + Über... + О программе... + + + Schlie&ßen + &Закрыть + + + Alt+ß + ALT+C + + + + CAboutDialog + + Keepass für Linux + Keepass for Linux + + + http://keepass.de.vu + http://keepass.de.vu + + + tarek.saidi@arcor.de + tarek.saidi@arcor.de + + + Lizenz + Лицензия + + + Fehler + Ошибка + + + Die Datei '%1' konnte nicht gefunden werden. + '%1' - файл или каталог не существуют + + + Die Anwendung wurde möglicherweiße nicht korrekt installiert. + Возможно программа установлена неправильно + + + OK + OK + + + Die Datei '%1' konnte nicht geöffnet werden. + Невозможно открыть файл '%1'. + + + Es trat folgender Fehler auf: +%1 + Произошла ошибка: +%1 + + + Keepass für Linux + Keepass for Linux + + + Die Anwendung wurde möglicherweiße nicht korrekt installiert. + Возможно программа установлена неправильно. + + + Die Datei '%1' konnte nicht geöffnet werden. + Невозможно открыть файл '%1'. + + + + CChangeKeyDlg + + Hauptschlüssel ändern + Изменить главный ключ + + + Fehler + Ошибка + + + Bitte geben Sie ein Passwort ein. + Пожалуйста, введите пароль. + + + OK + OK + + + Bitte wählen Sie eine Schlüsseldatei. + Пожалуйста, выберите ключевой файл. + + + Geben Sie bitte ein Passwort ein oder wählen Sie eine Schlüsseldatei. + Пожалуйста, выберите ключевой файл или введите пароль. + + + Vorhandene Datei überschreiben? + Перезаписать существующий файл? + + + Unter dem gewählten Dateinamen existiert bereits eine Datei. +Soll sie überschrieben werden? + Перезаписать существующий файл? + + + Schlüsseldatei konnte nicht geöffnet werden. + Невозможно открыть ключевой файл. + + + Das Schreiben der Schlüsseldatei ist fehlgeschlagen. + Невозможно записать ключевой файл. + + + Passwort und Passwortwiederholung stimmen nicht überein. +Bitte prüfen Sie Ihre Eingabe. + Пароли не совпадают. +Проверьте правильнось ввода паролей. + + + Schlüsseldatei öffnen + Открыть ключевой файл + + + Verzeichnis wählen + Изменить главный ключ + + + Hauptschlüssel ändern + Изменить главный ключ + + + Bitte wählen Sie eine Schlüsseldatei. + Пожалуйста, выберите ключевой файл. + + + Geben Sie bitte ein Passwort ein oder wählen Sie eine Schlüsseldatei. + Пожалуйста, выберите ключевой файл или введите пароль. + + + Vorhandene Datei überschreiben? + Перезаписать существующий файл? + + + Unter dem gewählten Dateinamen existiert bereits eine Datei. +Soll sie überschrieben werden? + Перезаписать существующий файл? + + + Schlüsseldatei konnte nicht geöffnet werden. + Невозможно открыть ключевой файл. + + + Das Schreiben der Schlüsseldatei ist fehlgeschlagen. + Невозможно записать ключевой файл. + + + Passwort und Passwortwiederholung stimmen nicht überein. +Bitte prüfen Sie Ihre Eingabe. + Пароли не совпадают. +Проверьте правильнось ввода паролей. + + + Schlüsseldatei öffnen + Открыть ключевой файл + + + Verzeichnis wählen + Изменить главный ключ + + + + CDbSettingsDlg + + AES(Rijndael): 256 Bit (Standard) + AES(Rijndael): 256 Bit (default) + + + Twofish: 256 Bit + Twofish: 256 Bit + + + Fehler + Ошибка + + + Geben Sie bitte die Anzahl der Verschlüsselungsrunden an. + Введите количество степеней шифрования. + + + OK + OK + + + ist kein gültiger Zahlenwert + некорректный номер + + + Die Anzahl an Verschlüsselungsrunden muss mindestens 1 betragen. + Количество уровней шифрования должно быть больше 0. + + + Geben Sie bitte die Anzahl der Verschlüsselungsrunden an. + Введите количество степеней шифрования. + + + ist kein gültiger Zahlenwert + некорректный номер + + + Die Anzahl an Verschlüsselungsrunden muss mindestens 1 betragen. + Количество уровней шифрования должно быть больше 0. + + + + CEditEntryDlg + + Eintrag bearbeiten + Редактировать + + + Fehler + Ошибка + + + Datei konnte nicht geöffnet werden. + Невозможно открыть файл. + + + Anhang speichern... + Сохранить вложение... + + + Anhang löschen? + Удалить вложение? + + + Sie sind dabei den Anhang zu löschen. +Sind Sie sicher, dass Sie dies tun wollen? + Вы уверены? + + + Ja + Да + + + Nein + Нет + + + Datei konnte nicht geöffnet werden. + Невозможно открыть файл. + + + Anhang löschen? + Удалить вложение? + + + Sie sind dabei den Anhang zu löschen. +Sind Sie sicher, dass Sie dies tun wollen? + Вы уверены? + + + + CLanguageDlg + + Spracheinstellungen + Настройки языка + + + Warnung + Предупреждение + + + Die Datei '%1' konnte nicht geladen werden. + Невозможно загрузить файл '%1'. + + + OK + OK + + + Hinweis + Информация + + + Es ist keine Übersetzung aufsgewählt. + Не выбран перевод. + + + Es ist keine Übersetzung aufsgewählt. + Не выбран перевод. + + + + CMainWindow + + Keepass Passwortsafe + Keepass Password Safe + + + Warnung + Предупреждение + + + Die Übersetzungsdatei '%1' konnte nicht geladen werden. +Die Sprache wurde auf Deutsch zurückgesetzt. + Файл перевода '%1' не может быть загружен +Будет использован язык по умолчанию. + + + OK + OK + + + Fehler + Ошибка + + + Die Datei '%1' konnte nicht gefunden werden. + Невозможно открыть файл '%1'. + + + Datenbank öffnen + Открыть базу паролей + + + Keepass - %1 + Keepass - %1 + + + Abbrechen + Отменить + + + Titel + Заголовок + + + Benutzername + Имя пользователя + + + URL + URL + + + Passwort + Пароль + + + Kommentare + Комментарии + + + Gültig bis + Годен до + + + Erstellung + Создание + + + letzte Änderung + Изменен + + + letzter Zugriff + последний Доступ + + + Anhang + Вложение + + + <B>Gruppe: </B>%1 <B>Titel: </B>%2 <B>Benutzername: </B>%3 <B>URL: </B>%4 <B>Passwort: </B>%5 <B>Erstellt: </B>%6 <B>letzte Änderung: </B>%7 <B>letzter Zugriff: </B>%8 <B>gültig bis: </B>%9 + <B>Категория: </B>%1 <B>Заголовок: </B>%2 <B>Имя пользователя: </B>%3 <B>URL: </B>%4 <B>Пароль: </B>%5 <B>Создан: </B>%6 <B>Изменен: </B>%7 <B>Доступ: </B>%8 <B>Годен до: </B>%9 + + + Gruppen + Категории + + + Datenbank speichern? + Сохранить базу? + + + Soll die aktuelle Datenbank vor dem Schließen gespeichert werden? + Хотите сохранить базу перед закрытием? + + + Ja + Да + + + Nein + Нет + + + Gruppeneigenschaften + Настройки + + + Hinweis + Информация + + + Dieser Eintrag hat keinen Dateianhang. + Запись не имеет вложений. + + + Anhang speichern... + Сохранить вложение... + + + Vorhandene Datei überschreiben? + Перезаписать существующий файл? + + + Unter dem gewählten Dateinamen existiert bereits eine Datei. +Soll sie überschrieben werden? + Перезаписать существующий файл? + + + Datei konnte nicht überschrieben werden. + Невозможно перезаписать файл. + + + Datei konnte nicht erstellt werden. + Невозможно создать файл. + + + Beim schreiben in der Datei ist ein Fehler aufgetreten. + Ошибка во время записи файла. + + + Die Datei konnte nicht vollständig geschrieben werden. + Файл не может быть полностью записан. + + + Suche erfolglos + Поиск закончен + + + Die Suche lieferte keine Ergebnisse. + Ничего не найдено. + + + Suchergebnisse + Результаты поиска + + + Passwort in Zwischenablage kopieren + Скопировать пароль в буфер обмена + + + Benutzername in Zwischenablage kopieren + Скопировать Имя Пользователя в буфер обмена + + + URL öffnen + Открыть URL + + + Eintrag hinzufügen... + Добавить запись... + + + Eintrag anzeigen/bearbeiten + Показать/Редактировать запись + + + Eintrag duplizieren + Повторяющаяся запись + + + Eintrag löschen + Удалить запись + + + Gruppe hinzufügen... + Добавить группу... + + + Untergruppe hinzufügen... + Добавить подгруппу... + + + Gruppe löschen + Удалить группу + + + Eigenschaften + Настройки + + + Ausblenden + Спрятать + + + Einstellungen + Опции + + + Platzhalter + Заменить символ + + + < noch nicht implementiert > + < еще не реализовано > + + + Beim öffnen der Datenbank ist ein Fehler aufgetreten. + Невозможно открыть базу. + + + Laden fehlgeschlagen. <TODO: Fehlerbeschreibung> + Загрузка невозможна. <TODO: Error Desc.> + + + Die Übersetzungsdatei '%1' konnte nicht geladen werden. +Die Sprache wurde auf Deutsch zurückgesetzt. + Файл перевода '%1' не может быть загружен +Будет использован язык по умолчанию. + + + Datenbank öffnen + Открыть базу паролей + + + Beim öffnen der Datenbank ist ein Fehler aufgetreten. + Невозможно открыть базу. + + + Gültig bis + Годен до + + + letzte Änderung + Изменен + + + <B>Gruppe: </B>%1 <B>Titel: </B>%2 <B>Benutzername: </B>%3 <B>URL: </B>%4 <B>Passwort: </B>%5 <B>Erstellt: </B>%6 <B>letzte Änderung: </B>%7 <B>letzter Zugriff: </B>%8 <B>gültig bis: </B>%9 + <B>Категория: </B>%1 <B>Заголовок: </B>%2 <B>Имя пользователя: </B>%3 <B>URL: </B>%4 <B>Пароль: </B>%5 <B>Создан: </B>%6 <B>Изменен: </B>%7 <B>Доступ: </B>%8 <B>Годен до: </B>%9 + + + Soll die aktuelle Datenbank vor dem Schließen gespeichert werden? + Хотите сохранить базу перед закрытием? + + + Vorhandene Datei überschreiben? + Перезаписать существующий файл? + + + Unter dem gewählten Dateinamen existiert bereits eine Datei. +Soll sie überschrieben werden? + Перезаписать существующий файл? + + + Datei konnte nicht überschrieben werden. + Невозможно перезаписать файл. + + + Die Datei konnte nicht vollständig geschrieben werden. + Файл не может быть полностью записан. + + + URL öffnen + Открыть URL + + + Eintrag hinzufügen... + Добавить запись... + + + Eintrag löschen + Удалить запись + + + Untergruppe hinzufügen... + Добавить подгруппу... + + + Gruppe löschen + Удалить группу + + + Gruppe hinzufügen... + Добавить группу... + + + Warnung: Verzeichnis ~/.keepass konnte nicht erstellt werden. + + + + Die Übersetzungsdatei '%1' konnte nicht geladen werden. + Die Sprache wurde auf Deutsch zurückgesetzt. + + + + Die Konfigurationsdatei konnte nicht gespeichert werden.Stellen Sie sicher, dass +Sie Schreibrechte im Verzeichnis ~/.keepass besitzen. + + + + Beim öffnen der Datenbank ist ein Fehler aufgetreten: +%1 + + + + Frage + + + + Es ist noch eine andere Datenbank geöffnet. Soll sie mit der zu importierenden Datenbank zusammengeführt oder geschlossen werden werden? + + + + Zusammenführen + + + + Schließen + + + + Datenbank importieren + + + + Die Datei konnte nicht importiert werden. +%1 + + + + + CPasswordDialog + + Datenbank öffnen + Открыть базу + + + Datei manuell wählen... + Выбрать файл вручную... + + + < keiner > + < нет > + + + Fehler + Ошибка + + + Bitte geben Sie ein Passwort ein. + Пожалуйста, введите пароль. + + + OK + OK + + + Bitte wählen Sie eine Schlüsseldatei. + Пожалуйста, выберите ключевой файл. + + + Geben Sie bitte ein Passwort ein oder wählen Sie eine Schlüsseldatei. + Пожалуйста, выберите ключевой файл или введите пароль. + + + Datenbank öffnen + Открыть базу + + + Datei manuell wählen... + Выбрать файл вручную... + + + Bitte wählen Sie eine Schlüsseldatei. + Пожалуйста, выберите ключевой файл. + + + Geben Sie bitte ein Passwort ein oder wählen Sie eine Schlüsseldatei. + Пожалуйста, выберите ключевой файл или введите пароль. + + + + CSearchDlg + + Suchen + Поиск + + + Hinweis + Информация + + + Bitte geben Sie einen Suchbegriff ein. + Пожалуйста, введите хотя-бы один символ. + + + + CSettingsDlg + + Einstellungen + Настройки + + + + ChangeKeyDialog + + Hauptschlüssel ändern + Изменить главный пароль + + + Geben Sie das Passwort ein und/oder wählen Sie eine Schlüsseldatei. + Введите пароль и/или выберите ключевой файл. + + + O&K + O&K + + + Alt+K + Alt+K + + + Schlüssel + Ключ + + + Schlüsseldatei oder Datenträger: + Ключевой файл или устройство: + + + Passwort: + Пароль: + + + Passwort <b>und</b> Schlüsseldatei verwenden + Использовать пароль <b>и</b> ключевой файл + + + W&ählen... + &Обзор... + + + Alt+ä + Alt+B + + + ... + ... + + + Passwortwiederholung: + Повторите пароль: + + + Abb&rechen + О&тмена + + + Alt+R + Alt+R + + + Abbrechen + Отмена + + + Hauptschlüssel ändern + Изменить главный пароль + + + Geben Sie das Passwort ein und/oder wählen Sie eine Schlüsseldatei. + Введите пароль и/или выберите ключевой файл. + + + Schlüssel + Ключ + + + Schlüsseldatei oder Datenträger: + Ключевой файл или устройство: + + + Passwort <b>und</b> Schlüsseldatei verwenden + Использовать пароль <b>и</b> ключевой файл + + + W&ählen... + &Обзор... + + + Alt+ä + + + + + EditEntryDialog + + Eintrag bearbeiten + Редактировать запись + + + 120 Bits + 120 Bit + + + Ge&n. + Ge&n. + + + Icon: + Icon: + + + ... + ... + + + O&K + O&K + + + Benutzername: + Имя пользователя: + + + Passwort Wdhlg.: + Повторите пароль: + + + Titel: + Заголовок: + + + URL: + URL: + + + Passwort: + Пароль: + + + Qualität: + Качество: + + + Kommentar: + Комментарий: + + + gültig bis: + Годен до: + + + Anhang: + Вложение: + + + Gruppe: + Категория: + + + 5,30 MB + 5,30 MB + + + Abbre&chen + &Отмена + + + Alt+C + Alt+C + + + Alt+K + Alt+K + + + Abbrechen + Отмена + + + Qualität: + Качество: + + + gültig bis: + годен до: + + + + EditGroupDialog + + Gruppeneigenschaften + Свойства категории + + + Titel: + Заголовок: + + + Symbol: + Icon: + + + Abbre&chen + О&тмена + + + Alt+C + Alt+C + + + O&K + O&K + + + Alt+K + Alt+K + + + + Form1 + + Form1 + Form1 + + + + GenPwDlg + + Passwort Generator + Генератор паролей + + + Generieren + Создать + + + Neues Passwort: + Новый пароль: + + + Qualität: + Качество: + + + Optionen + Параметры + + + Gro&ßbuchstaben + &Заглавные буквы + + + Alt+ß + Alt+L + + + &Kleinbuchstaben + &Строчные буквы + + + Alt+K + Alt+O + + + &Zahlen + &Числа + + + Alt+Z + Alt+N + + + Bindestriche + Минус + + + &Unterstriche + &Подчеркивание + + + Alt+U + Alt+U + + + h&öhere ANSI-Zeichen + &Верхние ANSI Символы + + + Alt+ö + Alt+H + + + &nur folgende Zeichen benutzen: + &Использовать только следующие символы: + + + Alt+N + Alt+Y + + + Zeichenanzahl: + Длина: + + + folgende Zeichengruppen &verwenden: + использовать следующие &символы: + + + Alt+V + Alt+C + + + &Leerzeichen + &Пробел + + + Alt+L + Alt+S + + + Akzep&tieren + &Принять + + + Abbre&chen + &Отменить + + + S&onderzeichen + &Спецсимволы + + + "/dev/rando&m" nutzen (empfohlen) + Использовать '/dev/rando&m' (рекомендуется) + + + Alt+M + Alt+M + + + Akzeptieren + Прнять + + + Abbrechen + Отмена + + + Sonderzeichen + Спецсимволы + + + "/dev/&random" nutzen (empfohlen) + использовать "/dev/&random" (рекомендуется) + + + Alt+R + Alt+R + + + Qualität: + Качество: + + + Gro&ßbuchstaben + &Заглавные буквы + + + Alt+ß + Alt+L + + + h&öhere ANSI-Zeichen + &Верхние ANSI Символы + + + Alt+ö + Alt+H + + + + LanguageDlg + + Keepass + Keepass + + + Schlie&ßen + &Закрыть + + + Alt+ß + Alt+C + + + * + * + + + Sprache + Язык + + + Version + Версия + + + Autor + Автор + + + Fes&tlegen + &Включить + + + Alt+T + Alt+U + + + Legt die aktuell markierte Sprache +als Übersetzung für Keepass fest. + Использовать выбранный язык, +как перевод по умолчанию для Keepass. + + + Schlie&ßen + &Закрыть + + + Alt+ß + Alt+C + + + Legt die aktuell markierte Sprache +als Übersetzung für Keepass fest. + Использовать выбранный язык, +как перевод по умолчанию для Keepass. + + + + MainFrame + + Form1 + Form1 + + + Neue Datenbank + Новая база + + + Datei + Файл + + + Bearbeiten + Редактирование + + + Ansicht + Вид + + + Spalten + Колонки + + + Extras + Дополнительно + + + Hilfe + Помощь + + + Toolbar + Панель инструментов + + + neue Datenbank + Новая база + + + Datenbank öffnen + Открыть базу + + + Datenbank speichern + Сохранить базу + + + Eintrag hinzufügen + Добавит запись + + + Eintrag bearbeiten + Редактировать запись + + + Eintrag löschen + Удалить запись + + + Benutzername in Zwischenablage kopieren + Копировать Имя в буфер обмена + + + Passwort in Zwischenablage kopieren + Копировать Пароль в буфер обмена + + + in Datenbank suchen + Поиск + + + < PLATZHALTER > + < пусто > + + + Hilfe anzeigen + Помощь + + + Schnellsuche + Быстрый поиск + + + Beenden + Выход + + + &Neue Datenbank... + &Новая база... + + + &Datenbank öffnen... + Обкрыть &базу... + + + Datenbank &schließen + &Закрыть базу + + + Datenbank s&peichern + &Сохранить базу + + + Datenbank speichern unter... + Сохранить базу как... + + + Datenbank-Einstellungen... + Настройки базы... + + + Hauptschlüssel ändern... + Изменить главный ключ... + + + &Neue Gruppe erstellen... + &Новая категория... + + + Neue &Untergruppe ertellen... + &Новая подкатегория... + + + Gruppe &bearbeiten... + &Редактировать категорию... + + + Gruppe &löschen + &Удалить категорию + + + &Passwort in Zwischenablage kopieren + Копировать &Пароль в буфер обмена + + + Ben&utzername in Zwischenablage kopieren + Копировать &имя в буфер обмена + + + U&RL öffnen + Открыть U&RL + + + &Anhang speichern unter... + Сохранить вложение &как... + + + Eintrag &hinzufügen... + Добавить &запись... + + + Eintrag bearbeiten/&anzeigen... + Показать/&Редактировать запись... + + + Eintrag &duplizieren + &Dup Копировать запись + + + Eintrag l&öschen + &Удалить запись + + + In Datenbank &suchen... + &Поиск в базе... + + + In dieser Gru&ppe suchen... + Поиск в &категории... + + + &Toolbar anzeigen + Показать панель &инструментов + + + Einstellungen... + Настройки... + + + Über... + О программе... + + + Titel + Заголовок + + + Benutzername + Имя пользователя + + + URL + URL + + + Passwort + Пароль + + + Kommentar + Комментарий + + + Ablaufdatum + Годен до + + + Letzter Zugriff + последний доступ + + + Letzte Änderung + Последее изменение + + + Erstellungsdatum + Создание + + + Anhang + Вложение + + + Unnamed + Неназвано + + + Sprache... + Язык... + + + DEBUG + DEBUG + + + Eintragsansicht anzeigen + Расширенный вид записи + + + Datenbankstruktur + Структура базы + + + Eintragsansicht antzeigen + Расширенный вид записи + + + Datenbank öffnen + Открыть базу + + + Eintrag hinzufügen + Добавить запись + + + Eintrag löschen + Удалить запись + + + &Datenbank öffnen... + Обкрыть &базу... + + + Datenbank &schließen + &Закрыть базу + + + Hauptschlüssel ändern... + Изменить главный ключ... + + + Gruppe &löschen + &Удалить категорию + + + U&RL öffnen + Открыть U&RL + + + Eintrag &hinzufügen... + Добавить &запись... + + + Eintrag l&öschen + &Удалить запись + + + Über... + О программе... + + + Letzte Änderung + Последее изменение + + + Importieren aus + + + + Über Keepass... + + + + PwManager-Datei (*.pwm)... + + + + Dokumentation... + + + + Passwörter verbergen + + + + Benutzernamen verbergen + + + + KWallet XML-Datei (*.xml)... + + + + Über QT... + + + + + PasswordDlg + + Datenbank öffnen + Открыть базу + + + Geben Sie das Passwort ein oder wählen Sie eine Schlüsseldatei. + Пожалуйста, выберите ключевой файл или введите пароль. + + + O&K + O&K + + + Alt+K + Alt+K + + + Schlüssel + Ключ + + + Passwort: + Пароль: + + + Schlüsseldatei oder Datenträger: + Ключевой файл или устройство: + + + ... + ... + + + W&ählen... + &Обзор... + + + Alt+ä + Alt+B + + + Passwort <b>und</b> Schlüsseldatei verwenden + Использовать пароль <b>и</b> ключевой файл + + + Abbre&chen + &Отмена + + + Abb&rechen + &Отмена + + + Datenbank öffnen + Открыть базу + + + Geben Sie das Passwort ein oder wählen Sie eine Schlüsseldatei. + Пожалуйста, выберите ключевой файл или введите пароль. + + + Schlüssel + Ключ + + + Schlüsseldatei oder Datenträger: + Ключевой файл или устройство: + + + W&ählen... + &Обзор... + + + Alt+ä + Alt+B + + + Passwort <b>und</b> Schlüsseldatei verwenden + Использовать пароль <b>и</b> ключевой файл + + + + PwDatabase + + Unerwartete Dateigröße (Dateigröße < DB_HEADER_SIZE) + + + + Falsche Signatur + + + + Nicht unterstüzte Dateiversion + + + + Unbekannter Verschlüsselungsalgorithmus + + + + Hash-Test fehlgeschlage: der Schlüssl ist falsch oder die Datei ist beschädigt. + + + + + QObject + + Fehler + Ошбка + + + Das Datenbankformat Version 0.1 wird nicht unterstützt. + База версии 0.1 не поддерживается. + + + OK + OK + + + Abbrechen + Отмена + + + Das Datenbankformat Version 0.2 wird nicht unterstützt. + База версии 0.2 не поддерживается. + + + Warnung: INI-Datei konnte nicht gespeichert werden. + Предупреждение: ini файл не может быть сохранен. + + + Warnung: + Предупреждение: + + + ungültiger RGB-Farbwert: + некорректное RGB значение цвета: + + + '/dev/random' bzw. '/dev/urandom' konnte nicht zum lesen geöffnet werden. + Невозможно открыть '/dev/random' или '/dev/urandom'. + + + Standardgruppe + по умолчанию + + + Standartgruppe + по умолчанию + + + Das Datenbankformat Version 0.1 wird nicht unterstützt. + База версии 0.1 не поддерживается. + + + Das Datenbankformat Version 0.2 wird nicht unterstützt. + База версии 0.2 не поддерживается. + + + ungültiger RGB-Farbwert: + некорректное RGB значение цвета: + + + '/dev/random' bzw. '/dev/urandom' konnte nicht zum lesen geöffnet werden. + Невозможно открыть '/dev/random' или '/dev/urandom'. + + + Die angegebene Datei existiert nicht. + + + + Datei konnte nicht geöffnet werden. + Невозможно открыть файл. + + + Datei ist leer + + + + Keine gültige PwManager-Datei + + + + Nicht unterstützte Version + + + + Nicht unterstützter Hash-Algorithmus + + + + Nicht unterstützter Verschlüsselungs-Algorithmus + + + + Komprimierte PwManager-Dateien werden nicht unterstützt + + + + Falsches Passwort + + + + Dateiinhalt ungültig (Hash-Test fehlgeschlagen) + + + + Ungültiger XML-Inhalt + + + + Datei nicht gefunden + + + + Datei konnte nicht geöffnet werden + + + + Ungültiges XML-Dokument + + + + Dokument enthält keine Daten + + + + /dev/random konnte nicht geöffnet werden - nutze Standardbibliothek (stdlib) + + + + + Search_Dlg + + Suche... + Поиск... + + + Suche nach + Поиск для + + + &Titel + &Заголовок + + + Alt+T + Alt+T + + + Benut&zername + &Имя пользователя + + + Alt+Z + Alt+S + + + &Kommentar + &Комментарий + + + Alt+K + Alt+C + + + &URL + &URL + + + Alt+U + Alt+U + + + A&nhang + &Вложение + + + Alt+N + Alt+A + + + Pass&wort + &Пароль + + + Alt+W + Alt+W + + + S&chließen + &Закрыть + + + Alt+C + Alt+C + + + Suchbegriff: + поиск для: + + + Suchen + Поиск + + + regul&ärer Ausdruck + &Регулярное выражение + + + Alt+ä + Alt+R + + + Gro&ß- und Kleinschreibung beachten + &Чувствительно к регистру + + + Alt+ß + Alt+S + + + S&chließen + &Закрыть + + + regul&ärer Ausdruck + &Регулярное выражение + + + Alt+ä + Alt+R + + + Gro&ß- und Kleinschreibung beachten + &Чувствительность к регистру + + + Alt+ß + Alt+S + + + + SettingsDialog + + Einstellungen + Настройки + + + Abbre&chen + &Отмена + + + Alt+C + Alt+C + + + O&K + O&K + + + Alt+K + Alt+K + + + Sicherhei&t + &Безопасность + + + Passw&örter standardmäßig in Klartext anzeigen + П&оказывать пароли по умолчанию + + + Alt+ö + Alt+W + + + Zwischenablage löschen nach: + Очищать буфер обмена после: + + + Sekunden + Секунд + + + E&rscheinungsbild + Вн&ешний вид + + + Bannerfarbverlauf: + Цвет баннера: + + + Farbe 1 + Цвет 1 + + + &ändern... + &Изменить... + + + Alt+ä + Alt+H + + + Farbe 2 + Цвет 2 + + + Textfarbe + Текст + + + ändern... + Изменить... + + + S&onstiges + &Другие + + + zuletzt geöffnete Datei bei Programmstart &öffnen + Запомнить последний файл при &запуске + + + Browseraufruf: + Браузер: + + + &Abbrechen + &Отмена + + + Alt+A + Alt+C + + + Erschei&nungsbild + &Внешний вид + + + Passw&örter standardmäßig in Klartext anzeigen + П&оказывать пароли по умолчанию + + + Alt+ö + Alt+W + + + Zwischenablage löschen nach: + Очищать буфер обмена после: + + + &ändern... + &Изменить... + + + Alt+ä + Alt+H + + + ändern... + Изменить... + + + zuletzt geöffnete Datei bei Programmstart &öffnen + Запомнить последний файл при &запуске + + + Bannerfarbverlauf + + + + Gruppenbaum beim &Öffnen aufklappen + + + + + SimplePasswordDialog + + Passworteingabe + + + + Passwort: + Пароль: + + + O&K + O&K + + + Alt+K + + + + Abbre&chen + + + + Alt+C + Alt+C + + + ... + ... + + + + _INFO + + $TRANSL_AUTHOR + Aleksey Kirpichnikov + + + $TRANSL_AUTHOR_CONTACT + alexcoder@gmail.com + + + $TRANSL_LANGUAGE + Russian + + + $TRANSL_VERSION + 0.1.1 + + + + _MSG + + Die Änderung der Sprache wird erst nach einem Neustart von Keepass wirksam. + Необходимо перезапустить KeePass чтобы изменения вступили в силу. + + + OK + OK + + + Hinweis + Информация + + + + dbsettingdlg_base + + Datenbankeinstellungen + Настройки базы + + + Verschlüsselung + Шифрование + + + Algorithmus: + Алгоритм: + + + ? + ? + + + Verschlüsselungsrunden: + Уровни шифрования: + + + O&K + O&K + + + Alt+K + Alt+K + + + Abbre&chen + &Отмена + + + Alt+C + Alt+C + + + Abbrechen + Отмена + + + Verschlüsselung + Шифрование + + + Verschlüsselungsrunden: + Уровни шифрования: + + +