Kaikki oikeudet pidätetään. Maailman parhaat satunnaisbitit: https://moijari.com:5006. Älä kuitenkaan käytä näitä sellaisenaan, summaa useampi generaattori, ja mielellään viimeinen omassa ohjelmassa.
Edit korjailen raporttia lähipäivien ja viikkojen aikana. Sorsia en ole vielä kokeillut kääntää… Sain käännettyä sorsan. Myös html lokit kirjoitetaan useammassa osassa. Lisätty palvelimiin vuorot lokien kirjoittamiseen. Raportti postin lopussa ennen sorsia. Korjattu pari bugia (uusi versio 0.14) ja lisätty koodia aktiivisuuden laskentaan ja lisätty yhteinen loki terttu hengessä kaikille palvelimille. Lisätty vielä muutoksia newressu.c tiedostoon, kappaleita lisätty loppuun ennen lähdekoodia.
Aiemmassa versiossa oli ongelmana se, että jos asiakas ei toteuta protokollaa oikein, palvelin saattoi pysähtyä ns blokkaavaan eli odottamaan jäävään funktioon. Tämän vuoksi uudet palvelimet (http ja https) luovat fork():lla lapsiprosessin, joka suorittaa toiminnot access() kutsusta lähtien. Näin jos lapsiprosessi “hyytyy” se ei hyydytä koko palvelinta. Seuraavana https palvelimen lapsiprosessi:
Jos palvelimeen tulee useita päällekkäisiä kyselyitä ne periaatteessa suoritetaan uudessa versiossa samaan aikaan, ja lokiin tulostuvat useamman prosessin lokirivit sekoittuneina. Tätä korjaamaan on lisätty uusi log_printf, jossa yhden prosessin lokirivit kerätään muistialueeseen ja tämä puskuri kirjoitetaan yhdellä kertaa prosessin päättyessä. Näin eri kutsujen lokirivit pysyvät eroteltuina.
Lisäksi yhteiset osat https_client:istä ja http_clientistä on yhdistetty dbs_server_vars() funktioon.
SSL_read yrittää lukua uudelleen viisi kertaa (error 1 ja error 5). Uudelleen lukujen välissä on kymmenesosasekunnin odotus (usleep()).
static void https_client(int news, SSL_CTX *ctx, struct sockaddr_in sa_cli, int addr_size, char *name)
{
int status, ok;
unsigned char buffer10[10];
SSL *ssl;
X509 *peer_cert;
ok=1;
// plus space for '\0'
htmlin = malloc(htmlinlen+1);
dbs_server_vars(sa_cli,addr_size,name);
if((ssl=SSL_new(ctx)) == NULL) {
log_printf("\n%s: cannot SSL_new()", procname);
}
if(SSL_set_fd(ssl,news) != 1) {
log_printf("\n%s: cannot SSL_set_fd()", procname);
}
status=SSL_accept(ssl);
peer_cert = SSL_get_peer_certificate(ssl);
if(peer_cert == NULL) {
log_printf(", No peer certificate");
}
log_printf("\n");
int clen = 0;
int reads = 0;
int first = 1;
htmlparams = NULL;
int bytes, totalbytes = 0;
htmlin[0]='\0';
while(htmlparams==NULL || clen-strlen(htmlparams) > 0) {
if(!first) {
log_printf(", ");
}
#ifdef DEBUG68
log_printf("SSL_read\n");
#endif
int tries=0;
for(;;) {
bytes = SSL_read(ssl, htmlin+totalbytes, htmlinlen-totalbytes);
int errerrno, err, err2;
errerrno=errno;
err=SSL_get_error(ssl,bytes);
err2=ERR_get_error();
log_printf("\nSSL_read()");
log_printf(", retval %d", bytes);
log_printf(", errno: %d", errerrno);
log_printf(", SSL_get_error(): %d", err);
log_printf(", ERR_get_error(): %d", err2);
while((err2=ERR_get_error())!=0)
log_printf(", %d",err2);
if(bytes>=0) {
reads++;
break;
}
if(bytes<0) {
if(++tries<5 && (err==1 || err==5)) {
log_printf(" try:%d",tries);
usleep(1024*512/5);
continue;
}
log_printf("\n%s: cannot SSL_read()", procname);
ok=0;
break;
} // if(bytes
break;
} // for(;;)
log_printf("(%d bytes)", bytes);
if(!ok)
break;
*(htmlin+totalbytes+bytes) = '\0';
if(bytes==0)
break;
totalbytes+=bytes;
if(totalbytes >= htmlinlen) {
// plus space for '\0'
htmlin=realloc(htmlin, htmlinlen*2+1);
htmlinlen *= 2;
}
htmlparams = dbs_html_get_params();
unsigned char *p=htmlin;
dbs_html_parse_string(sizeof(htmlmethod), htmlmethod,&p);
if(!strcmp(htmlmethod,"GET"))
break;
dbs_html_get_request_line_num("Content-Length",
sizeof(buffer10), buffer10);
clen = atoi(buffer10);
first = 0;
}
log_printf("\n%d reads", reads);
log_printf(", received %d chars", totalbytes);
log_printf(", read %d total bytes", totalbytes);
log_printf(", input buffer size %d chars", htmlinlen);
log_printf(", data=\"");
log_dump_string(htmlin);
log_printf("\"\n");
strncpy(htmlsslcipher, SSL_get_cipher(ssl), sizeof(htmlsslcipher));
if(ok)
dbs_run_loop();
if(ok) {
log_printf("buffers(ssl):");
for(int c=0;c<HTML_BUFFERS;c++) {
log_printf(" %d:%ld",c,strlen(html_get_string(c)));
if(strlen(html_get_string(c))>0) {
#ifdef DEBUG68
log_printf("SSL_write\n");
#endif
if((status=SSL_write(ssl, html_get_string(c), strlen(html_get_string(c))))<1) {
log_printf("\n%s: cannot SSL_write(), buffer %d, status: %d, SSL error: %d",
procname, c, status, SSL_get_error(ssl,status));
}
}
}
}
log_printf("\n");
log_printf("\nSSL connection using %s", htmlsslcipher);
log_printf("\n");
#ifdef DEBUG68
log_printf("SSL_free\n");
#endif
SSL_free(ssl);
free(htmlin);
}
Edellinen tuottaa joillekin käyttäjille seuraavia virheitä, joita en ole vielä saanut pois: Ne tosin voivat johtua myös kutsujan protokollaongelmasta. Listassa on tietenkin viisi uudelleen yritystä. Virheet tulevat vain joillekin käyttäjille, omissa testeissäni niitä ei esiinny.
SSL_read(), retval -1, errno: 0, SSL_get_error(): 5, ERR_get_error(): 0 try:1
SSL_read(), retval -1, errno: 0, SSL_get_error(): 5, ERR_get_error(): 0 try:2
SSL_read(), retval -1, errno: 0, SSL_get_error(): 5, ERR_get_error(): 0 try:3
SSL_read(), retval -1, errno: 0, SSL_get_error(): 5, ERR_get_error(): 0 try:4
SSL_read(), retval -1, errno: 0, SSL_get_error(): 5, ERR_get_error(): 0
./ressu4: cannot SSL_read()(-1 bytes)
Toisaalta SSL_write() tulostaa joskus tälläisen:
./ressu4: cannot SSL_write(), buffer 0, status: -1, SSL error: 6
./ressu4: cannot SSL_write(), buffer 8, status: -1, SSL error: 1, htmlparamslen: "0"
Seuraavassa varsinainen palvelinohjelma: se on samankaltainen kuin edellinenkin versio, tähän on lisätty fork() kutsu, joka luo aina asiakkaan protokollaa varten uuden lapsiprosessin.
Reset kytkintä ei ole vielä koodattu kokonaan, mutta ajatus on se että palvelin huomaisi SSL avainmuutoksen ja palvelin ottaisi resetin avulla käyttöön uudet avaimet.
log_clear() kutsu tyhjentää lokin lapsiprosessin alussa (eli fork():in paluuarvolla 0). Kuten mainittu lapsiprosessissa lokiin kirjoitukset kirjoitetaan log_printf():llä, siitä lisää myöhemmin. log_free() vapauttaa lokin puskurialueen.
Fork() suoritetaan yhden kerran, ja se palaa kahdesti, kerran lapsiprosessille paluuarvolla 0 ja kerran vanhempi prosessille, jolloin paluuarvo on lapsen prosessin id.
Jos käynnistät palvelimen $ nohup ./ressu4 –port5006 –https >>ressu4.nohup & -komennolla voit seurata palvelimen kutsuja $ tail *.nohup -f -komennolla.
https_server() kutsuu edellistä asiakasfunktiota.
#define DEBUG59 2
static void https_server()
{
int quit, reset, addr_size;
SSL_METHOD *method=NULL;
SSL_CTX *ctx=NULL;
struct sockaddr_in sa_cli;
struct addrinfo *res;
signal(SIGPIPE, SIG_IGN);
signal(SIGCHLD, SIG_IGN);
reset=1;
quit=0;
for(;;) {
if(quit) {
if(ctx!=NULL)
SSL_CTX_free(ctx);
break;
}
if(reset) {
if(ctx!=NULL)
SSL_CTX_free(ctx);
#ifdef DEBUG68
fprintf(stdout,"SSL_library_init\n");
fflush(stdout);
#endif
SSL_library_init();
#ifdef DEBUG68
fprintf(stdout,"OpenSSL_add_ssl_algorithms\n");
fflush(stdout);
#endif
OpenSSL_add_ssl_algorithms();
#ifdef DEBUG68
fprintf(stdout,"OpenSSL_add_ciphers\n");
fflush(stdout);
#endif
OpenSSL_add_all_ciphers();
#ifdef DEBUG68
fprintf(stdout,"OpenSSL_load_error_strings\n");
fflush(stdout);
#endif
SSL_load_error_strings();
#ifdef DEBUG68
fprintf(stdout,"SSLv23_server_method\n");
fflush(stdout);
#endif
if((method = (SSL_METHOD *)
SSLv23_server_method()) == NULL) {
fprintf(stderr,"\n%s: cannot SSLv3_server_method()", procname);
fflush(stderr);
}
#ifdef DEBUG68
fprintf(stdout,"SSL_CTX_new\n");
fflush(stdout);
#endif
if((ctx=SSL_CTX_new(method)) == NULL) {
fprintf(stderr,"\n%s: cannot SSL_CTX_new()", procname);
fflush(stderr);
}
#ifdef DEBUG68
fprintf(stdout,"SSL_CTX_use_certificate_file\n");
fflush(stdout);
#endif
if(SSL_CTX_use_certificate_file(ctx,
cert_file, SSL_FILETYPE_PEM) <= 0) {
fprintf(stderr,"\n%s: cannot SSL_CTX_use_certificate()", procname);
fflush(stderr);
}
#ifdef DEBUG68
fprintf(stdout,"SSL_CTX_use_PrivateKey_file\n");
fflush(stdout);
#endif
if(SSL_CTX_use_PrivateKey_file(ctx,
privatekey_file, SSL_FILETYPE_PEM)<=0) {
fprintf(stderr,"\n%s: cannot SSL_CTX_use_certificate()", procname);
fflush(stderr);
}
#ifdef DEBUG68
fprintf(stdout,"SSL_CTX_load_verify_locations\n");
fflush(stdout);
#endif
if(!SSL_CTX_load_verify_locations(ctx,
cert_file, NULL)) {
fprintf(stderr,"\n%s: cannot SSL_CTX_verify_locations()", procname);
fflush(stderr);
}
server_getaddrinfo(myport, &res);
s=server_socket(res);
server_bind(s, res);
freeaddrinfo(res);
server_listen(s);
reset=0;
} // if(reset)
fprintf(stdout,"\n");
fflush(stdout);
addr_size = sizeof(sa_cli);
#ifdef DEBUG68
fprintf(stdout,"accept\n");
fflush(stdout);
#endif
if((news=accept(s, (struct sockaddr *)&sa_cli, &addr_size))==-1) {
fprintf(stderr,"\n%s: cannot accept()\n", procname);
perror("accept");
fflush(stderr);
}
if(beepaccept)
fprintf(stderr,"\a");
pid_t pid;
#ifdef DEBUG59
fprintf(stdout,"Fork start (parent)");
fprintf(stdout," getpid:%d getppid:%d\n",getpid(),getppid());
fflush(stdout);
#endif
if((pid=fork())==0) {
log_clear();
log_printf("==========");
#ifdef DEBUG59
fprintf(stdout,"Fork start (child)");
fprintf(stdout," pid:%d getpid:%d getppid:%d\n",pid,getpid(),getppid());
#endif
close(s);
https_client(news,ctx,sa_cli,addr_size,"https");
server_close(news);
fprintf(stdout,"%s",logbuf);
#ifdef DEBUG59
fprintf(stdout,"Fork end (child)");
fprintf(stdout," pid:%d getpid:%d getppid:%d\n",pid,getpid(),getppid());
fflush(stdout);
#endif
log_free();
exit(0);
}
#ifdef DEBUG59
fprintf(stdout,"Fork end (parent)");
fprintf(stdout," pid:%d getpid:%d getppid:%d\n",pid,getpid(),getppid());
fflush(stdout);
#endif
} // for(;;)
SSL_CTX_free(ctx);
}
Seuraavassa lokin tulostukseen tarkoitetut clear(), free, ja printf rutiinit:
#include <stdarg.h>
unsigned char *logbuf=NULL;
int logbuf_length=0;
void log_clear()
{
if(logbuf!=NULL)
logbuf[0]='\0';
}
void log_free()
{
if(logbuf!=NULL) {
free(logbuf);
logbuf=NULL;
}
}
void log_printf(const char *format, ...)
{
int count,size;
va_list args;
static char *printbuf=NULL;
static int printbuf_len=0;
va_start(args,format);
count=vsnprintf(printbuf, printbuf_len, format, args) + 1;
va_end(args);
if(printbuf_len < count) {
printbuf_len = count;
printbuf=realloc(printbuf, printbuf_len);
va_start(args,format);
count=vsnprintf(printbuf, printbuf_len, format, args) + 1;
va_end(args);
}
if(logbuf==NULL ||
logbuf_length<(size=(logbuf==NULL? 0:strlen(logbuf))+count)) {
unsigned char *temp=logbuf;
logbuf_length=size;
logbuf=realloc(logbuf,size);
if(temp==NULL)
logbuf[0]='\0';
}
strcat(logbuf,printbuf);
}
Seuraavassa satunnaislukuohjelma joka on osoitteessa https://moijari.com:5006. Tietenkin siellä on myös nämä muut postissa mainitut osuudet. Ja kuten aina lopussa on kopipastattavat sorsat.
Ohjelma ajaa skriptin joka sisältää html rivejä ja /bin/newressu komentoja. Jos scriptiä ei ole, sellainen luodaan. Scriptin luonnissa se kirjoitetaan tiedostoon ressu4script.html. Jos ajat palvelinta, muuta scripti haluamaksesi.
Varsinaisessa palvelimessa scripti käydään rivi riviltä läpi, ja suoritetaan “/bin/newressu ” alkuiset rivit. Loput rivit tulostetaan sellaisenaan. Jos lisäät palvelimeen komentoja, komennon nimi kannattaa varmaankin kovakoodata kuten tässä “/bin/newressu”.
Puolipisteellä alkavat rivit ohitetaan kommentteina. Funktiolla popen() suoritetaan newressu-komento parametreineen ja saadaan fp2 tiedostohandle, josta voidaan lukea newressun tulostamat rivit.
ressuoriginal.html sisältää html-scriptin joka tulostaa sivun lopun linkit.
#define aDEBUG8
void ressu4_app()
{
unsigned char *p;
unsigned char command[128];
unsigned char buffer[1024];
unsigned char script_file[128]="ressu4script.html";
FILE *fp1,*fp2;
if((fp1=fopen(script_file,"r"))!=NULL) {
fclose(fp1);
} else {
if((fp1=fopen(script_file,"w"))!=NULL) {
fprintf(fp1,";\n");
fprintf(fp1,"; Script for ressu4 ©\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h1>%s</h1>\n",procheader);
fprintf(fp1,";\n");
fprintf(fp1,"<p>The next chapter consists of characters that\n");
fprintf(fp1," try to resemble throws of a 64 sided dice as closely as possible.\n");
fprintf(fp1," Characters have numbers from '0' to '9' (10 entries),\n");
fprintf(fp1," uppercase letters from 'A' to 'Z' (26 entries), lowercase letters\n");
fprintf(fp1," 'a' to 'z' (26 entries), '-' and '_' (2 entries).\n");
fprintf(fp1," Total is 10+26+26+2 = 64 values.\n");
fprintf(fp1," Characters are grouped into sets of 8 each. Throws\n");
fprintf(fp1," are random, so you cannot deduce value from\n");
fprintf(fp1," previous or next value(s).</p>\n");
fprintf(fp1,"<h3>Newressu random numbers</h3>\n");
fprintf(fp1,"/bin/newressu -2 -s8 -l1 -c5120 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Random digits</h3>\n");
fprintf(fp1,"/bin/newressu -11 -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Random uppercase letters</h3>\n");
fprintf(fp1,"/bin/newressu -12 -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Random lowercase letters</h3>\n");
fprintf(fp1,"/bin/newressu -13 -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h2>Random characters in number systems</h2>\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Random binary digits</h3>\n");
fprintf(fp1,"<p>Following binary numbers are eight bits from 0 to 255 decimal.\n");
fprintf(fp1," From right to left the bit multipliers are 1, 2, 4, 8, 16, 32, 64 and 128 (2^b) in decimal.\n");
fprintf(fp1," So 10000000b is 128d, 11111111b is 255d, 00000010b is 2d, 00000011b is 3d etc.\n");
fprintf(fp1," Here d after number means of course decimal. Digit numbers, b in 2^b, vary from 0 to 7.</p>\n");
fprintf(fp1,"/bin/newressu -b -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Random octal digits</h3>\n");
fprintf(fp1,"<p>These octal numbers are also from 0 to 255 decimal (0 to 377 octal).\n");
fprintf(fp1," From right to left octal digit multipliers are 1, 8, 64 (8^o) in decimal.\n");
fprintf(fp1," Here 377o is 255d, 010o is 8d, 100o is 64d.\n");
fprintf(fp1," Each octal digit contains 3 binary bits, and 377o can be grouped\n");
fprintf(fp1," in binary like this 011 111 111.</p>\n");
fprintf(fp1,"/bin/newressu -o --lim400 -l1 -c1792 --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Random decimal digits</h3>\n");
fprintf(fp1,"<p>These decimal numbers are from 0 to 99999. From right\n");
fprintf(fp1," to left decimal digit multipliers are 1, 10, 100, 1000 and 10000 (10^d).</p>\n");
fprintf(fp1,"/bin/newressu -d -s5 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Random hexadecimal digits</h3>\n");
fprintf(fp1,"<p>Next hexadecimal numbers are from 0000h to ffffh meaning 0 to 65535 decimal.\n");
fprintf(fp1," Hexadecimal digit has numbers from 0 to 9 and letters a(10),\n");
fprintf(fp1," b(11), c(12), d(13), e(14) and f(15). From right to left hexadecimal multipliers\n");
fprintf(fp1," are 1, 16, 256, 4096 decimal (16^h). Each hexadecimal digit contains 4 bits so ffffh can be\n");
fprintf(fp1," grouped in binary like this 1111 1111 1111 1111.</p>\n");
fprintf(fp1,"/bin/newressu -x -s4 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h2>Random characters in languages</h2>\n");
fprintf(fp1,";\n");
fprintf(fp1,"<p>The next chapters consists of random characters in various\n");
fprintf(fp1," languages. Most randomness is in chinese, japanese and\n");
fprintf(fp1," korean characters. Chinese has 20976 values per character,\n");
fprintf(fp1," japanese has 21158 values per character and korean has\n");
fprintf(fp1," 11172 values per character.</p>\n");
fprintf(fp1,"<p>Latin (or roman) based alphabets have characters as follows:\n");
fprintf(fp1," danish alphabet has 58 characters,\n");
fprintf(fp1," deutsch alphabet has 60 characters,\n");
fprintf(fp1," english has 52 characters,\n");
fprintf(fp1," estonian has 64 characters,\n");
fprintf(fp1," finnish alphabet has 58 characters,\n");
fprintf(fp1," french character set has 52 characters,\n");
fprintf(fp1," italian character set has 52 characters,\n");
fprintf(fp1," latvian has 66 characters,\n");
fprintf(fp1," lithuanian has 64 characters,\n");
fprintf(fp1," norwegian has 58 characters,\n");
fprintf(fp1," swedish has 58 characters.\n");
fprintf(fp1," </p>\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Chinese random characters</h3>\n");
fprintf(fp1,"/bin/newressu --cn -s8 -l1 -c1792 --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Danish random characters</h3>\n");
fprintf(fp1,";ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ\n");
fprintf(fp1,";abcdefghijklmnopqrstuvwxyzæøå\n");
fprintf(fp1,"/bin/newressu --dnk -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Deutsch random characters</h3>\n");
fprintf(fp1,";ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜẞ\n");
fprintf(fp1,";abcdefghijklmnopqrstuvwxyzäöüß\n");
fprintf(fp1,"/bin/newressu --deu -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>English random characters</h3>\n");
fprintf(fp1,";ABCDEFGHIJKLMNOPQRSTUVWXYZ\n");
fprintf(fp1,";abcdefghijklmnopqrstuvwxyz\n");
fprintf(fp1,"/bin/newressu --eng -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Estonian random characters</h3>\n");
fprintf(fp1,";ABCDEFGHIJKLMNOPQRSŠZŽTUVWÕÄÖÜXY\n");
fprintf(fp1,";abcdefghijklmnopqrsšzžtuvwõäöüxy\n");
fprintf(fp1,"/bin/newressu --est -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Finnish random characters</h3>\n");
fprintf(fp1,";ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ\n");
fprintf(fp1,";abcdefghijklmnopqrstuvwxyzåäö\n");
fprintf(fp1,"/bin/newressu --fin -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>French random characters</h3>\n");
fprintf(fp1,";ABCDEFGHIJKLMNOPQRSTUVWXYZ\n");
fprintf(fp1,";abcdefghijklmnopqrstuvwxyz\n");
fprintf(fp1,"/bin/newressu --fra -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Gothic random characters</h3>\n");
fprintf(fp1,"/bin/newressu --got -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Greek random characters</h3>\n");
fprintf(fp1,";ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ\n");
fprintf(fp1,";αβγδεζηθικλμνξοπρστυφχψω\n");
fprintf(fp1,"/bin/newressu --grc -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Italian random characters</h3>\n");
fprintf(fp1,";ABCDEFGHIJKLMNOPQRSTUVWXYZ\n");
fprintf(fp1,";abcdefghijklmnopqrstuvwxyz\n");
fprintf(fp1,"/bin/newressu --ita -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Japanese random characters</h3>\n");
fprintf(fp1,"/bin/newressu --jp -s8 -l1 -c1792 --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Korean random characters</h3>\n");
fprintf(fp1,"/bin/newressu --kor -s8 -l1 -c1792 --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Latvian random characters</h3>\n");
fprintf(fp1,";AĀBCČDEĒFGĢHIĪJKĶLĻMNŅOPRSŠTUŪVZŽ\n");
fprintf(fp1,";aābcčdeēfgģhiījkķlļmnņoprsštuūvzž\n");
fprintf(fp1,"/bin/newressu --lva -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Lithuanian random characters</h3>\n");
fprintf(fp1,";AĄBCČDEĘĖFGHIĮYJKLMNOPRSŠTUŲŪVZŽ\n");
fprintf(fp1,";aąbcčdeęėfghiįyjklmnoprsštuųūvzž\n");
fprintf(fp1,"/bin/newressu --ltu -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Norwegian random characters</h3>\n");
fprintf(fp1,";ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ\n");
fprintf(fp1,";abcdefghijklmnopqrstuvwxyzæøå\n");
fprintf(fp1,"/bin/newressu --nor -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Russian random characters</h3>\n");
fprintf(fp1,";АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ\n");
fprintf(fp1,";абвгдеёжзийклмнопрстуфхцчшщъыьэюя\n");
fprintf(fp1,"/bin/newressu --rus -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Swedish random characters</h3>\n");
fprintf(fp1,";ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ\n");
fprintf(fp1,";abcdefghijklmnopqrstuvwxyzåäö\n");
fprintf(fp1,"/bin/newressu --swe -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h2>Technical</h2>\n");
fprintf(fp1,"<p>This version runs newressu new for all of the previous\n");
fprintf(fp1," random number chapters (25 runs), so the buffer is empty in\n");
fprintf(fp1," the beginning of the chapter runs.\n");
fprintf(fp1," This whole page is created (including randomness) after your\n");
fprintf(fp1," network query is received,\n");
fprintf(fp1," so time newressu runs is quite reasonable.</p>\n");
fprintf(fp1,"<p>This version does random skips on clock material,\n");
fprintf(fp1," which makes it harder to guess it. Ressu skips\n");
fprintf(fp1," 0-255 bytes every ~1000 bytes.\n");
fprintf(fp1," This version also is ressu only, there is no whitening\n");
fprintf(fp1," or combining of other generators.</p>\n");
fclose(fp1);
}
} // if((fp1=fopen
if((fp1=fopen(script_file,"r"))!=NULL) {
while(fgets(command,sizeof(command),fp1)!=NULL) {
if(command[0]==';')
continue;
else if(!strncmp(command,"/bin/newressu ",14)) {
if((fp2=popen(command, "r"))!=NULL) {
dbs_html_printf("<code>");
while(fgets(buffer,sizeof(buffer),fp2)!=NULL) {
#ifdef DEBUG8
fprintf(stdout,"\"%s\"",buffer);
#endif
p=buffer;
while(*p!='\0') {
if(*p!='-')
dbs_html_printf("%c",*p);
else {
if(safari)
dbs_html_printf("‑");
//dbs_html_printf("−");
//dbs_html_printf("–");
//dbs_html_printf("‐");
//dbs_html_printf("-");
else
dbs_html_printf("−");
}
p++;
} // while(*p!='\0') {
//dbs_html_printf(" ");
//dbs_html_printf("\n");
//dbs_html_printf("<br>");
} // while(fgets(
dbs_html_printf("</code>");
fclose(fp2);
} // if((fp2
} else { // if(!strncmp(command
if(useragent)
dbs_html_printf("%s",command);
else if(strstr(command,"<h1>")!=NULL ||
strstr(command,"<h2>")!=NULL ||
strstr(command,"<h3>")!=NULL ||
strstr(command,"<h4>")!=NULL )
dbs_html_printf("%s",command);
} // if(strncmp
} // while(fgets
fclose(fp1);
} // if((fp1=fopen
if((fp1=fopen("ressuoriginal.html","r"))!=NULL) {
while(fgets(buffer,sizeof(buffer),fp1)!=NULL)
if(buffer[0]!=';')
dbs_html_printf("%s",buffer);
fclose(fp1);
}
}
Seuraavassa palvelimen kutsumat ressu4 funktiot: dbs_html_set valitsee puskurin, johon rivit tulostetaan tässä otsake(0) tai payload(1) (html.c). dba_loop tulostaa html sivun, dba_loop2 laskee sivun merkkien lukumäärän (Content-Length) otsakkeelle. Näiden välissä palvelin suorittaa html prettyprinter:in josta myöhemmin.
void dba_loop()
{
html_clear_all();
if(!strcmp(htmlfileextension,"ico") ||
!strcmp(htmlfileextension,"png")) {
dbs_html_set(0);
dbs_html_printf("HTTP/1.0 404 Not Found\r\n");
//dbs_html_printf("Location: \r\n");
//dbs_html_printf("Server: %s\r\n", programname);
} else {
dbs_html_set(0);
dbs_html_printf("HTTP/1.0 200 OK\r\n");
dbs_html_printf("Location: \r\n");
dbs_html_printf("Server: %s\r\n", programname);
dbs_html_printf("Date: %s\r\n", htmltime);
dbs_html_set(1);
dbs_html_printf("<!doctype html>\r\n");
dbs_html_printf("<html lang=\"fi\">");
dbs_html_printf("<head>");
dbs_html_printf("<meta charset=\"utf-8\">");
dbs_html_printf("<title>%s</title>",proctitle);
dbs_html_printf("<meta name=\"author\" content=\"Jari Kuivaniemi\">");
dbs_html_printf("<meta name=\"copyright\" content=\"Jari Kuivaniemi\">");
dbs_html_printf("<meta name=\"format-detection\" content=\"telephone=no\">"); // Safari
dbs_html_printf("<meta name=\"format-detection\" content=\"telephone=no\"/>"); // Safari
dbs_html_printf("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">");
dbs_html_printf("</head>");
dbs_html_printf("<body>");
ressu4_app();
dbs_html_printf("<p>%s", programname);
dbs_html_printf(", sha256(%s)", htmldigest);
dbs_html_printf("</p>");
dbs_html_printf("</body>");
dbs_html_printf("</html>");
}
}
Prettyprinter formatoi html scriptin uudestaan, ja tällöin payload puskurin pituus muuttuu. Content-Length lasketaan vasta prettyprinter:in jälkeen: Lisäksi tulostetaan otsakkeen ja payloadin välillä oleva cr-lf-cr-lf sarja.
Content-Length riville lasketaan kaikki muut puskurit paitsi 0 eli otsake.
void dba_loop2()
{
int len;
dbs_html_set(0);
len=strlen(html_get_string(1)) +
strlen(html_get_string(2)) +
strlen(html_get_string(3)) +
strlen(html_get_string(4)) +
strlen(html_get_string(5)) +
strlen(html_get_string(6)) +
strlen(html_get_string(7)) +
strlen(html_get_string(8));
log_printf("Content-Length: %d\n",len);
dbs_html_printf("Content-Length: %d", len);
dbs_html_printf("\r\n\r\n");
}
Tämä on klassinen joka ohjelmaan kuuluva write only pätkä. Se käy asiakas-ohjelman muodostaman html-scriptin läpi, ja muotoilee sen lisäten sisennykset. Ohjelmassa on iso iffi, jossa on erilaiset käsittelyt alkutagille, lopputagille ja teksteille. Ennen koodia muotoiltu html-scripti:
<!doctype html>
<html lang="fi">
<head>
<meta charset="utf-8">
<title>Ressu random numbers</title>
<meta name="author" content="Jari Kuivaniemi">
<meta name="copyright" content="Jari Kuivaniemi">
<meta name="format-detection" content="telephone=no">
<meta name="format-detection" content="telephone=no"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<h1>Ressu random numbers (3rd edition)</h1>
<p>The next chapter consists of characters that try to resemble throws of a 64 sided dice as closely
as possible. Characters have numbers from '0' to '9' (10 entries), uppercase letters from 'A' to 'Z'
(26 entries), lowercase letters 'a' to 'z' (26 entries), '-' and '_' (2 entries). Total is
10+26+26+2 = 64 values. Characters are grouped into sets of 8 each. Throws are random, so you cannot
deduce value from previous or next value(s).</p>
<h3>Newressu random numbers</h3>
<code>_−MnnU0t zMILwAzz _2QvgUvn ZiTlUvUa NFQ8SAWH Y16F−WfQ SuNISxyL pcfa1veB
SwY−Sv_s nGU8zPEL eEJXLzHh CM88ViFN dQOdn8G2 NlGtAMYI iGpPs7SH bzRse_PQ CZ0qnLpd
cARyjtSX 0WAhwrf− i0kNx3W2 9Z6Acz5q 8Ik0hsxy fHHT1jRD XXbwNO4_ AsIbJD7O MSiJX−wv
bDkAVVcu r9PHGcS0 IzCtSytI g8E565wO GyPga1LE 4aud−VdS RHJDDQL− CLd4oo4L oX9evdxW
...
kLq1ipRv gAx50HPh DmYWlnC6 YE3cFz6n SUXaGxNO VomWkvak PCIi0TZ0 −Aji6Ic_ o97UH−cf
c−bcT66x DBJZfuyP 0DInhV72 h3tg10Ut EemFvFM2 Vgqb7dTT rRu5cieb d525p4Mt P7dl5NK−
gz6nADAr b3NmlG2p yX6J2GiL 3_aQPB−F 2btVCtEI IVFKckK9 Z5Td_Efe IytGwbob kHZoXbOC
xVRHgtq7</code>
<h3>Random digits</h3>
<code>80313684 35745972 00745113 11965506 39675183 31627471 96260247 63282566 20584179
75300052 77578427 13585911 50498322 42744053 50358954 49905271 58259581 03942398 26828764
04379099 26025983 87357515 02820498 26270068 02318240 95638924 41550156 07366984 73725656
95465312 57023555 71860218 26527096 64829893 47562651 26652479 99838964 11307190 84028643
...
43822905 45192876 80902045 91287056 62271398 18354252 09842608 58491390 36494150 06737249
79097332 78982704 51002048 98004383 30727141 69582220 67771805 16857046 37252823 02127291
75806553 92973387 12285285 12582540 79234018 40546782 14578681 84859328 04505090 18357251
99180783 65733520 48631827 20279470 04679868 94102024 34890821 98137030 73108089 41263404</code>
<h3>Random uppercase letters</h3>
<code>AUBQMVVZ IDBFUNFU EWSQJXLI PESJYIUG RJKITODE IDWXMVAG KDEIQBJV YWVBTERK KXNHHMRD
JTDHVEQW VQUNSMSX JERKHYVQ WATLYHIM HOXBQRSX AWZEBOMC IURFFOEZ NICWPOBT YLHFCFFK LNYDTXXE
GVRVMCFM JZWLHOZF GDOYZIPU QARHVPHO PEAEHOIJ LWSAJEPN UWOAICBV OEZUEKYD PTCVQCUM EDLYCDOQ
RAANTTVG TTXVXNFM NZOLDAJS FTWIFKFE UUTDBSRA DAJGRZCY VDPVBAVM SYLLMMRQ MLAMPJOJ ZLPEMKSE
ISYDWSBF DHQMLMBM IUWRCHAZ KEZTQHWT NSFCBRDJ IVYCEYHG BRBJZOIP GRDHFPHE MALPLXHN SHPGMKIB
...
CLLLBWQV BBNZRWXD HUWJBBJR WEJYWLIJ NAJODNVH JRVLIWTY OGLLYFSF JRPMMCSY JLFJKQTO YUOZUKUM
WMGKGWET SRFZZGFK WSHLWUPX RKALRMFV XBHHHTTF GJNXCHAY FWCDAGCI BRGYQJKD XNTHBNUY YOLWRYCK
MCLIUAKU WERPDLSD WBFPJWGQ EUTNUJII VAJOLVPV ATVOVPQT PFUCXWZL JXYGYXOG EXMYXKYT EPOZVXFZ
WTHXVPUF OMMTIXXE BVNYVSVB MLZHOZNT NGZGYCRN SDBVJUEJ CCUCJBEF GZBFSXET PRRRMSBI PVBSQKKQ</code>
<h3>Random lowercase letters</h3>
<code>ncdxfqnc aouweehi hamohwtd rhccumkp zvsxtkbm kmkncixk poucraok gvgxnqmt xjddvykh
kqackiak krojmfsn gjgonlio sptakqqu jzzwsqmw bvkexphf exujzvtl moraehkn snthsdwb yvpcptom
roifedpi wzglxgvq rcuwbbje qbbohgvy pxqxsnmu mccldckk idcwlths vnfgeeaz xjnhwxyq gbuscedb
zowriyfe pjbqeoad hrqynigj vhrjlyui iokaxxmo zafimxzv pdjgldxs ocmaljlz mjbvdofr bhwudqkg
zzjgygoz fjhrqyru nwuivcqy vyfjsmzy xxznieam omzgczbu gcxppsqv azpworcc hbyyjcga hinulxnt
...
mjoxwldd aczipohr diltdgol olrccnqg nkmxjieo ttyxznjf zqzteonk inalvyvq esystahu zeesrmdv
pbdazwoy bkivauss tkvnizfk rwtsdsny otcdoaxv ttoewgtf utjkaqpc vqcbedri gluifwmx sevbupal
gowmzyia ruwvzzrg uqgmskzv onwwurib fwwginyp dklxxfwf hywmhqlc cyyfyenb hddfngsw zybqvptd
dwaixegk drrwmccs vouyjvwb spfxctdn onyjwcap zprretng ccemcduj lnrngwpj rsrqpucm onbeixhh</code>
<h2>Random characters in number systems</h2>
<h3>Random binary digits</h3>
<p>Following binary numbers are eight bits from 0 to 255 decimal. From right to left the bit
multipliers are 1, 2, 4, 8, 16, 32, 64 and 128 (2^b) in decimal. So 10000000b is 128d, 11111111b is
255d, 00000010b is 2d, 00000011b is 3d etc. Here d after number means of course decimal. Digit
numbers, b in 2^b, vary from 0 to 7.</p>
<code>10000100 10001011 00000101 01010110 10111101 01001011 01001010 01111100 10010111
11010010 11110111 11011111 00001100 10110101 10010110 11100011 01010001 10000101 00010010
10111111 10010101 01100011 01110110 10101010 01001100 10100011 11101101 00001011 10110011
10100001 11011101 10000000 10100100 01000010 11001000 11101110 00100000 00000010 01111000
...
10100011 11001000 01101010 11101001 10011001 10110010 11011110 11110001 11010110 00011000
01000100 00010011 00100100 01100010 11100110 01011101 10000110 10111000 11010110 11001111
01111101 10001000 00010110 11011010 10011101 11111001 01101011 00111011 00111111 10000111
11010111 11110010 10001110 11100011 11101010 00101111 01100101 11100110 10111100 11010011</code>
<h3>Random octal digits</h3>
<p>These octal numbers are also from 0 to 255 decimal (0 to 377 octal). From right to left octal digit
multipliers are 1, 8, 64 (8^o) in decimal. Here 377o is 255d, 010o is 8d, 100o is 64d. Each octal digit
contains 3 binary bits, and 377o can be grouped in binary like this 011 111 111.</p>
<code>102 025 024 061 277 033 242 213 004 334 107 102 144 367 150 247 237 016 217 134 042 370 267 162 175 301
230 373 125 115 272 123 014 026 112 351 047 132 252 326 053 344 073 364 174 017 150 324 326 040 224 231 165 173
143 011 160 175 143 010 021 136 076 017 231 164 135 167 313 021 245 230 300 234 314 267 150 271 367 352 042 177
125 070 337 074 061 342 117 353 176 331 372 100 152 110 012 340 016 362 161 322 323 032 227 061 047 215 006 216
003 157 212 001 005 375 326 125 227 154 354 345 063 214 263 120 257 255 037 276 305 234 214 137 277 075 134 267
...
011 343 304 205 146 152 276 223 110 115 334 250 115 173 027 371 376 317 133 234 107 352 053 155 212 044 032 253
323 127 347 231 066 011 026 366 102 260 227 344 231 153 044 371 115 264 352 237 330 071 322 156 173 307 133 065
066 245 275 270 321 145 222 036 140 060 362 077 270 166 330 117 173 017 223 066 170 304 063 221 036 223 165 073
357 066 353 334 116 025 201 360 321 200 073 020 077 156 141 162 011 126 157 344 111 240 164 315 122 252 137 244
072 015</code>
<h3>Random decimal digits</h3>
<p>These decimal numbers are from 0 to 99999. From right to left decimal digit multipliers are 1, 10,
100, 1000 and 10000 (10^d).</p>
<code>24419 31184 02393 04466 14613 16133 79118 27250 72887 08069 71932 68501 99089 75389 78600
27515 57258 86941 81577 34050 41156 02253 30409 02904 90536 95086 10717 44661 01654 28649 86938
26666 79745 87626 91850 86989 19827 11135 23508 12355 64724 04439 52568 63139 02473 05829 50914
32411 25782 02409 28444 63704 68532 86493 85871 00441 49962 73554 67031 15180 33919 12141 79904
...
38024 67921 62186 26159 42438 04270 78192 54364 96314 96670 15650 08550 35165 55312 71523 22212
72163 37309 41644 68769 28343 04812 81462 73380 88334 07695 95749 74636 93787 97867 26227 76150
78417 48706 88812 68138 53680 08453 31168 40950 14859 98299 53943 96364 12848 63945 66586 98180
15320 25092 79344 35777 71710 10193 88538 72530 37765 40684 49186 99440 96100 79970 63910 57759
00684 63359 12128 10759 83732 87712 36846 03493 36866 61989 50384</code>
...
<h2>Technical</h2>
<p>This version runs newressu new for all of the previous random number chapters (25 runs), so the
buffer is empty in the beginning of the chapter runs. This whole page is created (including
randomness) after your network query is received, so time newressu runs is quite reasonable.</p>
<p>This version does random skips on clock material, which makes it harder to guess it. Ressu skips
0-255 bytes every ~1000 bytes. This version also is ressu only, there is no whitening or combining of
other generators.</p>
<p>Original url(s):<br>
ressu:
<a href="https://moijari.com:5006">https://moijari.com:5006</a>(third edition)<br>
ressu:
<a href="https://moijari.com:5005">https://moijari.com:5005</a>(second
edition)<br>
ressu:
<a href="https://moijari.com:5001">https://moijari.com:5001</a>(first edition)<br>
terttu:
<a href="https://moijari.com:5004">https://moijari.com:5004</a>
</p>
<p>Ressu4 version 0.2 ©,
sha256(1b1c265ad48cefcdc43032f475775ab3ef68f2348e24f94f3282dce5e1e89e40)</p>
</body>
</html>
Here is prettyprinter code:
#define aDEBUG36 2
#define aDEBUG37 2
void html_indent(unsigned char *p2)
{
int space, ch, tags, tagfound, intag, inchar;
unsigned char *p,*q,*q2,name[32],tag[48];
p=p2;
ch=0;
indent=0;
inchar=0;
while(*p!='\0') {
space = 0;
while(*p=='\r' || *p=='\n' || *p=='\t' || *p==' ') {
p++;
space = 1;
}
if(!strncmp(p,"<br>",4)) {
p+=4;
html_printf("<br>");
#ifdef DEBUG36
fprintf(stdout,"<br>");
#endif
printedchars+=4;
while(*p=='\r' || *p=='\n' || *p=='\t' || *p==' ')
p++;
#ifdef DEBUG36
fprintf(stdout,"[nextchar:%c]",*p);
#endif
if(strncmp(p,"</",2))
html_out_crlf();
}
if(!strncmp(p,"</",2)) { // Check for end tag
q2 = p;
p += 2;
q = p;
html_parse_name(sizeof(name), name, &q);
q = q2 - 1;
tags = 0;
tagfound = 0;
// Search for start tag backward
sprintf(tag,"<%s", name);
while(q >= p2) {
if(*q == '<') {
if(!strncmp(tag, q, strlen(tag))) {
#ifdef DEBUG36
fprintf(stdout,"[tag:%s]", tag);
#endif
tagfound = 1;
break;
} else
tags++;
}
q--;
}
if(tags && indent > 0) {
indent--;
#ifdef DEBUG36
fprintf(stdout,"[indent:%d]",indent);
fprintf(stdout,"[tagfound:%d]",tagfound);
#endif
html_out_crlf();
}
html_printf("</");
#ifdef DEBUG36
fprintf(stdout,"</");
#endif
space = 0;
intag = 1;
inchar = 0;
#ifdef DEBUG36
fprintf(stdout,"[inchar:%d]",inchar);
#endif
printedchars+=2;
} else if(*p=='<') { // Check for start tag
p++;
q = p;
html_parse_name(sizeof(name),name,&q);
tags = 0;
tagfound = 0;
// Search for end tag forward
sprintf(tag,"</%s",name);
while(*q!='\0') {
if(*q=='<') {
if(!strncmp(tag, q, strlen(tag))) {
#ifdef DEBUG36
fprintf(stdout,"[tag:%s]",tag);
#endif
tagfound = 1;
break;
} else
tags++;
}
q++;
}
html_out_crlf();
if(tags && tagfound) {
indent++;
#ifdef DEBUG36
fprintf(stdout,"[indent:%d]",indent);
fprintf(stdout,"[tagfound:%d]",tagfound);
#endif
}
html_printf("<");
#ifdef DEBUG36
fprintf(stdout,"<");
#endif
space = 0;
intag = 1;
inchar = 0;
#ifdef DEBUG36
fprintf(stdout,"[inchar:%d]",inchar);
#endif
printedchars++;
} else if((isprint(*p) || *p>=128) && *p!='\0') {
if(!inchar && !intag) {
inchar=1;
#ifdef DEBUG36
fprintf(stdout,"[inchar:%d]",inchar);
#endif
//html_out_crlf();
}
int count=0;
for(q=p;(isprint(*q) || *q>=128) && *q!='\0';q++) {
if(*q=='\r' || *q=='\n' || *q=='\t' || *q==' ')
break;
#ifdef DEBUG36
fprintf(stdout,"%c",*q);
#endif
count++;
}
#ifdef DEBUG36
fprintf(stdout,"(%d)",count);
#endif
}
int chars = 0;
// calculate number of chars
q = p;
while((*q!='<' && (isprint(*q) || *q>=128)) && *q!='\0') {
if(*q=='\r' || *q=='\n' || *q=='\t' || *q==' ')
break;
if(*q<0x80 || *q>0xbf) // utf8 too
chars++;
if(*q=='>')
break;
q++;
}
// print line break if needed
if(indent*8+printedchars+chars > 100 && !intag) {
html_out_crlf(); // print nl+indent
space = 0;
}
// print space if needed
if(ch != '>' && // no space after tag
*p != '<' && // no space before tag
printedchars > 0 &&
space) {
html_printf(" ");
#ifdef DEBUG36
fprintf(stdout," ");
#endif
space = 0;
}
//print the string
while((*p != '<' && (isprint(*p) || *p >= 128)) && *p != '\0') {
if(*p == '>') {
intag = 0;
}
if(*p == '\r' || *p == '\n' || *p == '\t' || *p == ' ')
break;
ch = *p;
html_printf("%c", *p);
#ifdef DEBUG36
fprintf(stdout,"%c",*p);
#endif
printedchars++;
if(*p=='>') {
p++;
break;
}
p++;
}
#ifdef DEBUG36
fprintf(stdout,"(%d)",chars);
#endif
} //while(*p!='\0')
#ifdef DEBUG37
fprintf(stdout,"%s",html[html_now]);
#endif
}
Asiakas palvelin kutsuu newressu komentoa saadakseen satunnaisbittejä. Seuraavassa newressun päämuutos, eli satunnaisten bittien ohitus kellojonossa:
Ohituksen (skip) satunnaisuutta ei tietenkään voi ottaa puskurista, koska silloin se ei vaikuttaisi ollenkaan kahteen samalla kellojonolla tehtyyn ajoon. Tässä sitä varten lasketaan puskurimerkin numero, jolla varsinainen 8 bittinen satunnaismerkki luetaan puskurista. Puskurimerkin numeroon lasketaan muunmuassa kellon sekunnit (katso koodi).
#define MORESECURE 2
#define aDEBUG3 2
static unsigned char ressu_clockbyte() /* JariK 2013 */
{
unsigned char ch;
ch=ressu_clockbyte2();
#ifdef MORESECURE
static unsigned int rndbits2pausecount=1000, rndbits2pausebase=0;
if(--rndbits2pausecount == 0) {
#ifdef FORT
if(input == INPUT_FORT ||
input == INPUT_FORTXOR)
rndbits2pausebase += cvar[0] + 256 * cvar[1];
#endif
rndbits2pausebase = rndbits2pausebase +
rndbits2pausecount +
clockbytes +
genbytes +
gent_pos +
time(NULL) +
ch;
int skip=ressut[rndbits2pausebase % ressut_bytes];
while(skip>0) { // compare usleep(skip);
ch=ressu_clockbyte2();
skip--;
}
rndbits2+=8;
rndbits2pausecount=500+ressut[(rndbits2pausebase + 1) % ressut_bytes]*4; // value 500-1500
#ifdef DEBUG3
fprintf(stdout,"\n%05d",pausecount);
newressu_output=1;
#endif
}
#ifdef DEBUG3
fprintf(stdout," %02x",ch);
newressu_output=1;
#endif
#endif // #ifdef MORESECURE
return(ch);
}
Newressua on nopeutettu hieman lisäämällä väliinputoaja sanan pituuksille käsittelyitä: Ennen tässä rutiinissa oli käsittely vain yksimerkkisille (byte) 2 merkkisille (short), 4 merkkisille (int) ja 8 merkkisille (long) tietotyypeille. Uudessa versiossa on erilliset käsittelyt myös 3, 5, 6 ja 7 merkkisille satunnaislukusanoille.
// Little faster on middle byte numbers (3,5,6,7),
// try --rand & --timer
#define GENMIDBYTES 2
#define aDEBUG19 2
int ressu_genbyte_limit(int limit) // 1 byte
{
int c;
while((c=ressu_genbyte()) >= (0x100/limit)*limit);
#ifdef DEBUG19
fprintf(stdout," byte %x(%d)",c,c);
fflush(stdout);
#endif
return(c%limit);
}
int ressu_genshort() // 2 bytes
{
return(ressu_genbyte() | ressu_genbyte()<<8);
}
int ressu_genshort_limit(int limit) // 2 bytes
{
int c;
while((c=ressu_genshort()) >= (0x10000/limit)*limit);
#ifdef DEBUG19
fprintf(stdout," short %x(%d)",c,c);
fflush(stdout);
#endif
return(c%limit);
}
#ifdef GENMIDBYTES
int ressu_gen3bytes() // 3 bytes
{
return(ressu_genshort() | ressu_genbyte()<<16);
}
int ressu_gen3bytes_limit(int limit) // 3 bytes
{
int c;
while((c=ressu_gen3bytes()) >= (0x1000000/limit)*limit);
#ifdef DEBUG19
fprintf(stdout," 3 bytes %x(%d)",c,c);
fflush(stdout);
#endif
return(c%limit);
}
#endif // #ifdef GENMIDBYTES
unsigned int ressu_genint() // 4 bytes
{
return(ressu_genshort() | ressu_genshort()<<16);
}
unsigned int ressu_genint_limit(unsigned long limit) // 4 bytes
{
unsigned int c;
while((c=ressu_genint()) >= (((unsigned long)0x100000000)/limit)*limit);
#ifdef DEBUG19
fprintf(stdout," int %x(%d)",c,c);
fflush(stdout);
#endif
return(c%limit);
}
#ifdef GENMIDBYTES
unsigned long ressu_gen5bytes() // 5 bytes
{
return(ressu_genint() | ((unsigned long)ressu_genbyte())<<32);
}
unsigned long ressu_gen5bytes_limit(unsigned long limit) // 5 bytes
{
unsigned long c;
while((c=ressu_gen5bytes()) >= (((unsigned long)0x10000000000)/limit)*limit);
#ifdef DEBUG19
fprintf(stdout," 5 bytes %lx(%ld)",c,c);
fflush(stdout);
#endif
return(c%limit);
}
unsigned long ressu_gen6bytes() // 6 bytes
{
return(ressu_genint() | ((unsigned long)ressu_genshort())<<32);
}
unsigned long ressu_gen6bytes_limit(unsigned long limit) // 6 bytes
{
unsigned long c;
while((c=ressu_gen6bytes()) >= (((unsigned long)0x1000000000000)/limit)*limit);
#ifdef DEBUG19
fprintf(stdout," 6 bytes %lx(%ld)",c,c);
fflush(stdout);
#endif
return(c%limit);
}
unsigned long ressu_gen7bytes() // 7 bytes
{
return(ressu_genint() | ((unsigned long)ressu_gen3bytes())<<32);
}
#define aDEBUG22
unsigned long ressu_gen7bytes_limit(unsigned long limit) // 7 bytes
{
unsigned long c;
while((c=ressu_gen7bytes()) >= (((unsigned long)0x100000000000000)/limit)*limit);
#ifdef DEBUG19
fprintf(stdout," 7 bytes %lx(%ld)",c,c);
fflush(stdout);
#endif
return(c%limit);
}
#endif // #ifdef GENMIDBYTES
unsigned long ressu_genlong() // 8 bytes
{
return(((unsigned long)ressu_genint()) | ((unsigned long)ressu_genint())<<32);
}
unsigned long ressu_genlong_limit(unsigned long limit) // 8 bytes
{
unsigned long c;
while((c=ressu_genlong()) >= (((unsigned long)0xffffffffffffffff)/limit)*limit);
#ifdef DEBUG19
fprintf(stdout," long %lx(%lu)",c,c);
fflush(stdout);
#endif
return(c%limit);
}
#define aDEBUG24 2
unsigned long ressu_gen_limit(unsigned long limit)
{
unsigned long c;
if(limit<=0x100) // 1 byte
c=ressu_genbyte_limit(limit);
else if(limit<=0x10000) // 2 bytes
c=ressu_genshort_limit(limit);
#ifdef GENMIDBYTES
else if(limit<=0x1000000) // 3 bytes
c=ressu_gen3bytes_limit(limit);
#endif
else if(limit<=(unsigned long)0x100000000) // 4 bytes
c=ressu_genint_limit(limit);
#ifdef GENMIDBYTES
else if(limit<=(unsigned long)0x10000000000) // 5 bytes
c=ressu_gen5bytes_limit(limit);
else if(limit<=(unsigned long)0x1000000000000) // 6 bytes
c=ressu_gen6bytes_limit(limit);
else if(limit<=(unsigned long)0x100000000000000) // 7 bytes
c=ressu_gen7bytes_limit(limit);
#endif
else if(limit<=(unsigned long)0xffffffffffffffff) // 8 bytes
c=ressu_genlong_limit(limit);
else
c=-1;
#ifdef DEBUG24
fprintf(stdout,"/%ld/",c);
#endif
return(c);
}
Seuraavalla pääohjelmasta löytyvällä –screen optiolla voidaan tehdä satunnaismerkkejä näytöllinen.
for(c=1;c<argc;c++) {
if(!strncmp("-",argv[c],1)) {
...
} else if(!strncmp("--screen",argv[c],8)) {
struct winsize w;
ioctl(0, TIOCGWINSZ, &w);
chars = w.ws_col;
lines = w.ws_row-1;
words = 0;
screen = 1;
#ifdef DEBUG71
fprintf(stdout,"screencolumns:%d",chars);
fprintf(stdout," screenlines:%lld\n",lines);
#endif
Seuraavalla voidaan tulostaa heksadesimaalisatunnaismerkkejä isoilla kirjaimilla:
for(c=1;c<argc;c++) {
if(!strncmp("-",argv[c],1)) {
...
} else if(!strcmp("-X",argv[c])) {
digits = "0123456789ABCDEF";
charspaces = 0;
charwidth = 1;
size = 4;
type = 16;
Seuraavilla voidaan tulostaa japanilaisia, kiinalaisia ja korealaisia satunnaismerkkejä.
} else if(!strcmp("--jp",argv[c])) { // japanese hiragana alphabet
digits = NULL;
digits_add_string(&digits,
"ぁあぃいぅうぇえぉおかがきぎく"
"ぐけげこごさざしじすずせぜそぞた"
"だちぢっつづてでとどなにぬねのは"
"ばぱひびぴふぶぷへべぺほぼぽまみ"
"むめもゃやゅゆょよらりるれろゎわ"
"ゐゑをんゔゕゖ");
digits_add_string(&digits,
"゠ァアィイゥウェエォオカガキギク"
"グケゲコゴサザシジスズセゼソゾタ"
"ダチヂッツヅテデトドナニヌネノハ"
"バパヒビピフブプヘベペホボポマミ"
"ムメモャヤュユョヨラリルレロヮワ"
"ヰヱヲンヴヵヶヷヸヹヺ・ーヽヾヿ");
digits_add_limits(&digits,0x4e00,0x9fef);
digitsext = digits;
charspaces = 0;
charwidth = 2;
size = 8;
} else if(!strcmp("--jp1",argv[c]) // japanese hiragana alphabet
||!strcmp("--hir",argv[c])) { // japanese hiragana alphabet
digits=
"ぁあぃいぅうぇえぉおかがきぎく"
"ぐけげこごさざしじすずせぜそぞた"
"だちぢっつづてでとどなにぬねのは"
"ばぱひびぴふぶぷへべぺほぼぽまみ"
"むめもゃやゅゆょよらりるれろゎわ"
"ゐゑをんゔゕゖ";
charspaces = 0;
charwidth = 2;
size = 8;
} else if(!strcmp("--jp2",argv[c]) // japanese katakana alphabet
||!strcmp("--kat",argv[c])) { // japanese katakana alphabet
digits=
"゠ァアィイゥウェエォオカガキギク"
"グケゲコゴサザシジスズセゼソゾタ"
"ダチヂッツヅテデトドナニヌネノハ"
"バパヒビピフブプヘベペホボポマミ"
"ムメモャヤュユョヨラリルレロヮワ"
"ヰヱヲンヴヵヶヷヸヹヺ・ーヽヾヿ";
charspaces = 0;
charwidth = 2;
size = 8;
} else if(!strcmp("--cn",argv[c]) // chinese alphabet
||!strcmp("--jp3",argv[c]) // japanese kanji alphabet
||!strcmp("--kan",argv[c])) { // japanese kanji alphabet
digits = NULL;
digits_add_limits(&digits,0x4e00,0x9fef);
digitsext = digits;
charspaces = 0;
charwidth = 2;
size = 8;
} else if(!strcmp("--kor",argv[c])) { // korean alphabet
digits = NULL;
digits_add_limits(&digits,0xac00,0xd7a3); // Hangul Syllables (AC00–D7A3)
//digits_add_limits(&digits,0x1100,0x11ff); // Hangul Jamo (1100–11FF)
//digits_add_limits(&digits,0x3130,0x318f); // Hangul Compatibility Jamo (3130–318F)
//digits_add_limits(&digits,0xa960,0xa97f); // Hangul Jamo Extended-A (A960–A97F)
//digits_add_limits(&digits,0xd7b0,0xd7ff); //Hangul Jamo Extended-B (D7B0–D7FF)
digitsext = digits;
charspaces = 0;
charwidth = 2;
size = 8;
Mallituloste japanin satunnaisista merkeistä: (hirakana, katakana ja kanji)
$ newressu --hir
00000 にきこねのいにぺでいべえいほこづずおぼちとぬべもみぴややよばりや
00001 っすゔちでわておゖけゑゃぴいあぶどへぞかやのぇきむげだぱのぞろち
00002 つぺけゖゐだもをゅあにだぴっぁでげゕどたぅえぃゃれとてけはゆぇか
00003 つずばぇぺこぃげあそぷゑしわげびだろばろこぽべどたぶもちごにょな
00004 つにだぉやゃぐゃいほりりゆぺそぜゔべゐぱっぉごけこはゆぃひなぱや
00005 ゅめろっぺぺだへぎぃたいわのばはぜぇゑゃべくちまぬばひぞげっばの
00006 ゆそだほゔるびゐずぺやもゕのゅぁがさぞぃだゖぷだべやきわぱぞぉね
00007 けせばさわそぐぅべばごむやぐろぇになそしまをずぽずどべるぱぃきぶ
00008 だゖわゃゕんまぅよゔらみぞぢのぶべぃゖねぬゐぴほくばびぷめめゅぺ
00009 ぷすけぇかべぬしちぐがいてぬゕめろぬりぅぇひへゕやくへぢくゕこす
$ newressu --kat
00000 ヅァヌリブアスヷフヘケヰネヽヷブヺワリベツイトセッレペヲゾチヲェ
00001 ュハグルホマドゼーサヶヶヽテプユケヱヴフホゴヨョゲヺテグードゲガ
00002 ヨグペブヺパニジヅヘルキゥリイゾワンキオキジョパゲペボヒ゠ロヨピ
00003 ヿィベコセダノテダポヨヴフヵヅズヤースヘーヨーキヨツャヱオダ゠フ
00004 ヱカハメナムツリビヸヹキカンナダエオヱズヅモテマオザツヮゼレジパ
00005 ョエキヷセペヿ゠ゲヒカミメヺヰノガフキヽーナズグカプ゠オネカペネ
00006 ヵキカヾオンヨゼベヰモミボルヒプマトテヺヤヰスダヺバヒィヴロヷリ
00007 ワゥデヽフヽダヴメユヅマリラヅュブボピアマゲコヺセァネスヴモヂワ
00008 ンニバワヹユヨユベヂナツマヅププピミキウヶヸノトメブヰヮサペアズ
00009 ゠イヶモ゠ラヅホムツチガソホポメスヂドハトラバラ゠コリィョネアリ
$ newressu --kan
00000 賵媵眼甙倐賔歌明卣鼜藕喍咽嘖鳨烉鋺丁飧巎樣换凈詋筃耫吋昀汓菂嵫娻
00001 钼仒盜楃禄戨及耥湂循倾檟夅蘡榸來霢煯淯犪祘嘏彨萾簲癐亮驘晏禜焳喇
00002 釿縐鏄賢崠夑膗遈枆倍椕乗瑳邂炉糲贠停櫃姵鄹墱漱岷镨鰠駲啝壢屌卸睘
00003 裂梶娜奕登銴溏羅默祱嵷琠犛劭灥鰈麸駂夕聂剘蜈齾取壻铬尢唋祳蓿獂孀
00004 央镩塛镋薁觵俩蹘榣溃萱婖泠珎欝秓咈怋郃湷摘篡緹楑篑邒濝偃瞆聬綣饑
00005 矝龼撎畮龯徉惖嵜鴕鎮粎销攢煣籱氛揮誑筣抮殬渕勎顓牤豠課膵緣劎闝齮
00006 戏十諻劊壴銀阘誥闄吡堼羷籒皙鲻踑佑躍斛瘛旓餺茘髳何萣憊鱃祜枑搠堦
00007 腣闂媿辏巎鿘梶錢褶痈喕盡再哿劀粸幐豞湉噻髏慜淍嬳垎喇驾铕灠婿庭姑
00008 筎砏紻兮眮旋赀窤蚟膞霑唊鲙鐀鄒袴橆碙岅饛耉礮憴婲偈驞竇鰉晃鱃镘嵒
00009 儚湾埈劾醽莋癎鲄料偌卤嵹斵涷蒬仓睏咋霿鲺埽骘霖痰驞怊龜刚鞃炷筘蠊
Mallituloste kiinan satunnaisista merkeistä:
$ newressu --cn
00000 嚡拪帎鐓萱潞殣僓闚邐鈸薏道鴳鞇诡扙迊峐弧掐龀閏缋痗尛弦徑叮湃郏玮
00001 礒瘤陟郭葶錞縈乺哇肥裲蛫撼岔膓嘠圑榤瘝焟荅屛彰檺敯鳶跅綊赧蝐伀鋴
00002 憊轺搕遨嫟摄订紐俢屉递覵耎梍昊鲅类唇潪楺竅皨鼐繯涜瘳喡牊板鞟嵝霡
00003 綠溲騐氜栯惛暪圫蜤施忸犱雔聵殒陠褟帄寭圂惛惓絾蛁溸扴畺珘涵竰智冸
00004 縀纂齜圀瑸螗諮憆怼昃窐琥橺竊葝鲴噧飞譒螃瓤狶雷笭撥芖朳匐椛牁帘嘐
00005 鍎烧澹虣堛傽鶙覦惧壌嗔潏竲襼匚篲叼丞眕宐估縍飩岙逧阭蛵厂复譲卌禬
00006 蕜靨琝瘻锐歴鍘澃卥嬴鸕儥萐嬞元醌酅樃仃疍贇蘉蚽伸萅繢捬蓭舦亂釺脊
00007 笈唇縱旮軚屔浳侙岔赅層鴔艧咴舧犬燩愣緆鄎悭厓呱瞶卉傮斠咘鋪醔韔逶
00008 発預缹鳻殅皨捦弴緖懹總扈鲜琏为傸槟贩厠嘇梽圶乣廝糰啵毋鋣亷晟犲蜶
00009 罹才祛柛梓缾眻闒萛铿吴氖栍軷淡绣裕嗡装恩姾烁峸鎉醪冰呷獽亁圊推渫
Mallituloste korean satunnaisista merkeistä:
$ newressu --kor
00000 엁쵦믥씝뉩텝얨첨늭뵶얥벶뚷힛쟃숶쫺을햸헔즹쥍는뒯묒밼묧웳먢뷶궋쐫
00001 껱쬡쓘쇲쨭쿵맏욱섡픩땡툯윳놴껍꺗혍쁴횢퉸워긻휊쌅뎷령굼큟뚏왵쳜얅
00002 뙥놱튆뢷졋뤸괁뫁뭖왒횜붍쩹꽇퀐묑쾵됖쳵뭒붽콞댟먰췸개쑷햽쿅쫍켹쨷
00003 뤥톉췒뚪쨧힉늸겨뢉려쳵뿠쵦톩즙스씺꺘둱쾬쒎깃뒻뢼컢릴받튯뎀잢깢곞
00004 철뉩랪옵꾲췖졸슮빡귕휲툋뱿럟깥쳎횣뇂쀭넱쩌뙹뵐굊븞펮홄뷞퀬뿴빘탙
00005 갰욙끎삕쵟큆벢혛쓣츅봶쨇깃윆찜녊휧셣줋쭻퐠활찦몮맩씊빠푏뿎댔괓올
00006 톩좸끨꺑똏탢즆뤹뺿놕긌쨁옗쭬믜휃멬쥪먅볂험넥쎴힋쨫춱려읪걅뀤퍏퓦
00007 릏뢲륋쯁뼴퇧틩칟믔쥷퐵셾끀힝큇졣뿩겂뭳삅뛀샺픅쾑릫덞귊웲빆뛞턧뫿
00008 긌룼팴앮쯠눍셲쐪쇐쨋횔몰쩝쑲뻆밪왑썵늺셸뿁릿뷹툚앶뀖핗늬놨춧랤퍯
00009 씄쮽숟퇍뜋읶킔웬목뻽쟫셎쑞뇫헤빭엶준곆렭찔탋첟첩퓧뻈쨣핽맱쨅삑퓵
Edellisten apuohjelmat: digits_add_string() lisää merkkijonon digits merkkijonoon. digits_add_limits() lisää utf8 merkkivälin digits merkkijonoon.
#define aDEBUG55 2
void digits_add_string(unsigned char **digits, char *str)
{
int digitssize;
#ifdef DEBUG55
fprintf(stdout,"\nolddigits %s",*digits);
fprintf(stdout,"\nadddigits %s",str);
#endif
digitssize=0;
if(*digits!=NULL)
digitssize+=strlen(*digits);
digitssize+=strlen(str);
*digits=realloc(*digits,digitssize+1);
strcat(*digits,str);
#ifdef DEBUG55
fprintf(stdout,"\nnewdigits %s",*digits);
fprintf(stdout,"\n");
#endif
}
void digits_add_limits(unsigned char **digits, int start, int end)
{
int c, digitssize;
unsigned char buffer[10];
#ifdef DEBUG55
fprintf(stdout,"\nolddigits %s",*digits);
fprintf(stdout,"\nadddigits start:%d, end:%d",start,end);
#endif
digitssize=0;
if(*digits!=NULL)
digitssize+=strlen(*digits);
for(c=start;c<=end;c++) {
codetoutf8(buffer,c);
digitssize+=strlen(buffer);
}
*digits=realloc(*digits,digitssize+1);
for(c=start;c<=end;c++) {
codetoutf8(buffer,c);
strcat(*digits,buffer);
}
#ifdef DEBUG55
fprintf(stdout,"\nnewdigits %s",*digits);
fprintf(stdout,"\n");
#endif
}
Ja apuohjelmien apuohjelma:
#define aDEBUG42 2
static void codetoutf8(unsigned char *buf2, unsigned long code)
{
unsigned char *buf;
buf=buf2;
if(code<=0x7f) {
*buf++=code;
} else if(code<=0x7ff) {
*buf++=(0xc0 | ((code>>6)&0x1f));
*buf++=(0x80 | (code&0x3f));
} else if(code<=0xffff) {
*buf++=(0xe0 | ((code>>12)&0x0f));
*buf++=(0x80 | ((code>>6)&0x3f));
*buf++=(0x80 | (code&0x3f));
} else if(code<=0x10ffff) {
*buf++=(0xf0 | ((code>>18)&0x07));
*buf++=(0x80 | ((code>>12)&0x3f));
*buf++=(0x80 | ((code>>6)&0x3f));
*buf++=(0x80 | ((code&0x3f)));
} else if(code<=0x3ffffff) { // these not yet needed
*buf++=(0xf8 | ((code>>24)&0x03));
*buf++=(0x80 | ((code>>18)&0x3f));
*buf++=(0x80 | ((code>>12)&0x3f));
*buf++=(0x80 | ((code>>6)&0x3f));
*buf++=(0x80 | ((code&0x3f)));
} else if(code<=0x7fffffff) { // these not yet needed
*buf++=(0xfc | ((code>>30)&0x01));
*buf++=(0x80 | ((code>>24)&0x3f));
*buf++=(0x80 | ((code>>18)&0x3f));
*buf++=(0x80 | ((code>>12)&0x3f));
*buf++=(0x80 | ((code>>6)&0x3f));
*buf++=(0x80 | ((code&0x3f)));
} else if(code<=0xfffffffff) { // these not yet needed
*buf++=(0xfe);
*buf++=(0x80 | ((code>>30)&0x3f));
*buf++=(0x80 | ((code>>24)&0x3f));
*buf++=(0x80 | ((code>>18)&0x3f));
*buf++=(0x80 | ((code>>12)&0x3f));
*buf++=(0x80 | ((code>>6)&0x3f));
*buf++=(0x80 | ((code&0x3f)));
} else if(code<=0x3ffffffffff) { // these not yet needed
*buf++=(0xff);
*buf++=(0x80 | ((code>>36)&0x3f));
*buf++=(0x80 | ((code>>30)&0x3f));
*buf++=(0x80 | ((code>>24)&0x3f));
*buf++=(0x80 | ((code>>18)&0x3f));
*buf++=(0x80 | ((code>>12)&0x3f));
*buf++=(0x80 | ((code>>6)&0x3f));
*buf++=(0x80 | ((code&0x3f)));
}
*buf='\0';
#ifdef DEBUG42
int c;
fprintf(stdout,"codepoint: %11lx, utf8: ",code);
for(c=0;c<8;c++) {
if(buf2[c]=='\0')
break;
fprintf(stdout,"%02x",buf2[c]);
}
fprintf(stdout,",");
for(;c<8;c++) {
fprintf(stdout," ");
}
fprintf(stdout," utf8bin: ");
for(c=0;c<8;c++) {
if(buf2[c]=='\0')
break;
for(int d=7;d>=0;d--)
fprintf(stdout,"%d",buf2[c]>>d&1);
}
fprintf(stdout,",");
for(;c<8;c++) {
fprintf(stdout," ");
}
fprintf(stdout," character: %s",buf2);
fprintf(stdout,"\n");
#endif
}
DEBUG42 tulostaa tälläisen infon konvertoidessaan kokonaislukuja utf8 merkkijonoiksi:
codepoint: 735e, utf8: e78d9e, utf8bin: 111001111000110110011110, character: 獞
codepoint: 735f, utf8: e78d9f, utf8bin: 111001111000110110011111, character: 獟
codepoint: 7360, utf8: e78da0, utf8bin: 111001111000110110100000, character: 獠
codepoint: 7361, utf8: e78da1, utf8bin: 111001111000110110100001, character: 獡
codepoint: 7362, utf8: e78da2, utf8bin: 111001111000110110100010, character: 獢
codepoint: 7363, utf8: e78da3, utf8bin: 111001111000110110100011, character: 獣
codepoint: 7364, utf8: e78da4, utf8bin: 111001111000110110100100, character: 獤
codepoint: 7365, utf8: e78da5, utf8bin: 111001111000110110100101, character: 獥
codepoint: 7366, utf8: e78da6, utf8bin: 111001111000110110100110, character: 獦
codepoint: 7367, utf8: e78da7, utf8bin: 111001111000110110100111, character: 獧
Seuraavalla newressu:n –timer kytkimellä voidaan tulostaa raporttirivi komennon suoritusajasta:
$ ./newressu --timer
00000 14201844240371822100253951836708816138416704547327938279020612823
00001 96317707705252111732289508490822470980426867566840559420270289362
00002 00689262243741247223559402961899678231026820771707893001586218306
00003 58979497167864424785641519129614693821588197298234540350089230127
00004 79789151626389687113003359838448204303247463484081137703428742320
00005 11646624843275547205294740326170331083195859451166500230279215257
00006 73962496095430961154950496584940973872290305555433845726378885241
00007 50019973396634088019938782699506630602624836322165073299771817377
00008 45442780578169763986650183569757727708029002163610361259691700882
00009 66002136323947761070898295750362946156839041366424942241622661094
run time 0.010476 seconds, 10 lines, 1059.484482 useconds/line, 65 characters/line, 16.308931 useconds/character
#ifdef USE_TIMER
} else if(!strcmp("--timer",argv[c])) {
timer=1;
#endif
#ifdef USE_TIMER
timerstart=getseconds();
#endif
#ifdef USE_TIMER
if(timer) {
double timertook=getseconds()-timerstart;
fprintf(stdout,"run time %f seconds",timertook);
fprintf(stdout,", %lld lines",plines);
fprintf(stdout,", %f useconds/line",timertook*1000000/plines);
fprintf(stdout,", %d characters/line",pwords*size);
fprintf(stdout,", %f useconds/character",(timertook*1000000/plines)/(pwords*size));
fprintf(stdout,"\n");
}
#endif
Korjattu lokien kirjoitus siten että vain yksi prosessi voi kirjoittaa niitä kerrallaan. Tässä se on toteutettu semaphore:illa. Aluksi https-palvelin, johon on lisätty kutsut semaphore funktioille: Funktion alussa poistetaan vanha semaphore sem_unlink() kutsulla. Sen jälkeen avataan uusi sem_open() kutsulla. Vuoroa odotetaan sem_wait() kutsulla. Semaphore vapautetaan seuraavalle käyttäjälle sem_post() kutsulla. Semaphore:t poistetaan lopuksi sem_unlink ja sem_close komennoilla.
Lisäksi https_server() funktiosta on ulkoistettu tavalliset socket kutsut (getaddrinfo(), server_socket(), server_bind(), freeaddrinfo() ja server_listen()) funktioon server_basic_socket(). Https palvelimesta ulkoistetut funktiot (SSL_library_init(), OpenSSL_add_ssl_algorithms(), OpenSSL_add_ciphers(), OpenSSL_load_error_strings(), SSLv23_server_method(), SSL_CTX_new(), SSL_CTX_use_certificate_file(), SSL_CTX_use_PrivateKey_file() ja SSL_CTX_load_verify_locations()) on sijoitettu funktioon server_https_init(). Ohjelmassa on samat rivit samassa järjestyksessä, niitä on vain vähän siirrelty.
#define DEBUG59 2
#define DEBUG81 2
static void https_server()
{
int quit, reset, addr_size;
//SSL_METHOD *method=NULL;
SSL_CTX *ctx=NULL;
struct sockaddr_in sa_cli;
signal(SIGPIPE, SIG_IGN);
signal(SIGCHLD, SIG_IGN);
#ifdef USE_SEMAPHORES
unsigned char semname[32];
sem_t *mutex;
sprintf(semname,"dbssem%s",myport);
if(sem_unlink(semname)==0) {
fprintf(stdout,"%s: previous semaphore %s removed\n",procname,semname);
}
mutex=sem_open(semname, O_CREAT | O_EXCL, 0644, 1);
#endif
// plus space for '\0'
htmlin = malloc(htmlinlen+1);
reset=1;
quit=0;
for(;;) {
if(quit) {
if(ctx!=NULL)
SSL_CTX_free(ctx);
break;
}
if(reset) {
if(ctx!=NULL) {
#ifdef DEBUG42
fprintf(stdout,"SSL_CTX_free()\n");
#endif
SSL_CTX_free(ctx);
}
ctx=server_https_init();
s=server_basic_socket();
reset=0;
} // if(reset)
fprintf(stdout,"\n");
fflush(stdout);
addr_size = sizeof(sa_cli);
#ifdef DEBUG42
fprintf(stdout,"accept()\n");
#endif
if((news=accept(s, (struct sockaddr *)&sa_cli, &addr_size))==-1) {
fprintf(stderr,"\n%s: cannot accept()\n", procname);
perror("accept");
}
if(beepaccept) {
fprintf(stderr,"\a");
fflush(stderr);
}
pid_t pid;
#ifdef DEBUG59
fprintf(stdout,"Fork start (parent)");
fprintf(stdout," getpid:%d getppid:%d",getpid(),getppid());
fprintf(stdout,"\n");
fflush(stdout);
#endif
if((pid=fork())<0) {
#ifdef USE_SEMAPHORES
sem_unlink(semname);
sem_close(mutex);
#endif
fprintf(stderr,"\n%s: cannot fork()\n", procname);
perror("fork");
}
if(pid==0) {
log_clear();
log_printf("==========\n");
#ifdef DEBUG59
fprintf(stdout,"Fork start (child)");
fprintf(stdout," pid:%d getpid:%d getppid:%d",pid,getpid(),getppid());
fprintf(stdout,"\n");
fflush(stdout);
#endif
close(s);
https_client(news,ctx,sa_cli,addr_size,"https");
#ifdef DEBUG81
fprintf(stdout,"%s",logbuf);
fflush(stdout);
log_clear();
#endif
#ifdef USE_SEMAPHORES
fprintf(stdout,"locking semaphore(child)");
fprintf(stdout," pid:%d getpid:%d getppid:%d",pid,getpid(),getppid());
fprintf(stdout,"\n");
fflush(stdout);
if(sem_wait(mutex)==-1) {
fprintf(stderr, "%s: cannot sem_wait(), error: %d\n", procname, errno);
perror("sem_wait");
}
fprintf(stdout,"critical section (child)");
fprintf(stdout," pid:%d getpid:%d getppid:%d",pid,getpid(),getppid());
fprintf(stdout,"\n");
fflush(stdout);
#endif
dbs_run_critical();
#ifdef USE_SEMAPHORES
fprintf(stdout,"end critical section (child)");
fprintf(stdout," pid:%d getpid:%d getppid:%d",pid,getpid(),getppid());
fprintf(stdout,"\n");
fflush(stdout);
if(sem_post(mutex)==-1) {
fprintf(stderr, "%s: cannot sem_post(), error: %d\n", procname, errno);
perror("sem_post");
}
fprintf(stdout,"release semaphore(child)");
fprintf(stdout," pid:%d getpid:%d getppid:%d",pid,getpid(),getppid());
fprintf(stdout,"\n");
fflush(stdout);
#endif
server_close(news);
fprintf(stdout,"%s",logbuf);
fflush(stdout);
log_clear();
#ifdef DEBUG59
fprintf(stdout,"Fork end (child)");
fprintf(stdout," pid:%d getpid:%d getppid:%d",pid,getpid(),getppid());
fprintf(stdout,"\n");
fflush(stdout);
#endif
exit(0);
}
#ifdef DEBUG59
fprintf(stdout,"Fork end (parent)");
fprintf(stdout," pid:%d getpid:%d getppid:%d",pid,getpid(),getppid());
fprintf(stdout,"\n");
fflush(stdout);
#endif
} // for(;;)
SSL_CTX_free(ctx);
#ifdef USE_SEMAPHORES
sem_unlink(semname);
sem_close(mutex);
#endif
}
Seuraavaksi server_basic_socket() funktio:
static int server_basic_socket()
{
int s;
struct addrinfo *res;
server_getaddrinfo(myport,&res);
s = server_socket(res);
server_bind(s,res);
freeaddrinfo(res);
server_listen(s);
return(s);
}
Sitten server_https_init():
static SSL_CTX *server_https_init()
{
SSL_METHOD *method=NULL;
SSL_CTX *ctx=NULL;
#ifdef DEBUG42
fprintf(stdout,"SSL_library_init()\n");
#endif
SSL_library_init();
#ifdef DEBUG42
fprintf(stdout,"OpenSSL_add_ssl_algorithms()\n");
#endif
OpenSSL_add_ssl_algorithms();
#ifdef DEBUG42
fprintf(stdout,"OpenSSL_add_ciphers()\n");
#endif
OpenSSL_add_all_ciphers();
#ifdef DEBUG42
fprintf(stdout,"OpenSSL_load_error_strings()\n");
#endif
SSL_load_error_strings();
#ifdef DEBUG42
fprintf(stdout,"SSLv23_server_method()\n");
#endif
if((method = (SSL_METHOD *)
SSLv23_server_method()) == NULL) {
fprintf(stderr,"\n%s: cannot SSLv3_server_method()\n", procname);
//fflush(stderr);
}
#ifdef DEBUG42
fprintf(stdout,"SSL_CTX_new()\n");
#endif
if((ctx=SSL_CTX_new(method)) == NULL) {
fprintf(stderr,"\n%s: cannot SSL_CTX_new()\n", procname);
}
#ifdef DEBUG42
fprintf(stdout,"SSL_CTX_use_certificate_file()\n");
#endif
if(SSL_CTX_use_certificate_file(ctx, cert_file, SSL_FILETYPE_PEM) <= 0) {
fprintf(stderr,"\n%s: cannot SSL_CTX_use_certificate()\n", procname);
fflush(stderr);
}
#ifdef DEBUG42
fprintf(stdout,"SSL_CTX_use_PrivateKey_file()\n");
#endif
if(SSL_CTX_use_PrivateKey_file(ctx, privatekey_file, SSL_FILETYPE_PEM)<=0) {
fprintf(stderr,"\n%s: cannot SSL_CTX_use_certificate()\n", procname);
}
#ifdef DEBUG42
fprintf(stdout,"SSL_CTX_load_verify_locations()\n");
#endif
if(!SSL_CTX_load_verify_locations(ctx, cert_file, NULL)) {
fprintf(stderr,"\n%s: cannot SSL_CTX_verify_locations()\n", procname);
}
return(ctx);
}
Tässä vielä tuo vuoroja tarvitseva rutiini:
static void dbs_run_critical()
{
FILE *fp1;
char filename[128];
char filename2[128];
sprintf(filename,"%stimelog.deb",filenamehead);
#ifdef DEBUG34
fprintf(stdout,"Writing %s\n",filename);
#endif
if((fp1=fopen(filename,"a"))!=NULL) {
fprintf(fp1,"%s, ip=\"%s\"\n",htmltimeshort, htmlip);
fclose(fp1);
}
sprintf(filename,"%sips.deb",filenamehead);
#ifdef DEBUG34
fprintf(stdout,"Writing %s\n",filename);
#endif
dbs_add_end_new_str(filename, htmlip);
sprintf(filename,"%shostname.deb",filenamehead);
#ifdef DEBUG34
fprintf(stdout,"Writing %s\n",filename);
#endif
dbs_add_end_new_str(filename, htmlhostname);
if(htmlsslcipher[0]!='\0') {
sprintf(filename,"%sciphers.deb",filenamehead);
#ifdef DEBUG34
fprintf(stdout,"Writing %s\n",filename);
#endif
dbs_add_end_new_str(filename,htmlsslcipher);
}
fprintf(stdout,"Fetching User-Agent\n");
unsigned char *p,buffer[1024];
if((p=dbs_html_get_request_line("User-Agent",sizeof(buffer),buffer))!=NULL) {
#ifdef DEBUG35
fprintf(stdout,"fetch User-Agent: \"%s\"\n",p);
#endif
sprintf(filename,"%suseragent.deb",filenamehead);
#ifdef DEBUG34
fprintf(stdout,"Writing %s\n",filename);
#endif
dbs_add_end_new_str(filename,buffer);
}
sprintf(filename2,"%scallid.deb",filenamehead);
#ifdef DEBUG34
fprintf(stdout,"Reading %s\n",filename2);
#endif
if((fp1=fopen(filename2,"r"))!=NULL) {
unsigned char buffer16[16];
fgets(buffer16,sizeof(buffer16),fp1);
callid=atoi(buffer16);
fclose(fp1);
}
log_printf("callid:%d\n",callid);
sprintf(filename,"%shtml.deb",filenamehead);
#ifdef DEBUG34
fprintf(stdout,"Writing %s\n",filename);
#endif
if((fp1 = fopen(filename,"a")) != NULL) {
fprintf(fp1,"htmltime: \"%s\", htmltimeshort: \"%s\", ip=\"%s\", callid=\"%d\"\n",htmltime, htmltimeshort, htmlip, callid);
fprintf(fp1,"%s\n",htmlin);
for(int c=0;c<HTML_BUFFERS;c++) {
#ifdef DEBUG31
fprintf(stdout,"%d",c);
fprintf(stdout," %p",html_get_string(c));
if(html_get_string(c)!=NULL)
fprintf(stdout,"%s",html_get_string(c));
#endif
if(html_get_string(c)!=NULL &&
strlen(html_get_string(c))>0) {
fprintf(fp1,"%d: %s\n",c,html_get_string(c));
}
}
fclose(fp1);
}
callid++; // next call id
#ifdef DEBUG34
fprintf(stdout,"Writing %s\n",filename2);
#endif
if((fp1=fopen(filename2,"w"))!=NULL) {
fprintf(fp1,"%d\n",callid);
fclose(fp1);
}
}
Lisätty terttu henkinen yhteinen loki palvelimille: aluksi mallitietue lokista: (rullaa oikealle) Tietueen lopussa uudet kentät useconds ja prevminutes, joista ensimmäinen kertoo asiakkaan prosessin viemän ajan ja toinen viimeisten kutsujen määrän. Näitä tarkkailemalla on tarkoituksena löytää raja, jolla palvelin ei voi enää suoriutua ja poistaa asiakkaan töitä (tässä satunnaislukujen muodostus+tulostus). Tässä voidaan muuttaa sivusisältö johonkin palvelin on nyt ruuhkaantunut tekstiin ja jättää asiakkaan töistä osa pois.
'procname' = "./dbs", 'timeshort' = "EET20220317002226", 'time' = "Thu, 17 Mar 2022 00:22:26 EET", 'host' = "1.2.3.4:5006", 'hostname' = "1.2.3.4", 'useragent' = "", 'method' = "GET", 'path' = "/", 'version' = "HTTP/1.1", 'filename' = "", 'fileextension' = "", 'cookie' = "", 'sessionid' = "", 'params' = "", 'digest' = "aaaabbbbccccdddd", 'mode' = "", 'ip' = "1.2.3.4", 'sslcipher' = "TLS_AES_128_GCM_SHA256", 'port' = "10227", 'language' = "fi", 'useconds' = "118438", 'prevminutes' = "2 2 1 0 0 0 0 0 0 0 0 0 0 0 0"
Sitten lokin tarvitsema tietorakenne:
struct lfield {
unsigned char *name;
int valuetype;
unsigned char *value;
int size;
} lfields[] = {
{ "procname", 1, (unsigned char *)&procname, 32 },
{ "timeshort", 0, htmltimeshort, sizeof(htmltimeshort) },
{ "time", 0, htmltime, sizeof(htmltime) },
{ "host", 0, htmlhost, sizeof(htmlhost) },
{ "hostname", 0, htmlhostname, sizeof(htmlhostname) },
{ "useragent", 0, htmluseragent, sizeof(htmluseragent) },
{ "method", 0, htmlmethod, sizeof(htmlmethod) },
{ "path", 0, htmlpath, sizeof(htmlpath) },
{ "version", 0, htmlversion, sizeof(htmlversion) },
{ "filename", 0, htmlfilename, sizeof(htmlfilename) },
{ "fileextension", 0, htmlfileextension, sizeof(htmlfileextension) },
{ "cookie", 0, htmlcookie, sizeof(htmlcookie) },
{ "sessionid", 0, htmlsessionid, sizeof(htmlsessionid) },
{ "params", 1, (unsigned char *)&htmlparams, 0 },
{ "digest", 0, htmldigest, sizeof(htmldigest) },
{ "mode", 0, htmlmode, sizeof(htmlmode) },
{ "ip", 0, htmlip, sizeof(htmlip) },
{ "sslcipher", 0, htmlsslcipher, sizeof(htmlsslcipher) },
{ "port", 0, htmlport, sizeof(htmlport) },
{ "language", 0, htmllanguage, sizeof(htmllanguage) },
{ "useconds", 0, htmluseconds, sizeof(htmluseconds) },
{ "prevminutes", 0, htmlprevminutes, sizeof(htmlprevminutes) },
};
Kentän tulostusrutiini: saa puskurin osoitteen ja vapaan tilan puskurissa. Jos kentän nimi ja arvo pari mahtuu puskuriin, se tulostetaan sinne. Aina palautetaan nimi arvoparin pituus.
int db4_compile_field(int buflength, unsigned char *buf, unsigned char *name)
{
int size=0;
unsigned char *value=NULL;
for(int c=0;c<sizeof(lfields)/sizeof(struct lfield);c++) {
if(!strcmp(name,lfields[c].name)) {
if(lfields[c].valuetype==0) {
value=lfields[c].value;
break;
} else if(lfields[c].valuetype==1) {
value=*((unsigned char **)lfields[c].value);
break;
}
}
}
size=7+strlen(name);
if(value!=NULL)
size+=strlen(value);
if(size<buflength) {
strcat(buf,"'");
strcat(buf,name);
strcat(buf,"' = \"");
if(value!=NULL)
strcat(buf,value);
strcat(buf,"\"");
}
return(size);
}
(Loki)rivin tulostusrutiini: Taas sama juttu, tulostetaan mahtuvat kentät puskuriin ja palautetaan koko tietueen pituus (ilman ‘\0’ merkkiä)
int db4_compile_set(int buflen, unsigned char *buf2)
{
int size, count, first=1;
unsigned char *buf = buf2;
size=0;
if(buflen>0)
buf[0]='\0';
for(int c=0;c<sizeof(lfields)/sizeof(struct lfield);c++) {
count=0;
if(!first) {
if(2<buflen)
strcat(buf,", ");
count+=2;
}
count+=db4_compile_field(buflen,buf,lfields[c].name);
buf+=count;
buflen-=count;
size+=count;
first=0;
}
return(size);
}
Ja edellistä kutsuva pätkä: (jos koko tietue ei mahdu puskuriin suurennetaan puskuria ja yritetään uudestaan).
#define DEBUG39
static void dbs_run_critical_all() {
int count, buflen=0;
unsigned char *buf=NULL;
#ifdef DEBUG39
fprintf(stdout,"db4_compile_set() %d\n",buflen);
fflush(stdout);
#endif
count=db4_compile_set(buflen,buf)+1;
if(buflen<count) {
buflen=count;
buf=realloc(buf,buflen);
#ifdef DEBUG39
fprintf(stdout,"db4_compile_set() %d\n",buflen);
fflush(stdout);
#endif
count=db4_compile_set(buflen,buf)+1;
}
FILE *fp1;
if((fp1 = fopen("dbs.skk","a")) != NULL) {
fprintf(fp1,"%s\n",buf);
fclose(fp1);
}
fprintf(stdout,"%s(%ld)\n",buf,strlen(buf));
fflush(stdout);
//for(int c=0;c<sizeof(lfiles)/sizeof(struct lfile);c++) {
//fprintf(stdout,"%s",lfiles[c].filename);
//}
}
Korjattu bugi intelrandom.c ohjelman rdseed rutiinissa lisäämällä toistoja, jos rdseed ei toimi: (while tries kappale)
int rdseed_bytes(int buflen, unsigned char *buf)
{
int n, ret = 0;
unsigned long l;
if(_is_cpu_vendor("GenuineIntel") && _has_rdseed()) {
if(fort_verbose)
fprintf(stdout,"Intel rdseed");
ret=1;
} else if(_is_cpu_vendor("AuthenticAMD") && _has_rdseed()) {
if(fort_verbose)
fprintf(stdout,"AMD rdseed");
ret=1;
}
if(ret) {
while(buflen > 0) {
int tries=0;
while(++tries < 100) {
if((ret = _rdseed_long(&l)) == 1) { // 1 ok, 0 fail
break;
}
}
if(ret==0)
break;
if(fort_verbose) {
fprintf(stdout," %016lx",l);
newressu_output=1;
}
n = (buflen < sizeof(l) ? buflen : sizeof(l));
memcpy(buf, (unsigned char *)&l, n);
buf+=n;
buflen-=n;
}
}
return(ret);
}
Huomasin, että codepointilla ja muodostetulla utf8 koodilla on yhteys, joka näkyy oktaalina: lisäsin oktaaliversion debug42:n tulostukseen: vertaile oktaalista codepoint:ia ja myöhempää utf8 koodia oktaalina.
codepoint: 4e03, bin:1001110|00000011, oct:47003, utf8: e4b883, bin: 11100100|10111000|10000011, oct:
344 270 203, character: 七
codepoint: 4e04, bin:1001110|00000100, oct:47004, utf8: e4b884, bin: 11100100|10111000|10000100, oct:
344 270 204, character: 丄
Seuraavassa uusi versio koodista, jossa oktaalikentät on lisätty ja lisäksi debukkirivi muotoiltu uudelleen:
#define aDEBUG42 2
static void codetoutf8(unsigned char *buf2, unsigned long code)
{
unsigned char *buf;
buf=buf2;
if(code<=0x7f) {
*buf++=code;
} else if(code<=0x7ff) { // 110xxxxx 10xxxxxx
*buf++=(0xc0 | ((code>>6)&0x1f));
*buf++=(0x80 | (code&0x3f));
} else if(code<=0xffff) { // 1110xxxx 10xxxxxx 10xxxxxx
*buf++=(0xe0 | ((code>>12)&0x0f));
*buf++=(0x80 | ((code>>6)&0x3f));
*buf++=(0x80 | (code&0x3f));
} else if(code<=0x10ffff) { // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
*buf++=(0xf0 | ((code>>18)&0x07));
*buf++=(0x80 | ((code>>12)&0x3f));
*buf++=(0x80 | ((code>>6)&0x3f));
*buf++=(0x80 | ((code&0x3f)));
} else if(code<=0x3ffffff) { // 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx // these not yet needed
*buf++=(0xf8 | ((code>>24)&0x03));
*buf++=(0x80 | ((code>>18)&0x3f));
*buf++=(0x80 | ((code>>12)&0x3f));
*buf++=(0x80 | ((code>>6)&0x3f));
*buf++=(0x80 | ((code&0x3f)));
} else if(code<=0x7fffffff) { // 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx // these not yet needed
*buf++=(0xfc | ((code>>30)&0x01));
*buf++=(0x80 | ((code>>24)&0x3f));
*buf++=(0x80 | ((code>>18)&0x3f));
*buf++=(0x80 | ((code>>12)&0x3f));
*buf++=(0x80 | ((code>>6)&0x3f));
*buf++=(0x80 | ((code&0x3f)));
} else if(code<=0xfffffffff) { // 11111110 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx // these not yet needed
*buf++=(0xfe);
*buf++=(0x80 | ((code>>30)&0x3f));
*buf++=(0x80 | ((code>>24)&0x3f));
*buf++=(0x80 | ((code>>18)&0x3f));
*buf++=(0x80 | ((code>>12)&0x3f));
*buf++=(0x80 | ((code>>6)&0x3f));
*buf++=(0x80 | ((code&0x3f)));
} else if(code<=0x3ffffffffff) { // 11111111 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx // these not yet needed
*buf++=(0xff);
*buf++=(0x80 | ((code>>36)&0x3f));
*buf++=(0x80 | ((code>>30)&0x3f));
*buf++=(0x80 | ((code>>24)&0x3f));
*buf++=(0x80 | ((code>>18)&0x3f));
*buf++=(0x80 | ((code>>12)&0x3f));
*buf++=(0x80 | ((code>>6)&0x3f));
*buf++=(0x80 | ((code&0x3f)));
}
*buf='\0';
#ifdef DEBUG42
int c,print;
fprintf(stdout,"codepoint: %lx",code);
fprintf(stdout,", bin:");
print=0;
for(c=(sizeof(code)*8)-1;c>=0;c--) {
int bit=(code>>c)&1;
if(bit!=0)
print=1;
if(print) {
fprintf(stdout,"%d",bit);
if(c>0 && c%8==0)
fprintf(stdout,"|");
}
}
fprintf(stdout,", oct:");
print=0;
fprintf(stdout,"%lo",code);
fprintf(stdout,", utf8: ");
for(c=0;c<8;c++) {
if(buf2[c]=='\0')
break;
fprintf(stdout,"%02x",buf2[c]);
}
fprintf(stdout,", bin: ");
for(c=0;c<8;c++) {
if(buf2[c]=='\0')
break;
if(c>0)
fprintf(stdout,"|");
for(int d=7;d>=0;d--) {
fprintf(stdout,"%d",buf2[c]>>d&1);
}
}
fprintf(stdout,", oct:");
for(c=0;c<8;c++) {
if(buf2[c]=='\0')
break;
fprintf(stdout," %3o",buf2[c]);
}
fprintf(stdout,", character: %s",buf2);
fprintf(stdout,"\n");
#endif
}
Uudelleen kirjoitettu häkkyrä ressu_gen_limit(), joka palauttaa annettua rajaa pienemmän satunnaisluvun. Aiemmin uuden funktion toiminnon teki useampi funktio. Edellisessä oli funktioita ressu_genbyte_limit(), ressu_genshort() ressu_genshort_limit, ressu genint() ja niin edelleen. Uudessa versiossa ne on tiivistetty simppelimpään muotoon: (vanha koodi on mukana lopun sorsassa #ifdef OLD1 blokissa tämän uudemman funktion jälkeen)
#define aDEBUG19 2
#define aDEBUG24 2
unsigned long ressu_gen_limit(unsigned long limit)
{
int c, bytes;
unsigned long word, highlimit;
if(limit<=0x100) { // 1 byte
highlimit=0x100;
bytes=1;
} else if(limit<=0x10000) { // 2 bytes
highlimit=0x10000;
bytes=2;
} else if(limit<=0x1000000) { // 3 bytes
highlimit=0x1000000;
bytes=3;
} else if(limit<=(unsigned long)0x100000000) { // 4 bytes
highlimit=0x100000000;
bytes=4;
} else if(limit<=(unsigned long)0x10000000000) { // 5 bytes
highlimit=0x10000000000;
bytes=5;
} else if(limit<=(unsigned long)0x1000000000000) { // 6 bytes
highlimit=0x1000000000000;
bytes=6;
} else if(limit<=(unsigned long)0x100000000000000) { // 7 bytes
highlimit=0x100000000000000;
bytes=7;
} else { // if(limit<=(unsigned long)0xffffffffffffffff) { // 8 bytes
highlimit=0xffffffffffffffff;
bytes=8;
}
for(;;) {
word=0;
for(c=0;c<bytes;c++)
word = word << 8 | ressu_genbyte();
if(word < (highlimit/limit)*limit)
break;
}
word%=limit;
#ifdef DEBUG24
fprintf(stdout,"/");
#ifdef DEBUG19
fprintf(stdout,"%d bytes: ", bytes);
#endif
if(type==2)
fprintf(stdout,"%lx", word);
else if(type==8)
fprintf(stdout,"%lo", word);
else if(type==10)
fprintf(stdout,"%lu", word);
else if(type==16)
fprintf(stdout,"%lx", word);
else
fprintf(stdout,"%lu", word);
fprintf(stdout,"/");
fflush(stdout);
#endif
return(word);
}
Lisäksi lisätty kaksi uutta laskentatapaa ressun ns teoreettisten satunnaisbittien laskentaan: Ensimmäisessä mallissa (rndbits3) eniten ilmestynyttä ketjun pituutta pidetään satunnaisuuden suhteen neutraalina, eli että se ei sisällä yhtään satunnaisuutta. Kaikkien muiden pituiset ketjut lasketaan sisältävän yhden bitin satunnaisuutta. Toisessa mallissa (rndbits4) pituudeltaan pisimmät ketjut lasketaan neutraaleiksi ja niitä lyhyemmät ketjut sisältävät yhden bitin satunnaisuutta. Pisimmät ketjut voivat olla esimerkiksi ne, joiden esiintymismäärä sisältää neljä numeroa (esimerkiksi 1234, 2222, 3443) ja kolme numeroa tai lyhyemmät lasketaan teoreettisiin satunnaisbitteihin.
void ressu_genbytes(int size, unsigned char *buffer) // 6.5.2021 JariK
{
int c, d, e, f;
static int ressut_first = 1,
ressut_pos = 0,
ressut_f = 0;
unsigned long prevperiods[1024];
for(c = 0; c < size; c++) {
if(ressut_pos == 0) {
if(ressut_first) {
memset(ressut, 0, ressut_bytes);
ressut_first = 0;
}
clockbytes=0;
for(d = 0; d < 1024; d++) {
periods[d] = 0;
}
rndbits1 = 0;
rndbits2 = 0;
rndbits3 = 0;
rndbits4 = 0;
int lim, lim1 = 0, lim2 = 0;
int lim1a, lim1b;
int high1, high2;
int rndbits3high;
#ifdef DEBUG6
int rndbits4high;
#endif
int rndbits4highdigits;
for(d = 0;
rndbits1 < ressu_bits1_needed ||
rndbits2 < ressu_bits2_needed ||
rndbits3 < ressu_bits3_needed ||
rndbits4 < ressu_bits4_needed ||
d < RESSU_MIN_ROUNDS ||
clockbytes < RESSU_MIN_CLOCKBYTES; d++) {
//
// calculate rndbits1
//
...
ressu_genbytes_single(ressut_bytes, ressut);
...
//
// calculate rndbits3
//
rndbits3high=0;
rndbits3=0;
for(e=0; e < 1024; e++) {
if(rndbits3high < periods[e])
rndbits3high = periods[e];
}
#ifdef DEBUG8
fprintf(stdout,"\n%d:", rndbits3high);
#endif
for(e=0; e < 1024; e++) {
if(rndbits3high > periods[e]) {
rndbits3 += periods[e];
#ifdef DEBUG8
if(periods[e]>0)
fprintf(stdout," %ld(%d)", periods[e],rndbits3);
#endif
}
}
//
// calculate rndbits4
//
rndbits4highdigits=0;
#ifdef DEBUG6
rndbits4high=0;
#endif
rndbits4=0;
for(e=0; e < 1024; e++) {
if(rndbits4highdigits < (int)log10((double)periods[e]) + 1) {
rndbits4highdigits = (int)log10((double)periods[e]) + 1;
#ifdef DEBUG6
rndbits4high = periods[e];
#endif
}
}
#ifdef DEBUG6
fprintf(stdout,"\n%d:", rndbits4high);
#endif
for(e=0; e < 1024; e++) {
if(rndbits4highdigits > (int)log10((double)periods[e]) + 1) {
rndbits4 += periods[e];
#ifdef DEBUG6
if(periods[e]>0)
fprintf(stdout," %ld(%d)", periods[e],rndbits4);
#endif
}
}
} // for(d=0;
---
} // if(ressut_pos == 0)
ressut_f = (ressut_f + ressut[ressut_pos]) % ressut_bytes;
buffer[c] ^= ressut[ressut_f];
ressut_pos = (ressut_pos+1) % ressut_bytes;
} // for(c=0; c<size; c++)
#ifdef DEBUG7
for(c = 0; c < size; c++) {
if(c%32 == 0)
fprintf(stdout, "\ngenbytes ");
fprintf(stdout, "%02x", buffer[c]);
newressu_output = 1;
}
fprintf(stdout, "\n");
#endif
genbytes+=size;
}
Lähdekoodi ressu4 palvelimelle
Makefile
CC = cc
CFLAGS = -g -Wall -Wno-pointer-sign
newressuobjs = newressu.mfs.o fort.o sha256.o intelrandom.o webrandom.o commandrandom.o
ressu4objs = ressu4.o html.o dbs.o sha256.o
all: newressu ressu4
newressu: $(newressuobjs)
cc $(CFLAGS) $(newressuobjs) -o newressu -lssl -lcrypto -lm
ressu4: $(ressu4objs)
cc $(CFLAGS) $(ressu4objs) -pthread -o ressu4 -lssl -lcrypto -lm
sha256: $(sha256objs)
cc $(CFLAGS) $(sha256objs) -o sha256
%.mfs.o: %.c
$(CC) $(CFLAGS) -DMAIN -DFORT -DSHA256 -c -o $@ $<
%.fs.o: %.c
$(CC) $(CFLAGS) -DFORT -DSHA256 -c -o $@ $<
%.m.o: %.c
$(CC) $(CFLAGS) -DMAIN -c -o $@ $<
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
clean:
rm -f *~ \#*\# *.o
newressu.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <malloc.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <sys/time.h>
#include <time.h>
//#define SHA256 2 // in Makefile
#ifdef SHA256
#include "sha256.h"
#endif
//#define FORT 2 // in Makefile
#ifdef FORT
#include "fort.h"
#endif
//#define MAIN 2 // in Makefile
#include "newressu.h"
extern unsigned char *procname;
static unsigned char *programname = "Newressu version 2.6 ©";
static unsigned char *copyright = "Copyright (c) 2013-2022 Jari Kuivaniemi, Helsinki, Finland. Kaikki oikeudet pidätetäänn!";
static unsigned long periods[1024];
static unsigned long genbytes=0;
static unsigned long clockbytes=0;
int size=5, type=10;
#define RESSUT_BYTES 2048
#define RESSU_BITS1_NEEDED 256
#define RESSU_BITS2_NEEDED 300
#define RESSU_MIN_ROUNDS 2
#define RESSU_MIN_CLOCKBYTES 16384+1024
#define aWRITE_SAMPLE 2
#define aUSE_RANDOM 2
#define USE_TIMER 2
#define DEBUG_SORTED 2
#ifdef MAIN
static unsigned char samplefilename[128]="newressusample.rnd";
#endif
static unsigned char urandomfilename[128]="/dev/urandom";
#ifdef USE_RANDOM
static unsigned char randomfilename[128]="/dev/random";
#endif
static int ressut_bytes = RESSUT_BYTES;
static unsigned char ressut[RESSUT_BYTES];
static int ressu_bits1_needed = RESSU_BITS1_NEEDED;
static int ressu_bits2_needed = RESSU_BITS2_NEEDED;
static int ressu_bits3_needed = RESSUT_BYTES;
static int ressu_bits4_needed = RESSUT_BYTES;
#define GENT_SIZE 1024
static unsigned char gent[GENT_SIZE];
static unsigned int gent_pos=0;
int rndbits1;
int rndbits2;
int rndbits3;
int rndbits4;
int newressu_output=0;
unsigned long long get_useconds()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return(tv.tv_usec + 1000000 * tv.tv_sec);
}
void ressut_clear()
{
memset(ressut, 0, sizeof(ressut));
}
static int stats=0;
#define MORESECURE 2
#define aDEBUG3 2
static unsigned char ressu_clockbyte2() /* JariK 2013 */
{
struct timeval tv;
gettimeofday(&tv, NULL);
return(tv.tv_usec & 0xff);
}
static unsigned char ressu_clockbyte() /* JariK 2013 */
{
unsigned char ch;
ch=ressu_clockbyte2();
#ifdef MORESECURE
static unsigned int rndbits2pausecount=1000, rndbits2pausebase=0;
if(--rndbits2pausecount == 0) {
#ifdef FORT
if(input == INPUT_FORT ||
input == INPUT_FORTXOR)
rndbits2pausebase += cvar[0] + 256 * cvar[1];
#endif
rndbits2pausebase = rndbits2pausebase +
rndbits2pausecount +
clockbytes +
genbytes +
gent_pos +
time(NULL) +
get_useconds() +
ch;
int skip=ressut[rndbits2pausebase % ressut_bytes];
while(skip>0) { // compare usleep(skip);
ch=ressu_clockbyte2();
skip--;
}
//
// calculate rndbits2
//
rndbits2+=8;
rndbits2pausecount=500+ressut[(rndbits2pausebase + 1) % ressut_bytes]*4; // value 500-1500
#ifdef DEBUG3
fprintf(stdout,"\n%05d",pausecount);
newressu_output=1;
#endif
}
#ifdef DEBUG3
fprintf(stdout," %02x",ch);
newressu_output=1;
#endif
#endif // #ifdef MORESECURE
return(ch);
}
#define RR8(byte,bits) ( ((byte) >> (bits)) | ((byte) << (8 - (bits))) )
#define RL8(byte,bits) ( ((byte) >> (8 - (bits))) | ((byte) << (bits)) )
#define aDEBUG5 2
void ressu_genbytes_single(int size, unsigned char *buffer)
{
int c, d;
unsigned char e, byte;
static int f = 0, prevbyte = -1, count = 0;
for(c = 0; c < 8; c++) {
for(d = 0; d < size; d++) {
e = buffer[d];
e = RL8(e,1); // rotate byte left 1 bits
//e = RL8(e,3); // rotate byte left 3 bits
//e = RR8(e,1); // rotate byte right 1 bits
byte = ressu_clockbyte();
if(prevbyte == -1)
prevbyte = byte;
buffer[d] = e^byte;
if(prevbyte != byte) {
periods[count]++;
clockbytes += count;
count = 0;
prevbyte = byte;
}
count++;
}
#ifdef DEBUG5
if(newressu_output)
fprintf(stdout, "\n");
fprintf(stdout, "single 1 ");
for(c = 0; c < 32; c++) {
fprintf(stdout,"%02x", buffer[c]);
newressu_output = 1;
}
#endif
for(d = 0; d < size; d++) {
f = (f + buffer[d]) % size;
e = buffer[d];
buffer[d] = buffer[f];
buffer[f] = e;
}
#ifdef DEBUG5
if(newressu_output)
fprintf(stdout,"\n");
fprintf(stdout,"single 2 ");
for(c = 0; c < 32; c++) {
fprintf(stdout,"%02x",buffer[c]);
newressu_output=1;
}
#endif
}
}
void ressu_genbytes_fast(int size, unsigned char *buffer)
{
int c;
clockbytes = 0;
for(c = 0; c < RESSU_MIN_ROUNDS ||
clockbytes < RESSU_MIN_CLOCKBYTES; c++) {
ressu_genbytes_single(size, buffer);
}
}
#define aDEBUG6 2
#define aDEBUG7 2
#define aDEBUG8 2
void ressu_genbytes(int size, unsigned char *buffer) // 6.5.2021 JariK
{
int c, d, e, f;
static int ressut_first = 1,
ressut_pos = 0,
ressut_f = 0;
unsigned long prevperiods[1024];
for(c = 0; c < size; c++) {
if(ressut_pos == 0) {
if(ressut_first) {
memset(ressut, 0, ressut_bytes);
ressut_first = 0;
}
clockbytes=0;
for(d = 0; d < 1024; d++) {
periods[d] = 0;
}
rndbits1 = 0;
rndbits2 = 0;
rndbits3 = 0;
rndbits4 = 0;
int lim, lim1 = 0, lim2 = 0;
int lim1a, lim1b;
int high1, high2;
int rndbits3high;
#ifdef DEBUG6
int rndbits4high;
#endif
int rndbits4highdigits;
for(d = 0;
rndbits1 < ressu_bits1_needed ||
rndbits2 < ressu_bits2_needed ||
rndbits3 < ressu_bits3_needed ||
rndbits4 < ressu_bits4_needed ||
d < RESSU_MIN_ROUNDS ||
clockbytes < RESSU_MIN_CLOCKBYTES; d++) {
//
// calculate rndbits1
//
// save previous round
for(e = 0; e < 1024; e++) {
prevperiods[e] = periods[e];
}
ressu_genbytes_single(ressut_bytes, ressut);
// find new lim1
lim = lim1;
f = -1;
for(e = 0; e < 1024; e++) {
if(prevperiods[e] > 0 && prevperiods[e] == lim) {
if(f == -1 || (periods[e]>0 && f<periods[e])) {
f = periods[e];
}
}
}
if(f != -1)
lim = f;
lim1a = lim;
// find highest amount of chains
high1 = -1;
for(e = 0; e < 1024; e++) {
if(high1 == -1 || high1 < periods[e]) {
high1 = periods[e];
}
}
// and second highest
high2 = -1;
for(e = 0; e < 1024; e++) {
if( (high2 == -1 && periods[e] < high1) ||
(high2 < periods[e] && periods[e] < high1) ) {
high2 = periods[e];
}
}
// and average
int psum = 0;
int pcnt = 0;
for(e = 0; e < 1024; e++) {
if(periods[e] > 0) {
psum += periods[e];
pcnt++;
}
}
lim1b = (int)((double)psum / pcnt);
// find next smaller than average
f = -1;
for(e = 0; e < 1024; e++) {
if( (f == -1 && periods[e] < lim1b) ||
(f<periods[e] && periods[e] < lim1b) ) {
f = periods[e];
}
}
if(f != -1)
lim1b = f;
if(lim == 0 || lim > lim1b)
lim = lim1b;
// if lim greater that second highest,
// set to second highest
if(lim > high2) {
lim = high2;
}
lim1 = lim;
// find next greater than lim
f = -1;
for(e = 0; e < 1024; e++) {
if(periods[e] > lim &&
(f == -1 || periods[e] < f))
f = periods[e];
}
if(f != -1)
lim = f;
lim2 = lim;
// calculate rndbits1
rndbits1=0;
for(e = 0; e < 1024; e++) {
if(periods[e] > 0 && periods[e] < lim) {
rndbits1 += periods[e];
}
}
//
// calculate rndbits3
//
rndbits3high=0;
rndbits3=0;
for(e=0; e < 1024; e++) {
if(rndbits3high < periods[e])
rndbits3high = periods[e];
}
#ifdef DEBUG8
fprintf(stdout,"\n%d:", rndbits3high);
#endif
for(e=0; e < 1024; e++) {
if(rndbits3high > periods[e]) {
rndbits3 += periods[e];
#ifdef DEBUG8
if(periods[e]>0)
fprintf(stdout," %ld(%d)", periods[e],rndbits3);
#endif
}
}
//
// calculate rndbits4
//
rndbits4highdigits=0;
#ifdef DEBUG6
rndbits4high=0;
#endif
rndbits4=0;
for(e=0; e < 1024; e++) {
if(rndbits4highdigits < (int)log10((double)periods[e]) + 1) {
rndbits4highdigits = (int)log10((double)periods[e]) + 1;
#ifdef DEBUG6
rndbits4high = periods[e];
#endif
}
}
#ifdef DEBUG6
fprintf(stdout,"\n%d:", rndbits4high);
#endif
for(e=0; e < 1024; e++) {
if(rndbits4highdigits > (int)log10((double)periods[e]) + 1) {
rndbits4 += periods[e];
#ifdef DEBUG6
if(periods[e]>0)
fprintf(stdout," %ld(%d)", periods[e],rndbits4);
#endif
}
}
} // for(d=0;
if(stats) {
//
// display statistics
//
fprintf(stdout, "rounds: %d", d);
for(e = 0; e < 1024; e++) {
if(periods[e] > 0)
fprintf(stdout, " %d:%lu", e, periods[e]);
}
#ifdef DEBUG_SORTED
fprintf(stdout, ", sorted:");
int g = 0;
for(;;) {
f = -1;
for(e = 0; e < 1024; e++) {
if( (f==-1 && periods[e]>g) ||
(periods[e]>g && f>periods[e]) )
f = periods[e];
}
if(f == -1)
break;
g=f;
fprintf(stdout," %d", g);
}
#endif
fprintf(stdout, ", high1:%d", high1);
fprintf(stdout, ", high2:%d", high2);
fprintf(stdout, ", lim1a:%d", lim1a);
fprintf(stdout, ", lim1b:%d", lim1b);
fprintf(stdout, ", lim1:%d", lim1);
fprintf(stdout, ", lim2:%d", lim2);
fprintf(stdout, ", div:%f", (double)lim2 / lim1);
fprintf(stdout, ", clockbytes:%ld", clockbytes);
fprintf(stdout, ", rndbits1:%d", rndbits1);
fprintf(stdout, ", rndbits2:%d", rndbits2);
fprintf(stdout, ", rndbits3high:%d", rndbits3high);
fprintf(stdout, ", rndbits3:%d", rndbits3);
fprintf(stdout, ", rndbits4highdigits:%d", rndbits4highdigits);
fprintf(stdout, ", rndbits4:%d", rndbits4);
fprintf(stdout, "\n");
fflush(stdout);
}
} // if(ressut_pos == 0)
ressut_f = (ressut_f + ressut[ressut_pos]) % ressut_bytes;
buffer[c] ^= ressut[ressut_f];
ressut_pos = (ressut_pos+1) % ressut_bytes;
} // for(c=0; c<size; c++)
#ifdef DEBUG7
for(c = 0; c < size; c++) {
if(c%32 == 0)
fprintf(stdout, "\ngenbytes ");
fprintf(stdout, "%02x", buffer[c]);
newressu_output = 1;
}
fprintf(stdout, "\n");
#endif
genbytes+=size;
}
static unsigned char ressu_clockbyte_debug() /* JariK 2013 */
{
unsigned char ch;
ch=ressu_clockbyte2();
#ifdef MORESECURE
static unsigned int pausecount=1000, pausebase=0;
// every 1001 bytes skip randon
// clockbytes by usleeping
if(--pausecount == 0) {
#ifdef FORT
if(input == INPUT_FORT ||
input == INPUT_FORTXOR)
pausebase += cvar[0] + 256 * cvar[1];
#endif
pausebase = pausebase +
pausecount +
clockbytes +
genbytes +
gent_pos +
time(NULL) +
get_useconds() +
ch;
int skip=ressut[pausebase % ressut_bytes];
while(skip>0) { // compare usleep(skip);
ch=ressu_clockbyte2();
skip--;
}
rndbits2+=8;
pausecount=500+ressut[(pausebase + 1) % ressut_bytes]*4; // value 500-1500
}
#endif // #ifdef MORESECURE
return(ch);
}
void ressu_genbytes_single_debug(int size, unsigned char *buffer)
{
int c, d;
unsigned char e, byte;
static int f = 0, prevbyte = -1, count = 0;
for(c = 0; c < 8; c++) {
for(d = 0; d < size; d++) {
e = buffer[d];
e = RL8(e,1); // rotate byte left 1 bits
//e = RL8(e,3); // rotate byte left 3 bits
//e = RR8(e,1); // rotate byte right 1 bits
byte = ressu_clockbyte_debug();
if(prevbyte == -1)
prevbyte = byte;
buffer[d] = e^byte;
if(prevbyte != byte) {
periods[count]++;
clockbytes += count;
count = 0;
prevbyte = byte;
}
count++;
}
for(d = 0; d < size; d++) {
f = (f + buffer[d]) % size;
e = buffer[d];
buffer[d] = buffer[f];
buffer[f] = e;
}
}
}
void ressu_genbytes_debug(int size, unsigned char *buffer) // 6.5.2021 JariK
{
int c, d;
static int ressut_first=1,
ressut_pos = 0,
ressut_f = 0;
for(c = 0; c < size; c++) {
if(ressut_pos == 0) {
if(ressut_first) {
memset(ressut, 0, ressut_bytes);
ressut_first = 0;
}
rndbits2 = 0;
clockbytes = 0;
for(d = 0;rndbits2 < ressu_bits2_needed ||
d < RESSU_MIN_ROUNDS; d++) {
ressu_genbytes_single_debug(ressut_bytes, ressut);
}
if(stats) {
fprintf(stdout, "rounds: %d", d);
fprintf(stdout, ", clockbytes:%ld", clockbytes);
fprintf(stdout, ", rndbits2:%d", rndbits2);
fprintf(stdout, "\n");
fflush(stdout);
}
} // if(ressut_pos == 0)
ressut_f = (ressut_f + ressut[ressut_pos]) % ressut_bytes;
buffer[c] ^= ressut[ressut_f];
ressut_pos = (ressut_pos+1) % ressut_bytes;
} // for(c=0; c<size; c++)
#ifdef DEBUG7
for(c = 0; c < size; c++) {
if(c % 32 == 0)
fprintf(stdout, "\ngenbytes ");
fprintf(stdout, "%02x", buffer[c]);
newressu_output = 1;
}
fprintf(stdout, "\n");
#endif
genbytes += size;
}
static void readfile_xor(int len,
unsigned char *buf,
unsigned char *filename)
{
int c, n, n2;
unsigned char temp[64];
FILE *fp1;
if((fp1 = fopen(filename, "rb"))
!= NULL) {
while(len != 0) {
n = (len < sizeof(temp)) ?
len : sizeof(temp);
n2=fread(temp, 1, n, fp1);
for(c = 0; c < n2; c++)
buf[c] ^= temp[c];
len -= n2;
buf += n2;
}
fclose(fp1);
}
}
int input=0;
#define aDEBUG9 2
char *randomgen[] = { "ressu", "debug","fast","single","4","5","fort","fortxor","urandom","random" };
void gent_clear()
{
memset(gent,0,sizeof(gent));
}
#define aDEBUG17 2
#define aDEBUG18 2
int ressu_genbyte()
{
unsigned char ch;
if(gent_pos == 0) {
if(input == INPUT_RESSU) // ressu prod
ressu_genbytes(sizeof(gent), gent);
else if(input == INPUT_DEBUG) // ressu debug
ressu_genbytes_debug(sizeof(gent), gent);
else if(input == INPUT_FAST) // ressu_fast
ressu_genbytes_fast(sizeof(gent),gent);
else if(input == INPUT_SINGLE) // ressu single
ressu_genbytes_single(sizeof(gent), gent);
#ifdef FORT
else if(input == INPUT_FORT) // ressu fort
fort_random_data(sizeof(gent), gent);
else if(input == INPUT_FORTXOR) // ressu fort
fort_random_data_xor(sizeof(gent), gent);
#endif
else if(input == INPUT_URANDOM) // urandom
readfile_xor(sizeof(gent), gent, urandomfilename);
#ifdef USE_RANDOM
else if(input == INPUT_RANDOM) // random
readfile_xor(sizeof(gent), gent, randomfilename);
#endif
else {
fprintf(stdout,"%s: mode '%d'(%s) not available\n",
procname, input, randomgen[input]);
exit(1);
}
#ifdef DEBUG17
for(int c=0; c < sizeof(gent); c++) {
if(c % 32 == 0)
fprintf(stdout,"\ngenbyte ");
fprintf(stdout,"%02x", gent[c]);
}
fprintf(stdout,"\n");
#endif
} // if(gent_pos==0
ch = gent[gent_pos];
gent_pos = (gent_pos + 1) % sizeof(gent);
#ifdef DEBUG18
fprintf(stdout,"{%02x}",ch);
#endif
return(ch);
}
#define aDEBUG19 2
#define aDEBUG24 2
unsigned long ressu_gen_limit(unsigned long limit)
{
int c, bytes;
unsigned long word, highlimit;
if(limit<=0x100) { // 1 byte
highlimit=0x100;
bytes=1;
} else if(limit<=0x10000) { // 2 bytes
highlimit=0x10000;
bytes=2;
} else if(limit<=0x1000000) { // 3 bytes
highlimit=0x1000000;
bytes=3;
} else if(limit<=(unsigned long)0x100000000) { // 4 bytes
highlimit=0x100000000;
bytes=4;
} else if(limit<=(unsigned long)0x10000000000) { // 5 bytes
highlimit=0x10000000000;
bytes=5;
} else if(limit<=(unsigned long)0x1000000000000) { // 6 bytes
highlimit=0x1000000000000;
bytes=6;
} else if(limit<=(unsigned long)0x100000000000000) { // 7 bytes
highlimit=0x100000000000000;
bytes=7;
} else { // if(limit<=(unsigned long)0xffffffffffffffff) { // 8 bytes
highlimit=0xffffffffffffffff;
bytes=8;
}
for(;;) {
word=0;
for(c=0;c<bytes;c++)
word = word << 8 | ressu_genbyte();
if(word < (highlimit/limit)*limit)
break;
}
word%=limit;
#ifdef DEBUG24
fprintf(stdout,"/");
#ifdef DEBUG19
fprintf(stdout,"%d bytes: ", bytes);
#endif
if(type==2)
fprintf(stdout,"%lx", word);
else if(type==8)
fprintf(stdout,"%lo", word);
else if(type==10)
fprintf(stdout,"%lu", word);
else if(type==16)
fprintf(stdout,"%lx", word);
else
fprintf(stdout,"%lu", word);
fprintf(stdout,"/");
fflush(stdout);
#endif
return(word);
}
#ifdef OLD1
// Little faster on middle byte numbers (3,5,6,7),
// try --rand & --timer
#define GENMIDBYTES 2
int ressu_genbyte_limit(int limit) // 1 byte
{
int c;
while((c=ressu_genbyte()) >= (0x100/limit)*limit);
#ifdef DEBUG19
fprintf(stdout," byte %x(%d)",c,c);
fflush(stdout);
#endif
return(c%limit);
}
int ressu_genshort() // 2 bytes
{
return(ressu_genbyte() | ressu_genbyte()<<8);
}
int ressu_genshort_limit(int limit) // 2 bytes
{
int c;
while((c=ressu_genshort()) >= (0x10000/limit)*limit);
#ifdef DEBUG19
fprintf(stdout," short %x(%d)",c,c);
fflush(stdout);
#endif
return(c%limit);
}
#ifdef GENMIDBYTES
int ressu_gen3bytes() // 3 bytes
{
return(ressu_genshort() | ressu_genbyte()<<16);
}
int ressu_gen3bytes_limit(int limit) // 3 bytes
{
int c;
while((c=ressu_gen3bytes()) >= (0x1000000/limit)*limit);
#ifdef DEBUG19
fprintf(stdout," 3 bytes %x(%d)",c,c);
fflush(stdout);
#endif
return(c%limit);
}
#endif // #ifdef GENMIDBYTES
unsigned int ressu_genint() // 4 bytes
{
return(ressu_genshort() | ressu_genshort()<<16);
}
unsigned int ressu_genint_limit(unsigned long limit) // 4 bytes
{
unsigned int c;
while((c=ressu_genint()) >= (((unsigned long)0x100000000)/limit)*limit);
#ifdef DEBUG19
fprintf(stdout," int %x(%d)",c,c);
fflush(stdout);
#endif
return(c%limit);
}
#ifdef GENMIDBYTES
unsigned long ressu_gen5bytes() // 5 bytes
{
return(ressu_genint() | ((unsigned long)ressu_genbyte())<<32);
}
unsigned long ressu_gen5bytes_limit(unsigned long limit) // 5 bytes
{
unsigned long c;
while((c=ressu_gen5bytes()) >= (((unsigned long)0x10000000000)/limit)*limit);
#ifdef DEBUG19
fprintf(stdout," 5 bytes %lx(%ld)",c,c);
fflush(stdout);
#endif
return(c%limit);
}
unsigned long ressu_gen6bytes() // 6 bytes
{
return(ressu_genint() | ((unsigned long)ressu_genshort())<<32);
}
unsigned long ressu_gen6bytes_limit(unsigned long limit) // 6 bytes
{
unsigned long c;
while((c=ressu_gen6bytes()) >= (((unsigned long)0x1000000000000)/limit)*limit);
#ifdef DEBUG19
fprintf(stdout," 6 bytes %lx(%ld)",c,c);
fflush(stdout);
#endif
return(c%limit);
}
unsigned long ressu_gen7bytes() // 7 bytes
{
return(ressu_genint() | ((unsigned long)ressu_gen3bytes())<<32);
}
#define aDEBUG22
unsigned long ressu_gen7bytes_limit(unsigned long limit) // 7 bytes
{
unsigned long c;
while((c=ressu_gen7bytes()) >= (((unsigned long)0x100000000000000)/limit)*limit);
#ifdef DEBUG19
fprintf(stdout," 7 bytes %lx(%ld)",c,c);
fflush(stdout);
#endif
return(c%limit);
}
#endif // #ifdef GENMIDBYTES
unsigned long ressu_genlong() // 8 bytes
{
return(((unsigned long)ressu_genint()) | ((unsigned long)ressu_genint())<<32);
}
unsigned long ressu_genlong_limit(unsigned long limit) // 8 bytes
{
unsigned long c;
while((c=ressu_genlong()) >= (((unsigned long)0xffffffffffffffff)/limit)*limit);
#ifdef DEBUG19
fprintf(stdout," long %lx(%lu)",c,c);
fflush(stdout);
#endif
return(c%limit);
}
unsigned long ressu_gen_limit2(unsigned long limit)
{
unsigned long c;
if(limit<=0x100) // 1 byte
c=ressu_genbyte_limit(limit);
else if(limit<=0x10000) // 2 bytes
c=ressu_genshort_limit(limit);
#ifdef GENMIDBYTES
else if(limit<=0x1000000) // 3 bytes
c=ressu_gen3bytes_limit(limit);
#endif
else if(limit<=(unsigned long)0x100000000) // 4 bytes
c=ressu_genint_limit(limit);
#ifdef GENMIDBYTES
else if(limit<=(unsigned long)0x10000000000) // 5 bytes
c=ressu_gen5bytes_limit(limit);
else if(limit<=(unsigned long)0x1000000000000) // 6 bytes
c=ressu_gen6bytes_limit(limit);
else if(limit<=(unsigned long)0x100000000000000) // 7 bytes
c=ressu_gen7bytes_limit(limit);
#endif
else if(limit<=(unsigned long)0xffffffffffffffff) // 8 bytes
c=ressu_genlong_limit(limit);
else
c=-1;
#ifdef DEBUG24
fprintf(stdout,"/%ld/",c);
#endif
return(c);
}
#endif
void newressu_version()
{
fprintf(stderr,"%s",programname); // touch these outside MAIN
fprintf(stderr,", %s",copyright);
}
#ifdef MAIN
#include <stdarg.h>
#define aDEBUG31
static int stat_line_chars=0;
static int stat_line_edchars=0;
unsigned char *procname=NULL;
static void stat_line_begin()
{
#ifdef DEBUG31
fprintf(stderr,"\n");
#else
fprintf(stderr,"\r");
#endif
stat_line_edchars=stat_line_chars;
stat_line_chars=0;
}
static void stat_line_printf(const unsigned char *format, ...)
{
int count;
va_list args;
static unsigned char *stat_line_buf;
static size_t stat_line_buf_length;
va_start(args, format);
count = vsnprintf(stat_line_buf, stat_line_buf_length, format, args) + 1;
va_end(args);
if(stat_line_buf_length < count) {
stat_line_buf_length=count;
stat_line_buf=realloc(stat_line_buf, stat_line_buf_length);
va_start(args, format);
count = vsnprintf(stat_line_buf, stat_line_buf_length, format, args) + 1;
va_end(args);
}
fprintf(stderr,"%s",stat_line_buf);
stat_line_chars+=strlen(stat_line_buf);
}
#define READABLE_NUMBER_BIN 2
#ifdef READABLE_NUMBER_BIN
#define READABLE_NUMBER_HIGH 1023
#define READABLE_NUMBER_DIVIDER 1024
#else
#define READABLE_NUMBER_HIGH 999
#define READABLE_NUMBER_DIVIDER 1000
#endif
#define READABLE_NUMBER_WIDTH 32
static void stat_line_readable(unsigned long length)
{
int c, low;
double length2;
unsigned char buf10[10];
// B = byte
// K = kilo 10^3 2^10
// M = mega 10^6 2^20
// G = giga 10^9 2^30
// T = tera 10^12 2^40
// P = peta 10^15 2^50
// E = exa 10^18 2^60
// Z = zetta 10^21 2^70
// Y = yotta 10^24 2^80
char units[] = "BKMGTPEZY";
strcpy(buf10,"***");
low=0;
for(c=0; length>=low &&
c<sizeof(units)-1; c++) {
if(length>=low &&
length<=READABLE_NUMBER_HIGH) {
if(units[c]=='B')
sprintf(buf10,"%ld", length);
else if(units[c]=='K')
sprintf(buf10,"%ld%cB", length, units[c]);
else if(length==length2)
sprintf(buf10,"%ld%cB", length, units[c]);
else
sprintf(buf10,"%.1f%cB", length2, units[c]);
break;
}
length2=(double)length/READABLE_NUMBER_DIVIDER;
length/=READABLE_NUMBER_DIVIDER;
low=1;
}
stat_line_printf("%s",buf10);
}
void stat_line_end()
{
int c,d;
// previous line longer than this one,
// overwrite with spaces and backspace to
// end
if(stat_line_edchars>stat_line_chars) {
d=stat_line_edchars-stat_line_chars;
for(c=0;c<d;c++) {
#ifdef DEBUG31
fprintf(stderr,"*");
#else
fprintf(stderr," ");
#endif
}
for(c=0;c<d;c++)
fprintf(stderr,"\b");
}
fflush(stderr);
}
int help=0;
static int utf8characters(unsigned char *buf)
{
int characters;
unsigned char *p;
p=buf;
characters=0;
while(*p!='\0') {
if(*p<0x80 || // ascii char
*p>0xbf) // first utf8 byte
characters++;
p++;
}
return(characters);
}
#define aDEBUG29 2
int utf8lengths(unsigned char *buf)
{
int lengths,len,first=1;
unsigned char *p;
#ifdef DEBUG29
fprintf(stdout,"digits %s",buf);
fprintf(stdout,"\nlengths ");
#endif
p=buf;
len=0;
lengths=-1;
first=1;
while(*p!='\0') {
if(!first &&
(*p<0x80 || // ascii char
*p>0xbf)) { // first utf8 byte
#ifdef DEBUG29
fprintf(stdout,"%d",len);
#endif
if(lengths==-1)
lengths=len;
else if(lengths!=len)
lengths=0;
len=0;
}
p++;
len++;
first=0;
}
#ifdef DEBUG29
fprintf(stdout,"%d",len);
#endif
if(lengths==-1)
lengths=len;
else if(lengths!=len)
lengths=0;
#ifdef DEBUG29
fprintf(stdout,"\nlengths %d\n\n",lengths);
#endif
return(lengths);
}
#define aDEBUG42 2
static void codetoutf8(unsigned char *buf2, unsigned long code)
{
unsigned char *buf;
buf=buf2;
if(code<=0x7f) {
*buf++=code;
} else if(code<=0x7ff) { // 110xxxxx 10xxxxxx
*buf++=(0xc0 | ((code>>6)&0x1f));
*buf++=(0x80 | (code&0x3f));
} else if(code<=0xffff) { // 1110xxxx 10xxxxxx 10xxxxxx
*buf++=(0xe0 | ((code>>12)&0x0f));
*buf++=(0x80 | ((code>>6)&0x3f));
*buf++=(0x80 | (code&0x3f));
} else if(code<=0x10ffff) { // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
*buf++=(0xf0 | ((code>>18)&0x07));
*buf++=(0x80 | ((code>>12)&0x3f));
*buf++=(0x80 | ((code>>6)&0x3f));
*buf++=(0x80 | ((code&0x3f)));
} else if(code<=0x3ffffff) { // 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx // these not yet needed
*buf++=(0xf8 | ((code>>24)&0x03));
*buf++=(0x80 | ((code>>18)&0x3f));
*buf++=(0x80 | ((code>>12)&0x3f));
*buf++=(0x80 | ((code>>6)&0x3f));
*buf++=(0x80 | ((code&0x3f)));
} else if(code<=0x7fffffff) { // 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx // these not yet needed
*buf++=(0xfc | ((code>>30)&0x01));
*buf++=(0x80 | ((code>>24)&0x3f));
*buf++=(0x80 | ((code>>18)&0x3f));
*buf++=(0x80 | ((code>>12)&0x3f));
*buf++=(0x80 | ((code>>6)&0x3f));
*buf++=(0x80 | ((code&0x3f)));
} else if(code<=0xfffffffff) { // 11111110 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx // these not yet needed
*buf++=(0xfe);
*buf++=(0x80 | ((code>>30)&0x3f));
*buf++=(0x80 | ((code>>24)&0x3f));
*buf++=(0x80 | ((code>>18)&0x3f));
*buf++=(0x80 | ((code>>12)&0x3f));
*buf++=(0x80 | ((code>>6)&0x3f));
*buf++=(0x80 | ((code&0x3f)));
} else if(code<=0x3ffffffffff) { // 11111111 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx // these not yet needed
*buf++=(0xff);
*buf++=(0x80 | ((code>>36)&0x3f));
*buf++=(0x80 | ((code>>30)&0x3f));
*buf++=(0x80 | ((code>>24)&0x3f));
*buf++=(0x80 | ((code>>18)&0x3f));
*buf++=(0x80 | ((code>>12)&0x3f));
*buf++=(0x80 | ((code>>6)&0x3f));
*buf++=(0x80 | ((code&0x3f)));
}
*buf='\0';
#ifdef DEBUG42
int c,print;
fprintf(stdout,"codepoint: %lx",code);
fprintf(stdout,", bin:");
print=0;
for(c=(sizeof(code)*8)-1;c>=0;c--) {
int bit=(code>>c)&1;
if(bit!=0)
print=1;
if(print) {
fprintf(stdout,"%d",bit);
if(c>0 && c%8==0)
fprintf(stdout,"|");
}
}
fprintf(stdout,", oct:");
print=0;
fprintf(stdout,"%lo",code);
fprintf(stdout,", utf8: ");
for(c=0;c<8;c++) {
if(buf2[c]=='\0')
break;
fprintf(stdout,"%02x",buf2[c]);
}
fprintf(stdout,", bin: ");
for(c=0;c<8;c++) {
if(buf2[c]=='\0')
break;
if(c>0)
fprintf(stdout,"|");
for(int d=7;d>=0;d--) {
fprintf(stdout,"%d",buf2[c]>>d&1);
}
}
fprintf(stdout,", oct:");
for(c=0;c<8;c++) {
if(buf2[c]=='\0')
break;
fprintf(stdout," %3o",buf2[c]);
}
fprintf(stdout,", character: %s",buf2);
fprintf(stdout,"\n");
#endif
}
#ifdef NOTUSED
#define aDEBUG43 2
static void utf8tocode(unsigned long *code, unsigned char *buf2)
{
unsigned char *buf;
*code=0;
buf=buf2;
if(*buf<=0x7f) { // 0xxxxxxx
*code=*buf;
} else if(*buf<0xc0) { // 110xxxxx 10xxxxxx
*code=0;
} else if(*buf<0xe0) { // 110xxxxx 10xxxxxx
*code=*buf++&0x1f;
*code=(*code<<6)+(*buf++&0x3f);
} else if(*buf<0xf0) { // 1110xxxx 10xxxxxx 10xxxxxx
*code=*buf++&0x0f;
*code=(*code<<6)+(*buf++&0x3f);
*code=(*code<<6)+(*buf++&0x3f);
} else if(*buf<0xf8) { // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
*code=*buf++&0x07;
*code=(*code<<6)+(*buf++&0x3f);
*code=(*code<<6)+(*buf++&0x3f);
*code=(*code<<6)+(*buf++&0x3f);
} else if(*buf<0xfc) { // 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
*code=*buf++&0x03;
*code=(*code<<6)+(*buf++&0x3f);
*code=(*code<<6)+(*buf++&0x3f);
*code=(*code<<6)+(*buf++&0x3f);
*code=(*code<<6)+(*buf++&0x3f);
} else if(*buf<0xfe) { // 1111110x 10xxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
*code=*buf++&0x01;
*code=(*code<<6)+(*buf++&0x3f);
*code=(*code<<6)+(*buf++&0x3f);
*code=(*code<<6)+(*buf++&0x3f);
*code=(*code<<6)+(*buf++&0x3f);
*code=(*code<<6)+(*buf++&0x3f);
} else if(*buf<0xff) { // 11111110 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
buf++;
*code=*buf++&0x3f;
*code=(*code<<6)+(*buf++&0x3f);
*code=(*code<<6)+(*buf++&0x3f);
*code=(*code<<6)+(*buf++&0x3f);
*code=(*code<<6)+(*buf++&0x3f);
*code=(*code<<6)+(*buf++&0x3f);
} else if(*buf==0xff) { // 11111111 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
buf++;
*code=*buf++&0x3f;
*code=(*code<<6)+(*buf++&0x3f);
*code=(*code<<6)+(*buf++&0x3f);
*code=(*code<<6)+(*buf++&0x3f);
*code=(*code<<6)+(*buf++&0x3f);
*code=(*code<<6)+(*buf++&0x3f);
*code=(*code<<6)+(*buf++&0x3f);
}
#ifdef DEBUG43
int c;
fprintf(stdout,"character: %s",buf2);
fprintf(stdout,", utf8: ");
for(c=0;c<8;c++) {
if(buf2[c]=='\0')
break;
fprintf(stdout,"%02x",buf2[c]);
}
fprintf(stdout,", bin: ");
for(c=0;c<8;c++) {
if(buf2[c]=='\0')
break;
if(c>0)
fprintf(stdout,"|");
for(int d=7;d>=0;d--)
fprintf(stdout,"%d",buf2[c]>>d&1);
}
fprintf(stdout,", oct:");
for(c=0;c<8;c++) {
if(buf2[c]=='\0')
break;
fprintf(stdout," %3o",buf2[c]);
}
fprintf(stdout,", codepoint: %lx",*code);
fprintf(stdout,", bin:");
int print=0;
for(c=(sizeof(code)*8)-1;c>=0;c--) {
int bit=(*code>>c)&1;
if(bit!=0)
print=1;
if(print) {
fprintf(stdout,"%d",bit);
if(c>0 && c%8==0)
fprintf(stdout,"|");
}
}
fprintf(stdout,", oct:");
fprintf(stdout,"%lo",*code);
fprintf(stdout,"\n");
#endif
}
#endif
int characterlengths=0; // 0 multiple lengths, x lengths are same
#define aDEBUG30 2
static void utf8getcharacter(int size, unsigned char *buf, int n, unsigned char *string)
{
int d;
unsigned char *p,*q;
d=0;
p=string;
q=buf;
// find first byte of character
if(characterlengths!=0)
p+=characterlengths*n;
else {
while(*p!='\0') {
if(*p<0x80 || // ascii char
*p>0xbf) { // first utf8 char
if(d==n)
break;
d++;
}
p++;
}
}
// copy first byte and rest
// of character
if(*p!='\0') {
*q++=*p; // copy first byte
if(*p>0xbf) { // if first is utf8 char
p++;
for(;;) {
if(*p>0xbf || // first utf8 char
*p<0x80 || // ascii char
*p=='\0') // end of file
break;
*q++=*p++; // copy rest of the bytes
}
}
}
*q='\0';
#ifdef DEBUG30
fprintf(stdout,"%s: utf8getcharacter:",procname);
fprintf(stdout," string: %s",string);
fprintf(stdout,", n: %d",n);
fprintf(stdout,", character: %s",buf);
fprintf(stdout,", characterlengths: %d",characterlengths);
fprintf(stdout,"\n");
#endif
}
static void utf8getcharacter1(int size, unsigned char *buf, int n, unsigned char *string)
{
unsigned char *p,*q;
p=string;
q=buf;
// find first byte of character
p+=n;
// copy first byte and rest
// of character
if(*p!='\0') {
*q++=*p; // copy first byte
if(*p>0xbf) { // if first is utf8 char
p++;
for(;;) {
if(*p>0xbf || // first utf8 char
*p<0x80 || // ascii char
*p=='\0') // end of file
break;
*q++=*p++; // copy rest of the bytes
}
}
}
*q='\0';
#ifdef DEBUG30
fprintf(stdout,"%s: utf8getcharacter:",procname);
fprintf(stdout," string: %s",string);
fprintf(stdout,", n: %d",n);
fprintf(stdout,", character: %s",buf);
fprintf(stdout,", characterlengths: %d",characterlengths);
fprintf(stdout,"\n");
#endif
}
#define aDEBUG45 2
int digitscount=10;
static void out_word(int size, unsigned char *buf, unsigned char *digits, unsigned long word2) // 8.5.2021 JariK
{
int c, d, len;
unsigned long word;
unsigned char string[132], character[32];
//digitscount = utf8characters(digits);
word=word2;
len=0;
string[0]='\0';
if(word==0 || digitscount<2) {
// zero
utf8getcharacter(sizeof(character),character,0,digits);
if(len+strlen(character)<sizeof(string)) {
strcat(string,character);
len+=strlen(character);
}
} else {
// non zero
while(word>0) {
utf8getcharacter(sizeof(character),character,word%digitscount,digits);
if(len+strlen(character)<sizeof(string)) {
strcat(string,character);
len+=strlen(character);
}
word/=digitscount;
}
}
// reverse string
*buf='\0';
len=0;
d=utf8characters(string);
for(c=d-1;c>=0;c--) {
utf8getcharacter(sizeof(character),character,c,string);
if(len+strlen(character)<size) {
strcat(buf,character);
len+=strlen(character);
}
}
#ifdef DEBUG45
fprintf(stdout,"]\n%s: out_word: ",procname);
fprintf(stdout," reverse string: %s",string);
fprintf(stdout,", digits: %s",digits);
fprintf(stdout,", int: %lu",word2);
fprintf(stdout,"\n[");
#endif
}
static void out_word_10(int size, unsigned char *buf, unsigned long word2) // 8.5.2021 JariK
{
int c, d, len;
unsigned long word;
unsigned char string[132], character[32];
unsigned char *digits="0123456789";
int digitscount=10;
//digitscount = utf8characters(digits);
word=word2;
len=0;
string[0]='\0';
if(word==0 || digitscount<2) {
// zero
utf8getcharacter1(sizeof(character),character,0,digits);
if(len+strlen(character)<sizeof(string)) {
strcat(string,character);
len+=strlen(character);
}
} else {
// non zero
while(word>0) {
utf8getcharacter1(sizeof(character),character,word%digitscount,digits);
if(len+strlen(character)<sizeof(string)) {
strcat(string,character);
len+=strlen(character);
}
word/=digitscount;
}
}
// reverse string
*buf='\0';
len=0;
d=utf8characters(string);
for(c=d-1;c>=0;c--) {
utf8getcharacter1(sizeof(character),character,c,string);
if(len+strlen(character)<size) {
strcat(buf,character);
len+=strlen(character);
}
}
#ifdef DEBUG45
fprintf(stdout,"]\n%s: out_word: ",procname);
fprintf(stdout," reverse string: %s",string);
fprintf(stdout,", digits: %s",digits);
fprintf(stdout,", int: %lu",word2);
fprintf(stdout,"\n[");
#endif
}
#define aDEBUG48 2
static void in_word(unsigned long *word, unsigned char *digits, unsigned char *buf)
{
int c,d,e,f,ok;
unsigned char character[32], character2[32];
*word=0;
d=utf8characters(buf);
f=utf8characters(digits);
for(c=0;c<d;c++) {
utf8getcharacter(sizeof(character2),character2,c,buf);
ok=0;
for(e=0;e<f;e++) {
utf8getcharacter(sizeof(character),character,e,digits);
if(!strcmp(character,character2)) {
ok=1;
break;
}
}
if(ok) {
*word=((*word)*f)+e;
} else {
fprintf(stdout,"%s: in_word:",procname);
fprintf(stdout," illegal digit '%s'\n",character2);
help=1;
}
}
#ifdef DEBUG48
fprintf(stdout,"%s: in_word:",procname);
fprintf(stdout," word: %lu",*word);
fprintf(stdout,", digits: %s",digits);
fprintf(stdout,", string: %s",buf);
fprintf(stdout,"\n");
#endif
}
static void line_clear(int *len, unsigned char **buf)
{
if(*len<1) {
*len=129;
*buf=realloc(*buf,*len);
}
**buf='\0';
}
static int line_add_string_sort(int *len, unsigned char **buf, unsigned char *string)
{
int cmp,count,add;
unsigned char *p;
p=*buf;
add=1;
while(*p!='\0') {
cmp=strncmp(string,p,strlen(string));
if(cmp>0) {
while(*p!=' ' && *p!='\0') // find next space
p++;
while(*p==' ' && *p!='\0') // find next non space
p++;
} else if(cmp==0) {
add=0;
break;
} else {
break;
}
}
if(add) {
count=strlen(*buf)+strlen(string)+1+1;
if(*buf==NULL || count>*len) {
int diff=p-*buf;
*len = *len + 128;
*buf=realloc(*buf,*len);
p=*buf+diff;
}
memmove(p+strlen(string)+1,p,strlen(p)+1);
memmove(p,string,strlen(string));
p+=strlen(string);
*p=' ';
}
return(add);
}
static void line_get_string(int len, unsigned char *buf, int n, unsigned char *string)
{
int e,ok,count;
unsigned char *p,*q;
ok=0;
p=string;
e=0;
while(*p!='\0') {
if(e==n) {
ok=1;
break;
}
while(*p!=' ' && *p!='\0') // find next space
p++;
while(*p==' ' && *p!='\0') // find next non space
p++;
e++;
}
if(ok) {
q=buf;
count=0;
while(*q!=' ' && *q!='\0') {
if(++count<len)
*q++=*p;
p++;
}
*q='\0';
} else {
buf[0]='\0';
}
}
static int zero=1, sspace=0, snewline=0,
scrlf=1, chars=72, pchars=0, charwidth=1, charspaces=0,
words=0, pwords=0,
plinesdigits=5, slineno=1, screen=0,
quiet=0, sort=0, unique=0, sample=0;
#ifdef DEBUG51
static int limitsize=0,
#endif
static unsigned long long lines=10, plines=0, ptotallines=0;
static unsigned long limit, word;
static unsigned char *digits="0123456789", character[32];
static unsigned char digitstemp[256], *digitsext=NULL;
static unsigned char linenobuf[1024];
#define aDEBUG51 2
static void readword(unsigned char *buf)
{
int d,e;
unsigned char temp1024[1024];
if(limit!=0) {
word=0;
if(zero) {
word=ressu_gen_limit(limit); // include zeroes
} else if(limit>=1) {
while((word=ressu_gen_limit(limit))==0); // skip zeroes
}
#ifdef DEBUG51
if(type==2)
fprintf(stdout,"(%0*lx)",limitsize,word);
else if(type==8)
fprintf(stdout,"(%0*lo)",limitsize,word);
else if(type==10)
fprintf(stdout,"(%0*lu)",limitsize,word);
else if(type==16)
fprintf(stdout,"(%0*lx)",limitsize,word);
else {
fprintf(stdout,"(%02lu)",word);
}
#endif
out_word(sizeof(temp1024),temp1024,digits,word);
// fill leading zeroes
buf[0]='\0';
utf8getcharacter(sizeof(character),character,0,digits);
for(d=size-utf8characters(temp1024);d>0;d--) {
strcat(buf,character);
}
// rest of the number
strcat(buf,temp1024);
} else if(digits!=NULL) {
buf[0]='\0';
#ifdef DEBUG51
fprintf(stdout,"(");
#endif
// fill whole word digit by digit
for(d=0;d<size;d++) {
if(digits[0]=='0' && !zero)
e=ressu_gen_limit(digitscount-1)+1;
else
e=ressu_gen_limit(digitscount);
utf8getcharacter(sizeof(temp1024),temp1024,e,digits);
#ifdef DEBUG51
fprintf(stdout,"%s",temp1024);
if(charspaces==1)
fputc(' ',stdout);
#endif
strcat(buf,temp1024);
}
#ifdef DEBUG51
fprintf(stdout,")");
#endif
}
}
#ifdef OLD1
static void readword(unsigned char *buf)
{
int d,e;
unsigned char temp1024[1024];
if(limit!=0) {
word=0;
if(zero) {
word=ressu_gen_limit(limit); // include zeroes
#ifdef DEBUG51
if(type==2)
fprintf(stdout,"(%02lx)",word);
else if(type==8)
fprintf(stdout,"(%02lo)",word);
else if(type==10)
fprintf(stdout,"(%02ld)",word);
else if(type==16)
fprintf(stdout,"(%02lx)",word);
else
fprintf(stdout,"(%02ld)",word);
#endif
} else if(limit>=1) {
while((word=ressu_gen_limit(limit))==0); // skip zeroes
}
out_word(sizeof(temp1024),temp1024,digits,word);
// fill leading zeroes
buf[0]='\0';
utf8getcharacter(sizeof(character),character,0,digits);
for(d=size-utf8characters(temp1024);d>0;d--) {
strcat(buf,character);
}
// rest of the number
strcat(buf,temp1024);
} else if(digits!=NULL) {
buf[0]='\0';
//digitscount=utf8characters(digits);
// fill whole word digit by digit
//fprintf(stdout,"[");
for(d=0;d<size;d++) {
if(digits[0]=='0' && !zero)
e=ressu_gen_limit(digitscount-1)+1;
else
e=ressu_gen_limit(digitscount);
utf8getcharacter(sizeof(temp1024),temp1024,e,digits);
//fprintf(stdout,"%s",temp1024);
strcat(buf,temp1024);
}
//fprintf(stdout,"]");
}
}
#endif
static int line_number_length()
{
int c;
out_word_10(sizeof(linenobuf),linenobuf,lines-1);
c=strlen(linenobuf);
if(c<5)
c=5;
return(c);
}
static void print_line_number()
{
unsigned char linenobuf[32];
if(pwords==0 && slineno) {
sprintf(linenobuf,"%0*llu",plinesdigits,plines);
fprintf(stdout,"%s",linenobuf);
fprintf(stdout," ");
}
}
static int calc_spaces()
{
int spaces;
spaces=0;
if(sspace>=2 &&
// space between word groups
( (pwords>0 && pwords%sspace==0) ||
// space after linenumber
// are not printed if
// not printing linenumber
(slineno && pwords==0) ) )
spaces++;
if(sspace &&
// space between words
( (pwords>0) ||
// space after linenumber
(slineno && pwords==0) ) )
spaces++;
return(spaces);
}
static void print_spaces()
{
int sp;
for(sp=calc_spaces();sp>0;sp--)
fprintf(stdout," ");
}
static void print_word(unsigned char *buf)
{
int e;
if(size!=0) {
if(charspaces==0) {
fprintf(stdout,"%s",buf);
} else {
for(e=0;e<size;e++) {
unsigned char temp1024[1024];
utf8getcharacter(sizeof(temp1024),temp1024,e,buf);
fprintf(stdout,"%s",temp1024);
fputc(' ',stdout);
}
}
} else {
fprintf(stdout,"%s",buf);
if(charspaces==1) {
fputc(' ',stdout);
}
}
}
#ifdef OLD1
static void print_word(unsigned char *buf)
{
if(charspaces==1) {
fprintf(stdout,"%*s ",size,buf);
} else if(size!=0) {
fprintf(stdout,"%*s",size,buf);
} else {
fprintf(stdout,"%s",buf);
}
}
#endif
#ifdef SHA256
static void newressu_file_digest(char *filename,unsigned char *hash)
{
int c;
unsigned char buffer[1024];
FILE *fp1;
HashCtx ctx;
HashInit(&ctx);
if((fp1 = fopen(filename, "rb"))!=NULL) {
while((c=fread(buffer, 1, sizeof(buffer), fp1)) > 0)
HashUpdate(&ctx, buffer, c);
fclose(fp1);
}
HashFinal(hash, &ctx);
}
#endif
#define aDEBUG55 2
void digits_add_string(unsigned char **digits, char *str)
{
int digitssize;
#ifdef DEBUG55
fprintf(stdout,"\nolddigits %s",*digits);
fprintf(stdout,"\nadddigits %s",str);
#endif
digitssize=0;
if(*digits!=NULL)
digitssize+=strlen(*digits);
digitssize+=strlen(str);
*digits=realloc(*digits,digitssize+1);
strcat(*digits,str);
#ifdef DEBUG55
fprintf(stdout,"\nnewdigits %s",*digits);
fprintf(stdout,"\n");
#endif
}
void digits_add_limits(unsigned char **digits, int start, int end)
{
int c, digitssize;
unsigned char buffer[10];
#ifdef DEBUG55
fprintf(stdout,"\nolddigits %s",*digits);
fprintf(stdout,"\nadddigits start:%d, end:%d",start,end);
#endif
digitssize=0;
if(*digits!=NULL)
digitssize+=strlen(*digits);
for(c=start;c<=end;c++) {
codetoutf8(buffer,c);
digitssize+=strlen(buffer);
}
*digits=realloc(*digits,digitssize+1);
for(c=start;c<=end;c++) {
codetoutf8(buffer,c);
strcat(*digits,buffer);
}
#ifdef DEBUG55
fprintf(stdout,"\nnewdigits %s",*digits);
fprintf(stdout,"\n");
#endif
}
double getseconds()
{
struct timeval tv;
gettimeofday(&tv,NULL);
return((double)tv.tv_sec+(double)tv.tv_usec/1000000);
}
void dump_sample()
{
//sample file size = CLIM*DLIM*BLKSIZE
#define CLIM 8192 // outer loop
#define DLIM 256 // inner loop
#define BLKSIZE 4096 // block size
#define STAT_LINE_READY 2
#define STAT_LINE_NOW 2
#define STAT_LINE_ANIM 2
#define TIMEFORMAT "%H:%M %Z"
#define TIMEFORMAT2 "%a %H:%M %Z"
#define DATEFORMAT "%a %d %b %Y"
unsigned int c, d;
unsigned char buffer[BLKSIZE];
FILE *fp1;
time_t secondsstart, secondsnow;
#ifdef STAT_LINE_ANIM
long int secs, prev_secs=-1;
int crs=0;
#endif
if((fp1=fopen(samplefilename,"a")) != NULL) {
secondsstart=time(NULL);
for(c=0;c<CLIM;c++) {
secondsnow=time(NULL);
// print status line:
// blk 10, written 10MB, 269KB/sec, left 8 h 38 m, ready at Sat 17 Jul 2021 01:57:43 EEST, now Fri 17:19:32 EEST
stat_line_begin();
stat_line_printf("\rblk %d, written ",c);
stat_line_readable((unsigned long)c*DLIM*BLKSIZE);
if(c>0) {
stat_line_printf(", ");
stat_line_readable((unsigned long)((double)c*DLIM*BLKSIZE/(secondsnow-secondsstart)) );
stat_line_printf("/sec");
char timebuf[128], timebuf2[128];
#ifdef STAT_LINE_NOW
// print now
stat_line_printf(", now");
strftime(timebuf,sizeof(timebuf),TIMEFORMAT2,
localtime((time_t *)&secondsnow));
stat_line_printf(" %s",timebuf);
#endif
// print left
long int secondsleft=(int)((((double)secondsnow-secondsstart)/c)*(CLIM-c) );
long int secondsleft2;
long int temp,timeprinted=0;
secondsleft2=secondsleft;
stat_line_printf(", left");
temp=secondsleft2/(24*3600);
if(temp>0) {
timeprinted=1;
stat_line_printf(" %dd",temp);
secondsleft2-=temp*(24*3600);
}
temp=secondsleft2/3600;
if(temp>0) {
timeprinted=1;
stat_line_printf(" %dh",temp);
secondsleft2-=temp*3600;
}
temp=secondsleft2/60;
if(temp>0) {
timeprinted=1;
stat_line_printf(" %dm",temp);
secondsleft2-=temp*60;
}
temp=secondsleft2;
if(!timeprinted) {
stat_line_printf(" %d seconds",temp);
}
#ifdef STAT_LINE_READY
long int secondsend=(int)secondsstart+((((double)secondsnow-secondsstart)/c)*CLIM);
// print end date if different7
stat_line_printf(", ready at");
strftime(timebuf,sizeof(timebuf),DATEFORMAT,
localtime((time_t *)&secondsend));
strftime(timebuf2,sizeof(timebuf2),DATEFORMAT,
localtime((time_t *)&secondsnow));
if(strcmp(timebuf,timebuf2)) {
stat_line_printf(" %s",timebuf);
}
// print end time
strftime(timebuf,sizeof(timebuf),TIMEFORMAT,
localtime((time_t *)&secondsend));
stat_line_printf(" %s",timebuf);
#endif
}
stat_line_end();
// do the work
#ifdef STAT_LINE_ANIM
unsigned char cursor[4] = { '|', '/', '-', '\\' };
fprintf(stderr," ");
#endif
for(d=0;d<DLIM;d++) {
#ifdef STAT_LINE_ANIM
secs=time(NULL)%sizeof(cursor);
if(prev_secs!=secs) {
if(prev_secs!=-1)
crs=(crs+1)%sizeof(cursor);
fprintf(stderr,"\b%c",cursor[crs]);
fflush(stderr);
prev_secs=secs;
}
#endif
if(input==INPUT_RESSU) // ressu prod
ressu_genbytes(sizeof(buffer),buffer);
else if(input==INPUT_DEBUG) // ressu debug
ressu_genbytes_debug(sizeof(buffer),buffer);
else if(input==INPUT_FAST) // ressu fast
ressu_genbytes_fast(sizeof(buffer),buffer);
else if(input==INPUT_SINGLE) // ressu single
ressu_genbytes_single(sizeof(buffer),buffer);
#ifdef FORT
else if(input==INPUT_FORT) // ressu fort
fort_random_data(sizeof(buffer),buffer);
else if(input==INPUT_FORTXOR) // ressu fort
fort_random_data_xor(sizeof(buffer),buffer);
#endif
else if(input==INPUT_URANDOM) // urandom
readfile_xor(sizeof(buffer),buffer,urandomfilename);
#ifdef USE_RANDOM
else if(input==INPUT_RANDOM) // random
readfile_xor(sizeof(buffer),buffer,randomfilename);
#endif
#ifdef WRITE_SAMPLE
fwrite(buffer,1,sizeof(buffer),fp1);
#endif
} // for(d=0;
#ifdef STAT_LINE_ANIM
fprintf(stderr,"\b \b");
prev_secs=-1;
#endif
}
fclose(fp1);
} // if((fp1=fopen
// remove last status line
stat_line_begin();
stat_line_printf("Done!");
stat_line_end();
fprintf(stdout,"\n");
fflush(stdout);
}
#include <sys/ioctl.h> // for TIOCGWINSZ
#define aDEBUG50 2
#define aDEBUG71 2
void call_main(char *);
#define aCALL_MAIN 2
#define aDEBUG63 2
#ifdef CALL_MAIN
#define DEBUG99 2
int main2(int argc, char *argv[]);
void call_main(char *cmd)
{
int size, round, count, chars;
unsigned char *p, *q, *argmem,*params;
char **argv;
size = 0;
for(round = 0; round < 2; round++) {
count = 0;
p = cmd;
while(*p != '\0') {
while(*p == ' ' || *p == '\t')
p++;
q = p;
chars = 0;
while(*p != ' ' && *p != '\t' && *p != '\0') {
p++;
chars++;
}
if(round == 0) // calculate size & alloc
size += chars + 1 + sizeof(char *);
else { // move parameters to arg area
strncpy(params, q, chars);
*(argv+count) = params;
params += (chars+1);
}
count++;
}
if(round == 0) { // allocate
size += sizeof(char *); // ending NULL
argmem = malloc(size);
argv = (char **)argmem;
params = argmem + sizeof(char *) * (count+1);
}
}
*(argv+count) = NULL; // ending NULL
#ifdef DEBUG99
fprintf(stdout, "size:%d,", size);
fprintf(stdout, " argmem:");
for(int c = 0; c < size; c++) {
if(c > 0 && c%8 == 0)
fprintf(stdout, "|");
if(*(argmem+c) == '\\')
fprintf(stdout, "\\\\");
if(isprint(*(argmem+c)))
fprintf(stdout, "%c", *(argmem+c));
else
fprintf(stdout, "\\%02x", *(argmem+c));
}
fprintf(stdout, "\n");
#endif // #ifdef DEBUG99
main2(count, argv);
}
int main(int argc, char *argv[])
{
int first;
char buffer[1024];
first=1;
buffer[0]='\0';
for(int c=0;c<argc;c++) {
if(!first)
strcat(buffer," ");
strcat(buffer,argv[c]);
first=0;
}
#ifdef DEBUG99
fprintf(stdout,"main: cmd \"%s\"\n",buffer);
#endif
call_main(buffer);
}
#endif // #ifdef CALL_MAIN
#ifdef CALL_MAIN
int main2(int argc, char *argv[])
{
#ifdef DEBUG99
fprintf(stdout,"main2args:");
for(int c=0;c<argc;c++) {
fprintf(stdout," %d:\"%s\"",c,argv[c]);
}
fprintf(stdout,"\n");
#endif // #ifdef DEBUG99
#else // #ifdef CALL_MAIN
int main(int argc, char *argv[])
{
#endif // #ifdef CALL_MAIN
int c, d, status=0;
procname=argv[0];
limit=0;
#ifdef NOTUSED
for(c=0;c<100000000;c++) {
fprintf(stdout,"%d %f %f\n",c,log10((double)c),log10((double)c)+1);
}
#endif
gent_clear();
ressut_clear();
clockbytes=0;
for(d=0;d<1024;d++)
periods[d]=0;
#ifdef DEBUG63
//unsigned long l=(unsigned long)ressu_gen_limit((unsigned long)10001);
//for(;l<=0x3ffffffffff;l*=2) {
unsigned long l=1;
for(;l<=0x3ffffffffff;l*=2) {
if(l==0x9d || l==0x9e || l==0x9f)
continue;
unsigned char buffer[32];
unsigned long code;
codetoutf8(buffer, l);
utf8tocode(&code, buffer);
if(code!=l) {
fprintf(stdout,"%s: codetoutf8 and utf8tocode does not match",procname);
fprintf(stdout,", l:%ld",l);
fprintf(stdout,", code:%ld",code);
fprintf(stdout,"\n");
exit(1);
}
}
#endif
#ifdef USE_TIMER
int timer=0;
double timerstart;
#endif
// look thru command line parameters
for(c=1;c<argc;c++) {
if(!strncmp("-",argv[c],1)) {
if(!strcmp("--lineno",argv[c])) {
slineno = !slineno;
} else if(!strcmp("--crlf",argv[c])) {
scrlf = !scrlf;
slineno = 0;
} else if(!strcmp("--quiet",argv[c])) {
quiet = !quiet;
} else if(!strcmp("--stats",argv[c]) ||
!strcmp("--stat",argv[c])) {
stats = !stats;
} else if(!strcmp("--rand",argv[c])) {
digits = "0123456789";
sspace = 2;
snewline = 5;
slineno = 1;
words = 10;
chars = 0;
limit = 100000;
//size=5;
//lines=20000;
} else if(!strncmp("--space",argv[c],7)) {
if(*(argv[c]+7)!='\0' && atoi(argv[c]+7)>1) {
sspace = atoi(argv[c]+7);
} else if(c+1<argc && atoi(argv[c+1])>1) {
sspace = atoi(argv[c+1]);
c++;
} else {
sspace = !sspace;
}
} else if(!strncmp("--newline",argv[c],9)) {
if(*(argv[c]+9)!='\0' && atoi(argv[c]+9)>0) {
snewline = atoi(argv[c]+9);
} else if(c+1<argc && atoi(argv[c+1])>0) {
snewline = atoi(argv[c+1]);
c++;
}
} else if(!strcmp("--zero",argv[c])) {
zero = !zero;
} else if(!strcmp("--sort",argv[c])) {
sort = !sort;
if(sspace == 0)
sspace = 1;
} else if(!strcmp("--unique",argv[c])) {
unique =! unique;
if(sspace == 0)
sspace = 1;
} else if(!strcmp("--lotto",argv[c])) {
sort = !sort;
if(sspace==0)
sspace = 1;
//sort = 1;
//unique = 1;
} else if(!strcmp("--sample",argv[c])) {
sample = !sample;
} else if(!strcmp("--copyright",argv[c]) ||
!strcmp("--version",argv[c])) {
newressu_version();
#ifdef SHA256
unsigned char filedigest[HashLen];
newressu_file_digest("/proc/self/exe", filedigest);
fprintf(stderr,"\nsha256: ");
for(int c = 0;c < HashLen; c++) {
fprintf(stderr,"%02x", filedigest[c]);
}
#endif
fprintf(stderr,"\n\n");
help = 1;
} else if(!strncmp("--lim",argv[c],5)) {
if(*(argv[c]+5)!='\0') {
in_word(&limit, digits, argv[c]+5);
} else if(c+1<argc) {
in_word(&limit, digits, argv[c+1]);
c++;
}
if(sspace< 1 ) // 23.6.2021
sspace = 1;
} else if(!strncmp("-s",argv[c],2)) {
if(*(argv[c]+2)!='\0') {
size = atoi(argv[c]+2);
} else if(c+1<argc) {
size = atoi(argv[c+1]);
c++;
}
limit = 0; // 23.6.2021
} else if(!strncmp("--bits",argv[c],6)) {
if(*(argv[c]+6)!='\0') {
ressu_bits1_needed = atoi(argv[c]+6);
} else if(c+1<argc) {
ressu_bits1_needed = atoi(argv[c+1]);
c++;
}
} else if(!strncmp("--bytes",argv[c],7)) {
if(*(argv[c]+7)!='\0') {
ressut_bytes = atoi(argv[c]+7);
} else if(c+1<argc) {
ressut_bytes = atoi(argv[c+1]);
c++;
}
} else if(!strncmp("-w",argv[c],2)) { // words per line
if(*(argv[c]+2)!='\0') {
words = atoi(argv[c]+2);
} else if(c+1<argc) {
words = atoi(argv[c+1]);
c++;
}
if(words < 1)
words = 1;
chars = 0;
screen = 0;
} else if(!strncmp("-c*",argv[c],3)) {
struct winsize w;
ioctl(0, TIOCGWINSZ, &w);
chars = w.ws_col;
words = 0;
#ifdef DEBUG71
fprintf(stdout,"screencolumns:%d\n",chars);
#endif
} else if(!strncmp("-l*",argv[c],3)) {
struct winsize w;
ioctl(0, TIOCGWINSZ, &w);
lines = w.ws_row-1;
#ifdef DEBUG71
fprintf(stdout,"screenlines:%lld\n",lines);
#endif
} else if(!strncmp("--screen",argv[c],8)) {
struct winsize w;
ioctl(0, TIOCGWINSZ, &w);
chars = w.ws_col;
lines = w.ws_row-1;
words = 0;
screen = 1;
#ifdef DEBUG71
fprintf(stdout,"screencolumns:%d",chars);
fprintf(stdout," screenlines:%lld\n",lines);
#endif
} else if(!strncmp("-c",argv[c],2)) { // characters per line
if(*(argv[c]+2)!='\0') {
chars = atoi(argv[c]+2);
} else if(c+1<argc) {
chars = atoi(argv[c+1]);
c++;
}
if(chars < 1)
chars = 72;
words = 0;
screen = 0;
} else if(!strncmp("-l",argv[c],2)) { // lines
if(*(argv[c]+2)!='\0') {
lines = atoll(argv[c]+2);
} else if(c+1<argc) {
lines = atoll(argv[c+1]);
c++;
}
screen = 0;
} else if(!strcmp("-x",argv[c])) {
digits = "0123456789abcdef";
charspaces = 0;
charwidth = 1;
size = 4;
type = 16;
} else if(!strcmp("-X",argv[c])) {
digits = "0123456789ABCDEF";
charspaces = 0;
charwidth = 1;
size = 4;
type = 16;
} else if(!strcmp("-d",argv[c])) {
digits = "0123456789";
charspaces = 0;
charwidth = 1;
size = 5;
type = 10;
} else if(!strcmp("-o",argv[c])) {
digits = "01234567";
charspaces = 0;
charwidth = 1;
size = 3;
type = 8;
} else if(!strcmp("-b",argv[c])) {
digits = "01";
charspaces = 0;
charwidth = 1;
size = 8;
type = 2;
} else if(!strcmp("-1",argv[c])) {
digits=
"0123456789" \
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
"abcdefghijklmnopqrstuvwxyz";
charspaces = 0;
charwidth = 1;
size = 1;
type = 0;
} else if(!strcmp("-11",argv[c])) {
digits=
"0123456789";
charspaces = 0;
charwidth = 1;
size = 1;
type = 10;
} else if(!strcmp("-12",argv[c])) {
digits=
"ABCDEFGHIJKLMNOPQRSTUVWXYZ";
charspaces = 0;
charwidth = 1;
size = 1;
} else if(!strcmp("-13",argv[c])) {
digits=
"abcdefghijklmnopqrstuvwxyz";
charspaces = 0;
charwidth = 1;
size = 1;
type = 0;
} else if(!strcmp("-2",argv[c])) {
digits=
"0123456789" \
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
"abcdefghijklmnopqrstuvwxyz" \
"_-";
charspaces = 0;
charwidth = 1;
size = 8;
type = 0;
} else if(!strcmp("-3",argv[c])) { // 9.5.2021 JariK
digits=
"!\"#$%&'()*+,-./0123456789:;<=>?@" \
"ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`" \
"abcdefghijklmnopqrstuvwxyz{|}~";
charspaces = 0;
charwidth = 1;
size = 8;
type = 0;
} else if(!strcmp("--dnk",argv[c]) || // Danish alphabet
!strcmp("--nor",argv[c])) { // Norwegian alphabet
digits=
"ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ" \
"abcdefghijklmnopqrstuvwxyzæøå";
charspaces = 0;
charwidth = 1;
size = 8;
type = 0;
} else if(!strcmp("--fin",argv[c]) || // Finnish alphabet
!strcmp("--swe",argv[c])) { // Swedish alphabet
digits=
"ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ" \
"abcdefghijklmnopqrstuvwxyzåäö";
charspaces = 0;
charwidth = 1;
size = 8;
type = 0;
} else if(!strcmp("--rus",argv[c])) { // Russian alphabet
digits=
"АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ" \
"абвгдеёжзийклмнопрстуфхцчшщъыьэюя";
charspaces = 0;
charwidth = 1;
size = 8;
type = 0;
} else if(!strcmp("--est",argv[c])) { // Estonian alphabet
digits=
"ABCDEFGHIJKLMNOPQRSŠZŽTUVWÕÄÖÜXY" \
"abcdefghijklmnopqrsšzžtuvwõäöüxy";
charspaces = 0;
charwidth = 1;
size = 8;
type = 0;
} else if(!strcmp("--ltu",argv[c])) { // Lithuanian alphabet
digits=
"AĄBCČDEĘĖFGHIĮYJKLMNOPRSŠTUŲŪVZŽ" \
"aąbcčdeęėfghiįyjklmnoprsštuųūvzž";
charspaces = 0;
charwidth = 1;
size = 8;
type = 0;
} else if(!strcmp("--lva",argv[c])) { // Latvian alphabet
digits=
"AĀBCČDEĒFGĢHIĪJKĶLĻMNŅOPRSŠTUŪVZŽ" \
"aābcčdeēfgģhiījkķlļmnņoprsštuūvzž";
charspaces = 0;
charwidth = 1;
size = 8;
type = 0;
} else if(!strcmp("--fra",argv[c]) // French alphabet
||!strcmp("--gbr",argv[c]) // Great Britain alphabet
||!strcmp("--usa",argv[c]) // United States alphabet
||!strcmp("--ita",argv[c]) // Italian alphabet
||!strcmp("--eng",argv[c]) // English alphabet
) {
digits=
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
"abcdefghijklmnopqrstuvwxyz";
charspaces = 0;
charwidth = 1;
size = 8;
type = 0;
} else if(!strcmp("--deu",argv[c])) { // Deutsch alphabet
digits=
"ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜẞ" \
"abcdefghijklmnopqrstuvwxyzäöüß";
charspaces = 0;
charwidth = 1;
size = 8;
type = 0;
} else if(!strcmp("--grc",argv[c])) { // Greek alphabet
digits=
"ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ" \
"αβγδεζηθικλμνξοπρστυφχψω";
charspaces = 0;
charwidth = 1;
size = 8;
type = 0;
} else if(!strcmp("--jp",argv[c])) { // all Japanese alphabets
digits = NULL;
digits_add_string(&digits,
"ぁあぃいぅうぇえぉおかがきぎく"
"ぐけげこごさざしじすずせぜそぞた"
"だちぢっつづてでとどなにぬねのは"
"ばぱひびぴふぶぷへべぺほぼぽまみ"
"むめもゃやゅゆょよらりるれろゎわ"
"ゐゑをんゔゕゖ");
digits_add_string(&digits,
"゠ァアィイゥウェエォオカガキギク"
"グケゲコゴサザシジスズセゼソゾタ"
"ダチヂッツヅテデトドナニヌネノハ"
"バパヒビピフブプヘベペホボポマミ"
"ムメモャヤュユョヨラリルレロヮワ"
"ヰヱヲンヴヵヶヷヸヹヺ・ーヽヾヿ");
digits_add_limits(&digits,0x4e00,0x9fef);
digitsext = digits;
charspaces = 0;
charwidth = 2;
size = 8;
type = 0;
} else if(!strcmp("--jp1",argv[c]) // Japanese hiragana alphabet
||!strcmp("--hir",argv[c])) { // Japanese hiragana alphabet
digits=
"ぁあぃいぅうぇえぉおかがきぎく"
"ぐけげこごさざしじすずせぜそぞた"
"だちぢっつづてでとどなにぬねのは"
"ばぱひびぴふぶぷへべぺほぼぽまみ"
"むめもゃやゅゆょよらりるれろゎわ"
"ゐゑをんゔゕゖ";
charspaces = 0;
charwidth = 2;
size = 8;
type = 0;
} else if(!strcmp("--jp2",argv[c]) // Japanese katakana alphabet
||!strcmp("--kat",argv[c])) { // Japanese katakana alphabet
digits=
"゠ァアィイゥウェエォオカガキギク"
"グケゲコゴサザシジスズセゼソゾタ"
"ダチヂッツヅテデトドナニヌネノハ"
"バパヒビピフブプヘベペホボポマミ"
"ムメモャヤュユョヨラリルレロヮワ"
"ヰヱヲンヴヵヶヷヸヹヺ・ーヽヾヿ";
charspaces = 0;
charwidth = 2;
size = 8;
type = 0;
} else if(!strcmp("--cn",argv[c]) // Chinese alphabet
||!strcmp("--jp3",argv[c]) // Japanese kanji alphabet
||!strcmp("--kan",argv[c])) { // Japanese kanji alphabet
digits = NULL;
digits_add_limits(&digits,0x4e00,0x9fef);
digitsext = digits;
charspaces = 0;
charwidth = 2;
size = 8;
type = 0;
} else if(!strcmp("--kor",argv[c])) { // Korean alphabet
digits = NULL;
digits_add_limits(&digits,0xac00,0xd7a3); // Hangul Syllables (AC00–D7A3)
//digits_add_limits(&digits,0x1100,0x11ff); // Hangul Jamo (1100–11FF)
//digits_add_limits(&digits,0x3130,0x318f); // Hangul Compatibility Jamo (3130–318F)
//digits_add_limits(&digits,0xa960,0xa97f); // Hangul Jamo Extended-A (A960–A97F)
//digits_add_limits(&digits,0xd7b0,0xd7ff); //Hangul Jamo Extended-B (D7B0–D7FF)
digitsext = digits;
charspaces = 0;
charwidth = 2;
size = 8;
type = 0;
} else if(!strcmp("--got",argv[c])) { // Greek alphabet
digits=
"𐌰𐌱𐌲𐌳𐌴𐌵𐌶𐌷𐌸𐌹𐌺𐌻𐌼𐌽𐌾𐌿"
"𐍀𐍁𐍂𐍃𐍄𐍅𐍆𐍇𐍈𐍉𐍊";
charspaces = 0;
charwidth = 1;
size = 8;
type = 0;
} else if(!strcmp("--cards",argv[c])) {
digits=
"🂡🂢🂣🂤🂥🂦🂧🂨🂩🂪🂫🂭🂮" \
"🂱🂲🂳🂴🂵🂶🂷🂸🂹🂺🂻🂽🂾" \
"🃁🃂🃃🃄🃅🃆🃇🃈🃉🃊🃋🃍🃎" \
"🃑🃒🃓🃔🃕🃖🃗🃘🃙🃚🃛🃝🃞";
charspaces = 1;
charwidth = 2;
size = 1;
type = 0;
} else if(!strcmp("--cardsuits",argv[c])) {
digits=
"♠♡♢♣♤♥♦♧";
charspaces = 1;
charwidth = 2;
size = 1;
type = 0;
} else if(!strcmp("--chess",argv[c])) {
digits=
"♔♕♖♗♘♙♚♛♜♝♞♟";
charspaces = 1;
charwidth = 2;
size = 1;
type = 0;
} else if(!strcmp("--pattern1",argv[c])) {
digits=
"▌▙▄";
charspaces = 0;
charwidth = 1;
size = 1;
type = 0;
} else if(!strcmp("--pattern2",argv[c])) {
digits=
"◜◝◞◟";
charspaces = 0;
charwidth = 1;
size = 1;
type = 0;
} else if(!strcmp("--pattern3",argv[c])) {
digits=
"\\/";
charspaces = 0;
charwidth = 1;
size = 1;
type = 0;
} else if(!strcmp("--pattern4",argv[c])) {
digits=
"◸◹◺◿";
charspaces = 1;
charwidth = 2;
size = 1;
type = 0;
} else if(!strcmp("--pattern5",argv[c])) {
digits=
"▧▨";
charspaces = 1;
charwidth = 2;
size = 1;
type = 0;
} else if(!strcmp("--isalnum",argv[c]) || // 9.5.2021 JariK
!strcmp("--isalpha",argv[c]) ||
!strcmp("--isdigit",argv[c]) ||
!strcmp("--isgraph",argv[c]) ||
!strcmp("--islower",argv[c]) ||
!strcmp("--isprint",argv[c]) ||
!strcmp("--ispunct",argv[c]) ||
!strcmp("--isupper",argv[c]) ||
!strcmp("--isxdigit",argv[c])) {
unsigned char *p=digitstemp;
for(d=0;d<256;d++) {
if((!strcmp("--isalnum",argv[c]) && isalnum(d)) ||
(!strcmp("--isalpha",argv[c]) && isalpha(d)) ||
(!strcmp("--isdigit",argv[c]) && isdigit(d)) ||
(!strcmp("--isgraph",argv[c]) && isgraph(d)) ||
(!strcmp("--islower",argv[c]) && islower(d)) ||
(!strcmp("--isprint",argv[c]) && isprint(d)) ||
(!strcmp("--ispunct",argv[c]) && ispunct(d)) ||
(!strcmp("--isupper",argv[c]) && isupper(d)) ||
(!strcmp("--isxdigit",argv[c]) && isxdigit(d))) {
*p++=d;
}
}
*p='\0';
digits = digitstemp;
size = 8;
type = 0;
} else if(!strncmp("-i",argv[c],2)) {
digits=NULL;
if(*(argv[c]+2)!='\0') {
digits = argv[c]+2;
} else if(c+1 < argc) {
digits = argv[c+1];
c++;
}
if(digits==NULL || utf8characters(digits)<2) {
fprintf(stderr,"%s: not enough digits \"%s\"\n",procname,argv[c]);
help = 1;
}
size = 1;
#ifdef USE_TIMER
} else if(!strcmp("--timer",argv[c])) {
timer=1;
#endif
} else if(!strcmp("--ressu",argv[c])) {
input = INPUT_RESSU;
} else if(!strcmp("--debug",argv[c])) {
input = INPUT_DEBUG;
} else if(!strcmp("--fast",argv[c])) {
input = INPUT_FAST;
} else if(!strcmp("--single",argv[c])) {
input = INPUT_SINGLE;
#ifdef FORT
} else if(!strcmp("--fort",argv[c])) {
input = INPUT_FORT;
} else if(!strcmp("--fortxor",argv[c])) {
input = INPUT_FORTXOR;
} else if(!strcmp("--fortverbose",argv[c])) {
fort_verbose = !fort_verbose;
} else if(!strcmp("--fortuseweb",argv[c])) {
fort_use_web = !fort_use_web;
#endif
} else if(!strcmp("--urandom",argv[c])) {
input = INPUT_URANDOM;
#ifdef USE_RANDOM
} else if(!strcmp("--random",argv[c])) {
input = INPUT_RANDOM;
#endif
} else {
fprintf(stderr,"%s: invalid option %s\n",procname,argv[c]);
status = 1;
help = 1;
}
} else {
help = 1;
} // if(!strncmp
} // for(c=0
if(size == 0)
size = 1;
else if(size > 1024)
size = 1024;
if(lines < 1)
lines = 1;
#ifdef USE_TIMER
timerstart=getseconds();
#endif
digitscount = utf8characters(digits);
characterlengths = utf8lengths(digits);
#ifdef FORT
if(input == INPUT_FORT ||
input == INPUT_FORTXOR ) {
strcpy(fort_random_file, "newressufort.rnd");
//fort_verbose=0;
fort_init();
}
#endif
if(sample) {
dump_sample();
exit(status);
} // if(sample)
// get linenumber length in digits
plinesdigits = line_number_length();
// get data length in digits
if(limit != 0) {
unsigned char wordbuf[128];
out_word(sizeof(wordbuf), wordbuf, digits, limit-1);
size = utf8characters(wordbuf);
}
pchars = 0;
pwords = 0;
int linew = 0;
// in beginning of line, count printed line number
if(!quiet && slineno) {
sprintf(linenobuf,"%0*llu", plinesdigits, plines);
pchars += strlen(linenobuf);
pchars++;
}
// count words
while((chars > 0 && pchars+size*charwidth+calc_spaces() <= chars) ||
(words > 0 && pwords < words)) {
linew++;
#ifdef DEBUG50
fprintf(stdout,"spaces:%d", calc_spaces());
#endif
pchars += calc_spaces();
pchars += (size*charwidth);
pwords++;
#ifdef DEBUG50
fprintf(stdout,", chars:%d", chars);
fprintf(stdout,", pchars:%d", pchars);
fprintf(stdout,", words:%d", words);
fprintf(stdout,", pwords:%d", pwords);
fprintf(stdout,"\n");
#endif
}
// one data word needed
if(linew < 1)
linew = 1;
unsigned long wordvalues=1, wordvaluesold;
for(c = 0; c < size; c++) {
wordvaluesold = wordvalues;
wordvalues *= digitscount;
if(wordvalues / digitscount != wordvaluesold) {
wordvalues = 0;
break;
}
}
if(limit > 0) {
if(sort==1 && limit-!zero < words) {
fprintf(stderr,"%s: limit is less than words (zero)", procname);
fprintf(stderr,", limit:%lu", limit);
fprintf(stderr,", words:%d", words);
fprintf(stderr,", zero:%d", zero);
fprintf(stderr,"\n");
help = 1;
lines = 0;
}
} else {
if(sort == 1 && size > 0 && wordvalues > 0 && wordvalues < linew) {
fprintf(stderr,"%s:", procname);
fprintf(stderr," digits is less than calculated words");
fprintf(stderr,", digits:%d(%lu)", digitscount, wordvalues);
fprintf(stderr,", words:%d\n", linew);
help = 1;
lines = 0;
}
}
// "small" words as single ressu_gen_limit() call
if(limit == 0 && wordvalues > 0)
limit = wordvalues;
#ifdef DEBUG51
unsigned char buffer10[10];
if(type==2)
sprintf(buffer10,"%2lx",limit-1);
else if(type==8)
sprintf(buffer10,"%2lo",limit-1);
else if(type==10)
sprintf(buffer10,"%2ld",limit-1);
else if(type==16)
sprintf(buffer10,"%2lx",limit-1);
else
sprintf(buffer10,"%2ld",limit-1);
limitsize=strlen(buffer10);
#endif
if(stats) {
fprintf(stdout,"randomsource: %s", randomgen[input]);
fprintf(stdout,", size: %d", size);
fprintf(stdout,", linew: %d", linew);
fprintf(stdout,", pchars: %d", pchars);
fprintf(stdout,", pwords: %d", pwords);
fprintf(stdout,", tchars: %llu", (unsigned long long)size*linew*lines);
fprintf(stdout,", digitscount: %d", digitscount);
if(wordvalues > 0)
fprintf(stdout,", wordvalues: %lu", wordvalues);
if(limit > 0) {
fprintf(stdout,", limit: %lu", limit);
#ifdef DEBUG51
fprintf(stdout,", type: %d",type);
fprintf(stdout,", limitsize%d: %d",type,limitsize);
#endif
}
fprintf(stdout,"\n");
}
if(help) {
struct helpline {
char *command;
char *text;
} helplines[] = {
{ "newressu -d", "print random decimal digits (default)" },
{ "newressu -o", "print octal digits" },
{ "newressu -x", "print hexadecimal digits" },
{ "newressu -b", "print binary digits" },
{ "newressu -d --space", "print decimal digits, with spaces between \"words\"" },
{ "newressu -b --space", "print binary digits, with spaces between \"words\"" },
{ "newressu -d -l30", "print decimal digits, 30 lines" },
{ "newressu -d -l30 --lineno", "print decimal digits, 30 lines, no linenumbers" },
{ "newressu --rand", "print numbers in rand style listing" },
{ "newressu --space 2", "print numbers in 2 number groups" },
{ "newressu --newline 5", "print numbers in 5 line groups" },
{ "newressu -l*", "fill all screen lines" },
{ "newressu -c*", "fill all screen columns" },
{ "newressu --screen", "fill screen columns and lines" },
{ "newressu -d -c128", "print decimal digits, 128 characters per line" },
{ "newressu -d --lim10", "print decimal numbers between 0-9" },
{ "newressu -d --lim10 -x","print hexadecimal numbers with decimal limit" },
{ "newressu -d -s10 --space","print decimal numbers with spaces and wordsize 10" },
{ "newressu -d --space --zero --lim7","print rollings of dice (1-6)" },
{ "newressu -b -s1 --space","print throws of coin (0,1)" },
{ "newressu -d --lim41 -w7 --zero --lotto","print lotto numbers for finnish lotto 7x(1-40)" },
{ "newressu -d -s5 --sort -w16","print 16 sorted decimal numbers from 0 to 99999" },
{ "newressu --isalnum", "print alphanumeric characters" },
{ "newressu --isalpha", "print alphabetic characters" },
{ "newressu --isgraph", "print printables excluding space" },
{ "newressu --islower", "print lowercase characters" },
{ "newressu --ispunct", "print punctuation characters" },
{ "newressu --isupper", "print uppercase characters" },
{ "newressu -1", "print material for passwords" },
{ "newressu --dnk/--nor", "danish/norwegian alphabet" },
{ "newressu --fin/--swe", "finnish/norwegian alphabet" },
{ "newressu --rus", "russian alphabet" },
{ "newressu --est", "estonian alphabet" },
{ "newressu --ltu", "lithuanian alphabet" },
{ "newressu --lva", "latvian alphabet" },
{ "newressu --fra/--gbr/--usa/--ita", "french/gb/us/italian alphabet" },
{ "newressu --deu", "deutsch alphabet" },
{ "newressu --grc", "greek alphabet" },
{ "newressu --jp", "japan alphabet (hiragana, katakana, kanji) " },
{ "newressu --jp1/--hir", "japan alphabet (hiragana) " },
{ "newressu --jp2/--kat", "japan alphabet (katakana) " },
{ "newressu --jp3/--kan", "japan alphabet (kanji) " },
{ "newressu --cn", "chinese alphabet" },
{ "newressu --kor", "korean alphabet" },
{ "newressu --got", "gothic alphabet" },
{ "newressu --cards", "playing cards" },
{ "newressu --cardsuits", "playing card suits" },
{ "newressu --chess", "chess men" },
{ "newressu -i▌▙▄ / --pattern1", "print pattern1" },
{ "newressu -i\\\\/ / --pattern2", "print pattern2" },
{ "newressu --ressu", "use randomness from ressu (default)" },
{ "newressu --debug", "use randomness from debugging ressu" },
{ "newressu --fast", "use randomness from fast ressu" },
{ "newressu --single", "use randomness from single round of ressu" },
#ifdef FORT
{ "newressu --fort", "use randomness from fort" },
#endif
{ "newressu --urandom", "use randomness from /dev/urandom" },
#ifdef USE_RANDOM
{ "newressu --random", "use randomness from /dev/random" },
#endif
};
for(c = 0; c < sizeof(helplines) / sizeof(helplines[0]); c++) {
fprintf(stderr,"%-50s", helplines[c].text);
fprintf(stderr,"%-25s", helplines[c].command);
fprintf(stderr,"\n");
}
for(c = 0; c < chars; c++)
fprintf(stdout, "*");
fprintf(stdout, "\n");
if(lines > 1)
lines = 1; // print one line below help as a sample
}
if(lines == 0)
exit(status);
int linecnt = 0;
unsigned char *line = NULL;
unsigned char wordbuf[1025];
for(;;) {
if(!sort) { // no sort, no lotto
pwords = 0;
while(pwords < linew) {
readword(wordbuf);
if(!quiet) {
if(newressu_output) {
fprintf(stdout, "\n");
newressu_output = 0;
}
// in beginning of line, print line number
print_line_number();
// want to print spaces between "words"?
print_spaces();
// print word
print_word(wordbuf);
}
pwords++;
} // while(pwords<linew) {
} else { // if(!sort)
pwords = 0;
line_clear(&linecnt, &line);
// fetch and save words on this row
while(pwords < linew) {
readword(wordbuf);
if(line_add_string_sort(&linecnt, &line, wordbuf)) {
pwords++;
}
} // while(pwords<linew) {
pwords = 0;
// print words on this row
while(pwords < linew) {
line_get_string(sizeof(wordbuf), wordbuf, pwords, line);
if(!quiet) {
if(newressu_output) {
fprintf(stdout, "\n");
newressu_output = 0;
}
// in beginning of line, print line number
print_line_number();
// want to print spaces between "words"?
print_spaces();
// print word
print_word(wordbuf);
}
pwords++;
} // while(pwords<linew) {
} // if(!sort)
if(!quiet) {
fprintf(stdout, "\n");
}
plines++;
ptotallines++;
// print empty line
if(!quiet &&
snewline > 0 &&
plines%snewline == 0) {
// if screenfull printed, use
// total lines (contains also
// empty lines), if not
// screenfull use printed
// lines (without empty lines)
if((screen && ptotallines < lines) ||
(!screen && plines < lines)) {
fprintf(stdout, "\n");
ptotallines++;
}
}
newressu_output = 0;
// all needed lines printed?
if(screen && snewline > 0 &&
ptotallines >= lines)
break;
if(plines >= lines)
break;
} // for(;;)
#ifdef USE_TIMER
if(timer) {
// run time 1565 seconds, 0.000782 seconds/line (decimal)
// run time 6538 seconds, 0.003269 seconds/line (--ch)
// run time 1954 seconds, 0.000977 seconds/line (--ch digitscount)
// run time 1814 seconds, 0.000907 seconds/line (--ch digitscount)
// run time 1540 seconds, 0.000770 seconds/line (decimal)
// run time 2196 seconds, 0.001098 seconds/line (--got)
// run time 1536 seconds, 0.000768 seconds/line (decimal)
// run time 2008 seconds, 0.001004 seconds/line (--jp)
// run time 2043 seconds, 0.001022 seconds/line (--jp)
double timertook=getseconds()-timerstart;
fprintf(stdout,"run time %f seconds",
timertook);
fprintf(stdout,", %lld lines",
plines);
fprintf(stdout,", %f useconds/line",
timertook*1000000/plines);
fprintf(stdout,", %d characters/line",
pwords*size);
fprintf(stdout,", %f useconds/character",
(timertook*1000000/plines)/(pwords*size) );
fprintf(stdout,"\n");
}
#endif
fflush(stdout);
if(digitsext != NULL)
free(digitsext);
#ifdef FORT
if(input == INPUT_FORT ||
input == INPUT_FORTXOR) {
fort_save();
}
#endif
exit(status);
}
#endif // MAIN
fort.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#include <sys/time.h>
#include <errno.h>
#include <openssl/ssl.h>
#include "sha256.h"
#include "newressu.h"
extern unsigned char *procname;
static unsigned char *programname = "fort version 0.52 ©";
static unsigned char *copyright = "Copyright (c) 2020-2022 Jari Kuivaniemi, Helsinki, Finland. Kaikki oikeudet pidätetään!";
#define FORT_INTERNAL_EVENTS 2
#define aDEBUG10 2
#define aDEBUG18 2
#define FORT_XOR_VERSION 2
#define FORT_ORIGINAL_VERSION 2
#include "fort.h"
int fort_events = 1;
int fort_verbose = 0;
int fort_use_web=0;
#define DEBUG 2
#define FORT_MIN_POOL_SIZE 64
static unsigned int fort_internal_events = 1;
static unsigned int fort_internal_event_mode = 1;
#define FORT_USE_WEB 2
#define FORT_USE_URANDOM 2
#define aFORT_USE_RANDOM 2
#define FORT_USE_NEWRESSU_COMMAND 2
unsigned char fort_random_file[128] = "fort.rnd";
#ifdef DEBUG10
static int event_id = 0;
static char fort_events_file[128] = "fortevents.deb";
#endif
// Additional secrets to fort
// (Adversary must guess these too)
#define ADDITIONAL_SECRETS 2
#ifdef ADDITIONAL_SECRETS
static char fort_secret_file[128] = "fortsecret.rnd";
unsigned char *programsecret = "OHUwiVmwm8HlqNhKxPi9rdt_8lm4jXI8hi-FCntPAQN_UXOyt4s6zQnRo__ySAd1";
#endif
#define FORT_64_POOLS 2
#ifdef FORT_64_POOLS
#define FORT_POOLS 64
typedef unsigned long FORT_COUNTER;
#else
#define FORT_POOLS 32
typedef unsigned int FORT_COUNTER;
#endif
void fort_mix();
#define aDEBUG6 2
unsigned char cvar[16];
int cvarsize=0;
void inccvar()
{
int c;
/* 16 bytes, LSB first */
for(c=0;++cvar[c] == 0 && c < sizeof(cvar)-1;c++);
#ifdef OLD1
c=0;
while(++cvar[c] == 0 && c < sizeof(cvar)-1)
c++;
#endif
if(cvarsize<c)
cvarsize=c;
#ifdef DEBUG6
if(newressu_output==1)
fprintf(stdout,"\n");
fprintf(stdout,"cvar ");
for(int d=cvarsize;d>=0;d--) // in reverse
fprintf(stdout,"%02x",cvar[d]);
newressu_output=1;
#endif
}
void clearcvar()
{
int c;
for(c = 0; c < sizeof(cvar); c++)
cvar[c] = 0;
}
void hash_update_cvar(HashCtx *hash)
{
hash_update(hash, (unsigned char *)&cvar,
cvarsize+1);
inccvar();
}
static IUTIME gettenths()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return((IUTIME)tv.tv_sec*10 +
(int)tv.tv_usec/100000);
}
static IUTIME getmicroseconds()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return((IUTIME)tv.tv_sec*1000000 +
tv.tv_usec);
}
static IUTIME getseconds()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return((IUTIME)tv.tv_sec);
}
struct fort_pool {
unsigned long length;
HashCtx pool;
};
static struct fort_pool fort_pools[FORT_POOLS];
void fort_add_random_event(int *pool, int source, int mode, int len, unsigned char *buf)
{
while(len>1 && buf[len-1]==0)
len--;
HashUpdate(&fort_pools[*pool].pool, buf, len);
fort_pools[*pool].length+=len; // (unsigned long)2097152*16384;
#ifdef DEBUG10
if(event_id < 65536) {
FILE *fp1;
if((fp1=fopen(fort_events_file, "a"))!=NULL) {
fprintf(fp1,"id=%d", event_id);
fprintf(fp1,", source=%02d", source);
fprintf(fp1,", pool=%02d", *pool);
fprintf(fp1,", mode=%d", mode);
fprintf(fp1,", len=%d", len);
fprintf(fp1,", data=");
for(int c=0;c<len;c++)
fprintf(fp1,"%02x", buf[c]);
fprintf(fp1,"\n");
fflush(fp1);
fclose(fp1);
event_id++;
}
}
#endif
switch(mode) {
case 1:
(*pool) = ((*pool)+1) % FORT_POOLS;
break;
case 3:
break; // caller decides next pool
}
}
void fort_add_random_event_timer_start(IUTIME *micros)
{
*micros = getmicroseconds();
}
void fort_add_random_event_timer_do(int *pool, int source, int mode, IUTIME *micros)
{
unsigned char temp[2];
IUTIME t;
t = getmicroseconds()-*micros;
temp[0] = t & 0xff;
temp[1] = (t>>8) & 0xff;
fort_add_random_event(pool, source, mode,
sizeof(temp), temp);
}
void fort_add_random_event_time(int *pool, int source, int mode)
{
int len;
unsigned char temp[2];
IUTIME t;
static int prev_second=-1;
t = getmicroseconds();
temp[0] = t & 0xff;
temp[1] = (t>>8) & 0xff;
len=2;
if(prev_second==temp[1]) {
len--;
} else {
prev_second=temp[1];
}
fort_add_random_event(pool, source, mode,
len, temp);
}
void fort_add_random_event_split(int *pool, int source, int mode, int len, unsigned char *buf, int size)
{
int n;
while(len != 0) {
n = (size<len)? size:len;
fort_add_random_event(pool, source,
mode, n, buf);
buf += n;
len -= n;
}
}
#define aDEBUG18 2
void hash_init(HashCtx *hash)
{
FORT_INTERNAL_EVENTS_START(10)
HashInit(hash);
#ifdef DEBUG18
fprintf(stdout,"init\n");
#endif
FORT_INTERNAL_EVENTS_END(11)
}
void hash_update(HashCtx *hash, unsigned char *data, int len)
{
FORT_INTERNAL_EVENTS_START(12)
HashUpdate(hash, data, len);
#ifdef DEBUG18
fprintf(stdout,"data ");
for(int d=0;d<len;d++)
fprintf(stdout,"%02x",data[d]);
fprintf(stdout,"\n");
#endif
FORT_INTERNAL_EVENTS_END(13)
}
void hash_final(unsigned char digest[HashLen], HashCtx *hash)
{
FORT_INTERNAL_EVENTS_START(14)
HashFinal(digest, hash);
#ifdef DEBUG18
fprintf(stdout,"digest ");
for(int d=0;d<HashLen;d++)
fprintf(stdout,"%02x",digest[d]);
fprintf(stdout,"\n");
#endif
FORT_INTERNAL_EVENTS_END(15)
}
static unsigned char fort_key[HashLen];
void fort_rekey(unsigned char *digest)
{
HashCtx hash;
FORT_INTERNAL_EVENTS_START(16)
hash_init(&hash);
hash_update(&hash, fort_key, sizeof(fort_key));
hash_update_cvar(&hash);
hash_final(digest, &hash);
// Forget hash
memset(&hash, 0, sizeof(hash));
FORT_INTERNAL_EVENTS_END(17)
}
#define FORT_PSEUDO_LIMIT 1048576
// use
// $ ./newressu --fort -x -w32 -s2 -l2000 --space | more
// to debug...
// choose one of
// 60 (1 minute)
// 300 (5 minutes)
// 600 (10 minutes)
// 900 (15 minutes)
// 1200 (20 minutes)
// 1800 (30 minutes)
// 3600 (hour)
// 7200 (2 hours)
// 10800 (3 hours)
// 14400 (4 hours)
// 21600 (6 hours)
// 28800 (8 hours)
// 43200 (12 hours)
// 86400 (24 hours)
// to get readable report..
#define FORT_SECONDS_BETWEEN_SAVES 10*60
static IUTIME fort_next_save = 0;
#define TIMEFORMAT "%Z%Y%m%d%H%M%S"
void fort_save();
static char current_timezone[10];
#define aDEBUG22 2
void fort_reseed(int len, unsigned char *buf)
{
HashCtx hash;
FORT_INTERNAL_EVENTS_START(22)
hash_init(&hash);
hash_update(&hash, fort_key, sizeof(fort_key));
hash_update_cvar(&hash);
hash_update(&hash, buf, len);
#ifdef DEBUG22
fprintf(stdout,"\nprevkey ");
for(int d=0;d<sizeof(fort_key);d++)
fprintf(stdout,"%02x",fort_key[d]);
fprintf(stdout,"\ncvar ");
for(int d=0;d<cvarsize+1;d++)
fprintf(stdout,"%02x",cvar[d]);
fprintf(stdout,"\ndata ");
for(int d=0;d<HashLen;d++)
fprintf(stdout,"%02x",buf[d]);
fprintf(stdout,"\ndata asc ");
for(int d=0;d<len;d++) {
if(isprint(buf[d]))
fprintf(stdout,"%c",buf[d]);
else
fprintf(stdout,"\\%02x",buf[d]);
}
#endif
hash_final(fort_key, &hash);
#ifdef DEBUG22
fprintf(stdout,"\nnewkey ");
for(int d=0;d<sizeof(fort_key);d++)
fprintf(stdout,"%02x",fort_key[d]);
fprintf(stdout,"\n");
#endif
memset(&hash, 0, sizeof(hash));
if(fort_next_save != 0) {
IUTIME seconds;
seconds = getseconds();
char timezone[10];
strftime(timezone, sizeof(timezone), "%Z",
localtime((time_t *)&seconds) );
if(strcmp(current_timezone,timezone)) {
fort_next_save=1;
strcpy(current_timezone,timezone);
}
if(fort_next_save != 0 &&
seconds >= fort_next_save) {
IUTIME diff=
timegm(localtime((time_t *)&seconds))-seconds;
fort_next_save = seconds -
((seconds+diff) %
FORT_SECONDS_BETWEEN_SAVES) +
FORT_SECONDS_BETWEEN_SAVES;
fort_save();
}
}
FORT_INTERNAL_EVENTS_END(23)
}
static FORT_COUNTER fort_reseed_count = 0;
static IUTIME fort_next_reseed = 0;
#define aDEBUG28 2
#ifdef FORT_ORIGINAL_VERSION
void fort_pseudo_random_data(int len,
unsigned char *buf)
{
unsigned char digest[HashLen];
unsigned int n, blockbytes;
#ifdef DEBUG28
int d=0;
#endif
FORT_INTERNAL_EVENTS_START(18)
blockbytes = 0;
while(len != 0) {
FORT_INTERNAL_EVENTS_START(19)
fort_rekey(digest);
n = (len<HashLen) ? len : HashLen;
#ifdef DEBUG28
fprintf(stdout,"\nbuf(%02x): ",d++);
for(int c=0;c<n;c++)
fprintf(stdout,"%02x",buf[c]);
fprintf(stdout,"\ndigest: ");
for(int c=0;c<n;c++)
fprintf(stdout,"%02x",digest[c]);
fprintf(stdout,"\nsum: ");
for(int c=0;c<n;c++)
fprintf(stdout,"%02x",buf[c]^digest[c]);
fprintf(stdout,"\n");
#endif // #ifdef DEBUG18
memcpy(buf, digest, n);
buf += n;
len -= n;
blockbytes += n;
// rekey every 1048576 bytes if data left
if(blockbytes >= FORT_PSEUDO_LIMIT &&
len > 0) {
fort_rekey(fort_key);
blockbytes = 0;
}
FORT_INTERNAL_EVENTS_END(20)
}
fort_rekey(fort_key);
// Forget last bytes
memset(digest, 0, sizeof(digest));
FORT_INTERNAL_EVENTS_END(21)
}
#define aDEBUG34 2
void fort_random_data(int len, unsigned char *buf)
{
int c;
IUTIME tenths;
HashCtx hash;
unsigned char digest[HashLen];
FORT_INTERNAL_EVENTS_START(24)
tenths=gettenths();
if( (fort_next_reseed == 0) ||
(fort_next_reseed <= tenths &&
fort_pools[0].length >=
FORT_MIN_POOL_SIZE) ) {
fort_mix();
// next tenth of a second
fort_next_reseed = tenths + 1;
fort_reseed_count++;
hash_init(&hash);
c=0;
while(c < FORT_POOLS && (fort_reseed_count
% (1<<c)) == 0) {
FORT_INTERNAL_EVENTS_START(25)
hash_final(digest, &fort_pools[c].pool);
#ifdef DEBUG34
fprintf(stdout,"\ndata %2d ",c);
for(int d=0;d<HashLen;d++)
fprintf(stdout,"%02x",digest[d]);
#endif
hash_update(&hash, digest, sizeof(digest));
fort_pools[c].length = 0;
HashInit(&fort_pools[c].pool);
// save earlier pool to new one
hash_update(&fort_pools[c].pool,
digest, sizeof(digest));
c++;
FORT_INTERNAL_EVENTS_END(26)
}
hash_update_cvar(&hash);
hash_final(digest, &hash);
#ifdef DEBUG34
fprintf(stdout,"\ndigest ");
for(int d=0;d<HashLen;d++)
fprintf(stdout,"%02x",digest[d]);
fprintf(stdout,"\n");
#endif
fort_reseed(sizeof(digest), digest);
// Forget hash context
memset(&hash, 0, sizeof(hash));
// Forget reseed key
memset(digest, 0, sizeof(digest));
}
fort_pseudo_random_data(len, buf);
FORT_INTERNAL_EVENTS_END(27)
}
#endif // #ifdef FORT_ORIGINAL_VERSION
#ifdef FORT_XOR_VERSION
void fort_pseudo_random_data_xor(int len,
unsigned char *buf)
{
unsigned char digest[HashLen];
unsigned int n, blockbytes;
#ifdef DEBUG28
int d=0;
#endif
FORT_INTERNAL_EVENTS_START(18)
blockbytes = 0;
while(len != 0) {
FORT_INTERNAL_EVENTS_START(19)
fort_rekey(digest);
n = (len<HashLen) ? len : HashLen;
#ifdef DEBUG28
fprintf(stdout,"\nbuf(%02x): ",d++);
for(int c=0;c<n;c++)
fprintf(stdout,"%02x",buf[c]);
fprintf(stdout,"\ndigest: ");
for(int c=0;c<n;c++)
fprintf(stdout,"%02x",digest[c]);
fprintf(stdout,"\nsum: ");
for(int c=0;c<n;c++)
fprintf(stdout,"%02x",buf[c]^digest[c]);
fprintf(stdout,"\n");
#endif
for(int c=0;c<n;c++)
buf[c]^=digest[c];
buf += n;
len -= n;
blockbytes += n;
// rekey every 1048576 bytes if data left
if(blockbytes >= FORT_PSEUDO_LIMIT &&
len > 0) {
fort_rekey(fort_key);
blockbytes = 0;
}
FORT_INTERNAL_EVENTS_END(20)
}
fort_rekey(fort_key);
// Forget last bytes
memset(digest, 0, sizeof(digest));
FORT_INTERNAL_EVENTS_END(21)
}
void fort_random_data_xor(int len, unsigned char *buf)
{
int c;
IUTIME tenths;
HashCtx hash;
unsigned char digest[HashLen];
FORT_INTERNAL_EVENTS_START(24)
tenths=gettenths();
if( (fort_next_reseed == 0) ||
(fort_next_reseed <= tenths &&
fort_pools[0].length >=
FORT_MIN_POOL_SIZE) ) {
fort_mix();
// next tenth of a second
fort_next_reseed = tenths + 1;
fort_reseed_count++;
hash_init(&hash);
c=0;
while(c < FORT_POOLS && (fort_reseed_count
% (1<<c)) == 0) {
FORT_INTERNAL_EVENTS_START(25)
hash_final(digest, &fort_pools[c].pool);
#ifdef DEBUG34
fprintf(stdout,"\ndata %2d ",c);
for(int d=0;d<HashLen;d++)
fprintf(stdout,"%02x",digest[d]);
#endif
hash_update(&hash, digest, sizeof(digest));
fort_pools[c].length = 0;
HashInit(&fort_pools[c].pool);
// save earlier pool to new one
hash_update(&fort_pools[c].pool,
digest, sizeof(digest));
c++;
FORT_INTERNAL_EVENTS_END(26)
}
hash_update_cvar(&hash);
hash_final(digest, &hash);
#ifdef DEBUG34
fprintf(stdout,"\ndigest ");
for(int d=0;d<HashLen;d++)
fprintf(stdout,"%02x",digest[d]);
fprintf(stdout,"\n");
#endif
fort_reseed(sizeof(digest), digest);
// Forget hash context
memset(&hash, 0, sizeof(hash));
// Forget reseed key
memset(digest, 0, sizeof(digest));
}
fort_pseudo_random_data_xor(len, buf);
FORT_INTERNAL_EVENTS_END(27)
}
#endif // #ifdef FORT_XOR_VERSION
#define FORTCNT 128
static unsigned int fort_cnt = FORTCNT;
static unsigned char fort_bytes[FORTCNT];
static int fort_byte = 999999999;
int fort_random_data_byte()
{
if(fort_byte >= fort_cnt) {
fort_random_data(fort_cnt, fort_bytes);
fort_byte = 0;
}
return(fort_bytes[fort_byte++]);
}
void fort_clear()
{
memset(fort_bytes, 0, fort_cnt);
fort_byte = 999999998;
}
int fort_random_data_byte_limit(int limit)
{
int c;
while((c = fort_random_data_byte())>=
(256/limit)*limit);
return(c % limit);
}
void fort_random_data_buffer(int size,
unsigned char *buffer)
{
int c;
for(c=0; c<size; c++)
buffer[c] ^= fort_random_data_byte();
}
#define aDEBUG53 2
void fort_reseed_file(unsigned char *filename)
{
int c, cnt, bytes, characters;
#ifdef DEBUG53
unsigned char *p;
#endif
FILE *fp1;
unsigned char buffer[1024], digest[HashLen];
HashCtx hash;
bytes=0;
characters=0;
if((fp1=fopen(filename, "r"))!=NULL) {
HashInit(&hash);
while(fgets(buffer,sizeof(buffer),fp1)!=NULL) {
cnt=strlen(buffer);
HashUpdate(&hash, buffer, cnt);
bytes+=cnt;
for(c=0;c<cnt;c++) {
if(buffer[c]<0x80 || buffer[c]>0xbf)
characters++;
}
#ifdef DEBUG53
p=buffer;
while(*p!='\0') {
if(*p=='\\')
fprintf(stdout,"\\\\");
else if(isprint(*p) || *p=='\n')
fputc(*p,stdout);
else
fprintf(stdout,"\\%02x",*p);
p++;
}
#endif
}
hash_update_cvar(&hash);
HashFinal(digest, &hash);
fort_reseed(sizeof(digest), digest);
fclose(fp1);
}
#ifdef DEBUG53
//if(fort_verbose) {
fprintf(stdout,"fort_reseed_file %s",filename);
fprintf(stdout,", %d bytes read",bytes);
fprintf(stdout,", %d characters read",characters);
fprintf(stdout,", sha256: ");
for(int c = 0;c < HashLen; c++) {
fprintf(stdout,"%02x", digest[c]);
}
fprintf(stdout,"\n");
//}
#endif
}
#define FORT_SAVE_SIZE 1024
#define aDEBUG57
void fort_save()
{
FILE *fp1;
unsigned char buffer[FORT_SAVE_SIZE];
memset(buffer,0,sizeof(buffer));
if((fp1 = fopen(fort_random_file, "w")) != NULL) {
fort_pseudo_random_data(sizeof(buffer), buffer);
#ifdef DEBUG57
for(int c=0;c<sizeof(buffer);c++) {
if(c%32==0) {
if(c!=0)
fprintf(stdout,"\n");
fprintf(stdout,"save %05d ",c);
}
fprintf(stdout," %02x",buffer[c]);
}
fprintf(stdout,"\n");
#endif
fwrite(buffer, 1, sizeof(buffer), fp1);
memset(buffer, 0, sizeof(buffer));
fclose(fp1);
}
}
void fort_restore()
{
int d;
#ifdef DEBUG57
int random;
#endif
FILE *fp1;
unsigned char buffer[FORT_SAVE_SIZE];
memset(buffer,0,sizeof(buffer));
if((fp1 = fopen(fort_random_file, "r"))
!= NULL) {
d = fread(buffer, 1, sizeof(buffer), fp1);
fclose(fp1);
#ifdef DEBUG57
random=0;
#endif
} else {
fort_pseudo_random_data(sizeof(buffer), buffer);
ressu_genbytes(sizeof(buffer), buffer);
d = sizeof(buffer);
#ifdef DEBUG57
random=1;
#endif
}
#ifdef DEBUG57
for(int c=0;c<sizeof(buffer);c++) {
if(c%32==0) {
if(c!=0)
fprintf(stdout,"\n");
fprintf(stdout,"restore");
if(random)
fprintf(stdout,"*");
else
fprintf(stdout," ");
fprintf(stdout," %05d ",c);
}
fprintf(stdout," %02x",buffer[c]);
}
fprintf(stdout,"\n");
#endif
fort_reseed(d, buffer);
memset(buffer, 0, sizeof(buffer));
fort_save();
}
#if defined FORT_USE_URANDOM || \
defined FORT_USE_RANDOM
static void fort_readfile_xor(int len,
unsigned char *buf,
unsigned char *filename)
{
int c, n, n2;
unsigned char temp[64];
FILE *fp1;
if((fp1 = fopen(filename, "rb"))
!= NULL) {
while(len != 0) {
n = (len < sizeof(temp)) ?
len : sizeof(temp);
n2=fread(temp, 1, n, fp1);
for(c = 0; c < n2; c++)
buf[c] ^= temp[c];
len -= n2;
buf += n2;
}
fclose(fp1);
}
}
#endif
#ifdef FORT_USE_WEB
static void parse_string(unsigned char *string, int size, unsigned char **p2)
{
int count;
unsigned char *p, *q;
p=*p2;
q=string;
count=0;
// uppercase & lowercase letters, '.'
// or utf-8
while(isalnum(*p)||*p=='.'||*p>0x80) {
if(++count<size)
*q++=*p;
p++;
}
*q='\0';
*p2=p;
}
#endif // #ifdef FORT_USE_WEB
#ifdef FORT_USE_WEB
static int check_string(unsigned char *string, unsigned char *p)
{
int ok;
ok=0;
if(!strncmp(string,p,strlen(string))) {
ok=1;
}
return(ok);
}
#endif // #ifdef FORT_USE_WEB
void fort_internal_random_data_1(int size, char *buf)
{
ressu_genbytes(size, buf);
#ifdef FORT_XOR_VERSION
fort_pseudo_random_data_xor(size, buf);
#endif
}
void fort_internal_random_data_2(int size, char *buf)
{
#ifdef FORT_XOR_VERSION
fort_pseudo_random_data_xor(size, buf);
#else
fort_pseudo_random_data(size, buf);
#endif
ressu_genbytes(size, buf);
}
void fort_internal_random_data_3(int size, char *buf)
{
#ifdef FORT_XOR_VERSION
fort_random_data_xor(size, buf);
#else
fort_random_data(size, buf);
#endif
}
static IUTIME fort_next_localmix = 0;
//#define FORT_SECONDS_BETWEEN_LOCALMIXES 60*60
#define FORT_SECONDS_BETWEEN_LOCALMIXES 60*60
static IUTIME fort_next_webmix = 0;
//#define FORT_SECONDS_BETWEEN_WEBMIXES 12*3600
#define FORT_SECONDS_BETWEEN_WEBMIXES 12*3600
#define RANDOMNESS_IN_LANGUAGES 2
void fort_mix()
{
int webmix=0, localmix=0;
unsigned char temp[64];
IUTIME seconds;
seconds = getseconds();
webmix=0;
localmix=0;
if(fort_next_webmix == 0 ||
fort_next_webmix <= seconds) {
fort_next_webmix=seconds+FORT_SECONDS_BETWEEN_WEBMIXES;
fort_next_localmix=seconds+FORT_SECONDS_BETWEEN_LOCALMIXES;
webmix=1;
localmix=1;
}
if(fort_next_localmix == 0 ||
fort_next_localmix <= seconds) {
fort_next_localmix=seconds+FORT_SECONDS_BETWEEN_LOCALMIXES;
localmix=1;
}
if(!webmix && !localmix)
return;
if(fort_verbose) {
char timebuf[128];
strftime(timebuf, sizeof(timebuf), TIMEFORMAT,
localtime((time_t *)&seconds));
fprintf(stdout,"Fort mix time: %s\n",timebuf);
strftime(timebuf, sizeof(timebuf), TIMEFORMAT,
localtime((time_t *)&fort_next_webmix));
fprintf(stdout,"Next fort webmix: %s\n",timebuf);
strftime(timebuf, sizeof(timebuf), TIMEFORMAT,
localtime((time_t *)&fort_next_localmix));
fprintf(stdout,"Next fort localmix: %s\n",timebuf);
}
fort_internal_random_data_1(sizeof(temp), temp);
fort_reseed(sizeof(temp), temp);
#if defined FORT_USE_WEB || \
defined FORT_USE_RDRAND || \
defined FORT_USE_RDSEED || \
defined FORT_USE_NEWRESSU_COMMAND
unsigned char digest[HashLen];
#endif
#ifdef FORT_USE_WEB
if(webmix && fort_use_web) {
char *webpages[] = {
"https://moijari.com:5001/",
"https://moijari.com:5005/",
"https://moijari.com:5006/",
};
for(int c=0;c<sizeof(webpages)/sizeof(webpages[0]);c++) {
unsigned char *p;
unsigned char scheme[32];
unsigned char host[32];
unsigned char port[10];
unsigned char rest[128];
p=webpages[c];
parse_string(scheme,sizeof(scheme),&p);
if(check_string("://",p)) {
p+=3;
parse_string(host,sizeof(host),&p);
} else {
strcpy(host,scheme);
strcpy(scheme,"http");
}
if(check_string(":",p)) {
p++;
parse_string(port,sizeof(port),&p);
} else {
strcpy(port,"80");
}
if(*p!='/')
strcpy(rest,"/");
else
strcpy(rest,p);
if(fort_verbose) {
fprintf(stdout,"URL:%s ",webpages[c]);
fprintf(stdout,"[scheme:%s]",scheme);
fprintf(stdout,"[host:%s]",host);
fprintf(stdout,"[port:%s]",port);
fprintf(stdout,"[rest:%s]",p);
fflush(stdout);
}
if(!strcmp(scheme,"http")) {
fort_hash_http_page(host, port, p, digest);
} else if(!strcmp(scheme,"https")) {
fort_hash_https_page(host, port, p, digest);
}
if(fort_verbose) {
fprintf(stdout,"\n");
fflush(stdout);
}
fort_reseed(sizeof(digest), digest);
}
}
#endif // #ifdef FORT_USE_WEB
if(localmix) {
#ifdef FORT_USE_URANDOM
memset(temp, 0, sizeof(temp));
fort_readfile_xor(sizeof(temp), temp,
"/dev/urandom");
fort_reseed(sizeof(temp), temp);
#endif
#ifdef FORT_USE_RANDOM
memset(temp, 0, sizeof(temp));
fort_readfile_xor(sizeof(temp), temp,
"/dev/random");
fort_reseed(sizeof(temp), temp);
#endif
#if defined FORT_USE_RDRAND || \
defined FORT_USE_RDSEED
HashCtx hash;
unsigned char digest[HashLen];
#endif
#ifdef FORT_USE_RDRAND
memset(temp,0,sizeof(temp));
if(rdrand_bytes(sizeof(temp),temp)) {
HashInit(&hash);
hash_update_cvar(&hash);
HashUpdate(&hash, temp, sizeof(temp));
HashFinal(digest, &hash);
if(fort_verbose) {
fprintf(stdout,", sha256: ");
for(int c = 0;c < HashLen; c++) {
fprintf(stdout,"%02x", digest[c]);
}
fprintf(stdout,"\n");
fflush(stdout);
}
fort_reseed(sizeof(digest), digest);
}
#endif // #ifdef FORT_USE_RDRAND
#ifdef FORT_USE_RDSEED
memset(temp,0,sizeof(temp));
if(rdseed_bytes(sizeof(temp),temp)) {
HashInit(&hash);
hash_update_cvar(&hash);
HashUpdate(&hash, temp, sizeof(temp));
HashFinal(digest, &hash);
if(fort_verbose) {
fprintf(stdout,", sha256: ");
for(int c = 0;c < HashLen; c++) {
fprintf(stdout,"%02x", digest[c]);
}
fprintf(stdout,"\n");
fflush(stdout);
}
fort_reseed(sizeof(digest), digest);
}
#endif // #ifdef FORT_USE_RDSEED
#ifdef FORT_USE_NEWRESSU_COMMAND
char *commands[] = {
"/bin/newressu -2 -s8 -c64 -l1 --lineno",
"/bin/newressu -2 -s8 -c64 -l1 --lineno --fast",
"/bin/newressu -2 -s8 -c64 -l1 --lineno --urandom",
#ifdef RANDOMNESS_IN_LANGUAGES
"/bin/newressu --cn -s8 -c64 -l1 --single --lineno",
"/bin/newressu --deu -s8 -c64 -l1 --single --lineno",
"/bin/newressu --dnk -s8 -c64 -l1 --single --lineno",
"/bin/newressu --eng -s8 -c64 -l1 --single --lineno",
"/bin/newressu --est -s8 -c64 -l1 --single --lineno",
"/bin/newressu --fin -s8 -c64 -l1 --single --lineno",
"/bin/newressu --fra -s8 -c64 -l1 --single --lineno",
"/bin/newressu --gbr -s8 -c64 -l1 --single --lineno",
"/bin/newressu --got -s8 -c64 -l1 --single --lineno",
"/bin/newressu --grc -s8 -c64 -l1 --single --lineno",
"/bin/newressu --ita -s8 -c64 -l1 --single --lineno",
"/bin/newressu --jp -s8 -c64 -l1 --single --lineno",
"/bin/newressu --jp1 -s8 -c64 -l1 --single --lineno",
"/bin/newressu --jp2 -s8 -c64 -l1 --single --lineno",
"/bin/newressu --jp3 -s8 -c64 -l1 --single --lineno",
"/bin/newressu --kor -s8 -c64 -l1 --single --lineno",
"/bin/newressu --ltu -s8 -c64 -l1 --single --lineno",
"/bin/newressu --lva -s8 -c64 -l1 --single --lineno",
"/bin/newressu --nor -s8 -c64 -l1 --single --lineno",
"/bin/newressu --rus -s8 -c64 -l1 --single --lineno",
"/bin/newressu --swe -s8 -c64 -l1 --single --lineno",
#endif
};
for(int c=0;c<sizeof(commands)/sizeof(commands[0]);c++) {
if(strstr(commands[c], "--fort")) {
fprintf(stderr,"%s: fort_mix(): cannot call fort recursively \"%s\"\n",
procname,commands[c]);
} else {
fort_hash_command(commands[c], digest);
fort_reseed(sizeof(digest), digest);
}
}
#endif // #ifdef FORT_USE_NEWRESSU_COMMAND
}
}
void file_digest(char *filename,unsigned char temp[HashLen])
{
int c;
unsigned char buffer[1024];
FILE *fp1;
HashCtx ctx;
HashInit(&ctx);
if((fp1=fopen(filename,"rb"))!=NULL) {
while((c=fread(buffer,1,sizeof(buffer),fp1))>0)
HashUpdate(&ctx,buffer,c);
fclose(fp1);
}
HashFinal(temp,&ctx);
}
#define DEBUG88
void fort_init()
{
int c;
unsigned char temp32[32];
memset(temp32,0,sizeof(temp32));
memset(fort_bytes,0,sizeof(fort_bytes));
memset(fort_key,0,sizeof(fort_key));
if(fort_verbose) {
fprintf(stdout,"hash: %s",
HashName);
fprintf(stdout,", pools: %d*%ld", FORT_POOLS,
sizeof(struct fort_pool));
fprintf(stdout,", HashCtx: %ld",
sizeof(HashCtx));
fprintf(stdout,", hashsize: %d",
HashLen);
fprintf(stdout,"\n");
}
unsigned int save_fort_internal_events;
save_fort_internal_events=fort_internal_events;
fort_internal_events=1;
fort_next_save = 0;
clearcvar();
// first key to fort_key
fort_internal_random_data_1(sizeof(fort_key), fort_key);
#ifdef ADDITIONAL_SECRETS
// additional constant randomness from program
fort_reseed(strlen(copyright), copyright);
fort_reseed(strlen(programname), programname);
unsigned char filedigest[HashLen];
file_digest("/proc/self/exe",filedigest);
fort_reseed(strlen(filedigest), filedigest);
fort_reseed(strlen(programsecret), programsecret);
// additional constant randomness
// from you (one more secret adversary
// has to guess)
FILE *fp1;
if((fp1 = fopen(fort_secret_file, "r")) != NULL) {
fclose(fp1);
} else {
if((fp1 = fopen(fort_secret_file, "w")) != NULL) {
fprintf(fp1,"Your secret additional constant data to fort:\n");
fclose(fp1);
unsigned char temp2[160];
sprintf(temp2,"%s -2 -l1 >>%s",procname,fort_secret_file);
system(temp2);
fprintf(stdout,"File %s written\n",fort_secret_file);
}
}
fort_reseed_file(fort_secret_file);
#endif
// Initialize buffers
for(c=0; c<FORT_POOLS; c++) {
fort_pools[c].length = 0;
HashInit(&fort_pools[c].pool);
}
#ifdef DEBUG10
FILE *fp1;
// Empty events file
if((fp1 = fopen(fort_events_file, "w"))!=NULL)
fclose(fp1);
event_id = 0;
#endif // #ifdef DEBUG10
// Mix fort key with web + local
// random numbers
fort_mix();
for(c=0; c<FORT_POOLS; c++) {
FORT_INTERNAL_EVENTS_START(31)
fort_internal_random_data_2(sizeof(temp32), temp32);
hash_update(&fort_pools[c].pool,
temp32, sizeof(temp32));
FORT_INTERNAL_EVENTS_END(32)
}
#ifdef FORT_INTERNAL_EVENTS
if(fort_internal_events) {
// Create some internal events
for(c=0; c<32; c++) {
FORT_INTERNAL_EVENTS_START(34)
fort_internal_random_data_3(sizeof(temp32), temp32);
FORT_INTERNAL_EVENTS_END(35)
}
}
#endif // #ifdef FORT_INTERNAL_EVENTS
fort_reseed_count = 0;
fort_next_reseed = 0;
// Reseed fort_key with new events
fort_internal_random_data_3(sizeof(temp32), temp32);
fort_reseed(sizeof(temp32), temp32);
fort_restore();
// Forget temp
memset(temp32,0,sizeof(temp32));
fort_internal_events = save_fort_internal_events;
//fort_reseed_count = 0;
//fort_next_reseed = 0;
fort_next_save = 1;
}
void fort_version()
{
fprintf(stderr,"%s",programname); // touch these outside MAIN
fprintf(stderr,", %s\n",copyright);
}
#define aMAIN 2
#ifdef MAIN
unsigned char *procname;
int main(int argc, char *argv[])
{
procname=argv[0];
fort_version();
fort_init();
return(0);
}
#endif // #ifdef MAIN
sha256.c
/* Written from SHA256 documents by Jari Kuivaniemi, read "http://en.wikipedia.org/wiki/SHA-2" */
#include <stdio.h>
#include <memory.h>
#include <string.h>
#include "sha256.h"
extern unsigned char *procname;
//#ifdef MAIN // in Makefile
unsigned char *sha_name="SHA256 v1.0";
void SHA256Init(SHA256_CONTEXT *sha256)
{
sha256->state[0] = 0x6a09e667;
sha256->state[1] = 0xbb67ae85;
sha256->state[2] = 0x3c6ef372;
sha256->state[3] = 0xa54ff53a;
sha256->state[4] = 0x510e527f;
sha256->state[5] = 0x9b05688c;
sha256->state[6] = 0x1f83d9ab;
sha256->state[7] = 0x5be0cd19;
sha256->count = 0;
}
IUWORD k256[64] = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};
#define RR32(word,bits) ( ((word) >> (bits)) | ((word) << (32 - (bits))) )
#define RS32(word,bits) ( ((word) >> (bits)) )
void SHA256Transform(IUWORD state[8], IUBYTE buffer[64])
{
int i;
IUWORD w[64], s0;
IUWORD a, b, c, d, e, f, g, h;
IUWORD maj, t2, s1;
IUWORD ch, t1;
for(i=0;i<16;i++) {
w[i] =
(IUWORD)buffer[i*4+0] << 24 |
(IUWORD)buffer[i*4+1] << 16 |
(IUWORD)buffer[i*4+2] << 8 |
(IUWORD)buffer[i*4+3];
}
for(i=16;i<64;i++) {
s0 = (RR32(w[i-15],7)) ^ (RR32(w[i-15],18)) ^ (RS32(w[i-15],3));
s1 = (RR32(w[i-2],17)) ^ (RR32(w[i-2],19)) ^ (RS32(w[i-2],10));
w[i] = w[i-16] + s0 + w[i-7] + s1;
}
a = state[0];
b = state[1];
c = state[2];
d = state[3];
e = state[4];
f = state[5];
g = state[6];
h = state[7];
for(i=0;i<64;i++) {
s0 = (RR32(a,2)) ^ (RR32(a,13)) ^ (RR32(a,22));
maj = (a & b) ^ (a & c) ^ (b & c);
t2 = s0 + maj;
s1 = (RR32(e,6)) ^ (RR32(e,11)) ^ (RR32(e,25));
ch = (e & f) ^ ((~ e) & g);
t1 = h + s1 + ch + k256[i] + w[i];
h = g;
g = f;
f = e;
e = d + t1;
d = c;
c = b;
b = a;
a = t1 + t2;
}
state[0] = state[0] + a;
state[1] = state[1] + b;
state[2] = state[2] + c;
state[3] = state[3] + d;
state[4] = state[4] + e;
state[5] = state[5] + f;
state[6] = state[6] + g;
state[7] = state[7] + h;
}
void SHA256Update(SHA256_CONTEXT *sha256, unsigned char *data, int len)
{
int i,j;
j = (int)sha256->count & 63;
sha256->count+=len;
if((j+len)>63) {
memcpy(&sha256->buffer[j],data,64-j); /* last bytes of next block */
SHA256Transform(sha256->state, sha256->buffer);
for (i = 64 - j ; i + 63 < len; i += 64) {
SHA256Transform(sha256->state, &data[i]);
}
j = 0;
} else
i=0;
memcpy(&sha256->buffer[j],&data[i],len-i);
}
void SHA256Final(unsigned char digest[32], SHA256_CONTEXT *sha256)
{
int i,j;
unsigned char filelenght[8];
IULONG count;
count=sha256->count << 3;
SHA256Update(sha256,"\200",1);
while((sha256->count & 63) != 56)
SHA256Update(sha256,"\0",1);
filelenght[0]=(unsigned char)(count >> 56)&0xff;
filelenght[1]=(unsigned char)(count >> 48)&0xff;
filelenght[2]=(unsigned char)(count >> 40)&0xff;
filelenght[3]=(unsigned char)(count >> 32)&0xff;
filelenght[4]=(unsigned char)(count >> 24)&0xff;
filelenght[5]=(unsigned char)(count >> 16)&0xff;
filelenght[6]=(unsigned char)(count >> 8 )&0xff;
filelenght[7]=(unsigned char)(count&0xff);
SHA256Update(sha256,filelenght,sizeof(filelenght));
for(i=0,j=0;i<8;i++) {
digest[j++]=(unsigned char) (sha256->state[i] >> 24)&0xff;
digest[j++]=(unsigned char) (sha256->state[i] >> 16)&0xff;
digest[j++]=(unsigned char) (sha256->state[i] >> 8)&0xff;
digest[j++]=(unsigned char) (sha256->state[i] )&0xff;
}
}
#ifdef MAIN
void printhex(char *name, unsigned char *digest, int len)
{
int c;
fprintf(stdout,"%s=",name);
for(c=0;c<len;c++) {
fprintf(stdout,"%02x",digest[c]);
}
fflush(stdout);
}
int shahexdigit(int c)
{
if(c>='0' && c<='9') return(c-'0');
else if(c>='a' && c<='f') return(c-'a'+10);
else if(c>='A' && c<='F') return(c-'A'+10);
return(0);
}
void sha_test()
{
int c,d,e,ok,allok;
SHA256_CONTEXT sha256;
unsigned char result[32],*p;
fprintf(stdout,"%s",sha_name);
fprintf(stdout,", Context size: %ld", sizeof(SHA256_CONTEXT));
fprintf(stdout,", Hash size: 32");
fprintf(stdout,", IUBYTE size: %ld", sizeof(IUBYTE));
fprintf(stdout,", IUWORD size: %ld", sizeof(IUWORD));
fprintf(stdout,", IULONG size: %ld", sizeof(IULONG));
struct test {
unsigned char *string;
int count;
unsigned char *result;
} tests[] = {
{ "abc",1,"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" },
{ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",1,"248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1" },
{ "a",1000000,"cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0" },
{ "The quick brown fox jumps over the lazy dog",1,"d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592" },
};
allok=1;
for(c=0;c<sizeof(tests)/sizeof(tests[0]);c++) {
SHA256Init(&sha256);
for(d=0;d<tests[c].count;d++)
SHA256Update(&sha256,tests[c].string,strlen(tests[c].string));
SHA256Final(result,&sha256);
p=tests[c].result;
d=0;
ok=1;
while(*p!='\0') {
if(*p!='\0')
e=shahexdigit(*p++);
if(*p!='\0')
e=e*16+shahexdigit(*p++);
if(e!=result[d])
ok=0;
d++;
}
if(ok) {
fprintf(stdout,"\nsha256 test ");
fprintf(stdout,"string: %s",tests[c].string);
fprintf(stdout,", count: %d, ",tests[c].count);
printhex("tmp32",result,sizeof(result));
fprintf(stdout,", result: %s",tests[c].result);
fprintf(stdout," ok!!!!");
fflush(stdout);
} else {
fprintf(stdout,"\nsha256 test ");
fprintf(stdout,"string: %s",tests[c].string);
fprintf(stdout,", count: %d, ",tests[c].count);
printhex("tmp32",result,sizeof(result));
fprintf(stdout,", result: %s",tests[c].result);
fprintf(stdout," failed!!!!");
fflush(stdout);
allok=0;
}
}
if(allok) {
fprintf(stdout,", sha256 tests ok!!!!\n");
} else {
fprintf(stdout,", sha256 tests failed!!!!\n");
}
fflush(stdout);
}
int main(int argc, char *argv[])
{
sha_test();
}
#endif
intelrandom.c
#include <stdio.h>
#include <memory.h>
#include "fort.h"
#include "newressu.h"
#if defined FORT_USE_RDRAND || \
defined FORT_USE_RDSEED
// see: https://software.intel.com/content/www/us/en/develop/articles/intel-digital-random-number-generator-drng-software-implementation-guide.html
void _cpuid(unsigned int leaf, unsigned int subleaf,
unsigned int *a, unsigned int *b, unsigned int *c, unsigned int *d)
{
asm volatile("cpuid"
: "=a" (*a), "=b" (*b), "=c" (*c), "=d" (*d)
: "a" (leaf), "c" (subleaf) );
}
int _is_cpu_vendor(unsigned char *cpuvendor)
{
int ok=0;
unsigned int a, b, c, d;
_cpuid(0, 0, &a, &b, &c, &d);
if(memcmp((char *)(&b), cpuvendor,4)==0 &&
memcmp((char *)(&d), cpuvendor+4,4)==0 &&
memcmp((char *)(&c), cpuvendor+8,4)==0)
ok=1;
return(ok);
}
#endif
#ifdef FORT_USE_RDRAND
int _has_rdrand()
{
int ok=0;
unsigned int a, b, c, d;
_cpuid(1, 0, &a, &b, &c, &d);
if((c & 0x40000000) == 0x40000000) {
ok=1;
}
return(ok);
}
int _rdrand_long(unsigned long *therand)
{
unsigned char ret;
asm volatile("rdrand %0; setc %1"
: "=r" (*therand), "=qm" (ret) );
return(int) ret;
}
int rdrand_bytes(int buflen, unsigned char *buf)
{
int n, ret = 0;
unsigned long l;
if(_is_cpu_vendor("GenuineIntel") && _has_rdrand()) {
if(fort_verbose)
fprintf(stdout,"Intel rdrand");
ret=1;
} else if(_is_cpu_vendor("AuthenticAMD") && _has_rdrand()) {
if(fort_verbose)
fprintf(stdout,"AMD rdrand");
ret=1;
}
if(ret) {
while(buflen > 0) {
if((ret = _rdrand_long(&l)) == 0) // 1 ok, 0 fail
break;
if(fort_verbose)
fprintf(stdout," %016lx",l);
n = (buflen < sizeof(l) ? buflen : sizeof(l));
memcpy(buf, (unsigned char *)&l, n);
buf+=n;
buflen-=n;
}
}
return(ret);
}
#endif // #ifdef FORT_USE_RDRAND
#ifdef FORT_USE_RDSEED
int _has_rdseed()
{
int ok=0;
unsigned int a, b, c, d;
_cpuid(7, 0, &a, &b, &c, &d);
if((b & 0x40000) == 0x40000) {
ok=1;
}
return(ok);
}
int _rdseed_long(unsigned long *therand)
{
unsigned char ret;
asm volatile("rdseed %0; setc %1"
: "=r" (*therand), "=qm" (ret) );
return(int) ret;
}
int rdseed_bytes(int buflen, unsigned char *buf)
{
int n, ret = 0;
unsigned long l;
if(_is_cpu_vendor("GenuineIntel") && _has_rdseed()) {
if(fort_verbose)
fprintf(stdout,"Intel rdseed");
ret=1;
} else if(_is_cpu_vendor("AuthenticAMD") && _has_rdseed()) {
if(fort_verbose)
fprintf(stdout,"AMD rdseed");
ret=1;
}
if(ret) {
while(buflen > 0) {
int tries=0;
while(++tries < 100) {
if((ret = _rdseed_long(&l)) == 1) { // 1 ok, 0 fail
break;
}
}
if(ret==0)
break;
if(fort_verbose) {
fprintf(stdout," %016lx",l);
newressu_output=1;
}
n = (buflen < sizeof(l) ? buflen : sizeof(l));
memcpy(buf, (unsigned char *)&l, n);
buf+=n;
buflen-=n;
}
}
return(ret);
}
#endif // #ifdef FORT_USE_RDSEED
webrandom.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <memory.h>
#include <errno.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "sha256.h"
#include "fort.h"
extern unsigned char *procname;
extern int fort_verbose;
#include <stdarg.h>
void dbs_printf(unsigned char **buf, size_t *buf_length, const unsigned char *format, ...)
{
int count;
va_list args;;
va_start(args, format);
count = vsnprintf(*buf, *buf_length, format, args) + 1;
va_end(args);
if(*buf_length < count) {
*buf_length = count;
*buf = realloc(*buf, *buf_length);
va_start(args, format);
count = vsnprintf(*buf, *buf_length, format, args) + 1;
va_end(args);
}
}
int fort_connect(unsigned char *host, unsigned char *port)
{
struct addrinfo hints, *res, *resp;
int s, status;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
if((status = getaddrinfo(host, port, &hints, &res)) != 0) {
fprintf(stderr,"\n%s: getaddrinfo", procname);
fprintf(stderr,", status %d", status);
fprintf(stderr,", gai_strerror(): %s", gai_strerror(status));
fprintf(stderr,", errno %d\n", errno);
fflush(stderr);
}
for(resp=res; resp!=NULL; resp = resp->ai_next) {
if((s = socket(resp->ai_family, resp->ai_socktype, resp->ai_protocol))<0)
continue;
if(connect(s, resp->ai_addr, resp->ai_addrlen) == 0)
break;
close(s);
}
freeaddrinfo(res);
return(s);
}
#define aDEBUG27 2
void fort_hash_http_page(unsigned char *host,unsigned char *port, unsigned char *page, unsigned char *hash) // 202011 JariK
{
int c, cnt, s, status, bytes, characters;
if((s = fort_connect(host, port))<0) {
fprintf(stderr,"\n%s: cannot fort_connect()", procname);
fprintf(stderr,", status: %d", s);
fprintf(stderr,", errno: %d" , errno);
perror("fort_connect");
fflush(stderr);
}
unsigned char *format =
"GET %s HTTP/1.0\r\n"
"Host: %s:%s\r\n";
static unsigned char *msg = NULL;
static size_t msg_length=0;
dbs_printf(&msg, &msg_length, format, page, host, port);
if((status=write(s, msg, strlen(msg)))<0) {
fprintf(stderr, "\n%s: write(), error: %d\n", procname, errno);
perror("write");
fflush(stderr);
}
HashCtx ctx;
unsigned char buffer[1024];
HashInit(&ctx);
bytes=0;
characters=0;
while((cnt = read(s, buffer, sizeof(buffer)))>0) {
#ifdef DEBUG27
write(1,buffer,cnt);
fflush(stdout);
#endif
HashUpdate(&ctx, buffer, cnt);
bytes+=cnt;
for(c=0;c<cnt;c++) {
if(buffer[c]<0x80 || buffer[c]>0xbf)
characters++;
}
}
hash_update_cvar(&ctx);
HashFinal(hash, &ctx);
if(fort_verbose) {
fprintf(stdout,"fort_hash_http_page:");
fprintf(stdout," %d bytes read", bytes);
fprintf(stdout,", %d characters read", characters);
fprintf(stdout,", sha256: ");
for(int c = 0;c < HashLen; c++) {
fprintf(stdout,"%02x", hash[c]);
}
fprintf(stdout,"\n");
}
close(s);
}
#define aDEBUG49 2
#define aDEBUG50 2
void fort_hash_https_page(unsigned char *host,unsigned char *port, unsigned char *page, unsigned char *hash) // 202011 JariK
{
int c, cnt, s, status, bytes, characters;
SSL_METHOD *method=NULL;
SSL_CTX *ctx=NULL;
SSL *ssl;
SSL_library_init(); //see: http://h30266.www3.hpe.com/odl/axpos/opsys/vmsos84/BA554_90007/ch04s03.html
OpenSSL_add_ssl_algorithms();
SSL_load_error_strings();
#ifdef DEBUG49
fprintf(stdout,"SSLv23_client_method()\n");
#endif
if((method = (SSL_METHOD *)
SSLv23_client_method()) == NULL) {
fprintf(stderr,"\n%s: cannot SSLv3_server_method()", procname);
fflush(stderr);
}
#ifdef DEBUG49
fprintf(stdout,"SSL_CTX_new()\n");
#endif
if((ctx=SSL_CTX_new(method)) == NULL) {
fprintf(stderr,"\n%s: cannot SSL_CTX_new()", procname);
fflush(stderr);
}
#ifdef DEBUG49
fprintf(stdout,"SSL_new()\n");
#endif
if((ssl=SSL_new(ctx)) == NULL) {
fprintf(stderr,"\n%s: cannot SSL_new()", procname);
fflush(stderr);
}
#ifdef DEBUG49
fprintf(stdout,"fort_connect()\n");
#endif
if((s = fort_connect(host, port))<0) {
fprintf(stderr,"\n%s: cannot fort_connect()", procname);
fprintf(stderr,", status: %d", s);
fprintf(stderr,", errno: %d" , errno);
perror("fort_connect");
fflush(stderr);
}
SSL_set_fd(ssl,s);
#ifdef DEBUG49
fprintf(stdout,"SSL_connect(ssl)\n");
#endif
if((status=SSL_connect(ssl))<=0) {
fprintf(stderr,"\n%s: cannot SSL_connect()", procname);
fprintf(stderr,", status: %d", status);
fprintf(stderr,", errno: %d" , errno);
fprintf(stderr,", SSL_get_error(): %d\n", SSL_get_error(ssl,status));
perror("SSL_connect");
fflush(stderr);
}
unsigned char *format =
"GET %s HTTP/1.0\r\n"
"Host: %s:%s\r\n";
static unsigned char *msg = NULL;
static size_t msg_length=0;
dbs_printf(&msg, &msg_length, format, page, host, port);
#ifdef DEBUG49
fprintf(stdout,"SSL_write(), msg_length:%ld, msg=\"%s\"\n",msg_length,msg);
#endif
if((status=SSL_write(ssl, msg, strlen(msg)))<0) {
fprintf(stderr,"\n%s: SSL_write()", procname);
fprintf(stderr,", status: %d", status);
fprintf(stderr,", errno: %d", errno);
fprintf(stderr,", SSL_get_error(): %d", SSL_get_error(ssl,status));
perror("SSL_write");
fflush(stderr);
}
fflush(stdout);
HashCtx hashctx;
unsigned char buffer[2048];
HashInit(&hashctx);
bytes=0;
characters=0;
#ifdef DEBUG49
fprintf(stdout,"SSL_read()\n");
#endif
int bytesneeded=0, bytesheader=0, bytescontent=0;
do {
cnt=SSL_read(ssl, buffer, sizeof(buffer));
if(cnt<0) {
int err, err2;
err=SSL_get_error(ssl,cnt);
err2=ERR_get_error();
fprintf(stderr, "\n%s: cannot SSL_read()", procname);
fprintf(stderr, ", retval: %d", cnt);
fprintf(stderr, ", errno: %d", errno);
fprintf(stderr,", SSL_get_error() %d", err);
fprintf(stderr,", ERR_get_error() %d\n", err2);
perror("SSL_read");
fflush(stderr);
break;
}
#ifdef DEBUG50
write(1,buffer,cnt);
#endif
HashUpdate(&hashctx, buffer, cnt);
bytes+=cnt;
for(c=0;c<cnt;c++) {
if(buffer[c]<0x80 || buffer[c]>0xbf)
characters++;
}
if(bytesneeded==0) {
char *p;
p=buffer;
int count=0;
while(*p!='\0') {
if(!strncmp(p,"\r\nContent-Length: ",18)) {
bytescontent=atoi(p+18);
}
if(!strncmp(p,"\r\n\r\n",4)) {
bytesheader=count;
}
p++;
count++;
}
bytesneeded=bytescontent+bytesheader+4;
}
} while(SSL_pending(ssl) || bytes<bytesneeded);
fprintf(stdout,"bytescontent:%d",bytescontent);
fprintf(stdout,", bytesheader:%d",bytesheader);
fprintf(stdout,", bytesneeded:%d\n",bytesneeded);
fflush(stdout);
#ifdef OLD1
#ifdef DEBUG49
fprintf(stdout,"SSL_read()\n");
#endif
while((cnt=SSL_read(ssl, buffer, sizeof(buffer)))>0) {
#ifdef DEBUG49
fprintf(stdout,"SSL_read() round\n");
#endif
#ifdef DEBUG50
write(1,buffer,cnt);
fflush(stdout);
#endif
HashUpdate(&hashctx, buffer, cnt);
bytes+=cnt;
for(c=0;c<cnt;c++) {
if(buffer[c]<0x80 || buffer[c]>0xbf)
characters++;
}
}
fflush(stdout);
if(cnt<0) {
fprintf(stderr, "\n%s: SSL_read()", procname);
fprintf(stderr, ", status: %d", status);
fprintf(stderr, ", errno: %d", errno);
fprintf(stderr,", SSL_get_error(): %d", SSL_get_error(ssl,status));
perror("SSL_read");
fflush(stderr);
}
#endif
fflush(stdout);
hash_update_cvar(&hashctx);
HashFinal(hash, &hashctx);
fprintf(stdout,"fort_hash_https_page:");
fprintf(stdout," %d bytes read", bytes);
fprintf(stdout,", %d characters read", characters);
fprintf(stdout,", sha256: ");
for(int c = 0;c < HashLen; c++) {
fprintf(stdout,"%02x", hash[c]);
}
fprintf(stdout,"\n");
#ifdef NOTUSED
#ifdef DEBUG49
fprintf(stdout,"SSL_shutdown()\n");
#endif
SSL_shutdown(ssl);
#endif
#ifdef DEBUG49
fprintf(stdout,"SSL_free()\n");
#endif
SSL_free(ssl);
#ifdef DEBUG49
fprintf(stdout,"SSL_CTX_free()\n");
#endif
SSL_CTX_free(ctx);
close(s);
}
commandrandom.c
#include <stdio.h>
#include <stdlib.h>
#include "sha256.h"
#include "fort.h"
#define DEBUG6 2 // display random data
void fort_hash_command(unsigned char *command, unsigned char *hash)
{
int c, cnt, bytes, chars;
FILE *fp1;
unsigned char buffer[1024];
HashCtx hashctx;
bytes=0;
chars=0;
if((fp1=popen(command, "r"))!=NULL) {
HashInit(&hashctx);
if(fort_verbose) {
fprintf(stdout,"fort_hash_command: %s\n",command);
fflush(stdout);
}
while((cnt=fread(buffer,1,sizeof(buffer),fp1))>0) {
#ifdef DEBUG6
if(fort_verbose)
fwrite(buffer,1,cnt,stdout);
#endif
HashUpdate(&hashctx, buffer, cnt);
bytes+=cnt;
for(c=0;c<cnt;c++) {
if(buffer[c]<0x80 || buffer[c]>0xbf)
chars++;
}
}
pclose(fp1);
if(fort_verbose) {
fprintf(stdout,", %d bytes read",bytes);
fprintf(stdout,", %d characters read",chars);
}
hash_update_cvar(&hashctx);
HashFinal(hash, &hashctx);
if(fort_verbose) {
fprintf(stdout,", sha256: ");
for(int c = 0;c < HashLen; c++) {
fprintf(stdout,"%02x", hash[c]);
}
fprintf(stdout,"\n");
fflush(stdout);
}
}
}
ressu4.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include "html.h"
#include "dbs.h"
#include "sha256.h"
unsigned char htmldigest[HashLen*2+1];
static char *programname = "Ressu4 version 0.2 ©";
static unsigned char *copyright = "Copyright (c) 2013-2022 Jari Kuivaniemi, Helsinki, Finland. Kaikki oikeudet pidätetään!";
char *myport = "5006";
char *procheader = "Ressu random numbers (3rd edition)";
char *proctitle = "Ressu random numbers";
extern char *procname;
extern char filenamehead[64];
extern unsigned char htmlfilename[64];
extern unsigned char htmlfileextension[10];
extern unsigned char htmltime[32];
extern unsigned char htmltimeshort[32];
extern unsigned char useragent;
extern unsigned char safari;
int firstrun=1;
#define aDEBUG8
void ressu4_app()
{
unsigned char *p;
unsigned char command[128];
unsigned char buffer[1024];
unsigned char script_file[128]="ressu4script.html";
FILE *fp1,*fp2;
if((fp1=fopen(script_file,"r"))!=NULL) {
fclose(fp1);
} else {
if((fp1=fopen(script_file,"w"))!=NULL) {
fprintf(fp1,";\n");
fprintf(fp1,"; Script for ressu4 ©\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h1>%s</h1>\n",procheader);
fprintf(fp1,";\n");
fprintf(fp1,"<p>The next chapter consists of characters that\n");
fprintf(fp1," try to resemble throws of a 64 sided dice as closely as possible.\n");
fprintf(fp1," Characters have numbers from '0' to '9' (10 entries),\n");
fprintf(fp1," uppercase letters from 'A' to 'Z' (26 entries), lowercase letters\n");
fprintf(fp1," 'a' to 'z' (26 entries), '-' and '_' (2 entries).\n");
fprintf(fp1," Total is 10+26+26+2 = 64 values.\n");
fprintf(fp1," Characters are grouped into sets of 8 each. Throws\n");
fprintf(fp1," are random, so you cannot deduce value from\n");
fprintf(fp1," previous or next value(s).</p>\n");
#ifdef KOK
fprintf(fp1,"<p>Always have more than one random number generator.\n");
fprintf(fp1," Preferably one of them in your own program. If you have\n");
fprintf(fp1," to use these characters as is, add something\n");
fprintf(fp1," (and change something).</p>\n");
#endif
fprintf(fp1,"<h3>Newressu random numbers</h3>\n");
fprintf(fp1,"/bin/newressu -2 -s8 -l1 -c5120 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Random digits</h3>\n");
fprintf(fp1,"/bin/newressu -11 -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Random uppercase letters</h3>\n");
fprintf(fp1,"/bin/newressu -12 -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Random lowercase letters</h3>\n");
fprintf(fp1,"/bin/newressu -13 -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h2>Random characters in number systems</h2>\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Random binary digits</h3>\n");
fprintf(fp1,"<p>Following binary numbers are eight bits from 0 to 255 decimal.\n");
fprintf(fp1," From right to left the bit multipliers are 1, 2, 4, 8, 16, 32, 64 and 128 (2^b) in decimal.\n");
fprintf(fp1," So 10000000b is 128d, 11111111b is 255d, 00000010b is 2d, 00000011b is 3d etc.\n");
fprintf(fp1," Here d after number means of course decimal. Digit numbers, b in 2^b, vary from 0 to 7.</p>\n");
fprintf(fp1,"/bin/newressu -b -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Random octal digits</h3>\n");
fprintf(fp1,"<p>These octal numbers are also from 0 to 255 decimal (0 to 377 octal).\n");
fprintf(fp1," From right to left octal digit multipliers are 1, 8, 64 (8^o) in decimal.\n");
fprintf(fp1," Here 377o is 255d, 010o is 8d, 100o is 64d.\n");
fprintf(fp1," Each octal digit contains 3 binary bits, and 377o can be grouped\n");
fprintf(fp1," in binary like this 011 111 111.</p>\n");
fprintf(fp1,"/bin/newressu -o --lim400 -l1 -c1792 --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Random decimal digits</h3>\n");
fprintf(fp1,"<p>These decimal numbers are from 0 to 99999. From right\n");
fprintf(fp1," to left decimal digit multipliers are 1, 10, 100, 1000 and 10000 (10^d).</p>\n");
fprintf(fp1,"/bin/newressu -d -s5 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Random hexadecimal digits</h3>\n");
fprintf(fp1,"<p>Next hexadecimal numbers are from 0000h to ffffh meaning 0 to 65535 decimal.\n");
fprintf(fp1," Hexadecimal digit has numbers from 0 to 9 and letters a(10),\n");
fprintf(fp1," b(11), c(12), d(13), e(14) and f(15). From right to left hexadecimal multipliers\n");
fprintf(fp1," are 1, 16, 256, 4096 decimal (16^h). Each hexadecimal digit contains 4 bits so ffffh can be\n");
fprintf(fp1," grouped in binary like this 1111 1111 1111 1111.</p>\n");
fprintf(fp1,"/bin/newressu -x -s4 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h2>Random characters in languages</h2>\n");
fprintf(fp1,";\n");
fprintf(fp1,"<p>The next chapters consists of random characters in various\n");
fprintf(fp1," languages. Most randomness is in chinese, japanese and\n");
fprintf(fp1," korean characters. Chinese has 20976 values per character,\n");
fprintf(fp1," japanese has 21158 values per character and korean has\n");
fprintf(fp1," 11172 values per character.</p>\n");
fprintf(fp1,"<p>Latin (or roman) based alphabets have characters as follows:\n");
fprintf(fp1," danish alphabet has 58 characters,\n");
fprintf(fp1," deutsch alphabet has 60 characters,\n");
fprintf(fp1," english has 52 characters,\n");
fprintf(fp1," estonian has 64 characters,\n");
fprintf(fp1," finnish alphabet has 58 characters,\n");
fprintf(fp1," french character set has 52 characters,\n");
fprintf(fp1," italian character set has 52 characters,\n");
fprintf(fp1," latvian has 66 characters,\n");
fprintf(fp1," lithuanian has 64 characters,\n");
fprintf(fp1," norwegian has 58 characters,\n");
fprintf(fp1," swedish has 58 characters.\n");
fprintf(fp1," </p>\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Chinese random characters</h3>\n");
fprintf(fp1,"/bin/newressu --cn -s8 -l1 -c1792 --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Danish random characters</h3>\n");
#ifdef KOK
fprintf(fp1,"<p>Danish has latin letters 'a' to 'z' ('A' to 'Z')\n");
fprintf(fp1,"and 'æ', 'ø', and 'å' ('Æ', 'Ø', 'Å').</p>\n");
#endif
fprintf(fp1,";ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ\n");
fprintf(fp1,";abcdefghijklmnopqrstuvwxyzæøå\n");
fprintf(fp1,"/bin/newressu --dnk -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Deutsch random characters</h3>\n");
fprintf(fp1,";ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÜẞ\n");
fprintf(fp1,";abcdefghijklmnopqrstuvwxyzäöüß\n");
fprintf(fp1,"/bin/newressu --deu -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>English random characters</h3>\n");
fprintf(fp1,";ABCDEFGHIJKLMNOPQRSTUVWXYZ\n");
fprintf(fp1,";abcdefghijklmnopqrstuvwxyz\n");
fprintf(fp1,"/bin/newressu --eng -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Estonian random characters</h3>\n");
fprintf(fp1,";ABCDEFGHIJKLMNOPQRSŠZŽTUVWÕÄÖÜXY\n");
fprintf(fp1,";abcdefghijklmnopqrsšzžtuvwõäöüxy\n");
fprintf(fp1,"/bin/newressu --est -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Finnish random characters</h3>\n");
fprintf(fp1,";ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ\n");
fprintf(fp1,";abcdefghijklmnopqrstuvwxyzåäö\n");
fprintf(fp1,"/bin/newressu --fin -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>French random characters</h3>\n");
fprintf(fp1,";ABCDEFGHIJKLMNOPQRSTUVWXYZ\n");
fprintf(fp1,";abcdefghijklmnopqrstuvwxyz\n");
fprintf(fp1,"/bin/newressu --fra -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Gothic random characters</h3>\n");
fprintf(fp1,"/bin/newressu --got -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Greek random characters</h3>\n");
fprintf(fp1,";ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ\n");
fprintf(fp1,";αβγδεζηθικλμνξοπρστυφχψω\n");
fprintf(fp1,"/bin/newressu --grc -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Italian random characters</h3>\n");
fprintf(fp1,";ABCDEFGHIJKLMNOPQRSTUVWXYZ\n");
fprintf(fp1,";abcdefghijklmnopqrstuvwxyz\n");
fprintf(fp1,"/bin/newressu --ita -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Japanese random characters</h3>\n");
fprintf(fp1,"/bin/newressu --jp -s8 -l1 -c1792 --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Korean random characters</h3>\n");
fprintf(fp1,"/bin/newressu --kor -s8 -l1 -c1792 --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Latvian random characters</h3>\n");
fprintf(fp1,";AĀBCČDEĒFGĢHIĪJKĶLĻMNŅOPRSŠTUŪVZŽ\n");
fprintf(fp1,";aābcčdeēfgģhiījkķlļmnņoprsštuūvzž\n");
fprintf(fp1,"/bin/newressu --lva -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Lithuanian random characters</h3>\n");
fprintf(fp1,";AĄBCČDEĘĖFGHIĮYJKLMNOPRSŠTUŲŪVZŽ\n");
fprintf(fp1,";aąbcčdeęėfghiįyjklmnoprsštuųūvzž\n");
fprintf(fp1,"/bin/newressu --ltu -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Norwegian random characters</h3>\n");
fprintf(fp1,";ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ\n");
fprintf(fp1,";abcdefghijklmnopqrstuvwxyzæøå\n");
fprintf(fp1,"/bin/newressu --nor -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Russian random characters</h3>\n");
fprintf(fp1,";АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ\n");
fprintf(fp1,";абвгдеёжзийклмнопрстуфхцчшщъыьэюя\n");
fprintf(fp1,"/bin/newressu --rus -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h3>Swedish random characters</h3>\n");
fprintf(fp1,";ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ\n");
fprintf(fp1,";abcdefghijklmnopqrstuvwxyzåäö\n");
fprintf(fp1,"/bin/newressu --swe -s8 -l1 -c1792 --space --lineno\n");
fprintf(fp1,";\n");
fprintf(fp1,"<h2>Technical</h2>\n");
fprintf(fp1,"<p>This version runs newressu new for all of the previous\n");
fprintf(fp1," random number chapters (25 runs), so the buffer is empty in\n");
fprintf(fp1," the beginning of the chapter runs.\n");
fprintf(fp1," This whole page is created (including randomness) after your\n");
fprintf(fp1," network query is received,\n");
fprintf(fp1," so time newressu runs is quite reasonable.</p>\n");
fprintf(fp1,"<p>This version does random skips on clock material,\n");
fprintf(fp1," which makes it harder to guess it. Ressu skips\n");
fprintf(fp1," 0-255 bytes every ~1000 bytes.\n");
fprintf(fp1," This version also is ressu only, there is no whitening\n");
fprintf(fp1," or combining of other generators.</p>\n");
fclose(fp1);
}
} // if((fp1=fopen
if((fp1=fopen(script_file,"r"))!=NULL) {
while(fgets(command,sizeof(command),fp1)!=NULL) {
if(command[0]==';')
continue;
else if(!strncmp(command,"/bin/newressu ",14)) {
if((fp2=popen(command, "r"))!=NULL) {
dbs_html_printf("<code>");
while(fgets(buffer,sizeof(buffer),fp2)!=NULL) {
#ifdef DEBUG8
fprintf(stdout,"\"%s\"",buffer);
#endif
p=buffer;
while(*p!='\0') {
if(*p!='-')
dbs_html_printf("%c",*p);
else {
if(safari)
dbs_html_printf("‑");
//dbs_html_printf("−");
//dbs_html_printf("–");
//dbs_html_printf("‐");
//dbs_html_printf("-");
else
dbs_html_printf("−");
}
p++;
} // while(*p!='\0') {
//dbs_html_printf(" ");
//dbs_html_printf("\n");
//dbs_html_printf("<br>");
} // while(fgets(
dbs_html_printf("</code>");
fclose(fp2);
} // if((fp2
} else { // if(!strncmp(command
if(useragent)
dbs_html_printf("%s",command);
else if(strstr(command,"<h1>")!=NULL ||
strstr(command,"<h2>")!=NULL ||
strstr(command,"<h3>")!=NULL ||
strstr(command,"<h4>")!=NULL )
dbs_html_printf("%s",command);
} // if(strncmp
} // while(fgets
fclose(fp1);
} // if((fp1=fopen
if((fp1=fopen("ressuoriginal.html","r"))!=NULL) {
while(fgets(buffer,sizeof(buffer),fp1)!=NULL)
if(buffer[0]!=';')
dbs_html_printf("%s",buffer);
fclose(fp1);
}
}
void dba_loop()
{
html_clear_all();
if(!strcmp(htmlfileextension,"ico") ||
!strcmp(htmlfileextension,"png")) {
dbs_html_set(0);
dbs_html_printf("HTTP/1.0 404 Not Found\r\n");
//dbs_html_printf("Location: \r\n");
//dbs_html_printf("Server: %s\r\n", programname);
} else {
dbs_html_set(0);
dbs_html_printf("HTTP/1.0 200 OK\r\n");
dbs_html_printf("Location: \r\n");
dbs_html_printf("Server: %s\r\n", programname);
dbs_html_printf("Date: %s\r\n", htmltime);
dbs_html_set(1);
dbs_html_printf("<!doctype html>\r\n");
dbs_html_printf("<html lang=\"fi\">");
dbs_html_printf("<head>");
dbs_html_printf("<meta charset=\"utf-8\">");
dbs_html_printf("<title>%s</title>",proctitle);
dbs_html_printf("<meta name=\"author\" content=\"Jari Kuivaniemi\">");
dbs_html_printf("<meta name=\"copyright\" content=\"Jari Kuivaniemi\">");
dbs_html_printf("<meta name=\"format-detection\" content=\"telephone=no\">"); // Safari
dbs_html_printf("<meta name=\"format-detection\" content=\"telephone=no\"/>"); // Safari
dbs_html_printf("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">");
dbs_html_printf("</head>");
dbs_html_printf("<body>");
ressu4_app();
dbs_html_printf("<p>%s", programname);
dbs_html_printf(", sha256(%s)", htmldigest);
dbs_html_printf("</p>");
dbs_html_printf("</body>");
dbs_html_printf("</html>");
}
}
void dba_loop2()
{
int len;
dbs_html_set(0);
len=strlen(html_get_string(1)) +
strlen(html_get_string(2)) +
strlen(html_get_string(3)) +
strlen(html_get_string(4)) +
strlen(html_get_string(5)) +
strlen(html_get_string(6)) +
strlen(html_get_string(7)) +
strlen(html_get_string(8));
log_printf("Content-Length: %d\n",len);
dbs_html_printf("Content-Length: %d", len);
dbs_html_printf("\r\n\r\n");
}
void ressu4_version()
{
fprintf(stdout,"\n%s", programname);
fprintf(stdout," %s\n", copyright);
fflush(stdout);
}
void dba_main(int argc, char *argv[])
{
strcat(filenamehead,procname);
strcat(filenamehead,myport);
ressu4_version();
}
html.c
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include "html.h"
int html_now = 0;
unsigned char *html[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
int html_size[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
void html_set(int bufno)
{
html_now=bufno;
if(html[bufno]==NULL) {
html_size[bufno] = 10;
html[bufno]=malloc(html_size[bufno]);
}
}
int html_get()
{
return(html_now);
}
unsigned char *html_get_string(int bufno)
{
return(html[bufno]);
}
void html_clear()
{
html_set(html_now);
html[html_now][0]='\0';
}
void html_clear_all()
{
int c;
for(c=0;c<HTML_BUFFERS;c++) {
html_set(c);
html_clear();
}
}
static void html_printf_valist(const char *format, va_list ap)
{
int count;
static char *printbuf=NULL;
static int printbuf_len=0;
va_list ap2;
va_copy(ap2,ap);
count=vsnprintf(printbuf, printbuf_len, format, ap) + 1;
if(printbuf_len < count) {
printbuf_len = count;
printbuf=realloc(printbuf, printbuf_len);
count=vsnprintf(printbuf, printbuf_len, format, ap2) + 1;
}
if(html_size[html_now] <
strlen(html[html_now]) +
strlen(printbuf) + 1) {
html_size[html_now] =
strlen(html[html_now]) +
strlen(printbuf) + 1;
html[html_now] = realloc(html[html_now], html_size[html_now]);
}
strcpy(html[html_now]+strlen(html[html_now]), printbuf);
}
void html_printf(const char *format, ...)
{
va_list args;
va_start(args, format);
html_printf_valist(format, args);
//fprintf(stdout,format, args);
va_end(args);
}
void html_buf_printf(int bufno, const char *format, ...)
{
int save_html;
va_list args;
save_html=html_get();
html_set(bufno);
va_start(args, format);
html_printf_valist(format, args);
va_end(args);
html_set(save_html);
}
int indent;
int printedchars=0;
#define aDEBUG28
void html_out_crlf()
{
if(printedchars) {
#ifdef DEBUG28
fprintf(stdout,"(%d)",indent*8+printedchars);
#endif
html_printf("\n");
#ifdef DEBUG28
fprintf(stdout,"\n");
#endif
for(int c=0;c<indent;c++) {
html_printf("\t");
#ifdef DEBUG28
fprintf(stdout,"\t");
#endif
}
printedchars=0;
}
}
#define aDEBUG31 2
void html_parse_name(int size, unsigned char *name, unsigned char **p2)
{
int count;
unsigned char *p,*n;
p = *p2;
count = 0;
n = name;
while(isalpha(*p) || isdigit(*p) || *p=='!') {
if(++count < size)
*n++ = *p;
p++;
count++;
}
*n = '\0';
#ifdef DEBUG31
fprintf(stdout,"[name:%s]",name);
#endif
}
#define aDEBUG36 2
#define aDEBUG37 2
void html_indent(unsigned char *p2)
{
int space, ch, tags, tagfound, intag, inchar;
unsigned char *p,*q,*q2,name[32],tag[48];
p=p2;
ch=0;
indent=0;
inchar=0;
while(*p!='\0') {
space = 0;
while(*p=='\r' || *p=='\n' || *p=='\t' || *p==' ') {
p++;
space = 1;
}
if(!strncmp(p,"<br>",4)) {
p+=4;
html_printf("<br>");
#ifdef DEBUG36
fprintf(stdout,"<br>");
#endif
printedchars+=4;
while(*p=='\r' || *p=='\n' || *p=='\t' || *p==' ')
p++;
#ifdef DEBUG36
fprintf(stdout,"[nextchar:%c]",*p);
#endif
if(strncmp(p,"</",2))
html_out_crlf();
}
if(!strncmp(p,"</",2)) { // Check for end tag
q2 = p;
p += 2;
q = p;
html_parse_name(sizeof(name), name, &q);
q = q2 - 1;
tags = 0;
tagfound = 0;
// Search for start tag backward
sprintf(tag,"<%s", name);
while(q >= p2) {
if(*q == '<') {
if(!strncmp(tag, q, strlen(tag))) {
#ifdef DEBUG36
fprintf(stdout,"[tag:%s]", tag);
#endif
tagfound = 1;
break;
} else
tags++;
}
q--;
}
if(tags && indent > 0) {
indent--;
#ifdef DEBUG36
fprintf(stdout,"[indent:%d]",indent);
fprintf(stdout,"[tagfound:%d]",tagfound);
#endif
html_out_crlf();
}
html_printf("</");
#ifdef DEBUG36
fprintf(stdout,"</");
#endif
space = 0;
intag = 1;
inchar = 0;
#ifdef DEBUG36
fprintf(stdout,"[inchar:%d]",inchar);
#endif
printedchars+=2;
} else if(*p=='<') { // Check for start tag
p++;
q = p;
html_parse_name(sizeof(name),name,&q);
tags = 0;
tagfound = 0;
// Search for end tag forward
sprintf(tag,"</%s",name);
while(*q!='\0') {
if(*q=='<') {
if(!strncmp(tag, q, strlen(tag))) {
#ifdef DEBUG36
fprintf(stdout,"[tag:%s]",tag);
#endif
tagfound = 1;
break;
} else
tags++;
}
q++;
}
html_out_crlf();
if(tags && tagfound) {
indent++;
#ifdef DEBUG36
fprintf(stdout,"[indent:%d]",indent);
fprintf(stdout,"[tagfound:%d]",tagfound);
#endif
}
html_printf("<");
#ifdef DEBUG36
fprintf(stdout,"<");
#endif
space = 0;
intag = 1;
inchar = 0;
#ifdef DEBUG36
fprintf(stdout,"[inchar:%d]",inchar);
#endif
printedchars++;
} else if((isprint(*p) || *p>=128) && *p!='\0') {
if(!inchar && !intag) {
inchar=1;
#ifdef DEBUG36
fprintf(stdout,"[inchar:%d]",inchar);
#endif
//html_out_crlf();
}
int count=0;
for(q=p;(isprint(*q) || *q>=128) && *q!='\0';q++) {
if(*q=='\r' || *q=='\n' || *q=='\t' || *q==' ')
break;
#ifdef DEBUG36
fprintf(stdout,"%c",*q);
#endif
count++;
}
#ifdef DEBUG36
fprintf(stdout,"(%d)",count);
#endif
}
int chars = 0;
// calculate number of chars
q = p;
while((*q!='<' && (isprint(*q) || *q>=128)) && *q!='\0') {
if(*q=='\r' || *q=='\n' || *q=='\t' || *q==' ')
break;
if(*q<0x80 || *q>0xbf) // utf8 too
chars++;
if(*q=='>')
break;
q++;
}
// print line break if needed
if(indent*8+printedchars+chars > 100 && !intag) {
html_out_crlf(); // print nl+indent
space = 0;
}
// print space if needed
if(ch != '>' && // no space after tag
*p != '<' && // no space before tag
printedchars > 0 &&
space) {
html_printf(" ");
#ifdef DEBUG36
fprintf(stdout," ");
#endif
space = 0;
}
//print the string
while((*p != '<' && (isprint(*p) || *p >= 128)) && *p != '\0') {
if(*p == '>') {
intag = 0;
}
if(*p == '\r' || *p == '\n' || *p == '\t' || *p == ' ')
break;
ch = *p;
html_printf("%c", *p);
#ifdef DEBUG36
fprintf(stdout,"%c",*p);
#endif
printedchars++;
if(*p=='>') {
p++;
break;
}
p++;
}
#ifdef DEBUG36
fprintf(stdout,"(%d)",chars);
#endif
} //while(*p!='\0')
#ifdef DEBUG37
fprintf(stdout,"%s",html[html_now]);
#endif
}
dbs.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <poll.h>
#include <time.h>
#include <ctype.h>
#include <sys/time.h>
//#include "db2.h"
#include "sha256.h"
#include "dbs.h"
#ifdef RESSU
#include "ressugen.h"
#endif
#ifdef FORT
#define aFORT_EVENTS 2
static int fort_events = 0;
static unsigned int fort_event_mode = 1;
#endif
#include "fort.h"
#include "html.h"
static unsigned char *copyright = "Copyright (c) 2016-2022 Jari Kuivaniemi, Helsinki, Finland. Kaikki oikeudet pidätetään!";
static char *programname = "DBS version 0.15 ©";
#define html_printf dbs_html_printf
#define IUTIME unsigned long long
unsigned char *procname = "dbs";
int callid=-1;
unsigned char filenamehead[16];
unsigned char *htmlin;
int htmlinlen=2048;
unsigned char htmlrecvheaderlen=0;
unsigned char *htmlrecvheader=NULL;
unsigned char htmlrecvpayloadlen=0;
unsigned char *htmlrecvpayload=NULL;
unsigned char htmlsentheaderlen=0;
unsigned char *htmlsentheader=NULL;
unsigned char htmlsentpayloadlen=0;
unsigned char *htmlsentpayload=NULL;
unsigned char htmlmethod[10];
unsigned char htmlpath[128];
unsigned char htmlversion[32];
unsigned char htmlfilename[64];
unsigned char htmlfileextension[10];
unsigned char htmlhost[32];
unsigned char htmluseragent[1024];
unsigned char htmlcookie[1024];
unsigned char htmlsessionid[33];
unsigned char htmltimeshort[32];
unsigned char htmltime[32];
unsigned char *htmlparams=NULL;
unsigned char htmldigest[HashLen*2+1];
unsigned char htmlmode[10];
unsigned char htmlip[32];
unsigned char htmlsslcipher[64];
unsigned char htmlhostname[64];
unsigned char htmlport[10];
unsigned char htmllanguage[10];
unsigned char htmluseconds[10];
unsigned char htmlprevminutes[32];
unsigned char useragent=0;
unsigned char chrome=0;
unsigned char edg=0;
unsigned char firefox=0;
unsigned char ipad=0;
unsigned char iphone=0;
unsigned char flaglinux=0;
unsigned char safari=0;
#define USE_SEMAPHORES 2
void dump_string(FILE *fp1, unsigned char *p)
{
fprintf(stdout,"{");
while(*p != '\0') {
if(*p == '\\')
fprintf(fp1,"\\\\");
else if(isprint(*p))
fprintf(fp1,"%c", *p);
else
fprintf(fp1,"\\%02x", *p);
p++;
}
fprintf(stdout,"}");
}
static int dbs_parse_hex1(unsigned char **str) /* 20131003 JariK */
{
unsigned char *p;
int digit;
p=*str;
digit=0;
if(*p >= 'a' && *p <= 'f')
digit = *p - 'a' + 10, p++;
else if(*p >= 'A' && *p <= 'F')
digit = *p - 'A' + 10, p++;
else if(*p >= '0' && *p <= '9')
digit = *p - '0', p++;
else digit = -1;
*str = p;
return(digit);
}
static int dbs_parse_html_string(int stringlen, unsigned char *string, unsigned char **html)
{
int c,d, count, ok;
unsigned char *s=string;
unsigned char *h=*html;
ok = 0;
count = 0;
while(isalnum(*h) || *h=='%' || *h=='+'
|| *h == '-' || *h == '_' || *h == '.'
|| *h==',' || *h == '*') {
ok = 1;
if(*h == '%') {
h++;
if((c=dbs_parse_hex1(&h)) >= 0) {
if((d=dbs_parse_hex1(&h)) >= 0) {
c = c * 16 + d;
} else
c = c;
} else
c = 64;
if(++count < stringlen) {
if(c == 0x22)
*s++ = '\'';
else
*s++ = c;
}
} else if(*h == '+') {
if(++count < stringlen)
*s++ = ' ';
h++;
} else {
if(++count < stringlen)
*s++ = *h;
h++;
}
}
*s = '\0';
*html = h;
return(ok);
}
#include <stdarg.h>
int dbs_html_get_string(unsigned char *string,unsigned char **str,int len)
{
int c, d, ok, count;
unsigned char *p, *n;
n = string;
p = *str;
ok = 0;
count = 0;
while(isalnum(*p) || *p == '%'|| *p == '+'
|| *p == '-' || *p == '_' || *p == '='
|| *p=='&' || *p=='.' || *p=='*') {
ok = 1;
if(*p == '%') {
p++;
if((c = dbs_parse_hex1(&p)) >= 0) {
if((d = dbs_parse_hex1(&p)) >= 0) {
c = c * 16 + d;
} else
c = c;
} else
c = 64;
if(count++ < len)
*n++ = c;
} else if(*p == '+') {
if(count++ < len)
*n++ = ' ';
p++;
} else {
if(count++ < len)
*n++ = *p++;
else
p++;
}
}
*n = '\0';
*str = p;
return(ok);
}
int dbs_parse_html_parameter(int namelen, unsigned char *name, int valuelen,unsigned char *value, unsigned char **s)
{
if(dbs_parse_html_string(namelen, name, s) == 0)
return(0);
if((**s) == '=')
(*s)++;
dbs_parse_html_string(valuelen, value, s);
#ifdef OLD1
if(dbs_parse_html_string(valuelen, value, s) == 0)
return(0);
#endif
if(**s == '&')
(*s)++;
return(1);
}
int dbs_get_parameter(char *name, int valuelen, unsigned char *value)
{
int ok;
unsigned char name2[32];
unsigned char *h=htmlparams;
value[0] = '\0';
ok = 0;
while(*h != '\0') {
dbs_parse_html_parameter(sizeof(name2), name2, valuelen, value, &h);
if(!strcmp(name,name2)) {
ok = 1;
break;
}
}
if(ok == 0)
value[0] = '\0';
return(ok);
}
static unsigned long dbs_getseconds()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return((IUTIME)tv.tv_sec);
}
#define aDEBUG11 2
static unsigned char *dbs_html_get_request_line(unsigned char *name, int lenbuffer, unsigned char *buffer)
{
int len;
unsigned char *p, *q, tag[32];
p = htmlin;
#ifdef DEBUG11
fprintf(stdout,"Data:");
dump_string(stdout,p);
fprintf(stdout,"\n");
#endif
sprintf(tag,"\r\n%s:",name);
while(*p != '\0') {
if(!strncmp(p, tag, strlen(tag))) {
p += strlen(tag);
while(isblank(*p))
p++;
q = buffer;
len = 0;
while(*p != '\r' && *p != '\n' && *p != '\0') {
if(++len < lenbuffer)
*q++ = *p;
p++;
}
*q = '\0';
return(buffer);
}
if(*p != '\0')
p++;
}
return(NULL);
}
static void dbs_html_get_request_line_num(unsigned char *name, int lenbuffer, unsigned char *buffer)
{
unsigned char *p;
if((p = dbs_html_get_request_line(name,lenbuffer,buffer)) == NULL)
sprintf(buffer,"0");
#ifdef OLD1
else {
int len = 0;
unsigned char *n = buffer;
while(isdigit(*p)) {
if(++len < lenbuffer)
*n++ = *p;
p++;
}
*n = '\0';
}
#endif
}
void dbs_get_cookie(unsigned char *name, int valuelen, unsigned char *value)
{
int len;
unsigned char *p, *n;
value[0] = '\0';
p = htmlcookie;
while(*p != '\0') {
while(isblank(*p))
p++;
if(!strncmp(p,name,strlen(name))) {
p += strlen(name);
while(isblank(*p))
p++;
if(*p == '=')
p++;
while(isblank(*p))
p++;
n = value;
len = 0;
while(*p != ';' && isprint(*p)) {
if(++len < valuelen)
*n++ = *p;
p++;
}
*n = '\0';
return;
}
while(*p != ';' && *p != '\n' && *p != '\0')
p++;
if(*p == ';')
p++;
while(isblank(*p))
p++;
}
}
static void dbs_html_parse_string(int buflen, char *buf, unsigned char **p2)
{
int len;
unsigned char *p;
p=*p2;
len=0;
while(*p!='\0' && !isblank(*p) && *p!='\n' && *p!='\r') {
if(++len < buflen) {
*buf++ = *p;
}
p++;
}
*buf='\0';
while(isblank(*p))
p++;
*p2 = p;
}
static void dbs_html_parse_filename(int buflen, char *buf, unsigned char *p)
{
int len;
unsigned char *n;
len = 0;
n = buf;
while(*p != '\0') {
if(*p == '/') {
n = buf;
len = 0;
} else {
if(++len < buflen)
*n++ = *p;
}
p++;
}
*n = '\0';
}
static void dbs_html_parse_extension(int buflen, char *buf, unsigned char *p)
{
int len;
unsigned char *n;
len = 0;
n = buf;
while(*p != '\0') {
if(*p == '.') {
n = buf;
len = 0;
} else {
if(++len < buflen)
*n++ = *p;
}
p++;
}
*n = '\0';
}
static unsigned char *dbs_html_get_params()
{
int ok = 0;
unsigned char *p = htmlin;
while(*p != '\0') {
if(!strncmp(p,"\r\n\r\n",4)) {
p += 4;
ok = 1;
break;
}
p++;
}
if(ok)
return(p);
else
return(NULL);
}
#include <stdarg.h>
unsigned char *logbuf=NULL;
int logbuf_len=0;
void log_clear()
{
if(logbuf != NULL)
logbuf[0] = '\0';
}
void log_free()
{
if(logbuf != NULL) {
free(logbuf);
logbuf_len = 0;
logbuf = NULL;
}
}
#define aDEBUG20 2
#define aDEBUG21 2
void log_printf(const char *format, ...)
{
int count,size;
va_list args;
static char *printbuf=NULL;
static int printbuf_len=0;
va_start(args, format);
count=vsnprintf(printbuf, printbuf_len, format, args) + 1;
va_end(args);
if(printbuf_len < count) {
printbuf_len = count;
printbuf=realloc(printbuf, printbuf_len);
va_start(args, format);
count=vsnprintf(printbuf, printbuf_len, format, args) + 1;
va_end(args);
}
#ifdef DEBUG20
fprintf(stdout,"\n%p %d %s %p %d",
printbuf, printbuf_len, printbuf, logbuf, logbuf_len);
#endif
size=(logbuf==NULL? 0:strlen(logbuf))+count;
if(logbuf_len<size) {
unsigned char *temp=logbuf;
logbuf_len = size;
logbuf = realloc(logbuf, logbuf_len);
if(temp == NULL)
logbuf[0] = '\0';
}
#ifdef DEBUG21
fprintf(stdout,"\n%p %d %s",
logbuf, logbuf_len, logbuf);
#endif
strcat(logbuf, printbuf);
}
void log_dump_string(unsigned char *p)
{
while(*p != '\0') {
if(*p == '\\')
log_printf("\\\\");
else if(isprint(*p) || *p == '\r' || *p == '\n')
log_printf("%c",*p);
else
log_printf("\\%02x",*p);
p++;
}
}
static void dbs_add_end_new_str(char *filename, char *string)
{
int ok;
char buffer[256];
FILE *fp1;
ok = 0;
if((fp1 = fopen(filename,"r")) != NULL) {
while(fgets(buffer,sizeof(buffer),fp1) != NULL) {
buffer[strlen(buffer)-1] = '\0';
if(!strcmp(buffer,string)) {
ok = 1;
break;
}
}
fclose(fp1);
}
if(!ok) {
if((fp1 = fopen(filename,"a")) != NULL) {
fprintf(fp1,"%s\n", string);
fclose(fp1);
}
}
}
#define aDEBUG25 2
void dba_loop();
void dba_loop2();
static void dbs_run_loop()
{
unsigned char *p;
p=htmlin;
dbs_html_parse_string(sizeof(htmlmethod), htmlmethod,&p);
dbs_html_parse_string(sizeof(htmlpath), htmlpath, &p);
dbs_html_parse_string(sizeof(htmlversion), htmlversion, &p);
dbs_html_parse_filename(sizeof(htmlfilename), htmlfilename, htmlpath);
dbs_html_parse_extension(sizeof(htmlfileextension), htmlfileextension, htmlfilename);
htmlparams = dbs_html_get_params();
if(htmlparams == NULL)
htmlparams = "";
if(dbs_html_get_request_line("Host", sizeof(htmlhost), htmlhost) == NULL)
htmlhost[0] = '\0';
if(dbs_html_get_request_line("User-Agent", sizeof(htmluseragent), htmluseragent) == NULL)
htmluseragent[0] = '\0';
if(dbs_html_get_request_line("Cookie", sizeof(htmlcookie), htmlcookie)==NULL)
htmlcookie[0] = '\0';
chrome = 0;
edg = 0;
firefox = 0;
ipad = 0;
iphone = 0;
flaglinux = 0;
safari = 0;
useragent=0;
if(htmluseragent[0] != '\0')
useragent = 1;
unsigned char *p2 = htmluseragent;
log_printf(", useragent");
p2=p;
while(*p2 != '\r' && *p2 != '\n') {
if(!strncmp(p2,"Chrome",6)) {
chrome = 1;
log_printf(", chrome");
}
if(!strncmp(p2,"Edg",6)) {
edg = 1;
log_printf(", Edg");
}
if(!strncmp(p2,"Firefox",6)) {
firefox = 1;
log_printf(", firefox");
}
if(!strncmp(p2,"iPad",4)) {
ipad = 1;
log_printf(", ipad");
}
if(iphone==0 && !strncmp(p2,"iPhone",6)) {
iphone = 1;
log_printf(", iphone");
}
if(!strncmp(p2,"Linux",5)) {
flaglinux = 1;
log_printf(", linux");
}
if(!strncmp(p2,"Safari",6)) {
safari = 1;
log_printf(", safari");
}
p2++;
}
log_printf("\n");
html_clear_all();
dba_loop();
#ifdef DEBUG25
log_printf("\nhtml prettyprinter");
#endif
#ifdef DEBUG25
log_printf("\nbuffers1:");
for(int c = 0; c < HTML_BUFFERS; c++) {
log_printf(" %d:%ld", c, strlen(html_get_string(c)));
}
log_printf("\n");
#endif
for(int c = 1; c < HTML_BUFFERS-2; c++) {
p = html_get_string(c);
dbs_html_set(HTML_BUFFERS - 2);
html_printf("%s", p);
dbs_html_set(c);
html_clear();
}
#ifdef DEBUG25
log_printf("\nbuffers2:");
for(int c = 0; c < HTML_BUFFERS; c++) {
log_printf(" %d:%ld",c,strlen(html_get_string(c)));
}
log_printf("\n");
#endif
p = html_get_string(HTML_BUFFERS-2);
dbs_html_set(HTML_BUFFERS - 1);
html_indent(p);
dbs_html_set(HTML_BUFFERS - 2);
html_clear();
#ifdef DEBUG25
log_printf("\nbuffers3:");
for(int c = 0; c < HTML_BUFFERS; c++) {
log_printf(" %d:%ld",c, strlen(html_get_string(c)));
}
log_printf("\n");
#endif
#ifdef DEBUG25
log_printf("html prettyprinter done.\n");
#endif
dba_loop2();
}
#define aDEBUG34 2
#define aDEBUG31 2
static void dbs_run_critical_port()
{
FILE *fp1;
char filename[128];
char filename2[128];
sprintf(filename,"%stimelog.log", filenamehead);
#ifdef DEBUG34
fprintf(stdout,"Writing %s\n", filename);
#endif
if((fp1 = fopen(filename,"a")) != NULL) {
fprintf(fp1,"%s, ip=\"%s\"\n", htmltimeshort, htmlip);
fclose(fp1);
}
sprintf(filename,"%sips.log",filenamehead);
#ifdef DEBUG34
fprintf(stdout,"Writing %s\n",filename);
#endif
dbs_add_end_new_str(filename, htmlip);
sprintf(filename,"%shostname.log",filenamehead);
#ifdef DEBUG34
fprintf(stdout,"Writing %s\n",filename);
#endif
dbs_add_end_new_str(filename, htmlhostname);
if(htmlsslcipher[0] != '\0') {
sprintf(filename,"%sciphers.log",filenamehead);
#ifdef DEBUG34
fprintf(stdout,"Writing %s\n",filename);
#endif
dbs_add_end_new_str(filename, htmlsslcipher);
}
if(htmluseragent[0] != '\0') {
sprintf(filename,"%suseragent.log",filenamehead);
#ifdef DEBUG34
fprintf(stdout,"Writing %s\n", filename);
#endif
dbs_add_end_new_str(filename,htmluseragent);
}
sprintf(filename2,"%scallid.dat", filenamehead);
#ifdef DEBUG34
fprintf(stdout,"Reading %s\n", filename2);
#endif
if((fp1 = fopen(filename2, "r")) != NULL) {
unsigned char buffer16[16];
fgets(buffer16, sizeof(buffer16), fp1);
callid = atoi(buffer16);
fclose(fp1);
} else {
callid = 0;
}
log_printf("callid:%d\n",callid);
sprintf(filename,"%shtml.log",filenamehead);
#ifdef DEBUG34
fprintf(stdout,"Writing %s\n",filename);
#endif
if((fp1 = fopen(filename, "a")) != NULL) {
fprintf(fp1,"htmltime: \"%s\", htmltimeshort: \"%s\", ip=\"%s\", callid=\"%d\"\n",
htmltime, htmltimeshort, htmlip, callid);
fprintf(fp1,"%s\n", htmlin);
for(int c = 0; c < HTML_BUFFERS; c++) {
#ifdef DEBUG31
fprintf(stdout,"%d", c);
fprintf(stdout," %p", html_get_string(c));
if(html_get_string(c) != NULL)
fprintf(stdout,"%s", html_get_string(c));
#endif
if(html_get_string(c) != NULL &&
strlen(html_get_string(c)) > 0) {
fprintf(fp1,"%d: %s\n", c, html_get_string(c));
}
}
fclose(fp1);
}
callid++; // next call id
#ifdef DEBUG34
fprintf(stdout,"Writing %s\n",filename2);
#endif
if((fp1=fopen(filename2, "w")) != NULL) {
fprintf(fp1,"%d\n", callid);
fclose(fp1);
}
}
struct lfield {
unsigned char *name;
int valuetype;
unsigned char *value;
int size;
} lfields[] = {
{ "procname", 1, (unsigned char *)&procname, 32 },
{ "timeshort", 0, htmltimeshort, sizeof(htmltimeshort) },
{ "time", 0, htmltime, sizeof(htmltime) },
{ "hostname", 0, htmlhostname, sizeof(htmlhostname) },
{ "host", 0, htmlhost, sizeof(htmlhost) },
{ "useragent", 0, htmluseragent, sizeof(htmluseragent) },
{ "method", 0, htmlmethod, sizeof(htmlmethod) },
{ "path", 0, htmlpath, sizeof(htmlpath) },
{ "version", 0, htmlversion, sizeof(htmlversion) },
{ "filename", 0, htmlfilename, sizeof(htmlfilename) },
{ "fileextension", 0, htmlfileextension, sizeof(htmlfileextension) },
{ "cookie", 0, htmlcookie, sizeof(htmlcookie) },
{ "sessionid", 0, htmlsessionid, sizeof(htmlsessionid) },
{ "params", 1, (unsigned char *)&htmlparams, 0 },
{ "recvheader", 1, (unsigned char *)&htmlrecvheader, sizeof(htmlrecvheader) },
{ "recvpayload", 1, (unsigned char *)&htmlrecvpayload, sizeof(htmlrecvpayload) },
{ "sentheader", 1, (unsigned char *)&htmlsentheader, sizeof(htmlsentheader) },
{ "sentpayload", 1, (unsigned char *)&htmlsentpayload, sizeof(htmlsentpayload) },
{ "digest", 0, htmldigest, sizeof(htmldigest) },
{ "mode", 0, htmlmode, sizeof(htmlmode) },
{ "ip", 0, htmlip, sizeof(htmlip) },
{ "sslcipher", 0, htmlsslcipher, sizeof(htmlsslcipher) },
{ "port", 0, htmlport, sizeof(htmlport) },
{ "language", 0, htmllanguage, sizeof(htmllanguage) },
{ "useconds", 0, htmluseconds, sizeof(htmluseconds) },
{ "prevminutes", 0, htmlprevminutes, sizeof(htmlprevminutes) },
};
struct lfile {
unsigned char *query;
} lfiles[] = {
{ "" },
};
#define aDEBUG35 2
#define VALUEUTF8 2
int db4_compile_field(int buflength, unsigned char *buf, unsigned char *name)
{
int size=0;
unsigned char *value=NULL;
for(int c = 0; c < sizeof(lfields) / sizeof(struct lfield); c++) {
if(!strcmp(name, lfields[c].name)) {
if(lfields[c].valuetype == 0) {
value = lfields[c].value;
break;
} else if(lfields[c].valuetype == 1) {
value = *((unsigned char **)lfields[c].value);
break;
}
}
}
size = 7 + strlen(name);
if(value != NULL) {
unsigned char *p;
p = value;
while(*p != '\0') {
if(*p == '"')
size+=2;
else if(*p=='\\')
size+=2;
#ifdef VALUEUTF8
else if(isprint(*p) || *p>=0x80)
#else
else if(isprint(*p))
#endif
size++;
else
size+=3;
p++;
}
}
if(size < buflength) {
strcat(buf,"'");
strcat(buf,name);
strcat(buf,"' = \"");
if(value != NULL) {
unsigned char *p;
p=value;
while(*p != '\0') {
if(*p == '"') {
unsigned char char3[3];
sprintf(char3,"\\\"");
strcat(buf,char3);
} else if(*p == '\\') {
strcat(buf,"\\\\");
#ifdef VALUEUTF8
} else if(isprint(*p) || *p >= 0x80) {
#else
} else if(isprint(*p)) {
#endif
unsigned char char2[2];
sprintf(char2,"%c",*p);
strcat(buf, char2);
} else {
unsigned char char4[4];
sprintf(char4,"\\%02x",*p);
strcat(buf, char4);
}
p++;
}
#ifdef DEBUG35
unsigned char *q=buf;
while(*q != '\0') {
if(isprint(*q))
fprintf(stdout,"%c",*q);
else
fprintf(stdout,"\\%02x",*q);
q++;
}
#endif
}
strcat(buf,"\"");
}
return(size);
}
int db4_compile_set(int buflen, unsigned char *buf2)
{
int size, count, first=1;
unsigned char *buf = buf2;
size=0;
if(buflen > 0)
buf[0]='\0';
for(int c = 0; c < sizeof(lfields) / sizeof(struct lfield); c++) {
count = 0;
if(!first) {
if(2 < buflen)
strcat(buf,", ");
count += 2;
}
count += db4_compile_field(buflen,buf,lfields[c].name);
buf += count;
buflen -= count;
size += count;
first = 0;
}
return(size);
}
#define DEBUG39
static void dbs_run_critical_all() {
int count, buflen=0;
unsigned char *buf=NULL;
#ifdef DEBUG39
fprintf(stdout,"db4_compile_set() %d\n",buflen);
fflush(stdout);
#endif
count = db4_compile_set(buflen,buf) + 1;
if(buflen < count) {
buflen = count;
buf = realloc(buf,buflen);
#ifdef DEBUG39
fprintf(stdout,"db4_compile_set() %d\n",buflen);
fflush(stdout);
#endif
count = db4_compile_set(buflen,buf)+1;
}
FILE *fp1;
if((fp1 = fopen("dbs.skk","a")) != NULL) {
fprintf(fp1,"%s\n",buf);
fclose(fp1);
}
fprintf(stdout,"%s(%ld)\n",buf,strlen(buf));
fflush(stdout);
//for(int c=0;c<sizeof(lfiles)/sizeof(struct lfile);c++) {
//fprintf(stdout,"%s",lfiles[c].filename);
//}
}
#include <errno.h>
#include <semaphore.h>
#include <fcntl.h>
unsigned char semname[32], sem2name[32];
sem_t *mutex, *mutex2;
extern char *myport;
void dbs_open_semaphores()
{
// semaphore for critical_port
sprintf(semname,"dbssem%s", myport);
if(sem_unlink(semname) == 0) {
fprintf(stdout,"%s: previous semaphore %s removed\n", procname, semname);
}
#ifdef DEBUG42
fprintf(stdout,"sem_open()\n");
#endif
if((mutex = sem_open(semname, O_CREAT | O_EXCL, 0644, 1)) == SEM_FAILED) {
fprintf(stderr,"\n%s: cannot sem_open()", procname);
fprintf(stderr," errno %d", errno);
fprintf(stderr, "(%s)", strerror(errno));
fprintf(stderr,"\n");
perror("sem_open");
}
// semaphore for critical_all
sprintf(sem2name,"dbssem");
if(sem_unlink(sem2name) == 0) {
fprintf(stdout,"%s: previous semaphore %s removed\n", procname, sem2name);
}
#ifdef DEBUG42
fprintf(stdout,"sem_open()\n");
#endif
if((mutex2 = sem_open(sem2name, O_CREAT | O_EXCL, 0644, 1)) == SEM_FAILED) {
fprintf(stderr,"\n%s: cannot sem_open()", procname);
fprintf(stderr," errno %d", errno);
fprintf(stderr, "(%s)", strerror(errno));
fprintf(stderr,"\n");
perror("sem_open");
}
}
void dbs_close_semaphores()
{
sem_unlink(semname);
sem_close(mutex);
}
void dbs_run_critical_sections()
{
#ifdef USE_SEMAPHORES
fprintf(stdout,"locking port semaphore(child)");
fprintf(stdout,"\n");
fflush(stdout);
#ifdef DEBUG42
fprintf(stdout,"sem_wait()\n");
fflush(stdout);
#endif
if(sem_wait(mutex) == -1) {
fprintf(stderr, "%s: cannot sem_wait()", procname);
fprintf(stderr, ", errno: %d", errno);
fprintf(stderr, "(%s)", strerror(errno));
fprintf(stderr,"\n");
perror("sem_wait");
}
fprintf(stdout,"critical section (child)");
fprintf(stdout,"\n");
fflush(stdout);
#endif
#ifdef DEBUG42
fprintf(stdout,"dbs_run_critical_port()\n");
fflush(stdout);
#endif
dbs_run_critical_port();
#ifdef USE_SEMAPHORES
fprintf(stdout,"end critical section (child)");
fprintf(stdout,"\n");
fflush(stdout);
#ifdef DEBUG42
fprintf(stdout,"sem_post()\n");
#endif
if(sem_post(mutex) == -1) {
fprintf(stderr, "%s: cannot sem_post()", procname);
fprintf(stderr, ", errno: %d\n", errno);
fprintf(stderr, "(%s)", strerror(errno));
perror("sem_post");
}
fprintf(stdout,"release port semaphore(child)");
fprintf(stdout,"\n");
fflush(stdout);
fprintf(stdout,"locking all semaphore(child)");
fprintf(stdout,"\n");
fflush(stdout);
#ifdef DEBUG42
fprintf(stdout,"sem_wait()\n");
fflush(stdout);
#endif
if(sem_wait(mutex2) == -1) {
fprintf(stderr, "%s: cannot sem_wait()", procname);
fprintf(stderr, ", errno: %d", errno);
fprintf(stderr, "(%s)", strerror(errno));
fprintf(stderr,"\n");
perror("sem_wait");
}
fprintf(stdout,"critical section (child)");
fprintf(stdout,"\n");
fflush(stdout);
#endif
#ifdef DEBUG42
fprintf(stdout,"dbs_run_critical_all()\n");
fflush(stdout);
#endif
dbs_run_critical_all();
#ifdef USE_SEMAPHORES
fprintf(stdout,"end critical section (child)");
fprintf(stdout,"\n");
fflush(stdout);
#ifdef DEBUG42
fprintf(stdout,"sem_post()\n");
#endif
if(sem_post(mutex2) == -1) {
fprintf(stderr, "%s: cannot sem_post()", procname);
fprintf(stderr, ", errno: %d\n", errno);
fprintf(stderr, "(%s)", strerror(errno));
perror("sem_post");
}
fprintf(stdout,"release all semaphore(child)");
fprintf(stdout,"\n");
fflush(stdout);
}
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <signal.h>
#include <netinet/in.h>
#include <arpa/inet.h>
/* See: http://h41379.www4.hpe.com/doc/83final/ba554_90007/ch04s03.html */
#include <netdb.h>
#define backlog 64
int s,news;
char cert_file[128] = "fullchain.pem";
char privatekey_file[128] = "privkey.pem";
#define DEBUG42 2
static int server_getaddrinfo(unsigned char *myport, struct addrinfo **res)
{
int status;
struct addrinfo hints;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
#ifdef DEBUG42
fprintf(stdout,"getaddrinfo()\n");
#endif
if ((status = getaddrinfo(NULL, myport, &hints, res)) != 0) {
fprintf(stderr, "\n%s: getaddrinfo error: %s",
procname, gai_strerror(status));
fprintf(stderr, ", error code %d\n", status);
//fflush(stderr);
}
return(status);
}
static int server_socket(struct addrinfo *res)
{
int s;
#ifdef DEBUG42
fprintf(stdout,"socket()\n");
#endif
if((s = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) == -1) {
fprintf(stderr, "%s: socket()", procname);
fprintf(stderr, ", errno: %d", errno);
fprintf(stderr, "(%s)", strerror(errno));
fprintf(stderr,"\n");
perror("socket");
//fflush(stderr);
}
return(s);
}
static void server_bind(int s, struct addrinfo *res)
{
#ifdef DEBUG42
fprintf(stdout,"bind()\n");
#endif
if(bind(s, res->ai_addr, res->ai_addrlen) == -1) {
int errerrno = errno;
if(errerrno == 98) {
fprintf(stdout,"%s cannot bind, waiting to bind", procname);
while(errerrno == 98) {
sleep(10);
fprintf(stdout,".");
fflush(stdout);
bind(s, res->ai_addr, res->ai_addrlen);
errerrno = errno;
}
fprintf(stdout,"bind done!\n");
//fflush(stdout);
} else {
int errerrno = errno;
fprintf(stderr,"\n%s: cannot bind()", procname);
fprintf(stderr,", errno: %d", errerrno);
fprintf(stderr, "(%s)", strerror(errerrno));
fprintf(stderr,"\n");
perror("bind");
//fflush(stderr);
}
}
}
static int server_listen(int s)
{
int retval;
#ifdef DEBUG42
fprintf(stdout,"listen()\n");
#endif
if((retval = listen(s,backlog)) == -1) { // ==!
int errerrno = errno;
fprintf(stderr,"\n%s: cannot listen()", procname);
fprintf(stderr,", errno %d", errerrno);
fprintf(stderr, "(%s)", strerror(errerrno));
fprintf(stderr,"\n");
perror("listen");
//fflush(stderr);
}
return(retval);
}
static void server_close(int s)
{
#ifdef DEBUG42
fprintf(stdout,"close(s)\n");
#endif
if(close(s) == -1) {
int errerrno=errno;
fprintf(stderr,"\n%s: cannot close()", procname);
fprintf(stderr,", errno %d", errerrno);
fprintf(stderr, "(%s)", strerror(errerrno));
fprintf(stderr,"\n");
perror("close");
//fflush(stderr);
}
}
static int server_basic_socket()
{
int s;
struct addrinfo *res;
server_getaddrinfo(myport, &res);
s = server_socket(res);
server_bind(s, res);
freeaddrinfo(res);
server_listen(s);
return(s);
}
#define TIMEFORMAT "%Z%Y%m%d%H%M%S"
#define HTMLTIMEFORMAT "%a, %d %b %Y %H:%M:%S %Z"
// statistics for the previous minutes
unsigned long prevhtmlseconds=0, htmlseconds;
unsigned int callstats[15] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
static void dbs_time_vars()
{
htmlseconds = dbs_getseconds();
strftime(htmltimeshort, sizeof(htmltimeshort), TIMEFORMAT,
localtime((time_t *)&htmlseconds));
strftime(htmltime, sizeof(htmltime), HTMLTIMEFORMAT,
localtime((time_t *)&htmlseconds));
int c, d;
unsigned long prevminute = prevhtmlseconds / 60 * 60;
unsigned long minute = htmlseconds / 60 * 60;
unsigned long diff = (minute - prevminute) / 60;
// statistics for the previous 10 minutes
if(diff != 0) {
for(c = 15, d = 15 - diff; d >= 0; c--, d--) {
callstats[c] = callstats[d];
}
for(; c >= 0; c--)
callstats[c] = 0;
}
callstats[0]++;
fprintf(stdout,"previous minutes");
fprintf(stdout," prevmin:%10lu", prevminute);
fprintf(stdout," min:%10lu", minute);
fprintf(stdout," diff:%2lu", diff);
fprintf(stdout," stat:");
htmlprevminutes[0]='\0';
for(c=0;c<15;c++) {
fprintf(stdout," %d", callstats[c]);
unsigned char buffer[10];
sprintf(buffer,"%d", callstats[c]);
if(strlen(htmlprevminutes) + 1 + strlen(buffer) < sizeof(htmlprevminutes)) {
if(strlen(htmlprevminutes) > 0)
strcat(htmlprevminutes, " ");
strcat(htmlprevminutes, buffer);
}
}
fprintf(stdout,"\n");
prevhtmlseconds = htmlseconds;
}
unsigned long long dbs_get_useconds()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return(tv.tv_usec + 1000000 * tv.tv_sec);
}
#include <sys/socket.h>
static void dbs_server_vars(struct sockaddr_in sa_cli, int addr_size, char *name)
{
strcpy(htmlip, inet_ntoa(sa_cli.sin_addr));
sprintf(htmlport,"%d", sa_cli.sin_port);
htmlsslcipher[0] = '\0';
htmlhostname[0] = '\0';
log_printf("\n%s, Connection(%s) from %x", procname, name, sa_cli.sin_addr.s_addr);
log_printf(", ip %s", htmlip);
log_printf(", port %s", htmlport);
log_printf(", at %s", htmltime);
char host[NI_MAXHOST], serv[NI_MAXSERV];
host[0] = '\0';
serv[0] = '\0';
if(getnameinfo((struct sockaddr *)&sa_cli, addr_size, host, NI_MAXHOST, serv, NI_MAXSERV, NI_NUMERICHOST | NI_NUMERICSERV) == 0) {
log_printf(", numeric hostname:%s", host);
log_printf(", numeric service:%s", serv);
} else {
log_printf(", numeric hostname:????");
log_printf(", numeric service:????");
}
host[0] = '\0';
serv[0] = '\0';
if(getnameinfo((struct sockaddr *)&sa_cli, addr_size, host, NI_MAXHOST, serv, NI_MAXSERV, NI_NUMERICSERV) == 0) {
log_printf(", name hostname:%s", host);
log_printf(", service:%s", serv);
strncpy(htmlhostname, host, sizeof(htmlhostname));
} else {
log_printf(", name hostname:????");
log_printf(", service:????");
}
log_printf("\n");
}
#define DEBUG61 2
static void dbs_get_header(int *len, unsigned char **buf, unsigned char *text)
{
int count;
unsigned char *p;
if(text == NULL)
text = "";
#ifdef DEBUG61
fprintf(stdout,"get_header(): text:%s(%ld)\n", text, strlen(text));
fflush(stdout);
#endif
p = text;
count = 0;
while(*p != '\0' &&
strncmp(p,"\r\n\r\n",4) ) {
fprintf(stdout," %c", *p);
fflush(stdout);
p++;
count++;
}
if(!strncmp(p,"\r\n", 2))
count += 2; // include one cr-lf pair
count++; // and '\0'
if(*len < count) {
*len = count;
*buf = realloc(*buf,*len);
}
strncpy(*buf, text, count - 1);
*(*buf + count - 1) = '\0';
}
static void dbs_get_payload(int *len, unsigned char **buf, unsigned char *text)
{
int count;
unsigned char *p;
if(text == NULL)
text = "";
#ifdef DEBUG61
fprintf(stdout,"get_payload(), text:%s(%ld)\n", text, strlen(text));
fflush(stdout);
#endif
p = text;
count = 0;
while(*p != '\0' &&
strncmp(p,"\r\n\r\n",4) ) {
fprintf(stdout," %c",*p);
fflush(stdout);
p++;
}
if(!strncmp(p,"\r\n\r\n",4))
p+=4; // include one cr-lf pair
count = strlen(p) + 1;
if(*len < count) {
*len = count;
*buf = realloc(*buf, *len);
}
strncpy(*buf, p, count);
*(*buf + count - 1) = '\0';
}
#ifdef SENT_HTML_LOG
static void dbs_get_payload2(int *len, unsigned char **buf, unsigned char *text)
{
int count;
unsigned char *p;
if(text == NULL)
text = "";
#ifdef DEBUG61
fprintf(stdout,"get_payload(), text:%s(%ld)\n",text,strlen(text));
fflush(stdout);
#endif
p = text;
count = strlen(text) + 1;
if(*len < count) {
*len = count;
*buf = realloc(*buf,*len);
}
strcpy(*buf, p);
}
#endif
#define aSENT_HTML_LOG 2
static void dbs_query_vars()
{
dbs_get_header((int *)&htmlrecvheaderlen, &htmlrecvheader, htmlin);
dbs_get_payload((int *)&htmlrecvpayloadlen, &htmlrecvpayload, htmlin);
dbs_get_header((int *)&htmlsentheaderlen, &htmlsentheader, html_get_string(0));
#ifdef SENT_HTML_LOG
dbs_get_payload2((int *)&htmlsentpayloadlen, &htmlsentpayload, html_get_string(HTML_BUFFERS-1));
#endif
}
#define DEBUG38 2
static void http_client(int news, struct sockaddr_in sa_cli, int addr_size, char *name)
{
int clen = 0;
int reads = 0;
int first = 1;
int bytes, totalbytes = 0;
unsigned char buffer10[10];
unsigned long long useconds;
useconds = dbs_get_useconds();
htmlparams = NULL;
htmlin[0] = '\0';
dbs_server_vars(sa_cli, addr_size, name);
while(htmlparams == NULL ||
clen-strlen(htmlparams) > 0) {
if(!first) {
log_printf(", ");
}
struct pollfd fds;
fds.fd = news;
fds.events = POLLIN;
bytes = 0;
int retval = poll(&fds,1,1024*1024);
log_printf("******poll: %d\n",retval);
if(retval > 0) { // -1 err, 0 expire
#ifdef DEBUG42
fprintf(stdout,"read()\n");
#endif
if((bytes = read(news, htmlin + totalbytes, htmlinlen - totalbytes)) < 0) {
fprintf(stderr,"\n%s: cannot read()\n", procname);
perror("read");
//fflush(stderr);
}
if(retval > 0)
reads++;
}
log_printf("(%d bytes)", bytes);
if(bytes == 0)
break;
if(bytes > 3 &&
!isprint(htmlin[0]) &&
!isprint(htmlin[1]) &&
!isprint(htmlin[2])) {
log_printf("https packet?\n");
htmlin[0] = '\0';
totalbytes = 0;
bytes = 0;
break;
}
*(htmlin + totalbytes + bytes) = '\0';
totalbytes += bytes;
if(totalbytes >= htmlinlen) {
// plus space for '\0'
htmlin=realloc(htmlin, htmlinlen*2+1);
htmlinlen *= 2;
}
htmlparams = dbs_html_get_params();
unsigned char *p = htmlin;
dbs_html_parse_string(sizeof(htmlmethod), htmlmethod,&p);
if(!strcmp(htmlmethod, "GET"))
break;
dbs_html_get_request_line_num("Content-Length", sizeof(buffer10), buffer10);
clen = atoi(buffer10);
first = 0;
}
if(totalbytes != 0) {
log_printf("\n%d reads", reads);
log_printf(", received %d chars", totalbytes);
log_printf(", read %d total bytes", totalbytes);
log_printf(", input buffer size %d chars", htmlinlen);
log_printf(", data=\"");
log_dump_string(htmlin);
log_printf("\"\n");
dbs_run_loop();
log_printf("buffers(html):");
for(int c = 0; c < HTML_BUFFERS; c++) {
log_printf(" %d:%ld", c, strlen(html_get_string(c)));
if(strlen(html_get_string(c)) > 0) {
if((bytes = write(news, html_get_string(c), strlen(html_get_string(c)))) == -1) {
fprintf(stderr,"\n%s: cannot write() dbs_html[%d]\n", procname, c);
perror("write");
//fflush(stderr);
}
}
}
log_printf("\n");
}
dbs_query_vars();
useconds = dbs_get_useconds() - useconds;
sprintf(htmluseconds,"%lld", useconds);
}
int beepaccept=1;
#define DEBUG45 2
#define DEBUG57 2
static void http_server()
{
int quit, reset, addr_size;
struct sockaddr_in sa_cli;
signal(SIGPIPE, SIG_IGN);
signal(SIGCHLD, SIG_IGN);
dbs_open_semaphores();
// plus space for '\0'
htmlin = malloc(htmlinlen+1);
reset = 1;
quit = 0;
for(;;) {
if(quit) {
break;
}
if(reset) {
s = server_basic_socket();
reset = 0;
}
fprintf(stdout,"\n");
fflush(stdout);
addr_size = sizeof(sa_cli);
#ifdef DEBUG42
fprintf(stdout,"accept()\n");
#endif
if((news = accept(s, (struct sockaddr *)&sa_cli, &addr_size)) == -1) {
fprintf(stderr,"\n%s: cannot accept()\n", procname);
perror("accept");
//fflush(stderr);
}
dbs_time_vars();
if(beepaccept) {
fprintf(stderr,"\a");
fflush(stderr);
}
pid_t pid;
#ifdef DEBUG45
fprintf(stdout,"Fork start (parent)");
fprintf(stdout," getpid:%d getppid:%d", getpid(), getppid());
fprintf(stdout,"\n");
fflush(stdout);
#endif
#ifdef DEBUG42
fprintf(stdout,"fork()\n");
#endif
if((pid = fork()) < 0) {
dbs_close_semaphores();
fprintf(stderr,"\n%s: cannot fork()", procname);
fprintf(stderr,", errno %d", errno);
fprintf(stderr, "(%s)", strerror(errno));
fprintf(stderr, "\n");
perror("close");
//fflush(stderr);
exit(1);
} else if(pid == 0) { // child
#ifdef DEBUG42
fprintf(stdout,"log_clear()\n");
#endif
log_clear();
#ifdef DEBUG42
fprintf(stdout,"log_printf()\n");
#endif
log_printf("==========\n");
#ifdef DEBUG45
fprintf(stdout,"Fork start (child)");
fprintf(stdout," pid:%d getpid:%d getppid:%d", pid, getpid(), getppid());
fprintf(stdout,"\n");
fflush(stdout);
#endif
close(s);
#ifdef DEBUG42
fprintf(stdout,"http_client()\n");
#endif
http_client(news, sa_cli, addr_size, "http");
#ifdef DEBUG57
fprintf(stdout,"%s", logbuf);
fflush(stdout);
#ifdef DEBUG42
fprintf(stdout,"log_clear()\n");
#endif
log_clear();
#endif
dbs_run_critical_sections();
#ifdef DEBUG42
fprintf(stdout,"server_close(news)\n");
#endif
server_close(news);
fprintf(stdout,"%s", logbuf);
fflush(stdout);
#ifdef DEBUG42
fprintf(stdout,"log_clear()\n");
#endif
log_clear();
#ifdef DEBUG45
fprintf(stdout,"Fork end (child)");
fprintf(stdout," pid:%d getpid:%d getppid:%d", pid, getpid(), getppid());
fprintf(stdout,"\n");
fflush(stdout);
#endif
exit(0);
}
#ifdef DEBUG45
fprintf(stdout,"Fork end (parent)");
fprintf(stdout," pid:%d getpid:%d getppid:%d", pid, getpid(), getppid());
fprintf(stdout,"\n");
fflush(stdout);
#endif
#ifdef DEBUG42
fprintf(stdout,"server_close(news)\n");
#endif
server_close(news);
} // for(;;)
dbs_close_semaphores();
}
static void https_client(int news, SSL_CTX *ctx, struct sockaddr_in sa_cli, int addr_size, char *name)
{
int status, ok;
unsigned char buffer10[10];
SSL *ssl;
X509 *peer_cert;
unsigned long long useconds;
useconds = dbs_get_useconds();
ok = 1;
dbs_server_vars(sa_cli, addr_size, name);
#ifdef DEBUG42
fprintf(stdout,"SSL_new()\n");
#endif
if((ssl = SSL_new(ctx)) == NULL) {
fprintf(stdout,"\n%s: cannot SSL_new()", procname);
}
#ifdef DEBUG42
fprintf(stdout,"SSL_set_fd()\n");
#endif
if(SSL_set_fd(ssl,news) != 1) {
fprintf(stdout,"\n%s: cannot SSL_set_fd()\n", procname);
}
#ifdef DEBUG42
fprintf(stdout,"SSL_accept()\n");
#endif
if((status = SSL_accept(ssl)) < 0) {
fprintf(stdout,"\n%s: cannot SSL_accept(), retval: %d\n", procname,status);
}
#ifdef DEBUG42
fprintf(stdout,"SSL_get_peer_certificate()\n");
#endif
peer_cert = SSL_get_peer_certificate(ssl);
if(peer_cert == NULL) {
log_printf(", No peer certificate");
}
log_printf("\n");
int clen = 0;
int reads = 0;
int first = 1;
int bytes, totalbytes = 0;
htmlparams = NULL;
htmlin[0] = '\0';
while(htmlparams == NULL || clen-strlen(htmlparams) > 0) {
if(!first) {
log_printf(", ");
}
int tries = 0;
for(;;) {
bytes = SSL_read(ssl, htmlin+totalbytes, htmlinlen-totalbytes);
int errerrno, err, err2;
errerrno = errno;
err = SSL_get_error(ssl, bytes);
err2 = ERR_get_error();
log_printf("\nSSL_read()");
log_printf(", retval %d", bytes);
log_printf(", errno: %d", errerrno);
log_printf(", SSL_get_error(): %d", err);
log_printf(", ERR_get_error(): %d", err2);
while((err2 = ERR_get_error()) != 0)
log_printf(", %d",err2);
if(bytes >= 0) {
reads++;
break;
}
if(bytes < 0) {
if(++tries < 5 && (err == 1 || err == 5)) {
usleep(1024 * 512 / 5);
log_printf(" try:%d", tries);
continue;
}
log_printf("cannot SSL_read()\n");
ok = 0;
break;
} // if(bytes
break;
} // for(;;)
log_printf("(%d bytes)", bytes);
if(!ok)
break;
*(htmlin + totalbytes + bytes) = '\0';
if(bytes == 0)
break;
totalbytes += bytes;
if(totalbytes >= htmlinlen) {
// plus space for '\0'
htmlin=realloc(htmlin, htmlinlen * 2 + 1);
htmlinlen *= 2;
}
htmlparams = dbs_html_get_params();
unsigned char *p=htmlin;
dbs_html_parse_string(sizeof(htmlmethod), htmlmethod,&p);
if(!strcmp(htmlmethod,"GET"))
break;
dbs_html_get_request_line_num("Content-Length",
sizeof(buffer10), buffer10);
clen = atoi(buffer10);
first = 0;
}
log_printf("\n%d reads", reads);
log_printf(", received %d chars", totalbytes);
log_printf(", read %d total bytes", totalbytes);
log_printf(", input buffer size %d chars", htmlinlen);
log_printf(", data=\"");
log_dump_string(htmlin);
log_printf("\"\n");
strncpy(htmlsslcipher, SSL_get_cipher(ssl), sizeof(htmlsslcipher));
if(ok)
dbs_run_loop();
if(ok) {
log_printf("buffers(ssl):");
for(int c = 0; c < HTML_BUFFERS; c++) {
log_printf(" %d:%ld", c, strlen(html_get_string(c)));
if(strlen(html_get_string(c)) > 0) {
#ifdef DEBUG42
fprintf(stdout,"SSL_write()\n");
#endif
if((status = SSL_write(ssl, html_get_string(c), strlen(html_get_string(c)))) < 1) {
fprintf(stdout,"\n%s: cannot SSL_write(), buffer %d, status: %d, SSL error: %d",
procname, c, status, SSL_get_error(ssl, status));
}
}
}
}
log_printf("\n");
log_printf("\nSSL connection using %s", htmlsslcipher);
log_printf("\n");
#ifdef DEBUG42
fprintf(stdout,"dbs_query_vars()\n");
#endif
dbs_query_vars();
useconds = dbs_get_useconds() - useconds;
sprintf(htmluseconds,"%lld", useconds);
#ifdef DEBUG42
fprintf(stdout,"SSL_free()\n");
#endif
SSL_free(ssl);
}
static SSL_CTX *server_https_init()
{
SSL_METHOD *method=NULL;
SSL_CTX *ctx=NULL;
#ifdef DEBUG42
fprintf(stdout,"SSL_library_init()\n");
#endif
SSL_library_init();
#ifdef DEBUG42
fprintf(stdout,"OpenSSL_add_ssl_algorithms()\n");
#endif
OpenSSL_add_ssl_algorithms();
#ifdef DEBUG42
fprintf(stdout,"OpenSSL_add_ciphers()\n");
#endif
OpenSSL_add_all_ciphers();
#ifdef DEBUG42
fprintf(stdout,"OpenSSL_load_error_strings()\n");
#endif
SSL_load_error_strings();
#ifdef DEBUG42
fprintf(stdout,"SSLv23_server_method()\n");
#endif
if((method = (SSL_METHOD *)
SSLv23_server_method()) == NULL) {
fprintf(stderr,"\n%s: cannot SSLv3_server_method()\n", procname);
//fflush(stderr);
}
#ifdef DEBUG42
fprintf(stdout,"SSL_CTX_new()\n");
#endif
if((ctx=SSL_CTX_new(method)) == NULL) {
fprintf(stderr,"\n%s: cannot SSL_CTX_new()\n", procname);
}
#ifdef DEBUG42
fprintf(stdout,"SSL_CTX_use_certificate_file()\n");
#endif
if(SSL_CTX_use_certificate_file(ctx, cert_file, SSL_FILETYPE_PEM) != 1) {
int err2;
err2=ERR_get_error();
fprintf(stderr,"\n%s: cannot SSL_CTX_use_certificate_file()", procname);
fprintf(stderr,", ERR_get_error(): %d", err2);
while((err2 = ERR_get_error()) != 0)
fprintf(stderr,", %d", err2);
fprintf(stderr,"\n");
fflush(stderr);
}
#ifdef DEBUG42
fprintf(stdout,"SSL_CTX_use_PrivateKey_file()\n");
#endif
if(SSL_CTX_use_PrivateKey_file(ctx, privatekey_file, SSL_FILETYPE_PEM) != 1) {
int err2;
err2=ERR_get_error();
fprintf(stderr,"\n%s: cannot SSL_CTX_use_PrivateKey_file()", procname);
fprintf(stderr,", ERR_get_error(): %d", err2);
while((err2 = ERR_get_error()) != 0)
fprintf(stderr,", %d", err2);
fprintf(stderr,"\n");
fflush(stderr);
}
#ifdef DEBUG42
fprintf(stdout,"SSL_CTX_load_verify_locations()\n");
#endif
if(SSL_CTX_load_verify_locations(ctx, cert_file, NULL) != 1) {
int err2;
err2 = ERR_get_error();
fprintf(stderr,"\n%s: cannot SSL_CTX_load_verify_locations()", procname);
fprintf(stderr,", ERR_get_error(): %d", err2);
while((err2 = ERR_get_error()) != 0)
fprintf(stderr,", %d", err2);
}
return(ctx);
}
#define DEBUG59 2
#define DEBUG81 2
static void https_server()
{
int quit, reset, addr_size;
//SSL_METHOD *method=NULL;
SSL_CTX *ctx=NULL;
struct sockaddr_in sa_cli;
signal(SIGPIPE, SIG_IGN);
signal(SIGCHLD, SIG_IGN);
// plus space for '\0'
htmlin = malloc(htmlinlen+1);
reset = 1;
quit = 0;
for(;;) {
if(quit) {
if(ctx != NULL)
SSL_CTX_free(ctx);
break;
}
if(reset) {
if(ctx != NULL) {
#ifdef DEBUG42
fprintf(stdout,"SSL_CTX_free()\n");
#endif
SSL_CTX_free(ctx);
}
ctx = server_https_init();
s = server_basic_socket();
dbs_open_semaphores();
reset = 0;
} // if(reset)
fprintf(stdout,"\n");
fflush(stdout);
addr_size = sizeof(sa_cli);
#ifdef DEBUG42
fprintf(stdout,"accept()\n");
#endif
if((news = accept(s, (struct sockaddr *)&sa_cli, &addr_size)) == -1) {
fprintf(stderr,"\n%s: cannot accept()\n", procname);
perror("accept");
}
dbs_time_vars();
if(beepaccept) {
fprintf(stderr,"\a");
fflush(stderr);
}
pid_t pid;
#ifdef DEBUG59
fprintf(stdout,"Fork start (parent)");
fprintf(stdout," getpid:%d getppid:%d", getpid(), getppid());
fprintf(stdout,"\n");
fflush(stdout);
#endif
#ifdef DEBUG42
fprintf(stdout,"fork()\n");
#endif
if((pid = fork()) < 0) {
dbs_close_semaphores();
fprintf(stderr,"\n%s: cannot fork()", procname);
fprintf(stderr,", errno %d", errno);
fprintf(stderr, "(%s)", strerror(errno));
fprintf(stderr,"\n");
perror("fork");
exit(1);
} else if(pid == 0) {
#ifdef DEBUG42
fprintf(stdout,"close(s)\n");
fflush(stdout);
#endif
close(s);
#ifdef DEBUG42
fprintf(stdout,"log_clear()\n");
fflush(stdout);
#endif
log_clear();
#ifdef DEBUG42
fprintf(stdout,"log_printf()\n");
fflush(stdout);
#endif
fprintf(stdout,"log");
fflush(stdout);
log_printf("==========\n");
fprintf(stdout," done");
fflush(stdout);
#ifdef DEBUG59
fprintf(stdout,"Fork start (child)");
fprintf(stdout," pid:%d getpid:%d getppid:%d", pid, getpid(), getppid());
fprintf(stdout,"\n");
fflush(stdout);
#endif
#ifdef DEBUG42
fprintf(stdout,"https_client()\n");
fflush(stdout);
#endif
https_client(news, ctx, sa_cli, addr_size, "https");
#ifdef DEBUG81
fprintf(stdout,"%s",logbuf);
fflush(stdout);
#ifdef DEBUG42
fprintf(stdout,"log_clear()\n");
fflush(stdout);
#endif
log_clear();
#endif
dbs_run_critical_sections();
#endif
#ifdef DEBUG42
fprintf(stdout,"server_close(news)\n");
fflush(stdout);
#endif
server_close(news);
fprintf(stdout,"%s", logbuf);
fflush(stdout);
#ifdef DEBUG42
fprintf(stdout,"log_clear()\n");
fflush(stdout);
#endif
log_clear();
#ifdef DEBUG59
fprintf(stdout,"Fork end (child)");
fprintf(stdout," pid:%d getpid:%d getppid:%d", pid, getpid(), getppid());
fprintf(stdout,"\n");
fflush(stdout);
#endif
exit(0);
} // if(pid == 0)
#ifdef DEBUG42
fprintf(stdout,"server_close(news)\n");
fflush(stdout);
#endif
server_close(news);
#ifdef DEBUG59
fprintf(stdout,"Fork end (parent)");
fprintf(stdout," pid:%d getpid:%d getppid:%d", pid, getpid(), getppid());
fprintf(stdout,"\n");
fflush(stdout);
#endif
} // for(;;)
SSL_CTX_free(ctx);
dbs_close_semaphores();
}
static unsigned char *dbs_save_string(unsigned char *string)
{
unsigned char *temp = malloc(strlen(string) + 1);
strcpy(temp, string);
return(temp);
}
static void dbs_file_digest(char *filename, unsigned char *hash)
{
int c;
unsigned char buffer[1024];
FILE *fp1;
HashCtx ctx;
HashInit(&ctx);
if((fp1 = fopen(filename, "rb")) != NULL) {
while((c = fread(buffer, 1, sizeof(buffer), fp1)) > 0)
HashUpdate(&ctx, buffer, c);
fclose(fp1);
}
HashFinal(hash, &ctx);
}
int dba_main(int argc,char *argv[]);
static void dbs_version()
{
fprintf(stdout,"%s, ", programname);
fprintf(stdout,"%s\n", copyright);
fflush(stdout);
}
int https=1;
int dbs_main(int argc,char *argv[])
{
int c;
for(c = 1; c < argc; c++) {
if(!strncmp(argv[c], "--https", 7))
https = 1;
else if(!strncmp(argv[c], "--http", 6))
https = 0;
else if(!strncmp(argv[c], "--port", 6)) {
if(argv[c][6] != '\0')
myport = dbs_save_string(&argv[c][6]);
else
myport = dbs_save_string(argv[++c]);
} else if(!strncmp(argv[c], "-p", 2)) {
if(argv[c][2] != '\0')
myport = dbs_save_string(&argv[c][2]);
else
myport = dbs_save_string(argv[++c]);
} else if(!strncmp(argv[c], "--version", 9)) {
dbs_version();
} else if(!strncmp(argv[c], "-v", 2)) {
dbs_version();
}
}
return(0);
}
int main(int argc,char *argv[])
{
unsigned char filedigest[HashLen];
procname = argv[0];
dbs_file_digest("/proc/self/exe", filedigest);
htmldigest[0] = '\0';
for(int c = 0; c < HashLen; c++) {
char twodigits[3];
sprintf(twodigits,"%02x", filedigest[c]);
strcat(htmldigest, twodigits);
}
filenamehead[0] = '\0';
dbs_main(argc,argv);
dba_main(argc,argv);
//db2_main(argc,argv);
fprintf(stdout,"%s", programname);
fflush(stdout);
if(https)
fprintf(stdout,", https");
else
fprintf(stdout,", http");
fprintf(stdout,", port %s", myport);
fprintf(stdout,", sha256(%s)\n", htmldigest);
fflush(stdout);
FILE *fp1;
unsigned char filename[64];
snprintf(filename, sizeof(filename), "%spid.deb", filenamehead);
if((fp1 = fopen(filename,"w")) != NULL) {
fprintf(fp1,"%d\n", getpid());
fclose(fp1);
}
#define aDEBUG_FORT
#ifdef DEBUG_FORT
unsigned char buffer64[64];
fprintf(stdout,"dbs: for(;;)\n");
fflush(stdout);
for(;;) {
fort_random_data(sizeof(buffer64),buffer64);
}
#endif
if(https)
https_server();
else
http_server();
exit(0);
}
newressu.h
void ressu_genbytes(int size, unsigned char *buffer);
unsigned long ressu_gen_limit(unsigned long limit);
#define INPUT_RESSU 0
#define INPUT_DEBUG 1
#define INPUT_FAST 2
#define INPUT_SINGLE 3
#define INPUT_FORT 6
#define INPUT_FORTXOR 7
#define INPUT_URANDOM 8
#define INPUT_RANDOM 9
extern int input;
extern int newressu_output;
extern char *randomgen[];
fort.h
/* Perustuu Bruce Schneierin kirjassa esittämään fortuna järjestelmään.
* Written by Jari Kuivaniemi
*/
#ifndef SHA256_H
#include "sha256.h"
#endif
#define aFORT_USE_RDRAND 2
#define aFORT_USE_RDSEED 2
typedef unsigned long long IUTIME;
extern int fort_verbose;
extern int fort_partial_line;
extern int fort_use_web;
extern unsigned char fort_random_file[128];
extern unsigned char fort_pools_file[128];
#ifdef DEBUG10
static char fort_events_file[128] = "fortevents.deb";
#endif
unsigned char cvar[16];
int cvarsize;
void inccvar();
void clearcvar();
void hash_update_cvar(HashCtx *hash);
void fort_add_random_event(int *pool, int source, int mode, int len, unsigned char *buf);
void fort_add_random_event_timer_start(IUTIME *micros);
void fort_add_random_event_timer_do(int *pool, int source, int mode, IUTIME *millis);
void fort_add_random_event_split(int *pool, int source, int mode, int len, unsigned char *buf,int size);
void fort_add_random_event_time(int *pool, int source, int mode);
void fort_rekey(unsigned char *buf);
void fort_pseudo_random_data(int len,unsigned char *buf);
void fort_pseudo_random_data_xor(int len,unsigned char *buf);
void fort_reseed(int len,unsigned char *buf);
void fort_random_data(int len,unsigned char *buf);
void fort_random_data_xor(int len,unsigned char *buf);
int fort_random_data_byte();
void fort_clear();
int fort_random_data_byte_limit(int limit);
void fort_random_data_buffer(int size, unsigned char *buffer);
void fort_save();
void fort_read_file();
void fort_mix();
void fort_init();
void hash_init(HashCtx *hash);
void hash_update(HashCtx *hash, unsigned char *data, int len);
void hash_final(unsigned char digest[HashLen], HashCtx *hash);
void fort_hash_http_page(unsigned char *host,unsigned char *port, unsigned char *page, unsigned char *hash);
void fort_hash_https_page(unsigned char *host,unsigned char *port, unsigned char *page, unsigned char *hash);
void fort_hash_command(unsigned char *command, unsigned char *hash);
int rdrand_bytes(int buflen, unsigned char *buf);
int rdseed_bytes(int buflen, unsigned char *buf);
#ifdef FORT_INTERNAL_EVENTS
#define FORT_INTERNAL_EVENTS_START(source) \
IUTIME micros; \
static int \
pool=0, pool2=0; \
if(fort_internal_events) { \
fort_add_random_event_time(&pool, \
source, fort_internal_event_mode); \
fort_add_random_event_timer_start(µs); \
}
#else
#define FORT_INTERNAL_EVENTS_START(source)
#endif
#ifdef FORT_INTERNAL_EVENTS
#define FORT_INTERNAL_EVENTS_END(source) \
if(fort_internal_events) \
fort_add_random_event_timer_do(&pool2, \
source, fort_internal_event_mode, \
µs);
#else
#define FORT_INTERNAL_EVENTS_END(source)
#endif
#ifdef FORT_EVENTS
#define FORT_EVENTS_START(source) \
IUTIME micros; \
static int \
pool=0, pool2=0; \
if(fort_events) { \
fort_add_random_event_time(&pool, \
source, fort_event_mode); \
fort_add_random_event_timer_start(µs); \
}
#else
#define FORT_EVENTS_START(source)
#endif
#ifdef FORT_EVENTS
#define FORT_EVENTS_END(source) \
if(fort_events) \
fort_add_random_event_timer_do(&pool2, \
source, fort_event_mode, \
µs);
#else
#define FORT_EVENTS_END(source)
#endif
sha256.h
#ifndef SHA256_H
#define SHA256_H
#define HashName "SHA256"
#define HashInit SHA256Init
#define HashUpdate SHA256Update
#define HashFinal SHA256Final
#define HashLen 32
#define HashCtx SHA256_CONTEXT
typedef unsigned char IUBYTE;
typedef unsigned int IUWORD;
typedef unsigned long long IULONG;
typedef struct {
IUWORD state[8];
IULONG count;
IUBYTE buffer[64];
} SHA256_CONTEXT;
void SHA256Init(SHA256_CONTEXT *sha256);
void SHA256Update(SHA256_CONTEXT* sha256, unsigned char *data, int len);
void SHA256Final(unsigned char digest[32], SHA256_CONTEXT *sha256);
void sha_test();
#endif
dbs.h
#define aRESSU 2
#define aFORT 2
#define HTML_LAST_BUFFER 4
int dbs_get_parameter(char *name, int valuelen, unsigned char *value);
void dbs_get_cookie(unsigned char *name, int valuelen, unsigned char *value);
int dbs_html_get_string(unsigned char *string,unsigned char **str,int len);
int dbs_parse_html_parameter(int namelen, unsigned char *name, int valuelen,unsigned char *value, unsigned char **s);
void log_clear();
void log_free();
void log_printf(const char *format, ...);
/*
int dbs_parse_hex1(unsigned char **str);
int dbs_parse_html_string(int stringlen, unsigned char *string, unsigned char **html);
unsigned long dbs_getseconds();
unsigned char *dbs_html_get_request_line(unsigned char *name);
void dbs_html_get_request_line_num(unsigned char *name, int lenbuffer, unsigned char *buffer);
void dbs_html_parse_string(int buflen, char *buf, unsigned char **p2);
void dbs_html_parse_filename(int buflen, char *buf, unsigned char *p);
unsigned char *dbs_html_get_params();
void dbs_version();
*/
html.h
unsigned char *html[9];
void html_set(int html);
int html_get();
unsigned char *html_get_string(int bufno);
void html_clear();
void html_clear_all();
void html_printf(const char *format, ...);
void html_buf_printf(int bufno, const char *format, ...);
void html_start();
void html_indent(unsigned char *p);
#define dbs_html_set html_set
#define dbs_html_get html_get
#define dbs_html_clear html_clear
#define dbs_html_printf_valist html_printf_valist
#define dbs_html_printf html_printf
#define dbs_html_buf_printf html_buf_printf
#define HTML_BUFFERS 9