Ejemplo n.º 1
0
int mwChannel_destroy(struct mwChannel *chan,
		      guint32 reason, struct mwOpaque *info) {

  struct mwMsgChannelDestroy *msg;
  struct mwSession *session;
  struct mwChannelSet *cs;
  int ret;

  /* may make this not a warning in the future */
  g_return_val_if_fail(chan != NULL, 0);

  state(chan, reason? mwChannel_ERROR: mwChannel_DESTROY, reason);

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

  cs = mwSession_getChannels(session);
  g_return_val_if_fail(cs != NULL, -1);

  /* compose the message */
  msg = (struct mwMsgChannelDestroy *)
    mwMessage_new(mwMessage_CHANNEL_DESTROY);
  msg->head.channel = chan->id;
  msg->reason = reason;
  if(info) mwOpaque_clone(&msg->data, info);

  /* remove the channel from the channel set */
  g_hash_table_remove(cs->map, GUINT_TO_POINTER(chan->id));
  
  /* send the message */
  ret = mwSession_send(session, (struct mwMessage *) msg);
  mwMessage_free(MW_MESSAGE(msg));

  return ret;
}
Ejemplo n.º 2
0
static void mwMessageHead_clone(struct mwMessage *to,
				struct mwMessage *from) {

  to->type = from->type;
  to->options = from->options;
  to->channel = from->channel;
  mwOpaque_clone(&to->attribs, &from->attribs);
}
Ejemplo n.º 3
0
static void queue_incoming(struct mwChannel *chan,
			   struct mwMsgChannelSend *msg) {

  /* we clone the message, because session_process will clear it once
     we return */

  struct mwMsgChannelSend *m = g_new0(struct mwMsgChannelSend, 1);
  m->head.type = msg->head.type;
  m->head.options = msg->head.options;
  m->head.channel = msg->head.channel;
  mwOpaque_clone(&m->head.attribs, &msg->head.attribs);

  m->type = msg->type;
  mwOpaque_clone(&m->data, &msg->data);

  g_info("queue_incoming, channel 0x%08x", chan->id);
  chan->incoming_queue = g_slist_append(chan->incoming_queue, m);
}
Ejemplo n.º 4
0
struct mwStorageUnit *mwStorageUnit_newOpaque(guint32 key,
					      struct mwOpaque *data) {
  struct mwStorageUnit *u;

  u = g_new0(struct mwStorageUnit, 1);
  u->key = key;

  if(data)
    mwOpaque_clone(&u->data, data);

  return u;
}
Ejemplo n.º 5
0
/* send a channel create message */
int mwChannel_create(struct mwChannel *chan) {
  struct mwMsgChannelCreate *msg;
  GList *list, *l;
  int ret;

  g_return_val_if_fail(chan != NULL, -1);
  g_return_val_if_fail(chan->state == mwChannel_INIT, -1);
  g_return_val_if_fail(mwChannel_isOutgoing(chan), -1);

  msg = (struct mwMsgChannelCreate *)
    mwMessage_new(mwMessage_CHANNEL_CREATE);

  msg->channel = chan->id;
  msg->target.user = g_strdup(chan->user.user_id);
  msg->target.community = g_strdup(chan->user.community);
  msg->service = chan->service;
  msg->proto_type = chan->proto_type;
  msg->proto_ver = chan->proto_ver;
  msg->options = chan->options;
  mwOpaque_clone(&msg->addtl, &chan->addtl_create);

  list = mwChannel_getSupportedCipherInstances(chan);
  if(list) {
    /* offer what we have */
    for(l = list; l; l = l->next) {
      struct mwEncryptItem *ei = mwCipherInstance_offer(l->data);
      msg->encrypt.items = g_list_append(msg->encrypt.items, ei);
    }

    /* we're easy to get along with */
    chan->offered_policy = mwEncrypt_WHATEVER;
    g_list_free(list);

  } else {
    /* we apparently don't support anything */
    chan->offered_policy = mwEncrypt_NONE;
  }

  msg->encrypt.mode = chan->offered_policy;
  msg->encrypt.extra = chan->offered_policy;
  
  ret = mwSession_send(chan->session, MW_MESSAGE(msg));
  mwMessage_free(MW_MESSAGE(msg));

  state(chan, (ret)? mwChannel_ERROR: mwChannel_WAIT, ret);

  return ret;
}
Ejemplo n.º 6
0
static void channel_recv(struct mwChannel *chan,
			 struct mwMsgChannelSend *msg) {

  struct mwService *srvc;
  srvc = mwChannel_getService(chan);

  incr_stat(chan, mwChannelStat_MSG_RECV, 1);

  if(msg->head.options & mwMessageOption_ENCRYPT) {
    struct mwOpaque data = { 0, 0 };
    mwOpaque_clone(&data, &msg->data);

    mwCipherInstance_decrypt(chan->cipher, &data);
    mwService_recv(srvc, chan, msg->type, &data);
    mwOpaque_clear(&data);
    
  } else {
    mwService_recv(srvc, chan, msg->type, &msg->data);
  }
}
Ejemplo n.º 7
0
int mwChannel_sendEncrypted(struct mwChannel *chan,
			    guint32 type, struct mwOpaque *data,
			    gboolean encrypt) {

  struct mwMsgChannelSend *msg;

  g_return_val_if_fail(chan != NULL, -1);

  msg = (struct mwMsgChannelSend *) mwMessage_new(mwMessage_CHANNEL_SEND);
  msg->head.channel = chan->id;
  msg->type = type;

  mwOpaque_clone(&msg->data, data);

  if(encrypt && chan->cipher) {
    msg->head.options = mwMessageOption_ENCRYPT;
    mwCipherInstance_encrypt(chan->cipher, &msg->data);
  }

  return channel_send(chan, msg);  
}
Ejemplo n.º 8
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;
}