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