Saturday, February 9, 2019

How to upload and download files with https sftp and sftp protocols using python

Advertisements

We all use file servers. It may be ftp or http. to secure http communication we use https protocol. In case of ftp, there are two options. ftps and sftp.

FTP:
First we will see how the normal ftp works. FTP is one of the mostly used tool for file transfer. FTP user two channels for data transfer. Command channel and data channel. Ftp was created in beginning of the internet era when internet security was not a big issue. So they didn't encrypt the data transfer in these two channels. In effect all the user credentials and data transferred via ftp is clear. A usual man in the middle attack can see everything transferred via these channels.

As security became a big concern, techies created ways to make the data transfer secure using encryption.

FTPS:
FTPS is just like https. FTP + SSL(Secure socket layer). FTPS uses a user id and password, a certificate, or both. When connecting to a FTPS server, ftps client will first check if the server's certificate is trusted. The certificate is considered trusted if either the certificate was signed by a known certificate authority (CA) or if the certificate was self-signed and you have a copy of public certificate in your trusted key store. User id authentication can be used with any combination of certificate and/or password authentication.

In effect, FTPS just added another layer for security using ssl. It still uses two ports for commands and data transfer just like normal ftp.

SFTP:
SFTP works in another way. SFTP is based on SSH(secure shell) protocol. Unlike ftp and ftps which uses two ports, SFTP uses single ports and encrypts the transfer of commands and data through it. Just like normal ftp, in SFTP we can use just a user id and password. In SFTP, we can also use ssh keys for authentication.


Now let's see how to upload and download files to HTTPS,FTPS and SFTP using python.

HTTPS:
For https, we will use the requests python module. We will create a function which takes the hostname, file to be uploaded(file_name, i.e the path), and credentials. It returns the failed services to the call.

def check_https(hostname,file_name,username,password,verbose):
  if verbose:
    print("-"*60)
  https_services_failed = []
   # HTTPS: Upload the file. 
  if verbose:
    print("HTTPS: Uploading the file")    #print(file_name,username,password,hostname)
  url = 'https://{0}'.format(hostname)
  fh = open(file_name, 'rb')
  files = {'file': ('http.txt', fh, 'multipart/form-data', {'Expires': '0'})}  try:    p = requests.post(url, files=files,auth=('{0}'.format(username),'{0}'.format(password)),verify=False)
  except:    if verbose:
      print("HTTPS: Failed to upload the file via http.")      print(p.status_code)
    https_services_failed.append('https_upload')
  else:    fh.close()
    if p.status_code == 200:
      if verbose:
        print("HTTPS: File uploaded successfully.")    else:
      if verbose:
        print(p.status_code)
        print("HTTPS: Failed to upload the file via http.")      https_services_failed.append('https_upload')  

  # HTTPS: Download the file.   if verbose:
    print("-"*60)
    print("HTTPS: Downloading the uploaded file.\n")  url='https://{0}/{1}'.format(hostname,'http.txt')  try:    g = requests.get(url,auth=('{0}'.format(username),'{0}'.format(password)),verify=False)
  except:    if verbose:
      print("HTTPS: Failed to download the file via http")    https_services_failed.append('https_download')
  else:    if g.status_code == 200:
      if verbose:
        print("HTTPS: Downloaded the file successfully.")    else:
      if verbose:
        print(g.status_code)
        print("HTTPS: Failed to download the file via http")      https_services_failed.append('https_download'
  # HTTPS: Remove the uploaded file.
  url='https://{0}/{1}'.format(hostname,'http.txt')  headers = {'content-type': 'multipart/form-data'}  try:    d =  requests.delete(url,auth=('{0}'.format(username),'{0}'.format(password)),verify=False)   except:    if verbose:
      print("HTTPS: Failed to delete the uploaded file via http")      print(d.text)
    https_services_failed.append('https_delete')
  else:    if d.status_code == 200:
      if verbose:
        print("HTTPS: Deleted the file successfully.")    else:
      if verbose:
        print(d.status_code)
        print(d.text)
        print("HTTPS: Failed to delete the uploaded file via http")      https_services_failed.append('https_delete')
   return  https_services_failed


FTPS:
For FTPS we will use FTP_TLS class from the module ftplib. The following function takes the hostname, file to be uploaded(file_name, i.e the path), and credentials. It returns the failed services to the call.

def check_ftps(hostname,temp_name,username,password,verbose):
  ftps_services_failed = []
  if verbose:
    print("-"*60)
  if verbose:
    print(temp_name)
  ftps = FTP_TLS(hostname)
  ftps.login(username, password)
  ftps.prot_p()            #ftps.retrlines('LIST')
  if verbose:
    ftps.set_debuglevel(2)
    # Upload the file
  if verbose:
    print("FTPS: Uploading the file.")  try:    ftps.storbinary('STOR {0}'.format('ftps.txt'), open(temp_name,'rb'))
  except:    if verbose:
      print("FTPS: Uploading the file failed.")    ftps_services_failed.append('ftps_upload')
  else:    if verbose:
      print("FTPS: Uploaded file successfully.")    pass
  # Download the file
  if verbose:
    print("FTPS: Downloading the file.")  try:    myfile = open('/tmp/ftps.txt', 'wb')
    ftps.retrbinary('RETR {0}'.format('ftps.txt'), myfile.write)
  except:    if verbose:
      print("FTPS: Downloading the uploaded file failed.")    ftps_services_failed.append('ftps_download')
  else:    if verbose:
      print("FTPS: Downloaded the uploaded file successfully.")
  # Delete the file from remote system
  try:    ftps.delete('ftps.txt')
  except:    if verbose:
      print("FTPS: Deleting uploaded file failed.")    ftps_services_failed.append('ftps_delete')
  else:    if verbose:
      print("FTPS: Deleted the uploaded file successfully.")    pass
  # Close the ftps connection.
  ftps.close()
  # Detel the file which is downloaded
  delete_temp_file('/tmp/ftps.txt',verbose)
  return ftps_services_failed


SFTP:
For SFTP we will use the python module pysftp. The following function takes the hostname, file to be uploaded(file_name, i.e the path), and credentials. It returns the failed services to the call.

def check_sftp(hostname,file_name,username,password,verbose):
  sftp_services_failed = []
  if verbose:
    print("-"*60)
    print("Filename passed to upload is {0}".format(file_name))  sftip_file = file_name
  cnopts = pysftp.CnOpts()
  cnopts.hostkeys = None 
  # Uploading the file.
  if verbose:
    print("Uploading the file {0}".format(file_name))  try:    with pysftp.Connection(host=hostname, username=username, password=password,cnopts=cnopts) as sftp:
      sftp.put(sftip_file,'sftp.txt')
      #data = sftp.listdir()
  except:    if verbose:
      print("sftp upload failed.")    sftp_services_failed.append('sftp_upload')    else:    if verbose:
      print("SFTP: File uploaded sucessfully.")    pass     # Download the uploaded file.
  if verbose:
    print("-"*60)
  if verbose:     print("Downloading the file {0}".format('sftp.txt'))  try:    with pysftp.Connection(host=hostname, username=username, password=password,cnopts=cnopts) as sftp:
      sftp.get('sftp.txt','/tmp/sftp.txt')  except:    if verbose:
      print("sftp download failed.")    sftp_services_failed.append('sftp_download')
  else:    if verbose:
      print("SFTP: File downloaded successfully.")    pass
  # Remove the uploaded file.
  if verbose:     print("Removing the uploaded file")  try:    with pysftp.Connection(host=hostname, username=username, password=password,cnopts=cnopts) as sftp:
      sftp.remove('sftp.txt')
  except:    if verbose:
      print("sftp: Deleting uploaded file failed.")    sftp_services_failed.append('sftp_delete')
  else:    if verbose:
      print("SFTP: Deleted uploaded file successfully.")    pass
  delete_temp_file('/tmp/sftp.txt',verbose)
  return sftp_services_failed

No comments:

Post a Comment

Be nice. That's all.