diff --git a/examples/Makefile.am b/examples/Makefile.am index 196a71f..7a20aa9 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -14,7 +14,7 @@ AM_CFLAGS = -Wall -g libsxmp = ../lib/.libs/libsxmp.la if BUILD_SMPF_EXAMPLE -smpf_programs = smpfd +smpf_programs = smpfd smpfc else smpf_programs = endif @@ -40,3 +40,8 @@ streamflc_LDADD = $(LIBTDATA_LIBS) $(LIBSEXPR_LIBS) $(OPENSSL_LIBS) \ smpfd_SOURCES = helpers.c smpfd.c smpfd_LDADD = $(LIBTDATA_LIBS) $(LIBSEXPR_LIBS) $(OPENSSL_LIBS) \ $(LIBUUID_LIBS) $(libsxmp) -lpthread + +smpfc_SOURCES = smpfc.c +smpfc_LDADD = $(LIBTDATA_LIBS) $(LIBSEXPR_LIBS) $(OPENSSL_LIBS) \ + $(LIBUUID_LIBS) $(libsxmp) -lpthread -lreadline + diff --git a/examples/smpfc.c b/examples/smpfc.c new file mode 100644 index 0000000..87feeb0 --- /dev/null +++ b/examples/smpfc.c @@ -0,0 +1,238 @@ +/* + * Secure X Message Passing Library v2 examples. + * + * (c) Alexander Vdolainen 2016 + * + * libsxmp is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * libsxmp is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see ."; + * + */ + +#include +#include +#define __USE_GNU +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "smpf.h" +#include "../config.h" + +#define FULL_PROGRAM_NAME "SMPF (secure message passing file) client" +#include "helpers.h" + +struct _session { + list_head_t channels; + char cwd[MAX_CWDLEN]; +}; + +struct _remote_host { + char *root_x509; + char *user_x509; + char *hostname; + char *login; + char *password; + int port; + sxhub_t *hub; + sxlink_t *link; + struct _session *session; +}; + +/* sxmp stuff below */ +static void __session_free(sxlink_t *l) +{ + struct _session *s = (struct _session *)sxlink_getpriv(l); + + /* TODO: free all list entries if exists */ + free(s); + return; +} + +static int __rpcscheck_onclient(sxlink_t *l, int ch_tid, char *description) +{ + struct _session *s = (struct _session *)sxlink_getpriv(l); + + /* TODO: add all stuff to the list */ + + return SXE_SUCCESS; +} + +static int __remote_host_connect(struct _remote_host *rh) +{ + int r = 0; + struct _session *s = malloc(sizeof(struct _session)); + + sxhub_set_channelcall(rh->hub, __rpcscheck_onclient); + sxhub_set_ondestroy(rh->hub, __session_free); + if(!s) return SXE_ENOMEM; + + /* here we go, connect to the hist i.e. create a link to it */ + rh->link = sxlink_connect_at(rh->hub, rh->hostname, rh->port, rh->user_x509, + rh->login, rh->password, s); + if(!rh->link) r = errno; + + return r; +} + +/* standard output helpers */ +static void __help_print(FILE *fso, const char *fmtname) +{ + fprintf(fso, "\n%s\n\n", FULL_PROGRAM_NAME); + + /* usage options */ + fprintf(fso, "Usage:\n"); + fprintf(fso, "\t%s -r | --root-x509 -u | --user-x509 @[:port]\n", fmtname); + + /* defaults */ + fprintf(fso, "\t%s -h | --help\n", fmtname); + fprintf(fso, "\t%s -v | --version\n", fmtname); + + /* options description */ + fprintf(fso, "\nOptions:\n"); + fprintf(fso, "\t%-33s Set pathname of the remote root X.509 public certificate.\n", "-r | --root-x509 "); + fprintf(fso, "\t%-33s Set pathname of the user X.509 public and private certificate.\n", + "-u | --user-x509 "); + fprintf(fso, "\t%-33s Show help screen.\n", "-h | --help"); + fprintf(fso, "\t%-33s Print version information.\n", "-v | --version"); + return; +} + +int main(int argc, char **argv) +{ + char *rootca, *cert, *host, *cline; + char *login, *password; + int port = DEFAULT_PORT, opt, i = 0; + struct _remote_host *rh = malloc(sizeof(struct _remote_host)); + sxhub_t *lhub; + + if(!rh) return ENOMEM; + else memset(rh, 0, sizeof(struct _remote_host)); + + rootca = cert = host = login = password = NULL; + + while(1) { + int option_index = 0; + static struct option long_options[] = { + /* These options a generic ones. */ + {"help", no_argument, NULL, 'h'}, /* print out help and version info */ + {"version", no_argument, NULL, 'v'}, /* just out a version info */ + /* The following options about settings . */ + {"root-x509", required_argument, NULL, 'r'}, + {"user-x509", required_argument, NULL, 'u'}, + { NULL, 0, NULL, 0 }, + }; + + if((opt = getopt_long(argc, argv, "hvr:u:", long_options, + &option_index)) == -1) break; + + switch(opt) { + case 'h': + __help_print(stdout, argv[0]); + return 0; + break; + case 'v': + version_print(stdout); + return 0; + break; + case 'r': + if(!(rootca = strdup(optarg))) return ENOMEM; + break; + case 'u': + if(!(cert = strdup(optarg))) return ENOMEM; + break; + } + } + + if(optind < argc) cline = argv[optind]; + else { + fprintf(stderr, "No remote address given connect to.\n\n"); + __help_print(stderr, argv[0]); + return EINVAL; + } + + /* ok validate all before doing any stuff */ + if(!rootca || !cert) { + fprintf(stderr, "One or more x.509 certificates files not pointed.\n"); + __help_print(stderr, argv[0]); + return EINVAL; + } + if(!login || !password) { + fprintf(stderr, "Login or password not pointed.\n"); + __help_print(stderr, argv[0]); + return EINVAL; + } + if(port <= 0) { + fprintf(stderr, "Port number has invalid value.\n"); + __help_print(stderr, argv[0]); + return EINVAL; + } + + /* initialize sxmp first */ + sxmp_init(); /* init library */ + lhub = sxhub_create(); /* create sxhub for link creation */ + if(!lhub) return ENOMEM; + + i = sxhub_setsslserts(lhub, rootca, cert, cert); + if(i) return i; + + /* ok setup our structure */ + rh->port = port; + rh->root_x509 = rootca; + rh->user_x509 = cert; + rh->hostname = host; + rh->login = login; + rh->password = password; + rh->hub = lhub; + + i = __remote_host_connect(rh); + if(i) { + fprintf(stderr, "Failed to create link to %s@%s:%d with %d.\n", rh->login, rh->hostname, + rh->port, i); + } else { + + sxlink_close(rh->link); /* don't forget to do this */ + } + + /* free all stuff */ + if(rh->root_x509) free(rh->root_x509); + if(rh->user_x509) free(rh->user_x509); + if(rh->hostname) free(rh->hostname); + if(rh->password) free(rh->password); + if(rh->login) free(rh->login); + free(rh); + + if(lhub) sxhub_destroy(lhub); + + return 0; +}