1 /* $NetBSD: store_sock.c,v 1.2 2017/01/28 21:31:49 christos Exp $ */ 2 3 /* 4 * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan 5 * (Royal Institute of Technology, Stockholm, Sweden). 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 #include "krb5_locl.h" 37 #include "store-int.h" 38 39 #ifdef _WIN32 40 #include <winsock2.h> 41 #endif 42 43 typedef struct socket_storage { 44 krb5_socket_t sock; 45 } socket_storage; 46 47 #define SOCK(S) (((socket_storage*)(S)->data)->sock) 48 49 static ssize_t 50 socket_fetch(krb5_storage * sp, void *data, size_t size) 51 { 52 return net_read(SOCK(sp), data, size); 53 } 54 55 static ssize_t 56 socket_store(krb5_storage * sp, const void *data, size_t size) 57 { 58 return net_write(SOCK(sp), data, size); 59 } 60 61 static off_t 62 socket_seek(krb5_storage * sp, off_t offset, int whence) 63 { 64 return lseek(SOCK(sp), offset, whence); 65 } 66 67 static int 68 socket_trunc(krb5_storage * sp, off_t offset) 69 { 70 if (ftruncate(SOCK(sp), offset) == -1) 71 return errno; 72 return 0; 73 } 74 75 static int 76 socket_sync(krb5_storage * sp) 77 { 78 if (fsync(SOCK(sp)) == -1) 79 return errno; 80 return 0; 81 } 82 83 static void 84 socket_free(krb5_storage * sp) 85 { 86 int save_errno = errno; 87 if (rk_IS_SOCKET_ERROR(rk_closesocket(SOCK(sp)))) 88 errno = rk_SOCK_ERRNO; 89 else 90 errno = save_errno; 91 } 92 93 /** 94 * 95 * 96 * @return A krb5_storage on success, or NULL on out of memory error. 97 * 98 * @ingroup krb5_storage 99 * 100 * @sa krb5_storage_emem() 101 * @sa krb5_storage_from_mem() 102 * @sa krb5_storage_from_readonly_mem() 103 * @sa krb5_storage_from_data() 104 * @sa krb5_storage_from_fd() 105 */ 106 107 KRB5_LIB_FUNCTION krb5_storage * KRB5_LIB_CALL 108 krb5_storage_from_socket(krb5_socket_t sock_in) 109 { 110 krb5_storage *sp; 111 int saved_errno; 112 krb5_socket_t sock; 113 114 #ifdef _WIN32 115 WSAPROTOCOL_INFO info; 116 117 if (WSADuplicateSocket(sock_in, GetCurrentProcessId(), &info) == 0) 118 { 119 120 sock = WSASocket( FROM_PROTOCOL_INFO, 121 FROM_PROTOCOL_INFO, 122 FROM_PROTOCOL_INFO, 123 &info, 0, 0); 124 } 125 #else 126 sock = dup(sock_in); 127 #endif 128 129 if (sock == rk_INVALID_SOCKET) 130 return NULL; 131 132 errno = ENOMEM; 133 sp = malloc(sizeof(krb5_storage)); 134 if (sp == NULL) { 135 saved_errno = errno; 136 rk_closesocket(sock); 137 errno = saved_errno; 138 return NULL; 139 } 140 141 errno = ENOMEM; 142 sp->data = malloc(sizeof(socket_storage)); 143 if (sp->data == NULL) { 144 saved_errno = errno; 145 rk_closesocket(sock); 146 free(sp); 147 errno = saved_errno; 148 return NULL; 149 } 150 sp->flags = 0; 151 sp->eof_code = HEIM_ERR_EOF; 152 SOCK(sp) = sock; 153 sp->fetch = socket_fetch; 154 sp->store = socket_store; 155 sp->seek = socket_seek; 156 sp->trunc = socket_trunc; 157 sp->fsync = socket_sync; 158 sp->free = socket_free; 159 sp->max_alloc = UINT_MAX/8; 160 return sp; 161 } 162