blob: 3d25091daac650b6a6e991a8a57bc595aef119e3 [file] [log] [blame]
Paul Bakker1496d382011-05-23 12:07:29 +00001/*
2 * SSL client for SMTP servers
3 *
4 * Copyright (C) 2006-2010, Brainspark B.V.
5 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
7 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25
26#ifndef _CRT_SECURE_NO_DEPRECATE
27#define _CRT_SECURE_NO_DEPRECATE 1
28#endif
29
30#include <string.h>
31#include <stdlib.h>
32#include <stdio.h>
33#include <unistd.h>
34
Paul Bakker5690efc2011-05-26 13:16:06 +000035#include "polarssl/config.h"
36
Paul Bakker1496d382011-05-23 12:07:29 +000037#include "polarssl/base64.h"
38#include "polarssl/error.h"
39#include "polarssl/net.h"
40#include "polarssl/ssl.h"
41#include "polarssl/havege.h"
42#include "polarssl/certs.h"
43#include "polarssl/x509.h"
44
45#define DFL_SERVER_NAME "localhost"
46#define DFL_SERVER_PORT 465
47#define DFL_USER_NAME "user"
48#define DFL_USER_PWD "password"
49#define DFL_MAIL_FROM ""
50#define DFL_MAIL_TO ""
51#define DFL_DEBUG_LEVEL 0
Paul Bakker5690efc2011-05-26 13:16:06 +000052#define DFL_CA_FILE ""
Paul Bakker1496d382011-05-23 12:07:29 +000053#define DFL_CRT_FILE ""
54#define DFL_KEY_FILE ""
55#define DFL_FORCE_CIPHER 0
56#define DFL_MODE 0
57#define DFL_AUTHENTICATION 0
58
59#define MODE_SSL_TLS 0
60#define MODE_STARTTLS 0
61
62/*
63 * global options
64 */
65struct options
66{
67 char *server_name; /* hostname of the server (client only) */
68 int server_port; /* port on which the ssl service runs */
69 int debug_level; /* level of debugging */
70 int authentication; /* if authentication is required */
71 int mode; /* SSL/TLS (0) or STARTTLS (1) */
72 char *user_name; /* username to use for authentication */
73 char *user_pwd; /* password to use for authentication */
74 char *mail_from; /* E-Mail address to use as sender */
75 char *mail_to; /* E-Mail address to use as recipient */
Paul Bakker5690efc2011-05-26 13:16:06 +000076 char *ca_file; /* the file with the CA certificate(s) */
Paul Bakker1496d382011-05-23 12:07:29 +000077 char *crt_file; /* the file with the client certificate */
78 char *key_file; /* the file with the client key */
79 int force_ciphersuite[2]; /* protocol/ciphersuite to use, or all */
80} opt;
81
82void my_debug( void *ctx, int level, const char *str )
83{
84 if( level < opt.debug_level )
85 {
86 fprintf( (FILE *) ctx, "%s", str );
87 fflush( (FILE *) ctx );
88 }
89}
90
Paul Bakker5690efc2011-05-26 13:16:06 +000091#if !defined(POLARSSL_BIGNUM_C) || !defined(POLARSSL_HAVEGE_C) || \
92 !defined(POLARSSL_SSL_TLS_C) || !defined(POLARSSL_SSL_CLI_C) || \
93 !defined(POLARSSL_NET_C) || !defined(POLARSSL_RSA_C)
94int main( void )
95{
96 printf("POLARSSL_BIGNUM_C and/or POLARSSL_HAVEGE_C and/or "
97 "POLARSSL_SSL_TLS_C and/or POLARSSL_SSL_CLI_C and/or "
98 "POLARSSL_NET_C and/or POLARSSL_RSA_C not defined.\n");
99 return( 0 );
100}
101#else
Paul Bakker1496d382011-05-23 12:07:29 +0000102int do_handshake( ssl_context *ssl, struct options *opt )
103{
104 int ret;
105 unsigned char buf[1024];
Paul Bakker5690efc2011-05-26 13:16:06 +0000106 memset(buf, 0, 1024);
Paul Bakker1496d382011-05-23 12:07:29 +0000107
108 /*
109 * 4. Handshake
110 */
111 printf( " . Performing the SSL/TLS handshake..." );
112 fflush( stdout );
113
114 while( ( ret = ssl_handshake( ssl ) ) != 0 )
115 {
116 if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )
117 {
Paul Bakker5690efc2011-05-26 13:16:06 +0000118#if defined(POLARSSL_ERROR_C)
Paul Bakker1496d382011-05-23 12:07:29 +0000119 error_strerror( ret, (char *) buf, 1024 );
Paul Bakker5690efc2011-05-26 13:16:06 +0000120#endif
Paul Bakker1496d382011-05-23 12:07:29 +0000121 printf( " failed\n ! ssl_handshake returned %d: %s\n\n", ret, buf );
122 return( -1 );
123 }
124 }
125
126 printf( " ok\n [ Ciphersuite is %s ]\n",
127 ssl_get_ciphersuite( ssl ) );
128
129 /*
130 * 5. Verify the server certificate
131 */
132 printf( " . Verifying peer X.509 certificate..." );
133
134 if( ( ret = ssl_get_verify_result( ssl ) ) != 0 )
135 {
136 printf( " failed\n" );
137
138 if( ( ret & BADCERT_EXPIRED ) != 0 )
139 printf( " ! server certificate has expired\n" );
140
141 if( ( ret & BADCERT_REVOKED ) != 0 )
142 printf( " ! server certificate has been revoked\n" );
143
144 if( ( ret & BADCERT_CN_MISMATCH ) != 0 )
145 printf( " ! CN mismatch (expected CN=%s)\n", opt->server_name );
146
147 if( ( ret & BADCERT_NOT_TRUSTED ) != 0 )
148 printf( " ! self-signed or not signed by a trusted CA\n" );
149
150 printf( "\n" );
151 }
152 else
153 printf( " ok\n" );
154
155 printf( " . Peer certificate information ...\n" );
156 x509parse_cert_info( (char *) buf, sizeof( buf ) - 1, " ", ssl->peer_cert );
157 printf( "%s\n", buf );
158
159 return( 0 );
160}
161
162int write_ssl_data( ssl_context *ssl, unsigned char *buf, size_t len )
163{
164 int ret;
165
166 printf("\n%s", buf);
167 while( len && ( ret = ssl_write( ssl, buf, len ) ) <= 0 )
168 {
169 if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )
170 {
171 printf( " failed\n ! ssl_write returned %d\n\n", ret );
172 return -1;
173 }
174 }
175
176 return( 0 );
177}
178
179int write_ssl_and_get_response( ssl_context *ssl, unsigned char *buf, size_t len )
180{
181 int ret;
182 unsigned char data[128];
183 char code[4];
184 size_t i, idx = 0;
185
186 printf("\n%s", buf);
187 while( len && ( ret = ssl_write( ssl, buf, len ) ) <= 0 )
188 {
189 if( ret != POLARSSL_ERR_NET_WANT_READ && ret != POLARSSL_ERR_NET_WANT_WRITE )
190 {
191 printf( " failed\n ! ssl_write returned %d\n\n", ret );
192 return -1;
193 }
194 }
195
196 do
197 {
198 len = sizeof( data ) - 1;
199 memset( data, 0, sizeof( data ) );
200 ret = ssl_read( ssl, data, len );
201
202 if( ret == POLARSSL_ERR_NET_WANT_READ || ret == POLARSSL_ERR_NET_WANT_WRITE )
203 continue;
204
205 if( ret == POLARSSL_ERR_SSL_PEER_CLOSE_NOTIFY )
206 return -1;
207
208 if( ret <= 0 )
209 {
210 printf( "failed\n ! ssl_read returned %d\n\n", ret );
211 return -1;
212 }
213
214 printf("\n%s", data);
215 len = ret;
216 for( i = 0; i < len; i++ )
217 {
218 if( data[i] != '\n' )
219 {
220 if( idx < 4 )
221 code[ idx++ ] = data[i];
222 continue;
223 }
224
225 if( idx == 4 && code[0] >= '0' && code[0] <= '9' && code[3] == ' ' )
226 {
227 code[3] = '\0';
228 return atoi( code );
229 }
230
231 idx = 0;
232 }
233 }
234 while( 1 );
235}
236
237int write_and_get_response( int sock_fd, unsigned char *buf, size_t len )
238{
239 int ret;
240 unsigned char data[128];
241 char code[4];
242 size_t i, idx = 0;
243
244 printf("\n%s", buf);
245 if( len && ( ret = write( sock_fd, buf, len ) ) <= 0 )
246 {
247 printf( " failed\n ! ssl_write returned %d\n\n", ret );
248 return -1;
249 }
250
251 do
252 {
253 len = sizeof( data ) - 1;
254 memset( data, 0, sizeof( data ) );
255 ret = read( sock_fd, data, len );
256
257 if( ret <= 0 )
258 {
259 printf( "failed\n ! read returned %d\n\n", ret );
260 return -1;
261 }
262
263 printf("\n%s", data);
264 len = ret;
265 for( i = 0; i < len; i++ )
266 {
267 if( data[i] != '\n' )
268 {
269 if( idx < 4 )
270 code[ idx++ ] = data[i];
271 continue;
272 }
273
274 if( idx == 4 && code[0] >= '0' && code[0] <= '9' && code[3] == ' ' )
275 {
276 code[3] = '\0';
277 return atoi( code );
278 }
279
280 idx = 0;
281 }
282 }
283 while( 1 );
284}
285
Paul Bakker5690efc2011-05-26 13:16:06 +0000286#if defined(POLARSSL_BASE64_C)
287#define USAGE_AUTH \
288 " authentication=%%d default: 0 (disabled)\n" \
289 " user_name=%%s default: \"user\"\n" \
290 " user_pwd=%%s default: \"password\"\n"
291#else
292#define USAGE_AUTH \
293 " authentication options disabled. (Require POLARSSL_BASE64_C)\n"
294#endif /* POLARSSL_BASE64_C */
295
296#if defined(POLARSSL_FS_IO)
297#define USAGE_IO \
298 " ca_file=%%s default: \"\" (pre-loaded)\n" \
299 " crt_file=%%s default: \"\" (pre-loaded)\n" \
300 " key_file=%%s default: \"\" (pre-loaded)\n"
301#else
302#define USAGE_IO \
303 " No file operations available (POLARSSL_FS_IO not defined)\n"
304#endif /* POLARSSL_FS_IO */
305
Paul Bakker1496d382011-05-23 12:07:29 +0000306#define USAGE \
307 "\n usage: ssl_mail_client param=<>...\n" \
308 "\n acceptable parameters:\n" \
309 " server_name=%%s default: localhost\n" \
310 " server_port=%%d default: 4433\n" \
311 " debug_level=%%d default: 0 (disabled)\n" \
Paul Bakker1496d382011-05-23 12:07:29 +0000312 " mode=%%d default: 0 (SSL/TLS) (1 for STARTTLS)\n" \
Paul Bakker5690efc2011-05-26 13:16:06 +0000313 USAGE_AUTH \
Paul Bakker1496d382011-05-23 12:07:29 +0000314 " mail_from=%%s default: \"\"\n" \
315 " mail_to=%%s default: \"\"\n" \
Paul Bakker5690efc2011-05-26 13:16:06 +0000316 USAGE_IO \
Paul Bakker1496d382011-05-23 12:07:29 +0000317 " force_ciphersuite=<name> default: all enabled\n"\
318 " acceptable ciphersuite names:\n"
319
320int main( int argc, char *argv[] )
321{
322 int ret = 0, len, server_fd;
323 unsigned char buf[1024];
Paul Bakker5690efc2011-05-26 13:16:06 +0000324#if defined(POLARSSL_BASE64_C)
Paul Bakker1496d382011-05-23 12:07:29 +0000325 unsigned char base[1024];
Paul Bakker5690efc2011-05-26 13:16:06 +0000326#endif
Paul Bakker1496d382011-05-23 12:07:29 +0000327 char hostname[32];
328 havege_state hs;
329 ssl_context ssl;
330 ssl_session ssn;
331 x509_cert cacert;
332 x509_cert clicert;
333 rsa_context rsa;
334 int i;
335 size_t j, n;
336 char *p, *q;
337 const int *list;
338
339 /*
340 * Make sure memory references are valid.
341 */
342 server_fd = 0;
343 memset( &ssn, 0, sizeof( ssl_session ) );
344 memset( &ssl, 0, sizeof( ssl_context ) );
345 memset( &cacert, 0, sizeof( x509_cert ) );
346 memset( &clicert, 0, sizeof( x509_cert ) );
347 memset( &rsa, 0, sizeof( rsa_context ) );
348
349 if( argc == 0 )
350 {
351 usage:
352 printf( USAGE );
353
354 list = ssl_list_ciphersuites();
355 while( *list )
356 {
357 printf(" %s\n", ssl_get_ciphersuite_name( *list ) );
358 list++;
359 }
360 printf("\n");
361 goto exit;
362 }
363
364 opt.server_name = DFL_SERVER_NAME;
365 opt.server_port = DFL_SERVER_PORT;
366 opt.debug_level = DFL_DEBUG_LEVEL;
367 opt.authentication = DFL_AUTHENTICATION;
368 opt.mode = DFL_MODE;
369 opt.user_name = DFL_USER_NAME;
370 opt.user_pwd = DFL_USER_PWD;
371 opt.mail_from = DFL_MAIL_FROM;
372 opt.mail_to = DFL_MAIL_TO;
Paul Bakker5690efc2011-05-26 13:16:06 +0000373 opt.ca_file = DFL_CA_FILE;
Paul Bakker1496d382011-05-23 12:07:29 +0000374 opt.crt_file = DFL_CRT_FILE;
375 opt.key_file = DFL_KEY_FILE;
376 opt.force_ciphersuite[0]= DFL_FORCE_CIPHER;
377
378 for( i = 1; i < argc; i++ )
379 {
380 n = strlen( argv[i] );
381
382 for( j = 0; j < n; j++ )
383 {
384 if( argv[i][j] == '=')
385 break;
386
387 if( argv[i][j] >= 'A' && argv[i][j] <= 'Z' )
388 argv[i][j] |= 0x20;
389 }
390
391 p = argv[i];
392 if( ( q = strchr( p, '=' ) ) == NULL )
393 goto usage;
394 *q++ = '\0';
395
396 if( strcmp( p, "server_name" ) == 0 )
397 opt.server_name = q;
398 else if( strcmp( p, "server_port" ) == 0 )
399 {
400 opt.server_port = atoi( q );
401 if( opt.server_port < 1 || opt.server_port > 65535 )
402 goto usage;
403 }
404 else if( strcmp( p, "debug_level" ) == 0 )
405 {
406 opt.debug_level = atoi( q );
407 if( opt.debug_level < 0 || opt.debug_level > 65535 )
408 goto usage;
409 }
410 else if( strcmp( p, "authentication" ) == 0 )
411 {
412 opt.authentication = atoi( q );
413 if( opt.authentication < 0 || opt.authentication > 1 )
414 goto usage;
415 }
416 else if( strcmp( p, "mode" ) == 0 )
417 {
418 opt.mode = atoi( q );
419 if( opt.mode < 0 || opt.mode > 1 )
420 goto usage;
421 }
422 else if( strcmp( p, "user_name" ) == 0 )
423 opt.user_name = q;
424 else if( strcmp( p, "user_pwd" ) == 0 )
425 opt.user_pwd = q;
426 else if( strcmp( p, "mail_from" ) == 0 )
427 opt.mail_from = q;
428 else if( strcmp( p, "mail_to" ) == 0 )
429 opt.mail_to = q;
Paul Bakker5690efc2011-05-26 13:16:06 +0000430 else if( strcmp( p, "ca_file" ) == 0 )
431 opt.ca_file = q;
Paul Bakker1496d382011-05-23 12:07:29 +0000432 else if( strcmp( p, "crt_file" ) == 0 )
433 opt.crt_file = q;
434 else if( strcmp( p, "key_file" ) == 0 )
435 opt.key_file = q;
436 else if( strcmp( p, "force_ciphersuite" ) == 0 )
437 {
438 opt.force_ciphersuite[0] = -1;
439
440 opt.force_ciphersuite[0] = ssl_get_ciphersuite_id( q );
441
442 if( opt.force_ciphersuite[0] <= 0 )
443 goto usage;
444
445 opt.force_ciphersuite[1] = 0;
446 }
447 else
448 goto usage;
449 }
450
451 /*
452 * 0. Initialize the RNG and the session data
453 */
454 havege_init( &hs );
455
456 /*
457 * 1.1. Load the trusted CA
458 */
459 printf( "\n . Loading the CA root certificate ..." );
460 fflush( stdout );
461
Paul Bakker5690efc2011-05-26 13:16:06 +0000462#if defined(POLARSSL_FS_IO)
463 if( strlen( opt.ca_file ) )
464 ret = x509parse_crtfile( &cacert, opt.ca_file );
465 else
466#endif
467#if defined(POLARSSL_CERTS_C)
468 ret = x509parse_crt( &cacert, (unsigned char *) test_ca_crt,
469 strlen( test_ca_crt ) );
470#else
471 {
472 ret = 1;
473 printf("POLARSSL_CERTS_C not defined.");
474 }
475#endif
Paul Bakker1496d382011-05-23 12:07:29 +0000476 if( ret != 0 )
477 {
478 printf( " failed\n ! x509parse_crt returned %d\n\n", ret );
479 goto exit;
480 }
481
482 printf( " ok\n" );
483
484 /*
485 * 1.2. Load own certificate and private key
486 *
487 * (can be skipped if client authentication is not required)
488 */
489 printf( " . Loading the client cert. and key..." );
490 fflush( stdout );
491
Paul Bakker5690efc2011-05-26 13:16:06 +0000492#if defined(POLARSSL_FS_IO)
Paul Bakker1496d382011-05-23 12:07:29 +0000493 if( strlen( opt.crt_file ) )
494 ret = x509parse_crtfile( &clicert, opt.crt_file );
495 else
Paul Bakker5690efc2011-05-26 13:16:06 +0000496#endif
497#if defined(POLARSSL_CERTS_C)
Paul Bakker1496d382011-05-23 12:07:29 +0000498 ret = x509parse_crt( &clicert, (unsigned char *) test_cli_crt,
499 strlen( test_cli_crt ) );
Paul Bakker5690efc2011-05-26 13:16:06 +0000500#else
501 {
502 ret = 1;
503 printf("POLARSSL_CERTS_C not defined.");
504 }
505#endif
Paul Bakker1496d382011-05-23 12:07:29 +0000506 if( ret != 0 )
507 {
508 printf( " failed\n ! x509parse_crt returned %d\n\n", ret );
509 goto exit;
510 }
511
Paul Bakker5690efc2011-05-26 13:16:06 +0000512#if defined(POLARSSL_FS_IO)
Paul Bakker1496d382011-05-23 12:07:29 +0000513 if( strlen( opt.key_file ) )
514 ret = x509parse_keyfile( &rsa, opt.key_file, "" );
515 else
Paul Bakker5690efc2011-05-26 13:16:06 +0000516#endif
517#if defined(POLARSSL_CERTS_C)
Paul Bakker1496d382011-05-23 12:07:29 +0000518 ret = x509parse_key( &rsa, (unsigned char *) test_cli_key,
519 strlen( test_cli_key ), NULL, 0 );
Paul Bakker5690efc2011-05-26 13:16:06 +0000520#else
521 {
522 ret = 1;
523 printf("POLARSSL_CERTS_C not defined.");
524 }
525#endif
Paul Bakker1496d382011-05-23 12:07:29 +0000526 if( ret != 0 )
527 {
528 printf( " failed\n ! x509parse_key returned %d\n\n", ret );
529 goto exit;
530 }
531
532 printf( " ok\n" );
533
534 /*
535 * 2. Start the connection
536 */
537 printf( " . Connecting to tcp/%s/%-4d...", opt.server_name,
538 opt.server_port );
539 fflush( stdout );
540
541 if( ( ret = net_connect( &server_fd, opt.server_name,
542 opt.server_port ) ) != 0 )
543 {
544 printf( " failed\n ! net_connect returned %d\n\n", ret );
545 goto exit;
546 }
547
548 printf( " ok\n" );
549
550 /*
551 * 3. Setup stuff
552 */
553 printf( " . Setting up the SSL/TLS structure..." );
554 fflush( stdout );
555
556 havege_init( &hs );
557
558 if( ( ret = ssl_init( &ssl ) ) != 0 )
559 {
560 printf( " failed\n ! ssl_init returned %d\n\n", ret );
561 goto exit;
562 }
563
564 printf( " ok\n" );
565
566 ssl_set_endpoint( &ssl, SSL_IS_CLIENT );
567 ssl_set_authmode( &ssl, SSL_VERIFY_OPTIONAL );
568
569 ssl_set_rng( &ssl, havege_rand, &hs );
570 ssl_set_dbg( &ssl, my_debug, stdout );
571 ssl_set_bio( &ssl, net_recv, &server_fd,
572 net_send, &server_fd );
573
574 if( opt.force_ciphersuite[0] == DFL_FORCE_CIPHER )
575 ssl_set_ciphersuites( &ssl, ssl_default_ciphersuites );
576 else
577 ssl_set_ciphersuites( &ssl, opt.force_ciphersuite );
578
579 ssl_set_session( &ssl, 1, 600, &ssn );
580
581 ssl_set_ca_chain( &ssl, &cacert, NULL, opt.server_name );
582 ssl_set_own_cert( &ssl, &clicert, &rsa );
583
584 ssl_set_hostname( &ssl, opt.server_name );
585
586 if( opt.mode == MODE_SSL_TLS )
587 {
588 if( do_handshake( &ssl, &opt ) != 0 )
589 goto exit;
590
591 printf( " > Get header from server:" );
592 fflush( stdout );
593
594 ret = write_ssl_and_get_response( &ssl, buf, 0 );
595 if( ret < 200 || ret > 299 )
596 {
597 printf( " failed\n ! server responded with %d\n\n", ret );
598 goto exit;
599 }
600
601 printf(" ok\n" );
602
603 printf( " > Write EHLO to server:" );
604 fflush( stdout );
605
606 gethostname( hostname, 32 );
607 len = sprintf( (char *) buf, "EHLO %s\n", hostname );
608 ret = write_ssl_and_get_response( &ssl, buf, len );
609 if( ret < 200 || ret > 299 )
610 {
611 printf( " failed\n ! server responded with %d\n\n", ret );
612 goto exit;
613 }
614 }
615 else
616 {
617 printf( " > Get header from server:" );
618 fflush( stdout );
619
620 ret = write_and_get_response( server_fd, buf, 0 );
621 if( ret < 200 || ret > 299 )
622 {
623 printf( " failed\n ! server responded with %d\n\n", ret );
624 goto exit;
625 }
626
627 printf(" ok\n" );
628
629 printf( " > Write EHLO to server:" );
630 fflush( stdout );
631
632 gethostname( hostname, 32 );
633 len = sprintf( (char *) buf, "EHLO %s\n", hostname );
634 ret = write_and_get_response( server_fd, buf, len );
635 if( ret < 200 || ret > 299 )
636 {
637 printf( " failed\n ! server responded with %d\n\n", ret );
638 goto exit;
639 }
640
641 printf(" ok\n" );
642
643 printf( " > Write STARTTLS to server:" );
644 fflush( stdout );
645
646 gethostname( hostname, 32 );
647 len = sprintf( (char *) buf, "STARTTLS\n" );
648 ret = write_and_get_response( server_fd, buf, len );
649 if( ret < 200 || ret > 299 )
650 {
651 printf( " failed\n ! server responded with %d\n\n", ret );
652 goto exit;
653 }
654
655 printf(" ok\n" );
656
657 if( do_handshake( &ssl, &opt ) != 0 )
658 goto exit;
659 }
660
Paul Bakker5690efc2011-05-26 13:16:06 +0000661#if defined(POLARSSL_BASE64_C)
Paul Bakker1496d382011-05-23 12:07:29 +0000662 if( opt.authentication )
663 {
664 printf( " > Write AUTH LOGIN to server:" );
665 fflush( stdout );
666
667 len = sprintf( (char *) buf, "AUTH LOGIN\n" );
668 ret = write_ssl_and_get_response( &ssl, buf, len );
669 if( ret < 200 || ret > 399 )
670 {
671 printf( " failed\n ! server responded with %d\n\n", ret );
672 goto exit;
673 }
674
675 printf(" ok\n" );
676
677 printf( " > Write username to server: %s", opt.user_name );
678 fflush( stdout );
679
680 n = sizeof( buf );
Paul Bakkere22d7032011-05-23 16:02:34 +0000681 len = base64_encode( base, &n, (unsigned char *) opt.user_name, strlen( opt.user_name ) );
Paul Bakker1496d382011-05-23 12:07:29 +0000682 len = sprintf( (char *) buf, "%s\n", base );
683 ret = write_ssl_and_get_response( &ssl, buf, len );
684 if( ret < 300 || ret > 399 )
685 {
686 printf( " failed\n ! server responded with %d\n\n", ret );
687 goto exit;
688 }
689
690 printf(" ok\n" );
691
692 printf( " > Write password to server: %s", opt.user_pwd );
693 fflush( stdout );
694
Paul Bakkere22d7032011-05-23 16:02:34 +0000695 len = base64_encode( base, &n, (unsigned char *) opt.user_pwd, strlen( opt.user_pwd ) );
Paul Bakker1496d382011-05-23 12:07:29 +0000696 len = sprintf( (char *) buf, "%s\n", base );
697 ret = write_ssl_and_get_response( &ssl, buf, len );
698 if( ret < 200 || ret > 399 )
699 {
700 printf( " failed\n ! server responded with %d\n\n", ret );
701 goto exit;
702 }
703
704 printf(" ok\n" );
705 }
Paul Bakker5690efc2011-05-26 13:16:06 +0000706#endif
Paul Bakker1496d382011-05-23 12:07:29 +0000707
708 printf( " > Write MAIL FROM to server:" );
709 fflush( stdout );
710
711 len = sprintf( (char *) buf, "MAIL FROM:<%s>\n", opt.mail_from );
712 ret = write_ssl_and_get_response( &ssl, buf, len );
713 if( ret < 200 || ret > 299 )
714 {
715 printf( " failed\n ! server responded with %d\n\n", ret );
716 goto exit;
717 }
718
719 printf(" ok\n" );
720
721 printf( " > Write RCPT TO to server:" );
722 fflush( stdout );
723
724 len = sprintf( (char *) buf, "RCPT TO:<%s>\n", opt.mail_to );
725 ret = write_ssl_and_get_response( &ssl, buf, len );
726 if( ret < 200 || ret > 299 )
727 {
728 printf( " failed\n ! server responded with %d\n\n", ret );
729 goto exit;
730 }
731
732 printf(" ok\n" );
733
734 printf( " > Write DATA to server:" );
735 fflush( stdout );
736
737 len = sprintf( (char *) buf, "DATA\n" );
738 ret = write_ssl_and_get_response( &ssl, buf, len );
739 if( ret < 300 || ret > 399 )
740 {
741 printf( " failed\n ! server responded with %d\n\n", ret );
742 goto exit;
743 }
744
745 printf(" ok\n" );
746
747 printf( " > Write content to server:" );
748 fflush( stdout );
749
750 len = sprintf( (char *) buf, "From: %s\nSubject: PolarSSL Test mail\n\n"
751 "This is a simple test mail from the "
752 "PolarSSL mail client example.\n"
753 "\n"
754 "Enjoy!", opt.mail_from );
755 ret = write_ssl_data( &ssl, buf, len );
756
757 len = sprintf( (char *) buf, "\r\n.\r\n");
758 ret = write_ssl_and_get_response( &ssl, buf, len );
759 if( ret < 200 || ret > 299 )
760 {
761 printf( " failed\n ! server responded with %d\n\n", ret );
762 goto exit;
763 }
764
765 printf(" ok\n" );
766
767 ssl_close_notify( &ssl );
768
769exit:
770
771 if( server_fd )
772 net_close( server_fd );
773 x509_free( &clicert );
774 x509_free( &cacert );
775 rsa_free( &rsa );
776 ssl_free( &ssl );
777
778 memset( &ssl, 0, sizeof( ssl ) );
779
780#ifdef WIN32
781 printf( " + Press Enter to exit this program.\n" );
782 fflush( stdout ); getchar();
783#endif
784
785 return( ret );
786}
Paul Bakker5690efc2011-05-26 13:16:06 +0000787#endif /* POLARSSL_BIGNUM_C && POLARSSL_HAVEGE_C && POLARSSL_SSL_TLS_C &&
788 POLARSSL_SSL_CLI_C && POLARSSL_NET_C && POLARSSL_RSA_C */