#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <pwd.h>
#include <syslog.h>
#include <security/pam_appl.h>
#include <security/pam_misc.h>
#include <security/_pam_types.h>

void test_pam_error(pam_handle_t *ph, int pam_retval)
{
  if (pam_retval != PAM_SUCCESS)
    {
      fputs("authpam: auth error\n", stderr);
      syslog(LOG_ERR, pam_strerror(ph, pam_retval));
      exit(EXIT_FAILURE);
    }
}

int main(int argc, char *argv[])
{
  int retval;
  struct passwd *myinfo;
  struct pam_conv myconv;
  pam_handle_t *pamhandle = NULL;
  FILE *secure_file;
  char buf[256];

  openlog("authcat", LOG_PID, LOG_AUTHPRIV);
  if (argc != 2)
    {
      fputs("usage: authcat filename\n", stderr);
      exit(EXIT_FAILURE);
    }

myinfo = getpwuid(getuid());
  if (myinfo == NULL)
    {
      fputs("authcat: cannot determine the current user\n", stderr);
      exit(EXIT_FAILURE);
    }

myconv.conv = misc_conv;
  myconv.appdata_ptr = NULL;
  retval = pam_start("authcat", myinfo->pw_name, &myconv, &pamhandle);
  test_pam_error(pamhandle, retval);

  retval = pam_authenticate(pamhandle, 0);
  test_pam_error(pamhandle, retval);

  retval = pam_acct_mgmt(pamhandle, 0);
  test_pam_error(pamhandle, retval);

  secure_file = fopen(argv[1], "r");
  if (secure_file == NULL)
    {
      fputs("authcat: cannot open file\n", stderr);
      exit(EXIT_FAILURE);
    }

  while (!feof(secure_file))
    {
      if (fgets(buf, 256, secure_file))
        fputs(buf, stdout);
    }

  fclose(secure_file);

  retval = pam_end(pamhandle, retval);
  test_pam_error(pamhandle, retval);

  return EXIT_SUCCESS;
}
