195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* crypto/bio/bss_sock.c */
295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * All rights reserved.
495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This package is an SSL implementation written
695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * by Eric Young (eay@cryptsoft.com).
795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * The implementation was written so as to conform with Netscapes SSL.
895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This library is free for commercial and non-commercial use as long as
1095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the following conditions are aheared to.  The following conditions
1195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * apply to all code found in this distribution, be it the RC4, RSA,
1295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * included with this distribution is covered by the same copyright terms
1495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
1695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Copyright remains Eric Young's, and as such any Copyright notices in
1795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * the code are not to be removed.
1895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * If this package is used in a product, Eric Young should be given attribution
1995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * as the author of the parts of the library used.
2095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * This can be in the form of a textual message at program startup or
2195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * in documentation (online or textual) provided with the package.
2295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
2395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * Redistribution and use in source and binary forms, with or without
2495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * modification, are permitted provided that the following conditions
2595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * are met:
2695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 1. Redistributions of source code must retain the copyright
2795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    notice, this list of conditions and the following disclaimer.
2895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 2. Redistributions in binary form must reproduce the above copyright
2995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    notice, this list of conditions and the following disclaimer in the
3095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    documentation and/or other materials provided with the distribution.
3195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 3. All advertising materials mentioning features or use of this software
3295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    must display the following acknowledgement:
3395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    "This product includes cryptographic software written by
3495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *     Eric Young (eay@cryptsoft.com)"
3595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    The word 'cryptographic' can be left out if the rouines from the library
3695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    being used are not cryptographic related :-).
3795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * 4. If you include any Windows specific code (or a derivative thereof) from
3895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    the apps directory (application code) you must include an acknowledgement:
3995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
4095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
4195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * SUCH DAMAGE.
5295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley *
5395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * The licence and distribution terms for any publically available version or
5495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * derivative of this code cannot be changed.  i.e. this code cannot simply be
5595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * copied and put under another distribution licence
5695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley * [including the GNU Public Licence.] */
5795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
5895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <openssl/bio.h>
5995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
6095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <fcntl.h>
6195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
6295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#if !defined(OPENSSL_WINDOWS)
6395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include <unistd.h>
6495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#endif
6595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
6695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley#include "internal.h"
6795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
6895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
6995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int sock_new(BIO *bio) {
7095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  bio->init = 0;
7195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  bio->num = 0;
7295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  bio->ptr = NULL;
7395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  bio->flags = 0;
7495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  return 1;
7595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
7695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
7795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int sock_free(BIO *bio) {
7895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  if (bio == NULL) {
7995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    return 0;
8095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  }
8195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
8295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  if (bio->shutdown) {
8395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    if (bio->init) {
8495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley      close(bio->num);
8595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    }
8695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    bio->init = 0;
8795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    bio->flags = 0;
8895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  }
8995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  return 1;
9095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
9195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
9295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int sock_read(BIO *b, char *out, int outl) {
9395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  int ret = 0;
9495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
9595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  if (out == NULL) {
9695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    return 0;
9795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  }
9895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
9995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  bio_clear_socket_error();
10095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  ret = recv(b->num, out, outl, 0);
10195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  BIO_clear_retry_flags(b);
10295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  if (ret <= 0) {
10395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    if (bio_fd_should_retry(ret)) {
10495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley      BIO_set_retry_read(b);
10595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    }
10695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  }
10795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  return ret;
10895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
10995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
11095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int sock_write(BIO *b, const char *in, int inl) {
11195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  int ret;
11295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
11395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  bio_clear_socket_error();
11495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  ret = send(b->num, in, inl, 0);
11595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  BIO_clear_retry_flags(b);
11695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  if (ret <= 0) {
11795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    if (bio_fd_should_retry(ret)) {
11895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley      BIO_set_retry_write(b);
11995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    }
12095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  }
12195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  return ret;
12295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
12395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
12495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic int sock_puts(BIO *bp, const char *str) {
12595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  return sock_write(bp, str, strlen(str));
12695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
12795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
12895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic long sock_ctrl(BIO *b, int cmd, long num, void *ptr) {
12995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  long ret = 1;
13095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  int *ip;
13195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
13295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  switch (cmd) {
13395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    case BIO_C_SET_FD:
13495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley      sock_free(b);
13595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley      b->num = *((int *)ptr);
13695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley      b->shutdown = (int)num;
13795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley      b->init = 1;
13895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley      break;
13995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    case BIO_C_GET_FD:
14095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley      if (b->init) {
14195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        ip = (int *)ptr;
14295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        if (ip != NULL)
14395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley          *ip = b->num;
14495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        ret = b->num;
14595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley      } else
14695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley        ret = -1;
14795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley      break;
14895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    case BIO_CTRL_GET_CLOSE:
14995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley      ret = b->shutdown;
15095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley      break;
15195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    case BIO_CTRL_SET_CLOSE:
15295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley      b->shutdown = (int)num;
15395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley      break;
15495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    case BIO_CTRL_FLUSH:
15595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley      ret = 1;
15695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley      break;
15795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    default:
15895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley      ret = 0;
15995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley      break;
16095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  }
16195c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  return ret;
16295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
16395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
16495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleystatic const BIO_METHOD methods_sockp = {
16595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    BIO_TYPE_SOCKET,  "socket",  sock_write, sock_read, sock_puts,
16695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    NULL /* gets, */, sock_ctrl, sock_new,   sock_free, NULL,
16795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley};
16895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
16995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langleyconst BIO_METHOD *BIO_s_socket(void) { return &methods_sockp; }
17095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
17195c29f3cd1f6c08c6c0927868683392eea727ccAdam LangleyBIO *BIO_new_socket(int fd, int close_flag) {
17295c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  BIO *ret;
17395c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley
17495c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  ret = BIO_new(BIO_s_socket());
17595c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  if (ret == NULL) {
17695c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley    return NULL;
17795c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  }
17895c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  BIO_set_fd(ret, fd, close_flag);
17995c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley  return ret;
18095c29f3cd1f6c08c6c0927868683392eea727ccAdam Langley}
181