6 Replies Latest reply on Dec 19, 2013 5:39 PM by timothyt

    Validating Username and Password

    timothyt

      I would like to write scripts that interactively prompt the user for username and password and pass the same to ePO via the API when executing commands. Obviously, I would like to notify the user if the username and password combination they provided is invalid. It seems to me that when a valid set of credentials is provided, ePO commands via the API will provide positive feedback, such as an "OK:" message followed by other output; however, if the credentials are invalid, no output is produced. I don't want to assume that no output means that the credentials were invalid, as this could actually be caused by a number of different reasons.

       

      1. Is there a good way to validate credentials against ePO using the API? Can ePO produce output indicating that the credentials supplied are invalid?

        • 1. Re: Validating Username and Password
          cllapole

          Are you doing this with Python, cURL, or Powershell?  I just started learning a little Python last week and created a quick menu system to help with some ePolicy functions.  Here is the function I wrote for requesting username and password as well as my ePO connection function...

           

           

          def epoConnect():

                    global mc

                    global isConnected

                    print'\nA connection to the ePolicy server is required'

                    epoUsername = raw_input('Enter your ePolicy username: ')

                    epoPassword = getpass.getpass('Enter your password for ['+epoUsername+']: ')

                    print '\nAttempting connection to ePO Server.'

                    mc = mcafee.client(epoServerName, epoServerPort, epoUsername, epoPassword)

                    print 'Successfully connected to ['+epoServerName+']. \n'

                    isConnected = True

                    return;

           

           

          #Function to get AD credentials

          def getADcreds():

                    global ADusername

                    global ADpassword

                    global isADstored

           

                    print '\nIn order to convert the SAM Account Name to a Distingushed Name...'

                    ADusername = raw_input('Enter your Active Directory username: ')

                    ADpassword = getpass.getpass('Enter your password for ['+domainPrefix+ADusername+']: ')

                    ADusername = (domainPrefix+ADusername)

                    isADstored = True

                    return;

           

           

          Note the extra variables I used such as domainPrefix that will need defined.  Also, I keep a couple flags handy so my script doesn't repeatedly ask for credentials but instead stores them.  As for validation, right now I don't bother and just let the script bomb if it is invalid.  It is something I intend to add, but I don't exactly have a lot of free time.  In Python you want to use a try/except statement for validation.  Look at the following webpage to see how it works, and the last comment nicely explains how to figure out the exception that pops...

          http://www.pythonforbeginners.com/error-handling/python-try-and-except/

           

          If you want to see the rest of the script, send me an email (it is visible in my profile).  Again, I am by far not a programmer and just started learning a little tiny bit of Python, but sometimes a starting point can help others.

          • 2. Re: Validating Username and Password
            timothyt

            I am currently using curl for basic testing and intend to use curllib for production code.

             

            You have indicated "As for validation, right now I don't bother and just let the script bomb if it is invalid." Looking at your epoConnect() function, it seems to me that your "Successfully connected to..." message will be printed regardless if the connection attempt in the previous line fails. Will the mcafee.client() function throw an error code that specifically indicates that the credentials were invalid?

             

            Remember, I don't want to assume that a failed connection means that the credentials were invalid. My scripts will be included in a product sold to customers; and they must provide well-formatted, useful feedback. I don't want to show them a message indicating that their credentials were invalid if cause was actually a network issue, for example.

             

            Essentially, what I want to know is, "Is there some way to ask ePO, are these credentials valid?"

            • 3. Re: Validating Username and Password
              cllapole

              When using invalid credentials to attach to ePolicy I get a return of "mcafee.CommandInvokerError: The server myservername:myport could not fulfill the request. HTTP Error 401: Unauthorized".  I assume it is possible that there are conditions other than just invalid credentials that might get you the same return.  Of course, if you code to verify everything else first (ping to verify the ePolicy server is up, or does some port scanning on the server to make sure the correct ports are listening, etc.) you at some point can assume it is invalid credentials.  That is about as far as you can go, unless you are doing something like embedding a known user account (like admin) into the script, then making a connection using that account, then verifying the username exists, then disconnecting, and trying the username and password combination provided by the user (not that I would recommend any of that of course).  So if you verify the server is available, the port is available, and you watch for that error string I would say that would help you assume invalid credentials.

               

              I hope you have found the 'API explorer' program here in the communities, that seems to make things way quicker and easier to figure out what is or isn't possible through the Web API.  Any chance you might want to email me and give me some more info on what you are looking to build (and don't worry, I am no consultant or programmer, I wouldn't be looking to steal your ideas)? 

               

              Message was edited by: cllapole on 12/19/13 12:31:09 PM CST
              • 4. Re: Validating Username and Password
                cllapole

                Again, I am not sure this is exactly helpful, but I thought I would post it as an update to my original.  Again, I would do some other checks first (server status, port status, service is running, take your pick).  So if that all checks out, at the point the 401 error comes up, I myself will assume invalid credentials and just keep asking for them.  If you wanted the option to escape the loop, etc. that is obviously easily done.  But here is my rewrite so they script doesn't just bomb out for anyone else who finds this code snippet helpful (again, I am sure some of this code could be cleaner, but hey it works for me)...

                 

                #Function to make the ePolicy connection

                def epoConnect():

                          global mc

                          global isConnected

                          while isConnected != True:

                                    print'\nA connection to the ePolicy server is required'

                                    epoUsername = raw_input('Enter your ePolicy username: ')

                                    epoPassword = getpass.getpass('Enter your password for ['+epoUsername+']: ')

                                    print '\nAttempting connection to ePO Server.'

                                    try:

                                              mc = mcafee.client(epoServerName, epoServerPort, epoUsername, epoPassword)

                                              print 'Successfully connected to ['+epoServerName+']. \n'

                                              isConnected = True

                                    except Exception, e:

                                              e = sys.exc_info()[1]

                                              print e #Or print that the creds were invalid

                                              isConnected = False

                          return;

                 

                Message was edited by: cllapole on 12/19/13 1:14:53 PM CST
                • 5. Re: Validating Username and Password

                  Hi Timothy,

                   

                  The client uses BASIC authentication (http://en.wikipedia.org/wiki/Basic_access_authentication#cite_note-4) for communication with the ePO server.  When invalid credentials are submitted the server responds with a HTTP 401.    The mcafee.py script will wrap any HTTPError or URLError that gets thrown during a request and include that error text in the exception text (the details are in the get_response method of the _CommandInvoker object but that's more than you need to care about). For our purposes here and in python the HTTPError object is thrown and contains the following message:

                   

                  HTTP Error 401: Unauthorized

                   

                  This message is wrapped in a CommandInvokerError and then raised in the client.  If you catch the exception and look for that message, specifically up to the error code "HTTP Error 401" you can then determine that the user submitted invalid credentials.

                   

                  Here's a sample script that will print the text of any exceptions thrown by constructing a client instance and specifically look for invalid credentials and exit the script if it finds them.  This is just a sample to show you how you can deteremine when you've got invalid credentials; retry logic could be added if needed (as Chris is trying to demonstrate).

                   

                   

                   

                  import mcafee

                  import sys

                  import getpass

                   

                  if len(sys.argv) != 3:

                      print "Usage: %s %s %s" % (sys.argv[0], "<server>", "<port>")

                      exit(1)

                  server = sys.argv[1]

                  port = sys.argv[2]

                  usr = raw_input('Enter your ePolicy username: ')

                  pwd = getpass.getpass('Enter your password for ['+usr+']: ')

                  try:

                      mc = mcafee.client(server,port,usr,pwd)

                  except Exception, e:

                      print str(e) #Don't need this line; it's just to show what error messages look like

                      if "HTTP Error 401" in str(e):

                          print "Invalid credentials"

                          exit(1)

                      else:

                          #non HTTP 401 error (e.g. wrong port, etc)

                          raise e

                  print "Valid credentials. Run a command to verify..."

                  print mc.core.help("core.listUsers")

                   

                   

                   

                   

                  You invoke it by passing the server name and the port number.  Here's invoking it with valid credentials:

                  C:\pyclient\Python26>python promptforcreds.py myeposerver 16443

                  Enter your ePolicy username: gooduser

                  Enter your password for [gooduser]:

                  Valid credentials. Run a command to verify...

                  core.listUsers [permSetName]

                  List users in the system optionally filtered by permission set name or id.

                  Returns the list of users or throws on error.

                  Requires global administrator privilege.

                  Parameters:

                  [permSetName (param 1) | permSetId] - Either the unique id or name of the

                  permission set

                   

                  C:\pyclient\Python26>

                   

                  Invoking it with invalid credentials:

                   

                  C:\pyclient\Python26>python promptforcreds.py myeposerver 16443

                  Enter your ePolicy username: invaliduser

                  Enter your password for [invaliduser]:

                  The server myeposerver:16443 could not fulfill the request. HTTP Error 401: Unauth

                  orized

                  Invalid credentials

                   

                  C:\pyclient\Python26>

                   

                  Invoking with an unknown server name:

                   

                  C:\pyclient\Python26>python promptforcreds.py unknownserver 16443

                  Enter your ePolicy username: gooduser

                  Enter your password for [gooduser]:

                  Failed to reach the server unknownserver:16443. Error/reason: <urlopen error [Er

                  rno 11004] getaddrinfo failed>

                  Traceback (most recent call last):

                    File "promptforcreds.py", line 21, in <module>

                      raise e

                  mcafee.CommandInvokerError: Failed to reach the server unknownserver:16443. Erro

                  r/reason: <urlopen error [Errno 11004] getaddrinfo failed>

                  C:\pyclient\Python26>

                   

                  Invoking with an invalid port number:

                   

                  C:\pyclient\Python26>python promptforcreds.py myeposerver 10

                  Enter your ePolicy username: gooduser

                  Enter your password for [gooduser]:

                  Failed to reach the server myeposerver:10. Error/reason: <urlopen error [Errno 100

                  61] No connection could be made because the target machine actively refused it>

                  Traceback (most recent call last):

                    File "promptforcreds.py", line 21, in <module>

                      raise e

                  mcafee.CommandInvokerError: Failed to reach the server myeposerver:10. Error/reaso

                  n: <urlopen error [Errno 10061] No connection could be made because the target m

                  achine actively refused it>

                   

                  C:\pyclient\Python26>

                   

                  I hope that helps!

                  -Jeremy

                   

                  Message was edited by: jbrooks2 on 12/19/13 5:37:40 PM CST
                  • 6. Re: Validating Username and Password
                    timothyt

                    Thank you Jeremy. That answers my question.