#endif
#ifdef HAVE_OPENSSL_X509_H
#include <openssl/x509.h>
+#include <openssl/x509v3.h>
#include <openssl/x509_vfy.h>
#endif
#include <openssl/bn.h>
*/
#ifdef HAVE_SIGNING_C
-static int cb_check_cert __P((int, X509_STORE_CTX *));
+static int cb_check_cert_local __P((int, X509_STORE_CTX *));
+static int cb_check_cert_remote __P((int, X509_STORE_CTX *));
static void eay_setgentype __P((char *, int *));
static X509 *mem2x509 __P((vchar_t *));
#endif
* this functions is derived from apps/verify.c in OpenSSL0.9.5
*/
int
-eay_check_x509cert(cert, CApath)
+eay_check_x509cert(cert, CApath, local)
vchar_t *cert;
char *CApath;
+ int local;
{
X509_STORE *cert_ctx = NULL;
X509_LOOKUP *lookup = NULL;
cert_ctx = X509_STORE_new();
if (cert_ctx == NULL)
goto end;
- X509_STORE_set_verify_cb_func(cert_ctx, cb_check_cert);
+
+ if (local)
+ X509_STORE_set_verify_cb_func(cert_ctx, cb_check_cert_local);
+ else
+ X509_STORE_set_verify_cb_func(cert_ctx, cb_check_cert_remote);
+
lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file());
if (lookup == NULL)
if (csc == NULL)
goto end;
X509_STORE_CTX_init(csc, cert_ctx, x509, NULL);
+
+#if OPENSSL_VERSION_NUMBER >= 0x00907000L
+ X509_STORE_CTX_set_flags(csc, X509_V_FLAG_CRL_CHECK);
+ X509_STORE_CTX_set_flags(csc, X509_V_FLAG_CRL_CHECK_ALL);
+#endif
+
error = X509_verify_cert(csc);
X509_STORE_CTX_cleanup(csc);
#else
/*
* callback function for verifing certificate.
- * this function is derived from cb() in openssl/apps/s_server.c
+ * Derived from cb() in openssl/apps/s_server.c
+ *
+ * This one is called for certificates obtained from
+ * 'peers_certfile' directive.
*/
static int
-cb_check_cert(ok, ctx)
+cb_check_cert_local(ok, ctx)
int ok;
X509_STORE_CTX *ctx;
{
case X509_V_ERR_CERT_HAS_EXPIRED:
case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
#if OPENSSL_VERSION_NUMBER >= 0x00905100L
- case X509_V_ERR_INVALID_CA:
- case X509_V_ERR_PATH_LENGTH_EXCEEDED:
case X509_V_ERR_INVALID_PURPOSE:
+ case X509_V_ERR_UNABLE_TO_GET_CRL:
#endif
- ok = 1;
- log_tag = LLV_WARNING;
- break;
- default:
+ ok = 1;
+ log_tag = LLV_WARNING;
+ break;
+
+ default:
log_tag = LLV_ERROR;
- }
+ }
+
+
+#ifndef EAYDEBUG
+ plog(log_tag, LOCATION, NULL,
+ "%s(%d) at depth:%d SubjectName:%s\n",
+ X509_verify_cert_error_string(ctx->error),
+ ctx->error,
+ ctx->error_depth,
+ buf);
+#else
+ printf("%d: %s(%d) at depth:%d SubjectName:%s\n",
+ log_tag,
+ X509_verify_cert_error_string(ctx->error),
+ ctx->error,
+ ctx->error_depth,
+ buf);
+#endif
+ }
+ ERR_clear_error();
+
+ return ok;
+}
+
+/*
+ * Similar to cb_check_cert_local() but this one is called
+ * for certificates obtained from the IKE payload.
+ */
+static int
+cb_check_cert_remote(ok, ctx)
+ int ok;
+ X509_STORE_CTX *ctx;
+{
+ char buf[256];
+ int log_tag;
+
+ if (!ok) {
+ X509_NAME_oneline(
+ X509_get_subject_name(ctx->current_cert),
+ buf,
+ 256);
+ switch (ctx->error) {
+ case X509_V_ERR_UNABLE_TO_GET_CRL:
+ ok = 1;
+ log_tag = LLV_WARNING;
+ break;
+ default:
+ log_tag = LLV_ERROR;
+ }
#ifndef EAYDEBUG
plog(log_tag, LOCATION, NULL,
"%s(%d) at depth:%d SubjectName:%s\n",
evp = X509_get_pubkey(x509);
if (!evp) {
+#ifndef EAYDEBUG
plog(LLV_ERROR, LOCATION, NULL, "X509_get_pubkey: %s\n", eay_strerror());
+#endif
return -1;
}
extern vchar_t *eay_str2asn1dn __P((char *, int));
extern int eay_cmp_asn1dn __P((vchar_t *, vchar_t *));
-extern int eay_check_x509cert __P((vchar_t *, char *));
+extern int eay_check_x509cert __P((vchar_t *, char *, int));
extern vchar_t *eay_get_x509asn1subjectname __P((vchar_t *));
extern int eay_get_x509subjectaltname __P((vchar_t *, char **, int *, int));
extern char *eay_get_x509text __P((vchar_t *));
switch (iph1->rmconf->certtype) {
case ISAKMP_CERT_X509SIGN:
error = eay_check_x509cert(&iph1->cert_p->cert,
- lcconf->pathinfo[LC_PATHTYPE_CERT]);
+ lcconf->pathinfo[LC_PATHTYPE_CERT], 0);
break;
default:
plog(LLV_ERROR, LOCATION, NULL,
clear_partialfilelock(const char *hostname)
{
struct file_lock *ifl, *nfl;
+ enum partialfilelock_status pfsret;
/* Clear blocking file lock list */
clear_blockingfilelock(hostname);
* would mess up the iteration. Thus, a next element
* must be used explicitly
*/
-
+restart:
ifl = LIST_FIRST(&nfslocklist_head);
while (ifl != NULL) {
if (strncmp(hostname, ifl->client_name, SM_MAXSTRLEN) == 0) {
/* Unlock destroys ifl out from underneath */
- unlock_partialfilelock(ifl);
+ pfsret = unlock_partialfilelock(ifl);
+ if (pfsret != PFL_GRANTED) {
+ /* Uh oh... there was some sort of problem. */
+ /* If we restart the loop, we may get */
+ /* stuck here forever getting errors. */
+ /* So, let's just abort the whole scan. */
+ syslog(LOG_WARNING, "lock clearing for %s failed: %d",
+ hostname, pfsret);
+ break;
+ }
/* ifl is NO LONGER VALID AT THIS POINT */
+ /* Note: the unlock may deallocate several existing locks. */
+ /* Therefore, we need to restart the scanning of the list, */
+ /* because nfl could be pointing to a freed lock. */
+ goto restart;
}
ifl = nfl;
}
struct file_lock *ifl, *nfl;
struct sharefile *shrfile, *nshrfile;
struct file_share *ifs, *nfs;
+ enum partialfilelock_status pfsret;
/* clear non-monitored blocking file locks */
ifl = LIST_FIRST(&blockedlocklist_head);
}
/* clear non-monitored file locks */
+restart:
ifl = LIST_FIRST(&nfslocklist_head);
while (ifl != NULL) {
nfl = LIST_NEXT(ifl, nfslocklist);
if (((ifl->flags & LOCK_MON) == 0) &&
(strncmp(hostname, ifl->client_name, SM_MAXSTRLEN) == 0)) {
/* Unlock destroys ifl out from underneath */
- unlock_partialfilelock(ifl);
+ pfsret = unlock_partialfilelock(ifl);
+ if (pfsret != PFL_GRANTED) {
+ /* Uh oh... there was some sort of problem. */
+ /* If we restart the loop, we may get */
+ /* stuck here forever getting errors. */
+ /* So, let's just abort the whole scan. */
+ syslog(LOG_WARNING, "unmonitored lock clearing for %s failed: %d",
+ hostname, pfsret);
+ break;
+ }
/* ifl is NO LONGER VALID AT THIS POINT */
+ /* Note: the unlock may deallocate several existing locks. */
+ /* Therefore, we need to restart the scanning of the list, */
+ /* because nfl could be pointing to a freed lock. */
+ goto restart;
}
ifl = nfl;