cvs-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Cvs-cvs] ccvs/src ChangeLog client.c main.c sanity.sh su... [signed-com


From: Derek Robert Price
Subject: [Cvs-cvs] ccvs/src ChangeLog client.c main.c sanity.sh su... [signed-commits3]
Date: Sun, 01 Jan 2006 23:12:38 +0000

CVSROOT:        /cvsroot/cvs
Module name:    ccvs
Branch:         signed-commits3
Changes by:     Derek Robert Price <address@hidden>     06/01/01 23:12:37

Modified files:
        src            : ChangeLog client.c main.c sanity.sh subr.c 
                         subr.h verify.c verify.h 

Log message:
        * client.c (sig_cache): New static global.
        (update_entries): Save signatures to CVS/Base after a commit.
        (send_signature): Cache signatures after sending them to the server.
        Accept full file name as an argument.  Update all callers.
        * sanity.sh: Set GPG trust for test key.
        (verify): New test.
        * subr.c (write_file), subr.h: New function.
        * verify.c (iverify_signature): New function factored from...
        (verify_signature): ...here.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/ChangeLog.diff?only_with_tag=signed-commits3&tr1=1.3328.2.12&tr2=1.3328.2.13&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/client.c.diff?only_with_tag=signed-commits3&tr1=1.438.2.2&tr2=1.438.2.3&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/main.c.diff?only_with_tag=signed-commits3&tr1=1.262.6.2&tr2=1.262.6.3&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/sanity.sh.diff?only_with_tag=signed-commits3&tr1=1.1105.2.2&tr2=1.1105.2.3&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/subr.c.diff?only_with_tag=signed-commits3&tr1=1.148.6.1&tr2=1.148.6.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/subr.h.diff?only_with_tag=signed-commits3&tr1=1.7.6.1&tr2=1.7.6.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/verify.c.diff?only_with_tag=signed-commits3&tr1=1.1.2.1&tr2=1.1.2.2&r1=text&r2=text
http://cvs.savannah.gnu.org/viewcvs/cvs/ccvs/src/verify.h.diff?only_with_tag=signed-commits3&tr1=1.1.2.1&tr2=1.1.2.2&r1=text&r2=text

Patches:
Index: ccvs/src/ChangeLog
diff -u ccvs/src/ChangeLog:1.3328.2.12 ccvs/src/ChangeLog:1.3328.2.13
--- ccvs/src/ChangeLog:1.3328.2.12      Sun Jan  1 23:06:21 2006
+++ ccvs/src/ChangeLog  Sun Jan  1 23:12:36 2006
@@ -1,5 +1,15 @@
 2006-01-01  Derek Price  <address@hidden>
 
+       * client.c (sig_cache): New static global.
+       (update_entries): Save signatures to CVS/Base after a commit.
+       (send_signature): Cache signatures after sending them to the server.
+       Accept full file name as an argument.  Update all callers.
+       * sanity.sh: Set GPG trust for test key.
+       (verify): New test.
+       * subr.c (write_file), subr.h: New function.
+       * verify.c (iverify_signature): New function factored from...
+       (verify_signature): ...here.
+
        * sign.c (read_signature): Remove bin argument.  Update caller.
 
        * base.c (translate_exists): Suppress GCC warning.
Index: ccvs/src/client.c
diff -u ccvs/src/client.c:1.438.2.2 ccvs/src/client.c:1.438.2.3
--- ccvs/src/client.c:1.438.2.2 Fri Dec 30 23:48:58 2005
+++ ccvs/src/client.c   Sun Jan  1 23:12:37 2006
@@ -1493,6 +1493,13 @@
 
 
 
+/* Cache for OpenPGP signatures so they may be written to a file only on a
+ * successful commit.
+ */
+static List *sig_cache;
+
+
+
 /* Update the Entries line for this file.  */
 static void
 update_entries (void *data_arg, List *ent_list, const char *short_pathname,
@@ -1901,6 +1908,25 @@
            char *basefile = make_base_file_name (filename, vn);
            mkdir_if_needed (CVSADM_BASE);
            copy_file (filename, basefile);
+
+           if (get_sign_commits (false, supported_request ("Signature")))
+           {
+               if ((n = findnode_fn (sig_cache, short_pathname)))
+               {
+                   char *sigfile = Xasprintf ("%s%s", basefile, ".sig");
+                   write_file (sigfile, n->data, n->len);
+                   delnode (n);
+                   free (sigfile);
+               }
+               else
+               {
+                   error (0, 0,
+"Internal error: OpenPGP signature for `%s' not found in cache.",
+                          short_pathname);
+                   printlist (sig_cache);
+               }
+           }
+
            free (basefile);
        }
     }
@@ -5075,17 +5101,32 @@
 
 
 
+/* Generate and send an OpenPGP signature to the server.
+ */
 static void
-send_signature (const char *srepos, const char *filename, bool bin)
+send_signature (const char *srepos, const char *filename, const char *fullname,
+               bool bin)
 {
     char *sigbuf;
     size_t len;
+    Node *n;
 
     sigbuf = gen_signature (srepos, filename, bin, &len);
 
     send_to_server ("Signature\012", 0);
     send_to_server (sigbuf, len);
-    free (sigbuf);
+
+    /* Cache the signature for use with the base file which will be
+     * automatically generated later since the server will not send a new base
+     * file and signature unless keywords cause the file to change after it is
+     * committed.
+     */
+    if (!sig_cache) sig_cache = getlist ();
+    n = getnode ();
+    n->key = xstrdup (fullname);
+    n->data = sigbuf;
+    n->len = len;
+    addnode (sig_cache, n);
 }
 
 
@@ -5222,7 +5263,7 @@
                    error (1, 0, "Server doesn't support commit signatures.");
 
                send_signature (Short_Repository (finfo->repository),
-                               finfo->file,
+                               finfo->file, finfo->fullname,
                                vers && !strcmp (vers->options, "-kb"));
            }
            send_modified (filename, finfo->fullname, vers);
@@ -5756,7 +5797,7 @@
        if (!supported_request ("Signature"))
            error (1, 0, "Server doesn't support commit signatures.");
 
-       send_signature (Short_Repository (repository), vfile,
+       send_signature (Short_Repository (repository), vfile, fullname,
                        vers.options && !strcmp (vers.options, "-kb"));
     }
 
Index: ccvs/src/main.c
diff -u ccvs/src/main.c:1.262.6.2 ccvs/src/main.c:1.262.6.3
--- ccvs/src/main.c:1.262.6.2   Sat Dec 31 19:51:11 2005
+++ ccvs/src/main.c     Sun Jan  1 23:12:37 2006
@@ -186,6 +186,7 @@
     { "tag",      "ta",       "freeze",    cvstag,    
CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR },
     { "unedit",   NULL,       NULL,        unedit,    
CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR },
     { "update",   "up",       "upd",       update,    CVS_CMD_USES_WORK_DIR },
+    { "verify",   "ver",      NULL,        verify,    0 },
     { "version",  "ve",       "ver",       version,   0 },
     { "watch",    NULL,       NULL,        watch,     
CVS_CMD_MODIFIES_REPOSITORY | CVS_CMD_USES_WORK_DIR },
     { "watchers", NULL,       NULL,        watchers,  CVS_CMD_USES_WORK_DIR },
Index: ccvs/src/sanity.sh
diff -u ccvs/src/sanity.sh:1.1105.2.2 ccvs/src/sanity.sh:1.1105.2.3
--- ccvs/src/sanity.sh:1.1105.2.2       Fri Dec 30 23:26:32 2005
+++ ccvs/src/sanity.sh  Sun Jan  1 23:12:37 2006
@@ -1775,6 +1775,9 @@
 =k49u
 -----END PGP PRIVATE KEY BLOCK-----
 EOF
+  $GPG --import-ownertrust <<EOF >>$LOGFILE 2>&1
+F1D6D5842814BC3A264BE7068E0C2C7EF133BDE9:6:
+EOF
 
   # Some tests check the content of the RCS file and whether there is a
   # signature phrase or not depends on whether they were being generated.
@@ -1869,6 +1872,7 @@
        tests="${tests} dottedroot fork commit-d template"
        tests="${tests} writeproxy writeproxy-noredirect writeproxy-ssh"
        tests="${tests} writeproxy-ssh-noredirect"
+       tests="$tests verify"
 else
        tests="$*"
 fi
@@ -32696,6 +32700,30 @@
 
 
 
+       verify)
+         # More tests of basic/miscellaneous functionality.
+         mkdir verify; cd verify
+         mkdir top; cd top
+         dotest verify-init-1 "$testcvs -q co -l ."
+         mkdir verify
+         dotest verify-init-2 "$testcvs -Q add verify"
+         cd ..
+         dotest verify-init-3 "$testcvs -q co verify"
+         cd verify
+         echo some content >file1
+         dotest verify-init-4 "$testcvs -Q add file1"
+         dotest verify-init-5 "$testcvs -Q ci -m newfile file1"
+         dotest verify-1 "$testcvs verify file1" \
+"$DOTSTAR Good signature from \"CVS Test Script $DOTSTAR"
+
+         dokeep
+         cd ../..
+         rm -rf verify
+         modify_repo rm -rf $CVSROOT_DIRNAME/verify
+         ;;
+
+
+
        trace)
          # Check that there are no core dumps lurking in the trace
          # options. 
Index: ccvs/src/subr.c
diff -u ccvs/src/subr.c:1.148.6.1 ccvs/src/subr.c:1.148.6.2
--- ccvs/src/subr.c:1.148.6.1   Wed Dec 21 13:25:10 2005
+++ ccvs/src/subr.c     Sun Jan  1 23:12:37 2006
@@ -731,6 +731,31 @@
 
 
 
+void
+write_file (const char *file, const char *data, size_t len)
+{
+    FILE *fp;
+
+    TRACE (TRACE_FUNCTION,
+          "write_file (%s, %s, %u)", file, data, (unsigned int)len);
+
+    if (noexec) return;
+
+    if (!(fp = fopen (file, "w")))
+       error (1, errno, "cannot create `%s'", file);
+
+    if (len > 0)
+    {
+       if (fwrite (data, sizeof *data, len, fp) != len)
+           error (1, errno, "cannot write file `%s'", file);
+    }
+
+    if (fclose (fp) < 0)
+       error (1, errno, "cannot close `%s'", file);
+}
+
+
+
 /* Follow a chain of symbolic links to its destination.  FILENAME
    should be a handle to a malloc'd block of memory which contains the
    beginning of the chain.  This routine will replace the contents of
Index: ccvs/src/subr.h
diff -u ccvs/src/subr.h:1.7.6.1 ccvs/src/subr.h:1.7.6.2
--- ccvs/src/subr.h:1.7.6.1     Wed Dec 21 13:25:10 2005
+++ ccvs/src/subr.h     Sun Jan  1 23:12:37 2006
@@ -52,6 +52,7 @@
 bool file_contains_keyword (const struct file_info *finfo);
 void get_file (const char *, const char *, const char *,
                char **, size_t *, size_t *);
+void write_file (const char *file, const char *data, size_t len);
 void resolve_symlink (char **filename);
 char *backup_file (const char *file, const char *suffix);
 char *shell_escape (char *buf, const char *str);
Index: ccvs/src/verify.c
diff -u ccvs/src/verify.c:1.1.2.1 ccvs/src/verify.c:1.1.2.2
--- ccvs/src/verify.c:1.1.2.1   Sat Dec 31 19:51:11 2005
+++ ccvs/src/verify.c   Sun Jan  1 23:12:37 2006
@@ -32,6 +32,7 @@
 #include "xalloc.h"
 
 /* CVS headers.  */
+#include "base.h"
 #include "stack.h"
 
 /* Get current_parsed_root.  */
@@ -235,9 +236,204 @@
 
 
 
-/* Generate a signature and return it in allocated memory.  */
-char *
-verify_signature (const char *srepos, const char *filename, bool bin,\
-                 size_t *len)
+/* Verify a signature, returning true or false.
+ *
+ * ERRORS
+ *   Exits with a fatal error when FATAL and a signature cannot be verified.
+ */
+static bool
+iverify_signature (const char *srepos, const char *filename, bool bin,
+                 bool fatal)
+{
+    char *cmdline;
+    char *sigfile = Xasprintf ("%s%s", filename, ".sig");
+    FILE *pipefp;
+    bool save_noexec = noexec;
+    size_t len;
+    char buf[256];
+    int pipestatus;
+    bool retval;
+
+    if (!isfile (sigfile))
+    {
+       error (fatal, 0, "No signature file found (`%s')", sigfile);
+       free (sigfile);
+       return false;
+    }
+
+    /*
+     * %p = shortrepos
+     * %r = repository
+     * %{a} = user defined sign args
+     * %t = textmode flag
+     * %s = signature file name
+     * %d = signed (data) file name
+     */
+    /*
+     * Cast any NULL arguments as appropriate pointers as this is an
+     * stdarg function and we need to be certain the caller gets what
+     * is expected.
+     */
+    cmdline = format_cmdline (
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+                             false, srepos,
+#endif /* SUPPORT_OLD_INFO_FMT_STRINGS */
+                             get_verify_template (),
+                             "a", ",", get_verify_args (),
+                             verify_args_list_to_args_proc, (void *) NULL,
+                             "r", "s", current_parsed_root->directory,
+                             "p", "s", srepos,
+                             "t", "s", bin ? NULL : get_sign_textmode (),
+                             "s", "s", sigfile,
+                             "d", "s", filename,
+                             (char *) NULL);
+
+    if (!cmdline || !strlen (cmdline))
+    {
+       error (fatal, 0, "verify template resolved to the empty string!");
+       if (cmdline) free (cmdline);
+       free (sigfile);
+       return false;
+    }
+
+    noexec = false;
+    if (!(pipefp = run_popen (cmdline, "r")))
+    {
+       error (fatal, errno, "failed to execute signature verifier");
+       retval = false;
+       goto done;
+    }
+    noexec = save_noexec;
+
+    do
+    {
+       len = fread (buf, sizeof *buf, sizeof buf, pipefp);
+       if (!really_quiet && len)
+           cvs_output (buf, len);
+       /* Fewer bytes than requested means EOF or error.  */
+    } while (len == sizeof buf);
+
+    if (ferror (pipefp))
+       error (0, ferror (pipefp), "Error reading from verify program.");
+
+    pipestatus = pclose (pipefp);
+    if (pipestatus == -1)
+    {
+       error (fatal, errno,
+              "failed to obtain exit status from verify program");
+       retval = false;
+    }
+    else if (pipestatus)
+    {
+       if (WIFEXITED (pipestatus))
+           error (fatal, 0, "verify program exited with error code %d",
+                  WEXITSTATUS (pipestatus));
+       else
+           error (fatal, 0, "verify program exited via signal %d",
+                  WTERMSIG (pipestatus));
+       retval = false;
+    }
+    else
+       retval = true;
+
+done:
+    free (sigfile);
+    free (cmdline);
+
+    return retval;
+}
+
+
+
+/* Verify a signature, returning true or false.
+ *
+ * ERRORS
+ *   Exits with a fatal error when the verify mode is VERIFY_FATAL and a
+ *   signature cannot be verified.
+ */
+bool
+verify_signature (const char *srepos, const char *filename, bool bin,
+                 bool server_active, bool server_support)
+{
+    bool fatal = iget_verify_checkouts (server_active, server_support)
+                == VERIFY_FATAL;
+    return iverify_signature (srepos, filename, bin, fatal);
+}
+
+
+
+static const char *const verify_usage[] =
+{
+    "Usage: %s %s [-lR]\n",
+    "\t-l\tLocal directory only, no recursion.\n",
+    "\t-R\tProcess directories recursively.\n",
+    "(Specify the --help global option for a list of other help options)\n",
+    NULL
+};
+
+
+
+static int
+verify_fileproc (void *callerdat, struct file_info *finfo)
+{
+    const char *srepos = Short_Repository (finfo->repository);
+    Node *n;
+    bool bin;
+    Entnode *e;
+    bool retval;
+    char *basefn;
+
+    n = findnode (finfo->entries, finfo->file);
+    assert (n);
+
+    e = n->data;
+    bin = !strcmp (e->options, "-kb");
+
+    basefn = make_base_file_name (finfo->file, e->version);
+
+    retval = !iverify_signature (srepos, basefn, bin, false);
+
+    free (basefn);
+    return retval;
+}
+
+
+
+int
+verify (int argc, char **argv)
 {
+    bool local = false;
+    char c;
+    int err;
+
+    if (argc == -1)
+       usage (verify_usage);
+
+    /* parse the args */
+    optind = 0;
+    while ((c = getopt (argc, argv, "+lR")) != -1)
+    {
+       switch (c)
+       {
+           case 'l':
+               local = true;
+               break;
+           case 'R':
+               local = false;
+               break;
+           case '?':
+           default:
+               usage (verify_usage);
+               break;
+       }
+    }
+    argc -= optind;
+    argv += optind;
+
+    /* call the recursion processor */
+    err = start_recursion (verify_fileproc, NULL, NULL, NULL, NULL,
+                          argc, argv, local, W_LOCAL, false, CVS_LOCK_NONE,
+                          NULL, 1, NULL);
+
+    return err;
 }
Index: ccvs/src/verify.h
diff -u ccvs/src/verify.h:1.1.2.1 ccvs/src/verify.h:1.1.2.2
--- ccvs/src/verify.h:1.1.2.1   Sat Dec 31 19:51:11 2005
+++ ccvs/src/verify.h   Sun Jan  1 23:12:37 2006
@@ -45,6 +45,9 @@
 
 /* Get values.  */
 bool get_verify_checkouts (bool server_active, bool server_support);
-char *verify_signature (const char *srepos, const char *filename, bool bin,
-                       size_t *len);
+bool verify_signature (const char *srepos, const char *filename, bool bin,
+                      bool server_active, bool server_support);
+
+/* User command.  */
+int verify (int argc, char **argv);
 #endif /* VERIFY_H */




reply via email to

[Prev in Thread] Current Thread [Next in Thread]