int create_request(t_conf *conf, void *output, t_request *req) { char name[MAX_HOST_NAME_ENCODED + 1]; struct dns_hdr *hdr; int len; hdr = (struct dns_hdr *) output; create_req_hdr(conf, hdr); if ((ENCODED_LEN(BASE64_SIZE(req->len)) + strlen(req->domain) + 2 ) > (MAX_HOST_NAME_ENCODED)) { #ifndef _WIN32 fprintf(stderr, "send_query : data too long (%d bytes -> %zd bytes)\n", #else fprintf(stderr, "send_query : data too long (%d bytes -> %d bytes)\n", #endif req->len, ENCODED_LEN(BASE64_SIZE(req->len)) + strlen(req->domain) + 2 ); return (0); }
/* * Calculate the chksum of a whole file and updates: * - digest * - digest_stream * - digest_buffer * - digest_name * * Returns: true if digest calculation succeeded. * false if digest calculation failed. */ static bool calculate_file_chksum(JCR *jcr, FF_PKT *ff_pkt, DIGEST **digest, int *digest_stream, char **digest_buf, const char **digest_name) { /* * Create our digest context. * If this fails, the digest will be set to NULL and not used. */ if (ff_pkt->flags & FO_MD5) { *digest = crypto_digest_new(jcr, CRYPTO_DIGEST_MD5); *digest_stream = STREAM_MD5_DIGEST; } else if (ff_pkt->flags & FO_SHA1) { *digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA1); *digest_stream = STREAM_SHA1_DIGEST; } else if (ff_pkt->flags & FO_SHA256) { *digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA256); *digest_stream = STREAM_SHA256_DIGEST; } else if (ff_pkt->flags & FO_SHA512) { *digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA512); *digest_stream = STREAM_SHA512_DIGEST; } /* * compute MD5 or SHA1 hash */ if (*digest) { uint32_t size; char md[CRYPTO_DIGEST_MAX_SIZE]; size = sizeof(md); if (digest_file(jcr, ff_pkt, *digest) != 0) { jcr->JobErrors++; return false; } if (crypto_digest_finalize(*digest, (uint8_t *)md, &size)) { *digest_buf = (char *)malloc(BASE64_SIZE(size)); *digest_name = crypto_digest_name(*digest); bin_to_base64(*digest_buf, BASE64_SIZE(size), md, size, true); } } return true; }
/** Store a ntlm authorization challenge. */ static int auc_ntlm_challenge(auth_client_t *ca, msg_auth_t const *ch) { su_home_t *home = ca->ca_home; auth_ntlm_client_t *ntlm = (auth_ntlm_client_t *)ca; auth_challenge_t ac[1] = {{ sizeof ac }}; int stale; if (auth_ntlm_challenge_get(home, ac, ch->au_params) < 0) goto error; /* Check that we can handle the challenge */ if (!ac->ac_md5 && !ac->ac_md5sess) goto error; if (ac->ac_qop && !ac->ac_auth && !ac->ac_auth_int) goto error; stale = ac->ac_stale || str0cmp(ac->ac_nonce, ntlm->ntlm_ac->ac_nonce); if (ac->ac_qop && (ntlm->ntlm_cnonce == NULL || ac->ac_stale)) { su_guid_t guid[1]; char *cnonce; if (ntlm->ntlm_cnonce != NULL) /* Free the old one if we are updating after stale=true */ su_free(home, (void *)ntlm->ntlm_cnonce); su_guid_generate(guid); ntlm->ntlm_cnonce = cnonce = su_alloc(home, BASE64_SIZE(sizeof(guid)) + 1); base64_e(cnonce, BASE64_SIZE(sizeof(guid)) + 1, guid, sizeof(guid)); ntlm->ntlm_ncount = 0; } auth_ntlm_challenge_free_params(home, ntlm->ntlm_ac); *ntlm->ntlm_ac = *ac; return stale ? 2 : 1; error: auth_ntlm_challenge_free_params(home, ac); return -1; }
int build_error_reply(t_conf *conf, void *req, int max_len, char *error) { struct dns_hdr *hdr; void *where; t_packet *packet; char buffer[BASE64_SIZE(MAX_ERROR_SIZE) + PACKET_LEN]; char buffer2[BASE64_SIZE(MAX_ERROR_SIZE) + PACKET_LEN]; int len; hdr = req; hdr->ra = 1; hdr->qr = 1; if (!(where = jump_end_query(req, GET_16(&hdr->qdcount), max_len))) return (-1); packet = (t_packet *) memset(buffer, 0, PACKET_LEN); packet->type = ERR; len = strlen(error); memcpy(buffer+PACKET_LEN, error, len+1); base64_encode(buffer, buffer2, PACKET_LEN + len); where = add_reply(hdr, where, TYPE_KEY, buffer2); return (where - req); }
char* basic_authentication_encode(const char *user, const char *passwd) { /* prepare the user:pass key pair */ int pair_len = strlen(user) + 1 + strlen(passwd); char pair[pair_len + 1]; sprintf(pair, "%s:%s", user, passwd); /* calculate the final string length */ int basic_len = BASE64_SIZE(pair_len); char *basic_ptr = calloc(basic_len + 1, 1); if (!base64_encode(basic_ptr, basic_len, (const uint8_t*)pair, pair_len)) return NULL; return basic_ptr; }
/* * Note, we receive the whole attribute record, but we select out only the stat * packet, VolSessionId, VolSessionTime, FileIndex, file type, and file name to * store in the catalog. */ static void update_attribute(JCR *jcr, char *msg, int32_t msglen) { unser_declare; uint32_t VolSessionId, VolSessionTime; int32_t Stream; uint32_t FileIndex; char *p; int len; char *fname, *attr; ATTR_DBR *ar = NULL; uint32_t reclen; /* * Start transaction allocates jcr->attr and jcr->ar if needed */ db_start_transaction(jcr, jcr->db); /* start transaction if not already open */ ar = jcr->ar; /* * Start by scanning directly in the message buffer to get Stream * there may be a cached attr so we cannot yet write into * jcr->attr or jcr->ar */ p = msg; skip_nonspaces(&p); /* UpdCat */ skip_spaces(&p); skip_nonspaces(&p); /* Job=nnn */ skip_spaces(&p); skip_nonspaces(&p); /* "FileAttributes" */ p += 1; /* * The following "SD header" fields are serialized */ unser_begin(p, 0); unser_uint32(VolSessionId); /* VolSessionId */ unser_uint32(VolSessionTime); /* VolSessionTime */ unser_int32(FileIndex); /* FileIndex */ unser_int32(Stream); /* Stream */ unser_uint32(reclen); /* Record length */ p += unser_length(p); /* Raw record follows */ /** * At this point p points to the raw record, which varies according * to what kind of a record (Stream) was sent. Note, the integer * fields at the beginning of these "raw" records are in ASCII with * spaces between them so one can use scanf or manual scanning to * extract the fields. * * File Attributes * File_index * File type * Filename (full path) * Encoded attributes * Link name (if type==FT_LNK or FT_LNKSAVED) * Encoded extended-attributes (for Win32) * Delta sequence number (32 bit int) * * Restore Object * File_index * File_type * Object_index * Object_len (possibly compressed) * Object_full_len (not compressed) * Object_compression * Plugin_name * Object_name * Binary Object data */ Dmsg1(400, "UpdCat msg=%s\n", msg); Dmsg5(400, "UpdCat VolSessId=%d VolSessT=%d FI=%d Strm=%d reclen=%d\n", VolSessionId, VolSessionTime, FileIndex, Stream, reclen); jcr->SDJobBytes += reclen; /* update number of bytes transferred for quotas */ /* * Depending on the stream we are handling dispatch. */ switch (Stream) { case STREAM_UNIX_ATTRIBUTES: case STREAM_UNIX_ATTRIBUTES_EX: if (jcr->cached_attribute) { Dmsg2(400, "Cached attr. Stream=%d fname=%s\n", ar->Stream, ar->fname); if (!db_create_attributes_record(jcr, jcr->db, ar)) { Jmsg1(jcr, M_FATAL, 0, _("Attribute create error: ERR=%s"), db_strerror(jcr->db)); } jcr->cached_attribute = false; } /* * Any cached attr is flushed so we can reuse jcr->attr and jcr->ar */ jcr->attr = check_pool_memory_size(jcr->attr, msglen); memcpy(jcr->attr, msg, msglen); p = jcr->attr - msg + p; /* point p into jcr->attr */ skip_nonspaces(&p); /* skip FileIndex */ skip_spaces(&p); ar->FileType = str_to_int32(p); skip_nonspaces(&p); /* skip FileType */ skip_spaces(&p); fname = p; len = strlen(fname); /* length before attributes */ attr = &fname[len+1]; ar->DeltaSeq = 0; if (ar->FileType == FT_REG) { p = attr + strlen(attr) + 1; /* point to link */ p = p + strlen(p) + 1; /* point to extended attributes */ p = p + strlen(p) + 1; /* point to delta sequence */ /* * Older FDs don't have a delta sequence, so check if it is there */ if (p - jcr->attr < msglen) { ar->DeltaSeq = str_to_int32(p); /* delta_seq */ } } Dmsg2(400, "dird<stored: stream=%d %s\n", Stream, fname); Dmsg1(400, "dird<stored: attr=%s\n", attr); ar->attr = attr; ar->fname = fname; if (ar->FileType == FT_DELETED) { ar->FileIndex = 0; /* special value */ } else { ar->FileIndex = FileIndex; } ar->Stream = Stream; ar->link = NULL; if (jcr->mig_jcr) { ar->JobId = jcr->mig_jcr->JobId; } else { ar->JobId = jcr->JobId; } ar->Digest = NULL; ar->DigestType = CRYPTO_DIGEST_NONE; jcr->cached_attribute = true; Dmsg2(400, "dird<filed: stream=%d %s\n", Stream, fname); Dmsg1(400, "dird<filed: attr=%s\n", attr); break; case STREAM_RESTORE_OBJECT: { ROBJECT_DBR ro; memset(&ro, 0, sizeof(ro)); ro.Stream = Stream; ro.FileIndex = FileIndex; if (jcr->mig_jcr) { ro.JobId = jcr->mig_jcr->JobId; } else { ro.JobId = jcr->JobId; } Dmsg1(100, "Robj=%s\n", p); skip_nonspaces(&p); /* skip FileIndex */ skip_spaces(&p); ro.FileType = str_to_int32(p); /* FileType */ skip_nonspaces(&p); skip_spaces(&p); ro.object_index = str_to_int32(p); /* Object Index */ skip_nonspaces(&p); skip_spaces(&p); ro.object_len = str_to_int32(p); /* object length possibly compressed */ skip_nonspaces(&p); skip_spaces(&p); ro.object_full_len = str_to_int32(p); /* uncompressed object length */ skip_nonspaces(&p); skip_spaces(&p); ro.object_compression = str_to_int32(p); /* compression */ skip_nonspaces(&p); skip_spaces(&p); ro.plugin_name = p; /* point to plugin name */ len = strlen(ro.plugin_name); ro.object_name = &ro.plugin_name[len+1]; /* point to object name */ len = strlen(ro.object_name); ro.object = &ro.object_name[len+1]; /* point to object */ ro.object[ro.object_len] = 0; /* add zero for those who attempt printing */ Dmsg7(100, "oname=%s stream=%d FT=%d FI=%d JobId=%d, obj_len=%d\nobj=\"%s\"\n", ro.object_name, ro.Stream, ro.FileType, ro.FileIndex, ro.JobId, ro.object_len, ro.object); /* * Store it. */ if (!db_create_restore_object_record(jcr, jcr->db, &ro)) { Jmsg1(jcr, M_FATAL, 0, _("Restore object create error. %s"), db_strerror(jcr->db)); } break; } default: if (crypto_digest_stream_type(Stream) != CRYPTO_DIGEST_NONE) { fname = p; if (ar->FileIndex != FileIndex) { Jmsg3(jcr, M_WARNING, 0, _("%s not same File=%d as attributes=%d\n"), stream_to_ascii(Stream), FileIndex, ar->FileIndex); } else { /* * Update digest in catalog */ char digestbuf[BASE64_SIZE(CRYPTO_DIGEST_MAX_SIZE)]; int len = 0; int type = CRYPTO_DIGEST_NONE; switch(Stream) { case STREAM_MD5_DIGEST: len = CRYPTO_DIGEST_MD5_SIZE; type = CRYPTO_DIGEST_MD5; break; case STREAM_SHA1_DIGEST: len = CRYPTO_DIGEST_SHA1_SIZE; type = CRYPTO_DIGEST_SHA1; break; case STREAM_SHA256_DIGEST: len = CRYPTO_DIGEST_SHA256_SIZE; type = CRYPTO_DIGEST_SHA256; break; case STREAM_SHA512_DIGEST: len = CRYPTO_DIGEST_SHA512_SIZE; type = CRYPTO_DIGEST_SHA512; break; default: /* * Never reached ... */ Jmsg(jcr, M_ERROR, 0, _("Catalog error updating file digest. Unsupported digest stream type: %d"), Stream); } bin_to_base64(digestbuf, sizeof(digestbuf), fname, len, true); Dmsg3(400, "DigestLen=%d Digest=%s type=%d\n", strlen(digestbuf), digestbuf, Stream); if (jcr->cached_attribute) { ar->Digest = digestbuf; ar->DigestType = type; Dmsg2(400, "Cached attr with digest. Stream=%d fname=%s\n", ar->Stream, ar->fname); /* * Update BaseFile table */ if (!db_create_attributes_record(jcr, jcr->db, ar)) { Jmsg1(jcr, M_FATAL, 0, _("attribute create error. %s"), db_strerror(jcr->db)); } jcr->cached_attribute = false; } else { if (!db_add_digest_to_file_record(jcr, jcr->db, ar->FileId, digestbuf, type)) { Jmsg(jcr, M_ERROR, 0, _("Catalog error updating file digest. %s"), db_strerror(jcr->db)); } } } } break; } }
/* * Verify attributes of the requested files on the Volume * */ void do_verify_volume(JCR *jcr) { BSOCK *sd, *dir; POOLMEM *fname; /* original file name */ POOLMEM *lname; /* link name */ int32_t stream; uint32_t size; uint32_t VolSessionId, VolSessionTime, file_index; uint32_t record_file_index; char digest[BASE64_SIZE(CRYPTO_DIGEST_MAX_SIZE)]; int type, stat; sd = jcr->store_bsock; if (!sd) { Jmsg(jcr, M_FATAL, 0, _("Storage command not issued before Verify.\n")); jcr->setJobStatus(JS_FatalError); return; } dir = jcr->dir_bsock; jcr->setJobStatus(JS_Running); LockRes(); CLIENT *client = (CLIENT *)GetNextRes(R_CLIENT, NULL); UnlockRes(); uint32_t buf_size; if (client) { buf_size = client->max_network_buffer_size; } else { buf_size = 0; /* use default */ } if (!sd->set_buffer_size(buf_size, BNET_SETBUF_WRITE)) { jcr->setJobStatus(JS_FatalError); return; } jcr->buf_size = sd->msglen; fname = get_pool_memory(PM_FNAME); lname = get_pool_memory(PM_FNAME); /* * Get a record from the Storage daemon */ while (bget_msg(sd) >= 0 && !job_canceled(jcr)) { /* * First we expect a Stream Record Header */ if (sscanf(sd->msg, rec_header, &VolSessionId, &VolSessionTime, &file_index, &stream, &size) != 5) { Jmsg1(jcr, M_FATAL, 0, _("Record header scan error: %s\n"), sd->msg); goto bail_out; } Dmsg3(30, "Got hdr: FilInx=%d Stream=%d size=%d.\n", file_index, stream, size); /* * Now we expect the Stream Data */ if (bget_msg(sd) < 0) { Jmsg1(jcr, M_FATAL, 0, _("Data record error. ERR=%s\n"), sd->bstrerror()); goto bail_out; } if (size != ((uint32_t)sd->msglen)) { Jmsg2(jcr, M_FATAL, 0, _("Actual data size %d not same as header %d\n"), sd->msglen, size); goto bail_out; } Dmsg2(30, "Got stream data %s, len=%d\n", stream_to_ascii(stream), sd->msglen); /* File Attributes stream */ switch (stream) { case STREAM_UNIX_ATTRIBUTES: case STREAM_UNIX_ATTRIBUTES_EX: char *ap, *lp, *fp; Dmsg0(400, "Stream=Unix Attributes.\n"); if ((int)sizeof_pool_memory(fname) < sd->msglen) { fname = realloc_pool_memory(fname, sd->msglen + 1); } if ((int)sizeof_pool_memory(lname) < sd->msglen) { lname = realloc_pool_memory(lname, sd->msglen + 1); } *fname = 0; *lname = 0; /* * An Attributes record consists of: * File_index * Type (FT_types) * Filename * Attributes * Link name (if file linked i.e. FT_LNK) * Extended Attributes (if Win32) */ if (sscanf(sd->msg, "%d %d", &record_file_index, &type) != 2) { Jmsg(jcr, M_FATAL, 0, _("Error scanning record header: %s\n"), sd->msg); Dmsg0(0, "\nError scanning header\n"); goto bail_out; } Dmsg2(30, "Got Attr: FilInx=%d type=%d\n", record_file_index, type); ap = sd->msg; while (*ap++ != ' ') /* skip record file index */ ; while (*ap++ != ' ') /* skip type */ ; /* Save filename and position to attributes */ fp = fname; while (*ap != 0) { *fp++ = *ap++; /* copy filename to fname */ } *fp = *ap++; /* terminate filename & point to attribs */ Dmsg2(100, "File=%s Attr=%s\n", fname, ap); /* Skip to Link name */ if (type == FT_LNK || type == FT_LNKSAVED) { lp = ap; while (*lp++ != 0) { ; } pm_strcat(lname, lp); /* "save" link name */ } else { *lname = 0; } jcr->lock(); jcr->JobFiles++; jcr->num_files_examined++; pm_strcpy(jcr->last_fname, fname); /* last file examined */ jcr->unlock(); /* * Send file attributes to Director * File_index * Stream * Verify Options * Filename (full path) * Encoded attributes * Link name (if type==FT_LNK) * For a directory, link is the same as fname, but with trailing * slash. For a linked file, link is the link. */ /* Send file attributes to Director */ Dmsg2(200, "send ATTR inx=%d fname=%s\n", jcr->JobFiles, fname); if (type == FT_LNK || type == FT_LNKSAVED) { stat = dir->fsend("%d %d %s %s%c%s%c%s%c", jcr->JobFiles, STREAM_UNIX_ATTRIBUTES, "pinsug5", fname, 0, ap, 0, lname, 0); /* for a deleted record, we set fileindex=0 */ } else if (type == FT_DELETED) { stat = dir->fsend("%d %d %s %s%c%s%c%c", 0, STREAM_UNIX_ATTRIBUTES, "pinsug5", fname, 0, ap, 0, 0); } else { stat = dir->fsend("%d %d %s %s%c%s%c%c", jcr->JobFiles, STREAM_UNIX_ATTRIBUTES, "pinsug5", fname, 0, ap, 0, 0); } Dmsg2(200, "bfiled>bdird: attribs len=%d: msg=%s\n", dir->msglen, dir->msg); if (!stat) { Jmsg(jcr, M_FATAL, 0, _("Network error in send to Director: ERR=%s\n"), dir->bstrerror()); goto bail_out; } break; case STREAM_MD5_DIGEST: bin_to_base64(digest, sizeof(digest), (char *)sd->msg, CRYPTO_DIGEST_MD5_SIZE, true); Dmsg2(400, "send inx=%d MD5=%s\n", jcr->JobFiles, digest); dir->fsend("%d %d %s *MD5-%d*", jcr->JobFiles, STREAM_MD5_DIGEST, digest, jcr->JobFiles); Dmsg2(20, "bfiled>bdird: MD5 len=%d: msg=%s\n", dir->msglen, dir->msg); break; case STREAM_SHA1_DIGEST: bin_to_base64(digest, sizeof(digest), (char *)sd->msg, CRYPTO_DIGEST_SHA1_SIZE, true); Dmsg2(400, "send inx=%d SHA1=%s\n", jcr->JobFiles, digest); dir->fsend("%d %d %s *SHA1-%d*", jcr->JobFiles, STREAM_SHA1_DIGEST, digest, jcr->JobFiles); Dmsg2(20, "bfiled>bdird: SHA1 len=%d: msg=%s\n", dir->msglen, dir->msg); break; case STREAM_SHA256_DIGEST: bin_to_base64(digest, sizeof(digest), (char *)sd->msg, CRYPTO_DIGEST_SHA256_SIZE, true); Dmsg2(400, "send inx=%d SHA256=%s\n", jcr->JobFiles, digest); dir->fsend("%d %d %s *SHA256-%d*", jcr->JobFiles, STREAM_SHA256_DIGEST, digest, jcr->JobFiles); Dmsg2(20, "bfiled>bdird: SHA256 len=%d: msg=%s\n", dir->msglen, dir->msg); break; case STREAM_SHA512_DIGEST: bin_to_base64(digest, sizeof(digest), (char *)sd->msg, CRYPTO_DIGEST_SHA512_SIZE, true); Dmsg2(400, "send inx=%d SHA512=%s\n", jcr->JobFiles, digest); dir->fsend("%d %d %s *SHA512-%d*", jcr->JobFiles, STREAM_SHA512_DIGEST, digest, jcr->JobFiles); Dmsg2(20, "bfiled>bdird: SHA512 len=%d: msg=%s\n", dir->msglen, dir->msg); break; /* * Restore stream object is counted, but not restored here */ case STREAM_RESTORE_OBJECT: jcr->lock(); jcr->JobFiles++; jcr->num_files_examined++; jcr->unlock(); break; /* Ignore everything else */ default: break; } /* end switch */ } /* end while bnet_get */ jcr->setJobStatus(JS_Terminated); goto ok_out; bail_out: jcr->setJobStatus(JS_ErrorTerminated); ok_out: if (jcr->compress_buf) { free(jcr->compress_buf); jcr->compress_buf = NULL; } free_pool_memory(fname); free_pool_memory(lname); Dmsg2(050, "End Verify-Vol. Files=%d Bytes=%" lld "\n", jcr->JobFiles, jcr->JobBytes); }
/* static attachmemt size */ int mailAttachment(unsigned char **mail, const unsigned char *filePath) { FILE *fp = NULL; int fileSize, base64Size, headerSize, len; char *attach = NULL, *base64Attach = NULL, *attachHeader = NULL; char fileName[MAX_EMAIL_LEN] = {0}; const char *contentType = "Content-Type: application/octet-stream"; const char *contentEncode = "Content-Transfer-Encoding: base64"; const char *contentDes = "Content-Disposition: attachment"; fp = fopen(filePath, "rb"); if (NULL == fp) { perror("open..."); return -1; } fseek(fp, 0, SEEK_END); fileSize = ftell(fp); if (0 > fileSize) { perror("ftell...\n"); return -1; } rewind(fp); attach = calloc(fileSize, 1); if (NULL == attach) { perror("malloc..."); return -1; } headerSize = strlen(contentType)+strlen(contentEncode)+strlen(contentDes)+200; attachHeader = calloc(headerSize, 1); if (NULL == attach) { perror("malloc..."); return -1; } /* attachment header */ stringCut(filePath, "/", NULL, fileName); sprintf(attachHeader, "%s;name=\"%s\"\r\n%s\r\n%s;filename=\"%s\"\r\n\r\n", contentType, fileName, contentEncode, contentDes, fileName); base64Size = BASE64_SIZE(fileSize); base64Attach = calloc(base64Size, 1); if (NULL == base64Attach) { perror("malloc..."); return -1; } len = fread(attach, sizeof(char), fileSize, fp); SMTP_Print6("[%s][%d] %s size = %d, base64Size = %d \r\n",__FILE__, __LINE__, filePath, fileSize, base64Size); /* attachment transform to base64 */ base64_encode(base64Attach, base64Size, attach, fileSize); free(attach); *mail = realloc(*mail, strlen(*mail)+headerSize+base64Size+1); if (NULL == *mail) { perror("realloc...\n"); /* what should I do? */ return -1; } strcat(*mail, attachHeader); strcat(*mail, base64Attach); free(attachHeader); free(base64Attach); return fileSize; }
int authEmail(const int socketFd, const unsigned char *mailAddr, const unsigned char *mailPasswd) { int outSize = 0, stringLen; char readData[SMTP_MTU] = {0}; char writeData[SMTP_MTU] = {0}; char userName[MAX_EMAIL_LEN] = {0}; char userPasswd[MAX_EMAIL_LEN] = {0}; memset(&readData, 0, SMTP_MTU); safeRead(socketFd, readData, SMTP_MTU); SMTP_Print6("[%s][%d]recv: %s\r\n", __FILE__, __LINE__, readData); /* Send: EHLO */ safeWrite(socketFd, "EHLO Here\r\n", strlen("EHLO Here\r\n")); /* Recv: EHLO */ memset(&readData, 0, SMTP_MTU); safeRead(socketFd, readData, SMTP_MTU); SMTP_Print6("[%s][%d]recv: %s\r\n", __FILE__, __LINE__, readData); recvStatus(readData); /* Send: AUTH LOGIN */ safeWrite(socketFd, "AUTH LOGIN\r\n", strlen("AUTH LOGIN\r\n")); /* Recv: AUTH LOGIN */ memset(&readData, 0, SMTP_MTU); safeRead(socketFd, readData, SMTP_MTU); SMTP_Print6("[%s][%d]recv: %s\r\n", __FILE__, __LINE__, readData); recvStatus(readData); /* Send: username */ memset(&userName, 0, MAX_EMAIL_LEN); memset(&writeData, 0, SMTP_MTU); stringCut((unsigned char*)mailAddr, NULL, "@", userName); outSize = BASE64_SIZE(strlen(userName)); base64_encode(writeData, outSize, userName, strlen(userName)); strcat(writeData, "\r\n"); safeWrite(socketFd, writeData, strlen(writeData)); /* Recv: username */ memset(&readData, 0, SMTP_MTU); safeRead(socketFd, readData, SMTP_MTU); SMTP_Print6("[%s][%d]recv: %s\r\n", __FILE__, __LINE__, readData); recvStatus(readData); /* Send: passwd */ memset(&userPasswd, 0, MAX_EMAIL_LEN); strcpy(userPasswd, mailPasswd); memset(&writeData, 0, SMTP_MTU); outSize = BASE64_SIZE(strlen(userPasswd)); base64_encode(writeData, outSize, userPasswd, strlen(userPasswd)); strcat(writeData, "\r\n"); safeWrite(socketFd, writeData, strlen(writeData)); /* Recv: passwd */ memset(&readData, 0, SMTP_MTU); safeRead(socketFd, readData, SMTP_MTU); SMTP_Print6("[%s][%d]recv: %s\r\n", __FILE__, __LINE__, readData); recvStatus(readData); return 0; }
/* static attachmemt size */ int mailAttachment(unsigned char **mail, const unsigned char *filePath) { FILE *fp = NULL; int fileSize, base64Size, headerSize, len; char *attach = NULL, *base64Attach = NULL, *attachHeader = NULL; char fileName[MAX_EMAIL_LEN] = {0}; const char *contentType = "Content-Type: application/octet-stream"; const char *contentEncode = "Content-Transfer-Encoding: base64"; const char *contentDes = "Content-Disposition: attachment"; fp = ACE_OS::fopen((char* )filePath, "rb"); if (NULL == fp) { //ACE_DEBUG((LM_ERROR, "[mailAttachment]fp fopen fail.\n")); return -1; } ACE_OS::fseek(fp, 0, SEEK_END); fileSize = ACE_OS::ftell(fp); if (0 > fileSize) { //ACE_DEBUG((LM_ERROR, "[mailAttachment]fp ftell fail.\n")); ACE_OS::fclose(fp); return -1; } ACE_OS::rewind(fp); attach = (char* )calloc(fileSize, 1); if (NULL == attach) { //ACE_DEBUG((LM_ERROR, "[mailAttachment]fp calloc fileSize fail.\n")); ACE_OS::fclose(fp); return -1; } headerSize = ACE_OS::strlen(contentType)+ACE_OS::strlen(contentEncode)+ACE_OS::strlen(contentDes)+200; attachHeader = (char* )calloc(headerSize, 1); if (NULL == attach) { //ACE_DEBUG((LM_ERROR, "[mailAttachment]fp calloc headerSize fail.\n")); ACE_OS::fclose(fp); return -1; } /* attachment header */ stringCut(filePath, "/", NULL, fileName); ACE_OS::sprintf(attachHeader, "%s;name=\"%s\"\r\n%s\r\n%s;filename=\"%s\"\r\n\r\n", contentType, fileName, contentEncode, contentDes, fileName); base64Size = BASE64_SIZE(fileSize); base64Attach = (char* )calloc(base64Size, 1); if (NULL == base64Attach) { //ACE_DEBUG((LM_ERROR, "[mailAttachment]fp calloc base64Size fail.\n")); ACE_OS::fclose(fp); return -1; } len = ACE_OS::fread(attach, sizeof(char), fileSize, fp); //SMTP_Print6("[%s][%d] %s size = %d, base64Size = %d \r\n",__FILE__, __LINE__, filePath, fileSize, base64Size); /* attachment transform to base64 */ base64_encode(base64Attach, base64Size, (const unsigned char *)attach, fileSize); free(attach); *mail = (unsigned char* )realloc(*mail, strlen((char* )*mail)+headerSize+base64Size+1); if (NULL == *mail) { //ACE_DEBUG((LM_ERROR, "[mailAttachment]fp realloc base64Size fail.\n")); ACE_OS::fclose(fp); return -1; } ACE_OS::strcat((char* )*mail, attachHeader); ACE_OS::strcat((char* )*mail, base64Attach); free(attachHeader); free(base64Attach); ACE_OS::fclose(fp); return fileSize; }
int authEmail(const ACE_HANDLE socketFd, const unsigned char *mailAddr, const unsigned char *mailPasswd) { int outSize = 0; char readData[SMTP_MTU] = {0}; char writeData[SMTP_MTU] = {0}; char userName[MAX_EMAIL_LEN] = {0}; char userPasswd[MAX_EMAIL_LEN] = {0}; ACE_OS::memset(&readData, 0, SMTP_MTU); safeRead(socketFd, readData, SMTP_MTU); //SMTP_Print6("[%s][%d]recv: %s\r\n", __FILE__, __LINE__, readData); /* Send: EHLO */ char szRELO[50] = {'\0'}; ACE_OS::sprintf(szRELO, "EHLO Here\r\n"); safeWrite(socketFd, szRELO, ACE_OS::strlen("EHLO Here\r\n")); /* Recv: EHLO */ ACE_OS::memset(&readData, 0, SMTP_MTU); safeRead(socketFd, readData, SMTP_MTU); //SMTP_Print6("[%s][%d]recv: %s\r\n", __FILE__, __LINE__, readData); recvStatus(readData); /* Send: AUTH LOGIN */ char szLOGIN[50] = {'\0'}; ACE_OS::sprintf(szLOGIN, "AUTH LOGIN\r\n"); safeWrite(socketFd, szLOGIN, ACE_OS::strlen("AUTH LOGIN\r\n")); /* Recv: AUTH LOGIN */ ACE_OS::memset(&readData, 0, SMTP_MTU); safeRead(socketFd, readData, SMTP_MTU); //SMTP_Print6("[%s][%d]recv: %s\r\n", __FILE__, __LINE__, readData); recvStatus(readData); /* Send: username */ ACE_OS::memset(&userName, 0, MAX_EMAIL_LEN); ACE_OS::memset(&writeData, 0, SMTP_MTU); stringCut((unsigned char*)mailAddr, NULL, (char* )"@", userName); outSize = BASE64_SIZE(strlen(userName)); base64_encode(writeData, outSize, (const unsigned char *)userName, strlen(userName)); ACE_OS::strcat(writeData, "\r\n"); safeWrite(socketFd, writeData, strlen(writeData)); /* Recv: username */ ACE_OS::memset(&readData, 0, SMTP_MTU); safeRead(socketFd, readData, SMTP_MTU); //SMTP_Print6("[%s][%d]recv: %s\r\n", __FILE__, __LINE__, readData); recvStatus(readData); /* Send: passwd */ ACE_OS::memset(&userPasswd, 0, MAX_EMAIL_LEN); ACE_OS::strcpy((char* )userPasswd, (char* )mailPasswd); ACE_OS::memset(&writeData, 0, SMTP_MTU); outSize = BASE64_SIZE(strlen(userPasswd)); base64_encode(writeData, outSize, (const unsigned char *)userPasswd, strlen(userPasswd)); ACE_OS::strcat(writeData, "\r\n"); safeWrite(socketFd, writeData, strlen(writeData)); /* Recv: passwd */ ACE_OS::memset(&readData, 0, SMTP_MTU); safeRead(socketFd, readData, SMTP_MTU); //SMTP_Print6("[%s][%d]recv: %s\r\n", __FILE__, __LINE__, readData); recvStatus(readData); return 0; }
/* * Called here by find() for each file. * * Find the file, compute the MD5 or SHA1 and send it back to the Director */ static int verify_file(JCR *jcr, FF_PKT *ff_pkt, bool top_level) { POOL_MEM attribs(PM_NAME), attribsEx(PM_NAME); int digest_stream = STREAM_NONE; int status; DIGEST *digest = NULL; BSOCK *dir; if (job_canceled(jcr)) { return 0; } dir = jcr->dir_bsock; jcr->num_files_examined++; /* bump total file count */ switch (ff_pkt->type) { case FT_LNKSAVED: /* Hard linked, file already saved */ Dmsg2(30, "FT_LNKSAVED saving: %s => %s\n", ff_pkt->fname, ff_pkt->link); break; case FT_REGE: Dmsg1(30, "FT_REGE saving: %s\n", ff_pkt->fname); break; case FT_REG: Dmsg1(30, "FT_REG saving: %s\n", ff_pkt->fname); break; case FT_LNK: Dmsg2(30, "FT_LNK saving: %s -> %s\n", ff_pkt->fname, ff_pkt->link); break; case FT_DIRBEGIN: jcr->num_files_examined--; /* correct file count */ return 1; /* ignored */ case FT_REPARSE: case FT_JUNCTION: case FT_DIREND: Dmsg1(30, "FT_DIR saving: %s\n", ff_pkt->fname); break; case FT_SPEC: Dmsg1(30, "FT_SPEC saving: %s\n", ff_pkt->fname); break; case FT_RAW: Dmsg1(30, "FT_RAW saving: %s\n", ff_pkt->fname); break; case FT_FIFO: Dmsg1(30, "FT_FIFO saving: %s\n", ff_pkt->fname); break; case FT_NOACCESS: { berrno be; be.set_errno(ff_pkt->ff_errno); Jmsg(jcr, M_NOTSAVED, 1, _(" Could not access %s: ERR=%s\n"), ff_pkt->fname, be.bstrerror()); jcr->JobErrors++; return 1; } case FT_NOFOLLOW: { berrno be; be.set_errno(ff_pkt->ff_errno); Jmsg(jcr, M_NOTSAVED, 1, _(" Could not follow link %s: ERR=%s\n"), ff_pkt->fname, be.bstrerror()); jcr->JobErrors++; return 1; } case FT_NOSTAT: { berrno be; be.set_errno(ff_pkt->ff_errno); Jmsg(jcr, M_NOTSAVED, 1, _(" Could not stat %s: ERR=%s\n"), ff_pkt->fname, be.bstrerror()); jcr->JobErrors++; return 1; } case FT_DIRNOCHG: case FT_NOCHG: Jmsg(jcr, M_SKIPPED, 1, _(" Unchanged file skipped: %s\n"), ff_pkt->fname); return 1; case FT_ISARCH: Jmsg(jcr, M_SKIPPED, 1, _(" Archive file skipped: %s\n"), ff_pkt->fname); return 1; case FT_NORECURSE: Jmsg(jcr, M_SKIPPED, 1, _(" Recursion turned off. Directory skipped: %s\n"), ff_pkt->fname); ff_pkt->type = FT_DIREND; /* directory entry was backed up */ break; case FT_NOFSCHG: Jmsg(jcr, M_SKIPPED, 1, _(" File system change prohibited. Directory skipped: %s\n"), ff_pkt->fname); return 1; case FT_PLUGIN_CONFIG: case FT_RESTORE_FIRST: return 1; /* silently skip */ case FT_NOOPEN: { berrno be; be.set_errno(ff_pkt->ff_errno); Jmsg(jcr, M_NOTSAVED, 1, _(" Could not open directory %s: ERR=%s\n"), ff_pkt->fname, be.bstrerror()); jcr->JobErrors++; return 1; } default: Jmsg(jcr, M_NOTSAVED, 0, _(" Unknown file type %d: %s\n"), ff_pkt->type, ff_pkt->fname); jcr->JobErrors++; return 1; } /* Encode attributes and possibly extend them */ encode_stat(attribs.c_str(), &ff_pkt->statp, sizeof(ff_pkt->statp), ff_pkt->LinkFI, 0); encode_attribsEx(jcr, attribsEx.c_str(), ff_pkt); jcr->lock(); jcr->JobFiles++; /* increment number of files sent */ pm_strcpy(jcr->last_fname, ff_pkt->fname); jcr->unlock(); /* * Send file attributes to Director * File_index * Stream * Verify Options * Filename (full path) * Encoded attributes * Link name (if type==FT_LNK) * For a directory, link is the same as fname, but with trailing * slash. For a linked file, link is the link. */ /* Send file attributes to Director (note different format than for Storage) */ Dmsg2(400, "send ATTR inx=%d fname=%s\n", jcr->JobFiles, ff_pkt->fname); if (ff_pkt->type == FT_LNK || ff_pkt->type == FT_LNKSAVED) { status = dir->fsend("%d %d %s %s%c%s%c%s%c", jcr->JobFiles, STREAM_UNIX_ATTRIBUTES, ff_pkt->VerifyOpts, ff_pkt->fname, 0, attribs.c_str(), 0, ff_pkt->link, 0); } else if (ff_pkt->type == FT_DIREND || ff_pkt->type == FT_REPARSE || ff_pkt->type == FT_JUNCTION) { /* Here link is the canonical filename (i.e. with trailing slash) */ status = dir->fsend("%d %d %s %s%c%s%c%c", jcr->JobFiles, STREAM_UNIX_ATTRIBUTES, ff_pkt->VerifyOpts, ff_pkt->link, 0, attribs.c_str(), 0, 0); } else { status = dir->fsend("%d %d %s %s%c%s%c%c", jcr->JobFiles, STREAM_UNIX_ATTRIBUTES, ff_pkt->VerifyOpts, ff_pkt->fname, 0, attribs.c_str(), 0, 0); } Dmsg2(20, "filed>dir: attribs len=%d: msg=%s\n", dir->msglen, dir->msg); if (!status) { Jmsg(jcr, M_FATAL, 0, _("Network error in send to Director: ERR=%s\n"), bnet_strerror(dir)); return 0; } /* * The remainder of the function is all about getting the checksum. * First we initialise, then we read files, other streams and Finder Info. */ if (ff_pkt->type != FT_LNKSAVED && (S_ISREG(ff_pkt->statp.st_mode) && ff_pkt->flags & (FO_MD5|FO_SHA1|FO_SHA256|FO_SHA512))) { /* * Create our digest context. If this fails, the digest will be set to NULL * and not used. */ if (ff_pkt->flags & FO_MD5) { digest = crypto_digest_new(jcr, CRYPTO_DIGEST_MD5); digest_stream = STREAM_MD5_DIGEST; } else if (ff_pkt->flags & FO_SHA1) { digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA1); digest_stream = STREAM_SHA1_DIGEST; } else if (ff_pkt->flags & FO_SHA256) { digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA256); digest_stream = STREAM_SHA256_DIGEST; } else if (ff_pkt->flags & FO_SHA512) { digest = crypto_digest_new(jcr, CRYPTO_DIGEST_SHA512); digest_stream = STREAM_SHA512_DIGEST; } /* Did digest initialization fail? */ if (digest_stream != STREAM_NONE && digest == NULL) { Jmsg(jcr, M_WARNING, 0, _("%s digest initialization failed\n"), stream_to_ascii(digest_stream)); } /* compute MD5 or SHA1 hash */ if (digest) { char md[CRYPTO_DIGEST_MAX_SIZE]; uint32_t size; size = sizeof(md); if (digest_file(jcr, ff_pkt, digest) != 0) { jcr->JobErrors++; goto good_rtn; } if (crypto_digest_finalize(digest, (uint8_t *)md, &size)) { char *digest_buf; const char *digest_name; digest_buf = (char *)malloc(BASE64_SIZE(size)); digest_name = crypto_digest_name(digest); bin_to_base64(digest_buf, BASE64_SIZE(size), md, size, true); Dmsg3(400, "send inx=%d %s=%s\n", jcr->JobFiles, digest_name, digest_buf); dir->fsend("%d %d %s *%s-%d*", jcr->JobFiles, digest_stream, digest_buf, digest_name, jcr->JobFiles); Dmsg3(20, "filed>dir: %s len=%d: msg=%s\n", digest_name, dir->msglen, dir->msg); free(digest_buf); } } } good_rtn: if (digest) { crypto_digest_free(digest); } return 1; }