Asterisk - The Open Source Telephony Project  18.5.0
Functions
curl.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

struct curl_cb_datacurl_cb_data_create (void)
 Allocate memory for a curl_cb_data struct. More...
 
void curl_cb_data_free (struct curl_cb_data *data)
 Free a curl_cb_data struct. More...
 
char * curl_cb_data_get_cache_control (const struct curl_cb_data *data)
 Get the cache_control field from a curl_cb_data struct. More...
 
char * curl_cb_data_get_expires (const struct curl_cb_data *data)
 Get the expires field from a curl_cb_data struct. More...
 
char * curl_public_key (const char *public_cert_url, const char *path, struct curl_cb_data *data)
 CURL the public key from the provided URL to the specified path. More...
 

Function Documentation

◆ curl_cb_data_create()

struct curl_cb_data* curl_cb_data_create ( void  )

Allocate memory for a curl_cb_data struct.

Note
This will need to be freed by the consumer using curl_cb_data_free
Return values
NULLon failure
curl_cb_structon success

Definition at line 42 of file curl.c.

References ast_calloc.

Referenced by run_curl().

43 {
44  struct curl_cb_data *data;
45 
46  data = ast_calloc(1, sizeof(*data));
47 
48  return data;
49 }
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204

◆ curl_cb_data_free()

void curl_cb_data_free ( struct curl_cb_data data)

Free a curl_cb_data struct.

Parameters
dataThe curl_cb_data struct to free

Definition at line 51 of file curl.c.

References ast_free, curl_cb_data::cache_control, and curl_cb_data::expires.

Referenced by run_curl().

52 {
53  if (!data) {
54  return;
55  }
56 
57  ast_free(data->cache_control);
58  ast_free(data->expires);
59 
60  ast_free(data);
61 }
#define ast_free(a)
Definition: astmm.h:182
char * expires
Definition: curl.c:39
char * cache_control
Definition: curl.c:38

◆ curl_cb_data_get_cache_control()

char* curl_cb_data_get_cache_control ( const struct curl_cb_data data)

Get the cache_control field from a curl_cb_data struct.

Parameters
dataThe curl_cb_data
Return values
cache_controlon success
NULLotherwise

Definition at line 63 of file curl.c.

References curl_cb_data::cache_control, and NULL.

Referenced by set_public_key_expiration().

64 {
65  if (!data) {
66  return NULL;
67  }
68 
69  return data->cache_control;
70 }
#define NULL
Definition: resample.c:96
char * cache_control
Definition: curl.c:38

◆ curl_cb_data_get_expires()

char* curl_cb_data_get_expires ( const struct curl_cb_data data)

Get the expires field from a curl_cb_data struct.

Parameters
dataThe curl_cb_data
Return values
expireson success
NULLotherwise

Definition at line 72 of file curl.c.

References curl_cb_data::expires, and NULL.

Referenced by set_public_key_expiration().

73 {
74  if (!data) {
75  return NULL;
76  }
77 
78  return data->expires;
79 }
#define NULL
Definition: resample.c:96
char * expires
Definition: curl.c:39

◆ curl_public_key()

char* curl_public_key ( const char *  public_cert_url,
const char *  path,
struct curl_cb_data data 
)

CURL the public key from the provided URL to the specified path.

Note
The returned string will need to be freed by the caller
Parameters
public_cert_urlThe public cert URL
pathThe path to download the file to
dataThe curl_cb_data
Return values
NULLon failure
fullpath filename on success

Definition at line 185 of file curl.c.

References ast_asprintf, ast_free, ast_log, create_temp_file(), errno, get_curl_instance(), LOG_ERROR, NULL, RAII_VAR, and stir_shaken_get_serial_number_x509().

Referenced by run_curl().

186 {
187  FILE *public_key_file;
188  RAII_VAR(char *, tmp_filename, NULL, ast_free);
189  char *filename;
190  char *serial;
191  int fd;
192  long http_code;
193  CURL *curl;
194  char curl_errbuf[CURL_ERROR_SIZE + 1];
195 
196  curl_errbuf[CURL_ERROR_SIZE] = '\0';
197 
198  /* For now, it's fine to pass in path as is - it shouldn't end with a '/'. However,
199  * if we decide to change how certificates are stored in the future (configurable paths),
200  * then we will need to check to see if path ends with '/', copy everything up to the '/',
201  * and use this new variable for create_temp_file as well as for ast_asprintf below.
202  */
203  fd = create_temp_file(path, &tmp_filename);
204  if (fd == -1) {
205  ast_log(LOG_ERROR, "Failed to get temporary file descriptor for CURL\n");
206  return NULL;
207  }
208 
209  public_key_file = fdopen(fd, "wb");
210  if (!public_key_file) {
211  ast_log(LOG_ERROR, "Failed to open file '%s' to write public key from '%s': %s (%d)\n",
212  tmp_filename, public_cert_url, strerror(errno), errno);
213  close(fd);
214  remove(tmp_filename);
215  return NULL;
216  }
217 
218  curl = get_curl_instance(data);
219  if (!curl) {
220  ast_log(LOG_ERROR, "Failed to set up CURL isntance for '%s'\n", public_cert_url);
221  fclose(public_key_file);
222  remove(tmp_filename);
223  return NULL;
224  }
225 
226  curl_easy_setopt(curl, CURLOPT_URL, public_cert_url);
227  curl_easy_setopt(curl, CURLOPT_WRITEDATA, public_key_file);
228  curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_errbuf);
229 
230  if (curl_easy_perform(curl)) {
231  ast_log(LOG_ERROR, "%s\n", curl_errbuf);
232  curl_easy_cleanup(curl);
233  fclose(public_key_file);
234  remove(tmp_filename);
235  return NULL;
236  }
237 
238  curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
239 
240  curl_easy_cleanup(curl);
241  fclose(public_key_file);
242 
243  if (http_code / 100 != 2) {
244  ast_log(LOG_ERROR, "Failed to retrieve URL '%s': code %ld\n", public_cert_url, http_code);
245  remove(tmp_filename);
246  return NULL;
247  }
248 
249  serial = stir_shaken_get_serial_number_x509(tmp_filename);
250  if (!serial) {
251  ast_log(LOG_ERROR, "Failed to get serial from cert %s\n", tmp_filename);
252  remove(tmp_filename);
253  return NULL;
254  }
255 
256  if (ast_asprintf(&filename, "%s/%s.pem", path, serial) < 0) {
257  ast_log(LOG_ERROR, "Failed to allocate memory for new filename for temporary "
258  "file %s after CURL\n", tmp_filename);
259  ast_free(serial);
260  remove(tmp_filename);
261  return NULL;
262  }
263 
264  ast_free(serial);
265 
266  if (rename(tmp_filename, filename)) {
267  ast_log(LOG_ERROR, "Failed to rename temporary file %s to %s after CURL\n", tmp_filename, filename);
268  ast_free(filename);
269  remove(tmp_filename);
270  return NULL;
271  }
272 
273  return filename;
274 }
char * stir_shaken_get_serial_number_x509(const char *path)
Gets the serial number in hex form from the X509 certificate at path.
Definition: stir_shaken.c:140
#define NULL
Definition: resample.c:96
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:269
#define ast_log
Definition: astobj2.c:42
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
static CURL * get_curl_instance(struct curl_cb_data *data)
Prepare a CURL instance to use.
Definition: curl.c:128
#define LOG_ERROR
Definition: logger.h:285
int errno
#define ast_free(a)
Definition: astmm.h:182
static int create_temp_file(const char *path, char **filename)
Create a temporary file located at path.
Definition: curl.c:164