/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: 2008-01-18 21:23:46 UTC
  • mfrom: (2.1.1 Project)
  • Revision ID: teddy@fukt.bsnet.se-20080118212346-qo103d6o8r7xs4za
Merged from Björn.

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
                                // connect
4
4
#include <sys/socket.h>         // getaddrinfo, gai_strerror, socket, inet_pton
5
5
                                // connect
6
 
#include <unistd.h>             // close
 
6
#include <unistd.h>             // close, STDIN_FILENO, STDOUT_FILENO
7
7
#include <netdb.h>              // getaddrinfo, gai_strerror
8
8
#include <arpa/inet.h>          // inet_pton
9
9
#include <sys/select.h>         // select
10
10
#include <gnutls/gnutls.h>
 
11
#include <sys/ioctl.h>          // ioctl, ifreq, SIOCGIFFLAGS, IFF_UP, SIOCSIFFLAGS
 
12
#include <net/if.h>             // ioctl, ifreq, SIOCGIFFLAGS, IFF_UP, SIOCSIFFLAGS
 
13
#include <termios.h>            // struct termios, tcsetattr, tcgetattr, TCSAFLUSH, ECHO
11
14
}
12
15
 
13
 
#include <cstdio>               // fprintf
14
16
#include <cerrno>               // perror
15
17
#include <cstring>              // memset
 
18
#include <string>               // std::string, std::getline
 
19
#include <iostream>             // cin, cout, cerr
 
20
#include <ostream>              // <<
16
21
 
17
 
#define SOCKET_ERR(err,s) if(err<0) {perror(s);return(1);}
 
22
#define SOCKET_ERR(err,s) if(err<0) {perror(s); status = 1; goto quit;}
18
23
#define PORT 49001
19
 
#define CERTFILE "client-cert.pem"
20
 
#define KEYFILE "client-key.pem"
21
 
#define CAFILE "ca.pem"
 
24
#define CERTFILE "/conf/conf.d/cryptkeyreq/client-cert.pem"
 
25
#define KEYFILE "/conf/conf.d/cryptkeyreq/client-key.pem"
 
26
#define CAFILE "/conf/conf.d/cryptkeyreq/ca.pem"
22
27
 
23
28
gnutls_certificate_credentials_t x509_cred;
24
29
 
26
31
initgnutls(){
27
32
  gnutls_session_t session;
28
33
 
 
34
#ifdef DEBUG
 
35
  std::cerr << "Initiate certificates\n";
 
36
#endif
 
37
 
29
38
  gnutls_global_init ();
30
39
 
31
40
  /* X509 stuff */
43
52
 
44
53
 
45
54
int main (){
46
 
  int sd, ret;
 
55
  int udp_sd, tcp_sd, ret;
47
56
  char buffer[4096];
48
57
  struct sockaddr_in6 to;
49
58
  struct sockaddr_in6 from;
51
60
  fd_set rfds_orig;
52
61
  struct timeval timeout;
53
62
 
 
63
  struct termios t_old, t_new;
 
64
  int status = 0;
 
65
 
54
66
  session = initgnutls ();
55
67
 
56
 
  sd = socket(PF_INET6, SOCK_DGRAM, 0);
57
 
  SOCKET_ERR(sd,"socket");
58
 
 
 
68
#ifdef DEBUG
 
69
  std::cerr << "Open ipv6 UDP\n";
 
70
#endif
 
71
 
 
72
  udp_sd = socket(PF_INET6, SOCK_DGRAM, 0);
 
73
  SOCKET_ERR(udp_sd,"socket");
 
74
  
 
75
#ifdef DEBUG
 
76
  std::cerr << "Open socket with socket nr: " << udp_sd << '\n';
 
77
#endif
 
78
  
59
79
  {
60
80
    int flag = 1;
61
 
    ret = setsockopt(sd, SOL_SOCKET, SO_BROADCAST, & flag, sizeof(flag));
 
81
    ret = setsockopt(udp_sd, SOL_SOCKET, SO_BROADCAST, & flag, sizeof(flag));
62
82
    SOCKET_ERR(ret,"setsockopt broadcast");
63
83
  }
64
84
 
65
 
  setsockopt(sd, SOL_SOCKET, SO_BINDTODEVICE, "eth0", 5);
 
85
  ret = setsockopt(udp_sd, SOL_SOCKET, SO_BINDTODEVICE, "eth0", 5);
66
86
  SOCKET_ERR(ret,"setsockopt bindtodevice");
67
87
 
68
88
  memset (&to, '\0', sizeof (to));
69
89
  to.sin6_family = AF_INET6;
70
90
  ret = inet_pton(AF_INET6, "ff02::1" , &to.sin6_addr);
71
 
  SOCKET_ERR(ret,"setsockopt bindtodevice");
 
91
  SOCKET_ERR(ret,"inet_pton");
72
92
  to.sin6_port = htons (PORT);  // Server Port number
73
93
 
 
94
  struct ifreq network;
 
95
 
 
96
  strcpy(network.ifr_name, "eth0");
 
97
 
 
98
  ret = ioctl(udp_sd, SIOCGIFFLAGS, &network);
 
99
  SOCKET_ERR(ret,"ioctl SIOCGIFFLAGS");
 
100
 
 
101
  network.ifr_flags |= IFF_UP;
 
102
 
 
103
  ret = ioctl(udp_sd, SIOCSIFFLAGS, &network);
 
104
  SOCKET_ERR(ret,"ioctl SIOCSIFFLAGS");
 
105
    
74
106
  FD_ZERO(&rfds_orig);
75
 
  FD_SET(sd, &rfds_orig);
76
 
 
77
 
  timeout.tv_sec = 10;
78
 
  timeout.tv_usec = 0;
79
 
 
80
 
 
 
107
  FD_SET(udp_sd, &rfds_orig);
 
108
  FD_SET(STDIN_FILENO, &rfds_orig);
 
109
 
 
110
 
 
111
  if (tcgetattr (STDIN_FILENO, &t_old) != 0){
 
112
    return 1;
 
113
  }
 
114
  t_new = t_old;
 
115
  t_new.c_lflag &= ~ECHO;
 
116
  if (tcsetattr (STDIN_FILENO, TCSAFLUSH, &t_new) != 0){
 
117
    return 1;
 
118
  }
 
119
  
81
120
  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
 
    }
 
121
    for(;;){
 
122
 
 
123
#ifdef DEBUG
 
124
      std::cerr << "Sending Marco on UDP\n";
 
125
#endif
 
126
      ret = sendto(udp_sd, "Marco", 5, 0, reinterpret_cast<const sockaddr*>(&to), sizeof(to));
 
127
      if (ret < 0){
 
128
        perror("sendto");
 
129
      }
 
130
      
 
131
      fd_set rfds = rfds_orig;
 
132
      timeout.tv_sec = 10;
 
133
      timeout.tv_usec = 0;
 
134
      
 
135
      std::cerr << "Password: ";
 
136
      
 
137
      ret = select(udp_sd+1, &rfds, 0, 0, & timeout);
 
138
      SOCKET_ERR(udp_sd,"select");
 
139
      
 
140
      if (ret){
 
141
        if (FD_ISSET(STDIN_FILENO, &rfds)){
 
142
          std::string buffer;
 
143
          std::getline(std::cin, buffer);
 
144
          std::cerr << '\n';
 
145
          std::cout << buffer;
 
146
          goto quit;
 
147
        }
 
148
        
 
149
        socklen_t from_len = sizeof(from);
 
150
        ret = recvfrom(udp_sd,buffer,512,0, reinterpret_cast<sockaddr *>(& from),
 
151
                       & from_len);
 
152
        SOCKET_ERR(ret,"recv");
 
153
        
 
154
        if (strncmp(buffer,"Polo", 4) == 0){
 
155
          break;
 
156
        }
 
157
      }
 
158
      std::cerr << '\r';
 
159
    }
 
160
    
 
161
    
 
162
    tcp_sd = socket(PF_INET6, SOCK_STREAM, 0);
 
163
    SOCKET_ERR(tcp_sd,"socket");
 
164
    
 
165
    setsockopt(tcp_sd, SOL_SOCKET, SO_BINDTODEVICE, "eth0", 5);
 
166
    SOCKET_ERR(ret,"setsockopt bindtodevice");
 
167
    
 
168
    memset(&to,0,sizeof(to));
 
169
    to.sin6_family = from.sin6_family;
 
170
    to.sin6_port   = from.sin6_port;
 
171
    to.sin6_addr   = from.sin6_addr;
 
172
    to.sin6_scope_id   = from.sin6_scope_id;
 
173
    
 
174
    ret = connect(tcp_sd,reinterpret_cast<struct sockaddr *>(&to),sizeof(to));
 
175
    if (ret < 0){
 
176
      perror("connect");
 
177
      continue;
 
178
    }
 
179
    
 
180
    gnutls_transport_set_ptr (session, reinterpret_cast<gnutls_transport_ptr_t> (tcp_sd));
 
181
    
 
182
    ret = gnutls_handshake (session);
 
183
    
 
184
    if (ret < 0)
 
185
      {
 
186
        std::cerr << "\n*** Handshake failed ***\n";
 
187
        gnutls_perror (ret);
 
188
        continue;
 
189
      }
 
190
    
 
191
    //retrive password
 
192
    ret = gnutls_record_recv (session, buffer, sizeof(buffer));
 
193
    
 
194
    write(STDOUT_FILENO,buffer,ret);
 
195
    
 
196
    //shutdown procedure
 
197
    gnutls_bye (session, GNUTLS_SHUT_RDWR);
 
198
    close(tcp_sd);
 
199
    gnutls_deinit (session);
 
200
    gnutls_certificate_free_credentials (x509_cred);
 
201
    gnutls_global_deinit ();
 
202
    break;
99
203
  }
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;
 
204
  close(udp_sd);
 
205
 
 
206
 quit:
 
207
  tcsetattr (STDIN_FILENO, TCSAFLUSH, &t_old);
 
208
  return status;
147
209
}