

#include "sfsextauth.h"
#include "sfskeymisc.h"

bool opt_confirm = false;

class sfsdea : public sfsextauth 
{
public:
  sfsdea () : dur (0) {}
  sfsdea (int d) {
    if (d) { d += time (NULL); }
    dur = d;
  }
    
  ~sfsdea () {}
  bool confirmed (sfsextauth_init *aa);
  bool loadkey (str keyloc);
  void authinit (svccb *sbp);
  void authinitcb (svccb *sbp, ref<sfsagent_auth_res> res);
  void set_name (str &n);
  sfs_time get_expire_time () { return dur; }
private:
  int dur;
  key kmeth;
};

void
sfsdea::set_name (str &n)
{
  n = "sfs dummy external agent";
}

bool
sfsdea::confirmed (sfsextauth_init *aa)
{
  warn << "SFSDEA: " << aa->name << "!" << aa->autharg.requestor << ": @" 
       << aa->autharg.authinfo.name  << ","
       << armor32 (str (aa->autharg.authinfo.hostid.base (),
			aa->autharg.authinfo.hostid.size ()))
       << " (" << implicit_cast<int> (aa->autharg.authinfo.service) << ")\n";

  str s = getline ("*****Do you wish to agree to this signature? ", "no");

  if (s[0] == 'y' || s[0] == 'Y')
    return true;
  else
    return false;
}

void
sfsdea::authinit (svccb *sbp)
{
  ref<sfsagent_auth_res> res = New refcounted<sfsagent_auth_res> ();
  sfsextauth_init *aa = sbp->getarg<sfsextauth_init> ();

  if (opt_confirm && !confirmed (aa))
    sbp->replyref (sfsagent_auth_res (false));
  else
    kmeth.authinit (&(aa->autharg), res, 
	wrap (this, &sfsdea::authinitcb, sbp, res));
}

void
sfsdea::authinitcb (svccb *sbp, ref<sfsagent_auth_res> res)
{
  sbp->reply(res);
}

bool
sfsdea::loadkey (str keyloc)
{
  sfskey k;
  if (!keyloc || keyloc == "") {
    keyloc = defkey();
  }
  if (str err = sfskeyfetch (&k, keyloc, NULL)) {
    warn << err << "\n";
    return false;
  }
  kmeth.privkey = k.key;
  kmeth.name = keyloc;
  return true;
}


void 
usage(char *progname) 
{
  warn << "usage: " <<	progname << " [ -k <keyloc> ] [ -e <seconds> ] -c\n";
  exit (1);
}

int
main (int argc, char **argv)
{
  setprogname (argv[0]);
  sfsconst_init ();
  agent_setsock ();
  str keyloc;
  int expires = 0;

  int ch;
  while ((ch = getopt (argc, argv, "k:e:c")) != -1) {
    switch (ch) {
    case 'k':
      keyloc = optarg;
      break;
    case 'e':
      if (optarg) 
	expires = atoi(optarg);
      break;
    case 'c':
      opt_confirm = true;
      break;
    default:
      usage (argv[0]);
    }
  }
      
  sfsdea   dea (expires);

  if (!dea.loadkey (keyloc) || !dea.connect ()) {
    exit (1);
  }

  dea.register_with_agent ();
  amain ();
}


