BSTR CBoxEncoding::Base64Encode(VARIANT& var) { CBoxBinPtr varPtr(var); CStringA str; LPSTR pstr; int strSize; int nPos, i; strSize = ((varPtr.m_nSize + 2) / 3) * 4; strSize += (strSize / 64) * 2; pstr = str.GetBuffer(strSize); for(i = 0, nPos = 0; i < varPtr.m_nSize; i += 48) if(varPtr.m_nSize - i > 48) { EVP_EncodeBlock((unsigned char*)pstr + nPos, (unsigned char*)varPtr + i, 48); nPos += 64; pstr[nPos ++] = '\r'; pstr[nPos ++] = '\n'; }else EVP_EncodeBlock((unsigned char*)pstr + nPos, (unsigned char*)varPtr + i, varPtr.m_nSize - i); str.ReleaseBuffer(strSize); return str.AllocSysString(); }
/* Encode something to base-64 */ char * ship_encode_base64(unsigned char *input, int length) { char *ret = NULL; unsigned char in[48]; int blen, i=0, ilen, len=0, olen=0; blen = (((length + 2) / 3) * 4) + 3; ASSERT_TRUE(ret = (char *)malloc(blen), err); while(i<length){ ilen = (i+48<length)?48:length-i; memcpy (in, input, ilen); input += ilen; i += ilen; /* Each 48-byte text should encode to 64-byte binary */ len = EVP_EncodeBlock((unsigned char*)ret+olen, in, ilen); olen += len; } ret[olen] = '\0'; err: return ret; }
int WXBizMsgCrypt::EncodeBase64(const std::string sSrc, std::string & sTarget) { if(0 == sSrc.size() || kMaxBase64Size < sSrc.size()) { return -1; } uint32_t iBlockNum = sSrc.size() / 3; if (iBlockNum * 3 != sSrc.size()) { iBlockNum++; } uint32_t iOutBufSize = iBlockNum * 4 + 1; char * pcOutBuf = (char*)malloc( iOutBufSize); if(NULL == pcOutBuf) { return -1; } int iReturn = 0; int ret = EVP_EncodeBlock((unsigned char*)pcOutBuf, (const unsigned char*)sSrc.c_str(), sSrc.size()); if (ret > 0 && ret < (int)iOutBufSize) { sTarget.assign(pcOutBuf,ret); } else { iReturn = -1; } FREE_PTR(pcOutBuf); return iReturn; }
int PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen, EVP_PKEY *pkey) { unsigned char *m; int i, ret = 0; unsigned int m_len; m = malloc(EVP_PKEY_size(pkey) + 2); if (m == NULL) { PEMerr(PEM_F_PEM_SIGNFINAL, ERR_R_MALLOC_FAILURE); goto err; } if (EVP_SignFinal(ctx, m, &m_len, pkey) <= 0) goto err; i = EVP_EncodeBlock(sigret, m, m_len); *siglen = i; ret = 1; err: /* ctx has been zeroed by EVP_SignFinal() */ free(m); return (ret); }
char * NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki) { unsigned char *der_spki, *p; char *b64_str; size_t b64_len; int der_len; der_len = i2d_NETSCAPE_SPKI(spki, NULL); if (!EVP_EncodedLength(&b64_len, der_len)) { OPENSSL_PUT_ERROR(X509, NETSCAPE_SPKI_b64_encode, ERR_R_OVERFLOW); return NULL; } der_spki = OPENSSL_malloc(der_len); if (der_spki == NULL) { OPENSSL_PUT_ERROR(X509, NETSCAPE_SPKI_b64_encode, ERR_R_MALLOC_FAILURE); return NULL; } b64_str = OPENSSL_malloc(b64_len); if (b64_str == NULL) { OPENSSL_free(der_spki); OPENSSL_PUT_ERROR(X509, NETSCAPE_SPKI_b64_encode, ERR_R_MALLOC_FAILURE); return NULL; } p = der_spki; i2d_NETSCAPE_SPKI(spki, &p); EVP_EncodeBlock((unsigned char *)b64_str, der_spki, der_len); OPENSSL_free(der_spki); return b64_str; }
char *base64(const unsigned char *input, int length) { char *buffer = (char*)xmalloc(length*2); memset(buffer, 0, length*2); EVP_EncodeBlock((unsigned char*)buffer, input, length); return buffer; }
static char * _SSL_do_cipher_base64(char *buf, int buf_len, char *key, int operation) { char *pt; char *pt2; int i; if (operation) { i = _SSL_do_cipher(buf, buf_len, key, operation, &pt); pt2 = mmalloc(i * 2 + 1); /* + NULL */ memset(pt2, 0, i * 2 + 1); /* FIXME: need it? */ if ((i = EVP_EncodeBlock(pt2, pt, i)) == -1) { fprintf(stderr, "_SSL_do_cipher_base64 :: EVP_EncodeBlock failed\n"); exit(1); } fprintf(stderr, "_SSL_do_cipher_base64 :: EVP_EncodeBlock %d [%24s]\n", i, key); } else { pt = mmalloc(buf_len / 2 * 2 + 1); /* + NULL */ memset(pt, 0, buf_len / 2 * 2 + 1); /* FIXME: need it? */ if ((i = EVP_DecodeBlock(pt, buf, buf_len)) == -1) { fprintf(stderr, "_SSL_do_cipher_base64 :: EVP_DecodeBlock failed\n"); exit(1); } fprintf(stderr, "_SSL_do_cipher_base64 :: EVP_DecodeBlock %d [%24s]\n", i, key); i -= i % 8; /* cut padding */ i = _SSL_do_cipher(pt, i, key, operation, &pt2); } free (pt); return (pt2); }
void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl) { int i, j; size_t total = 0; *outl = 0; if (inl == 0) return; OPENSSL_assert(ctx->length <= (int)sizeof(ctx->enc_data)); if (ctx->length - ctx->num > inl) { memcpy(&(ctx->enc_data[ctx->num]), in, inl); ctx->num += inl; return; } if (ctx->num != 0) { i = ctx->length - ctx->num; memcpy(&(ctx->enc_data[ctx->num]), in, i); in += i; inl -= i; j = EVP_EncodeBlock(out, ctx->enc_data, ctx->length); ctx->num = 0; out += j; *(out++) = '\n'; *out = '\0'; total = j + 1; } while (inl >= ctx->length && total <= INT_MAX) { j = EVP_EncodeBlock(out, in, ctx->length); in += ctx->length; inl -= ctx->length; out += j; *(out++) = '\n'; *out = '\0'; total += j + 1; } if (total > INT_MAX) { /* Too much output data! */ *outl = 0; return; } if (inl != 0) memcpy(&(ctx->enc_data[0]), in, inl); ctx->num = inl; *outl = total; }
void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len, const uint8_t *in, size_t in_len) { size_t total = 0; *out_len = 0; if (in_len == 0) { return; } assert(ctx->length <= sizeof(ctx->enc_data)); assert(ctx->num < ctx->length); if (ctx->length - ctx->num > in_len) { memcpy(&ctx->enc_data[ctx->num], in, in_len); ctx->num += in_len; return; } if (ctx->num != 0) { size_t todo = ctx->length - ctx->num; memcpy(&ctx->enc_data[ctx->num], in, todo); in += todo; in_len -= todo; size_t encoded = EVP_EncodeBlock(out, ctx->enc_data, ctx->length); ctx->num = 0; out += encoded; *(out++) = '\n'; *out = '\0'; total = encoded + 1; } while (in_len >= ctx->length) { size_t encoded = EVP_EncodeBlock(out, in, ctx->length); in += ctx->length; in_len -= ctx->length; out += encoded; *(out++) = '\n'; *out = '\0'; total += encoded + 1; } if (in_len != 0) { memcpy(&ctx->enc_data[0], in, in_len); } ctx->num = in_len; *out_len = total; }
int PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type, EVP_MD *md_type, unsigned char **ek, int *ekl, unsigned char *iv, EVP_PKEY **pubk, int npubk) { unsigned char key[EVP_MAX_KEY_LENGTH]; int ret = -1; int i, j, max = 0; char *s = NULL; /* * Make sure ctx is properly initialized so that we can always pass * it to PEM_ENCODE_SEAL_CTX_cleanup() in the error path. */ EVP_EncodeInit(&ctx->encode); EVP_MD_CTX_init(&ctx->md); EVP_CIPHER_CTX_init(&ctx->cipher); for (i = 0; i < npubk; i++) { if (pubk[i]->type != EVP_PKEY_RSA) { PEMerror(PEM_R_PUBLIC_KEY_NO_RSA); goto err; } j = RSA_size(pubk[i]->pkey.rsa); if (j > max) max = j; } s = reallocarray(NULL, max, 2); if (s == NULL) { PEMerror(ERR_R_MALLOC_FAILURE); goto err; } if (!EVP_SignInit(&ctx->md, md_type)) goto err; ret = EVP_SealInit(&ctx->cipher, type, ek, ekl, iv, pubk, npubk); if (ret <= 0) goto err; /* base64 encode the keys */ for (i = 0; i < npubk; i++) { j = EVP_EncodeBlock((unsigned char *)s, ek[i], RSA_size(pubk[i]->pkey.rsa)); ekl[i] = j; memcpy(ek[i], s, j + 1); } ret = npubk; if (0) { err: PEM_ENCODE_SEAL_CTX_cleanup(ctx); } free(s); explicit_bzero(key, sizeof(key)); return (ret); }
/* * Authenticate to the server with the Challenge-Response Authentication * Mechanism (CRAM). The authentication type associated with CRAM is * "CRAM-MD5". */ int auth_cram_md5(session *ssn, const char *user, const char *pass) { int t; size_t n; unsigned int i; unsigned char *chal, *resp, *out, *buf; unsigned char md[EVP_MAX_MD_SIZE], mdhex[EVP_MAX_MD_SIZE * 2 + 1]; unsigned int mdlen; HMAC_CTX hmac; if ((t = imap_authenticate(ssn, "CRAM-MD5")) == -1) return -1; if (response_authenticate(ssn, t, &chal) == STATUS_RESPONSE_CONTINUE) { n = strlen((char *)(chal)) * 3 / 4 + 1; resp = (unsigned char *)xmalloc(n * sizeof(char)); memset(resp, 0, n); EVP_DecodeBlock(resp, chal, strlen((char *)(chal))); HMAC_Init(&hmac, (const unsigned char *)pass, strlen(pass), EVP_md5()); HMAC_Update(&hmac, resp, strlen((char *)(resp))); HMAC_Final(&hmac, md, &mdlen); xfree(chal); xfree(resp); for (i = 0; i < mdlen; i++) snprintf((char *)(mdhex) + i * 2, mdlen * 2 - i * 2 + 1, "%02x", md[i]); mdhex[mdlen * 2] = '\0'; n = strlen(user) + 1 + strlen((char *)(mdhex)) + 1; buf = (unsigned char *)xmalloc(n * sizeof(unsigned char)); memset(buf, 0, n); snprintf((char *)(buf), n, "%s %s", user, mdhex); n = (strlen((char *)(buf)) + 3) * 4 / 3 + 1; out = (unsigned char *)xmalloc(n * sizeof(unsigned char)); memset(out, 0, n); EVP_EncodeBlock(out, buf, strlen((char *)(buf))); imap_continuation(ssn, (char *)(out), strlen((char *)(out))); xfree(buf); xfree(out); } else return -1; return response_authenticate(ssn, t, NULL); }
void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl) { int i,j; unsigned int total=0; *outl=0; if (inl == 0) return; OPENSSL_assert(ctx->length <= (int)sizeof(ctx->enc_data)); if ((ctx->num+inl) < ctx->length) { TINYCLR_SSL_MEMCPY(&(ctx->enc_data[ctx->num]),in,inl); ctx->num+=inl; return; } if (ctx->num != 0) { i=ctx->length-ctx->num; TINYCLR_SSL_MEMCPY(&(ctx->enc_data[ctx->num]),in,i); in+=i; inl-=i; j=EVP_EncodeBlock(out,ctx->enc_data,ctx->length); ctx->num=0; out+=j; *(out++)='\n'; *out='\0'; total=j+1; } while (inl >= ctx->length) { j=EVP_EncodeBlock(out,in,ctx->length); in+=ctx->length; inl-=ctx->length; out+=j; *(out++)='\n'; *out='\0'; total+=j+1; } if (inl != 0) TINYCLR_SSL_MEMCPY(&(ctx->enc_data[0]),in,inl); ctx->num=inl; *outl=total; }
void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len) { unsigned ret = 0; if (ctx->num != 0) { ret = EVP_EncodeBlock(out, ctx->enc_data, ctx->num); out[ret++] = '\n'; out[ret] = '\0'; ctx->num = 0; } *out_len = ret; }
void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl) { unsigned int ret = 0; if (ctx->num != 0) { ret = EVP_EncodeBlock(out, ctx->enc_data, ctx->num); out[ret++] = '\n'; out[ret] = '\0'; ctx->num = 0; } *outl = ret; }
int PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type, EVP_MD *md_type, unsigned char **ek, int *ekl, unsigned char *iv, EVP_PKEY **pubk, int npubk) { unsigned char key[EVP_MAX_KEY_LENGTH]; int ret = -1; int i, j, max = 0; char *s = NULL; for (i = 0; i < npubk; i++) { if (pubk[i]->type != EVP_PKEY_RSA) { PEMerr(PEM_F_PEM_SEALINIT, PEM_R_PUBLIC_KEY_NO_RSA); goto err; } j = RSA_size(pubk[i]->pkey.rsa); if (j > max) max = j; } s = (char *)reallocarray(NULL, max, 2); if (s == NULL) { PEMerr(PEM_F_PEM_SEALINIT, ERR_R_MALLOC_FAILURE); goto err; } EVP_EncodeInit(&ctx->encode); EVP_MD_CTX_init(&ctx->md); if (!EVP_SignInit(&ctx->md, md_type)) goto err; EVP_CIPHER_CTX_init(&ctx->cipher); ret = EVP_SealInit(&ctx->cipher, type, ek, ekl, iv, pubk, npubk); if (ret <= 0) goto err; /* base64 encode the keys */ for (i = 0; i < npubk; i++) { j = EVP_EncodeBlock((unsigned char *)s, ek[i], RSA_size(pubk[i]->pkey.rsa)); ekl[i] = j; memcpy(ek[i], s, j + 1); } ret = npubk; err: if (s != NULL) free(s); OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH); return (ret); }
static char * _SSL_get_obj_base64(void *s, int type) { unsigned char *pt, *ppt; unsigned char *t; int len = 0; int i; switch (type) { case 0: len = i2d_PublicKey(s, NULL); break; case 1: len = i2d_PrivateKey(s, NULL); break; case 2: len = i2d_X509(s, NULL); break; } if (len < 0) return (NULL); pt = ppt = mmalloc(len); switch (type) { case 0: i2d_PublicKey(s, &pt); break; case 1: i2d_PrivateKey(s, &pt); break; case 2: i2d_X509(s, &pt); break; } t = mmalloc(len * 2 + 1); /* + NULL */ if ((i = EVP_EncodeBlock(t, ppt, len)) == -1) { fprintf(stderr, "_SSL_get_key_base64 :: EVP_EncodeBlock failed\n"); exit(1); } free (ppt); return (t); }
char * NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki) { unsigned char *der_spki, *p; char *b64_str; int der_len; der_len = i2d_NETSCAPE_SPKI(spki, NULL); der_spki = OPENSSL_malloc(der_len); b64_str = OPENSSL_malloc(der_len * 2); if(!der_spki || !b64_str) { X509err(X509_F_NETSCAPE_SPKI_B64_ENCODE, ERR_R_MALLOC_FAILURE); return NULL; } p = der_spki; i2d_NETSCAPE_SPKI(spki, &p); EVP_EncodeBlock((unsigned char *)b64_str, der_spki, der_len); OPENSSL_free(der_spki); return b64_str; }
int PEM_SealFinal(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *sig, int *sigl, unsigned char *out, int *outl, EVP_PKEY *priv) { unsigned char *s = NULL; int ret = 0, j; unsigned int i; if (priv->type != EVP_PKEY_RSA) { PEMerr(PEM_F_PEM_SEALFINAL, PEM_R_PUBLIC_KEY_NO_RSA); goto err; } i = RSA_size(priv->pkey.rsa); if (i < 100) i = 100; s = reallocarray(NULL, i, 2); if (s == NULL) { PEMerr(PEM_F_PEM_SEALFINAL, ERR_R_MALLOC_FAILURE); goto err; } if (!EVP_EncryptFinal_ex(&ctx->cipher, s, (int *)&i)) goto err; EVP_EncodeUpdate(&ctx->encode, out, &j, s, i); *outl = j; out += j; EVP_EncodeFinal(&ctx->encode, out, &j); *outl += j; if (!EVP_SignFinal(&ctx->md, s, &i, priv)) goto err; *sigl = EVP_EncodeBlock(sig, s, i); ret = 1; err: EVP_MD_CTX_cleanup(&ctx->md); EVP_CIPHER_CTX_cleanup(&ctx->cipher); if (s != NULL) free(s); return (ret); }
utility_retcode_t raopd_base64_encode(char *dst, size_t dstlen, const uint8_t *src, size_t srclen, size_t *encoded_length) { utility_retcode_t ret = UTILITY_SUCCESS; FUNC_ENTER; DEBG("srclen: %d dstlen: %d\n", srclen, dstlen); *encoded_length = EVP_EncodeBlock((uint8_t *)dst, src, srclen); remove_base64_columnation(dst, encoded_length); INFO("encoded_length: %d\n", *encoded_length); FUNC_RETURN; return ret; }
int mite_string_2_base64_block(char *input,int input_len,char **base64) { int len = 0; char *out = NULL; out = malloc(((input_len/3+1)*4)); len = EVP_EncodeBlock(out,input,input_len); *base64 = out; return len; /* char *p = out+len-1; int pad=0; int i = 0; for(i=0;i<4;i++) { if(*p=='=') pad++; p--; } */ }
/*++ * Function: cmd_authenticate_login * * Purpose: implement the AUTHENTICATE LOGIN mechanism * * Parameters: ptr to ITD_Struct for client connection. * ptr to client tag * * Returns: 0 on success prior to authentication * 1 on success after authentication (we caught a logout) * -1 on failure * * Authors: Dave McMurtrie <*****@*****.**> * * Notes: *-- */ static int cmd_authenticate_login( ITD_Struct *Client, char *Tag ) { char *fn = "cmd_authenticate_login()"; char SendBuf[BUFSIZE]; char Username[MAXUSERNAMELEN]; char EncodedUsername[BUFSIZE]; char Password[MAXPASSWDLEN]; char EncodedPassword[BUFSIZE]; ICD_Struct *conn; int rc; ITD_Struct Server; int BytesRead; struct sockaddr_in cli_addr; int addrlen; char *hostaddr; unsigned int BufLen = BUFSIZE - 1; memset ( &Server, 0, sizeof Server ); addrlen = sizeof( struct sockaddr_in ); /* * send a base64 encoded username prompt to the client. Note that we're * using our Username and EncodedUsername buffers temporarily here to * avoid allocating additional buffers. Keep this in mind for future * code modification... */ snprintf( Username, BufLen, "Username:"******"+ %s\r\n", EncodedUsername ); if ( IMAP_Write( Client->conn, SendBuf, strlen(SendBuf) ) == -1 ) { syslog(LOG_ERR, "%s: Unable to send base64 encoded username prompt to client: %s", fn, strerror(errno) ); return( -1 ); } /* * The response from the client should be a base64 encoded version of the * username. */ BytesRead = IMAP_Line_Read( Client ); if ( BytesRead == -1 ) { syslog( LOG_NOTICE, "%s: Failed to read base64 encoded username from client on socket %d", fn, Client->conn->sd ); return( -1 ); } /* * Easy, but not perfect sanity check. If the client sent enough data * to fill our entire buffer, we're not even going to bother looking at it. */ if ( Client->MoreData || BytesRead > BufLen ) { syslog( LOG_NOTICE, "%s: Base64 encoded username sent from client on sd %d is too large.", fn, Client->conn->sd ); return( -1 ); } /* * copy BytesRead -2 so we don't include the CRLF. */ memcpy( (void *)EncodedUsername, (const void *)Client->ReadBuf, BytesRead - 2 ); rc = EVP_DecodeBlock( Username, EncodedUsername, BytesRead - 2 ); Username[rc] = '\0'; /* * Same drill all over again, except this time it's for the password. */ snprintf( Password, BufLen, "Password:"******"+ %s\r\n", EncodedPassword ); if ( IMAP_Write( Client->conn, SendBuf, strlen(SendBuf) ) == -1 ) { syslog(LOG_ERR, "%s: Unable to send base64 encoded password prompt to client: %s", fn, strerror(errno) ); return( -1 ); }
/* adds a Identity header field to msg return value: 1: success 0: else */ static int addIdentity(char * dateHF, struct sip_msg * msg) { #define IDENTITY_HDR_S "Identity: \"" #define IDENTITY_HDR_L (sizeof(IDENTITY_HDR_S)-1) EVP_MD_CTX ctx; unsigned int siglen = 0; int b64len = 0; unsigned char * sig = NULL; char digestString[MAX_DIGEST]; str buf; if(!makeDigestString(digestString, dateHF, msg)) { LM_ERR("error making digest string\n"); return 0; } EVP_SignInit(&ctx, EVP_sha1()); EVP_SignUpdate(&ctx, digestString, strlen(digestString)); sig = pkg_malloc(EVP_PKEY_size(privKey_evp)); if(!sig) { EVP_MD_CTX_cleanup(&ctx); LM_ERR("failed allocating memory\n"); return 0; } if(!EVP_SignFinal(&ctx, sig, &siglen, privKey_evp)) { EVP_MD_CTX_cleanup(&ctx); pkg_free(sig); LM_ERR("error calculating signature\n"); return 0; } EVP_MD_CTX_cleanup(&ctx); /* ###Base64-encoding### */ /* annotation: The next few lines are based on example 7-11 of [VIE-02] */ b64len = (((siglen + 2) / 3) * 4) + 1; buf.len = IDENTITY_HDR_L + b64len + 1 + CRLF_LEN; buf.s = pkg_malloc(buf.len); if(!buf.s) { pkg_free(sig); LM_ERR("error allocating memory\n"); return 0; } memcpy( buf.s, IDENTITY_HDR_S, IDENTITY_HDR_L); EVP_EncodeBlock((unsigned char*)(buf.s+IDENTITY_HDR_L), sig, siglen); memcpy( buf.s+IDENTITY_HDR_L+b64len, "\""CRLF, CRLF_LEN+1); pkg_free(sig); if ( id_add_header( msg, buf.s, buf.len )!=0) { pkg_free(buf.s); LM_ERR("failed to add Identity header\n"); return 0; } return 1; }
int LOF_CONNECTION_FetionConnection_connect_with_proxy(LOF_CONNECTION_FetionConnectionType* connection , const char* ipaddress , const int port , LOF_CONNECTION_ProxyType *proxy) { struct sockaddr_in addr; char *ip = LOF_TOOL_get_ip_by_name(proxy->proxyHost); addr.sin_family = AF_INET; addr.sin_addr.s_addr = inet_addr(ip); free(ip); addr.sin_port = htons(proxy->proxyPort); strcpy(connection->remote_ipaddress , ipaddress); connection->remote_port = port; unsigned int n = LOF_MAX_RECV_BUF_SIZE; int ret = setsockopt(connection->socketfd , SOL_SOCKET , SO_RCVBUF , (const char*)&n , sizeof(n)); if(ret == -1) return -1; ret = connect(connection->socketfd , (struct sockaddr*)&addr , sizeof(struct sockaddr)); if(ret == -1) return -1; LOF_debug_info("%s:%d\n", ipaddress, port); char http[1024] , code[5] , *pos = NULL; unsigned char authentication[1024]; char authen[1024]; char authorization[1024]; memset(authorization, 0, sizeof(authorization)); if(strlen(proxy->proxyUser) != 0 && strlen(proxy->proxyPass) != 0) { memset(authen, 0, sizeof(authen)); sprintf(authen , "%s:%s" , proxy->proxyUser , proxy->proxyPass); EVP_EncodeBlock(authentication , (unsigned char*)authen , strlen(authen)); sprintf(authorization , "Proxy-Authorization: Basic %s\r\n" , (char*)authentication); } memset(http, 0, sizeof(http)); snprintf(http , sizeof(http)-1 , "CONNECT %s:%d HTTP/1.1\r\n" "Host: %s:%d\r\n%s" "User-Agent: OpenFetion\r\n\r\n" , ipaddress , port , ipaddress , port , authorization); LOF_CONNECTION_FetionConnection_send(connection , http , strlen(http)); memset(http, 0, sizeof(http)); LOF_CONNECTION_FetionConnection_recv(connection , http , sizeof(http)); pos = strstr(http , " "); if(pos == NULL) { return -1; } pos++; n = strlen(pos) - strlen(strstr(pos , " ")); memset(code, 0, sizeof(code)); strncpy(code, pos, (sizeof(code)-1 < n) ? (sizeof(code)-1) : n); code[sizeof(code)-1]='\0'; if(strcmp(code , "200") != 0) return -1; return 1; }
static int b64_write(BIO *b, const char *in, int inl) { int ret = 0, n, i; BIO_B64_CTX *ctx; ctx = (BIO_B64_CTX *)b->ptr; BIO_clear_retry_flags(b); if (ctx->encode != B64_ENCODE) { ctx->encode = B64_ENCODE; ctx->buf_len = 0; ctx->buf_off = 0; ctx->tmp_len = 0; EVP_EncodeInit(&(ctx->base64)); } assert(ctx->buf_off < (int)sizeof(ctx->buf)); assert(ctx->buf_len <= (int)sizeof(ctx->buf)); assert(ctx->buf_len >= ctx->buf_off); n = ctx->buf_len - ctx->buf_off; while (n > 0) { i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n); if (i <= 0) { BIO_copy_next_retry(b); return i; } assert(i <= n); ctx->buf_off += i; assert(ctx->buf_off <= (int)sizeof(ctx->buf)); assert(ctx->buf_len >= ctx->buf_off); n -= i; } // at this point all pending data has been written. ctx->buf_off = 0; ctx->buf_len = 0; if (in == NULL || inl <= 0) { return 0; } while (inl > 0) { n = (inl > B64_BLOCK_SIZE) ? B64_BLOCK_SIZE : inl; if (BIO_test_flags(b, BIO_FLAGS_BASE64_NO_NL)) { if (ctx->tmp_len > 0) { assert(ctx->tmp_len <= 3); n = 3 - ctx->tmp_len; // There's a theoretical possibility of this. if (n > inl) { n = inl; } OPENSSL_memcpy(&(ctx->tmp[ctx->tmp_len]), in, n); ctx->tmp_len += n; ret += n; if (ctx->tmp_len < 3) { break; } ctx->buf_len = EVP_EncodeBlock((uint8_t *)ctx->buf, (uint8_t *)ctx->tmp, ctx->tmp_len); assert(ctx->buf_len <= (int)sizeof(ctx->buf)); assert(ctx->buf_len >= ctx->buf_off); // Since we're now done using the temporary buffer, the length should // be zeroed. ctx->tmp_len = 0; } else { if (n < 3) { OPENSSL_memcpy(ctx->tmp, in, n); ctx->tmp_len = n; ret += n; break; } n -= n % 3; ctx->buf_len = EVP_EncodeBlock((uint8_t *)ctx->buf, (const uint8_t *)in, n); assert(ctx->buf_len <= (int)sizeof(ctx->buf)); assert(ctx->buf_len >= ctx->buf_off); ret += n; } } else { EVP_EncodeUpdate(&(ctx->base64), (uint8_t *)ctx->buf, &ctx->buf_len, (uint8_t *)in, n); assert(ctx->buf_len <= (int)sizeof(ctx->buf)); assert(ctx->buf_len >= ctx->buf_off); ret += n; } inl -= n; in += n; ctx->buf_off = 0; n = ctx->buf_len; while (n > 0) { i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n); if (i <= 0) { BIO_copy_next_retry(b); return ret == 0 ? i : ret; } assert(i <= n); n -= i; ctx->buf_off += i; assert(ctx->buf_off <= (int)sizeof(ctx->buf)); assert(ctx->buf_len >= ctx->buf_off); } ctx->buf_len = 0; ctx->buf_off = 0; } return ret; }
static long b64_ctrl(BIO *b, int cmd, long num, void *ptr) { BIO_B64_CTX *ctx; long ret = 1; int i; ctx = (BIO_B64_CTX *)b->ptr; switch (cmd) { case BIO_CTRL_RESET: ctx->cont = 1; ctx->start = 1; ctx->encode = B64_NONE; ret = BIO_ctrl(b->next_bio, cmd, num, ptr); break; case BIO_CTRL_EOF: // More to read if (ctx->cont <= 0) { ret = 1; } else { ret = BIO_ctrl(b->next_bio, cmd, num, ptr); } break; case BIO_CTRL_WPENDING: // More to write in buffer assert(ctx->buf_len >= ctx->buf_off); ret = ctx->buf_len - ctx->buf_off; if ((ret == 0) && (ctx->encode != B64_NONE) && (ctx->base64.data_used != 0)) { ret = 1; } else if (ret <= 0) { ret = BIO_ctrl(b->next_bio, cmd, num, ptr); } break; case BIO_CTRL_PENDING: // More to read in buffer assert(ctx->buf_len >= ctx->buf_off); ret = ctx->buf_len - ctx->buf_off; if (ret <= 0) { ret = BIO_ctrl(b->next_bio, cmd, num, ptr); } break; case BIO_CTRL_FLUSH: // do a final write again: while (ctx->buf_len != ctx->buf_off) { i = b64_write(b, NULL, 0); if (i < 0) { return i; } } if (BIO_test_flags(b, BIO_FLAGS_BASE64_NO_NL)) { if (ctx->tmp_len != 0) { ctx->buf_len = EVP_EncodeBlock((uint8_t *)ctx->buf, (uint8_t *)ctx->tmp, ctx->tmp_len); ctx->buf_off = 0; ctx->tmp_len = 0; goto again; } } else if (ctx->encode != B64_NONE && ctx->base64.data_used != 0) { ctx->buf_off = 0; EVP_EncodeFinal(&(ctx->base64), (uint8_t *)ctx->buf, &(ctx->buf_len)); // push out the bytes goto again; } // Finally flush the underlying BIO ret = BIO_ctrl(b->next_bio, cmd, num, ptr); break; case BIO_C_DO_STATE_MACHINE: BIO_clear_retry_flags(b); ret = BIO_ctrl(b->next_bio, cmd, num, ptr); BIO_copy_next_retry(b); break; case BIO_CTRL_INFO: case BIO_CTRL_GET: case BIO_CTRL_SET: default: ret = BIO_ctrl(b->next_bio, cmd, num, ptr); break; } return ret; }
BST_ERR_ENUM_UINT8 BST_CORE_EncryptChk ( BST_CORE_PID_ENUM_UINT16 enPid, const BST_VOID *pvData, BST_UINT16 usLen, BST_VOID **ppOutData, BST_UINT16 *pusOutLen ) { BST_ERR_ENUM_UINT8 enRet; BST_UINT32 ulInLen; BST_UINT32 ulOutLen; BST_UINT32 ulBase64DataLen; BST_UINT8 *pucIn; BST_UINT8 *pucOut; BST_UINT8 *pucBase64Data; ulInLen = 0; ulOutLen = 0; ulBase64DataLen = 0; pucIn = BST_NULL_PTR; pucOut = BST_NULL_PTR; pucBase64Data = BST_NULL_PTR; enRet = BST_NO_ERROR_MSG; if ( ( BST_NULL_PTR == pvData ) || ( BST_NULL_PTR == pusOutLen ) || ( BST_NULL_PTR == ppOutData) ) { return BST_ERR_INVALID_PTR; } if ( 0 == usLen ) { return BST_ERR_PAR_LEN; } if ( CheckIfEcryOrDecry ( enPid ) ) { pucIn = ( BST_UINT8 * )BST_OS_MALLOC ( usLen ); if ( BST_NULL_PTR == pucIn ) { return BST_ERR_NO_MEMORY; } BST_OS_MEMCPY ( pucIn, pvData, usLen ); ulInLen = usLen; pucOut = ( BST_UINT8 * )BST_OS_MALLOC ( ulInLen + EVP_MAX_IV_LENGTH ); if ( BST_NULL_PTR == pucOut ) { BST_OS_FREE ( pucIn ); pucIn = BST_NULL_PTR; return BST_ERR_NO_MEMORY; } enRet = EncryptInternal ( ( BST_UINT8 * )pucIn, ulInLen, pucOut, &ulOutLen, gs_BastetDsppKey ); if ( BST_NO_ERROR_MSG == enRet ) { pucBase64Data = ( BST_UINT8 * )BST_OS_MALLOC ( ulOutLen * 2 ); if ( BST_NULL_PTR == pucBase64Data ) { BST_OS_FREE ( pucIn ); pucIn = BST_NULL_PTR; BST_OS_FREE ( pucOut ); pucOut = BST_NULL_PTR; return BST_ERR_NO_MEMORY; } ulBase64DataLen = EVP_EncodeBlock ( pucBase64Data, pucOut, ulOutLen ); *ppOutData = pucBase64Data; *pusOutLen = ulBase64DataLen; } BST_OS_FREE ( pucIn ); pucIn = BST_NULL_PTR; BST_OS_FREE ( pucOut ); pucOut = BST_NULL_PTR; return enRet; } return BST_NO_ERROR_MSG; }
static int b64_write(BIO *b, const char *in, int inl) { int ret = 0; int n; int i; BIO_B64_CTX *ctx; ctx = (BIO_B64_CTX *)b->ptr; BIO_clear_retry_flags(b); if (ctx->encode != B64_ENCODE) { ctx->encode = B64_ENCODE; ctx->buf_len = 0; ctx->buf_off = 0; ctx->tmp_len = 0; EVP_EncodeInit(ctx->base64); } OPENSSL_assert(ctx->buf_off < (int)sizeof(ctx->buf)); OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf)); OPENSSL_assert(ctx->buf_len >= ctx->buf_off); n = ctx->buf_len - ctx->buf_off; while (n > 0) { i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n); if (i <= 0) { BIO_copy_next_retry(b); return (i); } OPENSSL_assert(i <= n); ctx->buf_off += i; OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf)); OPENSSL_assert(ctx->buf_len >= ctx->buf_off); n -= i; } /* at this point all pending data has been written */ ctx->buf_off = 0; ctx->buf_len = 0; if ((in == NULL) || (inl <= 0)) return (0); while (inl > 0) { n = (inl > B64_BLOCK_SIZE) ? B64_BLOCK_SIZE : inl; if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) { if (ctx->tmp_len > 0) { OPENSSL_assert(ctx->tmp_len <= 3); n = 3 - ctx->tmp_len; /* * There's a theoretical possibility for this */ if (n > inl) n = inl; memcpy(&(ctx->tmp[ctx->tmp_len]), in, n); ctx->tmp_len += n; ret += n; if (ctx->tmp_len < 3) break; ctx->buf_len = EVP_EncodeBlock((unsigned char *)ctx->buf, (unsigned char *)ctx->tmp, ctx->tmp_len); OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf)); OPENSSL_assert(ctx->buf_len >= ctx->buf_off); /* * Since we're now done using the temporary buffer, the * length should be 0'd */ ctx->tmp_len = 0; } else { if (n < 3) { memcpy(ctx->tmp, in, n); ctx->tmp_len = n; ret += n; break; } n -= n % 3; ctx->buf_len = EVP_EncodeBlock((unsigned char *)ctx->buf, (const unsigned char *)in, n); OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf)); OPENSSL_assert(ctx->buf_len >= ctx->buf_off); ret += n; } } else { EVP_EncodeUpdate(ctx->base64, (unsigned char *)ctx->buf, &ctx->buf_len, (unsigned char *)in, n); OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf)); OPENSSL_assert(ctx->buf_len >= ctx->buf_off); ret += n; } inl -= n; in += n; ctx->buf_off = 0; n = ctx->buf_len; while (n > 0) { i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n); if (i <= 0) { BIO_copy_next_retry(b); return ((ret == 0) ? i : ret); } OPENSSL_assert(i <= n); n -= i; ctx->buf_off += i; OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf)); OPENSSL_assert(ctx->buf_len >= ctx->buf_off); } ctx->buf_len = 0; ctx->buf_off = 0; } return (ret); }
static long b64_ctrl(BIO *b, int cmd, long num, void *ptr) { BIO_B64_CTX *ctx; long ret = 1; int i; ctx = (BIO_B64_CTX *)b->ptr; switch (cmd) { case BIO_CTRL_RESET: ctx->cont = 1; ctx->start = 1; ctx->encode = B64_NONE; ret = BIO_ctrl(b->next_bio, cmd, num, ptr); break; case BIO_CTRL_EOF: /* More to read */ if (ctx->cont <= 0) ret = 1; else ret = BIO_ctrl(b->next_bio, cmd, num, ptr); break; case BIO_CTRL_WPENDING: /* More to write in buffer */ OPENSSL_assert(ctx->buf_len >= ctx->buf_off); ret = ctx->buf_len - ctx->buf_off; if ((ret == 0) && (ctx->encode != B64_NONE) && (EVP_ENCODE_CTX_num(ctx->base64) != 0)) ret = 1; else if (ret <= 0) ret = BIO_ctrl(b->next_bio, cmd, num, ptr); break; case BIO_CTRL_PENDING: /* More to read in buffer */ OPENSSL_assert(ctx->buf_len >= ctx->buf_off); ret = ctx->buf_len - ctx->buf_off; if (ret <= 0) ret = BIO_ctrl(b->next_bio, cmd, num, ptr); break; case BIO_CTRL_FLUSH: /* do a final write */ again: while (ctx->buf_len != ctx->buf_off) { i = b64_write(b, NULL, 0); if (i < 0) return i; } if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) { if (ctx->tmp_len != 0) { ctx->buf_len = EVP_EncodeBlock((unsigned char *)ctx->buf, (unsigned char *)ctx->tmp, ctx->tmp_len); ctx->buf_off = 0; ctx->tmp_len = 0; goto again; } } else if (ctx->encode != B64_NONE && EVP_ENCODE_CTX_num(ctx->base64) != 0) { ctx->buf_off = 0; EVP_EncodeFinal(ctx->base64, (unsigned char *)ctx->buf, &(ctx->buf_len)); /* push out the bytes */ goto again; } /* Finally flush the underlying BIO */ ret = BIO_ctrl(b->next_bio, cmd, num, ptr); break; case BIO_C_DO_STATE_MACHINE: BIO_clear_retry_flags(b); ret = BIO_ctrl(b->next_bio, cmd, num, ptr); BIO_copy_next_retry(b); break; case BIO_CTRL_DUP: break; case BIO_CTRL_INFO: case BIO_CTRL_GET: case BIO_CTRL_SET: default: ret = BIO_ctrl(b->next_bio, cmd, num, ptr); break; } return (ret); }
int B64_encode(const char *strin, char *strout, int cbstr) { return EVP_EncodeBlock((unsigned char*)strout, (unsigned char*)strin, cbstr); }
/* * \fn hip_xmlrpc_getput() * * \param mode determines get or put, app, retry on/off * If retry is off only one attempt should be made, * on means the connect() should keep retrying * \param app string to use in the XML RPC application field * \param server server address and port to connect to * \param key DHT key used for get or put * \param key_len length of DHT key in bytes * \param value DHT value used for put, ptr for storing value for get * \param value_len ptr to length of value buffer, length of get is returned * \param secret secret value used to make put removable * \param secret_len length of secret value * \param ttl time to live in seconds * * \brief Perform the XML RPC GET, PUT, and RM operations. */ int hip_xmlrpc_getput(int mode, char *app, struct sockaddr *server, char *key, int key_len, char *value, int *value_len, char *secret, int secret_len, int ttl) { xmlDocPtr doc = NULL; xmlNodePtr root_node = NULL, node; int len = 0, s, retval = 0; char buff[2048], oper[14]; unsigned char key64[2 * DHT_KEY_SIZE], val64[2 * DHT_VAL_SIZE]; unsigned char tmp[2 * DHT_VAL_SIZE], *xmlbuff = NULL; fd_set read_fdset; struct timeval timeout, now; char *p; unsigned int retry_attempts = 0; struct sockaddr_in src_addr; struct dht_val *dv, rm; SHA_CTX c; __u8 secret_hash[SHA_DIGEST_LENGTH], value_hash[SHA_DIGEST_LENGTH]; int rm_ttl = 0, value_hash_len; int retry = ((mode & 0x00F0) == XMLRPC_MODE_RETRY_ON); if ((key_len > (2 * DHT_KEY_SIZE)) || (*value_len > (2 * DHT_VAL_SIZE))) { return(-1); } /* * support for removable puts */ memset(&rm, 0, sizeof(struct dht_val)); if ((mode & 0x000F) == XMLRPC_MODE_PUT) { /* * produce hashes of the secret and the value, for later removal */ SHA1_Init(&c); SHA1_Update(&c, value, *value_len); SHA1_Final(value_hash, &c); SHA1_Init(&c); SHA1_Update(&c, secret, secret_len); SHA1_Final(secret_hash, &c); /* * check if we already published a record with this key; record * this new secret value and value_hash */ pthread_mutex_lock(&dht_vals_lock); gettimeofday(&now, NULL); dv = lookup_dht_val(key); if (dv) { /* save old secret so we can remove it later below */ memcpy(&rm, &dv, sizeof(struct dht_val)); /* any time left for removing the old record? */ rm_ttl = TDIFF(rm.expire_time, now); } else { dv = insert_dht_val(key); } strncpy(dv->app, app, sizeof(dv->app)); dv->value_hash_len = SHA_DIGEST_LENGTH; memcpy(dv->value_hash, value_hash, SHA_DIGEST_LENGTH); dv->secret_len = secret_len; memcpy(dv->secret, secret, secret_len); dv->expire_time.tv_usec = now.tv_usec; dv->expire_time.tv_sec = now.tv_sec + ttl; pthread_mutex_unlock(&dht_vals_lock); } switch (mode & 0x000F) { case XMLRPC_MODE_PUT: sprintf(oper, "put_removable"); break; case XMLRPC_MODE_GET: sprintf(oper, "get"); break; case XMLRPC_MODE_RM: sprintf(oper, "rm"); break; default: log_(WARN, "Invalid XMLRPC mode given to DHT.\n"); return(-1); } /* * create a new XML document */ doc = xmlNewDoc(BAD_CAST "1.0"); root_node = xmlNewNode(NULL, BAD_CAST "methodCall"); xmlDocSetRootElement(doc, root_node); node = xmlNewChild(root_node, NULL, BAD_CAST "methodName", BAD_CAST oper); node = xmlNewChild(root_node, NULL, BAD_CAST "params", NULL); memset(tmp, 0, sizeof(tmp)); memcpy(tmp, key, key_len); EVP_EncodeBlock(key64, tmp, key_len); xml_new_param(node, "base64", (char *)key64); /* key */ /* log_(NORM, "Doing %s using key(%d)=", * ((mode & 0x000F)==XMLRPC_MODE_PUT) ? "PUT":"GET", key_len); * print_hex(key, key_len); * log_(NORM, " [%s]\n", key64); // */ switch (mode & 0x000F) { case XMLRPC_MODE_PUT: memset(tmp, 0, sizeof(tmp)); memcpy(tmp, value, *value_len); EVP_EncodeBlock(val64, tmp, *value_len); xml_new_param(node, "base64", (char *)val64); /* value */ xml_new_param(node, "string", "SHA"); /* hash type */ memset(tmp, 0, sizeof(tmp)); memcpy(tmp, secret_hash, SHA_DIGEST_LENGTH); EVP_EncodeBlock(val64, tmp, SHA_DIGEST_LENGTH); xml_new_param(node, "base64", (char *)val64); /* secret_hash */ sprintf((char *)tmp, "%d", ttl); xml_new_param(node, "int", (char *)tmp); /* lifetime */ break; case XMLRPC_MODE_GET: xml_new_param(node, "int", "10"); /* maxvals */ xml_new_param(node, "base64", ""); /* placemark */ memset(value, 0, *value_len); break; case XMLRPC_MODE_RM: memset(tmp, 0, sizeof(tmp)); memcpy(tmp, value_hash, SHA_DIGEST_LENGTH); EVP_EncodeBlock(val64, tmp, SHA_DIGEST_LENGTH); xml_new_param(node, "base64", (char *)val64); /* value_hash */ xml_new_param(node, "string", "SHA"); /* hash type */ memset(tmp, 0, sizeof(tmp)); memcpy(tmp, secret, secret_len); EVP_EncodeBlock(val64, tmp, secret_len); xml_new_param(node, "base64", (char *)val64); /* secret */ sprintf((char *)tmp, "%d", ttl); xml_new_param(node, "int", (char *)tmp); /* lifetime */ } xml_new_param(node, "string", app); /* app */ xmlDocDumpFormatMemory(doc, &xmlbuff, &len, 0); /* * Build an HTTP POST and transmit to server */ memset(buff, 0, sizeof(buff)); build_http_post_header(buff, len, server); /* len is XML length above */ memcpy(&buff[strlen(buff)], xmlbuff, len); xmlFree(xmlbuff); len = strlen(buff) + 1; connect_retry: /* Connect and send the XML RPC */ if ((s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { log_(WARN, "DHT connect - socket error: %s\n", strerror(errno)); retval = -1; goto putget_exit; } /* Use the preferred address as source */ memset(&src_addr, 0, sizeof(src_addr)); src_addr.sin_family = AF_INET; src_addr.sin_addr.s_addr = get_preferred_addr(); if (!src_addr.sin_addr.s_addr) { log_(NORM, "No preferred address, deferring DHT!\n"); return(-1); } log_(NORM, "Using source address of %s for DHT %s.\n", logaddr(SA(&src_addr)), oper); fflush(stdout); if (bind(s, SA(&src_addr), SALEN(&src_addr)) < 0) { log_(WARN, "DHT connect - bind error: %s\n", strerror(errno)); } if (g_state != 0) { return(-1); } if (retry && (retry_attempts > 0)) { /* quit after a certain number of retries */ if (retry_attempts >= HCNF.max_retries) { retval = -2; goto putget_exit; } /* wait packet_timeout seconds before retrying */ hip_sleep(HCNF.packet_timeout); } retry_attempts++; if (connect(s, server, SALEN(server)) < 0) { log_(WARN, "DHT server connect error: %s\n", strerror(errno)); closesocket(s); #ifdef __WIN32__ errno = WSAGetLastError(); if (retry && ((errno == WSAETIMEDOUT) || (errno == WSAENETUNREACH))) { goto connect_retry; } #else if (retry && ((errno == ETIMEDOUT) || (errno == EHOSTUNREACH))) { goto connect_retry; } #endif retval = -3; goto putget_exit; } if (send(s, buff, len, 0) != len) { log_(WARN, "DHT sent incorrect number of bytes\n"); retval = -4; goto putget_exit; } xmlFreeDoc(doc); doc = NULL; /* * Receive XML RPC response from server */ FD_ZERO(&read_fdset); FD_SET((unsigned int)s, &read_fdset); /* use longer timeout when retry==TRUE, because we have own thread */ if (retry) { timeout.tv_sec = 3; timeout.tv_usec = 0; } else { timeout.tv_sec = 0; timeout.tv_usec = 300000; /* 300ms */ } if (select(s + 1, &read_fdset, NULL, NULL, &timeout) < 0) { log_(WARN, "DHT select error: %s\n", strerror(errno)); retval = -5; goto putget_exit; } else if (FD_ISSET(s, &read_fdset)) { if ((len = recv(s, buff, sizeof(buff) - 1, 0)) <= 0) { log_(WARN, "DHT error receiving from server: %s\n", strerror(errno)); retval = -6; goto putget_exit; } if (strncmp(buff, "HTTP", 4) != 0) { return(-7); } if ((p = strstr(buff, "Content-Length: ")) == NULL) { return(-8); } else /* advance ptr to Content-Length */ { p += 16; } sscanf(p, "%d", &len); p = strchr(p, '\n') + 3; /* advance to end of line */ retval = hip_xmlrpc_parse_response(mode, p, len, value, value_len); log_(NORM, "DHT server responded with return code %d (%s).\n", retval, hip_xmlrpc_resp_to_str(retval)); } else { /* select timeout */ if (retry) /* XXX testme: retry select instead? */ { goto connect_retry; } retval = -9; } putget_exit: #ifdef __WIN32__ closesocket(s); #else close(s); #endif if (doc != NULL) { xmlFreeDoc(doc); } if (rm_ttl > 0) { value_hash_len = sizeof(rm.value_hash); hip_xmlrpc_getput(((mode & 0x00F0) | XMLRPC_MODE_RM), app, server, key, key_len, (char *)rm.value_hash, &value_hash_len, (char *)rm.secret, secret_len, rm_ttl); } return(retval); }