static void destroy(struct conduit *conduit)
{
    struct data *data;
    
    data = conduit->cdata;
    if(data->gdkread != -1)
	gdk_input_remove(data->gdkread);
    if(data->gdkwrite != -1)
	gdk_input_remove(data->gdkwrite);
    if(data->fd >= 0)
	dc_disconnect();
    if(inuse == conduit)
	inuse = NULL;
    free(data);
}
static void logincb(int err, wchar_t *reason, struct conduit *conduit)
{
    struct data *data;
    
    data = conduit->cdata;
    if(err != DC_LOGIN_ERR_SUCCESS)
    {
	dc_disconnect();
	disconnected(conduit);
	return;
    }
    condconnected(conduit);
    dc_gettrlistasync((void (*)(int, void *))trlistcb, conduit);
    dc_queuecmd(NULL, NULL, L"notify", L"trans:act", L"on", L"trans:prog", L"on", NULL);
}
Exemple #3
0
static void
timeout_during_auth(int signum)
{
    dc_disconnect();
}
Exemple #4
0
void
manage_request()
{
    ntlmhdr *fast_header;
    char buf[BUFFER_SIZE];
    const char *ch;
    char *ch2, *decoded, *cred = NULL;
    int plen;

    if (fgets(buf, BUFFER_SIZE, stdin) == NULL) {
        fprintf(stderr, "fgets() failed! dying..... errno=%d (%s)\n", errno,
                strerror(errno));
        exit(1);		/* BIIG buffer */
    }
    debug("managing request\n");
    ch2 = memchr(buf, '\n', BUFFER_SIZE);	/* safer against overrun than strchr */
    if (ch2) {
        *ch2 = '\0';		/* terminate the string at newline. */
        ch = ch2;
    }
    debug("ntlm authenticator. Got '%s' from Squid\n", buf);

    if (memcmp(buf, "KK ", 3) == 0) {	/* authenticate-request */
        /* figure out what we got */
        decoded = base64_decode(buf + 3);
        /* Note: we don't need to manage memory at this point, since
         *  base64_decode returns a pointer to static storage.
         */

        if (!decoded) {		/* decoding failure, return error */
            SEND("NA Packet format error, couldn't base64-decode");
            return;
        }
        /* fast-track-decode request type. */
        fast_header = (struct _ntlmhdr *) decoded;

        /* sanity-check: it IS a NTLMSSP packet, isn't it? */
        if (memcmp(fast_header->signature, "NTLMSSP", 8) != 0) {
            SEND("NA Broken authentication packet");
            return;
        }
        switch (le32toh(fast_header->type)) {
        case NTLM_NEGOTIATE:
            SEND("NA Invalid negotiation request received");
            return;
            /* notreached */
        case NTLM_CHALLENGE:
            SEND("NA Got a challenge. We refuse to have our authority disputed");
            return;
            /* notreached */
        case NTLM_AUTHENTICATE:
            /* check against the DC */
            plen = strlen(buf) * 3 / 4;		/* we only need it here. Optimization */
            signal(SIGALRM, timeout_during_auth);
            alarm(30);
            cred = ntlm_check_auth((ntlm_authenticate *) decoded, plen);
            alarm(0);
            signal(SIGALRM, SIG_DFL);
            if (got_timeout != 0) {
                fprintf(stderr, "ntlm-auth[%ld]: Timeout during authentication.\n", (long)getpid());
                SEND("BH Timeout during authentication");
                got_timeout = 0;
                return;
            }
            if (cred == NULL) {
                int smblib_err, smb_errorclass, smb_errorcode, nb_error;
                if (ntlm_errno == NTLM_LOGON_ERROR) {	/* hackish */
                    SEND("NA Logon Failure");
                    return;
                }
                /* there was an error. We have two errno's to look at.
                 * libntlmssp's erno is insufficient, we'll have to look at
                 * the actual SMB library error codes, to acually figure
                 * out what's happening. The thing has braindamaged interfacess..*/
                smblib_err = SMB_Get_Last_Error();
                smb_errorclass = SMBlib_Error_Class(SMB_Get_Last_SMB_Err());
                smb_errorcode = SMBlib_Error_Code(SMB_Get_Last_SMB_Err());
                nb_error = RFCNB_Get_Last_Error();
                debug("No creds. SMBlib error %d, SMB error class %d, SMB error code %d, NB error %d\n",
                      smblib_err, smb_errorclass, smb_errorcode, nb_error);
                /* Should I use smblib_err? Actually it seems I can do as well
                 * without it.. */
                if (nb_error != 0) {	/* netbios-level error */
                    send_bh_or_ld("NetBios error!",
                                  (ntlm_authenticate *) decoded, plen);
                    fprintf(stderr, "NetBios error code %d (%s)\n", nb_error,
                            RFCNB_Error_Strings[abs(nb_error)]);
                    return;
                }
                switch (smb_errorclass) {
                case SMBC_SUCCESS:
                    debug("Huh? Got a SMB success code but could check auth..");
                    SEND("NA Authentication failed");
                    /*
                     * send_bh_or_ld("SMB success, but no creds. Internal error?",
                     * (ntlm_authenticate *) decoded, plen);
                     */
                    return;
                case SMBC_ERRDOS:
                    /*this is the most important one for errors */
                    debug("DOS error\n");
                    switch (smb_errorcode) {
                        /* two categories matter to us: those which could be
                         * server errors, and those which are auth errors */
                    case SMBD_noaccess:	/* 5 */
                        SEND("NA Access denied");
                        return;
                    case SMBD_badformat:
                        SEND("NA bad format in authentication packet");
                        return;
                    case SMBD_badaccess:
                        SEND("NA Bad access request");
                        return;
                    case SMBD_baddata:
                        SEND("NA Bad Data");
                        return;
                    default:
                        send_bh_or_ld("DOS Error",
                                      (ntlm_authenticate *) decoded, plen);
                        return;
                    }
                case SMBC_ERRSRV:	/* server errors */
                    debug("Server error");
                    switch (smb_errorcode) {
                        /* mostly same as above */
                    case SMBV_badpw:
                        SEND("NA Bad password");
                        return;
                    case SMBV_access:
                        SEND("NA Server access error");
                        return;
                    default:
                        send_bh_or_ld("Server Error",
                                      (ntlm_authenticate *) decoded, plen);
                        return;
                    }
                case SMBC_ERRHRD:	/* hardware errors don't really matter */
                    send_bh_or_ld("Domain Controller Hardware error",
                                  (ntlm_authenticate *) decoded, plen);
                    return;
                case SMBC_ERRCMD:
                    send_bh_or_ld("Domain Controller Command Error",
                                  (ntlm_authenticate *) decoded, plen);
                    return;
                }
                SEND("BH unknown internal error.");
                return;
            }

            lc(cred);		/* let's lowercase them for our convenience */
            SEND2("AF %s", cred);
            return;
        default:
            SEND("BH unknown authentication packet type");
            return;
        }


        return;
    }
    if (memcmp(buf, "YR", 2) == 0) {	/* refresh-request */
        dc_disconnect();
        ch = obtain_challenge();
        /* Robert says we can afford to wait forever. I'll trust him on this
         * one */
        while (ch == NULL) {
            sleep(30);
            ch = obtain_challenge();
        }
        SEND2("TT %s", ch);
        return;
    }
    SEND("BH Helper detected protocol error");
    return;
    /********* END ********/


}
static void dcfdcb(struct conduit *conduit, int fd, GdkInputCondition condition)
{
    struct data *data;
    struct dc_response *resp;
    struct dc_intresp *ires;
    struct dc_transfer *dt;
    struct dtdata *dtd;
    
    data = conduit->cdata;
    if(((condition & GDK_INPUT_READ) && dc_handleread()) || ((condition & GDK_INPUT_WRITE) && dc_handlewrite()))
    {
	disconnected(conduit);
	return;
    }
    while((resp = dc_getresp()) != NULL)
    {
	if(!wcscmp(resp->cmdname, L".connect"))
	{
	    if(dc_checkprotocol(resp, DC_LATEST))
	    {
		dc_disconnect();
		disconnected(conduit);
	    } else {
		dc_loginasync(NULL, 1, noconv, (void (*)(int, wchar_t *, void *))logincb, conduit);
	    }
	} else if(!wcscmp(resp->cmdname, L".notify")) {
	    dc_uimisc_handlenotify(resp);
	    switch(resp->code)
	    {
	    case 610:
		if((ires = dc_interpret(resp)) != NULL)
		{
		    if((dt = dc_findtransfer(ires->argv[0].val.num)) != NULL)
		    {
			if(dt->dir == DC_TRNSD_DOWN)
			    inittrans(conduit, dt);
		    }
		    dc_freeires(ires);
		}
		break;
	    case 613:
		if((ires = dc_interpret(resp)) != NULL)
		{
		    if((dt = dc_findtransfer(ires->argv[0].val.num)) != NULL)
		    {
			if(((dtd = dt->udata) != NULL) && (dtd->ct != NULL))
			{
			    if(dtd->ct->size != dt->size)
				transfersetsize(dtd->ct, dt->size);
			}
		    }
		    dc_freeires(ires);
		}
		break;
	    case 615:
		if((ires = dc_interpret(resp)) != NULL)
		{
		    if((dt = dc_findtransfer(ires->argv[0].val.num)) != NULL)
		    {
			if(((dtd = dt->udata) != NULL) && (dtd->ct != NULL))
			{
			    if(dtd->ct->pos != dt->curpos)
				transfersetpos(dtd->ct, dt->curpos);
			}
		    }
		    dc_freeires(ires);
		}
		break;
	    }
	}
	dc_freeresp(resp);
    }
    updatewrite(conduit);
}