You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
xrdp-proprietary/xrdp/xrdp_login_wnd.c

725 lines
21 KiB

/*
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., 675 Mass Ave, Cambridge, MA 02139, USA.
xrdp: A Remote Desktop Protocol server.
Copyright (C) Jay Sorg 2004-2005
main login window and login help window
*/
#include "xrdp.h"
/*****************************************************************************/
/* all login help screen events go here */
static int DEFAULT_CC
xrdp_wm_login_help_notify(struct xrdp_bitmap* wnd,
struct xrdp_bitmap* sender,
int msg, long param1, long param2)
{
struct xrdp_painter* p;
if (wnd == 0)
{
return 0;
}
if (sender == 0)
{
return 0;
}
if (wnd->owner == 0)
{
return 0;
}
if (msg == 1) /* click */
{
if (sender->id == 1) /* ok button */
{
if (sender->owner->notify != 0)
{
wnd->owner->notify(wnd->owner, wnd, 100, 1, 0); /* ok */
}
}
}
else if (msg == WM_PAINT) /* 3 */
{
p = (struct xrdp_painter*)param1;
if (p != 0)
{
p->font->color = wnd->wm->black;
xrdp_painter_draw_text(p, wnd, 10, 30, "You must be authenticated \
before using this");
xrdp_painter_draw_text(p, wnd, 10, 46, "session.");
xrdp_painter_draw_text(p, wnd, 10, 78, "Enter a valid username in \
the username edit box.");
xrdp_painter_draw_text(p, wnd, 10, 94, "Enter the password in \
the password edit box.");
xrdp_painter_draw_text(p, wnd, 10, 110, "Both the username and \
password are case");
xrdp_painter_draw_text(p, wnd, 10, 126, "sensitive.");
xrdp_painter_draw_text(p, wnd, 10, 158, "Contact your system \
administrator if you are");
xrdp_painter_draw_text(p, wnd, 10, 174, "having problems \
logging on.");
}
}
return 0;
}
#if 0
/*****************************************************************************/
static int DEFAULT_CC
xrdp_wm_popup_notify(struct xrdp_bitmap* wnd,
struct xrdp_bitmap* sender,
int msg, int param1, int param2)
{
return 0;
}
#endif
/*****************************************************************************/
/* called from main thread */
static long DEFAULT_CC
sync_unload(long param1, long param2)
{
return g_free_library(param1);
}
/*****************************************************************************/
/* called from main thread */
static long DEFAULT_CC
sync_load(long param1, long param2)
{
return g_load_library((char*)param1);
}
/*****************************************************************************/
int APP_CC
xrdp_wm_setup_mod1(struct xrdp_wm* self,
struct xrdp_mod_data* mod_data)
{
void* func;
if (self == 0)
{
return 1;
}
if (self->mod_handle == 0)
{
self->mod_handle = g_xrdp_sync(sync_load, (long)mod_data->lib, 0);
if (self->mod_handle != 0)
{
func = g_get_proc_address(self->mod_handle, "mod_init");
if (func == 0)
{
func = g_get_proc_address(self->mod_handle, "_mod_init");
}
if (func == 0)
{
g_printf("error finding proc mod_init in %s\r\n", mod_data->lib);
}
self->mod_init = (struct xrdp_mod* (*)(void))func;
func = g_get_proc_address(self->mod_handle, "mod_exit");
if (func == 0)
{
func = g_get_proc_address(self->mod_handle, "_mod_exit");
}
if (func == 0)
{
g_printf("error finding proc mod_exit in %s\r\n", mod_data->lib);
}
self->mod_exit = (int (*)(struct xrdp_mod*))func;
if (self->mod_init != 0 && self->mod_exit != 0)
{
self->mod = self->mod_init();
}
}
else
{
g_printf("error loading %s\r\n", mod_data->lib);
}
if (self->mod != 0)
{
self->mod->wm = (long)self;
self->mod->server_begin_update = server_begin_update;
self->mod->server_end_update = server_end_update;
self->mod->server_fill_rect = server_fill_rect;
self->mod->server_screen_blt = server_screen_blt;
self->mod->server_paint_rect = server_paint_rect;
self->mod->server_set_pointer = server_set_pointer;
self->mod->server_palette = server_palette;
self->mod->server_msg = server_msg;
self->mod->server_is_term = server_is_term;
self->mod->server_set_clip = server_set_clip;
self->mod->server_reset_clip = server_reset_clip;
self->mod->server_set_fgcolor = server_set_fgcolor;
self->mod->server_set_bgcolor = server_set_bgcolor;
self->mod->server_set_opcode = server_set_opcode;
self->mod->server_set_mixmode = server_set_mixmode;
self->mod->server_set_brush = server_set_brush;
self->mod->server_set_pen = server_set_pen;
self->mod->server_draw_line = server_draw_line;
self->mod->server_add_char = server_add_char;
self->mod->server_draw_text = server_draw_text;
self->mod->server_reset = server_reset;
}
}
/* id self->mod is null, there must be a problem */
if (self->mod == 0)
{
DEBUG(("problem loading lib in xrdp_wm_setup_mod1\r\n"));
return 1;
}
return 0;
}
/*****************************************************************************/
int APP_CC
xrdp_wm_setup_mod2(struct xrdp_wm* self,
struct list* names,
struct list* values)
{
char text[256];
int i;
int rv;
rv = 1;
if (!self->pro_layer->term)
{
if (self->mod->mod_start(self->mod, self->screen->width,
self->screen->height, self->screen->bpp) != 0)
{
self->pro_layer->term = 1; /* kill session */
}
}
if (!self->pro_layer->term)
{
/* always set these */
self->mod->mod_set_param(self->mod, "hostname",
self->session->client_info->hostname);
g_sprintf(text, "%d", self->session->client_info->keylayout);
self->mod->mod_set_param(self->mod, "keylayout", text);
for (i = 0; i < names->count; i++)
{
self->mod->mod_set_param(self->mod,
(char*)list_get_item(names, i),
(char*)list_get_item(values, i));
}
/* connect */
if (self->mod->mod_connect(self->mod) == 0)
{
rv = 0;
}
}
return rv;
}
/*****************************************************************************/
static int APP_CC
xrdp_wm_delete_all_childs(struct xrdp_wm* self)
{
int i;
struct xrdp_bitmap* b;
for (i = self->screen->child_list->count - 1; i >= 0; i--)
{
b = (struct xrdp_bitmap*)list_get_item(self->screen->child_list, i);
xrdp_bitmap_delete(b);
}
xrdp_bitmap_invalidate(self->screen, 0);
return 0;
}
/*****************************************************************************/
static int APP_CC
set_mod_data_item(struct xrdp_mod_data* mod, char* name, char* value)
{
int index;
for (index = 0; index < mod->names->count; index++)
{
if (g_strncmp(name, (char*)list_get_item(mod->names, index), 255) == 0)
{
list_remove_item(mod->values, index);
list_insert_item(mod->values, index, (long)g_strdup(value));
}
}
return 0;
}
/*****************************************************************************/
static int APP_CC
xrdp_wm_help_clicked(struct xrdp_bitmap* wnd)
{
struct xrdp_bitmap* help;
struct xrdp_bitmap* but;
/* create help screen */
help = xrdp_bitmap_create(300, 300, wnd->wm->screen->bpp,
WND_TYPE_WND, wnd->wm);
list_insert_item(wnd->wm->screen->child_list, 0, (long)help);
help->parent = wnd->wm->screen;
help->owner = wnd;
wnd->modal_dialog = help;
help->bg_color = wnd->wm->grey;
help->left = wnd->wm->screen->width / 2 - help->width / 2;
help->top = wnd->wm->screen->height / 2 - help->height / 2;
help->notify = xrdp_wm_login_help_notify;
set_string(&help->caption1, "Login help");
/* ok button */
but = xrdp_bitmap_create(60, 25, wnd->wm->screen->bpp,
WND_TYPE_BUTTON, wnd->wm);
list_insert_item(help->child_list, 0, (long)but);
but->parent = help;
but->owner = help;
but->left = 120;
but->top = 260;
but->id = 1;
but->tab_stop = 1;
set_string(&but->caption1, "OK");
/* draw it */
help->focused_control = but;
help->default_button = but;
help->esc_button = but;
xrdp_bitmap_invalidate(help, 0);
xrdp_wm_set_focused(wnd->wm, help);
return 0;
}
/*****************************************************************************/
static int APP_CC
xrdp_wm_cancel_clicked(struct xrdp_bitmap* wnd)
{
if (wnd != 0)
{
if (wnd->wm != 0)
{
if (wnd->wm->pro_layer != 0)
{
wnd->wm->pro_layer->term = 1;
}
}
}
return 0;
}
/*****************************************************************************/
static int APP_CC
xrdp_wm_ok_clicked(struct xrdp_bitmap* wnd)
{
struct xrdp_bitmap* combo;
struct xrdp_bitmap* label;
struct xrdp_bitmap* edit;
struct xrdp_wm* wm;
struct list* names;
struct list* values;
struct xrdp_mod_data* mod_data;
int i;
wm = wnd->wm;
combo = xrdp_bitmap_get_child_by_id(wnd, 6);
if (combo != 0)
{
mod_data = (struct xrdp_mod_data*)
list_get_item(combo->data_list, combo->item_index);
if (mod_data != 0)
{
/* get the user typed values */
i = 100;
label = xrdp_bitmap_get_child_by_id(wnd, i);
edit = xrdp_bitmap_get_child_by_id(wnd, i + 1);
while (label != 0 && edit != 0)
{
set_mod_data_item(mod_data, label->caption1, edit->caption1);
i += 2;
label = xrdp_bitmap_get_child_by_id(wnd, i);
edit = xrdp_bitmap_get_child_by_id(wnd, i + 1);
}
if (xrdp_wm_setup_mod1(wm, mod_data) == 0)
{
/* gota copy these cause dialog gets freed */
names = list_create();
names->auto_free = 1;
for (i = 0; i < mod_data->names->count; i++)
{
list_add_item(names,
(long)g_strdup((char*)list_get_item(mod_data->names, i)));
}
values = list_create();
values->auto_free = 1;
for (i = 0; i < mod_data->values->count; i++)
{
list_add_item(values,
(long)g_strdup((char*)list_get_item(mod_data->values, i)));
}
xrdp_wm_delete_all_childs(wm);
if (xrdp_wm_setup_mod2(wm, names, values) != 0)
{
/* totaly free mod */
if (wm->mod_exit != 0)
{
wm->mod_exit(wm->mod);
}
g_xrdp_sync(sync_unload, wm->mod_handle, 0);
wm->mod = 0;
wm->mod_handle = 0;
wm->mod_init = 0;
wm->mod_exit = 0;
}
else /* close connection log window if connection is ok */
{
if (wm->log_wnd != 0)
{
xrdp_bitmap_delete(wm->log_wnd);
}
}
if (!wm->pro_layer->term)
{
if (wm->mod != 0)
{
if (wm->mod->sck != 0)
{
wm->pro_layer->app_sck = wm->mod->sck;
}
}
}
list_delete(names);
list_delete(values);
}
}
}
return 0;
}
/******************************************************************************/
static int APP_CC
xrdp_wm_show_edits(struct xrdp_wm* self, struct xrdp_bitmap* combo)
{
int count;
int index;
int insert_index;
int username_set;
char* name;
char* value;
struct xrdp_mod_data* mod;
struct xrdp_bitmap* b;
username_set = 0;
/* free labels and edits, cause we gota create them */
/* creation or combo changed */
for (index = 100; index < 200; index++)
{
b = xrdp_bitmap_get_child_by_id(combo->parent, index);
xrdp_bitmap_delete(b);
}
insert_index = list_index_of(self->login_window->child_list,
(long)combo);
insert_index++;
mod = (struct xrdp_mod_data*)
list_get_item(combo->data_list, combo->item_index);
if (mod != 0)
{
count = 0;
for (index = 0; index < mod->names->count; index++)
{
value = (char*)list_get_item(mod->values, index);
if (g_strncmp("ask", value, 3) == 0)
{
/* label */
b = xrdp_bitmap_create(60, 20, self->screen->bpp,
WND_TYPE_LABEL, self);
list_insert_item(self->login_window->child_list, insert_index,
(long)b);
insert_index++;
b->parent = self->login_window;
b->owner = self->login_window;
b->left = 155;
b->top = 60 + 25 * count;
b->id = 100 + 2 * count;
name = (char*)list_get_item(mod->names, index);
set_string(&b->caption1, name);
/* edit */
b = xrdp_bitmap_create(140, 20, self->screen->bpp,
WND_TYPE_EDIT, self);
list_insert_item(self->login_window->child_list, insert_index,
(long)b);
insert_index++;
b->parent = self->login_window;
b->owner = self->login_window;
b->left = 220;
b->top = 60 + 25 * count;
b->id = 100 + 2 * count + 1;
b->pointer = 1;
b->tab_stop = 1;
b->caption1 = (char*)g_malloc(256, 1);
g_strcpy(b->caption1, value + 3);
b->edit_pos = g_strlen(b->caption1);
if (self->login_window->focused_control == 0)
{
self->login_window->focused_control = b;
}
if (g_strncmp(name, "username", 255) == 0)
{
g_free(b->caption1);
b->caption1 = g_strdup(self->session->client_info->username);
b->edit_pos = g_strlen(b->caption1);
if (g_strlen(b->caption1) > 0)
{
username_set = 1;
}
}
if (g_strncmp(name, "password", 255) == 0)
{
b->password_char = '*';
if (username_set)
{
if (b->parent != 0)
{
b->parent->focused_control = b;
}
}
}
count++;
}
}
}
return 0;
}
/*****************************************************************************/
/* all login screen events go here */
static int DEFAULT_CC
xrdp_wm_login_notify(struct xrdp_bitmap* wnd,
struct xrdp_bitmap* sender,
int msg, long param1, long param2)
{
struct xrdp_bitmap* b;
struct xrdp_rect rect;
int i;
if (wnd->modal_dialog != 0 && msg != 100)
{
return 0;
}
if (msg == 1) /* click */
{
if (sender->id == 1) /* help button */
{
xrdp_wm_help_clicked(wnd);
}
else if (sender->id == 2) /* cancel button */
{
xrdp_wm_cancel_clicked(wnd);
}
else if (sender->id == 3) /* ok button */
{
xrdp_wm_ok_clicked(wnd);
}
}
else if (msg == 2) /* mouse move */
{
}
else if (msg == 100) /* modal result is done */
{
i = list_index_of(wnd->wm->screen->child_list, (long)sender);
if (i >= 0)
{
b = (struct xrdp_bitmap*)
list_get_item(wnd->wm->screen->child_list, i);
list_remove_item(sender->wm->screen->child_list, i);
MAKERECT(rect, b->left, b->top, b->width, b->height);
xrdp_bitmap_invalidate(wnd->wm->screen, &rect);
xrdp_bitmap_delete(sender);
wnd->modal_dialog = 0;
xrdp_wm_set_focused(wnd->wm, wnd);
}
}
else if (msg == CB_ITEMCHANGE) /* combo box change */
{
xrdp_wm_show_edits(wnd->wm, sender);
xrdp_bitmap_invalidate(wnd, 0); /* invalidate the whole dialog for now */
}
return 0;
}
/******************************************************************************/
static int APP_CC
xrdp_wm_login_fill_in_combo(struct xrdp_wm* self, struct xrdp_bitmap* b)
{
struct list* sections;
struct list* section_names;
struct list* section_values;
int fd;
int i;
int j;
char* p;
char* q;
char* r;
struct xrdp_mod_data* mod_data;
sections = list_create();
sections->auto_free = 1;
section_names = list_create();
section_names->auto_free = 1;
section_values = list_create();
section_values->auto_free = 1;
fd = g_file_open(XRDP_CFG_FILE); /* xrdp.ini */
file_read_sections(fd, sections);
for (i = 0; i < sections->count; i++)
{
p = (char*)list_get_item(sections, i);
file_read_section(fd, p, section_names, section_values);
if (g_strncmp(p, "globals", 255) == 0)
{
}
else
{
mod_data = (struct xrdp_mod_data*)
g_malloc(sizeof(struct xrdp_mod_data), 1);
mod_data->names = list_create();
mod_data->names->auto_free = 1;
mod_data->values = list_create();
mod_data->values->auto_free = 1;
g_strcpy(mod_data->name, p); /* set name in square bracket */
for (j = 0; j < section_names->count; j++)
{
q = (char*)list_get_item(section_names, j);
r = (char*)list_get_item(section_values, j);
if (g_strncmp("name", q, 255) == 0)
{
g_strcpy(mod_data->name, r);
}
else if (g_strncmp("lib", q, 255) == 0)
{
g_strcpy(mod_data->lib, r);
}
else
{
list_add_item(mod_data->names, (long)g_strdup(q));
list_add_item(mod_data->values, (long)g_strdup(r));
}
}
list_add_item(b->string_list, (long)g_strdup(mod_data->name));
list_add_item(b->data_list, (long)mod_data);
}
}
g_file_close(fd);
list_delete(sections);
list_delete(section_names);
list_delete(section_values);
return 0;
}
/******************************************************************************/
int APP_CC
xrdp_login_wnd_create(struct xrdp_wm* self)
{
struct xrdp_bitmap* but;
struct xrdp_bitmap* combo;
/* draw login window */
self->login_window = xrdp_bitmap_create(400, 200, self->screen->bpp,
WND_TYPE_WND, self);
list_add_item(self->screen->child_list, (long)self->login_window);
self->login_window->parent = self->screen;
self->login_window->owner = self->screen;
self->login_window->bg_color = self->grey;
self->login_window->left = self->screen->width / 2 -
self->login_window->width / 2;
self->login_window->top = self->screen->height / 2 -
self->login_window->height / 2;
self->login_window->notify = xrdp_wm_login_notify;
set_string(&self->login_window->caption1, "Login to xrdp");
/* image */
but = xrdp_bitmap_create(4, 4, self->screen->bpp, WND_TYPE_IMAGE, self);
xrdp_bitmap_load(but, "xrdp256.bmp", self->palette);
but->parent = self->screen;
but->owner = self->screen;
but->left = self->screen->width - but->width;
but->top = self->screen->height - but->height;
list_add_item(self->screen->child_list, (long)but);
/* image */
but = xrdp_bitmap_create(4, 4, self->screen->bpp, WND_TYPE_IMAGE, self);
xrdp_bitmap_load(but, "ad256.bmp", self->palette);
but->parent = self->login_window;
but->owner = self->login_window;
but->left = 10;
but->top = 30;
list_add_item(self->login_window->child_list, (long)but);
/* label */
but = xrdp_bitmap_create(60, 20, self->screen->bpp, WND_TYPE_LABEL, self);
list_add_item(self->login_window->child_list, (long)but);
but->parent = self->login_window;
but->owner = self->login_window;
but->left = 155;
but->top = 35;
set_string(&but->caption1, "Module");
/* combo */
combo = xrdp_bitmap_create(140, 20, self->screen->bpp, WND_TYPE_COMBO, self);
list_add_item(self->login_window->child_list, (long)combo);
combo->parent = self->login_window;
combo->owner = self->login_window;
combo->left = 220;
combo->top = 35;
combo->id = 6;
combo->tab_stop = 1;
xrdp_wm_login_fill_in_combo(self, combo);
/* button */
but = xrdp_bitmap_create(60, 25, self->screen->bpp, WND_TYPE_BUTTON, self);
list_add_item(self->login_window->child_list, (long)but);
but->parent = self->login_window;
but->owner = self->login_window;
but->left = 180;
but->top = 160;
but->id = 3;
set_string(&but->caption1, "OK");
but->tab_stop = 1;
self->login_window->default_button = but;
/* button */
but = xrdp_bitmap_create(60, 25, self->screen->bpp, WND_TYPE_BUTTON, self);
list_add_item(self->login_window->child_list, (long)but);
but->parent = self->login_window;
but->owner = self->login_window;
but->left = 250;
but->top = 160;
but->id = 2;
set_string(&but->caption1, "Cancel");
but->tab_stop = 1;
self->login_window->esc_button = but;
/* button */
but = xrdp_bitmap_create(60, 25, self->screen->bpp, WND_TYPE_BUTTON, self);
list_add_item(self->login_window->child_list, (long)but);
but->parent = self->login_window;
but->owner = self->login_window;
but->left = 320;
but->top = 160;
but->id = 1;
set_string(&but->caption1, "Help");
but->tab_stop = 1;
/* labels and edits */
xrdp_wm_show_edits(self, combo);
return 0;
}