diff options
| author | ArvidNorr <norrarvid@gmail.com> | 2013-01-16 01:28:35 -0800 | 
|---|---|---|
| committer | ArvidNorr <norrarvid@gmail.com> | 2013-01-16 01:28:35 -0800 | 
| commit | a2bbbd8cc336bedbda61a6af47d90bcccbe6aead (patch) | |
| tree | 9329f489b5dd4e245ee4c635d7dd18f553e260f3 | |
| parent | b2c242f50eed96431e19c5905fc1c0269709da7c (diff) | |
| download | xrdp-proprietary-a2bbbd8cc336bedbda61a6af47d90bcccbe6aead.tar.gz xrdp-proprietary-a2bbbd8cc336bedbda61a6af47d90bcccbe6aead.zip | |
Display PAM error in gateway setup, use domain name as IP/DNS, changed how the socket is closed
| -rw-r--r-- | common/trans.h | 2 | ||||
| -rw-r--r-- | libxrdp/xrdp_mcs.c | 28 | ||||
| -rw-r--r-- | sesman/auth.h | 2 | ||||
| -rw-r--r-- | sesman/scp_v0.c | 9 | ||||
| -rw-r--r-- | sesman/scp_v1.c | 4 | ||||
| -rw-r--r-- | sesman/scp_v1_mng.c | 2 | ||||
| -rw-r--r-- | sesman/verify_user_pam.c | 22 | ||||
| -rw-r--r-- | xrdp/xrdp.c | 2 | ||||
| -rw-r--r-- | xrdp/xrdp_login_wnd.c | 13 | ||||
| -rw-r--r-- | xrdp/xrdp_mm.c | 118 | ||||
| -rw-r--r-- | xrdp/xrdp_process.c | 4 | ||||
| -rw-r--r-- | xrdp/xrdp_wm.c | 7 | ||||
| -rw-r--r-- | xrdp/xrdpwin.c | 2 | 
13 files changed, 174 insertions, 41 deletions
| diff --git a/common/trans.h b/common/trans.h index 36d08a7c..1133477a 100644 --- a/common/trans.h +++ b/common/trans.h @@ -41,7 +41,7 @@ typedef int (*ttrans_conn_in)(struct trans* self, struct trans* new_self);  struct trans  { -  tbus sck; +  tbus sck; /* socket handle */    int mode; /* 1 tcp, 2 unix socket */    int status;    int type1; /* 1 listener 2 server 3 client */ diff --git a/libxrdp/xrdp_mcs.c b/libxrdp/xrdp_mcs.c index 77c0d10d..e5481c9c 100644 --- a/libxrdp/xrdp_mcs.c +++ b/libxrdp/xrdp_mcs.c @@ -819,6 +819,25 @@ xrdp_mcs_send(struct xrdp_mcs *self, struct stream *s, int chan)      return 0;  } +/** + * Internal help function to close the socket + * @param self + */ +void close_rdp_socket(struct xrdp_mcs *self) +{ +    if(self->iso_layer->tcp_layer) +    { +        if(self->iso_layer->tcp_layer->trans) +        {	     +            g_tcp_close(self->iso_layer->tcp_layer->trans->sck);	     +            self->iso_layer->tcp_layer->trans->sck = 0 ; +            g_writeln("xrdp_mcs_disconnect - socket closed"); +            return ; +        } +    } +    g_writeln("Failed to close socket"); +} +  /*****************************************************************************/  /* returns error */  int APP_CC @@ -833,7 +852,8 @@ xrdp_mcs_disconnect(struct xrdp_mcs *self)      if (xrdp_iso_init(self->iso_layer, s) != 0)      {          free_stream(s); -        DEBUG(("  out xrdp_mcs_disconnect error")); +        close_rdp_socket(self); +        DEBUG(("  out xrdp_mcs_disconnect error - 1"));          return 1;      } @@ -844,11 +864,13 @@ xrdp_mcs_disconnect(struct xrdp_mcs *self)      if (xrdp_iso_send(self->iso_layer, s) != 0)      {          free_stream(s); -        DEBUG(("  out xrdp_mcs_disconnect error")); +        close_rdp_socket(self); +        DEBUG(("  out xrdp_mcs_disconnect error - 2"));          return 1;      }      free_stream(s); -    DEBUG(("  out xrdp_mcs_disconnect")); +    close_rdp_socket(self); +    DEBUG(("xrdp_mcs_disconnect - close sent"));      return 0;  } diff --git a/sesman/auth.h b/sesman/auth.h index 09bec2e9..39acc0b8 100644 --- a/sesman/auth.h +++ b/sesman/auth.h @@ -36,7 +36,7 @@   *   */  long DEFAULT_CC -auth_userpass(char* user, char* pass); +auth_userpass(char* user, char* pass, int *errorcode);  /**   * diff --git a/sesman/scp_v0.c b/sesman/scp_v0.c index da6ab919..6ecb47b1 100644 --- a/sesman/scp_v0.c +++ b/sesman/scp_v0.c @@ -35,8 +35,9 @@ scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)      int display = 0;      tbus data;      struct session_item *s_item; +    int errorcode = 0 ; -    data = auth_userpass(s->username, s->password); +    data = auth_userpass(s->username, s->password,&errorcode);      if (s->type == SCP_GW_AUTHENTICATION)      { @@ -47,14 +48,14 @@ scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)              if (1 == access_login_allowed(s->username))              {                  /* the user is member of the correct groups. */ -                scp_v0s_replyauthentication(c, 0); +                scp_v0s_replyauthentication(c, errorcode);                  log_message(LOG_LEVEL_INFO, "Access permitted for user: %s",                              s->username);                  /* g_writeln("Connection allowed"); */              }              else              { -                scp_v0s_replyauthentication(c, 3); +                scp_v0s_replyauthentication(c, 32+3); /* all first 32 are reserved for PAM errors */                  log_message(LOG_LEVEL_INFO, "Username okey but group problem for "                              "user: %s", s->username);                  /* g_writeln("user password ok, but group problem"); */ @@ -65,7 +66,7 @@ scp_v0_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)              /* g_writeln("username or password error"); */              log_message(LOG_LEVEL_INFO, "Username or password error for user: %s",                          s->username); -            scp_v0s_replyauthentication(c, 2); +            scp_v0s_replyauthentication(c, errorcode);          }          auth_end(data); diff --git a/sesman/scp_v1.c b/sesman/scp_v1.c index 295fbce4..d3f0ab7f 100644 --- a/sesman/scp_v1.c +++ b/sesman/scp_v1.c @@ -50,7 +50,7 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)      retries = g_cfg->sec.login_retry;      current_try = retries; -    data = auth_userpass(s->username, s->password); +    data = auth_userpass(s->username, s->password,NULL);      /*LOG_DBG("user: %s\npass: %s", s->username, s->password);*/      while ((!data) && ((retries == 0) || (current_try > 0))) @@ -65,7 +65,7 @@ scp_v1_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)          {              case SCP_SERVER_STATE_OK:                  /* all ok, we got new username and password */ -                data = auth_userpass(s->username, s->password); +                data = auth_userpass(s->username, s->password,NULL);                  /* one try less */                  if (current_try > 0) diff --git a/sesman/scp_v1_mng.c b/sesman/scp_v1_mng.c index 0e20007d..9d1da0f5 100644 --- a/sesman/scp_v1_mng.c +++ b/sesman/scp_v1_mng.c @@ -42,7 +42,7 @@ scp_v1_mng_process(struct SCP_CONNECTION *c, struct SCP_SESSION *s)      int scount;      int end = 0; -    data = auth_userpass(s->username, s->password); +    data = auth_userpass(s->username, s->password,NULL);      /*LOG_DBG("user: %s\npass: %s", s->username, s->password);*/      if (!data) diff --git a/sesman/verify_user_pam.c b/sesman/verify_user_pam.c index b81398de..b7a7bef7 100644 --- a/sesman/verify_user_pam.c +++ b/sesman/verify_user_pam.c @@ -98,9 +98,11 @@ get_service_name(char *service_name)  }  /******************************************************************************/ -/* returns long, zero is no go */ +/* returns long, zero is no go  + Stores the detailed error code in the errorcode variable*/ +  long DEFAULT_CC -auth_userpass(char *user, char *pass) +auth_userpass(char *user, char *pass, int *errorcode)  {      int error;      struct t_auth_info *auth_info; @@ -116,6 +118,9 @@ auth_userpass(char *user, char *pass)      if (error != PAM_SUCCESS)      { +	if(errorcode!=NULL){ +		*errorcode = error ; +	}          g_printf("pam_start failed: %s\r\n", pam_strerror(auth_info->ph, error));          g_free(auth_info);          return 0; @@ -125,16 +130,27 @@ auth_userpass(char *user, char *pass)      if (error != PAM_SUCCESS)      { +	if(errorcode!=NULL){ +		*errorcode = error ; +	}          g_printf("pam_authenticate failed: %s\r\n",                   pam_strerror(auth_info->ph, error));          g_free(auth_info);          return 0;      } - +    /* From man page:   +       The pam_acct_mgmt function is used to determine if the users account is +       valid. It checks for authentication token and account expiration and +       verifies access restrictions. It is typically called after the user has +       been authenticated. +     */      error = pam_acct_mgmt(auth_info->ph, 0);      if (error != PAM_SUCCESS)      { +	if(errorcode!=NULL){ +		*errorcode = error ; +	}          g_printf("pam_acct_mgmt failed: %s\r\n",                   pam_strerror(auth_info->ph, error));          g_free(auth_info); 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_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 9b0de186..0f2fae2a 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,82 @@ 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 ; +	} +	 +    } +     +} +#endif  /*****************************************************************************/  int APP_CC  xrdp_mm_connect(struct xrdp_mm *self) @@ -1282,7 +1368,6 @@ 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"};          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,15 +1385,8 @@ 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); 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_wm.c b/xrdp/xrdp_wm.c index 24362f54..27a794a0 100644 --- a/xrdp/xrdp_wm.c +++ b/xrdp/xrdp_wm.c @@ -540,7 +540,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);  }  /*****************************************************************************/ | 
