Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

gdp / apps / gcl-clone.c @ master

History | View | Annotate | Download (5.15 KB)

1 e41ced34 Eric Allman
/* vim: set ai sw=4 sts=4 ts=4 : */
2
3
/*
4
**  LOG-CLONE --- clone a log --- essentially the same as doing
5
**                a gcl-create with the same metadata but on a different
6
**                server.  We can't actually do that because the meta
7
**                differs (notably creation time).
8
**
9
**                Note: it does NOT copy any data.  This program is only
10
**                intended for research purposes.
11
**
12
**                This is a temporary interface.  Ultimately we need a log
13
**                creation service that does reasonable log placement rather
14
**                than having to name a specific log server.
15
**
16
**        ----- BEGIN LICENSE BLOCK -----
17
**        Applications for the Global Data Plane
18
**        From the Ubiquitous Swarm Lab, 490 Cory Hall, U.C. Berkeley.
19
**
20 c87dd166 Eric Allman
**        Copyright (c) 2015-2019, Regents of the University of California.
21 e41ced34 Eric Allman
**        All rights reserved.
22
**
23
**        Permission is hereby granted, without written agreement and without
24
**        license or royalty fees, to use, copy, modify, and distribute this
25
**        software and its documentation for any purpose, provided that the above
26
**        copyright notice and the following two paragraphs appear in all copies
27
**        of this software.
28
**
29
**        IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
30
**        SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST
31
**        PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
32
**        EVEN IF REGENTS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
**
34
**        REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
35
**        LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
36
**        FOR A PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION,
37
**        IF ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO
38
**        OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
39
**        OR MODIFICATIONS.
40
**        ----- END LICENSE BLOCK -----
41
*/
42
43
#include <ep/ep.h>
44
#include <ep/ep_app.h>
45
#include <ep/ep_crypto.h>
46
#include <ep/ep_dbg.h>
47
#include <ep/ep_string.h>
48
#include <gdp/gdp.h>
49
50
#include <openssl/rsa.h>
51
#include <openssl/engine.h>
52
#include <openssl/pem.h>
53
54
#include <unistd.h>
55
#include <fcntl.h>
56
#include <getopt.h>
57
#include <netdb.h>
58
#include <pwd.h>
59
#include <string.h>
60
#include <sysexits.h>
61
#include <unistd.h>
62
#include <sys/stat.h>
63
64
65
// minimum secure key length
66
#ifndef GDP_MIN_KEY_LEN
67
# define GDP_MIN_KEY_LEN                1024
68
#endif // GDP_MIN_KEY_LEN
69
70
static EP_DBG        Dbg = EP_DBG_INIT("gdp.gcl-clone", "Clone log app");
71
72
void
73
usage(void)
74
{
75
        fprintf(stderr, "Usage: %s [-D dbgspec] [-G gdpd_addr]\n"
76
                        "\tgcl_name logd_name ...\n"
77
                        "    -D  set debugging flags\n"
78
                        "    -G  IP host to contact for GDP router\n"
79
                        "    gcl_name is the name of the GCL to be cloned\n"
80
                        "    logd_name is the name of the log server(s) to host this log\n",
81
                        ep_app_getprogname());
82
        exit(EX_USAGE);
83
}
84
85
86
int
87
main(int argc, char **argv)
88
{
89
        gdp_name_t gcliname;                        // internal name of GCL
90
        const char *gclxname = NULL;        // external name of GCL
91
        gdp_gcl_t *gcl = NULL;
92 eae1d3ec Eric Allman
        gdp_gob_md_t *gmd = NULL;
93 e41ced34 Eric Allman
        int opt;
94
        EP_STAT estat;
95
        char *gdpd_addr = NULL;
96
        char ebuf[100];
97
        bool show_usage = false;
98
        bool quiet = false;
99
100
        // collect command-line arguments
101
        while ((opt = getopt(argc, argv, "D:G:")) > 0)
102
        {
103
                switch (opt)
104
                {
105
                 case 'D':
106
                        ep_dbg_set(optarg);
107
                        break;
108
109
                 case 'G':
110
                        gdpd_addr = optarg;
111
                        break;
112
113
                 default:
114
                        show_usage = true;
115
                        break;
116
                }
117
        }
118
        argc -= optind;
119
        argv += optind;
120
121
        if (show_usage || argc-- < 2)
122
                usage();
123
124
        gclxname = *argv++;
125
126
        // initialize the GDP library
127
        estat = gdp_init(gdpd_addr);
128
        if (!EP_STAT_ISOK(estat))
129
        {
130
                ep_app_error("GDP Initialization failed");
131
                goto fail0;
132
        }
133
134
        // allow thread to settle to avoid interspersed debug output
135
        ep_time_nanosleep(INT64_C(100000000));
136
137
        // open the existing log to get the metadata
138
        estat = gdp_parse_name(gclxname, gcliname);
139 22f2276a Eric Allman
        if (EP_STAT_ISFAIL(estat))
140 e41ced34 Eric Allman
        {
141
                ep_app_error("Cannot parse source name %s: %s", gclxname,
142
                                ep_stat_tostr(estat, ebuf, sizeof ebuf));
143
                exit(EX_NOINPUT);
144
        }
145
146
        estat = gdp_gcl_open(gcliname, GDP_MODE_RO, NULL, &gcl);
147
        if (!EP_STAT_ISOK(estat))
148
        {
149
                ep_app_error("Cannot find source log %s: %s", gclxname,
150
                                ep_stat_tostr(estat, ebuf, sizeof ebuf));
151
                exit(EX_NOINPUT);
152
        }
153
154
        // get the metadata from the source log
155
        estat = gdp_gcl_getmetadata(gcl, &gmd);
156
        if (!EP_STAT_ISOK(estat))
157
        {
158
                ep_app_error("Cannot fetch metadata for log %s: %s", gclxname,
159
                                ep_stat_tostr(estat, ebuf, sizeof ebuf));
160
                exit(EX_NOINPUT);
161
        }
162
163
        // we no longer need the source log
164
        gdp_gcl_close(gcl);
165
166
        for (; argc-- > 0; ++argv)
167
        {
168
                gdp_name_t logdiname;
169
                estat = gdp_parse_name(*argv, logdiname);
170 22f2276a Eric Allman
                if (EP_STAT_ISFAIL(estat))
171 e41ced34 Eric Allman
                {
172
                        ep_app_error("Cannot parse log name %s: %s", *argv++,
173
                                        ep_stat_tostr(estat, ebuf, sizeof ebuf));
174
                        continue;
175
                }
176
177
                // do the actual create
178
                estat = gdp_gcl_create(gcliname, logdiname, gmd, &gcl);
179
                if (!EP_STAT_ISOK(estat))
180
                {
181
                        ep_app_error("Cannot create clone on %s: %s", *argv++,
182
                                        ep_stat_tostr(estat, ebuf, sizeof ebuf));
183
                        continue;
184
                }
185
186
                // we can now close the new log as well
187
                gdp_gcl_close(gcl);
188
        }
189
190
        // free metadata, if set
191
        if (gmd != NULL)
192 eae1d3ec Eric Allman
                gdp_gob_md_free(gmd);
193 e41ced34 Eric Allman
194
fail0:
195
        // OK status can have values; hide that from the user
196
        int xstat = 0;
197
        if (EP_STAT_ISOK(estat))
198
                estat = EP_STAT_OK;
199
        else
200
                xstat = EX_CANTCREAT;
201
        if (!quiet)
202 9829d4ae Eric Allman
                ep_app_message(estat, exiting with status");
203 e41ced34 Eric Allman
        exit(xstat);
204
}