Send Devl mailing list submissions to
        devl at freenetproject.org

To subscribe or unsubscribe via the World Wide Web, visit
        http://www.uprizer.com/mailman/listinfo/devl
or, via email, send a message with subject or body 'help' to
        devl-request at freenetproject.org

You can reach the person managing the list at
        devl-admin at freenetproject.org

When replying, please edit your Subject line so it is more specific
than "Re: Contents of Devl digest..."


Today's Topics:

   1. Re: Espra - what's that? (Mark J. Roberts)
   2. Re: progress on 0.4 data store rewrite (Ian Clarke)
   3. Re: Espra - what's that? (Mark J. Roberts)
   4. Is 0.3.7 officially released now? (Gianni Johansson)
   5. Re: Is 0.3.7 officially released now? (Ian Clarke)
   6. Re: Espra - what's that? (Ian Clarke)
   7. Re: Espra - what's that? (Steven Hazel)

--__--__--

Message: 1
Date: Tue, 6 Feb 2001 15:20:05 -0500 (EST)
From: "Mark J. Roberts" <[email protected]>
To: <devl at freenetproject.org>
Subject: Re: [freenet-devl] Espra - what's that?
Reply-To: devl at freenetproject.org

On 5 Feb 2001, Steven Hazel wrote:

> You can insert these snippets of code at these lines in protocol.c to
> see what those values are (all line numbers are before you make any
> modifications, so mark the lines for yourself before you insert any
> newlines):
>
> line 263:
> fprintf(stderr, "Y: ");
> BN_print_fp(stderr, y);
> fprintf(stderr, "\n");
>
> line 308:
> fprintf(stderr, "X: ");
> BN_print_fp(stderr, pub_key);
> fprintf(stderr, "\n");
>
> line 320:
> fprintf(stderr, "K: ");
> BN_print_fp(stderr, k);
> fprintf(stderr, "\n");

Here's what happens. I compile and see two warnings,

protocol.c: In function `diffie_hellman':
protocol.c:265: warning: passing arg 2 of `BN_print_fp' from incompatible 
pointer type
protocol.c:329: warning: passing arg 2 of `BN_print_fp' from incompatible 
pointer type

and the two that caused those warnings, Y and K, segfault 3 out of 5
times. X seems to work if I get past Y.

-- 
Mark Roberts
mjr at statesmean.com



--__--__--

Message: 2
Date: Tue, 6 Feb 2001 13:28:35 -0800
From: Ian Clarke <[email protected]>
To: devl at freenetproject.org
Subject: Re: [freenet-devl] progress on 0.4 data store rewrite
Reply-To: devl at freenetproject.org


--1Y7d0dPL928TPQbc
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Tue, Feb 06, 2001 at 01:02:02PM -0500, Tavin Cole wrote:
> To anyone who is interested, I have committed the first stage of my
> datastore rewrite for 0.4 to experimental cvs.  The files are in
> Freenet/node/store so cvs update -d please.
> Critiques would be appreciated.. I have done some pretty weird things,
> but not without justification.  I humbly await being torn to shreds by
> the pack of wild dogs who read this list..  ;^)

I plan to take a close look, but before that, I think we should think
about a test-harness which would provide us with reasonable security as
to how well this (and future improved versions) were working.

Ian.

--1Y7d0dPL928TPQbc
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.4 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE6gGyDQtgxRWSmsqwRAiVfAJ4+8d+Buh2sZ9HnkyBjOyTTO1dcFgCbBehY
jeF3fcYLAqhqbAIC1RHiWuc=
=H8na
-----END PGP SIGNATURE-----

--1Y7d0dPL928TPQbc--


--__--__--

Message: 3
Date: Tue, 6 Feb 2001 15:59:58 -0500 (EST)
From: "Mark J. Roberts" <[email protected]>
To: <devl at freenetproject.org>
Subject: Re: [freenet-devl] Espra - what's that?
Reply-To: devl at freenetproject.org

On Tue, 6 Feb 2001, Mark J. Roberts wrote:

> Here's what happens. I compile and see two warnings,
>
> protocol.c: In function `diffie_hellman':
> protocol.c:265: warning: passing arg 2 of `BN_print_fp' from incompatible 
> pointer type
> protocol.c:329: warning: passing arg 2 of `BN_print_fp' from incompatible 
> pointer type
>
> and the two that caused those warnings, Y and K, segfault 3 out of 5
> times. X seems to work if I get past Y.

X is sent to Fred intact, BTW.


-- 
Mark Roberts
mjr at statesmean.com



--__--__--

Message: 4
From: Gianni Johansson <[email protected]>
To: <devl at freenetproject.org>
Date: Tue, 6 Feb 2001 17:46:02 -0500
Subject: [freenet-devl] Is 0.3.7 officially released now?
Reply-To: devl at freenetproject.org

I want to switch from the old javascript date based redirects to a 
non-javascript date based redirect to a MSK for my Freenet page, but not 
until 0.3.7 is ready for the masses.  

-- gj

-- 
Web page inside Freenet:
freenet:KSK at webpages/gj_jump0


--__--__--

Message: 5
Date: Tue, 6 Feb 2001 14:53:24 -0800
From: Ian Clarke <[email protected]>
To: devl at freenetproject.org
Subject: Re: [freenet-devl] Is 0.3.7 officially released now?
Reply-To: devl at freenetproject.org


--V0207lvV8h4k8FAm
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Tue, Feb 06, 2001 at 05:46:02PM -0500, Gianni Johansson wrote:
> I want to switch from the old javascript date based redirects to a=20
> non-javascript date based redirect to a MSK for my Freenet page, but not=
=20
> until 0.3.7 is ready for the masses. =20

It was released yesterday.

Regards,

Ian.

--V0207lvV8h4k8FAm
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.4 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE6gIBkQtgxRWSmsqwRAi8gAJ9x227GxaxaEG63mwP+2gQ+MWYD/ACfY7uU
tTnBDZYIHWj+ooDSkEwOuT0=
=9JnE
-----END PGP SIGNATURE-----

--V0207lvV8h4k8FAm--


--__--__--

Message: 6
Date: Tue, 6 Feb 2001 14:56:16 -0800
From: Ian Clarke <[email protected]>
To: devl at freenetproject.org
Subject: Re: [freenet-devl] Espra - what's that?
Reply-To: devl at freenetproject.org


--t0UkRYy7tHLRMCai
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Tue, Feb 06, 2001 at 04:18:04AM -0000, tav wrote:
> some people wanted it, so here's a screenshot of espra...=20
>=20
>     http://espra.net/screenshots/espra01
>=20
> comments / thoughts much appreciated. thanks

Looks great!  How does it communicate with Freenet?

Ian.

--t0UkRYy7tHLRMCai
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.4 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQE6gIEQQtgxRWSmsqwRAhYjAJ0VmPaKBnsdJEtv+YYPD0pIcdEGygCfRiKi
tQDXRFY6jFWxg7gttaEyhQA=
=bjve
-----END PGP SIGNATURE-----

--t0UkRYy7tHLRMCai--


--__--__--

Message: 7
To: devl at freenetproject.org
Subject: Re: [freenet-devl] Espra - what's that?
From: Steven Hazel <[email protected]>
Date: 06 Feb 2001 17:04:58 -0600
Reply-To: devl at freenetproject.org

--=-=-=

"Mark J. Roberts" <mjr at statesmean.com> writes:

> Here's what happens. I compile and see two warnings,
> 
> protocol.c: In function `diffie_hellman':
> protocol.c:265: warning: passing arg 2 of `BN_print_fp' from incompatible 
> pointer type
> protocol.c:329: warning: passing arg 2 of `BN_print_fp' from incompatible 
> pointer type
> 
> and the two that caused those warnings, Y and K, segfault 3 out of 5
> times. X seems to work if I get past Y.

Oops.  Here, I've fixed the debugging code.


--=-=-=
Content-Disposition: attachment; filename=protocol.c
Content-Description: protocol.c

#include <stdio.h>
#include <malloc.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <stddef.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>

#include <openssl/sha.h>
#include <openssl/dh.h>
#include <openssl/rand.h>

#include "protocol.h"
#include "util.h"

int readall(int sock, unsigned char *buffer, int len);

int writeall(int sock, unsigned char *buffer, int len);

int open_connection (freenet_connection *connection, char *hostaddress,
                     char *service);

int get_connection(freenet_connection *connection, u_short port);

int diffie_hellman (freenet_connection *connection, unsigned char *k,
                    int len);

int start_ciphers (freenet_connection *connection, unsigned char *key);

int request_handshake (freenet_connection *connection);

int reply_handshake (freenet_connection *connection, freenet_message *request);

int writeline(freenet_connection *connection, const char *string);

int readto(freenet_connection *connection, char *buffer, int buflen, int term);

int internal_recvmsg (freenet_connection *connection,
                      freenet_message *message);

int freenet_senddata(freenet_connection *connection, const char *buffer,
                     int len);
int freenet_sendmsg (freenet_connection *connection, freenet_message *message);

int freenet_readdata(freenet_connection *connection, char *buffer, int len);

int freenet_recvmsg (freenet_connection *connection, freenet_message *message);

int freenet_connect (freenet_connection *connection, char *hostaddress,
                     char *service);

int freenet_get_connection (freenet_connection *connection, u_short port);

int freenet_init (void);

/* FIXME -- these functions aren't useful when they return an error
   (even EOF!), becuase it's impossible to tell what portion of the
   data was read or written.  Fix that (by returning the amount read
   in a parameter).  Right now, they can be used properly by only
   calling them with len > 1 if EOF is considered a real error (that
   is, if you are expecting an EOF at any time, read one byte at a
   time) */

int readall(int sock, unsigned char *buffer, int len)
{
  int br;
  int rlen = 0;

  while (rlen < len) {
    br = read(sock, &(buffer[rlen]), len-rlen);
    if ((br == 0) && (rlen == 0)) {
      return FNS_EOF;
    } else if (br < 1) {
      return FNS_READ_FAILED;
    }
    rlen += br;
  }

  return FNS_SUCCESS;
}


int writeall(int sock, unsigned char *buffer, int len)
{
  int bw;
  int wlen = 0;

  while (wlen < len) {
    bw = write(sock, &(buffer[wlen]), len-wlen);
    if (bw < 1) {
      return FNS_WRITE_FAILED;
    }
    wlen += bw;
  }

  return FNS_SUCCESS;
}


/* just open a tcp connection */
int open_connection (freenet_connection *connection, char *hostaddress,
                     char *service)
{
  struct in_addr addr;
  int connected_socket, connected;
  struct sockaddr_in address;
  struct servent *serv;
  long lport;
  char *errpos;
  struct hostent *host;
  int port = -1;

  serv = getservbyname(service, "tcp");
  if (serv != NULL)
    port = serv->s_port;
  else { /* Not in services, maybe a number? */
    lport = strtol(service,&errpos,0);
    if ( (errpos[0] != 0) || (lport < 1) || (lport > 65535) ) {
      return FNS_INVALID_PORT;
    }
    port = htons(lport);
  }

  addr.s_addr = inet_addr(hostaddress);
  if (addr.s_addr == -1) {
    host = gethostbyname(hostaddress);
    if (host == NULL) {
      return FNS_INVALID_ADDY;
    }
    addr.s_addr = ((struct in_addr *) *host->h_addr_list)->s_addr;
  }

  memset((char *) &address, 0, sizeof(address));
  address.sin_family = AF_INET;
  address.sin_port = (port);
  address.sin_addr.s_addr = addr.s_addr;

  connected_socket = socket(AF_INET, SOCK_STREAM, 0);

  connected = connect(connected_socket, (struct sockaddr *) &address,
    sizeof(address));
  if (connected < 0) {
    return FNS_CONNECT_FAILED;
  }

  connection->socket = connected_socket;

  return FNS_SUCCESS;
}


/* wait for a tcp connection */
int get_connection(freenet_connection *connection, u_short port)
{
  struct sockaddr_in address;
  int listening_socket;
  int connected_socket = -1;
  int reuse_addr = 1;
  struct sockaddr_in incoming;
  int b;

  /* Setup internet address information.
     This is used with the bind() call */
  memset((char *) &address, 0, sizeof(address));
  address.sin_family = AF_INET;
  address.sin_port = htons(port);
  address.sin_addr.s_addr = htonl(INADDR_ANY);

  listening_socket = socket(AF_INET, SOCK_STREAM, 0);
  if (listening_socket < 0) {
    return FNS_SOCKET_FAILED;
  }

  setsockopt(listening_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse_addr,
    sizeof(reuse_addr));

  if (bind(listening_socket, (struct sockaddr *)&address,
    sizeof(address)) < 0) {
    close(listening_socket);
    return FNS_BIND_FAILED;
  }

  if (listen(listening_socket, 1) < 0) {
    return FNS_LISTEN_FAILED;
  }

  while(connected_socket < 0) {
    b = sizeof(incoming);
    connected_socket = accept(listening_socket, &incoming, &b);
    if (connected_socket < 0) {
      /* Either a real error occured, or blocking was interrupted for
         some reason.  Only abort execution if a real error occured. */
      if (errno != EINTR) {
        close(listening_socket);
        return FNS_ACCEPT_FAILED;
      } else {
        continue;    /* don't quit - do the accept again */
      }
    }

    close(listening_socket); /* Close this socket */

  }

  connection->socket = connected_socket;

  return FNS_SUCCESS;
}


int diffie_hellman (freenet_connection *connection, unsigned char *k, int len)
{
  int16_t mpilen;
  unsigned char *y;
  unsigned char *ybuf;
  unsigned char *xbuf;
  DH *dhsys;
  BIGNUM *pub_key;
  BIGNUM *kbn;
  int ylen, klen;
  int status;
  int retval;

  dhsys = DH_new();
  if (dhsys == NULL) {
    return FNS_MALLOC_FAILED;
  }

  /* g and n are fixed for all of freenet */
  status = BN_hex2bn(&(dhsys->g), FN_DH_G);
  if (status != strlen(FN_DH_G)) {
    retval = FNS_BN_FAILED;
    goto end;
  }

  status = BN_hex2bn(&(dhsys->p), FN_DH_N);
  if (status != strlen(FN_DH_N)) {
    retval = FNS_BN_FAILED;
    goto end;
  }

  /* generate a random y */
  status = DH_generate_key(dhsys);
  if (status != 1) {
    retval = FNS_DH_FAILED;
    goto end;
  }

  fprintf(stderr, "Y: ");
  BN_print_fp(stderr, dhsys->pub_key);
  fprintf(stderr, "\n");

  ylen = BN_num_bytes(dhsys->pub_key);

  y = malloc(ylen);
  if (y == NULL) {
    retval = FNS_MALLOC_FAILED;
    goto end;
  }

  status = BN_bn2bin(dhsys->pub_key, y);
  if (status != ylen) {
    retval = FNS_BN_FAILED;
    goto end;
  }

  ybuf = malloc(ylen + 2);
  if (ybuf == NULL) {
    retval = FNS_MALLOC_FAILED;
    goto end;
  }

  status = raw_to_bagbiting_freenet_mpi(y, ylen, ybuf);
  if (status != FNS_SUCCESS) {
    retval = status;
    goto end;
  }
  status = writeall(connection->socket, ybuf, ylen + 2);
  if (status != FNS_SUCCESS) {
    retval = status;
    goto end;
  }


  status = readall(connection->socket, (char *)&mpilen, (size_t)2);
  if (status != FNS_SUCCESS) {
    retval = status;
    goto end;
  }

  mpilen = htons(mpilen);
  mpilen = (mpilen+7)/8;  /* convert to bytes */

  xbuf = malloc(mpilen);
  if (xbuf == NULL) {
    retval = FNS_MALLOC_FAILED;
    goto end;
  }

  status = readall(connection->socket, xbuf, (size_t)mpilen);
  if (status != FNS_SUCCESS) {
    retval = status;
    goto end;
  }

  pub_key = BN_bin2bn(xbuf, mpilen, NULL);
  if (pub_key == NULL) {
    retval = FNS_BN_FAILED;
    goto end;
  }

  fprintf(stderr, "X: ");
  BN_print_fp(stderr, pub_key);
  fprintf(stderr, "\n");

  if (len != DH_size(dhsys)) {
    retval = FNS_DH_FAILED;
    goto end;
  }

  klen = DH_compute_key(k, pub_key, dhsys);
  if (klen == -1) {
    retval = FNS_DH_FAILED;
    goto end;
  }

  if (len != klen) {
    retval = FNS_DH_FAILED;
    goto end;
  }

  kbn = BN_bin2bn(k, klen, NULL);
  if (kbn != NULL) {
    fprintf(stderr, "K: ");
    BN_print_fp(stderr, kbn);
    fprintf(stderr, "\n");
    BN_free(kbn);
  } else {
    fprintf(stderr, "couldn't convert K to a BIGNUM\n");
  }

  retval = FNS_SUCCESS;


 end:

  DH_free(dhsys);
  BN_free(pub_key);
  free(y);
  free(ybuf);
  free(xbuf);
  return retval;
}


/* initialize the incoming and outgoing rijndael ciphers */
int start_ciphers (freenet_connection *connection, unsigned char *key)
{
  unsigned char oiv[FN_KEY_BYTES];
  unsigned char iiv[FN_KEY_BYTES];
  int status;

  status = generate_random(oiv, FN_KEY_BYTES);
  if (status != FNS_SUCCESS) {
    return status;
  }

  status = writeall(connection->socket, oiv, FN_KEY_BYTES);
  if (status != FNS_SUCCESS) {
    return status;
  }

  status = readall(connection->socket, iiv, FN_KEY_BYTES);
  if (status != FNS_SUCCESS) {
    return status;
  }

  status = rijndael_makeKey(&(connection->sendsys.key), DIR_ENCRYPT, 
FN_KEY_BITS,
                            key);
  if (status != TRUE) {
    return FNS_MAKEKEY_FAILED;
  }
  status = rijndael_makeKey(&(connection->recvsys.key), DIR_ENCRYPT, 
FN_KEY_BITS,
                            key);
  if (status != TRUE) {
    return FNS_MAKEKEY_FAILED;
  }

  status = rijndael_cipherInit(&(connection->sendsys.cipher), MODE_ECB, NULL);
  if (status != TRUE) {
    return FNS_CIPHERINIT_FAILED;
  }
  status = rijndael_cipherInit(&(connection->recvsys.cipher), MODE_ECB, NULL);
  if (status != TRUE) {
    return FNS_CIPHERINIT_FAILED;
  }

  status = rijndael_blockEncrypt(&(connection->sendsys.cipher), 
&(connection->sendsys.key),
                                 oiv, FN_KEY_BITS, connection->sendsys.fb);
  if (status < 1) {
    return FNS_ENCRYPT_FAILED;
  }
  status = rijndael_blockEncrypt(&(connection->recvsys.cipher), 
&(connection->recvsys.key),
                                 iiv, FN_KEY_BITS, connection->recvsys.fb);
  if (status < 1) {
    return FNS_ENCRYPT_FAILED;
  }

  connection->sendsys.fbpos = 0;
  connection->recvsys.fbpos = 0;

  return FNS_SUCCESS;
}


/* initiate a handshake (and complete it) */
int request_handshake (freenet_connection *connection)
{
  freenet_message message;
  float version;
  freenet_message reply;
  int i, status;


  status = generate_random((unsigned char *)&(message.uniqueid),
                           sizeof(uint64_t));
  if (status != FNS_SUCCESS) {
    return status;
  }

  strcpy(message.type, "HandshakeRequest");
  strcpy(message.field[0], "Depth=1");
  strcpy(message.field[1], "HopsToLive=1");
  strcpy(message.field[2], "KeepAlive=true");
  strcpy(message.field[3], "EndMessage");
  message.numfields = 4;

  status = freenet_sendmsg(connection, &message);
  if (status != FNS_SUCCESS) {
    return status;
  }

  status = internal_recvmsg(connection, &reply);
  if (status != FNS_SUCCESS) {
    return status;
  }

  if (strcmp(reply.type, "HandshakeReply") != 0) {
    return FNS_INVALID_REPLY;
  }

  if (reply.uniqueid != message.uniqueid) {
    return FNS_WRONG_ID;
  }

  for (i = 0; i < reply.numfields; i++) {
    if (strncmp(reply.field[i], "Version=", 8) == 0) {
      sscanf(reply.field[i], "Version=%f", &version);
      if (version<FN_VERSION) {
        return FNS_INVALID_VERSION;
      }
    }
  }

  return FNS_SUCCESS;
}


/* handle a handshake */
int reply_handshake (freenet_connection *connection, freenet_message *request)
{
  freenet_message reply;
  float version;
  int i, status;

  if (strcmp(request->type, "HandshakeRequest") != 0) {
    return FNS_INVALID_REQUEST;
  }

  for (i = 0; i < request->numfields; i++) {
    if (strncmp(request->field[i], "Version=", 8) == 0) {
      sscanf(request->field[i], "Version=%f", &version);
      if (version > FN_VERSION) {
        return FNS_INVALID_VERSION;
      }
    }
  }

  strcpy(reply.type, "HandshakeReply");
  reply.uniqueid = request->uniqueid;
  sprintf(reply.field[0], "Version=%.3f", FN_VERSION);
  sprintf(reply.field[1], "Depth=1");
  sprintf(reply.field[2], "HopsToLive=1");
  sprintf(reply.field[3], "Revision=%.3f", FN_REVISION);
  sprintf(reply.field[4], "Build=%d", FN_BUILD);
  sprintf(reply.field[5], "EndMessage");
  reply.numfields = 6;

  status = freenet_sendmsg(connection, &reply);
  if (status != FNS_SUCCESS) {
    return status;
  }

  return FNS_SUCCESS;
}


int freenet_senddata(freenet_connection *connection, const char *buffer,
                     int len)
{
  unsigned char *outbuffer;
  unsigned char newsfb[FN_KEY_BYTES];
  int i, status, retval;

  outbuffer = malloc(len);
  if (outbuffer == NULL) {
    retval = FNS_MALLOC_FAILED;
    goto end;
  }


  for (i = 0; i < len; i++) {
    if (connection->sendsys.fbpos >= FN_KEY_BYTES) {
      status = rijndael_blockEncrypt(&(connection->sendsys.cipher),
                                     &(connection->sendsys.key), 
connection->sendsys.fb,
                                     FN_KEY_BITS, newsfb);
      if (status < 1) {
        retval = FNS_ENCRYPT_FAILED;
        goto end;
      }
      memcpy(connection->sendsys.fb, newsfb, FN_KEY_BYTES);
      connection->sendsys.fbpos = 0;
    }

    /* combine the cypher and the plaintext to get the cyphertext */
    outbuffer[i] = buffer[i] ^ 
connection->sendsys.fb[connection->sendsys.fbpos];
    /* put the cyphertext into the feedback buffer */
    connection->sendsys.fb[connection->sendsys.fbpos] = outbuffer[i];

    connection->sendsys.fbpos++;
  }

  status = writeall(connection->socket, outbuffer, len);
  if (status != FNS_SUCCESS) {
    retval = status;
    goto end;
  }

  retval = FNS_SUCCESS;

 end:

  free(outbuffer);
  return retval;
}


int writeline(freenet_connection *connection, const char *string)
{
  int status, len;

  len = strlen(string);

  status = freenet_senddata(connection, string, len);
  if (status != FNS_SUCCESS) {
    return status;
  }

  status = freenet_senddata(connection, "\n", 1);
  if (status != FNS_SUCCESS) {
    return status;
  }

  return FNS_SUCCESS;
}



int freenet_sendmsg (freenet_connection *connection, freenet_message *message)
{
  int i, status;
  unsigned char line[512];

  status = writeline(connection, message->type);
  if (status != FNS_SUCCESS) {
    return status;
  }

  sprintf(line, "UniqueID=%Lx", message->uniqueid);

  status = writeline(connection, line);
  if (status != FNS_SUCCESS) {
    return status;
  }

  /* DEBUG */
  fprintf(stderr, "sending = \n");
  fprintf(stderr, "%s\n", message->type);
  fprintf(stderr, "%s\n", line);
  for (i = 0; i < message->numfields; i++) {
    fprintf(stderr, "%s\n", message->field[i]);
  }

  for (i = 0; i < message->numfields; i++) {
    status = writeline(connection, message->field[i]);
    if (status != FNS_SUCCESS) {
      return status;
    }
  }

  return FNS_SUCCESS;
}


int freenet_readdata(freenet_connection *connection, char *buffer, int len)
{
  unsigned char *inbuffer;
  unsigned char newrfb[FN_KEY_BYTES];
  int i, status, retval;

  inbuffer = malloc(len);
  if (inbuffer == NULL) {
    retval = FNS_MALLOC_FAILED;
    goto end;
  }

  status = readall(connection->socket, inbuffer, len);
  if (status != FNS_SUCCESS) {
    retval = status;
    goto end;
  }

  for (i = 0; i < len; i++) {

    if (connection->recvsys.fbpos >= FN_KEY_BYTES) {
      status = rijndael_blockEncrypt(&(connection->recvsys.cipher),
                                     &(connection->recvsys.key), 
connection->recvsys.fb,
                                     FN_KEY_BITS, newrfb);
      if (status < 1) {
        retval = FNS_ENCRYPT_FAILED;
        goto end;
      }
      memcpy(connection->recvsys.fb, newrfb, FN_KEY_BYTES);
      connection->recvsys.fbpos = 0;
    }

    /* combine the cyphertext and the cypher to get the plaintext */
    buffer[i] = inbuffer[i] ^ connection->recvsys.fb[connection->recvsys.fbpos];
    /* put the cyphertext into the feedback buffer */
    connection->recvsys.fb[connection->recvsys.fbpos] = inbuffer[i];

    connection->recvsys.fbpos++;

  }

  retval = FNS_SUCCESS;


 end:

  free(inbuffer);
  return retval;
}


int readto(freenet_connection *connection, char *buffer, int buflen, int term)
{
  int i, status;
  char in;

  i = 0;
  do {

    status = freenet_readdata(connection, &in, 1);
    if (status != FNS_SUCCESS) {
      return status;
    }

    buffer[i] = in;
    i++;

  } while ((buffer[i-1] != term) && (i < buflen));

  i--; /* back up to the token terminator */

  buffer[i] = 0;  /* replace the token terminator with a string terminator */

  return FNS_SUCCESS;
}


int internal_recvmsg (freenet_connection *connection, freenet_message *message)
{
  int i, status;
  unsigned char line[512];

  message->numfields = 0;
  status = readto(connection, message->type, 81, '\n');
  if (status == FNS_EOF) {
    return FNS_CONNECTION_GONE;
  } else if (status != FNS_SUCCESS) {
    return FNS_SUCCESS;
  }

  do {

    status = readto(connection, line, 510, '\n');
    if (status != FNS_SUCCESS) {
      return FNS_SUCCESS;
    }

    if (strncmp(line, "UniqueID=", 9) == 0) {
      sscanf(&(line[9]), "%Lx", &(message->uniqueid));
    } else {
      strncpy(message->field[message->numfields], line, 510);
      message->numfields++;
    }

  } while (strchr(message->field[message->numfields-1], '=') != NULL);

  /* DEBUG */
  fprintf(stderr, "received = \n");
  fprintf(stderr, "%s\n", message->type);
  fprintf(stderr, "UniqueID=%Lx\n", message->uniqueid);
  for (i = 0; i < message->numfields; i++) {
    fprintf(stderr, "%s\n", message->field[i]);
  }

  return FNS_SUCCESS;
}


int freenet_recvmsg (freenet_connection *connection, freenet_message *message)
{
  int status;

  status = internal_recvmsg(connection, message);
  if ((status == FNS_CONNECTION_GONE) && (connection->expect_callback)) {
    close(connection->socket);
    status = freenet_get_connection(connection, 6666);
    if (status != FNS_SUCCESS) {
      return status;
    }
    status = internal_recvmsg(connection, message);
    if (status != FNS_SUCCESS) {
      return status;
    }
  } else if (status != FNS_SUCCESS) {
    return status;
  }

  if (strcmp(message->type, "HandshakeRequest")==0) {
    status = reply_handshake(connection, message);
    if (status != FNS_SUCCESS) {
      return status;
    }

    status = internal_recvmsg(connection, message);
    if (status != FNS_SUCCESS) {
      return status;
    }
  }

  return FNS_SUCCESS;
}


int freenet_connect (freenet_connection *connection, char *hostaddress,
                     char *service)
{
  unsigned char k[FN_DHK_LEN];
  unsigned char bfmpik[130];
  unsigned char key[FN_KEY_BYTES];
  int status;

  connection->expect_callback = FN_TRUE;

  status = open_connection(connection, hostaddress, service);
  if (status != FNS_SUCCESS) {
    return status;
  }

  status = diffie_hellman(connection, k, FN_DHK_LEN);
  if (status != FNS_SUCCESS) {
    return status;
  }

  status = raw_to_bagbiting_freenet_mpi(k, FN_DHK_LEN, bfmpik);
  if (status != FNS_SUCCESS) {
    return status;
  }

  status = keygen(bfmpik, FN_DHK_MPI_LEN, key, FN_KEY_BYTES);
  if (status != FNS_SUCCESS) {
    return status;
  }

  status = start_ciphers(connection, key);
  if (status != FNS_SUCCESS) {
    return status;
  }

  status = request_handshake(connection);
  if (status != FNS_SUCCESS) {
    return status;
  }

  return FNS_SUCCESS;
}


int freenet_get_connection (freenet_connection *connection, u_short port)
{
  unsigned char k[FN_DHK_LEN];
  unsigned char bfmpik[130];
  unsigned char key[FN_KEY_BYTES];
  int status;

  connection->expect_callback = FN_TRUE;

  status = get_connection(connection, port);
  if (status != FNS_SUCCESS) {
    return status;
  }

  status = diffie_hellman(connection, k, FN_DHK_LEN);
  if (status != FNS_SUCCESS) {
    return status;
  }

  status = raw_to_bagbiting_freenet_mpi(k, FN_DHK_LEN, bfmpik);
  if (status != FNS_SUCCESS) {
    return status;
  }

  status = keygen(bfmpik, FN_DHK_MPI_LEN, key, FN_KEY_BYTES);
  if (status != FNS_SUCCESS) {
    return status;
  }

  status = start_ciphers(connection, key);
  if (status != FNS_SUCCESS) {
    return status;
  }

  return FNS_SUCCESS;
}


int freenet_init (void) {

#ifndef FN_RANDOM_FILE
  if (oc_start() != 0) {
    return FNS_RANDOM_ERROR;
  }
#endif

  return FNS_SUCCESS;
}

--=-=-=


-S




--=-=-=--



--__--__--

_______________________________________________
Devl mailing list
Devl at freenetproject.org
http://www.uprizer.com/mailman/listinfo/devl


End of Devl Digest

Reply via email to