mirror of
https://github.com/lammertb/libhttp.git
synced 2025-09-04 12:42:09 +03:00
Dialog to add and delete users and reset user passwords for Windows
This commit is contained in:
@@ -3215,8 +3215,8 @@ static int is_authorized_for_put(struct mg_connection *conn)
|
|||||||
int mg_modify_passwords_file(const char *fname, const char *domain,
|
int mg_modify_passwords_file(const char *fname, const char *domain,
|
||||||
const char *user, const char *pass)
|
const char *user, const char *pass)
|
||||||
{
|
{
|
||||||
int found;
|
int found, i;
|
||||||
char line[512], u[512] = "", d[512] ="", ha1[33], tmp[PATH_MAX+1];
|
char line[512], u[512] = "", d[512] ="", ha1[33], tmp[PATH_MAX+8];
|
||||||
FILE *fp, *fp2;
|
FILE *fp, *fp2;
|
||||||
|
|
||||||
found = 0;
|
found = 0;
|
||||||
@@ -3227,6 +3227,25 @@ int mg_modify_passwords_file(const char *fname, const char *domain,
|
|||||||
pass = NULL;
|
pass = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Other arguments must not be empty */
|
||||||
|
if (fname == NULL || domain == NULL || user == NULL) return 0;
|
||||||
|
|
||||||
|
/* Using the given file format, user name and domain must not contain ':' */
|
||||||
|
if (strchr(user, ':') != NULL) return 0;
|
||||||
|
if (strchr(domain, ':') != NULL) return 0;
|
||||||
|
|
||||||
|
/* Do not allow control characters like newline in user name and domain.
|
||||||
|
Do not allow excessively long names either. */
|
||||||
|
for (i=0; user[i]!=0 && i<255; i++) {
|
||||||
|
if (iscntrl(user[i])) return 0;
|
||||||
|
}
|
||||||
|
if (user[i]) return 0;
|
||||||
|
for (i=0; domain[i]!=0 && i<255; i++) {
|
||||||
|
if (iscntrl(domain[i])) return 0;
|
||||||
|
}
|
||||||
|
if (domain[i]) return 0;
|
||||||
|
|
||||||
|
/* Create a temporary file name */
|
||||||
(void) snprintf(tmp, sizeof(tmp) - 1, "%s.tmp", fname);
|
(void) snprintf(tmp, sizeof(tmp) - 1, "%s.tmp", fname);
|
||||||
tmp[sizeof(tmp) - 1] = 0;
|
tmp[sizeof(tmp) - 1] = 0;
|
||||||
|
|
||||||
|
228
src/main.c
228
src/main.c
@@ -83,11 +83,16 @@ static char *server_name; /* Set by init_server_name() */
|
|||||||
static char *icon_name; /* Set by init_server_name() */
|
static char *icon_name; /* Set by init_server_name() */
|
||||||
static char config_file[PATH_MAX] = ""; /* Set by process_command_line_arguments() */
|
static char config_file[PATH_MAX] = ""; /* Set by process_command_line_arguments() */
|
||||||
static struct mg_context *ctx; /* Set by start_civetweb() */
|
static struct mg_context *ctx; /* Set by start_civetweb() */
|
||||||
|
static int guard = 0; /* test if any dialog is already open */
|
||||||
|
|
||||||
#if !defined(CONFIG_FILE)
|
#if !defined(CONFIG_FILE)
|
||||||
#define CONFIG_FILE "civetweb.conf"
|
#define CONFIG_FILE "civetweb.conf"
|
||||||
#endif /* !CONFIG_FILE */
|
#endif /* !CONFIG_FILE */
|
||||||
|
|
||||||
|
#if !defined(PASSWORDS_FILE_NAME)
|
||||||
|
#define PASSWORDS_FILE_NAME ".htpasswd"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* backup config file */
|
/* backup config file */
|
||||||
#if !defined(CONFIG_FILE2) && defined(LINUX)
|
#if !defined(CONFIG_FILE2) && defined(LINUX)
|
||||||
#define CONFIG_FILE2 "/usr/local/etc/civetweb.conf"
|
#define CONFIG_FILE2 "/usr/local/etc/civetweb.conf"
|
||||||
@@ -168,7 +173,7 @@ static void show_usage_and_exit(void)
|
|||||||
static const char *config_file_top_comment =
|
static const char *config_file_top_comment =
|
||||||
"# Civetweb web server configuration file.\n"
|
"# Civetweb web server configuration file.\n"
|
||||||
"# For detailed description of every option, visit\n"
|
"# For detailed description of every option, visit\n"
|
||||||
"# https://github.com/sunsetbrew/civetweb/blob/master/docs/UserManual.md\n"
|
"# https://github.com/bel2125/civetweb/blob/master/docs/UserManual.md\n"
|
||||||
"# Lines starting with '#' and empty lines are ignored.\n"
|
"# Lines starting with '#' and empty lines are ignored.\n"
|
||||||
"# To make a change, remove leading '#', modify option's value,\n"
|
"# To make a change, remove leading '#', modify option's value,\n"
|
||||||
"# save this file and then restart Civetweb.\n\n";
|
"# save this file and then restart Civetweb.\n\n";
|
||||||
@@ -575,9 +580,9 @@ static void start_civetweb(int argc, char *argv[])
|
|||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
enum {
|
enum {
|
||||||
ID_ICON = 100, ID_QUIT, ID_SETTINGS, ID_SEPARATOR, ID_INSTALL_SERVICE,
|
ID_ICON = 100, ID_QUIT, ID_SETTINGS, ID_SEPARATOR, ID_INSTALL_SERVICE,
|
||||||
ID_REMOVE_SERVICE, ID_STATIC, ID_GROUP,
|
ID_REMOVE_SERVICE, ID_STATIC, ID_GROUP, ID_PASSWORD,
|
||||||
ID_SAVE, ID_RESET_DEFAULTS, ID_RESET_FILE, ID_RESET_ACTIVE,
|
ID_SAVE, ID_RESET_DEFAULTS, ID_RESET_FILE, ID_RESET_ACTIVE,
|
||||||
ID_STATUS, ID_CONNECT,
|
ID_STATUS, ID_CONNECT, ID_ADD_USER, ID_ADD_USER_NAME, ID_ADD_USER_REALM,
|
||||||
|
|
||||||
/* All dynamically created text boxes for options have IDs starting from
|
/* All dynamically created text boxes for options have IDs starting from
|
||||||
ID_CONTROLS, incremented by one. */
|
ID_CONTROLS, incremented by one. */
|
||||||
@@ -622,7 +627,6 @@ static void WINAPI ServiceMain(void)
|
|||||||
SetServiceStatus(hStatus, &ss);
|
SetServiceStatus(hStatus, &ss);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void show_error(void)
|
static void show_error(void)
|
||||||
{
|
{
|
||||||
char buf[256];
|
char buf[256];
|
||||||
@@ -667,7 +671,8 @@ static void save_config(HWND hDlg, FILE *fp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lP)
|
|
||||||
|
static BOOL CALLBACK SettingsDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lP)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
int i, j;
|
int i, j;
|
||||||
@@ -740,7 +745,7 @@ static BOOL CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lP)
|
|||||||
CheckDlgButton(hDlg, ID_CONTROLS + i, !strcmp(value, "yes") ?
|
CheckDlgButton(hDlg, ID_CONTROLS + i, !strcmp(value, "yes") ?
|
||||||
BST_CHECKED : BST_UNCHECKED);
|
BST_CHECKED : BST_UNCHECKED);
|
||||||
} else {
|
} else {
|
||||||
SetWindowText(GetDlgItem(hDlg, ID_CONTROLS + i), value);
|
SetDlgItemText(hDlg, ID_CONTROLS + i, value == NULL ? "" : value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -791,18 +796,73 @@ static BOOL CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lP)
|
|||||||
free(title);
|
free(title);
|
||||||
}
|
}
|
||||||
SetFocus(GetDlgItem(hDlg, ID_SAVE));
|
SetFocus(GetDlgItem(hDlg, ID_SAVE));
|
||||||
for (i = 0; default_options[i].name != NULL; i++) {
|
|
||||||
name = default_options[i].name;
|
/* Init dialog with active settings */
|
||||||
value = mg_get_option(ctx, name);
|
SendMessage(hDlg, WM_COMMAND, ID_RESET_ACTIVE, 0);
|
||||||
if (default_options[i].type == CONFIG_TYPE_BOOLEAN) {
|
/* alternative: SendMessage(hDlg, WM_COMMAND, ID_RESET_FILE, 0); */
|
||||||
CheckDlgButton(hDlg, ID_CONTROLS + i, !strcmp(value, "yes") ?
|
break;
|
||||||
BST_CHECKED : BST_UNCHECKED);
|
|
||||||
} else {
|
default:
|
||||||
SetDlgItemText(hDlg, ID_CONTROLS + i, value == NULL ? "" : value);
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GetPassword(char * password, unsigned maxlen)
|
||||||
|
{
|
||||||
|
assert(maxlen>=255);
|
||||||
|
/* TODO: replace by a proper dialog */
|
||||||
|
strcpy(password, "12345");
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL CALLBACK PasswordDlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lP)
|
||||||
|
{
|
||||||
|
static const char *passfile = 0;
|
||||||
|
char domain[256], user[256], password[256];
|
||||||
|
WORD ctrlId;
|
||||||
|
|
||||||
|
switch (msg) {
|
||||||
|
case WM_CLOSE:
|
||||||
|
passfile = 0;
|
||||||
|
DestroyWindow(hDlg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WM_COMMAND:
|
||||||
|
ctrlId = LOWORD(wParam);
|
||||||
|
if (ctrlId == ID_ADD_USER) {
|
||||||
|
/* Add user */
|
||||||
|
GetWindowText(GetDlgItem(hDlg, ID_ADD_USER_NAME), user, sizeof(user));
|
||||||
|
GetWindowText(GetDlgItem(hDlg, ID_ADD_USER_REALM), domain, sizeof(domain));
|
||||||
|
GetPassword(password, sizeof(password));
|
||||||
|
mg_modify_passwords_file(passfile, domain, user, password);
|
||||||
|
EndDialog(hDlg, IDOK);
|
||||||
|
} else if ((ctrlId>=(ID_CONTROLS + ID_FILE_BUTTONS_DELTA * 3)) &&
|
||||||
|
(ctrlId<(ID_CONTROLS + ID_FILE_BUTTONS_DELTA * 4))) {
|
||||||
|
/* Modify password */
|
||||||
|
GetWindowText(GetDlgItem(hDlg, ctrlId - ID_FILE_BUTTONS_DELTA * 3), user, sizeof(user));
|
||||||
|
GetWindowText(GetDlgItem(hDlg, ctrlId - ID_FILE_BUTTONS_DELTA * 2), domain, sizeof(domain));
|
||||||
|
GetPassword(password, sizeof(password));
|
||||||
|
mg_modify_passwords_file(passfile, domain, user, password);
|
||||||
|
EndDialog(hDlg, IDOK);
|
||||||
|
} else if ((ctrlId>=(ID_CONTROLS + ID_FILE_BUTTONS_DELTA * 2)) &&
|
||||||
|
(ctrlId<(ID_CONTROLS + ID_FILE_BUTTONS_DELTA * 3))) {
|
||||||
|
/* Remove user */
|
||||||
|
GetWindowText(GetDlgItem(hDlg, ctrlId - ID_FILE_BUTTONS_DELTA * 2), user, sizeof(user));
|
||||||
|
GetWindowText(GetDlgItem(hDlg, ctrlId - ID_FILE_BUTTONS_DELTA), domain, sizeof(domain));
|
||||||
|
mg_modify_passwords_file(passfile, domain, user, NULL);
|
||||||
|
EndDialog(hDlg, IDOK);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case WM_INITDIALOG:
|
||||||
|
passfile = (const char *)lP;
|
||||||
|
SendMessage(hDlg, WM_SETICON,(WPARAM) ICON_SMALL, (LPARAM) hIcon);
|
||||||
|
SendMessage(hDlg, WM_SETICON,(WPARAM) ICON_BIG, (LPARAM) hIcon);
|
||||||
|
SetWindowText(hDlg, passfile);
|
||||||
|
SetFocus(GetDlgItem(hDlg, ID_ADD_USER_NAME));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -855,7 +915,6 @@ static void show_settings_dialog()
|
|||||||
DWORD style;
|
DWORD style;
|
||||||
DLGTEMPLATE *dia = (DLGTEMPLATE *) mem;
|
DLGTEMPLATE *dia = (DLGTEMPLATE *) mem;
|
||||||
WORD i, cl, x, y, width, nelems = 0;
|
WORD i, cl, x, y, width, nelems = 0;
|
||||||
static int guard = 0; /* test if dialog is already open */
|
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
DLGTEMPLATE template; /* 18 bytes */
|
DLGTEMPLATE template; /* 18 bytes */
|
||||||
@@ -939,8 +998,139 @@ static void show_settings_dialog()
|
|||||||
assert((int)p - (int)mem < sizeof(mem));
|
assert((int)p - (int)mem < sizeof(mem));
|
||||||
|
|
||||||
dia->cy = ((nelems + 1) / 2 + 1) * HEIGHT + 30;
|
dia->cy = ((nelems + 1) / 2 + 1) * HEIGHT + 30;
|
||||||
DialogBoxIndirectParam(NULL, dia, NULL, DlgProc, (LPARAM) NULL);
|
DialogBoxIndirectParam(NULL, dia, NULL, SettingsDlgProc, (LPARAM) NULL);
|
||||||
guard--;
|
guard--;
|
||||||
|
|
||||||
|
#undef HEIGHT
|
||||||
|
#undef WIDTH
|
||||||
|
#undef LABEL_WIDTH
|
||||||
|
}
|
||||||
|
|
||||||
|
static void change_password_file()
|
||||||
|
{
|
||||||
|
#define HEIGHT 15
|
||||||
|
#define WIDTH 320
|
||||||
|
#define LABEL_WIDTH 90
|
||||||
|
|
||||||
|
OPENFILENAME of;
|
||||||
|
char path[PATH_MAX] = PASSWORDS_FILE_NAME;
|
||||||
|
char strbuf[256], u[256], d[256];
|
||||||
|
HWND hDlg = NULL;
|
||||||
|
FILE * f;
|
||||||
|
int y, nelems;
|
||||||
|
unsigned char mem[4096], *p;
|
||||||
|
DLGTEMPLATE *dia = (DLGTEMPLATE *) mem;
|
||||||
|
const char * domain = mg_get_option(ctx, "authentication_domain");
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
DLGTEMPLATE template; /* 18 bytes */
|
||||||
|
WORD menu, class;
|
||||||
|
wchar_t caption[1];
|
||||||
|
WORD fontsiz;
|
||||||
|
wchar_t fontface[7];
|
||||||
|
} dialog_header = {{
|
||||||
|
WS_CAPTION | WS_POPUP | WS_SYSMENU | WS_VISIBLE |
|
||||||
|
DS_SETFONT | WS_DLGFRAME, WS_EX_TOOLWINDOW, 0, 200, 200, WIDTH, 0
|
||||||
|
},
|
||||||
|
0, 0, L"", 8, L"Tahoma"
|
||||||
|
};
|
||||||
|
|
||||||
|
if (guard == 0) {
|
||||||
|
guard++;
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&of, 0, sizeof(of));
|
||||||
|
of.lStructSize = sizeof(of);
|
||||||
|
of.hwndOwner = (HWND) hDlg;
|
||||||
|
of.lpstrFile = path;
|
||||||
|
of.nMaxFile = sizeof(path);
|
||||||
|
of.lpstrInitialDir = mg_get_option(ctx, "document_root");
|
||||||
|
of.Flags = OFN_CREATEPROMPT | OFN_NOCHANGEDIR | OFN_HIDEREADONLY;
|
||||||
|
|
||||||
|
if (IDOK != GetSaveFileName(&of)) {
|
||||||
|
guard--;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
f = fopen(path, "a+");
|
||||||
|
if (f) {
|
||||||
|
fclose(f);
|
||||||
|
} else {
|
||||||
|
MessageBox(NULL, path, "Can not open file", MB_ICONERROR);
|
||||||
|
guard--;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
(void) memset(mem, 0, sizeof(mem));
|
||||||
|
(void) memcpy(mem, &dialog_header, sizeof(dialog_header));
|
||||||
|
p = mem + sizeof(dialog_header);
|
||||||
|
|
||||||
|
f = fopen(path, "r+");
|
||||||
|
if (!f) {
|
||||||
|
MessageBox(NULL, path, "Can not open file", MB_ICONERROR);
|
||||||
|
guard--;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nelems = 0;
|
||||||
|
while (fgets(strbuf, sizeof(strbuf), f)) {
|
||||||
|
if (sscanf(strbuf, "%255[^:]:%255[^:]:%*s", u, d) != 2) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
u[255]=0;
|
||||||
|
d[255]=0;
|
||||||
|
y = (nelems + 1) * HEIGHT + 5;
|
||||||
|
add_control(&p, dia, 0x80, ID_CONTROLS + nelems + ID_FILE_BUTTONS_DELTA * 3,
|
||||||
|
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_TABSTOP,
|
||||||
|
10, y, 65, 12, "Modify password");
|
||||||
|
add_control(&p, dia, 0x80, ID_CONTROLS + nelems + ID_FILE_BUTTONS_DELTA * 2,
|
||||||
|
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_TABSTOP,
|
||||||
|
80, y, 55, 12, "Remove user");
|
||||||
|
add_control(&p, dia, 0x81, ID_CONTROLS + nelems + ID_FILE_BUTTONS_DELTA,
|
||||||
|
WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL | WS_DISABLED,
|
||||||
|
245, y, 60, 12, d);
|
||||||
|
add_control(&p, dia, 0x81, ID_CONTROLS + nelems,
|
||||||
|
WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL | WS_DISABLED,
|
||||||
|
140, y, 100, 12, u);
|
||||||
|
|
||||||
|
nelems++;
|
||||||
|
assert((int)p - (int)mem < sizeof(mem));
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
y = (WORD) ((nelems + 1) * HEIGHT + 10);
|
||||||
|
add_control(&p, dia, 0x80, ID_ADD_USER,
|
||||||
|
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_TABSTOP,
|
||||||
|
80, y, 55, 12, "Add user");
|
||||||
|
add_control(&p, dia, 0x81, ID_ADD_USER_REALM,
|
||||||
|
WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL,
|
||||||
|
245, y, 60, 12, domain);
|
||||||
|
add_control(&p, dia, 0x81, ID_ADD_USER_NAME,
|
||||||
|
WS_CHILD | WS_VISIBLE | WS_BORDER | ES_AUTOHSCROLL,
|
||||||
|
140, y, 100, 12, "");
|
||||||
|
|
||||||
|
y = (WORD) ((nelems + 2) * HEIGHT + 10);
|
||||||
|
add_control(&p, dia, 0x80, ID_GROUP, WS_CHILD | WS_VISIBLE |
|
||||||
|
BS_GROUPBOX, 5, 5, WIDTH - 10, y, " Users ");
|
||||||
|
|
||||||
|
y += HEIGHT;
|
||||||
|
add_control(&p, dia, 0x82, ID_STATIC,
|
||||||
|
WS_CHILD | WS_VISIBLE | WS_DISABLED,
|
||||||
|
5, y, 100, 12, server_base_name);
|
||||||
|
|
||||||
|
assert((int)p - (int)mem < sizeof(mem));
|
||||||
|
|
||||||
|
dia->cy = y + 20;
|
||||||
|
} while (IDOK == DialogBoxIndirectParam(NULL, dia, NULL, PasswordDlgProc, (LPARAM) path));
|
||||||
|
|
||||||
|
guard--;
|
||||||
|
|
||||||
|
#undef HEIGHT
|
||||||
|
#undef WIDTH
|
||||||
|
#undef LABEL_WIDTH
|
||||||
}
|
}
|
||||||
|
|
||||||
static int manage_service(int action)
|
static int manage_service(int action)
|
||||||
@@ -1022,6 +1212,9 @@ static LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam,
|
|||||||
case ID_SETTINGS:
|
case ID_SETTINGS:
|
||||||
show_settings_dialog();
|
show_settings_dialog();
|
||||||
break;
|
break;
|
||||||
|
case ID_PASSWORD:
|
||||||
|
change_password_file();
|
||||||
|
break;
|
||||||
case ID_INSTALL_SERVICE:
|
case ID_INSTALL_SERVICE:
|
||||||
case ID_REMOVE_SERVICE:
|
case ID_REMOVE_SERVICE:
|
||||||
manage_service(LOWORD(wParam));
|
manage_service(LOWORD(wParam));
|
||||||
@@ -1053,6 +1246,7 @@ static LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam,
|
|||||||
AppendMenu(hMenu, MF_SEPARATOR, ID_SEPARATOR, "");
|
AppendMenu(hMenu, MF_SEPARATOR, ID_SEPARATOR, "");
|
||||||
AppendMenu(hMenu, MF_STRING, ID_CONNECT, "Start browser");
|
AppendMenu(hMenu, MF_STRING, ID_CONNECT, "Start browser");
|
||||||
AppendMenu(hMenu, MF_STRING, ID_SETTINGS, "Edit settings");
|
AppendMenu(hMenu, MF_STRING, ID_SETTINGS, "Edit settings");
|
||||||
|
AppendMenu(hMenu, MF_STRING, ID_PASSWORD, "Modify password file");
|
||||||
AppendMenu(hMenu, MF_SEPARATOR, ID_SEPARATOR, "");
|
AppendMenu(hMenu, MF_SEPARATOR, ID_SEPARATOR, "");
|
||||||
AppendMenu(hMenu, MF_STRING, ID_QUIT, "Exit");
|
AppendMenu(hMenu, MF_STRING, ID_QUIT, "Exit");
|
||||||
GetCursorPos(&pt);
|
GetCursorPos(&pt);
|
||||||
|
Reference in New Issue
Block a user