1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
/* $OpenBSD: rrdp_util.c,v 1.1 2021/11/24 15:24:16 claudio Exp $ */
/*
* Copyright (c) 2020 Nils Fisher <nils_fisher@hotmail.com>
* Copyright (c) 2021 Claudio Jeker <claudio@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <assert.h>
#include <err.h>
#include <stdlib.h>
#include <string.h>
#include <expat.h>
#include <openssl/sha.h>
#include "extern.h"
#include "rrdp.h"
/*
* Both snapshots and deltas use publish_xml to store the publish and
* withdraw records. Once all the content is added the request is sent
* to the main process where it is processed.
*/
struct publish_xml *
new_publish_xml(enum publish_type type, char *uri, char *hash, size_t hlen)
{
struct publish_xml *pxml;
if ((pxml = calloc(1, sizeof(*pxml))) == NULL)
err(1, "%s", __func__);
pxml->type = type;
pxml->uri = uri;
if (hlen > 0) {
assert(hlen == sizeof(pxml->hash));
memcpy(pxml->hash, hash, hlen);
}
return pxml;
}
void
free_publish_xml(struct publish_xml *pxml)
{
if (pxml == NULL)
return;
free(pxml->uri);
free(pxml->data);
free(pxml);
}
/*
* Add buf to the base64 data string, ensure that this remains a proper
* string by NUL-terminating the string.
*/
int
publish_add_content(struct publish_xml *pxml, const char *buf, int length)
{
size_t newlen, outlen;
/*
* optmisiation, this often gets called with '\n' as the
* only data... seems wasteful
*/
if (length == 1 && buf[0] == '\n')
return 0;
/* append content to data */
if (SIZE_MAX - length - 1 <= pxml->data_length)
return -1;
newlen = pxml->data_length + length;
if (base64_decode_len(newlen, &outlen) == -1 ||
outlen > MAX_FILE_SIZE)
return -1;
pxml->data = realloc(pxml->data, newlen + 1);
if (pxml->data == NULL)
err(1, "%s", __func__);
memcpy(pxml->data + pxml->data_length, buf, length);
pxml->data[newlen] = '\0';
pxml->data_length = newlen;
return 0;
}
/*
* Base64 decode the data blob and send the file to the main process
* where the hash is validated and the file stored in the repository.
* Increase the file_pending counter to ensure the RRDP process waits
* until all files have been processed before moving to the next stage.
* Returns 0 on success or -1 on errors (base64 decode failed).
*/
int
publish_done(struct rrdp *s, struct publish_xml *pxml)
{
unsigned char *data = NULL;
size_t datasz = 0;
if (pxml->data_length > 0)
if ((base64_decode(pxml->data, pxml->data_length,
&data, &datasz)) == -1)
return -1;
rrdp_publish_file(s, pxml, data, datasz);
free(data);
free_publish_xml(pxml);
return 0;
}
|