security 5.85 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
/* Copyright 1998 Acorn Computers Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * HTTP (c.config)
 *
 *  Acorn Computers Ltd. 1998
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include "kernel.h"
#include "swis.h"
#include "sys/errno.h"
#include "sys/types.h"
#include "sys/socket.h"
#include "module.h"
#include "socklib.h"
#include "security.h"

static int ssl_module_present;

static int sec_socketioctl(int, unsigned long, ...);
static int sec_socket(int domain, int type, int protocol);
static int sec_connect(int s, const struct sockaddr *name, int namelen);
static int sec_shutdown(int s, int how);
static int sec_socketclose(int d);
static int sec_getsockopt(int s, int level, int optname,
		      void *optval, int *optlen);
static int sec_socketwrite(int s, const void *buf, unsigned int len);
static int sec_recv(int s, void *data, size_t size, int flags);

int security_ssl_available(void)
{
        return ssl_module_present;
}

void security_init(void)
{
        ssl_module_present = 0;
}

int security_ssl_arrived(int ver)
{
59 60 61 62
        if (ver < 3) {
                /* We do not support the 'old' interface */
                return security_ssl_gone();
        }
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
        ssl_module_present = ver;
        return ssl_module_present;
}

int security_ssl_gone(void)
{
        ssl_module_present = 0;
        return ssl_module_present;
}

const sock_vtbl *security_get_ssl_vtable(void)
{
        static const sock_vtbl vtable = {
                sec_socketioctl,
                sec_socket,
                sec_connect,
                sec_shutdown,
                sec_socketclose,
                sec_getsockopt,
                sec_socketwrite,
                sec_recv
        };
        return &vtable;
}

const sock_vtbl *security_get_normal_vtable(void)
{
        static const sock_vtbl vtable = {
                socketioctl,
                socket,
                connect,
                shutdown,
                socketclose,
                getsockopt,
                socketwrite,
                recv
        };
        return &vtable;
}

/* ---- implementation veneers to the secure socket stuff */

#ifdef FAKE_SSL_MODULE
/* Dummy implementation */

static int sec_socketioctl(int s, unsigned long op, ...)
{
        void *data;
        va_list ap;
        va_start(ap, op);
	data = va_arg(ap, void *);
        va_end(ap);
        return socketioctl(s, op, data);
}

static int sec_socket(int domain, int type, int protocol)
{
        return socket(domain, type, protocol);
}

static int sec_connect(int s, const struct sockaddr *name, int namelen)
{
        return connect(s, name, namelen);
}

static int sec_shutdown(int s, int how)
{
        return shutdown(s, how);
}

static int sec_socketclose(int d)
{
        return socketclose(d);
}

static int sec_getsockopt(int s, int level, int optname,
		      void *optval, int *optlen)
{
        return getsockopt(s, level, optname, optval, optlen);
}

static int sec_socketwrite(int s, const void *buf, unsigned int len)
{
        return socketwrite(s, buf, len);
}

static int sec_recv(int s, void *data, size_t size, int flags)
{
        return recv(s, data, size, flags);
}

#else

ROOL's avatar
ROOL committed
156
#include "sys/dcistructs.h"
ROOL's avatar
ROOL committed
157
#include "Interface/AcornSSL.h"
158 159 160 161 162 163 164 165 166 167 168 169

static int sec_socketioctl(int s, unsigned long op, ...)
{
        _kernel_oserror *e;
        int result;

        void *data;
        va_list ap;
        va_start(ap, op);
	data = va_arg(ap, void *);
        va_end(ap);

170
        e = _swix(AcornSSL_Ioctl, _INR(0,2)|_OUT(0),
171 172
        	s, op, data, &result);
        if (!e) return result;
ROOL's avatar
ROOL committed
173
        errno = GETDCI4ERRNO(e->errnum);
174 175 176 177 178 179 180 181
        return -1;
}

static int sec_socket(int domain, int type, int protocol)
{
        _kernel_oserror *e;
	int result;

ROOL's avatar
ROOL committed
182
	e = _swix(AcornSSL_Creat, _INR(0,2)|_OUT(0),
183 184 185
		domain, type, protocol,
		&result);
	if (!e) return result;
ROOL's avatar
ROOL committed
186
	errno = GETDCI4ERRNO(e->errnum);
187 188 189 190 191 192 193 194
	return -1;
}

static int sec_connect(int s, const struct sockaddr *name, int namelen)
{
        _kernel_oserror *e;
	int result;

195
	e = _swix(AcornSSL_Connect, _INR(0,2)|_OUT(0),
196 197 198
		s, name, namelen,
		&result);
	if (!e) return result;
ROOL's avatar
ROOL committed
199
	errno = GETDCI4ERRNO(e->errnum);
200 201 202 203 204 205 206 207
	return -1;
}

static int sec_shutdown(int s, int how)
{
        _kernel_oserror *e;
	int result;

208
	e = _swix(AcornSSL_Shutdown, _INR(0,1)|_OUT(0),
209 210 211
		s, how,
		&result);
	if (!e) return result;
ROOL's avatar
ROOL committed
212
	errno = GETDCI4ERRNO(e->errnum);
213 214 215 216 217 218 219 220
	return -1;
}

static int sec_socketclose(int d)
{
        _kernel_oserror *e;
	int result;

221
	e = _swix(AcornSSL_Close, _IN(0)|_OUT(0),
222 223 224
		d,
		&result);
	if (!e) return result;
ROOL's avatar
ROOL committed
225
	errno = GETDCI4ERRNO(e->errnum);
226 227 228 229 230 231 232 233 234
	return -1;
}

static int sec_getsockopt(int s, int level, int optname,
		      void *optval, int *optlen)
{
        _kernel_oserror *e;
	int result;

235
	e = _swix(AcornSSL_Getsockopt, _INR(0,4)|_OUT(0),
236 237 238
		s, level, optname, optval, optlen,
		&result);
	if (!e) return result;
ROOL's avatar
ROOL committed
239
	errno = GETDCI4ERRNO(e->errnum);
240 241 242 243 244 245 246 247
	return -1;
}

static int sec_socketwrite(int s, const void *buf, unsigned int len)
{
        _kernel_oserror *e;
	int result;

248
	e = _swix(AcornSSL_Write, _INR(0,2)|_OUT(0),
249 250 251
		s, buf, len,
		&result);
	if (!e) return result;
ROOL's avatar
ROOL committed
252
	errno = GETDCI4ERRNO(e->errnum);
253 254 255 256 257 258 259 260
	return -1;
}

static int sec_recv(int s, void *data, size_t size, int flags)
{
        _kernel_oserror *e;
	int result;

261
	e = _swix(AcornSSL_Recv, _INR(0,3)|_OUT(0),
262 263 264
		s, data, size, flags,
		&result);
	if (!e) return result;
ROOL's avatar
ROOL committed
265
	errno = GETDCI4ERRNO(e->errnum);
266 267 268
	return -1;
}
#endif