Example #1
0
atf_error_t
atf_fs_mkstemp(atf_fs_path_t *p, int *fdout)
{
    atf_error_t err;
    char *buf;
    int fd;

    if (!check_umask(S_IRWXU, S_IRWXU)) {
        err = invalid_umask_error(p, atf_fs_stat_reg_type, current_umask());
        goto out;
    }

    err = copy_contents(p, &buf);
    if (atf_is_error(err))
        goto out;

    err = do_mkstemp(buf, &fd);
    if (atf_is_error(err))
        goto out_buf;

    replace_contents(p, buf);
    *fdout = fd;

    INV(!atf_is_error(err));
out_buf:
    free(buf);
out:
    return err;
}
Example #2
0
void DocumentView::save(const unicode& path) {
    L_DEBUG("Saving file: " + path.encode());
    trim_trailing_newlines();
    trim_trailing_whitespace();

    Glib::ustring text = buffer()->get_text();

    if(file_->get_path() == path.encode()) {
        //FIXME: Use entity tag arguments to make sure that the file
        //didn't change since the last time we saved
        file_->replace_contents(std::string(text.c_str()), "", file_etag_);
        connect_file_monitor();
    } else {
        auto file = Gio::File::create_for_path(path.encode());
        if(!os::path::exists(path)) {
            file->create_file();
        }
        file->replace_contents(text, "", file_etag_);
        connect_file_monitor();
    }

    buffer()->set_modified(false);

    apply_settings(guess_mimetype()); //Make sure we update the settings when we've saved the file

    window_.rebuild_open_list();
    run_linters_and_stuff();
}
Example #3
0
atf_error_t
atf_fs_mkdtemp(atf_fs_path_t *p)
{
    atf_error_t err;
    char *buf = NULL;

    if (!check_umask(S_IRWXU, S_IRWXU)) {
        err = invalid_umask_error(p, atf_fs_stat_dir_type, current_umask());
        goto out;
    }

    err = copy_contents(p, &buf);
    if (atf_is_error(err))
        goto out;

    err = do_mkdtemp(buf);
    if (atf_is_error(err))
        goto out_buf;

    replace_contents(p, buf);

    INV(!atf_is_error(err));
out_buf:
    free(buf);
out:
    return err;
}
Example #4
0
/*
 * Mangle the "Transport:" header:
 *   - Replace all occurences of "client_port=<spec>"
 *   - Handle destination parameter
 *
 * In:
 *   ct, ctinfo = conntrack context
 *   skb        = packet
 *   tranoff    = Transport header offset from TCP data
 *   tranlen    = Transport header length (incl. CRLF)
 *   rport_lo   = replacement low  port (host endian)
 *   rport_hi   = replacement high port (host endian)
 *
 * Returns packet size difference.
 *
 * Assumes that a complete transport header is present, ending with CR or LF
 */
static int
rtsp_mangle_tran(enum ip_conntrack_info ctinfo,
                 struct nf_conntrack_expect* rtp_exp,
                 struct nf_conntrack_expect* rtcp_exp,
								 struct ip_ct_rtsp_expect* prtspexp,
                 struct sk_buff* skb, uint tranoff, uint tranlen)
{
    char*       ptcp;
    char*       ptcp_seq;
    uint        tcplen;
    char*       ptran;
    char        rbuf1[16];      /* Replacement buffer (one port) */
    uint        rbuf1len;       /* Replacement len (one port) */
    char        rbufa[16];      /* Replacement buffer (all ports) */
    uint        rbufalen;       /* Replacement len (all ports) */
    u_int32_t   newip;
    u_int16_t   loport, hiport;
    uint        off = 0;
    uint        diff;           /* Number of bytes we removed */

int diff_len = 0;

#define MAX_RTSP_MANGLE_BUFFER 1400
char mangle_buffer[MAX_RTSP_MANGLE_BUFFER];
uint len_old = 0, len_new = 0;

    struct nf_conn *ct = rtp_exp->master;
    struct nf_conntrack_tuple *t_rtp, *t_rtcp;

    char    szextaddr[15+1];
    uint    extaddrlen;
    int     is_stun;

#if 1 /* patch ...*/
    ptcp = mangle_buffer;
    memset(ptcp, 0, MAX_RTSP_MANGLE_BUFFER);
    get_skb_tcpdata(skb, &ptcp_seq, &tcplen);
    memcpy(mangle_buffer, ptcp_seq, tcplen);
#else
    get_skb_tcpdata(skb, &ptcp, &tcplen);
#endif
    ptran = ptcp+tranoff;

    if (tranoff+tranlen > tcplen || tcplen-tranoff < tranlen ||
        tranlen < 10 || !iseol(ptran[tranlen-1]) ||
        nf_strncasecmp(ptran, "Transport:", 10) != 0)
    {
        pr_info("sanity check failed\n");
        return 0;
    }
    off += 10;
    SKIP_WSPACE(ptcp+tranoff, tranlen, off);

    newip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip;

#ifdef CONFIG_NF_NAT_NEEDED
    rtp_exp->saved_proto.udp.port = rtp_exp->tuple.dst.u.udp.port;
    rtcp_exp->saved_proto.udp.port = rtcp_exp->tuple.dst.u.udp.port;
#endif

    t_rtp = &rtp_exp->tuple;
    t_rtcp = &rtcp_exp->tuple;

    t_rtp->dst.u3.ip = newip;
    t_rtcp->dst.u3.ip = newip;

    //extaddrlen = extip ? sprintf(szextaddr, "%pI4", &extip)
    //                   : sprintf(szextaddr, "%pI4", &newip);

    extaddrlen = extip ? sprintf(szextaddr, "%u.%u.%u.%u", NIPQUAD(extip))
                       : sprintf(szextaddr, "%u.%u.%u.%u", NIPQUAD(newip));
    pr_debug("stunaddr=%s (%s)\n", szextaddr, (extip?"forced":"auto"));

    rbuf1len = rbufalen = 0;
    switch (prtspexp->pbtype)
    {
    case pb_single:
        for (loport = prtspexp->loport; loport != 0; loport++) /* XXX: improper wrap? */
        {
            t_rtp->dst.u.udp.port = htons(loport);
            if (nf_ct_expect_related(rtp_exp) == 0)
            {
                printk("using port %hu\n", loport);
                break;
            }
        }
        if (loport != 0)
        {
            rbuf1len = sprintf(rbuf1, "%hu", loport);
            rbufalen = sprintf(rbufa, "%hu", loport);
        }
        break;
    case pb_range:
        for (loport = prtspexp->loport; loport != 0; loport += 2) /* XXX: improper wrap? */
        {
            t_rtp->dst.u.udp.port = htons(loport);
            if (nf_ct_expect_related(rtp_exp) == 0)
            {
                t_rtcp->dst.u.udp.port = htons(loport+1);
                if (nf_ct_expect_related(rtcp_exp) == 0)
                {
                    hiport = loport+1;
                    pr_debug("using ports %d-%d\n", loport, loport+1);
                }
                else
                {
                    hiport = 0;
                }
                break;
            }
        }
        if (loport != 0 && hiport != 0)
        {
            rbuf1len = sprintf(rbuf1, "%hu", loport);
            rbufalen = sprintf(rbufa, "%hu-%hu", loport, hiport);
        }
        break;
    case pb_discon:
        for (loport = prtspexp->loport; loport != 0; loport++) /* XXX: improper wrap? */
        {
            t_rtp->dst.u.udp.port = htons(loport);
            if (nf_ct_expect_related(rtp_exp) == 0)
            {
                pr_debug("using port %hu (1 of 2)\n", loport);
                break;
            }
        }
        for (hiport = prtspexp->hiport; hiport != 0; hiport++) /* XXX: improper wrap? */
        {
            t_rtcp->dst.u.udp.port = htons(hiport);
            if (nf_ct_expect_related(rtcp_exp) == 0)
            {
                pr_debug("using port %hu (2 of 2)\n", hiport);
                break;
            }
        }
        if (loport != 0 && hiport != 0)
        {
            rbuf1len = sprintf(rbuf1, "%hu", loport);
            if (hiport == loport+1)
            {
                rbufalen = sprintf(rbufa, "%hu-%hu", loport, hiport);
            }
            else
            {
                rbufalen = sprintf(rbufa, "%hu/%hu", loport, hiport);
            }
        }
        break;
    }

    if (rbuf1len == 0)
    {
        return 0;   /* cannot get replacement port(s) */
    }

    /* Transport: tran;field;field=val,tran;field;field=val,... */
    while (off < tranlen)
    {
        uint        saveoff;
        const char* pparamend;
        uint        nextparamoff;

        pparamend = memchr(ptran+off, ',', tranlen-off);
        pparamend = (pparamend == NULL) ? ptran+tranlen : pparamend+1;
        //nextparamoff = pparamend-ptcp;
nextparamoff = pparamend-ptran;
        /*
         * We pass over each param twice.  On the first pass, we look for a
         * destination= field.  It is handled by the security policy.  If it
         * is present, allowed, and equal to our external address, we assume
         * that STUN is being used and we leave the client_port= field alone.
         */
        is_stun = 0;
        saveoff = off;
        while (off < nextparamoff)
        {
            const char* pfieldend;
            uint        nextfieldoff;
            uint        replen;

            pfieldend = memchr(ptran+off, ';', nextparamoff-off);
            nextfieldoff = (pfieldend == NULL) ? nextparamoff : pfieldend-ptran+1;

            if (dstact != DSTACT_NONE && strncmp(ptran+off, "destination=", 12) == 0)
            {
                if (strncmp(ptran+off+12, szextaddr, extaddrlen) == 0)
                {
                    is_stun = 1;
                }
                if (dstact == DSTACT_STRIP || (dstact == DSTACT_AUTO && !is_stun))
                {
                    off += 12;
                    replen = (pfieldend == NULL) ? nextfieldoff-off : nextfieldoff-off-1;
                    diff = replen - extaddrlen;

#if 1
		    if( replace_contents(ptran+off, replen, szextaddr, extaddrlen, tcplen-off-(ptran-ptcp)) == 0) 
                    {
                        // mangle failed, all we can do is bail 
			nf_ct_unexpect_related(rtp_exp);
			nf_ct_unexpect_related(rtcp_exp);
                        return 0;
                    }

		    tcplen = tcplen + extaddrlen - replen;
		    diff_len = diff_len + extaddrlen - replen;

#else

                    if (!nf_nat_mangle_tcp_packet(skb, ct, ctinfo,
                                                         off, diff, NULL, 0))
                    {
                        // mangle failed, all we can do is bail 
			nf_ct_unexpect_related(rtp_exp);
			nf_ct_unexpect_related(rtcp_exp);
                        return 0;
                    }
#endif
#if 0
                    get_skb_tcpdata(skb, &ptcp, &tcplen);
#endif
                    ptran = ptcp+tranoff;
                    tranlen -= diff;
                    nextparamoff -= diff;
                    nextfieldoff -= diff;
                }
            }

            off = nextfieldoff;
        }
        if (is_stun)
        {
            continue;
        }
        off = saveoff;
        while (off < nextparamoff)
        {
            const char* pfieldend;
            uint        nextfieldoff;

            pfieldend = memchr(ptran+off, ';', nextparamoff-off);
            nextfieldoff = (pfieldend == NULL) ? nextparamoff : pfieldend-ptran+1;

            if (strncmp(ptran+off, "client_port=", 12) == 0)
            {
                u_int16_t   port;
                uint        numlen;
                uint        origoff;
                uint        origlen;
                char*       rbuf    = rbuf1;
                uint        rbuflen = rbuf1len;
                uint off1;

                off += 12;
                off1 = off;
                origoff = (ptran-ptcp)+off;
                origlen = 0;
                numlen = nf_strtou16(ptran+off, &port);
                off += numlen;
                origlen += numlen;
                if (port != prtspexp->loport)
                {
                    pr_debug("multiple ports found, port %hu ignored\n", port);
                }
                else
                {
                    if (ptran[off] == '-' || ptran[off] == '/')
                    {
                        off++;
                        origlen++;
                        numlen = nf_strtou16(ptran+off, &port);
                        off += numlen;
                        origlen += numlen;
                        rbuf = rbufa;
                        rbuflen = rbufalen;
                    }

                    /*
                     * note we cannot just memcpy() if the sizes are the same.
                     * the mangle function does skb resizing, checks for a
                     * cloned skb, and updates the checksums.
                     *
                     * parameter 4 below is offset from start of tcp data.
                     */
                    diff = origlen-rbuflen;
#if 1

		    if( replace_contents(ptran+off1, origlen, rbuf, rbuflen, tcplen-off1-(ptran-ptcp)) == 0) 
                    {
                        /* mangle failed, all we can do is bail */
			nf_ct_unexpect_related(rtp_exp);
			nf_ct_unexpect_related(rtcp_exp);
                        return 0;
                    }
		    tcplen = tcplen + rbuflen - origlen;
		    diff_len = diff_len + rbuflen - origlen;


#else
                    if (!nf_nat_mangle_tcp_packet(skb, ct, ctinfo,
                                              origoff, origlen, rbuf, rbuflen))
                    {
                        /* mangle failed, all we can do is bail */
			nf_ct_unexpect_related(rtp_exp);
			nf_ct_unexpect_related(rtcp_exp);
                        return 0;
                    }
#endif
#if 0
                    get_skb_tcpdata(skb, &ptcp, &tcplen);
#endif
                    ptran = ptcp+tranoff;
                    tranlen -= diff;
                    nextparamoff -= diff;
                    nextfieldoff -= diff;
                }
            }

            off = nextfieldoff;
        }

        off = nextparamoff;
    }

	if (!nf_nat_mangle_tcp_packet(skb, ct, ctinfo, 0, tcplen-diff_len, mangle_buffer, tcplen))
	{
		/* mangle failed, all we can do is bail */
		//DEBUGP(" mangle failed client_port\n");
		nf_ct_unexpect_related(rtp_exp);
			nf_ct_unexpect_related(rtcp_exp);
		return 0;
	}
    return 1;
}