dalgibbard / citrix_xenserver_patcher

Auto / Manual Patching tool for Citrix XenServer Boxes
Do What The F*ck You Want To Public License
142 stars 45 forks source link

XS65ESP1046.zip first file with citrix authentication? #60

Closed vmpr closed 7 years ago

vmpr commented 7 years ago

hi,

now we have the problem, that citrix built an authentication part, before you can download the files. is it possible to handle this? we can use our own credentials, maybe saved in a file or with parameters, or maybe you can create a user + pw for all and hard code it into the script?

Today i got this output:

Detected XenServer Version: 6.5.0

The following Patches are pending installation:

uuid: a2884e0b-ce29-4b9a-8ff5-419a867ee9d2 url: https://support.citrix.com/article/CTX219499 timestamp: 2016-12-21T00:00:00Z name_label: XS65ESP1046 patch_url: https://support.citrix.com/supportkc/filedownload?uri=/filedownload/CTX219499/XS65ESP1046.zip after_apply_guidance: restartHost name_description: Public Availability: Security fixes to Xen

Downloading: XS65ESP1046.zip Download Size: 6162 Bytes Applying: XS65ESP1046 Uncompressing... Error extracting compressed patchfile: XS65ESP1046.zip Failed to locate unzipped patchfile: XS65ESP1046.xsupdate

bkci commented 7 years ago

I can confirm this issue. Going directly to the download url presents a login screen. This is the first download that requires a Citrix account.

The redirect URL that is presented for Login is: https://www.citrix.com/login?url=https://support.citrix.com/article/CTX219499?download

If you are already authenticated on the site, there is no redirect.

bkci commented 7 years ago

Here is test code that authenticates. It ends up doing multiple. There is probably a cleaner way, but I will work on a patch.

import sys, re, subprocess, os, getopt, time, pprint, signal, base64, urllib2, cookielib, urllib

def download_patch(download, patch_url, error_url): cj = cookielib.CookieJar() opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))

opener.addheaders = [("User-agent", "XenTesting")]

urllib2.install_opener(opener)

url = patch_url
file_name = url.split("/")[-1]
authentication_url = "https://identity.citrix.com/Utility/STS/Sign-In"

payload = {
  "returnURL": download,
  "errorURL": error_url,
  "persistent": "1",
  "userName": "<user>",
  "password": "<pass>"
  }

data = urllib.urlencode(payload)

req = urllib2.Request(authentication_url, data)

print("")
print("Downloading: " + str(file_name))
try:
    u = urllib2.urlopen(req)
contents = u.read()
    u = urllib2.urlopen(url)
except Exception, err:
    print("...ERR: Failed to Download Patch!")
    print("Error: " + str(err))
    sys.exit(3)

try:
    f = open(file_name, "wb")
except IOError:
    print("Failed to open/write to " + file_name)
    sys.exit(2)

meta = u.info()
try:
    file_size = int(meta.getheaders("Content-Length")[0])
    size_ok = True
except IndexError, err:
    print("...WARN: Failed to get download size from: %s" % patch_url)
    print("         Will attempt to continue download, with unknown file size")
    time.sleep(4)
###############
    size_ok = False

s = os.statvfs(".")
freebytes = s.f_bsize * s.f_bavail
if size_ok == False:
    doublesize = 2048
    file_size = 1
else:
    doublesize = file_size * 2
if long(doublesize) > long(freebytes):
    print(str("Insufficient storage space for Patch ") + str(file_name))
    print(str("Please free up some space, and run the patcher again."))
    print("")
    print(str("Minimum space required: ") + str(doublesize))
    sys.exit(20)

print "Download Size: %s Bytes" % (file_size)

file_size_dl = 0
block_sz = 8192
while True:
    buffer = u.read(block_sz)
    if not buffer:
        break
    file_size_dl += len(buffer)
    f.write(buffer)
    if size_ok == False:
         status = r"%10d" % (file_size_dl)
    else:
         status = r"%10d  [%3.2f%%]" % (file_size_dl, file_size_dl * 100. / file_size)
    status = status + chr(8)*(len(status)+1)
    print status,
f.close()
if not os.path.isfile(file_name):
    print("\nERROR: File download for " + str(file_name) + " unsuccessful.")
    sys.exit(15)
return file_name

patch_url = "https://support.citrix.com/supportkc/filedownload?uri=/filedownload/CTX219499/XS65ESP1046.zip" download_url = "https://www.citrix.com/login/bridge?url=https://support.citrix.com/article/CTX219499" err_url="https://www.citrix.com/login?url=https://support.citrix.com/article/CTX219499" download_patch(download_url, patch_url, err_url)

bkci commented 7 years ago

Attached is a patch against current master. I have a fork as well, will apply there when I have more time.

There are two user variables that can be set for permanent use: cuser => citrix account username cpass => citrix account password

These can also be set from command line options: -U => Citrix account username -P => Citrix account password

I have done some minimal testing, please ensure this works correctly on your system in a non-production capacity first!

patcher.py.patch.txt

dalgibbard commented 7 years ago

Closed by #61

vmpr commented 7 years ago

thank u very much guys, nice job!