Hi, On Tue, 19 Nov 2002 21:20:57 -0500, Su Li <[EMAIL PROTECTED]> wrote... > Thanks a lot Mark and Ken, > > I am writing a C++ client to log into Sieve 2000 port. Can you send me the C++/C >code for base64 encode? So what I need to do to login to Sieve should be like: > > C: AUTHENTICATE "PLAIN" {21+} > C: <base64 encoded authname and username> > S: password? > C: <base64 encode password> > S: OK loged in > > Is that right? > No. PLAIN works differently than LOGIN. PLAIN does not use base64 encoding. In your C++ client, you should use the SASL libraries to do authentication as Ken Murchison suggests.
However, for testing purposes you may still want to connect to the timsieved by telnet. In that case using AUTHENTICATE "LOGIN" is easiest way to login to or authenticate with the server. To be able to use AUTHENTICATE "LOGIN", you need to have configured sasl with the "--enable-login" option. After installation you should have these files in /usr/lib/sasl2: liblogin.la liblogin.so liblogin.so.2 liblogin.so.2.0.7 Connecting to timsieved will yield a response similar to: $ telnet sievehost 2000 S: "IMPLEMENTATION" "Cyrus timsieved v1.1.0" S: "SASL" "PLAIN OTP LOGIN GSSAPI DIGEST-MD5 CRAM-MD5" S: "SIEVE" "fileinto reject envelope vacation imapflags notify subaddress relational regex" S: OK where LOGIN is listed in "SASL" line. At this point you are able to use the AUTHENTICATE "LOGIN" command as follows: C: AUTHENTICATE "LOGIN" S: {12} S: VXNlcm5hbWU6 C: {8+} C: b64data= S: {12} S: UGFzc3dvcmQ6 C: {8+} C: b64data= S: OK The base64 strings that the server returned are "VXNlcm5hbWU6" which is "Username:" and "UGFzc3dvcmQ6" which is "Password:". The theory is that these strings should be displayed to the user. The "{8+}" line tells the server how much base64 data to expect. Quoting the base64 strings also works: C: AUTHENTICATE "LOGIN" S: {12} S: VXNlcm5hbWU6 C: "b64data=" S: {12} S: UGFzc3dvcmQ6 C: "b64data=" S: OK To use AUTHENTICATE "PLAIN" you have to able to enter a '\0' in the data sent with the command which is not possible as far as I know when you are connecting with telnet. In C you could do something like the following to send a plain authentication command: // example untested code. It probably contains errors, doesn't compile // and/or does not work as expected. int socketfd = -1 ; int sentcommand = 0 ; char * authname = NULL, * username = NULL, * password = NULL ; char * databuffer = NULL, * commandbuffer = NULL ; unsigned int datalength = 0 ; const char * const command = "AUTHENTICATE \"PLAIN\" {%u+}\r\n" ; // set socketfd to the timseived connection file descriptor. // set the variables authname, username, password to non null. // empty string is ok. datalength = 2 + strlen( authname ) + strlen( username ) + strlen( password ) ; comandbuffer = (char *) malloc( 64 + strlen( command )) ; // guestimate if( commandbuffer ) { sprintf( commandbuffer, command, datalength ) ; databuffer = (char *) malloc( datalength + 1 ) ; // add one for terminator if( databuffer && ( -1 != socketfd )) { // databuffer contains embedded null characters. sprintf( databuffer, "%s\0%s\0%s", authname, username, password ) ; write( socketfd, (void *) commandbuffer, strlen( commandbuffer ) ; write( socketfd, (void *) databuffer, (size_t) length ) ; sentcommand = 1 ; } } if( commandbuffer ) free( (void *) commandbuffer ) ; if( databuffer ) free( (void *) databuffer ) ; if( sentcommand ) { // read server response... } else { // handle error... } However, using the SASL library is a better option for coding. Regards, Mark Keasling <[EMAIL PROTECTED]>