Ejemplo n.º 1
0
void mwChannel_recvCreate(struct mwChannel *chan,
			  struct mwMsgChannelCreate *msg) {

  struct mwSession *session;
  GList *list;
  struct mwService *srvc;
  
  g_return_if_fail(chan != NULL);
  g_return_if_fail(msg != NULL);
  g_return_if_fail(chan->id == msg->channel);

  session = chan->session;
  g_return_if_fail(session != NULL);

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

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

  for(list = msg->encrypt.items; list; list = list->next) {
    struct mwEncryptItem *ei = list->data;
    struct mwCipher *cipher;
    struct mwCipherInstance *ci;

    g_message("channel offered cipher id 0x%04x", ei->id);
    cipher = mwSession_getCipher(session, ei->id);
    if(! cipher) {
      g_message("no such cipher found in session");
      continue;
    }

    ci = mwCipher_newInstance(cipher, chan);
    mwCipherInstance_offered(ci, ei);
    mwChannel_addSupportedCipherInstance(chan, ci);
  }

  mwLoginInfo_clone(&chan->user, &msg->creator);
  chan->service = msg->service;
  chan->proto_type = msg->proto_type;
  chan->proto_ver = msg->proto_ver;
  
  srvc = mwSession_getService(session, msg->service);
  if(srvc) {
    mwService_recvCreate(srvc, chan, msg);

  } else {
    mwChannel_destroy(chan, ERR_SERVICE_NO_SUPPORT, NULL);
  }  
}
Ejemplo n.º 2
0
int mwFileTransfer_close(struct mwFileTransfer *ft, guint32 code) {
  struct mwServiceFileTransfer *srvc;
  struct mwFileTransferHandler *handler;
  int ret = 0;

  g_return_val_if_fail(ft != NULL, -1);

  if(mwFileTransfer_isOpen(ft))
    ft_state(ft, mwFileTransfer_CANCEL_LOCAL);

  if(ft->channel) {
    ret = mwChannel_destroy(ft->channel, code, NULL);
    ft->channel = NULL;
  }

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

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

  if(handler->ft_closed)
    handler->ft_closed(ft, code);

  return ret;
}
Ejemplo n.º 3
0
static void recv_create(struct mwServiceDirectory *srvc,
			struct mwChannel *chan,
			struct mwMsgChannelCreate *msg) {

  /* no way man, we call the shots around here */
  mwChannel_destroy(chan, ERR_FAILURE, NULL);
}
Ejemplo n.º 4
0
int mwConference_destroy(struct mwConference *conf,
			 guint32 reason, const char *text) {

  struct mwServiceConference *srvc;
  struct mwOpaque info = { 0, 0 };
  int ret = 0;

  g_return_val_if_fail(conf != NULL, -1);

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

  /* remove conference from the service */
  srvc->confs = g_list_remove_all(srvc->confs, conf);

  /* close the channel if applicable */
  if(conf->channel) {
    if(text && *text) {
      info.len = strlen(text);
      info.data = (guchar *) text;
    }

    ret = mwChannel_destroy(conf->channel, reason, &info);
  }
  
  /* free the conference */
  conf_free(conf);

  return ret;
}
Ejemplo n.º 5
0
static void stop(struct mwServiceDirectory *srvc) {
  /* XXX */

  if(srvc->channel) {
    mwChannel_destroy(srvc->channel, ERR_SUCCESS, NULL);
    srvc->channel = NULL;
  }
}
Ejemplo n.º 6
0
int mwPlace_destroy(struct mwPlace *p, guint32 code) {
  int ret = 0;

  place_state(p, mwPlace_CLOSING);

  if(p->channel) {
    ret = mwChannel_destroy(p->channel, code, NULL);
    p->channel = NULL;
  }

  place_free(p);

  return ret;
}
Ejemplo n.º 7
0
static void recv_channelCreate(struct mwServiceFileTransfer *srvc,
			       struct mwChannel *chan,
			       struct mwMsgChannelCreate *msg) {

  struct mwFileTransferHandler *handler;
  struct mwGetBuffer *b;

  char *fnm, *txt;
  guint32 size, junk;
  gboolean b_err;

  g_return_if_fail(srvc->handler != NULL);
  handler = srvc->handler;
  
  b = mwGetBuffer_wrap(&msg->addtl);

  guint32_get(b, &junk); /* unknown */
  mwString_get(b, &fnm); /* offered filename */
  mwString_get(b, &txt); /* offering message */
  guint32_get(b, &size); /* size of offered file */
  /// Miranda NG adaptation - start - http://www.lilotux.net/~mikael/pub/meanwhile/ft_fix.diff
  /* guint32_get(b, &junk); */ /* unknown */
  /// Miranda NG adaptation - end
  /* and we just skip an unknown guint16 at the end */

  b_err = mwGetBuffer_error(b);
  mwGetBuffer_free(b);

  if(b_err) {
    g_warning("bad/malformed addtl in File Transfer service");
    mwChannel_destroy(chan, ERR_FAILURE, NULL);

  } else {
    struct mwIdBlock idb;
    struct mwFileTransfer *ft;

    login_into_id(&idb, mwChannel_getUser(chan));
    ft = mwFileTransfer_new(srvc, &idb, txt, fnm, size);
    ft->channel = chan;
    ft_state(ft, mwFileTransfer_PENDING);

    mwChannel_setServiceData(chan, ft, NULL);

    if(handler->ft_offered)
      handler->ft_offered(ft);
  }

  g_free(fnm);
  g_free(txt);
}
Ejemplo n.º 8
0
static void recv_accept(struct mwServiceDirectory *srvc,
			struct mwChannel *chan,
			struct mwMsgChannelAccept *msg) {

  g_return_if_fail(srvc->channel != NULL);
  g_return_if_fail(srvc->channel == chan);

  if(MW_SERVICE_IS_STARTING(srvc)) {
    mwService_started(MW_SERVICE(srvc));
      
  } else {
    mwChannel_destroy(chan, ERR_FAILURE, NULL);
  }
}
Ejemplo n.º 9
0
void mwService_recvCreate(struct mwService *s, struct mwChannel *chan,
			  struct mwMsgChannelCreate *msg) {

  /* ensure none are null, ensure that the service and channel belong
     to the same session, and ensure that the message belongs on the
     channel */
  g_return_if_fail(s != NULL);
  g_return_if_fail(chan != NULL);
  g_return_if_fail(msg != NULL);
  g_return_if_fail(s->session == mwChannel_getSession(chan));
  g_return_if_fail(mwChannel_getId(chan) == msg->channel);

  if(s->recv_create) {
    s->recv_create(s, chan, msg);
  } else {
    mwChannel_destroy(chan, ERR_FAILURE, NULL);
  }
}
Ejemplo n.º 10
0
static void stop(struct mwService *srvc) {

  struct mwServiceStorage *srvc_store;
  GList *l;

  g_return_if_fail(srvc != NULL);
  srvc_store = (struct mwServiceStorage *) srvc;

  if(srvc_store->channel) {
    mwChannel_destroy(srvc_store->channel, ERR_SUCCESS, NULL);
    srvc_store->channel = NULL;
  }

#if 1
  /* the new way */
  /* remove pending requests. Sometimes we can crash the storage
     service, and when that happens, we end up resending the killer
     request over and over again, and the service never stays up */
  for(l = srvc_store->pending; l; l = l->next)
    request_free(l->data);

  g_list_free(srvc_store->pending);
  srvc_store->pending = NULL;

  srvc_store->id_counter = 0;

#else
  /* the old way */
  /* reset all of the started requests to their unstarted states */
  for(l = srvc_store->pending; l; l = l->next) {
    struct mwStorageReq *req = l->data;

    if(req->action == action_loaded) {
      req->action = action_load;
    } else if(req->action == action_saved) {
      req->action = action_save;
    }
  }
#endif

  mwService_stopped(srvc);
}
Ejemplo n.º 11
0
void mwFileTransfer_free(struct mwFileTransfer *ft) {
  struct mwServiceFileTransfer *srvc;

  if(! ft) return;

  srvc = ft->service;
  if(srvc)
    srvc->transfers = g_list_remove(srvc->transfers, ft);

  if(ft->channel) {
    mwChannel_destroy(ft->channel, mwFileTransfer_SUCCESS, NULL);
    ft->channel = NULL;
  }

  mwFileTransfer_removeClientData(ft);

  mwIdBlock_clear(&ft->who);
  g_free(ft->filename);
  g_free(ft->message);
  g_free(ft);
}
Ejemplo n.º 12
0
static void recv_accept(struct mwServiceAware *srvc,
			struct mwChannel *chan,
			struct mwMsgChannelAccept *msg) {

  g_return_if_fail(srvc->channel != NULL);
  g_return_if_fail(srvc->channel == chan);

  if(MW_SERVICE_IS_STARTING(MW_SERVICE(srvc))) {
    GList *list = NULL;

    list = map_collect_values(srvc->entries);
    send_add(chan, list);
    g_list_free(list);

    send_attrib_list(srvc);

    mwService_started(MW_SERVICE(srvc));

  } else {
    mwChannel_destroy(chan, ERR_FAILURE, NULL);
  }
}
Ejemplo n.º 13
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);
  }
}