示例#1
0
int mwFileTransfer_accept(struct mwFileTransfer *ft) {
  struct mwServiceFileTransfer *srvc;
  struct mwFileTransferHandler *handler;
  int ret;

  g_return_val_if_fail(ft != NULL, -1);
  g_return_val_if_fail(ft->channel != NULL, -1);
  g_return_val_if_fail(mwFileTransfer_isPending(ft), -1);
  g_return_val_if_fail(mwChannel_isIncoming(ft->channel), -1);
  g_return_val_if_fail(mwChannel_isState(ft->channel, mwChannel_WAIT), -1);

  g_return_val_if_fail(ft->service != NULL, -1);
  srvc = ft->service;

  g_return_val_if_fail(srvc->handler != NULL, -1);
  handler = srvc->handler;

  ret = mwChannel_accept(ft->channel);

  if(ret) {
    mwFileTransfer_close(ft, ERR_FAILURE);

  } else {
    ft_state(ft, mwFileTransfer_OPEN);
    if(handler->ft_opened)
      handler->ft_opened(ft);
  }

  return ret;
}
示例#2
0
int mwFileTransfer_ack(struct mwFileTransfer *ft) {
  struct mwChannel *chan;

  g_return_val_if_fail(ft != NULL, -1);

  chan = ft->channel;
  g_return_val_if_fail(chan != NULL, -1);
  g_return_val_if_fail(mwChannel_isIncoming(chan), -1);

  return mwChannel_sendEncrypted(chan, msg_RECEIVED, NULL, FALSE);
}
示例#3
0
void mwChannel_recvAccept(struct mwChannel *chan,
			  struct mwMsgChannelAccept *msg) {

  struct mwService *srvc;

  g_return_if_fail(chan != NULL);
  g_return_if_fail(msg != NULL);
  g_return_if_fail(chan->id == msg->head.channel);

  if(mwChannel_isIncoming(chan)) {
    g_warning("channel 0x%08x not an outgoing channel", chan->id);
    mwChannel_destroy(chan, ERR_REQUEST_INVALID, NULL);
    return;
  }

  if(chan->state != mwChannel_WAIT) {
    g_warning("channel 0x%08x state not WAIT: %s",
	      chan->id, state_str(chan->state));
    mwChannel_destroy(chan, ERR_REQUEST_INVALID, NULL);
    return;
  }

  mwLoginInfo_clone(&chan->user, &msg->acceptor);

  srvc = mwSession_getService(chan->session, chan->service);
  if(! srvc) {
    g_warning("no service: 0x%08x", chan->service);
    mwChannel_destroy(chan, ERR_SERVICE_NO_SUPPORT, NULL);
    return;
  }

  chan->policy = msg->encrypt.mode;
  g_message("channel accepted with encrypt policy 0x%04x", chan->policy);

  if(! msg->encrypt.mode || ! msg->encrypt.item) {
    /* no mode or no item means no encryption */
    mwChannel_selectCipherInstance(chan, NULL);

  } else {
    guint16 cid = msg->encrypt.item->id;
    struct mwCipherInstance *ci = get_supported(chan, cid);

    if(! ci) {
      g_warning("not an offered cipher: 0x%04x", cid);
      mwChannel_destroy(chan, ERR_REQUEST_INVALID, NULL);
      return;
    }

    mwCipherInstance_accepted(ci, msg->encrypt.item);
    mwChannel_selectCipherInstance(chan, ci);
  }

  /* mark it as open for the service */
  state(chan, mwChannel_OPEN, 0);

  /* let the service know */
  mwService_recvAccept(srvc, chan, msg);

  /* flush it if the service didn't just immediately close it */
  if(mwChannel_isState(chan, mwChannel_OPEN)) {
    channel_open(chan);
  }
}
示例#4
0
int mwChannel_accept(struct mwChannel *chan) {
  struct mwSession *session;
  struct mwMsgChannelAccept *msg;
  struct mwCipherInstance *ci;

  int ret;

  g_return_val_if_fail(chan != NULL, -1);
  g_return_val_if_fail(mwChannel_isIncoming(chan), -1);
  g_return_val_if_fail(chan->state == mwChannel_WAIT, -1);

  session = chan->session;
  g_return_val_if_fail(session != NULL, -1);

  msg = (struct mwMsgChannelAccept *)
    mwMessage_new(mwMessage_CHANNEL_ACCEPT);

  msg->head.channel = chan->id;
  msg->service = chan->service;
  msg->proto_type = chan->proto_type;
  msg->proto_ver = chan->proto_ver;
  mwOpaque_clone(&msg->addtl, &chan->addtl_accept);

  ci = chan->cipher;

  if(! ci) {
    /* automatically select a cipher if one hasn't been already */

    switch(chan->offered_policy) {
    case mwEncrypt_NONE:
      mwChannel_selectCipherInstance(chan, NULL);
      break;
      
    case mwEncrypt_RC2_40:
      ci = get_supported(chan, mwCipher_RC2_40);
      mwChannel_selectCipherInstance(chan, ci);
      break;

    case mwEncrypt_RC2_128:
      ci = get_supported(chan, mwCipher_RC2_128);
      mwChannel_selectCipherInstance(chan, ci);
      break;
      
    case mwEncrypt_WHATEVER:
    case mwEncrypt_ALL:
    default:
      {
	GList *l, *ll;

	l = mwChannel_getSupportedCipherInstances(chan);
	if(l) {
	  /* nobody selected a cipher, so we'll just pick the last in
	     the list of available ones */
	  for(ll = l; ll->next; ll = ll->next);
	  ci = ll->data;
	  g_list_free(l);
	  
	  mwChannel_selectCipherInstance(chan, ci);
	  
	} else {
	  /* this may cause breakage, but there's really nothing else
	     we can do. They want something we can't provide. If they
	     don't like it, then they'll error the channel out */
	  mwChannel_selectCipherInstance(chan, NULL);
	}
      }
    }
  }

  msg->encrypt.mode = chan->policy; /* set in selectCipherInstance */
  msg->encrypt.extra = chan->offered_policy;

  if(chan->cipher) {
    msg->encrypt.item = mwCipherInstance_accept(chan->cipher);
  }

  ret = mwSession_send(session, MW_MESSAGE(msg));
  mwMessage_free(MW_MESSAGE(msg));

  if(ret) {
    state(chan, mwChannel_ERROR, ret);
  } else {
    channel_open(chan);
  }

  return ret;
}