diff -ru a/sslscan-1.8.2/Changelog b/sslscan-1.8.2/Changelog --- a/sslscan-1.8.2/Changelog 2009-09-01 14:35:59.000000000 +0200 +++ b/sslscan-1.8.2/Changelog 2013-11-10 19:15:30.333323654 +0100 @@ -1,6 +1,14 @@ Changelog ========= +Version: 1.8.2.six +Date : 09/11/2013 +Author : Manuel Bieling (manuel@elektret.de) +Changes: The following are a list of changes + since the previous version: + > IPv6 support + > Verbose flag + Version: 1.8.2 Date : 19/06/2009 Author : Ian Ventura-Whiting (Fizz) @@ -105,4 +113,4 @@ Version: 1.0 Date : 13/07/2007 Author : Ian Ventura-Whiting (Fizz) -Notes : Initial version of sslscan \ No newline at end of file +Notes : Initial version of sslscan diff -ru a/sslscan-1.8.2/sslscan.1 b/sslscan-1.8.2/sslscan.1 --- a/sslscan-1.8.2/sslscan.1 2009-09-01 14:35:59.000000000 +0200 +++ b/sslscan-1.8.2/sslscan.1 2013-11-10 19:15:55.021641616 +0100 @@ -25,6 +25,9 @@ .B \-\-version Show version of program. .TP +.B \-\-verbose +Show some extra information +.TP .B \-\-targets= A file containing a list of hosts to check. Hosts can be supplied with @@ -34,6 +37,9 @@ List only accepted ciphers (default is to listing all ciphers). .TP +.B \-6 +Enforce IPv6 +.TP .B \-\-ssl2 .br Only check SSLv2 ciphers. diff -ru a/sslscan-1.8.2/sslscan.c b/sslscan-1.8.2/sslscan.c --- a/sslscan-1.8.2/sslscan.c 2009-09-01 14:35:59.000000000 +0200 +++ b/sslscan-1.8.2/sslscan.c 2013-11-10 19:52:35.720734838 +0100 @@ -2,6 +2,7 @@ * sslscan - A SSL cipher scanning tool * * Copyright 2007-2009 by Ian Ventura-Whiting (Fizz) * * fizz@titania.co.uk * + * Copyright 2013 by Manuel Bieling (manuel@elektret.de) * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * @@ -99,7 +100,7 @@ { // Program Options... char host[512]; - int port; + char *port; int noFailed; int starttls; int sslVersion; @@ -107,13 +108,14 @@ int pout; int sslbugs; int http; + int verbose; + int forcev6; // File Handles... FILE *xmlOutput; // TCP Connection Variables... - struct hostent *hostStruct; - struct sockaddr_in serverAddress; + struct addrinfo *serverAddress; // SSL Variables... SSL_CTX *ctx; @@ -239,33 +241,26 @@ // Variables... int socketDescriptor; char buffer[BUFFERSIZE]; - struct sockaddr_in localAddress; int status; // Create Socket - socketDescriptor = socket(AF_INET, SOCK_STREAM, 0); + socketDescriptor = socket(options->serverAddress->ai_family, + options->serverAddress->ai_socktype, + options->serverAddress->ai_protocol); + if(socketDescriptor < 0) { printf("%s ERROR: Could not open a socket.%s\n", COL_RED, RESET); return 0; } - // Configure Local Port - localAddress.sin_family = AF_INET; - localAddress.sin_addr.s_addr = htonl(INADDR_ANY); - localAddress.sin_port = htons(0); - status = bind(socketDescriptor, (struct sockaddr *) &localAddress, sizeof(localAddress)); - if(status < 0) - { - printf("%s ERROR: Could not bind to port.%s\n", COL_RED, RESET); - return 0; - } - // Connect - status = connect(socketDescriptor, (struct sockaddr *) &options->serverAddress, sizeof(options->serverAddress)); + status = connect(socketDescriptor, + options->serverAddress->ai_addr, + options->serverAddress->ai_addrlen); if(status < 0) { - printf("%s ERROR: Could not open a connection to host %s on port %d.%s\n", COL_RED, options->host, options->port, RESET); + printf("%s ERROR: Could not open a connection to host %s on port %s.%s\n", COL_RED, options->host, options->port, RESET); return 0; } @@ -277,7 +272,7 @@ if (strncmp(buffer, "220", 3) != 0) { close(socketDescriptor); - printf("%s ERROR: The host %s on port %d did not appear to be an SMTP service.%s\n", COL_RED, options->host, options->port, RESET); + printf("%s ERROR: The host %s on port %s did not appear to be an SMTP service.%s\n", COL_RED, options->host, options->port, RESET); return 0; } send(socketDescriptor, "EHLO titania.co.uk\r\n", 20, 0); @@ -286,7 +281,7 @@ if (strncmp(buffer, "250", 3) != 0) { close(socketDescriptor); - printf("%s ERROR: The SMTP service on %s port %d did not respond with status 250 to our HELO.%s\n", COL_RED, options->host, options->port, RESET); + printf("%s ERROR: The SMTP service on %s port %s did not respond with status 250 to our HELO.%s\n", COL_RED, options->host, options->port, RESET); return 0; } send(socketDescriptor, "STARTTLS\r\n", 10, 0); @@ -295,7 +290,7 @@ if (strncmp(buffer, "220", 3) != 0) { close(socketDescriptor); - printf("%s ERROR: The SMTP service on %s port %d did not appear to support STARTTLS.%s\n", COL_RED, options->host, options->port, RESET); + printf("%s ERROR: The SMTP service on %s port %s did not appear to support STARTTLS.%s\n", COL_RED, options->host, options->port, RESET); return 0; } } @@ -1120,27 +1115,75 @@ { // Variables... struct sslCipher *sslCipherPointer; - int status = true; + struct in6_addr serveraddr; + struct addrinfo hints; + int error, status = true; + char address_buffer[INET6_ADDRSTRLEN]; + + memset(&hints, '\0', sizeof(hints)); + hints.ai_flags = AI_NUMERICSERV; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; - // Resolve Host Name - options->hostStruct = gethostbyname(options->host); - if (options->hostStruct == NULL) + error = inet_pton(AF_INET, options->host, &serveraddr); + if (error == 1) { - printf("%sERROR: Could not resolve hostname %s.%s\n", COL_RED, options->host, RESET); - return false; + hints.ai_family = AF_INET; + hints.ai_flags |= AI_NUMERICHOST; } + else + { + error = inet_pton(AF_INET6, options->host, &serveraddr); + if (error == 1) + { + hints.ai_family = AF_INET6; + hints.ai_flags |= AI_NUMERICHOST; + } + else + { + if(options->forcev6) hints.ai_family = AF_INET6; + else hints.ai_family = AF_INET; + } + } + + if ((error = getaddrinfo( + options->host, + options->port, + &hints, + &options->serverAddress)) != 0) { + printf("%sERROR: Could not resolve hostname or ip %s.%s\n", + COL_RED, + options->host, + RESET); + return false; + } - // Configure Server Address and Port - options->serverAddress.sin_family = options->hostStruct->h_addrtype; - memcpy((char *) &options->serverAddress.sin_addr.s_addr, options->hostStruct->h_addr_list[0], options->hostStruct->h_length); - options->serverAddress.sin_port = htons(options->port); + if (options->verbose) { + struct addrinfo *run = options->serverAddress; + while(run != NULL) { + getnameinfo(run->ai_addr, + run->ai_addrlen, + address_buffer, + INET6_ADDRSTRLEN, + NULL, + 0, + NI_NUMERICHOST); + printf("\nfamily: %2d, socktype: %2d, protocol: %3d, address: %s(%d)", + run->ai_family, + run->ai_socktype, + run->ai_protocol, + address_buffer, + run->ai_addrlen); + run = run->ai_next; + } + } // XML Output... if (options->xmlOutput != 0) - fprintf(options->xmlOutput, " \n", options->host, options->port); + fprintf(options->xmlOutput, " \n", options->host, options->port); // Test supported ciphers... - printf("\n%sTesting SSL server %s on port %d%s\n\n", COL_GREEN, options->host, options->port, RESET); + printf("\n%sTesting SSL server %s on port %s%s\n\n", COL_GREEN, options->host, options->port, RESET); printf(" %sSupported Server Cipher(s):%s\n", COL_BLUE, RESET); if ((options->http == true) && (options->pout == true)) printf("|| Status || HTTP Code || Version || Bits || Cipher ||\n"); @@ -1240,13 +1283,16 @@ // Init... memset(&options, 0, sizeof(struct sslCheckOptions)); - options.port = 443; + options.port = "443"; + options.verbose = false; + options.forcev6 = false; xmlArg = 0; strcpy(options.host, "127.0.0.1"); options.noFailed = false; options.starttls = false; options.sslVersion = ssl_all; options.pout = false; + options.serverAddress = NULL; SSL_library_init(); // Get program parameters @@ -1256,6 +1302,10 @@ if (strcmp("--help", argv[argLoop]) == 0) mode = mode_help; + // Verbose + else if (strcmp("--verbose", argv[argLoop]) == 0) + options.verbose = true; + // targets else if ((strncmp("--targets=", argv[argLoop], 10) == 0) && (strlen(argv[argLoop]) > 10)) { @@ -1278,6 +1328,9 @@ // P Output else if (strcmp("-p", argv[argLoop]) == 0) options.pout = true; + + else if (strcmp("-6", argv[argLoop]) == 0) + options.forcev6 = true; // Client Certificates else if (strncmp("--certs=", argv[argLoop], 8) == 0) @@ -1322,19 +1375,40 @@ else if (argLoop + 1 == argc) { mode = mode_single; - - // Get host... - tempInt = 0; + tempInt = 0; maxSize = strlen(argv[argLoop]); - while ((argv[argLoop][tempInt] != 0) && (argv[argLoop][tempInt] != ':')) - tempInt++; - argv[argLoop][tempInt] = 0; - strncpy(options.host, argv[argLoop], sizeof(options.host) -1); - // Get port (if it exists)... - tempInt++; - if (tempInt < maxSize) - options.port = atoi(argv[argLoop] + tempInt); + if (argv[argLoop][tempInt] == '[') + { + if (options.verbose) puts("Parse IPv6"); + while ((argv[argLoop][tempInt] != 0) && (argv[argLoop][tempInt] != ']')) + tempInt++; + argv[argLoop][tempInt] = 0; + strncpy(options.host, argv[argLoop] + 1, sizeof(options.host) -1); + if (options.verbose) printf("Host: %s\n", options.host); + + tempInt++; + if (tempInt + 1 < maxSize) + { + printf("Port: %s\n", argv[argLoop] + tempInt + 1); + options.port = argv[argLoop] + tempInt + 1; + } + } + else + { + if (options.verbose) puts("Parse HOST"); + while ((argv[argLoop][tempInt] != 0) && (argv[argLoop][tempInt] != ':')) + tempInt++; + argv[argLoop][tempInt] = 0; + strncpy(options.host, argv[argLoop], sizeof(options.host) -1); + if (options.verbose) printf("Host: %s\n", options.host); + + tempInt++; + if (tempInt < maxSize) { + if (options.verbose) printf("Port: %s\n", argv[argLoop] + tempInt); + options.port = argv[argLoop] + tempInt; + } + } } // Not too sure what the user is doing... @@ -1433,6 +1507,11 @@ // Do the testing... if (mode == mode_single) status = testHost(&options); + if (options.serverAddress != NULL) + { + freeaddrinfo(options.serverAddress); + options.serverAddress = NULL; + } else { if (fileExists(argv[options.targets] + 10) == true) @@ -1448,20 +1527,47 @@ { if (strlen(line) != 0) { - // Get host... tempInt = 0; - while ((line[tempInt] != 0) && (line[tempInt] != ':')) + if (line[tempInt] == '[') + { + if (options.verbose) puts("Parse IPv6"); + while ((line[tempInt] != 0) && (line[tempInt] != ']')) + tempInt++; + line[tempInt] = 0; + strncpy(options.host, line + 1, sizeof(options.host) -1); + if (options.verbose) printf("Host: %s\n", options.host); + tempInt++; - line[tempInt] = 0; - strncpy(options.host, line, sizeof(options.host) -1); + if (strlen(line + tempInt) > 0) + { + if (options.verbose) printf("Port: %s\n", line + 1 + tempInt); + options.port = line + 1 + tempInt; + } - // Get port (if it exists)... - tempInt++; - if (strlen(line + tempInt) > 0) - options.port = atoi(line + tempInt); + } + else + { + if (options.verbose) puts("Parse HOST"); + while ((line[tempInt] != 0) && (line[tempInt] != ':')) + tempInt++; + line[tempInt] = 0; + strncpy(options.host, line, sizeof(options.host) -1); + if (options.verbose) printf("Host: %s\n", options.host); + tempInt++; + if (strlen(line + tempInt) > 0) + { + if (options.verbose) printf("Port: %s\n", line + tempInt); + options.port = line + tempInt; + } + } // Test the host... status = testHost(&options); + if (options.serverAddress != NULL) + { + freeaddrinfo(options.serverAddress); + options.serverAddress = NULL; + } } readLine(targetsFile, line, sizeof(line)); } Only in b/sslscan-1.8.2: sslscan-ipv6.patch