* Remove use of deprecated functions from the string module
[mirror/userdir-ldap.git] / userdir_gpg.py
index 3abc05c..9b497b2 100644 (file)
@@ -1,5 +1,19 @@
- #!/usr/bin/env python
-# -*- mode: python -*-
+#   Copyright (c) 1999-2001  Jason Gunthorpe <jgg@debian.org>
+#   Copyright (c) 2005       Joey Schulze <joey@infodrom.org>
+#
+#   This program is free software; you can redistribute it and/or modify
+#   it under the terms of the GNU General Public License as published by
+#   the Free Software Foundation; either version 2 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful,
+#   but WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#   GNU General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program; if not, write to the Free Software
+#   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
 # GPG issues - 
 #  - gpgm with a status FD being fed keymaterial and other interesting
 #    packets so I can tell if a signature is made by pgp2 to enable the
 #    pgp2 encrypting mode.
 
-import string, mimetools, multifile, sys, StringIO, os, tempfile, re;
-import rfc822, time, fcntl, FCNTL, anydbm
+import mimetools, multifile, sys, StringIO, os, tempfile, re;
+import rfc822, time, fcntl, anydbm
 
 # General GPG options
 GPGPath = "gpg"
 # "--load-extension","rsa",
-GPGBasicOptions = ["--no-options","--batch",
-          "--no-default-keyring","--always-trust"];
+GPGBasicOptions = [
+   "--no-options",
+   "--batch",
+   "--no-default-keyring",
+   "--secret-keyring", "/dev/null",
+   "--always-trust"];
 GPGKeyRings = [];
 GPGSigOptions = ["--output","-"];
 GPGSearchOptions = ["--dry-run","--with-colons","--fingerprint"];
@@ -75,7 +93,7 @@ def GetClearSig(Msg,Paranoid = 0):
         while 1:
             x = mf.readline();
             if not x: break;
-            if len(string.strip(x)) != 0:
+            if len(x.strip()) != 0:
                raise Error,"Unsigned text in message (at start)";
          mf.seek(Pos);
       
@@ -98,7 +116,7 @@ def GetClearSig(Msg,Paranoid = 0):
       InnerMsg = mimetools.Message(mf);
       if InnerMsg.gettype() != "application/pgp-signature":
          raise Error, "Invalid pgp/mime encoding [wrong signature type]";
-      Signature = string.joinfields(mf.readlines(),'');
+      Signature = ''.join(mf.readlines())
 
       # Check the last bit of the message..
       if Paranoid != 0:
@@ -107,7 +125,7 @@ def GetClearSig(Msg,Paranoid = 0):
         while 1:
             x = mf.readline();
             if not x: break; 
-            if len(string.strip(x)) != 0:
+            if len(x.strip()) != 0:
                raise Error,"Unsigned text in message (at end)";
          mf.seek(Pos);
       
@@ -116,20 +134,20 @@ def GetClearSig(Msg,Paranoid = 0):
       Output = "-----BEGIN PGP SIGNED MESSAGE-----\r\n";
       # Semi-evil hack to get the proper hash type inserted in the message
       if Msg.getparam('micalg') != None:
-          Output = Output + "Hash: %s\r\n"%(string.upper(Msg.getparam('micalg')[4:]));
+          Output = Output + "Hash: MD5,SHA1,%s\r\n"%(Msg.getparam('micalg')[4:].upper())
       Output = Output + "\r\n";
-      Output = Output +  string.replace(Signed.getvalue(),"\n---","\n- ---") + Signature;
+      Output = Output + Signed.getvalue().replace("\n-","\n- -") + Signature
       return (Output,1);
    else:
       if Paranoid == 0:
          # Just return the message body
-         return (string.joinfields(Msg.fp.readlines(),''),0);
+         return (''.join(Msg.fp.readlines()),0);
      
       Body = "";
       State = 1;
       for x in Msg.fp.readlines():
          Body = Body + x;
-         Tmp = string.strip(x);
+         Tmp = x.strip()
          if len(Tmp) == 0:
             continue;
         
@@ -324,7 +342,7 @@ def GPGCheckSig(Message):
            if Why == None:
               GoodSig = 1;
            KeyID = Split[2];
-           Owner = string.join(Split[3:],' ');
+           Owner = ' '.join(Split[3:])
            
         # Bad signature response
         if Split[1] == "BADSIG":
@@ -350,12 +368,12 @@ def GPGCheckSig(Message):
             Why = "Unable to verify signature, signing key missing.";
 
         # Expired signature
-        if Split[1] == "SIGEXPIRED":
+        if Split[1] == "SIGEXPIRED" or Split[1] == "EXPSIG":
            GoodSig = 0;
             Why = "Signature has expired";
            
         # Revoked key
-        if Split[1] == "KEYREVOKED":
+        if Split[1] == "KEYREVOKED" or Split[1] == "REVKEYSIG":
            GoodSig = 0;
             Why = "Signing key has been revoked";
 
@@ -371,7 +389,11 @@ def GPGCheckSig(Message):
 
          # ValidSig has the key finger print
         if Split[1] == "VALIDSIG":
-           KeyFinger = Split[2];
+           # Use the fingerprint of the primary key when available
+           if len(Split) >= 12:
+               KeyFinger = Split[11];
+            else:
+              KeyFinger = Split[2];
 
       # Reopen the stream as a readable stream
       Text = Res[2].read();
@@ -407,21 +429,26 @@ def GPGKeySearch(SearchCriteria):
    Owner = "";
    KeyID = "";
    Hits = {};
+
+   dir = os.path.expanduser("~/.gnupg")
+   if not os.path.isdir(dir):
+      os.mkdir(dir, 0700)
+                      
    try:
-      Strm = os.popen(string.join(Args," "),"r");
+      Strm = os.popen(" ".join(Args),"r")
       
       while(1):
          # Grab and split up line
          Line = Strm.readline();
          if Line == "":
             break;
-        Split = string.split(Line,":");
-        
-        # Store some of the key fields
+         Split = Line.split(":")
+
+         # Store some of the key fields
          if Split[0] == 'pub':
             KeyID = Split[4];
             Owner = Split[9];
-           Length = int(Split[2]);
+            Length = int(Split[2]);
 
          # Output the key
          if Split[0] == 'fpr':
@@ -444,7 +471,7 @@ def GPGPrintKeyInfo(Ident):
 # Perform a substition of template 
 def TemplateSubst(Map,Template):
    for x in Map.keys():
-      Template = string.replace(Template,x,Map[x]);
+      Template = Template.replace(x, Map[x])
    return Template;
 
 # The replay class uses a python DB (BSD db if avail) to implement
@@ -462,7 +489,7 @@ def TemplateSubst(Map,Template):
 class ReplayCache:
    def __init__(self,Database):
       self.Lock = open(Database + ".lock","w",0600);
-      fcntl.flock(self.Lock.fileno(),FCNTL.LOCK_EX);
+      fcntl.flock(self.Lock.fileno(),fcntl.LOCK_EX);
       self.DB = anydbm.open(Database,"c",0600);
       self.CleanCutOff = CleanCutOff;
       self.AgeCutOff = AgeCutOff;