/* Public domain */ /* * Minimal PerCGI authentication / session management module. * Here we use a plain password file stored in a hash database. */ #include #include #include "auth.h" #include "pathnames.h" DB *dbPasswd; Fatal(const char *txt, int rv) { fprintf(stderr, "%s: %s\n", txt, db_strerror(rv)); exit(1); } static void Init(void *pSess) { Session *sess = pSess; int rv; if ((rv = db_create(&dbPasswd, NULL, 0)) != 0) { Fatal("db_create", rv); } rv = dbPasswd->open(dbPasswd, NULL, _PATH_PASSWD, NULL, DB_HASH, 0, 0); if (rv != 0) Fatal(_PATH_PASSWD, rv); } static void Destroy(void *pSess) { Session *sess = pSess; int rv; if ((rv = dbPasswd->close(dbPasswd, 0)) != 0) { fprintf(stderr, "db_close: %s\n", db_strerror(rv)); } } static void SessOpen(void *pSess) { /* Session *sess = pSess; */ /* Fetch / set session variables here... */ } static int Auth(void *pSess, CGI_Query *q, const char *user, const char *pw) { char userBuf[128]; Session *sess = pSess; DBT key, data; int rv; Strlcpy(userBuf, user, sizeof(userBuf)); memset(&key, 0, sizeof(DBT)); memset(&data, 0, sizeof(DBT)); key.data = userBuf; key.size = strlen(user)+1; if ((rv = dbPasswd->get(dbPasswd, NULL, &key, &data, 0)) != 0 || strcmp(data.data, pw) != 0) { CGI_SetError("Invalid username or password."); return (-1); } CGI_Log(LOG_DEBUG, "[%s] Auth OK %s", SESSID(sess), user); return (0); } /* Display the login dialog. */ static void LoginPage(CGI_Query *q) { const char *user = CGI_Get(q, "username", USERNAME_MAX); const char *pass = CGI_Get(q, "password", PASSWORD_MAX); const char *loghome = CGI_Get(q, "login_home", OPNAME_MAX); CGI_Begin(q, "text/html"); if (user != NULL) { SetS("login_username", user); } if (pass != NULL) { SetS("login_password", pass); } if (loghome != NULL) { SetS("login_home", loghome); } HTML_Output(q, "login"); } /* Display the logout dialog. */ static void Logout(CGI_Query *q) { CGI_Begin(q, "text/html"); CGI_CloseSession(q->sess); HTML_Output(q, "logout"); } /* Assist a user in recovering a password. */ static void LostPwPage(CGI_Query *q) { CGI_Begin(q, "text/html"); HTML_Output(q, "auth_assist"); } CGI_SessionOps sessionOps = { "PerCGI session manager", sizeof(Session), Init, Destroy, NULL, /* load */ NULL, /* save */ Auth, Auth, /* ReAuth */ SessOpen, NULL, /* sessClose */ NULL, /* sessExpired */ LoginPage, Logout, LostPwPage };