Home | History | Annotate | Line # | Download | only in krb5
      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 Hgskolan
      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