• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

kleopatra

  • sources
  • kde-4.12
  • kdepim
  • kleopatra
  • utils
classify.cpp
Go to the documentation of this file.
1 /* -*- mode: c++; c-basic-offset:4 -*-
2  utils/classify.cpp
3 
4  This file is part of Kleopatra, the KDE keymanager
5  Copyright (c) 2007 Klarälvdalens Datakonsult AB
6 
7  Kleopatra is free software; you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation; either version 2 of the License, or
10  (at your option) any later version.
11 
12  Kleopatra is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 
21  In addition, as a special exception, the copyright holders give
22  permission to link the code of this program with any edition of
23  the Qt library by Trolltech AS, Norway (or with modified versions
24  of Qt that use the same license as Qt), and distribute linked
25  combinations including the two. You must obey the GNU General
26  Public License in all respects for all of the code used other than
27  Qt. If you modify this file, you may extend this exception to
28  your version of the file, but you are not obligated to do so. If
29  you do not wish to do so, delete this exception statement from
30  your version.
31 */
32 
33 #include <config-kleopatra.h>
34 
35 #include "classify.h"
36 
37 #include "fileoperationspreferences.h"
38 
39 #include <QString>
40 #include <QStringList>
41 #include <QFile>
42 #include <QFileInfo>
43 #include <QtAlgorithms>
44 #include <QByteArrayMatcher>
45 
46 #include <boost/range.hpp>
47 
48 #ifdef __GNUC__
49 # include <ext/algorithm>
50 #endif
51 
52 #include <functional>
53 
54 using namespace boost;
55 using namespace Kleo::Class;
56 
57 namespace {
58 
59  const unsigned int ExamineContentHint = 0x8000;
60 
61  static const struct _classification {
62  char extension[4];
63  unsigned int classification;
64  } classifications[] = {
65  // ordered by extension
66  { "arl", CMS | Binary | CertificateRevocationList },
67  { "asc", OpenPGP| Ascii | OpaqueSignature|DetachedSignature|CipherText|AnyCertStoreType | ExamineContentHint },
68  { "crl", CMS | Binary | CertificateRevocationList },
69  { "crt", CMS | Binary | Certificate },
70  { "der", CMS | Binary | Certificate|CertificateRevocationList },
71  { "gpg", OpenPGP| Binary | OpaqueSignature|CipherText|AnyCertStoreType },
72  { "p10", CMS | Ascii | CertificateRequest },
73  { "p12", CMS | Binary | ExportedPSM },
74  { "p7c", CMS | Binary | Certificate },
75  { "p7m", CMS | Binary | CipherText },
76  { "p7s", CMS | Binary | AnySignature },
77  { "pem", CMS | Ascii | AnyType | ExamineContentHint },
78  { "pgp", OpenPGP| Binary | OpaqueSignature|CipherText|AnyCertStoreType },
79  { "sig", OpenPGP|AnyFormat| DetachedSignature },
80  };
81 
82  static const unsigned int defaultClassification = NoClass;
83 
84  template <template <typename U> class Op>
85  struct ByExtension {
86  typedef bool result_type;
87 
88  template <typename T>
89  bool operator()( const T & lhs, const T & rhs ) const {
90  return Op<int>()( qstricmp( lhs.extension, rhs.extension ), 0 );
91  }
92  template <typename T>
93  bool operator()( const T & lhs, const char * rhs ) const {
94  return Op<int>()( qstricmp( lhs.extension, rhs ), 0 );
95  }
96  template <typename T>
97  bool operator()( const char * lhs, const T & rhs ) const {
98  return Op<int>()( qstricmp( lhs, rhs.extension ), 0 );
99  }
100  bool operator()( const char * lhs, const char * rhs ) const {
101  return Op<int>()( qstricmp( lhs, rhs ), 0 );
102  }
103  };
104 
105  static const struct _content_classification {
106  char content[28];
107  unsigned int classification;
108  } content_classifications[] = {
109  { "CERTIFICATE", Certificate },
110  { "ENCRYPTED MESSAGE", CipherText },
111  { "MESSAGE", OpaqueSignature|CipherText },
112  { "PKCS12", ExportedPSM },
113  { "PRIVATE KEY BLOCK", ExportedPSM },
114  { "PUBLIC KEY BLOCK", Certificate },
115  { "SIGNATURE", DetachedSignature },
116  { "SIGNED MESSAGE", ClearsignedMessage|DetachedSignature },
117  };
118 
119  template <template <typename U> class Op>
120  struct ByContent {
121  typedef bool result_type;
122 
123  const unsigned int N;
124  explicit ByContent( unsigned int n ) : N( n ) {}
125 
126  template <typename T>
127  bool operator()( const T & lhs, const T & rhs ) const {
128  return Op<int>()( qstrncmp( lhs.content, rhs.content, N ), 0 );
129  }
130  template <typename T>
131  bool operator()( const T & lhs, const char * rhs ) const {
132  return Op<int>()( qstrncmp( lhs.content, rhs, N ), 0 );
133  }
134  template <typename T>
135  bool operator()( const char * lhs, const T & rhs ) const {
136  return Op<int>()( qstrncmp( lhs, rhs.content, N ), 0 );
137  }
138  bool operator()( const char * lhs, const char * rhs ) const {
139  return Op<int>()( qstrncmp( lhs, rhs, N ), 0 );
140  }
141  };
142 
143 }
144 
145 unsigned int Kleo::classify( const QStringList & fileNames ) {
146  if ( fileNames.empty() )
147  return 0;
148  unsigned int result = classify( fileNames.front() );
149  Q_FOREACH( const QString & fileName, fileNames )
150  result &= classify( fileName );
151  return result;
152 }
153 
154 unsigned int Kleo::classify( const QString & filename ) {
155 #ifdef __GNUC__
156  assert( __gnu_cxx::is_sorted( begin( classifications ), end( classifications ), ByExtension<std::less>() ) );
157 #endif
158 
159  const QFileInfo fi( filename );
160 
161  const _classification * const it = qBinaryFind( begin( classifications ), end( classifications ),
162  fi.suffix().toLatin1().constData(),
163  ByExtension<std::less>() );
164  if ( it != end( classifications ) )
165  if ( !( it->classification & ExamineContentHint ) )
166  return it->classification;
167 
168  const unsigned int bestGuess =
169  it == end( classifications ) ? defaultClassification
170  /* else */ : it->classification ;
171 
172  QFile file( filename );
173  if ( !file.open( QIODevice::ReadOnly|QIODevice::Text ) )
174  return bestGuess;
175 
176  const unsigned int contentClassification = classifyContent( file.read( 4096 ) );
177  if ( contentClassification != defaultClassification )
178  return contentClassification;
179  else
180  return bestGuess;
181 }
182 
183 unsigned int Kleo::classifyContent( const QByteArray & data ) {
184 #ifdef __GNUC__
185  assert( __gnu_cxx::is_sorted( begin( content_classifications ), end( content_classifications ), ByContent<std::less>(100) ) );
186 #endif
187 
188  static const char beginString[] = "-----BEGIN ";
189  static const QByteArrayMatcher beginMatcher( beginString );
190  int pos = beginMatcher.indexIn( data );
191  if ( pos < 0 )
192  return defaultClassification;
193  pos += sizeof beginString - 1;
194 
195  const bool pgp = qstrncmp( data.data() + pos, "PGP ", 4 ) == 0;
196  if ( pgp )
197  pos += 4;
198 
199  const int epos = data.indexOf( "-----\n", pos );
200  if ( epos < 0 )
201  return defaultClassification;
202 
203  const _content_classification * const cit
204  = qBinaryFind( begin( content_classifications ), end( content_classifications ),
205  data.data() + pos, ByContent<std::less>( epos - pos ) );
206 
207  if ( cit == end( content_classifications ) )
208  return defaultClassification;
209  else
210  return cit->classification | ( pgp ? OpenPGP : CMS );
211 }
212 
213 QString Kleo::printableClassification( unsigned int classification ) {
214  QStringList parts;
215  if ( classification & CMS )
216  parts.push_back( QLatin1String("CMS") );
217  if ( classification & OpenPGP )
218  parts.push_back( QLatin1String("OpenPGP") );
219  if ( classification & Binary )
220  parts.push_back( QLatin1String("Binary") );
221  if ( classification & Ascii )
222  parts.push_back( QLatin1String("Ascii") );
223  if ( classification & DetachedSignature )
224  parts.push_back( QLatin1String("DetachedSignature") );
225  if ( classification & OpaqueSignature )
226  parts.push_back( QLatin1String("OpaqueSignature") );
227  if ( classification & ClearsignedMessage )
228  parts.push_back( QLatin1String("ClearsignedMessage") );
229  if ( classification & CipherText )
230  parts.push_back( QLatin1String("CipherText") );
231  if ( classification & Certificate )
232  parts.push_back( QLatin1String("Certificate" ));
233  if ( classification & ExportedPSM )
234  parts.push_back( QLatin1String("ExportedPSM") );
235  if ( classification & CertificateRequest )
236  parts.push_back( QLatin1String("CertificateRequest") );
237  return parts.join( QLatin1String(", ") );
238 }
239 
240 static QString chopped( QString s, unsigned int n ) {
241  s.chop( n );
242  return s;
243 }
244 
249 QString Kleo::findSignedData( const QString & signatureFileName ) {
250  if ( !mayBeDetachedSignature( signatureFileName ) )
251  return QString();
252  const QString baseName = chopped( signatureFileName, 4 );
253  return QFile::exists( baseName ) ? baseName : QString() ;
254 }
255 
262 QStringList Kleo::findSignatures( const QString & signedDataFileName ) {
263  QStringList result;
264  for ( unsigned int i = 0, end = size( classifications ) ; i < end ; ++i )
265  if ( classifications[i].classification & DetachedSignature ) {
266  const QString candiate = signedDataFileName + QLatin1Char('.') + QLatin1String(classifications[i].extension);
267  if ( QFile::exists( candiate ) )
268  result.push_back( candiate );
269  }
270  return result;
271 }
272 
277 QString Kleo::outputFileName( const QString & inputFileName ) {
278  const QFileInfo fi( inputFileName );
279 
280  if ( qBinaryFind( begin( classifications ), end( classifications ),
281  fi.suffix().toLatin1().constData(),
282  ByExtension<std::less>() ) == end( classifications ) )
283  return inputFileName + QLatin1String(".out");
284  else
285  return chopped( inputFileName, 4 );
286 }
287 
292 const char * Kleo::outputFileExtension( unsigned int classification ) {
293 
294  if ( classification & OpenPGP ) {
295  FileOperationsPreferences filePrefs;
296  if ( filePrefs.usePGPFileExt() ) {
297  return "pgp";
298  }
299  }
300 
301  for ( unsigned int i = 0 ; i < sizeof classifications / sizeof *classifications ; ++i )
302  if ( ( classifications[i].classification & classification ) == classification )
303  return classifications[i].extension;
304  return 0;
305 }
Kleo::outputFileExtension
const char * outputFileExtension(unsigned int classification)
Definition: classify.cpp:292
Kleo::Class::AnySignature
Definition: classify.h:66
Kleo::Class::NoClass
Definition: classify.h:45
Kleo::findSignedData
QString findSignedData(const QString &signatureFileName)
Definition: classify.cpp:249
Kleo::Class::CertificateRevocationList
Definition: classify.h:80
Kleo::Class::DetachedSignature
Definition: classify.h:62
Kleo::Class::ExportedPSM
Definition: classify.h:74
classify.h
Kleo::printableClassification
QString printableClassification(unsigned int classification)
Definition: classify.cpp:213
Kleo::Class::CipherText
Definition: classify.h:68
Kleo::Class::Ascii
Definition: classify.h:56
fileoperationspreferences.h
Kleo::Class::AnyCertStoreType
Definition: classify.h:76
Kleo::Class::OpenPGP
Definition: classify.h:49
Kleo::Class::CMS
Definition: classify.h:48
Kleo::Class::OpaqueSignature
Definition: classify.h:63
Kleo::outputFileName
QString outputFileName(const QString &input)
Definition: classify.cpp:277
Kleo::Class::CertificateRequest
Definition: classify.h:78
Kleo::FileOperationsPreferences
Definition: fileoperationspreferences.h:12
Kleo::Class::Binary
Definition: classify.h:55
Kleo::Class::AnyType
Definition: classify.h:82
Kleo::findSignatures
QStringList findSignatures(const QString &signedDataFileName)
Definition: classify.cpp:262
Kleo::classify
unsigned int classify(const QString &filename)
Definition: classify.cpp:154
Kleo::FileOperationsPreferences::usePGPFileExt
bool usePGPFileExt() const
Get Use pgp as the default extension for generated OpenPGP files.
Definition: fileoperationspreferences.h:31
Kleo::Class::Certificate
Definition: classify.h:73
chopped
static QString chopped(QString s, unsigned int n)
Definition: classify.cpp:240
Kleo::classifyContent
unsigned int classifyContent(const QByteArray &data)
Definition: classify.cpp:183
extension
static const char * extension(bool pgp, bool sign, bool encrypt, bool ascii, bool detached)
Definition: signencryptfilescontroller.cpp:285
Kleo::Class::AnyFormat
Definition: classify.h:58
Kleo::Class::ClearsignedMessage
Definition: classify.h:64
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:56:40 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kleopatra

Skip menu "kleopatra"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal