1 /* 2 * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <stdio.h> 11 #include <errno.h> 12 13 #include "bio_local.h" 14 15 #if defined(OPENSSL_NO_POSIX_IO) 16 /* 17 * Dummy placeholder for BIO_s_fd... 18 */ 19 BIO *BIO_new_fd(int fd, int close_flag) 20 { 21 return NULL; 22 } 23 24 int BIO_fd_non_fatal_error(int err) 25 { 26 return 0; 27 } 28 29 int BIO_fd_should_retry(int i) 30 { 31 return 0; 32 } 33 34 const BIO_METHOD *BIO_s_fd(void) 35 { 36 return NULL; 37 } 38 #else 39 /* 40 * As for unconditional usage of "UPLINK" interface in this module. 41 * Trouble is that unlike Unix file descriptors [which are indexes 42 * in kernel-side per-process table], corresponding descriptors on 43 * platforms which require "UPLINK" interface seem to be indexes 44 * in a user-land, non-global table. Well, in fact they are indexes 45 * in stdio _iob[], and recall that _iob[] was the very reason why 46 * "UPLINK" interface was introduced in first place. But one way on 47 * another. Neither libcrypto or libssl use this BIO meaning that 48 * file descriptors can only be provided by application. Therefore 49 * "UPLINK" calls are due... 50 */ 51 static int fd_write(BIO *h, const char *buf, int num); 52 static int fd_read(BIO *h, char *buf, int size); 53 static int fd_puts(BIO *h, const char *str); 54 static int fd_gets(BIO *h, char *buf, int size); 55 static long fd_ctrl(BIO *h, int cmd, long arg1, void *arg2); 56 static int fd_new(BIO *h); 57 static int fd_free(BIO *data); 58 int BIO_fd_should_retry(int s); 59 60 static const BIO_METHOD methods_fdp = { 61 BIO_TYPE_FD, 62 "file descriptor", 63 bwrite_conv, 64 fd_write, 65 bread_conv, 66 fd_read, 67 fd_puts, 68 fd_gets, 69 fd_ctrl, 70 fd_new, 71 fd_free, 72 NULL, /* fd_callback_ctrl */ 73 }; 74 75 const BIO_METHOD *BIO_s_fd(void) 76 { 77 return &methods_fdp; 78 } 79 80 BIO *BIO_new_fd(int fd, int close_flag) 81 { 82 BIO *ret; 83 ret = BIO_new(BIO_s_fd()); 84 if (ret == NULL) 85 return NULL; 86 BIO_set_fd(ret, fd, close_flag); 87 return ret; 88 } 89 90 static int fd_new(BIO *bi) 91 { 92 bi->init = 0; 93 bi->num = -1; 94 bi->ptr = NULL; 95 bi->flags = BIO_FLAGS_UPLINK_INTERNAL; /* essentially redundant */ 96 return 1; 97 } 98 99 static int fd_free(BIO *a) 100 { 101 if (a == NULL) 102 return 0; 103 if (a->shutdown) { 104 if (a->init) { 105 UP_close(a->num); 106 } 107 a->init = 0; 108 a->flags = BIO_FLAGS_UPLINK_INTERNAL; 109 } 110 return 1; 111 } 112 113 static int fd_read(BIO *b, char *out, int outl) 114 { 115 int ret = 0; 116 117 if (out != NULL) { 118 clear_sys_error(); 119 ret = UP_read(b->num, out, outl); 120 BIO_clear_retry_flags(b); 121 if (ret <= 0) { 122 if (BIO_fd_should_retry(ret)) 123 BIO_set_retry_read(b); 124 else if (ret == 0) 125 b->flags |= BIO_FLAGS_IN_EOF; 126 } 127 } 128 return ret; 129 } 130 131 static int fd_write(BIO *b, const char *in, int inl) 132 { 133 int ret; 134 clear_sys_error(); 135 ret = UP_write(b->num, in, inl); 136 BIO_clear_retry_flags(b); 137 if (ret <= 0) { 138 if (BIO_fd_should_retry(ret)) 139 BIO_set_retry_write(b); 140 } 141 return ret; 142 } 143 144 static long fd_ctrl(BIO *b, int cmd, long num, void *ptr) 145 { 146 long ret = 1; 147 int *ip; 148 149 switch (cmd) { 150 case BIO_CTRL_RESET: 151 num = 0; 152 /* fall thru */ 153 case BIO_C_FILE_SEEK: 154 ret = (long)UP_lseek(b->num, num, 0); 155 break; 156 case BIO_C_FILE_TELL: 157 case BIO_CTRL_INFO: 158 ret = (long)UP_lseek(b->num, 0, 1); 159 break; 160 case BIO_C_SET_FD: 161 fd_free(b); 162 b->num = *((int *)ptr); 163 b->shutdown = (int)num; 164 b->init = 1; 165 break; 166 case BIO_C_GET_FD: 167 if (b->init) { 168 ip = (int *)ptr; 169 if (ip != NULL) 170 *ip = b->num; 171 ret = b->num; 172 } else 173 ret = -1; 174 break; 175 case BIO_CTRL_GET_CLOSE: 176 ret = b->shutdown; 177 break; 178 case BIO_CTRL_SET_CLOSE: 179 b->shutdown = (int)num; 180 break; 181 case BIO_CTRL_PENDING: 182 case BIO_CTRL_WPENDING: 183 ret = 0; 184 break; 185 case BIO_CTRL_DUP: 186 case BIO_CTRL_FLUSH: 187 ret = 1; 188 break; 189 case BIO_CTRL_EOF: 190 ret = (b->flags & BIO_FLAGS_IN_EOF) != 0; 191 break; 192 default: 193 ret = 0; 194 break; 195 } 196 return ret; 197 } 198 199 static int fd_puts(BIO *bp, const char *str) 200 { 201 int n, ret; 202 203 n = strlen(str); 204 ret = fd_write(bp, str, n); 205 return ret; 206 } 207 208 static int fd_gets(BIO *bp, char *buf, int size) 209 { 210 int ret = 0; 211 char *ptr = buf; 212 char *end = buf + size - 1; 213 214 while (ptr < end && fd_read(bp, ptr, 1) > 0) { 215 if (*ptr++ == '\n') 216 break; 217 } 218 219 ptr[0] = '\0'; 220 221 if (buf[0] != '\0') 222 ret = strlen(buf); 223 return ret; 224 } 225 226 int BIO_fd_should_retry(int i) 227 { 228 int err; 229 230 if ((i == 0) || (i == -1)) { 231 err = get_last_sys_error(); 232 233 return BIO_fd_non_fatal_error(err); 234 } 235 return 0; 236 } 237 238 int BIO_fd_non_fatal_error(int err) 239 { 240 switch (err) { 241 242 # ifdef EWOULDBLOCK 243 # ifdef WSAEWOULDBLOCK 244 # if WSAEWOULDBLOCK != EWOULDBLOCK 245 case EWOULDBLOCK: 246 # endif 247 # else 248 case EWOULDBLOCK: 249 # endif 250 # endif 251 252 # if defined(ENOTCONN) 253 case ENOTCONN: 254 # endif 255 256 # ifdef EINTR 257 case EINTR: 258 # endif 259 260 # ifdef EAGAIN 261 # if EWOULDBLOCK != EAGAIN 262 case EAGAIN: 263 # endif 264 # endif 265 266 # ifdef EPROTO 267 case EPROTO: 268 # endif 269 270 # ifdef EINPROGRESS 271 case EINPROGRESS: 272 # endif 273 274 # ifdef EALREADY 275 case EALREADY: 276 # endif 277 return 1; 278 default: 279 break; 280 } 281 return 0; 282 } 283 #endif 284