2

I need to run a curl command that accesses a website that another person has the password to.

e.g. curl --basic --user myfriendsname:friendspassword http://www.updateinfo.com

I need a way where I can launch this script without being able to see my friend's password.

5

From man curl:

-u, --user <user:password>
  ...
  If you just give the user name (without entering a colon) curl will prompt
  for a password.
  ...

Just pass them the keyboard (or a screen/tmux share) and have them type it in.

  • Obviously, the problem with the --user parameter is that the password can be intercepted with ps while the process is running, if passed on the command line. Prompting is a cool solution if we're not trying to automate. :) – insignificant zebra May 19 '14 at 23:11
  • I guess input redirection would still be possible? I'm confused by redirecting unusual fd's too, but I think it should be possible. – Andreas Wiese May 19 '14 at 23:16
  • Thanks @Patrick, that's helpful if my friend is in the room but the whole point of scripting it is to automate it. – Joshua Robison May 20 '14 at 8:16
  • @JoshuaRobison Can you please update your question then. Without information we can't know what you're trying to accomplish. – Patrick May 20 '14 at 12:23
3

If you had checked man curl or the curl FAQ, you would know that curl has the --config/-K parameter to:

Specify which config file to read curl arguments from. The config file is a text file in which command line arguments can be written which then will be used as if they were written on the actual command line. ... (man curl)

For example, you could store and decrypt the password with gpg. The decrypt parameter is -d.

Update: A complete solution step-by-step

Initially I did not provide a complete solution, because that would be giving you a fish, when you learning to fish yourself is more valuable.

But since you seem really unsure about how to proceed, here's a quick and dirty script in Python 3.3 to manage the HTTP password secret.

Just download that script (or clone repo with git), chmod u+x ./curling-with-secrets.py then run it with ./curling-with-secrets --help, and you'll see this:

❯ ./curling-with-secrets.py --help
usage: curling-with-secrets.py [-h] [--secretfile [SECRETFILE]] user url

This is curling-with-secrets by Guy Hughes.

positional arguments:
  user                  the username to pass to curl
  url                   the url to pass to curl

optional arguments:
  -h, --help            show this help message and exit
  --secretfile [SECRETFILE]
                        specify an alternative secret file

The script creates a file, secret.enc given by the variable secretfile, in its directory by using openssl to encrypt the file using the sha512sum salted hash of the filepath as the passphrase. This does not provide a high level of security, but it would take a bit of effort for anyone to view the password, whereas storing it in cleartext makes viewing the password accidentially with cat or quicklook in OS X far too easy. Your friend could harden this by changing the encryption mechanism and the token() function, then storing the file in a location that your user account does not have read permissions, but does have execute permissions, and owned by another user and group, supposing you do not have sudoers or root access to the host.

After the secretfile is created, the script runs curl with the specified user authentication and url passed on the command line. These options are passed to STDIN to curl using the -K - option (which reads a configuration file from STDIN), formatted as a curl configuration file. You can easily extend this to suit your needs following man curl. :)

I am not really much of a Python person, so there's probably some kinks in this script, but it could be a good starting point for you. You should definitely test it throughly.

Here's the full source of the script:

#!/usr/bin/env python3.3

#  Guy Hughes, 2014
#  GNU General Public License Version 3, 29 June 2007

from sys import stdin
from sys import stdout
import os
import argparse
#from sys import os.environ
#from sys import os.access
#from sys import os.mkdirs
#from sys import os.path
import subprocess
import errno
import getpass

def init():
    global args
    global secretfile
    global secretfiledir
    # parse args
    parser = argparse.ArgumentParser(description='This is curling-with-secrets by Guy Hughes.')
    parser.add_argument('--secretfile',nargs='?',help='specify an alternative secret file',type=str)
    parser.add_argument('user', help='the username to pass to curl',type=str)
    parser.add_argument('url', help='the url to pass to curl',type=str)
    args=parser.parse_args()
    #secretfile=os.path.abspath(os.environ.get('XDG_CONFIG_HOME',os.environ.get('HOME') + "/.config") + "/secretcurl/secret.enc")
    if args.secretfile:
        secretfile = os.path.abspath(args.secretfile)
    else:
        secretfile=os.path.abspath('./secret.enc')
        secretfiledir=os.path.dirname(secretfile)

    if check():
        curl()

def check():
    if os.path.isfile(secretfile) and os.access(secretfile, os.R_OK):
        print("I found secretfile at %s. [OK]" % secretfile)
        return True
    else:
        print("I did not find the secretfile at %s. We'll now create it..." % secretfile)
        return createfile()

def token():
    echop=subprocess.Popen(["echo", secretfile], stdout=subprocess.PIPE)
    shap=subprocess.Popen(['sha512sum'],stdout=subprocess.PIPE,stdin=echop.stdout)
    grepp=subprocess.Popen(['grep', '-Eo','\'^.{40}\''],stdout=subprocess.PIPE,stdin=shap.stdout)
    echop.stdout.close()
    shap.stdout.close()
    result=grepp.communicate()[0]
    return result


def createfile():
    # safety check
    if os.path.isfile(secretfile):
        print("FATAL: secretfile exists at %s" % secretfile)
        print("Stopping, to prevent secretfile from being overriden.")
        print("If you wish to overwrite the secretfile, first delete it yourself this run this command again.")
        exit(1)

    print("Creating the secretfile at %s" % secretfile)
    print("Remember: Once the secret file is created, this script"
          " will only be able to decrypt while it is in the same directory and filename."
          "If you ever wish to rename the secretfile, you'd need to modify this script "
          "or recreate the secretfile using this script.")

    print("Checking for directory %s" % secretfiledir)
    if not os.path.exists(secretfiledir):
        sys.stdout.write("Making directories...")
        os.makedirs(secretfiledir, exist_ok=True)
    else:
        print("Parent directories are OK")

    print("Please enter the secret password to be passed to curl:")
    password=getpass.getpass()
    thetoken = token()
    echop=subprocess.Popen(['echo',password],stdout=subprocess.PIPE)
    opensslp=subprocess.Popen(['openssl', 'enc', '-aes-256-cbc',
                     '-salt', '-a',
                     '-k', thetoken,
                     '-out', secretfile
                     ], stdin=echop.stdout)
    echop.stdout.close()

    del password
    del thetoken

    print("Createfile done.")
    return True

def curl():
    print("Decrypting the password...")
    thetoken=token()
    opensslp=subprocess.Popen(['openssl','enc','-aes-256-cbc','-d', '-a','-k',thetoken,
                                      '-in', secretfile],stdout=subprocess.PIPE)
    password=opensslp.communicate()[0].decode('utf-8')
    print(args)
    print(args.url)
    print(password)
    curlconfig="user = " + args.user + "\:" + password  + "\nurl = " + args.url
    curlp=subprocess.Popen(['curl','--basic', '-K', '-'],
                          stdin=subprocess.PIPE,stderr=subprocess.STDOUT,shell=False)
    result=curlp.communicate(input=bytes(curlconfig, 'UTF-8'))
    print(result)



    del password



init()
  • Id like to take your word for it that this idea will work but it's going to take me a while to study the man file on curl and the curl FAQ and then do trial and error testing until i figure out a line of code that will work for my situation. Then if i did intact find the solution all the work i put into this research would prompt me to write an answer that someone could actually plugin and use and post it here myself .... 0_o – Joshua Robison May 20 '14 at 8:21
  • @JoshuaRobison I updated my answer with a full solution. ☺ – insignificant zebra May 22 '14 at 1:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.