1
0
mirror of https://github.com/lammertb/libhttp.git synced 2025-09-03 01:21:16 +03:00

Dialog to add and delete users and reset user passwords for Windows

This commit is contained in:
bel
2014-04-13 22:17:44 +02:00
parent b5da6dbcaa
commit 3a9aa9b80e
2 changed files with 232 additions and 19 deletions

View File

@@ -83,11 +83,16 @@ static char *server_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 struct mg_context *ctx; /* Set by start_civetweb() */
static int guard = 0; /* test if any dialog is already open */
#if !defined(CONFIG_FILE)
#define CONFIG_FILE "civetweb.conf"
#endif /* !CONFIG_FILE */
#if !defined(PASSWORDS_FILE_NAME)
#define PASSWORDS_FILE_NAME ".htpasswd"
#endif
/* backup config file */
#if !defined(CONFIG_FILE2) && defined(LINUX)
#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 =
"# Civetweb web server configuration file.\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"
"# To make a change, remove leading '#', modify option's value,\n"
"# save this file and then restart Civetweb.\n\n";
@@ -575,9 +580,9 @@ static void start_civetweb(int argc, char *argv[])
#ifdef _WIN32
enum {
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_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
ID_CONTROLS, incremented by one. */
@@ -622,7 +627,6 @@ static void WINAPI ServiceMain(void)
SetServiceStatus(hStatus, &ss);
}
static void show_error(void)
{
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;
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") ?
BST_CHECKED : BST_UNCHECKED);
} else {
SetWindowText(GetDlgItem(hDlg, ID_CONTROLS + i), value);
SetDlgItemText(hDlg, ID_CONTROLS + i, value == NULL ? "" : value);
}
}
break;
@@ -791,18 +796,73 @@ static BOOL CALLBACK DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lP)
free(title);
}
SetFocus(GetDlgItem(hDlg, ID_SAVE));
for (i = 0; default_options[i].name != NULL; i++) {
name = default_options[i].name;
value = mg_get_option(ctx, name);
if (default_options[i].type == CONFIG_TYPE_BOOLEAN) {
CheckDlgButton(hDlg, ID_CONTROLS + i, !strcmp(value, "yes") ?
BST_CHECKED : BST_UNCHECKED);
} else {
SetDlgItemText(hDlg, ID_CONTROLS + i, value == NULL ? "" : value);
}
/* Init dialog with active settings */
SendMessage(hDlg, WM_COMMAND, ID_RESET_ACTIVE, 0);
/* alternative: SendMessage(hDlg, WM_COMMAND, ID_RESET_FILE, 0); */
break;
default:
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;
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:
break;
}
@@ -855,7 +915,6 @@ static void show_settings_dialog()
DWORD style;
DLGTEMPLATE *dia = (DLGTEMPLATE *) mem;
WORD i, cl, x, y, width, nelems = 0;
static int guard = 0; /* test if dialog is already open */
static struct {
DLGTEMPLATE template; /* 18 bytes */
@@ -939,8 +998,139 @@ static void show_settings_dialog()
assert((int)p - (int)mem < sizeof(mem));
dia->cy = ((nelems + 1) / 2 + 1) * HEIGHT + 30;
DialogBoxIndirectParam(NULL, dia, NULL, DlgProc, (LPARAM) NULL);
DialogBoxIndirectParam(NULL, dia, NULL, SettingsDlgProc, (LPARAM) NULL);
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)
@@ -1022,6 +1212,9 @@ static LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam,
case ID_SETTINGS:
show_settings_dialog();
break;
case ID_PASSWORD:
change_password_file();
break;
case ID_INSTALL_SERVICE:
case ID_REMOVE_SERVICE:
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_STRING, ID_CONNECT, "Start browser");
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_STRING, ID_QUIT, "Exit");
GetCursorPos(&pt);