2013-08-30 3 views
0

Из предыдущего вопроса here Я узнал, как использовать INDY SMTP (TIdSMTP) для отправки писем с учетной записью Office 365. Я также понял это для многих других, и он работает практически для любого распространенного поставщика электронной почты. Но я не могу понять, как использовать его с моим локальным сервером Exchange. Некоторое время назад были компоненты SASL-NTLM, поставляемые с indy, но, похоже, они были удалены. Мне нужно, чтобы NTLM подключался к локальному серверу Exchange. Но я не могу понять, как это сделать без NTLM.Использование INDY 10 с Exchange SMTP-сервером

+1

Какие конкретные задачи у вас есть? Если вы не объясните, что такое «эта проблема», нам очень сложно дать советы о том, как ее исправить. Пожалуйста, отредактируйте свой вопрос и задайте более конкретный вопрос, чтобы мы могли попытаться помочь вам в его решении. –

+0

Suppprt для NTLM SASL не был удален. В первую очередь это не было завершено. Компонент 'TIdSASLNTLM' по-прежнему существует в модуле' IdSASL_NTLM.pas', он по умолчанию не зарегистрирован на палитре компонентов, но вы можете его программировать в коде. –

+0

@RemyLebeau: «IdSASL_NTLM.pas» не существует в моей версии INDY (Indy 10 поставляется с XE2). Я просто владею «IdNTLM.pas». {at} KenWhite: Я добавлю ошибки, которые получаю, когда буду использовать другие методы SALS (или просто не SASL) завтра, машина с сервером обмена не будет дома. – Timestop

ответ

0

Я недавно боролся с Инди и моим сервером Exchange. Компонент SaslNtlm не входит в версию Indy10, поставляемую с Delphi XE5. Это даже не в исходных файлах папки Indy Protocols.

К счастью, имеется много вещей, необходимых для проверки подлинности NTLM с помощью SMTP-клиента. Существует единица под названием IdAuthenticationSSPI, которая реализует весь обмен NTLM. Все, что осталось сделать, это реализовать пользовательский потомок от TIdSASL, который взаимодействует с объектом TIndySSPINTLMClient.

TSaslNtlm = class(TIdSASL) 
    public 
    constructor Create(AOwner: TComponent); 
    destructor Destroy; override; 

    function StartAuthenticate(const AChallenge, AHost, AProtocolName : string): string; override; 
    function ContinueAuthenticate(const ALastResponse, AHost, AProtocolName : string): string; override; 
    function IsReadyToStart: Boolean; override; 

    class function ServiceName: TIdSASLServiceName; override; 

    private 
    FSSPIClient: TIndySSPINTLMClient; 
    end; 

Реализация класса выглядит следующим образом:

constructor TSaslNtlm.Create(AOwner: TComponent); 
begin 
    inherited Create(AOwner); 
    FSSPIClient := TIndySSPINTLMClient.Create; 
end; 

destructor TSaslNtlm.Destroy; 
begin 
    FSSPIClient.Free; 
    inherited; 
end; 

function TSaslNtlm.StartAuthenticate(const AChallenge, AHost, 
            AProtocolName: string): string; 
begin 
    FSSPIClient.SetCredentials(AHost, '', ''); 
    Result := BytesToStringRaw(FSSPIClient.InitAndBuildType1Message); 
end; 

function TSaslNtlm.ContinueAuthenticate(const ALastResponse, AHost, 
             AProtocolName: string): string; 
var LastMsg: TIdBytes; 
begin 
    LastMsg := ToBytes(ALastResponse, Indy8BitEncoding 
        {$IFDEF STRING_IS_ANSI}, Indy8BitEncoding{$ENDIF}); 
    Result := BytesToStringRaw(FSSPIClient.UpdateAndBuildType3Message(LastMsg)); 
end; 

function TSaslNtlm.IsReadyToStart: Boolean; 
begin 
    Result := True; 
end; 

class function TSaslNtlm.ServiceName: TIdSASLServiceName; 
begin 
    Result := 'NTLM'; 
end; 

А потом это просто вопрос добавления этого механизма SASL для клиента SMTP:

smtp.AuthType := satSASL; 
ntml := TSaslNtlm.Create(smtp); 
with smtp.SASLMechanisms.Add do begin 
    DisplayName := ntlm.ServiceName; 
    SASL := ntlm; 
end; 
Смежные вопросы