Sophie

Sophie

distrib > Mandriva > 9.0 > i586 > by-pkgid > 2269bb274471fd2722517c2c0b740d7f > files > 306

rpm-devel-4.0.4-19mdk.i586.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>lib/signature.c Source File</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.2.17 -->
<center>
<a class="qindex" href="index.html">Main Page</a> &nbsp; <a class="qindex" href="modules.html">Modules</a> &nbsp; <a class="qindex" href="annotated.html">Data Structures</a> &nbsp; <a class="qindex" href="files.html">File List</a> &nbsp; <a class="qindex" href="functions.html">Data Fields</a> &nbsp; <a class="qindex" href="globals.html">Globals</a> &nbsp; <a class="qindex" href="pages.html">Related Pages</a> &nbsp; </center>
<hr><h1>lib/signature.c</h1><a href="signature_8c.html">Go to the documentation of this file.</a><div class="fragment"><pre>00001 
00005 <span class="comment">/* signature.c - RPM signature functions */</span>
00006 
00007 <span class="comment">/* NOTES</span>
00008 <span class="comment"> *</span>
00009 <span class="comment"> * Things have been cleaned up wrt PGP.  We can now handle</span>
00010 <span class="comment"> * signatures of any length (which means you can use any</span>
00011 <span class="comment"> * size key you like).  We also honor PGPPATH finally.</span>
00012 <span class="comment"> */</span>
00013 
00014 <span class="preprocessor">#include "<a class="code" href="system_8h.html">system.h</a>"</span>
00015 
00016 <span class="preprocessor">#include "<a class="code" href="rpmio__internal_8h.html">rpmio_internal.h</a>"</span>
00017 <span class="preprocessor">#include &lt;<a class="code" href="rpmlib_8h.html">rpmlib.h</a>&gt;</span>
00018 <span class="preprocessor">#include &lt;<a class="code" href="rpmmacro_8h.html">rpmmacro.h</a>&gt;</span>   <span class="comment">/* XXX for rpmGetPath() */</span>
00019 
00020 <span class="preprocessor">#include "md5.h"</span>
00021 <span class="preprocessor">#include "<a class="code" href="misc_8h.html">misc.h</a>"</span>       <span class="comment">/* XXX for dosetenv() and makeTempFile() */</span>
00022 <span class="preprocessor">#include "<a class="code" href="rpmlead_8h.html">rpmlead.h</a>"</span>
00023 <span class="preprocessor">#include "<a class="code" href="signature_8h.html">signature.h</a>"</span>
00024 <span class="preprocessor">#include "<a class="code" href="debug_8h.html">debug.h</a>"</span>
00025 
00026 <span class="comment">/*@access Header@*/</span>             <span class="comment">/* XXX compared with NULL */</span>
00027 <span class="comment">/*@access FD_t@*/</span>               <span class="comment">/* XXX compared with NULL */</span>
00028 
00029 <span class="preprocessor">#if !defined(__GLIBC__)</span>
<a name="l00030"></a><a class="code" href="signature_8c.html#a1">00030</a> <span class="preprocessor"></span><span class="keywordtype">char</span> ** <a class="code" href="signature_8c.html#a1">environ</a> = NULL;
00031 <span class="preprocessor">#endif</span>
00032 <span class="preprocessor"></span>
<a name="l00033"></a><a class="code" href="signature_8c.html#a2">00033</a> <span class="keyword">typedef</span> int (*<a class="code" href="signature_8c.html#a2">md5func</a>)(<span class="keyword">const</span> <span class="keywordtype">char</span> * fn, <span class="comment">/*@out@*/</span> byte * digest);
00034 
<a name="l00035"></a><a class="code" href="group__signature.html#a8">00035</a> <span class="keywordtype">int</span> <a class="code" href="group__signature.html#a8">rpmLookupSignatureType</a>(<span class="keywordtype">int</span> action)
00036 {
00037     <span class="keyword">static</span> <span class="keywordtype">int</span> disabled = 0;
00038     <span class="keywordtype">int</span> rc = 0;
00039 
00040     <span class="keywordflow">switch</span> (action) {
00041     <span class="keywordflow">case</span> <a class="code" href="signature_8h.html#a1">RPMLOOKUPSIG_DISABLE</a>:
00042         disabled = -2;
00043         <span class="keywordflow">break</span>;
00044     <span class="keywordflow">case</span> <a class="code" href="signature_8h.html#a2">RPMLOOKUPSIG_ENABLE</a>:
00045         disabled = 0;
00046         <span class="comment">/*@fallthrough@*/</span>
00047     <span class="keywordflow">case</span> <a class="code" href="signature_8h.html#a0">RPMLOOKUPSIG_QUERY</a>:
00048         <span class="keywordflow">if</span> (disabled)
00049             <span class="keywordflow">break</span>;      <span class="comment">/* Disabled */</span>
00050       { <span class="keyword">const</span> <span class="keywordtype">char</span> *name = <a class="code" href="macro_8c.html#a50">rpmExpand</a>(<span class="stringliteral">"%{?_signature}"</span>, NULL);
00051         <span class="keywordflow">if</span> (!(name &amp;&amp; *name != <span class="charliteral">'\0'</span>))
00052             rc = 0;
00053         <span class="keywordflow">else</span> <span class="keywordflow">if</span> (!<a class="code" href="group__rpmio.html#a0">xstrcasecmp</a>(name, <span class="stringliteral">"none"</span>))
00054             rc = 0;
00055         <span class="keywordflow">else</span> <span class="keywordflow">if</span> (!<a class="code" href="group__rpmio.html#a0">xstrcasecmp</a>(name, <span class="stringliteral">"pgp"</span>))
00056             rc = <a class="code" href="group__signature.html#a11a400">RPMSIGTAG_PGP</a>;
00057         <span class="keywordflow">else</span> <span class="keywordflow">if</span> (!<a class="code" href="group__rpmio.html#a0">xstrcasecmp</a>(name, <span class="stringliteral">"pgp5"</span>))    <span class="comment">/* XXX legacy */</span>
00058             rc = <a class="code" href="group__signature.html#a11a400">RPMSIGTAG_PGP</a>;
00059         <span class="keywordflow">else</span> <span class="keywordflow">if</span> (!<a class="code" href="group__rpmio.html#a0">xstrcasecmp</a>(name, <span class="stringliteral">"gpg"</span>))
00060             rc = <a class="code" href="group__signature.html#a11a403">RPMSIGTAG_GPG</a>;
00061         <span class="keywordflow">else</span>
00062             rc = -1;    <span class="comment">/* Invalid %_signature spec in macro file */</span>
00063         name = <a class="code" href="poptint_8h.html#a14">_free</a>(name);
00064       } <span class="keywordflow">break</span>;
00065     }
00066     <span class="keywordflow">return</span> rc;
00067 }
00068 
00069 <span class="comment">/* rpmDetectPGPVersion() returns the absolute path to the "pgp"  */</span>
00070 <span class="comment">/* executable of the requested version, or NULL when none found. */</span>
00071 
<a name="l00072"></a><a class="code" href="group__signature.html#a10">00072</a> <span class="keyword">const</span> <span class="keywordtype">char</span> * <a class="code" href="group__signature.html#a10">rpmDetectPGPVersion</a>(<a class="code" href="group__signature.html#a1">pgpVersion</a> * pgpVer)
00073 {
00074     <span class="comment">/* Actually this should support having more then one pgp version. */</span>
00075     <span class="comment">/* At the moment only one version is possible since we only       */</span>
00076     <span class="comment">/* have one %_pgpbin and one %_pgp_path.                          */</span>
00077 
00078     <span class="keyword">static</span> <a class="code" href="group__signature.html#a1">pgpVersion</a> saved_pgp_version = <a class="code" href="group__signature.html#a13a14">PGP_UNKNOWN</a>;
00079     <span class="keyword">const</span> <span class="keywordtype">char</span> *pgpbin = <a class="code" href="macro_8c.html#a53">rpmGetPath</a>(<span class="stringliteral">"%{?_pgpbin}"</span>, NULL);
00080 
00081     <span class="keywordflow">if</span> (saved_pgp_version == <a class="code" href="group__signature.html#a13a14">PGP_UNKNOWN</a>) {
00082         <span class="keywordtype">char</span> *pgpvbin;
00083         <span class="keyword">struct </span>stat st;
00084 
00085         <span class="keywordflow">if</span> (!(pgpbin &amp;&amp; pgpbin[0] != <span class="charliteral">'\0'</span>)) {
00086           pgpbin = <a class="code" href="poptint_8h.html#a14">_free</a>(pgpbin);
00087           saved_pgp_version = -1;
00088           <span class="keywordflow">return</span> NULL;
00089         }
00090         pgpvbin = (<span class="keywordtype">char</span> *)<a class="code" href="system_8h.html#a36">alloca</a>(strlen(pgpbin) + <span class="keyword">sizeof</span>(<span class="stringliteral">"v"</span>));
00091         (void)<a class="code" href="system_8h.html#a32">stpcpy</a>(<a class="code" href="system_8h.html#a32">stpcpy</a>(pgpvbin, pgpbin), <span class="stringliteral">"v"</span>);
00092 
00093         <span class="keywordflow">if</span> (stat(pgpvbin, &amp;st) == 0)
00094           saved_pgp_version = <a class="code" href="group__signature.html#a13a16">PGP_5</a>;
00095         <span class="keywordflow">else</span> <span class="keywordflow">if</span> (stat(pgpbin, &amp;st) == 0)
00096           saved_pgp_version = <a class="code" href="group__signature.html#a13a15">PGP_2</a>;
00097         <span class="keywordflow">else</span>
00098           saved_pgp_version = <a class="code" href="group__signature.html#a13a13">PGP_NOTDETECTED</a>;
00099     }
00100 
00101     <span class="keywordflow">if</span> (pgpVer &amp;&amp; pgpbin)
00102         *pgpVer = saved_pgp_version;
00103     <span class="keywordflow">return</span> pgpbin;
00104 }
00105 
<a name="l00115"></a><a class="code" href="signature_8c.html#a6">00115</a> <span class="keyword">static</span> <span class="keyword">inline</span> <a class="code" href="rpmlib_8h.html#a43">rpmRC</a> <a class="code" href="signature_8c.html#a6">checkSize</a>(<a class="code" href="struct__FD__s.html">FD_t</a> fd, <span class="keywordtype">int</span> siglen, <span class="keywordtype">int</span> pad, <span class="keywordtype">int</span> datalen)
00116         <span class="comment">/*@globals fileSystem @*/</span>
00117         <span class="comment">/*@modifies fileSystem @*/</span>
00118 {
00119     <span class="keyword">struct </span>stat st;
00120     <a class="code" href="rpmlib_8h.html#a43">rpmRC</a> rc;
00121 
00122     <span class="keywordflow">if</span> (fstat(<a class="code" href="group__rpmio.html#a86">Fileno</a>(fd), &amp;st))
00123         <span class="keywordflow">return</span> <a class="code" href="rpmlib_8h.html#a493a91">RPMRC_FAIL</a>;
00124 
00125     <span class="keywordflow">if</span> (!S_ISREG(st.st_mode)) {
00126         <a class="code" href="rpmmessages_8h.html#a7">rpmMessage</a>(<a class="code" href="rpmmessages_8h.html#a0">RPMMESS_DEBUG</a>,
00127             <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"file is not regular -- skipping size check\n"</span>));
00128         <span class="keywordflow">return</span> <a class="code" href="rpmlib_8h.html#a493a89">RPMRC_OK</a>;
00129     }
00130 
00131     rc = (((<span class="keyword">sizeof</span>(<span class="keyword">struct </span><a class="code" href="structrpmlead.html">rpmlead</a>) + siglen + pad + datalen) - st.st_size)
00132         ? RPMRC_BADSIZE : <a class="code" href="rpmlib_8h.html#a493a89">RPMRC_OK</a>);
00133 
00134     <a class="code" href="rpmmessages_8h.html#a7">rpmMessage</a>((rc == <a class="code" href="rpmlib_8h.html#a493a89">RPMRC_OK</a> ? <a class="code" href="rpmmessages_8h.html#a0">RPMMESS_DEBUG</a> : <a class="code" href="rpmmessages_8h.html#a0">RPMMESS_DEBUG</a>),
00135         _("Expected size: %12d = lead(%d)+sigs(%d)+pad(%d)+data(%d)\n"),
00136                 (int)sizeof(struct <a class="code" href="structrpmlead.html">rpmlead</a>)+siglen+pad+datalen,
00137                 (int)sizeof(struct <a class="code" href="structrpmlead.html">rpmlead</a>), siglen, pad, datalen);
00138     <a class="code" href="rpmmessages_8h.html#a7">rpmMessage</a>((rc == <a class="code" href="rpmlib_8h.html#a493a89">RPMRC_OK</a> ? <a class="code" href="rpmmessages_8h.html#a0">RPMMESS_DEBUG</a> : <a class="code" href="rpmmessages_8h.html#a0">RPMMESS_DEBUG</a>),
00139         _("  Actual size: %12d\n"), (int)st.st_size);
00140 
00141     return rc;
00142 }
00143 
<a name="l00144"></a><a class="code" href="group__signature.html#a5">00144</a> <a class="code" href="rpmlib_8h.html#a43">rpmRC</a> <a class="code" href="group__signature.html#a5">rpmReadSignature</a>(<a class="code" href="struct__FD__s.html">FD_t</a> fd, <a class="code" href="structheaderToken.html">Header</a> * headerp, <a class="code" href="group__signature.html#a0">sigType</a> sig_type)
00145 {
00146     byte buf[2048];
00147     <span class="keywordtype">int</span> sigSize, pad;
00148     <a class="code" href="header_8h.html#a9">int_32</a> <a class="code" href="structrpmlead.html#m3">type</a>, count;
00149     <a class="code" href="header_8h.html#a9">int_32</a> *archSize;
00150     <a class="code" href="structheaderToken.html">Header</a> h = NULL;
00151     <a class="code" href="rpmlib_8h.html#a43">rpmRC</a> rc = <a class="code" href="rpmlib_8h.html#a493a91">RPMRC_FAIL</a>;              <span class="comment">/* assume failure */</span>
00152 
00153     <span class="keywordflow">if</span> (headerp)
00154         *headerp = NULL;
00155 
00156     buf[0] = 0;
00157     <span class="keywordflow">switch</span> (sig_type) {
00158     <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a12a6">RPMSIGTYPE_NONE</a>:
00159         <a class="code" href="rpmmessages_8h.html#a7">rpmMessage</a>(<a class="code" href="rpmmessages_8h.html#a0">RPMMESS_DEBUG</a>, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"No signature\n"</span>));
00160         rc = <a class="code" href="rpmlib_8h.html#a493a89">RPMRC_OK</a>;
00161         <span class="keywordflow">break</span>;
00162     <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a12a7">RPMSIGTYPE_PGP262_1024</a>:
00163         <a class="code" href="rpmmessages_8h.html#a7">rpmMessage</a>(<a class="code" href="rpmmessages_8h.html#a0">RPMMESS_DEBUG</a>, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"Old PGP signature\n"</span>));
00164         <span class="comment">/* These are always 256 bytes */</span>
00165         <span class="keywordflow">if</span> (<a class="code" href="rpmio_8h.html#a8">timedRead</a>(fd, buf, 256) != 256)
00166             <span class="keywordflow">break</span>;
00167         h = <a class="code" href="group__header.html#a51">headerNew</a>();
00168         (void) <a class="code" href="group__header.html#a45">headerAddEntry</a>(h, <a class="code" href="group__signature.html#a11a400">RPMSIGTAG_PGP</a>, <a class="code" href="group__header.html#a93a72">RPM_BIN_TYPE</a>, buf, 152);
00169         rc = <a class="code" href="rpmlib_8h.html#a493a89">RPMRC_OK</a>;
00170         <span class="keywordflow">break</span>;
00171     <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a12a9">RPMSIGTYPE_MD5</a>:
00172     <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a12a10">RPMSIGTYPE_MD5_PGP</a>:
00173         <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a85">RPMERR_BADSIGTYPE</a>,
00174               <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"Old (internal-only) signature!  How did you get that!?\n"</span>));
00175         <span class="keywordflow">break</span>;
00176     <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a12a11">RPMSIGTYPE_HEADERSIG</a>:
00177     <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a12a12">RPMSIGTYPE_DISABLE</a>:
00178         <span class="comment">/* This is a new style signature */</span>
00179         h = <a class="code" href="group__header.html#a32">headerRead</a>(fd, <a class="code" href="group__header.html#a92a65">HEADER_MAGIC_YES</a>);
00180         <span class="keywordflow">if</span> (h == NULL)
00181             <span class="keywordflow">break</span>;
00182 
00183         rc = <a class="code" href="rpmlib_8h.html#a493a89">RPMRC_OK</a>;
00184         sigSize = <a class="code" href="group__header.html#a22">headerSizeof</a>(h, <a class="code" href="group__header.html#a92a65">HEADER_MAGIC_YES</a>);
00185 
00186         <span class="comment">/* XXX Legacy headers have a HEADER_IMAGE tag added. */</span>
00187         <span class="keywordflow">if</span> (<a class="code" href="group__header.html#a34">headerIsEntry</a>(h, <a class="code" href="rpmlib_8h.html#a494a94">RPMTAG_HEADERIMAGE</a>))
00188             sigSize -= (16 + 16);
00189 
00190         pad = (8 - (sigSize % 8)) % 8; <span class="comment">/* 8-byte pad */</span>
00191         <span class="keywordflow">if</span> (sig_type == <a class="code" href="group__signature.html#a12a11">RPMSIGTYPE_HEADERSIG</a>) {
00192             <span class="keywordflow">if</span> (! <a class="code" href="group__header.html#a40">headerGetEntry</a>(h, <a class="code" href="group__signature.html#a11a398">RPMSIGTAG_SIZE</a>, &amp;<a class="code" href="structrpmlead.html#m3">type</a>,
00193                                 (<span class="keywordtype">void</span> **)&amp;archSize, &amp;count))
00194                 <span class="keywordflow">break</span>;
00195             rc = <a class="code" href="signature_8c.html#a6">checkSize</a>(fd, sigSize, pad, *archSize);
00196         }
00197         <span class="keywordflow">if</span> (pad &amp;&amp; <a class="code" href="rpmio_8h.html#a8">timedRead</a>(fd, buf, pad) != pad)
00198             rc = <a class="code" href="rpmlib_8h.html#a493a93">RPMRC_SHORTREAD</a>;
00199         <span class="keywordflow">break</span>;
00200     <span class="keywordflow">default</span>:
00201         <span class="keywordflow">break</span>;
00202     }
00203 
00204     <span class="keywordflow">if</span> (rc == 0 &amp;&amp; headerp)
00205         <span class="comment">/*@-nullderef@*/</span>
00206         *headerp = h;
00207         <span class="comment">/*@=nullderef@*/</span>
00208     <span class="keywordflow">else</span> <span class="keywordflow">if</span> (h)
00209         h = <a class="code" href="group__header.html#a16">headerFree</a>(h);
00210 
00211     <span class="keywordflow">return</span> rc;
00212 }
00213 
<a name="l00214"></a><a class="code" href="group__signature.html#a6">00214</a> <span class="keywordtype">int</span> <a class="code" href="group__signature.html#a6">rpmWriteSignature</a>(<a class="code" href="struct__FD__s.html">FD_t</a> fd, <a class="code" href="structheaderToken.html">Header</a> h)
00215 {
00216     <span class="keyword">static</span> byte buf[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
00217     <span class="keywordtype">int</span> sigSize, pad;
00218     <span class="keywordtype">int</span> rc;
00219 
00220     rc = <a class="code" href="group__header.html#a33">headerWrite</a>(fd, h, <a class="code" href="group__header.html#a92a65">HEADER_MAGIC_YES</a>);
00221     <span class="keywordflow">if</span> (rc)
00222         <span class="keywordflow">return</span> rc;
00223 
00224     sigSize = <a class="code" href="group__header.html#a22">headerSizeof</a>(h, <a class="code" href="group__header.html#a92a65">HEADER_MAGIC_YES</a>);
00225     pad = (8 - (sigSize % 8)) % 8;
00226     <span class="keywordflow">if</span> (pad) {
00227         <span class="keywordflow">if</span> (<a class="code" href="group__rpmio.html#a78">Fwrite</a>(buf, <span class="keyword">sizeof</span>(buf[0]), pad, fd) != pad)
00228             rc = 1;
00229     }
00230     <a class="code" href="rpmmessages_8h.html#a7">rpmMessage</a>(<a class="code" href="rpmmessages_8h.html#a0">RPMMESS_DEBUG</a>, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"Signature: size(%d)+pad(%d)\n"</span>), sigSize, pad);
00231     <span class="keywordflow">return</span> rc;
00232 }
00233 
<a name="l00234"></a><a class="code" href="signature_8c.html#a3">00234</a> <a class="code" href="structheaderToken.html">Header</a> <a class="code" href="group__signature.html#a2">rpmNewSignature</a>(<span class="keywordtype">void</span>)
00235 {
00236     <a class="code" href="structheaderToken.html">Header</a> h = <a class="code" href="group__header.html#a51">headerNew</a>();
00237     <span class="keywordflow">return</span> h;
00238 }
00239 
<a name="l00240"></a><a class="code" href="group__signature.html#a9">00240</a> <a class="code" href="structheaderToken.html">Header</a> <a class="code" href="group__signature.html#a9">rpmFreeSignature</a>(<a class="code" href="structheaderToken.html">Header</a> h)
00241 {
00242     <span class="keywordflow">return</span> <a class="code" href="group__header.html#a16">headerFree</a>(h);
00243 }
00244 
<a name="l00245"></a><a class="code" href="signature_8c.html#a10">00245</a> <span class="keyword">static</span> <span class="keywordtype">int</span> <a class="code" href="signature_8c.html#a10">makePGPSignature</a>(<span class="keyword">const</span> <span class="keywordtype">char</span> * file, <span class="comment">/*@out@*/</span> <span class="keywordtype">void</span> ** sig,
00246                 <span class="comment">/*@out@*/</span> <a class="code" href="header_8h.html#a9">int_32</a> * size, <span class="comment">/*@null@*/</span> <span class="keyword">const</span> <span class="keywordtype">char</span> * passPhrase)
00247         <span class="comment">/*@globals rpmGlobalMacroContext, fileSystem @*/</span>
00248         <span class="comment">/*@modifies *sig, *size, rpmGlobalMacroContext, fileSystem @*/</span>
00249 {
00250     <span class="keywordtype">char</span> * sigfile = <a class="code" href="system_8h.html#a36">alloca</a>(1024);
00251     <span class="keywordtype">int</span> pid, status;
00252     <span class="keywordtype">int</span> inpipe[2];
00253     <span class="keyword">struct </span>stat st;
00254     <span class="keyword">const</span> <span class="keywordtype">char</span> * cmd;
00255     <span class="keywordtype">char</span> *<span class="keyword">const</span> *av;
00256     <span class="keywordtype">int</span> rc;
00257 
00258     (void) <a class="code" href="system_8h.html#a32">stpcpy</a>( <a class="code" href="system_8h.html#a32">stpcpy</a>(sigfile, file), <span class="stringliteral">".sig"</span>);
00259 
00260     <a class="code" href="macro_8c.html#a43">addMacro</a>(NULL, <span class="stringliteral">"__plaintext_filename"</span>, NULL, file, -1);
00261     <a class="code" href="macro_8c.html#a43">addMacro</a>(NULL, <span class="stringliteral">"__signature_filename"</span>, NULL, sigfile, -1);
00262 
00263     inpipe[0] = inpipe[1] = 0;
00264     (void) pipe(inpipe);
00265 
00266     <span class="keywordflow">if</span> (!(pid = fork())) {
00267         <span class="keyword">const</span> <span class="keywordtype">char</span> *pgp_path = <a class="code" href="macro_8c.html#a50">rpmExpand</a>(<span class="stringliteral">"%{?_pgp_path}"</span>, NULL);
00268         <span class="keyword">const</span> <span class="keywordtype">char</span> *path;
00269         <a class="code" href="group__signature.html#a1">pgpVersion</a> pgpVer;
00270 
00271         (void) close(STDIN_FILENO);
00272         (void) dup2(inpipe[0], 3);
00273         (void) close(inpipe[1]);
00274 
00275         (void) <a class="code" href="lib_2misc_8c.html#a6">dosetenv</a>(<span class="stringliteral">"PGPPASSFD"</span>, <span class="stringliteral">"3"</span>, 1);
00276         <span class="keywordflow">if</span> (pgp_path &amp;&amp; *pgp_path != <span class="charliteral">'\0'</span>)
00277             (void) <a class="code" href="lib_2misc_8c.html#a6">dosetenv</a>(<span class="stringliteral">"PGPPATH"</span>, pgp_path, 1);
00278 
00279         <span class="comment">/* dosetenv("PGPPASS", passPhrase, 1); */</span>
00280 
00281         <span class="keywordflow">if</span> ((path = <a class="code" href="group__signature.html#a10">rpmDetectPGPVersion</a>(&amp;pgpVer)) != NULL) {
00282             <span class="keywordflow">switch</span>(pgpVer) {
00283             <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a13a15">PGP_2</a>:
00284                 cmd = <a class="code" href="macro_8c.html#a50">rpmExpand</a>(<span class="stringliteral">"%{?__pgp_sign_cmd}"</span>, NULL);
00285                 rc = <a class="code" href="group__popt.html#a2">poptParseArgvString</a>(cmd, NULL, (<span class="keyword">const</span> <span class="keywordtype">char</span> ***)&amp;av);
00286                 <span class="keywordflow">if</span> (!rc)
00287                     rc = execve(av[0], av+1, <a class="code" href="signature_8c.html#a1">environ</a>);
00288                 <span class="keywordflow">break</span>;
00289             <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a13a16">PGP_5</a>:
00290                 cmd = <a class="code" href="macro_8c.html#a50">rpmExpand</a>(<span class="stringliteral">"%{?__pgp5_sign_cmd}"</span>, NULL);
00291                 rc = <a class="code" href="group__popt.html#a2">poptParseArgvString</a>(cmd, NULL, (<span class="keyword">const</span> <span class="keywordtype">char</span> ***)&amp;av);
00292                 <span class="keywordflow">if</span> (!rc)
00293                     rc = execve(av[0], av+1, <a class="code" href="signature_8c.html#a1">environ</a>);
00294                 <span class="keywordflow">break</span>;
00295             <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a13a14">PGP_UNKNOWN</a>:
00296             <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a13a13">PGP_NOTDETECTED</a>:
00297                 <a class="code" href="system_8h.html#a29">errno</a> = ENOENT;
00298                 <span class="keywordflow">break</span>;
00299             }
00300         }
00301         <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a56">RPMERR_EXEC</a>, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"Could not exec %s: %s\n"</span>), <span class="stringliteral">"pgp"</span>,
00302                         <a class="code" href="popt_8c.html#a1">strerror</a>(<a class="code" href="system_8h.html#a29">errno</a>));
00303         _exit(<a class="code" href="rpmerr_8h.html#a91a56">RPMERR_EXEC</a>);
00304     }
00305 
00306     <a class="code" href="macro_8c.html#a44">delMacro</a>(NULL, <span class="stringliteral">"__plaintext_filename"</span>);
00307     <a class="code" href="macro_8c.html#a44">delMacro</a>(NULL, <span class="stringliteral">"__signature_filename"</span>);
00308 
00309     (void) close(inpipe[0]);
00310     <span class="keywordflow">if</span> (passPhrase)
00311         (void) write(inpipe[1], passPhrase, strlen(passPhrase));
00312     (void) write(inpipe[1], <span class="stringliteral">"\n"</span>, 1);
00313     (void) close(inpipe[1]);
00314 
00315     (void)waitpid(pid, &amp;status, 0);
00316     <span class="keywordflow">if</span> (!WIFEXITED(status) || WEXITSTATUS(status)) {
00317         <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a86">RPMERR_SIGGEN</a>, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"pgp failed\n"</span>));
00318         <span class="keywordflow">return</span> 1;
00319     }
00320 
00321     <span class="keywordflow">if</span> (stat(sigfile, &amp;st)) {
00322         <span class="comment">/* PGP failed to write signature */</span>
00323         <span class="keywordflow">if</span> (sigfile) (void) unlink(sigfile);  <span class="comment">/* Just in case */</span>
00324         <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a86">RPMERR_SIGGEN</a>, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"pgp failed to write signature\n"</span>));
00325         <span class="keywordflow">return</span> 1;
00326     }
00327 
00328     *size = st.st_size;
00329     <a class="code" href="rpmmessages_8h.html#a7">rpmMessage</a>(<a class="code" href="rpmmessages_8h.html#a0">RPMMESS_DEBUG</a>, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"PGP sig size: %d\n"</span>), *size);
00330     *sig = <a class="code" href="rpmmalloc_8c.html#a1">xmalloc</a>(*size);
00331 
00332     {   <a class="code" href="struct__FD__s.html">FD_t</a> fd;
00333         rc = 0;
00334         fd = <a class="code" href="group__rpmio.html#a83">Fopen</a>(sigfile, <span class="stringliteral">"r.fdio"</span>);
00335         <span class="keywordflow">if</span> (fd != NULL &amp;&amp; !<a class="code" href="group__rpmio.html#a85">Ferror</a>(fd)) {
00336             rc = <a class="code" href="rpmio_8h.html#a8">timedRead</a>(fd, *sig, *size);
00337             <span class="keywordflow">if</span> (sigfile) (void) unlink(sigfile);
00338             (void) <a class="code" href="group__rpmio.html#a80">Fclose</a>(fd);
00339         }
00340         <span class="keywordflow">if</span> (rc != *size) {
00341             *sig = <a class="code" href="poptint_8h.html#a14">_free</a>(*sig);
00342             <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a86">RPMERR_SIGGEN</a>, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"unable to read the signature\n"</span>));
00343             <span class="keywordflow">return</span> 1;
00344         }
00345     }
00346 
00347     <a class="code" href="rpmmessages_8h.html#a7">rpmMessage</a>(<a class="code" href="rpmmessages_8h.html#a0">RPMMESS_DEBUG</a>, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"Got %d bytes of PGP sig\n"</span>), *size);
00348 
00349     <span class="keywordflow">return</span> 0;
00350 }
00351 
00352 <span class="comment">/* This is an adaptation of the makePGPSignature function to use GPG instead</span>
00353 <span class="comment"> * of PGP to create signatures.  I think I've made all the changes necessary,</span>
00354 <span class="comment"> * but this could be a good place to start looking if errors in GPG signature</span>
00355 <span class="comment"> * creation crop up.</span>
00356 <span class="comment"> */</span>
<a name="l00357"></a><a class="code" href="signature_8c.html#a11">00357</a> <span class="keyword">static</span> <span class="keywordtype">int</span> <a class="code" href="signature_8c.html#a11">makeGPGSignature</a>(<span class="keyword">const</span> <span class="keywordtype">char</span> * file, <span class="comment">/*@out@*/</span> <span class="keywordtype">void</span> ** sig,
00358                 <span class="comment">/*@out@*/</span> <a class="code" href="header_8h.html#a9">int_32</a> * size, <span class="comment">/*@null@*/</span> <span class="keyword">const</span> <span class="keywordtype">char</span> * passPhrase)
00359         <span class="comment">/*@globals rpmGlobalMacroContext, fileSystem @*/</span>
00360         <span class="comment">/*@modifies *sig, *size, rpmGlobalMacroContext, fileSystem @*/</span>
00361 {
00362     <span class="keywordtype">char</span> * sigfile = <a class="code" href="system_8h.html#a36">alloca</a>(1024);
00363     <span class="keywordtype">int</span> pid, status;
00364     <span class="keywordtype">int</span> inpipe[2];
00365     FILE * fpipe;
00366     <span class="keyword">struct </span>stat st;
00367     <span class="keyword">const</span> <span class="keywordtype">char</span> * cmd;
00368     <span class="keywordtype">char</span> *<span class="keyword">const</span> *av;
00369     <span class="keywordtype">int</span> rc;
00370 
00371     (void) <a class="code" href="system_8h.html#a32">stpcpy</a>( <a class="code" href="system_8h.html#a32">stpcpy</a>(sigfile, file), <span class="stringliteral">".sig"</span>);
00372 
00373     <a class="code" href="macro_8c.html#a43">addMacro</a>(NULL, <span class="stringliteral">"__plaintext_filename"</span>, NULL, file, -1);
00374     <a class="code" href="macro_8c.html#a43">addMacro</a>(NULL, <span class="stringliteral">"__signature_filename"</span>, NULL, sigfile, -1);
00375 
00376     inpipe[0] = inpipe[1] = 0;
00377     (void) pipe(inpipe);
00378 
00379     <span class="keywordflow">if</span> (!(pid = fork())) {
00380         <span class="keyword">const</span> <span class="keywordtype">char</span> *gpg_path = <a class="code" href="macro_8c.html#a50">rpmExpand</a>(<span class="stringliteral">"%{?_gpg_path}"</span>, NULL);
00381 
00382         (void) close(STDIN_FILENO);
00383         (void) dup2(inpipe[0], 3);
00384         (void) close(inpipe[1]);
00385 
00386         <span class="keywordflow">if</span> (gpg_path &amp;&amp; *gpg_path != <span class="charliteral">'\0'</span>)
00387             (void) <a class="code" href="lib_2misc_8c.html#a6">dosetenv</a>(<span class="stringliteral">"GNUPGHOME"</span>, gpg_path, 1);
00388 
00389         cmd = <a class="code" href="macro_8c.html#a50">rpmExpand</a>(<span class="stringliteral">"%{?__gpg_sign_cmd}"</span>, NULL);
00390         rc = <a class="code" href="group__popt.html#a2">poptParseArgvString</a>(cmd, NULL, (<span class="keyword">const</span> <span class="keywordtype">char</span> ***)&amp;av);
00391         <span class="keywordflow">if</span> (!rc)
00392             rc = execve(av[0], av+1, <a class="code" href="signature_8c.html#a1">environ</a>);
00393 
00394         <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a56">RPMERR_EXEC</a>, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"Could not exec %s: %s\n"</span>), <span class="stringliteral">"gpg"</span>,
00395                         <a class="code" href="popt_8c.html#a1">strerror</a>(<a class="code" href="system_8h.html#a29">errno</a>));
00396         _exit(<a class="code" href="rpmerr_8h.html#a91a56">RPMERR_EXEC</a>);
00397     }
00398 
00399     <a class="code" href="macro_8c.html#a44">delMacro</a>(NULL, <span class="stringliteral">"__plaintext_filename"</span>);
00400     <a class="code" href="macro_8c.html#a44">delMacro</a>(NULL, <span class="stringliteral">"__signature_filename"</span>);
00401 
00402     fpipe = fdopen(inpipe[1], <span class="stringliteral">"w"</span>);
00403     (void) close(inpipe[0]);
00404     <span class="keywordflow">if</span> (fpipe) {
00405         fprintf(fpipe, <span class="stringliteral">"%s\n"</span>, (passPhrase ? passPhrase : <span class="stringliteral">""</span>));
00406         (void) fclose(fpipe);
00407     }
00408 
00409     (void)waitpid(pid, &amp;status, 0);
00410     <span class="keywordflow">if</span> (!WIFEXITED(status) || WEXITSTATUS(status)) {
00411         <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a86">RPMERR_SIGGEN</a>, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"gpg failed\n"</span>));
00412         <span class="keywordflow">return</span> 1;
00413     }
00414 
00415     <span class="keywordflow">if</span> (stat(sigfile, &amp;st)) {
00416         <span class="comment">/* GPG failed to write signature */</span>
00417         <span class="keywordflow">if</span> (sigfile) (void) unlink(sigfile);  <span class="comment">/* Just in case */</span>
00418         <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a86">RPMERR_SIGGEN</a>, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"gpg failed to write signature\n"</span>));
00419         <span class="keywordflow">return</span> 1;
00420     }
00421 
00422     *size = st.st_size;
00423     <a class="code" href="rpmmessages_8h.html#a7">rpmMessage</a>(<a class="code" href="rpmmessages_8h.html#a0">RPMMESS_DEBUG</a>, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"GPG sig size: %d\n"</span>), *size);
00424     *sig = <a class="code" href="rpmmalloc_8c.html#a1">xmalloc</a>(*size);
00425 
00426     {   <a class="code" href="struct__FD__s.html">FD_t</a> fd;
00427         <span class="keywordtype">int</span> rc = 0;
00428         fd = <a class="code" href="group__rpmio.html#a83">Fopen</a>(sigfile, <span class="stringliteral">"r.fdio"</span>);
00429         <span class="keywordflow">if</span> (fd != NULL &amp;&amp; !<a class="code" href="group__rpmio.html#a85">Ferror</a>(fd)) {
00430             rc = <a class="code" href="rpmio_8h.html#a8">timedRead</a>(fd, *sig, *size);
00431             <span class="keywordflow">if</span> (sigfile) (void) unlink(sigfile);
00432             (void) <a class="code" href="group__rpmio.html#a80">Fclose</a>(fd);
00433         }
00434         <span class="keywordflow">if</span> (rc != *size) {
00435             *sig = <a class="code" href="poptint_8h.html#a14">_free</a>(*sig);
00436             <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a86">RPMERR_SIGGEN</a>, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"unable to read the signature\n"</span>));
00437             <span class="keywordflow">return</span> 1;
00438         }
00439     }
00440 
00441     <a class="code" href="rpmmessages_8h.html#a7">rpmMessage</a>(<a class="code" href="rpmmessages_8h.html#a0">RPMMESS_DEBUG</a>, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"Got %d bytes of GPG sig\n"</span>), *size);
00442 
00443     <span class="keywordflow">return</span> 0;
00444 }
00445 
<a name="l00446"></a><a class="code" href="group__signature.html#a7">00446</a> <span class="keywordtype">int</span> <a class="code" href="group__signature.html#a7">rpmAddSignature</a>(<a class="code" href="structheaderToken.html">Header</a> h, <span class="keyword">const</span> <span class="keywordtype">char</span> * file, <a class="code" href="header_8h.html#a9">int_32</a> sigTag,
00447                 <span class="keyword">const</span> <span class="keywordtype">char</span> *passPhrase)
00448 {
00449     <span class="keyword">struct </span>stat st;
00450     <a class="code" href="header_8h.html#a9">int_32</a> size;
00451     byte buf[16];
00452     <span class="keywordtype">void</span> *sig;
00453     <span class="keywordtype">int</span> ret = -1;
00454 
00455     <span class="keywordflow">switch</span> (sigTag) {
00456     <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a11a398">RPMSIGTAG_SIZE</a>:
00457         (void) stat(file, &amp;st);
00458         size = st.st_size;
00459         ret = 0;
00460         (void) <a class="code" href="group__header.html#a45">headerAddEntry</a>(h, <a class="code" href="group__signature.html#a11a398">RPMSIGTAG_SIZE</a>, <a class="code" href="group__header.html#a93a70">RPM_INT32_TYPE</a>, &amp;size, 1);
00461         <span class="keywordflow">break</span>;
00462     <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a11a402">RPMSIGTAG_MD5</a>:
00463         ret = <a class="code" href="misc_8h.html#a15">mdbinfile</a>(file, buf);
00464         <span class="keywordflow">if</span> (ret == 0)
00465             (void) <a class="code" href="group__header.html#a45">headerAddEntry</a>(h, sigTag, <a class="code" href="group__header.html#a93a72">RPM_BIN_TYPE</a>, buf, 16);
00466         <span class="keywordflow">break</span>;
00467     <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a11a404">RPMSIGTAG_PGP5</a>:        <span class="comment">/* XXX legacy */</span>
00468     <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a11a400">RPMSIGTAG_PGP</a>:
00469         <a class="code" href="rpmmessages_8h.html#a7">rpmMessage</a>(<a class="code" href="rpmmessages_8h.html#a1">RPMMESS_VERBOSE</a>, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"Generating signature using PGP.\n"</span>));
00470         ret = <a class="code" href="signature_8c.html#a10">makePGPSignature</a>(file, &amp;sig, &amp;size, passPhrase);
00471         <span class="keywordflow">if</span> (ret == 0)
00472             (void) <a class="code" href="group__header.html#a45">headerAddEntry</a>(h, sigTag, <a class="code" href="group__header.html#a93a72">RPM_BIN_TYPE</a>, sig, size);
00473         <span class="keywordflow">break</span>;
00474     <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a11a403">RPMSIGTAG_GPG</a>:
00475         <a class="code" href="rpmmessages_8h.html#a7">rpmMessage</a>(<a class="code" href="rpmmessages_8h.html#a1">RPMMESS_VERBOSE</a>, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"Generating signature using GPG.\n"</span>));
00476         ret = <a class="code" href="signature_8c.html#a11">makeGPGSignature</a>(file, &amp;sig, &amp;size, passPhrase);
00477         <span class="keywordflow">if</span> (ret == 0)
00478             (void) <a class="code" href="group__header.html#a45">headerAddEntry</a>(h, sigTag, <a class="code" href="group__header.html#a93a72">RPM_BIN_TYPE</a>, sig, size);
00479         <span class="keywordflow">break</span>;
00480     }
00481 
00482     <span class="keywordflow">return</span> ret;
00483 }
00484 
00485 <span class="keyword">static</span> <a class="code" href="rpmlib_8h.html#a88">rpmVerifySignatureReturn</a>
<a name="l00486"></a><a class="code" href="signature_8c.html#a13">00486</a> <a class="code" href="signature_8c.html#a13">verifySizeSignature</a>(<span class="keyword">const</span> <span class="keywordtype">char</span> * datafile, <a class="code" href="header_8h.html#a9">int_32</a> size, <span class="comment">/*@out@*/</span> <span class="keywordtype">char</span> * result)
00487         <span class="comment">/*@globals fileSystem @*/</span>
00488         <span class="comment">/*@modifies *result, fileSystem @*/</span>
00489 {
00490     <span class="keyword">struct </span>stat st;
00491 
00492     (void) stat(datafile, &amp;st);
00493     <span class="keywordflow">if</span> (size != st.st_size) {
00494         sprintf(result, <span class="stringliteral">"Header+Archive size mismatch.\n"</span>
00495                 <span class="stringliteral">"Expected %d, saw %d.\n"</span>,
00496                 size, (<span class="keywordtype">int</span>)st.st_size);
00497         <span class="keywordflow">return</span> <a class="code" href="rpmlib_8h.html#a510a413">RPMSIG_BAD</a>;
00498     }
00499 
00500     sprintf(result, <span class="stringliteral">"Header+Archive size OK: %d bytes\n"</span>, size);
00501     <span class="keywordflow">return</span> <a class="code" href="rpmlib_8h.html#a510a411">RPMSIG_OK</a>;
00502 }
00503 
<a name="l00504"></a><a class="code" href="signature_8c.html#a0">00504</a> <span class="preprocessor">#define X(_x)   (unsigned)((_x) &amp; 0xff)</span>
00505 <span class="preprocessor"></span>
00506 <span class="keyword">static</span> <a class="code" href="rpmlib_8h.html#a88">rpmVerifySignatureReturn</a>
<a name="l00507"></a><a class="code" href="signature_8c.html#a14">00507</a> <a class="code" href="signature_8c.html#a14">verifyMD5Signature</a>(<span class="keyword">const</span> <span class="keywordtype">char</span> * datafile, <span class="keyword">const</span> byte * sig,
00508                               <span class="comment">/*@out@*/</span> <span class="keywordtype">char</span> * result, <a class="code" href="signature_8c.html#a2">md5func</a> fn)
00509         <span class="comment">/*@globals fileSystem @*/</span>
00510         <span class="comment">/*@modifies *result, fileSystem @*/</span>
00511 {
00512     byte md5sum[16];
00513 
00514     memset(md5sum, 0, <span class="keyword">sizeof</span>(md5sum));
00515     (void) fn(datafile, md5sum);
00516     <span class="keywordflow">if</span> (memcmp(md5sum, sig, 16)) {
00517         sprintf(result, <span class="stringliteral">"MD5 sum mismatch\n"</span>
00518                 <span class="stringliteral">"Expected: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"</span>
00519                 <span class="stringliteral">"%02x%02x%02x%02x%02x\n"</span>
00520                 <span class="stringliteral">"Saw     : %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"</span>
00521                 <span class="stringliteral">"%02x%02x%02x%02x%02x\n"</span>,
00522                 <a class="code" href="signature_8c.html#a0">X</a>(sig[0]),  <a class="code" href="signature_8c.html#a0">X</a>(sig[1]),  <a class="code" href="signature_8c.html#a0">X</a>(sig[2]),  <a class="code" href="signature_8c.html#a0">X</a>(sig[3]),
00523                 <a class="code" href="signature_8c.html#a0">X</a>(sig[4]),  <a class="code" href="signature_8c.html#a0">X</a>(sig[5]),  <a class="code" href="signature_8c.html#a0">X</a>(sig[6]),  <a class="code" href="signature_8c.html#a0">X</a>(sig[7]),
00524                 <a class="code" href="signature_8c.html#a0">X</a>(sig[8]),  <a class="code" href="signature_8c.html#a0">X</a>(sig[9]),  <a class="code" href="signature_8c.html#a0">X</a>(sig[10]), <a class="code" href="signature_8c.html#a0">X</a>(sig[11]),
00525                 <a class="code" href="signature_8c.html#a0">X</a>(sig[12]), <a class="code" href="signature_8c.html#a0">X</a>(sig[13]), <a class="code" href="signature_8c.html#a0">X</a>(sig[14]), <a class="code" href="signature_8c.html#a0">X</a>(sig[15]),
00526                 <a class="code" href="signature_8c.html#a0">X</a>(md5sum[0]),  <a class="code" href="signature_8c.html#a0">X</a>(md5sum[1]),  <a class="code" href="signature_8c.html#a0">X</a>(md5sum[2]),  <a class="code" href="signature_8c.html#a0">X</a>(md5sum[3]),
00527                 <a class="code" href="signature_8c.html#a0">X</a>(md5sum[4]),  <a class="code" href="signature_8c.html#a0">X</a>(md5sum[5]),  <a class="code" href="signature_8c.html#a0">X</a>(md5sum[6]),  <a class="code" href="signature_8c.html#a0">X</a>(md5sum[7]),
00528                 <a class="code" href="signature_8c.html#a0">X</a>(md5sum[8]),  <a class="code" href="signature_8c.html#a0">X</a>(md5sum[9]),  <a class="code" href="signature_8c.html#a0">X</a>(md5sum[10]), <a class="code" href="signature_8c.html#a0">X</a>(md5sum[11]),
00529                 <a class="code" href="signature_8c.html#a0">X</a>(md5sum[12]), <a class="code" href="signature_8c.html#a0">X</a>(md5sum[13]), <a class="code" href="signature_8c.html#a0">X</a>(md5sum[14]), <a class="code" href="signature_8c.html#a0">X</a>(md5sum[15]) );
00530         <span class="keywordflow">return</span> <a class="code" href="rpmlib_8h.html#a510a413">RPMSIG_BAD</a>;
00531     }
00532 
00533     sprintf(result, <span class="stringliteral">"MD5 sum OK: %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x"</span>
00534                     <span class="stringliteral">"%02x%02x%02x%02x%02x\n"</span>,
00535             <a class="code" href="signature_8c.html#a0">X</a>(md5sum[0]),  <a class="code" href="signature_8c.html#a0">X</a>(md5sum[1]),  <a class="code" href="signature_8c.html#a0">X</a>(md5sum[2]),  <a class="code" href="signature_8c.html#a0">X</a>(md5sum[3]),
00536             <a class="code" href="signature_8c.html#a0">X</a>(md5sum[4]),  <a class="code" href="signature_8c.html#a0">X</a>(md5sum[5]),  <a class="code" href="signature_8c.html#a0">X</a>(md5sum[6]),  <a class="code" href="signature_8c.html#a0">X</a>(md5sum[7]),
00537             <a class="code" href="signature_8c.html#a0">X</a>(md5sum[8]),  <a class="code" href="signature_8c.html#a0">X</a>(md5sum[9]),  <a class="code" href="signature_8c.html#a0">X</a>(md5sum[10]), <a class="code" href="signature_8c.html#a0">X</a>(md5sum[11]),
00538             <a class="code" href="signature_8c.html#a0">X</a>(md5sum[12]), <a class="code" href="signature_8c.html#a0">X</a>(md5sum[13]), <a class="code" href="signature_8c.html#a0">X</a>(md5sum[14]), <a class="code" href="signature_8c.html#a0">X</a>(md5sum[15]) );
00539 
00540     <span class="keywordflow">return</span> <a class="code" href="rpmlib_8h.html#a510a411">RPMSIG_OK</a>;
00541 }
00542 
00543 <span class="keyword">static</span> <a class="code" href="rpmlib_8h.html#a88">rpmVerifySignatureReturn</a>
<a name="l00544"></a><a class="code" href="signature_8c.html#a15">00544</a> <a class="code" href="signature_8c.html#a15">verifyPGPSignature</a>(<span class="keyword">const</span> <span class="keywordtype">char</span> * datafile, <span class="keyword">const</span> <span class="keywordtype">void</span> * sig, <span class="keywordtype">int</span> count,
00545                 <span class="comment">/*@out@*/</span> <span class="keywordtype">char</span> * result)
00546         <span class="comment">/*@globals rpmGlobalMacroContext, fileSystem @*/</span>
00547         <span class="comment">/*@modifies *result, rpmGlobalMacroContext, fileSystem @*/</span>
00548 {
00549     <span class="keywordtype">int</span> pid, status, outpipe[2];
00550 <span class="comment">/*@only@*/</span> <span class="comment">/*@null@*/</span> <span class="keyword">const</span> <span class="keywordtype">char</span> * sigfile = NULL;
00551     byte buf[BUFSIZ];
00552     FILE *file;
00553     <span class="keywordtype">int</span> res = <a class="code" href="rpmlib_8h.html#a510a411">RPMSIG_OK</a>;
00554     <span class="keyword">const</span> <span class="keywordtype">char</span> *path;
00555     <a class="code" href="group__signature.html#a1">pgpVersion</a> pgpVer;
00556     <span class="keyword">const</span> <span class="keywordtype">char</span> * cmd;
00557     <span class="keywordtype">char</span> *<span class="keyword">const</span> *av;
00558     <span class="keywordtype">int</span> rc;
00559 
00560     <span class="comment">/* What version do we have? */</span>
00561     <span class="keywordflow">if</span> ((path = <a class="code" href="group__signature.html#a10">rpmDetectPGPVersion</a>(&amp;pgpVer)) == NULL) {
00562         <a class="code" href="system_8h.html#a29">errno</a> = ENOENT;
00563         <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a56">RPMERR_EXEC</a>, (<span class="stringliteral">"Could not exec %s: %s\n"</span>), <span class="stringliteral">"pgp"</span>,
00564                         <a class="code" href="popt_8c.html#a1">strerror</a>(<a class="code" href="system_8h.html#a29">errno</a>));
00565         _exit(<a class="code" href="rpmerr_8h.html#a91a56">RPMERR_EXEC</a>);
00566     }
00567 
00568     <span class="comment">/*</span>
00569 <span class="comment">     * Sad but true: pgp-5.0 returns exit value of 0 on bad signature.</span>
00570 <span class="comment">     * Instead we have to use the text output to detect a bad signature.</span>
00571 <span class="comment">     */</span>
00572     <span class="keywordflow">if</span> (pgpVer == <a class="code" href="group__signature.html#a13a16">PGP_5</a>)
00573         res = <a class="code" href="rpmlib_8h.html#a510a413">RPMSIG_BAD</a>;
00574 
00575     <span class="comment">/* Write out the signature */</span>
00576 <span class="preprocessor">#ifdef  DYING</span>
00577 <span class="preprocessor"></span>  { <span class="keyword">const</span> <span class="keywordtype">char</span> *tmppath = <a class="code" href="macro_8c.html#a53">rpmGetPath</a>(<span class="stringliteral">"%{_tmppath}"</span>, NULL);
00578     sigfile = tempnam(tmppath, <span class="stringliteral">"rpmsig"</span>);
00579     tmppath = <a class="code" href="poptint_8h.html#a14">_free</a>(tmppath);
00580   }
00581     sfd = <a class="code" href="group__rpmio.html#a83">Fopen</a>(sigfile, <span class="stringliteral">"w.fdio"</span>);
00582     <span class="keywordflow">if</span> (sfd != NULL &amp;&amp; !<a class="code" href="group__rpmio.html#a85">Ferror</a>(sfd)) {
00583         (void) <a class="code" href="group__rpmio.html#a78">Fwrite</a>(sig, <span class="keyword">sizeof</span>(<span class="keywordtype">char</span>), count, sfd);
00584         (void) <a class="code" href="group__rpmio.html#a80">Fclose</a>(sfd);
00585     }
00586 <span class="preprocessor">#else</span>
00587 <span class="preprocessor"></span>    {   <a class="code" href="struct__FD__s.html">FD_t</a> sfd;
00588         <span class="keywordflow">if</span> (!<a class="code" href="lib_2misc_8c.html#a8">makeTempFile</a>(NULL, &amp;sigfile, &amp;sfd)) {
00589             (void) <a class="code" href="group__rpmio.html#a78">Fwrite</a>(sig, <span class="keyword">sizeof</span>(<span class="keywordtype">char</span>), count, sfd);
00590             (void) <a class="code" href="group__rpmio.html#a80">Fclose</a>(sfd);
00591             sfd = NULL;
00592         }
00593     }
00594 <span class="preprocessor">#endif</span>
00595 <span class="preprocessor"></span>    <span class="keywordflow">if</span> (sigfile == NULL)
00596         <span class="keywordflow">return</span> <a class="code" href="rpmlib_8h.html#a510a413">RPMSIG_BAD</a>;
00597 
00598     <a class="code" href="macro_8c.html#a43">addMacro</a>(NULL, <span class="stringliteral">"__plaintext_filename"</span>, NULL, datafile, -1);
00599     <a class="code" href="macro_8c.html#a43">addMacro</a>(NULL, <span class="stringliteral">"__signature_filename"</span>, NULL, sigfile, -1);
00600 
00601     <span class="comment">/* Now run PGP */</span>
00602     outpipe[0] = outpipe[1] = 0;
00603     (void) pipe(outpipe);
00604 
00605     <span class="keywordflow">if</span> (!(pid = fork())) {
00606         <span class="keyword">const</span> <span class="keywordtype">char</span> *pgp_path = <a class="code" href="macro_8c.html#a50">rpmExpand</a>(<span class="stringliteral">"%{?_pgp_path}"</span>, NULL);
00607 
00608         (void) close(outpipe[0]);
00609         (void) close(STDOUT_FILENO);    <span class="comment">/* XXX unnecessary */</span>
00610         (void) dup2(outpipe[1], STDOUT_FILENO);
00611 
00612         <span class="keywordflow">if</span> (pgp_path &amp;&amp; *pgp_path != <span class="charliteral">'\0'</span>)
00613             (void) <a class="code" href="lib_2misc_8c.html#a6">dosetenv</a>(<span class="stringliteral">"PGPPATH"</span>, pgp_path, 1);
00614 
00615         <span class="keywordflow">switch</span> (pgpVer) {
00616         <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a13a15">PGP_2</a>:
00617             cmd = <a class="code" href="macro_8c.html#a50">rpmExpand</a>(<span class="stringliteral">"%{?__pgp_verify_cmd}"</span>, NULL);
00618             rc = <a class="code" href="group__popt.html#a2">poptParseArgvString</a>(cmd, NULL, (<span class="keyword">const</span> <span class="keywordtype">char</span> ***)&amp;av);
00619             <span class="keywordflow">if</span> (!rc)
00620                 rc = execve(av[0], av+1, <a class="code" href="signature_8c.html#a1">environ</a>);
00621             <span class="keywordflow">break</span>;
00622         <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a13a16">PGP_5</a>:
00623             <span class="comment">/* Some output (in particular "This signature applies to */</span>
00624             <span class="comment">/* another message") is _always_ written to stderr; we   */</span>
00625             <span class="comment">/* want to catch that output, so dup stdout to stderr:   */</span>
00626         {   <span class="keywordtype">int</span> save_stderr = dup(2);
00627             (void) dup2(1, 2);
00628 
00629             cmd = <a class="code" href="macro_8c.html#a50">rpmExpand</a>(<span class="stringliteral">"%{?__pgp5_verify_cmd}"</span>, NULL);
00630             rc = <a class="code" href="group__popt.html#a2">poptParseArgvString</a>(cmd, NULL, (<span class="keyword">const</span> <span class="keywordtype">char</span> ***)&amp;av);
00631             <span class="keywordflow">if</span> (!rc)
00632                 rc = execve(av[0], av+1, <a class="code" href="signature_8c.html#a1">environ</a>);
00633 
00634             <span class="comment">/* Restore stderr so we can print the error message below. */</span>
00635             (void) dup2(save_stderr, 2);
00636             (void) close(save_stderr);
00637         }   <span class="keywordflow">break</span>;
00638         <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a13a14">PGP_UNKNOWN</a>:
00639         <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a13a13">PGP_NOTDETECTED</a>:
00640             <span class="keywordflow">break</span>;
00641         }
00642 
00643         <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a56">RPMERR_EXEC</a>, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"Could not exec %s: %s\n"</span>), <span class="stringliteral">"pgp"</span>,
00644                         <a class="code" href="popt_8c.html#a1">strerror</a>(<a class="code" href="system_8h.html#a29">errno</a>));
00645         _exit(<a class="code" href="rpmerr_8h.html#a91a56">RPMERR_EXEC</a>);
00646     }
00647 
00648     <a class="code" href="macro_8c.html#a44">delMacro</a>(NULL, <span class="stringliteral">"__plaintext_filename"</span>);
00649     <a class="code" href="macro_8c.html#a44">delMacro</a>(NULL, <span class="stringliteral">"__signature_filename"</span>);
00650 
00651     (void) close(outpipe[1]);
00652     file = fdopen(outpipe[0], <span class="stringliteral">"r"</span>);
00653     result[0] = <span class="charliteral">'\0'</span>;
00654     <span class="keywordflow">if</span> (file) {
00655         <span class="keywordtype">char</span> *t = result;
00656         <span class="keywordtype">int</span> nb = 8*BUFSIZ - 1;
00657         <span class="keywordflow">while</span> (fgets(buf, 1024, file)) {
00658             <span class="keywordflow">if</span> (strncmp(<span class="stringliteral">"File '"</span>, buf, 6) &amp;&amp;
00659                 strncmp(<span class="stringliteral">"Text is assu"</span>, buf, 12) &amp;&amp;
00660                 strncmp(<span class="stringliteral">"This signature applies to another message"</span>, buf, 41) &amp;&amp;
00661                 buf[0] != <span class="charliteral">'\n'</span>) {
00662                     nb -= strlen(buf);
00663                     <span class="keywordflow">if</span> (nb &gt; 0) t = <a class="code" href="system_8h.html#a33">stpncpy</a>(t, buf, nb);
00664             }
00665             <span class="keywordflow">if</span> (!strncmp(<span class="stringliteral">"WARNING: Can't find the right public key"</span>, buf, 40))
00666                 res = <a class="code" href="rpmlib_8h.html#a510a414">RPMSIG_NOKEY</a>;
00667             <span class="keywordflow">else</span> <span class="keywordflow">if</span> (!strncmp(<span class="stringliteral">"Signature by unknown keyid:"</span>, buf, 27))
00668                 res = <a class="code" href="rpmlib_8h.html#a510a414">RPMSIG_NOKEY</a>;
00669             <span class="keywordflow">else</span> <span class="keywordflow">if</span> (!strncmp(<span class="stringliteral">"WARNING: The signing key is not trusted"</span>, buf, 39))
00670                 res = <a class="code" href="rpmlib_8h.html#a510a415">RPMSIG_NOTTRUSTED</a>;
00671             <span class="keywordflow">else</span> <span class="keywordflow">if</span> (!strncmp(<span class="stringliteral">"Good signature"</span>, buf, 14))
00672                 res = <a class="code" href="rpmlib_8h.html#a510a411">RPMSIG_OK</a>;
00673         }
00674         (void) fclose(file);
00675         *t = <span class="charliteral">'\0'</span>;
00676     }
00677 
00678     (void) waitpid(pid, &amp;status, 0);
00679     <span class="keywordflow">if</span> (sigfile) (void) unlink(sigfile);
00680     sigfile = <a class="code" href="poptint_8h.html#a14">_free</a>(sigfile);
00681     <span class="keywordflow">if</span> (!res &amp;&amp; (!WIFEXITED(status) || WEXITSTATUS(status))) {
00682         res = <a class="code" href="rpmlib_8h.html#a510a413">RPMSIG_BAD</a>;
00683     }
00684 
00685     <span class="keywordflow">return</span> res;
00686 }
00687 
00688 <span class="keyword">static</span> <a class="code" href="rpmlib_8h.html#a88">rpmVerifySignatureReturn</a>
<a name="l00689"></a><a class="code" href="signature_8c.html#a16">00689</a> <a class="code" href="signature_8c.html#a16">verifyGPGSignature</a>(<span class="keyword">const</span> <span class="keywordtype">char</span> * datafile, <span class="keyword">const</span> <span class="keywordtype">void</span> * sig, <span class="keywordtype">int</span> count,
00690                 <span class="comment">/*@out@*/</span> <span class="keywordtype">char</span> * result)
00691         <span class="comment">/*@globals rpmGlobalMacroContext, fileSystem @*/</span>
00692         <span class="comment">/*@modifies *result, rpmGlobalMacroContext, fileSystem @*/</span>
00693 {
00694     <span class="keywordtype">int</span> pid, status, outpipe[2];
00695 <span class="comment">/*@only@*/</span> <span class="comment">/*@null@*/</span> <span class="keyword">const</span> <span class="keywordtype">char</span> * sigfile = NULL;
00696     byte buf[BUFSIZ];
00697     FILE *file;
00698     <span class="keywordtype">int</span> res = <a class="code" href="rpmlib_8h.html#a510a411">RPMSIG_OK</a>;
00699     <span class="keyword">const</span> <span class="keywordtype">char</span> * cmd;
00700     <span class="keywordtype">char</span> *<span class="keyword">const</span> *av;
00701     <span class="keywordtype">int</span> rc;
00702 
00703     <span class="comment">/* Write out the signature */</span>
00704 <span class="preprocessor">#ifdef  DYING</span>
00705 <span class="preprocessor"></span>  { <span class="keyword">const</span> <span class="keywordtype">char</span> *tmppath = <a class="code" href="macro_8c.html#a53">rpmGetPath</a>(<span class="stringliteral">"%{_tmppath}"</span>, NULL);
00706     sigfile = tempnam(tmppath, <span class="stringliteral">"rpmsig"</span>);
00707     tmppath = <a class="code" href="poptint_8h.html#a14">_free</a>(tmppath);
00708   }
00709     sfd = <a class="code" href="group__rpmio.html#a83">Fopen</a>(sigfile, <span class="stringliteral">"w.fdio"</span>);
00710     <span class="keywordflow">if</span> (sfd != NULL &amp;&amp; !<a class="code" href="group__rpmio.html#a85">Ferror</a>(sfd)) {
00711         (void) <a class="code" href="group__rpmio.html#a78">Fwrite</a>(sig, <span class="keyword">sizeof</span>(<span class="keywordtype">char</span>), count, sfd);
00712         (void) <a class="code" href="group__rpmio.html#a80">Fclose</a>(sfd);
00713     }
00714 <span class="preprocessor">#else</span>
00715 <span class="preprocessor"></span>    {   <a class="code" href="struct__FD__s.html">FD_t</a> sfd;
00716         <span class="keywordflow">if</span> (!<a class="code" href="lib_2misc_8c.html#a8">makeTempFile</a>(NULL, &amp;sigfile, &amp;sfd)) {
00717             (void) <a class="code" href="group__rpmio.html#a78">Fwrite</a>(sig, <span class="keyword">sizeof</span>(<span class="keywordtype">char</span>), count, sfd);
00718             (void) <a class="code" href="group__rpmio.html#a80">Fclose</a>(sfd);
00719             sfd = NULL;
00720         }
00721     }
00722 <span class="preprocessor">#endif</span>
00723 <span class="preprocessor"></span>    <span class="keywordflow">if</span> (sigfile == NULL)
00724         <span class="keywordflow">return</span> <a class="code" href="rpmlib_8h.html#a510a413">RPMSIG_BAD</a>;
00725 
00726     <a class="code" href="macro_8c.html#a43">addMacro</a>(NULL, <span class="stringliteral">"__plaintext_filename"</span>, NULL, datafile, -1);
00727     <a class="code" href="macro_8c.html#a43">addMacro</a>(NULL, <span class="stringliteral">"__signature_filename"</span>, NULL, sigfile, -1);
00728 
00729     <span class="comment">/* Now run GPG */</span>
00730     outpipe[0] = outpipe[1] = 0;
00731     (void) pipe(outpipe);
00732 
00733     <span class="keywordflow">if</span> (!(pid = fork())) {
00734         <span class="keyword">const</span> <span class="keywordtype">char</span> *gpg_path = <a class="code" href="macro_8c.html#a50">rpmExpand</a>(<span class="stringliteral">"%{?_gpg_path}"</span>, NULL);
00735 
00736         (void) close(outpipe[0]);
00737         <span class="comment">/* gpg version 0.9 sends its output to stderr. */</span>
00738         (void) dup2(outpipe[1], STDERR_FILENO);
00739 
00740         <span class="keywordflow">if</span> (gpg_path &amp;&amp; *gpg_path != <span class="charliteral">'\0'</span>)
00741             (void) <a class="code" href="lib_2misc_8c.html#a6">dosetenv</a>(<span class="stringliteral">"GNUPGHOME"</span>, gpg_path, 1);
00742 
00743         cmd = <a class="code" href="macro_8c.html#a50">rpmExpand</a>(<span class="stringliteral">"%{?__gpg_verify_cmd}"</span>, NULL);
00744         rc = <a class="code" href="group__popt.html#a2">poptParseArgvString</a>(cmd, NULL, (<span class="keyword">const</span> <span class="keywordtype">char</span> ***)&amp;av);
00745         <span class="keywordflow">if</span> (!rc)
00746             rc = execve(av[0], av+1, <a class="code" href="signature_8c.html#a1">environ</a>);
00747 
00748         <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a56">RPMERR_EXEC</a>, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"Could not exec %s: %s\n"</span>), <span class="stringliteral">"gpg"</span>,
00749                         <a class="code" href="popt_8c.html#a1">strerror</a>(<a class="code" href="system_8h.html#a29">errno</a>));
00750         _exit(<a class="code" href="rpmerr_8h.html#a91a56">RPMERR_EXEC</a>);
00751     }
00752 
00753     <a class="code" href="macro_8c.html#a44">delMacro</a>(NULL, <span class="stringliteral">"__plaintext_filename"</span>);
00754     <a class="code" href="macro_8c.html#a44">delMacro</a>(NULL, <span class="stringliteral">"__signature_filename"</span>);
00755 
00756     (void) close(outpipe[1]);
00757     file = fdopen(outpipe[0], <span class="stringliteral">"r"</span>);
00758     result[0] = <span class="charliteral">'\0'</span>;
00759     <span class="keywordflow">if</span> (file) {
00760         <span class="keywordtype">char</span> * t = result;
00761         <span class="keywordtype">int</span> nb = 8*BUFSIZ - 1;
00762         <span class="keywordflow">while</span> (fgets(buf, 1024, file)) {
00763             nb -= strlen(buf);
00764             <span class="keywordflow">if</span> (nb &gt; 0) t = <a class="code" href="system_8h.html#a33">stpncpy</a>(t, buf, nb);
00765             <span class="keywordflow">if</span> (!<a class="code" href="group__rpmio.html#a1">xstrncasecmp</a>(<span class="stringliteral">"gpg: Can't check signature: Public key not found"</span>, buf, 48)) {
00766                 res = <a class="code" href="rpmlib_8h.html#a510a414">RPMSIG_NOKEY</a>;
00767             }
00768         }
00769         (void) fclose(file);
00770         *t = <span class="charliteral">'\0'</span>;
00771     }
00772 
00773     (void) waitpid(pid, &amp;status, 0);
00774     <span class="keywordflow">if</span> (sigfile) (void) unlink(sigfile);
00775     sigfile = <a class="code" href="poptint_8h.html#a14">_free</a>(sigfile);
00776     <span class="keywordflow">if</span> (!res &amp;&amp; (!WIFEXITED(status) || WEXITSTATUS(status))) {
00777         res = <a class="code" href="rpmlib_8h.html#a510a413">RPMSIG_BAD</a>;
00778     }
00779 
00780     <span class="keywordflow">return</span> res;
00781 }
00782 
<a name="l00783"></a><a class="code" href="signature_8c.html#a17">00783</a> <span class="keyword">static</span> <span class="keywordtype">int</span> <a class="code" href="signature_8c.html#a17">checkPassPhrase</a>(<span class="keyword">const</span> <span class="keywordtype">char</span> * passPhrase, <span class="keyword">const</span> <span class="keywordtype">int</span> sigTag)
00784         <span class="comment">/*@globals rpmGlobalMacroContext, fileSystem @*/</span>
00785         <span class="comment">/*@modifies rpmGlobalMacroContext, fileSystem @*/</span>
00786 {
00787     <span class="keywordtype">int</span> passPhrasePipe[2];
00788     <span class="keywordtype">int</span> pid, status;
00789     <span class="keywordtype">int</span> fd;
00790     <span class="keyword">const</span> <span class="keywordtype">char</span> * cmd;
00791     <span class="keywordtype">char</span> *<span class="keyword">const</span> *av;
00792     <span class="keywordtype">int</span> rc;
00793 
00794     passPhrasePipe[0] = passPhrasePipe[1] = 0;
00795     (void) pipe(passPhrasePipe);
00796     <span class="keywordflow">if</span> (!(pid = fork())) {
00797         (void) close(STDIN_FILENO);
00798         (void) close(STDOUT_FILENO);
00799         (void) close(passPhrasePipe[1]);
00800         <span class="keywordflow">if</span> (! <a class="code" href="rpmmessages_8h.html#a12">rpmIsVerbose</a>()) {
00801             (void) close(STDERR_FILENO);
00802         }
00803         <span class="keywordflow">if</span> ((fd = open(<span class="stringliteral">"/dev/null"</span>, O_RDONLY)) != STDIN_FILENO) {
00804             (void) dup2(fd, STDIN_FILENO);
00805             (void) close(fd);
00806         }
00807         <span class="keywordflow">if</span> ((fd = open(<span class="stringliteral">"/dev/null"</span>, O_WRONLY)) != STDOUT_FILENO) {
00808             (void) dup2(fd, STDOUT_FILENO);
00809             (void) close(fd);
00810         }
00811         (void) dup2(passPhrasePipe[0], 3);
00812 
00813         <span class="keywordflow">switch</span> (sigTag) {
00814         <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a11a403">RPMSIGTAG_GPG</a>:
00815         {   <span class="keyword">const</span> <span class="keywordtype">char</span> *gpg_path = <a class="code" href="macro_8c.html#a50">rpmExpand</a>(<span class="stringliteral">"%{?_gpg_path}"</span>, NULL);
00816 
00817             <span class="keywordflow">if</span> (gpg_path &amp;&amp; *gpg_path != <span class="charliteral">'\0'</span>)
00818                 (void) <a class="code" href="lib_2misc_8c.html#a6">dosetenv</a>(<span class="stringliteral">"GNUPGHOME"</span>, gpg_path, 1);
00819 
00820             cmd = <a class="code" href="macro_8c.html#a50">rpmExpand</a>(<span class="stringliteral">"%{?__gpg_check_password_cmd}"</span>, NULL);
00821             rc = <a class="code" href="group__popt.html#a2">poptParseArgvString</a>(cmd, NULL, (<span class="keyword">const</span> <span class="keywordtype">char</span> ***)&amp;av);
00822             <span class="keywordflow">if</span> (!rc)
00823                 rc = execve(av[0], av+1, <a class="code" href="signature_8c.html#a1">environ</a>);
00824 
00825             <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a56">RPMERR_EXEC</a>, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"Could not exec %s: %s\n"</span>), <span class="stringliteral">"gpg"</span>,
00826                         <a class="code" href="popt_8c.html#a1">strerror</a>(<a class="code" href="system_8h.html#a29">errno</a>));
00827             _exit(<a class="code" href="rpmerr_8h.html#a91a56">RPMERR_EXEC</a>);
00828         }   <span class="comment">/*@notreached@*/</span> <span class="keywordflow">break</span>;
00829         <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a11a404">RPMSIGTAG_PGP5</a>:    <span class="comment">/* XXX legacy */</span>
00830         <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a11a400">RPMSIGTAG_PGP</a>:
00831         {   <span class="keyword">const</span> <span class="keywordtype">char</span> *pgp_path = <a class="code" href="macro_8c.html#a50">rpmExpand</a>(<span class="stringliteral">"%{?_pgp_path}"</span>, NULL);
00832             <span class="keyword">const</span> <span class="keywordtype">char</span> *path;
00833             <a class="code" href="group__signature.html#a1">pgpVersion</a> pgpVer;
00834 
00835             (void) <a class="code" href="lib_2misc_8c.html#a6">dosetenv</a>(<span class="stringliteral">"PGPPASSFD"</span>, <span class="stringliteral">"3"</span>, 1);
00836             <span class="keywordflow">if</span> (pgp_path &amp;&amp; *pgp_path != <span class="charliteral">'\0'</span>)
00837                 (void) <a class="code" href="lib_2misc_8c.html#a6">dosetenv</a>(<span class="stringliteral">"PGPPATH"</span>, pgp_path, 1);
00838 
00839             <span class="keywordflow">if</span> ((path = <a class="code" href="group__signature.html#a10">rpmDetectPGPVersion</a>(&amp;pgpVer)) != NULL) {
00840                 <span class="keywordflow">switch</span>(pgpVer) {
00841                 <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a13a15">PGP_2</a>:
00842                     cmd = <a class="code" href="macro_8c.html#a50">rpmExpand</a>(<span class="stringliteral">"%{?__pgp_check_password_cmd}"</span>, NULL);
00843                     rc = <a class="code" href="group__popt.html#a2">poptParseArgvString</a>(cmd, NULL, (<span class="keyword">const</span> <span class="keywordtype">char</span> ***)&amp;av);
00844                     <span class="keywordflow">if</span> (!rc)
00845                         rc = execve(av[0], av+1, <a class="code" href="signature_8c.html#a1">environ</a>);
00846                     <span class="keywordflow">break</span>;
00847                 <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a13a16">PGP_5</a>:     <span class="comment">/* XXX legacy */</span>
00848                     cmd = <a class="code" href="macro_8c.html#a50">rpmExpand</a>(<span class="stringliteral">"%{?__pgp5_check_password_cmd}"</span>, NULL);
00849                     rc = <a class="code" href="group__popt.html#a2">poptParseArgvString</a>(cmd, NULL, (<span class="keyword">const</span> <span class="keywordtype">char</span> ***)&amp;av);
00850                     <span class="keywordflow">if</span> (!rc)
00851                         rc = execve(av[0], av+1, <a class="code" href="signature_8c.html#a1">environ</a>);
00852                     <span class="keywordflow">break</span>;
00853                 <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a13a14">PGP_UNKNOWN</a>:
00854                 <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a13a13">PGP_NOTDETECTED</a>:
00855                     <span class="keywordflow">break</span>;
00856                 }
00857             }
00858             <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a56">RPMERR_EXEC</a>, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"Could not exec %s: %s\n"</span>), <span class="stringliteral">"pgp"</span>,
00859                         <a class="code" href="popt_8c.html#a1">strerror</a>(<a class="code" href="system_8h.html#a29">errno</a>));
00860             _exit(<a class="code" href="rpmerr_8h.html#a91a56">RPMERR_EXEC</a>);
00861         }   <span class="comment">/*@notreached@*/</span> <span class="keywordflow">break</span>;
00862         <span class="keywordflow">default</span>: <span class="comment">/* This case should have been screened out long ago. */</span>
00863             <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a86">RPMERR_SIGGEN</a>, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"Invalid %%_signature spec in macro file\n"</span>));
00864             _exit(<a class="code" href="rpmerr_8h.html#a91a86">RPMERR_SIGGEN</a>);
00865             <span class="comment">/*@notreached@*/</span> <span class="keywordflow">break</span>;
00866         }
00867     }
00868 
00869     (void) close(passPhrasePipe[0]);
00870     (void) write(passPhrasePipe[1], passPhrase, strlen(passPhrase));
00871     (void) write(passPhrasePipe[1], <span class="stringliteral">"\n"</span>, 1);
00872     (void) close(passPhrasePipe[1]);
00873 
00874     (void)waitpid(pid, &amp;status, 0);
00875     <span class="keywordflow">if</span> (!WIFEXITED(status) || WEXITSTATUS(status)) {
00876         <span class="keywordflow">return</span> 1;
00877     }
00878 
00879     <span class="comment">/* passPhrase is good */</span>
00880     <span class="keywordflow">return</span> 0;
00881 }
00882 
<a name="l00883"></a><a class="code" href="group__signature.html#a9">00883</a> <span class="keywordtype">char</span> * <a class="code" href="group__signature.html#a9">rpmGetPassPhrase</a>(<span class="keyword">const</span> <span class="keywordtype">char</span> * prompt, <span class="keyword">const</span> <span class="keywordtype">int</span> sigTag)
00884 {
00885     <span class="keywordtype">char</span> *pass;
00886     <span class="keywordtype">int</span> aok;
00887 
00888     <span class="keywordflow">switch</span> (sigTag) {
00889     <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a11a403">RPMSIGTAG_GPG</a>:
00890       { <span class="keyword">const</span> <span class="keywordtype">char</span> *name = <a class="code" href="macro_8c.html#a50">rpmExpand</a>(<span class="stringliteral">"%{?_gpg_name}"</span>, NULL);
00891         aok = (name &amp;&amp; *name != <span class="charliteral">'\0'</span>);
00892         name = <a class="code" href="poptint_8h.html#a14">_free</a>(name);
00893       }
00894         <span class="keywordflow">if</span> (!aok) {
00895             <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a86">RPMERR_SIGGEN</a>,
00896                 <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"You must set \"%%_gpg_name\" in your macro file\n"</span>));
00897             <span class="keywordflow">return</span> NULL;
00898         }
00899         <span class="keywordflow">break</span>;
00900     <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a11a404">RPMSIGTAG_PGP5</a>:        <span class="comment">/* XXX legacy */</span>
00901     <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a11a400">RPMSIGTAG_PGP</a>:
00902       { <span class="keyword">const</span> <span class="keywordtype">char</span> *name = <a class="code" href="macro_8c.html#a50">rpmExpand</a>(<span class="stringliteral">"%{?_pgp_name}"</span>, NULL);
00903         aok = (name &amp;&amp; *name != <span class="charliteral">'\0'</span>);
00904         name = <a class="code" href="poptint_8h.html#a14">_free</a>(name);
00905       }
00906         <span class="keywordflow">if</span> (!aok) {
00907             <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a86">RPMERR_SIGGEN</a>,
00908                 <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"You must set \"%%_pgp_name\" in your macro file\n"</span>));
00909             <span class="keywordflow">return</span> NULL;
00910         }
00911         <span class="keywordflow">break</span>;
00912     <span class="keywordflow">default</span>:
00913         <span class="comment">/* Currently the calling function (rpm.c:main) is checking this and</span>
00914 <span class="comment">         * doing a better job.  This section should never be accessed.</span>
00915 <span class="comment">         */</span>
00916         <a class="code" href="rpmerr_8h.html#a5">rpmError</a>(<a class="code" href="rpmerr_8h.html#a91a86">RPMERR_SIGGEN</a>, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"Invalid %%_signature spec in macro file\n"</span>));
00917         <span class="keywordflow">return</span> NULL;
00918         <span class="comment">/*@notreached@*/</span> <span class="keywordflow">break</span>;
00919     }
00920 
00921     pass = <span class="comment">/*@-unrecog@*/</span> getpass( (prompt ? prompt : <span class="stringliteral">""</span>) ) <span class="comment">/*@=unrecog@*/</span> ;
00922 
00923     <span class="keywordflow">if</span> (<a class="code" href="signature_8c.html#a17">checkPassPhrase</a>(pass, sigTag))
00924         <span class="keywordflow">return</span> NULL;
00925 
00926     <span class="keywordflow">return</span> pass;
00927 }
00928 
00929 <a class="code" href="rpmlib_8h.html#a88">rpmVerifySignatureReturn</a>
<a name="l00930"></a><a class="code" href="group__signature.html#a19">00930</a> <a class="code" href="group__signature.html#a19">rpmVerifySignature</a>(<span class="keyword">const</span> <span class="keywordtype">char</span> * file, <a class="code" href="header_8h.html#a9">int_32</a> sigTag, <span class="keyword">const</span> <span class="keywordtype">void</span> * sig,
00931                 <span class="keywordtype">int</span> count, <span class="keywordtype">char</span> * result)
00932 {
00933      <a class="code" href="rpmlib_8h.html#a88">rpmVerifySignatureReturn</a> res;
00934 
00935     <span class="keywordflow">switch</span> (sigTag) {
00936     <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a11a398">RPMSIGTAG_SIZE</a>:
00937         res = <a class="code" href="signature_8c.html#a13">verifySizeSignature</a>(file, *(<a class="code" href="header_8h.html#a9">int_32</a> *)sig, result);
00938         <span class="keywordflow">break</span>;
00939     <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a11a402">RPMSIGTAG_MD5</a>:
00940         res = <a class="code" href="signature_8c.html#a14">verifyMD5Signature</a>(file, sig, result, mdbinfile);
00941         <span class="keywordflow">break</span>;
00942     <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a11a404">RPMSIGTAG_PGP5</a>:        <span class="comment">/* XXX legacy */</span>
00943     <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a11a400">RPMSIGTAG_PGP</a>:
00944         res = <a class="code" href="signature_8c.html#a15">verifyPGPSignature</a>(file, sig, count, result);
00945         <span class="keywordflow">break</span>;
00946     <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a11a403">RPMSIGTAG_GPG</a>:
00947         res = <a class="code" href="signature_8c.html#a16">verifyGPGSignature</a>(file, sig, count, result);
00948         <span class="keywordflow">break</span>;
00949     <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a11a399">RPMSIGTAG_LEMD5_1</a>:
00950     <span class="keywordflow">case</span> <a class="code" href="group__signature.html#a11a401">RPMSIGTAG_LEMD5_2</a>:
00951         sprintf(result, <a class="code" href="system_8h.html#a18">_</a>(<span class="stringliteral">"Broken MD5 digest: UNSUPPORTED\n"</span>));
00952         res = <a class="code" href="rpmlib_8h.html#a510a412">RPMSIG_UNKNOWN</a>;
00953         <span class="keywordflow">break</span>;
00954     <span class="keywordflow">default</span>:
00955         sprintf(result, <span class="stringliteral">"Do not know how to verify sig type %d\n"</span>, sigTag);
00956         res = <a class="code" href="rpmlib_8h.html#a510a412">RPMSIG_UNKNOWN</a>;
00957         <span class="keywordflow">break</span>;
00958     }
00959     <span class="keywordflow">return</span> res;
00960 }
</pre></div><hr><address style="align: right;"><small>Generated on Thu Sep 12 22:14:59 2002 for rpm by
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border=0 
width=110 height=53></a>1.2.17 </small></address>
</body>
</html>