1/* -*- c -*- ------------------------------------------------------------- *
2 *
3 *   Copyright 2004-2005 Murali Krishnan Ganapathy - All Rights Reserved
4 *
5 *   This program is free software; you can redistribute it and/or modify
6 *   it under the terms of the GNU General Public License as published by
7 *   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
8 *   Bostom MA 02111-1307, USA; either version 2 of the License, or
9 *   (at your option) any later version; incorporated herein by reference.
10 *
11 * ----------------------------------------------------------------------- */
12
13#include "passwords.h"
14#include "des.h"
15#include "string.h"
16#include <stdlib.h>
17#include <stdio.h>
18#include "tui.h"
19
20#define MAX_LINE 512
21// Max line length in a pwdfile
22p_pwdentry userdb[MAX_USERS];	// Array of pointers
23int numusers;			// Actual number of users
24
25// returns true or false, i.e. 1 or 0
26char authenticate_user(const char *username, const char *pwd)
27{
28    char salt[12];
29    int i;
30
31    for (i = 0; i < numusers; i++) {
32	if (userdb[i] == NULL)
33	    continue;
34	if (strcmp(username, userdb[i]->username) == 0) {
35	    strcpy(salt, userdb[i]->pwdhash);
36	    salt[2] = '\0';
37	    if (strcmp(userdb[i]->pwdhash, crypt(pwd, salt)) == 0)
38		return 1;
39	}
40    }
41    return 0;
42}
43
44// Does user USERNAME  have permission PERM
45char isallowed(const char *username, const char *perm)
46{
47    int i;
48    char *dperm;
49    char *tmp;
50
51    // If no users, then everybody is allowed to do everything
52    if (numusers == 0)
53	return 1;
54    if (strcmp(username, GUEST_USER) == 0)
55	return 0;
56    dperm = (char *)malloc(strlen(perm) + 3);
57    strcpy(dperm + 1, perm);
58    dperm[0] = ':';
59    dperm[strlen(perm) + 1] = ':';
60    dperm[strlen(perm) + 2] = 0;
61    // Now dperm = ":perm:"
62    for (i = 0; i < numusers; i++) {
63	if (strcmp(userdb[i]->username, username) == 0)	// Found the user
64	{
65	    if (userdb[i]->perms == NULL)
66		return 0;	// No permission
67	    tmp = strstr(userdb[i]->perms, dperm);	// Search for permission
68	    free(dperm);	// Release memory
69	    if (tmp == NULL)
70		return 0;
71	    else
72		return 1;
73	}
74    }
75    // User not found return 0
76    free(dperm);
77    return 0;
78}
79
80// Initialise the list of of user passwords permissions from file
81void init_passwords(const char *filename)
82{
83    int i;
84    char line[MAX_LINE], *p, *user, *pwdhash, *perms;
85    FILE *f;
86
87    for (i = 0; i < MAX_USERS; i++)
88	userdb[i] = NULL;
89    numusers = 0;
90
91    if (!filename)
92	return;			// No filename specified
93
94    f = fopen(filename, "r");
95    if (!f)
96	return;			// File does not exist
97
98    // Process each line
99    while (fgets(line, sizeof line, f)) {
100	// Replace EOLN with \0
101	p = strchr(line, '\r');
102	if (p)
103	    *p = '\0';
104	p = strchr(line, '\n');
105	if (p)
106	    *p = '\0';
107
108	// If comment line or empty ignore line
109	p = line;
110	while (*p == ' ')
111	    p++;		// skip initial spaces
112	if ((*p == '#') || (*p == '\0'))
113	    continue;		// Skip comment lines
114
115	user = p;		// This is where username starts
116	p = strchr(user, ':');
117	if (p == NULL)
118	    continue;		// Malformed line skip
119	*p = '\0';
120	pwdhash = p + 1;
121	if (*pwdhash == 0)
122	    continue;		// Malformed line (no password specified)
123	p = strchr(pwdhash, ':');
124	if (p == NULL) {	// No perms specified
125	    perms = NULL;
126	} else {
127	    *p = '\0';
128	    perms = p + 1;
129	    if (*perms == 0)
130		perms = NULL;
131	}
132	// At this point we have user,pwdhash and perms setup
133	userdb[numusers] = (p_pwdentry) malloc(sizeof(pwdentry));
134	strcpy(userdb[numusers]->username, user);
135	strcpy(userdb[numusers]->pwdhash, pwdhash);
136	if (perms == NULL)
137	    userdb[numusers]->perms = NULL;
138	else {
139	    userdb[numusers]->perms = (char *)malloc(strlen(perms) + 3);
140	    (userdb[numusers]->perms)[0] = ':';
141	    strcpy(userdb[numusers]->perms + 1, perms);
142	    (userdb[numusers]->perms)[strlen(perms) + 1] = ':';
143	    (userdb[numusers]->perms)[strlen(perms) + 2] = 0;
144	    // Now perms field points to ":perms:"
145	}
146	numusers++;
147    }
148    fclose(f);
149}
150
151void close_passwords(void)
152{
153    int i;
154
155    for (i = 0; i < numusers; i++)
156	if (userdb[i] != NULL)
157	    free(userdb[i]);
158    numusers = 0;
159}
160