⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ssluse.c

📁 harvest是一个下载html网页得机器人
💻 C
📖 第 1 页 / 共 3 页
字号:
/*************************************************************************** *                                  _   _ ____  _      *  Project                     ___| | | |  _ \| |     *                             / __| | | | |_) | |     *                            | (__| |_| |  _ <| |___  *                             \___|\___/|_| \_\_____| * * Copyright (C) 1998 - 2003, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms * are also available at http://curl.haxx.se/docs/copyright.html. *  * You may opt to use, copy, modify, merge, publish, distribute and/or sell * copies of the Software, and permit persons to whom the Software is * furnished to do so, under the terms of the COPYING file. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * * $Id: ssluse.c,v 1.84 2003/10/23 07:44:55 bagder Exp $ ***************************************************************************//* * The original SSL code for curl was written by * Linas Vepstas <linas@linas.org> and Sampo Kellomaki <sampo@iki.fi> */#include "setup.h"#include <string.h>#include <stdlib.h>#include <ctype.h>#ifdef HAVE_SYS_TYPES_H#include <sys/types.h>#endif#ifdef HAVE_SYS_SOCKET_H#include <sys/socket.h>#endif#include "urldata.h"#include "sendf.h"#include "formdata.h" /* for the boundary function */#include "url.h" /* for the ssl config check function */#include "inet_pton.h"#ifdef USE_SSLEAY#include <openssl/rand.h>#include <openssl/x509v3.h>/* The last #include file should be: */#ifdef CURLDEBUG#include "memdebug.h"#endif#if OPENSSL_VERSION_NUMBER >= 0x0090581fL#define HAVE_SSL_GET1_SESSION 1#else#undef HAVE_SSL_GET1_SESSION#endif#if OPENSSL_VERSION_NUMBER >= 0x00904100L#define HAVE_USERDATA_IN_PWD_CALLBACK 1#else#undef HAVE_USERDATA_IN_PWD_CALLBACK#endif#if OPENSSL_VERSION_NUMBER >= 0x00907001L/* ENGINE_load_private_key() takes four arguments */#define HAVE_ENGINE_LOAD_FOUR_ARGS#else/* ENGINE_load_private_key() takes three arguments */#undef HAVE_ENGINE_LOAD_FOUR_ARGS#endif#ifndef HAVE_USERDATA_IN_PWD_CALLBACKstatic char global_passwd[64];#endifstatic int passwd_callback(char *buf, int num, int verify#if HAVE_USERDATA_IN_PWD_CALLBACK                           /* This was introduced in 0.9.4, we can set this                              using SSL_CTX_set_default_passwd_cb_userdata()                              */                           , void *global_passwd#endif                           ){  if(verify)    fprintf(stderr, "%s\n", buf);  else {    if(num > (int)strlen((char *)global_passwd)) {      strcpy(buf, global_passwd);      return strlen(buf);    }  }    return 0;}staticbool seed_enough(int nread){#ifdef HAVE_RAND_STATUS  nread = 0; /* to prevent compiler warnings */  /* only available in OpenSSL 0.9.5a and later */  if(RAND_status())    return TRUE;#else  if(nread > 500)    /* this is a very silly decision to make */    return TRUE;#endif  return FALSE; /* not enough */}staticint random_the_seed(struct SessionHandle *data){  char *buf = data->state.buffer; /* point to the big buffer */  int nread=0;  /* Q: should we add support for a random file name as a libcurl option?     A: Yes, it is here */#ifndef RANDOM_FILE  /* if RANDOM_FILE isn't defined, we only perform this if an option tells     us to! */  if(data->set.ssl.random_file)#define RANDOM_FILE "" /* doesn't matter won't be used */#endif  {    /* let the option override the define */    nread += RAND_load_file((data->set.ssl.random_file?                             data->set.ssl.random_file:RANDOM_FILE),                            16384);    if(seed_enough(nread))      return nread;  }#if defined(HAVE_RAND_EGD)  /* only available in OpenSSL 0.9.5 and later */  /* EGD_SOCKET is set at configure time or not at all */#ifndef EGD_SOCKET  /* If we don't have the define set, we only do this if the egd-option     is set */  if(data->set.ssl.egdsocket)#define EGD_SOCKET "" /* doesn't matter won't be used */#endif  {    /* If there's an option and a define, the option overrides the       define */    int ret = RAND_egd(data->set.ssl.egdsocket?                       data->set.ssl.egdsocket:EGD_SOCKET);    if(-1 != ret) {      nread += ret;      if(seed_enough(nread))        return nread;    }  }#endif  /* If we get here, it means we need to seed the PRNG using a "silly"     approach! */#ifdef HAVE_RAND_SCREEN  /* This one gets a random value by reading the currently shown screen */  RAND_screen();  nread = 100; /* just a value */#else  {    int len;    char *area;    /* Changed call to RAND_seed to use the underlying RAND_add implementation     * directly.  Do this in a loop, with the amount of additional entropy     * being dependent upon the algorithm used by Curl_FormBoundary(): N bytes     * of a 7-bit ascii set. -- Richard Gorton, March 11 2003.     */	    do {      area = Curl_FormBoundary();      if(!area)        return 3; /* out of memory */	      len = strlen(area);      RAND_add(area, len, (len >> 1));      free(area); /* now remove the random junk */    } while (!RAND_status());  }#endif  /* generates a default path for the random seed file */  buf[0]=0; /* blank it first */  RAND_file_name(buf, BUFSIZE);  if(buf[0]) {    /* we got a file name to try */    nread += RAND_load_file(buf, 16384);    if(seed_enough(nread))      return nread;  }  infof(data, "libcurl is now using a weak random seed!\n");  return nread;}#ifndef SSL_FILETYPE_ENGINE#define SSL_FILETYPE_ENGINE 42#endifstatic int do_file_type(const char *type){  if(!type || !type[0])    return SSL_FILETYPE_PEM;  if(curl_strequal(type, "PEM"))    return SSL_FILETYPE_PEM;  if(curl_strequal(type, "DER"))    return SSL_FILETYPE_ASN1;  if(curl_strequal(type, "ENG"))    return SSL_FILETYPE_ENGINE;  return -1;}staticint cert_stuff(struct connectdata *conn,               char *cert_file,               const char *cert_type,               char *key_file,               const char *key_type){  struct SessionHandle *data = conn->data;  int file_type;  if(cert_file != NULL) {    SSL *ssl;    X509 *x509;    if(data->set.key_passwd) {#ifndef HAVE_USERDATA_IN_PWD_CALLBACK      /*       * If password has been given, we store that in the global       * area (*shudder*) for a while:       */      strcpy(global_passwd, data->set.key_passwd);#else      /*       * We set the password in the callback userdata       */      SSL_CTX_set_default_passwd_cb_userdata(conn->ssl.ctx,                                             data->set.key_passwd);#endif      /* Set passwd callback: */      SSL_CTX_set_default_passwd_cb(conn->ssl.ctx, passwd_callback);    }    file_type = do_file_type(cert_type);    switch(file_type) {    case SSL_FILETYPE_PEM:      /* SSL_CTX_use_certificate_chain_file() only works on PEM files */      if(SSL_CTX_use_certificate_chain_file(conn->ssl.ctx,                                             cert_file) != 1) {        failf(data, "unable to set certificate file (wrong password?)");        return 0;      }      break;    case SSL_FILETYPE_ASN1:      /* SSL_CTX_use_certificate_file() works with either PEM or ASN1, but         we use the case above for PEM so this can only be performed with         ASN1 files. */      if(SSL_CTX_use_certificate_file(conn->ssl.ctx,                                       cert_file,                                       file_type) != 1) {        failf(data, "unable to set certificate file (wrong password?)");        return 0;      }      break;    case SSL_FILETYPE_ENGINE:      failf(data, "file type ENG for certificate not implemented");      return 0;    default:      failf(data, "not supported file type '%s' for certificate", cert_type);      return 0;    }    file_type = do_file_type(key_type);    switch(file_type) {    case SSL_FILETYPE_PEM:      if(key_file == NULL)        /* cert & key can only be in PEM case in the same file */        key_file=cert_file;    case SSL_FILETYPE_ASN1:      if(SSL_CTX_use_PrivateKey_file(conn->ssl.ctx,                                      key_file,                                      file_type) != 1) {        failf(data, "unable to set private key file: '%s' type %s\n",              key_file, key_type?key_type:"PEM");        return 0;      }      break;    case SSL_FILETYPE_ENGINE:#ifdef HAVE_OPENSSL_ENGINE_H      {                         /* XXXX still needs some work */        EVP_PKEY *priv_key = NULL;        if(conn && conn->data && conn->data->engine) {#ifdef HAVE_ENGINE_LOAD_FOUR_ARGS          UI_METHOD *ui_method = UI_OpenSSL();#endif          if(!key_file || !key_file[0]) {            failf(data, "no key set to load from crypto engine\n");            return 0;          }          priv_key = ENGINE_load_private_key(conn->data->engine,key_file,#ifdef HAVE_ENGINE_LOAD_FOUR_ARGS                                             ui_method,#endif                                             data->set.key_passwd);          if(!priv_key) {            failf(data, "failed to load private key from crypto engine\n");            return 0;          }          if(SSL_CTX_use_PrivateKey(conn->ssl.ctx, priv_key) != 1) {            failf(data, "unable to set private key\n");            EVP_PKEY_free(priv_key);            return 0;          }          EVP_PKEY_free(priv_key);  /* we don't need the handle any more... */        }        else {          failf(data, "crypto engine not set, can't load private key\n");          return 0;        }      }#else      failf(data, "file type ENG for private key not supported\n");      return 0;#endif      break;    default:      failf(data, "not supported file type for private key\n");      return 0;    }    ssl=SSL_new(conn->ssl.ctx);    x509=SSL_get_certificate(ssl);    /* This version was provided by Evan Jordan and is supposed to not       leak memory as the previous version: */    if(x509 != NULL) {      EVP_PKEY *pktmp = X509_get_pubkey(x509);      EVP_PKEY_copy_parameters(pktmp,SSL_get_privatekey(ssl));      EVP_PKEY_free(pktmp);    }    SSL_free(ssl);    /* If we are using DSA, we can copy the parameters from     * the private key */		        /* Now we know that a key and cert have been set against     * the SSL context */    if(!SSL_CTX_check_private_key(conn->ssl.ctx)) {      failf(data, "Private key does not match the certificate public key");      return(0);    }#ifndef HAVE_USERDATA_IN_PWD_CALLBACK        /* erase it now */    memset(global_passwd, 0, sizeof(global_passwd));#endif  }  return(1);}staticint cert_verify_callback(int ok, X509_STORE_CTX *ctx){  X509 *err_cert;  char buf[256];  err_cert=X509_STORE_CTX_get_current_cert(ctx);  X509_NAME_oneline(X509_get_subject_name(err_cert),buf,256);  return ok;}#endif#ifdef USE_SSLEAY/* "global" init done? */static int init_ssl=0;/* we have the "SSL is seeded" boolean global for the application to   prevent multiple time-consuming seedings in vain */static bool ssl_seeded = FALSE;#endif/* Global init */void Curl_SSL_init(void){#ifdef USE_SSLEAY  /* make sure this is only done once */  if(0 != init_ssl)    return;  init_ssl++; /* never again */#ifdef HAVE_ENGINE_LOAD_BUILTIN_ENGINES  ENGINE_load_builtin_engines();#endif  /* Lets get nice error messages */  SSL_load_error_strings();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -