diff options
Diffstat (limited to 'vchat-protocol.c')
| -rwxr-xr-x | vchat-protocol.c | 186 |
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 | |||
| 33 | FILE * dumpfile; | 27 | FILE * 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 */ |
| 41 | const char *vchat_io_version = "vchat-protocol.c $Id$"; | 36 | const char *vchat_io_version = "vchat-protocol.c $Id$"; |
| 42 | 37 | ||
| 43 | /* externally used variables */ | ||
| 44 | int serverfd = -1; | ||
| 45 | |||
| 46 | /* locally global variables */ | ||
| 47 | /* our connection BIO */ | ||
| 48 | static BIO *server_conn = NULL; | ||
| 49 | |||
| 50 | /* declaration of local helper functions */ | 38 | /* declaration of local helper functions */ |
| 51 | static void usersignon (char *); | 39 | static void usersignon (char *); |
| 52 | static void usersignoff (char *); | 40 | static void usersignoff (char *); |
| @@ -74,137 +62,6 @@ static void pmnotsent (char *message); | |||
| 74 | extern int status; | 62 | extern int status; |
| 75 | char *encoding; | 63 | char *encoding; |
| 76 | 64 | ||
| 77 | static 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 */ | ||
| 107 | int | ||
| 108 | vcconnect (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 */ | ||
| 197 | void | ||
| 198 | vcdisconnect () { | ||
| 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 */ |
| 210 | static void | 67 | static 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) | |||
| 401 | void | 258 | void |
| 402 | ownjoin (int channel) | 259 | ownjoin (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 | |||
| 912 | void | ||
| 913 | networkoutput (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 | } | ||
