The Community Forums

Interact with an entire community of cPanel & WHM users!
  1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Receiving 403 when posting to /xml-api/listacct

Discussion in 'cPanel Developers' started by cpuden, Jun 9, 2011.

  1. cpuden

    cpuden Member

    Joined:
    Jun 9, 2011
    Messages:
    9
    Likes Received:
    0
    Trophy Points:
    1
    Hi,

    I am trying to post to /xml-api/listacct? but it keep receiving an http 403 and I am never presented with a 401. Also, what are the differences between 2082/2083 and 2086/2087 I see among the pairs themselves the lower numbered one is non-ssl, but between the two groups I don't know the difference. Here is my code in Python:

    I am trying to post some data to a form using urllib2, but instead of
    being presented with a 401 and then sending my credentials I am
    constantly being present with an HTTP 403.

    For some reason doesn't seem like the auth header is even being sent
    and the user-agent header is sent after connection-close http
    header...

    >>> print platform.python_version()
    2.6.5

    Here is what happens according to python (also corroborated on the
    server side as well, just incase). I'm also not sure the header
    order is exactly a problem, but I'm 95% sure.


    Sample run:

    $ ./cptest


    send: 'POST /xml-api/listaccts? HTTP/1.1\r\nAccept-Encoding:
    identity\r\nContent-Length: 13\r\nHost:
    servername:2082\r\nContent-Type:
    application/x-www-form-urlencoded\r\nConnection: close\r\nUser-Agent:
    Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv,1.9.2.13)
    Gecko/20101203 Firefox/3.6.13\r\n\r\n'
    send: 'domain=anjopa'
    reply: 'HTTP/1.1 403 Forbidden\r\n'
    header: Connection: close
    header: Server: cpsrvd/11.30.0.27
    header: Content-type: text/xml
    Traceback (most recent call last):
    File "./cptest", line 61, in <module>
    queryCpanel()
    File "./cptest", line 55, in queryCpanel
    response = opener.open(url, paramaters)
    File "/usr/lib/python2.6/urllib2.py", line 397, in open
    response = meth(req, response)
    File "/usr/lib/python2.6/urllib2.py", line 510, in http_response
    'http', request, response, code, msg, hdrs)
    File "/usr/lib/python2.6/urllib2.py", line 435, in error
    return self._call_chain(*args)
    File "/usr/lib/python2.6/urllib2.py", line 369, in _call_chain
    result = func(*args)
    File "/usr/lib/python2.6/urllib2.py", line 518, in http_error_default
    raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
    urllib2.HTTPError: HTTP Error 403: Forbidden



    #!/usr/bin/python
    import sys
    from xml.dom.minidom import parse, parseString
    import urllib
    import urllib2
    import base64
    from cookielib import CookieJar

    # Turn on HTTP debugging
    11.5. Setting the User-Agent
    import httplib
    httplib.HTTPConnection.debuglevel = 1
    #this doesn't seem to work

    url = 'http://servername/:2086/xml-api/listaccts?'

    #
    # username = username'
    # password = 'pass'
    #
    paramaters = urllib.urlencode(dict(domain='anjopa'))


    def query():


    # Instantiate and Initialize AuthInfo Handler for use w/ the build_opener

    authinfo = urllib2.HTTPBasicAuthHandler()
    authinfo.add_password(realm="Web Host Manager",
    uri="https://servername:2086/xml-api/listacct?",
    user="user",
    passwd="pass")

    # Instantiate Cookie jar Handler for use w/ build_opener

    cj = CookieJar()



    # Create an opener object from list of handlers above

    opener = urllib2.build_opener(authinfo,urllib2.HTTPCookieProcessor(cj),
    urllib2.HTTPHandler(debuglevel=1))


    # Add headers here:`
    opener.addheaders = [('User-Agent', 'Mozilla/5.0 (Windows; U;
    Windows NT 6.1; en-US; rv,1.9.2.13) Gecko/20101203 Firefox/3.6.13')]


    #probably un-necessary, but supposedly this makes the url open use
    the above handlers by default in our program
    urllib2.install_opener(opener)

    # The data is actually sent at this line
    # The presence of the paramaters argument signals urlopen to do a
    POST instead of a GET
    response = opener.open(url, paramaters)



    if __name__ == '__main__':
    #main()
    query()




    Anyone know where I can with this one?

    Thanks,

    Dennis O.
     
  2. MattDees

    MattDees cPanel Product Owner
    Staff Member

    Joined:
    Apr 29, 2005
    Messages:
    417
    Likes Received:
    1
    Trophy Points:
    18
    Location:
    Houston, TX
    cPanel Access Level:
    Root Administrator
    Not sure what the problem with what you are doing is, but here's how I handle requests in python:

    Code:
    import urllib2, base64
    user = 'root'
    password = 'somepass'
    req = urllib2.Request('https://localhost:2087/xml-api/listaccts', {}, {'Authorization':'Basic ' + base64.b64encode( user + ':' + password ) } )
    res =  urllib2.urlopen(req)
    print res.read()
    
    Of course you may want to add a few things into this for production use, such as putting the urlopen() call into a try-catch, etc.
     
  3. cpuden

    cpuden Member

    Joined:
    Jun 9, 2011
    Messages:
    9
    Likes Received:
    0
    Trophy Points:
    1
     
  4. cpuden

    cpuden Member

    Joined:
    Jun 9, 2011
    Messages:
    9
    Likes Received:
    0
    Trophy Points:
    1
    Hi Matt/Anyone else,

    (before you read into my text, I wanted to ask ask a quick follow up, how can limit my output to just a domain or a user, ip, etc? I thought I could just past it as parameters in my post but that doesn't seem to be working, like domain=sample should match all domains that have sample in them, no?)

    Thank you! This works perfectly. I don't understand what the difference between the open_builder and request objects are. It almost seems as if I can use a request object in a build_opener function, but I am not sure how.

    I think the crux of the problem with my last piece of code is I think it's not sending it because it wasn't first presented with a 401, so I don't think order of the headers really mattered. Some applications send anonymous application and then when presented with a 401 they will send the authorization header, but the cpanel when you don't send the authorization header it send a 403 (Forbidden). The odd thing is your piece of code works perfectly, because you added the headers manually.

    If I add this to my opener it works as well:
    opener.addheaders = [('Authorization: Basic', base64.b64encode( username + ':' + password )) ]


    Thank you for your awesome help!
     
  5. MattDees

    MattDees cPanel Product Owner
    Staff Member

    Joined:
    Apr 29, 2005
    Messages:
    417
    Likes Received:
    1
    Trophy Points:
    18
    Location:
    Houston, TX
    cPanel Access Level:
    Root Administrator
    The ability to filter these by different criteria is handled by the searchtype & search parameters (see ListAccounts < SoftwareDevelopmentKit < TWiki for more info)

    f.ex to search by ip, you would pass in:

    searchname=ip&search=127.0.0.1
     
  6. Saytik

    Saytik Member

    Joined:
    Jul 2, 2011
    Messages:
    15
    Likes Received:
    0
    Trophy Points:
    1
    Hello Matt, Thank you for your script example!

    Could you help me with script on python to use Access hash authentication (ApiAuthentication < SoftwareDevelopmentKit < TWiki). Cpanel recommends to use hash authentication.

    Thank you, waiting for your help.

    (also, post your examples to ApiAuthentication page on cpanel site)
     
  7. Saytik

    Saytik Member

    Joined:
    Jul 2, 2011
    Messages:
    15
    Likes Received:
    0
    Trophy Points:
    1
    I have already found a way to authenticate with Cpanel remote access key.
    Both examples (with login\pass and with Cpanel hash) I have posted on my blog

    Thank you!
     
  8. MattDees

    MattDees cPanel Product Owner
    Staff Member

    Joined:
    Apr 29, 2005
    Messages:
    417
    Likes Received:
    1
    Trophy Points:
    18
    Location:
    Houston, TX
    cPanel Access Level:
    Root Administrator
    Very nice, thanks for sharing.

    One of these days I'll find the time to implement PublicAPI in python.
     

Share This Page