예제 #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
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);
  }
}