socket.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736
  1. /*
  2. * mbsync - mailbox synchronizer
  3. * Copyright (C) 2000-2002 Michael R. Elkins <me@mutt.org>
  4. * Copyright (C) 2002-2006,2008,2010,2011 Oswald Buddenhagen <ossi@users.sf.net>
  5. * Copyright (C) 2004 Theodore Y. Ts'o <tytso@mit.edu>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. *
  20. * As a special exception, mbsync may be linked with the OpenSSL library,
  21. * despite that library's more restrictive license.
  22. */
  23. /* This must come before isync.h to avoid our #define S messing up
  24. * blowfish.h on MacOS X. */
  25. #include <config.h>
  26. #ifdef HAVE_LIBSSL
  27. # include <openssl/ssl.h>
  28. # include <openssl/err.h>
  29. # include <openssl/hmac.h>
  30. #endif
  31. #include "isync.h"
  32. #include <assert.h>
  33. #include <unistd.h>
  34. #include <stdlib.h>
  35. #include <stddef.h>
  36. #include <errno.h>
  37. #include <string.h>
  38. #include <fcntl.h>
  39. #include <sys/socket.h>
  40. #include <sys/ioctl.h>
  41. #include <netinet/in.h>
  42. #include <netinet/tcp.h>
  43. #include <arpa/inet.h>
  44. #include <netdb.h>
  45. enum {
  46. SCK_CONNECTING,
  47. #ifdef HAVE_LIBSSL
  48. SCK_STARTTLS,
  49. #endif
  50. SCK_READY
  51. };
  52. static void
  53. socket_fail( conn_t *conn )
  54. {
  55. conn->bad_callback( conn->callback_aux );
  56. }
  57. #ifdef HAVE_LIBSSL
  58. static int
  59. ssl_return( const char *func, conn_t *conn, int ret )
  60. {
  61. int err;
  62. switch ((err = SSL_get_error( conn->ssl, ret ))) {
  63. case SSL_ERROR_NONE:
  64. return ret;
  65. case SSL_ERROR_WANT_WRITE:
  66. conf_fd( conn->fd, POLLIN, POLLOUT );
  67. /* fallthrough */
  68. case SSL_ERROR_WANT_READ:
  69. return 0;
  70. case SSL_ERROR_SYSCALL:
  71. case SSL_ERROR_SSL:
  72. if (!(err = ERR_get_error())) {
  73. if (ret == 0)
  74. error( "Socket error: secure %s %s: unexpected EOF\n", func, conn->name );
  75. else
  76. sys_error( "Socket error: secure %s %s", func, conn->name );
  77. } else {
  78. error( "Socket error: secure %s %s: %s\n", func, conn->name, ERR_error_string( err, 0 ) );
  79. }
  80. break;
  81. default:
  82. error( "Socket error: secure %s %s: unhandled SSL error %d\n", func, conn->name, err );
  83. break;
  84. }
  85. if (conn->state == SCK_STARTTLS)
  86. conn->callbacks.starttls( 0, conn->callback_aux );
  87. else
  88. socket_fail( conn );
  89. return -1;
  90. }
  91. /* Some of this code is inspired by / lifted from mutt. */
  92. static int
  93. compare_certificates( X509 *cert, X509 *peercert,
  94. unsigned char *peermd, unsigned peermdlen )
  95. {
  96. unsigned char md[EVP_MAX_MD_SIZE];
  97. unsigned mdlen;
  98. /* Avoid CPU-intensive digest calculation if the certificates are
  99. * not even remotely equal. */
  100. if (X509_subject_name_cmp( cert, peercert ) ||
  101. X509_issuer_name_cmp( cert, peercert ))
  102. return -1;
  103. if (!X509_digest( cert, EVP_sha1(), md, &mdlen ) ||
  104. peermdlen != mdlen || memcmp( peermd, md, mdlen ))
  105. return -1;
  106. return 0;
  107. }
  108. #if OPENSSL_VERSION_NUMBER >= 0x00904000L
  109. #define READ_X509_KEY(fp, key) PEM_read_X509( fp, key, 0, 0 )
  110. #else
  111. #define READ_X509_KEY(fp, key) PEM_read_X509( fp, key, 0 )
  112. #endif
  113. /* this gets called when a certificate is to be verified */
  114. static int
  115. verify_cert( const server_conf_t *conf, conn_t *sock )
  116. {
  117. server_conf_t *mconf = (server_conf_t *)conf;
  118. SSL *ssl = sock->ssl;
  119. X509 *cert, *lcert;
  120. BIO *bio;
  121. FILE *fp;
  122. int err;
  123. unsigned n, i;
  124. X509_STORE_CTX xsc;
  125. char buf[256];
  126. unsigned char md[EVP_MAX_MD_SIZE];
  127. cert = SSL_get_peer_certificate( ssl );
  128. if (!cert) {
  129. error( "Error, no server certificate\n" );
  130. return -1;
  131. }
  132. while (conf->cert_file) { /* while() instead of if() so break works */
  133. if (X509_cmp_current_time( X509_get_notBefore( cert )) >= 0) {
  134. error( "Server certificate is not yet valid\n" );
  135. break;
  136. }
  137. if (X509_cmp_current_time( X509_get_notAfter( cert )) <= 0) {
  138. error( "Server certificate has expired\n" );
  139. break;
  140. }
  141. if (!X509_digest( cert, EVP_sha1(), md, &n )) {
  142. error( "*** Unable to calculate digest\n" );
  143. break;
  144. }
  145. if (!(fp = fopen( conf->cert_file, "rt" ))) {
  146. sys_error( "Unable to load CertificateFile '%s'", conf->cert_file );
  147. return -1;
  148. }
  149. err = -1;
  150. for (lcert = 0; READ_X509_KEY( fp, &lcert ); )
  151. if (!(err = compare_certificates( lcert, cert, md, n )))
  152. break;
  153. X509_free( lcert );
  154. fclose( fp );
  155. if (!err)
  156. return 0;
  157. break;
  158. }
  159. if (!mconf->cert_store) {
  160. if (!(mconf->cert_store = X509_STORE_new())) {
  161. error( "Error creating certificate store\n" );
  162. return -1;
  163. }
  164. if (!X509_STORE_set_default_paths( mconf->cert_store ))
  165. warn( "Error while loading default certificate files: %s\n",
  166. ERR_error_string( ERR_get_error(), 0 ) );
  167. if (!conf->cert_file) {
  168. info( "Note: CertificateFile not defined\n" );
  169. } else if (!X509_STORE_load_locations( mconf->cert_store, conf->cert_file, 0 )) {
  170. error( "Error while loading certificate file '%s': %s\n",
  171. conf->cert_file, ERR_error_string( ERR_get_error(), 0 ) );
  172. return -1;
  173. }
  174. }
  175. X509_STORE_CTX_init( &xsc, mconf->cert_store, cert, 0 );
  176. err = X509_verify_cert( &xsc ) > 0 ? 0 : X509_STORE_CTX_get_error( &xsc );
  177. X509_STORE_CTX_cleanup( &xsc );
  178. if (!err)
  179. return 0;
  180. error( "Error, cannot verify certificate: %s (%d)\n",
  181. X509_verify_cert_error_string( err ), err );
  182. X509_NAME_oneline( X509_get_subject_name( cert ), buf, sizeof(buf) );
  183. info( "\nSubject: %s\n", buf );
  184. X509_NAME_oneline( X509_get_issuer_name( cert ), buf, sizeof(buf) );
  185. info( "Issuer: %s\n", buf );
  186. bio = BIO_new( BIO_s_mem() );
  187. ASN1_TIME_print( bio, X509_get_notBefore( cert ) );
  188. memset( buf, 0, sizeof(buf) );
  189. BIO_read( bio, buf, sizeof(buf) - 1 );
  190. info( "Valid from: %s\n", buf );
  191. ASN1_TIME_print( bio, X509_get_notAfter( cert ) );
  192. memset( buf, 0, sizeof(buf) );
  193. BIO_read( bio, buf, sizeof(buf) - 1 );
  194. BIO_free( bio );
  195. info( " to: %s\n", buf );
  196. if (!X509_digest( cert, EVP_md5(), md, &n )) {
  197. error( "*** Unable to calculate fingerprint\n" );
  198. } else {
  199. info( "Fingerprint: " );
  200. for (i = 0; i < n; i += 2)
  201. info( "%02X%02X ", md[i], md[i + 1] );
  202. info( "\n" );
  203. }
  204. fputs( "\nAccept certificate? [y/N]: ", stderr );
  205. if (fgets( buf, sizeof(buf), stdin ) && (buf[0] == 'y' || buf[0] == 'Y'))
  206. return 0;
  207. return -1;
  208. }
  209. static int
  210. init_ssl_ctx( const server_conf_t *conf )
  211. {
  212. server_conf_t *mconf = (server_conf_t *)conf;
  213. const SSL_METHOD *method;
  214. int options = 0;
  215. if (conf->use_tlsv1 && !conf->use_sslv2 && !conf->use_sslv3)
  216. method = TLSv1_client_method();
  217. else
  218. method = SSLv23_client_method();
  219. mconf->SSLContext = SSL_CTX_new( method );
  220. if (!conf->use_sslv2)
  221. options |= SSL_OP_NO_SSLv2;
  222. if (!conf->use_sslv3)
  223. options |= SSL_OP_NO_SSLv3;
  224. if (!conf->use_tlsv1)
  225. options |= SSL_OP_NO_TLSv1;
  226. SSL_CTX_set_options( mconf->SSLContext, options );
  227. /* we check the result of the verification after SSL_connect() */
  228. SSL_CTX_set_verify( mconf->SSLContext, SSL_VERIFY_NONE, 0 );
  229. return 0;
  230. }
  231. static void start_tls_p2( conn_t * );
  232. static void start_tls_p3( conn_t *, int );
  233. void
  234. socket_start_tls( conn_t *conn, void (*cb)( int ok, void *aux ) )
  235. {
  236. static int ssl_inited;
  237. conn->callbacks.starttls = cb;
  238. if (!ssl_inited) {
  239. SSL_library_init();
  240. SSL_load_error_strings();
  241. ssl_inited = 1;
  242. }
  243. if (!conn->conf->SSLContext && init_ssl_ctx( conn->conf )) {
  244. start_tls_p3( conn, 0 );
  245. return;
  246. }
  247. conn->ssl = SSL_new( ((server_conf_t *)conn->conf)->SSLContext );
  248. SSL_set_fd( conn->ssl, conn->fd );
  249. SSL_set_mode( conn->ssl, SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER );
  250. start_tls_p2( conn );
  251. }
  252. static void
  253. start_tls_p2( conn_t *conn )
  254. {
  255. switch (ssl_return( "connect to", conn, SSL_connect( conn->ssl ) )) {
  256. case -1:
  257. start_tls_p3( conn, 0 );
  258. break;
  259. case 0:
  260. break;
  261. default:
  262. /* verify the server certificate */
  263. if (verify_cert( conn->conf, conn )) {
  264. start_tls_p3( conn, 0 );
  265. } else {
  266. info( "Connection is now encrypted\n" );
  267. start_tls_p3( conn, 1 );
  268. }
  269. break;
  270. }
  271. }
  272. static void start_tls_p3( conn_t *conn, int ok )
  273. {
  274. conn->state = SCK_READY;
  275. conn->callbacks.starttls( ok, conn->callback_aux );
  276. }
  277. #endif /* HAVE_LIBSSL */
  278. static void socket_fd_cb( int, void * );
  279. static void socket_connected2( conn_t * );
  280. static void socket_connect_bail( conn_t * );
  281. static void
  282. socket_close_internal( conn_t *sock )
  283. {
  284. del_fd( sock->fd );
  285. close( sock->fd );
  286. sock->fd = -1;
  287. }
  288. void
  289. socket_connect( conn_t *sock, void (*cb)( int ok, void *aux ) )
  290. {
  291. const server_conf_t *conf = sock->conf;
  292. struct hostent *he;
  293. struct sockaddr_in addr;
  294. int s, a[2];
  295. sock->callbacks.connect = cb;
  296. /* open connection to IMAP server */
  297. if (conf->tunnel) {
  298. nfasprintf( &sock->name, "tunnel '%s'", conf->tunnel );
  299. infon( "Starting %s... ", sock->name );
  300. if (socketpair( PF_UNIX, SOCK_STREAM, 0, a )) {
  301. perror( "socketpair" );
  302. exit( 1 );
  303. }
  304. if (fork() == 0) {
  305. if (dup2( a[0], 0 ) == -1 || dup2( a[0], 1 ) == -1)
  306. _exit( 127 );
  307. close( a[0] );
  308. close( a[1] );
  309. execl( "/bin/sh", "sh", "-c", conf->tunnel, (char *)0 );
  310. _exit( 127 );
  311. }
  312. close( a[0] );
  313. sock->fd = a[1];
  314. fcntl( a[1], F_SETFL, O_NONBLOCK );
  315. add_fd( a[1], socket_fd_cb, sock );
  316. } else {
  317. memset( &addr, 0, sizeof(addr) );
  318. addr.sin_port = conf->port ? htons( conf->port ) :
  319. #ifdef HAVE_LIBSSL
  320. conf->use_imaps ? htons( 993 ) :
  321. #endif
  322. htons( 143 );
  323. addr.sin_family = AF_INET;
  324. infon( "Resolving %s... ", conf->host );
  325. he = gethostbyname( conf->host );
  326. if (!he) {
  327. error( "IMAP error: Cannot resolve server '%s'\n", conf->host );
  328. goto bail;
  329. }
  330. info( "\vok\n" );
  331. addr.sin_addr.s_addr = *((int *)he->h_addr_list[0]);
  332. s = socket( PF_INET, SOCK_STREAM, 0 );
  333. if (s < 0) {
  334. perror( "socket" );
  335. exit( 1 );
  336. }
  337. sock->fd = s;
  338. fcntl( s, F_SETFL, O_NONBLOCK );
  339. add_fd( s, socket_fd_cb, sock );
  340. nfasprintf( &sock->name, "%s (%s:%hu)",
  341. conf->host, inet_ntoa( addr.sin_addr ), ntohs( addr.sin_port ) );
  342. infon( "Connecting to %s... ", sock->name );
  343. if (connect( s, (struct sockaddr *)&addr, sizeof(addr) )) {
  344. if (errno != EINPROGRESS) {
  345. sys_error( "Cannot connect to %s", sock->name );
  346. socket_close_internal( sock );
  347. goto bail;
  348. }
  349. conf_fd( s, 0, POLLOUT );
  350. sock->state = SCK_CONNECTING;
  351. info( "\v\n" );
  352. return;
  353. }
  354. }
  355. info( "\vok\n" );
  356. socket_connected2( sock );
  357. return;
  358. bail:
  359. socket_connect_bail( sock );
  360. }
  361. static void
  362. socket_connected( conn_t *conn )
  363. {
  364. int soerr;
  365. socklen_t selen = sizeof(soerr);
  366. if (getsockopt( conn->fd, SOL_SOCKET, SO_ERROR, &soerr, &selen )) {
  367. perror( "getsockopt" );
  368. exit( 1 );
  369. }
  370. if (soerr) {
  371. errno = soerr;
  372. sys_error( "Cannot connect to %s", conn->name );
  373. socket_close_internal( conn );
  374. socket_connect_bail( conn );
  375. return;
  376. }
  377. socket_connected2( conn );
  378. }
  379. static void
  380. socket_connected2( conn_t *conn )
  381. {
  382. conf_fd( conn->fd, 0, POLLIN );
  383. conn->state = SCK_READY;
  384. conn->callbacks.connect( 1, conn->callback_aux );
  385. }
  386. static void
  387. socket_connect_bail( conn_t *conn )
  388. {
  389. free( conn->name );
  390. conn->name = 0;
  391. conn->callbacks.connect( 0, conn->callback_aux );
  392. }
  393. static void dispose_chunk( conn_t *conn );
  394. void
  395. socket_close( conn_t *sock )
  396. {
  397. if (sock->fd >= 0)
  398. socket_close_internal( sock );
  399. free( sock->name );
  400. sock->name = 0;
  401. #ifdef HAVE_LIBSSL
  402. if (sock->ssl) {
  403. SSL_free( sock->ssl );
  404. sock->ssl = 0;
  405. }
  406. #endif
  407. while (sock->write_buf)
  408. dispose_chunk( sock );
  409. }
  410. static void
  411. socket_fill( conn_t *sock )
  412. {
  413. char *buf;
  414. int n = sock->offset + sock->bytes;
  415. int len = sizeof(sock->buf) - n;
  416. if (!len) {
  417. error( "Socket error: receive buffer full. Probably protocol error.\n" );
  418. socket_fail( sock );
  419. return;
  420. }
  421. assert( sock->fd >= 0 );
  422. buf = sock->buf + n;
  423. #ifdef HAVE_LIBSSL
  424. if (sock->ssl) {
  425. if ((n = ssl_return( "read from", sock, SSL_read( sock->ssl, buf, len ) )) <= 0)
  426. return;
  427. if (n == len && SSL_pending( sock->ssl ))
  428. fake_fd( sock->fd, POLLIN );
  429. } else
  430. #endif
  431. {
  432. if ((n = read( sock->fd, buf, len )) < 0) {
  433. sys_error( "Socket error: read from %s", sock->name );
  434. socket_fail( sock );
  435. return;
  436. } else if (!n) {
  437. error( "Socket error: read from %s: unexpected EOF\n", sock->name );
  438. socket_fail( sock );
  439. return;
  440. }
  441. }
  442. sock->bytes += n;
  443. sock->read_callback( sock->callback_aux );
  444. }
  445. int
  446. socket_read( conn_t *conn, char *buf, int len )
  447. {
  448. int n = conn->bytes;
  449. if (n > len)
  450. n = len;
  451. memcpy( buf, conn->buf + conn->offset, n );
  452. if (!(conn->bytes -= n))
  453. conn->offset = 0;
  454. else
  455. conn->offset += n;
  456. return n;
  457. }
  458. char *
  459. socket_read_line( conn_t *b )
  460. {
  461. char *p, *s;
  462. int n;
  463. s = b->buf + b->offset;
  464. p = memchr( s + b->scanoff, '\n', b->bytes - b->scanoff );
  465. if (!p) {
  466. b->scanoff = b->bytes;
  467. if (b->offset + b->bytes == sizeof(b->buf)) {
  468. memmove( b->buf, b->buf + b->offset, b->bytes );
  469. b->offset = 0;
  470. }
  471. return 0;
  472. }
  473. n = p + 1 - s;
  474. b->offset += n;
  475. b->bytes -= n;
  476. b->scanoff = 0;
  477. if (p != s && p[-1] == '\r')
  478. p--;
  479. *p = 0;
  480. if (DFlags & VERBOSE)
  481. puts( s );
  482. return s;
  483. }
  484. static int
  485. do_write( conn_t *sock, char *buf, int len )
  486. {
  487. int n;
  488. assert( sock->fd >= 0 );
  489. #ifdef HAVE_LIBSSL
  490. if (sock->ssl)
  491. return ssl_return( "write to", sock, SSL_write( sock->ssl, buf, len ) );
  492. #endif
  493. n = write( sock->fd, buf, len );
  494. if (n < 0) {
  495. if (errno != EAGAIN && errno != EWOULDBLOCK) {
  496. sys_error( "Socket error: write to %s", sock->name );
  497. socket_fail( sock );
  498. } else {
  499. n = 0;
  500. conf_fd( sock->fd, POLLIN, POLLOUT );
  501. }
  502. } else if (n != len) {
  503. conf_fd( sock->fd, POLLIN, POLLOUT );
  504. }
  505. return n;
  506. }
  507. static void
  508. dispose_chunk( conn_t *conn )
  509. {
  510. buff_chunk_t *bc = conn->write_buf;
  511. if (!(conn->write_buf = bc->next))
  512. conn->write_buf_append = &conn->write_buf;
  513. if (bc->data != bc->buf)
  514. free( bc->data );
  515. free( bc );
  516. }
  517. static int
  518. do_queued_write( conn_t *conn )
  519. {
  520. buff_chunk_t *bc;
  521. if (!conn->write_buf)
  522. return 0;
  523. while ((bc = conn->write_buf)) {
  524. int n, len = bc->len - conn->write_offset;
  525. if ((n = do_write( conn, bc->data + conn->write_offset, len )) < 0)
  526. return -1;
  527. if (n != len) {
  528. conn->write_offset += n;
  529. return 0;
  530. }
  531. conn->write_offset = 0;
  532. dispose_chunk( conn );
  533. }
  534. #ifdef HAVE_LIBSSL
  535. if (conn->ssl && SSL_pending( conn->ssl ))
  536. fake_fd( conn->fd, POLLIN );
  537. #endif
  538. return conn->write_callback( conn->callback_aux );
  539. }
  540. static void
  541. do_append( conn_t *conn, char *buf, int len, ownership_t takeOwn )
  542. {
  543. buff_chunk_t *bc;
  544. if (takeOwn == GiveOwn) {
  545. bc = nfmalloc( offsetof(buff_chunk_t, buf) );
  546. bc->data = buf;
  547. } else {
  548. bc = nfmalloc( offsetof(buff_chunk_t, buf) + len );
  549. bc->data = bc->buf;
  550. memcpy( bc->data, buf, len );
  551. }
  552. bc->len = len;
  553. bc->next = 0;
  554. *conn->write_buf_append = bc;
  555. conn->write_buf_append = &bc->next;
  556. }
  557. int
  558. socket_write( conn_t *conn, char *buf, int len, ownership_t takeOwn )
  559. {
  560. if (conn->write_buf) {
  561. do_append( conn, buf, len, takeOwn );
  562. return len;
  563. } else {
  564. int n = do_write( conn, buf, len );
  565. if (n != len && n >= 0) {
  566. conn->write_offset = n;
  567. do_append( conn, buf, len, takeOwn );
  568. } else if (takeOwn) {
  569. free( buf );
  570. }
  571. return n;
  572. }
  573. }
  574. static void
  575. socket_fd_cb( int events, void *aux )
  576. {
  577. conn_t *conn = (conn_t *)aux;
  578. if (events & POLLERR) {
  579. error( "Unidentified socket error from %s.\n", conn->name );
  580. socket_fail( conn );
  581. return;
  582. }
  583. if (conn->state == SCK_CONNECTING) {
  584. socket_connected( conn );
  585. return;
  586. }
  587. if (events & POLLOUT)
  588. conf_fd( conn->fd, POLLIN, 0 );
  589. #ifdef HAVE_LIBSSL
  590. if (conn->state == SCK_STARTTLS) {
  591. start_tls_p2( conn );
  592. return;
  593. }
  594. if (conn->ssl) {
  595. if (do_queued_write( conn ) < 0)
  596. return;
  597. socket_fill( conn );
  598. return;
  599. }
  600. #endif
  601. if ((events & POLLOUT) && do_queued_write( conn ) < 0)
  602. return;
  603. if (events & POLLIN)
  604. socket_fill( conn );
  605. }
  606. #ifdef HAVE_LIBSSL
  607. /* this isn't strictly socket code, but let's have all OpenSSL use in one file. */
  608. #define ENCODED_SIZE(n) (4*((n+2)/3))
  609. static char
  610. hexchar( unsigned int b )
  611. {
  612. if (b < 10)
  613. return '0' + b;
  614. return 'a' + (b - 10);
  615. }
  616. void
  617. cram( const char *challenge, const char *user, const char *pass, char **_final, int *_finallen )
  618. {
  619. unsigned char *response, *final;
  620. unsigned hashlen;
  621. int i, clen, rlen, blen, flen, olen;
  622. unsigned char hash[16];
  623. char buf[256], hex[33];
  624. HMAC_CTX hmac;
  625. HMAC_Init( &hmac, (unsigned char *)pass, strlen( pass ), EVP_md5() );
  626. clen = strlen( challenge );
  627. /* response will always be smaller than challenge because we are decoding. */
  628. response = nfcalloc( 1 + clen );
  629. rlen = EVP_DecodeBlock( response, (unsigned char *)challenge, clen );
  630. HMAC_Update( &hmac, response, rlen );
  631. free( response );
  632. hashlen = sizeof(hash);
  633. HMAC_Final( &hmac, hash, &hashlen );
  634. assert( hashlen == sizeof(hash) );
  635. hex[32] = 0;
  636. for (i = 0; i < 16; i++) {
  637. hex[2 * i] = hexchar( (hash[i] >> 4) & 0xf );
  638. hex[2 * i + 1] = hexchar( hash[i] & 0xf );
  639. }
  640. blen = nfsnprintf( buf, sizeof(buf), "%s %s", user, hex );
  641. flen = ENCODED_SIZE( blen );
  642. final = nfmalloc( flen + 1 );
  643. final[flen] = 0;
  644. olen = EVP_EncodeBlock( (unsigned char *)final, (unsigned char *)buf, blen );
  645. assert( olen == flen );
  646. *_final = (char *)final;
  647. *_finallen = flen;
  648. }
  649. #endif