You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

143 lines
5.0 KiB

  1. #!/usr/bin/env sh
  2. # Script to deploy certificates to Palo Alto Networks PANOS via API
  3. # Note PANOS API KEY and IP address needs to be set prior to running.
  4. # The following variables exported from environment will be used.
  5. # If not set then values previously saved in domain.conf file are used.
  6. #
  7. # Firewall admin with superuser and IP address is required.
  8. #
  9. # export PANOS_USER="" # required
  10. # export PANOS_PASS="" # required
  11. # export PANOS_HOST="" # required
  12. # This function is to parse the XML
  13. parse_response() {
  14. status=$(echo "$1" | sed 's/^.*"\([a-z]*\)".*/\1/g')
  15. message=$(echo "$1" | sed 's/^.*<result>\(.*\)<\/result.*/\1/g')
  16. return 0
  17. }
  18. deployer() {
  19. type=$1 # Types are cert, key, commit
  20. _debug "**** Deploying $type *****"
  21. #Generate DEIM
  22. delim="-----MultipartDelimiter$(date "+%s%N")"
  23. nl="\015\012"
  24. #Set Header
  25. _H1="Content-Type: multipart/form-data; boundary=$delim"
  26. if [ $type = 'cert' ]; then
  27. content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_cfullchain")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_cfullchain")"
  28. fi
  29. if [ $type = 'key' ]; then
  30. #Add key
  31. content="$content${nl}--$delim${nl}Content-Disposition: form-data; name=\"file\"; filename=\"$(basename "$_ckey")\"${nl}Content-Type: application/octet-stream${nl}${nl}$(cat "$_ckey")"
  32. fi
  33. #Close multipart
  34. content="$content${nl}--$delim--${nl}"
  35. #Convert CRLF
  36. content=$(printf %b "$content")
  37. if [ $type = 'cert' ]; then
  38. panos_url="https://$_panos_host/api/?type=import&category=certificate&certificate-name=$_cdomain&format=pem&key=$_panos_key"
  39. fi
  40. if [ $type = 'key' ]; then
  41. panos_url="https://$_panos_host/api/?type=import&category=private-key&certificate-name=$_cdomain&format=pem&passphrase=none&key=$_panos_key"
  42. fi
  43. if [ $type = 'commit' ]; then
  44. cmd=$(_url_encode "<commit><partial><$_panos_user></$_panos_user></partial></commit>")
  45. panos_url="https://$_panos_host/api/?type=commit&cmd=$cmd&key=$_panos_key"
  46. fi
  47. if [ $type = 'key' ] || [ $type = 'cert' ]; then
  48. response=$(_post "$content" "$panos_url" "" "POST")
  49. else
  50. response=$(_get $panos_url)
  51. fi
  52. _debug panos_url $panos_url
  53. _debug "RESPONSE $response"
  54. parse_response "$response"
  55. _debug "STATUS IS $status"
  56. _debug "MESSAGE IS $message"
  57. # Saving response to variables
  58. response_status=$status
  59. # Check for cert upload error and handle gracefully.
  60. #DEBUG
  61. _debug header "$_H1"
  62. # _debug content "$content"
  63. _debug response_status "$response_status"
  64. if [ "$response_status" = "success" ]; then
  65. _debug "Successfully deployed $type"
  66. return 0
  67. else
  68. _err "Deploy of type $type failed. Try deploying with --debug to troubleshoot."
  69. _debug "$message"
  70. return 1
  71. fi
  72. }
  73. # This is the main function that will call the other functions to deploy everything.
  74. panos_deploy() {
  75. _cdomain="$1"
  76. _ckey="$2"
  77. _cfullchain="$5"
  78. # PANOS HOST is required to make API calls to the PANOS/Panorama
  79. if [ -z "$PANOS_HOST" ]; then
  80. if [ -z "$_panos_host" ]; then
  81. _err "PANOS_HOST not defined."
  82. return 1
  83. fi
  84. else
  85. _debug "PANOS HOST is set. Save to domain conf."
  86. _panos_host="$PANOS_HOST"
  87. _savedomainconf _panos_host "$_panos_host"
  88. fi
  89. # Retrieve stored variables
  90. _panos_user="$(_readaccountconf_mutable PANOS_USER)"
  91. _panos_pass="$(_readaccountconf_mutable PANOS_PASS)"
  92. # PANOS Credentials check
  93. if [ -z "$PANOS_USER" ] || [ -z "$PANOS_PASS" ]; then
  94. _debug "PANOS_USER, PANOS_PASS is not defined"
  95. if [ -z "$_panos_user" ] && [ -z "$_panos_pass" ]; then
  96. _err "No user and pass found in storage. If this is the first time deploying please set PANOS_USER and PANOS_PASS in environment variables."
  97. return 1
  98. else
  99. _debug "ok"
  100. fi
  101. else
  102. _debug "Saving environment variables"
  103. # Encrypt and save user
  104. _saveaccountconf_mutable PANOS_USER "$PANOS_USER"
  105. _saveaccountconf_mutable PANOS_PASS "$PANOS_PASS"
  106. _panos_user="$PANOS_USER"
  107. _panos_pass="$PANOS_PASS"
  108. fi
  109. _debug "Let's use username and pass to generate token."
  110. if [ -z "$_panos_user" ] || [ -z "$_panos_pass" ] || [ -z "$_panos_host" ]; then
  111. _err "Please pass username and password and host as env variables PANOS_USER, PANOS_PASS and PANOS_HOST"
  112. return 1
  113. else
  114. _debug "Getting PANOS KEY"
  115. panos_key_response=$(_get "https://$_panos_host/api/?type=keygen&user=$_panos_user&password=$_panos_pass")
  116. _debug "PANOS KEY FULL RESPONSE $panos_key_response"
  117. status=$(echo "$panos_key_response" | sed 's/^.*\(['\'']\)\([a-z]*\)'\''.*/\2/g')
  118. _debug "STATUS IS $status"
  119. if [ "$status" = "success" ]; then
  120. panos_key=$(echo "$panos_key_response" | sed 's/^.*\(<key>\)\(.*\)<\/key>.*/\2/g')
  121. _panos_key=$panos_key
  122. else
  123. _err "PANOS Key could not be set. Deploy with --debug to troubleshoot"
  124. return 1
  125. fi
  126. if [ -z "$_panos_host" ] && [ -z "$_panos_key" ] && [ -z "$_panos_user" ]; then
  127. _err "Missing host, apikey, user."
  128. return 1
  129. else
  130. deployer cert
  131. deployer key
  132. deployer commit
  133. fi
  134. fi
  135. }