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; }
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); }
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); } }
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; }