/* $Id: sfskeyupdate.C,v 1.47 2002/12/04 20:48:49 max Exp $ */ /* * * Copyright (C) 1999 David Mazieres (dm@uun.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, 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" #include "srp.h" #include "sfskeymgr.h" static str srp_prepend (const str &in) { if (!strchr (in, '@')) { warnx << "Prepending '@' to '" << in << "' and using SRP\n"; return strbuf () << "@" << in; } else { return in; } } struct updatecmd { str nkeyname; str srpfile; bool realmup; u_int32_t opts; vec keys; vec servers; sfskeymgr *kmgr; sfskeyinfo *nki; sfskey *nk; u_int ncb; bool cberr; updatecmd () : realmup (false), opts (0), ncb (0), cberr (false) {} void setupargs () { size_t sz = servers.size (); if (!sz) fatal << "At least one target server must be specified\n\t" << "(use '-' for localhost)\n"; if (realmup) { if (sz != 1 || !issrpkey (servers[0])) fatal << "Exactly one SRP key must be used with -r\n"; if (keys.size () || opts & (KM_NOESK | KM_NOSRP)) fatal << "-r flag cannot be used with -akS flags\n"; nkeyname = srp_prepend (servers[0]); } else for (u_int i = 0; i < sz; i++) if (!(servers[i] == "-") && issrpkey (servers[i])) keys.push_back (srp_prepend (servers[i])); } void start () { setupargs (); opts |= KM_REALM; kmgr = New sfskeymgr (); if (servers.size () == 0) fatal << "Must specify at least one server to update\n"; str err; if (!(nki = kmgr->getkeyinfo (nkeyname, opts))) fatal << "No suitable new key found\n"; if (!(opts & KM_NOSRP) && !kmgr->getsrp (srpfile)) fatal << "Cannot find suitable SRP parameters.\n"; if (!(nk = kmgr->fetch (nki, &err, opts))) fatal << err << "\n"; kmgr->add (nk->key); kmgr->add_keys (keys); kmgr->check_connect (servers, wrap (this, &updatecmd::update)); } void update () { str err; ncb = servers.size (); for (u_int i = 0; i < ncb; i++) kmgr->update (nk, NULL, servers[i], opts, wrap (this, &updatecmd::updatecb, servers[i])); } void updatecb (str server, str err, bool gotconf) { if (err) { warn << server << ": update failed:\n" << err << "\n"; cberr = true; } if (--ncb == 0) { if (cberr) warn << "WARNING: Not all servers were successfully updated.\n"; exit (cberr); } } }; void sfskey_update (int argc, char **argv) { updatecmd *uc = New updatecmd (); u_int32_t opts = 0; int ch; while ((ch = getopt (argc, argv, "fESs:a:k:r")) != -1) switch (ch) { case 'E': opts |= KM_NOESK; break; case 'S': opts |= KM_NOSRP; break; case 's': uc->srpfile = optarg; break; case 'f': opts |= KM_FRC; break; case 'a': uc->keys.push_back (optarg); break; case 'r': uc->realmup = true; break; case 'k': if (uc->nkeyname) fatal << "-k can only be supplied once\n"; uc->nkeyname = optarg; break; default: usage (); break; } for (int i = optind; i < argc; i++) uc->servers.push_back (argv[i]); uc->opts = opts; uc->start (); }