/mandos/trunk

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/trunk

« back to all changes in this revision

Viewing changes to client.cpp

  • Committer: Teddy Hogeborn
  • Date: 2015-07-20 03:03:33 UTC
  • Revision ID: teddy@recompile.se-20150720030333-203m2aeblypcsfte
Bug fix for GnuTLS 3: be compatible with old 2048-bit DSA keys.

The mandos-keygen program in Mandos version 1.6.0 and older generated
2048-bit DSA keys, and when GnuTLS uses these it has trouble
connecting using the Mandos default priority string.  This was
previously fixed in Mandos 1.6.2, but the bug reappeared when using
GnuTLS 3, so the default priority string has to change again; this
time also the Mandos client has to change its default, so now the
server and the client should use the same default priority string:

SECURE256:!CTYPE-X.509:+CTYPE-OPENPGP:!RSA:+SIGN-DSA-SHA256

* mandos (main/server_defaults): Changed default priority string.
* mandos-options.xml (/section/para[id="priority_compat"]): Removed.
  (/section/para[id="priority"]): Changed default priority string.
* mandos.conf ([DEFAULT]/priority): - '' -
* mandos.conf.xml (OPTIONS/priority): Refer to the id "priority"
                                      instead of "priority_compat".
* mandos.xml (OPTIONS/--priority): - '' -
* plugins.d/mandos-client.c (main): Changed default priority string.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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;
47
 
  char buffer[512];
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
 
  write(1,buffer,ret);
102
 
  write(1,"\n",1);
103
 
 
104
 
  //shutdown procedure
105
 
  close(sd);
106
 
 
107
 
  sleep(1);
108
 
 
109
 
  sd = socket(PF_INET6, SOCK_STREAM, 0);
110
 
  SOCKET_ERR(sd,"socket");
111
 
 
112
 
  setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, "eth0", 5);
113
 
  SOCKET_ERR(ret,"setsockopt bindtodevice");
114
 
 
115
 
  memset(&to,0,sizeof(to));
116
 
  to.sin6_family = from.sin6_family;
117
 
  to.sin6_port   = from.sin6_port;
118
 
  to.sin6_addr   = from.sin6_addr;
119
 
  to.sin6_scope_id   = from.sin6_scope_id;
120
 
 
121
 
  ret = connect(sd,reinterpret_cast<struct sockaddr *>(&to),sizeof(to));
122
 
  SOCKET_ERR(ret,"connect");
123
 
 
124
 
  gnutls_transport_set_ptr (session, reinterpret_cast<gnutls_transport_ptr_t> (sd));
125
 
 
126
 
  ret = gnutls_handshake (session);
127
 
 
128
 
  if (ret < 0)
129
 
    {
130
 
      fprintf (stderr, "*** Handshake failed\n");
131
 
      gnutls_perror (ret);
132
 
      return 1;
133
 
    }
134
 
  printf ("- Handshake was completed\n");
135
 
 
136
 
  //message to be seent
137
 
  gnutls_record_send (session, "The secret message is \"squeamish ossifrage\"\n", 44);
138
 
 
139
 
  //shutdown procedure
140
 
  gnutls_bye (session, GNUTLS_SHUT_RDWR);
141
 
  close(sd);
142
 
  gnutls_deinit (session);
143
 
  gnutls_certificate_free_credentials (x509_cred);
144
 
  gnutls_global_deinit ();
145
 
 
146
 
  close(sd);
147
 
 
148
 
  return 0;
149
 
}