add fork of libsam3

add funtion to get i2p certificate crypto algo names
This commit is contained in:
sehraf 2020-10-26 21:45:03 +01:00
parent 130d846e47
commit 76f0678820
No known key found for this signature in database
GPG key ID: DF09F6EAE356B2C6
25 changed files with 5858 additions and 7 deletions

View file

@ -0,0 +1 @@
../src/libsam3

View file

@ -0,0 +1,26 @@
Examples
========
These examples show various ways of using libsam3 to enable i2p in your
application, and are also useful in other ways. If you implement an i2p
application library in another language, making variants basic tools wouldn't be
the worst way to make sure that it works.
building
--------
Once you have build the library in the root of this repository by running make
all, you can build all these examples at once by running
make
in this directory. I think it makes things easier to experiment with quickly.
namelookup
----------
Namelookup uses the SAM API to find the base64 destination of an readable "jump"
or base32 i2p address. You can use it like this:
./lookup i2p-projekt.i2p

View file

@ -0,0 +1,116 @@
/* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*
* I2P-Bote:
* 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV
* we are the Borg. */
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "../libsam3/libsam3.h"
// comment the following if you don't want to stress UDP with 'big' datagram
// seems that up to 32000 bytes can be used for localhost
// note that we need 516+6+? bytes for header; lets reserve 1024 bytes for it
#define BIG (32000 - 1024)
#define KEYFILE "dgrams.key"
int main(int argc, char *argv[]) {
Sam3Session ses;
char buf[1024];
char destkey[517] = {0}; // 516 chars + \0
int sz;
//
libsam3_debug = 1;
//
if (argc < 2) {
FILE *fl = fopen(KEYFILE, "rb");
//
if (fl != NULL) {
if (fread(destkey, 516, 1, fl) == 1) {
fclose(fl);
goto ok;
}
fclose(fl);
}
printf("usage: dgramc PUBKEY\n");
return 1;
} else {
if (strlen(argv[1]) != 516) {
fprintf(stderr, "FATAL: invalid key length!\n");
return 1;
}
strcpy(destkey, argv[1]);
}
//
ok:
printf("creating session...\n");
/* create TRANSIENT session with temporary disposible destination */
if (sam3CreateSession(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT,
SAM3_DESTINATION_TRANSIENT, SAM3_SESSION_DGRAM, 4,
NULL) < 0) {
fprintf(stderr, "FATAL: can't create session\n");
return 1;
}
/* send datagram */
printf("sending test datagram...\n");
if (sam3DatagramSend(&ses, destkey, "test", 4) < 0) {
fprintf(stderr, "ERROR: %s\n", ses.error);
goto error;
}
/** receive reply */
if ((sz = sam3DatagramReceive(&ses, buf, sizeof(buf) - 1)) < 0) {
fprintf(stderr, "ERROR: %s\n", ses.error);
goto error;
}
/** null terminated string */
buf[sz] = 0;
printf("received: [%s]\n", buf);
//
#ifdef BIG
{
char *big = calloc(BIG + 1024, sizeof(char));
/** generate random string */
sam3GenChannelName(big, BIG + 1023, BIG + 1023);
printf("sending BIG datagram...\n");
if (sam3DatagramSend(&ses, destkey, big, BIG) < 0) {
free(big);
fprintf(stderr, "ERROR: %s\n", ses.error);
goto error;
}
if ((sz = sam3DatagramReceive(&ses, big, BIG + 512)) < 0) {
free(big);
fprintf(stderr, "ERROR: %s\n", ses.error);
goto error;
}
big[sz] = 0;
printf("received (%d): [%s]\n", sz, big);
free(big);
}
#endif
//
printf("sending quit datagram...\n");
if (sam3DatagramSend(&ses, destkey, "quit", 4) < 0) {
fprintf(stderr, "ERROR: %s\n", ses.error);
goto error;
}
if ((sz = sam3DatagramReceive(&ses, buf, sizeof(buf) - 1)) < 0) {
fprintf(stderr, "ERROR: %s\n", ses.error);
goto error;
}
buf[sz] = 0;
printf("received: [%s]\n", buf);
//
sam3CloseSession(&ses);
return 0;
error:
sam3CloseSession(&ses);
return 1;
}

View file

@ -0,0 +1,113 @@
/* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*
* I2P-Bote:
* 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV
* we are the Borg. */
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "../libsam3/libsam3.h"
#define KEYFILE "dgrams.key"
int main(int argc, char *argv[]) {
Sam3Session ses;
char privkey[1024], pubkey[1024], buf[33 * 1024];
/** quit command */
const char *quitstr = "quit";
const size_t quitlen = strlen(quitstr);
/** reply response */
const char *replystr = "reply: ";
const size_t replylen = strlen(replystr);
FILE *fl;
//
libsam3_debug = 1;
//
/** generate new destination keypair */
printf("generating keys...\n");
if (sam3GenerateKeys(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, 4) < 0) {
fprintf(stderr, "FATAL: can't generate keys\n");
return 1;
}
/** copy keypair into local buffer */
strncpy(pubkey, ses.pubkey, sizeof(pubkey));
strncpy(privkey, ses.privkey, sizeof(privkey));
/** create sam session */
printf("creating session...\n");
if (sam3CreateSession(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, privkey,
SAM3_SESSION_DGRAM, 5, NULL) < 0) {
fprintf(stderr, "FATAL: can't create session\n");
return 1;
}
/** make sure we have the right destination */
// FIXME: probably not needed
if (strcmp(pubkey, ses.pubkey) != 0) {
fprintf(stderr, "FATAL: destination keys don't match\n");
sam3CloseSession(&ses);
return 1;
}
/** print destination to stdout */
printf("PUB KEY\n=======\n%s\n=======\n", ses.pubkey);
if ((fl = fopen(KEYFILE, "wb")) != NULL) {
/** write public key to keyfile */
fwrite(pubkey, strlen(pubkey), 1, fl);
fclose(fl);
}
/* now listen for UDP packets */
printf("starting main loop...\n");
for (;;) {
/** save replylen bytes for out reply at begining */
char *datagramBuf = buf + replylen;
const size_t datagramMaxLen = sizeof(buf) - replylen;
int sz, isquit;
printf("waiting for datagram...\n");
/** blocks until we get a UDP packet */
if ((sz = sam3DatagramReceive(&ses, datagramBuf, datagramMaxLen) < 0)) {
fprintf(stderr, "ERROR: %s\n", ses.error);
goto error;
}
/** ensure null terminated string */
datagramBuf[sz] = 0;
/** print out datagram payload to user */
printf("FROM\n====\n%s\n====\n", ses.destkey);
printf("SIZE=%d\n", sz);
printf("data: [%s]\n", datagramBuf);
/** check for "quit" */
isquit = (sz == quitlen && memcmp(datagramBuf, quitstr, quitlen) == 0);
/** echo datagram back to sender with "reply: " at the beginning */
memcpy(buf, replystr, replylen);
if (sam3DatagramSend(&ses, ses.destkey, buf, sz + replylen) < 0) {
fprintf(stderr, "ERROR: %s\n", ses.error);
goto error;
}
/** if we got a quit command wait for 10 seconds and break out of the
* mainloop */
if (isquit) {
printf("shutting down...\n");
sleep(10); /* let dgram reach it's destination */
break;
}
}
/** close session and delete keyfile */
sam3CloseSession(&ses);
unlink(KEYFILE);
return 0;
error:
/** error case, close session, delete keyfile and return exit code 1 */
sam3CloseSession(&ses);
unlink(KEYFILE);
return 1;
}

View file

@ -0,0 +1,43 @@
/* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*
* I2P-Bote:
* 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV
* we are the Borg. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "../libsam3/libsam3.h"
int main(int argc, char *argv[]) {
Sam3Session ses;
//
//
libsam3_debug = 1;
//
if (argc < 2) {
printf("usage: %s name [name...]\n", argv[0]);
return 1;
}
/** for each name in arguments ... */
for (int n = 1; n < argc; ++n) {
if (!getenv("I2P_LOOKUP_QUIET")) {
fprintf(stdout, "%s ... ", argv[n]);
fflush(stdout);
}
/** do oneshot name lookup */
if (sam3NameLookup(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT, argv[n]) >=
0) {
fprintf(stdout, "%s\n\n", ses.destkey);
} else {
fprintf(stdout, "FAILED [%s]\n", ses.error);
}
}
//
return 0;
}

View file

@ -0,0 +1,51 @@
/* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*
* I2P-Bote:
* 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV
* we are the Borg. */
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "../libsam3/libsam3.h"
int main(int argc, char *argv[]) {
int fd;
SAMFieldList *rep = NULL;
const char *v;
//
libsam3_debug = 1;
//
//
if ((fd = sam3Handshake(NULL, 0, NULL)) < 0)
return 1;
//
if (sam3tcpPrintf(fd, "DEST GENERATE\n") < 0)
goto error;
rep = sam3ReadReply(fd);
// sam3DumpFieldList(rep);
if (!sam3IsGoodReply(rep, "DEST", "REPLY", "PUB", NULL))
goto error;
if (!sam3IsGoodReply(rep, "DEST", "REPLY", "PRIV", NULL))
goto error;
v = sam3FindField(rep, "PUB");
printf("PUB KEY\n=======\n%s\n", v);
v = sam3FindField(rep, "PRIV");
printf("PRIV KEY\n========\n%s\n", v);
sam3FreeFieldList(rep);
rep = NULL;
//
sam3FreeFieldList(rep);
sam3tcpDisconnect(fd);
return 0;
error:
sam3FreeFieldList(rep);
sam3tcpDisconnect(fd);
return 1;
}

View file

@ -0,0 +1,87 @@
/* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*
* I2P-Bote:
* 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV
* we are the Borg. */
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "../libsam3/libsam3.h"
#define KEYFILE "streams.key"
int main(int argc, char *argv[]) {
Sam3Session ses;
Sam3Connection *conn;
char cmd[1024], destkey[617]; // 616 chars + \0
//
libsam3_debug = 1;
//
memset(destkey, 0, sizeof(destkey));
//
if (argc < 2) {
FILE *fl = fopen(KEYFILE, "rb");
//
if (fl != NULL) {
if (fread(destkey, 616, 1, fl) == 1) {
fclose(fl);
goto ok;
}
fclose(fl);
}
printf("usage: streamc PUBKEY\n");
return 1;
} else {
if (!sam3CheckValidKeyLength(argv[1])) {
fprintf(stderr, "FATAL: invalid key length! %s %lu\n", argv[1],
strlen(argv[1]));
return 1;
}
strcpy(destkey, argv[1]);
}
//
ok:
printf("creating session...\n");
// create TRANSIENT session
if (sam3CreateSession(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT,
SAM3_DESTINATION_TRANSIENT, SAM3_SESSION_STREAM, 4,
NULL) < 0) {
fprintf(stderr, "FATAL: can't create session\n");
return 1;
}
//
printf("connecting...\n");
if ((conn = sam3StreamConnect(&ses, destkey)) == NULL) {
fprintf(stderr, "FATAL: can't connect: %s\n", ses.error);
sam3CloseSession(&ses);
return 1;
}
//
// now waiting for incoming connection
printf("sending test command...\n");
if (sam3tcpPrintf(conn->fd, "test\n") < 0)
goto error;
if (sam3tcpReceiveStr(conn->fd, cmd, sizeof(cmd)) < 0)
goto error;
printf("echo: %s\n", cmd);
//
printf("sending quit command...\n");
if (sam3tcpPrintf(conn->fd, "quit\n") < 0)
goto error;
//
sam3CloseConnection(conn);
sam3CloseSession(&ses);
return 0;
error:
fprintf(stderr, "FATAL: some error occured!\n");
sam3CloseConnection(conn);
sam3CloseSession(&ses);
return 1;
}

View file

@ -0,0 +1,72 @@
/* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*
* I2P-Bote:
* 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV
* we are the Borg. */
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "../libsam3/libsam3.h"
#define KEYFILE "streams.key"
int main(int argc, char *argv[]) {
Sam3Session ses;
Sam3Connection *conn;
FILE *fl;
//
libsam3_debug = 1;
//
printf("creating session...\n");
// create TRANSIENT session
if (sam3CreateSession(&ses, SAM3_HOST_DEFAULT, SAM3_PORT_DEFAULT,
SAM3_DESTINATION_TRANSIENT, SAM3_SESSION_STREAM, 4,
NULL) < 0) {
fprintf(stderr, "FATAL: can't create session\n");
return 1;
}
//
printf("PUB KEY\n=======\n%s\n=======\n", ses.pubkey);
if ((fl = fopen(KEYFILE, "wb")) != NULL) {
fwrite(ses.pubkey, strlen(ses.pubkey), 1, fl);
fclose(fl);
}
//
printf("starting stream acceptor...\n");
if ((conn = sam3StreamAccept(&ses)) == NULL) {
fprintf(stderr, "FATAL: can't accept: %s\n", ses.error);
sam3CloseSession(&ses);
return 1;
}
printf("FROM\n====\n%s\n====\n", conn->destkey);
//
printf("starting main loop...\n");
for (;;) {
char cmd[256];
//
if (sam3tcpReceiveStr(conn->fd, cmd, sizeof(cmd)) < 0)
goto error;
printf("cmd: [%s]\n", cmd);
if (strcmp(cmd, "quit") == 0)
break;
// echo command
if (sam3tcpPrintf(conn->fd, "re: %s\n", cmd) < 0)
goto error;
}
//
sam3CloseSession(&ses);
unlink(KEYFILE);
return 0;
error:
fprintf(stderr, "FATAL: some error occured!\n");
sam3CloseSession(&ses);
unlink(KEYFILE);
return 1;
}

View file

@ -0,0 +1,178 @@
/* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*
* I2P-Bote:
* 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV
* we are the Borg. */
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include "../libsam3a/libsam3a.h"
////////////////////////////////////////////////////////////////////////////////
static void scbErrorClose(Sam3ASession *ses) {
fprintf(stderr,
"\n===============================\nSESION_ERROR: "
"[%s]\n===============================\n",
ses->error);
sam3aCloseSession(ses); // it's safe here
}
static void scbNRCreated(Sam3ASession *ses) {
fprintf(stderr, "\n===============================\nNAME RESOLVED: [%s]\n",
ses->params);
fprintf(stderr, "PUB: %s\n===============================\n", ses->destkey);
sam3aCloseSession(ses); // it's safe here
}
static const Sam3ASessionCallbacks scbNR = {
.cbError = scbErrorClose,
.cbCreated = scbNRCreated,
.cbDisconnected = NULL,
.cbDatagramRead = NULL,
.cbDestroy = NULL,
};
////////////////////////////////////////////////////////////////////////////////
static void scbKGCreated(Sam3ASession *ses) {
fprintf(stderr, "\n===============================\nKEYS GENERATED\n");
fprintf(stderr, "\rPRIV: %s\n", ses->privkey);
fprintf(stderr, "\nPUB: %s\n===============================\n", ses->pubkey);
sam3aCloseSession(ses); // it's safe here
}
static const Sam3ASessionCallbacks scbKG = {
.cbError = scbErrorClose,
.cbCreated = scbKGCreated,
.cbDisconnected = NULL,
.cbDatagramRead = NULL,
.cbDestroy = NULL,
};
////////////////////////////////////////////////////////////////////////////////
static void scbError(Sam3ASession *ses) {
fprintf(stderr,
"\n===============================\nSESION_ERROR: "
"[%s]\n===============================\n",
ses->error);
}
static void scbCreated(Sam3ASession *ses) {
fprintf(stderr, "\n===============================\nSESION_CREATED\n");
fprintf(stderr, "\rPRIV: %s\n", ses->privkey);
fprintf(stderr, "\nPUB: %s\n===============================\n", ses->pubkey);
sam3aCancelSession(ses); // it's safe here
}
static void scbDisconnected(Sam3ASession *ses) {
fprintf(stderr, "\n===============================\nSESION_DISCONNECTED\n===="
"===========================\n");
}
static void scbDGramRead(Sam3ASession *ses, const void *buf, int bufsize) {
fprintf(stderr, "\n===============================\nSESION_DATAGRAM_READ\n==="
"============================\n");
}
static void scbDestroy(Sam3ASession *ses) {
fprintf(stderr, "\n===============================\nSESION_DESTROYED\n======="
"========================\n");
}
/** callbacks for our SAM session */
static const Sam3ASessionCallbacks scb = {
.cbError = scbError,
.cbCreated = scbCreated,
.cbDisconnected = scbDisconnected,
.cbDatagramRead = scbDGramRead,
.cbDestroy = scbDestroy,
};
////////////////////////////////////////////////////////////////////////////////
#define HOST SAM3A_HOST_DEFAULT
//#define HOST "google.com"
int main(int argc, char *argv[]) {
Sam3ASession ses, snr, skg;
//
// libsam3a_debug = 1;
//
if (sam3aCreateSession(&ses, &scb, HOST, SAM3A_PORT_DEFAULT,
SAM3A_DESTINATION_TRANSIENT,
SAM3A_SESSION_STREAM) < 0) {
fprintf(stderr, "FATAL: can't create main session!\n");
return 1;
}
// generate keys
if (sam3aGenerateKeys(&skg, &scbKG, HOST, SAM3A_PORT_DEFAULT) < 0) {
sam3aCloseSession(&ses);
fprintf(stderr, "FATAL: can't create keygen session!\n");
return 1;
}
// do a name lookup for zzz.i2p
if (sam3aNameLookup(&snr, &scbNR, HOST, SAM3A_PORT_DEFAULT, "zzz.i2p") < 0) {
sam3aCloseSession(&skg);
sam3aCloseSession(&ses);
fprintf(stderr, "FATAL: can't create name resolving session!\n");
return 1;
}
// while we have sessions ...
while (sam3aIsActiveSession(&ses) || sam3aIsActiveSession(&snr) ||
sam3aIsActiveSession(&skg)) {
fd_set rds, wrs;
int res, maxfd = 0;
struct timeval to;
// set up file descriptors for select()
FD_ZERO(&rds);
FD_ZERO(&wrs);
// obtain the maximum fd for select()
if (sam3aIsActiveSession(&ses) &&
(maxfd = sam3aAddSessionToFDS(&ses, -1, &rds, &wrs)) < 0)
break;
if (sam3aIsActiveSession(&snr) &&
(maxfd = sam3aAddSessionToFDS(&snr, -1, &rds, &wrs)) < 0)
break;
if (sam3aIsActiveSession(&skg) &&
(maxfd = sam3aAddSessionToFDS(&skg, -1, &rds, &wrs)) < 0)
break;
// set timeout to 1 second
sam3ams2timeval(&to, 1000);
// call select()
res = select(maxfd + 1, &rds, &wrs, NULL, &to);
if (res < 0) {
if (errno == EINTR)
continue;
fprintf(stderr, "FATAL: select() error!\n");
break;
}
if (res == 0) {
// idle, no activity
fprintf(stdout, ".");
fflush(stdout);
} else {
// we have activity, process io
if (sam3aIsActiveSession(&ses))
sam3aProcessSessionIO(&ses, &rds, &wrs);
if (sam3aIsActiveSession(&snr))
sam3aProcessSessionIO(&snr, &rds, &wrs);
if (sam3aIsActiveSession(&skg))
sam3aProcessSessionIO(&skg, &rds, &wrs);
}
}
// close seessions
sam3aCloseSession(&ses);
sam3aCloseSession(&skg);
sam3aCloseSession(&snr);
// exit
return 0;
}

View file

@ -0,0 +1,205 @@
/* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*
* I2P-Bote:
* 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV
* we are the Borg. */
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include "../libsam3a/libsam3a.h"
////////////////////////////////////////////////////////////////////////////////
#define KEYFILE "streams.key"
////////////////////////////////////////////////////////////////////////////////
static void ccbError(Sam3AConnection *ct) {
fprintf(stderr,
"\n===============================\nCONNECTION_ERROR: "
"[%s]\n===============================\n",
ct->error);
}
static void ccbDisconnected(Sam3AConnection *ct) {
fprintf(stderr, "\n===============================\nCONNECTION_"
"DISCONNECTED\n===============================\n");
}
static void ccbConnected(Sam3AConnection *ct) {
fprintf(stderr, "\n===============================\nCONNECTION_CONNECTED\n==="
"============================\n");
// sam3aCancelConnection(ct); // cbSent() will not be called
}
static void ccbAccepted(Sam3AConnection *ct) {
fprintf(stderr, "\n===============================\nCONNECTION_ACCEPTED\n===="
"===========================\n");
}
static void ccbSent(Sam3AConnection *ct) {
fprintf(stderr, "\n===============================\nCONNECTION_WANTBYTES\n==="
"============================\n");
// sam3aCancelConnection(ct);
// sam3aCancelSession(ct->ses); // hehe
fprintf(stderr, "(%p)\n", ct->udata);
//
switch ((intptr_t)ct->udata) {
case 0:
if (sam3aSend(ct, "test\n", -1) < 0) {
fprintf(stderr, "SEND ERROR!\n");
sam3aCancelSession(ct->ses); // hehe
}
break;
case 1:
if (sam3aSend(ct, "quit\n", -1) < 0) {
fprintf(stderr, "SEND ERROR!\n");
sam3aCancelSession(ct->ses); // hehe
}
break;
default:
return;
}
ct->udata = (void *)(((intptr_t)ct->udata) + 1);
}
static void ccbRead(Sam3AConnection *ct, const void *buf, int bufsize) {
fprintf(stderr,
"\n===============================\nCONNECTION_GOTBYTES "
"(%d)\n===============================\n",
bufsize);
}
static void ccbDestroy(Sam3AConnection *ct) {
fprintf(stderr, "\n===============================\nCONNECTION_DESTROY\n====="
"==========================\n");
}
static const Sam3AConnectionCallbacks ccb = {
.cbError = ccbError,
.cbDisconnected = ccbDisconnected,
.cbConnected = ccbConnected,
.cbAccepted = ccbAccepted,
.cbSent = ccbSent,
.cbRead = ccbRead,
.cbDestroy = ccbDestroy,
};
////////////////////////////////////////////////////////////////////////////////
static void scbError(Sam3ASession *ses) {
fprintf(stderr,
"\n===============================\nSESION_ERROR: "
"[%s]\n===============================\n",
ses->error);
}
static void scbCreated(Sam3ASession *ses) {
char destkey[517];
FILE *fl;
//
fprintf(stderr, "\n===============================\nSESION_CREATED\n");
fprintf(stderr, "\rPRIV: %s\n", ses->privkey);
fprintf(stderr, "\nPUB: %s\n===============================\n", ses->pubkey);
//
fl = fopen(KEYFILE, "rb");
//
if (fl == NULL) {
fprintf(stderr, "ERROR: NO KEY FILE!\n");
sam3aCancelSession(ses);
return;
}
if (fread(destkey, 516, 1, fl) != 1) {
fprintf(stderr, "ERROR: INVALID KEY FILE!\n");
fclose(fl);
sam3aCancelSession(ses);
return;
}
fclose(fl);
destkey[516] = 0;
if (sam3aStreamConnect(ses, &ccb, destkey) == NULL) {
fprintf(stderr, "ERROR: CAN'T CREATE CONNECTION!\n");
sam3aCancelSession(ses);
return;
}
fprintf(stderr, "GOON: creating connection...\n");
}
static void scbDisconnected(Sam3ASession *ses) {
fprintf(stderr, "\n===============================\nSESION_DISCONNECTED\n===="
"===========================\n");
}
static void scbDGramRead(Sam3ASession *ses, const void *buf, int bufsize) {
fprintf(stderr, "\n===============================\nSESION_DATAGRAM_READ\n==="
"============================\n");
}
static void scbDestroy(Sam3ASession *ses) {
fprintf(stderr, "\n===============================\nSESION_DESTROYED\n======="
"========================\n");
}
static const Sam3ASessionCallbacks scb = {
.cbError = scbError,
.cbCreated = scbCreated,
.cbDisconnected = scbDisconnected,
.cbDatagramRead = scbDGramRead,
.cbDestroy = scbDestroy,
};
////////////////////////////////////////////////////////////////////////////////
#define HOST SAM3A_HOST_DEFAULT
//#define HOST "google.com"
int main(int argc, char *argv[]) {
Sam3ASession ses;
//
libsam3a_debug = 0;
//
if (sam3aCreateSession(&ses, &scb, HOST, SAM3A_PORT_DEFAULT,
SAM3A_DESTINATION_TRANSIENT,
SAM3A_SESSION_STREAM) < 0) {
fprintf(stderr, "FATAL: can't create main session!\n");
return 1;
}
//
while (sam3aIsActiveSession(&ses)) {
fd_set rds, wrs;
int res, maxfd = 0;
struct timeval to;
//
FD_ZERO(&rds);
FD_ZERO(&wrs);
if (sam3aIsActiveSession(&ses) &&
(maxfd = sam3aAddSessionToFDS(&ses, -1, &rds, &wrs)) < 0)
break;
sam3ams2timeval(&to, 1000);
res = select(maxfd + 1, &rds, &wrs, NULL, &to);
if (res < 0) {
if (errno == EINTR)
continue;
fprintf(stderr, "FATAL: select() error!\n");
break;
}
if (res == 0) {
fprintf(stdout, ".");
fflush(stdout);
} else {
if (sam3aIsActiveSession(&ses))
sam3aProcessSessionIO(&ses, &rds, &wrs);
}
}
//
sam3aCloseSession(&ses);
//
return 0;
}

View file

@ -0,0 +1,236 @@
/* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*
* I2P-Bote:
* 5m77dFKGEq6~7jgtrfw56q3t~SmfwZubmGdyOLQOPoPp8MYwsZ~pfUCwud6LB1EmFxkm4C3CGlzq-hVs9WnhUV
* we are the Borg. */
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include "../libsam3a/libsam3a.h"
////////////////////////////////////////////////////////////////////////////////
#define KEYFILE "streams.key"
////////////////////////////////////////////////////////////////////////////////
typedef struct {
char *str;
int strsize;
int strused;
int doQuit;
} ConnData;
static void cdAppendChar(ConnData *d, char ch) {
if (d->strused + 1 >= d->strsize) {
// fuck errors
d->strsize = d->strused + 1024;
d->str = realloc(d->str, d->strsize + 1);
}
d->str[d->strused++] = ch;
d->str[d->strused] = 0;
}
////////////////////////////////////////////////////////////////////////////////
static void ccbError(Sam3AConnection *ct) {
fprintf(stderr,
"\n===============================\nCONNECTION_ERROR: "
"[%s]\n===============================\n",
ct->error);
}
static void ccbDisconnected(Sam3AConnection *ct) {
fprintf(stderr, "\n===============================\nCONNECTION_"
"DISCONNECTED\n===============================\n");
}
static void ccbConnected(Sam3AConnection *ct) {
fprintf(stderr, "\n===============================\nCONNECTION_CONNECTED\n==="
"============================\n");
// sam3aCancelConnection(ct); // cbSent() will not be called
}
static void ccbAccepted(Sam3AConnection *ct) {
fprintf(stderr, "\n===============================\nCONNECTION_ACCEPTED\n===="
"===========================\n");
fprintf(stderr, "FROM: %s\n===============================\n", ct->destkey);
}
static void ccbSent(Sam3AConnection *ct) {
ConnData *d = (ConnData *)ct->udata;
//
fprintf(stderr, "\n===============================\nCONNECTION_WANTBYTES\n==="
"============================\n");
if (d->doQuit) {
sam3aCancelSession(ct->ses); // hehe
}
}
static void ccbRead(Sam3AConnection *ct, const void *buf, int bufsize) {
const char *b = (const char *)buf;
ConnData *d = (ConnData *)ct->udata;
//
fprintf(stderr,
"\n===============================\nCONNECTION_GOTBYTES "
"(%d)\n===============================\n",
bufsize);
while (bufsize > 0) {
cdAppendChar(ct->udata, *b);
if (*b == '\n') {
fprintf(stderr, "cmd: %s", d->str);
if (strcasecmp(d->str, "quit\n") == 0)
d->doQuit = 1;
if (sam3aSend(ct, d->str, -1) < 0) {
// sam3aCancelConnection(ct); // hehe
sam3aCancelSession(ct->ses); // hehe
return;
}
d->str[0] = 0;
d->strused = 0;
}
++b;
--bufsize;
}
}
static void ccbDestroy(Sam3AConnection *ct) {
fprintf(stderr, "\n===============================\nCONNECTION_DESTROY\n====="
"==========================\n");
if (ct->udata != NULL) {
ConnData *d = (ConnData *)ct->udata;
//
if (d->str != NULL)
free(d->str);
free(d);
}
}
static const Sam3AConnectionCallbacks ccb = {
.cbError = ccbError,
.cbDisconnected = ccbDisconnected,
.cbConnected = ccbConnected,
.cbAccepted = ccbAccepted,
.cbSent = ccbSent,
.cbRead = ccbRead,
.cbDestroy = ccbDestroy,
};
////////////////////////////////////////////////////////////////////////////////
static void scbError(Sam3ASession *ses) {
fprintf(stderr,
"\n===============================\nSESION_ERROR: "
"[%s]\n===============================\n",
ses->error);
}
static void scbCreated(Sam3ASession *ses) {
FILE *fl;
Sam3AConnection *conn;
//
fprintf(stderr, "\n===============================\nSESION_CREATED\n");
fprintf(stderr, "\rPRIV: %s\n", ses->privkey);
fprintf(stderr, "\nPUB: %s\n===============================\n", ses->pubkey);
//
fl = fopen(KEYFILE, "wb");
//
if (fl == NULL) {
fprintf(stderr, "ERROR: CAN'T CREATE KEY FILE!\n");
sam3aCancelSession(ses);
return;
}
if (fwrite(ses->pubkey, 516, 1, fl) != 1) {
fprintf(stderr, "ERROR: CAN'T WRITE KEY FILE!\n");
fclose(fl);
sam3aCancelSession(ses);
return;
}
fclose(fl);
if ((conn = sam3aStreamAccept(ses, &ccb)) == NULL) {
fprintf(stderr, "ERROR: CAN'T CREATE CONNECTION!\n");
sam3aCancelSession(ses);
return;
}
//
conn->udata = calloc(1, sizeof(ConnData));
fprintf(stderr, "GOON: accepting connection...\n");
}
static void scbDisconnected(Sam3ASession *ses) {
fprintf(stderr, "\n===============================\nSESION_DISCONNECTED\n===="
"===========================\n");
}
static void scbDGramRead(Sam3ASession *ses, const void *buf, int bufsize) {
fprintf(stderr, "\n===============================\nSESION_DATAGRAM_READ\n==="
"============================\n");
}
static void scbDestroy(Sam3ASession *ses) {
fprintf(stderr, "\n===============================\nSESION_DESTROYED\n======="
"========================\n");
}
static const Sam3ASessionCallbacks scb = {
.cbError = scbError,
.cbCreated = scbCreated,
.cbDisconnected = scbDisconnected,
.cbDatagramRead = scbDGramRead,
.cbDestroy = scbDestroy,
};
////////////////////////////////////////////////////////////////////////////////
#define HOST SAM3A_HOST_DEFAULT
//#define HOST "google.com"
int main(int argc, char *argv[]) {
Sam3ASession ses;
//
libsam3a_debug = 0;
//
if (sam3aCreateSession(&ses, &scb, HOST, SAM3A_PORT_DEFAULT,
SAM3A_DESTINATION_TRANSIENT,
SAM3A_SESSION_STREAM) < 0) {
fprintf(stderr, "FATAL: can't create main session!\n");
return 1;
}
//
while (sam3aIsActiveSession(&ses)) {
fd_set rds, wrs;
int res, maxfd = 0;
struct timeval to;
//
FD_ZERO(&rds);
FD_ZERO(&wrs);
if (sam3aIsActiveSession(&ses) &&
(maxfd = sam3aAddSessionToFDS(&ses, -1, &rds, &wrs)) < 0)
break;
sam3ams2timeval(&to, 1000);
res = select(maxfd + 1, &rds, &wrs, NULL, &to);
if (res < 0) {
if (errno == EINTR)
continue;
fprintf(stderr, "FATAL: select() error!\n");
break;
}
if (res == 0) {
fprintf(stdout, ".");
fflush(stdout);
} else {
if (sam3aIsActiveSession(&ses))
sam3aProcessSessionIO(&ses, &rds, &wrs);
}
}
//
sam3aCloseSession(&ses);
//
return 0;
}