[cisco-voip] CUCM Bulk TFTP File Upload

Anthony Holloway avholloway+cisco-voip at gmail.com
Sat Jun 2 15:19:21 EDT 2018


Here's your code re-worked a little Brian, for you or for anyone else, and
I tested it on 11.5 and it works.  I did not put in any error handling, so
I'll leave that up to you.  You can do things like Try/Catch or checking
for resp.status_code == 200, file existence checking, etc.  I figure,
knowing how to make it work was the challenge, not error handling, so I
left that out.

# Install Python 2.7 and choose the option to add to path (off by default)
# Then install two modules
#  C:\>pip install requests
#  C:\>pip install BeautifulSoup
# Then run the program
#  C:\>python tftp.py

import requests
from BeautifulSoup import BeautifulSoup
requests.packages.urllib3.disable_warnings()

tftp_host = ""
tftp_user = ""
tftp_pass = ""
tftp_file = ""
tftp_path = ""

url_base = "https://{}/cmplatform/".format(tftp_host)
url_login = "{}j_security_check".format(url_base)
url_upload = "{}tftpFileUpload.do".format(url_base)

# Allows us to keep track of our login session
print "\nLogging in to {}...".format(tftp_host),
connection = requests.Session()

# Start a new session by simply access a page on the server
resp = connection.get(url_base, verify = False)

# Our login form data
form_data = {
"appNav": "cmplatform",
"j_username": tftp_user,
"j_password": tftp_pass
}

# Our login submission to the server
resp = connection.post(url_login, verify = False, data = form_data)
print "Success!\n"

# We need to grab the token the server gives us, so we can pass it back
upon upload
print "Grabbing a new token...",
soup = BeautifulSoup(connection.get(url_upload, verify = False).content)

# It's a hidden input element on the upload form with the name of "token"
token = soup.find("input", {"name": "token"}).get("value")
print "Found! [{}]\n".format(token)

# Our upload form submission data
payload = {
"struts.token.name": (None, "token"),
"token": (None, token),
"file": (tftp_file, open(tftp_file, "rb"), {"Content-Type": "text/plain"}),
"directory": (None, tftp_path)
}

# Our upload submission to the server
print "Uploading file: {}...".format(tftp_file),
resp = connection.post(url_upload, verify = False, files = payload)
print "Success!\n"

print "Done!"

If you want multiple server/multiple file support, it's really just a small
modification (highlighted in red):

# Install Python 2.7 and choose the option to add to path (off by default)
# Then install two modules
#  C:\>pip install requests
#  C:\>pip install BeautifulSoup
# Then run the program
#  C:\>python tftp.py

import requests
from BeautifulSoup import BeautifulSoup
requests.packages.urllib3.disable_warnings()

tftp_hosts = [
"host1",
"hostN"
]
tftp_user = ""
tftp_pass = ""

tftp_files = [
"file1",
"fileN"
]
tftp_path = ""

for tftp_host in tftp_hosts:

url_base = "https://{}/cmplatform/".format(tftp_host)
url_login = "{}j_security_check".format(url_base)
url_upload = "{}tftpFileUpload.do".format(url_base)

# Allows us to keep track of our login session
print "\nLogging in to {}...".format(tftp_host),
connection = requests.Session()

# Start a new session by simply access a page on the server
resp = connection.get(url_base, verify = False)

# Our login form data
form_data = {
"appNav": "cmplatform",
"j_username": tftp_user,
"j_password": tftp_pass
}

# Our login submission to the server
resp = connection.post(url_login, verify = False, data = form_data)
print "Success!\n"
for tftp_file in tftp_files:

# We need to grab the token the server gives us, so we can pass it back
upon upload
print "Grabbing a new token...",
soup = BeautifulSoup(connection.get(url_upload, verify = False).content)

# It's a hidden input element on the upload form with the name of "token"
token = soup.find("input", {"name": "token"}).get("value")
print "Found! [{}]\n".format(token)

# Our upload form submission data
payload = {
"struts.token.name": (None, "token"),
"token": (None, token),
"file": (tftp_file, open(tftp_file, "rb"), {"Content-Type": "text/plain"}),
"directory": (None, tftp_path)
}

# Our upload submission to the server
print "Uploading file: {}...".format(tftp_file),
resp = connection.post(url_upload, verify = False, files = payload)
print "Success!\n"

print "Done!"

On Fri, Jun 1, 2018 at 3:38 PM Brian Meade <bmeade90 at vt.edu> wrote:

> So just re-read through everything and sure enough I was sending to the
> wrong IP when running the script.  No wonder it's shown as uploading
> successfully the entire time.
>
> Thanks for you and Stephen's assistance!
>
> Tommy, BTW you can remove a lot of the manual set headers if you want to
> clean yours up.  It seems to work without them.
>
> Thanks,
> Brian Meade
>
> On Fri, Jun 1, 2018 at 4:10 PM, Schlotterer, Tommy <
> tschlotterer at presidio.com> wrote:
>
>> Just tested on CUCM 11.5, worked just fine.
>>
>>
>>
>> Thanks
>>
>>
>> Tommy
>>
>>
>>
>> *From:* bmeade90 at gmail.com [mailto:bmeade90 at gmail.com] *On Behalf Of *Brian
>> Meade
>> *Sent:* Friday, June 1, 2018 4:06 PM
>> *To:* Schlotterer, Tommy <tschlotterer at presidio.com>
>> *Cc:* cisco-voip voyp list <cisco-voip at puck.nether.net>
>> *Subject:* Re: [cisco-voip] CUCM Bulk TFTP File Upload
>>
>>
>>
>> *EXTERNAL EMAIL*
>>
>>
>>
>>
>>
>> Thanks Tommy!
>>
>>
>>
>> Have you tested against CUCM 11.x okay?
>>
>>
>>
>> I need to build the dependencies to fully run yours.  I tried pulling out
>> the important upload code but seeing the same issue I'm having with my code.
>>
>>
>>
>> Thanks,
>>
>> Brian Meade
>>
>>
>>
>> On Fri, Jun 1, 2018 at 1:18 PM, Schlotterer, Tommy <
>> tschlotterer at presidio.com> wrote:
>>
>> Brian,
>>
>>
>>
>> Here is my really hacky python script to do this.
>>
>>
>>
>> Thanks
>>
>>
>> Tommy
>>
>>
>>
>> *From:* cisco-voip [mailto:cisco-voip-bounces at puck.nether.net] *On
>> Behalf Of *Brian Meade
>> *Sent:* Friday, June 1, 2018 9:54 AM
>> *To:* cisco-voip voyp list <cisco-voip at puck.nether.net>
>> *Subject:* [cisco-voip] CUCM Bulk TFTP File Upload
>>
>>
>>
>> *EXTERNAL EMAIL*
>>
>>
>>
>>
>>
>> Does anyone have a working script for this?
>>
>>
>>
>> I put together a script in python to do this but hitting some issues.
>>
>>
>>
>> Right now I’ve got it to the point that it’s trying to upload a single
>> file.
>>
>>
>>
>> I used Fiddler to copy what I saw for a working request through a browser.
>>
>>
>>
>> I first do a Get to the cmplatform page to get a cookie.
>>
>>
>>
>> I then do a Post to the /cmplatform/j_security_check page to authenticate
>> that cookie.
>>
>>
>>
>> I then do a Get to /cmplatform/tftpFileUpload.do to get a Struts Token.
>>
>>
>>
>> I then do a Post to /cmplatform/tftpFileUpload.do with the Struts token,
>> filename, and directory details.
>>
>>
>>
>> This looks to be successful as I get a "File uploaded successfully"
>> message returned but then I can't find the file on the TFTP File Management
>> page.
>>
>>
>>
>> I tried using the curl methods I found here (
>> https://communities.cisco.com/docs/DOC-43506 ) but no luck there.  Not
>> sure if this works in 11.5 without grabbing the Struts token.   Without a
>> token, I get an error message saying something to the affect of I hit the
>> Submit button twice.
>>
>>
>>
>> Here's what it looks like when my script runs in Fiddler:
>>
>>
>>
>>
>>
>> This looks almost exactly like the real example through a browser I
>> captured minus a few headers I tried manually adding with no luck.
>>
>>
>>
>> Python script attached.
>>
>>
>>
>>
>>
>>
>>
>> * Tommy Schlotterer | Systems Engineer - Collaboration Presidio (NASDAQ:
>> PSDO) | presidio.com <http://presidio.com> 20 N Saint Clair 3rd Floor,
>> Toledo, OH 43604
>> <https://maps.google.com/?q=20+N+Saint+Clair+3rd+Floor,+Toledo,+OH+43604&entry=gmail&source=g>
>> D: 419.214.1415 <(419)%20214-1415> | C: 419.706.0259 <(419)%20706-0259> |
>> tschlotterer at presidio.com <tschlotterer at presidio.com>*
>>
>>
>>
>> * [image: Future. Built.] <http://www.presidio.com>*
>>
>>
>>
>>
>> * Follow us: [image: Follow Presidio on Twitter]
>> <http://www.twitter.com/presidio>*
>>
>>
>>
>>
>>
>> *This message w/attachments (message) is intended solely for the use of
>> the intended recipient(s) and may contain information that is privileged,
>> confidential or proprietary. If you are not an intended recipient, please
>> notify the sender, and then please delete and destroy all copies and
>> attachments. Please be advised that any review or dissemination of, or the
>> taking of any action in reliance on, the information contained in or
>> attached to this message is prohibited.*
>>
>>
>>
>>
>>
>> [image: Future. Built.] <http://www.presidio.com>
>>
>>
>> Follow us:
>>
>> [image: Follow Presidio on Twitter] <http://www.twitter.com/presidio>
>>
>>
>>
>>
> _______________________________________________
> cisco-voip mailing list
> cisco-voip at puck.nether.net
> https://puck.nether.net/mailman/listinfo/cisco-voip
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://puck.nether.net/pipermail/cisco-voip/attachments/20180602/22aec45b/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image002.png
Type: image/png
Size: 370432 bytes
Desc: not available
URL: <https://puck.nether.net/pipermail/cisco-voip/attachments/20180602/22aec45b/attachment.png>


More information about the cisco-voip mailing list