ASG
IBM
Zystems
Cressida
Icon
Netflexity
 
  MQSeries.net
Search  Search       Tech Exchange      Education      Certifications      Library      Info Center      SupportPacs      LinkedIn  Search  Search                                                                   FAQ  FAQ   Usergroups  Usergroups
 
Register  ::  Log in Log in to check your private messages
 
RSS Feed - WebSphere MQ Support RSS Feed - Message Broker Support

MQSeries.net Forum Index » IBM MQ Security » Security Exit UserID/PWD passing issue

Post new topic  Reply to topic Goto page 1, 2  Next
 Security Exit UserID/PWD passing issue « View previous topic :: View next topic » 
Author Message
xelir13
PostPosted: Thu Jun 27, 2013 12:40 am    Post subject: Security Exit UserID/PWD passing issue Reply with quote

Novice

Joined: 03 Feb 2013
Posts: 14

HI All

We are currently implementing a security exit for our SVRCONN channels. This exit will authenticate to our LDAP(AD or UNIX). Our current implementation of the exit is working for only connections coming from MQ EXPLORER.

When we write a code to connect and pass the userID/PWD, the security exit is picking up the user account login on the client machine.

Here is a snippet on how we connect to MQ

Code:
MQCNO ConnectOptions = {MQCNO_DEFAULT};
MQCD ClientConn = {MQCD_CLIENT_CONN_DEFAULT};
MQCSP mqCSP = {MQCSP_DEFAULT};
MQHCONN HConn;
MQLONG CompCode;
MQLONG Reason;
char QMName[MQ_Q_MGR_NAME_LENGTH+1]="QMGRNAME";
char channelName[MQ_CHANNEL_NAME_LENGTH+1]="MY_CHANNEL";
char hostname[1024]="MQSERVER(PORT)";
char UserId[32+1]="MyID";
char Password[32+1]="MyPWD";
strncpy(ClientConn.ConnectionName,
 hostname, MQ_CONN_NAME_LENGTH);
strncpy(ClientConn.ChannelName,
 channelName, MQ_CHANNEL_NAME_LENGTH);
mqCSP.AuthenticationType = MQCSP_AUTH_USER_ID_AND_PWD;
mqCSP.Version = MQCSP_VERSION_1;
mqCSP.CSPUserIdPtr = &UserId;
mqCSP.CSPUserIdOffset = 0;
mqCSP.CSPUserIdLength = strlen(UserId);
mqCSP.CSPPasswordPtr = &Password;
mqCSP.CSPPasswordOffset = 0;
mqCSP.CSPPasswordLength = strlen(Password);
ConnectOptions.SecurityParmsPtr = &mqCSP;
ConnectOptions.SecurityParmsOffset = 0;
ConnectOptions.ClientConnPtr = &ClientConn;
ConnectOptions.Version = MQCNO_VERSION_5;
MQCONNX (QMName,
&ConnectOptions,
&HConn,
&CompCode,
&Reason);


Then we use this code to retrieve the userID/PWD on the security exit.
Code:
                memset (User, 0, pChDef->LongRemoteUserIdLength);
                memset (Pass, 0, MQ_PASSWORD_LENGTH);
                MakeCString(User,pChDef->LongRemoteUserIdPtr,pChDef->LongRemoteUserIdLength);
                MakeCString(Pass,pChDef->RemotePassword,MQ_PASSWORD_LENGTH);                 


MQ Server->7.1.0.2
Back to top
View user's profile Send private message
hughson
PostPosted: Thu Jun 27, 2013 12:48 am    Post subject: Reply with quote

Padawan

Joined: 09 May 2013
Posts: 1916
Location: Bay of Plenty, New Zealand

I'm not sure what your question is exactly, but I am curious that in the application at one end you are filling in and passing an MQCSP structure, but then at the security exit at the other end you are not retrieving the user ID and password from the MQCSP structure?

The information from the MQCSP is provided to a security exit with Exit Reason MQXR_SEC_PARMS and the MQCSP structure is hung off the MQCXP on the field called SecurityParms (which has a type PMQCSP).

Cheers
Morag
_________________
Morag Hughson @MoragHughson
IBM MQ Technical Education Specialist
Get your IBM MQ training here!
MQGem Software
Back to top
View user's profile Send private message Visit poster's website
xelir13
PostPosted: Thu Jun 27, 2013 1:06 am    Post subject: Reply with quote

Novice

Joined: 03 Feb 2013
Posts: 14

My question is, what parameter should I set on the security exit to pickup the UserID/PWD that is being passed via MQCONNX.

At first I was on the assumption that the LongRemoteUserIdPtr and RemotePassword are the correct parameters since by using MQ EXPLORER this parameters pickup the correct values.
Back to top
View user's profile Send private message
hughson
PostPosted: Thu Jun 27, 2013 1:30 am    Post subject: Reply with quote

Padawan

Joined: 09 May 2013
Posts: 1916
Location: Bay of Plenty, New Zealand

xelir13 wrote:
My question is, what parameter should I set on the security exit to pickup the UserID/PWD that is being passed via MQCONNX.

As I said above, your just need to write different code in your security exit to pick up the MQCSP user ID/PWD from the MQCSP structure.

Your security exit is probably also not looking for the correct Exit Reason? What Exit Reason are you driving your security exit in? MQXR_???

Cheers
Morag
_________________
Morag Hughson @MoragHughson
IBM MQ Technical Education Specialist
Get your IBM MQ training here!
MQGem Software
Back to top
View user's profile Send private message Visit poster's website
hughson
PostPosted: Thu Jun 27, 2013 1:33 am    Post subject: Reply with quote

Padawan

Joined: 09 May 2013
Posts: 1916
Location: Bay of Plenty, New Zealand

xelir13 wrote:
At first I was on the assumption that the LongRemoteUserIdPtr and RemotePassword are the correct parameters since by using MQ EXPLORER this parameters pickup the correct values.

MQ Explorer does not use MQCSP to provide it's User ID and PWD so it is not a good test of whether your security exit is correct for applications that do use MQCSP.

Cheers
Morag
_________________
Morag Hughson @MoragHughson
IBM MQ Technical Education Specialist
Get your IBM MQ training here!
MQGem Software
Back to top
View user's profile Send private message Visit poster's website
xelir13
PostPosted: Thu Jun 27, 2013 1:45 am    Post subject: Reply with quote

Novice

Joined: 03 Feb 2013
Posts: 14

How does MQExplorer provide its userID/PWD?

Is it possible to apply the way MQExplorer sends credentials on a client application?
Back to top
View user's profile Send private message
hughson
PostPosted: Thu Jun 27, 2013 2:00 am    Post subject: Reply with quote

Padawan

Joined: 09 May 2013
Posts: 1916
Location: Bay of Plenty, New Zealand

xelir13 wrote:
How does MQExplorer provide its userID/PWD?

Is it possible to apply the way MQExplorer sends credentials on a client application?

I would advise continuing the way you are doing it - using MQCSP. This is the architected way to pass user ID and Password which wasn't available initially when MQ Explorer was written but is now the advised way to do it if you are starting a-new.

Cheers
Morag
_________________
Morag Hughson @MoragHughson
IBM MQ Technical Education Specialist
Get your IBM MQ training here!
MQGem Software
Back to top
View user's profile Send private message Visit poster's website
xelir13
PostPosted: Thu Jun 27, 2013 2:08 am    Post subject: Reply with quote

Novice

Joined: 03 Feb 2013
Posts: 14

Thanks for the advice. Guess I need to find out how does the UserID/Pass is received by the security Exit.
Back to top
View user's profile Send private message
hughson
PostPosted: Thu Jun 27, 2013 2:12 am    Post subject: Reply with quote

Padawan

Joined: 09 May 2013
Posts: 1916
Location: Bay of Plenty, New Zealand

xelir13 wrote:
Guess I need to find out how does the UserID/Pass is received by the security Exit.

My earlier responses were trying to explain that to you.

Catch MQXR_SEC_PARMS as the Exit Reason and look in the MQCXP->SecurityParms field which is the MQCSP.

If you do not understand any of these words, please do ask.

Cheers
Morag
_________________
Morag Hughson @MoragHughson
IBM MQ Technical Education Specialist
Get your IBM MQ training here!
MQGem Software
Back to top
View user's profile Send private message Visit poster's website
xelir13
PostPosted: Thu Jun 27, 2013 2:17 am    Post subject: Reply with quote

Novice

Joined: 03 Feb 2013
Posts: 14

could you explain it to me more clearer. Im still kinda new in exit creation
Back to top
View user's profile Send private message
hughson
PostPosted: Thu Jun 27, 2013 2:32 am    Post subject: Reply with quote

Padawan

Joined: 09 May 2013
Posts: 1916
Location: Bay of Plenty, New Zealand

One of the first things your exit should code is to inspect the provided value in a parameter called ExitReason. Do you have any code in your exit doing that? All the sample exits usually have a switch statement will all the various Exit Reasons and then insert code in the appropriate case. Perhaps you can paste some snippets of your exit doing this into your response here?

Cheers
Morag
_________________
Morag Hughson @MoragHughson
IBM MQ Technical Education Specialist
Get your IBM MQ training here!
MQGem Software
Back to top
View user's profile Send private message Visit poster's website
mqjeff
PostPosted: Thu Jun 27, 2013 2:34 am    Post subject: Reply with quote

Grand Master

Joined: 25 Jun 2008
Posts: 17447

Exits are an advanced topic.

I think the main point that Morag is making is that your exit needs to use the same MQCSP structure to read out the userid/password as your exit is using to populate the userid/password.

The process flow you're trying to build should look something like this
  • MQClient application does something to authenticate and validate the real user and determines the proper LDAP credentials.
  • The MQClient application creates an MQCSP structure, and populates the credentials into that MQCSP structure, and then passes it as part of the connect options to MQCONNX (your code already does this)
  • The exit can be invoked on the client side to extract the credentials from the MQCSP and validate them against the LDAP before allowing the connection to proceed
  • The exit will be invoked on the server side and will extract the credentials from the MQCSP and validates them against the LDAP, and can choose to remap those credentials to a known user on the host OS (identity mapping).


You can also consider having the exit do all of the work to populate the MQCSP on the client side. But you need to figure out how the exit will find out the right credentials to populate given the information it has available to it. If you can rely on the host OS to provide you an identity token for the user running the MQ client process, that's great. It may not always be possible for the host OS to do that.

Did I mention exits are an advanced topic?
Back to top
View user's profile Send private message
hughson
PostPosted: Thu Jun 27, 2013 2:50 am    Post subject: Reply with quote

Padawan

Joined: 09 May 2013
Posts: 1916
Location: Bay of Plenty, New Zealand

mqjeff wrote:
I think the main point that Morag is making is that your exit needs to use the same MQCSP structure to read out the userid/password as your exit is using to populate the userid/password.

I don't think he is using an exit to populate the MQCSP on the application side. From the code snippet provided in the first post, the application is coding the MQCSP on the MQCONNX which is perfect.

He only needs to write the exit now on the server-conn side, to pull out the user ID and pwd from the MQCSP passed to the exit.

Cheers
Morag
_________________
Morag Hughson @MoragHughson
IBM MQ Technical Education Specialist
Get your IBM MQ training here!
MQGem Software
Back to top
View user's profile Send private message Visit poster's website
xelir13
PostPosted: Thu Jun 27, 2013 2:59 am    Post subject: Reply with quote

Novice

Joined: 03 Feb 2013
Posts: 14

@hughson
I do have a check for the ExitReason, although you mentioned that I need to catch MQXR_SEC_PARMS. On my current code, when it assigns the userID/Pwd the ExitReason that is catch is MQXR_INIT_SEC.


@mqjeff
Yes, Im aware that this is an advance topic already. I currently need to fix the our current security exit which was created by an old employee. Im just in a deadline that's why Im currently trying to rush studying security exits.

Here is a code snippet from the exit.

Code:
// EXIT Entry points
void MQENTRY MQStart(void) {;}
void MQENTRY MQAuthLdap(  PMQVOID channelExitParms,
                          PMQVOID channelDef,
                          PMQLONG pDataLength,
                          PMQLONG pAgentBufferLength,
                          PMQVOID pAgentBuffer,
                          PMQLONG pExitBufferLength,
                          PMQPTR  pExitBufferAddr )
{

    PMQCXP          pChlExParms    = ( PMQCXP ) channelExitParms;
    PMQCD             pChDef       = ( PMQCD ) channelDef;
   

   
    if ( firstTime  )
    {
        pLdapProperties = (pLDAP_PROPERTIES) malloc (LDAP_PROPERTIES_SIZE+1);
        PROP_READ_OK = GetProperties(pChDef,pLdapProperties); // Read the property file

        firstTime = 0;
    }
       
    switch ( pChlExParms->ExitId )
    {
      case MQXT_CHANNEL_SEC_EXIT:
        WriteLogFile( pLdapProperties,600,'D', ">>>>> MQAuthLdap exit started\n");
        break;
      default:
        WriteLogFile( pLdapProperties,610, 'E', "ERROR: Connection refused, unsupported ExitId = %i\n",pChlExParms->ExitId );
        pChlExParms->ExitResponse = MQXCC_SUPPRESS_FUNCTION;    // Return a failure
        break;
      }

    switch ( pChlExParms->ExitReason )
    {
        case MQXR_INIT:
       
          WriteLogFile( pLdapProperties,620, 'D', "ExitReason = MQXR_INIT\n");

          break;
         
        case MQXR_SEC_PARMS:
       
          WriteLogFile( pLdapProperties,630, 'D', "ExitReason = MQXR_SEC_PARMS\n" );
          break;
         
        case MQXR_TERM:
           
          WriteLogFile( pLdapProperties,640, 'D', "ExitReason = MQXR_TERM\n" );
          WriteLogFile( pLdapProperties,641, 'I', "ENDED: Channel %s, ConnectionName = %s(%s)\n", pLdapProperties->ChannelName, pLdapProperties->ConnectionHostName, pLdapProperties->ConnectionName );

          break;
         
        case MQXR_SEC_MSG:
       
           WriteLogFile( pLdapProperties,650, 'D', "ExitReason = MQXR_SEC_MSG\n" );
           break;
           
        case MQXR_RETRY:
           
           WriteLogFile( pLdapProperties,660, 'D', "ExitReason = MQXR_RETRY\n" );
           break;
           
        case MQXR_INIT_SEC:
       
          WriteLogFile( pLdapProperties,670, 'D', "ExitReason = MQXR_INIT_SEC\n" );
         
          switch ( pChDef->ChannelType )
          {
         
            case MQCHT_SVRCONN:
               
                PROP_READ_OK = GetProperties(pChDef,pLdapProperties); // Read the property file
                WriteLogFile( pLdapProperties,680, 'D', "Channel type = MQCHT_SVRCONN\n" );       
                memset (User, 0, pChDef->LongRemoteUserIdLength);
                memset (Pass, 0, MQ_PASSWORD_LENGTH);
                MakeCString(User,pChDef->LongRemoteUserIdPtr,pChDef->LongRemoteUserIdLength);
                MakeCString(Pass,pChDef->RemotePassword,MQ_PASSWORD_LENGTH);                 
                WriteLogFile( pLdapProperties,690, 'D', "RemoteUserIdentifier = %s\n",User );
                WriteLogFile( pLdapProperties,691, 'D', "RemotePassword = ...\n" );
                WriteLogFile( pLdapProperties,692, 'D', "ConnectionName = %s(%s)\n",pLdapProperties->ConnectionHostName, pLdapProperties->ConnectionName );
                //WriteLogFile( pLdapProperties,611, 'D', "RemotePassword = %s\n",Pass );   
                               
                // Authenticate user on LDAP
                if ( ! LdapAuthenticateUser(User,Pass,pLdapProperties) ) {
                    //WriteLogFile( pLdapProperties,700, 'E', "ERROR: Connection refused, user authentication failed\n");
                    WriteLogFile( pLdapProperties,700, 'E', "ERROR: Connection refused, user authentication failed on Channel %s, %s@%s(%s)\n",pLdapProperties->ChannelName, User, pLdapProperties->ConnectionHostName, pLdapProperties->ConnectionName);
                    pChlExParms->ExitResponse = MQXCC_SUPPRESS_FUNCTION;    // Return a failure
                    WriteLogFile( pLdapProperties,701, 'D', "return(MQXCC_SUPPRESS_FUNCTION)\n" );
                    break;
                }else{
                    //Set the SVRCONN MCAUserIdentifier to the user trying to connect if the channel MCAUser property is blank                   
                    if( strlen (pChDef->MCAUserIdentifier) == 0 )
                    { 
                      strncpy (pChDef->MCAUserIdentifier, User, sizeof(User));
                    }                                 
                    //Print to std out, usually the MQ listener log
                    if(CheckIPAdress(pChDef,pLdapProperties))
                    {
                      MakeCString (ChlMCAUser, pChDef->MCAUserIdentifier, sizeof (pChDef->MCAUserIdentifier));
                      WriteLogFile( pLdapProperties,710, 'I', "STARTED: Channel %s, ConnectionName = %s(%s), started by = %s, MCAUSER = %s\n",pLdapProperties->ChannelName, pLdapProperties->ConnectionHostName, pLdapProperties->ConnectionName, User, ChlMCAUser );                       
                      break;
                    }
                    else
                    {
                      WriteLogFile( pLdapProperties,700, 'E', "ERROR: Connection refused, bad client IP address for Channel %s, %s(%s)\n",pLdapProperties->ChannelName, pLdapProperties->ConnectionHostName, pLdapProperties->ConnectionName);
                      WriteLogFile( pLdapProperties,701, 'D', "return(MQXCC_SUPPRESS_FUNCTION)\n" );
                      pChlExParms->ExitResponse = MQXCC_SUPPRESS_FUNCTION;    // Return a failure
                      break;                 
                    }
                }
                   
          break;
          
            default:
             WriteLogFile( pLdapProperties,720, 'E', "ERROR: Connection refused, unsupported Channel type = %i\n",pChDef->ChannelType );
             pChlExParms->ExitResponse = MQXCC_SUPPRESS_FUNCTION;    // Return a failure
             break;
             
          } /* endswitch ChannelType in MQXR_INIT_SEC */     

          break;
                 
        default:
       
           WriteLogFile( pLdapProperties,730, 'E', "ERROR: Connection refused, unknown Exit Reason code in channel security exit call = %i\n", pChlExParms->ExitReason);
           pChlExParms->ExitResponse = MQXCC_SUPPRESS_FUNCTION;    // Return a failure
           break;
    }
    return;
}


Hope you guys could help
Back to top
View user's profile Send private message
hughson
PostPosted: Thu Jun 27, 2013 3:05 am    Post subject: Reply with quote

Padawan

Joined: 09 May 2013
Posts: 1916
Location: Bay of Plenty, New Zealand

xelir13 wrote:
@hughson
I do have a check for the ExitReason, although you mentioned that I need to catch MQXR_SEC_PARMS. On my current code, when it assigns the userID/Pwd the ExitReason that is catch is MQXR_INIT_SEC.

So you need to move that code into the case statement (which is already there) for MQXR_SEC_PARMS instead. Perhaps if you first wrapped the code that is working with the user ID and password into a function, it would make it clearer when you call it from the appropriate place. If that function took two parameters, one for user ID and one for password, then it would also be much simpler for me to guide you into what those parameters are to be.

Cheers
Morag
_________________
Morag Hughson @MoragHughson
IBM MQ Technical Education Specialist
Get your IBM MQ training here!
MQGem Software
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic  Reply to topic Goto page 1, 2  Next Page 1 of 2

MQSeries.net Forum Index » IBM MQ Security » Security Exit UserID/PWD passing issue
Jump to:  



You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Protected by Anti-Spam ACP
 
 


Theme by Dustin Baccetti
Powered by phpBB © 2001, 2002 phpBB Group

Copyright © MQSeries.net. All rights reserved.