summaryrefslogtreecommitdiff
path: root/vchat-protocol.c
diff options
context:
space:
mode:
authorDirk Engling <erdgeist@erdgeist.org>2022-05-16 15:53:39 +0200
committerDirk Engling <erdgeist@erdgeist.org>2022-05-16 15:53:39 +0200
commitd1ac67f6d73f24a165ccc008440bb8b208ae140f (patch)
tree0da0184ec2273ffa6f642ab06e776fcdda9f4ac3 /vchat-protocol.c
parent43b74147212ddc5e619ac17dd1b5967b6b293d8a (diff)
Decouple IO openssl's BIO abstraction and split connection and tls handling to allow for other TLS libs
Diffstat (limited to 'vchat-protocol.c')
-rwxr-xr-xvchat-protocol.c186
1 files changed, 13 insertions, 173 deletions
diff --git a/vchat-protocol.c b/vchat-protocol.c
index 0073956..b7d654e 100755
--- a/vchat-protocol.c
+++ b/vchat-protocol.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * vchat-client - alpha version 2 * vchat-client - alpha version
3 * vchat-protocol.c - handling of server connection & messages 3 * vchat-protocol.c - handling of server messages
4 * 4 *
5 * Copyright (C) 2001 Andreas Kotes <count@flatline.de> 5 * Copyright (C) 2001 Andreas Kotes <count@flatline.de>
6 * 6 *
@@ -15,38 +15,26 @@
15 */ 15 */
16 16
17/* general includes */ 17/* general includes */
18#include <unistd.h> 18#include <stdlib.h>
19#include <errno.h>
20#include <stdio.h> 19#include <stdio.h>
21#include <netdb.h>
22#include <string.h> 20#include <string.h>
23#include <sys/types.h> 21#include <errno.h>
24#include <sys/socket.h>
25#include <netinet/in.h>
26#include <readline/readline.h> 22#include <readline/readline.h>
27#include <locale.h> 23#include <locale.h>
28#include <langinfo.h> 24#include <langinfo.h>
29 25
30// TO BE GONE 26#ifdef DEBUG
31#include <openssl/bio.h>
32
33FILE * dumpfile; 27FILE * dumpfile;
28#endif
34 29
35/* local includes */ 30/* local includes */
36#include "vchat.h" 31#include "vchat.h"
37#include "vchat-user.h" 32#include "vchat-user.h"
38#include "vchat-ssl.h" 33#include "vchat-connection.h"
39 34
40/* version of this module */ 35/* version of this module */
41const char *vchat_io_version = "vchat-protocol.c $Id$"; 36const char *vchat_io_version = "vchat-protocol.c $Id$";
42 37
43/* externally used variables */
44int serverfd = -1;
45
46/* locally global variables */
47/* our connection BIO */
48static BIO *server_conn = NULL;
49
50/* declaration of local helper functions */ 38/* declaration of local helper functions */
51static void usersignon (char *); 39static void usersignon (char *);
52static void usersignoff (char *); 40static void usersignoff (char *);
@@ -74,137 +62,6 @@ static void pmnotsent (char *message);
74extern int status; 62extern int status;
75char *encoding; 63char *encoding;
76 64
77static int connect_socket( char *server, char *port ) {
78 struct addrinfo hints, *res, *res0;
79 int s, error;
80
81 memset(&hints, 0, sizeof(hints));
82 hints.ai_family = PF_UNSPEC;
83 hints.ai_socktype = SOCK_STREAM;
84 error = getaddrinfo( server, port, &hints, &res0 );
85 if (error) return -1;
86 s = -1;
87 for (res = res0; res; res = res->ai_next) {
88 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
89 if (s < 0) continue;
90 if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
91 close(s);
92 s = -1;
93 continue;
94 }
95 break; /* okay we got one */
96 }
97 freeaddrinfo(res0);
98
99 if (want_tcp_keepalive) { /* global from vchat-client.c */
100 int one=1;
101 setsockopt(s,SOL_SOCKET,SO_KEEPALIVE,&one,sizeof(one));
102 }
103 return s;
104}
105
106/* connects to server */
107int
108vcconnect (char *server, char *port)
109{
110 /* used for tilde expansion of cert & key filenames */
111 char *tildex = NULL;
112
113 /* vchat connection x509 store */
114 vc_x509store_t *vc_store;
115
116 /* pointer to tilde-expanded certificate/keyfile-names */
117 char *certfile = NULL, *keyfile = NULL;
118
119 /* Connect to the server */
120 serverfd = connect_socket( server, port );
121 if( serverfd < 0 ) {
122 /* inform user */
123 snprintf (tmpstr, TMPSTRSIZE, getformatstr(FS_CANTCONNECT), server, port );
124 writechan (tmpstr);
125 return -1;
126 }
127 /* Abstract server IO in openssls BIO */
128 server_conn = BIO_new_socket( serverfd, 1 );
129
130 /* If SSL is requested, get our ssl-BIO running */
131 if( server_conn && getintoption(CF_USESSL) ) {
132 vc_store = vc_init_x509store();
133 if( !vc_store ) {
134 snprintf (tmpstr, TMPSTRSIZE, getformatstr(FS_ERR), "Out of memory" );
135 writechan (tmpstr);
136 return -1;
137 }
138
139 vc_x509store_setflags(vc_store, VC_X509S_SSL_VERIFY_PEER);
140
141 /* get name of certificate file */
142 certfile = getstroption (CF_CERTFILE);
143 /* do we have a certificate file? */
144 if (certfile) {
145 /* does the filename start with a tilde? expand it! */
146 if (certfile[0] == '~')
147 tildex = tilde_expand (certfile);
148 else
149 tildex = certfile;
150
151 vc_x509store_setflags(vc_store, VC_X509S_USE_CERTIFICATE);
152 vc_x509store_setcertfile(vc_store, tildex);
153
154 /* get name of key file */
155 keyfile = getstroption (CF_KEYFILE);
156
157 /* if we don't have a key file, the key may be in the cert file */
158 if (!keyfile)
159 keyfile = certfile;
160
161 /* does the filename start with a tilde? expand it! */
162 if (keyfile[0] == '~')
163 tildex = tilde_expand (keyfile);
164 else
165 tildex = keyfile;
166
167 vc_x509store_set_pkeycb(vc_store, (vc_askpass_cb_t)passprompt);
168 vc_x509store_setkeyfile(vc_store, tildex);
169 }
170
171 /* upgrade our plain BIO to ssl */
172 if( vc_connect_ssl( &server_conn, vc_store ) ) {
173 BIO_free_all( server_conn );
174 server_conn = NULL;
175 errno = EIO;
176 }
177 }
178
179 if( !server_conn ) {
180 /* inform user */
181 snprintf (tmpstr, TMPSTRSIZE, getformatstr(FS_CANTCONNECT), server, port );
182 writechan (tmpstr);
183 return -1;
184 }
185
186 /* inform user */
187 snprintf (tmpstr, TMPSTRSIZE, getformatstr(FS_CONNECTED), server, port);
188 writechan (tmpstr);
189
190 dumpfile = fopen( "dumpfile", "a");
191
192 /* if we didn't fail until now, we've got a connection. */
193 return 0;
194}
195
196/* disconnect from server */
197void
198vcdisconnect () {
199 BIO_free_all( server_conn );
200 server_conn = 0;
201 if (serverfd>0) {
202 close(serverfd);
203 serverfd = -1;
204 }
205 loggedin = 0;
206}
207
208/* handle a pm not sent error 65/* handle a pm not sent error
209 * format: 412 %s */ 66 * format: 412 %s */
210static void 67static void
@@ -264,7 +121,7 @@ serverlogin (char *message)
264{ 121{
265 int utf8=!strcmp(nl_langinfo(CODESET), "UTF-8"); 122 int utf8=!strcmp(nl_langinfo(CODESET), "UTF-8");
266 if (utf8) 123 if (utf8)
267 networkoutput(".e utf8"); 124 vc_sendmessage(".e utf8");
268} 125}
269 126
270/* parse and handle an idle message 127/* parse and handle an idle message
@@ -401,9 +258,9 @@ justloggedin (char *message)
401void 258void
402ownjoin (int channel) 259ownjoin (int channel)
403{ 260{
404 networkoutput(".t"); 261 vc_sendmessage(".t");
405 snprintf(tmpstr, TMPSTRSIZE, ".S %d",channel); 262 snprintf(tmpstr, TMPSTRSIZE, ".S %d",channel);
406 networkoutput(tmpstr); 263 vc_sendmessage(tmpstr);
407} 264}
408 265
409/* this user changes his nick */ 266/* this user changes his nick */
@@ -443,7 +300,7 @@ nickerr (char *message)
443 300
444 /* form login message and send it to server */ 301 /* form login message and send it to server */
445 snprintf (tmpstr, TMPSTRSIZE, ".l %s %s %d", own_nick_get(), getstroption (CF_FROM), getintoption (CF_CHANNEL)); 302 snprintf (tmpstr, TMPSTRSIZE, ".l %s %s %d", own_nick_get(), getstroption (CF_FROM), getintoption (CF_CHANNEL));
446 networkoutput (tmpstr); 303 vc_sendmessage (tmpstr);
447 } 304 }
448} 305}
449 306
@@ -476,7 +333,7 @@ login (char *message) {
476 333
477 /* form login message and send it to server */ 334 /* form login message and send it to server */
478 snprintf (tmpstr, TMPSTRSIZE, ".l %s %s %d", own_nick_get(), getstroption (CF_FROM), getintoption (CF_CHANNEL)); 335 snprintf (tmpstr, TMPSTRSIZE, ".l %s %s %d", own_nick_get(), getstroption (CF_FROM), getintoption (CF_CHANNEL));
479 networkoutput (tmpstr); 336 vc_sendmessage (tmpstr);
480} 337}
481 338
482/* parse and handle anon login request 339/* parse and handle anon login request
@@ -496,7 +353,7 @@ anonlogin (char *message)
496 353
497 /* form login message and send it to server */ 354 /* form login message and send it to server */
498 snprintf (tmpstr, TMPSTRSIZE, ".l %s %s %d", own_nick_get(), getstroption (CF_FROM), getintoption (CF_CHANNEL)); 355 snprintf (tmpstr, TMPSTRSIZE, ".l %s %s %d", own_nick_get(), getstroption (CF_FROM), getintoption (CF_CHANNEL));
499 networkoutput (tmpstr); 356 vc_sendmessage (tmpstr);
500} 357}
501 358
502/* parse and handle list of nicks (from '.S') 359/* parse and handle list of nicks (from '.S')
@@ -849,7 +706,7 @@ networkinput (void)
849 buf[BUFSIZE-1] = '\0'; /* sanity stop */ 706 buf[BUFSIZE-1] = '\0'; /* sanity stop */
850 707
851 /* receive data at offset */ 708 /* receive data at offset */
852 bytes = BIO_read (server_conn, &buf[bufoff], BUFSIZE-1 - bufoff); 709 bytes = vc_receivemessage(&buf[bufoff], BUFSIZE-1 - bufoff);
853 710
854 /* no bytes transferred? raise error message, bail out */ 711 /* no bytes transferred? raise error message, bail out */
855 if (bytes < 0) 712 if (bytes < 0)
@@ -908,20 +765,3 @@ networkinput (void)
908 bufoff = 0; 765 bufoff = 0;
909 } 766 }
910} 767}
911
912void
913networkoutput (char *msg)
914{
915#ifdef DEBUG
916 /* debugging? log network output! */
917 fprintf (dumpfile, ">| %s (%zd)\n", msg, strlen(msg));
918#endif
919
920 /* send data to server */
921 if (BIO_write (server_conn, msg, strlen (msg)) != strlen (msg))
922 writecf (FS_ERR,"Message sending fuzzy.");
923
924 /* send line termination to server */
925 if (BIO_write (server_conn, "\r\n", 2) != 2)
926 writecf (FS_ERR,"Message sending fuzzy.");
927}