[examples] added autoconf stubs for smpf example i.e. new option to configure added, because this example require readline library;
This commit is contained in:
parent
bcda9e1810
commit
5448493764
24
configure.ac
24
configure.ac
@ -16,6 +16,7 @@ dnl *****************
|
|||||||
dnl ***** options *****
|
dnl ***** options *****
|
||||||
dnl *****************
|
dnl *****************
|
||||||
|
|
||||||
|
dnl Build basic examples option
|
||||||
AC_ARG_ENABLE([build_examples],
|
AC_ARG_ENABLE([build_examples],
|
||||||
AS_HELP_STRING([--enable-build-examples], [Enable examples build]))
|
AS_HELP_STRING([--enable-build-examples], [Enable examples build]))
|
||||||
|
|
||||||
@ -25,6 +26,19 @@ AS_IF([test "x$enable_build_examples" = "xyes"], [
|
|||||||
|
|
||||||
AM_CONDITIONAL(BUILD_EXAMPLES, test "x$enable_build_examples" = "xyes")
|
AM_CONDITIONAL(BUILD_EXAMPLES, test "x$enable_build_examples" = "xyes")
|
||||||
|
|
||||||
|
dnl Build smpf example daemon and client option
|
||||||
|
AC_ARG_ENABLE([build_smpf_example],
|
||||||
|
AS_HELP_STRING([--enable-build-smpf-example], [Enable to build smpf advanced example, requires readline]))
|
||||||
|
|
||||||
|
AS_IF([test "x$enable_build_smpf_example" = "xyes"], [
|
||||||
|
AC_DEFINE([BUILD_SMPF_EXAMPLE], 1, [build of smpf example enabled])
|
||||||
|
])
|
||||||
|
|
||||||
|
AM_CONDITIONAL(BUILD_SMPF_EXAMPLE, test "x$enable_build_smpf_example" = "xyes")
|
||||||
|
|
||||||
|
|
||||||
|
dnl checking fpr dependencies
|
||||||
|
|
||||||
PKG_CHECK_MODULES(OPENSSL, [openssl])
|
PKG_CHECK_MODULES(OPENSSL, [openssl])
|
||||||
|
|
||||||
PKG_CHECK_MODULES(LIBTDATA, [libtdata >= 0.2.2])
|
PKG_CHECK_MODULES(LIBTDATA, [libtdata >= 0.2.2])
|
||||||
@ -40,6 +54,16 @@ case $host_os in
|
|||||||
LINUX=no;;
|
LINUX=no;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
|
case $enable_build_smpf_example in
|
||||||
|
yes)
|
||||||
|
sic_save_LIBS=$LIBS
|
||||||
|
AC_CHECK_LIB(readline, readline)
|
||||||
|
if test x"${ac_cv_lib_readline_readline}" = xno; then
|
||||||
|
AC_MSG_ERROR(libreadline not found)
|
||||||
|
fi
|
||||||
|
LIBS=$sic_save_LIBS
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
AM_CONDITIONAL(COND_WIN32, test "x$WIN32" = "xyes")
|
AM_CONDITIONAL(COND_WIN32, test "x$WIN32" = "xyes")
|
||||||
|
|
||||||
|
2
examples/.gitignore
vendored
2
examples/.gitignore
vendored
@ -2,3 +2,5 @@ filelistc
|
|||||||
filelistd
|
filelistd
|
||||||
streamfld
|
streamfld
|
||||||
streamflc
|
streamflc
|
||||||
|
smpfd
|
||||||
|
smpfc
|
||||||
|
@ -13,7 +13,13 @@ AM_CFLAGS = -Wall -g
|
|||||||
# where to find libsxmp
|
# where to find libsxmp
|
||||||
libsxmp = ../lib/.libs/libsxmp.la
|
libsxmp = ../lib/.libs/libsxmp.la
|
||||||
|
|
||||||
bin_PROGRAMS = filelistd filelistc streamfld streamflc
|
if BUILD_SMPF_EXAMPLE
|
||||||
|
smpf_programs = smpfd
|
||||||
|
else
|
||||||
|
smpf_programs =
|
||||||
|
endif
|
||||||
|
|
||||||
|
bin_PROGRAMS = filelistd filelistc streamfld streamflc $(smpf_programs)
|
||||||
|
|
||||||
filelistd_SOURCES = helpers.c filelistd.c
|
filelistd_SOURCES = helpers.c filelistd.c
|
||||||
filelistd_LDADD = $(LIBTDATA_LIBS) $(LIBSEXPR_LIBS) $(OPENSSL_LIBS) \
|
filelistd_LDADD = $(LIBTDATA_LIBS) $(LIBSEXPR_LIBS) $(OPENSSL_LIBS) \
|
||||||
@ -30,3 +36,7 @@ streamfld_LDADD = $(LIBTDATA_LIBS) $(LIBSEXPR_LIBS) $(OPENSSL_LIBS) \
|
|||||||
streamflc_SOURCES = streamflc.c
|
streamflc_SOURCES = streamflc.c
|
||||||
streamflc_LDADD = $(LIBTDATA_LIBS) $(LIBSEXPR_LIBS) $(OPENSSL_LIBS) \
|
streamflc_LDADD = $(LIBTDATA_LIBS) $(LIBSEXPR_LIBS) $(OPENSSL_LIBS) \
|
||||||
$(LIBUUID_LIBS) $(libsxmp) -lpthread
|
$(LIBUUID_LIBS) $(libsxmp) -lpthread
|
||||||
|
|
||||||
|
smpfd_SOURCES = helpers.c smpfd.c
|
||||||
|
smpfd_LDADD = $(LIBTDATA_LIBS) $(LIBSEXPR_LIBS) $(OPENSSL_LIBS) \
|
||||||
|
$(LIBUUID_LIBS) $(libsxmp) -lpthread
|
||||||
|
303
examples/smpfd.c
Normal file
303
examples/smpfd.c
Normal file
@ -0,0 +1,303 @@
|
|||||||
|
/*
|
||||||
|
* Secure X Message Passing Library v2 examples.
|
||||||
|
*
|
||||||
|
* (c) Alexander Vdolainen 2013-2015 <avdolainen@gmail.com>
|
||||||
|
* (c) Alexander Vdolainen 2016 <avdolainen@zoho.com>
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.";
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is an example of sxmp usage.
|
||||||
|
* NOTE: It was developed quite fast within one day,
|
||||||
|
* btw - this the reason of some ugly code here.
|
||||||
|
*
|
||||||
|
* This implements a simple client-server topology, to see
|
||||||
|
* more advanced technics check out other examples.
|
||||||
|
*
|
||||||
|
* NOTE(win32): don't have a time to test it or fix it to
|
||||||
|
* make it works on windows, if you can - u're welcome.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#define __USE_GNU
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <uuid/uuid.h>
|
||||||
|
#include <execinfo.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
|
||||||
|
#include <tdata/usrtc.h>
|
||||||
|
#include <tdata/list.h>
|
||||||
|
#include <sexpr/sexp.h>
|
||||||
|
#include <sxmp/limits.h>
|
||||||
|
#include <sxmp/sxmp.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "helpers.h"
|
||||||
|
#include "smpf.h"
|
||||||
|
#include "smpfd_defs.h"
|
||||||
|
#include "../config.h"
|
||||||
|
|
||||||
|
#define FULL_PROGRAM_NAME "SMPF (secure message passing file) daemon"
|
||||||
|
|
||||||
|
static struct smpfd_ctx daemon_ctx;
|
||||||
|
|
||||||
|
/* firstly we need to take an rpc calls data,
|
||||||
|
* sxmp uses usrtc from libtdata to store it
|
||||||
|
*/
|
||||||
|
static usrtc_t *fulist;
|
||||||
|
|
||||||
|
/* ok, here we will define out sxmp specific functions */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RPC list contain groups of RPC calls called channel types
|
||||||
|
* for each sxmp link depends on access rules you can change
|
||||||
|
* available channel types.
|
||||||
|
* To do so you must provide a special callback returning this list.
|
||||||
|
* Since we haven't any access restrictions in our example, just
|
||||||
|
* create a fake.
|
||||||
|
*/
|
||||||
|
static usrtc_t *__rettlist(sxlink_t *l)
|
||||||
|
{
|
||||||
|
return fulist;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Each sxmp link validated by certificate ID,
|
||||||
|
* i.e. when basic checking is done, you can also
|
||||||
|
* review the certificate ID, for example you need
|
||||||
|
* to disable certificate for a time being.
|
||||||
|
*
|
||||||
|
* Here we don't have those checks, just always accept
|
||||||
|
*/
|
||||||
|
static int __validate_sslpem(sxlink_t *l)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* To be more paranoic, sxmp also allow to
|
||||||
|
* check up username and password.
|
||||||
|
* We don't overview this tuff here, just
|
||||||
|
* always allow.
|
||||||
|
*/
|
||||||
|
static int __secure_check(sxlink_t *l)
|
||||||
|
{
|
||||||
|
return SXE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* remote functions implementation */
|
||||||
|
/* misc functions */
|
||||||
|
static int __ping(void *m, sexp_t *sx)
|
||||||
|
{
|
||||||
|
return sxmsg_return((sxmsg_t*)m, SXE_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* command line options 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 <path> -u | --master-x509 <path> "
|
||||||
|
" [-p | --listen-port <port>] [-R | --root-dir <directory>]\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 <path>");
|
||||||
|
fprintf(fso, "\t%-33s Set pathname of the host X.509 public and private certificate.\n",
|
||||||
|
"-m | --master-x509 <path>");
|
||||||
|
fprintf(fso, "\t%-33s Remote host listening port number [default: %d].\n",
|
||||||
|
"-p | --listen-port <port>", DEFAULT_PORT);
|
||||||
|
fprintf(fso, "\t%-33s Remote directory becoming root for user [default: %s].\n",
|
||||||
|
"-R | --root-dir <directory>", DEFAULT_ROOT_DIR);
|
||||||
|
fprintf(fso, "\t%-33s Show help screen.\n", "-h | --help");
|
||||||
|
fprintf(fso, "\t%-33s Print version information.\n", "-v | --version");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __version_print(FILE *fso)
|
||||||
|
{
|
||||||
|
fprintf(fso, "\n%s.\n", FULL_PROGRAM_NAME);
|
||||||
|
fprintf(fso, "Examples bundle for %s %s.\n", PACKAGE_NAME, PACKAGE_VERSION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
char *rootca = NULL, *cert = NULL;
|
||||||
|
char *root_dir = NULL;
|
||||||
|
sxhub_t *sxmphub = sxhub_create();
|
||||||
|
int port = DEFAULT_PORT;
|
||||||
|
int opt;
|
||||||
|
|
||||||
|
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'},
|
||||||
|
{"master-x509", required_argument, NULL, 'm'},
|
||||||
|
{"root-dir", required_argument, NULL, 'R'},
|
||||||
|
{"listen-port", required_argument, NULL, 'p'},
|
||||||
|
{ NULL, 0, NULL, 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
if((opt = getopt_long(argc, argv, "hvr:m:R:p:", 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 'm':
|
||||||
|
if(!(cert = strdup(optarg))) return ENOMEM;
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
port = atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 'R':
|
||||||
|
root_dir = strdup(optarg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!rootca) {
|
||||||
|
fprintf(stderr, "Root CA not pointed.\n Failure.\n");
|
||||||
|
__help_print(stderr, argv[0]);
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!cert) {
|
||||||
|
fprintf(stderr, "User certificate not pointed.\n Failure.\n");
|
||||||
|
__help_print(stderr, argv[0]);
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
sxmp_init();
|
||||||
|
|
||||||
|
/* all is fine let's init connection subsystem */
|
||||||
|
if(!sxmphub) {
|
||||||
|
fprintf(stderr, "Subsystem init failed: %d\n", opt);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
/* root directory */
|
||||||
|
if(!root_dir) {
|
||||||
|
root_dir = strdup(DEFAULT_ROOT_DIR);
|
||||||
|
if(!root_dir) {
|
||||||
|
fprintf(stderr, "Not enough memory.\n");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* set working certificates */
|
||||||
|
opt = sxhub_setsslserts(sxmphub, rootca, cert, cert);
|
||||||
|
if(opt) {
|
||||||
|
fprintf(stderr, "Subsystem init failed (set SSL x.509 pems): %d\n", opt);
|
||||||
|
return opt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clean up */
|
||||||
|
free(rootca);
|
||||||
|
free(cert);
|
||||||
|
free(root_dir);
|
||||||
|
|
||||||
|
/* set important callbacks to do the security checking */
|
||||||
|
sxhub_set_authcheck(sxmphub, __secure_check);
|
||||||
|
sxhub_set_sslvalidate(sxmphub, __validate_sslpem);
|
||||||
|
|
||||||
|
/* ok, now we need to construct RPC lists (channels) */
|
||||||
|
if(!(fulist = malloc(sizeof(usrtc_t)))) {
|
||||||
|
fprintf(stderr, "Cannot allocate memory for RPC lists\n Failure.\n");
|
||||||
|
return ENOMEM;
|
||||||
|
}
|
||||||
|
opt = sxmp_rpclist_init(fulist);
|
||||||
|
if(opt) {
|
||||||
|
fprintf(stderr, "Failed to init rpc list\n Failure.\n");
|
||||||
|
return opt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* we will add one channel with type id READONLY_CHANNEL for read only operations */
|
||||||
|
opt = sxmp_rpclist_add(fulist, READONLY_CHANNEL, "Read only operations", NULL);
|
||||||
|
if(opt) {
|
||||||
|
fprintf(stderr, "Failed to add typed RPC channel\n Failure.\n");
|
||||||
|
return opt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ok, let's add stream functions */
|
||||||
|
opt = sxmp_rpclist_add_function(fulist, READONLY_CHANNEL, "ping", __ping);
|
||||||
|
if(opt) {
|
||||||
|
fprintf(stderr, "Failed to add functions to typed RPC channel\n Failure.\n");
|
||||||
|
return opt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ok, setup it */
|
||||||
|
sxhub_set_rpcvalidator(sxmphub, __rettlist);
|
||||||
|
|
||||||
|
/* setup our stream */
|
||||||
|
// sxhub_stream_register(sxmphub, &dirlist_stream);
|
||||||
|
|
||||||
|
signal(SIGPIPE, SIG_IGN);
|
||||||
|
|
||||||
|
/* now we're ready to run the listen process */
|
||||||
|
int srv = openlistener_socket(port);
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
struct sockaddr_in addr;
|
||||||
|
socklen_t len = sizeof(addr);
|
||||||
|
sxlink_t *link;
|
||||||
|
|
||||||
|
int client = accept(srv, (struct sockaddr*)&addr, &len); /* accept connection as usual */
|
||||||
|
|
||||||
|
link = sxlink_master_accept(sxmphub, client, NULL);
|
||||||
|
|
||||||
|
if(!link) fprintf(stderr, "Cannot create sxmp link (%d)\n", errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
sxhub_destroy(sxmphub);
|
||||||
|
|
||||||
|
sxmp_finalize();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -21,9 +21,12 @@
|
|||||||
#ifndef __SXMP_EXAMPLES_SMPFD_DEFS_H__
|
#ifndef __SXMP_EXAMPLES_SMPFD_DEFS_H__
|
||||||
#define __SXMP_EXAMPLES_SMPFD_DEFS_H__
|
#define __SXMP_EXAMPLES_SMPFD_DEFS_H__
|
||||||
|
|
||||||
|
struct mp_fnode;
|
||||||
|
|
||||||
struct smpfd_ctx {
|
struct smpfd_ctx {
|
||||||
char *hostname;
|
char *hostname;
|
||||||
char *root_dir;
|
char *root_dir;
|
||||||
|
struct mp_fnode *root;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mp_session {
|
struct mp_session {
|
||||||
@ -36,6 +39,11 @@ typedef enum {
|
|||||||
DIRECTORY,
|
DIRECTORY,
|
||||||
} fnode_type_t;
|
} fnode_type_t;
|
||||||
|
|
||||||
|
struct mp_pcache_t {
|
||||||
|
list_head_t *pg;
|
||||||
|
size_t size;
|
||||||
|
};
|
||||||
|
|
||||||
struct mp_fnode {
|
struct mp_fnode {
|
||||||
int fd;
|
int fd;
|
||||||
uid_t uid;
|
uid_t uid;
|
||||||
@ -47,9 +55,10 @@ struct mp_fnode {
|
|||||||
fnode_type_t type;
|
fnode_type_t type;
|
||||||
struct mp_fnode *parent;
|
struct mp_fnode *parent;
|
||||||
union {
|
union {
|
||||||
mp_pcache_t *bcache;
|
struct mp_pcache_t *bcache;
|
||||||
list_head_t *dcache;
|
list_head_t *dcache;
|
||||||
};
|
};
|
||||||
|
pthread_mutex_t lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user