/*****************************************************************************

  POPular -- A POP3 server and proxy for large mail systems

  $Id: libpdm_master.c,v 1.2 2001/04/25 10:01:21 sqrt Exp $

  http://www.remote.org/jochen/mail/popular/

******************************************************************************

  Copyright (C) 1999-2001  Jochen Topf <jochen@remote.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 of the License, 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 <popular.h>


static struct pdm_mvar *mv;

struct pdm_ctx_master {
  char filename[MAXBUF];
};


/*****************************************************************************
 
  pdm_init()
 
  Currently the filename is only saved in the init function and the file
  will be opened every time an authentication is done. This might change
  in a future version.
 
*****************************************************************************/
char *
pdm_init(int argc, char *argv[], struct pdm_mvar *mvar, void **pdmctx)
{
  struct pdm_ctx_master *ctx;
  mv = mvar;

  PDM_DEBUG3("pdm_init", "start with argc=%d id='%s' name='%s'", argc, argv[0], argv[1]);
  
  if (argc != 3) {
    PDM_DEBUG0("pdm_init", "argc != 1");
    return("not enough or too many arguments");
  }

  ctx = malloc(sizeof(struct pdm_ctx_master));
  if (! ctx) {
    PDM_DEBUG0("pdm_init", "out of memory");
    return("out of memory");
  }
  strlcpy(ctx->filename, argv[2], sizeof(ctx->filename));

  *pdmctx = ctx;
  PDM_DEBUG1("pdm_init", "module initialized (filename='%s')", ctx->filename);
  return NULL;
}


/*****************************************************************************
 
  pdm_close()

*****************************************************************************/
int
pdm_close(void *pdmctx)
{
  free(pdmctx);
  return 0;
}


/*****************************************************************************
 
  pdm_args()

*****************************************************************************/
char *
pdm_args(void *pdmctx)
{
  struct pdm_ctx_master *ctx = pdmctx;
  return ctx->filename;
}


/*****************************************************************************
 
  pdm_reload()

  We don't have to do anything in this module. Just return true.

*****************************************************************************/
int
pdm_reload(void *pdmctx)
{
  return 1;
}


/*****************************************************************************
 
  is_wild()

*****************************************************************************/
int
is_wild(const char *s)
{
  return (s[0] == '*') && (s[1] == '\0');
}


/*****************************************************************************
 
  pdm_auth()

*****************************************************************************/
pdm_result_t
pdm_auth(void *pdmctx, const struct pdm_request *pdmr, struct pdm_data *pdmd)
{
  struct pdm_ctx_master *ctx = pdmctx;
  FILE *maf;
  char buf[80];

  PDM_DEBUG0("pdm_auth", "start");

  maf = fopen(ctx->filename, "r");
  if (maf == NULL) {
    PDM_DEBUG1("pdm_auth", "file open failed with errmsg='%s'", strerror(errno));
    return pdmError;
  }

  PDM_DEBUG1("pdm_auth", "file '%s' opened", ctx->filename);

  while (fgets(buf, sizeof(buf), maf)) {
    char *dn, *dp;
    if (buf[0] == '#') continue;

    dn = strchr(buf, ':');
    if (dn == NULL) continue;
    *dn++ = '\0';
    dp = strchr(dn, ':');
    if (dp == NULL) continue;
    *dp++ = '\0';

    if (dp[strlen(dp)-1] == '\n') dp[strlen(dp)-1] = 0;

    PDM_DEBUG3("pdm_auth", "testing against peer='%s' ns='%s' pass='%s'", buf, dn, dp);
    if ((!strcmp(pdmr->peer, buf)           || is_wild(buf)) &&
        (!strcmp(pdmr->namespace, dn)       || is_wild(dn))  &&
        (!strcmp(crypt(pdmr->pass, dp), dp) || is_wild(dp))) {
      pdmd->flags = PP_FLAGS_M;
      fclose(maf);
      PDM_DEBUG0("pdm_auth", "match found");
      return pdmAccept;
    }
  }

  PDM_DEBUG0("pdm_auth", "no match found, returning");
  fclose(maf);
  pdmd->reason = pdmFailUnknown;
  return pdmFail;
}


/** THE END *****************************************************************/


syntax highlighted by Code2HTML, v. 0.9.1