summaryrefslogtreecommitdiffstats
path: root/xrdp
diff options
context:
space:
mode:
authorArvidNorr <norrarvid@gmail.com>2013-01-31 07:17:42 -0800
committerArvidNorr <norrarvid@gmail.com>2013-01-31 07:17:42 -0800
commit9aa0cb4e61eeb253a9a1177f1162eb5289130e96 (patch)
tree2b1be914a65edd952cf3ba22ef8d338be28e83a5 /xrdp
parentffc7e7ff270134c7f5c73f8f86cac81038e8fee3 (diff)
parent876f356dad387d3d9b1a8382c0115857ca605e54 (diff)
downloadxrdp-proprietary-9aa0cb4e61eeb253a9a1177f1162eb5289130e96.tar.gz
xrdp-proprietary-9aa0cb4e61eeb253a9a1177f1162eb5289130e96.zip
Merge pull request #58 from ArvidNorr/pam-cont
PAM additions mostly for a gateway situation
Diffstat (limited to 'xrdp')
-rw-r--r--xrdp/xrdp.c2
-rw-r--r--xrdp/xrdp.ini2
-rw-r--r--xrdp/xrdp_login_wnd.c13
-rw-r--r--xrdp/xrdp_mm.c179
-rw-r--r--xrdp/xrdp_process.c4
-rw-r--r--xrdp/xrdp_types.h1
-rw-r--r--xrdp/xrdp_wm.c12
-rw-r--r--xrdp/xrdpwin.c2
8 files changed, 189 insertions, 26 deletions
diff --git a/xrdp/xrdp.c b/xrdp/xrdp.c
index fb6fd5dd..2ed2c8fd 100644
--- a/xrdp/xrdp.c
+++ b/xrdp/xrdp.c
@@ -177,7 +177,7 @@ void DEFAULT_CC
pipe_sig(int sig_num)
{
/* do nothing */
- g_writeln("got SIGPIPE(%d)", sig_num);
+ g_writeln("got XRDP SIGPIPE(%d)", sig_num);
}
/*****************************************************************************/
diff --git a/xrdp/xrdp.ini b/xrdp/xrdp.ini
index f500f63f..d4a99dfb 100644
--- a/xrdp/xrdp.ini
+++ b/xrdp/xrdp.ini
@@ -25,6 +25,8 @@ tcp_keepalive=yes
#autorun=xrdp1
#hidelogwindow=yes
#bulk_compression=yes
+# You can set the PAM error text in a gateway setup (MAX 256 chars)
+#pamerrortxt=change your password according to policy at http://url
[Logging]
LogFile=xrdp.log
diff --git a/xrdp/xrdp_login_wnd.c b/xrdp/xrdp_login_wnd.c
index fc4cf125..08abfedb 100644
--- a/xrdp/xrdp_login_wnd.c
+++ b/xrdp/xrdp_login_wnd.c
@@ -315,7 +315,18 @@ xrdp_wm_show_edits(struct xrdp_wm *self, struct xrdp_bitmap *combo)
{
self->login_window->focused_control = b;
}
-
+ /*Use the domain name as the destination IP/DNS
+ This is useful in a gateway setup.*/
+ if (g_strncmp(name, "ip", 255) == 0)
+ {
+ /* If the first char in the domain name is '_' we use the domain name as IP*/
+ if(self->session->client_info->domain[0]=='_')
+ {
+ g_strncpy(b->caption1, &self->session->client_info->domain[1], 255);
+ b->edit_pos = g_mbstowcs(0, b->caption1, 0);
+ }
+
+ }
if (g_strncmp(name, "username", 255) == 0)
{
g_strncpy(b->caption1, self->session->client_info->username, 255);
diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c
index 52751b72..90127c4b 100644
--- a/xrdp/xrdp_mm.c
+++ b/xrdp/xrdp_mm.c
@@ -17,10 +17,12 @@
*
* module manager
*/
-
+#define ACCESS
#include "xrdp.h"
#include "log.h"
-#define ACCESS
+#ifdef ACCESS
+#include "security/_pam_types.h"
+#endif
/*****************************************************************************/
struct xrdp_mm *APP_CC
@@ -187,9 +189,17 @@ xrdp_mm_send_login(struct xrdp_mm *self)
}
/* send domain */
- index = g_strlen(self->wm->client_info->domain);
- out_uint16_be(s, index);
- out_uint8a(s, self->wm->client_info->domain, index);
+ if(self->wm->client_info->domain[0]!='_')
+ {
+ index = g_strlen(self->wm->client_info->domain);
+ out_uint16_be(s, index);
+ out_uint8a(s, self->wm->client_info->domain, index);
+ }
+ else
+ {
+ out_uint16_be(s, 0);
+ /* out_uint8a(s, "", 0); */
+ }
/* send program / shell */
index = g_strlen(self->wm->client_info->program);
@@ -1060,12 +1070,12 @@ xrdp_mm_sesman_data_in(struct trans *trans)
int access_control(char *username, char *password, char *srv)
{
int reply;
- int rec = 1; // failure
+ int rec = 32+1; /* 32 is reserved for PAM failures this means connect failure */
struct stream *in_s;
struct stream *out_s;
unsigned long version;
unsigned short int dummy;
- unsigned short int ok;
+ unsigned short int pAM_errorcode;
unsigned short int code;
unsigned long size;
int index;
@@ -1117,17 +1127,17 @@ int access_control(char *username, char *password, char *srv)
if ((size == 14) && (version == 0))
{
in_uint16_be(in_s, code);
- in_uint16_be(in_s, ok);
+ in_uint16_be(in_s, pAM_errorcode); /* this variable holds the PAM error code if the variable is >32 it is a "invented" code */
in_uint16_be(in_s, dummy);
- if (code != 4)
+ if (code != 4) /*0x04 means SCP_GW_AUTHENTICATION*/
{
log_message(LOG_LEVEL_ERROR, "Returned cmd code from "
"sesman is corrupt");
}
else
{
- rec = ok; /* here we read the reply from the access control */
+ rec = pAM_errorcode; /* here we read the reply from the access control */
}
}
else
@@ -1189,6 +1199,134 @@ void cleanup_states(struct xrdp_mm *self)
self-> usechansrv = 0; /* true if chansrvport is set in xrdp.ini or using sesman */
}
}
+#ifdef ACCESS
+const char *getPAMError(const int pamError)
+{
+ switch(pamError){
+ case PAM_SUCCESS:
+ return "Success";
+ case PAM_OPEN_ERR:
+ return "dlopen() failure";
+ case PAM_SYMBOL_ERR:
+ return "Symbol not found";
+ case PAM_SERVICE_ERR:
+ return "Error in service module";
+ case PAM_SYSTEM_ERR:
+ return "System error";
+ case PAM_BUF_ERR:
+ return "Memory buffer error";
+ case PAM_PERM_DENIED:
+ return "Permission denied";
+ case PAM_AUTH_ERR:
+ return "Authentication failure";
+ case PAM_CRED_INSUFFICIENT:
+ return "Insufficient credentials to access authentication data";
+ case PAM_AUTHINFO_UNAVAIL:
+ return "Authentication service cannot retrieve authentication info.";
+ case PAM_USER_UNKNOWN:
+ return "User not known to the underlying authentication module";
+ case PAM_MAXTRIES:
+ return "Have exhasted maximum number of retries for service.";
+ case PAM_NEW_AUTHTOK_REQD:
+ return "Authentication token is no longer valid; new one required.";
+ case PAM_ACCT_EXPIRED:
+ return "User account has expired";
+ case PAM_CRED_UNAVAIL:
+ return "Authentication service cannot retrieve user credentials";
+ case PAM_CRED_EXPIRED:
+ return "User credentials expired";
+ case PAM_CRED_ERR:
+ return "Failure setting user credentials";
+ case PAM_NO_MODULE_DATA:
+ return "No module specific data is present";
+ case PAM_BAD_ITEM:
+ return "Bad item passed to pam_*_item()";
+ case PAM_CONV_ERR:
+ return "Conversation error";
+ case PAM_AUTHTOK_ERR:
+ return "Authentication token manipulation error";
+ case PAM_AUTHTOK_LOCK_BUSY:
+ return "Authentication token lock busy";
+ case PAM_AUTHTOK_DISABLE_AGING:
+ return "Authentication token aging disabled";
+ case PAM_TRY_AGAIN:
+ return "Failed preliminary check by password service";
+ case PAM_IGNORE:
+ return "Please ignore underlying account module";
+ case PAM_MODULE_UNKNOWN:
+ return "Module is unknown";
+ case PAM_AUTHTOK_EXPIRED:
+ return "Authentication token expired";
+ case PAM_CONV_AGAIN:
+ return "Conversation is waiting for event";
+ case PAM_INCOMPLETE:
+ return "Application needs to call libpam again";
+ case 32+1:
+ return "Error connecting to PAM";
+ case 32+3:
+ return "Username okey but group problem";
+ default:{
+ char replytxt[80];
+ g_sprintf(replytxt,"Not defined PAM error:%d",pamError);
+ return replytxt ;
+ }
+
+ }
+
+}
+
+const char *getPAMAdditionalErrorInfo(const int pamError,struct xrdp_mm *self)
+{
+ switch(pamError){
+ case PAM_SUCCESS:
+ return NULL;
+ case PAM_OPEN_ERR:
+ case PAM_SYMBOL_ERR:
+ case PAM_SERVICE_ERR:
+ case PAM_SYSTEM_ERR:
+ case PAM_BUF_ERR:
+ case PAM_PERM_DENIED:
+ case PAM_AUTH_ERR:
+ case PAM_CRED_INSUFFICIENT:
+ case PAM_AUTHINFO_UNAVAIL:
+ case PAM_USER_UNKNOWN:
+ case PAM_CRED_UNAVAIL:
+ case PAM_CRED_ERR:
+ case PAM_NO_MODULE_DATA:
+ case PAM_BAD_ITEM:
+ case PAM_CONV_ERR:
+ case PAM_AUTHTOK_ERR:
+ case PAM_AUTHTOK_LOCK_BUSY:
+ case PAM_AUTHTOK_DISABLE_AGING:
+ case PAM_TRY_AGAIN:
+ case PAM_IGNORE:
+ case PAM_MODULE_UNKNOWN:
+ case PAM_CONV_AGAIN:
+ case PAM_INCOMPLETE:
+ case _PAM_RETURN_VALUES+1:
+ case _PAM_RETURN_VALUES+3:
+ return NULL;
+ case PAM_MAXTRIES:
+ case PAM_NEW_AUTHTOK_REQD:
+ case PAM_ACCT_EXPIRED:
+ case PAM_CRED_EXPIRED:
+ case PAM_AUTHTOK_EXPIRED:
+ if(self->wm->pamerrortxt[0])
+ {
+ return self->wm->pamerrortxt;
+ }
+ else
+ {
+ return "Authentication error - Verify that user/password is valid ";
+ }
+ default:{
+ return "No expected error" ;
+ }
+
+ }
+
+}
+#endif
/*****************************************************************************/
int APP_CC
xrdp_mm_connect(struct xrdp_mm *self)
@@ -1282,7 +1420,7 @@ xrdp_mm_connect(struct xrdp_mm *self)
{
int reply;
char replytxt[80];
- char replymessage[4][80] = {"Ok", "Sesman connect failure", "User or password error", "Privilege group error"};
+ char *additionalError;
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"); */
@@ -1300,18 +1438,19 @@ xrdp_mm_connect(struct xrdp_mm *self)
/* 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");
- }
+
+ g_sprintf(replytxt, "Reply from access control: %s", getPAMError(reply));
xrdp_wm_log_msg(self->wm, replytxt);
log_message(LOG_LEVEL_INFO, replytxt);
+ additionalError = getPAMAdditionalErrorInfo(reply,self);
+ if(additionalError)
+ {
+ if(additionalError[0])
+ {
+ xrdp_wm_log_msg(self->wm,additionalError);
+ }
+ }
if (reply != 0)
{
diff --git a/xrdp/xrdp_process.c b/xrdp/xrdp_process.c
index e3b846ea..070dc697 100644
--- a/xrdp/xrdp_process.c
+++ b/xrdp/xrdp_process.c
@@ -197,14 +197,14 @@ xrdp_process_main_loop(struct xrdp_process *self)
break;
}
}
-
+ /* send disconnect message if possible */
libxrdp_disconnect(self->session);
}
else
{
g_writeln("xrdp_process_main_loop: libxrdp_process_incomming failed");
}
-
+ /* Run end in module */
xrdp_process_mod_end(self);
libxrdp_exit(self->session);
self->session = 0;
diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h
index fdaed059..d99dced9 100644
--- a/xrdp/xrdp_types.h
+++ b/xrdp/xrdp_types.h
@@ -316,6 +316,7 @@ struct xrdp_wm
int hints;
int allowedchannels[MAX_NR_CHANNELS];
int allowedinitialized ;
+ char pamerrortxt[256];
};
/* rdp process */
diff --git a/xrdp/xrdp_wm.c b/xrdp/xrdp_wm.c
index 0a2600f2..e67bdff9 100644
--- a/xrdp/xrdp_wm.c
+++ b/xrdp/xrdp_wm.c
@@ -446,6 +446,11 @@ xrdp_wm_load_static_colors_plus(struct xrdp_wm *self, char *autorun_name)
val = (char *)list_get_item(values, index);
self->hide_log_window = text2bool(val);
}
+ else if (g_strcasecmp(val, "pamerrortxt") == 0)
+ {
+ val = (char *)list_get_item(values, index);
+ g_strncpy(self->pamerrortxt,val,255);
+ }
}
}
}
@@ -534,7 +539,12 @@ xrdp_wm_init(struct xrdp_wm *self)
names->auto_free = 1;
values = list_create();
values->auto_free = 1;
- g_strncpy(section_name, self->session->client_info->domain, 255);
+ /* domain names that starts with '_' are reserved for IP/DNS to simplify
+ * for the user in a gateway setup */
+ if(self->session->client_info->domain[0]!='_')
+ {
+ g_strncpy(section_name, self->session->client_info->domain, 255);
+ }
if (section_name[0] == 0)
{
diff --git a/xrdp/xrdpwin.c b/xrdp/xrdpwin.c
index ed6fa4c5..b6bf8fc8 100644
--- a/xrdp/xrdpwin.c
+++ b/xrdp/xrdpwin.c
@@ -137,7 +137,7 @@ void DEFAULT_CC
pipe_sig(int sig_num)
{
/* do nothing */
- g_writeln("got SIGPIPE(%d)", sig_num);
+ g_writeln("got XRDP WIN SIGPIPE(%d)", sig_num);
}
/*****************************************************************************/