summaryrefslogtreecommitdiffstats
path: root/xrdp
diff options
context:
space:
mode:
authornorrarvid <norrarvid@gmail.com>2012-06-18 10:23:09 +0200
committernorrarvid <norrarvid@gmail.com>2012-06-18 10:23:09 +0200
commit318e09fd470d177dd017e063ce434c9726f28ef7 (patch)
treec8c1c4626873a26aed91b32a84edcdc1227f4e76 /xrdp
parente87ec5072169e201c41bfb1ad70f78b549fc2767 (diff)
parent42edcbb6c193e5e825e7600a6784bd48fa9bf503 (diff)
downloadxrdp-proprietary-318e09fd470d177dd017e063ce434c9726f28ef7.tar.gz
xrdp-proprietary-318e09fd470d177dd017e063ce434c9726f28ef7.zip
fix merge conflics
Diffstat (limited to 'xrdp')
-rw-r--r--xrdp/xrdp.ini3
-rw-r--r--xrdp/xrdp_login_wnd.c11
-rw-r--r--xrdp/xrdp_mm.c246
3 files changed, 238 insertions, 22 deletions
diff --git a/xrdp/xrdp.ini b/xrdp/xrdp.ini
index 0bf1350c..47e93c99 100644
--- a/xrdp/xrdp.ini
+++ b/xrdp/xrdp.ini
@@ -65,6 +65,9 @@ ip=ask
port=ask5900
username=na
password=ask
+#pamusername=asksame
+#pampassword=asksame
+#pamsessionmng=127.0.0.1
[xrdp4]
name=sesman-any
diff --git a/xrdp/xrdp_login_wnd.c b/xrdp/xrdp_login_wnd.c
index d10094a0..69d3721f 100644
--- a/xrdp/xrdp_login_wnd.c
+++ b/xrdp/xrdp_login_wnd.c
@@ -21,6 +21,7 @@
*/
#include "xrdp.h"
+#define ACCESS
#include "log.h"
/*****************************************************************************/
@@ -223,6 +224,10 @@ xrdp_wm_ok_clicked(struct xrdp_bitmap* wnd)
xrdp_wm_set_login_mode(wm, 2);
}
}
+ else
+ {
+ log_message(LOG_LEVEL_ERROR,"Combo is 0 - potential programming error");
+ }
return 0;
}
@@ -262,7 +267,7 @@ xrdp_wm_show_edits(struct xrdp_wm* self, struct xrdp_bitmap* combo)
if (g_strncmp("ask", value, 3) == 0)
{
/* label */
- b = xrdp_bitmap_create(70, DEFAULT_EDIT_H, self->screen->bpp,
+ b = xrdp_bitmap_create(95, DEFAULT_EDIT_H, self->screen->bpp,
WND_TYPE_LABEL, self);
list_insert_item(self->login_window->child_list, insert_index,
(long)b);
@@ -303,7 +308,11 @@ xrdp_wm_show_edits(struct xrdp_wm* self, struct xrdp_bitmap* combo)
username_set = 1;
}
}
+#ifdef ACCESS
+ if ((g_strncmp(name, "password", 255) == 0) || (g_strncmp(name, "pampassword", 255) == 0))
+#else
if (g_strncmp(name, "password", 255) == 0)
+#endif
{
b->password_char = '*';
if (username_set)
diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c
index e25567fa..8dfac0b9 100644
--- a/xrdp/xrdp_mm.c
+++ b/xrdp/xrdp_mm.c
@@ -21,6 +21,8 @@
*/
#include "xrdp.h"
+#include "log.h"
+#define ACCESS
/*****************************************************************************/
struct xrdp_mm* APP_CC
@@ -104,6 +106,7 @@ xrdp_mm_delete(struct xrdp_mm* self)
}
/*****************************************************************************/
+/* Send login information to sesman */
static int APP_CC
xrdp_mm_send_login(struct xrdp_mm* self)
{
@@ -201,6 +204,7 @@ xrdp_mm_send_login(struct xrdp_mm* self)
s_mark_end(s);
s_pop_layer(s, channel_hdr);
+ /* Version 0 of the protocol to sesman is currently used by XRDP */
out_uint32_be(s, 0); /* version */
index = (int)(s->end - s->data);
out_uint32_be(s, index); /* size */
@@ -748,6 +752,17 @@ xrdp_mm_connect_chansrv(struct xrdp_mm* self, char* ip, char* port)
return 0;
}
+static void cleanup_sesman_connection(struct xrdp_mm* self)
+{
+ self->delete_sesman_trans = 1;
+ self->connected_state = 0;
+ if (self->wm->login_mode != 10)
+ {
+ xrdp_wm_set_login_mode(self->wm, 11);
+ xrdp_mm_module_cleanup(self);
+ }
+}
+
/*****************************************************************************/
static int APP_CC
xrdp_mm_process_login_response(struct xrdp_mm* self, struct stream* s)
@@ -793,14 +808,7 @@ xrdp_mm_process_login_response(struct xrdp_mm* self, struct stream* s)
xrdp_wm_log_msg(self->wm, "xrdp_mm_process_login_response: "
"login failed");
}
- self->delete_sesman_trans = 1;
- self->connected_state = 0;
- if (self->wm->login_mode != 10)
- {
- xrdp_wm_set_login_mode(self->wm, 11);
- xrdp_mm_module_cleanup(self);
- }
-
+ cleanup_sesman_connection(self);
return rv;
}
@@ -905,6 +913,7 @@ xrdp_mm_process_channel_data(struct xrdp_mm* self, tbus param1, tbus param2,
}
/*****************************************************************************/
+/* This is the callback registered for sesman communication replies. */
static int APP_CC
xrdp_mm_sesman_data_in(struct trans* trans)
{
@@ -933,11 +942,14 @@ xrdp_mm_sesman_data_in(struct trans* trans)
in_uint16_be(s, code);
switch (code)
{
+ /* even when the request is denied the reply will hold 3 as the command. */
case 3:
error = xrdp_mm_process_login_response(self, s);
break;
default:
- g_writeln("xrdp_mm_sesman_data_in: unknown code %d", code);
+ xrdp_wm_log_msg(self->wm, "An undefined reply code was received from sesman");
+ g_writeln("Fatal xrdp_mm_sesman_data_in: unknown cmd code %d", code);
+ cleanup_sesman_connection(self);
break;
}
}
@@ -945,6 +957,130 @@ xrdp_mm_sesman_data_in(struct trans* trans)
return error;
}
+#ifdef ACCESS
+/*********************************************************************/
+/* return 0 on success */
+int access_control(char *username, char *password, char *srv){
+ int reply ;
+ int rec = 1 ; // failure
+ struct stream* in_s;
+ struct stream* out_s;
+ unsigned long version ;
+ unsigned short int dummy;
+ unsigned short int ok;
+ unsigned short int code;
+ unsigned long size ;
+ int index ;
+ int socket = g_tcp_socket();
+ if (socket > 0) {
+ /* we use a blocking socket here */
+ reply = g_tcp_connect(socket, srv, "3350");
+ if (reply == 0)
+ {
+ make_stream(in_s);
+ init_stream(in_s, 500);
+ make_stream(out_s);
+ init_stream(out_s, 500);
+ s_push_layer(out_s, channel_hdr, 8);
+ out_uint16_be(out_s, 4); /*0x04 means SCP_GW_AUTHENTICATION*/
+ index = g_strlen(username);
+ out_uint16_be(out_s, index);
+ out_uint8a(out_s, username, index);
+
+ index = g_strlen(password);
+ out_uint16_be(out_s, index);
+ out_uint8a(out_s, password, index);
+ s_mark_end(out_s);
+ s_pop_layer(out_s, channel_hdr);
+ out_uint32_be(out_s, 0); /* version */
+ index = (int)(out_s->end - out_s->data);
+ out_uint32_be(out_s, index); /* size */
+ /* g_writeln("Number of data to send : %d",index); */
+ reply = g_tcp_send(socket, out_s->data, index, 0);
+ free_stream(out_s);
+ if (reply > 0)
+ {
+ /* We wait in 5 sec for a reply from sesman*/
+ if(g_tcp_can_recv(socket,5000)){
+ reply = g_tcp_recv(socket, in_s->end, 500, 0);
+ if (reply > 0)
+ {
+ in_s->end = in_s->end + reply ;
+ in_uint32_be(in_s, version);
+ /*g_writeln("Version number in reply from sesman: %d",version) ; */
+ in_uint32_be(in_s, size);
+ if((size==14) && (version==0))
+ {
+ in_uint16_be(in_s, code);
+ in_uint16_be(in_s, ok);
+ in_uint16_be(in_s, dummy);
+ if(code!=4)
+ {
+ log_message(LOG_LEVEL_ERROR,"Returned cmd code from "
+ "sesman is corrupt");
+ }
+ else
+ {
+ rec = ok; /* here we read the reply from the access control */
+ }
+ }
+ else
+ {
+ log_message(LOG_LEVEL_ERROR,"Corrupt reply size or "
+ "version from sesman: %d",size);
+ }
+ }
+ else
+ {
+ log_message(LOG_LEVEL_ERROR,"No data received from sesman");
+ }
+ }
+ else
+ {
+ log_message(LOG_LEVEL_ERROR,"Timeout when waiting for sesman");
+ }
+ }
+ else
+ {
+ log_message(LOG_LEVEL_ERROR,"No success sending to sesman");
+ }
+ free_stream(in_s);
+ g_tcp_close(socket);
+ }
+ else
+ {
+ log_message(LOG_LEVEL_ERROR,"Failure connecting to socket sesman");
+ }
+ }
+ else
+ {
+ log_message(LOG_LEVEL_ERROR,"Failure creating socket - for access control");
+ }
+ return rec;
+}
+#endif
+
+/*****************************************************************************/
+/* This routine clears all states to make sure that our next login will be
+ * as expected. If the user does not press ok on the log window and try to
+ * connect again we must make sure that no previous information is stored.*/
+void cleanup_states(struct xrdp_mm* self)
+{
+ if(self != NULL)
+ {
+ self-> connected_state = 0; /* true if connected to sesman else false */
+ self-> sesman_trans = NULL; /* connection to sesman */
+ self-> sesman_trans_up = 0 ; /* true once connected to sesman */
+ self-> delete_sesman_trans = 0; /* boolean set when done with sesman connection */
+ self-> display = 0; /* 10 for :10.0, 11 for :11.0, etc */
+ self-> code = 0; /* 0 Xvnc session 10 X11rdp session */
+ self-> sesman_controlled = 0; /* true if this is a sesman session */
+ self-> chan_trans = NULL; /* connection to chansrv */
+ self-> chan_trans_up = 0; /* true once connected to chansrv */
+ self-> delete_chan_trans = 0; /* boolean set when done with channel connection */
+ self-> usechansrv = 0; /* true if chansrvport is set in xrdp.ini or using sesman */
+ }
+}
/*****************************************************************************/
int APP_CC
xrdp_mm_connect(struct xrdp_mm* self)
@@ -953,7 +1089,6 @@ xrdp_mm_connect(struct xrdp_mm* self)
struct list* values;
int index;
int count;
- int use_sesman;
int ok;
int rv;
char* name;
@@ -963,14 +1098,24 @@ xrdp_mm_connect(struct xrdp_mm* self)
char text[256];
char port[8];
char chansrvport[256];
-
+#ifdef ACCESS
+ int use_pam_auth = 0 ;
+ char pam_auth_sessionIP[256] ;
+ char pam_auth_password[256];
+ char pam_auth_username[256];
+ char username[256];
+ char password[256];
+ username[0] = 0;
+ password[0] = 0;
+#endif
+ /* make sure we start in correct state */
+ cleanup_states(self);
g_memset(ip, 0, sizeof(ip));
g_memset(errstr, 0, sizeof(errstr));
g_memset(text, 0, sizeof(text));
g_memset(port, 0, sizeof(port));
g_memset(chansrvport, 0, sizeof(chansrvport));
rv = 0; /* success */
- use_sesman = 0;
names = self->login_names;
values = self->login_values;
count = names->count;
@@ -986,25 +1131,83 @@ xrdp_mm_connect(struct xrdp_mm* self)
{
if (g_strcasecmp(value, "-1") == 0)
{
- use_sesman = 1;
+ self->sesman_controlled = 1;
}
}
+#ifdef ACCESS
+ else if (g_strcasecmp(name, "pamusername") == 0)
+ {
+ use_pam_auth = 1;
+ g_strncpy(pam_auth_username, value, 255);
+ }
+ else if (g_strcasecmp(name, "pamsessionmng") == 0)
+ {
+ g_strncpy(pam_auth_sessionIP, value, 255);
+ }
+ else if (g_strcasecmp(name, "pampassword") == 0)
+ {
+ g_strncpy(pam_auth_password, value, 255);
+ }
+ else if (g_strcasecmp(name, "password") == 0)
+ {
+ g_strncpy(password, value, 255);
+ }
+ else if (g_strcasecmp(name, "username") == 0)
+ {
+ g_strncpy(username, value, 255);
+ }
+#endif
else if (g_strcasecmp(name, "chansrvport") == 0)
{
g_strncpy(chansrvport, value, 255);
self->usechansrv = 1;
}
}
- if (use_sesman)
+#ifdef ACCESS
+ if(use_pam_auth){
+ int reply;
+ char replytxt[80];
+ char replymessage[4][80] = {"Ok","Sesman connect failure","User or password error","Privilege group error"};
+ xrdp_wm_log_msg(self->wm, "Please wait, we now perform access control...");
+ /* g_writeln("we use pam modules to check if we can approve this user"); */
+ if(!g_strncmp(pam_auth_username,"same",255))
+ {
+ log_message(LOG_LEVEL_DEBUG,"pamusername copied from username - same: %s",username);
+ g_strncpy(pam_auth_username,username,255);
+ }
+ if(!g_strncmp(pam_auth_password,"same",255))
+ {
+ log_message(LOG_LEVEL_DEBUG,"pam_auth_password copied from username - same: %s",password);
+ g_strncpy(pam_auth_password,password,255);
+ }
+ /* access_control return 0 on success */
+ reply = access_control(pam_auth_username, pam_auth_password, pam_auth_sessionIP);
+ if(reply>=0 && reply<4)
+ {
+ g_sprintf(replytxt,"Reply from access control: %s",replymessage[reply]);
+ }
+ else
+ {
+ g_sprintf(replytxt,"Reply from access control undefined");
+ }
+ xrdp_wm_log_msg(self->wm,replytxt);
+ log_message(LOG_LEVEL_INFO,replytxt);
+ if(reply!=0)
+ {
+ rv = 1 ;
+ return rv ;
+ }
+ }
+#endif
+ if (self->sesman_controlled)
{
ok = 0;
- errstr[0] = 0;
trans_delete(self->sesman_trans);
self->sesman_trans = trans_create(TRANS_MODE_TCP, 8192, 8192);
xrdp_mm_get_sesman_port(port, sizeof(port));
g_snprintf(text, 255, "connecting to sesman ip %s port %s", ip, port);
xrdp_wm_log_msg(self->wm, text);
-
+ /* xrdp_mm_sesman_data_in is the callback that is called when data arrives */
self->sesman_trans->trans_data_in = xrdp_mm_sesman_data_in;
self->sesman_trans->header_size = 8;
self->sesman_trans->callback_data = self;
@@ -1030,6 +1233,8 @@ xrdp_mm_connect(struct xrdp_mm* self)
}
else
{
+ g_snprintf(errstr, 255, "Failure to connect to sesman: %s port: %s",
+ ip, port);
xrdp_wm_log_msg(self->wm, errstr);
trans_delete(self->sesman_trans);
self->sesman_trans = 0;
@@ -1049,13 +1254,13 @@ xrdp_mm_connect(struct xrdp_mm* self)
else
{
/* connect error */
- g_snprintf(errstr, 255, "Failure to connect to: %s port: %s",
- ip, port);
- g_writeln(errstr);
+ g_snprintf(errstr, 255, "Failure to connect to: %s",ip);
xrdp_wm_log_msg(self->wm, errstr);
rv = 1; /* failure */
}
- }else{
+ }
+ else
+ {
g_writeln("Failure setting up module");
}
if (self->wm->login_mode != 10)
@@ -1065,7 +1270,6 @@ xrdp_mm_connect(struct xrdp_mm* self)
rv = 1 ; /* failure */
}
}
- self->sesman_controlled = use_sesman;
if ((self->wm->login_mode == 10) && (self->sesman_controlled == 0) &&
(self->usechansrv != 0))