/* * 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 #include #include "smpf.h" #include "misc.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; }; /* session processing itself */ static void __shell(sxlink_t *link) { struct _session *s = (struct _session *)sxlink_getpriv(link); char *line; for(;;) { line = readline("$>"); if(line && *line) add_history(line); else break; if(!strcmp(line, "exit")) break; } return; } /* 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; } /* TODO: better check */ exmps_getaddrs(cline, &login, &host, &port); if(!host) { fprintf(stderr, "Host not pointed.\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) { fprintf(stderr, "Login 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; } /* read the password */ password = exmps_getpass("Password: "); fprintf(stdout, "\n"); /* 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 { /* hooray now we ready to do something */ __shell(rh->link); 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; }