Ejemplo n.º 1
0
int np_net_ssl_init_with_hostname_version_and_cert(int sd, char *host_name, int version, char *cert, char *privkey) {
	SSL_METHOD *method = NULL;

	switch (version) {
	case 0: /* Deafult to auto negotiation */
		method = SSLv23_client_method();
		break;
	case 1: /* TLSv1 protocol */
		method = TLSv1_client_method();
		break;
	case 2: /* SSLv2 protocol */
#if defined(USE_GNUTLS) || defined(OPENSSL_NO_SSL2)
		printf(("%s\n", _("CRITICAL - SSL protocol version 2 is not supported by your SSL library.")));
		return STATE_CRITICAL;
#else
		method = SSLv2_client_method();
#endif
		break;
	case 3: /* SSLv3 protocol */
		method = SSLv3_client_method();
		break;
	default: /* Unsupported */
		printf("%s\n", _("CRITICAL - Unsupported SSL protocol version."));
		return STATE_CRITICAL;
	}
	if (!initialized) {
		/* Initialize SSL context */
		SSLeay_add_ssl_algorithms();
		SSL_load_error_strings();
		OpenSSL_add_all_algorithms();
		initialized = 1;
	}
	if ((c = SSL_CTX_new(method)) == NULL) {
		printf("%s\n", _("CRITICAL - Cannot create SSL context."));
		return STATE_CRITICAL;
	}
	if (cert && privkey) {
		SSL_CTX_use_certificate_file(c, cert, SSL_FILETYPE_PEM);
		SSL_CTX_use_PrivateKey_file(c, privkey, SSL_FILETYPE_PEM);
#ifdef USE_OPENSSL
		if (!SSL_CTX_check_private_key(c)) {
			printf ("%s\n", _("CRITICAL - Private key does not seem to match certificate!\n"));
			return STATE_CRITICAL;
		}
#endif
	}
#ifdef SSL_OP_NO_TICKET
	SSL_CTX_set_options(c, SSL_OP_NO_TICKET);
#endif
	SSL_CTX_set_mode(c, SSL_MODE_AUTO_RETRY);
	if ((s = SSL_new(c)) != NULL) {
#ifdef SSL_set_tlsext_host_name
		if (host_name != NULL)
			SSL_set_tlsext_host_name(s, host_name);
#endif
		SSL_set_fd(s, sd);
		if (SSL_connect(s) == 1) {
			return OK;
		} else {
			printf("%s\n", _("CRITICAL - Cannot make SSL connection."));
#  ifdef USE_OPENSSL /* XXX look into ERR_error_string */
			ERR_print_errors_fp(stdout);
#  endif /* USE_OPENSSL */
		}
	} else {
			printf("%s\n", _("CRITICAL - Cannot initiate SSL handshake."));
	}
	return STATE_CRITICAL;
}
Ejemplo n.º 2
0
/*
 * This function initialize one web_server handler
 */
int web_server_init(struct web_server *server,int port,const char *logfile,int flags) {
#ifdef WIN32	
	unsigned long t=IOC_INOUT;
	WSADATA WSAinfo;
	WSAStartup(2,&WSAinfo); // Damn w32 sockets
#endif

	current_web_server=server;
	server->port=port;
	server->conffile=NULL;
	server->mimefile=NULL;
	server->weblog=NULL;
	server->usessl=0;
	server->flags=flags;
	server->dataconf="";
	if((flags & WS_USEEXTCONF) == WS_USEEXTCONF) {
		if(!(web_server_setup(server,logfile))) {
#ifdef WIN32		
			WSACleanup();
#endif
			return 0;
		};
		_logfile=server->weblog; // Set current log stream
		web_log("%s using config file %s\n",_libwebserver_version,logfile);
	};
	// Create a listen socket port 'port' and listen addr (0) (all interfaces)
	server->socket=__ILWS_listensocket((short)server->port,0);	
	if(server->socket==-1) {
		LWSERR(LE_NET);
#ifdef WIN32		
		WSACleanup();
#endif
		return 0;
	};
#ifdef WIN32
	ioctlsocket(server->socket,FIONBIO,&t);  //non blocking sockets for win32
#else
	fcntl(server->socket,F_SETFL,O_NONBLOCK);
#endif
	// Setup FILE structure of logfile
	if(logfile!=NULL && !((flags & WS_USEEXTCONF) == WS_USEEXTCONF)) {
		server->logfile=__ILWS_malloc(strlen(logfile)+1);
		memcpy(server->logfile,logfile,strlen(logfile));
		server->logfile[strlen(logfile)]=0;
		server->weblog=open_weblog(logfile); // Create File stream for log
	};
	
	web_log("\n[%s] Server started at port %d (%s)\n",__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"),server->port,_libwebserver_version);
	
	// Setup Flags
	
	// openssl
#ifdef HAVE_OPENSSL	
	if((server->flags & WS_USESSL) == WS_USESSL) {
		web_log("[%s] (FLAG) Using SSL in connections\n",__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"));	
		web_log("                       +-- %s certificate file\n",server->cert_file);
		SSL_load_error_strings();
		SSLeay_add_ssl_algorithms(); 	
		server->ctx=SSL_CTX_new (SSLv23_server_method());
		if (SSL_CTX_use_certificate_file(server->ctx, server->cert_file, SSL_FILETYPE_PEM) <= 0) {
			ERR_print_errors_fp(stderr);
			exit(3);
		}
		if (SSL_CTX_use_PrivateKey_file(server->ctx, server->cert_file, SSL_FILETYPE_PEM) <= 0) {
			ERR_print_errors_fp(stderr);
			exit(4);
		}                      
	 	if (SSL_CTX_check_private_key(server->ctx)<= 0)  	 {
			ERR_print_errors_fp(stderr);
			exit(4);
		};
		server->usessl=1;
	};
#endif
	if((server->flags & WS_LOCAL) == WS_LOCAL) {
		web_log("[%s] (FLAG) Accepting only local connections\n",__ILWS_date(time(NULL),"%d/%b/%Y:%H:%M:%S %z"));	
	};
	server->client=__ILWS_init_client_list();										// Initializate client list
	server->gethandler=__ILWS_init_handler_list();									// Initializate handlers list
	web_server_addhandler(server,"* /libwebserver.gif",_web_server_logo,0,NULL);	// Add logo default handler

#ifndef WIN32	
	signal(SIGPIPE,SIG_IGN);
#endif
	return 1;
}                            
Ejemplo n.º 3
0
int main ()
{
    int err, buflen, read;

    int sd;

    struct sockaddr_in dest_sin;

    int sock;


#ifdef _WIN32
    PHOSTENT phe;

    WORD wVersionRequested;

    WSADATA wsaData;

#endif                            /*  */
    SSL_CTX *ctx;

    SSL *ssl;

    X509 *server_cert;

    char *str;

    char buf[1024];

    SSL_METHOD *meth;

    int i;

    pthread_t pid[MAX_T];

    //加载EVP cipher/digest算法
    SSLeay_add_ssl_algorithms ();

    //加载crypto/ssl错误提示
    SSL_load_error_strings ();

    //为客户端构造TLSv1 SSL_METHOD结构
    meth = SSLv3_client_method ();

    //建立新的SSL上下文
    ctx = SSL_CTX_new (meth);
    if (ctx == NULL)

    {
        printf ("ssl ctx new eer\n");
        return -1;
    }

    //加载客户端证书
    if (SSL_CTX_use_certificate_file (ctx, CLIENTCERT, SSL_FILETYPE_PEM) <= 0)

    {
        ERR_print_errors_fp (stderr);
        exit (3);
    }
    if (SSL_CTX_use_PrivateKey_file_pass (ctx, CLIENTKEY, "123456") <= 0)

    {
        ERR_print_errors_fp (stderr);
        exit (4);
    }

    //验证私钥与证书是否一致
    if (!SSL_CTX_check_private_key (ctx))

    {
        printf ("Private key does not match the certificate public key\n");
        exit (1);
    }

    //openssl是不支持多线程的,需要自己做加锁处理
    //参见:http://blog.csdn.net/jaylong35/article/details/6988690
    lock_cs = OPENSSL_malloc (CRYPTO_num_locks () * sizeof (pthread_mutex_t));
    lock_count = OPENSSL_malloc (CRYPTO_num_locks () * sizeof (long));
    for (i = 0; i < CRYPTO_num_locks (); i++)

    {
        lock_count[i] = 0;
        pthread_mutex_init (&(lock_cs[i]), NULL);
    }

    //通过这两个设置就可以解决HTTPS多线程请求出现crash的问题
    CRYPTO_set_id_callback ((unsigned long (*)()) pthreads_thread_id);
    CRYPTO_set_locking_callback ((void (*)()) pthreads_locking_callback);
    for (i = 0; i < MAX_T; i++)

    {
        err = pthread_create (&(pid[i]), NULL, &thread_main, (void *) ctx);
        if (err != 0)

        {
            printf ("pthread_create err\n");
            continue;
        }
    }
    for (i = 0; i < MAX_T; i++)

    {
        pthread_join (pid[i], NULL);
    }
    SSL_CTX_free (ctx);
    printf ("test ok\n");
    return 0;
}
Ejemplo n.º 4
0
/*
 * Retrieve URL, via the proxy in $proxyvar if necessary.
 * Modifies the string argument given.
 * Returns -1 on failure, 0 on success
 */
static int
url_get(const char *origline, const char *proxyenv, const char *outfile)
{
	char pbuf[NI_MAXSERV], hbuf[NI_MAXHOST], *cp, *portnum, *path, ststr[4];
	char *hosttail, *cause = "unknown", *newline, *host, *port, *buf = NULL;
	int error, i, isftpurl = 0, isfileurl = 0, isredirect = 0, rval = -1;
	struct addrinfo hints, *res0, *res;
	const char * volatile savefile;
	char * volatile proxyurl = NULL;
	char *cookie = NULL;
	volatile int s = -1, out;
	volatile sig_t oldintr;
	FILE *fin = NULL;
	off_t hashbytes;
	const char *errstr;
	size_t len, wlen;
#ifndef SMALL
	char *sslpath = NULL, *sslhost = NULL;
	int ishttpsurl = 0;
	SSL_CTX *ssl_ctx = NULL;
#endif /* !SMALL */
	SSL *ssl = NULL;
	int status;

	newline = strdup(origline);
	if (newline == NULL)
		errx(1, "Can't allocate memory to parse URL");
	if (strncasecmp(newline, HTTP_URL, sizeof(HTTP_URL) - 1) == 0)
		host = newline + sizeof(HTTP_URL) - 1;
	else if (strncasecmp(newline, FTP_URL, sizeof(FTP_URL) - 1) == 0) {
		host = newline + sizeof(FTP_URL) - 1;
		isftpurl = 1;
	} else if (strncasecmp(newline, FILE_URL, sizeof(FILE_URL) - 1) == 0) {
		host = newline + sizeof(FILE_URL) - 1;
		isfileurl = 1;
#ifndef SMALL
	} else if (strncasecmp(newline, HTTPS_URL, sizeof(HTTPS_URL) - 1) == 0) {
		host = newline + sizeof(HTTPS_URL) - 1;
		ishttpsurl = 1;
#endif /* !SMALL */
	} else
		errx(1, "url_get: Invalid URL '%s'", newline);

	if (isfileurl) {
		path = host;
	} else {
		path = strchr(host, '/');		/* find path */
		if (EMPTYSTRING(path)) {
			if (isftpurl)
				goto noftpautologin;
			warnx("Invalid URL (no `/' after host): %s", origline);
			goto cleanup_url_get;
		}
		*path++ = '\0';
		if (EMPTYSTRING(path)) {
			if (isftpurl)
				goto noftpautologin;
			warnx("Invalid URL (no file after host): %s", origline);
			goto cleanup_url_get;
		}
	}

	if (outfile)
		savefile = outfile;
	else
		savefile = basename(path);

#ifndef SMALL
	if (resume && (strcmp(savefile, "-") == 0)) {
		warnx("can't append to stdout");
		goto cleanup_url_get;
	}
#endif /* !SMALL */

	if (EMPTYSTRING(savefile)) {
		if (isftpurl)
			goto noftpautologin;
		warnx("Invalid URL (no file after directory): %s", origline);
		goto cleanup_url_get;
	}

	if (!isfileurl && proxyenv != NULL) {		/* use proxy */
#ifndef SMALL
		if (ishttpsurl) {
			sslpath = strdup(path);
			sslhost = strdup(host);
			if (! sslpath || ! sslhost)
				errx(1, "Can't allocate memory for https path/host.");
		}
#endif /* !SMALL */
		proxyurl = strdup(proxyenv);
		if (proxyurl == NULL)
			errx(1, "Can't allocate memory for proxy URL.");
		if (strncasecmp(proxyurl, HTTP_URL, sizeof(HTTP_URL) - 1) == 0)
			host = proxyurl + sizeof(HTTP_URL) - 1;
		else if (strncasecmp(proxyurl, FTP_URL, sizeof(FTP_URL) - 1) == 0)
			host = proxyurl + sizeof(FTP_URL) - 1;
		else {
			warnx("Malformed proxy URL: %s", proxyenv);
			goto cleanup_url_get;
		}
		if (EMPTYSTRING(host)) {
			warnx("Malformed proxy URL: %s", proxyenv);
			goto cleanup_url_get;
		}
		*--path = '/';			/* add / back to real path */
		path = strchr(host, '/');	/* remove trailing / on host */
		if (!EMPTYSTRING(path))
			*path++ = '\0';		/* i guess this ++ is useless */

		path = strchr(host, '@');	/* look for credentials in proxy */
		if (!EMPTYSTRING(path)) {
			*path++ = '\0';
			cookie = strchr(host, ':');
			if (EMPTYSTRING(cookie)) {
				warnx("Malformed proxy URL: %s", proxyenv);
				goto cleanup_url_get;
			}
			cookie  = malloc(COOKIE_MAX_LEN);
			b64_ntop(host, strlen(host), cookie, COOKIE_MAX_LEN);
			/*
			 * This removes the password from proxyenv,
			 * filling with stars
			 */
			for (host = strchr(proxyenv + 5, ':');  *host != '@';
			     host++)
				*host = '*';

			host = path;
		}
		path = newline;
	}

	if (isfileurl) {
		struct stat st;

		s = open(path, O_RDONLY);
		if (s == -1) {
			warn("Can't open file %s", path);
			goto cleanup_url_get;
		}

		if (fstat(s, &st) == -1)
			filesize = -1;
		else
			filesize = st.st_size;

		/* Open the output file.  */
		if (strcmp(savefile, "-") != 0) {
#ifndef SMALL
			if (resume)
				out = open(savefile, O_APPEND | O_WRONLY);
			else
#endif /* !SMALL */
				out = open(savefile, O_CREAT | O_WRONLY |
					O_TRUNC, 0666);
			if (out < 0) {
				warn("Can't open %s", savefile);
				goto cleanup_url_get;
			}
		} else
			out = fileno(stdout);

#ifndef SMALL
		if (resume) {
			if (fstat(out, &st) == -1) {
				warn("Can't fstat %s", savefile);
				goto cleanup_url_get;
			}
			if (lseek(s, st.st_size, SEEK_SET) == -1) {
				warn("Can't lseek %s", path);
				goto cleanup_url_get;
			}
			restart_point = st.st_size;
		}
#endif /* !SMALL */

		/* Trap signals */
		oldintr = NULL;
		if (setjmp(httpabort)) {
			if (oldintr)
				(void)signal(SIGINT, oldintr);
			goto cleanup_url_get;
		}
		oldintr = signal(SIGINT, abortfile);

		bytes = 0;
		hashbytes = mark;
		progressmeter(-1);

		if ((buf = malloc(4096)) == NULL)
			errx(1, "Can't allocate memory for transfer buffer");

		/* Finally, suck down the file. */
		i = 0;
		while ((len = read(s, buf, 4096)) > 0) {
			bytes += len;
			for (cp = buf; len > 0; len -= i, cp += i) {
				if ((i = write(out, cp, len)) == -1) {
					warn("Writing %s", savefile);
					goto cleanup_url_get;
				}
				else if (i == 0)
					break;
			}
			if (hash && !progress) {
				while (bytes >= hashbytes) {
					(void)putc('#', ttyout);
					hashbytes += mark;
				}
				(void)fflush(ttyout);
			}
		}
		if (hash && !progress && bytes > 0) {
			if (bytes < mark)
				(void)putc('#', ttyout);
			(void)putc('\n', ttyout);
			(void)fflush(ttyout);
		}
		if (len != 0) {
			warn("Reading from file");
			goto cleanup_url_get;
		}
		progressmeter(1);
		if (verbose)
			fputs("Successfully retrieved file.\n", ttyout);
		(void)signal(SIGINT, oldintr);

		rval = 0;
		goto cleanup_url_get;
	}

	if (*host == '[' && (hosttail = strrchr(host, ']')) != NULL &&
	    (hosttail[1] == '\0' || hosttail[1] == ':')) {
		host++;
		*hosttail++ = '\0';
	} else
		hosttail = host;

	portnum = strrchr(hosttail, ':');		/* find portnum */
	if (portnum != NULL)
		*portnum++ = '\0';

#ifndef SMALL
	if (debug)
		fprintf(ttyout, "host %s, port %s, path %s, save as %s.\n",
		    host, portnum, path, savefile);
#endif /* !SMALL */

	memset(&hints, 0, sizeof(hints));
	hints.ai_family = family;
	hints.ai_socktype = SOCK_STREAM;
#ifndef SMALL
	port = portnum ? portnum : (ishttpsurl ? httpsport : httpport);
#else /* !SMALL */
	port = portnum ? portnum : httpport;
#endif /* !SMALL */
	error = getaddrinfo(host, port, &hints, &res0);
	/*
	 * If the services file is corrupt/missing, fall back
	 * on our hard-coded defines.
	 */
	if (error == EAI_SERVICE && port == httpport) {
		snprintf(pbuf, sizeof(pbuf), "%d", HTTP_PORT);
		error = getaddrinfo(host, pbuf, &hints, &res0);
#ifndef SMALL
	} else if (error == EAI_SERVICE && port == httpsport) {
		snprintf(pbuf, sizeof(pbuf), "%d", HTTPS_PORT);
		error = getaddrinfo(host, pbuf, &hints, &res0);
#endif /* !SMALL */
	}
	if (error) {
		warnx("%s: %s", gai_strerror(error), host);
		goto cleanup_url_get;
	}

	s = -1;
	for (res = res0; res; res = res->ai_next) {
		if (getnameinfo(res->ai_addr, res->ai_addrlen, hbuf,
		    sizeof(hbuf), NULL, 0, NI_NUMERICHOST) != 0)
			strlcpy(hbuf, "(unknown)", sizeof(hbuf));
		if (verbose)
			fprintf(ttyout, "Trying %s...\n", hbuf);

		s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
		if (s == -1) {
			cause = "socket";
			continue;
		}

again:
		if (connect(s, res->ai_addr, res->ai_addrlen) < 0) {
			int save_errno;

			if (errno == EINTR)
				goto again;
			save_errno = errno;
			close(s);
			errno = save_errno;
			s = -1;
			cause = "connect";
			continue;
		}

		/* get port in numeric */
		if (getnameinfo(res->ai_addr, res->ai_addrlen, NULL, 0,
		    pbuf, sizeof(pbuf), NI_NUMERICSERV) == 0)
			port = pbuf;
		else
			port = NULL;

#ifndef SMALL
		if (proxyenv && sslhost)
			proxy_connect(s, sslhost);
#endif /* !SMALL */
		break;
	}
	freeaddrinfo(res0);
	if (s < 0) {
		warn("%s", cause);
		goto cleanup_url_get;
	}

#ifndef SMALL
	if (ishttpsurl) {
		if (proxyenv && sslpath) {
			ishttpsurl = 0;
			proxyurl = NULL;
			path = sslpath;
		}
		SSL_library_init();
		SSL_load_error_strings();
		SSLeay_add_ssl_algorithms();
		ssl_ctx = SSL_CTX_new(SSLv23_client_method());
		ssl = SSL_new(ssl_ctx);
		if (ssl == NULL || ssl_ctx == NULL) {
			ERR_print_errors_fp(ttyout);
			goto cleanup_url_get;
		}
		if (SSL_set_fd(ssl, s) == 0) {
			ERR_print_errors_fp(ttyout);
			goto cleanup_url_get;
		}
		if (SSL_connect(ssl) <= 0) {
			ERR_print_errors_fp(ttyout);
			goto cleanup_url_get;
		}
	} else {
		fin = fdopen(s, "r+");
	}
#else /* !SMALL */
	fin = fdopen(s, "r+");
#endif /* !SMALL */

	if (verbose)
		fprintf(ttyout, "Requesting %s", origline);
	/*
	 * Construct and send the request. Proxy requests don't want leading /.
	 */
#ifndef SMALL
	cookie_get(host, path, ishttpsurl, &buf);
#endif /* !SMALL */
	if (proxyurl) {
		if (verbose)
			fprintf(ttyout, " (via %s)\n", proxyenv);
		/*
		 * Host: directive must use the destination host address for
		 * the original URI (path).  We do not attach it at this moment.
		 */
		if (cookie)
			ftp_printf(fin, ssl, "GET %s HTTP/1.0\r\n"
			    "Proxy-Authorization: Basic %s%s\r\n%s\r\n\r\n",
			    path, cookie, buf ? buf : "", HTTP_USER_AGENT);
		else
			ftp_printf(fin, ssl, "GET %s HTTP/1.0\r\n%s%s\r\n\r\n",
			    path, buf ? buf : "", HTTP_USER_AGENT);

	} else {
		ftp_printf(fin, ssl, "GET /%s %s\r\nHost: ", path,
#ifndef SMALL
			resume ? "HTTP/1.1" :
#endif /* !SMALL */
			"HTTP/1.0");
		if (strchr(host, ':')) {
			char *h, *p;

			/*
			 * strip off scoped address portion, since it's
			 * local to node
			 */
			h = strdup(host);
			if (h == NULL)
				errx(1, "Can't allocate memory.");
			if ((p = strchr(h, '%')) != NULL)
				*p = '\0';
			ftp_printf(fin, ssl, "[%s]", h);
			free(h);
		} else
			ftp_printf(fin, ssl, "%s", host);

		/*
		 * Send port number only if it's specified and does not equal
		 * 80. Some broken HTTP servers get confused if you explicitly
		 * send them the port number.
		 */
#ifndef SMALL
		if (port && strcmp(port, (ishttpsurl ? "443" : "80")) != 0)
			ftp_printf(fin, ssl, ":%s", port);
		if (resume) {
			int ret;
			struct stat stbuf;

			ret = stat(savefile, &stbuf);
			if (ret < 0) {
				if (verbose)
					fprintf(ttyout, "\n");
				warn("Can't open %s", savefile);
				goto cleanup_url_get;
			}
			restart_point = stbuf.st_size;
			ftp_printf(fin, ssl, "\r\nRange: bytes=%lld-",
				(long long)restart_point);
		}
#else /* !SMALL */
		if (port && strcmp(port, "80") != 0)
			ftp_printf(fin, ssl, ":%s", port);
#endif /* !SMALL */
		ftp_printf(fin, ssl, "\r\n%s%s\r\n\r\n",
		    buf ? buf : "", HTTP_USER_AGENT);
		if (verbose)
			fprintf(ttyout, "\n");
	}


#ifndef SMALL
	free(buf);
#endif /* !SMALL */
	buf = NULL;

	if (fin != NULL && fflush(fin) == EOF) {
		warn("Writing HTTP request");
		goto cleanup_url_get;
	}
	if ((buf = ftp_readline(fin, ssl, &len)) == NULL) {
		warn("Receiving HTTP reply");
		goto cleanup_url_get;
	}

	while (len > 0 && (buf[len-1] == '\r' || buf[len-1] == '\n'))
		buf[--len] = '\0';
#ifndef SMALL
	if (debug)
		fprintf(ttyout, "received '%s'\n", buf);
#endif /* !SMALL */

	cp = strchr(buf, ' ');
	if (cp == NULL)
		goto improper;
	else
		cp++;

	strlcpy(ststr, cp, sizeof(ststr));
	status = strtonum(ststr, 200, 416, &errstr);
	if (errstr) {
		warnx("Error retrieving file: %s", cp);
		goto cleanup_url_get;
	}

	switch (status) {
	case 200:	/* OK */
#ifndef SMALL
	case 206:	/* Partial Content */
		break;
#endif /* !SMALL */
	case 301:	/* Moved Permanently */
	case 302:	/* Found */
	case 303:	/* See Other */
	case 307:	/* Temporary Redirect */
		isredirect++;
		if (redirect_loop++ > 10) {
			warnx("Too many redirections requested");
			goto cleanup_url_get;
		}
		break;
#ifndef SMALL
	case 416:	/* Requested Range Not Satisfiable */
		warnx("File is already fully retrieved.");
		goto cleanup_url_get;
#endif /* !SMALL */
	default:
		warnx("Error retrieving file: %s", cp);
		goto cleanup_url_get;
	}

	/*
	 * Read the rest of the header.
	 */
	free(buf);
	filesize = -1;

	for (;;) {
		if ((buf = ftp_readline(fin, ssl, &len)) == NULL) {
			warn("Receiving HTTP reply");
			goto cleanup_url_get;
		}

		while (len > 0 && (buf[len-1] == '\r' || buf[len-1] == '\n'))
			buf[--len] = '\0';
		if (len == 0)
			break;
#ifndef SMALL
		if (debug)
			fprintf(ttyout, "received '%s'\n", buf);
#endif /* !SMALL */

		/* Look for some headers */
		cp = buf;
#define CONTENTLEN "Content-Length: "
		if (strncasecmp(cp, CONTENTLEN, sizeof(CONTENTLEN) - 1) == 0) {
			cp += sizeof(CONTENTLEN) - 1;
			filesize = strtonum(cp, 0, LLONG_MAX, &errstr);
			if (errstr != NULL)
				goto improper;
#ifndef SMALL
			if (resume)
				filesize += restart_point;
#endif /* !SMALL */
#define LOCATION "Location: "
		} else if (isredirect &&
		    strncasecmp(cp, LOCATION, sizeof(LOCATION) - 1) == 0) {
			cp += sizeof(LOCATION) - 1;
			if (verbose)
				fprintf(ttyout, "Redirected to %s\n", cp);
			if (fin != NULL)
				fclose(fin);
			else if (s != -1)
				close(s);
			free(proxyurl);
			free(newline);
			rval = url_get(cp, proxyenv, outfile);
			free(buf);
			return (rval);
		}
	}

	/* Open the output file.  */
	if (strcmp(savefile, "-") != 0) {
#ifndef SMALL
		if (resume)
			out = open(savefile, O_APPEND | O_WRONLY);
		else
#endif /* !SMALL */
			out = open(savefile, O_CREAT | O_WRONLY | O_TRUNC,
				0666);
		if (out < 0) {
			warn("Can't open %s", savefile);
			goto cleanup_url_get;
		}
	} else
		out = fileno(stdout);

	/* Trap signals */
	oldintr = NULL;
	if (setjmp(httpabort)) {
		if (oldintr)
			(void)signal(SIGINT, oldintr);
		goto cleanup_url_get;
	}
	oldintr = signal(SIGINT, aborthttp);

	bytes = 0;
	hashbytes = mark;
	progressmeter(-1);

	free(buf);

	/* Finally, suck down the file. */
	if ((buf = malloc(4096)) == NULL)
		errx(1, "Can't allocate memory for transfer buffer");
	i = 0;
	len = 1;
	while (len > 0) {
		len = ftp_read(fin, ssl, buf, 4096);
		bytes += len;
		for (cp = buf, wlen = len; wlen > 0; wlen -= i, cp += i) {
			if ((i = write(out, cp, wlen)) == -1) {
				warn("Writing %s", savefile);
				goto cleanup_url_get;
			}
			else if (i == 0)
				break;
		}
		if (hash && !progress) {
			while (bytes >= hashbytes) {
				(void)putc('#', ttyout);
				hashbytes += mark;
			}
			(void)fflush(ttyout);
		}
	}
	if (hash && !progress && bytes > 0) {
		if (bytes < mark)
			(void)putc('#', ttyout);
		(void)putc('\n', ttyout);
		(void)fflush(ttyout);
	}
	if (len != 0) {
		warn("Reading from socket");
		goto cleanup_url_get;
	}
	progressmeter(1);
	if (
#ifndef SMALL
		!resume &&
#endif /* !SMALL */
		filesize != -1 && len == 0 && bytes != filesize) {
		if (verbose)
			fputs("Read short file.\n", ttyout);
		goto cleanup_url_get;
	}

	if (verbose)
		fputs("Successfully retrieved file.\n", ttyout);
	(void)signal(SIGINT, oldintr);

	rval = 0;
	goto cleanup_url_get;

noftpautologin:
	warnx(
	    "Auto-login using ftp URLs isn't supported when using $ftp_proxy");
	goto cleanup_url_get;

improper:
	warnx("Improper response from %s", host);

cleanup_url_get:
#ifndef SMALL
	if (ssl) {
		SSL_shutdown(ssl);
		SSL_free(ssl);
	}
#endif /* !SMALL */
	if (fin != NULL)
		fclose(fin);
	else if (s != -1)
		close(s);
	free(buf);
	free(proxyurl);
	free(newline);
	return (rval);
}
Ejemplo n.º 5
0
/* OS dependent */
Boolean rocs_socket_connect( iOSocket inst ) {
#ifdef __ROCS_SOCKET__
    iOSocketData o = Data(inst);
    struct sockaddr_in srvaddr;
    struct in_addr* addr = o->hostaddr;
    int rc = 0;

    if( o->sh == 0 )
        rocs_socket_create( o );

    if( o->sh == 0 )
        return False;

    if( !rocs_socket_resolveHost( o ) )
        return False;

    addr = o->hostaddr;

    memset( &srvaddr,0, sizeof( struct sockaddr_in ) );
    srvaddr.sin_family = AF_INET;
    srvaddr.sin_port   = htons( (u_short)o->port );
    srvaddr.sin_addr   = *addr;

    rc = connect( o->sh, (struct sockaddr *)&srvaddr, sizeof( struct sockaddr_in ) );

    if( rc == -1 ) {
        o->rc = WSAGetLastError();
        TraceOp.trc( name, TRCLEVEL_EXCEPTION, __LINE__, 9999, "connect(%s:%d) failed [%d]",
                     o->host, o->port , WSAGetLastError() );
        o->connected = False;
        return False;
    }
    o->connected = True;
    TraceOp.trc( name, TRCLEVEL_DEBUG, __LINE__, 9999, "socket connected." );

    if( o->ssl ) {
#ifdef __OPENSSL__
        SSL_METHOD* meth;
        X509*       server_cert;

        o->openssl_support = True;

        SSLeay_add_ssl_algorithms();
        meth = SSLv3_client_method();
        SSL_load_error_strings();
        o->ssl_ctx = SSL_CTX_new (meth);

        TraceOp.trc( name, TRCLEVEL_INFO, __LINE__, 9999, "OpenSSL support.(v%d)", meth->version );

        o->ssl_sh = SSL_new( o->ssl_ctx );
        if( o->ssl_sh != NULL ) {
            SSL_set_fd( o->ssl_sh, o->sh );
            rc = SSL_connect( o->ssl_sh );
            if( rc <= 0 ) {
                char err[256] = {'\0'};
                rc = ERR_peek_error();
                ERR_error_string_n( (unsigned long) rc, err, sizeof(err) );

                TraceOp.trc( name, TRCLEVEL_EXCEPTION, __LINE__, 9999, "SSL_connect() failed [%d] %s", rc, err );
                o->connected = False;
                o->openssl_support = False;
                return False;
            }

            /* Trace some info. */
            TraceOp.trc( name, TRCLEVEL_INFO, __LINE__, 9999, "SSL connection using %s", SSL_get_cipher( o->ssl_sh ) );

            server_cert = SSL_get_peer_certificate( o->ssl_sh );
            if( server_cert != NULL ) {
                char* sub = NULL;
                char* iss = NULL;

                sub = X509_NAME_oneline( X509_get_subject_name( server_cert ), 0, 0 );
                iss = X509_NAME_oneline( X509_get_issuer_name ( server_cert ), 0, 0 );

                TraceOp.trc( name, TRCLEVEL_INFO, __LINE__, 9999,
                             "SSL Server certificate subject = %s, issuer = %s", sub, iss );
                free( sub );
                free( iss );
            }

        }
#else
        TraceOp.trc( name, TRCLEVEL_EXCEPTION, __LINE__, 9999, "SSL requested but not supported! Compile with __OPENSSL__ defined." );
        return False;
#endif
    }

#endif
    return True;
}
Ejemplo n.º 6
0
status_t SSO::SSLSend(const char *host, HTTPFormatter *send, HTTPFormatter **recv) {
	int err = B_OK;
	int sd;
	struct sockaddr_in sa;
	struct hostent *hp;
	SSL_CTX *ctx;
	SSL *ssl;
	char buffer[1024];
	SSL_METHOD *meth;

	SSL_load_error_strings();
	SSLeay_add_ssl_algorithms();
	meth = SSLv23_client_method();
	ctx = SSL_CTX_new (meth);
	CHK_NULL(ctx);
	SSL_CTX_set_options(ctx, SSL_OP_ALL);

	/* ----------------------------------------------- */
	/* Create a socket and connect to server using normal socket calls. */
	sd = socket (AF_INET, SOCK_STREAM, 0);
	CHK_ERR(sd, "socket");

	// clear sa
	memset (&sa, '\0', sizeof(sa));
	
	// get address
	if ((hp= gethostbyname(host)) == NULL) { 
		sa.sin_addr.s_addr = inet_addr (host);   /* Server IP */
	} else {
		memcpy((char *)&sa.sin_addr,hp->h_addr,hp->h_length); /* set address */
	};
	
	sa.sin_family = AF_INET;
	sa.sin_port = htons(443);    /* Server Port number */
	
	err = connect(sd, (struct sockaddr*) &sa, sizeof(sa));
	CHK_ERR(err, "connect");
	
	/* ----------------------------------------------- */
	/* Now we have TCP conncetion. Start SSL negotiation. */
  
	ssl = SSL_new (ctx);                         CHK_NULL(ssl);    
	if (SSL_set_fd(ssl, sd) == 0) {
		LOG(kProtocolName, liDebug, "C %lX: SSL Error setting fd", this);
		return -1;
	};
	
    SSL_set_verify(ssl, SSL_VERIFY_NONE, NULL);
	SSL_set_connect_state(ssl);
	
	err = SSL_connect (ssl);
	CHK_SSL(err);
	
	/* --------------------------------------------------- */
	/* DATA EXCHANGE - Send a message and receive a reply. */

	err = SSL_write(ssl, send->Flatten(), send->Length());
	CHK_SSL(err);
	
	if (err <= 0) {
		LOG(kProtocolName, liDebug, "C %lX: SSL Error writing. Err: %ld", this, SSL_get_error(ssl, err));
	};
	
	BString data;
	int received = 0;
	while (err > 0) {
		err = SSL_read(ssl, buffer, sizeof(buffer));
		CHK_SSL(err);
		if (err > 0) {
			received += err;
			data.Append(buffer, err);
			memset(buffer, 0, sizeof(buffer));
		};
	};

	*recv = new HTTPFormatter(data.String(), data.Length());
	LOG(kProtocolName, liDebug, "C %lX: Got %d chars", this, received);
	SSL_shutdown (ssl);  /* send SSL/TLS close_notify */
	
	/* Clean up. */
	close (sd);
	SSL_free (ssl);
	SSL_CTX_free (ctx);
	
	return received;
};
Ejemplo n.º 7
0
void rocksock_init_ssl(void) {
	SSL_library_init();
	SSL_load_error_strings();
	SSLeay_add_ssl_algorithms();
}
Ejemplo n.º 8
0
void main ()
{
  int err;
  int listen_sd;
  int sd;
  struct sockaddr_in sa_serv;
  struct sockaddr_in sa_cli;
  size_t client_len;
  SSL_CTX* ctx;
  SSL*     ssl;
  X509*    client_cert;
  char*    str;
  char     buf [4096];
  SSL_METHOD *meth;
  
  /* SSL preliminaries. We keep the certificate and key with the context. */

  SSL_load_error_strings();
  SSLeay_add_ssl_algorithms();
  meth = SSLv23_server_method();
  ctx = SSL_CTX_new (meth);
  if (!ctx) {
    ERR_print_errors_fp(stderr);
    exit(2);
  }
  
  if (SSL_CTX_use_certificate_file(ctx, CERTF, SSL_FILETYPE_PEM) <= 0) {
    ERR_print_errors_fp(stderr);
    exit(3);
  }
  if (SSL_CTX_use_PrivateKey_file(ctx, KEYF, SSL_FILETYPE_PEM) <= 0) {
    ERR_print_errors_fp(stderr);
    exit(4);
  }

  if (!SSL_CTX_check_private_key(ctx)) {
    fprintf(stderr,"Private key does not match the certificate public key\n");
    exit(5);
  }

  /* ----------------------------------------------- */
  /* Prepare TCP socket for receiving connections */

  listen_sd = socket (AF_INET, SOCK_STREAM, 0);   CHK_ERR(listen_sd, "socket");
  
  memset (&sa_serv, '\0', sizeof(sa_serv));
  sa_serv.sin_family      = AF_INET;
  sa_serv.sin_addr.s_addr = INADDR_ANY;
  sa_serv.sin_port        = htons (1111);          /* Server Port number */
  
  err = bind(listen_sd, (struct sockaddr*) &sa_serv,
	     sizeof (sa_serv));                   CHK_ERR(err, "bind");
	     
  /* Receive a TCP connection. */
	     
  err = listen (listen_sd, 5);                    CHK_ERR(err, "listen");
  
  client_len = sizeof(sa_cli);
  sd = accept (listen_sd, (struct sockaddr*) &sa_cli, &client_len);
  CHK_ERR(sd, "accept");
  close (listen_sd);

  printf ("Connection from %lx, port %x\n",
	  sa_cli.sin_addr.s_addr, sa_cli.sin_port);
  
  /* ----------------------------------------------- */
  /* TCP connection is ready. Do server side SSL. */

  ssl = SSL_new (ctx);                           CHK_NULL(ssl);
  SSL_set_fd (ssl, sd);
  err = SSL_accept (ssl);                        CHK_SSL(err);
  
  /* Get the cipher - opt */
  
  printf ("SSL connection using %s\n", SSL_get_cipher (ssl));
  
  /* Get client's certificate (note: beware of dynamic allocation) - opt */

  client_cert = SSL_get_peer_certificate (ssl);
  if (client_cert != NULL) {
    printf ("Client certificate:\n");
    
    str = X509_NAME_oneline (X509_get_subject_name (client_cert), 0, 0);
    CHK_NULL(str);
    printf ("\t subject: %s\n", str);
    OPENSSL_free (str);
    
    str = X509_NAME_oneline (X509_get_issuer_name  (client_cert), 0, 0);
    CHK_NULL(str);
    printf ("\t issuer: %s\n", str);
    OPENSSL_free (str);
    
    /* We could do all sorts of certificate verification stuff here before
       deallocating the certificate. */
    
    X509_free (client_cert);
  } else
    printf ("Client does not have certificate.\n");

  /* DATA EXCHANGE - Receive message and send reply. */

  err = SSL_read (ssl, buf, sizeof(buf) - 1);                   CHK_SSL(err);
  buf[err] = '\0';
  printf ("Got %d chars:'%s'\n", err, buf);
  
  err = SSL_write (ssl, "I hear you.", strlen("I hear you."));  CHK_SSL(err);

  /* Clean up. */

  close (sd);
  SSL_free (ssl);
  SSL_CTX_free (ctx);
}
Ejemplo n.º 9
0
/* The program expects at most four arguments: host in IP format, port
 * number to connect to, proxy in IP format and proxy port number.
 * If last two are specified, host can be in any format proxy will
 * understand (since this is an example for SSL programming, host name
 * resolving code is left out).
 *
 * Default values are "127.0.0.1", 443. If any proxy parameter is
 * omitted, the program will connect directly to the host.
 */
int main(int argc, char *argv[])
{
	char buffer[4096]; /* This should be dynamically allocated */
	const char *request = "GET / HTTP/1.0\r\n\r\n";
	BOOL is_ok = FALSE;
	X509 *server_cert;
	SSL_CTX *ctx;
	BIO *bio_err;
	SSL *ssl;

	if (Init())
	{
		/* Basic intialization. Next few steps (up to SSL_new()) need
		 * to be done only once per AmiSSL opener.
		 */
		SSLeay_add_ssl_algorithms();
		SSL_load_error_strings();

		/* Note: BIO writing routines are prepared for NULL BIO handle */
		if((bio_err = BIO_new(BIO_s_file())) != NULL)
			BIO_set_fp_amiga(bio_err, GetStdErr(), BIO_NOCLOSE | BIO_FP_TEXT);

		/* Get a new SSL context */
		if((ctx = SSL_CTX_new(SSLv23_client_method())) != NULL)
		{
			/* Basic certificate handling. OpenSSL documentation has more
			 * information on this.
			 */
			SSL_CTX_set_default_verify_paths(ctx);
			SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
			                   NULL);

			/* The following needs to be done once per socket */
			if((ssl = SSL_new(ctx)) != NULL)
			{
				int sock;

				/* Connect to the HTTPS server, directly or through a proxy */
				if (argc > 4)
					sock = ConnectToServer(argv[1], atol(argv[2]), argv[3],
					                       atol(argv[4]));
				else
					sock = ConnectToServer(argv[1] ? argv[1] : (char *)"127.0.0.1",
					                       argc > 2 ? atol(argv[2]) : 443,
					                       NULL, 0);

				/* Check if connection was established */
				if (sock >= 0)
				{
					int ssl_err = 0;

					/* Associate the socket with the ssl structure */
					SSL_set_fd(ssl, sock);

					/* Perform SSL handshake */
					if((ssl_err = SSL_connect(ssl)) >= 0)
					{
						Printf("SSL connection using %s\n", SSL_get_cipher(ssl));

						/* Certificate checking. This example is *very* basic */
						if((server_cert = SSL_get_peer_certificate(ssl)))
						{
							char *str;

							Printf("Server certificate:\n");

							if((str = X509_NAME_oneline(X509_get_subject_name(server_cert), 0, 0)))
							{
								Printf("\tSubject: %s\n", str);
								OPENSSL_free(str);
							}
							else
								FPrintf(GetStdErr(), "Warning: couldn't read subject name in certificate!\n");

							if((str = X509_NAME_oneline(X509_get_issuer_name(server_cert),
							                            0, 0)) != NULL)
							{
								Printf("\tIssuer: %s\n", str);
								OPENSSL_free(str);
							}
							else
								FPrintf(GetStdErr(), "Warning: couldn't read issuer name in certificate!\n");

							X509_free(server_cert);

							/* Send a HTTP request. Again, this is just
							 * a very basic example.
							 */
							if ((ssl_err = SSL_write(ssl, request, strlen(request)))
							    > 0)
							{
								/* Dump everything to output */
								while ((ssl_err = SSL_read(ssl, buffer,
								                           sizeof(buffer) - 1))
								       > 0)
									FWrite(Output(), buffer, ssl_err, 1);

								FFlush(Output());

								/* This is not entirely true, check
								 * the SSL_read documentation
								 */
								is_ok = ssl_err == 0;
							}
							else
								FPrintf(GetStdErr(), "Couldn't write request!\n");
						}
						else
							FPrintf(GetStdErr(), "Couldn't get server certificate!\n");
					}
					else
						FPrintf(GetStdErr(), "Couldn't establish SSL connection!\n");

					/* If there were errors, print them */
					if (ssl_err < 0)
						ERR_print_errors(bio_err);

					/* Send SSL close notification and close the socket */
					SSL_shutdown(ssl);
					CloseSocket(sock);
				}
				else
					FPrintf(GetStdErr(), "Couldn't connect to host!\n");

        
			  FPrintf(GetStdErr(), "before SSL_free()\n");
				SSL_free(ssl);
			}
			else
				FPrintf(GetStdErr(), "Couldn't create new SSL handle!\n");

			FPrintf(GetStdErr(), "before SSL_CTX_free()\n");
			SSL_CTX_free(ctx);
		}
		else
			FPrintf(GetStdErr(), "Couldn't create new context!\n");

	  FPrintf(GetStdErr(), "before Cleanup()\n");
		Cleanup();
	}

	FPrintf(GetStdErr(), "before end of main()\n");
	return(is_ok ? RETURN_OK : RETURN_ERROR);
}
Ejemplo n.º 10
0
int main(int argc, char **argv){
	int result=OK;
	int x;
	char buffer[MAX_INPUT_BUFFER];
	char *env_string=NULL;
#ifdef HAVE_SSL
	DH *dh;
	char seedfile[FILENAME_MAX];
	int i,c;
#endif

	/* set some environment variables */
	asprintf(&env_string,"NRPE_MULTILINESUPPORT=1");
	putenv(env_string);
	asprintf(&env_string,"NRPE_PROGRAMVERSION=%s",PROGRAM_VERSION);
	putenv(env_string);

	/* process command-line args */
	result=process_arguments(argc,argv);

        if(result!=OK || show_help==TRUE || show_license==TRUE || show_version==TRUE){

		printf("\n");
		printf("NRPE - Nagios Remote Plugin Executor\n");
		printf("Copyright (c) 1999-2008 Ethan Galstad ([email protected])\n");
		printf("Version: %s\n",PROGRAM_VERSION);
		printf("Last Modified: %s\n",MODIFICATION_DATE);
		printf("License: GPL v2 with exemptions (-l for more info)\n");
#ifdef HAVE_SSL
		printf("SSL/TLS Available: Anonymous DH Mode, OpenSSL 0.9.6 or higher required\n");
#endif
#ifdef HAVE_LIBWRAP
		printf("TCP Wrappers Available\n");
#endif
		printf("\n");
#ifdef ENABLE_COMMAND_ARGUMENTS
		printf("***************************************************************\n");
		printf("** POSSIBLE SECURITY RISK - COMMAND ARGUMENTS ARE SUPPORTED! **\n");
		printf("**      Read the NRPE SECURITY file for more information     **\n");
		printf("***************************************************************\n");
		printf("\n");
#endif
#ifndef HAVE_LIBWRAP
		printf("***************************************************************\n");
		printf("** POSSIBLE SECURITY RISK - TCP WRAPPERS ARE NOT AVAILABLE!  **\n");
		printf("**      Read the NRPE SECURITY file for more information     **\n");
		printf("***************************************************************\n");
		printf("\n");
#endif
	        }

	if(show_license==TRUE)
		display_license();

	else if(result!=OK || show_help==TRUE){

		printf("Usage: nrpe [-n] -c <config_file> <mode>\n");
		printf("\n");
		printf("Options:\n");
		printf(" -n            = Do not use SSL\n");
		printf(" <config_file> = Name of config file to use\n");
		printf(" <mode>        = One of the following operating modes:\n");  
		printf("   -i          =    Run as a service under inetd or xinetd\n");
		printf("   -d          =    Run as a standalone daemon\n");
		/* Updates help section to indicate how to start under SRC on AIX */
		printf("   -d -s       =    Run as a subsystem under AIX\n");        
		printf("\n");
		printf("Notes:\n");
		printf("This program is designed to process requests from the check_nrpe\n");
		printf("plugin on the host(s) running Nagios.  It can run as a service\n");
		printf("under inetd or xinetd (read the docs for info on this), or as a\n");
		printf("standalone daemon. Once a request is received from an authorized\n");
		printf("host, NRPE will execute the command/plugin (as defined in the\n");
		printf("config file) and return the plugin output and return code to the\n");
		printf("check_nrpe plugin.\n");
		printf("\n");
		}

        if(result!=OK || show_help==TRUE || show_license==TRUE || show_version==TRUE)
		exit(STATE_UNKNOWN);


	/* open a connection to the syslog facility */
	/* facility name may be overridden later */
	get_log_facility(NRPE_LOG_FACILITY);
        openlog("nrpe",LOG_PID,log_facility); 

	/* make sure the config file uses an absolute path */
	if(config_file[0]!='/'){

		/* save the name of the config file */
		strncpy(buffer,config_file,sizeof(buffer));
		buffer[sizeof(buffer)-1]='\x0';

		/* get absolute path of current working directory */
		strcpy(config_file,"");
		getcwd(config_file,sizeof(config_file));

		/* append a forward slash */
		strncat(config_file,"/",sizeof(config_file)-2);
		config_file[sizeof(config_file)-1]='\x0';

		/* append the config file to the path */
		strncat(config_file,buffer,sizeof(config_file)-strlen(config_file)-1);
		config_file[sizeof(config_file)-1]='\x0';
	        }

	/* read the config file */
	result=read_config_file(config_file);	

	/* exit if there are errors... */
	if(result==ERROR){
		syslog(LOG_ERR,"Config file '%s' contained errors, aborting...",config_file);
		return STATE_CRITICAL;
		}

        /* generate the CRC 32 table */
        generate_crc32_table();

	/* initialize macros */
	for(x=0;x<MAX_COMMAND_ARGUMENTS;x++)
		macro_argv[x]=NULL;

#ifdef HAVE_SSL
	/* initialize SSL */
	if(use_ssl==TRUE){
		SSL_library_init();
		SSLeay_add_ssl_algorithms();
		meth=SSLv23_server_method();
		SSL_load_error_strings();

		/* use week random seed if necessary */
		if(allow_weak_random_seed && (RAND_status()==0)){

			if(RAND_file_name(seedfile,sizeof(seedfile)-1))
				if(RAND_load_file(seedfile,-1))
					RAND_write_file(seedfile);

			if(RAND_status()==0){
				syslog(LOG_ERR,"Warning: SSL/TLS uses a weak random seed which is highly discouraged");
				srand(time(NULL));
				for(i=0;i<500 && RAND_status()==0;i++){
					for(c=0;c<sizeof(seedfile);c+=sizeof(int)){
						*((int *)(seedfile+c))=rand();
					        }
					RAND_seed(seedfile,sizeof(seedfile));
					}
				}
			}

		if((ctx=SSL_CTX_new(meth))==NULL){
			syslog(LOG_ERR,"Error: could not create SSL context.\n");
			exit(STATE_CRITICAL);
		        }

		/* ADDED 01/19/2004 */
		/* use only TLSv1 protocol */
		SSL_CTX_set_options(ctx,SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);

		/* use anonymous DH ciphers */
		SSL_CTX_set_cipher_list(ctx,"ADH");
		dh=get_dh512();
		SSL_CTX_set_tmp_dh(ctx,dh);
		DH_free(dh);
		if(debug==TRUE)
			syslog(LOG_INFO,"INFO: SSL/TLS initialized. All network traffic will be encrypted.");
	        }
	else{
		if(debug==TRUE)
			syslog(LOG_INFO,"INFO: SSL/TLS NOT initialized. Network encryption DISABLED.");
	        }
#endif

	/* if we're running under inetd... */
	if(use_inetd==TRUE){

		/* make sure we're not root */
		check_privileges();

		/* redirect STDERR to /dev/null */
		close(2);
		open("/dev/null",O_WRONLY);

		/* handle the connection */
		handle_connection(0);
	        }

	/* if we're running under SRC... 
	   we don't fork but does drop-privileges*/
	else if (use_src==TRUE){

		/* close standard file descriptors */
		close(0);
		close(1);
		close(2);

		/* redirect standard descriptors to /dev/null */
		open("/dev/null",O_RDONLY);
		open("/dev/null",O_WRONLY);
		open("/dev/null",O_WRONLY);

		chdir("/");
		/*umask(0);*/

		/* handle signals */
		signal(SIGQUIT,sighandler);
		signal(SIGTERM,sighandler);
		signal(SIGHUP,sighandler);

		/* log info to syslog facility */
		syslog(LOG_NOTICE,"Starting up daemon");

		/* write pid file */
		if(write_pid_file()==ERROR)
			return STATE_CRITICAL;

		/* drop privileges */
		drop_privileges(nrpe_user,nrpe_group);

		/* make sure we're not root */
		check_privileges();

		do{

			/* reset flags */
			sigrestart=FALSE;
			sigshutdown=FALSE;

			/* wait for connections */
			wait_for_connections();

			/* free all memory we allocated */
			free_memory();
			
			if(sigrestart==TRUE){

				/* read the config file */
				result=read_config_file(config_file);	

				/* exit if there are errors... */
				if(result==ERROR){
					syslog(LOG_ERR,"Config file '%s' contained errors, bailing out...",config_file);
					return STATE_CRITICAL;
				        }
			        }

		        }while(sigrestart==TRUE && sigshutdown==FALSE);

		/* remove pid file */
		remove_pid_file();

		syslog(LOG_NOTICE,"Daemon shutdown\n");
	        }            


	/* else daemonize and start listening for requests... */
	else if(fork()==0){
		
		/* we're a daemon - set up a new process group */
		setsid();

		/* close standard file descriptors */
		close(0);
		close(1);
		close(2);

		/* redirect standard descriptors to /dev/null */
		open("/dev/null",O_RDONLY);
		open("/dev/null",O_WRONLY);
		open("/dev/null",O_WRONLY);

		chdir("/");
		/*umask(0);*/

		/* handle signals */
		signal(SIGQUIT,sighandler);
		signal(SIGTERM,sighandler);
		signal(SIGHUP,sighandler);

		/* log info to syslog facility */
		syslog(LOG_NOTICE,"Starting up daemon");

		/* write pid file */
		if(write_pid_file()==ERROR)
			return STATE_CRITICAL;
		
		/* drop privileges */
		drop_privileges(nrpe_user,nrpe_group);

		/* make sure we're not root */
		check_privileges();

		do{

			/* reset flags */
			sigrestart=FALSE;
			sigshutdown=FALSE;

			/* wait for connections */
			wait_for_connections();

			/* free all memory we allocated */
			free_memory();

			if(sigrestart==TRUE){

				/* read the config file */
				result=read_config_file(config_file);	

				/* exit if there are errors... */
				if(result==ERROR){
					syslog(LOG_ERR,"Config file '%s' contained errors, bailing out...",config_file);
					return STATE_CRITICAL;
				        }
			        }
	
		        }while(sigrestart==TRUE && sigshutdown==FALSE);

		/* remove pid file */
		remove_pid_file();

		syslog(LOG_NOTICE,"Daemon shutdown\n");
	        }

#ifdef HAVE_SSL
	if(use_ssl==TRUE)
		SSL_CTX_free(ctx);
#endif

	/* We are now running in daemon mode, or the connection handed over by inetd has
	   been completed, so the parent process exits */
        return STATE_OK;
	}
Ejemplo n.º 11
0
int main ()
{
  int err;
  int listen_sd;
  int sd;
  struct sockaddr_in sa_serv;
  struct sockaddr_in sa_cli;
  size_t client_len;
  SSL_CTX* ctx;
  SSL*     ssl;
  X509*    client_cert;
  char*    str;
  char     buf [4096];
  SSL_METHOD *meth;
  int optval =1;
  
  /* SSL preliminaries. We keep the certificate and key with the context. */

  SSL_load_error_strings();
  SSLeay_add_ssl_algorithms();
  meth = SSLv23_server_method();
  ctx = SSL_CTX_new (meth);
  if (!ctx) {
    ERR_print_errors_fp(stderr);
    exit(2);
  }
  
  if (SSL_CTX_use_certificate_file(ctx, CERTF, SSL_FILETYPE_PEM) <= 0) {
    ERR_print_errors_fp(stderr);
    exit(3);
  }
  if (SSL_CTX_use_PrivateKey_file(ctx, KEYF, SSL_FILETYPE_PEM) <= 0) {
    ERR_print_errors_fp(stderr);
    exit(4);
  }

  if (!SSL_CTX_check_private_key(ctx)) {
    fprintf(stderr,"Private key does not match the certificate public key\n");
    exit(5);
  }

  /* ----------------------------------------------- */
  /* Prepare TCP socket for receiving connections */

  listen_sd = socket (AF_INET, SOCK_STREAM, 0);   CHK_ERR(listen_sd, "socket");
  
  memset (&sa_serv, '\0', sizeof(sa_serv));
  sa_serv.sin_family      = AF_INET;
  sa_serv.sin_addr.s_addr = INADDR_ANY;
  sa_serv.sin_port        = htons (8889);          /* Server Port number 
*/

  err = bind(listen_sd, (struct sockaddr*) &sa_serv,
	     sizeof (sa_serv));                   CHK_ERR(err, "bind");

	     
  /* Receive a TCP connection. */
	     
  err = listen (listen_sd, 5);                    CHK_ERR(err, "listen");
  
  client_len = sizeof(sa_cli);
  sd = accept (listen_sd, (struct sockaddr*) &sa_cli, &client_len);
  CHK_ERR(sd, "accept");

  /*  added by Carman Neustaedter, thanks to Hal & Darcy

     Set address to be reusable.  

     int optval=1 was added above
     1 means turn this option on
     0 means turn this option off
     SO_REUSEADDR specifies that we will toggle the feature of address reuse
  */
  if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char *)&optval, sizeof(optval)) <0)
  {
        perror("Error attempting to reuse address");
        exit(0);
  }




  close (listen_sd);

  printf ("\nIn server. Connection from %lx, port %x\n",
	  sa_cli.sin_addr.s_addr, sa_cli.sin_port);
  
  /* ----------------------------------------------- */
  /* TCP connection is ready. Do server side SSL. */

  ssl = SSL_new (ctx);                           CHK_NULL(ssl);
  SSL_set_fd (ssl, sd);
  err = SSL_accept (ssl);                        CHK_SSL(err);
  
  /* Get the cipher - opt */
  
  printf ("In server. SSL connection using %s\n", SSL_get_cipher (ssl));
  
  /* Get client's certificate (note: beware of dynamic allocation) - opt 

  client_cert = SSL_get_peer_certificate (ssl);
  if (client_cert != NULL) {
    printf ("Client certificate:\n");
    
    str = X509_NAME_oneline (X509_get_subject_name (client_cert), 0, 0);
    CHK_NULL(str);
    printf ("\t subject: %s\n", str);
    Free (str);
    
    str = X509_NAME_oneline (X509_get_issuer_name  (client_cert), 0, 0);
    CHK_NULL(str);
    printf ("\t issuer: %s\n", str);
    Free (str);
    
       We could do all sorts of certificate verification stuff here before
       deallocating the certificate. 
    
    X509_free (client_cert);
  } else
    printf ("Client does not have certificate.\n");

     DATA EXCHANGE - Receive message and send reply. */

  err = SSL_read (ssl, buf, sizeof(buf) - 1);

  printf("In server. Just after the first read\n\n");
  CHK_SSL(err);

  buf[err] = '\0';
  printf ("GotGOT  %d chars:'%s'\n", err, buf);
  
  err = SSL_write (ssl, "I hear you!!.", strlen("I hear you!!."));  
CHK_SSL(err);

  /* Clean up. */

  close (sd);
  SSL_free (ssl);
  SSL_CTX_free (ctx);
}
Ejemplo n.º 12
0
bool
ssl_init (void)
{
  SSL_METHOD const *meth;

  if (ssl_ctx)
    /* The SSL has already been initialized. */
    return true;

  /* Init the PRNG.  If that fails, bail out.  */
  init_prng ();
  if (RAND_status () != 1)
    {
      logprintf (LOG_NOTQUIET,
                 _("Could not seed PRNG; consider using --random-file.\n"));
      goto error;
    }

  SSL_library_init ();
  SSL_load_error_strings ();
  SSLeay_add_all_algorithms ();
  SSLeay_add_ssl_algorithms ();

  switch (opt.secure_protocol)
    {
    case secure_protocol_auto:
      meth = SSLv23_client_method ();
      break;
#ifndef OPENSSL_NO_SSL2
    case secure_protocol_sslv2:
      meth = SSLv2_client_method ();
      break;
#endif
    case secure_protocol_sslv3:
      meth = SSLv3_client_method ();
      break;
    case secure_protocol_pfs:
    case secure_protocol_tlsv1:
      meth = TLSv1_client_method ();
      break;
    default:
      abort ();
    }

  /* The type cast below accommodates older OpenSSL versions (0.9.8)
     where SSL_CTX_new() is declared without a "const" argument. */
  ssl_ctx = SSL_CTX_new ((SSL_METHOD *)meth);
  if (!ssl_ctx)
    goto error;

  /* OpenSSL ciphers: https://www.openssl.org/docs/apps/ciphers.html
   * Since we want a good protection, we also use HIGH (that excludes MD4 ciphers and some more)
   */
  if (opt.secure_protocol == secure_protocol_pfs)
    SSL_CTX_set_cipher_list (ssl_ctx, "HIGH:MEDIUM:!RC4:!SRP:!PSK:!RSA:!aNULL@STRENGTH");

  SSL_CTX_set_default_verify_paths (ssl_ctx);
  SSL_CTX_load_verify_locations (ssl_ctx, opt.ca_cert, opt.ca_directory);

  /* SSL_VERIFY_NONE instructs OpenSSL not to abort SSL_connect if the
     certificate is invalid.  We verify the certificate separately in
     ssl_check_certificate, which provides much better diagnostics
     than examining the error stack after a failed SSL_connect.  */
  SSL_CTX_set_verify (ssl_ctx, SSL_VERIFY_NONE, NULL);

  /* Use the private key from the cert file unless otherwise specified. */
  if (opt.cert_file && !opt.private_key)
    {
      opt.private_key = opt.cert_file;
      opt.private_key_type = opt.cert_type;
    }

  if (opt.cert_file)
    if (SSL_CTX_use_certificate_file (ssl_ctx, opt.cert_file,
                                      key_type_to_ssl_type (opt.cert_type))
        != 1)
      goto error;
  if (opt.private_key)
    if (SSL_CTX_use_PrivateKey_file (ssl_ctx, opt.private_key,
                                     key_type_to_ssl_type (opt.private_key_type))
        != 1)
      goto error;

  /* Since fd_write unconditionally assumes partial writes (and
     handles them correctly), allow them in OpenSSL.  */
  SSL_CTX_set_mode (ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);

  /* The OpenSSL library can handle renegotiations automatically, so
     tell it to do so.  */
  SSL_CTX_set_mode (ssl_ctx, SSL_MODE_AUTO_RETRY);

  return true;

 error:
  if (ssl_ctx)
    SSL_CTX_free (ssl_ctx);
  print_errors ();
  return false;
}
Ejemplo n.º 13
0
/*
 *	Start up the SSL Context for the application, and start a listen on the
 *	SSL port (usually 443, and defined by SSL_PORT)
 *	Return 0 on success, -1 on failure.
 */
int websSSLOpen()
{
	char		*certFile, *keyFile, *CApath, *CAfile;
	SSL_METHOD	*meth;
	
/*
 *	Install and initialize the SSL library
 */
	apps_startup();
	printf("ssl.c: SSL: Initializing SSL\n"); 
	
	SSL_load_error_strings();

	SSLeay_add_ssl_algorithms();


/*
 *	Important!  Enable both SSL versions 2 and 3
 */
	meth = SSLv23_server_method();
	sslctx = SSL_CTX_new(meth);
	
	if (sslctx == NULL) {
		printf("SSL: Unable to create SSL context!\n"); 
		return -1;
	}

/*
 *	Adjust some SSL Context variables
 */
	SSL_CTX_set_quiet_shutdown(sslctx, 1);
	SSL_CTX_set_options(sslctx, 0);
	SSL_CTX_sess_set_cache_size(sslctx, 128);

/*
 *	Set the certificate verification locations
 */
	CApath = DEFAULT_CA_PATH;
	CAfile = DEFAULT_CA_FILE;
	if ((!SSL_CTX_load_verify_locations(sslctx, CAfile, CApath)) ||
		(!SSL_CTX_set_default_verify_paths(sslctx))) {
		printf("SSL: Unable to set cert verification locations!\n"); 
		websSSLClose();
		return -1;
	}

/*
 *  Setting up certificates for the SSL server.
 *	Set the certificate and key files for the SSL context.
 */
	certFile = DEFAULT_CERT_FILE;
	keyFile = NULL;
	if (websSSLSetCertStuff(sslctx, certFile, keyFile) != 0) {
		websSSLClose();
		return -1;
	}

/*
 *	Set the RSA callback for the SSL context
 */
	SSL_CTX_set_tmp_rsa_callback(sslctx, websSSLTempRSACallback);

/*
 *	Set the verification callback for the SSL context
 */
	SSL_CTX_set_verify(sslctx, SSL_VERIFY_NONE, websSSLVerifyCallback);

/*
 *	Set the certificate authority list for the client
 */
	SSL_CTX_set_client_CA_list(sslctx, SSL_load_client_CA_file(CAfile));

/*
 *	Open the socket
 */
	sslListenSock = socketOpenConnection(NULL, SSL_PORT, 
		websSSLAccept, SOCKET_BLOCK);

	if (sslListenSock < 0) {
		trace(2, T("SSL: Unable to open SSL socket on port <%d>!\n"), 
			SSL_PORT);
		return -1;
	}

	return 0;
}
Ejemplo n.º 14
0
struct host_ret
openhost(char *host, int port, int dossl)
{
    struct hostent *hp;
    struct sockaddr_in sin;
    struct host_ret ret;
#ifdef USE_SSLEAY
    int     err;
    X509   *server_cert;
    char   *str;
#endif

    ret.s = -1;

    if ((hp = gethostbyname(host)) == NULL) {
        fprintf(stderr, "ERR: gethostbyname: %s\n", host);
        return (ret);
    }
    if ((ret.s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        perror("socket");
        return (ret);
    }
    sin.sin_family = AF_INET;
    sin.sin_port = htons(port);
    bcopy(hp->h_addr, &sin.sin_addr, hp->h_length);

    alarm(30);
    if (connect(ret.s, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
        close(ret.s);
        ret.s = -1;
        return (ret);
    }
    alarm(0);

#ifdef USE_SSLEAY
    if (dossl) {
        SSLeay_add_ssl_algorithms();
        SSL_load_error_strings();
        ret.ctx = SSL_CTX_new(SSLv2_method());
        CHK_NULL(ret.ctx);

        ret.ssl = SSL_new(ret.ctx);
        CHK_NULL(ret.ssl);
        SSL_set_fd(ret.ssl, ret.s);
        err = SSL_connect(ret.ssl);
        CHK_SSL(err);

        server_cert = SSL_get_peer_certificate(ret.ssl);
        CHK_NULL(server_cert);

        str = X509_NAME_oneline(X509_get_subject_name(server_cert), NULL, 0);
        CHK_NULL(str);
        Free(str);

        str = X509_NAME_oneline(X509_get_issuer_name(server_cert), NULL, 0);
        CHK_NULL(str);
        Free(str);

        if (server_cert)
            X509_free(server_cert);
    }
#endif /* USE_SSLEAY */

    return (ret);
}
Ejemplo n.º 15
0
// ================================================
CNetServer::CNetServer( uint32_t ip4_addr, unsigned short int port):CNet()
{
  int option = 1;
  BEGIN;

  Clients = new CPartimagedClients;

#ifdef HAVE_SSL
  ctx = NULL;
  if (g_bUseSSL)
    {
      SSL_load_error_strings();
      SSLeay_add_ssl_algorithms();
      ctx = SSL_CTX_new(SSLv23_server_method());
      if (!ctx)
        {
          ERR_print_errors_fp(stderr);
          THROW(ERR_SSL_CTX);
        }
     
      if (SSL_CTX_use_certificate_file(ctx, CERTF, SSL_FILETYPE_PEM) <= 0)
        {
          ERR_print_errors_fp(stderr);
          THROW(ERR_SSL_LOADCERT);
        }
    
      if (SSL_CTX_use_PrivateKey_file(ctx, KEYF, SSL_FILETYPE_PEM) <= 0)
        {
          ERR_print_errors_fp(stderr);
          THROW(ERR_SSL_LOADKEY);
        }
    
      if (!SSL_CTX_check_private_key(ctx))
        {
          fprintf(stderr,
             i18n("private key does not match the certificate public key\n"));
          THROW(ERR_SSL_PRIVKEY);
        }
    }
#endif


  if (!(sock_listen = socket(AF_INET, SOCK_STREAM, 0)))
    {
      showDebug(1, "socket error %d %s\n", errno, strerror(errno));
      THROW(ERR_ERRNO, errno); 
    }
  memset(&local_sa, '\0', sizeof(struct sockaddr));

  /* we want to reuse the (addr,port) -> SO_REUSEADDR */
  setsockopt(sock_listen, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(int));
  local_sa.sin_family = AF_INET;

  if ( ip4_addr )
      local_sa.sin_addr.s_addr = ip4_addr ;
  else
      local_sa.sin_addr.s_addr = htonl(INADDR_ANY);

  local_sa.sin_port = htons(port);

  if (bind(sock_listen, (struct sockaddr *) &local_sa, sizeof(struct sockaddr_in)))
    {
      showDebug(1, "bind error %s\n", strerror(errno));
      THROW(ERR_ERRNO, errno); 
    }

  if (listen(sock_listen, BACKLOG_SIZE))
    {
      showDebug(1, "listen error %s\n", strerror(errno));
      THROW(ERR_ERRNO, errno); 
    }
  showDebug(9, "end\n");
}      
Ejemplo n.º 16
0
/* Open a connection to one of the TrustCommerce gateway servers. */
static int Connect(TCLinkCon *c, int host_hash)
{
	struct hostent default_he;
	char *addr_list[5]; int addr[4];
	struct hostent *he;
	unsigned int **gw;

	enum { MAX_HOSTS = 32 };
	time_t last_connect[MAX_HOSTS];
	int sd[MAX_HOSTS];
	int num_sd = 0;
	int host;

	int i, j, sort, sort_val;


	c->sd = -1;
	c->is_error = 0;

	srand(time(0));

	/* These are used as BACKUP ONLY if the DNS if offline. */
	addr[0] = inet_addr("207.38.46.31");
	addr[1] = inet_addr("207.38.46.32");
	addr[2] = inet_addr("208.42.227.136");
	addr[3] = inet_addr("208.42.227.137");
	addr_list[0] = (char *)&addr[0];
	addr_list[1] = (char *)&addr[1];
	addr_list[2] = (char *)&addr[2];
	addr_list[3] = (char *)&addr[3];
	addr_list[4] = 0;
	default_he.h_addr_list = addr_list;

	/* determine IP addresses of gateway */
	if (!c->ip) 
	{
		he = gethostbyname(tclink_host);
		if (he)
			c->dns = 1;
		else {
			/* fall back to hardcoded IPs in an emergency */
			c->dns = 0;
			he = &default_he;
		}

		for (c->num_ips = 0; he->h_addr_list[c->num_ips]; c->num_ips++)
			;

		c->ip = (int *)malloc(c->num_ips * sizeof(int));
		gw = (int unsigned **)he->h_addr_list;

		/* sort the IP address list before storing it */
		for (i = 0; i < c->num_ips; i++)
		{
			sort = 0; sort_val = *gw[0];
			for (j = 1; j < c->num_ips; j++)
				if (*gw[j] > sort_val)
				{
					sort = j;
					sort_val = *gw[j];
				}

			c->ip[i] = sort_val;
			*gw[sort] = 0;
		}
	}

	/* do some SSL setup */
	if (!c->meth)
	{
		do_SSL_randomize();        /* handle systems without /dev/urandom */
		SSLeay_add_ssl_algorithms();
		c->meth = TLSv1_client_method();
	}

	if (!c->ctx)
	{
		extern int SSL_CTX_load_verify_locations_mem(SSL_CTX*, const char *);
		int val;

		c->ctx = SSL_CTX_new(c->meth);
		if (!c->ctx) return 0;
		/* do verifications from our trusted string */
		val = SSL_CTX_load_verify_locations_mem(c->ctx, c->trusted_ca_pem);
		/* turn on certificate chain validation */
		SSL_CTX_set_verify(c->ctx, SSL_VERIFY_PEER, NULL);
	}

	if (!c->ssl)
	{
		c->ssl = SSL_new(c->ctx);
		if (!c->ssl)
		{
			SSL_CTX_free(c->ctx);
			return 0;
		}
	}

	/* This loop works as follows:
	 * Grab the first host.  Try to open a connection to it.  If there was an
	 * error (host down or unreachable) go to the next one.  If nothing has happened
	 * after 3 seconds, open a second socket (the first one is still open!) and try
	 * with the next fail-over host.  Continue to do this for a maximum of MAX_HOSTS
	 * sockets, or until our TIMEOUT value runs out.  We also keep track of how recently
	 * we tried to connect to a given host, so that we avoid saturating the machines
	 * in a heavy-load situation (which could be caused by anything from heavy internet
	 * lag between the local host and the TrustCommerce servers, to heavy load on the
	 * servers themselves due to half a million people trying to run credit card
	 * transactions in the same half second - unlikely, but certainly possible.)
	 */
	c->start_time = time(0);
	c->pass = 1;
	memset(last_connect, 0, MAX_HOSTS * sizeof(time_t));
	host = host_hash % c->num_ips;

	for ( ; time(0) < (c->start_time + TIMEOUT); c->pass++)
	{
		/* retry the first host at least once */
		if (c->pass > 2) host += 1;
		if (host >= c->num_ips) host = 0;

		/* only connect if we haven't tried this host before, or it's been a little
		 * while (note random modifier to help stagger network traffic) */
		if (last_connect[host] == 0 ||
		    (time(0) - last_connect[host]) >= number(TIMEOUT / 4, TIMEOUT))
		{
			if (num_sd < MAX_HOSTS)
			{
				/* fire up a new connection to this host */
				if (c->pass != 1)
					last_connect[host] = time(0);

				sd[num_sd] = BeginConnection(c, c->ip[host]);
				if (sd[num_sd] >= 0)
					num_sd++;
			}

			/* scan all current sockets and see if we've made a successful connection
			 * somewhere.  note that this also includes SSL and all that sort of fun,
			 * so once it returns success, we're all done. */
			if (num_sd > 0)
				if (CheckConnection(c, sd, num_sd) >= 0)
				{
					/* Success: close all other file handles and return */
					for (i = 0; i < num_sd; i++)
						if (sd[i] >= 0 && sd[i] != c->sd)
							close(sd[i]);

					return 1;
				}
		}
	}

	return 0;
}
Ejemplo n.º 17
0
int main ()
{
  int err;
  int sd;
  struct sockaddr_in sa;
  SSL_CTX* ctx;
  SSL*     ssl;
  X509*    server_cert;
  char*    str;
  char     buf [4096];
  SSL_METHOD *meth;

  SSLeay_add_ssl_algorithms();   //设置支持SSL算法
  meth = (SSL_METHOD*)SSLv2_client_method(); //客户端设置SSLV2版本
  SSL_load_error_strings();		//提供将错误解析为字符串的功能
  ctx = SSL_CTX_new (meth);                        CHK_NULL(ctx);  
  //创建一个SSL上下文环境,每个进程守护一个SSL_CTX结构体

  CHK_SSL(err);
  
  /* ----------------------------------------------- */
  /* Create a socket and connect to server using normal socket calls. */
  
  sd = socket (AF_INET, SOCK_STREAM, 0);       CHK_ERR(sd, "socket");  //
 
  memset (&sa, '\0', sizeof(sa));
  sa.sin_family      = AF_INET;
  sa.sin_addr.s_addr = inet_addr ("127.0.0.1");   /* Server IP */
  sa.sin_port        = htons     (1111);          /* Server Port number */
  
  err = connect(sd, (struct sockaddr*) &sa,
		sizeof(sa));                   CHK_ERR(err, "connect");

  /* ----------------------------------------------- */
  /* Now we have TCP conncetion. Start SSL negotiation. */
//创建一个维护当前连接信息
  ssl = SSL_new (ctx);                         CHK_NULL(ssl);    
//将SSL绑定到套接字上
  SSL_set_fd (ssl, sd);
//建立SSL连接
  err = SSL_connect (ssl);                     CHK_SSL(err);
    
  /* Following two steps are optional and not required for
     data exchange to be successful. */
  
  /* Get the cipher - opt */

  printf ("SSL connection using %s\n", SSL_get_cipher (ssl));
  
  /* Get server's certificate (note: beware of dynamic allocation) - opt */
//获取服务端证书
  server_cert = SSL_get_peer_certificate (ssl);       CHK_NULL(server_cert);
  printf ("Server certificate:\n");
  
  str = X509_NAME_oneline (X509_get_subject_name (server_cert),0,0);
  CHK_NULL(str);
  printf ("\t subject: %s\n", str);
  OPENSSL_free (str);

  str = X509_NAME_oneline (X509_get_issuer_name  (server_cert),0,0);
  CHK_NULL(str);
  printf ("\t issuer: %s\n", str);
  OPENSSL_free (str);

  /* We could do all sorts of certificate verification stuff here before
     deallocating the certificate. */
//释放服务端证书
  X509_free (server_cert);
  
  /* --------------------------------------------------- */
  /* DATA EXCHANGE - Send a message and receive a reply. */

  err = SSL_write (ssl, "Hello World!", strlen("Hello World!"));  CHK_SSL(err);
  
  err = SSL_read (ssl, buf, sizeof(buf) - 1);                     CHK_SSL(err);
  buf[err] = '\0';
  printf ("Got %d chars:'%s'\n", err, buf);
  SSL_shutdown (ssl);  /* send SSL/TLS close_notify */

  /* Clean up. */

  close(sd);
  SSL_free (ssl);
  SSL_CTX_free (ctx);
}
Ejemplo n.º 18
0
Archivo: ssmtp.c Proyecto: fidian/sSMTP
/*
smtp_open() -- Open connection to a remote SMTP listener
*/
int smtp_open(char *host, int port)
{
#ifdef INET6
	struct addrinfo hints, *ai0, *ai;
	char servname[NI_MAXSERV];
	int s;
#else
	struct sockaddr_in name;
	struct hostent *hent;
	int i, s, namelen;
#endif

#ifdef HAVE_SSL
	int err;
	char buf[(BUF_SZ + 1)];

	/* Init SSL stuff */
	SSL_CTX *ctx;
	SSL_METHOD *meth;
	X509 *server_cert;

	SSL_load_error_strings();
	SSLeay_add_ssl_algorithms();
	meth=SSLv23_client_method();
	ctx = SSL_CTX_new(meth);
	if(!ctx) {
		log_event(LOG_ERR, "No SSL support initiated\n");
		return(-1);
	}

	if(use_cert == True) { 
		if(SSL_CTX_use_certificate_chain_file(ctx, tls_cert) <= 0) {
			perror("Use certfile");
			return(-1);
		}

		if(SSL_CTX_use_PrivateKey_file(ctx, tls_cert, SSL_FILETYPE_PEM) <= 0) {
			perror("Use PrivateKey");
			return(-1);
		}

		if(!SSL_CTX_check_private_key(ctx)) {
			log_event(LOG_ERR, "Private key does not match the certificate public key\n");
			return(-1);
		}
	}
#endif

#ifdef INET6
	memset(&hints, 0, sizeof(hints));
	hints.ai_family = p_family;
	hints.ai_socktype = SOCK_STREAM;
	snprintf(servname, sizeof(servname), "%d", port);

	/* Check we can reach the host */
	if (getaddrinfo(host, servname, &hints, &ai0)) {
		log_event(LOG_ERR, "Unable to locate %s", host);
		return(-1);
	}

	for (ai = ai0; ai; ai = ai->ai_next) {
		/* Create a socket for the connection */
		s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
		if (s < 0) {
			continue;
		}

		if (connect(s, ai->ai_addr, ai->ai_addrlen) < 0) {
			s = -1;
			continue;
		}
		break;
	}

	if(s < 0) {
		log_event (LOG_ERR,
			"Unable to connect to \"%s\" port %d.\n", host, port);

		return(-1);
	}
#else
	/* Check we can reach the host */
	if((hent = gethostbyname(host)) == (struct hostent *)NULL) {
		log_event(LOG_ERR, "Unable to locate %s", host);
		return(-1);
	}

	if(hent->h_length > sizeof(hent->h_addr)) {
		log_event(LOG_ERR, "Buffer overflow in gethostbyname()");
		return(-1);
	}

	/* Create a socket for the connection */
	if((s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
		log_event(LOG_ERR, "Unable to create a socket");
		return(-1);
	}

	for (i = 0; ; ++i) {
		if (!hent->h_addr_list[i]) {
			log_event(LOG_ERR, "Unable to connect to %s:%d", host, port);
			return(-1);
		}

	/* This SHOULD already be in Network Byte Order from gethostbyname() */
	name.sin_addr.s_addr = ((struct in_addr *)(hent->h_addr_list[i]))->s_addr;
	name.sin_family = hent->h_addrtype;
	name.sin_port = htons(port);

	namelen = sizeof(struct sockaddr_in);
	if(connect(s, (struct sockaddr *)&name, namelen) < 0)
		continue;
	break;
	}
#endif

#ifdef HAVE_SSL
	if(use_tls == True) {
		log_event(LOG_INFO, "Creating SSL connection to host");

		if (use_starttls == True)
		{
			use_tls=False; /* need to write plain text for a while */

			if (smtp_okay(s, buf))
			{
				smtp_write(s, "EHLO %s", hostname);
				if (smtp_okay(s, buf)) {
					smtp_write(s, "STARTTLS"); /* assume STARTTLS regardless */
					if (!smtp_okay(s, buf)) {
						log_event(LOG_ERR, "STARTTLS not working");
						return(-1);
					}
				}
				else
				{
					log_event(LOG_ERR, "Invalid response: %s (%s)", buf, hostname);
				}
			}
			else
			{
				log_event(LOG_ERR, "Invalid response SMTP Server (STARTTLS)");
				return(-1);
			}
			use_tls=True; /* now continue as normal for SSL */
		}

		ssl = SSL_new(ctx);
		if(!ssl) {
			log_event(LOG_ERR, "SSL not working");
			return(-1);
		}
		SSL_set_fd(ssl, s);

		err = SSL_connect(ssl);
		if(err < 0) { 
			perror("SSL_connect");
			return(-1);
		}

		if(log_level > 0 || 1) {
			log_event(LOG_INFO, "SSL connection using %s",
				SSL_get_cipher(ssl));
		}

		server_cert = SSL_get_peer_certificate(ssl);
		if(!server_cert) {
			return(-1);
		}
		X509_free(server_cert);

		/* TODO: Check server cert if changed! */
	}
#endif

	return(s);
}
Ejemplo n.º 19
0
int main ()
{
  int err;
  int sd;
  struct sockaddr_in sa;
  SSL_CTX* ctx;
  SSL*     ssl;
  X509*    server_cert;
  char*    str;
  char     buf [8096];
  SSL_METHOD *meth;

  SSLeay_add_ssl_algorithms();
#ifndef OPENSSL_NO_SSL2
  meth = (SSL_METHOD*)SSLv2_client_method();
#else
  ///meth = (SSL_METHOD*)SSLv3_client_method();
  //连接https 需要使用tls类型的
  meth = (SSL_METHOD*)TLSv1_2_client_method();
  //return ThrowException(Exception::Error(String::New("SSLv2 methods disabled")));
#endif
  SSL_load_error_strings();
  ctx = SSL_CTX_new (meth);
  if(ctx==NULL)
  {
	  printd("ctx is NULL\n");
	  exit(1);
  }

  CHK_SSL(err);
  
  /* ----------------------------------------------- */
  /* Create a socket and connect to server using normal socket calls. */
  
  sd = socket (AF_INET, SOCK_STREAM, 0);       CHK_ERR(sd, "socket");
 
  memset (&sa, '\0', sizeof(sa));
  sa.sin_family      = AF_INET;
  sa.sin_addr.s_addr = inet_addr (SERVERIP);   /* Server IP */
  sa.sin_port        = htons     (SERVERPORT);          /* Server Port number */
  
  err = connect(sd, (struct sockaddr*) &sa,
		sizeof(sa));                   CHK_ERR(err, "connect");

  /* ----------------------------------------------- */
  /* Now we have TCP conncetion. Start SSL negotiation. */
  printd("connect to %s:%d success.\n",SERVERIP, SERVERPORT);
  
  ssl = SSL_new (ctx);                         CHK_NULL(ssl);    
  printd("SSL_new ok\n");
  SSL_set_fd (ssl, sd);
  printd("Set fd OK\n");
  err = SSL_connect (ssl);                     CHK_SSL(err);
    
  /* Following two steps are optional and not required for
     data exchange to be successful. */
  
  /* Get the cipher - opt */

  printd ("SSL connection using %s\n", SSL_get_cipher (ssl));

  //验证证书是否可以信任
  if ( X509_V_OK != SSL_get_verify_result(ssl) )
  {
	  printd("SSL verify error\n");

	     int color = 32;

		       printf("\033[%dmHello, world.\n\033[0m", color);
  }


  /* Get server's certificate (note: beware of dynamic allocation) - opt */
  //比如连接 https时,需要打开以下选项
#if 1
  server_cert = SSL_get_peer_certificate (ssl);       CHK_NULL(server_cert);
  printd ("Server certificate:\n");
  
  str = X509_NAME_oneline (X509_get_subject_name (server_cert),0,0);
  CHK_NULL(str);
  printd ("\t subject: %s\n", str);
  OPENSSL_free (str);

  str = X509_NAME_oneline (X509_get_issuer_name  (server_cert),0,0);
  CHK_NULL(str);
  printd ("\t issuer: %s\n", str);
  OPENSSL_free (str);

  /* We could do all sorts of certificate verification stuff here before
     deallocating the certificate. */

  X509_free (server_cert);
  
#endif
  /* --------------------------------------------------- */
  /* DATA EXCHANGE - Send a message and receive a reply. */


#ifdef AUTH
  //init base 64
  //come from : http://doctrina.org/Base64-With-OpenSSL-C-API.html
  BIO *bio, *b64;
  char* base64EncodeOutput;
  BUF_MEM *bufferPtr;
  char message[] = USER ":"******"base encode str:->%s<-  message len:%d\n", message, message_len);

  b64 = BIO_new(BIO_f_base64());
  bio = BIO_new(BIO_s_mem());
  bio = BIO_push(b64, bio);

  /*
  ///!IMPORTANT
  //BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); //Ignore newlines - write everything in one line
  //BIO_FLAGS_BASE64_NO_NL: 编码结果中,每64个字符换行一次,整个编码后的字符串的末尾也有换行
  //如果有这个选项,测试结尾会出现0x76 0x7f字符 0x7f是del所以打印时显示正常,其实不正常
  */
  BIO_write(bio, message, strlen(message));
  BIO_flush(bio);
  BIO_get_mem_ptr(bio, &bufferPtr);
  BIO_set_close(bio, BIO_NOCLOSE);
  BIO_free_all(bio);

  char b64text[1024]={0};
  strcpy(b64text, (*bufferPtr).data);
  memcpy(b64text, (*bufferPtr).data, bufferPtr->length);
  printd("base64 encode str: ->%s<-, size:%ld\n", b64text, strlen(b64text));
  //printd("%x %x %x %x %x %x\n", b64text[0],b64text[1],b64text[2],b64text[3],b64text[4],b64text[5]);

 
#endif

  /*
   * 以下是模拟浏览器登陆https://172.20.1.209:8001的过程
   *
   * 服务器是python做的,服务器代码从:
   *  https://github.com/SevenW/httpwebsockethandler.git
   *  下载,
   *  运行服务器的命令:
   *  python ExampleWSServer.py 8001 secure u:2
   */
  char http_get_str[2048] = {0};
  sprintf(http_get_str,
	  "GET / HTTP/1.1\r\n"
	  "Host: %s:%d \r\n"
#ifdef AUTH
	  "Authorization: Basic %s\r\n"
#endif
	  "Connection: keep-alive\r\n"
	  "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/* ;q=0.8\r\n"
	  "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36\r\n"
	  "Accept-Encoding: gzip, deflate, sdch\r\n"
	  "Accept-Language: en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4,zh-TW;q=0.2\r\n"
	  "\r\n"
	,SERVERIP, SERVERPORT 
#ifdef AUTH
	,b64text
#endif
	);

  printd("http get str: ->%s<- len:%ld\n", http_get_str, strlen(http_get_str));

  err = SSL_write (ssl, http_get_str, strlen(http_get_str));  CHK_SSL(err);
  err = 0;
  int c1=0;
  do{
  err = SSL_read (ssl, buf+c1, sizeof(buf) - c1 - 1);                     CHK_SSL(err);
  c1 += err;
  while(err>0);
  buf[err] = '\0';
  printd ("Got %d chars:'%s'\n", err, buf);
  SSL_shutdown (ssl);  /* send SSL/TLS close_notify */

  /* Clean up. */

  close (sd);
  SSL_free (ssl);
  SSL_CTX_free (ctx);
}
Ejemplo n.º 20
0
int main(int argc, char **argv){
        u_int32_t packet_crc32;
        u_int32_t calculated_crc32;
	int16_t result;
	int rc;
	packet send_packet;
	packet receive_packet;
	int bytes_to_send;
	int bytes_to_recv;

	result=process_arguments(argc,argv);

        if(result!=OK || show_help==TRUE || show_license==TRUE || show_version==TRUE){

		if(result!=OK)
			printf("Incorrect command line arguments supplied\n");
                printf("\n");
		printf("NRPE Plugin for Nagios\n");
		printf("Copyright (c) 1999-2008 Ethan Galstad ([email protected])\n");
		printf("Version: %s\n",PROGRAM_VERSION);
		printf("Last Modified: %s\n",MODIFICATION_DATE);
		printf("License: GPL v2 with exemptions (-l for more info)\n");
#ifdef HAVE_SSL
		printf("SSL/TLS Available: Anonymous DH Mode, OpenSSL 0.9.6 or higher required\n");
#endif
		printf("\n");
	        }

	if(result!=OK || show_help==TRUE){

		printf("Usage: check_nrpe -H <host> [ -b <bindaddr> ] [-4] [-6] [-n] [-u] [-p <port>] [-t <timeout>] [-c <command>] [-a <arglist...>]\n");
		printf("\n");
		printf("Options:\n");
		printf(" -n         = Do no use SSL\n");
		printf(" -u         = Make socket timeouts return an UNKNOWN state instead of CRITICAL\n");
		printf(" <host>     = The address of the host running the NRPE daemon\n");
		printf(" <bindaddr> = bind to local address\n");
		printf(" -4         = user ipv4 only\n");
		printf(" -6         = user ipv6 only\n");
		printf(" [port]     = The port on which the daemon is running (default=%d)\n",DEFAULT_SERVER_PORT);
		printf(" [timeout]  = Number of seconds before connection times out (default=%d)\n",DEFAULT_SOCKET_TIMEOUT);
		printf(" [command]  = The name of the command that the remote daemon should run\n");
		printf(" [arglist]  = Optional arguments that should be passed to the command.  Multiple\n");
		printf("              arguments should be separated by a space.  If provided, this must be\n");
		printf("              the last option supplied on the command line.\n");
		printf("\n");
		printf("Note:\n");
		printf("This plugin requires that you have the NRPE daemon running on the remote host.\n");
		printf("You must also have configured the daemon to associate a specific plugin command\n");
		printf("with the [command] option you are specifying here.  Upon receipt of the\n");
		printf("[command] argument, the NRPE daemon will run the appropriate plugin command and\n");
		printf("send the plugin output and return code back to *this* plugin.  This allows you\n");
		printf("to execute plugins on remote hosts and 'fake' the results to make Nagios think\n");
		printf("the plugin is being run locally.\n");
		printf("\n");
	        }

	if(show_license==TRUE)
		display_license();

        if(result!=OK || show_help==TRUE || show_license==TRUE || show_version==TRUE)
		exit(STATE_UNKNOWN);


        /* generate the CRC 32 table */
        generate_crc32_table();

#ifdef HAVE_SSL
	/* initialize SSL */
	if(use_ssl==TRUE){
		SSL_library_init();
		SSLeay_add_ssl_algorithms();
		meth=SSLv23_client_method();
		SSL_load_error_strings();
		if((ctx=SSL_CTX_new(meth))==NULL){
			printf("CHECK_NRPE: Error - could not create SSL context.\n");
			exit(STATE_CRITICAL);
		        }

		/* ADDED 01/19/2004 */
		/* use only TLSv1 protocol */
		SSL_CTX_set_options(ctx,SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
                }
#endif

	/* initialize alarm signal handling */
	signal(SIGALRM,alarm_handler);

	/* set socket timeout */
	alarm(socket_timeout);

	/* try to connect to the host at the given port number */
	if((sd=my_connect(server_name, &hostaddr, server_port, address_family, 
			bind_address)) < 0 ) {
		exit (255);
		}
	else {
		result=STATE_OK;
	}

#ifdef HAVE_SSL
	/* do SSL handshake */
	if(result==STATE_OK && use_ssl==TRUE){
		if((ssl=SSL_new(ctx))!=NULL){
			SSL_CTX_set_cipher_list(ctx,"ADH");
			SSL_set_fd(ssl,sd);
			if((rc=SSL_connect(ssl))!=1){
				printf("CHECK_NRPE: Error - Could not complete SSL handshake.\n");
#ifdef DEBUG
				printf("SSL_connect=%d\n",rc);
				/*
				rc=SSL_get_error(ssl,rc);
				printf("SSL_get_error=%d\n",rc);
				printf("ERR_get_error=%lu\n",ERR_get_error());
				printf("%s\n",ERR_error_string(rc,NULL));
				*/
				ERR_print_errors_fp(stdout);
#endif
				result=STATE_CRITICAL;
			        }
		        }
		else{
			printf("CHECK_NRPE: Error - Could not create SSL connection structure.\n");
			result=STATE_CRITICAL;
		        }

		/* bail if we had errors */
		if(result!=STATE_OK){
			SSL_CTX_free(ctx);
			close(sd);
			exit(result);
		        }
	        }
#endif

	/* we're connected and ready to go */
	if(result==STATE_OK){

		/* clear the packet buffer */
		bzero(&send_packet,sizeof(send_packet));

		/* fill the packet with semi-random data */
		randomize_buffer((char *)&send_packet,sizeof(send_packet));

		/* initialize packet data */
		send_packet.packet_version=(int16_t)htons(NRPE_PACKET_VERSION_2);
		send_packet.packet_type=(int16_t)htons(QUERY_PACKET);
		strncpy(&send_packet.buffer[0],query,MAX_PACKETBUFFER_LENGTH);
		send_packet.buffer[MAX_PACKETBUFFER_LENGTH-1]='\x0';

		/* calculate the crc 32 value of the packet */
		send_packet.crc32_value=(u_int32_t)0L;
		calculated_crc32=calculate_crc32((char *)&send_packet,sizeof(send_packet));
		send_packet.crc32_value=(u_int32_t)htonl(calculated_crc32);


		/***** ENCRYPT REQUEST *****/


		/* send the packet */
		bytes_to_send=sizeof(send_packet);
		if(use_ssl==FALSE)
			rc=sendall(sd,(char *)&send_packet,&bytes_to_send);
#ifdef HAVE_SSL
		else{
			rc=SSL_write(ssl,&send_packet,bytes_to_send);
			if(rc<0)
				rc=-1;
		        }
#endif
		if(rc==-1){
			printf("CHECK_NRPE: Error sending query to host.\n");
			close(sd);
			return STATE_UNKNOWN;
		        }

		/* wait for the response packet */
		bytes_to_recv=sizeof(receive_packet);
		if(use_ssl==FALSE)
			rc=recvall(sd,(char *)&receive_packet,&bytes_to_recv,socket_timeout);
#ifdef HAVE_SSL
		else
			rc=SSL_read(ssl,&receive_packet,bytes_to_recv);
#endif

		/* reset timeout */
		alarm(0);

		/* close the connection */
#ifdef HAVE_SSL
		if(use_ssl==TRUE){
			SSL_shutdown(ssl);
			SSL_free(ssl);
			SSL_CTX_free(ctx);
	                }
#endif
		graceful_close(sd,1000);

		/* recv() error */
		if(rc<0){
			printf("CHECK_NRPE: Error receiving data from daemon.\n");
			return STATE_UNKNOWN;
		        }

		/* server disconnected */
		else if(rc==0){
			printf("CHECK_NRPE: Received 0 bytes from daemon.  Check the remote server logs for error messages.\n");
			return STATE_UNKNOWN;
		        }

		/* receive underflow */
		else if(bytes_to_recv<sizeof(receive_packet)){
			printf("CHECK_NRPE: Receive underflow - only %d bytes received (%d expected).\n",bytes_to_recv,sizeof(receive_packet));
			return STATE_UNKNOWN;
		        }

		
		/***** DECRYPT RESPONSE *****/


		/* check the crc 32 value */
		packet_crc32=ntohl(receive_packet.crc32_value);
		receive_packet.crc32_value=0L;
		calculated_crc32=calculate_crc32((char *)&receive_packet,sizeof(receive_packet));
		if(packet_crc32!=calculated_crc32){
			printf("CHECK_NRPE: Response packet had invalid CRC32.\n");
			close(sd);
			return STATE_UNKNOWN;
                        }
	
		/* check packet version */
		if(ntohs(receive_packet.packet_version)!=NRPE_PACKET_VERSION_2){
			printf("CHECK_NRPE: Invalid packet version received from server.\n");
			close(sd);
			return STATE_UNKNOWN;
			}

		/* check packet type */
		if(ntohs(receive_packet.packet_type)!=RESPONSE_PACKET){
			printf("CHECK_NRPE: Invalid packet type received from server.\n");
			close(sd);
			return STATE_UNKNOWN;
			}

		/* get the return code from the remote plugin */
		result=(int16_t)ntohs(receive_packet.result_code);

		/* print the output returned by the daemon */
		receive_packet.buffer[MAX_PACKETBUFFER_LENGTH-1]='\x0';
		if(!strcmp(receive_packet.buffer,""))
			printf("CHECK_NRPE: No output returned from daemon.\n");
		else
			printf("%s\n",receive_packet.buffer);
	        }

	/* reset the alarm */
	else
		alarm(0);

	return result;
        }
Ejemplo n.º 21
0
void context_init(void) { /* init SSL */
    int i;

#if SSLEAY_VERSION_NUMBER >= 0x00907000L
    /* Load all bundled ENGINEs into memory and make them visible */
    ENGINE_load_builtin_engines();
    /* Register all of them for every algorithm they collectively implement */
    ENGINE_register_all_complete();
#endif
    if(!init_prng())
        log(LOG_INFO, "PRNG seeded successfully");
    SSLeay_add_ssl_algorithms();
    SSL_load_error_strings();
    if(options.option.client) {
        ctx=SSL_CTX_new(SSLv3_client_method());
    } else { /* Server mode */
        ctx=SSL_CTX_new(SSLv23_server_method());
#ifndef NO_RSA
        SSL_CTX_set_tmp_rsa_callback(ctx, tmp_rsa_cb);
#endif /* NO_RSA */
        if(init_dh())
            log(LOG_WARNING, "Diffie-Hellman initialization failed");
    }
    if(options.ssl_options) {
        log(LOG_DEBUG, "Configuration SSL options: 0x%08lX",
            options.ssl_options);
        log(LOG_DEBUG, "SSL options set: 0x%08lX", 
            SSL_CTX_set_options(ctx, options.ssl_options));
    }
#if SSLEAY_VERSION_NUMBER >= 0x00906000L
    SSL_CTX_set_mode(ctx,
        SSL_MODE_ENABLE_PARTIAL_WRITE|SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER);
#endif /* OpenSSL-0.9.6 */

    SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_BOTH);
    SSL_CTX_set_timeout(ctx, options.session_timeout);
    if(options.option.cert) {
        if(!SSL_CTX_use_certificate_chain_file(ctx, options.cert)) {
            log(LOG_ERR, "Error reading certificate file: %s", options.cert);
            sslerror("SSL_CTX_use_certificate_chain_file");
            exit(1);
        }
        log(LOG_DEBUG, "Certificate: %s", options.cert);
        log(LOG_DEBUG, "Key file: %s", options.key);
#ifdef USE_WIN32
        SSL_CTX_set_default_passwd_cb(ctx, pem_passwd_cb);
#endif
        for(i=0; i<3; i++) {
#ifdef NO_RSA
            if(SSL_CTX_use_PrivateKey_file(ctx, options.key,
                    SSL_FILETYPE_PEM))
#else /* NO_RSA */
            if(SSL_CTX_use_RSAPrivateKey_file(ctx, options.key,
                    SSL_FILETYPE_PEM))
#endif /* NO_RSA */
                break;
            if(i<2 && ERR_GET_REASON(ERR_peek_error())==EVP_R_BAD_DECRYPT) {
                sslerror_stack(); /* dump the error stack */
                log(LOG_ERR, "Wrong pass phrase: retrying");
                continue;
            }
#ifdef NO_RSA
            sslerror("SSL_CTX_use_PrivateKey_file");
#else /* NO_RSA */
            sslerror("SSL_CTX_use_RSAPrivateKey_file");
#endif /* NO_RSA */
            exit(1);
        }
        if(!SSL_CTX_check_private_key(ctx)) {
            sslerror("Private key does not match the certificate");
            exit(1);
        }
    }

    verify_init(); /* Initialize certificate verification */

    SSL_CTX_set_info_callback(ctx, info_callback);

    if(options.cipher_list) {
        if (!SSL_CTX_set_cipher_list(ctx, options.cipher_list)) {
            sslerror("SSL_CTX_set_cipher_list");
            exit(1);
        }
    }
}
Ejemplo n.º 22
0
bool
ssl_init ()
{
  SSL_METHOD *meth;

  if (ssl_ctx)
    /* The SSL has already been initialized. */
    return true;

  /* Init the PRNG.  If that fails, bail out.  */
  init_prng ();
  if (RAND_status () != 1)
    {
      logprintf (LOG_NOTQUIET,
                 _("Could not seed PRNG; consider using --random-file.\n"));
      goto error;
    }

  SSL_library_init ();
  SSL_load_error_strings ();
  SSLeay_add_all_algorithms ();
  SSLeay_add_ssl_algorithms ();

  switch (opt.secure_protocol)
    {
    case secure_protocol_auto:
      meth = SSLv23_client_method ();
      break;
    case secure_protocol_sslv2:
      meth = SSLv2_client_method ();
      break;
    case secure_protocol_sslv3:
      meth = SSLv3_client_method ();
      break;
    case secure_protocol_tlsv1:
      meth = TLSv1_client_method ();
      break;
    default:
      abort ();
    }

  ssl_ctx = SSL_CTX_new (meth);
  if (!ssl_ctx)
    goto error;

  SSL_CTX_set_default_verify_paths (ssl_ctx);
  SSL_CTX_load_verify_locations (ssl_ctx, opt.ca_cert, opt.ca_directory);

  /* SSL_VERIFY_NONE instructs OpenSSL not to abort SSL_connect if the
     certificate is invalid.  We verify the certificate separately in
     ssl_check_certificate, which provides much better diagnostics
     than examining the error stack after a failed SSL_connect.  */
  SSL_CTX_set_verify (ssl_ctx, SSL_VERIFY_NONE, NULL);

  /* Use the private key from the cert file unless otherwise specified. */
  if (opt.cert_file && !opt.private_key)
    {
      opt.private_key = opt.cert_file;
      opt.private_key_type = opt.cert_type;
    }

  if (opt.cert_file)
    if (SSL_CTX_use_certificate_file (ssl_ctx, opt.cert_file,
                                      key_type_to_ssl_type (opt.cert_type))
        != 1)
      goto error;
  if (opt.private_key)
    if (SSL_CTX_use_PrivateKey_file (ssl_ctx, opt.private_key,
                                     key_type_to_ssl_type (opt.private_key_type))
        != 1)
      goto error;

  /* Since fd_write unconditionally assumes partial writes (and
     handles them correctly), allow them in OpenSSL.  */
  SSL_CTX_set_mode (ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);

  /* The OpenSSL library can handle renegotiations automatically, so
     tell it to do so.  */
  SSL_CTX_set_mode (ssl_ctx, SSL_MODE_AUTO_RETRY);

  return true;

 error:
  if (ssl_ctx)
    SSL_CTX_free (ssl_ctx);
  print_errors ();
  return false;
}
Ejemplo n.º 23
0
/**
 * link_init:
 * @thread_safe: if we want thread safety enabled.
 * 
 * Initialize linc.
 **/
void
link_init (gboolean thread_safe)
{
#if defined (CONNECTION_DEBUG) && defined (CONNECTION_DEBUG_FLAG)
	if (getenv ("LINK_CONNECTION_DEBUG"))
		link_connection_debug_flag = TRUE;
	if (link_connection_debug_flag &&
	    getenv ("LINK_PER_PROCESS_STDERR") &&
	    fileno (stderr) >= 0) {
		char *stderr_file = g_build_filename (g_get_tmp_dir (),
						      g_strdup_printf ("link_debug.%d", getpid ()),
						      NULL);
		int fd;
		fd = g_open (stderr_file, O_WRONLY|O_CREAT, 0666);
		if (fd >= 0) {
			char *prgname = g_get_prgname ();
			d_printf ("Redirecting stderr of %s to %s\n",
				  (prgname ? prgname : "this process"), stderr_file);
			dup2 (fd, fileno (stderr));
			close (fd);
		}
	        d_printf ("stderr redirected here\n");
	}
#endif

	if (thread_safe && !g_thread_supported ())
		g_thread_init (NULL);

	link_is_thread_safe = (thread_safe && g_thread_supported());

	g_type_init ();

#ifdef SIGPIPE
	/*
	 * Link's raison d'etre is for ORBit2 and Bonobo
	 *
	 * In Bonobo, components and containers must not crash if the
	 * remote end crashes.  If a remote server crashes and then we
	 * try to make a CORBA call on it, we may get a SIGPIPE.  So,
	 * for lack of a better solution, we ignore SIGPIPE here.  This
	 * is open for reconsideration in the future.
	 *
	 * When SIGPIPE is ignored, write() calls which would
	 * ordinarily trigger a signal will instead return -1 and set
	 * errno to EPIPE.  So linc will be able to catch these
	 * errors instead of letting them kill the component.
	 *
	 * Possibilities are the MSG_PEEK trick, where you test if the
	 * connection is dead right before doing the writev().  That
	 * approach has two problems:
	 *
	 *   1. There is the possibility of a race condition, where
	 *      the remote end calls right after the test, and right
	 *      before the writev().
	 * 
	 *   2. An extra system call per write might be regarded by
	 *      some as a performance hit.
	 *
	 * Another possibility is to surround the call to writev() in
	 * link_connection_writev (linc-connection.c) with something like
	 * this:
	 *
	 *		link_ignore_sigpipe = 1;
	 *
	 *		result = writev ( ... );
	 *
	 *		link_ignore_sigpipe = 0;
	 *
	 * The SIGPIPE signal handler will check the global
	 * link_ignore_sigpipe variable and ignore the signal if it
	 * is 1.  If it is 0, it can proxy to the user's original
	 * signal handler.  This is a real possibility.
	 */
	signal (SIGPIPE, SIG_IGN);
#endif
	
	link_context = g_main_context_new ();
	link_loop    = g_main_loop_new (link_context, TRUE);
	
#ifdef LINK_SSL_SUPPORT
	SSLeay_add_ssl_algorithms ();
	link_ssl_method = SSLv23_method ();
	link_ssl_ctx = SSL_CTX_new (link_ssl_method);
#endif

	link_main_lock = link_mutex_new ();
	link_cmd_queue_lock = link_mutex_new ();
	if (link_is_thread_safe) {
		link_main_cond = g_cond_new ();
		link_cmd_queue_cond = g_cond_new ();
	}

#ifdef HAVE_WINSOCK2_H
	{
		WSADATA wsadata;
		if (WSAStartup (MAKEWORD (2, 0), &wsadata) != 0)
			g_error ("Windows Sockets could not be initialized");
	}
#endif
}
Ejemplo n.º 24
0
Archivo: vpn.c Proyecto: BradleyZhu/VPN
//pki client
void doPKIClient(pid_t cpid, int* pipefd,char* newkeyiv,int port, int PORT, char* ip)//(int argc, char* argv[])
{
  int i;
  int err;
  int sd;
  struct sockaddr_in sa;
  SSL_CTX* ctx;//create a context for one or more ssl session
  SSL*     ssl;//hold ssl connection structure
  X509*    server_cert;
  char*    str;
  char     buf [4096];
  SSL_METHOD *meth;

  SSLeay_add_ssl_algorithms();
  meth = SSLv23_client_method();
  SSL_load_error_strings();
  ctx = SSL_CTX_new (meth);                        CHK_NULL(ctx);

  CHK_SSL(err);


  SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,NULL);
  SSL_CTX_load_verify_locations(ctx,CCACERT,NULL);//load cert, location for ca

  if (SSL_CTX_use_certificate_file(ctx, CCERTF, SSL_FILETYPE_PEM) <= 0) {//load the fisrt cert from file to ctx
	  ERR_print_errors_fp(stderr);
	  exit(-2);
  }
  
  if (SSL_CTX_use_PrivateKey_file(ctx, CKEYF, SSL_FILETYPE_PEM) <= 0) {//load private key for use with ssl
	  ERR_print_errors_fp(stderr);
	  exit(-3);
  }

  if (!SSL_CTX_check_private_key(ctx)) {//check private key with cert
	  printf("Private key does not match the certificate public keyn");
	  exit(-4);
  }
  
  /* ----------------------------------------------- */
  /* Create a socket and connect to server using normal socket calls. */
  
  sd = socket (AF_INET, SOCK_STREAM, 0);       CHK_ERR(sd, "socket");
 
  memset (&sa, '\0', sizeof(sa));
  sa.sin_family      = AF_INET;
  sa.sin_addr.s_addr = inet_addr (ip);   /* Server IP */
  sa.sin_port        = htons     (port);          /* Server Port number */
  
  err = connect(sd, (struct sockaddr*) &sa,
		sizeof(sa));                   CHK_ERR(err, "connect");

  /* ----------------------------------------------- */
  /* Now we have TCP conncetion. Start SSL negotiation. */
  
  ssl = SSL_new (ctx);                         CHK_NULL(ssl);    
  SSL_set_fd (ssl, sd);//assign a socket to ssl
//start ssl session with remote server
  err = SSL_connect (ssl);                     CHK_SSL(err);
    
  /* Following two steps are optional and not required for
     data exchange to be successful. */
  
  /* Get the cipher - opt */

  printf ("SSL connection using %s\n", SSL_get_cipher (ssl));
  
  /* Get server's certificate (note: beware of dynamic allocation) - opt */

  server_cert = SSL_get_peer_certificate (ssl);       CHK_NULL(server_cert);
  printf ("Server certificate:\n");

//blx verifying the common name

char commonName[512];
X509_NAME *name=X509_get_subject_name (server_cert);
X509_NAME_get_text_by_NID(name,NID_commonName,commonName,512);
//printf("%s\n",commonName);
if(strcmp(commonName,ServerCN)!=0)
{
printf("wrong CN\n");
exit(-1);
}
printf("right CN\n");

  str = X509_NAME_oneline (X509_get_subject_name (server_cert),0,0);
  CHK_NULL(str);
  printf ("\t subject: %s\n", str);

  OPENSSL_free (str);

  str = X509_NAME_oneline (X509_get_issuer_name  (server_cert),0,0);
  CHK_NULL(str);
  printf ("\t issuer: %s\n", str);
  OPENSSL_free (str);

  /* We could do all sorts of certificate verification stuff here before
     deallocating the certificate. */

  X509_free (server_cert);
  
  /* --------------------------------------------------- */
  /* DATA EXCHANGE - Send a message and receive a reply. */

  //generate rand iv and key as initial
  generateRandKey(newkeyiv);
  generateRandIV(newkeyiv);

  err = SSL_write (ssl, newkeyiv, 32);  CHK_SSL(err);//write new key and iv to server
  err = SSL_read (ssl, buf, sizeof(buf) - 1);                     CHK_SSL(err);//read reply from server
  buf[err] = '\0';
  //if(err == 0){continue;}
  //printf ("Got %d chars:'%s'\n", err, buf);
  printf ("%s\n", buf);
  write(pipefd[1], newkeyiv, 32);


  //not the first time, user decide
while(1){
  menuOp(cpid,newkeyiv);

  err = SSL_write (ssl, newkeyiv, 32);  CHK_SSL(err);//write new key and iv to server
  err = SSL_read (ssl, buf, sizeof(buf) - 1);                     CHK_SSL(err);//read reply from server
  buf[err] = '\0';
  //if(err == 0){continue;}
  //printf ("Got %d chars:'%s'\n", err, buf);
  printf ("%s\n", buf);
  write(pipefd[1], newkeyiv, 32);
}
  SSL_shutdown (ssl);  /* send SSL/TLS close_notify */

  /* Clean up. */

  close (sd);
  SSL_free (ssl);
  SSL_CTX_free (ctx);
}
Ejemplo n.º 25
0
Archivo: vpn.c Proyecto: BradleyZhu/VPN
//pki server
void doPKIServer(pid_t cpid, int* pipefd,char* newkeyiv, int port, int PORT, char* ip)//(int argc, char* argv[])
{
  int i;
  int err;
  int listen_sd;
  int sd;
  struct sockaddr_in sa_serv;
  struct sockaddr_in sa_cli;
  size_t client_len;
  SSL_CTX* ctx;
  SSL*     ssl;
  X509*    client_cert;
  char*    str;
  char     buf [4096];
  SSL_METHOD *meth;
  
  /* SSL preliminaries. We keep the certificate and key with the context. */

  SSL_load_error_strings();
  SSLeay_add_ssl_algorithms();
  meth = SSLv23_server_method();
  ctx = SSL_CTX_new (meth);
  if (!ctx) {
    ERR_print_errors_fp(stderr);
    exit(2);
  }

  SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER,NULL); /* whether verify the certificate */
  SSL_CTX_load_verify_locations(ctx,SCACERT,NULL);
  
  if (SSL_CTX_use_certificate_file(ctx, SCERTF, SSL_FILETYPE_PEM) <= 0) {
    ERR_print_errors_fp(stderr);
    exit(3);
  }
  if (SSL_CTX_use_PrivateKey_file(ctx, SKEYF, SSL_FILETYPE_PEM) <= 0) {
    ERR_print_errors_fp(stderr);
    exit(4);
  }

  if (!SSL_CTX_check_private_key(ctx)) {
    fprintf(stderr,"Private key does not match the certificate public key\n");
    exit(5);
  }

  /* ----------------------------------------------- */
  /* Prepare TCP socket for receiving connections */

  listen_sd = socket (AF_INET, SOCK_STREAM, 0);   CHK_ERR(listen_sd, "socket");
  
  memset (&sa_serv, '\0', sizeof(sa_serv));
  sa_serv.sin_family      = AF_INET;
  sa_serv.sin_addr.s_addr = INADDR_ANY;
  sa_serv.sin_port        = htons (PORT);          /* Server Port number */
  
  err = bind(listen_sd, (struct sockaddr*) &sa_serv,
	     sizeof (sa_serv));                   CHK_ERR(err, "bind");
	     
  /* Receive a TCP connection. */
	     
  err = listen (listen_sd, 5);                    CHK_ERR(err, "listen");
  
  client_len = sizeof(sa_cli);
  sd = accept (listen_sd, (struct sockaddr*) &sa_cli, &client_len);
  CHK_ERR(sd, "accept");
  close (listen_sd);

  printf ("Connection from %lx, port %x\n",
	  (long unsigned int)sa_cli.sin_addr.s_addr, sa_cli.sin_port);
  
  /* ----------------------------------------------- */
  /* TCP connection is ready. Do server side SSL. */

  ssl = SSL_new (ctx);                           CHK_NULL(ssl);
  SSL_set_fd (ssl, sd);
  err = SSL_accept (ssl);                        CHK_SSL(err);
  
  /* Get the cipher - opt */
  
  printf ("SSL connection using %s\n", SSL_get_cipher (ssl));
  
  /* Get client's certificate (note: beware of dynamic allocation) - opt */

  client_cert = SSL_get_peer_certificate (ssl);
  if (client_cert != NULL) {
    printf ("Client certificate:\n");


//blx verify the common name
char commonName[512];
X509_NAME *name=X509_get_subject_name (client_cert);
X509_NAME_get_text_by_NID(name,NID_commonName,commonName,512);
//printf("%s\n",commonName);
if(strcmp(commonName,ClientCN)!=0)
{
printf("wrong CN\n");
exit(-1);
}
printf("right CN\n");
  
    str = X509_NAME_oneline (X509_get_subject_name (client_cert), 0, 0);
    CHK_NULL(str);
    printf ("\t subject: %s\n", str);
    OPENSSL_free (str);
    
    str = X509_NAME_oneline (X509_get_issuer_name  (client_cert), 0, 0);
    CHK_NULL(str);
    printf ("\t issuer: %s\n", str);
    OPENSSL_free (str);
    
    /* We could do all sorts of certificate verification stuff here before
       deallocating the certificate. */
    
    X509_free (client_cert);
  } else
    printf ("Client does not have certificate.\n");

  /* DATA EXCHANGE - Receive message and send reply. */
while(1){//key read new key and iv
  err = SSL_read (ssl, buf, sizeof(buf) - 1);                   CHK_SSL(err);
  if(err ==0){continue;}
  buf[err] = '\0';
  //printf ("Got %d chars:'%s'\n", err, buf);

  for(i=0;i<32;i++)
  {
	newkeyiv[i] = buf[i];
  }
  write(pipefd[1], newkeyiv, 32);//write the new key and iv to tunnel process
  err = SSL_write (ssl, "server recieved new key or iv.", strlen("server recieved new key or iv."));  CHK_SSL(err);//write reply to client
}
  /* Clean up. */

  close (sd);
  SSL_free (ssl);
  SSL_CTX_free (ctx);
}
Ejemplo n.º 26
0
static int __ssl_setup(struct ast_tls_config *cfg, int client)
{
#ifndef DO_SSL
	cfg->enabled = 0;
	return 0;
#else
	if (!cfg->enabled)
		return 0;

	SSL_load_error_strings();
	SSLeay_add_ssl_algorithms();

	if (client) {
#ifndef OPENSSL_NO_SSL2
		if (ast_test_flag(&cfg->flags, AST_SSL_SSLV2_CLIENT)) {
			cfg->ssl_ctx = SSL_CTX_new(SSLv2_client_method());
		} else
#endif
		if (ast_test_flag(&cfg->flags, AST_SSL_SSLV3_CLIENT)) {
			cfg->ssl_ctx = SSL_CTX_new(SSLv3_client_method());
		} else if (ast_test_flag(&cfg->flags, AST_SSL_TLSV1_CLIENT)) {
			cfg->ssl_ctx = SSL_CTX_new(TLSv1_client_method());
		} else {
			/* SSLv23_client_method() sends SSLv2, this was the original
			 * default for ssl clients before the option was given to
			 * pick what protocol a client should use.  In order not
			 * to break expected behavior it remains the default. */
			cfg->ssl_ctx = SSL_CTX_new(SSLv23_client_method());
		}
	} else {
		/* SSLv23_server_method() supports TLSv1, SSLv2, and SSLv3 inbound connections. */
		cfg->ssl_ctx = SSL_CTX_new(SSLv23_server_method());
	}

	if (!cfg->ssl_ctx) {
		ast_debug(1, "Sorry, SSL_CTX_new call returned null...\n");
		cfg->enabled = 0;
		return 0;
	}
	if (!ast_strlen_zero(cfg->certfile)) {
		char *tmpprivate = ast_strlen_zero(cfg->pvtfile) ? cfg->certfile : cfg->pvtfile;
		if (SSL_CTX_use_certificate_file(cfg->ssl_ctx, cfg->certfile, SSL_FILETYPE_PEM) == 0) {
			if (!client) {
				/* Clients don't need a certificate, but if its setup we can use it */
				ast_verb(0, "SSL error loading cert file. <%s>", cfg->certfile);
				sleep(2);
				cfg->enabled = 0;
				return 0;
			}
		}
		if ((SSL_CTX_use_PrivateKey_file(cfg->ssl_ctx, tmpprivate, SSL_FILETYPE_PEM) == 0) || (SSL_CTX_check_private_key(cfg->ssl_ctx) == 0 )) {
			if (!client) {
				/* Clients don't need a private key, but if its setup we can use it */
				ast_verb(0, "SSL error loading private key file. <%s>", tmpprivate);
				sleep(2);
				cfg->enabled = 0;
				return 0;
			}
		}
	}
	if (!ast_strlen_zero(cfg->cipher)) {
		if (SSL_CTX_set_cipher_list(cfg->ssl_ctx, cfg->cipher) == 0 ) {
			if (!client) {
				ast_verb(0, "SSL cipher error <%s>", cfg->cipher);
				sleep(2);
				cfg->enabled = 0;
				return 0;
			}
		}
	}
	if (!ast_strlen_zero(cfg->cafile) || !ast_strlen_zero(cfg->capath)) {
		if (SSL_CTX_load_verify_locations(cfg->ssl_ctx, S_OR(cfg->cafile, NULL), S_OR(cfg->capath,NULL)) == 0)
			ast_verb(0, "SSL CA file(%s)/path(%s) error\n", cfg->cafile, cfg->capath);
	}

	ast_verb(0, "SSL certificate ok\n");
	return 1;
#endif
}
Ejemplo n.º 27
0
Archivo: io.c Proyecto: calestyo/icinga
/* opens data sink */
int ido_sink_open(char *name, int fd, int type, int port, int flags, int *nfd) {
	struct sockaddr_un server_address_u;
	struct sockaddr_in server_address_i;
	struct hostent *hp = NULL;
	mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
	int newfd = 0;
#ifdef HAVE_SSL
	int rc = 0;
#endif

	/* use file */
	if (type == IDO_SINK_FILE) {
		if ((newfd = open(name, flags, mode)) == -1)
			return IDO_ERROR;
	}

	/* use existing file descriptor */
	else if (type == IDO_SINK_FD) {
		if (fd < 0)
			return IDO_ERROR;
		else
			newfd = fd;
	}

	/* we are sending output to a unix domain socket */
	else if (type == IDO_SINK_UNIXSOCKET) {

		if (name == NULL)
			return IDO_ERROR;

		/* create a socket */
		if (!(newfd = socket(PF_UNIX, SOCK_STREAM, 0)))
			return IDO_ERROR;

		/* copy the socket address/path */
		strncpy(server_address_u.sun_path, name, sizeof(server_address_u.sun_path));
		server_address_u.sun_family = AF_UNIX;

		/* connect to the socket */
		if ((connect(newfd, (struct sockaddr *)&server_address_u, SUN_LEN(&server_address_u)))) {
			close(newfd);
			return IDO_ERROR;
		}
	}

	/* we are sending output to a TCP socket */
	else if (type == IDO_SINK_TCPSOCKET) {

		if (name == NULL)
			return IDO_ERROR;

#ifdef HAVE_SSL
		if (use_ssl == IDO_TRUE) {
			SSL_library_init();
			SSLeay_add_ssl_algorithms();
			meth = SSLv23_client_method();
			SSL_load_error_strings();

			if ((ctx = SSL_CTX_new(meth)) == NULL) {
				printf("IDOUtils: Error - could not create SSL context.\n");
				return IDO_ERROR;
			}
			/* ADDED 01/19/2004 */
			/* use only TLSv1 protocol */
			SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
		}
#endif

		/* clear the address */
		bzero((char *)&server_address_i, sizeof(server_address_i));

		/* try to bypass using a DNS lookup if this is just an IP address */
		if (!ido_inet_aton(name, &server_address_i.sin_addr)) {

			/* else do a DNS lookup */
			if ((hp = gethostbyname((const char *)name)) == NULL)
				return IDO_ERROR;

			memcpy(&server_address_i.sin_addr, hp->h_addr, hp->h_length);
		}

		/* create a socket */
		if (!(newfd = socket(PF_INET, SOCK_STREAM, 0)))
			return IDO_ERROR;

		/* copy the host/ip address and port */
		server_address_i.sin_family = AF_INET;
		server_address_i.sin_port = htons(port);

		/* connect to the socket */
		if ((connect(newfd, (struct sockaddr *)&server_address_i, sizeof(server_address_i)))) {
			close(newfd);
			return IDO_ERROR;
		}

#ifdef HAVE_SSL
		if (use_ssl == IDO_TRUE) {
			if ((ssl = SSL_new(ctx)) != NULL) {
				SSL_CTX_set_cipher_list(ctx, "ADH");
				SSL_set_fd(ssl, newfd);
				if ((rc = SSL_connect(ssl)) != 1) {
					printf("Error - Could not complete SSL handshake.\n");
					SSL_CTX_free(ctx);
					close(newfd);
					return IDO_ERROR;
				}
			} else {
				printf("IDOUtils: Error - Could not create SSL connection structure.\n");
				return IDO_ERROR;
			}
		}
#endif
	}

	/* unknown sink type */
	else
		return IDO_ERROR;

	/* save the new file descriptor */
	*nfd = newfd;

	return IDO_OK;
}
Ejemplo n.º 28
0
static void
handle_connect( int cnum, struct timeval* nowP, int double_check )
    {
    int url_num;
    char buf[600];
    int bytes, r;

    url_num = connections[cnum].url_num;
    if ( double_check )
	{
	/* Check to make sure the non-blocking connect succeeded. */
	int err;
	socklen_t errlen;

	if ( connect(
		 connections[cnum].conn_fd,
		 (struct sockaddr*) &connections[cnum].sa_in,
		 connections[cnum].sa_len ) < 0 )
	    {
	    switch ( errno )
		{
		case EISCONN:
		/* Ok! */
		break;
		case EINVAL:
		errlen = sizeof(err);
		if ( getsockopt( connections[cnum].conn_fd, SOL_SOCKET, SO_ERROR, (void*) &err, &errlen ) < 0 )
		    (void) fprintf(
			stderr, "%s: unknown connect error\n",
			urls[url_num].url_str );
		else
		    (void) fprintf(
			stderr, "%s: %s\n", urls[url_num].url_str,
			strerror( err ) );
		close_connection( cnum );
		return;
		default:
		perror( urls[url_num].url_str );
		close_connection( cnum );
		return;
		}
	    }
	}
#ifdef USE_SSL
    if ( urls[url_num].protocol == PROTO_HTTPS )
	{
	int flags;

	/* Make SSL connection. */
	if ( ssl_ctx == (SSL_CTX*) 0 )
	    {
	    SSL_load_error_strings();
	    SSLeay_add_ssl_algorithms();
	    ssl_ctx = SSL_CTX_new( SSLv23_client_method() );
	    if ( cipher != (char*) 0 )
		{
		if ( ! SSL_CTX_set_cipher_list( ssl_ctx, cipher ) )
		    {
		    (void) fprintf(
			stderr, "%s: cannot set cipher list\n", argv0 );
		    ERR_print_errors_fp( stderr );
		    close_connection( cnum );
		    return;
		    }
		}
	    }
	if ( ! RAND_status() )
	    {
	    unsigned char random_bytes[1024];
	    int i;
	    for ( i = 0; i < sizeof(random_bytes); ++i )
		random_bytes[i] = random() % 0xff;
	    RAND_seed( random_bytes, sizeof(random_bytes) );
	    }
	flags = fcntl( connections[cnum].conn_fd, F_GETFL, 0 );
	if ( flags != -1 )
	    (void) fcntl(
		connections[cnum].conn_fd, F_SETFL, flags & ~ (int) O_NDELAY );
	connections[cnum].ssl = SSL_new( ssl_ctx );
	SSL_set_fd( connections[cnum].ssl, connections[cnum].conn_fd );
	r = SSL_connect( connections[cnum].ssl );
	if ( r <= 0 )
	    {
	    (void) fprintf(
		stderr, "%s: SSL connection failed - %d\n", argv0, r );
	    ERR_print_errors_fp( stderr );
	    close_connection( cnum );
	    return;
	    }
	}
#endif
    connections[cnum].did_connect = 1;

    /* Format the request. */
    if ( do_proxy )
	{
#ifdef USE_SSL
	bytes = snprintf(
	    buf, sizeof(buf), "GET %s://%.500s:%d%.500s HTTP/1.0\r\n",
	    urls[url_num].protocol == PROTO_HTTPS ? "https" : "http",
	    urls[url_num].hostname, (int) urls[url_num].port,
	    urls[url_num].filename );
#else
	bytes = snprintf(
	    buf, sizeof(buf), "GET http://%.500s:%d%.500s HTTP/1.0\r\n",
	    urls[url_num].hostname, (int) urls[url_num].port,
	    urls[url_num].filename );
#endif
	}
    else
	bytes = snprintf(
	    buf, sizeof(buf), "GET %.500s HTTP/1.0\r\n",
	    urls[url_num].filename );
    bytes += snprintf(
	&buf[bytes], sizeof(buf) - bytes, "Host: %s\r\n",
	urls[url_num].hostname );
    bytes += snprintf(
	&buf[bytes], sizeof(buf) - bytes, "User-Agent: %s\r\n", HTTP_LOAD_VERSION );
    bytes += snprintf( &buf[bytes], sizeof(buf) - bytes, "\r\n" );

    /* Send the request. */
    connections[cnum].request_at = *nowP;
#ifdef USE_SSL
    if ( urls[url_num].protocol == PROTO_HTTPS )
	r = SSL_write( connections[cnum].ssl, buf, bytes );
    else
	r = write( connections[cnum].conn_fd, buf, bytes );
#else
    r = write( connections[cnum].conn_fd, buf, bytes );
#endif
    if ( r < 0 )
	{
	perror( urls[url_num].url_str );
	close_connection( cnum );
	return;
	}
    connections[cnum].conn_state = CNST_HEADERS;
    connections[cnum].header_state = HDST_LINE1_PROTOCOL;
    }
Ejemplo n.º 29
0
int main(int argc,char ** argv) {
	SSL *ssl;
	SSL_CTX *ctx;
	SSL_METHOD *client_method;
	X509 *server_cert;

	int sd,err;
	char *str,*hostname,outbuf[4096],inbuf[4096],host_header[512];
	struct hostent *host_entry;
	struct sockaddr_in server_socket_address;
	struct in_addr ip;

	//init ssl library
	SSLeay_add_ssl_algorithms();
	client_method = SSLv23_client_method();
	SSL_load_error_strings();
	ctx = SSL_CTX_new(client_method);
	printf("(1)ssl context init\n\n");

	//convert server hostname into a ip address
	hostname = argv[1];
	host_entry = gethostbyname(hostname);
	bcopy(host_entry->h_addr,&(ip.s_addr),host_entry->h_length);
	printf("(2)%s has ip address %s\n\n",hostname,inet_ntoa(ip));

	//open a tcp connection to port 443 on server

	sd = socket(AF_INET,SOCK_STREAM,0);
	memset(&server_socket_address,'\0',sizeof(server_socket_address));

	server_socket_address.sin_family = AF_INET;
	server_socket_address.sin_port = htons(443);
	memcpy(&(server_socket_address.sin_addr.s_addr),host_entry->h_addr,host_entry->h_length);


	err = connect(sd,(struct sockaddr *)&server_socket_address,sizeof(server_socket_address));
	if(err<0) {
		perror("can not connect to server port");
		exit(1);
	}
	printf("(3) tcp connection open to host %s,port %d\n\n",hostname,server_socket_address.sin_port);

	//init the ssl handshake over tcp connection
	ssl = SSL_new(ctx);
	SSL_set_fd(ssl,sd);
	err = SSL_connect(ssl);
	printf ("(4) ssl endpoint created & handshake compltete \n\n");

	//print out the negotiated cipher chosen
	printf("(5) ssl connected with cipher: %s\n\n",SSL_get_cipher(ssl));

	//print out the server's certificate
	server_cert = SSL_get_peer_certificate(ssl);
	printf("(6) server's certificate was received:\n\n");
	str = X509_NAME_oneline(X509_get_subject_name(server_cert),0,0);
	printf("\tsubject:%s\n",str);
	str = X509_NAME_oneline(X509_get_issuer_name(server_cert),0,0);
	printf("\tissuer:%s\n\n",str);

	//certificate verification would happen here
	X509_free(server_cert);

	//handshake complete--send http request over ssl

	sprintf(host_header,"Host:%s:443\r\n",hostname);
	strcpy(outbuf,"GET / HTTP/1.1\r\n");
	strcat(outbuf,host_header);
	strcat(outbuf,"Connection:close\r\n");
	strcat(outbuf,"\r\n");

	err=SSL_write(ssl,outbuf,strlen(outbuf));
	shutdown(sd,1);//send eof to server
	printf("(7) send http request over encrypted channel:\n\n%s\n",outbuf);

	//read back http response from the ssl stack
	err = SSL_read(ssl,inbuf,sizeof(inbuf)-1);
	inbuf[err]='\0';
	printf("(8)got back %d bytes of http response:\n\n%s\n",err,inbuf);

	//all done,so close connection & clean up
	SSL_shutdown(ssl);
	close(sd);
	SSL_free(ssl);
	SSL_CTX_free(ctx);
	printf("(9) all done ,cleaned up and closed connection\n\n");
	return 0;
}
Ejemplo n.º 30
-1
bool
ssl_init (void)
{
  SSL_METHOD const *meth;
  long ssl_options = 0;

#if OPENSSL_VERSION_NUMBER >= 0x00907000
  if (ssl_true_initialized == 0)
    {
      OPENSSL_config (NULL);
      ssl_true_initialized = 1;
    }
#endif

  if (ssl_ctx)
    /* The SSL has already been initialized. */
    return true;

  /* Init the PRNG.  If that fails, bail out.  */
  init_prng ();
  if (RAND_status () != 1)
    {
      logprintf (LOG_NOTQUIET,
                 _("Could not seed PRNG; consider using --random-file.\n"));
      goto error;
    }

#if OPENSSL_VERSION_NUMBER >= 0x00907000
  OPENSSL_load_builtin_modules();
  ENGINE_load_builtin_engines();
  CONF_modules_load_file(NULL, NULL,
      CONF_MFLAGS_DEFAULT_SECTION|CONF_MFLAGS_IGNORE_MISSING_FILE);
#endif
  SSL_library_init ();
  SSL_load_error_strings ();
  SSLeay_add_all_algorithms ();
  SSLeay_add_ssl_algorithms ();

  switch (opt.secure_protocol)
    {
#ifndef OPENSSL_NO_SSL2
    case secure_protocol_sslv2:
      meth = SSLv2_client_method ();
      break;
#endif

#ifndef OPENSSL_NO_SSL3
    case secure_protocol_sslv3:
      meth = SSLv3_client_method ();
      break;
#endif

    case secure_protocol_auto:
    case secure_protocol_pfs:
      meth = SSLv23_client_method ();
      ssl_options |= SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
      break;
    case secure_protocol_tlsv1:
      meth = TLSv1_client_method ();
      break;

#if OPENSSL_VERSION_NUMBER >= 0x10001000
    case secure_protocol_tlsv1_1:
      meth = TLSv1_1_client_method ();
      break;

    case secure_protocol_tlsv1_2:
      meth = TLSv1_2_client_method ();
      break;
#else
    case secure_protocol_tlsv1_1:
      logprintf (LOG_NOTQUIET, _("Your OpenSSL version is too old to support TLSv1.1\n"));
      goto error;

    case secure_protocol_tlsv1_2:
      logprintf (LOG_NOTQUIET, _("Your OpenSSL version is too old to support TLSv1.2\n"));
      goto error;
#endif

    default:
      logprintf (LOG_NOTQUIET, _("OpenSSL: unimplemented 'secure-protocol' option value %d\n"), opt.secure_protocol);
      logprintf (LOG_NOTQUIET, _("Please report this issue to [email protected]\n"));
      abort ();
    }

  /* The type cast below accommodates older OpenSSL versions (0.9.8)
     where SSL_CTX_new() is declared without a "const" argument. */
  ssl_ctx = SSL_CTX_new ((SSL_METHOD *)meth);
  if (!ssl_ctx)
    goto error;

  if (ssl_options)
    SSL_CTX_set_options (ssl_ctx, ssl_options);

  /* OpenSSL ciphers: https://www.openssl.org/docs/apps/ciphers.html
   * Since we want a good protection, we also use HIGH (that excludes MD4 ciphers and some more)
   */
  if (opt.secure_protocol == secure_protocol_pfs)
    SSL_CTX_set_cipher_list (ssl_ctx, "HIGH:MEDIUM:!RC4:!SRP:!PSK:!RSA:!aNULL@STRENGTH");

  SSL_CTX_set_default_verify_paths (ssl_ctx);
  SSL_CTX_load_verify_locations (ssl_ctx, opt.ca_cert, opt.ca_directory);

  if (opt.crl_file)
    {
      X509_STORE *store = SSL_CTX_get_cert_store (ssl_ctx);
      X509_LOOKUP *lookup;

      if (!(lookup = X509_STORE_add_lookup (store, X509_LOOKUP_file ()))
          || (!X509_load_crl_file (lookup, opt.crl_file, X509_FILETYPE_PEM)))
        goto error;

      X509_STORE_set_flags (store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
    }

  /* SSL_VERIFY_NONE instructs OpenSSL not to abort SSL_connect if the
     certificate is invalid.  We verify the certificate separately in
     ssl_check_certificate, which provides much better diagnostics
     than examining the error stack after a failed SSL_connect.  */
  SSL_CTX_set_verify (ssl_ctx, SSL_VERIFY_NONE, NULL);

  /* Use the private key from the cert file unless otherwise specified. */
  if (opt.cert_file && !opt.private_key)
    {
      opt.private_key = opt.cert_file;
      opt.private_key_type = opt.cert_type;
    }

  if (opt.cert_file)
    if (SSL_CTX_use_certificate_file (ssl_ctx, opt.cert_file,
                                      key_type_to_ssl_type (opt.cert_type))
        != 1)
      goto error;
  if (opt.private_key)
    if (SSL_CTX_use_PrivateKey_file (ssl_ctx, opt.private_key,
                                     key_type_to_ssl_type (opt.private_key_type))
        != 1)
      goto error;

  /* Since fd_write unconditionally assumes partial writes (and
     handles them correctly), allow them in OpenSSL.  */
  SSL_CTX_set_mode (ssl_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);

  /* The OpenSSL library can handle renegotiations automatically, so
     tell it to do so.  */
  SSL_CTX_set_mode (ssl_ctx, SSL_MODE_AUTO_RETRY);

  return true;

 error:
  if (ssl_ctx)
    SSL_CTX_free (ssl_ctx);
  print_errors ();
  return false;
}