Child pages
  • Tutorial - Call UAPI's SSL::install_ssl Function in Custom Code

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Introduction

Excerpt
This tutorial creates custom code to call UAPI's SSL::install_ssl function.
 Due to their inherent complexities, SSL-related functions often present problems for third-party developers. This tutorial provides explanations for the additional steps required in order to successfully call SSL functions.

Create custom SSL::install_ssl code


Note
titleNote:

Select the tab below that corresponds to the desired coding language.

Localtab Group
Localtab
activetrue
titlePerl
Section
Column
width72px

Column

Set the strict pragma and use warnings.

These declarations instruct Perl to return errors if the file contains potentially-unsafe code.

Note
titleNote:

You can omit the warnings declaration in production code, but we strongly recommend that you use it during development. 

Code Block
languageperl
firstline3
linenumberstrue
# Return errors if Perl experiences problems.
use strict;
use warnings;

 


 

Section
Column
width72px

Column

Set web request module dependencies.

We recommend that you set a dependency for one or more modules that allow you to perform web requests.

  • This tutorial uses the LWP::UserAgent and LWP::Protocol::https modules.
  • The HTTP::Tiny module also fulfills this need.
Code Block
languageperl
firstline7
linenumberstrue
# Allow my code to perform web requests.
use LWP::UserAgent;
use LWP::Protocol::https;

 


 

Section
Column
width72px

Column

Use UTF-8 encoding.

You must use UTF-8 encoding when you call UAPI functions. If you do not use the correct encoding, your code may result in wide character warnings.

Code Block
languageperl
firstline11
linenumberstrue
# Use the correct encoding to prevent wide character warnings.
use Encode;
use utf8;

 


 

Section
Column
width72px

Column

Use JSON formatting.

Declare the use of JSON formatting, to ensure that your code can properly decode JSON.

Code Block
languageperl
firstline15
linenumberstrue
# Properly decode JSON.
use JSON;

 


 

Section
Column
width72px

Column

Use Base64 encoding.

Declare the use of the MIME::Base64 module, which ensures that your code properly interacts with Base64-encoded authentication headers.

Code Block
languageperl
firstline18
linenumberstrue
# Function properly with Base64 authentication headers.
use MIME::Base64;

 


 

Section
Column
width72px

Column

Provide authentication information.

Declare the variables for your cPanel account username and password in order to allow your code to authenticate with cPanel & WHM.

Code Block
languageperl
firstline21
linenumberstrue
# Authentication information.
my $username = 'username';
my $password = '12345luggage';

 


 

Section
Column
width72px

Column

Set the API call location.

Set the $request variable to the URL for the desired API call.

Code Block
languageperl
firstline25
linenumberstrue
# The URL for the SSL::install_ssl UAPI function.
my $request = "https://localhost:2083/execute/SSL/install_ssl";

 


 

Section
Column
width72px

Column

Allow HTTPS connections to unsigned services.

Set the PERL_LWP_SSL_VERIFY_HOSTNAME environment variable to 0 to allow HTTPS connections to unsigned services.

Warning
titleWarning:

You must include this step in your code. Services on the local host are always unsigned. 

Code Block
languageperl
firstline28
linenumberstrue
# Required to allow HTTPS connections to unsigned services.
# Services on localhost are always unsigned.
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0;

 


 

Section
Column
width72px

Column

Create a new UserAgent object.

Use the LWP::UserAgent module's new() method to create a new UserAgent object to use for the API call.

Code Block
languageperl
firstline32
linenumberstrue
# Create a useragent object.
my $ua = LWP::UserAgent->new();

 


 

Section
Column
width72px

Column

Create authentication headers.

Use the new UserAgent object to set up authentication headers that use the $username and $password values from lines 22 and 23.

Code Block
languageperl
firstline35
linenumberstrue
# Add authentication headers.
$ua->default_header(
    'Authorization' => 'Basic ' . MIME::Base64::encode("$username:$password"),
);

 


 

Section
Column
width72px

Column

Read in the SSL certificate and key files.

Declare variables and set values for the SSL certificate and key files.

Code Block
languageperl
firstline40
linenumberstrue
# Read in the SSL certificate and key file.
my ( $cert, $key );
{
    local $/;
    open ( my $fh, '<', '/path/to/certificate.crt' );
    $cert = <$fh>;
    close $fh;
  
    open ( $fh, '<', '/path/to/key.key' );
    $key = <$fh>;
    close $key;
}

 


 

Section
Column
width72px

Column

Create a POST request for the call.

Create a POST request that includes the function's required input parameters. The $response variable will contain the call's output.

Code Block
languageperl
firstline53
linenumberstrue
# Make the call.
my $response = $ua->post($request,
    Content_Type => 'form-data',
    Content => [
        domain => 'example.com',
        cert   => $cert,
        key    => $key,
    ],
);

 


 

Section
Column
width72px

Column

Create an object to decode the call's output.

Create an object to decode the call's JSON-formatted output. You will use this object to sort and pretty-print the JSON.

Code Block
languageperl
firstline63
linenumberstrue
# Create an object to decode the JSON.
# Sorted by keys and pretty-printed.
my $json_printer = JSON->new->pretty->canonical(1);

 


 

Section
Column
width72px

Column

UTF-8 encode and then decode the call's output.

Use the Encode module to UTF-8 encode the call's output in the $response variable. Then, use the JSON module to decode the output.

Note
titleNote:

If you do not UTF-8 encode this output, you may receive wide character warnings.

Code Block
languageperl
firstline67
linenumberstrue
# UTF-8 encode before decoding to avoid wide character warnings.
my $content = JSON::decode_json(Encode::encode_utf8($response->decoded_content));

 


 

Section
Column
width72px

Column

Print the function's output.

Use the object that line 65 created to pretty-print and sort the JSON output. Then, use the Encode module to UTF-8 encode the pretty-printed and sorted JSON, and print the final result.

Note
titleNote:

If you do not UTF-8 encode this output, you may receive wide character warnings.

Code Block
languageperl
firstline70
linenumberstrue
# Print output, UTF-8 encoded to avoid wide character warnings.
print Encode::encode_utf8($json_printer->encode($content));
Localtab
titlePHP
Section
Column
width72px

Column

Initiate error logging.

Set error reporting to E_ALL in order to log all errors and warnings.

Note
titleNote:

You can omit this step in production code, but we strongly recommend its use during development. 

Code Block
languagephp
firstline2
linenumberstrue
// Log everything during development.
// If you run this on the CLI, set 'display_errors = On' in php.ini.
error_reporting(E_ALL);

 


 

Section
Column
width72px

Column

Provide authentication information.

Declare the variables for your cPanel account username and password in order to allow your code to authenticate with cPanel & WHM.

Code Block
languagephp
firstline6
linenumberstrue
// Declare your username and password for authentication.
$username = 'example';
$password = 'luggage12345';

 


 

Section
Column
width72px

Column

Define the API call.

Define the API host, and the URL for the desired API call.

Code Block
languagephp
firstline10
linenumberstrue
// Define the API call.
$cpanel_host = 'localhost';
$request_uri = "https://$cpanel_host:2083/execute/SSL/install_ssl";

 


 

Section
Column
width72px

Column

Specify the locations of the SSL certificate and key files.

Declare variables and set values for the SSL certificate and key files.

Note
titleNote:

This example manually defines the filename and destination. You can also use functions or the $argv array to pass these values.

Code Block
languagephp
firstline14
linenumberstrue
// Define the SSL certificate and key files.
$cert_file = realpath("/path/to/cert.crt");
$key_file = realpath("/path/to/key.key");

 


 

Section
Column
width72px

Column

Set up the payload to send to the server.

Set up the payload to send to the server. This data includes the function's required input parameters.

Code Block
languagephp
firstline18
linenumberstrue
// Set up the payload to send to the server.
$payload = array(
    'domain' => "example.com",
    'cert'   => file_get_contents($cert_file),
    'key'    => file_get_contents($key_file)
);

 


 

Section
Column
width72px

Column

Set up the cURL request object.

Set up a cURL request object that uses the specified $username and $password variables.

Note
titleNotes:
  • Only use the CURLOPT_SSL_VERIFYHOST and CURLOPT_SSL_VERIFYPEER options with self-signed or expired certificates.
  • localhost always uses a self-signed certificate.
Code Block
languagephp
firstline25
linenumberstrue
// Set up the cURL request object.
$ch = curl_init( $request_uri );
curl_setopt( $ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC );
curl_setopt( $ch, CURLOPT_USERPWD, $username . ':' . $password );
curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false );
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );

 


 

Section
Column
width72px

Column

Create a POST request for the call.

Create a POST request that includes the function's required input parameters and uses the $payload variable from line 19.

Code Block
languagephp
firstline32
linenumberstrue
// Set up a POST request with the payload.
curl_setopt( $ch, CURLOPT_POST, true );
curl_setopt( $ch, CURLOPT_POSTFIELDS, $payload );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );

 


 

Section
Column
width72px

Column

Make the call.

Use the curl_exec() method to make the API call. Then, use the curl_close() method to close the cURL object that you created.

Code Block
languagephp
firstline37
linenumberstrue
// Make the call, and then terminate the cURL caller object.
$curl_response = curl_exec( $ch );
curl_close( $ch );

 


 

Section
Column
width72px

Column

Decode and validate the output.

Use the json_decode() method to decode the $curl_response value, which contains the call's output. Then, validate that output.

  • Lines 43 through 45 of the example below check to ensure that the call returned output.
  • Lines 46 through 48 of the example below ensure that there were no errors.
Code Block
languagephp
firstline41
linenumberstrue
// Decode and validate output.
$response = json_decode( $curl_response );
if( empty( $response ) ) {
    echo "The cURL call did not return valid JSON:\n";
    die( $response );
} elseif ( !$response->status ) {
    echo "The cURL call returned valid JSON, but reported errors:\n";
    die( $response->errors[0] . "\n" );
}

 


 

Section
Column
width72px

Column

Print output.

Print the validated output and exit.

Code Block
languagephp
firstline51
linenumberstrue
// Print and exit.
die( print_r( $response ) );

Completed code


When you finish this tutorial, your code will resemble the following examples:

Expand
titleClick to view the complete Perl code...
Code Block
languageperl
linenumberstrue
#!/usr/local/cpanel/3rdparty/bin/perl

# Return errors if Perl experiences problems.
use strict;
use warnings;
 
# Allow my code to perform web requests.
use LWP::UserAgent;
use LWP::Protocol::https;
 
# Use the correct encoding to prevent wide character warnings.
use Encode;
use utf8;
 
# Properly decode JSON.
use JSON;
 
# Function properly with Base64 authentication headers.
use MIME::Base64;
 
# Authentication information.
my $username = 'username';
my $password = '12345luggage';
 
# The URL for the SSL::install_ssl UAPI function.
my $request = "https://localhost:2083/execute/SSL/install_ssl";
 
# Required to allow HTTPS connections to unsigned services.
# Services on localhost are always unsigned.
$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0;
 
# Create a useragent object.
my $ua = LWP::UserAgent->new();
 
# Add authentication headers.
$ua->default_header(
    'Authorization' => 'Basic ' . MIME::Base64::encode("$username:$password"),
);
 
# Read in the SSL certificate and key file.
my ( $cert, $key );
{
    local $/;
    open ( my $fh, '<', '/path/to/certificate.crt' );
    $cert = <$fh>;
    close $fh;
   
    open ( $fh, '<', '/path/to/key.key' );
    $key = <$fh>;
    close $key;
}
 
# Make the call.
my $response = $ua->post($request,
    Content_Type => 'form-data',
    Content => [
        domain => 'example.com',
        cert   => $cert,
        key    => $key,
    ],
);
 
# Create an object to decode the JSON.
# Sorted by keys and pretty-printed.
my $json_printer = JSON->new->pretty->canonical(1);
 
# UTF-8 encode before decoding to avoid wide character warnings.
my $content = JSON::decode_json(Encode::encode_utf8($response->decoded_content));
 
# Print output, UTF-8 encoded to avoid wide character warnings.
print Encode::encode_utf8($json_printer->encode($content));
Expand
titleClick to view the complete PHP code...
Code Block
languagephp
linenumberstrue
<?php
// Log everything during development.
// If you run this on the CLI, set 'display_errors = On' in php.ini.
error_reporting(E_ALL);

// Declare your username and password for authentication.
$username = 'example';
$password = 'luggage12345';
 
// Define the API call.
$cpanel_host = 'localhost';
$request_uri = "https://$cpanel_host:2083/execute/SSL/install_ssl";

// Define the SSL certificate and key files.
$cert_file = realpath("/path/to/cert.crt");
$key_file = realpath("/path/to/key.key");

// Set up the payload to send to the server.
$payload = array(
    'domain' => "example.com",
    'cert'   => file_get_contents($cert_file),
    'key'    => file_get_contents($key_file)
);

// Set up the cURL request object.
$ch = curl_init( $request_uri );
curl_setopt( $ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC );
curl_setopt( $ch, CURLOPT_USERPWD, $username . ':' . $password );
curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false );
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
 
// Set up a POST request with the payload.
curl_setopt( $ch, CURLOPT_POST, true );
curl_setopt( $ch, CURLOPT_POSTFIELDS, $payload );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );

// Make the call, and then terminate the cURL caller object.
$curl_response = curl_exec( $ch );
curl_close( $ch );

// Decode and validate output.
$response = json_decode( $curl_response );
if( empty( $response ) ) {
    echo "The cURL call did not return valid JSON:\n";
    die( $response );
} elseif ( !$response->status ) {
    echo "The cURL call returned valid JSON, but reported errors:\n";
    die( $response->errors[0] . "\n" );
}

// Print and exit.
die( print_r( $response ) );
?>