]> git.ipfire.org Git - thirdparty/FORT-validator.git/commitdiff
Merge from v1.0.0
authorpcarana <pc.moreno2099@gmail.com>
Tue, 27 Aug 2019 20:41:44 +0000 (15:41 -0500)
committerpcarana <pc.moreno2099@gmail.com>
Tue, 27 Aug 2019 20:41:44 +0000 (15:41 -0500)
46 files changed:
.gitignore
README.md
configure.ac
docs/_config.yml
docs/_layouts/default.html
docs/_layouts/home.html [deleted file]
docs/css/fort_project.css [deleted file]
docs/css/fort_validator.css [deleted file]
docs/css/screen.css
docs/doc/incidence.md
docs/doc/installation.md
docs/doc/usage.md
docs/index.md
docs/js/metodos.js
man/fort.8
src/address.c
src/address.h
src/asn1/asn1c/GeneralizedTime.c
src/asn1/signed_data.c
src/asn1/signed_data.h
src/common.c
src/config.c
src/config/uint.c
src/file.c
src/file.h
src/incidence/incidence.c
src/object/certificate.c
src/object/ghostbusters.c
src/object/manifest.c
src/object/manifest.h
src/object/name.c
src/object/name.h
src/object/roa.c
src/object/signed_object.c
src/object/signed_object.h
src/object/tal.c
src/rsync/rsync.c
src/rtr/db/vrp.h
src/rtr/rtr.c
src/slurm/slurm_db.c
src/slurm/slurm_db.h
src/slurm/slurm_loader.c
src/slurm/slurm_parser.c
src/state.c
src/updates_daemon.c
test/Makefile.am

index 5ab788a6d88321c8bf27b9b7f8d2e5a6738a1cd8..4da1a7cf20d93505a4cb144516c7988fd8fb0034 100644 (file)
@@ -86,6 +86,7 @@ src/stamp-h1
 *.rar
 *.tar
 *.zip
+*.asc
 
 # Check Framework
 *.test
index d11676e56167c170aa56ff05dce0b84ef959d42f..32ee19f381ef0418d89d3dc117db24655e39dff1 100644 (file)
--- a/README.md
+++ b/README.md
@@ -2,16 +2,16 @@
 
 An RPKI Validator and RTR Server.
 
-**This software is in beta**
-
 ## Installation
 
 Dependencies:
 
-1. libcrypto ([LibreSSL](http://www.libressl.org/) or [OpenSSL](https://www.openssl.org/))
+1. libcrypto ([LibreSSL](http://www.libressl.org/) or [OpenSSL](https://www.openssl.org/) >= 1.1)
 2. [jansson](https://github.com/akheron/jansson)
 3. [rsync](http://rsync.samba.org/)
 
+The validator is currently supported in *64-bit* OS. A 32-bit OS may face the [Year 2038 problem](https://en.wikipedia.org/wiki/Year_2038_problem) when handling dates at certificates.
+
 After all the dependencies are installed, run:
 
 ```
index 833ad861fb75aa1fba11200420e4b6a63fa798a6..6831fcac5177ab0eaed108d1022af41008de2043 100644 (file)
@@ -3,7 +3,7 @@
 
 AC_PREREQ([2.69])
 # TODO change the bug report address
-AC_INIT([fort], [0.0.2], [ydahhrk@gmail.com])
+AC_INIT([fort], [1.0.0], [fort-validator@nic.mx])
 AC_CONFIG_SRCDIR([src/main.c])
 AM_INIT_AUTOMAKE([subdir-objects])
 
@@ -27,8 +27,8 @@ AC_CHECK_FUNCS([memset socket])
 AC_SEARCH_LIBS([pthread_create], [pthread], [],
        [AC_MSG_ERROR([unable to find the pthread() function])]
 )
-AC_SEARCH_LIBS([d2i_X509_bio], [crypto], [],
-       [AC_MSG_ERROR([unable to find the d2i_X509_bio() function])]
+AC_SEARCH_LIBS([X509_get_version], [crypto], [],
+       [AC_MSG_ERROR([unable to find the X509_get_version() function])]
 )
 AC_SEARCH_LIBS([backtrace],[execinfo],[],
        [AC_MSG_ERROR([unable to find backtrace() function])]
index 31f54f7eaa19bbb8c8d3c330010e59063b2fdea5..1609bacb953dcb85cb6bad1e78ee88725f13bf42 100644 (file)
@@ -7,4 +7,4 @@ defaults:
     values:
       layout: "default"
 
-fort-latest-version: 0.0.2
+fort-latest-version: 1.0.0
index 8260e472766dc81debe4e6aedcbfe0fbf0224e0f..28c701813e0795b2ee62c5af76fbbd501bf3ec4b 100644 (file)
@@ -10,9 +10,7 @@
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
 
        <!-- Styles -->
-       <link href="../css/screen.css" rel="stylesheet" type="text/css">
-       <link href="../css/fort_project.css" rel="stylesheet" type="text/css">
-       <link href="../css/fort_validator.css" rel="stylesheet" type="text/css">
+       <link href="{% if page.url == '/' %}./css/screen.css{% else %}../css/screen.css{% endif %}" rel="stylesheet" type="text/css">
 
        <!-- Site is still under construction, so don't index it -->
        <meta name="robots" content="noindex,nofollow">
 <!-- Header -->
 <header class="site-header">
        <div class="container">
-               <div class="row align-items-end">
+               <div class="row align-items-center">
                        <div class="col">
                                <div class="logo">
-                                       <a href="../index.html" title="" class="d-flex">
-                                               <img src="../img/logo_validador_fort.svg" alt="Fort">
-                                       </a>
+                                       {% if page.url == '/' %}
+                                               <a href="./index.html" title="" class="d-flex">
+                                                       <img src="./img/logo_validador_fort.svg" alt="Fort" width="125px">
+                                               </a>
+                                       {% else %}
+                                               <a href="../index.html" title="" class="d-flex">
+                                                       <img src="../img/logo_validador_fort.svg" alt="Fort" width="125px">
+                                               </a>
+                                       {% endif %}
                                </div>
                        </div>
                        <div class="col-auto">
                                <div class="navigation">
                                        <nav class="site-nav">
                                                <ul>
-                                                       <li>
-                                                               <a class="" href="../index.html">
-                                                                       Home
-                                                               </a>
-                                                       </li>
-                                                       <li><a href="./index.html">
-                                                               Documentation
-                                                       </a></li>
+                                                       {% if page.url == '/' %}
+                                                               <li>
+                                                                       <a class="active-item" href="./index.html">Home</a>
+                                                               </li>
+                                                               <li>
+                                                                       <a href="./doc/index.html">Documentation</a>
+                                                               </li>
+                                                       {% else %}
+                                                               <li>
+                                                                       <a href="../index.html">Home</a>
+                                                               </li>
+                                                               <li><a class="active-item" href="./index.html">Documentation</a>
+                                                               </li>
+                                                       {% endif %}
+
                                                </ul>
                                        </nav>
 
        </div>
 </header>
 
-<section class="site-section">
+<section class="site-section section-h-full">
        <div class="container">
+               <div class="row">
+                       {% if (page.url.size} > 5 %}
+                       <div class="col-lg-3">
+                               <aside class="site-aside">
+                                       <ul class="list-bullet">
 
-               {{ content }}
+                                               <li>
+                                                       <a class="item-menu{% if page.url == '/doc/intro-rpki.html' %} active{% endif %}" href="intro-rpki.html">Introduction to RPKI</a>
+                                               </li>
+                                               <li>
+                                                       <a class="item-menu{% if page.url == '/doc/intro-fort.html' %} active{% endif %}" href="intro-fort.html">Introduction to Fort</a>
+                                               </li>
+                                               <li>
+                                                       <a class="item-menu{% if page.url == '/doc/installation.html' %} active{% endif %}" href="installation.html">Compilation and Installation</a>
+                                               </li>
+                                               <li>
+                                                       <a class="item-menu{% if page.url == '/doc/run.html' %} active{% endif %}" href="run.html">Running Fort</a>
+                                               </li>
+                                               <li>
+                                                       <a class="item-menu{% if page.url == '/doc/usage.html' %} active{% endif %}" href="usage.html">Fort usage</a>
+                                               </li>
+                                               <li>
+                                                       <a class="item-menu{% if page.url == '/doc/slurm.html' %} active{% endif %}" href="slurm.html">SLURM</a>
+                                               </li>
+                                               <li>
+                                                       <a class="item-menu{% if page.url == '/doc/incidence.html' %} active{% endif %}" href="incidence.html">Incidences</a>
+                                               </li>
+                                       </ul>
+                               </aside>
+                       </div>
+                       {% endif %}
+                       <div class="col">
+                               <article class="article-section">
+                               {{ content }}
+                               </article>
+                       </div>
+               </div>
        </div>
 </section>
 <!-- Footer -->
 <footer class="site-footer">
        <div class="container">
                <div class="row">
-                       <div class="col justify-content-center">
-                               <a href="https://github.com/NICMx/FORT-validator" target="_blank" title="" class="d-flex">
-                                       <img src="../img/GitHub-Mark-Light-120px-plus.png" alt="Git">
+                       <div class="col">
+                               <a href="https://github.com/NICMx/FORT-validator" target="_blank" title="" class="d-flex justify-content-center">
+                                       <img src="{% if page.url == '/' %}./img/GitHub-Mark-Light-120px-plus.png{% else %}../img/GitHub-Mark-Light-120px-plus.png{% endif %}" alt="Git" width="40">
                                </a>
                        </div>
                </div>
 <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
 
 <!-- APP JS -->
-<script src="../js/metodos.js" type="text/javascript"></script>
+<script src="{% if page.url == '/' %}./js/metodos.js{% else %}../js/metodos.js{% endif %}" type="text/javascript"></script>
 
 
 </body>
diff --git a/docs/_layouts/home.html b/docs/_layouts/home.html
deleted file mode 100644 (file)
index a94d9fe..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-       <meta http-equiv="content-type" content="text/html; charset=utf-8" />
-       <title>{{ page.title }}</title>
-       <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
-
-       <!-- Bootstrap CSS -->
-       <!--<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">-->
-       <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
-
-       <!-- Styles -->
-       <link href="./css/screen.css" rel="stylesheet" type="text/css">
-       <link href="./css/fort_project.css" rel="stylesheet" type="text/css">
-       <link href="./css/fort_validator.css" rel="stylesheet" type="text/css">
-
-       <!-- Site is still under construction, so don't index it -->
-       <meta name="robots" content="noindex,nofollow">
-</head>
-
-<body>
-<!-- Header -->
-<header class="site-header">
-       <div class="container">
-               <div class="row align-items-end">
-                       <div class="col">
-                               <div class="logo">
-                                       <a href="./index.html" title="" class="d-flex">
-                                               <img src="./img/logo_validador_fort.svg" alt="Fort">
-                                       </a>
-                               </div>
-                       </div>
-                       <div class="col-auto">
-                               <div class="menu-open">
-                                       <span></span>
-                                       <span></span>
-                                       <span></span>
-                               </div>
-                               <div class="navigation">
-                                       <nav class="site-nav">
-                                               <ul>
-                                                       <li>
-                                                               <a class="" href="./index.html">
-                                                                       Home
-                                                               </a>
-                                                       </li>
-                                                       <li><a href="./doc/index.html">
-                                                               Documentation
-                                                       </a></li>
-                                               </ul>
-                                       </nav>
-
-                               </div>
-                       </div>
-               </div>
-       </div>
-</header>
-
-<section class="site-section">
-       <div class="container">
-
-               {{ content }}
-       </div>
-</section>
-<!-- Footer -->
-<footer class="site-footer">
-       <div class="container">
-               <div class="row">
-                       <div class="col justify-content-center">
-                               <a href="https://github.com/NICMx/FORT-validator" target="_blank" title="" class="d-flex">
-                                       <img src="./img/GitHub-Mark-Light-120px-plus.png" alt="Git">
-                               </a>
-                       </div>
-               </div>
-       </div>
-</footer>
-
-<div class="js-overlay overlay-content"></div>
-
-<!-- Bootstrap js -->
-<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
-<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
-<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
-
-<!-- APP JS -->
-<script src="./js/metodos.js" type="text/javascript"></script>
-
-
-</body>
-</html>
diff --git a/docs/css/fort_project.css b/docs/css/fort_project.css
deleted file mode 100644 (file)
index f63bbf6..0000000
+++ /dev/null
@@ -1,401 +0,0 @@
-@import url("https://fonts.googleapis.com/css?family=Roboto:400,700,900");
-.bg-grey {
-       background: #f5f5f5; }
-
-.bg-blue-dark {
-       background: #10242d; }
-
-.site-nav ul,
-.site-nav ul li {
-       margin: 0;
-       padding: 0;
-       list-style-type: none; }
-ul.list-bullet li,
-ul li.list-bullet li {
-       margin-bottom: 5px; }
-ul.list-bullet li:before,
-ul li.list-bullet li:before {
-       content: "•";
-       color: #3389ff;
-       margin-right: 5px;
-       margin-left: 10px;
-       font-size: 16px; }
-
-.text-white,
-.text-white * {
-       color: white; }
-
-.text-blue-light,
-.text-blue-light * {
-       color: #3389ff !important; }
-
-.text-blue-dark,
-.text-blue-dark * {
-       color: #10242d !important; }
-
-figure img {
-       max-width: 100%; }
-
-* {
-       color: white;
-       font-family: "Roboto", sans-serif;
-}
-
-h1, h2, h3, h4,
-h1 *, h2 *, h3 *, h4 * {
-       color: white;
-       font-weight: 300;
-       margin-bottom: .5rem;}
-
-h2.text-blue-light, h2.text-blue-light * {
-       font-size: 4.4rem; }
-
-strong {
-       font-weight: 700; }
-
-.text-high,
-.text-high * {
-       font-size: 1.38rem;
-       font-weight: 300;
-       line-height: normal; }
-@media (max-width: 768px) {
-       .text-high,
-       .text-high * {
-               font-size: 1rem; } }
-
-.text-high {
-       margin: 40px 0; }
-@media (max-width: 768px) {
-       .text-high {
-               margin: 20px 0; } }
-
-@media (max-width: 1024px) {
-       .text-right {
-               text-align: left !important; } }
-
-a , a*{
-       color: #3389ff;
-       transition: all 0.5s ease;
-       -moz-transition: all 0.5s ease;
-       -ms-transition: all 0.5s ease;
-       -webkit-transition: all 0.5s ease; }
-a:hover, a:focus {
-       text-decoration: none; }
-
-body {
-       background: #152c38;
-       padding-top: 120px;
-       margin: 0;
-       margin-bottom: 120px;}
-@media (max-width: 768px) {
-       body {
-               padding-top: 60px; } }
-
-.site-header {
-       position: fixed;
-       top: 0;
-       right: 0;
-       height: 120px;
-       width: 100%;
-       background-color: #152c38;
-       transition: all 0.5s ease;
-       -moz-transition: all 0.5s ease;
-       -ms-transition: all 0.5s ease;
-       -webkit-transition: all 0.5s ease;
-       z-index: 2;
-       padding: 40px 0; }
-.site-header .logo a {
-       align-items: flex-end; }
-.site-header .logo a img {
-       margin-right: 20px;
-       /*width: 150px; }*/
-               height: 70px;}
-.site-header .logo a h1 {
-       margin: 0; }
-.site-header.small-header {
-       background: #10242d;
-       height: 80px;
-       padding: 10px 0; }
-.site-header.small-header .logo a img {
-       /*width: 100px;*/
-       height: 60px;}
-.site-header.small-header .small-nav {
-       margin-bottom: 0; }
-@media (max-width: 768px) {
-       .site-header {
-               background: #10242d;
-               height: 80px;
-               padding: 20px 0; }
-       .site-header .logo a img {
-               /*width: 100px; }*/
-               height: 60px;}
-       .site-header .small-nav {
-               margin-bottom: 0; }
-       .site-header.small-header {
-               padding: 20px 0; } }
-
-.site-footer {
-       position: absolute;
-       bottom: 0;
-       width: 100%;
-       height: 120px;
-       background: #09181e;
-       padding: 30px 0; }
-.site-footer p {
-       margin: 0; }
-
-.site-section {
-       padding: 80px 0; }
-@media (max-width: 768px) {
-       .site-section {
-               padding: 40px 0; } }
-
-.site-aside {
-       background: #10242d;
-       padding: 40px;
-}
-.site-aside a {
-       color: white; }
-@media (min-width: 1024px) {
-       .site-aside{position: fixed;}
-}
-.box {
-       border: 3px solid #3389ff;
-       border-radius: 15px;
-       -moz-border-radius: 15px;
-       -ms-border-radius: 15px;
-       -webkit-border-radius: 15px;
-       height: 320px;
-       padding: 40px; }
-.box h3, .box h3 * {
-       font-size: 14px;
-       font-weight: 700;
-       text-transform: uppercase; }
-.box h4, .box h4 * {
-       color: #3389ff; }
-@media (max-width: 1024px) {
-       .box {
-               border: none;
-               border-bottom: 3px solid #3389ff;
-               border-radius: 0;
-               padding: 0 0 20px 0;
-               height: auto;
-               margin: 20px 0; }
-       .box.last {
-               border: none;
-               padding: 0; } }
-
-.site-nav ul {
-       display: flex; }
-.site-nav ul li a {
-       color: white;
-       font-size: 16px;
-       font-weight: 400;
-       letter-spacing: 1px;
-       padding: 0 15px;
-       text-transform: uppercase; }
-.site-nav ul li a:hover, .site-nav ul li a:focus {
-       color: #3389ff; }
-.site-nav ul li a.active-item {
-       position: relative; }
-.site-nav ul li a.active-item:after {
-       background: #3389ff;
-       content: "";
-       position: absolute;
-       bottom: -10px;
-       left: 50%;
-       height: 2px;
-       width: 30px;
-       transform: translateX(-50%); }
-
-.small-nav {
-       margin-right: 10px;
-       margin-bottom: 30px; }
-.small-nav ul li a, .small-nav ul li a * {
-       color: rgba(245, 245, 245, 0.5);
-       font-size: 12px;
-       font-weight: 300;
-       padding: 0 3px; }
-.small-nav ul li a.active-item, .small-nav ul li a *.active-item {
-       color: #3389ff; }
-.small-nav ul li a.active-item:after, .small-nav ul li a *.active-item:after {
-       display: none; }
-
-@media (max-width: 1024px) {
-       .navigation {
-               display: none;
-               background: #10242d;
-               padding: 40px;
-               position: fixed;
-               top: 0;
-               left: 0;
-               height: 100%;
-               width: 100%;
-               z-index: 2; }
-       .navigation ul {
-               flex-direction: column; }
-       .navigation ul li {
-               border-bottom: 1px solid rgba(51, 137, 255, 0.2); }
-       .navigation ul li a {
-               display: block;
-               font-size: 18px;
-               text-align: center;
-               padding: 20px 0; }
-       .navigation ul li a.active-item {
-               color: #3389ff; }
-       .navigation ul li a.active-item:after {
-               display: none; }
-       .navigation ul li:last-child {
-               border: none; }
-       .navigation .small-nav ul {
-               flex-direction: row; }
-       .navigation .small-nav ul li {
-               border: none; }
-       .navigation .small-nav ul li a {
-               font-size: 12px;
-               padding: 0 3px; } }
-
-.menu-open {
-       display: none; }
-@media (max-width: 1024px) {
-       .menu-open {
-               display: block;
-               cursor: pointer;
-               position: fixed;
-               top: 35px;
-               right: 20px;
-               height: 25px;
-               width: 25px;
-               transform: rotate(0deg);
-               -moz-transform: rotate(0deg);
-               -ms-transform: rotate(0deg);
-               -webkit-transform: rotate(0deg);
-               transition: 0.5s ease-in-out;
-               -moz-transition: 0.5s ease-in-out;
-               -ms-transition: 0.5s ease-in-out;
-               -webkit-transition: 0.5s ease-in-out;
-               z-index: 20; }
-       .menu-open span {
-               background: white;
-               display: block;
-               opacity: 1;
-               position: absolute;
-               top: 0;
-               left: 0;
-               height: 3px;
-               width: 100%;
-               transition: 0.25s ease-in-out;
-               -moz-transition: 0.25s ease-in-out;
-               -ms-transition: 0.25s ease-in-out;
-               -webkit-transition: 0.25s ease-in-out;
-               transform: rotate(0deg);
-               -moz-transform: rotate(0deg);
-               -ms-transform: rotate(0deg);
-               -webkit-transform: rotate(0deg); }
-       .menu-open span:nth-child(1), .menu-open span:nth-child(2), .menu-open span:nth-child(3) {
-               transform-origin: left center;
-               -moz-transform-origin: left center;
-               -ms-transform-origin: left center;
-               -webkit-transform-origin: left center; }
-       .menu-open span:nth-child(1) {
-               top: 0px; }
-       .menu-open span:nth-child(2) {
-               top: 6px; }
-       .menu-open span:nth-child(3) {
-               top: 12px; }
-       .menu-open span:hover, .menu-open span:focus {
-               background: #006cff; }
-       .menu-open.clic span:nth-child(1) {
-               transform: rotate(45deg);
-               -moz-transform: rotate(45deg);
-               -ms-transform: rotate(45deg);
-               -webkit-transform: rotate(45deg);
-               position: absolute;
-               top: 0;
-               left: 0; }
-       .menu-open.clic span:nth-child(2) {
-               width: 0%;
-               opacity: 0; }
-       .menu-open.clic span:nth-child(3) {
-               transform: rotate(-45deg);
-               -moz-transform: rotate(-45deg);
-               -ms-transform: rotate(-45deg);
-               -webkit-transform: rotate(-45deg);
-               position: absolute;
-               top: 17px;
-               left: 0; } }
-
-.container {
-       max-width: 1250px;
-       padding-left: 30px;
-       padding-right: 30px; }
-
-.btn {
-       background: #66d394;
-       border-radius: 30px;
-       -moz-border-radius: 30px;
-       -ms-border-radius: 30px;
-       -webkit-border-radius: 30px;
-       color: white;
-       padding: 10px 30px;
-       text-transform: uppercase;
-       font-size: 13px;
-       font-weight: 700;
-       letter-spacing: 1px; }
-.btn:hover, .btn:focus {
-       background: #3ec878;
-       color: white; }
-.btn * {
-       font-size: 13px;
-       font-weight: 700;
-       text-transform: uppercase; }
-
-.i-black {
-       background: #5b5b5b; }
-
-.i-white {
-       background: white; }
-
-.sponsor{
-       display: flex;
-       align-items: center;}
-
-.sponsor a img{
-       max-height: 100px;
-       max-width: 224px;
-}
-
-html {
-       min-height: 100%;
-       position: relative;
-}
-
-footer figure img {
-       max-width: 22rem; }
-
-.alert-fort {
-       color: #383d41;
-       background-color: #b1b3b7;
-       border-color: #d6d8db;
-}
-
-.card-team {
-       background-color: unset;
-}
-
-ul.list-bullet-top > li,
-ul li.list-bullet-top >li {
-       margin-bottom: 10px; }
-ul.list-bullet-top > li:before,
-ul li.list-bullet-top > li:before {
-       content: "o";
-       color: #3389ff;
-       margin-right: 5px;
-       font-size: 16px; }
-
-.about-section{
-       margin-top: -120px;
-       padding-top: 120px;
-}
-
-/*# sourceMappingURL=app.css.map */
diff --git a/docs/css/fort_validator.css b/docs/css/fort_validator.css
deleted file mode 100644 (file)
index 813673e..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-/** {
-       font-size: 1rem;
-}*/
-
-body {
-       margin-bottom: 80px;
-}
-
-.site-footer {
-       height: 80px;
-       padding: 20px 0; }
-
-
-blockquote {
-       background-color: #b1b3b7;
-       margin: 0 1.5em 1.5em 1.5em;
-}
-
-code, code span {
-       color: white;
-       font-family: monospace;
-       font-size: inherit;
-       background-color: unset;
-}
-
-pre code{
-       color: white;
-       background-color: black;
-       font-size: 1rem;
-}
-pre code.terminal {
-       color: white;
-}
-
-.language-bash > .nb {
-       color: white;
-}
-
-p img {
-       background-color: #b1b3b7;
-}
-
-.site-footer a img {
-       margin: auto;
-       max-height: 40px;
-}
-
-
-h2{
-       margin-top: 2.5rem;
-}
-h3{
-       margin-top: 2.5rem;
-}
-h4{
-       margin-top: 1.5rem;
-}
-p{
-       margin-bottom: 0.5rem;
-}
-
-td, th {
-       text-align: center;
-       border-width: 1px;
-       border-style: solid;
-       border-color: #b1b3b7;
-       border-image: initial;
-       padding: 0.5rem;
-}
-
-pre code a{
-       color: #00bfFF;
-}
-
-figure {
-       margin-block-start: 1em;
-       margin-block-end: 1em;
-       margin-inline-start: 1.5em;
-       margin-inline-end: 1.5em;
-}
-
index 3349377b9e7fe274c91a531362d48e95b926c340..bde9bee05f17c4bfa021cf794c473788f199d9c8 100644 (file)
-blockquote {
-       padding: 1em;
-       border-radius: 3px;
-       border: 1px solid #ddd;
-       color: #404040;
-       background-color: #f0f6ff;
-       margin-left: 3em;
-       margin-right: 3em;
+@import url("https://fonts.googleapis.com/css?family=Roboto:300,400,400i,700,900|Roboto+Mono:400,500&display=swap");
+* {
+       color: white;
+       font-family: "Roboto", sans-serif;
+       font-size: 16px; }
+
+h1, h2, h3, h4,
+h1 *, h2 *, h3 *, h4 * {
+       color: white;
+       font-weight: 400;}
+
+h1, h1 * {
+       font-size: 35px;
+       margin-bottom: 20px; }
+@media (max-width: 768px) {
+       h1, h1 * {
+               font-size: 30px; } }
+h1.title-big, h1.title-big *, h1 *.title-big, h1 *.title-big * {
+       margin: 0;
+       font-size: 70px;
+       font-weight: 300; }
+h1.title-big strong, h1.title-big * strong, h1 *.title-big strong, h1 *.title-big * strong {
+       font-weight: 700; }
+@media (max-width: 768px) {
+       h1.title-big, h1.title-big *, h1 *.title-big, h1 *.title-big * {
+               font-size: 30px; } }
+
+h2, h2 * {
+       font-size: 26px;
 }
+@media (max-width: 768px) {
+       h2, h2 * {
+               font-size: 22px; } }
 
-code {
-       background-color: #f8f8f8;
+h3, h3 * {
+       font-size: 20px;
+}
+@media (max-width: 768px) {
+       h3, h3 * {
+               font-size: 18px; } }
+
+h4, h4 * {
+       font-size: 18px; }
+
+strong {
+       font-weight: 700; }
+
+.text-high,
+.text-high * {
+       font-size: 22px;
+       font-weight: 300;
+       line-height: normal; }
+@media (max-width: 768px) {
+       .text-high,
+       .text-high * {
+               font-size: 16px; } }
+
+.text-high {
+       margin: 40px 0; }
+@media (max-width: 768px) {
+       .text-high {
+               margin: 20px 0; } }
+
+@media (max-width: 1024px) {
+       .text-right {
+               text-align: left !important; } }
+
+a {
+       color: #009DCB;
+       transition: all 0.5s ease;
+       -moz-transition: all 0.5s ease;
+       -ms-transition: all 0.5s ease;
+       -webkit-transition: all 0.5s ease; }
+a:hover, a:focus {
+       text-decoration: none; }
+
+body {
+       background: #152c38;
+       padding-top: 120px; }
+@media (max-width: 768px) {
+       body {
+               padding-top: 60px; } }
+
+.site-header {
+       background: #10242d;
+       position: fixed;
+       top: 0;
+       right: 0;
+       height: 100px;
+       width: 100%;
+       transition: all 0.5s ease;
+       -moz-transition: all 0.5s ease;
+       -ms-transition: all 0.5s ease;
+       -webkit-transition: all 0.5s ease;
+       z-index: 2;
+       padding: 20px 0; }
+.site-header .logo a {
+       align-items: flex-end; }
+.site-header .logo a img {
+       margin-right: 20px;
+       height: 60px; }
+.site-header .logo a h1 {
+       margin: 0; }
+.site-header.small-header {
+       background: #10242d;
+       height: 80px;
+       padding: 10px 0; }
+.site-header.small-header .small-nav {
+       margin-bottom: 0; }
+@media (max-width: 768px) {
+       .site-header {
+               background: #10242d;
+               height: 80px;
+               padding: 20px 0; }
+       .site-header .logo a img {
+               height: 40px; }
+       .site-header .small-nav {
+               margin-bottom: 0; }
+       .site-header.small-header {
+               padding: 20px 0; } }
+
+.site-footer {
+       background: #09181e;
+       height: 100px;
+       padding: 20px 0; }
+.site-footer p {
+       margin: 0; }
+.site-footer .logos-fort {
+       max-width: 300px; }
+@media (max-width: 768px) {
+       .site-footer {
+               height: auto;
+               text-align: center; }
+       .site-footer .text-right {
+               text-align: center !important; } }
+.site-footer a.d-flex {
+       margin: 15px 0 10px 0; }
+
+.site-section {
+       padding: 80px 0; }
+@media (max-width: 768px) {
+       .site-section {
+               padding: 40px 0; } }
+@media (min-width: 768px) {
+       .site-section.section-h-full {
+               min-height: calc(100vh - (120px + 100px)); } }
+
+.article-section {
+       margin-bottom: 40px;
 }
+.article-section .about-section {
+       margin: 40px 0; }
+.article-section .about-section:last-child {
+       margin: 0; }
+
+.site-aside {
+       background: #10242d;
+       padding: 40px;
+       position: sticky;
+       top: 120px;
+       margin-bottom: 20px; }
+.site-aside a {
+       color: white; }
+.site-aside a.active , .site-aside a.active * {
+       color: #009DCB; }
+
+.box {
+       border: 3px solid #009DCB;
+       border-radius: 15px;
+       -moz-border-radius: 15px;
+       -ms-border-radius: 15px;
+       -webkit-border-radius: 15px;
+       height: 330px;
+       padding: 40px; }
+.box h3, .box h3 * {
+       color: white;
+       margin: 0;
+       font-size: 14px;
+       font-weight: 700;
+       text-transform: uppercase; }
+.box h4, .box h4 * {
+       color: #009DCB;
+       margin: 10px 0; }
+@media (max-width: 1024px) {
+       .box {
+               border: none;
+               border-radius: 0;
+               padding: 0 0 20px 0;
+               height: auto;
+               margin: 40px 0; }
+       .box.last {
+               border: none;
+               padding: 0; } }
+
+.sponsor {
+       display: flex;
+       align-items: center; }
+@media (max-width: 460px) {
+       .sponsor a img {
+               max-width: 150px; } }
+
+.card {
+       background: transparent; }
+
+.site-nav ul {
+       display: flex; }
+.site-nav ul li a {
+       color: white;
+       font-size: 14px;
+       font-weight: 400;
+       letter-spacing: 1px;
+       padding: 0 10px;
+       text-transform: uppercase; }
+.site-nav ul li a:hover, .site-nav ul li a:focus {
+       color: #009DCB; }
+.site-nav ul li a.active-item {
+       position: relative; }
+.site-nav ul li a.active-item:after {
+       background: #009DCB;
+       content: "";
+       position: absolute;
+       bottom: -10px;
+       left: 50%;
+       height: 2px;
+       width: 30px;
+       transform: translateX(-50%); }
+
+.small-nav {
+       margin: 0 10px 10px 0; }
+.small-nav ul li a, .small-nav ul li a * {
+       color: rgba(245, 245, 245, 0.5);
+       font-size: 12px;
+       font-weight: 300;
+       padding: 0 3px; }
+.small-nav ul li a.active-item, .small-nav ul li a *.active-item {
+       color: #009DCB; }
+.small-nav ul li a.active-item:after, .small-nav ul li a *.active-item:after {
+       display: none; }
+
+@media (max-width: 1024px) {
+       .navigation {
+               background: #10242d;
+               display: none;
+               padding: 40px;
+               position: fixed;
+               top: 0;
+               left: 0;
+               height: 100%;
+               width: 100%;
+               z-index: 2; }
+       .navigation ul {
+               flex-direction: column; }
+       .navigation ul li {
+               border-bottom: 1px solid rgba(51, 137, 255, 0.2); }
+       .navigation ul li a {
+               display: block;
+               font-size: 18px;
+               text-align: center;
+               padding: 20px 0; }
+       .navigation ul li a.active-item {
+               color: #009DCB; }
+       .navigation ul li a.active-item:after {
+               display: none; }
+       .navigation ul li:last-child {
+               border: none; }
+       .navigation .small-nav ul {
+               flex-direction: row; }
+       .navigation .small-nav ul li {
+               border: none; }
+       .navigation .small-nav ul li a {
+               font-size: 12px;
+               padding: 0 3px; } }
+
+.menu-open {
+       display: none; }
+@media (max-width: 1024px) {
+       .menu-open {
+               display: block;
+               cursor: pointer;
+               position: fixed;
+               top: 35px;
+               right: 20px;
+               height: 25px;
+               width: 25px;
+               transform: rotate(0deg);
+               -moz-transform: rotate(0deg);
+               -ms-transform: rotate(0deg);
+               -webkit-transform: rotate(0deg);
+               transition: 0.5s ease-in-out;
+               -moz-transition: 0.5s ease-in-out;
+               -ms-transition: 0.5s ease-in-out;
+               -webkit-transition: 0.5s ease-in-out;
+               z-index: 20; }
+       .menu-open span {
+               background: white;
+               display: block;
+               opacity: 1;
+               position: absolute;
+               top: 0;
+               left: 0;
+               height: 3px;
+               width: 100%;
+               transition: 0.25s ease-in-out;
+               -moz-transition: 0.25s ease-in-out;
+               -ms-transition: 0.25s ease-in-out;
+               -webkit-transition: 0.25s ease-in-out;
+               transform: rotate(0deg);
+               -moz-transform: rotate(0deg);
+               -ms-transform: rotate(0deg);
+               -webkit-transform: rotate(0deg); }
+       .menu-open span:nth-child(1), .menu-open span:nth-child(2), .menu-open span:nth-child(3) {
+               transform-origin: left center;
+               -moz-transform-origin: left center;
+               -ms-transform-origin: left center;
+               -webkit-transform-origin: left center; }
+       .menu-open span:nth-child(1) {
+               top: 0px; }
+       .menu-open span:nth-child(2) {
+               top: 6px; }
+       .menu-open span:nth-child(3) {
+               top: 12px; }
+       .menu-open span:hover, .menu-open span:focus {
+               background: #006cff; }
+       .menu-open.clic span:nth-child(1) {
+               transform: rotate(45deg);
+               -moz-transform: rotate(45deg);
+               -ms-transform: rotate(45deg);
+               -webkit-transform: rotate(45deg);
+               position: absolute;
+               top: 0;
+               left: 0; }
+       .menu-open.clic span:nth-child(2) {
+               width: 0%;
+               opacity: 0; }
+       .menu-open.clic span:nth-child(3) {
+               transform: rotate(-45deg);
+               -moz-transform: rotate(-45deg);
+               -ms-transform: rotate(-45deg);
+               -webkit-transform: rotate(-45deg);
+               position: absolute;
+               top: 17px;
+               left: 0; } }
+
+pre {
+       background: #10242d;
+       border-radius: 5px;
+       -moz-border-radius: 5px;
+       -ms-border-radius: 5px;
+       -webkit-border-radius: 5px;
+       padding: 20px;
+       margin: 0 0 1rem 0;
+       max-width: 800px;}
+
 pre code {
+       color: white; }
+
+
+code {
+       color: white;
+       font-family: "Roboto Mono", monospace;}
+code span {
+       color: white;
+       font-family: "Roboto Mono", monospace;
+       font-size: inherit;
+       background-color: unset; }
+code a {
+       color: #00bfFF; }
+
+blockquote {
+       background: rgba(51, 137, 255, 0.2);
+       border-radius: 5px;
+       -moz-border-radius: 5px;
+       -ms-border-radius: 5px;
+       -webkit-border-radius: 5px;
+       padding: 20px;
+       margin-bottom: 20px; }
+blockquote p, blockquote p em {
+       font-size: 90%;
+       margin: 0; }
+
+.language-bash > .c {
+       color: #3CB371; }
+
+.language-bash > .nt {
+       color: #DDA0DD; }
+
+.language-bash > .s2 {
+       color: #00bfFF; }
+
+.language-bash > .nb {
+       color: white; }
+
+.highlighter-rouge {
+       border: solid 1px rgba(51, 137, 255, 0.2);
+       font-size: 80%;
+       padding: 1px 5px;
+       background: #10242d;
+}
+
+a > .highlighter-rouge{
+       color: #009DCB;
+}
+
+
+.container {
+       max-width: 1180px;
+       padding-left: 30px;
+       padding-right: 30px; }
+
+.btn {
+       background: #66d394;
+       border-radius: 30px;
+       -moz-border-radius: 30px;
+       -ms-border-radius: 30px;
+       -webkit-border-radius: 30px;
+       color: white;
+       padding: 10px 30px;
+       text-transform: uppercase;
+       font-size: 13px;
+       font-weight: 700;
+       letter-spacing: 1px; }
+.btn:hover, .btn:focus {
+       background: #3ec878;
+       color: white; }
+.btn * {
+       font-size: 13px;
+       font-weight: 700;
+       text-transform: uppercase; }
+
+.i-black {
+       background: #5b5b5b; }
+
+.i-white {
+       background: white; }
+
+.bg-grey {
+       background: #f5f5f5; }
+
+.bg-blue-dark {
+       background: #10242d; }
+
+ul,
+ul li {
+       margin: 0;
+       padding: 0;
+       list-style-type: none; }
+ul.list-bullet li,
+ul li.list-bullet li {
+       margin-bottom: 10px; }
+ul.list-bullet li:before,
+ul li.list-bullet li:before {
+       content: "o";
+       color: #009DCB;
+       margin-right: 10px;
+       font-size: 16px; }
+ul.list-bullet li ul,
+ul li.list-bullet li ul {
+       margin: 20px 0 20px 20px; }
+ul.list-bullet li ul li,
+ul li.list-bullet li ul li {
+       margin: 0; }
+ul.list-bullet li ul li:before,
+ul li.list-bullet li ul li:before {
+       content: "-";
+       color: #009DCB;
+       margin-right: 5px;
+       font-size: 16px; }
+
+.text-white,
+.text-white * {
+       color: white; }
+
+.text-blue-light,
+.text-blue-light * {
+       color: #009DCB !important; }
+
+.text-blue-dark,
+.text-blue-dark * {
+       color: #10242d !important; }
+
+figure img {
+       max-width: 100%; }
+
+/*# sourceMappingURL=app.css.map */
+
+.article-section > p > img {
+       background-color: rgba(51, 137, 255, 0.2);
+       max-width: 100%;
+}
+
+h3{
+       font-size: 20px;
+       padding: 115px 0 0px 0;
+       margin-bottom: -80px;
        display: block;
-       overflow: auto;
-       padding: 1em;
+       position: relative;
+       top: -90px;
+       z-index: -1;
 }
-pre code.terminal {
-       color: lightgray;
-       background-color: black;
+
+h2{
+       padding: 130px 0 0px 0;
+       margin-bottom: -100px;
+       display: block;
+       position: relative;
+       top: -110px;
+       z-index: -1;
 }
 
-.language-bash > .c {
-       color: #3CB371;
+h4{
+       padding: 115px 0 0px 0;
+       margin-bottom: -100px;
+       display: block;
+       position: relative;
+       top: -110px;
+       z-index: -1;
 }
-.language-bash > .nt {
-       color: #DDA0DD;
+
+a:hover {
+       color: #3389ff;
 }
-.language-bash > .s2 {
-       color: #00bfFF;
+
+.article-section ul,
+.article-section ul li{
+       margin: 0 0 5px 10px;
+       list-style-type: circle; }
+
+ol{
+       padding-inline-start: 20px;}
+
+td, th {
+       text-align: center;
+       border-width: 1px;
+       border-style: solid;
+       border-color: #b1b3b7;
+       border-image: initial;
+       padding: 0.5rem;
+}
+
+div.highlighter-rouge{
+       margin-bottom: 1rem;
+       border: none;
 }
+
+table {
+       margin-bottom: 1rem;
+}
\ No newline at end of file
index 91fa9c984e3c2c9b546f76fa6ed23fb52a3e9e77..e084139b78040761c6d71161216edd008ce7168e 100644 (file)
@@ -17,7 +17,7 @@ title: Incidence
 
 The RPKI RFCs define fairly strict profiles for RPKI objects, and are unequivocal in stating that incorrectly-formed objects are supposed to be rejected by Relying Party validation. In practice, however, this does not prevent a significant amount of Certificate Authorities from issuing incorrect objects.
 
-By default, Fort is as pedantic as it can possibly be. The `incidence` section of its configuration file is a means to modify its behavior upon encountering profile violations that, from experience, are often overlooked.
+By default, Fort is lax with some of this bad practices. The `incidence` section of its configuration file is a means to modify its behavior upon encountering profile violations that, from experience, are often overlooked.
 
 ## `incidences` definition
 
@@ -26,13 +26,13 @@ By default, Fort is as pedantic as it can possibly be. The `incidence` section o
 ```
 "incidences": [
        {
-               "name": "Signed Object's hash algorithm has NULL object as parameters",
+               "name": "incid-hashalg-has-params",
                "action": "warn"
        }
 ]
 ```
 
-`name` is the identifier of an incidence. It is case-sensitive and developer-defined. It states the particular error condition that will be handled by the remaining field.
+`name` is the identifier of an incidence. It is case-sensitive and developer-defined. It states an ID of the particular error condition that will be handled by the remaining field.
 
 `action` is an enumeration that states the outcome of a violation of the corresponding incidence. It can take one of three values:
 
@@ -40,7 +40,7 @@ By default, Fort is as pedantic as it can possibly be. The `incidence` section o
 2. `warn`: Print error message in `warning` log level, continue validation as if nothing happened.
 3. `ignore`: Do not print error message, continue validation as if nothing happened.
 
-By Fort's pedantic nature, most incidences have an `action` of `error` by default.
+Since most of the incidences are result of a bad practice at the global RPKI, they have an `action` of `ignore` by default. If a strict behavior is desired, then the corresponding incidences should be configured with an `action` of `error`.
 
 ## Incidence types
 
@@ -48,6 +48,9 @@ Presently, there is only one incidence type defined. This list is expected to gr
 
 ### Signed Object's hash algorithm has NULL object as parameters
 
+- **Name:** `incid-hashalg-has-params`
+- **Default action:** `ignore`
+
 [RFC 6488](https://tools.ietf.org/html/rfc6488) (RPKI Signed Objects) defers digest algorithm specification to RFC 6485:
 
 ```
@@ -76,7 +79,7 @@ Presently, there is only one incidence type defined. This list is expected to gr
    parameters field;
 ```
 
-As of 2019-05-21, many signed objects in the global RPKI break this rule.
+As of 2019-08-12, many signed objects in the global RPKI break this rule.
 
 If not `ignore`d, Fort will report this incidence with the following error message:
 
index 6dd3ee749968983c572fffce10de353ff54e9915..7aabae744a48bbae0cb89f1719018d0082b256c9 100644 (file)
@@ -13,21 +13,26 @@ title: Compilation and Installation
 3. [Option 2: Compiling and installing the release tarball](#option-2-compiling-and-installing-the-release-tarball)
        1. [Debian version](#debian-version)
        2. [OpenBSD version](#openbsd-version)
+       3. [CentOS version](#centos-version)
+       4. [Fedora version](#fedora-version)
+       5. [openSUSE Leap version](#opensuse-leap-version)
+       6. [FreeBSD version](#freebsd-version)
+       7. [Slackware version](#slackware-version)
 4. [Option 3: Compiling and installing the git repository](#option-3-compiling-and-installing-the-git-repository)
 
 ## Dependencies
 
-> Note: I'm only including this section in case you intend to install Fort in an unlisted OS (and therefore need a little research). For Debians and OpenBSD, just follow the steps in the sections below.
+> Note: I'm only including this section in case you intend to install Fort in an unlisted OS (and therefore need a little research). For: Debians, OpenBSD, CentOS, Fedora, openSUSE Leap, FreeBSD, and Slackware just follow the steps in the sections below.
 
 The dependencies are
 
 1. [jansson](http://www.digip.org/jansson/)
-2. libcrypto (Either [LibreSSL](http://www.libressl.org/) or [OpenSSL](https://www.openssl.org/))
+2. libcrypto (Either [LibreSSL](http://www.libressl.org/) or [OpenSSL](https://www.openssl.org/) >= 1.1)
 3. [rsync](http://rsync.samba.org/)
 
-## Option 1: Installing the Debian package
+Fort is currently supported in *64-bit* OS. A 32-bit OS may face the [Year 2038 problem](https://en.wikipedia.org/wiki/Year_2038_problem) when handling dates at certificates, and currently there's no work around for this.
 
-> TODO Upload to Debian, add more archs
+## Option 1: Installing the Debian package
 
 {% highlight bash %}
 wget https://github.com/NICMx/FORT-validator/releases/download/v{{ site.fort-latest-version }}/fort_{{ site.fort-latest-version }}-1_amd64.deb
@@ -78,8 +83,131 @@ make install
 exit
 {% endhighlight %}
 
+### CentOS version
+
+The following steps are for CentOS 7, previous versions may require more steps to install Fort validator.
+
+This OS requires additional steps due to its GCC supported version (currently 4.8.5, fort needs >= 4.9 to compile) and default OpenSSL version (currently 1.0.2k, fort needs >= 1.1.0).
+
+**Install dependencies**
+
+OpenSSL devel (openssl-devel) package isn't necessary, if it's previously installed remove it to avoid future conflicts with newer OpenSSL versions.
+
+{% highlight bash %}
+sudo yum install autoconf automake git jansson-devel pkgconfig rsync
+# Install supported GCC to compile OpenSSL
+sudo yum groupinstall "Development Tools"
+{% endhighlight %}
+
+**Upgrade OpenSSL from 1.0.2k to 1.1.0k**
+
+The OpenSSL version must be greater than 1.0, in this case the version 1.1.0k is installed.
+
+{% highlight bash %}
+curl https://www.openssl.org/source/openssl-1.1.0k.tar.gz | tar xvz
+cd openssl-1.1.0k
+./config --prefix=/usr/local --openssldir=/usr/local/openssl
+make
+sudo make install
+# Update library files
+sudo mv libcrypto.so.1.1 libssl.so.1.1 /usr/lib64/
+sudo ln -sfn /usr/local/bin/openssl /usr/bin/openssl
+# Verify installed version
+openssl version
+{% endhighlight %}
+
+**Upgrade GCC**
+
+There are two options to upgrade GCC:
+1. Compile and install a newer version >= 4.9 (slow process).
+2. Use [Software Collections](https://www.softwarecollections.org) (indicated at the following steps).
+
+{% highlight bash %}
+sudo yum install centos-release-scl
+sudo yum install devtoolset-7-gcc
+# Start a session using the upgraded GCC
+scl enable devtoolset-7 bash
+cd ~
+curl -L https://github.com/NICMx/FORT-validator/releases/download/v{{ site.fort-latest-version }}/fort-{{ site.fort-latest-version }}.tar.gz --output fort-{{ site.fort-latest-version }}.tar.gz
+tar xvzf fort-{{ site.fort-latest-version }}.tar.gz
+cd fort-{{ site.fort-latest-version }}
+./configure
+make
+sudo make install
+# Close the 'devtoolset' session
+exit
+{% endhighlight %}
+
+### Fedora version
+
+The following steps are for Fedora 30.
+
+{% highlight bash %}
+sudo yum install autoconf automake gcc make openssl-devel jansson-devel
+
+wget https://github.com/NICMx/FORT-validator/releases/download/v{{ site.fort-latest-version }}/fort-{{ site.fort-latest-version }}.tar.gz
+tar xvzf fort-{{ site.fort-latest-version }}.tar.gz
+cd fort-{{ site.fort-latest-version }}/
+./configure
+make
+sudo make install
+{% endhighlight %}
+
+### openSUSE Leap version
+
+The following steps are for openSUSE Leap 15.1.
+
+{% highlight bash %}
+sudo zypper install autoconf automake gcc libopenssl-devel libjansson-devel
+
+wget https://github.com/NICMx/FORT-validator/releases/download/v{{ site.fort-latest-version }}/fort-{{ site.fort-latest-version }}.tar.gz
+tar xvzf fort-{{ site.fort-latest-version }}.tar.gz
+cd fort-{{ site.fort-latest-version }}/
+./configure
+make
+sudo make install
+{% endhighlight %}
+
+### FreeBSD version
+
+The following steps are for FreeBSD 12.0.
+
+{% highlight bash %}
+su
+pkg install autoconf automake gcc jansson pkgconf rsync
+exit
+
+curl -L https://github.com/NICMx/FORT-validator/releases/download/v{{ site.fort-latest-version }}/fort-{{ site.fort-latest-version }}.tar.gz --output fort-{{ site.fort-latest-version }}.tar.gz
+tar xvzf fort-{{ site.fort-latest-version }}.tar.gz
+cd fort-{{ site.fort-latest-version }}/
+./configure
+make
+su
+make install
+exit
+{% endhighlight %}
+
+### Slackware version
+
+The following steps are for Slackware "current" release (as of 2019-08-12).
+
+All dependencies are included in the current release, so there's no need to install any dependency.
+
+{% highlight bash %}
+wget https://github.com/NICMx/FORT-validator/releases/download/v{{ site.fort-latest-version }}/fort-{{ site.fort-latest-version }}.tar.gz
+tar xvzf fort-{{ site.fort-latest-version }}.tar.gz
+cd fort-{{ site.fort-latest-version }}/
+./configure
+make
+sudo make install
+{% endhighlight %}
+
 ## Option 3: Compiling and installing the git repository
 
+In case you wan't a fresh version of Fort validator, there's this third option. The steps are mostly the same as in [Option 2](#option-2-compiling-and-installing-the-release-tarball), just another dependency (as minimum) must be installed: "git"; and a few steps are included in order to get the source code and generate configuration scripts.
+
+The following example is the processo to clone, compile and install in Debian OS.
+
 {% highlight bash %}
 sudo apt install autoconf automake build-essential git libjansson-dev libssl-dev pkg-config rsync
 
index 5cc881072891d84a024969c580977f8b68b6bf8a..a38b5b8eaf311cf2d1574c24a166c8133173571e 100644 (file)
@@ -136,7 +136,7 @@ Prints program version.
 
 {% highlight bash %}
 $ {{ page.command }} --version
-fort 0.0.1
+fort {{ site.fort-latest-version }}
 {% endhighlight %}
 
 ### `--tal`
@@ -248,6 +248,7 @@ Of course, this is only relevant if the TAL lists more than one URL.
 - **Type:** Integer
 - **Availability:** `argv` and JSON
 - **Default:** 32
+- **Range:** 5--([`UINT_MAX`](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html)--1)
 
 Maximum allowable RPKI tree height. Meant to protect Fort from iterating infinitely due to certificate chain loops.
 
@@ -303,7 +304,7 @@ See the corresponding manual page from your operating system (likely `man 2 list
 - **Type:** Integer
 - **Availability:** `argv` and JSON
 - **Default:** 3600
-- **Range:** 60--[`UINT_MAX`](http://pubs.opengroup.org/onlinepubs/9699919799/)
+- **Range:** 60--[`UINT_MAX`](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html)
 
 Number of seconds the server will sleep between validation cycles.
 
@@ -440,11 +441,11 @@ Path to a JSON file from which additional configuration will be read.
 The configuration options are mostly the same as the ones from the `argv` interface. (See the "Availability" metadata of each field.) Here's a full configuration file example:
 
 <pre><code>{
-       "<a href="#--tal">tal</a>": "/tmp/tal/test.tal",
-       "<a href="#--local-repository">local-repository</a>": "/tmp/repository",
+       "<a href="#--tal">tal</a>": "/tmp/fort/tal/test.tal",
+       "<a href="#--local-repository">local-repository</a>": "/tmp/fort/repository",
        "<a href="#--sync-strategy">sync-strategy</a>": "root",
        "<a href="#--shuffle-uris">shuffle-uris</a>": true,
-       "<a href="#--slurm">slurm</a>": "/tmp/test.slurm",
+       "<a href="#--slurm">slurm</a>": "/tmp/fort/test.slurm",
        "<a href="#--mode">mode</a>": "server",
 
        "server": {
@@ -482,14 +483,14 @@ The configuration options are mostly the same as the ones from the `argv` interf
 
        "<a href="#incidences">incidences</a>": [
                {
-                       "name": "Signed Object's hash algorithm has NULL object as parameters",
+                       "name": "incid-hashalg-has-params",
                        "action": "ignore"
                }
        ],
 
        "output": {
-               "<a href="#--outputroa">roa</a>": "/tmp/fort_roas.csv",
-               "<a href="#--outputbgpsec">bgpsec</a>": "/tmp/fort_bgpsec.csv"
+               "<a href="#--outputroa">roa</a>": "/tmp/fort/roas.csv",
+               "<a href="#--outputbgpsec">bgpsec</a>": "/tmp/fort/bgpsec.csv"
        }
 }
 </code></pre>
@@ -510,25 +511,25 @@ $ cat a.json
 {
        "local-repository": "a",
        "sync-strategy": "root",
-       "maximum-certificate-depth": 1
+       "maximum-certificate-depth": 5
 }
 
 $ cat b.json
 {
        "sync-strategy": "strict"
-       "maximum-certificate-depth": 2
+       "maximum-certificate-depth": 6
 }
 
 $ cat c.json
 {
-       "maximum-certificate-depth": 4
+       "maximum-certificate-depth": 8
 }
 
 $ {{ page.command }} \
        --configuration-file="a.json" \
        --configuration-file="b.json" \
        --configuration-file="c.json"
-$ # local-repository is "a", sync-strategy is "strict" and maximum-certificate-depth is 4
+$ # local-repository is "a", sync-strategy is "strict" and maximum-certificate-depth is 8
 {% endhighlight %}
 
 ### rsync.program
index a3d70661876536d3d41f3aea28bca15885c13407..1c19062fca1b229cb1685b5d68d4b5fb2873d798 100644 (file)
@@ -1,6 +1,5 @@
 ---
 title: Home
-layout: home
 ---
 
 # {{ page.title }}
@@ -11,4 +10,4 @@ The documentation can be found [here](doc/index.html).
 
 ## Status
 
-Fort is currently in beta. Testing is underway.
+Version [{{ site.fort-latest-version }}](https://github.com/NICMx/FORT-validator/releases/tag/v{{ site.fort-latest-version }}){:target="_blank"} is the first official release! Don't forget to read the [docs](doc/index.html).
index 026bc15740cd774e7bdb161e80e4bd68f02cdae9..d613c6b81f799fdc3d1db2e494a49c61a1a7ccc9 100644 (file)
@@ -1,43 +1,31 @@
-$(document).ready(function () {
+$(document).ready(function() {
 
        //  Show nav + overlay-content
-       $('.menu-open').click(function () {
-               if ($(this).hasClass('clic')) {
+       $('.menu-open').click(function() {
+               if($(this).hasClass('clic')){
                        closeNavigation();
-               } else {
+               }else{
                        openNavigation();
                }
                $(this).toggleClass('clic');
        });
 
-       // $('.overlay-content').click(function() {
-       //     closeNavigation();
-       // });
-
-       // $('.menu-close').click(function() {
-       //      closeNav();
-       // });
-
-       function openNavigation() {
-               // $('body').addClass('nav-fixed');
+       function openNavigation(){
                $('.navigation').fadeIn();
-               // $('.js-overlay').fadeIn();
        }
 
-       function closeNavigation() {
-               // $('body').removeClass('nav-fixed');
+       function closeNavigation(){
                $('.navigation').fadeOut();
-               // $('.js-overlay').fadeOut();
        }
 
        // Header fixed
-       $(function () {
+       $(function(){
                var shrinkHeader = 80;
-               $(window).scroll(function () {
+               $(window).scroll(function() {
                        var scroll = getCurrentScroll();
-                       if (scroll >= shrinkHeader) {
+                       if ( scroll >= shrinkHeader ) {
                                $('.site-header').addClass('small-header');
-                       } else {
+                       }else {
                                $('.site-header').removeClass('small-header');
                        }
                });
@@ -47,13 +35,4 @@ $(document).ready(function () {
                return window.pageYOffset || document.documentElement.scrollTop;
        }
 
-       $(document).ready(function() { var pathname = window.location.pathname;
-               pathname = pathname.replace('/FORT-validator/doc', '.');
-               pathname = pathname.replace('/FORT-validator', '.');
-
-               //get the path of current page
-               $('.site-nav > ul > li > a[href="'+pathname+'"]').addClass('active-item');
-       })
-
-
 });
index 552e9929d3f56fb6f8504e596b7c63371da426d3..053f53df7d73a843e76866febb99a8ab41794fd0 100644 (file)
@@ -1,4 +1,4 @@
-.TH fort 8 "2019-06-07" "v0.0.1-beta" "FORT validator"
+.TH fort 8 "2019-08-26" "v1.0.0" "FORT validator"
 
 .SH NAME
 fort \- RPKI certificate path validator
@@ -121,7 +121,7 @@ of objects, each with two members "name" and "action", eg:
 .RS 2
 {
 .RS 2
-"name": "Signed Object's hash algorithm has NULL object as parameters",
+"name": "incid-hashalg-has-params",
 .br
 "action": "warn"
 .RE
@@ -147,9 +147,10 @@ nothing happened.
 happened.
 .RE
 .P
-By default, all the incidences have an action of \fIerror\fR. Currently there's
+By default, all the incidences have an action of \fIignore\fR. Currently there's
 only one registered incidence:
-\fISigned Object's hash algorithm has NULL object as parameters\fR.
+\fIincid-hashalg-has-params\fR (Signed Object's hash algorithm has NULL object
+as parameters).
 .P
 More information about incidences can be consulted at FORT's web docs.
 .RE
@@ -177,11 +178,13 @@ and/or read.
 Right now, FORT accesses RPKI repositories by way of \fIrsync\fR. During each
 validation cycle, FORT will literally invoke an rsync command (see
 \fBrsync.program\fR and \fBrsync.arguments-recursive\fR), which will download
-the files into \fB--local-repository\fR. FORT’s validation operates on the resulting
-copy.
+the files into \fB--local-repository\fR. FORT’s validation operates on the
+resulting copy.
 .P
 Because rsync uses delta encoding, you’re advised to keep this cache around. It
 significantly speeds up subsequent validation cycles.
+.P
+By default, the path is \fI/tmp/fort/repository\fR.
 .RE
 .P
 
@@ -282,7 +285,7 @@ that yields a successful traversal.
 Maximum allowable certificate chain length. Meant to protect FORT from
 iterating infinitely due to certificate chain loops.
 .P
-By default, it has a value of \fI32\fR.
+By default, it has a value of \fI32\fR. The minimum allowed value is 5.
 .P
 (Required to prevent loops and "other degenerate forms of the logical RPKI
 hierarchy." (RFC 6481))
@@ -532,8 +535,8 @@ to a specific value:
 .nf
 
 {
-  "tal": "/tmp/tal/",
-  "local-repository": "/tmp/repository",
+  "tal": "/tmp/fort/tal/",
+  "local-repository": "/tmp/fort/repository",
   "sync-strategy": "root",
   "shuffle-uris": true,
   "maximum-certificate-depth": 32,
@@ -574,13 +577,13 @@ to a specific value:
   },
   "incidences": [
     {
-      "name": "Signed Object's hash algorithm has NULL object as parameters",
+      "name": "incid-hashalg-has-params",
       "action": "ignore"
     }
   ],
   "output": {
-    "roa": "/tmp/fort_roas.csv",
-    "bgpsec": "/tmp/fort_bgpsec.csv"
+    "roa": "/tmp/fort/roas.csv",
+    "bgpsec": "/tmp/fort/bgpsec.csv"
   }
 }
 .fi
@@ -671,4 +674,4 @@ well as some dummy Router Keys (BGPsec) info:
 More documentation about FORT validator can be consulted at github repository
 (https://github.com/NICMx/FORT-validator) and github website
 (https://nicmx.github.io/FORT-validator/)
-.RE
\ No newline at end of file
+.RE
index 296584f93aee9fefd3600953166a0b8c331131f3..93e62e4d44769ce760dbe6721a913365a425ff82 100644 (file)
@@ -496,3 +496,32 @@ ipv6_prefix_validate(struct ipv6_prefix *prefix)
 
        return 0;
 }
+
+/*
+ * Check if @son_addr is covered by @f_addr prefix of @f_len length
+ */
+bool
+ipv4_covered(struct in_addr *f_addr, uint8_t f_len, struct in_addr *son_addr)
+{
+       return (son_addr->s_addr & ~be32_suffix_mask(f_len)) == f_addr->s_addr;
+}
+
+/*
+ * Check if @son_addr is covered by @f_addr prefix of @f_len length
+ */
+bool
+ipv6_covered(struct in6_addr *f_addr, uint8_t f_len, struct in6_addr *son_addr)
+{
+       struct in6_addr suffix;
+       unsigned int i;
+
+       memset(&suffix, 0, sizeof(suffix));
+       ipv6_suffix_mask(f_len, &suffix);
+
+       for (i = 0; i < 16; i++)
+               if ((son_addr->s6_addr[i] & ~suffix.s6_addr[i]) !=
+                   f_addr->s6_addr[i])
+                       return false;
+
+       return true;
+}
index 78f9fdb22286de4f64b137521d0c3015769f5fb4..fb6e1e7a2dc536713dac377eea39be65fbe2ae18 100644 (file)
@@ -47,4 +47,7 @@ int prefix_length_parse(const char *, uint8_t *, uint8_t);
 int ipv4_prefix_validate(struct ipv4_prefix *);
 int ipv6_prefix_validate(struct ipv6_prefix *);
 
+bool ipv4_covered(struct in_addr *, uint8_t, struct in_addr *);
+bool ipv6_covered(struct in6_addr *, uint8_t, struct in6_addr *);
+
 #endif /* SRC_ADDRESS_H_ */
index dd4c386a0fbb92f7e365915f3b5fe766c44931b1..11515c5c2e1beb3575d4edc70f5346556dd32d72 100644 (file)
@@ -5,6 +5,9 @@
 #define        _POSIX_PTHREAD_SEMANTICS        /* for Sun */
 #define        _REENTRANT                      /* for Sun */
 #define __EXTENSIONS__                  /* for Sun */
+#ifndef _DEFAULT_SOURCE
+#define _DEFAULT_SOURCE 1
+#endif
 #ifndef _BSD_SOURCE
 #define _BSD_SOURCE     /* for timegm(3) */
 #endif
index 732ffd405de0f770a15ca90408a70b60f8ecb937..7bcd57b06d6e6e8a7fea21803f4d58a8256ceb7c 100644 (file)
@@ -90,6 +90,8 @@ handle_sdata_certificate(ANY_t *cert_encoded, struct signed_object_args *args,
                goto end1;
        }
 
+       x509_name_pr_debug("Issuer", X509_get_issuer_name(cert));
+
        error = certificate_validate_chain(cert, args->crls);
        if (error)
                goto end2;
@@ -443,37 +445,38 @@ release_sdata_pkcs7:
 }
 
 int
-signed_data_decode(ANY_t *coded, struct signed_object_args *args,
-    struct SignedData **result)
+signed_data_decode(struct signed_data *sdata, ANY_t *coded)
 {
-       struct SignedData *sdata;
        int error;
 
+       sdata->encoded = coded;
+
        /* rfc6488#section-3.1.l */
        /* TODO (next iteration) this is BER, not guaranteed to be DER. */
-       error = asn1_decode_any(coded, &asn_DEF_SignedData, (void **) &sdata,
-           false);
+       error = asn1_decode_any(coded, &asn_DEF_SignedData,
+           (void **) &sdata->decoded, false);
        if (error) {
                /* Try to decode as PKCS content (RFC 5652 section 5.2.1) */
-               error = signed_data_decode_pkcs7(coded, &sdata);
-               if (error)
-                       return (error);
+               error = signed_data_decode_pkcs7(coded, &sdata->decoded);
        }
 
-       error = validate(sdata, coded, args);
-       if (error) {
-               signed_data_free(sdata);
-               return error;
-       }
+       return error;
+}
 
-       *result = sdata;
-       return 0;
+int
+signed_data_validate(struct signed_data *sdata, struct signed_object_args *args)
+{
+       /*
+        * TODO (fine) maybe collapse this wrapper,
+        * since there's no point to it anymore.
+        */
+       return validate(sdata->decoded, sdata->encoded, args);
 }
 
 void
-signed_data_free(struct SignedData *sdata)
+signed_data_cleanup(struct signed_data *sdata)
 {
-       ASN_STRUCT_FREE(asn_DEF_SignedData, sdata);
+       ASN_STRUCT_FREE(asn_DEF_SignedData, sdata->decoded);
 }
 
 /* Caller must free *@result. */
index ed0e5dbd30241cd175cc95223269d9263e34b8ea..d627def8ed60e7c52d347c8dc58b1d2cfbb014cf 100644 (file)
@@ -10,6 +10,8 @@
 
 /*
  * This only exists to reduce argument lists.
+ * TODO (fine) rename to signed_data_args, since it has nothing to do with
+ * signed objects anymore.
  */
 struct signed_object_args {
        /** Location of the signed object. */
@@ -29,9 +31,14 @@ int signed_object_args_init(struct signed_object_args *, struct rpki_uri *,
     STACK_OF(X509_CRL) *, bool);
 void signed_object_args_cleanup(struct signed_object_args *);
 
-int signed_data_decode(ANY_t *, struct signed_object_args *args,
-    struct SignedData **);
-void signed_data_free(struct SignedData *);
+struct signed_data {
+       ANY_t *encoded;
+       struct SignedData *decoded;
+};
+
+int signed_data_decode(struct signed_data *, ANY_t *);
+int signed_data_validate(struct signed_data *, struct signed_object_args *);
+void signed_data_cleanup(struct signed_data *);
 
 int get_content_type_attr(struct SignedData *, OBJECT_IDENTIFIER_t **);
 
index 19f50226cf9221a20f7c20e76b48515757ea3bbb..8ef84aca89c465c0a1ea08f413f940e94f309b91 100644 (file)
@@ -86,7 +86,7 @@ close_thread(pthread_t thread, char const *what)
 
 static int
 process_file(char const *dir_name, char const *file_name, char const *file_ext,
-    process_file_cb cb, void *arg)
+    int *fcount, process_file_cb cb, void *arg)
 {
        char *ext, *fullpath, *tmp;
        int error;
@@ -98,6 +98,8 @@ process_file(char const *dir_name, char const *file_name, char const *file_ext,
                        return 0;
        }
 
+       (*fcount)++; /* Increment the found count */
+
        /* Get the full file path */
        tmp = strdup(dir_name);
        if (tmp == NULL)
@@ -129,7 +131,7 @@ process_dir_files(char const *location, char const *file_ext,
 {
        DIR *dir_loc;
        struct dirent *dir_ent;
-       int error;
+       int found, error;
 
        dir_loc = opendir(location);
        if (dir_loc == NULL) {
@@ -138,9 +140,10 @@ process_dir_files(char const *location, char const *file_ext,
        }
 
        errno = 0;
+       found = 0;
        while ((dir_ent = readdir(dir_loc)) != NULL) {
-               error = process_file(location, dir_ent->d_name, file_ext, cb,
-                   arg);
+               error = process_file(location, dir_ent->d_name, file_ext,
+                   &found, cb, arg);
                if (error) {
                        pr_err("The error was at file %s", dir_ent->d_name);
                        goto close_dir;
@@ -151,6 +154,9 @@ process_dir_files(char const *location, char const *file_ext,
                pr_err("Error reading dir %s", location);
                error = -errno;
        }
+       if (!error && found == 0)
+               pr_warn("Location '%s' doesn't have files with extension '%s'",
+                   location, file_ext);
 close_dir:
        closedir(dir_loc);
 end:
index 448d82491af695a83fdf47656fb4d70e0e7a8cc9..98e348b268874cb73d5f326e23cf8c99776b6fc5 100644 (file)
@@ -9,6 +9,7 @@
 
 #include "common.h"
 #include "configure_ac.h"
+#include "file.h"
 #include "json_handler.h"
 #include "log.h"
 #include "config/boolean.h"
@@ -181,7 +182,7 @@ static const struct option_field options[] = {
                .offset = offsetof(struct rpki_config,
                    maximum_certificate_depth),
                .doc = "Maximum allowable certificate chain length",
-               .min = 1,
+               .min = 5,
                /**
                 * It cannot be UINT_MAX, because then the actual number will
                 * overflow and will never be bigger than this.
@@ -349,8 +350,7 @@ static const struct option_field options[] = {
                .offset = offsetof(struct rpki_config, output.roa),
                .doc = "File where ROAs will be stored in CSV format, use '-' to print at console",
                .arg_doc = "<file>",
-       },
-       {
+       }, {
                .id = 6001,
                .name = "output.bgpsec",
                .type = &gt_string,
@@ -575,6 +575,12 @@ revert_port:
        return error;
 }
 
+static bool
+valid_output_file(char const *path)
+{
+       return strcmp(path, "-") == 0 || file_valid(path);
+}
+
 static int
 validate_config(void)
 {
@@ -584,6 +590,10 @@ validate_config(void)
            rpki_config.server.interval.retry)
                return pr_err("Expire interval must be greater than refresh and retry intervals");
 
+       if (rpki_config.output.roa != NULL &&
+           !valid_output_file(rpki_config.output.roa))
+               return pr_err("Invalid output.roa file.");
+
        return (rpki_config.tal != NULL)
            ? 0
            : pr_err("The TAL file/directory (--tal) is mandatory.");
index 7d89b5aee297691f2196cc58ba83f727e5dcf5a0..af2464b9c98ed86f84204e43f23a5a0f368f1928 100644 (file)
@@ -15,6 +15,7 @@ int
 parse_argv_uint(struct option_field const *field, char const *str,
     void *result)
 {
+       char *tmp;
        unsigned long parsed;
 
        if (field->type->has_arg != required_argument || str == NULL) {
@@ -23,13 +24,17 @@ parse_argv_uint(struct option_field const *field, char const *str,
        }
 
        errno = 0;
-       parsed = strtoul(str, NULL, 10);
-       if (errno)
-               return pr_errno(errno, "'%s' is not an unsigned integer", str);
+       parsed = strtoul(str, &tmp, 10);
+       if (errno || *tmp != '\0')
+               return errno ? pr_errno(errno,
+                   "Value '%s' at '%s' is not an unsigned integer", str,
+                   field->name) :
+                   pr_err("Value '%s' at '%s' is not an unsigned integer",
+                   str, field->name);
 
        if (parsed < field->min || field->max < parsed) {
-               return pr_err("'%lu' is out of bounds (%u-%u).", parsed,
-                   field->min, field->max);
+               return pr_err("Value of '%s' is out of range (%u-%u).",
+                   field->name, field->min, field->max);
        }
 
        *((unsigned int *) result) = parsed;
index d1e26b6f4329d0036f5a4166884d077d44a47af3..8df0f966dd4861711e3fa430ab78240e1c33f687 100644 (file)
@@ -110,3 +110,25 @@ file_free(struct file_contents *fc)
 {
        free(fc->buffer);
 }
+
+/*
+ * Validate @file_name, if it doesn't exist, this function will create it and
+ * close it.
+ */
+bool
+file_valid(char const *file_name)
+{
+       FILE *tmp;
+       struct stat stat;
+       int error;
+
+       if (file_name == NULL)
+               return false;
+
+       error = file_write(file_name, &tmp, &stat);
+       if (error)
+               return false;
+
+       file_close(tmp);
+       return true;
+}
index 8440dfe4e6e2d177e152cbe6481fb55d716f3cf1..1699587c9c23a8a9481324bfe980491961858ca9 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef SRC_FILE_H_
 #define SRC_FILE_H_
 
+#include <stdbool.h>
 #include <stddef.h>
 #include <stdio.h>
 #include <sys/stat.h>
@@ -22,4 +23,6 @@ void file_close(FILE *);
 int file_load(char const *, struct file_contents *);
 void file_free(struct file_contents *);
 
+bool file_valid(char const *);
+
 #endif /* SRC_FILE_H_ */
index 5cd7fb34083d368b121c42f09b55888f17f48b60..d9a7b77d58366a8d920ad82308283c7121c27eb0 100644 (file)
@@ -11,6 +11,7 @@
 struct incidence {
        const enum incidence_id id;
        char const *const name;
+       char const *const description;
        const enum incidence_action default_action;
        enum incidence_action action;
 };
@@ -18,8 +19,9 @@ struct incidence {
 static struct incidence incidences[__INID_MAX] = {
        {
                INID_HASHALG_HAS_PARAMS,
+               "incid-hashalg-has-params",
                "Signed Object's hash algorithm has NULL object as parameters",
-               INAC_ERROR,
+               INAC_IGNORE,
        },
 };
 
@@ -81,10 +83,6 @@ init_action(json_t *json)
        else
                return pr_err("Unknown incidence action: '%s'", action_str);
 
-       if (action > incidences[id].action)
-               return pr_err("The '%s' incidence cannot have a more severe action than '%s'.",
-                   name, action2str(incidences[id].action));
-
        incidences[id].action = action;
        return 0;
 }
@@ -134,24 +132,16 @@ void
 incidence_print(void)
 {
        array_index i;
-       bool printed;
 
        pr_info("Custom incidences:");
        pr_indent_add();
 
-       printed = false;
-
        for (i = 0; i < __INID_MAX; i++) {
-               if (incidences[i].action != incidences[i].default_action) {
-                       pr_info("%s: %s", incidences[i].name,
-                           action2str(incidences[i].action));
-                       printed = true;
-               }
+               pr_info("%s (%s): %s", incidences[i].name,
+                   incidences[i].description,
+                   action2str(incidences[i].action));
        }
 
-       if (!printed)
-               pr_info("<None>");
-
        pr_indent_rm();
 }
 
index 735698ab9e334de117796a028f5f61fd29521ad0..78f4aef3749132430bd3cb854da86d229d0f8eaa 100644 (file)
@@ -15,8 +15,8 @@
 #include "asn1/oid.h"
 #include "asn1/asn1c/IPAddrBlocks.h"
 #include "crypto/hash.h"
-#include "object/name.h"
 #include "object/bgpsec.h"
+#include "object/name.h"
 #include "object/manifest.h"
 #include "rsync/rsync.h"
 
@@ -93,11 +93,15 @@ validate_issuer(X509 *cert, bool is_ta)
        if (!is_ta)
                return validate_issuer_name("Certificate", issuer);
 
+       /* TODO wait. Shouldn't we check subject == issuer? */
+
        error = x509_name_decode(issuer, "issuer", &name);
-       if (!error)
-               x509_name_put(name);
+       if (error)
+               return error;
+       pr_debug("Issuer: %s", x509_name_commonName(name));
 
-       return error;
+       x509_name_put(name);
+       return 0;
 }
 
 static int
@@ -114,6 +118,7 @@ validate_subject(X509 *cert)
        error = x509_name_decode(X509_get_subject_name(cert), "subject", &name);
        if (error)
                return error;
+       pr_debug("Subject: %s", x509_name_commonName(name));
 
        error = x509stack_store_subject(validation_certstack(state), name);
 
@@ -1610,12 +1615,6 @@ certificate_traverse(struct rpp *rpp_parent, struct rpki_uri *cert_uri)
        if (error)
                goto revert_uris;
 
-       /* -- Validate the manifest (@mft) pointed by the certificate -- */
-       error = x509stack_push(validation_certstack(state), cert_uri, cert,
-           policy, type);
-       if (error)
-               goto revert_uris;
-
        if (type == BGPSEC) {
                /* This is an EE, so there's no manifest to process */
                error = handle_bgpsec(cert, ski,
@@ -1626,7 +1625,6 @@ certificate_traverse(struct rpp *rpp_parent, struct rpki_uri *cert_uri)
 
                goto revert_refs;
        }
-       cert = NULL; /* Ownership stolen */
 
        /*
         * RFC 6481 section 5: "when the repository publication point contents
@@ -1639,7 +1637,17 @@ certificate_traverse(struct rpp *rpp_parent, struct rpki_uri *cert_uri)
         */
        mft_retry = true;
        do {
-               error = handle_manifest(mft, rpp_parent_crl, &pp);
+               /* Validate the manifest (@mft) pointed by the certificate */
+               error = x509stack_push(validation_certstack(state), cert_uri,
+                   cert, policy, IS_TA);
+               if (error) {
+                       if (!mft_retry)
+                               uri_refput(mft);
+                       goto revert_uris;
+               }
+               cert = NULL; /* Ownership stolen */
+
+               error = handle_manifest(mft, &pp);
                if (!mft_retry)
                        uri_refput(mft);
                if (!error || !mft_retry)
@@ -1650,6 +1658,13 @@ certificate_traverse(struct rpp *rpp_parent, struct rpki_uri *cert_uri)
                error = download_files(caRepository, false, true);
                if (error)
                        break;
+
+               /* Cancel stack, reload certificate (no need to revalidate) */
+               x509stack_cancel(validation_certstack(state));
+               error = certificate_load(cert_uri, &cert);
+               if (error) {
+                       goto revert_uris;
+               }
                uri_refget(mft);
                mft_retry = false;
        } while (true);
index 42f82ca0fffdd9fdddb815588f3d69e9ab82db61..5dabb9633ad42f0b9b3bff671ad1ca5d5576b61b 100644 (file)
@@ -7,9 +7,11 @@
 #include "vcard.h"
 
 static int
-handle_vcard(OCTET_STRING_t *vcard, void *arg)
+handle_vcard(struct signed_object *sobj)
 {
-       return handle_ghostbusters_vcard(vcard);
+       return handle_ghostbusters_vcard(
+               sobj->sdata.decoded->encapContentInfo.eContent
+       );
 }
 
 int
@@ -17,30 +19,42 @@ ghostbusters_traverse(struct rpki_uri *uri, struct rpp *pp)
 {
        static OID oid = OID_GHOSTBUSTERS;
        struct oid_arcs arcs = OID2ARCS("ghostbusters", oid);
+       struct signed_object sobj;
        struct signed_object_args sobj_args;
        STACK_OF(X509_CRL) *crl;
        int error;
 
+       /* Prepare */
        pr_debug_add("Ghostbusters '%s' {", uri_get_printable(uri));
        fnstack_push_uri(uri);
 
-       error = rpp_crl(pp, &crl);
+       /* Decode */
+       error = signed_object_decode(&sobj, uri);
        if (error)
-               goto end1;
+               goto revert_log;
 
+       /* Prepare validation arguments */
+       error = rpp_crl(pp, &crl);
+       if (error)
+               goto revert_sobj;
        error = signed_object_args_init(&sobj_args, uri, crl, true);
        if (error)
-               goto end1;
+               goto revert_sobj;
 
-       error = signed_object_decode(&sobj_args, &arcs, handle_vcard, NULL);
+       /* Validate everything */
+       error = signed_object_validate(&sobj, &arcs, &sobj_args);
        if (error)
-               goto end2;
-
+               goto revert_args;
+       error = handle_vcard(&sobj);
+       if (error)
+               goto revert_args;
        error = refs_validate_ee(&sobj_args.refs, pp, sobj_args.uri);
 
-end2:
+revert_args:
        signed_object_args_cleanup(&sobj_args);
-end1:
+revert_sobj:
+       signed_object_cleanup(&sobj);
+revert_log:
        pr_debug_rm("}");
        fnstack_pop();
        return error;
index 9515ce7f462e5ac722100f2de287e3388b76432b..7806925629c825588aabe5405fc95afb821e9678 100644 (file)
 #include "object/signed_object.h"
 
 static int
-manifest_decode(OCTET_STRING_t *string, void *arg)
+decode_manifest(struct signed_object *sobj, struct Manifest **result)
 {
-       return asn1_decode_octet_string(string, &asn_DEF_Manifest, arg, true);
+       return asn1_decode_octet_string(
+               sobj->sdata.decoded->encapContentInfo.eContent,
+               &asn_DEF_Manifest,
+               (void **) result,
+               true
+       );
 }
 
 static int
@@ -141,8 +146,7 @@ validate_manifest(struct Manifest *manifest)
 }
 
 static int
-__handle_manifest(struct Manifest *mft, struct rpki_uri *mft_uri,
-    struct rpp **pp)
+build_rpp(struct Manifest *mft, struct rpki_uri *mft_uri, struct rpp **pp)
 {
        int i;
        struct FileAndHash *fah;
@@ -206,41 +210,65 @@ fail:
  * @pp.
  */
 int
-handle_manifest(struct rpki_uri *uri, STACK_OF(X509_CRL) *crls, struct rpp **pp)
+handle_manifest(struct rpki_uri *uri, struct rpp **pp)
 {
        static OID oid = OID_MANIFEST;
        struct oid_arcs arcs = OID2ARCS("manifest", oid);
+       struct signed_object sobj;
        struct signed_object_args sobj_args;
        struct Manifest *mft;
+       STACK_OF(X509_CRL) *crl;
        int error;
 
+       /* Prepare */
        pr_debug_add("Manifest '%s' {", uri_get_printable(uri));
        fnstack_push_uri(uri);
 
-       error = signed_object_args_init(&sobj_args, uri, crls, false);
+       /* Decode */
+       error = signed_object_decode(&sobj, uri);
        if (error)
-               goto end1;
+               goto revert_log;
+       error = decode_manifest(&sobj, &mft);
+       if (error)
+               goto revert_sobj;
 
-       error = signed_object_decode(&sobj_args, &arcs, manifest_decode, &mft);
+       /* Initialize out parameter (@pp) */
+       error = build_rpp(mft, uri, pp);
        if (error)
-               goto end2;
+               goto revert_manifest;
 
-       error = validate_manifest(mft);
+       /* Prepare validation arguments */
+       error = rpp_crl(*pp, &crl);
        if (error)
-               goto end3;
-       error = __handle_manifest(mft, uri, pp);
+               goto revert_rpp;
+       error = signed_object_args_init(&sobj_args, uri, crl, false);
        if (error)
-               goto end3;
+               goto revert_rpp;
 
+       /* Validate everything */
+       error = signed_object_validate(&sobj, &arcs, &sobj_args);
+       if (error)
+               goto revert_args;
+       error = validate_manifest(mft);
+       if (error)
+               goto revert_args;
        error = refs_validate_ee(&sobj_args.refs, *pp, uri);
        if (error)
-               rpp_refput(*pp);
+               goto revert_args;
 
-end3:
-       ASN_STRUCT_FREE(asn_DEF_Manifest, mft);
-end2:
+       /* Success */
+       signed_object_args_cleanup(&sobj_args);
+       goto revert_manifest;
+
+revert_args:
        signed_object_args_cleanup(&sobj_args);
-end1:
+revert_rpp:
+       rpp_refput(*pp);
+revert_manifest:
+       ASN_STRUCT_FREE(asn_DEF_Manifest, mft);
+revert_sobj:
+       signed_object_cleanup(&sobj);
+revert_log:
        pr_debug_rm("}");
        fnstack_pop();
        return error;
index ded148c04866700aaeef5c98db7eb392628f6120..a9cfcb992c972271be1678bca57d365ce18c7216 100644 (file)
@@ -1,10 +1,9 @@
 #ifndef SRC_OBJECT_MANIFEST_H_
 #define SRC_OBJECT_MANIFEST_H_
 
-#include <openssl/x509.h>
 #include "uri.h"
 #include "rpp.h"
 
-int handle_manifest(struct rpki_uri *, STACK_OF(X509_CRL) *, struct rpp **);
+int handle_manifest(struct rpki_uri *, struct rpp **);
 
 #endif /* SRC_OBJECT_MANIFEST_H_ */
index d800fde2951802e6f0ccaac0dc5ad755ae5978ea..a5dc7f0205b39c48eee510d7a768d1ed8c2d6e41 100644 (file)
@@ -174,6 +174,7 @@ validate_issuer_name(char const *container, X509_NAME *issuer)
        error = x509_name_decode(issuer, "issuer", &child_issuer);
        if (error)
                goto end;
+       pr_debug("Issuer: %s", child_issuer->commonName);
 
        if (!x509_name_equals(parent_subject, child_issuer)) {
                char const *parent_serial;
@@ -196,3 +197,24 @@ validate_issuer_name(char const *container, X509_NAME *issuer)
 end:   x509_name_put(parent_subject);
        return error;
 }
+
+#ifdef DEBUG
+
+void
+x509_name_pr_debug(const char *prefix, X509_NAME *name)
+{
+       struct rfc5280_name *printable;
+
+       if (name == NULL) {
+               pr_debug("%s: (null)", prefix);
+               return;
+       }
+
+       if (x509_name_decode(name, prefix, &printable) != 0)
+               return; /* Error message already printed */
+
+       pr_debug("%s: %s", prefix, printable->commonName);
+       x509_name_put(printable);
+}
+
+#endif
index 85d487e073742c2789f7bbc40e66fde011cc67be..a1a070d59cf07e6aaf0f640900176cb8d99eaef2 100644 (file)
@@ -18,6 +18,14 @@ char const *x509_name_serialNumber(struct rfc5280_name *);
 
 bool x509_name_equals(struct rfc5280_name *, struct rfc5280_name *);
 
+
+/* X509_NAME utils */
 int validate_issuer_name(char const *, X509_NAME *);
 
+#ifdef DEBUG
+void x509_name_pr_debug(char const *, X509_NAME *);
+#else
+#define x509_name_pr_debug(a, b) /* Nothing */
+#endif
+
 #endif /* SRC_OBJECT_NAME_H_ */
index e971f5fb8998f24095f5973b79b77a71f47efaaa..71024026844eb3cdae668430d22b0d2c85434b98 100644 (file)
 #include "object/signed_object.h"
 
 static int
-roa_decode(OCTET_STRING_t *string, void *arg)
+decode_roa(struct signed_object *sobj, struct RouteOriginAttestation **result)
 {
-       return asn1_decode_octet_string(string, &asn_DEF_RouteOriginAttestation,
-           arg, true);
+       return asn1_decode_octet_string(
+               sobj->sdata.decoded->encapContentInfo.eContent,
+               &asn_DEF_RouteOriginAttestation,
+               (void **) result,
+               true
+       );
 }
 
 static int
@@ -151,7 +155,6 @@ __handle_roa(struct RouteOriginAttestation *roa, struct resources *parent)
        int a;
        int error;
 
-
        pr_debug_add("eContent {");
        if (roa->version != NULL) {
                error = asn_INTEGER2ulong(roa->version, &version);
@@ -185,8 +188,10 @@ __handle_roa(struct RouteOriginAttestation *roa, struct resources *parent)
 
        /* rfc6482#section-3.3 */
 
-       if (roa->ipAddrBlocks.list.array == NULL)
-               pr_crit("ipAddrBlocks array is NULL.");
+       if (roa->ipAddrBlocks.list.array == NULL) {
+               error = pr_err("ipAddrBlocks array is NULL.");
+               goto end_error;
+       }
 
        pr_debug_add("ipAddrBlocks {");
        for (b = 0; b < roa->ipAddrBlocks.list.count; b++) {
@@ -242,37 +247,48 @@ roa_traverse(struct rpki_uri *uri, struct rpp *pp)
 {
        static OID oid = OID_ROA;
        struct oid_arcs arcs = OID2ARCS("roa", oid);
+       struct signed_object sobj;
        struct signed_object_args sobj_args;
        struct RouteOriginAttestation *roa;
        STACK_OF(X509_CRL) *crl;
        int error;
 
+       /* Prepare */
        pr_debug_add("ROA '%s' {", uri_get_printable(uri));
        fnstack_push_uri(uri);
 
-       error = rpp_crl(pp, &crl);
+       /* Decode */
+       error = signed_object_decode(&sobj, uri);
        if (error)
-               goto revert_fnstack;
-
-       error = signed_object_args_init(&sobj_args, uri, crl, false);
-       if (error)
-               goto revert_fnstack;
-
-       error = signed_object_decode(&sobj_args, &arcs, roa_decode, &roa);
+               goto revert_log;
+       error = decode_roa(&sobj, &roa);
        if (error)
                goto revert_sobj;
 
-       error = refs_validate_ee(&sobj_args.refs, pp, sobj_args.uri);
+       /* Prepare validation arguments */
+       error = rpp_crl(pp, &crl);
+       if (error)
+               goto revert_roa;
+       error = signed_object_args_init(&sobj_args, uri, crl, false);
        if (error)
                goto revert_roa;
 
+       /* Validate and handle everything */
+       error = signed_object_validate(&sobj, &arcs, &sobj_args);
+       if (error)
+               goto revert_args;
        error = __handle_roa(roa, sobj_args.res);
+       if (error)
+               goto revert_args;
+       error = refs_validate_ee(&sobj_args.refs, pp, sobj_args.uri);
 
+revert_args:
+       signed_object_args_cleanup(&sobj_args);
 revert_roa:
        ASN_STRUCT_FREE(asn_DEF_RouteOriginAttestation, roa);
 revert_sobj:
-       signed_object_args_cleanup(&sobj_args);
-revert_fnstack:
+       signed_object_cleanup(&sobj);
+revert_log:
        fnstack_pop();
        pr_debug_rm("}");
        return error;
index e7949d7aae422339dda37d0ee5e486a69bf2686e..25d17bd2fe147325d42db42eb7ed3f6ba54a3077 100644 (file)
@@ -4,6 +4,24 @@
 #include "log.h"
 #include "asn1/content_info.h"
 
+int
+signed_object_decode(struct signed_object *sobj, struct rpki_uri *uri)
+{
+       int error;
+
+       error = content_info_load(uri, &sobj->cinfo);
+       if (error)
+               return error;
+
+       error = signed_data_decode(&sobj->sdata, &sobj->cinfo->content);
+       if (error) {
+               content_info_free(sobj->cinfo);
+               return error;
+       }
+
+       return 0;
+}
+
 static int
 validate_eContentType(struct SignedData *sdata, struct oid_arcs const *oid)
 {
@@ -50,39 +68,30 @@ validate_content_type(struct SignedData *sdata, struct oid_arcs const *oid)
 }
 
 int
-signed_object_decode(struct signed_object_args *args,
-    struct oid_arcs const *oid,
-    signed_object_cb cb,
-    void *cb_arg)
+signed_object_validate(struct signed_object *sobj, struct oid_arcs const *oid,
+    struct signed_object_args *args)
 {
-       struct ContentInfo *cinfo;
-       struct SignedData *sdata;
        int error;
 
-       error = content_info_load(args->uri, &cinfo);
-       if (error)
-               goto end1;
-
-       error = signed_data_decode(&cinfo->content, args, &sdata);
-       if (error)
-               goto end2;
-
        /* rfc6482#section-2 */
        /* rfc6486#section-4.1 */
        /* rfc6486#section-4.4.1 */
-       error = validate_eContentType(sdata, oid);
+       error = validate_eContentType(sobj->sdata.decoded, oid);
        if (error)
-               goto end3;
+               return error;
 
        /* rfc6482#section-2 */
        /* rfc6486#section-4.3 */
-       error = validate_content_type(sdata, oid);
+       error = validate_content_type(sobj->sdata.decoded, oid);
        if (error)
-               goto end3;
+               return error;
 
-       error = cb(sdata->encapContentInfo.eContent, cb_arg);
+       return signed_data_validate(&sobj->sdata, args);
+}
 
-end3:  signed_data_free(sdata);
-end2:  content_info_free(cinfo);
-end1:  return error;
+void
+signed_object_cleanup(struct signed_object *sobj)
+{
+       content_info_free(sobj->cinfo);
+       signed_data_cleanup(&sobj->sdata);
 }
index 41dc55867396765dfd27d536b5d228edbfdc5109..41404d74e30cee402dd0b792f348385d1236a742 100644 (file)
@@ -1,13 +1,17 @@
 #ifndef SRC_OBJECT_SIGNED_OBJECT_H_
 #define SRC_OBJECT_SIGNED_OBJECT_H_
 
-#include <openssl/x509.h>
 #include "asn1/oid.h"
 #include "asn1/signed_data.h"
 
-typedef int (*signed_object_cb)(OCTET_STRING_t *, void *);
+struct signed_object {
+       struct ContentInfo *cinfo;
+       struct signed_data sdata;
+};
 
-int signed_object_decode(struct signed_object_args *, struct oid_arcs const *,
-    signed_object_cb, void *);
+int signed_object_decode(struct signed_object *, struct rpki_uri *);
+int signed_object_validate(struct signed_object *, struct oid_arcs const *,
+    struct signed_object_args *);
+void signed_object_cleanup(struct signed_object *);
 
 #endif /* SRC_OBJECT_SIGNED_OBJECT_H_ */
index 7f8e4789f99a0fb5dca07dcf14b89b922006ebf3..d395f8559eba1f5173bd9c4a55dc502fa7715220 100644 (file)
@@ -6,6 +6,7 @@
 #include <stdbool.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 #include <sys/stat.h>
 #include <openssl/evp.h>
 
@@ -110,6 +111,17 @@ read_uris(struct line_file *lfile, struct uris *uris)
        } while (true);
 }
 
+static size_t
+get_spki_orig_size(struct line_file *lfile)
+{
+       struct stat st;
+       size_t result;
+
+       stat(lfile_name(lfile), &st);
+       result = st.st_size - lfile_offset(lfile);
+       return result;
+}
+
 /*
  * Will usually allocate slightly more because of the newlines, but I'm fine
  * with it.
@@ -117,38 +129,128 @@ read_uris(struct line_file *lfile, struct uris *uris)
 static size_t
 get_spki_alloc_size(struct line_file *lfile)
 {
-       struct stat st;
-       size_t result;
+       return EVP_DECODE_LENGTH(get_spki_orig_size(lfile));
+}
 
-       stat(lfile_name(lfile), &st);
-       result = st.st_size - lfile_offset(lfile);
+/*
+ * Get the base64 chars from @lfile and allocate to @out with lines no greater
+ * than 65 chars (including line feed).
+ *
+ * Why? LibreSSL doesn't like lines greater than 80 chars, so use a common
+ * length per line.
+ */
+static int
+base64_sanitize(struct line_file *lfile, char **out)
+{
+#define BUF_SIZE 65
+       FILE *fd;
+       char buf[BUF_SIZE];
+       char *result, *eol;
+       size_t original_size, new_size;
+       size_t fread_result, offset;
+       int error;
 
-       return EVP_DECODE_LENGTH(result);
+       /*
+        * lfile_read() isn't called since the lines aren't returned as needed
+        * "sanitized" (a.k.a. each line with a desired length)
+        */
+       original_size = get_spki_orig_size(lfile);
+       new_size = original_size + (original_size / BUF_SIZE);
+       result = malloc(new_size + 1);
+       if (result == NULL)
+               return pr_enomem();
+
+       fd = lfile_fd(lfile);
+       offset = 0;
+       while ((fread_result = fread(buf, 1,
+           (original_size > BUF_SIZE) ? BUF_SIZE : original_size, fd)) > 0) {
+               error = ferror(lfile_fd(lfile));
+               if (error) {
+                       /*
+                        * The manpage doesn't say that the result is an error
+                        * code. It literally doesn't say how to get an error
+                        * code.
+                        */
+                       pr_errno(error,
+                           "File reading error. Error message (apparently)");
+                       goto free_result;
+               }
+
+               original_size -= fread_result;
+               eol = strchr(buf, '\n');
+               /* Larger than buffer length, add LF and copy last char */
+               if (eol == NULL) {
+                       memcpy(&result[offset], buf, fread_result - 1);
+                       offset += fread_result - 1;
+                       result[offset] = '\n';
+                       result[offset + 1] = buf[fread_result - 1];
+                       offset += 2;
+                       continue;
+               }
+               /* Copy till last LF */
+               memcpy(&result[offset], buf, eol - buf + 1);
+               offset += eol - buf + 1;
+               if (eol - buf + 1 < fread_result) {
+                       /* And add new line with remaining chars */
+                       memcpy(&result[offset], eol + 1,
+                           buf + fread_result - 1 - eol);
+                       offset += buf + fread_result -1 - eol;
+                       result[offset] = '\n';
+                       offset++;
+               }
+       }
+       /* Reallocate to exact size and add nul char */
+       if (offset != new_size + 1) {
+               eol = realloc(result, offset + 1);
+               if (eol == NULL) {
+                       error = pr_enomem();
+                       goto free_result;
+               }
+               result = eol;
+       }
+       result[offset] = '\0';
+
+       *out = result;
+       return 0;
+free_result:
+       free(result);
+       return error;
+#undef BUF_SIZE
 }
 
 static int
 read_spki(struct line_file *lfile, struct tal *tal)
 {
        BIO *encoded; /* base64 encoded. */
+       char *tmp;
        size_t alloc_size;
        int error;
 
        alloc_size = get_spki_alloc_size(lfile);
        tal->spki = malloc(alloc_size);
        if (tal->spki == NULL)
-               return -ENOMEM;
+               return pr_enomem();
 
-       encoded = BIO_new_fp(lfile_fd(lfile), BIO_NOCLOSE);
+       tmp = NULL;
+       error = base64_sanitize(lfile, &tmp);
+       if (error) {
+               free(tal->spki);
+               return error;
+       }
+
+       encoded = BIO_new_mem_buf(tmp, -1);
        if (encoded == NULL) {
                free(tal->spki);
-               return crypto_err("BIO_new_fp() returned NULL");
+               free(tmp);
+               return crypto_err("BIO_new_mem_buf() returned NULL");
        }
 
        error = base64_decode(encoded, tal->spki, true, alloc_size,
-           &tal->spki_len);
+                   &tal->spki_len);
        if (error)
                free(tal->spki);
 
+       free(tmp);
        BIO_free(encoded);
        return error;
 }
@@ -300,8 +402,9 @@ handle_tal_uri(struct tal *tal, struct rpki_uri *uri, void *arg)
 
        error = download_files(uri, true, false);
        if (error) {
-               return pr_warn("TAL '%s' could not be RSYNC'd.",
+               pr_warn("TAL '%s' could not be RSYNC'd.",
                    uri_get_printable(uri));
+               return ENSURE_NEGATIVE(error);
        }
 
        error = validation_prepare(&state, tal, arg);
@@ -389,7 +492,8 @@ do_file_validation(char const *tal_file, void *arg)
                error = pr_err("None of the URIs of the TAL '%s' yielded a successful traversal.",
                    tal_file);
 
-end:   tal_destroy(tal);
+       tal_destroy(tal);
+end:
        fnstack_pop();
        return error;
 }
index 5065dcea07b683f80bd43169d4fa1461e2cc23a0..5e7e2449c8eedd5650b5eaadc8d4cfe92022f568 100644 (file)
@@ -304,6 +304,7 @@ do_rsync(struct rpki_uri *uri, bool is_ta)
        int child_status;
        int error;
 
+       child_status = 0;
        error = create_dir_recursive(uri);
        if (error)
                return error;
@@ -318,12 +319,16 @@ do_rsync(struct rpki_uri *uri, bool is_ta)
        /* This code is run by us. */
 
        error = waitpid(child_pid, &child_status, 0);
-       if (error == -1) {
-               error = errno;
-               pr_err("The rsync sub-process returned error %d (%s)",
-                   error, strerror(error));
-               return error;
-       }
+       do {
+               if (error == -1) {
+                       error = errno;
+                       pr_err("The rsync sub-process returned error %d (%s)",
+                           error, strerror(error));
+                       if (child_status > 0)
+                               break;
+                       return error;
+               }
+       } while (0);
 
        if (WIFEXITED(child_status)) {
                /* Happy path (but also sad path sometimes). */
@@ -347,11 +352,11 @@ do_rsync(struct rpki_uri *uri, bool is_ta)
                        pr_err("The RSYNC was terminated by a signal I don't have a handler for. Dunno; guess I'll just die.");
                        break;
                }
-               exit(-EINTR); /* Meh? */
+               return -EINTR; /* Meh? */
        }
 
        pr_err("The RSYNC command died in a way I don't have a handler for. Dunno; guess I'll die as well.");
-       exit(-EINVAL);
+       return -EINVAL;
 }
 
 /**
index 68edf7610af3f1a0e0c8ad36d1c434da36904b5b..59c05528a938d24f7e9d50fcd97e676ff1e05782 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <stdint.h>
 #include <netinet/in.h>
+#include "address.h"
 #include "object/router_key.h"
 
 #define FLAG_WITHDRAWAL                0
 #define VRP_MAX_PREFIX_LEN_EQ(a, b)                                    \
        (a)->max_prefix_length == (b)->max_prefix_length
 
+#define SAME_ADDR_FAM(a, b, fam)                                       \
+       (a)->addr_fam == fam &&                                         \
+       (b)->addr_fam == fam
+
 #define VRP_PREFIX_V4_EQ(a, b)                                         \
-       ((a)->addr_fam == AF_INET &&                                    \
-       (b)->addr_fam == AF_INET &&                                     \
+       (SAME_ADDR_FAM(a, b, AF_INET) &&                                \
        (a)->prefix.v4.s_addr == (b)->prefix.v4.s_addr &&               \
        (a)->prefix_length == (b)->prefix_length)
 
+#define VRP_PREFIX_V4_COV(a, b)                                                \
+       (SAME_ADDR_FAM(a, b, AF_INET) &&                                \
+       ipv4_covered(&(a)->prefix.v4, (a)->prefix_length,               \
+           &(b)->prefix.v4) &&                                         \
+       (a)->prefix_length <= (b)->prefix_length)
+
 #define VRP_PREFIX_V6_EQ(a, b)                                         \
-       ((a)->addr_fam == AF_INET6 &&                                   \
-       (b)->addr_fam == AF_INET6 &&                                    \
+       (SAME_ADDR_FAM(a, b, AF_INET6) &&                               \
        IN6_ARE_ADDR_EQUAL(&(a)->prefix.v6, &(b)->prefix.v6) &&         \
        (a)->prefix_length == (b)->prefix_length)
 
+#define VRP_PREFIX_V6_COV(a, b)                                                \
+       (SAME_ADDR_FAM(a, b, AF_INET6) &&                               \
+       ipv6_covered(&(a)->prefix.v6, (a)->prefix_length,               \
+           &(b)->prefix.v6) &&                                         \
+       (a)->prefix_length <= (b)->prefix_length)
+
 #define VRP_PREFIX_EQ(a, b)                                            \
        (VRP_PREFIX_V4_EQ(a, b) || VRP_PREFIX_V6_EQ(a, b))
 
+/* Checks if 'a' equals or covers 'b' */
+#define VRP_PREFIX_COV(a, b)                                           \
+       (VRP_PREFIX_V4_COV(a, b) || VRP_PREFIX_V6_COV(a, b))
+
 #define VRP_EQ(a, b)                                                   \
        (VRP_ASN_EQ(a, b) && VRP_PREFIX_EQ(a, b) && VRP_MAX_PREFIX_LEN_EQ(a, b))
 
index 8001e4323db5804798ff2a9b3c70615f7f71607d..e767b32016e69fab4763fa79240406098d742dd6 100644 (file)
@@ -3,7 +3,6 @@
 #include <errno.h>
 #include <netdb.h>
 #include <pthread.h>
-#include <signal.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -19,8 +18,6 @@
 #include "rtr/pdu.h"
 #include "rtr/db/vrps.h"
 
-struct sigaction act;
-
 struct thread_param {
        int fd;
        pthread_t tid;
@@ -32,7 +29,9 @@ init_addrinfo(struct addrinfo **result)
 {
        char const *hostname;
        char const *service;
+       char *tmp;
        struct addrinfo hints;
+       unsigned long parsed, port;
        int error;
 
        memset(&hints, 0 , sizeof(hints));
@@ -43,6 +42,9 @@ init_addrinfo(struct addrinfo **result)
        hostname = config_get_server_address();
        service = config_get_server_port();
 
+       if (hostname != NULL)
+               hints.ai_flags |= AI_CANONNAME;
+
        error = getaddrinfo(hostname, service, &hints, result);
        if (error) {
                pr_err("Could not infer a bindable address out of address '%s' and port '%s': %s",
@@ -51,6 +53,26 @@ init_addrinfo(struct addrinfo **result)
                return error;
        }
 
+       errno = 0;
+       parsed = strtoul(service, &tmp, 10);
+       if (errno || *tmp != '\0')
+               return 0; /* Ok, not a number */
+
+       /*
+        * 'getaddrinfo' isn't very strict validating the service when a port
+        * number is indicated. If a port larger than the max (65535) is
+        * received, the 16 rightmost bits are utilized as the port and set at
+        * the addrinfo returned.
+        *
+        * So, a manual validation is implemented. Port is actually a uint16_t,
+        * so read what's necessary and compare using the same data type.
+        */
+       port = (unsigned char)((*result)->ai_addr->sa_data[0]) << 8;
+       port += (unsigned char)((*result)->ai_addr->sa_data[1]);
+       if (parsed != port)
+               return pr_err("Service port %s is out of range (max value is %d)",
+                   service, USHRT_MAX);
+
        return 0;
 }
 
@@ -64,6 +86,7 @@ create_server_socket(int *result)
 {
        struct addrinfo *addrs;
        struct addrinfo *addr;
+       unsigned long port;
        int fd; /* "file descriptor" */
        int error;
 
@@ -90,7 +113,18 @@ create_server_socket(int *result)
                        continue;
                }
 
-               printf("Success.\n");
+               error = getsockname(fd, addr->ai_addr, &addr->ai_addrlen);
+               if (error) {
+                       close(fd);
+                       freeaddrinfo(addrs);
+                       return pr_errno(errno, "getsockname() failed");
+               }
+
+               port = (unsigned char)(addr->ai_addr->sa_data[0]) << 8;
+               port += (unsigned char)(addr->ai_addr->sa_data[1]);
+               printf("Success, bound to address '%s', port '%ld'.\n",
+                   (addr->ai_canonname != NULL) ? addr->ai_canonname : "any",
+                   port);
                freeaddrinfo(addrs);
                *result = fd;
                return 0; /* Happy path */
@@ -305,30 +339,6 @@ handle_client_connections(int server_fd)
        return 0; /* Unreachable. */
 }
 
-static void
-signal_handler(int signal, siginfo_t *info, void *param)
-{
-       /* Empty handler */
-}
-
-static int
-init_signal_handler(void)
-{
-       int error;
-
-       memset(&act, 0, sizeof act);
-       sigemptyset(&act.sa_mask);
-       act.sa_flags = SA_SIGINFO;
-       act.sa_sigaction = signal_handler;
-
-       error = sigaction(SIGINT, &act, NULL);
-       if (error) {
-               pr_errno(errno, "Error initializing signal handler");
-               error = -errno;
-       }
-       return error;
-}
-
 /*
  * Receive @arg to be called as a clients_foreach_cb
  */
@@ -369,10 +379,6 @@ rtr_listen(void)
        int server_fd; /* "file descriptor" */
        int error;
 
-       error = init_signal_handler();
-       if (error)
-               return error;
-
        error = clients_db_init();
        if (error)
                return error;
index 5f683be9748fdcc62236e4928bfa2717c83038f5..be592d85d7009ffc2ecd8ffd33d9a8762ba66bae 100644 (file)
@@ -7,10 +7,20 @@
 #include "data_structure/array_list.h"
 #include "object/router_key.h"
 
-ARRAY_LIST(al_filter_prefix, struct slurm_prefix)
-ARRAY_LIST(al_assertion_prefix, struct slurm_prefix)
-ARRAY_LIST(al_filter_bgpsec, struct slurm_bgpsec)
-ARRAY_LIST(al_assertion_bgpsec, struct slurm_bgpsec)
+struct slurm_prefix_ctx {
+       struct slurm_prefix element;
+       int ctx;
+};
+
+struct slurm_bgpsec_ctx {
+       struct slurm_bgpsec element;
+       int ctx;
+};
+
+ARRAY_LIST(al_filter_prefix, struct slurm_prefix_ctx)
+ARRAY_LIST(al_assertion_prefix, struct slurm_prefix_ctx)
+ARRAY_LIST(al_filter_bgpsec, struct slurm_bgpsec_ctx)
+ARRAY_LIST(al_assertion_bgpsec, struct slurm_bgpsec_ctx)
 
 struct arraylist_db {
        struct al_filter_prefix filter_pfx_al;
@@ -29,13 +39,20 @@ slurm_db_init(void)
 }
 
 static bool
-prefix_filtered_by(struct slurm_prefix *filter, struct slurm_prefix *prefix)
+prefix_filtered_by(struct slurm_prefix *filter, struct slurm_prefix *prefix,
+    bool exact_match)
 {
        struct vrp *filter_vrp, *prefix_vrp;
 
        filter_vrp = &filter->vrp;
        prefix_vrp = &prefix->vrp;
 
+       /* The filter has ASN and prefix */
+       if (exact_match && (filter->data_flag & ~SLURM_COM_FLAG_COMMENT) ==
+           (SLURM_COM_FLAG_ASN | SLURM_PFX_FLAG_PREFIX))
+               return VRP_ASN_EQ(filter_vrp, prefix_vrp) &&
+                   VRP_PREFIX_COV(filter_vrp, prefix_vrp);
+
        /* Both have ASN */
        if ((filter->data_flag & SLURM_COM_FLAG_ASN) > 0 &&
            (prefix->data_flag & SLURM_COM_FLAG_ASN) > 0)
@@ -44,45 +61,93 @@ prefix_filtered_by(struct slurm_prefix *filter, struct slurm_prefix *prefix)
        /* Both have a prefix of the same type */
        if ((filter->data_flag & SLURM_PFX_FLAG_PREFIX) > 0 &&
            (prefix->data_flag & SLURM_PFX_FLAG_PREFIX) > 0)
-               return VRP_PREFIX_EQ(filter_vrp, prefix_vrp);
+               return VRP_PREFIX_COV(filter_vrp, prefix_vrp);
 
        return false;
 }
 
 static bool
-prefix_equal(struct slurm_prefix *left, struct slurm_prefix *right,
-    bool filter)
+prefix_contained(struct slurm_prefix_ctx *left_ctx, struct slurm_prefix *right,
+    int ctx)
 {
+       struct slurm_prefix *left;
+       struct vrp *left_vrp, *right_vrp;
+
+       /*
+        * rfc8416#section-4.2:
+        * 1. There may be conflicting changes to ROA Prefix Assertions if an
+        *    IP address X and distinct SLURM files Y and Z exist such that X
+        *    is contained by any prefix in any "prefixAssertions" or
+        *    "prefixFilters" in file Y and X is contained by any prefix in any
+        *    "prefixAssertions" or "prefixFilters" in file Z.
+        *
+        * A negative @ctx or an equal context will avoid this check.
+        */
+       if (ctx < 0 || ctx == left_ctx->ctx)
+               return false;
+
+       left = &left_ctx->element;
+       left_vrp = &left->vrp;
+       right_vrp = &right->vrp;
+
+       return (left->data_flag & SLURM_PFX_FLAG_PREFIX) > 0 &&
+           (right->data_flag & SLURM_PFX_FLAG_PREFIX) > 0 &&
+           VRP_PREFIX_COV(left_vrp, right_vrp);
+}
+
+/*
+ * @left_ctx is the prefix loaded from SLURM, @right is the VRP "masked" as a
+ * slurm prefix
+ */
+static bool
+prefix_equal(struct slurm_prefix_ctx *left_ctx, struct slurm_prefix *right,
+    int ctx, bool filter, bool exact_match)
+{
+       struct slurm_prefix *left;
        struct vrp *left_vrp, *right_vrp;
        bool equal;
 
+       left = &left_ctx->element;
        left_vrp = &left->vrp;
        right_vrp = &right->vrp;
 
-       /* Ignore the comments */
+       if (prefix_contained(left_ctx, right, ctx))
+               return true;
+
+       /*
+        * Ignore the comments, remember: FILTERS don't have the same data (no
+        * max_length is declared), while ASSERTIONS do.
+        */
        if ((left->data_flag & ~SLURM_COM_FLAG_COMMENT) !=
            (right->data_flag & ~SLURM_COM_FLAG_COMMENT))
-               return filter && prefix_filtered_by(left, right);
+               return filter && prefix_filtered_by(left, right, exact_match);
 
        /* It has the same data, compare it */
        equal = true;
-       if ((left->data_flag & SLURM_COM_FLAG_ASN) > 0)
-               equal = equal && VRP_ASN_EQ(left_vrp, right_vrp);
+       if (equal && (left->data_flag & SLURM_COM_FLAG_ASN) > 0)
+               equal = VRP_ASN_EQ(left_vrp, right_vrp);
 
        if (equal && (left->data_flag & SLURM_PFX_FLAG_PREFIX) > 0)
-               equal = equal && VRP_PREFIX_EQ(left_vrp, right_vrp);
+               equal = (filter ?
+                   VRP_PREFIX_COV(left_vrp, right_vrp) :
+                   VRP_PREFIX_EQ(left_vrp, right_vrp));
 
        if (equal && (left->data_flag & SLURM_PFX_FLAG_MAX_LENGTH) > 0)
-               equal = equal &&
-                   ((left->data_flag & SLURM_PFX_FLAG_MAX_LENGTH) > 0) &&
-                   VRP_MAX_PREFIX_LEN_EQ(left_vrp, right_vrp);
+               equal = VRP_MAX_PREFIX_LEN_EQ(left_vrp, right_vrp);
 
        return equal;
 }
 
 static bool
-bgpsec_filtered_by(struct slurm_bgpsec *bgpsec, struct slurm_bgpsec *filter)
+bgpsec_filtered_by(struct slurm_bgpsec *bgpsec, struct slurm_bgpsec *filter,
+    bool exact_match)
 {
+       /* The filter has ASN and SKI */
+       if (exact_match && (filter->data_flag & ~SLURM_COM_FLAG_COMMENT) ==
+           (SLURM_COM_FLAG_ASN | SLURM_BGPS_FLAG_SKI))
+               return bgpsec->asn == filter->asn &&
+                   memcmp(bgpsec->ski, filter->ski, RK_SKI_LEN) == 0;
+
        /* Both have ASN */
        if ((bgpsec->data_flag & SLURM_COM_FLAG_ASN) > 0 &&
            (filter->data_flag & SLURM_COM_FLAG_ASN) > 0)
@@ -91,74 +156,119 @@ bgpsec_filtered_by(struct slurm_bgpsec *bgpsec, struct slurm_bgpsec *filter)
        /* Both have a SKI */
        if ((bgpsec->data_flag & SLURM_BGPS_FLAG_SKI) > 0 &&
            (filter->data_flag & SLURM_BGPS_FLAG_SKI) > 0)
-               return memcmp(bgpsec->ski, filter->ski, RK_SKI_LEN) == 0;
+               return memcmp(bgpsec->ski, filter->ski, RK_SPKI_LEN) == 0;
 
        return false;
 }
 
 static bool
-bgpsec_equal(struct slurm_bgpsec *left, struct slurm_bgpsec *right,
-    bool filter)
+bgpsec_contained(struct slurm_bgpsec_ctx *left_ctx, struct slurm_bgpsec *right,
+    int ctx)
+{
+       struct slurm_bgpsec *left;
+
+       /*
+        * rfc8416#section-4.2:
+        * 2. There may be conflicting changes to BGPsec Assertions if an ASN X
+        *    and distinct SLURM files Y and Z exist such that X is used in any
+        *    "bgpsecAssertions" or "bgpsecFilters" in file Y and X is used in
+        *    any "bgpsecAssertions" or "bgpsecFilters" in file Z.
+        *
+        * A negative @ctx or an equal context will avoid this check.
+        */
+       if (ctx < 0 || ctx == left_ctx->ctx)
+               return false;
+
+       left = &left_ctx->element;
+
+       return (left->data_flag & SLURM_COM_FLAG_ASN) > 0 &&
+           (right->data_flag & SLURM_COM_FLAG_ASN) > 0 &&
+           left->asn == right->asn;
+}
+
+static bool
+bgpsec_equal(struct slurm_bgpsec_ctx *left_ctx, struct slurm_bgpsec *right,
+    int ctx, bool filter, bool exact_filter)
 {
+       struct slurm_bgpsec *left;
        bool equal;
 
+       left = &left_ctx->element;
+
+       if (bgpsec_contained(left_ctx, right, ctx))
+               return true;
+
        /* Ignore the comments */
        if ((left->data_flag & ~SLURM_COM_FLAG_COMMENT) !=
            (right->data_flag & ~SLURM_COM_FLAG_COMMENT))
-               return filter && bgpsec_filtered_by(left, right);
+               return filter && bgpsec_filtered_by(left, right, exact_filter);
 
        /* It has the same data, compare it */
        equal = true;
-       if ((left->data_flag & SLURM_COM_FLAG_ASN) > 0)
-               equal = equal && left->asn == right->asn;
+       if (equal && (left->data_flag & SLURM_COM_FLAG_ASN) > 0)
+               equal = left->asn == right->asn;
 
        if (equal && (left->data_flag & SLURM_BGPS_FLAG_SKI) > 0)
-               equal = equal &&
-                   memcmp(left->ski, right->ski, RK_SKI_LEN) == 0;
+               equal = memcmp(left->ski, right->ski, RK_SKI_LEN) == 0;
 
        if (equal && (left->data_flag & SLURM_BGPS_FLAG_ROUTER_KEY) > 0)
-               equal = equal &&
-                   memcmp(left->router_public_key, right->router_public_key,
-                   RK_SPKI_LEN) == 0;
+               equal = memcmp(left->router_public_key,
+                   right->router_public_key, RK_SPKI_LEN) == 0;
 
        return equal;
 }
 
-#define ADD_FUNCS(name, type, list_name, db_list, equal_cb, filter)    \
+#define ADD_FUNCS(name, type, list_name, db_list, db_alt_list, equal_cb,\
+    cont_cb, filter)                                                   \
        static type *                                                   \
-       name##_locate(type *obj)                                        \
+       name##_locate(type *obj, bool flt, int ctx)                     \
        {                                                               \
-               type *cursor;                                           \
+               type##_ctx *cursor;                                     \
                array_index i;                                          \
                                                                        \
                ARRAYLIST_FOREACH(db_list, cursor, i)                   \
-                       if (equal_cb(cursor, obj, filter))              \
-                               return cursor;                          \
+                       if (equal_cb(cursor, obj, ctx, filter, flt))    \
+                               return &cursor->element;                \
+                                                                       \
+               if (ctx < 0)                                            \
+                       return NULL; /* Avoid the next loop */          \
+                                                                       \
+               ARRAYLIST_FOREACH(db_alt_list, cursor, i)               \
+                       if (cont_cb(cursor, obj, ctx))                  \
+                               return &cursor->element;                \
                                                                        \
                return NULL;                                            \
        }                                                               \
                                                                        \
        static bool                                                     \
-       name##_exists(type *obj)                                        \
+       name##_exists(type *obj, bool flt, int ctx)                     \
        {                                                               \
-               return name##_locate(obj) != NULL;                      \
+               return name##_locate(obj, flt, ctx) != NULL;            \
        }                                                               \
                                                                        \
        int                                                             \
-       slurm_db_add_##name(type *elem) {                               \
-               if (name##_exists(elem))                                \
+       slurm_db_add_##name(type *elem, int ctx)                        \
+       {                                                               \
+               type##_ctx new_elem;                                    \
+               if (name##_exists(elem, !filter, ctx))                  \
                        return -EEXIST;                                 \
-               return list_name##_add(db_list, elem);                  \
+               new_elem.element = *elem;                               \
+               new_elem.ctx = ctx;                                     \
+               return list_name##_add(db_list, &new_elem);             \
        }
 
 ADD_FUNCS(prefix_filter, struct slurm_prefix, al_filter_prefix,
-    &array_lists_db.filter_pfx_al, prefix_equal, true)
+    &array_lists_db.filter_pfx_al, &array_lists_db.assertion_pfx_al,
+    prefix_equal, prefix_contained, true)
 ADD_FUNCS(bgpsec_filter, struct slurm_bgpsec, al_filter_bgpsec,
-    &array_lists_db.filter_bgps_al, bgpsec_equal, true)
+    &array_lists_db.filter_bgps_al, &array_lists_db.assertion_bgps_al,
+    bgpsec_equal, bgpsec_contained, true)
 ADD_FUNCS(prefix_assertion, struct slurm_prefix, al_assertion_prefix,
-    &array_lists_db.assertion_pfx_al, prefix_equal, false)
+    &array_lists_db.assertion_pfx_al, &array_lists_db.filter_pfx_al,
+    prefix_equal, prefix_contained, false)
 ADD_FUNCS(bgpsec_assertion, struct slurm_bgpsec, al_assertion_bgpsec,
-    &array_lists_db.assertion_bgps_al, bgpsec_equal, false)
+    &array_lists_db.assertion_bgps_al, &array_lists_db.filter_bgps_al,
+    bgpsec_equal, bgpsec_contained, false)
 
 bool
 slurm_db_vrp_is_filtered(struct vrp const *vrp)
@@ -170,18 +280,18 @@ slurm_db_vrp_is_filtered(struct vrp const *vrp)
        slurm_prefix.vrp = *vrp;
        slurm_prefix.comment = NULL;
 
-       return prefix_filter_exists(&slurm_prefix);
+       return prefix_filter_exists(&slurm_prefix, true, -1);
 }
 
 int
 slurm_db_foreach_assertion_prefix(assertion_pfx_foreach_cb cb, void *arg)
 {
-       struct slurm_prefix *cursor;
+       struct slurm_prefix_ctx *cursor;
        array_index i;
        int error;
 
        ARRAYLIST_FOREACH(&array_lists_db.assertion_pfx_al, cursor, i) {
-               error = cb(cursor, arg);
+               error = cb(&cursor->element, arg);
                if (error)
                        return error;
        }
@@ -209,7 +319,7 @@ slurm_db_bgpsec_is_filtered(struct router_key const *key)
        slurm_bgpsec.router_public_key = NULL;
        slurm_bgpsec.comment = NULL;
 
-       result = bgpsec_filter_exists(&slurm_bgpsec);
+       result = bgpsec_filter_exists(&slurm_bgpsec, true, -1);
        free(tmp);
        return result;
 }
@@ -217,12 +327,12 @@ slurm_db_bgpsec_is_filtered(struct router_key const *key)
 int
 slurm_db_foreach_assertion_bgpsec(assertion_bgpsec_foreach_cb cb, void *arg)
 {
-       struct slurm_bgpsec *cursor;
+       struct slurm_bgpsec_ctx *cursor;
        array_index i;
        int error;
 
        ARRAYLIST_FOREACH(&array_lists_db.assertion_bgps_al, cursor, i) {
-               error = cb(cursor, arg);
+               error = cb(&cursor->element, arg);
                if (error)
                        return error;
        }
@@ -231,21 +341,21 @@ slurm_db_foreach_assertion_bgpsec(assertion_bgpsec_foreach_cb cb, void *arg)
 }
 
 static void
-clean_slurm_prefix(struct slurm_prefix *prefix)
+clean_slurm_prefix(struct slurm_prefix_ctx *prefix)
 {
-       if ((prefix->data_flag & SLURM_COM_FLAG_COMMENT) > 0)
-               free(prefix->comment);
+       if ((prefix->element.data_flag & SLURM_COM_FLAG_COMMENT) > 0)
+               free(prefix->element.comment);
 }
 
 static void
-clean_slurm_bgpsec(struct slurm_bgpsec *bgpsec)
+clean_slurm_bgpsec(struct slurm_bgpsec_ctx *bgpsec)
 {
-       if ((bgpsec->data_flag & SLURM_BGPS_FLAG_SKI) > 0)
-               free(bgpsec->ski);
-       if ((bgpsec->data_flag & SLURM_BGPS_FLAG_ROUTER_KEY) > 0)
-               free(bgpsec->router_public_key);
-       if ((bgpsec->data_flag & SLURM_COM_FLAG_COMMENT) > 0)
-               free(bgpsec->comment);
+       if ((bgpsec->element.data_flag & SLURM_BGPS_FLAG_SKI) > 0)
+               free(bgpsec->element.ski);
+       if ((bgpsec->element.data_flag & SLURM_BGPS_FLAG_ROUTER_KEY) > 0)
+               free(bgpsec->element.router_public_key);
+       if ((bgpsec->element.data_flag & SLURM_COM_FLAG_COMMENT) > 0)
+               free(bgpsec->element.comment);
 }
 
 void
index 971f6f3e4be27ff42cc5fba6a3d2b72e9c33c7f4..7b5d9190c77ce3e9bad06059db64c50d3717f4dd 100644 (file)
@@ -3,33 +3,17 @@
 
 #include <stdbool.h>
 #include "slurm/slurm_parser.h"
-
-struct slurm_prefix_list {
-       struct slurm_prefix *list;
-       unsigned int len;
-};
-
-struct slurm_bgpsec_list {
-       struct slurm_bgpsec *list;
-       unsigned int len;
-};
-
-struct slurm_db {
-       struct slurm_prefix_list prefix_filters;
-       struct slurm_bgpsec_list bgpsec_filters;
-       struct slurm_prefix_list prefix_assertions;
-       struct slurm_bgpsec_list bgpsec_assertions;
-};
+#include "rtr/db/vrp.h"
 
 typedef int (*assertion_pfx_foreach_cb)(struct slurm_prefix *, void *);
 typedef int (*assertion_bgpsec_foreach_cb)(struct slurm_bgpsec *, void *);
 
 void slurm_db_init(void);
 
-int slurm_db_add_prefix_filter(struct slurm_prefix *);
-int slurm_db_add_prefix_assertion(struct slurm_prefix *);
-int slurm_db_add_bgpsec_filter(struct slurm_bgpsec *);
-int slurm_db_add_bgpsec_assertion(struct slurm_bgpsec *);
+int slurm_db_add_prefix_filter(struct slurm_prefix *, int);
+int slurm_db_add_prefix_assertion(struct slurm_prefix *, int);
+int slurm_db_add_bgpsec_filter(struct slurm_bgpsec *, int);
+int slurm_db_add_bgpsec_assertion(struct slurm_bgpsec *, int);
 
 bool slurm_db_vrp_is_filtered(struct vrp const *);
 int slurm_db_foreach_assertion_prefix(assertion_pfx_foreach_cb, void *);
index f904cae98d17e7c15854e46eb544ce9d481a7104..1e65a36bfd1d15f54de10211435ac0228a3b1d52 100644 (file)
@@ -16,6 +16,7 @@
 static int
 slurm_load(bool *loaded)
 {
+       int ctx = 0; /* Context (file number) */
        /* Optional configuration */
        *loaded = false;
        if (config_get_slurm() == NULL)
@@ -24,8 +25,8 @@ slurm_load(bool *loaded)
        *loaded = true;
        slurm_db_init();
 
-       return process_file_or_dir(config_get_slurm(),
-           SLURM_FILE_EXTENSION, slurm_parse, NULL);
+       return process_file_or_dir(config_get_slurm(), SLURM_FILE_EXTENSION,
+           slurm_parse, &ctx);
 }
 
 static void
index a432de2788d247bbfbaf9747fffa0fae4fd526e5..a9aa77d79f9db11c5050ac3c00bf4fc141426fcc 100644 (file)
        if (element == NULL)                                            \
                return pr_err("SLURM member '%s' is required", name);
 
-static int handle_json(json_t *);
+/* Context value, local to avoid forwarding the parameter */
+int cur_ctx;
+
+static int handle_json(json_t *, int *);
 
 int
 slurm_parse(char const *location, void *arg)
@@ -54,7 +57,7 @@ slurm_parse(char const *location, void *arg)
                return -ENOENT;
        }
 
-       error = handle_json(json_root);
+       error = handle_json(json_root, arg);
 
        json_decref(json_root);
        return error;
@@ -412,7 +415,7 @@ load_single_prefix(json_t *object, bool is_assertion)
                        goto release_comment;
                }
 
-               error = slurm_db_add_prefix_filter(&result);
+               error = slurm_db_add_prefix_filter(&result, cur_ctx);
                if (error)
                        goto release_comment;
 
@@ -439,7 +442,7 @@ load_single_prefix(json_t *object, bool is_assertion)
                goto release_comment;
        }
 
-       error = slurm_db_add_prefix_assertion(&result);
+       error = slurm_db_add_prefix_assertion(&result, cur_ctx);
        if (error)
                goto release_comment;
 
@@ -458,21 +461,24 @@ load_prefix_array(json_t *array, bool is_assertion)
 
        json_array_foreach(array, index, element) {
                error = load_single_prefix(element, is_assertion);
-               if (error) {
-                       if (error == -EEXIST)
-                               pr_err(
-                                   "The prefix %s element #%d, is duplicated or covered by another %s; SLURM loading will be stopped",
-                                   (is_assertion ? "assertion" : "filter"),
-                                   index + 1,
-                                   (is_assertion ? "assertion" : "filter"));
-                       else
-                               pr_err(
-                                   "Error at prefix %s, element #%d, SLURM loading will be stopped",
-                                   (is_assertion ? "assertions" : "filters"),
-                                   index + 1);
+               if (!error)
+                       continue;
+               if (error == -EEXIST)
+                       pr_err(
+                           "The prefix %s element \"%s\", is duplicated or covered by another %s; SLURM loading will be stopped.%s",
+                           (is_assertion ? "assertion" : "filter"),
+                           json_dumps(element, 0),
+                           (is_assertion ? "assertion" : "filter"),
+                           (cur_ctx > 0
+                           ? " TIP: More than 1 SLURM files were found, check if the prefix is contained in multiple files (see RFC 8416 section 4.2)."
+                           : ""));
+               else
+                       pr_err(
+                           "Error at prefix %s, element \"%s\", SLURM loading will be stopped",
+                           (is_assertion ? "assertions" : "filters"),
+                           json_dumps(element, 0));
 
-                       return error;
-               }
+               return error;
        }
 
        return 0;
@@ -543,7 +549,7 @@ load_single_bgpsec(json_t *object, bool is_assertion)
                        goto release_comment;
                }
 
-               error = slurm_db_add_bgpsec_filter(&result);
+               error = slurm_db_add_bgpsec_filter(&result, cur_ctx);
                if (error)
                        goto release_comment;
 
@@ -557,7 +563,7 @@ load_single_bgpsec(json_t *object, bool is_assertion)
                goto release_comment;
        }
 
-       error = slurm_db_add_bgpsec_assertion(&result);
+       error = slurm_db_add_bgpsec_assertion(&result, cur_ctx);
        if (error)
                goto release_comment;
 
@@ -584,15 +590,18 @@ load_bgpsec_array(json_t *array, bool is_assertion)
                        continue;
                if (error == -EEXIST)
                        pr_err(
-                           "The bgpsec %s element #%d, is duplicated or covered by another %s; SLURM loading will be stopped",
+                           "The bgpsec %s element \"%s\", is duplicated or covered by another %s; SLURM loading will be stopped.%s",
+                           (is_assertion ? "assertion" : "filter"),
+                           json_dumps(element, 0),
                            (is_assertion ? "assertion" : "filter"),
-                           index + 1,
-                           (is_assertion ? "assertion" : "filter"));
+                           (cur_ctx > 0
+                           ? " TIP: More than 1 SLURM files were found, check if the ASN is contained in multiple files (see RFC 8416 section 4.2)."
+                           : ""));
                else
                        pr_err(
-                           "Error at bgpsec %s, element #%d, SLURM loading will be stopped",
+                           "Error at bgpsec %s, element \"%s\", SLURM loading will be stopped",
                            (is_assertion ? "assertions" : "filters"),
-                           index + 1);
+                           json_dumps(element, 0));
 
                return error;
        }
@@ -688,7 +697,7 @@ load_assertions(json_t *root)
 }
 
 static int
-handle_json(json_t *root)
+handle_json(json_t *root, int *ctx)
 {
        size_t expected_members;
        int error;
@@ -696,6 +705,8 @@ handle_json(json_t *root)
        if (!json_is_object(root))
                return pr_err("The root of the SLURM is not a JSON object.");
 
+       cur_ctx = *ctx;
+
        error = load_version(root);
        if (error)
                return error;
@@ -714,5 +725,7 @@ handle_json(json_t *root)
                    "SLURM root must have only %lu members (RFC 8416 section 3.2)",
                    expected_members);
 
+       (*ctx)++; /* Next time will be another context */
+
        return 0;
 }
index b136bdc2f52ffeb3c19ed17eb4ab3245a4f8121b..f35513925cc0919b6c92e14951a846f81fc7e4af 100644 (file)
 struct validation {
        struct tal *tal;
 
-       /** https://www.openssl.org/docs/man1.1.1/man3/X509_STORE_load_locations.html */
-       X509_STORE *store;
+       struct x509_data {
+               /** https://www.openssl.org/docs/man1.1.1/man3/X509_STORE_load_locations.html */
+               X509_STORE *store;
+               X509_VERIFY_PARAM *params;
+       } x509_data;
 
        struct cert_stack *certstack;
 
@@ -79,6 +82,7 @@ validation_prepare(struct validation **out, struct tal *tal,
     struct validation_handler *validation_handler)
 {
        struct validation *result;
+       X509_VERIFY_PARAM *params;
        int error;
 
        result = malloc(sizeof(struct validation));
@@ -91,26 +95,36 @@ validation_prepare(struct validation **out, struct tal *tal,
 
        result->tal = tal;
 
-       result->store = X509_STORE_new();
-       if (!result->store) {
+       result->x509_data.store = X509_STORE_new();
+       if (!result->x509_data.store) {
                error = crypto_err("X509_STORE_new() returned NULL");
                goto abort1;
        }
 
-       X509_STORE_set_verify_cb(result->store, cb);
+       params = X509_VERIFY_PARAM_new();
+       if (params == NULL) {
+               error = pr_enomem();
+               goto abort2;
+       }
+
+       X509_VERIFY_PARAM_set_flags(params, X509_V_FLAG_CRL_CHECK);
+       X509_STORE_set1_param(result->x509_data.store, params);
+       X509_STORE_set_verify_cb(result->x509_data.store, cb);
 
        error = certstack_create(&result->certstack);
        if (error)
-               goto abort2;
+               goto abort3;
 
        result->pubkey_state = PKS_UNTESTED;
        result->validation_handler = *validation_handler;
+       result->x509_data.params = params; /* Ownership transfered */
 
        *out = result;
        return 0;
-
+abort3:
+       X509_VERIFY_PARAM_free(params);
 abort2:
-       X509_STORE_free(result->store);
+       X509_STORE_free(result->x509_data.store);
 abort1:
        free(result);
        return error;
@@ -119,7 +133,8 @@ abort1:
 void
 validation_destroy(struct validation *state)
 {
-       X509_STORE_free(state->store);
+       X509_VERIFY_PARAM_free(state->x509_data.params);
+       X509_STORE_free(state->x509_data.store);
        certstack_destroy(state->certstack);
        free(state);
 }
@@ -133,7 +148,7 @@ validation_tal(struct validation *state)
 X509_STORE *
 validation_store(struct validation *state)
 {
-       return state->store;
+       return state->x509_data.store;
 }
 
 struct cert_stack *
index 7868ff27cb0ff6f01783e88dc03021fcb7947621..622c8bb15d32e2d0d94afce9f62d01543685267f 100644 (file)
@@ -21,6 +21,9 @@ check_vrps_updates(void *param_void)
 
        do {
                error = vrps_update(&changed);
+               if (error == -EINTR)
+                       break; /* Process interrupted, terminate thread */
+
                if (error) {
                        pr_err("Error code %d while trying to update the ROA database. Sleeping...",
                            error);
index 549709b24833095966d3f25643049b3b5982fa04..42ec30adb72441d76386b58b169359919231d803 100644 (file)
@@ -66,9 +66,11 @@ rtr_primitive_reader_test_SOURCES = rtr/primitive_reader_test.c
 rtr_primitive_reader_test_LDADD = ${MY_LDADD}
 
 EXTRA_DIST  = impersonator.c
-EXTRA_DIST += rtr/db/rtr_db_impersonator.c
 EXTRA_DIST += line_file/core.txt
 EXTRA_DIST += line_file/empty.txt
 EXTRA_DIST += line_file/error.txt
+EXTRA_DIST += rtr/stream.c rtr/stream.h
+EXTRA_DIST += rtr/db/rtr_db_impersonator.c
+EXTRA_DIST += tal/lacnic.tal
 
 endif