/* * Copyright (c) 2008-2016 Computer Network Information Center (CNIC), Chinese Academy of Sciences. * * This file is part of Duckling project. * * 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. * */ package cn.vlabs.duckling.ca.action; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.Inet4Address; import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; import java.util.Enumeration; import java.util.Map; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.mime.MultipartEntityBuilder; public class DownloadCertificateAndKeypairByKeyAction implements HttpAction { private String getLocalIPAddress(){ Enumeration<NetworkInterface> interfaces; try { interfaces = NetworkInterface.getNetworkInterfaces(); while (interfaces.hasMoreElements()){ NetworkInterface current = interfaces.nextElement(); if (!current.isUp() || current.isLoopback() || current.isVirtual()) continue; Enumeration<InetAddress> addresses = current.getInetAddresses(); while (addresses.hasMoreElements()){ InetAddress current_addr = addresses.nextElement(); if (current_addr.isLoopbackAddress()) continue; if (current_addr instanceof Inet4Address){ return current_addr.getHostAddress(); } } } } catch (SocketException e) { e.printStackTrace(); } return null; } private MultipartEntityBuilder buildGetCert(String xsrfToken, String requestKey,String password,String dn,String keyFormat) throws UnsupportedEncodingException { String ipAddress = getLocalIPAddress(); String port = "40065"; MultipartEntityBuilder builder = MultipartEntityBuilder.create(); String fullScript = "pki?format_sendcert=cer;format_send_cert_key=openssl;Submit=Download;" +"GET_PARAMS_CMD=send_cert_key;cmd=getParams;dataType=VALID_CERTIFICATE;name=PUBLIC;" +"HIDDEN_key={key};xsrf_protection_token={xsrfToken};key={key};passwd={password};" +"signature=;format=;text=;new_dn=;dn={dn};" +"HTTP_REQUEST_METHOD=POST;HTTP_USER_AGENT=Mozilla%2F5.0%20%28Macintosh%3B%20Intel%20Mac%20OS%20X%2010_9_5%29%20AppleWebKit%2F537.36%20%28KHTML%2C%20like%20Gecko%29%20Chrome%2F45.0.2454.93%20Safari%2F537.36;" +"AGENT_NAME=Safari;AGENT_VERSION=537.36;AGENT_OS_NAME=KHTML;AGENT_OS_VERSION=%2C;REMOTE_ADDR={remoteAddr};REMOTE_PORT={remotePort};HTTP_CGI_SCRIPT=pki"; fullScript = fullScript.replaceAll("\\{xsrfToken\\}", xsrfToken); fullScript = fullScript.replaceAll("\\{remoteAddr\\}", ipAddress); fullScript = fullScript.replaceAll("\\{remotePort\\}", port); fullScript = fullScript.replaceAll("\\{key\\}", requestKey); fullScript = fullScript.replaceAll("\\{dn\\}", escape(dn)); builder .addTextBody("GET_PARAMS_STEP", "0") .addTextBody("GET_PARAMS_CMD", "send_cert_key") .addTextBody("AGENT_OS_NAME", "KHTML") .addTextBody("dataType", "VALID_CERTIFICATE") .addTextBody("key", requestKey) .addTextBody("xsrf_protection_token", xsrfToken) .addTextBody("HTTP_FULL_CGI_SCRIPT", fullScript) .addTextBody("REMOTE_PORT", port) .addTextBody( "HTTP_USER_AGENT", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.130 Safari/537.36") .addTextBody("HTTP_ACCEPT_LANGUAGE", "zh-CN,zh;q=0.8") .addTextBody("cmd", "getParams") .addTextBody("name", "PUBLIC") .addTextBody("HIDDEN_key", requestKey) .addTextBody("OPENCA_AC_CHANNEL_SERVER_SOFTWARE", "Apache/2.2.15 (CentOS)") .addTextBody("signature", "") .addTextBody("HTTP_REQUEST_METHOD", "POST") .addTextBody("Submit", "Download") .addTextBody("AGENT_OS_VERSION", "") .addTextBody("HTTP_ACCEPT_ENCODING", "gzip, deflate") .addTextBody("OPENCA_AC_CHANNEL_REMOTE_ADDRESS", ipAddress) .addTextBody("HTTP_CGI_SCRIPT", "pki") .addTextBody("text", "") .addTextBody("OPENCA_AC_INTERFACE", "public") .addTextBody("new_dn", "") .addTextBody("format_sendcert", "cer") .addTextBody("REMOTE_ADDR", ipAddress) .addTextBody("AGENT_VERSION", "537.36") .addTextBody("passwd", password) .addTextBody("format", "") .addTextBody("format_send_cert_key", keyFormat) .addTextBody("AGENT_NAME", "Safari") .addTextBody("dn", dn); return builder; } @Override public ActionResult execute(HttpClient httpClient, Map<String, String> context) throws IOException { String xsrfToken = context.get(XSRF_TOKEN); String baseUrl = context.get(BASE_URL); String requestKey = context.get(REQUEST_KEY); String password = context.get(PASSWORD); String dn= context.get("dn"); String keyFormat=context.get(CERT_KEY_Format); MultipartEntityBuilder builder = buildGetCert(xsrfToken, requestKey,password,dn,keyFormat); HttpPost post = new HttpPost(baseUrl + "/cgi-bin/pki/pub/pki"); post.setEntity(builder.build()); HttpResponse response = httpClient.execute(post); ActionResult result=new ActionResult(response); post.releaseConnection(); return result; } private String escape (String src) { int i; char j; StringBuffer tmp = new StringBuffer(); tmp.ensureCapacity(src.length()*6); for (i=0;i<src.length() ;i++ ) { j = src.charAt(i); if (Character.isDigit(j) || Character.isLowerCase(j) || Character.isUpperCase(j)) tmp.append(j); else if (j<256) { tmp.append( "%" ); if (j<16) tmp.append( "0" ); tmp.append( Integer.toString(j,16) ); } else { tmp.append( "%u" ); tmp.append( Integer.toString(j,16) ); } } return tmp.toString().toUpperCase(); } }