/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[4096];
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
 
    }
131
 
 
132
 
  //retrive password
133
 
  ret = gnutls_record_recv (session, buffer, sizeof(buffer));
134
 
 
135
 
  write(1,buffer,ret);
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
 
}