/* * * Copyright (C) 1999 Frans Kaashoek (kaashoek@lcs.mit.edu) * Copyright (C) 1999 David Mazieres (dm@lcs.mit.edu) * * 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, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * */ #include "sfskey.h" void sfskey_norevokelist (int argc, char **argv) { bool opt_q = false; int ch; while ((ch = getopt (argc, argv, "q")) != -1) switch (ch) { case 'q': opt_q = true; break; default: usage (); break; } if (optind < argc) usage (); sfsagent_norevoke_list res; if (clnt_stat err = cagent ()->scall (AGENTCTL_GETNOREVOKE, NULL, &res)) fatal << "agent: " << err << "\n"; strbuf list; if (!opt_q) list.fmt ("%s\n", "HOSTID"); for (sfs_hash *p = res.base (); p < res.lim (); p++) { list << armor32 (p, sizeof (*p)) << "\n"; } make_sync (1); list.tosuio ()->output (1); exit (0); } void sfskey_norevokeset (int argc, char **argv) { vec revvec; sfsagent_norevoke_list arg; for (int i = optind; i < argc; i++) { sfs_hash h; if (!sfs_ascii2hostid (&h, argv[i])) { warnx << "sfskey_norevokeset: invalid hostid\n"; exit(-1); } revvec.push_back (h); } arg.set (revvec.base (), revvec.size (), freemode::NOFREE); if (clnt_stat err = cagent ()->scall (AGENTCTL_SETNOREVOKE, &arg, NULL)) fatal << "agent: " << err << "\n"; exit(0); } void sfskey_revokeclear (int argc, char **argv) { nularg (argc, argv); if (clnt_stat err = cagent ()->scall (AGENTCTL_CLRREVOKEPROGS, NULL, NULL)) fatal << "agent: " << err << "\n"; exit (0); } void sfskey_revokegen (int argc, char **argv) { str hostname; str keyname; sfskey k; str newkeyname; str newhostname; sfskey newk; int ch; while ((ch = getopt (argc, argv, "n:o:r:")) != -1) switch (ch) { case 'o': hostname = optarg; break; case 'r': newkeyname = optarg; break; case 'n': if (!newkeyname) usage (); newhostname = optarg; default: usage (); break; } if (argc != optind + 1) usage (); keyname = argv[optind]; if (!hostname && !(hostname = myname ())) fatal ("could not find my own hostname\n"); if (str err = keyfetch (&k, keyname)) fatal << err << "\n"; if (!strchr (hostname, '.')) { str dom = mydomain (); hostname = hostname << "." << dom; } if (newkeyname) { if (str err = keyfetch (&newk, newkeyname)) fatal << err << "\n"; if (!newhostname && !(newhostname = myname ())) fatal ("could not find my own hostname\n"); if (!strchr (newhostname, '.')) { str dom = mydomain (); newhostname = newhostname << "." << dom; } } sfs_pathrevoke cert; cert.msg.type = SFS_PATHREVOKE; cert.msg.path.type = SFS_HOSTINFO; cert.msg.path.hostname = hostname; cert.msg.path.pubkey = k.key->n; if (newkeyname) { cert.msg.redirect.alloc (); cert.msg.redirect->serial = 0; cert.msg.redirect->expire = 0; cert.msg.redirect->hostinfo.type = SFS_HOSTINFO; cert.msg.redirect->hostinfo.hostname = newhostname; cert.msg.redirect->hostinfo.pubkey = newk.key->n; } str rawmsg (xdr2str (cert.msg)); if (!rawmsg) fatal << "revoke: could not marshal cert.msg\n"; cert.sig = k.key->sign (rawmsg); str rawcert (xdr2str (cert)); if (!rawcert) fatal << "revoke: could not marshal cert\n"; sfs_hash hostid; if (!sfs_mkhostid(&hostid, cert.msg.path)) fatal << "Couldn't make hostid\n"; str p = armor32 (&hostid, sizeof (hostid)); if (!str2file (p, rawcert, 0444, true)) fatal << "Couldn't create " << p << "\n"; exit(0); } void sfskey_revokelist (int argc, char **argv) { bool opt_q = false; int ch; while ((ch = getopt (argc, argv, "q")) != -1) switch (ch) { case 'q': opt_q = true; break; default: usage (); break; } if (optind < argc) usage (); sfsagent_revokeprogs res; if (clnt_stat err = cagent ()->scall (AGENTCTL_DUMPREVOKEPROGS, NULL, &res)) fatal << "agent: " << err << "\n"; strbuf list; if (!opt_q) list.fmt ("%-8s %-8s %-8s %s\n", "BLOCK", "FILTER", "EXCLUDE", "PROGRAM"); for (sfsagent_revokeprog *p = res.base (); p < res.lim (); p++) { if (p->block) list.fmt ("%-8s %-8s %-8s", "***", p->block->filter.cstr (), p->block->exclude.cstr ()); else list.fmt ("%-8s %-8s %-8s", "", "", ""); for (sfsagent_progarg *a = p->av.base (); a < p->av.lim (); a++) list << " " << *a; list << "\n"; } make_sync (1); list.tosuio ()->output (1); exit (0); } void sfskey_revokeprog (int argc, char **argv) { sfsagent_revokeprog arg; bool block = false; str filter; str exclude; int ch; while ((ch = getopt (argc, argv, "bf:e:")) != -1) switch (ch) { case 'b': if (block) usage (); block = true; case 'e': if (!block || exclude) usage (); exclude = optarg; break; case 'f': if (!block || filter) usage(); filter = optarg; break; default: usage (); break; } if (optind >= argc) usage (); if (block) { if (!filter) filter = ""; if (!exclude) exclude = ""; arg.block.alloc (); arg.block->filter = filter; arg.block->exclude = exclude; } arg.av.setsize (argc - optind); for (int i = optind; i < argc; i++) arg.av[i - optind] = argv[i]; bool res; if (clnt_stat err = cagent ()->scall (AGENTCTL_ADDREVOKEPROG, &arg, &res)) fatal << "agent: " << err << "\n"; if (!res) fatal << "agent refused revoke program\n"; exit (0); } void sfskey_revoke (int argc, char **argv) { if (getopt (argc, argv, "") != -1 || optind != argc - 1) usage (); str file (argv[optind]); int fd; if (file == "-") { fd = 0; make_sync (fd); } else if ((fd = open (file, O_RDONLY)) < 0) fatal ("%s: %m\n", file.cstr ()); if (isatty (fd)) fatal ("cannot read revocation certificate from a tty.\n"); char buf[8192]; int n = read (fd, buf, 8192); if (n < 0) fatal ("read: %m\n"); xdrmem x (buf, n); sfs_pathrevoke cert; if (!buf2xdr (cert, buf, n) || !sfs_checkrevoke (cert)) fatal ("invalid revocation certificate\n"); if (clnt_stat err = ccd ()->scall (AGENT_REVOKE, &cert, NULL)) fatal << "sfscd: " << err << "\n"; exit (0); }