/* $Id: sfskeyfetch.C,v 1.29 2000/03/21 19:43:11 dm Exp $ */ /* * * Copyright (C) 1999 David Mazieres (dm@uun.org) * Copyright (C) 1999 Michael Kaminsky (kaminsky@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" #include "srp.h" bool isremote (str keyname) { return !strchr (keyname, '/') && strchr (keyname, '@'); } static void keyfetch_srp_cb (ptr *scp, str *errp, ptr sc, str err) { if (sc) { *scp = sc; *errp = ""; } else *errp = err; } static str keyfetch_srp (sfskey *sk, str keyname, ptr *scp) { static bool srpprimed; if (!srpprimed) { srpprimed = true; bigint N, g; if (str srpfile = sfsconst_etcfile ("sfs_srp_parms")) if (str parms = file2str (srpfile)) if (import_srp_params (parms, &N, &g) && !srp_base::seedparam (N, g)) warn << "DANGER: " << srpfile << " contains bogus parameters!\n"; } ptr sc; srp_client srp; str serr; str pwd; sfs_connect_srp (sk->keyname, &srp, wrap (keyfetch_srp_cb, &sc, &serr), &sk->keyname, &pwd); while (!serr) acheck (); if (serr.len ()) return serr; ref c (aclnt::alloc (sc->x, sfsauth_program_1)); sfsauth_fetchres fetchres; if (clnt_stat err = c->scall (SFSAUTHPROC_FETCH, NULL, &fetchres)) return sk->keyname << ": fetch: " << err; if (fetchres.status != SFSAUTH_OK) return sk->keyname << ": server refused key fetch request"; sk->key = import_rabin_decrypt_sec (fetchres.resok->privkey, &srp.eksb); if (!sk->key) return sk->keyname << ": server returned undecryptable private key"; sk->cost = srp.cost; sk->pwd = pwd; sk->srpparms = New sfssrp_parms; sk->srpparms->N = srp.N; sk->srpparms->g = srp.g; if (!sc->hostid_valid) { warn << "Warning: host for " << sk->keyname << " is actually server\n" << " " << sc->path << "\n"; sc = NULL; } else if (fetchres.resok->hostid != sc->hostid) { warnx << sc->path << " returned incorrect hostid in fetch\n"; sc = NULL; } if (scp) *scp = sc; return NULL; } str keyfetch (sfskey *sk, str keyname, ptr *scp) { sk->key = NULL; sk->keyname = keyname; sk->pwd = NULL; sk->cost = 0; if (scp) *scp = NULL; if (isremote (keyname)) return keyfetch_srp (sk, keyname, scp); str ske = file2wstr (keyname); if (!ske) return keyname << ": " << strerror (errno); if (import_rabin_priv_need_pwd (ske, &sk->cost)) sk->pwd = getpwd ("Passphrase for " << sk->keyname << ": "); sk->key = import_rabin_priv (ske, sk->pwd, &sk->keyname); if (!sk->key) { sk->key = NULL; return "Bad passphrase."; } if (!sk->keyname || !sk->keyname.len ()) sk->keyname = keyname; return NULL; }