Read This! |
Picolisp |
Picolisp Machine |
Pil Sources |
Pil Tutorials |
Linux |
BASH |
C-Programmming |
Javascipt |
Python |
Scheme |
Operating Systems |
AssemblyLanguage |
Computer Security |
Firewalls |
Exploitation |
Social Engineering |
Metasploit |
Emacs |
vim |
Pharo Smalltalk |
Databases |
Networking |
Machine Learning |
Git |
Machine Learning |
Algorithms |
Open Data Science
/* 28mar17abu
* (c) Software Lab. Alexander Burger
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <sys/stat.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
typedef enum {NO,YES} bool;
static char *File, *Dir, *Data;
static off_t Size;
static bool Safe, Hot;
static char Ciphers[] = "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:DES-CBC3-SHA";
static char Get[] =
"GET /%s HTTP/1.0rn"
"User-Agent: PicoLisprn"
"Host: %s:%srn"
"Accept-Charset: utf-8rnrn";
static void giveup(char *msg) {
fprintf(stderr, "ssl: %sn", msg);
exit(1);
}
static int sslConnect(SSL *ssl, char *node, char *service) {
struct addrinfo hints, *lst, *p;
int sd;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
if (getaddrinfo(node, service, &hints, &lst) == 0) {
for (p = lst; p; p = p->ai_next) {
if ((sd = socket(p->ai_family, p->ai_socktype, 0)) >= 0) {
if (connect(sd, p->ai_addr, p->ai_addrlen) == 0) {
SSL_set_fd(ssl, sd);
if (SSL_connect(ssl) == 1) {
X509 *cert;
freeaddrinfo(lst);
if (Safe)
return sd;
if (cert = SSL_get_peer_certificate(ssl)) {
X509_free(cert);
if (SSL_get_verify_result(ssl) == X509_V_OK)
return sd;
}
return -1;
}
}
close(sd);
}
}
freeaddrinfo(lst);
}
return -1;
}
static void sslClose(SSL *ssl, int sd) {
SSL_shutdown(ssl);
SSL_clear(ssl);
close(sd);
}
static bool sslFile(SSL *ssl, char *file) {
int fd, n;
char buf[BUFSIZ];
if (file[0] == '-') {
if (file[1] != '0')
return SSL_write(ssl, file+1, strlen(file)-1) >= 0;
fd = STDIN_FILENO;
}
else if ((fd = open(file, O_RDONLY)) < 0)
return NO;
while ((n = read(fd, buf, sizeof(buf))) > 0)
if (SSL_write(ssl, buf, n) < 0) {
close(fd);
return NO;
}
close(fd);
return n == 0;
}
static void lockFile(int fd) {
struct flock fl;
fl.l_type = F_WRLCK;
fl.l_whence = SEEK_SET;
fl.l_start = 0;
fl.l_len = 0;
if (fcntl(fd, F_SETLKW, &fl) < 0)
giveup("Can't lock");
}
static void doSigTerm(int n __attribute__((unused))) {
int fd;
struct stat st;
char *data;
if (Hot) {
if ((fd = open(File, O_RDWR)) < 0)
giveup("Can't final open");
lockFile(fd);
if (fstat(fd,&st) < 0)
giveup("Can't final access");
if (st.st_size != 0) {
if ((data = malloc(st.st_size)) == NULL)
giveup("Can't final alloc");
if (read(fd, data, st.st_size) != st.st_size)
giveup("Can't final read");
if (ftruncate(fd,0) < 0)
giveup("Can't final truncate");
}
if (write(fd, Data, Size) != Size)
giveup("Can't final write (1)");
if (st.st_size != 0 && write(fd, data, st.st_size) != st.st_size)
giveup("Can't final write (2)");
}
exit(0);
}
static void iSignal(int n, void (*foo)(int)) {
struct sigaction act;
act.sa_handler = foo;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(n, &act, NULL);
}
// ssl host port url
// ssl host port url [key [file]]
// ssl host port url key file dir sec [min]
int main(int ac, char *av[]) {
bool dbg;
SSL_CTX *ctx;
SSL *ssl;
int n, sec, lim, getLen, lenLen, fd, sd;
DIR *dp;
struct dirent *p;
struct stat st;
char get[1024], buf[4096], nm[4096], len[64];
if (dbg = strcmp(av[ac-1], "+") == 0)
--ac;
if (!(ac >= 4 && ac <= 6 || ac >= 8 && ac <= 9))
giveup("host port url [[key] file] | host port url key file dir sec [min]");
if (*av[2] == '-')
++av[2], Safe = YES;
if (strlen(Get)+strlen(av[1])+strlen(av[2])+strlen(av[3]) >= sizeof(get))
giveup("Names too long");
getLen = sprintf(get, Get, av[3], av[1], av[2]);
SSL_library_init();
SSL_load_error_strings();
if (!(ctx = SSL_CTX_new(SSLv23_client_method())) || !SSL_CTX_set_default_verify_paths(ctx)) {
ERR_print_errors_fp(stderr);
giveup("SSL init");
}
SSL_CTX_set_options(ctx,
SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_ALL | SSL_OP_NO_COMPRESSION );
SSL_CTX_set_cipher_list(ctx, Ciphers);
ssl = SSL_new(ctx);
if (ac <= 6) {
if (sslConnect(ssl, av[1], av[2]) < 0) {
ERR_print_errors_fp(stderr);
giveup("Can't connect");
}
if (SSL_write(ssl, get, getLen) < 0) {
ERR_print_errors_fp(stderr);
giveup("SSL GET");
}
if (ac > 4) {
if (*av[4] && !sslFile(ssl,av[4]))
giveup(av[4]);
if (ac > 5 && *av[5] && !sslFile(ssl,av[5]))
giveup(av[5]);
}
while ((n = SSL_read(ssl, buf, sizeof(buf))) > 0)
write(STDOUT_FILENO, buf, n);
if (dbg)
ERR_print_errors_fp(stderr);
return 0;
}
if (!dbg) {
signal(SIGCHLD,SIG_IGN); /* Prevent zombies */
if ((n = fork()) < 0)
giveup("detach");
if (n)
return 0;
setsid();
}
File = av[5];
Dir = av[6];
sec = atoi(av[7]);
iSignal(SIGINT, doSigTerm);
iSignal(SIGTERM, doSigTerm);
signal(SIGPIPE, SIG_IGN);
lim = 0;
if (ac > 8) {
iSignal(SIGALRM, doSigTerm);
alarm(lim = 60 * atoi(av[8]));
}
for (;;) {
if (*File && (fd = open(File, O_RDWR)) >= 0) {
if (fstat(fd,&st) < 0 || st.st_size == 0)
close(fd);
else {
alarm(lim);
lockFile(fd);
if (fstat(fd,&st) < 0 || (Size = st.st_size) == 0)
giveup("Can't access");
lenLen = sprintf(len, "%ldn", Size);
if ((Data = malloc(Size)) == NULL)
giveup("Can't alloc");
if (read(fd, Data, Size) != Size)
giveup("Can't read");
Hot = YES;
if (ftruncate(fd,0) < 0)
giveup("Can't truncate");
close(fd);
for (;;) {
if ((sd = sslConnect(ssl, av[1], av[2])) >= 0) {
if (SSL_write(ssl, get, getLen) == getLen &&
(!*av[4] || sslFile(ssl,av[4])) && // key
SSL_write(ssl, len, lenLen) == lenLen && // length
SSL_write(ssl, Data, Size) == Size && // data
SSL_write(ssl, "T", 1) == 1 && // ack
SSL_read(ssl, buf, 1) == 1 && buf[0] == 'T' ) {
Hot = NO;
sslClose(ssl,sd);
break;
}
sslClose(ssl,sd);
}
if (dbg)
ERR_print_errors_fp(stderr);
sleep(sec);
}
free(Data);
}
}
if (*Dir && (dp = opendir(Dir))) {
while (p = readdir(dp)) {
if (p->d_name[0] == '=') {
snprintf(nm, sizeof(nm), "%s%s", Dir, p->d_name);
if ((n = readlink(nm, buf, sizeof(buf))) > 0 && stat(nm, &st) >= 0) {
lenLen = sprintf(len, "%ldn", st.st_size);
buf[n++] = 'n';
alarm(lim);
if ((sd = sslConnect(ssl, av[1], av[2])) >= 0) {
if (SSL_write(ssl, get, getLen) == getLen &&
(!*av[4] || sslFile(ssl,av[4])) && // key
SSL_write(ssl, buf, n) == n && // path
SSL_write(ssl, len, lenLen) == lenLen && // length
sslFile(ssl, nm) && // file
SSL_write(ssl, "T", 1) == 1 && // ack
SSL_read(ssl, buf, 1) == 1 && buf[0] == 'T' )
unlink(nm);
sslClose(ssl,sd);
}
if (dbg)
ERR_print_errors_fp(stderr);
}
}
}
closedir(dp);
}
sleep(sec);
}
}
http:///wiki/?sslc