canl-c-3.0.0/0000755000015500017500000000000013017332513012443 5ustar tomcat6jenkinscanl-c-3.0.0/doc/0000755000015500017500000000000013017332510013205 5ustar tomcat6jenkinscanl-c-3.0.0/doc/src/0000755000015500017500000000000013017332511013775 5ustar tomcat6jenkinscanl-c-3.0.0/doc/src/emi.cls0000644000015500017500000003501213017332510015252 0ustar tomcat6jenkins% emi.cls: % Branched from egee.cls 1.6 % revision 2.0 [based on word template] % Emidio Giorgio -- emidio.giorgio@ct.infn.it % March 31, 2011 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % License % % This work is licensed under Creative Commons Attribution-ShareAlike 3.0. % http://creativecommons.org/licenses/by/3.0/ % You are free: % * to Share to copy, distribute and transmit the work % * to Remix to adapt the work % % Under the following conditions: % * Attribution. You must attribute the work in the manner specified by the author or licensor % (but not in any way that suggests that they endorse you or your use of the work). % * Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting % work only under the same, similar or a compatible license. % % * For any reuse or distribution, you must make clear to others the license terms of this work. % The best way to do this is with a link to this web page : http://creativecommons.org/licenses/by/3.0/ % * Any of the above conditions can be waived if you get permission from the copyright holder. % * Nothing in this license impairs or restricts the author's moral rights. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \NeedsTeXFormat{LaTeX2e} \ProvidesClass{emi}[2011/03/24 EMI LaTeX Class] \typeout{EMI LaTeX class -- 2011/03/24} % %% Interface - example of an option, should we want to use these later. %\newif\ifmonotitle\monotitlefalse %\DeclareOption{mono}{\monotitletrue} \DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}} \ProcessOptions % Inherit! \LoadClass[11pt]{article} % Necessary packages: \RequirePackage{lastpage} \RequirePackage{tabularx} \RequirePackage{pslatex} \RequirePackage{times} \RequirePackage{verbatim} \RequirePackage{geometry} \RequirePackage{url} \usepackage[hang,bf,small]{caption} \usepackage[T1]{fontenc} \usepackage[scaled]{helvet} \usepackage{multirow} \renewcommand*\familydefault{\sfdefault} % % We now define a new \if command to test for PDF being enabled. % It is important because loading graphicx overrides the definition % of \pdfoutput and sets it to true even when PDF is not enabled. % Use \ifpdf instead of \ifx\pdfoutput\undefined hereafter. % \newif\ifpdf \ifx\pdfoutput\undefined \pdffalse % \typeout{PDF _not_ defined} \else \pdfoutput=1 \pdftrue % \typeout{PDF _is_ defined} \fi \ifpdf \usepackage[pdftex, pdfpagemode={UseOutlines},bookmarks=true,bookmarksopen=true, bookmarksopenlevel=0,bookmarksnumbered=true, hypertexnames=false,colorlinks,linkcolor={blue}, citecolor={blue},urlcolor={red}, pdfstartview={FitV}]{hyperref} \else \usepackage[hypertex]{hyperref} \fi \ifpdf \usepackage[pdftex]{graphicx} \pdfcompresslevel 9 \pdfadjustspacing 1 \else \usepackage[dvips]{graphicx} \fi \usepackage{color} \def\footsize{5mm} %% %% PAGE GEOMETRY DEFINITIONS %% % From Template file \geometry{centering,includeheadfoot} %\geometry{a4paper,top=12.5mm,headheight=12.5mm,headsep=5mm,foot=\footsize,footskip=13.3mm,bottom=12.5mm} \geometry{a4paper,top=15.5mm,headheight=20mm,headsep=5mm,foot=\footsize,footskip=13.3mm,bottom=12.5mm} \geometry{right=25mm,left=25mm} % APM -- I don't think these are right, my impression is above is correct %\geometry{a4paper,margin=0.98in,headheight=0.72in} %% %% PAGE COLOUR DEFINITIONS %% % paulm's prefered name ... \def\bibname{References} \setlength{\parindent}{0pt} \setlength{\parskip}{1.4mm plus 0.4mm minus 0.2mm} \def\@defaultfooter{ \def\@oddfoot{\vbox to \footsize {% {\color{blue}\hrule width \textwidth height 1pt depth 0pt}% \vfil %\small\hbox to \textwidth{\ISTNumber% \small\hbox to \textwidth{% %\hfil %\hbox{\colorbox{yellow}{\MakeUppercase{\@Dissemination}}}% \hfil \hbox{\thepage/\pageref{LastPage}}}% }% }% } \def\ps@title{% \@defaultfooter \def\@oddhead{\hbox to \textwidth{\EMILogo\hfil\LargeCESNETLogo}} } \def\ps@headings{% \@defaultfooter \def\@oddhead{\vbox to \headheight{% %\hrule width \textwidth height 1pt\relax \vbox to 0.75\headheight{% \hbox to \textwidth{% \hbox to 0pt{\EMILogo\hss}% \hfil %% \hbox to 8cm{% %% \vbox to 0.75\headheight{% %% \vfil %% \parbox{8cm}{% %% \centering\color{blue}% %% \textbf{\MakeUppercase{\@title}}% %% %\ifx\@Subtitle\@empty\else %% % \par\textbf{\scriptsize\@Subtitle}% %% %\fi %% }% %% \vfil %% }% %% \hss}% \hfil %\hbox to 0pt{\vrule width 1pt height 10pt depth 0pt \hss}% %% {\scriptsize\setlength{\parskip}{0pt}\setlength{\topsep}{0pt}% %% % \vbox to 0.75\headheight{% %% \parbox{4cm}{x% %% \begin{flushright}% %% \textit{Doc. Identifier}:\\ %% \textbf{\@DocIdentifier}\\ %% \vfil %% \textit{Date}: \textbf{\@Date} %% \end{flushright}% %% }% %% % }% %% }% \hbox to 0pt{\hss\vbox to 0.75\headheight{%\hrule \small \parfillskip0pt \leftskip 0pt plus 1fil \parskip0ex \textsc{Title}: \par \textbf{\@title} \textit{Date}: \textbf{\@Date} \vfil %\hrule }}% % \hbox to 4cm{\scriptsize % \vbox to 0.75\headheight{% % \parbox{4cm}{ % \halign{\hfill####\cr % \textit{Doc. Identifier}:\cr % \textbf{\@DocIdentifier}\cr % % \noalign{\vfil} % \textit{Date}: \textbf{\@Date}\cr % }}% % \vfil % }% % }% }% }% %\hrule width \textwidth height 1pt\relax \vfil\vskip 2.5mm\relax {\color{blue}\hrule width \textwidth height 1pt depth 0pt}% }% }% } \pagestyle{headings} \setlength{\captionmargin}{1cm} % image file extensions respective to the output format \ifpdf \DeclareGraphicsExtensions{.jpg,.pdf,.png} \pdfcompresslevel=9 \pdfinfo{ /Title (EMI) } \else \DeclareGraphicsExtensions{.eps} \fi \def\frontboxwidth{11cm}% \definecolor{MyTeal}{rgb}{0,0.46,0.46} \definecolor{blue}{rgb}{0.05,0.26,0.5} %\definecolor{blue}{rgb}{0.1,0.1,0.5} %% egee blue \definecolor{lightgrey}{gray}{0.65} %% %% Define our title page %% \AtBeginDocument{ \pagestyle{title}% \hbox{}% Force top of page \vfill {\centering \fontsize{30}{50}{\textbf{\textsc{\textcolor{blue}{European Middleware Initiative}}}}\\[40mm]% %\Huge{\textbf{\textsc{\textcolor{blue}{European Middleware Initiative}}}}\\[20mm]% \fontsize{22}{28}{\textbf{\textsc{\@title}}}\\[2mm]% %\ifx\@Subtitle\@empty\else % \normalsize\textsf{\@Subtitle}\\[10mm]% %\fi } \vfill \begin{center} \hbox to \textwidth{ \vbox{ {\color{MyTeal}\hrule width \frontboxwidth height 1mm depth 0pt} \hbox to \frontboxwidth{\sf \begin{tabularx}{\frontboxwidth}{l>{\raggedright\arraybackslash}X} \\ Document version: & \textbf{\@DocVersion}\\[3mm] EMI Component Version: & \textbf{\@EMICompVersion}\\[3mm] Date: & \textbf{\@Date}\\[3mm] %Document status: & \textbf{\@DocStatus}\\[3mm] \end{tabularx} } {\color{MyTeal}\hrule width \frontboxwidth height 1mm depth 0pt} %}%centering } } \end{center} %\vfill %{\sf\underline{Abstract}: \@Abstract} \vfill \newpage % end of the first page \pagestyle{headings} \setcounter{tocdepth}{3} } % End of AtBeginningDocument % % EMI style small-capital section titles. % % The numbering is aligned with the WinWord style, % although it is not common in the english typography... % \newcommand{\sectionbreak}{\newpage} %\renewcommand{\thesection}{\arabic{section}.} %\renewcommand{\thesubsection}{\thesection\arabic{subsection}.} %\renewcommand{\thesubsubsection}{\thesubsection\arabic{subsubsection}.} \renewcommand\section{\@startsection {section}{1}{\z@}% {-3.5ex \@plus -1ex \@minus -.2ex}% {2.3ex \@plus.2ex}% {\normalfont\Large\bfseries\sffamily\scshape}} \renewcommand\subsection{\@startsection{subsection}{2}{\z@}% {-3.25ex\@plus -1ex \@minus -.2ex}% {1.5ex \@plus .2ex}% {\normalfont\large\bfseries\sffamily\scshape}} \renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}% {-3.25ex\@plus -1ex \@minus -.2ex}% {1.5ex \@plus .2ex}% {\normalfont\normalsize\bfseries\sffamily\scshape}} %% APM NEED TO REDEFINE section %\titleformat{\section}{\Large\bfseries\sffamily\scshape}{\thesection}{1em}{} %\titlecontents{section} [2em] {\vspace*{4pt}} % {\large \sc \bfseries \contentslabel{2em}} % {\large \sc \bfseries \hspace*{-2em}} % {\large \textbf{\titlerule*[1ex]{.}\contentspage}} [\vspace*{4pt}] %\titleformat{\subsection}{\large\bfseries\sffamily\scshape}{\thesubsection}{1em}{} %\titlecontents{subsection} [5em] {} % {\sc \contentslabel{3em}} % {\sc \hspace*{-3em}} % {\titlerule*[1ex]{.}\contentspage} % % common constants % %\def\ISTNumber{INFSO-RI-508833} \newsavebox{\@EMILogo} %\savebox{\@EMILogo}{\includegraphics[height=0.75\headheight]{EMI_Logo_std}} \savebox{\@EMILogo}{\includegraphics[height=0.95\headheight]{EMI_Logo_std}} \def\EMILogo{\usebox{\@EMILogo}} %\def\LargeEMILogo{\includegraphics[height=\headheight]{EMI_Logo_std}} \def\SmallEMILogo{\includegraphics[height=\headheight]{EMI_Logo_std}} \def\LargeCESNETLogo{\includegraphics[height=\headheight]{cesnet}} % DEL \def\ISTLogo{\includegraphics[height=\headheight]{isi}} % % parameters to be supplied by the author % % EG : subtitle seems no more needed %\def\Subtitle#1{\gdef\@Subtitle{#1}} %\gdef\@Subtitle{\@latex@warning@no@line{No \noexpand\Subtitle given}} %\def\DeliverableId#1{\gdef\@DeliverableId{#1}} %\gdef\@DeliverableId{\@latex@warning@no@line{No \noexpand\DeliverableId given}} \def\DocVersion#1{\gdef\@DocVersion{#1}} \gdef\@DocVersion{\@latex@warning@no@line{No \noexpand\DocVersion given % (e.g. 0.1.2)}} \def\EMICompVersion#1{\gdef\@EMICompVersion{#1}} \gdef\@EMICompVersion{\@latex@warning@no@line{No \noexpand\EMICompVersion given % (e.g. 1.2.3)}} \def\Date#1{\gdef\@Date{#1}} \gdef\@Date{\@latex@warning@no@line{No \noexpand\Date given % (e.g. 01/04/2010)}} %\def\Activity#1{\gdef\@Activity{#1}} %\gdef\@Activity{\@latex@warning@no@line{No \noexpand\Activity given % % (e.g. NA2 Dissemination and Outreach )}} %\def\LeadPartner#1{\gdef\@LeadPartner{#1}} %\gdef\@LeadPartner{\@latex@warning@no@line{No \noexpand\LeadPartner given % % (e.g. CERN, RAL )}} %\def\DocStatus#1{\gdef\@DocStatus{#1}} %\gdef\@DocStatus{\@latex@warning@no@line{No \noexpand\DocStatus given % % (e.g. DRAFT, WORKING, DELIVERED)}} %\def\Dissemination#1{\gdef\@Dissemination{#1}} %\gdef\@Dissemination{\@latex@warning@no@line{No \noexpand\Dissemination given % % (e.g. PUBLIC, INTERNAL, ...)}} \long\def\Abstract#1{\gdef\@Abstract{#1}} \gdef\@Abstract{\@latex@warning@no@line{No \noexpand\Abstract given}} %% %% Define the abstract using an environment abstract % % This will produce the mailto link in the PDF file % % % We use the URL package, which does this nicely. The old way (\HTTP) was % a bit buggy as it had problems with '~'s and '_'s % \urlstyle{sf} \ifpdf \newcommand{\Email}[1]{\href{mailto:#1}{<{#1}>}} \newcommand{\HTTP}[1]{\href{#1}{\url{#1}}} \else \newcommand{\Email}[1]{\textsf{<{#1}>}} \newcommand{\HTTP}[1]{\url{#1}} \fi % % We now redifine \part and \section so that the table of contents % has the sections/parts in upper case. % % Note: need to use \uppercase because \MakeUppercase is not robust % \def\@part[#1]#2{% \ifnum \c@secnumdepth >\m@ne \refstepcounter{part}% \addcontentsline{toc}{part}{\thepart\hspace{1em}\uppercase{#1}}% \else \addcontentsline{toc}{part}{\uppercase{#1}}% \fi {\parindent \z@ \raggedright \interlinepenalty \@M \normalfont \ifnum \c@secnumdepth >\m@ne \Large\bfseries \partname\nobreakspace\thepart \par\nobreak \fi \huge \bfseries #2% \markboth{}{}\par}% \nobreak \vskip 3ex \@afterheading} \def\@sect#1#2#3#4#5#6[#7]#8{% \ifnum #2>\c@secnumdepth \let\@svsec\@empty \else \refstepcounter{#1}% \protected@edef\@svsec{\@seccntformat{#1}\relax}% \fi \@tempskipa #5\relax \ifdim \@tempskipa>\z@ \begingroup #6{% \@hangfrom{\hskip #3\relax\@svsec}% \interlinepenalty \@M #8\@@par}% \endgroup \csname #1mark\endcsname{\uppercase{#7}}% \addcontentsline{toc}{#1}{% \ifnum #2>\c@secnumdepth \else \protect\numberline{\csname the#1\endcsname}% \fi \texorpdfstring{\uppercase{#7}}{#7}}% \else \def\@svsechd{% #6{\hskip #3\relax \@svsec #8}% \csname #1mark\endcsname{\uppercase{#7}}% \addcontentsline{toc}{#1}{% \ifnum #2>\c@secnumdepth \else \protect\numberline{\csname the#1\endcsname}% \fi \texorpdfstring{\uppercase{#7}}{#7}}}% \fi \@xsect{#5}} % \addcontentsline{toc} expands to \contentsline{NAME} % which in turn expands to \l@NAME. So, to specify % the table of contents, we must define \l@chapter, \l@section, % \l@subsection, ... ; to specify the list of figures, we must define % \l@figure; and so on. Most of these can be defined with the % \@dottedtocline command, which produces a contents line with dots % between the title and the page number. It works as follows: % % \@dottedtocline{LEVEL}{INDENT}{NUMWIDTH} % LEVEL : An entry is produced only if LEVEL < or = value of % 'tocdepth' counter. Note, \chapter is level 0, \section % is level 1, etc. % INDENT : The indentation from the outer left margin of the start of % the contents line. % NUMWIDTH : The width of a box in which the section number is to go, % if TITLE includes a \numberline command. % \def\l@part{\@dottedtocline{1}{4em}{2.0em}} \def\l@subsection{\@dottedtocline{2}{1.5em}{2.3em}} \def\l@subsubsection{\@dottedtocline{3}{3.8em}{3.2em}} \def\l@paragraph{\@dottedtocline{4}{7.0em}{4.1em}} \def\l@subparagraph{\@dottedtocline{5}{10em}{5em}} canl-c-3.0.0/doc/src/canl-abstract.tex0000644000015500017500000000174013017332510017236 0ustar tomcat6jenkins% %% Copyright (c) Members of the EGEE Collaboration. 2004-2010. %% See http://www.eu-egee.org/partners for details on the copyright holders. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. % % when changed, update also http://egee.cesnet.cz/en/JRA1/LB/lb.html % (in CVSROOT=:gserver:lindir.ics.muni.cz:/cvs/edg, cvsweb/lb.html) The Developer's Guide explains how to use the canl C (\CANL) API. Main and Credentials API is described in details together with programing examples. canl-c-3.0.0/doc/src/canl-cs-auth-connection.tex0000644000015500017500000002413513017332510021137 0ustar tomcat6jenkins% %% Copyright (c) Members of the EGEE Collaboration. 2004-2010. %% See http://www.eu-egee.org/partners for details on the copyright holders. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. % % -*- mode: latex -*- \section{Client-Server Authenticated Connection} \label{s:cs-auth-conn} For client-server authenticated connection we just use \CANL \textit{Main API} calls. In time of writing this paper \CANL use \textit{openssl -- SSL/TLS and cryptography toolkit}. However, core of the \CANL has been developed to be as independent on any cryptography toolkit as possible, so it may support other libraries in the future. \subsection{Main API Without Direct Calls To Openssl} These are the functions of the \textit{Main API} that do not use \textit{openssl API} calls or variable types directly (as a parameter or in their definitions): \begin{itemize} \item \verb'canl_ctx canl_create_ctx()' This function returns an initialized \textit{authentication context} object \item \verb'void canl_free_ctx(canl_ctx cc)' This function will free the \textit{authentication context}, releasing all associated information. The context must not be used after this call. \begin{itemize} \item param cc -- the \textit{authentication context} to free \end{itemize} \item \textit{canl error code} \verb'canl_create_io_handler(canl_ctx cc, canl_io_handler *io)' This function will create an \textit{i/o handler} from the \textit{authentication context}. This handler shall be passed to all I/O-related functions. \begin{itemize} \item param cc -- the \textit{authentication context} \item param io -- return an initialized \textit{i/o context}, or NULL if it did not succeed \item return -- \CANL error code \end{itemize} \item \verb'canl_err_code canl_io_close(canl_ctx cc, canl_io_handler io)' This function will close an existing connection. The 'io' object may be reused by another connection. It is safe to call this function on an io object which was connected. \begin{itemize} \item param cc -- the \textit{authentication context} \item param io -- the \textit{i/o context} \item return -- \textit{canl error code} \end{itemize} \item \begin{verbatim}canl_err_code canl_io_connect(canl_ctx cc, canl_io_handler io, const char *host, const char *service, int port, gss_OID_set auth_mechs, int flags, struct timeval *timeout)\end{verbatim} This function will try to connect to a server object, doing authentication (if not forbidden) \begin{itemize} \item param cc -- the \textit{authentication context} \item param io -- the \textit{i/o context} \item param host -- the server to which to connect \item param service -- the service on the server - usually NULL \item param port -- the port on which the server is listening \item param auth\_mechs -- authentication mechanism to use \item param flags -- for future usage \item param peer -- if not NULL the canl\_principal will be filled with peer's principal info. Approppriate free funcion should be called if canl\_princ is no longer to be used \item param timeout -- the timeout after which to drop the connect attempt \item return -- \textit{canl error code} \end{itemize} \item \begin{verbatim}canl_err_code canl_io_accept(canl_ctx cc, canl_io_handler io,int fd, struct sockaddr s_addr, int flags,canl_principal *peer, struct timeval *timeout)\end{verbatim} This function will setup a server to accept connections from clients, doing authentication (if not forbidden) \begin{itemize} \item param cc -- the \textit{authentication context} \item param io -- the \textit{i/o context} \item param fd -- file descriptor to use \item param port -- the port on which the server is listening \item param sockaddr -- open socket address \item param flags -- for future usage \item param peer -- if not NULL the canl\_principal will be filled with peer's principal info. Approppriate free funcion should be called if canl\_princ is no longer to be used \item return -- \textit{canl error code} \end{itemize} \item \begin{verbatim}canl_err_code canl_princ_name(canl_ctx cc, const canl_principal cp, char **ret_name)\end{verbatim} Get the peer's principal name in text readable form. \begin{itemize} \item param cc -- the \textit{authentication context} \item param cp -- canl structure to hold peer's principal info. Have to be filled by previous call to canl\_io\_accept or canl\_io\_connect funcions. \item param ret\_name -- text form of the peer's princ. name \item return -- \textit{canl error code} \end{itemize} \item \begin{verbatim}void canl_princ_free(canl_ctx cc, canl_principal cp)\end{verbatim} If canl\_princ structure filled before by some canl io funcion, this function should be called to free the allocated memory. \begin{itemize} \item param cc -- the \textit{authentication context} \item param cp -- canl peer's principal structure \item return -- void \end{itemize} \end{itemize} \subsection{Main API With Direct Calls To Openssl} \begin{itemize} \item \begin{verbatim}canl_err_code canl_ctx_set_ssl_cred(canl_ctx cc, char *cert, char *key, char *proxy, canl_password_callback clb, void *pass)\end{verbatim} This function will set the credential to be associated to the \textit{context}. These credentials will become the default ones for all API calls depending on this \textit{context}. \begin{itemize} \item param cc -- the \textit{authentication context} \item param cert -- the certificate to be set \item param key -- its private key \item param proxy -- the proxy certificate to be set \item param clb -- a callback function which should return the password to the private key, if needed \item param pass -- user specified data that will be passed as is to the callback function. Note that the content of this pointer will not be copied internally, and will be passed directly to the callback. This means that altering the data pointed by it will have a direct effect on the behavior of the function. \item return -- \textit{canl error code} \end{itemize} \item \verb'canl_err_code' \verb'canl_ctx_set_ca_dir(canl_ctx cc, const char *ca_dir)' Set certficate authority directory (openssl ca directory structure) \begin{itemize} \item param cc -- rhe \textit{authentication context} \item param ca\_dir -- the path that will be set. It will not be checked whether this path actually contains the CAs or not \item return -- \textit{canl error code} \end{itemize} \item \verb'canl_err_code' \verb'canl_ctx_set_crl_dir(canl_ctx cc, const char *crl_dir)' \begin{itemize} \item param cc -- the \textit{authentication context} \item param crl\_dir -- the path that will be set. It will not be checked whether this path actually contains the CRLs or not \item return -- \textit{canl error code} \end{itemize} \item \begin{verbatim}canl_err_code canl_ctx_set_ssl_flags(canl_ctx cc, unsigned int flags) \end{verbatim} Set SSL specific flags. This function can turn OCSP check ON. (OFF by default) \begin{itemize} \item param cc -- the \textit{authentication context} \item param flags -- one of the canl\_ctx\_ssl\_flags in canl\_ssl.h (e.g. CANL\_SSL\_OCSP\_VERIFY\_ALL) \item return -- \textit{canl error code} \end{itemize} \end{itemize} \subsection{Secure Client-Server Connection Example} We give an example of a caNl client that use \textit{Main API} with openssl. We do not define variables in this example, unless their type is \CANL defined. For complete sample see {\tt canl\_samples\_server.c} in source package or \href{http://glite.cvs.cern.ch/cgi-bin/glite.cgi/emi.canl.canl-c/examples/canl\_sample\_server.c?revision=HEAD}{canl\_sample\_server.c at CVS} Include nesessary header files: \begin{lstlisting} #include #include \end{lstlisting} Initialize context and set parameters: \begin{lstlisting} canl_ctx my_ctx; canl_io_handler my_io_h = NULL; my_ctx = canl_create_ctx(); err = canl_create_io_handler(my_ctx, &my_io_h); err = canl_ctx_set_ssl_cred(my_ctx, serv_cert, serv_key, NULL, NULL); \end{lstlisting} set user's credentials (X509 auth. mechanism) \begin{lstlisting} if (serv_cert || serv_key || proxy_cert){ err = canl_ctx_set_ssl_cred(my_ctx, serv_cert, serv_key, proxy_cert, NULL, NULL); if (err) { printf("[CLIENT] cannot set certificate or key to context: %s\n", canl_get_error_message(my_ctx)); goto end; } } \end{lstlisting} If using X509 auth. mechanism, we might set \textit{CA directory} and/or \textit{CRL directory} at this place. (If not set, default directories will be used, \ie those in proper env. variables ) . . . Connect to the server, send something then read the response: \begin{lstlisting} err = canl_io_connect(my_ctx, my_io_h, p_server, NULL, port, NULL, 0, &timeout); if (err) { printf("[CLIENT] connection to %s cannot be established: %s\n", p_server, canl_get_error_message(my_ctx)); goto end; } err = canl_io_write (my_ctx, my_io_h, buf, buf_len, &timeout); if (err <= 0) { printf("can't write using ssl: %s\n", canl_get_error_message(my_ctx)); goto end; } err = canl_io_read (my_ctx, my_io_h, buf, sizeof(buf)-1, &timeout); if (err > 0) { buf[err] = '\0'; printf ("[CLIENT] received: %s\n", buf); err = 0; } \end{lstlisting} Free the allocated memory: \begin{lstlisting} if (my_io_h) canl_io_destroy(my_ctx, my_io_h); canl_free_ctx(my_ctx); \end{lstlisting} canl-c-3.0.0/doc/src/canl-introduction.tex0000644000015500017500000001515113017332510020155 0ustar tomcat6jenkins% %% Copyright (c) Members of the EGEE Collaboration. 2004-2010. %% See http://www.eu-egee.org/partners for details on the copyright holders. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. % % -*- mode: latex -*- \section{Introduction} This document serves as a developer's guide and could be seen as an API reference too, even though comments in the header files may give the reader better insights into that matter. Common Authentication Library (\CANL for short) was designed to provide common security layer support in grid applications. It is largely based on existing code (VOMS, LB). Its simple API can be devided by functionality into two parts: \begin{itemize} \item \textit{\CANL Main API} is used to establish (secure) client-server connection with one or both sides authenticated, send or receive data. As will be described in~\ref{s:cs-auth-conn}, most of the \textit{Main API} is not directly dependent on some chosen cryptography toolkit (SSL implementation). It is also internally plugin-based and therefore other security mechanisms support can be added in future. \item \textit{\CANL Certificate API} allows certificate and proxy management \eg proxy creation, signing, etc. We may think of \textit{Certificate API} as the second level of \textit{Main API} \end{itemize} Currently there is EMI Product Team assigned to \CANL development with three subgroups for each language binding. \subsection{Language Bindings} \CANL is developed in C language as well as C++ and Java language bindings, however this document covers only the C interface. \subsection{Getting and Building Library} TODO package names external dependencies: \begin{itemize} \item c-ares -- asynchronous resolver library \item openssl -- cryptography and SSL/TLS toolkit \end{itemize} \subsection{General Guidelines} \marginpar{Naming conventions}% All function names are prefixed with \verb'canl_' \marginpar{Input and output arguments}% All structures and objects passed in output of functions (even though pointers are used as a help) are dynamically allocated, so proper functions to free the allocated memory has to be called. e.g. \verb'canl_free_ctx()' deallocates members of the structure \verb'canl_ctx'. \marginpar{Opaque types}% Almost all types used in caNl are \textit{Opaque types} -- i.e. their structure is not exposed to users. To use and/or modify these structures API call has to be used. Example of opaque type is {\tt canl\_ctx}. \marginpar{Return values}% The return type of most of the API functions is {\tt canl\_err\_code} which in most cases can be interpreted as int. Unless specified otherwise, zero return value means success, non-zero failure. Standard error codes from {\tt errno.h} are used as much as possible. Few API functions return {\tt char *}. In such a~case {\tt NULL} indicates an error, non-null value means success. \subsection{Context and Parameter Settings} \label{s:context} All the API functions use a \emph{context} parameter of type {\tt canl\_ctx} to maintain state information like error message and code. Some API functions also use an \emph{io context} of type {\tt canl\_io\_handler} which keeps information about each particular connection (\eg socket number, oid, SSL context).The caller can create as many contexts as needed, all of them will be independent. When calling \verb'canl_create_ctx()' or \verb'canl_create_io_handler()' all members of the objects are initialized with default values which are often NULL for pointer type and 0 in case of int and similar types. \section{\CANL Components} \label{s:common} \subsection{Header Files} Header files for the common structures and functions are summarized in table~\ref{t:cheaders}. \begin{table}[h] \begin{tabularx}{\textwidth}{>{\tt}lX} canl.h & Definition of context objects and \textit{Main API} common functions declarations. \\ canl\_ssl.h & Declaration of functions that use X509 certificates based authentication mechanism (pretty much dependent on openssl library functions).\\ canl\_cred.h & Definition of context objects of the \textit{Certificate API} and functions declarations.\\ \end{tabularx} \caption{Header files} \label{t:cheaders} \end{table} \subsection{Building Client Programs} The easiest way to build programs using \CANL in C is to use GNU's libtool to take care of all the dependencies: \begin{verbatim} libtool --mode=compile gcc -c example1.c -D_GNU_SOURCE libtool --mode=link gcc -o example1 example1.o -lcanl_c \end{verbatim} \subsection{Context} \label{s:canl_ctx} \marginpar{Context initialization}% There are two opaque data structures representing caNl \textit{Main API} context: {\tt canl\_ctx} and {\tt canl\_io\_handler} (see section~\ref{s:context}). {\tt canl\_ctx} must be initialized before any caNl API call. {\tt canl\_io\_handler} must be initialized before calling function representing io operation (\eg \verb'canl_io_connect()') and after {\tt canl\_ctx} initialization. \begin{lstlisting} #include #include canl_io_handler my_io_h = NULL; canl_ctx my_ctx; my_ctx = canl_create_ctx(); err = canl_create_io_handler(my_ctx, &my_io_h); \end{lstlisting} There is one opaque data structure representing \CANL \textit{Certificate API} context: {\tt canl\_cred}. It must only be initialized before function calls that use this context as a parameter. \begin{lstlisting} #include #include canl_ctx ctx; canl_cred c_cred; ctx = canl_create_ctx(); canl_cred_new(ctx, &c_cred); \end{lstlisting} \marginpar{Obtaining error description}% {\tt canl\_ctx} stores details of all errors which has occurred since context initialization, in human readable format. To obtain it use \verb'canl_get_error_message()': \begin{lstlisting} printf("%s\n", canl_get_error_message(my_ctx)); \end{lstlisting} \marginpar{Context deallocation}% It is recommended to free the memory allocated to each context if they are not needed anymore, in first case {\tt canl\_io\_handler} , then {\tt canl\_ctx} in case of the \textit{Main API}: \begin{lstlisting} if (my_io_h) canl_io_destroy(my_ctx, my_io_h); canl_free_ctx(my_ctx); \end{lstlisting} as for the Certificate API: \begin{lstlisting} canl_cred_free(ctx, c_cred); \end{lstlisting} canl-c-3.0.0/doc/src/canl-proxy-cert.tex0000644000015500017500000002502313017332511017550 0ustar tomcat6jenkins% %% Copyright (c) Members of the EGEE Collaboration. 2004-2010. %% See http://www.eu-egee.org/partners for details on the copyright holders. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. % % -*- mode: latex -*- \section{Credentials Handling} \label{s:cs-auth-conn} If we want to create new proxy certificate or \eg delegate credentials, we can use \CANL \textit{Certificate API}. This part of API uses X509 authentication mechanism (openssl library now) \subsection{Certificate API} These are the functions of the \textit{Certificate API}, all of them use {\tt canl\_ctx} as first parameter and {\tt canl\_err\_code} as a return value, so we do not include them in following description: \begin{itemize} \item \begin{verbatim} canl_err_code canl_cred_new(canl_ctx, canl_cred *cred)\end{verbatim} This function creates new structure (context) to hold credentials. \begin{itemize} \item param cred -- a new object will be returned to this pointer after success \end{itemize} \item \begin{verbatim} canl_err_code canl_cred_free(canl_ctx, canl_cred *cred)\end{verbatim} This function will free the credentials context, releasing all associated information. The context must not be used after this call. \begin{itemize} \item param cred -- the credentials context to free \end{itemize} \item \begin{verbatim} canl_err_code canl_ctx_set_cred(canl_ctx, canl_cred cred)\end{verbatim} This one sets users credentials to \CANL context. \begin{itemize} \item param cred -- credentials to set to global \CANL context \end{itemize} \item \begin{verbatim} canl_err_code canl_cred_load_priv_key_file(canl_ctx, canl_cred cred, const char * file, canl_password_callback clb, void *pass)\end{verbatim} Load private key from specified file into the credentials context. \begin{itemize} \item param cred -- credentials which save private key to \item param file -- the file to load private key from \item param clb -- the callback function which should return the password to the private key, if needed. \item param pass -- User specified data that will be passed as is to the callback function \end{itemize} \item \verb'canl_cred_load_chain(canl_ctx, canl_cred cred,' \verb' STACK_OF(X509) *chain)' This function loads the certificate chain out of an openssl structure. The chain usually consist of a proxy certificate and certificates forming a chain of trust. \begin{itemize} \item param cred -- the credentials context to set chain to \item param chain -- the openssl structure to load certificate chain from. \end{itemize} \item \verb'canl_cred_load_chain_file(canl_ctx, canl_cred cred,' \verb' const char * file)' This function loads the certificate chain out of a file. The chain usually consists of a proxy certificate and certificates forming a chain of trust. \begin{itemize} \item param cred -- credentials which save certificate chain to \item param file -- the file to load certificate chain from \end{itemize} \item \begin{verbatim} canl_err_code canl_cred_load_cert(canl_ctx, canl_cred cred, X509 *cert)\end{verbatim} This function loads user certificate out of an openssl structure \begin{itemize} \item param cred -- the credentials context to set certificate to \item param cert -- the openssl structure to load certificate from \end{itemize} \item \begin{verbatim} canl_err_code canl_cred_load_cert_file(canl_ctx, canl_cred cred, const char *file)\end{verbatim} This function loads user certificate out of a file. \begin{itemize} \item param cred -- credentials which save certificate to \item param file -- the file to load certificate from \end{itemize} \item \begin{verbatim} canl_err_code canl_cred_set_lifetime(canl_ctx, canl_cred cred, const long lt)\end{verbatim} This function sets the lifetime for a certificate which is going to be created \begin{itemize} \item param cred -- the credentials context \item param lt -- the lifetime in seconds \end{itemize} \item \begin{verbatim} canl_err_code canl_cred_set_extension(canl_ctx, canl_cred cred, X509_EXTENSION *ext)\end{verbatim} This function sets the certificate extension to for the certificate which is going to be created \begin{itemize} \item param cred -- the credentials context \item param ext -- the openssl structure holding X509 certificate extension \end{itemize} \item \begin{verbatim} canl_err_code canl_cred_set_cert_type(canl_ctx, canl_cred cred, const enum canl_cert_type type)\end{verbatim} This function sets the certificate type to for the certificate which is going to be created. \begin{itemize} \item param cred -- the credentials context \item param type -- a canl\_cert\_type in canl\_cred.h \end{itemize} \item \begin{verbatim} canl_err_code canl_cred_sign_proxy(canl_ctx, canl_cred signer, canl_cred proxy)\end{verbatim} This function makes new proxy certificate based on information in \textit{proxy} parameter. The new certificate is signed with private key saved in \textit{signer}. A new certificate chain is saved into \textit{proxy}. \begin{itemize} \item param signer -- the credentials context which holds signer's certificate and key. \item param proxy -- the credentials context with a certificate signing request, public key and user certificate; optionally lifetime, certificate type and extensions. \end{itemize} \item \begin{verbatim} canl_err_code canl_cred_save_proxyfile(canl_ctx, canl_cred cred, const char * file)\end{verbatim} This function saves proxy certificate into a file. \begin{itemize} \item param cred -- the credentials context with certificate to save \item param file -- save the certificate into \end{itemize} \item \begin{verbatim} canl_err_code canl_cred_save_cert(canl_ctx, canl_cred cred, X509 **to)\end{verbatim} This function saves certificate into openssl object of type \textit{X509} \begin{itemize} \item param cred -- the credentials context with certificate to save \item param to -- save the certificate into \end{itemize} \item \begin{verbatim} canl_err_code canl_cred_save_chain(canl_ctx, canl_cred cred, STACK_OF(X509) **to)\end{verbatim} This function saves certificate chain of trust with proxy certificate into openssl object of type \textit{STACK\_OF(X509)}. \begin{itemize} \item param cred -- the credentials context with certificate chain to save \item param to -- save the certificate into \end{itemize} \item \begin{verbatim} canl_err_code canl_cred_new_req(canl_ctx, canl_cred cred, unsigned int bits)\end{verbatim} This function creates a new certificate signing request after a new key pair is generated. \begin{itemize} \item param cred -- the credentials context, certificate signing request is saved there \item param bits -- the key length \end{itemize} \item \begin{verbatim} canl_err_code canl_cred_save_req(canl_ctx, canl_cred cred, X509_REQ **to)\end{verbatim} This function saves certificate signing request into openssl object of type \textit{X509\_REQ}. \begin{itemize} \item param cred -- the credentials context with certificate request \item param to -- save the certificate request into \end{itemize} \item \begin{verbatim} canl_err_code canl_cred_save_req(canl_ctx, canl_cred cred, X509_REQ **to)\end{verbatim} This function loads certificate signing request from openssl object of type \textit{X509\_REQ} into \CANL certificate context \begin{itemize} \item param cred -- the credentials context, the cert. request will be stored there \item param to -- load the certificate request from \end{itemize} \item \begin{verbatim} canl_err_code canl_verify_chain(canl_ctx ctx, X509 *ucert, STACK_OF(X509) *cert_chain, char *cadir)\end{verbatim} Verify the certificate chain, openssl verification, CRL, OCSP, signing policies etc... \begin{itemize} \item param ucert -- user certificate \item param cert\_chain -- certificate chain to verify \item param cadir -- CA certificate directory \end{itemize} \item \begin{verbatim} canl_err_code canl_verify_chain_wo_ossl(canl_ctx ctx, char *cadir, X509_STORE_CTX *store_ctx)\end{verbatim} Verify certificate chain, SKIP openssl verif. part; Check CRL, OCSP (if on), signing policies etc. (This is special case usage of caNl, not recommended to use unless you really know what you are doing) \begin{itemize} \item param cadir -- CA certificate directory \item param store\_ctx -- openssl store context structure fed with certificates to verify \end{itemize} \end{itemize} \subsection{Make New Proxy Certificate -- Example} We give an example of a proxy certificate creation. We do not define variables in this example, unless their type is \CANL defined. We do not check return values in most cases as well. For complete sample see example sources. Include necessary header files: \begin{lstlisting} #include #include \end{lstlisting} \CANL context variables \begin{lstlisting} canl_cred signer = NULL; canl_cred proxy = NULL; canl_ctx ctx = NULL; \end{lstlisting} Initialize context: \begin{lstlisting} ctx = canl_create_ctx(); ret = canl_cred_new(ctx, &proxy); \end{lstlisting} Create a certificate request with a new key-pair. \begin{lstlisting} ret = canl_cred_new_req(ctx, proxy, bits); \end{lstlisting} (Optional) Set cert. creation parameters \begin{lstlisting} ret = canl_cred_set_lifetime(ctx, proxy, lifetime); ret = canl_cred_set_cert_type(ctx, proxy, CANL_RFC); \end{lstlisting} Load the signing credentials \begin{lstlisting} ret = canl_cred_new(ctx, &signer); ret = canl_cred_load_cert_file(ctx, signer, user_cert); ret = canl_cred_load_priv_key_file(ctx, signer, user_key, NULL, NULL); \end{lstlisting} Create the new proxy certificate \begin{lstlisting} ret = canl_cred_sign_proxy(ctx, signer, proxy); \end{lstlisting} And store it in a file \begin{lstlisting} ret = canl_cred_save_proxyfile(ctx, proxy, output); \end{lstlisting} \begin{lstlisting} if (signer) canl_cred_free(ctx, signer); if (proxy) canl_cred_free(ctx, proxy); if (ctx) canl_free_ctx(ctx); \end{lstlisting} canl-c-3.0.0/doc/src/canl.tex0000644000015500017500000000514113017332511015435 0ustar tomcat6jenkins% %% Copyright (c) Members of the EGEE Collaboration. 2004-2010. %% See http://www.eu-egee.org/partners for details on the copyright holders. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. % % -*- mode: latex -*- \documentclass{emi} \def\insideDG{} \input{definitions} %\def\LB{LB\xspace} \title{Common Authentication Library -- Developer's Guide} %\Subtitle{Developer's Guide} \author{CESNET caNl team} %\DocIdentifier{glite-lb-doc-dg-\version} %\DeliverableId{} \Date{\today} %\Activity{JRA1: Middleware Engineering} %\DocStatus{DRAFT} \DocVersion{\version} %\Dissemination{PUBLIC} %\DocumentLink{\url{http://egee.cesnet.cz/cvsweb/LB/LBDG.pdf}} \Abstract{\input{canl-abstract}} \EMICompVersion{2.x} \usepackage{listings} \usepackage{amsmath} \usepackage{hyperref} %\setlength{\marginparwidth}{1.2in} \let\oldmarginpar\marginpar \renewcommand\marginpar[1]{\-\oldmarginpar[\raggedleft\footnotesize #1]% {\raggedright\footnotesize #1}} \begin{document} \reversemarginpar \lstset{language=C,basicstyle=\footnotesize,numbers=none,breaklines=true} %\lstset{title={\bf File: }\lstname} \lstset{rangeprefix=/*,rangesuffix=*/,includerangemarker=false} \lstset{escapeinside={//*}{\^^M}} % ----- BEGIN COPY ----- % copied from org.glite.lb.client/doc/api/api.tex in hope it could be useful %\parindent=0pt %\parskip=\smallskipamount \makeatletter \def\jobid{\textit{JobId}\xspace} \def\@tti[#1]{\item[{\normalfont\texttt{#1}}]\catcode`\_=8} \def\tti{\catcode`\_=11\noexpand\@tti} \newlength{\tw} \def\synopsis{\catcode`\_=11\noexpand\@synopsis} \def\@synopsis#1#2{ \tw=\linewidth \advance\tw-2em \texttt{#1(}\\ \strut\hskip2em\begin{tabularx}\tw{>{\begingroup\tt}l<{\endgroup}lX} #2 \end{tabularx}\\ \texttt) \catcode`\_=8 } \def\Synopsis{\subsubsection*{Synopsis}} \def\Description{\subsubsection*{Description}} \def\Return{\subsubsection*{Return values}} % ----- END COPY ----- %\input{frontmatter} \input{funding} \input{copyright} \tableofcontents \newpage \input{canl-introduction} \newpage \input{canl-cs-auth-connection} \newpage \input{canl-proxy-cert} %\newpage %\bibliographystyle{unsrt} %\bibliography{lbjp} \end{document} canl-c-3.0.0/doc/src/copyright.tex0000644000015500017500000000237013017332511016531 0ustar tomcat6jenkins% %% Copyright (c) EMI. 2010-2013. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. ~ \vfill{} {\bf Copyright} \copyright\ {\bf EMI. 2010-2013. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at \begin{center} \href{http://www.apache.org/licenses/LICENSE-2.0}{http://www.apache.org/licenses/LICENSE-2.0} \end{center} Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. } \clearpage canl-c-3.0.0/doc/src/definitions.tex0000644000015500017500000000307313017332511017035 0ustar tomcat6jenkins% %% Copyright (c) Members of the EGEE Collaboration. 2004-2010. %% See http://www.eu-egee.org/partners for details on the copyright holders. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. % % external packages \usepackage{xspace} \usepackage{ifthen} \usepackage{listings} % useful definitions \def\CANL{caNl\xspace} \newcommand\LBver[1]{\textit{\LB version {#1}}} \def\JP{JP\xspace} %\def\eg{e.\,g.} \def\eg{for example\xspace} \def\Eg{For example\xspace} %\def\ie{i.\,e.} \def\ie{that is\xspace} \def\Ie{That is\xspace} \def\wrt{with respect to\xspace} \def\Dash{---\penalty-1000} \def\req{\noindent\textbf{Prerequisities:}} \def\how{\noindent\textbf{How to run:}} \def\what{\noindent\textbf{What to test:}} \def\result{\noindent\textbf{Expected result:}} \def\note{\noindent\textbf{Note:}} \def\path#1{{\normalfont\textsf{#1}}} \def\code#1{\texttt{#1}} \def\ctblb#1{\code{org.glite.testsuites.ctb/LB/tests/#1}} \long\def\TODO#1{\par\noindent\textbf{TODO:} {\sl#1}\par} \long\def\ludek#1{} \hyphenation{plug-in} \newcommand{\email}[1]{\href{mailto:#1}{#1}} \input{ver.tex} canl-c-3.0.0/doc/src/funding.tex0000644000015500017500000000016413017332511016152 0ustar tomcat6jenkinsThis work is co-funded by the European Commission as part of the EMI project under Grant Agreement INFSO-RI-261611. canl-c-3.0.0/doc/src/images/0000755000015500017500000000000013017332511015242 5ustar tomcat6jenkinscanl-c-3.0.0/doc/src/images/EMI_Logo_std.pdf0000644000015500017500000010371413017332511020207 0ustar tomcat6jenkins%PDF-1.4 %쏢 6 0 obj <> stream x]I%) \4<ЋV/j!Tt~όglR*!@Y|9Ly9?_~{')G~sȑ%>|nHg$C|:/*Soj!k'9|LzT-\_fh,)÷;t"kYwG(ms)|7IZQ D9alZncDY+(8ǭU)E2t*79&ܦۑBr){z:qU.bVK(N, @*>XE(G}< pq9˪) :: |C>߆Bv8*m~@B"F9j .Wc#VIIr0R oԑMxz;rmB[ڄ#Zw$ZۤIWG6qIƈQTS&lvrH2>ؤҪjN,6! e ϝf +/ W<9OC2ʏ*GԦӷ@poH>pYx׎@ZYq+^{?{=q}{\~`+t8pP&`'m?ohՓpP. hGN\Uxǫ>^?WW} >(>PF WBTS>*G[*(5CګxXhV3 n!E+Dk_AXpbYev.FGR:@AY}@h;Z{D>8Rl3ƌ#4!(#>*JZ7Y!D(Cjx#j0E4#hK*%ɛj nTeR!`Y_+c9uנ"7Y 3&itNw DSeGEGk m2f*+83TA :B!SZ4@Ε[WjP΁7g:ʴ(v0@z,ݧ61x7/K5"/NpǒF Nƀd`,~ioA.w/ ȧʝ$mDy5$v&+ݵXHrGojȜą{O-O-O-O-sLgE{#>t JR:7^l0T|\;.80ИJ'F7$+zP_gl1JhxσhMtbnv<_CP"IvߊWR!У4=|+;r\BFߩ߽;ϏY;NYOZoI -b;X'!IÁQ+m TJkH5胜X3/PKQ)Oy2l*gyAo C4'1xU}&.)柪4 n'*LIw`9M*:{&lH\jPq}h\y̠J[_$,/HD-Da>Fmb cD OD OD OD Op~ӓ'y'y'y'y˶m6[z= FPy7 9o!]Zw$3` pBZws#s]_9nf<+g Y2aD Mu$ԟ"NmM0 /B`9H&X=XyF 3P h<~>tAl<إ՘2]td)"J= !\H% x`1obƠ}ҁe.#G.hŇa 3DVQ˪hjpߢQ " Tѻ7=`k`VDK o)CRex㑏>U3[Zl9axkݎZ*2M+Vu -vwZ݌h,ћ 5l IUٕbklȟ\'A5Vrޅ XrR0 6ס!fr`l_< gӋZʠ`.$GBND]\I I,Y<`48ɹ9ߑ/b_jVL qx/mQ0$o kqԺ#kqԺ#kqԺ#kjcw+ ?܍љ7X(T.un OֆR}ّK-RR1UVx%[ǧg4^2]P!otHJ})q6)2`Gu%چ detzG0nvFLqXWrәMwt֘x`\ ^$ 9:`@xgChۑKq<0Ms0b:Fz[7 sJPeۦSFM܀/BNS-I0aw?c@b|G9e5&B_0A@OX@b=;Z;D{kQLG 3sv̄)= aa‘֠p Aҏ{+~V]l+O+QZ1T7B (vS[n~]Q䃘!Æf(5)ٽrmvLqfy)bKdH{x0&V۔bEFLub}T}ıyW]`wJ!Lwt^gsƊ]ǦD ڃ|܅4훔[H#ۍ-%ڑM8vDo/q幊,iawM ]qN,qGje^XWU.)wÒ^Б)LsCbe rP|`HPs]d,Y=!*~' &>[&My,uv, 91m27Bud ,[7jqX[Gj%syyD_tt%_Ml ޑt 0:mse+/B\F;ZwdZuGWǟc)#|iRY˖|} ncGwײ;&y[0IsED75a] ]%9iWwQg Ug6r8 RXQ"KvbJۦ\RZ`aО/~̹vFE4&iYap4Q^iViVDiV[]iVYV(YV- TnXF i\8ۙ4ZUikXwxIV‡xdIVRgq6~ɀd dq%Ya 2pm&Y)]=ФFeɋr›{ 7|R {$%ahMWlW1cyGh׺#U uGh׺#;lw+u1ƴ=/xӦQؚuWAlrGڎպFKW.Nvl6SB+_e4ϡ;Ly{sz;osz_y͂{n֤M0'0u{=rrJlΧluFw䋩'Sv;^9݁7sG"G6pGNQѼ8[3|շ-'\N{f'嘛)01{pJLGQNtN](bv퇜ig"_B^#Dd 7dFg~^}G-{̝f;G\ `auWRk~ ѧG{i  MתGǭػ%im|ӹ}qW+u zHJjgM_ aRzendstream endobj 7 0 obj 5493 endobj 5 0 obj <> /Contents 6 0 R >> endobj 3 0 obj << /Type /Pages /Kids [ 5 0 R ] /Count 1 >> endobj 1 0 obj <> endobj 8 0 obj <>endobj 9 0 obj [/Pattern] endobj 15 0 obj <>endobj 4 0 obj <>stream xJ5v?Oq]k p!,=@ =^Aŏtߚ ޛ($d\+C[/oe=RCtN}Nr ?oyo6[?=J83k~,_~>~5k?e{Po$'DiưG?Q_o?4~=/2,1Z|tK{7?ٜL尔}Qܯ_~~Ai <%Mڬ[f ~96Z CS&)g?SvzY?%} z/7ro|eǁ|h'~Ynu^Ϸ]m?n,dKw._1}_TdX_6ze &8aסb 8]R=#}˼jG7׃1D{Cǜ .…s˽]^xy/s? ~a c͹]cqig߂ty':!xB uk?7̀>^\˽;dNf \3z!pzܸ,i\ dC F %^=ԷSdТGUf4cxNv654&2XO-!jXpW6,DŽȽ-0z{5@lIpj4Cp$ 2%S6dde1(JXĞ}{ &v%Mo_s䧺)< Qe9!Uð"7Q;CVg!92n2Ss!-I[uo%}HxOaߠ^GV)SP$G+%T]U/O`+; EEvPy|0+co˨c_ {J`B"_P@IYXr i7L>dl߹颵fbiO(?!ƛs`ې2۸lN;;µs1Xφ-f#1ŦmmP_H"Ơ1{x:3d.Ȝ,׵`X:Ql"2qmh?Jr/ p{C{@2F2nWdR o> eD4y|8\֢UAHMT2lx\֮$sC $Ekx#=s}zBc7UQGb 1cb&)"=\ɪ^/Rkq`i/4uũ6ꑼ(Q(([sc).Nt!7v(ٴ-r:f7 ;/ >\2bfsHC9Fz,#L_dqF,Y|k% %;N:_TPAOTb` ^Qg 'Ka2ܖ03k_߬hHL< G"%G{V!*z9ʪ]Pζذ!#m8euRzj3k^.r̓ͣE 5P' $m-Ktz ߉r̥=gk0Ehk^oxɭȝܭ5Ke?'2ʍB0z<=< wjuY.F:v\JSzѻw*EM? veiXR>ɓN$CJpl@6LoeհwkL^dC BQCk2ҖQ!Id,_n[^)֧[Qw;NTBsOj=ֶ5k,j 큢pJ bWRJJhMN\Yz1gE/f5m)w *6<zuF#y61Ĝ)o7|WIMx n&w52+' 5R};lhXKJS.vGu 0o}UXJ^3a*2>ʊٸ |fc #e}GʼA!u֟# S9؇ZIx>fB6P[ B0{lD%*r,Dul HyI."L=LGӲ$=l&r CMRgm&ߺ /x07?)K ! -zDnaTO4:gs*:^ :+{L|'@R!\ctk YbSz%=NU Ǡ61 Phsf N {}@V01]9UfԀ'oy;eyE5~<4fc\ hubp1:I:fvSk}fN5 clxLuU 1M9QBQj#ݶ_v_^fAdKڽ&gKޢÜ{+-h s\2j`E/ޟ+z־9 BLGݦ6/%tq^CG./b9XH | wC/>e2 C Ϗ%9-GQӰCxկ2]/ArQ=CG5/4Ǜ]eO^2E zW:ɧTM;OꜼig^Zhu4{) /O5{ {ڼ8 nYx3Sz%,ǞG׸꿲q;|ĎӃ|P*suG=: EgsXW<@z"rVOxė&Öؐؓ:KZ25` `hmc tb*)T񛗉a8."m@СbaEd` OY^=#ΰ,]eȶ- LZ-6eh τAZ[lH=\$ y7(΢wbz&UxJlMQ&f2wFZ ,@#[ Zt?E%VE YY-y\PGb~ u( `*}u *( |yێ@;tP.̹C(+ !}諑u3%d_R(;XsBe{K*w #.ab_}3AC'Fyr Gr υ)/Jo&x P?Lx hvWB Do}:"Q+ky/K͆_$YK,xﻧ٦AY/' | L&r&o~3ϝC DatB«ڷ‰^3G Eu4:Jaoh>SR@<Io&JaӽHQwv% 6:ML^'XF)VRxNpI=TFɚz~L⃖4h@h4uHS)zdBIPN|Y~._:7BIJl'QhXҳ7pV:%MAÑJ,T]AfC|<72CGdI}f^˴8RhY~Яrmy_WSfy1@:3Le&4f6Ȱ lrW򇗵6aG9}laG~Z#bw!T?gU 3='jT0++d4J_An>`,P umV7bۺȬCrc:~PQm'2t{pSSS̆Ӎjg\<^i/- _:+]3͛zvd } Ztu=)W+qdAJ^zҦu$4έ\M1,*RY,ӗ,E'ԕ]-jɹ=0lJZ4.|`yb2nh!|٬fon |3:Y@8PY B,ANOf5%zK| l#ndv}55(u2 " /b ?S N/H?6;f3!S%Fh&s4l,Xeewhq#ؤ/p`9IlեdԨ8H6MEdePظz|ya2ӋfN,SW 0LČ0K,B[T樛(/חB}^&RW#Prb _Z nפ8|ߐm]m<^e\M[ 3)u`-Nt7I`jK'+{j@(pOv/Βb\#^׳8;y|[R4{g1X7*2ױ=_KV\] o.2/.B-~Mf37ՏI?`s'3`GIA?A=}j () Vo|;.&,rnހkJအvɟ,t|PdԹ4ub| >3dr"o0Cfi ,2!iyGc6?Qi៨ 4Zd)4?NaY/HV=t<.3N3d[E)604W-OpQ7>,6zcHAU; Cm/2ji*쬆FZ󧥋 `N-U"Cj>קg<`V Ҍ$o, w3+6mPnm_vQvoIRu)6RIP?sT5PwOv Ӣd]V 73xo!oHt}Vy1o,7En لU5Lբ^"AprE}kS)7oZqx-_Wl_EwՀA$1-*"jv 6l[>3ޅ+%hvanO6M.[AhHWة+_3n3#y54BQVZwO߯߃C5i)=mk6UX2kw &#M p! s5kG_%b Bb&$Y:]KiIB ndfXlč䎙5Ht0U7dc Q?(pH-32­b>DP0a"h*lp@Awkj;6L ߾H [;?;`Xmlޫ8 CK^vX-yyܭJp W rrQ(&lgXĥ2./P%;w՗J3ҸC6ƠȮ†H~)E(TAka'#{(6I)(2tatGs:36XQ _0S㕾nSzNic[ssk8z~H7HT<YzݻoK^!tP Wooنt\_׾q_)iŠ*;1}." mWo -,qM_w?SlO.rxR*4e#d|N% ӓESuм<%a@P!rMoR1Zˡdbӕ# v*z^r8חJ5qJF^)m2$zd>~fo|鷲d7xQld T e؂5$PqF7d(Ka]W$~NŒ}U@{=Qc-e=F7׽rDK>h*do]۳a#фa/yr,DCJk(Y}fIݿmA>w}8ϫR;Y9}aP<ܕ1UӀQ:4J_χ/%=hT xh:v '܆n[ShF5FEF J<>L#X3Otj^BP|0s>7[2Hwq/sukx,s"Cex\d }1nIWB JAjBCE1^Icl`l\bY ~lѯӉc9̾Xd~z.miKG 4'hȂ| j7L53o7z$˼jiwd5@@{)+t Npx>$m)xc3tb`^01}`h>8sOߥY4jjҒ#블Jg2ggΔjiJ7SV> ~eJBJfQo*6f}O;" 'ҲL㉫ZvyymL B8 {~ByĴ^ }62mr"wjBԺ9WkOTDž! U<(oY9[INՒQ8ݪMGSGXumȬp~Ҝ 4wjXU 2 ]^7PcӀo+̾Ef5g<߾C1AE˶[|CiR.b}dpLD\/ebD%UU'7iպlC8N!j+5(#1 A9D*[O4{q`hhn05pw*c}}1LTfRz>~,# 7NtՖ]iM@>|x + >y`CΎF9Oh> N_MURNSYc7䒬 V1jjQr XǛ4GU6a/ї,Ӥqլ`?ӡch ŗ9||RqsD/EbC|wgSL/s J"iQ°&D4}lzazB4DS^qIwjB7g ~D:g&Q#yOŜn..t7w:O2b\`+w`R}.3羨.)=REzc-4O!Hw(̪Zm5)T4a{ ߭LVvю !+k*sBOND:']%/[G}YQcx]s4Բ$׌9o/)cQ(,.՛nш_xSTf1A9dê7 /k@^ȦWk{~0JUHS1rw<+kwvR5mHodbRkΓs$:d%lH!o`r ȩ $4&7t485%`$"y['{g籵y U{s0 #lC3HEVO2.>Q6K62zkhҫHɝbN$ $Zf~ K%sg~fNV7AZEE:$ڂϠ;uQv/ry-kgYȦHMk z^oF+*z =Ly$A:B@]Dtxe0OrF"AM+D*}~|A剘]Qn^]*,$SJ%x^s Vij]=, w,.4UE_QMD-1:8/2a)3d/Y0=ջEYا;whHO6R+ hztfNipyݔ^AEJa7wC/ˆ ȂOk(dVE' =ڝ59lƗ̪] ܢ$3=KF[@- _g8JVn׽i!c./ RU5;N.#YuFM^r g$"l~Kt+ :NV1\!Of L]5d&g,v\%ZcL~[汬4;A?+oZ4EqkGiıݟAD xR;zJtFU IQXԤnSEpyeFh> a\K %SX`R7fߺ4]|M9q]Bp-lL픷idďF`KV)|["{VNR)OrڛS Sl |:@x"F>ݺVR|=R-<2HO}oAe uV!16]>K7r<$f 1 |;=rQoNzV)~w ȰSÒF?#U(m}t7*cN;B6YW&hoTF00 ?2fBAg(3R)9KA<ѻKDSDŽ:l|FK6({t {_u͐X[2ԏg2HXk Ksi9#xUKBav{nۡ1(vZ+$}w̶"N8=819"FkI9qIW2#U1,8=e8-,BEz;Hoԣ-G"<,1c ~Vn8E8+׽ʁFZU+"̳qSa;ͪ5.W>TQ`0nQȻc@Wή?R20B832 *}x}@ah%B JNp0Us*M[ W+}gÿ#SBJL"OLq2$pp JL0AxGd=g2< &;T#vhjz8>+(R7#r &ԱobGYvF3 r8nt lvBwf<s^G:v-g /6=K@mkfQߤ0mIxV;ǭ g^eQl:8CAS4C RӚ8^>WNzYGBz^ݰ*=J;KUu;8W&&s5"@f$:?oofΞt$G?6~T zV;S o{1ib5u")_2ϧO#F>|4i_e/nv՗ endstream endobj 79 0 obj <> endobj 80 0 obj <> endobj 81 0 obj <> endobj 77 0 obj <>endobj 75 0 obj <>endobj 73 0 obj <>endobj 71 0 obj <>endobj 69 0 obj <>endobj 67 0 obj <>endobj 65 0 obj <>endobj 63 0 obj <>endobj 61 0 obj <>endobj 59 0 obj <>endobj 57 0 obj <>endobj 55 0 obj <>endobj 53 0 obj <>endobj 51 0 obj <>endobj 49 0 obj <>endobj 47 0 obj <>endobj 45 0 obj <>endobj 43 0 obj <>endobj 41 0 obj <>endobj 39 0 obj <>endobj 37 0 obj <>endobj 35 0 obj <>endobj 33 0 obj <>endobj 31 0 obj <>endobj 29 0 obj <>endobj 27 0 obj <>endobj 25 0 obj <>endobj 20 0 obj <>endobj 18 0 obj <>endobj 16 0 obj <>endobj 10 0 obj <>endobj 82 0 obj <> endobj 78 0 obj <>endobj 76 0 obj <>endobj 74 0 obj <>endobj 72 0 obj <>endobj 70 0 obj <>endobj 68 0 obj <>endobj 66 0 obj <>endobj 64 0 obj <>endobj 62 0 obj <>endobj 60 0 obj <>endobj 58 0 obj <>endobj 56 0 obj <>endobj 54 0 obj <>endobj 52 0 obj <>endobj 50 0 obj <>endobj 48 0 obj <>endobj 46 0 obj <>endobj 44 0 obj <>endobj 42 0 obj <>endobj 40 0 obj <>endobj 38 0 obj <>endobj 36 0 obj <>endobj 34 0 obj <>endobj 32 0 obj <>endobj 30 0 obj <>endobj 28 0 obj <>endobj 26 0 obj <>endobj 21 0 obj <>endobj 19 0 obj <>endobj 17 0 obj <>endobj 11 0 obj <>endobj 23 0 obj <>stream x{wuŕ endstream endobj 22 0 obj <>stream x /qefff I$IsuW3 'ﺈ{H|OC7dSd *ܶuӶm^k%ѩ;qN䣚=f2ߏOMm=i%>endobj 13 0 obj <>stream xąąÅÄĄăăĂāāŀŀ~}||{zyx~v{uytvssrprlqipeocn`l]kZjWhSgPfLdIcFaC`?^<\9Z6Y3W0U-T*R'O$M!KIGEC@>;9 6 4 1/s endstream endobj 12 0 obj <>stream x /q辰cLEJ.Mob֚*o%?/R29@٧@9-g@.my{(-`]oUw p&7A;!'{.= _ѐ 2eO2JdAI ʃa *S:ҡ(v;}~^+^|>/?ISy~7nW_Qm?m endstream endobj 14 0 obj <>endobj 83 0 obj <>stream 2011-03-25T16:22:07+01:00 2011-03-25T16:22:07+01:00 UnknownApplication Untitled endstream endobj 2 0 obj <>endobj xref 0 84 0000000000 65535 f 0000005846 00000 n 0000032807 00000 n 0000005787 00000 n 0000006022 00000 n 0000005598 00000 n 0000000015 00000 n 0000005578 00000 n 0000005911 00000 n 0000005952 00000 n 0000025779 00000 n 0000029583 00000 n 0000030884 00000 n 0000030430 00000 n 0000031302 00000 n 0000005978 00000 n 0000025667 00000 n 0000029472 00000 n 0000025559 00000 n 0000029361 00000 n 0000025444 00000 n 0000029250 00000 n 0000029895 00000 n 0000029694 00000 n 0000030321 00000 n 0000025329 00000 n 0000029139 00000 n 0000025214 00000 n 0000029028 00000 n 0000025099 00000 n 0000028917 00000 n 0000024984 00000 n 0000028806 00000 n 0000024869 00000 n 0000028695 00000 n 0000024754 00000 n 0000028584 00000 n 0000024639 00000 n 0000028473 00000 n 0000024524 00000 n 0000028362 00000 n 0000024409 00000 n 0000028251 00000 n 0000024294 00000 n 0000028140 00000 n 0000024179 00000 n 0000028029 00000 n 0000024064 00000 n 0000027918 00000 n 0000023949 00000 n 0000027807 00000 n 0000023834 00000 n 0000027696 00000 n 0000023719 00000 n 0000027585 00000 n 0000023604 00000 n 0000027474 00000 n 0000023489 00000 n 0000027363 00000 n 0000023374 00000 n 0000027252 00000 n 0000023259 00000 n 0000027141 00000 n 0000023144 00000 n 0000027030 00000 n 0000023029 00000 n 0000026919 00000 n 0000022914 00000 n 0000026808 00000 n 0000022799 00000 n 0000026697 00000 n 0000022684 00000 n 0000026586 00000 n 0000022569 00000 n 0000026475 00000 n 0000022454 00000 n 0000026364 00000 n 0000022339 00000 n 0000026253 00000 n 0000021906 00000 n 0000021936 00000 n 0000021977 00000 n 0000025891 00000 n 0000031411 00000 n trailer << /Size 84 /Root 1 0 R /Info 2 0 R /ID [] >> startxref 32930 %%EOF canl-c-3.0.0/doc/src/images/cesnet.pdf0000644000015500017500000001064613017332511017225 0ustar tomcat6jenkins%PDF-1.3 %쏢 6 0 obj <> stream x}ZY+9*JQ_VYx)E8⢐@'Z(CLL/?V_G)kxO޵ ǹb/y_eYsu/|7=9Am aOJ@M*bIēfy۝~ 1zZtr ,5 'USwC='>]CXp;da }N)V\*8tbp-3:8s,,l:d.&\B)N! 5%ELneKrRj>B*6v8V NhRzS BM; 'D͔W'wB?)~Hs)(x $N}nxܛY˳.g+tX~8"s ycmCw>d'T*a`[/PM{sJCk l@N\wHܲdlkȵq4+OCNq/y2^9OxᨸoBFٓr%ws*ݣ`pF@THpg;^y̌=1?\w[pagax?zc#=_gn7 I&][H=S~ W5n9q"bڠQ{i K%Qi>_wvQ=<SvjlDTR(wgNNO46sZ8a5(:@b % u৭9M0n<*W@B0 ixv HqjMWB#:hru/W킂o$ A `?( G*5wze/3xEN >P74!.;~4I{Uށ/5skʤ`s HH$iY@N:A'X7daǓAYXkǴ5Bb{h@ z*oDw<_ZF/4& fZԖT ruYx+ӖApRM%Bš;$А51N%Tr4|K6eq:r,$X3{ӜaB$#@aWaeA9QL.q:u,Wy@"̂bͭOf#<&Πg9*丽͆7n#E rܻC6?KL$J_.o-Q^[j;dl` na̸C~ƛj+yu$"ȱ{Փ,;MZz9})jgfhU䩹^ZrRfe/1,wH@A' QLëݾڑ ~a]OL ׃*\/0nK`S ,#&Τ4?1c9sK$VMM8ג~Q35 *.v8K |<4گ(h|)p~B k䖯B*$jΔ* LuO\5M!ij+,t5ow!TJF7פuUmYeoL=<V>0@0x3yn.[4&s~e$hJ tI]LDޖk4\4K\ׂSR{Hs@3"IYi9iÒrD4n#+Nqq7TG\@3J' NEpK^$Ȯ*15TB 2$#<*2JAC 4iSғ&(p\D,X@G"bxdePԜJ-p A8( hPNqE/2WPf+sӄuYУfWo3nEK|*2Lr5UDDfCE% 3-oF.ج'a݃18}l"VgJ7"iGE?k vTHio%*/[ Z0T)=#ev~?XPT&!ȖuES4+Mi2&hPi"}s he}n'ԕΝpũKw\t'.-7fWБ=HFtm,{K|k1C| ](,i#&lg,r7ϴ`E U lxbLEdPX >{ dot0nJWkW |Kl=1dxut҅?ܣݖpU77ïHQw?fB=y`#u]Ty@yMA{vL, ^ÊaG˶J1*r:Omk8Q]@ؙVītΥVGJ4FW.34ꚚZ9ͦQxŖ ):Nh|i6 4{/2;҈p{t7{Ûm B;mOelVgSùmOs[rDn$w6͚r55֤H ?nFmvX}v7QS "t"؆7ӟx3d0en:x`r1da{l_^&eHӊLe@,̴?:K2r*?+rKẘ?;LeiNfRQyD,4gY5 T]j`/H2񲟿'bׁ@6a5ջ .3Ӹ:J߿ $C˯%|޴P>eO_& >/=M/3i\A&m_o#+>?Eױm,5蟧_>/Ij\>ILTߗ,>c__9.'֗G!PΑ1G8YXncAN!ǩ1: 7"cj&< h//ȩ)2~ؐsִ{NW>+a^ >DxuAhnv> /Contents 6 0 R >> endobj 3 0 obj << /Type /Pages /Kids [ 5 0 R ] /Count 1 >> endobj 1 0 obj <> endobj 4 0 obj <> endobj 8 0 obj <> endobj 2 0 obj <>endobj xref 0 9 0000000000 65535 f 0000004066 00000 n 0000004212 00000 n 0000004007 00000 n 0000004114 00000 n 0000003867 00000 n 0000000015 00000 n 0000003847 00000 n 0000004183 00000 n trailer << /Size 9 /Root 1 0 R /Info 2 0 R >> startxref 4262 %%EOF canl-c-3.0.0/examples/0000755000015500017500000000000013017332511014257 5ustar tomcat6jenkinscanl-c-3.0.0/examples/canl_sample_client.c0000644000015500017500000001145013017332511020240 0ustar tomcat6jenkins#include #include #include #include #include #include #define BUF_LEN 1000 #define DEF_PORT 4321 #define DEF_TIMEOUT 150 int main(int argc, char *argv[]) { canl_ctx my_ctx; canl_io_handler my_io_h = NULL; int err = 0; char buf[BUF_LEN]; int buf_len = 0; char *ca_dir = NULL; char *p_server = NULL; char *def_server = "www.linuxfoundation.org"; int opt, port = DEF_PORT; struct timeval timeout; char *serv_cert = NULL; char *serv_key = NULL; char *proxy_cert = NULL; canl_principal princ = NULL; int get_peer_princ = 0; char *name = NULL; int ocsp_on = 0; timeout.tv_sec = DEF_TIMEOUT; timeout.tv_usec = 0; while ((opt = getopt(argc, argv, "nhop:s:c:k:t:x:")) != -1) { switch (opt) { case 'h': fprintf(stderr, "Usage: %s [-p port] [-c certificate]" " [-k private key] [-d ca_dir] [-h] " " [-s server] [-x proxy certificate] " "[-t timeout] [-n {print peer's princ name}] " "[-o {turn OCSP on}] " " \n", argv[0]); exit(0); case 'p': port = atoi(optarg); break; case 's': p_server = optarg; break; case 'c': serv_cert = optarg; break; case 'k': serv_key = optarg; break; case 'x': proxy_cert = optarg; break; case 'd': ca_dir = optarg; break; case 't': timeout.tv_sec = atoi(optarg); break; case 'n': get_peer_princ = 1; break; case 'o': ocsp_on = 1; break; default: /* '?' */ fprintf(stderr, "Usage: %s [-p port] [-c certificate]" " [-k private key] [-d ca_dir] [-h]" " [-s server] [-x proxy certificate]" "[-t timeout] [-n {print peer's princ name}] " "[-o {turn OCSP on}] " " \n", argv[0]); exit(-1); } } if (!p_server) p_server = def_server; my_ctx = canl_create_ctx(); if (!my_ctx){ printf("CANL context cannot be created, exiting.\n"); goto end; } err = canl_create_io_handler(my_ctx, &my_io_h); if (err) { printf("io handler cannot be created:\n[CANL] %s\n", canl_get_error_message(my_ctx)); goto end; } if (serv_cert || serv_key || proxy_cert){ err = canl_ctx_set_ssl_cred(my_ctx, serv_cert, serv_key, proxy_cert, NULL, NULL); if (err) { printf("[CLIENT] cannot set certificate or key" " to context:\n[CANL] %s\n", canl_get_error_message(my_ctx)); goto end; } } if (ocsp_on) canl_ctx_set_ssl_flags(my_ctx, CANL_SSL_OCSP_VERIFY_ALL); if (get_peer_princ) { err = canl_io_connect(my_ctx, my_io_h, p_server, NULL, port, NULL, 0, &princ, &timeout); if (err) { printf("[CLIENT] connection cannot be established:\n[CANL] %s\n", canl_get_error_message(my_ctx)); goto end; } err = canl_princ_name(my_ctx, princ, &name); printf("[CLIENT] connection established with %s\n", name); free(name); canl_princ_free(my_ctx, princ); } else{ err = canl_io_connect(my_ctx, my_io_h, p_server, NULL, port, NULL, 0, NULL, &timeout); if (err) { printf("[CLIENT] connection cannot be established:\n[CANL] %s\n", canl_get_error_message(my_ctx)); goto end; } printf("[CLIENT] connection established\n"); } strcpy(buf, "This is the testing message to send"); buf_len = strlen(buf) + 1; printf("[CLIENT] Trying to send sth to the server\n"); err = canl_io_write (my_ctx, my_io_h, buf, buf_len, &timeout); if (err <= 0) { printf("can't write using ssl:\n[CANL] %s\n", canl_get_error_message(my_ctx)); goto end; } else { buf[err] = '\0'; printf("[CLIENT] message \"%s\" sent successfully\n", buf); } buf[0] = '\0'; err = canl_io_read (my_ctx, my_io_h, buf, sizeof(buf)-1, &timeout); if (err > 0) { buf[err] = '\0'; printf ("[CLIENT] received: %s\n", buf); err = 0; } end: if (my_io_h) canl_io_destroy(my_ctx, my_io_h); canl_free_ctx(my_ctx); return err; } canl-c-3.0.0/examples/canl_sample_server.c0000644000015500017500000001466413017332511020302 0ustar tomcat6jenkins#include #include #include #include #include #include #include #include #define BUF_LEN 1000 #define BACKLOG 10 #define DEF_PORT 4321 #define DEF_TIMEOUT 150 int main(int argc, char *argv[]) { canl_ctx my_ctx; canl_io_handler my_io_h = NULL; int err = 0; int opt, port = DEF_PORT; char *serv_cert = NULL; char *serv_key = NULL; char *ca_dir = NULL; char buf[BUF_LEN]; int buf_len = 0; struct timeval timeout; canl_principal princ = NULL; int get_peer_princ = 0; int ocsp_on = 0; char *name = NULL; timeout.tv_sec = DEF_TIMEOUT; timeout.tv_usec = 0; while ((opt = getopt(argc, argv, "nhop:c:k:d:t:")) != -1) { switch (opt) { case 'h': fprintf(stderr, "Usage: %s [-p port] [-c certificate]" " [-k private key] [-d ca_dir] [-h] " "[-t timeout] [-n {print peer's princ name}] " " [-o {turn OCSP on}] " " \n", argv[0]); exit(0); case 'p': port = atoi(optarg); break; case 'c': serv_cert = optarg; break; case 'k': serv_key = optarg; break; case 'd': ca_dir = optarg; break; case 't': timeout.tv_sec = atoi(optarg); break; case 'n': get_peer_princ = 1; break; case 'o': ocsp_on = 1; break; default: /* '?' */ fprintf(stderr, "Usage: %s [-p port] [-c certificate]" " [-k private key] [-d ca_dir] [-h] " "[-t timeout] [-n {print peer's princ name}] " " [-o {turn OCSP on}] " " \n", argv[0]); exit(-1); } } my_ctx = canl_create_ctx(); if (!my_ctx){ printf("[SERVER] canl context cannot be created\n"); return -1; } err = canl_create_io_handler(my_ctx, &my_io_h); if (err) { printf("[SERVER] io handler cannot be created:\n[CANL] %s\n", canl_get_error_message(my_ctx)); goto end; } if (serv_cert || serv_key){ err = canl_ctx_set_ssl_cred(my_ctx, serv_cert, serv_key, NULL, NULL, NULL); if (err) { printf("[SERVER] cannot set certificate or key to" " context:\n[CANL] %s\n", canl_get_error_message(my_ctx)); goto end; } } /* ACCEPT from canl_io_accept*/ int sockfd = 0, new_fd = 0; char str_port[8]; struct addrinfo hints, *servinfo, *p; struct sockaddr s_addr; socklen_t sin_size; int yes=1; memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; // use my IP if (snprintf(str_port, 8, "%d", port) < 0) { printf ("[SERVER] Wrong port request"); return 1; } /* XXX timeouts - use c-ares, too */ if ((err = getaddrinfo(NULL, str_port, &hints, &servinfo)) != 0) { printf("[SERVER] getaddrinfo: %s\n", gai_strerror(err)); return 1; } for (p = servinfo; p != NULL; p = p->ai_next) { if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) { err = errno; continue; } if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { err = errno; continue; } if ((err = bind(sockfd, p->ai_addr, p->ai_addrlen))) { err = errno; close(sockfd); continue; } if ((err = listen(sockfd, BACKLOG))) { close(sockfd); err = errno; continue; } break; } freeaddrinfo(servinfo); // all done with this structure if (p == NULL) { /* Beware that only the last error is displayed here ... */ printf("Failed to acquire a server socket: %s\n", strerror(err)); return 1; } printf("server: waiting for connections...\n"); sin_size = sizeof(s_addr); if (ocsp_on) canl_ctx_set_ssl_flags(my_ctx, CANL_SSL_OCSP_VERIFY_ALL); new_fd = accept(sockfd, &s_addr, &sin_size); if (new_fd == -1){ printf("Failed to accept network connection: %s", strerror(errno)); } /* canl_create_io_handler has to be called for my_io_h*/ /* TODO timeout in this function? and select around it*/ if (get_peer_princ) { err = canl_io_accept(my_ctx, my_io_h, new_fd, s_addr, 0, &princ, &timeout); if (err) { printf("[SERVER] connection cannot be established:\n[CANL] %s\n", canl_get_error_message(my_ctx)); goto end; } err = canl_princ_name(my_ctx, princ, &name); printf("[SERVER] connection established with %s\n", name); free(name); canl_princ_free(my_ctx, princ); } else{ err = canl_io_accept(my_ctx, my_io_h, new_fd, s_addr, 0, NULL, &timeout); if (err) { printf("[SERVER] connection cannot be established:\n[CANL] %s\n", canl_get_error_message(my_ctx)); goto end; } printf("[SERVER] connection established\n"); } strncpy(buf, "This is a testing message to send", sizeof(buf)); buf_len = strlen(buf) + 1; printf("[SERVER] Trying to send sth to the client\n"); err = canl_io_write (my_ctx, my_io_h, buf, buf_len, &timeout); if (err <= 0) { printf("[SERVER] cannot send message to the client:\n[CANL] %s\n", canl_get_error_message(my_ctx)); goto end; } else { buf[err] = '\0'; printf("[SERVER] message \"%s\" sent successfully\n", buf); } buf[0] = '\0'; err = canl_io_read (my_ctx, my_io_h, buf, sizeof(buf)-1, &timeout); if (err <= 0) { printf("[SERVER] Failed to receive reply from client:\n[CANL] %s\n", canl_get_error_message(my_ctx)); goto end; } buf[err] = '\0'; printf ("[SERVER] received: %s\n", buf); err = 0; end: if (my_io_h) canl_io_destroy(my_ctx, my_io_h); canl_free_ctx(my_ctx); return err; } canl-c-3.0.0/examples/delegation.c0000644000015500017500000001456513017332511016551 0ustar tomcat6jenkins#include #include #include #include #define BITS 1024 #define LIFETIME 43200 /*12 hours*/ #define OUTPUT "/tmp/x509_u99999" int main(int argc, char *argv[]) { canl_cred signer = NULL; canl_cred proxy = NULL; canl_cred proxy_cert = NULL; canl_cred proxy_bob = NULL; X509_REQ *req = NULL; X509 *x509_cert = NULL; STACK_OF(X509) *x509_chain= NULL; canl_ctx ctx = NULL; canl_err_code ret; char *user_cert = NULL; char *output = NULL; char *user_key = NULL; long int lifetime = 0; unsigned int bits = 0; int opt = 0; while ((opt = getopt(argc, argv, "hc:k:l:b:o:")) != -1) { switch (opt) { case 'h': fprintf(stderr, "Usage: %s [-c certificate]" " [-k private key] [-h] [-l lifetime] [-b bits]" " [-o output]" "\n", argv[0]); exit(0); case 'c': user_cert = optarg; break; case 'k': user_key = optarg; break; case 'l': lifetime = atoi(optarg); break; case 'b': bits = atoi(optarg); break; case 'o': output = optarg; break; default: /* '?' */ fprintf(stderr, "Usage: %s [-c certificate]" " [-k private key] [-h] [-l lifetime] [-b bits]" " [-o output]" "\n", argv[0]); exit(-1); } } ctx = canl_create_ctx(); if (ctx == NULL) { fprintf(stderr, "[DELEGATION] Failed to create library context\n"); return 1; } /* Bob - after Alice has asked to delegate her credentials */ ret = canl_cred_new(ctx, &proxy_bob); if (ret){ fprintf(stderr, "[DELEGATION] Proxy context cannot be created" ": %s\n", canl_get_error_message(ctx)); goto end; } if (!bits) bits = BITS; ret = canl_cred_new_req(ctx, proxy_bob, bits); if (ret) { fprintf(stderr, "[DELEGATION] Failed to create certificate " "request container: %s\n", canl_get_error_message(ctx)); goto end; } ret = canl_cred_save_req(ctx, proxy_bob, &req); if (ret) { fprintf(stderr, "[DELEGATION] Failed to get certificate " "request container: %s\n", canl_get_error_message(ctx)); goto end; } /* serialize 'req' and send it to Alice */ /* Alice - after receiving the CSR from Bob. (The private key stays with Bob.) */ { ret = canl_cred_new(ctx, &signer); if (ret){ fprintf(stderr, "[DELEGATION] Proxy context cannot be created" ": %s\n", canl_get_error_message(ctx)); goto end; } ret = canl_cred_load_cert_file(ctx, signer, user_cert); if (ret){ fprintf(stderr, "[DELEGATION] Cannot load signer's certificate" ": %s\n", canl_get_error_message(ctx)); goto end; } ret = canl_cred_load_priv_key_file(ctx, signer, user_key, NULL, NULL); if (ret){ fprintf(stderr, "[DELEGATION] Cannot access signer's key" ": %s\n", canl_get_error_message(ctx)); goto end; } /* deserialize 'req' from Bob */ ret = canl_cred_new(ctx, &proxy_cert); if (ret){ fprintf(stderr, "[DELEGATION] Proxy context cannot be created" ": %s\n", canl_get_error_message(ctx)); goto end; } ret = canl_cred_load_req(ctx, proxy_cert, req); if (ret) { fprintf(stderr, "[DELEGATION] Failed to load certificate " "request container: %s\n", canl_get_error_message(ctx)); goto end; } if (!lifetime) lifetime = LIFETIME; ret = canl_cred_set_lifetime(ctx, proxy_cert, lifetime); if (ret) fprintf(stderr, "[DELEGATION] Failed set new cert lifetime" ": %s\n", canl_get_error_message(ctx)); ret = canl_cred_set_cert_type(ctx, proxy_cert, CANL_RFC); if (ret) fprintf(stderr, "[DELEGATION] Failed set new cert type" ": %s\n", canl_get_error_message(ctx)); ret = canl_cred_sign_proxy(ctx, signer, proxy_cert); if (ret){ fprintf(stderr, "[DELEGATION] Cannot sign new proxy" ": %s\n", canl_get_error_message(ctx)); goto end; } ret = canl_cred_save_cert(ctx, proxy_cert, &x509_cert); if (ret){ fprintf(stderr, "[DELEGATION] Cannot save new cert file" ": %s\n", canl_get_error_message(ctx)); goto end; } ret = canl_cred_save_chain(ctx, proxy_cert, &x509_chain); if (ret){ fprintf(stderr, "[DELEGATION] Cannot save cert chain" ": %s\n", canl_get_error_message(ctx)); goto end; } /* serialize the new proxy cert and chain and send it back to Bob */ } /* Bob - on receiving the final certificate and chain */ /* deserialize the new proxy cert and chain from Alice */ ret = canl_cred_load_cert(ctx, proxy_bob, x509_cert); if (ret){ fprintf(stderr, "[DELEGATION] Cannot load certificate" ": %s\n", canl_get_error_message(ctx)); goto end; } ret = canl_cred_load_chain(ctx, proxy_bob, x509_chain); if (ret){ fprintf(stderr, "[DELEGATION] Cannot load cert. chain" ": %s\n", canl_get_error_message(ctx)); goto end; } if (!output) output = OUTPUT; ret = canl_cred_save_proxyfile(ctx, proxy_bob, output); if (ret){ fprintf(stderr, "[PROXY-INIT] Cannot save new proxy" ": %s\n", canl_get_error_message(ctx)); goto end; } ret = 0; end: if (signer) canl_cred_free(ctx, signer); if (proxy) canl_cred_free(ctx, proxy); if (proxy_cert) canl_cred_free(ctx, proxy_cert); if (proxy_bob) canl_cred_free(ctx, proxy_bob); if (req) X509_REQ_free(req); if (x509_cert) X509_free(x509_cert); /* TODO free stack * if (x509_chain) X509_free(x509_cert); */ if (ctx) canl_free_ctx(ctx); return ret; } canl-c-3.0.0/examples/grid-proxy-init.c0000644000015500017500000001124413017332511017472 0ustar tomcat6jenkins#include #include #include #include #define BITS 1024 #define LIFETIME 43200 /*12 hours*/ #define OUTPUT "/tmp/x509_u99999" int main(int argc, char *argv[]) { canl_cred signer = NULL; canl_cred proxy = NULL; canl_ctx ctx = NULL; canl_err_code ret = 0; char *user_cert = NULL; char *output = NULL; char *user_key = NULL; long int lifetime = 0; unsigned int bits = 0; int opt = 0; int proxyver = 2; enum canl_cert_type cert_type = CANL_RFC; while ((opt = getopt(argc, argv, "hc:k:l:b:o:v:")) != -1) { switch (opt) { case 'h': fprintf(stderr, "Usage: %s [-c certificate]" " [-k private key] [-h] [-l lifetime] [-b bits]" " [-o output] [-v proxy version]" "\n", argv[0]); exit(0); case 'c': user_cert = optarg; break; case 'k': user_key = optarg; break; case 'l': lifetime = atoi(optarg); break; case 'b': bits = atoi(optarg); break; case 'o': output = optarg; break; case 'v': proxyver = atoi(optarg); break; default: /* '?' */ fprintf(stderr, "Usage: %s [-c certificate]" " [-k private key] [-h] [-l lifetime] [-b bits]" " [-o output] [-v proxy version]" "\n", argv[0]); exit(-1); } } switch (proxyver){ case 2: cert_type = CANL_EEC; break; case 3: cert_type = CANL_RFC; break; default: cert_type = CANL_RFC; } ctx = canl_create_ctx(); if (ctx == NULL) { fprintf(stderr, "[PROXY-INIT] Failed to create library context\n"); return 1; } /* First create a certificate request with a brand-new keypair */ ret = canl_cred_new(ctx, &proxy); if (ret){ fprintf(stderr, "[PROXY-INIT] Proxy context cannot be created" ": %s\n", canl_get_error_message(ctx)); goto end; } if (!bits) bits = BITS; ret = canl_cred_new_req(ctx, proxy, bits); if (ret) { fprintf(stderr, "[PROXY-INIT] Failed to create certificate " "request container: %s\n", canl_get_error_message(ctx)); goto end; } if (!lifetime) lifetime = LIFETIME; /*Create key-pairs implicitly*/ ret = canl_cred_set_lifetime(ctx, proxy, lifetime); if (ret) fprintf(stderr, "[PROXY-INIT] Failed set new cert lifetime" ": %s\n", canl_get_error_message(ctx)); ret = canl_cred_set_cert_type(ctx, proxy, cert_type); if (ret) fprintf(stderr, "[PROXY-INIT] Failed set new cert type" ": %s\n", canl_get_error_message(ctx)); /* Load the signing credentials */ ret = canl_cred_new(ctx, &signer); if (ret){ fprintf(stderr, "[PROXY-INIT] Proxy context cannot be created" ": %s\n", canl_get_error_message(ctx)); goto end; } ret = canl_cred_load_cert_file(ctx, signer, user_cert); if (ret){ fprintf(stderr, "[PROXY-INIT] Cannot load signer's certificate" ": %s\n", canl_get_error_message(ctx)); goto end; } ret = canl_cred_load_priv_key_file(ctx, signer, user_key, NULL, NULL); if (ret){ fprintf(stderr, "[PROXY-INIT] Cannot access signer's key" ": %s\n", canl_get_error_message(ctx)); goto end; } /*TODO? export lookup routines ?? */ #ifdef VOMS GET_VOMS_EXTS(ctx, signer, STACK_OF(EXTS)); foreach (EXTS) { ret = canl_cred_set_extension(ctx, proxy, ext); if (ret){ fprintf(stderr, "[PROXY-INIT] Cannot set voms extension" ": %s\n", canl_get_error_message(ctx)); } } #endif /* Create the proxy certificate */ ret = canl_cred_sign_proxy(ctx, signer, proxy); if (ret){ fprintf(stderr, "[PROXY-INIT] Cannot sign new proxy" ": %s\n", canl_get_error_message(ctx)); goto end; } /* and store it in a file */ if (!output) output = OUTPUT; ret = canl_cred_save_proxyfile(ctx, proxy, output); if (ret){ fprintf(stderr, "[PROXY-INIT] Cannot save new proxy" ": %s\n", canl_get_error_message(ctx)); goto end; } ret = 0; end: if (signer) canl_cred_free(ctx, signer); if (proxy) canl_cred_free(ctx, proxy); if (ctx) canl_free_ctx(ctx); return ret; } canl-c-3.0.0/src/0000755000015500017500000000000013017332513013232 5ustar tomcat6jenkinscanl-c-3.0.0/src/canl_error_codes0000644000015500017500000000371013017332511016457 0ustar tomcat6jenkins# # Additional codes MUST be added to the end only! # unknown unknownMsg inputError nsUndefinedAndRequired nsDeny nsNotAccepted proxyEECInChain proxyLength proxyNoIssuer proxyCASet proxyIssuerAltNameSet proxySubjectAltNameSet proxyIssuedByCa proxyNoIssuerSubject proxySubjectInconsistent proxyIssuerNoDsig proxySubjectOneRDN proxySubjectMultiLastRDN proxySubjectLastRDNNotCN proxySubjectBaseWrong noIssuerPublicKey noBasicConstraints pathLenghtExtended conflictingTrustAnchors noTrustAnchorFound trustButInvalidCert signatureNotVerified certificateNotYetValid certificateExpired noCACert noCertSign unknownCriticalExt certRevoked noBaseCRL noValidCrlFound certPathCheckerError certPathValidDate certWrongIssuer criticalExtensionError crlAuthInfoAccError crlBCExtError crlDistPoint crlDistPtExtError crlExtractionError crlIssuerException crlNbrExtError crlNoIssuerPublicKey crlOnlyAttrCert crlOnlyCaCert crlOnlyUserCert crlReasonExtError crlUpdateAvailable crlVerifyFailed deltaCrlExtError distrPtExtError emptyCertPath errorProcesingBC excludedDN excludedEmail excludedIP explicitPolicy invalidPolicy invalidPolicyMapping loadCrlDistPointError localInvalidCRL localValidCRL ncExtError ncSubjectNameError noCrlInCertstore noCrlSigningPermited notPermittedDN notPermittedEmail notPermittedIP notRevoked noValidPolicyTree ocspLocation onlineCRLWrongCA onlineInvalidCRL onlineValidCRL policyConstExtError policyExtError policyInhibitExtError policyMapExtError policyQualifierError processLengthConstError pubKeyError QcEuCompliance QcLimitValueAlpha QcLimitValueNum QcSSCD QcStatementExtError QcUnknownStatement revokedAfterValidation rootKeyIsValidButNotATrustAnchor subjAltNameExtError totalPathLength trustAnchorIssuerError trustDNInvalid trustPubKeyError # # Recently added error codes without appropriate desc. # generalSSLError hostNotFound resolverError noPeerCertificate noKeyFound noCertFound # # Recently added error codes without appropriate desc. # invalidPurpose noRouteToServer canl-c-3.0.0/src/canl_error_desc0000644000015500017500000001453013017332511016302 0ustar tomcat6jenkins# # Generic errors # unknown=Unknown error unknown.category=OTHER unknownMsg={0} unknownMsg.category=OTHER inputError=Input certificate chain processing error: {0} inputError.category=GENERAL_INPUT noRouteToServer=Server does not respond or accept new connection. noRouteToServer.category=OTHER # # Namespace related errors # nsUndefinedAndRequired=Namespace definition for the certificate issuer ({0}) is not defined, and namespaces are configured to be required. nsUndefinedAndRequired.category=NAMESPACE nsDeny=The certificate subject {0} is denied by the namespace policy: {1} nsDeny.category=NAMESPACE nsNotAccepted=The certificate subject {0} is not accepted by any rule of the the relevant namespace policies. Policies which matches the issuer are: {1} nsNotAccepted.category=NAMESPACE # # Proxy certificate specific errors # proxyEECInChain=Certificate issued by an end-entity certificate or a proxy certificate is not a proxy proxy certificate. proxyEECInChain.category=INCONSISTENT_PROXY_CHAIN proxyLength=At the current position the proxy certificates chain exceeded its length limit. proxyLength.category=INCONSISTENT_PROXY_CHAIN proxyNoIssuer=Issuing end entity certificate was not found in the chain with proxy certificates. proxyNoIssuer.category=INCONSISTENT_PROXY_CHAIN proxyCASet=Proxy certificate has the cA field set proxyCASet.category=INVALID_PROXY_CERT proxyIssuerAltNameSet=Proxy certificate has the IssuerAlternativeName set proxyIssuerAltNameSet.category=INVALID_PROXY_CERT proxySubjectAltNameSet=Proxy certificate has the SubjectAlternativeName set proxySubjectAltNameSet.category=INVALID_PROXY_CERT proxyIssuedByCa=Proxy certificate issuer has the cA field set proxyIssuedByCa.category=INCONSISTENT_PROXY_CHAIN proxyNoIssuerSubject=Proxy certificate issuer has no Subject field set proxyNoIssuerSubject.category=INVALID_PROXY_CERT proxySubjectInconsistent=Proxy certificate issuer field is different than the issuing certificate subject field set. proxySubjectInconsistent.category=INCONSISTENT_PROXY_CHAIN proxySubjectInconsistent.openssl_code=ERR_USER_LIB_PRXYERR_NUMBER,PRXYERR_R_BAD_PROXY_ISSUER proxyIssuerNoDsig=Proxy certificate issuer has no digital signature creation right proxyIssuerNoDsig.category=INCONSISTENT_PROXY_CHAIN proxySubjectOneRDN=The proxy certificate subject name has less then two elements proxySubjectOneRDN.category=INVALID_PROXY_CERT proxySubjectMultiLastRDN=The last RDN in proxy subject name is multivalued proxySubjectMultiLastRDN.category=INVALID_PROXY_CERT proxySubjectLastRDNNotCN=The last RDN in proxy subject name is not a CN proxySubjectLastRDNNotCN.category=INVALID_PROXY_CERT proxySubjectBaseWrong=The proxy subject without its last CN component is not equal to its issuer name proxySubjectBaseWrong.category=INVALID_PROXY_CERT # # Regular X.509 path validation errors # noIssuerPublicKey=Trusted issuer of this certificate was not established noIssuerPublicKey.category=X509_CHAIN noBasicConstraints=The selected CA certificate does not contain the mandatory Basic Constraints extension noBasicConstraints.category=X509_BASIC pathLenghtExtended=Total chain length exceeds the limit pathLenghtExtended.category=X509_CHAIN conflictingTrustAnchors=More then one trusted CA certificate was found for the certificate chain conflictingTrustAnchors.category=X509_CHAIN noTrustAnchorFound=No trusted CA certificate was found for the certificate chain noTrustAnchorFound.category=X509_CHAIN noTrustAnchorFound.openssl_code=ERR_LIB_X509V3,X509V3_R_NO_ISSUER_CERTIFICATE trustButInvalidCert=CA certificate was found for the certificate chain but the initial certificate in chain is not issued (correctly signed) by the CA certificate trustButInvalidCert.category=X509_CHAIN signatureNotVerified=Unable to verify signature of certificates in the chain: {0} signatureNotVerified.category=X509_BASIC certificateNotYetValid=Certificate is not yet valid. Will be from: {0} certificateNotYetValid.category=X509_BASIC certificateNotYetValid.openssl_code=ERR_USER_LIB_PRXYERR_NUMBER,PRXYERR_R_CERT_NOT_YET_VALID certificateExpired=Certificate has expired at: {0} certificateExpired.category=X509_BASIC certificateExpired.openssl_code=ERR_LIB_SSL,SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED noCACert=CA certificate was not found for the chain noCACert.category=X509_CHAIN noCertSign=Issuer of the certificate is not eligible to sign certificates as its certificate has no keyCertSign flag set in its KeyUsage extension. noCertSign.category=X509_CHAIN unknownCriticalExt=Unknown critical extension was found: {0} unknownCriticalExt.category=X509_BASIC unknownCriticalExt.openssl_code=ERR_USER_LIB_PRXYERR_NUMBER,PRXYERR_R_UNKNOWN_CRIT_EXT certRevoked=Certificate was revoked at: {0}, the reason reported is: {1} certRevoked.category=CRL certRevoked.openssl_code=ERR_LIB_SSL,SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED noBaseCRL=Base CRL for the delta CRL was not found noBaseCRL.category=CRL noValidCrlFound=No valid CRL was found for the CA which issued the chain noValidCrlFound.category=CRL invalidPurpose=Invalid purpose of the peer certificate invalidPurpose.category=X509_BASIC # # Rare errors lacking "translations" and meta-information # # # certPathCheckerError # certPathValidDate # certWrongIssuer # criticalExtensionError # crlAuthInfoAccError # crlBCExtError # crlDistPoint # crlDistPtExtError # crlExtractionError # crlIssuerException # crlNbrExtError # crlNoIssuerPublicKey # crlOnlyAttrCert # crlOnlyCaCert # crlOnlyUserCert # crlReasonExtError # crlUpdateAvailable # crlVerifyFailed # deltaCrlExtError # distrPtExtError # emptyCertPath # errorProcesingBC # excludedDN # excludedEmail # excludedIP # explicitPolicy # invalidPolicy # invalidPolicyMapping # loadCrlDistPointError # localInvalidCRL # localValidCRL # ncExtError # ncSubjectNameError # noCrlInCertstore # noCrlSigningPermited # notPermittedDN # notPermittedEmail # notPermittedIP # notRevoked # noValidPolicyTree # ocspLocation # onlineCRLWrongCA # onlineInvalidCRL # onlineValidCRL # policyConstExtError # policyExtError # policyInhibitExtError # policyMapExtError # policyQualifierError # processLengthConstError # pubKeyError # QcEuCompliance # QcLimitValueAlpha # QcLimitValueNum # QcSSCD # QcStatementExtError # QcUnknownStatement # revokedAfterValidation # rootKeyIsValidButNotATrustAnchor # signatureNotVerified # subjAltNameExtError # totalPathLength # trustAnchorIssuerError # trustDNInvalid # trustPubKeyError # unknown canl-c-3.0.0/src/canl.c0000644000015500017500000003572113017332511014321 0ustar tomcat6jenkins#include "canl_locl.h" #define tv_sub(a,b) {\ (a).tv_usec -= (b).tv_usec;\ (a).tv_sec -= (b).tv_sec;\ if ((a).tv_usec < 0) {\ (a).tv_sec--;\ (a).tv_usec += 1000000;\ }\ } static struct canl_mech *mechs[] = { &canl_mech_ssl, }; static void io_destroy(glb_ctx *cc, io_handler *io); static int init_io_content(glb_ctx *cc, io_handler *io); static int try_connect(glb_ctx *glb_cc, io_handler *io_cc, char *addr, int addrtype, int port, struct timeval *timeout); canl_ctx canl_create_ctx() { glb_ctx *ctx = NULL; int i; /*create context*/ ctx = (glb_ctx *) calloc(1, sizeof(*ctx)); if (!ctx) return NULL; for (i = 0; i < sizeof(mechs)/sizeof(mechs[0]); i++) mechs[i]->initialize(ctx); /*TODO every mech must have its own ctx*/ return ctx; } void canl_free_ctx(canl_ctx cc) { glb_ctx *ctx = (glb_ctx*) cc; struct canl_mech *mech = find_mech(GSS_C_NO_OID); if (!cc) return; /*delete content*/ if (ctx->err_msg) { free(ctx->err_msg); ctx->err_msg = NULL; } /*TODO delete ctx content for real*/ if (mech) mech->free_ctx(ctx); if (ctx->err_msg){ free(ctx->err_msg); ctx->err_msg = NULL; } free(ctx); } canl_err_code canl_create_io_handler(canl_ctx cc, canl_io_handler *io) { io_handler *new_io_h = NULL; glb_ctx *g_cc = cc; int err = 0; if (!g_cc) return EINVAL; if (!io) return set_error(g_cc, EINVAL, POSIX_ERROR, "IO handler not" " initialized"); /*create io handler*/ new_io_h = (io_handler *) calloc(1, sizeof(*new_io_h)); if (!new_io_h) return set_error(g_cc, ENOMEM, POSIX_ERROR, "Not enough memory"); /* allocate memory and initialize io content*/ if ((err = init_io_content(g_cc, new_io_h))){ free(new_io_h); return err; } *io = new_io_h; return 0; } static int init_io_content(glb_ctx *cc, io_handler *io) { io->oid = GSS_C_NO_OID; io->sock = -1; return 0; } canl_err_code canl_io_connect(canl_ctx cc, canl_io_handler io, const char *host, const char *service, int port, gss_OID_set auth_mechs, int flags, canl_principal *peer, struct timeval *timeout) { int err = 0; io_handler *io_cc = (io_handler*) io; glb_ctx *glb_cc = (glb_ctx*) cc; struct _asyn_result ar; int i = 0, k; int addr_types[] = {AF_INET, AF_INET6}; //TODO ip versions policy? int ipver = AF_INET6; int j = 0, done; struct canl_mech *mech; gss_OID oid; memset(&ar, 0, sizeof(ar)); if (!glb_cc) { return EINVAL; } if (!io_cc) return set_error(glb_cc, EINVAL, POSIX_ERROR, "IO handler not initialized"); done = 0; for (k = 0; k < sizeof(addr_types)/sizeof(*addr_types); k++) { ipver = addr_types[k]; if (ar.ent) { free_hostent(ar.ent); memset(&ar, 0, sizeof(ar)); } ar.ent = (struct hostent *) calloc (1, sizeof(struct hostent)); if (ar.ent == NULL) return set_error(cc, ENOMEM, POSIX_ERROR, "Not enough memory"); switch (err = canl_asyn_getservbyname(ipver, &ar, host, NULL)) { case NETDB_SUCCESS: err = 0; break; case TRY_AGAIN: err = update_error(glb_cc, ETIMEDOUT, POSIX_ERROR, " Timeout reached when connecting to (%s)", host); goto end; case NETDB_INTERNAL: err = update_error(glb_cc, errno, POSIX_ERROR, "Cannot resolve the server hostname (%s)", host); continue; default: err = update_error(glb_cc, err, NETDB_ERROR, "Cannot resolve the server hostname (%s)", host); continue; } j = 0; do { if (auth_mechs == GSS_C_NO_OID_SET || auth_mechs->count == 0) oid = GSS_C_NO_OID; else oid = &auth_mechs->elements[j]; mech = find_mech(oid); err = 0; for (i = 0; ar.ent->h_addr_list[i]; i++) { void *ctx = NULL; if (err == ETIMEDOUT) goto end; err = try_connect(glb_cc, io_cc, ar.ent->h_addr_list[i], ar.ent->h_addrtype, port, timeout);//TODO timeout if (err) continue; err = mech->client_init(glb_cc, &ctx); if (err) { canl_io_close(glb_cc, io_cc); continue; } err = mech->connect(glb_cc, io_cc, ctx, timeout, host); if (err) { canl_io_close(glb_cc, io_cc); mech->finish(glb_cc, ctx); ctx = NULL; continue; } io_cc->conn_ctx = ctx; done = 1; /* If peer != NULL then client certificate is mandatory*/ if (peer) { err = mech->get_peer(glb_cc, io_cc, ctx, peer); if (err) goto end; } break; } if (err == ETIMEDOUT) goto end; j++; } while (auth_mechs != GSS_C_NO_OID_SET && j < auth_mechs->count && !done); free_hostent(ar.ent); ar.ent = NULL; if (done) break; } if (!done) { err = ECONNREFUSED; goto end; } err = 0; end: if (err) /* XXX: rather invent own error */ err = update_error(glb_cc, ECONNREFUSED, POSIX_ERROR, "Failed to make network connection to server %s", host); if (ar.ent != NULL) free_hostent(ar.ent); return err; } /* try to connect to addr with port (both ipv4 and 6) * return 0 when successful * errno otherwise*/ /* XXX use set_error on errors and return a CANL return code */ static int try_connect(glb_ctx *glb_cc, io_handler *io_cc, char *addr, int addrtype, int port, struct timeval *timeout) { struct sockaddr_storage a; struct sockaddr_storage *p_a=&a; socklen_t a_len; socklen_t err_len; int sock; int sock_err; struct timeval before,after,to; struct sockaddr_in *p4 = (struct sockaddr_in *)p_a; struct sockaddr_in6 *p6 = (struct sockaddr_in6 *)p_a; memset(p_a, 0, sizeof *p_a); p_a->ss_family = addrtype; switch (addrtype) { case AF_INET: memcpy(&p4->sin_addr, addr, sizeof(struct in_addr)); p4->sin_port = htons(port); a_len = sizeof (struct sockaddr_in); break; case AF_INET6: memcpy(&p6->sin6_addr, addr, sizeof(struct in6_addr)); p6->sin6_port = htons(port); a_len = sizeof (struct sockaddr_in6); break; default: return update_error(glb_cc, EINVAL, POSIX_ERROR, "Unsupported address type (%d)", addrtype); break; } sock = socket(a.ss_family, SOCK_STREAM, 0); if (sock == -1) return update_error(glb_cc, errno, POSIX_ERROR, "Failed to create network socket"); /* TODO from L&B; do we need it? opt = 1; setsockopt(sock,IPPROTO_TCP,TCP_NODELAY,&opt,sizeof opt); */ if (timeout) { int flags = fcntl(sock, F_GETFL, 0); if (fcntl(sock, F_SETFL, flags | O_NONBLOCK) < 0) return update_error(glb_cc, errno, POSIX_ERROR, "Failed to set socket file status flags"); gettimeofday(&before,NULL); } if (connect(sock,(struct sockaddr *) &a, a_len) < 0) { if (timeout && errno == EINPROGRESS) { fd_set fds; FD_ZERO(&fds); FD_SET(sock, &fds); /*TODO why don't we use timeout explicitly?*/ memcpy(&to, timeout, sizeof to); gettimeofday(&before, NULL); switch (select(sock+1, NULL, &fds, NULL, &to)) { case -1: close(sock); return update_error(glb_cc, errno, POSIX_ERROR, "Connection error"); case 0: close(sock); timeout->tv_sec = 0; timeout->tv_usec = 0; return update_error(glb_cc, errno, POSIX_ERROR, "Connection timeout reached"); } gettimeofday(&after, NULL); tv_sub(after, before); tv_sub(*timeout, after); err_len = sizeof sock_err; if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &sock_err, &err_len)) { close(sock); return update_error(glb_cc, errno, POSIX_ERROR, "Cannost get socket options"); } if (sock_err) { close(sock); errno = sock_err; return update_error(glb_cc, errno, POSIX_ERROR, "Connection error"); } } else { close(sock); return update_error(glb_cc, errno, POSIX_ERROR, "Connection error"); } } io_cc->sock = sock; return 0; } /*TODO select + timeout, EINTR!!! */ canl_err_code canl_io_accept(canl_ctx cc, canl_io_handler io, int new_fd, struct sockaddr s_addr, int flags, canl_principal *peer, struct timeval *timeout) { int err = 0; io_handler *io_cc = (io_handler*) io; glb_ctx *glb_cc = (glb_ctx*) cc; struct canl_mech *mech = find_mech(GSS_C_NO_OID); void *conn_ctx = NULL; if (!glb_cc) return EINVAL; /* XXX Should rather be a CANL error */ if (!io_cc) return set_error(cc, EINVAL, POSIX_ERROR, "IO handler not initialized"); io_cc->sock = new_fd; err = mech->server_init(glb_cc, &conn_ctx); if (err) goto end; err = mech->accept(glb_cc, io_cc, conn_ctx, timeout); if (err) goto end; /* If peer != NULL then client certificate is mandatory*/ if (peer) { err = mech->get_peer(glb_cc, io_cc, conn_ctx, peer); if (err) goto end; } io_cc->conn_ctx = conn_ctx; io_cc->oid = GSS_C_NO_OID; err = 0; end: if (err) { (io_cc)->sock = -1; if (conn_ctx) mech->finish(glb_cc, conn_ctx); } return err; } /* close connection, preserve some info for the future reuse */ canl_err_code canl_io_close(canl_ctx cc, canl_io_handler io) { io_handler *io_cc = (io_handler*) io; glb_ctx *glb_cc = (glb_ctx*) cc; int err = 0; canl_mech *mech; /*check cc and io*/ if (!cc) { return EINVAL; /* XXX Should rather be a CANL error */ } if (!io) return set_error(cc, EINVAL, POSIX_ERROR, "IO handler not initialized"); if (io_cc->conn_ctx) { mech = find_mech(io_cc->oid); mech->close(glb_cc, io, io_cc->conn_ctx); /* XXX can it be safely reopened ?*/ } if (io_cc->sock != -1) { close (io_cc->sock); io_cc->sock = -1; } return err; } static void io_destroy(glb_ctx *cc, io_handler *io) { io_handler *io_cc = (io_handler*) io; canl_mech *mech; if (io == NULL) return; if (io_cc->conn_ctx) { mech = find_mech(io->oid); mech->finish(cc, io_cc->conn_ctx); io_cc->conn_ctx = NULL; io_cc->oid = GSS_C_NO_OID; } return; } canl_err_code canl_io_destroy(canl_ctx cc, canl_io_handler io) { int err = 0; glb_ctx *glb_cc = (glb_ctx*) cc; io_handler *io_cc = (io_handler*) io; /*check cc and io*/ if (!glb_cc) { return EINVAL; /* XXX Should rather be a CANL error */ } if (!io_cc) return set_error(glb_cc, EINVAL, POSIX_ERROR, "Invalid io handler"); canl_io_close(cc, io); io_destroy(glb_cc, io_cc); free (io_cc); return err; } /* XXX: 0 returned returned by ssl_read() means error or EOF ? */ size_t canl_io_read(canl_ctx cc, canl_io_handler io, void *buffer, size_t size, struct timeval *timeout) { io_handler *io_cc = (io_handler*) io; glb_ctx *glb_cc = (glb_ctx*) cc; int b_recvd = 0; struct canl_mech *mech; if (!cc) return -1; if (!io) { set_error(cc, EINVAL, POSIX_ERROR, "IO handler not initialized"); return -1; } if (io_cc->conn_ctx == NULL) return set_error(cc, EINVAL, POSIX_ERROR, "Connection not secured"); if (!buffer || !size) { set_error(cc, EINVAL, POSIX_ERROR, "No memory to write into"); return -1; } mech = find_mech(io_cc->oid); b_recvd = mech->read(glb_cc, io_cc, io_cc->conn_ctx, buffer, size, timeout); return b_recvd; } size_t canl_io_write(canl_ctx cc, canl_io_handler io, void *buffer, size_t size, struct timeval *timeout) { io_handler *io_cc = (io_handler*) io; glb_ctx *glb_cc = (glb_ctx*) cc; int b_written = 0; struct canl_mech *mech; if (!cc) return -1; if (!io) { set_error(cc, EINVAL, POSIX_ERROR, "IO handler not initialized"); return -1; } if (io_cc->conn_ctx == NULL) return set_error(cc, EINVAL, POSIX_ERROR, "Connection not secured"); if (!buffer || !size) { set_error(cc, EINVAL, POSIX_ERROR, "No memory to read from"); return -1; } mech = find_mech(io_cc->oid); b_written = mech->write(glb_cc, io_cc, io_cc->conn_ctx, buffer, size, timeout); return b_written; } #if 0 int canl_set_ctx_own_cert(canl_ctx cc, canl_x509 cert, canl_stack_of_x509 chain, canl_pkey key) { glb_ctx *glb_cc = (glb_ctx*) cc; int err = 0; if (!cc) return EINVAL; if(!cert) return set_error(glb_cc, EINVAL, POSIX_ERROR, "invalid" "parameter value"); err = do_set_ctx_own_cert(glb_cc, cert, chain, key); if(err) { update_error(glb_cc, "can't set cert or key to context"); } return err; } //TODO callback and userdata process int canl_set_ctx_own_cert_file(canl_ctx cc, char *cert, char *key, canl_password_callback cb, void *userdata) { glb_ctx *glb_cc = (glb_ctx*) cc; int err = 0; if (!cc) return EINVAL; if(!cert ) { set_error(glb_cc, EINVAL, POSIX_ERROR, "invalid parameter value"); return EINVAL; } err = do_set_ctx_own_cert_file(glb_cc, cert, key); if(err) { update_error(glb_cc, "can't set cert or key to context"); } return err; } #endif struct canl_mech * find_mech(gss_OID oid) { /* XXX */ return &canl_mech_ssl; } canl_err_code canl_princ_name(canl_ctx cc, const canl_principal princ, char **name) { struct _principal_int *p = (struct _principal_int *) princ; if (cc == NULL) return EINVAL; if (princ == NULL) return set_error(cc, EINVAL, POSIX_ERROR, "Principal not initialized"); if (name == NULL) return set_error(cc, EINVAL, POSIX_ERROR, "invalid parameter value"); *name = strdup(p->name); if (*name == NULL) return set_error(cc, ENOMEM, POSIX_ERROR, "not enough memory"); return 0; } void canl_princ_free(canl_ctx cc, canl_principal princ) { struct _principal_int *p = (struct _principal_int *) princ; if (cc == NULL) return; if (princ == NULL) return; if (p->name) free(p->name); free(princ); return; } canl_err_code CANL_CALLCONV canl_ctx_set_pkcs11_lib(canl_ctx ctx, const char *lib) { setenv("PKCS11_LIB", lib, 1); return 0; } canl_err_code CANL_CALLCONV canl_ctx_set_pkcs11_init_args(canl_ctx ctx, const char *args) { setenv("PKCS11_INIT_ARGS", args, 1); return 0; } canl-c-3.0.0/src/canl_cert.c0000644000015500017500000001321313017332512015327 0ustar tomcat6jenkins#include "canl_locl.h" #include "canl_mech_ssl.h" #if 0 static int set_cert(glb_ctx *cc, X509 *cert); //TODO just stub int do_set_ctx_own_cert(glb_ctx *cc, canl_x509 cert, canl_stack_of_x509 chain, canl_pkey key) { int err = 0; X509 *l_cert = (X509 *) cert; STACK_OF(X509*) *l_chain = (STACK_OF(X509*)*) chain; EVP_PKEY *l_key = (EVP_PKEY *)key; /* if (cert) set_cert(l_cert); cert if (chain) is_chain = 1; if (key) is_key = 1; if (!m_ctx->cert_key){ m_ctx->cert_key = (cert_key_store *) calloc(1, sizeof(*(m_ctx->cert_key))); if (!m_ctx->cert_key) { err = ENOMEM; goto end; } } if (!m_ctx->cert_key->cert) { } */ return 0; } static int set_cert(glb_ctx *cc, X509 *cert) { int err = 0; CANL_ERROR_ORIGIN err_orig = 0; if (m_ctx->cert_key->cert) { free(m_ctx->cert_key->cert); m_ctx->cert_key->cert = NULL; } m_ctx->cert_key->cert = (X509 *) malloc (sizeof(X509)); if (!m_ctx->cert_key->cert) { err = ENOMEM; goto end; } end: if (err) set_error(cc, err, err_orig, "cannot get certificate"); return err; } #endif //TODO cert int do_set_ctx_own_cert_file(glb_ctx *cc, mech_glb_ctx *m_ctx, char *cert, char *key, char *proxy) { int err = 0; if (!m_ctx->cert_key){ m_ctx->cert_key = (cert_key_store *) calloc(1, sizeof(*(m_ctx->cert_key))); if (!m_ctx->cert_key) { return set_error(cc, ENOMEM, POSIX_ERROR, "not enought memory" " for the certificate storage"); } } if (key) { err = set_key_file(cc, &m_ctx->cert_key->key, key); if (err) return err; } if (cert) { err = set_cert_file(cc, &m_ctx->cert_key->cert, cert); if (err) return err; } if (proxy) { err = load_credentials(proxy, proxy, &m_ctx->cert_key->cert, &m_ctx->cert_key->chain, &m_ctx->cert_key->key, NULL); if (!err) return err; } return 0; } int set_key_file(glb_ctx *cc, EVP_PKEY **to, const char *key) { unsigned long ssl_err = 0; int err = 0; FILE * key_file = NULL; if (*to) { EVP_PKEY_free(*to); *to = NULL; } key_file = fopen(key, "rb"); if (!key_file) { err = errno; set_error(cc, err, POSIX_ERROR, "cannot open file with key"); return err; } ERR_clear_error(); /*TODO NULL NULL, callback and user data*/ *to = PEM_read_PrivateKey(key_file, NULL, NULL, NULL); if (!(*to)) { ssl_err = ERR_peek_error(); err = set_error(cc, ssl_err, SSL_ERROR, "Cannot read the key " "from the file"); goto end; } if (fclose(key_file)){ err = errno; set_error(cc, err, POSIX_ERROR, "cannot close file with key"); return errno; } return 0; end: if (fclose(key_file)){ err = errno; update_error(cc, errno, POSIX_ERROR, "cannot close file with key"); } return err; } int set_cert_file(glb_ctx *cc, X509 **to, const char *cert) { unsigned long ssl_err = 0; int err = 0; FILE * cert_file = NULL; if (*to) { X509_free(*to); *to = NULL; } cert_file = fopen(cert, "rb"); if (!cert_file) { err = errno; set_error(cc, err, POSIX_ERROR, "cannot open file with cert"); return err; } ERR_clear_error(); /*TODO NULL NULL, callback and user data*/ *to = PEM_read_X509(cert_file, NULL, NULL, NULL); if (!(*to)) { ssl_err = ERR_get_error(); err = set_error(cc, ssl_err, SSL_ERROR, "error while writing certificate" " to context"); goto end; } if (fclose(cert_file)){ err = errno; set_error(cc, err, POSIX_ERROR, "cannot close file with certificate"); return errno; } return 0; end: if (fclose(cert_file)){ err = errno; update_error(cc, errno, POSIX_ERROR, "cannot close file with certificate"); } return err; } int set_cert_chain_file(glb_ctx *cc, STACK_OF(X509) **to, const char *file) { unsigned long ssl_err = 0; FILE * cert_file = NULL; int count = 0; int ret = -1; X509 *x = NULL; if (file == NULL) return set_error(cc, EINVAL, POSIX_ERROR, "Cert. chain file" "does not exist"); if (*to) { sk_X509_pop_free(*to, X509_free); *to = NULL; } cert_file = fopen(file, "rb"); if (!cert_file) return set_error(cc, errno, POSIX_ERROR, "Cannot " "open the file with the cert. chain"); for (;;) { /* TODO maybe callback can be specified*/ x = PEM_read_X509(cert_file,NULL, NULL, NULL); if (x == NULL) { ssl_err = ERR_peek_error(); if ((ERR_GET_REASON(ssl_err) == PEM_R_NO_START_LINE)) { /*everything OK*/ if ((count > 0)) { ERR_clear_error(); break; } else { ret = set_error(cc, ssl_err, SSL_ERROR, "Cannot read" " the certificate from the file"); goto end; } } } (void)sk_X509_insert(*to, x, sk_X509_num(*to)); x = NULL; count++; } return 0; end: if (fclose(cert_file)){ ret = errno; return update_error(cc, errno, POSIX_ERROR, "cannot close file with" " the certificate"); } return ret; } canl-c-3.0.0/src/canl_cred.c0000644000015500017500000006026113017332512015314 0ustar tomcat6jenkins#include "canl_locl.h" #include "canl_cred.h" #include "canl_mech_ssl.h" #include "scutils.h" #define DEF_KEY_LEN 1024 #define DEF_KEY_LEN_LONGER 2048 #define LIFETIME_TRESHOLD 10*24*60*60 //10 days static STACK_OF(X509)* my_sk_X509_dup(glb_ctx *cc, STACK_OF(X509) *stack); extern int proxy_verify_cert_chain(X509 * ucert, STACK_OF(X509) * cert_chain, canl_proxy_verify_desc * pvd); extern canl_proxy_verify_desc *canl_pvd_setup_initializers(char *cadir, char *ocsp_url, unsigned int flags); extern void canl_pvd_destroy_initializers(void *data); extern canl_error map_verify_result(unsigned long ssl_err, const X509_STORE_CTX *store_ctx, SSL *ssl); static STACK_OF(X509)* my_sk_X509_dup(glb_ctx *cc, STACK_OF(X509) *stack) { int count = 0; X509 *cert_from_chain = NULL; STACK_OF(X509) *new_chain = NULL; int i = 0; if (!stack) return NULL; count = sk_X509_num(stack); if (!count) return NULL; new_chain = sk_X509_new_null(); if (!new_chain) return NULL; for (i = 0; i < count; i++){ cert_from_chain = sk_X509_value(stack, i); if (cert_from_chain) { sk_X509_push(new_chain, X509_dup(cert_from_chain)); } } return new_chain; } canl_err_code CANL_CALLCONV canl_cred_new(canl_ctx ctx, canl_cred * cred) { glb_ctx *cc = ctx; creds *crd = NULL; if (!ctx) return EINVAL; if (!cred) return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" " not initialized" ); /*create new cred. handler*/ crd = (creds *) calloc(1, sizeof(*crd)); if (!crd) return set_error(cc, ENOMEM, POSIX_ERROR, "Not enough memory"); *cred = crd; return 0; } canl_err_code CANL_CALLCONV canl_cred_free(canl_ctx ctx, canl_cred cred) { glb_ctx *cc = (glb_ctx*) ctx; creds *crd = (creds*) cred; if (!ctx) return EINVAL; if (!cred) return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" " not initialized" ); /* Delete contents*/ if (crd->c_key) { EVP_PKEY_free(crd->c_key); crd->c_key = NULL; } if (crd->c_cert) { X509_free(crd->c_cert); crd->c_cert = NULL; } if (crd->c_cert_ext) { sk_X509_EXTENSION_pop_free(crd->c_cert_ext, X509_EXTENSION_free); crd->c_cert_ext = NULL; } if (crd->c_cert_chain) { sk_X509_pop_free(crd->c_cert_chain, X509_free); crd->c_cert_chain = NULL; } if (crd->c_req) { X509_REQ_free(crd->c_req); crd->c_req = NULL; } free (crd); crd = NULL; return 0; } canl_err_code CANL_CALLCONV canl_ctx_set_cred(canl_ctx ctx, canl_cred cred) { glb_ctx *cc = (glb_ctx*) ctx; creds *crd = (creds*) cred; mech_glb_ctx *m_ctx = (mech_glb_ctx *)cc->mech_ctx; if (!ctx) return EINVAL; if (!m_ctx) return set_error(cc, EINVAL, POSIX_ERROR, "SSL context not" " initialized"); if (!crd || !m_ctx->cert_key) return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" " not initialized" ); if (!m_ctx->cert_key){ m_ctx->cert_key = (cert_key_store *) calloc(1, sizeof(*(m_ctx->cert_key))); if (!m_ctx->cert_key) { return set_error(cc, ENOMEM, POSIX_ERROR, "not enought memory" " for the certificate storage"); } } if (crd->c_key) pkey_dup(&m_ctx->cert_key->key, crd->c_key); if (crd->c_cert) m_ctx->cert_key->cert = X509_dup(crd->c_cert); if (crd->c_cert_chain) m_ctx->cert_key->chain = my_sk_X509_dup(cc, crd->c_cert_chain); return 0; } void pkey_dup(EVP_PKEY **to, EVP_PKEY *from) { EVP_PKEY_up_ref(from); *to = from; } canl_err_code CANL_CALLCONV canl_cred_load_priv_key_file(canl_ctx ctx, canl_cred cred, const char *pkey_file, canl_password_callback pass_clb, void *arg) { glb_ctx *cc = (glb_ctx*) ctx; creds *crd = (creds*) cred; int ret = 0; if (!ctx) return EINVAL; if (!cred) return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" " not initialized" ); if (!pkey_file) return set_error(cc, EINVAL, POSIX_ERROR, "Invalid filename"); ret = set_key_file(cc, &crd->c_key, pkey_file); return ret; } canl_err_code CANL_CALLCONV canl_cred_save_priv_key(canl_ctx ctx, canl_cred cred, EVP_PKEY **pkey) { glb_ctx *cc = (glb_ctx*) ctx; creds *crd = (creds*) cred; int ret = 0; if (!ctx) return EINVAL; if (!cred) return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" " not initialized" ); if (!pkey) return set_error(cc, EINVAL, POSIX_ERROR, "Invalid private key" " parameter"); pkey_dup(pkey, crd->c_key); return ret; } canl_err_code CANL_CALLCONV canl_cred_load_priv_key(canl_ctx ctx, canl_cred cred, EVP_PKEY *pkey) { glb_ctx *cc = (glb_ctx*) ctx; creds *crd = (creds*) cred; int ret = 0; if (!ctx) return EINVAL; if (!cred) return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" " not initialized" ); if (!pkey) return set_error(cc, EINVAL, POSIX_ERROR, "Invalid private key" " parameter"); pkey_dup(&crd->c_key, pkey); return ret; } canl_err_code CANL_CALLCONV canl_cred_load_chain(canl_ctx ctx, canl_cred cred, STACK_OF(X509) *cert_stack) { glb_ctx *cc = (glb_ctx*) ctx; creds *crd = (creds*) cred; int count = 0; if (!ctx) return EINVAL; if (!cred) return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" " not initialized" ); if (!cert_stack) return set_error(cc, EINVAL, POSIX_ERROR, "Invalid stack value"); count = sk_X509_num(cert_stack); if (!count) return 0; //TODO is empty cert_stack error? if (crd->c_cert_chain) { sk_X509_pop_free(crd->c_cert_chain, X509_free); crd->c_cert_chain = NULL; } crd->c_cert_chain = my_sk_X509_dup(cc, cert_stack); if (!crd->c_cert_chain) return set_error(cc, ENOMEM, POSIX_ERROR, "Cannot copy" " certificate chain" ); //TODO check ret val return 0; } canl_err_code CANL_CALLCONV canl_cred_load_chain_file(canl_ctx ctx, canl_cred cred, const char *chain_file) { glb_ctx *cc = (glb_ctx*) ctx; creds *crd = (creds*) cred; if (!ctx) return EINVAL; if (!cred) return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" " not initialized" ); if (!chain_file) return set_error(cc, EINVAL, POSIX_ERROR, "Invalid chain filename"); if (crd->c_cert_chain) { sk_X509_pop_free(crd->c_cert_chain, X509_free); crd->c_cert_chain = NULL; } else crd->c_cert_chain = sk_X509_new_null(); return set_cert_chain_file(cc, &crd->c_cert_chain, chain_file); } canl_err_code CANL_CALLCONV canl_cred_load_cert(canl_ctx ctx, canl_cred cred, X509 *cert) { glb_ctx *cc = (glb_ctx*) ctx; creds *crd = (creds*) cred; if (!ctx) return EINVAL; if (!cred) return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" " not initialized" ); if (!cert) return set_error(cc, EINVAL, POSIX_ERROR, "Invalid cert. file name"); if (crd->c_cert) { X509_free(crd->c_cert); crd->c_cert = NULL; } crd->c_cert = X509_dup(cert); if (!crd->c_cert) return set_error(cc, ENOMEM, POSIX_ERROR, "Cannot copy" " certificate" ); //TODO check ret val return 0; } canl_err_code CANL_CALLCONV canl_cred_load_cert_file(canl_ctx ctx, canl_cred cred, const char *cert_file) { glb_ctx *cc = (glb_ctx*) ctx; creds *crd = (creds*) cred; int ret = 0; if (!ctx) return EINVAL; if (!cred) return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" " not initialized" ); if (!cert_file) return set_error(cc, EINVAL, POSIX_ERROR, "Invalid filename"); ret = set_cert_file(cc, &crd->c_cert, cert_file); return ret; } canl_err_code CANL_CALLCONV canl_cred_set_lifetime(canl_ctx ctx, canl_cred cred, const long lifetime) { glb_ctx *cc = (glb_ctx*) ctx; creds *crd = (creds*) cred; if (!ctx) return EINVAL; if (!cred) return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" " not initialized" ); crd->c_lifetime = lifetime; return 0; } /*TODO rather use STACK_OF(X509_EXTENSION) ???*/ canl_err_code CANL_CALLCONV canl_cred_set_extension(canl_ctx ctx, canl_cred cred, X509_EXTENSION *cert_ext) { glb_ctx *cc = (glb_ctx*) ctx; creds *crd = (creds*) cred; if (!ctx) return EINVAL; if (!cred) return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" " not initialized" ); if (!cert_ext) return 0; //TODO is it error? I guesss no. if (!crd->c_cert_ext) crd->c_cert_ext = sk_X509_EXTENSION_new_null(); sk_X509_EXTENSION_push(crd->c_cert_ext, X509_EXTENSION_dup(cert_ext)); return 0; } canl_err_code CANL_CALLCONV canl_cred_set_cert_type(canl_ctx ctx, canl_cred cred, const enum canl_cert_type cert_type) { glb_ctx *cc = (glb_ctx*) ctx; creds *crd = (creds*) cred; if (!ctx) return EINVAL; if (!cred) return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" " not initialized" ); crd->c_type = cert_type; return 0; } /*TODO use flags*/ canl_err_code CANL_CALLCONV canl_cred_sign_proxy(canl_ctx ctx, canl_cred signer_cred, canl_cred proxy_cred) { glb_ctx *cc = (glb_ctx*) ctx; creds *signer_crd = (creds*) signer_cred; creds *proxy_crd = (creds*) proxy_cred; int err = 0; #if 0 int key_size = 0; #endif int proxyver; if (!ctx) return EINVAL; if (!signer_crd) return set_error(cc, EINVAL, POSIX_ERROR, "Signer cred. handler" " not initialized" ); if (!proxy_crd) return set_error(cc, EINVAL, POSIX_ERROR, "Proxy cred. handler" " not initialized" ); #if 0 #This part of the code was mentioned to check for the unpropriate key size with #respect to the certificate validity period. The LIFETIME_TRESHOLD should # not be hardwired in the code (or may not be there at all). if (proxy_crd->c_req) { EVP_PKEY *tmp_key = X509_REQ_get_pubkey(proxy_crd->c_req); if (!tmp_key) return set_error(cc, CANL_ERR_unknown, CANL_ERROR, "Cannot" "extract key out of the certificate request" ); key_size = EVP_PKEY_size(tmp_key); /*TODO free tmp_key? is it duplicate or poiter? */ if ((proxy_crd->c_lifetime > LIFETIME_TRESHOLD) && (key_size <= DEF_KEY_LEN_LONGER)) return set_error(cc, CANL_ERR_unknown, CANL_ERROR, "Cannot" "sign cert. request -the key is too short with " "respect to cert. lifetime"); } #endif switch (proxy_crd->c_type){ case CANL_EEC: proxyver = 2; break; case CANL_RFC: proxyver = 3; break; default: proxyver = 2; break; } /*TODO flags - limited,version*/ err = proxy_sign(signer_crd->c_cert, signer_crd->c_key, proxy_crd->c_req, &proxy_crd->c_cert, proxy_crd->c_lifetime, proxy_crd->c_cert_ext, 0, proxyver, NULL, NULL, 0, NULL, 0); if (err) return set_error(cc, CANL_ERR_unknown, CANL_ERROR, ""); /*concatenate new chain*/ if (signer_crd->c_cert_chain) proxy_crd->c_cert_chain = my_sk_X509_dup(cc, signer_crd->c_cert_chain); if (!proxy_crd->c_cert_chain) proxy_crd->c_cert_chain = sk_X509_new_null(); sk_X509_push(proxy_crd->c_cert_chain, X509_dup(signer_crd->c_cert)); return 0; } canl_err_code CANL_CALLCONV canl_cred_save_proxyfile(canl_ctx ctx, canl_cred cred, const char *proxy_file) { glb_ctx *cc = (glb_ctx*) ctx; creds *crd = (creds*) cred; FILE *cert_file = NULL; int ret = 0; int o_ret = 0; unsigned long ssl_err = 0; int n_certs = 0; int i = 0; X509 *cert_from_chain = NULL; int cert_in_chain = 0; if (!ctx) return EINVAL; if (!cred) return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" " not initialized" ); if (!proxy_file) return set_error(cc, EINVAL, POSIX_ERROR, "Invalid proxy file name"); /*posix compliant*/ o_ret = open(proxy_file, O_CREAT | O_EXCL |O_WRONLY, S_IRUSR | S_IWUSR); if (o_ret == -1){ ret = errno; set_error(cc, ret, POSIX_ERROR, "Cannot open file for writing"); } else { ret = close(o_ret); if (ret == -1){ ret = errno; set_error(cc, ret, POSIX_ERROR, "Cannot close file for writing"); return ret; } } if (o_ret) cert_file = fopen(proxy_file, "wb"); else cert_file = fopen(proxy_file, "ab"); if (!cert_file) { ret = errno; set_error(cc, ret, POSIX_ERROR, "cannot open file for writing"); return ret; } ERR_clear_error(); /*new cert + priv key + chain if the new cert is empty, take it from the chain*/ if (crd->c_cert){ ret = PEM_write_X509(cert_file, crd->c_cert); if (!ret) { ssl_err = ERR_get_error(); if (ssl_err) ret = set_error(cc, ssl_err, SSL_ERROR, "Error while writing" " the certificate to the file"); goto end; } } else if (crd->c_cert_chain){ cert_from_chain = sk_X509_value(crd->c_cert_chain, 0); if (cert_from_chain) { ret = PEM_write_X509(cert_file, cert_from_chain); if (!ret) { ssl_err = ERR_get_error(); if (ssl_err) ret = set_error(cc, ssl_err, SSL_ERROR, "Error " " while writing the certificate to the file"); goto end; } cert_in_chain = 1; } } ret = PEM_write_PrivateKey(cert_file, crd->c_key, NULL, NULL, 0, 0, NULL); if (!ret) { ssl_err = ERR_get_error(); ret = set_error(cc, ssl_err, SSL_ERROR, "Error while writing" " the key to the file"); goto end; } n_certs = sk_X509_num(crd->c_cert_chain); for (i = cert_in_chain; i < n_certs; i++){ cert_from_chain = sk_X509_value(crd->c_cert_chain, i); if (cert_from_chain) { ret = PEM_write_X509(cert_file, cert_from_chain); if (!ret) { ssl_err = ERR_get_error(); if (ssl_err) ret = set_error(cc, ssl_err, SSL_ERROR, "Error " " while writing the certificate to the file"); goto end; } } } if (fclose(cert_file)){ ret = errno; set_error(cc, ret, POSIX_ERROR, "cannot close file with certificate"); return errno; } return 0; end: if (fclose(cert_file)){ ret = errno; update_error(cc, ret, POSIX_ERROR, "cannot close file" " with certificate"); return errno; } return ret; } canl_err_code CANL_CALLCONV canl_cred_save_cert(canl_ctx ctx, canl_cred cred, X509 ** cert) { glb_ctx *cc = (glb_ctx*) ctx; creds *crd = (creds*) cred; if (!ctx) return EINVAL; if (!cred) return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" " not initialized" ); if (!cert) return set_error(cc, EINVAL, POSIX_ERROR, "Invalid cert." " handler"); if (*cert) { *cert = NULL; } *cert = X509_dup(crd->c_cert); if (!(*cert)) return set_error(cc, ENOMEM, POSIX_ERROR, "Cannot copy" " certificate" ); //TODO check ret val return 0; } canl_err_code CANL_CALLCONV canl_cred_save_chain(canl_ctx ctx, canl_cred cred, STACK_OF(X509) **cert_stack) { glb_ctx *cc = (glb_ctx*) ctx; creds *crd = (creds*) cred; int count = 0; if (!ctx) return EINVAL; if (!cred) return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" " not initialized" ); if (!cert_stack) return set_error(cc, EINVAL, POSIX_ERROR, "Invalid stack value"); if (!crd->c_cert_chain) return 0; //TODO is empty cert_stack error? count = sk_X509_num(crd->c_cert_chain); if (!count) return 0; //TODO is empty cert_stack error? if (*cert_stack) { sk_X509_pop_free(*cert_stack, X509_free); *cert_stack = NULL; } *cert_stack = my_sk_X509_dup(cc, crd->c_cert_chain); if (!(*cert_stack)) return set_error(cc, ENOMEM, POSIX_ERROR, "Cannot copy" " certificate chain" ); //TODO check ret val return 0; } /* handle requests*/ canl_err_code CANL_CALLCONV canl_cred_new_req(canl_ctx ctx, canl_cred ret_req, unsigned int bits) { glb_ctx *cc = (glb_ctx*) ctx; creds *crd_req = (creds*) ret_req; int ret = 0; int in_bits = DEF_KEY_LEN; if (!ctx) return EINVAL; if (bits) in_bits = bits; /*set longer key if lifetime is long enough*/ else if (crd_req->c_lifetime > LIFETIME_TRESHOLD) in_bits = DEF_KEY_LEN_LONGER; if (!ret_req) return set_error(cc, EINVAL, POSIX_ERROR, "Cred. handler" " not initialized" ); if (crd_req->c_req) { X509_REQ_free(crd_req->c_req); crd_req->c_req = NULL; } /*TODO 1st NULL may invoke callback to ask user for new name*/ ret = proxy_genreq(NULL, &crd_req->c_req, &crd_req->c_key, in_bits, NULL, NULL); if (ret) return set_error(cc, CANL_ERR_unknown, CANL_ERROR, "Cannot make new" "proxy certificate"); return 0; } canl_err_code CANL_CALLCONV canl_cred_save_req(canl_ctx ctx, canl_cred req_in, X509_REQ ** req_ret) { glb_ctx *cc = (glb_ctx*) ctx; creds *req = (creds*) req_in; if (!ctx) return EINVAL; if (!req || !req->c_req) return set_error(cc, EINVAL, POSIX_ERROR, "Request handler" " not initialized" ); if (!req_ret) return set_error(cc, EINVAL, POSIX_ERROR, "Request handler" " not initialized" ); /*TODO free REQ if req_ret full*/ *req_ret = X509_REQ_dup(req->c_req); if (!(*req_ret)) return set_error(cc, ENOMEM, POSIX_ERROR, "Cannot copy" " X509 request handler" ); //TODO check ret val return 0; } canl_err_code CANL_CALLCONV canl_cred_load_req(canl_ctx ctx, canl_cred cred_out, const X509_REQ *req_in) { glb_ctx *cc = (glb_ctx*) ctx; creds *req = (creds*) cred_out; if (!ctx) return EINVAL; if (!req) return set_error(cc, EINVAL, POSIX_ERROR, "Request handler" " not initialized" ); if (!req_in) return set_error(cc, EINVAL, POSIX_ERROR, "Request handler" " not initialized" ); if (req->c_req) { X509_REQ_free(req->c_req); req->c_req = NULL; } req->c_req = X509_REQ_dup(req_in); if (!req->c_req) return set_error(cc, ENOMEM, POSIX_ERROR, "Cannot copy" " X509 request handler" ); //TODO check ret val return 0; } canl_err_code CANL_CALLCONV canl_verify_chain(canl_ctx ctx, X509 *ucert, STACK_OF(X509) *cert_chain, char *cadir) { int ret = 0; canl_proxy_verify_desc *pvd = NULL; /* verification context */ pvd = canl_pvd_setup_initializers(cadir, NULL, 0); ret = proxy_verify_cert_chain(ucert, cert_chain, pvd); canl_pvd_destroy_initializers(pvd); if (!ret) /* This will be ommited when proxy_verify_cert sets errors itself or propagate them out. */ return set_error(ctx, CANL_ERR_unknown, CANL_ERROR, "Certificate chain" " validation failed"); // TODO error code check return 0; } canl_err_code CANL_CALLCONV canl_verify_chain_wo_ossl(canl_ctx ctx, char *cadir, X509_STORE_CTX *store_ctx) { int ret = 0, depth = 0, i = 0; STACK_OF(X509) *certstack; canl_proxy_verify_desc *pvd = NULL; /* verification context */ unsigned long ssl_err = 0; canl_error canl_err = 0; pvd = canl_pvd_setup_initializers(cadir, NULL, 0); X509_STORE_CTX_set_ex_data(store_ctx, PVD_STORE_EX_DATA_IDX, (void *)pvd); #ifdef X509_V_FLAG_ALLOW_PROXY_CERTS X509_STORE_CTX_set_flags(store_ctx, X509_V_FLAG_ALLOW_PROXY_CERTS); #endif canl_pvd_destroy_initializers(pvd); certstack = X509_STORE_CTX_get_chain(store_ctx); depth = sk_X509_num(certstack); /*TODO maybe free() certstack? is it refferenced? */ ERR_clear_error(); /* Go through the client cert chain and check it */ for (i = depth - 1; i >= 0; i--){ ret = proxy_verify_callback(1, store_ctx); if (!ret){ /* Verification failed */ ssl_err = ERR_get_error(); canl_err = map_verify_result(ssl_err, store_ctx, NULL); if (canl_err) return set_error (ctx, canl_err, CANL_ERROR, "Error during SSL handshake"); else return set_error(ctx, ssl_err, SSL_ERROR, "Error during SSL handshake"); } } return 0; } canl_proxy_verify_desc *canl_pvd_setup_initializers(char *cadir, char *ocsp_url, unsigned int pvxd_flags) { canl_proxy_verify_ctx_desc *pvxd = NULL; canl_proxy_verify_desc *pvd = NULL; char *ca_cert_dirn = NULL; int err = 0; pvd = (canl_proxy_verify_desc*) malloc(sizeof(canl_proxy_verify_desc)); pvxd = (canl_proxy_verify_ctx_desc *)malloc(sizeof(canl_proxy_verify_ctx_desc)); pvd->cert_store = NULL; if (!pvd || !pvxd) { free(pvd); free(pvxd); return NULL; } canl_proxy_verify_ctx_init(pvxd); canl_proxy_verify_init(pvd, pvxd); /* If cadir is not specified, do the best as to get the standard CA certificates directory name */ if (!cadir){ err = proxy_get_filenames(0, NULL, &ca_cert_dirn, NULL, NULL, NULL); if (!err){ pvd->pvxd->certdir = ca_cert_dirn; return pvd; } } else pvd->pvxd->certdir = strdup(cadir); pvd->pvxd->flags |= pvxd_flags; if (ocsp_url) pvd->pvxd->ocsp_url = strdup(ocsp_url); return pvd; } void canl_pvd_destroy_initializers(void *data) { canl_proxy_verify_desc *pvd = (canl_proxy_verify_desc *)data; if (pvd) { if (pvd->pvxd) canl_proxy_verify_ctx_release(pvd->pvxd); free(pvd->pvxd); pvd->pvxd = NULL; canl_proxy_verify_release(pvd); /* X509_STORE_CTX_free segfaults if passed a NULL store_ctx */ if (pvd->cert_store) X509_STORE_CTX_free(pvd->cert_store); pvd->cert_store = NULL; free(pvd); } } #if 0 canl_err_code CANL_CALLCONV canl_req_get_pair(canl_ctx, canl_x509_req, EVP_PKEY **) { return ENOSYS; } #endif canl_err_code CANL_CALLCONV canl_cred_load_priv_key_pkcs11(canl_ctx ctx, canl_cred cred, const char *label, canl_password_callback pass_clb, void *arg) { #ifdef USE_PKCS11 int ret; creds *crd = (creds*) cred; unsigned long hSession; ret = sc_init(&hSession, NULL, NULL, NULL, CKU_USER, 0); if (ret) return set_error(ctx, EINVAL, POSIX_ERROR, "Failed to open session to smartcard"); ret = sc_get_priv_key_obj_by_label(hSession, label, &crd->c_key); if (ret) return set_error(ctx, EINVAL, POSIX_ERROR, "Failed to locate private key for '%s' on smartcard", label); return 0; #else return ENOSYS; #endif /* USE_PKCS11 */ } canl_err_code CANL_CALLCONV canl_cred_load_cert_pkcs11(canl_ctx ctx, canl_cred cred, const char *label) { #ifdef USE_PKCS11 int ret; creds *crd = (creds*) cred; unsigned long hSession; ret = sc_init(&hSession, NULL, NULL, NULL, CKU_USER, 0); if (ret) return set_error(ctx, EINVAL, POSIX_ERROR, "Failed to open session to smartcard"); ret = sc_get_cert_obj_by_label(hSession, label, &crd->c_cert); if (ret) return set_error(ctx, EINVAL, POSIX_ERROR, "Failed to locate X.509 certificate for '%s' on smartcard", label); return 0; #else return ENOSYS; #endif /* USE_PKCS11 */ } canl-c-3.0.0/src/canl_dns.c0000644000015500017500000001102213017332512015152 0ustar tomcat6jenkins#include "canl_locl.h" static int decrement_timeout(struct timeval *timeout, struct timeval before, struct timeval after); //#if ARES_VERSION >= 0x010500 static void callback_ares_gethostbyname(void *arg, int status, int timeouts, struct hostent *h) //#else //static void callback_ares_gethostbyname(void *arg, int status, struct hostent *h) //#endif { asyn_result *arp = (asyn_result *) arg; int n_addr = 0; int i = 0; switch (status) { case ARES_SUCCESS: if (h == NULL || h->h_addr_list[0] == NULL){ arp->err = NO_DATA; break; } /*how many addresses are there in h->h_addr_list*/ while (h->h_addr_list[n_addr]) n_addr++; arp->ent->h_addr_list = (char **) calloc((n_addr+1), sizeof(char *)); if (arp->ent->h_addr_list == NULL) { arp->err = NETDB_INTERNAL; break; } for (i = 0; i < n_addr; i++) { arp->ent->h_addr_list[i] = malloc(h->h_length); if (arp->ent->h_addr_list[i] == NULL) { free_hostent (arp->ent); arp->ent = NULL; arp->err = NETDB_INTERNAL; break; } memcpy(arp->ent->h_addr_list[i], h->h_addr_list[i], h->h_length); } /* rest of h members might be assigned here(name,aliases), not necessery now */ arp->ent->h_addr_list[n_addr] = NULL; arp->ent->h_addrtype = h->h_addrtype; arp->ent->h_length = h->h_length; arp->err = NETDB_SUCCESS; break; case ARES_EBADNAME: case ARES_ENOTFOUND: case ARES_ENODATA: arp->err = HOST_NOT_FOUND; break; case ARES_ENOTIMP: arp->err = NO_RECOVERY; break; case ARES_ENOMEM: case ARES_EDESTRUCTION: default: arp->err = NETDB_INTERNAL; break; } } static int decrement_timeout(struct timeval *timeout, struct timeval before, struct timeval after) { (*timeout).tv_sec = (*timeout).tv_sec - (after.tv_sec - before.tv_sec); (*timeout).tv_usec = (*timeout).tv_usec - (after.tv_usec - before.tv_usec); while ( (*timeout).tv_usec < 0) { (*timeout).tv_sec--; (*timeout).tv_usec += 1000000; } if ( ((*timeout).tv_sec < 0) || (((*timeout).tv_sec == 0) && ((*timeout).tv_usec == 0)) ) return(1); else return(0); } void free_hostent(struct hostent *h) { int i; if (h) { if (h->h_name) free(h->h_name); if (h->h_aliases) { for (i=0; h->h_aliases[i]; i++) free(h->h_aliases[i]); free(h->h_aliases); } if (h->h_addr_list) { for (i=0; h->h_addr_list[i]; i++) free(h->h_addr_list[i]); free(h->h_addr_list); } free(h); } } int canl_asyn_getservbyname(int a_family, asyn_result *ares_result,char const *name, struct timeval *timeout) { int err; ares_channel channel; int nfds; fd_set readers, writers; struct timeval tv, *tvp; struct timeval start_time,check_time; /* start timer */ gettimeofday(&start_time,0); /* ares init */ if ( ares_init(&channel) != ARES_SUCCESS ) return(NETDB_INTERNAL); //TODO return value... /* query DNS server asynchronously */ ares_gethostbyname(channel, name, a_family, callback_ares_gethostbyname, (void *) ares_result); /* wait for result */ while (1) { FD_ZERO(&readers); FD_ZERO(&writers); nfds = ares_fds(channel, &readers, &writers); if (nfds == 0) break; gettimeofday(&check_time,0); if (timeout && decrement_timeout(timeout, start_time, check_time)) { ares_destroy(channel); return(TRY_AGAIN); } start_time = check_time; tvp = ares_timeout(channel, timeout, &tv); switch ( select(nfds, &readers, &writers, NULL, tvp) ) { case -1: if (errno != EINTR) { ares_destroy(channel); return NETDB_INTERNAL; } else continue; case 0: FD_ZERO(&readers); FD_ZERO(&writers); /* fallthrough */ default: ares_process(channel, &readers, &writers); } } err = ares_result->err; ares_destroy(channel); return err; } canl-c-3.0.0/src/canl_err.c0000644000015500017500000001741213017332512015167 0ustar tomcat6jenkins#include "canl_locl.h" #define ERR_CODE_LEN 512 static canl_err_code resolve_error_code(glb_ctx *cc, unsigned long err_code, canl_err_origin err_orig); static void get_error_string(glb_ctx *cc, char *code_str); static canl_err_code update_error_msg(canl_ctx cc, const char *new_msg); static const char *canl_strerror(const canl_err_code c_code); static int canl_err_ssl_to_canl(const unsigned long ossl_lib, const unsigned long ossl_reason); /* Save error message into err_msg * use NULL for empty err_format */ canl_err_code update_error (glb_ctx *cc, unsigned long err_code, canl_err_origin err_orig, const char *err_format, ...) { int err_format_len = 0; va_list ap; char *new_msg = NULL; int ret = 0; if (!cc) return EINVAL; if (err_format == NULL || err_format[0] == '\0') { goto wo_msg; } va_start(ap, err_format); /*TODO if vasprintf not successful?*/ err_format_len = vasprintf(&new_msg, err_format, ap); if (!err_format_len) { va_end(ap); return EINVAL; } va_end(ap); wo_msg: ret = resolve_error_code(cc, err_code, err_orig); update_error_msg(cc, new_msg); if (new_msg) free(new_msg); return ret; } /* If there was some error message in ctx, delete it and make new */ canl_err_code set_error (glb_ctx *cc, unsigned long err_code, canl_err_origin err_orig, const char *err_format, ...) { va_list ap; char *new_msg = NULL; int ret; int err_format_len = 0; if (!cc) return 1; /* if message already exists, delete it */ if (cc->err_msg) reset_error(cc, err_code); if (err_format == NULL || err_format[0] == '\0') { goto wo_msg; } /* make new message */ va_start(ap, err_format); err_format_len = vasprintf(&new_msg, err_format, ap); if (!err_format_len) { va_end(ap); return EINVAL; } va_end(ap); wo_msg: ret = resolve_error_code(cc, err_code, err_orig); update_error_msg(cc, new_msg); if (new_msg) free(new_msg); if (!err_code) //TODO ??? return 0; return ret; } /* Delete error message in ctx, suppose msg is not empty.Set pointer to NULL*/ void reset_error (glb_ctx *cc, unsigned long err_code) { /*check cc*/ if (!cc ) return; if (cc->err_msg) free(cc->err_msg); cc->err_msg = NULL; cc->err_code = 0; cc->err_orig = UNKNOWN_ERROR; } /* Provide human readable information about errors */ static canl_err_code update_error_msg(canl_ctx cc, const char *new_msg) { int error_length = 0; char *new_error = NULL; char code_str[ERR_CODE_LEN]; int code_len = 0; char *separ = ": "; char *separ_2 = "; "; int separ_len = 0; int separ_2_len = 0; int err_old_msg_len = 0; int err_new_msg_len = 0; glb_ctx *ctx = (glb_ctx*) cc; code_str[0] = '\0'; /*check cc*/ if (!ctx) { return EINVAL; } if (ctx->err_msg) err_old_msg_len = strlen(ctx->err_msg); if (new_msg) err_new_msg_len = strlen(new_msg); /* get human readable error code */ get_error_string(cc, code_str); code_len = strlen(code_str); separ_len = strlen(separ); separ_2_len = strlen(separ_2); error_length = err_new_msg_len + err_old_msg_len + code_len + (2*separ_len) + 1; new_error = (char *) malloc ((error_length) * sizeof (char)); if (!new_error) { return set_error(ctx, ENOMEM, POSIX_ERROR, "cannot get error message"); } new_error[0] = '\0'; if (new_msg) { strncpy(new_error, new_msg, err_new_msg_len + 1); strncat(new_error, separ, separ_len + 1); } strncat(new_error, code_str, code_len + 1); strncat(new_error, separ_2, separ_2_len + 1); if (ctx->err_msg) { strncat(new_error, ctx->err_msg, err_old_msg_len + 1); } if (ctx->err_msg) free(ctx->err_msg); ctx->err_msg = new_error; return 0; } static void get_error_string(glb_ctx *cc, char *code_str) { const char *new_str = NULL; switch (cc->err_orig) { case SSL_ERROR: ERR_error_string_n(cc->err_code, code_str, ERR_CODE_LEN); break; case POSIX_ERROR: new_str = strerror(cc->err_code); if (new_str) { strncpy(code_str, new_str, ERR_CODE_LEN); code_str[ERR_CODE_LEN - 1] = '\0'; } break; case NETDB_ERROR: new_str = hstrerror(cc->err_code); if (new_str) { strncpy(code_str, new_str, ERR_CODE_LEN); code_str[ERR_CODE_LEN - 1] = '\0'; } break; case CANL_ERROR: new_str = canl_strerror(cc->err_code); if (new_str) { strncpy(code_str, new_str, ERR_CODE_LEN); code_str[ERR_CODE_LEN - 1] = '\0'; } break; default: snprintf(code_str, ERR_CODE_LEN, "Unknown error origin (%u) of error %lu!", cc->err_orig, cc->err_code); break; } } static const char * canl_strerror(const canl_err_code c_code) { const char *new_str = NULL; int k = 0; for (k = 0; k < canl_err_descs_num; k++) { if (canl_err_descs[k].code == c_code) { new_str = canl_err_descs[k].desc; } } return new_str; } /*return appropriate CANL_ERROR according to openssl error code or -1 if no one found */ static int canl_err_ssl_to_canl(const unsigned long ossl_lib, const unsigned long ossl_reason) { int ret_err = -1; int k = 0; for (k = 0; k < canl_err_descs_num; k++) { if (canl_err_descs[k].openssl_lib == ossl_lib) { if (canl_err_descs[k].openssl_reason == ossl_reason) ret_err = canl_err_descs[k].code; } } return ret_err; } canl_err_code canl_get_error_code(canl_ctx cc) { glb_ctx *ctx = (glb_ctx*) cc; if (ctx == NULL) return -1; return ctx->err_code; } char * canl_get_error_message(canl_ctx cc) { glb_ctx *ctx = (glb_ctx*) cc; if (ctx == NULL) return "Context is not initialized"; return ctx->err_msg; } /*if the error code is known to canl, assign appropriate canl code TODO go through ssl errors and assign appr. canl code ?preserve original one? */ static canl_err_code resolve_error_code(glb_ctx *cc, unsigned long err_code, canl_err_origin err_orig) { int ret = 0; cc->original_err_code = err_code; cc->err_orig = err_orig; switch (err_orig) { case UNKNOWN_ERROR: cc->err_code = (err_code) ? CANL_ERR_unknown : 0; break; case POSIX_ERROR: /* We don't use that many posix-like codes, perhaps we want to * map them to CANL codes. */ cc->err_code = err_code; break; case SSL_ERROR: /* TODO What about CANL_ERR_GeneralSSLError ?*/ if ((ret = canl_err_ssl_to_canl(ERR_GET_LIB(err_code), ERR_GET_REASON(err_code))) != -1){ cc->err_code = ret; cc->err_orig = CANL_ERROR; } cc->err_code = err_code; break; case CANL_ERROR: cc->err_code = err_code; break; case NETDB_ERROR: switch (cc->err_code) { case HOST_NOT_FOUND: cc->err_code = CANL_ERR_hostNotFound; break; default: cc->err_code = CANL_ERR_resolverError; break; } break; default: cc->err_code = CANL_ERR_unknown; cc->err_orig = UNKNOWN_ERROR; } return cc->err_code; } canl-c-3.0.0/src/canl_ocsp.c0000644000015500017500000003377413017332512015354 0ustar tomcat6jenkins#include "canl_ocsp.h" #include "canl_mech_ssl.h" #include #define USENONCE 0 static X509_STORE * canl_create_x509store(canl_x509store_t *store); static OCSP_RESPONSE *send_request(OCSP_REQUEST *req, char *host, char *path, int port, int ssl, int req_timeout); static OCSP_RESPONSE * query_responder(BIO *conn, char *path, OCSP_REQUEST *req, int req_timeout); static char *get_ocsp_url_from_aia(X509 * cert, char** urls); int ocsprequest_init(canl_ocsprequest_t **ocspreq) { if (!ocspreq) return 1; *ocspreq = calloc(1, sizeof(**ocspreq)); if (!(*ocspreq)) return 1; return 0; } void ocsprequest_free(canl_ocsprequest_t *ocspreq) { if (ocspreq) free(ocspreq); } int set_ocsp_url(canl_ocsprequest_t *ocspreq, char *url) { int len = 0; if (!ocspreq) return 1; if (url) { if (!ocspreq->url) { free (ocspreq->url); ocspreq->url = NULL; } len = strlen(url); ocspreq->url = (char *) malloc((len +1) * sizeof (char)); if (!ocspreq->url) return 1; strncpy(ocspreq->url, url, len + 1); } return 0; } int set_ocsp_sign_cert(canl_ocsprequest_t *ocspreq, X509 *sign_cert) { if (!ocspreq) return 1; if (sign_cert) { if (!ocspreq->sign_cert) { X509_free (ocspreq->sign_cert); ocspreq->sign_cert = NULL; } ocspreq->sign_cert = X509_dup(sign_cert); if (!ocspreq->sign_cert) return 1; } return 0; } int set_ocsp_sign_key(canl_ocsprequest_t *ocspreq, EVP_PKEY *sign_key) { if (!ocspreq) return 1; if (sign_key) { if (!ocspreq->sign_key) { EVP_PKEY_free (ocspreq->sign_key); ocspreq->sign_key = NULL; } pkey_dup(&ocspreq->sign_key, sign_key); if (!ocspreq->sign_key) return 1; } return 0; } static X509_STORE * canl_create_x509store(canl_x509store_t *c_store) { X509_STORE *store = NULL; X509_LOOKUP *lookup = NULL; if (!c_store) return NULL; if(!(store = X509_STORE_new())) goto end; lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); if (lookup == NULL) goto end; if (c_store->ca_file) { if(!X509_LOOKUP_load_file(lookup, c_store->ca_file, X509_FILETYPE_PEM)) { goto end; } } else X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT); lookup=X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir()); if (lookup == NULL) goto end; if (c_store->ca_dir) { if(!X509_LOOKUP_add_dir(lookup, c_store->ca_dir, X509_FILETYPE_PEM)) { goto end; } } else X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); ERR_clear_error(); return store; end: X509_STORE_free(store); return NULL; } /* Extract an url of given ocsp responder out of the AIA extension. Newer openssl libs support OPENSSL_STRING type and X509_get1_ocsp() funcion which can easily do that. We may use it in future. aia = X509_get1_ocsp(x); return sk_OPENSSL_STRING_value(aia, 0); Returns string of the form: URI:uri1 \0 URI:uri2 \0 ... URI:urin \0\0 (without spaces) */ static char *get_ocsp_url_from_aia(X509 * cert, char** urls) { BIO* mem=NULL; ACCESS_DESCRIPTION* ad=NULL; STACK_OF(ACCESS_DESCRIPTION)* ads=NULL; int adsnum; int crit = 0; int idx = 0; int i; if(!cert||!urls) return NULL; *urls=NULL; mem=BIO_new(BIO_s_mem()); if(!mem) goto cleanup; ads=(STACK_OF(ACCESS_DESCRIPTION)*)X509_get_ext_d2i(cert, NID_info_access, &crit, &idx); if(!ads) goto cleanup; adsnum=sk_ACCESS_DESCRIPTION_num(ads); for(i=0; imethod) == NID_ad_OCSP){ if(GENERAL_NAME_print(mem, ad->location)<=0) goto cleanup; BIO_write(mem, "\0", 1); } } BIO_write(mem, "\0\0", 2); BIO_flush(mem); BIO_get_mem_data(mem, urls); BIO_set_close(mem, BIO_NOCLOSE); cleanup: if(ads) sk_ACCESS_DESCRIPTION_free(ads); if(mem) BIO_free(mem); return *urls; } /*TODO error codes in this function has to be passed to canl_ctx somehow*/ /*Timeout shoult be in data structure*/ int do_ocsp_verify (canl_ocsprequest_t *data) { OCSP_REQUEST *req = NULL; OCSP_RESPONSE *resp = NULL; OCSP_BASICRESP *basic = NULL; X509_STORE *store = NULL; int rc = 0, reason = 0, ssl = 0, status = 0; char *host = NULL, *path = NULL, *port = NULL; OCSP_CERTID *id = NULL; char *chosenurl = NULL; char *tr_chosenurl = NULL; canl_ocspresult_t result = 0; ASN1_GENERALIZEDTIME *producedAt, *thisUpdate, *nextUpdate; int timeout = -1; // -1 means no timeout - use blocking I/O unsigned long verify_flags = 0; if (!data || !data->cert) { // TODO || !data->issuer ? result = EINVAL; //TODO error code return result; } /*get url from cert or use some implicit value*/ /*TODO duplicate the value*/ if (data->url) chosenurl = strdup(data->url); else if (!get_ocsp_url_from_aia(data->cert, &chosenurl)) { result = CANL_OCSPRESULT_ERROR_NOAIAOCSPURI; goto end; } /* It is necessary to truncate chosenurl for URI:*/ tr_chosenurl = strstr(chosenurl, "URI:"); if (tr_chosenurl) tr_chosenurl += 4; else tr_chosenurl = chosenurl; /*get connection parameters out of the tr_chosenurl. Determine whether to use encrypted (ssl) connection (based on the url format). Url is http[s]://host where host consists of DN [:port] and [path]*/ if (!OCSP_parse_url(tr_chosenurl, &host, &port, &path, &ssl)) { result = CANL_OCSPRESULT_ERROR_BADOCSPADDRESS; goto end; } /*Make new OCSP_REQUEST*/ if (!(req = OCSP_REQUEST_new())) { result = CANL_OCSPRESULT_ERROR_OUTOFMEMORY; goto end; } /*map a cert and its issuer to an ID*/ id = OCSP_cert_to_id(0, data->cert, data->issuer); /* Add an id and nonce to the request*/ if (!id || !OCSP_request_add0_id(req, id)) goto end; if (USENONCE) OCSP_request_add1_nonce(req, 0, -1); /* sign the request Default hash algorithm is sha1(), might be changed. Do not add additional certificates to request Do not use flags (e.g. like -no_certs for command line ) now */ if (data->sign_cert && data->sign_key && !OCSP_request_sign(req, data->sign_cert, data->sign_key, EVP_sha1(), 0, 0)) { result = CANL_OCSPRESULT_ERROR_SIGNFAILURE; goto end; } /* establish a connection to the OCSP responder */ if (!(resp = send_request(req, host, path, atoi(port), ssl, timeout))) { result = CANL_OCSPRESULT_ERROR_CONNECTFAILURE; goto end; } /* send the request and get a response */ if ((rc = OCSP_response_status(resp)) != OCSP_RESPONSE_STATUS_SUCCESSFUL) { switch (rc) { case OCSP_RESPONSE_STATUS_MALFORMEDREQUEST: result = CANL_OCSPRESULT_ERROR_MALFORMEDREQUEST; break; case OCSP_RESPONSE_STATUS_INTERNALERROR: result = CANL_OCSPRESULT_ERROR_INTERNALERROR; break; case OCSP_RESPONSE_STATUS_TRYLATER: result = CANL_OCSPRESULT_ERROR_TRYLATER; break; case OCSP_RESPONSE_STATUS_SIGREQUIRED: result = CANL_OCSPRESULT_ERROR_SIGREQUIRED; break; case OCSP_RESPONSE_STATUS_UNAUTHORIZED: result = CANL_OCSPRESULT_ERROR_UNAUTHORIZED; break; } goto end; } /* verify the response */ result = CANL_OCSPRESULT_ERROR_INVALIDRESPONSE; if (!(basic = OCSP_response_get1_basic(resp))) goto end; if (USENONCE && OCSP_check_nonce(req, basic) <= 0) goto end; /* TODO is this compulsory? */ store = canl_create_x509store(&data->store); if (!store) goto end; /* The last param. may be used when OCSP API is fully defined*/ rc = OCSP_basic_verify(basic, data->cert_chain, store, verify_flags); if (rc < 0) rc = OCSP_basic_verify(basic, NULL, store, 0); if (rc <= 0) { /*response verify failure*/ result = CANL_OCSPRESULT_ERROR_VERIFYRESPONSE; goto end; } if (!OCSP_resp_find_status(basic, id, &status, &reason, &producedAt, &thisUpdate, &nextUpdate)){ result = CANL_OCSPRESULT_ERROR_NOSTATUS; goto end; } if (!OCSP_check_validity(thisUpdate, nextUpdate, data->skew, data->maxage)) { result = CANL_OCSPRESULT_ERROR_INVTIME; goto end; } /* All done. Set the return code based on the status from the response. */ if (status == V_OCSP_CERTSTATUS_REVOKED) { result = CANL_OCSPRESULT_CERTIFICATE_REVOKED; /*TODO myproxy_log("OCSP status revoked!"); */ } else { result = CANL_OCSPRESULT_CERTIFICATE_VALID; /*TODO myproxy_log("OCSP status valid"); */ } end: if (host) OPENSSL_free(host); if (port) OPENSSL_free(port); if (path) OPENSSL_free(path); if (req) OCSP_REQUEST_free(req); if (resp) OCSP_RESPONSE_free(resp); if (basic) OCSP_BASICRESP_free(basic); if (chosenurl) free(chosenurl); if (store) X509_STORE_free(store); return result; } static OCSP_RESPONSE * send_request(OCSP_REQUEST *req, char *host, char *path, int port, int ssl, int req_timeout) { BIO *conn; SSL_CTX *ctx_in = NULL; OCSP_RESPONSE *resp = NULL; if (!(conn = BIO_new_connect(host))) goto end; BIO_set_conn_port(conn, &port); if (ssl){ BIO *sbio; ctx_in = SSL_CTX_new(TLS_client_method()); if (ctx_in == NULL) { goto end; } //SSL_CTX_set_cert_store(ctx_in, store); /*TODO verify using OCSP? Infinite loop !!!!!!!!!!!!!!!!!!!!!!!§ SSL_CTX_set_mode(ctx_in, SSL_MODE_AUTO_RETRY); ? - return only after the handshake and successful completion*/ SSL_CTX_set_verify(ctx_in, SSL_VERIFY_PEER, NULL); sbio = BIO_new_ssl(ctx_in, 1); conn = BIO_push(sbio, conn); /* BIO_get_ssl(conn, &ssl_ptr); TODO figure out, how to check cert without canl_ctx if (!check_hostname_cert(SSL_get_peer_certificate(ssl_ptr), host)) goto end; TODO verify certs in OCSP at this place? openssl CL tool does not do that. if (SSL_get_verify_result(ssl_ptr) != X509_V_OK) goto end; */ } resp = query_responder(conn, path, req, req_timeout); end: if (conn) BIO_free_all(conn); if (ctx_in) SSL_CTX_free(ctx_in); return resp; } #ifdef OPENSSL_SYSNAME_WIN32 #define openssl_fdset(a,b) FD_SET((unsigned int)a, b) #else #define openssl_fdset(a,b) FD_SET(a, b) #endif #if SSLEAY_VERSION_NUMBER >= 0x0090900fL /*TODO the timeout variable should be modified if TO is reached. Somehow retur error codes! */ static OCSP_RESPONSE * query_responder(BIO *conn, char *path, OCSP_REQUEST *req, int req_timeout) { OCSP_RESPONSE *rsp = NULL; int fd; int rv; OCSP_REQ_CTX *ctx = NULL; fd_set confds; struct timeval tv; /*If timeout is set, the nonblocking I/O flag is set*/ if (req_timeout != -1) BIO_set_nbio(conn, 1); rv = BIO_do_connect(conn); if ((rv <= 0) && ((req_timeout == -1) || !BIO_should_retry(conn))) { /*connect failed*/ return NULL; } if (BIO_get_fd(conn, &fd) <= 0) { /*Cannot get the socket*/ goto err; } if (req_timeout != -1 && rv <= 0) { /*try connecting untill timeout is reached*/ FD_ZERO(&confds); FD_SET(fd, &confds); tv.tv_usec = 0; tv.tv_sec = req_timeout; rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv); if (rv == 0) { /*Timeout reached*/ return NULL; } } /*Prepare OCSP_REQ_CTX*/ ctx = OCSP_sendreq_new(conn, path, NULL, -1); if (!ctx) return NULL; if (!OCSP_REQ_CTX_set1_req(ctx, req)) goto err; /*send the OCSP request and wait for the response*/ for (;;) { rv = OCSP_sendreq_nbio(&rsp, ctx); if (rv != -1) break; /* Blocking I/O flag set TODO - might end in an infinite loop? - what about SSL_MODE_AUTO_RETRY ?? */ if (req_timeout == -1) continue; FD_ZERO(&confds); openssl_fdset(fd, &confds); tv.tv_usec = 0; tv.tv_sec = req_timeout; if (BIO_should_read(conn)) rv = select(fd + 1, (void *)&confds, NULL, NULL, &tv); else if (BIO_should_write(conn)) rv = select(fd + 1, NULL, (void *)&confds, NULL, &tv); else { /* Unexpected retry condition */ goto err; } if (rv == 0) { /*Timeout on request */ break; } if (rv == -1) { /*Select error*/ break; } } err: if (ctx) OCSP_REQ_CTX_free(ctx); return rsp; } #endif #if SSLEAY_VERSION_NUMBER < 0x0090900fL /*TODO the timeout variable should be modified if TO is reached. Somehow retur error codes! */ static OCSP_RESPONSE * query_responder(BIO *conn, char *path, OCSP_REQUEST *req, int req_timeout) { OCSP_RESPONSE *rsp = NULL; /*openssl does support non blocking BIO for OCSP_send_request*/ /*openssl does not support non blocking BIO for OCSP_send_request*/ if (BIO_do_connect(conn) <= 0) { /*Error connecting BIO*/ goto err; } rsp = OCSP_sendreq_bio(conn, path, req); if (!rsp) { /*no response from the server*/ goto err; } err: return rsp; } #endif canl-c-3.0.0/src/canl_ssl.c0000644000015500017500000011760713017332512015207 0ustar tomcat6jenkins#include "canl_locl.h" #include "canl_ssl.h" #include "canl_mech_ssl.h" #include #include #define SSL_SERVER_METH TLS_server_method() #define SSL_CLIENT_METH TLS_client_method() #define DESTROY_TIMEOUT 10 pthread_mutex_t canl_lock = PTHREAD_MUTEX_INITIALIZER; static int do_ssl_connect( glb_ctx *cc, io_handler *io, SSL *ssl, struct timeval *timeout); static int do_ssl_accept( glb_ctx *cc, io_handler *io, SSL *ssl, struct timeval *timeout); static int check_hostname_cert(glb_ctx *cc, io_handler *io, SSL *ssl, const char *host); canl_error map_verify_result(unsigned long ssl_err, const X509_STORE_CTX *store_ctx, SSL *ssl); static canl_error map_proxy_error(int reason); static int setup_SSL_proxy_handler(glb_ctx *cc, SSL_CTX *ssl, char *cadir, int leave_pvd); extern canl_proxy_verify_desc *canl_pvd_setup_initializers(char *cadir, char *ocsp_url, unsigned int flags); extern void canl_pvd_destroy_initializers(void *data); #ifdef DEBUG static void dbg_print_ssl_error(int errorcode); #endif /*static int set_ocsp_url(char *url, X509 *cert, X509 *issuer, canl_x509store_t *store, X509 *sign_cert, EVP_PKEY *sign_key, long skew, long maxage) { */ static void openssl_init(void) { SSL_library_init(); SSL_load_error_strings(); OpenSSL_add_all_algorithms(); } static canl_err_code ssl_initialize(glb_ctx *cc) { static pthread_once_t openssl_once = PTHREAD_ONCE_INIT; X509_STORE *store; mech_glb_ctx **m_glb_ctx = (mech_glb_ctx **) &cc->mech_ctx; int err = 0; char *ca_cert_fn, *user_cert_fn, *user_key_fn, *user_proxy_fn; char *ca_cert_dirn = NULL; ca_cert_fn = user_cert_fn = user_key_fn = user_proxy_fn = NULL; SSL_CTX *ssl_ctx = NULL; if (!cc) return EINVAL; pthread_once(&openssl_once, openssl_init); ERR_clear_error(); ssl_ctx = SSL_CTX_new(SSLv23_method()); if (!ssl_ctx) return set_error(cc, ERR_get_error(), SSL_ERROR, "Cannot initialize SSL context"); if (!*m_glb_ctx) *m_glb_ctx = (mech_glb_ctx *) calloc(1, sizeof(**m_glb_ctx)); if (!*m_glb_ctx) return set_error(cc, ENOMEM, POSIX_ERROR, "Not enough memory"); err = proxy_get_filenames(0, &ca_cert_fn, &ca_cert_dirn, NULL, NULL, NULL); if (!err){ /* set ca dir and ca file to SSL_CTX*/ if (ca_cert_fn || ca_cert_dirn) if (!SSL_CTX_load_verify_locations(ssl_ctx, ca_cert_fn, ca_cert_dirn)) err = set_error(cc, ERR_get_error(), SSL_ERROR, "Cannot set verify locations"); /* set ca dir and/or ca file to canl glb_ctx*/ if (!(*m_glb_ctx)->ca_file && ca_cert_fn && !access(ca_cert_fn, R_OK)) { err = canl_ctx_set_ca_fn(cc, ca_cert_fn); if (err) return err; } if (!(*m_glb_ctx)->ca_dir && ca_cert_dirn && !access(ca_cert_dirn, R_OK)) { err = canl_ctx_set_ca_dir(cc, ca_cert_dirn); if (err) return err; } } if (ca_cert_fn) free(ca_cert_fn); if (ca_cert_dirn) free(ca_cert_dirn); err = SSL_CTX_set_cipher_list(ssl_ctx, "ALL:!LOW:!EXP:!MD5:!MD2"); if (!err) { err = set_error(cc, ERR_get_error(), SSL_ERROR, "Error setting cipher list"); goto end; } /* XXX: should be only defined on the SSL level: */ store = SSL_CTX_get_cert_store(ssl_ctx); X509_STORE_set_check_issued(store, proxy_check_issued); (*m_glb_ctx)->mech_ctx = ssl_ctx; ssl_ctx = NULL; err = 0; end: if (ssl_ctx) SSL_CTX_free(ssl_ctx); return err; } static canl_err_code ssl_set_flags(glb_ctx *cc, unsigned int *mech_flags, unsigned int flags) { if (cc == NULL) return EINVAL; *mech_flags = (flags | *mech_flags); return 0; } static canl_err_code ssl_set_dir(glb_ctx *cc, char **target, const char *ca_dir) { int fn_len = 0; if (cc == NULL) return EINVAL; if (ca_dir == NULL) return set_error(cc, EINVAL, POSIX_ERROR, "CA dir. name NULL"); if (target && *target){ free (*target); *target = NULL; } fn_len = strlen(ca_dir); *target = (char *) malloc ((fn_len + 1) * sizeof (char)); if (!(*target)) { return set_error(cc, ENOMEM, POSIX_ERROR, NULL); } strncpy (*target, ca_dir, fn_len + 1); return 0; } static canl_err_code ssl_server_init(glb_ctx *cc, void **ctx) { mech_glb_ctx *m_ctx = (mech_glb_ctx *)cc->mech_ctx; SSL_CTX *ssl_ctx = NULL; SSL *ssl = NULL; char *user_cert_fn, *user_key_fn; int err = 0; user_cert_fn = user_key_fn = NULL; if (cc == NULL) return EINVAL; if (!m_ctx || !m_ctx->mech_ctx) return set_error(cc, EINVAL, POSIX_ERROR, "SSL context not" " initialized"); ssl_ctx = (SSL_CTX *) m_ctx->mech_ctx; err = proxy_get_filenames(0, NULL, NULL, NULL, &user_cert_fn, &user_key_fn); if (!err && (!m_ctx->cert_key || !m_ctx->cert_key->cert || !m_ctx->cert_key->key)) { if (user_cert_fn && user_key_fn && !access(user_cert_fn, R_OK) && !access(user_key_fn, R_OK)) { err = do_set_ctx_own_cert_file(cc, m_ctx, user_cert_fn, user_key_fn, NULL); if (err) { free(user_cert_fn); free(user_key_fn); return err; } } } if (user_cert_fn){ free(user_cert_fn); user_cert_fn = NULL; } if (user_key_fn){ free(user_key_fn); user_key_fn = NULL; } if (err || (!m_ctx->cert_key || !m_ctx->cert_key->cert || !m_ctx->cert_key->key)) return set_error(cc, CANL_ERR_noCertFound, CANL_ERROR, "No key or certificate found"); ssl = SSL_new(ssl_ctx); if (ssl == NULL) return set_error(cc, ERR_get_error(), SSL_ERROR, "Failed to create SSL connection context"); if (CANL_SSL_VERIFY_NONE & m_ctx->flags) SSL_set_verify(ssl, SSL_VERIFY_NONE, proxy_verify_callback); else SSL_set_verify(ssl, SSL_VERIFY_PEER, proxy_verify_callback); if (!(CANL_SSL_ACCEPT_SSLv2 & m_ctx->flags)) SSL_set_options(ssl, SSL_OP_NO_SSLv2); // SSL_use_certificate_file(ssl, "/etc/grid-security/hostcert.pem", SSL_FILETYPE_PEM); // SSL_use_PrivateKey_file(ssl, "/etc/grid-security/hostkey.pem", SSL_FILETYPE_PEM); SSL_set_accept_state(ssl); if (m_ctx->cert_key) { if (m_ctx->cert_key->cert) { err = SSL_use_certificate(ssl, m_ctx->cert_key->cert); if (err != 1) { return set_error(cc, ERR_get_error(), SSL_ERROR, "Cannot" "use certificate"); } else err = 0; } if (m_ctx->cert_key->key) { err = SSL_use_PrivateKey(ssl, m_ctx->cert_key->key); if (err != 1) { return set_error(cc, ERR_get_error(), SSL_ERROR, "Cannot" "use private key"); } else err = 0; } } else { set_error(cc, CANL_ERR_noCertFound, CANL_ERROR, "server key or certificate missing"); return 1; } /*Make sure the key and certificate file match*/ if ( (err = SSL_check_private_key(ssl)) != 1) return set_error(cc, ERR_get_error(), SSL_ERROR, "Private key" " does not match the certificate public key"); *ctx = ssl; return 0; } static canl_err_code ssl_client_init(glb_ctx *cc, void **ctx) { mech_glb_ctx *m_ctx = (mech_glb_ctx *)cc->mech_ctx; SSL_CTX *ssl_ctx = NULL; SSL *ssl = NULL; X509_STORE *cert_store; int err = 0, i = 0; char *user_cert_fn, *user_key_fn, *user_proxy_fn; user_cert_fn = user_key_fn = user_proxy_fn = NULL; if (cc == NULL) return EINVAL; if (!m_ctx || !m_ctx->mech_ctx) return set_error(cc, EINVAL, POSIX_ERROR, "SSL context not" " initialized"); ssl_ctx = (SSL_CTX *) m_ctx->mech_ctx; cert_store = SSL_CTX_get_cert_store(ssl_ctx); err = proxy_get_filenames(0, NULL, NULL, &user_proxy_fn, &user_cert_fn, &user_key_fn); if (!err && (!m_ctx->cert_key || !m_ctx->cert_key->cert || !m_ctx->cert_key->key)) { if (user_proxy_fn && !access(user_proxy_fn, R_OK)) { err = do_set_ctx_own_cert_file(cc, m_ctx, NULL, NULL, user_proxy_fn); if (err) goto err; } else { if (user_cert_fn && !access(user_cert_fn, R_OK)) { err = do_set_ctx_own_cert_file(cc, m_ctx, user_cert_fn, NULL, NULL); if (err) goto err; } if (user_key_fn && !access(user_key_fn, R_OK)) { err = do_set_ctx_own_cert_file(cc, m_ctx, NULL, user_key_fn, NULL); if (err) goto err; } } } if (err || (!m_ctx->cert_key || !m_ctx->cert_key->cert || !m_ctx->cert_key->key)) update_error(cc, CANL_ERR_noCertFound, CANL_ERROR, "No key or certificate found"); if (user_cert_fn){ free(user_cert_fn); user_cert_fn = NULL; } if (user_key_fn){ free(user_key_fn); user_key_fn = NULL; } if (user_proxy_fn) { free(user_proxy_fn); user_proxy_fn = NULL; } if (m_ctx->cert_key && m_ctx->cert_key->chain) { /* * Certificate was a proxy with a cert. chain. * Add the certificates one by one to the chain. */ X509_STORE_add_cert(cert_store, m_ctx->cert_key->cert); for (i = 0; i < sk_X509_num(m_ctx->cert_key->chain); ++i) { X509 *cert = (sk_X509_value(m_ctx->cert_key->chain, i)); if (!X509_STORE_add_cert(cert_store, cert)) { if (ERR_GET_REASON(ERR_peek_error()) == X509_R_CERT_ALREADY_IN_HASH_TABLE) { ERR_clear_error(); continue; } else { set_error(cc, 1, CANL_ERROR, "Cannot add certificate " "to the SSL context's certificate store"); } } } #if OPENSSL_VERSION_NUMBER >= 0x10000000L X509_STORE_set_verify_cb(cert_store, proxy_verify_callback); #endif } ssl = SSL_new(ssl_ctx); if (ssl == NULL) return set_error(cc, ERR_get_error(), SSL_ERROR, "Failed to create SSL connection context"); SSL_set_connect_state(ssl); if (CANL_SSL_VERIFY_NONE & m_ctx->flags) SSL_set_verify(ssl, SSL_VERIFY_NONE, proxy_verify_callback); else SSL_set_verify(ssl, SSL_VERIFY_PEER, proxy_verify_callback); if (!(CANL_SSL_ACCEPT_SSLv2 & m_ctx->flags)) SSL_set_options(ssl, SSL_OP_NO_SSLv2); if (m_ctx->cert_key) { if (m_ctx->cert_key->key) { err = SSL_use_PrivateKey(ssl, m_ctx->cert_key->key); if (err != 1) { return set_error(cc, ERR_get_error(), SSL_ERROR, "Cannot" "use private key"); } } if (m_ctx->cert_key->cert) { err = SSL_use_certificate(ssl, m_ctx->cert_key->cert); if (err != 1) { return set_error(cc, ERR_get_error(), SSL_ERROR, "Cannot" "use certificate"); } } /*Make sure the key and certificate file match * not mandatory on client side*/ if (m_ctx->cert_key->cert && m_ctx->cert_key->key) if ( (err = SSL_check_private_key(ssl)) != 1) return set_error(cc, ERR_get_error(), SSL_ERROR, "Private key" " does not match the certificate public key"); } *ctx = ssl; return 0; err: if (user_cert_fn){ free(user_cert_fn); user_cert_fn = NULL; } if (user_key_fn){ free(user_key_fn); user_key_fn = NULL; } if (user_proxy_fn) { free(user_proxy_fn); user_proxy_fn = NULL; } return err; } static int setup_SSL_proxy_handler(glb_ctx *cc, SSL_CTX *ssl, char *cadir, int leave_pvd) { canl_proxy_verify_desc *new_pvd = NULL; mech_glb_ctx *m_ctx = (mech_glb_ctx *)cc->mech_ctx; new_pvd = canl_pvd_setup_initializers(cadir, m_ctx->ocsp_url, m_ctx->flags); if (new_pvd){ SSL_CTX_set_ex_data(ssl, PVD_SSL_EX_DATA_IDX, new_pvd); if (!leave_pvd) m_ctx->pvd_ctx = new_pvd; return 0; } return 1; } static canl_err_code ssl_connect(glb_ctx *cc, io_handler *io, void *auth_ctx, struct timeval *timeout, const char * host) { SSL *ssl = (SSL *) auth_ctx; SSL_CTX *ssl_ctx = NULL; int err = 0, flags; mech_glb_ctx *m_ctx = (mech_glb_ctx *)cc->mech_ctx; if (!cc) { return EINVAL; } if (!io) { err = EINVAL; goto end; } if (ssl == NULL) return set_error(cc, EINVAL, POSIX_ERROR, "SSL not initialized"); flags = fcntl(io->sock, F_GETFL, 0); (void)fcntl(io->sock, F_SETFL, flags | O_NONBLOCK); ssl_ctx = SSL_get_SSL_CTX(ssl); setup_SSL_proxy_handler(cc, ssl_ctx, m_ctx->ca_dir, 0); SSL_set_fd(ssl, io->sock); err = do_ssl_connect(cc, io, ssl, timeout); if (err) { goto end; } /*check server hostname on the certificate*/ err = check_hostname_cert(cc, io, ssl, host); end: return err; } static int check_hostname_cert(glb_ctx *cc, io_handler *io, SSL *ssl, const char *host) { X509 * serv_cert = NULL; X509_EXTENSION *ext = NULL; int i = 0; GENERAL_NAMES *ialt = NULL; char *pBuffer = NULL; int correspond = 0; X509_NAME *sn = NULL; /*if extensions are present, hostname has to correspond * to subj. alt. name*/ serv_cert = SSL_get_peer_certificate(ssl); if (!serv_cert) return set_error(cc, CANL_ERR_unknownMsg, CANL_ERROR, "Server certificate missing"); i = X509_get_ext_by_NID(serv_cert, NID_subject_alt_name, -1); if (i != -1) { /* subj. alt. name extention present */ if(!(ext = X509_get_ext(serv_cert, i)) || !(ialt = X509V3_EXT_d2i(ext)) ) goto end; for(i = 0; i < sk_GENERAL_NAME_num(ialt); i++) { const GENERAL_NAME *gen = sk_GENERAL_NAME_value(ialt, i); switch (gen->type) { case GEN_DNS: ASN1_STRING_to_UTF8((unsigned char**)&pBuffer, gen->d.ia5); #ifdef DEBUG printf(" %s",pBuffer); #endif if (!strcmp(pBuffer, host)) { correspond = 1; OPENSSL_free(pBuffer); pBuffer = NULL; goto end; } OPENSSL_free(pBuffer); pBuffer = NULL; break; } } } /*else hostname has to correspond to common name*/ else { sn = X509_get_subject_name(serv_cert); i = X509_NAME_get_index_by_NID(sn, NID_commonName, -1); if (i != -1) { while (1) { X509_NAME_ENTRY *cn = X509_NAME_get_entry(sn, i); ASN1_STRING_to_UTF8((unsigned char**)&pBuffer, X509_NAME_ENTRY_get_data(cn)); if (!strcmp(pBuffer, host)) { //TODO substr maybe correspond = 1; OPENSSL_free(pBuffer); pBuffer = NULL; goto end; } i = X509_NAME_get_index_by_NID(sn, NID_commonName, i); OPENSSL_free(pBuffer); pBuffer = NULL; if (i == -1) break; } } else return set_error(cc, CANL_ERR_unknownMsg, CANL_ERROR, "Common name entry does not exist"); //TODO check } end: X509_free(serv_cert); if (correspond) return 0; else { return set_error(cc, CANL_ERR_unknownMsg, CANL_ERROR, "Cannot validate server hostname against its certificate" ); //TODO check } } static canl_err_code ssl_accept(glb_ctx *cc, io_handler *io, void *auth_ctx, struct timeval *timeout) { SSL *ssl = (SSL *) auth_ctx; SSL_CTX *ssl_ctx = NULL; int err = 0, flags; mech_glb_ctx *m_ctx = (mech_glb_ctx *)cc->mech_ctx; if (!cc) { return EINVAL; } if (!io) { err = EINVAL; goto end; } if (auth_ctx == NULL) return set_error(cc, EINVAL, POSIX_ERROR, "SSL not initialized"); flags = fcntl(io->sock, F_GETFL, 0); (void)fcntl(io->sock, F_SETFL, flags | O_NONBLOCK); ssl_ctx = SSL_get_SSL_CTX(ssl); setup_SSL_proxy_handler(cc, ssl_ctx, m_ctx->ca_dir, 0); SSL_set_fd(ssl, io->sock); err = do_ssl_accept(cc, io, ssl, timeout); if (err) { goto end; } end: return err; } /* * Encapsulates select behaviour * * Returns: * > 0 : Ready to read or write. * = 0 : timeout reached. * < 0 : error. */ static int do_select(int fd, time_t starttime, int timeout, int wanted) { int ret = 0; fd_set rset; fd_set wset; FD_ZERO(&rset); FD_ZERO(&wset); if (wanted == 0 || wanted == SSL_ERROR_WANT_READ) FD_SET(fd, &rset); if (wanted == 0 || wanted == SSL_ERROR_WANT_WRITE) FD_SET(fd, &wset); if (timeout != -1) { struct timeval endtime; time_t curtime = time(NULL); if (curtime - starttime >= timeout) return 0; endtime.tv_sec = timeout - (curtime - starttime); endtime.tv_usec = 0; ret = select(fd+1, &rset, &wset, NULL, &endtime); } else { ret = select(fd+1, &rset, &wset, NULL, NULL); } if (ret == 0) return 0; if ((wanted == SSL_ERROR_WANT_READ && !FD_ISSET(fd, &rset)) || (wanted == SSL_ERROR_WANT_WRITE && !FD_ISSET(fd, &wset))) return -1; if (ret < 0 && (!FD_ISSET(fd, &rset) || !FD_ISSET(fd, &wset))) return 1; return ret; } #define TEST_SELECT(ret, ret2, timeout, curtime, starttime, errorcode) \ ((ret) > 0 && ((ret2) <= 0 && (((timeout) == -1) || \ (((timeout) != -1) && \ ((curtime) - (starttime)) < (timeout))) && \ ((errorcode) == SSL_ERROR_WANT_READ || \ (errorcode) == SSL_ERROR_WANT_WRITE))) static int do_ssl_connect(glb_ctx *cc, io_handler *io, SSL *ssl, struct timeval *timeout) { time_t starttime, curtime; int ret = -1, ret2 = -1; unsigned long ssl_err = 0; long errorcode = 0; int expected = 0; int locl_timeout = -1; canl_error canl_err = 0; /* do not take tv_usec into account in this function*/ if (timeout) locl_timeout = timeout->tv_sec; else locl_timeout = -1; curtime = starttime = time(NULL); ERR_clear_error(); do { ret = do_select(io->sock, starttime, locl_timeout, expected); if (ret > 0) { ret2 = SSL_connect(ssl); if (ret2 < 0) { ssl_err = ERR_get_error(); } expected = errorcode = SSL_get_error(ssl, ret2); } curtime = time(NULL); } while (TEST_SELECT(ret, ret2, locl_timeout, curtime, starttime, errorcode)); timeout->tv_sec = timeout->tv_sec - (curtime - starttime); //TODO split ret2 and ret into 2 ifs to set approp. err. msg and check ag. if (ret2 <= 0 || ret <= 0) { if (timeout && (curtime - starttime >= locl_timeout)){ timeout->tv_sec=0; timeout->tv_usec=0; update_error (cc, ETIMEDOUT, POSIX_ERROR, "Connection stuck during" " handshake: timeout reached"); } else if (ret2 < 0 && ssl_err){ canl_err = map_verify_result(ssl_err, NULL, ssl); if (canl_err) update_error (cc, canl_err, CANL_ERROR, "Error during SSL handshake"); else update_error(cc, ssl_err, SSL_ERROR, "Error during SSL handshake"); } else if (ret2 == 0)//TODO is 0 (conn closed by the other side) error? update_error (cc, ECONNREFUSED, POSIX_ERROR, "Connection closed" " by the other side"); else /*ret2 < 0 && !ssl_err*/ update_error (cc, CANL_ERR_noRouteToServer, CANL_ERROR, "Error" " during SSL handshake" " in communication with the server"); return 1; } return 0; } static int do_ssl_accept(glb_ctx *cc, io_handler *io, SSL *ssl, struct timeval *timeout) { time_t starttime, curtime; int ret = -1, ret2 = -1; unsigned long ssl_err = 0; long errorcode = 0; int expected = 0; int locl_timeout = -1; canl_error canl_err = 0; /* do not take tv_usec into account in this function*/ if (timeout) locl_timeout = timeout->tv_sec; else locl_timeout = -1; curtime = starttime = time(NULL); ERR_clear_error(); do { ret = do_select(io->sock, starttime, locl_timeout, expected); if (ret > 0) { ret2 = SSL_accept(ssl); if (ret2 < 0) { ssl_err = ERR_peek_error(); } expected = errorcode = SSL_get_error(ssl, ret2); } curtime = time(NULL); #ifdef DEBUG dbg_print_ssl_error(errorcode); #endif } while (ret > 0 && (ret2 <= 0 && ((locl_timeout == -1) || ((locl_timeout != -1) && (curtime - starttime) < locl_timeout)) && (errorcode == SSL_ERROR_WANT_READ || errorcode == SSL_ERROR_WANT_WRITE))); #ifdef DEBUG if (errorcode == SSL_ERROR_WANT_READ) printf("SSL_ERR_WANT_READ"); if (errorcode == SSL_ERROR_WANT_WRITE) printf("SSL_ERR_WANT_WRITE"); printf ("STR: %s \n",ERR_error_string(ssl_err,NULL)); printf ("LIB: %s ;",ERR_lib_error_string(ssl_err)); printf ("FUNC: %s ;",ERR_func_error_string(ssl_err)); printf ("LIB: %s \n",ERR_reason_error_string(ssl_err)); #endif timeout->tv_sec = timeout->tv_sec - (curtime - starttime); //TODO split ret2 and ret into 2 ifs to set approp. error message if (ret2 <= 0 || ret <= 0) { if (timeout && (curtime - starttime >= locl_timeout)){ timeout->tv_sec=0; timeout->tv_usec=0; set_error (cc, ETIMEDOUT, POSIX_ERROR, "Connection stuck" " during handshake: timeout reached"); } else if (ret2 == 0) set_error (cc, ECONNREFUSED, POSIX_ERROR, "Connection closed by" " the other side"); else if (ret2 < 0 && ssl_err){ canl_err = map_verify_result(ssl_err, NULL, ssl); if (canl_err) set_error(cc, canl_err, CANL_ERROR, "Error during SSL handshake"); else set_error(cc, ssl_err, SSL_ERROR, "Error during SSL handshake"); } else /*ret2 < 0 && !ssl_err*/ set_error (cc, 0, UNKNOWN_ERROR, "Error during SSL handshake" " in communication with the server"); return 1; } return 0; } canl_error map_verify_result(unsigned long ssl_err, const X509_STORE_CTX *store_ctx, SSL *ssl) { long result = 0; canl_error canl_err = 0; int err_lib = 0; /*Try PRXYERR codes first*/ if (ssl_err) if ((err_lib = ERR_GET_LIB(ssl_err)) == ERR_USER_LIB_PRXYERR_NUMBER) { canl_err = map_proxy_error(ERR_GET_REASON(ssl_err)); if (canl_err) return canl_err; } /*Then try to get verify error out of X509_STORE_CTX or SSL*/ if (store_ctx) result = X509_STORE_CTX_get_error(store_ctx); else if (ssl) result = SSL_get_verify_result(ssl); else return 0; /*We have openssl cert verification result code*/ switch (result) { case X509_V_OK: return 0; case X509_V_ERR_CERT_CHAIN_TOO_LONG: canl_err = CANL_ERR_pathLenghtExtended; break; case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: canl_err = CANL_ERR_noIssuerPublicKey; break; case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: canl_err = CANL_ERR_signatureNotVerified; break; case X509_V_ERR_CERT_NOT_YET_VALID: canl_err = CANL_ERR_certificateNotYetValid; break; case X509_V_ERR_CERT_HAS_EXPIRED: canl_err = CANL_ERR_certificateExpired; break; case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION: canl_err = CANL_ERR_unknownCriticalExt; break; case X509_V_ERR_CERT_REVOKED: canl_err = CANL_ERR_certRevoked; break; case X509_V_ERR_UNABLE_TO_GET_CRL: canl_err = CANL_ERR_noValidCrlFound; break; case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED: canl_err = CANL_ERR_proxyLength; break; case X509_V_ERR_INVALID_PURPOSE: canl_err = CANL_ERR_invalidPurpose; break; default: break; } return canl_err; } /*go through PRXYERR reasons and map them on canl error codes*/ static canl_error map_proxy_error(int reason) { canl_error canl_err = 0; switch (reason) { case PRXYERR_R_UNKNOWN_CRIT_EXT: canl_err = CANL_ERR_unknownCriticalExt; break; case PRXYERR_R_CA_POLICY_VIOLATION: //TODO map break; case PRXYERR_R_CERT_REVOKED: canl_err = CANL_ERR_certRevoked; case PRXYERR_R_CRL_HAS_EXPIRED: //TODO map break; case PRXYERR_R_CRL_NEXT_UPDATE_FIELD: //TODO map break; case PRXYERR_R_CRL_SIGNATURE_FAILURE: //TODO map break; case PRXYERR_R_LPROXY_MISSED_USED: //TODO map break; case PRXYERR_R_BAD_PROXY_ISSUER: // canl_err = CANL_ERR_certWrongProxyIssuer; //TODO does not exist yet break; case PRXYERR_R_BAD_MAGIC: //Todo map break; } return canl_err; } /* this function has to return # bytes written or ret < 0 when sth went wrong*/ static size_t ssl_write(glb_ctx *cc, io_handler *io, void *auth_ctx, void *buffer, size_t size, struct timeval *timeout) { int ret = 0, nwritten=0, ret2 = 0; const char *str; int fd = -1; time_t starttime, curtime; int expected = 0, error = 0; int locl_timeout; SSL *ssl = (SSL *) auth_ctx; if (cc == NULL) return -1; if (io == NULL) { set_error(cc, EINVAL, POSIX_ERROR, "Connection not established"); return -1; } if (ssl == NULL) { set_error(cc, EINVAL, POSIX_ERROR, "SSL not initialized"); return -1; } fd = BIO_get_fd(SSL_get_rbio(ssl), NULL); str = buffer;//TODO !!!!!! text.c_str(); curtime = starttime = time(NULL); if (timeout) { locl_timeout = timeout->tv_sec; } else { locl_timeout = -1; } ERR_clear_error(); do { ret = do_select(fd, starttime, locl_timeout, expected); curtime = time(NULL); if (ret > 0) { ret2 = SSL_write(ssl, str + nwritten, size - nwritten); if (ret2 <= 0) { expected = error = SSL_get_error(ssl, ret2); } } nwritten += ret; if ((size_t)nwritten == size) goto end; } while (TEST_SELECT(ret, ret2, locl_timeout, curtime, starttime, error)); end: curtime = time(NULL); if (timeout) timeout->tv_sec = timeout->tv_sec - (curtime - starttime); if (ret <= 0 || ret2 <= 0) { // what if ret2 == 0? conn closed? if (locl_timeout != -1 && (curtime - starttime >= locl_timeout)){ timeout->tv_sec = 0; timeout->tv_usec = 0; set_error(cc, ETIMEDOUT, POSIX_ERROR, "Connection stuck" " during write: timeout reached"); return -1; } else { set_error(cc, 0, UNKNOWN_ERROR, "Error during SSL write"); return -1; } } return ret2; } static size_t ssl_read(glb_ctx *cc, io_handler *io, void *auth_ctx, void *buffer, size_t size, struct timeval *tout) { int ret = 0, nwritten=0, ret2 = 0; char *str; int fd = -1; time_t starttime, curtime; int expected = 0, error = 0; int timeout; SSL *ssl = (SSL *) auth_ctx; if (cc == NULL) return -1; if (io == NULL) { set_error(cc, EINVAL, POSIX_ERROR, "Connection not established"); return -1; } if (ssl == NULL) { set_error(cc, EINVAL, POSIX_ERROR, "SSL not initialized"); return -1; } fd = BIO_get_fd(SSL_get_rbio(ssl), NULL); str = buffer;//TODO !!!!!! text.c_str(); curtime = starttime = time(NULL); if (tout) { timeout = tout->tv_sec; } else timeout = -1; ERR_clear_error(); do { ret = do_select(fd, starttime, timeout, expected); curtime = time(NULL); if (ret > 0) { ret2 = SSL_read(ssl, str + nwritten, size - nwritten); if (ret2 <= 0) { expected = error = SSL_get_error(ssl, ret2); } } } while (TEST_SELECT(ret, ret2, timeout, curtime, starttime, error)); if (tout) tout->tv_sec = tout->tv_sec - (curtime - starttime); if (ret <= 0 || ret2 <= 0) { // what if ret2 == 0? conn closed? if (timeout != -1 && (curtime - starttime >= timeout)){ tout->tv_sec = 0; tout->tv_usec = 0; set_error(cc, ETIMEDOUT, POSIX_ERROR, "Connection stuck" " during read: timeout reached"); return -1; } else { set_error(cc, 1, UNKNOWN_ERROR, "Error during SSL read"); return -1; } } return ret2; } /* ret > 1 if connection does not exist or has been closed before * ret = 0 connection closed successfully (one direction) * ret = 1 connection closed successfully (both directions) * ret < 0 error occured (e.g. timeout reached) */ static canl_err_code ssl_close(glb_ctx *cc, io_handler *io, void *auth_ctx) { int timeout = DESTROY_TIMEOUT; time_t starttime, curtime; int expected = 0, error = 0, ret = 0, ret2 = 0; int fd; unsigned long ssl_err = 0; SSL *ssl = (SSL *) auth_ctx; if (!cc) return EINVAL; if (!io) return set_error(cc, EINVAL, POSIX_ERROR, "Connection not initialized"); if (ssl == NULL) return set_error(cc, EINVAL, POSIX_ERROR, "SSL not initialized"); fd = BIO_get_fd(SSL_get_rbio(ssl), NULL); curtime = starttime = time(NULL); /* check the shutdown state*/ ret = SSL_get_shutdown(ssl); if (ret & SSL_SENT_SHUTDOWN) { if (ret & SSL_RECEIVED_SHUTDOWN) return 1; else return 0; } /* TODO check the proper states, maybe also call SSL_shutdown if (ret & SSL_RECEIVED_SHUTDOWN) { return 0; } */ do { ret = do_select(fd, starttime, timeout, expected); curtime = time(NULL); if (ret > 0) { ret2 = SSL_shutdown(ssl); if (ret2 < 0) { ssl_err = ERR_peek_error(); expected = error = SSL_get_error(ssl, ret2); } } } while (TEST_SELECT(ret, ret2, timeout, curtime, starttime, error)); if (timeout != -1 && (curtime - starttime >= timeout)){ set_error(cc, ETIMEDOUT, POSIX_ERROR, "Connection stuck" " during ssl shutdown : timeout reached"); return -1; } /* TODO set_error*/ if (ret < 0) { set_error(cc, 0, UNKNOWN_ERROR, "Error during SSL shutdown"); return -1; } /* successful shutdown (uni/bi directional)*/ if (ret2 == 0 || ret2 == 1) return ret2; else { set_error(cc, ssl_err, SSL_ERROR, "Error during SSL shutdown"); return -1; } } static canl_err_code ssl_finish(glb_ctx *cc, void *ctx) { SSL_free(ctx); return 0; } static canl_err_code ssl_free_ctx(glb_ctx *cc) { mech_glb_ctx *m_ctx = cc->mech_ctx; SSL_CTX_free(m_ctx->mech_ctx); m_ctx->mech_ctx = NULL; if (!m_ctx) return 0; if (m_ctx->ca_dir){ free(m_ctx->ca_dir); m_ctx->ca_dir = NULL; } if (m_ctx->ca_file){ free(m_ctx->ca_file); m_ctx->ca_file = NULL; } if (m_ctx->crl_dir){ free(m_ctx->crl_dir); m_ctx->crl_dir = NULL; } if (m_ctx->cert_key){ if (m_ctx->cert_key->cert){ X509_free(m_ctx->cert_key->cert); m_ctx->cert_key->cert = NULL; } if (m_ctx->cert_key->key){ EVP_PKEY_free(m_ctx->cert_key->key); m_ctx->cert_key->key = NULL; } if (m_ctx->cert_key->chain){ sk_X509_pop_free(m_ctx->cert_key->chain, X509_free); m_ctx->cert_key->chain = NULL; } free(m_ctx->cert_key); m_ctx->cert_key = NULL; } if (m_ctx->pvd_ctx){ canl_pvd_destroy_initializers(m_ctx->pvd_ctx); m_ctx->pvd_ctx = NULL; } if (m_ctx->ocsp_url){ free(m_ctx->ocsp_url); m_ctx->ocsp_url = NULL; } free(m_ctx); cc->mech_ctx = NULL; return 0; } /*maybe move to better file*/ canl_err_code canl_ctx_set_ssl_cred(canl_ctx cc, char *cert, char *key, char *proxy, canl_password_callback cb, void *userdata) { glb_ctx *glb_cc = (glb_ctx*) cc; int err = 0; mech_glb_ctx *m_ctx = (mech_glb_ctx *)glb_cc->mech_ctx; if (!m_ctx) return set_error(cc, EINVAL, POSIX_ERROR, "SSL context not" " initialized"); if (!cc) return EINVAL; if(!cert ) { set_error(glb_cc, EINVAL, POSIX_ERROR, "invalid parameter value"); return EINVAL; } err = do_set_ctx_own_cert_file(glb_cc, m_ctx, cert, key, proxy); if(err) { // update_error(glb_cc, "can't set cert or key to context"); } return err; } canl_err_code canl_ctx_set_ssl_flags(canl_ctx cc, unsigned int flags) { glb_ctx *glb_cc = (glb_ctx*) cc; mech_glb_ctx *m_ctx = (mech_glb_ctx *)glb_cc->mech_ctx; if (!m_ctx) return set_error(cc, EINVAL, POSIX_ERROR, "SSL context not" " initialized"); if (!cc) return EINVAL; m_ctx->flags |= flags; return 0; } canl_err_code CANL_CALLCONV canl_ocsp_set_url(canl_ctx cc, const char *ocsp_url) { glb_ctx *glb_cc = (glb_ctx*) cc; mech_glb_ctx *m_ctx = (mech_glb_ctx *)glb_cc->mech_ctx; if (!cc) return EINVAL; if (!m_ctx) return set_error(glb_cc, EINVAL, POSIX_ERROR, "SSL context not" " initialized"); m_ctx->ocsp_url = strdup(ocsp_url); return 0; } canl_err_code canl_ctx_set_crl_dir(canl_ctx cc, const char *dir) { glb_ctx *glb_cc = (glb_ctx*) cc; mech_glb_ctx *m_ctx = (mech_glb_ctx *)glb_cc->mech_ctx; if (!cc) return EINVAL; if (!m_ctx) return set_error(glb_cc, EINVAL, POSIX_ERROR, "SSL context not" " initialized"); return ssl_set_dir(glb_cc, &m_ctx->crl_dir, dir); } canl_err_code canl_ctx_set_ca_dir(canl_ctx cc, const char *dir) { glb_ctx *glb_cc = (glb_ctx*) cc; mech_glb_ctx *m_ctx = (mech_glb_ctx *)glb_cc->mech_ctx; if (!cc) return EINVAL; if (!m_ctx) return set_error(glb_cc, EINVAL, POSIX_ERROR, "SSL context not" " initialized"); return ssl_set_dir(glb_cc, &m_ctx->ca_dir, dir); } canl_err_code canl_ctx_set_ca_fn(canl_ctx cc, const char *fn) { glb_ctx *glb_cc = (glb_ctx*) cc; mech_glb_ctx *m_ctx = (mech_glb_ctx *)glb_cc->mech_ctx; if (!cc) return EINVAL; if (!m_ctx) return set_error(glb_cc, EINVAL, POSIX_ERROR, "Mech context not" " initialized"); return ssl_set_dir(glb_cc, &m_ctx->ca_file, fn); } canl_err_code CANL_CALLCONV canl_ssl_ctx_set_clb(canl_ctx cc, SSL_CTX *ssl_ctx, int ver_mode, int (*verify_callback)(int, X509_STORE_CTX *)) { glb_ctx *glb_cc = (glb_ctx*) cc; int (*vc)(int, X509_STORE_CTX *) = NULL; X509_STORE *store; vc = (verify_callback) ? verify_callback : proxy_verify_callback; if (!cc) return EINVAL; if (!ssl_ctx) return set_error(glb_cc, EINVAL, POSIX_ERROR, "SSL context not" " initialized"); mech_glb_ctx *m_ctx = (mech_glb_ctx *)glb_cc->mech_ctx; setup_SSL_proxy_handler(glb_cc, ssl_ctx, m_ctx->ca_dir, 1); store = SSL_CTX_get_cert_store(ssl_ctx); X509_STORE_set_check_issued(store, proxy_check_issued); SSL_CTX_set_verify(ssl_ctx, ver_mode, vc); return 0; } int CANL_CALLCONV canl_direct_pv_clb(canl_ctx cc, X509_STORE_CTX *store_ctx, int ok) { glb_ctx *glb_cc = (glb_ctx*) cc; if (!store_ctx){ if (glb_cc) set_error(glb_cc, EINVAL, POSIX_ERROR, "X509_STORE_CTX not" " initialized"); return 0; } return proxy_verify_callback(ok, store_ctx); } static canl_err_code ssl_get_peer(glb_ctx *cc, io_handler *io, void *auth_ctx, canl_principal *peer) { struct _principal_int *princ; SSL *ssl = (SSL *) auth_ctx; X509 *cert = NULL; X509_NAME *subject = NULL; int ret; BIO *name_out = BIO_new(BIO_s_mem()); long name_len = 0; mech_glb_ctx *m_ctx = (mech_glb_ctx *)cc->mech_ctx; if (peer == NULL) return set_error(cc, EINVAL, POSIX_ERROR, "invalid parameter value"); cert = SSL_get_peer_certificate(ssl); if (cert == NULL) return set_error(cc, CANL_ERR_noPeerCertificate, CANL_ERROR, "No peer certificate"); princ = calloc(1, sizeof(*princ)); if (princ == NULL) return set_error(cc, ENOMEM, POSIX_ERROR, "Not enough memory"); subject = X509_get_subject_name(cert); if (CANL_SSL_DN_OSSL & m_ctx->flags) ret = X509_NAME_print_ex(name_out, subject, 0, 0); else ret = X509_NAME_print_ex(name_out, subject, 0, XN_FLAG_RFC2253); if (!ret){ ret = set_error(cc, CANL_ERR_unknown, CANL_ERROR, "Cannot extract subject name out of" " the peer's certificate"); //TODO error code goto end; } name_len = BIO_ctrl_pending(name_out); if (name_len) { princ->name = (char *) malloc((name_len +1) * sizeof(char)); if (princ->name == NULL) { ret = set_error(cc, ENOMEM, POSIX_ERROR, "Not enough memory"); goto end; } } else { ret = set_error(cc, CANL_ERR_unknown, CANL_ERROR, "Zero subject name length"); //TODO error code goto end; } BIO_read(name_out, princ->name, name_len); princ->name[name_len] = '\0'; *peer = princ; princ = NULL; ret = 0; end: if (princ) free(princ); BIO_vfree(name_out); return ret; } #ifdef DEBUG static void dbg_print_ssl_error(int errorcode) { printf("[DBG CANL] "); switch (errorcode) { case SSL_ERROR_NONE: printf ("SSL_ERROR_NONE\n"); break; case SSL_ERROR_ZERO_RETURN: printf("SSL_ERROR_ZERO_RETURN\n"); break; case SSL_ERROR_WANT_READ: printf ("SSL_ERROR_WANT_READ\n"); break; case SSL_ERROR_WANT_WRITE: printf ("SSL_ERROR_WANT_WRITE\n"); break; case SSL_ERROR_WANT_CONNECT: printf ("SSL_ERROR_WANT_CONNECT\n"); break; case SSL_ERROR_WANT_ACCEPT: printf ("SSL_ERROR_WANT_ACCEPT\n"); break; case SSL_ERROR_WANT_X509_LOOKUP: printf ("SSL_ERROR_WANT_X509_LOOKUP\n"); break; case SSL_ERROR_SYSCALL: printf ("SSL_ERROR_SYSCALL\n"); break; case SSL_ERROR_SSL: printf ("SSL_ERROR_SSL\n"); break; default: printf ("no known error\n"); break; } } #endif canl_mech canl_mech_ssl = { TLS, ssl_initialize, ssl_set_flags, ssl_finish, ssl_client_init, ssl_server_init, ssl_free_ctx, ssl_connect, ssl_accept, ssl_close, ssl_read, ssl_write, ssl_get_peer, }; canl-c-3.0.0/src/canl.h0000644000015500017500000000406113017332512014320 0ustar tomcat6jenkins#ifndef _CANL_H #define _CANL_H #include #include #include /* for the OID structs */ #ifdef __cplusplus extern "C" { #endif #ifndef CANL_CALLCONV #define CANL_CALLCONV #endif typedef void *canl_io_handler; typedef void *canl_ctx; typedef void *canl_principal; typedef unsigned long canl_err_code; typedef char (*canl_password_callback)(canl_ctx cc, void *userdata); canl_ctx CANL_CALLCONV canl_create_ctx(); void CANL_CALLCONV canl_free_ctx(canl_ctx cc); canl_err_code CANL_CALLCONV canl_create_io_handler(canl_ctx cc, canl_io_handler *io); canl_err_code CANL_CALLCONV canl_io_connect(canl_ctx cc, canl_io_handler io, const char *host, const char *service, int port, gss_OID_set auth_mechs, int flags, canl_principal *peer, struct timeval *timeout); canl_err_code CANL_CALLCONV canl_io_accept(canl_ctx cc, canl_io_handler io, int fd, struct sockaddr s_addr, int flags, canl_principal *peer, struct timeval *timeout); size_t CANL_CALLCONV canl_io_read(canl_ctx cc, canl_io_handler io, void *buffer, size_t size, struct timeval *timeout); size_t CANL_CALLCONV canl_io_write(canl_ctx cc, canl_io_handler io, void *buffer, size_t size, struct timeval *timeout); canl_err_code CANL_CALLCONV canl_get_error_code(canl_ctx cc); char * CANL_CALLCONV canl_get_error_message(canl_ctx); canl_err_code CANL_CALLCONV canl_io_close(canl_ctx cc, canl_io_handler io); canl_err_code CANL_CALLCONV canl_io_destroy(canl_ctx cc, canl_io_handler io); canl_err_code CANL_CALLCONV canl_princ_name(canl_ctx, const canl_principal, char **); canl_err_code CANL_CALLCONV canl_princ_mech(canl_ctx, const canl_principal, gss_OID *); void CANL_CALLCONV canl_princ_free(canl_ctx, canl_principal); char * CANL_CALLCONV canl_mech2str(canl_ctx, gss_OID); const gss_OID_desc * CANL_CALLCONV canl_str2mech(canl_ctx, const char mech); canl_err_code CANL_CALLCONV canl_ctx_set_pkcs11_lib(canl_ctx, const char *); canl_err_code CANL_CALLCONV canl_ctx_set_pkcs11_init_args(canl_ctx, const char *); #ifdef __cplusplus } #endif #endif canl-c-3.0.0/src/canl_cred.h0000644000015500017500000000605113017332512015316 0ustar tomcat6jenkins#ifndef _CANL_CRED_H #define _CANL_CRED_H #include #include #ifdef __cplusplus extern "C" { #endif typedef void *canl_cred; typedef enum canl_cert_type { CANL_EEC, CANL_RFC, } canl_cert_type; typedef struct _creds { EVP_PKEY *c_key; STACK_OF(X509) *c_cert_chain; X509 *c_cert; long c_lifetime; STACK_OF(X509_EXTENSION) * c_cert_ext; canl_cert_type c_type; X509_REQ *c_req; } creds; /* Routines to handle credentials */ canl_err_code CANL_CALLCONV canl_cred_new(canl_ctx, canl_cred *); canl_err_code CANL_CALLCONV canl_cred_free(canl_ctx, canl_cred); canl_err_code CANL_CALLCONV canl_ctx_set_cred(canl_ctx, canl_cred); canl_err_code CANL_CALLCONV canl_cred_load_priv_key_file(canl_ctx, canl_cred, const char *, canl_password_callback, void *); canl_err_code CANL_CALLCONV canl_cred_load_priv_key(canl_ctx, canl_cred, EVP_PKEY *); canl_err_code CANL_CALLCONV canl_cred_save_priv_key(canl_ctx, canl_cred, EVP_PKEY **); canl_err_code CANL_CALLCONV canl_cred_load_priv_key_pkcs11(canl_ctx, canl_cred, const char *, canl_password_callback, void *); canl_err_code CANL_CALLCONV canl_cred_load_chain(canl_ctx, canl_cred, STACK_OF(X509) *); canl_err_code CANL_CALLCONV canl_cred_load_chain_file(canl_ctx, canl_cred, const char *); canl_err_code CANL_CALLCONV canl_cred_load_cert(canl_ctx, canl_cred, X509 *); canl_err_code CANL_CALLCONV canl_cred_load_cert_file(canl_ctx, canl_cred, const char *); canl_err_code CANL_CALLCONV canl_cred_load_cert_pkcs11(canl_ctx, canl_cred, const char *); canl_err_code CANL_CALLCONV canl_cred_set_lifetime(canl_ctx, canl_cred, const long); canl_err_code CANL_CALLCONV canl_cred_set_extension(canl_ctx, canl_cred, X509_EXTENSION *); canl_err_code CANL_CALLCONV canl_cred_set_cert_type(canl_ctx, canl_cred, const enum canl_cert_type); canl_err_code CANL_CALLCONV canl_cred_sign_proxy(canl_ctx, canl_cred, canl_cred); canl_err_code CANL_CALLCONV canl_cred_save_proxyfile(canl_ctx, canl_cred, const char *); canl_err_code CANL_CALLCONV canl_cred_save_cert(canl_ctx, canl_cred, X509 **); canl_err_code CANL_CALLCONV canl_cred_save_chain(canl_ctx, canl_cred, STACK_OF(X509) **); /* Routines to handle X.509 requests */ canl_err_code CANL_CALLCONV canl_cred_new_req(canl_ctx, canl_cred, unsigned int); canl_err_code CANL_CALLCONV canl_cred_save_req(canl_ctx, canl_cred, X509_REQ **); canl_err_code CANL_CALLCONV canl_cred_load_req(canl_ctx, canl_cred, const X509_REQ *); /* Routines to verify cert. chain */ /* Verify certificate chain, openssl verif. CRL, OCSP, signing policies etc. */ canl_err_code CANL_CALLCONV canl_verify_chain(canl_ctx ctx, X509 *ucert, STACK_OF(X509) *cert_chain, char *cadir); /* Verify certificate chain, SKIP openssl verif. part; Check CRL, OCSP, * signing policies etc. */ canl_err_code CANL_CALLCONV canl_verify_chain_wo_ossl(canl_ctx ctx, char *cadir, X509_STORE_CTX *store_ctx); #if 0 canl_err_code CANL_CALLCONV canl_req_get_pair(canl_ctx, canl_x509_req, EVP_PKEY **); #endif #ifdef __cplusplus } #endif #endif canl-c-3.0.0/src/canl_locl.h0000644000015500017500000000615413017332512015336 0ustar tomcat6jenkins#ifndef _CANL_LOCL_H #define _CANL_LOCL_H #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "sslutils.h" #include "canl.h" #include "canl_err.h" typedef struct canl_err_desc { canl_error code; const char *desc; unsigned long openssl_lib; unsigned long openssl_reason; } canl_err_desc; typedef enum canl_err_origin { UNKNOWN_ERROR = 0, POSIX_ERROR, SSL_ERROR, CANL_ERROR, NETDB_ERROR, } canl_err_origin; typedef enum _CANL_AUTH_MECHANISM { AUTH_UNDEF = -1, x509 = 0, KRB5 = 1, /* and others may be added*/ TLS, GSSAPI, } CANL_AUTH_MECHANISM; typedef struct _glb_ctx { char * err_msg; canl_err_code err_code; /* XXX Do we need to keep these two:? */ canl_err_origin err_orig; long original_err_code; void *mech_ctx; } glb_ctx; typedef struct _asyn_result { struct hostent *ent; int err; } asyn_result; typedef struct _principal_int { char *name; // CANL_AUTH_MECHANISM mech_oid; // char *raw; /* e.g. the PEM encoded cert/chain */ } principal_int; typedef struct _io_handler { int sock; principal_int *princ_int; void *conn_ctx; //like SSL * gss_OID oid; } io_handler; typedef struct canl_mech { CANL_AUTH_MECHANISM mech; canl_err_code (*initialize) (glb_ctx *); canl_err_code (*set_flags) (glb_ctx *cc, unsigned int *mech_flags, unsigned int flags); canl_err_code (*finish) (glb_ctx *, void *); canl_err_code (*client_init) (glb_ctx *, void **); canl_err_code (*server_init) (glb_ctx *, void **); canl_err_code (*free_ctx) (glb_ctx *); canl_err_code (*connect) (glb_ctx *, io_handler *, void *, struct timeval *, const char *); canl_err_code (*accept) (glb_ctx *, io_handler *, void *, struct timeval *); canl_err_code (*close) (glb_ctx *, io_handler *, void *); size_t (*read) (glb_ctx *, io_handler *, void *, void *, size_t, struct timeval *); size_t (*write) (glb_ctx *, io_handler *, void *, void *, size_t, struct timeval *); canl_err_code (*get_peer) (glb_ctx *, io_handler *, void *, canl_principal *); } canl_mech; /* Mechanism specific */ extern canl_mech canl_mech_ssl; extern canl_err_desc canl_err_descs[]; extern int canl_err_descs_num; struct canl_mech * find_mech(gss_OID oid); void reset_error (glb_ctx *cc, unsigned long err_code); canl_err_code set_error (glb_ctx *cc, unsigned long err_code, canl_err_origin err_orig, const char *err_format, ...); canl_err_code update_error (glb_ctx *cc, unsigned long err_code, canl_err_origin err_orig, const char *err_format, ...); void free_hostent(struct hostent *h); //TODO is there some standard funcion to free hostent? int canl_asyn_getservbyname(int a_family, asyn_result *ares_result,char const *name, struct timeval *timeout); #endif canl-c-3.0.0/src/canl_mech_ssl.h0000644000015500017500000000166113017332512016200 0ustar tomcat6jenkins#ifndef _CANL_MECH_SSL_H #define _CANL_MECH_SSL_H #include #include #include #include #include #include typedef struct _cert_key_store { X509 *cert; EVP_PKEY *key; STACK_OF(X509) *chain; } cert_key_store; typedef struct _mech_glb_ctx { void *mech_ctx; //like SSL_CTX * unsigned int flags; char *ca_dir; char *ca_file; char *crl_dir; cert_key_store *cert_key; canl_proxy_verify_desc *pvd_ctx; char *ocsp_url; } mech_glb_ctx; int do_set_ctx_own_cert_file(glb_ctx *cc, mech_glb_ctx *m_ctx, char *cert, char *key, char * proxy); int set_key_file(glb_ctx *cc, EVP_PKEY **to, const char *key); int set_cert_file(glb_ctx *cc, X509 **to, const char *cert); int set_cert_chain_file(glb_ctx *cc, STACK_OF(X509) **to, const char *cert); void pkey_dup(EVP_PKEY **to, EVP_PKEY *from); #endif canl-c-3.0.0/src/canl_ocsp.h0000644000015500017500000000345313017332512015350 0ustar tomcat6jenkins#ifndef _CANL_OCSP_H #define _CANL_OCSP_H #include "canl_locl.h" typedef struct { char *ca_dir; char *ca_file; char *crl_dir; } canl_x509store_t; typedef struct { char *url; X509 *cert; X509 *issuer; STACK_OF(X509) *cert_chain; canl_x509store_t store; X509 *sign_cert; EVP_PKEY *sign_key; long skew; long maxage; int timeout; } canl_ocsprequest_t; typedef enum { CANL_OCSPRESULT_ERROR_NOSTATUS = -17, CANL_OCSPRESULT_ERROR_INVTIME = -16, CANL_OCSPRESULT_ERROR_VERIFYRESPONSE = -15, CANL_OCSPRESULT_ERROR_NOTCONFIGURED = -14, CANL_OCSPRESULT_ERROR_NOAIAOCSPURI = -13, CANL_OCSPRESULT_ERROR_INVALIDRESPONSE = -12, CANL_OCSPRESULT_ERROR_CONNECTFAILURE = -11, CANL_OCSPRESULT_ERROR_SIGNFAILURE = -10, CANL_OCSPRESULT_ERROR_BADOCSPADDRESS = -9, CANL_OCSPRESULT_ERROR_OUTOFMEMORY = -8, CANL_OCSPRESULT_ERROR_UNKNOWN = -7, CANL_OCSPRESULT_ERROR_UNAUTHORIZED = -6, CANL_OCSPRESULT_ERROR_SIGREQUIRED = -5, CANL_OCSPRESULT_ERROR_TRYLATER = -3, CANL_OCSPRESULT_ERROR_INTERNALERROR = -2, CANL_OCSPRESULT_ERROR_MALFORMEDREQUEST = -1, CANL_OCSPRESULT_CERTIFICATE_VALID = 0, CANL_OCSPRESULT_CERTIFICATE_REVOKED = 1 } canl_ocspresult_t; /* Methods to access canl_ocsprequest_t */ int set_ocsp_sign_cert(canl_ocsprequest_t *ocspreq, X509 *sign_cert); int set_ocsp_sign_key(canl_ocsprequest_t *ocspreq, EVP_PKEY *sign_key); int set_ocsp_url(canl_ocsprequest_t *ocspreq, char *url); int ocsprequest_init(canl_ocsprequest_t **ocspreq); void ocsprequest_free(canl_ocsprequest_t *ocspreq); int do_ocsp_verify (canl_ocsprequest_t *data); #endif canl-c-3.0.0/src/canl_ssl.h0000644000015500017500000000435413017332512015206 0ustar tomcat6jenkins#ifndef _CANL_SSL_H #define _CANL_SSL_H #include #include #ifdef __cplusplus extern "C" { #endif typedef enum canl_ctx_ssl_flags { CANL_SSL_ACCEPT_SSLv2 = 0x0001, CANL_SSL_DN_OSSL = 0x0002, CANL_SSL_VERIFY_NONE = 0x0004, CANL_SSL_OCSP_VERIFY_ALL = 0x0008, } canl_ctx_ssl_flags; canl_err_code CANL_CALLCONV canl_ctx_set_ssl_flags(canl_ctx, unsigned int); canl_err_code CANL_CALLCONV canl_ctx_set_ssl_cred(canl_ctx, char *, char *key, char *proxy, canl_password_callback, void *); canl_err_code CANL_CALLCONV canl_ctx_set_ca_dir(canl_ctx, const char *); canl_err_code CANL_CALLCONV canl_ctx_set_crl_dir(canl_ctx, const char *); canl_err_code CANL_CALLCONV canl_ctx_set_ca_fn(canl_ctx, const char *); /*MP not impemented yet*/ canl_err_code CANL_CALLCONV canl_ctx_set_crl_fn(canl_ctx, const char *); /* Set canl cert verification callbacks into SSL_CTX. Do not use SSL_CTX stored in canl_ctx. Special case: if verify_callback is not NULL, then caNl will be ready to use its callback,but it must be called separately by canl_direct_pv_clb() (e.g. in verify_callback)-try to avoid this, unless you know what you are doing. Any data set into the extern SSL_CTX by the caNl in this function are not freed by calling canl_free_ctx(). This might look like memory leak (e.g. by valgrind), but in this special case is intended. */ canl_err_code CANL_CALLCONV canl_ssl_ctx_set_clb(canl_ctx cc, SSL_CTX *ssl_ctx, int ver_mode, int (*verify_callback)(int, X509_STORE_CTX *)); /* Call caNl proxy certificate verification callback directly. Use it only when you really know what you are doing. canl_ssl_ctx_set_clb() should be called before. (X509_STORE_CTX param of this function must correspond to SSL_CTX of canl_ssl_ctx_set_clb()) Return - 0 varification OK, 1 verification failed Note: This is one of the funcions that accept NULL as canl_ctx parameter, since it is intended to be called inside other callback funcion. */ int CANL_CALLCONV canl_direct_pv_clb(canl_ctx cc, X509_STORE_CTX *store_ctx, int ok); canl_err_code CANL_CALLCONV canl_ocsp_set_url(canl_ctx cc, const char *ocsp_url); #ifdef __cplusplus } #endif #endif canl-c-3.0.0/src/gen_err_codes.pl0000755000015500017500000000046713017332513016377 0ustar tomcat6jenkins#!/usr/bin/perl $err_name = ""; $num = 0; print STDOUT qq (/* * Automatically generated file. Don't edit. */ typedef enum canl_error {); while () { chomp; next if /^\s*#/; printf ("\n CANL_ERR_%s%s,", $_, (!$num++) ? " = 1024" : ""); } print STDOUT qq ( } canl_error; ); canl-c-3.0.0/src/gen_err_desc.pl0000755000015500017500000000324213017332513016212 0ustar tomcat6jenkins#!/usr/bin/perl my $codes_file = $ARGV[0]; my $desc_file = $ARGV[1]; my %codes; my $err_name, $err_dsc, $openssl_err_lib, $openssl_err_reason; sub make_c_line { my ($err_name, $err_dsc, $openssl_err_lib, $openssl_err_reason) = @_; printf("\n { CANL_ERR_%s, \"%s\", %s, %s },", $err_name, $err_dsc, ($openssl_err_lib) ? $openssl_err_lib : "ERR_LIB_NONE", ($openssl_err_reason) ? $openssl_err_reason : 0); } die ("Usage: $0 ") if (!$codes_file || !$desc_file); open (ERRS, $codes_file) or die ("Failed to open $codes_file: $!"); while () { chomp; next if /^\s*#/; $codes{$_} = 1; } close (ERRS); print qq (/* * Automatically generated file. Don't edit. */ #include "canl_locl.h" #include "canl_mech_ssl.h" canl_err_desc canl_err_descs[] = {); open (DESC, $desc_file) or die ("Failed to open $desc_file: $!"); while () { chomp; next if /^\s*#/; $line = $_; if (!$line) { make_c_line($err_name, $err_dsc, $openssl_err_lib, $openssl_err_reason) if ($err_name); $err_name = $err_dsc = $openssl_err_lib = $openssl_err_reason = ""; next; } if (!$err_name) { ($err_name, $err_dsc) = split(/=/, $line, 2); defined($codes{$err_name}) or die("Unknown error code ('$err_name') read"); next; } if ($line =~ m/(.+)\.openssl_code=(.+),(.+)/) { ($name, $openssl_err_lib, $openssl_err_reason) = ($1,$2,$3); die ("Parsing error (\"$line\")") if ($name != $err_name); next; } } close (DESC); make_c_line ($err_name, $err_dsc, $openssl_err_lib, $openssl_err_reason) if ($err_name); print STDOUT qq ( }; int canl_err_descs_num = sizeof(canl_err_descs)/sizeof(*canl_err_descs); ); canl-c-3.0.0/src/proxy/0000755000015500017500000000000013017332513014413 5ustar tomcat6jenkinscanl-c-3.0.0/src/proxy/data.c0000644000015500017500000000037413017332512015473 0ustar tomcat6jenkins/* XXX from common/data.cc */ #include int hex2num(char c) { if (isdigit(c)) return c - '0'; else { char d = tolower(c); if (d >= 'a' && d <= 'f') return d - 'a' + 10; return 0; } } canl-c-3.0.0/src/proxy/doio.c0000644000015500017500000000320413017332512015507 0ustar tomcat6jenkins/********************************************************************* * * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it * * Copyright (c) Members of the EGEE Collaboration. 2004-2010. * See http://www.eu-egee.org/partners/ for details on the copyright holders. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Parts of this code may be based upon or even include verbatim pieces, * originally written by other people, in which case the original header * follows. * *********************************************************************/ #include "config.h" #include #include #include #include "doio.h" char *vsnprintf_wrap(const char *format, va_list v) { va_list w; va_copy(w,v);; char *str = NULL; int plen = 0; plen = vsnprintf(str, 0, format, v); if (plen > 0) { str = (char *)malloc(plen+1); if (str) { (void)vsnprintf(str, plen+1, format, w); va_end(w); } } return str; } char *snprintf_wrap(const char *format, ...) { va_list v; char *str = NULL; va_start(v, format); str = vsnprintf_wrap(format, v); va_end(v); return str; } canl-c-3.0.0/src/proxy/evaluate.c0000644000015500017500000002337513017332512016376 0ustar tomcat6jenkins/********************************************************************* * * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it * * Copyright (c) Members of the EGEE Collaboration. 2004-2010. * See http://www.eu-egee.org/partners/ for details on the copyright holders. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Parts of this code may be based upon or even include verbatim pieces, * originally written by other people, in which case the original header * follows. * *********************************************************************/ #include "config.h" #include #include "parsertypes.h" #include "doio.h" #include "listfunc.h" #include "normalize.h" #include #include #include static char *gethash(X509 *cert, char *hash); static int find_policy(struct policy **policies, X509 *cert, int current); static int evaluate_match_namespace(char *pattern, char *subject, int type); static int evaluate_match_signing(char *pattern, char *subject, int type); static int restriction_evaluate_policy(X509 *cert, struct policy *policy); static int evaluate_cert(X509 *cert, struct policy **namespaces); static int restriction_evaluate_namespace(STACK_OF(X509) *chain, struct policy **namespaces); static int restriction_evaluate_signing(STACK_OF(X509) *chain, struct policy **signings); static FILE *open_from_dir(char *path, char *file); extern int signinglex_init (void** scanner); extern void signingset_in (FILE * in_str ,void *yyscanner ); extern int signinglex_destroy (void* yyscanner ); extern int signingparse(struct policy ***policies, void *scanner); extern int namespaceslex_init (void** scanner); extern void namespacesset_in (FILE * in_str ,void *yyscanner ); extern int namespaceslex_destroy (void* yyscanner ); extern int namespacesparse(struct policy ***policies, void *scanner); static int find_policy(struct policy **policies, X509 *cert, int current) { int i = (current == -1 ? 0 : current + 1); char hash[EVP_MAX_MD_SIZE+1]; if (!policies || !(policies[0]) || !cert) return -1; while (policies[i]) { if (policies[i]->self) { if (!strcmp(gethash(cert, hash), policies[i]->caname)) return i; } else { char *issuer = X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0); int ret = strcmp(issuer, policies[i]->caname); OPENSSL_free(issuer); if (!ret) return i; } i++; } /* If code reaches here, no match was found. */ return -1; } static char *gethash(X509 *cert, char *hash) { unsigned long hashvalue = X509_subject_name_hash(cert); sprintf(hash, "%08lx", hashvalue); return hash; } static int evaluate_match_namespace(char *pattern, char *subject, int type) { regex_t compiled; regmatch_t match[1]; int success = SUCCESS_UNDECIDED; char *patterntmp = normalize(pattern); char *subjecttmp = normalize(subject); if (!regcomp(&compiled, patterntmp, REG_NOSUB)) { if (!regexec(&compiled, subjecttmp, 0, match, 0)) { /* matched */ if (type) success = SUCCESS_PERMIT; else success = SUCCESS_DENY; } } regfree(&compiled); free(patterntmp); free(subjecttmp); return success; } static int evaluate_match_signing(char *pattern, char *subject, int type) { int success = SUCCESS_UNDECIDED; int len = 0; int compare; char *patterntmp = normalize(pattern); char *subjecttmp = normalize(subject); if (!pattern || !subject) return success; len = strlen(pattern); if (pattern[len-1] == '*') compare = strncmp(patterntmp, subjecttmp, len-1); else compare = strcmp(patterntmp, subjecttmp); free(patterntmp); free(subjecttmp); if (!compare) { if (type) return SUCCESS_PERMIT; else return SUCCESS_DENY; } return success; } static int restriction_evaluate_policy(X509 *cert, struct policy *policy) { int success = SUCCESS_UNDECIDED; char *subject = NULL; struct condition **cond = NULL; int condindex = 0; int subjindex = 0; if (!policy || !cert || !policy->conds) return success; subject = X509_NAME_oneline(X509_get_subject_name(cert), 0 ,0); if (!subject) return success; cond = policy->conds; while (cond[condindex]) { if (cond[condindex]->subjects) { char **subjects = cond[condindex]->subjects; int tempsuccess; while (subjects[subjindex]) { if (policy->type == TYPE_NAMESPACE) tempsuccess = evaluate_match_namespace(subjects[subjindex], subject, cond[condindex]->positive); else tempsuccess = evaluate_match_signing(subjects[subjindex], subject, cond[condindex]->positive); if (tempsuccess != SUCCESS_UNDECIDED) success = tempsuccess; if (success == SUCCESS_DENY) goto end; subjindex++; } } condindex++; } end: OPENSSL_free(subject); return success; } static int isselfsigned(X509*cert) { return !X509_NAME_cmp(X509_get_subject_name(cert), X509_get_issuer_name(cert)); } static int evaluate_cert(X509 *cert, struct policy **namespaces) { int result = SUCCESS_UNDECIDED; int policyindex = -1, currentindex = -1; /* self-signed certificates always pass */ if (isselfsigned(cert)) { char *subject = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0); OPENSSL_free(subject); return SUCCESS_PERMIT; } while ((policyindex = find_policy(namespaces, cert, currentindex)) != -1) { struct policy *policy = namespaces[policyindex]; result = restriction_evaluate_policy(cert, policy); if (result != SUCCESS_UNDECIDED) break; currentindex = policyindex; } return result; } static int restriction_evaluate_namespace(STACK_OF(X509) *chain, struct policy **namespaces) { int size = sk_X509_num(chain); int i = 0; int result = 0; int start = 0, end = 0; int step = 0; if (size > 1 && isselfsigned(sk_X509_value(chain,0))) { /* reverse certificate ordering. Reverse direction of visit */ start = size - 1; end = -1; step = -1; } else { /* right order */ start = 0; end = size; step = 1; } for (i = start; i != end; i += step) { int j; X509 *cert = sk_X509_value(chain, i); for (j = i; j >= 0; j--) { result = evaluate_cert(cert, namespaces); if (result != SUCCESS_UNDECIDED) break; } } if (result == SUCCESS_UNDECIDED) { result = SUCCESS_PERMIT; } return result; } static int restriction_evaluate_signing(STACK_OF(X509) *chain, struct policy **signings) { int size = sk_X509_num(chain); int i = 0; int result = 0; for (i = 0; i < size; i++) { X509 *cert = sk_X509_value(chain, i); result = evaluate_cert(cert, signings); if (result != SUCCESS_UNDECIDED) break; } if (result == SUCCESS_UNDECIDED) result = SUCCESS_DENY; return result; } int PRIVATE restriction_evaluate(STACK_OF(X509) *chain, struct policy **namespaces, struct policy **signings) { int result = 0; result = restriction_evaluate_namespace(chain, namespaces); if (result == SUCCESS_UNDECIDED) { result = restriction_evaluate_signing(chain, signings); } return result; } static void free_condition(struct condition *cond) { free(cond->original); free(cond->subjects); free(cond); } static void free_policy(struct policy *pol) { free(pol->caname); listfree((char**)(pol->conds), (freefn)free_condition); free(pol); } void PRIVATE voms_free_policies(struct policy **policies) { listfree((char**)policies, (freefn)free_policy); } static FILE *open_from_dir(char *path, char *filename) { char *realpath=snprintf_wrap("%s%s", path, filename); FILE *file = NULL; file = fopen(realpath, "rb"); free(realpath); return file; } void PRIVATE read_pathrestriction(STACK_OF(X509) *chain, char *path, struct policy ***names, struct policy ***signs) { int size = sk_X509_num(chain); char hashed[9]; char *hash; char signing[25] = "/XXXXXXXX.signing_policy"; char namespace[21] = "/XXXXXXXX.namespaces"; int i = 0, j = 0; FILE *file = NULL; for (i = 0; i < size; i++) { X509 *cert = sk_X509_value(chain, i); hash = gethash(cert, hashed); /* Determine file names */ strncpy(signing + 1, hash, 8); strncpy(namespace + 1, hash, 8); file = open_from_dir(path, signing); if (file) { void *scanner = NULL; signinglex_init(&scanner); signingset_in(file, scanner); (void)signingparse(signs, scanner); signinglex_destroy(scanner); fclose(file); } j = 0; if (*signs) { while ((*signs)[j]) { if ((*signs)[j]->self) (*signs)[j]->caname = strdup(hash); j++; } } file = open_from_dir(path, namespace); if (file) { void *scanner = NULL; namespaceslex_init(&scanner); namespacesset_in(file, scanner); (void)namespacesparse(names, scanner); namespaceslex_destroy(scanner); fclose(file); } if (*names) { int j = 0; while ((*names)[j]) { if ((*names)[j]->self) (*names)[j]->caname = strdup(hash); j++; } } } } canl-c-3.0.0/src/proxy/list.c0000644000015500017500000000334713017332512015540 0ustar tomcat6jenkins/********************************************************************* * * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it * * Copyright (c) Members of the EGEE Collaboration. 2004-2010. * See http://www.eu-egee.org/partners/ for details on the copyright holders. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Parts of this code may be based upon or even include verbatim pieces, * originally written by other people, in which case the original header * follows. * *********************************************************************/ #include "config.h" #include #include char **listadd(char **vect, char *data) { int i = 0; char **newvect; if (!data) return vect; if (vect) while (vect[i++]) ; else i=1; if ((newvect = (char **)malloc((i+1)*sizeof(char *)))) { if (vect) { memcpy(newvect, vect, (sizeof(char*)*(i-1))); newvect[i-1] = data; newvect[i] = NULL; free(vect); } else { newvect[0] = data; newvect[1] = NULL; } return newvect; } return NULL; } void listfree(char **vect, void (*f)(void *)) { char **tmp = vect; if (tmp) { int i = 0; while (tmp[i]) f(tmp[i++]); free(vect); } } canl-c-3.0.0/src/proxy/normalize.c0000644000015500017500000000427013017332512016561 0ustar tomcat6jenkins/********************************************************************* * * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it * * Copyright (c) Members of the EGEE Collaboration. 2004-2010. * See http://www.eu-egee.org/partners/ for details on the copyright holders. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Parts of this code may be based upon or even include verbatim pieces, * originally written by other people, in which case the original header * follows. * *********************************************************************/ #include "config.h" #include #include #include "doio.h" static char *change(const char *str, char *from, char *to) { char *copy = strdup(str); if (!copy) return NULL; char *pos = strstr(copy, from); char *tmp = NULL; while (pos) { *pos = '\0'; tmp = snprintf_wrap("%s%s%s", copy, to, pos + strlen(from)); if (tmp) { free(copy); copy = tmp; } pos = strstr(copy + strlen(to), from); } return copy; } char *normalize(const char *str) { char *tmp = NULL; char *tmp2 = NULL; tmp = change(str, "/USERID=", "/UID="); tmp2 = change(tmp, "/emailAddress=", "/Email="); free(tmp); tmp = change(tmp2, "/E=", "/Email="); free(tmp2); return tmp; } #if 0 int main(int argc, char *argv) { char *str1="/prova/Email=frge/CN=op"; char *str2="/prova/E=boh/emailAddress=mah/E=op/CN=fr"; char *str3="/USERID=56/mah"; char *n1 = normalize(str1); char *n2 = normalize(str2); char *n3 = normalize(str3); printf("%s -> %s\n", str1, n1); free(n1); printf("%s -> %s\n", str2, n2); free(n2); printf("%s -> %s\n", str3, n3); free(n3); exit(0); } #endif canl-c-3.0.0/src/proxy/proxycertinfo.c0000644000015500017500000003312713017332513017500 0ustar tomcat6jenkins/********************************************************************* * * Authors: Valerio Venturi - Valerio.Venturi@cnaf.infn.it * Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it * * Copyright (c) Members of the EGEE Collaboration. 2004-2010. * See http://www.eu-egee.org/partners/ for details on the copyright holders. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Parts of this code may be based upon or even include verbatim pieces, * originally written by other people, in which case the original header * follows. * *********************************************************************/ #include "config.h" #include #include #include #include "myproxycertinfo.h" #include "doio.h" /* myPROXYPOLICY function */ myPROXYPOLICY * myPROXYPOLICY_new() { ASN1_CTX c; myPROXYPOLICY * ret; ret = NULL; M_ASN1_New_Malloc(ret, myPROXYPOLICY); ret->policy_language = OBJ_nid2obj(OBJ_sn2nid(IMPERSONATION_PROXY_SN)); ret->policy = NULL; return (ret); M_ASN1_New_Error(ASN1_F_PROXYPOLICY_NEW); } void myPROXYPOLICY_free(myPROXYPOLICY * policy) { if(policy == NULL) return; ASN1_OBJECT_free(policy->policy_language); M_ASN1_OCTET_STRING_free(policy->policy); OPENSSL_free(policy); } /* duplicate */ myPROXYPOLICY * myPROXYPOLICY_dup(myPROXYPOLICY * policy) { #ifdef TYPEDEF_I2D_OF return ((myPROXYPOLICY *) ASN1_dup((i2d_of_void *)i2d_myPROXYPOLICY, (d2i_of_void *)d2i_myPROXYPOLICY, (char *)policy)); #else return ((myPROXYPOLICY *) ASN1_dup((int (*)())i2d_myPROXYPOLICY, (char *(*)())d2i_myPROXYPOLICY, (char *)policy)); #endif } /* set policy language */ int myPROXYPOLICY_set_policy_language(myPROXYPOLICY * policy, ASN1_OBJECT * policy_language) { if(policy_language != NULL) { ASN1_OBJECT_free(policy->policy_language); policy->policy_language = OBJ_dup(policy_language); return 1; } return 0; } /* get policy language */ ASN1_OBJECT * myPROXYPOLICY_get_policy_language(myPROXYPOLICY * policy) { return policy->policy_language; } /* set policy */ int myPROXYPOLICY_set_policy(myPROXYPOLICY * proxypolicy, unsigned char * policy, int length) { if(policy != NULL) { /* if member policy of proxypolicy non set */ if(!proxypolicy->policy) proxypolicy->policy = ASN1_OCTET_STRING_new(); /* set member policy of proxypolicy */ ASN1_OCTET_STRING_set(proxypolicy->policy, policy, length); } else ASN1_OCTET_STRING_free(proxypolicy->policy); return 1; } /* get policy */ unsigned char * myPROXYPOLICY_get_policy(myPROXYPOLICY * proxypolicy, int * length) { /* assure field policy is set */ if(proxypolicy->policy) { *length = proxypolicy->policy->length; /* assure ASN1_OCTET_STRING is full */ if (*length>0 && proxypolicy->policy->data) { unsigned char * copy = malloc(*length); memcpy(copy, proxypolicy->policy->data, *length); return copy; } } return NULL; } /* internal to der conversion */ int i2d_myPROXYPOLICY(myPROXYPOLICY * policy, unsigned char ** pp) { M_ASN1_I2D_vars(policy); M_ASN1_I2D_len(policy->policy_language, i2d_ASN1_OBJECT); if(policy->policy) { M_ASN1_I2D_len(policy->policy, i2d_ASN1_OCTET_STRING); } M_ASN1_I2D_seq_total(); M_ASN1_I2D_put(policy->policy_language, i2d_ASN1_OBJECT); if(policy->policy) { M_ASN1_I2D_put(policy->policy, i2d_ASN1_OCTET_STRING); } M_ASN1_I2D_finish(); } myPROXYPOLICY * d2i_myPROXYPOLICY(myPROXYPOLICY ** a, unsigned char ** pp, long length) { M_ASN1_D2I_vars(a, myPROXYPOLICY *, myPROXYPOLICY_new); M_ASN1_D2I_Init(); M_ASN1_D2I_start_sequence(); M_ASN1_D2I_get(ret->policy_language, d2i_ASN1_OBJECT); /* need to try getting the policy using * a) a call expecting no tags * b) a call expecting tags * one of which should succeed */ M_ASN1_D2I_get_opt(ret->policy, d2i_ASN1_OCTET_STRING, V_ASN1_OCTET_STRING); M_ASN1_D2I_get_IMP_opt(ret->policy, d2i_ASN1_OCTET_STRING, 0, V_ASN1_OCTET_STRING); M_ASN1_D2I_Finish(a, myPROXYPOLICY_free, ASN1_F_D2I_PROXYPOLICY); } /* myPROXYCERTINFO function */ myPROXYCERTINFO * myPROXYCERTINFO_new() { myPROXYCERTINFO * ret = NULL; ASN1_CTX c; M_ASN1_New_Malloc(ret, myPROXYCERTINFO); memset(ret, 0, sizeof(myPROXYCERTINFO)); ret->path_length = NULL; ret->proxypolicy = myPROXYPOLICY_new(); return (ret); M_ASN1_New_Error(ASN1_F_PROXYCERTINFO_NEW); } void myPROXYCERTINFO_free(myPROXYCERTINFO * proxycertinfo) { /* assure proxycertinfo not empty */ if(proxycertinfo == NULL) return; ASN1_INTEGER_free(proxycertinfo->path_length); myPROXYPOLICY_free(proxycertinfo->proxypolicy); OPENSSL_free(proxycertinfo); } /* set path_length */ int myPROXYCERTINFO_set_path_length(myPROXYCERTINFO * proxycertinfo, long path_length) { /* assure proxycertinfo is not empty */ if(proxycertinfo != NULL) { if(path_length != -1) { /* if member path_length is empty allocate memory then set */ if(proxycertinfo->path_length == NULL) proxycertinfo->path_length = ASN1_INTEGER_new(); return ASN1_INTEGER_set(proxycertinfo->path_length, path_length); } else { ASN1_INTEGER_free(proxycertinfo->path_length); proxycertinfo->path_length = NULL; } return 1; } return 0; } int myPROXYCERTINFO_set_version(myPROXYCERTINFO * proxycertinfo, int version) { if (proxycertinfo != NULL) { proxycertinfo->version = version; return 1; } return 0; } int myPROXYCERTINFO_get_version(myPROXYCERTINFO * proxycertinfo) { if (proxycertinfo) return proxycertinfo->version; return -1; } /* get path length */ long myPROXYCERTINFO_get_path_length(myPROXYCERTINFO * proxycertinfo) { if(proxycertinfo && proxycertinfo->path_length) return ASN1_INTEGER_get(proxycertinfo->path_length); else return -1; } /* set policy */ int myPROXYCERTINFO_set_proxypolicy(myPROXYCERTINFO * proxycertinfo, myPROXYPOLICY * proxypolicy) { myPROXYPOLICY_free(proxycertinfo->proxypolicy); if(proxypolicy != NULL) proxycertinfo->proxypolicy = myPROXYPOLICY_dup(proxypolicy); else proxycertinfo->proxypolicy = NULL; return 1; } /* get policy */ myPROXYPOLICY * myPROXYCERTINFO_get_proxypolicy(myPROXYCERTINFO * proxycertinfo) { if(proxycertinfo) return proxycertinfo->proxypolicy; return NULL; } /* internal to der conversion */ static int i2d_myPROXYCERTINFO_v3(myPROXYCERTINFO * proxycertinfo, unsigned char ** pp) { int v1; M_ASN1_I2D_vars(proxycertinfo); v1 = 0; M_ASN1_I2D_len(proxycertinfo->proxypolicy, i2d_myPROXYPOLICY); M_ASN1_I2D_len_EXP_opt(proxycertinfo->path_length,i2d_ASN1_INTEGER, 1, v1); M_ASN1_I2D_seq_total(); M_ASN1_I2D_put(proxycertinfo->proxypolicy, i2d_myPROXYPOLICY); M_ASN1_I2D_put_EXP_opt(proxycertinfo->path_length, i2d_ASN1_INTEGER, 1, v1); M_ASN1_I2D_finish(); } static int i2d_myPROXYCERTINFO_v4(myPROXYCERTINFO * proxycertinfo, unsigned char ** pp) { M_ASN1_I2D_vars(proxycertinfo); if(proxycertinfo->path_length) { M_ASN1_I2D_len(proxycertinfo->path_length, i2d_ASN1_INTEGER); } M_ASN1_I2D_len(proxycertinfo->proxypolicy, i2d_myPROXYPOLICY); M_ASN1_I2D_seq_total(); if(proxycertinfo->path_length) { M_ASN1_I2D_put(proxycertinfo->path_length, i2d_ASN1_INTEGER); } M_ASN1_I2D_put(proxycertinfo->proxypolicy, i2d_myPROXYPOLICY); M_ASN1_I2D_finish(); } int i2d_myPROXYCERTINFO(myPROXYCERTINFO * proxycertinfo, unsigned char ** pp) { switch(proxycertinfo->version) { case 3: return i2d_myPROXYCERTINFO_v3(proxycertinfo, pp); break; case 4: return i2d_myPROXYCERTINFO_v4(proxycertinfo, pp); break; default: return -1; break; } } static myPROXYCERTINFO * d2i_myPROXYCERTINFO_v3(myPROXYCERTINFO ** cert_info, unsigned char ** pp, long length) { M_ASN1_D2I_vars(cert_info, myPROXYCERTINFO *, myPROXYCERTINFO_new); M_ASN1_D2I_Init(); M_ASN1_D2I_start_sequence(); M_ASN1_D2I_get((ret->proxypolicy), d2i_myPROXYPOLICY); M_ASN1_D2I_get_EXP_opt(ret->path_length, d2i_ASN1_INTEGER, 1); ret->version = 3; M_ASN1_D2I_Finish(cert_info, myPROXYCERTINFO_free, ASN1_F_D2I_PROXYCERTINFO); } static myPROXYCERTINFO * d2i_myPROXYCERTINFO_v4(myPROXYCERTINFO ** cert_info, unsigned char ** pp, long length) { M_ASN1_D2I_vars(cert_info, myPROXYCERTINFO *, myPROXYCERTINFO_new); M_ASN1_D2I_Init(); M_ASN1_D2I_start_sequence(); M_ASN1_D2I_get_EXP_opt(ret->path_length, d2i_ASN1_INTEGER, 1); M_ASN1_D2I_get_opt(ret->path_length, d2i_ASN1_INTEGER, V_ASN1_INTEGER); M_ASN1_D2I_get((ret->proxypolicy),d2i_myPROXYPOLICY); ret->version = 4; M_ASN1_D2I_Finish(cert_info, myPROXYCERTINFO_free, ASN1_F_D2I_PROXYCERTINFO); } myPROXYCERTINFO * d2i_myPROXYCERTINFO(myPROXYCERTINFO ** cert_info, unsigned char ** pp, long length) { myPROXYCERTINFO *info = d2i_myPROXYCERTINFO_v3(cert_info, pp, length); if (!info) info = d2i_myPROXYCERTINFO_v4(cert_info, pp, length); return info; } static int nativeopenssl = 0; static char *norep() { static char *buffer=""; return buffer; } static void *myproxycertinfo_s2i(UNUSED(struct v3_ext_method *method), UNUSED(struct v3_ext_ctx *ctx), UNUSED(char *data)) { return (myPROXYCERTINFO*)data; } static char *myproxycertinfo_i2s(UNUSED(struct v3_ext_method *method), void *ext) { myPROXYCERTINFO *pci = NULL; char *encoding = NULL; char *output = NULL; myPROXYPOLICY *pp; int dooid = 0; char oid[256]; pci = (myPROXYCERTINFO *)ext; if (!pci) return norep(); if (pci->path_length) { int j = ASN1_INTEGER_get(pci->path_length); char *buffer = snprintf_wrap("%X", j); output = snprintf_wrap("Path Length Constraint: %s%s\n\n", strlen(buffer)%2 ? "0" : "", buffer); free(buffer); } else output = strdup("Path Length Constraint: unlimited\n"); pp = pci->proxypolicy; if (pp && i2t_ASN1_OBJECT(oid, 256, pp->policy_language)) { dooid = 1; } encoding = snprintf_wrap("%sPolicy Language: %s%s%s%s\n", output, ( dooid ? oid : ""), ( (pp && pp->policy) ? "\nPolicy Text: " : ""), ( (pp && pp->policy) ? (char*)ASN1_STRING_data(pp->policy) : ""), ( (pp && pp->policy) ? "\n" : "")); free(output); return encoding; } void InitProxyCertInfoExtension(int full) { #define PROXYCERTINFO_V3 "1.3.6.1.4.1.3536.1.222" #define PROXYCERTINFO_V4 "1.3.6.1.5.5.7.1.14" #define OBJC(c,n) OBJ_create(c,n,n) X509V3_EXT_METHOD *pcert; static int set = 0; ASN1_OBJECT *objv3; ASN1_OBJECT *objv4; if (set) return; set = 1; objv3 = OBJ_txt2obj(PROXYCERTINFO_V3,1); objv4 = OBJ_txt2obj(PROXYCERTINFO_V4,1); /* Proxy Certificate Extension's related objects */ if (OBJ_obj2nid(objv3) == 0) { ERR_clear_error(); OBJC(PROXYCERTINFO_V3, "Proxy Certificate Information"); if (full) { pcert = (X509V3_EXT_METHOD *)OPENSSL_malloc(sizeof(X509V3_EXT_METHOD)); if (pcert) { memset(pcert, 0, sizeof(*pcert)); pcert->ext_nid = OBJ_txt2nid(PROXYCERTINFO_V3); pcert->ext_flags = 0; pcert->ext_new = (X509V3_EXT_NEW) myPROXYCERTINFO_new; pcert->ext_free = (X509V3_EXT_FREE)myPROXYCERTINFO_free; pcert->d2i = (X509V3_EXT_D2I) d2i_myPROXYCERTINFO; pcert->i2d = (X509V3_EXT_I2D) i2d_myPROXYCERTINFO; pcert->i2s = (X509V3_EXT_I2S) myproxycertinfo_i2s; pcert->s2i = (X509V3_EXT_S2I) myproxycertinfo_s2i; pcert->v2i = (X509V3_EXT_V2I) NULL; pcert->r2i = (X509V3_EXT_R2I) NULL; pcert->i2v = (X509V3_EXT_I2V) NULL; pcert->i2r = (X509V3_EXT_I2R) NULL; X509V3_EXT_add(pcert); } } } if (OBJ_obj2nid(objv4) == 0) { ERR_clear_error(); OBJC(PROXYCERTINFO_V4, "Proxy Certificate Information"); if (full) { pcert = (X509V3_EXT_METHOD *)OPENSSL_malloc(sizeof(X509V3_EXT_METHOD)); if (pcert) { memset(pcert, 0, sizeof(*pcert)); pcert->ext_nid = OBJ_txt2nid(PROXYCERTINFO_V4); pcert->ext_flags = 0; pcert->ext_new = (X509V3_EXT_NEW) myPROXYCERTINFO_new; pcert->ext_free = (X509V3_EXT_FREE)myPROXYCERTINFO_free; pcert->d2i = (X509V3_EXT_D2I) d2i_myPROXYCERTINFO; pcert->i2d = (X509V3_EXT_I2D) i2d_myPROXYCERTINFO; pcert->i2s = (X509V3_EXT_I2S) myproxycertinfo_i2s; pcert->s2i = (X509V3_EXT_S2I) myproxycertinfo_s2i; pcert->v2i = (X509V3_EXT_V2I) NULL; pcert->r2i = (X509V3_EXT_R2I) NULL; pcert->i2v = (X509V3_EXT_I2V) NULL; pcert->i2r = (X509V3_EXT_I2R) NULL; X509V3_EXT_add(pcert); } } } #ifdef X509_V_FLAG_ALLOW_PROXY_CERTS nativeopenssl = 1; #endif ASN1_OBJECT_free(objv3); ASN1_OBJECT_free(objv4); return; } int proxynative(void) { return nativeopenssl; } canl-c-3.0.0/src/proxy/scutils.c0000644000015500017500000007144613017332513016261 0ustar tomcat6jenkins/********************************************************************** scutils.c Description: Routines used internally to work with smart card using PKCS11 **********************************************************************/ /********************************************************************** Include header files **********************************************************************/ //#include "config.h" #ifdef USE_PKCS11 #include "scutils.h" #include "sslutils.h" #ifndef WIN32 #define FILE_SEPERATOR "/" #else #define FILE_SEPERATOR "\\" #include #endif #include #include #include #ifdef USE_PKCS11_DL #include #endif #include #include #include #include #include #include #include #include #include /********************************************************************** Type definitions **********************************************************************/ /********************************************************************** Module specific prototypes **********************************************************************/ static int sc_RSA_eay_private_decrypt(int flen, unsigned char * from, unsigned char * to, RSA * rsa, int padding); static int sc_RSA_eay_private_encrypt(int flen, unsigned char * from, unsigned char * to, RSA * rsa, int padding); /********************************************************************** Define module specific variables **********************************************************************/ static ERR_STRING_DATA scerr_str_functs[]= { {ERR_PACK(0,SCERR_F_RSA_ENCRYPT,0),"sc_RSA_private_encrypt"}, {ERR_PACK(0,SCERR_F_RSA_DECRYPT,0),"sc_RSA_private_decrypt"}, {ERR_PACK(0,SCERR_F_SCINIT,0),"sc_init"}, {ERR_PACK(0,SCERR_F_GET_RSA_PRIV_KEY_OBJ,0),"sc_get_rsa_priv_key_obj"}, {ERR_PACK(0,SCERR_F_GET_PRIV_KEY_OBJ,0),"sc_get_priv_key_obj"}, {ERR_PACK(0,SCERR_F_GET_PRIV_KEY_BY_LABEL,0),"sc_get_priv_key_by_label"}, {ERR_PACK(0,SCERR_F_GET_CERT_OBJ,0),"sc_get_cert_obj"}, {ERR_PACK(0,SCERR_F_FIND_ONE_OBJ,0),"sc_find_one_obj"}, {ERR_PACK(0,SCERR_F_FIND_CERT_BY_LABEL,0),"sc_find_cert_by_label"}, {ERR_PACK(0,SCERR_F_LOAD_DLL,0),"sc_get_function_list"}, {0,NULL}, }; static ERR_STRING_DATA scerr_str_reasons[]= { {SCERR_R_PKCS11_ERROR, "PKCS11 error"}, {SCERR_R_SIGNINIT, "C_SignInit"}, {SCERR_R_SIGN, "C_Sign"}, {SCERR_R_SIGNRECINIT, "C_SignRecoverInit"}, {SCERR_R_SIGNREC, "C_SignRecover"}, {SCERR_R_INITIALIZE, "C_Initialize"}, {SCERR_R_GETSLOTLIST, "C-GetSlotList"}, {SCERR_R_OPENSESSION, "C_OpenSession"}, {SCERR_R_LOGIN, "C_Login"}, {SCERR_R_CREATEOBJ, "C_CreateObject"}, {SCERR_R_UNSUPPORTED, "Unsupported feature"}, {SCERR_R_GETATTRVAL, "C_GetAttributeValue"}, {SCERR_R_FINDOBJINIT, "C_FindObjectInit"}, {SCERR_R_FINDOBJ, "C_FindObject"}, {SCERR_R_FOUNDMANY, "Found more then one matching key"}, {SCERR_R_FIND_FAILED, "Unable to find object on smart card"}, {SCERR_R_NO_PKCS11_DLL,"Unable to load the PKCS11 support"}, {0,NULL}, }; CK_FUNCTION_LIST_PTR pFunctionList = NULL; #ifdef WIN32 HMODULE h_m_pkcs11 = NULL; #else void * h_m_pkcs11 = NULL; #endif /********************************************************************** Function: sc_get_function_list() Description: Get the name of the PKCS11 dll to use from the registry, load it, get the entry for the C_GetFunctionList call it to set the pFunctionList. Parameters: Returns: the pFunctionList or NULL **********************************************************************/ CK_FUNCTION_LIST_PTR sc_get_function_list() { CK_RV status; #if defined(USE_PKCS11_DL) || defined(WIN32) CK_RV (*gfl)(CK_FUNCTION_LIST_PTR_PTR); #endif if (pFunctionList) { return pFunctionList; } #if defined(USE_PKCS11_DL) || defined(WIN32) if (!h_m_pkcs11) { char * dllname = NULL; #ifdef WIN32 HKEY hkDir = NULL; char val_dllname[512] = {"NONE"}; LONG lval; DWORD type; if (!h_m_pkcs11) { RegOpenKey(HKEY_CURRENT_USER,GSI_REGISTRY_DIR,&hkDir); lval = sizeof(val_dllname) -1; if (hkDir && (RegQueryValueEx(hkDir, "PKCS11.DLL", 0, &type, val_dllname,&lval) == ERROR_SUCCESS)) { h_m_pkcs11 = LoadLibrary(val_dllname); } if (hkDir) { RegCloseKey(hkDir); } if (!h_m_pkcs11) { SCerr(SCERR_F_SCINIT,SCERR_R_NO_PKCS11_DLL); ERR_add_error_data(2,"Name of DLL=", dllname? dllname:"NONE"); return NULL; } } gfl = (CK_RV (*)(CK_FUNCTION_LIST_PTR *)) GetProcAddress(h_m_pkcs11,"C_GetFunctionList"); #else if (!h_m_pkcs11) { dllname = getenv("PKCS11_LIB"); if (!dllname) { dllname = "libDSPKCS.so"; } h_m_pkcs11 = dlopen(dllname,RTLD_LAZY); } if (!h_m_pkcs11) { SCerr(SCERR_F_SCINIT,SCERR_R_NO_PKCS11_DLL); ERR_add_error_data(2,"Name of shared library=", dllname); return NULL; } gfl = (CK_RV(*)(CK_FUNCTION_LIST_PTR_PTR)) dlsym(h_m_pkcs11,"C_GetFunctionList"); #endif if (!gfl) { SCerr(SCERR_F_LOAD_DLL,SCERR_R_NO_PKCS11_DLL); ERR_add_error_data(1,"Cant find C_GetFunctionList"); return NULL; } } status = (*gfl)(&pFunctionList); #else status = C_GetFunctionList(&pFunctionList); #endif /* PKCS11_DYNLOAD */ if (status != CKR_OK) { SCerr(SCERR_F_LOAD_DLL,SCERR_R_UNSUPPORTED); ERR_add_error_data(1,sc_ERR_code(status)); return NULL; } return pFunctionList; } /********************************************************************** Function: ERR_load_scerr_strings() Description: Sets up the error tables used by SSL and adds ours using the ERR_LIB_USER Only the first call does anything. Parameters: i should be zero the first time any of the ERR_load_.*_string functions is called and non-zero for the rest of the calls. Returns: **********************************************************************/ int ERR_load_scerr_strings( int i) { static int init=1; if (init) { init=0; if (i == 0) { SSL_load_error_strings(); } ERR_load_strings(ERR_USER_LIB_SCERR_NUMBER,scerr_str_functs); ERR_load_strings(ERR_USER_LIB_SCERR_NUMBER,scerr_str_reasons); i++; } return i; } /********************************************************************/ /*******************************************************************/ /* Temporary function to reuten the error number. Should return char */ char * sc_ERR_code( CK_RV status) { static char buf[256]; sprintf(buf,"PKCS#11 return=0x%8.8lx",status); return buf; } /********************************************************************/ int sc_init( CK_SESSION_HANDLE_PTR PsessionHandle, char * card, CK_SLOT_ID_PTR ppslot, char * ppin, CK_USER_TYPE userType, int initialized) { int rc; CK_SLOT_ID rslot; CK_SLOT_ID_PTR pslot; if (ppslot) { pslot = ppslot; } else { pslot = &rslot; } if (!initialized) { rc = sc_init_one(pslot); if (rc) { return rc; } } /* rc = sc_init_info(pslot, &tokenInfo); if (rc) { return rc; } */ rc = sc_init_open_login(PsessionHandle, pslot, ppin, userType); if (rc) { return rc; } return 0; } /*********************************************************** Function: sc_init_one Description: get the function list pointer first. initialize and find the slot with the card ***********************************************************/ int sc_init_one( CK_SLOT_ID_PTR pslot) { CK_RV status; CK_SLOT_ID list[20]; CK_SLOT_ID slot; CK_SLOT_ID_PTR slotList = &list[0]; CK_ULONG count = 0; CK_C_Initialize pC_Initialize; CK_C_INITIALIZE_ARGS initArgs; CK_C_INITIALIZE_ARGS_PTR args = NULL; const char * nss_library_params = NULL; if (!sc_get_function_list()) { return SCERR_R_INITIALIZE; } nss_library_params = getenv("PKCS11_INIT_ARGS"); if (nss_library_params) { /* hack to initialize the NSS soft token */ memset(&initArgs, 0, sizeof(initArgs)); initArgs.flags = CKF_OS_LOCKING_OK; initArgs.pReserved = (void *) nss_library_params; args = &initArgs; } pC_Initialize = pFunctionList->C_Initialize; status = (*pC_Initialize)(args); if (status != CKR_OK) { SCerr(SCERR_F_SCINIT,SCERR_R_INITIALIZE); ERR_add_error_data(1,sc_ERR_code(status)); return SCERR_R_INITIALIZE; } /* status = (*(pFunctionList->C_GetSlotList))(FALSE, NULL, &count); if (status != CKR_OK) { SCerr(SCERR_F_SCINIT,SCERR_R_GETSLOTLIST); ERR_add_error_data(1,sc_ERR_code(status)); return SCERR_R_GETSLOTLIST; } fprintf(stderr,"Slotlist count = %d\n",count); */ count = 20; status = (*(pFunctionList->C_GetSlotList))(FALSE, slotList, &count); if (status != CKR_OK) { SCerr(SCERR_F_SCINIT,SCERR_R_GETSLOTLIST); ERR_add_error_data(1,sc_ERR_code(status)); return SCERR_R_GETSLOTLIST; } if (count == 0) { SCerr(SCERR_F_SCINIT,SCERR_R_OPENSESSION); ERR_add_error_data(1,"\n No SmartCard readers found"); return SCERR_R_OPENSESSION; } /* * need to look at all the slots. * Maybe provide the card label then look for it */ // slot = list[0]; slot = list[1]; if (pslot) { *pslot = slot; } return 0; } /*************************************************************** Function: sc_init_info Description: Read the card info and print debuging **************************************************************/ int sc_init_info( CK_SLOT_ID_PTR pslot, CK_TOKEN_INFO_PTR ptokenInfo) { CK_RV status; status = (*(pFunctionList->C_GetTokenInfo))(*pslot, ptokenInfo); if (status != CKR_OK) { SCerr(SCERR_F_SCINIT,SCERR_R_LOGIN); ERR_add_error_data(2, "While reading Smart Card Info", sc_ERR_code(status)); return SCERR_R_LOGIN; } return 0; } /***************************************************************** Function: sc_init_open_login Description: Open a session to the card, and login *****************************************************************/ int sc_init_open_login( CK_SESSION_HANDLE_PTR PsessionHandle, CK_SLOT_ID_PTR pslot, char * ppin, CK_USER_TYPE userType) { CK_RV status; char * pin; char rpin[256]; /* could also add CKF_EXCLUSIVE_SESSION */ int flags = CKF_RW_SESSION | CKF_SERIAL_SESSION ; status = (*(pFunctionList->C_OpenSession))(*pslot, flags, 0, NULL, PsessionHandle); if (status != CKR_OK) { SCerr(SCERR_F_SCINIT,SCERR_R_OPENSESSION); ERR_add_error_data(1,sc_ERR_code(status)); return SCERR_R_OPENSESSION; } if (ppin) /* did user provide the pin? */ { pin = ppin; } else { pin = rpin; memset(rpin,0,sizeof(rpin)); #ifdef WIN32 read_passphrase_win32_prompt( (userType == CKU_USER) ? "Smart Card User PIN:" : "Smart Card SO PIN:",0); read_passphrase_win32(rpin,sizeof(rpin),0); #else EVP_read_pw_string(rpin,sizeof(rpin), (userType == CKU_USER) ? "Smart Card User PIN:" : "Smart Card SO PIN:",0); #endif /*DEE should test this too */ } status = (*(pFunctionList->C_Login))(*PsessionHandle, userType, (CK_CHAR_PTR)pin, strlen(pin)); memset(rpin,0,sizeof(rpin)); if (status != CKR_OK) { SCerr(SCERR_F_SCINIT,SCERR_R_LOGIN); ERR_add_error_data(1,sc_ERR_code(status)); return SCERR_R_LOGIN; } return 0; } /*********************************************************************/ int sc_final( CK_SESSION_HANDLE sessionHandle) { CK_RV status; status = (*(pFunctionList->C_Logout))(sessionHandle); status = (*(pFunctionList->C_CloseSession))(sessionHandle); return 0; } /*******************************************************************/ /* find and get data off the card */ /*******************************************************************/ int sc_get_rsa_priv_key_obj( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPrivKey, RSA ** nrkey) { CK_RV sc_status; CK_BYTE_PTR pModulus = NULL; CK_BYTE_PTR pExponent = NULL; CK_ATTRIBUTE template[] = { {CKA_MODULUS, NULL_PTR, 0}, {CKA_PUBLIC_EXPONENT, NULL_PTR, 0} }; RSA * rsa = NULL; RSA_METHOD * ometh = NULL; RSA_METHOD * nmeth = NULL; rsa = RSA_new(); /* * set to use our method for this key. i * This will use the smart card for this key * But to do this requires us to copy the RSA method, and * replace two routines. This is done this way to avoid * chanfges to the SSLeay, and since these routines are not * exported in the Win32 DLL. */ nmeth = (RSA_METHOD *)malloc(sizeof(RSA_METHOD)); if (!nmeth) { return 1; /* DEE need to fix */ } ometh = rsa->meth; nmeth->name = ometh->name; nmeth->rsa_pub_enc = ometh->rsa_pub_enc; nmeth->rsa_pub_dec = ometh->rsa_pub_dec; nmeth->rsa_priv_enc = sc_RSA_eay_private_encrypt; nmeth->rsa_priv_dec = sc_RSA_eay_private_decrypt; nmeth->rsa_mod_exp = ometh->rsa_mod_exp; nmeth->bn_mod_exp = ometh->bn_mod_exp; nmeth->init = ometh->init; nmeth->finish = ometh->finish; nmeth->flags = ometh->flags; nmeth->app_data = ometh->app_data; rsa->meth = nmeth; RSA_set_ex_data(rsa,SC_RSA_EX_DATA_INDEX_SESSION,(char *) hSession); RSA_set_ex_data(rsa,SC_RSA_EX_DATA_INDEX_OBJECT, (char *) hPrivKey); sc_status = (*(pFunctionList->C_GetAttributeValue)) (hSession, hPrivKey, template, 2); /* * HACK for the LITRONIC cards, as the RSA PKCS11 says * Section 9.7.1, the card must return the Modulus */ if (sc_status == CKR_ATTRIBUTE_TYPE_INVALID) { *nrkey = rsa; return 0; } if (sc_status == CKR_OK) { pModulus = (CK_BYTE_PTR) malloc(template[0].ulValueLen); template[0].pValue = pModulus; pExponent = (CK_BYTE_PTR) malloc(template[1].ulValueLen); template[1].pValue = pExponent; sc_status = (*(pFunctionList->C_GetAttributeValue))(hSession, hPrivKey, template, 1); } if (sc_status != CKR_OK) { SCerr(SCERR_F_GET_RSA_PRIV_KEY_OBJ,SCERR_R_GETATTRVAL); ERR_add_error_data(1,sc_ERR_code(sc_status)); free(pModulus); free(pExponent); return 1; } rsa->n = BN_bin2bn(pModulus,template[0].ulValueLen,NULL); rsa->e = BN_bin2bn(pExponent,template[1].ulValueLen,NULL); free(pModulus); free(pExponent); *nrkey = rsa; return 0; } /*******************************************************************/ int sc_get_priv_key_obj( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPrivKey, EVP_PKEY ** npkey) { int rc; CK_RV sc_status; CK_KEY_TYPE keyType = 0; CK_ATTRIBUTE template[] = { {CKA_KEY_TYPE, &keyType, sizeof(keyType)} }; RSA * newrkey = NULL; EVP_PKEY * upkey=NULL; upkey = EVP_PKEY_new(); /* We should look at the attribute of the key found to * deside if it is RSA or DSA, then call correct routine. * For now only support RSA. */ sc_status = (*(pFunctionList->C_GetAttributeValue))(hSession, hPrivKey, template, 1); if (sc_status != CKR_OK) { SCerr(SCERR_F_GET_PRIV_KEY_OBJ,SCERR_R_GETATTRVAL); ERR_add_error_data(1,sc_ERR_code(sc_status)); return 1; } switch (keyType) { case (CKK_RSA): rc = sc_get_rsa_priv_key_obj(hSession, hPrivKey, &newrkey); if (rc) { return rc; } EVP_PKEY_assign(upkey, EVP_PKEY_RSA, (char *)newrkey); break; default: SCerr(SCERR_F_GET_PRIV_KEY_OBJ,SCERR_R_UNSUPPORTED); return 1; } *npkey = upkey; return 0; } /*******************************************************************/ int sc_get_priv_key_obj_by_label( CK_SESSION_HANDLE hSession, char * mylabel, EVP_PKEY ** npkey) { int rc; CK_OBJECT_HANDLE hKey; rc = sc_find_priv_key_obj_by_label(hSession,mylabel,&hKey); if (rc) { return rc; } return sc_get_priv_key_obj(hSession, hKey, npkey); } /*******************************************************************/ int sc_find_priv_key_obj_by_label( CK_SESSION_HANDLE hSession, char * mylabel, CK_OBJECT_HANDLE_PTR phPrivKey) { CK_RV status; CK_KEY_TYPE keyType = CKK_RSA; CK_OBJECT_CLASS keyClass = CKO_PRIVATE_KEY; CK_BBOOL true = TRUE; CK_BBOOL false = FALSE; CK_ATTRIBUTE template[20]; int ai; int li = -1; int rc; ai = 0; template[ai].type = CKA_CLASS; template[ai].pValue = &keyClass; template[ai].ulValueLen = sizeof(keyClass); ai++; template[ai].type = CKA_TOKEN; template[ai].pValue = &true; template[ai].ulValueLen = sizeof(true); ai++; if (strlen(mylabel)) { template[ai].type = CKA_LABEL; template[ai].pValue = mylabel; template[ai].ulValueLen = strlen(mylabel) + HACK_PKCS11_LOCAL_STRING_NULL; li = ai; ai++; } rc = sc_find_one_obj(hSession, template, ai, phPrivKey); /* * we may or may not have a null as part of the name, * so we will try again this is a modified HACK * If we added the NULL to the test, we wont this time. * If we did not, we will this time. */ if (rc && li >= 0) { template[li].ulValueLen += 1 - 2 * HACK_PKCS11_LOCAL_STRING_NULL; rc = sc_find_one_obj(hSession, template, ai, phPrivKey); } if (rc) { SCerr(SCERR_F_GET_PRIV_KEY_BY_LABEL,SCERR_R_FIND_FAILED); return 1; } return 0; } /*****************************************************************/ int sc_find_one_obj( CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR template, int ai, CK_OBJECT_HANDLE_PTR phObject) { CK_RV status; CK_ULONG ulObjectCount; status = (*(pFunctionList->C_FindObjectsInit))(hSession,template,ai); if (status != CKR_OK) { SCerr(SCERR_F_FIND_ONE_OBJ,SCERR_R_FINDOBJINIT); ERR_add_error_data(1,sc_ERR_code(status)); return 1; } ulObjectCount = 0; status = (*(pFunctionList->C_FindObjects))(hSession, phObject, 1, &ulObjectCount); (*(pFunctionList->C_FindObjectsFinal))(hSession); if (status != CKR_OK) { SCerr(SCERR_F_FIND_ONE_OBJ,SCERR_R_FINDOBJ); ERR_add_error_data(1,sc_ERR_code(status)); return 1; } if (ulObjectCount != 1) { SCerr(SCERR_F_FIND_ONE_OBJ,SCERR_R_FOUNDMANY); return 1; } return 0; } /*******************************************************************/ /* find and get certificates off of card */ /*******************************************************************/ int sc_get_cert_obj( CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hCert, X509 ** ncert) { CK_RV sc_status; CK_BYTE_PTR pCert = NULL; unsigned char * tasn1; CK_ATTRIBUTE template[] = { {CKA_VALUE, NULL_PTR, 0} }; X509 * x509 = NULL; sc_status = (*(pFunctionList->C_GetAttributeValue))(hSession, hCert, template, 1); if (sc_status == CKR_OK) { pCert = (CK_BYTE_PTR) malloc(template[0].ulValueLen); template[0].pValue = pCert; } sc_status = (*(pFunctionList->C_GetAttributeValue))(hSession, hCert, template, 1); if (sc_status != CKR_OK) { SCerr(SCERR_F_GET_CERT_OBJ,SCERR_R_GETATTRVAL); ERR_add_error_data(1,sc_ERR_code(sc_status)); free(pCert); return 1; } tasn1 = pCert; x509 = d2i_X509(NULL,&tasn1,template[0].ulValueLen); if (x509 == NULL) { SCerr(SCERR_F_GET_CERT_OBJ,SCERR_R_BAD_CERT_OBJ); free(pCert); return 1; } *ncert = x509; free(pCert); return 0; } /*******************************************************************/ int sc_find_cert_obj_by_label( CK_SESSION_HANDLE hSession, char * mylabel, CK_OBJECT_HANDLE_PTR phCert) { CK_RV status; CK_CERTIFICATE_TYPE certType = CKC_X_509; CK_OBJECT_CLASS certClass = CKO_CERTIFICATE; CK_BBOOL true = TRUE; CK_BBOOL false = FALSE; CK_ULONG ulObjectCount; CK_ATTRIBUTE template[20]; int ai; int li = -1; int rc; ai = 0; template[ai].type = CKA_CLASS; template[ai].pValue = &certClass; template[ai].ulValueLen = sizeof(certClass); ai++; template[ai].type = CKA_CERTIFICATE_TYPE; template[ai].pValue = &certType; template[ai].ulValueLen = sizeof(certType); ai++; template[ai].type = CKA_TOKEN; template[ai].pValue = &true; template[ai].ulValueLen = sizeof(true); ai++; if (strlen(mylabel)) { template[ai].type = CKA_LABEL; template[ai].pValue = mylabel; template[ai].ulValueLen = strlen(mylabel) + HACK_PKCS11_LOCAL_STRING_NULL; li = ai; ai++; } rc = sc_find_one_obj(hSession, template, ai, phCert); /* * we may or may not have a null as part of the name, * so we will try again this is a modified HACK * If we added the NULL to the test, we wont this time. * If we did not, we will this time. */ if (rc && li >= 0) { template[li].ulValueLen += 1 - 2 * HACK_PKCS11_LOCAL_STRING_NULL; rc = sc_find_one_obj(hSession, template, ai, phCert); } if (rc) { SCerr(SCERR_F_FIND_CERT_BY_LABEL,SCERR_R_FIND_FAILED); return 1; } return 0; } /*******************************************************************/ int sc_get_cert_obj_by_label( CK_SESSION_HANDLE hSession, char * mylabel, X509 ** ncert) { int rc; CK_OBJECT_HANDLE hCert; rc = sc_find_cert_obj_by_label(hSession,mylabel,&hCert); if (rc) { return rc; } return sc_get_cert_obj(hSession, hCert, ncert); } /****************************************************************/ static int sc_RSA_eay_private_encrypt( int flen, unsigned char * from, unsigned char * to, RSA * rsa, int padding) { CK_ULONG ulsiglen; CK_MECHANISM_PTR pMech = NULL; CK_MECHANISM m_rsa_pkcs = {CKM_RSA_PKCS, 0,0}; CK_MECHANISM m_rsa_raw = {CKM_RSA_X_509, 0,0}; CK_RV ck_status; CK_SESSION_HANDLE hSession; CK_OBJECT_HANDLE hObject; hSession = (CK_SESSION_HANDLE )RSA_get_ex_data( rsa, SC_RSA_EX_DATA_INDEX_SESSION); hObject = (CK_OBJECT_HANDLE) RSA_get_ex_data( rsa, SC_RSA_EX_DATA_INDEX_OBJECT); switch (padding) { case RSA_PKCS1_PADDING: pMech = &m_rsa_pkcs; break; case RSA_NO_PADDING: pMech = &m_rsa_raw; break; case RSA_SSLV23_PADDING: default: RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE); } if (pMech == NULL) { return 0; } ck_status = (*(pFunctionList->C_SignInit))(hSession, pMech, hObject); if (ck_status != CKR_OK) { SCerr(SCERR_F_RSA_ENCRYPT,SCERR_R_SIGNINIT); ERR_add_error_data(1,sc_ERR_code(ck_status)); return 0; } ck_status = (*(pFunctionList->C_Sign))(hSession, from, flen, to, &ulsiglen); if (ck_status != CKR_OK) { SCerr(SCERR_F_RSA_ENCRYPT,SCERR_R_SIGN); ERR_add_error_data(1,sc_ERR_code(ck_status)); return 0; } return ulsiglen; } /***************************************************************/ static int sc_RSA_eay_private_decrypt( int flen, unsigned char * from, unsigned char * to, RSA * rsa, int padding) { CK_ULONG ulsiglen; CK_MECHANISM_PTR pMech = NULL; CK_MECHANISM m_rsa_pkcs = {CKM_RSA_PKCS, 0,0}; CK_MECHANISM m_rsa_raw = {CKM_RSA_X_509, 0,0}; CK_RV ck_status; CK_SESSION_HANDLE hSession; CK_OBJECT_HANDLE hObject; hSession = (CK_SESSION_HANDLE )RSA_get_ex_data( rsa, SC_RSA_EX_DATA_INDEX_SESSION); hObject = (CK_OBJECT_HANDLE) RSA_get_ex_data( rsa, SC_RSA_EX_DATA_INDEX_OBJECT); switch (padding) { case RSA_PKCS1_PADDING: pMech = &m_rsa_pkcs; break; case RSA_NO_PADDING: pMech = &m_rsa_raw; break; case RSA_SSLV23_PADDING: default: RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT,RSA_R_UNKNOWN_PADDING_TYPE); } if (pMech == NULL) { return 0; } ulsiglen = BN_num_bytes(rsa->n); ck_status = (*(pFunctionList->C_SignRecoverInit))(hSession, pMech, hObject); if (ck_status != CKR_OK) { SCerr(SCERR_F_RSA_DECRYPT,SCERR_R_SIGNRECINIT); ERR_add_error_data(1,sc_ERR_code(ck_status)); return 0; } ck_status = (*(pFunctionList->C_SignRecover))(hSession, from, flen, to, &ulsiglen); if (ck_status != CKR_OK) { SCerr(SCERR_F_RSA_DECRYPT,SCERR_R_SIGNREC); ERR_add_error_data(1,sc_ERR_code(ck_status)); return 0; } return ulsiglen; } #endif /*USE_PKCS11*/ canl-c-3.0.0/src/proxy/sslutils.c0000644000015500017500000042010313017332513016441 0ustar tomcat6jenkins/********************************************************************* * * Authors: Valerio Venturi - Valerio.Venturi@cnaf.infn.it * Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it * * Copyright (c) 2002-2009 INFN-CNAF on behalf of the EU DataGrid * and EGEE I, II and III * For license conditions see LICENSE file or * http://www.apache.org/licenses/LICENSE-2.0.txt * * Parts of this code may be based upon or even include verbatim pieces, * originally written by other people, in which case the original header * follows. * *********************************************************************/ /********************************************************************** sslutils.c Description: Routines used internally to implement delegation and proxy certificates for use with Globus The same file is also used for the non-exportable sslk5 which allows Kerberos V5 to accept SSLv3 with certificates as proof of identiy and issue a TGT. **********************************************************************/ /********************************************************************** Include header files **********************************************************************/ #define _GNU_SOURCE //#include "config.h" //#include "replace.h" #include "myproxycertinfo.h" #include "sslutils.h" #include "parsertypes.h" #include "doio.h" //#include "data.h" #ifdef HAVE_UNISTD_H #include #endif #ifndef DEFAULT_SECURE_TMP_DIR #ifndef WIN32 #define DEFAULT_SECURE_TMP_DIR "/tmp" #else #define DEFAULT_SECURE_TMP_DIR "c:\\tmp" #endif #endif #ifndef WIN32 #define FILE_SEPERATOR "/" #else #define FILE_SEPERATOR "\\" #endif #ifdef WIN32 #include "winglue.h" #include #else #ifdef HAVE_UNISTD_H #include #endif #include #endif #include #include #include #include #include #include #include #include "openssl/buffer.h" #include "openssl/crypto.h" #include "openssl/objects.h" #include "openssl/asn1.h" #include "openssl/evp.h" #include "openssl/pkcs12.h" #include "openssl/rsa.h" #include "openssl/rand.h" #if SSLEAY_VERSION_NUMBER >= 0x0090581fL #include "openssl/x509v3.h" #endif #ifndef X509_V_ERR_INVALID_PURPOSE #define X509_V_ERR_INVALID_PURPOSE X509_V_ERR_CERT_CHAIN_TOO_LONG #endif #ifdef USE_PKCS11 #include "scutils.h" #endif /* Maximum leeway in validity period: default 5 minutes */ #define MAX_VALIDITY_PERIOD (5 * 60) static int fix_add_entry_asn1_set_param = 0; #define V1_ROOT (EXFLAG_V1|EXFLAG_SS) #define ku_reject(x, usage) \ (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage))) #define xku_reject(x, usage) \ (((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage))) #define ns_reject(x, usage) \ (((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage))) static X509_NAME *make_DN(const char *dnstring); extern int restriction_evaluate(STACK_OF(X509) *chain, struct policy **namespaces, struct policy **signings); extern void voms_free_policies(struct policy **policies); extern int read_pathrestriction(STACK_OF(X509) *chain, char *path, struct policy ***namespaces, struct policy ***signings); static int check_critical_extensions(X509 *cert, int itsaproxy); static int grid_verifyPathLenConstraints (STACK_OF(X509) * chain); /********************************************************************** Type definitions **********************************************************************/ /********************************************************************** Module specific prototypes **********************************************************************/ /********************************************************************** Define module specific variables **********************************************************************/ static ERR_STRING_DATA prxyerr_str_functs[]= { {ERR_PACK(0,PRXYERR_F_PROXY_GENREQ ,0),"proxy_genreq"}, {ERR_PACK(0,PRXYERR_F_PROXY_SIGN ,0),"proxy_sign"}, {ERR_PACK(0,PRXYERR_F_VERIFY_CB ,0),"verify_callback"}, {ERR_PACK(0,PRXYERR_F_PROXY_TMP ,0),"proxy_marshal_tmp"}, {ERR_PACK(0,PRXYERR_F_INIT_CRED ,0),"proxy_init_cred"}, {ERR_PACK(0,PRXYERR_F_LOCAL_CREATE, 0),"proxy_local_create"}, {ERR_PACK(0,PRXYERR_F_CB_NO_PW, 0),"proxy_pw_cb"}, {ERR_PACK(0,PRXYERR_F_GET_CA_SIGN_PATH, 0),"get_ca_signing_policy_path"}, {ERR_PACK(0,PRXYERR_F_PROXY_SIGN_EXT ,0),"proxy_sign_ext"}, {ERR_PACK(0,PRXYERR_F_PROXY_CHECK_SUBJECT_NAME,0), "proxy_check_subject_name"}, {ERR_PACK(0,PRXYERR_F_PROXY_CONSTRUCT_NAME ,0),"proxy_construct_name"}, {0,NULL}, }; static ERR_STRING_DATA prxyerr_str_reasons[]= { {PRXYERR_R_PROCESS_PROXY_KEY, "processing proxy key"}, {PRXYERR_R_PROCESS_REQ, "creating proxy req"}, {PRXYERR_R_PROCESS_SIGN, "while signing proxy req"}, {PRXYERR_R_MALFORM_REQ, "malformed proxy req"}, {PRXYERR_R_SIG_VERIFY, "proxy req signature verification error"}, {PRXYERR_R_SIG_BAD, "proxy req signature does not match"}, {PRXYERR_R_PROCESS_PROXY, "processing user proxy cert"}, {PRXYERR_R_PROXY_NAME_BAD, "proxy name does not match"}, {PRXYERR_R_PROCESS_SIGNC, "while signing proxy cert"}, {PRXYERR_R_BAD_PROXY_ISSUER, "proxy can only be signed by user"}, {PRXYERR_R_SIGN_NOT_CA ,"user cert not signed by CA"}, {PRXYERR_R_PROBLEM_PROXY_FILE ,"problems creating proxy file"}, {PRXYERR_R_PROCESS_KEY, "processing key"}, {PRXYERR_R_PROCESS_CERT, "processing cert"}, {PRXYERR_R_PROCESS_CERTS, "unable to access trusted certificates in:"}, {PRXYERR_R_PROCESS_PROXY, "processing user proxy cert"}, {PRXYERR_R_NO_TRUSTED_CERTS, "check X509_CERT_DIR and X509_CERT_FILE"}, {PRXYERR_R_PROBLEM_KEY_FILE, "bad file system permissions on private key\n" " key must only be readable by the user"}, {PRXYERR_R_SERVER_ZERO_LENGTH_KEY_FILE, "system key file is empty"}, {PRXYERR_R_USER_ZERO_LENGTH_KEY_FILE, "user private key file is empty"}, {PRXYERR_R_PROBLEM_SERVER_NOKEY_FILE, "system key cannot be accessed"}, {PRXYERR_R_PROBLEM_USER_NOKEY_FILE, "user private key cannot be accessed"}, {PRXYERR_R_PROBLEM_SERVER_NOCERT_FILE, "system certificate not found"}, {PRXYERR_R_PROBLEM_USER_NOCERT_FILE, "user certificate not found"}, {PRXYERR_R_INVALID_CERT, "no certificate in file"}, {PRXYERR_R_REMOTE_CRED_EXPIRED, "remote certificate has expired"}, {PRXYERR_R_USER_CERT_EXPIRED, "user certificate has expired"}, {PRXYERR_R_SERVER_CERT_EXPIRED, "system certificate has expired"}, {PRXYERR_R_PROXY_EXPIRED, "proxy expired: run grid-proxy-init or wgpi first"}, {PRXYERR_R_NO_PROXY, "no proxy credentials: run grid-proxy-init or wgpi first"}, {PRXYERR_R_CRL_SIGNATURE_FAILURE, "invalid signature on a CRL"}, {PRXYERR_R_CRL_NEXT_UPDATE_FIELD, "invalid nextupdate field in CRL"}, {PRXYERR_R_CRL_HAS_EXPIRED, "outdated CRL found, revoking all certs till you get new CRL"}, {PRXYERR_R_CERT_REVOKED, "certificate revoked per CRL"}, {PRXYERR_R_NO_HOME, "can't determine HOME directory"}, {PRXYERR_R_KEY_CERT_MISMATCH, "user key and certificate don't match"}, {PRXYERR_R_WRONG_PASSPHRASE, "wrong pass phrase"}, {PRXYERR_R_CA_POLICY_VIOLATION, "remote certificate CA signature not allowed by policy"}, {PRXYERR_R_CA_POLICY_ERR,"no matching CA found in file for remote certificate"}, {PRXYERR_R_CA_NOFILE,"could not find CA policy file"}, {PRXYERR_R_CA_NOPATH,"could not determine path to CA policy file"}, {PRXYERR_R_CA_POLICY_RETRIEVE, "CA policy retrieve problems"}, {PRXYERR_R_CA_POLICY_PARSE, "CA policy parse problems"}, {PRXYERR_R_CA_UNKNOWN,"remote certificate signed by unknown CA"}, {PRXYERR_R_PROBLEM_CLIENT_CA, "problems getting client_CA list"}, {PRXYERR_R_CB_NO_PW, "no proxy credentials: run grid-proxy-init or wgpi first"}, {PRXYERR_R_CB_CALLED_WITH_ERROR,"certificate failed verify:"}, {PRXYERR_R_CB_ERROR_MSG, "certificate:"}, {PRXYERR_R_CLASS_ADD_OID,"can't find CLASS_ADD OID"}, {PRXYERR_R_CLASS_ADD_EXT,"problem adding CLASS_ADD Extension"}, {PRXYERR_R_DELEGATE_VERIFY,"problem verifiying the delegate extension"}, {PRXYERR_R_EXT_ADD,"problem adding extension"}, {PRXYERR_R_DELEGATE_CREATE,"problem creating delegate extension"}, {PRXYERR_R_DELEGATE_COPY,"problem copying delegate extension to proxy"}, {PRXYERR_R_BUFFER_TOO_SMALL,"buffer too small"}, {PRXYERR_R_CERT_NOT_YET_VALID,"remote certificate not yet valid"}, {PRXYERR_R_LOCAL_CA_UNKNOWN,"cannot find CA certificate for local credential"}, {PRXYERR_R_OUT_OF_MEMORY,"out of memory"}, {PRXYERR_R_BAD_ARGUMENT,"bad argument"}, {PRXYERR_R_BAD_MAGIC,"bad magic number"}, {PRXYERR_R_UNKNOWN_CRIT_EXT,"unable to handle critical extension"}, {0,NULL} }; int my_txt2nid(char *name) { ASN1_OBJECT *obj = OBJ_txt2obj(name,1); int nid = OBJ_obj2nid(obj); ASN1_OBJECT_free(obj); return nid; } /********************************************************************* Function: X509_NAME_cmp_no_set Description: To circumvent a bug with adding X509_NAME_ENTRIES with the wrong "set", we will compare names without the set. This is a temporary fix which will be removed when we fix the creation of the names using the correct sets. This is only being done this way for some compatability while installing the these fixes. This fix is needed in all previous versions of Globus. Parameters: same as X509_NAME_cmp Returns : same as X509_NAME_cmp ********************************************************************/ static int X509_NAME_cmp_no_set( X509_NAME * a, X509_NAME * b) { int i; int j; X509_NAME_ENTRY * na; X509_NAME_ENTRY * nb; if (X509_NAME_entry_count(a) != X509_NAME_entry_count(b)) { return(X509_NAME_entry_count(a) - X509_NAME_entry_count(b)); } for (i=X509_NAME_entry_count(a)-1; i>=0; i--) { ASN1_STRING *val_a, *val_b; na = X509_NAME_get_entry(a,i); nb = X509_NAME_get_entry(b,i); val_a = X509_NAME_ENTRY_get_data(na); val_b = X509_NAME_ENTRY_get_data(nb); j = val_a->length - val_b->length; if (j) { return(j); } j = memcmp(val_a->data, val_b->data, val_a->length); if (j) { return(j); } } /* We will check the object types after checking the values * since the values will more often be different than the object * types. */ for (i=X509_NAME_entry_count(a)-1; i>=0; i--) { na = X509_NAME_get_entry(a,i); nb = X509_NAME_get_entry(b,i); j = OBJ_cmp(X509_NAME_ENTRY_get_object(na), X509_NAME_ENTRY_get_object(nb)); if (j) { return(j); } } return(0); } #ifdef WIN32 /********************************************************************* Function: getuid, getpid Descriptions: For Windows95, WIN32, we don't have these, so we will default to using uid 0 and pid 0 Need to look at this better for NT. ******************************************************************/ static unsigned long getuid() { return 0; } static int getpid() { return 0; } #endif /* WIN32 */ #if SSLEAY_VERSION_NUMBER < 0x0900 /********************************************************************** Function: ERR_add_error_data() Description: Dummy routine only defined if running with SSLeay-0.8.x this feature was introduced with SSLeay-0.9.0 Parameters: Returns: **********************************************************************/ void PRIVATE ERR_add_error_data( VAR_PLIST( int, num )) VAR_ALIST { VAR_BDEFN(args, int, num); } /********************************************************************** Function: ERR_get_error_line_data() Description: Dummy routine only defined if running with SSLeay-0.8.x this feature was introduced with SSLeay-0.9.0. We will simulate it for 0.8.1 Parameters: Returns: **********************************************************************/ unsigned long PRIVATE ERR_get_error_line_data( char ** file, int * line, char ** data, int * flags) { if (data) { *data = ""; } if (flags) { *flags = 0; } return (ERR_get_error_line(file, line)); } #endif /********************************************************************** Function: ERR_set_continue_needed() Description: Sets state information which error display routines can use to determine if the error just added is enough information to describe the error or if further error information need displayed. (By default gss_display_status will only show one user level error) note: This function must be called after (or instead of) the ssl add error data functions. Parameters: Returns: **********************************************************************/ void PRIVATE ERR_set_continue_needed(void) { ERR_STATE *es; es = ERR_get_state(); es->err_data_flags[es->top] = es->err_data_flags[es->top] | ERR_DISPLAY_CONTINUE_NEEDED; } /********************************************************************** Function: ERR_load_prxyerr_strings() Description: Sets up the error tables used by SSL and adds ours using the ERR_LIB_USER Only the first call does anything. Will also add any builtin objects for SSLeay. Parameters: i should be zero the first time one of the ERR_load functions is called and non-zero for each additional call. Returns: **********************************************************************/ int PRIVATE ERR_load_prxyerr_strings( int i) { static int init = 1; struct stat stx; clock_t cputime; #if SSLEAY_VERSION_NUMBER >= 0x00904100L const char * randfile; #else char * randfile; #endif #if SSLEAY_VERSION_NUMBER >= 0x0090581fL char * egd_path; #endif char buffer[200]; if (init) { init = 0; #ifndef RAND_DO_NOT_USE_CLOCK clock(); #endif if (i == 0) { SSL_load_error_strings(); } OBJ_create("1.3.6.1.4.1.3536.1.1.1.1","CLASSADD","ClassAdd"); OBJ_create("1.3.6.1.4.1.3536.1.1.1.2","DELEGATE","Delegate"); OBJ_create("1.3.6.1.4.1.3536.1.1.1.3","RESTRICTEDRIGHTS", "RestrictedRights"); OBJ_create("0.9.2342.19200300.100.1.1","USERID","userId"); ERR_load_strings(ERR_USER_LIB_PRXYERR_NUMBER,prxyerr_str_functs); ERR_load_strings(ERR_USER_LIB_PRXYERR_NUMBER,prxyerr_str_reasons); /* * We need to get a lot of randomness for good security * OpenSSL will use /dev/urandom (if available), * uid, time, and gid. * * If user has RANDFILE set, or $HOME/.rnd * load it for extra random seed. * This may also not be enough, so we will also add in * the time it takes to run this routine, which includes * reading the randfile. * Later we will also add in some keys and some stats * if we have them. * look for RAND_add in this source file. * * Other methods we could use: * * Librand from Don Mitchell and Matt Blaze * * Doing a netstat -in * * some form of pstat * But /dev/random and/or egd should be enough. */ randfile = RAND_file_name(buffer,200); if (randfile) { RAND_load_file(randfile,1024L*1024L); } #if 0 #if SSLEAY_VERSION_NUMBER >= 0x0090581fL /* * Try to use the Entropy Garthering Deamon * See the OpenSSL crypto/rand/rand_egd.c */ egd_path = getenv("EGD_PATH"); if (egd_path == NULL) { egd_path = "/etc/entropy"; } RAND_egd(egd_path); #endif #endif /* if still not enough entropy*/ if (RAND_status() == 0) { stat("/tmp",&stx); /* get times /tmp was modified */ RAND_add((void*)&stx,sizeof(stx),16); } #ifndef RAND_DO_NOT_USE_CLOCK cputime = clock(); RAND_add((void*)&cputime, sizeof(cputime),8); #endif i++; #ifdef USE_PKCS11 i = ERR_load_scerr_strings(i); #endif } return i; } /********************************************************************** Function: checkstat() Description: check the status of a file Parameters: Returns: 0 pass all the following tests 1 does not exist 2 not owned by user 3 readable by someone else 4 zero length **********************************************************************/ static int checkstat(const char* filename) { struct stat stx; if (stat(filename,&stx) != 0) { return 1; } /* * use any stat output as random data, as it will * have file sizes, and last use times in it. */ RAND_add((void*)&stx,sizeof(stx),2); #if !defined(WIN32) && !defined(TARGET_ARCH_CYGWIN) if (stx.st_uid != getuid()) { return 2; } if (stx.st_mode & 066) { return 3; } #endif /* !WIN32 && !TARGET_ARCH_CYGWIN */ if (stx.st_size == 0) { return 4; } return 0; } /********************************************************************** Function: proxy_load_user_proxy() Description: Given the user_proxy file, skip the first cert, and add any additional certs to the cert_chain. These must be additional proxies, or the user's cert which signed the proxy. This is based on the X509_load_cert_file routine. Parameters: Returns: **********************************************************************/ int PRIVATE proxy_load_user_proxy( STACK_OF(X509) * cert_chain, const char * file) { int ret = -1; BIO * in = NULL; int count=0; X509 * x = NULL; if (file == NULL) return(1); in = BIO_new(BIO_s_file()); if ((in == NULL) || (BIO_read_filename(in,file) <= 0)) { X509err(PRXYERR_F_PROXY_LOAD, PRXYERR_R_PROCESS_PROXY); goto err; } for (;;) { x = PEM_read_bio_X509(in,NULL, OPENSSL_PEM_CB(NULL,NULL)); if (x == NULL) { if ((ERR_GET_REASON(ERR_peek_error()) == PEM_R_NO_START_LINE) && (count > 0)) { ERR_clear_error(); break; } else { X509err(PRXYERR_F_PROXY_LOAD, PRXYERR_R_PROCESS_PROXY); goto err; } } if (count) { (void)sk_X509_insert(cert_chain,x,sk_X509_num(cert_chain)); x = NULL; } count++; if (x) { X509_free(x); x = NULL; } } ret = count; err: if (x != NULL) { X509_free(x); } if (in != NULL) { BIO_free(in); } return(ret); } /********************************************************************** Function: proxy_genreq() Description: generate certificate request for a proxy certificate. This is based on using the current user certificate. If the current user cert is NULL, we are asking fke the server to fill this in, and give us a new cert. Used with k5cert. Parameters: Returns: **********************************************************************/ int PRIVATE proxy_genreq( X509 * ucert, X509_REQ ** reqp, EVP_PKEY ** pkeyp, int bits, const char * newdn, int (*callback)()) { RSA * rsa = NULL; EVP_PKEY * pkey = NULL; EVP_PKEY * upkey = NULL; X509_NAME * name = NULL; X509_REQ * req = NULL; X509_NAME_ENTRY * ne = NULL; int rbits; if (bits) { rbits = bits; } else if (ucert) { if ((upkey = X509_get_pubkey(ucert)) == NULL) { PRXYerr(PRXYERR_F_PROXY_GENREQ,PRXYERR_R_PROCESS_PROXY_KEY); goto err; } if (EVP_PKEY_id(upkey) != EVP_PKEY_RSA) { PRXYerr(PRXYERR_F_PROXY_GENREQ,PRXYERR_R_PROCESS_PROXY_KEY); goto err; } rbits = 8 * EVP_PKEY_size(upkey); EVP_PKEY_free(upkey); } else { rbits = 512; } if ((pkey = EVP_PKEY_new()) == NULL) { PRXYerr(PRXYERR_F_PROXY_GENREQ,PRXYERR_R_PROCESS_PROXY_KEY); goto err; } /* * Note: The cast of the callback function is consistent with * the declaration of RSA_generate_key() in OpenSSL. It may * trigger a warning if you compile with SSLeay. */ if ((rsa = RSA_generate_key(rbits, RSA_F4, (void (*)(int,int,void *))callback ,NULL)) == NULL) { PRXYerr(PRXYERR_F_PROXY_GENREQ,PRXYERR_R_PROCESS_PROXY_KEY); goto err; } if (!EVP_PKEY_assign_RSA(pkey,rsa)) { PRXYerr(PRXYERR_F_PROXY_GENREQ,PRXYERR_R_PROCESS_PROXY_KEY); goto err; } if ((req = X509_REQ_new()) == NULL) { PRXYerr(PRXYERR_F_PROXY_GENREQ,PRXYERR_R_PROCESS_REQ); goto err; } X509_REQ_set_version(req,0L); if (!newdn) { if (ucert) { if ((name = X509_NAME_dup(X509_get_subject_name(ucert))) == NULL) { PRXYerr(PRXYERR_F_PROXY_GENREQ,PRXYERR_R_PROCESS_REQ); goto err; } } else { name = X509_NAME_new(); } if ((ne = X509_NAME_ENTRY_create_by_NID(NULL,NID_commonName, V_ASN1_APP_CHOOSE, (unsigned char *)"proxy", -1)) == NULL) { PRXYerr(PRXYERR_F_PROXY_GENREQ,PRXYERR_R_PROCESS_REQ); goto err; } X509_NAME_add_entry(name, ne, X509_NAME_entry_count(name), fix_add_entry_asn1_set_param); } else { name = make_DN(newdn); if (!name) { PRXYerr(PRXYERR_F_PROXY_GENREQ,PRXYERR_R_PROCESS_REQ); goto err; } } X509_REQ_set_subject_name(req,name); X509_NAME_free(name); name = NULL; X509_REQ_set_pubkey(req,pkey); if (!X509_REQ_sign(req,pkey,EVP_sha1())) { PRXYerr(PRXYERR_F_PROXY_GENREQ,PRXYERR_R_PROCESS_SIGN); goto err; } if (ne) { X509_NAME_ENTRY_free(ne); ne = NULL; } *pkeyp = pkey; *reqp = req; return 0; err: if (upkey) EVP_PKEY_free(upkey); if(rsa) { RSA_free(rsa); } if (pkey) { EVP_PKEY_free(pkey); } if (name) { X509_NAME_free(name); } if (req) { X509_REQ_free(req); } if (ne) { X509_NAME_ENTRY_free(ne); } return 1; } /** * Sign a certificate request * * This function is a wrapper function for proxy_sign_ext. The subject * name of the resulting certificate is generated by adding either * cn=proxy or cn=limited proxy to the subject name of user_cert. The * issuer name is set to the subject name of user_cert. * * @param user_cert * A certificate to be used for subject and issuer name * information if that information isn't provided. * @param user_private_key * The private key to be used for signing the certificate * request. * @param req * The certificate request * @param new_cert * This parameter will contain the signed certficate upon * success. * @param seconds * The number of seconds the new cert is going to be * valid. The validity should not exceed that of the issuing * key pair. If this parameter is 0 the generated cert will * have the same lifetime as the issuing key pair. * @param extensions * Extensions to be placed in the new certificate. * @param limited_proxy * If this value is non zero the resulting cert will be a * limited proxy. * * @return * This functions returns 0 upon success, 1 upon failure. It * will also place a more detailed error on an error stack. */ int PRIVATE proxy_sign( X509 * user_cert, EVP_PKEY * user_private_key, X509_REQ * req, X509 ** new_cert, int seconds, STACK_OF(X509_EXTENSION) * extensions, int limited_proxy, int proxyver, const char * newdn, const char * newissuer, int pastproxy, const char * newserial, int selfsigned ) { char * newcn; EVP_PKEY * user_public_key; X509_NAME * subject_name = NULL; X509_NAME * issuer_name = NULL; int rc = 0; unsigned char md[SHA_DIGEST_LENGTH]; unsigned int len; if(proxyver>=3) { long sub_hash; user_public_key = X509_get_pubkey(user_cert); #ifdef TYPEDEF_I2D_OF ASN1_digest((i2d_of_void*)i2d_PUBKEY, EVP_sha1(), (char *) user_public_key, md, &len); #else ASN1_digest(i2d_PUBKEY, EVP_sha1(), (char *) user_public_key, md, &len); #endif EVP_PKEY_free(user_public_key); sub_hash = md[0] + (md[1] + (md[2] + (md[3] >> 1) * 256) * 256) * 256; newcn = snprintf_wrap("%ld", sub_hash); } else { if(limited_proxy) newcn = "limited proxy"; else newcn = "proxy"; } if (newdn == NULL) { if(proxy_construct_name( user_cert, &subject_name, newcn, -1)) { PRXYerr(PRXYERR_F_PROXY_SIGN,PRXYERR_R_PROCESS_SIGN); if (proxyver >= 3) free(newcn); return 1; } } else subject_name = make_DN(newdn); if (newissuer) issuer_name = make_DN(newissuer); else issuer_name = NULL; if(proxy_sign_ext(user_cert, user_private_key, EVP_sha1(), req, new_cert, subject_name, issuer_name, seconds, extensions, proxyver, pastproxy, newserial, selfsigned)) { PRXYerr(PRXYERR_F_PROXY_SIGN,PRXYERR_R_PROCESS_SIGN); rc = 1; } X509_NAME_free(subject_name); if (issuer_name) X509_NAME_free(issuer_name); if (proxyver >= 3) free(newcn); return rc; } /** * Sign a certificate request * * This function signs the given certificate request. Before signing * the certificate the certificate's subject and issuer names may be * replaced and extensions may be added to the certificate. * * @param user_cert * A certificate to be used for lifetime and serial number * information if that information isn't provided. * @param user_private_key * The private key to be used for signing the certificate * request. * @param method * The method to employ for signing * @param req * The certificate request * @param new_cert * This parameter will contain the signed certficate upon * success. * @param subject_name * The subject name to be used for the new certificate. If no * subject name is provided the subject name in the certificate * request will remain untouched. * @param issuer_name * The issuer name to be used for the new certificate. If no * issuer name is provided the issuer name will be set to the * subject name of the user cert. * @param seconds * The number of seconds the new cert is going to be * valid. The validity should not exceed that of the issuing * key pair. If this parameter is 0 the generated cert will * have the same lifetime as the issuing key pair. * @param serial_num * The serial number to be used for the new cert. If this * parameter is 0 the serial number of the user_cert is used. * @param extensions * Extensions to be placed in the new certificate. * * @return * This functions returns 0 upon success, 1 upon failure. It * will also place a more detailed error on an error stack. */ int PRIVATE proxy_sign_ext( X509 * user_cert, EVP_PKEY * user_private_key, const EVP_MD * method, X509_REQ * req, X509 ** new_cert, X509_NAME * subject_name, X509_NAME * issuer_name, int seconds, STACK_OF(X509_EXTENSION) *extensions, int proxyver, int pastproxy, const char *newserial, int selfsigned) { EVP_PKEY * new_public_key = NULL; EVP_PKEY * tmp_public_key = NULL; X509_CINF * user_cert_info; X509_EXTENSION * extension = NULL; time_t time_diff, time_now, time_after; ASN1_UTCTIME * asn1_time = NULL; int i; unsigned char md[SHA_DIGEST_LENGTH]; unsigned int len; /* for openssl 1.1 if (!selfsigned) user_cert_info = user_cert->cert_info; */ *new_cert = NULL; /* if ((req->req_info == NULL) || (req->req_info->pubkey == NULL) || (req->req_info->pubkey->public_key == NULL) || (req->req_info->pubkey->public_key->data == NULL)) { PRXYerr(PRXYERR_F_PROXY_SIGN,PRXYERR_R_MALFORM_REQ); goto err; } */ if ((new_public_key=X509_REQ_get_pubkey(req)) == NULL) { PRXYerr(PRXYERR_F_PROXY_SIGN_EXT,PRXYERR_R_MALFORM_REQ); goto err; } i = X509_REQ_verify(req,new_public_key); EVP_PKEY_free(new_public_key); new_public_key = NULL; if (i < 0) { PRXYerr(PRXYERR_F_PROXY_SIGN_EXT,PRXYERR_R_SIG_VERIFY); goto err; } if (i == 0) { PRXYerr(PRXYERR_F_PROXY_SIGN_EXT,PRXYERR_R_SIG_BAD); goto err; } /* signature ok. */ if ((*new_cert = X509_new()) == NULL) { PRXYerr(PRXYERR_F_PROXY_SIGN_EXT,PRXYERR_R_PROCESS_PROXY); goto err; } /* set the subject name */ if(subject_name && !X509_set_subject_name(*new_cert,subject_name)) { PRXYerr(PRXYERR_F_PROXY_SIGN_EXT,PRXYERR_R_PROCESS_PROXY); goto err; } /* DEE? will use same serial number, this may help * with revocations, or may cause problems. */ if (newserial) { BIGNUM *bn = NULL; if (BN_hex2bn(&bn, newserial) != 0) { ASN1_INTEGER *a_int = BN_to_ASN1_INTEGER(bn, NULL); i = X509_set_serialNumber(*new_cert, a_int); BN_free(bn); } } else if (proxyver > 2) { ASN1_INTEGER *serial = NULL; // ASN1_INTEGER_free(X509_get_serialNumber(*new_cert)); new_public_key = X509_REQ_get_pubkey(req); #ifdef TYPEDEF_I2D_OF ASN1_digest((i2d_of_void*)i2d_PUBKEY, EVP_sha1(), (char *) new_public_key, md, &len); #else ASN1_digest(i2d_PUBKEY, EVP_sha1(), (char *) new_public_key, md, &len); #endif EVP_PKEY_free(new_public_key); new_public_key = NULL; /* According to ITU-T recommendation X.690 the first nine bites shall not * be 0 or 1, see also https://ggus.eu/index.php?mode=ticket_info&ticket_id=113418. * To obey the demand we put an additional byte at the very beginning. */ len++; serial = ASN1_INTEGER_new(); serial->length = len; serial->data = malloc(len); if (serial->data == NULL) { PRXYerr(PRXYERR_F_PROXY_SIGN_EXT, PRXYERR_R_PROCESS_PROXY); goto err; } serial->data[0] = 0x01; memcpy(serial->data+1, md, SHA_DIGEST_LENGTH); i = X509_set_serialNumber(*new_cert, serial); ASN1_INTEGER_free(serial); /* (*new_cert)->cert_info->serialNumber = ASN1_INTEGER_new(); (*new_cert)->cert_info->serialNumber->length = len; (*new_cert)->cert_info->serialNumber->data = malloc(len); if (!((*new_cert)->cert_info->serialNumber->data)) { PRXYerr(PRXYERR_F_PROXY_SIGN_EXT, PRXYERR_R_PROCESS_PROXY); goto err; } (*new_cert)->cert_info->serialNumber->data[0] = 0x01; memcpy((*new_cert)->cert_info->serialNumber->data + 1, md, SHA_DIGEST_LENGTH); */ } else if (selfsigned) { ASN1_INTEGER *copy = ASN1_INTEGER_new(); if (copy) { ASN1_INTEGER_set(copy, 1); i = X509_set_serialNumber(*new_cert, copy); ASN1_INTEGER_free(copy); } else goto err; } else { #if 0 ASN1_INTEGER *copy = ASN1_INTEGER_dup(X509_get_serialNumber(user_cert)); ASN1_INTEGER_free((*new_cert)->cert_info->serialNumber); /* Note: The copy == NULL case is handled immediately below. */ (*new_cert)->cert_info->serialNumber = copy; #endif i = X509_set_serialNumber(*new_cert, X509_get_serialNumber(user_cert)); } if (i == 0) { PRXYerr(PRXYERR_F_PROXY_SIGN_EXT,PRXYERR_R_PROCESS_PROXY); goto err; } /* set the issuer name */ if (issuer_name) { if(!X509_set_issuer_name(*new_cert,issuer_name)) { PRXYerr(PRXYERR_F_PROXY_SIGN_EXT,PRXYERR_R_PROCESS_PROXY); goto err; } } else { if(!X509_set_issuer_name(*new_cert,X509_get_subject_name(user_cert))) { PRXYerr(PRXYERR_F_PROXY_SIGN_EXT,PRXYERR_R_PROCESS_PROXY); goto err; } } /* Allow for a five minute clock skew here. */ X509_gmtime_adj(X509_get_notBefore(*new_cert),-5*60 -pastproxy); /* DEE? should accept an seconds parameter, and set to min of * hours or the ucert notAfter * for now use seconds if not zero. */ if (selfsigned) { X509_gmtime_adj(X509_get_notAfter(*new_cert),(long) seconds - pastproxy); } else { /* doesn't create a proxy longer than the user cert */ asn1_time = ASN1_UTCTIME_new(); X509_gmtime_adj(asn1_time, -pastproxy); time_now = ASN1_UTCTIME_mktime(asn1_time); ASN1_UTCTIME_free(asn1_time); time_after = ASN1_UTCTIME_mktime(X509_get_notAfter(user_cert)); time_diff = time_after - time_now; if(time_diff > (seconds - pastproxy)) { X509_gmtime_adj(X509_get_notAfter(*new_cert),(long) seconds - pastproxy); } else { X509_set_notAfter(*new_cert, X509_get0_notAfter(user_cert)); } } /* transfer the public key from req to new cert */ /* DEE? should this be a dup? */ new_public_key = X509_REQ_get0_pubkey(req); X509_set_pubkey(*new_cert, new_public_key); // req->req_info->pubkey = NULL; /* * We can now add additional extentions here * such as to control the usage of the cert */ X509_set_version(*new_cert, 2); /* version 3 certificate */ #if 0 /* Free the current entries if any, there should not * be any I belive */ if (new_cert_info->extensions != NULL) { sk_X509_EXTENSION_pop_free(new_cert_info->extensions, X509_EXTENSION_free); } #endif /* Add extensions provided by the client */ if (extensions) { #if 0 if ((new_cert_info->extensions = sk_X509_EXTENSION_new_null()) == NULL) { PRXYerr(PRXYERR_F_PROXY_SIGN_EXT,PRXYERR_R_DELEGATE_COPY); } #endif /* Lets 'copy' the client extensions to the new proxy */ /* we should look at the type, and only copy some */ for (i=0; iextensions, extension)) { PRXYerr(PRXYERR_F_PROXY_SIGN_EXT,PRXYERR_R_DELEGATE_COPY); goto err; } #endif extension = sk_X509_EXTENSION_value(extensions, i); i = X509_add_ext(*new_cert, extension, -1); if (i == 0) { PRXYerr(PRXYERR_F_PROXY_SIGN_EXT,PRXYERR_R_DELEGATE_COPY); goto err; } } } /* new cert is built, now sign it */ #ifndef NO_DSA /* DEE? not sure what this is doing, I think * it is adding from the key to be used to sign to the * new certificate any info DSA may need */ tmp_public_key = X509_get_pubkey(*new_cert); if (EVP_PKEY_missing_parameters(tmp_public_key) && !EVP_PKEY_missing_parameters(user_private_key)) { EVP_PKEY_copy_parameters(tmp_public_key,user_private_key); } #endif EVP_PKEY_free(tmp_public_key); if (!X509_sign(*new_cert,user_private_key,method)) { PRXYerr(PRXYERR_F_PROXY_SIGN_EXT,PRXYERR_R_PROCESS_SIGNC); goto err; } return 0; err: /* free new_cert upon error */ if (*new_cert) { X509_free(*new_cert); } if (new_public_key) EVP_PKEY_free(new_public_key); return 1; } /** * Construct a X509 name * * This function constructs a X509 name by taking the subject name of * the certificate and adding a new CommonName field with value newcn * (if this parameter is non NULL). The resulting name should be freed * using X509_NAME_free. * * @param cert * The certificate to extract the subject name from. * @param name * The resulting name * @param newcn * The value of the CommonName field to add. If this value is * NULL this function just returns a copy of the subject name * of the certificate. * * @return * This functions returns 0 upon success, 1 upon failure. It * will also place a more detailed error on an error stack. */ int PRIVATE proxy_construct_name( X509 * cert, X509_NAME ** name, char * newcn, unsigned int len) { X509_NAME_ENTRY * name_entry = NULL; *name = NULL; if ((*name = X509_NAME_dup(X509_get_subject_name(cert))) == NULL) { PRXYerr(PRXYERR_F_PROXY_CONSTRUCT_NAME,PRXYERR_R_PROCESS_PROXY); goto err; } if(newcn) { if ((name_entry = X509_NAME_ENTRY_create_by_NID(NULL, NID_commonName, V_ASN1_APP_CHOOSE, (unsigned char *)newcn, len)) == NULL) { PRXYerr(PRXYERR_F_PROXY_CONSTRUCT_NAME,PRXYERR_R_PROCESS_PROXY); goto err; } if (!X509_NAME_add_entry(*name, name_entry, X509_NAME_entry_count(*name), fix_add_entry_asn1_set_param)) { PRXYerr(PRXYERR_F_PROXY_CONSTRUCT_NAME,PRXYERR_R_PROCESS_PROXY); goto err; } X509_NAME_ENTRY_free(name_entry); } return 0; err: if (*name) { X509_NAME_free(*name); } if (name_entry) { X509_NAME_ENTRY_free(name_entry); } return 1; } /********************************************************************** Function: proxy_marshal_bp() Description: Write to a bio the proxy certificate, key, users certificate, and any other certificates need to use the proxy. Parameters: Returns: **********************************************************************/ int PRIVATE proxy_marshal_bp( BIO * bp, X509 * ncert, EVP_PKEY * npkey, X509 * ucert, STACK_OF(X509) * cert_chain) { X509 * cert; if (!PEM_write_bio_X509(bp,ncert)) { return 1; } if (!PEM_write_bio_RSAPrivateKey(bp, EVP_PKEY_get0_RSA(npkey), NULL, NULL, 0, OPENSSL_PEM_CB(NULL,NULL))) { return 2; } if (ucert) { if (!PEM_write_bio_X509(bp,ucert)) { return 3; } } if (cert_chain) { /* * add additional certs, but not our cert, or the * proxy cert, or any self signed certs */ int i; for(i=0; i < sk_X509_num(cert_chain); i++) { cert = sk_X509_value(cert_chain,i); if (!(!X509_NAME_cmp_no_set(X509_get_subject_name(cert), X509_get_subject_name(ncert)) || (ucert && !X509_NAME_cmp_no_set(X509_get_subject_name(cert), X509_get_subject_name(ucert))) || !X509_NAME_cmp_no_set(X509_get_subject_name(cert), X509_get_issuer_name(cert)))) { if (!PEM_write_bio_X509(bp,cert)) { return 4; } } } } return 0; } /********************************************************************** Function: canl_proxy_verify_init() Description: Parameters: Returns: **********************************************************************/ void canl_proxy_verify_init( canl_proxy_verify_desc * pvd, canl_proxy_verify_ctx_desc * pvxd) { pvd->magicnum = PVD_MAGIC_NUMBER; /* used for debuging */ pvd->flags = 0; pvd->previous = NULL; pvd->pvxd = pvxd; pvd->proxy_depth = 0; pvd->cert_depth = 0; pvd->cert_chain = NULL; pvd->limited_proxy = 0; pvd->multiple_limited_proxy_ok = 0; } /********************************************************************** Function: canl_proxy_verify_ctx_init() Description: Parameters: Returns: **********************************************************************/ void canl_proxy_verify_ctx_init( canl_proxy_verify_ctx_desc * pvxd) { pvxd->magicnum = PVXD_MAGIC_NUMBER; /* used for debuging */ pvxd->certdir = NULL; pvxd->goodtill = 0; pvxd->flags = 0; pvxd->ocsp_url = NULL; } /********************************************************************** Function: proxy_verify_release() Description: Parameters: Returns: **********************************************************************/ void canl_proxy_verify_release( canl_proxy_verify_desc * pvd) { pvd->cert_chain = NULL; pvd->pvxd = NULL; } /********************************************************************** Function: canl_proxy_verify_ctx_release() Description: Parameters: Returns: **********************************************************************/ void canl_proxy_verify_ctx_release( canl_proxy_verify_ctx_desc * pvxd) { if (pvxd->certdir) { free(pvxd->certdir); pvxd->certdir = NULL; } if (pvxd->ocsp_url) { free(pvxd->ocsp_url); pvxd->ocsp_url = NULL; } } #if SSLEAY_VERSION_NUMBER >= 0x0090600fL /********************************************************************** Function: proxy_app_verify_callback() Description: SSL callback which lets us do the x509_verify_cert ourself. We use this to set the ctx->check_issued routine so we can override some of the tests if needed. Parameters: Returns: Same as X509_verify_cert **********************************************************************/ #if 0 int proxy_app_verify_callback(X509_STORE_CTX *ctx, UNUSED(void *empty)) { /* * OpenSSL-0.9.6 has a check_issued routine which * we want to override so we can replace some of the checks. */ ctx->check_issued = proxy_check_issued; return X509_verify_cert(ctx); } #endif #endif /* Ifdef out all extra code not needed for k5cert * This includes the OLDGAA */ #ifndef BUILD_FOR_K5CERT_ONLY /********************************************************************** Function: proxy_check_proxy_name() Description: Check if the subject name is a proxy, and the issuer name is the same as the subject name, but without the proxy entry. i.e. inforce the proxy signing requirement of only a user or a user's proxy can sign a proxy. Also pass back Rif this is a limited proxy. Parameters: Returns: -1 if there was an error 0 if not a proxy 1 if a proxy 2 if a limited proxy *********************************************************************/ int proxy_check_proxy_name( X509 * cert) { int ret = 0; X509_NAME * subject; X509_NAME * name = NULL; X509_NAME_ENTRY * ne = NULL; ASN1_STRING * data; int nidv3, nidv4 = 0; int indexv3 = -1, indexv4 = -1; X509_EXTENSION *ext = NULL; nidv3 = my_txt2nid(PROXYCERTINFO_V3); nidv4 = my_txt2nid(PROXYCERTINFO_V4); if (nidv3 == 0 || nidv4 == 0) ERR_clear_error(); indexv3 = X509_get_ext_by_NID(cert, nidv3, -1); indexv4 = X509_get_ext_by_NID(cert, nidv4, -1); if (indexv3 != -1 || indexv4 != -1) { /* Its a proxy! */ ext = X509_get_ext(cert, (indexv3 == -1 ? indexv4 : indexv3)); if (ext) { #if 0 myPROXYCERTINFO *certinfo = NULL; certinfo = (myPROXYCERTINFO *)X509V3_EXT_d2i(ext); if (certinfo) { myPROXYPOLICY *policy = myPROXYCERTINFO_get_proxypolicy(certinfo); if (policy) { /* ASN1_OBJECT *policylang; */ /* policylang = myPROXYPOLICY_get_policy_language(policy); */ /* TO DO: discover exact type of proxy. */ } myPROXYCERTINFO_free(certinfo); } #endif #if OPENSSL_VERSION_NUMBER >= 0x00908010 #ifdef EXFLAG_PROXY X509_set_proxy_flag(cert); #endif #endif //return 1; } } subject = X509_get_subject_name(cert); ne = X509_NAME_get_entry(subject, X509_NAME_entry_count(subject)-1); if (!OBJ_cmp(X509_NAME_ENTRY_get_object(ne),OBJ_nid2obj(NID_commonName))) { data = X509_NAME_ENTRY_get_data(ne); if ((data->length == 5 && !memcmp(data->data,"proxy",5)) || (data->length == 13 && !memcmp(data->data,"limited proxy",13))) { if (data->length == 13) { ret = 2; /* its a limited proxy */ } else { ret = 1; /* its a proxy */ } /* * Lets dup the issuer, and add the CN=proxy. This should * match the subject. i.e. proxy can only be signed by * the owner. We do it this way, to double check * all the ANS1 bits as well. */ /* DEE? needs some more err processing here */ name = X509_NAME_dup(X509_get_issuer_name(cert)); ne = X509_NAME_ENTRY_create_by_NID(NULL, NID_commonName, V_ASN1_APP_CHOOSE, (ret == 2) ? (unsigned char *) "limited proxy" : (unsigned char *)"proxy", -1); X509_NAME_add_entry(name,ne,X509_NAME_entry_count(name),0); X509_NAME_ENTRY_free(ne); ne = NULL; if (X509_NAME_cmp_no_set(name,subject)) { /* * Reject this certificate, only the user * may sign the proxy */ ret = -1; } X509_NAME_free(name); } else if (ext != NULL) { name = X509_NAME_dup(X509_get_issuer_name(cert)); ne = X509_NAME_ENTRY_create_by_NID(NULL, NID_commonName, data->type, data->data, -1); X509_NAME_add_entry(name,ne,X509_NAME_entry_count(name),0); X509_NAME_ENTRY_free(ne); ne = NULL; if (X509_NAME_cmp_no_set(name,subject)) { /* * Reject this certificate, only the user * may sign the proxy */ ret = -1; } else ret = 1; X509_NAME_free(name); } } #if OPENSSL_VERSION_NUMBER >= 0x00908010 #ifdef EXFLAG_PROXY if (ret > 0) { X509_set_proxy_flag(cert); if (ret == 1) X509_set_proxy_pathlen(cert, -1); /* unlimited */ else if (ret == 2) X509_set_proxy_pathlen(cert, 0); /* Only at top level if limited */ } #endif #endif return ret; } #if SSLEAY_VERSION_NUMBER >= 0x0090600fL /********************************************************************** Function: proxy_check_issued() Description: Replace the OpenSSL check_issued in x509_vfy.c with our own, so we can override the key usage checks if its a proxy. We are only looking for X509_V_ERR_KEYUSAGE_NO_CERTSIGN Parameters:r See OpenSSL check_issued Returns: See OpenSSL check_issued **********************************************************************/ int PRIVATE proxy_check_issued( UNUSED(X509_STORE_CTX * ctx), X509 * x, X509 * issuer) { int ret; int ret_code = 1; ret = X509_check_issued(issuer, x); if (ret != X509_V_OK) { ret_code = 0; switch (ret) { case X509_V_ERR_AKID_SKID_MISMATCH: /* * If the proxy was created with a previous version of Globus * where the extensions where copied from the user certificate * This error could arise, as the akid will be the wrong key * So if its a proxy, we will ignore this error. * We should remove this in 12/2001 * At which time we may want to add the akid extension to the proxy. */ case X509_V_ERR_KEYUSAGE_NO_CERTSIGN: /* * If this is a proxy certificate then the issuer * does not need to have the key_usage set. * So check if its a proxy, and ignore * the error if so. */ if (proxy_check_proxy_name(x) >= 1) { ret_code = 1; } break; default: break; } } return ret_code; } #endif /********************************************************************** Function: proxy_verify_callback() Description: verify callback for SSL. Used to check that proxy certificates are only signed by the correct user, and used for debuging. Also on the server side, the s3_srvr.c code does not appear to save the peer cert_chain, like the client side does. We need these for additional proxies, so we need to copy the X509 to our own stack. Parameters: ok 1 then we are given one last chance to check this certificate. 0 then this certificate has failed, and ctx has the reason (see X509_STORE_CTX_get_error()). We may want to override the failure. ctx the X509_STORE_CTX which has as a user arg, our proxy verify desc. Returns: 1 - Passed the tests 0 - failed. The x509_vfy.c will return a failed to caller. **********************************************************************/ int proxy_verify_callback( int ok, X509_STORE_CTX * ctx) { X509_OBJECT *obj = NULL; X509 * cert = NULL; #ifdef X509_V_ERR_CERT_REVOKED X509_CRL * crl; X509_REVOKED * revoked; #endif SSL * ssl = NULL; SSL_CTX * ssl_ctx = NULL; canl_proxy_verify_desc * pvd; int itsaproxy = 0; int i; int ret; time_t goodtill; char * cert_dir = NULL; EVP_PKEY *key = NULL; canl_ocsprequest_t *ocsp_data = NULL; X509 *ctx_cert, *ctx_current_cert, *ctx_current_issuer; STACK_OF(X509) *ctx_chain; int ctx_error; /* * If we are being called recursivly to check delegate * cert chains, or being called by the grid-proxy-init, * a pointer to a canl_proxy_verify_desc will be * pased in the store. If we are being called by SSL, * by a roundabout process, the app_data of the ctx points at * the SSL. We have saved a pointer to the context handle * in the SSL, and its magic number should be PVD_MAGIC_NUMBER */ if (!(pvd = (canl_proxy_verify_desc *) X509_STORE_CTX_get_ex_data(ctx, PVD_STORE_EX_DATA_IDX))) { ssl = (SSL *)X509_STORE_CTX_get_app_data(ctx); if (ssl) { ssl_ctx = SSL_get_SSL_CTX(ssl); pvd = (canl_proxy_verify_desc *)SSL_CTX_get_ex_data(ssl_ctx, PVD_SSL_EX_DATA_IDX); } } /* * For now we hardcode the ex_data. We could look at all * ex_data to find ours. * Double check that we are indeed pointing at the context * handle. If not, we have an internal error, SSL may have changed * how the callback and app_data are handled */ if (pvd) { if(pvd->magicnum != PVD_MAGIC_NUMBER) { PRXYerr(PRXYERR_F_VERIFY_CB, PRXYERR_R_BAD_MAGIC); return(0); } } ctx_cert = X509_STORE_CTX_get0_cert(ctx); ctx_current_cert = X509_STORE_CTX_get_current_cert(ctx); ctx_current_issuer = X509_STORE_CTX_get0_current_issuer(ctx); ctx_chain = X509_STORE_CTX_get0_chain(ctx); ctx_error = X509_STORE_CTX_get_error(ctx); /* * We now check for some error conditions which * can be disregarded. */ if (!ok) { switch (ctx_error) { #if SSLEAY_VERSION_NUMBER >= 0x0090581fL case X509_V_ERR_PATH_LENGTH_EXCEEDED: /* * Since OpenSSL does not know about proxies, * it will count them against the path length * So we will ignore the errors and do our * own checks later on, when we check the last * certificate in the chain we will check the chain. */ /* Path length exceeded for the CA (should never happen in OpenSSL - famous last words) */ /*Log( L_DEBUG, "Shallow Error X509_V_ERR_PATH_LENGTH_EXCEEDED: Running alternative RFC5280 and RFC3820 compliance tests.\n"); */ if (grid_verifyPathLenConstraints(ctx_chain) == X509_V_OK){ ok = 1; break; } #endif /* Path length exceeded for the Proxy! -> Override and continue */ /* This is NOT about X509_V_ERR_PATH_LENGTH_EXCEEDED */ #if OPENSSL_VERSION_NUMBER >= 0x00908000L if (ctx_error == X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED) if (grid_verifyPathLenConstraints(ctx_chain) == X509_V_OK){ ok = 1; break; } #endif #if OPENSSL_VERSION_NUMBER >= 0x10000000L case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: /* * OpenSSL 1.0 causes the cert to be added twice to * the store. */ if (proxy_check_proxy_name(ctx_cert) && !X509_cmp(ctx_cert, ctx_current_cert)) ok = 1; break; #endif case X509_V_ERR_INVALID_CA: case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: /* * This may happen since proxy issuers are not CAs */ if (proxy_check_proxy_name(ctx_cert) >= 1) { if (proxy_check_issued(ctx, ctx_cert, ctx_current_cert)) { ok = 1; } } break; case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: if (proxy_check_proxy_name(ctx_cert) >= 1) { if (check_critical_extensions(ctx_cert, 1)) /* Allows proxy specific extensions on proxies. */ ok = 1; } break; case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: case X509_V_ERR_CERT_UNTRUSTED: if (proxy_check_proxy_name(ctx_current_cert) > 0) { /* Server side, needed to fully recognize a proxy. */ ok = 1; } break; #ifdef X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED: /* Proxies ARE allowed */ ok = 1; break; #endif default: break; } /* if already failed, skip the rest */ if (!ok) goto fail_verify; /*openssl failed, but we checked it ourselves and it was OK*/ X509_STORE_CTX_set_error(ctx, 0); //return(ok); } /* Note: OpenSSL will try to verify the client's chain on the client side before sending it abroad. However, to properly verify proxy conditions, we need access to pvd, which is not passed. For this reason, in this scenario we assume that if the checks above passed, everything is ok. If it is not, it will be discovered during server-side validation of the cert. */ if (!pvd) return ok; /* * All of the OpenSSL tests have passed and we now get to * look at the certificate to verify the proxy rules, * and ca-signing-policy rules. We will also do a CRL check */ /* * Test if the name ends in CN=proxy and if the issuer * name matches the subject without the final proxy. */ ret = proxy_check_proxy_name(ctx_current_cert); if (ret < 0) { PRXYerr(PRXYERR_F_VERIFY_CB,PRXYERR_R_BAD_PROXY_ISSUER); X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_SIGNATURE_FAILURE); goto fail_verify; } if (ret > 0) { /* Its a proxy */ if (ret == 2) { /* * If its a limited proxy, it means it use has been limited * during delegation. It can not sign other certs i.e. * it must be the top cert in the chain. * Depending on who we are, * We may want to accept this for authentication. * * Globus gatekeeper -- don't accept * sslk5d accept, but should check if from local site. * globus user-to-user Yes, thats the purpose * of this cert. * * We will set the limited_proxy flag, to show we found * one. A Caller can then reject. */ pvd->limited_proxy = 1; /* its a limited proxy */ if (X509_STORE_CTX_get_error_depth(ctx) && !pvd->multiple_limited_proxy_ok) { /* tried to sign a cert with a limited proxy */ /* i.e. there is still another cert on the chain */ /* indicating we are trying to sign it! */ PRXYerr(PRXYERR_F_VERIFY_CB,PRXYERR_R_LPROXY_MISSED_USED); X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_SIGNATURE_FAILURE); goto fail_verify; } } pvd->proxy_depth++; itsaproxy = 1; } if (!itsaproxy) { #ifdef X509_V_ERR_CERT_REVOKED int n = 0; /* * SSLeay 0.9.0 handles CRLs but does not check them. * We will check the crl for this cert, if there * is a CRL in the store. * If we find the crl is not valid, we will fail, * as once the sysadmin indicates that CRLs are to * be checked, he best keep it upto date. * * When future versions of SSLeay support this better, * we can remove these tests. * we come through this code for each certificate, * starting with the CA's We will check for a CRL * each time, but only check the signature if the * subject name matches, and check for revoked * if the issuer name matches. * this allows the CA to revoke its own cert as well. */ obj = X509_OBJECT_new(); if (X509_STORE_get_by_subject(ctx, X509_LU_CRL, X509_get_subject_name(ctx_current_issuer), obj)) { crl = X509_OBJECT_get0_X509_CRL(obj); /* verify the signature on this CRL */ key = X509_get_pubkey(ctx_current_issuer); if (X509_CRL_verify(crl, key) <= 0) { PRXYerr(PRXYERR_F_VERIFY_CB,PRXYERR_R_CRL_SIGNATURE_FAILURE); X509_STORE_CTX_set_error(ctx, X509_V_ERR_CRL_SIGNATURE_FAILURE); goto fail_verify; } /* Check date see if expired */ i = X509_cmp_current_time(X509_CRL_get0_nextUpdate(crl)); if (i == 0) { PRXYerr(PRXYERR_F_VERIFY_CB,PRXYERR_R_CRL_NEXT_UPDATE_FIELD); X509_STORE_CTX_set_error(ctx, X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD); goto fail_verify; } if (i < 0) { PRXYerr(PRXYERR_F_VERIFY_CB,PRXYERR_R_CRL_HAS_EXPIRED); X509_STORE_CTX_set_error(ctx, X509_V_ERR_CRL_HAS_EXPIRED); goto fail_verify; } /* check if this cert is revoked */ n = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl)); for (i=0; ipvxd->certdir ? pvd->pvxd->certdir : getenv(X509_CERT_DIR); /* Do not need to check self signed certs against ca_policy_file */ if (X509_NAME_cmp(X509_get_subject_name(ctx_current_cert), X509_get_issuer_name(ctx_current_cert))) { { char * error_string = NULL; struct policy **signings = NULL; struct policy **namespaces = NULL; int result = SUCCESS_UNDECIDED; read_pathrestriction(ctx_chain, cert_dir, &namespaces, &signings); result = restriction_evaluate(ctx_chain, namespaces, signings); voms_free_policies(namespaces); voms_free_policies(signings); if (result != SUCCESS_PERMIT) { PRXYerr(PRXYERR_F_VERIFY_CB, PRXYERR_R_CA_POLICY_VIOLATION); if (error_string != NULL) { /* * Seperate error message returned from policy check * from above error message with colon */ ERR_add_error_data(2, ": ", error_string); free(error_string); } ERR_set_continue_needed(); goto fail_verify; } else { if (error_string != NULL) { free(error_string); } } } } /* end of do not check self signed certs */ } /* * We want to determine the minimum amount of time * any certificate in the chain is good till * Will be used for lifetime calculations */ goodtill = ASN1_UTCTIME_mktime(X509_get_notAfter(ctx_current_cert)); if (pvd->pvxd->goodtill == 0 || goodtill < pvd->pvxd->goodtill) { pvd->pvxd->goodtill = goodtill; } /* We need to make up a cert_chain if we are the server. * The ssl code does not save this as I would expect. * This is used to create a new proxy by delegation. */ pvd->cert_depth++; if (!check_critical_extensions(ctx_current_cert, itsaproxy)) { PRXYerr(PRXYERR_F_VERIFY_CB, PRXYERR_R_UNKNOWN_CRIT_EXT); X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REJECTED); goto fail_verify; } /* * We ignored any path length restrictions above because * OpenSSL was counting proxies against the limit. * If we are on the last cert in the chain, we * know how many are proxies, so we can do the * path length check now. * See x509_vfy.c check_chain_purpose * all we do is substract off the proxy_dpeth */ if(ctx_current_cert == ctx_cert) { int err; err = grid_verifyPathLenConstraints(ctx_chain); X509_STORE_CTX_set_error(ctx, err); if (err != X509_V_OK) goto fail_verify; } /* OCSP check */ ret = 0; if (pvd->pvxd->flags & CANL_SSL_OCSP_VERIFY_ALL){ if (!ocsp_data) ocsprequest_init(&ocsp_data); if (ocsp_data) { if (ctx_current_cert) ocsp_data->cert = ctx_current_cert; if (ctx_current_issuer) ocsp_data->issuer = ctx_current_issuer; if (cert_dir) ocsp_data->store.ca_dir = cert_dir; ocsp_data->skew = MAX_VALIDITY_PERIOD; ocsp_data->maxage = -1; if (ctx_chain) ocsp_data->cert_chain = ctx_chain; /*Timeout should be set here ocsp_data->timeout = -1; */ ret = do_ocsp_verify (ocsp_data); /* TODO sign key and cert */ ocsprequest_free(ocsp_data); ocsp_data = NULL; } } EVP_PKEY_free(key); if (obj) X509_OBJECT_free(obj); if (ret != 0) if (ret != CANL_OCSPRESULT_ERROR_NOAIAOCSPURI) ok = 0; return(ok); fail_verify: if (key) EVP_PKEY_free(key); if (obj) X509_OBJECT_free(obj); return(0); } /********************************************************************** Function: proxy_verify_cert_chain() Description: Parameters: Returns: 1 OK **********************************************************************/ int PRIVATE proxy_verify_cert_chain( X509 * ucert, STACK_OF(X509) * cert_chain, canl_proxy_verify_desc * pvd) { int retval = 0; X509_STORE * cert_store = NULL; X509_LOOKUP * lookup = NULL; X509_STORE_CTX *csc = NULL; X509 * xcert = NULL; X509 * scert = NULL; scert = ucert; if(!(cert_store = X509_STORE_new())){ goto err; } X509_STORE_set_verify_cb_func(cert_store, proxy_verify_callback); if (cert_chain != NULL) { int i =0; for (i=0;ipvxd->certdir,X509_FILETYPE_PEM); csc = X509_STORE_CTX_new(); X509_STORE_set_check_issued(cert_store, proxy_check_issued); X509_STORE_CTX_init(csc,cert_store,scert,NULL); X509_STORE_CTX_set_ex_data(csc, PVD_STORE_EX_DATA_IDX, (void *)pvd); #ifdef X509_V_FLAG_ALLOW_PROXY_CERTS X509_STORE_CTX_set_flags(csc, X509_V_FLAG_ALLOW_PROXY_CERTS); #endif if(X509_verify_cert(csc) != 1) { goto err; } } retval = 1; err: if (csc) X509_STORE_CTX_free(csc); if (cert_store) X509_STORE_free(cert_store); return retval; } #endif /* NO_PROXY_VERIFY_CALLBACK */ /********************************************************************** Function: proxy_get_filenames() Description: Gets the filenames for the various files used to store the cert, key, cert_dir and proxy. Environment variables to use: X509_CERT_DIR Directory of trusted certificates File names are hash values, see the SSLeay c_hash script. X509_CERT_FILE File of trusted certifiates X509_USER_PROXY File with a proxy certificate, key, and additional certificates to makeup a chain of certificates used to sign the proxy. X509_USER_CERT User long term certificate. X509_USER_KEY private key for the long term certificate. All of these are assumed to be in PEM form. If there is a X509_USER_PROXY, it will be searched first for the cert and key. If not defined, but a file /tmp/x509up_u is present, it will be used, otherwise the X509_USER_CERT and X509_USER_KEY will be used to find the certificate and key. If X509_USER_KEY is not defined, it will be assumed that the key is is the same file as the certificate. If windows, look in the registry HKEY_CURRENT_USER for the GSI_REGISTRY_DIR, then look for the x509_user_cert, etc. Then try $HOME/.globus/usercert.pem and $HOME/.globus/userkey.pem Unless it is being run as root, then look for /etc/grid-security/hostcert.pem and /etc/grid-security/hostkey.pem X509_CERT_DIR and X509_CERT_FILE can point to world readable shared director and file. One of these must be present. if not use $HOME/.globus/certificates or /etc/grid-security/certificates or $GLOBUS_DEPLOY_PATH/share/certificates or $GLOBUS_LOCATION/share/certificates or $GSI_DEPLOY_PATH/share/certificates or $GSI_INSTALL_PATH/share/certificates The file with the key must be owned by the user, and readable only by the user. This could be the X509_USER_PROXY, X509_USER_CERT or the X509_USER_KEY X509_USER_PROXY_FILE is used to generate the default proxy file name. In other words: proxy_get_filenames() is used by grid-proxy-init, wgpi, grid-proxy-info and Indirectly by gss_acquire_creds. For grid-proxy-init and wgpi, the proxy_in is 0, for acquire_creds its 1. This is used to signal how the proxy file is to be used, 1 for input 0 for output. The logic for output is to use the provided input parameter, registry, environment, or default name for the proxy. Wgpi calls this multiple times as the options window is updated. The file will be created if needed. The logic for input is to use the provided input parameter, registry, environment variable. But only use the default file if it exists, is owned by the user, and has something in it. But not when run as root. Then on input if there is a proxy, the user_cert and user_key are set to use the proxy. Smart card support using PKCS#11 is controled by the USE_PKCS11 flag. If the filename for the user key starts with SC: then it is assumed to be of the form SC:card:label where card is the name of a smart card, and label is the label of the key on the card. The card must be using Cryptoki (PKCS#11) This code has been developed using the DataKey implementation under Windows 95. This will allow the cert to have the same form, with the same label as well in the future. Parameters: Returns: **********************************************************************/ int proxy_get_filenames( int proxy_in, char ** p_cert_file, char ** p_cert_dir, char ** p_user_proxy, char ** p_user_cert, char ** p_user_key) { int status = -1; char * cert_file = NULL; char * cert_dir = NULL; char * user_proxy = NULL; char * user_cert = NULL; char * user_key = NULL; char * home = NULL; char * default_user_proxy = NULL; char * default_user_cert = NULL; char * default_user_key = NULL; char * default_cert_dir = NULL; char * installed_cert_dir = NULL; #ifdef WIN32 HKEY hkDir = NULL; char val_user_cert[512]; char val_user_key[512]; char val_user_proxy[512]; char val_cert_dir[512]; char val_cert_file[512]; LONG lval; DWORD type; #endif #ifdef WIN32 RegOpenKey(HKEY_CURRENT_USER,GSI_REGISTRY_DIR,&hkDir); #endif /* setup some default values */ if (p_cert_dir) { cert_dir = *p_cert_dir; } if (!cert_dir) { cert_dir = (char *)getenv(X509_CERT_DIR); } #ifdef WIN32 if (!cert_dir) { lval = sizeof(val_cert_dir)-1; if (hkDir && (RegQueryValueEx(hkDir,"x509_cert_dir",0,&type, val_cert_dir,&lval) == ERROR_SUCCESS)) { cert_dir = val_cert_dir; } } #endif if (p_cert_file) { cert_file = *p_cert_file; } if (!cert_file) { cert_file = (char *)getenv(X509_CERT_FILE); } #ifdef WIN32 if (!cert_file) { lval = sizeof(val_cert_file)-1; if (hkDir && (RegQueryValueEx(hkDir,"x509_cert_file",0,&type, val_cert_file,&lval) == ERROR_SUCCESS)) { cert_file = val_cert_file; } } #endif if (cert_dir == NULL) { /* * If ~/.globus/certificates exists, then use that */ home = getenv("HOME"); #ifndef WIN32 /* Under windows use c:\windows as default home */ if (!home) { home = "c:\\windows"; } #endif /* WIN32 */ if (home) { default_cert_dir = snprintf_wrap("%s%s%s", home, FILE_SEPERATOR, X509_DEFAULT_CERT_DIR); if (!default_cert_dir) { PRXYerr(PRXYERR_F_INIT_CRED, PRXYERR_R_OUT_OF_MEMORY); goto err; } if (checkstat(default_cert_dir) != 1) { /* default_cert_dir exists */ cert_dir = default_cert_dir; } } /* * Now check for host based default directory */ if (!cert_dir) { if (checkstat(X509_INSTALLED_HOST_CERT_DIR) != 1) { /* default_cert_dir exists */ cert_dir = X509_INSTALLED_HOST_CERT_DIR; } } if (!cert_dir) { /* * ...else look for (in order) * $GLOBUS_DEPLOY_PATH/share/certificates * $GLOBUS_LOCATION/share/certficates */ char *globus_location; globus_location = getenv("GLOBUS_DEPLOY_PATH"); if (!globus_location) { globus_location = getenv("GLOBUS_LOCATION"); } if (!globus_location) { globus_location = getenv("GSI_DEPLOY_PATH"); } if (!globus_location) { globus_location = getenv("GSI_INSTALL_PATH"); } if (globus_location) { installed_cert_dir = snprintf_wrap("%s%s%s", globus_location, FILE_SEPERATOR, X509_INSTALLED_CERT_DIR); if (!installed_cert_dir) { PRXYerr(PRXYERR_F_INIT_CRED, PRXYERR_R_OUT_OF_MEMORY); goto err; } /* * Previous code always set cert_dir to * default_cert_dir without checking for its * existance, so we'll also skip the existance * check here. */ cert_dir = installed_cert_dir; } } if (!cert_dir) { cert_dir = X509_INSTALLED_HOST_CERT_DIR; } } if (cert_dir) { if (checkstat(cert_dir) == 1) { PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROCESS_CERTS); ERR_add_error_data(2,"x509_cert_dir=",cert_dir); goto err; } } if (cert_file) { if (checkstat(cert_file) == 1) { PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROCESS_CERTS); ERR_add_error_data(2,"x509_cert_file=",cert_file); goto err; } } /* if X509_USER_PROXY is defined, use it for cert and key, * and for additional certs. * if not, and the default user_proxy file is present, * use it. * If not, get the X509_USER_CERT and X509_USER_KEY * if not, use ~/.globus/usercert.pem ~/.globus/userkey.pem */ if (p_user_proxy) { user_proxy = *p_user_proxy; } if (!user_proxy) { user_proxy = (char *)getenv(X509_USER_PROXY); } #ifdef WIN32 if (!user_proxy) { lval = sizeof(val_user_proxy)-1; if (hkDir && (RegQueryValueEx(hkDir,"x509_user_proxy",0,&type, val_user_proxy,&lval) == ERROR_SUCCESS)) { user_proxy = val_user_proxy; } } #endif if (!user_proxy && !getenv("X509_RUN_AS_SERVER")) { default_user_proxy = snprintf_wrap("%s%s%s%lu", DEFAULT_SECURE_TMP_DIR, FILE_SEPERATOR, X509_USER_PROXY_FILE, getuid()); if (!default_user_proxy) { PRXYerr(PRXYERR_F_INIT_CRED, PRXYERR_R_OUT_OF_MEMORY); goto err; } #ifndef WIN32 if ((!proxy_in || getuid() != 0) && checkstat(default_user_proxy) == 0) #endif { user_proxy = default_user_proxy; } } if (proxy_in && user_proxy) { user_cert = user_proxy; user_key = user_proxy; } else { if (!user_proxy && !proxy_in) { user_proxy = default_user_proxy; } if (p_user_cert) { user_cert = *p_user_cert; } if(!user_cert) { user_cert = (char *)getenv(X509_USER_CERT); } #ifdef WIN32 if (!user_cert) { lval = sizeof(val_user_cert)-1; if (hkDir && (RegQueryValueEx( hkDir, "x509_user_cert", 0, &type, val_user_cert,&lval) == ERROR_SUCCESS)) { user_cert = val_user_cert; } } #endif if (user_cert) { if (p_user_key) { user_key = *p_user_key; } if (!user_key) { user_key = (char *)getenv(X509_USER_KEY); } #ifdef WIN32 if (!user_key) { lval = sizeof(val_user_key)-1; if (hkDir && (RegQueryValueEx( hkDir, "x509_user_key", 0, &type, val_user_key,&lval) == ERROR_SUCCESS)) { user_key = val_user_key; } } #endif if (!user_key) { user_key = user_cert; } } else { #ifndef WIN32 if (getuid() == 0) { if (checkstat(X509_DEFAULT_HOST_CERT) != 1) { user_cert = X509_DEFAULT_HOST_CERT; } if (checkstat(X509_DEFAULT_HOST_KEY) != 1) { user_key = X509_DEFAULT_HOST_KEY; } } else #endif { if (!home) { home = getenv("HOME"); } if (!home) { #ifndef WIN32 PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_NO_HOME); goto err; #else home = "c:\\"; #endif } default_user_cert = snprintf_wrap("%s%s%s", home, FILE_SEPERATOR, X509_DEFAULT_USER_CERT); if (!default_user_cert) { PRXYerr(PRXYERR_F_INIT_CRED, PRXYERR_R_OUT_OF_MEMORY); goto err; } default_user_key = snprintf_wrap("%s%s%s", home,FILE_SEPERATOR, X509_DEFAULT_USER_KEY); if (!default_user_key) { PRXYerr(PRXYERR_F_INIT_CRED, PRXYERR_R_OUT_OF_MEMORY); goto err; } user_cert = default_user_cert; user_key = default_user_key; /* Support for pkcs12 credentials. */ { int fd = open(default_user_cert, O_RDONLY); if (fd >= 0) close(fd); else { /* Cannot open normal file -- look for pkcs12. */ char *certname = NULL; free(default_user_cert); free(default_user_key); certname = getenv("X509_USER_CRED"); if (!certname) { default_user_cert = snprintf_wrap("%s%s%s", home, FILE_SEPERATOR, X509_DEFAULT_USER_CERT_P12); if (!default_user_cert) { PRXYerr(PRXYERR_F_INIT_CRED, PRXYERR_R_OUT_OF_MEMORY); goto err; } if (checkstat(default_user_cert) != 0) { free(default_user_cert); default_user_cert = snprintf_wrap("%s%s%s", home, FILE_SEPERATOR, X509_DEFAULT_USER_CERT_P12_GT); } if (!default_user_cert) { PRXYerr(PRXYERR_F_INIT_CRED, PRXYERR_R_OUT_OF_MEMORY); goto err; } } else strcpy(default_user_cert, certname); default_user_key = strndup(default_user_cert, strlen(default_user_cert)); if (!default_user_key) { PRXYerr(PRXYERR_F_INIT_CRED, PRXYERR_R_OUT_OF_MEMORY); goto err; } user_cert = default_user_cert; user_key = default_user_key; } } } } } status = 0; err: if (!status) { if (p_cert_file && cert_file && !(*p_cert_file)) { *p_cert_file = strdup(cert_file); } if (p_cert_dir && cert_dir && !(*p_cert_dir)) { *p_cert_dir = strdup(cert_dir); } if (p_user_proxy && user_proxy && !(*p_user_proxy)) { *p_user_proxy = strdup(user_proxy); } if (p_user_cert && user_cert && !(*p_user_cert)) { free(*p_user_cert); *p_user_cert = strdup(user_cert); } if (p_user_key && user_key && !(*p_user_key)) { free(*p_user_key); *p_user_key = strdup(user_key); } } #ifdef WIN32 if (hkDir) { RegCloseKey(hkDir); } #endif free(default_user_proxy); free(installed_cert_dir); free(default_cert_dir); free(default_user_cert); free(default_user_key); return status; } /********************************************************************** Function: proxy_load_user_cert() Description: loads the users cert. May need a pw callback for Smartcard PIN. May use a smartcard too. Parameters: Returns: **********************************************************************/ static int cert_load_pkcs12(BIO *bio, int (*pw_cb)(), X509 **cert, EVP_PKEY **key, STACK_OF(X509) **chain) { PKCS12 *p12 = NULL; char *password = NULL; char buffer[1024]; int ret = 0; p12 = d2i_PKCS12_bio(bio, NULL); if (!p12) return 0; if (!PKCS12_verify_mac(p12, "", 0)) { int sz = 0; if (pw_cb) sz = pw_cb(buffer, 1024, 0); else if (EVP_read_pw_string(buffer, 1024, EVP_get_pw_prompt(), 0) != -1) sz = strlen(buffer); if (sz) password = buffer; else goto err; } else password=""; ret = PKCS12_parse(p12, password, key, cert, chain); err: memset(buffer, 0, 1024); if (p12) PKCS12_free(p12); return ret; } int PRIVATE proxy_load_user_cert_and_key_pkcs12(const char *user_cert, X509 **cert, STACK_OF(X509) **stack, EVP_PKEY **pkey, int (*pw_cb) ()) { BIO *bio = BIO_new_file(user_cert, "rb"); int res = cert_load_pkcs12(bio, pw_cb, cert, pkey, stack); BIO_free(bio); if (res) return 1; else { if (ERR_peek_error() == ERR_PACK(ERR_LIB_PEM,PEM_F_PEM_READ_BIO,PEM_R_NO_START_LINE)) { ERR_clear_error(); PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_INVALID_CERT); } else { PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROCESS_CERT); } ERR_add_error_data(2, "\n File=", user_cert); return 0; } } int PRIVATE proxy_load_user_cert( const char * user_cert, X509 ** certificate, UNUSED(int (*pw_cb)()), UNUSED(unsigned long * hSession)) { int status = -1; FILE * fp; /* Check arguments */ if (!user_cert) { PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROBLEM_USER_NOCERT_FILE); status = PRXYERR_R_PROBLEM_USER_NOCERT_FILE; ERR_add_error_data(1, "\n No certificate file found"); goto err; } if (!strncmp(user_cert,"SC:",3)) { #ifdef USE_PKCS11 char * cp; char * kp; int rc; cp = user_cert + 3; kp = strchr(cp,':'); if (kp == NULL) { PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROBLEM_USER_NOCERT_FILE); ERR_add_error_data(2, "\n SmartCard reference=", user_cert); status = PRXYERR_R_PROBLEM_USER_NOCERT_FILE; goto err; } kp++; /* skip the : */ if (*hSession == 0) { rc = sc_init(hSession, cp, NULL, NULL, CKU_USER, 0); if (rc) { PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROCESS_CERT); ERR_add_error_data( 1, "\n Failed to open session to smartcard"); status = PRXYERR_R_PROCESS_CERT; goto err; } } rc = sc_get_cert_obj_by_label(*hSession,kp, certificate); if (rc) { PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROCESS_CERT); ERR_add_error_data( 2, "\n Could not find certificate on smartcard, label=", kp); status = PRXYERR_R_PROCESS_CERT; goto err; } #else PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROCESS_CERT); ERR_add_error_data( 1, "\n Smartcard support not compiled with this program"); status = PRXYERR_R_PROCESS_CERT; goto err; /* * DEE? need to add a random number routine here, to use * the random number generator on the card */ #endif /* USE_PKCS11 */ } else { if((fp = fopen(user_cert,"rb")) == NULL) { PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROBLEM_USER_NOCERT_FILE); status = PRXYERR_R_PROBLEM_USER_NOCERT_FILE; ERR_add_error_data(2, "\n Cert File=", user_cert); goto err; } if (PEM_read_X509(fp, certificate, OPENSSL_PEM_CB(NULL,NULL)) == NULL) { if (ERR_peek_error() == ERR_PACK(ERR_LIB_PEM,PEM_F_PEM_READ_BIO,PEM_R_NO_START_LINE)) { ERR_clear_error(); PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_INVALID_CERT); status = PRXYERR_R_INVALID_CERT; } else { PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROCESS_CERT); status = PRXYERR_R_PROCESS_CERT; } ERR_add_error_data(2, "\n File=", user_cert); fclose(fp); goto err; } fclose(fp); } status = 0; err: return status; } /********************************************************************** Function: proxy_load_user_key() Description: loads the users key. Assumes the cert has been loaded, and checks they match. May use a smartcard too. Parameters: Returns: an int specifying the error **********************************************************************/ int PRIVATE proxy_load_user_key( EVP_PKEY ** private_key, X509 * ucert, const char * user_key, int (*pw_cb)(), UNUSED(unsigned long * hSession)) { int status = -1; FILE * fp; EVP_PKEY * ucertpkey; int (*xpw_cb)(); if (!private_key) return 0; xpw_cb = pw_cb; #ifdef WIN32 if (!xpw_cb) { xpw_cb = read_passphrase_win32; } #endif /* Check arguments */ if (!user_key) { PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROBLEM_USER_NOKEY_FILE); status = PRXYERR_R_PROBLEM_USER_NOKEY_FILE; ERR_add_error_data(1,"\n No key file found"); goto err; } if (!strncmp(user_key,"SC:",3)) { #ifdef USE_PKCS11 char *cp; char *kp; int rc; cp = user_key + 3; kp = strchr(cp,':'); if (kp == NULL) { PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROBLEM_KEY_FILE); ERR_add_error_data(2,"\n SmartCard reference=",user_key); status = PRXYERR_R_PROBLEM_KEY_FILE; goto err; } kp++; /* skip the : */ if (*hSession == 0) { rc = sc_init(hSession, cp, NULL, NULL, CKU_USER, 0); if (rc) { PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROCESS_KEY); ERR_add_error_data( 1, "\n Failed to open session to smartcard"); status = PRXYERR_R_PROCESS_KEY; goto err; } } rc = sc_get_priv_key_obj_by_label(hSession,kp, private_key); if (rc) { PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROCESS_KEY); ERR_add_error_data( 2, "\n Could not find key on smartcard, label=", kp); status = PRXYERR_R_PROCESS_KEY; goto err; } #else PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROCESS_KEY); ERR_add_error_data( 1, "\n Smartcard support not compiled with this program"); status = PRXYERR_R_PROCESS_KEY; goto err; /* * DEE? could add a random number routine here, to use * the random number generator on the card */ #endif /* USE_PKCS11 */ } else { int keystatus; if ((fp = fopen(user_key,"rb")) == NULL) { PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROBLEM_USER_NOKEY_FILE); status = PRXYERR_R_PROBLEM_USER_NOKEY_FILE; ERR_add_error_data(2, "\n File=",user_key); goto err; } /* user key must be owned by the user, and readable * only be the user */ if ((keystatus = checkstat(user_key))) { if (keystatus == 4) { status = PRXYERR_R_USER_ZERO_LENGTH_KEY_FILE; PRXYerr(PRXYERR_F_INIT_CRED, PRXYERR_R_USER_ZERO_LENGTH_KEY_FILE); } else { status = PRXYERR_R_PROBLEM_KEY_FILE; PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROBLEM_KEY_FILE); } ERR_add_error_data(2, "\n File=", user_key); fclose(fp); goto err; } if (PEM_read_PrivateKey(fp, private_key, OPENSSL_PEM_CB(xpw_cb,NULL)) == NULL) { unsigned long error = ERR_peek_error(); fclose(fp); #ifdef PEM_F_PEM_DEF_CALLBACK if (error == ERR_PACK(ERR_LIB_PEM, PEM_F_PEM_DEF_CALLBACK, PEM_R_PROBLEMS_GETTING_PASSWORD)) #else if (error == ERR_PACK(ERR_LIB_PEM, PEM_F_DEF_CALLBACK, PEM_R_PROBLEMS_GETTING_PASSWORD)) #endif { ERR_clear_error(); } #ifdef EVP_F_EVP_DECRYPTFINAL_EX else if (error == ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT)) #else else if (error == ERR_PACK(ERR_LIB_EVP, EVP_F_EVP_DECRYPTFINAL, EVP_R_BAD_DECRYPT)) #endif { ERR_clear_error(); PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_WRONG_PASSPHRASE); status = PRXYERR_R_WRONG_PASSPHRASE; } else { PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_PROCESS_KEY); ERR_add_error_data(2, "\n File=", user_key); status = PRXYERR_R_PROCESS_KEY; } goto err; } fclose(fp); } /* * check that the private key matches the certificate * Dont want a mixup of keys and certs * Will only check rsa type for now. */ if (ucert) { int match; #if 0 X509_PUBKEY *key = X509_get_X509_PUBKEY(ucert); ucertpkey = X509_PUBKEY_get(key); int mismatch = 0; if (ucertpkey!= NULL && ucertpkey->type == (*private_key)->type) { if (ucertpkey->type == EVP_PKEY_RSA) { /* add in key as random data too */ if (ucertpkey->pkey.rsa != NULL) { if(ucertpkey->pkey.rsa->p != NULL) { RAND_add((void*)ucertpkey->pkey.rsa->p->d, BN_num_bytes(ucertpkey->pkey.rsa->p), BN_num_bytes(ucertpkey->pkey.rsa->p)); } if(ucertpkey->pkey.rsa->q != NULL) { RAND_add((void*)ucertpkey->pkey.rsa->q->d, BN_num_bytes(ucertpkey->pkey.rsa->q), BN_num_bytes(ucertpkey->pkey.rsa->q)); } } if ((ucertpkey->pkey.rsa != NULL) && (ucertpkey->pkey.rsa->n != NULL) && ((*private_key)->pkey.rsa != NULL) ) { if ((*private_key)->pkey.rsa->n != NULL && BN_num_bytes((*private_key)->pkey.rsa->n)) { if (BN_cmp(ucertpkey->pkey.rsa->n, (*private_key)->pkey.rsa->n)) { mismatch=1; } } else { (*private_key)->pkey.rsa->n = BN_dup(ucertpkey->pkey.rsa->n); (*private_key)->pkey.rsa->e = BN_dup(ucertpkey->pkey.rsa->e); } } } } else { mismatch=1; } EVP_PKEY_free(ucertpkey); #endif match = X509_check_private_key(ucert, *private_key); if (match != 1) { PRXYerr(PRXYERR_F_INIT_CRED,PRXYERR_R_KEY_CERT_MISMATCH); status = PRXYERR_R_KEY_CERT_MISMATCH; goto err; } } status = 0; err: /* DEE need more cleanup */ return status; } /********************************************************************** Function: ASN1_UTCTIME_mktime() Description: SSLeay only has compare functions to the current So we define a convert to time_t from which we can do differences Much of this it taken from the X509_cmp_current_time() routine. Parameters: Returns: time_t **********************************************************************/ time_t PRIVATE ASN1_TIME_mktime(ASN1_TIME *ctm) { /* * note: ASN1_TIME, ASN1_UTCTIME, ASN1_GENERALIZEDTIME are different * typedefs of the same type. */ return ASN1_UTCTIME_mktime(ctm); } time_t PRIVATE ASN1_UTCTIME_mktime( ASN1_UTCTIME * ctm) { char *str; time_t offset; time_t newtime; char buff1[32]; char *p; int i; struct tm tm; int size = 0; switch (ctm->type) { case V_ASN1_UTCTIME: size=10; break; case V_ASN1_GENERALIZEDTIME: size=12; break; } p = buff1; i = ctm->length; str = (char *)ctm->data; if ((i < 11) || (i > 17)) { return 0; } memcpy(p,str,size); p += size; str += size; if ((*str == 'Z') || (*str == '-') || (*str == '+')) { *(p++)='0'; *(p++)='0'; } else { *(p++)= *(str++); *(p++)= *(str++); } *(p++) = 'Z'; *p = '\0'; if (*str == 'Z') { offset=0; } else { if ((*str != '+') && (str[5] != '-')) { return 0; } offset=((str[1]-'0')*10+(str[2]-'0'))*60; offset+=(str[3]-'0')*10+(str[4]-'0'); if (*str == '-') { offset=-offset; } } tm.tm_isdst = 0; int index = 0; if (ctm->type == V_ASN1_UTCTIME) { tm.tm_year = (buff1[index++]-'0')*10; tm.tm_year += (buff1[index++]-'0'); } else { tm.tm_year = (buff1[index++]-'0')*1000; tm.tm_year += (buff1[index++]-'0')*100; tm.tm_year += (buff1[index++]-'0')*10; tm.tm_year += (buff1[index++]-'0'); } if (tm.tm_year < 70) { tm.tm_year+=100; } if (tm.tm_year > 1900) { tm.tm_year -= 1900; } tm.tm_mon = (buff1[index++]-'0')*10; tm.tm_mon += (buff1[index++]-'0')-1; tm.tm_mday = (buff1[index++]-'0')*10; tm.tm_mday += (buff1[index++]-'0'); tm.tm_hour = (buff1[index++]-'0')*10; tm.tm_hour += (buff1[index++]-'0'); tm.tm_min = (buff1[index++]-'0')*10; tm.tm_min += (buff1[index++]-'0'); tm.tm_sec = (buff1[index++]-'0')*10; tm.tm_sec += (buff1[index]-'0'); /* * mktime assumes local time, so subtract off * timezone, which is seconds off of GMT. first * we need to initialize it with tzset() however. */ tzset(); #if defined(HAVE_TIMEGM) newtime = (timegm(&tm) + offset*60*60); #elif defined(HAVE_TIME_T_TIMEZONE) newtime = (mktime(&tm) + offset*60*60 - timezone); #elif defined(HAVE_TIME_T__TIMEZONE) newtime = (mktime(&tm) + offset*60*60 - _timezone); #else newtime = (mktime(&tm) + offset*60*60); #endif return newtime; } #ifdef CLASS_ADD /********************************************************************** Function: proxy_extension_class_add_create() Description: create a X509_EXTENSION for the class_add info. Parameters: A buffer and length. The date is added as ANS1_OCTET_STRING to an extension with the class_add OID. Returns: **********************************************************************/ X509_EXTENSION PRIVATE * proxy_extension_class_add_create( void * buffer, size_t length) { X509_EXTENSION * ex = NULL; ASN1_OBJECT * class_add_obj = NULL; ASN1_OCTET_STRING * class_add_oct = NULL; int crit = 0; if(!(class_add_obj = OBJ_nid2obj(OBJ_txt2nid("CLASSADD")))) { PRXYerr(PRXYERR_F_PROXY_SIGN,PRXYERR_R_CLASS_ADD_OID); goto err; } if(!(class_add_oct = ASN1_OCTET_STRING_new())) { PRXYerr(PRXYERR_F_PROXY_SIGN,PRXYERR_R_CLASS_ADD_EXT); goto err; } class_add_oct->data = buffer; class_add_oct->length = length; if (!(ex = X509_EXTENSION_create_by_OBJ(NULL, class_add_obj, crit, class_add_oct))) { PRXYerr(PRXYERR_F_PROXY_SIGN,PRXYERR_R_CLASS_ADD_EXT); goto err; } class_add_oct = NULL; return ex; err: if (class_add_oct) { ASN1_OCTET_STRING_free(class_add_oct); } if (class_add_obj) { ASN1_OBJECT_free(class_add_obj); } return NULL; } #endif int PRIVATE determine_filenames(char **cacert, char **certdir, char **outfile, char **certfile, char **keyfile, int noregen) { char *oldoutfile = NULL; if (noregen) { int modify = 0; if (*certfile == NULL && *keyfile == NULL) modify = 1; if (proxy_get_filenames(0, NULL, NULL, &oldoutfile, certfile, keyfile)) goto err; if (modify) { free(*certfile); free(*keyfile); *certfile = strdup(oldoutfile); *keyfile = oldoutfile; } else free(oldoutfile); if (proxy_get_filenames(0, cacert, certdir, outfile, certfile, keyfile)) goto err; } else if (proxy_get_filenames(0, cacert, certdir, outfile, certfile, keyfile)) goto err; return 1; err: return 0; } int load_credentials(const char *certname, const char *keyname, X509 **cert, STACK_OF(X509) **stack, EVP_PKEY **key, int (*callback)()) { STACK_OF(X509) *chain = NULL; if (!certname) return 0; unsigned long hSession = 0; if (!strncmp(certname, "SC:", 3)) EVP_set_pw_prompt("Enter card pin:"); else EVP_set_pw_prompt("Enter GRID pass phrase for this identity:"); if (strcmp(certname + strlen(certname) - 4, ".p12")) { if(proxy_load_user_cert(certname, cert, callback, &hSession)) goto err; EVP_set_pw_prompt("Enter GRID pass phrase:"); if (keyname) { if (!strncmp(keyname, "SC:", 3)) EVP_set_pw_prompt("Enter card pin:"); if (proxy_load_user_key(key, *cert, keyname, callback, &hSession)) goto err; } if (stack && (strncmp(certname, "SC:", 3) && (!keyname || !strcmp(certname, keyname)))) { chain = sk_X509_new_null(); if (proxy_load_user_proxy(chain, certname) < 0) goto err; *stack = chain; } } else { if (!proxy_load_user_cert_and_key_pkcs12(certname, cert, stack, key, callback)) goto err; } return 1; err: if (chain) sk_X509_free(chain); if (cert) { X509_free(*cert); *cert = NULL; } if (key) { EVP_PKEY_free(*key); *key = NULL; } return 0; } int PRIVATE load_certificate_from_file(FILE *file, X509 **cert, STACK_OF(X509) **stack) { BIO *in = NULL; if (!cert) return 0; in = BIO_new_fp(file, BIO_NOCLOSE); if (in) { *cert = PEM_read_bio_X509(in, NULL, 0, NULL); if(!*cert) goto err; if (stack) { *stack = load_chain(in, 0); if (!(*stack)) goto err; } } BIO_free(in); return 1; err: BIO_free(in); if (cert) X509_free(*cert); if (stack) sk_X509_pop_free(*stack, X509_free); return 0; } STACK_OF(X509) *load_chain(BIO *in, char *certfile) { STACK_OF(X509_INFO) *sk=NULL; STACK_OF(X509) *stack=NULL, *ret=NULL; X509_INFO *xi; int first = 1; if(!(stack = sk_X509_new_null())) { if (certfile) printf("memory allocation failure\n"); goto end; } /* This loads from a file, a stack of x509/crl/pkey sets */ if(!(sk=PEM_X509_INFO_read_bio(in,NULL,NULL,NULL))) { if (certfile) printf("error reading the file, %s\n",certfile); goto end; } /* scan over it and pull out the certs */ while (sk_X509_INFO_num(sk)) { /* skip first cert */ if (first) { first = 0; continue; } xi=sk_X509_INFO_shift(sk); if (xi->x509 != NULL) { sk_X509_push(stack,xi->x509); xi->x509=NULL; } X509_INFO_free(xi); } if(!sk_X509_num(stack)) { if (certfile) printf("no certificates in file, %s\n",certfile); sk_X509_free(stack); goto end; } ret=stack; end: sk_X509_INFO_free(sk); return(ret); } static char hextoint(char r, char s) { int v = 0; if (isxdigit(r) && isxdigit(s)) { v = hex2num(r); v <<= 4; v += hex2num(s); } return v; } static unsigned char *reencode_string(unsigned char *string, int *len) { unsigned char *temp = string; unsigned char *pos = string; char t = '\0'; char r = '\0'; *len = 0; while(*string) { switch (*string) { case '\\': t = *++string; if (t == '\\') { *pos++ = '\\'; ++(*len); } else if (isxdigit(t)) { r = *++string; *pos++ = hextoint(tolower(t), tolower(r)); ++(*len); ++string; } else { *pos++ = t; ++(*len); ++string; } break; default: ++(*len); *pos++ = *string++; break; } } return temp; } static X509_NAME *make_DN(const char *dnstring) { char *buffername = (char*)malloc(strlen(dnstring)+1); unsigned char *buffervalue = (unsigned char*)malloc(strlen(dnstring)+1); char *currentname; unsigned char *currentvalue; X509_NAME *name = NULL; int valuelen = 0; char next = 0; name = X509_NAME_new(); int status = 0; /* * 0 = looking for /type * 1 = looking for value */ do { switch (status) { case 0: /* Parse for /Name= */ currentname=buffername; while (*dnstring) { if (*dnstring == '\\') { *currentname++ = *++dnstring; if (*dnstring == '\0') { break; } dnstring++; } else if (*dnstring == '=') { *currentname='\0'; break; } else if (*dnstring == '\0') { break; } else *currentname++ = *dnstring++; } /* now, if *dnstring == '\0' then error; */ if (*dnstring == '\0') goto err; /* else, we got a type, now look for a value. */ status = 1; dnstring++; break; case 1: /* Parse for value */ currentvalue=buffervalue; while (*dnstring) { if (*dnstring == '\\') { next = *++dnstring; if (next == '\0') { break; } else if (next != '/') { *currentvalue++ = '\\'; *currentvalue++ = next; } else { *currentvalue++ = '/'; } dnstring++; } else if (*dnstring == '/') { *currentvalue='\0'; break; } else if (*dnstring == '\0') { *currentvalue='\0'; break; } else *currentvalue++ = *dnstring++; } *currentvalue='\0'; if (strlen((char*)buffervalue) == 0) goto err; /* Now we have both type and value. Add to the X509_NAME_ENTRY */ buffervalue = reencode_string(buffervalue, &valuelen); X509_NAME_add_entry_by_txt(name, buffername+1, /* skip initial '/' */ V_ASN1_APP_CHOOSE, buffervalue, valuelen, X509_NAME_entry_count(name), 0); status = 0; break; } } while (*dnstring); free(buffername); free(buffervalue); return name; err: free(buffername); free(buffervalue); X509_NAME_free(name); return NULL; } static int check_critical_extensions(X509 *cert, int itsaproxy) { int i = 0; ASN1_OBJECT *extension_obj; int nid; X509_EXTENSION *ex; int nid_pci3 = my_txt2nid(PROXYCERTINFO_V3); int nid_pci4 = my_txt2nid(PROXYCERTINFO_V4); for (i=0; i < X509_get_ext_count(cert); i++) { ex = X509_get_ext(cert,i); if(X509_EXTENSION_get_critical(ex)) { extension_obj = X509_EXTENSION_get_object(ex); nid = OBJ_obj2nid(extension_obj); if (itsaproxy) { if (nid != NID_basic_constraints && nid != NID_key_usage && nid != NID_ext_key_usage && nid != NID_netscape_cert_type && nid != NID_subject_key_identifier && nid != NID_authority_key_identifier && nid != nid_pci3 && nid != nid_pci4) { return 0; } } else { if (nid != NID_basic_constraints && nid != NID_key_usage && nid != NID_ext_key_usage && nid != NID_netscape_cert_type && nid != NID_subject_key_identifier && nid != NID_authority_key_identifier) { return 0; } } } } return 1; } /* Check if certificate can be used as a CA to sign standard X509 certs */ /* * Return 1 if true; 0 if not. */ int grid_x509IsCA(X509 *cert) { int idret; /* final argument to X509_check_purpose() is whether to check for CAness */ idret = X509_check_purpose(cert, X509_PURPOSE_SSL_CLIENT, 1); if (idret == 1) return 1; else if (idret == 0) return 0; else { /* Log( L_WARN, "Purpose warning code = %d\n", idret );*/ return 1; } } /****************************************************************************** Function: verify_PROXYCERTINFO_get_policy Description: Get a policy from the PROXYCERTINFO structure ******************************************************************************/ PROXYPOLICY * verify_PROXYCERTINFO_get_policy(PROXYCERTINFO *cert_info) { if(cert_info) { return cert_info->policy; } return NULL; } /****************************************************************************** Function: verify_PROXYPOLICY_get_policy_language Description: Get the proxy language from the proxy policy ******************************************************************************/ ASN1_OBJECT * verify_PROXYPOLICY_get_policy_language(PROXYPOLICY *policy) { return policy->policy_language; } /****************************************************************************** Function: lcmaps_type_of_proxy Description: This function detects the type of certificates Parameters: certificate Returns: NONE CA EEC GT2_PROXY RFC_PROXY GT2_LIMITED_PROXY RFC_LIMITED_PROXY GT3_PROXY GT3_LIMITED_PROXY ******************************************************************************/ lcmaps_proxy_type_t lcmaps_type_of_proxy(X509 * cert) { lcmaps_proxy_type_t pt = NONE; char * cert_subjectdn = NULL; char * cert_issuerdn = NULL; char * tail_str = NULL; int len_subject_dn = 0; int len_issuer_dn = 0; X509_EXTENSION * pci_ext = NULL; PROXYCERTINFO * pci = NULL; PROXYPOLICY * policy = NULL; ASN1_OBJECT * policy_lang = NULL; int policy_nid; int index = -1; int retval = 0; /* Is it a CA certificate */ if (grid_x509IsCA(cert)) { /* Log (L_DEBUG, "%s: Detected CA certificate", __func__); */ pt = CA; goto finalize; } int i; char s[80]; X509_EXTENSION *ex; /* Check by OID */ for (i = 0; i < X509_get_ext_count(cert); ++i) { ex = X509_get_ext(cert, i); if (X509_EXTENSION_get_object(ex)) { OBJ_obj2txt(s, sizeof(s), X509_EXTENSION_get_object(ex), 1); if (strcmp(s, OID_RFC_PROXY) == 0) { pt = RFC_PROXY; /* Find index of OID_RFC_PROXY */ if((index = X509_get_ext_by_NID(cert, OBJ_txt2nid(OID_RFC_PROXY), -1)) != -1 && (pci_ext = X509_get_ext(cert,index)) && X509_EXTENSION_get_critical(pci_ext)) { if((pci = X509V3_EXT_d2i(pci_ext)) == NULL) { retval = 1; goto failure; } /* Pull a certificate policy from the extension */ if((policy = verify_PROXYCERTINFO_get_policy(pci)) == NULL) { retval = 2; goto failure; } /* Get policy language */ if((policy_lang = verify_PROXYPOLICY_get_policy_language(policy)) == NULL) { retval = 3; goto failure; } /* Lang to NID, lang's NID holds RFC Proxy type, like limited. Impersonation is the default */ policy_nid = OBJ_obj2nid(policy_lang); if(policy_nid == OBJ_txt2nid(IMPERSONATION_PROXY_OID)) { pt = RFC_PROXY; } else if(policy_nid == OBJ_txt2nid(INDEPENDENT_PROXY_OID)) { pt = RFC_PROXY; } else if(policy_nid == OBJ_txt2nid(LIMITED_PROXY_OID)) { pt = RFC_LIMITED_PROXY; } else { /* RFC_RESTRICTED_PROXY */ pt = RFC_PROXY; } if(X509_get_ext_by_NID(cert, OBJ_txt2nid(OID_RFC_PROXY), index) != -1) { retval = 4; goto failure; } } goto finalize; } if (strcmp(s, OID_GLOBUS_PROXY_V3) == 0) { pt = GT3_PROXY; /* Find index of OID_GT3_PROXY - Don't make it search for critical extentions... VOMS doesn't set those. */ if((index = X509_get_ext_by_NID(cert, OBJ_txt2nid(OID_GLOBUS_PROXY_V3), -1)) != -1 && (pci_ext = X509_get_ext(cert,index))) { if((pci = X509V3_EXT_d2i(pci_ext)) == NULL) { retval = 5; goto failure; } /* Pull a certificate policy from the extension */ if((policy = verify_PROXYCERTINFO_get_policy(pci)) == NULL) { retval = 6; goto failure; } /* Get policy language */ if((policy_lang = verify_PROXYPOLICY_get_policy_language(policy)) == NULL) { retval = 16; /*Error(__func__, "Can't get policy language from PROXYCERTINFO extension");*/ goto failure; } /* Lang to NID, lang's NID holds RFC Proxy type, like limited. Impersonation is the default */ policy_nid = OBJ_obj2nid(policy_lang); if(policy_nid == OBJ_txt2nid(IMPERSONATION_PROXY_OID)) { pt = GT3_PROXY; } else if(policy_nid == OBJ_txt2nid(INDEPENDENT_PROXY_OID)) { pt = GT3_PROXY; } else if(policy_nid == OBJ_txt2nid(LIMITED_PROXY_OID)) { pt = GT3_LIMITED_PROXY; } else { /* GT3_RESTRICTED_PROXY */ pt = GT3_PROXY; } if(X509_get_ext_by_NID(cert, OBJ_txt2nid(OID_GLOBUS_PROXY_V3), index) != -1) { retval = 7; goto failure; } } goto finalize; } if (strcmp(s, OID_GLOBUS_PROXY_V2) == 0) { pt = GT3_PROXY; /* Check for GT2_PROXY tail */ if (cert_subjectdn && (strlen(cert_subjectdn) > strlen("/cn=proxy")) && (tail_str = &cert_subjectdn[strlen(cert_subjectdn) - strlen("/cn=proxy")]) && (strcasecmp(tail_str, "/cn=proxy") == 0) ) { pt = GT2_PROXY; goto finalize; } /* Check for GT2_LIMITED_PROXY tail */ if (cert_subjectdn && (strlen(cert_subjectdn) > strlen("/cn=limited proxy")) && (tail_str = &cert_subjectdn[strlen(cert_subjectdn) - strlen("/cn=limited proxy")]) && (strcasecmp(tail_str, "/cn=limited proxy") == 0) ) { pt = GT2_LIMITED_PROXY; goto finalize; } retval = 8; goto failure; } } } /* Options left: GT2_PROXY, GT2_LIMITED_PROXY, EEC */ /* Extract Subject DN - Needs free */ if (!(cert_subjectdn = X509_NAME_oneline (X509_get_subject_name (cert), NULL, 0))) { retval = 9; goto failure; } if (!(cert_issuerdn = X509_NAME_oneline (X509_get_issuer_name (cert), NULL, 0))) { retval = 10; goto failure; } /* Check length of the DNs */ len_subject_dn = strlen(cert_subjectdn); len_issuer_dn = strlen(cert_issuerdn); /* Lower case the Subject DN */ /* for (j = 0; j < strlen(cert_subjectdn); j++) { cert_subjectdn[j] = tolower(cert_subjectdn[j]); } */ /* Proxies always has a longer subject_dn then a issuer_dn and * the issuer_dn is a substring of the subject_dn */ if ( (len_issuer_dn < len_subject_dn) && (strncmp(cert_subjectdn, cert_issuerdn, len_issuer_dn) == 0) ) { /* Check for GT2_PROXY tail */ if (cert_subjectdn && (strlen(cert_subjectdn) > strlen("/cn=proxy")) && (tail_str = &cert_subjectdn[strlen(cert_subjectdn) - strlen("/cn=proxy")]) && (strcasecmp(tail_str, "/cn=proxy") == 0) ) { pt = GT2_PROXY; goto finalize; } /* Check for GT2_LIMITED_PROXY tail */ if (cert_subjectdn && (strlen(cert_subjectdn) > strlen("/cn=limited proxy")) && (tail_str = &cert_subjectdn[strlen(cert_subjectdn) - strlen("/cn=limited proxy")]) && (strcasecmp(tail_str, "/cn=limited proxy") == 0) ) { pt = GT2_LIMITED_PROXY; goto finalize; } /* Check for RFC_PROXY, without the need for OpenSSL proxy support */ /* Method: Check if the subject_dn is long enough, grab its tail and * snip of the 10 characters. Then check if the 10 characters are * numbers. */ if (cert_subjectdn && (strlen(cert_subjectdn) > strlen("/cn=0123456789")) && (tail_str = strrchr(cert_subjectdn, '=')) && (tail_str = &tail_str[1]) && (strtol(tail_str, NULL, 10)) && (errno != ERANGE) ) { /* Log (L_DEBUG, "%s: Detected RFC proxy certificate", __func__); */ pt = RFC_PROXY; goto finalize; } /* Don't know the type of proxy, could be an RFC proxy with * improper/incomplete implementation in the active OpenSSL version or * a mistake in the client software */ goto failure; } /* I have no idea what else it is, so I conclude that it's an EEC */ pt = EEC; goto finalize; failure: /* On failure, or non-distinct selections of the certificate, indicate NONE */ pt = NONE; finalize: if (cert_subjectdn) free(cert_subjectdn); if (cert_issuerdn) free(cert_issuerdn); return pt; } /****************************************************************************** Function: grid_verifyPathLenConstraints Oscar Koeroo's solution, thank you. Description: This function will check the certificate chain on CA based (RFC5280) and RFC3820 Proxy based Path Length Constraints. Parameters: chain of certificates Returns: 0 : Not ok, failure in the verification or the verification failed 1 : Ok, verification has succeeded and positive ******************************************************************************/ static int grid_verifyPathLenConstraints (STACK_OF(X509) * chain) { char *oper = "grid_verifyPathLenConstraints"; X509 *cert = NULL; int i, depth; lcmaps_proxy_type_t curr_cert_type = NONE, expe_cert_type = CA|EEC|RFC_PROXY|GT2_PROXY; int found_EEC = 0; char *cert_subjectdn = NULL; char *error_msg = NULL; int retval = 0; int ca_path_len_countdown = -1; int proxy_path_len_countdown = -1; int ex_pcpathlen, ex_pathlen; /* No chain, no game */ if (!chain) { retval = 1; goto failure; } /* Go through the list, from the CA(s) down through the EEC to the final delegation */ depth = sk_X509_num (chain); for (i=depth-1; i >= 0; --i) { if ((cert = sk_X509_value(chain, i))) { /* Init to None, indicating not to have identified it yet */ curr_cert_type = NONE; /* Extract Subject DN - Needs free */ if (!(cert_subjectdn = X509_NAME_oneline (X509_get_subject_name (cert), NULL, 0))) { retval = 1; goto failure; } ex_pcpathlen = X509_get_proxy_pathlen(cert); ex_pathlen = X509_get_pathlen(cert); /* Log (L_DEBUG, "\tCert here is: %s\n", cert_subjectdn); */ curr_cert_type = lcmaps_type_of_proxy(cert); if (curr_cert_type == NONE) { /* Error (oper, "Couldn't classify certificate at depth %d with subject DN \"%s\"\n", depth, cert_subjectdn); */ retval = 2; goto failure; } /* Mark that we've found an EEC - When we see it again, it's a failure */ if (curr_cert_type == EEC && found_EEC == 0) { found_EEC = 1; } else if (curr_cert_type == EEC && found_EEC == 1) { /* Error (oper, "Found another EEC classified certificate in the same chain at depth %d with subject DN \"%s\"\n", depth, cert_subjectdn); */ retval = 3; goto failure; } #if 0 /* NOTE: This is for quick debugging only */ error_msg = verify_generate_proxy_expectation_error_message(curr_cert_type, expe_cert_type); printf("%s: Build chain checker: %s. Cert at depth %d of %d with Subject DN: %s\n", oper, error_msg, i, depth, cert_subjectdn); free(error_msg); error_msg = NULL; #endif /* Expectation management */ if (!((expe_cert_type & curr_cert_type) == curr_cert_type)) { /* Failed to comply with the expectations! */ #define USE_STRICT_PATH_VALIDATION #ifdef USE_STRICT_PATH_VALIDATION /* error_msg = verify_generate_proxy_expectation_error_message(curr_cert_type, expe_cert_type); Error(oper, "Certificate chain not build in the right order. %s. Cert at depth %d of %d with Subject DN: %s\n", error_msg, i, depth, cert_subjectdn); free(error_msg); error_msg = NULL;*/ goto failure; #else /* error_msg = verify_generate_proxy_expectation_error_message(curr_cert_type, expe_cert_type); Log(L_INFO, "%s: Certificate chain not build in the right order. %s. Cert at depth %d of %d with Subject DN: %s\n", oper, error_msg, i, depth, cert_subjectdn); free(error_msg); error_msg = NULL; */ goto continue_after_warning; #endif } #ifndef USE_STRICT_PATH_VALIDATION continue_after_warning: #endif if (curr_cert_type == CA) { /* Expected next certificate type is: CA or EEC certificate */ expe_cert_type = CA|EEC; /*Log (L_DEBUG, "Current cert is a CA: %s\n", cert_subjectdn);*/ /* Exceeded CA Path Length ? */ if (ca_path_len_countdown == 0) { /*Error(oper, "CA Path Length Constraint exceeded on depth %d for certificate \"%s\". No CA certifcates were expected at this stage.\n", i, cert_subjectdn);*/ retval = 4; goto failure; } /* Store pathlen, override when small, otherwise keep the smallest */ if (ex_pathlen != -1) { /* Update when ca_path_len_countdown is the initial value * or when the PathLenConstraint is smaller then the * remembered ca_path_len_countdown */ if ((ca_path_len_countdown == -1) || (ex_pathlen < ca_path_len_countdown)) { ca_path_len_countdown = ex_pathlen; } else { /* If a path length was already issuesd, lower ca_path_len_countdown */ if (ca_path_len_countdown != -1) ca_path_len_countdown--; } } else { /* If a path length was already issuesd, lower ca_path_len_countdown */ if (ca_path_len_countdown != -1) ca_path_len_countdown--; } } else if (curr_cert_type == EEC) { /* Expected next certificate type is: GT2_PROXY, GT3_PROXY, RFC_PROXY or a Limited proxy of these flavors certificate */ expe_cert_type = GT2_PROXY|GT3_PROXY|RFC_PROXY|GT2_LIMITED_PROXY|GT3_LIMITED_PROXY|RFC_LIMITED_PROXY; /*Log (L_DEBUG, "Current cert is a EEC: %s\n", cert_subjectdn);*/ } else if (curr_cert_type == GT2_PROXY) { /* Expected next certificate type is: GT2_PROXY certificate */ expe_cert_type = GT2_PROXY|GT2_LIMITED_PROXY; /*Log (L_DEBUG, "Current cert is a GT2 Proxy: %s\n", cert_subjectdn);*/ } else if (curr_cert_type == GT2_LIMITED_PROXY) { /* Expected next certificate type is: GT2_LIMITED_PROXY certificate */ expe_cert_type = GT2_LIMITED_PROXY; /* Log (L_DEBUG, "Current cert is a GT2 Limited Proxy: %s\n", cert_subjectdn); */ } else if (curr_cert_type == GT3_PROXY) { /* Expected next certificate type is: GT3_PROXY certificate */ expe_cert_type = GT3_PROXY|GT3_LIMITED_PROXY; /* Log (L_DEBUG, "Current cert is a GT3 Proxy: %s\n", cert_subjectdn);*/ } else if (curr_cert_type == GT3_LIMITED_PROXY) { /* Expected next certificate type is: GT3_LIMITED_PROXY certificate */ expe_cert_type = GT3_LIMITED_PROXY; /* Log (L_DEBUG, "Current cert is a GT3 Limited Proxy: %s\n", cert_subjectdn);*/ } else if (curr_cert_type == RFC_PROXY) { /* Expected next certificate type is: RFC_PROXY certificate */ expe_cert_type = RFC_PROXY|RFC_LIMITED_PROXY; /* Log (L_DEBUG, "Current cert is a RFC Proxy: %s\n", cert_subjectdn);*/ /* Exceeded CA Path Length ? */ if (proxy_path_len_countdown == 0) { /* Error(oper, "Proxy Path Length Constraint exceeded on depth %d of %d for certificate \"%s\". No Proxy certifcates were expected at this stage.\n", i, depth, cert_subjectdn);*/ goto failure; } /* Store pathlen, override when small, otherwise keep the smallest */ if (ex_pcpathlen != -1) { /* Update when proxy_path_len_countdown is the initial value * or when the PathLenConstraint is smaller then the * remembered proxy_path_len_countdown */ if ((proxy_path_len_countdown == -1) || (ex_pcpathlen < proxy_path_len_countdown)) { proxy_path_len_countdown = ex_pcpathlen; /* Log (L_DEBUG, "Cert here is: %s -> Setting proxy path len constraint to: %d\n", cert_subjectdn, cert->ex_pcpathlen);*/ } else { /* If a path length was already issuesd, lower ca_path_len_countdown */ if (proxy_path_len_countdown != -1) proxy_path_len_countdown--; /* Log (L_DEBUG, "Cert here is: %s -> Countdown is at %d\n", cert_subjectdn, proxy_path_len_countdown);*/ } } else { /* If a path length was already issued, lower ca_path_len_countdown */ if (proxy_path_len_countdown != -1) { proxy_path_len_countdown--; /* Log (L_DEBUG, "Cert here is: %s -> Countdown is at %d\n", cert_subjectdn, proxy_path_len_countdown);*/ } } } else if (curr_cert_type == RFC_LIMITED_PROXY) { /* Expected next certificate type is: RFC_LIMITED_PROXY certificate */ expe_cert_type = RFC_LIMITED_PROXY; /* Log (L_DEBUG, "Current cert is a RFC Limited Proxy: %s\n", cert_subjectdn);*/ /* Exceeded CA Path Length ? */ if (proxy_path_len_countdown == 0) { /* Error(oper, "Proxy Path Length Constraint exceeded on depth %d of %d for certificate \"%s\". No Proxy certifcates were expected at this stage.\n", i, depth, cert_subjectdn);*/ goto failure; } /* Store pathlen, override when small, otherwise keep the smallest */ if (ex_pcpathlen != -1) { /* Update when proxy_path_len_countdown is the initial value * or when the PathLenConstraint is smaller then the * remembered proxy_path_len_countdown */ if ((proxy_path_len_countdown == -1) || (ex_pcpathlen < proxy_path_len_countdown)) { proxy_path_len_countdown = ex_pcpathlen; /* Log (L_DEBUG, "Cert here is: %s -> Setting proxy path len constraint to: %d\n", cert_subjectdn, cert->ex_pcpathlen);*/ } else { /* If a path length was already issuesd, lower ca_path_len_countdown */ if (proxy_path_len_countdown != -1) proxy_path_len_countdown--; /* Log (L_DEBUG, "Cert here is: %s -> Countdown is at %d\n", cert_subjectdn, proxy_path_len_countdown);*/ } } else { /* If a path length was already issued, lower ca_path_len_countdown */ if (proxy_path_len_countdown != -1) { proxy_path_len_countdown--; /* Log (L_DEBUG, "Cert here is: %s -> Countdown is at %d\n", cert_subjectdn, proxy_path_len_countdown);*/ } } } /* Free memory during each cycle */ if (cert_subjectdn) { free(cert_subjectdn); cert_subjectdn = NULL; } } } /* Return an OK (thumbs up) in the grid_X509_verify_callback() */ if (cert_subjectdn) { free(cert_subjectdn); cert_subjectdn = NULL; } return X509_V_OK; failure: if (cert_subjectdn) { free(cert_subjectdn); cert_subjectdn = NULL; } return X509_V_ERR_CERT_REJECTED; } canl-c-3.0.0/src/proxy/config.h0000644000015500017500000000053413017332513016033 0ustar tomcat6jenkins#if defined(__GNUC__) #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) #define UNUSED(z) z __attribute__ ((unused)) #else #define UNUSED(z) z #endif #define PRIVATE __attribute__ ((visibility ("hidden"))) #define PUBLIC __attribute__ ((visibility ("default"))) #else #define UNUSED(z) z #define PRIVATE #define PUBLIC #endif canl-c-3.0.0/src/proxy/doio.h0000644000015500017500000000235413017332513015522 0ustar tomcat6jenkins/********************************************************************* * * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it * * Copyright (c) Members of the EGEE Collaboration. 2004-2010. * See http://www.eu-egee.org/partners/ for details on the copyright holders. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Parts of this code may be based upon or even include verbatim pieces, * originally written by other people, in which case the original header * follows. * *********************************************************************/ #ifndef VOMS_DOIO_H #define VOMS_DOIO_H #include extern char *snprintf_wrap(const char *format, ...); extern char *vsnprintf_wrap(const char *format, va_list v); #endif canl-c-3.0.0/src/proxy/listfunc.h0000644000015500017500000000240113017332513016410 0ustar tomcat6jenkins/********************************************************************* * * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it * * Copyright (c) Members of the EGEE Collaboration. 2004-2010. * See http://www.eu-egee.org/partners/ for details on the copyright holders. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Parts of this code may be based upon or even include verbatim pieces, * originally written by other people, in which case the original header * follows. * *********************************************************************/ #ifndef VOMS_LISTFUNC_H #define VOMS_LISTFUNC_H #include typedef void (*freefn)(void *); extern char **listadd(char **vect, char *data); extern void listfree(char **vect, freefn f); #endif canl-c-3.0.0/src/proxy/myproxycertinfo.h0000644000015500017500000001106013017332513020043 0ustar tomcat6jenkins/********************************************************************* * * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it * Valerio Venturi - valerio.venturi@cnaf.infn.it * * Copyright (c) Members of the EGEE Collaboration. 2004-2010. * See http://www.eu-egee.org/partners/ for details on the copyright holders. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Parts of this code may be based upon or even include verbatim pieces, * originally written by other people, in which case the original header * follows. * *********************************************************************/ #ifndef VOMS_PROXYCERTINFO_H #define VOMS_PROXYCERTINFO_H #include #include #include /* predefined policy language */ #define IMPERSONATION_PROXY_OID "1.3.6.1.5.5.7.21.1" #define IMPERSONATION_PROXY_SN "IMPERSONATION_PROXY" #define IMPERSONATION_PROXY_LN "GSI impersonation proxy" #define INDEPENDENT_PROXY_OID "1.3.6.1.5.5.7.21.2" #define INDEPENDENT_PROXY_SN "INDEPENDENT_PROXY" #define INDEPENDENT_PROXY_LN "GSI independent proxy" /* generic policy language */ #define GLOBUS_GSI_PROXY_GENERIC_POLICY_OID "1.3.6.1.4.1.3536.1.1.1.8" #define LIMITED_PROXY_OID "1.3.6.1.4.1.3536.1.1.1.9" #define LIMITED_PROXY_SN "LIMITED_PROXY" #define LIMITED_PROXY_LN "GSI limited proxy" #define PROXYCERTINFO_V3 "1.3.6.1.4.1.3536.1.222" #define PROXYCERTINFO_V4 "1.3.6.1.5.5.7.1.14" /* error handling */ #define ASN1_F_PROXYPOLICY_NEW 450 #define ASN1_F_D2I_PROXYPOLICY 451 #define ASN1_F_PROXYCERTINFO_NEW 430 #define ASN1_F_D2I_PROXYCERTINFO 431 /* data structure */ typedef struct myPROXYPOLICY_st { ASN1_OBJECT * policy_language; ASN1_OCTET_STRING * policy; } myPROXYPOLICY; typedef struct myPROXYCERTINFO_st { ASN1_INTEGER * path_length; myPROXYPOLICY * proxypolicy; int version; } myPROXYCERTINFO; /* myPROXYPOLICY function */ /* allocating and free memory */ extern myPROXYPOLICY * myPROXYPOLICY_new(); extern void myPROXYPOLICY_free(myPROXYPOLICY * proxypolicy); /* duplicate */ extern myPROXYPOLICY * myPROXYPOLICY_dup(myPROXYPOLICY * policy); /* set policy language */ extern int myPROXYPOLICY_set_policy_language(myPROXYPOLICY * policy, ASN1_OBJECT * policy_language); /* get policy language */ extern ASN1_OBJECT * myPROXYPOLICY_get_policy_language(myPROXYPOLICY * policy); /* set policy contents */ extern int myPROXYPOLICY_set_policy(myPROXYPOLICY * proxypolicy, unsigned char * policy, int length); /* get policy contents */ extern unsigned char * myPROXYPOLICY_get_policy(myPROXYPOLICY * policy, int * length); /* internal to der conversion */ extern int i2d_myPROXYPOLICY(myPROXYPOLICY * policy, unsigned char ** pp); /* der to internal conversion */ extern myPROXYPOLICY * d2i_myPROXYPOLICY(myPROXYPOLICY ** policy, unsigned char ** pp, long length); /*myPROXYCERTINFO function */ /* allocating and free memory */ extern myPROXYCERTINFO * myPROXYCERTINFO_new(); extern void myPROXYCERTINFO_free(myPROXYCERTINFO * proxycertinfo); /* set path_length */ extern int myPROXYCERTINFO_set_path_length(myPROXYCERTINFO * proxycertinfo, long path_length); /* get ptah length */ extern long myPROXYCERTINFO_get_path_length(myPROXYCERTINFO * proxycertinfo); /* set proxypolicy */ extern int myPROXYCERTINFO_set_proxypolicy(myPROXYCERTINFO * proxycertinfo, myPROXYPOLICY * proxypolicy); /* get proxypolicy */ extern myPROXYPOLICY * myPROXYCERTINFO_get_proxypolicy(myPROXYCERTINFO * proxycertinfo); /* internal to der conversion */ extern int i2d_myPROXYCERTINFO(myPROXYCERTINFO * proxycertinfo, unsigned char ** pp); /* der to internal conversion */ extern myPROXYCERTINFO * d2i_myPROXYCERTINFO(myPROXYCERTINFO ** cert_info, unsigned char ** a, long length); extern int myPROXYCERTINFO_set_version(myPROXYCERTINFO *cert_info, int version); extern int proxynative(void); extern void InitProxyCertInfoExtension(int full); #endif canl-c-3.0.0/src/proxy/normalize.h0000644000015500017500000000234113017332513016564 0ustar tomcat6jenkins/********************************************************************* * * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it * * Copyright (c) Members of the EGEE Collaboration. 2004-2010. * See http://www.eu-egee.org/partners/ for details on the copyright holders. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Parts of this code may be based upon or even include verbatim pieces, * originally written by other people, in which case the original header * follows. * *********************************************************************/ #ifndef _VOMS_NORMALIZE_H #define _VOMS_NORMALIZE_H #ifdef __cplusplus extern "C" { #endif extern char *normalize(const char *str); #ifdef __cplusplus } #endif #endif canl-c-3.0.0/src/proxy/parsertypes.h0000644000015500017500000000274413017332513017154 0ustar tomcat6jenkins/********************************************************************* * * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it * Valerio Venturi - Valerio.Venturi@cnaf.infn.it * * Copyright (c) Members of the EGEE Collaboration. 2004-2010. * See http://www.eu-egee.org/partners/ for details on the copyright holders. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Parts of this code may be based upon or even include verbatim pieces, * originally written by other people, in which case the original header * follows. * *********************************************************************/ #ifndef _OLDGAA_PARSERTYPES_H #define _OLDGAA_PARSERTYPES_H struct condition { char **subjects; char *original; int positive; }; #define TYPE_SIGNING 0 #define TYPE_NAMESPACE 1 struct policy { char *caname; int self; int type; struct condition **conds; }; #define SUCCESS_PERMIT 0 #define SUCCESS_DENY 1 #define SUCCESS_UNDECIDED 2 #endif canl-c-3.0.0/src/proxy/pkcs11.h0000644000015500017500000012503013017332513015667 0ustar tomcat6jenkins/* pkcs11.h Copyright 2006, 2007 g10 Code GmbH Copyright 2006 Andreas Jellinghaus This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without modifications, as long as this notice is preserved. This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, to the extent permitted by law; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ /* Please submit changes back to the Scute project at http://www.scute.org/ (or send them to marcus@g10code.com), so that they can be picked up by other projects from there as well. */ /* This file is a modified implementation of the PKCS #11 standard by RSA Security Inc. It is mostly a drop-in replacement, with the following change: This header file does not require any macro definitions by the user (like CK_DEFINE_FUNCTION etc). In fact, it defines those macros for you (if useful, some are missing, let me know if you need more). There is an additional API available that does comply better to the GNU coding standard. It can be switched on by defining CRYPTOKI_GNU before including this header file. For this, the following changes are made to the specification: All structure types are changed to a "struct ck_foo" where CK_FOO is the type name in PKCS #11. All non-structure types are changed to ck_foo_t where CK_FOO is the lowercase version of the type name in PKCS #11. The basic types (CK_ULONG et al.) are removed without substitute. All members of structures are modified in the following way: Type indication prefixes are removed, and underscore characters are inserted before words. Then the result is lowercased. Note that function names are still in the original case, as they need for ABI compatibility. CK_FALSE, CK_TRUE and NULL_PTR are removed without substitute. Use . If CRYPTOKI_COMPAT is defined before including this header file, then none of the API changes above take place, and the API is the one defined by the PKCS #11 standard. */ #ifndef PKCS11_H #define PKCS11_H 1 #if defined(__cplusplus) extern "C" { #endif /* The version of cryptoki we implement. The revision is changed with each modification of this file. If you do not use the "official" version of this file, please consider deleting the revision macro (you may use a macro with a different name to keep track of your versions). */ #define CRYPTOKI_VERSION_MAJOR 2 #define CRYPTOKI_VERSION_MINOR 20 #define CRYPTOKI_VERSION_REVISION 6 /* Compatibility interface is default, unless CRYPTOKI_GNU is given. */ #ifndef CRYPTOKI_GNU #ifndef CRYPTOKI_COMPAT #define CRYPTOKI_COMPAT 1 #endif #endif /* System dependencies. */ #if defined(_WIN32) || defined(CRYPTOKI_FORCE_WIN32) /* There is a matching pop below. */ #pragma pack(push, cryptoki, 1) #ifdef CRYPTOKI_EXPORTS #define CK_SPEC __declspec(dllexport) #else #define CK_SPEC __declspec(dllimport) #endif #else #define CK_SPEC #endif #ifdef CRYPTOKI_COMPAT /* If we are in compatibility mode, switch all exposed names to the PKCS #11 variant. There are corresponding #undefs below. */ #define ck_flags_t CK_FLAGS #define ck_version _CK_VERSION #define ck_info _CK_INFO #define cryptoki_version cryptokiVersion #define manufacturer_id manufacturerID #define library_description libraryDescription #define library_version libraryVersion #define ck_notification_t CK_NOTIFICATION #define ck_slot_id_t CK_SLOT_ID #define ck_slot_info _CK_SLOT_INFO #define slot_description slotDescription #define hardware_version hardwareVersion #define firmware_version firmwareVersion #define ck_token_info _CK_TOKEN_INFO #define serial_number serialNumber #define max_session_count ulMaxSessionCount #define session_count ulSessionCount #define max_rw_session_count ulMaxRwSessionCount #define rw_session_count ulRwSessionCount #define max_pin_len ulMaxPinLen #define min_pin_len ulMinPinLen #define total_public_memory ulTotalPublicMemory #define free_public_memory ulFreePublicMemory #define total_private_memory ulTotalPrivateMemory #define free_private_memory ulFreePrivateMemory #define utc_time utcTime #define ck_session_handle_t CK_SESSION_HANDLE #define ck_user_type_t CK_USER_TYPE #define ck_state_t CK_STATE #define ck_session_info _CK_SESSION_INFO #define slot_id slotID #define device_error ulDeviceError #define ck_object_handle_t CK_OBJECT_HANDLE #define ck_object_class_t CK_OBJECT_CLASS #define ck_hw_feature_type_t CK_HW_FEATURE_TYPE #define ck_key_type_t CK_KEY_TYPE #define ck_certificate_type_t CK_CERTIFICATE_TYPE #define ck_attribute_type_t CK_ATTRIBUTE_TYPE #define ck_attribute _CK_ATTRIBUTE #define value pValue #define value_len ulValueLen #define ck_date _CK_DATE #define ck_mechanism_type_t CK_MECHANISM_TYPE #define ck_mechanism _CK_MECHANISM #define parameter pParameter #define parameter_len ulParameterLen #define ck_mechanism_info _CK_MECHANISM_INFO #define min_key_size ulMinKeySize #define max_key_size ulMaxKeySize #define ck_rv_t CK_RV #define ck_notify_t CK_NOTIFY #define ck_function_list _CK_FUNCTION_LIST #define ck_createmutex_t CK_CREATEMUTEX #define ck_destroymutex_t CK_DESTROYMUTEX #define ck_lockmutex_t CK_LOCKMUTEX #define ck_unlockmutex_t CK_UNLOCKMUTEX #define ck_c_initialize_args _CK_C_INITIALIZE_ARGS #define create_mutex CreateMutex #define destroy_mutex DestroyMutex #define lock_mutex LockMutex #define unlock_mutex UnlockMutex #define reserved pReserved #endif /* CRYPTOKI_COMPAT */ typedef unsigned long ck_flags_t; struct ck_version { unsigned char major; unsigned char minor; }; struct ck_info { struct ck_version cryptoki_version; unsigned char manufacturer_id[32]; ck_flags_t flags; unsigned char library_description[32]; struct ck_version library_version; }; typedef unsigned long ck_notification_t; #define CKN_SURRENDER (0UL) typedef unsigned long ck_slot_id_t; struct ck_slot_info { unsigned char slot_description[64]; unsigned char manufacturer_id[32]; ck_flags_t flags; struct ck_version hardware_version; struct ck_version firmware_version; }; #define CKF_TOKEN_PRESENT (1UL << 0) #define CKF_REMOVABLE_DEVICE (1UL << 1) #define CKF_HW_SLOT (1UL << 2) #define CKF_ARRAY_ATTRIBUTE (1UL << 30) struct ck_token_info { unsigned char label[32]; unsigned char manufacturer_id[32]; unsigned char model[16]; unsigned char serial_number[16]; ck_flags_t flags; unsigned long max_session_count; unsigned long session_count; unsigned long max_rw_session_count; unsigned long rw_session_count; unsigned long max_pin_len; unsigned long min_pin_len; unsigned long total_public_memory; unsigned long free_public_memory; unsigned long total_private_memory; unsigned long free_private_memory; struct ck_version hardware_version; struct ck_version firmware_version; unsigned char utc_time[16]; }; #define CKF_RNG (1UL << 0) #define CKF_WRITE_PROTECTED (1UL << 1) #define CKF_LOGIN_REQUIRED (1UL << 2) #define CKF_USER_PIN_INITIALIZED (1UL << 3) #define CKF_RESTORE_KEY_NOT_NEEDED (1UL << 5) #define CKF_CLOCK_ON_TOKEN (1UL << 6) #define CKF_PROTECTED_AUTHENTICATION_PATH (1UL << 8) #define CKF_DUAL_CRYPTO_OPERATIONS (1UL << 9) #define CKF_TOKEN_INITIALIZED (1UL << 10) #define CKF_SECONDARY_AUTHENTICATION (1UL << 11) #define CKF_USER_PIN_COUNT_LOW (1UL << 16) #define CKF_USER_PIN_FINAL_TRY (1UL << 17) #define CKF_USER_PIN_LOCKED (1UL << 18) #define CKF_USER_PIN_TO_BE_CHANGED (1UL << 19) #define CKF_SO_PIN_COUNT_LOW (1UL << 20) #define CKF_SO_PIN_FINAL_TRY (1UL << 21) #define CKF_SO_PIN_LOCKED (1UL << 22) #define CKF_SO_PIN_TO_BE_CHANGED (1UL << 23) #define CK_UNAVAILABLE_INFORMATION ((unsigned long) -1) #define CK_EFFECTIVELY_INFINITE (0UL) typedef unsigned long ck_session_handle_t; #define CK_INVALID_HANDLE (0UL) typedef unsigned long ck_user_type_t; #define CKU_SO (0UL) #define CKU_USER (1UL) #define CKU_CONTEXT_SPECIFIC (2UL) typedef unsigned long ck_state_t; #define CKS_RO_PUBLIC_SESSION (0UL) #define CKS_RO_USER_FUNCTIONS (1UL) #define CKS_RW_PUBLIC_SESSION (2UL) #define CKS_RW_USER_FUNCTIONS (3UL) #define CKS_RW_SO_FUNCTIONS (4UL) struct ck_session_info { ck_slot_id_t slot_id; ck_state_t state; ck_flags_t flags; unsigned long device_error; }; #define CKF_RW_SESSION (1UL << 1) #define CKF_SERIAL_SESSION (1UL << 2) typedef unsigned long ck_object_handle_t; typedef unsigned long ck_object_class_t; #define CKO_DATA (0UL) #define CKO_CERTIFICATE (1UL) #define CKO_PUBLIC_KEY (2UL) #define CKO_PRIVATE_KEY (3UL) #define CKO_SECRET_KEY (4UL) #define CKO_HW_FEATURE (5UL) #define CKO_DOMAIN_PARAMETERS (6UL) #define CKO_MECHANISM (7UL) #define CKO_VENDOR_DEFINED (1UL << 31) typedef unsigned long ck_hw_feature_type_t; #define CKH_MONOTONIC_COUNTER (1UL) #define CKH_CLOCK (2UL) #define CKH_USER_INTERFACE (3UL) #define CKH_VENDOR_DEFINED (1UL << 31) typedef unsigned long ck_key_type_t; #define CKK_RSA (0UL) #define CKK_DSA (1UL) #define CKK_DH (2UL) #define CKK_ECDSA (3UL) #define CKK_EC (3UL) #define CKK_X9_42_DH (4UL) #define CKK_KEA (5UL) #define CKK_GENERIC_SECRET (0x10UL) #define CKK_RC2 (0x11UL) #define CKK_RC4 (0x12UL) #define CKK_DES (0x13UL) #define CKK_DES2 (0x14UL) #define CKK_DES3 (0x15UL) #define CKK_CAST (0x16UL) #define CKK_CAST3 (0x17UL) #define CKK_CAST128 (0x18UL) #define CKK_RC5 (0x19UL) #define CKK_IDEA (0x1aUL) #define CKK_SKIPJACK (0x1bUL) #define CKK_BATON (0x1cUL) #define CKK_JUNIPER (0x1dUL) #define CKK_CDMF (0x1eUL) #define CKK_AES (0x1fUL) #define CKK_BLOWFISH (0x20UL) #define CKK_TWOFISH (0x21UL) #define CKK_GOSTR3410 (0x30UL) #define CKK_VENDOR_DEFINED (1UL << 31) typedef unsigned long ck_certificate_type_t; #define CKC_X_509 (0UL) #define CKC_X_509_ATTR_CERT (1UL) #define CKC_WTLS (2UL) #define CKC_VENDOR_DEFINED (1UL << 31) typedef unsigned long ck_attribute_type_t; #define CKA_CLASS (0UL) #define CKA_TOKEN (1UL) #define CKA_PRIVATE (2UL) #define CKA_LABEL (3UL) #define CKA_APPLICATION (0x10UL) #define CKA_VALUE (0x11UL) #define CKA_OBJECT_ID (0x12UL) #define CKA_CERTIFICATE_TYPE (0x80UL) #define CKA_ISSUER (0x81UL) #define CKA_SERIAL_NUMBER (0x82UL) #define CKA_AC_ISSUER (0x83UL) #define CKA_OWNER (0x84UL) #define CKA_ATTR_TYPES (0x85UL) #define CKA_TRUSTED (0x86UL) #define CKA_CERTIFICATE_CATEGORY (0x87UL) #define CKA_JAVA_MIDP_SECURITY_DOMAIN (0x88UL) #define CKA_URL (0x89UL) #define CKA_HASH_OF_SUBJECT_PUBLIC_KEY (0x8aUL) #define CKA_HASH_OF_ISSUER_PUBLIC_KEY (0x8bUL) #define CKA_CHECK_VALUE (0x90UL) #define CKA_KEY_TYPE (0x100UL) #define CKA_SUBJECT (0x101UL) #define CKA_ID (0x102UL) #define CKA_SENSITIVE (0x103UL) #define CKA_ENCRYPT (0x104UL) #define CKA_DECRYPT (0x105UL) #define CKA_WRAP (0x106UL) #define CKA_UNWRAP (0x107UL) #define CKA_SIGN (0x108UL) #define CKA_SIGN_RECOVER (0x109UL) #define CKA_VERIFY (0x10aUL) #define CKA_VERIFY_RECOVER (0x10bUL) #define CKA_DERIVE (0x10cUL) #define CKA_START_DATE (0x110UL) #define CKA_END_DATE (0x111UL) #define CKA_MODULUS (0x120UL) #define CKA_MODULUS_BITS (0x121UL) #define CKA_PUBLIC_EXPONENT (0x122UL) #define CKA_PRIVATE_EXPONENT (0x123UL) #define CKA_PRIME_1 (0x124UL) #define CKA_PRIME_2 (0x125UL) #define CKA_EXPONENT_1 (0x126UL) #define CKA_EXPONENT_2 (0x127UL) #define CKA_COEFFICIENT (0x128UL) #define CKA_PRIME (0x130UL) #define CKA_SUBPRIME (0x131UL) #define CKA_BASE (0x132UL) #define CKA_PRIME_BITS (0x133UL) #define CKA_SUB_PRIME_BITS (0x134UL) #define CKA_VALUE_BITS (0x160UL) #define CKA_VALUE_LEN (0x161UL) #define CKA_EXTRACTABLE (0x162UL) #define CKA_LOCAL (0x163UL) #define CKA_NEVER_EXTRACTABLE (0x164UL) #define CKA_ALWAYS_SENSITIVE (0x165UL) #define CKA_KEY_GEN_MECHANISM (0x166UL) #define CKA_MODIFIABLE (0x170UL) #define CKA_ECDSA_PARAMS (0x180UL) #define CKA_EC_PARAMS (0x180UL) #define CKA_EC_POINT (0x181UL) #define CKA_SECONDARY_AUTH (0x200UL) #define CKA_AUTH_PIN_FLAGS (0x201UL) #define CKA_ALWAYS_AUTHENTICATE (0x202UL) #define CKA_WRAP_WITH_TRUSTED (0x210UL) #define CKA_GOSTR3410_PARAMS (0x250UL) #define CKA_GOSTR3411_PARAMS (0x251UL) #define CKA_GOST28147_PARAMS (0x252UL) #define CKA_HW_FEATURE_TYPE (0x300UL) #define CKA_RESET_ON_INIT (0x301UL) #define CKA_HAS_RESET (0x302UL) #define CKA_PIXEL_X (0x400UL) #define CKA_PIXEL_Y (0x401UL) #define CKA_RESOLUTION (0x402UL) #define CKA_CHAR_ROWS (0x403UL) #define CKA_CHAR_COLUMNS (0x404UL) #define CKA_COLOR (0x405UL) #define CKA_BITS_PER_PIXEL (0x406UL) #define CKA_CHAR_SETS (0x480UL) #define CKA_ENCODING_METHODS (0x481UL) #define CKA_MIME_TYPES (0x482UL) #define CKA_MECHANISM_TYPE (0x500UL) #define CKA_REQUIRED_CMS_ATTRIBUTES (0x501UL) #define CKA_DEFAULT_CMS_ATTRIBUTES (0x502UL) #define CKA_SUPPORTED_CMS_ATTRIBUTES (0x503UL) #define CKA_WRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x211UL) #define CKA_UNWRAP_TEMPLATE (CKF_ARRAY_ATTRIBUTE | 0x212UL) #define CKA_ALLOWED_MECHANISMS (CKF_ARRAY_ATTRIBUTE | 0x600UL) #define CKA_VENDOR_DEFINED (1UL << 31) struct ck_attribute { ck_attribute_type_t type; void *value; unsigned long value_len; }; struct ck_date { unsigned char year[4]; unsigned char month[2]; unsigned char day[2]; }; typedef unsigned long ck_mechanism_type_t; #define CKM_RSA_PKCS_KEY_PAIR_GEN (0UL) #define CKM_RSA_PKCS (1UL) #define CKM_RSA_9796 (2UL) #define CKM_RSA_X_509 (3UL) #define CKM_MD2_RSA_PKCS (4UL) #define CKM_MD5_RSA_PKCS (5UL) #define CKM_SHA1_RSA_PKCS (6UL) #define CKM_RIPEMD128_RSA_PKCS (7UL) #define CKM_RIPEMD160_RSA_PKCS (8UL) #define CKM_RSA_PKCS_OAEP (9UL) #define CKM_RSA_X9_31_KEY_PAIR_GEN (0xaUL) #define CKM_RSA_X9_31 (0xbUL) #define CKM_SHA1_RSA_X9_31 (0xcUL) #define CKM_RSA_PKCS_PSS (0xdUL) #define CKM_SHA1_RSA_PKCS_PSS (0xeUL) #define CKM_DSA_KEY_PAIR_GEN (0x10UL) #define CKM_DSA (0x11UL) #define CKM_DSA_SHA1 (0x12UL) #define CKM_DH_PKCS_KEY_PAIR_GEN (0x20UL) #define CKM_DH_PKCS_DERIVE (0x21UL) #define CKM_X9_42_DH_KEY_PAIR_GEN (0x30UL) #define CKM_X9_42_DH_DERIVE (0x31UL) #define CKM_X9_42_DH_HYBRID_DERIVE (0x32UL) #define CKM_X9_42_MQV_DERIVE (0x33UL) #define CKM_SHA256_RSA_PKCS (0x40UL) #define CKM_SHA384_RSA_PKCS (0x41UL) #define CKM_SHA512_RSA_PKCS (0x42UL) #define CKM_SHA256_RSA_PKCS_PSS (0x43UL) #define CKM_SHA384_RSA_PKCS_PSS (0x44UL) #define CKM_SHA512_RSA_PKCS_PSS (0x45UL) #define CKM_RC2_KEY_GEN (0x100UL) #define CKM_RC2_ECB (0x101UL) #define CKM_RC2_CBC (0x102UL) #define CKM_RC2_MAC (0x103UL) #define CKM_RC2_MAC_GENERAL (0x104UL) #define CKM_RC2_CBC_PAD (0x105UL) #define CKM_RC4_KEY_GEN (0x110UL) #define CKM_RC4 (0x111UL) #define CKM_DES_KEY_GEN (0x120UL) #define CKM_DES_ECB (0x121UL) #define CKM_DES_CBC (0x122UL) #define CKM_DES_MAC (0x123UL) #define CKM_DES_MAC_GENERAL (0x124UL) #define CKM_DES_CBC_PAD (0x125UL) #define CKM_DES2_KEY_GEN (0x130UL) #define CKM_DES3_KEY_GEN (0x131UL) #define CKM_DES3_ECB (0x132UL) #define CKM_DES3_CBC (0x133UL) #define CKM_DES3_MAC (0x134UL) #define CKM_DES3_MAC_GENERAL (0x135UL) #define CKM_DES3_CBC_PAD (0x136UL) #define CKM_CDMF_KEY_GEN (0x140UL) #define CKM_CDMF_ECB (0x141UL) #define CKM_CDMF_CBC (0x142UL) #define CKM_CDMF_MAC (0x143UL) #define CKM_CDMF_MAC_GENERAL (0x144UL) #define CKM_CDMF_CBC_PAD (0x145UL) #define CKM_MD2 (0x200UL) #define CKM_MD2_HMAC (0x201UL) #define CKM_MD2_HMAC_GENERAL (0x202UL) #define CKM_MD5 (0x210UL) #define CKM_MD5_HMAC (0x211UL) #define CKM_MD5_HMAC_GENERAL (0x212UL) #define CKM_SHA_1 (0x220UL) #define CKM_SHA_1_HMAC (0x221UL) #define CKM_SHA_1_HMAC_GENERAL (0x222UL) #define CKM_RIPEMD128 (0x230UL) #define CKM_RIPEMD128_HMAC (0x231UL) #define CKM_RIPEMD128_HMAC_GENERAL (0x232UL) #define CKM_RIPEMD160 (0x240UL) #define CKM_RIPEMD160_HMAC (0x241UL) #define CKM_RIPEMD160_HMAC_GENERAL (0x242UL) #define CKM_SHA256 (0x250UL) #define CKM_SHA256_HMAC (0x251UL) #define CKM_SHA256_HMAC_GENERAL (0x252UL) #define CKM_SHA384 (0x260UL) #define CKM_SHA384_HMAC (0x261UL) #define CKM_SHA384_HMAC_GENERAL (0x262UL) #define CKM_SHA512 (0x270UL) #define CKM_SHA512_HMAC (0x271UL) #define CKM_SHA512_HMAC_GENERAL (0x272UL) #define CKM_CAST_KEY_GEN (0x300UL) #define CKM_CAST_ECB (0x301UL) #define CKM_CAST_CBC (0x302UL) #define CKM_CAST_MAC (0x303UL) #define CKM_CAST_MAC_GENERAL (0x304UL) #define CKM_CAST_CBC_PAD (0x305UL) #define CKM_CAST3_KEY_GEN (0x310UL) #define CKM_CAST3_ECB (0x311UL) #define CKM_CAST3_CBC (0x312UL) #define CKM_CAST3_MAC (0x313UL) #define CKM_CAST3_MAC_GENERAL (0x314UL) #define CKM_CAST3_CBC_PAD (0x315UL) #define CKM_CAST5_KEY_GEN (0x320UL) #define CKM_CAST128_KEY_GEN (0x320UL) #define CKM_CAST5_ECB (0x321UL) #define CKM_CAST128_ECB (0x321UL) #define CKM_CAST5_CBC (0x322UL) #define CKM_CAST128_CBC (0x322UL) #define CKM_CAST5_MAC (0x323UL) #define CKM_CAST128_MAC (0x323UL) #define CKM_CAST5_MAC_GENERAL (0x324UL) #define CKM_CAST128_MAC_GENERAL (0x324UL) #define CKM_CAST5_CBC_PAD (0x325UL) #define CKM_CAST128_CBC_PAD (0x325UL) #define CKM_RC5_KEY_GEN (0x330UL) #define CKM_RC5_ECB (0x331UL) #define CKM_RC5_CBC (0x332UL) #define CKM_RC5_MAC (0x333UL) #define CKM_RC5_MAC_GENERAL (0x334UL) #define CKM_RC5_CBC_PAD (0x335UL) #define CKM_IDEA_KEY_GEN (0x340UL) #define CKM_IDEA_ECB (0x341UL) #define CKM_IDEA_CBC (0x342UL) #define CKM_IDEA_MAC (0x343UL) #define CKM_IDEA_MAC_GENERAL (0x344UL) #define CKM_IDEA_CBC_PAD (0x345UL) #define CKM_GENERIC_SECRET_KEY_GEN (0x350UL) #define CKM_CONCATENATE_BASE_AND_KEY (0x360UL) #define CKM_CONCATENATE_BASE_AND_DATA (0x362UL) #define CKM_CONCATENATE_DATA_AND_BASE (0x363UL) #define CKM_XOR_BASE_AND_DATA (0x364UL) #define CKM_EXTRACT_KEY_FROM_KEY (0x365UL) #define CKM_SSL3_PRE_MASTER_KEY_GEN (0x370UL) #define CKM_SSL3_MASTER_KEY_DERIVE (0x371UL) #define CKM_SSL3_KEY_AND_MAC_DERIVE (0x372UL) #define CKM_SSL3_MASTER_KEY_DERIVE_DH (0x373UL) #define CKM_TLS_PRE_MASTER_KEY_GEN (0x374UL) #define CKM_TLS_MASTER_KEY_DERIVE (0x375UL) #define CKM_TLS_KEY_AND_MAC_DERIVE (0x376UL) #define CKM_TLS_MASTER_KEY_DERIVE_DH (0x377UL) #define CKM_SSL3_MD5_MAC (0x380UL) #define CKM_SSL3_SHA1_MAC (0x381UL) #define CKM_MD5_KEY_DERIVATION (0x390UL) #define CKM_MD2_KEY_DERIVATION (0x391UL) #define CKM_SHA1_KEY_DERIVATION (0x392UL) #define CKM_PBE_MD2_DES_CBC (0x3a0UL) #define CKM_PBE_MD5_DES_CBC (0x3a1UL) #define CKM_PBE_MD5_CAST_CBC (0x3a2UL) #define CKM_PBE_MD5_CAST3_CBC (0x3a3UL) #define CKM_PBE_MD5_CAST5_CBC (0x3a4UL) #define CKM_PBE_MD5_CAST128_CBC (0x3a4UL) #define CKM_PBE_SHA1_CAST5_CBC (0x3a5UL) #define CKM_PBE_SHA1_CAST128_CBC (0x3a5UL) #define CKM_PBE_SHA1_RC4_128 (0x3a6UL) #define CKM_PBE_SHA1_RC4_40 (0x3a7UL) #define CKM_PBE_SHA1_DES3_EDE_CBC (0x3a8UL) #define CKM_PBE_SHA1_DES2_EDE_CBC (0x3a9UL) #define CKM_PBE_SHA1_RC2_128_CBC (0x3aaUL) #define CKM_PBE_SHA1_RC2_40_CBC (0x3abUL) #define CKM_PKCS5_PBKD2 (0x3b0UL) #define CKM_PBA_SHA1_WITH_SHA1_HMAC (0x3c0UL) #define CKM_KEY_WRAP_LYNKS (0x400UL) #define CKM_KEY_WRAP_SET_OAEP (0x401UL) #define CKM_SKIPJACK_KEY_GEN (0x1000UL) #define CKM_SKIPJACK_ECB64 (0x1001UL) #define CKM_SKIPJACK_CBC64 (0x1002UL) #define CKM_SKIPJACK_OFB64 (0x1003UL) #define CKM_SKIPJACK_CFB64 (0x1004UL) #define CKM_SKIPJACK_CFB32 (0x1005UL) #define CKM_SKIPJACK_CFB16 (0x1006UL) #define CKM_SKIPJACK_CFB8 (0x1007UL) #define CKM_SKIPJACK_WRAP (0x1008UL) #define CKM_SKIPJACK_PRIVATE_WRAP (0x1009UL) #define CKM_SKIPJACK_RELAYX (0x100aUL) #define CKM_KEA_KEY_PAIR_GEN (0x1010UL) #define CKM_KEA_KEY_DERIVE (0x1011UL) #define CKM_FORTEZZA_TIMESTAMP (0x1020UL) #define CKM_BATON_KEY_GEN (0x1030UL) #define CKM_BATON_ECB128 (0x1031UL) #define CKM_BATON_ECB96 (0x1032UL) #define CKM_BATON_CBC128 (0x1033UL) #define CKM_BATON_COUNTER (0x1034UL) #define CKM_BATON_SHUFFLE (0x1035UL) #define CKM_BATON_WRAP (0x1036UL) #define CKM_ECDSA_KEY_PAIR_GEN (0x1040UL) #define CKM_EC_KEY_PAIR_GEN (0x1040UL) #define CKM_ECDSA (0x1041UL) #define CKM_ECDSA_SHA1 (0x1042UL) #define CKM_ECDH1_DERIVE (0x1050UL) #define CKM_ECDH1_COFACTOR_DERIVE (0x1051UL) #define CKM_ECMQV_DERIVE (0x1052UL) #define CKM_JUNIPER_KEY_GEN (0x1060UL) #define CKM_JUNIPER_ECB128 (0x1061UL) #define CKM_JUNIPER_CBC128 (0x1062UL) #define CKM_JUNIPER_COUNTER (0x1063UL) #define CKM_JUNIPER_SHUFFLE (0x1064UL) #define CKM_JUNIPER_WRAP (0x1065UL) #define CKM_FASTHASH (0x1070UL) #define CKM_AES_KEY_GEN (0x1080UL) #define CKM_AES_ECB (0x1081UL) #define CKM_AES_CBC (0x1082UL) #define CKM_AES_MAC (0x1083UL) #define CKM_AES_MAC_GENERAL (0x1084UL) #define CKM_AES_CBC_PAD (0x1085UL) #define CKM_GOSTR3410_KEY_PAIR_GEN (0x1200UL) #define CKM_GOSTR3410 (0x1201UL) #define CKM_GOSTR3410_WITH_GOSTR3411 (0x1202UL) #define CKM_GOSTR3411 (0x1210UL) #define CKM_DSA_PARAMETER_GEN (0x2000UL) #define CKM_DH_PKCS_PARAMETER_GEN (0x2001UL) #define CKM_X9_42_DH_PARAMETER_GEN (0x2002UL) #define CKM_VENDOR_DEFINED (1UL << 31) struct ck_mechanism { ck_mechanism_type_t mechanism; void *parameter; unsigned long parameter_len; }; struct ck_mechanism_info { unsigned long min_key_size; unsigned long max_key_size; ck_flags_t flags; }; #define CKF_HW (1UL << 0) #define CKF_ENCRYPT (1UL << 8) #define CKF_DECRYPT (1UL << 9) #define CKF_DIGEST (1UL << 10) #define CKF_SIGN (1UL << 11) #define CKF_SIGN_RECOVER (1UL << 12) #define CKF_VERIFY (1UL << 13) #define CKF_VERIFY_RECOVER (1UL << 14) #define CKF_GENERATE (1UL << 15) #define CKF_GENERATE_KEY_PAIR (1UL << 16) #define CKF_WRAP (1UL << 17) #define CKF_UNWRAP (1UL << 18) #define CKF_DERIVE (1UL << 19) #define CKF_EXTENSION (1UL << 31) /* Flags for C_WaitForSlotEvent. */ #define CKF_DONT_BLOCK (1UL) typedef unsigned long ck_rv_t; typedef ck_rv_t (*ck_notify_t) (ck_session_handle_t session, ck_notification_t event, void *application); /* Forward reference. */ struct ck_function_list; #define _CK_DECLARE_FUNCTION(name, args) \ typedef ck_rv_t (*CK_ ## name) args; \ ck_rv_t CK_SPEC name args _CK_DECLARE_FUNCTION (C_Initialize, (void *init_args)); _CK_DECLARE_FUNCTION (C_Finalize, (void *reserved)); _CK_DECLARE_FUNCTION (C_GetInfo, (struct ck_info *info)); _CK_DECLARE_FUNCTION (C_GetFunctionList, (struct ck_function_list **function_list)); _CK_DECLARE_FUNCTION (C_GetSlotList, (unsigned char token_present, ck_slot_id_t *slot_list, unsigned long *count)); _CK_DECLARE_FUNCTION (C_GetSlotInfo, (ck_slot_id_t slot_id, struct ck_slot_info *info)); _CK_DECLARE_FUNCTION (C_GetTokenInfo, (ck_slot_id_t slot_id, struct ck_token_info *info)); _CK_DECLARE_FUNCTION (C_WaitForSlotEvent, (ck_flags_t flags, ck_slot_id_t *slot, void *reserved)); _CK_DECLARE_FUNCTION (C_GetMechanismList, (ck_slot_id_t slot_id, ck_mechanism_type_t *mechanism_list, unsigned long *count)); _CK_DECLARE_FUNCTION (C_GetMechanismInfo, (ck_slot_id_t slot_id, ck_mechanism_type_t type, struct ck_mechanism_info *info)); _CK_DECLARE_FUNCTION (C_InitToken, (ck_slot_id_t slot_id, unsigned char *pin, unsigned long pin_len, unsigned char *label)); _CK_DECLARE_FUNCTION (C_InitPIN, (ck_session_handle_t session, unsigned char *pin, unsigned long pin_len)); _CK_DECLARE_FUNCTION (C_SetPIN, (ck_session_handle_t session, unsigned char *old_pin, unsigned long old_len, unsigned char *new_pin, unsigned long new_len)); _CK_DECLARE_FUNCTION (C_OpenSession, (ck_slot_id_t slot_id, ck_flags_t flags, void *application, ck_notify_t notify, ck_session_handle_t *session)); _CK_DECLARE_FUNCTION (C_CloseSession, (ck_session_handle_t session)); _CK_DECLARE_FUNCTION (C_CloseAllSessions, (ck_slot_id_t slot_id)); _CK_DECLARE_FUNCTION (C_GetSessionInfo, (ck_session_handle_t session, struct ck_session_info *info)); _CK_DECLARE_FUNCTION (C_GetOperationState, (ck_session_handle_t session, unsigned char *operation_state, unsigned long *operation_state_len)); _CK_DECLARE_FUNCTION (C_SetOperationState, (ck_session_handle_t session, unsigned char *operation_state, unsigned long operation_state_len, ck_object_handle_t encryption_key, ck_object_handle_t authentiation_key)); _CK_DECLARE_FUNCTION (C_Login, (ck_session_handle_t session, ck_user_type_t user_type, unsigned char *pin, unsigned long pin_len)); _CK_DECLARE_FUNCTION (C_Logout, (ck_session_handle_t session)); _CK_DECLARE_FUNCTION (C_CreateObject, (ck_session_handle_t session, struct ck_attribute *templ, unsigned long count, ck_object_handle_t *object)); _CK_DECLARE_FUNCTION (C_CopyObject, (ck_session_handle_t session, ck_object_handle_t object, struct ck_attribute *templ, unsigned long count, ck_object_handle_t *new_object)); _CK_DECLARE_FUNCTION (C_DestroyObject, (ck_session_handle_t session, ck_object_handle_t object)); _CK_DECLARE_FUNCTION (C_GetObjectSize, (ck_session_handle_t session, ck_object_handle_t object, unsigned long *size)); _CK_DECLARE_FUNCTION (C_GetAttributeValue, (ck_session_handle_t session, ck_object_handle_t object, struct ck_attribute *templ, unsigned long count)); _CK_DECLARE_FUNCTION (C_SetAttributeValue, (ck_session_handle_t session, ck_object_handle_t object, struct ck_attribute *templ, unsigned long count)); _CK_DECLARE_FUNCTION (C_FindObjectsInit, (ck_session_handle_t session, struct ck_attribute *templ, unsigned long count)); _CK_DECLARE_FUNCTION (C_FindObjects, (ck_session_handle_t session, ck_object_handle_t *object, unsigned long max_object_count, unsigned long *object_count)); _CK_DECLARE_FUNCTION (C_FindObjectsFinal, (ck_session_handle_t session)); _CK_DECLARE_FUNCTION (C_EncryptInit, (ck_session_handle_t session, struct ck_mechanism *mechanism, ck_object_handle_t key)); _CK_DECLARE_FUNCTION (C_Encrypt, (ck_session_handle_t session, unsigned char *data, unsigned long data_len, unsigned char *encrypted_data, unsigned long *encrypted_data_len)); _CK_DECLARE_FUNCTION (C_EncryptUpdate, (ck_session_handle_t session, unsigned char *part, unsigned long part_len, unsigned char *encrypted_part, unsigned long *encrypted_part_len)); _CK_DECLARE_FUNCTION (C_EncryptFinal, (ck_session_handle_t session, unsigned char *last_encrypted_part, unsigned long *last_encrypted_part_len)); _CK_DECLARE_FUNCTION (C_DecryptInit, (ck_session_handle_t session, struct ck_mechanism *mechanism, ck_object_handle_t key)); _CK_DECLARE_FUNCTION (C_Decrypt, (ck_session_handle_t session, unsigned char *encrypted_data, unsigned long encrypted_data_len, unsigned char *data, unsigned long *data_len)); _CK_DECLARE_FUNCTION (C_DecryptUpdate, (ck_session_handle_t session, unsigned char *encrypted_part, unsigned long encrypted_part_len, unsigned char *part, unsigned long *part_len)); _CK_DECLARE_FUNCTION (C_DecryptFinal, (ck_session_handle_t session, unsigned char *last_part, unsigned long *last_part_len)); _CK_DECLARE_FUNCTION (C_DigestInit, (ck_session_handle_t session, struct ck_mechanism *mechanism)); _CK_DECLARE_FUNCTION (C_Digest, (ck_session_handle_t session, unsigned char *data, unsigned long data_len, unsigned char *digest, unsigned long *digest_len)); _CK_DECLARE_FUNCTION (C_DigestUpdate, (ck_session_handle_t session, unsigned char *part, unsigned long part_len)); _CK_DECLARE_FUNCTION (C_DigestKey, (ck_session_handle_t session, ck_object_handle_t key)); _CK_DECLARE_FUNCTION (C_DigestFinal, (ck_session_handle_t session, unsigned char *digest, unsigned long *digest_len)); _CK_DECLARE_FUNCTION (C_SignInit, (ck_session_handle_t session, struct ck_mechanism *mechanism, ck_object_handle_t key)); _CK_DECLARE_FUNCTION (C_Sign, (ck_session_handle_t session, unsigned char *data, unsigned long data_len, unsigned char *signature, unsigned long *signature_len)); _CK_DECLARE_FUNCTION (C_SignUpdate, (ck_session_handle_t session, unsigned char *part, unsigned long part_len)); _CK_DECLARE_FUNCTION (C_SignFinal, (ck_session_handle_t session, unsigned char *signature, unsigned long *signature_len)); _CK_DECLARE_FUNCTION (C_SignRecoverInit, (ck_session_handle_t session, struct ck_mechanism *mechanism, ck_object_handle_t key)); _CK_DECLARE_FUNCTION (C_SignRecover, (ck_session_handle_t session, unsigned char *data, unsigned long data_len, unsigned char *signature, unsigned long *signature_len)); _CK_DECLARE_FUNCTION (C_VerifyInit, (ck_session_handle_t session, struct ck_mechanism *mechanism, ck_object_handle_t key)); _CK_DECLARE_FUNCTION (C_Verify, (ck_session_handle_t session, unsigned char *data, unsigned long data_len, unsigned char *signature, unsigned long signature_len)); _CK_DECLARE_FUNCTION (C_VerifyUpdate, (ck_session_handle_t session, unsigned char *part, unsigned long part_len)); _CK_DECLARE_FUNCTION (C_VerifyFinal, (ck_session_handle_t session, unsigned char *signature, unsigned long signature_len)); _CK_DECLARE_FUNCTION (C_VerifyRecoverInit, (ck_session_handle_t session, struct ck_mechanism *mechanism, ck_object_handle_t key)); _CK_DECLARE_FUNCTION (C_VerifyRecover, (ck_session_handle_t session, unsigned char *signature, unsigned long signature_len, unsigned char *data, unsigned long *data_len)); _CK_DECLARE_FUNCTION (C_DigestEncryptUpdate, (ck_session_handle_t session, unsigned char *part, unsigned long part_len, unsigned char *encrypted_part, unsigned long *encrypted_part_len)); _CK_DECLARE_FUNCTION (C_DecryptDigestUpdate, (ck_session_handle_t session, unsigned char *encrypted_part, unsigned long encrypted_part_len, unsigned char *part, unsigned long *part_len)); _CK_DECLARE_FUNCTION (C_SignEncryptUpdate, (ck_session_handle_t session, unsigned char *part, unsigned long part_len, unsigned char *encrypted_part, unsigned long *encrypted_part_len)); _CK_DECLARE_FUNCTION (C_DecryptVerifyUpdate, (ck_session_handle_t session, unsigned char *encrypted_part, unsigned long encrypted_part_len, unsigned char *part, unsigned long *part_len)); _CK_DECLARE_FUNCTION (C_GenerateKey, (ck_session_handle_t session, struct ck_mechanism *mechanism, struct ck_attribute *templ, unsigned long count, ck_object_handle_t *key)); _CK_DECLARE_FUNCTION (C_GenerateKeyPair, (ck_session_handle_t session, struct ck_mechanism *mechanism, struct ck_attribute *public_key_template, unsigned long public_key_attribute_count, struct ck_attribute *private_key_template, unsigned long private_key_attribute_count, ck_object_handle_t *public_key, ck_object_handle_t *private_key)); _CK_DECLARE_FUNCTION (C_WrapKey, (ck_session_handle_t session, struct ck_mechanism *mechanism, ck_object_handle_t wrapping_key, ck_object_handle_t key, unsigned char *wrapped_key, unsigned long *wrapped_key_len)); _CK_DECLARE_FUNCTION (C_UnwrapKey, (ck_session_handle_t session, struct ck_mechanism *mechanism, ck_object_handle_t unwrapping_key, unsigned char *wrapped_key, unsigned long wrapped_key_len, struct ck_attribute *templ, unsigned long attribute_count, ck_object_handle_t *key)); _CK_DECLARE_FUNCTION (C_DeriveKey, (ck_session_handle_t session, struct ck_mechanism *mechanism, ck_object_handle_t base_key, struct ck_attribute *templ, unsigned long attribute_count, ck_object_handle_t *key)); _CK_DECLARE_FUNCTION (C_SeedRandom, (ck_session_handle_t session, unsigned char *seed, unsigned long seed_len)); _CK_DECLARE_FUNCTION (C_GenerateRandom, (ck_session_handle_t session, unsigned char *random_data, unsigned long random_len)); _CK_DECLARE_FUNCTION (C_GetFunctionStatus, (ck_session_handle_t session)); _CK_DECLARE_FUNCTION (C_CancelFunction, (ck_session_handle_t session)); struct ck_function_list { struct ck_version version; CK_C_Initialize C_Initialize; CK_C_Finalize C_Finalize; CK_C_GetInfo C_GetInfo; CK_C_GetFunctionList C_GetFunctionList; CK_C_GetSlotList C_GetSlotList; CK_C_GetSlotInfo C_GetSlotInfo; CK_C_GetTokenInfo C_GetTokenInfo; CK_C_GetMechanismList C_GetMechanismList; CK_C_GetMechanismInfo C_GetMechanismInfo; CK_C_InitToken C_InitToken; CK_C_InitPIN C_InitPIN; CK_C_SetPIN C_SetPIN; CK_C_OpenSession C_OpenSession; CK_C_CloseSession C_CloseSession; CK_C_CloseAllSessions C_CloseAllSessions; CK_C_GetSessionInfo C_GetSessionInfo; CK_C_GetOperationState C_GetOperationState; CK_C_SetOperationState C_SetOperationState; CK_C_Login C_Login; CK_C_Logout C_Logout; CK_C_CreateObject C_CreateObject; CK_C_CopyObject C_CopyObject; CK_C_DestroyObject C_DestroyObject; CK_C_GetObjectSize C_GetObjectSize; CK_C_GetAttributeValue C_GetAttributeValue; CK_C_SetAttributeValue C_SetAttributeValue; CK_C_FindObjectsInit C_FindObjectsInit; CK_C_FindObjects C_FindObjects; CK_C_FindObjectsFinal C_FindObjectsFinal; CK_C_EncryptInit C_EncryptInit; CK_C_Encrypt C_Encrypt; CK_C_EncryptUpdate C_EncryptUpdate; CK_C_EncryptFinal C_EncryptFinal; CK_C_DecryptInit C_DecryptInit; CK_C_Decrypt C_Decrypt; CK_C_DecryptUpdate C_DecryptUpdate; CK_C_DecryptFinal C_DecryptFinal; CK_C_DigestInit C_DigestInit; CK_C_Digest C_Digest; CK_C_DigestUpdate C_DigestUpdate; CK_C_DigestKey C_DigestKey; CK_C_DigestFinal C_DigestFinal; CK_C_SignInit C_SignInit; CK_C_Sign C_Sign; CK_C_SignUpdate C_SignUpdate; CK_C_SignFinal C_SignFinal; CK_C_SignRecoverInit C_SignRecoverInit; CK_C_SignRecover C_SignRecover; CK_C_VerifyInit C_VerifyInit; CK_C_Verify C_Verify; CK_C_VerifyUpdate C_VerifyUpdate; CK_C_VerifyFinal C_VerifyFinal; CK_C_VerifyRecoverInit C_VerifyRecoverInit; CK_C_VerifyRecover C_VerifyRecover; CK_C_DigestEncryptUpdate C_DigestEncryptUpdate; CK_C_DecryptDigestUpdate C_DecryptDigestUpdate; CK_C_SignEncryptUpdate C_SignEncryptUpdate; CK_C_DecryptVerifyUpdate C_DecryptVerifyUpdate; CK_C_GenerateKey C_GenerateKey; CK_C_GenerateKeyPair C_GenerateKeyPair; CK_C_WrapKey C_WrapKey; CK_C_UnwrapKey C_UnwrapKey; CK_C_DeriveKey C_DeriveKey; CK_C_SeedRandom C_SeedRandom; CK_C_GenerateRandom C_GenerateRandom; CK_C_GetFunctionStatus C_GetFunctionStatus; CK_C_CancelFunction C_CancelFunction; CK_C_WaitForSlotEvent C_WaitForSlotEvent; }; typedef ck_rv_t (*ck_createmutex_t) (void **mutex); typedef ck_rv_t (*ck_destroymutex_t) (void *mutex); typedef ck_rv_t (*ck_lockmutex_t) (void *mutex); typedef ck_rv_t (*ck_unlockmutex_t) (void *mutex); struct ck_c_initialize_args { ck_createmutex_t create_mutex; ck_destroymutex_t destroy_mutex; ck_lockmutex_t lock_mutex; ck_unlockmutex_t unlock_mutex; ck_flags_t flags; void *reserved; }; #define CKF_LIBRARY_CANT_CREATE_OS_THREADS (1UL << 0) #define CKF_OS_LOCKING_OK (1UL << 1) #define CKR_OK (0UL) #define CKR_CANCEL (1UL) #define CKR_HOST_MEMORY (2UL) #define CKR_SLOT_ID_INVALID (3UL) #define CKR_GENERAL_ERROR (5UL) #define CKR_FUNCTION_FAILED (6UL) #define CKR_ARGUMENTS_BAD (7UL) #define CKR_NO_EVENT (8UL) #define CKR_NEED_TO_CREATE_THREADS (9UL) #define CKR_CANT_LOCK (0xaUL) #define CKR_ATTRIBUTE_READ_ONLY (0x10UL) #define CKR_ATTRIBUTE_SENSITIVE (0x11UL) #define CKR_ATTRIBUTE_TYPE_INVALID (0x12UL) #define CKR_ATTRIBUTE_VALUE_INVALID (0x13UL) #define CKR_DATA_INVALID (0x20UL) #define CKR_DATA_LEN_RANGE (0x21UL) #define CKR_DEVICE_ERROR (0x30UL) #define CKR_DEVICE_MEMORY (0x31UL) #define CKR_DEVICE_REMOVED (0x32UL) #define CKR_ENCRYPTED_DATA_INVALID (0x40UL) #define CKR_ENCRYPTED_DATA_LEN_RANGE (0x41UL) #define CKR_FUNCTION_CANCELED (0x50UL) #define CKR_FUNCTION_NOT_PARALLEL (0x51UL) #define CKR_FUNCTION_NOT_SUPPORTED (0x54UL) #define CKR_KEY_HANDLE_INVALID (0x60UL) #define CKR_KEY_SIZE_RANGE (0x62UL) #define CKR_KEY_TYPE_INCONSISTENT (0x63UL) #define CKR_KEY_NOT_NEEDED (0x64UL) #define CKR_KEY_CHANGED (0x65UL) #define CKR_KEY_NEEDED (0x66UL) #define CKR_KEY_INDIGESTIBLE (0x67UL) #define CKR_KEY_FUNCTION_NOT_PERMITTED (0x68UL) #define CKR_KEY_NOT_WRAPPABLE (0x69UL) #define CKR_KEY_UNEXTRACTABLE (0x6aUL) #define CKR_MECHANISM_INVALID (0x70UL) #define CKR_MECHANISM_PARAM_INVALID (0x71UL) #define CKR_OBJECT_HANDLE_INVALID (0x82UL) #define CKR_OPERATION_ACTIVE (0x90UL) #define CKR_OPERATION_NOT_INITIALIZED (0x91UL) #define CKR_PIN_INCORRECT (0xa0UL) #define CKR_PIN_INVALID (0xa1UL) #define CKR_PIN_LEN_RANGE (0xa2UL) #define CKR_PIN_EXPIRED (0xa3UL) #define CKR_PIN_LOCKED (0xa4UL) #define CKR_SESSION_CLOSED (0xb0UL) #define CKR_SESSION_COUNT (0xb1UL) #define CKR_SESSION_HANDLE_INVALID (0xb3UL) #define CKR_SESSION_PARALLEL_NOT_SUPPORTED (0xb4UL) #define CKR_SESSION_READ_ONLY (0xb5UL) #define CKR_SESSION_EXISTS (0xb6UL) #define CKR_SESSION_READ_ONLY_EXISTS (0xb7UL) #define CKR_SESSION_READ_WRITE_SO_EXISTS (0xb8UL) #define CKR_SIGNATURE_INVALID (0xc0UL) #define CKR_SIGNATURE_LEN_RANGE (0xc1UL) #define CKR_TEMPLATE_INCOMPLETE (0xd0UL) #define CKR_TEMPLATE_INCONSISTENT (0xd1UL) #define CKR_TOKEN_NOT_PRESENT (0xe0UL) #define CKR_TOKEN_NOT_RECOGNIZED (0xe1UL) #define CKR_TOKEN_WRITE_PROTECTED (0xe2UL) #define CKR_UNWRAPPING_KEY_HANDLE_INVALID (0xf0UL) #define CKR_UNWRAPPING_KEY_SIZE_RANGE (0xf1UL) #define CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT (0xf2UL) #define CKR_USER_ALREADY_LOGGED_IN (0x100UL) #define CKR_USER_NOT_LOGGED_IN (0x101UL) #define CKR_USER_PIN_NOT_INITIALIZED (0x102UL) #define CKR_USER_TYPE_INVALID (0x103UL) #define CKR_USER_ANOTHER_ALREADY_LOGGED_IN (0x104UL) #define CKR_USER_TOO_MANY_TYPES (0x105UL) #define CKR_WRAPPED_KEY_INVALID (0x110UL) #define CKR_WRAPPED_KEY_LEN_RANGE (0x112UL) #define CKR_WRAPPING_KEY_HANDLE_INVALID (0x113UL) #define CKR_WRAPPING_KEY_SIZE_RANGE (0x114UL) #define CKR_WRAPPING_KEY_TYPE_INCONSISTENT (0x115UL) #define CKR_RANDOM_SEED_NOT_SUPPORTED (0x120UL) #define CKR_RANDOM_NO_RNG (0x121UL) #define CKR_DOMAIN_PARAMS_INVALID (0x130UL) #define CKR_BUFFER_TOO_SMALL (0x150UL) #define CKR_SAVED_STATE_INVALID (0x160UL) #define CKR_INFORMATION_SENSITIVE (0x170UL) #define CKR_STATE_UNSAVEABLE (0x180UL) #define CKR_CRYPTOKI_NOT_INITIALIZED (0x190UL) #define CKR_CRYPTOKI_ALREADY_INITIALIZED (0x191UL) #define CKR_MUTEX_BAD (0x1a0UL) #define CKR_MUTEX_NOT_LOCKED (0x1a1UL) #define CKR_FUNCTION_REJECTED (0x200UL) #define CKR_VENDOR_DEFINED (1UL << 31) /* Compatibility layer. */ #ifdef CRYPTOKI_COMPAT #undef CK_DEFINE_FUNCTION #define CK_DEFINE_FUNCTION(retval, name) retval CK_SPEC name /* For NULL. */ #include typedef unsigned char CK_BYTE; typedef unsigned char CK_CHAR; typedef unsigned char CK_UTF8CHAR; typedef unsigned char CK_BBOOL; typedef unsigned long int CK_ULONG; typedef long int CK_LONG; typedef CK_BYTE *CK_BYTE_PTR; typedef CK_CHAR *CK_CHAR_PTR; typedef CK_UTF8CHAR *CK_UTF8CHAR_PTR; typedef CK_ULONG *CK_ULONG_PTR; typedef void *CK_VOID_PTR; typedef void **CK_VOID_PTR_PTR; #define CK_FALSE 0 #define CK_TRUE 1 #ifndef CK_DISABLE_TRUE_FALSE #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif #endif typedef struct ck_version CK_VERSION; typedef struct ck_version *CK_VERSION_PTR; typedef struct ck_info CK_INFO; typedef struct ck_info *CK_INFO_PTR; typedef ck_slot_id_t *CK_SLOT_ID_PTR; typedef struct ck_slot_info CK_SLOT_INFO; typedef struct ck_slot_info *CK_SLOT_INFO_PTR; typedef struct ck_token_info CK_TOKEN_INFO; typedef struct ck_token_info *CK_TOKEN_INFO_PTR; typedef ck_session_handle_t *CK_SESSION_HANDLE_PTR; typedef struct ck_session_info CK_SESSION_INFO; typedef struct ck_session_info *CK_SESSION_INFO_PTR; typedef ck_object_handle_t *CK_OBJECT_HANDLE_PTR; typedef ck_object_class_t *CK_OBJECT_CLASS_PTR; typedef struct ck_attribute CK_ATTRIBUTE; typedef struct ck_attribute *CK_ATTRIBUTE_PTR; typedef struct ck_date CK_DATE; typedef struct ck_date *CK_DATE_PTR; typedef ck_mechanism_type_t *CK_MECHANISM_TYPE_PTR; typedef struct ck_mechanism CK_MECHANISM; typedef struct ck_mechanism *CK_MECHANISM_PTR; typedef struct ck_mechanism_info CK_MECHANISM_INFO; typedef struct ck_mechanism_info *CK_MECHANISM_INFO_PTR; typedef struct ck_function_list CK_FUNCTION_LIST; typedef struct ck_function_list *CK_FUNCTION_LIST_PTR; typedef struct ck_function_list **CK_FUNCTION_LIST_PTR_PTR; typedef struct ck_c_initialize_args CK_C_INITIALIZE_ARGS; typedef struct ck_c_initialize_args *CK_C_INITIALIZE_ARGS_PTR; #define NULL_PTR NULL /* Delete the helper macros defined at the top of the file. */ #undef ck_flags_t #undef ck_version #undef ck_info #undef cryptoki_version #undef manufacturer_id #undef library_description #undef library_version #undef ck_notification_t #undef ck_slot_id_t #undef ck_slot_info #undef slot_description #undef hardware_version #undef firmware_version #undef ck_token_info #undef serial_number #undef max_session_count #undef session_count #undef max_rw_session_count #undef rw_session_count #undef max_pin_len #undef min_pin_len #undef total_public_memory #undef free_public_memory #undef total_private_memory #undef free_private_memory #undef utc_time #undef ck_session_handle_t #undef ck_user_type_t #undef ck_state_t #undef ck_session_info #undef slot_id #undef device_error #undef ck_object_handle_t #undef ck_object_class_t #undef ck_hw_feature_type_t #undef ck_key_type_t #undef ck_certificate_type_t #undef ck_attribute_type_t #undef ck_attribute #undef value #undef value_len #undef ck_date #undef ck_mechanism_type_t #undef ck_mechanism #undef parameter #undef parameter_len #undef ck_mechanism_info #undef min_key_size #undef max_key_size #undef ck_rv_t #undef ck_notify_t #undef ck_function_list #undef ck_createmutex_t #undef ck_destroymutex_t #undef ck_lockmutex_t #undef ck_unlockmutex_t #undef ck_c_initialize_args #undef create_mutex #undef destroy_mutex #undef lock_mutex #undef unlock_mutex #undef reserved #endif /* CRYPTOKI_COMPAT */ /* System dependencies. */ #if defined(_WIN32) || defined(CRYPTOKI_FORCE_WIN32) #pragma pack(pop, cryptoki) #endif #if defined(__cplusplus) } #endif #endif /* PKCS11_H */ canl-c-3.0.0/src/proxy/scutils.h0000644000015500017500000001635713017332513016266 0ustar tomcat6jenkins/********************************************************************** scutils.h: Description: This header file used internally for smart card access via PKCS11 For windows we can dynamicly load, and so PKCS#11 support can allways be compiled, as we now have the RSA header files included from the PKCS#11 2.01 version **********************************************************************/ #ifndef VOMS_SCUTILS_H #define VOMS_SCUTILS_H /********************************************************************** Include header files **********************************************************************/ #include #include "openssl/ssl.h" #include "openssl/err.h" #include "openssl/bio.h" #include "openssl/pem.h" #include "openssl/x509.h" #include "openssl/stack.h" #include "openssl/evp.h" #include "openssl/rsa.h" #include "pkcs11.h" #ifdef USE_TYPEMAP #include "typemap.h" #endif /********************************************************************** Define constants **********************************************************************/ /* RSA PKCS#11 says local strings donot include the null, * but examples do. Litronics writes the null in their labels * and expect them when formating. * The following will be added when writing a label or * other local string which might have this problem. * If other cards dont require, or this gets fixed, * set this to 0 * * This was with Litronic before NetSign 2.0 * * We have added code to try with and without the null, * So set this to 0 for now. */ #define HACK_PKCS11_LOCAL_STRING_NULL 0 /* * We need to store the session and object handles with the key. * In order to avoid changes to SSLeay, for the RSA structire, * we will use two of the ex_data fields, by grabing 3 and 4. * This may be a problem in future versions. * These are used by the _get_ key routines when creating * the key structure below, and by the sc_RSA_eay routines when * they go to use the key. */ #define SC_RSA_EX_DATA_INDEX_SESSION 3 #define SC_RSA_EX_DATA_INDEX_OBJECT 4 /* Location where the SCERR library will be stored */ #define ERR_USER_LIB_SCERR_NUMBER ((ERR_LIB_USER) + 1) /* * Use the SSLeay error facility with the ERR_LIB_USER */ #define SCerr(f,r) ERR_PUT_error(ERR_USER_LIB_SCERR_NUMBER,(f),(r),__FILE__,__LINE__) /* * defines for function codes our minor error codes */ #define SCERR_F_RSA_ENCRYPT 100 #define SCERR_F_RSA_DECRYPT 101 #define SCERR_F_SCINIT 102 #define SCERR_F_CREATE_DATA_OBJ 103 #define SCERR_F_CREATE_CERT_OBJ 104 #define SCERR_F_CREATE_RSA_PRIV_KEY_OBJ 105 #define SCERR_F_CREATE_PRIV_KEY_OBJ 106 #define SCERR_F_GET_RSA_PRIV_KEY_OBJ 107 #define SCERR_F_GET_PRIV_KEY_OBJ 108 #define SCERR_F_GET_PRIV_KEY_BY_LABEL 109 #define SCERR_F_GET_CERT_OBJ 110 #define SCERR_F_FIND_ONE_OBJ 111 #define SCERR_F_FIND_CERT_BY_LABEL 112 #define SCERR_F_LOAD_DLL 113 /* * defines for reasons */ #define SCERR_R_BASE 1500 #define SCERR_R_PKCS11_ERROR SCERR_R_BASE + 1 #define SCERR_R_SIGNINIT SCERR_R_BASE + 2 #define SCERR_R_SIGN SCERR_R_BASE + 3 #define SCERR_R_SIGNRECINIT SCERR_R_BASE + 4 #define SCERR_R_SIGNREC SCERR_R_BASE + 5 #define SCERR_R_INITIALIZE SCERR_R_BASE + 6 #define SCERR_R_GETSLOTLIST SCERR_R_BASE + 7 #define SCERR_R_OPENSESSION SCERR_R_BASE + 8 #define SCERR_R_LOGIN SCERR_R_BASE + 9 #define SCERR_R_CREATEOBJ SCERR_R_BASE + 10 #define SCERR_R_UNSUPPORTED SCERR_R_BASE + 11 #define SCERR_R_GETATTRVAL SCERR_R_BASE + 12 #define SCERR_R_FINDOBJINIT SCERR_R_BASE + 13 #define SCERR_R_FINDOBJ SCERR_R_BASE + 14 #define SCERR_R_FOUNDMANY SCERR_R_BASE + 15 #define SCERR_R_BAD_CERT_OBJ SCERR_R_BASE + 16 #define SCERR_R_FIND_FAILED SCERR_R_BASE + 17 #define SCERR_R_NO_PKCS11_DLL SCERR_R_BASE + 18 /* NOTE: Reason codes are limited to <4096 by openssl error handler */ /********************************************************************** Type definitions **********************************************************************/ /********************************************************************** Global variables *********************************************************************/ /* The pFunctionList is a pointer to the PKCS11 list * of functions which is in the lib or DLL. * It is initialized once on the first call to the * sc_init() by sc_get_funct_list() */ extern CK_FUNCTION_LIST_PTR pFunctionList; /********************************************************************** Function prototypes **********************************************************************/ int ERR_load_scerr_strings(int i); char * sc_ERR_code(CK_RV status); CK_FUNCTION_LIST_PTR sc_get_function_list(); int sc_init(CK_SESSION_HANDLE_PTR PsessionHandle, char *card, CK_SLOT_ID_PTR pslot, char * ppin, CK_USER_TYPE userType, int initialized); int sc_init_one(CK_SLOT_ID_PTR pslot); int sc_init_info(CK_SLOT_ID_PTR pslot, CK_TOKEN_INFO_PTR ptokenInfo); int sc_init_open_login(CK_SESSION_HANDLE_PTR PsessionHandle, CK_SLOT_ID_PTR pslot, char * ppin, CK_USER_TYPE userType); int sc_final(CK_SESSION_HANDLE sessionHandle); int sc_create_data_obj(CK_SESSION_HANDLE sessionHandle, char *mylabel, char *myvalue, int mylen); int sc_create_rsa_priv_key_obj(CK_SESSION_HANDLE sessionHandle, char *mylabel, RSA *rkey); int sc_create_priv_key_obj(CK_SESSION_HANDLE sessionHandle, char *mylabel, EVP_PKEY *key); int sc_create_cert_obj(CK_SESSION_HANDLE sessionHandle, char *mylabel, X509 *ucert); /**********************/ int sc_get_rsa_priv_key_obj(CK_SESSION_HANDLE sessionHandle, CK_OBJECT_HANDLE hPrivKey, RSA ** nrkey); int sc_get_priv_key_obj(CK_SESSION_HANDLE sessionHandle, CK_OBJECT_HANDLE hPrivKey, EVP_PKEY ** nkey); int sc_get_priv_key_obj_by_label(CK_SESSION_HANDLE sessionHandle, char *mylabel, EVP_PKEY ** nkey); int sc_get_cert_obj_by_label(CK_SESSION_HANDLE sessionHandle, char *mylabel, X509 ** ncert); int sc_find_one_obj(CK_SESSION_HANDLE sessionHandle, CK_ATTRIBUTE_PTR template, int ai, CK_OBJECT_HANDLE_PTR phObject); int sc_find_priv_key_obj_by_label(CK_SESSION_HANDLE sessionHandle, char * mylabel, CK_OBJECT_HANDLE_PTR phPrivKey); int sc_find_cert_obj_by_label(CK_SESSION_HANDLE hSession, char * mylabel, CK_OBJECT_HANDLE_PTR phCert); int sc_find_cert_obj_by_subject(CK_SESSION_HANDLE hSession, X509_NAME * x509name, CK_OBJECT_HANDLE_PTR phCert); /************************************************************************/ /* replacement RSA_PKCS1_SSLeay routines which will use the key on the */ /* smart card We have our own method which will call PKCS11 */ /* These are in sc_rsa_ssleay.c */ /************************************************************************/ RSA_METHOD * sc_RSA_PKCS1_SSLeay(); #endif /* _SCUTILS_H */ canl-c-3.0.0/src/proxy/sslutils.h0000644000015500017500000005134113017332513016452 0ustar tomcat6jenkins/********************************************************************* * * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it * Valerio Venturi - Valerio.Venturi@cnaf.infn.it * * Copyright (c) Members of the EGEE Collaboration. 2004-2010. * See http://www.eu-egee.org/partners/ for details on the copyright holders. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Parts of this code may be based upon or even include verbatim pieces, * originally written by other people, in which case the original header * follows. * *********************************************************************/ /********************************************************************** sslutils.h: Description: This header file used internally by the gssapi_ssleay routines **********************************************************************/ #ifndef VOMS_SSLUTILS_H #define VOMS_SSLUTILS_H #ifndef EXTERN_C_BEGIN #ifdef __cplusplus #define EXTERN_C_BEGIN extern "C" { #define EXTERN_C_END } #else #define EXTERN_C_BEGIN #define EXTERN_C_END #endif #endif EXTERN_C_BEGIN /********************************************************************** Include header files **********************************************************************/ //#include "config.h" #include #include #include #include #include #include "openssl/crypto.h" //canl headers #include "canl_ocsp.h" #include "canl_ssl.h" #if defined(__GNUC__) #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) #define UNUSED(z) z __attribute__ ((unused)) #else #define UNUSED(z) z #endif #define PRIVATE __attribute__ ((visibility ("hidden"))) #define PUBLIC __attribute__ ((visibility ("default"))) #else #define UNUSED(z) z #define PRIVATE #define PUBLIC #endif #if SSLEAY_VERSION_NUMBER < 0x0090581fL #define RAND_add(a,b,c) RAND_seed(a,b) #define RAND_status() 1 #endif #if SSLEAY_VERSION_NUMBER >= 0x00904100L /* Support both OpenSSL 0.9.4 and SSLeay 0.9.0 */ #define OPENSSL_PEM_CB(A,B) A, B #else #define RAND_add(a,b,c) RAND_seed(a,b) #define OPENSSL_PEM_CB(A,B) A #define STACK_OF(A) STACK #define sk_X509_num sk_num #define sk_X509_value (X509 *)sk_value #define sk_X509_push(A, B) sk_push(A, (char *) B) #define sk_X509_insert(A,B,C) sk_insert(A, (char *) B, C) #define sk_X509_delete sk_delete #define sk_X509_new_null sk_new_null #define sk_X509_pop_free sk_pop_free #define sk_X509_NAME_ENTRY_num sk_num #define sk_X509_NAME_ENTRY_value (X509_NAME_ENTRY *)sk_value #define sk_SSL_CIPHER_num sk_num #define sk_SSL_CIPHER_value (SSL_CIPHER*)sk_value #define sk_SSL_CIPHER_insert(A,B,C) sk_insert(A, (char *) B, C) #define sk_SSL_CIPHER_delete sk_delete #define sk_SSL_CIPHER_push(A, B) sk_push(A, (char *) B) #define sk_SSL_CIPHER_shift(A) sk_shift(A) #define sk_SSL_CIPHER_dup(A) sk_dup(A) #define sk_SSL_CIPHER_unshift(A, B) sk_unshift(A, (char *) B) #define sk_SSL_CIPHER_pop(A) sk_pop(A) #define sk_SSL_CIPHER_delete_ptr(A, B) sk_delete_ptr(A, B) #define sk_X509_EXTENSION_num sk_num #define sk_X509_EXTENSION_value (X509_EXTENSION *)sk_value #define sk_X509_EXTENSION_push(A, B) sk_push(A, (char *) B) #define sk_X509_EXTENSION_new_null sk_new_null #define sk_X509_EXTENSION_pop_free sk_pop_free #define sk_X509_REVOKED_num sk_num #define sk_X509_REVOKED_value (X509_REVOKED*)sk_value #endif #include "openssl/ssl.h" #include "openssl/err.h" #include "openssl/bio.h" #include "openssl/pem.h" #include "openssl/x509.h" #include "openssl/stack.h" /********************************************************************** Define constants **********************************************************************/ #define X509_CERT_DIR "X509_CERT_DIR" #define X509_CERT_FILE "X509_CERT_FILE" #define X509_USER_PROXY "X509_USER_PROXY" #define X509_USER_CERT "X509_USER_CERT" #define X509_USER_KEY "X509_USER_KEY" #define X509_USER_DELEG_PROXY "X509_USER_DELEG_PROXY" #define X509_USER_DELEG_FILE "x509up_p" #define X509_USER_PROXY_FILE "x509up_u" /* This is added after the CA name hash to make the policy filename */ #define SIGNING_POLICY_FILE_EXTENSION ".signing_policy" #ifdef WIN32 #define GSI_REGISTRY_DIR "software\\Globus\\GSI" #define X509_DEFAULT_CERT_DIR ".globus\\certificates" #define X509_DEFAULT_USER_CERT ".globus\\usercert.pem" #define X509_DEFAULT_USER_CERT_P12 ".globus\\usercert.p12" #define X509_DEFAULT_USER_CERT_P12_GT ".globus\\usercred.p12" #define X509_DEFAULT_USER_KEY ".globus\\userkey.pem" #define X509_INSTALLED_CERT_DIR "share\\certificates" #define X509_INSTALLED_HOST_CERT_DIR "NEEDS_TO_BE_DETERMINED" #define X509_DEFAULT_HOST_CERT "NEEDS_TO_BE_DETERMINED" #define X509_DEFAULT_HOST_KEY "NEEDS_TO_BE_DETERMINED" #else #define X509_DEFAULT_CERT_DIR ".globus/certificates" #define X509_DEFAULT_USER_CERT ".globus/usercert.pem" #define X509_DEFAULT_USER_CERT_P12 ".globus/usercert.p12" #define X509_DEFAULT_USER_CERT_P12_GT ".globus/usercred.p12" #define X509_DEFAULT_USER_KEY ".globus/userkey.pem" #define X509_INSTALLED_CERT_DIR "share/certificates" #define X509_INSTALLED_HOST_CERT_DIR "/etc/grid-security/certificates" #define X509_DEFAULT_HOST_CERT "/etc/grid-security/hostcert.pem" #define X509_DEFAULT_HOST_KEY "/etc/grid-security/hostkey.pem" #endif /* * To allow the use of the proxy_verify_callback with * applications which already use the SSL_set_app_data, * we define here the index for use with the * SSL_set_ex_data. This is hardcoded today, but * if needed we could add ours at the highest available, * then look at all of them for the magic number. * To allow for recursive calls to proxy_verify_callback * when verifing a delegate cert_chain, we also have * PVD_STORE_EX_DATA_IDX */ #define PVD_SSL_EX_DATA_IDX 5 #define PVD_STORE_EX_DATA_IDX 6 #define PVD_MAGIC_NUMBER 22222 #define PVXD_MAGIC_NUMBER 33333 /* Used by ERR_set_continue_needed as a flag for error routines */ #define ERR_DISPLAY_CONTINUE_NEEDED 64 /* Location relative to ERR_LIB_USER where PRXYERR library will be stored */ #define ERR_USER_LIB_PRXYERR_NUMBER ERR_LIB_USER /* * Use the SSLeay error facility with the ERR_LIB_USER */ #define PRXYerr(f,r) ERR_PUT_error(ERR_USER_LIB_PRXYERR_NUMBER,(f),(r),__FILE__,__LINE__) /* * SSLeay 0.9.0 added the error_data feature. We may be running * with 0.8.1 which does not have it, if so, define a dummy * ERR_add_error_data and ERR_get_error_line_data */ #if SSLEAY_VERSION_NUMBER < 0x0900 void ERR_add_error_data( VAR_PLIST( int, num ) ); unsigned long ERR_get_error_line_data(char **file,int *line, char **data, int *flags); #endif void ERR_set_continue_needed(void); /* * defines for function codes our minor error codes * These match strings defined in gsserr.c. */ #define PRXYERR_F_BASE 100 #define PRXYERR_F_PROXY_GENREQ PRXYERR_F_BASE + 0 #define PRXYERR_F_PROXY_SIGN PRXYERR_F_BASE + 1 #define PRXYERR_F_VERIFY_CB PRXYERR_F_BASE + 2 #define PRXYERR_F_PROXY_LOAD PRXYERR_F_BASE + 3 #define PRXYERR_F_PROXY_TMP PRXYERR_F_BASE + 4 #define PRXYERR_F_INIT_CRED PRXYERR_F_BASE + 5 #define PRXYERR_F_LOCAL_CREATE PRXYERR_F_BASE + 6 #define PRXYERR_F_CB_NO_PW PRXYERR_F_BASE + 7 #define PRXYERR_F_GET_CA_SIGN_PATH PRXYERR_F_BASE + 8 #define PRXYERR_F_PROXY_SIGN_EXT PRXYERR_F_BASE + 9 #define PRXYERR_F_PROXY_CHECK_SUBJECT_NAME PRXYERR_F_BASE + 10 #define PRXYERR_F_PROXY_CONSTRUCT_NAME PRXYERR_F_BASE + 11 /* * defines for reasons * The match strings defined in gsserr.c * These are also used for the minor_status codes. * We want to make sure these don't overlap with the errors in * gssapi_ssleay.h. */ #define PRXYERR_R_BASE 1000 #define PRXYERR_R_PROCESS_PROXY_KEY PRXYERR_R_BASE + 1 #define PRXYERR_R_PROCESS_REQ PRXYERR_R_BASE + 2 #define PRXYERR_R_PROCESS_SIGN PRXYERR_R_BASE + 3 #define PRXYERR_R_MALFORM_REQ PRXYERR_R_BASE + 4 #define PRXYERR_R_SIG_VERIFY PRXYERR_R_BASE + 5 #define PRXYERR_R_SIG_BAD PRXYERR_R_BASE + 6 #define PRXYERR_R_PROCESS_PROXY PRXYERR_R_BASE + 7 #define PRXYERR_R_PROXY_NAME_BAD PRXYERR_R_BASE + 8 #define PRXYERR_R_PROCESS_SIGNC PRXYERR_R_BASE + 9 #define PRXYERR_R_BAD_PROXY_ISSUER PRXYERR_R_BASE + 10 #define PRXYERR_R_PROBLEM_PROXY_FILE PRXYERR_R_BASE + 11 #define PRXYERR_R_SIGN_NOT_CA PRXYERR_R_BASE + 12 #define PRXYERR_R_PROCESS_KEY PRXYERR_R_BASE + 13 #define PRXYERR_R_PROCESS_CERT PRXYERR_R_BASE + 14 #define PRXYERR_R_PROCESS_CERTS PRXYERR_R_BASE + 15 #define PRXYERR_R_NO_TRUSTED_CERTS PRXYERR_R_BASE + 16 #define PRXYERR_R_PROBLEM_KEY_FILE PRXYERR_R_BASE + 17 #define PRXYERR_R_USER_ZERO_LENGTH_KEY_FILE PRXYERR_R_BASE + 18 #define PRXYERR_R_SERVER_ZERO_LENGTH_KEY_FILE PRXYERR_R_BASE + 19 #define PRXYERR_R_ZERO_LENGTH_CERT_FILE PRXYERR_R_BASE + 20 #define PRXYERR_R_PROBLEM_USER_NOCERT_FILE PRXYERR_R_BASE + 21 #define PRXYERR_R_PROBLEM_SERVER_NOCERT_FILE PRXYERR_R_BASE + 22 #define PRXYERR_R_PROBLEM_USER_NOKEY_FILE PRXYERR_R_BASE + 23 #define PRXYERR_R_PROBLEM_SERVER_NOKEY_FILE PRXYERR_R_BASE + 24 #define PRXYERR_R_USER_CERT_EXPIRED PRXYERR_R_BASE + 25 #define PRXYERR_R_SERVER_CERT_EXPIRED PRXYERR_R_BASE + 26 #define PRXYERR_R_CRL_SIGNATURE_FAILURE PRXYERR_R_BASE + 27 #define PRXYERR_R_CRL_NEXT_UPDATE_FIELD PRXYERR_R_BASE + 28 #define PRXYERR_R_CRL_HAS_EXPIRED PRXYERR_R_BASE + 29 #define PRXYERR_R_CERT_REVOKED PRXYERR_R_BASE + 30 #define PRXYERR_R_NO_HOME PRXYERR_R_BASE + 31 #define PRXYERR_R_LPROXY_MISSED_USED PRXYERR_R_BASE + 32 #define PRXYERR_R_LPROXY_REJECTED PRXYERR_R_BASE + 33 #define PRXYERR_R_KEY_CERT_MISMATCH PRXYERR_R_BASE + 34 #define PRXYERR_R_WRONG_PASSPHRASE PRXYERR_R_BASE + 35 #define PRXYERR_R_CA_POLICY_VIOLATION PRXYERR_R_BASE + 36 #define PRXYERR_R_CA_POLICY_RETRIEVE PRXYERR_R_BASE + 37 #define PRXYERR_R_CA_POLICY_PARSE PRXYERR_R_BASE + 38 #define PRXYERR_R_PROBLEM_CLIENT_CA PRXYERR_R_BASE + 39 #define PRXYERR_R_CB_NO_PW PRXYERR_R_BASE + 40 #define PRXYERR_R_CB_CALLED_WITH_ERROR PRXYERR_R_BASE + 41 #define PRXYERR_R_CB_ERROR_MSG PRXYERR_R_BASE + 42 #define PRXYERR_R_CLASS_ADD_OID PRXYERR_R_BASE + 43 #define PRXYERR_R_CLASS_ADD_EXT PRXYERR_R_BASE + 44 #define PRXYERR_R_DELEGATE_VERIFY PRXYERR_R_BASE + 45 #define PRXYERR_R_EXT_ADD PRXYERR_R_BASE + 46 #define PRXYERR_R_DELEGATE_COPY PRXYERR_R_BASE + 47 #define PRXYERR_R_DELEGATE_CREATE PRXYERR_R_BASE + 48 #define PRXYERR_R_BUFFER_TOO_SMALL PRXYERR_R_BASE + 49 #define PRXYERR_R_PROXY_EXPIRED PRXYERR_R_BASE + 50 #define PRXYERR_R_NO_PROXY PRXYERR_R_BASE + 51 #define PRXYERR_R_CA_UNKNOWN PRXYERR_R_BASE + 52 #define PRXYERR_R_CA_NOPATH PRXYERR_R_BASE + 53 #define PRXYERR_R_CA_NOFILE PRXYERR_R_BASE + 54 #define PRXYERR_R_CA_POLICY_ERR PRXYERR_R_BASE + 55 #define PRXYERR_R_INVALID_CERT PRXYERR_R_BASE + 56 #define PRXYERR_R_CERT_NOT_YET_VALID PRXYERR_R_BASE + 57 #define PRXYERR_R_LOCAL_CA_UNKNOWN PRXYERR_R_BASE + 58 #define PRXYERR_R_REMOTE_CRED_EXPIRED PRXYERR_R_BASE + 59 #define PRXYERR_R_OUT_OF_MEMORY PRXYERR_R_BASE + 60 #define PRXYERR_R_BAD_ARGUMENT PRXYERR_R_BASE + 61 #define PRXYERR_R_BAD_MAGIC PRXYERR_R_BASE + 62 #define PRXYERR_R_UNKNOWN_CRIT_EXT PRXYERR_R_BASE + 63 /* NOTE: Don't go over 1500 here or will conflict with errors in scutils.h */ /********************************************************************** Type definitions **********************************************************************/ /* canl_proxy_verify_ctx_desc - common to all verifys */ typedef struct canl_proxy_verify_ctx_desc_struct { int magicnum ; char * certdir; time_t goodtill; unsigned int flags; //OCSP flags etc. char * ocsp_url; } canl_proxy_verify_ctx_desc ; /* canl_proxy_verify_desc - allows for recursive verifys with delegation */ typedef struct canl_proxy_verify_desc_struct canl_proxy_verify_desc; struct canl_proxy_verify_desc_struct { int magicnum; canl_proxy_verify_desc * previous; canl_proxy_verify_ctx_desc * pvxd; int flags; X509_STORE_CTX * cert_store; int recursive_depth; int proxy_depth; int cert_depth; int limited_proxy; STACK_OF(X509) * cert_chain; /* X509 */ int multiple_limited_proxy_ok; }; typedef enum { NONE = 0, CA = 1, EEC = 2, GT2_PROXY = 4, RFC_PROXY = 8, GT2_LIMITED_PROXY = 16, RFC_LIMITED_PROXY = 32, GT3_PROXY = 64, GT3_LIMITED_PROXY = 128 } lcmaps_proxy_type_t; struct PROXYPOLICY_st { ASN1_OBJECT * policy_language; ASN1_OCTET_STRING * policy; }; typedef struct PROXYPOLICY_st PROXYPOLICY; struct PROXYCERTINFO_st { ASN1_INTEGER * path_length; /* [ OPTIONAL ] */ PROXYPOLICY * policy; }; typedef struct PROXYCERTINFO_st PROXYCERTINFO; #define PROXYCERTINFO_OID "1.3.6.1.5.5.7.1.14" #define OLD_PROXYCERTINFO_OID "1.3.6.1.4.1.3536.1.222" #define OID_GLOBUS_PROXY_V2 PROXYCERTINFO_OID #define OID_GLOBUS_PROXY_V3 OLD_PROXYCERTINFO_OID #define OID_RFC_PROXY "1.3.6.1.5.5.7.1.14" /********************************************************************** Global variables **********************************************************************/ /********************************************************************** Function prototypes **********************************************************************/ int ERR_load_prxyerr_strings(int i); int proxy_load_user_cert_and_key_pkcs12(const char *user_cert, X509 **cert, STACK_OF(X509) **stack, EVP_PKEY **pkey, int (*pw_cb) ()); int proxy_get_filenames( int proxy_in, char ** p_cert_file, char ** p_cert_dir, char ** p_user_proxy, char ** p_user_cert, char ** p_user_key); int proxy_load_user_cert( const char * user_cert, X509 ** certificate, int (*pw_cb)(), unsigned long * hSession); int proxy_load_user_key( EVP_PKEY ** private_key, X509 * ucert, const char * user_key, int (*pw_cb)(), unsigned long * hSession); void canl_proxy_verify_init( canl_proxy_verify_desc * pvd, canl_proxy_verify_ctx_desc * pvxd); void canl_proxy_verify_release( canl_proxy_verify_desc * pvd); void canl_proxy_verify_ctx_init( canl_proxy_verify_ctx_desc *pvxd); void canl_proxy_verify_ctx_release( canl_proxy_verify_ctx_desc *pvxd); int proxy_check_proxy_name( X509 *); int proxy_check_issued( X509_STORE_CTX * ctx, X509 * x, X509 * issuer); int proxy_verify_certchain( STACK_OF(X509) * certchain, canl_proxy_verify_desc * ppvd); int proxy_verify_callback( int ok, X509_STORE_CTX * ctx); int proxy_genreq( X509 * ucert, X509_REQ ** reqp, EVP_PKEY ** pkeyp, int bits, const char * newdn, int (*callback)()); int proxy_sign( X509 * user_cert, EVP_PKEY * user_private_key, X509_REQ * req, X509 ** new_cert, int seconds, STACK_OF(X509_EXTENSION) * extensions, int limited_proxy, int proxyver, const char * newdn, const char * newissuer, int pastproxy, const char * newserial, int selfsigned ); int proxy_sign_ext( X509 * user_cert, EVP_PKEY * user_private_key, const EVP_MD * method, X509_REQ * req, X509 ** new_cert, X509_NAME * subject_name, X509_NAME * issuer_name, int seconds, STACK_OF(X509_EXTENSION) * extensions, int proxyver, int pastproxy, const char * newserial, int selfsigned); int proxy_check_subject_name( X509_REQ * req, X509_NAME * subject_name); int proxy_construct_name( X509 * cert, X509_NAME ** name, char * newcn, unsigned int len); int proxy_marshal_tmp( X509 * ncert, EVP_PKEY * npkey, X509 * ucert, STACK_OF(X509) * store_ctx, char ** filename); int proxy_marshal_bp( BIO * bp, X509 * ncert, EVP_PKEY * npkey, X509 * ucert, STACK_OF(X509) * store_ctx); int proxy_load_user_proxy( STACK_OF(X509) * cert_chain, const char * file); int proxy_get_base_name( X509_NAME * subject); X509_EXTENSION * proxy_extension_class_add_create( void * buffer, size_t length); /* * SSLeay does not have a compare time function * So we add a convert to time_t function */ time_t ASN1_UTCTIME_mktime( ASN1_UTCTIME * ctm); time_t ASN1_TIME_mktime(ASN1_TIME *ctm); int PRIVATE determine_filenames(char **cacert, char **certdir, char **outfile, char **certfile, char **keyfile, int noregen); int load_credentials(const char *certname, const char *keyname, X509 **cert, STACK_OF(X509) **stack, EVP_PKEY **key, int (*callback)()); int PRIVATE load_certificate_from_file(FILE *file, X509 **cert, STACK_OF(X509) **stack); int proxy_app_verify_callback(X509_STORE_CTX *ctx, UNUSED(void *empty)); STACK_OF(X509) *load_chain(BIO *in, char*); int my_txt2nid(char *name); int hex2num(char c); EXTERN_C_END #endif /* _SSLUTILS_H */ canl-c-3.0.0/src/proxy/vomsproxy.h0000644000015500017500000000633213017332513016656 0ustar tomcat6jenkins/********************************************************************* * * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it * * Copyright (c) Members of the EGEE Collaboration. 2004-2010. * See http://www.eu-egee.org/partners/ for details on the copyright holders. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Parts of this code may be based upon or even include verbatim pieces, * originally written by other people, in which case the original header * follows. * *********************************************************************/ #ifndef VOMS_PROXY_H #define VOMS_PROXY_H #ifdef __cplusplus extern "C" { #endif #include #include #include #include "newformat.h" struct VOMSProxyArguments { X509_REQ *proxyrequest; char *proxyfilename; char *filename; AC **aclist; int proxyversion; char *data; int datalen; char *newsubject; int newsubjectlen; X509 *cert; EVP_PKEY *key; int bits; char *policyfile; char *policylang; char *policytext; int pathlength; int hours; int minutes; int limited; char *voID; int (*callback)(); STACK_OF(X509_EXTENSION) *extensions; STACK_OF(X509) *chain; int pastproxy; char *keyusage; char *netscape; char *exkusage; char *newissuer; char *newserial; int selfsigned; }; struct VOMSProxy { X509 *cert; STACK_OF(X509) *chain; EVP_PKEY *key; }; struct VOMSProxyArguments *VOMS_MakeProxyArguments(); void VOMS_FreeProxyArguments(struct VOMSProxyArguments *args); void VOMS_FreeProxy(struct VOMSProxy *proxy); struct VOMSProxy *VOMS_AllocProxy(); int VOMS_WriteProxy(const char *filename, struct VOMSProxy *proxy); struct VOMSProxy *VOMS_MakeProxy(struct VOMSProxyArguments *args, int *warning, void **additional); X509_EXTENSION *CreateProxyExtension(char * name, char *data, int datalen, int crit); char *ProxyCreationError(int error, void *additional); #define PROXY_ERROR_IS_WARNING(error) (error >= 1000) #define PROXY_NO_ERROR 0 #define PROXY_ERROR_OPEN_FILE 1 #define PROXY_ERROR_STAT_FILE 2 #define PROXY_ERROR_OUT_OF_MEMORY 3 #define PROXY_ERROR_FILE_READ 4 #define PROXY_ERROR_UNKNOWN_BIT 5 #define PROXY_ERROR_UNKNOWN_EXTENDED_BIT 6 #define PROXY_WARNING_GSI_ASSUMED 1000 #define PROXY_WARNING_GENERIC_LANGUAGE_ASSUMED 1001 #ifdef __cplusplus } #endif #endif canl-c-3.0.0/src/proxy/namespaces_lex.c.in0000644000015500017500000016550313017332513020165 0ustar tomcat6jenkins #line 3 "" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_SUBMINOR_VERSION 35 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; #endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! FLEXINT_H */ #ifdef __cplusplus /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST #else /* ! __cplusplus */ /* C99 requires __STDC__ to be defined as 1. */ #if defined (__STDC__) #define YY_USE_CONST #endif /* defined (__STDC__) */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* An opaque pointer. */ #ifndef YY_TYPEDEF_YY_SCANNER_T #define YY_TYPEDEF_YY_SCANNER_T typedef void* yyscan_t; #endif /* For convenience, these vars (plus the bison vars far below) are macros in the reentrant scanner. */ #define yyin yyg->yyin_r #define yyout yyg->yyout_r #define yyextra yyg->yyextra_r #define yyleng yyg->yyleng_r #define yytext yyg->yytext_r #define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) #define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) #define yy_flex_debug yyg->yy_flex_debug_r /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN yyg->yy_start = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START ((yyg->yy_start - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE namespacesrestart(yyin ,yyscanner ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #define YY_BUF_SIZE 16384 #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = yyg->yy_hold_char; \ YY_RESTORE_YY_MORE_OFFSET \ yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via namespacesrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] void namespacesrestart (FILE *input_file ,yyscan_t yyscanner ); void namespaces_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); YY_BUFFER_STATE namespaces_create_buffer (FILE *file,int size ,yyscan_t yyscanner ); void namespaces_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); void namespaces_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); void namespacespush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); void namespacespop_buffer_state (yyscan_t yyscanner ); static void namespacesensure_buffer_stack (yyscan_t yyscanner ); static void namespaces_load_buffer_state (yyscan_t yyscanner ); static void namespaces_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner ); #define YY_FLUSH_BUFFER namespaces_flush_buffer(YY_CURRENT_BUFFER ,yyscanner) YY_BUFFER_STATE namespaces_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); YY_BUFFER_STATE namespaces_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); YY_BUFFER_STATE namespaces_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner ); void *namespacesalloc (yy_size_t ,yyscan_t yyscanner ); void *namespacesrealloc (void *,yy_size_t ,yyscan_t yyscanner ); void namespacesfree (void * ,yyscan_t yyscanner ); #define yy_new_buffer namespaces_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ namespacesensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ namespaces_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ namespacesensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ namespaces_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) /* Begin user sect3 */ #define namespaceswrap(n) 1 #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; typedef int yy_state_type; #define yytext_ptr yytext_r static yy_state_type yy_get_previous_state (yyscan_t yyscanner ); static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner); static int yy_get_next_buffer (yyscan_t yyscanner ); static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ yyg->yytext_ptr = yy_bp; \ yyleng = (size_t) (yy_cp - yy_bp); \ yyg->yy_hold_char = *yy_cp; \ *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; #define YY_NUM_RULES 15 #define YY_END_OF_BUFFER 16 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_accept[53] = { 0, 0, 0, 0, 0, 0, 0, 16, 14, 13, 4, 1, 2, 14, 14, 14, 14, 14, 14, 15, 3, 15, 5, 1, 0, 0, 0, 0, 0, 6, 12, 0, 3, 0, 5, 0, 0, 0, 0, 0, 9, 0, 0, 10, 0, 0, 0, 0, 7, 8, 0, 11, 0 } ; static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 4, 1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 7, 8, 9, 10, 1, 1, 11, 12, 1, 13, 14, 15, 16, 17, 1, 18, 19, 20, 21, 1, 1, 1, 22, 1, 1, 23, 1, 1, 1, 1, 1, 24, 25, 26, 27, 28, 1, 1, 29, 30, 1, 31, 32, 33, 34, 35, 1, 36, 37, 38, 39, 1, 1, 1, 40, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int32_t yy_meta[41] = { 0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int16_t yy_base[59] = { 0, 0, 37, 79, 78, 79, 78, 80, 107, 107, 107, 0, 107, 0, 6, 1, 23, 0, 20, 16, 107, 11, 107, 0, 0, 12, 0, 33, 0, 107, 107, 8, 107, 4, 107, 25, 30, 38, 2, 41, 107, 46, 47, 107, 50, 43, 47, 61, 107, 107, 58, 107, 107, 96, 98, 100, 0, 102, 104 } ; static yyconst flex_int16_t yy_def[59] = { 0, 53, 53, 54, 54, 55, 55, 52, 52, 52, 52, 56, 52, 52, 52, 52, 52, 52, 52, 57, 52, 58, 52, 56, 52, 52, 52, 52, 52, 52, 52, 57, 52, 58, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 0, 52, 52, 52, 52, 52, 52 } ; static yyconst flex_int16_t yy_nxt[148] = { 0, 23, 9, 10, 11, 12, 39, 34, 13, 24, 26, 14, 43, 32, 34, 35, 29, 15, 37, 16, 17, 32, 30, 18, 39, 25, 13, 24, 26, 14, 43, 36, 27, 35, 29, 15, 37, 16, 17, 9, 10, 11, 12, 25, 28, 13, 38, 40, 14, 36, 27, 41, 42, 44, 15, 45, 16, 17, 46, 47, 18, 48, 28, 13, 38, 40, 14, 49, 50, 41, 42, 44, 15, 45, 16, 17, 46, 47, 51, 48, 52, 22, 22, 20, 20, 49, 50, 52, 52, 52, 52, 52, 52, 52, 52, 52, 51, 8, 8, 19, 19, 21, 21, 31, 31, 33, 33, 7, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52 } ; static yyconst flex_int16_t yy_chk[148] = { 0, 56, 1, 1, 1, 1, 28, 33, 1, 13, 15, 1, 38, 31, 21, 24, 17, 1, 26, 1, 1, 19, 18, 1, 28, 14, 1, 13, 15, 1, 38, 25, 16, 24, 17, 1, 26, 1, 1, 2, 2, 2, 2, 14, 16, 2, 27, 35, 2, 25, 16, 36, 37, 39, 2, 41, 2, 2, 42, 44, 2, 45, 16, 2, 27, 35, 2, 46, 47, 36, 37, 39, 2, 41, 2, 2, 42, 44, 50, 45, 7, 6, 5, 4, 3, 46, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, 53, 53, 54, 54, 55, 55, 57, 57, 58, 58, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52 } ; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET #line 1 "./src/proxy/namespaces_lex.l" #line 2 "./src/proxy/namespaces_lex.l" /********************************************************************* * * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it * * Copyright (c) Members of the EGEE Collaboration. 2004-2010. * See http://www.eu-egee.org/partners/ for details on the copyright holders. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Parts of this code may be based upon or even include verbatim pieces, * originally written by other people, in which case the original header * follows. * *********************************************************************/ #include "config.h" #include #include #include #include "parsertypes.h" #include "namespaces_parse.h" #line 515 "" #define INITIAL 0 #define SINGLE_QUOTED 1 #define DOUBLE_QUOTED 2 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif /* Holds the entire state of the reentrant scanner. */ struct yyguts_t { /* User-defined. Not touched by flex. */ YY_EXTRA_TYPE yyextra_r; /* The rest are the same as the globals declared in the non-reentrant scanner. */ FILE *yyin_r, *yyout_r; size_t yy_buffer_stack_top; /**< index of top of stack. */ size_t yy_buffer_stack_max; /**< capacity of stack. */ YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ char yy_hold_char; int yy_n_chars; int yyleng_r; char *yy_c_buf_p; int yy_init; int yy_start; int yy_did_buffer_switch_on_eof; int yy_start_stack_ptr; int yy_start_stack_depth; int *yy_start_stack; yy_state_type yy_last_accepting_state; char* yy_last_accepting_cpos; int yylineno_r; int yy_flex_debug_r; char *yytext_r; int yy_more_flag; int yy_more_len; YYSTYPE * yylval_r; }; /* end struct yyguts_t */ static int yy_init_globals (yyscan_t yyscanner ); /* This must go here because YYSTYPE and YYLTYPE are included * from bison output in section 1.*/ # define yylval yyg->yylval_r int namespaceslex_init (yyscan_t* scanner); int namespaceslex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int namespaceslex_destroy (yyscan_t yyscanner ); int namespacesget_debug (yyscan_t yyscanner ); void namespacesset_debug (int debug_flag ,yyscan_t yyscanner ); YY_EXTRA_TYPE namespacesget_extra (yyscan_t yyscanner ); void namespacesset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); FILE *namespacesget_in (yyscan_t yyscanner ); void namespacesset_in (FILE * in_str ,yyscan_t yyscanner ); FILE *namespacesget_out (yyscan_t yyscanner ); void namespacesset_out (FILE * out_str ,yyscan_t yyscanner ); int namespacesget_leng (yyscan_t yyscanner ); char *namespacesget_text (yyscan_t yyscanner ); int namespacesget_lineno (yyscan_t yyscanner ); void namespacesset_lineno (int line_number ,yyscan_t yyscanner ); YYSTYPE * namespacesget_lval (yyscan_t yyscanner ); void namespacesset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int namespaceswrap (yyscan_t yyscanner ); #else extern int namespaceswrap (yyscan_t yyscanner ); #endif #endif static void yyunput (int c,char *buf_ptr ,yyscan_t yyscanner); #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (yyscan_t yyscanner ); #else static int input (yyscan_t yyscanner ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #define YY_READ_BUF_SIZE 8192 #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ unsigned n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ buf[n++] = (char) c; \ if ( c == EOF && ferror( yyin ) ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ else \ { \ errno=0; \ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(yyin); \ } \ }\ \ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int namespaceslex \ (YYSTYPE * yylval_param ,yyscan_t yyscanner); #define YY_DECL int namespaceslex \ (YYSTYPE * yylval_param , yyscan_t yyscanner) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK break; #endif #define YY_RULE_SETUP \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; #line 45 "./src/proxy/namespaces_lex.l" #line 753 "" yylval = yylval_param; if ( !yyg->yy_init ) { yyg->yy_init = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! yyg->yy_start ) yyg->yy_start = 1; /* first start state */ if ( ! yyin ) yyin = stdin; if ( ! yyout ) yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { namespacesensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = namespaces_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); } namespaces_load_buffer_state(yyscanner ); } while ( 1 ) /* loops until end-of-file is reached */ { yy_cp = yyg->yy_c_buf_p; /* Support of yytext. */ *yy_cp = yyg->yy_hold_char; /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = yyg->yy_start; yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 53 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } while ( yy_base[yy_current_state] != 107 ); yy_find_action: yy_act = yy_accept[yy_current_state]; if ( yy_act == 0 ) { /* have to back up */ yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; yy_act = yy_accept[yy_current_state]; } YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = yyg->yy_hold_char; yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; goto yy_find_action; case 1: YY_RULE_SETUP #line 47 "./src/proxy/namespaces_lex.l" /* comment. Ignore */ YY_BREAK case 2: YY_RULE_SETUP #line 49 "./src/proxy/namespaces_lex.l" BEGIN(SINGLE_QUOTED); YY_BREAK case 3: /* rule 3 can match eol */ YY_RULE_SETUP #line 51 "./src/proxy/namespaces_lex.l" yytext[strlen(yytext)-1]='\0'; yylval_param->string = yytext; BEGIN(INITIAL); return SUBJECT; YY_BREAK case 4: YY_RULE_SETUP #line 53 "./src/proxy/namespaces_lex.l" BEGIN(DOUBLE_QUOTED); YY_BREAK case 5: /* rule 5 can match eol */ YY_RULE_SETUP #line 54 "./src/proxy/namespaces_lex.l" yytext[strlen(yytext)-1]='\0'; yylval_param->string = yytext; BEGIN(INITIAL); return SUBJECT; YY_BREAK case 6: YY_RULE_SETUP #line 57 "./src/proxy/namespaces_lex.l" return TO; YY_BREAK case 7: YY_RULE_SETUP #line 58 "./src/proxy/namespaces_lex.l" return ISSUER; YY_BREAK case 8: YY_RULE_SETUP #line 59 "./src/proxy/namespaces_lex.l" return PERMIT; YY_BREAK case 9: YY_RULE_SETUP #line 60 "./src/proxy/namespaces_lex.l" return DENY; YY_BREAK case 10: YY_RULE_SETUP #line 61 "./src/proxy/namespaces_lex.l" return SELF; YY_BREAK case 11: YY_RULE_SETUP #line 62 "./src/proxy/namespaces_lex.l" return SUBJECT_WORD; YY_BREAK case 12: *yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */ yyg->yy_c_buf_p = yy_cp -= 1; YY_DO_BEFORE_ACTION; /* set up yytext again */ YY_RULE_SETUP #line 63 "./src/proxy/namespaces_lex.l" YY_BREAK case 13: /* rule 13 can match eol */ YY_RULE_SETUP #line 64 "./src/proxy/namespaces_lex.l" YY_BREAK case 14: YY_RULE_SETUP #line 65 "./src/proxy/namespaces_lex.l" YY_BREAK case 15: YY_RULE_SETUP #line 67 "./src/proxy/namespaces_lex.l" ECHO; YY_BREAK #line 919 "" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(SINGLE_QUOTED): case YY_STATE_EOF(DOUBLE_QUOTED): yyterminate(); case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = yyg->yy_hold_char; YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * namespaceslex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) { /* This was really a NUL. */ yy_state_type yy_next_state; yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( yyscanner ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++yyg->yy_c_buf_p; yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = yyg->yy_c_buf_p; goto yy_find_action; } } else switch ( yy_get_next_buffer( yyscanner ) ) { case EOB_ACT_END_OF_FILE: { yyg->yy_did_buffer_switch_on_eof = 0; if ( namespaceswrap(yyscanner ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! yyg->yy_did_buffer_switch_on_eof ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( yyscanner ); yy_cp = yyg->yy_c_buf_p; yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: yyg->yy_c_buf_p = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; yy_current_state = yy_get_previous_state( yyscanner ); yy_cp = yyg->yy_c_buf_p; yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of namespaceslex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; register char *source = yyg->yytext_ptr; register int number_to_move, i; int ret_val; if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; else { int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER; int yy_c_buf_p_offset = (int) (yyg->yy_c_buf_p - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { int new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ namespacesrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = 0; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), yyg->yy_n_chars, (size_t) num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } if ( yyg->yy_n_chars == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; namespacesrestart(yyin ,yyscanner); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) namespacesrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } yyg->yy_n_chars += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state (yyscan_t yyscanner) { register yy_state_type yy_current_state; register char *yy_cp; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_current_state = yyg->yy_start; for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 53 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) { register int yy_is_jam; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ register char *yy_cp = yyg->yy_c_buf_p; register YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 53 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 52); return yy_is_jam ? 0 : yy_current_state; } static void yyunput (int c, register char * yy_bp , yyscan_t yyscanner) { register char *yy_cp; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_cp = yyg->yy_c_buf_p; /* undo effects of setting up yytext */ *yy_cp = yyg->yy_hold_char; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ register int number_to_move = yyg->yy_n_chars + 2; register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; yyg->yytext_ptr = yy_bp; yyg->yy_hold_char = *yy_cp; yyg->yy_c_buf_p = yy_cp; } #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (yyscan_t yyscanner) #else static int input (yyscan_t yyscanner) #endif { int c; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; *yyg->yy_c_buf_p = yyg->yy_hold_char; if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) /* This was really a NUL. */ *yyg->yy_c_buf_p = '\0'; else { /* need more input */ int offset = yyg->yy_c_buf_p - yyg->yytext_ptr; ++yyg->yy_c_buf_p; switch ( yy_get_next_buffer( yyscanner ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ namespacesrestart(yyin ,yyscanner); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( namespaceswrap(yyscanner ) ) return EOF; if ( ! yyg->yy_did_buffer_switch_on_eof ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(yyscanner); #else return input(yyscanner); #endif } case EOB_ACT_CONTINUE_SCAN: yyg->yy_c_buf_p = yyg->yytext_ptr + offset; break; } } } c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ yyg->yy_hold_char = *++yyg->yy_c_buf_p; return c; } #endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * @param yyscanner The scanner object. * @note This function does not reset the start condition to @c INITIAL . */ void namespacesrestart (FILE * input_file , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! YY_CURRENT_BUFFER ){ namespacesensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = namespaces_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); } namespaces_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner); namespaces_load_buffer_state(yyscanner ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * @param yyscanner The scanner object. */ void namespaces_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* TODO. We should be able to replace this entire function body * with * namespacespop_buffer_state(); * namespacespush_buffer_state(new_buffer); */ namespacesensure_buffer_stack (yyscanner); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *yyg->yy_c_buf_p = yyg->yy_hold_char; YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } YY_CURRENT_BUFFER_LVALUE = new_buffer; namespaces_load_buffer_state(yyscanner ); /* We don't actually know whether we did this switch during * EOF (namespaceswrap()) processing, but the only time this flag * is looked at is after namespaceswrap() is called, so it's safe * to go ahead and always set it. */ yyg->yy_did_buffer_switch_on_eof = 1; } static void namespaces_load_buffer_state (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; yyg->yy_hold_char = *yyg->yy_c_buf_p; } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * @param yyscanner The scanner object. * @return the allocated buffer state. */ YY_BUFFER_STATE namespaces_create_buffer (FILE * file, int size , yyscan_t yyscanner) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) namespacesalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in namespaces_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) namespacesalloc(b->yy_buf_size + 2 ,yyscanner ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in namespaces_create_buffer()" ); b->yy_is_our_buffer = 1; namespaces_init_buffer(b,file ,yyscanner); return b; } /** Destroy the buffer. * @param b a buffer created with namespaces_create_buffer() * @param yyscanner The scanner object. */ void namespaces_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) namespacesfree((void *) b->yy_ch_buf ,yyscanner ); namespacesfree((void *) b ,yyscanner ); } #ifndef __cplusplus extern int isatty (int ); #endif /* __cplusplus */ /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a namespacesrestart() or at EOF. */ static void namespaces_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) { int oerrno = errno; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; namespaces_flush_buffer(b ,yyscanner); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then namespaces_init_buffer was _probably_ * called from namespacesrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * @param yyscanner The scanner object. */ void namespaces_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) namespaces_load_buffer_state(yyscanner ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * @param yyscanner The scanner object. */ void namespacespush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (new_buffer == NULL) return; namespacesensure_buffer_stack(yyscanner); /* This block is copied from namespaces_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *yyg->yy_c_buf_p = yyg->yy_hold_char; YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) yyg->yy_buffer_stack_top++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from namespaces_switch_to_buffer. */ namespaces_load_buffer_state(yyscanner ); yyg->yy_did_buffer_switch_on_eof = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * @param yyscanner The scanner object. */ void namespacespop_buffer_state (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!YY_CURRENT_BUFFER) return; namespaces_delete_buffer(YY_CURRENT_BUFFER ,yyscanner); YY_CURRENT_BUFFER_LVALUE = NULL; if (yyg->yy_buffer_stack_top > 0) --yyg->yy_buffer_stack_top; if (YY_CURRENT_BUFFER) { namespaces_load_buffer_state(yyscanner ); yyg->yy_did_buffer_switch_on_eof = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void namespacesensure_buffer_stack (yyscan_t yyscanner) { int num_to_alloc; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!yyg->yy_buffer_stack) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; yyg->yy_buffer_stack = (struct yy_buffer_state**)namespacesalloc (num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) YY_FATAL_ERROR( "out of dynamic memory in namespacesensure_buffer_stack()" ); memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); yyg->yy_buffer_stack_max = num_to_alloc; yyg->yy_buffer_stack_top = 0; return; } if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; num_to_alloc = yyg->yy_buffer_stack_max + grow_size; yyg->yy_buffer_stack = (struct yy_buffer_state**)namespacesrealloc (yyg->yy_buffer_stack, num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) YY_FATAL_ERROR( "out of dynamic memory in namespacesensure_buffer_stack()" ); /* zero only the new slots.*/ memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); yyg->yy_buffer_stack_max = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ YY_BUFFER_STATE namespaces_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return 0; b = (YY_BUFFER_STATE) namespacesalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in namespaces_scan_buffer()" ); b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = 0; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; namespaces_switch_to_buffer(b ,yyscanner ); return b; } /** Setup the input buffer state to scan a string. The next call to namespaceslex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan * @param yyscanner The scanner object. * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * namespaces_scan_bytes() instead. */ YY_BUFFER_STATE namespaces_scan_string (yyconst char * yystr , yyscan_t yyscanner) { return namespaces_scan_bytes(yystr,strlen(yystr) ,yyscanner); } /** Setup the input buffer state to scan the given bytes. The next call to namespaceslex() will * scan from a @e copy of @a bytes. * @param bytes the byte buffer to scan * @param len the number of bytes in the buffer pointed to by @a bytes. * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ YY_BUFFER_STATE namespaces_scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner) { YY_BUFFER_STATE b; char *buf; yy_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; buf = (char *) namespacesalloc(n ,yyscanner ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in namespaces_scan_bytes()" ); for ( i = 0; i < _yybytes_len; ++i ) buf[i] = yybytes[i]; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = namespaces_scan_buffer(buf,n ,yyscanner); if ( ! b ) YY_FATAL_ERROR( "bad buffer in namespaces_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) { (void) fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = yyg->yy_hold_char; \ yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ yyg->yy_hold_char = *yyg->yy_c_buf_p; \ *yyg->yy_c_buf_p = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the user-defined data for this scanner. * @param yyscanner The scanner object. */ YY_EXTRA_TYPE namespacesget_extra (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyextra; } /** Get the current line number. * @param yyscanner The scanner object. */ int namespacesget_lineno (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (! YY_CURRENT_BUFFER) return 0; return yylineno; } /** Get the current column number. * @param yyscanner The scanner object. */ int namespacesget_column (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (! YY_CURRENT_BUFFER) return 0; return yycolumn; } /** Get the input stream. * @param yyscanner The scanner object. */ FILE *namespacesget_in (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyin; } /** Get the output stream. * @param yyscanner The scanner object. */ FILE *namespacesget_out (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyout; } /** Get the length of the current token. * @param yyscanner The scanner object. */ int namespacesget_leng (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyleng; } /** Get the current token. * @param yyscanner The scanner object. */ char *namespacesget_text (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yytext; } /** Set the user-defined data. This data is never touched by the scanner. * @param user_defined The data to be associated with this scanner. * @param yyscanner The scanner object. */ void namespacesset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyextra = user_defined ; } /** Set the current line number. * @param line_number * @param yyscanner The scanner object. */ void namespacesset_lineno (int line_number , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* lineno is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) yy_fatal_error( "namespacesset_lineno called with no buffer" , yyscanner); yylineno = line_number; } /** Set the current column. * @param line_number * @param yyscanner The scanner object. */ void namespacesset_column (int column_no , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* column is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) yy_fatal_error( "namespacesset_column called with no buffer" , yyscanner); yycolumn = column_no; } /** Set the input stream. This does not discard the current * input buffer. * @param in_str A readable stream. * @param yyscanner The scanner object. * @see namespaces_switch_to_buffer */ void namespacesset_in (FILE * in_str , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyin = in_str ; } void namespacesset_out (FILE * out_str , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyout = out_str ; } int namespacesget_debug (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yy_flex_debug; } void namespacesset_debug (int bdebug , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_flex_debug = bdebug ; } /* Accessor methods for yylval and yylloc */ YYSTYPE * namespacesget_lval (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yylval; } void namespacesset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yylval = yylval_param; } /* User-visible API */ /* namespaceslex_init is special because it creates the scanner itself, so it is * the ONLY reentrant function that doesn't take the scanner as the last argument. * That's why we explicitly handle the declaration, instead of using our macros. */ int namespaceslex_init(yyscan_t* ptr_yy_globals) { if (ptr_yy_globals == NULL){ errno = EINVAL; return 1; } *ptr_yy_globals = (yyscan_t) namespacesalloc ( sizeof( struct yyguts_t ), NULL ); if (*ptr_yy_globals == NULL){ errno = ENOMEM; return 1; } /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); return yy_init_globals ( *ptr_yy_globals ); } /* namespaceslex_init_extra has the same functionality as namespaceslex_init, but follows the * convention of taking the scanner as the last argument. Note however, that * this is a *pointer* to a scanner, as it will be allocated by this call (and * is the reason, too, why this function also must handle its own declaration). * The user defined value in the first argument will be available to namespacesalloc in * the yyextra field. */ int namespaceslex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals ) { struct yyguts_t dummy_yyguts; namespacesset_extra (yy_user_defined, &dummy_yyguts); if (ptr_yy_globals == NULL){ errno = EINVAL; return 1; } *ptr_yy_globals = (yyscan_t) namespacesalloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); if (*ptr_yy_globals == NULL){ errno = ENOMEM; return 1; } /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); namespacesset_extra (yy_user_defined, *ptr_yy_globals); return yy_init_globals ( *ptr_yy_globals ); } static int yy_init_globals (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* Initialization is the same as for the non-reentrant scanner. * This function is called from namespaceslex_destroy(), so don't allocate here. */ yyg->yy_buffer_stack = 0; yyg->yy_buffer_stack_top = 0; yyg->yy_buffer_stack_max = 0; yyg->yy_c_buf_p = (char *) 0; yyg->yy_init = 0; yyg->yy_start = 0; yyg->yy_start_stack_ptr = 0; yyg->yy_start_stack_depth = 0; yyg->yy_start_stack = NULL; /* Defined in main.c */ #ifdef YY_STDINIT yyin = stdin; yyout = stdout; #else yyin = (FILE *) 0; yyout = (FILE *) 0; #endif /* For future reference: Set errno on error, since we are called by * namespaceslex_init() */ return 0; } /* namespaceslex_destroy is for both reentrant and non-reentrant scanners. */ int namespaceslex_destroy (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ namespaces_delete_buffer(YY_CURRENT_BUFFER ,yyscanner ); YY_CURRENT_BUFFER_LVALUE = NULL; namespacespop_buffer_state(yyscanner); } /* Destroy the stack itself. */ namespacesfree(yyg->yy_buffer_stack ,yyscanner); yyg->yy_buffer_stack = NULL; /* Destroy the start condition stack. */ namespacesfree(yyg->yy_start_stack ,yyscanner ); yyg->yy_start_stack = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * namespaceslex() is called, initialization will occur. */ yy_init_globals( yyscanner); /* Destroy the main struct (reentrant only). */ namespacesfree ( yyscanner , yyscanner ); yyscanner = NULL; return 0; } /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner) { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *namespacesalloc (yy_size_t size , yyscan_t yyscanner) { return (void *) malloc( size ); } void *namespacesrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } void namespacesfree (void * ptr , yyscan_t yyscanner) { free( (char *) ptr ); /* see namespacesrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 67 "./src/proxy/namespaces_lex.l" canl-c-3.0.0/src/proxy/signing_policy_lex.c.in0000644000015500017500000016751513017332513021070 0ustar tomcat6jenkins #line 3 "" #define YY_INT_ALIGNED short int /* A lexical scanner generated by flex */ #define FLEX_SCANNER #define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_SUBMINOR_VERSION 35 #if YY_FLEX_SUBMINOR_VERSION > 0 #define FLEX_BETA #endif /* First, we deal with platform-specific or compiler-specific issues. */ /* begin standard C headers. */ #include #include #include #include /* end standard C headers. */ /* flex integer type definitions */ #ifndef FLEXINT_H #define FLEXINT_H /* C99 systems have . Non-C99 systems may or may not. */ #if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, * if you want the limit (max/min) macros for int types. */ #ifndef __STDC_LIMIT_MACROS #define __STDC_LIMIT_MACROS 1 #endif #include typedef int8_t flex_int8_t; typedef uint8_t flex_uint8_t; typedef int16_t flex_int16_t; typedef uint16_t flex_uint16_t; typedef int32_t flex_int32_t; typedef uint32_t flex_uint32_t; #else typedef signed char flex_int8_t; typedef short int flex_int16_t; typedef int flex_int32_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; #endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN #define INT8_MIN (-128) #endif #ifndef INT16_MIN #define INT16_MIN (-32767-1) #endif #ifndef INT32_MIN #define INT32_MIN (-2147483647-1) #endif #ifndef INT8_MAX #define INT8_MAX (127) #endif #ifndef INT16_MAX #define INT16_MAX (32767) #endif #ifndef INT32_MAX #define INT32_MAX (2147483647) #endif #ifndef UINT8_MAX #define UINT8_MAX (255U) #endif #ifndef UINT16_MAX #define UINT16_MAX (65535U) #endif #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif #endif /* ! FLEXINT_H */ #ifdef __cplusplus /* The "const" storage-class-modifier is valid. */ #define YY_USE_CONST #else /* ! __cplusplus */ /* C99 requires __STDC__ to be defined as 1. */ #if defined (__STDC__) #define YY_USE_CONST #endif /* defined (__STDC__) */ #endif /* ! __cplusplus */ #ifdef YY_USE_CONST #define yyconst const #else #define yyconst #endif /* Returned upon end-of-file. */ #define YY_NULL 0 /* Promotes a possibly negative, possibly signed char to an unsigned * integer for use as an array index. If the signed char is negative, * we want to instead treat it as an 8-bit unsigned char, hence the * double cast. */ #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) /* An opaque pointer. */ #ifndef YY_TYPEDEF_YY_SCANNER_T #define YY_TYPEDEF_YY_SCANNER_T typedef void* yyscan_t; #endif /* For convenience, these vars (plus the bison vars far below) are macros in the reentrant scanner. */ #define yyin yyg->yyin_r #define yyout yyg->yyout_r #define yyextra yyg->yyextra_r #define yyleng yyg->yyleng_r #define yytext yyg->yytext_r #define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) #define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) #define yy_flex_debug yyg->yy_flex_debug_r /* Enter a start condition. This macro really ought to take a parameter, * but we do it the disgusting crufty way forced on us by the ()-less * definition of BEGIN. */ #define BEGIN yyg->yy_start = 1 + 2 * /* Translate the current start state into a value that can be later handed * to BEGIN to return to the state. The YYSTATE alias is for lex * compatibility. */ #define YY_START ((yyg->yy_start - 1) / 2) #define YYSTATE YY_START /* Action number for EOF rule of a given start state. */ #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) /* Special action meaning "start processing a new file". */ #define YY_NEW_FILE signingrestart(yyin ,yyscanner ) #define YY_END_OF_BUFFER_CHAR 0 /* Size of default input buffer. */ #ifndef YY_BUF_SIZE #define YY_BUF_SIZE 16384 #endif /* The state buf must be large enough to hold one state per character in the main buffer. */ #define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) #ifndef YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE typedef struct yy_buffer_state *YY_BUFFER_STATE; #endif #define EOB_ACT_CONTINUE_SCAN 0 #define EOB_ACT_END_OF_FILE 1 #define EOB_ACT_LAST_MATCH 2 #define YY_LESS_LINENO(n) /* Return all but the first "n" matched characters back to the input stream. */ #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = yyg->yy_hold_char; \ YY_RESTORE_YY_MORE_OFFSET \ yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ YY_DO_BEFORE_ACTION; /* set up yytext again */ \ } \ while ( 0 ) #define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) #ifndef YY_TYPEDEF_YY_SIZE_T #define YY_TYPEDEF_YY_SIZE_T typedef size_t yy_size_t; #endif #ifndef YY_STRUCT_YY_BUFFER_STATE #define YY_STRUCT_YY_BUFFER_STATE struct yy_buffer_state { FILE *yy_input_file; char *yy_ch_buf; /* input buffer */ char *yy_buf_pos; /* current position in input buffer */ /* Size of input buffer in bytes, not including room for EOB * characters. */ yy_size_t yy_buf_size; /* Number of characters read into yy_ch_buf, not including EOB * characters. */ int yy_n_chars; /* Whether we "own" the buffer - i.e., we know we created it, * and can realloc() it to grow it, and should free() it to * delete it. */ int yy_is_our_buffer; /* Whether this is an "interactive" input source; if so, and * if we're using stdio for input, then we want to use getc() * instead of fread(), to make sure we stop fetching input after * each newline. */ int yy_is_interactive; /* Whether we're considered to be at the beginning of a line. * If so, '^' rules will be active on the next match, otherwise * not. */ int yy_at_bol; int yy_bs_lineno; /**< The line count. */ int yy_bs_column; /**< The column count. */ /* Whether to try to fill the input buffer when we reach the * end of it. */ int yy_fill_buffer; int yy_buffer_status; #define YY_BUFFER_NEW 0 #define YY_BUFFER_NORMAL 1 /* When an EOF's been seen but there's still some text to process * then we mark the buffer as YY_EOF_PENDING, to indicate that we * shouldn't try reading from the input source any more. We might * still have a bunch of tokens to match, though, because of * possible backing-up. * * When we actually see the EOF, we change the status to "new" * (via signingrestart()), so that the user can continue scanning by * just pointing yyin at a new input file. */ #define YY_BUFFER_EOF_PENDING 2 }; #endif /* !YY_STRUCT_YY_BUFFER_STATE */ /* We provide macros for accessing buffer states in case in the * future we want to put the buffer states in a more general * "scanner state". * * Returns the top of the stack, or NULL. */ #define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ : NULL) /* Same as previous macro, but useful when we know that the buffer stack is not * NULL or when we need an lvalue. For internal use only. */ #define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] void signingrestart (FILE *input_file ,yyscan_t yyscanner ); void signing_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); YY_BUFFER_STATE signing_create_buffer (FILE *file,int size ,yyscan_t yyscanner ); void signing_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); void signing_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); void signingpush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); void signingpop_buffer_state (yyscan_t yyscanner ); static void signingensure_buffer_stack (yyscan_t yyscanner ); static void signing_load_buffer_state (yyscan_t yyscanner ); static void signing_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner ); #define YY_FLUSH_BUFFER signing_flush_buffer(YY_CURRENT_BUFFER ,yyscanner) YY_BUFFER_STATE signing_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); YY_BUFFER_STATE signing_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); YY_BUFFER_STATE signing_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner ); void *signingalloc (yy_size_t ,yyscan_t yyscanner ); void *signingrealloc (void *,yy_size_t ,yyscan_t yyscanner ); void signingfree (void * ,yyscan_t yyscanner ); #define yy_new_buffer signing_create_buffer #define yy_set_interactive(is_interactive) \ { \ if ( ! YY_CURRENT_BUFFER ){ \ signingensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ signing_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ } #define yy_set_bol(at_bol) \ { \ if ( ! YY_CURRENT_BUFFER ){\ signingensure_buffer_stack (yyscanner); \ YY_CURRENT_BUFFER_LVALUE = \ signing_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ } \ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ } #define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) #define signingwrap(n) 1 #define YY_SKIP_YYWRAP typedef unsigned char YY_CHAR; typedef int yy_state_type; #define yytext_ptr yytext_r static yy_state_type yy_get_previous_state (yyscan_t yyscanner ); static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner); static int yy_get_next_buffer (yyscan_t yyscanner ); static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); /* Done after the current pattern has been matched and before the * corresponding action - sets up yytext. */ #define YY_DO_BEFORE_ACTION \ yyg->yytext_ptr = yy_bp; \ yyleng = (size_t) (yy_cp - yy_bp); \ yyg->yy_hold_char = *yy_cp; \ *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; #define YY_NUM_RULES 17 #define YY_END_OF_BUFFER 18 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info { flex_int32_t yy_verify; flex_int32_t yy_nxt; }; static yyconst flex_int16_t yy_accept[107] = { 0, 0, 0, 0, 0, 0, 0, 18, 16, 15, 4, 1, 2, 16, 16, 16, 16, 16, 16, 16, 17, 3, 17, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 9, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 7, 0 } ; static yyconst flex_int32_t yy_ec[256] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 4, 1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 1, 1, 1, 7, 1, 1, 1, 8, 9, 1, 1, 1, 1, 1, 1, 10, 11, 12, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 14, 15, 1, 1, 1, 1, 1, 1, 1, 1, 16, 17, 1, 1, 1, 1, 1, 18, 1, 19, 20, 21, 22, 23, 1, 24, 25, 26, 27, 1, 28, 1, 29, 30, 31, 1, 32, 33, 34, 35, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int32_t yy_meta[36] = { 0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; static yyconst flex_int16_t yy_base[113] = { 0, 0, 30, 130, 129, 130, 129, 131, 136, 136, 136, 0, 136, 120, 122, 107, 97, 98, 102, 94, 118, 136, 119, 136, 0, 112, 114, 98, 89, 87, 92, 82, 109, 136, 110, 136, 79, 103, 87, 87, 88, 89, 88, 79, 136, 71, 85, 67, 69, 68, 75, 65, 3, 64, 70, 69, 65, 75, 73, 56, 136, 66, 65, 136, 62, 58, 66, 60, 59, 61, 53, 54, 46, 45, 60, 54, 53, 42, 41, 1, 51, 51, 136, 136, 46, 48, 39, 22, 38, 136, 20, 19, 39, 13, 136, 32, 25, 31, 16, 24, 17, 136, 18, 4, 4, 136, 136, 61, 63, 65, 0, 67, 69 } ; static yyconst flex_int16_t yy_def[113] = { 0, 107, 107, 108, 108, 109, 109, 106, 106, 106, 106, 110, 106, 106, 106, 106, 106, 106, 106, 106, 111, 106, 112, 106, 110, 106, 106, 106, 106, 106, 106, 106, 111, 106, 112, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 0, 106, 106, 106, 106, 106, 106 } ; static yyconst flex_int16_t yy_nxt[172] = { 0, 24, 9, 10, 11, 12, 106, 106, 106, 106, 106, 84, 13, 85, 106, 106, 14, 106, 106, 15, 106, 16, 106, 58, 17, 106, 106, 106, 106, 18, 106, 19, 9, 10, 11, 12, 59, 105, 104, 103, 102, 101, 13, 100, 99, 98, 14, 97, 96, 15, 95, 16, 94, 93, 17, 92, 91, 90, 89, 18, 88, 19, 8, 8, 20, 20, 22, 22, 32, 32, 34, 34, 87, 86, 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, 62, 61, 60, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 35, 33, 42, 41, 40, 39, 38, 37, 36, 35, 33, 31, 30, 29, 28, 27, 26, 25, 106, 23, 23, 21, 21, 7, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106 } ; static yyconst flex_int16_t yy_chk[172] = { 0, 110, 1, 1, 1, 1, 0, 0, 0, 0, 0, 79, 1, 79, 0, 0, 1, 0, 0, 1, 0, 1, 0, 52, 1, 0, 0, 0, 0, 1, 0, 1, 2, 2, 2, 2, 52, 104, 103, 102, 100, 99, 2, 98, 97, 96, 2, 95, 93, 2, 92, 2, 91, 90, 2, 88, 87, 86, 85, 2, 84, 2, 107, 107, 108, 108, 109, 109, 111, 111, 112, 112, 81, 80, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 62, 61, 59, 58, 57, 56, 55, 54, 53, 51, 50, 49, 48, 47, 46, 45, 43, 42, 41, 40, 39, 38, 37, 36, 34, 32, 31, 30, 29, 28, 27, 26, 25, 22, 20, 19, 18, 17, 16, 15, 14, 13, 7, 6, 5, 4, 3, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106 } ; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. */ #define REJECT reject_used_but_not_detected #define yymore() yymore_used_but_not_detected #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET #line 1 "./src/proxy/signing_policy_lex.l" #line 2 "./src/proxy/signing_policy_lex.l" /********************************************************************* * * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it * * Copyright (c) Members of the EGEE Collaboration. 2004-2010. * See http://www.eu-egee.org/partners/ for details on the copyright holders. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Parts of this code may be based upon or even include verbatim pieces, * originally written by other people, in which case the original header * follows. * *********************************************************************/ #include "config.h" #include #include #include #include "parsertypes.h" #include "signing_policy_parse.h" #line 539 "" #define INITIAL 0 #define SINGLE_QUOTED 1 #define DOUBLE_QUOTED 2 #ifndef YY_NO_UNISTD_H /* Special case for "unistd.h", since it is non-ANSI. We include it way * down here because we want the user's section 1 to have been scanned first. * The user has a chance to override it with an option. */ #include #endif #ifndef YY_EXTRA_TYPE #define YY_EXTRA_TYPE void * #endif /* Holds the entire state of the reentrant scanner. */ struct yyguts_t { /* User-defined. Not touched by flex. */ YY_EXTRA_TYPE yyextra_r; /* The rest are the same as the globals declared in the non-reentrant scanner. */ FILE *yyin_r, *yyout_r; size_t yy_buffer_stack_top; /**< index of top of stack. */ size_t yy_buffer_stack_max; /**< capacity of stack. */ YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ char yy_hold_char; int yy_n_chars; int yyleng_r; char *yy_c_buf_p; int yy_init; int yy_start; int yy_did_buffer_switch_on_eof; int yy_start_stack_ptr; int yy_start_stack_depth; int *yy_start_stack; yy_state_type yy_last_accepting_state; char* yy_last_accepting_cpos; int yylineno_r; int yy_flex_debug_r; char *yytext_r; int yy_more_flag; int yy_more_len; YYSTYPE * yylval_r; }; /* end struct yyguts_t */ static int yy_init_globals (yyscan_t yyscanner ); /* This must go here because YYSTYPE and YYLTYPE are included * from bison output in section 1.*/ # define yylval yyg->yylval_r int signinglex_init (yyscan_t* scanner); int signinglex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); /* Accessor methods to globals. These are made visible to non-reentrant scanners for convenience. */ int signinglex_destroy (yyscan_t yyscanner ); int signingget_debug (yyscan_t yyscanner ); void signingset_debug (int debug_flag ,yyscan_t yyscanner ); YY_EXTRA_TYPE signingget_extra (yyscan_t yyscanner ); void signingset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); FILE *signingget_in (yyscan_t yyscanner ); void signingset_in (FILE * in_str ,yyscan_t yyscanner ); FILE *signingget_out (yyscan_t yyscanner ); void signingset_out (FILE * out_str ,yyscan_t yyscanner ); int signingget_leng (yyscan_t yyscanner ); char *signingget_text (yyscan_t yyscanner ); int signingget_lineno (yyscan_t yyscanner ); void signingset_lineno (int line_number ,yyscan_t yyscanner ); YYSTYPE * signingget_lval (yyscan_t yyscanner ); void signingset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); /* Macros after this point can all be overridden by user definitions in * section 1. */ #ifndef YY_SKIP_YYWRAP #ifdef __cplusplus extern "C" int signingwrap (yyscan_t yyscanner ); #else extern int signingwrap (yyscan_t yyscanner ); #endif #endif static void yyunput (int c,char *buf_ptr ,yyscan_t yyscanner); #ifndef yytext_ptr static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); #endif #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (yyscan_t yyscanner ); #else static int input (yyscan_t yyscanner ); #endif #endif /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE #define YY_READ_BUF_SIZE 8192 #endif /* Copy whatever the last rule matched to the standard output. */ #ifndef ECHO /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ #define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, * is returned in "result". */ #ifndef YY_INPUT #define YY_INPUT(buf,result,max_size) \ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ unsigned n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ if ( c == '\n' ) \ buf[n++] = (char) c; \ if ( c == EOF && ferror( yyin ) ) \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ result = n; \ } \ else \ { \ errno=0; \ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ { \ if( errno != EINTR) \ { \ YY_FATAL_ERROR( "input in flex scanner failed" ); \ break; \ } \ errno=0; \ clearerr(yyin); \ } \ }\ \ #endif /* No semi-colon after return; correct usage is to write "yyterminate();" - * we don't want an extra ';' after the "return" because that will cause * some compilers to complain about unreachable statements. */ #ifndef yyterminate #define yyterminate() return YY_NULL #endif /* Number of entries by which start-condition stack grows. */ #ifndef YY_START_STACK_INCR #define YY_START_STACK_INCR 25 #endif /* Report a fatal error. */ #ifndef YY_FATAL_ERROR #define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) #endif /* end tables serialization structures and prototypes */ /* Default declaration of generated scanner - a define so the user can * easily add parameters. */ #ifndef YY_DECL #define YY_DECL_IS_OURS 1 extern int signinglex \ (YYSTYPE * yylval_param ,yyscan_t yyscanner); #define YY_DECL int signinglex \ (YYSTYPE * yylval_param , yyscan_t yyscanner) #endif /* !YY_DECL */ /* Code executed at the beginning of each rule, after yytext and yyleng * have been set up. */ #ifndef YY_USER_ACTION #define YY_USER_ACTION #endif /* Code executed at the end of each rule. */ #ifndef YY_BREAK #define YY_BREAK break; #endif #define YY_RULE_SETUP \ YY_USER_ACTION /** The main scanner function which does all the work. */ YY_DECL { register yy_state_type yy_current_state; register char *yy_cp, *yy_bp; register int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; #line 45 "./src/proxy/signing_policy_lex.l" #line 777 "" yylval = yylval_param; if ( !yyg->yy_init ) { yyg->yy_init = 1; #ifdef YY_USER_INIT YY_USER_INIT; #endif if ( ! yyg->yy_start ) yyg->yy_start = 1; /* first start state */ if ( ! yyin ) yyin = stdin; if ( ! yyout ) yyout = stdout; if ( ! YY_CURRENT_BUFFER ) { signingensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = signing_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); } signing_load_buffer_state(yyscanner ); } while ( 1 ) /* loops until end-of-file is reached */ { yy_cp = yyg->yy_c_buf_p; /* Support of yytext. */ *yy_cp = yyg->yy_hold_char; /* yy_bp points to the position in yy_ch_buf of the start of * the current run. */ yy_bp = yy_cp; yy_current_state = yyg->yy_start; yy_match: do { register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 107 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } while ( yy_base[yy_current_state] != 136 ); yy_find_action: yy_act = yy_accept[yy_current_state]; if ( yy_act == 0 ) { /* have to back up */ yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; yy_act = yy_accept[yy_current_state]; } YY_DO_BEFORE_ACTION; do_action: /* This label is used only to access EOF actions. */ switch ( yy_act ) { /* beginning of action switch */ case 0: /* must back up */ /* undo the effects of YY_DO_BEFORE_ACTION */ *yy_cp = yyg->yy_hold_char; yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; goto yy_find_action; case 1: YY_RULE_SETUP #line 47 "./src/proxy/signing_policy_lex.l" /* ignore comments */ YY_BREAK case 2: YY_RULE_SETUP #line 48 "./src/proxy/signing_policy_lex.l" BEGIN(SINGLE_QUOTED); YY_BREAK case 3: /* rule 3 can match eol */ YY_RULE_SETUP #line 50 "./src/proxy/signing_policy_lex.l" yytext[strlen(yytext)-1]='\0'; yylval_param->string = yytext; BEGIN(INITIAL); return SUBJECTS; YY_BREAK case 4: YY_RULE_SETUP #line 52 "./src/proxy/signing_policy_lex.l" BEGIN(DOUBLE_QUOTED); YY_BREAK case 5: /* rule 5 can match eol */ YY_RULE_SETUP #line 53 "./src/proxy/signing_policy_lex.l" yytext[strlen(yytext)-1]='\0'; yylval_param->string = yytext; BEGIN(INITIAL); return SUBJECTS; YY_BREAK case 6: YY_RULE_SETUP #line 56 "./src/proxy/signing_policy_lex.l" return COND_SUBJECTS; YY_BREAK case 7: YY_RULE_SETUP #line 57 "./src/proxy/signing_policy_lex.l" return COND_BANNED; YY_BREAK case 8: YY_RULE_SETUP #line 58 "./src/proxy/signing_policy_lex.l" return GLOBUS; YY_BREAK case 9: YY_RULE_SETUP #line 59 "./src/proxy/signing_policy_lex.l" return POS_RIGHTS; YY_BREAK case 10: YY_RULE_SETUP #line 60 "./src/proxy/signing_policy_lex.l" return NEG_RIGHTS; YY_BREAK case 11: YY_RULE_SETUP #line 61 "./src/proxy/signing_policy_lex.l" return CA_SIGN; YY_BREAK case 12: YY_RULE_SETUP #line 62 "./src/proxy/signing_policy_lex.l" return ACCESS_ID_CA; YY_BREAK case 13: YY_RULE_SETUP #line 63 "./src/proxy/signing_policy_lex.l" return ACCESS_ID_ANYBODY; YY_BREAK case 14: YY_RULE_SETUP #line 64 "./src/proxy/signing_policy_lex.l" return X509; YY_BREAK case 15: /* rule 15 can match eol */ YY_RULE_SETUP #line 66 "./src/proxy/signing_policy_lex.l" YY_BREAK case 16: YY_RULE_SETUP #line 67 "./src/proxy/signing_policy_lex.l" YY_BREAK case 17: YY_RULE_SETUP #line 69 "./src/proxy/signing_policy_lex.l" ECHO; YY_BREAK #line 950 "" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(SINGLE_QUOTED): case YY_STATE_EOF(DOUBLE_QUOTED): yyterminate(); case YY_END_OF_BUFFER: { /* Amount of text matched not including the EOB char. */ int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; /* Undo the effects of YY_DO_BEFORE_ACTION. */ *yy_cp = yyg->yy_hold_char; YY_RESTORE_YY_MORE_OFFSET if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) { /* We're scanning a new file or input source. It's * possible that this happened because the user * just pointed yyin at a new source and called * signinglex(). If so, then we have to assure * consistency between YY_CURRENT_BUFFER and our * globals. Here is the right place to do so, because * this is the first action (other than possibly a * back-up) that will match for the new input source. */ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; } /* Note that here we test for yy_c_buf_p "<=" to the position * of the first EOB in the buffer, since yy_c_buf_p will * already have been incremented past the NUL character * (since all states make transitions on EOB to the * end-of-buffer state). Contrast this with the test * in input(). */ if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) { /* This was really a NUL. */ yy_state_type yy_next_state; yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( yyscanner ); /* Okay, we're now positioned to make the NUL * transition. We couldn't have * yy_get_previous_state() go ahead and do it * for us because it doesn't know how to deal * with the possibility of jamming (and we don't * want to build jamming into it because then it * will run more slowly). */ yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; if ( yy_next_state ) { /* Consume the NUL. */ yy_cp = ++yyg->yy_c_buf_p; yy_current_state = yy_next_state; goto yy_match; } else { yy_cp = yyg->yy_c_buf_p; goto yy_find_action; } } else switch ( yy_get_next_buffer( yyscanner ) ) { case EOB_ACT_END_OF_FILE: { yyg->yy_did_buffer_switch_on_eof = 0; if ( signingwrap(yyscanner ) ) { /* Note: because we've taken care in * yy_get_next_buffer() to have set up * yytext, we can now set up * yy_c_buf_p so that if some total * hoser (like flex itself) wants to * call the scanner after we return the * YY_NULL, it'll still work - another * YY_NULL will get returned. */ yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; yy_act = YY_STATE_EOF(YY_START); goto do_action; } else { if ( ! yyg->yy_did_buffer_switch_on_eof ) YY_NEW_FILE; } break; } case EOB_ACT_CONTINUE_SCAN: yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; yy_current_state = yy_get_previous_state( yyscanner ); yy_cp = yyg->yy_c_buf_p; yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; goto yy_match; case EOB_ACT_LAST_MATCH: yyg->yy_c_buf_p = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; yy_current_state = yy_get_previous_state( yyscanner ); yy_cp = yyg->yy_c_buf_p; yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; goto yy_find_action; } break; } default: YY_FATAL_ERROR( "fatal flex scanner internal error--no action found" ); } /* end of action switch */ } /* end of scanning one token */ } /* end of signinglex */ /* yy_get_next_buffer - try to read in a new buffer * * Returns a code representing an action: * EOB_ACT_LAST_MATCH - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position * EOB_ACT_END_OF_FILE - end of file */ static int yy_get_next_buffer (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; register char *source = yyg->yytext_ptr; register int number_to_move, i; int ret_val; if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) YY_FATAL_ERROR( "fatal flex scanner internal error--end of buffer missed" ); if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) { /* Don't try to fill the buffer, so this is an EOF. */ if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) { /* We matched a single character, the EOB, so * treat this as a final EOF. */ return EOB_ACT_END_OF_FILE; } else { /* We matched some text prior to the EOB, first * process it. */ return EOB_ACT_LAST_MATCH; } } /* Try to read more data. */ /* First move last chars to start of buffer. */ number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) /* don't do the read, it's not guaranteed to return an EOF, * just force an EOF */ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; else { int num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; while ( num_to_read <= 0 ) { /* Not enough room in the buffer - grow it. */ /* just a shorter name for the current buffer */ YY_BUFFER_STATE b = YY_CURRENT_BUFFER; int yy_c_buf_p_offset = (int) (yyg->yy_c_buf_p - b->yy_ch_buf); if ( b->yy_is_our_buffer ) { int new_size = b->yy_buf_size * 2; if ( new_size <= 0 ) b->yy_buf_size += b->yy_buf_size / 8; else b->yy_buf_size *= 2; b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ signingrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner ); } else /* Can't grow it, we don't own it. */ b->yy_ch_buf = 0; if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "fatal error - scanner input buffer overflow" ); yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; } if ( num_to_read > YY_READ_BUF_SIZE ) num_to_read = YY_READ_BUF_SIZE; /* Read in more data. */ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), yyg->yy_n_chars, (size_t) num_to_read ); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } if ( yyg->yy_n_chars == 0 ) { if ( number_to_move == YY_MORE_ADJ ) { ret_val = EOB_ACT_END_OF_FILE; signingrestart(yyin ,yyscanner); } else { ret_val = EOB_ACT_LAST_MATCH; YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_EOF_PENDING; } } else ret_val = EOB_ACT_CONTINUE_SCAN; if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) signingrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } yyg->yy_n_chars += number_to_move; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; return ret_val; } /* yy_get_previous_state - get the state just before the EOB char was reached */ static yy_state_type yy_get_previous_state (yyscan_t yyscanner) { register yy_state_type yy_current_state; register char *yy_cp; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_current_state = yyg->yy_start; for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) { register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 107 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; } return yy_current_state; } /* yy_try_NUL_trans - try to make a transition on the NUL character * * synopsis * next_state = yy_try_NUL_trans( current_state ); */ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) { register int yy_is_jam; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ register char *yy_cp = yyg->yy_c_buf_p; register YY_CHAR yy_c = 1; if ( yy_accept[yy_current_state] ) { yyg->yy_last_accepting_state = yy_current_state; yyg->yy_last_accepting_cpos = yy_cp; } while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; if ( yy_current_state >= 107 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; yy_is_jam = (yy_current_state == 106); return yy_is_jam ? 0 : yy_current_state; } static void yyunput (int c, register char * yy_bp , yyscan_t yyscanner) { register char *yy_cp; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_cp = yyg->yy_c_buf_p; /* undo effects of setting up yytext */ *yy_cp = yyg->yy_hold_char; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) { /* need to shift things up to make room */ /* +2 for EOB chars. */ register int number_to_move = yyg->yy_n_chars + 2; register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; register char *source = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) *--dest = *--source; yy_cp += (int) (dest - source); yy_bp += (int) (dest - source); YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) YY_FATAL_ERROR( "flex scanner push-back overflow" ); } *--yy_cp = (char) c; yyg->yytext_ptr = yy_bp; yyg->yy_hold_char = *yy_cp; yyg->yy_c_buf_p = yy_cp; } #ifndef YY_NO_INPUT #ifdef __cplusplus static int yyinput (yyscan_t yyscanner) #else static int input (yyscan_t yyscanner) #endif { int c; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; *yyg->yy_c_buf_p = yyg->yy_hold_char; if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) { /* yy_c_buf_p now points to the character we want to return. * If this occurs *before* the EOB characters, then it's a * valid NUL; if not, then we've hit the end of the buffer. */ if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) /* This was really a NUL. */ *yyg->yy_c_buf_p = '\0'; else { /* need more input */ int offset = yyg->yy_c_buf_p - yyg->yytext_ptr; ++yyg->yy_c_buf_p; switch ( yy_get_next_buffer( yyscanner ) ) { case EOB_ACT_LAST_MATCH: /* This happens because yy_g_n_b() * sees that we've accumulated a * token and flags that we need to * try matching the token before * proceeding. But for input(), * there's no matching to consider. * So convert the EOB_ACT_LAST_MATCH * to EOB_ACT_END_OF_FILE. */ /* Reset buffer status. */ signingrestart(yyin ,yyscanner); /*FALLTHROUGH*/ case EOB_ACT_END_OF_FILE: { if ( signingwrap(yyscanner ) ) return EOF; if ( ! yyg->yy_did_buffer_switch_on_eof ) YY_NEW_FILE; #ifdef __cplusplus return yyinput(yyscanner); #else return input(yyscanner); #endif } case EOB_ACT_CONTINUE_SCAN: yyg->yy_c_buf_p = yyg->yytext_ptr + offset; break; } } } c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ yyg->yy_hold_char = *++yyg->yy_c_buf_p; return c; } #endif /* ifndef YY_NO_INPUT */ /** Immediately switch to a different input stream. * @param input_file A readable stream. * @param yyscanner The scanner object. * @note This function does not reset the start condition to @c INITIAL . */ void signingrestart (FILE * input_file , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! YY_CURRENT_BUFFER ){ signingensure_buffer_stack (yyscanner); YY_CURRENT_BUFFER_LVALUE = signing_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); } signing_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner); signing_load_buffer_state(yyscanner ); } /** Switch to a different input buffer. * @param new_buffer The new input buffer. * @param yyscanner The scanner object. */ void signing_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* TODO. We should be able to replace this entire function body * with * signingpop_buffer_state(); * signingpush_buffer_state(new_buffer); */ signingensure_buffer_stack (yyscanner); if ( YY_CURRENT_BUFFER == new_buffer ) return; if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *yyg->yy_c_buf_p = yyg->yy_hold_char; YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } YY_CURRENT_BUFFER_LVALUE = new_buffer; signing_load_buffer_state(yyscanner ); /* We don't actually know whether we did this switch during * EOF (signingwrap()) processing, but the only time this flag * is looked at is after signingwrap() is called, so it's safe * to go ahead and always set it. */ yyg->yy_did_buffer_switch_on_eof = 1; } static void signing_load_buffer_state (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; yyg->yy_hold_char = *yyg->yy_c_buf_p; } /** Allocate and initialize an input buffer state. * @param file A readable stream. * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. * @param yyscanner The scanner object. * @return the allocated buffer state. */ YY_BUFFER_STATE signing_create_buffer (FILE * file, int size , yyscan_t yyscanner) { YY_BUFFER_STATE b; b = (YY_BUFFER_STATE) signingalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in signing_create_buffer()" ); b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ b->yy_ch_buf = (char *) signingalloc(b->yy_buf_size + 2 ,yyscanner ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in signing_create_buffer()" ); b->yy_is_our_buffer = 1; signing_init_buffer(b,file ,yyscanner); return b; } /** Destroy the buffer. * @param b a buffer created with signing_create_buffer() * @param yyscanner The scanner object. */ void signing_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) return; if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; if ( b->yy_is_our_buffer ) signingfree((void *) b->yy_ch_buf ,yyscanner ); signingfree((void *) b ,yyscanner ); } #ifndef __cplusplus extern int isatty (int ); #endif /* __cplusplus */ /* Initializes or reinitializes a buffer. * This function is sometimes called more than once on the same buffer, * such as during a signingrestart() or at EOF. */ static void signing_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) { int oerrno = errno; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; signing_flush_buffer(b ,yyscanner); b->yy_input_file = file; b->yy_fill_buffer = 1; /* If b is the current buffer, then signing_init_buffer was _probably_ * called from signingrestart() or through yy_get_next_buffer. * In that case, we don't want to reset the lineno or column. */ if (b != YY_CURRENT_BUFFER){ b->yy_bs_lineno = 1; b->yy_bs_column = 0; } b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; errno = oerrno; } /** Discard all buffered characters. On the next scan, YY_INPUT will be called. * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. * @param yyscanner The scanner object. */ void signing_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if ( ! b ) return; b->yy_n_chars = 0; /* We always need two end-of-buffer characters. The first causes * a transition to the end-of-buffer state. The second causes * a jam in that state. */ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; b->yy_buf_pos = &b->yy_ch_buf[0]; b->yy_at_bol = 1; b->yy_buffer_status = YY_BUFFER_NEW; if ( b == YY_CURRENT_BUFFER ) signing_load_buffer_state(yyscanner ); } /** Pushes the new state onto the stack. The new state becomes * the current state. This function will allocate the stack * if necessary. * @param new_buffer The new state. * @param yyscanner The scanner object. */ void signingpush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (new_buffer == NULL) return; signingensure_buffer_stack(yyscanner); /* This block is copied from signing_switch_to_buffer. */ if ( YY_CURRENT_BUFFER ) { /* Flush out information for old buffer. */ *yyg->yy_c_buf_p = yyg->yy_hold_char; YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; } /* Only push if top exists. Otherwise, replace top. */ if (YY_CURRENT_BUFFER) yyg->yy_buffer_stack_top++; YY_CURRENT_BUFFER_LVALUE = new_buffer; /* copied from signing_switch_to_buffer. */ signing_load_buffer_state(yyscanner ); yyg->yy_did_buffer_switch_on_eof = 1; } /** Removes and deletes the top of the stack, if present. * The next element becomes the new top. * @param yyscanner The scanner object. */ void signingpop_buffer_state (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!YY_CURRENT_BUFFER) return; signing_delete_buffer(YY_CURRENT_BUFFER ,yyscanner); YY_CURRENT_BUFFER_LVALUE = NULL; if (yyg->yy_buffer_stack_top > 0) --yyg->yy_buffer_stack_top; if (YY_CURRENT_BUFFER) { signing_load_buffer_state(yyscanner ); yyg->yy_did_buffer_switch_on_eof = 1; } } /* Allocates the stack if it does not exist. * Guarantees space for at least one push. */ static void signingensure_buffer_stack (yyscan_t yyscanner) { int num_to_alloc; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (!yyg->yy_buffer_stack) { /* First allocation is just for 2 elements, since we don't know if this * scanner will even need a stack. We use 2 instead of 1 to avoid an * immediate realloc on the next call. */ num_to_alloc = 1; yyg->yy_buffer_stack = (struct yy_buffer_state**)signingalloc (num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) YY_FATAL_ERROR( "out of dynamic memory in signingensure_buffer_stack()" ); memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); yyg->yy_buffer_stack_max = num_to_alloc; yyg->yy_buffer_stack_top = 0; return; } if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ /* Increase the buffer to prepare for a possible push. */ int grow_size = 8 /* arbitrary grow size */; num_to_alloc = yyg->yy_buffer_stack_max + grow_size; yyg->yy_buffer_stack = (struct yy_buffer_state**)signingrealloc (yyg->yy_buffer_stack, num_to_alloc * sizeof(struct yy_buffer_state*) , yyscanner); if ( ! yyg->yy_buffer_stack ) YY_FATAL_ERROR( "out of dynamic memory in signingensure_buffer_stack()" ); /* zero only the new slots.*/ memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); yyg->yy_buffer_stack_max = num_to_alloc; } } /** Setup the input buffer state to scan directly from a user-specified character buffer. * @param base the character buffer * @param size the size in bytes of the character buffer * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ YY_BUFFER_STATE signing_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) { YY_BUFFER_STATE b; if ( size < 2 || base[size-2] != YY_END_OF_BUFFER_CHAR || base[size-1] != YY_END_OF_BUFFER_CHAR ) /* They forgot to leave room for the EOB's. */ return 0; b = (YY_BUFFER_STATE) signingalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in signing_scan_buffer()" ); b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = 0; b->yy_n_chars = b->yy_buf_size; b->yy_is_interactive = 0; b->yy_at_bol = 1; b->yy_fill_buffer = 0; b->yy_buffer_status = YY_BUFFER_NEW; signing_switch_to_buffer(b ,yyscanner ); return b; } /** Setup the input buffer state to scan a string. The next call to signinglex() will * scan from a @e copy of @a str. * @param yystr a NUL-terminated string to scan * @param yyscanner The scanner object. * @return the newly allocated buffer state object. * @note If you want to scan bytes that may contain NUL values, then use * signing_scan_bytes() instead. */ YY_BUFFER_STATE signing_scan_string (yyconst char * yystr , yyscan_t yyscanner) { return signing_scan_bytes(yystr,strlen(yystr) ,yyscanner); } /** Setup the input buffer state to scan the given bytes. The next call to signinglex() will * scan from a @e copy of @a bytes. * @param bytes the byte buffer to scan * @param len the number of bytes in the buffer pointed to by @a bytes. * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ YY_BUFFER_STATE signing_scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner) { YY_BUFFER_STATE b; char *buf; yy_size_t n; int i; /* Get memory for full buffer, including space for trailing EOB's. */ n = _yybytes_len + 2; buf = (char *) signingalloc(n ,yyscanner ); if ( ! buf ) YY_FATAL_ERROR( "out of dynamic memory in signing_scan_bytes()" ); for ( i = 0; i < _yybytes_len; ++i ) buf[i] = yybytes[i]; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; b = signing_scan_buffer(buf,n ,yyscanner); if ( ! b ) YY_FATAL_ERROR( "bad buffer in signing_scan_bytes()" ); /* It's okay to grow etc. this buffer, and we should throw it * away when we're done. */ b->yy_is_our_buffer = 1; return b; } #ifndef YY_EXIT_FAILURE #define YY_EXIT_FAILURE 2 #endif static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) { (void) fprintf( stderr, "%s\n", msg ); exit( YY_EXIT_FAILURE ); } /* Redefine yyless() so it works in section 3 code. */ #undef yyless #define yyless(n) \ do \ { \ /* Undo effects of setting up yytext. */ \ int yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = yyg->yy_hold_char; \ yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ yyg->yy_hold_char = *yyg->yy_c_buf_p; \ *yyg->yy_c_buf_p = '\0'; \ yyleng = yyless_macro_arg; \ } \ while ( 0 ) /* Accessor methods (get/set functions) to struct members. */ /** Get the user-defined data for this scanner. * @param yyscanner The scanner object. */ YY_EXTRA_TYPE signingget_extra (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyextra; } /** Get the current line number. * @param yyscanner The scanner object. */ int signingget_lineno (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (! YY_CURRENT_BUFFER) return 0; return yylineno; } /** Get the current column number. * @param yyscanner The scanner object. */ int signingget_column (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; if (! YY_CURRENT_BUFFER) return 0; return yycolumn; } /** Get the input stream. * @param yyscanner The scanner object. */ FILE *signingget_in (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyin; } /** Get the output stream. * @param yyscanner The scanner object. */ FILE *signingget_out (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyout; } /** Get the length of the current token. * @param yyscanner The scanner object. */ int signingget_leng (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yyleng; } /** Get the current token. * @param yyscanner The scanner object. */ char *signingget_text (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yytext; } /** Set the user-defined data. This data is never touched by the scanner. * @param user_defined The data to be associated with this scanner. * @param yyscanner The scanner object. */ void signingset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyextra = user_defined ; } /** Set the current line number. * @param line_number * @param yyscanner The scanner object. */ void signingset_lineno (int line_number , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* lineno is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) yy_fatal_error( "signingset_lineno called with no buffer" , yyscanner); yylineno = line_number; } /** Set the current column. * @param line_number * @param yyscanner The scanner object. */ void signingset_column (int column_no , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* column is only valid if an input buffer exists. */ if (! YY_CURRENT_BUFFER ) yy_fatal_error( "signingset_column called with no buffer" , yyscanner); yycolumn = column_no; } /** Set the input stream. This does not discard the current * input buffer. * @param in_str A readable stream. * @param yyscanner The scanner object. * @see signing_switch_to_buffer */ void signingset_in (FILE * in_str , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyin = in_str ; } void signingset_out (FILE * out_str , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yyout = out_str ; } int signingget_debug (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yy_flex_debug; } void signingset_debug (int bdebug , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yy_flex_debug = bdebug ; } /* Accessor methods for yylval and yylloc */ YYSTYPE * signingget_lval (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; return yylval; } void signingset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; yylval = yylval_param; } /* User-visible API */ /* signinglex_init is special because it creates the scanner itself, so it is * the ONLY reentrant function that doesn't take the scanner as the last argument. * That's why we explicitly handle the declaration, instead of using our macros. */ int signinglex_init(yyscan_t* ptr_yy_globals) { if (ptr_yy_globals == NULL){ errno = EINVAL; return 1; } *ptr_yy_globals = (yyscan_t) signingalloc ( sizeof( struct yyguts_t ), NULL ); if (*ptr_yy_globals == NULL){ errno = ENOMEM; return 1; } /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); return yy_init_globals ( *ptr_yy_globals ); } /* signinglex_init_extra has the same functionality as signinglex_init, but follows the * convention of taking the scanner as the last argument. Note however, that * this is a *pointer* to a scanner, as it will be allocated by this call (and * is the reason, too, why this function also must handle its own declaration). * The user defined value in the first argument will be available to signingalloc in * the yyextra field. */ int signinglex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals ) { struct yyguts_t dummy_yyguts; signingset_extra (yy_user_defined, &dummy_yyguts); if (ptr_yy_globals == NULL){ errno = EINVAL; return 1; } *ptr_yy_globals = (yyscan_t) signingalloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); if (*ptr_yy_globals == NULL){ errno = ENOMEM; return 1; } /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); signingset_extra (yy_user_defined, *ptr_yy_globals); return yy_init_globals ( *ptr_yy_globals ); } static int yy_init_globals (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* Initialization is the same as for the non-reentrant scanner. * This function is called from signinglex_destroy(), so don't allocate here. */ yyg->yy_buffer_stack = 0; yyg->yy_buffer_stack_top = 0; yyg->yy_buffer_stack_max = 0; yyg->yy_c_buf_p = (char *) 0; yyg->yy_init = 0; yyg->yy_start = 0; yyg->yy_start_stack_ptr = 0; yyg->yy_start_stack_depth = 0; yyg->yy_start_stack = NULL; /* Defined in main.c */ #ifdef YY_STDINIT yyin = stdin; yyout = stdout; #else yyin = (FILE *) 0; yyout = (FILE *) 0; #endif /* For future reference: Set errno on error, since we are called by * signinglex_init() */ return 0; } /* signinglex_destroy is for both reentrant and non-reentrant scanners. */ int signinglex_destroy (yyscan_t yyscanner) { struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* Pop the buffer stack, destroying each element. */ while(YY_CURRENT_BUFFER){ signing_delete_buffer(YY_CURRENT_BUFFER ,yyscanner ); YY_CURRENT_BUFFER_LVALUE = NULL; signingpop_buffer_state(yyscanner); } /* Destroy the stack itself. */ signingfree(yyg->yy_buffer_stack ,yyscanner); yyg->yy_buffer_stack = NULL; /* Destroy the start condition stack. */ signingfree(yyg->yy_start_stack ,yyscanner ); yyg->yy_start_stack = NULL; /* Reset the globals. This is important in a non-reentrant scanner so the next time * signinglex() is called, initialization will occur. */ yy_init_globals( yyscanner); /* Destroy the main struct (reentrant only). */ signingfree ( yyscanner , yyscanner ); yyscanner = NULL; return 0; } /* * Internal utility routines. */ #ifndef yytext_ptr static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner) { register int i; for ( i = 0; i < n; ++i ) s1[i] = s2[i]; } #endif #ifdef YY_NEED_STRLEN static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) { register int n; for ( n = 0; s[n]; ++n ) ; return n; } #endif void *signingalloc (yy_size_t size , yyscan_t yyscanner) { return (void *) malloc( size ); } void *signingrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) { /* The cast to (char *) in the following accommodates both * implementations that use char* generic pointers, and those * that use void* generic pointers. It works with the latter * because both ANSI C and C++ allow castless assignment from * any pointer type to void*, and deal with argument conversions * as though doing an assignment. */ return (void *) realloc( (char *) ptr, size ); } void signingfree (void * ptr , yyscan_t yyscanner) { free( (char *) ptr ); /* see signingrealloc() for (char *) cast */ } #define YYTABLES_NAME "yytables" #line 69 "./src/proxy/signing_policy_lex.l" canl-c-3.0.0/src/proxy/namespaces_parse.y0000644000015500017500000000615313017332513020123 0ustar tomcat6jenkins%{ /********************************************************************* * * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it * * Copyright (c) Members of the EGEE Collaboration. 2004-2010. * See http://www.eu-egee.org/partners/ for details on the copyright holders. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Parts of this code may be based upon or even include verbatim pieces, * originally written by other people, in which case the original header * follows. * *********************************************************************/ #include "config.h" #include #include #include #include "parsertypes.h" #include "listfunc.h" char **parse_subjects(char *string); void namespaceserror(void *policies, void *scanner, char const *msg); extern int namespaceslex(void *, void *scanner); %} %error-verbose %pure-parser %name-prefix="namespaces" %parse-param {struct policy ***policies} %parse-param {void *scanner} %lex-param {void *scanner} %union{ char *string; struct condition *cond; struct policy *policy; int integer; } %token SUBJECT %token TO %token SELF %token PERMIT %token DENY %token SUBJECT_WORD %token ISSUER %type rule %type condition %type permit_or_deny %% eacl: rule { *policies = (struct policy**)listadd((char**)*policies, (char*)($1)); } | eacl rule { *policies = (struct policy**)listadd((char**)*policies, (char*)($2)); } ; rule: TO ISSUER SUBJECT condition { $$ = (struct policy *)calloc(1, sizeof(struct policy)); if ($$) { $$->self = 0; $$->caname = strdup($3); $$->conds = (struct condition**)listadd(NULL, (char*)($4)); $$->type = TYPE_NAMESPACE; } } | TO ISSUER SELF condition { $$ = (struct policy *)calloc(1, sizeof(struct policy)); if ($$) { $$->self = 1; $$->caname = NULL; $$->conds = (struct condition**)listadd(NULL, (char*)($4)); $$->type = TYPE_NAMESPACE; } } ; condition: permit_or_deny SUBJECT_WORD SUBJECT { $$ = (struct condition *)calloc(1, sizeof(struct condition)); if ($$) { $$->positive = $1; $$->original = strdup($3); $$->subjects = listadd(NULL, $$->original); if (!$$->subjects) { free($$->original); free($$); $$ = NULL; } } } ; permit_or_deny: PERMIT { $$ = 1; } | DENY { $$ = 0; } ; %% #if 0 int main() { namespacesdebug = 1; struct policy **arg = NULL; void *scanner=NULL; namespaceslex_init(&scanner); namespacesset_debug(1, scanner); return namespacesparse(&arg, scanner); } #endif void namespaceserror(UNUSED(void *policies), UNUSED(void *scanner), UNUSED(char const *msg)) { } canl-c-3.0.0/src/proxy/signing_policy_parse.y0000644000015500017500000001114713017332513021020 0ustar tomcat6jenkins%{ /********************************************************************* * * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it * Valerio Venturi - Valerio.Venturi@cnaf.infn.it * * Copyright (c) Members of the EGEE Collaboration. 2004-2010. * See http://www.eu-egee.org/partners/ for details on the copyright holders. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Parts of this code may be based upon or even include verbatim pieces, * originally written by other people, in which case the original header * follows. * *********************************************************************/ #include "config.h" #include #include #include #include #include "parsertypes.h" #include "listfunc.h" char **parse_subjects(char *string); void signingerror(void *policies, void *scanner, char const *msg); extern int signinglex(void *, void *scanner); %} %error-verbose %pure-parser %name-prefix="signing" %parse-param {struct policy ***policies} %parse-param {void *scanner} %lex-param {void *scanner} %union{ char *string; struct condition *cond; struct policy *policy; void *array; } %token SUBJECTS %token COND_SUBJECTS %token COND_BANNED %token GLOBUS %token POS_RIGHTS %token NEG_RIGHTS %token CA_SIGN %token ACCESS_ID_CA %token ACCESS_ID_ANYBODY %token X509 %type eacl_entry %type access_identity %type realcondition %type restrictions %type access_identities %% eacl: eacl_entry { *policies = (struct policy **)listadd((char**)(*policies), (char*)($1)); } | eacl eacl_entry { *policies = (struct policy **)listadd((char**)(*policies), (char*)($2)); } eacl_entry: access_identities POS_RIGHTS GLOBUS CA_SIGN restrictions { if ($1) { $$->conds = (struct condition**)($5); } $$ = $1; } | access_identities NEG_RIGHTS GLOBUS CA_SIGN restrictions { /* Ignore this. Globus does. */ free($1); $$ = NULL; } access_identities: access_identity { $$ = $1; } restrictions: realcondition { $$ = listadd(NULL, (char*)($1)); } | realcondition restrictions { $$ = listadd($2, (char*)($1)); } access_identity: ACCESS_ID_CA X509 SUBJECTS { $$ = (struct policy *)calloc(1, sizeof(struct policy)); if ($$) { char **subjects = parse_subjects($3); $$->caname = strdup(subjects[0]); free(subjects); $$->type = TYPE_SIGNING; } if ($$ && !$$->caname) { free($$); $$ = NULL; } } | ACCESS_ID_ANYBODY { $$ = (struct policy *)calloc(1, sizeof(struct policy)); } realcondition: COND_SUBJECTS GLOBUS SUBJECTS { $$ = (struct condition*)malloc(sizeof(struct condition)); if ($$) { $$->positive = 1; $$->original = strdup($3); $$->subjects = parse_subjects($$->original); if (!$$->subjects) { free($$->original); free($$); $$ = NULL; } } } | COND_BANNED GLOBUS SUBJECTS { $$ = (struct condition*)malloc(sizeof(struct condition)); if ($$) { $$->positive = 0; $$->original = strdup($3); $$->subjects = parse_subjects($$->original); if (!$$->subjects) { free($$->original); free($$); $$ = NULL; } } } ; %% char **parse_subjects(char *string) { char **list = NULL; char divider; if (!string) return NULL; do { divider = string[0]; if (divider == '\'' || divider == '"') { char *end = strchr(string + 1, divider); if (!end) return list; *end = '\0'; list = (char**)listadd(list, string+1); string = ++end; while (isspace(*string)) string++; } else if (divider == '\0') break; else { list = (char**)listadd(list, string); string += strlen(string); } } while (string && string[0] != '\0'); return list; } #if 0 int main() { signingdebug = 1; void **arg = NULL; void *scanner=NULL; signinglex_init(&scanner); signingset_debug(1, scanner); return signingparse(arg, scanner); } #endif void signingerror(UNUSED(void *policies), UNUSED(void *scanner), UNUSED(char const *msg)) { } canl-c-3.0.0/src/proxy/namespaces_lex.l0000644000015500017500000000346613017332513017570 0ustar tomcat6jenkins%{ /********************************************************************* * * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it * * Copyright (c) Members of the EGEE Collaboration. 2004-2010. * See http://www.eu-egee.org/partners/ for details on the copyright holders. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Parts of this code may be based upon or even include verbatim pieces, * originally written by other people, in which case the original header * follows. * *********************************************************************/ #include "config.h" #include #include #include #include "parsertypes.h" #include "namespaces_parse.h" %} %x SINGLE_QUOTED %x DOUBLE_QUOTED %option reentrant %option noyywrap %option prefix="namespaces" %option bison-bridge %% \#.* /* comment. Ignore */ \' BEGIN(SINGLE_QUOTED); [^']*\' yytext[strlen(yytext)-1]='\0'; yylval_param->string = yytext; BEGIN(INITIAL); return SUBJECT; \" BEGIN(DOUBLE_QUOTED); [^"]*\" yytext[strlen(yytext)-1]='\0'; yylval_param->string = yytext; BEGIN(INITIAL); return SUBJECT; (?i:TO) return TO; (?i:ISSUER) return ISSUER; (?i:PERMIT) return PERMIT; (?i:DENY) return DENY; (?i:SELF) return SELF; (?i:SUBJECT) return SUBJECT_WORD; \\$ \n . %% canl-c-3.0.0/src/proxy/signing_policy_lex.l0000644000015500017500000000415013017332513020455 0ustar tomcat6jenkins%{ /********************************************************************* * * Authors: Vincenzo Ciaschini - Vincenzo.Ciaschini@cnaf.infn.it * * Copyright (c) Members of the EGEE Collaboration. 2004-2010. * See http://www.eu-egee.org/partners/ for details on the copyright holders. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Parts of this code may be based upon or even include verbatim pieces, * originally written by other people, in which case the original header * follows. * *********************************************************************/ #include "config.h" #include #include #include #include "parsertypes.h" #include "signing_policy_parse.h" %} %x SINGLE_QUOTED %x DOUBLE_QUOTED %option reentrant %option noyywrap %option prefix="signing" %option bison-bridge %% #.* /* ignore comments */ \' BEGIN(SINGLE_QUOTED); [^']*\' yytext[strlen(yytext)-1]='\0'; yylval_param->string = yytext; BEGIN(INITIAL); return SUBJECTS; \" BEGIN(DOUBLE_QUOTED); [^"]*\" yytext[strlen(yytext)-1]='\0'; yylval_param->string = yytext; BEGIN(INITIAL); return SUBJECTS; cond_subjects return COND_SUBJECTS; cond_banned_subjects return COND_BANNED; globus return GLOBUS; pos_rights return POS_RIGHTS; neg_rights return NEG_RIGHTS; CA\:sign return CA_SIGN; access_id_CA return ACCESS_ID_CA; access_id_ANYBODY return ACCESS_ID_ANYBODY; X509 return X509; \n . canl-c-3.0.0/Makefile0000644000015500017500000001232413017332513014105 0ustar tomcat6jenkinstop_srcdir=. stagedir=$(shell pwd) package=canl-c PREFIX= prefix=/usr libdir=lib default: all -include Makefile.inc -include ${top_srcdir}/project/version.properties version=${module.version} docdir?=${prefix}/share/doc/${package}-${version} VPATH=${top_srcdir}/src/:${top_srcdir}/src/proxy/:${top_srcdir}/examples:${top_srcdir}/doc/src KPATH = TEXINPUTS=".:${top_srcdir}/doc/src//:" KPATHBIB = BIBINPUTS=".:$(VPATH)//:" LIBCARES_LIBS?=-lcares LIBSSL_LIBS?=-lssl -lcrypto LIBDL_LIBS?=-ldl CC=gcc YACC=bison -y LEX=flex PDFLATEX = $(KPATH) pdflatex BIBTEX = $(KPATHBIB) bibtex COMPILE=libtool --mode=compile ${CC} ${CFLAGS} LINK=libtool --mode=link ${CC} ${LDFLAGS} INSTALL=libtool --mode=install install SOURCES=\ doc/src/*.cls doc/src/*.tex doc/src/images/*.pdf \ examples/*.c \ src/canl_error_* src/*.c src/*.h src/*.pl \ src/proxy/*.c src/proxy/*.h src/proxy/*.in src/proxy/*.y src/proxy/*.l \ Makefile README SOURCES_EXEC=src/*.pl CFLAGS_LIB=-fPIC -I${top_srcdir}/src ${LIBCARES_CFLAGS} ${LIBSSL_CFLAGS} -I. LFLAGS_LIB=${LIBCARES_LIBS} ${LIBSSL_LIBS} ${LIBDL_LIBS} -lpthread CFLAGS_CLI=-I${top_srcdir}/src -I. LFLAGS_CLI=-L. -lcanl_c CFLAGS_SER=-Wall -g -I${top_srcdir}/src -I. LFLAGS_SER=-L. -lcanl_c CFLAGS_PRX=-Wall -g -I${top_srcdir}/src -I. LFLAGS_PRX=-L. -lcanl_c CFLAGS_DEL=-Wall -g -I${top_srcdir}/src -I. LFLAGS_DEL=-L. -lcanl_c -lcrypto HEAD_CANL=canl.h canl_locl.h canl_err.h canl_cred.h canl_ssl.h canl_mech_ssl.h canl_ocsp.h SRC_CLI=canl_sample_client.c HEAD_CLI=canl.h OBJ_CLI=canl_sample_client.lo SRC_SER=canl_sample_server.c HEAD_SER=canl.h OBJ_SER=canl_sample_server.lo SRC_PRX=grid-proxy-init.c HEAD_PRX=canl.h canl_cred.h OBJ_PRX=canl_proxy_init.lo SRC_DEL=delegation.c HEAD_DEL=canl.h canl_cred.h OBJ_DEL=canl_delegation.lo CFLAGS:=-Wall -g -I${top_srcdir}/src/proxy -I. ${CFLAGS} LIBCANL=libcanl_c.la # In order to use libtool versioning correcty, we must have: # # current = major + minor + offset # revision = patch # age = minor # # where offset is a sum of maximal released minor's of all previous major's # # counted minors: 1.0, 2.1 offset=1 version_info:=-version-info ${shell \ perl -e '$$,=":"; @F=split "\\.","${version}"; print $$F[0]+$$F[1]+${offset},$$F[2],$$F[1]' } major:=${shell \ perl -e '$$,=":"; @F=split "\\.","${version}"; print $$F[0]+$$F[1]+${offset}' } all: ${LIBCANL} server client proxy delegation doc doc: canl.pdf ${LIBCANL}:\ canl_err_desc.lo canl.lo canl_err.lo canl_dns.lo canl_ssl.lo \ canl_cert.lo canl_cred.lo canl_ocsp.lo\ doio.lo evaluate.lo list.lo normalize.lo \ scutils.lo sslutils.lo data.lo namespaces_parse.lo namespaces_lex.lo\ signing_policy_parse.lo signing_policy_lex.lo ${LINK} -rpath ${stagedir}${prefix}/${libdir} ${version_info} $+ ${LFLAGS_LIB} -o $@ %.c: %.y -mkdir $* (cd $*; \ ${YACC} -d ${YFLAGS} ../$< && \ mv y.tab.c ../$*.c && \ mv y.tab.h ../$*.h) rm -r $* %.c: %.l # ${LEX} -t $< > $@ cp `echo $< | sed -e 's/\.l$$/.c.in/'` $@ %.lo: %.c ${HEAD_CANL} ${COMPILE} -c $< ${CFLAGS_LIB} -o $@ %.pdf: %.tex $(PDFLATEX) $< # $(BIBTEX) `basename $< .tex` $(PDFLATEX) $< $(PDFLATEX) $< canl.tex: ver.tex client: ${OBJ_CLI} ${LINK} $< ${LFLAGS_CLI} -o $@ ${OBJ_CLI}: ${SRC_CLI} ${HEAD_CLI} ${LIBCANL} ${COMPILE} -c ${top_srcdir}/examples/${SRC_CLI} ${CFLAGS_CLI} -o $@ server: ${OBJ_SER} ${LINK} $< ${LFLAGS_SER} -o $@ ${OBJ_SER}: ${SRC_SER} ${HEAD_SER} ${LIBCANL} ${COMPILE} -c ${top_srcdir}/examples/${SRC_SER} ${CFLAGS_SER} -o $@ proxy: ${OBJ_PRX} ${LINK} $< ${LFLAGS_PRX} -o $@ ${OBJ_PRX}: ${SRC_PRX} ${HEAD_PRX} ${LIBCANL} ${COMPILE} -c ${top_srcdir}/examples/${SRC_PRX} ${CFLAGS_PRX} -o $@ delegation: ${OBJ_DEL} ${LINK} $< ${LFLAGS_DEL} -o $@ ${OBJ_DEL}: ${SRC_DEL} ${HEAD_DEL} ${LIBCANL} ${COMPILE} -c ${top_srcdir}/examples/${SRC_DEL} ${CFLAGS_DEL} -o $@ canl_err.h: canl_error_codes ${top_srcdir}/src/gen_err_codes.pl < $^ > $@ canl_err_desc.c: canl_error_codes canl_error_desc ${top_srcdir}/src/gen_err_desc.pl $^ > $@ ver.tex: printf "\134def\134version{${version}}\n" > ver.tex check: install: all mkdir -p ${DESTDIR}${PREFIX}${prefix}/bin mkdir -p ${DESTDIR}${PREFIX}${prefix}/${libdir} mkdir -p ${DESTDIR}${PREFIX}${prefix}/include mkdir -p ${DESTDIR}${PREFIX}${docdir} ${INSTALL} -m 755 server ${DESTDIR}${PREFIX}${prefix}/bin/emi-canl-server ${INSTALL} -m 755 client ${DESTDIR}${PREFIX}${prefix}/bin/emi-canl-client ${INSTALL} -m 755 proxy \ ${DESTDIR}${PREFIX}${prefix}/bin/emi-canl-proxy-init ${INSTALL} -m 755 delegation \ ${DESTDIR}${PREFIX}${prefix}/bin/emi-canl-delegation ${INSTALL} -m 755 ${LIBCANL} ${DESTDIR}${PREFIX}${prefix}/${libdir} ${INSTALL} -m 644 ${top_srcdir}/src/canl.h \ ${top_srcdir}/src/canl_ssl.h canl_err.h \ ${top_srcdir}/src/canl_cred.h \ ${DESTDIR}${PREFIX}${prefix}/include ${INSTALL} -m 644 canl.pdf ${DESTDIR}${PREFIX}${docdir} ${INSTALL} -m 644 README ${DESTDIR}${PREFIX}${docdir} stage: all $(MAKE) install PREFIX=${stagedir} clean: rm -rfv *.o *.lo ${LIBCANL} .libs client server proxy delegation \ *.c *.h lex.backup stage \ canl.aux canl.log canl.pdf canl.out canl.toc ver.tex \ canl.bbl canl.blg rm -rvf dist ${package}-*.tar.gz distclean: rm -rvf Makefile.inc config.status project/changelog *.spec debian/ .PHONY: default all doc check install stage clean distclean dist distcheck canl-c-3.0.0/README0000644000015500017500000000141313017332513013322 0ustar tomcat6jenkinsCommon Authentication Library (caNl) was designed to provide common security layer support in grid applications. It is largely based on existing code (VOMS, LB). Its simple API can be devided by functionality into two parts: * caNl Main API is used to establish (secure) client-server connection with one or both sides authenticated, send or receive data. It is not directly dependent on any specific cryptography toolkit (SSL implementation). It is also internally plugin-based and therefore support for other security mechanisms can be added in future. * caNl Certificate API enables certificate and proxy management, e.g., proxy creation, signing, etc. One may think of the Certificate API as the second level of the Main API Project home: https://github.com/CESNET/canl-c canl-c-3.0.0/configure0000755000015500017500000013673413017332513014370 0ustar tomcat6jenkins#!/usr/bin/perl # WARNING: Don't edit this file unless it is the master copy in org.glite.lb # # For the purpose of standalone builds of lb/jobid/lbjp-common components # it is copied on tagging # $Header$ # # Copyright (c) Members of the EGEE Collaboration. 2004-2010. # See http://www.eu-egee.org/partners/ for details on the copyright holders. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # use Getopt::Long; use POSIX qw(locale_h strftime); my $default_url = 'http://scientific.zcu.cz/emi/${moduleName}'; my $pwd = `pwd`; chomp $pwd; my $prefix = '/usr'; my $stagedir = undef; my $root = $pwd.'/stage'; my $sysroot = ''; my $sysconfdir; my $localstatedir; my $os_type; my $staged; my $module='canl.c'; my $thrflavour = ''; my $nothrflavour = ''; my $mode = 'build'; my $help = 0; my $listmodules; my ($version, $force_version); my $lb_tag = ''; my $lbjp_tag = ''; my $jp_tag = ''; my $jobid_tag = ''; my $libdir = getlibdir(); my $project = 'emi'; my $project_version; my (%projects, %project); my $debug = 0; my $url = $default_url; my $url_source; my $docdir; my $mysqlconfdir; my $sysdefaultdir; my $pkg_config_env = (defined $ENV{PKG_CONFIG_PATH}) ? "$ENV{PKG_CONFIG_PATH}:" : ''; my @nodes = qw/client server logger logger-msg nagios utils client-java doc ws-test db jpprimary jpindex jpclient harvester lb px proxyrenewal canl/; my @default_nodes = qw/lb px proxyrenewal nagios canl client-java/; my %enable_nodes; my %disable_nodes; my %default_nodes; @default_nodes{@default_nodes} = (1) x ($#default_nodes + 1); my %package = ( 'maintainer' => 'CESNET Product Teams ', 'uploaders' => 'František Dvořák ', 'url' => 'http://glite.cern.ch', ); # key: internal package name (arguments, ...) # 'pkg': pkg-config name # 'prefix': used when pkg-config fails my %externs = ( cares => { prefix => '/opt/c-ares', pkg => 'libcares' }, classads => { prefix=> '/usr', pkg => 'classads' }, cppunit => { prefix=> '/usr', pkg => 'cppunit' }, expat => { prefix=> '/usr', pkg => 'expat' }, globus => { prefix=> '/opt/globus', pkg => 'globus-gssapi-gsi' }, 'myproxy-devel' => { prefix=> '/opt/globus', pkg => 'myproxy' }, 'myproxy-server' => { prefix=> '', }, 'myproxy-admin' => { prefix=> '', }, gsoap => { prefix=> '/usr', pkg => 'gsoap' }, gsoapxx => { prefix=> '/usr', pkg => 'gsoap++' }, mysql => { prefix=> '/usr' }, 'mysql-devel' => { prefix=> '' }, 'mysql-server' => { prefix => '' }, voms => { prefix => '/usr', pkg => 'voms-2.0' }, gridsite => { prefix => '/usr', pkg => 'gridsite-openssl' }, trustmanager => { prefix => '/usr' }, trustmanager_axis => { prefix => '/usr' }, utiljava => { prefix=> '/opt/glite' }, ant => { prefix=> '/usr' }, jdk => { prefix=> '/usr/java/latest', locations => [ '/usr/lib/jvm/java', '/usr/lib/jvm/default-java', '/usr/java/latest' ], }, libtar => { prefix=> '/usr' }, axis => { prefix=> '/usr' }, log4c => { prefix=> '/usr' }, postgresql => { prefix=> '/usr' }, activemq => { prefix=>'/opt/activemq-cpp-library', pkg => 'activemq-cpp' }, crypto => { prefix => '/usr', pkg => 'libcrypto', }, ); my %jar = ( 'jakarta-commons-codec' => '/usr/share/java/commons-codec.jar', 'jakarta-commons-lang' => '/usr/share/java/commons-lang.jar', ); my %glite_prefix; my %need_externs; my %need_externs_type; my %need_jars; my %extrafull; my %extranodmod; my %deps; my %deps_type; my %buildroot; # # modules of the subsystems # # additional modules from $project{modules} are automatically added # my %lbmodules = ( 'lb' => [ qw/client client-java common doc logger server state-machine types utils ws-interface ws-test harvester yaim logger-msg nagios client-devel client-progs common-devel logger-devel state-machine-devel/], 'lbjp-common' => [qw/db log maildir server-bones trio jp-interface gss gsoap-plugin db-devel log-devel maildir-devel server-bones-devel trio-devel jp-interface-devel gss-devel gsoap-plugin-devel/], 'jobid' => [qw/api-c api-c-devel api-cpp api-cpp-devel api-java/], 'jp' => [ qw/client doc index primary server-common ws-interface/ ], 'gridsite' => [ qw/apache libs commands core devel services service-clients/ ], 'px' => [ qw/proxyrenewal myproxy-yaim proxyrenewal-devel proxyrenewal-progs/ ], 'canl' => [ qw/c c-devel/ ], ); # # sub-packages # # modify %lbmodules, %deps_aux, %extrafull, and %properties accodingly # my %subpackages = ( 'jobid.api-c-devel' => 'jobid.api-c', 'jobid.api-cpp-devel' => 'jobid.api-cpp', 'lbjp-common.db-devel' => 'lbjp-common.db', 'lbjp-common.gsoap-plugin-devel' => 'lbjp-common.gsoap-plugin', 'lbjp-common.gss-devel' => 'lbjp-common.gss', 'lbjp-common.jp-interface-devel' => 'lbjp-common.jp-interface', 'lbjp-common.log-devel' => 'lbjp-common.log', 'lbjp-common.maildir-devel' => 'lbjp-common.maildir', 'lbjp-common.server-bones-devel' => 'lbjp-common.server-bones', 'lbjp-common.trio-devel' => 'lbjp-common.trio', 'lb.client-progs' => 'lb.client', 'lb.client-devel' => 'lb.client', 'lb.common-devel' => 'lb.common', 'lb.logger-devel' => 'lb.logger', 'lb.state-machine-devel' => 'lb.state-machine', 'px.proxyrenewal-devel' => 'px.proxyrenewal', 'px.proxyrenewal-progs' => 'px.proxyrenewal', 'canl.c-devel' => 'canl.c', 'gridsite.apache' => 'gridsite.core', 'gridsite.shared' => 'gridsite.core', 'gridsite.commands' => 'gridsite.core', 'gridsite.devel' => 'gridsite.core', 'gridsite.libs' => 'gridsite.core', 'gridsite.services' => 'gridsite.core', 'gridsite.service-clients' => 'gridsite.core', ); my @opts = ( 'prefix:s' => \$prefix, 'staged=s' => \$staged, 'module=s' => \$module, 'thrflavour:s' => \$thrflavour, 'nothrflavour:s' => \$nothrflavour, 'mode=s' => \$mode, 'listmodules=s' => \$listmodules, 'version=s' => \$force_version, 'stage=s' => \$stagedir, 'root:s' => \$root, 'sysroot:s' => \$sysroot, 'sysconfdir=s' => \$sysconfdir, 'localstatedir=s' => \$localstatedir, 'os-type=s' => \$os_type, 'lb-tag=s' => \$lb_tag, 'lbjp-common-tag=s' => \$lbjp_tag, 'jp-tag=s' => \$jp_tag, 'jobid-tag=s' => \$jobid_tag, 'canl-tag=s' => \$canl_tag, 'px-tag=s' => \$px_tag, 'help' => \$help, 'libdir=s' => \$libdir, 'project=s' => \$project, 'debug' => \$debug, 'url=s' => \$url, 'url-source=s' => \$url_source, 'docdir=s' => \$docdir, 'mysqlconfdir=s' => \$mysqlconfdir, 'sysdefaultdir=s' => \$sysdefaultdir, ); for (@nodes) { $enable_nodes{$_} = 0; $disable_nodes{$_} = 0; push @opts,"disable-$_",\$disable_nodes{$_}; push @opts,"enable-$_",\$enable_nodes{$_}; } push @opts,"with-$_=s",\$externs{$_}{withprefix} for keys %externs; push @opts,"with-$_=s",\$jar{$_} for keys %jar; my @keeparg = @ARGV; GetOptions @opts or die "Errors parsing command line\n"; $prefix=~s/\/$//; $root=~s/\/$//; $sysroot=~s/\/$//; if (not $sysconfdir) { $sysconfdir = $prefix eq '/usr' ? '/etc' : "$prefix/etc"; } if (not $localstatedir) { $localstatedir = $prefix eq '/usr' ? '/var' : "$prefix/var"; } $sysconfdir=~s/\/$//; $localstatedir=~s/\/$//; if (not $os_type) { $os_type = os_type(); } if (not $url_source) { $url_source = $url; } $url=~s/\/$//; $url_source=~s/\/$//; $externs{'mysql-server'}{prefix}=$externs{mysql}{prefix} if $externs{'mysql-server'}{prefix} eq ''; $externs{'mysql-devel'}{prefix}=$externs{mysql}{prefix} if $externs{'mysql-devel'}{prefix} eq ''; $externs{'gsoapxx'}{prefix}=$externs{gsoap}{prefix} if $externs{'gsoapxx'}{prefix} eq ''; $externs{'mysql-server'}{withprefix}=$externs{mysql}{withprefix} if $externs{'mysql-server'}{withprefix} eq ''; $externs{'mysql-devel'}{wihtprefix}=$externs{mysql}{withprefix} if $externs{'mysql-devel'}{withprefix} eq ''; $externs{'gsoapxx'}{withprefix}=$externs{gsoap}{withprefix} if $externs{'gsoapxx'}{withprefix} eq ''; if ($project =~ /^([^0-9]*)(.*)$/) { $project = $1; $project_version = $2; } %project = %{$projects{$project}}; $project_version = $project{current_version} unless $project_version; if ($project ne 'emi' or $project_version <= 1) { $lbmodules{'gridsite'} = [ qw/apache shared commands core devel services service-clients/ ]; } for $_ (keys %{$project{need_externs_aux}}) { $need_externs_aux{$_} = $project{need_externs_aux}{$_}; } for my $ext (keys %need_externs_aux) { for (@{$need_externs_aux{$ext}}) { my ($pkg, $type) =/([^:]*)(?::(.*))?/; $type = 'BR' unless ($type); push @{$need_externs{$ext}},$pkg; $need_externs_type{$ext}->{$pkg} = $type; } } if ($project eq 'emi') { $extranodmod{lb} = 'lb.emi-lb'; $extranodmod{px} = 'px.emi-px'; } if ($project ne 'emi' or $project_version <= 2) { $project{modules}{gridsite} = [ qw/slashgrid gsexec/ ]; } for $_ (keys %{$project{modules}}) { push @{$lbmodules{$_}},@{$project{modules}{$_}}; } if ($help) { usage(); exit 0; } if ($listmodules) { my $name_prefix = ($listmodules eq 'gridsite' and $project eq 'glite') ? 'org' : $project{etics_name}; my @m; if (exists $lbmodules{$listmodules}) { @m = map exists $subpackages{$listmodules . '.' . $_} ? "" : "$name_prefix.$listmodules.$_",@{$lbmodules{$listmodules}}; } else { if ($project eq 'emi' and $project_version == 1 and $listmodules ne 'gridsite.core') { # no sub-packages in EMI-1 } else { for my $sub (keys %subpackages) { push @m, $sub if ($subpackages{$sub} eq $listmodules); } } } print map $_ eq "" ? "" : "$_ ", @m; print "\n"; exit 0; } my $en; for (keys %enable_nodes) { $en = 1 if $enable_nodes{$_}; } my $dis; for (keys %disable_nodes) { $dis = 1 if $disable_nodes{$_}; } die "--enable-* and --disable-* are mutually exclusive\n" if $en && $dis; die "--module cannot be used with --enable-* or --disable-*\n" if $module && ($en || $dis); die "$module: unknown module\n" if $module && ! grep $module,@{$lbmodules{lb}},{$lbmodules{jp}}; if ($dis) { for (@nodes) { $enable_nodes{$_} = 1 unless ($disable_nodes{$_} or not $default_nodes{$_}); } } if (!$en && !$dis) { for (@nodes) { $enable_nodes{$_} = 1 if ($default_nodes{$_}) } }; for (keys %enable_nodes) { delete $enable_nodes{$_} unless $enable_nodes{$_}; } $stagedir = $root unless $stagedir; $stagedir=~s/\/$// if ($stagedir); if ($mode eq 'build') { for my $ext (keys %externs) { if (defined $externs{$ext} and defined $externs{$ext}{withprefix}) { $externs{$ext}{prefix} = $externs{$ext}{withprefix}; } elsif (defined $externs{$ext}{pkg}) { my ($flag, $env, $cmd, $ret); my $pkg = $externs{$ext}{pkg}; my $flagname = uc $externs{$ext}{pkg}; $flagname =~ s/-[0-9\.]*$//; $flagname =~ y/-\+/_X/; print "Checking $pkg ... "; $env = "PKG_CONFIG_PATH=$pkg_config_env$stagedir$prefix/$libdir/pkgconfig"; $cmd = "$env pkg-config $pkg --exists >/dev/null"; `$cmd`; $ret = $?; print "('$cmd' => $ret)\n" if ($debug); if ($ret == 0) { $externs{$ext}{prefix}=`$env pkg-config $pkg --variable=prefix`; chomp $externs{$ext}{prefix}; print "$externs{$ext}{prefix}\n"; $flag=`$env pkg-config $pkg --cflags`; $externs{$ext}{flags} .= "${flagname}_CFLAGS=$flag" if ($flag); $flag=`$env pkg-config $pkg --libs`; $externs{$ext}{flags} .= "${flagname}_LIBS=$flag" if ($flag); } else { print "(using default $externs{$ext}{prefix})\n"; } print "\n" if ($debug); } elsif ($ext eq 'jdk') { my $jdk_prefix; print "Looking for some caffein ... "; if (defined($ENV{'JDK_HOME'}) and -f "$ENV{'JDK_HOME'}/include/jni.h") { $jdk_prefix = $ENV{'JDK_HOME'}; print "JDK_HOME=$jdk_prefix\n"; } elsif (defined($ENV{'JAVA_HOME'}) and -f "$ENV{'JAVA_HOME'}/include/jni.h") { $jdk_prefix = $ENV{'JAVA_HOME'}; print "JAVA_HOME=$jdk_prefix\n"; } else { foreach my $i (0..$#{$externs{$ext}{locations}}) { if (-e $externs{$ext}{locations}[$i] and -f "$externs{$ext}{locations}[$i]/include/jni.h") { $jdk_prefix=$externs{$ext}{locations}[$i]; print "(found directory $jdk_prefix)\n"; last; } } print "(using default $externs{$ext}{prefix})\n" unless ($jdk_prefix); } $externs{$ext}{prefix} = $jdk_prefix if ($jdk_prefix); } } } if ($mode eq 'build') { print "Writing config.status\n"; open CONF,">config.status" or die "config.status: $!\n"; for ('JDK_HOME', 'JAVA_HOME', 'PKG_CONFIG_PATH') { print CONF "$_=$ENV{$_} " if (defined $ENV{$_}); } print CONF "$0 @keeparg\n"; close CONF; } my @modules; my %aux; if ($module) { # push @modules,split(/[,.]+/,$module); push @modules,$module; } else { @modules = map(($extranodmod{$_} ? $extranodmod{$_} : 'lb.'.$_),(keys %enable_nodes)); my $n; do { local $"="\n"; $n = $#modules; push @modules,(map @{$deps{$_}},@modules); undef %aux; @aux{@modules} = (1) x ($#modules+1); @modules = keys %aux; } while ($#modules > $n); } @aux{@modules} = (1) x ($#modules+1); delete $aux{$_} for (split /,/,$staged); @modules = keys %aux; mode_build() if $mode eq 'build'; mode_checkout() if $mode eq 'checkout'; sub mode_build { print "\nBuilding modules: @modules\n"; print "Mode: "; print $module ? "single module" : "multiple modules"; print "\n"; my @ext = map @{$need_externs{$_}},@modules; my @myjars = map @{$need_jars{$_}},@modules; undef %aux; @aux{@ext} = 1; @ext = keys %aux; undef %aux; @aux{@myjars} = (1) x ($#myjars+1); @myjars = keys %aux; print "\nRequired externals:\n"; print "\t$_: ".($externs{$_}{prefix}?$externs{$_}{prefix}:'-')."\n" for @ext; print "\t$_: $jar{$_}\n" for @myjars; for (@ext) { if (defined($externs{$_}{flags})) { print "$externs{$_}{flags}"; } }; print "\nThis is a poor-man configure, it's up to you to have sources and externals there\n\n"; mkinc($_) for @modules; if ($module) { print "Not creating summary Makefile\n" if $debug; } else { print "Creating Makefile\n"; open MAK,">Makefile" or die "Makefile: $!\n"; print MAK "all: @modules\n\n"; print MAK "stage: ".(join '-stage ', @modules)."-stage\n\n"; print MAK "clean check install dist distcheck rpm deb:\n"; for (@modules) { my $full = full($_); print MAK "\tcd $full/$buildroot{$_} && \${MAKE} \$@\n" } print MAK "\ndistclean:\n"; for (@modules) { my $full = full($_); print MAK $buildroot{$_} eq '' ? "\tcd $full && \${MAKE} distclean\n" : "\trm -rf $full/$buildroot{$_}\n" } print MAK "\n"; for (@modules) { my %ldeps; undef %ldeps; @ldeps{@{$deps{$_}}} = 1; for my $x (split /,/,$staged) { delete $ldeps{$x}; } my @dnames = $module ? () : keys %ldeps; my $snames = $#dnames == -1 ? '' : join('-stage ', @dnames).'-stage'; my $full = full($_); my $build = $buildroot{$_}; print MAK "$_: @dnames\n\tcd $full/$build && \${MAKE} && \${MAKE} install\n\n"; print MAK "$_-stage: $snames\n\tcd $full/$build && \${MAKE} && \${MAKE} stage\n\n"; } print MAK qq/release-rpm: clean dist distcheck rpm release-deb: clean dist distcheck deb .PHONY: all stage clean check install dist distcheck rpm deb release-rpm release-deb .NOTPARALLEL: /; close MAK; } } sub mode_checkout() { for (@modules) { my $module = $_; my $tag = ""; if ($lb_tag){ for (@{$lbmodules{lb}}){ if ("lb.".$_ eq $module){ $tag = '-r '.$lb_tag; } } } if ($lbjp_tag) { for (@{$lbmodules{'lbjp-common'}}){ if ("lbjp-common.".$_ eq $module){ $tag = '-r '.$lbjp_tag; } } } if ($jp_tag){ for (@{$lbmodules{'jp'}}){ if ("jp.".$_ eq $module){ $tag = '-r '.$jp_tag; } } } if ($jobid_tag){ for (@{$lbmodules{jobid}}){ if ("jobid.".$_ eq $module){ $tag = '-r '.$jobid_tag; } } } if ($canl_tag) { for (@{$lbmodules{'canl'}}){ if ("canl.".$_ eq $module){ $tag = '-r '.$canl_tag; } } } if ($px_tag) { for (@{$lbmodules{'px'}}){ if ("px.".$_ eq $module){ $tag = '-r '.$px_tag; } } } #if (grep {"lb.".$_ eq $module} @{$lbmodules{lb}}){ # print "found"; #} $_ = full($_); print "\n*** Checking out $_\n"; system("cvs checkout $tag $_") == 0 or die "cvs checkout $tag $_: $?\n"; } } BEGIN{ %need_externs_aux = ( 'lb.client' => [ qw/cppunit:B classads:B libtool:B globus:B pkgconfig:B/ ], 'lb.common' => [ qw/expat:B cares:B cppunit:B classads:B libtool:B globus:B pkgconfig:B/ ], 'lb.doc' => [ qw/tetex-latex:B texlive-latex-recommended:B texlive-fonts-recommended:B texlive-latex-extra:B/ ], 'lb.logger' => [ qw/cppunit:B libtool:B globus:B pkgconfig:B/ ], 'lb.logger-msg' => [ qw/cppunit:B activemq libtool:B globus:B pkgconfig:B/ ], 'lb.nagios' => [ qw/globus_proxy_utils:R/ ], 'lb.server' => [ qw/globus_essentials:R globus:B expat:B cares mysql-server:R cppunit:B gsoap:B classads:B voms:B gridsite:B bison:B libtool:B libxml2 flex:B pkgconfig:B/ ], 'lb.state-machine' => [ qw/classads:B libtool:B libxslt:B expat:B globus:B pkgconfig:B/ ], 'lb.utils' => [ qw/cppunit:B libtool:B globus:B pkgconfig:B/ ], 'lb.ws-interface' => [ qw/libxslt:B tidy:B/ ], 'lb.ws-test' => [ qw/gsoap:B libtool:B globus:B pkgconfig:B/ ], 'lb.types' => [ qw// ], 'lb.harvester' => [ qw/docbook-utils:B libtool:B globus:B pkgconfig:B/ ], 'lbjp-common.db' => [ qw/mysql-devel:B postgresql:B cppunit:B log4c:B libtool:B pkgconfig:B/ ], 'lbjp-common.log' => [ qw/log4c libtool:B/ ], 'lbjp-common.maildir' => [ qw/libtool:B/ ], 'lbjp-common.server-bones' => [ qw/libtool:B/ ], 'lbjp-common.trio' => [ qw/cppunit:B libtool:B pkgconfig:B/ ], 'lbjp-common.jp-interface' => [ qw/cppunit:B log4c:B libtool:B pkgconfig:B/ ], 'lbjp-common.gss' => [ qw/globus_essentials:R globus:B cares cppunit:B libtool:B pkgconfig:B/ ], 'lbjp-common.gsoap-plugin' => [ qw/cppunit:B globus_essentials:R globus:B cares:B gsoap gsoapxx libtool:B pkgconfig:B/ ], 'jobid.api-c' => [ qw/cppunit:B libtool:B crypto:B pkgconfig:B/ ], 'jobid.api-cpp' => [ qw// ], 'jobid.api-java' => [ qw/ant:B jdk:B/ ], 'jp.client' => [ qw/gsoap libtar globus_essentials:R globus:B pkgconfig:B/ ], 'jp.doc' => [], 'jp.index' => [ qw/gsoap globus_essentials:R globus:B mysql-server:R pkgconfig:B/ ], 'jp.primary' => [ qw/classads:B gsoap libtar globus_essentials:R globus:B mysql-server:R pkgconfig:B/ ], 'jp.server-common' => [], 'jp.ws-interface' => [], 'gridsite.core' => [ qw/httpd-devel:B gsoap:B globus:B curl:B doxygen:B libxml2:B openssl:B doxygen:B pkgconfig:B libtool:B/ ], 'gridsite.commands' => [ qw/curl:R openssl:R/ ], 'gridsite.apache' => [ qw/libxml2:R openssl:R curl:R/ ], 'gridsite.libs' => [ qw/libxml2:R openssl:R/ ], 'gridsite.shared' => [ qw/libxml2:R openssl:R/ ], 'gridsite.devel' => [ qw// ], 'gridsite.slashgrid' => [ qw/curl:R fuse:R/], 'gridsite.services' => [ qw/curl:R gsoap:R/ ], 'gridsite.service-clients' => [ qw/curl:R gsoap:R gsoapxx:R/ ], 'gridsite.gsexec' => [ qw// ], 'gridsite.1.5-compat' => [ qw/httpd-devel:B gsoap:B globus:B curl:B doxygen:B fuse-devel:B libxml2:B openssl:B doxygen:B/ ], 'px.proxyrenewal' => [ qw/globus:B globus_essentials:R myproxy-devel:B voms:B libtool:B pkgconfig:B/ ], 'px.myproxy-config' => [ qw/myproxy-admin:R/ ], # in myproxy-config.spec 'canl.c' => [ qw/cares:B openssl:B libtool:B bison:B flex:B krb5-devel:B pkgconfig:B tetex-latex:B texlive-latex-recommended:B texlive-fonts-recommended:B texlive-latex-extra:/ ], ); %need_jars = ( 'jobid.api-java' => [ qw/jakarta-commons-codec/ ], 'lb.client-java' => [ qw/jakarta-commons-lang/ ], ); for my $jar (keys %need_jars) { for (@{$need_jars{$jar}}) { $need_externs_type{$jar}->{$_} = 'BR'; # XXX } } %deps_aux = ( 'lb.client' => [ qw/ lb.types:B lb.common lbjp-common.trio jobid.api-cpp:B jobid.api-c lbjp-common.gss / ], 'lb.client-java' => [ qw/ lb.types:B lb.ws-interface:B jobid.api-java / ], 'lb.common' => [ qw/ jobid.api-cpp:B jobid.api-c lb.types:B lbjp-common.trio lbjp-common.gss / ], 'lb.doc' => [ qw/lb.types:B/ ], 'lb.logger' => [ qw/ lbjp-common.trio lbjp-common.log jobid.api-c lb.common lbjp-common.gss / ], 'lb.logger-msg' => [ qw/ lb.logger:B / ], 'lb.nagios' => [ qw/ lb.client:R lb.ws-test:R lb.utils:R / ], 'lb.server' => [ qw/ lb.ws-interface lb.types:B lb.common lb.state-machine lb.utils:R lbjp-common.db lbjp-common.server-bones lbjp-common.trio lbjp-common.maildir lbjp-common.log jobid.api-c lbjp-common.gsoap-plugin lbjp-common.gss / ], 'lb.state-machine' => [ qw/lb.types:B lb.common lbjp-common.jp-interface lbjp-common.gss/ ], 'lb.utils' => [ qw/ lbjp-common.jp-interface jobid.api-c lbjp-common.trio lbjp-common.maildir lb.client lb.state-machine lb.types:B / ], 'lb.ws-test' => [ qw/lbjp-common.gsoap-plugin lb.ws-interface:B/ ], 'lb.ws-interface' => [ qw/lb.types:B/ ], 'lb.types' => [ qw// ], 'lb.harvester' => [ qw/ jobid.api-c lbjp-common.trio lbjp-common.db lb.common lb.client lbjp-common.gss lbjp-common.log / ], 'lb.yaim' => [ qw// ], 'lb.glite-LB' => [ qw/ lb.logger:R lb.server:R lb.utils:R lb.doc:R lb.ws-test:R lb.harvester:R lb.yaim:R lb.logger-msg:R / ], 'lb.emi-lb' => [ qw/ lb.logger:R lb.server:R lb.utils:R lb.doc:R lb.ws-test:R lb.harvester:R lb.yaim:R lb.logger-msg:R / ], 'lbjp-common.db' => [ qw/lbjp-common.trio lbjp-common.log/ ], 'lbjp-common.maildir' => [ qw// ], 'lbjp-common.log' => [ qw// ], 'lbjp-common.server-bones' => [ qw/lbjp-common.log/ ], 'lbjp-common.trio' => [ qw// ], 'lbjp-common.gss' => [ qw// ], 'lbjp-common.gsoap-plugin' => [ qw/lbjp-common.gss/ ], 'jobid.api-c' => [ qw// ], 'jobid.api-cpp' => [ qw/jobid.api-c/ ], 'jobid.api-java' => [ qw// ], 'lbjp-common.jp-interface' => [ qw/lbjp-common.trio lbjp-common.db jobid.api-c/ ], 'jp.client' => [ qw/ jp.ws-interface lbjp-common.jp-interface lbjp-common.maildir jobid.api-c lbjp-common.gsoap-plugin / ], 'jp.doc' => [ qw// ], 'jp.index' => [ qw/ jp.server-common jp.ws-interface lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones lbjp-common.gsoap-plugin / ], 'jp.primary' => [ qw/ jobid.api-c jp.server-common jp.ws-interface lb.state-machine lbjp-common.jp-interface lbjp-common.trio lbjp-common.db lbjp-common.server-bones lbjp-common.gsoap-plugin / ], 'jp.server-common' => [ qw/ lbjp-common.jp-interface lbjp-common.db / ], 'jp.ws-interface' => [ qw// ], 'gridsite.core' => [ qw/canl.c:B/ ], 'gridsite.commands' => [ qw/gridsite.core:B/ ], 'gridsite.apache' => [ qw/gridsite.core:B/ ], 'gridsite.libs' => [ qw/gridsite.core:B / ], 'gridsite.shared' => [ qw/gridsite.core:B / ], 'gridsite.devel' => [ qw/gridsite.core:B/ ], 'gridsite.slashgrid' => [ qw/gridsite.core:B/], 'gridsite.services' => [ qw/gridsite.core:B/ ], 'gridsite.service-clients' => [ qw/gridsite.core:B/ ], 'gridsite.gsexec' => [ qw/gridsite.core:B/ ], 'px.proxyrenewal' => [ qw// ], 'px.glite-PX' => [qw/px.myproxy-yaim:R/], 'px.emi-px' => [qw/px.myproxy-yaim:R/], 'px.myproxy-yaim' => [ qw// ], 'px.myproxy-config' => [], 'canl.c' => [], # sub-packages (virtual ETICS components depending on the main) 'jobid.api-c-devel' => [ qw/jobid.api-c:B/ ], 'jobid.api-cpp-devel' => [ qw/jobid.api-cpp:B/ ], 'lbjp-common.db-devel' => [ qw/lbjp-common.db:B/ ], 'lbjp-common.gsoap-plugin-devel' => [ qw/lbjp-common.gsoap-plugin:B/ ], 'lbjp-common.gss-devel' => [ qw/lbjp-common.gss:B/ ], 'lbjp-common.jp-interface-devel' => [ qw/lbjp-common.jp-interface:B/ ], 'lbjp-common.log-devel' => [ qw/lbjp-common.log:B/ ], 'lbjp-common.maildir-devel' => [ qw/lbjp-common.maildir:B/ ], 'lbjp-common.server-bones-devel' => [ qw/lbjp-common.server-bones:B/ ], 'lbjp-common.trio-devel' => [ qw/lbjp-common.trio:B/ ], 'lb.client-progs' => [ qw/lb.client:B/ ], 'lb.client-devel' => [ qw/lb.client:B/ ], 'lb.common-devel' => [ qw/lb.common:B/ ], 'lb.logger-devel' => [ qw/lb.logger:B/ ], 'lb.state-machine-devel' => [ qw/lb.state-machine:B/ ], 'px.proxyrenewal-devel' => [ qw/px.proxyrenewal:B/ ], 'px.proxyrenewal-progs' => [ qw/px.proxyrenewal:B/ ], 'canl.c-devel' => [ qw/canl.c:B/ ], ); for my $ext (keys %deps_aux) { for (@{$deps_aux{$ext}}) { /([^:]*)(?::(.*))?/; push @{$deps{$ext}},$1; my $type = $2 ? $2 : 'BR'; $deps_type{$ext}->{$1} = $type; } } %extrafull = ( gridsite=>'org.gridsite.core', 'canl.c' => 'emi.canl.canl-c', 'canl.c-devel' => 'emi.canl.canl-c', 'jobid.api-c-devel' => 'org.glite.jobid.api-c', 'jobid.api-cpp-devel' => 'org.glite.jobid.api-cpp', 'lbjp-common.db-devel' => 'org.glite.lbjp-common.db', 'lbjp-common.gsoap-plugin-devel' => 'org.glite.lbjp-common.gsoap-plugin', 'lbjp-common.gss-devel' => 'org.glite.lbjp-common.gss', 'lbjp-common.jp-interface-devel' => 'org.glite.lbjp-common.jp-interface', 'lbjp-common.log-devel' => 'org.glite.lbjp-common.log', 'lbjp-common.maildir-devel' => 'org.glite.lbjp-common.maildir', 'lbjp-common.server-bones-devel' => 'org.glite.lbjp-common.server-bones', 'lbjp-common.trio-devel' => 'org.glite.lbjp-common.trio', 'lb.client-devel' => 'org.glite.lb.client', 'lb.client-progs' => 'org.glite.lb.client', 'lb.common-devel' => 'org.glite.lb.common', 'lb.logger-devel' => 'org.glite.lb.logger', 'lb.state-machine-devel' => 'org.glite.lb.state-machine', 'px.proxyrenewal-devel' => 'org.glite.px.proxyrenewal', 'px.proxyrenewal-progs' => 'org.glite.px.proxyrenewal', ); #( java => 'client-java' ); %extranodmod = ( db => 'lbjp-common.db', jpprimary => 'jp.primary', jpindex => 'jp.index', jpclient => 'jp.client', lb => 'lb.glite-LB', px => 'px.glite-PX', proxyrenewal => 'px.proxyrenewal', canl => 'canl.c', ); %obsoletes = ( 'lb.yaim' => [ qq/glite-yaim-lb/ ], 'px.proxyrenewal' => [ qq/glite-security-proxyrenewal/ ], 'px.myproxy-yaim' => [ qq/glite-yaim-myproxy/ ], 'px.myproxy-config' => [ qq/myproxy-config/ ], # in myproxy-config.spec 'lbjp-common.gss' => [ qq/glite-security-gss/ ], 'lbjp-common.gsoap-plugin' => [ qq/glite-security-gsoap-plugin/ ], ); %conflicts = ( ); %provides = ( 'lbjp-common.gss' => [ qq/glite-security-gss/ ], 'lbjp-common.gsoap-plugin' => [ qq/glite-security-gsoap-plugin/ ], 'lb.nagios' => [ qq/glite-lb-nagios-plugins/ ], ); %cvs_prefix = ( 'lb' => 'org.glite', 'jp' => 'org.glite', 'jobid' => 'org.glite', 'lbjp-common' => 'org.glite', 'gridsite' => 'org', 'px' => 'org.glite', 'canl' => 'emi', ); %cvs_tag_prefix = ( 'lb' => 'glite-', 'jp' => 'glite-', 'jobid' => 'glite-', 'lbjp-common' => 'glite-', 'gridsite' => '', 'px' => 'glite-', 'canl' => 'emi-', ); %cvs_tag_suffix = ( 'lb' => '', 'jp' => '', 'jobid' => '', 'lbjp-common' => '', 'gridsite' => '-core', 'px' => '', 'canl' => '', ); # ==== projects specification ==== # etics_name ........... ETICS project name # tag_prefix ........... VCS tag prefix # local_prefix ......... prefix (relative to stage) # need_externs_aux ..... project-specific external dependencies # modules .............. additional modules in subsystems %projects = ( glite => { current_version => 3, etics_name => 'org.glite', tag_prefix => { %cvs_tag_prefix }, tag_suffix => { %cvs_tag_suffix }, flavours => '--thrflavour=${globus.thr.flavor} --nothrflavour=${globus.nothr.flavor}', local_prefix => '', need_externs_aux => { 'lb.client-java' => [ qw/ant:B jdk:B axis:B trustmanager utiljava libtool:B/ ], 'lb.glite-LB' => [ qw/fetchcrl:R gpt:R gip_release:R gip_service:R bdii:R glite_version:R glite_info_templates:R glue_schema:R/ ], 'lb.yaim' => [ qw/yaim_core:R/ ], 'px.glite-PX' => [qw/myproxy-server:R myproxy-admin:R fetchcrl:R gip_service:R bdii:R glite_version:R gpt:R glue_schema:R/], 'px.myproxy-yaim' => [ qw/yaim_core:R/ ], }, modules => { 'lb' => [ qw/glite-LB/ ], 'px' => [ qw/glite-PX/ ], }, }, emi => { current_version => 3, etics_name => 'emi', tag_prefix => { %cvs_tag_prefix }, tag_suffix => { %cvs_tag_suffix }, flavours => '--thrflavour= --nothrflavour=', local_prefix => '/usr', need_externs_aux => { 'lb.client-java' => [ qw/ant:B jdk:B axis:B trustmanager trustmanager_axis libtool:B/ ], 'lb.emi-lb' => [ qw/fetchcrl:R gip_service:R bdii:R glite_version:R glue_schema:R/ ], 'lb.yaim' => [ qw/yaim_core:R yaim_bdii:R/ ], 'px.emi-px' => [qw/myproxy-server:R myproxy-admin:R fetchcrl:R gip_service:R bdii:R glite_version:R glue_schema:R/], 'px.myproxy-yaim' => [ qw/yaim_core:R yaim_bdii:R/ ], }, modules => { 'lb' => [ qw/emi-lb/ ], 'px' => [ qw/emi-px/ ], }, }, ); %platform_properties = ( 'jobid.api-cpp' => { default => { 'package.buildarch' => 'noarch' }, }, 'jobid.api-java' => { default => { 'package.buildarch' => 'noarch' }, }, 'lb.types' => { default => { 'package.buildarch' => 'noarch' }, }, 'lb.doc' => { default => { 'package.buildarch' => 'noarch' }, }, 'lb.ws-interface' => { default => { 'package.buildarch' => 'noarch' }, }, 'lb.yaim' => { default => { 'package.buildarch' => 'noarch' }, }, 'lb.nagios' => { default => { 'package.buildarch' => 'noarch' }, }, 'px.yaim' => { default => { 'package.buildarch' => 'noarch' }, }, 'px.myproxy-config' => { default => { 'package.buildarch' => 'noarch' }, }, 'gridsite.devel' => { default => { 'packageName' => 'gridsite-devel' }, deb6_x86_64_gcc445 => { 'packageName' => 'libgridsite-dev' }, }, 'canl.c-devel' => { default => { 'packageName' => 'canl-c-devel' }, deb6_x86_64_gcc445 => { 'packageName' => 'libcanl-dev' }, }, 'jobid.api-c-devel' => { default => { 'packageName' => 'glite-jobid-api-c-devel' }, deb6_x86_64_gcc445 => { 'packageName' => 'libglite-jobid-dev' }, }, 'jobid.api-cpp-devel' => { default => { 'packageName' => 'glite-jobid-api-cpp-devel' }, deb6_x86_64_gcc445 => { 'packageName' => 'libglite-jobid-cpp-dev' }, }, 'lbjp-common.db-devel' => { default => { 'packageName' => 'glite-lbjp-common-db-devel' }, deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-db-dev' }, }, 'lbjp-common.gsoap-plugin-devel' => { default => { 'packageName' => 'glite-lbjp-common-gsoap-plugin-devel' }, deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-gsoap-plugin-dev' }, }, 'lbjp-common.gss-devel' => { default => { 'packageName' => 'glite-lbjp-common-gss-devel' }, deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-gss-dev' }, }, 'lbjp-common.jp-interface-devel' => { default => { 'packageName' => 'glite-lbjp-common-jp-interface-devel' }, deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-jp-interface-dev' }, }, 'lbjp-common.log-devel' => { default => { 'packageName' => 'glite-lbjp-common-log-devel' }, deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-log-dev' }, }, 'lbjp-common.maildir-devel' => { default => { 'packageName' => 'glite-lbjp-common-maildir-devel' }, deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-maildir-dev' }, }, 'lbjp-common.server-bones-devel' => { default => { 'packageName' => 'glite-lbjp-common-server-bones-devel' }, deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-server-bones-dev' }, }, 'lbjp-common.trio-devel' => { default => { 'packageName' => 'glite-lbjp-common-trio-devel' }, deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lbjp-common-trio-dev' }, }, 'lb.client-devel' => { default => { 'packageName' => 'glite-lb-client-devel' }, deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-client-dev' }, }, 'lb.common-devel' => { default => { 'packageName' => 'glite-lb-common-devel' }, deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-common-dev' }, }, 'lb.state-machine-devel' => { default => { 'packageName' => 'glite-lb-state-machine-devel' }, deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-state-machine-dev' }, }, 'lb.logger-devel' => { default => { 'packageName' => 'glite-lb-logger-devel' }, deb6_x86_64_gcc445 => { 'packageName' => 'libglite-lb-logger-dev' }, }, 'px.proxyrenewal-devel' => { default => { 'packageName' => 'glite-px-proxyrenewal-devel' }, deb6_x86_64_gcc445 => { 'packageName' => 'libglite-security-proxyrenewal-dev' }, }, 'canl.c-devel' => { default => { 'packageName' => 'canl-c-devel' }, deb6_x86_64_gcc445 => { 'packageName' => 'libcanl-c-dev' }, }, ); my @k = keys %deps_aux; @buildroot{@k} = ('') x ($#k+1); $buildroot{'gridsite.core'} = 'src'; } sub full { my ($short) = @_; my $subsys = $short; $subsys =~ s/\..*//; my $cvs_prefix = exists $cvs_prefix{$subsys} ? $cvs_prefix{$subsys} : 'org.glite'; return $extrafull{$short} ? $extrafull{$short} : "$cvs_prefix.$short"; } sub get_version { my ($fmod, $top_srcdir) = @_; my ($subsys,$mod) = split /\./,$fmod,2; my ($major,$minor,$rev,$age); my $old_; if ($force_version) { $force_version =~ /([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)-(.+)/; ($major,$minor,$rev,$age) = ($1,$2,$3,$4); } else { my $path = "$top_srcdir/project"; if ($subsys eq 'gridsite') { $path = "$cvs_prefix{$subsys}.$subsys.core/project"; } open V,"$path/version.properties" or die "$path/version.properties: $!\n"; $old_ = $_; while () { chomp; ($major,$minor,$rev) = ($1,$2,$3) if /module\.version\s*=\s*([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+)/; $age = $1 if /module\.age\s*=\s*(\S+)/; } close V; $_ = $old_; } $version = "$major.$minor.$rev-$age"; return ($major, $minor, $rev, $age); } sub get_description { my ($top_srcdir) = @_; my $cvs_module = $top_srcdir; my $package_description = ""; my $package_summary = ""; if (-e "$cvs_module/project/package.description") { open V, "$cvs_module/project/package.description"; $package_description = join ("", ); close V; chomp $package_description; } else { print STDERR "package.description not found for $subsys.$module!\n"; } if (-e "$cvs_module/project/package.summary") { open V, "$cvs_module/project/package.summary"; $package_summary = join ("", ); close V; chomp $package_summary; $package_summary =~ s/\n/\\n/g; } else { print STDERR "package.summary not found for $subsys.$module!\n"; } return ($package_summary, $package_description); } sub mkinc { my %aux; undef %aux; my @m=qw/ lb.client lb.doc lb.state-machine lb.ws-interface lb.logger lb.logger-msg lb.nagios lb.types lb.common lb.server lb.utils lb.ws-test lb.client-java lb.harvester lb.yaim lb.glite-LB lb.emi-lb lbjp-common.gss lbjp-common.gsoap-plugin jobid.api-c jobid.api-cpp jobid.api-java lbjp-common.db lbjp-common.log lbjp-common.maildir lbjp-common.server-bones lbjp-common.trio lbjp-common.jp-interface lbjp-common.gss lbjp-common.gsoap-plugin jp.client jp.doc jp.index jp.primary jp.server-common jp.ws-interface px.proxyrenewal px.myproxy-yaim px.glite-PX px.myproxy-config px.emi-px canl.c /; @aux{@m} = (1) x ($#m+1); my ($short) = @_; my $full = full $short; my ($subsys,$mod) = split /\./,$short,2; my $packageName = "$project{tag_prefix}{$subsys}$subsys-${mod}"; unless ($aux{$short}) { print "Makefile.inc not needed in $full\n"; return; } my $top_srcdir = '.'; my $abs_srcdir = ''; my $build = ''; if ($module) { $top_srcdir = $0; $top_srcdir =~ s,/?[^/]*$,,; $abs_srcdir = $top_srcdir; $top_srcdir =~ s,^$,\.,; } else { $build = "$full/"; $abs_srcdir = "$full/"; unless ($buildroot{$_} eq '') { $top_srcdir = '..'; $build .= "$buildroot{$_}/"; unless (-d "$build") { mkdir "$build" or die "mkdir $build: $!\n"; } } } my ($major, $minor, $rev, $age) = get_version $short, $abs_srcdir; my ($package_summary, $package_description) = get_description $abs_srcdir; if ($package_description) { $package_description =~ s/(.{1,78}\S|\S+)\s+/$1\n/mg; } my $package_description_debian = $package_description; $package_description_debian =~ s/^/ /mg; my ($old_locale, $specdate, $debdate); $old_locale = setlocale(LC_TIME); setlocale(LC_TIME, "C"); $specdate = strftime("%a %b %d %Y", gmtime()); $debdate = strftime("%a, %d %b %Y %H:%M:%S %z", gmtime()); setlocale(LC_TIME, $old_locale); unless ($top_srcdir eq '.') { unlink $build."Makefile"; symlink "$top_srcdir/Makefile",$build."Makefile" or die "symlink $top_srcdir/Makefile ".$build."Makefile: $!\n"; } # package name my $dh; opendir $dh, "$abs_srcdir/project" || die "Can't open $abs_srcdir/project: $!"; for my $dir (readdir $dh) { if ($dir=~/^(.*)\.spec$/) { if ($1 ne $packageName) { printf STDERR "Changed RPM name: $packageName --> $1\n" if ($debug);; $packageName=$1; } last; } } closedir $dh; open MKINC,">".$build."Makefile.inc" or die $build."Makefile.inc: $!\n"; print "Creating ".$build."Makefile.inc\n"; print MKINC qq{project = $project PREFIX = $root prefix = $prefix stagedir = $stagedir sysroot = $sysroot sysconfdir = $sysconfdir localstatedir = $localstatedir os_type = $os_type thrflavour = $thrflavour nothrflavour = $nothrflavour libdir = $libdir top_srcdir = $top_srcdir }; if ($docdir) { my $d = $docdir; $d =~ s/\$\{prefix\}/$prefix/g; $d =~ s/\$\{moduleName\}/$full/g; $d =~ s/\$\{packageName\}/$packageName/g; $d =~ s/\$\{version\}/$major.$minor.$rev/g; $d =~ s/\$\{age\}/$age/g; print MKINC "docdir = $d\n"; } if ($mysqlconfdir) { print MKINC "mysqlconfdir = $mysqlconfdir\n"; } if ($sysdefaultdir) { print MKINC "sysdefaultdir = $sysdefaultdir\n"; } for (@{$need_externs{$short}}) { next unless defined $externs{$_} and defined $externs{$_}{prefix}; print MKINC "${_}_prefix = $externs{$_}{prefix}\n"; print MKINC "$externs{$_}{flags}" if defined $externs{$_}{flags}; } for (@{$need_jars{$short}}) { print MKINC "${_}_jar = $jar{$_}\n" } my $need_gsoap = 0; for (@{$need_externs{$short}}) { $need_gsoap = 1 if $_ eq 'gsoap'; } print MKINC "gsoap_default_version=".gsoap_version()."\n" if $need_gsoap; print MKINC ' -include ${top_srcdir}/project/version.properties version=${module.version} ${package}-${version}.tar.gz: rm -rf dist for dist in ${SOURCES} ${SOURCES_EXEC} configure ChangeLog project/debian.* project/*.spec project/package.* project/version.properties LICENSE; do \ dir=${package}-${version}/`dirname $$dist`; \ mkdir -p dist/$$dir || :; \ install -m 0644 ${top_srcdir}/$$dist dist/$$dir; \ done for dist in ${SOURCES_EXEC} configure; do \ chmod +x dist/${package}-${version}/$$dist; \ done (cd dist; tar -czf ${package}-${version}.tar.gz ${package}-${version}) mv dist/${package}-${version}.tar.gz . dist: ${package}-${version}.tar.gz distcheck: ${package}-${version}.tar.gz rm -rf dist mkdir -p dist cp ${package}-${version}.tar.gz dist (cd dist; tar -xzf ${package}-${version}.tar.gz) a=`(cd dist/${package}-${version}; find . -type f | sort)`; \ b=`(cd ${top_srcdir}; find . -path ./dist -prune -or -type f -print | sort)`; \ echo "$$a" >dist/files-dist; \ echo "$$b" | egrep -v "(^./Makefile.inc$$|^./${package}-${version}.tar.gz$$|^./debian|^./[^/]*.spec$$|\.cvsignore|^\./project/changelog$$|/CVS|^\./\.git|^\./config\.status$$)" >dist/files-original diff -U0 dist/files-dist dist/files-original rpm: ${package}-${version}.tar.gz dir=dist/rpm_build_src; \ rm -rf $$dir; \ mkdir -p $$dir/BUILD $$dir/RPMS $$dir/SOURCES $$dir/SRPMS; \ cp ${package}-${version}.tar.gz $$dir/SOURCES/${package}-${version}.tar.gz && \ rpmbuild -bs --nodeps --define "_topdir $$dir" ${package}.spec && \ cp -v $$dir/SRPMS/*.src.rpm dist/ deb: ${package}-${version}.tar.gz dir=dist/dpkg_build_src; \ rm -rf $$dir; \ mkdir -p $$dir; \ cp ${package}-${version}.tar.gz $$dir/${package}_${version}.orig.tar.gz && \ tar zxf $$dir/${package}_${version}.orig.tar.gz -C $$dir && \ cp -rf debian/ $$dir/${package}-${version} && \ (cd $$dir/${package}-${version} && dpkg-buildpackage -S -d -nc -us -uc) && \ cp -v $$dir/*.tar.* $$dir/*.dsc dist/ '; close MKINC; my $debian = 0; for my $file ("$packageName.spec", "debian.rules", "debian.control", "debian.changelog", "debian.copyright") { if (-f "$abs_srcdir/project/$file") { my $old_ = $_; my $url_spec = $url_source; $url_spec =~ s/\$\{moduleName\}/$project{etics_name}.$subsys.$mod/g; $url_spec =~ s/\$\{packageName\}/%{name}/g; $url_spec =~ s/\$\{version\}/%{version}/g; $url_spec =~ s/\$\{age\}/%{rel}/g; printf STDERR "Creating $build$file\n" if ($debug);; open DST, ">$build$file"; open SRC, "<$abs_srcdir/project/$file"; while () { if (/\@MODULE\@/) { s/\@MODULE\@/$full/g; } if (/\@PACKAGE_NAME\@/) { s/\@PACKAGE_NAME\@/$packageName/g; } if (/\@URL\@/) { s/\@URL\@/$package{url}/g; } if (/\@SUMMARY\@/) { s/\@SUMMARY\@/$package_summary/g; } if (/\@DESCRIPTION\@/) { s/\@DESCRIPTION\@/$package_description/g; } if (/\@DEBIAN_DESCRIPTION\@/) { s/\@DEBIAN_DESCRIPTION\@/$package_description_debian/g; } if (/\@VERSION\@/) { s/\@VERSION\@/$version/g; } if (/\@MAJOR\@/) { s/\@MAJOR\@/$major/g; } if (/\@MINOR\@/) { s/\@MINOR\@/$minor/g; } if (/\@REVISION\@/) { s/\@REVISION\@/$rev/g; } if (/\@AGE\@/) { s/\@AGE\@/$age/g; } if (/\@MAINTAINER\@/) { s/\@MAINTAINER\@/$package{maintainer}/g; } if (/\@UPLOADERS\@/) { s/\@UPLOADERS\@/$package{uploaders}/g; } if (/\@DEBIAN_DATE\@/) { s/\@DEBIAN_DATE\@/$debdate/g; } if (/\@SPEC_DATE\@/) { s/\@SPEC_DATE\@/$specdate/g; } if (/^\s*.+\/configure\s/ and $force_version) { print "Version forced to $version\n" if ($debug);; s/--version\s+\S+\s?//; s/$/ --version $version/; } if (/^Source:.*/ and $file =~ /\.spec$/) { s,^(Source:\s*).*?([^/]*)$,\1$url_spec/\2,; } printf DST "%s", "$_"; } close SRC; close DST; $_ = $old_; } } if ($module and -d $build."debian") { print "Skipping ${build}debian/ (no rewrite in single module mode)\n" if ($debug); `rm -f ${build}debian.*`; } else { print "Creating ${build}debian/\n" if ($debug);; `rm -rfv ${build}debian`; mkdir $build."debian" or die $!; `cp $abs_srcdir/project/debian.* ${build}debian/ 2>/dev/null`; `mv ${build}debian.* ${build}debian/ 2>/dev/null`; `rm -f ${build}debian/*.orig`; opendir $dh, "${build}debian" || die "Can't open ${build}debian: $!"; for $_ (readdir $dh) { if (/^debian\.(.*)/) { `mv ${build}debian/$_ ${build}debian/$1`; $debian = 1; } } closedir $dh; if ($debian) { my ($dir, $file); chmod 0755, "${build}debian/rules"; $file="${build}debian/docs"; if (not -f $file) { `touch $file`; } $dir="${build}debian/source"; if (not -d $dir) { mkdir $dir; } $file="${build}debian/source/format"; if (not -f $file) { `echo "3.0 (quilt)" > $file` } $file="${build}debian/compat"; if (not -f $file) { `echo "7" > $file` } $file="${build}debian/changelog"; if (not -f $file) { open FH, ">$file" or die $!; print FH qq{$packageName ($major.$minor.$rev-$age) stable; urgency=low * Automatically generated package -- $package{maintainer} $debdate }; close FH; } } else { `rm -rf ${build}debian`; } } } BEGIN{ }; sub gsoap_version { local $_; my $gsoap_version; open S,"$externs{gsoap}{prefix}/bin/soapcpp2 -v 2>&1 |" or die "$externs{gsoap}{prefix}/bin/soapcpp2: $!\n"; while ($_ = ) { chomp; $gsoap_version = $1 if /The gSOAP Stub and Skeleton Compiler for C and C\+\+ ([.[:digit:][:alpha:]]+)$/; $gsoap_version = $1 if /The gSOAP code generator for C and C\+\+, soapcpp2 release ([.[:digit:][:alpha:]]+)$/; } close S; return $gsoap_version; } sub getlibdir { if ( -e "/etc/debian_version") { # We are on Debian $lib64="lib"; $lib32="lib32"; } else { # Another distribution $lib64="lib64"; $lib32="lib"; } $libdir=$lib32; open INP, "uname -s | "; # Check kernel name $kname= ; chomp($kname); close INP; if ( $kname eq "Linux") { $arch = ("x86_64\npowerpc\nppc64\n"); open INP, "uname -p | "; # Check processor type $procname= ; chomp($procname); close INP; if ($arch =~/^$procname\n/) { return ($lib64); } open INP, "uname -m | "; # Check machine hardware $machname= ; chomp($machname); close INP; if ($arch =~/^$machname\n/) { return ($lib64); } # special cases (hyperlink lib64, Debian) if (-l "/usr/lib64") { $libdir=$lib32; } # if /usr/lib64 doesn't exist at all (AIX) unless ( -e "/usr/lib64" ) { $libdir=$lib32; } } if ( $kname eq "SunOS") { if (-e "/usr/lib/64") { $libdir="lib/64"; } } return $libdir; } sub os_type { # # 1) check for systemd first (it can be used across distributions) # 2) check for debian-like distribution (systemv scripts for Debian) # 3) default is redhat-like (systemv scripts for Red Hat) # `pkg-config --exists systemd`; return "systemd" if ($? == 0); return "systemd" if (-e '/etc/fedora-release'); return "debian" if (-e '/etc/debian_version'); return "redhat" if (-r '/etc/redhat-release'); open FH, '<', '/etc/issue' or return "redhat"; $_=; close FH; if (/Debian|Ubuntu/i) { return "debian"; } else { return "redhat"; } } sub usage { my @ext = keys %externs; my @myjars = keys %jar; print STDERR qq{ Usage: $0 options General options (defaults in []): --prefix=PREFIX destination directory [./stage] --stage=DIR staging directory [./stage] --root=DIR installation root (custom relocation root -> sysroot) [./stage] --sysroot=DIR system root (custom relocation root -> sysroot) [] --sysconfdir=DIR system configuration directory [PREFIX/etc] --localstatedir=DIR system local status directory [PREFIX/var] --docdir documentation directory [] --mysqlconfdir MySQL/MariaDB configuration directory [] --sysdefaultdir default configuration directory [] --os-type=DIST boot system type (debian/redhat/systemd) --staged=module,module,... what is already in PREFIX (specify without org.glite.) --thrflavour=flavour --nothrflavour=flavour threaded and non-treaded flavours [] --listmodules=subsys list modules of a subsystem --listmodules=module list subpackages of a module --version=maj.min.rev-age version used instead of reading version.properties --libdir=libdir typically [lib,lib64] postfix --project=PROJECT build for a project (glite/emi1/emi) [emi] --debug print more details --url URL of all published files [$default_url] --url-source URL of published source tarballs [] Mode of operation: --mode=\{checkout|build\} what to do [build] What to build: --module=module build this module only --enable-NODE build this "node" (set of modules) only --disable-NODE don't build this node --lb-tag=tag checkout LB modules with specific tag --jp-tag=tag checkout JP modules with specific tag --lbjp-common-tag=tag checkout lbjp-common modules with specific tag --jobid-tag=tag checkout jobid modules with specific tag --canl-tag=tag checkout canl modules with specific tag --px-tag=tag checkout px modules with specific tag Dependencies (summary of what will be used is always printed): --with-EXTERNAL=PATH where to look for an external [autodetect] --with-JAR=JAR where to look for jars Available nodes: @nodes Default nodes: @default_nodes Externals (not all for all modules) are: @ext External jars are: @myjars }; } canl-c-3.0.0/ChangeLog0000644000015500017500000001021313017332513014212 0ustar tomcat6jenkins1.0.0-1 - Initial version of the module 1.0.1-1 - Using pre-cooked lexical analyser instead of having it generated at build time - Build cleanups - Improvements throughout the code 1.0.2-1 - Building certificate delegation samples - Making use of canl_mech_ssl to include openssl header files - Examples added: canl-proxy-init - Client can give cert and key paths explicitly - Recognition of command line args - License string as recognized by rpmlint and packaging guidelines - Truly independent of auth. mechanism - Cert, key in mech. context - Writing proxy to file with restrictive permissions - Duplicating only existing certificates - Set CA directory and CRL directory to context - Compatiblity with FIPS openssl releases 1.0.3-1 - Examples extended - Storing certificate + chain of approp. certs in context - Duplicate certificates instead of using pointers in cred handling - Delegation sample made truly funcional - Setting CA directory and CRL directory is X509 authn. mechanism specific - Preparation for OCSP support - Using proxy cert file (chain of certs) as easy as user cert 1.0.4-1 - Build dependency on krb5-devel added - Better error codes - Refuse to sign certificate if key size is not long enough - Using default key size of 1024 bits - canl_cert_req object not used anymore - Preparing implementation of OCSP support - Fixed Vulnerability in Voms CRL processing 2.0.0-1 - OCSP support - PKCS11 support - Preparation for Fedora & EPEL packaging - Features and bugfixes 2.0.0-2 - Update debian packaging due to major version bump - Module rebuilt 2.0.1-1 - License and packaging fixes 2.0.2-1 - Memory handling fixes 2.0.3-1 - Minor changes of error messages in caNl examples - Library sonames tracked in rpm - caNl API documentation located only in canl-devel subpackage - proxy_verify_desc and proxy_verify_ctx_desc structures taken care of - New parameter to setup_SSL_proxy_handler (gridsite speciality) - New error codes added - Older error descriptions revised 2.0.4-1 - Changes based on Fedora reviews - More than one return code from newer c-ares handled (fixes possible problem for IPv6 only machines) - fixed vulnerability reported in EGI RT ticket #4781 1) - SSL_CTX_set_cipher_list(ssl_ctx, "ALL") set to chosen ciphers 2.0.5-1 - Spec macros fixed, building canl-c documentation on Fedora 18 - Fixes to follow recent Debian updates 2.0.6-1 - Support multilib for canl-c-devel - Fixes for EGI RT ticket #4781, section 2 - Detecting Limited proxies in (pre-)RFC proxies fixed - Distinguish between proxy sub-types - Detect path lenght restriction violation 2.0.7-1 - Get peer's certificate if asked for 2.0.8-1 - Optionally turn on OCSP in examples - OCSP off by default, can be switched of by setting CANL_SSL_OCSP_VERIFY_ALL as a flag to canl_ctx_set_ssl_flags() 2.0.9-1 - proxy_verify... renamed to canl_proxy_verify, may solve GGUS ticket 91208 - New funcions added to doc 2.0.10-1 - Debugging packages for subpackages in Debian - Sensitive exported functions renamed to prevent collisions - API enhancement, let the user choose ocsp responder url 2.1.0-1 - There was an API enhancement -- minor version bump is appropriate 2.1.1-1 - Uninitialized context variable fixed 2.1.2-1 - Proxy type honoured in the signing function 2.1.3-1 - Fixed Makefile dependencies - Adjustment to Fedora packaging guidelines - Some build-time warnings fixed - Parallel build support - Reactions to Fedora review - Support for EPEL 7 (Fedora 20) 2.1.4-1 - Fixing Certificate chain validation error (GH Issue #3) 2.1.5-1 - Memory handling issues - Fixin upgrade from older debug package - Polishing makefile rules usage for bison files - Fixing build issues (LDFLAGS) - Moving ChangeLogs from project subdirectory to module root directory - Removing Debian VCS fields - Simplified Debian packaging - Updating debian.control according to current Debian "downstream" 2.1.6-1 - Fixing build errors with newer compilers - Adding missing ptherad library for Debian 8 - Calling OpenSSL init routines exactly once (Fixes Issue #7) - Makes the first byte of SN always 0x01 (Fixes GGUS #113418) 2.1.7-1 - Quick fix to prevent RFC Proxy DN forgery (RT #11476) 3.0.0-1 - Migrate to openssl 1.1.0 canl-c-3.0.0/project/0000755000015500017500000000000013017332513014111 5ustar tomcat6jenkinscanl-c-3.0.0/project/debian.control0000644000015500017500000000353013017332513016736 0ustar tomcat6jenkinsSource: canl-c Priority: optional Maintainer: @MAINTAINER@ Uploaders: @UPLOADERS@ Build-Depends: debhelper (>= 7.0.50~), bison, flex, libc-ares-dev, libkrb5-dev, libssl-dev, libtool-bin, pkg-config, texlive-fonts-recommended, texlive-latex-extra, texlive-latex-recommended Standards-Version: 3.9.1 Section: net Homepage: http://www.eu-emi.eu Package: libcanl-c2 Section: libs Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: @SUMMARY@ @DEBIAN_DESCRIPTION@ Package: libcanl-c-dev Section: libdevel Architecture: any Depends: libcanl-c2 (= ${binary:Version}), libkrb5-dev, ${misc:Depends} Description: Development files for EMI caNl @DEBIAN_DESCRIPTION@ . This package contains development libraries and header files for EMI caNl. Package: libcanl-c-examples Section: misc Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} Description: Example programs of EMI caNl @DEBIAN_DESCRIPTION@ . This package contains client and server examples of EMI caNl. Package: libcanl-c2-dbg Section: debug Architecture: any Priority: extra Depends: libcanl-c2 (= ${binary:Version}), ${misc:Depends} Replaces: canl-c-dbg (<< 2.0.10) Breaks: canl-c-dbg (<< 2.0.10) Description: Debugging symbols for EMI caNl library @DEBIAN_DESCRIPTION@ . This package contains debugging symbols for EMI caNl library. Package: libcanl-c-examples-dbg Section: debug Architecture: any Priority: extra Depends: libcanl-c-examples (= ${binary:Version}), ${misc:Depends} Description: Debugging symbols for EMI caNl examples @DEBIAN_DESCRIPTION@ . This package contains debugging symbols for EMI caNl client and server examples. Package: canl-c-dbg Section: oldlibs Architecture: all Priority: extra Depends: libcanl-c2-dbg, libcanl-c-examples-dbg, ${misc:Depends} Description: transitional dummy package This is a transitional dummy package. It can safely be removed. canl-c-3.0.0/project/debian.copyright0000644000015500017500000000311313017332513017263 0ustar tomcat6jenkinsFormat: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: @PACKAGE_NAME@ Upstream-Contact: @MAINTAINER@ Source: http://scientific.zcu.cz/emi/ Files: * Copyright: 2004-2010 Members of the EGEE Collaboration 2010-2013 EMI License: Apache-2.0 Files: src/proxy/sslutils.c Copyright: 2002-2009 INFN-CNAF on behalf of the EU DataGrid License: Apache-2.0 Files: src/proxy/pkcs11.h Copyright: 2006 Andreas Jellinghaus 2006, 2007 g10 Code GmbH License: Pkcs License: Apache-2.0 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at . http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. . On Debian systems the full text of the Apache 2.0 license can be found in the /usr/share/common-licenses/Apache-2.0 file. License: Pkcs This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without modifications, as long as this notice is preserved. . This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY, to the extent permitted by law; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. canl-c-3.0.0/project/debian.libcanl-c-dev.doc-base0000644000015500017500000000052313017332513021331 0ustar tomcat6jenkinsDocument: canl-dg Title: Common Authentication Library - Developer's Guide Abstract: CaNl Developer’s Guide explains how to use the Common Authentication Library C API. Main and Credentials API is described in details together with programing examples. Section: Programming/C Format: PDF Files: /usr/share/doc/libcanl-c-dev/canl.pdf.gz canl-c-3.0.0/project/debian.libcanl-c-dev.docs0000644000015500017500000000001113017332513020574 0ustar tomcat6jenkinscanl.pdf canl-c-3.0.0/project/debian.libcanl-c-dev.install0000644000015500017500000000005513017332513021322 0ustar tomcat6jenkinsusr/include/* usr/lib/lib*.a usr/lib/lib*.so canl-c-3.0.0/project/debian.libcanl-c-examples.install0000644000015500017500000000001213017332513022353 0ustar tomcat6jenkinsusr/bin/* canl-c-3.0.0/project/debian.libcanl-c2.docs0000644000015500017500000000000713017332513020107 0ustar tomcat6jenkinsREADME canl-c-3.0.0/project/debian.libcanl-c2.install0000644000015500017500000000002213017332513020622 0ustar tomcat6jenkinsusr/lib/lib*.so.* canl-c-3.0.0/project/debian.rules0000644000015500017500000000213613017332513016411 0ustar tomcat6jenkins#!/usr/bin/make -f DPKG_EXPORT_BUILDFLAGS = 1 -include /usr/share/dpkg/buildflags.mk p_base=canl-c p_dev=libcanl-c-dev p_examples=libcanl-c-examples p_lib=libcanl-c2 p_dummy=canl-c-dbg # Uncomment this to turn on verbose mode. export DH_VERBOSE=1 %: dh $@ --parallel --fail-missing override_dh_auto_configure: config.status config.status: ./configure --root=/ --prefix=/usr --libdir=lib --project=emi --module=canl.c override_dh_auto_clean: config.status make clean override_dh_clean: dh_clean rm -vf Makefile.inc config.status *.spec override_dh_strip: dh_strip -p$(p_examples) --dbg-package=$(p_examples)-dbg dh_strip -p$(p_lib) --dbg-package=$(p_lib)-dbg override_dh_auto_install: dh_auto_install rm -vf debian/tmp/usr/lib/*.la # Documentation is installed by dh_installdocs rm -rf debian/tmp/usr/share/doc override_dh_installdocs: dh_installdocs -p$(p_lib) dh_installdocs -p$(p_dev) dh_installdocs -p$(p_examples) --link-doc=$(p_lib) dh_installdocs -p$(p_lib)-dbg --link-doc=$(p_lib) dh_installdocs -p$(p_examples)-dbg --link-doc=$(p_lib) dh_installdocs -p$(p_dummy) --link-doc=$(p_lib) canl-c-3.0.0/project/debian.watch0000644000015500017500000000010713017332513016361 0ustar tomcat6jenkinsversion=3 http://scientific.zcu.cz/emi/emi.canl.c/canl-c-(.*)\.tar\.gz canl-c-3.0.0/project/canl-c.spec0000644000015500017500000000553213017332513016127 0ustar tomcat6jenkinsName: canl-c Version: @MAJOR@.@MINOR@.@REVISION@ Release: @AGE@%{?dist} Summary: @SUMMARY@ Group: System Environment/Libraries License: ASL 2.0 Vendor: EMI URL: http://www.eu-emi.eu Source: http://eticssoft.web.cern.ch/eticssoft/repository/emi/emi.canl.c/%{version}/src/%{name}-%{version}.tar.gz BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) BuildRequires: bison BuildRequires: c-ares-devel BuildRequires: flex BuildRequires: krb5-devel BuildRequires: libtool BuildRequires: openssl-devel BuildRequires: perl BuildRequires: perl(Getopt::Long) BuildRequires: perl(POSIX) BuildRequires: pkgconfig %if 0%{?fedora} || 0%{?rhel} >= 6 BuildRequires: tex(latex) %else BuildRequires: tetex-latex %endif %if 0%{?fedora} || 0%{?rhel} >= 7 BuildRequires: tex(lastpage.sty) BuildRequires: tex(multirow.sty) BuildRequires: tex(ptmr7t.tfm) BuildRequires: tex(phvr8t.tfm) BuildRequires: tex(psyr.tfm) BuildRequires: tex(pzcmi8r.tfm) BuildRequires: tex(ucrr8a.pfb) %endif %description @DESCRIPTION@ %package devel Summary: Development files for EMI caNl Group: Development/Libraries Requires: %{name}%{?_isa} = %{version}-%{release} Requires: krb5-devel%{?_isa} %description devel This package contains development libraries and header files for EMI caNl. %package doc Summary: API documentation for EMI caNl Group: Documentation %if 0%{?fedora} || 0%{?rhel} >= 6 BuildArch: noarch %endif %description doc This package contains API documentation for EMI caNl. %package examples Summary: Example programs of EMI caNl Group: System Environment/Base Requires: %{name}%{?_isa} = %{version}-%{release} %description examples This package contains client and server examples of EMI caNl. %prep %setup -q %build ./configure --root=/ --prefix=%{_prefix} --libdir=%{_lib} --project=emi CFLAGS="%{?optflags}" LDFLAGS="%{?__global_ldflags}" make %{?_smp_mflags} %install rm -rf %{buildroot} make install DESTDIR=%{buildroot} # in -doc subpackage rm -f %{buildroot}%{_defaultdocdir}/%{name}-%{version}/README rm -f %{buildroot}%{_defaultdocdir}/%{name}-%{version}/canl.pdf rm -f %{buildroot}%{_libdir}/*.a rm -f %{buildroot}%{_libdir}/*.la %clean rm -rf %{buildroot} %post -p /sbin/ldconfig %postun -p /sbin/ldconfig %files %{!?_licensedir:%global license %doc} %defattr(-,root,root) %doc ChangeLog README %license LICENSE %{_libdir}/libcanl_c.so.2 %{_libdir}/libcanl_c.so.2.* %files devel %defattr(-,root,root) %{_includedir}/*.h %{_libdir}/libcanl_c.so %files doc %defattr(-,root,root) %doc canl.pdf %license LICENSE %files examples %defattr(-,root,root) %{_bindir}/* %changelog * @SPEC_DATE@ @MAINTAINER@ - @MAJOR@.@MINOR@.@REVISION@-@AGE@ - automatically generated package canl-c-3.0.0/project/package.description0000644000015500017500000000011113017332513017742 0ustar tomcat6jenkinsThis is the C part of the EMI caNl -- the Common Authentication Library. canl-c-3.0.0/project/package.summary0000644000015500017500000000006313017332513017122 0ustar tomcat6jenkinsEMI Common Authentication library - bindings for C canl-c-3.0.0/project/version.properties0000644000015500017500000000004213017332513017710 0ustar tomcat6jenkinsmodule.version=3.0.0 module.age=1 canl-c-3.0.0/LICENSE0000644000015500017500000002613613017332513013460 0ustar tomcat6jenkins Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.