=== modified file 'Makefile' --- Makefile 2007-10-20 21:38:25 +0000 +++ Makefile 2007-10-28 17:59:38 +0000 @@ -1,4 +1,4 @@ -CXXFLAGS=-Wall -g +CXXFLAGS=-Wall -W -g LDFLAGS=-lgnutls all: client server === modified file 'client.cpp' --- client.cpp 2007-10-20 21:38:25 +0000 +++ client.cpp 2007-10-28 17:59:38 +0000 @@ -44,7 +44,7 @@ int main (){ int sd, ret; - char buffer[512]; + char buffer[4096]; struct sockaddr_in6 to; struct sockaddr_in6 from; gnutls_session_t session; @@ -98,9 +98,6 @@ } } - write(1,buffer,ret); - write(1,"\n",1); - //shutdown procedure close(sd); @@ -131,10 +128,11 @@ gnutls_perror (ret); return 1; } - printf ("- Handshake was completed\n"); - - //message to be seent - gnutls_record_send (session, "The secret message is \"squeamish ossifrage\"\n", 44); + + //retrive password + ret = gnutls_record_recv (session, buffer, sizeof(buffer)); + + write(1,buffer,ret); //shutdown procedure gnutls_bye (session, GNUTLS_SHUT_RDWR); === added file 'clients.conf' --- clients.conf 1970-01-01 00:00:00 +0000 +++ clients.conf 2007-10-28 17:59:38 +0000 @@ -0,0 +1,3 @@ +C=SE,ST=BL,L=Ronneby,O=gnustuff,CN=braxen_client,EMAIL=belorn@fukt.bsnet.se +The secret message is "squeamish ossifrage" +asdjiadsjadsads === modified file 'server.cpp' --- server.cpp 2007-10-20 21:38:25 +0000 +++ server.cpp 2007-10-28 17:59:38 +0000 @@ -17,6 +17,11 @@ #include #include // std::max #include // exit() +#include // std::ifstream +#include // std::string +#include // std::map +#include // cout +#include // << #define SOCKET_ERR(err,s) if(err<0) {perror(s);exit(1);} @@ -27,8 +32,14 @@ #define CRLFILE "crl.pem" #define DH_BITS 1024 +using std::string; +using std::ifstream; +using std::map; +using std::cout; + /* These are global */ gnutls_certificate_credentials_t x509_cred; +map table; static gnutls_dh_params_t dh_params; @@ -98,14 +109,19 @@ } -void tcpreply(int sd, struct sockaddr_in6 sa_cli, gnutls_session_t session){ +void tcpreply(int sd, struct sockaddr_in6 *sa_cli, gnutls_session_t session){ + int ret; unsigned int status; char buffer[512]; - - printf ("- connection from %s, port %d\n", - inet_ntop (AF_INET6, &sa_cli.sin6_addr, buffer, - sizeof (buffer)), ntohs (sa_cli.sin6_port)); + int exit_status = 0; + char dn[128]; + +#define DIE(s){ exit_status = s; goto tcpreply_die; } + + printf ("- TCP connection from %s, port %d\n", + inet_ntop (AF_INET6, &(sa_cli->sin6_addr), buffer, + sizeof (buffer)), ntohs (sa_cli->sin6_port)); gnutls_transport_set_ptr (session, reinterpret_cast (sd)); @@ -118,47 +134,29 @@ gnutls_deinit (session); fprintf (stderr, "*** Handshake has failed (%s)\n\n", gnutls_strerror (ret)); - exit(1); + DIE(1); } printf ("- Handshake was completed\n"); //time to validate - ret = gnutls_certificate_verify_peers2 (session, &status); - - if (ret < 0) - { - printf ("Verify failed\n"); - exit(1); - } - - if (status & GNUTLS_CERT_INVALID) - printf ("The certificate is not trusted.\n"); - - if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) - printf ("The certificate hasn't got a known issuer.\n"); - - if (status & GNUTLS_CERT_REVOKED) - printf ("The certificate has been revoked.\n"); - if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509){ printf("Recived certificate not X.509\n"); - exit(1); + DIE(1); } { const gnutls_datum_t *cert_list; unsigned int cert_list_size = 0; gnutls_x509_crt_t cert; size_t size; - char dn[128]; cert_list = gnutls_certificate_get_peers (session, &cert_list_size); printf ("Peer provided %d certificates.\n", cert_list_size); if (cert_list_size == 0){ - printf("No certificates recived\n"); //should never happen because verify_peers2 should fail if so - exit(1); + printf("No certificates recived\n"); + DIE(1); } gnutls_x509_crt_init (&cert); @@ -171,24 +169,86 @@ printf ("DN: %s\n", dn); } + + ret = gnutls_certificate_verify_peers2 (session, &status); + + if (ret < 0){ + printf ("Verify failed\n"); + DIE(1); + } - ret = gnutls_record_recv (session, buffer, sizeof(buffer)); + if (status & (GNUTLS_CERT_INVALID | GNUTLS_CERT_SIGNER_NOT_FOUND | GNUTLS_CERT_REVOKED)) { + if (status & GNUTLS_CERT_INVALID) { + printf ("The certificate is not trusted.\n"); + } + + if (status & GNUTLS_CERT_SIGNER_NOT_FOUND){ + printf ("The certificate hasn't got a known issuer.\n"); + } + + if (status & GNUTLS_CERT_REVOKED){ + printf ("The certificate has been revoked.\n"); + } + DIE(1); + } - if (ret > 0) - { - write(1, buffer, ret); - } + if (table.find(dn) != table.end()){ + gnutls_record_send (session, table[dn].c_str(), table[dn].size()); + printf("Password sent to client\n"); + } else { - fprintf (stderr, "\n*** Received corrupted " - "data(%d). Closing the connection.\n\n", ret); + printf("dn not in list of allowed clients\n"); } + + tcpreply_die: gnutls_bye (session, GNUTLS_SHUT_WR); close(sd); gnutls_deinit (session); gnutls_certificate_free_credentials (x509_cred); gnutls_global_deinit (); -} + exit(exit_status); +} + + +void badconfigparser(string file){ + + string dn; + string pw; + string pwfile; + ifstream infile (file.c_str()); + + while(infile){ + getline(infile, dn, '\n'); + if(not infile){ + break; + } + getline(infile, pw, '\n'); + if(not infile){ + break; + } + getline(infile, pwfile, '\n'); + if(not infile){ + break; + } + if(pw.empty()){ + ifstream pwf(pwfile.c_str()); + std::string tmp; + + while(true){ + getline(pwf,tmp); + if (not pwf){ + break; + } + pw = pw + tmp + '\n'; + } + + } + table[dn]=pw; + } + infile.close(); +} + int main (){ @@ -203,9 +263,11 @@ fd_set rfds_orig; + badconfigparser(string("clients.conf")); + session = initialize_tls_session (); - //UDP socket creation + //UDP IPv6 socket creation udp_listen_sd = socket (PF_INET6, SOCK_DGRAM, 0); SOCKET_ERR (udp_listen_sd, "socket"); @@ -214,7 +276,7 @@ sa_serv.sin6_addr = in6addr_any; //XXX only listen to link local? sa_serv.sin6_port = htons (PORT); /* Server Port number */ - ret = setsockopt (udp_listen_sd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof (int)); + ret = setsockopt (udp_listen_sd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof (optval)); SOCKET_ERR(ret,"setsockopt reuseaddr"); ret = setsockopt(udp_listen_sd, SOL_SOCKET, SO_BINDTODEVICE, "eth0", 5); @@ -233,7 +295,7 @@ //UDP socket creation done - //TCP socket creation + //TCP IPv6 socket creation tcp_listen_sd = socket(PF_INET6, SOCK_STREAM, 0); SOCKET_ERR(tcp_listen_sd,"socket"); @@ -241,7 +303,7 @@ setsockopt(tcp_listen_sd, SOL_SOCKET, SO_BINDTODEVICE, "eth0", 5); SOCKET_ERR(ret,"setsockopt bindtodevice"); - ret = setsockopt (tcp_listen_sd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof (int)); + ret = setsockopt (tcp_listen_sd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof (optval)); SOCKET_ERR(ret,"setsockopt reuseaddr"); err = bind (tcp_listen_sd, reinterpret_cast (& sa_serv), @@ -251,7 +313,7 @@ err = listen (tcp_listen_sd, 1024); SOCKET_ERR (err, "listen"); - //TCP sockets creation done + //TCP IPv6 sockets creation done FD_ZERO(&rfds_orig); FD_SET(udp_listen_sd, &rfds_orig); @@ -270,16 +332,14 @@ } if (FD_ISSET(tcp_listen_sd, &rfds)){ - client_len = sizeof(sa_cli); - int sd = accept (tcp_listen_sd, reinterpret_cast (& sa_cli), &client_len); SOCKET_ERR(sd,"accept"); //xxx not dieing when just connection abort switch(fork()){ case 0: - tcpreply(sd, sa_cli, session); + tcpreply(sd, &sa_cli, session); return 0; break; case -1: @@ -293,7 +353,7 @@ } } } - + close(tcp_listen_sd); close(udp_listen_sd); return 0;