155714Skris/* crypto/bio/bss_rtcp.c */ 255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 355714Skris * All rights reserved. 455714Skris * 555714Skris * This package is an SSL implementation written 655714Skris * by Eric Young (eay@cryptsoft.com). 755714Skris * The implementation was written so as to conform with Netscapes SSL. 8280297Sjkim * 955714Skris * This library is free for commercial and non-commercial use as long as 1055714Skris * the following conditions are aheared to. The following conditions 1155714Skris * apply to all code found in this distribution, be it the RC4, RSA, 1255714Skris * lhash, DES, etc., code; not just the SSL code. The SSL documentation 1355714Skris * included with this distribution is covered by the same copyright terms 1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15280297Sjkim * 1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in 1755714Skris * the code are not to be removed. 1855714Skris * If this package is used in a product, Eric Young should be given attribution 1955714Skris * as the author of the parts of the library used. 2055714Skris * This can be in the form of a textual message at program startup or 2155714Skris * in documentation (online or textual) provided with the package. 22280297Sjkim * 2355714Skris * Redistribution and use in source and binary forms, with or without 2455714Skris * modification, are permitted provided that the following conditions 2555714Skris * are met: 2655714Skris * 1. Redistributions of source code must retain the copyright 2755714Skris * notice, this list of conditions and the following disclaimer. 2855714Skris * 2. Redistributions in binary form must reproduce the above copyright 2955714Skris * notice, this list of conditions and the following disclaimer in the 3055714Skris * documentation and/or other materials provided with the distribution. 3155714Skris * 3. All advertising materials mentioning features or use of this software 3255714Skris * must display the following acknowledgement: 3355714Skris * "This product includes cryptographic software written by 3455714Skris * Eric Young (eay@cryptsoft.com)" 3555714Skris * The word 'cryptographic' can be left out if the rouines from the library 3655714Skris * being used are not cryptographic related :-). 37280297Sjkim * 4. If you include any Windows specific code (or a derivative thereof) from 3855714Skris * the apps directory (application code) you must include an acknowledgement: 3955714Skris * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40280297Sjkim * 4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 4455714Skris * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 5155714Skris * SUCH DAMAGE. 52280297Sjkim * 5355714Skris * The licence and distribution terms for any publically available version or 5455714Skris * derivative of this code cannot be changed. i.e. this code cannot simply be 5555714Skris * copied and put under another distribution licence 5655714Skris * [including the GNU Public Licence.] 5755714Skris */ 5855714Skris 59280297Sjkim/*- 60280297Sjkim * Written by David L. Jones <jonesd@kcgl1.eng.ohio-state.edu> 6155714Skris * Date: 22-JUL-1996 62280297Sjkim * Revised: 25-SEP-1997 Update for 0.8.1, BIO_CTRL_SET -> BIO_C_SET_FD 6355714Skris */ 6455714Skris/* VMS */ 6555714Skris#include <stdio.h> 6655714Skris#include <stdlib.h> 6755714Skris#include <string.h> 6855714Skris#include <errno.h> 6955714Skris#include "cryptlib.h" 7055714Skris#include <openssl/bio.h> 7155714Skris 72280297Sjkim#include <iodef.h> /* VMS IO$_ definitions */ 7355714Skris#include <starlet.h> 7455714Skris 7555714Skristypedef unsigned short io_channel; 7655714Skris/*************************************************************************/ 77280297Sjkimstruct io_status { 78280297Sjkim short status, count; 79280297Sjkim long flags; 80280297Sjkim}; 8155714Skris 82280297Sjkim/* Should have member alignment inhibited */ 83280297Sjkimstruct rpc_msg { 84280297Sjkim /* 'A'-app data. 'R'-remote client 'G'-global */ 85280297Sjkim char channel; 86280297Sjkim /* 'G'-get, 'P'-put, 'C'-confirm, 'X'-close */ 87280297Sjkim char function; 88280297Sjkim /* Amount of data returned or max to return */ 89280297Sjkim unsigned short int length; 90280297Sjkim /* variable data */ 91280297Sjkim char data[4092]; 9255714Skris}; 9355714Skris#define RPC_HDR_SIZE (sizeof(struct rpc_msg) - 4092) 9455714Skris 9555714Skrisstruct rpc_ctx { 9655714Skris int filled, pos; 9755714Skris struct rpc_msg msg; 9855714Skris}; 9955714Skris 100280297Sjkimstatic int rtcp_write(BIO *h, const char *buf, int num); 101280297Sjkimstatic int rtcp_read(BIO *h, char *buf, int size); 102280297Sjkimstatic int rtcp_puts(BIO *h, const char *str); 103280297Sjkimstatic int rtcp_gets(BIO *h, char *str, int size); 104280297Sjkimstatic long rtcp_ctrl(BIO *h, int cmd, long arg1, void *arg2); 10555714Skrisstatic int rtcp_new(BIO *h); 10655714Skrisstatic int rtcp_free(BIO *data); 10755714Skris 108280297Sjkimstatic BIO_METHOD rtcp_method = { 109280297Sjkim BIO_TYPE_FD, 110280297Sjkim "RTCP", 111280297Sjkim rtcp_write, 112280297Sjkim rtcp_read, 113280297Sjkim rtcp_puts, 114280297Sjkim rtcp_gets, 115280297Sjkim rtcp_ctrl, 116280297Sjkim rtcp_new, 117280297Sjkim rtcp_free, 118280297Sjkim NULL, 119280297Sjkim}; 12055714Skris 12155714SkrisBIO_METHOD *BIO_s_rtcp(void) 122280297Sjkim{ 123280297Sjkim return (&rtcp_method); 124280297Sjkim} 125280297Sjkim 12655714Skris/*****************************************************************************/ 127280297Sjkim/* 128280297Sjkim * Decnet I/O routines. 12955714Skris */ 13055714Skris 13155714Skris#ifdef __DECC 132280297Sjkim# pragma message save 133280297Sjkim# pragma message disable DOLLARID 13455714Skris#endif 13555714Skris 136280297Sjkimstatic int get(io_channel chan, char *buffer, int maxlen, int *length) 13755714Skris{ 13855714Skris int status; 13955714Skris struct io_status iosb; 140280297Sjkim status = sys$qiow(0, chan, IO$_READVBLK, &iosb, 0, 0, 141280297Sjkim buffer, maxlen, 0, 0, 0, 0); 142280297Sjkim if ((status & 1) == 1) 143280297Sjkim status = iosb.status; 144280297Sjkim if ((status & 1) == 1) 145280297Sjkim *length = iosb.count; 14655714Skris return status; 14755714Skris} 14855714Skris 149280297Sjkimstatic int put(io_channel chan, char *buffer, int length) 15055714Skris{ 15155714Skris int status; 15255714Skris struct io_status iosb; 153280297Sjkim status = sys$qiow(0, chan, IO$_WRITEVBLK, &iosb, 0, 0, 154280297Sjkim buffer, length, 0, 0, 0, 0); 155280297Sjkim if ((status & 1) == 1) 156280297Sjkim status = iosb.status; 15755714Skris return status; 15855714Skris} 15955714Skris 16055714Skris#ifdef __DECC 161280297Sjkim# pragma message restore 16255714Skris#endif 16355714Skris 16455714Skris/***************************************************************************/ 16555714Skris 16655714Skrisstatic int rtcp_new(BIO *bi) 16755714Skris{ 16855714Skris struct rpc_ctx *ctx; 169280297Sjkim bi->init = 1; 170280297Sjkim bi->num = 0; 171280297Sjkim bi->flags = 0; 172280297Sjkim bi->ptr = OPENSSL_malloc(sizeof(struct rpc_ctx)); 173306195Sjkim if (bi->ptr == NULL) 174306195Sjkim return (0); 175280297Sjkim ctx = (struct rpc_ctx *)bi->ptr; 176280297Sjkim ctx->filled = 0; 177280297Sjkim ctx->pos = 0; 178280297Sjkim return (1); 17955714Skris} 18055714Skris 18155714Skrisstatic int rtcp_free(BIO *a) 18255714Skris{ 183280297Sjkim if (a == NULL) 184280297Sjkim return (0); 185280297Sjkim if (a->ptr) 186280297Sjkim OPENSSL_free(a->ptr); 187280297Sjkim a->ptr = NULL; 188280297Sjkim return (1); 18955714Skris} 190280297Sjkim 19155714Skrisstatic int rtcp_read(BIO *b, char *out, int outl) 19255714Skris{ 19355714Skris int status, length; 19455714Skris struct rpc_ctx *ctx; 19555714Skris /* 19655714Skris * read data, return existing. 19755714Skris */ 198280297Sjkim ctx = (struct rpc_ctx *)b->ptr; 199280297Sjkim if (ctx->pos < ctx->filled) { 200280297Sjkim length = ctx->filled - ctx->pos; 201280297Sjkim if (length > outl) 202280297Sjkim length = outl; 203280297Sjkim memmove(out, &ctx->msg.data[ctx->pos], length); 204280297Sjkim ctx->pos += length; 205280297Sjkim return length; 20655714Skris } 20755714Skris /* 20855714Skris * Requst more data from R channel. 20955714Skris */ 21055714Skris ctx->msg.channel = 'R'; 21155714Skris ctx->msg.function = 'G'; 21255714Skris ctx->msg.length = sizeof(ctx->msg.data); 213280297Sjkim status = put(b->num, (char *)&ctx->msg, RPC_HDR_SIZE); 214280297Sjkim if ((status & 1) == 0) { 215280297Sjkim return -1; 21655714Skris } 21755714Skris /* 21855714Skris * Read. 21955714Skris */ 22055714Skris ctx->pos = ctx->filled = 0; 221280297Sjkim status = get(b->num, (char *)&ctx->msg, sizeof(ctx->msg), &length); 222280297Sjkim if ((status & 1) == 0) 223280297Sjkim length = -1; 224280297Sjkim if (ctx->msg.channel != 'R' || ctx->msg.function != 'C') { 225280297Sjkim length = -1; 22655714Skris } 22755714Skris ctx->filled = length - RPC_HDR_SIZE; 228280297Sjkim 229280297Sjkim if (ctx->pos < ctx->filled) { 230280297Sjkim length = ctx->filled - ctx->pos; 231280297Sjkim if (length > outl) 232280297Sjkim length = outl; 233280297Sjkim memmove(out, ctx->msg.data, length); 234280297Sjkim ctx->pos += length; 235280297Sjkim return length; 23655714Skris } 23755714Skris 23855714Skris return length; 23955714Skris} 24055714Skris 24168651Skrisstatic int rtcp_write(BIO *b, const char *in, int inl) 24255714Skris{ 24355714Skris int status, i, segment, length; 24455714Skris struct rpc_ctx *ctx; 24555714Skris /* 24655714Skris * Output data, send in chunks no larger that sizeof(ctx->msg.data). 24755714Skris */ 248280297Sjkim ctx = (struct rpc_ctx *)b->ptr; 249280297Sjkim for (i = 0; i < inl; i += segment) { 250280297Sjkim segment = inl - i; 251280297Sjkim if (segment > sizeof(ctx->msg.data)) 252280297Sjkim segment = sizeof(ctx->msg.data); 253280297Sjkim ctx->msg.channel = 'R'; 254280297Sjkim ctx->msg.function = 'P'; 255280297Sjkim ctx->msg.length = segment; 256280297Sjkim memmove(ctx->msg.data, &in[i], segment); 257280297Sjkim status = put(b->num, (char *)&ctx->msg, segment + RPC_HDR_SIZE); 258280297Sjkim if ((status & 1) == 0) { 259280297Sjkim i = -1; 260280297Sjkim break; 261280297Sjkim } 26255714Skris 263280297Sjkim status = get(b->num, (char *)&ctx->msg, sizeof(ctx->msg), &length); 264280297Sjkim if (((status & 1) == 0) || (length < RPC_HDR_SIZE)) { 265280297Sjkim i = -1; 266280297Sjkim break; 267280297Sjkim } 268280297Sjkim if ((ctx->msg.channel != 'R') || (ctx->msg.function != 'C')) { 269280297Sjkim printf("unexpected response when confirming put %c %c\n", 270280297Sjkim ctx->msg.channel, ctx->msg.function); 27155714Skris 272280297Sjkim } 27355714Skris } 274280297Sjkim return (i); 27555714Skris} 27655714Skris 27768651Skrisstatic long rtcp_ctrl(BIO *b, int cmd, long num, void *ptr) 278280297Sjkim{ 279280297Sjkim long ret = 1; 28055714Skris 281280297Sjkim switch (cmd) { 282280297Sjkim case BIO_CTRL_RESET: 283280297Sjkim case BIO_CTRL_EOF: 284280297Sjkim ret = 1; 285280297Sjkim break; 286280297Sjkim case BIO_C_SET_FD: 287280297Sjkim b->num = num; 288280297Sjkim ret = 1; 289280297Sjkim break; 290280297Sjkim case BIO_CTRL_SET_CLOSE: 291280297Sjkim case BIO_CTRL_FLUSH: 292280297Sjkim case BIO_CTRL_DUP: 293280297Sjkim ret = 1; 294280297Sjkim break; 295280297Sjkim case BIO_CTRL_GET_CLOSE: 296280297Sjkim case BIO_CTRL_INFO: 297280297Sjkim case BIO_CTRL_GET: 298280297Sjkim case BIO_CTRL_PENDING: 299280297Sjkim case BIO_CTRL_WPENDING: 300280297Sjkim default: 301280297Sjkim ret = 0; 302280297Sjkim break; 303280297Sjkim } 304280297Sjkim return (ret); 305280297Sjkim} 30655714Skris 30755714Skrisstatic int rtcp_gets(BIO *bp, char *buf, int size) 308280297Sjkim{ 309280297Sjkim return (0); 310280297Sjkim} 31155714Skris 31268651Skrisstatic int rtcp_puts(BIO *bp, const char *str) 31355714Skris{ 31455714Skris int length; 315280297Sjkim if (str == NULL) 316280297Sjkim return (0); 317280297Sjkim length = strlen(str); 318280297Sjkim if (length == 0) 319280297Sjkim return (0); 320280297Sjkim return rtcp_write(bp, str, length); 32155714Skris} 322