Example #1
0
void
_iris_progress_monitor_handle_message (IrisMessage  *message,
                                       gpointer      user_data)
{
	IrisProgressWatch            *watch = user_data;
	IrisProgressMonitor          *progress_monitor = watch->monitor;
	IrisProgressMonitorInterface *iface;

	if (watch->cancelled || watch->complete)
		if (message->what != IRIS_PROGRESS_MESSAGE_TITLE)
			g_warning ("IrisProgressMonitor: watch %lx sent a progress message "
			           "after already sending %s.\n",
			           (gulong)watch,
			           watch->cancelled? "CANCELLED": "COMPLETE");

	g_return_if_fail (IRIS_IS_PROGRESS_MONITOR (progress_monitor));

	/* Any of these messages indicate that the connections cannot now change. Note that for
	 * watch->chain_flag to be TRUE if watch->task is not of type IrisProcess is an error. 
	 * Normally you must be aware that watch->task could be an IrisTask.
	 */
	if (watch->chain_flag) {
		watch->chain_flag = FALSE;
		watch_chain (progress_monitor, IRIS_PROCESS (watch->task));
	}

	switch (message->what) {
		case IRIS_PROGRESS_MESSAGE_CANCELLED:
			handle_cancelled (watch, message);
			break;
		case IRIS_PROGRESS_MESSAGE_COMPLETE:
			handle_complete (watch, message);
			break;
		case IRIS_PROGRESS_MESSAGE_PULSE:
			break;
		case IRIS_PROGRESS_MESSAGE_FRACTION:
			handle_fraction (watch, message);
			break;
		case IRIS_PROGRESS_MESSAGE_PROCESSED_ITEMS:
			handle_processed_items (watch, message);
			break;
		case IRIS_PROGRESS_MESSAGE_TOTAL_ITEMS:
			handle_total_items (watch, message);
			break;
		case IRIS_PROGRESS_MESSAGE_TITLE:
			handle_title (watch, message);
			break;
		default:
			g_warn_if_reached ();
	}

	/* Chain the message to implementation, after we have processed what we need */
	iface = IRIS_PROGRESS_MONITOR_GET_INTERFACE (progress_monitor);
	iface->handle_message (progress_monitor, watch, message);
}
Example #2
0
/**
 * Check an announce phase message and pass to appropriate message handler,
 * decrypting first if necessary
 * Returns 1 on success, 0 on error
 */
int handle_announce_phase(const unsigned char *packet, unsigned char *decrypted,
                          const struct sockaddr_in *receiver,
                          struct finfo_t *finfo,
                          int announce, int open, int regconf)
{
    struct uftp_h *header;
    const unsigned char *message;
    int hostidx;
    unsigned decryptlen, meslen;
    uint8_t *func;
    struct in_addr srcaddr;

    header = (struct uftp_h *)packet;
    hostidx = find_client(header->srcaddr);
    if (header->srcaddr == 0) {
        srcaddr = receiver->sin_addr;
    } else {
        srcaddr.s_addr = header->srcaddr;
    }
    if ((keytype != KEY_NONE) && (header->func == ENCRYPTED)) {
        if (hostidx == -1) {
            log(0, 0, "Got encrypted packet from unknown receiver %s",
                       inet_ntoa(srcaddr));
            return 0;
        }
        if (!validate_and_decrypt(packet, &decrypted, &decryptlen, mtu,
                keytype, groupkey, groupsalt, ivlen, hashtype, grouphmackey,
                hmaclen, sigtype, destlist[hostidx].encinfo->pubkey,
                destlist[hostidx].encinfo->pubkeylen)) {
            log1(0, 0, "Rejecting message from %s: decrypt/validate failed",
                        destlist[hostidx].name);
            return 0;
        }
        func = (uint8_t *)decrypted;
        message = decrypted;
        meslen = decryptlen;
    } else {
        if ((keytype != KEY_NONE) && (header->func == INFO_ACK)) {
            log1(0, 0, "Rejecting %s message from %s: not encrypted",
                       func_name(header->func), inet_ntoa(srcaddr));
            return 0;
        }
        func = (uint8_t *)&header->func;
        message = packet + sizeof(struct uftp_h);
        meslen = ntohs(header->blsize);
    }

    if (*func == ABORT) {
        handle_abort(message, meslen, hostidx, finfo, &srcaddr);
        return 1;
    }

    if (hostidx == -1) {
        if (open) {
            if (*func == REGISTER) {
                handle_open_register(message, meslen, finfo, receiver,
                                     &srcaddr, regconf);
            } else if (*func == CLIENT_KEY) {
                handle_open_clientkey(message, meslen, finfo, receiver,
                                      &srcaddr);
            } else {
                log1(0, 0, "Invalid function: expected "
                           "REGISTER or CLIENT_KEY, got %s", func_name(*func));
            }
        } else {
            log1(0, 0, "Host %s not in host list", inet_ntoa(srcaddr));
            send_abort(finfo, "Not in host list", receiver, &srcaddr, 0, 0);
        }
    } else {
        switch (destlist[hostidx].status) {
        case DEST_MUTE:
            if (*func == REGISTER) {
                handle_register(message, meslen, finfo, receiver,
                                &srcaddr, hostidx, regconf, open);
            } else if (*func == CLIENT_KEY) {
                handle_clientkey(message, meslen, finfo, receiver,
                                 &srcaddr, hostidx);
            } else {
                log1(0, 0, "Invalid function: expected "
                           "REGISTER or CLIENT_KEY, got %s", func_name(*func));
            }
            break;
        case DEST_REGISTERED:
            if (*func == INFO_ACK) {
                handle_info_ack(message, meslen, finfo, receiver,
                                &srcaddr, hostidx, announce);
            } else if (*func == REGISTER) {
                handle_register(message, meslen, finfo, receiver,
                                &srcaddr, hostidx, regconf, open);
            } else if (*func == CLIENT_KEY) {
                log(0, 0, "Received CLIENT_KEY+ from %s",
                           destlist[hostidx].name);
            } else if (!announce && (*func == COMPLETE)) {
                handle_complete(message, meslen, finfo, hostidx);
            } else {
                log1(0, 0, "Received invalid message %s from %s",
                            func_name(*func), destlist[hostidx].name);
            }
            break;
        case DEST_ACTIVE:
            if (*func == REGISTER) {
                handle_register(message, meslen, finfo, receiver,
                                &srcaddr, hostidx, regconf, open);
            } else if (*func == CLIENT_KEY) {
                log(0, 0, "Received CLIENT_KEY+ from %s",
                           destlist[hostidx].name);
            } else if (*func == INFO_ACK) {
                finfo->deststate[hostidx].conf_sent = 0;
                handle_info_ack(message, meslen, finfo, receiver,
                                &srcaddr, hostidx, announce);
            } else if (!announce && (*func == COMPLETE)) {
                handle_complete(message, meslen, finfo, hostidx);
            } else {
                log1(0, 0, "Received invalid message %s from %s",
                            func_name(*func), destlist[hostidx].name);
            }
            break;
        default:
            log1(0, 0, "Received invalid message %s from %s",
                      func_name(*func), destlist[hostidx].name);
            break;
        }
    }

    return 1;
}
Example #3
0
/**
 * Check a transfer phase message and pass to appropriate message handler,
 * decrypting first if necessary
 * Returns 1 on success, 0 on error
 */
int handle_transfer_phase(const unsigned char *packet, unsigned char *decrypted,
                          const struct sockaddr_in *receiver,
                          int blocks_this_sec, int section_offset,
                          int pass, int section, struct finfo_t *finfo)
{
    struct uftp_h *header;
    const unsigned char *message;
    int hostidx;
    unsigned int decryptlen, meslen;
    uint8_t *func;
    struct in_addr srcaddr;

    header = (struct uftp_h *)packet;
    hostidx = find_client(header->srcaddr);
    srcaddr.s_addr = header->srcaddr;
    if ((keytype != KEY_NONE) && (header->func == ENCRYPTED)) {
        if (hostidx == -1) {
            log1(0, 0, "Host %s not in host list", inet_ntoa(srcaddr));
            send_abort(finfo, "Not in host list", receiver, &srcaddr, 0, 0);
            return 0;
        }
        if (!validate_and_decrypt(packet, &decrypted, &decryptlen, mtu,
                keytype, groupkey, groupsalt, ivlen, hashtype, grouphmackey,
                hmaclen, sigtype, destlist[hostidx].encinfo->pubkey,
                destlist[hostidx].encinfo->pubkeylen)) {
            log1(0, 0, "Rejecting message from %s: decrypt/validate failed",
                        destlist[hostidx].name);
            return 0;
        }
        func = (uint8_t *)decrypted;
        message = decrypted;
        meslen = decryptlen;
    } else {
        if ((keytype != KEY_NONE) && ((header->func == PRSTATUS) ||
                (header->func == STATUS) || (header->func == COMPLETE) ||
                (header->func == ABORT))) {
            log1(0, 0, "Rejecting %s message from %s: not encrypted",
                       func_name(header->func), inet_ntoa(srcaddr));
            return 0;
        }
        func = (uint8_t *)&header->func;
        message = packet + sizeof(struct uftp_h);
        meslen = ntohs(header->blsize);
    }

    if (*func == ABORT) {
        handle_abort(message, meslen, hostidx, finfo, &srcaddr);
    } else if (hostidx == -1) {
        log1(0, 0, "Host %s not in host list", inet_ntoa(srcaddr));
        send_abort(finfo, "Not in host list", receiver, &srcaddr, 0, 0);
    } else {
        switch (destlist[hostidx].status) {
        case DEST_ACTIVE:
            if (*func == STATUS) {
                handle_status(message, meslen, finfo, hostidx,
                        blocks_this_sec, section_offset, pass, section);
            } else if (*func == COMPLETE) {
                handle_complete(message, meslen, finfo, hostidx);
            } else if ((destlist[hostidx].clientcnt != -1) &&
                       (*func == PRSTATUS)) {
                handle_prstatus(message, meslen, finfo, hostidx,
                        blocks_this_sec, section_offset, pass, section);
            } else {
                log1(0, 0, "Received invalid message %s from %s",
                           func_name(*func), destlist[hostidx].name);
            }
            break;
        case DEST_STATUS:
            if (*func == COMPLETE) {
                handle_complete(message, meslen, finfo, hostidx);
            } else if (*func == STATUS) {
                handle_status(message, meslen, finfo, hostidx,
                              blocks_this_sec, section_offset, pass, section);
            } else {
                log1(0, 0, "Received invalid message %s from %s",
                           func_name(*func), destlist[hostidx].name);
            }
            break;
        case DEST_DONE:
            if (*func == COMPLETE) {
                handle_complete(message, meslen, finfo, hostidx);
            } else {
                log1(0, 0, "Received invalid message %s from %s",
                           func_name(*func), destlist[hostidx].name);
            }
            break;
        }
    }
    return 1;
}
Example #4
0
/**
 * This is the main message reading loop.  Messages are read, validated,
 * decrypted if necessary, then passed to the appropriate routine for handling.
 */
void mainloop()
{
    struct uftp_h *header;
    unsigned char *buf, *decrypted, *message;
    int packetlen, listidx, hostidx, i;
    unsigned int decryptlen, meslen;
    uint8_t *func;
    struct sockaddr_in src;
    struct in_addr srcaddr;
    struct timeval *tv;
    const int bsize = 9000;  // Roughly size of ethernet jumbo frame

    log0(0, 0, "%s", VERSIONSTR);
    for (i = 0; i < key_count; i++) {
        log(0, 0, "Loaded key with fingerprint %s",
                  print_key_fingerprint(privkey[i]));
    }

    buf = calloc(bsize, 1);
    decrypted = calloc(bsize, 1);
    if ((buf == NULL) || (decrypted == NULL)) {
        syserror(0, 0, "calloc failed!");
        exit(1);
    }
    header = (struct uftp_h *)buf;

    while (1) {
        tv = getrecenttimeout();
        if (read_packet(listener, &src, buf, &packetlen,
                        bsize, tv) <= 0) {
            continue;
        }

        if ((header->uftp_id != UFTP_VER_NUM) &&
                (header->uftp_id != UFTP_3_0_VER)) {
            log(0, 0, "Invalid message from %s: not uftp packet "
                      "or invalid version", inet_ntoa(src.sin_addr));
            continue;
        }
        if (packetlen != sizeof(struct uftp_h) + ntohs(header->blsize)) {
            log(0, 0, "Invalid packet size from %s: got %d, expected %d",
                      inet_ntoa(src.sin_addr), packetlen,
                      sizeof(struct uftp_h) + ntohs(header->blsize));
            continue;
        }

        if ((src.sin_addr.s_addr == out_addr.s_addr) &&
                (src.sin_port == htons(port))) {
            // Packet from self -- drop
            continue;
        }
        if (header->func == HB_REQ) {
            handle_hb_request(&src, buf);
            continue;
        }
        if (header->func == HB_RESP) {
            handle_hb_response(listener, &src, buf, hb_hosts, hbhost_count,
                               noname, privkey[0]);
            continue;
        }
        if (header->func == KEY_REQ) {
            handle_key_req(&src, buf);
            continue;
        }
        if (header->func == PROXY_KEY) {
            // Only clients handle these, so drop
            continue;
        }
        if ((proxy_type == SERVER_PROXY) &&
                (down_addr.sin_addr.s_addr == INADDR_ANY)) {
            log(0, 0, "Rejecting message from %s: downstream address "
                      "not established", inet_ntoa(src.sin_addr));
            continue;
        }

        listidx = find_group(ntohl(header->group_id));
        if (header->func == ANNOUNCE) {
            handle_announce(listidx, &src, buf);
        } else {
            if (listidx == -1) {
                continue;
            }
            if (proxy_type == SERVER_PROXY) {
                // Server proxies don't do anything outside of an ANNOUNCE.
                // Just send it on through.
                forward_message(listidx, &src, buf);
                continue;
            }
            if (header->func == ABORT) {
                handle_abort(listidx, &src, buf);
                continue;
            }
            if (!memcmp(&src, &group_list[listidx].up_addr, sizeof(src))) {
                // Downstream message
                if (header->func == KEYINFO) {
                    handle_keyinfo(listidx, buf);
                } else if ((header->func == REG_CONF) &&
                           (group_list[listidx].keytype != KEY_NONE)) {
                    handle_regconf(listidx, buf);
                } else {
                    // If we don't need to process the message, don't bother
                    // decrypting anything.  Just forward it on.
                    forward_message(listidx, &src, buf);
                }
            } else {
                // Upstream message
                // Decrypt first if necessary
                hostidx = find_client(listidx, header->srcaddr);
                if ((hostidx != -1) && (header->func == ENCRYPTED) &&
                        (group_list[listidx].keytype != KEY_NONE)) {
                    if (!validate_and_decrypt(buf, &decrypted, &decryptlen,
                            group_list[listidx].mtu,group_list[listidx].keytype,
                            group_list[listidx].groupkey,
                            group_list[listidx].groupsalt,
                            group_list[listidx].ivlen,
                            group_list[listidx].hashtype,
                            group_list[listidx].grouphmackey,
                            group_list[listidx].hmaclen,
                            group_list[listidx].sigtype,
                            group_list[listidx].destinfo[hostidx].pubkey,
                            group_list[listidx].destinfo[hostidx].pubkeylen)) {
                        log(ntohl(header->group_id), 0, "Rejecting message "
                                "from %s: decrypt/validate failed",
                                inet_ntoa(src.sin_addr));
                        continue;
                    }
                    func = (uint8_t *)decrypted;
                    message = decrypted;
                    meslen = decryptlen;
                } else {
                    if ((hostidx != -1) &&
                            (group_list[listidx].keytype != KEY_NONE) &&
                            ((header->func == INFO_ACK) ||
                             (header->func == STATUS) ||
                             (header->func == COMPLETE))) {
                        log(ntohl(header->group_id), 0, "Rejecting %s message "
                                "from %s: not encrypted", 
                                func_name(header->func),
                                inet_ntoa(src.sin_addr));
                        continue;
                    }
                    func = (uint8_t *)&header->func;
                    message = buf + sizeof(struct uftp_h);
                    meslen = ntohs(header->blsize);
                }

                if ((hostidx == -1) && (header->srcaddr == 0)) {
                    srcaddr = src.sin_addr;
                } else {
                    srcaddr.s_addr = header->srcaddr;
                }
                switch (*func) {
                case REGISTER:
                    handle_register(listidx, hostidx, message, meslen,
                                    srcaddr.s_addr);
                    break;
                case CLIENT_KEY:
                    handle_clientkey(listidx, hostidx, message, meslen,
                                     srcaddr.s_addr);
                    break;
                case INFO_ACK:
                    handle_info_ack(listidx, hostidx, message, meslen);
                    break;
                case STATUS:
                    handle_status(listidx, hostidx, message, meslen);
                    break;
                case COMPLETE:
                    handle_complete(listidx, hostidx, message, meslen);
                    break;
                default:
                    forward_message(listidx, &src, buf);
                    break;
                }
            }
        }
    }
}