From cvs at cvs.gnupg.org Sun Jun 1 21:44:25 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Sun, 01 Jun 2008 21:44:25 +0200 Subject: [svn] GnuPG - r4775 - in trunk: agent doc g10 po Message-ID: Author: wk Date: 2008-06-01 21:44:05 +0200 (Sun, 01 Jun 2008) New Revision: 4775 Modified: trunk/agent/ChangeLog trunk/doc/a-decade-of-gnupg.txt trunk/doc/help.de.txt trunk/doc/help.txt trunk/g10/ChangeLog trunk/g10/keygen.c trunk/po/be.po trunk/po/ca.po trunk/po/cs.po trunk/po/da.po trunk/po/de.po trunk/po/el.po trunk/po/eo.po trunk/po/es.po trunk/po/et.po trunk/po/fi.po trunk/po/fr.po trunk/po/gl.po trunk/po/hu.po trunk/po/id.po trunk/po/it.po trunk/po/ja.po trunk/po/nb.po trunk/po/pl.po trunk/po/pt.po trunk/po/pt_BR.po trunk/po/ro.po trunk/po/ru.po trunk/po/sk.po trunk/po/sv.po trunk/po/tr.po trunk/po/zh_CN.po trunk/po/zh_TW.po Log: Changes the header presented before requesting the user ID. Modified: trunk/agent/ChangeLog =================================================================== --- trunk/agent/ChangeLog 2008-05-28 10:08:37 UTC (rev 4774) +++ trunk/agent/ChangeLog 2008-06-01 19:44:05 UTC (rev 4775) @@ -1,7 +1,7 @@ 2008-05-27 Werner Koch - * trustlist.c (insert_colons): Fix stupidly wrong allocation - computation. + * trustlist.c (insert_colons): Fix stupidly wrong allocation size + computation. 2008-05-26 Werner Koch Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2008-05-28 10:08:37 UTC (rev 4774) +++ trunk/g10/ChangeLog 2008-06-01 19:44:05 UTC (rev 4775) @@ -1,3 +1,9 @@ +2008-05-31 Werner Koch + + * keygen.c (ask_user_id): Change the string printed as header of + the user ID generation. Use code to not break existing + translations. Suggested by Eric Tetz. + 2008-05-08 Werner Koch * sig-check.c (do_check_messages): Print a revocation diagnostic Modified: trunk/doc/a-decade-of-gnupg.txt =================================================================== --- trunk/doc/a-decade-of-gnupg.txt 2008-05-28 10:08:37 UTC (rev 4774) +++ trunk/doc/a-decade-of-gnupg.txt 2008-06-01 19:44:05 UTC (rev 4775) @@ -196,3 +196,23 @@ [8] http://partners.nytimes.com/library/tech/99/11/cyber/articles/19encrypt.html [9] http://www.heise.de/tp/r4/artikel/5/5124/1.html +=== Remarks === + +In a reply to this mail Alan Olsen remakrked on the ML: + + MIT was forced to use the RSAREF library which had a non free + license. At first they used the RSAREF2 library, but then they were + told to use the RSAREF1 library. (I diffed the two libraries and + determined that the only difference was that RSAREF2 had fixed a + number of buffer overflows and other security flaws. There were no + added features.) + + If I remember correctly, 2.5 had RSAREF2 and 2.6 had RSAREF1. One + of the main reasons for the creation of the "International version" + was the use of RSAREF. (Besides the security issues, it was pretty + damn slow. In the days of the i386 people cared about speed.) + +Jaime Suarez translated the text in his blog, see + + http://wordpress.mundocripto.com + Modified: trunk/doc/help.de.txt =================================================================== --- trunk/doc/help.de.txt 2008-05-28 10:08:37 UTC (rev 4774) +++ trunk/doc/help.de.txt 2008-06-01 19:44:05 UTC (rev 4775) @@ -102,16 +102,18 @@ . .gpg.keygen.name -Geben Sie den Namen des Schl?sselinhabers ein +Geben Sie den Namen des Schl?sselinhabers ein. +Beispiel: Heinrich Heine. . .gpg.keygen.email Geben Sie eine Email-Adresse ein. Dies ist zwar nicht unbedingt notwendig, aber sehr empfehlenswert. +Beispiel: heinrichh at duesseldorf.de . .gpg.keygen.comment -Geben Sie - bei Bedarf - einen Kommentar ein +Geben Sie - bei Bedarf - einen Kommentar ein. . .gpg.keygen.userid.cmd Modified: trunk/doc/help.txt =================================================================== --- trunk/doc/help.txt 2008-05-28 10:08:37 UTC (rev 4774) +++ trunk/doc/help.txt 2008-06-01 19:44:05 UTC (rev 4775) @@ -161,16 +161,19 @@ .gpg.keygen.name -Enter the name of the key holder. +Enter the name of the key holder. +Example: Heinrich Heine . .gpg.keygen.email Please enter an optional but highly suggested email address. +Example: heinrichh at duesseldorf.de . .gpg.keygen.comment Please enter an optional comment. +In general there is no need for a comment. . Modified: trunk/g10/keygen.c =================================================================== --- trunk/g10/keygen.c 2008-05-28 10:08:37 UTC (rev 4774) +++ trunk/g10/keygen.c 2008-06-01 19:44:05 UTC (rev 4775) @@ -1941,12 +1941,31 @@ char *answer; char *aname, *acomment, *amail, *uid; - if( !mode ) - tty_printf( _("\n" + if ( !mode ) + { + const char *s1 = + N_("\n" + "GnuPG needs to construct a user ID to identify your key.\n" + "\n"); + const char *s2 = _(s1); + + if (!strcmp (s1, s2)) + { + /* There is no translation for the string thus we to use + the old info text. gettext has no way to tell whether + a translation is actually available, thus we need to + to compare again. */ + const char *s3 = N_("\n" "You need a user ID to identify your key; " "the software constructs the user ID\n" "from the Real Name, Comment and Email Address in this form:\n" -" \"Heinrich Heine (Der Dichter) \"\n\n") ); +" \"Heinrich Heine (Der Dichter) \"\n\n"); + const char *s4 = _(s3); + if (strcmp (s3, s4)) + s2 = s3; /* A translation exists - use it. */ + } + tty_printf ("%s", s2) ; + } uid = aname = acomment = amail = NULL; for(;;) { char *p; Modified: trunk/po/be.po [not shown] Modified: trunk/po/ca.po [not shown] Modified: trunk/po/cs.po [not shown] Modified: trunk/po/da.po [not shown] Modified: trunk/po/de.po [not shown] Modified: trunk/po/el.po [not shown] Modified: trunk/po/eo.po [not shown] Modified: trunk/po/es.po [not shown] Modified: trunk/po/et.po [not shown] Modified: trunk/po/fi.po [not shown] Modified: trunk/po/fr.po [not shown] Modified: trunk/po/gl.po [not shown] Modified: trunk/po/hu.po [not shown] Modified: trunk/po/id.po [not shown] Modified: trunk/po/it.po [not shown] Modified: trunk/po/ja.po [not shown] Modified: trunk/po/nb.po [not shown] Modified: trunk/po/pl.po [not shown] Modified: trunk/po/pt.po [not shown] Modified: trunk/po/pt_BR.po [not shown] Modified: trunk/po/ro.po [not shown] Modified: trunk/po/ru.po [not shown] Modified: trunk/po/sk.po [not shown] Modified: trunk/po/sv.po [not shown] Modified: trunk/po/tr.po [not shown] Modified: trunk/po/zh_CN.po [not shown] Modified: trunk/po/zh_TW.po [not shown] From cvs at cvs.gnupg.org Wed Jun 4 16:14:42 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 04 Jun 2008 16:14:42 +0200 Subject: [svn] gpgme - r1314 - in trunk: . doc gpgme Message-ID: Author: wk Date: 2008-06-04 16:14:38 +0200 (Wed, 04 Jun 2008) New Revision: 1314 Added: trunk/doc/gpl.texi Modified: trunk/NEWS trunk/doc/ChangeLog trunk/doc/Makefile.am trunk/doc/gpgme.texi trunk/doc/lesser.texi trunk/gpgme/gpgme.h Log: Include the GnuPG UI Server specification. Change the license of the manual to GPLv3+. [The diff below has been truncated] Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2008-05-09 08:26:28 UTC (rev 1313) +++ trunk/doc/ChangeLog 2008-06-04 14:14:38 UTC (rev 1314) @@ -1,3 +1,9 @@ +2008-06-04 Werner Koch + + * gpgme.texi: Use @copying command. Change license to + GPLv3. Include protocol specis from GpgOL and GPGEx. Minor + cleanups. + 2008-03-11 Marcus Brinkmann * gpgme.texi (File Based Data Buffers): Document the need for Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2008-05-09 08:26:28 UTC (rev 1313) +++ trunk/NEWS 2008-06-04 14:14:38 UTC (rev 1314) @@ -12,6 +12,9 @@ applications (it only affects the S/MIME backend on certain operations). + * The reference manual now includes the specification of "The GnuPG + UI Server protocol". + * Interface changes relative to the 1.1.6 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ gpgme_op_encrypt CHANGED: Output encoding can affect result. Modified: trunk/doc/Makefile.am =================================================================== --- trunk/doc/Makefile.am 2008-05-09 08:26:28 UTC (rev 1313) +++ trunk/doc/Makefile.am 2008-06-04 14:14:38 UTC (rev 1314) @@ -22,7 +22,7 @@ DISTCLEANFILES = gpgme.tmp info_TEXINFOS = gpgme.texi -gpgme_TEXINFOS = lesser.texi +gpgme_TEXINFOS = uiserver.texi lesser.texi gpl.texi online: gpgme.html gpgme.pdf set -e; \ Modified: trunk/doc/gpgme.texi =================================================================== --- trunk/doc/gpgme.texi 2008-05-09 08:26:28 UTC (rev 1313) +++ trunk/doc/gpgme.texi 2008-06-04 14:14:38 UTC (rev 1314) @@ -1,4 +1,5 @@ -()\input texinfo @c -*- Texinfo -*- +\input texinfo @c -*- mode: texinfo; coding: latin-1; -*- + at documentencoding ISO-8859-1 @setfilename gpgme.info @settitle The `GnuPG Made Easy' Reference Manual @@ -7,12 +8,41 @@ * @acronym{GPGME}: (gpgme). Adding support for cryptography to your program. @end direntry - at include version.texi - @c Unify some of the indices. @syncodeindex tp fn @syncodeindex pg fn + at copying +Copyright @copyright{} 2002, 2003, 2004, 2005, 2006, 2007, 2008 g10 Code GmbH. + + at quotation +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. The text of the license can be found in the +section entitled ``Copying''. + at end quotation + +This document 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. + at end copying + + at include version.texi + + at c Macros used by the description of the UI server protocol + at macro clnt + @sc{c:} @c + at end macro + at macro srvr + @sc{s:} @c + at end macro + + + at c + at c T I T L E P A G E + at c @ifinfo This file documents the @acronym{GPGME} library. @@ -21,27 +51,14 @@ @value{VERSION}. @c NOTE: Don't forget to update the year for the TeX version, too. -Copyright @copyright{} 2002, 2003, 2004, 2005, 2006, 2007 g10 Code GmbH. + at insertcopying -The GPGME reference manual 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. - -The GPGME reference manual 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 - @end ifinfo - at iftex - at shorttitlepage The `GnuPG Made Easy' Reference Manual - at end iftex + at c We do not want that bastard short titlepage. + at c @iftex + at c @shorttitlepage The `GnuPG Made Easy' Reference Manual + at c @end iftex @titlepage @center @titlefont{The `GnuPG Made Easy'} @sp 1 @@ -54,25 +71,15 @@ @center for version @value{VERSION} @page @vskip 0pt plus 1filll -Copyright @copyright{} 2002, 2003, 2004, 2005, 2006, 2007 g10 Code GmbH. +Published by g10 Code GmbH@* H?ttenstr. 61@* 40699 Erkrath, Germany - -The GPGME reference manual 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. - -The GPGME reference manual 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 + at insertcopying @end titlepage @page + at summarycontents + at contents + @ifnottex @node Top @top Main Menu @@ -92,8 +99,12 @@ Appendices +* UI Server Protocol:: The GnuPG UI Server Protocol. + * Library Copying:: The GNU Lesser General Public License says how you can copy and share `GnuPG Made Easy'. +* Copying:: The GNU General Public License says how you + can copy and share this manual. Indices @@ -5501,22 +5512,25 @@ case the state of @var{ctx} is not modified). @end deftypefun + at c ********************************************************** + at c ******************* Appendices ************************* + at c ********************************************************** + at include uiserver.texi + @include lesser.texi + at include gpl.texi + at node Function and Data Index + at unnumbered Function and Data Index + + at printindex fn + @node Concept Index @unnumbered Concept Index @printindex cp - at node Function and Data Index - at unnumbered Function and Data Index - - at printindex fn - - - at summarycontents - at contents @bye Added: trunk/doc/gpl.texi =================================================================== --- trunk/doc/gpl.texi 2008-05-09 08:26:28 UTC (rev 1313) +++ trunk/doc/gpl.texi 2008-06-04 14:14:38 UTC (rev 1314) @@ -0,0 +1,724 @@ + at node Copying + at unnumbered GNU General Public License + at center Version 3, 29 June 2007 + + at c This file is intended to be included in another file. + + at display +Copyright @copyright{} 2007 Free Software Foundation, Inc. @url{http://fsf.org/} + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + at end display + + at section Preamble + +The GNU General Public License is a free, copyleft license for +software and other kinds of works. + +The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom +to share and change all versions of a program--to make sure it remains +free software for all its users. We, the Free Software Foundation, +use the GNU General Public License for most of our software; it +applies also to any other work released this way by its authors. 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 +them 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 prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you +have certain responsibilities if you distribute copies of the +software, or if you modify it: responsibilities to respect the freedom +of others. + +For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. 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. + +Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + +For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + +Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the +manufacturer can do so. This is fundamentally incompatible with the +aim of protecting users' freedom to change the software. The +systematic pattern of such abuse occurs in the area of products for +individuals to use, which is precisely where it is most unacceptable. +Therefore, we have designed this version of the GPL to prohibit the +practice for those products. If such problems arise substantially in +other domains, we stand ready to extend this provision to those +domains in future versions of the GPL, as needed to protect the +freedom of users. + +Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish +to avoid the special danger that patents applied to a free program +could make it effectively proprietary. To prevent this, the GPL +assures that patents cannot be used to render the program non-free. + +The precise terms and conditions for copying, distribution and +modification follow. + + at iftex + at section TERMS AND CONDITIONS + at end iftex + at ifinfo + at center TERMS AND CONDITIONS + at end ifinfo + + at enumerate 0 + at item Definitions. + +``This License'' refers to version 3 of the GNU General Public License. + +``Copyright'' also means copyright-like laws that apply to other kinds +of works, such as semiconductor masks. + +``The Program'' refers to any copyrightable work licensed under this +License. Each licensee is addressed as ``you''. ``Licensees'' and +``recipients'' may be individuals or organizations. + +To ``modify'' a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of +an exact copy. The resulting work is called a ``modified version'' of +the earlier work or a work ``based on'' the earlier work. + +A ``covered work'' means either the unmodified Program or a work based +on the Program. + +To ``propagate'' a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + +To ``convey'' a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user +through a computer network, with no transfer of a copy, is not +conveying. + +An interactive user interface displays ``Appropriate Legal Notices'' to +the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + at item Source Code. + +The ``source code'' for a work means the preferred form of the work for +making modifications to it. ``Object code'' means any non-source form +of a work. + +A ``Standard Interface'' means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + +The ``System Libraries'' of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +``Major Component'', in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + +The ``Corresponding Source'' for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + +The Corresponding Source need not include anything that users can +regenerate automatically from other parts of the Corresponding Source. + +The Corresponding Source for a work in source code form is that same +work. + + at item Basic Permissions. + +All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + +You may make, run and propagate covered works that you do not convey, +without conditions so long as your license otherwise remains in force. +You may convey covered works to others for the sole purpose of having +them make modifications exclusively for you, or provide you with +facilities for running those works, provided that you comply with the +terms of this License in conveying all material for which you do not +control copyright. Those thus making or running the covered works for +you must do so exclusively on your behalf, under your direction and +control, on terms that prohibit them from making any copies of your +copyrighted material outside their relationship with you. + +Conveying under any other circumstances is permitted solely under the +conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + at item Protecting Users' Legal Rights From Anti-Circumvention Law. + +No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + +When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such +circumvention is effected by exercising rights under this License with +respect to the covered work, and you disclaim any intention to limit +operation or modification of the work as a means of enforcing, against +the work's users, your or third parties' legal rights to forbid +circumvention of technological measures. + + at item Conveying Verbatim Copies. + +You may convey 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; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + +You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + at item Conveying Modified Source Versions. + +You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these +conditions: + + at enumerate a + at item +The work must carry prominent notices stating that you modified it, +and giving a relevant date. + + at item +The work must carry prominent notices stating that it is released +under this License and any conditions added under section 7. This +requirement modifies the requirement in section 4 to ``keep intact all +notices''. + + at item +You must license the entire work, as a whole, under this License to +anyone who comes into possession of a copy. This License will +therefore apply, along with any applicable section 7 additional terms, +to the whole of the work, and all its parts, regardless of how they +are packaged. This License gives no permission to license the work in +any other way, but it does not invalidate such permission if you have +separately received it. + + at item +If the work has interactive user interfaces, each must display +Appropriate Legal Notices; however, if the Program has interactive +interfaces that do not display Appropriate Legal Notices, your work +need not make them do so. + at end enumerate + +A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +``aggregate'' if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + at item Conveying Non-Source Forms. + +You may convey a covered work in object code form under the terms of +sections 4 and 5, provided that you also convey the machine-readable +Corresponding Source under the terms of this License, in one of these +ways: + + at enumerate a + at item +Convey the object code in, or embodied in, a physical product +(including a physical distribution medium), accompanied by the +Corresponding Source fixed on a durable physical medium customarily +used for software interchange. + + at item +Convey the object code in, or embodied in, a physical product +(including a physical distribution medium), accompanied by a written +offer, valid for at least three years and valid for as long as you +offer spare parts or customer support for that product model, to give +anyone who possesses the object code either (1) a copy of the +Corresponding Source for all the software in the product that is +covered by this License, on a durable physical medium customarily used +for software interchange, for a price no more than your reasonable +cost of physically performing this conveying of source, or (2) access +to copy the Corresponding Source from a network server at no charge. + + at item +Convey individual copies of the object code with a copy of the written +offer to provide the Corresponding Source. This alternative is +allowed only occasionally and noncommercially, and only if you +received the object code with such an offer, in accord with subsection +6b. + + at item From cvs at cvs.gnupg.org Wed Jun 4 16:15:23 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 04 Jun 2008 16:15:23 +0200 Subject: [svn] GpgEX - r57 - in trunk: . doc Message-ID: Author: wk Date: 2008-06-04 16:15:22 +0200 (Wed, 04 Jun 2008) New Revision: 57 Modified: trunk/ChangeLog trunk/doc/gpgex.texi Log: Moved protocol specs to gpgme.info Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2008-03-26 17:57:51 UTC (rev 56) +++ trunk/ChangeLog 2008-06-04 14:15:22 UTC (rev 57) @@ -1,3 +1,8 @@ +2008-06-04 Werner Koch + + * doc/gpgex.texi (Assuan Protocol): Replace the spec by a + reference to the gpgme manual. + 2008-03-26 Marcus Brinkmann Released 0.9.0. Modified: trunk/doc/gpgex.texi =================================================================== --- trunk/doc/gpgex.texi 2008-03-26 17:57:51 UTC (rev 56) +++ trunk/doc/gpgex.texi 2008-06-04 14:15:22 UTC (rev 57) @@ -111,194 +111,15 @@ @node Assuan Protocol @chapter Description of the UI Server Protocol -This section describes the protocol used between @acronym{GpgEX} and the -User Interface Server (UI server). All cryptographic operations are -done by this server and the server is responsible for all dialogs. If a -a server is not available, @acronym{GpgEX} does not work. +All cryptographic operations are done by this server and the server is +responsible for all dialogs. If a a server is not available, + at acronym{GpgEX} does not work. -We assume that the connection has already been established; see the -Assuan manual for details. +This protocol used between @acronym{GpgEX} and the User Interface Server +(UI server) is specified in the `GPGME Reference Manual', under the +heading `The GnuPG UI Server Protocol'. - at menu -* Specifying input files:: Specifying the input files to operate on. -* Encrypt and sign files:: Encrypting and signing files. -* Decrypt and verify files:: Decrypting and verifying files. -* Certificate management:: Managing certificates. -* Checksum files:: Create and verify checksums for files. -* Miscellaneous commands:: Support functions. - at end menu - - at node Specifying input files - at section Specifying the input files to operate on. - -All commands operate on a number of input files or directories, -specified by one or more @code{FILE} commands: - - at deffn Command FILE @var{name} [--continued] -Add the file or directory @var{name} to the list of pathnames to be -processed by the server. The parameter @var{name} must be an absolute -path name (including the drive letter) and is percent espaced (in -particular, the characters %, = and white space characters are always -escaped). The option @code{--continued} is present for all but the -last @code{FILE} command. - at end deffn - - - at node Encrypt and sign files - at section Encrypting and signing files. - -First, the input files need to be specified by one or more - at code{FILE} commands. Afterwards, the actual operation is requested: - - at deffn Command ENCRYPT_FILES --nohup - at deffnx Command SIGN_FILES --nohup - at deffnx Command ENCRYPT_SIGN_FILES --nohup -Request that the files specified by @code{FILE} are encrypted and/or -signed. The command selects the default action. The UI server may -allow the user to change this default afterwards interactively, and -even abort the operation or complete it only on some of the selected -files and directories. - -What it means to encrypt or sign a file or directory is specific to -the preferences of the user, the functionality the UI server provides, -and the selected protocol. Typically, for each input file a new file -is created under the original filename plus a protocol specific -extension (like @code{.gpg} or @code{.sig}), which contain the -encrypted/signed file or a detached signature. For directories, the -server may offer multiple options to the user (for example ignore or -process recursively). - -The @code{ENCRYPT_SIGN_FILES} command requests a combined sign and -encrypt operation. It may not be available for all protocols (for -example, it is available for OpenPGP but not for CMS). - -The option @code{--nohup} is mandatory. It is currently unspecified -what should happen if @code{--nohup} is not present. Because - at code{--nohup} is present, the server always returns @code{OK} -promptly, and completes the operation asynchronously. - at end deffn - - - at node Decrypt and verify files - at section Decrypting and verifying files. - -First, the input files need to be specified by one or more - at code{FILE} commands. Afterwards, the actual operation is requested: - - at deffn Command DECRYPT_FILES --nohup - at deffnx Command VERIFY_FILES --nohup - at deffnx Command DECRYPT_VERIFY_FILES --nohup -Request that the files specified by @code{FILE} are decrypted and/or -verified. The command selects the default action. The UI server may -allow the user to change this default afterwards interactively, and -even abort the operation or complete it only on some of the selected -files and directories. - -What it means to decrypt or verify a file or directory is specific to -the preferences of the user, the functionality the UI server provides, -and the selected protocol. Typically, for decryption, a new file is -created for each input file under the original filename minus a -protocol specific extension (like @code{.gpg}) which contains the -original plaintext. For verification a status is displayed for each -signed input file, indicating if it is signed, and if yes, if the -signature is valid. For files that are signed and encrypted, the - at code{VERIFY} command transiently decrypts the file to verify the -enclosed signature. For directories, the server may offer multiple -options to the user (for example ignore or process recursively). - -The option @code{--nohup} is mandatory. It is currently unspecified -what should happen if @code{--nohup} is not present. Because - at code{--nohup} is present, the server always returns @code{OK} -promptly, and completes the operation asynchronously. - at end deffn - - - at node Certificate management - at section Managing certificates. - -First, the input files need to be specified by one or more - at code{FILE} commands. Afterwards, the actual operation is requested: - - at deffn Command IMPORT_FILES --nohup -Request that the certificates contained in the files specified by - at code{FILE} are imported into the local certificate databases. - -For directories, the server may offer multiple options to the user -(for example ignore or process recursively). - -The option @code{--nohup} is mandatory. It is currently unspecified -what should happen if @code{--nohup} is not present. Because - at code{--nohup} is present, the server always returns @code{OK} -promptly, and completes the operation asynchronously. - at end deffn - -FIXME: It may be nice to support an @code{EXPORT} command as well, -which is enabled by the context menu of the background of a directory. - - - at node Checksum files - at section Create and verify checksums for files. - -First, the input files need to be specified by one or more - at code{FILE} commands. Afterwards, the actual operation is requested: - - at deffn Command CHECKSUM_CREATE_FILES --nohup -Request that checksums are created for the files specifed by - at code{FILE}. The choice of checksum algorithm and the destination -storage and format for the created checksums depend on the preferences -of the user and the functionality provided by the UI server. For -directories, the server may offer multiple options to the user (for -example ignore or process recursively). - -The option @code{--nohup} is mandatory. It is currently unspecified -what should happen if @code{--nohup} is not present. Because - at code{--nohup} is present, the server always returns @code{OK} -promptly, and completes the operation asynchronously. - at end deffn - - - at deffn Command CHECKSUM_VERIFY_FILES --nohup -Request that checksums are created for the files specifed by - at code{FILE} and verified against previously created and stored -checksums. The choice of checksum algorithm and the source storage -and format for previously created checksums depend on the preferences -of the user and the functionality provided by the UI server. For -directories, the server may offer multiple options to the user (for -example ignore or process recursively). - -If the source storage of previously created checksums is available to -the user through the Windows shell, this command may also accept such -checksum files as @code{FILE} arguments. In this case, the UI server -should instead verify the checksum of the referenced files as if they -were given as INPUT files. - -The option @code{--nohup} is mandatory. It is currently unspecified -what should happen if @code{--nohup} is not present. Because - at code{--nohup} is present, the server always returns @code{OK} -promptly, and completes the operation asynchronously. - at end deffn - - - at c - at c M I S C E L L A N E O U S C O M M A N D S - at c - at node Miscellaneous commands - at section Support functions. - - at noindent -To allow the server to pop up the windows in the correct relation to the -client, the client is advised to tell the server by sending the option: - - at deffn {Command option} window-id @var{number} -The @var{number} represents the native window ID of the clients current -window. On Windows systems this is a windows handle (@code{HWND}) and -on X11 systems it is the @code{X Window ID}. The number needs to be -given as a hexadecimal value so that it is easier to convey pointer -values (e.g. @code{HWND}). - at end deffn - - @include gpl.texi @c From cvs at cvs.gnupg.org Wed Jun 4 16:19:12 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 04 Jun 2008 16:19:12 +0200 Subject: [svn] GpgOL - r255 - in trunk: . doc Message-ID: Author: wk Date: 2008-06-04 16:19:11 +0200 (Wed, 04 Jun 2008) New Revision: 255 Modified: trunk/ChangeLog trunk/doc/gpgol.texi Log: Moved UI server protocol specs to the GPGME manual. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2008-05-28 14:08:03 UTC (rev 254) +++ trunk/ChangeLog 2008-06-04 14:19:11 UTC (rev 255) @@ -1,3 +1,8 @@ +2008-06-04 Werner Koch + + * doc/gpgol.texi (Assuan Protocol): Remove protocol specs. They + are now part of the GPGME manual. + 2008-05-28 Werner Koch * Release 0.10.14. Modified: trunk/doc/gpgol.texi =================================================================== --- trunk/doc/gpgol.texi 2008-05-28 14:08:03 UTC (rev 254) +++ trunk/doc/gpgol.texi 2008-06-04 14:19:11 UTC (rev 255) @@ -134,426 +134,16 @@ @node Assuan Protocol @chapter Description of the UI Server Protocol -This section describes the protocol used between @acronym{GpgOL} and the -User Interface Server (UI server). All cryptographic operations are -done by this server and the server is responsible for all dialogs. If a -a server is not available, @acronym{GpgOL} can only use a very limited -internal crypto server. +All cryptographic operations are done by a server and the server is +responsible for all dialogs. If a a server is not available, + at acronym{GpgOL} does not work. -We assume that the connection has already been established; see the -Assuan manual for details. +This protocol used between @acronym{GpgOL} and the User Interface Server +(UI server) is specified in the `GPGME Reference Manual', under the +heading `The GnuPG UI Server Protocol'. - at menu -* ENCRYPT:: Encrypt a message. -* SIGN:: Sign a message. -* DECRYPT:: Decrypt a message. -* VERIFY:: Verify a message. -* Miscellaneous Commands:: Commands not related to a specific operation. - at end menu - - at node ENCRYPT - at section Encrypt a Message - -Before encryption can be done the recipients must be set using the -command: - - at deffn Command RECIPIENT @var{string} - -Set the recipient for the encryption. @var{string} is an RFC-2822 -recipient name ("mailbox" as per section 3.4). This command may or may -not check the recipient for validity right away; if it does not all -recipients are expected to be checked at the time of the @code{ENCRYPT} -command. All @code{RECIPIENT} commands are cumulative until a -successful @code{ENCRYPT} command or until a @code{RESET} command. -Linefeeds are obviously not allowed in @var{string} and should be folded -into spaces (which are equivalent). - at end deffn - - at noindent -To tell the server the source and destination of the data, the next two -commands are to be used: - - at deffn Command INPUT FD=@var{n} -Set the file descriptor for the message to be encrypted to @var{n}. The -message send to the server is binary encoded. - -GpgOL is a Windows only program, thus @var{n} is not a libc file -descriptor but a regular system handle. Given that the Assuan -connection works over a socket, it is not possible to use regular -inheritance to make the file descriptor available to the server. -Thus @code{DuplicateHandle} needs to be used to duplicate a handle -to the server process. This is the reason that the server needs to -implement the @code{GETINFO pid} command. Sending this command a second -time replaces the file descriptor set by the last one. - at c If @var{n} is not given, this commands uses the - at c %last file descriptor passed to the application. - at c %@xref{fun-assuan_sendfd, ,the assuan_sendfd function,assuan,the - at c %Libassuan manual}, on how to do descriptor passing. - at end deffn - - at deffn Command OUTPUT FD=@var{n} -Set the file descriptor to be used for the output (i.e. the encrypted -message) to @var{n}. For OpenPGP, the output needs to be ASCII armored; -for CMS, the output needs to be Base-64 encoded. For details on the -file descriptor, see the @code{INPUT} command. - at end deffn - - at noindent -The setting of the recipients, the data source and destination may -happen in any order, even intermixed. If this has been done the actual -encryption operation is called using: - - at deffn Command ENCRYPT - at w{}-protocol=@var{name} - -This command reads the plaintext from the file descriptor set by the - at code{INPUT} command, encrypts it and writes the ciphertext to the file -descriptor set by the @code{OUTPUT} command. The server may (and -should) overlap reading and writing. The recipients used for the -encryption are all the recipients set so far. If any recipient is not -usable the server should take appropriate measures to notify the user -about the problem and may cancel the operation by returning an error -code. The used file descriptors are void after this command; the -recipient list is only cleared if the server returns success. - - at noindent -Because GpgOL uses a streaming mode of operation the server is not -allowed to auto select the protocol and must obey to the mandatory - at var{protocol} parameter: - - at table @code - at item OpenPGP -Use the OpenPGP protocol (RFC-2440). - at item CMS -Use the CMS (PKCS#7) protocol (RFC-3852). - at end table - - at end deffn - -To support automagically selection of the protocol depending on the -selected keys, the server MAY implement the command: - - at deffn Command PREP_ENCRYPT [- at w{}-protocol=@var{name}] - -This commands considers all recipients set so far and decides whether it -is able to take input and start the actual decryption. This is kind of -a dry-run @command{ENCRYPT} without requiring or using the input and -output file descriptors. The server shall cache the result of any user -selection to avoid asking this again when the actual @command{ENCRYPT} -command is send. The @option{--protocol} option is optional; if it is -not given, the server should allow the user to select the protocol to be -used based on the recipients given or by any other means. - -If this command is given again before a successful @command{ENCRYPT} -command, the second one takes effect. - -Before sending the OK response the server shall tell the client the -protocol to be used (either the one given by the argument or the one -selected by the user) by means of a status line: - at end deffn - - at deffn {Status line} PROTOCOL @var{name} -Advise the client to use the protocol @var{name} for the - at command{ENCRYPT} command. The valid protocol names are listed under -the description of the @command{ENCRYPT} command. The server shall emit -exactly one PROTOCOL status line. - at end deffn - - at noindent -Here is an example of a complete encryption sequence; client lines are -indicated by a @sc{c:}, server responses by @sc{c:}: - - at smallexample - at group - @clnt RESET - @srvr OK - @clnt RECIPIENT foo@@example.net - @srvr OK - @clnt RECIPIENT bar@@example.com - @srvr OK - @clnt PREP_ENCRYPT - @srvr S PROTOCOL OpenPGP - @srvr OK - @clnt INPUT FD=17 - @srvr OK - @clnt OUTPUT FD=18 - @srvr OK - @clnt ENCRYPT - @srvr OK - at end group - at end smallexample - - - - at node SIGN - at section Sign a Message - -The server needs to implement opaque signing as well as detached -signing. Due to the nature of OpenPGP messages it is always required to -send the entire message to the server; sending just the hash is not -possible. The following two commands are required to set the input and -output file descriptors: - - at deffn Command INPUT FD=@var{n} -Set the file descriptor for the message to be signed to @var{n}. The -message send to the server is binary encoded. For details on the file -descriptor, see the description of @code{INPUT} in the @code{ENCRYPT} -section. - at end deffn - - at deffn Command OUTPUT FD=@var{n} -Set the file descriptor to be used for the output. The output is either -the complete signed message or in case of a detached signature just that -detached signature. For OpenPGP, the output needs to be ASCII armored; -for CMS, the output needs to be Base-64 encoded. For details on the -file descriptor, see the @code{INPUT} command. - at end deffn - - at noindent -To allow the server the selection of a non-default signing key the -client may optionally use the @code{SENDER} command, see @ref{command -SENDER}. - - at noindent -The signing operation is then initiated by: - - at deffn Command SIGN - at w{}-protocol=@var{name} [- at w{}-detached] -Sign the data set with the @code{INPUT} command and write it to the sink -set by OUTPUT. @var{name} is the signing protocol used for the -message. For a description of the allowed protocols see the - at code{ENCRYPT} command. With option @code{--detached} given, a detached -signature is created; this is actually the usual way the command is -used. - at end deffn - - at noindent -The client expects the server to send at least this status information -before the final OK response: - - at deffn {Status line} MICALG @var{string} -The @var{string} represents the hash algorithm used to create the -signature. It is used with MOSS style signature messages and defined by -PGP/MIME (RFC-3156) and S/MIME (RFC-3851). The GPGME library has a -supporting function @code{gpgme_hash_algo_name} to return the algorithm -name as a string. This string needs to be lowercased and for OpenPGP -prefixed with "@code{pgp-}". - at end deffn - - - - at node DECRYPT - at section Decrypt a Message - -Decryption may include the verification of OpenPGP messages. This is -due to the often used combined signing/encryption modus of OpenPGP. The -client may pass an option to the server to inhibit the signature -verification. The following two commands are required to set the input -and output file descriptors: - - at deffn Command INPUT FD=@var{n} -Set the file descriptor for the message to be decrypted to @var{n}. The -message send to the server is either binary encoded or --- in the case -of OpenPGP --- ASCII armored. For details on the file descriptor, see -the description of @code{INPUT} in the @code{ENCRYPT} section. - at end deffn - - at deffn Command OUTPUT FD=@var{n} -Set the file descriptor to be used for the output. The output is binary -encoded. For details on the file descriptor, see the description of - at code{INPUT} in the @code{ENCRYPT} section. - at end deffn - - at noindent -The decryption is started with the command: - - at deffn Command DECRYPT - at w{}-protocol=@var{name} [- at w{}-no-verify] - at var{name} is the encryption protocol used for the message. For a -description of the allowed protocols see the @code{ENCRYPT} command. -This argument is mandatory. If the option @option{--no-verify} is given, -the server should not try to verify a signature, in case the input data -is an OpenPGP combined message. - at end deffn - - - at node VERIFY - at section Verify a Message - -The server needs to support the verification of opaque signatures as -well as detached signatures. The kind of input sources controls what -kind message is to be verified. - - at deffn Command MESSAGE FD=@var{n} -This command is used with detached signatures to set the file descriptor -for the signed data to @var{n}. The data is binary encoded (used -verbatim). For details on the file descriptor, see the description of - at code{INPUT} in the @code{ENCRYPT} section. - at end deffn - - at deffn Command INPUT FD=@var{n} -Set the file descriptor for the opaque message or the signature part of -a detached signature to @var{n}. The message send to the server is -either binary encoded or -- in the case of OpenPGP -- ASCII armored. -For details on the file descriptor, see the description of @code{INPUT} -in the @code{ENCRYPT} section. - at end deffn - - at deffn Command OUTPUT FD=@var{n} -Set the file descriptor to be used for the output. The output is binary -encoded and only used for opaque signatures. For details on the file -descriptor, see the description of @code{INPUT} in the @code{ENCRYPT} -section. - at end deffn - - at noindent -The verification is then started using: - - at deffn Command VERIFY - at w{}-protocol=@var{name} [- at w{}-silent] - at var{name} is the signing protocol used for the message. For a -description of the allowed protocols see the @code{ENCRYPT} command. -This argument is mandatory. Depending on the combination of - at code{MESSAGE} @code{INPUT} and @code{OUTPUT} commands, the server needs -to select the appropriate verification mode: - - at table @asis - at item MESSAGE and INPUT -This indicates a detached signature. Output data is not applicable. - at item INPUT -This indicates an opaque signature. As no output command has been given, -the server is only required to check the signature. - at item INPUT and OUTPUT -This indicates an opaque signature. The server shall write the signed -data to the file descriptor set by the output command. This data shall -even be written if the signatures can't be verified. - at end table - at end deffn - -With @option{--silent} the server shall not display any dialog; this is -for example used by the client to get the content of opaque signed -messages. The client expects the server to send at least this status -information before the final OK response: - - at deffn {Status line} SIGSTATUS @var{flag} @var{displaystring} -Returns the status for the signature and a short string explaining the -status. Valid values for @var{flag} are: - - at table @code - at item none -The message has a signature but it could not not be verified due to a -missing key. - at item green -The signature is fully valid. - at item yellow -The signature is valid but additional information was shown regarding the -validity of the key. - at item red -The signature is not valid. - at end table - - at var{displaystring} is a percent-and-plus-encoded string with a short -human readable description of the status. For example - - at smallexample -S SIGSTATUS green Good+signature+from+Keith+Moon+ - at end smallexample - -Note that this string needs to fit into an Assuan line and should be -short enough to be displayed as short one-liner on the clients window. -As usual the encoding of this string is UTF-8 and it should be send in -its translated form. - -The server shall send one status line for every signature found on the -message. - - - at end deffn - - - - at c - at c M I S C E L L A N E O U S C O M M A N D S - at c - at node Miscellaneous Commands - at section Miscellaneous Commands - -The server needs to implement the following commands which are not -related to a specific command: - - at deffn Command GETINFO @var{what} -This is a multi purpose command, commonly used to return a variety of -information. The required subcommands as described by the @var{what} -parameter are: - - at table @code - at item pid -Return the process id of the server in decimal notation using an Assuan -data line. - at end table - at end deffn - - - at noindent -To allow the server to pop up the windows in the correct relation to the -client, the client is advised to tell the server by sending the option: - - at deffn {Command option} window-id @var{number} -The @var{number} represents the native window ID of the clients current -window. On Windows systems this is a windows handle (@code{HWND}) and -on X11 systems it is the @code{X Window ID}. The number needs to be -given as a hexadecimal value so that it is easier to convey pointer -values (e.g. @code{HWND}). - at end deffn - - - at noindent -GpgOL features a button to invoke the certificate manager. To do this -it uses the Assuan command: - - at deffn Command START_KEYMANAGER -The server shall pop up the main window of the key manager (aka -certificate manager). The client expects that the key manager is brought -into the foregound and that this command immediatley returns (does not -wait until the key manager has been fully brought up). - at end deffn - - at anchor{command SENDER} - at noindent -When doing an operation on a mail, it is useful to let the server know -the address of the sender: - - at deffn Command SENDER [- at w{}-info] @var{email} - at var{email} is the plain ASCII encoded address ("addr-spec" as per -RFC-2822) enclosed in angle brackets. The address set with this command -is valid until a successful completion of the operation or until a - at code{RESET} command. A second command overrides the effect of the -first one; if @var{email} is not given and @option{--info} is not used, -the server shall use the default signing key. - -If option @option{--info} is not given, the server shall also suggest a -protocol to use for signing. The client may use this suggested protocol -on its own discretion. The same status line as with PREP_ENCRYPT is -used for this. - at end deffn - - at noindent -To allow the UI-server to visually identify a running operation or to -associate operations the server MAY support the command: - - at deffn Command SESSION @var{number} [@var{string}] -The @var{number} is an arbitrary value, a server may use to associate -simultaneous running sessions. It is a 32 bit unsigned integer with - at code{0} as a special value indicating that no session association shall -be done. - -If @var{string} is given, the server may use this as the title of a -window or, in the case of an email operation, to extract the sender's -address. The string may contain spaces; thus no plus-escaping is used. - -This command may be used at any time and overrides the effect of the -last command. A @code{RESET} undoes the effect of this command. - - at end deffn - @c xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx @c @c M A P I P r o p e r t i e s From cvs at cvs.gnupg.org Thu Jun 5 09:46:13 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 05 Jun 2008 09:46:13 +0200 Subject: [svn] GnuPG - r4776 - trunk/common Message-ID: Author: wk Date: 2008-06-05 09:46:12 +0200 (Thu, 05 Jun 2008) New Revision: 4776 Modified: trunk/common/ChangeLog trunk/common/gettime.c trunk/common/util.h Log: As a failsafe measure use memcpy instead of strcpy in gnupg_copy_time. Typo fix. Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2008-06-01 19:44:05 UTC (rev 4775) +++ trunk/common/ChangeLog 2008-06-05 07:46:12 UTC (rev 4776) @@ -1,3 +1,7 @@ +2008-06-05 Werner Koch + + * util.h (gnupg_copy_time): Replace strcpy by memcpy. + 2008-05-26 Werner Koch * asshelp.c (send_one_option, send_pinentry_environment): use Modified: trunk/common/gettime.c =================================================================== --- trunk/common/gettime.c 2008-06-01 19:44:05 UTC (rev 4775) +++ trunk/common/gettime.c 2008-06-05 07:46:12 UTC (rev 4776) @@ -402,7 +402,7 @@ /* Convert YEAR, MONTH and DAY into the Julian date. We assume that - it is already noon; we dont; support dates before 1582-10-15. */ + it is already noon. We do not support dates before 1582-10-15. */ static unsigned long date2jd (int year, int month, int day) { Modified: trunk/common/util.h =================================================================== --- trunk/common/util.h 2008-06-01 19:44:05 UTC (rev 4775) +++ trunk/common/util.h 2008-06-05 07:46:12 UTC (rev 4776) @@ -115,13 +115,19 @@ gpg_error_t check_isotime (const gnupg_isotime_t atime); /* Copy one ISO date to another, this is inline so that we can do a - sanity check. */ + minimal sanity check. A null date (empty string) is allowed. */ static inline void gnupg_copy_time (gnupg_isotime_t d, const gnupg_isotime_t s) { - if (*s && (strlen (s) != 15 || s[8] != 'T')) - BUG(); - strcpy (d, s); + if (*s) + { + if ((strlen (s) != 15 || s[8] != 'T')) + BUG(); + memcpy (d, s, 15); + d[15] = 0; + } + else + *d = 0; } From cvs at cvs.gnupg.org Thu Jun 5 12:38:05 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 05 Jun 2008 12:38:05 +0200 Subject: [svn] GpgOL - r256 - trunk/src Message-ID: Author: wk Date: 2008-06-05 12:38:03 +0200 (Thu, 05 Jun 2008) New Revision: 256 Modified: trunk/src/ChangeLog trunk/src/engine-assuan.c trunk/src/engine.c trunk/src/engine.h trunk/src/mapihelp.cpp trunk/src/mapihelp.h trunk/src/mimeparser.c Log: Send the SESSION command to the server. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2008-06-04 14:19:11 UTC (rev 255) +++ trunk/src/ChangeLog 2008-06-05 10:38:03 UTC (rev 256) @@ -1,3 +1,20 @@ +2008-06-05 Werner Koch + + * mimeparser.c (mime_decrypt): Set session number and title. + (mime_verify_opaque, mime_verify): Ditto. + * mapihelp.cpp (mapi_get_subject): New. + * engine.c (engine_set_session_number, engine_set_session_title) + (engine_set_sender_address): New. + (struct engine_filter_s): Add fields session_number, session_title + and sender_address. + (engine_private_get_session_number): New. + (engine_private_get_session_title): New. + (release_filter): Release them. + (engine_new_session_number): New. + * engine-assuan.c (send_session_info): New + (op_assuan_decrypt, op_assuan_verify): Call it. + (op_assuan_sign): Use the end-of-option option for the SENDER command. + 2008-05-28 Werner Koch * dialogs.h (IDC_BODY_AS_ATTACHMENT): New. Modified: trunk/src/engine-assuan.c =================================================================== --- trunk/src/engine-assuan.c 2008-06-04 14:19:11 UTC (rev 255) +++ trunk/src/engine-assuan.c 2008-06-05 10:38:03 UTC (rev 256) @@ -526,9 +526,23 @@ } +/* end the optiona session information. */ +static void +send_session_info (assuan_context_t ctx, engine_filter_t filter) +{ + char line[1020]; + unsigned int number = engine_private_get_session_number (filter); + const char *title = engine_private_get_session_title (filter); + if (title && *title) + snprintf (line, sizeof line, "SESSION %u %s", number, title); + else + snprintf (line, sizeof line, "SESSION %u", number); + assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); +} + + - static void cleanup (void) { @@ -1796,13 +1810,14 @@ if (err) goto leave; - /* We always send the SENDER command becuase it allows us to figure + /* We always send the SENDER command because it allows us to figure out the protocol to use. In case the UI server faisl to send the protocol we fall back to OpenPGP. */ suggested_protocol = PROTOCOL_UNKNOWN; if (!sender) sender = ""; - snprintf (line, sizeof line, "SENDER%s%s", sender? " ":"", sender?sender:""); + snprintf (line, sizeof line, "SENDER%s%s", + sender? " -- ":"", sender?sender:""); err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, prep_foo_status_cb, &suggested_protocol); if (err) @@ -1915,6 +1930,8 @@ if (err) goto leave; + send_session_info (ctx, filter); + snprintf (line, sizeof line, "INPUT FD=%ld", (unsigned long int)inpipe[0]); err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); if (err) @@ -2044,6 +2061,8 @@ if (err) goto leave; + send_session_info (ctx, filter); + if (!opaque_mode) { snprintf (line, sizeof line, "MESSAGE FD=%ld", Modified: trunk/src/engine.c =================================================================== --- trunk/src/engine.c 2008-06-04 14:19:11 UTC (rev 255) +++ trunk/src/engine.c 2008-06-05 10:38:03 UTC (rev 256) @@ -108,6 +108,13 @@ /* Counter used to optimize voluntary thread switching. */ ULONG switch_counter; + + /* Optional data to be passed to the backend to help the server + display a useful title and to associate operations with one OL + task. */ + unsigned int session_number; + char *session_title; /* (malloced) */ + char *sender_address; /* (malloced) */ }; @@ -196,6 +203,8 @@ CloseHandle (filter->in.ready_event); gpgme_data_release (filter->indata); gpgme_data_release (filter->outdata); + xfree (filter->session_title); + xfree (filter->sender_address); xfree (filter); } } @@ -384,8 +393,19 @@ } +unsigned int +engine_private_get_session_number (engine_filter_t filter) +{ + return filter? filter->session_number : 0; +} +const char * +engine_private_get_session_title (engine_filter_t filter) +{ + return filter? filter->session_title : NULL; +} + /* Initialize the engine dispatcher. */ int @@ -424,7 +444,22 @@ op_gpgme_deinit (); } +/* Helper function to return a new session number. */ +unsigned int +engine_new_session_number (void) +{ + static ULONG number; + ULONG n; + /* The protocol says the session number is a 32 bit value, thus we + make that sure even in the case that ULONG is changed to a 64 bit + type (Not an issue under Windows, though). */ + while (!((n = InterlockedIncrement (&number))&0xffffffff) ) + ; + return n; +} + + /* Filter the INDATA of length INDATA and write the output using OUTFNC. OUTFNCDATA is passed as first argument to OUTFNC, followed @@ -601,7 +636,7 @@ } -/* Set the FILTER in a mode which pushes an extra lineffed out. */ +/* Set the FILTER in a mode which pushes an extra linefeed out. */ void engine_request_exra_lf (engine_filter_t filter) { @@ -609,6 +644,41 @@ } +/* Set the session number for FILTER to NUMBER. */ +void +engine_set_session_number (engine_filter_t filter, unsigned int value) +{ + if (filter) + filter->session_number = value; +} + +/* Set the session title for FILTER to TITLE. */ +void +engine_set_session_title (engine_filter_t filter, const char *title) +{ + if (filter) + { + xfree (filter->session_title); + filter->session_title = title? xstrdup (title) : NULL; + } +} + +/* Set the sender address for FILTER to ADDR. Setting the sender + address to NULL is allowed. This sender address may be used by the + server to check whether the used key matches the sender address + while verifying a message. Note that this sender address is not + used for selecting a key during encryption or verification. */ +void +engine_set_sender_address (engine_filter_t filter, const char *addr) +{ + if (filter) + { + xfree (filter->sender_address); + filter->sender_address = addr? xstrdup (addr) : NULL; + } +} + + /* Wait for FILTER to finish. Returns 0 on success. FILTER is not valid after the function has returned success. */ int @@ -763,7 +833,7 @@ -/* Start an encryption operation to all RECIPEINTS using PROTOCOL +/* Start an encryption operation to all RECIPIENTS using PROTOCOL RECIPIENTS is a NULL terminated array of rfc2822 addresses. FILTER is an object created by engine_create_filter. The caller needs to call engine_wait to finish the operation. A filter object may not Modified: trunk/src/engine.h =================================================================== --- trunk/src/engine.h 2008-06-04 14:19:11 UTC (rev 255) +++ trunk/src/engine.h 2008-06-05 10:38:03 UTC (rev 256) @@ -50,16 +50,24 @@ /*-- engine.c -- */ int engine_init (void); void engine_deinit (void); +unsigned int engine_new_session_number (void); void engine_private_set_cancel (engine_filter_t filter, void *cancel_data); void engine_private_finished (engine_filter_t filter, gpg_error_t status); +unsigned int engine_private_get_session_number (engine_filter_t filter); +const char *engine_private_get_session_title (engine_filter_t filter); + int engine_filter (engine_filter_t filter, const void *indata, size_t indatalen); int engine_create_filter (engine_filter_t *r_filter, int (*outfnc) (void *, const void *, size_t), void *outfncdata); void engine_request_exra_lf (engine_filter_t filter); +void engine_set_session_number (engine_filter_t filter, unsigned int value); +void engine_set_session_title (engine_filter_t filter, const char *title); +void engine_set_sender_address (engine_filter_t filter, const char *addr); + int engine_wait (engine_filter_t filter); void engine_cancel (engine_filter_t filter); Modified: trunk/src/mapihelp.cpp =================================================================== --- trunk/src/mapihelp.cpp 2008-06-04 14:19:11 UTC (rev 255) +++ trunk/src/mapihelp.cpp 2008-06-05 10:38:03 UTC (rev 256) @@ -998,7 +998,7 @@ -/* Return teh sender of the message. According to the specs this is +/* Return the sender of the message. According to the specs this is an UTF-8 string; we rely on that the UI server handles internationalized domain names. */ char * @@ -1055,9 +1055,48 @@ return buf; } +/* Return the subject of the message as a malloced UTF-8 string. + Returns a replacement string if a subject is missing. */ +char * +mapi_get_subject (LPMESSAGE message) +{ + HRESULT hr; + LPSPropValue propval = NULL; + char *buf; + + if (!message) + return xstrdup ("[no message]"); /* Ooops. */ + hr = HrGetOneProp ((LPMAPIPROP)message, PR_SUBJECT_W, &propval); + if (FAILED (hr)) + { + log_debug ("%s:%s: HrGetOneProp failed: hr=%#lx\n", + SRCNAME, __func__, hr); + return xstrdup (_("[no subject]")); + } + + if (PROP_TYPE (propval->ulPropTag) != PT_UNICODE) + { + log_debug ("%s:%s: HrGetOneProp returns invalid type %lu\n", + SRCNAME, __func__, PROP_TYPE (propval->ulPropTag) ); + MAPIFreeBuffer (propval); + return xstrdup (_("[no subject]")); + } + + buf = wchar_to_utf8 (propval->Value.lpszW); + MAPIFreeBuffer (propval); + if (!buf) + { + log_error ("%s:%s: error converting to utf8\n", SRCNAME, __func__); + return xstrdup (_("[no subject]")); + } + return buf; +} + + + /* Return the message type. This function knows only about our own message types. Returns MSGTYPE_UNKNOWN for any MESSAGE we have no special support for. */ Modified: trunk/src/mapihelp.h =================================================================== --- trunk/src/mapihelp.h 2008-06-04 14:19:11 UTC (rev 255) +++ trunk/src/mapihelp.h 2008-06-05 10:38:03 UTC (rev 256) @@ -117,6 +117,8 @@ char *mapi_get_binary_prop (LPMESSAGE message,ULONG proptype,size_t *r_nbytes); +char *mapi_get_subject (LPMESSAGE message); + LPSTREAM mapi_get_body_as_stream (LPMESSAGE message); char *mapi_get_body (LPMESSAGE message, size_t *r_nbytes); Modified: trunk/src/mimeparser.c =================================================================== --- trunk/src/mimeparser.c 2008-06-04 14:19:11 UTC (rev 255) +++ trunk/src/mimeparser.c 2008-06-05 10:38:03 UTC (rev 256) @@ -1238,6 +1238,12 @@ if ((err=engine_create_filter (&filter, NULL, NULL))) goto leave; + engine_set_session_number (filter, engine_new_session_number ()); + { + char *tmp = mapi_get_subject (mapi_message); + engine_set_session_title (filter, tmp); + xfree (tmp); + } if ((err=engine_verify_start (filter, hwnd, signature, sig_len, ctx->protocol))) goto leave; @@ -1350,6 +1356,12 @@ if ((err=engine_create_filter (&filter, plaintext_handler, ctx))) goto leave; + engine_set_session_number (filter, engine_new_session_number ()); + { + char *tmp = mapi_get_subject (mapi_message); + engine_set_session_title (filter, tmp); + xfree (tmp); + } if ((err=engine_verify_start (filter, hwnd, NULL, 0, protocol))) goto leave; @@ -1690,6 +1702,12 @@ goto leave; if (simple_pgp) engine_request_exra_lf (filter); + engine_set_session_number (filter, engine_new_session_number ()); + { + char *tmp = mapi_get_subject (mapi_message); + engine_set_session_title (filter, tmp); + xfree (tmp); + } if ((err=engine_decrypt_start (filter, hwnd, protocol, !preview_mode))) goto leave; From cvs at cvs.gnupg.org Thu Jun 5 12:56:46 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 05 Jun 2008 12:56:46 +0200 Subject: [svn] gpgme - r1315 - trunk/doc Message-ID: Author: wk Date: 2008-06-05 12:56:40 +0200 (Thu, 05 Jun 2008) New Revision: 1315 Added: trunk/doc/uiserver.texi Log: Add missing file. From cvs at cvs.gnupg.org Mon Jun 9 16:49:39 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 09 Jun 2008 16:49:39 +0200 Subject: [svn] GnuPG - r4777 - trunk/common Message-ID: Author: wk Date: 2008-06-09 16:49:28 +0200 (Mon, 09 Jun 2008) New Revision: 4777 Added: trunk/common/b64dec.c Modified: trunk/common/ChangeLog trunk/common/Makefile.am trunk/common/t-b64.c trunk/common/util.h Log: Add Base64 decoder. Not yet used but complements out encoder. Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2008-06-05 07:46:12 UTC (rev 4776) +++ trunk/common/ChangeLog 2008-06-09 14:49:28 UTC (rev 4777) @@ -1,3 +1,7 @@ +2008-06-09 Werner Koch + + * b64dec.c: New. + 2008-06-05 Werner Koch * util.h (gnupg_copy_time): Replace strcpy by memcpy. Modified: trunk/common/Makefile.am =================================================================== --- trunk/common/Makefile.am 2008-06-05 07:46:12 UTC (rev 4776) +++ trunk/common/Makefile.am 2008-06-09 14:49:28 UTC (rev 4777) @@ -50,7 +50,7 @@ homedir.c \ gettime.c \ yesno.c \ - b64enc.c \ + b64enc.c b64dec.c \ convert.c \ miscellaneous.c \ xasprintf.c \ Added: trunk/common/b64dec.c =================================================================== --- trunk/common/b64dec.c 2008-06-05 07:46:12 UTC (rev 4776) +++ trunk/common/b64dec.c 2008-06-09 14:49:28 UTC (rev 4777) @@ -0,0 +1,217 @@ +/* b64dec.c - Simple Base64 decoder. + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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, see . + */ + +#include +#include +#include +#include +#include +#include + +#include "i18n.h" +#include "util.h" + + +/* The reverse base-64 list used for base-64 decoding. */ +static unsigned char const asctobin[128] = + { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, + 0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff + }; + +enum decoder_states + { + s_init, s_idle, s_lfseen, s_begin, + s_b64_0, s_b64_1, s_b64_2, s_b64_3, + s_waitendtitle, s_waitend + }; + + + +/* Initialize the context for the base64 decoder. If TITLE is NULL a + plain base64 decoding is done. If it is the empty string the + decoder will skip everything until a "-----BEGIN " line has been + seen, decoding ends at a "----END " line. + + Not yet implemented: If TITLE is either "PGP" or begins with "PGP " + the PGP armor lines are skipped as well. */ +gpg_error_t +b64dec_start (struct b64state *state, const char *title) +{ + memset (state, 0, sizeof *state); + if (title) + { + if (!strncmp (title, "PGP", 3) && (!title[3] || title[3] == ' ')) + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); + + state->title = xtrystrdup (title); + if (!state->title) + return gpg_error_from_syserror (); + state->idx = s_init; + } + else + state->idx = s_b64_0; + return 0; +} + + +/* Do in-place decoding of base-64 data of LENGTH in BUFFER. Stores the + new length of the buffer at R_NBYTES. */ +gpg_error_t +b64dec_proc (struct b64state *state, void *buffer, size_t length, + size_t *r_nbytes) +{ + enum decoder_states ds = state->idx; + unsigned char val = state->radbuf[0]; + int pos = state->quad_count; + char *d, *s; + + if (state->stop_seen) + { + *r_nbytes = 0; + return gpg_error (GPG_ERR_EOF); + } + + for (s=d=buffer; length && !state->stop_seen; length--, s++) + { + switch (ds) + { + case s_idle: + if (*s == '\n') + { + ds = s_lfseen; + pos = 0; + } + break; + case s_init: + ds = s_lfseen; + case s_lfseen: + if (*s != "-----BEGIN "[pos]) + ds = s_idle; + else if (pos == 10) + ds = s_begin; + else + pos++; + break; + case s_begin: + if (*s == '\n') + ds = s_b64_0; + break; + case s_b64_0: + case s_b64_1: + case s_b64_2: + case s_b64_3: + { + int c; + + if (*s == '-' && state->title) + { + /* Not a valid Base64 character: assume end + header. */ + ds = s_waitend; + } + else if (*s == '=') + { + /* Pad character: stop */ + if (ds == s_b64_1) + *d++ = val; + ds = state->title? s_waitendtitle : s_waitend; + } + else if (*s == '\n' || *s == ' ' || *s == '\r' || *s == '\t') + ; /* Skip white spaces. */ + else if ( (*s & 0x80) + || (c = asctobin[*(unsigned char *)s]) == 255) + { + /* Skip invalid encodings. */ + state->invalid_encoding = 1; + } + else if (ds == s_b64_0) + { + val = c << 2; + ds = s_b64_1; + } + else if (ds == s_b64_1) + { + val |= (c>>4)&3; + *d++ = val; + val = (c<<4)&0xf0; + ds = s_b64_2; + } + else if (ds == s_b64_2) + { + val |= (c>>2)&15; + *d++ = val; + val = (c<<6)&0xc0; + ds = s_b64_3; + } + else + { + val |= c&0x3f; + *d++ = val; + ds = s_b64_0; + } + } + break; + case s_waitendtitle: + if (*s == '-') + ds = s_waitend; + break; + case s_waitend: + if ( *s == '\n') + state->stop_seen = 1; + break; + default: + BUG(); + } + } + + + state->idx = ds; + state->radbuf[0] = val; + state->quad_count = pos; + *r_nbytes = (d -(char*) buffer); + return 0; +} + + +/* This function needs to be called before releasing the decoder + state. It may return an error code in case an encoding error has + been found during decoding. */ +gpg_error_t +b64dec_finish (struct b64state *state) +{ + xfree (state->title); + state->title = NULL; + return state->invalid_encoding? gpg_error(GPG_ERR_BAD_DATA): 0; +} + Modified: trunk/common/t-b64.c =================================================================== --- trunk/common/t-b64.c 2008-06-05 07:46:12 UTC (rev 4776) +++ trunk/common/t-b64.c 2008-06-09 14:49:28 UTC (rev 4777) @@ -65,13 +65,92 @@ } +static void +test_b64enc_file (const char *fname) +{ + gpg_error_t err; + struct b64state state; + FILE *fp; + char buffer[50]; + size_t nread; + fp = fname ? fopen (fname, "r") : stdin; + if (!fp) + { + fprintf (stderr, "%s:%d: can't open `%s': %s\n", + __FILE__, __LINE__, fname? fname:"[stdin]", strerror (errno)); + fail (0); + } + err = b64enc_start (&state, stdout, "DATA"); + if (err) + fail (1); + while ( (nread = fread (buffer, 1, sizeof buffer, fp)) ) + { + err = b64enc_write (&state, buffer, nread); + if (err) + fail (2); + } + err = b64enc_finish (&state); + if (err) + fail (3); + + fclose (fp); + pass (); +} + +static void +test_b64dec_file (const char *fname) +{ + gpg_error_t err; + struct b64state state; + FILE *fp; + char buffer[50]; + size_t nread, nbytes; + + fp = fname ? fopen (fname, "r") : stdin; + if (!fp) + { + fprintf (stderr, "%s:%d: can't open `%s': %s\n", + __FILE__, __LINE__, fname? fname:"[stdin]", strerror (errno)); + fail (0); + } + + err = b64dec_start (&state, ""); + if (err) + fail (1); + + while ( (nread = fread (buffer, 1, sizeof buffer, fp)) ) + { + err = b64dec_proc (&state, buffer, nread, &nbytes); + if (err) + { + if (gpg_err_code (err) == GPG_ERR_EOF) + break; + fail (2); + } + else if (nbytes) + fwrite (buffer, 1, nbytes, stdout); + } + + err = b64dec_finish (&state); + if (err) + fail (3); + + fclose (fp); + pass (); +} + + + int main (int argc, char **argv) { + int do_encode = 0; + int do_decode = 0; + if (argc) { argc--; argv++; } if (argc && !strcmp (argv[0], "--verbose")) @@ -80,8 +159,24 @@ argc--; argv++; } - test_b64enc_pgp (argc? *argv: NULL); + if (argc && !strcmp (argv[0], "--encode")) + { + do_encode = 1; + argc--; argv++; + } + else if (argc && !strcmp (argv[0], "--decode")) + { + do_decode = 1; + argc--; argv++; + } + if (do_encode) + test_b64enc_file (argc? *argv: NULL); + else if (do_decode) + test_b64dec_file (argc? *argv: NULL); + else + test_b64enc_pgp (argc? *argv: NULL); + return !!errcount; } Modified: trunk/common/util.h =================================================================== --- trunk/common/util.h 2008-06-05 07:46:12 UTC (rev 4776) +++ trunk/common/util.h 2008-06-09 14:49:28 UTC (rev 4777) @@ -149,7 +149,7 @@ size_t *max_length); -/*-- b64enc.c --*/ +/*-- b64enc.c and b64dec.c --*/ struct b64state { unsigned int flags; @@ -159,12 +159,23 @@ char *title; unsigned char radbuf[4]; u32 crc; + int stop_seen:1; + int invalid_encoding:1; }; + gpg_error_t b64enc_start (struct b64state *state, FILE *fp, const char *title); gpg_error_t b64enc_write (struct b64state *state, const void *buffer, size_t nbytes); gpg_error_t b64enc_finish (struct b64state *state); +gpg_error_t b64dec_start (struct b64state *state, const char *title); +gpg_error_t b64dec_proc (struct b64state *state, void *buffer, size_t length, + size_t *r_nbytes); +gpg_error_t b64dec_finish (struct b64state *state); + + + + /*-- sexputil.c */ gpg_error_t keygrip_from_canon_sexp (const unsigned char *key, size_t keylen, unsigned char *grip); From cvs at cvs.gnupg.org Tue Jun 10 12:05:21 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 10 Jun 2008 12:05:21 +0200 Subject: [svn] dirmngr - r300 - in trunk: . jnlib src Message-ID: Author: wk Date: 2008-06-10 12:05:20 +0200 (Tue, 10 Jun 2008) New Revision: 300 Added: trunk/src/b64dec.c Modified: trunk/ChangeLog trunk/NEWS trunk/configure.ac trunk/jnlib/ChangeLog trunk/jnlib/argparse.c trunk/src/ChangeLog trunk/src/Makefile.am trunk/src/crlfetch.c trunk/src/util.h Log: Support PEM encoded CRLs via HTTP. [The diff below has been truncated] Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2008-05-26 15:07:04 UTC (rev 299) +++ trunk/ChangeLog 2008-06-10 10:05:20 UTC (rev 300) @@ -1,3 +1,7 @@ +2008-04-01 Werner Koch + + * configure.ac (AC_INIT): Fix quoting. + 2008-02-21 Werner Koch * configure.ac: Check for gcry_md_debug. Modified: trunk/jnlib/ChangeLog =================================================================== --- trunk/jnlib/ChangeLog 2008-05-26 15:07:04 UTC (rev 299) +++ trunk/jnlib/ChangeLog 2008-06-10 10:05:20 UTC (rev 300) @@ -1,3 +1,7 @@ +2008-02-22 Werner Koch + + * argparse.c (strusage): Set copyright year to 2008. + 2008-02-12 Marcus Brinkmann * logging.c (do_logv): Flush the logstream. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2008-05-26 15:07:04 UTC (rev 299) +++ trunk/src/ChangeLog 2008-06-10 10:05:20 UTC (rev 300) @@ -1,3 +1,17 @@ +2008-06-10 Werner Koch + + Support PEM encoded CRLs. Fixes bug#927. + + * crlfetch.c (struct reader_cb_context_s): New. + (struct file_reader_map_s): Replace FP by new context. + (register_file_reader, get_file_reader): Adjust accordingly. + (my_es_read): Detect Base64 encoded CRL and decode if needed. + (crl_fetch): Pass new context to the callback. + (crl_close_reader): Cleanup the new context. + * b64dec.c: New. Taken from GnuPG. + * util.h (struct b64state): Add new fields STOP_SEEN and + INVALID_ENCODING. + 2008-05-26 Marcus Brinkmann * dirmngr.c (main) [HAVE_W32_SYSTEM]: Switch to system Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2008-05-26 15:07:04 UTC (rev 299) +++ trunk/NEWS 2008-06-10 10:05:20 UTC (rev 300) @@ -10,7 +10,9 @@ * Improved certificate chain construction. + * Support loading of PEM encoded CRLs via HTTP. + Noteworthy changes in version 1.0.1 (2007-08-16) ------------------------------------------------ Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2008-05-26 15:07:04 UTC (rev 299) +++ trunk/configure.ac 2008-06-10 10:05:20 UTC (rev 300) @@ -31,7 +31,8 @@ m4_define([svn_revision], m4_esyscmd([echo -n $( (svn info 2>/dev/null \ || echo 'Revision: 0')|sed -n '/^Revision:/ {s/[^0-9]//gp;q;}')])) -AC_INIT([dirmngr], my_version[]m4_if(my_issvn,[yes],[-svn[]svn_revision]), +AC_INIT([dirmngr], + [my_version[]m4_if(my_issvn,[yes],[-svn[]svn_revision])], [bug-dirmngr at gnupg.org]) NEED_GPG_ERROR_VERSION=1.4 Modified: trunk/jnlib/argparse.c =================================================================== --- trunk/jnlib/argparse.c 2008-05-26 15:07:04 UTC (rev 299) +++ trunk/jnlib/argparse.c 2008-06-10 10:05:20 UTC (rev 300) @@ -1,6 +1,6 @@ /* [argparse.c wk 17.06.97] Argument Parser for option handling * Copyright (C) 1998, 1999, 2000, 2001, 2006 - * 2007 Free Software Foundation, Inc. + * 2007, 2008 Free Software Foundation, Inc. * * This file is part of JNLIB. * @@ -936,7 +936,7 @@ switch( level ) { case 11: p = "foo"; break; case 13: p = "0.0"; break; - case 14: p = "Copyright (C) 2007 Free Software Foundation, Inc."; break; + case 14: p = "Copyright (C) 2008 Free Software Foundation, Inc."; break; case 15: p = "This program comes with ABSOLUTELY NO WARRANTY.\n" "This is free software, and you are welcome to redistribute it\n" Modified: trunk/src/Makefile.am =================================================================== --- trunk/src/Makefile.am 2008-05-26 15:07:04 UTC (rev 299) +++ trunk/src/Makefile.am 2008-06-10 10:05:20 UTC (rev 300) @@ -42,7 +42,7 @@ dirmngr_SOURCES = \ dirmngr.c dirmngr.h server.c crlcache.c crlfetch.c \ - certcache.c certcache.h i18n.h util.h \ + certcache.c certcache.h i18n.h util.h b64dec.c \ cdb.h cdblib.c ldap.c http.c http.h misc.c ocsp.c ocsp.h \ estream.c estream.h estream-printf.c estream-printf.h \ validate.c validate.h exechelp.h exechelp.c get-path.c Added: trunk/src/b64dec.c =================================================================== --- trunk/src/b64dec.c 2008-05-26 15:07:04 UTC (rev 299) +++ trunk/src/b64dec.c 2008-06-10 10:05:20 UTC (rev 300) @@ -0,0 +1,217 @@ +/* b64dec.c - Simple Base64 decoder. + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG 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 3 of the License, or + * (at your option) any later version. + * + * GnuPG 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, see . + */ + +#include +#include +#include +#include +#include +#include + +#include "i18n.h" +#include "util.h" + + +/* The reverse base-64 list used for base-64 decoding. */ +static unsigned char const asctobin[128] = + { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, + 0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff + }; + +enum decoder_states + { + s_init, s_idle, s_lfseen, s_begin, + s_b64_0, s_b64_1, s_b64_2, s_b64_3, + s_waitendtitle, s_waitend + }; + + + +/* Initialize the context for the base64 decoder. If TITLE is NULL a + plain base64 decoding is done. If it is the empty string the + decoder will skip everything until a "-----BEGIN " line has been + seen, decoding ends at a "----END " line. + + Not yet implemented: If TITLE is either "PGP" or begins with "PGP " + the PGP armor lines are skipped as well. */ +gpg_error_t +b64dec_start (struct b64state *state, const char *title) +{ + memset (state, 0, sizeof *state); + if (title) + { + if (!strncmp (title, "PGP", 3) && (!title[3] || title[3] == ' ')) + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); + + state->title = xtrystrdup (title); + if (!state->title) + return gpg_error_from_syserror (); + state->idx = s_init; + } + else + state->idx = s_b64_0; + return 0; +} + + +/* Do in-place decoding of base-64 data of LENGTH in BUFFER. Stores the + new length of the buffer at R_NBYTES. */ +gpg_error_t +b64dec_proc (struct b64state *state, void *buffer, size_t length, + size_t *r_nbytes) +{ + enum decoder_states ds = state->idx; + unsigned char val = state->radbuf[0]; + int pos = state->quad_count; + char *d, *s; + + if (state->stop_seen) + { + *r_nbytes = 0; + return gpg_error (GPG_ERR_EOF); + } + + for (s=d=buffer; length && !state->stop_seen; length--, s++) + { + switch (ds) + { + case s_idle: + if (*s == '\n') + { + ds = s_lfseen; + pos = 0; + } + break; + case s_init: + ds = s_lfseen; + case s_lfseen: + if (*s != "-----BEGIN "[pos]) + ds = s_idle; + else if (pos == 10) + ds = s_begin; + else + pos++; + break; + case s_begin: + if (*s == '\n') + ds = s_b64_0; + break; + case s_b64_0: + case s_b64_1: + case s_b64_2: + case s_b64_3: + { + int c; + + if (*s == '-' && state->title) + { + /* Not a valid Base64 character: assume end + header. */ + ds = s_waitend; + } + else if (*s == '=') + { + /* Pad character: stop */ + if (ds == s_b64_1) + *d++ = val; + ds = state->title? s_waitendtitle : s_waitend; + } + else if (*s == '\n' || *s == ' ' || *s == '\r' || *s == '\t') + ; /* Skip white spaces. */ + else if ( (*s & 0x80) + || (c = asctobin[*(unsigned char *)s]) == 255) + { + /* Skip invalid encodings. */ + state->invalid_encoding = 1; + } + else if (ds == s_b64_0) + { + val = c << 2; + ds = s_b64_1; + } + else if (ds == s_b64_1) + { + val |= (c>>4)&3; + *d++ = val; + val = (c<<4)&0xf0; + ds = s_b64_2; + } + else if (ds == s_b64_2) + { + val |= (c>>2)&15; + *d++ = val; + val = (c<<6)&0xc0; + ds = s_b64_3; + } + else + { + val |= c&0x3f; + *d++ = val; + ds = s_b64_0; + } + } + break; + case s_waitendtitle: + if (*s == '-') + ds = s_waitend; + break; + case s_waitend: + if ( *s == '\n') + state->stop_seen = 1; + break; + default: + BUG(); + } + } + + + state->idx = ds; + state->radbuf[0] = val; + state->quad_count = pos; + *r_nbytes = (d -(char*) buffer); + return 0; +} + + +/* This function needs to be called before releasing the decoder + state. It may return an error code in case an encoding error has + been found during decoding. */ +gpg_error_t +b64dec_finish (struct b64state *state) +{ + xfree (state->title); + state->title = NULL; + return state->invalid_encoding? gpg_error(GPG_ERR_BAD_DATA): 0; +} + Modified: trunk/src/crlfetch.c =================================================================== --- trunk/src/crlfetch.c 2008-05-26 15:07:04 UTC (rev 299) +++ trunk/src/crlfetch.c 2008-06-10 10:05:20 UTC (rev 300) @@ -31,12 +31,25 @@ #include "estream.h" -/* We need to associate a reader object with file streams. This table - is used for it. */ + +/* For detecting armored CRLs received via HTTP (yes, such CRLS really + exits, e.g. http://grid.fzk.de/ca/gridka-crl.pem at least in June + 2008) we need a context in the reader callback. */ +struct reader_cb_context_s +{ + estream_t fp; /* The stream used with the ksba reader. */ + int checked:1; /* PEM/binary detection ahs been done. */ + int is_pem:1; /* The file stream is PEM encoded. */ + struct b64state b64state; /* The state used for Base64 decoding. */ +}; + + +/* We need to associate a reader object with the reader callback + context. This table is used for it. */ struct file_reader_map_s { ksba_reader_t reader; - estream_t fp; + struct reader_cb_context_s *cb_ctx; }; #define MAX_FILE_READER 50 static struct file_reader_map_s file_reader_map[MAX_FILE_READER]; @@ -44,7 +57,7 @@ /* Associate FP with READER. If the table is full wait until another thread has removed an entry. */ static void -register_file_reader (ksba_reader_t reader, estream_t fp) +register_file_reader (ksba_reader_t reader, struct reader_cb_context_s *cb_ctx) { int i; @@ -54,7 +67,7 @@ if (!file_reader_map[i].reader) { file_reader_map[i].reader = reader; - file_reader_map[i].fp = fp; + file_reader_map[i].cb_ctx = cb_ctx; return; } log_info (_("reader to file mapping table full - waiting\n")); @@ -62,23 +75,23 @@ } } -/* Scan the table for an entry matching READER, emove tha entry and +/* Scan the table for an entry matching READER, remove that entry and return the associated file pointer. */ -static estream_t +static struct reader_cb_context_s * get_file_reader (ksba_reader_t reader) { - estream_t fp = NULL; + struct reader_cb_context_s *cb_ctx = NULL; int i; for (i=0; i < MAX_FILE_READER; i++) if (file_reader_map[i].reader == reader) { - fp = file_reader_map[i].fp; + cb_ctx = file_reader_map[i].cb_ctx; file_reader_map[i].reader = NULL; - file_reader_map[i].fp = NULL; + file_reader_map[i].cb_ctx = NULL; break; } - return fp; + return cb_ctx; } @@ -86,7 +99,43 @@ static int my_es_read (void *opaque, char *buffer, size_t nbytes, size_t *nread) { - return es_read (opaque, buffer, nbytes, nread); + struct reader_cb_context_s *cb_ctx = opaque; + int result; + + result = es_read (cb_ctx->fp, buffer, nbytes, nread); + if (result) + return result; + + if (!cb_ctx->checked && *nread) + { + int c = *(unsigned char *)buffer; + + cb_ctx->checked = 1; + if ( ((c & 0xc0) >> 6) == 0 /* class: universal */ + && (c & 0x1f) == 16 /* sequence */ + && (c & 0x20) /* is constructed */ ) + ; /* Binary data. */ + else + { + cb_ctx->is_pem = 1; + b64dec_start (&cb_ctx->b64state, ""); + } + } + if (cb_ctx->is_pem && *nread) + { + size_t nread2; + + if (b64dec_proc (&cb_ctx->b64state, buffer, *nread, &nread2)) + { + /* EOF from decoder. */ + *nread = 0; + result = gpg_error (GPG_ERR_EOF); + } + else + *nread = nread2; + } + + return result; } @@ -147,10 +196,18 @@ case 200: { estream_t fp = http_get_read_ptr (hd); - - err = ksba_reader_new (reader); + struct reader_cb_context_s *cb_ctx; + + cb_ctx = xtrycalloc (1, sizeof *cb_ctx); + if (!cb_ctx) + err = gpg_error_from_syserror (); if (!err) - err = ksba_reader_set_cb (*reader, &my_es_read, fp); + err = ksba_reader_new (reader); + if (!err) + { + cb_ctx->fp = fp; + err = ksba_reader_set_cb (*reader, &my_es_read, cb_ctx); + } if (err) { log_error (_("error initializing reader object: %s\n"), @@ -161,7 +218,13 @@ } else { - register_file_reader (*reader, fp); + /* The ksba reader misses a user pointer thus we need + to come up with our own way of associating a file + pointer (or well the callback context) with the + reader. It is only required when closing the + reader thus there is no performance issue doing it + this way. */ + register_file_reader (*reader, cb_ctx); http_close (hd, 1); } } @@ -384,16 +447,25 @@ void crl_close_reader (ksba_reader_t reader) { - estream_t fp; + struct reader_cb_context_s *cb_ctx; if (!reader) return; /* Check whether this is a HTTP one. */ - fp = get_file_reader (reader); - if (fp) /* This is an HTTP context. */ - es_fclose (fp); - else /* This is an ldap wrapper context. */ + cb_ctx = get_file_reader (reader); + if (cb_ctx) + { + /* This is an HTTP context. */ + if (cb_ctx->fp) + es_fclose (cb_ctx->fp); + /* Release the base64 decoder state. */ + if (cb_ctx->is_pem) + b64dec_finish (&cb_ctx->b64state); + /* Release the callback context. */ + xfree (cb_ctx); + } + else /* This is an ldap wrapper context (Currently not used). */ ldap_wrapper_release_context (reader); /* Now get rid of the reader object. */ Modified: trunk/src/util.h =================================================================== --- trunk/src/util.h 2008-05-26 15:07:04 UTC (rev 299) +++ trunk/src/util.h 2008-06-10 10:05:20 UTC (rev 300) @@ -1,5 +1,5 @@ /* util.h - * Copyright (C) 2004 g10 Code GmbH + * Copyright (C) 2004, 2008 g10 Code GmbH * * This file is part of DirMngr. * @@ -14,8 +14,7 @@ * 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 From cvs at cvs.gnupg.org Wed Jun 11 10:08:00 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 11 Jun 2008 10:08:00 +0200 Subject: [svn] GnuPG - r4778 - in trunk: . doc g10 Message-ID: Author: wk Date: 2008-06-11 10:07:54 +0200 (Wed, 11 Jun 2008) New Revision: 4778 Modified: trunk/NEWS trunk/doc/DETAILS trunk/doc/gpg.texi trunk/g10/ChangeLog trunk/g10/gpg.c trunk/g10/keyid.c trunk/g10/keylist.c trunk/g10/options.h Log: Made --fixed-list-mode obsolete. [The diff below has been truncated] Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2008-06-09 14:49:28 UTC (rev 4777) +++ trunk/g10/ChangeLog 2008-06-11 08:07:54 UTC (rev 4778) @@ -1,3 +1,13 @@ +2008-06-11 Werner Koch + + * gpg.c: Make --fixed-list-mode a dummy. + * options.h (struct): Removed FIXED_LIST_MODE. + * keyid.c (colon_strtime, colon_datestr_from_pk) + (colon_datestr_from_sk, colon_datestr_from_sig) + (colon_expirestr_from_sig): Remove fixed_list_mode case. + * keylist.c (list_keyblock_colon): Ditto. Remove all now unsed + code and reindent. + 2008-05-31 Werner Koch * keygen.c (ask_user_id): Change the string printed as header of Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2008-06-09 14:49:28 UTC (rev 4777) +++ trunk/NEWS 2008-06-11 08:07:54 UTC (rev 4778) @@ -17,7 +17,9 @@ * gpg-connect-agent accepts commands given as command line arguments. + * The gpg2 option --fixed-list-mode is now implicitly used and obsolete. + Noteworthy changes in version 2.0.9 (2008-03-26) ------------------------------------------------ Modified: trunk/doc/DETAILS =================================================================== --- trunk/doc/DETAILS 2008-06-09 14:49:28 UTC (rev 4777) +++ trunk/doc/DETAILS 2008-06-11 08:07:54 UTC (rev 4778) @@ -16,9 +16,9 @@ fpr:::::::::AB059359A3B81F410FCFF97F5CE086B5B5A18FF4: The double --with-fingerprint prints the fingerprint for the subkeys -too, --fixed-list-mode is themodern listing way printing dates in +too. --fixed-list-mode is the modern listing way printing dates in seconds since Epoch and does not merge the first userID with the pub -record. +record; gpg2 does this by default and the option is a dummy. 1. Field: Type of record Modified: trunk/doc/gpg.texi =================================================================== --- trunk/doc/gpg.texi 2008-06-09 14:49:28 UTC (rev 4777) +++ trunk/doc/gpg.texi 2008-06-11 08:07:54 UTC (rev 4778) @@ -1846,6 +1846,10 @@ @opindex fixed-list-mode Do not merge primary user ID and primary key in @option{--with-colon} listing mode and print all timestamps as seconds since 1970-01-01. + at ifclear gpgone +Since GnuPG 2.0.10, this mode is always used and thus this option is +obsolete; it does not harm to use it though. + at end ifclear @item --with-fingerprint @opindex with-fingerprint Modified: trunk/g10/gpg.c =================================================================== --- trunk/g10/gpg.c 2008-06-09 14:49:28 UTC (rev 4777) +++ trunk/g10/gpg.c 2008-06-11 08:07:54 UTC (rev 4778) @@ -2734,7 +2734,7 @@ "--keyserver-options ","http-proxy"); break; case oFastListMode: opt.fast_list_mode = 1; break; - case oFixedListMode: opt.fixed_list_mode = 1; break; + case oFixedListMode: /* Dummy */ break; case oListOnly: opt.list_only=1; break; case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break; case oIgnoreValidFrom: opt.ignore_valid_from = 1; break; Modified: trunk/g10/keyid.c =================================================================== --- trunk/g10/keyid.c 2008-06-09 14:49:28 UTC (rev 4777) +++ trunk/g10/keyid.c 2008-06-11 08:07:54 UTC (rev 4778) @@ -607,60 +607,51 @@ const char * colon_strtime (u32 t) { - if (!t) - return ""; - if (opt.fixed_list_mode) { - static char buf[15]; - sprintf (buf, "%lu", (ulong)t); - return buf; - } - return strtimestamp(t); + static char buf[20]; + + if (!t) + return ""; + snprintf (buf, sizeof buf, "%lu", (ulong)t); + return buf; } const char * colon_datestr_from_pk (PKT_public_key *pk) { - if (opt.fixed_list_mode) { - static char buf[15]; - sprintf (buf, "%lu", (ulong)pk->timestamp); - return buf; - } - return datestr_from_pk (pk); + static char buf[20]; + + snprintf (buf, sizeof buf, "%lu", (ulong)pk->timestamp); + return buf; } const char * colon_datestr_from_sk (PKT_secret_key *sk) { - if (opt.fixed_list_mode) { - static char buf[15]; - sprintf (buf, "%lu", (ulong)sk->timestamp); - return buf; - } - return datestr_from_sk (sk); + static char buf[20]; + + snprintf (buf, sizeof buf, "%lu", (ulong)sk->timestamp); + return buf; } const char * colon_datestr_from_sig (PKT_signature *sig) { - if (opt.fixed_list_mode) { - static char buf[15]; - sprintf (buf, "%lu", (ulong)sig->timestamp); - return buf; - } - return datestr_from_sig (sig); + static char buf[20]; + + snprintf (buf, sizeof buf, "%lu", (ulong)sig->timestamp); + return buf; } const char * colon_expirestr_from_sig (PKT_signature *sig) { - if(!sig->expiredate) - return ""; - if (opt.fixed_list_mode) { - static char buf[15]; - sprintf (buf, "%lu", (ulong)sig->expiredate); - return buf; - } - return expirestr_from_sig (sig); + static char buf[20]; + + if (!sig->expiredate) + return ""; + + snprintf (buf, sizeof buf,"%lu", (ulong)sig->expiredate); + return buf; } Modified: trunk/g10/keylist.c =================================================================== --- trunk/g10/keylist.c 2008-06-09 14:49:28 UTC (rev 4777) +++ trunk/g10/keylist.c 2008-06-11 08:07:54 UTC (rev 4778) @@ -1,6 +1,6 @@ /* keylist.c - print keys * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, - * 2004, 2005 Free Software Foundation, Inc. + * 2004, 2005, 2008 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -1062,367 +1062,324 @@ static void list_keyblock_colon( KBNODE keyblock, int secret, int fpr ) { - int rc = 0; - KBNODE kbctx; - KBNODE node; - PKT_public_key *pk; - PKT_secret_key *sk; - u32 keyid[2]; - int any=0; - int trustletter = 0; - int ulti_hack = 0; - int i; + int rc = 0; + KBNODE kbctx; + KBNODE node; + PKT_public_key *pk; + PKT_secret_key *sk; + u32 keyid[2]; + int trustletter = 0; + int ulti_hack = 0; + int i; - /* get the keyid from the keyblock */ - node = find_kbnode( keyblock, secret? PKT_SECRET_KEY : PKT_PUBLIC_KEY ); - if( !node ) { - log_error("Oops; key lost!\n"); - dump_kbnode( keyblock ); - return; + /* get the keyid from the keyblock */ + node = find_kbnode( keyblock, secret? PKT_SECRET_KEY : PKT_PUBLIC_KEY ); + if ( !node ) + { + log_error("Oops; key lost!\n"); + dump_kbnode( keyblock ); + return; } - if( secret ) { - pk = NULL; - sk = node->pkt->pkt.secret_key; - keyid_from_sk( sk, keyid ); - printf("sec::%u:%d:%08lX%08lX:%s:%s:::", - nbits_from_sk( sk ), - sk->pubkey_algo, - (ulong)keyid[0],(ulong)keyid[1], - colon_datestr_from_sk( sk ), - colon_strtime (sk->expiredate) - /* fixme: add LID here */ ); + if ( secret ) + { + pk = NULL; + sk = node->pkt->pkt.secret_key; + keyid_from_sk ( sk, keyid ); + printf ("sec::%u:%d:%08lX%08lX:%s:%s:::", + nbits_from_sk( sk ), + sk->pubkey_algo, + (ulong)keyid[0],(ulong)keyid[1], + colon_datestr_from_sk( sk ), + colon_strtime (sk->expiredate) + /* fixme: add LID here */ ); } - else { - pk = node->pkt->pkt.public_key; - sk = NULL; - keyid_from_pk( pk, keyid ); - fputs( "pub:", stdout ); - if ( !pk->is_valid ) + else + { + pk = node->pkt->pkt.public_key; + sk = NULL; + keyid_from_pk( pk, keyid ); + fputs( "pub:", stdout ); + if ( !pk->is_valid ) + putchar ('i'); + else if ( pk->is_revoked ) + putchar ('r'); + else if ( pk->has_expired ) + putchar ('e'); + else if ( opt.fast_list_mode || opt.no_expensive_trust_checks ) + ; + else + { + trustletter = get_validity_info ( pk, NULL ); + if ( trustletter == 'u' ) + ulti_hack = 1; + putchar(trustletter); + } + printf (":%u:%d:%08lX%08lX:%s:%s::", + nbits_from_pk( pk ), + pk->pubkey_algo, + (ulong)keyid[0],(ulong)keyid[1], + colon_datestr_from_pk( pk ), + colon_strtime (pk->expiredate) ); + if ( !opt.fast_list_mode && !opt.no_expensive_trust_checks ) + putchar( get_ownertrust_info(pk) ); + putchar(':'); + } + + putchar (':'); + putchar (':'); + print_capabilities (pk, sk, keyblock); + if (secret) + { + putchar (':'); /* End of field 13. */ + putchar (':'); /* End of field 14. */ + if (sk->protect.s2k.mode == 1001) + putchar ('#'); /* Key is just a stub. */ + else if (sk->protect.s2k.mode == 1002) + { + /* Key is stored on an external token (card) or handled by + the gpg-agent. Print the serial number of that token + here. */ + for (i=0; i < sk->protect.ivlen; i++) + printf ("%02X", sk->protect.iv[i]); + } + putchar (':'); /* End of field 15. */ + } + putchar('\n'); + if (pk) + print_revokers (pk); + if (fpr) + print_fingerprint (pk, sk, 0); + if (opt.with_key_data) + print_key_data (pk); + + + for ( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) + { + if ( node->pkt->pkttype == PKT_USER_ID && !opt.fast_list_mode ) + { + char *str; + PKT_user_id *uid=node->pkt->pkt.user_id; + + if (attrib_fp && node->pkt->pkt.user_id->attrib_data != NULL) + dump_attribs (node->pkt->pkt.user_id,pk,sk); + /* + * Fixme: We need a is_valid flag here too + */ + str = uid->attrib_data? "uat":"uid"; + /* If we're listing a secret key, leave out the validity + values for now. This is handled better in 1.9. */ + if (sk) + printf ("%s:::::",str); + else if ( uid->is_revoked ) + printf ("%s:r::::",str); + else if ( uid->is_expired ) + printf ("%s:e::::",str); + else if ( opt.no_expensive_trust_checks ) + printf ("%s:::::",str); + else + { + int uid_validity; + + if ( pk && !ulti_hack ) + uid_validity=get_validity_info (pk, uid); + else + uid_validity = 'u'; + printf ("%s:%c::::",str,uid_validity); + } + + printf ("%s:", colon_strtime (uid->created)); + printf ("%s:", colon_strtime (uid->expiredate)); + + namehash_from_uid (uid); + + for (i=0; i < 20; i++ ) + printf ("%02X",uid->namehash[i]); + + printf ("::"); + + if (uid->attrib_data) + printf ("%u %lu",uid->numattribs,uid->attrib_len); + else + print_string (stdout,uid->name,uid->len, ':' ); + putchar (':'); + putchar ('\n'); + } + else if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) + { + u32 keyid2[2]; + PKT_public_key *pk2 = node->pkt->pkt.public_key; + + keyid_from_pk ( pk2, keyid2 ); + fputs ("sub:", stdout ); + if ( !pk2->is_valid ) putchar ('i'); - else if ( pk->is_revoked ) + else if ( pk2->is_revoked ) putchar ('r'); - else if ( pk->has_expired ) + else if ( pk2->has_expired ) putchar ('e'); - else if ( opt.fast_list_mode || opt.no_expensive_trust_checks ) + else if ( opt.fast_list_mode || opt.no_expensive_trust_checks ) ; - else { - trustletter = get_validity_info ( pk, NULL ); - if( trustletter == 'u' ) - ulti_hack = 1; - putchar(trustletter); + else + { + /* TRUSTLETTER should always be defined here. */ + if (trustletter) + printf ("%c", trustletter ); + } + printf(":%u:%d:%08lX%08lX:%s:%s:::::", + nbits_from_pk( pk2 ), + pk2->pubkey_algo, + (ulong)keyid2[0],(ulong)keyid2[1], + colon_datestr_from_pk( pk2 ), + colon_strtime (pk2->expiredate) + /* fixme: add LID and ownertrust here */ + ); + print_capabilities (pk2, NULL, NULL); + putchar ('\n'); + if ( fpr > 1 ) + print_fingerprint ( pk2, NULL, 0 ); + if ( opt.with_key_data ) + print_key_data( pk2 ); } - printf(":%u:%d:%08lX%08lX:%s:%s::", - nbits_from_pk( pk ), - pk->pubkey_algo, - (ulong)keyid[0],(ulong)keyid[1], - colon_datestr_from_pk( pk ), - colon_strtime (pk->expiredate) ); - if( !opt.fast_list_mode && !opt.no_expensive_trust_checks ) - putchar( get_ownertrust_info(pk) ); - putchar(':'); - } + else if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) + { + u32 keyid2[2]; + PKT_secret_key *sk2 = node->pkt->pkt.secret_key; - if (opt.fixed_list_mode) { - /* do not merge the first uid with the primary key */ - putchar(':'); - putchar(':'); - print_capabilities (pk, sk, keyblock); - if (secret) { + keyid_from_sk ( sk2, keyid2 ); + printf ("ssb::%u:%d:%08lX%08lX:%s:%s:::::", + nbits_from_sk( sk2 ), + sk2->pubkey_algo, + (ulong)keyid2[0],(ulong)keyid2[1], + colon_datestr_from_sk( sk2 ), + colon_strtime (sk2->expiredate) + /* fixme: add LID */ ); + print_capabilities (NULL, sk2, NULL); putchar(':'); /* End of field 13. */ putchar(':'); /* End of field 14. */ - if (sk->protect.s2k.mode == 1001) - putchar('#'); /* Key is just a stub. */ - else if (sk->protect.s2k.mode == 1002) { - /* Key is stored on an external token (card) or handled by - the gpg-agent. Print the serial number of that token - here. */ - for (i=0; i < sk->protect.ivlen; i++) - printf ("%02X", sk->protect.iv[i]); - } + if (sk2->protect.s2k.mode == 1001) + putchar ('#'); /* Key is just a stub. */ + else if (sk2->protect.s2k.mode == 1002) + { + /* Key is stored on an external token (card) or handled by + the gpg-agent. Print the serial number of that token + here. */ + for (i=0; i < sk2->protect.ivlen; i++) + printf ("%02X", sk2->protect.iv[i]); + } putchar(':'); /* End of field 15. */ + putchar ('\n'); + + if ( fpr > 1 ) + print_fingerprint ( NULL, sk2, 0 ); } - putchar('\n'); - if(pk) - print_revokers(pk); - if( fpr ) - print_fingerprint( pk, sk, 0 ); - if( opt.with_key_data ) - print_key_data( pk ); - any = 1; - } + else if ( opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE ) + { + PKT_signature *sig = node->pkt->pkt.signature; + int sigrc,fprokay=0; + char *sigstr; + size_t fplen; + byte fparray[MAX_FINGERPRINT_LEN]; + + if ( sig->sig_class == 0x20 || sig->sig_class == 0x28 + || sig->sig_class == 0x30 ) + sigstr = "rev"; + else if ( (sig->sig_class&~3) == 0x10 ) + sigstr = "sig"; + else if ( sig->sig_class == 0x18 ) + sigstr = "sig"; + else if ( sig->sig_class == 0x1F ) + sigstr = "sig"; + else + { + printf ("sig::::::::::%02x%c:\n", + sig->sig_class, sig->flags.exportable?'x':'l'); + continue; + } - for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 0)) ; ) { - if( node->pkt->pkttype == PKT_USER_ID && !opt.fast_list_mode ) { - PKT_user_id *uid=node->pkt->pkt.user_id; - if(attrib_fp && node->pkt->pkt.user_id->attrib_data!=NULL) - dump_attribs(node->pkt->pkt.user_id,pk,sk); - /* - * Fixme: We need a is_valid flag here too - */ - if( any ) { - char *str=uid->attrib_data?"uat":"uid"; - /* If we're listing a secret key, leave out the - validity values for now. This is handled better in - 1.9. */ - if ( sk ) - printf("%s:::::",str); - else if ( uid->is_revoked ) - printf("%s:r::::",str); - else if ( uid->is_expired ) - printf("%s:e::::",str); - else if ( opt.no_expensive_trust_checks ) - printf("%s:::::",str); From cvs at cvs.gnupg.org Wed Jun 11 18:35:05 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 11 Jun 2008 18:35:05 +0200 Subject: [svn] GnuPG - r4779 - trunk/jnlib Message-ID: Author: wk Date: 2008-06-11 18:35:03 +0200 (Wed, 11 Jun 2008) New Revision: 4779 Modified: trunk/jnlib/ChangeLog trunk/jnlib/utf8conv.c Log: Removed unused variable. Modified: trunk/jnlib/ChangeLog =================================================================== --- trunk/jnlib/ChangeLog 2008-06-11 08:07:54 UTC (rev 4778) +++ trunk/jnlib/ChangeLog 2008-06-11 16:35:03 UTC (rev 4779) @@ -1,3 +1,8 @@ +2008-06-11 Werner Koch + + * utf8conv.c: Remove useless variable ACTIVE_CHARSET. Suggested + by Petr Uzel. + 2008-05-26 Werner Koch * argparse.c (usage): Make sure to print a trailing LF for usage(1). Modified: trunk/jnlib/utf8conv.c =================================================================== --- trunk/jnlib/utf8conv.c 2008-06-11 08:07:54 UTC (rev 4778) +++ trunk/jnlib/utf8conv.c 2008-06-11 16:35:03 UTC (rev 4779) @@ -1,6 +1,6 @@ /* utf8conf.c - UTF8 character set conversion * Copyright (C) 1994, 1998, 1999, 2000, 2001, - * 2003, 2006 Free Software Foundation, Inc. + * 2003, 2006, 2008 Free Software Foundation, Inc. * * This file is part of JNLIB. * @@ -41,7 +41,6 @@ #endif static const char *active_charset_name = "iso-8859-1"; -static unsigned short *active_charset; static int no_translation; /* Set to true if we let simply pass through. */ static int use_iconv; /* iconv comversion fucntions required. */ @@ -142,7 +141,6 @@ default. */ active_charset_name = "iso-8859-1"; no_translation = 0; - active_charset = NULL; use_iconv = 0; } } @@ -262,7 +260,6 @@ { active_charset_name = "iso-8859-1"; no_translation = 0; - active_charset = NULL; use_iconv = 0; } else if ( !ascii_strcasecmp (newset, "utf8" ) @@ -270,7 +267,6 @@ { active_charset_name = "utf-8"; no_translation = 1; - active_charset = NULL; use_iconv = 0; } else @@ -298,7 +294,6 @@ iconv_close (cd); active_charset_name = full_newset; no_translation = 0; - active_charset = NULL; use_iconv = 1; } return 0; @@ -334,7 +329,7 @@ /* Already utf-8 encoded. */ buffer = jnlib_xstrdup (orig_string); } - else if (!active_charset && !use_iconv) + else if (!use_iconv) { /* For Latin-1 we can avoid the iconv overhead. */ for (s = string; *s; s++) From cvs at cvs.gnupg.org Thu Jun 12 09:32:14 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 12 Jun 2008 09:32:14 +0200 Subject: [svn] GpgOL - r257 - trunk/src Message-ID: Author: wk Date: 2008-06-12 09:32:09 +0200 (Thu, 12 Jun 2008) New Revision: 257 Modified: trunk/src/ChangeLog trunk/src/olflange.cpp Log: Remove CLSID Registry key. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2008-06-05 10:38:03 UTC (rev 256) +++ trunk/src/ChangeLog 2008-06-12 07:32:09 UTC (rev 257) @@ -1,3 +1,7 @@ +2008-06-12 Werner Koch + + * olflange.cpp (DllUnregisterServer): Delete CLSIDs. + 2008-06-05 Werner Koch * mimeparser.c (mime_decrypt): Set session number and title. Modified: trunk/src/olflange.cpp =================================================================== --- trunk/src/olflange.cpp 2008-06-05 10:38:03 UTC (rev 256) +++ trunk/src/olflange.cpp 2008-06-12 07:32:09 UTC (rev 257) @@ -250,12 +250,12 @@ DllUnregisterServer (void) { HKEY hkey; - CHAR buf[512]; + CHAR buf[MAX_PATH+1024]; DWORD ntemp; long res; strcpy (buf, "Software\\Microsoft\\Exchange\\Client\\Extensions"); - /* create and open key and subkey */ + /* Create and open key and subkey. */ res = RegCreateKeyEx (HKEY_LOCAL_MACHINE, buf, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, NULL); @@ -266,14 +266,18 @@ } RegDeleteValue (hkey, "GpgOL"); - /* set outlook update flag */ + /* Set outlook update flag. */ strcpy (buf, "4.0;Outxxx.dll;7;000000000000000;0000000000;OutXXX"); ntemp = strlen (buf) + 1; RegSetValueEx (hkey, "Outlook Setup Extension", 0, REG_SZ, (BYTE*) buf, ntemp); RegCloseKey (hkey); - /* Fixme: delet CLSIDs. */ + /* Delete CLSIDs. */ + strcpy (buf, "CLSID\\" CLSIDSTR_GPGOL "\\InprocServer32"); + RegDeleteKey (HKEY_CLASSES_ROOT, buf); + strcpy (buf, "CLSID\\" CLSIDSTR_GPGOL); + RegDeleteKey (HKEY_CLASSES_ROOT, buf); return S_OK; } From cvs at cvs.gnupg.org Thu Jun 12 16:22:47 2008 From: cvs at cvs.gnupg.org (svn author marcus) Date: Thu, 12 Jun 2008 16:22:47 +0200 Subject: [svn] dirmngr - r301 - trunk/src Message-ID: Author: marcus Date: 2008-06-12 16:22:42 +0200 (Thu, 12 Jun 2008) New Revision: 301 Added: trunk/src/ldapserver.c trunk/src/ldapserver.h Modified: trunk/src/ChangeLog trunk/src/Makefile.am trunk/src/dirmngr.c trunk/src/dirmngr.h trunk/src/ldap.c trunk/src/server.c Log: 2008-06-12 Marcus Brinkmann * Makefile.am (dirmngr_SOURCES): Add ldapserver.h and ldapserver.c. * ldapserver.h, ldapserver.c: New files. * ldap.c: Include "ldapserver.h". (url_fetch_ldap): Use iterator to get session servers as well. (attr_fetch_ldap, start_default_fetch_ldap): Likewise. * dirmngr.c: Include "ldapserver.h". (free_ldapservers_list): Removed. Change callers to ldapserver_list_free. (parse_ldapserver_file): Use ldapserver_parse_one. * server.c: Include "ldapserver.h". (cmd_ldapserver): New command. (register_commands): Add new command LDAPSERVER. (reset_notify): New function. (start_command_handler): Register reset notify handler. Deallocate session server list. (lookup_cert_by_pattern): Use iterator to get session servers as well. (struct server_local_s): Move to ... * dirmngr.h (struct server_local_s): ... here. Add new member ldapservers. [The diff below has been truncated] Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2008-06-10 10:05:20 UTC (rev 300) +++ trunk/src/ChangeLog 2008-06-12 14:22:42 UTC (rev 301) @@ -1,3 +1,25 @@ +2008-06-12 Marcus Brinkmann + + * Makefile.am (dirmngr_SOURCES): Add ldapserver.h and ldapserver.c. + * ldapserver.h, ldapserver.c: New files. + * ldap.c: Include "ldapserver.h". + (url_fetch_ldap): Use iterator to get session servers as well. + (attr_fetch_ldap, start_default_fetch_ldap): Likewise. + * dirmngr.c: Include "ldapserver.h". + (free_ldapservers_list): Removed. Change callers to + ldapserver_list_free. + (parse_ldapserver_file): Use ldapserver_parse_one. + * server.c: Include "ldapserver.h". + (cmd_ldapserver): New command. + (register_commands): Add new command LDAPSERVER. + (reset_notify): New function. + (start_command_handler): Register reset notify handler. + Deallocate session server list. + (lookup_cert_by_pattern): Use iterator to get session servers as well. + (struct server_local_s): Move to ... + * dirmngr.h (struct server_local_s): ... here. Add new member + ldapservers. + 2008-06-10 Werner Koch Support PEM encoded CRLs. Fixes bug#927. Modified: trunk/src/Makefile.am =================================================================== --- trunk/src/Makefile.am 2008-06-10 10:05:20 UTC (rev 300) +++ trunk/src/Makefile.am 2008-06-12 14:22:42 UTC (rev 301) @@ -40,12 +40,12 @@ noinst_HEADERS = dirmngr.h crlcache.h crlfetch.h error.h misc.h -dirmngr_SOURCES = \ - dirmngr.c dirmngr.h server.c crlcache.c crlfetch.c \ - certcache.c certcache.h i18n.h util.h b64dec.c \ - cdb.h cdblib.c ldap.c http.c http.h misc.c ocsp.c ocsp.h \ - estream.c estream.h estream-printf.c estream-printf.h \ - validate.c validate.h exechelp.h exechelp.c get-path.c +dirmngr_SOURCES = dirmngr.c dirmngr.h server.c crlcache.c crlfetch.c \ + ldapserver.h ldapserver.c certcache.c certcache.h i18n.h \ + util.h b64dec.c cdb.h cdblib.c ldap.c http.c http.h misc.c \ + ocsp.c ocsp.h estream.c estream.h estream-printf.c \ + estream-printf.h validate.c validate.h exechelp.h exechelp.c \ + get-path.c dirmngr_LDADD = ../jnlib/libjnlib.a $(LIBOBJS) $(LIBASSUAN_PTH_LIBS) \ $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(PTH_LIBS) $(LIBINTL) $(LIBICONV) Modified: trunk/src/dirmngr.c =================================================================== --- trunk/src/dirmngr.c 2008-06-10 10:05:20 UTC (rev 300) +++ trunk/src/dirmngr.c 2008-06-12 14:22:42 UTC (rev 301) @@ -51,6 +51,7 @@ #include "crlfetch.h" #include "misc.h" #include "i18n.h" +#include "ldapserver.h" #ifdef HAVE_W32_SYSTEM #define sleep _sleep @@ -241,7 +242,6 @@ /* Prototypes. */ static void cleanup (void); static ldap_server_t parse_ldapserver_file (const char* filename); -static void free_ldapservers_list (ldap_server_t servers); static fingerprint_list_t parse_ocsp_signer (const char *string); static void handle_connections (assuan_fd_t listen_fd); @@ -1282,7 +1282,7 @@ crl_cache_deinit (); cert_cache_deinit (1); - free_ldapservers_list (opt.ldapservers); + ldapserver_list_free (opt.ldapservers); opt.ldapservers = NULL; if (cleanup_socket) @@ -1329,12 +1329,11 @@ parse_ldapserver_file (const char* filename) { char buffer[1024]; - char *p, *endp; + char *p; ldap_server_t server, serverstart, *serverend; int c; unsigned int lineno = 0; FILE *fp; - int fieldno; fp = fopen (filename, "r"); if (!fp) @@ -1347,8 +1346,6 @@ serverend = &serverstart; while (fgets (buffer, sizeof buffer, fp)) { - int fail = 0; - lineno++; if (!*buffer || buffer[strlen(buffer)-1] != '\n') { @@ -1370,65 +1367,9 @@ continue; /* Parse the colon separated fields. */ - server = xcalloc (1, sizeof *server); - for (fieldno=1, p = buffer; p; p = endp, fieldno++ ) + server = ldapserver_parse_one (buffer, filename, lineno); + if (server) { - endp = strchr (p, ':'); - if (endp) - *endp++ = '\0'; - trim_spaces (p); - switch (fieldno) - { - case 1: - if (*p) - server->host = xstrdup (p); - else - { - log_error (_("%s:%u: no hostname given\n"), - filename, lineno); - fail = 1; - } - break; - - case 2: - if (*p) - server->port = atoi (p); - break; - - case 3: - if (*p) - server->user = xstrdup (p); - break; - - case 4: - if (*p && !server->user) - { - log_error (_("%s:%u: password given without user\n"), - filename, lineno); - fail = 1; - } - else if (*p) - server->pass = xstrdup (p); - break; - - case 5: - if (*p) - server->base = xstrdup (p); - break; - - default: - /* (We silently ignore extra fields.) */ - break; - } - } - - if (fail) - { - log_info (_("%s:%u: skipping this line\n"), filename, lineno); - free_ldapservers_list (server); - } - else - { *serverend = server; serverend = &server->next; } @@ -1442,26 +1383,6 @@ } -/* Release the list of SERVERS. As usual it is okay to call this - fucntion with SERVERS passed as NULL. */ -static void -free_ldapservers_list (ldap_server_t servers) -{ - while (servers) - { - ldap_server_t tmp = servers->next; - xfree (servers->host); - xfree (servers->user); - if (servers->pass) - memset (servers->pass, 0, strlen (servers->pass)); - xfree (servers->pass); - xfree (servers->base); - xfree (servers); - servers = tmp; - } -} - - static fingerprint_list_t parse_ocsp_signer (const char *string) { Modified: trunk/src/dirmngr.h =================================================================== --- trunk/src/dirmngr.h 2008-06-10 10:05:20 UTC (rev 300) +++ trunk/src/dirmngr.h 2008-06-12 14:22:42 UTC (rev 301) @@ -145,8 +145,16 @@ /* Control structure per connection. */ -struct server_local_s; +struct server_local_s +{ + /* Data used to associate an Assuan context with local server data */ + assuan_context_t assuan_ctx; + /* Per-session LDAP serfver. */ + ldap_server_t ldapservers; +}; + + struct server_control_s { int refcount; /* Count additional references to this object. */ Modified: trunk/src/ldap.c =================================================================== --- trunk/src/ldap.c 2008-06-10 10:05:20 UTC (rev 300) +++ trunk/src/ldap.c 2008-06-12 14:22:42 UTC (rev 301) @@ -34,6 +34,7 @@ #include "exechelp.h" #include "crlfetch.h" #include "dirmngr.h" +#include "ldapserver.h" #include "misc.h" #ifdef HAVE_W32_SYSTEM @@ -820,14 +821,18 @@ again using our default list of servers. */ if (err && !(opt.ldap_proxy && opt.only_ldap_proxy)) { - ldap_server_t server; + struct ldapserver_iter iter; if (DBG_LOOKUP) log_debug ("no hostname in URL or query failed; " "trying all default hostnames\n"); - for (server = opt.ldapservers; err && server; server = server->next) + for (ldapserver_iter_begin (&iter, ctrl); + err && ! ldapserver_iter_end_p (&iter); + ldapserver_iter_next (&iter)) { + ldap_server_t server = iter.server; + err = run_ldap_wrapper (ctrl, 0, 0, @@ -852,15 +857,18 @@ attr_fetch_ldap (ctrl_t ctrl, const char *dn, const char *attr, ksba_reader_t *reader) { - struct ldap_server_s *server; gpg_error_t err = gpg_error (GPG_ERR_CONFIGURATION); + struct ldapserver_iter iter; *reader = NULL; /* FIXME; we might want to look at the Base SN to try matching servers first. */ - for (server = opt.ldapservers; server; server = server->next) + for (ldapserver_iter_begin (&iter, ctrl); ! ldapserver_iter_end_p (&iter); + ldapserver_iter_next (&iter)) { + ldap_server_t server = iter.server; + err = run_ldap_wrapper (ctrl, 0, 0, @@ -875,12 +883,7 @@ return err; } - - - - - /* Parse PATTERN and return a new strlist to be used for the actual LDAP query. Bit 0 of the flags field is set if that pattern is actually a base specification. Caller must release the returned @@ -1051,14 +1054,14 @@ /* Prepare an LDAP query to return the attribute ATTR for the DN. All - vonfigured default servers are queried until one responds. This + configured default servers are queried until one responds. This function returns an error code or 0 and a CONTEXT on success. */ gpg_error_t start_default_fetch_ldap (ctrl_t ctrl, cert_fetch_context_t *context, const char *dn, const char *attr) { gpg_error_t err; - struct ldap_server_s *server; + struct ldapserver_iter iter; *context = xtrycalloc (1, sizeof **context); if (!*context) @@ -1067,8 +1070,12 @@ /* FIXME; we might want to look at the Base SN to try matching servers first. */ err = gpg_error (GPG_ERR_CONFIGURATION); - for (server = opt.ldapservers; server; server = server->next) + + for (ldapserver_iter_begin (&iter, ctrl); ! ldapserver_iter_end_p (&iter); + ldapserver_iter_next (&iter)) { + ldap_server_t server = iter.server; + err = run_ldap_wrapper (ctrl, 0, 1, Added: trunk/src/ldapserver.c =================================================================== --- trunk/src/ldapserver.c 2008-06-10 10:05:20 UTC (rev 300) +++ trunk/src/ldapserver.c 2008-06-12 14:22:42 UTC (rev 301) @@ -0,0 +1,133 @@ +/* dirmngr.c - LDAP access + Copyright (C) 2008 g10 Code GmbH + + This file is part of DirMngr. + + DirMngr 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. + + DirMngr 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., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "util.h" +#include "ldapserver.h" + + +/* Release the list of SERVERS. As usual it is okay to call this + function with SERVERS passed as NULL. */ +void +ldapserver_list_free (ldap_server_t servers) +{ + while (servers) + { + ldap_server_t tmp = servers->next; + xfree (servers->host); + xfree (servers->user); + if (servers->pass) + memset (servers->pass, 0, strlen (servers->pass)); + xfree (servers->pass); + xfree (servers->base); + xfree (servers); + servers = tmp; + } +} + + +/* Parse a single LDAP server configuration line. Returns the server + or NULL in case of errors. The configuration lineis assumed to be + colon seprated with these fields: + + 1. field: Hostname + 2. field: Portnumber + 3. field: Username + 4. field: Password + 5. field: Base DN + + FILENAME and LINENO are used for diagnostic purposes only. +*/ +ldap_server_t +ldapserver_parse_one (char *line, + const char *filename, unsigned int lineno) +{ + char *p; + char *endp; + ldap_server_t server; + int fieldno; + int fail = 0; + + /* Parse the colon separated fields. */ + server = xcalloc (1, sizeof *server); + for (fieldno = 1, p = line; p; p = endp, fieldno++ ) + { + endp = strchr (p, ':'); + if (endp) + *endp++ = '\0'; + trim_spaces (p); + switch (fieldno) + { + case 1: + if (*p) + server->host = xstrdup (p); + else + { + log_error (_("%s:%u: no hostname given\n"), + filename, lineno); + fail = 1; + } + break; + + case 2: + if (*p) + server->port = atoi (p); + break; + + case 3: + if (*p) + server->user = xstrdup (p); + break; + + case 4: + if (*p && !server->user) + { + log_error (_("%s:%u: password given without user\n"), + filename, lineno); + fail = 1; + } + else if (*p) + server->pass = xstrdup (p); + break; + + case 5: + if (*p) + server->base = xstrdup (p); + break; + + default: + /* (We silently ignore extra fields.) */ + break; + } + } + + if (fail) + { + log_info (_("%s:%u: skipping this line\n"), filename, lineno); + ldapserver_list_free (server); + } + + return server; +} + + Added: trunk/src/ldapserver.h =================================================================== --- trunk/src/ldapserver.h 2008-06-10 10:05:20 UTC (rev 300) +++ trunk/src/ldapserver.h 2008-06-12 14:22:42 UTC (rev 301) @@ -0,0 +1,90 @@ +/* ldapserver.h + Copyright (C) 2008 g10 Code GmbH + + This file is part of DirMngr. + + DirMngr 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. + + DirMngr 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, see . */ + +#ifndef LDAPSERVER_H +#define LDAPSERVER_H + +#include "dirmngr.h" + +/* Release the list of SERVERS. As usual it is okay to call this + function with SERVERS passed as NULL. */ +void ldapserver_list_free (ldap_server_t servers); + + +/* Parse a single LDAP server configuration line. Returns the server + or NULL in case of errors. The configuration lineis assumed to be + colon seprated with these fields: + + 1. field: Hostname + 2. field: Portnumber + 3. field: Username + 4. field: Password + 5. field: Base DN + + FILENAME and LINENO are used for diagnostic purposes only. +*/ +ldap_server_t ldapserver_parse_one (char *line, + const char *filename, unsigned int lineno); + + +/* Iterate over all servers. */ + +struct ldapserver_iter +{ + ctrl_t ctrl; + enum { LDAPSERVER_SESSION, LDAPSERVER_OPT } group; + ldap_server_t server; +}; + + +static inline void +ldapserver_iter_next (struct ldapserver_iter *iter) +{ + if (iter->server) + iter->server = iter->server->next; + + if (! iter->server) + { From cvs at cvs.gnupg.org Thu Jun 12 16:24:50 2008 From: cvs at cvs.gnupg.org (svn author marcus) Date: Thu, 12 Jun 2008 16:24:50 +0200 Subject: [svn] GnuPG - r4780 - in trunk: sm tools Message-ID: Author: marcus Date: 2008-06-12 16:24:46 +0200 (Thu, 12 Jun 2008) New Revision: 4780 Modified: trunk/sm/ChangeLog trunk/sm/call-dirmngr.c trunk/sm/gpgsm.c trunk/sm/gpgsm.h trunk/tools/ChangeLog trunk/tools/gpgconf-comp.c Log: sm/ 2008-06-12 Marcus Brinkmann * gpgsm.h (struct keyserver_spec): New struct. (opt): Add member keyserver. * gpgsm.c (keyserver_list_free, parse_keyserver_line): New functions. (main): Implement --keyserver option. * call-dirmngr.c (prepare_dirmngr): Send LDAPSERVER commands. tools/ 2008-06-12 Marcus Brinkmann * gpgconf-comp.c (gc_options_gpgsm): Add option keyserver. Modified: trunk/sm/ChangeLog =================================================================== --- trunk/sm/ChangeLog 2008-06-11 16:35:03 UTC (rev 4779) +++ trunk/sm/ChangeLog 2008-06-12 14:24:46 UTC (rev 4780) @@ -1,3 +1,11 @@ +2008-06-12 Marcus Brinkmann + + * gpgsm.h (struct keyserver_spec): New struct. + (opt): Add member keyserver. + * gpgsm.c (keyserver_list_free, parse_keyserver_line): New functions. + (main): Implement --keyserver option. + * call-dirmngr.c (prepare_dirmngr): Send LDAPSERVER commands. + 2008-05-20 Werner Koch * gpgsm.c (main) : Pass FP and not stdout to Modified: trunk/tools/ChangeLog =================================================================== --- trunk/tools/ChangeLog 2008-06-11 16:35:03 UTC (rev 4779) +++ trunk/tools/ChangeLog 2008-06-12 14:24:46 UTC (rev 4780) @@ -1,3 +1,7 @@ +2008-06-12 Marcus Brinkmann + + * gpgconf-comp.c (gc_options_gpgsm): Add option keyserver. + 2008-05-26 Marcus Brinkmann * gpgconf-comp.c: Replace pathname by filename everywhere. Modified: trunk/sm/call-dirmngr.c =================================================================== --- trunk/sm/call-dirmngr.c 2008-06-11 16:35:03 UTC (rev 4779) +++ trunk/sm/call-dirmngr.c 2008-06-12 14:24:46 UTC (rev 4780) @@ -140,6 +140,8 @@ static void prepare_dirmngr (ctrl_t ctrl, assuan_context_t ctx, gpg_error_t err) { + struct keyserver_spec *server; + if (!ctrl->dirmngr_seen) { ctrl->dirmngr_seen = 1; @@ -152,6 +154,25 @@ } audit_log_ok (ctrl->audit, AUDIT_DIRMNGR_READY, err); } + + server = opt.keyserver; + while (server) + { + char line[ASSUAN_LINELENGTH]; + char *user = server->user ? server->user : ""; + char *pass = server->pass ? server->pass : ""; + char *base = server->base ? server->base : ""; + + snprintf (line, DIM (line) - 1, "LDAPSERVER %s:%i:%s:%s:%s", + server->host, server->port, user, pass, base); + line[DIM (line) - 1] = 0; + + err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); + if (gpg_err_code (err) == GPG_ERR_UNKNOWN_OPTION) + err = 0; /* Allow the use of old dirmngr versions. */ + + server = server->next; + } } Modified: trunk/sm/gpgsm.c =================================================================== --- trunk/sm/gpgsm.c 2008-06-11 16:35:03 UTC (rev 4779) +++ trunk/sm/gpgsm.c 2008-06-12 14:24:46 UTC (rev 4780) @@ -361,7 +361,7 @@ { oKeyring, "keyring" ,2, N_("add this keyring to the list of keyrings")}, { oSecretKeyring, "secret-keyring" ,2, N_("add this secret keyring to the list")}, { oDefaultKey, "default-key" ,2, N_("|NAME|use NAME as default secret key")}, - { oKeyServer, "keyserver",2, N_("|HOST|use this keyserver to lookup keys")}, + { oKeyServer, "keyserver",2, N_("|SPEC|use this keyserver to lookup keys")}, { oCharset, "charset" , 2, N_("|NAME|set terminal charset to NAME") }, { oOptions, "options" , 2, N_("read options from file")}, @@ -819,6 +819,99 @@ } +/* Release the list of SERVERS. As usual it is okay to call this + function with SERVERS passed as NULL. */ +void +keyserver_list_free (struct keyserver_spec *servers) +{ + while (servers) + { + struct keyserver_spec *tmp = servers->next; + xfree (servers->host); + xfree (servers->user); + if (servers->pass) + memset (servers->pass, 0, strlen (servers->pass)); + xfree (servers->pass); + xfree (servers->base); + xfree (servers); + servers = tmp; + } +} + +/* See also dirmngr ldapserver_parse_one(). */ +struct keyserver_spec * +parse_keyserver_line (char *line, + const char *filename, unsigned int lineno) +{ + char *p; + char *endp; + struct keyserver_spec *server; + int fieldno; + int fail = 0; + + /* Parse the colon separated fields. */ + server = xcalloc (1, sizeof *server); + for (fieldno = 1, p = line; p; p = endp, fieldno++ ) + { + endp = strchr (p, ':'); + if (endp) + *endp++ = '\0'; + trim_spaces (p); + switch (fieldno) + { + case 1: + if (*p) + server->host = xstrdup (p); + else + { + log_error (_("%s:%u: no hostname given\n"), + filename, lineno); + fail = 1; + } + break; + + case 2: + if (*p) + server->port = atoi (p); + break; + + case 3: + if (*p) + server->user = xstrdup (p); + break; + + case 4: + if (*p && !server->user) + { + log_error (_("%s:%u: password given without user\n"), + filename, lineno); + fail = 1; + } + else if (*p) + server->pass = xstrdup (p); + break; + + case 5: + if (*p) + server->base = xstrdup (p); + break; + + default: + /* (We silently ignore extra fields.) */ + break; + } + } + + if (fail) + { + log_info (_("%s:%u: skipping this line\n"), filename, lineno); + keyserver_list_free (server); + } + + return server; +} + + int main ( int argc, char **argv) { @@ -1317,6 +1410,24 @@ case oValidationModel: parse_validation_model (pargs.r.ret_str); break; + case oKeyServer: + { + struct keyserver_spec *keyserver; + keyserver = parse_keyserver_line (pargs.r.ret_str, + configname, configlineno); + if (! keyserver) + log_error (_("could not parse keyserver\n")); + else + { + /* FIXME: Keep last next pointer. */ + struct keyserver_spec **next_p = &opt.keyserver; + while (*next_p) + next_p = &(*next_p)->next; + *next_p = keyserver; + } + } + break; + case aDummy: break; default: @@ -1578,40 +1689,25 @@ GC_OPT_FLAG_DEFAULT, config_filename_esc); xfree (config_filename_esc); - printf ("verbose:%lu:\n" - "quiet:%lu:\n" - "debug-level:%lu:\"none:\n" - "log-file:%lu:\n", - GC_OPT_FLAG_NONE, - GC_OPT_FLAG_NONE, - GC_OPT_FLAG_DEFAULT, - GC_OPT_FLAG_NONE ); - printf ("disable-crl-checks:%lu:\n", - GC_OPT_FLAG_NONE ); - printf ("disable-trusted-cert-crl-check:%lu:\n", - GC_OPT_FLAG_NONE ); - printf ("enable-ocsp:%lu:\n", - GC_OPT_FLAG_NONE ); - printf ("include-certs:%lu:1:\n", - GC_OPT_FLAG_DEFAULT ); - printf ("disable-policy-checks:%lu:\n", - GC_OPT_FLAG_NONE ); - printf ("auto-issuer-key-retrieve:%lu:\n", - GC_OPT_FLAG_NONE ); - printf ("disable-dirmngr:%lu:\n", - GC_OPT_FLAG_NONE ); + printf ("verbose:%lu:\n", GC_OPT_FLAG_NONE); + printf ("quiet:%lu:\n", GC_OPT_FLAG_NONE); + printf ("debug-level:%lu:\"none:\n", GC_OPT_FLAG_DEFAULT); + printf ("log-file:%lu:\n", GC_OPT_FLAG_NONE); + printf ("disable-crl-checks:%lu:\n", GC_OPT_FLAG_NONE); + printf ("disable-trusted-cert-crl-check:%lu:\n", GC_OPT_FLAG_NONE); + printf ("enable-ocsp:%lu:\n", GC_OPT_FLAG_NONE); + printf ("include-certs:%lu:1:\n", GC_OPT_FLAG_DEFAULT); + printf ("disable-policy-checks:%lu:\n", GC_OPT_FLAG_NONE); + printf ("auto-issuer-key-retrieve:%lu:\n", GC_OPT_FLAG_NONE); + printf ("disable-dirmngr:%lu:\n", GC_OPT_FLAG_NONE); #ifndef HAVE_W32_SYSTEM - printf ("prefer-system-dirmngr:%lu:\n", - GC_OPT_FLAG_NONE ); + printf ("prefer-system-dirmngr:%lu:\n", GC_OPT_FLAG_NONE); #endif - printf ("cipher-algo:%lu:\"3DES:\n", - GC_OPT_FLAG_DEFAULT ); - printf ("p12-charset:%lu:\n", - GC_OPT_FLAG_DEFAULT ); - printf ("default-key:%lu:\n", - GC_OPT_FLAG_DEFAULT ); - printf ("encrypt-to:%lu:\n", - GC_OPT_FLAG_DEFAULT ); + printf ("cipher-algo:%lu:\"3DES:\n", GC_OPT_FLAG_DEFAULT); + printf ("p12-charset:%lu:\n", GC_OPT_FLAG_DEFAULT); + printf ("default-key:%lu:\n", GC_OPT_FLAG_DEFAULT); + printf ("encrypt-to:%lu:\n", GC_OPT_FLAG_DEFAULT); + printf ("keyserver:%lu:\n", GC_OPT_FLAG_NONE); } break; @@ -1883,6 +1979,8 @@ } /* cleanup */ + keyserver_list_free (opt.keyserver); + opt.keyserver = NULL; gpgsm_release_certlist (recplist); gpgsm_release_certlist (signerlist); FREE_STRLIST (remusr); Modified: trunk/sm/gpgsm.h =================================================================== --- trunk/sm/gpgsm.h 2008-06-11 16:35:03 UTC (rev 4779) +++ trunk/sm/gpgsm.h 2008-06-12 14:24:46 UTC (rev 4780) @@ -35,6 +35,18 @@ #define MAX_DIGEST_LEN 24 +struct keyserver_spec +{ + struct keyserver_spec *next; + + char *host; + int port; + char *user; + char *pass; + char *base; +}; + + /* A large struct named "opt" to keep global flags. */ struct { @@ -123,6 +135,8 @@ runtime option in case we want to check the integrity of the software at runtime. */ + + struct keyserver_spec *keyserver; } opt; Modified: trunk/tools/gpgconf-comp.c =================================================================== --- trunk/tools/gpgconf-comp.c 2008-06-11 16:35:03 UTC (rev 4779) +++ trunk/tools/gpgconf-comp.c 2008-06-12 14:24:46 UTC (rev 4780) @@ -732,6 +732,9 @@ { "p12-charset", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, "gnupg", N_("|NAME|use encoding NAME for PKCS#12 passphrases"), GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM }, + { "keyserver", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC, + "gnupg", N_("|SPEC|use this keyserver to lookup keys"), + GC_ARG_TYPE_STRING, GC_BACKEND_GPGSM }, { "Debug", GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, From cvs at cvs.gnupg.org Thu Jun 12 17:48:32 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 12 Jun 2008 17:48:32 +0200 Subject: [svn] GpgOL - r258 - in trunk: doc po src Message-ID: Author: wk Date: 2008-06-12 17:48:29 +0200 (Thu, 12 Jun 2008) New Revision: 258 Modified: trunk/doc/gpgol.texi trunk/po/de.po trunk/po/sv.po trunk/src/ChangeLog trunk/src/dialogs.h trunk/src/dialogs.rc trunk/src/engine-assuan.c trunk/src/engine-assuan.h trunk/src/engine.c trunk/src/engine.h trunk/src/mapihelp.cpp trunk/src/mapihelp.h trunk/src/mimemaker.c trunk/src/mimeparser.c trunk/src/olflange-dlgs.cpp Log: Convey from address to the UI-server. Add a Configure Engine button. [The diff below has been truncated] Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2008-06-12 07:32:09 UTC (rev 257) +++ trunk/src/ChangeLog 2008-06-12 15:48:29 UTC (rev 258) @@ -1,5 +1,18 @@ 2008-06-12 Werner Koch + * dialogs.rc: Add button for calling the engine's configuration. + * dialogs.h (IDC_GPG_CONF): New. + * engine.c (engine_start_confdialog): New. + * engine-assuan.c (op_assuan_start_confdialog): New. + * olflange-dlgs.cpp (GPGOptionsDlgProc): Act upon the button. + + * mapihelp.cpp (mapi_get_from_address): New. + * engine.c (engine_decrypt_start, engine_verify_start): Add new + arg FROM_ADDRESS. + * engine-assuan.c (op_assuan_verify, op_assuan_decrypt): Ditto. + * mimeparser.c (mime_verify, mime_verify_opaque, mime_decrypt): + Pass FROM_ADDRESS to the backend. + * olflange.cpp (DllUnregisterServer): Delete CLSIDs. 2008-06-05 Werner Koch Modified: trunk/doc/gpgol.texi =================================================================== --- trunk/doc/gpgol.texi 2008-06-12 07:32:09 UTC (rev 257) +++ trunk/doc/gpgol.texi 2008-06-12 15:48:29 UTC (rev 258) @@ -32,7 +32,7 @@ 40699 Erkrath, Germany @end iftex -Copyright @copyright{} 2007 g10 Code GmbH +Copyright @copyright{} 2007, 2008 g10 Code GmbH @quotation Permission is granted to copy, distribute and/or modify this document @@ -89,6 +89,8 @@ * Assuan Protocol:: Description of the UI server protocol. * MAPI Properties:: MAPI Properties used by GpgOL. * Registry Settings:: How GpgOL uses the Registry. +* MAPI Providers:: What MAPI Storage or Transport providers + can do to help GpgOL. Appendices @@ -330,8 +332,110 @@ @end table + at c xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + at c + at c MAPI Providers + at c + at c xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + at node MAPI Providers + at chapter What MAPI Storage or Transport providers can do to help GpgOL +GpgOL uses some tricks to make decryption of OpenPGP message better fit +into the Outlook framework. This is due to a lack of proper Plugin API +for Outllok and becuase some features of Outlook --- meant as a security +measure --- hinder a better implementation. That is not to say that +Outlook will be less secure when used with GpgOL --- to the opposite: +Due to encryption and digital signature reading and sending mail with +GpgOL support can be much more secure than using Outlook as is. +There are some points where custom MAPI storage or transport +providers can help GpgOL to gain better performance and to make it more +secure. + + at section MAPI Message Class Renaming + +To implement S/MIME processing in GpgOL and inhibit XXXXXX + + + at section MAPI Attachment Processing + +GpgOL creates a couple of attachments for the purpose of storing a +parsed mail and to allow Outlook to display attachments in the usual way +without sending them as plaintext to the storage. The attachments are +only stored on the local disk while being opened from the attachment's +context menu for viewing. Almost all these attchments are ephemeral and +may be deleted when not displayed. GpgOL re-creates them by parsing the +orginal message if neeeded. In fact they are always re-created after +Outlook as been started again. This is because the attachments holding +the plaintext are symmetrical encrypted with an ephemeral session key, +only valid as long as Outlook runs. + +TODO + + + at section MAPI PR_BODY Processing + +GPOL does not use the PR_BODY property. This is because internal +Outlook syncronisation may change that property after the plaintext of a +message has been displayed. In general this is not a problem because +the messages processed by GpgOL do not use that property (the orginal +S/MIME and PGP/MIME message is stored in attachments). However, there +is one exception: Inline PGP message (in contrast to the modern PGP/MIME +messages) are conveyed in the PR_BODY. To avoid changing that orginal +mail, GpgOL copies such a body to a new attachment named + at file{gpgolPGP.dat}, flags it as hidden and sets the attach type to +ATTACHTYPE_PGPBODY (See above under MAPI Properties). That attachment +may never be deleted! + +Due to internal OL syncronisation, plaintext data may end up in PR_BODY, +GpgOL tries hard to delete PR_BODY so that it nevers shows up in the +MAPI storage. However this is hard and here a storage provider can help +by deleting PR_BODY under one of these conditions: + + at itemize @bullet + + at item +If the message class is either @code{IPM.Note.GpgOL.MultipartEncrypted} +or @code{IPM.Note.GpgOL.OpaqueEncrypted} and in addition the message has +a property @code{GpgOL Last Decrypted} (with any value), delete the +properties @code{PR_BODY} and @code{PR_BODY_HTML}. + + at item +If the message class is @code{IPM.Note.GpgOL.PGPMessage} and an +attachment of ATTACHTYPE_PGPBODY with a filename @file{gpgolPGP.dat} +exists, delete the properties @code{PR_BODY} and @code{PR_BODY_HTML}. + + at end itemize + +Instead of deleting it should be sufficient to make sure +that such PR_BODYs are not update and don't make it to the disk or a +strage server. + +Implementing such a feature would really help with end-to-end encryption +where the security policy requires that the plaintext of an encrypted +message will never be stored on a disk or leave the local machine. + + + at section Filtering GpgOL internal properties + +To avoid attacks by importing TNEF data with certain GpgOL internal +properties, a MAPI provider may want to filter them out when receiving a +message from an external location. It is not yet clear whetehr this is +really needed. + +FIXME. + + + + + + + + + + + + @c xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx @c @c A P P E N D I X Modified: trunk/po/de.po [not shown] Modified: trunk/po/sv.po [not shown] Modified: trunk/src/dialogs.h =================================================================== --- trunk/src/dialogs.h 2008-06-12 07:32:09 UTC (rev 257) +++ trunk/src/dialogs.h 2008-06-12 15:48:29 UTC (rev 258) @@ -40,6 +40,7 @@ #define IDC_G_SEND 4024 #define IDC_G_RECV 4025 #define IDC_BODY_AS_ATTACHMENT 4026 +#define IDC_GPG_CONF 4027 /* Ids for the extended options dialog. */ Modified: trunk/src/dialogs.rc =================================================================== --- trunk/src/dialogs.rc 2008-06-12 07:32:09 UTC (rev 257) +++ trunk/src/dialogs.rc 2008-06-12 15:48:29 UTC (rev 258) @@ -97,8 +97,11 @@ 8, 212, 150, 64 PUSHBUTTON "advanced", IDC_GPG_OPTIONS, - 209, 240, 50, 14 + 130, 240, 50, 14 + PUSHBUTTON "gpgconf", IDC_GPG_CONF, + 190, 240, 70, 14 + END Modified: trunk/src/engine-assuan.c =================================================================== --- trunk/src/engine-assuan.c 2008-06-12 07:32:09 UTC (rev 257) +++ trunk/src/engine-assuan.c 2008-06-12 15:48:29 UTC (rev 258) @@ -1769,8 +1769,8 @@ /* Created a detached signature for INDATA and write it to OUTDATA. On termination of the signing command engine_private_finished() is called with FILTER as the first argument. SENDER is the sender's - mail address (a mailbox). The used protocol wioll be stored at - R_PROTOCOL. */ + mail address (a mailbox). The used protocol will be stored at + R_USED_PROTOCOL on return. */ int op_assuan_sign (protocol_t protocol, gpgme_data_t indata, gpgme_data_t outdata, @@ -1896,7 +1896,7 @@ op_assuan_decrypt (protocol_t protocol, gpgme_data_t indata, gpgme_data_t outdata, engine_filter_t filter, void *hwnd, - int with_verify) + int with_verify, const char *from_address) { gpg_error_t err; closure_data_t cld; @@ -1931,6 +1931,13 @@ goto leave; send_session_info (ctx, filter); + if (with_verify && from_address) + { + snprintf (line, sizeof line, "SENDER --info -- %s", from_address); + err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); + if (err) + goto leave; + } snprintf (line, sizeof line, "INPUT FD=%ld", (unsigned long int)inpipe[0]); err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); @@ -1996,7 +2003,7 @@ op_assuan_verify (gpgme_protocol_t protocol, gpgme_data_t msgdata, const char *signature, size_t sig_len, gpgme_data_t outdata, - engine_filter_t filter, void *hwnd) + engine_filter_t filter, void *hwnd, const char *from_address) { gpg_error_t err; closure_data_t cld = NULL; @@ -2062,6 +2069,13 @@ goto leave; send_session_info (ctx, filter); + if (from_address) + { + snprintf (line, sizeof line, "SENDER --info -- %s", from_address); + err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); + if (err) + goto leave; + } if (!opaque_mode) { @@ -2142,3 +2156,24 @@ } return err; } + + + +/* Ask the server to fire up the config dialog. */ +int +op_assuan_start_confdialog (void *hwnd) +{ + gpg_error_t err; + assuan_context_t ctx; + ULONG cmdid; + pid_t pid; + + err = connect_uiserver (&ctx, &pid, &cmdid, hwnd); + if (!err) + { + err = assuan_transact (ctx, "START_CONFDIALOG", + NULL, NULL, NULL, NULL, NULL, NULL); + assuan_disconnect (ctx); + } + return err; +} Modified: trunk/src/engine-assuan.h =================================================================== --- trunk/src/engine-assuan.h 2008-06-12 07:32:09 UTC (rev 257) +++ trunk/src/engine-assuan.h 2008-06-12 15:48:29 UTC (rev 258) @@ -51,15 +51,18 @@ int op_assuan_decrypt (protocol_t protocol, gpgme_data_t indata, gpgme_data_t outdata, engine_filter_t filter, void *hwnd, - int with_verify); + int with_verify, const char *from_address); int op_assuan_verify (gpgme_protocol_t protocol, gpgme_data_t data, const char *signature, size_t sig_len, gpgme_data_t outdata, - engine_filter_t filter, void *hwnd); + engine_filter_t filter, void *hwnd, + const char *from_address); int op_assuan_start_keymanager (void *hwnd); +int op_assuan_start_confdialog (void *hwnd); + #ifdef __cplusplus } #endif Modified: trunk/src/engine.c =================================================================== --- trunk/src/engine.c 2008-06-12 07:32:09 UTC (rev 257) +++ trunk/src/engine.c 2008-06-12 15:48:29 UTC (rev 258) @@ -924,16 +924,18 @@ finish the operation. A filter object may not be reused after having been used through this function. However, the lifetime of the filter object lasts until the final engine_wait or - engine_cancel. */ + engine_cancel. FROM_ADDRESS may be passed to allow the backend + matching the sender's address with the one in the certificate (in + case the decrypted message ncludes a signed message). */ int engine_decrypt_start (engine_filter_t filter, HWND hwnd, protocol_t protocol, - int with_verify) + int with_verify, const char *from_address) { gpg_error_t err; if (filter->use_assuan) err = op_assuan_decrypt (protocol, filter->indata, filter->outdata, - filter, hwnd, with_verify); + filter, hwnd, with_verify, from_address); else err = op_gpgme_decrypt (protocol, filter->indata, filter->outdata, filter, hwnd, with_verify); @@ -947,10 +949,13 @@ signature. The caller needs to call engine_wait to finish the operation. A filter object may not be reused after having been used through this function. However, the lifetime of the filter - object lasts until the final engine_wait or engine_cancel. */ + object lasts until the final engine_wait or engine_cancel. + FROM_ADDRESS may be passed to allow the backend matching the + sender's address with the one in the certificate. */ int engine_verify_start (engine_filter_t filter, HWND hwnd, const char *signature, - size_t sig_len, protocol_t protocol) + size_t sig_len, protocol_t protocol, + const char *from_address) { gpg_error_t err; @@ -964,10 +969,10 @@ if (filter->use_assuan && !signature) err = op_assuan_verify (protocol, filter->indata, NULL, 0, - filter->outdata, filter, hwnd); + filter->outdata, filter, hwnd, from_address); else if (filter->use_assuan) err = op_assuan_verify (protocol, filter->indata, signature, sig_len, - NULL, filter, hwnd); + NULL, filter, hwnd, from_address); else err = op_gpgme_verify (protocol, filter->indata, signature, sig_len, filter, hwnd); @@ -984,3 +989,13 @@ else return gpg_error (GPG_ERR_NOT_SUPPORTED); } + +/* Fire up the config dialog. Returns 0 on success. */ +int +engine_start_confdialog (HWND hwnd) +{ + if (use_assuan) + return op_assuan_start_confdialog (hwnd); + else + return gpg_error (GPG_ERR_NOT_SUPPORTED); +} Modified: trunk/src/engine.h =================================================================== --- trunk/src/engine.h 2008-06-12 07:32:09 UTC (rev 257) +++ trunk/src/engine.h 2008-06-12 15:48:29 UTC (rev 258) @@ -79,12 +79,15 @@ const char *sender, protocol_t *r_protocol); int engine_decrypt_start (engine_filter_t filter, HWND hwnd, - protocol_t protocol, int with_verify); + protocol_t protocol, int with_verify, + const char *from_address); int engine_verify_start (engine_filter_t filter, HWND hwnd, const char *signature, size_t sig_len, - protocol_t protocol); + protocol_t protocol, + const char *from_address); int engine_start_keymanager (HWND hwnd); +int engine_start_confdialog (HWND hwnd); Modified: trunk/src/mapihelp.cpp =================================================================== --- trunk/src/mapihelp.cpp 2008-06-12 07:32:09 UTC (rev 257) +++ trunk/src/mapihelp.cpp 2008-06-12 15:48:29 UTC (rev 258) @@ -1055,6 +1055,46 @@ return buf; } +/* Return the from address of the message as a malloced UTF-8 string. + Returns NULL if that address is not available. */ +char * +mapi_get_from_address (LPMESSAGE message) +{ + HRESULT hr; + LPSPropValue propval = NULL; + char *buf; + + if (!message) + return xstrdup ("[no message]"); /* Ooops. */ + + hr = HrGetOneProp ((LPMAPIPROP)message, PR_SENDER_EMAIL_ADDRESS_W, &propval); + if (FAILED (hr)) + { + log_debug ("%s:%s: HrGetOneProp failed: hr=%#lx\n", + SRCNAME, __func__, hr); + return NULL; + } + + if (PROP_TYPE (propval->ulPropTag) != PT_UNICODE) + { + log_debug ("%s:%s: HrGetOneProp returns invalid type %lu\n", + SRCNAME, __func__, PROP_TYPE (propval->ulPropTag) ); + MAPIFreeBuffer (propval); + return NULL; + } + + buf = wchar_to_utf8 (propval->Value.lpszW); + MAPIFreeBuffer (propval); + if (!buf) + { + log_error ("%s:%s: error converting to utf8\n", SRCNAME, __func__); + return NULL; + } + + return buf; +} + + /* Return the subject of the message as a malloced UTF-8 string. Returns a replacement string if a subject is missing. */ char * Modified: trunk/src/mapihelp.h =================================================================== --- trunk/src/mapihelp.h 2008-06-12 07:32:09 UTC (rev 257) +++ trunk/src/mapihelp.h 2008-06-12 15:48:29 UTC (rev 258) @@ -117,6 +117,7 @@ char *mapi_get_binary_prop (LPMESSAGE message,ULONG proptype,size_t *r_nbytes); +char *mapi_get_from_address (LPMESSAGE message); char *mapi_get_subject (LPMESSAGE message); LPSTREAM mapi_get_body_as_stream (LPMESSAGE message); Modified: trunk/src/mimemaker.c =================================================================== --- trunk/src/mimemaker.c 2008-06-12 07:32:09 UTC (rev 257) +++ trunk/src/mimemaker.c 2008-06-12 15:48:29 UTC (rev 258) @@ -1159,7 +1159,7 @@ return -1; } - /* Prepare the signing. FIXME: figure out the signer of the mail. */ + /* Prepare the signing. */ if (engine_create_filter (&filter, collect_signature, &sigbuffer)) goto failure; if (engine_sign_start (filter, hwnd, protocol, Modified: trunk/src/mimeparser.c =================================================================== --- trunk/src/mimeparser.c 2008-06-12 07:32:09 UTC (rev 257) +++ trunk/src/mimeparser.c 2008-06-12 15:48:29 UTC (rev 258) @@ -1244,8 +1244,13 @@ engine_set_session_title (filter, tmp); xfree (tmp); } - if ((err=engine_verify_start (filter, hwnd, signature, sig_len, - ctx->protocol))) + { + char *from = mapi_get_from_address (mapi_message); + err = engine_verify_start (filter, hwnd, signature, sig_len, + ctx->protocol, from); + xfree (from); + } + if (err) goto leave; /* Filter the data. */ @@ -1362,7 +1367,12 @@ engine_set_session_title (filter, tmp); xfree (tmp); } - if ((err=engine_verify_start (filter, hwnd, NULL, 0, protocol))) + { + char *from = mapi_get_from_address (mapi_message); + err = engine_verify_start (filter, hwnd, NULL, 0, protocol, from); + xfree (from); + } + if (err); goto leave; if (instream) @@ -1708,7 +1718,12 @@ engine_set_session_title (filter, tmp); xfree (tmp); } - if ((err=engine_decrypt_start (filter, hwnd, protocol, !preview_mode))) + { + char *from = preview_mode? NULL : mapi_get_from_address (mapi_message); + err = engine_decrypt_start (filter, hwnd, protocol, !preview_mode, from); + xfree (from); + } + if (err) goto leave; if (decctx) From cvs at cvs.gnupg.org Fri Jun 13 18:19:00 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 13 Jun 2008 18:19:00 +0200 Subject: [svn] GnuPG - r4781 - in trunk: g10 jnlib po Message-ID: Author: wk Date: 2008-06-13 18:18:59 +0200 (Fri, 13 Jun 2008) New Revision: 4781 Modified: trunk/g10/build-packet.c trunk/jnlib/ChangeLog trunk/jnlib/dotlock.c trunk/po/POTFILES.in Log: Implement dotlocking for W32. [The diff below has been truncated] Modified: trunk/jnlib/ChangeLog =================================================================== --- trunk/jnlib/ChangeLog 2008-06-12 14:24:46 UTC (rev 4780) +++ trunk/jnlib/ChangeLog 2008-06-13 16:18:59 UTC (rev 4781) @@ -1,3 +1,8 @@ +2008-06-13 Werner Koch + + * dotlock.c: Reformat code and implement locking for W32. + (create_dotlock): Use snprintf. + 2008-06-11 Werner Koch * utf8conv.c: Remove useless variable ACTIVE_CHARSET. Suggested Modified: trunk/g10/build-packet.c =================================================================== --- trunk/g10/build-packet.c 2008-06-12 14:24:46 UTC (rev 4780) +++ trunk/g10/build-packet.c 2008-06-13 16:18:59 UTC (rev 4781) @@ -589,7 +589,7 @@ { int rc = 0; - /* We must use the old convention and don't use blockmode for tyhe + /* We must use the old convention and don't use blockmode for the sake of PGP 2 compatibility. However if the new_ctb flag was set, CTB is already formatted as new style and write_header2 does create a partial length encoding using new the new Modified: trunk/jnlib/dotlock.c =================================================================== --- trunk/jnlib/dotlock.c 2008-06-12 14:24:46 UTC (rev 4780) +++ trunk/jnlib/dotlock.c 2008-06-13 16:18:59 UTC (rev 4781) @@ -1,6 +1,6 @@ /* dotlock.c - dotfile locking * Copyright (C) 1998, 2000, 2001, 2003, 2004, - * 2005, 2006 Free Software Foundation, Inc. + * 2005, 2006, 2008 Free Software Foundation, Inc. * * This file is part of JNLIB. * @@ -25,8 +25,11 @@ #include #include #include -#ifndef HAVE_DOSISH_SYSTEM -#include +#ifdef HAVE_DOSISH_SYSTEM +# define WIN32_LEAN_AND_MEAN +# include +#else +# include #endif #include #include @@ -54,69 +57,97 @@ #endif +/* The object describing a lock. */ struct dotlock_handle { struct dotlock_handle *next; - char *tname; /* Name of lockfile template. */ + char *lockname; /* Name of the actual lockfile. */ + int locked; /* Lock status. */ + int disable; /* If true, locking is disabled. */ + +#ifdef HAVE_DOSISH_SYSTEM + HANDLE lockhd; /* The W32 handle of the lock file. */ +#else + char *tname; /* Name of the lockfile template. */ size_t nodename_off; /* Offset in TNAME of the nodename part. */ - size_t nodename_len; /* Length of the nodename part. */ - char *lockname; /* Name of the real lockfile. */ - int locked; /* Lock status. */ - int disable; /* When true, locking is disabled. */ + size_t nodename_len; /* Length of the nodename part. */ +#endif /* HAVE_DOSISH_SYSTEM */ }; +/* A list of of all lock handles. */ static volatile DOTLOCK all_lockfiles; + +/* If this has the value true all locking is disabled. */ static int never_lock; + +/* Local protototypes. */ +#ifndef HAVE_DOSISH_SYSTEM static int read_lockfile (DOTLOCK h, int *same_node); +#endif /*!HAVE_DOSISH_SYSTEM*/ + + + +/* Entirely disable all locking. This function should be called + before any locking is done. It may be called right at startup of + the process as it only sets a global value. */ void disable_dotlock(void) { never_lock = 1; } -/**************** - * Create a lockfile with the given name and return an object of - * type DOTLOCK which may be used later to actually do the lock. - * A cleanup routine gets installed to cleanup left over locks - * or other files used together with the lock mechanism. - * Although the function is called dotlock, this does not necessarily - * mean that real lockfiles are used - the function may decide to - * use fcntl locking. Calling the function with NULL only install - * the atexit handler and maybe used to assure that the cleanup - * is called after all other atexit handlers. - * - * Notes: This function creates a lock file in the same directory - * as file_to_lock with the name "file_to_lock.lock" - * A temporary file ".#lk..pid[.threadid] is used. - * This function does nothing for Windoze. + + +/* Create a lockfile for a file name FILE_TO_LOCK and returns an + object of type DOTLOCK which may be used later to actually acquire + the lock. A cleanup routine gets installed to cleanup left over + locks or other files used internally by the lock mechanism. + + Calling this function with NULL does only install the atexit + handler and may thus be used to assure that the cleanup is called + after all other atexit handlers. + + This function creates a lock file in the same directory as + FILE_TO_LOCK using that name and a suffix of ".lock". Note that on + POSIX systems a temporary file ".#lk..pid[.threadid] is + used. + + The function returns an new handle which needs to be released using + destroy_dotlock but gets also released at the termination of the + process. On error NULL is returned. */ DOTLOCK -create_dotlock( const char *file_to_lock ) +create_dotlock (const char *file_to_lock) { static int initialized; DOTLOCK h; +#ifndef HAVE_DOSISH_SYSTEM int fd = -1; char pidstr[16]; const char *nodename; const char *dirpart; int dirpartlen; -#ifndef HAVE_DOSISH_SYSTEM struct utsname utsbuf; + size_t tnamelen; #endif if ( !initialized ) { - atexit( dotlock_remove_lockfiles ); + atexit (dotlock_remove_lockfiles); initialized = 1; } + if ( !file_to_lock ) return NULL; /* Only initialization was requested. */ - h = jnlib_xcalloc ( 1, sizeof *h ); - if( never_lock ) + h = jnlib_calloc (1, sizeof *h); + if (!h) + return NULL; + + if (never_lock) { h->disable = 1; #ifdef _REENTRANT @@ -128,7 +159,12 @@ } #ifndef HAVE_DOSISH_SYSTEM - sprintf (pidstr, "%10d\n", (int)getpid() ); + /* + This is the POSIX version which uses a temporary file and the + link system call to make locking an atomic operation. + */ + + snprintf (pidstr, sizeof pidstr, "%10d\n", (int)getpid() ); /* fixme: add the hostname to the second line (FQDN or IP addr?) */ /* Create a temporary file. */ @@ -146,7 +182,7 @@ } #endif /* __riscos__ */ - if ( !(dirpart = strrchr ( file_to_lock, DIRSEP_C )) ) + if ( !(dirpart = strrchr (file_to_lock, DIRSEP_C)) ) { dirpart = EXTSEP_S; dirpartlen = 1; @@ -163,16 +199,26 @@ h->next = all_lockfiles; all_lockfiles = h; - h->tname = jnlib_xmalloc ( dirpartlen + 6+30+ strlen(nodename) + 11 ); + tnamelen = dirpartlen + 6 + 30 + strlen(nodename) + 10; + h->tname = jnlib_malloc (tnamelen + 1); + if (!h->tname) + { + all_lockfiles = h->next; + jnlib_free (h); + return NULL; + } h->nodename_len = strlen (nodename); + #ifndef __riscos__ - sprintf (h->tname, "%.*s/.#lk%p.", dirpartlen, dirpart, h ); + snprintf (h->tname, tnamelen, "%.*s/.#lk%p.", dirpartlen, dirpart, h ); h->nodename_off = strlen (h->tname); - sprintf (h->tname+h->nodename_off, "%s.%d", nodename, (int)getpid ()); + snprintf (h->tname+h->nodename_off, tnamelen - h->nodename_off, + "%s.%d", nodename, (int)getpid ()); #else /* __riscos__ */ - sprintf (h->tname, "%.*s.lk%p/", dirpartlen, dirpart, h ); + snprintf (h->tname, tnamelen, "%.*s.lk%p/", dirpartlen, dirpart, h ); h->nodename_off = strlen (h->tname); - sprintf (h->tname+h->nodename_off, "%s/%d", nodename, (int)getpid () ); + snprintf (h->tname+h->nodename_off, tnamelen - h->modename_off, + "%s/%d", nodename, (int)getpid () ); #endif /* __riscos__ */ do @@ -186,10 +232,10 @@ if ( fd == -1 ) { all_lockfiles = h->next; - log_error ( "failed to create temporary file `%s': %s\n", + log_error (_("failed to create temporary file `%s': %s\n"), h->tname, strerror(errno)); - jnlib_free(h->tname); - jnlib_free(h); + jnlib_free (h->tname); + jnlib_free (h); return NULL; } if ( write (fd, pidstr, 11 ) != 11 ) @@ -204,61 +250,120 @@ # ifdef _REENTRANT /* release mutex */ # endif -#endif /* !HAVE_DOSISH_SYSTEM */ - h->lockname = jnlib_xmalloc ( strlen (file_to_lock) + 6 ); - strcpy (stpcpy(h->lockname, file_to_lock), EXTSEP_S "lock"); + h->lockname = jnlib_malloc ( strlen (file_to_lock) + 6 ); + if (!h->lockname) + { + all_lockfiles = h->next; + unlink (h->tname); + jnlib_free (h->tname); + jnlib_free (h); + return NULL; + } + strcpy (stpcpy (h->lockname, file_to_lock), EXTSEP_S "lock"); return h; + write_failed: all_lockfiles = h->next; # ifdef _REENTRANT /* fixme: release mutex */ # endif - log_error ( "error writing to `%s': %s\n", h->tname, strerror(errno) ); - close(fd); - unlink(h->tname); - jnlib_free(h->tname); - jnlib_free(h); + log_error ( _("error writing to `%s': %s\n"), h->tname, strerror(errno) ); + close (fd); + unlink (h->tname); + jnlib_free (h->tname); + jnlib_free (h); return NULL; + +#else /* HAVE_DOSISH_SYSTEM */ + + /* The Windows version does not need a temporary file but uses the + plain lock file along with record locking. We create this file + here so that we later do only need to do the file locking. For + error reporting it is useful to keep the name of the file in the + handle. */ + h->next = all_lockfiles; + all_lockfiles = h; + + h->lockname = jnlib_malloc ( strlen (file_to_lock) + 6 ); + if (!h->lockname) + { + all_lockfiles = h->next; + jnlib_free (h); + return NULL; + } + strcpy (stpcpy(h->lockname, file_to_lock), EXTSEP_S "lock"); + + /* If would be nice if we would use the FILE_FLAG_DELETE_ON_CLOSE + along with FILE_SHARE_DELETE but that does not work due to a race + condition: Despite the OPEN_ALWAYS flag CreateFile may return an + error and we can't reliable create/open the lock file unless we + would wait here until it works - however there are other valid + reasons why a lock file can't be created and thus the process + would not stop as expected but spin til until Windows crashes. + Our solution is to keep the lock file open; that does not + harm. */ + h->lockhd = CreateFile (h->lockname, + GENERIC_READ|GENERIC_WRITE, + FILE_SHARE_READ|FILE_SHARE_WRITE, + NULL, OPEN_ALWAYS, 0, NULL); + if (h->lockhd == INVALID_HANDLE_VALUE) + { + log_error (_("can't create `%s': %s\n"), h->lockname, w32_strerror (-1)); + all_lockfiles = h->next; + jnlib_free (h->lockname); + jnlib_free (h); + return NULL; + } + return h; + +#endif /* HAVE_DOSISH_SYSTEM */ } +/* Destroy the local handle H and release the lock. */ void destroy_dotlock ( DOTLOCK h ) { -#ifndef HAVE_DOSISH_SYSTEM - if ( h ) + DOTLOCK hprev, htmp; + + if ( !h ) + return; + + /* First remove the handle from our global list of all locks. */ + for (hprev=NULL, htmp=all_lockfiles; htmp; hprev=htmp, htmp=htmp->next) + if (htmp == h) + { + if (hprev) + hprev->next = htmp->next; + else + all_lockfiles = htmp->next; + h->next = NULL; + break; + } + + /* Then destroy the lock. */ + if (!h->disable) { - DOTLOCK hprev, htmp; - - /* First remove the handle from our global list of all locks. */ - for (hprev=NULL, htmp=all_lockfiles; htmp; hprev=htmp, htmp=htmp->next) - if (htmp == h) - { - if (hprev) - hprev->next = htmp->next; - else - all_lockfiles = htmp->next; - h->next = NULL; - break; - } - - /* Second destroy the lock. */ - if (!h->disable) +#ifdef HAVE_DOSISH_SYSTEM + if (h->locked) { - if (h->locked && h->lockname) - unlink (h->lockname); - if (h->tname) - unlink (h->tname); - jnlib_free (h->tname); - jnlib_free (h->lockname); + UnlockFile (h->lockhd, 0, 0, 1, 0); } - jnlib_free(h); + CloseHandle (h->lockhd); +#else /* !HAVE_DOSISH_SYSTEM */ + if (h->locked && h->lockname) + unlink (h->lockname); + if (h->tname) + unlink (h->tname); + jnlib_free (h->tname); +#endif /* HAVE_DOSISH_SYSTEM */ + jnlib_free (h->lockname); } -#endif /*!HAVE_DOSISH_SYSTEM*/ + jnlib_free(h); } - +#ifndef HAVE_DOSISH_SYSTEM static int maybe_deadlock( DOTLOCK h ) { @@ -271,22 +376,22 @@ } return 0; } +#endif /*!HAVE_DOSISH_SYSTEM*/ -/**************** - * Do a lock on H. A TIMEOUT of 0 returns immediately, -1 waits - * forever (hopefully not), other values are reserved (should then be - * timeouts in milliseconds). Returns: 0 on success - */ + + +/* Do a lock on H. A TIMEOUT of 0 returns immediately, -1 waits + forever (hopefully not), other values are reserved (should then be + timeouts in milliseconds). Returns: 0 on success */ int -make_dotlock( DOTLOCK h, long timeout ) +make_dotlock ( DOTLOCK h, long timeout ) { -#ifdef HAVE_DOSISH_SYSTEM - return 0; -#else + int backoff = 0; +#ifndef HAVE_DOSISH_SYSTEM int pid; const char *maybe_dead=""; - int backoff=0; int same_node; +#endif /*!HAVE_DOSISH_SYSTEM*/ if ( h->disable ) return 0; /* Locks are completely disabled. Return success. */ @@ -294,14 +399,15 @@ if ( h->locked ) { #ifndef __riscos__ - log_debug("oops, `%s' is already locked\n", h->lockname ); + log_debug ("Oops, `%s' is already locked\n", h->lockname); #endif /* !__riscos__ */ return 0; } - for(;;) + for (;;) { -#ifndef __riscos__ +#ifndef HAVE_DOSISH_SYSTEM +# ifndef __riscos__ if ( !link(h->tname, h->lockname) ) { /* fixme: better use stat to check the link count */ @@ -310,10 +416,10 @@ } if ( errno != EEXIST ) { - log_error( "lock not made: link() failed: %s\n", strerror(errno) ); + log_error ( "lock not made: link() failed: %s\n", strerror(errno) ); return -1; } -#else /* __riscos__ */ +# else /* __riscos__ */ if ( !renamefile(h->tname, h->lockname) ) { h->locked = 1; @@ -324,7 +430,7 @@ log_error( "lock not made: rename() failed: %s\n", strerror(errno) ); return -1; } -#endif /* __riscos__ */ +# endif /* __riscos__ */ if ( (pid = read_lockfile (h, &same_node)) == -1 ) { @@ -344,16 +450,16 @@ } else if ( same_node && kill (pid, 0) && errno == ESRCH ) { -#ifndef __riscos__ - log_info ("removing stale lockfile (created by %d)", pid ); +# ifndef __riscos__ + log_info (_("removing stale lockfile (created by %d)\n"), pid ); unlink (h->lockname); continue; -#else /* __riscos__ */ +# else /* __riscos__ */ /* Under RISCOS we are *pretty* sure that the other task is dead and therefore we remove the stale lock file. */ - maybe_dead = " - probably dead - removing lock"; + maybe_dead = _(" - probably dead - removing lock"); unlink(h->lockname); -#endif /* __riscos__ */ +# endif /* __riscos__ */ } if ( timeout == -1 ) @@ -361,8 +467,8 @@ /* Wait until lock has been released. */ struct timeval tv; - log_info ("waiting for lock (held by %d%s) %s...\n", - pid, maybe_dead, maybe_deadlock(h)? "(deadlock?) ":""); + log_info (_("waiting for lock (held by %d%s) %s...\n"), + pid, maybe_dead, maybe_deadlock(h)? _("(deadlock?) "):""); /* We can't use sleep, cause signals may be blocked. */ @@ -374,24 +480,42 @@ } else return -1; +#else /*HAVE_DOSISH_SYSTEM*/ From cvs at cvs.gnupg.org Fri Jun 13 18:51:00 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 13 Jun 2008 18:51:00 +0200 Subject: [svn] GnuPG - r4782 - trunk/doc Message-ID: Author: wk Date: 2008-06-13 18:50:59 +0200 (Fri, 13 Jun 2008) New Revision: 4782 Modified: trunk/doc/DETAILS Log: Clarify descrition for field 10. Modified: trunk/doc/DETAILS =================================================================== --- trunk/doc/DETAILS 2008-06-13 16:18:59 UTC (rev 4781) +++ trunk/doc/DETAILS 2008-06-13 16:50:59 UTC (rev 4782) @@ -92,7 +92,7 @@ 10. Field: User-ID. The value is quoted like a C string to avoid control characters (the colon is quoted "\x3a"). - This is not used with --fixed-list-mode in gpg. + For a "pub" record this field is not used on --fixed-list-mode. A UAT record puts the attribute subpacket count here, a space, and then the total attribute subpacket size. In gpgsm the issuer name comes here From cvs at cvs.gnupg.org Sat Jun 14 00:10:22 2008 From: cvs at cvs.gnupg.org (svn author marcus) Date: Sat, 14 Jun 2008 00:10:22 +0200 Subject: [svn] GnuPG - r4783 - trunk/sm Message-ID: Author: marcus Date: 2008-06-14 00:10:22 +0200 (Sat, 14 Jun 2008) New Revision: 4783 Modified: trunk/sm/ChangeLog trunk/sm/call-dirmngr.c Log: 2008-06-13 Marcus Brinkmann * call-dirmngr.c (prepare_dirmngr): Fix error code to ignore. Modified: trunk/sm/ChangeLog =================================================================== --- trunk/sm/ChangeLog 2008-06-13 16:50:59 UTC (rev 4782) +++ trunk/sm/ChangeLog 2008-06-13 22:10:22 UTC (rev 4783) @@ -1,3 +1,7 @@ +2008-06-13 Marcus Brinkmann + + * call-dirmngr.c (prepare_dirmngr): Fix error code to ignore. + 2008-06-12 Marcus Brinkmann * gpgsm.h (struct keyserver_spec): New struct. Modified: trunk/sm/call-dirmngr.c =================================================================== --- trunk/sm/call-dirmngr.c 2008-06-13 16:50:59 UTC (rev 4782) +++ trunk/sm/call-dirmngr.c 2008-06-13 22:10:22 UTC (rev 4783) @@ -168,7 +168,7 @@ line[DIM (line) - 1] = 0; err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); - if (gpg_err_code (err) == GPG_ERR_UNKNOWN_OPTION) + if (gpg_err_code (err) == GPG_ERR_ASS_UNKNOWN_CMD) err = 0; /* Allow the use of old dirmngr versions. */ server = server->next; From cvs at cvs.gnupg.org Mon Jun 16 15:55:03 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 16 Jun 2008 15:55:03 +0200 Subject: [svn] GnuPG - r4784 - in trunk: . common Message-ID: Author: wk Date: 2008-06-16 15:55:01 +0200 (Mon, 16 Jun 2008) New Revision: 4784 Modified: trunk/NEWS trunk/common/ChangeLog trunk/common/homedir.c Log: [W32] Change location of /etc. Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2008-06-13 22:10:22 UTC (rev 4783) +++ trunk/common/ChangeLog 2008-06-16 13:55:01 UTC (rev 4784) @@ -1,3 +1,8 @@ +2008-06-16 Werner Koch + + * homedir.c (w32_commondir): New. + (gnupg_sysconfdir): Use it. + 2008-06-09 Werner Koch * b64dec.c: New. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2008-06-13 22:10:22 UTC (rev 4783) +++ trunk/NEWS 2008-06-16 13:55:01 UTC (rev 4784) @@ -9,6 +9,9 @@ * [W32] Initialized the socket subsystem for all keyserver helpers. + * [W32] The sysconf directory has been moved from a subdirectory of + the installation directory to %CSIDL_COMMON_APPDATA%/GNU/etc/gnupg. + * New gpg2 command --locate-keys. * New gpg2 options --with-sig-list and --with-sig-check. Modified: trunk/common/homedir.c =================================================================== --- trunk/common/homedir.c 2008-06-13 22:10:22 UTC (rev 4783) +++ trunk/common/homedir.c 2008-06-16 13:55:01 UTC (rev 4784) @@ -197,6 +197,35 @@ /* Fallback to the hardwired value. */ return GNUPG_LIBEXECDIR; } + +static const char * +w32_commondir (void) +{ + static char *dir; + + if (!dir) + { + char path[MAX_PATH]; + + if (w32_shgetfolderpath (NULL, CSIDL_COMMON_APPDATA, + NULL, 0, path) >= 0) + { + char *tmp = xmalloc (strlen (path) + 4 +1); + strcpy (stpcpy (tmp, path), "\\GNU"); + dir = tmp; + /* No auto create of the directory. Either the installer or + the admin has to create these directories. */ + } + else + { + /* Ooops: Not defined - probably an old Windows version. + Use the installation directory instead. */ + dir = xstrdup (w32_rootdir ()); + } + } + + return dir; +} #endif /*HAVE_W32_SYSTEM*/ @@ -214,7 +243,7 @@ if (!name) { const char *s1, *s2; - s1 = w32_rootdir (); + s1 = w32_commondir (); s2 = DIRSEP_S "etc" DIRSEP_S "gnupg"; name = xmalloc (strlen (s1) + strlen (s2) + 1); strcpy (stpcpy (name, s1), s2); From cvs at cvs.gnupg.org Mon Jun 16 16:12:54 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 16 Jun 2008 16:12:54 +0200 Subject: [svn] dirmngr - r302 - in trunk: doc src Message-ID: Author: wk Date: 2008-06-16 16:12:53 +0200 (Mon, 16 Jun 2008) New Revision: 302 Modified: trunk/doc/dirmngr.texi trunk/src/ChangeLog trunk/src/get-path.c Log: [W32] Move /etc/and /var/lib dir Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2008-06-12 14:22:42 UTC (rev 301) +++ trunk/src/ChangeLog 2008-06-16 14:12:53 UTC (rev 302) @@ -1,3 +1,9 @@ +2008-06-16 Werner Koch + + * get-path.c (w32_commondir): New. + (dirmngr_sysconfdir): Use it here. + (dirmngr_datadir): Ditto. + 2008-06-12 Marcus Brinkmann * Makefile.am (dirmngr_SOURCES): Add ldapserver.h and ldapserver.c. Modified: trunk/doc/dirmngr.texi =================================================================== --- trunk/doc/dirmngr.texi 2008-06-12 14:22:42 UTC (rev 301) +++ trunk/doc/dirmngr.texi 2008-06-16 14:12:53 UTC (rev 302) @@ -177,7 +177,7 @@ This directory should be filled with certificates of Root CAs you are trusting in checking the CRLS and signing OCSP Reponses. Usually these are the same certificates you use with the applications making use of -dirmngr. It is expected that each of these certificates files contain +dirmngr. It is expected that each of these certificate files contain exactly one @acronym{DER} encoded certificate in a file with the suffix @file{.crt}. @command{dirmngr} reads those certificates on startup and when given a SIGHUP. Certificates which are not readable or do not make Modified: trunk/src/get-path.c =================================================================== --- trunk/src/get-path.c 2008-06-12 14:22:42 UTC (rev 301) +++ trunk/src/get-path.c 2008-06-16 14:12:53 UTC (rev 302) @@ -285,6 +285,9 @@ #ifndef CSIDL_LOCAL_APPDATA #define CSIDL_LOCAL_APPDATA 0x001c #endif +#ifndef CSIDL_COMMON_APPDATA +#define CSIDL_COMMON_APPDATA 0x0023 +#endif #ifndef CSIDL_FLAG_CREATE #define CSIDL_FLAG_CREATE 0x8000 #endif @@ -357,7 +360,7 @@ xfree (tmp); tmp = NULL; } - if (tmp) + if (tmp) saved_dir = tmp; } @@ -406,6 +409,35 @@ /* Fallback to the hardwired value. */ return DIRMNGR_LIBEXECDIR; } + +static const char * +w32_commondir (void) +{ + static char *dir; + + if (!dir) + { + char path[MAX_PATH]; + + if (w32_shgetfolderpath (NULL, CSIDL_COMMON_APPDATA, + NULL, 0, path) >= 0) + { + char *tmp = xmalloc (strlen (path) + 4 +1); + strcpy (stpcpy (tmp, path), "\\GNU"); + dir = tmp; + /* No auto create of the directory. Either the installer or + the admin has to create these directories. */ + } + else + { + /* Ooops: Not defined - probably an old Windows version. + Use the installation directory instead. */ + dir = xstrdup (w32_rootdir ()); + } + } + + return dir; +} #endif /*HAVE_W32_SYSTEM*/ @@ -423,7 +455,7 @@ if (!name) { const char *s1, *s2; - s1 = w32_rootdir (); + s1 = w32_commondir (); s2 = DIRSEP_S "etc" DIRSEP_S "dirmngr"; name = xmalloc (strlen (s1) + strlen (s2) + 1); strcpy (stpcpy (name, s1), s2); @@ -457,7 +489,7 @@ if (!name) { const char *s1, *s2; - s1 = w32_rootdir (); /* FIXME: /var in windows? */ + s1 = w32_commondir (); s2 = DIRSEP_S "lib" DIRSEP_S "dirmngr"; name = xmalloc (strlen (s1) + strlen (s2) + 1); strcpy (stpcpy (name, s1), s2); @@ -529,7 +561,10 @@ const char *s2; /* We need something akin CSIDL_COMMON_PROGRAMS, but local - (non-roaming). */ + (non-roaming). This is becuase the file needs to be on the + local machine and makes only sense on that machine. + CSIDL_WINDOWS seems to be the only location which guarantees + that. */ if (w32_shgetfolderpath (NULL, CSIDL_WINDOWS, NULL, 0, s1) < 0) strcpy (s1, "C:\\WINDOWS"); s2 = DIRSEP_S "S.dirmngr"; From cvs at cvs.gnupg.org Mon Jun 16 17:48:35 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 16 Jun 2008 17:48:35 +0200 Subject: [svn] GnuPG - r4785 - in trunk: . common doc g10 Message-ID: Author: wk Date: 2008-06-16 17:48:33 +0200 (Mon, 16 Jun 2008) New Revision: 4785 Modified: trunk/NEWS trunk/common/homedir.c trunk/doc/ChangeLog trunk/doc/DETAILS trunk/g10/ChangeLog trunk/g10/keygen.c Log: Add controlo statement %ask-passphrase Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2008-06-16 13:55:01 UTC (rev 4784) +++ trunk/doc/ChangeLog 2008-06-16 15:48:33 UTC (rev 4785) @@ -1,3 +1,7 @@ +2008-06-16 Werner Koch + + * DETAILS (group): Document %ask-passphrase. + 2008-05-26 Werner Koch * gpgv.texi: Minor fixes. Fixes bug#918. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2008-06-16 13:55:01 UTC (rev 4784) +++ trunk/g10/ChangeLog 2008-06-16 15:48:33 UTC (rev 4785) @@ -1,3 +1,9 @@ +2008-06-16 Werner Koch + + * keygen.c (output_control_s): Add ASK_PASSPHRASE. + (read_parameter_file): Add commands %ask-passphrase and + %no-ask-passphrase. + 2008-06-11 Werner Koch * gpg.c: Make --fixed-list-mode a dummy. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2008-06-16 13:55:01 UTC (rev 4784) +++ trunk/NEWS 2008-06-16 15:48:33 UTC (rev 4785) @@ -22,7 +22,10 @@ * The gpg2 option --fixed-list-mode is now implicitly used and obsolete. + * New control statement %ask-passphrase for the unattended key + generation of gpg2. + Noteworthy changes in version 2.0.9 (2008-03-26) ------------------------------------------------ Modified: trunk/common/homedir.c =================================================================== --- trunk/common/homedir.c 2008-06-16 13:55:01 UTC (rev 4784) +++ trunk/common/homedir.c 2008-06-16 15:48:33 UTC (rev 4785) @@ -30,6 +30,9 @@ #ifndef CSIDL_LOCAL_APPDATA #define CSIDL_LOCAL_APPDATA 0x001c #endif +#ifndef CSIDL_COMMON_APPDATA +#define CSIDL_COMMON_APPDATA 0x0023 +#endif #ifndef CSIDL_FLAG_CREATE #define CSIDL_FLAG_CREATE 0x8000 #endif Modified: trunk/doc/DETAILS =================================================================== --- trunk/doc/DETAILS 2008-06-16 13:55:01 UTC (rev 4784) +++ trunk/doc/DETAILS 2008-06-16 15:48:33 UTC (rev 4785) @@ -789,6 +789,16 @@ and all keys are written to that file. If a new filename is given, this file is created (and overwrites an existing one). Both control statements must be given. + %ask-passphrase + Enable a mode where the command "passphrase" is ignored and + instead the usual passphrase dialog is used. This does not + make sense for batch key generation; however the unattended + key generation feature is also used by GUIs and this feature + relinquishes the GUI from implementing its own passphrase + entry code. This is a global option. + %no-ask-passphrase + Disable the ask-passphrase mode. + o The order of the parameters does not matter except for "Key-Type" which must be the first parameter. The parameters are only for the generated keyblock and parameters from previous key generations are not Modified: trunk/g10/keygen.c =================================================================== --- trunk/g10/keygen.c 2008-06-16 13:55:01 UTC (rev 4784) +++ trunk/g10/keygen.c 2008-06-16 15:48:33 UTC (rev 4785) @@ -92,6 +92,7 @@ struct output_control_s { int lnr; int dryrun; + int ask_passphrase; int use_files; struct { char *fname; @@ -2527,36 +2528,70 @@ if (parse_revocation_key (fname, para, pREVOKER)) return -1; - /* make DEK and S2K from the Passphrase */ - r = get_parameter( para, pPASSPHRASE ); - if( r && *r->u.value ) { - /* We have a plain text passphrase - create a DEK from it. - * It is a little bit ridiculous to keep it ih secure memory - * but because we do this always, why not here */ - STRING2KEY *s2k; - DEK *dek; + /* Make DEK and S2K from the Passphrase. */ + if (outctrl->ask_passphrase) + { + /* %ask-passphrase is active - ignore pPASSPRASE and ask. This + feature is required so that GUIs are able to do a key + creation but have gpg-agent ask for the passphrase. */ + int canceled = 0; + STRING2KEY *s2k; + DEK *dek; - s2k = xmalloc_secure( sizeof *s2k ); - s2k->mode = opt.s2k_mode; - s2k->hash_algo = S2K_DIGEST_ALGO; - set_next_passphrase( r->u.value ); - dek = passphrase_to_dek( NULL, 0, opt.s2k_cipher_algo, s2k, 2, - NULL, NULL); - set_next_passphrase( NULL ); - assert( dek ); - memset( r->u.value, 0, strlen(r->u.value) ); + dek = do_ask_passphrase ( &s2k, &canceled ); + if (dek) + { + r = xmalloc_clear( sizeof *r ); + r->key = pPASSPHRASE_DEK; + r->u.dek = dek; + r->next = para; + para = r; + r = xmalloc_clear( sizeof *r ); + r->key = pPASSPHRASE_S2K; + r->u.s2k = s2k; + r->next = para; + para = r; + } - r = xmalloc_clear( sizeof *r ); - r->key = pPASSPHRASE_S2K; - r->u.s2k = s2k; - r->next = para; - para = r; - r = xmalloc_clear( sizeof *r ); - r->key = pPASSPHRASE_DEK; - r->u.dek = dek; - r->next = para; - para = r; - } + if (canceled) + { + log_error ("%s:%d: key generation canceled\n", fname, r->lnr ); + return -1; + } + } + else + { + r = get_parameter( para, pPASSPHRASE ); + if ( r && *r->u.value ) + { + /* We have a plain text passphrase - create a DEK from it. + * It is a little bit ridiculous to keep it in secure memory + * but because we do this always, why not here. */ + STRING2KEY *s2k; + DEK *dek; + + s2k = xmalloc_secure ( sizeof *s2k ); + s2k->mode = opt.s2k_mode; + s2k->hash_algo = S2K_DIGEST_ALGO; + set_next_passphrase ( r->u.value ); + dek = passphrase_to_dek (NULL, 0, opt.s2k_cipher_algo, s2k, 2, + NULL, NULL); + set_next_passphrase (NULL ); + assert (dek); + memset (r->u.value, 0, strlen(r->u.value)); + + r = xmalloc_clear (sizeof *r); + r->key = pPASSPHRASE_S2K; + r->u.s2k = s2k; + r->next = para; + para = r; + r = xmalloc_clear (sizeof *r); + r->key = pPASSPHRASE_DEK; + r->u.dek = dek; + r->next = para; + para = r; + } + } /* Make KEYCREATIONDATE from Creation-Date. */ r = get_parameter (para, pCREATIONDATE); @@ -2696,6 +2731,10 @@ log_info("%s\n", value ); else if( !ascii_strcasecmp( keyword, "%dry-run" ) ) outctrl.dryrun = 1; + else if( !ascii_strcasecmp( keyword, "%ask-passphrase" ) ) + outctrl.ask_passphrase = 1; + else if( !ascii_strcasecmp( keyword, "%no-ask-passphrase" ) ) + outctrl.ask_passphrase = 0; else if( !ascii_strcasecmp( keyword, "%commit" ) ) { outctrl.lnr = lnr; if (proc_parameter_file( para, fname, &outctrl, 0 )) From cvs at cvs.gnupg.org Wed Jun 18 16:46:06 2008 From: cvs at cvs.gnupg.org (svn author marcus) Date: Wed, 18 Jun 2008 16:46:06 +0200 Subject: [svn] GnuPG - r4786 - trunk/common Message-ID: Author: marcus Date: 2008-06-18 16:46:05 +0200 (Wed, 18 Jun 2008) New Revision: 4786 Modified: trunk/common/ChangeLog trunk/common/iobuf.c trunk/common/sysutils.c trunk/common/sysutils.h Log: 2008-06-18 Marcus Brinkmann * sysutils.h (translate_table_init, translate_table_lookup): New prototypes. * sysutils.c: Include . (FD_TRANSLATE_MAX): New macro. (fd_translate, fd_translate_len): New static variables. (translate_table_init, translate_table_lookup): New functions. (translate_sys2libc_fd_int): Translate file descriptor. * iobuf.c (check_special_filename): Translate handle values from special filenames. Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2008-06-16 15:48:33 UTC (rev 4785) +++ trunk/common/ChangeLog 2008-06-18 14:46:05 UTC (rev 4786) @@ -1,3 +1,15 @@ +2008-06-18 Marcus Brinkmann + + * sysutils.h (translate_table_init, translate_table_lookup): New + prototypes. + * sysutils.c: Include . + (FD_TRANSLATE_MAX): New macro. + (fd_translate, fd_translate_len): New static variables. + (translate_table_init, translate_table_lookup): New functions. + (translate_sys2libc_fd_int): Translate file descriptor. + * iobuf.c (check_special_filename): Translate handle values from + special filenames. + 2008-06-16 Werner Koch * homedir.c (w32_commondir): New. Modified: trunk/common/iobuf.c =================================================================== --- trunk/common/iobuf.c 2008-06-16 15:48:33 UTC (rev 4785) +++ trunk/common/iobuf.c 2008-06-18 14:46:05 UTC (rev 4786) @@ -1177,7 +1177,7 @@ for (i = 0; digitp (fname+i); i++) ; if (!fname[i]) - return atoi (fname); + return translate_table_lookup (atoi (fname)); } return -1; } Modified: trunk/common/sysutils.c =================================================================== --- trunk/common/sysutils.c 2008-06-16 15:48:33 UTC (rev 4785) +++ trunk/common/sysutils.c 2008-06-18 14:46:05 UTC (rev 4786) @@ -50,6 +50,7 @@ # include #endif #include +#include #include "util.h" #include "i18n.h" @@ -278,6 +279,116 @@ } + +/* Handle translation. On W32, we provide handle values on the + command line directly and using special file names such as + "-&HANDLE". However, in GPGME we can not directly inherit the + handles as this may interfere with other components in a + multithreaded application. Thus, we inject the handles after + creating the GPG process. The problem is that the handle numbers + change at injection, but it is too late to change the command line. + Hence this hack, which allows us to translate the handle values + in the command line to their new values after injection. + + Handles that must be translated are those occuring in special file + names (see iobuf.c::check_special_filename) as well as those given + directly to options (see translate_sys2libc_fd_int). */ + +/* For W32, we may have to translate handle values given on the + command line. */ +#define FD_TRANSLATE_MAX 8 +static struct +{ + int from; + int to; +} fd_translate[8]; + +/* Number of entries used in fd_translate. */ +static int fd_translate_len; + + +/* Initialize the fd translation table. This reads one line from + stdin which is expected to be in the format "FROM TO [...]" where + each "FROM TO" pair are two handle numbers. Handle number FROM on + the command line is translated to handle number TO. */ +void +translate_table_init (void) +{ +#define TRANS_MAX 100 + char line[TRANS_MAX + 1]; + char *linep; + int idx; + int res; + int newl = 0; + + /* We always read one line from stdin. */ + for (idx = 0; idx < TRANS_MAX; idx++) + { + res = read (0, &line[idx], 1); + if (res != 1) + break; + if (line[idx] == '\n') + { + newl = 1; + break; + } + } + if (!newl) + { + char buf[1]; + do + res = read (0, buf, 1); + while (res == 1 && *buf != '\n'); + } + + line[idx] = '\0'; + linep = line; + + /* Now start to read mapping pairs. */ + for (idx = 0; idx < FD_TRANSLATE_MAX; idx++) + { + unsigned long from; + unsigned long to; + char *tail; + + while (isspace (*linep)) + linep++; + if (*linep == '\0') + break; + from = strtoul (linep, &tail, 0); + if (tail == NULL || ! (*tail == '\0' || isspace (*tail))) + break; + linep = tail; + + while (isspace (*linep)) + linep++; + if (*linep == '\0') + break; + to = strtoul (linep, &tail, 0); + if (tail == NULL || ! (*tail == '\0' || isspace (*tail))) + break; + linep = tail; + + fd_translate[idx].from = from; + fd_translate[idx].to = to; + fd_translate_len++; + } +} + + +/* Translate a handle number. */ +int +translate_table_lookup (int fd) +{ + int idx; + + for (idx = 0; idx < fd_translate_len; idx++) + if (fd_translate[idx].from == fd) + return fd_translate[idx].to; + return fd; +} + + /* This function is a NOP for POSIX systems but required under Windows as the file handles as returned by OS calls (like CreateFile) are different from the libc file descriptors (like open). This function @@ -303,6 +414,7 @@ #endif } + /* This is the same as translate_sys2libc_fd but takes an integer which is assumed to be such an system handle. */ int @@ -312,8 +424,14 @@ if (fd <= 2) return fd; /* Do not do this for error, stdin, stdout, stderr. */ + /* Note: If this function is ever used in a different context than + option parsing in the main function, a variant that does not do + translation probable needs to be used. */ + fd = translate_table_lookup (fd); + return translate_sys2libc_fd ((void*)fd, for_write); #else + fd = translate_table_lookup (fd); return fd; #endif } Modified: trunk/common/sysutils.h =================================================================== --- trunk/common/sysutils.h 2008-06-16 15:48:33 UTC (rev 4785) +++ trunk/common/sysutils.h 2008-06-18 14:46:05 UTC (rev 4786) @@ -43,6 +43,16 @@ const unsigned char *get_session_marker (size_t *rlen); /*int check_permissions (const char *path,int extension,int checkonly);*/ void gnupg_sleep (unsigned int seconds); + +/* Initialize the fd translation table. This reads one line from + stdin which is expected to be in the format "FROM TO [...]" where + each "FROM TO" pair are two handle numbers. Handle number FROM on + the command line is translated to handle number TO. */ +void translate_table_init (void); + +/* Translate a handle number. */ +int translate_table_lookup (int fd); + int translate_sys2libc_fd (gnupg_fd_t fd, int for_write); int translate_sys2libc_fd_int (int fd, int for_write); FILE *gnupg_tmpfile (void); From cvs at cvs.gnupg.org Wed Jun 18 16:49:56 2008 From: cvs at cvs.gnupg.org (svn author marcus) Date: Wed, 18 Jun 2008 16:49:56 +0200 Subject: [svn] GnuPG - r4787 - trunk/g10 Message-ID: Author: marcus Date: 2008-06-18 16:49:54 +0200 (Wed, 18 Jun 2008) New Revision: 4787 Modified: trunk/g10/ChangeLog trunk/g10/gpg.c Log: 2008-06-18 Marcus Brinkmann * gpg.c (enum cmd_and_opt_values): New option oEnableW32HandleTranslation. (opts): New option --enable-w32-handle-translation. (main): New variable w32_handle_translation to keep track of option. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2008-06-18 14:46:05 UTC (rev 4786) +++ trunk/g10/ChangeLog 2008-06-18 14:49:54 UTC (rev 4787) @@ -1,3 +1,11 @@ +2008-06-18 Marcus Brinkmann + + * gpg.c (enum cmd_and_opt_values): New option + oEnableW32HandleTranslation. + (opts): New option --enable-w32-handle-translation. + (main): New variable w32_handle_translation to keep track of + option. + 2008-06-16 Werner Koch * keygen.c (output_control_s): Add ASK_PASSPHRASE. Modified: trunk/g10/gpg.c =================================================================== --- trunk/g10/gpg.c 2008-06-18 14:46:05 UTC (rev 4786) +++ trunk/g10/gpg.c 2008-06-18 14:49:54 UTC (rev 4787) @@ -300,6 +300,7 @@ oNoAllowFreeformUID, oAllowSecretKeyImport, oEnableSpecialFilenames, + oEnableW32HandleTranslation, oNoLiteral, oSetFilesize, oHonorHttpProxy, @@ -664,6 +665,7 @@ { oAllowSecretKeyImport, "allow-secret-key-import", 0, "@" }, { oTryAllSecrets, "try-all-secrets", 0, "@" }, { oEnableSpecialFilenames, "enable-special-filenames", 0, "@" }, + { oEnableW32HandleTranslation, "enable-w32-handle-translation", 0, "@" }, { oNoExpensiveTrustChecks, "no-expensive-trust-checks", 0, "@" }, { aDeleteSecretAndPublicKeys, "delete-secret-and-public-keys",256, "@" }, { aRebuildKeydbCaches, "rebuild-keydb-caches", 256, "@"}, @@ -1876,6 +1878,7 @@ int eyes_only=0; int multifile=0; int pwfd = -1; + int w32_handle_translation = 0; int with_fpr = 0; /* make an option out of --fingerprint */ int any_explicit_recipient = 0; int require_secmem=0,got_secmem=0; @@ -1991,6 +1994,15 @@ { /* Not used */ } + else if (pargs.r_opt == oEnableW32HandleTranslation ) + { + /* We must initialize handle translation before parsing + the options. */ + if (! w32_handle_translation) + translate_table_init (); + w32_handle_translation = 1; + break; + } } #ifdef HAVE_DOSISH_SYSTEM @@ -2769,6 +2781,7 @@ case oEnableSpecialFilenames: iobuf_enable_special_filenames (1); break; + case oEnableW32HandleTranslation: break; case oNoExpensiveTrustChecks: opt.no_expensive_trust_checks=1; break; case oAutoCheckTrustDB: opt.no_auto_check_trustdb=0; break; case oNoAutoCheckTrustDB: opt.no_auto_check_trustdb=1; break; @@ -3333,6 +3346,7 @@ if( pwfd != -1 ) /* Read the passphrase now. */ read_passphrase_from_fd( pwfd ); + fname = argc? *argv : NULL; if(fname && utf8_strings) From cvs at cvs.gnupg.org Wed Jun 18 17:16:55 2008 From: cvs at cvs.gnupg.org (svn author marcus) Date: Wed, 18 Jun 2008 17:16:55 +0200 Subject: [svn] GnuPG - r4788 - trunk/common Message-ID: Author: marcus Date: 2008-06-18 17:16:53 +0200 (Wed, 18 Jun 2008) New Revision: 4788 Modified: trunk/common/ChangeLog trunk/common/sysutils.c Log: 2008-06-18 Marcus Brinkmann * sysutils.c (TRANS_MAX): Bump up to 350 to be on the safe side. Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2008-06-18 14:49:54 UTC (rev 4787) +++ trunk/common/ChangeLog 2008-06-18 15:16:53 UTC (rev 4788) @@ -1,5 +1,7 @@ 2008-06-18 Marcus Brinkmann + * sysutils.c (TRANS_MAX): Bump up to 350 to be on the safe side. + * sysutils.h (translate_table_init, translate_table_lookup): New prototypes. * sysutils.c: Include . Modified: trunk/common/sysutils.c =================================================================== --- trunk/common/sysutils.c 2008-06-18 14:49:54 UTC (rev 4787) +++ trunk/common/sysutils.c 2008-06-18 15:16:53 UTC (rev 4788) @@ -314,7 +314,10 @@ void translate_table_init (void) { -#define TRANS_MAX 100 + /* Hold roughly 8 pairs of 64 bit numbers in hex notation: + "0xFEDCBA9876543210 0xFEDCBA9876543210". 8*19*2 - 1 = 303. This + plans ahead for a time where a HANDLE is 64 bit. */ +#define TRANS_MAX 350 char line[TRANS_MAX + 1]; char *linep; int idx; From cvs at cvs.gnupg.org Mon Jun 23 10:49:06 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 23 Jun 2008 10:49:06 +0200 Subject: [svn] GnuPG - r4791 - branches/STABLE-BRANCH-1-4/po Message-ID: Author: wk Date: 2008-06-23 10:49:04 +0200 (Mon, 23 Jun 2008) New Revision: 4791 Modified: branches/STABLE-BRANCH-1-4/po/ChangeLog branches/STABLE-BRANCH-1-4/po/de.po Log: Typo fix by Ludwig H?\195?\131?\194?\188gelsch?\195?\131?\194?\164fer. Modified: branches/STABLE-BRANCH-1-4/po/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/po/ChangeLog 2008-06-19 13:09:40 UTC (rev 4790) +++ branches/STABLE-BRANCH-1-4/po/ChangeLog 2008-06-23 08:49:04 UTC (rev 4791) @@ -1,3 +1,7 @@ +2008-06-23 Ludwig H?gelsch?fer (wk) + + * de.po: 3 typo fixes. + 2008-05-26 Werner Koch * de.po: Minor fixes submitted by Jan Seidel. Fixes bug#916. Modified: branches/STABLE-BRANCH-1-4/po/de.po [not shown] From cvs at cvs.gnupg.org Mon Jun 23 16:43:16 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 23 Jun 2008 16:43:16 +0200 Subject: [svn] GnuPG - r4792 - trunk/sm Message-ID: Author: wk Date: 2008-06-23 16:43:14 +0200 (Mon, 23 Jun 2008) New Revision: 4792 Modified: trunk/sm/ChangeLog trunk/sm/encrypt.c Log: Code cleanup. Modified: trunk/sm/ChangeLog =================================================================== --- trunk/sm/ChangeLog 2008-06-23 08:49:04 UTC (rev 4791) +++ trunk/sm/ChangeLog 2008-06-23 14:43:14 UTC (rev 4792) @@ -1,3 +1,9 @@ +2008-06-23 Werner Koch + + * encrypt.c (encode_session_key): Replace xmalloc by xtrymalloc. + Use bin2hex instead of open coding the conversion. + (encrypt_dek): Init S_DATA. + 2008-06-13 Marcus Brinkmann * call-dirmngr.c (prepare_dirmngr): Fix error code to ignore. Modified: trunk/sm/encrypt.c =================================================================== --- trunk/sm/encrypt.c 2008-06-23 08:49:04 UTC (rev 4791) +++ trunk/sm/encrypt.c 2008-06-23 14:43:14 UTC (rev 4792) @@ -1,5 +1,5 @@ /* encrypt.c - Encrypt a message - * Copyright (C) 2001, 2003, 2004, 2007 Free Software Foundation, Inc. + * Copyright (C) 2001, 2003, 2004, 2007, 2008 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -144,17 +144,14 @@ encode_session_key (DEK dek, gcry_sexp_t * r_data) { gcry_sexp_t data; - char * p, tmp[3]; - int i; + char *p; int rc; - p = xmalloc (64 + 2 * dek->keylen); + p = xtrymalloc (64 + 2 * dek->keylen); + if (!p) + return gpg_error_from_syserror (); strcpy (p, "(data\n (flags pkcs1)\n (value #"); - for (i=0; i < dek->keylen; i++) - { - sprintf (tmp, "%02x", (unsigned char) dek->key[i]); - strcat (p, tmp); - } + bin2hex (dek->key, dek->keylen, p + strlen (p)); strcat (p, "#))\n"); rc = gcry_sexp_sscan (&data, NULL, p, strlen (p)); xfree (p); @@ -196,13 +193,14 @@ return rc; } - /* put the encoded cleartext into a simple list */ + /* Put the encoded cleartext into a simple list. */ + s_data = NULL; /* (avoid compiler warning) */ rc = encode_session_key (dek, &s_data); if (rc) - { - log_error ("encode_session_key failed: %s\n", gpg_strerror (rc)); - return rc; - } + { + log_error ("encode_session_key failed: %s\n", gpg_strerror (rc)); + return rc; + } /* pass it to libgcrypt */ rc = gcry_pk_encrypt (&s_ciph, s_data, s_pkey); From cvs at cvs.gnupg.org Tue Jun 24 10:11:05 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 24 Jun 2008 10:11:05 +0200 Subject: [svn] gcry - r1292 - in trunk: . cipher Message-ID: Author: wk Date: 2008-06-24 10:11:04 +0200 (Tue, 24 Jun 2008) New Revision: 1292 Modified: trunk/THANKS trunk/TODO trunk/cipher/ChangeLog trunk/cipher/ac.c Log: Fixed memory leak inthe ac functions. Modified: trunk/cipher/ChangeLog =================================================================== --- trunk/cipher/ChangeLog 2008-05-27 11:46:15 UTC (rev 1291) +++ trunk/cipher/ChangeLog 2008-06-24 08:11:04 UTC (rev 1292) @@ -1,3 +1,8 @@ +2008-06-24 Szakats Istvan (wk) + + * ac.c (_gcry_ac_key_destroy, _gcry_ac_key_pair_generate): Relase + some more memory. + 2008-04-22 Werner Koch * rijndael.c (_gcry_aes_cfb_enc, _gcry_aes_cbc_enc) Modified: trunk/THANKS =================================================================== --- trunk/THANKS 2008-05-27 11:46:15 UTC (rev 1291) +++ trunk/THANKS 2008-06-24 08:11:04 UTC (rev 1292) @@ -126,6 +126,7 @@ Steffen Zahn zahn at berlin.snafu.de Steven Bakker steven at icoe.att.com Susanne Schultz schultz at hsp.de +Szakats Istvan szaki.ms at gmail.com Thiago Jung Bauermann jungmann at cwb.matrix.com.br Thomas Roessler roessler at guug.de Tom Holroyd tomh at po.crl.go.jp Modified: trunk/TODO =================================================================== --- trunk/TODO 2008-05-27 11:46:15 UTC (rev 1291) +++ trunk/TODO 2008-06-24 08:11:04 UTC (rev 1292) @@ -66,6 +66,16 @@ collectros need to run that bunch of Unix utilities we don't waste their precious results. +* Add transient flag to RSA key generation + For short living keys it makes sense to allow generation using a PRNG. + We could implement it this way: + + (genkey + (rsa + (nbits 4:1024) + (transient-key))) + + * Out of memory handler for secure memory should do proper logging There is no shortage of standard memory, so logging is most likely Modified: trunk/cipher/ac.c =================================================================== --- trunk/cipher/ac.c 2008-05-27 11:46:15 UTC (rev 1291) +++ trunk/cipher/ac.c 2008-06-24 08:11:04 UTC (rev 1292) @@ -1,6 +1,6 @@ /* ac.c - Alternative interface for asymmetric cryptography. Copyright (C) 2003, 2004, 2005, 2006 - 2007 Free Software Foundation, Inc. + 2007, 2008 Free Software Foundation, Inc. This file is part of Libgcrypt. @@ -1496,6 +1496,7 @@ arg_list = NULL; genkey_sexp_request = NULL; genkey_sexp_reply = NULL; + key_sexp = NULL; /* Allocate key pair. */ key_pair_new = gcry_malloc (sizeof (struct gcry_ac_key_pair)); @@ -1631,6 +1632,7 @@ gcry_free (arg_list); gcry_sexp_release (genkey_sexp_request); gcry_sexp_release (genkey_sexp_reply); + gcry_sexp_release (key_sexp); if (err) { _gcry_ac_data_destroy (key_data_secret); @@ -1679,8 +1681,13 @@ if (key->data) { for (i = 0; i < key->data->data_n; i++) - if (key->data->data[i].mpi != NULL) - gcry_mpi_release (key->data->data[i].mpi); + { + if (key->data->data[i].mpi) + gcry_mpi_release (key->data->data[i].mpi); + if (key->data->data[i].name) + gcry_free (key->data->data[i].name); + } + gcry_free (key->data->data); gcry_free (key->data); } gcry_free (key); From cvs at cvs.gnupg.org Tue Jun 24 18:00:33 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 24 Jun 2008 18:00:33 +0200 Subject: [svn] GnuPG - r4793 - in trunk: doc scd Message-ID: Author: wk Date: 2008-06-24 18:00:29 +0200 (Tue, 24 Jun 2008) New Revision: 4793 Modified: trunk/doc/scdaemon.texi trunk/scd/ChangeLog trunk/scd/app-common.h trunk/scd/app-nks.c trunk/scd/app-openpgp.c trunk/scd/command.c Log: Add support for the TCOS NullPIN feature. Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2008-06-23 14:43:14 UTC (rev 4792) +++ trunk/scd/ChangeLog 2008-06-24 16:00:29 UTC (rev 4793) @@ -1,3 +1,14 @@ +2008-06-24 Werner Koch + + * app-common.h (app_ctx_s): Renamed reset_mode parameter of + change_pin to mode_Flags and make it an unsigned int. + (APP_CHANGE_FLAG_RESET, APP_CHANGE_FLAG_NULLPIN): New. + * app-openpgp.c (do_change_pin): Adjust for that. + + * command.c (cmd_passwd): Add option --nullpin. + * app-nks.c (do_check_pin, do_change_pin): New. + (app_select_nks): Register new functions. + 2008-04-21 Moritz Schulte (wk) * app-openpgp.c (verify_a_chv): Make use of the default CHV flag. Modified: trunk/doc/scdaemon.texi =================================================================== --- trunk/doc/scdaemon.texi 2008-06-23 14:43:14 UTC (rev 4792) +++ trunk/doc/scdaemon.texi 2008-06-24 16:00:29 UTC (rev 4793) @@ -580,11 +580,12 @@ @subsection Change PINs. @example - PASSWD [--reset] @var{chvno} + PASSWD [--reset] [--nullpin] @var{chvno} @end example Change the PIN or reset the retry counter of the card holder -verification vector number @var{chvno}. +verification vector number @var{chvno}. The option @option{--nullpin} +is used to initialize the PIN of TCOS cards (6 byte NullPIN only). @node Scdaemon CHECKPIN Modified: trunk/scd/app-common.h =================================================================== --- trunk/scd/app-common.h 2008-06-23 14:43:14 UTC (rev 4792) +++ trunk/scd/app-common.h 2008-06-24 16:00:29 UTC (rev 4793) @@ -31,6 +31,10 @@ #endif +#define APP_CHANGE_FLAG_RESET 1 +#define APP_CHANGE_FLAG_NULLPIN 2 + + struct app_local_s; /* Defined by all app-*.c. */ struct app_ctx_s { @@ -101,7 +105,7 @@ gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg); gpg_error_t (*change_pin) (app_t app, ctrl_t ctrl, - const char *chvnostr, int reset_mode, + const char *chvnostr, unsigned int flags, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg); gpg_error_t (*check_pin) (app_t app, const char *keyidstr, Modified: trunk/scd/app-nks.c =================================================================== --- trunk/scd/app-nks.c 2008-06-23 14:43:14 UTC (rev 4792) +++ trunk/scd/app-nks.c 2008-06-24 16:00:29 UTC (rev 4793) @@ -1,5 +1,5 @@ /* app-nks.c - The Telesec NKS 2.0 card application. - * Copyright (C) 2004, 2007 Free Software Foundation, Inc. + * Copyright (C) 2004, 2007, 2008 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -414,7 +414,7 @@ if (indatalen != 20 && indatalen != 16 && indatalen != 35) return gpg_error (GPG_ERR_INV_VALUE); - /* Check that the provided ID is vaid. This is not really needed + /* Check that the provided ID is valid. This is not really needed but we do it to enforce correct usage by the caller. */ if (strncmp (keyidstr, "NKS-DF01.", 9) ) return gpg_error (GPG_ERR_INV_ID); @@ -517,7 +517,66 @@ } +/* Handle the PASSWD command. CHVNOSTR is currently ignored; we + always use VHV0. RESET_MODE is not yet implemented. */ +static gpg_error_t +do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, + unsigned int flags, + gpg_error_t (*pincb)(void*, const char *, char **), + void *pincb_arg) +{ + gpg_error_t err; + char *pinvalue; + const char *oldpin; + size_t oldpinlen; + if ((flags & APP_CHANGE_FLAG_RESET)) + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); + + if ((flags & APP_CHANGE_FLAG_NULLPIN)) + { + /* With the nullpin flag, we do not verify the PIN - it would fail + if the Nullpin is still set. */ + oldpin = "\0\0\0\0\0"; + oldpinlen = 6; + } + else + { + err = verify_pin (app, pincb, pincb_arg); + if (err) + return err; + oldpin = NULL; + oldpinlen = 0; + } + + /* TRANSLATORS: Do not translate the "|*|" prefixes but + keep it at the start of the string. We need this elsewhere + to get some infos on the string. */ + err = pincb (pincb_arg, _("|N|New PIN"), &pinvalue); + if (err) + { + log_error (_("error getting new PIN: %s\n"), gpg_strerror (err)); + return err; + } + + err = iso7816_change_reference_data (app->slot, 0x00, + oldpin, oldpinlen, + pinvalue, strlen (pinvalue)); + xfree (pinvalue); + return err; +} + + +/* Perform a simple verify operation. KEYIDSTR should be NULL or empty. */ +static gpg_error_t +do_check_pin (app_t app, const char *keyidstr, + gpg_error_t (*pincb)(void*, const char *, char **), + void *pincb_arg) +{ + return verify_pin (app, pincb, pincb_arg); +} + + /* Select the NKS 2.0 application. */ gpg_error_t app_select_nks (app_t app) @@ -539,8 +598,8 @@ app->fnc.sign = do_sign; app->fnc.auth = NULL; app->fnc.decipher = do_decipher; - app->fnc.change_pin = NULL; - app->fnc.check_pin = NULL; + app->fnc.change_pin = do_change_pin; + app->fnc.check_pin = do_check_pin; } return rc; Modified: trunk/scd/app-openpgp.c =================================================================== --- trunk/scd/app-openpgp.c 2008-06-23 14:43:14 UTC (rev 4792) +++ trunk/scd/app-openpgp.c 2008-06-24 16:00:29 UTC (rev 4793) @@ -1644,13 +1644,15 @@ /* Handle the PASSWD command. */ static gpg_error_t -do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, int reset_mode, +do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, + unsigned int flags, gpg_error_t (*pincb)(void*, const char *, char **), void *pincb_arg) { int rc = 0; int chvno = atoi (chvnostr); char *pinvalue; + int reset_mode = !!(flags & APP_CHANGE_FLAG_RESET); if (reset_mode && chvno == 3) { Modified: trunk/scd/command.c =================================================================== --- trunk/scd/command.c 2008-06-23 14:43:14 UTC (rev 4792) +++ trunk/scd/command.c 2008-06-24 16:00:29 UTC (rev 4793) @@ -1273,18 +1273,24 @@ } -/* PASSWD [--reset] +/* PASSWD [--reset] [--nullpin] Change the PIN or reset the retry counter of the card holder - verfication vector CHVNO. */ + verfication vector CHVNO. The option --nullpin is used for TCOS + cards to set the initial PIN. */ static int cmd_passwd (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); int rc; char *chvnostr; - int reset_mode = has_option (line, "--reset"); + unsigned int flags = 0; + if (has_option (line, "--reset")) + flags |= APP_CHANGE_FLAG_RESET; + if (has_option (line, "--nullpin")) + flags |= APP_CHANGE_FLAG_NULLPIN; + if ( IS_LOCKED (ctrl) ) return gpg_error (GPG_ERR_LOCKED); @@ -1312,7 +1318,7 @@ chvnostr = xtrystrdup (chvnostr); if (!chvnostr) return out_of_core (); - rc = app_change_pin (ctrl->app_ctx, ctrl, chvnostr, reset_mode, pin_cb, ctx); + rc = app_change_pin (ctrl->app_ctx, ctrl, chvnostr, flags, pin_cb, ctx); if (rc) log_error ("command passwd failed: %s\n", gpg_strerror (rc)); xfree (chvnostr); From cvs at cvs.gnupg.org Wed Jun 25 03:44:53 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 25 Jun 2008 03:44:53 +0200 Subject: [svn] gpgme - r1320 - trunk/doc Message-ID: Author: wk Date: 2008-06-25 03:44:50 +0200 (Wed, 25 Jun 2008) New Revision: 1320 Modified: trunk/doc/ChangeLog trunk/doc/gpgme.texi Log: Updated example. Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2008-06-20 10:40:52 UTC (rev 1319) +++ trunk/doc/ChangeLog 2008-06-25 01:44:50 UTC (rev 1320) @@ -1,3 +1,8 @@ +2008-06-25 Werner Koch + + * gpgme.texi (Listing Keys): Updated example to the current API. + Noted by Nico Schottelius. + 2008-06-05 Werner Koch * uiserver.texi (Miscellaneous UI Server Commands): Describe Modified: trunk/doc/gpgme.texi =================================================================== --- trunk/doc/gpgme.texi 2008-06-20 10:40:52 UTC (rev 1319) +++ trunk/doc/gpgme.texi 2008-06-25 01:44:50 UTC (rev 1320) @@ -2772,6 +2772,7 @@ @example gpgme_ctx_t ctx; +gpgme_key_t key; gpgme_error_t err = gpgme_new (&ctx); if (!err) @@ -2782,15 +2783,19 @@ err = gpgme_op_keylist_next (ctx, &key); if (err) break; - printf ("%s: %s <%s>\n", key->keyid, key->name, key->email); + printf ("%s:", key->subkeys->keyid); + if (key->uids && key->uids->name) + printf (" %s", key->uids->name); + if (key->uids && key->uids->email) + printf (" <%s>", key->uids->email); + putchar ('\n'); gpgme_key_release (key); @} gpgme_release (ctx); @} if (gpg_err_code (err) != GPG_ERR_EOF) @{ - fprintf (stderr, "%s: can not list keys: %s\n", - argv[0], gpgme_strerror (err)); + fprintf (stderr, "can not list keys: %s\n", gpgme_strerror (err)); exit (1); @} @end example From cvs at cvs.gnupg.org Wed Jun 25 13:14:52 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 25 Jun 2008 13:14:52 +0200 Subject: [svn] GnuPG - r4794 - in trunk/doc: . examples Message-ID: Author: wk Date: 2008-06-25 13:14:48 +0200 (Wed, 25 Jun 2008) New Revision: 4794 Modified: trunk/doc/ChangeLog trunk/doc/com-certs.pem trunk/doc/examples/trustlist.txt trunk/doc/qualified.txt Log: add new certifciates Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2008-06-24 16:00:29 UTC (rev 4793) +++ trunk/doc/ChangeLog 2008-06-25 11:14:48 UTC (rev 4794) @@ -1,3 +1,9 @@ +2008-06-25 Werner Koch + + * qualified.txt: Add new BnetzA certs 12R and 13R. + * com-certs.pem: Ditto. + * examples/trustlist.txt: Ditto. + 2008-06-19 Werner Koch * tools.texi (Listing options): Describe new complect gpgconf type Modified: trunk/doc/com-certs.pem =================================================================== --- trunk/doc/com-certs.pem 2008-06-24 16:00:29 UTC (rev 4793) +++ trunk/doc/com-certs.pem 2008-06-25 11:14:48 UTC (rev 4794) @@ -149,6 +149,73 @@ yDmXv3nzPTGVM3F+aavJCybjJ1qk -----END CERTIFICATE----- +Issuer ...: /CN=12R-CA 1:PN/O=Bundesnetzagentur/C=DE +Serial ...: 0139 +Subject ..: /CN=12R-CA 1:PN/O=Bundesnetzagentur/C=DE + +-----BEGIN CERTIFICATE----- +MIIErTCCA5WgAwIBAgICATkwDQYJKoZIhvcNAQENBQAwPzELMAkGA1UEBhMCREUx +GjAYBgNVBAoMEUJ1bmRlc25ldHphZ2VudHVyMRQwEgYDVQQDDAsxMlItQ0EgMTpQ +TjAeFw0wNzA1MjUxMTAxNDRaFw0xMjA1MjUxMDU2MDdaMD8xCzAJBgNVBAYTAkRF +MRowGAYDVQQKDBFCdW5kZXNuZXR6YWdlbnR1cjEUMBIGA1UEAwwLMTJSLUNBIDE6 +UE4wggEjMA0GCSqGSIb3DQEBAQUAA4IBEAAwggELAoIBAQCYOqYxUqr6ZdlIuVaz +1raETmld82tCCFjUnIlHGpaTbBGQ9ddW4pdkdNmK4dHDesAnGFB6tgZzFTYivjTY +Jyzv3NunMth8AjwCivQ0u2RBlunY2jg6dNSeTwGlmOlG709HgWPHvvAboqLDoV81 +knMbNbG4P7Ff/+lsTnbN/gT0X5fHUz5UO3eowyl2kD6GBZwb+noR/86U0V39yXsk +ZD/NNBXKOzKo9VXx09S1Uq027Cc+VIa62DWUeUGiUDjCXXJoaAF2wQcD/crrAJlU +zeOVZkSzRJXpjpG8kZhKgSgOpgfnpjDXAXWbkJuyDL2fqXLPxAyBq3ThgUHZT99s +QSd3AgRAAACBo4IBsDCCAawwDgYDVR0PAQH/BAQDAgIEMBgGCCsGAQUFBwEDBAww +CjAIBgYEAI5GAQEwSgYIKwYBBQUHAQEEPjA8MDoGCCsGAQUFBzABhi5odHRwOi8v +b2NzcC5ucmNhLWRzLmRlOjgwODAvb2NzcC1vY3NwcmVzcG9uZGVyMBIGA1UdIAQL +MAkwBwYFKyQIAQEwgbEGA1UdHwSBqTCBpjCBo6CBoKCBnYaBmmxkYXA6Ly9sZGFw +Lm5yY2EtZHMuZGU6Mzg5L0NOPUNSTCxPPUJ1bmRlc25ldHphZ2VudHVyLEM9REUs +ZGM9bGRhcCxkYz1ucmNhLWRzLGRjPWRlP2NlcnRpZmljYXRlUmV2b2NhdGlvbkxp +c3Q7YmluYXJ5P2Jhc2U/b2JqZWN0Q2xhc3M9Y1JMRGlzdHJpYnV0aW9uUG9pbnQw +GwYJKwYBBAHAbQMFBA4wDAYKKwYBBAHAbQMFATAPBgNVHRMBAf8EBTADAQH/MB8G +A1UdIwQYMBaAFATenX/fQ3KJumlJAfToSSjeAhlvMB0GA1UdDgQWBBQE3p1/30Ny +ibppSQH06Eko3gIZbzANBgkqhkiG9w0BAQ0FAAOCAQEADf4IOMHGmSpkPc1UP0LS +sK8Y/xXvOgdHPx4f2CpcgUKRRk+Ue9MKiZG0KCFaNK9Qpnxejuk42Iu3flC5kn8T +fPQWtxC3ZQqD8sd6EX/FDdfkHJFJ9rIYKiSG6m2PDBUcbpQZ9kwhC7qCKE1coUhb +FW3WbntkDtrQycz7ZyQ6Ip+PpRoxwToJqTsExb+8whukhOo1vsgdaMZS/6iwwVkt +rJvl7EWMJVWctm15iDQzp4sawgSOg7U5icyTb1q+FqI5KlAfd/dRbv2yvThiOl7+ +bfN9Brosoxtwi/uJO8vSGOCIUUkiGhIk7+OX+mvppTG+7R1Jn6Af6AOzGSbQz5Ks +Uw== +-----END CERTIFICATE----- + +Issuer ...: /CN=13R-CA 1:PN/O=Bundesnetzagentur/C=DE +Serial ...: 013C +Subject ..: /CN=13R-CA 1:PN/O=Bundesnetzagentur/C=DE + +-----BEGIN CERTIFICATE----- +MIIErTCCA5WgAwIBAgICATwwDQYJKoZIhvcNAQENBQAwPzELMAkGA1UEBhMCREUx +GjAYBgNVBAoMEUJ1bmRlc25ldHphZ2VudHVyMRQwEgYDVQQDDAsxM1ItQ0EgMTpQ +TjAeFw0wNzA1MjkxMTAyMzdaFw0xMjA1MjkxMDU1NTRaMD8xCzAJBgNVBAYTAkRF +MRowGAYDVQQKDBFCdW5kZXNuZXR6YWdlbnR1cjEUMBIGA1UEAwwLMTNSLUNBIDE6 +UE4wggEjMA0GCSqGSIb3DQEBAQUAA4IBEAAwggELAoIBAQCaXK0TY+Vp+Hxx8B9D +lrHkc0zRdhXNuDP4Cedl9e6wPwdi90HVEjDK3FoDv7UPBtgGwMzRUQVIz/etbcQr +tnGwSQlsDI/Q5R1HAh241+/rWYodi6OqNsNeb065RRBlwHAa4uvT3b/Cj/OJI5Kp +6qRPquK0iuMaFwuxGCxfhTLOmmGVNYOE7/9UzKXA2yvthY3jfmIm18l/z08PgUYj +rjENdrez3ZRgjZ/XsXSNw3B2K3cZQ+xRP4rqfkmfPO8T6UhOeoiQFx2v1PizBWRQ +uiUtFjrCiaDeBjo3kfGgbpdPnHzqUEoEOyAlsglFLJC9xaCiLtt2ic1/1OFFlNgQ +tLJLAgRAAACBo4IBsDCCAawwDgYDVR0PAQH/BAQDAgIEMBgGCCsGAQUFBwEDBAww +CjAIBgYEAI5GAQEwSgYIKwYBBQUHAQEEPjA8MDoGCCsGAQUFBzABhi5odHRwOi8v +b2NzcC5ucmNhLWRzLmRlOjgwODAvb2NzcC1vY3NwcmVzcG9uZGVyMBIGA1UdIAQL +MAkwBwYFKyQIAQEwgbEGA1UdHwSBqTCBpjCBo6CBoKCBnYaBmmxkYXA6Ly9sZGFw +Lm5yY2EtZHMuZGU6Mzg5L0NOPUNSTCxPPUJ1bmRlc25ldHphZ2VudHVyLEM9REUs +ZGM9bGRhcCxkYz1ucmNhLWRzLGRjPWRlP2NlcnRpZmljYXRlUmV2b2NhdGlvbkxp +c3Q7YmluYXJ5P2Jhc2U/b2JqZWN0Q2xhc3M9Y1JMRGlzdHJpYnV0aW9uUG9pbnQw +GwYJKwYBBAHAbQMFBA4wDAYKKwYBBAHAbQMFATAPBgNVHRMBAf8EBTADAQH/MB8G +A1UdIwQYMBaAFAYenQPZrutto05LK939ru/TEqiNMB0GA1UdDgQWBBQGHp0D2a7r +baNOSyvd/a7v0xKojTANBgkqhkiG9w0BAQ0FAAOCAQEADrtfqJ8lnYsVyV5YK/H/ +evPf9LY1AfuuQkMkm9UP9a9BBQINoIULB+n+gF/c0dxEboF74Ikp08dhDOq0mjvj +f0lpsBPgX/eN9IOWdMBs3rKIXn7suOoUtnBuFgW6fJ32CPTLUQd5Dqv9DizTiKMf +X66oMBQD784IKya1bLaJd7x1UXtP1h2DAej1scF9DbiDDDieuid0wyibrPDgjUN1 +tbYiLH2did0zZRLlp6gDpgh4t8Efqb7XDijKzQHvWKzr4IALTpYoD42yeslMa5yV +mm15NhiRGAdX+JbvYgfP3aDIMX/yoaMB8GXEUq7CmFhAwpxfhy/oyvswX5MyE8D2 +Lw== +-----END CERTIFICATE----- + + Issuer ...: /CN=8R-CA 1:PN/O=Regulierungsbeh?rde f?r Telekommunikation und Post/C=DE Serial ...: 01 Subject ..: /CN=8R-CA 1:PN/O=Regulierungsbeh?rde f?r Telekommunikation und Post/C=DE @@ -199,7 +266,6 @@ -----END CERTIFICATE----- - Issuer ...: /CN=D-TRUST Qualified Root CA 1 2006:PN/O=D-Trust GmbH/C=DE Serial ...: 00B95F Subject ..: /CN=D-TRUST Qualified Root CA 1 2006:PN/O=D-Trust GmbH/C=DE Modified: trunk/doc/examples/trustlist.txt =================================================================== --- trunk/doc/examples/trustlist.txt 2008-06-24 16:00:29 UTC (rev 4793) +++ trunk/doc/examples/trustlist.txt 2008-06-25 11:14:48 UTC (rev 4794) @@ -38,6 +38,15 @@ # Issuer: /CN=11R-CA 1:PN/O=Bundesnetzagentur/C=DE A0:8B:DF:3B:AA:EE:3F:9D:64:6C:47:81:23:21:D4:A6:18:81:67:1D S +# S/N: 0139 +# Issuer: /CN=12R-CA 1:PN/O=Bundesnetzagentur/C=DE +44:7E:D4:E3:9A:D7:92:E2:07:FA:53:1A:2E:F5:B8:02:5B:47:57:B0 de + +# S/N: 013C +# Issuer: /CN=13R-CA 1:PN/O=Bundesnetzagentur/C=DE +AC:A7:BE:45:1F:A6:BF:09:F2:D1:3F:08:7B:BC:EB:7F:46:A2:CC:8A de + + # S/N: 00B3963E0E6C2D65125853E970665402E5 # Issuer: /CN=S-TRUST Qualified Root CA 2008-001:PN # /O=Deutscher Sparkassen Verlag GmbH/L=Stuttgart/C=DE Modified: trunk/doc/qualified.txt =================================================================== --- trunk/doc/qualified.txt 2008-06-24 16:00:29 UTC (rev 4793) +++ trunk/doc/qualified.txt 2008-06-25 11:14:48 UTC (rev 4794) @@ -109,6 +109,31 @@ A0:8B:DF:3B:AA:EE:3F:9D:64:6C:47:81:23:21:D4:A6:18:81:67:1D de +# ID: 0x5B4757B0 +# S/N: 0139 +# Issuer: /CN=12R-CA 1:PN/O=Bundesnetzagentur/C=DE +# Subject: /CN=12R-CA 1:PN/O=Bundesnetzagentur/C=DE +# validity: 2007-05-25 11:01:44 through 2012-05-25 10:56:07 +# key type: 2048 bit RSA +# key usage: certSign +# policies: 1.3.36.8.1.1:N: +# chain length: unlimited +# [checked: 2008-06-25] +44:7E:D4:E3:9A:D7:92:E2:07:FA:53:1A:2E:F5:B8:02:5B:47:57:B0 de + +# ID: 0x46A2CC8A +# S/N: 013C +# Issuer: /CN=13R-CA 1:PN/O=Bundesnetzagentur/C=DE +# Subject: /CN=13R-CA 1:PN/O=Bundesnetzagentur/C=DE +# validity: 2007-05-29 11:02:37 through 2012-05-29 10:55:54 +# key type: 2048 bit RSA +# key usage: certSign +# policies: 1.3.36.8.1.1:N: +# chain length: unlimited +# [checked: 2008-06-25] +AC:A7:BE:45:1F:A6:BF:09:F2:D1:3F:08:7B:BC:EB:7F:46:A2:CC:8A de + + # # D-Trust root certificates. Probably by shifting a lot of Euros to # laywer companies, German CAs achieved to get the permission to Property changes on: trunk/doc/qualified.txt ___________________________________________________________________ Name: gpg:signature - -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.8 (GNU/Linux) iEYEABECAAYFAkefYsgACgkQzT/NXj1SwoI+/wCeNYbFKlAPqVP9AZ+GBzsANnLv 18YAn1KYjowfJ4ZMFYFNlcr8jdF185oM =gSzo -----END PGP SIGNATURE----- + -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEABECAAYFAkhiGIkACgkQzT/NXj1SwoJvcACg/t+2G6gx4ko5pqwCAGCSQxDh hYMAoN3VQSEPWAUTJRd0gLxCW0+zj5FH =XO6S -----END PGP SIGNATURE----- From cvs at cvs.gnupg.org Wed Jun 25 18:52:38 2008 From: cvs at cvs.gnupg.org (svn author marcus) Date: Wed, 25 Jun 2008 18:52:38 +0200 Subject: [svn] gpgme - r1321 - in trunk: assuan gpgme Message-ID: Author: marcus Date: 2008-06-25 18:52:31 +0200 (Wed, 25 Jun 2008) New Revision: 1321 Added: trunk/gpgme/gpgme-w32spawn.c Modified: trunk/assuan/ChangeLog trunk/assuan/assuan-pipe-connect.c trunk/gpgme/ChangeLog trunk/gpgme/Makefile.am trunk/gpgme/engine-gpgconf.c trunk/gpgme/engine-gpgsm.c trunk/gpgme/gpgme.h trunk/gpgme/posix-io.c trunk/gpgme/priv-io.h trunk/gpgme/rungpg.c trunk/gpgme/util.h trunk/gpgme/version.c trunk/gpgme/w32-glib-io.c trunk/gpgme/w32-io.c trunk/gpgme/w32-qt-io.cpp trunk/gpgme/w32-util.c Log: assuan/ 2008-06-25 Marcus Brinkmann * assuan-pipe-connect.c (struct spawn_fd_item_s): Add new members. (HANDLE_TRANSLATION): New macro. (pipe_connect_gpgme): Adjust caller of _gpgme_io_spawn. [HANDLE_TRANSLATION]: Return translated handles. gpgme/ 2008-06-25 Marcus Brinkmann * gpgme-w32spawn.c: New file. * Makefile.am (libexec_PROGRAMS) [HAVE_W32_SYSTEM]: New variable with gpgme-w32spawn. * engine-gpgsm.c (gpgsm_new): Use server translated handles. (gpgsm_set_locale): Return early if locale value is NULL. * util.h (_gpgme_mkstemp) (_gpgme_get_w32spawn_path) [HAVE_W32_SYSTEM]: New function prototypes. * w32-util.c: Include , and . (letters, mkstemp, _gpgme_mkstemp, _gpgme_get_w32spawn_path): New functions. * rungpg.c (gpg_decrypt, gpg_encrypt, gpg_encrypt_sign) (gpg_genkey, gpg_import, gpg_verify, gpg_sign): Pass data over special filename FD rather than stdin. (struct arg_and_data_s): Add member ARG_LOCP. (struct fd_data_map_s): Add member ARG_LOC. (struct engine_gpg): Add member ARG_LOC to status and colon. (_add_arg, add_arg_with_locp): New function. (add_arg_ext): Reimplement in terms of _add_arg. (gpg_new): Remember argument location for status FD. (build_argv): Set argument location if requested. Also set argument location of fd_data_map for data items. (start): Adjust caller of _gpgme_io_spawn. * priv-io.h (struct spawn_fd_item_s): Add members peer_name and arg_loc. (_gpgme_io_spawn): Remove parent fd list argument. * posix-io.c (get_max_fds): New function. (_gpgme_io_dup): Add tracing. (_gpgme_io_spawn): Remove parent fd list. Change meaning of child fd list to contain all child fds that should be inherited. Close all other file descriptors after fork. * w32-io.c, w32-glib-io.c, w32-qt-io.c(_gpgme_io_spawn): Remove parent fd list. Change meaning of child fd list to contain all child fds that should be inherited. Do not inherit any file descriptors, but DuplicateHandle them. Spawn process through wrapper process. Provide wrapper process with a temporary file containing handle translation data. Return translated handle names. * w32-io.c (reader): Add more tracing output. (_gpgme_io_read): Likewise. * engine-gpgconf.c (gpgconf_read): Adjust caller of _gpgme_io_spawn. * version.c (_gpgme_get_program_version): Likewise. [The diff below has been truncated] Modified: trunk/assuan/ChangeLog =================================================================== --- trunk/assuan/ChangeLog 2008-06-25 01:44:50 UTC (rev 1320) +++ trunk/assuan/ChangeLog 2008-06-25 16:52:31 UTC (rev 1321) @@ -1,3 +1,10 @@ +2008-06-25 Marcus Brinkmann + + * assuan-pipe-connect.c (struct spawn_fd_item_s): Add new members. + (HANDLE_TRANSLATION): New macro. + (pipe_connect_gpgme): Adjust caller of _gpgme_io_spawn. + [HANDLE_TRANSLATION]: Return translated handles. + 2008-02-14 Werner Koch * assuan-pipe-connect.c (_gpgme_io_spawn): Adjust prototype. Modified: trunk/gpgme/ChangeLog =================================================================== --- trunk/gpgme/ChangeLog 2008-06-25 01:44:50 UTC (rev 1320) +++ trunk/gpgme/ChangeLog 2008-06-25 16:52:31 UTC (rev 1321) @@ -1,3 +1,49 @@ +2008-06-25 Marcus Brinkmann + + * gpgme-w32spawn.c: New file. + * Makefile.am (libexec_PROGRAMS) [HAVE_W32_SYSTEM]: New variable + with gpgme-w32spawn. + * engine-gpgsm.c (gpgsm_new): Use server translated handles. + (gpgsm_set_locale): Return early if locale value is NULL. + * util.h (_gpgme_mkstemp) + (_gpgme_get_w32spawn_path) [HAVE_W32_SYSTEM]: New function + prototypes. + * w32-util.c: Include , and . + (letters, mkstemp, _gpgme_mkstemp, _gpgme_get_w32spawn_path): New + functions. + * rungpg.c (gpg_decrypt, gpg_encrypt, gpg_encrypt_sign) + (gpg_genkey, gpg_import, gpg_verify, gpg_sign): Pass data over + special filename FD rather than stdin. + (struct arg_and_data_s): Add member ARG_LOCP. + (struct fd_data_map_s): Add member ARG_LOC. + (struct engine_gpg): Add member ARG_LOC to status and colon. + (_add_arg, add_arg_with_locp): New function. + (add_arg_ext): Reimplement in terms of _add_arg. + (gpg_new): Remember argument location for status FD. + (build_argv): Set argument location if requested. Also set + argument location of fd_data_map for data items. + (start): Adjust caller of _gpgme_io_spawn. + * priv-io.h (struct spawn_fd_item_s): Add members peer_name and + arg_loc. + (_gpgme_io_spawn): Remove parent fd list argument. + * posix-io.c (get_max_fds): New function. + (_gpgme_io_dup): Add tracing. + (_gpgme_io_spawn): Remove parent fd list. Change meaning of child + fd list to contain all child fds that should be inherited. Close + all other file descriptors after fork. + * w32-io.c, w32-glib-io.c, w32-qt-io.c(_gpgme_io_spawn): Remove + parent fd list. Change meaning of child fd list to contain all + child fds that should be inherited. Do not inherit any file + descriptors, but DuplicateHandle them. Spawn process through + wrapper process. Provide wrapper process with a temporary file + containing handle translation data. Return translated handle + names. + * w32-io.c (reader): Add more tracing output. + (_gpgme_io_read): Likewise. + * engine-gpgconf.c (gpgconf_read): Adjust caller of + _gpgme_io_spawn. + * version.c (_gpgme_get_program_version): Likewise. + 2008-06-20 Werner Koch * engine-gpgconf.c (gpgconf_read): Change ARGV initialization for Modified: trunk/assuan/assuan-pipe-connect.c =================================================================== --- trunk/assuan/assuan-pipe-connect.c 2008-06-25 01:44:50 UTC (rev 1320) +++ trunk/assuan/assuan-pipe-connect.c 2008-06-25 16:52:31 UTC (rev 1321) @@ -41,10 +41,19 @@ #ifdef _ASSUAN_IN_GPGME_BUILD_ASSUAN +/* From GPGME priv-io.h */ +struct spawn_fd_item_s +{ + int fd; + int dup_to; + int peer_name; + int arg_loc; +}; + + int _gpgme_io_pipe (int filedes[2], int inherit_idx); int _gpgme_io_spawn (const char *path, char **argv, - struct spawn_fd_item_s *fd_child_list, - struct spawn_fd_item_s *fd_parent_list, pid_t *r_pid); + struct spawn_fd_item_s *fd_list, pid_t *r_pid); #endif /* Hacks for Slowaris. */ @@ -566,13 +575,6 @@ #define pipe_connect pipe_connect_gpgme -/* From GPGME priv-io.h */ -struct spawn_fd_item_s -{ - int fd; - int dup_to; -}; - /* W32 version of the pipe connection code. */ static assuan_error_t pipe_connect_gpgme (assuan_context_t *ctx, @@ -583,14 +585,25 @@ { assuan_error_t err; int res; + int idx; + int nr; int rp[2]; int wp[2]; char mypidstr[50]; - struct spawn_fd_item_s child_fds[3]; /* stdin, stdout, terminating -1 */ + struct spawn_fd_item_s *child_fds; if (!ctx || !name || !argv || !argv[0]) return _assuan_error (ASSUAN_Invalid_Value); + /* stdin, stdout, terminating -1 */ + nr = 3; + for (idx = 0; fd_child_list[idx] != -1; idx++) + nr++; + + child_fds = calloc (nr, sizeof *child_fds); + if (! child_fds) + return _assuan_error (ASSUAN_Out_Of_Core); + /* Actually, GPGME does this for us. But we plan to reuse this code in the generic assuan. */ fix_signals (); @@ -631,19 +644,28 @@ the old value, changeit, create proces and restore it, is not thread safe. */ - /* Parent list is same as client list. Note that GPGME will dup nul - to stderr even if the caller wants to inherit the handle for - it. */ + nr = 0; /* Server stdout is its write end of our read pipe. */ - child_fds[0].fd = rp[1]; - child_fds[0].dup_to = 1; + child_fds[nr].fd = rp[1]; + child_fds[nr].dup_to = 1; + nr++; /* Server stdin is its read end of our write pipe. */ - child_fds[1].fd = wp[0]; - child_fds[1].dup_to = 0; - child_fds[2].fd = -1; + child_fds[nr].fd = wp[0]; + child_fds[nr].dup_to = 0; + nr++; + for (idx = 0; fd_child_list[idx] != -1; idx++) + { + child_fds[nr].fd = fd_child_list[idx]; + child_fds[nr].dup_to = -1; + nr++; + } + + child_fds[nr].fd = -1; + child_fds[nr].dup_to = -1; + /* Start the process. */ - res = _gpgme_io_spawn (name, argv, child_fds, child_fds, NULL); + res = _gpgme_io_spawn (name, argv, child_fds, NULL); if (res == -1) { _assuan_log_printf ("CreateProcess failed: %s\n", strerror (errno)); @@ -653,6 +675,14 @@ _gpgme_io_close (wp[1]); return _assuan_error (ASSUAN_General_Error); } + else + { + /* For W32, the user needs to know the server-local names of the + inherited handles. Return them here. */ + for (idx = 0; fd_child_list[idx] != -1; idx++) + /* We add 2 to skip over the stdin/stdout pair. */ + fd_child_list[idx] = child_fds[idx + 2].peer_name; + } (*ctx)->pid = 0; /* We don't use the PID. */ Modified: trunk/gpgme/Makefile.am =================================================================== --- trunk/gpgme/Makefile.am 2008-06-25 01:44:50 UTC (rev 1320) +++ trunk/gpgme/Makefile.am 2008-06-25 16:52:31 UTC (rev 1321) @@ -142,6 +142,12 @@ if HAVE_W32_SYSTEM +# Windows provides us with an endless stream of Tough Love. To spawn +# processes with a controlled set of inherited handles, we need a +# wrapper process. +libexec_PROGRAMS = gpgme-w32spawn + + LTRCCOMPILE = $(LIBTOOL) --mode=compile $(RC) \ `echo $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) | \ sed -e 's/-I/--include-dir /g;s/-D/--define /g'` Modified: trunk/gpgme/engine-gpgconf.c =================================================================== --- trunk/gpgme/engine-gpgconf.c 2008-06-25 01:44:50 UTC (rev 1320) +++ trunk/gpgme/engine-gpgconf.c 2008-06-25 16:52:31 UTC (rev 1321) @@ -201,8 +201,8 @@ int linelen = 0; char *argv[4] = { NULL /* file_name */, NULL, NULL, NULL }; int rp[2]; - struct spawn_fd_item_s pfd[] = { {0, -1}, {-1, -1} }; - struct spawn_fd_item_s cfd[] = { {-1, 1 /* STDOUT_FILENO */}, {-1, -1} }; + struct spawn_fd_item_s cfd[] = { {-1, 1 /* STDOUT_FILENO */, -1, 0}, + {-1, -1} }; int status; int nread; char *mark = NULL; @@ -219,10 +219,9 @@ if (_gpgme_io_pipe (rp, 1) < 0) return gpg_error_from_syserror (); - pfd[0].fd = rp[1]; cfd[0].fd = rp[1]; - status = _gpgme_io_spawn (gpgconf->file_name, argv, cfd, pfd, NULL); + status = _gpgme_io_spawn (gpgconf->file_name, argv, cfd, NULL); if (status < 0) { _gpgme_io_close (rp[0]); @@ -645,7 +644,6 @@ int buflen = 0; char *argv[] = { NULL /* file_name */, arg1, arg2, 0 }; int rp[2]; - struct spawn_fd_item_s pfd[] = { {1, -1}, {-1, -1} }; struct spawn_fd_item_s cfd[] = { {-1, 0 /* STDIN_FILENO */}, {-1, -1} }; int status; int nwrite; @@ -659,10 +657,9 @@ if (_gpgme_io_pipe (rp, 0) < 0) return gpg_error_from_syserror (); - pfd[0].fd = rp[0]; cfd[0].fd = rp[0]; - status = _gpgme_io_spawn (gpgconf->file_name, argv, cfd, pfd, NULL); + status = _gpgme_io_spawn (gpgconf->file_name, argv, cfd, NULL); if (status < 0) { _gpgme_io_close (rp[0]); Modified: trunk/gpgme/engine-gpgsm.c =================================================================== --- trunk/gpgme/engine-gpgsm.c 2008-06-25 01:44:50 UTC (rev 1320) +++ trunk/gpgme/engine-gpgsm.c 2008-06-25 16:52:31 UTC (rev 1321) @@ -405,9 +405,6 @@ } gpgsm->input_cb.fd = fds[1]; gpgsm->input_cb.server_fd = fds[0]; - _gpgme_io_fd2str (gpgsm->input_cb.server_fd_str, - sizeof gpgsm->input_cb.server_fd_str, - gpgsm->input_cb.server_fd); if (_gpgme_io_pipe (fds, 1) < 0) { @@ -416,9 +413,6 @@ } gpgsm->output_cb.fd = fds[0]; gpgsm->output_cb.server_fd = fds[1]; - _gpgme_io_fd2str (gpgsm->output_cb.server_fd_str, - sizeof gpgsm->output_cb.server_fd_str, - gpgsm->output_cb.server_fd); if (_gpgme_io_pipe (fds, 0) < 0) { @@ -427,9 +421,6 @@ } gpgsm->message_cb.fd = fds[1]; gpgsm->message_cb.server_fd = fds[0]; - _gpgme_io_fd2str (gpgsm->message_cb.server_fd_str, - sizeof gpgsm->message_cb.server_fd_str, - gpgsm->message_cb.server_fd); child_fds[0] = gpgsm->input_cb.server_fd; child_fds[1] = gpgsm->output_cb.server_fd; @@ -455,10 +446,35 @@ err = assuan_pipe_connect (&gpgsm->assuan_ctx, file_name ? file_name : _gpgme_get_gpgsm_path (), argv, child_fds); + + /* On Windows, handles are inserted in the spawned process with + DuplicateHandle, and child_fds contains the server-local names + for the inserted handles when assuan_pipe_connect returns. */ + if (!err) + { + /* Note: We don't use _gpgme_io_fd2str here. On W32 the + returned handles are real W32 system handles, not whatever + GPGME uses internally (which may be a system handle, a C + library handle or a GLib/Qt channel. Confusing, yes, but + remember these are server-local names, so they are not part + of GPGME at all. */ + snprintf (gpgsm->input_cb.server_fd_str, + sizeof gpgsm->input_cb.server_fd_str, "%d", child_fds[0]); + snprintf (gpgsm->output_cb.server_fd_str, + sizeof gpgsm->output_cb.server_fd_str, "%d", child_fds[1]); + snprintf (gpgsm->message_cb.server_fd_str, + sizeof gpgsm->message_cb.server_fd_str, "%d", child_fds[2]); + } #endif if (err) goto leave; + /* assuan_pipe_connect in this case uses _gpgme_io_spawn which + closes the child fds for us. */ + gpgsm->input_cb.server_fd = -1; + gpgsm->output_cb.server_fd = -1; + gpgsm->message_cb.server_fd = -1; + err = _gpgme_getenv ("DISPLAY", &dft_display); if (err) goto leave; @@ -623,6 +639,10 @@ else return gpg_error (GPG_ERR_INV_VALUE); + /* FIXME: Reset value to default. */ + if (!value) + return 0; + if (asprintf (&optstr, "OPTION %s=%s", catstr, value) < 0) err = gpg_error_from_errno (errno); else @@ -633,6 +653,7 @@ if (err) err = map_assuan_error (err); } + return err; } Added: trunk/gpgme/gpgme-w32spawn.c =================================================================== --- trunk/gpgme/gpgme-w32spawn.c 2008-06-25 01:44:50 UTC (rev 1320) +++ trunk/gpgme/gpgme-w32spawn.c 2008-06-25 16:52:31 UTC (rev 1321) @@ -0,0 +1,434 @@ +/* gpgme-w32spawn.c - Wrapper to spawn a process under Windows. + Copyright (C) 2008 g10 Code GmbH + + This file is part of GPGME. + + GPGME 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. + + GPGME 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, see . + */ + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +struct spawn_fd_item_s +{ + int handle; + int dup_to; + int peer_name; + int arg_loc; +}; + + +static char * +build_commandline (char **argv) +{ + int i; + int n = 0; + char *buf; + char *p; + + /* We have to quote some things because under Windows the program + parses the commandline and does some unquoting. We enclose the + whole argument in double-quotes, and escape literal double-quotes + as well as backslashes with a backslash. We end up with a + trailing space at the end of the line, but that is harmless. */ + for (i = 0; argv[i]; i++) + { + p = argv[i]; + /* The leading double-quote. */ + n++; + while (*p) + { + /* An extra one for each literal that must be escaped. */ + if (*p == '\\' || *p == '"') + n++; + n++; + p++; + } + /* The trailing double-quote and the delimiter. */ + n += 2; + } + /* And a trailing zero. */ + n++; + + buf = p = malloc (n); + if (!buf) + return NULL; + for (i = 0; argv[i]; i++) + { + char *argvp = argv[i]; + + *(p++) = '"'; + while (*argvp) + { + if (*argvp == '\\' || *argvp == '"') + *(p++) = '\\'; + *(p++) = *(argvp++); + } + *(p++) = '"'; + *(p++) = ' '; + } + *(p++) = 0; + + return buf; +} + + +int +my_spawn (char **argv, struct spawn_fd_item_s *fd_list) +{ + SECURITY_ATTRIBUTES sec_attr; + PROCESS_INFORMATION pi = + { + NULL, /* returns process handle */ + 0, /* returns primary thread handle */ + 0, /* returns pid */ + 0 /* returns tid */ + }; + STARTUPINFO si; + char *envblock = NULL; + int cr_flags = CREATE_DEFAULT_ERROR_MODE + | GetPriorityClass (GetCurrentProcess ()); + int i; + char *arg_string; + int duped_stdin = 0; + int duped_stdout = 0; + int duped_stderr = 0; + HANDLE hnul = INVALID_HANDLE_VALUE; + /* FIXME. */ + int debug_me = 0; + + i = 0; + while (argv[i]) + { + fprintf (stderr, "argv[%2i] = %s\n", i, argv[i]); + i++; + } + + memset (&sec_attr, 0, sizeof sec_attr); + sec_attr.nLength = sizeof sec_attr; + sec_attr.bInheritHandle = FALSE; + + arg_string = build_commandline (argv); + if (!arg_string) + return -1; + + memset (&si, 0, sizeof si); + si.cb = sizeof (si); + si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; + si.wShowWindow = debug_me ? SW_SHOW : SW_HIDE; + si.hStdInput = GetStdHandle (STD_INPUT_HANDLE); + si.hStdOutput = GetStdHandle (STD_OUTPUT_HANDLE); + si.hStdError = GetStdHandle (STD_ERROR_HANDLE); + + fprintf (stderr, "spawning: %s\n", arg_string); + + for (i = 0; fd_list[i].handle != -1; i++) + { + /* The handle already is inheritable. */ + if (fd_list[i].dup_to == 0) + { + si.hStdInput = (HANDLE) fd_list[i].peer_name; + duped_stdin = 1; + fprintf (stderr, "dup 0x%x to stdin\n", fd_list[i].peer_name); + } + else if (fd_list[i].dup_to == 1) + { + si.hStdOutput = (HANDLE) fd_list[i].peer_name; + duped_stdout = 1; + fprintf (stderr, "dup 0x%x to stdout\n", fd_list[i].peer_name); + } + else if (fd_list[i].dup_to == 2) + { + si.hStdError = (HANDLE) fd_list[i].peer_name; + duped_stderr = 1; + fprintf (stderr, "dup 0x%x to stderr\n", fd_list[i].peer_name); + } + } + + if (!duped_stdin || !duped_stdout || !duped_stderr) + { + SECURITY_ATTRIBUTES sa; + + memset (&sa, 0, sizeof sa); + sa.nLength = sizeof sa; + sa.bInheritHandle = TRUE; + hnul = CreateFile ("nul", + GENERIC_READ|GENERIC_WRITE, + FILE_SHARE_READ|FILE_SHARE_WRITE, + &sa, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (hnul == INVALID_HANDLE_VALUE) + { + free (arg_string); + /* FIXME: Should translate the error code. */ + errno = EIO; + return -1; + } + /* Make sure that the process has a connected stdin. */ + if (!duped_stdin) + si.hStdInput = hnul; + /* Make sure that the process has a connected stdout. */ + if (!duped_stdout) + si.hStdOutput = hnul; + /* We normally don't want all the normal output. */ + if (!duped_stderr) + si.hStdError = hnul; + } + + cr_flags |= CREATE_SUSPENDED; + cr_flags |= DETACHED_PROCESS; + if (!CreateProcessA (argv[0], + arg_string, + &sec_attr, /* process security attributes */ + &sec_attr, /* thread security attributes */ + TRUE, /* inherit handles */ + cr_flags, /* creation flags */ + envblock, /* environment */ + NULL, /* use current drive/directory */ + &si, /* startup information */ + &pi)) /* returns process information */ From cvs at cvs.gnupg.org Wed Jun 25 19:44:29 2008 From: cvs at cvs.gnupg.org (svn author marcus) Date: Wed, 25 Jun 2008 19:44:29 +0200 Subject: [svn] GnuPG - r4795 - in trunk: common g10 Message-ID: Author: marcus Date: 2008-06-25 19:44:26 +0200 (Wed, 25 Jun 2008) New Revision: 4795 Modified: trunk/common/ChangeLog trunk/common/iobuf.c trunk/common/sysutils.c trunk/common/sysutils.h trunk/g10/ChangeLog trunk/g10/gpg.c Log: g10/ 2008-06-25 Marcus Brinkmann * gpg.c (enum cmd_and_opt_values): Remove option oEnableW32HandleTranslation. (opts): Remove option --enable-w32-handle-translation. (main): Remove variable w32_handle_translation. common/ 2008-06-25 Marcus Brinkmann Revert last three changes related to handle translation. * sysutils.c: (FD_TRANSLATE_MAX, fd_translate, fd_translate_len) (translate_table_init, translate_table_lookup): Removed. * iobuf.c (check_special_filename): Do not use translate_table_lookup. * sysutils.h (translate_table_init, translate_table_lookup): Remove prototypes. Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2008-06-25 11:14:48 UTC (rev 4794) +++ trunk/common/ChangeLog 2008-06-25 17:44:26 UTC (rev 4795) @@ -1,3 +1,14 @@ +2008-06-25 Marcus Brinkmann + + Revert last three changes related to handle translation. + * sysutils.c: + (FD_TRANSLATE_MAX, fd_translate, fd_translate_len) + (translate_table_init, translate_table_lookup): Removed. + * iobuf.c (check_special_filename): Do not use + translate_table_lookup. + * sysutils.h (translate_table_init, translate_table_lookup): + Remove prototypes. + 2008-06-19 Werner Koch * sysutils.c: Remove . Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2008-06-25 11:14:48 UTC (rev 4794) +++ trunk/g10/ChangeLog 2008-06-25 17:44:26 UTC (rev 4795) @@ -1,3 +1,10 @@ +2008-06-25 Marcus Brinkmann + + * gpg.c (enum cmd_and_opt_values): Remove option + oEnableW32HandleTranslation. + (opts): Remove option --enable-w32-handle-translation. + (main): Remove variable w32_handle_translation. + 2008-06-19 Werner Koch * gpg.c (gpgconf_list): Add "group". Modified: trunk/common/iobuf.c =================================================================== --- trunk/common/iobuf.c 2008-06-25 11:14:48 UTC (rev 4794) +++ trunk/common/iobuf.c 2008-06-25 17:44:26 UTC (rev 4795) @@ -1177,7 +1177,7 @@ for (i = 0; digitp (fname+i); i++) ; if (!fname[i]) - return translate_table_lookup (atoi (fname)); + return atoi (fname); } return -1; } Modified: trunk/common/sysutils.c =================================================================== --- trunk/common/sysutils.c 2008-06-25 11:14:48 UTC (rev 4794) +++ trunk/common/sysutils.c 2008-06-25 17:44:26 UTC (rev 4795) @@ -278,127 +278,6 @@ } - -/* Handle translation. On W32, we provide handle values on the - command line directly and using special file names such as - "-&HANDLE". However, in GPGME we can not directly inherit the - handles as this may interfere with other components in a - multithreaded application. Thus, we inject the handles after - creating the GPG process. The problem is that the handle numbers - change at injection, but it is too late to change the command line. - Hence this hack, which allows us to translate the handle values - in the command line to their new values after injection. - - Handles that must be translated are those occuring in special file - names (see iobuf.c::check_special_filename) as well as those given - directly to options (see translate_sys2libc_fd_int). */ - -/* For W32, we may have to translate handle values given on the - command line. */ -#define FD_TRANSLATE_MAX 8 -static struct -{ - int from; - int to; -} fd_translate[FD_TRANSLATE_MAX]; - -/* Number of entries used in fd_translate. */ -static int fd_translate_len; - - -/* Initialize the fd translation table. This reads one line from - stdin which is expected to be in the format "FROM TO [...]" where - each "FROM TO" pair are two handle numbers. Handle number FROM on - the command line is translated to handle number TO. - - Note that this function may be called while still being setuid. */ -void -translate_table_init (void) -{ - /* Hold roughly 8 pairs of 64 bit numbers in hex notation: - "0xFEDCBA9876543210 0xFEDCBA9876543210". 8*19*2 - 1 = 303. This - plans ahead for a time where a HANDLE is 64 bit. */ -#define TRANS_MAX 350 - char line[TRANS_MAX + 1]; - char *linep; - int idx; - int res; - int newl = 0; - - /* We always read one line from stdin. */ - for (idx = 0; idx < TRANS_MAX; idx++) - { - do - res = read (0, &line[idx], 1); - while (res == -1 && errno == EINTR); - if (res != 1) - break; - if (line[idx] == '\n') - { - newl = 1; - break; - } - } - if (!newl) - { - char buf[1]; - do - { - do - res = read (0, buf, 1); - while (res == -1 && errno == EINTR); - } - while (res == 1 && *buf != '\n'); - } - - line[idx] = '\0'; - linep = line; - - /* Now start to read mapping pairs. */ - for (idx = 0; idx < FD_TRANSLATE_MAX; idx++) - { - unsigned long from; - unsigned long to; - char *tail; - - while (spacep (linep)) - linep++; - if (*linep == '\0') - break; - from = strtoul (linep, &tail, 0); - if (tail == NULL || ! (*tail == '\0' || spacep (tail))) - break; - linep = tail; - - while (spacep (linep)) - linep++; - if (*linep == '\0') - break; - to = strtoul (linep, &tail, 0); - if (tail == NULL || ! (*tail == '\0' || spacep (tail))) - break; - linep = tail; - - fd_translate[idx].from = from; - fd_translate[idx].to = to; - fd_translate_len++; - } -} - - -/* Translate a handle number. */ -int -translate_table_lookup (int fd) -{ - int idx; - - for (idx = 0; idx < fd_translate_len; idx++) - if (fd_translate[idx].from == fd) - return fd_translate[idx].to; - return fd; -} - - /* This function is a NOP for POSIX systems but required under Windows as the file handles as returned by OS calls (like CreateFile) are different from the libc file descriptors (like open). This function @@ -424,7 +303,6 @@ #endif } - /* This is the same as translate_sys2libc_fd but takes an integer which is assumed to be such an system handle. */ int @@ -434,14 +312,8 @@ if (fd <= 2) return fd; /* Do not do this for error, stdin, stdout, stderr. */ - /* Note: If this function is ever used in a different context than - option parsing in the main function, a variant that does not do - translation probable needs to be used. */ - fd = translate_table_lookup (fd); - return translate_sys2libc_fd ((void*)fd, for_write); #else - fd = translate_table_lookup (fd); return fd; #endif } Modified: trunk/common/sysutils.h =================================================================== --- trunk/common/sysutils.h 2008-06-25 11:14:48 UTC (rev 4794) +++ trunk/common/sysutils.h 2008-06-25 17:44:26 UTC (rev 4795) @@ -43,16 +43,6 @@ const unsigned char *get_session_marker (size_t *rlen); /*int check_permissions (const char *path,int extension,int checkonly);*/ void gnupg_sleep (unsigned int seconds); - -/* Initialize the fd translation table. This reads one line from - stdin which is expected to be in the format "FROM TO [...]" where - each "FROM TO" pair are two handle numbers. Handle number FROM on - the command line is translated to handle number TO. */ -void translate_table_init (void); - -/* Translate a handle number. */ -int translate_table_lookup (int fd); - int translate_sys2libc_fd (gnupg_fd_t fd, int for_write); int translate_sys2libc_fd_int (int fd, int for_write); FILE *gnupg_tmpfile (void); Modified: trunk/g10/gpg.c =================================================================== --- trunk/g10/gpg.c 2008-06-25 11:14:48 UTC (rev 4794) +++ trunk/g10/gpg.c 2008-06-25 17:44:26 UTC (rev 4795) @@ -300,7 +300,6 @@ oNoAllowFreeformUID, oAllowSecretKeyImport, oEnableSpecialFilenames, - oEnableW32HandleTranslation, oNoLiteral, oSetFilesize, oHonorHttpProxy, @@ -665,7 +664,6 @@ { oAllowSecretKeyImport, "allow-secret-key-import", 0, "@" }, { oTryAllSecrets, "try-all-secrets", 0, "@" }, { oEnableSpecialFilenames, "enable-special-filenames", 0, "@" }, - { oEnableW32HandleTranslation, "enable-w32-handle-translation", 0, "@" }, { oNoExpensiveTrustChecks, "no-expensive-trust-checks", 0, "@" }, { aDeleteSecretAndPublicKeys, "delete-secret-and-public-keys",256, "@" }, { aRebuildKeydbCaches, "rebuild-keydb-caches", 256, "@"}, @@ -1878,7 +1876,6 @@ int eyes_only=0; int multifile=0; int pwfd = -1; - int w32_handle_translation = 0; int with_fpr = 0; /* make an option out of --fingerprint */ int any_explicit_recipient = 0; int require_secmem=0,got_secmem=0; @@ -1994,15 +1991,6 @@ { /* Not used */ } - else if (pargs.r_opt == oEnableW32HandleTranslation ) - { - /* We must initialize handle translation before parsing - the options. */ - if (! w32_handle_translation) - translate_table_init (); - w32_handle_translation = 1; - break; - } } #ifdef HAVE_DOSISH_SYSTEM @@ -2781,7 +2769,6 @@ case oEnableSpecialFilenames: iobuf_enable_special_filenames (1); break; - case oEnableW32HandleTranslation: break; case oNoExpensiveTrustChecks: opt.no_expensive_trust_checks=1; break; case oAutoCheckTrustDB: opt.no_auto_check_trustdb=0; break; case oNoAutoCheckTrustDB: opt.no_auto_check_trustdb=1; break; @@ -3346,7 +3333,6 @@ if( pwfd != -1 ) /* Read the passphrase now. */ read_passphrase_from_fd( pwfd ); - fname = argc? *argv : NULL; if(fname && utf8_strings) From cvs at cvs.gnupg.org Thu Jun 26 16:38:40 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 26 Jun 2008 16:38:40 +0200 Subject: [svn] gpgme - r1322 - trunk/gpgme Message-ID: Author: wk Date: 2008-06-26 16:38:39 +0200 (Thu, 26 Jun 2008) New Revision: 1322 Modified: trunk/gpgme/ChangeLog trunk/gpgme/w32-util.c Log: Fix incompatibility with non-recent mingw runtimes. Modified: trunk/gpgme/ChangeLog =================================================================== --- trunk/gpgme/ChangeLog 2008-06-25 16:52:31 UTC (rev 1321) +++ trunk/gpgme/ChangeLog 2008-06-26 14:38:39 UTC (rev 1322) @@ -1,3 +1,9 @@ +2008-06-26 Werner Koch + + * w32-util.c (_gpgme_mkstemp): Replace sprint by stpcpy. + (mkstemp): Need to use GetSystemTimeAsFileTime for better + compatibility. + 2008-06-25 Marcus Brinkmann * gpgme-w32spawn.c: New file. Modified: trunk/gpgme/w32-util.c =================================================================== --- trunk/gpgme/w32-util.c 2008-06-25 16:52:31 UTC (rev 1321) +++ trunk/gpgme/w32-util.c 2008-06-26 14:38:39 UTC (rev 1322) @@ -470,9 +470,11 @@ /* Get some more or less random data. */ { - struct timeval tv; - gettimeofday (&tv, NULL); - random_time_bits = ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec; + FILETIME ft; + + GetSystemTimeAsFileTime (&ft); + random_time_bits = (((uint64_t)ft.dwHighDateTime << 32) + | (uint64_t)ft.dwLowDateTime); } value += random_time_bits ^ getpid (); @@ -537,7 +539,7 @@ tmpname = malloc (strlen (tmp) + 13 + 1); if (!tmpname) return -1; - sprintf (tmpname, "%s\\gpgme-XXXXXX", tmp); + strcpy (stpcpy (tmpname, tmp), "\\gpgme-XXXXXX"); *fd = mkstemp (tmpname); if (fd < 0) return -1; From cvs at cvs.gnupg.org Thu Jun 26 16:41:57 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 26 Jun 2008 16:41:57 +0200 Subject: [svn] GpgOL - r260 - trunk/doc Message-ID: Author: wk Date: 2008-06-26 16:41:57 +0200 (Thu, 26 Jun 2008) New Revision: 260 Modified: trunk/doc/gpgol.texi Log: Minor doc updates. Modified: trunk/doc/gpgol.texi =================================================================== --- trunk/doc/gpgol.texi 2008-06-19 09:48:24 UTC (rev 259) +++ trunk/doc/gpgol.texi 2008-06-26 14:41:57 UTC (rev 260) @@ -173,7 +173,7 @@ @item ATTACHTYPE_FROMMOSS = 2 The attachment has been created from the original MOSS attachment. It - will automagically be recreated as needed. If the atatchment has + will automagically be recreated as needed. If the attachment has been created from an encrypted message, it is saved re-encrypted under a non-permanent session key. This session key is valid as long as the current Outlook porcess exists. @@ -342,7 +342,7 @@ GpgOL uses some tricks to make decryption of OpenPGP message better fit into the Outlook framework. This is due to a lack of proper Plugin API -for Outllok and becuase some features of Outlook --- meant as a security +for Outllok and because some features of Outlook --- meant as a security measure --- hinder a better implementation. That is not to say that Outlook will be less secure when used with GpgOL --- to the opposite: Due to encryption and digital signature reading and sending mail with @@ -354,28 +354,98 @@ @section MAPI Message Class Renaming -To implement S/MIME processing in GpgOL and inhibit XXXXXX +To implement S/MIME processing using its own engine, GpgOL needs to +inhibit Outlook from doing the S/MIME before the message is passed to +the ECE hooks. As usual this is done by changing the message class +(PR_MESSAGE_CLASS). For new message this happens right away at the +OnDelivery hook; for already existing messages GpgOL tries to detect +the case at several other places (which is less reliable but in general +works). + at noindent +The renaming is very straightforward: + at itemize @bullet + at item +If the message class is just @code{IPM.Note} extra tests are done to +figure out a suitable message class. This yields one of these new +message classes: + + at table @code + at item IPM.Note.GpgOL.OpaqueSigned + at item IPM.Note.GpgOL.OpaqueEncrypted + at item IPM.Note.GpgOL.ClearSigned + at item IPM.Note.GpgOL.PGPMessage + at end table + + at item +If the message class is either @code{IPM.Note.SMIME} or that one +followed by a dot and a subclass, the @code{SMIME} string is replaced +by @code{GpgOL}. + + at item +If the message class is @code{IPM.Note.Secure.CexSig} or + at code{IPM.Note.Secure.CexEnc} the class is changed depending on other +information to one of: + + at table @code + at item IPM.Note.GpgOL.OpaqueSigned + at item IPM.Note.GpgOL.OpaqueEncrypted + at item IPM.Note.GpgOL.MultipartSigned + at item IPM.Note.GpgOL + at item IPM.Note.GpgOL.ClearSigned + at item IPM.Note.GpgOL.PGPMessage + at end table + + at end itemize + +To revert these message class changes one need to replace any message +class prefix of @code{IPM.Note.GpgOL} by @code{IPM.Note.SMIME}. There +are two caveats however: + + at itemize + + at item +GpgOL copies or flags the original MOSS attachment as created by +Outlook to a new attachment with the attach type set to ATTACHTYPE_MOSS. +If such an attachment exists it should be converted back to the original +attachment (or used to convert the message back to RFC-822). It might +however not exist and in this case there should be only one attachment +at all as created by Outlook, so no further changes are required. + + at item +Inline PGP encrypted mails (@code{IPM.Note.GpgOL.PGPMessage}) might have +a wrong PR_BODY. This condition can be detected by the existance of an +attachment named @file{gpgolPGP.dat}, flagged as hidden and with the +attach type ATTACHTYPE_PGPBODY (See above under MAPI Properties). If +such an attachment exists, it should be copied to PR_BODY and may then +be deleted. + at end itemize + + at noindent +Note that reverting original CryptoEx message classes (@code{CexSig} +etc.) back is not possible. They are identical to GpgOL messages. + + @section MAPI Attachment Processing GpgOL creates a couple of attachments for the purpose of storing a parsed mail and to allow Outlook to display attachments in the usual way without sending them as plaintext to the storage. The attachments are only stored on the local disk while being opened from the attachment's -context menu for viewing. Almost all these attchments are ephemeral and +context menu for viewing. Almost all these attachments are ephemeral and may be deleted when not displayed. GpgOL re-creates them by parsing the -orginal message if neeeded. In fact they are always re-created after +original message if neeeded. In fact they are always re-created after Outlook as been started again. This is because the attachments holding the plaintext are symmetrical encrypted with an ephemeral session key, only valid as long as Outlook runs. -TODO +FIXME: Needs more documentation. @section MAPI PR_BODY Processing -GPOL does not use the PR_BODY property. This is because internal +GpgOL does not use the PR_BODY property. This is because internal Outlook syncronisation may change that property after the plaintext of a message has been displayed. In general this is not a problem because the messages processed by GpgOL do not use that property (the orginal @@ -420,7 +490,7 @@ To avoid attacks by importing TNEF data with certain GpgOL internal properties, a MAPI provider may want to filter them out when receiving a -message from an external location. It is not yet clear whetehr this is +message from an external location. It is not yet clear whether this is really needed. FIXME. @@ -429,13 +499,6 @@ - - - - - - - @c xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx @c @c A P P E N D I X From cvs at cvs.gnupg.org Thu Jun 26 21:09:10 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 26 Jun 2008 21:09:10 +0200 Subject: [svn] GnuPG - r4796 - in trunk: . common jnlib scd sm Message-ID: Author: wk Date: 2008-06-26 21:09:07 +0200 (Thu, 26 Jun 2008) New Revision: 4796 Modified: trunk/NEWS trunk/TODO trunk/common/ChangeLog trunk/common/estream.c trunk/jnlib/ChangeLog trunk/jnlib/stringhelp.c trunk/scd/ChangeLog trunk/scd/app-dinsig.c trunk/sm/ChangeLog trunk/sm/gpgsm.c trunk/sm/gpgsm.h trunk/sm/keylist.c trunk/sm/qualified.c trunk/sm/sign.c Log: Start support of TCOS 3 cards. Support restriction attribute. Fix utf-8 printing problems. Use AES by default. [The diff below has been truncated] Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2008-06-25 17:44:26 UTC (rev 4795) +++ trunk/common/ChangeLog 2008-06-26 19:09:07 UTC (rev 4796) @@ -1,3 +1,9 @@ +2008-06-26 Werner Koch + + * estream.c (es_write_sanitized): Loose check for control + characters to better cope with utf-8. The range 0x80..0x9f is + nowadays not anymore accidently used for control charaters. + 2008-06-25 Marcus Brinkmann Revert last three changes related to handle translation. Modified: trunk/jnlib/ChangeLog =================================================================== --- trunk/jnlib/ChangeLog 2008-06-25 17:44:26 UTC (rev 4795) +++ trunk/jnlib/ChangeLog 2008-06-26 19:09:07 UTC (rev 4796) @@ -1,3 +1,9 @@ +2008-06-26 Werner Koch + + * stringhelp.c (print_sanitized_buffer2): Loose check for control + characters to better cope with utf-8. The range 0x80..0x9f is + nowadays not anymore accidently used for control charaters. + 2008-06-13 Werner Koch * dotlock.c: Reformat code and implement locking for W32. Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2008-06-25 17:44:26 UTC (rev 4795) +++ trunk/scd/ChangeLog 2008-06-26 19:09:07 UTC (rev 4796) @@ -1,3 +1,7 @@ +2008-06-25 Werner Koch + + * app-dinsig.c (do_sign): Allow for SHA256. + 2008-06-24 Werner Koch * app-common.h (app_ctx_s): Renamed reset_mode parameter of Modified: trunk/sm/ChangeLog =================================================================== --- trunk/sm/ChangeLog 2008-06-25 17:44:26 UTC (rev 4795) +++ trunk/sm/ChangeLog 2008-06-26 19:09:07 UTC (rev 4796) @@ -1,3 +1,16 @@ +2008-06-25 Werner Koch + + * sign.c (gpgsm_sign): Revamp the hash algorithm selection. + * gpgsm.h (struct certlist_s): Add field HASH_ALGO and HASH_ALGO_OID. + + * qualified.c (gpgsm_qualified_consent): Fix double free. + + * gpgsm.c (main): Change default cipher algo to AES. + + * keylist.c (print_utf8_extn_raw, print_utf8_extn): New. + (list_cert_raw, list_cert_std): Print the TeleSec restriction + extension. + 2008-06-23 Werner Koch * encrypt.c (encode_session_key): Replace xmalloc by xtrymalloc. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2008-06-25 17:44:26 UTC (rev 4795) +++ trunk/NEWS 2008-06-26 19:09:07 UTC (rev 4796) @@ -25,7 +25,9 @@ * New control statement %ask-passphrase for the unattended key generation of gpg2. + * gpgsm now uses AES by default. + Noteworthy changes in version 2.0.9 (2008-03-26) ------------------------------------------------ Modified: trunk/TODO =================================================================== --- trunk/TODO 2008-06-25 17:44:26 UTC (rev 4795) +++ trunk/TODO 2008-06-26 19:09:07 UTC (rev 4796) @@ -66,7 +66,8 @@ We should check the card status in open-card to make this smoother. Needs to be integrated with the status file update, though. It is not a real problem because application will get a card removed - status and should the send a reset to try solving the problem. + status and should then send a reset to try solving the problem. +** Resolve fixme in do_sign of app-dinsig. ** Add a regression test to check the extkeyusage. Modified: trunk/common/estream.c =================================================================== --- trunk/common/estream.c 2008-06-25 17:44:26 UTC (rev 4795) +++ trunk/common/estream.c 2008-06-26 19:09:07 UTC (rev 4796) @@ -3074,7 +3074,7 @@ for (; length; length--, p++, count++) { if (*p < 0x20 - || (*p >= 0x7f && *p < 0xa0) + || *p == 0x7f || (delimiters && (strchr (delimiters, *p) || *p == '\\'))) { Modified: trunk/jnlib/stringhelp.c =================================================================== --- trunk/jnlib/stringhelp.c 2008-06-25 17:44:26 UTC (rev 4795) +++ trunk/jnlib/stringhelp.c 2008-06-26 19:09:07 UTC (rev 4796) @@ -406,9 +406,8 @@ for (; length; length--, p++, count++) { - /* Fixme: Check whether *p < 0xa0 is correct for utf8 encoding. */ if (*p < 0x20 - || (*p >= 0x7f && *p < 0xa0) + || *p == 0x7f || *p == delim || *p == delim2 || ((delim || delim2) && *p=='\\')) Modified: trunk/scd/app-dinsig.c =================================================================== --- trunk/scd/app-dinsig.c 2008-06-25 17:44:26 UTC (rev 4795) +++ trunk/scd/app-dinsig.c 2008-06-26 19:09:07 UTC (rev 4796) @@ -1,5 +1,5 @@ /* app-dinsig.c - The DINSIG (DIN V 66291-1) card application. - * Copyright (C) 2002, 2004, 2005, 2007 Free Software Foundation, Inc. + * Copyright (C) 2002, 2004, 2005, 2007, 2008 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -397,14 +397,20 @@ static unsigned char rmd160_prefix[15] = /* Object ID is 1.3.36.3.2.1 */ { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x24, 0x03, 0x02, 0x01, 0x05, 0x00, 0x04, 0x14 }; + static unsigned char sha256_prefix[19] = /* OID is 2.16.840.1.101.3.4.2.1 */ + { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, + 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, + 0x00, 0x04, 0x20 }; int rc; int fid; - unsigned char data[35]; /* Must be large enough for a SHA-1 digest - + the largest OID _prefix above. */ + unsigned char data[19+32]; /* Must be large enough for a SHA-256 digest + + the largest OID _prefix above. */ + int datalen; if (!keyidstr || !*keyidstr) return gpg_error (GPG_ERR_INV_VALUE); - if (indatalen != 20 && indatalen != 16 && indatalen != 35) + if (indatalen != 20 && indatalen != 16 && indatalen != 32 + && indatalen != (15+20) && indatalen != (19+32)) return gpg_error (GPG_ERR_INV_VALUE); /* Check that the provided ID is vaid. This is not really needed @@ -421,7 +427,8 @@ return gpg_error (GPG_ERR_NOT_FOUND); /* Prepare the DER object from INDATA. */ - if (indatalen == 35) + datalen = 35; + if (indatalen == 15+20) { /* Alright, the caller was so kind to send us an already prepared DER object. Check that it is what we want and that @@ -434,25 +441,104 @@ return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); memcpy (data, indata, indatalen); } + else if (indatalen == 19+32) + { + /* Alright, the caller was so kind to send us an already + prepared DER object. Check that it is what we want and that + it matches the hash algorithm. */ + datalen = indatalen; + if (hashalgo == GCRY_MD_SHA256 && !memcmp (indata, sha256_prefix, 19)) + ; + else if (hashalgo == GCRY_MD_SHA1 && !memcmp (indata, sha256_prefix, 19)) + { + /* Fixme: This is a kludge. A better solution is not to use + SHA1 as default but use an autodetection. However this + needs changes in all app-*.c */ + hashalgo = GCRY_MD_SHA256; + datalen = indatalen; + } + else + return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); + memcpy (data, indata, indatalen); + } else { + int len = 15; if (hashalgo == GCRY_MD_SHA1) - memcpy (data, sha1_prefix, 15); + memcpy (data, sha1_prefix, len); else if (hashalgo == GCRY_MD_RMD160) - memcpy (data, rmd160_prefix, 15); + memcpy (data, rmd160_prefix, len); + else if (hashalgo == GCRY_MD_SHA256) + { + len = 19; + datalen = len + indatalen; + memcpy (data, sha256_prefix, len); + } else return gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM); - memcpy (data+15, indata, indatalen); + memcpy (data+len, indata, indatalen); } rc = verify_pin (app, pincb, pincb_arg); if (!rc) - rc = iso7816_compute_ds (app->slot, data, 35, outdata, outdatalen); + rc = iso7816_compute_ds (app->slot, data, datalen, outdata, outdatalen); return rc; } +#if 0 +#warning test function - works but may brick your card +/* Handle the PASSWD command. CHVNOSTR is currently ignored; we + always use VHV0. RESET_MODE is not yet implemented. */ +static gpg_error_t +do_change_pin (app_t app, ctrl_t ctrl, const char *chvnostr, + unsigned int flags, + gpg_error_t (*pincb)(void*, const char *, char **), + void *pincb_arg) +{ + gpg_error_t err; + char *pinvalue; + const char *oldpin; + size_t oldpinlen; + if ((flags & APP_CHANGE_FLAG_RESET)) + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); + + if ((flags & APP_CHANGE_FLAG_NULLPIN)) + { + /* With the nullpin flag, we do not verify the PIN - it would fail + if the Nullpin is still set. */ + oldpin = "\0\0\0\0\0"; + oldpinlen = 6; + } + else + { + err = verify_pin (app, pincb, pincb_arg); + if (err) + return err; + oldpin = NULL; + oldpinlen = 0; + } + + /* TRANSLATORS: Do not translate the "|*|" prefixes but + keep it at the start of the string. We need this elsewhere + to get some infos on the string. */ + err = pincb (pincb_arg, _("|N|Initial New PIN"), &pinvalue); + if (err) + { + log_error (_("error getting new PIN: %s\n"), gpg_strerror (err)); + return err; + } + + err = iso7816_change_reference_data (app->slot, 0x81, + oldpin, oldpinlen, + pinvalue, strlen (pinvalue)); + xfree (pinvalue); + return err; +} + + + /* Select the DINSIG application on the card in SLOT. This function must be used before any other DINSIG application functions. */ gpg_error_t @@ -475,7 +561,7 @@ app->fnc.sign = do_sign; app->fnc.auth = NULL; app->fnc.decipher = NULL; - app->fnc.change_pin = NULL; + app->fnc.change_pin = NULL /*do_change_pin*/; app->fnc.check_pin = NULL; app->force_chv1 = 1; Modified: trunk/sm/gpgsm.c =================================================================== --- trunk/sm/gpgsm.c 2008-06-25 17:44:26 UTC (rev 4795) +++ trunk/sm/gpgsm.c 2008-06-26 19:09:07 UTC (rev 4796) @@ -987,7 +987,7 @@ create_dotlock (NULL); /* register locking cleanup */ i18n_init(); - opt.def_cipher_algoid = "3DES"; /*des-EDE3-CBC*/ + opt.def_cipher_algoid = "AES"; /*des-EDE3-CBC*/ opt.homedir = default_homedir (); Modified: trunk/sm/gpgsm.h =================================================================== --- trunk/sm/gpgsm.h 2008-06-25 17:44:26 UTC (rev 4795) +++ trunk/sm/gpgsm.h 2008-06-26 19:09:07 UTC (rev 4796) @@ -207,6 +207,8 @@ ksba_cert_t cert; int is_encrypt_to; /* True if the certificate has been set through the --encrypto-to option. */ + int hash_algo; /* Used to track the hash algorithm to use. */ + const char *hash_algo_oid; /* And the corresponding OID. */ }; typedef struct certlist_s *certlist_t; Modified: trunk/sm/keylist.c =================================================================== --- trunk/sm/keylist.c 2008-06-25 17:44:26 UTC (rev 4795) +++ trunk/sm/keylist.c 2008-06-26 19:09:07 UTC (rev 4796) @@ -1,6 +1,6 @@ /* keylist.c - Print certificates in various formats. * Copyright (C) 1998, 1999, 2000, 2001, 2003, - * 2004, 2005 Free Software Foundation, Inc. + * 2004, 2005, 2008 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -35,6 +35,7 @@ #include "keydb.h" #include "../kbx/keybox.h" /* for KEYBOX_FLAG_* */ #include "i18n.h" +#include "tlv.h" struct list_external_parm_s { @@ -77,12 +78,18 @@ }; +/* Do not print this extension in the list of extensions. This is set + for oids which are already available via ksba fucntions. */ +#define OID_FLAG_SKIP 1 +/* The extension is a simple UTF8String and should be printed. */ +#define OID_FLAG_UTF8 2 + /* A table mapping OIDs to a descriptive string. */ static struct { char *oid; char *name; - unsigned int flag; + unsigned int flag; /* A flag as described above. */ } oidtranstbl[] = { /* Algorithms. */ @@ -115,7 +122,11 @@ { "0.2.262.1.10.12.4", "telesecCRLFilteredExt" }, { "0.2.262.1.10.12.5", "telesecCRLFilterExt"}, { "0.2.262.1.10.12.6", "telesecNamingAuthorityExt" }, +#define OIDSTR_restriction \ + "1.3.36.8.3.8" + { OIDSTR_restriction, "restriction", OID_FLAG_UTF8 }, + /* PKIX private extensions. */ { "1.3.6.1.5.5.7.1.1", "authorityInfoAccess" }, { "1.3.6.1.5.5.7.1.2", "biometricInfo" }, @@ -135,12 +146,12 @@ { "1.3.6.1.5.5.7.48.5", "caRepository" }, /* X.509 id-ce */ - { "2.5.29.14", "subjectKeyIdentifier", 1}, - { "2.5.29.15", "keyUsage", 1 }, + { "2.5.29.14", "subjectKeyIdentifier", OID_FLAG_SKIP}, + { "2.5.29.15", "keyUsage", OID_FLAG_SKIP}, { "2.5.29.16", "privateKeyUsagePeriod" }, - { "2.5.29.17", "subjectAltName", 1 }, - { "2.5.29.18", "issuerAltName", 1 }, - { "2.5.29.19", "basicConstraints", 1}, + { "2.5.29.17", "subjectAltName", OID_FLAG_SKIP}, + { "2.5.29.18", "issuerAltName", OID_FLAG_SKIP}, + { "2.5.29.19", "basicConstraints", OID_FLAG_SKIP}, { "2.5.29.20", "cRLNumber" }, { "2.5.29.21", "cRLReason" }, { "2.5.29.22", "expirationDate" }, @@ -150,13 +161,13 @@ { "2.5.29.28", "issuingDistributionPoint" }, { "2.5.29.29", "certificateIssuer" }, { "2.5.29.30", "nameConstraints" }, - { "2.5.29.31", "cRLDistributionPoints", 1 }, - { "2.5.29.32", "certificatePolicies", 1 }, + { "2.5.29.31", "cRLDistributionPoints", OID_FLAG_SKIP}, + { "2.5.29.32", "certificatePolicies", OID_FLAG_SKIP}, { "2.5.29.32.0", "anyPolicy" }, { "2.5.29.33", "policyMappings" }, - { "2.5.29.35", "authorityKeyIdentifier", 1 }, + { "2.5.29.35", "authorityKeyIdentifier", OID_FLAG_SKIP}, { "2.5.29.36", "policyConstraints" }, - { "2.5.29.37", "extKeyUsage", 1 }, + { "2.5.29.37", "extKeyUsage", OID_FLAG_SKIP}, { "2.5.29.46", "freshestCRL" }, { "2.5.29.54", "inhibitAnyPolicy" }, @@ -561,6 +572,59 @@ } +static void +print_utf8_extn_raw (estream_t fp, int indent, + const unsigned char *der, size_t derlen) +{ + gpg_error_t err; + int class, tag, constructed, ndef; + size_t objlen, hdrlen; + + if (indent < 0) + indent = - indent; + + err = parse_ber_header (&der, &derlen, &class, &tag, &constructed, + &ndef, &objlen, &hdrlen); + if (!err && (objlen > derlen || tag != TAG_UTF8_STRING)) + err = gpg_error (GPG_ERR_INV_OBJ); + if (err) + { + es_fprintf (fp, "%*s[%s]\n", indent, "", gpg_strerror (err)); + return; + } + es_fprintf (fp, "%*s(%.*s)\n", indent, "", objlen, der); +} + + +static void +print_utf8_extn (estream_t fp, int indent, + const unsigned char *der, size_t derlen) +{ + gpg_error_t err; + int class, tag, constructed, ndef; + size_t objlen, hdrlen; + int indent_all; + + if ((indent_all = (indent < 0))) + indent = - indent; + + err = parse_ber_header (&der, &derlen, &class, &tag, &constructed, + &ndef, &objlen, &hdrlen); + if (!err && (objlen > derlen || tag != TAG_UTF8_STRING)) + err = gpg_error (GPG_ERR_INV_OBJ); + if (err) + { + es_fprintf (fp, "%*s[Error - %s]\n", + indent_all? indent:0, "", gpg_strerror (err)); + return; + } + es_fprintf (fp, "%*s\"", indent_all? indent:0, ""); + /* Fixme: we should implement word wrapping */ + es_write_sanitized (fp, der, objlen, "\"", NULL); + es_fputs ("\"\n", fp); +} + + /* List one certificate in raw mode useful to have a closer look at the certificate. This one does no beautification and only minimal output sanitation. It is mainly useful for debugging. */ @@ -581,6 +645,7 @@ const char *oid, *s; ksba_name_t name, name2; unsigned int reason; + const unsigned char *cert_der = NULL; es_fprintf (fp, " ID: 0x%08lX\n", gpgsm_get_short_fingerprint (cert)); @@ -892,11 +957,19 @@ unsigned int flag; s = get_oid_desc (oid, &flag); + if ((flag & OID_FLAG_SKIP)) + continue; - if (!(flag & 1)) - es_fprintf (fp, " %s: %s%s%s%s [%d octets]\n", - i? "critExtn":" extn", - oid, s?" (":"", s?s:"", s?")":"", (int)len); + es_fprintf (fp, " %s: %s%s%s%s [%d octets]\n", + i? "critExtn":" extn", + oid, s?" (":"", s?s:"", s?")":"", (int)len); + if ((flag & OID_FLAG_UTF8)) + { + if (!cert_der) + cert_der = ksba_cert_get_image (cert, NULL); + assert (cert_der); + print_utf8_extn_raw (fp, -15, cert_der+off, len); + } } @@ -938,7 +1011,11 @@ int is_ca, chainlen; unsigned int kusage; char *string, *p, *pend; + size_t off, len; + const char *oid; + const unsigned char *cert_der = NULL; + es_fprintf (fp, " ID: 0x%08lX\n", gpgsm_get_short_fingerprint (cert)); @@ -1053,6 +1130,21 @@ es_putc ('\n', fp); } + /* Print restrictions. */ + for (idx=0; !(err=ksba_cert_get_extension (cert, idx, + &oid, NULL, &off, &len));idx++) + { + if (!strcmp (oid, OIDSTR_restriction) ) + { + if (!cert_der) + cert_der = ksba_cert_get_image (cert, NULL); + assert (cert_der); + es_fputs (" restriction: ", fp); + print_utf8_extn (fp, 15, cert_der+off, len); + } + } + + /* Print policies. */ err = ksba_cert_get_cert_policies (cert, &string); if (gpg_err_code (err) != GPG_ERR_NO_DATA) { Modified: trunk/sm/qualified.c =================================================================== --- trunk/sm/qualified.c 2008-06-25 17:44:26 UTC (rev 4795) +++ trunk/sm/qualified.c 2008-06-26 19:09:07 UTC (rev 4796) @@ -215,7 +215,6 @@ err = 0; i18n_switchback (orig_codeset); - xfree (orig_codeset); xfree (subject); if (err) Modified: trunk/sm/sign.c =================================================================== --- trunk/sm/sign.c 2008-06-25 17:44:26 UTC (rev 4795) +++ trunk/sm/sign.c 2008-06-26 19:09:07 UTC (rev 4796) @@ -1,5 +1,5 @@ /* sign.c - Sign a message - * Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. + * Copyright (C) 2001, 2002, 2003, 2008 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -396,7 +396,45 @@ release_signerlist = 1; } + /* Figure out the hash algorithm to use. We do not want to use the + one for the certificate but if possible an OID for the plain + algorithm. */ + for (i=0, cl=signerlist; cl; cl = cl->next, i++) + { From cvs at cvs.gnupg.org Thu Jun 26 21:21:46 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 26 Jun 2008 21:21:46 +0200 Subject: [svn] GnuPG - r4797 - in trunk: scd sm Message-ID: Author: wk Date: 2008-06-26 21:21:45 +0200 (Thu, 26 Jun 2008) New Revision: 4797 Modified: trunk/scd/app-dinsig.c trunk/sm/keylist.c Log: Minor fixes. Modified: trunk/scd/app-dinsig.c =================================================================== --- trunk/scd/app-dinsig.c 2008-06-26 19:09:07 UTC (rev 4796) +++ trunk/scd/app-dinsig.c 2008-06-26 19:21:45 UTC (rev 4797) @@ -536,9 +536,9 @@ xfree (pinvalue); return err; } +#endif /*0*/ - /* Select the DINSIG application on the card in SLOT. This function must be used before any other DINSIG application functions. */ gpg_error_t Modified: trunk/sm/keylist.c =================================================================== --- trunk/sm/keylist.c 2008-06-26 19:09:07 UTC (rev 4796) +++ trunk/sm/keylist.c 2008-06-26 19:21:45 UTC (rev 4797) @@ -614,8 +614,8 @@ err = gpg_error (GPG_ERR_INV_OBJ); if (err) { - es_fprintf (fp, "%*s[Error - %s]\n", - indent_all? indent:0, "", gpg_strerror (err)); + es_fprintf (fp, "%*s[%s%s]\n", + indent_all? indent:0, "", _("Error - "), gpg_strerror (err)); return; } es_fprintf (fp, "%*s\"", indent_all? indent:0, ""); From cvs at cvs.gnupg.org Fri Jun 27 18:07:36 2008 From: cvs at cvs.gnupg.org (svn author marcus) Date: Fri, 27 Jun 2008 18:07:36 +0200 Subject: [svn] gpgme - r1323 - in trunk: doc gpgme Message-ID: Author: marcus Date: 2008-06-27 18:07:33 +0200 (Fri, 27 Jun 2008) New Revision: 1323 Modified: trunk/doc/ChangeLog trunk/doc/gpgme.texi trunk/gpgme/ChangeLog trunk/gpgme/context.h trunk/gpgme/gpgme.c trunk/gpgme/gpgme.h trunk/gpgme/op-support.c trunk/gpgme/wait-global.c trunk/gpgme/wait-private.c trunk/gpgme/wait-user.c Log: 2008-06-27 Marcus Brinkmann * gpgme.texi (Cancellation): Document gpgme_cancel_async. gpgme/ 2008-06-27 Marcus Brinkmann * context.h: Include "sema.h". (struct gpgme_context): New members lock and canceled. * gpgme.c (gpgme_new): Initialize lock. (gpgme_release): Destroy lock. (gpgme_cancel_async): New function. * op-support.c (_gpgme_op_reset): Reset the canceled flag. * wait-global.c (gpgme_wait): Check cancel flag before processing any I/O callbacks. * wait-private.c (_gpgme_wait_on_condition): Likewise. * wait-user.c (_gpgme_user_io_cb_handler): Likewise. Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2008-06-26 14:38:39 UTC (rev 1322) +++ trunk/doc/ChangeLog 2008-06-27 16:07:33 UTC (rev 1323) @@ -1,3 +1,7 @@ +2008-06-27 Marcus Brinkmann + + * gpgme.texi (Cancellation): Document gpgme_cancel_async. + 2008-06-25 Werner Koch * gpgme.texi (Listing Keys): Updated example to the current API. Modified: trunk/gpgme/ChangeLog =================================================================== --- trunk/gpgme/ChangeLog 2008-06-26 14:38:39 UTC (rev 1322) +++ trunk/gpgme/ChangeLog 2008-06-27 16:07:33 UTC (rev 1323) @@ -1,3 +1,16 @@ +2008-06-27 Marcus Brinkmann + + * context.h: Include "sema.h". + (struct gpgme_context): New members lock and canceled. + * gpgme.c (gpgme_new): Initialize lock. + (gpgme_release): Destroy lock. + (gpgme_cancel_async): New function. + * op-support.c (_gpgme_op_reset): Reset the canceled flag. + * wait-global.c (gpgme_wait): Check cancel flag before processing + any I/O callbacks. + * wait-private.c (_gpgme_wait_on_condition): Likewise. + * wait-user.c (_gpgme_user_io_cb_handler): Likewise. + 2008-06-26 Werner Koch * w32-util.c (_gpgme_mkstemp): Replace sprint by stpcpy. Modified: trunk/doc/gpgme.texi =================================================================== --- trunk/doc/gpgme.texi 2008-06-26 14:38:39 UTC (rev 1322) +++ trunk/doc/gpgme.texi 2008-06-27 16:07:33 UTC (rev 1323) @@ -5488,13 +5488,15 @@ @cindex aborting operations @cindex cancelling operations -Sometimes you do not want to wait for an operation to finish. If you -use external I/O callbacks, you can cancel a pending operation. -However, you must ensure that no other thread is currently using the -context in which the operation you want to cancel runs. This includes -callback handlers. So your external event loop must either be halted -or otherwise it must be guaranteed that no installed I/O callbacks are -run for this context. +Sometimes you do not want to wait for an operation to finish. + at acronym{GPGME} provides two different functions to achieve that. The +function @code{gpgme_cancel} takes effect immediately. When it +returns, the operation is effectively canceled. However, it has some +limitations and can not be used with synchronous operations. In +contrast, the function @code{gpgme_cancel_async} can be used with any +context and from any thread, but it is not guaranteed to take effect +immediately. Instead, cancellation occurs at the next possible time +(typically the next time I/O occurs in the target context). @deftypefun gpgme_ctx_t gpgme_cancel (@w{gpgme_ctx_t @var{ctx}}) The function @code{gpgme_cancel} attempts to cancel a pending @@ -5517,6 +5519,18 @@ case the state of @var{ctx} is not modified). @end deftypefun + + at deftypefun gpgme_ctx_t gpgme_cancel_async (@w{gpgme_ctx_t @var{ctx}}) +The function @code{gpgme_cancel} attempts to cancel a pending +operation in the context @var{ctx}. This can be called by any thread +at any time after starting an operation on the context, but will not +take effect immediately. The actual cancellation happens at the next +time GPGME processes I/O in that context. + +The function returns an error code if the cancellation failed (in this +case the state of @var{ctx} is not modified). + at end deftypefun + @c ********************************************************** @c ******************* Appendices ************************* @c ********************************************************** Modified: trunk/gpgme/context.h =================================================================== --- trunk/gpgme/context.h 2008-06-26 14:38:39 UTC (rev 1322) +++ trunk/gpgme/context.h 2008-06-27 16:07:33 UTC (rev 1323) @@ -25,6 +25,7 @@ #include "gpgme.h" #include "engine.h" #include "wait.h" +#include "sema.h" /* Operations might require to remember arbitrary information and data @@ -63,6 +64,11 @@ be performed (sequentially). */ struct gpgme_context { + DECLARE_LOCK (lock); + + /* True if the context was canceled asynchronously. */ + int canceled; + /* The engine info for this context. */ gpgme_engine_info_t engine_info; Modified: trunk/gpgme/gpgme.c =================================================================== --- trunk/gpgme/gpgme.c 2008-06-26 14:38:39 UTC (rev 1322) +++ trunk/gpgme/gpgme.c 2008-06-27 16:07:33 UTC (rev 1323) @@ -54,6 +54,8 @@ if (!ctx) return TRACE_ERR (gpg_error_from_errno (errno)); + INIT_LOCK (ctx->lock); + _gpgme_engine_info_copy (&ctx->engine_info); if (!ctx->engine_info) { @@ -121,6 +123,22 @@ return TRACE_ERR (0); } + +/* Cancel a pending operation asynchronously. */ +gpgme_error_t +gpgme_cancel_async (gpgme_ctx_t ctx) +{ + gpgme_error_t err; + TRACE_BEG (DEBUG_CTX, "gpgme_cancel_async", ctx); + + LOCK (ctx->lock); + ctx->canceled = 1; + UNLOCK (ctx->lock); + + return TRACE_ERR (0); +} + + /* Release all resources associated with the given context. */ void gpgme_release (gpgme_ctx_t ctx) @@ -139,6 +157,7 @@ if (ctx->lc_messages) free (ctx->lc_messages); _gpgme_engine_info_release (ctx->engine_info); + DESTROY_LOCK (ctx->lock); free (ctx); } Modified: trunk/gpgme/gpgme.h =================================================================== --- trunk/gpgme/gpgme.h 2008-06-26 14:38:39 UTC (rev 1322) +++ trunk/gpgme/gpgme.h 2008-06-27 16:07:33 UTC (rev 1323) @@ -1120,6 +1120,9 @@ /* Cancel a pending asynchronous operation. */ gpgme_error_t gpgme_cancel (gpgme_ctx_t ctx); +/* Cancel a pending operation asynchronously. */ +gpgme_error_t gpgme_cancel_async (gpgme_ctx_t ctx); + struct _gpgme_invalid_key { Modified: trunk/gpgme/op-support.c =================================================================== --- trunk/gpgme/op-support.c 2008-06-26 14:38:39 UTC (rev 1322) +++ trunk/gpgme/op-support.c 2008-06-27 16:07:33 UTC (rev 1323) @@ -76,6 +76,9 @@ type &= 255; _gpgme_release_result (ctx); + LOCK (ctx->lock); + ctx->canceled = 0; + UNLOCK (ctx->lock); if (ctx->engine && no_reset) reuse_engine = 1; Modified: trunk/gpgme/wait-global.c =================================================================== --- trunk/gpgme/wait-global.c 2008-06-26 14:38:39 UTC (rev 1322) +++ trunk/gpgme/wait-global.c 2008-06-27 16:07:33 UTC (rev 1323) @@ -299,7 +299,7 @@ if (fdt.fds[i].fd != -1 && fdt.fds[i].signaled) { gpgme_ctx_t ictx; - gpgme_error_t err; + gpgme_error_t err = 0; struct wait_item_s *item; assert (nr); @@ -310,7 +310,13 @@ ictx = item->ctx; assert (ictx); - err = _gpgme_run_io_cb (&fdt.fds[i], 0); + LOCK (ctx->lock); + if (ctx->canceled) + err = gpg_error (GPG_ERR_CANCELED); + UNLOCK (ctx->lock); + + if (!err) + err = _gpgme_run_io_cb (&fdt.fds[i], 0); if (err) { /* An error occured. Close all fds in this context, Modified: trunk/gpgme/wait-private.c =================================================================== --- trunk/gpgme/wait-private.c 2008-06-26 14:38:39 UTC (rev 1322) +++ trunk/gpgme/wait-private.c 2008-06-27 16:07:33 UTC (rev 1323) @@ -105,7 +105,13 @@ assert (nr); nr--; - err = _gpgme_run_io_cb (&ctx->fdt.fds[i], 0); + LOCK (ctx->lock); + if (ctx->canceled) + err = gpg_error (GPG_ERR_CANCELED); + UNLOCK (ctx->lock); + + if (!err) + err = _gpgme_run_io_cb (&ctx->fdt.fds[i], 0); if (err) { /* An error occured. Close all fds in this context, Modified: trunk/gpgme/wait-user.c =================================================================== --- trunk/gpgme/wait-user.c 2008-06-26 14:38:39 UTC (rev 1322) +++ trunk/gpgme/wait-user.c 2008-06-27 16:07:33 UTC (rev 1323) @@ -39,7 +39,7 @@ gpgme_error_t _gpgme_user_io_cb_handler (void *data, int fd) { - gpgme_error_t err; + gpgme_error_t err = 0; struct tag *tag = (struct tag *) data; gpgme_ctx_t ctx; @@ -47,7 +47,13 @@ ctx = tag->ctx; assert (ctx); - err = _gpgme_run_io_cb (&ctx->fdt.fds[tag->idx], 0); + LOCK (ctx->lock); + if (ctx->canceled) + err = gpg_error (GPG_ERR_CANCELED); + UNLOCK (ctx->lock); + + if (! err) + err = _gpgme_run_io_cb (&ctx->fdt.fds[tag->idx], 0); if (err) { unsigned int idx; From cvs at cvs.gnupg.org Fri Jun 27 18:08:36 2008 From: cvs at cvs.gnupg.org (svn author marcus) Date: Fri, 27 Jun 2008 18:08:36 +0200 Subject: [svn] gpgme - r1324 - trunk Message-ID: Author: marcus Date: 2008-06-27 18:08:35 +0200 (Fri, 27 Jun 2008) New Revision: 1324 Modified: trunk/NEWS Log: Add gpgme_cancel_async Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2008-06-27 16:07:33 UTC (rev 1323) +++ trunk/NEWS 2008-06-27 16:08:35 UTC (rev 1324) @@ -15,6 +15,9 @@ * The reference manual now includes the specification of "The GnuPG UI Server protocol". + * A new function gpgme_cancel_async can be used to asynchronously + cancel any pending operation at any time, from any thread. + * Interface changes relative to the 1.1.6 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ gpgme_op_encrypt CHANGED: Output encoding can affect result. @@ -27,6 +30,7 @@ gpgme_op_export_start CHANGED: Output encoding can affect result. gpgme_op_export_ext CHANGED: Output encoding can affect result. gpgme_op_export_ext_start CHANGED: Output encoding can affect result. +gpgme_cancel_async NEW ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From cvs at cvs.gnupg.org Fri Jun 27 18:14:58 2008 From: cvs at cvs.gnupg.org (svn author marcus) Date: Fri, 27 Jun 2008 18:14:58 +0200 Subject: [svn] gpgme - r1325 - trunk/gpgme Message-ID: Author: marcus Date: 2008-06-27 18:14:57 +0200 (Fri, 27 Jun 2008) New Revision: 1325 Modified: trunk/gpgme/ChangeLog trunk/gpgme/gpgme.def trunk/gpgme/libgpgme.vers Log: 2008-06-27 Marcus Brinkmann * libgpgme.vers: Add gpgme_cancel_async. * gpgme.def: Likewise. Modified: trunk/gpgme/ChangeLog =================================================================== --- trunk/gpgme/ChangeLog 2008-06-27 16:08:35 UTC (rev 1324) +++ trunk/gpgme/ChangeLog 2008-06-27 16:14:57 UTC (rev 1325) @@ -1,5 +1,8 @@ 2008-06-27 Marcus Brinkmann + * libgpgme.vers: Add gpgme_cancel_async. + * gpgme.def: Likewise. + * context.h: Include "sema.h". (struct gpgme_context): New members lock and canceled. * gpgme.c (gpgme_new): Initialize lock. Modified: trunk/gpgme/gpgme.def =================================================================== --- trunk/gpgme/gpgme.def 2008-06-27 16:08:35 UTC (rev 1324) +++ trunk/gpgme/gpgme.def 2008-06-27 16:14:57 UTC (rev 1325) @@ -166,5 +166,6 @@ gpgme_op_conf_load @129 gpgme_op_conf_save @130 + gpgme_cancel_async @131 ; END Modified: trunk/gpgme/libgpgme.vers =================================================================== --- trunk/gpgme/libgpgme.vers 2008-06-27 16:08:35 UTC (rev 1324) +++ trunk/gpgme/libgpgme.vers 2008-06-27 16:14:57 UTC (rev 1325) @@ -46,6 +46,8 @@ gpgme_conf_opt_change; gpgme_op_conf_load; gpgme_op_conf_save; + + gpgme_cancel_async; }; From cvs at cvs.gnupg.org Fri Jun 27 20:10:45 2008 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 27 Jun 2008 20:10:45 +0200 Subject: [svn] GpgOL - r261 - in trunk: doc src Message-ID: Author: wk Date: 2008-06-27 20:10:42 +0200 (Fri, 27 Jun 2008) New Revision: 261 Modified: trunk/doc/gpgol.texi trunk/src/ChangeLog trunk/src/mapihelp.cpp trunk/src/mapihelp.h Log: Save old message class. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2008-06-26 14:41:57 UTC (rev 260) +++ trunk/src/ChangeLog 2008-06-27 18:10:42 UTC (rev 261) @@ -1,3 +1,8 @@ +2008-06-27 Werner Koch + + * mapihelp.cpp (get_gpgololdmsgclass_tag): New. + (mapi_change_message_class): Save old message class. + 2008-06-19 Werner Koch * olflange-dlgs.cpp (GPGOptionsDlgProc): Change S/MIME enabled Modified: trunk/doc/gpgol.texi =================================================================== --- trunk/doc/gpgol.texi 2008-06-26 14:41:57 UTC (rev 260) +++ trunk/doc/gpgol.texi 2008-06-27 18:10:42 UTC (rev 261) @@ -161,6 +161,14 @@ @table @code + at item GpgOL Msg Class +This is a STRING8 property used as a override for PR_MESSAGE_CLASS. +GpgOL uses this internally for creating messages. + + at item GpgOL Old Msg Class +This is a STRING8 property which saves the original PR_MESSAGE_CLASS +before GpgOL chnages it. + @item GpgOL Attach Type This is a property of type LONG and used to further describe the attachments created by GpgOL. These values are used: Modified: trunk/src/mapihelp.cpp =================================================================== --- trunk/src/mapihelp.cpp 2008-06-26 14:41:57 UTC (rev 260) +++ trunk/src/mapihelp.cpp 2008-06-27 18:10:42 UTC (rev 261) @@ -144,7 +144,19 @@ return 0; } +/* Return the property tag for GpgOL Old Msg Class. The Old Msg Class + saves the message class as seen before we changed it the first + time. */ +int +get_gpgololdmsgclass_tag (LPMESSAGE message, ULONG *r_tag) +{ + if (!(*r_tag = create_gpgol_tag (message, L"GpgOL Old Msg Class", __func__))) + return -1; + *r_tag |= PT_STRING8; + return 0; +} + /* Return the property tag for GpgOL Attach Type. */ int get_gpgolattachtype_tag (LPMESSAGE message, ULONG *r_tag) @@ -926,7 +938,6 @@ newvalue = xstrdup ("IPM.Note.GpgOL"); } } - MAPIFreeBuffer (propval); if (!newvalue) { /* We use our Sig-Status property to mark messages which passed @@ -939,6 +950,37 @@ } else { + /* Save old message class if not yet done. (The second + consition is just a failsafe check). */ + if (!get_gpgololdmsgclass_tag (message, &tag) + && PROP_TYPE (propval->ulPropTag) == PT_STRING8) + { + LPSPropValue propval2 = NULL; + + hr = HrGetOneProp ((LPMAPIPROP)message, tag, &propval2); + if (!FAILED (hr)) + MAPIFreeBuffer (propval2); + else + { + /* No such property - save it. */ + log_debug ("%s:%s: saving old message class\n", + SRCNAME, __func__); + prop.ulPropTag = tag; + prop.Value.lpszA = propval->Value.lpszA; + hr = message->SetProps (1, &prop, NULL); + xfree (newvalue); + if (hr) + { + log_error ("%s:%s: can't save old message class: hr=%#lx\n", + SRCNAME, __func__, hr); + MAPIFreeBuffer (propval); + return 0; + } + need_save = 1; + } + } + + /* Change message class. */ log_debug ("%s:%s: setting message class to `%s'\n", SRCNAME, __func__, newvalue); prop.ulPropTag = PR_MESSAGE_CLASS_A; @@ -949,10 +991,12 @@ { log_error ("%s:%s: can't set message class: hr=%#lx\n", SRCNAME, __func__, hr); + MAPIFreeBuffer (propval); return 0; } need_save = 1; } + MAPIFreeBuffer (propval); if (need_save) { Modified: trunk/src/mapihelp.h =================================================================== --- trunk/src/mapihelp.h 2008-06-26 14:41:57 UTC (rev 260) +++ trunk/src/mapihelp.h 2008-06-27 18:10:42 UTC (rev 261) @@ -93,6 +93,7 @@ #define PGPBODYFILENAME "gpgolPGP.dat" void log_mapi_property (LPMESSAGE message, ULONG prop, const char *propname); +int get_gpgololdmsgclass_tag (LPMESSAGE message, ULONG *r_tag); int get_gpgolattachtype_tag (LPMESSAGE message, ULONG *r_tag); int get_gpgolsigstatus_tag (LPMESSAGE message, ULONG *r_tag); int get_gpgolprotectiv_tag (LPMESSAGE message, ULONG *r_tag); From cvs at cvs.gnupg.org Sun Jun 29 20:41:20 2008 From: cvs at cvs.gnupg.org (svn author marcus) Date: Sun, 29 Jun 2008 20:41:20 +0200 Subject: [svn] gpgme - r1326 - trunk/gpgme Message-ID: Author: marcus Date: 2008-06-29 20:41:19 +0200 (Sun, 29 Jun 2008) New Revision: 1326 Modified: trunk/gpgme/ChangeLog trunk/gpgme/gpgme.c Log: 2008-06-29 Marcus Brinkmann * gpgme.c (gpgme_cancel_async): Remove unused variable. Modified: trunk/gpgme/ChangeLog =================================================================== --- trunk/gpgme/ChangeLog 2008-06-27 16:14:57 UTC (rev 1325) +++ trunk/gpgme/ChangeLog 2008-06-29 18:41:19 UTC (rev 1326) @@ -1,3 +1,7 @@ +2008-06-29 Marcus Brinkmann + + * gpgme.c (gpgme_cancel_async): Remove unused variable. + 2008-06-27 Marcus Brinkmann * libgpgme.vers: Add gpgme_cancel_async. Modified: trunk/gpgme/gpgme.c =================================================================== --- trunk/gpgme/gpgme.c 2008-06-27 16:14:57 UTC (rev 1325) +++ trunk/gpgme/gpgme.c 2008-06-29 18:41:19 UTC (rev 1326) @@ -128,7 +128,6 @@ gpgme_error_t gpgme_cancel_async (gpgme_ctx_t ctx) { - gpgme_error_t err; TRACE_BEG (DEBUG_CTX, "gpgme_cancel_async", ctx); LOCK (ctx->lock);