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

📄 security.c

📁 harvest是一个下载html网页得机器人
💻 C
字号:
/* This source code was modified by Martin Hedenfalk <mhe@stacken.kth.se> for * use in Curl. His latest changes were done 2000-09-18. * * It has since been patched and modified a lot by Daniel Stenberg * <daniel@haxx.se> to make it better applied to curl conditions, and to make * it not use globals, pollute name space and more. This source code awaits a * rewrite to work around the paragraph 2 in the BSD licenses as explained * below. * * Copyright (c) 1998, 1999 Kungliga Tekniska H鰃skolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: *  * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. *  * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. *  * 3. Neither the name of the Institute nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. *  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE.  */#include "setup.h"#ifndef CURL_DISABLE_FTP#ifdef KRB4#define _MPRINTF_REPLACE /* we want curl-functions instead of native ones */#include <curl/mprintf.h>#include "security.h"#include <stdlib.h>#include <string.h>#include <netdb.h>#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#include "base64.h"#include "sendf.h"#include "ftp.h"/* The last #include file should be: */#ifdef CURLDEBUG#include "memdebug.h"#endif#define min(a, b)   ((a) < (b) ? (a) : (b))static struct {    enum protection_level level;    const char *name;} level_names[] = {    { prot_clear, "clear" },    { prot_safe, "safe" },    { prot_confidential, "confidential" },    { prot_private, "private" }};static enum protection_level name_to_level(const char *name){  int i;  for(i = 0; i < (int)sizeof(level_names)/(int)sizeof(level_names[0]); i++)    if(!strncasecmp(level_names[i].name, name, strlen(name)))      return level_names[i].level;  return (enum protection_level)-1;}static struct Curl_sec_client_mech *mechs[] = {#ifdef KRB5  /* not supported */#endif#ifdef KRB4    &Curl_krb4_client_mech,#endif    NULL};intCurl_sec_getc(struct connectdata *conn, FILE *F){  if(conn->sec_complete && conn->data_prot) {    char c;    if(Curl_sec_read(conn, fileno(F), &c, 1) <= 0)      return EOF;    return c;  }  else    return getc(F);}static intblock_read(int fd, void *buf, size_t len){  unsigned char *p = buf;  int b;  while(len) {    b = read(fd, p, len);    if (b == 0)      return 0;    else if (b < 0)      return -1;    len -= b;    p += b;  }  return p - (unsigned char*)buf;}static intblock_write(int fd, void *buf, size_t len){  unsigned char *p = buf;  int b;  while(len) {    b = write(fd, p, len);    if(b < 0)      return -1;    len -= b;    p += b;  }  return p - (unsigned char*)buf;}static intsec_get_data(struct connectdata *conn,             int fd, struct krb4buffer *buf){  int len;  int b;    b = block_read(fd, &len, sizeof(len));  if (b == 0)    return 0;  else if (b < 0)    return -1;  len = ntohl(len);  buf->data = realloc(buf->data, len);  b = block_read(fd, buf->data, len);  if (b == 0)    return 0;  else if (b < 0)    return -1;  buf->size = (conn->mech->decode)(conn->app_data, buf->data, len,                                   conn->data_prot, conn);  buf->index = 0;  return 0;}static size_tbuffer_read(struct krb4buffer *buf, void *data, size_t len){    len = min(len, buf->size - buf->index);    memcpy(data, (char*)buf->data + buf->index, len);    buf->index += len;    return len;}static size_tbuffer_write(struct krb4buffer *buf, void *data, size_t len){    if(buf->index + len > buf->size) {	void *tmp;	if(buf->data == NULL)	    tmp = malloc(1024);	else	    tmp = realloc(buf->data, buf->index + len);	if(tmp == NULL)	    return -1;	buf->data = tmp;	buf->size = buf->index + len;    }    memcpy((char*)buf->data + buf->index, data, len);    buf->index += len;    return len;}intCurl_sec_read(struct connectdata *conn, int fd, void *buffer, int length){    size_t len;    int rx = 0;    if(conn->sec_complete == 0 || conn->data_prot == 0)      return read(fd, buffer, length);    if(conn->in_buffer.eof_flag){      conn->in_buffer.eof_flag = 0;      return 0;    }        len = buffer_read(&conn->in_buffer, buffer, length);    length -= len;    rx += len;    buffer = (char*)buffer + len;        while(length) {      if(sec_get_data(conn, fd, &conn->in_buffer) < 0)        return -1;      if(conn->in_buffer.size == 0) {        if(rx)          conn->in_buffer.eof_flag = 1;        return rx;      }      len = buffer_read(&conn->in_buffer, buffer, length);      length -= len;      rx += len;      buffer = (char*)buffer + len;    }    return rx;}static intsec_send(struct connectdata *conn, int fd, char *from, int length){  int bytes;  void *buf;  bytes = (conn->mech->encode)(conn->app_data, from, length, conn->data_prot,                               &buf, conn);  bytes = htonl(bytes);  block_write(fd, &bytes, sizeof(bytes));  block_write(fd, buf, ntohl(bytes));  free(buf);  return length;}intCurl_sec_fflush_fd(struct connectdata *conn, int fd){  if(conn->data_prot != prot_clear) {    if(conn->out_buffer.index > 0){      Curl_sec_write(conn, fd,                conn->out_buffer.data, conn->out_buffer.index);      conn->out_buffer.index = 0;    }    sec_send(conn, fd, NULL, 0);  }  return 0;}intCurl_sec_write(struct connectdata *conn, int fd, char *buffer, int length){  int len = conn->buffer_size;  int tx = 0;        if(conn->data_prot == prot_clear)    return write(fd, buffer, length);  len -= (conn->mech->overhead)(conn->app_data, conn->data_prot, len);  while(length){    if(length < len)      len = length;    sec_send(conn, fd, buffer, len);    length -= len;    buffer += len;    tx += len;  }  return tx;}intCurl_sec_putc(struct connectdata *conn, int c, FILE *F){  char ch = c;  if(conn->data_prot == prot_clear)    return putc(c, F);      buffer_write(&conn->out_buffer, &ch, 1);  if(c == '\n' || conn->out_buffer.index >= 1024 /* XXX */) {    Curl_sec_write(conn, fileno(F), conn->out_buffer.data,                   conn->out_buffer.index);    conn->out_buffer.index = 0;  }  return c;}intCurl_sec_read_msg(struct connectdata *conn, char *s, int level){    int len;    char *buf;    int code;        buf = malloc(strlen(s));    len = Curl_base64_decode(s + 4, buf); /* XXX */        len = (conn->mech->decode)(conn->app_data, buf, len, level, conn);    if(len < 0)	return -1;        buf[len] = '\0';    if(buf[3] == '-')	code = 0;    else	sscanf(buf, "%d", &code);    if(buf[len-1] == '\n')	buf[len-1] = '\0';    strcpy(s, buf);    free(buf);    return code;}enum protection_levelCurl_set_command_prot(struct connectdata *conn, enum protection_level level){    enum protection_level old = conn->command_prot;    conn->command_prot = level;    return old;}static intsec_prot_internal(struct connectdata *conn, int level){  char *p;  unsigned int s = 1048576;  ssize_t nread;  if(!conn->sec_complete){    infof(conn->data, "No security data exchange has taken place.\n");    return -1;  }  if(level){    int code;    if(Curl_ftpsendf(conn, "PBSZ %u", s))      return -1;    if(Curl_GetFTPResponse(&nread, conn, &code))      return -1;    if(code/100 != '2'){      failf(conn->data, "Failed to set protection buffer size.");      return -1;    }    conn->buffer_size = s;    p = strstr(conn->data->state.buffer, "PBSZ=");    if(p)      sscanf(p, "PBSZ=%u", &s);    if(s < conn->buffer_size)      conn->buffer_size = s;  }  if(Curl_ftpsendf(conn, "PROT %c", level["CSEP"]))    return -1;  if(Curl_GetFTPResponse(&nread, conn, NULL))    return -1;  if(conn->data->state.buffer[0] != '2'){    failf(conn->data, "Failed to set protection level.");    return -1;  }      conn->data_prot = (enum protection_level)level;  return 0;}voidCurl_sec_set_protection_level(struct connectdata *conn){  if(conn->sec_complete && conn->data_prot != conn->request_data_prot)    sec_prot_internal(conn, conn->request_data_prot);}intCurl_sec_request_prot(struct connectdata *conn, const char *level){  int l = name_to_level(level);  if(l == -1)    return -1;  conn->request_data_prot = (enum protection_level)l;  return 0;}intCurl_sec_login(struct connectdata *conn){  int ret;  struct Curl_sec_client_mech **m;  ssize_t nread;  struct SessionHandle *data=conn->data;  int ftpcode;  for(m = mechs; *m && (*m)->name; m++) {    void *tmp;    tmp = realloc(conn->app_data, (*m)->size);    if (tmp == NULL) {      failf (data, "realloc %u failed", (*m)->size);      return -1;    }    conn->app_data = tmp;	        if((*m)->init && (*(*m)->init)(conn->app_data) != 0) {      infof(data, "Skipping %s...\n", (*m)->name);      continue;    }    infof(data, "Trying %s...\n", (*m)->name);    if(Curl_ftpsendf(conn, "AUTH %s", (*m)->name))      return -1;    if(Curl_GetFTPResponse(&nread, conn, &ftpcode))      return -1;    if(conn->data->state.buffer[0] != '3'){      switch(ftpcode) {      case 504:        infof(data,              "%s is not supported by the server.\n", (*m)->name);        break;      case 534:        infof(data, "%s rejected as security mechanism.\n", (*m)->name);        break;      default:        if(conn->data->state.buffer[0] == '5') {          infof(data, "The server doesn't support the FTP "                "security extensions.\n");          return -1;        }        break;      }      continue;    }    ret = (*(*m)->auth)(conn->app_data, conn);	    if(ret == AUTH_CONTINUE)      continue;    else if(ret != AUTH_OK){      /* mechanism is supposed to output error string */      return -1;    }    conn->mech = *m;    conn->sec_complete = 1;    conn->command_prot = prot_safe;    break;  }      return *m == NULL;}voidCurl_sec_end(struct connectdata *conn){  if (conn->mech != NULL) {    if(conn->mech->end)      (conn->mech->end)(conn->app_data);    memset(conn->app_data, 0, conn->mech->size);    free(conn->app_data);    conn->app_data = NULL;  }  conn->sec_complete = 0;  conn->data_prot = (enum protection_level)0;  conn->mech=NULL;}#endif /* KRB4 */#endif /* CURL_DISABLE_FTP */

⌨️ 快捷键说明

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