05.04.2015 Views

Cloudmark Authority Engine

Cloudmark Authority Engine

Cloudmark Authority Engine

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

<strong>Cloudmark</strong><br />

<strong>Authority</strong> <strong>Engine</strong><br />

SDK Guide


Copyright © 2006 <strong>Cloudmark</strong>, Inc. All rights reserved.<br />

This document may not, in whole or in part, be copied, photocopied, reproduced,<br />

translated or reduced to any electronic medium or machine readable form without prior<br />

consent in writing from:<br />

<strong>Cloudmark</strong>, Inc. 128 King Street, 2nd Floor, San Francisco, CA 94107<br />

All examples with names, company names or companies that appear in this guide are<br />

fictitious and do not refer to, or portray, in name or substance, any actual names,<br />

organizations, entities or institutions. Any resemblance to any real person, organization,<br />

entity or institution is purely coincidental.<br />

While every effort has been made to ensure technical accuracy, information in this<br />

document is subject to change without notice and does not represent a commitment on<br />

the part of <strong>Cloudmark</strong>, Inc. <strong>Cloudmark</strong> makes no warranties with respect to this<br />

documentation and disclaims any implied warranties of merchantability and fitness for<br />

a particular purpose. <strong>Cloudmark</strong> shall not be liable for any errors or for incidental or<br />

consequential damages in connection with the furnishing, performance or use of this<br />

manual or examples herein.<br />

<strong>Cloudmark</strong> <strong>Authority</strong> <strong>Engine</strong> version 1.5<br />

Last modified: March 14, 2006


Contents<br />

CONTENTS<br />

CHAPTER 1 About This Guide . . . . . . . . . . . . . 1<br />

CHAPTER 2 System Requirements . . . . . . . . . . . 3<br />

Windows . . . . . . . . . . . . . . . . . . . . . . . . . 3<br />

Development Environment . . . . . . . . . . . . . . . . . . . 3<br />

File Manifest . . . . . . . . . . . . . . . . . . . . . . . . 3<br />

Platform Dependencies . . . . . . . . . . . . . . . . . . . . 4<br />

Linux . . . . . . . . . . . . . . . . . . . . . . . . . . 4<br />

Development Environment . . . . . . . . . . . . . . . . . . . 5<br />

File Manifest . . . . . . . . . . . . . . . . . . . . . . . . 5<br />

Platform Dependencies . . . . . . . . . . . . . . . . . . . . 6<br />

Solaris . . . . . . . . . . . . . . . . . . . . . . . . . . 7<br />

Development Environment . . . . . . . . . . . . . . . . . . . 7<br />

File Manifest . . . . . . . . . . . . . . . . . . . . . . . . 7<br />

Platform Dependencies . . . . . . . . . . . . . . . . . . . . 8<br />

FreeBSD . . . . . . . . . . . . . . . . . . . . . . . . . 9<br />

Development Environment . . . . . . . . . . . . . . . . . . . 9<br />

File Manifest . . . . . . . . . . . . . . . . . . . . . . . . 9<br />

Platform Dependencies . . . . . . . . . . . . . . . . . . . 10<br />

CHAPTER 3 Application Development . . . . . . . . . . 11<br />

How CMAE detects spam . . . . . . . . . . . . . . . . . . .11<br />

Spam filtering basics . . . . . . . . . . . . . . . . . . . .12<br />

Obtaining message scores . . . . . . . . . . . . . . . . . . 12<br />

Classifying messages based on score . . . . . . . . . . . . . . 13<br />

Applying actions to messages . . . . . . . . . . . . . . . . . 13<br />

iii


Contents<br />

Designing your application . . . . . . . . . . . . . . . . . 14<br />

CHAPTER 4 API Reference . . . . . . . . . . . . . . 15<br />

Conventions . . . . . . . . . . . . . . . . . . . . . . . 15<br />

Scoring messages . . . . . . . . . . . . . . . . . . . . . . 15<br />

Object Management . . . . . . . . . . . . . . . . . . . . . 16<br />

Synchronization and Threading. . . . . . . . . . . . . . . . . 16<br />

Memory Management . . . . . . . . . . . . . . . . . . . . 16<br />

Call Sequence . . . . . . . . . . . . . . . . . . . . . . . 17<br />

Error Codes . . . . . . . . . . . . . . . . . . . . . . . . 17<br />

Constants . . . . . . . . . . . . . . . . . . . . . . . . 18<br />

Structures . . . . . . . . . . . . . . . . . . . . . . . . 18<br />

Callback Functions . . . . . . . . . . . . . . . . . . . . 19<br />

CMAE Functions . . . . . . . . . . . . . . . . . . . . . 22<br />

Scoring Functions . . . . . . . . . . . . . . . . . . . . . 25<br />

Envelope Functions . . . . . . . . . . . . . . . . . . . . 27<br />

CHAPTER 5 The CMAE SDK Client and Daemon . . . . . . 35<br />

The CMAE daemon . . . . . . . . . . . . . . . . . . . . 35<br />

The CMAE client library. . . . . . . . . . . . . . . . . . . 37<br />

The CMAE client binary . . . . . . . . . . . . . . . . . . . 42<br />

APPENDIX A Sample Code . . . . . . . . . . . . . . 45<br />

Index . . . . . . . . . . . . . . . . . 49<br />

iv


About This Guide<br />

CHAPTER<br />

1<br />

The <strong>Cloudmark</strong> <strong>Authority</strong> <strong>Engine</strong> Software Development Kit (the CMAE<br />

SDK) enables C/C++ developers to add the spam-filtering functionality of<br />

the <strong>Cloudmark</strong> <strong>Authority</strong> <strong>Engine</strong> (CMAE) to applications that run on<br />

Linux, Solaris and Windows.<br />

Filtering email for spam with CMAE has several advantages:<br />

• universal compatibility with a wide range of network components;<br />

CMAE deploys in nearly any environment that uses firewalls, border<br />

systems, email management tools, anti-virus filters and other SMTP<br />

message processors<br />

• minimal impact on network resources<br />

• continuous, real-time adaptation to the latest trends in spam-,<br />

worldwide. CMAE is automatically updated with new spam definitions<br />

as they are created via micro-updates: light-weight, <strong>Cloudmark</strong>-issued<br />

update files that enhance the spam-filtering functionality of CMAE,<br />

without requiring any downtime<br />

• up-to-date spam-filtering technology. <strong>Cloudmark</strong> periodic microupdates<br />

This guide provides the information necessary to develop applications<br />

using the CMAE SDK:<br />

• Chapter 2, “System Requirements”, lists the hardware and software<br />

platforms, IDEs, and compilation tools required by the CMAE SDK.<br />

• Chapter 3, “Application Development”, provides guidelines for<br />

developing applications with the CMAE SDK.<br />

• Chapter 4, “API Reference”, details each API call available in the<br />

CMAE SDK.<br />

• Chapter 5, “The CMAE SDK Client and Daemon”, describes the<br />

lightweight client and daemon provided with the CMAE SDK.<br />

• Appendix A, “Sample Code”, illustrates the usage of the CMAE SDK<br />

with a small example program.<br />

1


<strong>Cloudmark</strong> <strong>Authority</strong> <strong>Engine</strong> SDK Guide Chapter 1<br />

2


System Requirements<br />

CHAPTER<br />

2<br />

This section lists the platforms supported by the CMAE SDK, as well as<br />

the development requirements for each:<br />

• “Windows” below<br />

• “Linux” on page 4<br />

• “Solaris” on page 7<br />

• “FreeBSD” on page 9<br />

Windows<br />

The CMAE SDK for Windows runs on Microsoft Windows Server 2000<br />

and 2003 (with the latest service packs installed).<br />

Development Environment<br />

The CMAE SDK for Windows integrates with Microsoft Visual Studio<br />

.NET 7.1 using the Multithreaded DLL settings for runtime library<br />

inclusion. For other development environments, use standard settings.<br />

File Manifest<br />

The resources included with the CMAE SDK for Windows are:<br />

Table 1<br />

File<br />

cmae.h<br />

cmae.dll<br />

Windows file manifest<br />

Description<br />

Header file for the CMAE C interface<br />

The CMAE dynamic library implementation<br />

3


<strong>Cloudmark</strong> <strong>Authority</strong> <strong>Engine</strong> SDK Guide Chapter 2<br />

Table 1<br />

File<br />

cmae.lib<br />

example.c<br />

Windows file manifest<br />

Description<br />

The library file for implicit linking of the CMAE dynamic library<br />

An example application; run it like this:<br />

example <br />

example<br />

example.vcproj<br />

example.sln<br />

engtest.exe<br />

A precompiled version of example.c and the associated Visual<br />

Studio project files<br />

A more comprehensive precompiled version of engine.c that<br />

scores all messages in an mbox file<br />

In addition to the files included in the SDK, you must also download the<br />

latest cartridge update. The cartridge contains the latest algorithms for<br />

analyzing messages and detecting spam.<br />

Platform Dependencies<br />

The CMAE SDK for Windows requires the following libraries:<br />

Table 2<br />

DLL<br />

Windows platform dependencies<br />

Folder<br />

msvcr71.dll<br />

msvcp71.dll<br />

[SystemDir]\system32<br />

[SystemDir]\system32<br />

Linux<br />

The CMAE SDK for Linux is supported by Pentium II hardware and<br />

above, running Red Hat Enterprise Linux ES 2.1 or higher or Redhat<br />

Desktop 8 or higher.<br />

! The CMAE SDKis not compatible with the AMD K6 processor.<br />

4 Linux


Chapter 2<br />

System Requirements<br />

Development Environment<br />

The CMAE SDK for Linux is compiled by two different versions of gcc;<br />

specifically, versions 2.96 and 3.2. When developing your application, use<br />

only the build compiled for its target platform:<br />

• If your application is targeted for Red Hat Enterprise Linux ES 2.1, use<br />

the gcc 2.96-complied build.<br />

• If it targets Red Hat Desktop and Red Hat Enterprise Linux ES 3.0 or<br />

higher, use the gcc 3.2-compiled build.<br />

File Manifest<br />

The resources included with the CMAE SDK for Linux are:<br />

Table 3<br />

Linux file manifest<br />

Table 4<br />

File<br />

cmae.h<br />

cmae_port.h<br />

cmae_error.h<br />

cmae_envelope.h<br />

libcmae.so<br />

example.c<br />

examp<br />

engtest<br />

cmae_client.h<br />

libcmaeclient.so<br />

cmae_server<br />

cmae_client<br />

Description<br />

Header file for the C interface to CMAE<br />

A subsidiary header file required by cmae.h<br />

A subsidiary header file required by cmae.h<br />

A subsidiary header file required by cmae.h<br />

The CMAE library to add to the multi-threaded runtime libraries used<br />

to compile your application<br />

An example application; run it like this:<br />

example <br />

A precompiled version of example.c<br />

A more comprehensive precompiled version of example.c that scores<br />

all messages in an mbox file<br />

Header file for the C interface to the CMAE lightweight client<br />

The shared library containing the CMAE lightweight client<br />

The CMAE daemon<br />

A simple CMAE client binary<br />

In addition to the files included in the SDK, you must also download the<br />

latest cartridge update. The cartridge contains the latest algorithms for<br />

analyzing messages and detecting spam.<br />

Linux 5


<strong>Cloudmark</strong> <strong>Authority</strong> <strong>Engine</strong> SDK Guide Chapter 2<br />

Platform Dependencies<br />

The library dependencies for each build differ. The next two tables list the<br />

dependencies for each.<br />

The gcc 2.96-compiled build requires these libraries:<br />

Table 5 Linux platform dependencies for GCC 2.96<br />

Library<br />

libz.so.1<br />

libpthread.so.0<br />

libdl.so.2<br />

libstdc++-libc6.2-2.so.3<br />

libm.so.6<br />

libc.so.6<br />

ld-linux.so.2<br />

Directory<br />

/usr/lib<br />

/lib<br />

/lib<br />

/usr/lib<br />

/lib<br />

/lib<br />

/lib<br />

The gcc 3.2-compiled build requires these libraries:<br />

Table 6 Linux platform dependencies for GCC 3.2<br />

Table 7<br />

Library<br />

libz.so.1<br />

libpthread.so.0<br />

libdl.so.2<br />

libstdc++.so.5<br />

libgcc_s.so.1<br />

libm.so.6<br />

libc.so.6<br />

ld-linux.so.2<br />

Directory<br />

/usr/lib<br />

/lib<br />

/usr/lib<br />

/usr/lib<br />

/lib<br />

/lib<br />

/lib<br />

/lib<br />

6 Linux


Chapter 2<br />

System Requirements<br />

Solaris<br />

The CMAE SDK for Solaris is supported by the Sun Microsystems’<br />

UltraSPARC hardware platform running Solaris 8 or 9 (with the latest<br />

patch clusters installed).<br />

! For best application performance on Solaris 8, <strong>Cloudmark</strong> recommends<br />

using the T2 threading libraries found in /usr/lib/lwp.<br />

Development Environment<br />

The CMAE SDK for Solaris is compiled by two different versions of gcc;<br />

specifically, 2.95.3 and 3.2.3.<br />

File Manifest<br />

The resources included with the CMAE SDK for Solaris are:<br />

Solaris 7


<strong>Cloudmark</strong> <strong>Authority</strong> <strong>Engine</strong> SDK Guide Chapter 2<br />

Table 8<br />

Linux file manifest<br />

Table 9<br />

File<br />

cmae.h<br />

cmae_port.h<br />

cmae_error.h<br />

cmae_envelope.h<br />

libcmae.so<br />

example.c<br />

examp<br />

engtest<br />

cmae_client.h<br />

libcmaeclient.so<br />

cmae_server<br />

cmae_client<br />

Description<br />

Header file for the C interface to CMAE<br />

A subsidiary header file required by cmae.h<br />

A subsidiary header file required by cmae.h<br />

A subsidiary header file required by cmae.h<br />

The CMAE library to add to the multi-threaded runtime<br />

libraries used to compile your application<br />

An example application; run it like this:<br />

example <br />

A precompiled version of example.c<br />

A more comprehensive precompiled version of example.c that<br />

scores all messages in an mbox file<br />

Header file for the C interface to the CMAE lightweight client<br />

The shared library containing the CMAE lightweight client<br />

The CMAE daemon<br />

A simple CMAE client binary<br />

In addition to the files included in the SDK, you must also download the<br />

latest cartridge update. The cartridge contains the latest algorithms for<br />

analyzing messages and detecting spam.<br />

Platform Dependencies<br />

Both gcc-compiled builds of the CMAE SDK for Solaris depend on the<br />

same libraries; however, additional libraries are required by each build,<br />

depending on the version chosen by the tool-chain:<br />

• The gcc 2.95.3-compiled build requires libstc++.so.2.10.0.<br />

• The gcc 3.2.3-compiled build requires libstdc++.so.5 and libgcc_s.so.1.<br />

Both builds require these libraries:<br />

Table 10<br />

Solaris platform dependencies<br />

Library<br />

libz.so<br />

libpthread.so.1<br />

Directory<br />

/usr/lib<br />

/usr/lib<br />

8 Solaris


Chapter 2<br />

System Requirements<br />

Table 10<br />

Solaris platform dependencies<br />

Library<br />

libsocket.so.1<br />

libnsl.so.1<br />

libresolv.so.2<br />

libdl.so.1<br />

librt.so.1<br />

libstdc++.so.2.10.0<br />

libm.so.1<br />

libc.so.1<br />

libmp.so.2<br />

libaio.so.1<br />

libthread.so.1<br />

Directory<br />

/usr/lib<br />

/usr/lib<br />

/usr/lib<br />

/usr/lib<br />

/usr/lib<br />

/usr/local/lib<br />

/usr/lib<br />

/usr/lib<br />

/usr/lib<br />

/usr/lib<br />

/usr/lib/lwp<br />

FreeBSD<br />

Development Environment<br />

The FreeBSD build requires FreeBSD 4.11 / i386 and gcc-3.3.6.<br />

File Manifest<br />

The resources included with the CMAE SDK for FreeBSD are:<br />

Table 11<br />

File<br />

cmae.h<br />

FreeBSD file manifest<br />

Description<br />

Header file for the C interface to CMAE<br />

cmae_port.h<br />

cmae_error.h<br />

cmae_envelope.h<br />

libcmae.so<br />

example.c<br />

A subsidiary header file required by cmae.h<br />

A subsidiary header file required by cmae.h<br />

A subsidiary header file required by cmae.h<br />

The CMAE library to add to the multi-threaded runtime<br />

libraries used to compile your application<br />

An example application; run it like this:<br />

example <br />

FreeBSD 9


<strong>Cloudmark</strong> <strong>Authority</strong> <strong>Engine</strong> SDK Guide Chapter 2<br />

Table 11<br />

FreeBSD file manifest<br />

File<br />

examp<br />

engtest<br />

cmae_client.h<br />

libcmaeclient.so<br />

cmae_server<br />

cmae_client<br />

Description<br />

A precompiled version of example.c<br />

A more comprehensive precompiled version of example.c that<br />

scores all messages in an mbox file<br />

Header file for the C interface to the CMAE lightweight client<br />

The shared library containing the CMAE lightweight client<br />

The CMAE daemon<br />

A simple CMAE client binary<br />

In addition to the files included in the SDK, you must also download the<br />

latest cartridge update. The cartridge contains the latest algorithms for<br />

analyzing messages and detecting spam.<br />

Platform Dependencies<br />

The FreeBSD build requires these libraries:<br />

Table 12<br />

Solaris platform dependencies<br />

Library<br />

libc_r.so.4<br />

libm.so.2<br />

Directory<br />

/usr/lib<br />

/usr/lib<br />

On the FreeBSD platform, applications linked against CMAE must use the<br />

reentrant version of the C library. The default C compiler on the system,<br />

gcc, will select the correct libraries when passed the -pthread flag.<br />

10 FreeBSD


Application Development<br />

CHAPTER<br />

3<br />

This chapter provides guidelines for developing a CMAE-enabled<br />

application using the SDK.<br />

How CMAE detects spam<br />

<strong>Cloudmark</strong> has developed a set of fingerprinting algorithms designed to<br />

intelligently analyze messages and detect spam. When subjected to these<br />

algorithms, all messages that are part of a spam attack will produce the<br />

same fingerprint, even if the spammer randomizes portions of each<br />

message. CMAE maintains an in-memory list of bad fingerprints, updated<br />

every minute with micro-updates from the <strong>Cloudmark</strong> Collaborative<br />

Security Network.<br />

The <strong>Cloudmark</strong> Collaborative Security Network consists of millions of<br />

users submitting real-time feedback about the legitimacy of the messages<br />

they receive. A Trust Evaluation System tracks the reputation of each user,<br />

so that each user’s feedback is weighted based on reputation.<br />

Depending on a message’s fingerprint and the feedback from the<br />

<strong>Cloudmark</strong> user community, CMAE assigns a spam confidence score to<br />

the message, from 0 to 100. A score of 0 means the message is certainly<br />

legitimate, while a score of 100 means the message is certainly spam.<br />

Most messages receive a score that lies somewhere between these two<br />

numbers. You configure a threshold that determines the range of scores<br />

that represent spam.<br />

11


<strong>Cloudmark</strong> <strong>Authority</strong> <strong>Engine</strong> SDK Guide Chapter 3<br />

Spam filtering basics<br />

The basic steps for filtering spam in your application are as follows:<br />

1. obtain a score for each message<br />

2. classify each message as spam or legitimate<br />

3. apply an appropriate action to each message<br />

<strong>Cloudmark</strong> recommends scanning messages more than once. Because spam<br />

scores are affected by community feedback, a message’s score may change<br />

after the community has had time to submit feedback.<br />

For example, messages that were sent overnight should be re-scanned in<br />

the morning, after users have awakened and submitted feedback about<br />

them. In general, re-scan the message store every few hours or so, in order<br />

to filter spam that was recently detected by the community rather than by<br />

existing fingerprints.<br />

Obtaining message scores<br />

To obtain a score for a given message, you use the API to pass the message<br />

(without its envelope) to CMAE, which returns a score. There are three<br />

methods for doing this:<br />

• CMAE_ScoreRFC822()<br />

This is the simplest method, in which you provide only the message<br />

string (headers and body as a properly-formatted RFC822 message) and<br />

receive a score in return. See “CMAE_ScoreRFC822” on page 25.<br />

• CMAE_ScoreEnvelopeRFC822()<br />

This method provides both the RFC822-formatted message and its<br />

envelope as input. The envelope object is built using the provided<br />

envelope functions. The message and its envelope are scored as a unit.<br />

Whitelist filters are also applied to both the envelope data and the<br />

message. See “CMAE_ScoreEnvelopeRFC822” on page 26.<br />

12 Spam filtering basics


Chapter 3<br />

Application Development<br />

Classifying messages based on score<br />

Once your application has obtained a score from 0 to 100 from CMAE, it<br />

must use the score to classify the message. You can do this using one or<br />

more threshold values:<br />

• one threshold<br />

A single threshold represents the minimum score that qualifies a<br />

message as spam. Messages with a score greater than or equal to this<br />

value are treated as spam, while messages with a score less than this<br />

value are treated as legitimate. Initially, a threshold of 95 is<br />

recommended as the default value.<br />

• two or more thresholds<br />

The highest threshold represents the minimum score for messages that<br />

are certainly spam, while the lowest threshold represents the maximum<br />

score for messages that are certainly legitimate. Messages with scores<br />

that fall between these two thresholds are suspected spam. Depending<br />

on how many thresholds you establish, you can take action based on<br />

varying degrees of certainty about a message’s legitimacy.<br />

After some experimentation, users may want to fine-tune these values<br />

based on the actual rate of accuracy. Your application should provide a<br />

way for users to modify the threshold value.<br />

! For cartridge 3043 only, CMAE returns one of only two scores: 0 or<br />

100.<br />

Applying actions to messages<br />

Your application must provide functionality that applies an action to a<br />

message of a given classification. Examples of such actions may include the<br />

following:<br />

• moving spam to a mailbox folder specifically designated for it<br />

• adding a header to a message to trigger actions in other email processing<br />

applications<br />

• placing a text identifier in the subject line of suspected spam that allows<br />

users to readily identify it in their mail clients<br />

Spam filtering basics 13


<strong>Cloudmark</strong> <strong>Authority</strong> <strong>Engine</strong> SDK Guide Chapter 3<br />

Designing your application<br />

There are two major options for designing your application:<br />

• run CMAE directly within your application<br />

This method entails a few moments of initialization time, as it requires<br />

loading both CMAE and its filtering data. If the latest micro-update is<br />

not already on disk, then downloading it from <strong>Cloudmark</strong> may require<br />

a minute or more, depending on available bandwidth. The CMAE<br />

process must run on the same host as the MTA.<br />

Once CMAE and its data set are loaded, queries to CMAE can take<br />

place efficiently. No further setup or tear-down is required. With both<br />

the MTA and CMAE on the same host, messages can be passed quickly<br />

without using network resources.<br />

! The fork() function is not supported under this scenario.<br />

• create a daemon that encapsulates CMAE, then query the daemon using<br />

a lightweight client layer<br />

Using this approach, the cost of initializing the client layer should be<br />

negligible. Potential benefits of this approach include the ability to<br />

perform the filtering work outside of the application, sharing a single<br />

filtering daemon among multiple application instances, and the ability<br />

to run the daemon on a different host than the MTA.<br />

14 Designing your application


API Reference<br />

CHAPTER<br />

4<br />

This chapter provides API conventions for developing CMAE-enabled<br />

applications; they are followed by a complete list of functions, constants,<br />

and structures available in the CMAE SDK and usage details for each.<br />

Conventions<br />

The CMAE API is a standards-based C interface and can be compiled by<br />

any ANSI C compiler. The functions, constants and structures of the API<br />

are defined in cmae.h, the header file for the C interface.<br />

Scoring messages<br />

The CMAE SDK provides two methods for scoring messages:<br />

• The first method passes an entire message to CMAE to obtain a score<br />

for it, including both the headers and body, using only one function<br />

(CMAE_ScoreRFC822). While this the simplest method, it is also the<br />

most resource intensive.<br />

• The second method passes one or more parts of a message to CMAE,<br />

which returns a score based on only the provided subset of SMTP data<br />

(e.g., just the envelope or the headers, or both). With it, messages can be<br />

scored at various stages of the SMTP transaction, from the initial<br />

network connection to the receipt of the message body. This method<br />

enables your application to optimize CMAE message scoring<br />

performance by, for example, bypassing analysis of the headers and<br />

body content for messages with a specific IP address in their envelope.<br />

To score a message using its SMTP envelope, construct an envelope object<br />

(CMAE_Envelope) with the envelope handling functions prior to scoring it<br />

(CMAE_ScoreEnvelopeRFC822). The constructed envelope must be freed<br />

15


<strong>Cloudmark</strong> <strong>Authority</strong> <strong>Engine</strong> SDK Guide Chapter 4<br />

after scoring with the CMAE_EnvelopeDone function. See “Envelope<br />

Functions” on page 27.<br />

Object Management<br />

CMAE_Envelope objects are instantiated by CMAE_Init and<br />

CMAE_EnvelopeInit, and are freed by the CMAE_Shutdown and<br />

CMAE_EnvelopeDone destructors, respectively; however, if the objects are<br />

instantiated by CMAE, they are freed automatically.<br />

All CMAE_Envelope objects must be synchronized by your application.<br />

Synchronization and Threading<br />

CMAE is thread-safe and can process multiple messages in multiple<br />

threads.<br />

When initializing CMAE, your application should not call any API<br />

functions until CMAE_Init is done (with the exception of registering<br />

callback functions). Conversely, your application should wait until all API<br />

functions in every thread are done before shutting down CMAE via<br />

CMAE_Shutdown.<br />

Memory Management<br />

To manage CMAE memory allocation, your application can register both<br />

the CMAE_MallocCB and CMAE_FreeCB callbacks before initializing<br />

CMAE. If your application does not register both callbacks before<br />

CMAE_Init is called, CMAE will use its built-in memory allocation<br />

scheme.<br />

Note that the functions specified as arguments for the CMAE_LogCB,<br />

CMAE_MallocCB, and CMAE_FreeCB functions do not guard against<br />

multiple entry. For CMAE_MallocCB in particular, avoid calls that may<br />

allocate memory, such as stdio.h functions like printf().<br />

16 Conventions


Chapter 4<br />

API Reference<br />

Call Sequence<br />

The following call sequence is recommended:<br />

1. Override the callback functions for memory allocation management and<br />

logging.<br />

2. Initialize the <strong>Authority</strong> <strong>Engine</strong> with CMAE_Init.<br />

3. Call scoring and accessor functions.<br />

4. Release CMAE with CMAE_Shutdown.<br />

Error Codes<br />

All CMAE API functions return a CMAE_ERR type that indicates the<br />

success or failure of the function call. A function call that succeeds returns<br />

CMAE_ERR_NONE. A function call that fails returns a CMAE_ERR<br />

enumeration that indicates the reason for failure. There are three<br />

exceptions: CMAE_strerror, CMAE_MicroupdatesVersion, and<br />

CMAE_CartridgeVersion.<br />

Your application must provide error handling routines for every error code<br />

returned by a function. The possible error codes are:<br />

Table 1<br />

Error codes<br />

Constant<br />

CMAE_ERR_BADARG<br />

CMAE_ERR_BADFILE<br />

CMAE_ERR_ENGINE<br />

CMAE_ERR_MALLOC<br />

CMAE_ERR_NOFILE<br />

CMAE_ERR_NOINIT<br />

CMAE_ERR_NONE<br />

CMAE_ERR_STATE<br />

Description<br />

The function argument(s) was invalid<br />

A necessary file or resource—such as the cartridge—is<br />

malformed and cannot be opened by CMAE<br />

CMAE failed during the function call<br />

Memory allocation errors reported by the function call<br />

The specified file was not found<br />

A function was called prior to CMAE initialization<br />

No errors were returned by the function<br />

An operation was performed on an object in the wrong state,<br />

including multiple initialization<br />

Conventions 17


<strong>Cloudmark</strong> <strong>Authority</strong> <strong>Engine</strong> SDK Guide Chapter 4<br />

Constants<br />

The following constants provide CMAE version information and should be<br />

used to manage multiple version compatibility.<br />

CMAE_INTERFACE_VERSION_1 Version of the CMAE C interface in<br />

use by your application, which is passed to CMAE_Init().<br />

const unsigned int CMAE_INTERFACE_VERSION_1<br />

Use this constant to maintain backward-compatibility in your application<br />

to other applications that use earlier versions of the interface.<br />

! <strong>Cloudmark</strong> strives to maintain backward-compatibility between new<br />

and prior versions of the C interface.<br />

CMAE_InterfaceVersion Version of the CMAE C interface in use by<br />

your application, returned as an integer, which is updated with each new<br />

version of the interface.<br />

const unsigned int CMAE_InterfaceVersion<br />

CMAE_Version Version of CMAE linked to your application, as a<br />

human-readable string. As best practice, your application should log this<br />

value when initializing CMAE.<br />

const char *CMAE_Version<br />

Structures<br />

The following structures define the configuration parameters for CMAE:<br />

CMAE_Config<br />

Description<br />

Specifies the maximum number of bytes in the header and body<br />

content of a message to use for scoring.<br />

Syntax typedef struct {<br />

unsigned int MaxInspectHeaderSize;<br />

unsigned int MaxInspectBodySize;<br />

unsigned int UseMsgAnalysis;<br />

} CMAE_Config;<br />

18 Constants


Chapter 4<br />

API Reference<br />

CMAE_Config<br />

Parameters • MaxInspectHeaderSize<br />

The maximum size of the header to use for scoring.<br />

• MaxInspectBodySize<br />

Maximum size of the message content to use for scoring.<br />

• UseMsgAnalysis<br />

When non-zero, UseMsgAnalysis generates message analysis<br />

callbacks. To debug scoring issues, your application should register<br />

the callbacks with CMAE_MsgAnalysisCB and then, for example,<br />

add the returned values to the message as a header for later<br />

analysis.<br />

A size of less than 32k is recommended for both<br />

MaxInspectHeaderSize and MaxInspectBodySize.<br />

See also “CMAE_Configure” on page 23<br />

CMAE_Envelope<br />

Description<br />

An opaque handle to parts of the envelope structure. When<br />

instantiated, it contains each part of the envelope for a given message.<br />

CMAE_Envelope is managed by CMAE; only use the CMAE_Envelope<br />

accessor functions to manipulate it. See “Envelope Functions” on<br />

page 27.<br />

“Object Management” on page 16 provides additional information on<br />

CMAE_Envelope.<br />

Syntax<br />

Parameters<br />

See also<br />

Callback Functions<br />

The CMAE SDK callback functions enable logging and provide accuracy<br />

debugging and memory management facilities.<br />

Callback Functions 19


<strong>Cloudmark</strong> <strong>Authority</strong> <strong>Engine</strong> SDK Guide Chapter 4<br />

CMAE_LogCB<br />

Description<br />

Syntax<br />

Acquires the log messages and levels generated by the built-in logging<br />

functionality of CMAE.<br />

Your application should register for this callback and provide any<br />

functionality required to handle CMAE log messages.<br />

CMAE_ERR CMAE_LogCB(<br />

void (*CallBack)(CMAE_LOG LogLevel,<br />

const char *ASCIIFacility,<br />

const char *ASCIIMsg));<br />

Parameters • [in] CallBack<br />

Pointer to a function in your application; passes the three<br />

parameters described next. Passing in NULL as the argument<br />

removes the callback registration, restoring the default behavior.<br />

• [in] LogLevel<br />

The severity of the log message as one of the following constants:<br />

- CMAE_LOG_ERROR<br />

An error that requires operator intervention; your application<br />

must provide error handling for this error<br />

- CMAE_LOG_WARNING<br />

Warnings returned by CMAE; your application is not required<br />

handle warnings, but should as best practice<br />

- CMAE_LOG_INFO<br />

General information returned by CMAE during normal<br />

operation; provides verbose logging capability<br />

• [in] ASCIIFacility<br />

The service that requested the logging; may be NULL.<br />

• [in] ASCIIMessage<br />

The log message as text.<br />

Return values See “Error Codes” on page 17.<br />

20 Callback Functions


Chapter 4<br />

API Reference<br />

CMAE_MallocCB<br />

Description<br />

Syntax<br />

Overrides the built-in memory allocation scheme of CMAE.<br />

The registered callback CMAE_MallocCB requires the same semantics<br />

as the malloc() call in C. When registered, the callback must return a<br />

valid pointer to a region of memory that has the number of bytes<br />

specified in size_t free. If unable to allocate memory, the callback must<br />

return NULL. Note that while CMAE uses this callback, the cartridges<br />

do not.<br />

This callback must be used in tandem with “CMAE_FreeCB” on<br />

page 21.<br />

If this callback is not registered, CMAE will manage memory allocation<br />

internally.<br />

CMAE_ERR CMAE_MallocCB (void<br />

*(*CallBack)(size_t Size));<br />

Parameters • [in] CallBack<br />

Pointer to a function in your application that returns a pointer to<br />

the amount of memory allocated to CMAE (via the size_t<br />

parameter). Passing in NULL as the argument removes the callback<br />

registration, restoring the default behavior.<br />

Return values See “Error Codes” on page 17.<br />

CMAE_FreeCB<br />

Description<br />

Syntax<br />

Overrides the built-in memory allocation scheme of CMAE.<br />

The registered callback CMAE_FreeCB requires the same semantics as<br />

the free() call in C. The parameter passed to the registered callback<br />

contains the pointer returned by CMAE_MallocCB. Note that while<br />

CMAE uses this callback, the cartridges do not.<br />

This callback must be used in tandem with “CMAE_MallocCB” on<br />

page 21.<br />

If this callback is not registered, CMAE will manage memory allocation<br />

internally.<br />

CMAE_ERR CMAE_FreeCB(void (*CallBack)(void<br />

*Block));<br />

Parameters • [in] CallBack<br />

Pointer to a function in the application to the allocated memory<br />

space via the *Block parameter; this pointer must be acquired<br />

from the callback function registered with CMAE_MallocCB.<br />

Passing in NULL as the argument removes the callback registration,<br />

restoring the default behavior.<br />

Return values See “Error Codes” on page 17.<br />

Callback Functions 21


<strong>Cloudmark</strong> <strong>Authority</strong> <strong>Engine</strong> SDK Guide Chapter 4<br />

CMAE_MsgAnalysisCB<br />

Description<br />

Syntax<br />

Acquires message analysis information from <strong>Cloudmark</strong> for<br />

troubleshooting scoring issues.<br />

Your application should register for this callback, if possible; doing so<br />

helps improve the effectiveness of CMAE.<br />

CMAE_ERR CMAE_MsgAnalysisCB<br />

(void (*CallBack)<br />

(const char *ASCIIMsg,<br />

void *AnalysisUserData));<br />

Parameters • [in] CallBack<br />

Pointer to a function in the application with the specified<br />

parameters. Passing in NULL as the argument removes the callback<br />

registration, restoring the default behavior.<br />

Return values See “Error Codes” on page 17.<br />

See also “CMAE_MsgAnalysisUserData” on page 25<br />

CMAE Functions<br />

CMAE functions are used to do the following:<br />

• control initialization of the <strong>Authority</strong> <strong>Engine</strong><br />

• configure the <strong>Authority</strong> <strong>Engine</strong> while in use<br />

• query the version of the cartridge and micro-updates<br />

• acquire the full text description of any error code<br />

CMAE_Init<br />

Description<br />

Syntax<br />

Initializes CMAE.<br />

CMAE_Init is not reentrant. Your application—and any threads it<br />

creates—must wait until CMAE_Init is complete before calling other<br />

CMAE functions; otherwise, the functions will return<br />

CMAE_ERR_NOINIT.<br />

CMAE_ERR CMAE_Init(unsigned int<br />

InterfaceVersion,<br />

const CMAE_Config *Config,<br />

const char *CartridgeDirectory,<br />

const char *ConfigDirectory);<br />

22 CMAE Functions


Chapter 4<br />

API Reference<br />

CMAE_Init<br />

Parameters • [in] InterfaceVersion<br />

Version of the CMAE C interface in use by your application. Set it<br />

to CMAE_INTERFACE_VERSION_1.<br />

• [in] Config<br />

Configuration updates for CMAE, contained in a CMAE_Config<br />

object.<br />

• [in] CartridgeDirectory<br />

The cartridge directory path.<br />

Always set CartridgeDirectory to the directory path containing the<br />

cartridge.<br />

• [in] ConfigDirectory<br />

Directory path to the configuration file.<br />

Always set ConfigDirectory with the directory path to the cartridge<br />

configuration file.<br />

Return values<br />

If the CartridgeDirectory or ConfigDirectory parameters are NULL, this<br />

function returns CMAE_ERR_BADARG<br />

See also See “Error Codes” on page 17.<br />

CMAE_Configure<br />

Description<br />

Syntax<br />

Applies a set of configuration parameters to CMAE when it is running.<br />

CMAE_ERR CMAE_Configure(<br />

const CMAE_Config *NewConfig);<br />

Parameters • [in] NewConfig<br />

The set of CMAE configuration parameters contained in<br />

CMAE_Config.<br />

See also See “Error Codes” on page 17.<br />

CMAE_Shutdown<br />

Description<br />

Syntax<br />

Shuts down CMAE gracefully, releasing all resources used by it. All<br />

scoring threads must be idle before this interface is called. The<br />

application must ensure that no messages are being processed when<br />

this function is called.<br />

Call CMAE_Shutdown during the exit sequence of your application.<br />

CMAE_Shutdown is not reentrant. Your application—and the threads<br />

it creates—must not call any CMAE functions during or after CMAE<br />

shutdown.<br />

CMAE_ERR CMAE_Shutdown(void);<br />

Return values See “Error Codes” on page 17.<br />

CMAE Functions 23


<strong>Cloudmark</strong> <strong>Authority</strong> <strong>Engine</strong> SDK Guide Chapter 4<br />

CMAE_CartridgeVersion<br />

Description<br />

Syntax<br />

Return values<br />

Returns the version of the cartridge in use by CMAE.<br />

Call CMAE_CartridgeVersion after CMAE_Init is complete; otherwise,<br />

the function calls will return CMAE_ERR_NOINIT.<br />

const char *CMAE_CartridgeVersion(void);<br />

CMAE_CartridgeVersion returns a pointer (as a constant) to a nullterminated<br />

text buffer containing the cartridge version.<br />

See also “Constants” on page 18.<br />

CMAE_MicroupdatesVersion<br />

Description<br />

Syntax<br />

Return values<br />

Returns the version of the last micro-updates file downloaded from<br />

<strong>Cloudmark</strong>.<br />

Call CMAE_MicroupdatesVersion after CMAE_Init is complete;<br />

otherwise, the function calls will return CMAE_ERR_NOINIT.<br />

int CMAE_MicroupdatesVersion(void);<br />

CMAE_MicroupdatesVersion returns the version of the current microupdates<br />

file via a pointer to an integer.<br />

See also “Constants” on page 18.<br />

CMAE_strerror<br />

Description<br />

Syntax<br />

Returns the text description of a CMAE_ERR error code constant<br />

returned by another function.<br />

const char *CMAE_strerror(CMAE_ERR Error);<br />

Parameters • [in] Error<br />

The CMAE_ERR error code constant returned by any given<br />

function.<br />

Return values<br />

CMAE_strerror returns a pointer (as a constant) to a null-terminated<br />

text buffer describing the error message in human-readable form<br />

(instead of a CMAE_ERR error code constant).<br />

See also “Error Codes” on page 17<br />

24 CMAE Functions


Chapter 4<br />

API Reference<br />

Scoring Functions<br />

The following functions provide CMAE with the necessary message data<br />

for facilitating the scoring process:<br />

CMAE_MsgAnalysisUserData<br />

Description<br />

Syntax<br />

Associates user data acquired by your application with a given<br />

message.<br />

Call CMAE_MsgAnalysisUserData before calling another scoring<br />

function, such as CMAE_ScoreRFC822.<br />

This function sets the AnalysisUserData field of the callback for the<br />

current thread and is reset after a scoring function is complete.<br />

CMAE_ERR CMAE_SetUserData (void<br />

*AnalysisUserData);<br />

Parameters • [in] AnalysisUserData<br />

Opaque user data.<br />

Return values See “Error Codes” on page 17.<br />

See also “CMAE_MsgAnalysisCB” on page 22<br />

CMAE_ScoreRFC822<br />

Description<br />

Syntax<br />

Returns the score generated by CMAE for an RFC822-compliant<br />

message.<br />

CMAE_ScoreRFC822 sets ScoreMask to CMAE_SCORE_CONTENT.<br />

The message envelope is not used by CMAE when calculating its score.<br />

CMAE_ERR CMAE_ScoreRFC822 (const char<br />

*RFC822Content,<br />

double *ScoreOut);<br />

Parameters • [in] RFC822Content<br />

An RFC822-compliant message.<br />

• [out] ScoreOut<br />

The score returned by CMAE for an RFC822-compliant message.<br />

Return values See “Error Codes” on page 17.<br />

See also “CMAE_ScoreRFC822Len” on page 26<br />

Scoring Functions 25


<strong>Cloudmark</strong> <strong>Authority</strong> <strong>Engine</strong> SDK Guide Chapter 4<br />

CMAE_ScoreRFC822Len<br />

Description<br />

Syntax<br />

Returns the score generated by CMAE for an RFC822-compliant<br />

message of a specified length.<br />

CMAE_ScoreRFC822Len increases the performance of CMAE by<br />

allowing your application to specify the length of a message instead of<br />

requiring CMAE to calculate it before scoring the message.<br />

CMAE_ERR CMAE_ScoreRFC822 (const char<br />

*RFC822Content,<br />

size_t RFC822ContentLength,<br />

double *ScoreOut);<br />

Parameters • [in] RFC822Content<br />

An RFC822-compliant message.<br />

• [in] RFC822ContentLength<br />

The length (in bytes) of an RFC822-compliant message.<br />

• [out] ScoreOut<br />

The score returned by CMAE.<br />

Return values See “Error Codes” on page 17.<br />

See also “CMAE_ScoreRFC822” on page 25<br />

CMAE_ScoreEnvelopeRFC822<br />

Description<br />

Syntax<br />

Returns the score generated by CMAE using an RFC822-compliant<br />

message and its envelope.<br />

CMAE_ERR CMAE_ScoreEnvelopeRFC822(const<br />

CMAE_Envelope Envelope,<br />

const char *RFC822Content,<br />

double *ScoreOut);<br />

Parameters • [in] Envelope<br />

The SMTP envelope of an RFC822-compliant message.<br />

• [in] RFC822Content<br />

An RFC822-compliant message.<br />

• [out] ScoreOut<br />

The score returned by CMAE.<br />

Return values See “Error Codes” on page 17.<br />

See also “CMAE_ScoreRFC822” on page 25<br />

26 Scoring Functions


Chapter 4<br />

API Reference<br />

CMAE_ScoreEnvelopeRFC822Len<br />

Description<br />

Returns the score generated by CMAE for an RFC822-compliant<br />

message of a specified length, and its envelope.<br />

CMAE_ScoreEnvelopeRFC822Len increases the performance of CMAE<br />

by allowing your application to specify the length of the message and<br />

its envelope instead of requiring CMAE to calculate it prior to scoring<br />

the message.<br />

Syntax CMAE_ERR CMAE_ScoreEnvelopeLenRFC822 (<br />

const CMAE_Envelope Envelope,<br />

const char *RFC822Content,<br />

size_t RFC822ContentLength,<br />

double *ScoreOut);<br />

Parameters • [in] Envelope<br />

The SMTP envelope of an RFC822-compliant message.<br />

• [in] RFC822Content<br />

An RFC822-compliant message.<br />

• [in] RFC822ContentLength<br />

The length (in bytes) of an RFC822-compliant message.<br />

• [out] ScoreOut<br />

The score returned by CMAE.<br />

Return values See “Error Codes” on page 17.<br />

See also • “CMAE_ScoreEnvelopeRFC822” on page 26<br />

• “CMAE_ScoreRFC822” on page 25<br />

Envelope Functions<br />

Envelope functions are located in cmae_envelope.h. Use the envelope<br />

functions to initialize (and destroy) CMAE_Envelope objects and manage<br />

configuration properties for them.<br />

Envelope Functions 27


<strong>Cloudmark</strong> <strong>Authority</strong> <strong>Engine</strong> SDK Guide Chapter 4<br />

CMAE_EnvelopeInit<br />

Description<br />

Syntax<br />

Initializes a CMAE_Envelope object.<br />

The CMAE_Envelope object initialized by this function is used by<br />

CMAE_ScoreEnvelopeRFC822 for scoring an RFC822-compliant<br />

message.<br />

CMAE_EnvelopeInit registers with CMAE_MallocCB to allocate<br />

memory for the CMAE_Envelope object before initializing it.<br />

CMAE_ERR CMAE_EnvelopeInit (CMAE_Envelope<br />

*EnvelopeOut);<br />

Parameters • [out] EnvelopeOut<br />

The SMTP envelope as an opaque CMAE_Envelope construct.<br />

Return values See “Error Codes” on page 17.<br />

See also • “CMAE_ScoreEnvelopeRFC822Len” on page 27<br />

• “CMAE_EnvelopeDone” on page 28<br />

CMAE_EnvelopeDone<br />

Description<br />

Syntax<br />

Releases a CMAE_Envelope object created by CMAE_EnvelopeInit.<br />

If Envelope is set to null, CMAE returns CMAE_ERR_BADARG.<br />

Calling CMAE_EnvelopeDone on a CMAE_Envelope object that was<br />

created by CMAE—and not CMAE_Envelope may cause memory leaks<br />

in your application.<br />

The CMAE_EnvelopeDone function should be called after the<br />

application has finished scoring the message to release the Envelope.<br />

The <strong>Authority</strong> <strong>Engine</strong> does not cache the Envelope pointer so failure to<br />

call CMAE_EnvelopeDone may result in memory leaks.<br />

CMAE does not cache envelope pointers and, consequently, cannot<br />

release CMAE_Envelope objects created byCMAE_EnvelopeInit. Your<br />

application should cache the CMAE_Envelope pointer for releasing the<br />

envelope after the message is scored.<br />

Failure to call CMAE_EnvelopeDone after the message is scored may<br />

cause memory leaks in your application. In addition, releasing a<br />

CMAE_Envelope object created by CMAE—instead of by<br />

CMAE_EnvelopeInit—may also cause memory leaks.<br />

CMAE_ERR CMAE_EnvelopeDone (CMAE_Envelope<br />

Envelope);<br />

Parameters • [in] Envelope<br />

The opaque CMAE_Envelope object previously created with<br />

CMAE_EnvelopeInit.<br />

28 Envelope Functions


Chapter 4<br />

API Reference<br />

CMAE_EnvelopeDone<br />

Return values See “Error Codes” on page 17.<br />

See also • “CMAE_ScoreRFC822Len” on page 26<br />

• “CMAE_ScoreEnvelopeRFC822Len” on page 27<br />

CMAE_EnvelopeFromHost<br />

Description<br />

Syntax<br />

The CMAE_EnvelopeFromHost function associated the connecting<br />

host’s name with SMTP envelope information stored in the Envelope<br />

object.<br />

The CMAE_Envelope object created by this function is used by<br />

CMAE_ScoreEnvelopeRFC822 to check the whitelist for the IP address<br />

of the RFC822-compliant message.<br />

The validity of the hostname is not evaluated.<br />

CMAE_ERR CMAE_EnvelopeFromHost<br />

(CMAE_Envelope Envelope,<br />

const char *Host);<br />

Parameters • [in] Envelope<br />

The CMAE_Envelope object with which to associate the email<br />

address.<br />

• [in] Host<br />

The hostname of the connecting host. This must be a fullyqualified<br />

hostname.<br />

Return values<br />

If no error occurs, CMAE_EnvelopeFromHost returns a value of<br />

CMAE_ERR_NONE. If a NULL pointer is passed into the Envelope<br />

parameter, the function will return CMAE_ERR_BADARG.<br />

CMAE_EnvelopeFromIP<br />

Description<br />

Syntax<br />

Adds the MailFrom IP address contained in the SMTP envelope to a<br />

CMAE_Envelope object.<br />

The CMAE_Envelope object created by this function is used by<br />

CMAE_ScoreEnvelopeRFC822 to check the whitelist for the IP address<br />

of the RFC822-compliant message.<br />

CMAE_ERR CMAE_EnvelopeFromIP (CMAE_Envelope<br />

Envelope,<br />

unsigned long IPAddress);<br />

Envelope Functions 29


<strong>Cloudmark</strong> <strong>Authority</strong> <strong>Engine</strong> SDK Guide Chapter 4<br />

CMAE_EnvelopeFromIP<br />

Parameters • [in] Envelope<br />

The SMTP envelope as a CMAE_Envelope object.<br />

• [in] IPAddress<br />

The IP address contained in the MailFrom header of the envelope,<br />

in network byte order.<br />

If IPAddress is set to null, CMAE returns CMAE_ERR_BADARG. In<br />

addition, CMAE does not validate IP addresses.<br />

Return values See “Error Codes” on page 17.<br />

See also • “CMAE_ScoreRFC822Len” on page 26<br />

• “CMAE_ScoreEnvelopeRFC822Len” on page 27<br />

• “CMAE_EnvelopeRcptTo” on page 31<br />

CMAE_EnvelopeHelo<br />

Description<br />

Syntax<br />

Adds the HELO domain string contained in the SMTP envelope to a<br />

CMAE_Envelope object.<br />

If HeloDomain is set to null, CMAE returns CMAE_ERR_BADARG.<br />

The CMAE_Envelope object created by this function is used by<br />

CMAE_ScoreEnvelopeRFC822 to check the whitelist for the Helo<br />

domain string in the RFC822-compliant message.<br />

CMAE_ERR CMAE_EnvelopeHelo (CMAE_Envelope<br />

Envelope,<br />

const char *HeloDomain);<br />

Parameters • [in] Envelope<br />

The SMTP envelope as a CMAE_Envelope object.<br />

• [in] HeloDomain<br />

The HELO domain string.<br />

Return values See “Error Codes” on page 17.<br />

See also • “CMAE_ScoreRFC822Len” on page 26<br />

• “CMAE_ScoreEnvelopeRFC822Len” on page 27<br />

• “CMAE_EnvelopeRcptTo” on page 31<br />

30 Envelope Functions


Chapter 4<br />

API Reference<br />

CMAE_EnvelopeMailFrom<br />

Description<br />

Syntax<br />

Adds the MailFrom address contained in the SMTP envelope to a<br />

CMAE_Envelope object.<br />

The CMAE_Envelope object created by this function is used by<br />

CMAE_ScoreEnvelopeRFC822 to check the whitelist for the MailFrom<br />

address of the RFC822-compliant message.<br />

CMAE_ERR CMAE_EnvelopeMailFrom (CMAE_Envelope<br />

Envelope,<br />

const char *EmailAddress);<br />

Parameters • [in] Envelope<br />

The SMTP envelope as a CMAE_Envelope object.<br />

• [in] EmailAddress<br />

The SMTP MailFrom address.<br />

If EmailAddress is set to null, CMAE returns CMAE_ERR_BADARG.<br />

In addition, CMAE does not validate MailFrom addresses.<br />

Return values See “Error Codes” on page 17.<br />

See also • “CMAE_ScoreRFC822Len” on page 26<br />

• “CMAE_ScoreEnvelopeRFC822Len” on page 27<br />

• “CMAE_EnvelopeRcptTo” on page 31<br />

CMAE_EnvelopeRcptTo<br />

Description<br />

Syntax<br />

Adds the RcptTo address contained in the SMTP envelope to a<br />

CMAE_Envelope object.<br />

The MailFrom address added to the CMAE_Envelope object by this<br />

function is used by CMAE_ScoreEnvelopeRFC822 for scoring an<br />

RFC822-compliant message.<br />

Your application must call CMAE_EnvelopeRcptTo once for each<br />

recipient.<br />

CMAE_ERR CMAE_EnvelopeRcptTo (CMAE_Envelope<br />

Envelope,<br />

const char *EmailAddress);<br />

Parameters • [in] Envelope<br />

The SMTP envelope as a CMAE_Envelope object.<br />

• [in] EmailAddress<br />

The SMTP RcptTo address.<br />

If EmailAddress is set to null, CMAE returns CMAE_ERR_BADARG.<br />

In addition, CMAE does not validate the address.<br />

Envelope Functions 31


<strong>Cloudmark</strong> <strong>Authority</strong> <strong>Engine</strong> SDK Guide Chapter 4<br />

CMAE_EnvelopeRcptTo<br />

Return values See “Error Codes” on page 17.<br />

See also • “CMAE_ScoreRFC822Len” on page 26<br />

• “CMAE_ScoreEnvelopeRFC822Len” on page 27<br />

• “CMAE_EnvelopeFromIP” on page 29<br />

CMAE_EnvelopeGetFromHost<br />

Description<br />

Syntax<br />

The CMAE_EnvelopeGetFromHost function is an accessor for<br />

obtaining the hostname in the CMAE_Envelope object.<br />

This function returns the hostname contained in the Envelope. If there<br />

is no hostname associated with the Envelope, then the returned value<br />

is NULL.<br />

CMAE_ERR CMAE_EnvelopeGetFromHost<br />

(const CMAE_Envelope Envelope,<br />

const char **HostOut);<br />

Parameters • [in] Envelope<br />

The CMAE_Envelope object of interest.<br />

• [out] HostOut<br />

The hostname previously stored in the Envelope. This must be a<br />

fully-qualified hostname.<br />

Return values<br />

If no error occurs, CMAE_EnvelopeGetFromHost returns a value of<br />

CMAE_ERR_NONE. If a NULL pointer is passed into the Envelope<br />

parameter, the function will return CMAE_ERR_BADARG. If a NULL<br />

pointer is passed into the IPAddressOut parameter, the function will<br />

return CMAE_ERR_BADARG.<br />

CMAE_EnvelopeGetFromIP<br />

Description<br />

Syntax<br />

Gets the IP address from a CMAE_Envelope object created by<br />

CMAE_EnvelopeInit.<br />

If there is no IP address in the CMAE_Envelope object, the IPAddress<br />

parameter returns zero.<br />

CMAE_ERR CMAE_EnvelopeGetFromIP<br />

(CMAE_Envelope Envelope,<br />

unsigned long *IPAddressOut);<br />

32 Envelope Functions


Chapter 4<br />

API Reference<br />

CMAE_EnvelopeGetFromIP<br />

Parameters • [in] Envelope<br />

The envelope as a CMAE_Envelope object.<br />

• [out] IPAddress<br />

The MailFrom IP address contained in the CMAE_Envelope object,<br />

in network byte order.<br />

CMAE does not validate the MailFrom IP addresses.<br />

Return values See “Error Codes” on page 17.<br />

CMAE_EnvelopeGetHelo_Config<br />

Description<br />

Syntax<br />

Gets the HELO domain string from a CMAE_Envelope object created<br />

by CMAE_EnvelopeInit.<br />

If there is no HELO domain string in the CMAE_Envelope object, the<br />

HeloDomainOut parameter returns null.<br />

CMAE_ERR CMAE_EnvelopeGetHelo (CMAE_Envelope<br />

Envelope,<br />

const char **HeloDomainOut);<br />

Parameters • [in] Envelope<br />

The envelope as a CMAE_Envelope object.<br />

• [out] HeloDomainOut<br />

The Helo domain string contained in the CMAE_Envelope object.<br />

Your application should not free the HeloDomainOut parameter; it<br />

is freed when the CMAE_Envelope object is released.<br />

Return values See “Error Codes” on page 17.<br />

CMAE_EnvelopeGetMailFrom<br />

Description<br />

Gets the MailFrom address from a CMAE_Envelope object created by<br />

CMAE_EnvelopeInit.<br />

If there is no MailFrom address in the CMAE_Envelope object, the<br />

IPAddress parameter returns null.<br />

Syntax CMAE_ERR CMAE_EnvelopeGetMailFrom (<br />

CMAE_Envelope Envelope,<br />

const char **EmailAddressOut);<br />

Parameters • [in] Envelope<br />

The envelope as a CMAE_Envelope object.<br />

• [out] EmailAddressOut<br />

The MailFrom address contained in the CMAE_Envelope object.<br />

Return values See “Error Codes” on page 17.<br />

Envelope Functions 33


<strong>Cloudmark</strong> <strong>Authority</strong> <strong>Engine</strong> SDK Guide Chapter 4<br />

CMAE_EnvelopeGetRcptToSize<br />

Description<br />

Syntax<br />

Gets the number of RcptTo addresses in an envelope.<br />

If there are no RcptTo addresses contained in the CMAE_Envelope<br />

object, then the SizeOut parameter returns zero.<br />

CMAE_ERR CMAE_EnvelopeGetRcptToSize<br />

(CMAE_Envelope Envelope,<br />

unsigned *SizeOut);<br />

Parameters • [in] Envelope<br />

The envelope as a CMAE_Envelope object.<br />

• [out] SizeOut<br />

The number of RcptTo addresses in the envelope.<br />

Return values See “Error Codes” on page 17.<br />

CMAE_EnvelopeGetRcptTo<br />

Description<br />

Syntax<br />

Gets the RcptTo address from a CMAE_Envelope object with the<br />

specified index.<br />

Index numbers are for RcptTo addresses are generated in<br />

monotonically increasing order, starting at zero and ending at the<br />

value of the SizeOut parameter of CMAE_EnvelopeGetRcptToSize,<br />

minus 1.<br />

If there are no RcptTo addresses contained in the CMAE_Envelope<br />

object, then the EmailAddressOut parameter returns null.<br />

CMAE_ERR CMAE_EnvelopeGetRcptTo<br />

(CMAE_Envelope Envelope,<br />

unsigned Index,<br />

const char **EmailAddressOut);<br />

Parameters • [in] Envelope<br />

The envelope as a CMAE_Envelope object.<br />

If Envelope is set to null, CMAE returns CMAE_ERR_BADARG.<br />

• [in] Index<br />

The index of the RcptTo address in the CMAE_Envelope object.<br />

• [out] EmailAddressOut<br />

The RcptTo address.<br />

Your application should not free the EmailAddressOut parameter;<br />

it is freed when the CMAE_Envelope object is released.<br />

Return values See “Error Codes” on page 17.<br />

34 Envelope Functions


The CMAE SDK Client and<br />

Daemon<br />

CHAPTER<br />

5<br />

In some cases, the message processing model may not lend itself to direct<br />

communication with the resource-intensive CMAE. To facilitate quick<br />

spam score queries without compromising performance, the CMAE SDK<br />

now includes a lightweight client program with a corresponding message<br />

scoring daemon and C API.<br />

The following components are included:<br />

• the CMAE daemon<br />

The daemon listens in the background for client requests.<br />

• the CMAE client C library<br />

You can use these functions to add the client functionality to your own<br />

programs.<br />

• a CMAE client binary<br />

This simple program is suitable for production. It retrieves a spam<br />

confidence score for any single message.<br />

The CMAE daemon<br />

By default, cmae_server listens in the background for spam score queries<br />

from the client. You can start it with the following options:<br />

Table 1<br />

cmae_server runtime arguments<br />

Option Description<br />

-h Print help and exit.<br />

-d Debug mode. Stay in the foreground and log to stderr.<br />

35


<strong>Cloudmark</strong> <strong>Authority</strong> <strong>Engine</strong> SDK Guide Chapter 5<br />

Table 1<br />

cmae_server runtime arguments<br />

-v Print the version number.<br />

-c Read the server configuration from the specified file. Default:<br />

$CMAE_CS_CONFIG<br />

! Make sure that libcmae.so is in the daemon’s $LD_LIBRARY_PATH.<br />

If the -c option is not specified, the server runs with the default<br />

configuration. You can configure the server and the client to share the<br />

same configuration file. Each will ignore the directives that pertain to the<br />

other. The cmae_server recognizes the following configuration directives:<br />

Table 2<br />

cmae_server configuration directives<br />

Directive Description Default<br />

address IP address or hostname on which to listen all<br />

port Port number on which to listen 2703<br />

workers Number of worker threads 4<br />

max clients<br />

max message size<br />

idle timeout<br />

Maximum number of simultaneous client<br />

connections<br />

Maximum size, in bytes, of message to accept<br />

from the client<br />

Number of seconds of inactivity, after which<br />

the server disconnects from the client<br />

0 (no limit)<br />

0 (no limit)<br />

0 (no timeout)<br />

server log priority Minimum event priority to log NOTICE<br />

server log file Filename of the server log none (log to syslog)<br />

server syslog facility Syslog facility daemon<br />

cartridge code dir Cartridge code directory .<br />

cartridge config dir Cartridge configuration directory .<br />

max inspect header<br />

max inspect body<br />

Maximum bytes of the header to examine; this<br />

directive is deprecated<br />

Maximum bytes of the body to examine; this<br />

directive is deprecated<br />

65536<br />

256000<br />

36 The CMAE daemon


Chapter 5<br />

The CMAE SDK Client and Daemon<br />

The CMAE client library<br />

The client’s C interface is available by linking to libcmaeclient.so and its<br />

header file, cmae_client.h. The general steps for using the CMAE client<br />

library are as follows:<br />

1. Start the CMAE server.<br />

2. Call CMAE_Client_Open() once to establish a connection to the<br />

daemon.<br />

3. For each message to be scored, call one of the following functions:<br />

CMAE_Client_ScoreRFC822()<br />

CMAE_Client_ScoreRFC822Len()<br />

CMAE_Client_ScoreEnvelopeRFC822()<br />

CMAE_Client_ScoreEnvelopeRFC822Len()<br />

4. When you are finished collecting the scores, call CMAE_Client_Close()<br />

once to close the connection.<br />

This procedure is sufficiently lightweight to be performed once per<br />

message, even if your mail volume is high.<br />

! The CMAE library and the CMAE client library are mutually exclusive.<br />

The results of linking both libraries into the same application are<br />

undefined.<br />

CMAE_Client_Default_Port<br />

Description<br />

Syntax<br />

Parameters<br />

The default port on which the daemon listens, in host byte order. This<br />

is currently port 2703. Because the default port can change in future<br />

releases, <strong>Cloudmark</strong> recommends setting a port number of your own<br />

choice.<br />

None.<br />

unsigned short<br />

CMAE_Client_Default_Port(void);<br />

The CMAE client library 37


<strong>Cloudmark</strong> <strong>Authority</strong> <strong>Engine</strong> SDK Guide Chapter 5<br />

CMAE_Client_Open<br />

Description<br />

Syntax<br />

This function sets up a client connection to the daemon.<br />

Be sure to clear errno before calling this function, and check errno<br />

after any failure. Many failures are the result of failed system calls.<br />

CMAE_ERR CMAE_Client_Open<br />

(CMAE_Client_Session *SessionOut,<br />

const char *ServerName,<br />

unsigned long ServerIPAddr,<br />

unsigned short ServerPort<br />

unsigned ConnectTimeout);<br />

Parameters • [in]ServerName<br />

The specified ServerName, if any, can be either a hostname or an<br />

IP address in network byte order.<br />

• [in]ServerIPAddr<br />

If no ServerName is specified, then ServerIPAddr must be an IP<br />

address in network byte order.<br />

• [in]ServerPort<br />

Specify the server port in host byte order. If ServerPort is set to<br />

zero, then the client uses the default port in<br />

CMAE_Client_Default_Port().<br />

• [in]ConnectTimeout<br />

The time, in seconds, after which this connection expires. Specify<br />

zero (0) to use the system default TCP timeout.<br />

• [out]SessionOut<br />

A session identifier.<br />

Return values<br />

On success, this function returns a value of CMAE_ERR_NONE and<br />

sets *SessionOut to a CMAE_Client_Session value; otherwise, it<br />

returns a negative error code. See “Error Codes” on page 17.<br />

CMAE_Client_ScoreRFC822<br />

Description<br />

Syntax<br />

This function retrieves a spam score for an RFC822-compliant<br />

message.<br />

CMAE_ERR<br />

CMAE_Client_ScoreRFC822(CMAE_Client_Session<br />

Session,<br />

const char *RFC822Content,<br />

double *ScoreOut);<br />

38 The CMAE client library


Chapter 5<br />

The CMAE SDK Client and Daemon<br />

CMAE_Client_ScoreRFC822<br />

Parameters • [in]Session<br />

The session identifier returned by CMAE_Client_Open.<br />

• [in]RFC822Content<br />

An RFC822-compliant message.<br />

• [out]ScoreOut<br />

The spam score for the specified message.<br />

Return values<br />

On success, this function returns a value of CMAE_ERR_NONE and<br />

sets *ScoreOut to a score from 0 to 100, where 0 means the message<br />

is certainly legitimate and 100 means it is certainly spam. Otherwise, it<br />

returns a negative error code. See “Error Codes” on page 17.<br />

CMAE_Client_ScoreRFC822Len<br />

Description<br />

Syntax<br />

This function retrieves a spam score for an RFC822-compliant message<br />

of a specified length.<br />

CMAE_ERR CMAE_Client_ScoreRFC822Len<br />

(CMAE_Client_Session Session,<br />

const char *RFC822Content,<br />

size_t RFC822ContentLength,<br />

double *ScoreOut);<br />

Parameters • [in]CMAE_Client_Session<br />

The session identifier returned by CMAE_Client_Open.<br />

• [in]RFC822Content<br />

An RFC822-compliant message.<br />

• [in]RFC822ContentLength<br />

The length, in bytes, of the specified message.<br />

• [out]ScoreOut<br />

The spam score for the specified message.<br />

Return values<br />

On success, this function returns a value of CMAE_ERR_NONE and<br />

sets *ScoreOut to a score from 0 to 100, where 0 means the message<br />

is certainly legitimate and 100 means it is certainly spam. Otherwise, it<br />

returns a negative error code. See “Error Codes” on page 17.<br />

CMAE_Client_ScoreEnvelopeRFC822<br />

Description<br />

Syntax<br />

This function retrieves a spam score for an RFC822-compliant message<br />

and its envelope.<br />

CMAE_ERR CMAE_Client_ScoreEnvelopeRFC822<br />

(CMAE_Client_Session Session,<br />

CMAE_Envelope Envelope,<br />

const char *RFC822Content,<br />

double *ScoreOut);<br />

The CMAE client library 39


<strong>Cloudmark</strong> <strong>Authority</strong> <strong>Engine</strong> SDK Guide Chapter 5<br />

CMAE_Client_ScoreEnvelopeRFC822<br />

Parameters • [in]CMAE_Client_Session<br />

The session identifier returned by CMAE_Client_Open.<br />

• [in]Envelope<br />

The SMTP envelope of an RFC822-compliant message.<br />

• [in]RFC822Content<br />

An RFC822-compliant message.<br />

• [out]ScoreOut<br />

The spam score for the specified message.<br />

Return values<br />

On success, this function returns a value of CMAE_ERR_NONE and<br />

sets *ScoreOut to a score from 0 to 100, where 0 means the message<br />

is certainly legitimate and 100 means it is certainly spam. Otherwise, it<br />

returns a negative error code. See “Error Codes” on page 17.<br />

CMAE_Client_ScoreEnvelopeRFC822Len<br />

Description<br />

Syntax<br />

This function retrieves a spam score for an RFC822-compliant message<br />

of a specified length, and its envelope.<br />

CMAE_ERR CMAE_Client_ScoreEnvelopeRFC822Len<br />

(CMAE_Client_Session Session,<br />

CMAE_Envelope Envelope,<br />

const char *RFC822Content,<br />

size_t RFC822ContentLength,<br />

double *ScoreOut);<br />

Parameters • [in]Session<br />

The session identifier returned by CMAE_Client_Open.<br />

• [in]Envelope<br />

The SMTP envelope of the specified message.<br />

• [in]RFC822Content<br />

An RFC822-compliant message.<br />

• [in]RFC822ContentLength<br />

The length, in bytes, of the specified message.<br />

• [out]ScoreOut<br />

The spam score for the specified message.<br />

Return values<br />

On success, this function returns a value of CMAE_ERR_NONE and<br />

sets *ScoreOut to a score from 0 to 100, where 0 means the message<br />

is certainly legitimate and 100 means it is certainly spam. Otherwise, it<br />

returns a negative error code. See “Error Codes” on page 17.<br />

40 The CMAE client library


Chapter 5<br />

The CMAE SDK Client and Daemon<br />

CMAE_Client_GetProtocolTimeout<br />

Description<br />

Syntax<br />

This gets the value of the protocol timeout. The default is zero (no<br />

timeout).<br />

CMAE_ERR CMAE_Client_GetProtocolTimeout<br />

(CMAE_Client_Session Session,<br />

unsigned *ProtocolTimeout);<br />

Parameters • [out]ProtocolTimeout<br />

The timeout, in seconds, for protocol send/receive.<br />

Return values<br />

On success, this function returns zero. On failure, it returns a negative<br />

error code. See “Error Codes” on page 17.<br />

CMAE_Client_SetProtocolTimeout<br />

Description<br />

Syntax<br />

This sets the value of the protocol timeout. The default is zero (no<br />

timeout). Generally, you do not need to set a timeout unless you wish<br />

to quickly detect a possible failure of the network or the server.<br />

CMAE_ERR CMAE_Client_SetProtocolTimeout<br />

(CMAE_Client_Session Session,<br />

unsigned ProtocolTimeout);<br />

Parameters • [in]ProtocolTimeout<br />

The timeout, in seconds, for protocol send/receive.<br />

Return values<br />

On success, this function returns zero. On failure, it returns a negative<br />

error code. See “Error Codes” on page 17.<br />

CMAE_Client_Close<br />

Description<br />

Syntax<br />

This function closes a client connection to the daemon.<br />

Once a session has been closed with this function, its session identifier<br />

cannot be re-used.<br />

CMAE_ERR<br />

CMAE_Client_Close(CMAE_Client_Session<br />

Session);<br />

Parameters • [in]Session<br />

The session identifier of the session to close.<br />

Return values<br />

On success, this function returns a value of CMAE_ERR_NONE;<br />

otherwise, it returns a negative error code. See “Error Codes” on<br />

page 17.<br />

The CMAE client library 41


<strong>Cloudmark</strong> <strong>Authority</strong> <strong>Engine</strong> SDK Guide Chapter 5<br />

The CMAE client binary<br />

The client binary, cmae_client, is provided for scripting and testing<br />

purposes. It reads an RFC822 message from standard input or from a file,<br />

then returns a spam confidence score obtained from the CMAE daemon.<br />

You can invoke it like this:<br />

cmae_client [-d] [-c ] [-[INHFT] ] []<br />

Table 3<br />

cmae_client runtime arguments<br />

Argument Description Default<br />

-h print help and exit<br />

-v version<br />

-t exit with status of 6 if spam confidence<br />

reaches configured threshold<br />

print spam confidence<br />

-d debug: log to stderr<br />

-c read configuration from $CMAE_CS_CONFIG<br />

-I IP address of sending host localhost<br />

-N Name of sending host (reverse DNS of IP)<br />

-H HELO string<br />

-F Sender email address<br />

-T Recipient email address--multiple -T is OK<br />

file containing an RFC822 message stdin<br />

The following exit codes may be returned:<br />

Table 4<br />

cmae_client exit codes<br />

Exit code<br />

Description<br />

0 Success<br />

6 When the -t runtime argument is specified, this exit code indicates that the<br />

message is spam.<br />

64 Command line usage error; check Table 3 above<br />

66 Cannot open the email message<br />

69 The CMAE server is unreachable on the specified host and port<br />

70 Internal error<br />

71 System error<br />

76 Remote error in protocol; the CMAE server was reached, but the attempt to<br />

obtain a score failed<br />

42 The CMAE client binary


Chapter 5<br />

The CMAE SDK Client and Daemon<br />

If the -c option is not specified, the client runs with the default<br />

configuration values. You can configure the server and the client to share<br />

the same configuration file. Each will ignore the directives that pertain to<br />

the other. The client-specific configuration directives are as follows:<br />

Table 5<br />

cmae_client configuration directives<br />

Directive Description Default<br />

address IP address or hostname to listen on all<br />

port port to listen on 2703<br />

client log priority minimum event priority to log NOTICE<br />

client log file log file none (log to syslog)<br />

client syslog facility syslog facility user<br />

client protocol timeout network send/receive timeout none<br />

threshold spam confidence threshold for -t option 96<br />

The CMAE client binary 43


<strong>Cloudmark</strong> <strong>Authority</strong> <strong>Engine</strong> SDK Guide Chapter 5<br />

44 The CMAE client binary


Sample Code<br />

APPENDIX<br />

A<br />

The program listed here (example.c) shows the minimum amount of<br />

coding required to score messages with CMAE. The example.c file is<br />

located in the example directory of the CMAE SDK.<br />

/*<br />

*<br />

* C:\>c:\example.exe spam.txt<br />

* Score: 99.999997<br />

*<br />

*/<br />

#include <br />

#include <br />

#ifdef _WIN32<br />

#include <br />

#define ETCDIR ".\\etc"<br />

#define LIBDIR ".\\lib"<br />

#else<br />

#include <br />

#define ETCDIR "./etc"<br />

#define LIBDIR "./lib"<br />

#endif<br />

/* Include <strong>Cloudmark</strong> <strong>Authority</strong> <strong>Engine</strong> */<br />

#include "cmae.h"<br />

/* Logging callback function */<br />

void LogCB(CMAE_LOG MsgLevel, const char *Facility, const char<br />

*ASCIIMsg)<br />

{<br />

printf("%d:%s: %s\n", MsgLevel, Facility ? Facility : "", ASCIIMsg ? ASCIIMsg : "");<br />

}<br />

/* MSG Analysis CB */<br />

void MsgAnalysisCB(const char *ASCIIMsg, void *UserData)<br />

{<br />

45


<strong>Cloudmark</strong> Desktop User’s Guide<br />

Appendix A<br />

}<br />

printf("(%p) %s\n", UserData, ASCIIMsg);<br />

/* Main */<br />

int main(int argc, char *argv[])<br />

{<br />

CMAE_Config config;<br />

char mail[65536];<br />

double score;<br />

CMAE_ERR ret;<br />

size_t readlen;<br />

const char *cv;<br />

FILE *mailfile;<br />

if (argc != 2) {<br />

fprintf(stderr, "usage: %s \n", argv[0]);<br />

return 1;<br />

}<br />

/* Initialize engine */<br />

CMAE_LogCB(LogCB);<br />

CMAE_MsgAnalysisCB(MsgAnalysisCB);<br />

config.MaxInspectHeaderSize = 65536;<br />

config.MaxInspectBodySize = 32767;<br />

config.UseMsgAnalysis = 1;<br />

if ((ret = CMAE_Init(CMAE_INTERFACE_VERSION_1, &config,<br />

LIBDIR, ETCDIR)) != 0)<br />

{<br />

fprintf(stderr, "init error: %s\n", CMAE_strerror(ret));<br />

return 1;<br />

}<br />

/* CMAE_CartrdigeVersion may be NULL if CMAE_Init returned<br />

error */<br />

cv = CMAE_CartridgeVersion();<br />

printf("Cartridge version : %s\n", cv?cv:"(null)");<br />

printf("Microupdates version: %d\n",<br />

CMAE_MicroupdatesVersion());<br />

/* Read the email from the provided file */<br />

if ((mailfile=fopen(argv[1], "r")) == NULL) {<br />

fprintf(stderr, "Could not open file %s\n", argv[1]);<br />

return 1;<br />

}<br />

46


Appendix A<br />

Sample Code<br />

if ((readlen = fread(mail, 1, sizeof(mail)-1, mailfile))


<strong>Cloudmark</strong> Desktop User’s Guide<br />

Appendix A<br />

48


Index<br />

INDEX<br />

A<br />

ANSI C 15<br />

C<br />

callbacks 19<br />

cartridge 4, 5, 8, 10, 13, 23, 24, 36<br />

client 35, 37<br />

<strong>Cloudmark</strong> Collaborative Security<br />

Network 11<br />

cmae.dll 3<br />

cmae.h 3, 5, 8, 9, 15<br />

cmae.lib 4<br />

CMAE_CartridgeVersion 24<br />

cmae_client 5, 8, 10<br />

cmae_client.h 5, 8, 10, 37<br />

CMAE_Client_GetProtocolTimeout 4<br />

1<br />

CMAE_Client_Open 37<br />

CMAE_Client_SetProtocolTimeout 4<br />

1<br />

CMAE_Config 18, 23<br />

CMAE_Configure 23<br />

CMAE_Envelope 15, 19, 27<br />

cmae_envelope.h 5, 8, 9<br />

CMAE_EnvelopeDone 28<br />

CMAE_EnvelopeFromHost 29<br />

CMAE_EnvelopeFromIP 29<br />

CMAE_EnvelopeGetFromHost 32<br />

CMAE_EnvelopeGetFromIP 32<br />

CMAE_EnvelopeGetHelo_Config 33<br />

CMAE_EnvelopeGetMailFrom 33<br />

CMAE_EnvelopeGetRcptTo 34<br />

CMAE_EnvelopeGetRcptToSize 34<br />

CMAE_EnvelopeHelo 30<br />

CMAE_EnvelopeInit 28, 32<br />

CMAE_EnvelopeMailFrom 31<br />

CMAE_EnvelopeRcptTo 31<br />

CMAE_ERR_BADARG 17, 28, 29,<br />

30, 32<br />

CMAE_ERR_BADFILE 17<br />

CMAE_ERR_ENGINE 17<br />

CMAE_ERR_MALLOC 17<br />

CMAE_ERR_NOFILE 17<br />

CMAE_ERR_NOINIT 17, 22, 24<br />

CMAE_ERR_NONE 17, 29, 32<br />

CMAE_ERR_STATE 17<br />

cmae_error.h 5, 8, 9<br />

CMAE_FreeCB 21<br />

CMAE_Init 18, 22, 24<br />

CMAE_INTERFACE_VERSION_1 1<br />

8, 23<br />

CMAE_InterfaceVersion 18<br />

CMAE_LogCB 20<br />

CMAE_MallocCB 21, 28<br />

CMAE_MicroupdatesVersion 24<br />

CMAE_MsgAnalysisCB 22<br />

CMAE_MsgAnalysisUserData 25<br />

cmae_port.h 5, 8, 9<br />

CMAE_ScoreEnvelopeRFC822 12,<br />

15, 26, 28, 29, 31<br />

CMAE_ScoreEnvelopeRFC822Len 27<br />

CMAE_ScoreRFC822 12, 25<br />

CMAE_ScoreRFC822Len 26<br />

cmae_server 5, 8, 10, 35<br />

CMAE_Shutdown 23<br />

CMAE_strerror 24<br />

CMAE_Version 18<br />

configuration 42, 43<br />

constants 18<br />

49


Index<br />

D<br />

daemon 14, 35<br />

debug mode 35<br />

logging 36<br />

debug mode 35<br />

E<br />

engtest 5, 8, 10<br />

engtest.exe 4<br />

envelope functions 27<br />

error codes 17<br />

example.c 4, 5, 8, 9, 45<br />

example.sln 4<br />

example.vcproj 4<br />

G<br />

gcc 5, 6, 7, 8<br />

L<br />

ld-linux.so.2 6<br />

libaio.so.1 9<br />

libc.so.1 9<br />

libc.so.6 6<br />

libc_r.so.4 10<br />

libcmae.so 5, 8, 9<br />

libcmaeclient.so 5, 8, 10, 37<br />

libdl.so.1 9<br />

libdl.so.2 6<br />

libgcc_s.so.1 6<br />

libm.so.1 9, 10<br />

libm.so.6 6<br />

libmp.so.2 9<br />

libnsl.so.1 9<br />

libpthread.so.0 6<br />

libpthread.so.1 8<br />

libresolv.so.2 9<br />

librt.so.1 9<br />

libsocket.so.1 9<br />

libstdc++.so.2.10.0 9<br />

libstdc++.so.5 6<br />

libstdc++-libc6.2-2.so.3 6<br />

libthread.so.1 9<br />

libz.so 8<br />

libz.so.1 6<br />

Linux 4<br />

logging 20, 35, 36<br />

M<br />

memory leaks 28<br />

memory management 16, 21<br />

messages<br />

applying actions to 13<br />

classifying 13<br />

scoring 12, 15, 25, 35<br />

Microsoft Visual Studio 3<br />

Microsoft Windows 3<br />

micro-updates 11, 14, 24<br />

msvcp71.dll 4<br />

msvcr71.dll 4<br />

O<br />

object management 16<br />

P<br />

performance 26, 27<br />

R<br />

Red Hat Enterprise Linux 4<br />

Redhat Desktop 4<br />

re-scanning messages 12<br />

S<br />

Solaris 7<br />

spam 11<br />

filtering 12<br />

score 11, 12<br />

structures 18<br />

synchronization 16<br />

T<br />

threading 16<br />

Trust Evaluation System 11<br />

U<br />

UltraSPARC 7<br />

50


Index<br />

W<br />

whitelist 29, 30<br />

51


Index<br />

52

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!