/mandos/trunk

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/trunk
1 by Björn Påhlsson
First working version with: IPv6, GnuTLS, X.509 certificates, DN
1
extern "C" {
2
#include <sys/types.h>		// getaddrinfo, gai_strerror, socket, inet_pton
3
				// connect
4
#include <sys/socket.h>		// getaddrinfo, gai_strerror, socket, inet_pton
5
				// connect
6
#include <unistd.h>		// close
7
#include <netdb.h>		// getaddrinfo, gai_strerror
8
#include <arpa/inet.h>		// inet_pton
9
#include <sys/select.h> 	// select
10
#include <gnutls/gnutls.h>
11
}
12
13
#include <cstdio>		// fprintf
14
#include <cerrno>		// perror
15
#include <cstring> 		// memset
16
17
#define SOCKET_ERR(err,s) if(err<0) {perror(s);return(1);}
18
#define PORT 49001
19
#define CERTFILE "client-cert.pem"
20
#define KEYFILE "client-key.pem"
21
#define CAFILE "ca.pem"
22
23
gnutls_certificate_credentials_t x509_cred;
24
25
gnutls_session_t
26
initgnutls(){
27
  gnutls_session_t session;
28
29
  gnutls_global_init ();
30
31
  /* X509 stuff */
32
  gnutls_certificate_allocate_credentials (&x509_cred);
33
  gnutls_certificate_set_x509_trust_file (x509_cred, CAFILE, GNUTLS_X509_FMT_PEM);
34
  gnutls_certificate_set_x509_key_file (x509_cred, CERTFILE, KEYFILE,
35
					GNUTLS_X509_FMT_PEM);
36
37
  //Gnutls stuff
38
  gnutls_init (&session, GNUTLS_CLIENT);
39
  gnutls_set_default_priority (session);
40
  gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, x509_cred);
41
  return session;
42
}
43
44
45
int main (){
46
  int sd, ret;
2 by Björn Påhlsson
Working client and server and password system
47
  char buffer[4096];
1 by Björn Påhlsson
First working version with: IPv6, GnuTLS, X.509 certificates, DN
48
  struct sockaddr_in6 to;
49
  struct sockaddr_in6 from;
50
  gnutls_session_t session;
51
  fd_set rfds_orig;
52
  struct timeval timeout;
53
54
  session = initgnutls ();
55
56
  sd = socket(PF_INET6, SOCK_DGRAM, 0);
57
  SOCKET_ERR(sd,"socket");
58
 
59
  {
60
    int flag = 1;
61
    ret = setsockopt(sd, SOL_SOCKET, SO_BROADCAST, & flag, sizeof(flag));
62
    SOCKET_ERR(ret,"setsockopt broadcast");
63
  }
64
65
  setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, "eth0", 5);
66
  SOCKET_ERR(ret,"setsockopt bindtodevice");
67
68
  memset (&to, '\0', sizeof (to));
69
  to.sin6_family = AF_INET6;
70
  ret = inet_pton(AF_INET6, "ff02::1" , &to.sin6_addr);
71
  SOCKET_ERR(ret,"setsockopt bindtodevice");
72
  to.sin6_port = htons (PORT);	// Server Port number
73
74
  FD_ZERO(&rfds_orig);
75
  FD_SET(sd, &rfds_orig);
76
77
  timeout.tv_sec = 10;
78
  timeout.tv_usec = 0;
79
80
81
  for(;;){
82
    sendto(sd, "Marco", 5, 0, reinterpret_cast<const sockaddr*>(&to), sizeof(to));
83
84
    fd_set rfds = rfds_orig;
85
86
    ret = select(sd+1, &rfds, 0, 0, & timeout);
87
    SOCKET_ERR(sd,"select");
88
89
    if (ret){
90
      socklen_t from_len = sizeof(from);
91
      ret = recvfrom(sd,buffer,512,0, reinterpret_cast<sockaddr *>(& from),
92
		     & from_len);
93
      SOCKET_ERR(ret,"recv");
94
95
      if (strncmp(buffer,"Polo", 4) == 0){
96
	break;
97
      }
98
    }
99
  }
100
101
  //shutdown procedure
102
  close(sd);
103
104
  sleep(1);
105
106
  sd = socket(PF_INET6, SOCK_STREAM, 0);
107
  SOCKET_ERR(sd,"socket");
108
109
  setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, "eth0", 5);
110
  SOCKET_ERR(ret,"setsockopt bindtodevice");
111
112
  memset(&to,0,sizeof(to));
113
  to.sin6_family = from.sin6_family;
114
  to.sin6_port   = from.sin6_port;
115
  to.sin6_addr   = from.sin6_addr;
116
  to.sin6_scope_id   = from.sin6_scope_id;
117
118
  ret = connect(sd,reinterpret_cast<struct sockaddr *>(&to),sizeof(to));
119
  SOCKET_ERR(ret,"connect");
120
121
  gnutls_transport_set_ptr (session, reinterpret_cast<gnutls_transport_ptr_t> (sd));
122
123
  ret = gnutls_handshake (session);
124
125
  if (ret < 0)
126
    {
127
      fprintf (stderr, "*** Handshake failed\n");
128
      gnutls_perror (ret);
129
      return 1;
130
    }
2 by Björn Påhlsson
Working client and server and password system
131
132
  //retrive password
133
  ret = gnutls_record_recv (session, buffer, sizeof(buffer));
134
135
  write(1,buffer,ret);
1 by Björn Påhlsson
First working version with: IPv6, GnuTLS, X.509 certificates, DN
136
137
  //shutdown procedure
138
  gnutls_bye (session, GNUTLS_SHUT_RDWR);
139
  close(sd);
140
  gnutls_deinit (session);
141
  gnutls_certificate_free_credentials (x509_cred);
142
  gnutls_global_deinit ();
143
144
  close(sd);
145
146
  return 0;
147
}