/*
 * Copyright (c) 2003-2011
 * Distributed Systems Software.  All rights reserved.
 * See the file LICENSE for redistribution information.
 */

/*****************************************************************************
 * COPYRIGHT AND PERMISSION NOTICE
 * 
 * Copyright (c) 2001-2003 The Queen in Right of Canada
 * 
 * All rights reserved.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation 
 * the rights to use, copy, modify, merge, publish, distribute, and/or sell
 * copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, provided that the above copyright notice(s) and this
 * permission notice appear in all copies of the Software and that both the
 * above copyright notice(s) and this permission notice appear in supporting
 * documentation.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE 
 * BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES,
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 
 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 
 * SOFTWARE.
 * 
 * Except as contained in this notice, the name of a copyright holder shall not
 * be used in advertising or otherwise to promote the sale, use or other
 * dealings in this Software without prior written authorization of the
 * copyright holder.
 ***************************************************************************/

/*
 * This CGI program extracts REMOTE_USER from the environment
 * (presumably set by Apache), runs dacs_authenticate to verify that DACS
 * should generate credentials for the user, and finally sends a browser
 * redirect to DACS_ERROR_URL to maintain the requested flow of control.
 */

#ifndef lint
static const char copyright[] =
"Copyright (c) 2003-2011\n\
Distributed Systems Software.  All rights reserved.";
static const char revid[] =
  "$Id: autologin.c 2529 2011-09-23 22:19:51Z brachman $";
#endif

#include "dacs.h"

static MAYBE_UNUSED char *log_module_name = "autologin";

static const char *auth_prog = CGIBINDIR/**/"/dacs_authenticate";
static int just_dump_stdin = 0;

int
main(int argc, char **argv)
{
  int i, redirect;
  char *run_dacs_auth, *auth_query_string, *dacs_conf, *dacs_jurisdiction;
  char *errmsg, *goto_url, *jurisdiction_uri, *qs, *remote_user, *username;
  Ds ds;
  Kwv *kwv;

  errmsg = NULL;
  if (dacs_init(DACS_STANDALONE, &argc, &argv, NULL, &errmsg) == -1) {

  fail:
	emit_plain_header(stdout);
	if (errmsg != NULL)
	  printf("%s\n", errmsg);
	else
	  printf("A fatal error occurred\n");
	emit_plain_trailer(stdout);

	exit(1);
  }

  if ((kwv = kwv_init(INIT_CGI_KWV)) == NULL) {
	errmsg = "kwv_init() failed";
	goto fail;
  }

  qs = getenv("QUERY_STRING");

  if (just_dump_stdin || (qs != NULL && streq(qs, "just_dump_stdin"))) {
	char buf[1024];

	emit_plain_header(stdout);
	while (fgets(buf, sizeof(buf), stdin) != NULL)
	  printf("%s", buf);

	exit(1);
  }

  if (cgiparse(stdin, qs, kwv, NULL) == -1) {
	errmsg = "cgiparse() failed";
	goto fail;
  }

  redirect = 1;
  goto_url = NULL;
  dacs_conf = NULL;
  dacs_jurisdiction = NULL;
  jurisdiction_uri = NULL;

  for (i = 0; i < kwv->nused; i++) {
    if (streq(kwv->pairs[i]->name, "NOREDIRECT"))
      redirect = 0;
    else if (streq(kwv->pairs[i]->name, "DACS_CONF"))
	  dacs_conf = kwv->pairs[i]->val;
    else if (streq(kwv->pairs[i]->name, "DACS_ERROR_URL"))
	  goto_url = kwv->pairs[i]->val;
    else if (streq(kwv->pairs[i]->name, "DACS_JURISDICTION")
			 && dacs_jurisdiction == NULL)
	  dacs_jurisdiction = kwv->pairs[i]->val;
    else if (streq(kwv->pairs[i]->name, "DACS_SET_JURISDICTION"))
      dacs_jurisdiction = kwv->pairs[i]->val;
    else if (streq(kwv->pairs[i]->name, "JURISDICTION_URI"))
	  jurisdiction_uri = kwv->pairs[i]->val;
  }

  if (dacs_conf == NULL) {
	emit_plain_header(stdout);
    printf("Location of dacs.conf is not set as value of \n");
	printf("the QUERY_STRING parameter DACS_CONF -- exiting.\n");
	emit_plain_trailer(stdout);

    exit(1);
  }

  if (dacs_jurisdiction == NULL) {
	emit_plain_header(stdout);
    printf("Jurisdiction is not set as value of the QUERY_STRING \n");
	printf("parameter DACS_JURISDICTION -- exiting.\n");
	emit_plain_trailer(stdout);

    exit(1);
  }

  if ((remote_user = getenv("REMOTE_USER")) == NULL) {
	emit_plain_header(stdout);
	printf("REMOTE_USER needs to be set -- exiting.\n");
	emit_plain_trailer(stdout);

	exit(1);
  }
  username = url_encode(remote_user, 0);

  if (goto_url == NULL && redirect) {
	emit_plain_header(stdout);
    printf("The redirect URL is not set as the value of the QUERY_STRING \n");
	printf("parameter DACS_ERROR_URL -- exiting.\n");
	emit_plain_trailer(stdout);

    exit(1);
  }

  /* Construct a QUERY_STRING for dacs_authenticate. */
  ds_init(&ds);
  if (redirect) {
    ds_asprintf(&ds, "QUERY_STRING=USERNAME=%s", username);
	ds_asprintf(&ds, "&DACS_AUTH_SUCCESS_HANDLER=%s", goto_url);
	ds_asprintf(&ds, "&DACS_JURISDICTION=%s", dacs_jurisdiction);
	ds_asprintf(&ds, "&DACS_BROWSER=1");
  } else {
    ds_asprintf(&ds, "QUERY_STRING=USERNAME=%s", username);
	ds_asprintf(&ds, "&DACS_JURISDICTION=%s", dacs_jurisdiction);
	ds_asprintf(&ds, "&DACS_BROWSER=1");
  }
  auth_query_string = ds_buf(&ds);

  putenv(auth_query_string);

  /* Construct the command to run dacs_authenticate. */
  if (jurisdiction_uri == NULL)
	run_dacs_auth = ds_xprintf("%s -v -t -uj %s -c %s",
							   auth_prog, dacs_jurisdiction, dacs_conf);
  else
	run_dacs_auth = ds_xprintf("%s -v -t -u %s -c %s",
							   auth_prog, jurisdiction_uri, dacs_conf);

  /*
   * Run dacs_authenticate.
   * XXX Any error is ignored.
   */
  system(run_dacs_auth);

  exit(0);
}
