#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <malloc.h>
#include <libgen.h>
#include <fcntl.h>
#include <errno.h>
#include <cryptoutil.h>
#include "common.h"
#include <kmfapi.h>
int
pk_download(int argc, char *argv[])
{
int rv;
int opt;
extern int optind_av;
extern char *optarg_av;
int oclass = 0;
char *url = NULL;
char *http_proxy = NULL;
char *dir = NULL;
char *outfile = NULL;
char *proxy = NULL;
int proxy_port = 0;
KMF_HANDLE_T kmfhandle = NULL;
KMF_ENCODE_FORMAT format;
KMF_RETURN ch_rv = KMF_OK;
char *fullpath = NULL;
KMF_DATA cert = { 0, NULL };
KMF_DATA cert_der = { 0, NULL };
while ((opt = getopt_av(argc, argv,
"t:(objtype)u:(url)h:(http_proxy)o:(outfile)d:(dir)")) != EOF) {
if (EMPTYSTRING(optarg_av))
return (PK_ERR_USAGE);
switch (opt) {
case 't':
if (oclass)
return (PK_ERR_USAGE);
oclass = OT2Int(optarg_av);
if (!(oclass & (PK_CERT_OBJ | PK_CRL_OBJ)))
return (PK_ERR_USAGE);
break;
case 'u':
if (url)
return (PK_ERR_USAGE);
url = optarg_av;
break;
case 'h':
if (http_proxy)
return (PK_ERR_USAGE);
http_proxy = optarg_av;
break;
case 'o':
if (outfile)
return (PK_ERR_USAGE);
outfile = optarg_av;
break;
case 'd':
if (dir)
return (PK_ERR_USAGE);
dir = optarg_av;
break;
default:
cryptoerror(LOG_STDERR, gettext(
"unrecognized download option '%s'\n"),
argv[optind_av]);
return (PK_ERR_USAGE);
}
}
argc -= optind_av;
argv += optind_av;
if (argc) {
return (PK_ERR_USAGE);
}
if (outfile == NULL) {
outfile = basename(url);
}
fullpath = get_fullpath(dir, outfile);
if (fullpath == NULL) {
cryptoerror(LOG_STDERR, gettext("Incorrect dir or outfile "
"option value \n"));
return (PK_ERR_USAGE);
}
if (verify_file(fullpath) != KMF_OK) {
cryptoerror(LOG_STDERR,
gettext("Warning: file \"%s\" exists, "
"will be overwritten."), fullpath);
if (yesno(gettext("Continue with download? "),
gettext("Respond with yes or no.\n"), B_FALSE) == B_FALSE) {
return (0);
}
}
if (url == NULL) {
cryptoerror(LOG_STDERR, gettext("A URL must be specified\n"));
rv = PK_ERR_USAGE;
goto end;
}
if (http_proxy == NULL)
http_proxy = getenv("http_proxy");
if (http_proxy != NULL) {
char *ptmp = http_proxy;
char *proxy_port_s;
if (strncasecmp(ptmp, "http://", 7) == 0)
ptmp += 7;
proxy = strtok(ptmp, ":");
proxy_port_s = strtok(NULL, "\0");
if (proxy_port_s != NULL)
proxy_port = strtol(proxy_port_s, NULL, 0);
else
proxy_port = 8080;
}
if (oclass == 0) {
oclass = PK_CRL_OBJ;
}
if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
cryptoerror(LOG_STDERR, gettext("Error initializing KMF\n"));
rv = PK_ERR_USAGE;
goto end;
}
if (oclass & PK_CRL_OBJ) {
rv = kmf_download_crl(kmfhandle, url, proxy, proxy_port, 30,
fullpath, &format);
} else if (oclass & PK_CERT_OBJ) {
rv = kmf_download_cert(kmfhandle, url, proxy, proxy_port, 30,
fullpath, &format);
}
if (rv != KMF_OK) {
switch (rv) {
case KMF_ERR_BAD_URI:
cryptoerror(LOG_STDERR,
gettext("Error in parsing URI\n"));
rv = PK_ERR_USAGE;
break;
case KMF_ERR_OPEN_FILE:
cryptoerror(LOG_STDERR,
gettext("Error in opening file\n"));
rv = PK_ERR_USAGE;
break;
case KMF_ERR_WRITE_FILE:
cryptoerror(LOG_STDERR,
gettext("Error in writing file\n"));
rv = PK_ERR_USAGE;
break;
case KMF_ERR_BAD_CRLFILE:
cryptoerror(LOG_STDERR, gettext("Not a CRL file\n"));
rv = PK_ERR_USAGE;
break;
case KMF_ERR_BAD_CERTFILE:
cryptoerror(LOG_STDERR,
gettext("Not a certificate file\n"));
rv = PK_ERR_USAGE;
break;
case KMF_ERR_MEMORY:
cryptoerror(LOG_STDERR,
gettext("Not enough memory\n"));
rv = PK_ERR_SYSTEM;
break;
default:
cryptoerror(LOG_STDERR,
gettext("Error in downloading the file.\n"));
rv = PK_ERR_SYSTEM;
break;
}
goto end;
}
if (oclass & PK_CRL_OBJ) {
ch_rv = kmf_check_crl_date(kmfhandle, fullpath);
} else {
ch_rv = kmf_read_input_file(kmfhandle, fullpath, &cert);
if (ch_rv != KMF_OK)
goto end;
if (format == KMF_FORMAT_PEM) {
int len;
ch_rv = kmf_pem_to_der(cert.Data, cert.Length,
&cert_der.Data, &len);
if (ch_rv != KMF_OK)
goto end;
cert_der.Length = (size_t)len;
}
ch_rv = kmf_check_cert_date(kmfhandle,
format == KMF_FORMAT_ASN1 ? &cert : &cert_der);
}
end:
if (ch_rv == KMF_ERR_VALIDITY_PERIOD) {
cryptoerror(LOG_STDERR,
gettext("Warning: the downloaded file is expired.\n"));
} else if (ch_rv != KMF_OK) {
cryptoerror(LOG_STDERR,
gettext("Warning: failed to check the validity.\n"));
}
if (fullpath)
free(fullpath);
kmf_free_data(&cert);
kmf_free_data(&cert_der);
(void) kmf_finalize(kmfhandle);
return (rv);
}